{"id":15733034,"url":"https://github.com/airblade/headlessui-stimulus","last_synced_at":"2025-05-13T01:24:55.548Z","repository":{"id":154539941,"uuid":"632045865","full_name":"airblade/headlessui-stimulus","owner":"airblade","description":"Stimulus components for Headless UI","archived":false,"fork":false,"pushed_at":"2023-05-25T13:09:26.000Z","size":55,"stargazers_count":15,"open_issues_count":5,"forks_count":1,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-16T14:40:42.969Z","etag":null,"topics":["headlessui","stimulus-controller","stimulusjs","tailwindcss"],"latest_commit_sha":null,"homepage":"https://headlessui-stimulus.com","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/airblade.png","metadata":{"files":{"readme":"README.markdown","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-04-24T15:41:15.000Z","updated_at":"2024-12-18T23:25:47.000Z","dependencies_parsed_at":null,"dependency_job_id":"45becc01-225b-4671-bece-06923eccde2d","html_url":"https://github.com/airblade/headlessui-stimulus","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/airblade%2Fheadlessui-stimulus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/airblade%2Fheadlessui-stimulus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/airblade%2Fheadlessui-stimulus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/airblade%2Fheadlessui-stimulus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/airblade","download_url":"https://codeload.github.com/airblade/headlessui-stimulus/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253852179,"owners_count":21973874,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["headlessui","stimulus-controller","stimulusjs","tailwindcss"],"created_at":"2024-10-04T00:40:40.065Z","updated_at":"2025-05-13T01:24:55.528Z","avatar_url":"https://github.com/airblade.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Headless UI - Stimulus\n\nPlease see the [demo page](https://airblade.github.io/headlessui-stimulus) for some examples.\n\nStatus: implementing the components as I need them.  Just started and a long way to go :)\n\nThis is a set of [Stimulus](https://stimulus.hotwired.dev) controllers for [Headless UI's components](https://headlessui.com).\n\n- [x] [Menu (Dropdown)](#menu-dropdown)\n- [ ] Listbox (Select)\n- [ ] Combobox (Autocomplete)\n- [ ] Switch (Toggle)\n- [ ] Disclosure\n- [x] [Dialog (Modal)](#dialog-modal)\n- [x] [Popover](#popover)\n- [ ] Radio Group\n- [ ] Tabs\n- [x] [Transitions](#transitions)\n\nThey all come with keyboard navigation and focus management, and automatically manage relevant ARIA attributes.\n\n\n## Installation\n\n```\nbin/importmap pin headlessui-stimulus\n```\n\n\n## Usage\n\nRegister the components with your Stimulus application.  For example, to register the Menu (Dropdown) component:\n\n```diff\n  import { Application } from '@hotwired/stimulus'\n+ import { Menu } from 'headlessui-stimulus'\n\n  const application = Application.start()\n+ application.register('menu', Menu)\n```\n\nNote: you must have a `hidden` CSS class for elements to show and hide:\n\n```css\n.hidden {\n  display: none;\n}\n```\n\nIf you use Tailwind CSS's [@headlessui/tailwindcss](https://github.com/tailwindlabs/headlessui/tree/main/packages/%40headlessui-tailwindcss) plugin, you can use modifiers like `ui-open:*` and `ui-active:*` to style these components.\n\nIf you don't use the plugin, you can use the `data-headlessui-state` attributes directly to conditionally apply different styles.\n\n\n## Menu (Dropdown)\n\nSee [Headless UI: Menu](https://headlessui.com/react/menu).\n\nUse the following markup (the classes and ARIA attributes are omitted for clarity).\n\n```html\n\u003cdiv data-controller=\"menu\"\u003e\n    \u003cbutton\n        type=\"button\"\n        data-menu-target=\"button\"\n        data-action=\"click-\u003emenu#toggle keydown-\u003emenu#keydownButton\"\n    \u003e\n        ...\n    \u003c/button\u003e\n    \u003cdiv\n        class=\"hidden\"\n        role=\"menu\"\n        tabindex=\"-1\"\n        data-menu-target=\"menuItems\"\n        data-action=\"keydown-\u003emenu#keydownItems\"\n    \u003e\n        \u003ca\n            href=\"...\"\n            role=\"menuitem\"\n            tabindex=\"-1\"\n            data-menu-target=\"menuItem\"\n            data-action=\"mouseover-\u003emenu#activate\"\n        \u003e\n            ...\n        \u003c/a\u003e\n        \u003c!-- more menu item links --\u003e\n    \u003c/div\u003e\n\u003c/div\u003e\n```\n\nOptionally you can specify classes for the active and inactive menu items like this:\n\n```html\n\u003cdiv\n    data-controller=\"menu\"\n    data-menu-active-class=\"...\"\n    data-menu-inactive-class=\"...\"\n\u003e\n```\n\n\n## Dialog (Modal)\n\nSee [Headless UI: Dialog](https://headlessui.com/react/dialog).\n\nUse the following markup (the classes and ARIA attributes are omitted for clarity).\n\n```html\n\u003cdiv data-controller=\"dialog\"\u003e\n    \u003c!-- optional backdrop --\u003e\n    \u003cdiv data-dialog-target=\"backdrop\"\u003e\u003c/div\u003e\n\n    \u003cdiv data-dialog-target=\"panel\" data-action=\"keydown-\u003edialog#keydown\"\u003e\n        \u003ch1 data-dialog-target=\"title\"\u003eAn important notice\u003c/h1\u003e\n        \u003cp data-dialog-target=\"description\"\u003eBlah blah blah.\u003c/p\u003e\n        ...\n        \u003cbutton data-action=\"dialog#close\"\u003e...\u003c/button\u003e\n        ...\n    \u003c/div\u003e\n\u003c/div\u003e\n```\n\nTo open the dialog:\n\n- either call `dialog#open` on the controller;\n- or set `data-dialog-open-value=\"true\"` on the controller's element.\n\nTo close the dialog:\n\n- either call `dialog#close` on the controller;\n- or set `data-dialog-open-value=\"false\"` on the controller's element;\n- or click outside the panel;\n- or press \u003ckbd\u003eEscape\u003c/kbd\u003e.\n\nIf your dialog has a title and a description, use `data-dialog-target=\"title\"` and `data-dialog-target=\"description\"` to provide the most accessible experience.  This will link your title and description to the controller element via the `aria-labelledby` and `aria-describedby` attributes.\n\nWhen the dialog opens, the panel's first focusable element by DOM order receives focus.  To specify that a different element should receive focus initially, give it the data attribute `data-dialog-target=\"initialFocus\"`.\n\nTo toggle class(es) on the `\u003chtml\u003e` element when the dialog opens/closes, use `data-dialog-html-open-class=\"...\"` where the value is a space-separated list of classes.\n\nYou can configure your dialog with the following attributes.  Declare them on the controller as `data-dialog-[name]-value`.\n\n| Name | Default | Description |\n|--|--|--|\n| open | `false` | Whether the dialog is open (`true`) or closed (`false`). |\n| unmount | `false` | On closing the dialog, whether to remove it from the DOM (`true`) or hide it (`false`). |\n\nYou can specify transitions on the backdrop and the panel.\n\n\n## Popover\n\nSee [Headless UI: Popover](https://headlessui.com/react/popover).\n\nUse the following markup (the classes and ARIA attributes are omitted for clarity).\n\n```html\n\u003cdiv data-controller=\"popover\" data-action=\"keydown.esc-\u003epopover#close\"\u003e\n    \u003cbutton\n        type=\"button\"\n        data-popover-target=\"button\"\n        data-action=\"popover#toggle\"\n    \u003e\n        ...\n    \u003c/button\u003e\n\n    \u003c!-- optional --\u003e\n    \u003cdiv data-popover-target=\"overlay\" data-action=\"click-\u003epopover#close\"\u003e\u003c/div\u003e\n\n    \u003cdiv data-popover-target=\"panel\" data-action=\"keydown-\u003epopover#keydownPanel\"\u003e\n        ...\n    \u003c/div\u003e\n\u003c/div\u003e\n```\n\nTo open the popover:\n\n- either call `popover#open` on the controller;\n- or set `data-popover-open-value=\"true\"` on the controller's element.\n\nTo close the popover:\n\n- either call `popover#close` on the controller;\n- or set `data-popover-open-value=\"false\"` on the controller's element.\n- or \u003ckbd\u003eTab\u003c/kbd\u003e out of the panel;\n- or click outside the panel;\n- or press \u003ckbd\u003eEscape\u003c/kbd\u003e.\n\nWhen the popover opens, the panel does not receive focus until you \u003ckbd\u003eTab\u003c/kbd\u003e into it.  If you would prefer the first focusable element in the panel to receive focus when the panel opens, set the `data-popover-focus-panel=\"true\"` data attribute on the controller's element.\n\nWhen the popover closes (unless you \u003ckbd\u003eTab\u003c/kbd\u003e out), focus returns to the button target.  If you want another element to receive focus, set the `data-popover-focus-on-close-value=\"...\"`.  The value should be a CSS selector.\n\nYou can configure your popover with the following attributes.  Declare them on the controller as `data-popover-[name]-value`.\n\n| Name | Default | Description |\n|--|--|--|\n| open | `false` | Whether the popover is open (`true`) or closed (`false`). |\n| focus-panel | `false` | On opening the popover, whether to focus the panel's first focusable element. |\n| focus-on-close | \"\" | On closing the popover (except by using \u003ckbd\u003eTab\u003c/kbd\u003e), the element to focus, expressed as a CSS selector.  `\"\"` focuses the button target. |\n| unmount | `false` | On closing the popover, whether to remove it from the DOM (`true`) or hide it (`false`). |\n\nYou can specify transitions on the overlay and the panel.\n\nPopover groups are not supported yet (because [I'm not sure how they are supposed to behave](https://github.com/tailwindlabs/headlessui/discussions/2503).)\n\n\n## Transitions\n\nTransitions are supported by each component.  Specify the transitions you want with these data attributes:\n\n```html\ndata-transition-enter=\"...\"\ndata-transition-enter-start=\"...\"\ndata-transition-enter-end=\"...\"\ndata-transition-leave=\"...\"\ndata-transition-leave-start=\"...\"\ndata-transition-leave-end=\"...\"\n```\n\nIf you are using Tailwind UI components, you can pretty much copy and paste the the transitions specified in the code comments.\n\nFor example, a sidebar component might include this comment in its source code:\n\n```html\n\u003c!--\n      Off-canvas menu backdrop, show/hide based on off-canvas menu state.\n\n      Entering: \"transition-opacity ease-linear duration-300\"\n        From: \"opacity-0\"\n        To: \"opacity-100\"\n      Leaving: \"transition-opacity ease-linear duration-300\"\n        From: \"opacity-100\"\n        To: \"opacity-0\"\n--\u003e\n```\n\nHere are the corresponding data attributes you would use:\n\n```html\ndata-transition-enter=\"transition-opacity ease-linear duration-300\"\ndata-transition-enter-start=\"opacity-0\"\ndata-transition-enter-end=\"opacity-100\"\ndata-transition-leave=\"transition-opacity ease-linear duration-300\"\ndata-transition-leave-start=\"opacity-100\"\ndata-transition-leave-end=\"opacity-0\"\n```\n\n\n## Intellectual Property\n\nThis package is copyright Andrew Stewart.\n\nThis package is available as open source under the terms of the MIT licence.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fairblade%2Fheadlessui-stimulus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fairblade%2Fheadlessui-stimulus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fairblade%2Fheadlessui-stimulus/lists"}