@doitrix/headless
v1.2.0
Published
Unstyled, accessible Vue 3 behaviour for the Doitrix design system — dialog, popover, tooltip, menu, select, tabs, form controls and data-table state. Zero dependencies, tree-shakable.
Readme
@doitrix/headless
Unstyled, accessible behaviour for Vue 3 — the part of a component that is hard to get right and should never be written twice. No styles, no dependencies, one module per file so an app ships only what it imports.
bun add @doitrix/headlessWhat is in it
| Area | Exports |
|---|---|
| Overlays | Dialog* (dialog and alertdialog), Popover*, Tooltip*, DropdownMenu* |
| Form controls | Select*, Checkbox*, Switch*, RadioGroup* |
| Navigation | Tabs* |
| Display | Avatar* |
| Composition | Primitive (as, asChild), Slot, Portal |
| Composables | useFocusTrap, useDismissable, useScrollLock, useFloating, usePresence, useCollection, useControllable, useDataTable |
| Pure core | computeFloating, createTypeahead, moveFromKey, paginate, sortRows, selectionState, cardLayout, … |
Behaviour it guarantees
- Keyboard: WAI-ARIA patterns throughout — roving tab stops, arrow keys by orientation (swapped in RTL), Home/End, typeahead in menus and selects.
- Focus: moved in on open, trapped in modals, returned to the trigger on close — but never stolen back if the user has already moved on.
- Dismissal: Escape and outside presses go to the topmost layer only, so a select inside a dialog closes the select alone. Both are cancelable.
- ARIA wiring: ids are generated, and follow your own
idif you pass one. - Motion: content stays mounted through its exit animation, then unmounts; with no animation it unmounts at once.
- State: every stateful part works with
v-modelor uncontrolled with adefault*prop. Everything exposesdata-state,data-disabled,data-highlighted,data-sidefor styling.
Styling
Target the data attributes:
<DialogContent class="data-[state=open]:animate-pop-in data-[state=closed]:animate-pop-out">For styled, ready-made components built on this package, see @doitrix/ui.
