# Faye UI
> Modular React UI framework. Version 0.1.0. The npm package is unpublished and unavailable. Documentation is published separately. Consult installation and verification for availability and limitations.
## Documentation
- [Faye UI](/markdown/overview.md): A modular React UI system. Quiet defaults, explicit contracts, complete customization paths.
- [Installation and first use](/markdown/installation.md): Install the single npm package, check release availability, and add Faye UI to your React application.
- [Functional coverage against Material UI](/markdown/material-ui-coverage.md): A function-level benchmark, verified features and concrete remaining gaps using Faye UI’s own implementation.
- [Example application: Faye Tasks](/markdown/example-app.md): Compose a task manager with the Faye UI package, native forms and browser-local recovery.
- [Interactive consumer experience](/markdown/consumer-experience.md): Plan a day with responsive navigation, labeled fields, radio descriptions, visible loading and purposeful transitions.
- [Consumer interactions and navigation](/markdown/functional-completion.md): Icon dismiss controls, queued feedback, marked sliders, responsive navigation and purposeful interactions.
- [Consumer application: Faye Places](/markdown/consumer-app.md): Discovery, saved places, collections, responsive sheets and resilient local interactions using the public package.
- [Packages and boundaries](/markdown/architecture.md): One public package with twenty-two private modules, explicit ownership and one-way dependencies.
- [Theme and color system](/markdown/theming.md): Generate complete palettes, switch schemes, scope brands, and preserve readable state colors.
- [Customization sheets](/markdown/customization.md): Typed component parts, variant conditions, defaults, and deterministic override layers.
- [Theme studio](/markdown/studio.md): Edit, inspect, export and re-import the actual theme contract.
- [Token reference and metrics](/markdown/tokens.md): Inspect every token and build spacing, breakpoints and fluid typography explicitly.
- [Accessibility and input behavior](/markdown/accessibility.md): Automatic focus guidance, optional keyboard hints, system preferences and explicit user controls.
- [Interoperability and migration](/markdown/interoperability.md): DTCG exchange, locale catalogs, design identity and reviewed migration.
- [Localization](/markdown/localization.md): Explicit English, Chinese, Korean and Japanese catalogs with fallback and review.
- [Server rendering and RSC](/markdown/server-rendering.md): Request-local configuration, stable initial markup, streaming assets and explicit client boundaries.
- [Client-only application](/markdown/client-rendering.md): A separate Next.js static export with an explicit client-only document boundary.
- [Optional runtime styling](/markdown/runtime-styles.md): Request-local collection, ownership-safe adoption, and explicit streaming constraints.
- [Atomic theme asset loading](/markdown/theme-assets.md): Prepare a trusted stylesheet, then commit identity and appearance together.
- [Extension packages](/markdown/extensions.md): Share system contracts without pulling data engines into the core.
- [Browser and interaction utilities](/markdown/utilities.md): Explicit client-only behavior, debouncing, media queries and outside-pointer handling.
- [LLM-friendly documentation](/markdown/machine-reading.md): Direct Markdown, API JSON, schemas and examples without browser execution.
- [Verification and limitations](/markdown/verification.md): Current package availability, supported checks and accessibility limitations.
- [Component reference](/markdown/component-reference.md): Search every documented public UI component, inspect its package entry, and jump to the real executable example that uses it.
- [All components gallery](/markdown/all-components.md): One visual QA route that renders every component-family example from the public documentation using the real Faye UI React components.
- [Typography and surfaces](/markdown/foundations.md): Semantic typography, surfaces, and server-safe rendering of explicitly imported Lucide and Faye icon artwork.
- [Layout primitives](/markdown/layout.md): Responsive grids, spacing, constraints, container boundaries and native columns.
- [Buttons and actions](/markdown/buttons.md): Variants, intent, sizing, pending states, composition and toggles.
- [Text fields and forms](/markdown/fields.md): Native form values, validation, adornments, multiline input and reset.
- [Advanced field compositions](/markdown/advanced-fields.md): Native forms, shared input frames, grouped selections, editable tags and asynchronous recovery in a themed dialog.
- [Cards, media and composed dialogs](/markdown/surface-compositions.md): Native independent card actions, interactive lists, packed media and consistent scrollable dialog anatomy.
- [Motion and interactive navigation](/markdown/interaction-compositions.md): Responsive mixed toolbar, scrollable tabs, interactive stepper and keyed content transitions.
- [Checkboxes, radios and switches](/markdown/selection.md): Selection groups with explicit controlled state and native labels.
- [Select and autocomplete](/markdown/pickers.md): Fixed choices, searchable selection and free-form suggestions.
- [Numeric and specialized input](/markdown/numeric.md): Number fields, sliders, one-time codes and fractional ratings.
- [Dialogs, modal and drawers](/markdown/dialogs.md): Focus-aware overlays, confirmation flows and logical-edge sheets.
- [Portals and floating content](/markdown/floating.md): Popover, tooltip, preview card, positioning, backdrop and explicit portal destinations.
- [Menus and contextual actions](/markdown/menus.md): Command lists, checked states, submenus and menubars.
- [Navigation and disclosure](/markdown/navigation.md): Tabs, accordions, toolbars, location, pagination and progress steps.
- [Feedback and status](/markdown/feedback.md): Alerts, inline and anchored badges, progress, loading and notifications.
- [Tables, lists and display](/markdown/display.md): Semantic tables, pagination, sorting affordances, avatars, image lists and timeline.
- [Motion and presence](/markdown/motion.md): Deliberate transitions, interruption, exit completion and reduced motion.
- [Application patterns](/markdown/patterns.md): Shells, page headers, forms, search, transfer lists and command palettes.
- [Asynchronous workflows](/markdown/async-workflows.md): Latest intent, request ownership, retry and retained drafts in a real application example.
- [@fayegram-ai/faye-ui/contracts](/markdown/api-contracts.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/contracts/accessibility](/markdown/api-contracts-accessibility.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/contracts/extend-descriptor](/markdown/api-contracts-extend-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/contracts/icon](/markdown/api-contracts-icon.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/contracts/interaction](/markdown/api-contracts-interaction.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/contracts/scope](/markdown/api-contracts-scope.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/contracts/visual-variants](/markdown/api-contracts-visual-variants.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls](/markdown/api-controls.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/autocomplete](/markdown/api-controls-autocomplete.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/autocomplete.descriptor](/markdown/api-controls-autocomplete-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/autosize-textarea](/markdown/api-controls-autosize-textarea.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/button](/markdown/api-controls-button.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/button.descriptor](/markdown/api-controls-button-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/checkbox](/markdown/api-controls-checkbox.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/checkbox-group](/markdown/api-controls-checkbox-group.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/checkbox.descriptor](/markdown/api-controls-checkbox-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/chip](/markdown/api-controls-chip.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/chip.descriptor](/markdown/api-controls-chip-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/combobox](/markdown/api-controls-combobox.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/combobox.descriptor](/markdown/api-controls-combobox-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/field](/markdown/api-controls-field.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/field-layout](/markdown/api-controls-field-layout.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/field.descriptor](/markdown/api-controls-field-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/fieldset](/markdown/api-controls-fieldset.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/fieldset.descriptor](/markdown/api-controls-fieldset-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/form](/markdown/api-controls-form.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/input](/markdown/api-controls-input.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/input-group](/markdown/api-controls-input-group.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/input-group.descriptor](/markdown/api-controls-input-group-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/input.descriptor](/markdown/api-controls-input-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/link](/markdown/api-controls-link.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/native-select](/markdown/api-controls-native-select.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/native-select.descriptor](/markdown/api-controls-native-select-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/number-field](/markdown/api-controls-number-field.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/number-field.descriptor](/markdown/api-controls-number-field-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/otp-field](/markdown/api-controls-otp-field.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/otp-field.descriptor](/markdown/api-controls-otp-field-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/radio](/markdown/api-controls-radio.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/radio-group](/markdown/api-controls-radio-group.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/radio.descriptor](/markdown/api-controls-radio-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/rating](/markdown/api-controls-rating.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/rating-model](/markdown/api-controls-rating-model.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/rating.descriptor](/markdown/api-controls-rating-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/select](/markdown/api-controls-select.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/select.descriptor](/markdown/api-controls-select-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/slider](/markdown/api-controls-slider.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/slider.descriptor](/markdown/api-controls-slider-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/switch](/markdown/api-controls-switch.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/switch.descriptor](/markdown/api-controls-switch-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/text-field](/markdown/api-controls-text-field.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/textarea-field](/markdown/api-controls-textarea-field.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/textarea.descriptor](/markdown/api-controls-textarea-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/toggle](/markdown/api-controls-toggle.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/controls/toggle-group](/markdown/api-controls-toggle-group.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/core](/markdown/api-core.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/core/box](/markdown/api-core-box.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/core/card.descriptor](/markdown/api-core-card-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/core/code](/markdown/api-core-code.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/core/heading.descriptor](/markdown/api-core-heading-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/core/icon](/markdown/api-core-icon.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/core/profile](/markdown/api-core-profile.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/core/scoped-baseline](/markdown/api-core-scoped-baseline.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/core/scoped-baseline.descriptor](/markdown/api-core-scoped-baseline-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/core/separator](/markdown/api-core-separator.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/core/surface](/markdown/api-core-surface.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/core/surface.descriptor](/markdown/api-core-surface-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/core/text](/markdown/api-core-text.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/core/text.descriptor](/markdown/api-core-text-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/core/unstyled](/markdown/api-core-unstyled.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/core/utils](/markdown/api-core-utils.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/core/visually-hidden](/markdown/api-core-visually-hidden.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/devtools](/markdown/api-devtools.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/devtools/design-exchange](/markdown/api-devtools-design-exchange.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/devtools/figma](/markdown/api-devtools-figma.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/devtools/inspector](/markdown/api-devtools-inspector.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/devtools/sheet-editor](/markdown/api-devtools-sheet-editor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/devtools/theme-editor](/markdown/api-devtools-theme-editor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/devtools/theme-model](/markdown/api-devtools-theme-model.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/display](/markdown/api-display.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/display/avatar](/markdown/api-display-avatar.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/display/avatar-group](/markdown/api-display-avatar-group.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/display/avatar-group-model](/markdown/api-display-avatar-group-model.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/display/avatar-group.descriptor](/markdown/api-display-avatar-group-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/display/avatar.descriptor](/markdown/api-display-avatar-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/display/image-list](/markdown/api-display-image-list.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/display/image-list.descriptor](/markdown/api-display-image-list-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/display/list](/markdown/api-display-list.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/display/list.descriptor](/markdown/api-display-list-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/display/packed-masonry](/markdown/api-display-packed-masonry.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/display/packed-masonry.descriptor](/markdown/api-display-packed-masonry-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/display/scroll-area](/markdown/api-display-scroll-area.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/display/scroll-area.descriptor](/markdown/api-display-scroll-area-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/display/table](/markdown/api-display-table.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/display/table-controls](/markdown/api-display-table-controls.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/display/table-pagination-model](/markdown/api-display-table-pagination-model.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/display/table-pagination.descriptor](/markdown/api-display-table-pagination-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/display/table-sort-label.descriptor](/markdown/api-display-table-sort-label-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/display/timeline](/markdown/api-display-timeline.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/display/timeline-item.descriptor](/markdown/api-display-timeline-item-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/display/timeline.descriptor](/markdown/api-display-timeline-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/example-extension](/markdown/api-example-extension.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/example-extension/activity.manifest](/markdown/api-example-extension-activity-manifest.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/example-extension/assets](/markdown/api-example-extension-assets.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/example-extension/unstyled](/markdown/api-example-extension-unstyled.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/extensions](/markdown/api-extensions.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/feedback](/markdown/api-feedback.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/feedback/alert](/markdown/api-feedback-alert.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/feedback/alert.descriptor](/markdown/api-feedback-alert-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/feedback/badge](/markdown/api-feedback-badge.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/feedback/badge-indicator](/markdown/api-feedback-badge-indicator.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/feedback/badge-indicator.descriptor](/markdown/api-feedback-badge-indicator-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/feedback/badge.descriptor](/markdown/api-feedback-badge-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/feedback/circular-progress](/markdown/api-feedback-circular-progress.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/feedback/circular-progress.descriptor](/markdown/api-feedback-circular-progress-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/feedback/loading](/markdown/api-feedback-loading.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/feedback/loading.descriptor](/markdown/api-feedback-loading-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/feedback/meter](/markdown/api-feedback-meter.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/feedback/meter.descriptor](/markdown/api-feedback-meter-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/feedback/progress](/markdown/api-feedback-progress.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/feedback/progress.descriptor](/markdown/api-feedback-progress-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/feedback/toast](/markdown/api-feedback-toast.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/feedback/toast.descriptor](/markdown/api-feedback-toast-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/hooks](/markdown/api-hooks.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/hooks/click-away](/markdown/api-hooks-click-away.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/hooks/client-only](/markdown/api-hooks-client-only.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/hooks/outside-press](/markdown/api-hooks-outside-press.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/hooks/scroll-trigger](/markdown/api-hooks-scroll-trigger.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/icons](/markdown/api-icons.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/icons/faye-mark](/markdown/api-icons-faye-mark.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/integrations](/markdown/api-integrations.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/integrations/bootstrap](/markdown/api-integrations-bootstrap.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/integrations/deferred-assets](/markdown/api-integrations-deferred-assets.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/integrations/react](/markdown/api-integrations-react.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/layout](/markdown/api-layout.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/layout/grid-item](/markdown/api-layout-grid-item.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/layout/grid-item.descriptor](/markdown/api-layout-grid-item-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/layout/layout](/markdown/api-layout-layout.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/layout/masonry](/markdown/api-layout-masonry.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/layout/masonry.descriptor](/markdown/api-layout-masonry-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/layout/responsive](/markdown/api-layout-responsive.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/motion](/markdown/api-motion.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/motion/presence](/markdown/api-motion-presence.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/motion/timing](/markdown/api-motion-timing.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/motion/transition-group](/markdown/api-motion-transition-group.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/navigation](/markdown/api-navigation.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/navigation/accordion](/markdown/api-navigation-accordion.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/navigation/accordion.descriptor](/markdown/api-navigation-accordion-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/navigation/breadcrumbs](/markdown/api-navigation-breadcrumbs.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/navigation/breadcrumbs.descriptor](/markdown/api-navigation-breadcrumbs-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/navigation/collapsible](/markdown/api-navigation-collapsible.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/navigation/collapsible.descriptor](/markdown/api-navigation-collapsible-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/navigation/menubar](/markdown/api-navigation-menubar.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/navigation/menubar.descriptor](/markdown/api-navigation-menubar-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/navigation/mobile-stepper](/markdown/api-navigation-mobile-stepper.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/navigation/mobile-stepper.descriptor](/markdown/api-navigation-mobile-stepper-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/navigation/navigation-menu](/markdown/api-navigation-navigation-menu.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/navigation/navigation-menu.descriptor](/markdown/api-navigation-navigation-menu-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/navigation/pagination](/markdown/api-navigation-pagination.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/navigation/pagination-model](/markdown/api-navigation-pagination-model.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/navigation/pagination.descriptor](/markdown/api-navigation-pagination-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/navigation/stepper](/markdown/api-navigation-stepper.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/navigation/stepper.descriptor](/markdown/api-navigation-stepper-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/navigation/tabs](/markdown/api-navigation-tabs.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/navigation/tabs.descriptor](/markdown/api-navigation-tabs-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/navigation/toolbar](/markdown/api-navigation-toolbar.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/navigation/toolbar.descriptor](/markdown/api-navigation-toolbar-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/nextjs](/markdown/api-nextjs.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/overlays](/markdown/api-overlays.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/overlays/alert-dialog](/markdown/api-overlays-alert-dialog.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/overlays/alert-dialog.descriptor](/markdown/api-overlays-alert-dialog-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/overlays/backdrop](/markdown/api-overlays-backdrop.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/overlays/context-menu](/markdown/api-overlays-context-menu.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/overlays/context-menu.descriptor](/markdown/api-overlays-context-menu-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/overlays/dialog](/markdown/api-overlays-dialog.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/overlays/dialog.descriptor](/markdown/api-overlays-dialog-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/overlays/drawer](/markdown/api-overlays-drawer.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/overlays/interaction-hint](/markdown/api-overlays-interaction-hint.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/overlays/menu](/markdown/api-overlays-menu.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/overlays/menu.descriptor](/markdown/api-overlays-menu-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/overlays/modal](/markdown/api-overlays-modal.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/overlays/popover](/markdown/api-overlays-popover.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/overlays/popover.descriptor](/markdown/api-overlays-popover-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/overlays/popper](/markdown/api-overlays-popper.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/overlays/popper.descriptor](/markdown/api-overlays-popper-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/overlays/portal](/markdown/api-overlays-portal.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/overlays/preview-card](/markdown/api-overlays-preview-card.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/overlays/preview-card.descriptor](/markdown/api-overlays-preview-card-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/overlays/swipe-drawer](/markdown/api-overlays-swipe-drawer.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/overlays/swipe-drawer.descriptor](/markdown/api-overlays-swipe-drawer-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/overlays/tooltip](/markdown/api-overlays-tooltip.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/overlays/tooltip.descriptor](/markdown/api-overlays-tooltip-descriptor.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/patterns](/markdown/api-patterns.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/patterns/accessibility-preferences](/markdown/api-patterns-accessibility-preferences.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/patterns/application-navigation](/markdown/api-patterns-application-navigation.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/patterns/collapsed-breadcrumbs](/markdown/api-patterns-collapsed-breadcrumbs.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/patterns/command-palette](/markdown/api-patterns-command-palette.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/patterns/content](/markdown/api-patterns-content.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/patterns/floating-actions](/markdown/api-patterns-floating-actions.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/patterns/navigation-drawer](/markdown/api-patterns-navigation-drawer.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/patterns/search-field](/markdown/api-patterns-search-field.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/patterns/shell](/markdown/api-patterns-shell.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/patterns/toaster](/markdown/api-patterns-toaster.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/patterns/transfer-list](/markdown/api-patterns-transfer-list.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/provider](/markdown/api-provider.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/provider/computed-tokens](/markdown/api-provider-computed-tokens.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/provider/configuration](/markdown/api-provider-configuration.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/provider/configuration-utils](/markdown/api-provider-configuration-utils.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/provider/document-theme](/markdown/api-provider-document-theme.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/provider/locale-en](/markdown/api-provider-locale-en.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/provider/locale-ja](/markdown/api-provider-locale-ja.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/provider/locale-ko](/markdown/api-provider-locale-ko.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/provider/locale-zh-hans](/markdown/api-provider-locale-zh-hans.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/provider/locale-zh-hant](/markdown/api-provider-locale-zh-hant.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/provider/messages](/markdown/api-provider-messages.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/provider/parts](/markdown/api-provider-parts.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/provider/preferences](/markdown/api-provider-preferences.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/provider/profiles](/markdown/api-provider-profiles.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/provider/provider](/markdown/api-provider-provider.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/runtime-styles](/markdown/api-runtime-styles.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/runtime-styles/react](/markdown/api-runtime-styles-react.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/runtime-styles/registry](/markdown/api-runtime-styles-registry.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/runtime-styles/server](/markdown/api-runtime-styles-server.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/runtime-styles/stream-dom](/markdown/api-runtime-styles-stream-dom.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/runtime-styles/styled](/markdown/api-runtime-styles-styled.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/styles](/markdown/api-styles.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/theme](/markdown/api-theme.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/theme/asset-controller](/markdown/api-theme-asset-controller.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/theme/assets](/markdown/api-theme-assets.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/theme/audit](/markdown/api-theme-audit.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/theme/brand](/markdown/api-theme-brand.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/theme/color](/markdown/api-theme-color.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/theme/contexts](/markdown/api-theme-contexts.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/theme/css-values](/markdown/api-theme-css-values.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/theme/dtcg](/markdown/api-theme-dtcg.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/theme/metrics](/markdown/api-theme-metrics.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/theme/migration](/markdown/api-theme-migration.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/theme/named-colors](/markdown/api-theme-named-colors.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/tokens](/markdown/api-tokens.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/tokens/contract](/markdown/api-tokens-contract.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/tokens/default-theme](/markdown/api-tokens-default-theme.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/tokens/scales](/markdown/api-tokens-scales.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
- [@fayegram-ai/faye-ui/tokens/typography](/markdown/api-tokens-typography.md): Public exports and dependency-resolved component properties, with usage and rendering guidance.
## Machine resources
- [Complete text](/llms-full.txt)
- [API index](/api/index.json)
- [Tokens](/api/tokens.json)
- [Theme capabilities](/api/theme-capabilities.json)
- [Visual variants](/api/visual-variants.json)
- [Component reference](/api/components.json)
- [All public entries](/api/public-entries.json)
- [Example dispositions](/api/component-dispositions.json)
- [Example coverage](/api/coverage.json)
- [Schemas](/schemas/index.json)
# Faye UI
A modular React UI system. Quiet defaults, explicit contracts, complete customization paths.
## What this system is
Faye UI is designed for one npm package, `@fayegram-ai/faye-ui`, with modular import paths. The interaction foundation is Base UI. Faye UI owns its tokens, visual components, customization contracts, layout vocabulary, rendering integrations and extension seams.
The default design favors clear type, thin borders, restrained radii and limited elevation. The visual language is independent of Material Design. Material UI is a capability reference, not an API or appearance to reproduce.
## Explore the system
Use **Theme** in the top navigation to preview a different primary palette or custom color, light/dark mode, density and text direction.
Try the [interactive consumer experience](/docs/consumer-experience/) first: a responsive sidebar, labeled forms, radio choices, loading indicators, fade/slide transitions and a saved itinerary in one working composition.
Start with [installation](/docs/installation/), then [theming](/docs/theming/), [customization sheets](/docs/customization/) and [layout](/docs/layout/). Every component-family page includes actual React imports and downloadable example source. The [component reference](/docs/component-reference/) indexes every documented JSX component by public import path, while the [all-components gallery](/docs/all-components/) combines component-family examples for exploration and theme comparison.
## Two real application architectures
The SSR edition uses request-rendered Next.js pages and client islands for interaction. The CSR edition uses a static Next.js export with an explicit client-only document boundary. Static export alone does not imply client-only rendering.
Both applications share the same source corpus and example modules. They publish Markdown, API JSON and an LLM index independently of JavaScript.
## Release status
**The npm package is not ready for release.** The `0.1.0` publication was withdrawn on October 23, 2026, and the package is currently unavailable from npm. These guides preview the implemented API. See [installation](/docs/installation/) for availability and [verification](/docs/verification/) for supported checks and limitations.
See [functional coverage against Material UI](/docs/material-ui-coverage/) for the current comparison and scope boundaries.
---
# Installation and first use
Install the single npm package, check release availability, and add Faye UI to your React application.
## Install Faye UI from npm
Faye UI is packaged as one npm package, `@fayegram-ai/faye-ui`. Its component families, tokens, themes and integrations are import paths within that package. Component families are subpaths of that single install.
**Publication status: unpublished and not ready for release.** The `0.1.0` publication was withdrawn on October 23, 2026. The package is currently unavailable from npm. The command below describes installation after a corrected release becomes available; it does not work today. Documentation previews do not establish package availability.
Run this in your React application after publication:
```bash
npm install @fayegram-ai/faye-ui
```
A published package will not require GitHub access, repository cloning or a local library build. Package distribution is through npm. The official documentation address is [faye-ui.fayegram.com](https://faye-ui.fayegram.com/). Package support information will be announced with a corrected npm release.
## Requirements
Use Node.js 22.12 or later and React / React DOM 19.3 compatible with the declared `^19.3.0` peer ranges. The package installs its Base UI, Floating UI and raw Lucide dependencies automatically. Next.js is an optional peer (`^16.4.2`) for the Next integration; ordinary React applications do not need it.
## Component consumption
```tsx
'use client';
import '@fayegram-ai/faye-ui/tokens/layers.css';
import '@fayegram-ai/faye-ui/tokens/reset.css';
import '@fayegram-ai/faye-ui/tokens/theme.css';
import { FayeUIProvider } from '@fayegram-ai/faye-ui/provider/provider';
import { Button } from '@fayegram-ai/faye-ui/controls/button';
export function Application() {
return ;
}
```
Import the layer prelude and theme once at your application boundary. Component entry points import their own styles. The global reset is opt-in; embedded applications can use ScopedBaseline instead.
## Product namespace
The npm scope identifies the organization; `faye-ui` identifies this UI product. UI-owned styles, state and rendering integrations use the full product namespace:
| Contract | Identifier |
|---|---|
| Root CSS class | `.faye-ui-root` |
| CSS custom properties | `--faye-ui-*` |
| Theme scope attributes | `data-faye-ui-theme`, `data-faye-ui-scheme`, `data-faye-ui-density` |
| JavaScript DOM dataset access | `element.dataset.fayeUiTheme` |
| Docs color preference cookie | `faye-ui.docs.preference` |
| CSS cascade layers | `faye-ui.tokens`, `faye-ui.components`, `faye-ui.local` |
| Default theme ID | `faye-ui` |
| Native Node SSR condition | `--conditions=faye-ui-ssr` |
Organization artwork retains its own identity, such as `FayeMark`. Component families, themes and rendering integrations are module paths inside the one public package.
## Release status
See [verification](/docs/verification/) for the implementation's current checks and limits. Publishing the documentation and publishing the npm package are separate steps. The package currently declares an MIT license; repository visibility and package licensing are separate properties.
---
# Functional coverage against Material UI
A function-level benchmark, verified features and concrete remaining gaps using Faye UI’s own implementation.
## Functional benchmark
Faye UI uses its own implementation. The benchmark is the functions an application can deliver: selection, fields, feedback, overlays, navigation, layout, themes and transitions. Matching Material styling or prop names is not required.
## Current coverage
The functional audit reviewed 58 official component-guide pages from Material UI 9.5.0. Faye UI has implementations for all reviewed families, with public modular imports from one package. Broad coverage is not a declaration of complete functional parity.
Notifications now support semantic types, actions, six placements, timeout/pause, visible limits, keyboard dismissal and transitions. Shared fields cover persistent labels, hints/errors, adornments, validation and autosizing. Cards/lists/media, progress modes, four-edge dialogs/drawers, grouped actions, steppers, tabs, responsive layouts and motion have concrete implementations and behavioral examples. See [feedback](/docs/feedback/), [advanced fields](/docs/advanced-fields/), [surface compositions](/docs/surface-compositions/), [interactive consumer experience](/docs/consumer-experience/) and [motion](/docs/motion/).
## Completed reference functions
The follow-up implementation closes the eight ordinary core compositions and additional MUI Lab timeline layout identified by the audit. See [consumer interactions and navigation](/docs/functional-completion/) for the APIs, working examples and behavior boundaries.
| Function | Faye UI implementation |
| --- | --- |
| Named marks, restricted nonuniform values and nonlinear scales | Slider.Marks, Slider.DiscreteRoot, scale and formatValue |
| FIFO notifications after exit and optional click-away | useToastQueue and Toaster.dismissOnClickAway |
| Persistent/content-pushing and mini navigation | NavigationDrawer, with a responsive modal sheet |
| Hidden breadcrumb path expansion | CollapsedBreadcrumbs with Menu links and focus return |
| Scroll-aware navigation | useScrollTrigger, ScrollAppBar, reduced-motion back-to-top |
| Controlled, hover and directional quick actions | FloatingActions with configurable trigger and popup parts |
| Touch long-press tooltip activation | TouchTooltip, preserving normal tap behavior |
| All badge corners and circular overlap | BadgeIndicator position and overlap variants |
| Alternating and opposite-content timelines | Timeline position and TimelineItem.opposite |
Dialog, drawer, popover, swipe drawer and notification dismiss controls now default to localized icon buttons. Explicit text/content/render overrides remain available. Functional parity refers to delivered behavior within this reviewed scope; matching APIs or artwork is unnecessary. Qualification results are recorded separately from the implementation ledger.
## Themes and customization
The [theme system](/docs/theming/) supports semantic accent, secondary, information, success, warning and danger palettes; light/dark/system, brands, density, typography, spacing, shape, elevation, motion, nested scopes, RTL and additional named axes. [Customization](/docs/customization/) covers per-part profiles, variants and component defaults. [Theme studio](/docs/studio/) uses the actual contract/compiler.
Specialist grids, charts, advanced date/time, virtualization, rich text and data engines remain separate extension scope. These boundaries do not waive missing ordinary UI functions. Tests and [verification](/docs/verification/) describe executed coverage; universal accessibility or device certification is not claimed.
---
# Example application: Faye Tasks
Compose a task manager with the Faye UI package, native forms and browser-local recovery.
## A real small application
Faye Tasks is a browser-local task manager built with Faye UI. It demonstrates selected public controls, native forms, typography, icons, dialogs, provider preferences and feedback. Task state and persistence belong to the application; no data engine is added to the library.
## Explore the application patterns
Read the example source below to see how to compose the components in your own application. Install Faye UI through npm once a corrected release is available; [installation](/docs/installation/) records its current status. Access to the private Faye UI repository is not a requirement for using the published package.
| Flow | Faye UI responsibility | Application responsibility |
|---|---|---|
| Create and edit | Named native controls and dialog behavior | Trimmed title validation and task updates |
| Complete | Checkbox state and keyboard semantics | Stored completion value |
| Delete | Confirmation dialog and focus behavior | Remove the selected record and choose surviving focus |
| Filter | Search input and native select | Filter current records |
| Persistence | Warning feedback and actions | Validate versioned data, retain memory on failure, explicit reset |
| Appearance | Theme/provider, tokens and shared Icon | Select density/direction and explicit artwork |
## Read the actual source
[Application](/examples/task-app/src/app.tsx), [task model](/examples/task-app/src/tasks.ts), [client entry](/examples/task-app/src/main.tsx), [styles](/examples/task-app/src/styles.css), [manifest](/examples/task-app/package.json), [TypeScript configuration](/examples/task-app/tsconfig.json), [Vite configuration](/examples/task-app/vite.config.ts) and [setup/limitations](/examples/task-app/README.md) are copied from the real application, not a second illustrative implementation.
## Package usage
The example imports the same public package paths documented for application developers. The standalone example uses normal package dependencies, with no source aliases. The package must be available from npm before installing the example.
## Deliberate limits
The app is CSR, uses English copy and persists in one browser. Invalid stored data is retained until explicit confirmed reset. Failed writes preserve in-memory changes but cannot guarantee persistence after closing the tab. There is no backend, cross-tab conflict resolution, authentication, deployment or publication. Five-language library examples and SSR/streaming/RSC consumers remain separate documented contracts.
---
# Interactive consumer experience
Plan a day with responsive navigation, labeled fields, radio descriptions, visible loading and purposeful transitions.
## Try the journey
Plan a day, choose your pace, and create an itinerary. Clear the name and submit to see the error beside the persistent label and hint. Create a valid day to see circular and linear progress, a busy button, and a sliding confirmation. Cancel while loading to retain the draft. Hide or show the landscape for a fade, and navigate to the itinerary and back without losing your edits.
The sidebar becomes a horizontal navigation area on small screens. The preview uses the active documentation theme, density, text direction and reduced-motion preference. Open the accordion and its dialog to inspect longer titles and header spacing.
## Components and ownership
This example imports the public package: layout, surfaces, advanced text fields, radio groups with `ControlLabel`, loading feedback, accordion, dialog, and motion primitives. `ControlLabel` aligns its control with the first label line and exposes the hint as an accessible description. Spread its callback attributes onto the control.
Application code owns the temporary itinerary and a cancelable local preparation timer. Nothing is booked, no server is contacted, and data lasts only while this example is mounted. [Faye Places](/docs/consumer-app/) is the separate full application with on-device persistence, discovery, saved collections and responsive drawers.
## Source
The complete React example is below. Its small [layout stylesheet](/examples/consumer-experience.css) arranges the responsive sidebar and content; component appearance and interaction come from Faye UI.
## Executable example source
```tsx
'use client';
import { useEffect, useId, useRef, useState } from 'react';
import { ArrowLeft, ArrowRight, Bookmark, Check, Compass, Info, Leaf, MapPin, Search, X } from '@lucide/icons';
import { Icon } from '@fayegram-ai/faye-ui/core/icon';
import { Heading, Text } from '@fayegram-ai/faye-ui/core/text';
import { Card, CardBody, CardHeader, CardTitle, CardDescription, CardMedia } from '@fayegram-ai/faye-ui/core/surface';
import { Stack, Inline, Grid } from '@fayegram-ai/faye-ui/layout/layout';
import { Button, IconButton } from '@fayegram-ai/faye-ui/controls/button';
import { TextField } from '@fayegram-ai/faye-ui/controls/text-field';
import { TextareaField } from '@fayegram-ai/faye-ui/controls/textarea-field';
import { ControlLabel } from '@fayegram-ai/faye-ui/controls/field-layout';
import { Radio } from '@fayegram-ai/faye-ui/controls/radio';
import { RadioGroup } from '@fayegram-ai/faye-ui/controls/radio-group';
import { Accordion } from '@fayegram-ai/faye-ui/navigation/accordion';
import { Badge } from '@fayegram-ai/faye-ui/feedback/badge';
import { CircularProgress } from '@fayegram-ai/faye-ui/feedback/circular-progress';
import { LinearProgress } from '@fayegram-ai/faye-ui/feedback/progress';
import { Fade, Slide } from '@fayegram-ai/faye-ui/motion/presence';
import { TransitionGroup } from '@fayegram-ai/faye-ui/motion/transition-group';
import { PageHeader, EmptyState } from '@fayegram-ai/faye-ui/patterns/content';
import { Modal } from '@fayegram-ai/faye-ui/overlays/modal';
import './consumer-experience.css';
const landscape = `data:image/svg+xml,${encodeURIComponent('')}`;
type Plan = { name: string; notes: string; pace: string };
export default function ConsumerExperience() {
const id = useId(), nameInput = useRef(null), heading = useRef(null);
const [view, setView] = useState('plan'), [name, setName] = useState('Sunday by the water'), [notes, setNotes] = useState('Leave time for a good coffee.'), [pace, setPace] = useState('slow');
const [error, setError] = useState(''), [pending, setPending] = useState(false), [progress, setProgress] = useState(0), [saved, setSaved] = useState(null), [preview, setPreview] = useState(true), [details, setDetails] = useState(false);
const timer = useRef | null>(null), request = useRef(0);
const cancel = () => { request.current++; if (timer.current) clearInterval(timer.current); timer.current = null; setPending(false); };
useEffect(() => () => { if (timer.current) clearInterval(timer.current); }, []);
const navigate = (next: string) => { setView(next); requestAnimationFrame(() => heading.current?.focus()); };
return
{view === 'plan' ? 'Make a little room for wonder.' : 'Your next small adventure.'}
{view === 'plan' ?
What happens when I create my day?Your choices become a small itinerary in this preview. Nothing is booked or sent to a server.About this preview} title="A little space for your plans" description="Explore at your own pace." footer={}>This example keeps your draft during navigation and shows validation, cancelable loading, a fading preview and a sliding confirmation. It stores nothing after this page is closed. : {saved ? <>{[[MapPin, 'By the water', saved.pace === 'slow' ? 'A gentle riverside stroll.' : 'Take the longer hill trail.'], [Leaf, 'A moment to pause', 'Coffee, a good view, and no hurry.']].map(([icon, title, description]) => {String(title)}{String(description)})}> : } title="A little room for a new plan" description="Choose a pace and a name, then keep your ideas together." action={}/>}}
;
}
```
---
# Consumer interactions and navigation
Icon dismiss controls, queued feedback, marked sliders, responsive navigation and purposeful interactions.
## Purpose and composition
These examples use the public Faye UI package to deliver the remaining ordinary UI functions from the Material UI comparison. The implementation and APIs belong to Faye UI. Explore the interactive weekend example below with keyboard, pointer, and touch.
## Common dismiss controls
`Dialog.Close`, `Drawer.Close`, `Popover.Close`, `AlertDialog.Close`, `SwipeDrawer.Close`, and `Toast.Close` supply an X icon and a localized accessible name when no content is supplied. Their default frames are square, with a 44px touch target on coarse pointers. Supply `aria-label` for a context-specific name, `children` for text or custom artwork, or `render` for a custom control. Provider part settings, refs, events and class/style overrides continue to apply. `Modal.closeProps` exposes that same configurable control. Footer actions such as “Done” remain explicit text actions.
## Sliders with marks and restricted values
`Slider.Marks` belongs inside `Slider.Control`, alongside the track. Each mark has a numeric `value` and an optional `label`. Marks are decorative; give every thumb an accessible name. `Slider.Root.scale` and `formatValue` transform displayed and announced values while forms submit the raw numeric value. A nonlinear example maps raw exponents to storage sizes.
`Slider.DiscreteRoot` accepts an ascending `allowedValues` array and scalar or range values. Its physical positions follow the numeric domain, including uneven gaps. Arrow keys advance to the next allowed value; Home/End and pointer interaction respect the domain. Forms submit actual values. It supports controlled/uncontrolled values, disabled state, orientation, styles and refs. `minStepsBetweenValues` counts allowed choices between range thumbs. This restricted composition uses non-crossing thumbs; use ordinary `Slider.Root` when push/swap behavior is required. Uncontrolled native form reset restores `defaultValue`, including canceled-reset handling. Controlled resets remain application-owned.
## Consecutive notifications
Call `useToastQueue` inside `Toast.Provider`, then enqueue normal toast options. Only one queued notification enters the provider at a time. The next enters after the previous is removed, including its exit transition. Pending messages have no running timeout. `clear()` discards pending messages and closes the active one; `pendingCount` reports waiting messages. IDs must be unique among queued messages. Use a dedicated provider for an independent queue. `Toaster.dismissOnClickAway` is an explicit optional policy; its default is false. It dismisses one visible notification on a primary outside press without canceling that interaction. Avoid click-away for messages requiring an explicit decision.
## Navigation and layouts
`NavigationDrawer` pushes content on desktop and switches to a modal drawer below 48rem. `mode="mini"` retains `miniNavigation` when collapsed. Supply accessible icon links for the mini rail. Logical `edge` follows RTL. The application owns `open`; closing returns focus to the toggle. Its viewport subscription and portal use the provider document, including an embedded document. Mobile and desktop trigger/close props are configurable separately. Widths can be overridden with `--_navigation-width` and `--_mini-width`. Its responsive threshold is shared by its CSS and media-query subscription.
`CollapsedBreadcrumbs` keeps leading/trailing items and puts hidden ancestors in a keyboard-operated menu. `maxItems`, `beforeCollapse`, `afterCollapse`, separator, accessible labels, profiles and normal navigation props are configurable. Escape returns focus to the expansion control. Hidden items retain actual links; path segments without links are descriptive disabled menu items.
`useScrollTrigger` observes the window or a stable mounted `targetRef`. It reports offset, direction, threshold crossing and a hysteresis-aware trigger. Compose `ScrollAppBar` with `hidden={triggered}` and `elevated={scrolled}`. Focus within reveals the bar. `scrollToTop()` respects operating-system reduced motion and a Faye UI theme's zero-duration motion policy; its optional `reducedMotion` flag also supports custom policies outside a Faye UI theme. Subscriptions and animation frames clean up on unmount.
`FloatingActions` exposes controlled/default open state, hover activation, logical/vertical direction, disabled actions and trigger/positioner/popup props. Its default launcher uses an icon button whose plus rotates into a close mark while open. The short transition respects system and provider reduced-motion preferences; custom trigger artwork supplied through triggerProps.children keeps its own behavior. Horizontal docks preserve readable action widths and scroll when constrained. Keyboard navigation brings the focused action into view, and pointer/touch scrolling remains available. Menu owns keyboard navigation, dismissal and focus restoration. `items[].icon` supplies decorative artwork independently from labels. Direction changes keyboard orientation; radial artwork is not required for these functions.
## Touch, badges and timelines
`TouchTooltip` adds long-press activation to the same tooltip hover/focus/Escape/outside-dismissal model. A normal tap activates the child control; a completed hold previews its description and suppresses the following activation. Movement beyond tolerance, pointer cancellation and leaving the trigger cancel a hold. Delay, release timeout, tolerance, controlled state, disabled state and part props are configurable. Essential instructions should always remain visible elsewhere.
`BadgeIndicator.position` accepts all logical corners; legacy `start`/`end` retain their top-corner meaning. `overlap="circular"` moves the indicator inward along round artwork. Counts, dots, maximums and accessible labels retain their existing behavior.
`Timeline.position` supports start/end, alternate and alternate-reverse sides. `TimelineItem.opposite` adds metadata opposite the entry. Narrow containers reflow to one readable column without changing DOM reading order. Timestamp semantics and custom markers remain available. Timeline is an additional MUI Lab comparison.
## Verification boundary
Functional tests exercise actual interactions and form/focus behavior. Visual review covers theme, density, RTL, narrow layouts, long headings and icon frames. Linux browser qualification does not certify every physical device or assistive-technology combination. Specialist grid/chart/date engines remain separate scope.
## Executable example source
```tsx
'use client';
import { Choice } from '../choice';
import { useRef, useState } from 'react';
import { ArrowUp, Bell, Bookmark, Compass, Heart, MapPin, Plus, Share } from '@lucide/icons';
import { Icon } from '@fayegram-ai/faye-ui/core/icon';
import { Card, CardHeader, CardTitle, CardDescription, CardBody } from '@fayegram-ai/faye-ui/core/surface';
import { Button, IconButton } from '@fayegram-ai/faye-ui/controls/button';
import { TextField } from '@fayegram-ai/faye-ui/controls/text-field';
import { Slider } from '@fayegram-ai/faye-ui/controls/slider';
import { Stack, Inline } from '@fayegram-ai/faye-ui/layout/layout';
import { BadgeIndicator } from '@fayegram-ai/faye-ui/feedback/badge-indicator';
import { Toast } from '@fayegram-ai/faye-ui/feedback/toast';
import { Toaster, useToastQueue } from '@fayegram-ai/faye-ui/patterns/toaster';
import { NavigationDrawer } from '@fayegram-ai/faye-ui/patterns/navigation-drawer';
import { CollapsedBreadcrumbs } from '@fayegram-ai/faye-ui/patterns/collapsed-breadcrumbs';
import { ScrollAppBar } from '@fayegram-ai/faye-ui/patterns/application-navigation';
import { FloatingActions } from '@fayegram-ai/faye-ui/patterns/floating-actions';
import { TouchTooltip } from '@fayegram-ai/faye-ui/overlays/tooltip';
import { Drawer } from '@fayegram-ai/faye-ui/overlays/drawer';
import { Timeline, TimelineItem } from '@fayegram-ai/faye-ui/display/timeline';
import { useScrollTrigger } from '@fayegram-ai/faye-ui/hooks/scroll-trigger';
import { ThemeScope } from '@fayegram-ai/faye-ui/provider/provider';
import { Section, Result } from '../example';
import './functional-completion.css';
function QueuedSaves() {
const queue = useToastQueue(), [clickAway,setClickAway] = useState(false), [undone,setUndone] = useState(0);
return {queue.pendingCount} waiting · {undone} {undone === 1 ? 'save' : 'saves'} undone;
}
const allowed = [5,15,30,60,120];
export default function FunctionalCompletion() {
const [open,setOpen] = useState(false), [mini,setMini] = useState(false), [duration,setDuration] = useState(15), [range,setRange] = useState([15,60]);
const [navigationEdge,setNavigationEdge] = useState<'start'|'end'>('start'), [timelinePosition,setTimelinePosition] = useState<'start'|'end'|'alternate'|'alternate-reverse'>('alternate');
const [storyReduced,setStoryReduced] = useState(false);
const [highlight,setHighlight] = useState(false);
const [explored,setExplored] = useState(false), [readBadges,setReadBadges] = useState([]);
const [submitted,setSubmitted] = useState('Choose a duration'), [cancelReset,setCancelReset] = useState(false), [tapCount,setTapCount] = useState(0);
const [dock,setDock] = useState(false), [dockOpen,setDockOpen] = useState(false), [direction,setDirection] = useState<'up'|'down'|'start'|'end'>('up'), [selected,setSelected] = useState('No quick action selected');
const scrollRef = useRef(null), scroll = useScrollTrigger({targetRef:scrollRef,threshold:40,hysteresis:8});
const navigation = ;
const miniNavigation = ;
return setNavigationEdge(value as typeof navigationEdge)} options={['start','end'].map(value=>({value,label:value}))}/>
Explore, save, and make a plan at your own pace.
Follow the coastA gentle route, a warm drink, and time to notice the view.}/> setTapCount(v => v+1)}>{explored && Coastal route selected}
A slow Saturday scroll.scrollToTop()}>
{['Start with the morning light','Take the path beside the water','Leave room for a longer lunch','Find a place to watch the sunset'].map(title =>
{title}
Move through the day at your own pace. The navigation returns when you scroll back or focus its controls.
)}
{(['top','bottom','start','end'] as const).map(edge => }>Plan from {edge}Make room for your next journeyKeep the details close, with space to breathe.}>Done planning)}{(['top-start','top-end','bottom-start','bottom-end'] as const).map((position,index) => setReadBadges(values => values.includes(position) ? values.filter(value => value !== position) : [...values,position])} className="faye-ui-weekend-round">{position})} setTimelinePosition(value as typeof timelinePosition)} options={['end','start','alternate','alternate-reverse'].map(value=>({value,label:value}))}/>Morning walkA picnic with friendsSunset and a quiet moment setDirection(value as typeof direction)} options={['up','down','start','end'].map(value=>({value,label:value}))}/>{dock && ,onSelect:() => setSelected('Route saved')},{id:'share',label:'Share plan',icon:,onSelect:() => setSelected('Share selected')},{id:'new',label:'New plan',icon:,disabled:true,onSelect:() => setSelected('Unexpected action')}]}/>}{selected};
}
```
---
# Consumer application: Faye Places
Discovery, saved places, collections, responsive sheets and resilient local interactions using the public package.
## Faye Places
Faye Places demonstrates a consumer application composed from the public Faye UI APIs: cards, illustrated media, filter chips, search, progress, selection, saved collections, dialogs, notifications with undo, toolbars, tabs, themes and keyed motion.
Browse places, filter a category or search, open details, save places and organize a collection. The interface adapts between narrow and wide layouts. Appearance settings demonstrate color schemes, palette, density, direction and reduced motion.
The service is a deterministic local simulation. Bookmarks and collections are stored on the current device; there is no account, backend or synchronization. The example illustrates component composition rather than a hosted application service. See [consumer interactions](/docs/consumer-experience/) for an interactive composition and [asynchronous workflows](/docs/async-workflows/) for request ownership and recovery patterns.
---
# Packages and boundaries
One public package with twenty-two private modules, explicit ownership and one-way dependencies.
## One package and explicit imports
Consumers install one package, `@fayegram-ai/faye-ui`, and import its public subpaths. Component families are public subpaths within that package. Consumers do not need source repository access. See [installation](/docs/installation/) for npm instructions and the current publication status.
## Dependency direction
Contracts are framework-independent. Tokens declare names and types. Theme resolves and validates values. Styles compiles portable component sheets. Static core and layout primitives do not require React client context.
Provider owns preferences and environment transport. Component-family packages consume that environment and Base UI where needed. Patterns combine public components but do not introduce remote data ownership.
The optional runtime-styles and nextjs packages provide dynamic stylesheet collection and framework insertion. Developer tools and the example extension are separate from the core graph.
## Maintainability rules
A package may depend on lower-level contracts, not a global component registry. Private helpers are not consumer contracts. Component parts, variant attributes, token meanings and rendering boundaries are versioned interfaces.
The API index and component reference are generated from declarations and component contracts. Documentation tooling is not required by application components.
## Data extensions
A plain table is core presentation. Sorting, fetching, row models, virtualization, charts, calendars and editors belong in separate extensions when they require an engine. TablePagination owns no records; its state is supplied by the application.
## Rendering classification
Static primitives can execute in a Server Component. Interactive components are Client Components and may still produce server-rendered initial HTML. A client provider cannot change the already-executed logic of a Server Component.
## Artwork boundaries
`@lucide/icons@1.52.0` supplies raw upstream data. `@fayegram-ai/faye-ui/icons` provides an independently imported organization artwork module inside the single UI package. That module has no React, DOM, CSS, UI-runtime or Lucide imports. `@fayegram-ai/faye-ui/contracts/icon` owns portable definitions and validation. `@fayegram-ai/faye-ui/core/icon` imports neither collection; components and applications import only their chosen artwork. The foundations chapter includes executable examples and the authoring procedure.
---
# Theme and color system
Generate complete palettes, switch schemes, scope brands, and preserve readable state colors.
## Contract first
Faye UI distinguishes the token contract, theme definitions, compiled component sheets and runtime environment. Revision 3 adds source linkage for every token rather than treating a larger count as proof of completeness.
There are six built-in semantic palette families: accent, secondary, danger, success, warning and info. Each has solid, hover, active, soft, soft-hover, soft-active, readable text and paired on-color values. Neutral, selected, disabled, inverse, link, placeholder and focus roles remain separate.
The default Faye UI palette pairs muted periwinkle blue (`#606fbd` light / `#adb9ee` dark), a warm coral secondary and cool slate neutrals. Text, soft surfaces, focus rings and hover/pressed states use paired palette values to retain readable contrast in both schemes.
## Build complete palettes
createBrandTheme accepts explicit light/dark seeds for each family. Font and radius options are applied in both schemes, rather than being masked by scheme overrides. Surface changes are applied before palette derivation.
## Preview the documentation
Open **Theme** in the top navigation. Choose a primary palette, pick a custom primary color, switch between system/light/dark modes, and adjust density or text direction. Custom primary colors use the theme palette generator, including readable foregrounds, hover/pressed colors and focus colors. The documentation and its live examples share these settings. **Use preset color** restores the selected preset; appearance choices persist locally across navigation and reloads.
The example is a developer-tool module: Apply palettes runs authoring and validation, while ordinary production components consume precompiled CSS and a small profile. Editing just a CSS accent variable does not regenerate its paired foreground or states.
## Named contexts
Additional axes declare choices and a default. Resolution order is base, scheme, density, named axes sorted by name, then matching conditions in declaration order. The compiler validates references in all reachable contexts and limits expansion to 256 complete contexts. Split independent theme assets beyond that boundary.
The example's contrast axis changes the border without duplicating every scheme. Its typography selector changes the base font on the theme boundary; semantic typography references are rebound there and recompute with it.
## Honest contrast reporting
The audit tests declared opaque numeric-sRGB role pairs across contexts. Standard named colors are supported. Accepted non-sRGB CSS expressions are unresolved for numeric contrast, not marked passing. Ratios are not rounded up to pass a threshold. Gradients, images, external CSS, arbitrary conditional backgrounds and full accessibility conformance require additional review.
## Scope and rendering
Compile and load the theme asset before choosing its themeId. ThemeScope carries scheme, density, direction, axes, declared variables and motion settings. Portals carry the same environment but not arbitrary ancestor CSS or container geometry.
Static/server components use emitted attributes and CSS; a client provider cannot change their already-executed logical defaults. Actual Next builds, SSR/CSR applications and hydration behavior are mandatory qualification gates. See [verification](/docs/verification/) for source-bound results.
## Editor
The separate ThemeEditor searches and edits every contract token. It supports named-axis selection, typed drafts, explicit @token.name references, JSON import/export, compiled CSS output and context-specific reset. Editing writes a final condition for exactly the selected context so earlier density/scheme overrides cannot mask it. Palette rebuilding is explicit and applies all paired states together.
## Shared interaction defaults
`FayeUIProvider` and `ThemeScope` accept `interaction` with the same `variant`, `level` and `effects` options as supported controls. Theme scopes extend their parent's declared options; an isolated scope starts from the library defaults. React portals preserve the active configuration.
Precedence is library defaults, provider/scoped defaults, component settings, then explicit instance options. Partial options preserve inherited fields. Selecting a new variant resolves that preset's defaults; changing an effect type removes incompatible options from the previous type.
The number tokens `interaction.track-scale.standard` and `interaction.track-scale.enhanced` define the default expansion ratios. State colors and timing follow the existing theme tokens. Scale remains bounded from 1 to 2. Reduced-motion preferences take precedence over per-instance durations.
## Executable example source
```tsx
'use client';
import { useMemo, useState } from 'react';
import { createBrandTheme, semanticColorRoles, type SemanticColorRole } from '@fayegram-ai/faye-ui/theme/brand';
import { compileThemeCSS, extendTheme } from '@fayegram-ai/faye-ui/theme';
import { auditThemeContrast } from '@fayegram-ai/faye-ui/theme/audit';
import { ThemeScope } from '@fayegram-ai/faye-ui/provider/provider';
import { Button } from '@fayegram-ai/faye-ui/controls/button';
import { TextField } from '@fayegram-ai/faye-ui/controls/text-field';
import { Slider } from '@fayegram-ai/faye-ui/controls/slider';
import { Text, Heading } from '@fayegram-ai/faye-ui/core/text';
import { Grid, Inline, Stack } from '@fayegram-ai/faye-ui/layout/layout';
import { Dialog } from '@fayegram-ai/faye-ui/overlays/dialog';
import { Section, Result } from '../example';
import { Choice } from '../choice';
const initialSeeds: Record = { accent: '#5264aa', secondary: '#7255a3', danger: '#ad353a', success: '#35764f', warning: '#94671c', info: '#326894' };
/** Authoring/compiler code is deliberately confined to this developer-tool example. */
export default function Theming() {
const [seeds, setSeeds] = useState(initialSeeds);
const [radius, setRadius] = useState(5);
const [applied, setApplied] = useState({ seeds: initialSeeds, radius: 5 });
const [contrast, setContrast] = useState('normal');
const [font, setFont] = useState('system-ui, sans-serif');
const theme = useMemo(() => extendTheme(createBrandTheme({ id: 'docs-custom', ...applied.seeds, radius: `${applied.radius}px` }), {
axes: { contrast: { default: 'normal', values: { normal: {}, high: { 'border.width': { $type: 'length', $value: '3px' } } } } }
}), [applied]);
const css = useMemo(() => compileThemeCSS(theme), [theme]);
const audit = useMemo(() => auditThemeContrast(theme), [theme]);
return
{audit.passed} declared color pairs passed; {audit.failed} failed; {audit.unresolved} unresolved. Contexts include both schemes, both densities, and the contrast axis.{(['light', 'dark'] as const).map(scheme => {scheme} paletteThis role derives its family from the same theme scope.
{semanticColorRoles.map(role =>
{role}
)}
}>Themed overlayCustom theme in a portalScheme, axis selection and declared font variables travel together.}>Done)};
}
```
---
# Customization sheets
Typed component parts, variant conditions, defaults, and deterministic override layers.
## One portable contract
A component sheet identifies a component and supplies visual defaults and ordered rules. Rules target public parts, variant conditions, interaction states, breakpoints or fixed container-query bounds.
The compiler emits CSS and a minimal component profile. Centralized authoring does not require retaining every component's customization in the browser.
## Precedence
Library defaults are overridden by brand, product and local configuration, then explicit instance props. Profiles accumulate part classes and only contribute defaults they actually specify.
CSS layer order is fixed by the layer prelude. Within one layer, overlapping rules still require deterministic stylesheet order. Class-name accumulation is not a replacement for the CSS cascade.
## Static and executable configuration
Portable sheets contain validated data. Slot constructors, callbacks and arbitrary executable customization remain code-bound on the appropriate server or client side.
The optional runtime styled helper binds a compiled sheet to a React element. It is not a compatibility implementation of MUI sx and does not accept unrestricted runtime CSS callback syntax.
## Responsive rules
Spacing values can update through CSS variables. A threshold inside a compiled media query cannot be changed by assigning a similarly named custom property. Change the compiled profile or use an explicit dynamic rule-generation path.
The live compiler below is intentionally part of a developer-tool page, not part of the ordinary Button payload.
## Open typed variants
The type-only visual-variants registry is generated from component descriptors. ComponentVariantOverrides accepts keys such as button.variant with additional string values. Extend the runtime authoring descriptor with extendDescriptor and compile matching rules as well: TypeScript augmentation alone does not create a style.
Composed styledPart controls accept a typed variants prop. It is removed before DOM forwarding and inherited by descendant parts through ComponentStyleScope. Generic collection roots remain composable without erasing their value types. Server-safe Text, Heading, Surface and supported display parts accept explicit profiles rather than requiring a client hook.
## Theme versus component axes
Theme axes select token contexts. Component variants select a control's appearance and do not create new theme contexts. Their schemas, generation, precedence and runtime responsibilities are intentionally distinct. This avoids a global all-component configuration payload.
## Print-aware component sheets
A rule can select `media: 'print'` or `media: 'screen'`, in addition to a breakpoint or container condition. Numeric transition durations and delays are milliseconds; numeric length properties are pixels. Invalid typed-token/property pairs fail compilation.
```ts
const printRule = {
id: 'printed-action',
part: 'root',
media: 'print',
declarations: { color: 'black', boxShadow: 'none', breakInside: 'avoid' },
} as const;
```
## Pattern labels
Command palette, transfer list and toaster labels also accept code-bound component settings. Close/dismiss labels, empty messages, action labels and announcement formatters can be localized without replacing the component. This is not a bundled complete translation catalog.
## Named interaction presets
The shared `interaction` prop is separate from component size, tone and surface variants. Use its `variant` to choose a feedback preset, `level` to choose strength, and `effects` for individual behavior overrides. Initial adoption covers slider roots and custom ScrollArea roots; unsupported components do not advertise this prop.
For a custom named preset, augment `InteractionVariantOverrides` in `@fayegram-ai/faye-ui/contracts/interaction` and provide matching CSS or profile classes. A custom name starts from the minimal feedback baseline; TypeScript augmentation alone does not supply its styling. The root hooks `data-faye-ui-interaction-variant`, `data-faye-ui-interaction-level` and `data-faye-ui-track-effect` identify the resolved choices. Public interaction tokens can customize expansion without targeting internal paint layers.
The typed effect union and target map can grow as additional component capabilities are implemented. Existing configuration syntax remains the same; there is no separate enhanced-mode customization API.
## Executable example source
```tsx
'use client';
import { useMemo, useState } from 'react';
import { compileSheet } from '@fayegram-ai/faye-ui/styles';
import { SheetInspector } from '@fayegram-ai/faye-ui/devtools/inspector';
import { buttonDescriptor } from '@fayegram-ai/faye-ui/controls/button.descriptor';
import { Slider } from '@fayegram-ai/faye-ui/controls/slider';
import { Checkbox } from '@fayegram-ai/faye-ui/controls/checkbox';
import { ControlLabel } from '@fayegram-ai/faye-ui/controls/field-layout';
import { Button } from '@fayegram-ai/faye-ui/controls/button';
import { ThemeScope, ComponentStyleScope } from '@fayegram-ai/faye-ui/provider/provider';
import { Stack, Inline } from '@fayegram-ai/faye-ui/layout/layout';
import { Section, Result } from '../example';
export default function Customization() {
const [weight, setWeight] = useState(500), [uppercase, setUppercase] = useState(false);
const sheet = useMemo(() => compileSheet({ schemaVersion: 1, id: 'docs-button', component: 'button', defaults: { tone: 'accent' }, rules: [{ id: 'label', part: 'label', declarations: { fontWeight: weight, textTransform: uppercase ? 'uppercase' : 'none' } }, { id: 'root', part: 'root', when: { variant: 'solid' }, declarations: { borderRadius: { token: 'radius.control' }, paddingInline: { token: 'space.6' } } }] }, buttonDescriptor), [weight, uppercase]);
return Label weight: {attrs => }{JSON.stringify(sheet.profile, null, 2)};
}
```
---
# Theme studio
Edit, inspect, export and re-import the actual theme contract.
## Production contracts
The theme studio edits the production ThemeDefinition. Search and edit every contract token, select scheme/density/named axes, apply a validated draft, or reset only the current editor-owned context override. Use `@token.name` for aliases. Palette rebuilding is explicit; changing a seed alone does not regenerate companion colors.
JSON import validates portable data and all references. JSON export preserves editable source. CSS output is generated and is not authoritative. Clipboard permission failure leaves the editable export visible.
## Separate customization plane
The component sheet studio edits the production ComponentSheet against a ComponentDescriptor. Visual defaults, named part/state/variant rules, responsive conditions and source JSON compile to actual CSS and a ComponentProfile. The preview renders a real exported Button under that profile; the inspector exposes rule provenance. Invalid imports keep the previous valid preview.
Behavioral settings and event callbacks stay in the provider configuration plane. They are not serialized into a theme or sheet. Build/compiler/editor dependencies remain outside minimal component graphs.
## Review limits
Contrast checks cover declared pairs and supported numeric colors. An editor preview does not certify all themes, assistive technology or custom layouts. Source exports must be reviewed before persistence. See [interoperability](/docs/interoperability/) for versioned design exchange and migration.
## Executable example source
```tsx
'use client';
import { useState } from 'react';
import type { ThemeDefinition, ComponentSheet } from '@fayegram-ai/faye-ui/contracts';
import { ThemeEditor } from '@fayegram-ai/faye-ui/devtools/theme-editor';
import { ComponentSheetEditor } from '@fayegram-ai/faye-ui/devtools/sheet-editor';
import { buttonDescriptor } from '@fayegram-ai/faye-ui/controls/button.descriptor';
import { Button } from '@fayegram-ai/faye-ui/controls/button';
import { defaultTheme } from '@fayegram-ai/faye-ui/tokens/default-theme';
export default function Studio() {
const [theme, setTheme] = useState(defaultTheme);
const [sheet, setSheet] = useState({ schemaVersion: 1, id: 'studio.button', component: 'button', rules: [] });
return <>>;
}
```
---
# Token reference and metrics
Inspect every token and build spacing, breakpoints and fluid typography explicitly.
## One source contract
The contract currently contains 258 nodes including aliases, not 258 independent visual promises. token-specs.json declares types and meanings; tokens.json supplies the default definition. TypeScript contracts and CSS are generated from those files. Generation checks reject drift, missing definitions and CSS-variable name collisions.
Each node is classified by a runtime source reference, an alias dependent or a documented authoring use. Static linkage is not proof that a React component or every state executes correctly.
## Semantic coverage
The token system includes six complete color families, thirteen typography roles with family/size/weight/line/tracking fields, spacing, control geometry, icons, avatars, sliders/switches, feedback sizes, overlays, borders, elevation, layering, focus, opacity and motion. Use meaning-bearing roles rather than raw color constants.
## References and live values
compileThemeCSS and themeBindings redeclare the whole contract on a theme boundary, including alias var() expressions. A base font or size change on that boundary updates dependent role tokens. A raw descendant override without a new complete boundary cannot recompute an inherited alias.
resolveTheme returns concrete values. themeVariables applied to that result is deliberately a resolved snapshot, useful for non-CSS integrations. It is not the live-binding form.
## Authoring helpers
createSpacing accepts one to four finite scale factors or auto. fluidType emits a validated clamp expression. createBreakpoints supplies up/down/between/only/not helpers and ordered distinct thresholds. createTransition validates timing values and property names.
The sheet compiler accepts custom named fixed breakpoint maps. Changing a CSS custom property does not change already compiled media-query thresholds or the bundled layout utility scale.
## Migration and verification
Existing full theme JSON files with the earlier 99 nodes must be explicitly completed against the current default contract, then re-audited. completeTheme takes a patch without schemaVersion, not an arbitrary complete JSON document. Regenerate semantic palettes after migrating older custom colors and review visual changes.
Machine-readable token definitions and theme capabilities are available independently of JavaScript at /api/tokens.json and /api/theme-capabilities.json. No full DTCG conformance or accessibility certification is implied.
---
# Accessibility and input behavior
Automatic focus guidance, optional keyboard hints, system preferences and explicit user controls.
## Automatic presentation, continuous accessibility
Faye UI keeps accessible names, labels, errors, screen-reader semantics and keyboard operation available continuously. The presentation preferences below control focus indicators, optional interaction hints, contrast and motion.
| Preference | Default | Explicit choice |
|---|---|---|
| Focus indicators | Automatic browser `:focus-visible` behavior | Show the same indicator on every focus, including pointer focus |
| Interaction hints | Show authored guidance on keyboard navigation | Show it on every focus, including pointer focus |
| Contrast | Follow system preferences | Increase text and boundary contrast |
| Motion | Follow system preferences | Reduce nonessential movement |
Text fields can receive a visible focus indicator after a pointer click: browsers treat text entry as keyboard interaction. Automatic hints specifically follow navigation keys such as Tab and the arrow keys. Ordinary typing or pointer hover does not enable the new hints. System contrast and motion preferences act independently; they do not turn on every other preference.
## Provider and scoped preferences
```tsx
'use client';
import { FayeUIProvider, ThemeScope } from '@fayegram-ai/faye-ui/provider/provider';
import { Button } from '@fayegram-ai/faye-ui/controls/button';
export function AccessibleApplication() {
return ;
}
```
Omitted properties inherit. Explicit `auto` or `system` values restore automatic behavior inside a scope. Accessibility preferences remain inherited through isolated visual themes and are carried into dialogs, menus and other portals. The read-only `useAccessibilityPreferences()` hook returns the effective scoped configuration. Applications own updates and persistence. `useInputModality()` reports document-local navigation modality (`unknown`, `keyboard` or `pointer`); it does not detect a screen reader.
Use `ThemeScope` to override one control or a region. With `applyToDocument={false}`, use a `ThemeScope` around the region to supply its DOM presentation, just as for scoped theme colors. The existing `motion="system"` and `motion="reduced"` properties remain supported. Forced system colors retain priority, and a system request to reduce motion is respected.
## Optional floating interaction hints
```tsx
'use client';
import { InteractionHint } from '@fayegram-ai/faye-ui/overlays/interaction-hint';
import { Button } from '@fayegram-ai/faye-ui/controls/button';
export function SaveAction() {
return ;
}
```
Supply one control that forwards its ref and event/ARIA props. The hint adds no focus stop or wrapper to the layout. Use brief, noninteractive content. It opens immediately for eligible focus, stays within the viewport, and closes on blur, Escape, disabling or unmounting. Escape keeps it dismissed until focus leaves and returns. Reduced-motion preferences remove its fade.
`hints="always"` means every focused control with an authored hint, not every hint at once. Existing tooltips keep their hover and focus behavior. Essential field descriptions, validation messages and accessible labels belong on their controls and must remain available independently of an optional hint.
## Optional preference controls
```tsx
'use client';
import { useState } from 'react';
import { FayeUIProvider } from '@fayegram-ai/faye-ui/provider/provider';
import { AccessibilityPreferences, type AccessibilityPreferencesValue } from '@fayegram-ai/faye-ui/patterns/accessibility-preferences';
export function PreferenceExample() {
const [value, setValue] = useState({
focus: 'auto', hints: 'auto', contrast: 'system', motion: 'system'
});
const { motion, ...accessibility } = value;
return ;
}
```
The controls are optional and remain inside the single Faye UI package. They use the provider's message catalogs, support label overrides, and leave persistence to the application. The documentation's header **Theme → Accessibility** section saves explicit choices locally. Its reset action resets these four preferences while preserving palette, density and direction.
## Application responsibilities and verification
Keep labels visible, provide meaningful task structure, and distinguish disabled and read-only states. Use the existing dialog and menu components for their keyboard and focus behavior. Drag or swipe interactions need appropriate alternatives. No browser signal reliably establishes whether a screen reader is active; Faye UI does not attempt that detection.
WCAG 2.2 AA remains the target, not a completed certification. Automated checks and direct visual/interaction inspection cover different facts. Manual screen-reader, physical-device and linguistic reviews retain their recorded limitations. See [verification](/docs/verification/).
## Executable example source
```tsx
'use client';
import { useState } from 'react';
import { ThemeScope, useAccessibilityPreferences, useVisualScope } from '@fayegram-ai/faye-ui/provider/provider';
import { AccessibilityPreferences, type AccessibilityPreferencesValue } from '@fayegram-ai/faye-ui/patterns/accessibility-preferences';
import { InteractionHint } from '@fayegram-ai/faye-ui/overlays/interaction-hint';
import { Dialog } from '@fayegram-ai/faye-ui/overlays/dialog';
import { Button } from '@fayegram-ai/faye-ui/controls/button';
import { Input } from '@fayegram-ai/faye-ui/controls/input';
import { ControlLabel } from '@fayegram-ai/faye-ui/controls/field-layout';
import { Field } from '@fayegram-ai/faye-ui/controls/field';
import { Radio } from '@fayegram-ai/faye-ui/controls/radio';
import { RadioGroup } from '@fayegram-ai/faye-ui/controls/radio-group';
import { Slider } from '@fayegram-ai/faye-ui/controls/slider';
import { Rating } from '@fayegram-ai/faye-ui/controls/rating';
import { Text } from '@fayegram-ai/faye-ui/core/text';
import { Inline, Stack } from '@fayegram-ai/faye-ui/layout/layout';
import { Section } from '../example';
const responsiveAction = { maxInlineSize: '100%', whiteSpace: 'normal' } as const;
function Controls() {
const preferences = useAccessibilityPreferences();
return Use Tab to explore. Optional hints follow the focused control; labels and form help stay visible.Collection nameThis name is visible only in this preview.{attrs => }{attrs => }Preview volume}>Open assistance dialogKeep your collectionThe dialog uses the same accessibility preferences.Focus: {preferences.focus}; hints: {preferences.hints}; contrast: {preferences.contrast}.;
}
export default function AccessibilityExample() {
const inherited = useAccessibilityPreferences(), scope = useVisualScope();
const [override, setValue] = useState();
const value = override ?? { ...inherited, motion: scope.motion };
const { motion, ...accessibility } = value;
return ;
}
```
---
# Interoperability and migration
DTCG exchange, locale catalogs, design identity and reviewed migration.
## DTCG 2025.10
The optional `@fayegram-ai/faye-ui/theme/dtcg` entry accepts portable DTCG documents and exposes `resolveDTCG` and `resolveDTCGResolver`. Source preserves metadata and references; resolved tokens are a separate frozen snapshot. The adapter performs no network or filesystem reads.
Supported structures include inherited types, root tokens, group extension, whole-token aliases, escaped JSON pointers and component references, standard simple/composite token types, ordered sets, modifiers and defaults. External references must appear in an explicit URI-to-document map. Resolver inputs are case-sensitive strings. Context products are bounded to 256; portable size/depth limits apply. Unsupported structures fail explicitly.
This is a bounded interchange profile, not a claim of universal tool compatibility. Faye UI's CSS-oriented theme value grammar differs from DTCG structured values. A design tool must perform an explicit, reviewed conversion rather than paste arbitrary token JSON into ThemeDefinition. Format and resolver specifications are available at https://www.designtokens.org/tr/2025.10/format/ and https://www.designtokens.org/tr/2025.10/resolver/.
## Locale catalogs
The optional `@fayegram-ai/faye-ui/provider/messages` entry defines version-1 plain-text catalogs with a locale, revision and known message keys. FayeUIProvider accepts explicit catalogs; regional/script parents fall back to English per key. Parameters must retain source names. No HTML, executable interpolation, remote fetching or automatic language-pack loading is performed.
Already interactive compositions consume catalog defaults for command palettes, modals, notifications and transfer lists. Explicit props and configured settings take precedence. Server-safe compositions retain explicit label props. Application content, plural-sensitive business messages and date/number formatting remain the application's locale responsibility.
English, Traditional/Simplified Chinese, Korean and Japanese catalogs are available as optional subpaths. The translations retain their draft status without qualified human linguistic signoff. The pseudo locale is an expansion/encoding fixture, not a reviewed translation. See [localization](/docs/localization/) for fallback, ownership and review limits. Direction is an explicit provider setting and does not follow automatically from language.
## Tool-neutral design exchange
Default stable token IDs use the product prefix `faye-ui:`. Callers can supply their own explicit stable ID map; those application-owned identities are preserved and checked on import.
`@fayegram-ai/faye-ui/devtools/design-exchange` exports a versioned local exchange carrying repository authority, source revision, base/payload SHA-256 digests, unique stable token IDs and the full portable theme. Updating an exchange preserves its base. Applying it rejects repository revision conflicts and payload corruption before returning a validated theme.
Digests detect changes; they do not authenticate the author. Review differences before writing source. Metadata/aliases/axes remain in the portable theme; generated CSS is not authoritative. The optional `@fayegram-ai/faye-ui/devtools/figma` adapter creates a reviewable Figma Variables plan from explicitly selected contexts. Supply actual mode capacity and rem-to-pixel conversion. Numeric lengths/durations and sRGB colors project to native values; other CSS stays exact STRING data with notices. Compatible aliases preserve stable identity. SDK typings are checked against the pinned Figma PluginAPI.
A host can export a plan into a fresh unpublished collection, read a snapshot and import reviewed changes back into the exchange. Export detects name conflicts and rolls back every acquired resource on failure. Snapshot import checks repository revision, contexts, identities, types and alias targets. Account mode limits and portable/metadata bounds apply. Complete end-to-end Figma host validation has not been performed; protocol validation alone does not establish a complete host pass. Ordinary component use does not require a Figma connection.
## Reviewed migration
`@fayegram-ai/faye-ui/theme/migration` accepts documented version-1 partial/full themes plus a supplied current base. Explicit renames update references in base, schemes, densities, axes and conditions. Explicit obsolete-name removals are recorded. Unknown names, collisions, broken aliases and unsupported versions fail.
The result lists added, removed and renamed tokens and contrast findings. Review is always required; filling new tokens is not an accessibility or palette approval. The existing completeTheme API remains available. Keep previous source and paired assets for rollback, and test accepted consumers before replacing deployed assets.
---
# Localization
Explicit English, Chinese, Korean and Japanese catalogs with fallback and review.
## Requested catalogs
English, Traditional Chinese (zh-Hant), Simplified Chinese (zh-Hans), Korean (ko) and Japanese (ja) have optional versioned catalog entries. Import only the catalogs the application needs. The four translations remain draft working material without qualified human linguistic signoff. The project records that unavailable review as non-blocking; see [verification](/docs/verification/) for the policy and retained automated checks.
```tsx
import type { ReactNode } from 'react';
import { FayeUIProvider } from '@fayegram-ai/faye-ui/provider/provider';
import { traditionalChineseCatalog } from '@fayegram-ai/faye-ui/provider/locale-zh-hant';
export function TraditionalChineseApplication({ children }: { children: ReactNode }) {
return
{children}
;
}
```
## Fallback and ownership
Canonical BCP 47 tags use language/script/region fallback. Likely scripts allow zh-TW to select zh-Hant and zh-CN to select zh-Hans. Missing keys fall back to English. Placeholder names and schema versions must match the source catalog. Updates use explicit catalog revisions; duplicate catalogs are rejected.
Catalogs supply library-owned interactive labels for modals, notifications, command palettes, chips, ratings, pagination, table pagination and transfer lists. Explicit props/configured settings retain precedence. Server-safe compositions accept their labels explicitly. Direction remains an explicit provider choice; these requested locales use left-to-right layout.
Application titles, descriptions, item labels, plural-sensitive business text and date/number formatting remain application content. Catalog labels are plain text and React escapes substituted values. No HTML, callbacks, remote fetching or automatic imports enter the catalog contract.
## Review
Use the real example to change catalogs while a dialog or pagination is active. Check announcements, language accuracy, font fallback, long labels and IME input on actual devices. The expansion pseudo locale is a test fixture, not a shipped translation or a review signoff.
## Executable example source
```tsx
'use client';
import { NativeSelect } from '@fayegram-ai/faye-ui/controls/native-select';
import { useState } from 'react';
import { FayeUIProvider } from '@fayegram-ai/faye-ui/provider/provider';
import { englishCatalog } from '@fayegram-ai/faye-ui/provider/locale-en';
import { traditionalChineseCatalog } from '@fayegram-ai/faye-ui/provider/locale-zh-hant';
import { simplifiedChineseCatalog } from '@fayegram-ai/faye-ui/provider/locale-zh-hans';
import { koreanCatalog } from '@fayegram-ai/faye-ui/provider/locale-ko';
import { japaneseCatalog } from '@fayegram-ai/faye-ui/provider/locale-ja';
import { Modal } from '@fayegram-ai/faye-ui/overlays/modal';
import { Chip } from '@fayegram-ai/faye-ui/controls/chip';
import { Pagination } from '@fayegram-ai/faye-ui/navigation/pagination';
import { Button } from '@fayegram-ai/faye-ui/controls/button';
const catalogs = [englishCatalog, traditionalChineseCatalog, simplifiedChineseCatalog, koreanCatalog, japaneseCatalog];
export default function Localization() {
const [locale, setLocale] = useState('en'), [open, setOpen] = useState(false), [page, setPage] = useState(1), [removed, setRemoved] = useState(false);
return The close label comes from the selected catalog. Application content is supplied separately.
{!removed && setRemoved(true)}>Application-provided item}
;
}
```
---
# Server rendering and RSC
Request-local configuration, stable initial markup, streaming assets and explicit client boundaries.
## SSR application
The server-rendered documentation edition uses Next.js App Router. Document prose is rendered on the server for each request. Interactive examples remain Client Components. The server resolves the route-specific example before rendering the article, so its controls are visible in the initial HTML and hydrate in place without a streamed loading swap. Server HTML is not replaced by a static screenshot.
Request-known preferences initialize the provider. The head bootstrap resolves browser-local preference before visible content. Its inline script requires an appropriate CSP nonce or exact hash authorization in a restricted deployment.
## Server Component boundaries
Static typography, layout and surface primitives do not need a client provider to execute. Behavioral defaults needed during server execution must be explicit or build-bound. Client context cannot configure server execution retroactively.
## Optional runtime styles
`@fayegram-ai/faye-ui/nextjs` connects a request-local streaming collector with useServerInsertedHTML and a deferred client registry. Precompiled CSS does not require this adapter.
A streaming response cannot retroactively reorder previously flushed CSS. Late rules that would precede already-emitted rules are rejected. Precollect those sheets or assign an order compatible with stream arrival.
## Verification status
SSR, streaming, React Server Components and optional framework adapters require integration testing in the consuming application. Match client/server boundaries, initial state and stylesheet delivery. See [verification](/docs/verification/) for package status and review limits.
## Matching first-paint scope settings
ThemeScript accepts serverScheme, axes and motion in addition to color preference, density and direction. Match serverScheme to the provider's initial snapshot; it is used when system media access is unavailable. A stored explicit light/dark preference and a readable system preference still take precedence.
Omitting axes or motion preserves server-authored attributes for backward compatibility. Passing axes replaces the named-axis selection, including removal of stale attributes; an explicit empty map resets it. motion="system" removes an explicit reduced-motion attribute, while motion="reduced" installs it. The browser's own reduced-motion preference continues to apply through CSS.
These first-paint helpers do not change React's hydration contract. Static markup, IDs and logical initial values must still agree between server and client. Test the actual server/client integration used by your application.
---
# Client-only application
A separate Next.js static export with an explicit client-only document boundary.
## Client rendering and static output
Faye UI can be used in a client-rendered React application. Import the public component entrypoints and load the theme at the application boundary, as shown in [installation](/docs/installation/).
A static host and client rendering are different choices. A framework can generate complete initial HTML and hydrate its interactive controls, or load a client-only interface after startup. Choose the rendering model that fits your application's content and framework.
## Loading without layout shifts
Reserve the expected content frame while client-only content loads. Use Skeleton for structure, Spinner or Progress for status, and meaningful accessible status text. Keep navigation, page titles and persistent controls stable. Preserve dimensions when a loading state changes and respect reduced motion.
## Documentation examples
The prerendered documentation profile includes article content and route-specific examples in the initial HTML. Its client-only comparison reserves the same page geometry while loading. Markdown, API JSON and example resources remain directly readable without JavaScript.
## Themes and overlays
Apply matching initial theme preferences before content becomes visible, then preserve the same snapshot during hydration. Modal scroll locking should retain desktop scrollbar space so opening an overlay does not change the content width. See [server rendering](/docs/server-rendering/), [themes](/docs/theming/) and [dialogs](/docs/dialogs/).
---
# Optional runtime styling
Request-local collection, ownership-safe adoption, and explicit streaming constraints.
## Optional dependency
The standard component path uses prebuilt CSS. Applications that need runtime rule insertion can opt into `@fayegram-ai/faye-ui/runtime-styles` and a rendering integration such as `@fayegram-ai/faye-ui/nextjs`, within the single public package.
GlobalStyles accepts trusted CSS with an immutable identity and order. The styled helper binds an already-compiled sheet and forwards explicitly permitted props. Neither API makes untrusted arbitrary CSS safe.
## Registry lifecycle
A DOM container has one registry owner. The registry adopts matching direct-child hydrated sheets, validates identities, reference-counts client additions, and releases only what it owns.
The Next adapter marks emitted styles with a request-local React identity. Hydration hoists only its marked streamed tags, validates all identities before mutation, preserves unrelated registries, and observes late stream arrivals. The head container still has one owner: place one FayeUIStyleRegistry at the application boundary, not one around every widget.
The deferred registry is memory-only until attachment. React rendering does not mutate a document or acquire global ownership. StrictMode detach and reattach are supported by the registry contract.
## Integration evidence
Actual Next.js/React integration, streaming ownership and cleanup are mandatory verification gates. A matching passing report establishes those automated checks; it does not constitute a general streaming performance guarantee or replace device/CSP review.
## Executable example source
```tsx
'use client';
import { compileSheet } from '@fayegram-ai/faye-ui/styles';
import { styled } from '@fayegram-ai/faye-ui/runtime-styles/styled';
import { GlobalStyles } from '@fayegram-ai/faye-ui/runtime-styles/react';
import { FayeUIStyleRegistry } from '@fayegram-ai/faye-ui/nextjs';
import { Section } from '../example';
const sheet = compileSheet({ schemaVersion: 1, id: 'docs-styled-note', component: 'docs.note', rules: [{ id: 'base', part: 'root', declarations: { padding: { token: 'space.4' }, border: '1px solid var(--faye-ui-color-border)', borderRadius: { token: 'radius.control' }, backgroundColor: { token: 'color.subtle' } } }] }, { schemaVersion: 1, name: 'docs.note', parts: ['root'], states: [], variants: {}, defaults: {} });
const Note = styled('aside', { sheet });
export default function RuntimeStyles() {
return A component bound to a compiled customization sheet.
A scoped global rule from the optional runtime.
;
}
```
---
# Atomic theme asset loading
Prepare a trusted stylesheet, then commit identity and appearance together.
## Loading contract
`createThemeAssetManager` belongs to a DOM theme scope. It stages trusted stylesheets, validates allowed origins, supports integrity and a timeout, and keeps the last valid theme while another is loading.
A newer load cancels and supersedes an older load. Failed preparation or activation does not discard the current asset. Disposal aborts pending work and restores the previous identity only when the manager still owns that attribute.
```ts
import { createThemeAssetManager } from '@fayegram-ai/faye-ui/theme/assets';
const manager = createThemeAssetManager(document.documentElement, {
allowedOrigins: ['https://assets.your-domain.example'],
onCommit: id => updateApplicationThemeId(id),
});
await manager.load({ id: 'brand-a', href: '/themes/brand-a.css' });
// During application teardown:
manager.dispose();
```
The callback is application code; it must synchronize the provider's identity. Do not let another provider effect overwrite a manager-owned theme. Stylesheets must use the expected theme scope selectors. Origin validation is not a CSS sandbox.
## Pure and browser evidence
The state-machine tests cover stale completions, failure, cancellation and cleanup. Browser tests use controlled link load/error events to inspect DOM ownership; they do not prove an external CDN or integrity policy is operational.
## Cleanup diagnostics
Successful activation commits before the previous asset is disposed. A disposal error cannot retroactively turn that committed switch into a failed load. `getCleanupErrors()` exposes cleanup failures separately; the browser manager removes its own link nodes without third-party cleanup code. A rejected activation still reports the original activation error, not a secondary disposal error.
The target must carry the effective `data-faye-ui-theme`, `data-faye-ui-scheme`, and `data-faye-ui-density` attributes used by compiled themes. FayeUIProvider and ThemeScope supply them.
## Synchronous activation boundary
Activation and onCommit are synchronous. Reentrant load or disposal during activation is rejected before it can corrupt ownership or supersede the committing asset. Schedule another transition after the commit. Cleanup errors from a previous asset are diagnostic and do not reverse a successfully committed theme.
Controlled DOM link events in the offline browser suite are not evidence of real network delivery, integrity enforcement, Next streaming or hydration behavior. Those remain separate integration gates.
## Origin, integrity and style-root policy
Relative URLs use the document's base URI for resolution. Permission comes from the document URL's HTTP(S) origin plus explicit allowedOrigins, not from an external base element. Opaque-origin documents must declare allowedOrigins. Entries must be origins, not URL paths or credential-bearing URLs; case and default ports are normalized.
The manager installs a link in the target's shadow root when applicable, rather than injecting a shadow theme into the document head. Moving to another document or style root during preparation rejects activation and removes the staged link. Start a new load after moving the scope. Static component/reset CSS still needs independent installation in the shadow root; this loader does not transport arbitrary application styles or prove initially open portal behavior.
When integrity is supplied, Faye UI accepts a bounded list of canonical padded-base64 sha256, sha384 or sha512 digests. Unknown algorithms, truncated digests and metadata options are rejected rather than relying on the browser to ignore them. This is a deliberately restricted authoring policy, not complete SRI grammar support. The browser still must fetch and verify the actual bytes; a syntactically valid hash is not proof of delivery or authenticity. Cross-origin assets use anonymous CORS when integrity is set.
A rejected URL or malformed metadata does not cancel an already valid pending request. Caller-owned request objects are snapshotted. Cancellation settles the returned promise even when a custom preparer ignores AbortSignal; any resource it returns later is disposed without activation. Cancellation cannot forcibly stop work in a noncooperating preparer.
Reentrant loads or disposal during synchronous request handoff, activation or resource cleanup are rejected. Schedule the next transition after the current operation. A cleanup failure remains diagnostic instead of silently disposing the newly committed theme.
---
# Extension packages
Share system contracts without pulling data engines into the core.
## Extension seam
An extension declares its namespaced component identity, tokens, parts, variants, compatibility and stylesheet assets. It can consume core components but core cannot import it.
The activity panel below is loaded only by this example route. It consumes the public extension and core APIs. There is no special private theme provider for extension components.
## Non-CSS renderers
A canvas or other non-CSS renderer may need a resolved browser value, not a var expression. The provider's computed-token utilities are an explicit browser seam. Their availability and updates must be handled by the extension.
## Data-engine exclusions
Data grids, chart engines, advanced date/time pickers, rich-text editors and remote data caches remain separate work. A UI table and pagination control are not a data-grid engine.
## Explicit deferred delivery
Ordinary extension imports bring their CSS automatically. Dynamic JavaScript imports alone do not guarantee deferred CSS in a bundler.
For managed delivery, use `@fayegram-ai/faye-ui/example-extension/unstyled` and `@fayegram-ai/faye-ui/integrations/deferred-assets`. The public `assets` entry lists required CSS specifiers. Build tooling must translate those specifiers into deployed URLs. Normal core primitives retain automatic styles; the `@fayegram-ai/faye-ui/core/unstyled` entry is available for this explicit boundary.
`loadDeferredModule` stages owned links, waits for successful stylesheet loading, imports the module, then activates styles before the caller renders. Its lease has an idempotent release method. Shared consumers keep styles until their last release. Failure/cancellation removes owned resources and allows retry. Module evaluation cannot be undone by cancellation.
Supply a live Document or ShadowRoot, exact allowed origins, optional nonce and canonical SHA-256/384/512 integrity. Initial URL validation uses the owner document's origin even when a base URL points elsewhere. Redirect destination restrictions are the host's CSP responsibility; this adapter does not intercept browser redirects. A deployment must protect asset URLs and preserve the compiled content hashes.
The packed gate records the initial JavaScript/CSS closure, emitted assets, network requests and a real Chromium activation, invalid-integrity rejection and shared-lease cleanup. The playground demonstrates Vite URL assets with loading, retry and unload controls. Those profiles do not establish support for every bundler.
## Executable example source
```tsx
import { ActivityPanel } from '@fayegram-ai/faye-ui/example-extension';
import { Section } from '../example';
export default function Extensions() { return ; }
```
---
# Browser and interaction utilities
Explicit client-only behavior, debouncing, media queries and outside-pointer handling.
## Prefer declarative layout
Use CSS breakpoints and container queries for layout. useMediaQuery is for genuinely behavioral decisions and accepts a stable server snapshot. It must not create incompatible server and hydration trees.
ClientOnly is an explicit browser-only boundary. Do not wrap every troublesome component in it and call the system SSR-compatible.
## State and lifecycle
useControllableState forbids switching between controlled and uncontrolled operation. useDisclosure is local UI state. useDebouncedValue validates its delay and cancels outdated timers.
ClickAwayListener is a structural wrapper with an explicit outside-pointer policy. It is not a competing dismissal implementation for Base UI menus and dialogs.
## Executable example source
```tsx
'use client';
import { useState } from 'react';
import { ClientOnly } from '@fayegram-ai/faye-ui/hooks/client-only';
import { useMediaQuery, useDebouncedValue, useDisclosure } from '@fayegram-ai/faye-ui/hooks';
import { Button } from '@fayegram-ai/faye-ui/controls/button';
import { Input } from '@fayegram-ai/faye-ui/controls/input';
import { Section, Result } from '../example';
export default function Utilities() {
const [query, setQuery] = useState(''), debounced = useDebouncedValue(query, 200), wide = useMediaQuery('(min-width: 60rem)', false), disclosure = useDisclosure();
return <>Browser-only content pending.
}>;
}
```
---
# LLM-friendly documentation
Direct Markdown, API JSON, schemas and examples without browser execution.
## Stable resources
Each page has a direct `/markdown/.md` representation. `/llms.txt` indexes the corpus, and `/llms-full.txt` contains the complete text and example source. These resources exist in both applications before JavaScript runs.
The `/api/index.json` resource inventories package modules and source declarations. `/api/coverage.json` records which public symbols are actually referenced by JSX examples. Coverage is syntactic, not a claim of runtime success or exhaustive state testing.
## Exact versus inferred API data
API JSON reports explicit source declarations, component descriptors, public parts and declared variant defaults. It does not pretend to flatten inherited Base UI and React types without a successful semantic build. The generated declaration files remain the semantic type authority after compilation.
## Source and schemas
Every example has a raw `/examples/.tsx` resource. JSON schemas are exposed under `/schemas/`. Theme source and contract are available under `/api/`.
llms.txt is a discoverability convention, not an access-control mechanism, a ranking guarantee or a claim that every agent implements it.
## Availability
These resources describe the implementation shown by the documentation. They do not establish npm availability; see [installation](/docs/installation/) for current release status.
## Theme and customization resources
/api/theme-capabilities.json includes the palette roles, typography roles, context ceiling, precedence, alias behavior and numeric contrast scope. /api/visual-variants.json contains descriptor-derived component choices and parts. These are generated with the documentation; inherited React/Base UI types still require the dependency-backed declaration build.
---
# Verification and limitations
Current package availability, supported checks and accessibility limitations.
## Current release status
**The Faye UI npm package is unpublished and not ready for release.** The `0.1.0` publication was withdrawn on October 23, 2026. The final npm package metadata and support destinations still require review. The guides describe the implemented API; they do not establish npm availability or certification.
## What release qualification covers
Each release candidate is checked as an installed npm package as well as in the development workspace. Checks cover types and imports, generated tokens and styles, React behavior, keyboard navigation and focus, forms, overlays, themes, motion, and cleanup. Chromium, Firefox and WebKit exercise the component suite. Production documentation and consumer applications are also tested.
Server rendering, streaming, React Server Components and client rendering have separate integration checks. Package checks verify declarations, explicit entrypoints, stylesheet delivery, dependency boundaries and installed application builds. Dependency auditing is part of qualification.
## Visual and interaction review
Rendered examples are inspected in light and dark themes, narrow layouts, enlarged text and right-to-left layouts. Reviews include open menus and dialogs, loading and error states, pointer and keyboard reactions, animations, reduced motion and forced colors. A component appearing in the gallery is not sufficient evidence that all its interactions work.
Checks run against a fixed candidate. Changes require fresh qualification; a successful older run does not qualify a newer package. Release checks are tied to the exact package being reviewed. Repository access is not needed to install or use a published release. See [installation](/docs/installation/) for npm publication status.
## Accessibility and review limits
Semantic labels, descriptions, validation errors and keyboard operation remain available continuously. Automated accessibility checks, keyboard/focus flows, zoom and reflow, reduced motion and forced colors are part of qualification. See [accessibility](/docs/accessibility/) for system preferences and optional interaction guidance.
Physical-device and assistive-technology certification, and qualified linguistic review of the optional language catalogs, have not been performed. Those reviews remain unperformed. Automated tests and rendered-image inspection do not replace those reviews.
## Supported boundaries
The package includes UI primitives, controls and compositions. Specialized data-grid, chart, advanced date/time, rich-text and virtualization engines remain separate extensions. Native-column Masonry and measured PackedMasonry have different layout contracts; the latter starts with a server-rendered grid fallback.
Portable customization, DTCG exchange and design-tool adapters have documented bounds. Design-tool host integration has separate limitations and is not required to build applications. Publishing the npm package and deploying the documentation site are separate operations.
---
# Component reference
Search every documented public UI component, inspect its package entry, and jump to the real executable example that uses it.
## Independent public API coverage
The reference derives components and compound parts from emitted package declarations using dependency-aware TypeScript symbol resolution. Manifest exports supply the complete public-entry denominator. Example registration does not determine which components exist.
Each component links to a readable reference page and a usage guide. Callable components and parts must have registered JSX use or an explicit documented disposition. Optional presentation, advanced grouping and server-only resources have stated reasons; this is source coverage, not interaction certification.
## Properties and parts
Reference pages list public exports, resolved component and compound-part properties, event callbacks, descriptor defaults, rendering boundaries and links to actual usage. Common React/native HTML attributes are intentionally omitted from property tables. Installed TypeScript declarations remain authoritative for inherited attributes, overloads, generics and discriminated unions.
## Machine access
The same index is published as [components](/api/components.json). [All public entries](/api/public-entries.json), [example coverage](/api/coverage.json), [explicit dispositions](/api/component-dispositions.json) and the [API index](/api/index.json) expose the independent inventory and coverage without browser execution.
## Executable example source
```tsx
'use client';
import { useMemo, useState } from 'react';
import Link from 'next/link';
import components from '../generated/components.json';
import { Input } from '@fayegram-ai/faye-ui/controls/input';
import { Badge } from '@fayegram-ai/faye-ui/feedback/badge';
import { Text } from '@fayegram-ai/faye-ui/core/text';
import { Stack } from '@fayegram-ai/faye-ui/layout/layout';
export default function ComponentReference() {
const [query, setQuery] = useState('');
const normalized = query.trim().toLowerCase();
const rows = useMemo(() => components.components.filter(item => !normalized || `${item.name} ${item.entry} ${item.pages.map(page => page.title).join(' ')}`.toLowerCase().includes(normalized)), [normalized]);
return {rows.length} of {components.components.length} documented UI components
{rows.map(item =>
{item.name}{item.clientBoundary && client}
{item.entry}
Properties and parts{item.pages.map(page => {page.title})}{!item.pages.length && Usage guide}API JSON
)}
;
}
```
---
# All components gallery
One visual QA route that renders every component-family example from the public documentation using the real Faye UI React components.
## Purpose
This page is the visual integration gallery for the component layer. It mounts every component-family documentation example using the actual exported Faye UI React components. It is deliberately large: the purpose is regression review, theme review, density review, responsive inspection and screenshot capture rather than a minimal application payload.
The gallery starts with a consumer journey, composed cards and dialogs, and interactive navigation. The consumer example exposes hints and validation directly; create a day to see circular/linear loading and a sliding confirmation, toggle the landscape to see a fade, and switch to the saved itinerary through the responsive navigation.
Use the normal family pages for focused learning. Use this gallery when reviewing a release, a theme, or a broad visual change.
## What this proves
When the real documentation application builds and this page executes without its error boundary, it proves that the documented component examples can coexist in one application tree. It does not by itself prove every state, keyboard path, server boundary, accessibility requirement or tree-shaking property; those remain separate verification gates.
## Screenshot policy
The documentation browser suite captures light, dark and mobile screenshots from this route after a successful build. A static CSS specimen is never substituted for those application screenshots.
## Executable example source
```tsx
'use client';
import ConsumerExperience from './consumer-experience';
import FunctionalCompletion from './functional-completion';
import SurfaceCompositions from './surface-compositions';
import InteractionCompositions from './interaction-compositions';
import Foundations from './foundations';
import Layout from './layout';
import Buttons from './buttons';
import Fields from './fields';
import Selection from './selection';
import Pickers from './pickers';
import Numeric from './numeric';
import Dialogs from './dialogs';
import Floating from './floating';
import Menus from './menus';
import Navigation from './navigation';
import Feedback from './feedback';
import Display from './display';
import Motion from './motion';
import Patterns from './patterns';
import Accessibility from './accessibility';
import { Heading, Text } from '@fayegram-ai/faye-ui/core/text';
import { Stack } from '@fayegram-ai/faye-ui/layout/layout';
const families = [
['Consumer experience', ConsumerExperience], ['Consumer navigation and feedback', FunctionalCompletion], ['Cards and composed surfaces', SurfaceCompositions], ['Interactive navigation and transitions', InteractionCompositions],
['Foundations', Foundations], ['Layout', Layout], ['Buttons and actions', Buttons],
['Fields and forms', Fields], ['Selection controls', Selection], ['Pickers', Pickers],
['Numeric inputs', Numeric], ['Dialogs and drawers', Dialogs], ['Floating content', Floating],
['Menus', Menus], ['Navigation', Navigation], ['Feedback', Feedback], ['Display', Display],
['Motion', Motion], ['Application patterns', Patterns], ['Accessibility guidance', Accessibility],
] as const;
export default function AllComponents() {
return {families.map(([name, Example]) => {name}Live Faye UI examples.)};
}
```
---
# Typography and surfaces
Semantic typography, surfaces, and server-safe rendering of explicitly imported Lucide and Faye icon artwork.
## Quick start
After the [application setup](/docs/installation/#component-consumption), copy this component into your application. It imports only public packages; the complete live demo later on this page also uses documentation layout helpers.
```tsx
import { Card, CardHeader, CardTitle, CardDescription, CardBody } from '@fayegram-ai/faye-ui/core/surface';
import { Text } from '@fayegram-ai/faye-ui/core/text';
export function StoryCard() {
return A little room for wonderIdeas for your next day out.Choose a place and make it your own.;
}
```
API reference: [Surface](/docs/api-core-surface/), [Text](/docs/api-core-text/).
## Usage contract
Static primitives can execute on the server without a client theme hook. Use explicit profiles for their nonvisual defaults. Card sections preserve structure; an icon requires an accessible name when it conveys meaning.
## Customization
Use semantic tokens for visual changes, public component parts for structural customization, and explicit props for instance behavior. The surrounding site lets you compare light and dark, different brands and density.
## Source and verification
The examples below import actual public package entries. Full source is downloadable. Source coverage does not establish keyboard, hydration or browser compatibility; those require the application test suite.
## Semantic typography
Text and Heading support display, six heading roles, body/body-large, caption, label, overline and code. A visual role controls family, size, weight, line height and tracking. It never implicitly changes the semantic element or heading level. Explicit profiles and type augmentation remain available for server-safe use.
## Faye UI icon system
Faye UI uses two independent artwork sources behind one server-safe SVG renderer. `@lucide/icons@1.52.0` supplies pinned upstream data without a fork. `@fayegram-ai/faye-ui/icons` supplies Faye-owned data; its initial `FayeMark` is the organization mark and preserves the existing favicon letterform. `@fayegram-ai/faye-ui/contracts/icon` defines and validates portable artwork. `@fayegram-ai/faye-ui/core/icon` renders either source and imports neither collection.
## Installation and rendering
Install `@fayegram-ai/faye-ui` with its declared React peers. Import the renderer from `@fayegram-ai/faye-ui/core/icon` and organization artwork from `@fayegram-ai/faye-ui/icons`; these are module paths inside that one package. Upstream artwork uses the pinned `@lucide/icons@1.52.0` data package. The package is currently unpublished; see [installation](/docs/installation/) for availability.
```tsx
import { Search } from '@lucide/icons';
import { FayeMark } from '@fayegram-ai/faye-ui/icons';
import { Icon } from '@fayegram-ai/faye-ui/core/icon';
export function ArtworkExample() {
return <>
>;
}
```
Faye UI supports typed per-icon entrypoints, for example `import { FayeMark } from '@fayegram-ai/faye-ui/icons/faye-mark'`. Use Lucide's typed named root exports; the pinned raw package's `icons/*` entries do not supply individual declarations. Both root imports preserve tree shaking in the installed consumers. Avoid a namespace import, the upstream `icons` catalogue object, dynamic name imports, or a global registry in application/library code. A local lookup map containing explicitly imported entries is supported and retains those entries only.
The renderer produces one SVG and requires no client provider or browser state. It works in client, SSR and RSC consumers. React 19 `ref` reaches the SVG through ordinary prop forwarding. Normal public entries own their local CSS; native Node SSR uses the `faye-ui-ssr` condition and the host delivers CSS separately, as with other Faye UI primitives.
## Inputs and property precedence
Use either `icon` data or SVG children. TypeScript rejects both inputs together; runtime rendering also rejects that combination. Existing children-based calls remain supported:
```tsx
import { Icon } from '@fayegram-ai/faye-ui/core/icon';
export function CustomActionArtwork() {
return ;
}
```
Explicit SVG rendering props override definition root defaults, which override renderer defaults. Node-local drawing attributes retain ordinary SVG inheritance; root props do not erase deliberately filled paths, local transforms, or local stroke choices. Explicit `viewBox` overrides the definition's viewBox. An omitted definition viewBox derives from `size`, paired `width`/`height`, or the 24-unit default. Non-square coordinate spaces keep SVG's normal aspect-ratio behavior.
New outlined data defaults to `fill="none"`, `stroke="currentColor"`, a 2-unit stroke and round caps/joins. Legacy children retain their 1.6-unit stroke. Filled definitions such as FayeMark supply `fill="currentColor"` and `stroke="none"`; their viewBoxes and drawing attributes are preserved. Set a root `color`/CSS color to affect inherited `currentColor`, or explicit drawing props for a specific rendering choice.
Sizes `xs`, `sm`, `md`, and `lg` use 12, 16, 18, and 24px intrinsic frames, with corresponding `--faye-ui-size-icon-*` CSS tokens. Coordinate dimensions describe artwork, not control height. Token styles determine the displayed frame when CSS is present. Explicit CSS sizing can override that frame; width/height attributes remain intrinsic fallback dimensions. Icons do not add control padding or define pointer targets.
## Accessibility and direction
Explicit ARIA attributes take precedence. Otherwise `label` supplies `aria-label` and a named icon defaults to `role="img"`. An unnamed icon defaults to `aria-hidden="true"` and `focusable="false"`. Give an icon-only button its action name on the button and leave the nested artwork decorative. Use `aria-labelledby` for a shared visible name. Callers control intentional role, focusability, or hidden-state overrides.
Mirroring is opt-in: `mirrorInRtl` overrides optional definition `rtl: 'mirror'`; definitions without either stay unchanged. Set `dir="rtl"`/`dir="ltr"` on an ancestor or the SVG itself. Faye UI's directional scopes already emit those attributes. The inherited CSS direction variable handles nested overrides without a provider. `dir="auto"` and CSS-only direction changes are not the mirroring contract; use an explicit direction attribute.
The renderer mirrors an inner artwork group around its viewBox center. Outer SVG positioning transforms and authored nested transforms remain intact. Pagination/back/navigation arrows request mirroring. Nondirectional checks, close marks and search icons do not. NativeSelect still restores its system arrow in forced-colors mode; generic artwork inherits system colors through `currentColor`. Automated coverage does not replace human forced-colors or screen-reader review.
## Portable custom artwork
Definitions contain plain data, not React elements, functions, event handlers or browser state. The shared contract supports nested `g` nodes, `path`, `circle`, `rect`, `line`, `ellipse`, `polyline`, and `polygon`. It supports positive square `size` or paired `width`/`height`, a four-number viewBox, root drawing defaults, optional aliases/name, and optional RTL behavior.
```ts
import type { IconDefinition } from '@fayegram-ai/faye-ui/contracts/icon';
export const ExampleArtwork = {
name: 'example-artwork',
width: 32,
height: 16,
viewBox: [0, 0, 32, 16],
defaults: { fill: 'currentColor', stroke: 'none' },
node: [['g', { transform: 'translate(1 1)' }, [
['rect', { x: 0, y: 0, width: 8, height: 6 }],
]]],
} as const satisfies IconDefinition;
```
`validateIconDefinition(definition)` validates authored data without React/DOM and returns the same object. The renderer validates data before creating SVG nodes. Both camelCase and ordinary hyphenated SVG drawing attributes are supported. Geometry and drawing attributes are allowlisted; `key`, `class`/`className`, and local `transform` are also supported on nodes. Root defaults accept drawing attributes only.
Unsupported data includes embedded SVG wrappers, text, XML, scripts, foreignObject, use/href, defs, gradients, filters, masks, clipPath resources, animation nodes, URL paint references, event attributes, and style objects. Limits are 512 nodes, depth 16, and 65,536 characters per string attribute. Numbers must be finite; dimensions must be positive. Do not cast unsupported data to silence TypeScript. The plain-data restrictions apply to definitions; supported legacy children remain a caller-authored React/SVG compatibility path.
## Authoring custom artwork
Create a named constant satisfying `IconDefinition`, then pass it to `Icon` through its `icon` property. Validate it with `validateIconDefinition` before rendering. Keep the artwork's coordinate space explicit, use drawing attributes supported by the validator, and add RTL metadata only when direction changes its meaning. Your application owns custom artwork licensing and attribution.
The renderer imports neither artwork catalog automatically. Choose only the definitions your application needs. Upgrade an external icon dependency deliberately and check its type, geometry and license changes.
The package's `LICENSE` retains applicable upstream ISC and Feather MIT notices. Faye-owned artwork uses MIT. Raw Lucide artwork remains an external dependency.
## Labeled separators
Separator accepts children for a visible section label and `textAlign="start"`, `"center"` or `"end"`. Decorative lines remain separate from meaningful text. Set `decorative={false}` when the separator itself needs structural semantics. Both horizontal and vertical separators remain available.
## Executable example source
```tsx
import { Plus, Search, ArrowLeft } from '@lucide/icons';
import { FayeMark } from '@fayegram-ai/faye-ui/icons';
import { ThemeScope } from '@fayegram-ai/faye-ui/provider/provider';
import { ScopedBaseline } from '@fayegram-ai/faye-ui/core/scoped-baseline';
import { Box } from '@fayegram-ai/faye-ui/core/box';
import { Text, Heading } from '@fayegram-ai/faye-ui/core/text';
import { Surface, Card, CardHeader, CardBody, CardFooter } from '@fayegram-ai/faye-ui/core/surface';
import { Separator } from '@fayegram-ai/faye-ui/core/separator';
import { Code, Kbd } from '@fayegram-ai/faye-ui/core/code';
import { Icon } from '@fayegram-ai/faye-ui/core/icon';
import { VisuallyHidden, SkipLink } from '@fayegram-ai/faye-ui/core/visually-hidden';
import { Inline, Stack } from '@fayegram-ai/faye-ui/layout/layout';
import { Section } from '../example';
export default function Foundations() {
return <>Structure before decorationA readable baseline for product interfaces.Use semantic roles; the same tokens resolve in both schemes.color.text is a meaning, not a palette index. Press Tab to explore.Import artwork explicitly; icons inherit color through the shared renderer.A deliberately long title that may be truncated in a constrained layout while preserving the original text.Additional screen-reader context.{(["xs", "sm", "md", "lg"] as const).map(size => {size})}Directional artwork mirrors inside its positioned frame.SVG children remain supported with their original stroke default.{(['plain', 'subtle', 'outlined', 'raised'] as const).map(variant => {variant})}Research workspaceHeader, body and footer share spacing, not business rules.Updated locallySkip this preview>;
}
```
---
# Layout primitives
Responsive grids, spacing, constraints, container boundaries and native columns.
## Quick start
After the [application setup](/docs/installation/#component-consumption), copy this component into your application. It imports only public packages; the complete live demo later on this page also uses documentation layout helpers.
```tsx
import { Container, Grid, Stack, Inline, AspectRatio } from '@fayegram-ai/faye-ui/layout/layout';
import { Card, CardBody } from '@fayegram-ai/faye-ui/core/surface';
export function ResponsiveCards() {
return PlacesCollections
{['Coast', 'Gardens', 'City'].map(name => {name})}
;
}
```
API reference: [Surface](/docs/api-core-surface/).
## Usage contract
The responsive class vocabulary is finite and validated. GridItem adds span, start and order. Use logical direction rather than left/right layout assumptions. CSS column masonry has column-major reading order; do not use it when row-major order is essential.
## Customization
Use semantic tokens for visual changes, public component parts for structural customization, and explicit props for instance behavior. The surrounding site lets you compare light and dark, different brands and density.
## Source and verification
The examples below import actual public package entries. Full source is downloadable. Source coverage does not establish keyboard, hydration or browser compatibility; those require the application test suite.
## Executable example source
```tsx
import { Stack, Inline, Cluster, Grid, Container, Center, Spacer, Split, AspectRatio, Bleed, QueryContainer } from '@fayegram-ai/faye-ui/layout/layout';
import { GridItem } from '@fayegram-ai/faye-ui/layout/grid-item';
import { Masonry } from '@fayegram-ai/faye-ui/layout/masonry';
import { Text } from '@fayegram-ai/faye-ui/core/text';
import { Section } from '../example';
const Cell = ({ children }: {
children: React.ReactNode;
}) =>
{children}
;
export default function Layout() {
return <>8 / 12, full width on narrow screens4 / 12Full rowLeadingTrailing{['Research', 'Design', 'Engineering', 'Operations'].map(x => {x})}
Centered without a custom margin rule
ContextThe containing element is the responsive boundary.
3:1 content region
Controlled half-gutter bleed
{[2, 4, 3, 5, 2, 4].map((n, i) =>
Item {i + 1}
{Array.from({ length: n }, (_, j) =>
Variable content height.
)})}>;
}
```
---
# Buttons and actions
Variants, intent, sizing, pending states, composition and toggles.
## Quick start
After the [application setup](/docs/installation/#component-consumption), copy this component into your application. It imports only public packages; the complete live demo later on this page also uses documentation layout helpers.
```tsx
'use client';
import { useState } from 'react';
import { Button } from '@fayegram-ai/faye-ui/controls/button';
import { Chip } from '@fayegram-ai/faye-ui/controls/chip';
import { Inline } from '@fayegram-ai/faye-ui/layout/layout';
export function FavoriteAction() {
const [favorite, setFavorite] = useState(false);
return setFavorite(value => !value)}>Favorite;
}
```
API reference: [Button](/docs/api-controls-button/), [Chip](/docs/api-controls-chip/).
## Usage contract
Native button semantics are retained. A pending action is disabled against duplicate activation. Provide a name for icon-only controls. A link-shaped button should render an anchor with a real href, not emulate navigation with click handlers.
## Customization
Use semantic tokens for visual changes, public component parts for structural customization, and explicit props for instance behavior. The surrounding site lets you compare light and dark, different brands and density.
## Source and verification
The examples below import actual public package entries. Full source is downloadable. Source coverage does not establish keyboard, hydration or browser compatibility; those require the application test suite.
## Geometry and pending state
Long button labels wrap within the available width, including with enlarged text. Leading and trailing icons keep their size alongside the label; icon-only buttons remain square. Toggle groups keep a single scrollable row when space is limited, with keyboard focus bringing the active control into view. Set `orientation="vertical"` for a column and matching up/down keyboard navigation.
The outer border box uses the shared control heights: small 32/28px, medium 36/32px, large 44/36px in comfortable/compact density. Coarse-pointer buttons have at least a 44px target. Pass `pending={busy}` in both states. The default `pendingPosition="center"` keeps the idle label centered, then replaces it with a spinner while retaining the accessible name and dimensions. Use `pendingPosition="start"` or `"end"` to keep the label visible and reserve an indicator slot on that side. Pending actions expose `aria-busy` without the faded unavailable appearance. IconButton also defaults to the centered presentation. `pendingIndicator` accepts custom progress artwork. Use a native submit button inside a form for Enter/pointer parity and an explicit reset/cancel policy for drafts.
## Content spacing and icon alignment
Horizontal inset is 4/8/8/12px for xs/sm/md/lg; icon-to-label gap is 4/4/6/8px. These insets sit inside the existing outer-height contract. IconButton has zero horizontal padding at every size, keeping its icon centered inside the square border. Icons and labels share a centered flex row. Use `startIcon` and `endIcon` for decorative artwork before and after the label; these slots are hidden from assistive technology by default, so keep the accessible action name in the label. Both slots are configurable component parts (`start-icon` and `end-icon`) and follow logical direction. Supply tightly bounded SVG artwork at the intended icon size; extra whitespace inside a custom SVG viewBox remains part of the artwork. Pending labels retain their dimensions.
## Grouped and chip actions
`ButtonGroup` supports horizontal and vertical orientation, with shared size, tone, variant and disabled defaults. Explicit child props win. For a split button, put a primary Button and a Menu.Trigger rendered as an IconButton inside the group; Menu continues to own focus and dismissal.
Chip is passive by default. `onClick` creates a native primary button; `href` creates a link. `selected` supplies pressed semantics for an action and current-page semantics for a link. `onRemove` adds a separate labeled button. Disabled chips disable both controls. Leading/trailing artwork, soft/outline presentation, sm/md sizes and wrapping policy are supported. Keep the label text meaningful and give each remove action a specific `removeLabel`.
Use `startIcon` and `endIcon` separately or together. Both slots are decorative, use the same size-dependent gap and remain centered in RTL. For a removable chip that can be restored inline, reserve the footprint of both states so adjacent filters do not move. The live example uses the same Chip frame for removal and restoration.
## Executable example source
```tsx
'use client';
import { Plus, ArrowRight, RotateCcw } from '@lucide/icons';
import { useEffect, useRef, useState } from 'react';
import { Button, IconButton, ButtonGroup } from '@fayegram-ai/faye-ui/controls/button';
import { Link } from '@fayegram-ai/faye-ui/controls/link';
import { Toggle } from '@fayegram-ai/faye-ui/controls/toggle';
import { ToggleGroup } from '@fayegram-ai/faye-ui/controls/toggle-group';
import { Chip } from '@fayegram-ai/faye-ui/controls/chip';
import { Inline, Stack } from '@fayegram-ai/faye-ui/layout/layout';
import { Icon } from '@fayegram-ai/faye-ui/core/icon';
import { Section, Result } from '../example';
export default function Buttons() {
const designRef = useRef(null), restoreRef = useRef(null), moveChipFocus = useRef(false);
const [count, setCount] = useState(0), [pending, setPending] = useState(false), [chip, setChip] = useState(true), [favorite, setFavorite] = useState(false), [alignment, setAlignment] = useState(['start']);
useEffect(() => {
if (moveChipFocus.current) {
(chip ? designRef : restoreRef).current?.querySelector('button')?.focus({preventScroll:true});
moveChipFocus.current = false;
}
}, [chip]);
return <>{(['solid', 'outline', 'soft', 'ghost'] as const).map(variant => {(['neutral', 'accent', 'secondary', 'danger', 'success', 'warning', 'info'] as const).map(tone => )})}Actions activated: {count}{(['xs','sm','md','lg'] as const).map(size=>} data-testid={`leading-${size}`} onClick={()=>setCount(n=>n+1)}>New project} data-testid={`trailing-${size}`} onClick={()=>setCount(n=>n+1)}>Continue} endIcon={} data-testid={`both-${size}`} onClick={()=>setCount(n=>n+1)}>Create and open)}{(['xs', 'sm', 'md', 'lg'] as const).map(size => )} setCount(n => n + 1)}>}>Composed anchorTheme documentationStartCenterEnd {moveChipFocus.current = true; setChip(false);}} removeLabel="Remove design filter">Design {moveChipFocus.current = true; setChip(true);}} leading={}>Restore chipRead-only label setFavorite(value => !value)}>FavoritesFeedback guideAlignment: {alignment.join(', ') || 'none'}>;
}
```
---
# Text fields and forms
Native form values, validation, adornments, multiline input and reset.
## Quick start
After the [application setup](/docs/installation/#component-consumption), copy this component into your application. It imports only public packages; the complete live demo later on this page also uses documentation layout helpers.
```tsx
'use client';
import { useState } from 'react';
import { TextField } from '@fayegram-ai/faye-ui/controls/text-field';
import { TextareaField } from '@fayegram-ai/faye-ui/controls/textarea-field';
import { Button } from '@fayegram-ai/faye-ui/controls/button';
import { Stack } from '@fayegram-ai/faye-ui/layout/layout';
export function ContactForm() {
const [email, setEmail] = useState('');
const [error, setError] = useState();
return ;
}
```
API reference: [Text Field](/docs/api-controls-text-field/), [Textarea Field](/docs/api-controls-textarea-field/), [Button](/docs/api-controls-button/).
## Usage contract
TextField is a convenience composition. Field and Fieldset expose validation anatomy. InputAdornment is a sibling, not a hidden label substitute. AutosizeTextarea measures browser geometry after mounting and remains a normal textarea for forms.
`AutosizeTextarea` recalculates its row bounds after React updates, including changes to typography, padding, and classes, as well as edits and observed width changes. Its `form` prop can associate it with an external form, including one mounted later or replaced without changing its ID. Native resets restore both the value and the measured height, and repeating an edit after a reset still resizes the field. A canceled reset preserves the draft and its height. Content beyond `maxRows` scrolls within the field.
## Customization
Use semantic tokens for visual changes, public component parts for structural customization, and explicit props for instance behavior. The surrounding site lets you compare light and dark, different brands and density.
## Source and verification
The examples below import actual public package entries. Full source is downloadable. Source coverage does not establish keyboard, hydration or browser compatibility; those require the application test suite.
## Disabled and read-only composition
Disabled surface styling takes precedence when an input or textarea also has `readOnly`. This applies to standalone fields and `InputGroup` frames, including frames that infer disabled state from their input. The distinction remains correct when a custom theme gives the two states different surface colors.
## Executable example source
```tsx
'use client';
import { ArrowUpRight } from '@lucide/icons';
import { Icon } from '@fayegram-ai/faye-ui/core/icon';
import { useState } from 'react';
import { InputGroup, InputAdornment } from '@fayegram-ai/faye-ui/controls/input-group';
import { Input, Textarea } from '@fayegram-ai/faye-ui/controls/input';
import { AutosizeTextarea } from '@fayegram-ai/faye-ui/controls/autosize-textarea';
import { TextField } from '@fayegram-ai/faye-ui/controls/text-field';
import { NativeSelect } from '@fayegram-ai/faye-ui/controls/native-select';
import { Field } from '@fayegram-ai/faye-ui/controls/field';
import { FieldLayout } from '@fayegram-ai/faye-ui/controls/field-layout';
import { Fieldset } from '@fayegram-ai/faye-ui/controls/fieldset';
import { Form } from '@fayegram-ai/faye-ui/controls/form';
import { Button } from '@fayegram-ai/faye-ui/controls/button';
import { Stack, Inline } from '@fayegram-ai/faye-ui/layout/layout';
import { Section, Result } from '../example';
import AdvancedFields from './advanced-fields';
export default function Fields() {
const [result, setResult] = useState('Submit to inspect native FormData.');
return <>https://{attrs => }>;
}
```
---
# Advanced field compositions
Native forms, shared input frames, grouped selections, editable tags and asynchronous recovery in a themed dialog.
## Quick start
After the [application setup](/docs/installation/#component-consumption), copy this component into your application. It imports only public packages; the complete live demo later on this page also uses documentation layout helpers.
```tsx
'use client';
import { useState } from 'react';
import { Eye, EyeOff } from '@lucide/icons';
import { Icon } from '@fayegram-ai/faye-ui/core/icon';
import { IconButton } from '@fayegram-ai/faye-ui/controls/button';
import { TextField } from '@fayegram-ai/faye-ui/controls/text-field';
export function PasswordField() {
const [visible, setVisible] = useState(false);
return setVisible(value => !value)}>
} />;
}
```
API reference: [Icon](/docs/api-core-icon/), [Button](/docs/api-controls-button/), [Text Field](/docs/api-controls-text-field/).
## Shared field anatomy
Use TextField for a single-line input and TextareaField for multiline content. Both apply the same field label, description and error profiles, preserve native refs and form associations, and accept zero-valued helper content. TextareaField can autosize between minRows and maxRows while retaining native reset behavior. FieldLayout passes stable accessible attributes to native selects, custom selection triggers and number inputs.
TextField accepts startAdornment and endAdornment. The containing InputGroup owns one border and focus ring, derives invalid/read-only/disabled appearance from the actual input, and keeps adornments as siblings. Interactive adornments need their own names and disabled state. Use frame={false} for an intentionally frameless sibling layout.
## Selection and asynchronous ownership
Select.Root and Combobox.Root preserve their original generic value types. Grouped and multiple values, serialization, comparison and labels remain explicit. The example renders the completed Chip inside Combobox.Chip and uses Combobox.ChipRemove for the selection engine's keyboard/focus behavior. New tag values are owned by this example's application state.
The destination search uses AbortController, cancels superseded requests and refuses stale results. Query “old” takes longer than other queries; “fail” simulates a retryable error. The form's first save fails deliberately, then retry succeeds. Values remain editable and retained after error or cancellation. Reset restores the initial draft. These are local deterministic simulations, not a backend or a library-owned query cache.
## Native behavior
Names, required fields, FormData, refs, autocomplete hints and external form association reach the actual control. Password visibility changes only the input type. Controlled clear/count/reset operations belong to the application. Do not intercept composition events to implement filtering or shortcuts; continue to use the native composition and change stream.
## Executable example source
```tsx
'use client';
import { useEffect, useId, useRef, useState } from 'react';
import { Eye, EyeOff, X, Search, Plus, Minus } from '@lucide/icons';
import { Heading, Text } from '@fayegram-ai/faye-ui/core/text';
import { Icon } from '@fayegram-ai/faye-ui/core/icon';
import { Stack, Inline, Grid } from '@fayegram-ai/faye-ui/layout/layout';
import { ThemeScope } from '@fayegram-ai/faye-ui/provider/provider';
import { Button, IconButton } from '@fayegram-ai/faye-ui/controls/button';
import { TextField } from '@fayegram-ai/faye-ui/controls/text-field';
import { TextareaField } from '@fayegram-ai/faye-ui/controls/textarea-field';
import { FieldLayout } from '@fayegram-ai/faye-ui/controls/field-layout';
import { NativeSelect } from '@fayegram-ai/faye-ui/controls/native-select';
import { Select } from '@fayegram-ai/faye-ui/controls/select';
import { Combobox } from '@fayegram-ai/faye-ui/controls/combobox';
import { NumberField } from '@fayegram-ai/faye-ui/controls/number-field';
import { Chip } from '@fayegram-ai/faye-ui/controls/chip';
import { Modal } from '@fayegram-ai/faye-ui/overlays/modal';
import { Spinner } from '@fayegram-ai/faye-ui/feedback/loading';
import { LinearProgress } from '@fayegram-ai/faye-ui/feedback/progress';
// A deterministic local service demonstrates ownership; no backend is contacted.
function wait(milliseconds: number, signal: AbortSignal): Promise {
return new Promise((resolve, reject) => {
const abort = () => { clearTimeout(timer); reject(new DOMException('Canceled', 'AbortError')); };
const timer = setTimeout(() => { signal.removeEventListener('abort', abort); resolve(); }, milliseconds);
signal.addEventListener('abort', abort, { once: true });
if (signal.aborted) abort();
});
}
const destinations = [{ id: 'lisbon', label: 'Lisbon' }, { id: 'oslo', label: 'Oslo' }, { id: 'tokyo', label: 'Tokyo' }, { id: 'old-town', label: 'Old town' }];
const topicGroups = [{ label: 'Outside', items: ['Nature', 'Walking'] }, { label: 'Culture', items: ['Design', 'Food'] }];
const knownTags = ['Weekend', 'Friends', 'Photography'];
export function AsyncDestination() {
const id = useId(), [query, setQuery] = useState(''), [retry, setRetry] = useState(0);
const [selected, setSelected] = useState<(typeof destinations)[number] | null>(null);
const [results, setResults] = useState([]), [status, setStatus] = useState('idle');
const request = useRef(null);
useEffect(() => {
const controller = new AbortController(); request.current = controller;
if (!query.trim()) { setResults([]); setStatus('idle'); return () => controller.abort(); }
setStatus('loading'); setResults([]);
wait(query.toLowerCase() === 'old' ? 450 : 150, controller.signal).then(() => {
if (controller.signal.aborted) return;
if (query.toLowerCase() === 'fail' && retry === 0) throw Error('Search unavailable');
setResults(query.toLowerCase() === 'fail' ? destinations : destinations.filter(item => item.label.toLowerCase().includes(query.toLowerCase())));
setStatus('ready');
}).catch(() => { if (!controller.signal.aborted) setStatus('error'); });
return () => { controller.abort(); if (request.current === controller) request.current = null; };
}, [query, retry]);
return { setSelected(value); if (value) setQuery(value.label); }} inputValue={query} onInputValueChange={(value, details) => { if (details.reason === 'input-change' || details.reason === 'clear-press') { setQuery(value); setSelected(current => current?.label === value ? current : null); } else details.cancel(); }} itemToStringLabel={item => item.label} itemToStringValue={item => item.id} isItemEqualToValue={(a, b) => a.id === b.id} name="destination">
{status === 'loading' ? 'Searching destinations…' : status === 'error' ? 'Search unavailable. Your query is retained.' : status === 'canceled' ? 'Search canceled.' : status === 'ready' ? `${results.length} ${results.length === 1 ? 'destination' : 'destinations'} found.` : 'Enter a destination.'}
{attrs => }
{status === 'error' && }
{(item: (typeof destinations)[number]) => {item.label}}{status === 'loading' ? Searching… : status === 'error' ? 'Search unavailable. Use Retry destination search.' : 'No destinations found.'};
}
export default function AdvancedFields() {
const id = useId(), [open, setOpen] = useState(false), [visible, setVisible] = useState(false);
const [title, setTitle] = useState('Weekend stories'), [description, setDescription] = useState('A few places worth remembering.'), [secret, setSecret] = useState('');
const [access, setAccess] = useState('private'), [topics, setTopics] = useState(['Nature']), [tags, setTags] = useState(['Weekend']), [tagQuery, setTagQuery] = useState('');
const [limit, setLimit] = useState(3), [pending, setPending] = useState(false), [error, setError] = useState(''), [titleError, setTitleError] = useState(''), [result, setResult] = useState('');
const titleRef = useRef(null), tagRef = useRef(null), request = useRef(null), attempts = useRef(0);
useEffect(() => () => request.current?.abort(), []);
const cancel = () => { request.current?.abort(); request.current = null; setPending(false); };
const reset = () => { cancel(); setTitle('Weekend stories'); setDescription('A few places worth remembering.'); setSecret(''); setAccess('private'); setTopics(['Nature']); setTags(['Weekend']); setTagQuery(''); setLimit(3); setError(''); setTitleError(''); setResult(''); };
const tagItems = [...new Set([...knownTags, ...tags, ...(tagQuery.trim() ? [tagQuery.trim()] : [])])];
return Compose a collectionThis local form deliberately fails its first save so draft retention and retry can be tried. No server is contacted.{result} { if (!value) cancel(); setOpen(value); }} title="Edit your collection" description="Keep the details that matter to you." size="lg">
;
}
```
---
# Cards, media and composed dialogs
Native independent card actions, interactive lists, packed media and consistent scrollable dialog anatomy.
## Quick start
After the [application setup](/docs/installation/#component-consumption), copy this component into your application. It imports only public packages; the complete live demo later on this page also uses documentation layout helpers.
```tsx
import { Card, CardHeader, CardTitle, CardDescription, CardMedia, CardBody, CardActions } from '@fayegram-ai/faye-ui/core/surface';
import { Button } from '@fayegram-ai/faye-ui/controls/button';
export function PlaceCard() {
return Take the scenic routeA gentle walk by the water.Allow an hour and bring a good book.}>Explore this place;
}
```
API reference: [Surface](/docs/api-core-surface/), [Button](/docs/api-controls-button/).
## Cards and independent actions
Card remains server-renderable. Use explicit card profiles on the root and parts: header, avatar, action, title, description, media, body, actions and primary-action. CardTitle supports semantic heading levels. CardMedia owns a positive aspect ratio and crops image/video content with object-fit. Supply intrinsic image dimensions when known.
Card owns the gap between its parts. CardFooter remains an alias for the actions region. Header avatar/action slots leave the content flexible and keep secondary actions separate. CardPrimaryAction stretches a native link or button over the card using a pseudo-element; put secondary controls in CardActions or CardHeader.action, which sit above that region. Do not wrap a card containing buttons inside another button or link.
## Lists and image compositions
ListItemButton uses native button activation and disabled behavior; selected exposes aria-pressed. Put independent controls in ListItem.trailing. ListSubheader provides an actual heading within a presentation list entry. Navigation destinations can use an ordinary link inside ListItem rather than exposing toggle semantics.
ImageList supports standard, quilted and woven layouts. Quilt item columns/rows are explicit; narrow containers reduce spans to one. ImageListItem owns a stable ratio, caption and action region. Captions may sit below the image or overlay it with a readable themed surface.
## Two masonry contracts
Masonry uses native CSS columns and column-major reading order. PackedMasonry is an opt-in client component that assigns each successive item to the shortest column without reordering DOM or tab order. It observes content, fonts, image loading and container size. Container padding and borders are preserved in both box-sizing models, including RTL layouts; row and column gaps are independent, and changing styled gaps reflows the collection even when its children are unchanged. The server output is a usable responsive grid until hydration measures it; no server-side height is guessed. Use explicit image sizes/ratios to limit movement. Avoid CSS transforms on the packing wrappers; animate content inside them.
## Dialog anatomy and ownership
Dialog and AlertDialog expose Header, Body and Actions. Popup owns the gap between these parts; Title and Description have no outside margins. A direct Body child scrolls within a bounded popup while header/actions remain visible. Use Viewport for full-document scrolling of a long dialog when that is preferable. Modal composes the same parts.
Base UI continues to own focus trapping, inert background, dismissal, nested overlay behavior and exit lifetime. Portal transports provider theme/density/direction and custom properties. Backdrop by itself is visual only; Portal by itself does not create a modal. Use the compound overlay for accessible modal behavior.
## Executable example source
```tsx
'use client';
import { useState } from 'react';
import { Bookmark, Heart, MapPin, Trash2, X, ArrowRight } from '@lucide/icons';
import { Icon } from '@fayegram-ai/faye-ui/core/icon';
import { Card, CardHeader, CardTitle, CardDescription, CardMedia, CardBody, CardActions, CardPrimaryAction, Surface } from '@fayegram-ai/faye-ui/core/surface';
import { Text, Heading } from '@fayegram-ai/faye-ui/core/text';
import { Stack, Grid, Inline } from '@fayegram-ai/faye-ui/layout/layout';
import { PackedMasonry } from '@fayegram-ai/faye-ui/display/packed-masonry';
import { ImageList, ImageListItem } from '@fayegram-ai/faye-ui/display/image-list';
import { List, ListItem, ListItemButton, ListSubheader } from '@fayegram-ai/faye-ui/display/list';
import { Avatar } from '@fayegram-ai/faye-ui/display/avatar';
import { Badge } from '@fayegram-ai/faye-ui/feedback/badge';
import { Button, IconButton } from '@fayegram-ai/faye-ui/controls/button';
import { TextField } from '@fayegram-ai/faye-ui/controls/text-field';
import { Dialog } from '@fayegram-ai/faye-ui/overlays/dialog';
import { AlertDialog } from '@fayegram-ai/faye-ui/overlays/alert-dialog';
import { ThemeScope } from '@fayegram-ai/faye-ui/provider/provider';
const subjects = ['Coastal paths','A slower morning','Hidden gardens','Weekend stories','Old town','Open water'];
const artwork = (index:number) => `data:image/svg+xml,${encodeURIComponent(``)}`;
export default function SurfaceCompositions() {
const [saved,setSaved] = useState(false),[selected,setSelected] = useState('Coastal paths'),[removed,setRemoved]=useState(false),[long,setLong]=useState(false);
return AL} action={setSaved(s=>!s)}>}>Coastal pathsCurated by Alex · 6 placesRoom to wander, a place to pause. Save a few places for your next day outside.Ready to explore}>Explore coastal pathsCoastal paths detailsA collection for slower weekends.Six walks connected by open water and small cafés.}>Back to discoveryYour collectionsSaved for later{subjects.slice(0,3).map((title,i)=>} trailing={setSelected(title)}>}>setSelected(title)}>{title})}{selected}}>Open composed collection dialogA long collection editor}/>Header and actions remain reachable while the content scrolls.{Array.from({length:14},(_,i)=>Place {i+1}: A longer description with room for a meaningful name and details, without changing the surrounding frame.)}}>Remove nested collectionRemove this collection?Your original places stay available.Only the saved grouping is removed in this local example.}>Keep collection} onClick={()=>setRemoved(true)}>Remove collection{removed?'Collection removed.':'Collection retained.'}}>Finish editing collection
{(['standard','quilted','woven'] as const).map(variant=>{variant} image list{subjects.slice(0,4).map((subject,i)=>event.currentTarget.setAttribute('aria-pressed',event.currentTarget.getAttribute('aria-pressed')==='true'?'false':'true')} aria-pressed={false}>}>)})}
Packed collections{subjects.map((subject,i)=>{subject}{i===0&&long?'A much longer story. '.repeat(20):'A small collection for a new perspective.'})};
}
```
---
# Motion and interactive navigation
Responsive mixed toolbar, scrollable tabs, interactive stepper and keyed content transitions.
## Quick start
After the [application setup](/docs/installation/#component-consumption), copy this component into your application. It imports only public packages; the complete live demo later on this page also uses documentation layout helpers.
```tsx
'use client';
import { useState } from 'react';
import { Tabs } from '@fayegram-ai/faye-ui/navigation/tabs';
import { Stepper } from '@fayegram-ai/faye-ui/navigation/stepper';
import { Stack } from '@fayegram-ai/faye-ui/layout/layout';
export function PlanningSteps() {
const [step, setStep] = useState('place');
return PlanSaved ideasCurrent stage: {step}Your saved ideas go here.;
}
```
API reference: [Tabs](/docs/api-navigation-tabs/), [Stepper](/docs/api-navigation-stepper/).
## Motion with ownership
Presence, Fade, Slide, Collapse and Scale own ordinary content lifetime. Keep Base UI dialogs, popovers, sheets and their backdrops on their existing lifecycle. Presence forwards its root ref and accepts enterDuration/exitDuration in milliseconds; durations must be finite and nonnegative. CSS token defaults remain the default and reduced-motion policy overrides custom durations.
Slide direction is the starting edge (up/down/left/right/start/end). Logical start/end follow computed text direction. An optional container element/ref moves the content fully beyond that boundary; clip the container if that is the intended effect. Without a container, the default is a small offset. Collapse can animate vertical intrinsic height or horizontal content width; horizontal children own a deliberate width. Scale accepts scaleOrigin.
TransitionGroup children require unique explicit stable keys. Removed children remain inert during exit; restoring a key before completion cancels removal and retains child state. After completed removal, adding the key mounts new state. Stack mode defaults to collapse, so the space occupied by exiting content shrinks. Overlap mode layers route/view content in one grid area. Reordering preserves keyed state; no physics-based position interpolation is implied. Router state and focus destination after removing a focused item remain application decisions.
## Scrollable tabs and toolbars
Tabs.ScrollableList adds logical previous/next controls to the existing tab list. It keeps focused tabs visible, measures overflow and works in RTL. Scroll controls use aria-disabled at an edge while remaining focusable, so reaching the edge does not discard keyboard focus. Labels and part styles are configurable. Use Tabs.List for a vertical list.
The collection toolbar mixes a search input, actions, a pressed toggle and a menu. Secondary actions move into the menu at the compact breakpoint. The same action handlers serve both views; focus moves to the persistent More control if its focused secondary action disappears. Menu and roving toolbar focus remain owned by Base UI. This is a recipe: application priorities determine which actions overflow.
## Interactive and mobile steps
Stepper is a static overview when onStepChange is omitted. Supplying it renders native buttons, with linear gating by default and an explicit nonLinear option. Applications own activeStep, completion, optional steps, errors and validation. Disabled steps cannot activate. Vertical mode keeps descriptions and errors next to the numbered indicator.
MobileStepper provides dots, progress or text, accessible progress text, custom labels and optional back/next slots. Its progress variant keeps native progress semantics while painting a themed track that animates from the logical start edge. Step hover/press feedback and progress transitions honor system and provider reduced-motion preferences. The progress label isolates its text direction; use formatLabel to supply your own language and wording. activeStep is zero-based and must be within a positive integer steps count. It does not infer whether business validation permits moving forward.
## Executable example source
```tsx
'use client';
import { useState, useRef, useLayoutEffect, useEffect } from 'react';
import { Plus, MoreHorizontal, Pencil, Share2, Download, Heart, ArrowLeft, ArrowRight, Compass, Bookmark, Search } from '@lucide/icons';
import { Icon } from '@fayegram-ai/faye-ui/core/icon';
import { Card,CardTitle,CardBody,CardActions,Surface } from '@fayegram-ai/faye-ui/core/surface';
import { Text,Heading } from '@fayegram-ai/faye-ui/core/text';
import { Stack,Inline,Grid } from '@fayegram-ai/faye-ui/layout/layout';
import { Button, IconButton } from '@fayegram-ai/faye-ui/controls/button';
import { TextField } from '@fayegram-ai/faye-ui/controls/text-field';
import { Choice } from '../choice';
import { FieldLayout } from '@fayegram-ai/faye-ui/controls/field-layout';
import { Toolbar } from '@fayegram-ai/faye-ui/navigation/toolbar';
import { Tabs } from '@fayegram-ai/faye-ui/navigation/tabs';
import { Stepper } from '@fayegram-ai/faye-ui/navigation/stepper';
import { MobileStepper } from '@fayegram-ai/faye-ui/navigation/mobile-stepper';
import { Menu } from '@fayegram-ai/faye-ui/overlays/menu';
import { Slide,Collapse,Scale } from '@fayegram-ai/faye-ui/motion/presence';
import { TransitionGroup } from '@fayegram-ai/faye-ui/motion/transition-group';
import { ThemeScope } from '@fayegram-ai/faye-ui/provider/provider';
import { useMediaQuery } from '@fayegram-ai/faye-ui/hooks';
const categories=['For you','Outdoors','Architecture','Food and drink','Art and culture','Weekend trips','Quiet places','Your favourites'];
export function CollectionToolbar(){
const compact=useMediaQuery('(max-width:40rem)'),[open,setOpen]=useState(false),[liked,setLiked]=useState(false),[message,setMessage]=useState('Choose a collection tool.'),[filter,setFilter]=useState('');
const more=useRef(null),lastSecondary=useRef(null);
useLayoutEffect(()=>{const previous=lastSecondary.current,document=more.current?.ownerDocument;if(compact&&previous&&!previous.isConnected&&document&&document.activeElement===document.body)more.current?.focus();},[compact]);
useEffect(()=>{if(!compact)setOpen(false);},[compact]);
return {if((event.target as HTMLElement).hasAttribute('data-secondary-action'))lastSecondary.current=event.target as HTMLElement;}}>
setMessage('New collection selected.')}>NewsetFilter(event.target.value)} style={{flex:'1 1 8rem'}}/>
} aria-pressed={liked} onClick={()=>setLiked(value=>!value)}/>
{!compact&&setMessage('Rename selected.')}>RenamesetMessage('Share selected.')}>Share}
}/>}/>{compact&&<>setMessage('Rename selected.')}>Rename collectionsetMessage('Share selected.')}>Share collection>}setMessage('Download selected.')}>Download collection{message}{filter&&` Filter: ${filter}.`}{liked&&' Favourites only.'};
}
function Draft({name}:{name:string}){const [value,setValue]=useState(name);return {name}setValue(event.target.value)}/>;}
export default function InteractionCompositions(){
const [show,setShow]=useState(true),[reduced,setReduced]=useState(false),[direction,setDirection]=useState<'start'|'end'|'up'|'down'>('start'),[items,setItems]=useState(['First','Second','Third']),[route,setRoute]=useState('Discover');
const boundary=useRef(null),[completed,setCompleted]=useState([]),[active,setActive]=useState('details'),[name,setName]=useState(''),[invalid,setInvalid]=useState(false),[nonLinear,setNonLinear]=useState(false),[vertical,setVertical]=useState(false);
const keys=['details','review','finish'],index=keys.indexOf(active),[exits,setExits]=useState(0);
const advance=()=>{if(active==='details'&&!name.trim()){setInvalid(true);return;}setInvalid(false);setCompleted(old=>Array.from(new Set([...old,active])));setActive(keys[Math.min(index+1,2)]!);};
return Responsive collection tools{categories.map((label,i)=>{label})}{categories.map(label=>{label} collections)}Create a collection({key,label:key==='details'?'Details':key==='review'?'Review':'Finish',optional:key==='review',status:key==='details'&&invalid?'error':completed.includes(key)?'complete':key===active?'current':'upcoming',errorMessage:key==='details'&&invalid?'A collection needs a name.':undefined}))}/>{setName(event.target.value);setInvalid(false);}}/>Current step: {active}{(['dots','progress','text'] as const).map(variant=>)}Motion and continuitysetDirection(value as typeof direction)} options={['start','end','up','down'].map(value=>({value,label:value}))}/>setExits(n=>n+1)} data-directed-slide>Horizontal details with a fixed content width.Scale from the top start corner.Completed slide exits: {exits}{items.map(item=>)}{route} view;
}
```
---
# Checkboxes, radios and switches
Selection groups with explicit controlled state and native labels.
## Quick start
After the [application setup](/docs/installation/#component-consumption), copy this component into your application. It imports only public packages; the complete live demo later on this page also uses documentation layout helpers.
```tsx
'use client';
import { useState } from 'react';
import { Radio } from '@fayegram-ai/faye-ui/controls/radio';
import { RadioGroup } from '@fayegram-ai/faye-ui/controls/radio-group';
import { Switch } from '@fayegram-ai/faye-ui/controls/switch';
import { ControlLabel } from '@fayegram-ai/faye-ui/controls/field-layout';
import { Stack } from '@fayegram-ai/faye-ui/layout/layout';
export function Preferences() {
const [pace, setPace] = useState('slow');
const [notifications, setNotifications] = useState(true);
return setPace(String(value))}>
{['slow', 'adventurous'].map(value =>
{attributes => }
)}
{attributes => }
;
}
```
API reference: [Radio](/docs/api-controls-radio/), [Radio Group](/docs/api-controls-radio-group/), [Switch](/docs/api-controls-switch/), [Field Layout](/docs/api-controls-field-layout/).
## Usage contract
Checkboxes model independent selections. Radio groups model exclusive choices. Switches represent immediate on/off settings. Disabled, indeterminate and read-only are separate states. The examples supply labels instead of relying on position or color.
Read-only checkboxes, radios and switches retain their value and keyboard focus indicator without advertising a change through hover or press effects. Their controls and `ControlLabel` labels use a neutral cursor. Set `readOnly` on a radio group or an individual choice; use `disabled` when the control must also leave keyboard interaction. Disabled appearance takes precedence when both states apply.
## Customization
Use semantic tokens for visual changes, public component parts for structural customization, and explicit props for instance behavior. The surrounding site lets you compare light and dark, different brands and density.
## Source and verification
The examples below import actual public package entries. Full source is downloadable. Source coverage does not establish keyboard, hydration or browser compatibility; those require the application test suite.
## Executable example source
```tsx
'use client';
import { Check, Minus } from '@lucide/icons';
import { Icon } from '@fayegram-ai/faye-ui/core/icon';
import { useState } from 'react';
import { Checkbox } from '@fayegram-ai/faye-ui/controls/checkbox';
import { CheckboxGroup } from '@fayegram-ai/faye-ui/controls/checkbox-group';
import { Radio } from '@fayegram-ai/faye-ui/controls/radio';
import { RadioGroup } from '@fayegram-ai/faye-ui/controls/radio-group';
import { Switch } from '@fayegram-ai/faye-ui/controls/switch';
import { ControlLabel } from '@fayegram-ai/faye-ui/controls/field-layout';
import { ThemeScope } from '@fayegram-ai/faye-ui/provider/provider';
import { Stack, Inline } from '@fayegram-ai/faye-ui/layout/layout';
import { Section, Result } from '../example';
export default function Selection() {
const [channels, setChannels] = useState(['email']), [frequency, setFrequency] = useState('weekly'), [enabled, setEnabled] = useState(true);
return <>{['email', 'inbox', 'mobile'].map(value => {attrs => })}{attrs => }{attrs => }Channels: {channels.join(', ') || 'none'} setFrequency(String(value))} aria-label="Digest frequency">{['daily', 'weekly', 'never'].map(value => {attrs => })}Frequency: {frequency}{attrs => }Notifications {enabled ? 'enabled' : 'disabled'}{attrs => }>;
}
```
---
# Select and autocomplete
Fixed choices, searchable selection and free-form suggestions.
## Quick start
After the [application setup](/docs/installation/#component-consumption), copy this component into your application. It imports only public packages; the complete live demo later on this page also uses documentation layout helpers.
```tsx
'use client';
import { useState } from 'react';
import { Select } from '@fayegram-ai/faye-ui/controls/select';
import { FieldLayout } from '@fayegram-ai/faye-ui/controls/field-layout';
const places = [{ value: 'coast', label: 'By the coast' }, { value: 'garden', label: 'In the gardens' }];
export function PlacePicker() {
const [place, setPlace] = useState('coast');
return
{attributes =>
{places.map(item => {item.label})}
}
;
}
```
API reference: [Select](/docs/api-controls-select/), [Field Layout](/docs/api-controls-field-layout/).
## Usage contract
Select does not accept arbitrary text. Combobox selects values while filtering items. Autocomplete can preserve free-form input. Generic collection roots remain direct exports to preserve value types. Network loading and stale-response handling belong to the application or extension.
## Customization
Use semantic tokens for visual changes, public component parts for structural customization, and explicit props for instance behavior. The surrounding site lets you compare light and dark, different brands and density.
## Editing before hydration
Server-rendered Faye UI Input, Combobox.Input and Autocomplete.Input preserve text edited before client hydration by replaying it through their existing change callbacks during initialization. The accepted edit retains its focus and caret. Combobox query text remains separate from its committed value: typing a city name does not submit a different selected city until an option is chosen. Autocomplete can retain free-form text.
Controlled callers keep authority: store the requested change to accept it, or retain the controlled prop to reject it. Later controlled updates replace the value normally. Disabled/read-only inputs are not replayed. The replay is a synthetic input event and does not grant trusted user activation. CSR has no server input to edit before its client module loads. Physical IME/autofill and assistive-technology behavior still require target-device review.
## Source and verification
The examples below import actual public package entries. Full source is downloadable. Source coverage does not establish keyboard, hydration or browser compatibility; those require the application test suite.
## Labels, anatomy and dimensions
When the editable input is the form control, use a native label with `htmlFor`/`id` or `Field.Label`. `Combobox.Label` labels the popup trigger; it is for a trigger-first composition, not the editable input. Clear and popup controls need their own action names.
Standalone Combobox/Autocomplete inputs have a border and focus ring. In an InputGroup, the group owns the boundary and focus ring, and the input fits inside its border. Use the same size variants on a composed group/input. Medium controls measure 36px comfortable and 32px compact; small 32/28px; large 44/36px. Single-line options use 32/28px rows, with room to grow for wrapping text. Coarse pointers use at least 44px targets.
Selection popups align to the trigger subject to the configured maximum and viewport space. Command menus use content width. Pending/error/empty states, cancellation and latest-result ownership remain application responsibilities; see asynchronous workflows for the executable pattern.
## Dropdown indicators
Picker defaults use licensed Lucide ChevronDown, X and Check SVG geometry, with a 16px frame and 2-unit stroke in a 24-unit viewBox. The chevron frame sits 13px inside the default one-pixel border in either direction, centered vertically. Select, Combobox and Autocomplete keep a fixed trailing indicator slot; custom children still override the default artwork. Give separate clear and popup actions accessible names. Decorative SVGs do not add characters to those names.
NativeSelect keeps the native select element, ref, options, form behavior and keyboard interaction. A decorative span/SVG wrapper positions its arrow consistently. Consumer classes, profiles and ordinary props still target the select; CSS relying on it being a direct child may need to account for the wrapper. Multiple selects and visible listboxes have no added wrapper/arrow. Forced-colors mode restores the browser's native arrow.
Picker defaults explicitly import ChevronDown, X and Check from pinned `@lucide/icons@1.52.0` and render them through `@fayegram-ai/faye-ui/core/icon`. The renderer imports neither icon catalogue. Application artwork now uses the same system. The foundations chapter documents both artwork packs, legacy compatibility, accessibility and authoring. Applicable attribution and license notices are retained in the distributed package's `LICENSE` and the upstream icon package.
Select defaults to a popup below the trigger, aligned to its logical start with a 4px offset. The popup follows the anchor width and remains bounded by the available viewport. Set `alignItemWithTrigger` explicitly on `Select.Positioner` to opt into selected-item alignment. Combobox and Autocomplete popups use the same anchor-width bounds. A compound field shows one keyboard focus frame: the input group owns input focus, while clear/trigger buttons own their own focus.
`Combobox.ChipRemove` includes a compact close icon and a localized fallback label. Give it an item-specific `aria-label`, such as `Remove Oslo`, when the value is known. Children, render props and provider settings can replace the default artwork or label.
When `Select.List` is supplied, it owns the bounded scroll area. Optional `Select.ScrollUpArrow` and `Select.ScrollDownArrow` stay at the popup edges and scroll on hover when more options exist; both include replaceable chevron artwork. Touch input uses ordinary scrolling, and keyboard users retain arrow, Home and End navigation. Direct-item popup compositions remain supported.
Read-only pickers still allow browsing their options, while preserving the selected value. Combobox and Autocomplete clear actions become disabled, including custom-rendered clear controls. Fully disabled pickers show unavailable cursors and suppress action feedback. When a field is both disabled and read-only, its disabled surface token takes precedence, including inside input groups.
## Native mobile selection
`SelectField` from `controls/select` is a convenience composition for single selection with unique, nonempty string values and string labels. Set `nativeOnMobile` to use a native `