Morphos

Documentation

Headless primitive component library for PraxisJS.

Morphos

Welcome! Morphos is a headless, accessible primitive component library built on top of PraxisJS. If you've used Base UI or Radix UI before, you'll feel right at home — same idea, rebuilt for PraxisJS's signals and class components instead of hooks.

You bring the styles. Morphos brings the behavior.

Every component ships fully accessible and keyboard-navigable, with zero CSS attached. State is exposed through plain data-* attributes, so styling is just writing selectors — no className juggling, no context providers, no framework adapters to fight with.

New here? Start with the guide below — it walks through installing Morphos, understanding the compound-component pattern every package uses, and styling your first primitive.

Browse components

Design philosophy

  • Headless — zero built-in styles. Style via the class prop or data-* attribute selectors, however you like.
  • Accessible — ARIA roles, keyboard navigation, focus management, and screen reader support are built into every component, not bolted on.
  • PraxisJS-native — class components + decorators (@Component(), @Prop(), @State()). No hooks, no framework adapters to keep in sync.
  • State lives in data-* — every interactive state is exposed as a data-* attribute on the component root (data-open, data-disabled, data-selected, data-expanded, and more). Open DevTools and the state is right there on the element.

Not sure where to start? Getting Started has a full working example, including the compound-component pattern (dialog={this.dialog}-style props) used across every overlay, layout, and grouped-input component.

Full component list

Inputs — @morphos/inputs

ComponentDescription
ButtonPolymorphic button with an as prop
InputText input with controlled/uncontrolled modes
CheckboxCheckbox with indeterminate support
CheckboxGroup + CheckboxGroupItemGroup of checkboxes sharing one set of checked values
RadioGroup + RadioRadio group with keyboard navigation
SelectCustom listbox select with keyboard support
SwitchToggle switch (role="switch")
ToggleToggle button (aria-pressed)
ToggleGroup + ToggleGroupItemSingle- or multiple-selection toggle group
SliderRange slider driven by a CSS custom property
NumberFieldSpinbutton with increment/decrement controls
OtpFieldOne-time password input, split across N cells
ComboboxSearchable select with text filtering
AutocompleteFree-text input backed by a suggestion list
Field + FieldLabel / FieldControl / FieldDescription / FieldErrorForm field wrapper with label, description, and error message
FieldsetNative <fieldset> with a <legend>
FormForm wrapper with submit/reset handling

Overlays — @morphos/overlays

ComponentDescription
DialogModal dialog with focus trap and scroll lock
AlertDialogConfirmation dialog for destructive or important actions
DrawerSide panel sliding in from any edge (top/right/bottom/left)
PopoverClick-toggled floating panel
TooltipHover/focus-activated tooltip
Dropdown (aliased Menu)Menu with full keyboard navigation
ContextMenuRight-click context menu
PreviewCardHover-activated preview card

Layout — @morphos/layout

ComponentDescription
AccordionCollapsible item list, single or multiple open at once
TabsTab panel with keyboard navigation
Disclosure (aliased Collapsible)Single expand/collapse toggle
SeparatorHorizontal or vertical visual divider
ScrollAreaCustom-styled scroll container with a proportional scrollbar thumb
ToolbarRoving-tabindex toolbar for grouping controls
MenubarHorizontal menu bar with dropdown menus
NavigationMenuSite navigation with submenus

Feedback — @morphos/feedback

ComponentDescription
ToastProvider + ToastAuto-dismissing notification queue
AlertStatic inline notification
ProgressProgress bar with an indeterminate mode
SpinnerLoading indicator
AvatarImage with automatic fallback on load failure
MeterGauge for measurements within a known range

Getting help

  • Every component page includes a Props table for each of its parts, a data-* attributes table, and a Styling example.
  • See a bug or want a feature? Open an issue on GitHub.
  • Check the changelog for what's new in each package.

On this page