Skip to main content
On this pageWhat is Foldkit UI?

Foldkit UI

What is Foldkit UI?

Foldkit UI is a set of headless, accessible UI components. Each component is renderless. You provide the markup and styling through a toView callback, and Foldkit UI provides the accessibility attributes, keyboard navigation, and (where applicable) state management.

Installation

@foldkit/ui is a separate package from foldkit. Projects scaffolded by create-foldkit-app from an example that uses UI components already include it. Its peer dependencies are foldkit and effect, which every Foldkit project already has. Add it to any other project with:

npm install @foldkit/ui

Two categories

Foldkit UI components fall into two categories, distinguished by whether they carry state.

Stateful Submodels (Menu, Listbox, Combobox, Calendar, Dialog, Popover, among others) manage their own Model, Message, update, and OutMessage. You embed them via h.submodel and handle their events by pattern-matching the OutMessage in your update.

Stateless render helpers (Button, Input, Textarea, Select, Checkbox, Switch, Disclosure, Fieldset, Nav) are called directly with a ViewConfig and your builder, and return Html. They bundle ARIA and data attributes onto consumer-rendered DOM. No Model, no h.submodel wiring. The controlled helpers dispatch the Messages returned by their config callbacks, and the builder you pass is what determines the Message type those callbacks must return, so there is no type argument to write. The “Kind” column in the table below marks which is which.

Components

ComponentKindDescription
ButtonHelperAccessible button with consistent ARIA attributes and data-attribute hooks for styling.
InputHelperText input with ARIA label/description linking and data-attribute hooks.
TextareaHelperMulti-line text input with ARIA label/description linking and data-attribute hooks.
CheckboxHelperToggle with accessible labeling, keyboard support, indeterminate state, and optional form integration.
FieldsetHelperGroups related form controls with a legend and description. Disabled state propagates to all children.
Radio GroupSubmodelRadio options with roving tabindex, keyboard navigation, read-only navigation, and per-option label/description linking.
SwitchHelperOn/off toggle with accessible labeling, keyboard support, and optional form integration.
SliderSubmodelNumeric range input with pointer drag, keyboard step / page / home / end navigation, and ARIA slider semantics.
SelectHelperNative select wrapper with ARIA label/description linking and data-attribute hooks.
ListboxSubmodelCustom select dropdown with persistent selection, keyboard navigation, typeahead search, and read-only browsing.
ComboboxSubmodelAutocomplete input with filtering, keyboard navigation, custom rendering, and read-only browsing.
DialogSubmodelModal dialog using native <dialog> with focus trapping, backdrop, and scroll locking.
MenuSubmodelDropdown menu with keyboard navigation, typeahead search, and aria-activedescendant focus.
PopoverSubmodelFloating panel with arbitrary content and natural Tab navigation.
DisclosureHelperShow/hide toggle for building collapsible sections like FAQs and accordions.
TabsSubmodelTabbed interface with keyboard navigation, Home/End support, and wrapping.
NavHelperStateless, URL-driven navigation landmark whose items are links, marking the current destination with aria-current="page".
Drag and DropSubmodelSortable lists and cross-container movement with pointer tracking, keyboard navigation, auto-scrolling, and screen reader announcements.
File DropSubmodelFile input with drag-and-drop support, configurable accept patterns, and multiple-file mode. Emits typed OutMessages for received files and non-file drops.
CalendarSubmodelInline calendar grid with 2D keyboard navigation, locale-aware headers, min/max constraints, and disabled-date support. Foundation for date pickers.
Date PickerSubmodelInput paired with a popover Calendar. Inherits the calendar’s constraint and keyboard-navigation support, with programmatic open/close and setters.
AnimationSubmodelCoordinates CSS enter/leave animations via a state machine and data attributes. Works with both CSS transitions and CSS keyframe animations. Sends an OutMessage when the leave animation completes.

Underneath the floating components sits Anchor, the positioning runtime Listbox, Combobox, Menu, Popover, Tooltip, and Date Picker share. It is neither a helper nor a Submodel, so it has no row above. Reach for it directly only when you are building an anchored component none of those cover.

Showcase

The UI Showcase example demonstrates every component with styled, interactive examples. It’s a good reference for how to wire up component state, handle Messages, and compose views.

Stay in the update loop.

New releases, patterns, and the occasional deep dive.


Built with Foldkit.

© 2026 Devin Jameson