Meta's open source design system: accessible React components, hooks, examples, and page templates. Components install as re-exports of the Astryx package; examples and pages copy editable source.
The radio visual: a circle with a filled inner dot when selected. Draws in both states; an unselected radio is an empty circle, which is what lets it stand in for a checkmark in a selection slot.
Radio group container with field integration for label, description, and status.
Astryx showcase: RadioList.
Radio list with horizontal orientation for compact selections.
Individual radio item with label, description, and content slots.
Radio list items with labels, descriptions, and different states including disabled.
Radio items with labels and descriptions inside a controlled RadioList. Use for single-choice option groups like shipping methods.
Radio list with pricing info in end content for plan selection.
Radio list with descriptions on the group and each item.
Required radio list with an error message when nothing is selected.
Draggable separator between panels. Pill-grip design: invisible at rest, visible on hover (0.6 opacity), fully opaque during drag (1.0). Keyboard-accessible.
A WYSIWYG rich-text editor built on Lexical, styled with Astryx design tokens. Its field container shares TextArea input visuals for the resting border, hover ring, focus-within ring, disabled state, and status colors. Ships from @astryxdesign/richtext; lexical and @lexical/* are optional peer dependencies. The editor is deliberately minimal and extensible: pass toolbar, nodes, and plugins to layer richer behaviour (formatting, mentions, hover cards) on top without forking. Use RichTextView to render serialized content read-only.
Provides a native scroll viewport and a real observed content box. The viewport enters the tab order only while a requested logical axis is effectively scrollable, and containment applies only to effective axes.
A fixed-height file panel that scrolls on the block axis; the heading sits inside the viewport, so it scrolls away with the content.
axis="inline" scrolls the same cards sideways; isFullBleed lets the rail run to the panel edges while the content padding keeps the first card aligned with the heading.
The same section, two edge policies: the default overscroll="allow" hands a gesture that reaches the end to the panel behind it, while overscroll="contain" stops it at the section edge.
A section whose content fits clips instead of scrolling, so its sticky label passes outward and pins to the panel edge. The next section sets stickyContainment="always" and keeps its label in its own box.
A scrollable viewport is the containing block for position: sticky, so section labels pin to the top edge of the list instead of the page.
axis="both" gives the content box max-content inline sizing, so a board wider and taller than its panel scrolls on both axes from one viewport.
Flat table of uniform rows under a block of record-level facts, narrowed three ways at once — a full-text search box, a scope toggle, and per-column popovers — with sortable and filterable columns, per-row hover detail, and totals derived from the visible rows that flag themselves as partial while a filter is on. The shape for one homogeneous list, not nested rows or groups with their own columns.
Section is the correct way to create page regions and group related content on a page. Use it for settings groups, form sections, sidebar areas, or any time you need visual separation between parts of a page. If you are tempted to use a Card for a page section, use Section instead.
A default section stacked with a full-width muted section. Shows how muted draws attention to a specific region like an upgrade prompt or banner.
All three background variants stacked: section (default surface), muted, and transparent. A quick visual reference for choosing the right variant.
Adjacent sections separated by bottom dividers, like a settings page. Use dividers when stacking same-variant sections that need visual separation without a background change.
Container wrapper providing context (value, onChange, size, isDisabled) to SegmentedControlItem children.
Astryx showcase: SegmentedControl.
Segmented control with an individually disabled option for unavailable choices.
Segmented control that stretches segments equally to fill the available width, useful for fixed-width containers.
Compact segmented control with hidden labels, showing only icons for space-constrained layouts.
Individual segment item rendering as a radio button within the segmented control.
Segmented control items with text labels and icons, including a disabled item.
A row of label-only options that switches between a few views, here Board, List, and Timeline. Each item declares a value; the parent control holds the selected value and change handler.
Segmented control with icon and label pairs for a view mode switcher.
A card that toggles between selected and unselected states with an accent border. For navigation use ClickableCard.
A plan picker with single-select radio behavior. Cards show an accent border when selected.
Raised selectable cards with `elevation="low"`. The inset selection ring composes on top of the shadow, so a selected card keeps its elevation.
Multi-select tag picker using color variant selectable cards with color-matched selection borders.
Dropdown selector for choosing from a list of options.
Astryx showcase: Selector.
Presents a single-selection list in a bottom sheet for compact touch interfaces.
Selector with a clear button to reset the selected value.
Borderless Selector variant composed with ghost buttons in a toolbar.
Selector with options grouped into labeled sections.
Helper component for custom item rendering inside an Selector renderOption prop.
Selector with custom-rendered options using SelectorOption for icons and descriptions.
A selector whose options are rendered with SelectorOption, adding a secondary description below each label. Use inside renderOption for consistent custom option styling.
Options carry a description, so the dropdown draws a two-line row. The closed trigger is sized by padding, so it is the size token for a one-line value and exactly one line taller for a two-line one; both on the 4px rhythm. An InputGroup pins the row, so the value folds back onto one line there.
Selector showing error, warning, and success validation states.