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.
Menu items organized into titled sections for easy scanning. Use when you have 6+ actions that fall into distinct categories, like Create vs Manage.
A single menu row that reveals a nested flyout of its own items. The row adopts DropdownMenuItem semantics (label / icon / description / isDisabled); its children become the flyout content. Opens inline-end with viewport auto-flip; Right/Enter/Space opens and focuses the first item, Left/Escape closes and returns focus to the trigger (Right/Left swap in RTL). On a phone (a coarse pointer, decided when the menu opened) the row drills in instead: its rows replace the menu's rows in the same box, led by a Back row named "Back to <parent>", and Back, Escape or ArrowLeft return to the row. Host attributes and DOM event handlers (aria-*, data-*, id) reach the trigger row, the element carrying role="menuitem" and aria-haspopup="menu"; a caller's handlers run after the row's own, except for the keys that open the flyout (the open arrow, Enter, Space) and a click on a disabled row. For data-driven menus, give a menu item a nested `items` array instead of using this component directly.
Action menu with a nested submenu. Hover or Right arrow opens the flyout; Left arrow / Escape closes it. Use to group related destinations or secondary actions without crowding the top level.
Compose a Layout with DrawerHeader, the fields in LayoutContent, and Cancel and Save in a pinned LayoutFooter. purpose="form" keeps Escape but ignores scrim clicks, so a stray click outside does not discard edits.
EmptyState shows a placeholder when a content area has no data. Use it for empty lists, zero search results, first-time setups, or cleared inboxes. Always include a title and a next step so the user is not stuck.
A no-results empty state with an icon, descriptive message, and a call-to-action button.
Full empty state with icon, message, and action buttons. Use when a search returns no results, a filter clears all items, or a list has been emptied. The buttons give the user a way forward: go back, clear filters, or try a different query.
Smaller empty state with reduced spacing for constrained areas. Use inside sidebar panels, card widgets, or notification drawers where a full-size empty state would overwhelm the layout.
Empty state wrapped in a Card for first-time setup or onboarding. Use when the user has not created any items yet, like a project list, team roster, or dashboard widget that will fill with data once they take action.
Report-shaped analytics with a prose rail beside the charts: a scorecard of headline numbers with period deltas and status coloring, goal-attainment bars, a trend grid, and a written commentary column that folds beneath the content when narrow.
Low-level form field wrapper for custom controls that need a label, description, and optional/required indicators.
A form field wrapping a text input with a label, description, and validation status.
Fields with helper text below the label. Use descriptions to explain format requirements, constraints, or what happens with the data, like "At least 8 characters" or "We will send a confirmation link".
Standalone label group for one control or a caller-labelled group, with optional supporting text, optionality indicators, icon, and tooltip.
Standalone field labels demonstrating required, optional, tooltip, and icon variations.
Standalone labels with required and optional indicators and a helper description. Use when labeling a custom control that does not render its own label.
Required and optional field indicators side by side. Use isRequired on fields the user must fill in, and isOptional to clarify which fields can be skipped.
FieldStatus renders validation feedback for fields and field-like controls. Use it directly for custom controls that need the same error, warning, or success presentation as Field.
Field status messages in error, warning, and success states with attached and detached variants.
Detached error and success messages for validation feedback. Use below checkboxes, switches, or custom controls where an attached status would overlap.
All three validation states: error, warning, and success. Use error for invalid input, warning for potential issues like reserved names, and success to confirm valid entries like API keys.
Hierarchical browser that drills through nested levels as adjacent columns rather than replacing the list each time, with breadcrumb history, switchable list and grid density, and a metadata pane for the selected node.
FileInput provides file upload with optional drag-and-drop support. Use it for single or multiple file selection with built-in validation for file type, size, and count. Pair with validation status for upload feedback.
Astryx showcase: FileInput.
A controlled single-file upload with accepted types, a size limit, and helper text. Use for standard document upload fields in forms.
Flat row collection built around progressive filtering: a token bar that escalates into full query syntax, saved views that persist a filter set, column and grouping options, and a resizable detail pane.
A layout container that arranges form fields with consistent spacing and direction. FormLayout handles where fields go, not state or submission. Wrap it in a <form> for that. Supports vertical (default), horizontal, and horizontal-labels directions, and can be nested to mix them.
A vertical form layout with text input fields.
Two fields side by side for naturally paired inputs like first and last name
Form with different control types: text input, selector, and checkboxes
Address form mixing vertical and horizontal layouts for grouped fields
Settings form with labels placed beside their inputs
Linear multi-step form that moves through one panel at a time, with a horizontal progress track pinned above rather than running down a rail, so every step keeps the full content width for its fields. Only the current step renders, unlike an accordion where each section expands into one long scrolling form. Each advance is validated, and a step left broken stays flagged to jump back to.
Analytics for sequence and retention questions, pairing two shapes a plain dashboard cannot hold: a staged funnel where each step reads as drop-off against the one before, and a two-axis cohort matrix rendered as a heatmap.
Centered stack (headline, short blurb, call-to-action buttons) resolving into a multi-image photo grid rather than one wide full-bleed picture, so the imagery reads as a set.
Grid container with fixed or responsive columns; `{minWidth, max}` reflows, a number never does.
Astryx showcase: Grid.
Card gallery with responsive columns that maintain consistent widths
Grid with featured items spanning multiple columns and rows
Dashboard layout with mixed-size widgets and a full-width summary row
Grid item that spans multiple columns or rows.
GridSpan lets a grid item span multiple columns or rows within an Grid, enabling masonry-style and asymmetric layouts.
Grid items spanning two of three columns. Wrap a grid child in GridSpan to make it occupy multiple columns for asymmetric layouts.
Row collection bundled into collapsible sections with per-group counts, so a long list reads as a handful of blocks that expand and collapse. Query filtering and a resizable inspector for the selected row.
Semantic heading component that renders h1-h6 elements with themed styling, themed sizing via type scale tokens, and line-clamp truncation.
Astryx showcase: Heading.
Responsive card grid with truncated headings and descriptions for uniform layout
Real-world page layout demonstrating heading levels h1 through h3 with supporting text