Showing preview only (3,497K chars total). Download the full file or copy to clipboard to get everything.
Repository: tailwindlabs/headlessui
Branch: main
Commit: 7c06d2b53622
Files: 472
Total size: 3.2 MB
Directory structure:
gitextract_53laupa_/
├── .eslintignore
├── .github/
│ ├── CONTRIBUTING.md
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug-report.md
│ │ └── config.yml
│ └── workflows/
│ ├── main.yml
│ ├── prepare-release.yml
│ ├── release-insiders.yml
│ └── release.yml
├── .gitignore
├── .prettierignore
├── .swcrc
├── CHANGELOG.md
├── LICENSE
├── README.md
├── jest/
│ ├── create-jest-config.cjs
│ ├── custom-matchers.ts
│ └── polyfills.ts
├── jest.config.cjs
├── package.json
├── packages/
│ ├── @headlessui-react/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── build/
│ │ │ └── index.cjs
│ │ ├── jest.config.cjs
│ │ ├── jest.setup.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── components/
│ │ │ │ ├── button/
│ │ │ │ │ ├── button.test.tsx
│ │ │ │ │ └── button.tsx
│ │ │ │ ├── checkbox/
│ │ │ │ │ ├── checkbox.test.tsx
│ │ │ │ │ └── checkbox.tsx
│ │ │ │ ├── close-button/
│ │ │ │ │ └── close-button.tsx
│ │ │ │ ├── combobox/
│ │ │ │ │ ├── combobox-machine-glue.tsx
│ │ │ │ │ ├── combobox-machine.ts
│ │ │ │ │ ├── combobox.test.tsx
│ │ │ │ │ └── combobox.tsx
│ │ │ │ ├── combobox-button/
│ │ │ │ │ └── combobox-button.tsx
│ │ │ │ ├── combobox-input/
│ │ │ │ │ └── combobox-input.tsx
│ │ │ │ ├── combobox-label/
│ │ │ │ │ └── combobox-label.tsx
│ │ │ │ ├── combobox-option/
│ │ │ │ │ └── combobox-option.tsx
│ │ │ │ ├── combobox-options/
│ │ │ │ │ └── combobox-options.tsx
│ │ │ │ ├── data-interactive/
│ │ │ │ │ ├── data-interactive.test.tsx
│ │ │ │ │ └── data-interactive.tsx
│ │ │ │ ├── description/
│ │ │ │ │ ├── __snapshots__/
│ │ │ │ │ │ └── description.test.tsx.snap
│ │ │ │ │ ├── description.test.tsx
│ │ │ │ │ └── description.tsx
│ │ │ │ ├── dialog/
│ │ │ │ │ ├── dialog.test.tsx
│ │ │ │ │ └── dialog.tsx
│ │ │ │ ├── dialog-description/
│ │ │ │ │ └── dialog-description.tsx
│ │ │ │ ├── dialog-panel/
│ │ │ │ │ └── dialog-panel.tsx
│ │ │ │ ├── dialog-title/
│ │ │ │ │ └── dialog-title.tsx
│ │ │ │ ├── disclosure/
│ │ │ │ │ ├── disclosure.test.tsx
│ │ │ │ │ └── disclosure.tsx
│ │ │ │ ├── disclosure-button/
│ │ │ │ │ └── disclosure-button.tsx
│ │ │ │ ├── disclosure-panel/
│ │ │ │ │ └── disclosure-panel.tsx
│ │ │ │ ├── field/
│ │ │ │ │ ├── field.test.tsx
│ │ │ │ │ └── field.tsx
│ │ │ │ ├── fieldset/
│ │ │ │ │ ├── fieldset.test.tsx
│ │ │ │ │ └── fieldset.tsx
│ │ │ │ ├── focus-trap/
│ │ │ │ │ ├── focus-trap.test.tsx
│ │ │ │ │ └── focus-trap.tsx
│ │ │ │ ├── focus-trap-features/
│ │ │ │ │ └── focus-trap-features.tsx
│ │ │ │ ├── input/
│ │ │ │ │ ├── input.test.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── keyboard.ts
│ │ │ │ ├── label/
│ │ │ │ │ ├── __snapshots__/
│ │ │ │ │ │ └── label.test.tsx.snap
│ │ │ │ │ ├── label.test.tsx
│ │ │ │ │ └── label.tsx
│ │ │ │ ├── legend/
│ │ │ │ │ └── legend.tsx
│ │ │ │ ├── listbox/
│ │ │ │ │ ├── listbox-machine-glue.tsx
│ │ │ │ │ ├── listbox-machine.ts
│ │ │ │ │ ├── listbox.test.tsx
│ │ │ │ │ └── listbox.tsx
│ │ │ │ ├── listbox-button/
│ │ │ │ │ └── listbox-button.tsx
│ │ │ │ ├── listbox-label/
│ │ │ │ │ └── listbox-label.tsx
│ │ │ │ ├── listbox-option/
│ │ │ │ │ └── listbox-option.tsx
│ │ │ │ ├── listbox-options/
│ │ │ │ │ └── listbox-options.tsx
│ │ │ │ ├── listbox-selected-option/
│ │ │ │ │ └── listbox-selected-option.tsx
│ │ │ │ ├── menu/
│ │ │ │ │ ├── menu-machine-glue.tsx
│ │ │ │ │ ├── menu-machine.ts
│ │ │ │ │ ├── menu.test.tsx
│ │ │ │ │ └── menu.tsx
│ │ │ │ ├── menu-button/
│ │ │ │ │ └── menu-button.tsx
│ │ │ │ ├── menu-heading/
│ │ │ │ │ └── menu-heading.tsx
│ │ │ │ ├── menu-item/
│ │ │ │ │ └── menu-item.tsx
│ │ │ │ ├── menu-items/
│ │ │ │ │ └── menu-items.tsx
│ │ │ │ ├── menu-section/
│ │ │ │ │ └── menu-section.tsx
│ │ │ │ ├── menu-separator/
│ │ │ │ │ └── menu-separator.tsx
│ │ │ │ ├── mouse.ts
│ │ │ │ ├── popover/
│ │ │ │ │ ├── popover-machine-glue.tsx
│ │ │ │ │ ├── popover-machine.ts
│ │ │ │ │ ├── popover.test.tsx
│ │ │ │ │ └── popover.tsx
│ │ │ │ ├── popover-backdrop/
│ │ │ │ │ └── popover-backdrop.tsx
│ │ │ │ ├── popover-button/
│ │ │ │ │ └── popover-button.tsx
│ │ │ │ ├── popover-group/
│ │ │ │ │ └── popover-group.tsx
│ │ │ │ ├── popover-overlay/
│ │ │ │ │ └── popover-overlay.tsx
│ │ │ │ ├── popover-panel/
│ │ │ │ │ └── popover-panel.tsx
│ │ │ │ ├── portal/
│ │ │ │ │ ├── __snapshots__/
│ │ │ │ │ │ └── portal.test.tsx.snap
│ │ │ │ │ ├── portal.test.tsx
│ │ │ │ │ └── portal.tsx
│ │ │ │ ├── radio/
│ │ │ │ │ └── radio.tsx
│ │ │ │ ├── radio-group/
│ │ │ │ │ ├── radio-group.test.tsx
│ │ │ │ │ └── radio-group.tsx
│ │ │ │ ├── radio-group-description/
│ │ │ │ │ └── radio-group-description.tsx
│ │ │ │ ├── radio-group-label/
│ │ │ │ │ └── radio-group-label.tsx
│ │ │ │ ├── radio-group-option/
│ │ │ │ │ └── radio-group-option.tsx
│ │ │ │ ├── select/
│ │ │ │ │ ├── select.test.tsx
│ │ │ │ │ └── select.tsx
│ │ │ │ ├── switch/
│ │ │ │ │ ├── switch.test.tsx
│ │ │ │ │ └── switch.tsx
│ │ │ │ ├── switch-description/
│ │ │ │ │ └── switch-description.tsx
│ │ │ │ ├── switch-group/
│ │ │ │ │ └── switch-group.tsx
│ │ │ │ ├── switch-label/
│ │ │ │ │ └── switch-label.tsx
│ │ │ │ ├── tab/
│ │ │ │ │ └── tab.tsx
│ │ │ │ ├── tab-group/
│ │ │ │ │ └── tab-group.tsx
│ │ │ │ ├── tab-list/
│ │ │ │ │ └── tab-list.tsx
│ │ │ │ ├── tab-panel/
│ │ │ │ │ └── tab-panel.tsx
│ │ │ │ ├── tab-panels/
│ │ │ │ │ └── tab-panels.tsx
│ │ │ │ ├── tabs/
│ │ │ │ │ ├── tabs.ssr.test.tsx
│ │ │ │ │ ├── tabs.test.tsx
│ │ │ │ │ └── tabs.tsx
│ │ │ │ ├── textarea/
│ │ │ │ │ ├── textarea.test.tsx
│ │ │ │ │ └── textarea.tsx
│ │ │ │ ├── tooltip/
│ │ │ │ │ └── tooltip.tsx
│ │ │ │ ├── transition/
│ │ │ │ │ ├── __snapshots__/
│ │ │ │ │ │ └── transition.test.tsx.snap
│ │ │ │ │ ├── transition.ssr.test.tsx
│ │ │ │ │ ├── transition.test.tsx
│ │ │ │ │ └── transition.tsx
│ │ │ │ ├── transition-child/
│ │ │ │ │ └── transition-child.tsx
│ │ │ │ └── transitions/
│ │ │ │ └── transition.tsx
│ │ │ ├── hooks/
│ │ │ │ ├── __mocks__/
│ │ │ │ │ └── use-id.ts
│ │ │ │ ├── document-overflow/
│ │ │ │ │ ├── adjust-scrollbar-padding.ts
│ │ │ │ │ ├── handle-ios-locking.ts
│ │ │ │ │ ├── overflow-store.ts
│ │ │ │ │ ├── prevent-scroll.ts
│ │ │ │ │ └── use-document-overflow.ts
│ │ │ │ ├── use-active-press.tsx
│ │ │ │ ├── use-by-comparator.ts
│ │ │ │ ├── use-computed.ts
│ │ │ │ ├── use-controllable.ts
│ │ │ │ ├── use-default-value.ts
│ │ │ │ ├── use-disposables.ts
│ │ │ │ ├── use-document-event.ts
│ │ │ │ ├── use-element-size.ts
│ │ │ │ ├── use-escape.ts
│ │ │ │ ├── use-event-listener.ts
│ │ │ │ ├── use-event.ts
│ │ │ │ ├── use-flags.ts
│ │ │ │ ├── use-handle-toggle.tsx
│ │ │ │ ├── use-id.ts
│ │ │ │ ├── use-inert-others.test.tsx
│ │ │ │ ├── use-inert-others.tsx
│ │ │ │ ├── use-is-initial-render.ts
│ │ │ │ ├── use-is-mounted.ts
│ │ │ │ ├── use-is-top-layer.ts
│ │ │ │ ├── use-is-touch-device.ts
│ │ │ │ ├── use-iso-morphic-effect.ts
│ │ │ │ ├── use-latest-value.ts
│ │ │ │ ├── use-on-disappear.ts
│ │ │ │ ├── use-on-unmount.ts
│ │ │ │ ├── use-outside-click.ts
│ │ │ │ ├── use-owner.ts
│ │ │ │ ├── use-quick-release.ts
│ │ │ │ ├── use-refocusable-input.ts
│ │ │ │ ├── use-resolve-button-type.ts
│ │ │ │ ├── use-resolved-tag.ts
│ │ │ │ ├── use-root-containers.tsx
│ │ │ │ ├── use-scroll-lock.ts
│ │ │ │ ├── use-server-handoff-complete.ts
│ │ │ │ ├── use-slot.ts
│ │ │ │ ├── use-store.ts
│ │ │ │ ├── use-sync-refs.ts
│ │ │ │ ├── use-tab-direction.ts
│ │ │ │ ├── use-text-value.ts
│ │ │ │ ├── use-tracked-pointer.ts
│ │ │ │ ├── use-transition.ts
│ │ │ │ ├── use-tree-walker.ts
│ │ │ │ ├── use-watch.ts
│ │ │ │ └── use-window-event.ts
│ │ │ ├── index.test.ts
│ │ │ ├── index.ts
│ │ │ ├── internal/
│ │ │ │ ├── close-provider.tsx
│ │ │ │ ├── disabled.tsx
│ │ │ │ ├── floating.tsx
│ │ │ │ ├── focus-sentinel.tsx
│ │ │ │ ├── form-fields.tsx
│ │ │ │ ├── frozen.tsx
│ │ │ │ ├── hidden.tsx
│ │ │ │ ├── id.tsx
│ │ │ │ ├── open-closed.tsx
│ │ │ │ └── portal-force-root.tsx
│ │ │ ├── machine.ts
│ │ │ ├── machines/
│ │ │ │ └── stack-machine.ts
│ │ │ ├── react-glue.tsx
│ │ │ ├── test-utils/
│ │ │ │ ├── accessibility-assertions.ts
│ │ │ │ ├── execute-timeline.ts
│ │ │ │ ├── fake-pointer.ts
│ │ │ │ ├── interactions.test.tsx
│ │ │ │ ├── interactions.ts
│ │ │ │ ├── report-dom-node-changes.ts
│ │ │ │ ├── scenarios.tsx
│ │ │ │ ├── snapshot.ts
│ │ │ │ ├── ssr.tsx
│ │ │ │ └── suppress-console-logs.ts
│ │ │ ├── types.ts
│ │ │ └── utils/
│ │ │ ├── __snapshots__/
│ │ │ │ └── render.test.tsx.snap
│ │ │ ├── active-element-history.ts
│ │ │ ├── bugs.ts
│ │ │ ├── calculate-active-index.ts
│ │ │ ├── class-names.ts
│ │ │ ├── default-map.ts
│ │ │ ├── disposables.ts
│ │ │ ├── document-ready.ts
│ │ │ ├── dom.ts
│ │ │ ├── element-movement.ts
│ │ │ ├── env.ts
│ │ │ ├── focus-management.ts
│ │ │ ├── form.test.ts
│ │ │ ├── form.ts
│ │ │ ├── get-text-value.test.ts
│ │ │ ├── get-text-value.ts
│ │ │ ├── match.ts
│ │ │ ├── micro-task.ts
│ │ │ ├── once.ts
│ │ │ ├── owner.ts
│ │ │ ├── platform.ts
│ │ │ ├── render.test.tsx
│ │ │ ├── render.ts
│ │ │ ├── stable-collection.tsx
│ │ │ ├── start-transition.ts
│ │ │ └── store.ts
│ │ ├── tsconfig.json
│ │ └── types/
│ │ └── jest.d.ts
│ ├── @headlessui-tailwindcss/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── build/
│ │ │ └── index.cjs
│ │ ├── jest.config.cjs
│ │ ├── package.json
│ │ ├── scripts/
│ │ │ └── fix-types.cjs
│ │ ├── src/
│ │ │ ├── __snapshots__/
│ │ │ │ └── index.test.ts.snap
│ │ │ ├── index.test.ts
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ └── @headlessui-vue/
│ ├── CHANGELOG.md
│ ├── LICENSE
│ ├── README.md
│ ├── build/
│ │ └── index.cjs
│ ├── jest.config.cjs
│ ├── package.json
│ ├── src/
│ │ ├── components/
│ │ │ ├── combobox/
│ │ │ │ ├── combobox.test.ts
│ │ │ │ └── combobox.ts
│ │ │ ├── description/
│ │ │ │ ├── __snapshots__/
│ │ │ │ │ └── description.test.ts.snap
│ │ │ │ ├── description.test.ts
│ │ │ │ └── description.ts
│ │ │ ├── dialog/
│ │ │ │ ├── dialog.test.ts
│ │ │ │ └── dialog.ts
│ │ │ ├── disclosure/
│ │ │ │ ├── disclosure.srr.test.ts
│ │ │ │ ├── disclosure.test.ts
│ │ │ │ └── disclosure.ts
│ │ │ ├── focus-trap/
│ │ │ │ ├── focus-trap.test.ts
│ │ │ │ └── focus-trap.ts
│ │ │ ├── label/
│ │ │ │ ├── __snapshots__/
│ │ │ │ │ └── label.test.ts.snap
│ │ │ │ ├── label.test.ts
│ │ │ │ └── label.ts
│ │ │ ├── listbox/
│ │ │ │ ├── listbox.test.tsx
│ │ │ │ └── listbox.ts
│ │ │ ├── menu/
│ │ │ │ ├── menu.test.tsx
│ │ │ │ └── menu.ts
│ │ │ ├── popover/
│ │ │ │ ├── popover.test.ts
│ │ │ │ └── popover.ts
│ │ │ ├── portal/
│ │ │ │ ├── __snapshots__/
│ │ │ │ │ └── portal.test.ts.snap
│ │ │ │ ├── portal.test.ts
│ │ │ │ └── portal.ts
│ │ │ ├── radio-group/
│ │ │ │ ├── radio-group.test.ts
│ │ │ │ └── radio-group.ts
│ │ │ ├── switch/
│ │ │ │ ├── switch.test.tsx
│ │ │ │ └── switch.ts
│ │ │ ├── tabs/
│ │ │ │ ├── tabs.ssr.test.ts
│ │ │ │ ├── tabs.test.ts
│ │ │ │ └── tabs.ts
│ │ │ └── transitions/
│ │ │ ├── __snapshots__/
│ │ │ │ └── transition.test.ts.snap
│ │ │ ├── transition.ssr.test.ts
│ │ │ ├── transition.test.ts
│ │ │ ├── transition.ts
│ │ │ └── utils/
│ │ │ ├── transition.test.ts
│ │ │ └── transition.ts
│ │ ├── hooks/
│ │ │ ├── __mocks__/
│ │ │ │ └── use-id.ts
│ │ │ ├── document-overflow/
│ │ │ │ ├── adjust-scrollbar-padding.ts
│ │ │ │ ├── handle-ios-locking.ts
│ │ │ │ ├── overflow-store.ts
│ │ │ │ ├── prevent-scroll.ts
│ │ │ │ └── use-document-overflow.ts
│ │ │ ├── use-controllable.ts
│ │ │ ├── use-disposables.ts
│ │ │ ├── use-document-event.ts
│ │ │ ├── use-event-listener.ts
│ │ │ ├── use-frame-debounce.ts
│ │ │ ├── use-id.ts
│ │ │ ├── use-inert.test.ts
│ │ │ ├── use-inert.ts
│ │ │ ├── use-outside-click.ts
│ │ │ ├── use-resolve-button-type.ts
│ │ │ ├── use-root-containers.ts
│ │ │ ├── use-store.ts
│ │ │ ├── use-tab-direction.ts
│ │ │ ├── use-text-value.ts
│ │ │ ├── use-tracked-pointer.ts
│ │ │ ├── use-tree-walker.ts
│ │ │ └── use-window-event.ts
│ │ ├── index.test.ts
│ │ ├── index.ts
│ │ ├── internal/
│ │ │ ├── dom-containers.ts
│ │ │ ├── focus-sentinel.ts
│ │ │ ├── hidden.ts
│ │ │ ├── open-closed.ts
│ │ │ ├── portal-force-root.ts
│ │ │ └── stack-context.ts
│ │ ├── keyboard.ts
│ │ ├── mouse.ts
│ │ ├── test-utils/
│ │ │ ├── accessibility-assertions.ts
│ │ │ ├── execute-timeline.ts
│ │ │ ├── fake-pointer.ts
│ │ │ ├── html.ts
│ │ │ ├── interactions.test.ts
│ │ │ ├── interactions.ts
│ │ │ ├── report-dom-node-changes.ts
│ │ │ ├── ssr.ts
│ │ │ ├── suppress-console-logs.ts
│ │ │ └── vue-testing-library.ts
│ │ └── utils/
│ │ ├── active-element-history.ts
│ │ ├── calculate-active-index.ts
│ │ ├── disposables.ts
│ │ ├── document-ready.ts
│ │ ├── dom.ts
│ │ ├── env.ts
│ │ ├── focus-management.ts
│ │ ├── form.test.ts
│ │ ├── form.ts
│ │ ├── get-text-value.test.ts
│ │ ├── get-text-value.ts
│ │ ├── match.ts
│ │ ├── micro-task.ts
│ │ ├── once.ts
│ │ ├── owner.ts
│ │ ├── pipeline.ts
│ │ ├── platform.ts
│ │ ├── render.test.ts
│ │ ├── render.ts
│ │ ├── resolve-prop-value.ts
│ │ └── store.ts
│ ├── tsconfig.json
│ └── types/
│ └── jest.d.ts
├── playgrounds/
│ ├── react/
│ │ ├── components/
│ │ │ ├── button.tsx
│ │ │ └── input.tsx
│ │ ├── data.ts
│ │ ├── next-env.d.ts
│ │ ├── next.config.js
│ │ ├── package.json
│ │ ├── pages/
│ │ │ ├── _app.tsx
│ │ │ ├── _document.tsx
│ │ │ ├── _error.tsx
│ │ │ ├── combinations/
│ │ │ │ ├── form.tsx
│ │ │ │ └── tabs-in-dialog.tsx
│ │ │ ├── combobox/
│ │ │ │ ├── combobox-countries.tsx
│ │ │ │ ├── combobox-open-on-focus.tsx
│ │ │ │ ├── combobox-virtual-with-empty-states.tsx
│ │ │ │ ├── combobox-virtualized.tsx
│ │ │ │ ├── combobox-with-pure-tailwind.tsx
│ │ │ │ ├── command-palette-with-groups.tsx
│ │ │ │ ├── command-palette.tsx
│ │ │ │ └── multi-select.tsx
│ │ │ ├── dialog/
│ │ │ │ ├── dialog-built-in-transition.tsx
│ │ │ │ ├── dialog-focus-issue.tsx
│ │ │ │ ├── dialog-scroll-issue.tsx
│ │ │ │ ├── dialog-with-shadow-children.tsx
│ │ │ │ ├── dialog.tsx
│ │ │ │ ├── scrollable-dialog.tsx
│ │ │ │ ├── scrollable-page-with-dialog.tsx
│ │ │ │ └── sibling-dialogs.tsx
│ │ │ ├── disclosure/
│ │ │ │ └── disclosure.tsx
│ │ │ ├── listbox/
│ │ │ │ ├── listbox-overlaps.tsx
│ │ │ │ ├── listbox-with-pure-tailwind.tsx
│ │ │ │ ├── multi-select.tsx
│ │ │ │ └── multiple-elements.tsx
│ │ │ ├── menu/
│ │ │ │ ├── menu-with-floating-ui.tsx
│ │ │ │ ├── menu-with-framer-motion.tsx
│ │ │ │ ├── menu-with-popper.tsx
│ │ │ │ ├── menu-with-transition-and-popper.tsx
│ │ │ │ ├── menu-with-transition.tsx
│ │ │ │ ├── menu.tsx
│ │ │ │ └── multiple-elements.tsx
│ │ │ ├── popover/
│ │ │ │ └── popover.tsx
│ │ │ ├── radio-group/
│ │ │ │ └── radio-group.tsx
│ │ │ ├── styles.css
│ │ │ ├── suspense/
│ │ │ │ └── portal.tsx
│ │ │ ├── switch/
│ │ │ │ └── switch-with-pure-tailwind.tsx
│ │ │ ├── tabs/
│ │ │ │ └── tabs-with-pure-tailwind.tsx
│ │ │ └── transitions/
│ │ │ ├── appear.tsx
│ │ │ ├── both-apis.tsx
│ │ │ ├── component-examples/
│ │ │ │ ├── dropdown.tsx
│ │ │ │ ├── modal.tsx
│ │ │ │ ├── nested/
│ │ │ │ │ ├── hidden.tsx
│ │ │ │ │ └── unmount.tsx
│ │ │ │ └── peek-a-boo.tsx
│ │ │ ├── full-page-examples/
│ │ │ │ ├── full-page-transition.tsx
│ │ │ │ └── layout-with-sidebar.tsx
│ │ │ └── react-hot-toast.tsx
│ │ ├── postcss.config.js
│ │ ├── tsconfig.json
│ │ └── utils/
│ │ ├── class-names.ts
│ │ ├── hooks/
│ │ │ └── use-popper.ts
│ │ ├── match.ts
│ │ └── resolve-all-examples.ts
│ └── vue/
│ ├── index.html
│ ├── package.json
│ ├── postcss.config.js
│ ├── src/
│ │ ├── .generated/
│ │ │ └── .gitignore
│ │ ├── App.vue
│ │ ├── KeyCaster.vue
│ │ ├── Layout.vue
│ │ ├── components/
│ │ │ ├── Button.vue
│ │ │ ├── Home.vue
│ │ │ ├── combinations/
│ │ │ │ ├── form.vue
│ │ │ │ └── tabs-in-dialog.vue
│ │ │ ├── combobox/
│ │ │ │ ├── _virtual-example.vue
│ │ │ │ ├── combobox-countries.vue
│ │ │ │ ├── combobox-open-on-focus.vue
│ │ │ │ ├── combobox-virtual-with-empty-states.vue
│ │ │ │ ├── combobox-virtualized.vue
│ │ │ │ ├── combobox-with-pure-tailwind.vue
│ │ │ │ ├── command-palette-with-groups.vue
│ │ │ │ ├── command-palette.vue
│ │ │ │ └── multi-select.vue
│ │ │ ├── dialog/
│ │ │ │ ├── dialog.vue
│ │ │ │ └── slide-over.vue
│ │ │ ├── disclosure/
│ │ │ │ └── disclosure.vue
│ │ │ ├── focus-trap/
│ │ │ │ └── focus-trap.vue
│ │ │ ├── listbox/
│ │ │ │ ├── listbox.vue
│ │ │ │ ├── multi-select.vue
│ │ │ │ └── multiple-elements.vue
│ │ │ ├── menu/
│ │ │ │ ├── menu-with-floating-ui.vue
│ │ │ │ ├── menu-with-popper.vue
│ │ │ │ ├── menu-with-transition-and-popper.vue
│ │ │ │ ├── menu-with-transition.vue
│ │ │ │ ├── menu.vue
│ │ │ │ └── multiple-elements.vue
│ │ │ ├── popover/
│ │ │ │ └── popover.vue
│ │ │ ├── portal/
│ │ │ │ └── portal.vue
│ │ │ ├── radio-group/
│ │ │ │ └── radio-group.vue
│ │ │ ├── switch/
│ │ │ │ └── switch.vue
│ │ │ └── tabs/
│ │ │ ├── simple-tabs.vue
│ │ │ └── tabs.vue
│ │ ├── data.ts
│ │ ├── main.ts
│ │ ├── playground-utils/
│ │ │ └── hooks/
│ │ │ └── use-popper.js
│ │ ├── router.ts
│ │ └── styles.css
│ ├── tsconfig.json
│ ├── vercel.json
│ └── vite.config.js
└── scripts/
├── build.sh
├── lint.sh
├── make-nextjs-happy.js
├── package-path.js
├── release-channel.js
├── release-notes.js
├── resolve-files.js
├── rewrite-imports.js
├── test.sh
└── watch.sh
================================================
FILE CONTENTS
================================================
================================================
FILE: .eslintignore
================================================
/dist
/packages/**/dist
/node_modules
/packages/**/node_modules
================================================
FILE: .github/CONTRIBUTING.md
================================================
# Contributing
Thanks for your interest in contributing to Headless UI! Please take a moment to review this document **before submitting a pull request**.
- [Pull requests](#pull-requests)
- [Monorepo](#monorepo)
- [Installation](#installation)
- [Coding standards](#coding-standards)
- [Running tests](#running-tests)
- [Running playgrounds](#running-playgrounds)
- [Scripts summary](#scripts-summary)
## Pull requests
**Please ask first before starting work on any significant new features.**
It's never a fun experience to have your pull request declined after investing a lot of time and effort into a new feature. To avoid this from happening, we request that contributors create [an issue](https://github.com/tailwindlabs/headlessui/issues) to first discuss any significant new features. This includes things like adding new components, exposing internal information, etc.
Also make sure that you are making changes to both the `React` and `Vue` versions so that we can ensure feature parity.
## Monorepo
The Headless UI repo is a monorepo using `npm` workspaces.
## Installation
You only require a `npm install` in the root directory to install everything you need.
```sh
npm install
```
## Coding standards
We use `prettier` for making sure that the codebase is formatted consistently.
To automatically fix any style violations in your code, you can run:
```sh
npm lint
```
**Note**: Whenever you commit, the lint check will run on all staged files.
**Note**: In CI, we will only check your code, and not write with the formatted files. If you want to just check, then you can either run `npm run lint-check` or `CI=true npm run lint`
## Running tests
You can run the test suite using the following commands:
```sh
npm run test
```
You can also run them for React or Vue individually:
```sh
npm run react test
# or
npm run vue test
```
Please ensure that the tests are passing when submitting a pull request. If you're adding new features to Headless UI, please include tests.
## Running playgrounds
Currently the `React` playground (located in `packages/playground-react`) is a Next.js app that contains some examples which you can find in the `pages` directory. The `Vue` playground (located in `packages/playground-vue`) is a Vite app that contains some examples which you can find in the `src/components` directory.
You can launch them by running:
```sh
npm run react playground
# or
npm run vue playground
```
This will also start the necessary watchers so that you don't have to care about them.
## Scripts summary
Global scripts, and some aliases:
- `npm install`: install all dependencies for all packages
- `npm run clean`: this will call all `npm run {package} clean` commands
- `npm run build`: this will call all `npm run {package} build` commands
- `npm run lint`: this will `lint` all packages
- `npm run test`: this will `test` all packages
- `npm run test`: run all jest tests
- `npm run test --watch`: run all jest tests in interactive mode
- `npm run test tabs`: run all jest tests filtered by `tabs`
- `npm run test tabs --watch`: run all jest tests in interactive mode filtered by `tabs`
Scripts per package:
- `npm run react`: Prefix to run anything in the `@headlessui/react` package
- `npm run react test`: run all jest tests
- `npm run react test --watch`: run all jest tests in interactive mode
- `npm run react test tabs`: run all jest tests filtered by `tabs`
- `npm run react test tabs --watch`: run all jest tests in interactive mode filtered by `tabs`
- `npm run react build`: build the final artefacts
- `npm run react lint`: validate and fix the react codebase using prettier
- `npm run react watch`: start a watcher for the react esm build
- **Note**: this will be executed for you when using the `npm run react playground`
- **Note**: this is not required for jest. You will probably never need this
- `npm run react playground`: (alias) start a development server in the `playground-react` package
- **Note**: this will also run `npm run react watch` for you, which means that you only need to execute `npm run react playground`
- `npm run react clean`: this will remove `dist` files
- `npm run vue`: Prefix to run anything in the `@headlessui/vue` package
- `npm run vue test`: run all jest tests
- `npm run vue test --watch`: run all jest tests in interactive mode
- `npm run vue test tabs`: run all jest tests filtered by `tabs`
- `npm run vue test tabs --watch`: run all jest tests in interactive mode filtered by `tabs`
- `npm run vue build`: build the final artefacts
- `npm run vue lint`: validate and fix the vue codebase using prettier
- `npm run vue watch`: start a watcher for the vue esm build
- **Note**: this will be executed for you when using the `npm run vue playground`
- **Note**: this is not required for jest. You will probably never need this
- `npm run vue playground`: (alias) start a development server in the `playground-vue` package
- **Note**: this will also run `npm run vue watch` for you, which means that you only need to execute `npm run react playground`
- `npm run vue clean`: this will remove `dist` files
================================================
FILE: .github/FUNDING.yml
================================================
custom: ['https://tailwindcss.com/sponsor']
================================================
FILE: .github/ISSUE_TEMPLATE/bug-report.md
================================================
---
name: Bug report
about: If you've already asked for help with a problem and confirmed something is broken with Headless UI itself, create a bug report.
title: ''
labels: ''
assignees: ''
---
<!-- Please provide all of the information requested below. We're a small team and without all of this information it's not possible for us to help and your bug report will be closed. -->
**What package within Headless UI are you using?**
For example: @headlessui/react
**What version of that package are you using?**
For example: v0.3.1
**What browser are you using?**
For example: Chrome, Safari, or N/A
**Reproduction URL**
A public GitHub repo that includes a minimal reproduction of the bug. **Please do not link to your actual project**, what we need instead is a _minimal_ reproduction in a fresh project without any unnecessary code. This means it doesn't matter if your real project is private/confidential, since we want a link to a separate, isolated reproduction anyways. Unfortunately we can't provide support without a reproduction, and your issue will be closed with no comment if this is not provided.
You can use one of the starting projects on CodeSandbox:
- With React and Tailwind CSS: https://codesandbox.io/s/github/tailwindlabs/reproduction-headlessui-react
- With Vue and Tailwind CSS: https://codesandbox.io/s/github/tailwindlabs/reproduction-headlessui-vue
**Describe your issue**
Describe the problem you're seeing, any important steps to reproduce and what behavior you expect instead.
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
- name: Get Help
url: https://github.com/tailwindlabs/headlessui/discussions/new?category=help
about: If you can't get something to work the way you expect, open a question in our discussion forums.
- name: Feature Request
url: https://github.com/tailwindlabs/headlessui/discussions/new?category=ideas
about: 'Suggest any ideas you have using our discussion forums.'
- name: Documentation Issue
url: https://github.com/tailwindlabs/headlessui/issues/new?title=%5BDOCS%5D:%20
about: 'For documentation issues, suggest changes on our documentation repository.'
================================================
FILE: .github/workflows/main.yml
================================================
name: CI
on:
push:
branches: [main]
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
env:
NODE_VERSION: 18.x
jobs:
install:
runs-on: ubuntu-latest
steps:
- name: Begin CI...
uses: actions/checkout@v4
- name: Use Node ${{ env.NODE_VERSION }}
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- uses: actions/cache@v4
with:
path: '**/node_modules'
key: ${{ runner.os }}-${{ env.NODE_VERSION }}-modules-${{ hashFiles('**/package-lock.json') }}
- name: Install dependencies
run: npm ci
env:
CI: true
lint:
runs-on: ubuntu-latest
needs: [install]
steps:
- name: Begin CI...
uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: '**/node_modules'
key: ${{ runner.os }}-${{ env.NODE_VERSION }}-modules-${{ hashFiles('**/package-lock.json') }}
- name: Lint
run: npm run lint
env:
CI: true
test:
runs-on: ubuntu-latest
needs: [install]
steps:
- name: Begin CI...
uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: '**/node_modules'
key: ${{ runner.os }}-${{ env.NODE_VERSION }}-modules-${{ hashFiles('**/package-lock.json') }}
- name: Test
run: |
npm run test || npm run test || npm run test || exit 1
env:
CI: true
build:
runs-on: ubuntu-latest
needs: [install]
steps:
- name: Begin CI...
uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: '**/node_modules'
key: ${{ runner.os }}-${{ env.NODE_VERSION }}-modules-${{ hashFiles('**/package-lock.json') }}
- name: Build
run: npm run build
env:
CI: true
check-types:
runs-on: ubuntu-latest
needs: [build]
steps:
- name: Begin CI...
uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: '**/node_modules'
key: ${{ runner.os }}-${{ env.NODE_VERSION }}-modules-${{ hashFiles('**/package-lock.json') }}
- name: Check Types
run: npm run lint-types
env:
CI: true
================================================
FILE: .github/workflows/prepare-release.yml
================================================
name: Prepare Release
on:
workflow_dispatch:
push:
tags:
- '**'
env:
CI: true
permissions:
contents: read
jobs:
build:
permissions:
contents: write # for softprops/action-gh-release to create GitHub release
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18]
steps:
- uses: actions/checkout@v4
- run: git fetch --tags -f
- name: Resolve version
id: vars
run: |
echo "TAG_NAME=${{ github.ref_name }}" >> $GITHUB_ENV
- name: Get release notes
run: |
RELEASE_NOTES=$(npm run release-notes $TAG_NAME --silent)
echo "RELEASE_NOTES<<EOF" >> $GITHUB_ENV
echo "$RELEASE_NOTES" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
registry-url: 'https://registry.npmjs.org'
- name: Release
uses: softprops/action-gh-release@v2
with:
draft: true
tag_name: ${{ env.TAG_NAME }}
body: |
${{ env.RELEASE_NOTES }}
================================================
FILE: .github/workflows/release-insiders.yml
================================================
name: Release Insiders
on:
push:
branches: [main]
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
permissions:
contents: read
# https://docs.npmjs.com/generating-provenance-statements#publishing-packages-with-provenance-via-github-actions
id-token: write
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [20]
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
registry-url: 'https://registry.npmjs.org'
- name: Use cached node_modules
id: cache
uses: actions/cache@v4
with:
path: '**/node_modules'
key: ${{ runner.os }}-${{ env.NODE_VERSION }}-modules-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
nodeModules-
- name: Install dependencies
run: npm ci
env:
CI: true
- name: Test
run: |
npm run test || npm run test || npm run test || exit 1
env:
CI: true
- name: Resolve version
id: vars
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
- name: 'Version based on commit: 0.0.0-insiders.${{ steps.vars.outputs.sha_short }}'
run: npm version -w packages 0.0.0-insiders.${{ steps.vars.outputs.sha_short }} --force --no-git-tag-version
- name: Publish
run: npm publish -w packages --provenance --tag insiders
env:
CI: true
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
================================================
FILE: .github/workflows/release.yml
================================================
name: Release
on:
release:
types: [published]
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
permissions:
contents: read
# https://docs.npmjs.com/generating-provenance-statements#publishing-packages-with-provenance-via-github-actions
id-token: write
env:
CI: true
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18]
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
registry-url: 'https://registry.npmjs.org'
- name: Use cached node_modules
id: cache
uses: actions/cache@v4
with:
path: '**/node_modules'
key: ${{ runner.os }}-${{ env.NODE_VERSION }}-modules-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
nodeModules-
- name: Install dependencies
run: npm ci
env:
CI: true
- name: Test
run: |
npm run test || npm run test || npm run test || exit 1
env:
CI: true
- name: Calculate environment variables
run: |
echo "TAG_NAME=${{ github.event.tag_name }}" >> $GITHUB_ENV
echo "RELEASE_CHANNEL=$(npm run release-channel $TAG_NAME --silent)" >> $GITHUB_ENV
echo "PACKAGE_PATH=$(npm run package-path $TAG_NAME --silent)" >> $GITHUB_ENV
- name: Publish
run: npm publish ${{ env.PACKAGE_PATH }} --provenance --tag ${{ env.RELEASE_CHANNEL }}
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
================================================
FILE: .gitignore
================================================
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/packages/**/node_modules
/playgrounds/**/node_modules
# testing
/coverage
/packages/**/coverage
/playgrounds/**/coverage
# logs
*.log
/packages/**/*.log
/playgrounds/**/*.log
# next.js
/.next/
/playgrounds/**/.next/
/out/
/packages/**/out/
/playgrounds/**/out/
# production
/dist
/packages/**/dist
/playgrounds/**/dist
# misc
.DS_Store
*.pem
.cache
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local
# vercel
.vercel
================================================
FILE: .prettierignore
================================================
dist/
node_modules/
coverage/
.next/
================================================
FILE: .swcrc
================================================
{
"minify": false,
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true,
"decorators": false,
"dynamicImport": false
}
}
}
================================================
FILE: CHANGELOG.md
================================================
# Changelog
Each package has its own changelog.
- [@headlessui/react](https://github.com/tailwindlabs/headlessui/blob/main/packages/@headlessui-react/CHANGELOG.md)
- [@headlessui/vue](https://github.com/tailwindlabs/headlessui/blob/main/packages/@headlessui-vue/CHANGELOG.md)
- [@headlessui/tailwindcss](https://github.com/tailwindlabs/headlessui/blob/main/packages/@headlessui-tailwindcss/CHANGELOG.md)
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2020 Tailwind Labs
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
<h3 align="center">
Headless UI
</h3>
<p align="center">
A set of completely unstyled, fully accessible UI components, designed to integrate
beautifully with Tailwind CSS.
</p>
---
## Documentation
For full documentation, visit [headlessui.com](https://headlessui.com).
### Installing the latest version
You can install the latest version by using:
- `npm install @headlessui/react@latest`
- `npm install @headlessui/vue@latest`
### Installing the insiders version
You can install the insiders version (which points to whatever the latest commit on the `main` branch is) by using:
- `npm install @headlessui/react@insiders`
- `npm install @headlessui/vue@insiders`
**Note:** The insiders build doesn't follow semver and therefore doesn't guarantee that the APIs will be the same once they are released.
## Packages
| Name | Version | Downloads |
| :------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------: |
| [`@headlessui/react`](https://github.com/tailwindlabs/headlessui/tree/main/packages/%40headlessui-react) | [](https://www.npmjs.com/package/@headlessui/react) | [](https://www.npmjs.com/package/@headlessui/react) |
| [`@headlessui/vue`](https://github.com/tailwindlabs/headlessui/tree/main/packages/%40headlessui-vue) | [](https://www.npmjs.com/package/@headlessui/vue) | [](https://www.npmjs.com/package/@headlessui/vue) |
| [`@headlessui/tailwindcss`](https://github.com/tailwindlabs/headlessui/tree/main/packages/%40headlessui-tailwindcss) | [](https://www.npmjs.com/package/@headlessui/tailwindcss) | [](https://www.npmjs.com/package/@headlessui/tailwindcss) |
## Community
For help, discussion about best practices, or feature ideas:
[Discuss Headless UI on GitHub](https://github.com/tailwindlabs/headlessui/discussions)
## Contributing
If you're interested in contributing to Headless UI, please read our [contributing docs](https://github.com/tailwindlabs/headlessui/blob/main/.github/CONTRIBUTING.md) **before submitting a pull request**.
================================================
FILE: jest/create-jest-config.cjs
================================================
module.exports = function createJestConfig(root, options) {
let { setupFilesAfterEnv = [], transform = {}, ...rest } = options
return Object.assign(
{
rootDir: root,
setupFilesAfterEnv: [
'<rootDir>../../jest/custom-matchers.ts',
'<rootDir>../../jest/polyfills.ts',
...setupFilesAfterEnv,
],
transform: {
'^.+\\.(t|j)sx?$': '@swc/jest',
...transform,
},
globals: {
__DEV__: true,
},
},
rest
)
}
================================================
FILE: jest/custom-matchers.ts
================================================
import '@testing-library/jest-dom/extend-expect'
// Assuming requestAnimationFrame is roughly 60 frames per second
let frame = 1000 / 60
let amountOfFrames = 2
let formatter = new Intl.NumberFormat('en')
expect.extend({
toBeWithinRenderFrame(actual, expected) {
let min = expected - frame * amountOfFrames
let max = expected + frame * amountOfFrames
let pass = actual >= min && actual <= max
return {
message: pass
? () => {
return `expected ${actual} not to be within range of a frame ${formatter.format(
min
)} - ${formatter.format(max)}`
}
: () => {
return `expected ${actual} not to be within range of a frame ${formatter.format(
min
)} - ${formatter.format(max)}`
},
pass,
}
},
})
================================================
FILE: jest/polyfills.ts
================================================
import { mockAnimationsApi, mockResizeObserver } from 'jsdom-testing-mocks'
mockAnimationsApi() // `Element.prototype.getAnimations` and `CSSTransition` polyfill
mockResizeObserver() // `ResizeObserver` polyfill
// JSDOM Doesn't implement innerText yet: https://github.com/jsdom/jsdom/issues/1245
// So this is a hacky way of implementing it using `textContent`.
// Real implementation doesn't use textContent because:
// > textContent gets the content of all elements, including <script> and <style> elements. In
// > contrast, innerText only shows "human-readable" elements.
// >
// > — https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent#differences_from_innertext
Object.defineProperty(HTMLElement.prototype, 'innerText', {
get() {
return this.textContent
},
set(value) {
this.textContent = value
},
})
// Source: https://github.com/testing-library/react-testing-library/issues/838#issuecomment-735259406
//
// Polyfill the PointerEvent class for JSDOM
class PointerEvent extends Event {
constructor(type, props) {
super(type, props)
if (props.button != null) {
// @ts-expect-error JSDOM doesn't support `button` yet...
this.button = props.button
}
if (props.pointerType != null) {
// @ts-expect-error JSDOM doesn't support `pointerType` yet...
this.pointerType = props.pointerType
}
// @ts-expect-error JSDOM doesn't support `pointerType` yet...
if (this.pointerType === undefined) {
// Fallback to `pointerType` of `'mouse'` if not provided.
// @ts-expect-error JSDOM doesn't support `pointerType` yet...
this.pointerType = 'mouse'
}
}
}
// @ts-expect-error JSDOM doesn't support `PointerEvent` yet...
window.PointerEvent = PointerEvent
================================================
FILE: jest.config.cjs
================================================
module.exports = {
projects: ['<rootDir>/packages/*/jest.config.cjs'],
}
================================================
FILE: package.json
================================================
{
"name": "headlessui",
"version": "0.0.0",
"description": "Headless UI components for various libraries like React and Vue",
"main": "index.js",
"repository": "https://github.com/tailwindlabs/headlessui",
"license": "MIT",
"private": true,
"workspaces": [
"packages/*",
"playgrounds/*"
],
"scripts": {
"react": "npm run --workspace=@headlessui/react",
"react-playground": "npm run --workspace=playground-react dev",
"playground-react": "npm run --workspace=playground-react dev",
"vue": "npm run --workspace=@headlessui/vue",
"playground-vue": "npm run --workspace=playground-vue dev",
"vue-playground": "npm run --workspace=playground-vue dev",
"clean": "npm run clean --workspaces --if-present",
"build": "npm-run-all -p 'react build' 'vue build'",
"test": "./scripts/test.sh",
"lint": "./scripts/lint.sh",
"lint-check": "CI=true ./scripts/lint.sh",
"lint-types": "CI=true npm run lint-types --workspaces --if-present",
"release-channel": "node ./scripts/release-channel.js",
"release-notes": "node ./scripts/release-notes.js",
"package-path": "node ./scripts/package-path.js"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*": "npm run lint"
},
"prettier": {
"printWidth": 100,
"semi": false,
"singleQuote": true,
"trailingComma": "es5",
"plugins": [
"prettier-plugin-organize-imports",
"prettier-plugin-tailwindcss"
],
"overrides": [
{
"files": [
"./playgrounds/react/**/*"
],
"options": {
"tailwindStylesheet": "./playgrounds/react/pages/styles.css"
}
},
{
"files": [
"./playgrounds/vue/**/*"
],
"options": {
"tailwindStylesheet": "./playgrounds/vue/src/styles.css"
}
}
]
},
"devDependencies": {
"@arethetypeswrong/cli": "^0.13.3",
"@swc-node/register": "^1.6.8",
"@swc/core": "^1.2.131",
"@swc/jest": "^0.2.17",
"@testing-library/jest-dom": "^5.16.4",
"@types/node": "^14.14.22",
"esbuild": "^0.17.8",
"fast-glob": "^3.2.11",
"husky": "^4.3.8",
"jest": "26",
"lint-staged": "^12.2.1",
"npm-run-all": "^4.1.5",
"prettier": "^3.1.0",
"prettier-plugin-organize-imports": "^3.2.4",
"prettier-plugin-tailwindcss": "^0.6.11",
"resize-observer-polyfill": "^1.5.1",
"rimraf": "^3.0.2",
"tslib": "^2.3.1",
"typescript": "^5.4.3"
}
}
================================================
FILE: packages/@headlessui-react/CHANGELOG.md
================================================
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Fixed
- Don’t render `<Portal>` while hydrating ([#3825](https://github.com/tailwindlabs/headlessui/pull/3825))
## [2.2.9] - 2025-09-25
### Fixed
- Improve focus management in shadow DOM roots ([#3794](https://github.com/tailwindlabs/headlessui/pull/3794))
- Don't accidentally open the `Combobox` when touching the `ComboboxButton` while dragging on mobile ([#3795](https://github.com/tailwindlabs/headlessui/pull/3795))
- Ensure sibling `Dialog` components are scrollable on mobile ([#3796](https://github.com/tailwindlabs/headlessui/pull/3796))
- Infer `Combobox` type based on `onChange` handler ([#3798](https://github.com/tailwindlabs/headlessui/pull/3798))
- Allow home/end key default behavior inside `ComboboxInput` when `Combobox` is closed ([#3798](https://github.com/tailwindlabs/headlessui/pull/3798))
- Ensure interacting with a `Dialog` on iOS works after interacting with a disallowed area ([#3801](https://github.com/tailwindlabs/headlessui/pull/3801))
- Freeze Listbox values as soon as a value is selected ([#3802](https://github.com/tailwindlabs/headlessui/pull/3802))
- Ensure refs are forwarded when freezing data ([#3390](https://github.com/tailwindlabs/headlessui/pull/3390))
- Do not serialize React components into form fields ([49e9e8e](https://github.com/tailwindlabs/headlessui/commit/49e9e8e54d71b50971af7bc064a62827190e8b36))
## [2.2.8] - 2025-09-12
### Fixed
- Ensure we are not freezing data when the `static` prop is used ([#3779](https://github.com/tailwindlabs/headlessui/pull/3779))
- Ensure `onChange` types are contravariant instead of bivariant ([#3781](https://github.com/tailwindlabs/headlessui/pull/3781))
- Support `<summary>` as a focusable element inside `<details>` ([#3389](https://github.com/tailwindlabs/headlessui/pull/3389))
- Fix `Maximum update depth exceeded` crash when using `transition` prop ([#3782](https://github.com/tailwindlabs/headlessui/pull/3782))
- Ensure pressing `Tab` in the `ComboboxInput`, correctly syncs the input value ([#3785](https://github.com/tailwindlabs/headlessui/pull/3785))
- Ensure `--button-width` and `--input-width` have the latest value ([#3786](https://github.com/tailwindlabs/headlessui/pull/3786))
- Fix 'Invalid prop `data-headlessui-state` supplied to `React.Fragment`' warning ([#3788](https://github.com/tailwindlabs/headlessui/pull/3788))
- Ensure `element` in `ref` callback is always connected when rendering in a `Portal` ([#3789](https://github.com/tailwindlabs/headlessui/pull/3789))
- Ensure form state is up to date when using uncontrolled components ([#3790](https://github.com/tailwindlabs/headlessui/pull/3790))
- Ensure `data-open` on `ComboboxInput` is up to date ([#3791](https://github.com/tailwindlabs/headlessui/pull/3791))
- Ensure changing the `immediate` prop value on the `Combobox` component works as expected ([#3792](https://github.com/tailwindlabs/headlessui/pull/3792))
## [2.2.7] - 2025-07-30
### Fixed
- Fix incorrect double invocation of menu items, listbox options and combobox options ([#3766](https://github.com/tailwindlabs/headlessui/pull/3766))
- Fix memory leak in SSR environment ([#3767](https://github.com/tailwindlabs/headlessui/pull/3767))
- Ensure programmatic `.click()` on `MenuButton` ref works ([#3768](https://github.com/tailwindlabs/headlessui/pull/3768))
- Don't activate hovered items while using the keyboard ([#3769](https://github.com/tailwindlabs/headlessui/pull/3769))
## [2.2.6] - 2025-07-24
### Fixed
- Fix immediately closing Listbox by requiring some cursor movement ([#3762](https://github.com/tailwindlabs/headlessui/pull/3762))
## [2.2.5] - 2025-07-23
### Fixed
- Fix listbox closing immediately after opening on touch devices ([#3755](https://github.com/tailwindlabs/headlessui/pull/3755))
## [2.2.4] - 2025-05-20
### Fixed
- Fix `Combobox` error (unexpected undefined) when using virtual mode ([#3734](https://github.com/tailwindlabs/headlessui/pull/3734))
## [2.2.3] - 2025-05-12
### Added
- Add a quick trigger action to the `Menu`, `Listbox` and `Combobox` components ([#3700](https://github.com/tailwindlabs/headlessui/pull/3700))
### Fixed
- Fix clicking `Label` component should open `<Input type="file">` ([#3707](https://github.com/tailwindlabs/headlessui/pull/3707))
- Ensure clicking on interactive elements inside `Label` component works ([#3709](https://github.com/tailwindlabs/headlessui/pull/3709))
- Fix focus not returned to SVG Element ([#3704](https://github.com/tailwindlabs/headlessui/pull/3704))
- Fix `Listbox` not focusing first or last option on ArrowUp / ArrowDown ([#3721](https://github.com/tailwindlabs/headlessui/pull/3721))
- Performance improvement: only re-render top-level component when nesting components e.g.: `Menu` inside a `Dialog` ([#3722](https://github.com/tailwindlabs/headlessui/pull/3722))
- Fix closing `Menu` when other `Menu` is opened ([#3726](https://github.com/tailwindlabs/headlessui/pull/3726))
## [2.2.2] - 2025-04-17
### Fixed
- Improve `Menu` component performance ([#3685](https://github.com/tailwindlabs/headlessui/pull/3685))
- Improve `Listbox` component performance ([#3688](https://github.com/tailwindlabs/headlessui/pull/3688))
- Open `Menu` and `Listbox` on `mousedown` ([#3689](https://github.com/tailwindlabs/headlessui/pull/3689))
- Fix `Transition` component from incorrectly exposing the `Closing` state ([#3696](https://github.com/tailwindlabs/headlessui/pull/3696))
- Improve `Combobox` component performance ([#3697](https://github.com/tailwindlabs/headlessui/pull/3697))
## [2.2.1] - 2025-04-04
### Added
- Accept `tabIndex` on the `Checkbox` component ([#3645](https://github.com/tailwindlabs/headlessui/pull/3645))
- Accept `tabIndex` on the `RadioGroup` component ([#3646](https://github.com/tailwindlabs/headlessui/pull/3646))
### Fixed
- Use correct `ownerDocument` when using internal `Portal` component ([#3594](https://github.com/tailwindlabs/headlessui/pull/3594))
- Bump `@tanstack/react-virtual` to fix warnings in React 19 projects ([#3588](https://github.com/tailwindlabs/headlessui/pull/3588))
- Fix `aria-invalid` attributes to have a valid `'true'` value ([#3639](https://github.com/tailwindlabs/headlessui/pull/3639))
- Add missing `invalid` prop to `Combobox` component ([#3677](https://github.com/tailwindlabs/headlessui/pull/3677))
- Fix `Unexpected undefined` crash in `Combobox` component with `virtual` mode ([#3678](https://github.com/tailwindlabs/headlessui/pull/3678))
## [2.2.0] - 2024-10-25
### Added
- Add React 19 support ([#3543](https://github.com/tailwindlabs/headlessui/pull/3543))
## [2.1.10] - 2024-10-10
### Fixed
- Use `React.JSX` instead of deprecated global `JSX` ([#3511](https://github.com/tailwindlabs/headlessui/pull/3511))
- Fix crash in `ListboxOptions` when using `as={Fragment}` ([#3513](https://github.com/tailwindlabs/headlessui/pull/3513))
## [2.1.9] - 2024-10-03
### Fixed
- Ensure `Element` is available before polyfilling to prevent crashes in non-browser environments ([#3493](https://github.com/tailwindlabs/headlessui/pull/3493))
- Fix crash when using `instanceof HTMLElement` in some environments ([#3494](https://github.com/tailwindlabs/headlessui/pull/3494))
- Cleanup `process` in Combobox component when using virtualization ([#3495](https://github.com/tailwindlabs/headlessui/pull/3495))
## [2.1.8] - 2024-09-12
### Fixed
- Fix crash when using `as={Fragment}` on `MenuButton`, `ListboxButton`, `DisclosureButton` or `Button` components ([#3478](https://github.com/tailwindlabs/headlessui/pull/3478))
## [2.1.7] - 2024-09-11
### Fixed
- Prevent crash in environments where `Element.prototype.getAnimations` is not available ([#3473](https://github.com/tailwindlabs/headlessui/pull/3473))
## [2.1.6] - 2024-09-09
### Fixed
- Fix `ListboxOptions` being incorrectly marked as `inert` ([#3466](https://github.com/tailwindlabs/headlessui/pull/3466))
- Fix crash when using `DisclosureButton` inside of a `DisclosurePanel` when the `Disclosure` is open by default ([#3465](https://github.com/tailwindlabs/headlessui/pull/3465))
## [2.1.5] - 2024-09-04
### Fixed
- Fix transition bug on Firefox, triggered by clicking the `PopoverButton` in rapid succession ([#3452](https://github.com/tailwindlabs/headlessui/pull/3452))
## [2.1.4] - 2024-09-03
### Fixed
- Fix components not closing properly when using the `transition` prop ([#3448](https://github.com/tailwindlabs/headlessui/pull/3448))
## [2.1.3] - 2024-08-23
### Fixed
- Ensure `Transition` component state doesn't change when it becomes hidden ([#3372](https://github.com/tailwindlabs/headlessui/pull/3372))
- Fix closing components using the `transition` prop, and after scrolling the page ([#3407](https://github.com/tailwindlabs/headlessui/pull/3407))
- Ensure all client components are marked correctly to avoid a crash with React 19 and Turbopack ([#3429](https://github.com/tailwindlabs/headlessui/pull/3429))
## [2.1.2] - 2024-07-05
### Fixed
- Fix prematurely added anchoring styles on `ListboxOptions` ([#3337](https://github.com/tailwindlabs/headlessui/pull/3337))
- Ensure `unmount` on `Dialog` works in combination with the `transition` prop on `DialogBackdrop` and `DialogPanel` components ([#3352](https://github.com/tailwindlabs/headlessui/pull/3352))
- Fix crash in `Combobox` component when in `virtual` mode when options are empty ([#3356](https://github.com/tailwindlabs/headlessui/pull/3356))
- Fix hanging tests when using `anchor` prop ([#3357](https://github.com/tailwindlabs/headlessui/pull/3357))
- Fix `transition` and `focus` prop combination for `PopoverPanel` component ([#3361](https://github.com/tailwindlabs/headlessui/pull/3361))
- Fix outside click in nested portalled `Popover` components ([#3362](https://github.com/tailwindlabs/headlessui/pull/3362))
- Fix restoring focus to correct element when closing `Dialog` component ([#3365](https://github.com/tailwindlabs/headlessui/pull/3365))
- Fix `flushSync` warning for `Combobox` component with `immediate` prop enabled ([#3366](https://github.com/tailwindlabs/headlessui/pull/3366))
## [2.1.1] - 2024-06-26
### Fixed
- Fix issues spreading omitted props onto components ([#3313](https://github.com/tailwindlabs/headlessui/pull/3313))
- Fix initial `anchor="selection"` positioning ([#3324](https://github.com/tailwindlabs/headlessui/pull/3324))
- Fix render prop in `ComboboxOptions` to use `any` instead of `unknown` ([#3327](https://github.com/tailwindlabs/headlessui/pull/3327))
- Fix incorrect `Transition` boundary for `Dialog` component ([#3331](https://github.com/tailwindlabs/headlessui/pull/3331))
## [2.1.0] - 2024-06-21
### Added
- Add ability to render multiple `Dialog` components at once (without nesting them) ([#3242](https://github.com/tailwindlabs/headlessui/pull/3242))
- Add new data-attribute-based transition API ([#3273](https://github.com/tailwindlabs/headlessui/pull/3273), [#3285](https://github.com/tailwindlabs/headlessui/pull/3285), [#3307](https://github.com/tailwindlabs/headlessui/pull/3307), [#3309](https://github.com/tailwindlabs/headlessui/pull/3309), [#3312](https://github.com/tailwindlabs/headlessui/pull/3312))
- Add `DialogBackdrop` component ([#3307](https://github.com/tailwindlabs/headlessui/pull/3307), [#3310](https://github.com/tailwindlabs/headlessui/pull/3310))
- Add `PopoverBackdrop` component to replace `PopoverOverlay` ([#3308](https://github.com/tailwindlabs/headlessui/pull/3308))
### Fixed
- Keep `Combobox` open when clicking scrollbar in `ComboboxOptions` ([#3249](https://github.com/tailwindlabs/headlessui/pull/3249))
- Ensure `ComboboxInput` does not sync with current value while typing ([#3259](https://github.com/tailwindlabs/headlessui/pull/3259))
- Fix visual jitter in `Combobox` component when using native scrollbar ([#3190](https://github.com/tailwindlabs/headlessui/pull/3190))
- Improve UX by freezing `ComboboxOptions` while closing ([#3304](https://github.com/tailwindlabs/headlessui/pull/3304))
- Merge incoming `style` prop on `ComboboxOptions`, `ListboxOptions`, `MenuItems`, and `PopoverPanel` components ([#3250](https://github.com/tailwindlabs/headlessui/pull/3250))
- Prevent focus on `Checkbox` when it is `disabled` ([#3251](https://github.com/tailwindlabs/headlessui/pull/3251))
- Use `useId` instead of React internals (for React 19 compatibility) ([#3254](https://github.com/tailwindlabs/headlessui/pull/3254))
- Cancel outside click behavior on touch devices when scrolling ([#3266](https://github.com/tailwindlabs/headlessui/pull/3266))
- Correctly apply conditional classes when using `Transition` and `TransitionChild` components ([#3303](https://github.com/tailwindlabs/headlessui/pull/3303))
### Changed
- Allow using the `Tab` and `Shift+Tab` keys when the `Listbox` component is open ([#3284](https://github.com/tailwindlabs/headlessui/pull/3284))
## [2.0.4] - 2024-05-25
### Fixed
- [internal] Don’t set a focus fallback for Dialog’s in demo mode ([#3194](https://github.com/tailwindlabs/headlessui/pull/3194))
- Ensure page doesn't scroll down when pressing `Escape` to close the `Dialog` component ([#3218](https://github.com/tailwindlabs/headlessui/pull/3218))
- Fix crash when toggling between `virtual` and non-virtual mode in `Combobox` component ([#3236](https://github.com/tailwindlabs/headlessui/pull/3236))
- Ensure tabbing to a portalled `PopoverPanel` component moves focus inside (without using `PortalGroup`) ([#3239](https://github.com/tailwindlabs/headlessui/pull/3239))
- Only handle form reset when `defaultValue` is used ([#3240](https://github.com/tailwindlabs/headlessui/pull/3240))
### Deprecated
- Mark `SwitchGroup` as deprecated, prefer `Field` instead ([#3232](https://github.com/tailwindlabs/headlessui/pull/3232))
### Changed
- Use native `fieldset` instead of `div` by default for `Fieldset` component ([#3237](https://github.com/tailwindlabs/headlessui/pull/3237))
## [2.0.3] - 2024-05-07
### Fixed
- Make sure disabling demo mode on `Combobox` works ([#3182](hhttps://github.com/tailwindlabs/headlessui/pull/3182))
## [2.0.2] - 2024-05-07
### Fixed
- Improve performance of internal `useInertOthers` hook ([#3181](https://github.com/tailwindlabs/headlessui/pull/3181))
## [2.0.1] - 2024-05-06
### Fixed
- Remove accidental deprecation comments on `DialogPanel` and `DialogTitle` ([#3176](https://github.com/tailwindlabs/headlessui/pull/3176))
## [2.0.0] - 2024-05-06
### Added
- Add new `Checkbox` component ([#2887](https://github.com/tailwindlabs/headlessui/pull/2887), [#2962](https://github.com/tailwindlabs/headlessui/pull/2962))
- Add new `Button` component ([#2887](https://github.com/tailwindlabs/headlessui/pull/2887))
- Add new `Input` component ([#2887](https://github.com/tailwindlabs/headlessui/pull/2887), [#2902](https://github.com/tailwindlabs/headlessui/pull/2902), [#2940](https://github.com/tailwindlabs/headlessui/pull/2940))
- Add new `Textarea` component ([#2887](https://github.com/tailwindlabs/headlessui/pull/2887), [#2902](https://github.com/tailwindlabs/headlessui/pull/2902), [#2940](https://github.com/tailwindlabs/headlessui/pull/2940))
- Add new `Select` component ([#2887](https://github.com/tailwindlabs/headlessui/pull/2887), [#2902](https://github.com/tailwindlabs/headlessui/pull/2902))
- Add new `Fieldset` and `Legend` components ([#2887](https://github.com/tailwindlabs/headlessui/pull/2887))
- Add new `Field`, `Label`, and `Description` components ([#2887](https://github.com/tailwindlabs/headlessui/pull/2887), [#2941](https://github.com/tailwindlabs/headlessui/pull/2941))
- Add new `MenuSection`, `MenuHeading`, and `MenuSeparator` components ([#2887](https://github.com/tailwindlabs/headlessui/pull/2887))
- Add new `ListboxSelectedOption` component ([#2887](https://github.com/tailwindlabs/headlessui/pull/2887))
- Add new `DataInteractive` component ([#2887](https://github.com/tailwindlabs/headlessui/pull/2887))
- Add new `CloseButton` component and `useClose` hook ([#3096](https://github.com/tailwindlabs/headlessui/pull/3096))
- Add new `anchor`, `modal`, and `portal` props to `Combobox`, `Listbox`, `Menu` and `Popover` components ([#2887](https://github.com/tailwindlabs/headlessui/pull/2887), [#3075](https://github.com/tailwindlabs/headlessui/pull/3075), [#3097](https://github.com/tailwindlabs/headlessui/pull/3097), [#3111](https://github.com/tailwindlabs/headlessui/pull/3111), [#3115](https://github.com/tailwindlabs/headlessui/pull/3115), [#3121](https://github.com/tailwindlabs/headlessui/pull/3121), [#3124](https://github.com/tailwindlabs/headlessui/pull/3124), [#3133](https://github.com/tailwindlabs/headlessui/pull/3133), [#3138](https://github.com/tailwindlabs/headlessui/pull/3138), [#3148](https://github.com/tailwindlabs/headlessui/pull/3148), [#3152](https://github.com/tailwindlabs/headlessui/pull/3152), [#3154](https://github.com/tailwindlabs/headlessui/pull/3154), [#3157](https://github.com/tailwindlabs/headlessui/pull/3157))
- Add new `autoFocus` prop to focusable components ([#2887](https://github.com/tailwindlabs/headlessui/pull/2887))
- Add new `virtual` prop to `Combobox` component ([#2779](https://github.com/tailwindlabs/headlessui/pull/2779), [#3128](https://github.com/tailwindlabs/headlessui/pull/3128), [#3160](https://github.com/tailwindlabs/headlessui/pull/3160), [#3161](https://github.com/tailwindlabs/headlessui/pull/3161), [#3163](https://github.com/tailwindlabs/headlessui/pull/3163))
- Add new `onClose` prop to `Combobox` component ([#3122](https://github.com/tailwindlabs/headlessui/pull/3122))
- Add new `immediate` prop to `Combobox` for immediately opening the Combobox when the `input` receives focus ([#2686](https://github.com/tailwindlabs/headlessui/pull/2686))
- Add new `--button-width` CSS variable on the `ListboxOptions`, `MenuItems`, and `PopoverPanel` components ([#2887](https://github.com/tailwindlabs/headlessui/pull/2887), [#3058](https://github.com/tailwindlabs/headlessui/pull/3058))
- Add new `--input-width` and `--button-width` CSS variables on the `ComboboxOptions` component ([#3057](https://github.com/tailwindlabs/headlessui/pull/3057))
- Add new `data-*` attributes as an alternative to the existing `data-headlessui-state` attribute ([#2887](https://github.com/tailwindlabs/headlessui/pull/2887), [#3035](https://github.com/tailwindlabs/headlessui/pull/3035), [#3061](https://github.com/tailwindlabs/headlessui/pull/3061))
### Fixed
- Fix scroll-locking on iOS ([#2891](https://github.com/tailwindlabs/headlessui/pull/2891))
- Fix cancellation of events when using `disabled` or `aria-disabled` attributes ([#2890](https://github.com/tailwindlabs/headlessui/pull/2890))
- Fix unnecessary execution of the `displayValue` callback in `ComboboxInput` component ([#3048](https://github.com/tailwindlabs/headlessui/pull/3048))
- Fix types for `multiple` prop in `Combobox` component ([#3099](https://github.com/tailwindlabs/headlessui/pull/3099))
- Fix focus handling in `ComboboxInput` component ([#3065](https://github.com/tailwindlabs/headlessui/pull/3065), [#3073](https://github.com/tailwindlabs/headlessui/pull/3073))
- Fix enter transitions in `Transition` component ([#3074](https://github.com/tailwindlabs/headlessui/pull/3074))
- Fix focus handling in `ListboxOptions` and `MenuItems` components ([#3112](https://github.com/tailwindlabs/headlessui/pull/3112))
- Fix horizontal scrolling inside the `Dialog` component ([#2889](https://github.com/tailwindlabs/headlessui/pull/2889))
- Don’t cancel `touchmove` on `input` elements inside a dialog ([#3166](https://github.com/tailwindlabs/headlessui/pull/3166))
### Changed
- Require React 18 ([#2887](https://github.com/tailwindlabs/headlessui/pull/2887), [#3092](https://github.com/tailwindlabs/headlessui/pull/3092), [#3131](https://github.com/tailwindlabs/headlessui/pull/3131))
- Always render hidden form input fields for `Checkbox`, `Switch`, and `RadioGroup` components ([#3095](https://github.com/tailwindlabs/headlessui/pull/3095))
- Deprecate the `RadioGroup.Option` component in favor of new `Radio` component ([#2887](https://github.com/tailwindlabs/headlessui/pull/2887))
- Deprecate the `active` prop in favor of new `focus` prop ([#2887](https://github.com/tailwindlabs/headlessui/pull/2887))
- Dialog is now focused by default instead of the first focusable element ([#2887](https://github.com/tailwindlabs/headlessui/pull/2887))
- Change default tags for `ListboxOptions`, `ListboxOption`, `ComboboxOptions`, `ComboboxOption`, and `TabGroup` components ([#3109](https://github.com/tailwindlabs/headlessui/pull/3109))
- Change default tag from `div` to `Fragment` on `Transition` components ([#3110](https://github.com/tailwindlabs/headlessui/pull/3110), [#3147](https://github.com/tailwindlabs/headlessui/pull/3147))
- Allow `Combobox` component to have a `null` value ([#3064](https://github.com/tailwindlabs/headlessui/pull/3064), [#3100](https://github.com/tailwindlabs/headlessui/pull/3100))
- Attempt form submission when pressing enter on the `ListboxButton` component ([#2972](https://github.com/tailwindlabs/headlessui/pull/2972))
- Deprecate the `entered` prop on the `Transition` component ([#3089](https://github.com/tailwindlabs/headlessui/pull/3089))
- Deprecate dot notation for components ([#2887](https://github.com/tailwindlabs/headlessui/pull/2887), [#3170](https://github.com/tailwindlabs/headlessui/pull/3170))
- Add frozen value to `ComboboxOptions` component ([#3126](https://github.com/tailwindlabs/headlessui/pull/3126))
- Remove deprecated `DialogBackdrop` and `DialogOverlay` components ([#3171](https://github.com/tailwindlabs/headlessui/pull/3171))
## [1.7.19] - 2024-04-15
### Fixed
- Make sure panels re-register when IDs are calculated in React < 18 ([#2883](https://github.com/tailwindlabs/headlessui/pull/2883))
- Expose `disabled` state on `Tab` component ([#2918](https://github.com/tailwindlabs/headlessui/pull/2918))
- Prevent default behavior when clicking outside of a `Dialog.Panel` ([#2919](https://github.com/tailwindlabs/headlessui/pull/2919))
- Add `hidden` attribute to internal `Hidden` component when the `Features.Hidden` feature is used ([#2955](https://github.com/tailwindlabs/headlessui/pull/2955))
- Allow setting custom `tabIndex` on the `Switch` component ([#2966](https://github.com/tailwindlabs/headlessui/pull/2966))
- Forward `disabled` state to hidden inputs in form-like components ([#3004](https://github.com/tailwindlabs/headlessui/pull/3004))
- Respect `selectedIndex` for controlled `Tab` components ([#3037](https://github.com/tailwindlabs/headlessui/pull/3037))
## [2.0.0-alpha.4] - 2024-01-03
### Fixed
- Ensure `Input`, `Select` and `Textarea` expose `Ref` related types ([#2902](https://github.com/tailwindlabs/headlessui/pull/2902))
## [2.0.0-alpha.3] - 2023-12-20
### Fixed
- Further fine tune scroll locking on iOS ([#2891](https://github.com/tailwindlabs/headlessui/pull/2891))
## [2.0.0-alpha.2] - 2023-12-20
### Fixed
- Allow horizontal scrolling inside the `Dialog` component ([#2889](https://github.com/tailwindlabs/headlessui/pull/2889))
- Improve cancellation of events when using `disabled` or `aria-disabled` attributes ([#2890](https://github.com/tailwindlabs/headlessui/pull/2890))
## [2.0.0-alpha.1] - 2023-12-20
### Added
- Add `immediate` prop to `Combobox` for immediately opening the Combobox when the `input` receives focus ([#2686](https://github.com/tailwindlabs/headlessui/pull/2686))
- Add `virtual` prop to `Combobox` component ([#2779](https://github.com/tailwindlabs/headlessui/pull/2779))
- Add new `Checkbox` component
- Add new `Radio` component as an alternative to the existing `RadioGroup.Option` component
- Add new `Button` component
- Add new `Input` component
- Add new `Textarea` component
- Add new `Select` component
- Add new `Field`, `Label`, `Description`, `Fieldset` and `Legend` components
- Add new `DataInteractive` component
- Add new `anchor` and `modal` prop to `ComboboxOptions`, `ListboxOptions`, `MenuItems` and `PopoverPanel` components
- Add new `ListboxSelectedOption` component
- Add new `MenuSection`, `MenuHeading`, and `MenuSeparator` components
- Add new simplified `data-*` attributes as an alternative to the existing `data-headlessui-state="..."` attribute
- Add `autoFocus` prop on focusable components (which maps to `data-autofocus`)
### Changed
- Bumped to React and React DOM 18
- Dialog is focused by default instead of the first focusable element (unless an element exists with a `data-autofocus` in the dialog)
## [1.7.18] - 2024-01-08
### Fixed
- Don't call `Dialog`'s `onClose` twice on mobile devices ([#2690](https://github.com/tailwindlabs/headlessui/pull/2690))
- Lazily resolve default containers in `Dialog` ([#2697](https://github.com/tailwindlabs/headlessui/pull/2697))
- Ensure hidden `Tab.Panel` components are hidden from the accessibility tree ([#2708](https://github.com/tailwindlabs/headlessui/pull/2708))
- Add support for `role="alertdialog"` to `Dialog` component ([#2709](https://github.com/tailwindlabs/headlessui/pull/2709))
- Ensure blurring the `Combobox.Input` component closes the `Combobox` ([#2712](https://github.com/tailwindlabs/headlessui/pull/2712))
- Allow changes to the `className` prop when the `Transition` component is currently not transitioning ([#2722](https://github.com/tailwindlabs/headlessui/pull/2722))
- Export (internal-only) component interfaces for TypeScript compiler ([#2313](https://github.com/tailwindlabs/headlessui/pull/2313))
- Fix infinite render-loop for `Disclosure.Panel` and `Popover.Panel` when `as={Fragment}` ([#2760](https://github.com/tailwindlabs/headlessui/pull/2760))
- Fix VoiceOver bug for `Listbox` component in Chrome ([#2824](https://github.com/tailwindlabs/headlessui/pull/2824))
- Fix outside click detection when component is mounted in the Shadow DOM ([#2866](https://github.com/tailwindlabs/headlessui/pull/2866))
- Fix CJS types ([#2880](https://github.com/tailwindlabs/headlessui/pull/2880))
- Fix error when transition classes contain new lines ([#2871](https://github.com/tailwindlabs/headlessui/pull/2871))
- Improve iOS locking ([7721aca](https://github.com/tailwindlabs/headlessui/commit/7721acaecea2008c2d7e8ab29cc8d45b70bb021e))
## [1.7.17] - 2023-08-17
### Fixed
- Use correct value when resetting `<Listbox multiple>` and `<Combobox multiple>` ([#2626](https://github.com/tailwindlabs/headlessui/pull/2626))
- Render `MainTreeNode` in `Popover.Group` component only ([#2634](https://github.com/tailwindlabs/headlessui/pull/2634))
- Disable smooth scrolling when opening/closing `Dialog` components on iOS ([#2635](https://github.com/tailwindlabs/headlessui/pull/2635))
- Don't assume `Tab` components are available when setting the next index ([#2642](https://github.com/tailwindlabs/headlessui/pull/2642))
- Fix incorrectly focused `Combobox.Input` component on page load ([#2654](https://github.com/tailwindlabs/headlessui/pull/2654))
- Ensure `appear` works using the `Transition` component (even when used with SSR) ([#2646](https://github.com/tailwindlabs/headlessui/pull/2646))
- Improve resetting values when using the `nullable` prop on the `Combobox` component ([#2660](https://github.com/tailwindlabs/headlessui/pull/2660))
- Fix hydration of components inside `Suspense` ([#2663](https://github.com/tailwindlabs/headlessui/pull/2663))
- Prevent scrolling when focusing a tab ([#2674](https://github.com/tailwindlabs/headlessui/pull/2674))
## [1.7.16] - 2023-07-27
### Fixed
- Ensure the caret is in a consistent position when syncing the `Combobox.Input` value ([#2568](https://github.com/tailwindlabs/headlessui/pull/2568))
- Improve "outside click" behavior in combination with 3rd party libraries ([#2572](https://github.com/tailwindlabs/headlessui/pull/2572))
- Ensure IME works on Android devices ([#2580](https://github.com/tailwindlabs/headlessui/pull/2580))
- Calculate `aria-expanded` purely based on the open/closed state ([#2610](https://github.com/tailwindlabs/headlessui/pull/2610))
- Submit form on `Enter` even if no submit-like button was found ([#2613](https://github.com/tailwindlabs/headlessui/pull/2613))
## [1.7.15] - 2023-06-01
### Added
- [internal] add demo mode to `Menu` and `Popover` components ([#2448](https://github.com/tailwindlabs/headlessui/pull/2448))
### Fixed
- Ensure `FocusTrap` is only active when the given `enabled` value is `true` ([#2456](https://github.com/tailwindlabs/headlessui/pull/2456))
- Stop `<Transition appear>` from overwriting classes on re-render ([#2457](https://github.com/tailwindlabs/headlessui/pull/2457))
- Improve control over `Menu` and `Listbox` options while searching ([#2471](https://github.com/tailwindlabs/headlessui/pull/2471))
- Consider clicks inside iframes to be "outside" ([#2485](https://github.com/tailwindlabs/headlessui/pull/2485))
- Ensure moving focus within a `Portal` component, does not close the `Popover` component ([#2492](https://github.com/tailwindlabs/headlessui/pull/2492))
### Changed
- Move `types` condition to the front ([#2469](https://github.com/tailwindlabs/headlessui/pull/2469))
## [1.7.14] - 2023-04-12
### Fixed
- Fix focus styles showing up when using the mouse ([#2347](https://github.com/tailwindlabs/headlessui/pull/2347))
- Fix "Can't perform a React state update on an unmounted component." when using the `Transition` component ([#2374](https://github.com/tailwindlabs/headlessui/pull/2374))
- Add `FocusTrap` event listeners once document has loaded ([#2389](https://github.com/tailwindlabs/headlessui/pull/2389))
- Fix `className` hydration for `<Transition appear>` ([#2390](https://github.com/tailwindlabs/headlessui/pull/2390))
- Improve `Combobox` types to improve false positives ([#2411](https://github.com/tailwindlabs/headlessui/pull/2411))
- Merge `className` correctly when it’s a function ([#2412](https://github.com/tailwindlabs/headlessui/pull/2412))
- Correctly handle IME composition in `Combobox.Input` ([#2426](https://github.com/tailwindlabs/headlessui/pull/2426))
### Added
- Add `form` prop to form-like components such as `RadioGroup`, `Switch`, `Listbox`, and `Combobox` ([#2356](https://github.com/tailwindlabs/headlessui/pull/2356))
## [1.7.13] - 2023-03-03
### Fixed
- Ensure `Transition` component completes if nothing is transitioning ([#2318](https://github.com/tailwindlabs/headlessui/pull/2318))
- Enable native label behavior for `Switch` where possible ([#2265](https://github.com/tailwindlabs/headlessui/pull/2265))
- Allow root containers from the `Dialog` component in the `FocusTrap` component ([#2322](https://github.com/tailwindlabs/headlessui/pull/2322))
- Fix `XYZPropsWeControl` and cleanup internal TypeScript types ([#2329](https://github.com/tailwindlabs/headlessui/pull/2329))
- Fix invalid warning when using multiple `Popover.Button` components inside a `Popover.Panel` ([#2333](https://github.com/tailwindlabs/headlessui/pull/2333))
- Fix restore focus to buttons in Safari, when `Dialog` component closes ([#2326](https://github.com/tailwindlabs/headlessui/pull/2326))
## [1.7.12] - 2023-02-24
### Added
- Add explicit props types for every component ([#2282](https://github.com/tailwindlabs/headlessui/pull/2282))
### Fixed
- Ensure the main tree and parent `Dialog` components are marked as `inert` ([#2290](https://github.com/tailwindlabs/headlessui/pull/2290))
- Fix nested `Popover` components not opening ([#2293](https://github.com/tailwindlabs/headlessui/pull/2293))
- Make React types more compatible with other libraries ([#2282](https://github.com/tailwindlabs/headlessui/pull/2282))
- Fix `Dialog` cleanup when the `Dialog` becomes hidden ([#2303](https://github.com/tailwindlabs/headlessui/pull/2303))
## [1.7.11] - 2023-02-15
### Fixed
- Ensure we handle `null` values for the `dataRef` correctly ([#2258](https://github.com/tailwindlabs/headlessui/pull/2258))
- Move `aria-multiselectable` to `[role=listbox]` in the `Combobox` component ([#2271](https://github.com/tailwindlabs/headlessui/pull/2271))
- Re-focus `Combobox.Input` when a `Combobox.Option` is selected ([#2272](https://github.com/tailwindlabs/headlessui/pull/2272))
- Ensure we reset the `activeOptionIndex` if the active option is unmounted ([#2274](https://github.com/tailwindlabs/headlessui/pull/2274))
- Improve `Ref` type for forwarded `Switch`'s ref ([#2277](https://github.com/tailwindlabs/headlessui/pull/2277))
- Start cleanup phase of the `Dialog` component when going into the `Closing` state ([#2264](https://github.com/tailwindlabs/headlessui/pull/2264))
## [1.7.10] - 2023-02-06
### Fixed
- Revert "Use the `import * as React from 'react'` pattern ([#2242](https://github.com/tailwindlabs/headlessui/pull/2242))
## [1.7.9] - 2023-02-03
### Fixed
- Fix SSR tab hydration when using Strict Mode in development ([#2231](https://github.com/tailwindlabs/headlessui/pull/2231))
- Don't break overflow when multiple dialogs are open at the same time ([#2215](https://github.com/tailwindlabs/headlessui/pull/2215))
- Fix "This `Suspense` boundary received an update before it finished hydrating" error in the `Disclosure` component ([#2238](https://github.com/tailwindlabs/headlessui/pull/2238))
- Use the `import * as React from 'react'` pattern ([#2242](https://github.com/tailwindlabs/headlessui/pull/2242))
## [1.7.8] - 2023-01-27
### Fixed
- Fix SSR tab rendering on React 17 ([#2102](https://github.com/tailwindlabs/headlessui/pull/2102))
- Fix arrow key handling in `Tab` (after DOM order changes) ([#2145](https://github.com/tailwindlabs/headlessui/pull/2145))
- Fix false positive warning about using multiple `Popover.Button` components ([#2146](https://github.com/tailwindlabs/headlessui/pull/2146))
- Fix `Tab` key with non focusable elements in `Popover.Panel` ([#2147](https://github.com/tailwindlabs/headlessui/pull/2147))
- Fix false positive warning when using `Popover.Button` in React 17 ([#2163](https://github.com/tailwindlabs/headlessui/pull/2163))
- Fix `failed to removeChild on Node` bug ([#2164](https://github.com/tailwindlabs/headlessui/pull/2164))
- Don’t overwrite classes during SSR when rendering fragments ([#2173](https://github.com/tailwindlabs/headlessui/pull/2173))
- Improve `Combobox` accessibility ([#2153](https://github.com/tailwindlabs/headlessui/pull/2153))
- Fix crash when reading `headlessuiFocusGuard` of `relatedTarget` in the `FocusTrap` component ([#2203](https://github.com/tailwindlabs/headlessui/pull/2203))
- Fix `FocusTrap` in `Dialog` when there is only 1 focusable element ([#2172](https://github.com/tailwindlabs/headlessui/pull/2172))
- Improve `Tabs` wrapping around when controlling the component and overflowing the `selectedIndex` ([#2213](https://github.com/tailwindlabs/headlessui/pull/2213))
- Fix `shadow-root` bug closing `Dialog` containers ([#2217](https://github.com/tailwindlabs/headlessui/pull/2217))
### Added
- Allow setting `tabIndex` on the `Tab.Panel` ([#2214](https://github.com/tailwindlabs/headlessui/pull/2214))
## [1.7.7] - 2022-12-16
### Fixed
- Improve scroll restoration after `Dialog` closes ([b20e48dd](https://github.com/tailwindlabs/headlessui/commit/b20e48dde3c37867f3900be3d475f9ac2058b587))
## [1.7.6] - 2022-12-15
### Fixed
- Fix regression where `displayValue` crashes ([#2087](https://github.com/tailwindlabs/headlessui/pull/2087))
- Fix `displayValue` syncing when `Combobox.Input` is unmounted and re-mounted in different trees ([#2090](https://github.com/tailwindlabs/headlessui/pull/2090))
- Fix FocusTrap escape due to strange tabindex values ([#2093](https://github.com/tailwindlabs/headlessui/pull/2093))
- Improve scroll locking on iOS ([#2100](https://github.com/tailwindlabs/headlessui/pull/2100), [28234b0e](https://github.com/tailwindlabs/headlessui/commit/28234b0e37633c0e2ec62ac8bd12320207a5d02b))
## [1.7.5] - 2022-12-08
### Fixed
- Reset form-like components when the parent `form` resets ([#2004](https://github.com/tailwindlabs/headlessui/pull/2004))
- Add warning when using `Popover.Button` multiple times ([#2007](https://github.com/tailwindlabs/headlessui/pull/2007))
- Ensure Popover doesn't crash when `focus` is going to `window` ([#2019](https://github.com/tailwindlabs/headlessui/pull/2019))
- Ensure `shift+home` and `shift+end` works as expected in the `Combobox.Input` component ([#2024](https://github.com/tailwindlabs/headlessui/pull/2024))
- Improve syncing of the `Combobox.Input` value ([#2042](https://github.com/tailwindlabs/headlessui/pull/2042))
- Fix crash when using `multiple` mode without `value` prop (uncontrolled) for `Listbox` and `Combobox` components ([#2058](https://github.com/tailwindlabs/headlessui/pull/2058))
- Apply `enter` and `enterFrom` classes in SSR for `Transition` component ([#2059](https://github.com/tailwindlabs/headlessui/pull/2059))
- Allow passing in your own `id` prop ([#2060](https://github.com/tailwindlabs/headlessui/pull/2060))
- Fix `Dialog` unmounting problem due to incorrect `transitioncancel` event in the `Transition` component on Android ([#2071](https://github.com/tailwindlabs/headlessui/pull/2071))
- Ignore pointer events in Listbox, Menu, and Combobox when cursor hasn't moved ([#2069](https://github.com/tailwindlabs/headlessui/pull/2069))
- Allow clicks inside dialog panel when target is inside shadow root ([#2079](https://github.com/tailwindlabs/headlessui/pull/2079))
## [1.7.4] - 2022-11-03
### Fixed
- Fix `<Popover.Button as={Fragment} />` crash ([#1889](https://github.com/tailwindlabs/headlessui/pull/1889))
- Expose `close` function for `Menu` and `Menu.Item` components ([#1897](https://github.com/tailwindlabs/headlessui/pull/1897))
- Fix `useOutsideClick`, add improvements for ShadowDOM ([#1914](https://github.com/tailwindlabs/headlessui/pull/1914))
- Fire `Combobox.Input`'s `onChange` handler when changing the value internally ([#1916](https://github.com/tailwindlabs/headlessui/pull/1916))
- Add `client-only` to mark everything as client components ([#1981](https://github.com/tailwindlabs/headlessui/pull/1981))
### Added
- Warn when changing components between controlled and uncontrolled ([#1878](https://github.com/tailwindlabs/headlessui/issues/1878))
## [1.7.3] - 2022-09-30
### Fixed
- Improve `Portal` detection for `Popover` components ([#1842](https://github.com/tailwindlabs/headlessui/pull/1842))
- Fix `useOutsideClick` swallowing events inside ShadowDOM ([#1876](https://github.com/tailwindlabs/headlessui/pull/1876))
- Fix `Tab` incorrectly activating on `focus` event ([#1887](https://github.com/tailwindlabs/headlessui/pull/1887))
## [1.7.2] - 2022-09-15
### Fixed
- Prevent option selection in `Combobox.Input` while composing ([#1850](https://github.com/tailwindlabs/headlessui/issues/1850))
- Ensure we handle the `static` prop in `Tab.Panel` components correctly ([#1856](https://github.com/tailwindlabs/headlessui/pull/1856))
## [1.7.1] - 2022-09-12
### Fixed
- Improve iOS scroll locking ([#1830](https://github.com/tailwindlabs/headlessui/pull/1830))
- Add `<fieldset disabled>` check to radio group options in React ([#1835](https://github.com/tailwindlabs/headlessui/pull/1835))
- Ensure `Tab` order stays consistent, and the currently active `Tab` stays active ([#1837](https://github.com/tailwindlabs/headlessui/pull/1837))
- Ensure `Combobox.Label` is properly linked when rendered after `Combobox.Button` and `Combobox.Input` components ([#1838](https://github.com/tailwindlabs/headlessui/pull/1838))
- Remove `forceRerender` from `Tab` component ([#1846](https://github.com/tailwindlabs/headlessui/pull/1846))
## [1.7.0] - 2022-09-06
### Added
- Add `by` prop for `Listbox`, `Combobox` and `RadioGroup` ([#1482](https://github.com/tailwindlabs/headlessui/pull/1482), [#1717](https://github.com/tailwindlabs/headlessui/pull/1717), [#1814](https://github.com/tailwindlabs/headlessui/pull/1814), [#1815](https://github.com/tailwindlabs/headlessui/pull/1815))
- Make form components uncontrollable ([#1683](https://github.com/tailwindlabs/headlessui/pull/1683))
- Add `@headlessui/tailwindcss` plugin ([#1487](https://github.com/tailwindlabs/headlessui/pull/1487))
### Fixed
- Fixed SSR support on Deno ([#1671](https://github.com/tailwindlabs/headlessui/pull/1671))
- Don’t close dialog when opened during mouse up event ([#1667](https://github.com/tailwindlabs/headlessui/pull/1667))
- Don’t close dialog when drag ends outside dialog ([#1667](https://github.com/tailwindlabs/headlessui/pull/1667))
- Fix outside clicks to close dialog when nested, unopened dialogs are present ([#1667](https://github.com/tailwindlabs/headlessui/pull/1667))
- Close `Menu` component when using `tab` key ([#1673](https://github.com/tailwindlabs/headlessui/pull/1673))
- Resync input when display value changes ([#1679](https://github.com/tailwindlabs/headlessui/pull/1679), [#1755](https://github.com/tailwindlabs/headlessui/pull/1755))
- Ensure controlled `Tabs` don't change automagically ([#1680](https://github.com/tailwindlabs/headlessui/pull/1680))
- Don't scroll lock when a Transition + Dialog is mounted but hidden ([#1681](https://github.com/tailwindlabs/headlessui/pull/1681))
- Allow `Popover` `close` to be passed directly to `onClick` handlers ([#1696](https://github.com/tailwindlabs/headlessui/pull/1696))
- Improve outside click on Safari iOS ([#1712](https://github.com/tailwindlabs/headlessui/pull/1712))
- Improve event handler merging ([#1715](https://github.com/tailwindlabs/headlessui/pull/1715))
- Fix incorrect scrolling to the bottom when opening a `Dialog` ([#1716](https://github.com/tailwindlabs/headlessui/pull/1716))
- Improve `Combobox` re-opening keyboard issue on mobile ([#1732](https://github.com/tailwindlabs/headlessui/pull/1732))
- Ensure `Disclosure.Panel` is properly linked ([#1747](https://github.com/tailwindlabs/headlessui/pull/1747))
- Only select the active option when using "singular" mode when pressing `tab` in the `Combobox` component ([#1750](https://github.com/tailwindlabs/headlessui/pull/1750))
- Improve the types of the `Combobox` component ([#1761](https://github.com/tailwindlabs/headlessui/pull/1761))
- Only restore focus to the `Menu.Button` if necessary when activating a `Menu.Option` ([#1782](https://github.com/tailwindlabs/headlessui/pull/1782))
- Don't scroll when wrapping around in focus trap ([#1789](https://github.com/tailwindlabs/headlessui/pull/1789))
- Fix `Transition` component's incorrect cleanup and order of events ([#1803](https://github.com/tailwindlabs/headlessui/pull/1803))
- Ensure enter transitions work when using `unmount={false}` ([#1811](https://github.com/tailwindlabs/headlessui/pull/1811))
- Improve accessibility when announcing `Listbox.Option` and `Combobox.Option` components ([#1812](https://github.com/tailwindlabs/headlessui/pull/1812))
- Fix `ref` stealing from children ([#1820](https://github.com/tailwindlabs/headlessui/pull/1820))
- Expose the `value` from the `Combobox` and `Listbox` components render prop ([#1822](https://github.com/tailwindlabs/headlessui/pull/1822))
- Improve `scroll lock` on iOS ([#1824](https://github.com/tailwindlabs/headlessui/pull/1824))
- Fix maximum call stack size exceeded error on `Tab` component when using `as={Fragment}` ([#1826](https://github.com/tailwindlabs/headlessui/pull/1826))
- Fix "blank" screen on initial load of `Transition` component ([#1823](https://github.com/tailwindlabs/headlessui/pull/1823))
## [1.6.6] - 2022-07-07
### Fixed
- Ensure `CMD`+`Backspace` works in nullable mode for `Combobox` component ([#1617](https://github.com/tailwindlabs/headlessui/pull/1617))
## [1.6.5] - 2022-06-20
### Fixed
- Fix incorrect transitionend/transitioncancel events for the Transition component ([#1537](https://github.com/tailwindlabs/headlessui/pull/1537))
- Improve outside click of `Dialog` component ([#1546](https://github.com/tailwindlabs/headlessui/pull/1546))
- Detect outside clicks from within `iframe` elements ([#1552](https://github.com/tailwindlabs/headlessui/pull/1552))
- Improve Combobox input cursor position ([#1574](https://github.com/tailwindlabs/headlessui/pull/1574))
- Fix scrolling issue in `Tab` component when using arrow keys ([#1584](https://github.com/tailwindlabs/headlessui/pull/1584))
## [1.6.4] - 2022-05-29
### Fixed
- Ensure `Escape` propagates correctly in `Combobox` component ([#1511](https://github.com/tailwindlabs/headlessui/pull/1511))
- Remove leftover code in Combobox component ([#1514](https://github.com/tailwindlabs/headlessui/pull/1514))
- Fix event handlers with arity > 1 ([#1515](https://github.com/tailwindlabs/headlessui/pull/1515))
- Fix transition `enter` bug ([#1519](https://github.com/tailwindlabs/headlessui/pull/1519))
- Fix render prop data in `RadioGroup` component ([#1522](https://github.com/tailwindlabs/headlessui/pull/1522))
## [1.6.3] - 2022-05-25
### Fixed
- Allow to override the `type` on the `Combobox.Input` ([#1476](https://github.com/tailwindlabs/headlessui/pull/1476))
- Ensure the the `<Popover.Panel focus>` closes correctly ([#1477](https://github.com/tailwindlabs/headlessui/pull/1477))
- Only render the `FocusSentinel` if required in the `Tabs` component ([#1493](https://github.com/tailwindlabs/headlessui/pull/1493))
- Ensure the Transition stops once DOM Nodes are hidden ([#1500](https://github.com/tailwindlabs/headlessui/pull/1500))
## [1.6.2] - 2022-05-19
### Fixed
- Fix closing of `Popover.Panel` in React 18 ([#1409](https://github.com/tailwindlabs/headlessui/pull/1409))
- Ignore `Escape` when event got prevented in `Dialog` component ([#1424](https://github.com/tailwindlabs/headlessui/pull/1424))
- Improve `FocusTrap` behavior ([#1432](https://github.com/tailwindlabs/headlessui/pull/1432))
- Simplify `Popover` Tab logic by using sentinel nodes instead of keydown event interception ([#1440](https://github.com/tailwindlabs/headlessui/pull/1440))
- Ensure the `Popover.Panel` is clickable without closing the `Popover` ([#1443](https://github.com/tailwindlabs/headlessui/pull/1443))
- Improve "Scroll lock" scrollbar width for `Dialog` component ([#1457](https://github.com/tailwindlabs/headlessui/pull/1457))
- Make the `ref` optional in the `Popover` component ([#1465](https://github.com/tailwindlabs/headlessui/pull/1465))
- Ensure the `ref` is forwarded on the `Transition.Child` component ([#1473](https://github.com/tailwindlabs/headlessui/pull/1473))
## [1.6.1] - 2022-05-03
### Fixed
- Fix hydration issue with `Tab` component ([#1393](https://github.com/tailwindlabs/headlessui/pull/1393))
## [1.6.0] - 2022-04-25
### Fixed
- Ensure that you can add the `ref` prop to all components ([#1116](https://github.com/tailwindlabs/headlessui/pull/1116))
- Ensure links are triggered inside `Popover.Panel` components ([#1153](https://github.com/tailwindlabs/headlessui/pull/1153))
- Improve SSR for `Tab` component ([#1155](https://github.com/tailwindlabs/headlessui/pull/1155))
- Fix `hover` scroll issue in `Listbox`, `Combobox` and `Menu` components ([#1161](https://github.com/tailwindlabs/headlessui/pull/1161))
- Guarantee DOM sort order when performing `Listbox`, `Combobox` and `Menu` actions ([#1168](https://github.com/tailwindlabs/headlessui/pull/1168))
- Fix `Transition` flickering issue ([#1118](https://github.com/tailwindlabs/headlessui/pull/1118))
- Improve outside click support ([#1175](https://github.com/tailwindlabs/headlessui/pull/1175))
- Ensure that `appear` prop on the `Transition` component works regardless of multiple rerenders ([#1179](https://github.com/tailwindlabs/headlessui/pull/1179))
- Reset `Combobox.Input` when the value gets reset ([#1181](https://github.com/tailwindlabs/headlessui/pull/1181))
- Fix double `beforeEnter` callback on the `Transition` component caused by SSR ([#1183](https://github.com/tailwindlabs/headlessui/pull/1183))
- Adjust active `item`/`option` index on `Listbox`, `Combobox` and `Menu` components ([#1184](https://github.com/tailwindlabs/headlessui/pull/1184))
- Only activate the `Tab` on mouseup ([#1192](https://github.com/tailwindlabs/headlessui/pull/1192))
- Ignore "outside click" on removed elements ([#1193](https://github.com/tailwindlabs/headlessui/pull/1193))
- Remove `focus()` from `Listbox.Option` ([#1218](https://github.com/tailwindlabs/headlessui/pull/1218))
- Improve some internal code ([#1221](https://github.com/tailwindlabs/headlessui/pull/1221))
- Use `ownerDocument` instead of `document` ([#1158](https://github.com/tailwindlabs/headlessui/pull/1158))
- Ensure focus trapping plays well with the `Tab` and `Dialog` components ([#1231](https://github.com/tailwindlabs/headlessui/pull/1231))
- Improve syncing of `Combobox.Input` value ([#1248](https://github.com/tailwindlabs/headlessui/pull/1248))
- Fix tree-shaking support ([#1247](https://github.com/tailwindlabs/headlessui/pull/1247))
- Stop propagation on the `Popover.Button` ([#1263](https://github.com/tailwindlabs/headlessui/pull/1263))
- Fix incorrect `active` option in the `Listbox` and `Combobox` components ([#1264](https://github.com/tailwindlabs/headlessui/pull/1264))
- Properly merge incoming props ([#1265](https://github.com/tailwindlabs/headlessui/pull/1265))
- Fix incorrect closing while interacting with third party libraries in `Dialog` component ([#1268](https://github.com/tailwindlabs/headlessui/pull/1268))
- Mimic browser select on focus when navigating the `Tab` component ([#1272](https://github.com/tailwindlabs/headlessui/pull/1272))
- Ensure that there is always an active option in the `Combobox` ([#1279](https://github.com/tailwindlabs/headlessui/pull/1279), [#1281](https://github.com/tailwindlabs/headlessui/pull/1281))
- Support classic form submissions in `RadioGroup`, `Switch` and `Combobox` components ([#1285](https://github.com/tailwindlabs/headlessui/pull/1285))
- Add React 18 compatibility ([#1326](https://github.com/tailwindlabs/headlessui/pull/1326))
- Fix open/closed state issue in `Dialog` ([#1360](https://github.com/tailwindlabs/headlessui/pull/1360))
### Added
- Add classic form submission compatibility via new hidden inputs ([#1214](https://github.com/tailwindlabs/headlessui/pull/1214))
- Add multiple value support to `Listbox` and `Combobox` components ([#1243](https://github.com/tailwindlabs/headlessui/pull/1243), [#1355](https://github.com/tailwindlabs/headlessui/pull/1355))
- Add support for clearing the value of a `Combobox` ([#1295](https://github.com/tailwindlabs/headlessui/pull/1295))
- Add `Dialog.Backdrop` and `Dialog.Panel` components ([#1333](https://github.com/tailwindlabs/headlessui/pull/1333))
## [1.5.0] - 2022-02-17
### Fixed
- Ensure correct order when conditionally rendering `Menu.Item`, `Listbox.Option` and `RadioGroup.Option` ([#1045](https://github.com/tailwindlabs/headlessui/pull/1045))
- Improve controlled Tabs behavior ([#1050](https://github.com/tailwindlabs/headlessui/pull/1050))
- Improve typeahead search logic ([#1051](https://github.com/tailwindlabs/headlessui/pull/1051))
- Improve overal codebase, use modern tech like `esbuild` and TypeScript 4! ([#1055](https://github.com/tailwindlabs/headlessui/pull/1055))
- Improve build files ([#1078](https://github.com/tailwindlabs/headlessui/pull/1078))
- Ensure typeahead stays on same item if it still matches ([#1098](https://github.com/tailwindlabs/headlessui/pull/1098))
- Fix off-by-one frame issue causing flicker ([#1111](https://github.com/tailwindlabs/headlessui/pull/1111))
- Trigger scrollIntoView effect when position changes ([#1113](https://github.com/tailwindlabs/headlessui/pull/1113))
### Added
- Add `Combobox` component ([#1047](https://github.com/tailwindlabs/headlessui/pull/1047), [#1099](https://github.com/tailwindlabs/headlessui/pull/1099), [#1101](https://github.com/tailwindlabs/headlessui/pull/1101), [#1104](https://github.com/tailwindlabs/headlessui/pull/1104), [#1109](https://github.com/tailwindlabs/headlessui/pull/1109))
## [1.4.3] - 2022-01-14
### Fixes
- Ensure portal root exists in the DOM ([#950](https://github.com/tailwindlabs/headlessui/pull/950))
- Ensure correct DOM node order when performing focus actions ([#1038](https://github.com/tailwindlabs/headlessui/pull/1038))
### Added
- Allow for `Tab.Group` to be controllable ([#909](https://github.com/tailwindlabs/headlessui/pull/909), [#970](https://github.com/tailwindlabs/headlessui/pull/970))
## [1.4.2] - 2021-11-08
### Fixes
- Stop the event from propagating in the `Popover` component ([#798](https://github.com/tailwindlabs/headlessui/pull/798))
- Allow clicking on elements inside a `Dialog.Overlay` ([#816](https://github.com/tailwindlabs/headlessui/pull/816))
- Ensure interactability with `Popover.Panel` contents when using the `static` prop ([#857](https://github.com/tailwindlabs/headlessui/pull/857))
- Fix initial transition in `Transition` component ([#882](https://github.com/tailwindlabs/headlessui/pull/882))
## [1.4.1] - 2021-08-30
### Fixes
- Only add `type=button` to real buttons ([#709](https://github.com/tailwindlabs/headlessui/pull/709))
- Fix `escape` bug not closing Dialog after clicking in Dialog ([#754](https://github.com/tailwindlabs/headlessui/pull/754))
- Use `console.warn` instead of throwing an error when there are no focusable elements ([#775](https://github.com/tailwindlabs/headlessui/pull/775))
## [1.4.0] - 2021-07-29
### Added
- Add new `Tabs` component ([#674](https://github.com/tailwindlabs/headlessui/pull/674), [#698](https://github.com/tailwindlabs/headlessui/pull/698))
- Make `Disclosure.Button` close the disclosure inside a `Disclosure.Panel` ([#682](https://github.com/tailwindlabs/headlessui/pull/682))
- Add `aria-orientation` to `Listbox`, which swaps Up/Down with Left/Right keys ([#683](https://github.com/tailwindlabs/headlessui/pull/683))
- Expose `close` function from the render prop for `Disclosure`, `Disclosure.Panel`, `Popover` and `Popover.Panel` ([#697](https://github.com/tailwindlabs/headlessui/pull/697))
## [1.3.0] - 2021-06-21
### Added
- Ensure that you can use `Transition.Child` when using implicit Transitions ([#503](https://github.com/tailwindlabs/headlessui/pull/503))
- Add new `entered` prop for `Transition` and `Transition.Child` components ([#504](https://github.com/tailwindlabs/headlessui/pull/504))
### Fixes
- Add `aria-disabled` on disabled `RadioGroup.Option` components ([#543](https://github.com/tailwindlabs/headlessui/pull/543))
- Improve `disabled` and `tabindex` prop handling ([#512](https://github.com/tailwindlabs/headlessui/pull/512))
- Improve React peer dependency version range ([#544](https://github.com/tailwindlabs/headlessui/pull/544))
- Improve types for the `open` prop in the `Dialog` component ([#550](https://github.com/tailwindlabs/headlessui/pull/550))
- Improve `aria-expanded` logic ([#592](https://github.com/tailwindlabs/headlessui/pull/592))
- Remove undocumented `:className` prop ([#607](https://github.com/tailwindlabs/headlessui/pull/607))
- Improve types for `Listbox` component ([#576](https://github.com/tailwindlabs/headlessui/pull/576))
- Remove explicit `:class` prop ([#608](https://github.com/tailwindlabs/headlessui/pull/608))
- Improve tree shaking ([#602](https://github.com/tailwindlabs/headlessui/pull/602))
- Improve peer dependencies for `react-dom`, and for the future version `18` ([#622](https://github.com/tailwindlabs/headlessui/pull/622))
## [1.2.0] - 2021-05-10
### Added
- Introduce Open/Closed state, to simplify component communication ([#466](https://github.com/tailwindlabs/headlessui/pull/466))
### Fixes
- Improve SSR for `Dialog` ([#477](https://github.com/tailwindlabs/headlessui/pull/477))
- Delay focus trap initialization ([#477](https://github.com/tailwindlabs/headlessui/pull/477))
- Improve incorrect behavior for nesting `Dialog` components ([#560](https://github.com/tailwindlabs/headlessui/pull/560))
## [1.1.1] - 2021-04-28
### Fixes
- Fix form submission within Dialog ([#460](https://github.com/tailwindlabs/headlessui/pull/460))
## [1.1.0] - 2021-04-26
### Fixes
- Improve search, make searching case insensitive ([#385](https://github.com/tailwindlabs/headlessui/pull/385))
- Fix unreachable `RadioGroup` ([#401](https://github.com/tailwindlabs/headlessui/pull/401))
- Fix closing nested `Dialog` components when pressing `Escape` ([#430](https://github.com/tailwindlabs/headlessui/pull/430))
### Added
- Add `disabled` prop to `RadioGroup` and `RadioGroup.Option` ([#401](https://github.com/tailwindlabs/headlessui/pull/401))
- Add `defaultOpen` prop to the `Disclosure` component ([#447](https://github.com/tailwindlabs/headlessui/pull/447))
## [1.0.0] - 2021-04-14
### Fixes
- Fixed `outside click` not re-focusing the `Menu.Button` ([#220](https://github.com/tailwindlabs/headlessui/pull/220), [#256](https://github.com/tailwindlabs/headlessui/pull/256))
- Fixed `outside click` not re-focusing the `Listbox.Button` ([#220](https://github.com/tailwindlabs/headlessui/pull/220), [#256](https://github.com/tailwindlabs/headlessui/pull/256))
- Force focus in `Menu.Items` and `Listbox.Options` from within the component itself ([#261](https://github.com/tailwindlabs/headlessui/pull/261))
- Stop propagating keyboard/mouse events ([#261](https://github.com/tailwindlabs/headlessui/pull/261))
### Added
- Add `Disclosure`, `Disclosure.Button` and `Disclosure.Panel` components ([#220](https://github.com/tailwindlabs/headlessui/pull/220))
- Add `Dialog`, `Dialog.Overlay`, `Dialog.Tile` and `Dialog.Description` components ([#220](https://github.com/tailwindlabs/headlessui/pull/220))
- Add `Portal` and `Portal.Group` component ([#220](https://github.com/tailwindlabs/headlessui/pull/220))
- Add `Switch.Description` component, which adds the `aria-describedby` to the actual Switch ([#220](https://github.com/tailwindlabs/headlessui/pull/220))
- Add `FocusTrap` component ([#220](https://github.com/tailwindlabs/headlessui/pull/220))
- Add `Popover`, `Popover.Button`, `Popover.Overlay`, `Popover.Panel` and `Popover.Group` components ([#220](https://github.com/tailwindlabs/headlessui/pull/220))
- All components that accept a `className`, can now also receive a function with the renderProp argument ([#257](https://github.com/tailwindlabs/headlessui/pull/257))
- Add `RadioGroup`, `RadioGroup.Option`, `RadioGroup.Label` and `RadioGroup.Description` components ([#274](https://github.com/tailwindlabs/headlessui/pull/274))
## [0.3.2] - 2021-04-02
### Fixes
- Fix incorrect type error `unique symbol` ([#248](https://github.com/tailwindlabs/headlessui/pull/248), [#240](https://github.com/tailwindlabs/headlessui/issues/240))
## [0.3.1] - 2021-02-11
### Fixes
- Fix incorrect `types` path ([d557d50](https://github.com/tailwindlabs/headlessui/commit/d557d5013968f7bb9877f190b682318704043905))
- Fix TypeScript render related types ([bb68793](https://github.com/tailwindlabs/headlessui/commit/bb68793f08a57833095a38519b639a744076dc69))
## [0.3.0] - 2021-02-06
### Fixes
- Ensure that you can't use Enter to invoke the Switch
- Fix outside click refocus bug ([#114](https://github.com/tailwindlabs/headlessui/pull/114))
- Prevent scrolling when refocusing items
- Ensure `Switch` has `type="button"` ([#192](https://github.com/tailwindlabs/headlessui/pull/192))
- Fix `useId()` hook returning `undefined` on the client
- Fix `disabled` not working when inside a disabled fieldset ([#202](https://github.com/tailwindlabs/headlessui/pull/202))
- Trigger "outside click" behavior on mousedown ([#212](https://github.com/tailwindlabs/headlessui/pull/212))
- Ensure the `active` MenuItem is scrolled into view
- Ensure valid Menu accessibility tree ([#228](https://github.com/tailwindlabs/headlessui/pull/228))
### Added
- Add Transition events (`beforeEnter`, `afterEnter`, `beforeLeave` and `afterLeave`) ([#57](https://github.com/tailwindlabs/headlessui/pull/57))
- Add render features + render strategy (`static` and `unmount={true | false}`) ([#106](https://github.com/tailwindlabs/headlessui/pull/106))
- Add displayName to all contexts ([#175](https://github.com/tailwindlabs/headlessui/pull/175))
- Add `disabled` prop to `Listbox` itself, instead of the `Listbox.Button` ([#229](https://github.com/tailwindlabs/headlessui/pull/229))
### Changes
- Changes the API of the Transition component.
- We will now always render a `div` by default (unless you change this using the `as={...}` prop).
- The render function prop doesn't expose a `ref` anymore.
- Adds `unmount` prop to the `Transition` and `Transition.Child` components.
## [0.2.0] - 2020-10-06
### Added
- Add `Listbox` component
- Add `Switch` component
## [0.1.3] - 2020-09-29
### Fixes
- Fix outside click behavior. If you had multiple menu's, when menu 1 is open, menu 2 is closed and you click on menu button 2 it will open both menu's. This is now fixed.
- Ensure when using keyboard navigation we prevent the default behavior.
## [0.1.2] - 2020-09-25
### Added
- Add tests for `onClick` handling that wasn't working properly in @headlessui/vue to ensure behavior stays the same in this library
### Fixes
- Don't pass `disabled` prop through to children, only add `aria-disabled`
## [0.1.1] - 2020-09-24
### Added
- Everything!
[unreleased]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.2.9...HEAD
[2.2.9]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.2.8...@headlessui/react@v2.2.9
[2.2.8]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.2.7...@headlessui/react@v2.2.8
[2.2.7]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.2.6...@headlessui/react@v2.2.7
[2.2.6]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.2.5...@headlessui/react@v2.2.6
[2.2.5]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.2.4...@headlessui/react@v2.2.5
[2.2.4]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.2.3...@headlessui/react@v2.2.4
[2.2.3]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.2.2...@headlessui/react@v2.2.3
[2.2.2]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.2.1...@headlessui/react@v2.2.2
[2.2.1]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.2.0...@headlessui/react@v2.2.1
[2.2.0]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.1.10...@headlessui/react@v2.2.0
[2.1.10]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.1.9...@headlessui/react@v2.1.10
[2.1.9]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.1.8...@headlessui/react@v2.1.9
[2.1.8]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.1.7...@headlessui/react@v2.1.8
[2.1.7]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.1.6...@headlessui/react@v2.1.7
[2.1.6]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.1.5...@headlessui/react@v2.1.6
[2.1.5]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.1.4...@headlessui/react@v2.1.5
[2.1.4]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.1.3...@headlessui/react@v2.1.4
[2.1.3]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.1.2...@headlessui/react@v2.1.3
[2.1.2]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.1.1...@headlessui/react@v2.1.2
[2.1.1]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.1.0...@headlessui/react@v2.1.1
[2.1.0]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.0.4...@headlessui/react@v2.1.0
[2.0.4]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.0.3...@headlessui/react@v2.0.4
[2.0.3]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.0.2...@headlessui/react@v2.0.3
[2.0.2]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.0.1...@headlessui/react@v2.0.2
[2.0.1]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.0.0...@headlessui/react@v2.0.1
[2.0.0]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.0.0-alpha.4...@headlessui/react@v2.0.0
[1.7.19]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.7.18...v1.7.19
[2.0.0-alpha.4]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.0.0-alpha.3...v2.0.0-alpha.4
[2.0.0-alpha.3]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.0.0-alpha.2...v2.0.0-alpha.3
[2.0.0-alpha.2]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v2.0.0-alpha.1...v2.0.0-alpha.2
[2.0.0-alpha.1]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.7.18...v2.0.0-alpha.1
[1.7.18]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.7.17...v1.7.18
[1.7.17]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.7.16...v1.7.17
[1.7.16]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.7.15...@headlessui/react@v1.7.16
[1.7.15]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.7.14...@headlessui/react@v1.7.15
[1.7.14]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.7.13...@headlessui/react@v1.7.14
[1.7.13]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.7.12...@headlessui/react@v1.7.13
[1.7.12]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.7.11...@headlessui/react@v1.7.12
[1.7.11]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.7.10...@headlessui/react@v1.7.11
[1.7.10]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.7.9...@headlessui/react@v1.7.10
[1.7.9]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.7.8...@headlessui/react@v1.7.9
[1.7.8]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.7.7...@headlessui/react@v1.7.8
[1.7.7]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.7.6...@headlessui/react@v1.7.7
[1.7.6]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.7.5...@headlessui/react@v1.7.6
[1.7.5]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.7.4...@headlessui/react@v1.7.5
[1.7.4]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.7.3...@headlessui/react@v1.7.4
[1.7.3]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.7.2...@headlessui/react@v1.7.3
[1.7.2]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.7.1...@headlessui/react@v1.7.2
[1.7.1]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.7.0...@headlessui/react@v1.7.1
[1.7.0]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.6.6...@headlessui/react@v1.7.0
[1.6.6]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.6.5...@headlessui/react@v1.6.6
[1.6.5]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.6.4...@headlessui/react@v1.6.5
[1.6.4]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.6.3...@headlessui/react@v1.6.4
[1.6.3]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.6.2...@headlessui/react@v1.6.3
[1.6.2]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.6.1...@headlessui/react@v1.6.2
[1.6.1]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.6.0...@headlessui/react@v1.6.1
[1.6.0]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.5.0...@headlessui/react@v1.6.0
[1.5.0]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.4.3...@headlessui/react@v1.5.0
[1.4.3]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.4.2...@headlessui/react@v1.4.3
[1.4.2]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.4.1...@headlessui/react@v1.4.2
[1.4.1]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.4.0...@headlessui/react@v1.4.1
[1.4.0]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.3.0...@headlessui/react@v1.4.0
[1.3.0]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.2.0...@headlessui/react@v1.3.0
[1.2.0]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.1.1...@headlessui/react@v1.2.0
[1.1.1]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.1.0...@headlessui/react@v1.1.1
[1.1.0]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v1.0.0...@headlessui/react@v1.1.0
[1.0.0]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v0.3.2...@headlessui/react@v1.0.0
[0.3.2]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v0.3.1...@headlessui/react@v0.3.2
[0.3.1]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v0.3.0...@headlessui/react@v0.3.1
[0.3.0]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v0.2.0...@headlessui/react@v0.3.0
[0.2.0]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v0.1.3...@headlessui/react@v0.2.0
[0.1.3]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v0.1.2...@headlessui/react@v0.1.3
[0.1.2]: https://github.com/tailwindlabs/headlessui/compare/@headlessui/react@v0.1.1...@headlessui/react@v0.1.2
[0.1.1]: https://github.com/tailwindlabs/headlessui/releases/tag/@headlessui/react@v0.1.1
================================================
FILE: packages/@headlessui-react/LICENSE
================================================
MIT License
Copyright (c) 2020 Tailwind Labs
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: packages/@headlessui-react/README.md
================================================
<h3 align="center">
@headlessui/react
</h3>
<p align="center">
A set of completely unstyled, fully accessible UI components for React, designed to integrate
beautifully with Tailwind CSS.
</p>
<p align="center">
<a href="https://www.npmjs.com/package/@headlessui/react"><img src="https://img.shields.io/npm/dt/@headlessui/react.svg" alt="Total Downloads"></a>
<a href="https://github.com/tailwindlabs/headlessui/releases"><img src="https://img.shields.io/npm/v/@headlessui/react.svg" alt="Latest Release"></a>
<a href="https://github.com/tailwindlabs/headlessui/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/@headlessui/react.svg" alt="License"></a>
</p>
## Installation
```sh
npm install @headlessui/react
```
## Documentation
For full documentation, visit [headlessui.dev](https://headlessui.dev/react/menu).
## Community
For help, discussion about best practices, or feature ideas:
[Discuss Headless UI on GitHub](https://github.com/tailwindlabs/headlessui/discussions)
================================================
FILE: packages/@headlessui-react/build/index.cjs
================================================
'use strict'
if (process.env.NODE_ENV === 'production') {
module.exports = require('./headlessui.prod.cjs')
} else {
module.exports = require('./headlessui.dev.cjs')
}
================================================
FILE: packages/@headlessui-react/jest.config.cjs
================================================
let create = require('../../jest/create-jest-config.cjs')
module.exports = create(__dirname, {
displayName: 'React',
setupFilesAfterEnv: ['./jest.setup.js'],
})
================================================
FILE: packages/@headlessui-react/jest.setup.js
================================================
globalThis.IS_REACT_ACT_ENVIRONMENT = true
================================================
FILE: packages/@headlessui-react/package.json
================================================
{
"name": "@headlessui/react",
"version": "2.2.9",
"description": "A set of completely unstyled, fully accessible UI components for React, designed to integrate beautifully with Tailwind CSS.",
"main": "dist/index.cjs",
"typings": "dist/index.d.ts",
"module": "dist/headlessui.esm.js",
"license": "MIT",
"files": [
"README.md",
"dist"
],
"exports": {
"types": {
"import": "./dist/index.d.ts",
"require": "./dist/index.d.cts"
},
"import": "./dist/headlessui.esm.js",
"require": "./dist/index.cjs"
},
"type": "module",
"sideEffects": false,
"engines": {
"node": ">=10"
},
"repository": {
"type": "git",
"url": "git+https://github.com/tailwindlabs/headlessui.git",
"directory": "packages/@headlessui-react"
},
"publishConfig": {
"access": "public"
},
"scripts": {
"prepublishOnly": "npm run build",
"build": "../../scripts/build.sh --external:react --external:react-dom --external:use-sync-external-store",
"watch": "../../scripts/watch.sh --external:react --external:react-dom --external:use-sync-external-store",
"test": "../../scripts/test.sh",
"lint": "../../scripts/lint.sh",
"lint-types": "npm run attw -P --workspaces --if-present",
"playground": "npm run dev --workspace=playground-react",
"clean": "rimraf ./dist"
},
"peerDependencies": {
"react": "^18 || ^19 || ^19.0.0-rc",
"react-dom": "^18 || ^19 || ^19.0.0-rc"
},
"devDependencies": {
"@testing-library/react": "^15.0.7",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@types/use-sync-external-store": "^1.5.0",
"jsdom-testing-mocks": "^1.13.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"snapshot-diff": "^0.10.0"
},
"dependencies": {
"@floating-ui/react": "^0.26.16",
"@react-aria/focus": "^3.20.2",
"@react-aria/interactions": "^3.25.0",
"@tanstack/react-virtual": "^3.13.9",
"use-sync-external-store": "^1.5.0"
}
}
================================================
FILE: packages/@headlessui-react/src/components/button/button.test.tsx
================================================
import { render, screen } from '@testing-library/react'
import React, { Fragment } from 'react'
import { Button } from './button'
describe('Rendering', () => {
describe('Button', () => {
it('should render a button', async () => {
render(<Button>My Button</Button>)
expect(screen.getByRole('button')).toBeInTheDocument()
})
it('should default to `type="button"`', async () => {
render(<Button>My Button</Button>)
expect(screen.getByRole('button')).toHaveAttribute('type', 'button')
})
it('should render a button using a render prop', () => {
render(<Button>{(slot) => <>{JSON.stringify(slot)}</>}</Button>)
expect(screen.getByRole('button').textContent).toEqual(
JSON.stringify({
disabled: false,
hover: false,
focus: false,
active: false,
autofocus: false,
})
)
})
it('should map the `autoFocus` prop to a `data-autofocus` attribute', () => {
render(<Button autoFocus>My Button</Button>)
expect(screen.getByRole('button')).toHaveAttribute('data-autofocus')
})
it('should be possible to render a Button using as={Fragment}', async () => {
render(
<Button as={Fragment}>
<button>Toggle</button>
</Button>
)
expect(screen.getByRole('button')).toHaveAttribute('type')
})
})
})
================================================
FILE: packages/@headlessui-react/src/components/button/button.tsx
================================================
'use client'
import { useFocusRing } from '@react-aria/focus'
import { useHover } from '@react-aria/interactions'
import { type ElementType, type Ref } from 'react'
import { useActivePress } from '../../hooks/use-active-press'
import { useSlot } from '../../hooks/use-slot'
import { useDisabled } from '../../internal/disabled'
import type { Props } from '../../types'
import {
forwardRefWithAs,
mergeProps,
useRender,
type HasDisplayName,
type RefProp,
} from '../../utils/render'
let DEFAULT_BUTTON_TAG = 'button' as const
type ButtonRenderPropArg = {
disabled: boolean
hover: boolean
focus: boolean
active: boolean
autofocus: boolean
}
type ButtonPropsWeControl = never
export type ButtonProps<TTag extends ElementType = typeof DEFAULT_BUTTON_TAG> = Props<
TTag,
ButtonRenderPropArg,
ButtonPropsWeControl,
{
disabled?: boolean
autoFocus?: boolean
type?: 'button' | 'submit' | 'reset'
}
>
function ButtonFn<TTag extends ElementType = typeof DEFAULT_BUTTON_TAG>(
props: ButtonProps<TTag>,
ref: Ref<HTMLElement>
) {
let providedDisabled = useDisabled()
let { disabled = providedDisabled || false, autoFocus = false, ...theirProps } = props
let { isFocusVisible: focus, focusProps } = useFocusRing({ autoFocus })
let { isHovered: hover, hoverProps } = useHover({ isDisabled: disabled })
let { pressed: active, pressProps } = useActivePress({ disabled })
let ourProps = mergeProps(
{
ref,
type: theirProps.type ?? 'button',
disabled: disabled || undefined,
autoFocus,
},
focusProps,
hoverProps,
pressProps
)
let slot = useSlot<ButtonRenderPropArg>({ disabled, hover, focus, active, autofocus: autoFocus })
let render = useRender()
return render({
ourProps,
theirProps,
slot,
defaultTag: DEFAULT_BUTTON_TAG,
name: 'Button',
})
}
export interface _internal_ComponentButton extends HasDisplayName {
<TTag extends ElementType = typeof DEFAULT_BUTTON_TAG>(
props: ButtonProps<TTag> & RefProp<typeof ButtonFn>
): React.JSX.Element
}
export let Button = forwardRefWithAs(ButtonFn) as _internal_ComponentButton
================================================
FILE: packages/@headlessui-react/src/components/checkbox/checkbox.test.tsx
================================================
import { render } from '@testing-library/react'
import React, { useState } from 'react'
import {
CheckboxState,
assertCheckbox,
getCheckbox,
} from '../../test-utils/accessibility-assertions'
import { Keys, click, focus, press } from '../../test-utils/interactions'
import {
commonControlScenarios,
commonFormScenarios,
commonRenderingScenarios,
} from '../../test-utils/scenarios'
import { suppressConsoleLogs } from '../../test-utils/suppress-console-logs'
import { Checkbox, type CheckboxProps } from './checkbox'
commonRenderingScenarios(Checkbox, { getElement: getCheckbox })
commonControlScenarios(Checkbox)
commonFormScenarios((props) => <Checkbox defaultChecked {...props} />, {
async performUserInteraction(control) {
await click(control)
},
})
describe('Rendering', () => {
it(
'should be possible to put the checkbox in an indeterminate state',
suppressConsoleLogs(async () => {
render(<Checkbox indeterminate />)
assertCheckbox({ state: CheckboxState.Indeterminate })
})
)
it(
'should be possible to put the checkbox in an default checked state',
suppressConsoleLogs(async () => {
render(<Checkbox defaultChecked />)
assertCheckbox({ state: CheckboxState.Checked })
})
)
it(
'should render a checkbox in an unchecked state',
suppressConsoleLogs(async () => {
render(<Checkbox />)
assertCheckbox({ state: CheckboxState.Unchecked })
})
)
})
describe.each([
[
'Uncontrolled',
function Example(props: CheckboxProps) {
return <Checkbox {...props} />
},
],
[
'Controlled',
function Example(props: CheckboxProps) {
let [checked, setChecked] = useState(false)
return <Checkbox checked={checked} onChange={setChecked} {...props} />
},
],
])('Keyboard interactions (%s)', (_, Example) => {
describe('`Space` key', () => {
it(
'should be possible to toggle a checkbox',
suppressConsoleLogs(async () => {
render(<Example />)
assertCheckbox({ state: CheckboxState.Unchecked })
await focus(getCheckbox())
await press(Keys.Space)
assertCheckbox({ state: CheckboxState.Checked })
await press(Keys.Space)
assertCheckbox({ state: CheckboxState.Unchecked })
})
)
})
})
describe.each([
[
'Uncontrolled',
function Example(props: CheckboxProps) {
return <Checkbox {...props} />
},
],
[
'Controlled',
function Example(props: CheckboxProps) {
let [checked, setChecked] = useState(false)
return <Checkbox checked={checked} onChange={setChecked} {...props} />
},
],
])('Mouse interactions (%s)', (_, Example) => {
it(
'should be possible to toggle a checkbox by clicking it',
suppressConsoleLogs(async () => {
render(<Example />)
assertCheckbox({ state: CheckboxState.Unchecked })
await click(getCheckbox())
assertCheckbox({ state: CheckboxState.Checked })
await click(getCheckbox())
assertCheckbox({ state: CheckboxState.Unchecked })
})
)
})
describe('Form submissions', () => {
it('should be possible to use in an uncontrolled way', async () => {
let handleSubmission = jest.fn()
render(
<form
onSubmit={(e) => {
e.preventDefault()
handleSubmission(Object.fromEntries(new FormData(e.target as HTMLFormElement)))
}}
>
<Checkbox name="notifications" />
</form>
)
let checkbox = document.querySelector('[id^="headlessui-checkbox-"]') as HTMLInputElement
// Focus the checkbox
await focus(checkbox)
// Submit
await press(Keys.Enter)
// No values
expect(handleSubmission).toHaveBeenLastCalledWith({})
// Toggle
await click(checkbox)
// Submit
await press(Keys.Enter)
// Notifications should be on
expect(handleSubmission).toHaveBeenLastCalledWith({ notifications: 'on' })
// Toggle
await click(checkbox)
// Submit
await press(Keys.Enter)
// Notifications should be off (or in this case, non-existent)
expect(handleSubmission).toHaveBeenLastCalledWith({})
})
})
================================================
FILE: packages/@headlessui-react/src/components/checkbox/checkbox.tsx
================================================
'use client'
import { useFocusRing } from '@react-aria/focus'
import { useHover } from '@react-aria/interactions'
import React, {
useCallback,
useState,
type ElementType,
type KeyboardEvent as ReactKeyboardEvent,
type MouseEvent as ReactMouseEvent,
type Ref,
} from 'react'
import { useActivePress } from '../../hooks/use-active-press'
import { useControllable } from '../../hooks/use-controllable'
import { useDefaultValue } from '../../hooks/use-default-value'
import { useDisposables } from '../../hooks/use-disposables'
import { useEvent } from '../../hooks/use-event'
import { useId } from '../../hooks/use-id'
import { useSlot } from '../../hooks/use-slot'
import { useDisabled } from '../../internal/disabled'
import { FormFields } from '../../internal/form-fields'
import { useProvidedId } from '../../internal/id'
import type { Props } from '../../types'
import { isDisabledReactIssue7711 } from '../../utils/bugs'
import { attemptSubmit } from '../../utils/form'
import {
forwardRefWithAs,
mergeProps,
useRender,
type HasDisplayName,
type RefProp,
} from '../../utils/render'
import { useDescribedBy } from '../description/description'
import { Keys } from '../keyboard'
import { useLabelledBy } from '../label/label'
let DEFAULT_CHECKBOX_TAG = 'span' as const
type CheckboxRenderPropArg = {
checked: boolean
changing: boolean
focus: boolean
active: boolean
hover: boolean
autofocus: boolean
disabled: boolean
indeterminate: boolean
}
type CheckboxPropsWeControl =
| 'aria-checked'
| 'aria-describedby'
| 'aria-disabled'
| 'aria-labelledby'
| 'role'
export type CheckboxProps<
TTag extends ElementType = typeof DEFAULT_CHECKBOX_TAG,
TType = string,
> = Props<
TTag,
CheckboxRenderPropArg,
CheckboxPropsWeControl,
{
value?: TType
disabled?: boolean
indeterminate?: boolean
checked?: boolean
defaultChecked?: boolean
autoFocus?: boolean
form?: string
name?: string
onChange?: (checked: boolean) => void
tabIndex?: number
}
>
function CheckboxFn<TTag extends ElementType = typeof DEFAULT_CHECKBOX_TAG, TType = any>(
props: CheckboxProps<TTag, TType>,
ref: Ref<HTMLElement>
) {
let internalId = useId()
let providedId = useProvidedId()
let providedDisabled = useDisabled()
let {
id = providedId || `headlessui-checkbox-${internalId}`,
disabled = providedDisabled || false,
autoFocus = false,
checked: controlledChecked,
defaultChecked: _defaultChecked,
onChange: controlledOnChange,
name,
value,
form,
indeterminate = false,
tabIndex = 0,
...theirProps
} = props
let defaultChecked = useDefaultValue(_defaultChecked)
let [checked, onChange] = useControllable(
controlledChecked,
controlledOnChange,
defaultChecked ?? false
)
let labelledBy = useLabelledBy()
let describedBy = useDescribedBy()
let d = useDisposables()
let [changing, setChanging] = useState(false)
let toggle = useEvent(() => {
setChanging(true)
onChange?.(!checked)
d.nextFrame(() => {
setChanging(false)
})
})
let handleClick = useEvent((event: ReactMouseEvent) => {
if (isDisabledReactIssue7711(event.currentTarget)) return event.preventDefault()
event.preventDefault()
toggle()
})
let handleKeyUp = useEvent((event: ReactKeyboardEvent<HTMLButtonElement>) => {
if (event.key === Keys.Space) {
event.preventDefault()
toggle()
} else if (event.key === Keys.Enter) {
attemptSubmit(event.currentTarget)
}
})
// This is needed so that we can "cancel" the click event when we use the `Enter` key on a button.
let handleKeyPress = useEvent((event: ReactKeyboardEvent<HTMLElement>) => event.preventDefault())
let { isFocusVisible: focus, focusProps } = useFocusRing({ autoFocus })
let { isHovered: hover, hoverProps } = useHover({ isDisabled: disabled })
let { pressed: active, pressProps } = useActivePress({ disabled })
let ourProps = mergeProps(
{
ref,
id,
role: 'checkbox',
'aria-checked': indeterminate ? 'mixed' : checked ? 'true' : 'false',
'aria-labelledby': labelledBy,
'aria-describedby': describedBy,
'aria-disabled': disabled ? true : undefined,
indeterminate: indeterminate ? 'true' : undefined,
tabIndex: disabled ? undefined : tabIndex,
onKeyUp: disabled ? undefined : handleKeyUp,
onKeyPress: disabled ? undefined : handleKeyPress,
onClick: disabled ? undefined : handleClick,
},
focusProps,
hoverProps,
pressProps
)
let slot = useSlot<CheckboxRenderPropArg>({
checked,
disabled,
hover,
focus,
active,
indeterminate,
changing,
autofocus: autoFocus,
})
let reset = useCallback(() => {
if (defaultChecked === undefined) return
return onChange?.(defaultChecked)
}, [onChange, defaultChecked])
let render = useRender()
return (
<>
{name != null && (
<FormFields
disabled={disabled}
data={{ [name]: value || 'on' }}
overrides={{ type: 'checkbox', checked }}
form={form}
onReset={reset}
/>
)}
{render({
ourProps,
theirProps,
slot,
defaultTag: DEFAULT_CHECKBOX_TAG,
name: 'Checkbox',
})}
</>
)
}
// ---
export interface _internal_ComponentCheckbox extends HasDisplayName {
<TTag extends ElementType = typeof DEFAULT_CHECKBOX_TAG, TType = string>(
props: CheckboxProps<TTag, TType> & RefProp<typeof CheckboxFn>
): React.JSX.Element
}
export let Checkbox = forwardRefWithAs(CheckboxFn) as _internal_ComponentCheckbox
================================================
FILE: packages/@headlessui-react/src/components/close-button/close-button.tsx
================================================
'use client'
import React, { type ElementType, type Ref } from 'react'
import { useClose } from '../../internal/close-provider'
import { forwardRefWithAs, mergeProps } from '../../utils/render'
import { Button, type ButtonProps, type _internal_ComponentButton } from '../button/button'
let DEFAULT_BUTTON_TAG = 'button' as const
export type CloseButtonProps<TTag extends ElementType = typeof DEFAULT_BUTTON_TAG> =
ButtonProps<TTag>
function CloseButtonFn<TTag extends ElementType = typeof DEFAULT_BUTTON_TAG>(
props: ButtonProps<TTag>,
ref: Ref<HTMLElement>
) {
let close = useClose()
return <Button ref={ref} {...mergeProps({ onClick: close }, props)} />
}
export let CloseButton = forwardRefWithAs(CloseButtonFn) as _internal_ComponentButton
================================================
FILE: packages/@headlessui-react/src/components/combobox/combobox-machine-glue.tsx
================================================
import { createContext, useContext, useMemo } from 'react'
import { useOnUnmount } from '../../hooks/use-on-unmount'
import { ComboboxMachine } from './combobox-machine'
export const ComboboxContext = createContext<ComboboxMachine<unknown> | null>(null)
export function useComboboxMachineContext<T>(component: string) {
let context = useContext(ComboboxContext)
if (context === null) {
let err = new Error(`<${component} /> is missing a parent <Combobox /> component.`)
if (Error.captureStackTrace) Error.captureStackTrace(err, useComboboxMachine)
throw err
}
return context as ComboboxMachine<T>
}
export function useComboboxMachine({
id,
virtual = null,
__demoMode = false,
}: Parameters<typeof ComboboxMachine.new>[0]) {
let machine = useMemo(() => ComboboxMachine.new({ id, virtual, __demoMode }), [])
useOnUnmount(() => machine.dispose())
return machine
}
================================================
FILE: packages/@headlessui-react/src/components/combobox/combobox-machine.ts
================================================
import { Machine } from '../../machine'
import { ActionTypes as StackActionTypes, stackMachines } from '../../machines/stack-machine'
import type { EnsureArray } from '../../types'
import { Focus, calculateActiveIndex } from '../../utils/calculate-active-index'
import {
ElementPositionState,
computeVisualPosition,
detectMovement,
} from '../../utils/element-movement'
import { sortByDomNode } from '../../utils/focus-management'
import { match } from '../../utils/match'
interface MutableRefObject<T> {
current: T
}
export enum ComboboxState {
Open,
Closed,
}
export enum ValueMode {
Single,
Multi,
}
export enum ActivationTrigger {
Pointer,
Focus,
Other,
}
export type ComboboxOptionDataRef<T> = MutableRefObject<{
disabled: boolean
value: T
domRef: MutableRefObject<HTMLElement | null>
order: number | null
}>
export interface State<T> {
id: string
dataRef: MutableRefObject<{
value: unknown
defaultValue: unknown
disabled: boolean
invalid: boolean
mode: ValueMode
immediate: boolean
onChange: (value: T) => void
onClose?: () => void
compare(a: unknown, z: unknown): boolean
isSelected(value: unknown): boolean
virtual: { options: T[]; disabled: (value: T) => boolean } | null
calculateIndex(value: unknown): number
__demoMode: boolean
optionsPropsRef: MutableRefObject<{
static: boolean
hold: boolean
}>
}>
virtual: { options: T[]; disabled: (value: unknown) => boolean } | null
comboboxState: ComboboxState
defaultToFirstOption: boolean
options: { id: string; dataRef: ComboboxOptionDataRef<T> }[]
activeOptionIndex: number | null
activationTrigger: ActivationTrigger
isTyping: boolean
inputElement: HTMLInputElement | null
buttonElement: HTMLButtonElement | null
optionsElement: HTMLElement | null
// Track input to determine if it moved
inputPositionState: ElementPositionState
__demoMode: boolean
}
export enum ActionTypes {
OpenCombobox,
CloseCombobox,
GoToOption,
SetTyping,
RegisterOption,
UnregisterOption,
DefaultToFirstOption,
SetActivationTrigger,
UpdateVirtualConfiguration,
SetInputElement,
SetButtonElement,
SetOptionsElement,
MarkInputAsMoved,
}
function adjustOrderedState<T>(
state: State<T>,
adjustment: (options: State<T>['options']) => State<T>['options'] = (i) => i
) {
let currentActiveOption =
state.activeOptionIndex !== null ? state.options[state.activeOptionIndex] : null
let list = adjustment(state.options.slice())
let sortedOptions =
list.length > 0 && list[0].dataRef.current.order !== null
? // Prefer sorting based on the `order`
list.sort((a, z) => a.dataRef.current.order! - z.dataRef.current.order!)
: // Fallback to much slower DOM order
sortByDomNode(list, (option) => option.dataRef.current.domRef.current)
// If we inserted an option before the current active option then the active option index
// would be wrong. To fix this, we will re-lookup the correct index.
let adjustedActiveOptionIndex = currentActiveOption
? sortedOptions.indexOf(currentActiveOption)
: null
// Reset to `null` in case the currentActiveOption was removed.
if (adjustedActiveOptionIndex === -1) {
adjustedActiveOptionIndex = null
}
return {
options: sortedOptions,
activeOptionIndex: adjustedActiveOptionIndex,
}
}
type Actions<T> =
| { type: ActionTypes.CloseCombobox }
| { type: ActionTypes.OpenCombobox }
| {
type: ActionTypes.GoToOption
focus: Focus.Specific
idx: number
trigger?: ActivationTrigger
}
| { type: ActionTypes.SetTyping; isTyping: boolean }
| {
type: ActionTypes.GoToOption
focus: Exclude<Focus, Focus.Specific>
trigger?: ActivationTrigger
}
| {
type: ActionTypes.RegisterOption
payload: { id: string; dataRef: ComboboxOptionDataRef<T> }
}
| { type: ActionTypes.UnregisterOption; id: string }
| { type: ActionTypes.DefaultToFirstOption; value: boolean }
| { type: ActionTypes.SetActivationTrigger; trigger: ActivationTrigger }
| {
type: ActionTypes.UpdateVirtualConfiguration
options: T[]
disabled: ((value: any) => boolean) | null
}
| { type: ActionTypes.SetInputElement; element: HTMLInputElement | null }
| { type: ActionTypes.SetButtonElement; element: HTMLButtonElement | null }
| { type: ActionTypes.SetOptionsElement; element: HTMLElement | null }
| { type: ActionTypes.MarkInputAsMoved }
let reducers: {
[P in ActionTypes]: <T>(state: State<T>, action: Extract<Actions<T>, { type: P }>) => State<T>
} = {
[ActionTypes.CloseCombobox](state) {
if (state.dataRef.current?.disabled) return state
if (state.comboboxState === ComboboxState.Closed) return state
let inputPositionState = state.inputElement
? ElementPositionState.Tracked(computeVisualPosition(state.inputElement))
: state.inputPositionState
return {
...state,
activeOptionIndex: null,
comboboxState: ComboboxState.Closed,
isTyping: false,
// Clear the last known activation trigger
// This is because if a user interacts with the combobox using a mouse
// resulting in it closing we might incorrectly handle the next interaction
// for example, not scrolling to the active option in a virtual list
activationTrigger: ActivationTrigger.Other,
inputPositionState,
__demoMode: false,
}
},
[ActionTypes.OpenCombobox](state) {
if (state.dataRef.current?.disabled) return state
if (state.comboboxState === ComboboxState.Open) return state
// Check if we have a selected value that we can make active
if (state.dataRef.current?.value) {
let idx = state.dataRef.current.calculateIndex(state.dataRef.current.value)
if (idx !== -1) {
return {
...state,
activeOptionIndex: idx,
comboboxState: ComboboxState.Open,
__demoMode: false,
inputPositionState: ElementPositionState.Idle,
}
}
}
return {
...state,
comboboxState: ComboboxState.Open,
inputPositionState: ElementPositionState.Idle,
__demoMode: false,
}
},
[ActionTypes.SetTyping](state, action) {
if (state.isTyping === action.isTyping) return state
return { ...state, isTyping: action.isTyping }
},
[ActionTypes.GoToOption](state, action) {
if (state.dataRef.current?.disabled) return state
if (
state.optionsElement &&
!state.dataRef.current?.optionsPropsRef.current.static &&
state.comboboxState === ComboboxState.Closed
) {
return state
}
if (state.virtual) {
let { options, disabled } = state.virtual
let activeOptionIndex =
action.focus === Focus.Specific
? action.idx
: calculateActiveIndex(action, {
resolveItems: () => options,
resolveActiveIndex: () =>
state.activeOptionIndex ?? options.findIndex((option) => !disabled(option)) ?? null,
resolveDisabled: disabled,
resolveId() {
throw new Error('Function not implemented.')
},
})
let activationTrigger = action.trigger ?? ActivationTrigger.Other
if (
state.activeOptionIndex === activeOptionIndex &&
state.activationTrigger === activationTrigger
) {
return state
}
return {
...state,
activeOptionIndex,
activationTrigger,
isTyping: false,
__demoMode: false,
}
}
let adjustedState = adjustOrderedState(state)
// It's possible that the activeOptionIndex is set to `null` internally, but
// this means that we will fallback to the first non-disabled option by default.
// We have to take this into account.
if (adjustedState.activeOptionIndex === null) {
let localActiveOptionIndex = adjustedState.options.findIndex(
(option) => !option.dataRef.current.disabled
)
if (localActiveOptionIndex !== -1) {
adjustedState.activeOptionIndex = localActiveOptionIndex
}
}
let activeOptionIndex =
action.focus === Focus.Specific
? action.idx
: calculateActiveIndex(action, {
resolveItems: () => adjustedState.options,
resolveActiveIndex: () => adjustedState.activeOptionIndex,
resolveId: (item) => item.id,
resolveDisabled: (item) => item.dataRef.current.disabled,
})
let activationTrigger = action.trigger ?? ActivationTrigger.Other
if (
state.activeOptionIndex === activeOptionIndex &&
state.activationTrigger === activationTrigger
) {
return state
}
return {
...state,
...adjustedState,
isTyping: false,
activeOptionIndex,
activationTrigger,
__demoMode: false,
}
},
[ActionTypes.RegisterOption]: (state, action) => {
if (state.dataRef.current?.virtual) {
return {
...state,
options: [...state.options, action.payload],
}
}
let option = action.payload
let adjustedState = adjustOrderedState(state, (options) => {
options.push(option)
return options
})
// Check if we need to make the newly registered option active.
if (state.activeOptionIndex === null) {
if (state.dataRef.current.isSelected?.(action.payload.dataRef.current.value)) {
adjustedState.activeOptionIndex = adjustedState.options.indexOf(option)
}
}
let nextState = {
...state,
...adjustedState,
activationTrigger: ActivationTrigger.Other,
}
if (state.dataRef.current?.__demoMode && state.dataRef.current.value === undefined) {
nextState.activeOptionIndex = 0
}
return nextState
},
[ActionTypes.UnregisterOption]: (state, action) => {
if (state.dataRef.current?.virtual) {
return {
...state,
options: state.options.filter((option) => option.id !== action.id),
}
}
let adjustedState = adjustOrderedState(state, (options) => {
let idx = options.findIndex((option) => option.id === action.id)
if (idx !== -1) options.splice(idx, 1)
return options
})
return {
...state,
...adjustedState,
activationTrigger: ActivationTrigger.Other,
}
},
[ActionTypes.DefaultToFirstOption]: (state, action) => {
if (state.defaultToFirstOption === action.value) return state
return {
...state,
defaultToFirstOption: action.value,
}
},
[ActionTypes.SetActivationTrigger]: (state, action) => {
if (state.activationTrigger === action.trigger) {
return state
}
return {
...state,
activationTrigger: action.trigger,
}
},
[ActionTypes.UpdateVirtualConfiguration]: (state, action) => {
if (state.virtual === null) {
return {
...state,
virtual: { options: action.options, disabled: action.disabled ?? (() => false) },
}
}
if (state.virtual.options === action.options && state.virtual.disabled === action.disabled) {
return state
}
let adjustedActiveOptionIndex = state.activeOptionIndex
if (state.activeOptionIndex !== null) {
let idx = action.options.indexOf(state.virtual.options[state.activeOptionIndex])
if (idx !== -1) {
adjustedActiveOptionIndex = idx
} else {
adjustedActiveOptionIndex = null
}
}
return {
...state,
activeOptionIndex: adjustedActiveOptionIndex,
virtual: { options: action.options, disabled: action.disabled ?? (() => false) },
}
},
[ActionTypes.SetInputElement]: (state, action) => {
if (state.inputElement === action.element) return state
return { ...state, inputElement: action.element }
},
[ActionTypes.SetButtonElement]: (state, action) => {
if (state.buttonElement === action.element) return state
return { ...state, buttonElement: action.element }
},
[ActionTypes.SetOptionsElement]: (state, action) => {
if (state.optionsElement === action.element) return state
return { ...state, optionsElement: action.element }
},
[ActionTypes.MarkInputAsMoved](state) {
if (state.inputPositionState.kind !== 'Tracked') return state
return {
...state,
inputPositionState: ElementPositionState.Moved,
}
},
}
export class ComboboxMachine<T> extends Machine<State<T>, Actions<T>> {
static new<T, TMultiple extends boolean | undefined>({
id,
virtual = null,
__demoMode = false,
}: {
id: string
virtual?: {
options: TMultiple extends true ? EnsureArray<NoInfer<T>> : NoInfer<T>[]
disabled?: (
value: TMultiple extends true ? EnsureArray<NoInfer<T>>[number] : NoInfer<T>
) => boolean
} | null
__demoMode?: boolean
}) {
return new ComboboxMachine({
id,
// @ts-expect-error TODO: Re-structure such that we don't need to ignore this
dataRef: { current: {} },
comboboxState: __demoMode ? ComboboxState.Open : ComboboxState.Closed,
isTyping: false,
options: [],
// @ts-expect-error TODO: Ensure we use the correct type
virtual: virtual
? { options: virtual.options, disabled: virtual.disabled ?? (() => false) }
: null,
activeOptionIndex: null,
activationTrigger: ActivationTrigger.Other,
inputElement: null,
buttonElement: null,
optionsElement: null,
__demoMode,
inputPositionState: ElementPositionState.Idle,
})
}
constructor(initialState: State<T>) {
super(initialState)
// When the combobox is open, and it's not on the top of the hierarchy, we
// should close it again.
{
let id = this.state.id
let stackMachine = stackMachines.get(null)
this.disposables.add(
stackMachine.on(StackActionTypes.Push, (state) => {
if (
!stackMachine.selectors.isTop(state, id) &&
this.state.comboboxState === ComboboxState.Open
) {
this.actions.closeCombobox()
}
})
)
this.on(ActionTypes.OpenCombobox, () => stackMachine.actions.push(id))
this.on(ActionTypes.CloseCombobox, () => stackMachine.actions.pop(id))
}
// Track whether the input moved or not
this.disposables.group((d) => {
this.on(ActionTypes.CloseCombobox, (state) => {
if (!state.inputElement) return
d.dispose()
d.add(
detectMovement(state.inputElement, state.inputPositionState, () => {
this.send({ type: ActionTypes.MarkInputAsMoved })
})
)
})
})
}
actions = {
onChange: (newValue: T) => {
let { onChange, compare, mode, value } = this.state.dataRef.current
return match(mode, {
[ValueMode.Single]: () => {
return onChange?.(newValue)
},
[ValueMode.Multi]: () => {
let copy = (value as T[]).slice()
let idx = copy.findIndex((item) => compare(item, newValue))
if (idx === -1) {
copy.push(newValue)
} else {
copy.splice(idx, 1)
}
return onChange?.(copy as T)
},
})
},
registerOption: (id: string, dataRef: ComboboxOptionDataRef<T>) => {
this.send({ type: ActionTypes.RegisterOption, payload: { id, dataRef } })
return () => {
// When we are unregistering the currently active option, then we also have to make sure to
// reset the `defaultToFirstOption` flag, so that visually something is selected and the next
// time you press a key on your keyboard it will go to the proper next or previous option in
// the list.
//
// Since this was the active option and it could have been anywhere in the list, resetting to
// the very first option seems like a fine default. We _could_ be smarter about this by going
// to the previous / next item in list if we know the direction of the keyboard navigation,
// but that might be too complex/confusing from an end users perspective.
if (
this.state.activeOptionIndex ===
this.state.dataRef.current.calculateIndex(dataRef.current.value)
) {
this.send({ type: ActionTypes.DefaultToFirstOption, value: true })
}
this.send({ type: ActionTypes.UnregisterOption, id })
}
},
goToOption: (
focus: { focus: Focus.Specific; idx: number } | { focus: Exclude<Focus, Focus.Specific> },
trigger?: ActivationTrigger
) => {
this.send({ type: ActionTypes.DefaultToFirstOption, value: false })
return this.send({ type: ActionTypes.GoToOption, ...focus, trigger })
},
setIsTyping: (isTyping: boolean) => {
this.send({ type: ActionTypes.SetTyping, isTyping })
},
closeCombobox: () => {
this.send({ type: ActionTypes.CloseCombobox })
this.send({ type: ActionTypes.DefaultToFirstOption, value: false })
this.state.dataRef.current.onClose?.()
},
openCombobox: () => {
this.send({ type: ActionTypes.OpenCombobox })
this.send({ type: ActionTypes.DefaultToFirstOption, value: true })
},
setActivationTrigger: (trigger: ActivationTrigger) => {
this.send({ type: ActionTypes.SetActivationTrigger, trigger })
},
selectActiveOption: () => {
let activeOptionIndex = this.selectors.activeOptionIndex(this.state)
if (activeOptionIndex === null) return
this.actions.setIsTyping(false)
if (this.state.virtual) {
this.actions.onChange(this.state.virtual.options[activeOptionIndex])
} else {
let { dataRef } = this.state.options[activeOptionIndex]
this.actions.onChange(dataRef.current.value)
}
// It could happen that the `activeOptionIndex` stored in state is actually null, but we are
// getting the fallback active option back instead.
this.actions.goToOption({ focus: Focus.Specific, idx: activeOptionIndex })
},
setInputElement: (element: HTMLInputElement | null) => {
this.send({ type: ActionTypes.SetInputElement, element })
},
setButtonElement: (element: HTMLButtonElement | null) => {
this.send({ type: ActionTypes.SetButtonElement, element })
},
setOptionsElement: (element: HTMLElement | null) => {
this.send({ type: ActionTypes.SetOptionsElement, element })
},
}
selectors = {
activeDescendantId: (state: State<T>) => {
let activeOptionIndex = this.selectors.activeOptionIndex(state)
if (activeOptionIndex === null) {
return undefined
}
if (!state.virtual) {
return state.options[activeOptionIndex]?.id
}
return state.options.find((option) => {
return (
!option.dataRef.current.disabled &&
state.dataRef.current.compare(
option.dataRef.current.value,
state.virtual!.options[activeOptionIndex]
)
)
})?.id
},
activeOptionIndex: (state: State<T>) => {
if (
state.defaultToFirstOption &&
state.activeOptionIndex === null &&
(state.virtual ? state.virtual.options.length > 0 : state.options.length > 0)
) {
if (state.virtual) {
let { options, disabled } = state.virtual
let activeOptionIndex = options.findIndex((option) => !(disabled?.(option) ?? false))
if (activeOptionIndex !== -1) {
return activeOptionIndex
}
}
let activeOptionIndex = state.options.findIndex((option) => {
return !option.dataRef.current.disabled
})
if (activeOptionIndex !== -1) {
return activeOptionIndex
}
}
return state.activeOptionIndex
},
activeOption: (state: State<T>) => {
let activeOptionIndex = this.selectors.activeOptionIndex(state)
return activeOptionIndex === null
? null
: state.virtual
? state.virtual.options[activeOptionIndex ?? 0]
: state.options[activeOptionIndex]?.dataRef.current.value ?? null
},
isActive: (state: State<T>, value: T, id: string) => {
let activeOptionIndex = this.selectors.activeOptionIndex(state)
if (activeOptionIndex === null) return false
if (state.virtual) {
return activeOptionIndex === state.dataRef.current.calculateIndex(value)
}
return state.options[activeOptionIndex]?.id === id
},
shouldScrollIntoView: (state: State<T>, value: T, id: string): boolean => {
if (state.virtual) return false
if (state.__demoMode) return false
if (state.comboboxState !== ComboboxState.Open) return false
if (state.activationTrigger === ActivationTrigger.Pointer) return false
let active = this.selectors.isActive(state, value, id)
if (!active) return false
return true
},
didInputMove(state: State<T>) {
return state.inputPositionState.kind === 'Moved'
},
}
reduce(state: Readonly<State<T>>, action: Actions<T>): State<T> {
return match(action.type, reducers, state, action) as State<T>
}
}
================================================
FILE: packages/@headlessui-react/src/components/combobox/combobox.test.tsx
================================================
import { render, waitFor } from '@testing-library/react'
import React, { Fragment, createElement, useEffect, useState } from 'react'
import {
ComboboxMode,
ComboboxState,
assertActiveComboboxOption,
assertActiveElement,
assertCombobox,
assertComboboxButton,
assertComboboxButtonLinkedWithCombobox,
assertComboboxButtonLinkedWithComboboxLabel,
assertComboboxInput,
assertComboboxLabel,
assertComboboxLabelLinkedWithCombobox,
assertComboboxList,
assertComboboxOption,
assertNoActiveComboboxOption,
assertNoSelectedComboboxOption,
assertNotActiveComboboxOption,
getByText,
getComboboxButton,
getComboboxButtons,
getComboboxInput,
getComboboxInputs,
getComboboxLabel,
getComboboxOptions,
getComboboxes,
} from '../../test-utils/accessibility-assertions'
import {
Keys,
MouseButton,
blur,
click,
focus,
mouseLeave,
mouseMove,
press,
rawClick,
shift,
type,
word,
} from '../../test-utils/interactions'
import { mockingConsoleLogs, suppressConsoleLogs } from '../../test-utils/suppress-console-logs'
import { Transition } from '../transition/transition'
import {
Combobox,
ComboboxButton,
ComboboxInput,
ComboboxOption,
ComboboxOptions,
} from './combobox'
let NOOP = () => {}
// Mocking the `getBoundingClientRect` method for the virtual tests otherwise
// the `Virtualizer` from `@tanstack/react-virtual` will not work as expected
// because it couldn't measure the elements correctly.
jest.spyOn(Element.prototype, 'getBoundingClientRect').mockImplementation(() => ({
width: 120,
height: 40,
top: 0,
left: 0,
bottom: 0,
right: 0,
x: 0,
y: 0,
toJSON: () => {},
}))
jest.spyOn(HTMLElement.prototype, 'offsetWidth', 'get').mockReturnValue(100)
jest.spyOn(HTMLElement.prototype, 'offsetHeight', 'get').mockReturnValue(40)
beforeAll(() => {
jest.spyOn(window, 'requestAnimationFrame').mockImplementation(setImmediate as any)
jest.spyOn(window, 'cancelAnimationFrame').mockImplementation(clearImmediate as any)
})
afterAll(() => jest.restoreAllMocks())
describe('safeguards', () => {
it.each([
['Combobox.Button', Combobox.Button],
['Combobox.Label', Combobox.Label],
['Combobox.Options', Combobox.Options],
['Combobox.Option', Combobox.Option],
])(
'should error when we are using a <%s /> without a parent <Combobox />',
suppressConsoleLogs((name, Component) => {
if (name === 'Combobox.Label') {
// @ts-expect-error This is fine
expect(() => render(createElement(Component))).toThrow(
'You used a <Label /> component, but it is not inside a relevant parent.'
)
} else {
// @ts-expect-error This is fine
expect(() => render(createElement(Component))).toThrow(
`<${name} /> is missing a parent <Combobox /> component.`
)
}
})
)
it(
'should be possible to render a Combobox without crashing',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
<Combobox.Option value="a">Option A</Combobox.Option>
<Combobox.Option value="b">Option B</Combobox.Option>
<Combobox.Option value="c">Option C</Combobox.Option>
</Combobox.Options>
</Combobox>
)
assertComboboxButton({ state: ComboboxState.InvisibleUnmounted })
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
})
)
})
describe('Rendering', () => {
describe('Combobox', () => {
it(
'should be possible to render a Combobox using a render prop',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={(x) => console.log(x)}>
{({ open }) => (
<>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
{open && (
<Combobox.Options>
<Combobox.Option value="a">Option A</Combobox.Option>
<Combobox.Option value="b">Option B</Combobox.Option>
<Combobox.Option value="c">Option C</Combobox.Option>
</Combobox.Options>
)}
</>
)}
</Combobox>
)
assertComboboxButton({ state: ComboboxState.InvisibleUnmounted })
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
await click(getComboboxButton())
assertComboboxButton({ state: ComboboxState.Visible })
assertComboboxList({ state: ComboboxState.Visible })
})
)
it(
'should be possible to disable a Combobox',
suppressConsoleLogs(async () => {
render(
<Combobox value={undefined} onChange={(x) => console.log(x)} disabled>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
<Combobox.Option value="a">Option A</Combobox.Option>
<Combobox.Option value="b">Option B</Combobox.Option>
<Combobox.Option value="c">Option C</Combobox.Option>
</Combobox.Options>
</Combobox>
)
assertComboboxButton({ state: ComboboxState.InvisibleUnmounted })
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
await click(getComboboxButton())
assertComboboxButton({ state: ComboboxState.InvisibleUnmounted })
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
await press(Keys.Enter, getComboboxButton())
assertComboboxButton({ state: ComboboxState.InvisibleUnmounted })
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
// The input should also be disabled
assertComboboxInput({
state: ComboboxState.InvisibleUnmounted,
attributes: { disabled: '' },
})
// And even if we try to focus it, it should not open the combobox
await focus(getComboboxInput())
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
})
)
it(
'should not crash in multiple mode',
suppressConsoleLogs(async () => {
render(
<Combobox multiple name="abc">
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
<Combobox.Option value={{ id: 1, name: 'alice' }}>alice</Combobox.Option>
<Combobox.Option value={{ id: 2, name: 'bob' }}>bob</Combobox.Option>
<Combobox.Option value={{ id: 3, name: 'charlie' }}>charlie</Combobox.Option>
</Combobox.Options>
</Combobox>
)
await click(getComboboxButton())
let [alice, bob, charlie] = getComboboxOptions()
await click(alice)
await click(bob)
await click(charlie)
})
)
describe('Equality', () => {
let options = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Charlie' },
]
it(
'should use object equality by default',
suppressConsoleLogs(async () => {
render(
<Combobox value={options[1]} onChange={(x) => console.log(x)}>
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
{options.map((option) => (
<Combobox.Option
key={option.id}
value={option}
className={(info) => JSON.stringify(info)}
>
{option.name}
</Combobox.Option>
))}
</Combobox.Options>
</Combobox>
)
await click(getComboboxButton())
let bob = getComboboxOptions()[1]
expect(bob).toHaveAttribute(
'class',
JSON.stringify({ active: true, focus: true, selected: true, disabled: false })
)
})
)
it(
'should be possible to compare null values by a field',
suppressConsoleLogs(async () => {
render(
<Combobox value={null} onChange={(x) => console.log(x)} by="id">
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
{options.map((option) => (
<Combobox.Option
key={option.id}
value={option}
className={(info) => JSON.stringify(info)}
>
{option.name}
</Combobox.Option>
))}
</Combobox.Options>
</Combobox>
)
await click(getComboboxButton())
let [alice, bob, charlie] = getComboboxOptions()
expect(alice).toHaveAttribute(
'class',
JSON.stringify({
active: true,
focus: true,
selected: false,
disabled: false,
})
)
expect(bob).toHaveAttribute(
'class',
JSON.stringify({
active: false,
focus: false,
selected: false,
disabled: false,
})
)
expect(charlie).toHaveAttribute(
'class',
JSON.stringify({
active: false,
focus: false,
selected: false,
disabled: false,
})
)
})
)
it(
'should be possible to compare objects by a field',
suppressConsoleLogs(async () => {
render(
<Combobox value={{ id: 2, name: 'Bob' }} onChange={(x) => console.log(x)} by="id">
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
{options.map((option) => (
<Combobox.Option
key={option.id}
value={option}
className={(info) => JSON.stringify(info)}
>
{option.name}
</Combobox.Option>
))}
</Combobox.Options>
</Combobox>
)
await click(getComboboxButton())
let bob = getComboboxOptions()[1]
expect(bob).toHaveAttribute(
'class',
JSON.stringify({
active: true,
focus: true,
selected: true,
disabled: false,
})
)
})
)
it(
'should be possible to compare objects by a comparator function',
suppressConsoleLogs(async () => {
render(
<Combobox
value={{ id: 2, name: 'Bob' }}
onChange={(x) => console.log(x)}
by={(a, z) => a.id === z.id}
>
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
{options.map((option) => (
<Combobox.Option
key={option.id}
value={option}
className={(info) => JSON.stringify(info)}
>
{option.name}
</Combobox.Option>
))}
</Combobox.Options>
</Combobox>
)
await click(getComboboxButton())
let bob = getComboboxOptions()[1]
expect(bob).toHaveAttribute(
'class',
JSON.stringify({
active: true,
focus: true,
selected: true,
disabled: false,
})
)
})
)
it(
'should be possible to use completely new objects while rendering (single mode)',
suppressConsoleLogs(async () => {
function Example() {
let [value, setValue] = useState<{ id: number; name: string } | null>({
id: 2,
name: 'Bob',
})
return (
<Combobox value={value} onChange={setValue} by="id">
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
<Combobox.Option value={{ id: 1, name: 'alice' }}>alice</Combobox.Option>
<Combobox.Option value={{ id: 2, name: 'bob' }}>bob</Combobox.Option>
<Combobox.Option value={{ id: 3, name: 'charlie' }}>charlie</Combobox.Option>
</Combobox.Options>
</Combobox>
)
}
render(<Example />)
await click(getComboboxButton())
let [alice, bob, charlie] = getComboboxOptions()
expect(alice).toHaveAttribute('aria-selected', 'false')
expect(bob).toHaveAttribute('aria-selected', 'true')
expect(charlie).toHaveAttribute('aria-selected', 'false')
await click(getComboboxOptions()[2])
await click(getComboboxButton())
;[alice, bob, charlie] = getComboboxOptions()
expect(alice).toHaveAttribute('aria-selected', 'false')
expect(bob).toHaveAttribute('aria-selected', 'false')
expect(charlie).toHaveAttribute('aria-selected', 'true')
await click(getComboboxOptions()[1])
await click(getComboboxButton())
;[alice, bob, charlie] = getComboboxOptions()
expect(alice).toHaveAttribute('aria-selected', 'false')
expect(bob).toHaveAttribute('aria-selected', 'true')
expect(charlie).toHaveAttribute('aria-selected', 'false')
})
)
it(
'should be possible to use completely new objects while rendering (multiple mode)',
suppressConsoleLogs(async () => {
function Example() {
let [value, setValue] = useState([{ id: 2, name: 'Bob' }])
return (
<Combobox value={value} onChange={setValue} by="id" multiple>
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
<Combobox.Option value={{ id: 1, name: 'alice' }}>alice</Combobox.Option>
<Combobox.Option value={{ id: 2, name: 'bob' }}>bob</Combobox.Option>
<Combobox.Option value={{ id: 3, name: 'charlie' }}>charlie</Combobox.Option>
</Combobox.Options>
</Combobox>
)
}
render(<Example />)
await click(getComboboxButton())
await click(getComboboxOptions()[2])
let [alice, bob, charlie] = getComboboxOptions()
expect(alice).toHaveAttribute('aria-selected', 'false')
expect(bob).toHaveAttribute('aria-selected', 'true')
expect(charlie).toHaveAttribute('aria-selected', 'true')
await click(getComboboxOptions()[2])
;[alice, bob, charlie] = getComboboxOptions()
expect(alice).toHaveAttribute('aria-selected', 'false')
expect(bob).toHaveAttribute('aria-selected', 'true')
expect(charlie).toHaveAttribute('aria-selected', 'false')
})
)
})
it(
'should not crash when a defaultValue is not given',
suppressConsoleLogs(async () => {
let data = [
{ id: 1, name: 'alice', label: 'Alice' },
{ id: 2, name: 'bob', label: 'Bob' },
{ id: 3, name: 'charlie', label: 'Charlie' },
]
render(
<Combobox<(typeof data)[number]> name="assignee" by="id">
<Combobox.Input
displayValue={(value: { name: string }) => value.name}
onChange={NOOP}
/>
<Combobox.Options>
{data.map((person) => (
<Combobox.Option key={person.id} value={person}>
{person.label}
</Combobox.Option>
))}
</Combobox.Options>
</Combobox>
)
})
)
it(
'should keep the defaultValue when the Combobox state changes',
suppressConsoleLogs(async () => {
let data = [
{ id: 1, name: 'alice', label: 'Alice' },
{ id: 2, name: 'bob', label: 'Bob' },
{ id: 3, name: 'charlie', label: 'Charlie' },
]
function Example() {
let [person, setPerson] = useState<(typeof data)[number] | null>(data[1])
return (
<Combobox value={person} onChange={setPerson} name="assignee" by="id">
<Combobox.Input displayValue={() => String(Math.random())} />
<Combobox.Button />
<Combobox.Options>
{data.map((person) => (
<Combobox.Option key={person.id} value={person}>
{person.label}
</Combobox.Option>
))}
</Combobox.Options>
</Combobox>
)
}
render(<Example />)
let value = getComboboxInput()?.value
// Toggle the state a few times combobox
await click(getComboboxButton())
await click(getComboboxButton())
await click(getComboboxButton())
// Verify the value is still the same
expect(getComboboxInput()?.value).toBe(value)
// Choose an option, which should update the value
await click(getComboboxOptions()[2])
// Verify the value changed
expect(getComboboxInput()?.value).not.toBe(value)
})
)
it(
'should close the Combobox when the input is blurred',
suppressConsoleLogs(async () => {
let closeHandler = jest.fn()
let data = [
{ id: 1, name: 'alice', label: 'Alice' },
{ id: 2, name: 'bob', label: 'Bob' },
{ id: 3, name: 'charlie', label: 'Charlie' },
]
render(
<Combobox<(typeof data)[number]> name="assignee" by="id" onClose={closeHandler}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button />
<Combobox.Options>
{data.map((person) => (
<Combobox.Option key={person.id} value={person}>
{person.label}
</Combobox.Option>
))}
</Combobox.Options>
</Combobox>
)
// Open the combobox
await click(getComboboxButton())
// Verify it is open
assertComboboxList({ state: ComboboxState.Visible })
// Close the combobox
expect(closeHandler).toHaveBeenCalledTimes(0)
await blur(getComboboxInput())
expect(closeHandler).toHaveBeenCalledTimes(1)
// Verify it is closed
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
})
)
it(
'should not crash when the `Combobox` still contains a `nullable` prop',
suppressConsoleLogs(async () => {
let data = [
{ id: 1, name: 'alice', label: 'Alice' },
{ id: 2, name: 'bob', label: 'Bob' },
{ id: 3, name: 'charlie', label: 'Charlie' },
]
render(
<Combobox nullable as={Fragment}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button />
<Combobox.Options>
{data.map((person) => (
<Combobox.Option key={person.id} value={person}>
{person.label}
</Combobox.Option>
))}
</Combobox.Options>
</Combobox>
)
})
)
})
describe('Combobox.Input', () => {
it(
'selecting an option puts the value into Combobox.Input when displayValue is not provided',
suppressConsoleLogs(async () => {
function Example() {
let [value, setValue] = useState(null)
return (
<Combobox value={value} onChange={setValue}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
<Combobox.Option value="a">Option A</Combobox.Option>
<Combobox.Option value="b">Option B</Combobox.Option>
<Combobox.Option value="c">Option C</Combobox.Option>
</Combobox.Options>
</Combobox>
)
}
render(<Example />)
assertComboboxInput({ state: ComboboxState.InvisibleUnmounted })
await click(getComboboxButton())
assertComboboxInput({ state: ComboboxState.Visible })
assertComboboxList({ state: ComboboxState.Visible })
await click(getComboboxOptions()[1])
expect(getComboboxInput()).toHaveValue('b')
})
)
it(
'selecting an option puts the display value into Combobox.Input when displayValue is provided',
suppressConsoleLogs(async () => {
function Example() {
let [value, setValue] = useState(null)
return (
<Combobox value={value} onChange={setValue}>
<Combobox.Input
onChange={NOOP}
displayValue={(str?: string) => str?.toUpperCase() ?? ''}
/>
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
<Combobox.Option value="a">Option A</Combobox.Option>
<Combobox.Option value="b">Option B</Combobox.Option>
<Combobox.Option value="c">Option C</Combobox.Option>
</Combobox.Options>
</Combobox>
)
}
render(<Example />)
await click(getComboboxButton())
assertComboboxList({ state: ComboboxState.Visible })
await click(getComboboxOptions()[1])
expect(getComboboxInput()).toHaveValue('B')
})
)
it(
'selecting an option puts the display value into Combobox.Input when displayValue is provided (when value is undefined)',
suppressConsoleLogs(async () => {
function Example() {
let [value, setValue] = useState<null | undefined>(undefined)
return (
<Combobox value={value} onChange={setValue}>
<Combobox.Input
onChange={NOOP}
displayValue={(str?: string) => str?.toUpperCase() ?? ''}
/>
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
<Combobox.Option value="a">Option A</Combobox.Option>
<Combobox.Option value="b">Option B</Combobox.Option>
<Combobox.Option value="c">Option C</Combobox.Option>
</Combobox.Options>
</Combobox>
)
}
render(<Example />)
// Focus the input
await focus(getComboboxInput())
// Type in it
await type(word('A'), getComboboxInput())
// Stop typing (and clear the input)
await press(Keys.Escape, getComboboxInput())
// Focus the body (so the input loses focus)
await focus(document.body)
expect(getComboboxInput()).toHaveValue('')
})
)
it(
'conditionally rendering the input should allow changing the display value',
suppressConsoleLogs(async () => {
function Example() {
let [value, setValue] = useState(null)
let [suffix, setSuffix] = useState(false)
return (
<>
<Combobox value={value} onChange={setValue}>
<Combobox.Input
onChange={NOOP}
displayValue={(str?: string) =>
`${str?.toUpperCase() ?? ''} ${suffix ? 'with suffix' : 'no suffix'}`
}
/>
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
<Combobox.Option value="a">Option A</Combobox.Option>
<Combobox.Option value="b">Option B</Combobox.Option>
<Combobox.Option value="c">Option C</Combobox.Option>
</Combobox.Options>
<button onClick={() => setSuffix((v) => !v)}>Toggle suffix</button>
</Combobox>
</>
)
}
render(<Example />)
expect(getComboboxInput()).toHaveValue(' no suffix')
await click(getComboboxButton())
expect(getComboboxInput()).toHaveValue(' no suffix')
await click(getComboboxOptions()[1])
expect(getComboboxInput()).toHaveValue('B no suffix')
await click(getByText('Toggle suffix'))
expect(getComboboxInput()).toHaveValue('B with suffix')
await click(getComboboxButton())
expect(getComboboxInput()).toHaveValue('B with suffix')
await click(getComboboxOptions()[0])
expect(getComboboxInput()).toHaveValue('A with suffix')
})
)
it(
'should be possible to override the `type` on the input',
suppressConsoleLogs(async () => {
function Example() {
let [value, setValue] = useState(null)
return (
<Combobox value={value} onChange={setValue}>
<Combobox.Input type="search" onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
<Combobox.Option value="a">Option A</Combobox.Option>
<Combobox.Option value="b">Option B</Combobox.Option>
<Combobox.Option value="c">Option C</Combobox.Option>
</Combobox.Options>
</Combobox>
)
}
render(<Example />)
expect(getComboboxInput()).toHaveAttribute('type', 'search')
})
)
xit(
'should reflect the value in the input when the value changes and when you are typing',
suppressConsoleLogs(async () => {
function Example() {
let [value, setValue] = useState<string | null>('bob')
let [_query, setQuery] = useState('')
return (
<Combobox value={value} onChange={setValue}>
{({ open }) => (
<>
<Combobox.Input
onChange={(event) => setQuery(event.target.value)}
displayValue={(person) => `${person ?? ''} - ${open ? 'open' : 'closed'}`}
/>
<Combobox.Button />
<Combobox.Options>
<Combobox.Option value="alice">alice</Combobox.Option>
<Combobox.Option value="bob">bob</Combobox.Option>
<Combobox.Option value="charlie">charlie</Combobox.Option>
</Combobox.Options>
</>
)}
</Combobox>
)
}
render(<Example />)
// Check for proper state sync
expect(getComboboxInput()).toHaveValue('bob - closed')
await click(getComboboxButton())
expect(getComboboxInput()).toHaveValue('bob - open')
await click(getComboboxButton())
expect(getComboboxInput()).toHaveValue('bob - closed')
// Check if we can still edit the input
for (let _ of Array(' - closed'.length)) {
await press(Keys.Backspace, getComboboxInput())
}
getComboboxInput()?.select()
await type(word('alice'), getComboboxInput())
expect(getComboboxInput()).toHaveValue('alice')
// Open the combobox and choose an option
await click(getComboboxOptions()[2])
expect(getComboboxInput()).toHaveValue('charlie - closed')
})
)
it(
'should move the caret to the end of the input when syncing the value',
suppressConsoleLogs(async () => {
function Example() {
return (
<Combobox>
<Combobox.Input />
<Combobox.Button />
<Combobox.Options>
<Combobox.Option value="alice">alice</Combobox.Option>
<Combobox.Option value="bob">bob</Combobox.Option>
<Combobox.Option value="charlie">charlie</Combobox.Option>
</Combobox.Options>
</Combobox>
)
}
render(<Example />)
// Open the combobox
await click(getComboboxButton())
// Choose charlie
await click(getComboboxOptions()[2])
expect(getComboboxInput()).toHaveValue('charlie')
// Ensure the selection is in the correct position
expect(getComboboxInput()?.selectionStart).toBe('charlie'.length)
expect(getComboboxInput()?.selectionEnd).toBe('charlie'.length)
})
)
// Skipped because JSDOM doesn't implement this properly: https://github.com/jsdom/jsdom/issues/3524
xit(
'should not move the caret to the end of the input when syncing the value if a custom selection is made',
suppressConsoleLogs(async () => {
function Example() {
return (
<Combobox>
<Combobox.Input
onFocus={(e) => {
e.target.select()
e.target.setSelectionRange(0, e.target.value.length)
}}
/>
<Combobox.Button />
<Combobox.Options>
<Combobox.Option value="alice">alice</Combobox.Option>
<Combobox.Option value="bob">bob</Combobox.Option>
<Combobox.Option value="charlie">charlie</Combobox.Option>
</Combobox.Options>
</Combobox>
)
}
render(<Example />)
// Open the combobox
await click(getComboboxButton())
// Choose charlie
await click(getComboboxOptions()[2])
expect(getComboboxInput()).toHaveValue('charlie')
// Ensure the selection is in the correct position
expect(getComboboxInput()?.selectionStart).toBe(0)
expect(getComboboxInput()?.selectionEnd).toBe('charlie'.length)
})
)
})
describe('Combobox.Label', () => {
it(
'should be possible to render a Combobox.Label using a render prop',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Label>{(slot) => <>{JSON.stringify(slot)}</>}</Combobox.Label>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
<Combobox.Option value="a">Option A</Combobox.Option>
<Combobox.Option value="b">Option B</Combobox.Option>
<Combobox.Option value="c">Option C</Combobox.Option>
</Combobox.Options>
</Combobox>
)
assertComboboxButton({ state: ComboboxState.InvisibleUnmounted })
assertComboboxLabel({ textContent: JSON.stringify({ open: false, disabled: false }) })
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
await click(getComboboxButton())
assertComboboxLabel({ textContent: JSON.stringify({ open: true, disabled: false }) })
assertComboboxList({ state: ComboboxState.Visible })
assertComboboxLabelLinkedWithCombobox()
assertComboboxButtonLinkedWithComboboxLabel()
})
)
it(
'should be possible to link Input/Button and Label if Label is rendered last',
suppressConsoleLogs(async () => {
render(
<Combobox value="Test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button />
<Combobox.Label>Label</Combobox.Label>
</Combobox>
)
assertComboboxLabelLinkedWithCombobox()
assertComboboxButtonLinkedWithComboboxLabel()
})
)
it(
'should be possible to render a Combobox.Label using a render prop and an `as` prop',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Label as="p">{(slot) => <>{JSON.stringify(slot)}</>}</Combobox.Label>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
<Combobox.Option value="a">Option A</Combobox.Option>
<Combobox.Option value="b">Option B</Combobox.Option>
<Combobox.Option value="c">Option C</Combobox.Option>
</Combobox.Options>
</Combobox>
)
assertComboboxLabel({
textContent: JSON.stringify({ open: false, disabled: false }),
tag: 'p',
})
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
await click(getComboboxButton())
assertComboboxLabel({
textContent: JSON.stringify({ open: true, disabled: false }),
tag: 'p',
})
assertComboboxList({ state: ComboboxState.Visible })
})
)
})
describe('Combobox.Button', () => {
it(
'should be possible to render a Combobox.Button using a render prop',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>{(slot) => <>{JSON.stringify(slot)}</>}</Combobox.Button>
<Combobox.Options>
<Combobox.Option value="a">Option A</Combobox.Option>
<Combobox.Option value="b">Option B</Combobox.Option>
<Combobox.Option value="c">Option C</Combobox.Option>
</Combobox.Options>
</Combobox>
)
assertComboboxButton({
state: ComboboxState.InvisibleUnmounted,
textContent: JSON.stringify({
open: false,
active: false,
disabled: false,
invalid: false,
value: 'test',
hover: false,
focus: false,
}),
})
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
await click(getComboboxButton())
assertComboboxButton({
state: ComboboxState.Visible,
textContent: JSON.stringify({
open: true,
active: true,
disabled: false,
invalid: false,
value: 'test',
hover: false,
focus: false,
}),
})
assertComboboxList({ state: ComboboxState.Visible })
})
)
it(
'should be possible to render a Combobox.Button using a render prop and an `as` prop',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button as="div" role="button">
{(slot) => <>{JSON.stringify(slot)}</>}
</Combobox.Button>
<Combobox.Options>
<Combobox.Option value="a">Option A</Combobox.Option>
<Combobox.Option value="b">Option B</Combobox.Option>
<Combobox.Option value="c">Option C</Combobox.Option>
</Combobox.Options>
</Combobox>
)
assertComboboxButton({
state: ComboboxState.InvisibleUnmounted,
textContent: JSON.stringify({
open: false,
active: false,
disabled: false,
invalid: false,
value: 'test',
hover: false,
focus: false,
}),
})
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
await click(getComboboxButton())
assertComboboxButton({
state: ComboboxState.Visible,
textContent: JSON.stringify({
open: true,
active: true,
disabled: false,
invalid: false,
value: 'test',
hover: false,
focus: false,
}),
})
assertComboboxList({ state: ComboboxState.Visible })
})
)
it(
'should be possible to render a Combobox.Button and a Combobox.Label and see them linked together',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Label>Label</Combobox.Label>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
<Combobox.Option value="a">Option A</Combobox.Option>
<Combobox.Option value="b">Option B</Combobox.Option>
<Combobox.Option value="c">Option C</Combobox.Option>
</Combobox.Options>
</Combobox>
)
// TODO: Needed to make it similar to vue test implementation?
// await new Promise(requestAnimationFrame)
assertComboboxButton({ state: ComboboxState.InvisibleUnmounted })
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
assertComboboxButtonLinkedWithComboboxLabel()
})
)
describe('`type` attribute', () => {
it('should set the `type` to "button" by default', async () => {
render(
<Combobox value={null} onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
</Combobox>
)
expect(getComboboxButton()).toHaveAttribute('type', 'button')
})
it('should not set the `type` to "button" if it already contains a `type`', async () => {
render(
<Combobox value={null} onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button type="submit">Trigger</Combobox.Button>
</Combobox>
)
expect(getComboboxButton()).toHaveAttribute('type', 'submit')
})
it('should set the `type` to "button" when using the `as` prop which resolves to a "button"', async () => {
let CustomButton = React.forwardRef<HTMLButtonElement>((props, ref) => (
<button ref={ref} {...props} />
))
render(
<Combobox value={null} onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button as={CustomButton}>Trigger</Combobox.Button>
</Combobox>
)
expect(getComboboxButton()).toHaveAttribute('type', 'button')
})
it('should not set the type if the "as" prop is not a "button"', async () => {
render(
<Combobox value={null} onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button as="div">Trigger</Combobox.Button>
</Combobox>
)
expect(getComboboxButton()).not.toHaveAttribute('type')
})
it('should not set the `type` to "button" when using the `as` prop which resolves to a "div"', async () => {
let CustomButton = React.forwardRef<HTMLDivElement>((props, ref) => (
<div ref={ref} {...props} />
))
render(
<Combobox value={null} onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button as={CustomButton}>Trigger</Combobox.Button>
</Combobox>
)
expect(getComboboxButton()).not.toHaveAttribute('type')
})
})
it(
'should be possible to render a ComboboxButton using as={Fragment}',
suppressConsoleLogs(async () => {
render(
<Combobox>
<ComboboxInput />
<ComboboxButton as={Fragment}>
<button>Toggle</button>
</ComboboxButton>
<ComboboxOptions>
<ComboboxOption value="a">Option A</ComboboxOption>
<ComboboxOption value="b">Option B</ComboboxOption>
<ComboboxOption value="c">Option C</ComboboxOption>
</ComboboxOptions>
</Combobox>
)
assertComboboxButton({ state: ComboboxState.InvisibleUnmounted })
await click(getComboboxButton())
assertComboboxButton({ state: ComboboxState.Visible })
})
)
})
describe('Combobox.Options', () => {
it(
'should be possible to render Combobox.Options using a render prop',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
{(data) => (
<>
<Combobox.Option value="a">{JSON.stringify(data)}</Combobox.Option>
</>
)}
</Combobox.Options>
</Combobox>
)
assertComboboxButton({ state: ComboboxState.InvisibleUnmounted })
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
await click(getComboboxButton())
assertComboboxButton({ state: ComboboxState.Visible })
assertComboboxList({
state: ComboboxState.Visible,
textContent: JSON.stringify({ open: true }),
})
assertActiveElement(getComboboxInput())
})
)
it('should be possible to always render the Combobox.Options if we provide it a `static` prop', () => {
render(
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options static>
<Combobox.Option value="a">Option A</Combobox.Option>
<Combobox.Option value="b">Option B</Combobox.Option>
<Combobox.Option value="c">Option C</Combobox.Option>
</Combobox.Options>
</Combobox>
)
// Let's verify that the Combobox is already there
expect(getComboboxInput()).not.toBe(null)
})
it('should be possible to use a different render strategy for the Combobox.Options', async () => {
render(
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options unmount={false}>
<Combobox.Option value="a">Option A</Combobox.Option>
<Combobox.Option value="b">Option B</Combobox.Option>
<Combobox.Option value="c">Option C</Combobox.Option>
</Combobox.Options>
</Combobox>
)
assertComboboxList({ state: ComboboxState.InvisibleHidden })
// Let's open the Combobox, to see if it is not hidden anymore
await click(getComboboxButton())
assertComboboxList({ state: ComboboxState.Visible })
})
})
describe('Combobox.Option', () => {
it(
'should be possible to render a Combobox.Option using a render prop',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
<Combobox.Option value="a">{(slot) => <>{JSON.stringify(slot)}</>}</Combobox.Option>
</Combobox.Options>
</Combobox>
)
assertComboboxButton({ state: ComboboxState.InvisibleUnmounted })
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
await click(getComboboxButton())
assertComboboxButton({ state: ComboboxState.Visible })
assertComboboxList({
state: ComboboxState.Visible,
textContent: JSON.stringify({
active: true,
focus: true,
selected: false,
disabled: false,
}),
})
})
)
})
it('should guarantee the order of DOM nodes when performing actions', async () => {
function Example({ hide = false }) {
return (
<>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
<Combobox.Option value="a">Option 1</Combobox.Option>
{!hide && <Combobox.Option value="b">Option 2</Combobox.Option>}
<Combobox.Option value="c">Option 3</Combobox.Option>
</Combobox.Options>
</Combobox>
</>
)
}
let { rerender } = render(<Example />)
// Open the Combobox
await click(getByText('Trigger'))
rerender(<Example hide={true} />) // Remove Combobox.Option 2
rerender(<Example hide={false} />) // Re-add Combobox.Option 2
assertComboboxList({ state: ComboboxState.Visible })
let options = getComboboxOptions()
// Verify that the first combobox option is active
assertActiveComboboxOption(options[0])
await press(Keys.ArrowDown)
// Verify that the second combobox option is active
assertActiveComboboxOption(options[1])
await press(Keys.ArrowDown)
// Verify that the third combobox option is active
assertActiveComboboxOption(options[2])
})
it('should guarantee the order of options based on `order` when performing actions', async () => {
function Example({ hide = false }) {
return (
<>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
<Combobox.Option value="a" order={1}>
Option 1
</Combobox.Option>
{!hide && (
<Combobox.Option value="b" order={2}>
Option 2
</Combobox.Option>
)}
<Combobox.Option value="c" order={3}>
Option 3
</Combobox.Option>
</Combobox.Options>
</Combobox>
</>
)
}
let { rerender } = render(<Example />)
// Open the Combobox
await click(getByText('Trigger'))
rerender(<Example hide={true} />) // Remove Combobox.Option 2
rerender(<Example hide={false} />) // Re-add Combobox.Option 2
assertComboboxList({ state: ComboboxState.Visible })
let options = getComboboxOptions()
// Verify that the first combobox option is active
assertActiveComboboxOption(options[0])
await press(Keys.ArrowDown)
// Verify that the second combobox option is active
assertActiveComboboxOption(options[1])
await press(Keys.ArrowDown)
// Verify that the third combobox option is active
assertActiveComboboxOption(options[2])
})
describe('Uncontrolled', () => {
it('should be possible to use in an uncontrolled way', async () => {
let handleSubmission = jest.fn()
render(
<form
onSubmit={(e) => {
e.preventDefault()
handleSubmission(Object.fromEntries(new FormData(e.target as HTMLFormElement)))
}}
>
<Combobox name="assignee">
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
<Combobox.Option value="alice">Alice</Combobox.Option>
<Combobox.Option value="bob">Bob</Combobox.Option>
<Combobox.Option value="charlie">Charlie</Combobox.Option>
</Combobox.Options>
</Combobox>
<button id="submit">submit</button>
</form>
)
await click(document.getElementById('submit'))
// No values
expect(handleSubmission).toHaveBeenLastCalledWith({})
// Open combobox
await click(getComboboxButton())
// Choose alice
await click(getComboboxOptions()[0])
// Submit
await click(document.getElementById('submit'))
// Alice should be submitted
expect(handleSubmission).toHaveBeenLastCalledWith({ assignee: 'alice' })
// Open combobox
await click(getComboboxButton())
// Choose charlie
await click(getComboboxOptions()[2])
// Submit
await click(document.getElementById('submit'))
// Charlie should be submitted
expect(handleSubmission).toHaveBeenLastCalledWith({ assignee: 'charlie' })
})
it('should expose the value via the render prop', async () => {
let handleSubmission = jest.fn()
let { getByTestId } = render(
<form
onSubmit={(e) => {
e.preventDefault()
handleSubmission(Object.fromEntries(new FormData(e.target as HTMLFormElement)))
}}
>
<Combobox<string> name="assignee">
{({ value }) => (
<>
<div data-testid="value">{value}</div>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>
{({ value }) => (
<>
Trigger
<div data-testid="value-2">{value}</div>
</>
)}
</Combobox.Button>
<Combobox.Options>
<Combobox.Option value="alice">Alice</Combobox.Option>
<Combobox.Option value="bob">Bob</Combobox.Option>
<Combobox.Option value="charlie">Charlie</Combobox.Option>
</Combobox.Options>
</>
)}
</Combobox>
<button id="submit">submit</button>
</form>
)
await click(document.getElementById('submit'))
// No values
expect(handleSubmission).toHaveBeenLastCalledWith({})
// Open combobox
await click(getComboboxButton())
// Choose alice
await click(getComboboxOptions()[0])
expect(getByTestId('value')).toHaveTextContent('alice')
expect(getByTestId('value-2')).toHaveTextContent('alice')
// Submit
await click(document.getElementById('submit'))
// Alice should be submitted
expect(handleSubmission).toHaveBeenLastCalledWith({ assignee: 'alice' })
// Open combobox
await click(getComboboxButton())
// Choose charlie
await click(getComboboxOptions()[2])
expect(getByTestId('value')).toHaveTextContent('charlie')
expect(getByTestId('value-2')).toHaveTextContent('charlie')
// Submit
await click(document.getElementById('submit'))
// Charlie should be submitted
expect(handleSubmission).toHaveBeenLastCalledWith({ assignee: 'charlie' })
})
it('should be possible to provide a default value', async () => {
let handleSubmission = jest.fn()
render(
<form
onSubmit={(e) => {
e.preventDefault()
handleSubmission(Object.fromEntries(new FormData(e.target as HTMLFormElement)))
}}
>
<Combobox name="assignee" defaultValue="bob">
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
<Combobox.Option value="alice">Alice</Combobox.Option>
<Combobox.Option value="bob">Bob</Combobox.Option>
<Combobox.Option value="charlie">Charlie</Combobox.Option>
</Combobox.Options>
</Combobox>
<button id="submit">submit</button>
</form>
)
await click(document.getElementById('submit'))
// Bob is the defaultValue
expect(handleSubmission).toHaveBeenLastCalledWith({ assignee: 'bob' })
// Open combobox
await click(getComboboxButton())
// Choose alice
await click(getComboboxOptions()[0])
// Submit
await click(document.getElementById('submit'))
// Alice should be submitted
expect(handleSubmission).toHaveBeenLastCalledWith({ assignee: 'alice' })
})
it('should be possible to reset to the default value if the form is reset', async () => {
let handleSubmission = jest.fn()
render(
<form
onSubmit={(e) => {
e.preventDefault()
handleSubmission(Object.fromEntries(new FormData(e.target as HTMLFormElement)))
}}
>
<Combobox name="assignee" defaultValue="bob">
<Combobox.Button>{({ value }) => value ?? 'Trigger'}</Combobox.Button>
<Combobox.Input onChange={NOOP} displayValue={(value: string) => value} />
<Combobox.Options>
<Combobox.Option value="alice">Alice</Combobox.Option>
<Combobox.Option value="bob">Bob</Combobox.Option>
<Combobox.Option value="charlie">Charlie</Combobox.Option>
</Combobox.Options>
</Combobox>
<button id="submit">submit</button>
<button type="reset" id="reset">
reset
</button>
</form>
)
await click(document.getElementById('submit'))
// Bob is the defaultValue
expect(handleSubmission).toHaveBeenLastCalledWith({ assignee: 'bob' })
// Open combobox
await click(getComboboxButton())
// Choose alice
await click(getComboboxOptions()[0])
expect(getComboboxButton()).toHaveTextContent('alice')
expect(getComboboxInput()).toHaveValue('alice')
// Reset
await click(document.getElementById('reset'))
// The combobox should be reset to bob
expect(getComboboxButton()).toHaveTextContent('bob')
expect(getComboboxInput()).toHaveValue('bob')
// Open combobox
await click(getComboboxButton())
assertActiveComboboxOption(getComboboxOptions()[1])
})
it('should be possible to reset to the default value if the form is reset (using objects)', async () => {
let handleSubmission = jest.fn()
let data = [
{ id: 1, name: 'alice', label: 'Alice' },
{ id: 2, name: 'bob', label: 'Bob' },
{ id: 3, name: 'charlie', label: 'Charlie' },
]
render(
<form
onSubmit={(e) => {
e.preventDefault()
handleSubmission(Object.fromEntries(new FormData(e.target as HTMLFormElement)))
}}
>
<Combobox<(typeof data)[number]>
name="assignee"
defaultValue={{ id: 2, name: 'bob', label: 'Bob' }}
by="id"
>
<Combobox.Button>{({ value }) => value?.name ?? 'Trigger'}</Combobox.Button>
<Combobox.Input
onChange={NOOP}
displayValue={(value: (typeof data)[0]) => value.name}
/>
<Combobox.Options>
{data.map((person) => (
<Combobox.Option key={person.id} value={person}>
{person.label}
</Combobox.Option>
))}
</Combobox.Options>
</Combobox>
<button id="submit">submit</button>
<button type="reset" id="reset">
reset
</button>
</form>
)
await click(document.getElementById('submit'))
// Bob is the defaultValue
expect(handleSubmission).toHaveBeenLastCalledWith({
'assignee[id]': '2',
'assignee[name]': 'bob',
'assignee[label]': 'Bob',
})
// Open combobox
await click(getComboboxButton())
// Choose alice
await click(getComboboxOptions()[0])
expect(getComboboxButton()).toHaveTextContent('alice')
expect(getComboboxInput()).toHaveValue('alice')
// Reset
await click(document.getElementById('reset'))
// The combobox should be reset to bob
expect(getComboboxButton()).toHaveTextContent('bob')
expect(getComboboxInput()).toHaveValue('bob')
// Open combobox
await click(getComboboxButton())
assertActiveComboboxOption(getComboboxOptions()[1])
})
it('should be possible to reset to the default value in multiple mode', async () => {
let handleSubmission = jest.fn()
let data = ['alice', 'bob', 'charlie']
render(
<form
onSubmit={(e) => {
e.preventDefault()
handleSubmission(Object.fromEntries(new FormData(e.target as HTMLFormElement)))
}}
>
<Combobox name="assignee" defaultValue={['bob'] as string[]} multiple>
<Combobox.Button>{({ value }) => value.join(', ') || 'Trigger'}</Combobox.Button>
<Combobox.Options>
{data.map((person) => (
<Combobox.Option key={person} value={person}>
{person}
</Combobox.Option>
))}
</Combobox.Options>
</Combobox>
<button id="submit">submit</button>
<button type="reset" id="reset">
reset
</button>
</form>
)
await click(document.getElementById('submit'))
// Bob is the defaultValue
expect(handleSubmission).toHaveBeenLastCalledWith({
'assignee[0]': 'bob',
})
await click(document.getElementById('reset'))
await click(document.getElementById('submit'))
// Bob is still the defaultValue
expect(handleSubmission).toHaveBeenLastCalledWith({
'assignee[0]': 'bob',
})
})
it('should still call the onChange listeners when choosing new values', async () => {
let handleChange = jest.fn()
render(
<Combobox name="assignee" onChange={handleChange}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
<Combobox.Option value="alice">Alice</Combobox.Option>
<Combobox.Option value="bob">Bob</Combobox.Option>
<Combobox.Option value="charlie">Charlie</Combobox.Option>
</Combobox.Options>
</Combobox>
)
// Open combobox
await click(getComboboxButton())
// Choose alice
await click(getComboboxOptions()[0])
// Open combobox
await click(getComboboxButton())
// Choose bob
await click(getComboboxOptions()[1])
// Change handler should have been called twice
expect(handleChange).toHaveBeenNthCalledWith(1, 'alice')
expect(handleChange).toHaveBeenNthCalledWith(2, 'bob')
})
})
describe.each([{ virtual: true }, { virtual: false }])('Data attributes', ({ virtual }) => {
let data = ['Option A', 'Option B', 'Option C']
function MyCombobox<T>({
options = data.slice() as T[],
useComboboxOptions = true,
comboboxProps = {},
inputProps = {},
buttonProps = {},
optionProps = {},
}: {
options?: T[]
useComboboxOptions?: boolean
comboboxProps?: Record<string, any>
inputProps?: Record<string, any>
gitextract_53laupa_/
├── .eslintignore
├── .github/
│ ├── CONTRIBUTING.md
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug-report.md
│ │ └── config.yml
│ └── workflows/
│ ├── main.yml
│ ├── prepare-release.yml
│ ├── release-insiders.yml
│ └── release.yml
├── .gitignore
├── .prettierignore
├── .swcrc
├── CHANGELOG.md
├── LICENSE
├── README.md
├── jest/
│ ├── create-jest-config.cjs
│ ├── custom-matchers.ts
│ └── polyfills.ts
├── jest.config.cjs
├── package.json
├── packages/
│ ├── @headlessui-react/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── build/
│ │ │ └── index.cjs
│ │ ├── jest.config.cjs
│ │ ├── jest.setup.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── components/
│ │ │ │ ├── button/
│ │ │ │ │ ├── button.test.tsx
│ │ │ │ │ └── button.tsx
│ │ │ │ ├── checkbox/
│ │ │ │ │ ├── checkbox.test.tsx
│ │ │ │ │ └── checkbox.tsx
│ │ │ │ ├── close-button/
│ │ │ │ │ └── close-button.tsx
│ │ │ │ ├── combobox/
│ │ │ │ │ ├── combobox-machine-glue.tsx
│ │ │ │ │ ├── combobox-machine.ts
│ │ │ │ │ ├── combobox.test.tsx
│ │ │ │ │ └── combobox.tsx
│ │ │ │ ├── combobox-button/
│ │ │ │ │ └── combobox-button.tsx
│ │ │ │ ├── combobox-input/
│ │ │ │ │ └── combobox-input.tsx
│ │ │ │ ├── combobox-label/
│ │ │ │ │ └── combobox-label.tsx
│ │ │ │ ├── combobox-option/
│ │ │ │ │ └── combobox-option.tsx
│ │ │ │ ├── combobox-options/
│ │ │ │ │ └── combobox-options.tsx
│ │ │ │ ├── data-interactive/
│ │ │ │ │ ├── data-interactive.test.tsx
│ │ │ │ │ └── data-interactive.tsx
│ │ │ │ ├── description/
│ │ │ │ │ ├── __snapshots__/
│ │ │ │ │ │ └── description.test.tsx.snap
│ │ │ │ │ ├── description.test.tsx
│ │ │ │ │ └── description.tsx
│ │ │ │ ├── dialog/
│ │ │ │ │ ├── dialog.test.tsx
│ │ │ │ │ └── dialog.tsx
│ │ │ │ ├── dialog-description/
│ │ │ │ │ └── dialog-description.tsx
│ │ │ │ ├── dialog-panel/
│ │ │ │ │ └── dialog-panel.tsx
│ │ │ │ ├── dialog-title/
│ │ │ │ │ └── dialog-title.tsx
│ │ │ │ ├── disclosure/
│ │ │ │ │ ├── disclosure.test.tsx
│ │ │ │ │ └── disclosure.tsx
│ │ │ │ ├── disclosure-button/
│ │ │ │ │ └── disclosure-button.tsx
│ │ │ │ ├── disclosure-panel/
│ │ │ │ │ └── disclosure-panel.tsx
│ │ │ │ ├── field/
│ │ │ │ │ ├── field.test.tsx
│ │ │ │ │ └── field.tsx
│ │ │ │ ├── fieldset/
│ │ │ │ │ ├── fieldset.test.tsx
│ │ │ │ │ └── fieldset.tsx
│ │ │ │ ├── focus-trap/
│ │ │ │ │ ├── focus-trap.test.tsx
│ │ │ │ │ └── focus-trap.tsx
│ │ │ │ ├── focus-trap-features/
│ │ │ │ │ └── focus-trap-features.tsx
│ │ │ │ ├── input/
│ │ │ │ │ ├── input.test.tsx
│ │ │ │ │ └── input.tsx
│ │ │ │ ├── keyboard.ts
│ │ │ │ ├── label/
│ │ │ │ │ ├── __snapshots__/
│ │ │ │ │ │ └── label.test.tsx.snap
│ │ │ │ │ ├── label.test.tsx
│ │ │ │ │ └── label.tsx
│ │ │ │ ├── legend/
│ │ │ │ │ └── legend.tsx
│ │ │ │ ├── listbox/
│ │ │ │ │ ├── listbox-machine-glue.tsx
│ │ │ │ │ ├── listbox-machine.ts
│ │ │ │ │ ├── listbox.test.tsx
│ │ │ │ │ └── listbox.tsx
│ │ │ │ ├── listbox-button/
│ │ │ │ │ └── listbox-button.tsx
│ │ │ │ ├── listbox-label/
│ │ │ │ │ └── listbox-label.tsx
│ │ │ │ ├── listbox-option/
│ │ │ │ │ └── listbox-option.tsx
│ │ │ │ ├── listbox-options/
│ │ │ │ │ └── listbox-options.tsx
│ │ │ │ ├── listbox-selected-option/
│ │ │ │ │ └── listbox-selected-option.tsx
│ │ │ │ ├── menu/
│ │ │ │ │ ├── menu-machine-glue.tsx
│ │ │ │ │ ├── menu-machine.ts
│ │ │ │ │ ├── menu.test.tsx
│ │ │ │ │ └── menu.tsx
│ │ │ │ ├── menu-button/
│ │ │ │ │ └── menu-button.tsx
│ │ │ │ ├── menu-heading/
│ │ │ │ │ └── menu-heading.tsx
│ │ │ │ ├── menu-item/
│ │ │ │ │ └── menu-item.tsx
│ │ │ │ ├── menu-items/
│ │ │ │ │ └── menu-items.tsx
│ │ │ │ ├── menu-section/
│ │ │ │ │ └── menu-section.tsx
│ │ │ │ ├── menu-separator/
│ │ │ │ │ └── menu-separator.tsx
│ │ │ │ ├── mouse.ts
│ │ │ │ ├── popover/
│ │ │ │ │ ├── popover-machine-glue.tsx
│ │ │ │ │ ├── popover-machine.ts
│ │ │ │ │ ├── popover.test.tsx
│ │ │ │ │ └── popover.tsx
│ │ │ │ ├── popover-backdrop/
│ │ │ │ │ └── popover-backdrop.tsx
│ │ │ │ ├── popover-button/
│ │ │ │ │ └── popover-button.tsx
│ │ │ │ ├── popover-group/
│ │ │ │ │ └── popover-group.tsx
│ │ │ │ ├── popover-overlay/
│ │ │ │ │ └── popover-overlay.tsx
│ │ │ │ ├── popover-panel/
│ │ │ │ │ └── popover-panel.tsx
│ │ │ │ ├── portal/
│ │ │ │ │ ├── __snapshots__/
│ │ │ │ │ │ └── portal.test.tsx.snap
│ │ │ │ │ ├── portal.test.tsx
│ │ │ │ │ └── portal.tsx
│ │ │ │ ├── radio/
│ │ │ │ │ └── radio.tsx
│ │ │ │ ├── radio-group/
│ │ │ │ │ ├── radio-group.test.tsx
│ │ │ │ │ └── radio-group.tsx
│ │ │ │ ├── radio-group-description/
│ │ │ │ │ └── radio-group-description.tsx
│ │ │ │ ├── radio-group-label/
│ │ │ │ │ └── radio-group-label.tsx
│ │ │ │ ├── radio-group-option/
│ │ │ │ │ └── radio-group-option.tsx
│ │ │ │ ├── select/
│ │ │ │ │ ├── select.test.tsx
│ │ │ │ │ └── select.tsx
│ │ │ │ ├── switch/
│ │ │ │ │ ├── switch.test.tsx
│ │ │ │ │ └── switch.tsx
│ │ │ │ ├── switch-description/
│ │ │ │ │ └── switch-description.tsx
│ │ │ │ ├── switch-group/
│ │ │ │ │ └── switch-group.tsx
│ │ │ │ ├── switch-label/
│ │ │ │ │ └── switch-label.tsx
│ │ │ │ ├── tab/
│ │ │ │ │ └── tab.tsx
│ │ │ │ ├── tab-group/
│ │ │ │ │ └── tab-group.tsx
│ │ │ │ ├── tab-list/
│ │ │ │ │ └── tab-list.tsx
│ │ │ │ ├── tab-panel/
│ │ │ │ │ └── tab-panel.tsx
│ │ │ │ ├── tab-panels/
│ │ │ │ │ └── tab-panels.tsx
│ │ │ │ ├── tabs/
│ │ │ │ │ ├── tabs.ssr.test.tsx
│ │ │ │ │ ├── tabs.test.tsx
│ │ │ │ │ └── tabs.tsx
│ │ │ │ ├── textarea/
│ │ │ │ │ ├── textarea.test.tsx
│ │ │ │ │ └── textarea.tsx
│ │ │ │ ├── tooltip/
│ │ │ │ │ └── tooltip.tsx
│ │ │ │ ├── transition/
│ │ │ │ │ ├── __snapshots__/
│ │ │ │ │ │ └── transition.test.tsx.snap
│ │ │ │ │ ├── transition.ssr.test.tsx
│ │ │ │ │ ├── transition.test.tsx
│ │ │ │ │ └── transition.tsx
│ │ │ │ ├── transition-child/
│ │ │ │ │ └── transition-child.tsx
│ │ │ │ └── transitions/
│ │ │ │ └── transition.tsx
│ │ │ ├── hooks/
│ │ │ │ ├── __mocks__/
│ │ │ │ │ └── use-id.ts
│ │ │ │ ├── document-overflow/
│ │ │ │ │ ├── adjust-scrollbar-padding.ts
│ │ │ │ │ ├── handle-ios-locking.ts
│ │ │ │ │ ├── overflow-store.ts
│ │ │ │ │ ├── prevent-scroll.ts
│ │ │ │ │ └── use-document-overflow.ts
│ │ │ │ ├── use-active-press.tsx
│ │ │ │ ├── use-by-comparator.ts
│ │ │ │ ├── use-computed.ts
│ │ │ │ ├── use-controllable.ts
│ │ │ │ ├── use-default-value.ts
│ │ │ │ ├── use-disposables.ts
│ │ │ │ ├── use-document-event.ts
│ │ │ │ ├── use-element-size.ts
│ │ │ │ ├── use-escape.ts
│ │ │ │ ├── use-event-listener.ts
│ │ │ │ ├── use-event.ts
│ │ │ │ ├── use-flags.ts
│ │ │ │ ├── use-handle-toggle.tsx
│ │ │ │ ├── use-id.ts
│ │ │ │ ├── use-inert-others.test.tsx
│ │ │ │ ├── use-inert-others.tsx
│ │ │ │ ├── use-is-initial-render.ts
│ │ │ │ ├── use-is-mounted.ts
│ │ │ │ ├── use-is-top-layer.ts
│ │ │ │ ├── use-is-touch-device.ts
│ │ │ │ ├── use-iso-morphic-effect.ts
│ │ │ │ ├── use-latest-value.ts
│ │ │ │ ├── use-on-disappear.ts
│ │ │ │ ├── use-on-unmount.ts
│ │ │ │ ├── use-outside-click.ts
│ │ │ │ ├── use-owner.ts
│ │ │ │ ├── use-quick-release.ts
│ │ │ │ ├── use-refocusable-input.ts
│ │ │ │ ├── use-resolve-button-type.ts
│ │ │ │ ├── use-resolved-tag.ts
│ │ │ │ ├── use-root-containers.tsx
│ │ │ │ ├── use-scroll-lock.ts
│ │ │ │ ├── use-server-handoff-complete.ts
│ │ │ │ ├── use-slot.ts
│ │ │ │ ├── use-store.ts
│ │ │ │ ├── use-sync-refs.ts
│ │ │ │ ├── use-tab-direction.ts
│ │ │ │ ├── use-text-value.ts
│ │ │ │ ├── use-tracked-pointer.ts
│ │ │ │ ├── use-transition.ts
│ │ │ │ ├── use-tree-walker.ts
│ │ │ │ ├── use-watch.ts
│ │ │ │ └── use-window-event.ts
│ │ │ ├── index.test.ts
│ │ │ ├── index.ts
│ │ │ ├── internal/
│ │ │ │ ├── close-provider.tsx
│ │ │ │ ├── disabled.tsx
│ │ │ │ ├── floating.tsx
│ │ │ │ ├── focus-sentinel.tsx
│ │ │ │ ├── form-fields.tsx
│ │ │ │ ├── frozen.tsx
│ │ │ │ ├── hidden.tsx
│ │ │ │ ├── id.tsx
│ │ │ │ ├── open-closed.tsx
│ │ │ │ └── portal-force-root.tsx
│ │ │ ├── machine.ts
│ │ │ ├── machines/
│ │ │ │ └── stack-machine.ts
│ │ │ ├── react-glue.tsx
│ │ │ ├── test-utils/
│ │ │ │ ├── accessibility-assertions.ts
│ │ │ │ ├── execute-timeline.ts
│ │ │ │ ├── fake-pointer.ts
│ │ │ │ ├── interactions.test.tsx
│ │ │ │ ├── interactions.ts
│ │ │ │ ├── report-dom-node-changes.ts
│ │ │ │ ├── scenarios.tsx
│ │ │ │ ├── snapshot.ts
│ │ │ │ ├── ssr.tsx
│ │ │ │ └── suppress-console-logs.ts
│ │ │ ├── types.ts
│ │ │ └── utils/
│ │ │ ├── __snapshots__/
│ │ │ │ └── render.test.tsx.snap
│ │ │ ├── active-element-history.ts
│ │ │ ├── bugs.ts
│ │ │ ├── calculate-active-index.ts
│ │ │ ├── class-names.ts
│ │ │ ├── default-map.ts
│ │ │ ├── disposables.ts
│ │ │ ├── document-ready.ts
│ │ │ ├── dom.ts
│ │ │ ├── element-movement.ts
│ │ │ ├── env.ts
│ │ │ ├── focus-management.ts
│ │ │ ├── form.test.ts
│ │ │ ├── form.ts
│ │ │ ├── get-text-value.test.ts
│ │ │ ├── get-text-value.ts
│ │ │ ├── match.ts
│ │ │ ├── micro-task.ts
│ │ │ ├── once.ts
│ │ │ ├── owner.ts
│ │ │ ├── platform.ts
│ │ │ ├── render.test.tsx
│ │ │ ├── render.ts
│ │ │ ├── stable-collection.tsx
│ │ │ ├── start-transition.ts
│ │ │ └── store.ts
│ │ ├── tsconfig.json
│ │ └── types/
│ │ └── jest.d.ts
│ ├── @headlessui-tailwindcss/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── build/
│ │ │ └── index.cjs
│ │ ├── jest.config.cjs
│ │ ├── package.json
│ │ ├── scripts/
│ │ │ └── fix-types.cjs
│ │ ├── src/
│ │ │ ├── __snapshots__/
│ │ │ │ └── index.test.ts.snap
│ │ │ ├── index.test.ts
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ └── @headlessui-vue/
│ ├── CHANGELOG.md
│ ├── LICENSE
│ ├── README.md
│ ├── build/
│ │ └── index.cjs
│ ├── jest.config.cjs
│ ├── package.json
│ ├── src/
│ │ ├── components/
│ │ │ ├── combobox/
│ │ │ │ ├── combobox.test.ts
│ │ │ │ └── combobox.ts
│ │ │ ├── description/
│ │ │ │ ├── __snapshots__/
│ │ │ │ │ └── description.test.ts.snap
│ │ │ │ ├── description.test.ts
│ │ │ │ └── description.ts
│ │ │ ├── dialog/
│ │ │ │ ├── dialog.test.ts
│ │ │ │ └── dialog.ts
│ │ │ ├── disclosure/
│ │ │ │ ├── disclosure.srr.test.ts
│ │ │ │ ├── disclosure.test.ts
│ │ │ │ └── disclosure.ts
│ │ │ ├── focus-trap/
│ │ │ │ ├── focus-trap.test.ts
│ │ │ │ └── focus-trap.ts
│ │ │ ├── label/
│ │ │ │ ├── __snapshots__/
│ │ │ │ │ └── label.test.ts.snap
│ │ │ │ ├── label.test.ts
│ │ │ │ └── label.ts
│ │ │ ├── listbox/
│ │ │ │ ├── listbox.test.tsx
│ │ │ │ └── listbox.ts
│ │ │ ├── menu/
│ │ │ │ ├── menu.test.tsx
│ │ │ │ └── menu.ts
│ │ │ ├── popover/
│ │ │ │ ├── popover.test.ts
│ │ │ │ └── popover.ts
│ │ │ ├── portal/
│ │ │ │ ├── __snapshots__/
│ │ │ │ │ └── portal.test.ts.snap
│ │ │ │ ├── portal.test.ts
│ │ │ │ └── portal.ts
│ │ │ ├── radio-group/
│ │ │ │ ├── radio-group.test.ts
│ │ │ │ └── radio-group.ts
│ │ │ ├── switch/
│ │ │ │ ├── switch.test.tsx
│ │ │ │ └── switch.ts
│ │ │ ├── tabs/
│ │ │ │ ├── tabs.ssr.test.ts
│ │ │ │ ├── tabs.test.ts
│ │ │ │ └── tabs.ts
│ │ │ └── transitions/
│ │ │ ├── __snapshots__/
│ │ │ │ └── transition.test.ts.snap
│ │ │ ├── transition.ssr.test.ts
│ │ │ ├── transition.test.ts
│ │ │ ├── transition.ts
│ │ │ └── utils/
│ │ │ ├── transition.test.ts
│ │ │ └── transition.ts
│ │ ├── hooks/
│ │ │ ├── __mocks__/
│ │ │ │ └── use-id.ts
│ │ │ ├── document-overflow/
│ │ │ │ ├── adjust-scrollbar-padding.ts
│ │ │ │ ├── handle-ios-locking.ts
│ │ │ │ ├── overflow-store.ts
│ │ │ │ ├── prevent-scroll.ts
│ │ │ │ └── use-document-overflow.ts
│ │ │ ├── use-controllable.ts
│ │ │ ├── use-disposables.ts
│ │ │ ├── use-document-event.ts
│ │ │ ├── use-event-listener.ts
│ │ │ ├── use-frame-debounce.ts
│ │ │ ├── use-id.ts
│ │ │ ├── use-inert.test.ts
│ │ │ ├── use-inert.ts
│ │ │ ├── use-outside-click.ts
│ │ │ ├── use-resolve-button-type.ts
│ │ │ ├── use-root-containers.ts
│ │ │ ├── use-store.ts
│ │ │ ├── use-tab-direction.ts
│ │ │ ├── use-text-value.ts
│ │ │ ├── use-tracked-pointer.ts
│ │ │ ├── use-tree-walker.ts
│ │ │ └── use-window-event.ts
│ │ ├── index.test.ts
│ │ ├── index.ts
│ │ ├── internal/
│ │ │ ├── dom-containers.ts
│ │ │ ├── focus-sentinel.ts
│ │ │ ├── hidden.ts
│ │ │ ├── open-closed.ts
│ │ │ ├── portal-force-root.ts
│ │ │ └── stack-context.ts
│ │ ├── keyboard.ts
│ │ ├── mouse.ts
│ │ ├── test-utils/
│ │ │ ├── accessibility-assertions.ts
│ │ │ ├── execute-timeline.ts
│ │ │ ├── fake-pointer.ts
│ │ │ ├── html.ts
│ │ │ ├── interactions.test.ts
│ │ │ ├── interactions.ts
│ │ │ ├── report-dom-node-changes.ts
│ │ │ ├── ssr.ts
│ │ │ ├── suppress-console-logs.ts
│ │ │ └── vue-testing-library.ts
│ │ └── utils/
│ │ ├── active-element-history.ts
│ │ ├── calculate-active-index.ts
│ │ ├── disposables.ts
│ │ ├── document-ready.ts
│ │ ├── dom.ts
│ │ ├── env.ts
│ │ ├── focus-management.ts
│ │ ├── form.test.ts
│ │ ├── form.ts
│ │ ├── get-text-value.test.ts
│ │ ├── get-text-value.ts
│ │ ├── match.ts
│ │ ├── micro-task.ts
│ │ ├── once.ts
│ │ ├── owner.ts
│ │ ├── pipeline.ts
│ │ ├── platform.ts
│ │ ├── render.test.ts
│ │ ├── render.ts
│ │ ├── resolve-prop-value.ts
│ │ └── store.ts
│ ├── tsconfig.json
│ └── types/
│ └── jest.d.ts
├── playgrounds/
│ ├── react/
│ │ ├── components/
│ │ │ ├── button.tsx
│ │ │ └── input.tsx
│ │ ├── data.ts
│ │ ├── next-env.d.ts
│ │ ├── next.config.js
│ │ ├── package.json
│ │ ├── pages/
│ │ │ ├── _app.tsx
│ │ │ ├── _document.tsx
│ │ │ ├── _error.tsx
│ │ │ ├── combinations/
│ │ │ │ ├── form.tsx
│ │ │ │ └── tabs-in-dialog.tsx
│ │ │ ├── combobox/
│ │ │ │ ├── combobox-countries.tsx
│ │ │ │ ├── combobox-open-on-focus.tsx
│ │ │ │ ├── combobox-virtual-with-empty-states.tsx
│ │ │ │ ├── combobox-virtualized.tsx
│ │ │ │ ├── combobox-with-pure-tailwind.tsx
│ │ │ │ ├── command-palette-with-groups.tsx
│ │ │ │ ├── command-palette.tsx
│ │ │ │ └── multi-select.tsx
│ │ │ ├── dialog/
│ │ │ │ ├── dialog-built-in-transition.tsx
│ │ │ │ ├── dialog-focus-issue.tsx
│ │ │ │ ├── dialog-scroll-issue.tsx
│ │ │ │ ├── dialog-with-shadow-children.tsx
│ │ │ │ ├── dialog.tsx
│ │ │ │ ├── scrollable-dialog.tsx
│ │ │ │ ├── scrollable-page-with-dialog.tsx
│ │ │ │ └── sibling-dialogs.tsx
│ │ │ ├── disclosure/
│ │ │ │ └── disclosure.tsx
│ │ │ ├── listbox/
│ │ │ │ ├── listbox-overlaps.tsx
│ │ │ │ ├── listbox-with-pure-tailwind.tsx
│ │ │ │ ├── multi-select.tsx
│ │ │ │ └── multiple-elements.tsx
│ │ │ ├── menu/
│ │ │ │ ├── menu-with-floating-ui.tsx
│ │ │ │ ├── menu-with-framer-motion.tsx
│ │ │ │ ├── menu-with-popper.tsx
│ │ │ │ ├── menu-with-transition-and-popper.tsx
│ │ │ │ ├── menu-with-transition.tsx
│ │ │ │ ├── menu.tsx
│ │ │ │ └── multiple-elements.tsx
│ │ │ ├── popover/
│ │ │ │ └── popover.tsx
│ │ │ ├── radio-group/
│ │ │ │ └── radio-group.tsx
│ │ │ ├── styles.css
│ │ │ ├── suspense/
│ │ │ │ └── portal.tsx
│ │ │ ├── switch/
│ │ │ │ └── switch-with-pure-tailwind.tsx
│ │ │ ├── tabs/
│ │ │ │ └── tabs-with-pure-tailwind.tsx
│ │ │ └── transitions/
│ │ │ ├── appear.tsx
│ │ │ ├── both-apis.tsx
│ │ │ ├── component-examples/
│ │ │ │ ├── dropdown.tsx
│ │ │ │ ├── modal.tsx
│ │ │ │ ├── nested/
│ │ │ │ │ ├── hidden.tsx
│ │ │ │ │ └── unmount.tsx
│ │ │ │ └── peek-a-boo.tsx
│ │ │ ├── full-page-examples/
│ │ │ │ ├── full-page-transition.tsx
│ │ │ │ └── layout-with-sidebar.tsx
│ │ │ └── react-hot-toast.tsx
│ │ ├── postcss.config.js
│ │ ├── tsconfig.json
│ │ └── utils/
│ │ ├── class-names.ts
│ │ ├── hooks/
│ │ │ └── use-popper.ts
│ │ ├── match.ts
│ │ └── resolve-all-examples.ts
│ └── vue/
│ ├── index.html
│ ├── package.json
│ ├── postcss.config.js
│ ├── src/
│ │ ├── .generated/
│ │ │ └── .gitignore
│ │ ├── App.vue
│ │ ├── KeyCaster.vue
│ │ ├── Layout.vue
│ │ ├── components/
│ │ │ ├── Button.vue
│ │ │ ├── Home.vue
│ │ │ ├── combinations/
│ │ │ │ ├── form.vue
│ │ │ │ └── tabs-in-dialog.vue
│ │ │ ├── combobox/
│ │ │ │ ├── _virtual-example.vue
│ │ │ │ ├── combobox-countries.vue
│ │ │ │ ├── combobox-open-on-focus.vue
│ │ │ │ ├── combobox-virtual-with-empty-states.vue
│ │ │ │ ├── combobox-virtualized.vue
│ │ │ │ ├── combobox-with-pure-tailwind.vue
│ │ │ │ ├── command-palette-with-groups.vue
│ │ │ │ ├── command-palette.vue
│ │ │ │ └── multi-select.vue
│ │ │ ├── dialog/
│ │ │ │ ├── dialog.vue
│ │ │ │ └── slide-over.vue
│ │ │ ├── disclosure/
│ │ │ │ └── disclosure.vue
│ │ │ ├── focus-trap/
│ │ │ │ └── focus-trap.vue
│ │ │ ├── listbox/
│ │ │ │ ├── listbox.vue
│ │ │ │ ├── multi-select.vue
│ │ │ │ └── multiple-elements.vue
│ │ │ ├── menu/
│ │ │ │ ├── menu-with-floating-ui.vue
│ │ │ │ ├── menu-with-popper.vue
│ │ │ │ ├── menu-with-transition-and-popper.vue
│ │ │ │ ├── menu-with-transition.vue
│ │ │ │ ├── menu.vue
│ │ │ │ └── multiple-elements.vue
│ │ │ ├── popover/
│ │ │ │ └── popover.vue
│ │ │ ├── portal/
│ │ │ │ └── portal.vue
│ │ │ ├── radio-group/
│ │ │ │ └── radio-group.vue
│ │ │ ├── switch/
│ │ │ │ └── switch.vue
│ │ │ └── tabs/
│ │ │ ├── simple-tabs.vue
│ │ │ └── tabs.vue
│ │ ├── data.ts
│ │ ├── main.ts
│ │ ├── playground-utils/
│ │ │ └── hooks/
│ │ │ └── use-popper.js
│ │ ├── router.ts
│ │ └── styles.css
│ ├── tsconfig.json
│ ├── vercel.json
│ └── vite.config.js
└── scripts/
├── build.sh
├── lint.sh
├── make-nextjs-happy.js
├── package-path.js
├── release-channel.js
├── release-notes.js
├── resolve-files.js
├── rewrite-imports.js
├── test.sh
└── watch.sh
SYMBOL INDEX (1932 symbols across 299 files)
FILE: jest/custom-matchers.ts
method toBeWithinRenderFrame (line 10) | toBeWithinRenderFrame(actual, expected) {
FILE: jest/polyfills.ts
method get (line 14) | get() {
method set (line 17) | set(value) {
class PointerEvent (line 25) | class PointerEvent extends Event {
method constructor (line 26) | constructor(type, props) {
FILE: packages/@headlessui-react/src/components/button/button.tsx
constant DEFAULT_BUTTON_TAG (line 18) | let DEFAULT_BUTTON_TAG = 'button' as const
type ButtonRenderPropArg (line 20) | type ButtonRenderPropArg = {
type ButtonPropsWeControl (line 27) | type ButtonPropsWeControl = never
type ButtonProps (line 29) | type ButtonProps<TTag extends ElementType = typeof DEFAULT_BUTTON_TAG> =...
function ButtonFn (line 40) | function ButtonFn<TTag extends ElementType = typeof DEFAULT_BUTTON_TAG>(
type _internal_ComponentButton (line 76) | interface _internal_ComponentButton extends HasDisplayName {
FILE: packages/@headlessui-react/src/components/checkbox/checkbox.test.tsx
method performUserInteraction (line 20) | async performUserInteraction(control) {
FILE: packages/@headlessui-react/src/components/checkbox/checkbox.tsx
constant DEFAULT_CHECKBOX_TAG (line 37) | let DEFAULT_CHECKBOX_TAG = 'span' as const
type CheckboxRenderPropArg (line 38) | type CheckboxRenderPropArg = {
type CheckboxPropsWeControl (line 48) | type CheckboxPropsWeControl =
type CheckboxProps (line 55) | type CheckboxProps<
function CheckboxFn (line 77) | function CheckboxFn<TTag extends ElementType = typeof DEFAULT_CHECKBOX_T...
type _internal_ComponentCheckbox (line 204) | interface _internal_ComponentCheckbox extends HasDisplayName {
FILE: packages/@headlessui-react/src/components/close-button/close-button.tsx
constant DEFAULT_BUTTON_TAG (line 8) | let DEFAULT_BUTTON_TAG = 'button' as const
type CloseButtonProps (line 10) | type CloseButtonProps<TTag extends ElementType = typeof DEFAULT_BUTTON_T...
function CloseButtonFn (line 13) | function CloseButtonFn<TTag extends ElementType = typeof DEFAULT_BUTTON_...
FILE: packages/@headlessui-react/src/components/combobox/combobox-machine-glue.tsx
function useComboboxMachineContext (line 6) | function useComboboxMachineContext<T>(component: string) {
function useComboboxMachine (line 16) | function useComboboxMachine({
FILE: packages/@headlessui-react/src/components/combobox/combobox-machine.ts
type MutableRefObject (line 13) | interface MutableRefObject<T> {
type ComboboxState (line 17) | enum ComboboxState {
type ValueMode (line 22) | enum ValueMode {
type ActivationTrigger (line 27) | enum ActivationTrigger {
type ComboboxOptionDataRef (line 33) | type ComboboxOptionDataRef<T> = MutableRefObject<{
type State (line 40) | interface State<T> {
type ActionTypes (line 88) | enum ActionTypes {
function adjustOrderedState (line 111) | function adjustOrderedState<T>(
type Actions (line 143) | type Actions<T> =
method [ActionTypes.CloseCombobox] (line 178) | [ActionTypes.CloseCombobox](state) {
method [ActionTypes.OpenCombobox] (line 203) | [ActionTypes.OpenCombobox](state) {
method [ActionTypes.SetTyping] (line 228) | [ActionTypes.SetTyping](state, action) {
method [ActionTypes.GoToOption] (line 232) | [ActionTypes.GoToOption](state, action) {
method [ActionTypes.MarkInputAsMoved] (line 429) | [ActionTypes.MarkInputAsMoved](state) {
class ComboboxMachine (line 439) | class ComboboxMachine<T> extends Machine<State<T>, Actions<T>> {
method new (line 440) | static new<T, TMultiple extends boolean | undefined>({
method constructor (line 475) | constructor(initialState: State<T>) {
method didInputMove (line 689) | didInputMove(state: State<T>) {
method reduce (line 694) | reduce(state: Readonly<State<T>>, action: Actions<T>): State<T> {
FILE: packages/@headlessui-react/src/components/combobox/combobox.test.tsx
function Example (line 387) | function Example() {
function Example (line 432) | function Example() {
function Example (line 502) | function Example() {
function Example (line 610) | function Example() {
function Example (line 644) | function Example() {
function Example (line 678) | function Example() {
function Example (line 718) | function Example() {
function Example (line 772) | function Example() {
function Example (line 797) | function Example() {
function Example (line 849) | function Example() {
function Example (line 883) | function Example() {
function Example (line 1315) | function Example({ hide = false }) {
function Example (line 1358) | function Example({ hide = false }) {
function MyCombobox (line 1772) | function MyCombobox<T>({
function Debug (line 2025) | function Debug({ fn, name }: { fn: (text: string) => void; name: string ...
function MyCombobox (line 2094) | function MyCombobox<T>({
function Example (line 2818) | function Example() {
function Example (line 2879) | function Example() {
function Example (line 2920) | function Example() {
function Example (line 2960) | function Example() {
function Example (line 3001) | function Example() {
function Example (line 3042) | function Example() {
function Example (line 4101) | function Example() {
type Option (line 4169) | type Option = { value: string; name: string; disabled: boolean }
function Example (line 4170) | function Example(props: { people: { value: string; name: string; disable...
function MyCombobox (line 4432) | function MyCombobox<T>({
function Example (line 5075) | function Example() {
function Example (line 5140) | function Example() {
function Example (line 5193) | function Example() {
function Example (line 5282) | function Example() {
function Example (line 5316) | function Example() {
function Example (line 5353) | function Example() {
function Example (line 5396) | function Example() {
function Example (line 5438) | function Example() {
function Example (line 5474) | function Example() {
function Example (line 5503) | function Example() {
function Example (line 5536) | function Example() {
function Example (line 5584) | function Example() {
function Example (line 5629) | function Example() {
function Example (line 5674) | function Example() {
function Example (line 5737) | function Example() {
function Example (line 5799) | function Example() {
FILE: packages/@headlessui-react/src/components/combobox/combobox.tsx
function useData (line 121) | function useData(component: string) {
type _Data (line 130) | type _Data = ReturnType<typeof useData>
function VirtualProvider (line 134) | function VirtualProvider(props: {
constant DEFAULT_COMBOBOX_TAG (line 238) | let DEFAULT_COMBOBOX_TAG = Fragment
type ComboboxRenderPropArg (line 239) | type ComboboxRenderPropArg<TValue, TActive = TValue> = {
type ComboboxProps (line 248) | type ComboboxProps<
function ComboboxFn (line 287) | function ComboboxFn<TValue, TTag extends ElementType = typeof DEFAULT_CO...
constant DEFAULT_INPUT_TAG (line 488) | let DEFAULT_INPUT_TAG = 'input' as const
type InputRenderPropArg (line 489) | type InputRenderPropArg = {
type InputPropsWeControl (line 497) | type InputPropsWeControl =
type ComboboxInputProps (line 506) | type ComboboxInputProps<
function InputFn (line 522) | function InputFn<
constant DEFAULT_BUTTON_TAG (line 962) | let DEFAULT_BUTTON_TAG = 'button' as const
type ButtonRenderPropArg (line 963) | type ButtonRenderPropArg = {
type ButtonPropsWeControl (line 972) | type ButtonPropsWeControl =
type ComboboxButtonProps (line 980) | type ComboboxButtonProps<TTag extends ElementType = typeof DEFAULT_BUTTO...
function ButtonFn (line 990) | function ButtonFn<TTag extends ElementType = typeof DEFAULT_BUTTON_TAG>(
constant DEFAULT_OPTIONS_TAG (line 1155) | let DEFAULT_OPTIONS_TAG = 'div' as const
type OptionsRenderPropArg (line 1156) | type OptionsRenderPropArg = {
type OptionsPropsWeControl (line 1160) | type OptionsPropsWeControl = 'aria-labelledby' | 'aria-multiselectable' ...
type ComboboxOptionsProps (line 1164) | type ComboboxOptionsProps<TTag extends ElementType = typeof DEFAULT_OPTI...
function OptionsFn (line 1177) | function OptionsFn<TTag extends ElementType = typeof DEFAULT_OPTIONS_TAG>(
constant DEFAULT_OPTION_TAG (line 1407) | let DEFAULT_OPTION_TAG = 'div' as const
type OptionRenderPropArg (line 1408) | type OptionRenderPropArg = {
type OptionPropsWeControl (line 1415) | type OptionPropsWeControl = 'role' | 'tabIndex' | 'aria-disabled' | 'ari...
type ComboboxOptionProps (line 1417) | type ComboboxOptionProps<
function OptionFn (line 1431) | function OptionFn<
type _internal_ComponentCombobox (line 1614) | interface _internal_ComponentCombobox extends HasDisplayName {
type _internal_ComponentComboboxButton (line 1624) | interface _internal_ComponentComboboxButton extends HasDisplayName {
type _internal_ComponentComboboxInput (line 1630) | interface _internal_ComponentComboboxInput extends HasDisplayName {
type _internal_ComponentComboboxLabel (line 1636) | interface _internal_ComponentComboboxLabel extends _internal_ComponentLa...
type _internal_ComponentComboboxOptions (line 1638) | interface _internal_ComponentComboboxOptions extends HasDisplayName {
type _internal_ComponentComboboxOption (line 1644) | interface _internal_ComponentComboboxOption extends HasDisplayName {
FILE: packages/@headlessui-react/src/components/data-interactive/data-interactive.tsx
constant DEFAULT_DATA_INTERACTIVE_TAG (line 17) | let DEFAULT_DATA_INTERACTIVE_TAG = Fragment
type DataInteractiveRenderPropArg (line 19) | type DataInteractiveRenderPropArg = {
type DataInteractivePropsWeControl (line 24) | type DataInteractivePropsWeControl = never
type DataInteractiveProps (line 26) | type DataInteractiveProps<TTag extends ElementType = typeof DEFAULT_DATA...
function DataInteractiveFn (line 29) | function DataInteractiveFn<TTag extends ElementType = typeof DEFAULT_DAT...
type _internal_ComponentDataInteractive (line 59) | interface _internal_ComponentDataInteractive extends HasDisplayName {
FILE: packages/@headlessui-react/src/components/description/description.test.tsx
function Component (line 8) | function Component(props: { children: ReactNode }) {
function Example (line 18) | function Example() {
function Component (line 27) | function Component(props: { children: ReactNode }) {
function Example (line 37) | function Example() {
function Component (line 51) | function Component(props: { children: ReactNode }) {
function Example (line 61) | function Example() {
FILE: packages/@headlessui-react/src/components/description/description.tsx
type SharedData (line 23) | interface SharedData {
function useDescriptionContext (line 34) | function useDescriptionContext() {
function useDescribedBy (line 46) | function useDescribedBy() {
type DescriptionProviderProps (line 50) | interface DescriptionProviderProps extends SharedData {
function useDescriptions (line 55) | function useDescriptions(): [
constant DEFAULT_DESCRIPTION_TAG (line 104) | let DEFAULT_DESCRIPTION_TAG = 'p' as const
type DescriptionProps (line 106) | type DescriptionProps<TTag extends ElementType = typeof DEFAULT_DESCRIPT...
function DescriptionFn (line 109) | function DescriptionFn<TTag extends ElementType = typeof DEFAULT_DESCRIP...
type _internal_ComponentDescription (line 136) | interface _internal_ComponentDescription extends HasDisplayName {
FILE: packages/@headlessui-react/src/components/dialog/dialog.test.tsx
function nextFrame (line 26) | function nextFrame() {
function frames (line 30) | async function frames(count: number) {
function TabSentinel (line 36) | function TabSentinel(props: PropsOf<'button'>) {
function Example (line 89) | function Example() {
function Example (line 118) | function Example() {
function Example (line 147) | function Example() {
function Example (line 232) | function Example() {
function Example (line 298) | function Example() {
function Example (line 333) | function Example() {
function Example (line 369) | function Example() {
function Example (line 412) | function Example() {
function DialogWrapper (line 434) | function DialogWrapper({
function Example (line 495) | function Example({ open = true }) {
function Example (line 521) | function Example({ open = true }) {
function Example (line 549) | function Example() {
function Example (line 618) | function Example() {
function Example (line 724) | function Example() {
function Example (line 759) | function Example() {
function Example (line 795) | function Example() {
function Example (line 839) | function Example() {
function Example (line 890) | function Example() {
function Example (line 937) | function Example() {
function Example (line 987) | function Example() {
function Example (line 1022) | function Example() {
function Example (line 1054) | function Example() {
function Example (line 1093) | function Example() {
function ThirdPartyLibrary (line 1134) | function ThirdPartyLibrary() {
function Example (line 1145) | function Example() {
function ThirdPartyLibrary (line 1186) | function ThirdPartyLibrary() {
function Example (line 1197) | function Example() {
function ShadowChildren (line 1240) | function ShadowChildren({ id, buttonId }: { id: string; buttonId: string...
function Example (line 1259) | function Example() {
function Example (line 1331) | function Example() {
function Example (line 1366) | function Example() {
function Example (line 1398) | function Example() {
function Example (line 1430) | function Example() {
function Example (line 1462) | function Example() {
type RenderStrategy (line 1502) | type RenderStrategy = 'mounted' | 'always'
function Nested (line 1504) | function Nested({
function Example (line 1539) | function Example({ renderWhen = 'mounted' }: { renderWhen: RenderStrateg...
FILE: packages/@headlessui-react/src/components/dialog/dialog.tsx
type DialogStates (line 63) | enum DialogStates {
type StateDefinition (line 68) | interface StateDefinition {
type ActionTypes (line 73) | enum ActionTypes {
type Actions (line 77) | type Actions = { type: ActionTypes.SetTitleId; id: string | null }
method [ActionTypes.SetTitleId] (line 85) | [ActionTypes.SetTitleId](state, action) {
function useDialogContext (line 105) | function useDialogContext(component: string) {
function stateReducer (line 115) | function stateReducer(state: StateDefinition, action: Actions) {
method current (line 186) | get current() {
constant DEFAULT_DIALOG_TAG (line 352) | let DEFAULT_DIALOG_TAG = 'div' as const
type DialogRenderPropArg (line 353) | type DialogRenderPropArg = {
type DialogPropsWeControl (line 356) | type DialogPropsWeControl = 'aria-describedby' | 'aria-labelledby' | 'ar...
type DialogProps (line 360) | type DialogProps<TTag extends ElementType = typeof DEFAULT_DIALOG_TAG> =...
function DialogFn (line 375) | function DialogFn<TTag extends ElementType = typeof DEFAULT_DIALOG_TAG>(
constant DEFAULT_PANEL_TAG (line 435) | let DEFAULT_PANEL_TAG = 'div' as const
type PanelRenderPropArg (line 436) | type PanelRenderPropArg = {
type DialogPanelProps (line 440) | type DialogPanelProps<TTag extends ElementType = typeof DEFAULT_PANEL_TA...
function PanelFn (line 447) | function PanelFn<TTag extends ElementType = typeof DEFAULT_PANEL_TAG>(
constant DEFAULT_BACKDROP_TAG (line 490) | let DEFAULT_BACKDROP_TAG = 'div' as const
type BackdropRenderPropArg (line 491) | type BackdropRenderPropArg = {
type DialogBackdropProps (line 495) | type DialogBackdropProps<TTag extends ElementType = typeof DEFAULT_BACKD...
function BackdropFn (line 502) | function BackdropFn<TTag extends ElementType = typeof DEFAULT_BACKDROP_T...
constant DEFAULT_TITLE_TAG (line 533) | let DEFAULT_TITLE_TAG = 'h2' as const
type TitleRenderPropArg (line 534) | type TitleRenderPropArg = {
type DialogTitleProps (line 538) | type DialogTitleProps<TTag extends ElementType = typeof DEFAULT_TITLE_TA...
function TitleFn (line 543) | function TitleFn<TTag extends ElementType = typeof DEFAULT_TITLE_TAG>(
type _internal_ComponentDialog (line 575) | interface _internal_ComponentDialog extends HasDisplayName {
type _internal_ComponentDialogPanel (line 581) | interface _internal_ComponentDialogPanel extends HasDisplayName {
type _internal_ComponentDialogBackdrop (line 587) | interface _internal_ComponentDialogBackdrop extends HasDisplayName {
type _internal_ComponentDialogTitle (line 593) | interface _internal_ComponentDialogTitle extends HasDisplayName {
type _internal_ComponentDialogDescription (line 599) | interface _internal_ComponentDialogDescription extends _internal_Compone...
FILE: packages/@headlessui-react/src/components/disclosure/disclosure.test.tsx
function nextFrame (line 19) | function nextFrame() {
function Example (line 184) | function Example() {
function Example (line 580) | function Example() {
function Debug (line 620) | function Debug({ fn, name }: { fn: (text: string) => void; name: string ...
FILE: packages/@headlessui-react/src/components/disclosure/disclosure.tsx
type DisclosureStates (line 55) | enum DisclosureStates {
type StateDefinition (line 60) | interface StateDefinition {
type ActionTypes (line 70) | enum ActionTypes {
type Actions (line 81) | type Actions =
method [ActionTypes.SetButtonId] (line 106) | [ActionTypes.SetButtonId](state, action) {
method [ActionTypes.SetPanelId] (line 110) | [ActionTypes.SetPanelId](state, action) {
method [ActionTypes.SetButtonElement] (line 114) | [ActionTypes.SetButtonElement](state, action) {
method [ActionTypes.SetPanelElement] (line 118) | [ActionTypes.SetPanelElement](state, action) {
function useDisclosureContext (line 127) | function useDisclosureContext(component: string) {
function useDisclosureAPIContext (line 142) | function useDisclosureAPIContext(component: string) {
function useDisclosurePanelContext (line 155) | function useDisclosurePanelContext() {
function stateReducer (line 159) | function stateReducer(state: StateDefinition, action: Actions) {
constant DEFAULT_DISCLOSURE_TAG (line 165) | let DEFAULT_DISCLOSURE_TAG = Fragment
type DisclosureRenderPropArg (line 166) | type DisclosureRenderPropArg = {
type DisclosurePropsWeControl (line 170) | type DisclosurePropsWeControl = never
type DisclosureProps (line 172) | type DisclosureProps<TTag extends ElementType = typeof DEFAULT_DISCLOSUR...
function DisclosureFn (line 181) | function DisclosureFn<TTag extends ElementType = typeof DEFAULT_DISCLOSU...
constant DEFAULT_BUTTON_TAG (line 266) | let DEFAULT_BUTTON_TAG = 'button' as const
type ButtonRenderPropArg (line 267) | type ButtonRenderPropArg = {
type ButtonPropsWeControl (line 275) | type ButtonPropsWeControl = 'aria-controls' | 'aria-expanded'
type DisclosureButtonProps (line 277) | type DisclosureButtonProps<TTag extends ElementType = typeof DEFAULT_BUT...
function ButtonFn (line 287) | function ButtonFn<TTag extends ElementType = typeof DEFAULT_BUTTON_TAG>(
constant DEFAULT_PANEL_TAG (line 428) | let DEFAULT_PANEL_TAG = 'div' as const
type PanelRenderPropArg (line 429) | type PanelRenderPropArg = {
type DisclosurePanelPropsWeControl (line 433) | type DisclosurePanelPropsWeControl = never
type DisclosurePanelProps (line 437) | type DisclosurePanelProps<TTag extends ElementType = typeof DEFAULT_PANE...
function PanelFn (line 444) | function PanelFn<TTag extends ElementType = typeof DEFAULT_PANEL_TAG>(
type _internal_ComponentDisclosure (line 519) | interface _internal_ComponentDisclosure extends HasDisplayName {
type _internal_ComponentDisclosureButton (line 525) | interface _internal_ComponentDisclosureButton extends HasDisplayName {
type _internal_ComponentDisclosurePanel (line 531) | interface _internal_ComponentDisclosurePanel extends HasDisplayName {
FILE: packages/@headlessui-react/src/components/field/field.tsx
constant DEFAULT_FIELD_TAG (line 14) | let DEFAULT_FIELD_TAG = 'div' as const
type FieldRenderPropArg (line 16) | type FieldRenderPropArg = {}
type FieldPropsWeControl (line 17) | type FieldPropsWeControl = never
type FieldProps (line 19) | type FieldProps<TTag extends ElementType = typeof DEFAULT_FIELD_TAG> = P...
function FieldFn (line 28) | function FieldFn<TTag extends ElementType = typeof DEFAULT_FIELD_TAG>(
type _internal_ComponentField (line 78) | interface _internal_ComponentField extends HasDisplayName {
FILE: packages/@headlessui-react/src/components/fieldset/fieldset.tsx
constant DEFAULT_FIELDSET_TAG (line 12) | let DEFAULT_FIELDSET_TAG = 'fieldset' as const
type FieldsetRenderPropArg (line 14) | type FieldsetRenderPropArg = {}
type FieldsetPropsWeControl (line 15) | type FieldsetPropsWeControl = 'aria-labelledby' | 'aria-disabled' | 'role'
type FieldsetProps (line 17) | type FieldsetProps<TTag extends ElementType = typeof DEFAULT_FIELDSET_TA...
function FieldsetFn (line 26) | function FieldsetFn<TTag extends ElementType = typeof DEFAULT_FIELDSET_T...
type _internal_ComponentFieldset (line 71) | interface _internal_ComponentFieldset extends HasDisplayName {
FILE: packages/@headlessui-react/src/components/focus-trap/focus-trap.test.tsx
function nextFrame (line 15) | function nextFrame() {
function Example (line 52) | function Example() {
function Example (line 72) | function Example() {
function Example (line 94) | function Example() {
function Example (line 114) | function Example() {
function Example (line 159) | function Example() {
function Example (line 221) | function Example() {
function Example (line 474) | function Example() {
function Example (line 538) | function Example() {
FILE: packages/@headlessui-react/src/components/focus-trap/focus-trap.tsx
type Containers (line 31) | type Containers =
function resolveContainers (line 38) | function resolveContainers(containers?: Containers): Set<Element> {
constant DEFAULT_FOCUS_TRAP_TAG (line 51) | let DEFAULT_FOCUS_TRAP_TAG = 'div' as const
type FocusTrapFeatures (line 53) | enum FocusTrapFeatures {
type FocusTrapRenderPropArg (line 73) | type FocusTrapRenderPropArg = {}
type FocusTrapPropsWeControl (line 74) | type FocusTrapPropsWeControl = never
type FocusTrapProps (line 76) | type FocusTrapProps<TTag extends ElementType = typeof DEFAULT_FOCUS_TRAP...
function FocusTrapFn (line 91) | function FocusTrapFn<TTag extends ElementType = typeof DEFAULT_FOCUS_TRA...
type _internal_ComponentFocusTrap (line 236) | interface _internal_ComponentFocusTrap extends HasDisplayName {
function useRestoreElement (line 251) | function useRestoreElement(enabled: boolean = true) {
function useRestoreFocus (line 280) | function useRestoreFocus(
function useInitialFocus (line 305) | function useInitialFocus(
function useFocusLock (line 412) | function useFocusLock(
function contains (line 462) | function contains(containers: Set<Element>, element: Element) {
FILE: packages/@headlessui-react/src/components/input/input.test.tsx
method performUserInteraction (line 13) | async performUserInteraction(input) {
FILE: packages/@headlessui-react/src/components/input/input.tsx
constant DEFAULT_INPUT_TAG (line 21) | let DEFAULT_INPUT_TAG = 'input' as const
type InputRenderPropArg (line 23) | type InputRenderPropArg = {
type InputPropsWeControl (line 30) | type InputPropsWeControl = 'aria-labelledby' | 'aria-describedby'
type InputProps (line 32) | type InputProps<TTag extends ElementType = typeof DEFAULT_INPUT_TAG> = P...
function InputFn (line 43) | function InputFn<TTag extends ElementType = typeof DEFAULT_INPUT_TAG>(
type _internal_ComponentInput (line 91) | interface _internal_ComponentInput extends HasDisplayName {
FILE: packages/@headlessui-react/src/components/keyboard.ts
type Keys (line 3) | enum Keys {
FILE: packages/@headlessui-react/src/components/label/label.test.tsx
function Component (line 8) | function Component(props: { children: ReactNode }) {
function Example (line 18) | function Example() {
function Component (line 27) | function Component(props: { children: ReactNode }) {
function Example (line 37) | function Example() {
function Component (line 51) | function Component(props: { children: ReactNode }) {
function Example (line 61) | function Example() {
FILE: packages/@headlessui-react/src/components/label/label.tsx
type SharedData (line 26) | interface SharedData {
function useLabelContext (line 37) | function useLabelContext() {
function useLabelledBy (line 47) | function useLabelledBy(alwaysAvailableIds?: (string | undefined | null)[...
type LabelProviderProps (line 55) | interface LabelProviderProps extends SharedData {
function useLabels (line 60) | function useLabels({ inherit = false } = {}): [
constant DEFAULT_LABEL_TAG (line 108) | let DEFAULT_LABEL_TAG = 'label' as const
type LabelProps (line 110) | type LabelProps<TTag extends ElementType = typeof DEFAULT_LABEL_TAG> = P...
function LabelFn (line 115) | function LabelFn<TTag extends ElementType = typeof DEFAULT_LABEL_TAG>(
type _internal_ComponentLabel (line 240) | interface _internal_ComponentLabel extends HasDisplayName {
FILE: packages/@headlessui-react/src/components/legend/legend.tsx
constant DEFAULT_LEGEND_TAG (line 8) | let DEFAULT_LEGEND_TAG = Label
type LegendRenderPropArg (line 10) | type LegendRenderPropArg = {}
type LegendPropsWeControl (line 11) | type LegendPropsWeControl = never
type LegendProps (line 13) | type LegendProps<TTag extends ElementType = typeof DEFAULT_LEGEND_TAG> =...
function LegendFn (line 20) | function LegendFn<TTag extends ElementType = typeof DEFAULT_LEGEND_TAG>(
type _internal_ComponentLegend (line 30) | interface _internal_ComponentLegend extends HasDisplayName {
FILE: packages/@headlessui-react/src/components/listbox/listbox-machine-glue.tsx
function useListboxMachineContext (line 6) | function useListboxMachineContext<T>(component: string) {
function useListboxMachine (line 16) | function useListboxMachine({
FILE: packages/@headlessui-react/src/components/listbox/listbox-machine.ts
type MutableRefObject (line 12) | interface MutableRefObject<T> {
type ListboxStates (line 16) | enum ListboxStates {
type ValueMode (line 21) | enum ValueMode {
type ActivationTrigger (line 26) | enum ActivationTrigger {
type ListboxOptionDataRef (line 31) | type ListboxOptionDataRef<T> = MutableRefObject<{
type State (line 38) | interface State<T> {
type ActionTypes (line 80) | enum ActionTypes {
function adjustOrderedState (line 100) | function adjustOrderedState<T>(
type Actions (line 129) | type Actions<T> =
method [ActionTypes.CloseListbox] (line 157) | [ActionTypes.CloseListbox](state) {
method [ActionTypes.OpenListbox] (line 173) | [ActionTypes.OpenListbox](state, action) {
method [ActionTypes.GoToOption] (line 196) | [ActionTypes.GoToOption](state, action) {
method [ActionTypes.ClearSearch] (line 340) | [ActionTypes.ClearSearch](state) {
method [ActionTypes.SelectOption] (line 346) | [ActionTypes.SelectOption](state) {
method [ActionTypes.MarkButtonAsMoved] (line 435) | [ActionTypes.MarkButtonAsMoved](state) {
class ListboxMachine (line 445) | class ListboxMachine<T> extends Machine<State<T>, Actions<T>> {
method new (line 446) | static new({ id, __demoMode = false }: { id: string; __demoMode?: bool...
method constructor (line 466) | constructor(initialState: State<T>) {
method activeDescendantId (line 620) | activeDescendantId(state: State<T>) {
method isActive (line 626) | isActive(state: State<T>, id: string) {
method hasFrozenValue (line 633) | hasFrozenValue(state: State<T>) {
method shouldScrollIntoView (line 637) | shouldScrollIntoView(state: State<T>, id: string) {
method didButtonMove (line 644) | didButtonMove(state: State<T>) {
method reduce (line 649) | reduce(state: Readonly<State<T>>, action: Actions<T>): State<T> {
FILE: packages/@headlessui-react/src/components/listbox/listbox.test.tsx
function Example (line 296) | function Example() {
function Example (line 339) | function Example() {
function Example (line 387) | function Example() {
function Example (line 429) | function Example() {
function Example (line 852) | function Example({ hide = false }) {
function Debug (line 1414) | function Debug({ fn, name }: { fn: (text: string) => void; name: string ...
function Example (line 1521) | function Example() {
function Example (line 1814) | function Example() {
function Example (line 4048) | function Example() {
function Example (line 4099) | function Example() {
function Example (line 4212) | function Example() {
function Example (line 4247) | function Example() {
function Example (line 4275) | function Example() {
function Example (line 4307) | function Example() {
function Example (line 4355) | function Example() {
function Example (line 4399) | function Example() {
function Example (line 4467) | function Example() {
function Example (line 4529) | function Example() {
function Example (line 4590) | function Example() {
FILE: packages/@headlessui-react/src/components/listbox/listbox.tsx
type ListboxOptionDataRef (line 89) | type ListboxOptionDataRef<T> = MutableRefObject<{
function useData (line 115) | function useData(component: string) {
type _Data (line 124) | type _Data = ReturnType<typeof useData>
constant DEFAULT_LISTBOX_TAG (line 128) | let DEFAULT_LISTBOX_TAG = Fragment
type ListboxRenderPropArg (line 129) | type ListboxRenderPropArg<T> = {
type ListboxProps (line 136) | type ListboxProps<
function ListboxFn (line 160) | function ListboxFn<
constant DEFAULT_BUTTON_TAG (line 311) | let DEFAULT_BUTTON_TAG = 'button' as const
type ButtonRenderPropArg (line 312) | type ButtonRenderPropArg = {
type ButtonPropsWeControl (line 322) | type ButtonPropsWeControl =
type ListboxButtonProps (line 329) | type ListboxButtonProps<TTag extends ElementType = typeof DEFAULT_BUTTON...
function ButtonFn (line 339) | function ButtonFn<TTag extends ElementType = typeof DEFAULT_BUTTON_TAG>(
constant DEFAULT_OPTIONS_TAG (line 490) | let DEFAULT_OPTIONS_TAG = 'div' as const
type OptionsRenderPropArg (line 491) | type OptionsRenderPropArg = {
type OptionsPropsWeControl (line 494) | type OptionsPropsWeControl =
type ListboxOptionsProps (line 504) | type ListboxOptionsProps<TTag extends ElementType = typeof DEFAULT_OPTIO...
function OptionsFn (line 516) | function OptionsFn<TTag extends ElementType = typeof DEFAULT_OPTIONS_TAG>(
constant DEFAULT_OPTION_TAG (line 786) | let DEFAULT_OPTION_TAG = 'div' as const
type OptionRenderPropArg (line 787) | type OptionRenderPropArg = {
type OptionPropsWeControl (line 796) | type OptionPropsWeControl = 'aria-disabled' | 'aria-selected' | 'role' |...
type ListboxOptionProps (line 798) | type ListboxOptionProps<
function OptionFn (line 811) | function OptionFn<
constant DEFAULT_SELECTED_OPTION_TAG (line 955) | let DEFAULT_SELECTED_OPTION_TAG = Fragment
type SelectedOptionRenderPropArg (line 956) | type SelectedOptionRenderPropArg = {}
type SelectedOptionPropsWeControl (line 957) | type SelectedOptionPropsWeControl = never
type ListboxSelectedOptionProps (line 959) | type ListboxSelectedOptionProps<
function SelectedFn (line 971) | function SelectedFn<TTag extends ElementType = typeof DEFAULT_SELECTED_O...
type _internal_ComponentListbox (line 1007) | interface _internal_ComponentListbox extends HasDisplayName {
type _internal_ComponentListboxButton (line 1017) | interface _internal_ComponentListboxButton extends HasDisplayName {
type _internal_ComponentListboxLabel (line 1023) | interface _internal_ComponentListboxLabel extends _internal_ComponentLab...
type _internal_ComponentListboxOptions (line 1025) | interface _internal_ComponentListboxOptions extends HasDisplayName {
type _internal_ComponentListboxOption (line 1031) | interface _internal_ComponentListboxOption extends HasDisplayName {
type _internal_ComponentListboxSelectedOption (line 1040) | interface _internal_ComponentListboxSelectedOption extends HasDisplayName {
FILE: packages/@headlessui-react/src/components/menu/menu-machine-glue.tsx
function useMenuMachineContext (line 6) | function useMenuMachineContext(component: string) {
function useMenuMachine (line 16) | function useMenuMachine({ id, __demoMode = false }: { id: string; __demo...
FILE: packages/@headlessui-react/src/components/menu/menu-machine.ts
type MenuState (line 12) | enum MenuState {
type ActivationTrigger (line 17) | enum ActivationTrigger {
type MenuItemDataRef (line 22) | type MenuItemDataRef = {
type State (line 30) | interface State {
type ActionTypes (line 51) | enum ActionTypes {
function adjustOrderedState (line 69) | function adjustOrderedState(
type Actions (line 95) | type Actions =
method [ActionTypes.CloseMenu] (line 120) | [ActionTypes.CloseMenu](state) {
method [ActionTypes.OpenMenu] (line 134) | [ActionTypes.OpenMenu](state, action) {
method [ActionTypes.ClearSearch] (line 283) | [ActionTypes.ClearSearch](state) {
method [ActionTypes.MarkButtonAsMoved] (line 351) | [ActionTypes.MarkButtonAsMoved](state) {
class MenuMachine (line 361) | class MenuMachine extends Machine<State, Actions> {
method new (line 362) | static new({ id, __demoMode = false }: { id: string; __demoMode?: bool...
method constructor (line 379) | constructor(initialState: State) {
method reduce (line 424) | reduce(state: Readonly<State>, action: Actions): State {
method activeDescendantId (line 457) | activeDescendantId(state: State) {
method isActive (line 463) | isActive(state: State, id: string) {
method shouldScrollIntoView (line 470) | shouldScrollIntoView(state: State, id: string) {
method didButtonMove (line 477) | didButtonMove(state: State) {
FILE: packages/@headlessui-react/src/components/menu/menu.test.tsx
function Example (line 504) | function Example({ hide = false }) {
function Debug (line 731) | function Debug({ fn, name }: { fn: (text: string) => void; name: string ...
FILE: packages/@headlessui-react/src/components/menu/menu.tsx
constant DEFAULT_MENU_TAG (line 78) | let DEFAULT_MENU_TAG = Fragment
type MenuRenderPropArg (line 79) | type MenuRenderPropArg = {
type MenuPropsWeControl (line 83) | type MenuPropsWeControl = never
type MenuProps (line 85) | type MenuProps<TTag extends ElementType = typeof DEFAULT_MENU_TAG> = Props<
function MenuFn (line 94) | function MenuFn<TTag extends ElementType = typeof DEFAULT_MENU_TAG>(
constant DEFAULT_BUTTON_TAG (line 159) | let DEFAULT_BUTTON_TAG = 'button' as const
type ButtonRenderPropArg (line 160) | type ButtonRenderPropArg = {
type ButtonPropsWeControl (line 168) | type ButtonPropsWeControl = 'aria-controls' | 'aria-expanded' | 'aria-ha...
type MenuButtonProps (line 170) | type MenuButtonProps<TTag extends ElementType = typeof DEFAULT_BUTTON_TA...
function ButtonFn (line 180) | function ButtonFn<TTag extends ElementType = typeof DEFAULT_BUTTON_TAG>(
constant DEFAULT_ITEMS_TAG (line 325) | let DEFAULT_ITEMS_TAG = 'div' as const
type ItemsRenderPropArg (line 326) | type ItemsRenderPropArg = {
type ItemsPropsWeControl (line 329) | type ItemsPropsWeControl = 'aria-activedescendant' | 'aria-labelledby' |...
type MenuItemsProps (line 333) | type MenuItemsProps<TTag extends ElementType = typeof DEFAULT_ITEMS_TAG>...
function ItemsFn (line 349) | function ItemsFn<TTag extends ElementType = typeof DEFAULT_ITEMS_TAG>(
constant DEFAULT_ITEM_TAG (line 585) | let DEFAULT_ITEM_TAG = Fragment
type ItemRenderPropArg (line 586) | type ItemRenderPropArg = {
type ItemPropsWeControl (line 593) | type ItemPropsWeControl =
type MenuItemProps (line 600) | type MenuItemProps<TTag extends ElementType = typeof DEFAULT_ITEM_TAG> =...
function ItemFn (line 609) | function ItemFn<TTag extends ElementType = typeof DEFAULT_ITEM_TAG>(
constant DEFAULT_SECTION_TAG (line 741) | let DEFAULT_SECTION_TAG = 'div' as const
type SectionRenderPropArg (line 742) | type SectionRenderPropArg = {}
type SectionPropsWeControl (line 743) | type SectionPropsWeControl = 'role' | 'aria-labelledby'
type MenuSectionProps (line 745) | type MenuSectionProps<TTag extends ElementType = typeof DEFAULT_SECTION_...
function SectionFn (line 751) | function SectionFn<TTag extends ElementType = typeof DEFAULT_SECTION_TAG>(
constant DEFAULT_HEADING_TAG (line 777) | let DEFAULT_HEADING_TAG = 'header' as const
type HeadingRenderPropArg (line 778) | type HeadingRenderPropArg = {}
type HeadingPropsWeControl (line 779) | type HeadingPropsWeControl = 'role'
type MenuHeadingProps (line 781) | type MenuHeadingProps<TTag extends ElementType = typeof DEFAULT_HEADING_...
function HeadingFn (line 787) | function HeadingFn<TTag extends ElementType = typeof DEFAULT_HEADING_TAG>(
constant DEFAULT_SEPARATOR_TAG (line 812) | let DEFAULT_SEPARATOR_TAG = 'div' as const
type SeparatorRenderPropArg (line 813) | type SeparatorRenderPropArg = {}
type SeparatorPropsWeControl (line 814) | type SeparatorPropsWeControl = 'role'
type MenuSeparatorProps (line 816) | type MenuSeparatorProps<TTag extends ElementType = typeof DEFAULT_SEPARA...
function SeparatorFn (line 822) | function SeparatorFn<TTag extends ElementType = typeof DEFAULT_SEPARATOR...
type _internal_ComponentMenu (line 842) | interface _internal_ComponentMenu extends HasDisplayName {
type _internal_ComponentMenuButton (line 848) | interface _internal_ComponentMenuButton extends HasDisplayName {
type _internal_ComponentMenuItems (line 854) | interface _internal_ComponentMenuItems extends HasDisplayName {
type _internal_ComponentMenuItem (line 860) | interface _internal_ComponentMenuItem extends HasDisplayName {
type _internal_ComponentMenuSection (line 866) | interface _internal_ComponentMenuSection extends HasDisplayName {
type _internal_ComponentMenuHeading (line 872) | interface _internal_ComponentMenuHeading extends HasDisplayName {
type _internal_ComponentMenuSeparator (line 878) | interface _internal_ComponentMenuSeparator extends HasDisplayName {
FILE: packages/@headlessui-react/src/components/mouse.ts
type MouseButton (line 1) | enum MouseButton {
FILE: packages/@headlessui-react/src/components/popover/popover-machine-glue.tsx
function usePopoverMachineContext (line 6) | function usePopoverMachineContext(component: string) {
function usePopoverMachine (line 16) | function usePopoverMachine({
FILE: packages/@headlessui-react/src/components/popover/popover-machine.ts
type MouseEvent (line 9) | type MouseEvent<T> = Parameters<MouseEventHandler<T>>[0]
type PopoverStates (line 11) | enum PopoverStates {
type State (line 16) | interface State {
type ActionTypes (line 35) | enum ActionTypes {
type Actions (line 45) | type Actions =
method [ActionTypes.ClosePopover] (line 60) | [ActionTypes.ClosePopover](state) {
method [ActionTypes.SetButton] (line 64) | [ActionTypes.SetButton](state, action) {
method [ActionTypes.SetButtonId] (line 68) | [ActionTypes.SetButtonId](state, action) {
method [ActionTypes.SetPanel] (line 72) | [ActionTypes.SetPanel](state, action) {
method [ActionTypes.SetPanelId] (line 76) | [ActionTypes.SetPanelId](state, action) {
class PopoverMachine (line 82) | class PopoverMachine extends Machine<State, Actions> {
method new (line 83) | static new({ id, __demoMode = false }: { id: string; __demoMode?: bool...
method constructor (line 99) | constructor(initialState: State) {
method reduce (line 111) | reduce(state: Readonly<State>, action: Actions): State {
FILE: packages/@headlessui-react/src/components/popover/popover.test.tsx
function nextFrame (line 23) | function nextFrame() {
function Example (line 212) | function Example() {
function Example (line 256) | function Example() {
function Example (line 744) | function Example() {
function Debug (line 945) | function Debug({ fn, name }: { fn: (text: string) => void; name: string ...
function Example (line 1885) | function Example() {
FILE: packages/@headlessui-react/src/components/popover/popover.tsx
type MouseEvent (line 88) | type MouseEvent<T> = Parameters<MouseEventHandler<T>>[0]
function usePopoverGroupContext (line 98) | function usePopoverGroupContext() {
function usePopoverPanelContext (line 105) | function usePopoverPanelContext() {
type PopoverRegisterBag (line 109) | interface PopoverRegisterBag {
constant DEFAULT_POPOVER_TAG (line 117) | let DEFAULT_POPOVER_TAG = 'div' as const
type PopoverRenderPropArg (line 118) | type PopoverRenderPropArg = {
type PopoverPropsWeControl (line 124) | type PopoverPropsWeControl = never
type PopoverProps (line 126) | type PopoverProps<TTag extends ElementType = typeof DEFAULT_POPOVER_TAG>...
function PopoverFn (line 135) | function PopoverFn<TTag extends ElementType = typeof DEFAULT_POPOVER_TAG>(
constant DEFAULT_BUTTON_TAG (line 283) | let DEFAULT_BUTTON_TAG = 'button' as const
type ButtonRenderPropArg (line 284) | type ButtonRenderPropArg = {
type ButtonPropsWeControl (line 292) | type ButtonPropsWeControl = 'aria-controls' | 'aria-expanded'
type PopoverButtonProps (line 294) | type PopoverButtonProps<TTag extends ElementType = typeof DEFAULT_BUTTON...
function ButtonFn (line 304) | function ButtonFn<TTag extends ElementType = typeof DEFAULT_BUTTON_TAG>(
constant DEFAULT_BACKDROP_TAG (line 583) | let DEFAULT_BACKDROP_TAG = 'div' as const
type BackdropRenderPropArg (line 584) | type BackdropRenderPropArg = {
type BackdropPropsWeControl (line 587) | type BackdropPropsWeControl = 'aria-hidden'
type PopoverBackdropProps (line 591) | type PopoverBackdropProps<TTag extends ElementType = typeof DEFAULT_BACK...
type PopoverOverlayProps (line 598) | type PopoverOverlayProps<TTag extends ElementType = typeof DEFAULT_BACKD...
function BackdropFn (line 601) | function BackdropFn<TTag extends ElementType = typeof DEFAULT_BACKDROP_T...
constant DEFAULT_PANEL_TAG (line 666) | let DEFAULT_PANEL_TAG = 'div' as const
type PanelRenderPropArg (line 667) | type PanelRenderPropArg = {
type PanelPropsWeControl (line 674) | type PanelPropsWeControl = 'tabIndex'
type PopoverPanelProps (line 676) | type PopoverPanelProps<TTag extends ElementType = typeof DEFAULT_PANEL_T...
function PanelFn (line 693) | function PanelFn<TTag extends ElementType = typeof DEFAULT_PANEL_TAG>(
constant DEFAULT_GROUP_TAG (line 980) | let DEFAULT_GROUP_TAG = 'div' as const
type GroupRenderPropArg (line 981) | type GroupRenderPropArg = {}
type GroupPropsWeControl (line 982) | type GroupPropsWeControl = never
type PopoverGroupProps (line 984) | type PopoverGroupProps<TTag extends ElementType = typeof DEFAULT_GROUP_T...
function GroupFn (line 990) | function GroupFn<TTag extends ElementType = typeof DEFAULT_GROUP_TAG>(
type _internal_ComponentPopover (line 1071) | interface _internal_ComponentPopover extends HasDisplayName {
type _internal_ComponentPopoverButton (line 1077) | interface _internal_ComponentPopoverButton extends HasDisplayName {
type _internal_ComponentPopoverBackdrop (line 1083) | interface _internal_ComponentPopoverBackdrop extends HasDisplayName {
type _internal_ComponentPopoverPanel (line 1089) | interface _internal_ComponentPopoverPanel extends HasDisplayName {
type _internal_ComponentPopoverGroup (line 1095) | interface _internal_ComponentPopoverGroup extends HasDisplayName {
FILE: packages/@headlessui-react/src/components/portal/portal.test.tsx
function getPortalRoot (line 6) | function getPortalRoot() {
function Example (line 77) | function Example() {
function Example (line 145) | function Example() {
function Example (line 226) | function Example() {
function Example (line 276) | function Example() {
FILE: packages/@headlessui-react/src/components/portal/portal.tsx
function usePortalTarget (line 28) | function usePortalTarget(ownerDocument: Document | null): HTMLElement | ...
constant DEFAULT_PORTAL_TAG (line 68) | let DEFAULT_PORTAL_TAG = Fragment
type PortalRenderPropArg (line 69) | type PortalRenderPropArg = {}
type PortalPropsWeControl (line 70) | type PortalPropsWeControl = never
type PortalProps (line 72) | type PortalProps<TTag extends ElementType = typeof DEFAULT_PORTAL_TAG> =...
function PortalFn (line 137) | function PortalFn<TTag extends ElementType = typeof DEFAULT_PORTAL_TAG>(
constant DEFAULT_GROUP_TAG (line 162) | let DEFAULT_GROUP_TAG = Fragment
type GroupRenderPropArg (line 163) | type GroupRenderPropArg = {}
type GroupPropsWeControl (line 164) | type GroupPropsWeControl = never
type PortalGroupProps (line 168) | type PortalGroupProps<TTag extends ElementType = typeof DEFAULT_GROUP_TA...
function GroupFn (line 177) | function GroupFn<TTag extends ElementType = typeof DEFAULT_GROUP_TAG>(
function useNestedPortals (line 208) | function useNestedPortals() {
type _internal_ComponentPortal (line 241) | interface _internal_ComponentPortal extends HasDisplayName {
type _internal_ComponentPortalGroup (line 247) | interface _internal_ComponentPortalGroup extends HasDisplayName {
FILE: packages/@headlessui-react/src/components/radio-group/radio-group.test.tsx
function Example (line 117) | function Example() {
function Example (line 154) | function Example() {
function Example (line 226) | function Example() {
function Example (line 301) | function Example({ hide = false }) {
function Example (line 335) | function Example() {
function Example (line 1254) | function Example() {
function Example (line 1305) | function Example() {
function Example (line 1344) | function Example() {
function Example (line 1409) | function Example() {
function Example (line 1451) | function Example() {
function Example (line 1492) | function Example() {
function Example (line 1543) | function Example() {
function Example (line 1600) | function Example() {
FILE: packages/@headlessui-react/src/components/radio-group/radio-group.tsx
type Option (line 52) | interface Option<T = unknown> {
type StateDefinition (line 58) | interface StateDefinition<T = unknown> {
type ActionTypes (line 62) | enum ActionTypes {
type Actions (line 67) | type Actions =
method [ActionTypes.RegisterOption] (line 77) | [ActionTypes.RegisterOption](state, action) {
method [ActionTypes.UnregisterOption] (line 88) | [ActionTypes.UnregisterOption](state, action) {
function useData (line 110) | function useData(component: string) {
type _Data (line 119) | type _Data = ReturnType<typeof useData>
function useActions (line 127) | function useActions(component: string) {
type _Actions (line 136) | type _Actions = ReturnType<typeof useActions>
function stateReducer (line 138) | function stateReducer<T>(state: StateDefinition<T>, action: Actions) {
constant DEFAULT_RADIO_GROUP_TAG (line 144) | let DEFAULT_RADIO_GROUP_TAG = 'div' as const
type RadioGroupRenderPropArg (line 145) | type RadioGroupRenderPropArg<TType> = {
type RadioGroupPropsWeControl (line 148) | type RadioGroupPropsWeControl = 'role' | 'aria-labelledby' | 'aria-descr...
type RadioGroupProps (line 150) | type RadioGroupProps<
function RadioGroupFn (line 168) | function RadioGroupFn<TTag extends ElementType = typeof DEFAULT_RADIO_GR...
constant DEFAULT_OPTION_TAG (line 340) | let DEFAULT_OPTION_TAG = 'div' as const
type OptionRenderPropArg (line 341) | type OptionRenderPropArg = {
type OptionPropsWeControl (line 350) | type OptionPropsWeControl =
type RadioOptionProps (line 357) | type RadioOptionProps<TTag extends ElementType, TType> = Props<
function OptionFn (line 368) | function OptionFn<
constant DEFAULT_RADIO_TAG (line 461) | let DEFAULT_RADIO_TAG = 'span' as const
type RadioRenderPropArg (line 462) | type RadioRenderPropArg = {
type RadioPropsWeControl (line 469) | type RadioPropsWeControl =
type RadioProps (line 476) | type RadioProps<TTag extends ElementType = typeof DEFAULT_RADIO_TAG, TTy...
function RadioFn (line 487) | function RadioFn<
type _internal_ComponentRadioGroup (line 568) | interface _internal_ComponentRadioGroup extends HasDisplayName {
type _internal_ComponentRadioOption (line 574) | interface _internal_ComponentRadioOption extends HasDisplayName {
type _internal_ComponentRadio (line 580) | interface _internal_ComponentRadio extends HasDisplayName {
type _internal_ComponentRadioLabel (line 586) | interface _internal_ComponentRadioLabel extends _internal_ComponentLabel {}
type _internal_ComponentRadioDescription (line 587) | interface _internal_ComponentRadioDescription extends _internal_Componen...
FILE: packages/@headlessui-react/src/components/select/select.test.tsx
method performUserInteraction (line 21) | async performUserInteraction(control) {
FILE: packages/@headlessui-react/src/components/select/select.tsx
constant DEFAULT_SELECT_TAG (line 22) | let DEFAULT_SELECT_TAG = 'select' as const
type SelectRenderPropArg (line 24) | type SelectRenderPropArg = {
type SelectPropsWeControl (line 32) | type SelectPropsWeControl = 'aria-labelledby' | 'aria-describedby'
type SelectProps (line 34) | type SelectProps<TTag extends ElementType = typeof DEFAULT_SELECT_TAG> =...
function SelectFn (line 45) | function SelectFn<TTag extends ElementType = typeof DEFAULT_SELECT_TAG>(
type _internal_ComponentSelect (line 102) | interface _internal_ComponentSelect extends HasDisplayName {
FILE: packages/@headlessui-react/src/components/switch/switch.test.tsx
function Example (line 418) | function Example() {
function Example (line 473) | function Example() {
function Example (line 506) | function Example() {
function Example (line 566) | function Example() {
function Example (line 599) | function Example() {
function Example (line 641) | function Example() {
function Example (line 672) | function Example() {
function Example (line 700) | function Example() {
function Example (line 737) | function Example() {
function Example (line 776) | function Example() {
function Example (line 815) | function Example() {
FILE: packages/@headlessui-react/src/components/switch/switch.tsx
type StateDefinition (line 50) | interface StateDefinition {
constant DEFAULT_GROUP_TAG (line 60) | let DEFAULT_GROUP_TAG = Fragment
type SwitchGroupProps (line 62) | type SwitchGroupProps<TTag extends ElementType = typeof DEFAULT_GROUP_TA...
function GroupFn (line 64) | function GroupFn<TTag extends ElementType = typeof DEFAULT_GROUP_TAG>(
constant DEFAULT_SWITCH_TAG (line 114) | let DEFAULT_SWITCH_TAG = 'button' as const
type SwitchRenderPropArg (line 115) | type SwitchRenderPropArg = {
type SwitchPropsWeControl (line 124) | type SwitchPropsWeControl = 'aria-checked' | 'aria-describedby' | 'aria-...
type SwitchProps (line 126) | type SwitchProps<TTag extends ElementType = typeof DEFAULT_SWITCH_TAG> =...
function SwitchFn (line 143) | function SwitchFn<TTag extends ElementType = typeof DEFAULT_SWITCH_TAG>(
type _internal_ComponentSwitch (line 269) | interface _internal_ComponentSwitch extends HasDisplayName {
type _internal_ComponentSwitchGroup (line 275) | interface _internal_ComponentSwitchGroup extends HasDisplayName {
type _internal_ComponentSwitchLabel (line 281) | interface _internal_ComponentSwitchLabel extends _internal_ComponentLabe...
type _internal_ComponentSwitchDescription (line 282) | interface _internal_ComponentSwitchDescription extends _internal_Compone...
FILE: packages/@headlessui-react/src/components/tabs/tabs.ssr.test.tsx
function Example (line 14) | function Example(props: { defaultIndex?: number; selectedIndex?: number ...
FILE: packages/@headlessui-react/src/components/tabs/tabs.test.tsx
function Example (line 85) | function Example() {
function Example (line 127) | function Example() {
function Example (line 171) | function Example() {
function Example (line 218) | function Example() {
function Example (line 302) | function Example() {
function Example (line 848) | function Example() {
function Example (line 898) | function Example({ defaultIndex = undefined }: { defaultIndex?: number }...
function Example (line 943) | function Example({ defaultIndex = undefined }: { defaultIndex?: number }...
function Example (line 988) | function Example({ defaultIndex = undefined }: { defaultIndex?: number }...
function ControlledTabs (line 1041) | function ControlledTabs() {
function ControlledTabs (line 1099) | function ControlledTabs() {
function Example (line 1315) | function Example() {
function Example (line 1359) | function Example() {
FILE: packages/@headlessui-react/src/components/tabs/tabs.tsx
type Direction (line 45) | enum Direction {
type Ordering (line 50) | enum Ordering {
type StateDefinition (line 56) | interface StateDefinition {
type ActionTypes (line 64) | enum ActionTypes {
type Actions (line 74) | type Actions =
method [ActionTypes.SetSelectedIndex] (line 87) | [ActionTypes.SetSelectedIndex](state, action) {
method [ActionTypes.RegisterTab] (line 145) | [ActionTypes.RegisterTab](state, action) {
method [ActionTypes.UnregisterTab] (line 165) | [ActionTypes.UnregisterTab](state, action) {
method [ActionTypes.RegisterPanel] (line 168) | [ActionTypes.RegisterPanel](state, action) {
method [ActionTypes.UnregisterPanel] (line 175) | [ActionTypes.UnregisterPanel](state, action) {
function useData (line 189) | function useData(component: string) {
type _Data (line 198) | type _Data = ReturnType<typeof useData>
function useActions (line 207) | function useActions(component: string) {
type _Actions (line 216) | type _Actions = ReturnType<typeof useActions>
function stateReducer (line 218) | function stateReducer(state: StateDefinition, action: Actions) {
constant DEFAULT_TABS_TAG (line 224) | let DEFAULT_TABS_TAG = 'div' as const
type TabsRenderPropArg (line 225) | type TabsRenderPropArg = {
type TabsPropsWeControl (line 228) | type TabsPropsWeControl = never
type TabGroupProps (line 230) | type TabGroupProps<TTag extends ElementType = typeof DEFAULT_TABS_TAG> =...
function GroupFn (line 243) | function GroupFn<TTag extends ElementType = typeof DEFAULT_TABS_TAG>(
constant DEFAULT_LIST_TAG (line 356) | let DEFAULT_LIST_TAG = 'div' as const
type ListRenderPropArg (line 357) | type ListRenderPropArg = {
type ListPropsWeControl (line 360) | type ListPropsWeControl = 'aria-orientation' | 'role'
type TabListProps (line 362) | type TabListProps<TTag extends ElementType = typeof DEFAULT_LIST_TAG> = ...
function ListFn (line 371) | function ListFn<TTag extends ElementType = typeof DEFAULT_LIST_TAG>(
constant DEFAULT_TAB_TAG (line 400) | let DEFAULT_TAB_TAG = 'button' as const
type TabRenderPropArg (line 401) | type TabRenderPropArg = {
type TabPropsWeControl (line 409) | type TabPropsWeControl = 'aria-controls' | 'aria-selected' | 'role' | 't...
type TabProps (line 411) | type TabProps<TTag extends ElementType = typeof DEFAULT_TAB_TAG> = Props<
function TabFn (line 421) | function TabFn<TTag extends ElementType = typeof DEFAULT_TAB_TAG>(
constant DEFAULT_PANELS_TAG (line 572) | let DEFAULT_PANELS_TAG = 'div' as const
type PanelsRenderPropArg (line 573) | type PanelsRenderPropArg = {
type TabPanelsProps (line 577) | type TabPanelsProps<TTag extends ElementType = typeof DEFAULT_PANELS_TAG...
function PanelsFn (line 582) | function PanelsFn<TTag extends ElementType = typeof DEFAULT_PANELS_TAG>(
constant DEFAULT_PANEL_TAG (line 607) | let DEFAULT_PANEL_TAG = 'div' as const
type PanelRenderPropArg (line 608) | type PanelRenderPropArg = {
type PanelPropsWeControl (line 612) | type PanelPropsWeControl = 'role' | 'aria-labelledby'
type TabPanelProps (line 615) | type TabPanelProps<TTag extends ElementType = typeof DEFAULT_PANEL_TAG> ...
function PanelFn (line 622) | function PanelFn<TTag extends ElementType = typeof DEFAULT_PANEL_TAG>(
type _internal_ComponentTab (line 676) | interface _internal_ComponentTab extends HasDisplayName {
type _internal_ComponentTabGroup (line 682) | interface _internal_ComponentTabGroup extends HasDisplayName {
type _internal_ComponentTabList (line 688) | interface _internal_ComponentTabList extends HasDisplayName {
type _internal_ComponentTabPanels (line 694) | interface _internal_ComponentTabPanels extends HasDisplayName {
type _internal_ComponentTabPanel (line 700) | interface _internal_ComponentTabPanel extends HasDisplayName {
FILE: packages/@headlessui-react/src/components/textarea/textarea.test.tsx
method performUserInteraction (line 13) | async performUserInteraction(control) {
FILE: packages/@headlessui-react/src/components/textarea/textarea.tsx
constant DEFAULT_TEXTAREA_TAG (line 21) | let DEFAULT_TEXTAREA_TAG = 'textarea' as const
type TextareaRenderPropArg (line 23) | type TextareaRenderPropArg = {
type TextareaPropsWeControl (line 30) | type TextareaPropsWeControl = 'aria-labelledby' | 'aria-describedby'
type TextareaProps (line 32) | type TextareaProps<TTag extends ElementType = typeof DEFAULT_TEXTAREA_TA...
function TextareaFn (line 43) | function TextareaFn<TTag extends ElementType = typeof DEFAULT_TEXTAREA_T...
type _internal_ComponentTextarea (line 97) | interface _internal_ComponentTextarea extends HasDisplayName {
FILE: packages/@headlessui-react/src/components/tooltip/tooltip.tsx
type TooltipState (line 46) | enum TooltipState {
type When (line 60) | enum When {
type ActiveTooltipId (line 68) | type ActiveTooltipId = string | null
class TooltipStore (line 69) | class TooltipStore {
type StateDefinition (line 97) | interface StateDefinition {
type ActionTypes (line 102) | enum ActionTypes {
type Actions (line 107) | type Actions =
method [ActionTypes.ShowTooltip] (line 117) | [ActionTypes.ShowTooltip](state, action) {
method [ActionTypes.HideTooltip] (line 134) | [ActionTypes.HideTooltip](state, action) {
function useActions (line 159) | function useActions(component: string) {
type _Actions (line 168) | type _Actions = ReturnType<typeof useActions>
function useData (line 173) | function useData(component: string) {
type _Data (line 182) | type _Data = ReturnType<typeof useData>
function stateReducer (line 184) | function stateReducer(state: StateDefinition, action: Actions) {
constant DEFAULT_TOOLTIP_TAG (line 190) | let DEFAULT_TOOLTIP_TAG = Fragment
type TooltipRenderPropArg (line 192) | type TooltipRenderPropArg = {}
type TooltipPropsWeControl (line 193) | type TooltipPropsWeControl = never
type TooltipProps (line 195) | type TooltipProps<TTag extends ElementType = typeof DEFAULT_TOOLTIP_TAG>...
function TooltipFn (line 205) | function TooltipFn<TTag extends ElementType = typeof DEFAULT_TOOLTIP_TAG>(
constant DEFAULT_TRIGGER_TAG (line 317) | let DEFAULT_TRIGGER_TAG = Fragment
type TriggerRenderPropArg (line 319) | type TriggerRenderPropArg = { hover: boolean; focus: boolean; autofocus:...
type TriggerPropsWeControl (line 320) | type TriggerPropsWeControl = 'aria-describedby'
type TooltipTriggerProps (line 322) | type TooltipTriggerProps<TTag extends ElementType = typeof DEFAULT_TRIGG...
function TriggerFn (line 329) | function TriggerFn<TTag extends ElementType = typeof DEFAULT_TRIGGER_TAG>(
constant DEFAULT_PANEL_TAG (line 411) | let DEFAULT_PANEL_TAG = Description
type PanelRenderPropArg (line 413) | type PanelRenderPropArg = {}
type PanelPropsWeControl (line 414) | type PanelPropsWeControl = 'role'
type TooltipPanelProps (line 417) | type TooltipPanelProps<TTag extends ElementType = typeof DEFAULT_PANEL_T...
function PanelFn (line 424) | function PanelFn<TTag extends ElementType = typeof DEFAULT_PANEL_TAG>(
type _internal_ComponentTooltip (line 477) | interface _internal_ComponentTooltip extends HasDisplayName {
type _internal_ComponentTrigger (line 483) | interface _internal_ComponentTrigger extends HasDisplayName {
type _internal_ComponentPanel (line 489) | interface _internal_ComponentPanel extends HasDisplayName {
FILE: packages/@headlessui-react/src/components/transition/transition.test.tsx
function nextFrame (line 10) | function nextFrame() {
function Dummy (line 124) | function Dummy(props: any) {
function Dummy (line 263) | function Dummy(props: any) {
function Dummy (line 313) | function Dummy(props: any) {
function Example (line 337) | function Example() {
function Example (line 408) | function Example() {
function Example (line 442) | function Example() {
function Example (line 474) | function Example() {
function Example (line 508) | function Example() {
function Example (line 542) | function Example() {
function Example (line 576) | function Example() {
function Example (line 611) | function Example() {
function Example (line 647) | function Example() {
function Example (line 698) | function Example() {
function Example (line 758) | function Example() {
function Example (line 805) | function Example() {
function Example (line 859) | function Example() {
function Example (line 938) | function Example() {
function Example (line 1110) | function Example() {
FILE: packages/@headlessui-react/src/components/transition/transition.tsx
type ContainerElement (line 39) | type ContainerElement = MutableRefObject<HTMLElement | null>
type TransitionDirection (line 41) | type TransitionDirection = 'enter' | 'leave'
function shouldForwardRef (line 61) | function shouldForwardRef<TTag extends ElementType = typeof DEFAULT_TRAN...
type TransitionContextValues (line 81) | interface TransitionContextValues {
type TreeStates (line 89) | enum TreeStates {
type TransitionClasses (line 94) | interface TransitionClasses {
type TransitionEvents (line 107) | interface TransitionEvents {
type TransitionChildPropsWeControl (line 114) | type TransitionChildPropsWeControl = never
type TransitionChildProps (line 116) | type TransitionChildProps<TTag extends ReactTag> = Props<
function useTransitionContext (line 125) | function useTransitionContext() {
function useParentNesting (line 137) | function useParentNesting() {
type NestingContextValues (line 149) | interface NestingContextValues {
function hasChildren (line 164) | function hasChildren(
function useNesting (line 175) | function useNesting(done?: () => void, parent?: NestingContextValues) {
constant DEFAULT_TRANSITION_CHILD_TAG (line 292) | let DEFAULT_TRANSITION_CHILD_TAG = Fragment
type TransitionChildRenderPropArg (line 293) | type TransitionChildRenderPropArg = MutableRefObject<HTMLElement>
function TransitionChildFn (line 296) | function TransitionChildFn<TTag extends ElementType = typeof DEFAULT_TRA...
type TransitionRootProps (line 497) | type TransitionRootProps<TTag extends ElementType = typeof DEFAULT_TRANS...
function TransitionRootFn (line 503) | function TransitionRootFn<TTag extends ElementType = typeof DEFAULT_TRAN...
function ChildFn (line 607) | function ChildFn<TTag extends ElementType = typeof DEFAULT_TRANSITION_CH...
type _internal_ComponentTransitionRoot (line 625) | interface _internal_ComponentTransitionRoot extends HasDisplayName {
type _internal_ComponentTransitionChild (line 631) | interface _internal_ComponentTransitionChild extends HasDisplayName {
FILE: packages/@headlessui-react/src/hooks/__mocks__/use-id.ts
function generateId (line 8) | function generateId() {
function useId (line 12) | function useId() {
FILE: packages/@headlessui-react/src/hooks/document-overflow/adjust-scrollbar-padding.ts
function adjustScrollbarPadding (line 3) | function adjustScrollbarPadding(): ScrollLockStep {
FILE: packages/@headlessui-react/src/hooks/document-overflow/handle-ios-locking.ts
type ContainerMetadata (line 6) | interface ContainerMetadata {
function handleIOSLocking (line 10) | function handleIOSLocking(): ScrollLockStep<ContainerMetadata> {
FILE: packages/@headlessui-react/src/hooks/document-overflow/overflow-store.ts
type DocEntry (line 7) | interface DocEntry {
function buildMeta (line 15) | function buildMeta(fns: Iterable<MetaFn>) {
type MetaFn (line 23) | type MetaFn = (meta: Record<string, any>) => Record<string, any>
type Context (line 25) | interface Context<MetaType extends Record<string, any> = any> {
type ScrollLockStep (line 31) | interface ScrollLockStep<MetaType extends Record<string, any> = any> {
method PUSH (line 37) | PUSH(doc: Document, meta: MetaFn) {
method POP (line 54) | POP(doc: Document, meta: MetaFn) {
method SCROLL_PREVENT (line 65) | SCROLL_PREVENT(entry: DocEntry) {
method SCROLL_ALLOW (line 95) | SCROLL_ALLOW({ d }: DocEntry) {
method TEARDOWN (line 99) | TEARDOWN({ doc }: DocEntry) {
FILE: packages/@headlessui-react/src/hooks/document-overflow/prevent-scroll.ts
function preventScroll (line 3) | function preventScroll(): ScrollLockStep {
FILE: packages/@headlessui-react/src/hooks/document-overflow/use-document-overflow.ts
function useDocumentOverflowLockedEffect (line 5) | function useDocumentOverflowLockedEffect(
FILE: packages/@headlessui-react/src/hooks/use-active-press.tsx
type Rect (line 7) | type Rect = { left: number; right: number; top: number; bottom: number }
function pointerRectFromPointerEvent (line 9) | function pointerRectFromPointerEvent(event: PointerEvent): Rect {
function areRectsOverlapping (line 22) | function areRectsOverlapping(a: Rect | null, b: Rect | null) {
function useActivePress (line 38) | function useActivePress({ disabled = false }: Partial<{ disabled: boolea...
FILE: packages/@headlessui-react/src/hooks/use-by-comparator.ts
type ByComparator (line 3) | type ByComparator<T> =
function defaultBy (line 7) | function defaultBy<T>(a: T, z: T) {
function useByComparator (line 22) | function useByComparator<T>(by: ByComparator<T> = defaultBy) {
FILE: packages/@headlessui-react/src/hooks/use-computed.ts
function useComputed (line 5) | function useComputed<T>(cb: () => T, dependencies: React.DependencyList) {
FILE: packages/@headlessui-react/src/hooks/use-controllable.ts
function useControllable (line 5) | function useControllable<T>(
FILE: packages/@headlessui-react/src/hooks/use-default-value.ts
function useDefaultValue (line 10) | function useDefaultValue<T>(value: T) {
FILE: packages/@headlessui-react/src/hooks/use-disposables.ts
function useDisposables (line 8) | function useDisposables() {
FILE: packages/@headlessui-react/src/hooks/use-document-event.ts
function useDocumentEvent (line 4) | function useDocumentEvent<TType extends keyof DocumentEventMap>(
FILE: packages/@headlessui-react/src/hooks/use-element-size.ts
function computeSize (line 5) | function computeSize(element: HTMLElement | null) {
function useElementSize (line 11) | function useElementSize(enabled: boolean, element: HTMLElement | null, u...
FILE: packages/@headlessui-react/src/hooks/use-escape.ts
function useEscape (line 5) | function useEscape(
FILE: packages/@headlessui-react/src/hooks/use-event-listener.ts
function useEventListener (line 4) | function useEventListener<TType extends keyof WindowEventMap>(
FILE: packages/@headlessui-react/src/hooks/use-flags.ts
function useFlags (line 3) | function useFlags(initialFlags = 0) {
FILE: packages/@headlessui-react/src/hooks/use-handle-toggle.tsx
function useHandleToggle (line 6) | function useHandleToggle(cb: (event: ReactPointerEvent) => void) {
FILE: packages/@headlessui-react/src/hooks/use-inert-others.test.tsx
function Example (line 13) | function Example() {
function Before (line 25) | function Before() {
function After (line 29) | function After() {
function Example (line 59) | function Example() {
function Before (line 71) | function Before() {
function After (line 75) | function After() {
function Example (line 94) | function Example({ children }: { children: ReactNode }) {
function Example (line 144) | function Example({ children }: { children: ReactNode }) {
FILE: packages/@headlessui-react/src/hooks/use-inert-others.tsx
function markInert (line 9) | function markInert(element: HTMLElement) {
function markNotInert (line 30) | function markNotInert(element: HTMLElement) {
function useInertOthers (line 76) | function useInertOthers(
FILE: packages/@headlessui-react/src/hooks/use-is-initial-render.ts
function useIsInitialRender (line 3) | function useIsInitialRender() {
FILE: packages/@headlessui-react/src/hooks/use-is-mounted.ts
function useIsMounted (line 4) | function useIsMounted() {
FILE: packages/@headlessui-react/src/hooks/use-is-top-layer.ts
function useIsTopLayer (line 29) | function useIsTopLayer(enabled: boolean, scope: string | null) {
FILE: packages/@headlessui-react/src/hooks/use-is-touch-device.ts
function useIsTouchDevice (line 4) | function useIsTouchDevice() {
FILE: packages/@headlessui-react/src/hooks/use-latest-value.ts
function useLatestValue (line 4) | function useLatestValue<T>(value: T) {
FILE: packages/@headlessui-react/src/hooks/use-on-disappear.ts
function useOnDisappear (line 13) | function useOnDisappear(
FILE: packages/@headlessui-react/src/hooks/use-on-unmount.ts
function useOnUnmount (line 5) | function useOnUnmount(cb: () => void) {
FILE: packages/@headlessui-react/src/hooks/use-outside-click.ts
type Container (line 9) | type Container = Element | null
type ContainerCollection (line 10) | type ContainerCollection = Container[] | Set<Container>
type ContainerInput (line 11) | type ContainerInput = Container | ContainerCollection
constant MOVE_THRESHOLD_PX (line 19) | const MOVE_THRESHOLD_PX = 30
function useOutsideClick (line 21) | function useOutsideClick(
FILE: packages/@headlessui-react/src/hooks/use-owner.ts
function useOwnerDocument (line 4) | function useOwnerDocument(...args: Parameters<typeof getOwnerDocument>) {
function useRootDocument (line 8) | function useRootDocument(...args: Parameters<typeof getRootNode>) {
FILE: packages/@headlessui-react/src/hooks/use-quick-release.ts
type ActionKind (line 5) | enum ActionKind {
constant POINTER_HOLD_THRESHOLD (line 29) | const POINTER_HOLD_THRESHOLD = 200
constant POINTER_MOVEMENT_THRESHOLD (line 33) | const POINTER_MOVEMENT_THRESHOLD = 5
type PointerEventWithTarget (line 35) | type PointerEventWithTarget = Exclude<PointerEvent, 'target'> & {
function useQuickRelease (line 39) | function useQuickRelease(
FILE: packages/@headlessui-react/src/hooks/use-refocusable-input.ts
function useRefocusableInput (line 13) | function useRefocusableInput(input: HTMLInputElement | null) {
FILE: packages/@headlessui-react/src/hooks/use-resolve-button-type.ts
function useResolveButtonType (line 3) | function useResolveButtonType<TTag>(
FILE: packages/@headlessui-react/src/hooks/use-resolved-tag.ts
function useResolvedTag (line 12) | function useResolvedTag<T extends React.ElementType>(tag: T) {
FILE: packages/@headlessui-react/src/hooks/use-root-containers.tsx
function useRootContainers (line 7) | function useRootContainers({
function MainTreeProvider (line 90) | function MainTreeProvider({
function useMainTreeNode (line 144) | function useMainTreeNode(fallbackMainTreeNode: Element | null = null) {
FILE: packages/@headlessui-react/src/hooks/use-scroll-lock.ts
function useScrollLock (line 4) | function useScrollLock(
FILE: packages/@headlessui-react/src/hooks/use-server-handoff-complete.ts
function useIsHydratingInReact18 (line 13) | function useIsHydratingInReact18(): boolean {
function useServerHandoffComplete (line 36) | function useServerHandoffComplete() {
FILE: packages/@headlessui-react/src/hooks/use-slot.ts
function useSlot (line 5) | function useSlot<ExpectedType extends Record<string, any>>(object: Expec...
FILE: packages/@headlessui-react/src/hooks/use-store.ts
function useStore (line 4) | function useStore<T>(store: Store<T, any>) {
FILE: packages/@headlessui-react/src/hooks/use-sync-refs.ts
function optionalRef (line 6) | function optionalRef<T>(cb: (ref: T) => void, isOptional = true) {
function useSyncRefs (line 10) | function useSyncRefs<TType>(
FILE: packages/@headlessui-react/src/hooks/use-tab-direction.ts
type Direction (line 4) | enum Direction {
function useTabDirection (line 9) | function useTabDirection() {
FILE: packages/@headlessui-react/src/hooks/use-text-value.ts
function useTextValue (line 5) | function useTextValue(element: MutableRefObject<HTMLElement | null>) {
FILE: packages/@headlessui-react/src/hooks/use-tracked-pointer.ts
type PointerPosition (line 3) | type PointerPosition = [x: number, y: number]
function eventToPosition (line 5) | function eventToPosition(evt: PointerEvent): PointerPosition {
function useTrackedPointer (line 9) | function useTrackedPointer() {
FILE: packages/@headlessui-react/src/hooks/use-transition.ts
type TransitionState (line 54) | enum TransitionState {
type TransitionData (line 63) | type TransitionData = {
function transitionDataAttributes (line 70) | function transitionDataAttributes(data: TransitionData) {
function useTransition (line 80) | function useTransition(
function transition (line 209) | function transition(
function waitForTransition (line 256) | function waitForTransition(node: HTMLElement | null, done: () => void) {
function prepareTransition (line 283) | function prepareTransition(
function hasPendingTransitions (line 308) | function hasPendingTransitions(node: HTMLElement) {
FILE: packages/@headlessui-react/src/hooks/use-tree-walker.ts
type AcceptNode (line 5) | type AcceptNode = (
function useTreeWalker (line 12) | function useTreeWalker(
FILE: packages/@headlessui-react/src/hooks/use-watch.ts
function useWatch (line 4) | function useWatch<T extends any[]>(
FILE: packages/@headlessui-react/src/hooks/use-window-event.ts
function useWindowEvent (line 4) | function useWindowEvent<TType extends keyof WindowEventMap>(
FILE: packages/@headlessui-react/src/internal/close-provider.tsx
function useClose (line 7) | function useClose() {
function CloseProvider (line 11) | function CloseProvider({ value, children }: React.PropsWithChildren<{ va...
FILE: packages/@headlessui-react/src/internal/disabled.tsx
function useDisabled (line 5) | function useDisabled() {
function DisabledProvider (line 9) | function DisabledProvider({
FILE: packages/@headlessui-react/src/internal/floating.tsx
type Align (line 21) | type Align = 'start' | 'end'
type Placement (line 22) | type Placement = 'top' | 'right' | 'bottom' | 'left'
type AnchorTo (line 23) | type AnchorTo = `${Placement}` | `${Placement} ${Align}`
type AnchorToWithSelection (line 24) | type AnchorToWithSelection = `${Placement | 'selection'}` | `${Placement...
type BaseAnchorProps (line 26) | type BaseAnchorProps = {
type AnchorProps (line 43) | type AnchorProps =
type AnchorPropsWithSelection (line 56) | type AnchorPropsWithSelection =
type InternalFloatingPanelProps (line 69) | type InternalFloatingPanelProps = Partial<{
function useResolvedAnchor (line 99) | function useResolvedAnchor<T extends AnchorProps | AnchorPropsWithSelect...
function useFloatingReference (line 109) | function useFloatingReference() {
function useFloatingReferenceProps (line 113) | function useFloatingReferenceProps() {
function useFloatingPanelProps (line 117) | function useFloatingPanelProps() {
function useFloatingPanel (line 129) | function useFloatingPanel(
constant MINIMUM_ITEMS_VISIBLE (line 162) | let MINIMUM_ITEMS_VISIBLE = 4
function FloatingProvider (line 164) | function FloatingProvider({
function useFixScrollingPixel (line 373) | function useFixScrollingPixel(element: HTMLElement | null) {
function useResolvedConfig (line 402) | function useResolvedConfig(
function useResolvePxValue (line 413) | function useResolvePxValue(
function resolveVariables (line 527) | function resolveVariables(value: string): string[] {
function resolveCSSVariablePxValue (line 548) | function resolveCSSVariablePxValue(input: string, element: HTMLElement) {
FILE: packages/@headlessui-react/src/internal/focus-sentinel.tsx
type FocusSentinelProps (line 5) | interface FocusSentinelProps {
function FocusSentinel (line 9) | function FocusSentinel({ onFocus }: FocusSentinelProps) {
FILE: packages/@headlessui-react/src/internal/form-fields.tsx
function FormFieldsProvider (line 10) | function FormFieldsProvider(props: React.PropsWithChildren<{}>) {
function HoistFormFields (line 21) | function HoistFormFields({ children }: React.PropsWithChildren<{}>) {
function FormFields (line 31) | function FormFields({
function FormResolver (line 80) | function FormResolver({
FILE: packages/@headlessui-react/src/internal/frozen.tsx
function FrozenFn (line 3) | function FrozenFn(
function useFrozenData (line 18) | function useFrozenData<T>(freeze: boolean, data: T) {
FILE: packages/@headlessui-react/src/internal/hidden.tsx
constant DEFAULT_VISUALLY_HIDDEN_TAG (line 5) | let DEFAULT_VISUALLY_HIDDEN_TAG = 'span' as const
type HiddenFeatures (line 7) | enum HiddenFeatures {
type HiddenRenderPropArg (line 18) | type HiddenRenderPropArg = {}
type HiddenPropsWeControl (line 19) | type HiddenPropsWeControl = never
type HiddenProps (line 20) | type HiddenProps<TTag extends ElementType = typeof DEFAULT_VISUALLY_HIDD...
function VisuallyHidden (line 27) | function VisuallyHidden<TTag extends ElementType = typeof DEFAULT_VISUAL...
type ComponentHidden (line 69) | interface ComponentHidden extends HasDisplayName {
FILE: packages/@headlessui-react/src/internal/id.tsx
function useProvidedId (line 5) | function useProvidedId() {
function IdProvider (line 9) | function IdProvider({ id, children }: React.PropsWithChildren<{ id: stri...
FILE: packages/@headlessui-react/src/internal/open-closed.tsx
type State (line 6) | enum State {
function useOpenClosed (line 13) | function useOpenClosed() {
type Props (line 17) | interface Props {
function OpenClosedProvider (line 22) | function OpenClosedProvider({ value, children }: Props): ReactElement {
function ResetOpenClosedProvider (line 26) | function ResetOpenClosedProvider({ children }: { children: React.ReactNo...
FILE: packages/@headlessui-react/src/internal/portal-force-root.tsx
function usePortalRoot (line 5) | function usePortalRoot() {
type ForcePortalRootProps (line 9) | interface ForcePortalRootProps {
function ForcePortalRoot (line 14) | function ForcePortalRoot(props: ForcePortalRootProps) {
FILE: packages/@headlessui-react/src/machine.ts
method constructor (line 15) | constructor(initialState: State) {
method dispose (line 26) | dispose() {
method state (line 30) | get state(): Readonly<State> {
method subscribe (line 36) | subscribe<Slice>(
method on (line 54) | on<T extends Event['type']>(
method send (line 66) | send(event: Event) {
type Subscriber (line 86) | interface Subscriber<State, Slice> {
function shallowEqual (line 92) | function shallowEqual(a: any, b: any): boolean {
function compareEntries (line 123) | function compareEntries(a: IterableIterator<any>, b: IterableIterator<an...
function isPlainObject (line 135) | function isPlainObject<T>(value: T): value is T & Record<keyof T, unknow...
function batch (line 144) | function batch<F extends (...args: any[]) => void, P extends any[] = Par...
FILE: packages/@headlessui-react/src/machines/stack-machine.ts
type Scope (line 5) | type Scope = string | null
type Id (line 6) | type Id = string
type State (line 8) | interface State {
type ActionTypes (line 12) | enum ActionTypes {
type Actions (line 17) | type Actions = { type: ActionTypes.Push; id: Id } | { type: ActionTypes....
method [ActionTypes.Push] (line 22) | [ActionTypes.Push](state, action) {
method [ActionTypes.Pop] (line 40) | [ActionTypes.Pop](state, action) {
class StackMachine (line 52) | class StackMachine extends Machine<State, Actions> {
method new (line 53) | static new() {
method reduce (line 57) | reduce(state: Readonly<State>, action: Actions): State {
FILE: packages/@headlessui-react/src/react-glue.tsx
function useSlice (line 6) | function useSlice<M extends Machine<any, any>, Slice>(
function identity (line 20) | function identity<T>(value: T) {
FILE: packages/@headlessui-react/src/test-utils/accessibility-assertions.ts
function assertNever (line 4) | function assertNever(x: never): never {
function getLabel (line 10) | function getLabel(): HTMLElement | null {
function getLabels (line 14) | function getLabels(): HTMLElement[] {
function getDescription (line 18) | function getDescription(): HTMLElement | null {
function getDescriptions (line 22) | function getDescriptions(): HTMLElement[] {
function getControl (line 26) | function getControl(): HTMLElement | null {
function getInput (line 30) | function getInput(): HTMLElement | null {
function getSelect (line 34) | function getSelect(): HTMLElement | null {
function getTextarea (line 38) | function getTextarea(): HTMLElement | null {
function getCheckbox (line 42) | function getCheckbox(): HTMLElement | null {
type CheckboxState (line 46) | enum CheckboxState {
function assertCheckbox (line 57) | function assertCheckbox(
function assertLinkedWithLabel (line 114) | function assertLinkedWithLabel(
function assertNotLinkedWithLabel (line 135) | function assertNotLinkedWithLabel(
function assertLinkedWithDescription (line 154) | function assertLinkedWithDescription(
function getMenuButton (line 177) | function getMenuButton(): HTMLElement | null {
function getMenuButtons (line 181) | function getMenuButtons(): HTMLElement[] {
function getMenu (line 185) | function getMenu(): HTMLElement | null {
function getMenus (line 189) | function getMenus(): HTMLElement[] {
function getMenuItems (line 193) | function getMenuItems(): HTMLElement[] {
type MenuState (line 199) | enum MenuState {
function assertMenuButton (line 210) | function assertMenuButton(
function assertMenuButtonLinkedWithMenu (line 259) | function assertMenuButtonLinkedWithMenu(button = getMenuButton(), menu =...
function assertMenuLinkedWithMenuItem (line 273) | function assertMenuLinkedWithMenuItem(item: HTMLElement | null, menu = g...
function assertNoActiveMenuItem (line 286) | function assertNoActiveMenuItem(menu = getMenu()) {
function assertMenu (line 298) | function assertMenu(
function assertMenuItem (line 351) | function assertMenuItem(
function getComboboxLabel (line 384) | function getComboboxLabel(): HTMLElement | null {
function getComboboxButton (line 388) | function getComboboxButton(): HTMLElement | null {
function getComboboxButtons (line 392) | function getComboboxButtons(): HTMLElement[] {
function getComboboxInput (line 396) | function getComboboxInput(): HTMLInputElement | null {
function getCombobox (line 400) | function getCombobox(): HTMLElement | null {
function getComboboxInputs (line 404) | function getComboboxInputs(): HTMLElement[] {
function getComboboxes (line 408) | function getComboboxes(): HTMLElement[] {
function getComboboxOptions (line 412) | function getComboboxOptions(): HTMLElement[] {
type ComboboxState (line 418) | enum ComboboxState {
type ComboboxMode (line 429) | enum ComboboxMode {
function assertCombobox (line 437) | function assertCombobox(
function assertComboboxInput (line 494) | function assertComboboxInput(
function assertComboboxList (line 537) | function assertComboboxList(
function assertComboboxButton (line 590) | function assertComboboxButton(
function assertComboboxLabel (line 639) | function assertComboboxLabel(
function assertComboboxButtonLinkedWithCombobox (line 671) | function assertComboboxButtonLinkedWithCombobox(
function assertComboboxLabelLinkedWithCombobox (line 688) | function assertComboboxLabelLinkedWithCombobox(
function assertComboboxButtonLinkedWithComboboxLabel (line 703) | function assertComboboxButtonLinkedWithComboboxLabel(
function assertActiveComboboxOption (line 720) | function assertActiveComboboxOption(
function assertNotActiveComboboxOption (line 736) | function assertNotActiveComboboxOption(
function assertNoActiveComboboxOption (line 752) | function assertNoActiveComboboxOption(combobox = getComboboxInput()) {
function assertNoSelectedComboboxOption (line 764) | function assertNoSelectedComboboxOption(items = getComboboxOptions()) {
function assertComboboxOption (line 773) | function assertComboboxOption(
function getListboxLabel (line 814) | function getListboxLabel(): HTMLElement | null {
function getListboxButton (line 818) | function getListboxButton(): HTMLElement | null {
function getListboxButtons (line 822) | function getListboxButtons(): HTMLElement[] {
function getListbox (line 826) | function getListbox(): HTMLElement | null {
function getListboxes (line 830) | function getListboxes(): HTMLElement[] {
function getListboxOptions (line 834) | function getListboxOptions(): HTMLElement[] {
type ListboxState (line 840) | enum ListboxState {
type ListboxMode (line 851) | enum ListboxMode {
function assertListbox (line 859) | function assertListbox(
function assertListboxButton (line 922) | function assertListboxButton(
function assertListboxLabel (line 971) | function assertListboxLabel(
function assertListboxButtonLinkedWithListbox (line 1003) | function assertListboxButtonLinkedWithListbox(
function assertListboxLabelLinkedWithListbox (line 1020) | function assertListboxLabelLinkedWithListbox(
function assertListboxButtonLinkedWithListboxLabel (line 1035) | function assertListboxButtonLinkedWithListboxLabel(
function assertActiveListboxOption (line 1052) | function assertActiveListboxOption(item: HTMLElement | null, listbox = g...
function assertNoActiveListboxOption (line 1065) | function assertNoActiveListboxOption(listbox = getListbox()) {
function assertNoSelectedListboxOption (line 1077) | function assertNoSelectedListboxOption(items = getListboxOptions()) {
function assertListboxOption (line 1086) | function assertListboxOption(
function getSwitch (line 1127) | function getSwitch(): HTMLElement | null {
function getSwitchLabel (line 1131) | function getSwitchLabel(): HTMLElement | null {
type SwitchState (line 1137) | enum SwitchState {
function assertSwitch (line 1142) | function assertSwitch(
function getDisclosureButton (line 1201) | function getDisclosureButton(): HTMLElement | null {
function getDisclosurePanel (line 1205) | function getDisclosurePanel(): HTMLElement | null {
type DisclosureState (line 1211) | enum DisclosureState {
function assertDisclosureButton (line 1224) | function assertDisclosureButton(
function assertDisclosurePanel (line 1272) | function assertDisclosurePanel(
function getPopoverButton (line 1321) | function getPopoverButton(): HTMLElement | null {
function getPopoverPanel (line 1325) | function getPopoverPanel(): HTMLElement | null {
function getPopoverOverlay (line 1329) | function getPopoverOverlay(): HTMLElement | null {
type PopoverState (line 1335) | enum PopoverState {
function assertPopoverButton (line 1348) | function assertPopoverButton(
function assertPopoverPanel (line 1396) | function assertPopoverPanel(
function assertLabelValue (line 1445) | function assertLabelValue(element: HTMLElement | null, value: string) {
function assertDescriptionValue (line 1469) | function assertDescriptionValue(element: HTMLElement | null, value: stri...
function getDialog (line 1478) | function getDialog(): HTMLElement | null {
function getDialogs (line 1482) | function getDialogs(): HTMLElement[] {
function getDialogTitle (line 1486) | function getDialogTitle(): HTMLElement | null {
function getDialogDescription (line 1490) | function getDialogDescription(): HTMLElement | null {
type DialogState (line 1496) | enum DialogState {
function assertDialog (line 1509) | function assertDialog(
function assertDialogTitle (line 1562) | function assertDialogTitle(
function assertDialogDescription (line 1618) | function assertDialogDescription(
function getRadioGroup (line 1676) | function getRadioGroup(): HTMLElement | null {
function getRadioGroupLabel (line 1680) | function getRadioGroupLabel(): HTMLElement | null {
function getRadioGroupOptions (line 1684) | function getRadioGroupOptions(): HTMLElement[] {
function assertRadioGroupLabel (line 1690) | function assertRadioGroupLabel(
function getTabList (line 1718) | function getTabList(): HTMLElement | null {
function getTabs (line 1722) | function getTabs(): HTMLElement[] {
function getPanels (line 1726) | function getPanels(): HTMLElement[] {
function assertTabs (line 1732) | function assertTabs(
function assertActiveElement (line 1810) | function assertActiveElement(element: HTMLElement | null) {
function assertContainsActiveElement (line 1828) | function assertContainsActiveElement(element: HTMLElement | null) {
function assertHidden (line 1840) | function assertHidden(element: HTMLElement | null) {
function assertVisible (line 1852) | function assertVisible(element: HTMLElement | null) {
function assertFocusable (line 1866) | function assertFocusable(element: HTMLElement | null) {
function assertNotFocusable (line 1877) | function assertNotFocusable(element: HTMLElement | null) {
function assertInert (line 1888) | function assertInert(element: HTMLElement | null) {
function assertNotInert (line 1900) | function assertNotInert(element: HTMLElement | null) {
function assertDisabledish (line 1915) | function assertDisabledish(element: HTMLElement | null) {
function getByText (line 1938) | function getByText(text: string): HTMLElement | null {
FILE: packages/@headlessui-react/src/test-utils/execute-timeline.ts
function redentSnapshot (line 6) | function redentSnapshot(input: string) {
function executeTimeline (line 25) | async function executeTimeline(
function isWithinFrame (line 180) | function isWithinFrame(actual: number, expected: number) {
FILE: packages/@headlessui-react/src/test-utils/fake-pointer.ts
class FakePointer (line 1) | class FakePointer {
method constructor (line 5) | constructor(
method options (line 13) | get options() {
method randomize (line 20) | randomize() {
method advance (line 25) | advance(amount: number = 1) {
method bypassingTrackingChecks (line 44) | bypassingTrackingChecks(callback: () => void) {
FILE: packages/@headlessui-react/src/test-utils/interactions.test.tsx
type Events (line 5) | type Events = 'onKeyDown' | 'onKeyUp' | 'onKeyPress' | 'onClick' | 'onBl...
type Args (line 8) | type Args = [
function key (line 14) | function key(input: string | Partial<KeyboardEvent>): Partial<KeyboardEv...
function event (line 19) | function event(
function createProps (line 149) | function createProps(id: string) {
FILE: packages/@headlessui-react/src/test-utils/interactions.ts
function nextFrame (line 6) | function nextFrame(cb: Function): void {
function shift (line 36) | function shift(event: Partial<KeyboardEvent>) {
function word (line 40) | function word(input: string): Partial<KeyboardEvent>[] {
function type (line 175) | async function type(events: Partial<KeyboardEvent>[], element = document...
function press (line 220) | async function press(event: Partial<KeyboardEvent>, element = document.a...
type MouseButton (line 224) | enum MouseButton {
function click (line 229) | async function click(
function rawClick (line 236) | async function rawClick(
function focus (line 294) | async function focus(element: Document | Element | Window | Node | null) {
function blur (line 312) | async function blur(element: Document | Element | Window | Node | null) {
function mouseEnter (line 331) | async function mouseEnter(element: Document | Element | Window | null) {
function mouseMove (line 346) | async function mouseMove(element: Document | Element | Window | null) {
function mouseLeave (line 365) | async function mouseLeave(element: Document | Element | Window | null) {
function mouseDrag (line 386) | async function mouseDrag(
function focusNext (line 459) | function focusNext(event: Partial<KeyboardEvent>) {
function getFocusableElements (line 507) | function getFocusableElements(container = document.body) {
FILE: packages/@headlessui-react/src/test-utils/report-dom-node-changes.ts
function reportChanges (line 3) | function reportChanges<TType>(key: () => TType, onChange: (value: TType)...
FILE: packages/@headlessui-react/src/test-utils/scenarios.tsx
function commonControlScenarios (line 17) | function commonControlScenarios(Control: React.ComponentType<any>) {
function commonFormScenarios (line 166) | function commonFormScenarios(
function commonRenderingScenarios (line 284) | function commonRenderingScenarios(
FILE: packages/@headlessui-react/src/test-utils/snapshot.ts
function createSnapshot (line 3) | function createSnapshot() {
FILE: packages/@headlessui-react/src/test-utils/ssr.tsx
type ServerRenderOptions (line 12) | type ServerRenderOptions = Omit<RenderOptions, 'queries'> & {
type ServerRenderResult (line 16) | interface ServerRenderResult {
function renderSSR (line 23) | async function renderSSR(
function renderHydrate (line 77) | async function renderHydrate(el: ReactElement, options: ServerRenderOpti...
FILE: packages/@headlessui-react/src/test-utils/suppress-console-logs.ts
type FunctionPropertyNames (line 1) | type FunctionPropertyNames<T> = {
function suppressConsoleLogs (line 6) | function suppressConsoleLogs<T extends unknown[]>(
function mockingConsoleLogs (line 19) | function mockingConsoleLogs<T extends unknown[]>(
FILE: packages/@headlessui-react/src/types.ts
type ReactTag (line 3) | type ReactTag = keyof React.JSX.IntrinsicElements | JSXElementConstructo...
type Expand (line 5) | type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never
type PropsOf (line 7) | type PropsOf<TTag extends ReactTag> = TTag extends React.ElementType
type PropsWeControl (line 11) | type PropsWeControl = 'as' | 'children' | 'refName' | 'className'
type CleanProps (line 14) | type CleanProps<TTag extends ReactTag, TOmittableProps extends PropertyK...
type OurProps (line 20) | type OurProps<TTag extends ReactTag, TSlot> = {
type HasProperty (line 26) | type HasProperty<T extends object, K extends PropertyKey> = T extends never
type ClassNameOverride (line 35) | type ClassNameOverride<TTag extends ReactTag, TSlot = {}> =
type Props (line 42) | type Props<
type EnsureArray (line 52) | type EnsureArray<T> = T extends any[] ? T : Expand<T>[]
FILE: packages/@headlessui-react/src/utils/active-element-history.ts
function handle (line 7) | function handle(e: Event) {
FILE: packages/@headlessui-react/src/utils/bugs.ts
function isDisabledReactIssue7711 (line 6) | function isDisabledReactIssue7711(element: Element): boolean {
function isFirstLegend (line 21) | function isFirstLegend(element: HTMLLegendElement | null): boolean {
FILE: packages/@headlessui-react/src/utils/calculate-active-index.ts
function assertNever (line 1) | function assertNever(x: never): never {
type Focus (line 5) | enum Focus {
function calculateActiveIndex (line 25) | function calculateActiveIndex<TItem>(
FILE: packages/@headlessui-react/src/utils/class-names.ts
function classNames (line 1) | function classNames(...classes: (false | null | undefined | string)[]): ...
FILE: packages/@headlessui-react/src/utils/default-map.ts
class DefaultMap (line 1) | class DefaultMap<T = string, V = any> extends Map<T, V> {
method constructor (line 2) | constructor(private factory: (key: T) => V) {
method get (line 6) | get(key: T): V {
FILE: packages/@headlessui-react/src/utils/disposables.ts
type Disposables (line 3) | type Disposables = ReturnType<typeof disposables>
function disposables (line 17) | function disposables() {
FILE: packages/@headlessui-react/src/utils/document-ready.ts
function onDocumentReady (line 1) | function onDocumentReady(cb: () => void) {
FILE: packages/@headlessui-react/src/utils/dom.ts
function isNode (line 11) | function isNode(element: unknown): element is Node {
function isElement (line 17) | function isElement(element: unknown): element is Element {
function isHTMLElement (line 21) | function isHTMLElement(element: unknown): element is HTMLElement {
function isHTMLorSVGElement (line 30) | function isHTMLorSVGElement(element: unknown): element is HTMLOrSVGEleme...
function hasInlineStyle (line 34) | function hasInlineStyle(element: unknown): element is ElementCSSInlineSt...
function isHTMLIframeElement (line 38) | function isHTMLIframeElement(element: unknown): element is HTMLIFrameEle...
function isHTMLInputElement (line 42) | function isHTMLInputElement(element: unknown): element is HTMLInputEleme...
function isHTMLTextAreaElement (line 46) | function isHTMLTextAreaElement(element: unknown): element is HTMLTextAre...
function isHTMLLabelElement (line 50) | function isHTMLLabelElement(element: unknown): element is HTMLLabelEleme...
function isHTMLFieldSetElement (line 54) | function isHTMLFieldSetElement(element: unknown): element is HTMLFieldSe...
function isHTMLLegendElement (line 58) | function isHTMLLegendElement(element: unknown): element is HTMLLegendEle...
function isInteractiveElement (line 75) | function isInteractiveElement(element: unknown): element is Element {
FILE: packages/@headlessui-react/src/utils/element-movement.ts
type ResolvedStates (line 9) | type ResolvedStates<T extends Record<string, any>> = {
type ElementPositionState (line 13) | type ElementPositionState = ResolvedStates<typeof ElementPositionState>
function computeVisualPosition (line 15) | function computeVisualPosition(element: HTMLElement): string {
function detectMovement (line 20) | function detectMovement(
FILE: packages/@headlessui-react/src/utils/env.ts
type RenderEnv (line 1) | type RenderEnv = 'client' | 'server'
type HandoffState (line 2) | type HandoffState = 'pending' | 'complete'
class Env (line 4) | class Env {
method set (line 9) | set(env: RenderEnv): void {
method reset (line 17) | reset(): void {
method nextId (line 21) | nextId() {
method isServer (line 25) | get isServer(): boolean {
method isClient (line 29) | get isClient(): boolean {
method detect (line 33) | private detect(): RenderEnv {
method handoff (line 41) | handoff(): void {
method isHandoffComplete (line 47) | get isHandoffComplete(): boolean {
FILE: packages/@headlessui-react/src/utils/focus-management.ts
type Focus (line 47) | enum Focus {
type FocusResult (line 70) | enum FocusResult {
type Direction (line 84) | enum Direction {
type QuerySelectorAll (line 89) | interface QuerySelectorAll {
function getFocusableElements (line 93) | function getFocusableElements(container: QuerySelectorAll | null = docum...
function getAutoFocusableElements (line 102) | function getAutoFocusableElements(container: HTMLElement | null = docume...
type FocusableMode (line 111) | enum FocusableMode {
function isFocusableElement (line 119) | function isFocusableElement(
function restoreFocusIfNecessary (line 142) | function restoreFocusIfNecessary(element: HTMLElement | null) {
type ActivationMethod (line 158) | enum ActivationMethod {
function focusElement (line 197) | function focusElement(element: HTMLOrSVGElement | null) {
function isSelectableElement (line 203) | function isSelectableElement(
function sortByDomNode (line 209) | function sortByDomNode<T>(
function focusFrom (line 227) | function focusFrom(
function focusIn (line 235) | function focusIn(
FILE: packages/@headlessui-react/src/utils/form.ts
type Entries (line 3) | type Entries = [string, string][]
function objectToFormEntries (line 5) | function objectToFormEntries(
function composeKey (line 17) | function composeKey(parent: string | null, key: string): string {
function append (line 21) | function append(entries: Entries, key: string, value: any): void {
function attemptSubmit (line 41) | function attemptSubmit(elementInForm: HTMLElement) {
function isPlainObject (line 68) | function isPlainObject<T>(value: T): value is T & Record<keyof T, unknow...
FILE: packages/@headlessui-react/src/utils/get-text-value.ts
function getTextContents (line 6) | function getTextContents(element: HTMLElement): string {
function getTextValue (line 50) | function getTextValue(element: HTMLElement): string {
FILE: packages/@headlessui-react/src/utils/match.ts
function match (line 1) | function match<TValue extends string | number = string, TReturnValue = u...
FILE: packages/@headlessui-react/src/utils/micro-task.ts
function microTask (line 2) | function microTask(cb: () => void) {
FILE: packages/@headlessui-react/src/utils/once.ts
function once (line 1) | function once<T>(cb: (...args: T[]) => void) {
FILE: packages/@headlessui-react/src/utils/owner.ts
function getOwnerDocument (line 3) | function getOwnerDocument<T extends Element>(
function getRootNode (line 12) | function getRootNode<T extends Element>(
function getActiveElement (line 22) | function getActiveElement(element: Element | null | undefined): Element ...
function isActiveElement (line 26) | function isActiveElement(element: Element | null | undefined): boolean {
FILE: packages/@headlessui-react/src/utils/platform.ts
function isIOS (line 4) | function isIOS() {
function isAndroid (line 19) | function isAndroid() {
function isMobile (line 23) | function isMobile() {
FILE: packages/@headlessui-react/src/utils/render.test.tsx
function contents (line 7) | function contents(id = 'wrapper') {
function Dummy (line 15) | function Dummy<TTag extends ElementType = 'div'>(
function DummyWithClassName (line 32) | function DummyWithClassName<TTag extends ElementType = 'div'>(
function MyComponent (line 94) | function MyComponent<T extends ElementType = 'div'>({
function OtherDummy (line 101) | function OtherDummy<TTag extends ElementType = 'div'>(props: Props<TTag>) {
function Dummy (line 160) | function Dummy<TTag extends ElementType = 'div'>(
function Dummy (line 183) | function Dummy<TTag extends ElementType = 'div'>(
function testStaticFeature (line 280) | function testStaticFeature(Dummy: (props: any) => React.JSX.Element) {
function Dummy (line 309) | function Dummy<TTag extends ElementType = 'div'>(
function testRenderStrategyFeature (line 334) | function testRenderStrategyFeature(Dummy: (props: any) => React.JSX.Elem...
function Dummy (line 385) | function Dummy<TTag extends ElementType = 'div'>(
function Dummy (line 414) | function Dummy<TTag extends ElementType = 'div'>(
FILE: packages/@headlessui-react/src/utils/render.ts
type RenderFeatures (line 18) | enum RenderFeatures {
type RenderStrategy (line 38) | enum RenderStrategy {
type UnionToIntersection (line 43) | type UnionToIntersection<T> = (T extends any ? (x: T) => any : never) ex...
type PropsForFeature (line 47) | type PropsForFeature<
type PropsForFeatures (line 53) | type PropsForFeatures<T extends RenderFeatures> = Expand<
function useRender (line 60) | function useRender() {
function render (line 69) | function render<TFeature extends RenderFeatures, TTag extends ElementTyp...
function _render (line 130) | function _render<TTag extends ElementType, TSlot>(
function useMergeRefsFn (line 294) | function useMergeRefsFn() {
function defaultMergeRefs (line 320) | function defaultMergeRefs(...refs: any[]) {
function mergePropsAdvanced (line 334) | function mergePropsAdvanced(...listOfProps: Props<any, any>[]) {
type HasDisplayName (line 391) | type HasDisplayName = {
type RefProp (line 395) | type RefProp<T extends Function> = T extends (props: any, ref: Ref<infer...
function mergeProps (line 400) | function mergeProps<T extends Props<any, any>[]>(...listOfProps: T) {
function forwardRefWithAs (line 441) | function forwardRefWithAs<T extends { name: string; displayName?: string...
function compact (line 449) | function compact<T extends Record<any, any>>(object: T) {
function omit (line 457) | function omit<T extends Record<any, any>>(object: T, keysToOmit: string[...
function getElementRef (line 465) | function getElementRef(element: React.ReactElement) {
function isFragment (line 470) | function isFragment(element: any): element is typeof Fragment {
function isFragmentInstance (line 474) | function isFragmentInstance(element: React.ReactElement): boolean {
FILE: packages/@headlessui-react/src/utils/stable-collection.tsx
type CollectionKey (line 3) | type CollectionKey = string | symbol
type CollectionItem (line 4) | type CollectionItem = [number, () => void]
type CollectionRef (line 5) | type CollectionRef = React.MutableRefObject<ReturnType<typeof createColl...
function createCollection (line 8) | function createCollection() {
function StableCollection (line 41) | function StableCollection({ children }: { children: React.ReactNode | Re...
function useStableCollectionIndex (line 51) | function useStableCollectionIndex(group: string) {
FILE: packages/@headlessui-react/src/utils/store.ts
type ChangeFn (line 1) | type ChangeFn = () => void
type UnsubscribeFn (line 2) | type UnsubscribeFn = () => void
type ActionFn (line 3) | type ActionFn<T> = (this: T, ...args: any[]) => T | void
type StoreActions (line 4) | type StoreActions<Key extends string, T> = Record<Key, ActionFn<T>>
type Store (line 6) | interface Store<T, ActionKey extends string> {
function createStore (line 12) | function createStore<T, ActionKey extends string>(
FILE: packages/@headlessui-react/types/jest.d.ts
type Matchers (line 5) | interface Matchers<R> {
FILE: packages/@headlessui-tailwindcss/scripts/fix-types.cjs
function run (line 18) | async function run() {
FILE: packages/@headlessui-tailwindcss/src/index.test.ts
function run (line 8) | function run(input: string, config: any, plugin = tailwind) {
FILE: packages/@headlessui-tailwindcss/src/index.ts
type Options (line 3) | interface Options {
FILE: packages/@headlessui-vue/src/components/combobox/combobox.test.ts
function nextFrame (line 63) | function nextFrame() {
function getDefaultComponents (line 73) | function getDefaultComponents() {
method displayValue (line 777) | displayValue(person: string, open: boolean) {
method setup (line 1314) | setup() {
method setup (line 1366) | setup() {
method handleSubmit (line 1423) | handleSubmit(e: SubmitEvent) {
method handleSubmit (line 1483) | handleSubmit(e: SubmitEvent) {
method handleSubmit (line 1543) | handleSubmit(e: SubmitEvent) {
method handleSubmit (line 1590) | handleSubmit(e: SubmitEvent) {
method handleSubmit (line 1652) | handleSubmit(e: SubmitEvent) {
method handleSubmit (line 1712) | handleSubmit(e: SubmitEvent) {
method setup (line 1887) | setup(props, { slots }) {
method setup (line 1895) | setup(_, { slots, emit }) {
method setup (line 1977) | setup() {
method setup (line 2055) | setup(props) {
method setup (line 2961) | setup() {
method setup (line 3007) | setup() {
method update (line 3057) | update(newValue: any) {
method update (line 3105) | update(newValue: any) {
method setup (line 4401) | setup(props) {
function filter (line 4681) | function filter(event: Event & { target: HTMLInputElement }) {
function activeIndex (line 4693) | function activeIndex() {
method setup (line 4782) | setup(props) {
method update (line 5501) | update(newValue: any) {
method update (line 5571) | update(newValue: any) {
method update (line 5616) | update(newValue: any) {
method update (line 5836) | update(newValue: any) {
method handleSubmit (line 6119) | handleSubmit(event: SubmitEvent) {
method handleSubmit (line 6161) | handleSubmit(event: SubmitEvent) {
method handleSubmit (line 6226) | handleSubmit(event: SubmitEvent) {
method handleSubmit (line 6290) | handleSubmit(event: SubmitEvent) {
FILE: packages/@headlessui-vue/src/components/combobox/combobox.ts
function defaultComparator (line 47) | function defaultComparator<T>(a: T, z: T): boolean {
type ComboboxStates (line 51) | enum ComboboxStates {
type ValueMode (line 56) | enum ValueMode {
type ActivationTrigger (line 61) | enum ActivationTrigger {
type ComboboxOptionData (line 67) | type ComboboxOptionData = {
type StateDefinition (line 73) | type StateDefinition = {
function useComboboxContext (line 120) | function useComboboxContext(component: string) {
method setup (line 138) | setup(_, { slots }) {
method setup (line 273) | setup(props, { slots, attrs, emit }) {
method setup (line 777) | setup(props, { attrs, slots }) {
method setup (line 813) | setup(props, { attrs, slots, expose }) {
method setup (line 922) | setup(props, { emit, attrs, slots, expose }) {
method setup (line 1344) | setup(props, { attrs, slots, expose }) {
method setup (line 1433) | setup(props, { slots, attrs, expose }) {
FILE: packages/@headlessui-vue/src/components/description/description.test.ts
function format (line 7) | function format(input: Element | null | string) {
method setup (line 26) | setup() {
method setup (line 42) | setup() {
method setup (line 65) | setup() {
method setup (line 89) | setup() {
FILE: packages/@headlessui-vue/src/components/description/description.ts
function useDescriptionContext (line 26) | function useDescriptionContext() {
function useDescriptions (line 34) | function useDescriptions({
method setup (line 71) | setup(myProps, { attrs, slots }) {
FILE: packages/@headlessui-vue/src/components/dialog/dialog.test.ts
function nextFrame (line 46) | function nextFrame() {
function frames (line 50) | async function frames(count: number) {
method setup (line 131) | setup() {
method setup (line 154) | setup() {
method setup (line 198) | setup() {
method setup (line 231) | setup() {
method setup (line 264) | setup() {
method setup (line 316) | setup() {
method setup (line 347) | setup() {
method setup (line 379) | setup() {
method setup (line 403) | setup() {
method setup (line 425) | setup() {
method setup (line 468) | setup() {
method setup (line 519) | setup() {
method setup (line 576) | setup(props) {
method setup (line 592) | setup() {
method setup (line 651) | setup(props, { slots }) {
method setup (line 753) | setup() {
method setup (line 794) | setup() {
method setup (line 842) | setup() {
method errorCaptured (line 854) | errorCaptured(err) {
method setup (line 886) | setup() {
method setup (line 921) | setup() {
method setup (line 1035) | setup() {
method setup (line 1140) | setup() {
method setup (line 1189) | setup() {
method setup (line 1241) | setup() {
method setup (line 1296) | setup() {
method setup (line 1345) | setup() {
method setup (line 1366) | setup() {
method setup (line 1426) | setup() {
method setup (line 1486) | setup() {
method setup (line 1549) | setup() {
method setup (line 1595) | setup() {
method setup (line 1636) | setup() {
method setup (line 1678) | setup() {
method setup (line 1720) | setup() {
method setup (line 1765) | setup() {
method setup (line 1804) | setup() {
method setup (line 1849) | setup() {
method setup (line 1903) | setup() {
method setup (line 1959) | setup() {
method setup (line 1998) | setup(props) {
method setup (line 2039) | setup() {
method setup (line 2099) | setup(props) {
method setup (line 2140) | setup() {
method setup (line 2211) | setup() {
method setup (line 2253) | setup() {
method setup (line 2295) | setup() {
method setup (line 2338) | setup() {
method setup (line 2376) | setup(props, { emit }) {
method setup (line 2427) | setup() {
FILE: packages/@headlessui-vue/src/components/dialog/dialog.ts
type DialogStates (line 35) | enum DialogStates {
type StateDefinition (line 40) | interface StateDefinition {
function useDialogContext (line 53) | function useDialogContext(component: string) {
method setup (line 80) | setup(props, { emit, attrs, slots, expose }) {
method setup (line 358) | setup(props, { attrs, slots }) {
method setup (line 397) | setup(props, { attrs, slots, expose }) {
method setup (line 443) | setup(props, { attrs, slots, expose }) {
method setup (line 480) | setup(props, { attrs, slots }) {
FILE: packages/@headlessui-vue/src/components/disclosure/disclosure.test.ts
method setup (line 530) | setup(props, { slots }) {
method setup (line 538) | setup(_, { slots, emit }) {
method setup (line 615) | setup() {
FILE: packages/@headlessui-vue/src/components/disclosure/disclosure.ts
type DisclosureStates (line 22) | enum DisclosureStates {
type StateDefinition (line 27) | interface StateDefinition {
function useDisclosureContext (line 45) | function useDisclosureContext(component: string) {
function useDisclosurePanelContext (line 58) | function useDisclosurePanelContext() {
method setup (line 70) | setup(props, { slots, attrs }) {
method setup (line 142) | setup(props, { attrs, slots, expose }) {
method setup (line 268) | setup(props, { attrs, slots, expose }) {
FILE: packages/@headlessui-vue/src/components/focus-trap/focus-trap.test.ts
function nextFrame (line 18) | function nextFrame() {
method setup (line 53) | setup() {
method setup (line 76) | setup() {
method setup (line 96) | setup() {
method setup (line 197) | setup() {
FILE: packages/@headlessui-vue/src/components/focus-trap/focus-trap.ts
type Containers (line 25) | type Containers =
function resolveContainers (line 32) | function resolveContainers(containers?: Containers): Set<HTMLElement> {
type Features (line 46) | enum Features {
method setup (line 79) | setup(props, { attrs, slots, expose }) {
function useRestoreElement (line 210) | function useRestoreElement(enabled: Ref<boolean>) {
function useRestoreFocus (line 240) | function useRestoreFocus(
function useInitialFocus (line 268) | function useInitialFocus(
function useFocusLock (line 345) | function useFocusLock(
function contains (line 391) | function contains(containers: Set<HTMLElement>, element: HTMLElement) {
FILE: packages/@headlessui-vue/src/components/label/label.test.ts
function format (line 7) | function format(input: Element | null | string) {
method setup (line 26) | setup() {
method setup (line 41) | setup() {
method setup (line 64) | setup() {
method setup (line 88) | setup() {
FILE: packages/@headlessui-vue/src/components/label/label.ts
function useLabelContext (line 25) | function useLabelContext() {
function useLabels (line 35) | function useLabels({
method setup (line 70) | setup(myProps, { slots, attrs }) {
FILE: packages/@headlessui-vue/src/components/listbox/listbox.test.tsx
function nextFrame (line 50) | function nextFrame() {
method setup (line 923) | setup() {
method handleSubmit (line 982) | handleSubmit(e: SubmitEvent) {
method handleSubmit (line 1041) | handleSubmit(e: SubmitEvent) {
method handleSubmit (line 1100) | handleSubmit(e: SubmitEvent) {
method handleSubmit (line 1146) | handleSubmit(e: SubmitEvent) {
method handleSubmit (line 1204) | handleSubmit(e: SubmitEvent) {
method handleSubmit (line 1258) | handleSubmit(e: SubmitEvent) {
method setup (line 1379) | setup(props, { slots }) {
method setup (line 1387) | setup(_, { slots, emit }) {
method setup (line 1466) | setup() {
method setup (line 1940) | setup() {
method setup (line 2266) | setup() {
method setup (line 4643) | setup() {
method setup (line 4689) | setup() {
method handleSubmit (line 4991) | handleSubmit(event: SubmitEvent) {
method handleSubmit (line 5032) | handleSubmit(event: SubmitEvent) {
method handleSubmit (line 5096) | handleSubmit(event: SubmitEvent) {
method handleSubmit (line 5159) | handleSubmit(event: SubmitEvent) {
FILE: packages/@headlessui-vue/src/components/listbox/listbox.ts
function defaultComparator (line 37) | function defaultComparator<T>(a: T, z: T): boolean {
type ListboxStates (line 41) | enum ListboxStates {
type ValueMode (line 46) | enum ValueMode {
type ActivationTrigger (line 51) | enum ActivationTrigger {
function nextFrame (line 56) | function nextFrame(cb: () => void) {
type ListboxOptionData (line 60) | type ListboxOptionData = {
type StateDefinition (line 67) | type StateDefinition = {
function useListboxContext (line 100) | function useListboxContext(component: string) {
method setup (line 139) | setup(props, { slots, attrs, emit }) {
method setup (line 432) | setup(props, { attrs, slots }) {
method setup (line 467) | setup(props, { attrs, slots, expose }) {
method setup (line 570) | setup(props, { attrs, slots, expose }) {
method setup (line 702) | setup(props, { slots, attrs, expose }) {
FILE: packages/@headlessui-vue/src/components/menu/menu.test.tsx
function nextFrame (line 46) | function nextFrame() {
method errorCaptured (line 172) | errorCaptured(err) {
method setup (line 298) | setup(_, { slots }) {
method errorCaptured (line 341) | errorCaptured(err) {
method errorCaptured (line 537) | errorCaptured(err) {
method errorCaptured (line 751) | errorCaptured(err) {
method setup (line 827) | setup() {
method setup (line 898) | setup(props) {
method setup (line 985) | setup(props, { slots }) {
method setup (line 993) | setup(_, { slots, emit }) {
method setup (line 1074) | setup() {
method setup (line 1117) | setup() {
FILE: packages/@headlessui-vue/src/components/menu/menu.ts
type MenuStates (line 37) | enum MenuStates {
type ActivationTrigger (line 42) | enum ActivationTrigger {
function nextFrame (line 47) | function nextFrame(cb: () => void) {
type MenuItemData (line 51) | type MenuItemData = {
type StateDefinition (line 56) | type StateDefinition = {
function useMenuContext (line 78) | function useMenuContext(component: string) {
method setup (line 93) | setup(props, { slots, attrs }) {
method setup (line 252) | setup(props, { attrs, slots, expose }) {
method setup (line 349) | setup(props, { attrs, slots, expose }) {
method setup (line 503) | setup(props, { slots, attrs, expose }) {
FILE: packages/@headlessui-vue/src/components/popover/popover.test.ts
function getTrigger (line 91) | function getTrigger(number: number) {
function getPanel (line 95) | function getPanel(number: number) {
method setup (line 686) | setup(props, { slots }) {
method setup (line 694) | setup(_, { slots, emit }) {
method setup (line 771) | setup() {
function getTrigger (line 1067) | function getTrigger(number: number) {
function getPanel (line 1071) | function getPanel(number: number) {
method setup (line 1687) | setup() {
method setup (line 2270) | setup() {
FILE: packages/@headlessui-vue/src/components/popover/popover.ts
type PopoverStates (line 41) | enum PopoverStates {
type StateDefinition (line 46) | interface StateDefinition {
function usePopoverContext (line 68) | function usePopoverContext(component: string) {
function usePopoverGroupContext (line 86) | function usePopoverGroupContext() {
function usePopoverPanelContext (line 91) | function usePopoverPanelContext() {
type PopoverRegisterBag (line 95) | interface PopoverRegisterBag {
method setup (line 109) | setup(props, { slots, attrs, expose }) {
method setup (line 291) | setup(props, { attrs, slots, expose }) {
method setup (line 490) | setup(props, { attrs, slots }) {
method setup (line 541) | setup(props, { attrs, slots, expose }) {
method setup (line 758) | setup(props, { attrs, slots, expose }) {
FILE: packages/@headlessui-vue/src/components/portal/portal.test.ts
function getPortalRoot (line 15) | function getPortalRoot() {
function ssrRenderTemplate (line 34) | async function ssrRenderTemplate(input: string | ComponentOptionsWithout...
function withoutBrowserGlobals (line 59) | async function withoutBrowserGlobals<T>(fn: () => Promise<T>) {
method setup (line 188) | setup() {
method setup (line 265) | setup() {
method setup (line 339) | setup() {
method setup (line 389) | setup() {
FILE: packages/@headlessui-vue/src/components/portal/portal.ts
type ContextType (line 24) | type ContextType<T> = T extends InjectionKey<infer V> ? V : never
function getPortalRoot (line 28) | function getPortalRoot(contextElement?: HTMLElement | null) {
method setup (line 52) | setup(props, { slots, attrs }) {
function useNestedPortals (line 138) | function useNestedPortals() {
method setup (line 184) | setup(props, { attrs, slots }) {
FILE: packages/@headlessui-vue/src/components/radio-group/radio-group.test.ts
function nextFrame (line 25) | function nextFrame() {
method setup (line 64) | setup() {
method setup (line 79) | setup() {
method setup (line 98) | setup() {
method setup (line 123) | setup() {
method setup (line 148) | setup() {
method setup (line 172) | setup() {
method setup (line 205) | setup() {
method setup (line 228) | setup() {
method setup (line 280) | setup() {
method setup (line 307) | setup() {
method setup (line 334) | setup() {
method setup (line 402) | setup() {
method setup (line 466) | setup() {
method handleSubmit (line 665) | handleSubmit(e: SubmitEvent) {
method handleSubmit (line 714) | handleSubmit(e: SubmitEvent) {
method handleSubmit (line 755) | handleSubmit(e: SubmitEvent) {
method handleSubmit (line 811) | handleSubmit(e: SubmitEvent) {
method setup (line 894) | setup() {
method setup (line 918) | setup() {
method setup (line 944) | setup() {
method setup (line 966) | setup() {
method setup (line 992) | setup() {
method setup (line 1020) | setup() {
method setup (line 1049) | setup() {
method setup (line 1076) | setup() {
method setup (line 1104) | setup() {
method setup (line 1129) | setup() {
method setup (line 1157) | setup() {
method setup (line 1186) | setup() {
method setup (line 1216) | setup() {
method setup (line 1259) | setup() {
method setup (line 1300) | setup() {
method setup (line 1345) | setup() {
method setup (line 1390) | setup() {
method setup (line 1425) | setup() {
method setup (line 1467) | setup() {
method setup (line 1503) | setup() {
method setup (line 1542) | setup() {
method setup (line 1569) | setup() {
method setup (line 1607) | setup() {
method setup (line 1645) | setup() {
method handleSubmit (line 1703) | handleSubmit(event: SubmitEvent) {
method setup (line 1735) | setup() {
FILE: packages/@headlessui-vue/src/components/radio-group/radio-group.ts
function defaultComparator (line 30) | function defaultComparator<T>(a: T, z: T): boolean {
type Option (line 34) | interface Option {
type StateDefinition (line 40) | interface StateDefinition {
function useRadioGroupContext (line 58) | function useRadioGroupContext(component: string) {
method setup (line 86) | setup(props, { emit, attrs, slots, expose }) {
type OptionState (line 287) | enum OptionState {
method setup (line 300) | setup(props, { attrs, slots, expose }) {
FILE: packages/@headlessui-vue/src/components/switch/switch.test.tsx
method handleSubmit (line 164) | handleSubmit(e: SubmitEvent) {
method handleSubmit (line 206) | handleSubmit(e: SubmitEvent) {
method handleSubmit (line 248) | handleSubmit(e: SubmitEvent) {
method handleSubmission (line 282) | handleSubmission(e: SubmitEvent) {
method setup (line 540) | setup() {
method setup (line 572) | setup() {
method setup (line 600) | setup() {
method setup (line 632) | setup() {
method setup (line 692) | setup() {
method setup (line 724) | setup() {
method setup (line 762) | setup() {
method setup (line 797) | setup() {
method setup (line 829) | setup() {
method setup (line 864) | setup() {
method setup (line 905) | setup() {
method handleSubmit (line 951) | handleSubmit(event: SubmitEvent) {
FILE: packages/@headlessui-vue/src/components/switch/switch.ts
type StateDefinition (line 25) | type StateDefinition = {
method setup (line 41) | setup(props, { slots, attrs }) {
method setup (line 85) | setup(props, { emit, attrs, slots, expose }) {
FILE: packages/@headlessui-vue/src/components/tabs/tabs.test.ts
method setup (line 105) | setup() {
method setup (line 150) | setup() {
method setup (line 189) | setup() {
method setup (line 229) | setup() {
method setup (line 316) | setup() {
method setup (line 716) | setup() {
method setup (line 760) | setup() {
method setup (line 802) | setup() {
method setup (line 846) | setup() {
method setup (line 903) | setup() {
method setup (line 962) | setup() {
method setup (line 1165) | setup() {
method setup (line 1215) | setup() {
FILE: packages/@headlessui-vue/src/components/tabs/tabs.ts
type Direction (line 28) | enum Direction {
type Ordering (line 33) | enum Ordering {
type StateDefinition (line 39) | type StateDefinition = {
function useTabsContext (line 58) | function useTabsContext(component: string) {
method setup (line 89) | setup(props, { slots, attrs, emit }) {
method setup (line 287) | setup(props, { attrs, slots }) {
method setup (line 320) | setup(props, { attrs, slots, expose }) {
method setup (line 470) | setup(props, { slots, attrs }) {
method setup (line 497) | setup(props, { attrs, slots, expose }) {
FILE: packages/@headlessui-vue/src/components/transitions/transition.test.ts
function getByTestId (line 14) | function getByTestId(id: string) {
function withStyles (line 25) | function withStyles(css: string) {
method errorCaptured (line 61) | errorCaptured(err) {
method errorCaptured (line 141) | errorCaptured(err) {
method setup (line 251) | setup() {
method errorCaptured (line 266) | errorCaptured(err) {
method setup (line 342) | setup() {
method setup (line 377) | setup() {
method setup (line 412) | setup() {
method setup (line 447) | setup() {
method setup (line 484) | setup() {
method setup (line 528) | setup() {
method setup (line 579) | setup() {
method setup (line 637) | setup() {
method setup (line 697) | setup() {
method setup (line 751) | setup() {
method setup (line 815) | setup() {
method setup (line 917) | setup() {
FILE: packages/@headlessui-vue/src/components/transitions/transition.ts
type ID (line 30) | type ID = ReturnType<typeof useId>
function splitClasses (line 38) | function splitClasses(classes: string = '') {
type TransitionContextValues (line 42) | interface TransitionContextValues {
type TreeStates (line 48) | enum TreeStates {
function hasTransitionContext (line 53) | function hasTransitionContext() {
function useTransitionContext (line 57) | function useTransitionContext() {
function useParentNesting (line 67) | function useParentNesting() {
type NestingContextValues (line 77) | interface NestingContextValues {
function hasChildren (line 85) | function hasChildren(
function useNesting (line 92) | function useNesting(done?: () => void) {
method setup (line 159) | setup(props, { emit, attrs, slots, expose }) {
method setup (line 413) | setup(props, { emit, attrs, slots }) {
FILE: packages/@headlessui-vue/src/components/transitions/utils/transition.ts
function addClasses (line 4) | function addClasses(node: HTMLElement, ...classes: string[]) {
function removeClasses (line 8) | function removeClasses(node: HTMLElement, ...classes: string[]) {
type Reason (line 12) | enum Reason {
function waitForTransition (line 17) | function waitForTransition(node: HTMLElement, done: (reason: Reason) => ...
function transition (line 56) | function transition(
FILE: packages/@headlessui-vue/src/hooks/__mocks__/use-id.ts
function generateId (line 6) | function generateId() {
function useId (line 10) | function useId() {
FILE: packages/@headlessui-vue/src/hooks/document-overflow/adjust-scrollbar-padding.ts
function adjustScrollbarPadding (line 3) | function adjustScrollbarPadding(): ScrollLockStep {
FILE: packages/@headlessui-vue/src/hooks/document-overflow/handle-ios-locking.ts
type ContainerMetadata (line 5) | interface ContainerMetadata {
function handleIOSLocking (line 9) | function handleIOSLocking(): ScrollLockStep<ContainerMetadata> {
FILE: packages/@headlessui-vue/src/hooks/document-overflow/overflow-store.ts
type DocEntry (line 7) | interface DocEntry {
function buildMeta (line 14) | function buildMeta(fns: Iterable<MetaFn>) {
type MetaFn (line 22) | type MetaFn = (meta: Record<string, any>) => Record<string, any>
type Context (line 24) | interface Context<MetaType extends Record<string, any> = any> {
type ScrollLockStep (line 30) | interface ScrollLockStep<MetaType extends Record<string, any> = any> {
method PUSH (line 36) | PUSH(doc: Document, meta: MetaFn) {
method POP (line 51) | POP(doc: Document, meta: MetaFn) {
method SCROLL_PREVENT (line 61) | SCROLL_PREVENT({ doc, d, meta }: DocEntry) {
method SCROLL_ALLOW (line 81) | SCROLL_ALLOW({ d }: DocEntry) {
method TEARDOWN (line 85) | TEARDOWN({ doc }: DocEntry) {
FILE: packages/@headlessui-vue/src/hooks/document-overflow/prevent-scroll.ts
function preventScroll (line 3) | function preventScroll(): ScrollLockStep {
FILE: packages/@headlessui-vue/src/hooks/document-overflow/use-document-overflow.ts
function useDocumentOverflowLockedEffect (line 5) | function useDocumentOverflowLockedEffect(
FILE: packages/@headlessui-vue/src/hooks/use-controllable.ts
function useControllable (line 3) | function useControllable<T>(
FILE: packages/@headlessui-vue/src/hooks/use-disposables.ts
function useDisposables (line 8) | function useDisposables() {
FILE: packages/@headlessui-vue/src/hooks/use-document-event.ts
function useDocumentEvent (line 4) | function useDocumentEvent<TType extends keyof DocumentEventMap>(
FILE: packages/@headlessui-vue/src/hooks/use-event-listener.ts
function useEventListener (line 4) | function useEventListener<TType extends keyof WindowEventMap>(
FILE: packages/@headlessui-vue/src/hooks/use-frame-debounce.ts
function useFrameDebounce (line 10) | function useFrameDebounce() {
FILE: packages/@headlessui-vue/src/hooks/use-id.ts
function generateId (line 2) | function generateId() {
function useId (line 6) | function useId() {
FILE: packages/@headlessui-vue/src/hooks/use-inert.test.ts
function renderTemplate (line 17) | function renderTemplate(input: string | ComponentOptionsWithoutProps) {
method setup (line 63) | setup() {
method setup (line 110) | setup() {
method setup (line 147) | setup() {
FILE: packages/@headlessui-vue/src/hooks/use-inert.ts
function useInert (line 7) | function useInert<TElement extends HTMLElement>(
FILE: packages/@headlessui-vue/src/hooks/use-outside-click.ts
type Container (line 8) | type Container = Ref<HTMLElement | null> | HTMLElement | null
type ContainerCollection (line 9) | type ContainerCollection = Container[] | Set<Container>
type ContainerInput (line 10) | type ContainerInput = Container | ContainerCollection
constant MOVE_THRESHOLD_PX (line 18) | const MOVE_THRESHOLD_PX = 30
function useOutsideClick (line 20) | function useOutsideClick(
FILE: packages/@headlessui-vue/src/hooks/use-resolve-button-type.ts
function resolveType (line 4) | function resolveType(type: unknown, as: string | object) {
function useResolveButtonType (line 13) | function useResolveButtonType(
FILE: packages/@headlessui-vue/src/hooks/use-root-containers.ts
function useRootContainers (line 6) | function useRootContainers({
function useMainTreeNode (line 68) | function useMainTreeNode() {
FILE: packages/@headlessui-vue/src/hooks/use-store.ts
function useStore (line 4) | function useStore<T>(store: Store<T, any>) {
FILE: packages/@headlessui-vue/src/hooks/use-tab-direction.ts
type Direction (line 4) | enum Direction {
function useTabDirection (line 9) | function useTabDirection() {
FILE: packages/@headlessui-vue/src/hooks/use-text-value.ts
function useTextValue (line 5) | function useTextValue(element: Ref<HTMLElement | null>) {
FILE: packages/@headlessui-vue/src/hooks/use-tracked-pointer.ts
type PointerPosition (line 3) | type PointerPosition = [x: number, y: number]
function eventToPosition (line 5) | function eventToPosition(evt: PointerEvent): PointerPosition {
function useTrackedPointer (line 9) | function useTrackedPointer() {
FILE: packages/@headlessui-vue/src/hooks/use-tree-walker.ts
type AcceptNode (line 4) | type AcceptNode = (
function useTreeWalker (line 11) | function useTreeWalker({
FILE: packages/@headlessui-vue/src/hooks/use-window-event.ts
function useWindowEvent (line 4) | function useWindowEvent<TType extends keyof WindowEventMap>(
FILE: packages/@headlessui-vue/src/internal/dom-containers.ts
function contains (line 1) | function contains(containers: Set<HTMLElement>, element: HTMLElement) {
FILE: packages/@headlessui-vue/src/internal/focus-sentinel.ts
method setup (line 11) | setup(props) {
FILE: packages/@headlessui-vue/src/internal/hidden.ts
type Features (line 4) | enum Features {
method setup (line 21) | setup(props, { slots, attrs }) {
FILE: packages/@headlessui-vue/src/internal/open-closed.ts
type State (line 5) | enum State {
function hasOpenClosed (line 12) | function hasOpenClosed() {
function useOpenClosed (line 16) | function useOpenClosed() {
function useOpenClosedProvider (line 20) | function useOpenClosedProvider(value: Ref<State>) {
FILE: packages/@headlessui-vue/src/internal/portal-force-root.ts
function usePortalRoot (line 6) | function usePortalRoot() {
method setup (line 16) | setup(props, { slots, attrs }) {
FILE: packages/@headlessui-vue/src/internal/stack-context.ts
type OnUpdate (line 3) | type OnUpdate = (message: StackMessage, type: string, element: Ref<HTMLE...
type StackMessage (line 7) | enum StackMessage {
function useStackContext (line 12) | function useStackContext() {
function useStackProvider (line 16) | function useStackProvider({
FILE: packages/@headlessui-vue/src/keyboard.ts
type Keys (line 3) | enum Keys {
FILE: packages/@headlessui-vue/src/mouse.ts
type MouseButton (line 1) | enum MouseButton {
FILE: packages/@headlessui-vue/src/test-utils/accessibility-assertions.ts
function assertNever (line 3) | function assertNever(x: never): never {
function getMenuButton (line 9) | function getMenuButton(): HTMLElement | null {
function getMenuButtons (line 13) | function getMenuButtons(): HTMLElement[] {
function getMenu (line 17) | function getMenu(): HTMLElement | null {
function getMenus (line 21) | function getMenus(): HTMLElement[] {
function getMenuItems (line 25) | function getMenuItems(): HTMLElement[] {
type MenuState (line 31) | enum MenuState {
function assertMenuButton (line 42) | function assertMenuButton(
function assertMenuButtonLinkedWithMenu (line 91) | function assertMenuButtonLinkedWithMenu(button = getMenuButton(), menu =...
function assertMenuLinkedWithMenuItem (line 105) | function assertMenuLinkedWithMenuItem(item: HTMLElement | null, menu = g...
function assertNoActiveMenuItem (line 118) | function assertNoActiveMenuItem(menu = getMenu()) {
function assertMenu (line 130) | function assertMenu(
function assertMenuItem (line 183) | function assertMenuItem(
function getComboboxLabel (line 216) | function getComboboxLabel(): HTMLElement | null {
function getComboboxButton (line 220) | function getComboboxButton(): HTMLElement | null {
function getComboboxButtons (line 224) | function getComboboxButtons(): HTMLElement[] {
function getComboboxInput (line 228) | function getComboboxInput(): HTMLInputElement | null {
function getCombobox (line 232) | function getCombobox(): HTMLElement | null {
function getComboboxInputs (line 236) | function getComboboxInputs(): HTMLElement[] {
function getComboboxes (line 240) | function getComboboxes(): HTMLElement[] {
function getComboboxOptions (line 244) | function getComboboxOptions(): HTMLElement[] {
type ComboboxState (line 250) | enum ComboboxState {
type ComboboxMode (line 261) | enum ComboboxMode {
function assertCombobox (line 269) | function assertCombobox(
function assertComboboxInput (line 326) | function assertComboboxInput(
function assertComboboxList (line 369) | function assertComboboxList(
function assertComboboxButton (line 422) | function assertComboboxButton(
function assertComboboxLabel (line 471) | function assertComboboxLabel(
function assertComboboxButtonLinkedWithCombobox (line 503) | function assertComboboxButtonLinkedWithCombobox(
function assertComboboxLabelLinkedWithCombobox (line 520) | function assertComboboxLabelLinkedWithCombobox(
function assertComboboxButtonLinkedWithComboboxLabel (line 535) | function assertComboboxButtonLinkedWithComboboxLabel(
function assertActiveComboboxOption (line 552) | function assertActiveComboboxOption(
function assertNotActiveComboboxOption (line 568) | function assertNotActiveComboboxOption(
function assertNoActiveComboboxOption (line 584) | function assertNoActiveComboboxOption(combobox = getComboboxInput()) {
function assertNoSelectedComboboxOption (line 596) | function assertNoSelectedComboboxOption(items = getComboboxOptions()) {
function assertComboboxOption (line 605) | function assertComboboxOption(
function getListboxLabel (line 646) | function getListboxLabel(): HTMLElement | null {
function getListboxButton (line 650) | function getListboxButton(): HTMLElement | null {
function getListboxButtons (line 654) | function getListboxButtons(): HTMLElement[] {
function getListbox (line 658) | function getListbox(): HTMLElement | null {
function getListboxes (line 662) | function getListboxes(): HTMLElement[] {
function getListboxOptions (line 666) | function getListboxOptions(): HTMLElement[] {
type ListboxState (line 672) | enum ListboxState {
type ListboxMode (line 683) | enum ListboxMode {
function assertListbox (line 691) | function assertListbox(
function assertListboxButton (line 754) | function assertListboxButton(
function assertListboxLabel (line 803) | function assertListboxLabel(
function assertListboxButtonLinkedWithListbox (line 835) | function assertListboxButtonLinkedWithListbox(
function assertListboxLabelLinkedWithListbox (line 852) | function assertListboxLabelLinkedWithListbox(
function assertListboxButtonLinkedWithListboxLabel (line 867) | function assertListboxButtonLinkedWithListboxLabel(
function assertActiveListboxOption (line 884) | function assertActiveListboxOption(item: HTMLElement | null, listbox = g...
function assertNoActiveListboxOption (line 897) | function assertNoActiveListboxOption(listbox = getListbox()) {
function assertNoSelectedListboxOption (line 909) | function assertNoSelectedListboxOption(items = getListboxOptions()) {
function assertListboxOption (line 918) | function assertListboxOption(
function getSwitch (line 959) | function getSwitch(): HTMLElement | null {
function getSwitchLabel (line 963) | function getSwitchLabel(): HTMLElement | null {
type SwitchState (line 969) | enum SwitchState {
function assertSwitch (line 974) | function assertSwitch(
function getDisclosureButton (line 1033) | function getDisclosureButton(): HTMLElement | null {
function getDisclosurePanel (line 1037) | function getDisclosurePanel(): HTMLElement | null {
type DisclosureState (line 1043) | enum DisclosureState {
function assertDisclosureButton (line 1056) | function assertDisclosureButton(
function assertDisclosurePanel (line 1104) | function assertDisclosurePanel(
function getPopoverButton (line 1153) | function getPopoverButton(): HTMLElement | null {
function getPopoverPanel (line 1157) | function getPopoverPanel(): HTMLElement | null {
function getPopoverOverlay (line 1161) | function getPopoverOverlay(): HTMLElement | null {
type PopoverState (line 1167) | enum PopoverState {
function assertPopoverButton (line 1180) | function assertPopoverButton(
function assertPopoverPanel (line 1228) | function assertPopoverPanel(
function assertLabelValue (line 1277) | function assertLabelValue(element: HTMLElement | null, value: string) {
function assertDescriptionValue (line 1301) | function assertDescriptionValue(element: HTMLElement | null, value: stri...
function getDialog (line 1310) | function getDialog(): HTMLElement | null {
function getDialogs (line 1314) | function getDialogs(): HTMLElement[] {
function getDialogTitle (line 1318) | function getDialogTitle(): HTMLElement | null {
function getDialogDescription (line 1322) | function getDialogDescription(): HTMLElement | null {
function getDialogOverlay (line 1326) | function getDialogOverlay(): HTMLElement | null {
function getDialogBackdrop (line 1330) | function getDialogBackdrop(): HTMLElement | null {
function getDialogOverlays (line 1334) | function getDialogOverlays(): HTMLElement[] {
type DialogState (line 1340) | enum DialogState {
function assertDialog (line 1353) | function assertDialog(
function assertDialogTitle (line 1406) | function assertDialogTitle(
function assertDialogDescription (line 1462) | function assertDialogDescription(
function assertDialogOverlay (line 1518) | function assertDialogOverlay(
function getRadioGroup (line 1567) | function getRadioGroup(): HTMLElement | null {
function getRadioGroupLabel (line 1571) | function getRadioGroupLabel(): HTMLElement | null {
function getRadioGroupOptions (line 1575) | function getRadioGroupOptions(): HTMLElement[] {
function assertRadioGroupLabel (line 1581) | function assertRadioGroupLabel(
function getTabList (line 1609) | function getTabList(): HTMLElement | null {
function getTabs (line 1613) | function getTabs(): HTMLElement[] {
function getPanels (line 1617) | function getPanels(): HTMLElement[] {
function assertTabs (line 1623) | function assertTabs(
function assertActiveElement (line 1701) | function assertActiveElement(element: HTMLElement | null) {
function assertContainsActiveElement (line 1719) | function assertContainsActiveElement(element: HTMLElement | null) {
function assertHidden (line 1731) | function assertHidden(element: HTMLElement | null) {
function assertVisible (line 1743) | function assertVisible(element: HTMLElement | null) {
function assertFocusable (line 1757) | function assertFocusable(element: HTMLElement | null) {
function assertNotFocusable (line 1768) | function assertNotFocusable(element: HTMLElement | null) {
function assertInert (line 1779) | function assertInert(element: HTMLElement | null) {
function assertNotInert (line 1791) | function assertNotInert(element: HTMLElement | null) {
function getByText (line 1806) | function getByText(text: string): HTMLElement | null {
FILE: packages/@headlessui-vue/src/test-utils/execute-timeline.ts
function redentSnapshot (line 7) | function redentSnapshot(input: string) {
function executeTimeline (line 26) | async function executeTimeline(
function isWithinFrame (line 175) | function isWithinFrame(actual: number, expected: number) {
FILE: packages/@headlessui-vue/src/test-utils/fake-pointer.ts
class FakePointer (line 1) | class FakePointer {
method constructor (line 5) | constructor(
method options (line 13) | get options() {
method randomize (line 20) | randomize() {
method advance (line 25) | advance(amount: number = 1) {
method bypassingTrackingChecks (line 44) | bypassingTrackingChecks(callback: () => void) {
FILE: packages/@headlessui-vue/src/test-utils/html.ts
function jsx (line 1) | function jsx(templates: TemplateStringsArray) {
function html (line 5) | function html(templates: TemplateStringsArray) {
FILE: packages/@headlessui-vue/src/test-utils/interactions.test.ts
type Events (line 5) | type Events = 'onKeydown' | 'onKeyup' | 'onKeypress' | 'onClick' | 'onBl...
function renderTemplate (line 8) | function renderTemplate(input: string | ComponentOptionsWithoutProps) {
type Args (line 24) | type Args = [
function key (line 30) | function key(input: string | Partial<KeyboardEvent>): Partial<KeyboardEv...
function event (line 35) | function event(
function createProps (line 165) | function createProps(id: string) {
method setup (line 189) | setup(_props, { slots, attrs }) {
FILE: packages/@headlessui-vue/src/test-utils/interactions.ts
function nextFrame (line 4) | function nextFrame(cb: Function): void {
function shift (line 32) | function shift(event: Partial<KeyboardEvent>) {
function word (line 36) | function word(input: string): Partial<KeyboardEvent>[] {
function type (line 171) | async function type(events: Partial<KeyboardEvent>[], element = document...
function press (line 216) | async function press(event: Partial<KeyboardEvent>, element = document.a...
type MouseButton (line 220) | enum MouseButton {
function click (line 225) | async function click(
function focus (line 280) | async function focus(element: Document | Element | Window | Node | null) {
function blur (line 297) | async function blur(element: Document | Element | Window | Node | null) {
function mouseEnter (line 314) | async function mouseEnter(element: Document | Element | Window | null) {
function mouseMove (line 331) | async function mouseMove(element: Document | Element | Window | null) {
function mouseLeave (line 350) | async function mouseLeave(element: Document | Element | Window | null) {
function mouseDrag (line 371) | async function mouseDrag(
function focusNext (line 441) | function focusNext(event: Partial<KeyboardEvent>) {
function getFocusableElements (line 485) | function getFocusableElements(container = document.body) {
FILE: packages/@headlessui-vue/src/test-utils/report-dom-node-changes.ts
function reportChanges (line 3) | function reportChanges<TType>(key: () => TType, onChange: (value: TType)...
FILE: packages/@headlessui-vue/src/test-utils/ssr.ts
function renderSSR (line 5) | async function renderSSR(component: any, rootProps: any = {}) {
function renderHydrate (line 30) | async function renderHydrate(component: any, rootProps: any = {}) {
FILE: packages/@headlessui-vue/src/test-utils/suppress-console-logs.ts
type FunctionPropertyNames (line 1) | type FunctionPropertyNames<T> = {
function suppressConsoleLogs (line 6) | function suppressConsoleLogs<T extends unknown[]>(
FILE: packages/@headlessui-vue/src/test-utils/vue-testing-library.ts
function resolveContainer (line 7) | function resolveContainer(): HTMLElement {
type AnyComponent (line 19) | type AnyComponent = ReturnType<typeof defineComponent>
function createRenderTemplate (line 21) | function createRenderTemplate(defaultComponents: Record<string, AnyCompo...
function render (line 35) | function render(TestComponent: any, options?: Parameters<typeof mount>[1...
function cleanup (line 61) | function cleanup() {
function cleanupAtWrapper (line 66) | function cleanupAtWrapper(wrapper: any) {
FILE: packages/@headlessui-vue/src/utils/active-element-history.ts
function handle (line 6) | function handle(e: Event) {
FILE: packages/@headlessui-vue/src/utils/calculate-active-index.ts
function assertNever (line 1) | function assertNever(x: never): never {
type Focus (line 5) | enum Focus {
function calculateActiveIndex (line 25) | function calculateActiveIndex<TItem>(
FILE: packages/@headlessui-vue/src/utils/disposables.ts
type Disposables (line 3) | type Disposables = ReturnType<typeof disposables>
function disposables (line 5) | function disposables() {
FILE: packages/@headlessui-vue/src/utils/document-ready.ts
function onDocumentReady (line 1) | function onDocumentReady(cb: () => void) {
FILE: packages/@headlessui-vue/src/utils/dom.ts
type AsElement (line 3) | type AsElement<T extends HTMLElement | ComponentPublicInstance> =
function dom (line 7) | function dom<T extends HTMLElement | ComponentPublicInstance>(
function isNode (line 33) | function isNode(element: unknown): element is Node {
function isElement (line 39) | function isElement(element: unknown): element is Element {
function isHTMLElement (line 43) | function isHTMLElement(element: unknown): element is HTMLElement {
function isHTMLorSVGElement (line 52) | function isHTMLorSVGElement(element: unknown): element is HTMLOrSVGEleme...
function isHTMLIframeElement (line 56) | function isHTMLIframeElement(element: unknown): element is HTMLIFrameEle...
FILE: packages/@headlessui-vue/src/utils/env.ts
type RenderEnv (line 1) | type RenderEnv = 'client' | 'server'
class Env (line 3) | class Env {
method set (line 7) | set(env: RenderEnv): void {
method reset (line 14) | reset(): void {
method nextId (line 18) | nextId() {
method isServer (line 22) | get isServer(): boolean {
method isClient (line 26) | get isClient(): boolean {
method detect (line 30) | private detect(): RenderEnv {
FILE: packages/@headlessui-vue/src/utils/focus-management.ts
type Focus (line 31) | enum Focus {
type FocusResult (line 51) | enum FocusResult {
type Direction (line 58) | enum Direction {
function getFocusableElements (line 63) | function getFocusableElements(container: HTMLElement | null = document.b...
type FocusableMode (line 72) | enum FocusableMode {
function isFocusableElement (line 80) | function isFocusableElement(
function restoreFocusIfNecessary (line 103) | function restoreFocusIfNecessary(element: HTMLElement | null) {
type ActivationMethod (line 117) | enum ActivationMethod {
function focusElement (line 156) | function focusElement(element: HTMLElement | null) {
function isSelectableElement (line 162) | function isSelectableElement(
function sortByDomNode (line 168) | function sortByDomNode<T>(
function focusFrom (line 186) | function focusFrom(current: HTMLElement | null, focus: Focus) {
function focusIn (line 190) | function focusIn(
FILE: packages/@headlessui-vue/src/utils/form.ts
type Entries (line 1) | type Entries = [string, string][]
function objectToFormEntries (line 3) | function objectToFormEntries(
function composeKey (line 15) | function composeKey(parent: string | null, key: string): string {
function append (line 19) | function append(entries: Entries, key: string, value: any): void {
function attemptSubmit (line 39) | function attemptSubmit(elementInForm: HTMLElement) {
FILE: packages/@headlessui-vue/src/utils/get-text-value.ts
function getTextContents (line 4) | function getTextContents(element: HTMLElement): string {
function getTextValue (line 48) | function getTextValue(element: HTMLElement): string {
FILE: packages/@headlessui-vue/src/utils/match.ts
function match (line 1) | function match<TValue extends string | number = string, TReturnValue = u...
FILE: packages/@headlessui-vue/src/utils/micro-task.ts
function microTask (line 2) | function microTask(cb: () => void) {
FILE: packages/@headlessui-vue/src/utils/once.ts
function once (line 1) | function once<T>(cb: (...args: T[]) => void) {
FILE: packages/@headlessui-vue/src/utils/owner.ts
function getOwnerDocument (line 5) | function getOwnerDocument<T extends Element | Ref<Element | null>>(
FILE: packages/@headlessui-vue/src/utils/pipeline.ts
type Middleware (line 1) | interface Middleware<ReqType> {
function pipeline (line 5) | function pipeline<ReqType>(handlers: Middleware<ReqType>[]) {
FILE: packages/@headlessui-vue/src/utils/platform.ts
function isIOS (line 4) | function isIOS() {
function isAndroid (line 19) | function isAndroid() {
function isMobile (line 23) | function isMobile() {
FILE: packages/@headlessui-vue/src/utils/render.test.ts
method setup (line 11) | setup(props, { attrs, slots }) {
method errorCaptured (line 35) | errorCaptured(err) {
method PassThrough (line 71) | PassThrough(props, context) {
FILE: packages/@headlessui-vue/src/utils/render.ts
type Features (line 4) | enum Features {
type RenderStrategy (line 24) | enum RenderStrategy {
function render (line 29) | function render({
function _render (line 77) | function _render({
function flattenFragments (line 187) | function flattenFragments(children: VNode[]): VNode[] {
function mergeProps (line 197) | function mergeProps(...listOfProps: Record<any, any>[]) {
function compact (line 253) | function compact<T extends Record<any, any>>(object: T) {
function omit (line 261) | function omit<T extends Record<any, any>, Keys extends keyof T>(
function isValidElement (line 272) | function isValidElement(input: any): boolean {
FILE: packages/@headlessui-vue/src/utils/resolve-prop-value.ts
function resolvePropValue (line 1) | function resolvePropValue<TProperty, TBag>(property: TProperty, bag: TBa...
FILE: packages/@headlessui-vue/src/utils/store.ts
type ChangeFn (line 1) | type ChangeFn = () => void
type UnsubscribeFn (line 2) | type UnsubscribeFn = () => void
type ActionFn (line 3) | type ActionFn<T> = (this: T, ...args: any[]) => T | void
type StoreActions (line 4) | type StoreActions<Key extends string, T> = Record<Key, ActionFn<T>>
type Store (line 6) | interface Store<T, ActionKey extends string> {
function createStore (line 12) | function createStore<T, ActionKey extends string>(
FILE: packages/@headlessui-vue/types/jest.d.ts
type Matchers (line 5) | interface Matchers<R> {
FILE: playgrounds/react/components/button.tsx
function classNames (line 3) | function classNames(...classes: (string | false | undefined | null)[]) {
FILE: playgrounds/react/components/input.tsx
function classNames (line 3) | function classNames(...classes: (string | false | undefined | null)[]) {
FILE: playgrounds/react/pages/_app.tsx
function disposables (line 7) | function disposables() {
function useDisposables (line 41) | function useDisposables() {
type KeyDisplayMac (line 48) | enum KeyDisplayMac {
type KeyDisplayWindows (line 70) | enum KeyDisplayWindows {
function tap (line 85) | function tap<T>(value: T, cb: (value: T) => void) {
function useKeyDisplay (line 90) | function useKeyDisplay() {
function KeyCaster (line 102) | function KeyCaster() {
function MyApp (line 131) | function MyApp({ Component, pageProps }) {
function Logo (line 157) | function Logo({ className }) {
FILE: playgrounds/react/pages/_document.tsx
function Document (line 3) | function Document() {
FILE: playgrounds/react/pages/_error.tsx
function getStaticProps (line 7) | async function getStaticProps() {
function Page (line 15) | function Page(props: { examples: false | ExamplesType[] }) {
function Examples (line 36) | function Examples(props: { examples: ExamplesType[] }) {
FILE: playgrounds/react/pages/combinations/form.tsx
function Section (line 6) | function Section({ title, children }) {
function App (line 23) | function App() {
FILE: playgrounds/react/pages/combinations/tabs-in-dialog.tsx
function App (line 5) | function App() {
FILE: playgrounds/react/pages/combobox/combobox-countries.tsx
function useDebounce (line 8) | function useDebounce<T>(value: T, delay: number) {
function Home (line 16) | function Home() {
FILE: playgrounds/react/pages/combobox/combobox-open-on-focus.tsx
function useDebounce (line 21) | function useDebounce<T>(value: T, delay: number) {
function Home (line 29) | function Home() {
FILE: playgrounds/react/pages/combobox/combobox-virtual-with-empty-states.tsx
type Option (line 8) | type Option = {
function Home (line 14) | function Home() {
FILE: playgrounds/react/pages/combobox/combobox-virtualized.tsx
function Home (line 9) | function Home() {
function Example (line 52) | function Example({ virtual = true, data, initial }: { virtual?: boolean;...
FILE: playgrounds/react/pages/combobox/combobox-with-pure-tailwind.tsx
function useDebounce (line 20) | function useDebounce<T>(value: T, delay: number) {
function Home (line 28) | function Home() {
FILE: playgrounds/react/pages/combobox/command-palette-with-groups.tsx
function Home (line 21) | function Home() {
FILE: playgrounds/react/pages/combobox/command-palette.tsx
function Home (line 21) | function Home() {
FILE: playgrounds/react/pages/combobox/multi-select.tsx
function classNames (line 4) | function classNames(...classes) {
function Home (line 21) | function Home() {
function MultiPeopleList (line 29) | function MultiPeopleList() {
FILE: playgrounds/react/pages/dialog/dialog-built-in-transition.tsx
function Home (line 6) | function Home() {
FILE: playgrounds/react/pages/dialog/dialog-focus-issue.tsx
function Modal (line 5) | function Modal(props) {
function DialogFocusIssue (line 21) | function DialogFocusIssue() {
FILE: playgrounds/react/pages/dialog/dialog-scroll-issue.tsx
function MyDialog (line 4) | function MyDialog({ open, close }) {
function App (line 47) | function App() {
FILE: playgrounds/react/pages/dialog/dialog-with-shadow-children.tsx
class MyCustomElement (line 6) | class MyCustomElement extends HTMLElement {
method constructor (line 9) | constructor() {
method connectedCallback (line 14) | connectedCallback() {
function ShadowChildren (line 24) | function ShadowChildren({ id }: { id: string }) {
function App (line 47) | function App() {
FILE: playgrounds/react/pages/dialog/dialog.tsx
function resolveClass (line 10) | function resolveClass({ active, disabled }) {
function Nested (line 18) | function Nested({ onClose, level = 0 }) {
function Home (line 44) | function Home() {
FILE: playgrounds/react/pages/dialog/scrollable-dialog.tsx
function Example (line 5) | function Example() {
FILE: playgrounds/react/pages/dialog/scrollable-page-with-dialog.tsx
function Home (line 4) | function Home() {
FILE: playgrounds/react/pages/dialog/sibling-dialogs.tsx
function App (line 14) | function App() {
function MyDialog (line 103) | function MyDialog({ level = 0, open, onClose, children }: any) {
FILE: playgrounds/react/pages/disclosure/disclosure.tsx
function Home (line 3) | function Home() {
FILE: playgrounds/react/pages/listbox/listbox-overlaps.tsx
function Home (line 17) | function Home() {
FILE: playgrounds/react/pages/listbox/listbox-with-pure-tailwind.tsx
function Home (line 17) | function Home() {
FILE: playgrounds/react/pages/listbox/multi-select.tsx
function classNames (line 4) | function classNames(...classes) {
function Home (line 21) | function Home() {
function MultiPeopleList (line 29) | function MultiPeopleList() {
FILE: playgrounds/react/pages/listbox/multiple-elements.tsx
function Home (line 18) | function Home() {
function PeopleList (line 40) | function PeopleList() {
FILE: playgrounds/react/pages/menu/menu-with-floating-ui.tsx
function Home (line 9) | function Home() {
function Portal (line 86) | function Portal(props: { children: ReactNode }) {
FILE: playgrounds/react/pages/menu/menu-with-framer-motion.tsx
function Home (line 9) | function Home() {
FILE: playgrounds/react/pages/menu/menu-with-popper.tsx
function Home (line 9) | function Home() {
function Portal (line 85) | function Portal(props: { children: ReactNode }) {
FILE: playgrounds/react/pages/menu/menu-with-transition-and-popper.tsx
function Home (line 7) | function Home() {
FILE: playgrounds/react/pages/menu/menu-with-transition.tsx
function Home (line 5) | function Home() {
FILE: playgrounds/react/pages/menu/menu.tsx
function Home (line 6) | function Home() {
function ExampleMenu (line 14) | function ExampleMenu() {
function CustomMenuItem (line 61) | function CustomMenuItem(props) {
FILE: playgrounds/react/pages/menu/multiple-elements.tsx
function Home (line 5) | function Home() {
function Dropdown (line 24) | function Dropdown() {
FILE: playgrounds/react/pages/popover/popover.tsx
function Home (line 17) | function Home() {
FILE: playgrounds/react/pages/radio-group/radio-group.tsx
function Home (line 5) | function Home() {
FILE: playgrounds/react/pages/suspense/portal.tsx
function MyComponent (line 6) | function MyComponent({ children }: { children(message: string): React.JS...
function Index (line 16) | function Index() {
FILE: playgrounds/react/pages/switch/switch-with-pure-tailwind.tsx
function Home (line 6) | function Home() {
FILE: playgrounds/react/pages/tabs/tabs-with-pure-tailwind.tsx
function Home (line 6) | function Home() {
FILE: playgrounds/react/pages/transitions/appear.tsx
function AppearExample (line 5) | function AppearExample() {
FILE: playgrounds/react/pages/transitions/both-apis.tsx
function Example (line 5) | function Example() {
function Before (line 20) | function Before({ open }: { open: boolean }) {
function After (line 36) | function After({ open }: { open: boolean }) {
FILE: playgrounds/react/pages/transitions/component-examples/dropdown.tsx
function Home (line 5) | function Home() {
function Dropdown (line 19) | function Dropdown() {
FILE: playgrounds/react/pages/transitions/component-examples/modal.tsx
function Home (line 4) | function Home() {
FILE: playgrounds/react/pages/transitions/component-examples/nested/hidden.tsx
function Home (line 4) | function Home() {
function Box (line 43) | function Box({ children }: { children?: ReactNode }) {
FILE: playgrounds/react/pages/transitions/component-examples/nested/unmount.tsx
function Home (line 4) | function Home() {
function Box (line 43) | function Box({ children }: { children?: ReactNode }) {
FILE: playgrounds/react/pages/transitions/component-examples/peek-a-boo.tsx
function Home (line 4) | function Home() {
FILE: playgrounds/react/pages/transitions/full-page-examples/full-page-transition.tsx
function Shell (line 8) | function Shell() {
function usePrevious (line 23) | function usePrevious<T>(value: T) {
type Direction (line 31) | enum Direction {
function FullPageTransition (line 45) | function FullPageTransition() {
FILE: playgrounds/react/pages/transitions/full-page-examples/layout-with-sidebar.tsx
function App (line 5) | function App() {
FILE: playgrounds/react/pages/transitions/react-hot-toast.tsx
function App (line 28) | function App() {
FILE: playgrounds/react/utils/class-names.ts
function classNames (line 1) | function classNames(...classes: (false | null | undefined | string)[]): ...
FILE: playgrounds/react/utils/hooks/use-popper.ts
function usePopper (line 7) | function usePopper(
FILE: playgrounds/react/utils/match.ts
function match (line 1) | function match<TValue extends string | number = string, TReturnValue = u...
FILE: playgrounds/react/utils/resolve-all-examples.ts
type ExamplesType (line 3) | type ExamplesType = {
function resolveAllExamples (line 9) | async function resolveAllExamples(...paths: string[]) {
FILE: playgrounds/vue/src/playground-utils/hooks/use-popper.js
function usePopper (line 4) | function usePopper(options) {
FILE: playgrounds/vue/src/router.ts
type Component (line 3) | type Component = import('vue').Component
function buildRoutes (line 5) | function buildRoutes() {
FILE: scripts/make-nextjs-happy.js
function run (line 15) | async function run() {
function template (line 40) | async function template(name, module) {
Condensed preview — 472 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,564K chars).
[
{
"path": ".eslintignore",
"chars": 63,
"preview": "/dist\n/packages/**/dist\n/node_modules\n/packages/**/node_modules"
},
{
"path": ".github/CONTRIBUTING.md",
"chars": 5187,
"preview": "# Contributing\n\nThanks for your interest in contributing to Headless UI! Please take a moment to review this document **"
},
{
"path": ".github/FUNDING.yml",
"chars": 44,
"preview": "custom: ['https://tailwindcss.com/sponsor']\n"
},
{
"path": ".github/ISSUE_TEMPLATE/bug-report.md",
"chars": 1522,
"preview": "---\nname: Bug report\nabout: If you've already asked for help with a problem and confirmed something is broken with Headl"
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 632,
"preview": "blank_issues_enabled: false\ncontact_links:\n - name: Get Help\n url: https://github.com/tailwindlabs/headlessui/discus"
},
{
"path": ".github/workflows/main.yml",
"chars": 2367,
"preview": "name: CI\n\non:\n push:\n branches: [main]\n pull_request:\n\nconcurrency:\n group: ${{ github.workflow }}-${{ github.head"
},
{
"path": ".github/workflows/prepare-release.yml",
"chars": 1189,
"preview": "name: Prepare Release\n\non:\n workflow_dispatch:\n push:\n tags:\n - '**'\n\nenv:\n CI: true\n\npermissions:\n contents"
},
{
"path": ".github/workflows/release-insiders.yml",
"chars": 1708,
"preview": "name: Release Insiders\n\non:\n push:\n branches: [main]\n\nconcurrency:\n group: ${{ github.workflow }}-${{ github.head_r"
},
{
"path": ".github/workflows/release.yml",
"chars": 1709,
"preview": "name: Release\n\non:\n release:\n types: [published]\n\nconcurrency:\n group: ${{ github.workflow }}-${{ github.head_ref |"
},
{
"path": ".gitignore",
"chars": 636,
"preview": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/pac"
},
{
"path": ".prettierignore",
"chars": 37,
"preview": "dist/\nnode_modules/\ncoverage/\n.next/\n"
},
{
"path": ".swcrc",
"chars": 165,
"preview": "{\n \"minify\": false,\n \"jsc\": {\n \"parser\": {\n \"syntax\": \"typescript\",\n \"tsx\": true,\n \"decorators\": fal"
},
{
"path": "CHANGELOG.md",
"chars": 406,
"preview": "# Changelog\n\nEach package has its own changelog.\n\n- [@headlessui/react](https://github.com/tailwindlabs/headlessui/blob/"
},
{
"path": "LICENSE",
"chars": 1069,
"preview": "MIT License\n\nCopyright (c) 2020 Tailwind Labs\n\nPermission is hereby granted, free of charge, to any person obtaining a c"
},
{
"path": "README.md",
"chars": 3162,
"preview": "<h3 align=\"center\">\n Headless UI\n</h3>\n\n<p align=\"center\">\n A set of completely unstyled, fully accessible UI componen"
},
{
"path": "jest/create-jest-config.cjs",
"chars": 503,
"preview": "module.exports = function createJestConfig(root, options) {\n let { setupFilesAfterEnv = [], transform = {}, ...rest } ="
},
{
"path": "jest/custom-matchers.ts",
"chars": 839,
"preview": "import '@testing-library/jest-dom/extend-expect'\n\n// Assuming requestAnimationFrame is roughly 60 frames per second\nlet "
},
{
"path": "jest/polyfills.ts",
"chars": 1756,
"preview": "import { mockAnimationsApi, mockResizeObserver } from 'jsdom-testing-mocks'\n\nmockAnimationsApi() // `Element.prototype.g"
},
{
"path": "jest.config.cjs",
"chars": 75,
"preview": "module.exports = {\n projects: ['<rootDir>/packages/*/jest.config.cjs'],\n}\n"
},
{
"path": "package.json",
"chars": 2532,
"preview": "{\n \"name\": \"headlessui\",\n \"version\": \"0.0.0\",\n \"description\": \"Headless UI components for various libraries like Reac"
},
{
"path": "packages/@headlessui-react/CHANGELOG.md",
"chars": 69816,
"preview": "# Changelog\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Change"
},
{
"path": "packages/@headlessui-react/LICENSE",
"chars": 1069,
"preview": "MIT License\n\nCopyright (c) 2020 Tailwind Labs\n\nPermission is hereby granted, free of charge, to any person obtaining a c"
},
{
"path": "packages/@headlessui-react/README.md",
"chars": 1006,
"preview": "<h3 align=\"center\">\n @headlessui/react\n</h3>\n\n<p align=\"center\">\n A set of completely unstyled, fully accessible UI co"
},
{
"path": "packages/@headlessui-react/build/index.cjs",
"chars": 173,
"preview": "'use strict'\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./headlessui.prod.cjs')\n} else {\n"
},
{
"path": "packages/@headlessui-react/jest.config.cjs",
"chars": 165,
"preview": "let create = require('../../jest/create-jest-config.cjs')\nmodule.exports = create(__dirname, {\n displayName: 'React',\n "
},
{
"path": "packages/@headlessui-react/jest.setup.js",
"chars": 43,
"preview": "globalThis.IS_REACT_ACT_ENVIRONMENT = true\n"
},
{
"path": "packages/@headlessui-react/package.json",
"chars": 1996,
"preview": "{\n \"name\": \"@headlessui/react\",\n \"version\": \"2.2.9\",\n \"description\": \"A set of completely unstyled, fully accessible "
},
{
"path": "packages/@headlessui-react/src/components/button/button.test.tsx",
"chars": 1391,
"preview": "import { render, screen } from '@testing-library/react'\nimport React, { Fragment } from 'react'\nimport { Button } from '"
},
{
"path": "packages/@headlessui-react/src/components/button/button.tsx",
"chars": 2153,
"preview": "'use client'\n\nimport { useFocusRing } from '@react-aria/focus'\nimport { useHover } from '@react-aria/interactions'\nimpor"
},
{
"path": "packages/@headlessui-react/src/components/checkbox/checkbox.test.tsx",
"chars": 4171,
"preview": "import { render } from '@testing-library/react'\nimport React, { useState } from 'react'\nimport {\n CheckboxState,\n asse"
},
{
"path": "packages/@headlessui-react/src/components/checkbox/checkbox.tsx",
"chars": 5684,
"preview": "'use client'\n\nimport { useFocusRing } from '@react-aria/focus'\nimport { useHover } from '@react-aria/interactions'\nimpor"
},
{
"path": "packages/@headlessui-react/src/components/close-button/close-button.tsx",
"chars": 759,
"preview": "'use client'\n\nimport React, { type ElementType, type Ref } from 'react'\nimport { useClose } from '../../internal/close-p"
},
{
"path": "packages/@headlessui-react/src/components/combobox/combobox-machine-glue.tsx",
"chars": 895,
"preview": "import { createContext, useContext, useMemo } from 'react'\nimport { useOnUnmount } from '../../hooks/use-on-unmount'\nimp"
},
{
"path": "packages/@headlessui-react/src/components/combobox/combobox-machine.ts",
"chars": 21278,
"preview": "import { Machine } from '../../machine'\nimport { ActionTypes as StackActionTypes, stackMachines } from '../../machines/s"
},
{
"path": "packages/@headlessui-react/src/components/combobox/combobox.test.tsx",
"chars": 195806,
"preview": "import { render, waitFor } from '@testing-library/react'\nimport React, { Fragment, createElement, useEffect, useState } "
},
{
"path": "packages/@headlessui-react/src/components/combobox/combobox.tsx",
"chars": 55001,
"preview": "'use client'\n\nimport { useFocusRing } from '@react-aria/focus'\nimport { useHover } from '@react-aria/interactions'\nimpor"
},
{
"path": "packages/@headlessui-react/src/components/combobox-button/combobox-button.tsx",
"chars": 149,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../combobox/combobox'\nexport { ComboboxButton }"
},
{
"path": "packages/@headlessui-react/src/components/combobox-input/combobox-input.tsx",
"chars": 148,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../combobox/combobox'\nexport { ComboboxInput } "
},
{
"path": "packages/@headlessui-react/src/components/combobox-label/combobox-label.tsx",
"chars": 148,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../combobox/combobox'\nexport { ComboboxLabel } "
},
{
"path": "packages/@headlessui-react/src/components/combobox-option/combobox-option.tsx",
"chars": 149,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../combobox/combobox'\nexport { ComboboxOption }"
},
{
"path": "packages/@headlessui-react/src/components/combobox-options/combobox-options.tsx",
"chars": 150,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../combobox/combobox'\nexport { ComboboxOptions "
},
{
"path": "packages/@headlessui-react/src/components/data-interactive/data-interactive.test.tsx",
"chars": 1269,
"preview": "import { render, screen } from '@testing-library/react'\nimport React from 'react'\nimport { focus, mouseEnter } from '../"
},
{
"path": "packages/@headlessui-react/src/components/data-interactive/data-interactive.tsx",
"chars": 2061,
"preview": "'use client'\n\nimport { useFocusRing } from '@react-aria/focus'\nimport { useHover } from '@react-aria/interactions'\nimpor"
},
{
"path": "packages/@headlessui-react/src/components/description/__snapshots__/description.test.tsx.snap",
"chars": 933,
"preview": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`should be possible to use a DescriptionProvider and a single Descri"
},
{
"path": "packages/@headlessui-react/src/components/description/description.test.tsx",
"chars": 2083,
"preview": "import { render } from '@testing-library/react'\nimport React, { type ReactNode } from 'react'\nimport { Description, useD"
},
{
"path": "packages/@headlessui-react/src/components/description/description.tsx",
"chars": 4087,
"preview": "'use client'\n\nimport React, {\n createContext,\n useContext,\n useMemo,\n useState,\n type ElementType,\n type ReactNode"
},
{
"path": "packages/@headlessui-react/src/components/dialog/dialog.test.tsx",
"chars": 51079,
"preview": "import { render } from '@testing-library/react'\nimport React, { Fragment, createElement, useCallback, useEffect, useRef,"
},
{
"path": "packages/@headlessui-react/src/components/dialog/dialog.tsx",
"chars": 18710,
"preview": "'use client'\n\n// WAI-ARIA: https://www.w3.org/WAI/ARIA/apg/patterns/dialogmodal/\nimport React, {\n Fragment,\n createCon"
},
{
"path": "packages/@headlessui-react/src/components/dialog-description/dialog-description.tsx",
"chars": 144,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../dialog/dialog'\nexport { DialogDescription } "
},
{
"path": "packages/@headlessui-react/src/components/dialog-panel/dialog-panel.tsx",
"chars": 138,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../dialog/dialog'\nexport { DialogPanel } from '"
},
{
"path": "packages/@headlessui-react/src/components/dialog-title/dialog-title.tsx",
"chars": 138,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../dialog/dialog'\nexport { DialogTitle } from '"
},
{
"path": "packages/@headlessui-react/src/components/disclosure/disclosure.test.tsx",
"chars": 31675,
"preview": "import { render, waitFor } from '@testing-library/react'\nimport React, { Fragment, Suspense, createElement, useEffect, u"
},
{
"path": "packages/@headlessui-react/src/components/disclosure/disclosure.tsx",
"chars": 16059,
"preview": "'use client'\n\n// WAI-ARIA: https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/\nimport { useFocusRing } from '@react-ari"
},
{
"path": "packages/@headlessui-react/src/components/disclosure-button/disclosure-button.tsx",
"chars": 159,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../disclosure/disclosure'\nexport { DisclosureBu"
},
{
"path": "packages/@headlessui-react/src/components/disclosure-panel/disclosure-panel.tsx",
"chars": 158,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../disclosure/disclosure'\nexport { DisclosurePa"
},
{
"path": "packages/@headlessui-react/src/components/field/field.test.tsx",
"chars": 1594,
"preview": "import { render } from '@testing-library/react'\nimport React from 'react'\nimport { Fieldset } from '../fieldset/fieldset"
},
{
"path": "packages/@headlessui-react/src/components/field/field.tsx",
"chars": 2539,
"preview": "'use client'\n\nimport React, { type ElementType, type Ref } from 'react'\nimport { useId } from '../../hooks/use-id'\nimpor"
},
{
"path": "packages/@headlessui-react/src/components/fieldset/fieldset.test.tsx",
"chars": 3341,
"preview": "import { render, screen } from '@testing-library/react'\nimport React from 'react'\nimport {\n assertLinkedWithLabel,\n as"
},
{
"path": "packages/@headlessui-react/src/components/fieldset/fieldset.tsx",
"chars": 2262,
"preview": "'use client'\n\nimport React, { type ElementType, type Ref } from 'react'\nimport { useResolvedTag } from '../../hooks/use-"
},
{
"path": "packages/@headlessui-react/src/components/focus-trap/focus-trap.test.tsx",
"chars": 14801,
"preview": "import { render, screen } from '@testing-library/react'\nimport React, { useRef, useState } from 'react'\nimport { assertA"
},
{
"path": "packages/@headlessui-react/src/components/focus-trap/focus-trap.tsx",
"chars": 14837,
"preview": "'use client'\n\nimport React, {\n useRef,\n type ElementType,\n type MutableRefObject,\n type FocusEvent as ReactFocusEven"
},
{
"path": "packages/@headlessui-react/src/components/focus-trap-features/focus-trap-features.tsx",
"chars": 160,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../focus-trap/focus-trap'\nexport { FocusTrapFea"
},
{
"path": "packages/@headlessui-react/src/components/input/input.test.tsx",
"chars": 508,
"preview": "import { getInput } from '../../test-utils/accessibility-assertions'\nimport { focus, type, word } from '../../test-utils"
},
{
"path": "packages/@headlessui-react/src/components/input/input.tsx",
"chars": 2520,
"preview": "'use client'\n\nimport { useFocusRing } from '@react-aria/focus'\nimport { useHover } from '@react-aria/interactions'\nimpor"
},
{
"path": "packages/@headlessui-react/src/components/keyboard.ts",
"chars": 451,
"preview": "// TODO: This must already exist somewhere, right? 🤔\n// Ref: https://www.w3.org/TR/uievents-key/#named-key-attribute-val"
},
{
"path": "packages/@headlessui-react/src/components/label/__snapshots__/label.test.tsx.snap",
"chars": 847,
"preview": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`should be possible to use a LabelProvider and a single Label, and h"
},
{
"path": "packages/@headlessui-react/src/components/label/label.test.tsx",
"chars": 1888,
"preview": "import { render } from '@testing-library/react'\nimport React, { type ReactNode } from 'react'\nimport { Label, useLabels "
},
{
"path": "packages/@headlessui-react/src/components/label/label.tsx",
"chars": 7237,
"preview": "'use client'\n\nimport React, {\n createContext,\n useContext,\n useMemo,\n useState,\n type ElementType,\n type MouseEven"
},
{
"path": "packages/@headlessui-react/src/components/legend/legend.tsx",
"chars": 1169,
"preview": "'use client'\n\nimport React, { type ElementType, type Ref } from 'react'\nimport type { Props } from '../../types'\nimport "
},
{
"path": "packages/@headlessui-react/src/components/listbox/listbox-machine-glue.tsx",
"chars": 855,
"preview": "import { createContext, useContext, useMemo } from 'react'\nimport { useOnUnmount } from '../../hooks/use-on-unmount'\nimp"
},
{
"path": "packages/@headlessui-react/src/components/listbox/listbox-machine.ts",
"chars": 20177,
"preview": "import { Machine, batch } from '../../machine'\nimport { ActionTypes as StackActionTypes, stackMachines } from '../../mac"
},
{
"path": "packages/@headlessui-react/src/components/listbox/listbox.test.tsx",
"chars": 152646,
"preview": "import { act, render, waitFor } from '@testing-library/react'\nimport React, { Fragment, createElement, createRef, useEff"
},
{
"path": "packages/@headlessui-react/src/components/listbox/listbox.tsx",
"chars": 33434,
"preview": "'use client'\n\nimport { useFocusRing } from '@react-aria/focus'\nimport { useHover } from '@react-aria/interactions'\nimpor"
},
{
"path": "packages/@headlessui-react/src/components/listbox-button/listbox-button.tsx",
"chars": 144,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../listbox/listbox'\nexport { ListboxButton } fr"
},
{
"path": "packages/@headlessui-react/src/components/listbox-label/listbox-label.tsx",
"chars": 143,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../listbox/listbox'\nexport { ListboxLabel } fro"
},
{
"path": "packages/@headlessui-react/src/components/listbox-option/listbox-option.tsx",
"chars": 144,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../listbox/listbox'\nexport { ListboxOption } fr"
},
{
"path": "packages/@headlessui-react/src/components/listbox-options/listbox-options.tsx",
"chars": 145,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../listbox/listbox'\nexport { ListboxOptions } f"
},
{
"path": "packages/@headlessui-react/src/components/listbox-selected-option/listbox-selected-option.tsx",
"chars": 152,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../listbox/listbox'\nexport { ListboxSelectedOpt"
},
{
"path": "packages/@headlessui-react/src/components/menu/menu-machine-glue.tsx",
"chars": 784,
"preview": "import { createContext, useContext, useMemo } from 'react'\nimport { useOnUnmount } from '../../hooks/use-on-unmount'\nimp"
},
{
"path": "packages/@headlessui-react/src/components/menu/menu-machine.ts",
"chars": 14593,
"preview": "import { Machine, batch } from '../../machine'\nimport { ActionTypes as StackActionTypes, stackMachines } from '../../mac"
},
{
"path": "packages/@headlessui-react/src/components/menu/menu.test.tsx",
"chars": 101060,
"preview": "import { act, render, waitFor } from '@testing-library/react'\nimport React, { Fragment, createElement, createRef, useEff"
},
{
"path": "packages/@headlessui-react/src/components/menu/menu.tsx",
"chars": 27707,
"preview": "'use client'\n\n// WAI-ARIA: https://www.w3.org/WAI/ARIA/apg/patterns/menubutton/\nimport { useFocusRing } from '@react-ari"
},
{
"path": "packages/@headlessui-react/src/components/menu-button/menu-button.tsx",
"chars": 129,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../menu/menu'\nexport { MenuButton } from '../me"
},
{
"path": "packages/@headlessui-react/src/components/menu-heading/menu-heading.tsx",
"chars": 130,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../menu/menu'\nexport { MenuHeading } from '../m"
},
{
"path": "packages/@headlessui-react/src/components/menu-item/menu-item.tsx",
"chars": 127,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../menu/menu'\nexport { MenuItem } from '../menu"
},
{
"path": "packages/@headlessui-react/src/components/menu-items/menu-items.tsx",
"chars": 128,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../menu/menu'\nexport { MenuItems } from '../men"
},
{
"path": "packages/@headlessui-react/src/components/menu-section/menu-section.tsx",
"chars": 130,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../menu/menu'\nexport { MenuSection } from '../m"
},
{
"path": "packages/@headlessui-react/src/components/menu-separator/menu-separator.tsx",
"chars": 132,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../menu/menu'\nexport { MenuSeparator } from '.."
},
{
"path": "packages/@headlessui-react/src/components/mouse.ts",
"chars": 53,
"preview": "export enum MouseButton {\n Left = 0,\n Right = 2,\n}\n"
},
{
"path": "packages/@headlessui-react/src/components/popover/popover-machine-glue.tsx",
"chars": 829,
"preview": "import { createContext, useContext, useMemo } from 'react'\nimport { useOnUnmount } from '../../hooks/use-on-unmount'\nimp"
},
{
"path": "packages/@headlessui-react/src/components/popover/popover-machine.ts",
"chars": 6182,
"preview": "import { type MouseEventHandler } from 'react'\nimport { Machine } from '../../machine'\nimport { stackMachines } from '.."
},
{
"path": "packages/@headlessui-react/src/components/popover/popover.test.tsx",
"chars": 84312,
"preview": "import { render, waitFor } from '@testing-library/react'\nimport React, { Fragment, act, createElement, useEffect, useRef"
},
{
"path": "packages/@headlessui-react/src/components/popover/popover.tsx",
"chars": 34907,
"preview": "'use client'\n\nimport { useFocusRing } from '@react-aria/focus'\nimport { useHover } from '@react-aria/interactions'\nimpor"
},
{
"path": "packages/@headlessui-react/src/components/popover-backdrop/popover-backdrop.tsx",
"chars": 146,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../popover/popover'\nexport { PopoverBackdrop } "
},
{
"path": "packages/@headlessui-react/src/components/popover-button/popover-button.tsx",
"chars": 144,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../popover/popover'\nexport { PopoverButton } fr"
},
{
"path": "packages/@headlessui-react/src/components/popover-group/popover-group.tsx",
"chars": 143,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../popover/popover'\nexport { PopoverGroup } fro"
},
{
"path": "packages/@headlessui-react/src/components/popover-overlay/popover-overlay.tsx",
"chars": 145,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../popover/popover'\nexport { PopoverOverlay } f"
},
{
"path": "packages/@headlessui-react/src/components/popover-panel/popover-panel.tsx",
"chars": 143,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../popover/popover'\nexport { PopoverPanel } fro"
},
{
"path": "packages/@headlessui-react/src/components/portal/__snapshots__/portal.test.tsx.snap",
"chars": 411,
"preview": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`should be possible to force the Portal into a specific element usin"
},
{
"path": "packages/@headlessui-react/src/components/portal/portal.test.tsx",
"chars": 7380,
"preview": "import { render } from '@testing-library/react'\nimport React, { useRef, useState } from 'react'\nimport { click } from '."
},
{
"path": "packages/@headlessui-react/src/components/portal/portal.tsx",
"chars": 7213,
"preview": "'use client'\n\nimport React, {\n Fragment,\n createContext,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n "
},
{
"path": "packages/@headlessui-react/src/components/radio/radio.tsx",
"chars": 152,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../radio-group/radio-group'\nexport { Radio } fr"
},
{
"path": "packages/@headlessui-react/src/components/radio-group/radio-group.test.tsx",
"chars": 53249,
"preview": "import { render } from '@testing-library/react'\nimport React, { createElement, useState } from 'react'\nimport {\n assert"
},
{
"path": "packages/@headlessui-react/src/components/radio-group/radio-group.tsx",
"chars": 18213,
"preview": "'use client'\n\nimport { useFocusRing } from '@react-aria/focus'\nimport { useHover } from '@react-aria/interactions'\nimpor"
},
{
"path": "packages/@headlessui-react/src/components/radio-group-description/radio-group-description.tsx",
"chars": 168,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../radio-group/radio-group'\nexport { RadioGroup"
},
{
"path": "packages/@headlessui-react/src/components/radio-group-label/radio-group-label.tsx",
"chars": 162,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../radio-group/radio-group'\nexport { RadioGroup"
},
{
"path": "packages/@headlessui-react/src/components/radio-group-option/radio-group-option.tsx",
"chars": 163,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../radio-group/radio-group'\nexport { RadioGroup"
},
{
"path": "packages/@headlessui-react/src/components/select/select.test.tsx",
"chars": 722,
"preview": "import React from 'react'\nimport { getSelect } from '../../test-utils/accessibility-assertions'\nimport {\n commonControl"
},
{
"path": "packages/@headlessui-react/src/components/select/select.tsx",
"chars": 2747,
"preview": "'use client'\n\nimport { useFocusRing } from '@react-aria/focus'\nimport { useHover } from '@react-aria/interactions'\nimpor"
},
{
"path": "packages/@headlessui-react/src/components/switch/switch.test.tsx",
"chars": 23689,
"preview": "import { render } from '@testing-library/react'\nimport React, { useState } from 'react'\nimport {\n assertActiveElement,\n"
},
{
"path": "packages/@headlessui-react/src/components/switch/switch.tsx",
"chars": 8897,
"preview": "'use client'\n\nimport { useFocusRing } from '@react-aria/focus'\nimport { useHover } from '@react-aria/interactions'\nimpor"
},
{
"path": "packages/@headlessui-react/src/components/switch-description/switch-description.tsx",
"chars": 144,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../switch/switch'\nexport { SwitchDescription } "
},
{
"path": "packages/@headlessui-react/src/components/switch-group/switch-group.tsx",
"chars": 138,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../switch/switch'\nexport { SwitchGroup } from '"
},
{
"path": "packages/@headlessui-react/src/components/switch-label/switch-label.tsx",
"chars": 138,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../switch/switch'\nexport { SwitchLabel } from '"
},
{
"path": "packages/@headlessui-react/src/components/tab/tab.tsx",
"chars": 122,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../tabs/tabs'\nexport { Tab } from '../tabs/tabs"
},
{
"path": "packages/@headlessui-react/src/components/tab-group/tab-group.tsx",
"chars": 127,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../tabs/tabs'\nexport { TabGroup } from '../tabs"
},
{
"path": "packages/@headlessui-react/src/components/tab-list/tab-list.tsx",
"chars": 126,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../tabs/tabs'\nexport { TabList } from '../tabs/"
},
{
"path": "packages/@headlessui-react/src/components/tab-panel/tab-panel.tsx",
"chars": 127,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../tabs/tabs'\nexport { TabPanel } from '../tabs"
},
{
"path": "packages/@headlessui-react/src/components/tab-panels/tab-panels.tsx",
"chars": 128,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../tabs/tabs'\nexport { TabPanels } from '../tab"
},
{
"path": "packages/@headlessui-react/src/components/tabs/tabs.ssr.test.tsx",
"chars": 4362,
"preview": "import React from 'react'\nimport { renderHydrate, renderSSR } from '../../test-utils/ssr'\nimport { Tab } from './tabs'\n\n"
},
{
"path": "packages/@headlessui-react/src/components/tabs/tabs.test.tsx",
"chars": 83909,
"preview": "import { render } from '@testing-library/react'\nimport React, { createElement, useState } from 'react'\nimport {\n assert"
},
{
"path": "packages/@headlessui-react/src/components/tabs/tabs.tsx",
"chars": 20838,
"preview": "'use client'\n\nimport { useFocusRing } from '@react-aria/focus'\nimport { useHover } from '@react-aria/interactions'\nimpor"
},
{
"path": "packages/@headlessui-react/src/components/textarea/textarea.test.tsx",
"chars": 533,
"preview": "import { getTextarea } from '../../test-utils/accessibility-assertions'\nimport { focus, type, word } from '../../test-ut"
},
{
"path": "packages/@headlessui-react/src/components/textarea/textarea.tsx",
"chars": 2609,
"preview": "'use client'\n\nimport { useFocusRing } from '@react-aria/focus'\nimport { useHover } from '@react-aria/interactions'\nimpor"
},
{
"path": "packages/@headlessui-react/src/components/tooltip/tooltip.tsx",
"chars": 13556,
"preview": "'use client'\n\nimport { useFocusRing } from '@react-aria/focus'\nimport { useHover } from '@react-aria/interactions'\nimpor"
},
{
"path": "packages/@headlessui-react/src/components/transition/__snapshots__/transition.test.tsx.snap",
"chars": 3490,
"preview": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Setup API nested should be possible to change the underlying DOM ta"
},
{
"path": "packages/@headlessui-react/src/components/transition/transition.ssr.test.tsx",
"chars": 1736,
"preview": "import React, { Fragment } from 'react'\nimport { renderSSR } from '../../test-utils/ssr'\nimport { Transition } from './t"
},
{
"path": "packages/@headlessui-react/src/components/transition/transition.test.tsx",
"chars": 36694,
"preview": "import { fireEvent, render } from '@testing-library/react'\nimport React, { act, useEffect, useLayoutEffect, useRef, useS"
},
{
"path": "packages/@headlessui-react/src/components/transition/transition.tsx",
"chars": 20059,
"preview": "'use client'\n\nimport React, {\n Fragment,\n createContext,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n "
},
{
"path": "packages/@headlessui-react/src/components/transition-child/transition-child.tsx",
"chars": 158,
"preview": "// Next.js barrel file improvements (GENERATED FILE)\nexport type * from '../transition/transition'\nexport { TransitionCh"
},
{
"path": "packages/@headlessui-react/src/components/transitions/transition.tsx",
"chars": 111,
"preview": "// Backwards compatibility for the `transitions` (plural name) folder\nexport * from '../transition/transition'\n"
},
{
"path": "packages/@headlessui-react/src/hooks/__mocks__/use-id.ts",
"chars": 194,
"preview": "import { useState } from 'react'\n\nbeforeEach(() => {\n id = 0\n})\n\nlet id = 0\nfunction generateId() {\n return ++id\n}\n\nex"
},
{
"path": "packages/@headlessui-react/src/hooks/document-overflow/adjust-scrollbar-padding.ts",
"chars": 877,
"preview": "import type { ScrollLockStep } from './overflow-store'\n\nexport function adjustScrollbarPadding(): ScrollLockStep {\n let"
},
{
"path": "packages/@headlessui-react/src/hooks/document-overflow/handle-ios-locking.ts",
"chars": 7684,
"preview": "import { disposables } from '../../utils/disposables'\nimport * as DOM from '../../utils/dom'\nimport { isIOS } from '../."
},
{
"path": "packages/@headlessui-react/src/hooks/document-overflow/overflow-store.ts",
"chars": 3438,
"preview": "import { disposables, type Disposables } from '../../utils/disposables'\nimport { createStore } from '../../utils/store'\n"
},
{
"path": "packages/@headlessui-react/src/hooks/document-overflow/prevent-scroll.ts",
"chars": 212,
"preview": "import type { ScrollLockStep } from './overflow-store'\n\nexport function preventScroll(): ScrollLockStep {\n return {\n "
},
{
"path": "packages/@headlessui-react/src/hooks/document-overflow/use-document-overflow.ts",
"chars": 784,
"preview": "import { useStore } from '../../hooks/use-store'\nimport { useIsoMorphicEffect } from '../use-iso-morphic-effect'\nimport "
},
{
"path": "packages/@headlessui-react/src/hooks/use-active-press.tsx",
"chars": 2821,
"preview": "import { useRef, useState } from 'react'\nimport { getOwnerDocument } from '../utils/owner'\nimport { useDisposables } fro"
},
{
"path": "packages/@headlessui-react/src/hooks/use-by-comparator.ts",
"chars": 685,
"preview": "import { useCallback } from 'react'\n\nexport type ByComparator<T> =\n | (NonNullable<T> extends never ? string : keyof No"
},
{
"path": "packages/@headlessui-react/src/hooks/use-computed.ts",
"chars": 409,
"preview": "import { useState } from 'react'\nimport { useIsoMorphicEffect } from './use-iso-morphic-effect'\nimport { useLatestValue "
},
{
"path": "packages/@headlessui-react/src/hooks/use-controllable.ts",
"chars": 1793,
"preview": "import { useRef, useState } from 'react'\nimport { flushSync } from 'react-dom'\nimport { useEvent } from './use-event'\n\ne"
},
{
"path": "packages/@headlessui-react/src/hooks/use-default-value.ts",
"chars": 437,
"preview": "import { useState } from 'react'\n\n/**\n * Returns a stable value that never changes unless the component is re-mounted.\n "
},
{
"path": "packages/@headlessui-react/src/hooks/use-disposables.ts",
"chars": 424,
"preview": "import { useEffect, useState } from 'react'\nimport { disposables } from '../utils/disposables'\n\n/**\n * The `useDisposabl"
},
{
"path": "packages/@headlessui-react/src/hooks/use-document-event.ts",
"chars": 638,
"preview": "import { useEffect } from 'react'\nimport { useLatestValue } from './use-latest-value'\n\nexport function useDocumentEvent<"
},
{
"path": "packages/@headlessui-react/src/hooks/use-element-size.ts",
"chars": 1303,
"preview": "import { useState } from 'react'\nimport { disposables } from '../utils/disposables'\nimport { useIsoMorphicEffect } from "
},
{
"path": "packages/@headlessui-react/src/hooks/use-escape.ts",
"chars": 547,
"preview": "import { Keys } from '../components/keyboard'\nimport { useEventListener } from './use-event-listener'\nimport { useIsTopL"
},
{
"path": "packages/@headlessui-react/src/hooks/use-event-listener.ts",
"chars": 712,
"preview": "import { useEffect } from 'react'\nimport { useLatestValue } from './use-latest-value'\n\nexport function useEventListener<"
},
{
"path": "packages/@headlessui-react/src/hooks/use-event.ts",
"chars": 436,
"preview": "import React from 'react'\nimport { useLatestValue } from './use-latest-value'\n\nexport let useEvent =\n // TODO: Add Reac"
},
{
"path": "packages/@headlessui-react/src/hooks/use-flags.ts",
"chars": 624,
"preview": "import { useCallback, useState } from 'react'\n\nexport function useFlags(initialFlags = 0) {\n let [flags, setFlags] = us"
},
{
"path": "packages/@headlessui-react/src/hooks/use-handle-toggle.tsx",
"chars": 2009,
"preview": "import { useRef, type PointerEvent as ReactPointerEvent } from 'react'\nimport { MouseButton } from '../components/mouse'"
},
{
"path": "packages/@headlessui-react/src/hooks/use-id.ts",
"chars": 110,
"preview": "// Re-exporting the useId hook such that we can easily mock this hook in tests.\nexport { useId } from 'react'\n"
},
{
"path": "packages/@headlessui-react/src/hooks/use-inert-others.test.tsx",
"chars": 4991,
"preview": "import { render } from '@testing-library/react'\nimport React, { useRef, useState, type ReactNode } from 'react'\nimport {"
},
{
"path": "packages/@headlessui-react/src/hooks/use-inert-others.tsx",
"chars": 4080,
"preview": "import { disposables } from '../utils/disposables'\nimport { getOwnerDocument } from '../utils/owner'\nimport { useIsTopLa"
},
{
"path": "packages/@headlessui-react/src/hooks/use-is-initial-render.ts",
"chars": 252,
"preview": "import { useEffect, useRef } from 'react'\n\nexport function useIsInitialRender() {\n let initial = useRef(true)\n\n useEff"
},
{
"path": "packages/@headlessui-react/src/hooks/use-is-mounted.ts",
"chars": 301,
"preview": "import { useRef } from 'react'\nimport { useIsoMorphicEffect } from './use-iso-morphic-effect'\n\nexport function useIsMoun"
},
{
"path": "packages/@headlessui-react/src/hooks/use-is-top-layer.ts",
"chars": 2243,
"preview": "import { useCallback, useId } from 'react'\nimport { stackMachines } from '../machines/stack-machine'\nimport { useSlice }"
},
{
"path": "packages/@headlessui-react/src/hooks/use-is-touch-device.ts",
"chars": 661,
"preview": "import { useState } from 'react'\nimport { useIsoMorphicEffect } from './use-iso-morphic-effect'\n\nexport function useIsTo"
},
{
"path": "packages/@headlessui-react/src/hooks/use-iso-morphic-effect.ts",
"chars": 328,
"preview": "import { useEffect, useLayoutEffect, type DependencyList, type EffectCallback } from 'react'\nimport { env } from '../uti"
},
{
"path": "packages/@headlessui-react/src/hooks/use-latest-value.ts",
"chars": 258,
"preview": "import { useRef } from 'react'\nimport { useIsoMorphicEffect } from './use-iso-morphic-effect'\n\nexport function useLatest"
},
{
"path": "packages/@headlessui-react/src/hooks/use-on-disappear.ts",
"chars": 1543,
"preview": "import { useEffect, type MutableRefObject } from 'react'\nimport { disposables } from '../utils/disposables'\nimport * as "
},
{
"path": "packages/@headlessui-react/src/hooks/use-on-unmount.ts",
"chars": 478,
"preview": "import { useEffect, useRef } from 'react'\nimport { microTask } from '../utils/micro-task'\nimport { useEvent } from './us"
},
{
"path": "packages/@headlessui-react/src/hooks/use-outside-click.ts",
"chars": 6998,
"preview": "import { useCallback, useRef } from 'react'\nimport * as DOM from '../utils/dom'\nimport { FocusableMode, isFocusableEleme"
},
{
"path": "packages/@headlessui-react/src/hooks/use-owner.ts",
"chars": 374,
"preview": "import { useMemo } from 'react'\nimport { getOwnerDocument, getRootNode } from '../utils/owner'\n\nexport function useOwner"
},
{
"path": "packages/@headlessui-react/src/hooks/use-quick-release.ts",
"chars": 3033,
"preview": "import { useRef } from 'react'\nimport * as DOM from '../utils/dom'\nimport { useDocumentEvent } from './use-document-even"
},
{
"path": "packages/@headlessui-react/src/hooks/use-refocusable-input.ts",
"chars": 2003,
"preview": "import { useRef } from 'react'\nimport * as DOM from '../utils/dom'\nimport { isActiveElement } from '../utils/owner'\nimpo"
},
{
"path": "packages/@headlessui-react/src/hooks/use-resolve-button-type.ts",
"chars": 641,
"preview": "import { useMemo } from 'react'\n\nexport function useResolveButtonType<TTag>(\n props: { type?: string; as?: TTag },\n el"
},
{
"path": "packages/@headlessui-react/src/hooks/use-resolved-tag.ts",
"chars": 1163,
"preview": "import { useCallback, useState } from 'react'\nimport * as DOM from '../utils/dom'\n\n/**\n * Resolve the actual rendered ta"
},
{
"path": "packages/@headlessui-react/src/hooks/use-root-containers.tsx",
"chars": 5522,
"preview": "import React, { createContext, useContext, useState, type MutableRefObject } from 'react'\nimport { Hidden, HiddenFeature"
},
{
"path": "packages/@headlessui-react/src/hooks/use-scroll-lock.ts",
"chars": 513,
"preview": "import { useDocumentOverflowLockedEffect } from './document-overflow/use-document-overflow'\nimport { useIsTopLayer } fro"
},
{
"path": "packages/@headlessui-react/src/hooks/use-server-handoff-complete.ts",
"chars": 1784,
"preview": "import * as React from 'react'\nimport { env } from '../utils/env'\n\n/**\n * This is used to determine if we're hydrating i"
},
{
"path": "packages/@headlessui-react/src/hooks/use-slot.ts",
"chars": 318,
"preview": "import { useMemo } from 'react'\n\n// The only goal of this hook is to get a stable object reference using\n// `useMemo`. T"
},
{
"path": "packages/@headlessui-react/src/hooks/use-store.ts",
"chars": 229,
"preview": "import { useSyncExternalStore } from 'react'\nimport type { Store } from '../utils/store'\n\nexport function useStore<T>(st"
},
{
"path": "packages/@headlessui-react/src/hooks/use-sync-refs.ts",
"chars": 801,
"preview": "import { useEffect, useRef } from 'react'\nimport { useEvent } from './use-event'\n\nlet Optional = Symbol()\n\nexport functi"
},
{
"path": "packages/@headlessui-react/src/hooks/use-tab-direction.ts",
"chars": 471,
"preview": "import { useRef } from 'react'\nimport { useWindowEvent } from './use-window-event'\n\nexport enum Direction {\n Forwards,\n"
},
{
"path": "packages/@headlessui-react/src/hooks/use-text-value.ts",
"chars": 701,
"preview": "import { useRef, type MutableRefObject } from 'react'\nimport { getTextValue } from '../utils/get-text-value'\nimport { us"
},
{
"path": "packages/@headlessui-react/src/hooks/use-tracked-pointer.ts",
"chars": 1005,
"preview": "import { useRef } from 'react'\n\ntype PointerPosition = [x: number, y: number]\n\nfunction eventToPosition(evt: PointerEven"
},
{
"path": "packages/@headlessui-react/src/hooks/use-transition.ts",
"chars": 8494,
"preview": "import { useRef, useState, type MutableRefObject } from 'react'\nimport { disposables } from '../utils/disposables'\nimpor"
},
{
"path": "packages/@headlessui-react/src/hooks/use-tree-walker.ts",
"chars": 1331,
"preview": "import { useEffect, useRef } from 'react'\nimport { getOwnerDocument } from '../utils/owner'\nimport { useIsoMorphicEffect"
},
{
"path": "packages/@headlessui-react/src/hooks/use-watch.ts",
"chars": 681,
"preview": "import { useEffect, useRef } from 'react'\nimport { useEvent } from './use-event'\n\nexport function useWatch<T extends any"
},
{
"path": "packages/@headlessui-react/src/hooks/use-window-event.ts",
"chars": 626,
"preview": "import { useEffect } from 'react'\nimport { useLatestValue } from './use-latest-value'\n\nexport function useWindowEvent<TT"
},
{
"path": "packages/@headlessui-react/src/index.test.ts",
"chars": 1572,
"preview": "import * as HeadlessUI from './index'\n\n/**\n * Looks a bit of a silly test, however this ensures that we don't accidental"
},
{
"path": "packages/@headlessui-react/src/index.ts",
"chars": 1313,
"preview": "export * from './components/button/button'\nexport * from './components/checkbox/checkbox'\nexport * from './components/cl"
},
{
"path": "packages/@headlessui-react/src/internal/close-provider.tsx",
"chars": 366,
"preview": "'use client'\n\nimport React, { createContext, useContext } from 'react'\n\nlet CloseContext = createContext(() => {})\n\nexpo"
},
{
"path": "packages/@headlessui-react/src/internal/disabled.tsx",
"chars": 395,
"preview": "import React, { createContext, useContext } from 'react'\n\nlet DisabledContext = createContext<boolean | undefined>(undef"
},
{
"path": "packages/@headlessui-react/src/internal/floating.tsx",
"chars": 20421,
"preview": "import {\n autoUpdate,\n flip as flipMiddleware,\n inner as innerMiddleware,\n offset as offsetMiddleware,\n shift as sh"
},
{
"path": "packages/@headlessui-react/src/internal/focus-sentinel.tsx",
"chars": 1366,
"preview": "import React, { useState, type FocusEvent as ReactFocusEvent } from 'react'\nimport { useIsMounted } from '../hooks/use-i"
},
{
"path": "packages/@headlessui-react/src/internal/form-fields.tsx",
"chars": 2889,
"preview": "import React, { createContext, useContext, useEffect, useState } from 'react'\nimport { createPortal } from 'react-dom'\ni"
},
{
"path": "packages/@headlessui-react/src/internal/frozen.tsx",
"chars": 888,
"preview": "import React, { cloneElement, isValidElement, useState } from 'react'\n\nfunction FrozenFn(\n { children, freeze }: { chil"
},
{
"path": "packages/@headlessui-react/src/internal/hidden.tsx",
"chars": 2117,
"preview": "import type { ElementType, Ref } from 'react'\nimport type { Props } from '../types'\nimport { forwardRefWithAs, useRender"
},
{
"path": "packages/@headlessui-react/src/internal/id.tsx",
"chars": 362,
"preview": "import React, { createContext, useContext } from 'react'\n\nlet IdContext = createContext<string | undefined>(undefined)\n\n"
},
{
"path": "packages/@headlessui-react/src/internal/open-closed.tsx",
"chars": 733,
"preview": "import React, { createContext, useContext, type ReactElement, type ReactNode } from 'react'\n\nlet Context = createContext"
},
{
"path": "packages/@headlessui-react/src/internal/portal-force-root.tsx",
"chars": 481,
"preview": "import React, { createContext, useContext, type ReactNode } from 'react'\n\nlet ForcePortalRootContext = createContext(fal"
},
{
"path": "packages/@headlessui-react/src/machine.ts",
"chars": 4125,
"preview": "import { DefaultMap } from './utils/default-map'\nimport { disposables } from './utils/disposables'\nimport { env } from '"
},
{
"path": "packages/@headlessui-react/src/machines/stack-machine.ts",
"chars": 1795,
"preview": "import { Machine } from '../machine'\nimport { DefaultMap } from '../utils/default-map'\nimport { match } from '../utils/m"
},
{
"path": "packages/@headlessui-react/src/react-glue.tsx",
"chars": 672,
"preview": "import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector'\n\nimport { useEvent } from './ho"
},
{
"path": "packages/@headlessui-react/src/test-utils/accessibility-assertions.ts",
"chars": 57118,
"preview": "import { FocusableMode, isFocusableElement } from '../utils/focus-management'\nimport { getActiveElement } from '../utils"
},
{
"path": "packages/@headlessui-react/src/test-utils/execute-timeline.ts",
"chars": 5696,
"preview": "import { render } from '@testing-library/react'\nimport snapshotDiff from 'snapshot-diff'\nimport { disposables } from '.."
},
{
"path": "packages/@headlessui-react/src/test-utils/fake-pointer.ts",
"chars": 1263,
"preview": "export class FakePointer {\n private x: number = 0\n private y: number = 0\n\n constructor(\n private width: number,\n "
},
{
"path": "packages/@headlessui-react/src/test-utils/interactions.test.tsx",
"chars": 5564,
"preview": "import { render } from '@testing-library/react'\nimport React from 'react'\nimport { Keys, shift, type } from './interacti"
},
{
"path": "packages/@headlessui-react/src/test-utils/interactions.ts",
"chars": 14175,
"preview": "import { fireEvent } from '@testing-library/react'\nimport { act } from 'react'\nimport * as DOM from '../utils/dom'\nimpor"
}
]
// ... and 272 more files (download for full content)
About this extraction
This page contains the full source code of the tailwindlabs/headlessui GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 472 files (3.2 MB), approximately 877.8k tokens, and a symbol index with 1932 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.