Reference for the public @askrjs/ui surface.
The package exports a curated root surface and direct component subpaths. Use the root package for everyday imports and subpaths when you want a single family with a narrower surface.
import { Button, Checkbox, Input } from '@askrjs/ui';
import { Dialog, OverlayHost, Popover, Tooltip } from '@askrjs/ui';
import { Dialog } from '@askrjs/ui/dialog';Type names are family-shaped rather than globally uniform. Most families use
OwnProps, Props, and AsChildProps naming. Some host-bound families use a
host-specific suffix when the underlying element is part of the contract.
The source tree follows the same layout: each public family owns its own folder
under src/components/, and shared internals stay in
src/components/_internal/.
These are documentation groupings only.
| Group | Families |
|---|---|
| Primitives | Button, Checkbox, Input, Label, Form, Toggle, ToggleGroup, RadioGroup, Select, Slider, Switch, Table, Textarea, Progress, ProgressCircle, VisuallyHidden |
| Focus | FocusScope, DismissableLayer |
| Overlays | OverlayHost, Dialog, AlertDialog, Popover, HoverCard, Tooltip, Dropdown, Menu |
| Disclosure | Accordion, Collapsible |
| Status | Progress, ProgressCircle, Toast |
| Identity | Avatar |
| Navigation | Menubar |
| Layout and layout-adjacent | Scroll Area |
| Virtualization | VirtualList, VirtualTable |
- AlertDialog is a Dialog specialization for blocking confirmations. Its action
and cancel parts intentionally alias the same close behavior for
compatibility. Always render
AlertDialogOverlayalongsideAlertDialogContentinside the portal. DialogOverlayandAlertDialogOverlayare fully styled out of the box when used with@askrjs/themes/default: the theme supplies the backdrop token, blur, stacking, and fade animation. Standard usage needs no additional CSS.OverlayHostprovides one explicit application-shell outlet for descendant overlay portals. Use it when overlays rendered inside clipping or virtualized content must escape that layout boundary; standalone roots retain their local portal behavior when no host is present.- Toast is a stacked notification family.
ToastHostowns the registry,ToastViewportrenders the stack, andToastregisters entries rather than rendering standalone DOM. - Select uses
SelectItemTextas the text slot used bySelectItemfor labeling and styling. DebouncedInputwrapsInputfor search and filter surfaces that need a settled value callback.ToastActioncloses a toast after a custom user action;ToastCloseis the explicit dismiss control.AlertDialogActionandAlertDialogCancelintentionally aliasDialogClosefor confirmation-dialog compatibility.VirtualListis a fixed-height list windowing primitive with stable keys, anchor correction, and optional follow-bottom behavior.VirtualTableis a fixed-height table windowing primitive with a sticky head, stable keys, selection, and keyboard navigation.
Anchored overlay families (Popover, HoverCard, Tooltip, Dropdown,
Menu, and Select) interpret align="start" and align="end" as logical
inline edges. The shared positioning engine reads the trigger's computed text
direction, so those alignments mirror in right-to-left layouts when the overlay
is above or below its trigger.
Viewport collision handling chooses and clamps the overlay position. Because
this package is headless, it does not shrink anchored content whose intrinsic
size is larger than the viewport. The content exposes the current padded
viewport bounds as --ak-overlay-available-width and
--ak-overlay-available-height; apply them with an appropriate wrapping and
overflow policy for application content:
.app-overlay-content {
max-width: var(--ak-overlay-available-width);
max-height: var(--ak-overlay-available-height);
overflow: auto;
overflow-wrap: anywhere;
}Without that consumer rule, a long unbroken URL, hash, or identifier can remain wider than a narrow viewport. The engine still clamps its position, but position clamping alone cannot make oversized content fit.
Keyboard behavior follows the semantic role of each public component and is
preserved through asChild composition.
| Surface | Keyboard contract |
|---|---|
| Button-like pressable controls | Enter activates on keydown, Space activates on keyup, disabled controls do not activate, and caller cancellation still suppresses the component's default action. |
| Checkbox, Switch, and RadioGroupItem | Native and asChild hosts activate with Space, not Enter. Radio-group arrows continue to move both focus and selection. |
| Roving composites | Arrow keys move the single active tab stop and skip disabled items. Horizontal movement follows computed text direction; Tab leaves the composite or dismisses an open popup and continues to the next page control. |
| Menu, Dropdown, Menubar, and Select | Printable keys perform case-insensitive prefix matching against textValue (or rendered text), skip disabled items, wrap to the next match, and cycle when the same character is repeated. The buffer resets after 500 ms. |
| Select | Typeahead works while either the closed trigger or open listbox has focus. Closed-trigger matches update the value; open-listbox matches move focus. |
| Accordion | Every enabled trigger remains in the page Tab sequence. Orientation arrows and Home/End provide optional direct navigation. |
| RadioGroup | Arrows skip disabled radios and move focus and selection. |
| ToggleGroup | Arrows move focus only; Enter or Space activates the focused toggle. |
| ScrollArea | Its enabled scrollbar uses arrows for 40 CSS-pixel steps, PageUp/PageDown for one viewport, and Home/End for the boundaries. |
Horizontal Slider arrows and Menubar submenu open/close arrows also follow the nearest computed text direction. ScrollArea arrows remain physical scrolling controls, so their left/right meaning does not mirror.
Spaces typed after a typeahead prefix can match multiword values; a standalone
Space remains an activation key. Typeahead only moves focus or selection. A
visible text field that filters options is a separate Combobox capability, not
Select behavior.
Native buttons and direct asChild buttons retain browser activation and form
submit/reset behavior. Non-native asChild hosts receive button-role
Enter/Space behavior. Component defaults run only when neither an ancestor nor
the caller canceled the event; activation remains exactly once in either path.
Menu-item links preserve native Enter navigation, while Space maps to one click.
HoverCard is a non-modal interactive preview. Pointer opening does not move focus. Tab can enter its content from the trigger, Escape restores the trigger, and leaving its final control continues after the trigger.
Uncontrolled Checkbox, RadioGroup, Select, Switch, and Slider state returns to its declared default when the nearest native form resets. Controlled values remain owned by the caller.
Menu is also the supported accessible primitive for an always-visible list
of navigation choices; it does not require a popover or trigger. Compose links
through MenuItem asChild so native navigation is preserved while arrow keys,
Home/End, and typeahead remain available without consumer event wiring.
<Menu>
<MenuContent aria-label="Choose a workspace">
<MenuItem asChild textValue="Acme production">
<a href="/workspaces/acme">
<MenuItemIcon aria-hidden="true">
<BuildingIcon />
</MenuItemIcon>
<MenuItemLabel>Acme</MenuItemLabel>
<MenuItemDescription>Production workspace</MenuItemDescription>
</a>
</MenuItem>
</MenuContent>
</Menu>The default theme styles the content surface, item dividers, leading icon,
primary label, description, and hover/focus states. Use textValue whenever
structured children do not provide the intended typeahead phrase directly.
Dynamic descendants are a supported composition contract for
context-coordinated group families. Their parts may be written directly,
nested in caller markup, returned from an array .map(), or rendered with
Askr's <For>.
| Family | Dynamic descendant contract |
|---|---|
accordion |
AccordionItem and its parts retain Accordion context. |
dropdown |
DropdownItem retains Dropdown and content context. |
menu |
MenuItem retains Menu and content context. |
menubar |
Menus, content, submenus, and items retain Menubar context. |
radio-group |
RadioGroupItem retains RadioGroup context. |
select |
Select groups, labels, and items retain Select context. |
slider |
Track, range, and thumb parts retain Slider context. |
toggle-group |
ToggleGroupItem retains ToggleGroup context. |
Use stable key props for array-mapped children and a stable by selector for
<For>. Dynamically reordered MenubarMenu children should also provide a
stable, unique value; it preserves each menu's trigger, content, and portal
identity as its position changes. Duplicate sibling values are rejected.
import { VirtualList, VirtualTable } from '@askrjs/ui';
import { VirtualList as VirtualListSubpath } from '@askrjs/ui/virtual-list';
import { VirtualTable as VirtualTableSubpath } from '@askrjs/ui/virtual-table';VirtualList keeps list rendering headless while the caller supplies the row
component. VirtualTable renders native table elements with interactive grid
semantics while the caller supplies column metadata and cell renderers. Give a
virtual table an accessible name and a bounded viewport. Keyboard row selection
is handled only while the grid itself has focus; links, buttons, and form
controls rendered inside cells retain their native click, focus, and keyboard
behavior.
Accordion items may be rendered as VirtualList or VirtualTable rows. Their roving-focus positions use the full dataset indices exposed by the virtual row, so navigation can scroll to and restore focus on an item outside the current mounted window.