GitShow/tailwindlabs/headlessui
tailwindlabs

headlessui

Completely unstyled, fully accessible UI components, designed to integrate beautifully with Tailwind CSS.

by tailwindlabs
a11yaccessibilitycomponentsheadless-uiheadlessuireacttailwindcssvue
Star on GitHubForkWebsitenpm

TypeScript

28.7k stars1.2k forks75 contributorsQuiet · 4mo agoSince 2020@headlessui/react@v2.2.10MIT

Meet the team

See all 75 on GitHub →
RobinMalfait
RobinMalfait737 contributions
thecrypticace
thecrypticace101 contributions
adamwathan
adamwathan12 contributions
reinink
reinink11 contributions
dependabot[bot]Bot
dependabot[bot]5 contributions
philipp-spiess
philipp-spiess4 contributions
simonswiss
simonswiss3 contributions
milhamm
milhamm2 contributions

Languages

View on GitHub →
TypeScript95.3%
Vue4.2%
JavaScript0.3%
Shell0.1%
CSS0%
HTML0%

Commit activity

Last 12 weeks · 0 commits

Full graph →

Community health

3 of 6 standards met

Community profile →
62
✓README✓License✓Contributing○Code of Conduct○Issue Template○PR Template

Recent PRs & issues

Quiet · Last activity 4mo ago
See all on GitHub →
amansoomro062
Accessibility conformance results for Headless UI, ahead of publication (one finding)OpenIssue

What package within Headless UI are you using? What version of that package are you using? v2.2.10 What browser are you using? Chromium 151.0.7922.34 (Playwright), macOS Reproduction URL https://github.com/amansoomro062/railing Not a CodeSandbox, and I want to be upfront about why: the reproduction here is the measurement harness itself. From a clone, two commands mount exactly as your docs describe and replay the one failing check, and the scored run has a replayable Playwright trace: The adapter that mounts the component is about fifty lines and is included in full in the report below, so you can check the mounting before trusting anything else in this issue. Describe your issue This is not the usual bug report, so thank you for reading this far. These are accessibility conformance results from Railing, an open source project that tests React component libraries against the W3C ARIA Authoring Practices Guide and publishes the results. Headless UI is one of the seven libraries measured, and I wanted you to hear the results from me before anything is public. The short version: Headless UI passes 63 of 64 checks. Four of five components pass everything. One moderate finding on the accordion pattern, detailed below. Components were mounted with default configuration, following your documentation, with no hand-written ARIA. Headless UI ships no styles by design, so the harness is unstyled. That is the library working as intended, not a missing step. The one finding: . The APG accordion pattern expects each header control to sit inside a heading (- or ), because screen reader users navigate by heading and an accordion whose headers are not headings disappears from that shortcut. Mounted per your Disclosure documentation, has no heading ancestor. Severity moderate, cited against the APG pattern and WCAG 1.3.1. I would also like to contribute a fix. If you would take a docs change adding the heading wrapper to the Disclosure example, or a change in the component if you would rather it ship there, I am happy to open the PR; tell me which you would prefer and I will push it. A fix that ships inside the notice window means the fixed score is what gets published. We can also see the reasonable counterargument, and we want you to make it if you hold it: Disclosure is a primitive, not an accordion, and the heading wrapper may be the application's responsibility rather than the library's. If that is your position, say so and we publish your reasoning beside the score, in full and unedited. Why tell you at all? Three reasons: 1. You should hear about a public score from us rather than come across it. No score for Headless UI is on our index yet, and none will be for at least fourteen days. 2. You may think we measured something wrongly, and please let us know. The likeliest source of error in this project is our adapter, not your library, and we publish corrections in the open (decision log). 3. When the index goes live, Headless UI will be on it at 63 of 64, with a caveat we print on every page: a high score means no violations were detected by automated testing, not that a component is accessible. If you would rather phrase your own caveat beside it, we publish responses in full and unedited. How the measurement works: railing.dev/method · scoring · disclosure policy · source Full report Accessibility conformance results for Headless UI You are hearing this before we publish anything. No score for Headless UI is on our index, and none will be for at least fourteen days, whatever this report says. Railing runs component libraries against the W3C ARIA Authoring Practices Guide and publishes the results. Every check cites the clause it measures, every score names an exact version, and every result is run repeatedly and discarded if the answer changes. The short version Read this before the findings We mounted your components like this: Mounted with default configuration, using only components Headless UI exports and no hand-written ARIA. Headless UI ships no styles by design, so the harness is unstyled, that is the library working as intended, not a missing step. If that choice is the disagreement rather than the findings themselves, say so and we will publish your reasoning beside the score. It is a judgement call, not a measurement, and you are better placed to argue it than we are. The 1 finding One or more header controls are not contained in a heading. Check: , "Each header control sits inside a heading" Component: accordion Severity: moderate, meaning behaviour departs from the specified pattern; users are inconvenienced Why it matters: Screen reader users navigate documents by heading. If accordion headers are not headings, an entire page structure disappears from the shortcut that most users rely on to move around it. Expected: each control inside an h1–h6 or role=heading element We measured: hr-header-1, hr-header-2, hr-header-3 have no heading ancestor Measured against: APG pattern · WCAG 1.3.1 Info and Relationships Reproduce: How we tested it Versions: @headlessui/react@2.2.10 Browser: chromium 151.0.7922.34 Configuration: default. We use only what the library exports and never hand-write ARIA, even where the documentation instructs the developer to. If we did, the score would measure how carefully we copied your docs rather than what ships in the box. Traces: every run above has a replayable Playwright trace, captured from exactly the run that was scored. Ask and we will send them, or regenerate them with the command below. Reproduce any of it from a clone of the repository: Where we might be wrong The most likely cause of a wrong result is our adapter, not your library. We have got this wrong repeatedly. One library's first run scored 27% and almost all of it was a selector of ours. Another was reported as having a broken focus trap when the trap worked and our test was reading focus too early. So the adapter source is included below. Please tell us if we mounted your component in a way you would not recommend, or if a check misreads the specification. We will correct it and, if it has already been published, correct that too. Where to check us How the measurement works, including why the runner never learns which library it is testing. How scoring works, with every weighting and what is deliberately left out. Our disclosure policy, covering notice, right of reply, and conflicts of interest. The decision log, which is largely a record of results we got wrong and corrected. The source. Every adapter, spec and score, and the code that produced this report. What happens next You have fourteen days before anything about this library is published. If you reply, your response is published beside the score, in full and unedited. If you ship a fix in that window, we publish the fixed score. A finding that gets fixed before publication is the best outcome this project has, not a story we lost. If fourteen days is not enough for your release process, ask for more and you will get it. The adapter we used This is the whole of the library-specific code. There is nothing else. accordion.tsx combobox.tsx dialog.tsx menu.tsx tabs.tsx Thanks for building a library where the hardest thing to find was one heading. Aman

amansoomro062 · 1w ago
MILLERMARRU
Vue: stale scroll-lock meta breaks touch-scrolling in sibling Dialogs on iOS (React fixed in #3796, Vue never got the port)OpenIssue

What package is this bug report for? @headlessui/vue What version are you using? Latest (checked and directly) Reproduction URL N/A — source-level finding, see mechanism below. I can put together a repro if useful. Describe your issue fixed this exact bug in #3796 (merged 2025-09-17, "Ensure sibling components are scrollable on mobile"), but the Vue package never received the port. Note:* this is a different, more specific bug than the one tracked in #3584. #3584 is about the top-layer/stack architecture from #3242 (which sibling is "active" for Escape/outside-click) — that's a separate mechanism in a separate file. This issue is only about the iOS scroll-lock staleness in /, fixed by #3796, unrelated to #3242's stack. The bug 's handler computes the allowed-containers once, at the moment the document transitions from unlocked to locked: only fires when is true (the lock count goes from 0 to something >0). If a second //etc. opens while the document is already* locked, only runs (updates ), does not run again — so 's closure keeps referencing the stale captured from only the first overlay's containers: Concretely: open a , then open a second on top of it (both stay mounted — e.g. a confirm dialog over a form dialog). On iOS Safari, touches inside the second dialog aren't recognized as "inside an allowed container" (since its containers were never added to the frozen ), so they get /'d, making the second dialog unscrollable. The fix that already landed for React (#3796) Makes a lazily-evaluated function instead of a frozen snapshot, recomputed on every /: I confirmed the Vue package's / still have the pre-#3796 shape ( computed once in , used as a plain object rather than a function in ) — the Vue changelog has no entry corresponding to #3796. Expected behavior Same fix as #3796, ported to .

MILLERMARRU · 1w ago
waterWang
fix(@headlessui-vue): ensure Dialog on iOS works after touching disallowed areaOpenPR

Description This PR ports the iOS touch locking fix from @headlessui/react (PR #3801) to @headlessui/vue. Problem The handler in applies to elements touched outside the Dialog, but never clears those styles. Each touchstart event accumulates more styles, eventually making the Dialog unscrollable and unzoomable until closed and reopened. Fix Wrap the handler in and call at the start of each touch. This disposes the previous group's side effects (reset styles) before applying new ones, exactly matching the fix already merged for @headlessui/react in #3801. Verification The method is already available in the Vue package's with the same API as React's The change is identical to the proven fix in #3801, just applied to the Vue version of the file No new dependencies or API changes Fixes #3888

waterWang · 1w ago
Structured data for AI agents

Repository: tailwindlabs/headlessui. Description: Completely unstyled, fully accessible UI components, designed to integrate beautifully with Tailwind CSS. Stars: 28721, Forks: 1203. Primary language: TypeScript. Languages: TypeScript (95.3%), Vue (4.2%), JavaScript (0.3%), Shell (0.1%), CSS (0%). License: MIT. Homepage: https://headlessui.com Topics: a11y, accessibility, components, headless-ui, headlessui, react, tailwindcss, vue. Latest release: @headlessui/react@v2.2.10 (4mo ago). Open PRs: 25, open issues: 84. Last activity: 4mo ago. Community health: 62%. Top contributors: RobinMalfait, thecrypticace, adamwathan, reinink, dependabot[bot], philipp-spiess, simonswiss, milhamm, NoelDeMartin, eps1lon and others.

·@ofershap

Replace github.com with gitshow.dev