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.
<tr> wrapper that reads TableContext to apply striped, hover, and divider styles when used inside Table.
Table with row selection checkboxes and a select-all header checkbox.
Selection-aware bulk-action surface built on Toolbar. Pass selectionState from useTableSelectionState so count, visibility, and complete clearing stay synchronized with the Table selection plugin. The component owns no table or sticky layout: place it in flow or apply caller-owned positioning through xstyle.
Table with sortable columns, click headers to sort ascending or descending.
Table with alternating row colors and hover highlighting for easy scanning.
Tab strip that provides TabListContext (value, onChange, size) to Tab and TabMenu children; a nav landmark, or the WAI-ARIA tabs pattern where role="tablist" asks for it.
Astryx showcase: TabList.
Tabs that stretch to fill the available width with a bottom divider.
Page header pattern with tabs on the left and action buttons pushed to the right. When hasDivider is true, match the Button size to the TabList size so the tabs and actions align to a shared baseline above the divider.
Tabs with notification badge counts rendered via endContent. Uses error variant for urgent counts and neutral for informational ones.
Tabs with leading icons alongside text labels.
Tab list with a dropdown menu for additional items that do not fit inline.
Tabs with status dot indicators rendered via endContent to show live environment health at a glance.
Overflow menu trigger that opens a dropdown of additional tab options, showing the selected option's label as the trigger text. Host attributes and DOM event handlers (id, aria-*, data-*, drag and drop) reach the trigger button, not the popup or its options. The button keeps its role, tab stop, and menu disclosure attributes.
TabMenu is an overflow menu within a TabList that groups additional tab options into a dropdown, showing the selected option's label as the trigger text.
An overflow menu at the end of a TabList that collects secondary tabs behind a dropdown. Use it when there are more tabs than fit comfortably inline.
A tab that changes its icon when selected.
Semantic body text component that renders text with type-based styling from the theme, with optional truncation, decoration, and layout props.
Astryx showcase: Text.
TextArea is a multi-line text input for collecting longer-form content like comments, descriptions, or messages. Use it when the expected input spans multiple lines. For shorter, single-line values, use TextInput.
A text area with placeholder text.
Textareas with maxLength and a live character counter. The counter turns red when the limit is exceeded.
Textareas with a leading icon that hints at the expected content, like a chat bubble for messages or a pencil for notes.
Required, disabled, and loading textareas side by side. Shows the interactive states the component supports.
All three status variants (error, warning, and success) with status messages, plus error without a message. Use to show inline validation feedback as the user types.
All text color options (primary, secondary, disabled, placeholder, active) applied to body text to show their intended use.
All 6 heading levels (h1 through h6) rendered with Heading to show the full type scale.
Mixing body and code text inline within a single line using the default inline display mode.
TextInput collects short-form text like names, emails, or search queries. Use it for single-line values where the expected input is brief. Pair it with validation status to guide users through required or formatted fields.
Astryx showcase: TextInput.
Inputs with a leading icon that hints at the expected content. Use when the icon helps users identify the field faster, like a lock for passwords or an envelope for email.
Search input with a hidden label, start icon, and clear button. Use for toolbar and header search bars where the icon provides sufficient context.
Small, medium, and large inputs side by side. Use small in dense UIs like table filters, medium for most forms, and large for prominent single-field pages.
Error, warning, and success validation states with status messages. Use to show users what went wrong and how to fix it.
The statusVariant prop controls whether the status message is attached to the bordered input (default, overlapping directly below) or detached from it (floating below as a separate element with spacing).
Text, password, and email types plus field-level features: tooltip, required, optional, description, disabled, and loading.
Single-line and multi-line text truncation with ellipsis using maxLines in a width-constrained container.
All 5 semantic text types (body, large, label, supporting, code) with their default styling from the theme.
The 4 font weight variants (normal, medium, semibold, bold) applied to body text.
Compares break-word and break-all word break modes on a long unbreakable string.
The 4 text-wrap modes (wrap, nowrap, balance, pretty) shown in width-constrained containers.
Wraps a subtree with a specific Astryx theme. For static production themes, use `astryx theme build` and import the generated CSS plus built theme object for first-paint and SSR performance. Use runtime `defineTheme()` when themes are dynamic or for prototyping. `defineTheme` accepts a `tokens` object whose keys are CSS custom property names (always prefixed with `--`). Common token names include `--color-accent`, `--color-background-surface`, `--color-background-body`, `--color-text-primary`, `--color-text-secondary`, `--radius-container`, `--spacing-1` through `--spacing-6`. Values can be a string (same for light/dark) or a `[light, dark]` tuple. Example: ```ts import {defineTheme} from '@astryxdesign/core/theme'; const myTheme = defineTheme({ name: 'ocean', tokens: { '--color-accent': ['#0077B6', '#48CAE4'], '--color-background-surface': ['#F0F8FF', '#0A1628'], '--color-text-primary': ['#0A1317', '#FFFFFF'], '--radius-container': '16px', }, }); ```
Wrap a subtree in Theme to apply a theme to every child component in that region.
Two visually distinct theme providers wrapping identical content to show how Theme changes the visual treatment of child components.
Nested Theme providers let a local region use a different theme without affecting the rest of the page.
Several unrelated product surfaces rendered together on one canvas so a token change can be judged across contexts at once. A comparison harness rather than a layout to ship.
Use state to switch the theme object passed to Theme and preview a different visual treatment.
Thumbnail displays a compact, square preview of an image attachment. It shows a shimmer effect while uploading, the image on success, and a placeholder icon when no source is set. Use it in chat composers, file upload lists, or anywhere you need a small image preview with optional remove and click actions.