Headless Component
A component that gives you the behavior, keyboard handling, and accessibility of a widget with zero styling. You bring the CSS.
See it
What it is
A headless component ships the hard, invisible half of a widget and none of the looks: state machine, keyboard handling, focus management, ARIA wiring, positioning. You supply every pixel. The canonical examples are Radix UI, React Aria, Headless UI, TanStack Table, and Downshift. shadcn/ui is the pattern in public: Radix behavior underneath, your own Tailwind classes on top.
Reach for it when the component has to look like your brand rather than like Material or Bootstrap, and you still do not want to hand-write roving tabindex, type-ahead, or dismiss-on-outside-click for the fifth time. Styled kits are faster on day one; headless kits stop hurting on month six, when the design changes.
Gotcha: headless is not styling-free, it is styling-mandatory. You now own hover, focus-visible, disabled, open, selected, and every in-between state, usually via data attributes the library sets (data-state='open', data-disabled). Teams adopt a headless kit, style the default state only, and ship a menu with no visible focus ring.
Ask AI for it
Build this as a headless component. Put all the state, keyboard handling, and ARIA wiring inside, and ship zero visual CSS: no colors, no borders, no spacing. Follow the Radix UI pattern: compound parts (Root, Trigger, Content, Item), controlled and uncontrolled modes, an 'asChild' prop for polymorphic rendering, focus management and roving tabindex handled internally, dismiss on Escape and outside click. Expose every state as a data attribute (data-state='open', data-disabled, data-highlighted) so consumers can style it. Then show one consumer example where all the Tailwind classes live, and style hover, focus-visible, disabled, and open explicitly.