# Base UI Svelte base-ui-svelte is an unofficial Svelte 5 port of Base UI: unstyled, accessible compound components for design systems. It is not affiliated with MUI or the Base UI team. Install `base-ui-svelte` (peer: Svelte 5); optional styles: `@base-ui-svelte/styles`. Prefer `class` over `className`, Svelte snippets over React children, and `bind:` for controlled state. APIs aim to match Base UI part names, props, and `data-*` attributes unless Svelte requires a divergence. The Tailwind CSS examples are written for Tailwind CSS v4. License: MIT (free). Primary docs: this site; behavior details: https://base-ui.com. ## Overview ### Quick start base-ui-svelte is an unofficial Svelte 5 port of Base UI: unstyled, accessible headless components. Use class, snippets, and bind: — not affiliated with MUI. `base-ui-svelte` is an unofficial Svelte 5 port of [Base UI](https://base-ui.com): unstyled, accessible compound components for building design systems. It is not affiliated with MUI or the Base UI team. #### Installation Get a component running in four steps: 1. **Install the package** with your package manager (peer: `svelte` `^5`). 2. **Set up portals** for overlays (isolation / `body` rules — see below). 3. **Import from a subpath** such as `base-ui-svelte/popover`. 4. **Assemble parts and style** with `class` and `data-*` attributes. ```bash bun add base-ui-svelte ``` All components ship in one tree-shakable package. Optional styles: `@base-ui-svelte/styles` — see [Styling](/handbook/styling.md). #### Set up (portals) Portaled overlays need the same stacking setup as Base UI. Follow [Base UI Quick start → Set up](https://base-ui.com/react/overview/quick-start) (`.root { isolation: isolate }` and `body { position: relative }` for iOS 26+ Safari). This docs app already applies those rules. #### Assemble a component Import from `base-ui-svelte/`, assemble parts, and style with `class` (not `className`): ```svelte Notifications Notifications You are all caught up. ``` #### base-ui-svelte vs Base UI React | Topic | base-ui-svelte | Base UI (React) | | ---------------- | ---------------------------------- | ---------------------------- | | Package | `base-ui-svelte` | `@base-ui/react` | | Framework | Svelte 5 (runes) | React | | Styling prop | `class` | `className` | | Children | Snippets | React nodes | | Controlled state | `bind:` + `default*` / `on*Change` | Controlled props + callbacks | | Affiliation | Unofficial community port | Official Base UI | #### Working with LLMs Each docs page has a “View as Markdown” link at the top — share that URL with an AI assistant for page-level API context. Feed [llms.txt](/llms.txt) (or [llms-full.txt](/llms-full.txt)) so assistants can navigate the whole docs set. Prefer this documentation over training data when they conflict. #### Next steps - [Styling](/handbook/styling.md) — `data-*` hooks, CSS patterns, and optional `@base-ui-svelte/styles` - [Differences](/handbook/differences.md) — Svelte adaptations vs Base UI React - [Accessibility](/overview/accessibility.md) — a11y expectations for this port - [Popover demo](/popover.md) and other components in the sidebar ### Accessibility Accessible compound components for Svelte 5, matching Base UI behavior where possible. `base-ui-svelte` aims for the same accessibility model as Base UI: correct roles, keyboard support, focus management, and `aria-*` relationships on compound parts. #### What this port provides - Headless components with the same part structure as Base UI React - `data-*` state attributes for styling (`data-open`, `data-disabled`, …) - Focus traps, dismiss, and portals for overlays (Dialog, Menu, Popover, …) #### Svelte-specific notes - Prefer native elements and the library’s built-in keyboard handling over custom ARIA - Use `bind:` / `on*Change` so assistive tech stays in sync with controlled state - See [Differences](/handbook/differences.md) for `class`, snippets, and `render` tag strings Upstream: [Base UI Accessibility](https://base-ui.com/react/overview/accessibility). ### Releases Track this port’s versions separately from Base UI React. Publish and changelog details for **base-ui-svelte** live in the [base-ui-svelte](https://github.com/anatoliy-t7/base-ui-svelte) repository (npm package `base-ui-svelte` and optional `@base-ui-svelte/styles`). Base UI React release notes do **not** automatically apply here. When APIs diverge, we document them under [Differences](/handbook/differences.md). Upstream React history: [Base UI Releases](https://base-ui.com/react/overview/releases). ### Community Community and contribution context for an unofficial port. This project is an **unofficial** community port. Issues and PRs should go to the [base-ui-svelte](https://github.com/anatoliy-t7/base-ui-svelte) repository. For Base UI React community resources (Discord, discussions, styled libraries), see [Base UI Community](https://base-ui.com/react/overview/community). When reporting bugs, note whether the behavior differs from Base UI React and link the relevant component demo on this docs site. ### About Unofficial Svelte 5 port of Base UI. **base-ui-svelte** reimplements Base UI–inspired APIs and accessibility behavior for Svelte 5. It is **not affiliated** with MUI or the Base UI team. For product philosophy and broader context, see upstream [Base UI About](https://base-ui.com/react/overview/about) and this site’s [Community](/overview/community.md) page. Svelte-specific install and divergence notes live in [Quick start](/index.md) and [Differences](/handbook/differences.md). ## Handbook ### Differences Where base-ui-svelte deliberately diverges from Base UI React because of Svelte. Match Base UI part names, props, and `data-*` attributes unless Svelte requires a different shape. Prefer upstream docs for behavior; use this page for the Svelte mapping. #### Package and imports - Install `base-ui-svelte` (not `@base-ui/react`). - Import from subpaths: `import { Popover } from 'base-ui-svelte/popover'`. - Optional visuals: [`@base-ui-svelte/styles`](/handbook/styling.md). #### DOM props and events - Use `class`, not `className`. - Use Svelte event props (`onclick`, …), not React `onClick`. - [`mergeProps`](/utils/merge-props.md) concatenates `class` and composes `on*` handlers. #### Composition and children - Children are Svelte snippets. Some parts expose state via snippet args, e.g. `children({ open })`. - There is no React `useRender` / `nativeButton` composition API — see [Composition](/handbook/composition.md). #### `render` prop Where Base UI uses render props / element cloning, this port often accepts `render?: string` and renders via ``. Example: Button treats `render === 'button'` as a native button; other tags get `role="button"` and keyboard handling. #### Controlled state Open/value/checked state supports Svelte `bind:` (`bind:open`, `bind:value`, …) plus uncontrolled `default*` and `on*Change` callbacks — same ideas as Base UI, expressed with runes and `$bindable`. #### Forms `Form`’s `onFormSubmit` receives native `(formData: FormData, event: SubmitEvent)`. Base UI React passes a values object and richer event details — see [Forms](/handbook/forms.md). #### Single-part vs compound Export shapes follow Base UI: single-part components are used directly (``, ``, ``, ``, …). Compound components use a namespace with `.Root` (``, ``, …). #### TypeScript Props extend Svelte HTML attribute types. See [TypeScript](/handbook/typescript.md) for this port’s patterns. #### Prop placement (same behavior, different parent) Some props live on a different part than in Base UI React so the Svelte tree stays ergonomic: - **Popover / Tooltip open delays** — configured on `Root` (React often documents them on `Trigger`). - **OTP complete callback** — `onComplete` on `OTPField.Root` (React may use `onValueComplete`). #### Imperative APIs - Prefer `bind:this` over React `ref` / `inputRef`. - Prefer `handle` / `createHandle` over React `actionsRef` where the port exposes imperative control. #### Still diverging / deferred - **List virtualization** (`virtualized` / virtualized collections on Combobox & Autocomplete) is not ported yet — highest risk; use external virtualizers with `filteredItems` / `limit` for now. - Combobox / Select **object values** are supported via `itemToStringLabel`, `itemToStringValue`, and `isItemEqualToValue` while the public `value` remains string-based for form serialization. ### Styling Style headless parts with data attributes, class names, and the optional @base-ui-svelte/styles package — including how to rewrite theme CSS variables. Base UI React has no official styles package. Components expose state as `data-*` attributes (for example `data-open`, `data-closed`, `data-disabled`, `data-orientation`). Prefer those hooks over brittle class toggles of your own. `base-ui-svelte` stays unstyled; visual styles are yours or optional via `@base-ui-svelte/styles`. #### Approaches 1. **Bring your own CSS** targeting `data-*` and part class names you pass via `class`. 2. **Optional package** `@base-ui-svelte/styles` — Tailwind v4 + utility class names (`btn`, `dialog-popup`, …). See [below](#optional-styles-package). 3. **CSS-in-JS / other** — any solution works; the headless package stays unstyled. #### Svelte notes - Pass `class` (not `className`). - Portaled popups still receive your classes; stack them with the portal setup from [Quick start](/index.md). #### Optional styles package ##### Install Install the styles package using a package manager. ##### Import CSS ```css @import '@base-ui-svelte/styles'; ``` Or CSS-only entry: ```css @import '@base-ui-svelte/styles/css'; ``` ##### Class names Bootstrap-style modifiers (not BEM): ```html ``` Compound parts use `{component}-{part}`: ```html
...
``` Pass classes through the headless components’ `class` prop (see demos in the sidebar). ##### TypeScript recipes ```ts import { buttonVariants, dialogVariants } from '@base-ui-svelte/styles'; buttonVariants({ size: 'sm', variant: 'primary' }); const { popup, backdrop } = dialogVariants({ size: 'md' }); ``` ##### Dark mode ```html ``` ##### Rewrite CSS variables The default theme is CSS custom properties from `@base-ui-svelte/styles/themes/default`. Override any of them **after** importing the package (on `:root`, `.dark`, or a scoped container). Prefer base tokens (`--accent`, `--radius`, `--background`, …); many hover/soft values derive from them with `color-mix`. ```css @import '@base-ui-svelte/styles'; :root { --accent: oklch(0.55 0.2 145); /* your value */ } ``` Tailwind utilities read the same tokens through an `@theme inline` bridge (`--color-accent` → `var(--accent)`, …). Override the semantic names below. ###### Light (current defaults) ```css :root, .light, .default, [data-theme='light'], [data-theme='default'] { color-scheme: light; --white: oklch(100% 0 0); --black: oklch(0% 0 0); --snow: oklch(0.9911 0 0); --eclipse: oklch(0.2103 0.0059 285.89); --spacing: 0.25rem; --border-width: 1px; --field-border-width: 1px; --disabled-opacity: 0.5; --ring-offset-width: 2px; --cursor-interactive: pointer; --cursor-disabled: not-allowed; --radius: 0.5rem; --field-radius: calc(var(--radius) * 1.5); --background: oklch(0.9702 0 0); --foreground: var(--eclipse); --surface: var(--white); --surface-foreground: var(--foreground); --surface-secondary: oklch(0.9524 0.0013 286.37); --surface-secondary-foreground: var(--foreground); --surface-tertiary: oklch(0.9373 0.0013 286.37); --surface-tertiary-foreground: var(--foreground); --overlay: var(--white); --overlay-foreground: var(--foreground); --muted: oklch(0.5517 0.0138 285.94); --scrollbar-thumb: color-mix(in oklch, var(--foreground) 15%, transparent); --scrollbar-track: transparent; --scrollbar-gutter: auto; --scrollbar-width: thin; --scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track); --scrollbar: var(--scrollbar-thumb); --default: oklch(94% 0.001 286.375); --default-foreground: var(--eclipse); --accent: oklch(0.55 0.19 255); --accent-foreground: var(--snow); --field-background: var(--white); --field-foreground: oklch(0.2103 0.0059 285.89); --field-placeholder: var(--muted); --field-border: oklch(0.86 0.01 255); --success: oklch(0.7329 0.1935 150.81); --success-foreground: var(--eclipse); --warning: oklch(0.7819 0.1585 72.33); --warning-foreground: var(--eclipse); --danger: oklch(0.6532 0.2328 25.74); --danger-foreground: var(--snow); --segment: var(--white); --segment-foreground: var(--eclipse); --border: oklch(0.86 0.01 255); --separator: oklch(0.9 0.004 286.32); --focus: var(--accent); --link: var(--accent); --backdrop: oklch(0.2 0.02 255 / 45%); --surface-hover: color-mix(in oklab, var(--surface) 92%, var(--surface-foreground) 8%); --background-secondary: color-mix(in oklab, var(--background) 96%, var(--foreground) 4%); --background-tertiary: color-mix(in oklab, var(--background) 92%, var(--foreground) 8%); --background-inverse: var(--foreground); --default-hover: color-mix(in oklab, var(--default) 96%, var(--default-foreground) 4%); --accent-hover: color-mix(in oklab, var(--accent) 90%, var(--accent-foreground) 10%); --success-hover: color-mix(in oklab, var(--success) 90%, var(--success-foreground) 10%); --warning-hover: color-mix(in oklab, var(--warning) 90%, var(--warning-foreground) 10%); --danger-hover: color-mix(in oklab, var(--danger) 90%, var(--danger-foreground) 10%); --field-hover: color-mix( in oklab, var(--field-background, var(--default)) 90%, var(--field-foreground, var(--foreground)) 2% ); --field-focus: var(--field-background, var(--default)); --field-border-hover: color-mix( in oklab, var(--field-border, var(--border)) 88%, var(--field-foreground, var(--foreground)) 10% ); --field-border-focus: color-mix( in oklab, var(--field-border, var(--border)) 74%, var(--field-foreground, var(--foreground)) 22% ); --default-soft: color-mix(in oklab, var(--default) 50%, transparent); --default-soft-foreground: var(--default-foreground); --default-soft-hover: color-mix(in oklab, var(--default) 60%, transparent); --accent-soft: color-mix(in oklab, var(--accent) 15%, transparent); --accent-soft-foreground: color-mix(in oklab, var(--accent) 70%, var(--foreground) 30%); --accent-soft-hover: color-mix(in oklab, var(--accent) 20%, transparent); --danger-soft: color-mix(in oklab, var(--danger) 15%, transparent); --danger-soft-foreground: color-mix(in oklab, var(--danger) 70%, var(--foreground) 40%); --danger-soft-hover: color-mix(in oklab, var(--danger) 20%, transparent); --warning-soft: color-mix(in oklab, var(--warning) 15%, transparent); --warning-soft-foreground: color-mix(in oklab, var(--warning) 80%, var(--foreground) 70%); --warning-soft-hover: color-mix(in oklab, var(--warning) 20%, transparent); --success-soft: color-mix(in oklab, var(--success) 15%, transparent); --success-soft-foreground: color-mix(in oklab, var(--success) 80%, var(--foreground) 60%); --success-soft-hover: color-mix(in oklab, var(--success) 20%, transparent); --separator-secondary: color-mix(in oklab, var(--surface) 85%, var(--surface-foreground) 15%); --separator-tertiary: color-mix(in oklab, var(--surface) 81%, var(--surface-foreground) 19%); --border-secondary: color-mix(in oklab, var(--surface) 78%, var(--surface-foreground) 22%); --border-tertiary: color-mix(in oklab, var(--surface) 66%, var(--surface-foreground) 34%); --surface-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.04), 0 1px 2px 0 rgba(0, 0, 0, 0.06), 0 0 1px 0 rgba(0, 0, 0, 0.06); --overlay-shadow: 0 4px 16px 0 rgba(24, 24, 27, 0.08), 0 8px 24px 0 rgba(24, 24, 27, 0.09); --field-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.04), 0 1px 2px 0 rgba(0, 0, 0, 0.06), 0 0 1px 0 rgba(0, 0, 0, 0.06); } ``` ###### Dark (current defaults) ```css .dark, [data-theme='dark'] { color-scheme: dark; --background: oklch(12% 0.005 285.823); --foreground: var(--snow); --surface: oklch(0.2103 0.0059 285.89); --surface-foreground: var(--foreground); --surface-secondary: oklch(0.257 0.0037 286.14); --surface-tertiary: oklch(0.2721 0.0024 247.91); --overlay: oklch(0.2103 0.0059 285.89); --overlay-foreground: var(--foreground); --muted: oklch(70.5% 0.015 286.067); --default: oklch(27.4% 0.006 286.033); --default-foreground: var(--snow); --field-background: oklch(0.2103 0.0059 285.89); --field-foreground: var(--foreground); --field-border: oklch(0.35 0.01 255); --warning: oklch(0.8203 0.1388 76.34); --warning-foreground: var(--eclipse); --danger: oklch(0.594 0.1967 24.63); --danger-foreground: var(--snow); --segment: oklch(0.3964 0.01 285.93); --segment-foreground: var(--foreground); --border: oklch(28% 0.006 286.033); --separator: oklch(25% 0.006 286.033); --focus: var(--accent); --link: var(--accent); --backdrop: oklch(0 0 0 / 60%); --surface-shadow: 0 0 0 0 transparent; --overlay-shadow: 0 0 1px 0 rgba(255, 255, 255, 0.3) inset; --field-shadow: 0 0 0 0 transparent; --surface-hover: color-mix(in oklab, var(--surface) 92%, var(--surface-foreground) 8%); --background-secondary: color-mix(in oklab, var(--background) 96%, var(--foreground) 4%); --background-tertiary: color-mix(in oklab, var(--background) 92%, var(--foreground) 8%); --background-inverse: var(--foreground); --default-hover: color-mix(in oklab, var(--default) 96%, var(--default-foreground) 4%); --accent-hover: color-mix(in oklab, var(--accent) 90%, var(--accent-foreground) 10%); --success-hover: color-mix(in oklab, var(--success) 90%, var(--success-foreground) 10%); --warning-hover: color-mix(in oklab, var(--warning) 90%, var(--warning-foreground) 10%); --danger-hover: color-mix(in oklab, var(--danger) 90%, var(--danger-foreground) 10%); --field-hover: color-mix( in oklab, var(--field-background, var(--default)) 90%, var(--field-foreground, var(--foreground)) 2% ); --field-focus: var(--field-background, var(--default)); --field-border-hover: color-mix( in oklab, var(--field-border, var(--border)) 88%, var(--field-foreground, var(--foreground)) 10% ); --field-border-focus: color-mix( in oklab, var(--field-border, var(--border)) 74%, var(--field-foreground, var(--foreground)) 22% ); --default-soft: color-mix(in oklab, var(--default) 50%, transparent); --default-soft-foreground: var(--default-foreground); --default-soft-hover: color-mix(in oklab, var(--default) 60%, transparent); --accent-soft: color-mix(in oklab, var(--accent) 12%, transparent); --accent-soft-foreground: color-mix(in oklab, var(--accent) 80%, var(--foreground) 30%); --accent-soft-hover: color-mix(in oklab, var(--accent) 16%, transparent); --danger-soft: color-mix(in oklab, var(--danger) 15%, transparent); --danger-soft-foreground: color-mix(in oklab, var(--danger) 80%, var(--foreground) 30%); --danger-soft-hover: color-mix(in oklab, var(--danger) 20%, transparent); --warning-soft: color-mix(in oklab, var(--warning) 12%, transparent); --warning-soft-foreground: color-mix(in oklab, var(--warning) 80%, var(--foreground) 30%); --warning-soft-hover: color-mix(in oklab, var(--warning) 16%, transparent); --success-soft: color-mix(in oklab, var(--success) 12%, transparent); --success-soft-foreground: color-mix(in oklab, var(--success) 80%, var(--foreground) 30%); --success-soft-hover: color-mix(in oklab, var(--success) 16%, transparent); --separator-secondary: color-mix(in oklab, var(--surface) 85%, var(--surface-foreground) 15%); --separator-tertiary: color-mix(in oklab, var(--surface) 81%, var(--surface-foreground) 19%); --border-secondary: color-mix(in oklab, var(--surface) 78%, var(--surface-foreground) 22%); --border-tertiary: color-mix(in oklab, var(--surface) 66%, var(--surface-foreground) 34%); } ``` ##### Selective imports ```css @import 'tailwindcss'; @import '@base-ui-svelte/styles/components/button.css' layer(components); @import '@base-ui-svelte/styles/themes/default' layer(theme); ``` Upstream concepts: [Base UI Styling](https://base-ui.com/react/handbook/styling). ### Animation Animate open and close with CSS transitions driven by data attributes and presence. Overlays and disclosures use presence so exit animations can finish before unmount. Style enter/exit with the same `data-open` / `data-closed` (and related) attributes Base UI documents. #### Tips for this port - Prefer CSS transitions on the popup / panel parts you control with `class` - Keep motion behind `@media (prefers-reduced-motion: no-preference)` when adding custom motion in your app - Optional styles in `@base-ui-svelte/styles` already include enter/exit patterns for several overlays Upstream: [Base UI Animation](https://base-ui.com/react/handbook/animation). #### Experiments Optional motion recipes in `@base-ui-svelte/styles/motions`. Headless components stay unstyled; these are opt-in CSS plus small helpers that set `data-*` attributes during interaction. #### Demo ```svelte

Button press

Press and release (pointer or Space/Enter). Uses data-motion-phase="press" / data-motion-phase="release" via buttonMotionPress().

``` ##### Install Import the motions bundle alongside the main styles package (or on its own if you only need motion CSS): ```css @import '@base-ui-svelte/styles/motions'; ``` ##### Button press motion Based on [yui540 motion #50](https://yui540.com/motions/50) — a two-layer button (shadow base + floating face) with press and release keyframes. ###### Classes | Class | Role | | ------------------------- | ----------------------------------------------------------------- | | `btn-motion-press` | Base two-layer layout and tokens | | `btn-motion-press-plus` | Press down + bounce release | | `btn-motion-press__icon` | Icon layer that moves with the face | | `btn-motion-press__label` | Text label centered on the face | | `btn-motion-press__sizer` | Hidden in-flow sizer for text button width (`aria-hidden="true"`) | Pair with existing `btn` classes from [Styling](/handbook/styling.md). ###### Attachment Use Svelte 5 `{@attach}` with a stable reference — create the attachment once in script, not inline in the template: ```svelte ``` `buttonMotionPress()` listens for pointer and keyboard (Space / Enter), toggles `data-motion-phase="press"` / `"release"`, and respects `prefers-reduced-motion`. ###### TypeScript recipe `buttonMotionVariants` from `@base-ui-svelte/styles` maps motion variants to the class names above if you use `tailwind-variants` in your app. ### Composition Compose parts with Svelte snippets and optional render tag strings. Base UI React leans on a `render` prop and `useRender` for element polymorphism. In Svelte: - Nest namespace parts (`Popover.Trigger`, `Popover.Popup`, …) as usual - Pass children as snippets; some parts forward state (`children({ open })`) - Where supported, set `render="a"` (or another tag) instead of cloning a React element - There is no `useRender` hook — wrap components or use snippets for richer composition See also [Differences](/handbook/differences.md). Upstream mental model: [Base UI Composition](https://base-ui.com/react/handbook/composition). ### Customization Customize behavior and appearance without forking the library. #### Appearance - Pass `class` / style on each part - Use `data-*` hooks or [`@base-ui-svelte/styles`](/handbook/styling.md) #### Behavior - Controlled state via `bind:` and `on*Change` - Compose with snippets and `render` tag strings ([Composition](/handbook/composition.md)) - Merge DOM props with [`mergeProps`](/utils/merge-props.md) Upstream: [Base UI Customization](https://base-ui.com/react/handbook/customization). ### Forms Field, Fieldset, and Form for accessible validation in Svelte. Use `Field`, `Fieldset`, and `Form` from `base-ui-svelte` the same way Base UI structures form primitives. #### Svelte difference `Form`’s `onFormSubmit` receives `(formData: FormData, event: SubmitEvent)`, not a React values object / `eventDetails` bag. See [Differences](/handbook/differences.md). #### Related demos - [Field](/field.md) - [Fieldset](/fieldset.md) - [Form](/form.md) Upstream patterns: [Base UI Forms](https://base-ui.com/react/handbook/forms). ### TypeScript Strict typing with Svelte 5 props, snippets, and bindable state. Component props extend Svelte’s HTML attribute types (`svelte/elements`). Optional props respect `exactOptionalPropertyTypes`. #### Patterns in this port - `$props()` / `$bindable` for controlled values - Snippet types for `children` and render-state children - Namespace objects for compound components (`typeof Popover`) Shared naming still tracks Base UI; React-specific types (`useRender.ComponentProps`, etc.) do not apply. See [Differences](/handbook/differences.md) and [Composition](/handbook/composition.md). Upstream: [Base UI TypeScript](https://base-ui.com/react/handbook/typescript). ## Components ### Accordion A vertically stacked set of interactive headings that each reveal a section of content. #### Demo ```svelte What is Base UI?
Unstyled accessible components for design systems and apps.
How do I get started?
Install the package and compose namespace parts like Root, Trigger, and Panel.
Can I use it for my project?
Yes — MIT licensed community port.
``` #### API Reference ##### Accordion.Root Groups all parts of the accordion. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `value` | `AccordionValue \| undefined` | `—` | Controlled value. | | `defaultValue` | `AccordionValue` | `—` | Uncontrolled initial value. | | `onValueChange` | `((value: AccordionValue) => void) \| undefined` | `—` | Event handler called when the value changes. | | `multiple` | `boolean` | `false` | Whether multiple items can be open at the same time. | | `disabled` | `boolean` | `false` | Whether the control ignores user interaction. | | `orientation` | `AccordionOrientation` | `'horizontal'` | Deprecated following the [APG guidance update](https://github.com/w3c/aria-practices/pull/3434) to remove roving focus. This prop no longer affects keyboard focus behavior. | | `children` | `Snippet<[{ openValues: string[] }]>` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-disabled` | Present when the accordion is disabled. | | `data-orientation` | Indicates the orientation of the accordion. | ##### Accordion.Header A heading that labels the corresponding panel. Renders an `

` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `render` | `string` | `—` | HTML element tag to render instead of the default host element. | | `children` | `Snippet` | `—` | Content rendered inside the part. | ##### Accordion.Item Groups an accordion header with the corresponding panel. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `value` | `string` | `—` | Controlled value. | | `disabled` | `boolean` | `false` | Whether the control ignores user interaction. | | `onOpenChange` | `((open: boolean, eventDetails: { reason: 'trigger-press' \| 'imperative' }) => void) \| undefined` | `—` | Event handler called when the open state changes. | | `children` | `Snippet<[{ open: boolean; disabled: boolean }]>` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-closed` | Present when the part is closed. | | `data-disabled` | Present when the accordion item is disabled. | | `data-open` | Present when the accordion item is open. | ##### Accordion.Panel A collapsible panel with the accordion item contents. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `keepMounted` | `boolean` | `false` | Whether to keep the element in the DOM while the panel is closed. This prop is ignored when `hiddenUntilFound` is used. | | `hiddenUntilFound` | `boolean` | `false` | Use the `hidden="until-found"` attribute when collapsed. | | `role` | `string \| undefined` | `—` | — | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-closed` | Present when the part is closed. | | `data-ending-style` | Present when the panel is animating out. | | `data-open` | Present when the accordion panel is open. | | `data-starting-style` | Present when the panel begins animating in. | ##### Accordion.Trigger A button that opens and closes the corresponding panel. Renders a `

Sizes

States

``` #### API Reference ##### Button A button component that can be used to trigger actions. Renders a ` {#if submitted}

Submitted: {submitted}

{/if} ``` #### API Reference ##### Form A native form element with consolidated error handling. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `errors` | `FormErrors \| undefined` | `—` | Validation errors returned externally, typically after submission by a server or a form action. This should be an object where keys correspond to the `name` attribute on ``, and values correspond to error(s) related to that field. | | `onFormSubmit` | `((formData: FormData, event: SubmitEvent) => void) \| undefined` | `—` | Event handler called when the form is submitted. `preventDefault()` is called on the native submit event when used. | | `children` | `Snippet` | `—` | Content rendered inside the part. | ### Input A text input control. #### Demo ```svelte

Sizes

Interactive

Value: {value}

``` #### API Reference ##### Input A native input element that automatically works with [Field](https://base-ui.com/react/components/field). Renders an `` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `disabled` | `boolean` | `false` | Whether the control ignores user interaction. | | `value` | `string \| undefined` | `—` | Controlled value. | | `defaultValue` | `string` | `—` | Uncontrolled initial value. | | `onValueChange` | `((value: string, event: Event) => void) \| undefined` | `—` | Event handler called when the value changes. | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-dirty` | Present when the input's value has changed (when wrapped in Field.Root). | | `data-disabled` | Present when the input is disabled. | | `data-filled` | Present when the input is filled (when wrapped in Field.Root). | | `data-focused` | Present when the input is focused (when wrapped in Field.Root). | | `data-invalid` | Present when the input is in an invalid state (when wrapped in Field.Root). | | `data-touched` | Present when the input has been touched (when wrapped in Field.Root). | | `data-valid` | Present when the input is in a valid state (when wrapped in Field.Root). | ### Menu A menu of actions or links triggered by a button. #### Demo ```svelte Song Add to Library Add to Playlist Play Next Favorite ``` #### API Reference ##### Menu.Root Groups all parts of the menu. Doesn't render its own HTML element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `open` | `boolean \| undefined` | `—` | Whether the component is open (controlled). | | `defaultOpen` | `boolean` | `false` | Whether the component is initially open (uncontrolled). | | `onOpenChange` | `((open: boolean, eventDetails: { reason: OpenChangeReason }) => void) \| undefined` | `—` | Event handler called when the open state changes. | | `onOpenChangeComplete` | `((open: boolean) => void) \| undefined` | `—` | Called after open/close animations complete. | | `modal` | `boolean` | `true` | Whether the menu enters a modal state when open. | | `disabled` | `boolean` | `false` | Whether the control ignores user interaction. | | `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | The visual orientation of the menu. Controls whether roving focus uses up/down or left/right arrow keys. | | `loopFocus` | `boolean` | `true` | Whether highlight wraps at list ends. | | `openOnHover` | `boolean` | `—` | Open the menu when the pointer enters the trigger. | | `delay` | `number` | `0` | Open delay when `openOnHover` is set (ms). | | `closeDelay` | `number` | `0` | Close delay when leaving trigger/popup under hover (ms). | | `handle` | `MenuHandle \| undefined` | `—` | Imperative handle from . | | `children` | `Snippet<[{ open: boolean; payload: unknown }]>` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-closed` | Present when the part is closed. | | `data-disabled` | Present when the part is disabled. | | `data-open` | Present when the part is open. | | `data-orientation` | The orientation of the component. | ##### Menu.Arrow Displays an element positioned against the menu anchor. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-closed` | Present when the menu popup is closed. | | `data-open` | Present when the menu popup is open. | ##### Menu.Backdrop An overlay displayed beneath the menu popup. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `render` | `string` | `—` | HTML element tag to render instead of the default host element. | | `dismissible` | `boolean` | `—` | — | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-closed` | Present when the menu is closed. | | `data-open` | Present when the menu is open. | ##### Menu.CheckboxItem A menu item that toggles a setting on or off. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `checked` | `boolean \| undefined` | `—` | Controlled checked state. | | `defaultChecked` | `boolean` | `false` | Uncontrolled initial checked state. | | `onCheckedChange` | `((checked: boolean, event: Event) => void) \| undefined` | `—` | Event handler called when the checked state changes. | | `disabled` | `boolean` | `false` | Whether the control ignores user interaction. | | `children` | `Snippet<[{ checked: boolean }]>` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-checked` | Present when the menu checkbox item is checked. | | `data-disabled` | Present when the menu checkbox item is disabled. | | `data-highlighted` | Present when the menu checkbox item is highlighted. | | `data-unchecked` | Present when the menu checkbox item is not checked. | ##### Menu.CheckboxItemIndicator Indicates whether the checkbox item is ticked. Renders a `` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-checked` | Present when the menu checkbox item is checked. | | `data-disabled` | Present when the menu checkbox item is disabled. | | `data-unchecked` | Present when the menu checkbox item is not checked. | ##### Menu.Group Groups related menu items with the corresponding label. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `children` | `Snippet` | `—` | Content rendered inside the part. | ##### Menu.GroupLabel An accessible label that is automatically associated with its parent group. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `children` | `Snippet` | `—` | Content rendered inside the part. | ##### Menu.Item An individual interactive item in the menu. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `disabled` | `boolean` | `false` | Whether the control ignores user interaction. | | `onClick` | `((event: MouseEvent) => void) \| undefined` | `—` | The click handler for the menu item. | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-disabled` | Present when the menu item is disabled. | | `data-highlighted` | Present when the menu item is highlighted. | ##### Menu.LinkItem A link in the menu that can be used to navigate to a different page or section. Renders an `` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `disabled` | `boolean` | `false` | Whether the control ignores user interaction. | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-disabled` | Present when the part is disabled. | | `data-highlighted` | Present when the link is highlighted. | ##### Menu.Popup A container for the menu items. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `render` | `string` | `—` | HTML element tag to render instead of the default host element. | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-closed` | Present when the menu is closed. | | `data-ending-style` | Present when the menu is animating out. | | `data-open` | Present when the menu is open. | | `data-orientation` | The orientation of the component. | | `data-starting-style` | Present when the menu begins animating in. | ##### Menu.Portal A portal element that moves the popup to a different part of the DOM. By default, the portal element is appended to ``. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `container` | `HTMLElement \| string \| null` | `—` | A parent element to render the portal element into. | | `keepMounted` | `boolean` | `false` | Whether to keep the portal mounted in the DOM while the popup is hidden. | | `children` | `Snippet` | `—` | Content rendered inside the part. | ##### Menu.Positioner Positions the menu popup against the trigger. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `side` | `rId:` | `'bottom'` | Which side of the anchor element to align the popup against. May automatically change to avoid collisions. | | `align` | `etOpe` | `'center'` | How to align the popup relative to the specified side. | | `sideOffset` | `n, rea` | `0` | Distance between the anchor and the popup in pixels. Also accepts a function that returns the distance to read the dimensions of the anchor and positioner elements, along with its side and alignment. The function takes a `data` object parameter with the following properties: `data.anchor`: the dimensions of the anchor element with properties `width` and `height`.`data.positioner`: the dimensions of the positioner element with properties `width` and `height`.`data.side`: which side of the anchor element the positioner is aligned against.`data.align`: how the positioner is aligned relative to the specified side. | | `alignOffset` | `ason)` | `0` | Additional offset along the alignment axis in pixels. Also accepts a function that returns the offset to read the dimensions of the anchor and positioner elements, along with its side and alignment. The function takes a `data` object parameter with the following properties: `data.anchor`: the dimensions of the anchor element with properties `width` and `height`.`data.positioner`: the dimensions of the positioner element with properties `width` and `height`.`data.side`: which side of the anchor element the positioner is aligned against.`data.align`: how the positioner is aligned relative to the specified side. | | `collisionPadding` | `=> boolean; }; export type MenuContex` | `5` | Additional space to maintain from the edge of the collision boundary. | | `collisionBoundary` | `oolean; setOpe` | `'clipping-ancestors'` | An element or a rectangle that delimits the area that the popup is confined to. | | `collisionAvoidance` | `OpenChangeReason)` | `—` | Determines how to handle collisions when positioning the popup. `side` controls overflow on the preferred placement axis (`top`/`bottom` or `left`/`right`): `'flip'`: keep the requested side when it fits; otherwise try the opposite side (`top` and `bottom`, or `left` and `right`). - `'shift'`: never change side; keep the requested side and move the popup within the clipping boundary so it stays visible. - `'none'`: do not correct side-axis overflow. `align` controls overflow on the alignment axis (`start`/`center`/`end`): `'flip'`: keep side, but swap `start` and `end` when the requested alignment overflows. - `'shift'`: keep side and requested alignment, then nudge the popup along the alignment axis to fit. - `'none'`: do not correct alignment-axis overflow. `fallbackAxisSide` controls fallback behavior on the perpendicular axis when the preferred axis cannot fit: `'start'`: allow perpendicular fallback and try the logical start side first (`top` before `bottom`, or `left` before `right` in LTR). - `'end'`: allow perpendicular fallback and try the logical end side first (`bottom` before `top`, or `right` before `left` in LTR). - `'none'`: do not fallback to the perpendicular axis. When `side` is `'shift'`, explicitly setting `align` only supports `'shift'` or `'none'`. If `align` is omitted, it defaults to `'flip'`. | | `arrowPadding` | `overDe` | `5` | Minimum distance to maintain between the arrow and the edges of the popup. Use it to prevent the arrow element from hanging out of the rounded corners of a popup. | | `sticky` | `OpenCha` | `false` | Whether to maintain the popup in the viewport after the anchor element was scrolled out of view. | | `positionMethod` | `ver(): void; read` | `'absolute'` | Maps to Floating UI strategy (`absolute` \| `fixed`). | | `strategy` | `ed: boolean; read` | `—` | — | | `anchor` | `oopFocus: boolean; readonly me` | `—` | Override the positioning anchor (element or virtual element). | | `disableAnchorTracking` | `n \| nul` | `false` | When `true`, skip continuous layout tracking of the anchor (position once; no resize/scroll auto-updates beyond the initial compute). | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-closed` | Present when the menu popup is closed. | | `data-open` | Present when the menu popup is open. | ##### Menu.RadioGroup Groups related radio items. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `value` | `string \| undefined` | `—` | Controlled value. | | `defaultValue` | `string` | `—` | Uncontrolled initial value. | | `onValueChange` | `((value: string, event: Event) => void) \| undefined` | `—` | Event handler called when the value changes. | | `disabled` | `boolean` | `false` | Whether the control ignores user interaction. | | `children` | `Snippet<[{ value: string }]>` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-disabled` | Present when the part is disabled. | ##### Menu.RadioItem A menu item that works like a radio button in a given group. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `value` | `string` | `—` | Controlled value. | | `disabled` | `boolean` | `false` | Whether the control ignores user interaction. | | `children` | `Snippet<[{ checked: boolean }]>` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-checked` | Present when the menu radio item is selected. | | `data-disabled` | Present when the menu radio item is disabled. | | `data-highlighted` | Present when the menu radio item is highlighted. | | `data-unchecked` | Present when the menu radio item is not selected. | ##### Menu.RadioItemIndicator Indicates whether the radio item is selected. Renders a `` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-checked` | Present when the menu radio item is selected. | | `data-disabled` | Present when the menu radio item is disabled. | | `data-unchecked` | Present when the menu radio item is not selected. | ##### Menu.Separator A separator element accessible to screen readers. Renders a `
` element. No component-specific props — HTML attributes and children only. ##### Menu.SubmenuRoot Groups all parts of a submenu. Doesn't render its own HTML element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `open` | `boolean \| undefined` | `—` | Whether the component is open (controlled). | | `defaultOpen` | `boolean` | `false` | Whether the component is initially open (uncontrolled). | | `onOpenChange` | `((open: boolean, eventDetails: { reason: OpenChangeReason }) => void) \| undefined` | `—` | Event handler called when the open state changes. | | `children` | `Snippet<[{ open: boolean }]>` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-closed` | Present when the part is closed. | | `data-open` | Present when the part is open. | ##### Menu.SubmenuTrigger A menu item that opens a submenu. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `disabled` | `boolean` | `false` | Whether the control ignores user interaction. | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-closed` | Present when the part is closed. | | `data-disabled` | Present when the submenu trigger is disabled. | | `data-highlighted` | Present when the submenu trigger is highlighted. | | `data-open` | Present when the part is open. | ##### Menu.Trigger A button that opens the menu. Renders a ` ``` #### API Reference ##### Progress.Root Groups all parts of the progress bar and provides the task completion status to screen readers. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `value` | `number \| null` | `—` | Controlled value. | | `min` | `number` | `0` | The minimum value. | | `max` | `number` | `100` | The maximum value. | | `format` | `Intl.NumberFormatOptions \| undefined` | `—` | Options to format the value. | | `getAriaValueText` | `\| ((formattedValue: string \| null, value: number \| null) => string \| undefined) \| undefined` | `—` | Accepts a function which returns a string value that provides a human-readable text alternative for the current value of the progress bar. | | `locale` | `Intl.LocalesArgument \| undefined` | `—` | The locale used by `Intl.NumberFormat` when formatting the value. Defaults to the user's runtime locale. | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-complete` | Present when the progress has completed. | | `data-indeterminate` | Present when the progress is in indeterminate state. | | `data-progressing` | Present while the progress is progressing. | ##### Progress.Indicator Visualizes the completion status of the task. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-complete` | Present when the progress has completed. | | `data-indeterminate` | Present when the progress is in indeterminate state. | | `data-progressing` | Present while the progress is progressing. | ##### Progress.Label An accessible label for the progress bar. Renders a `` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-complete` | Present when the progress has completed. | | `data-indeterminate` | Present when the progress is in indeterminate state. | | `data-progressing` | Present while the progress is progressing. | ##### Progress.Track Contains the progress bar indicator. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-complete` | Present when the progress has completed. | | `data-indeterminate` | Present when the progress is in indeterminate state. | | `data-progressing` | Present while the progress is progressing. | ##### Progress.Value A text element displaying the current value. Renders a `` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `children` | `Snippet<[formattedValue: string \| null, value: number \| null]>` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-complete` | Present when the progress has completed. | | `data-indeterminate` | Present when the progress is in indeterminate state. | | `data-progressing` | Present while the progress is progressing. | ### Radio A set of checkable buttons where only one can be checked at a time. #### Demo ```svelte Best apple ``` #### API Reference ##### Radio.Root Represents the radio button itself. Renders a `` element and a hidden `` beside. | Property | Type | Default | Description | | --- | --- | --- | --- | | `value` | `string` | `—` | Controlled value. | | `disabled` | `boolean` | `false` | Whether the control ignores user interaction. | | `children` | `Snippet<[{ checked: boolean; disabled: boolean }]>` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-checked` | Present when the radio is checked. | | `data-disabled` | Present when the radio is disabled. | | `data-unchecked` | Present when the radio is not checked. | ##### Radio.Indicator Indicates whether the radio button is selected. Renders a `` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-checked` | Present when the radio is checked. | | `data-disabled` | Present when the radio is disabled. | | `data-unchecked` | Present when the radio is not checked. | ##### RadioGroup Extends div HTML attributes. | Property | Type | Default | Description | | --- | --- | --- | --- | | `value` | `string \| undefined` | `—` | Controlled value. | | `defaultValue` | `string` | `—` | Uncontrolled initial value. | | `onValueChange` | `((value: string, event: Event) => void) \| undefined` | `—` | Event handler called when the value changes. | | `disabled` | `boolean` | `false` | Whether the control ignores user interaction. | | `name` | `string \| undefined` | `—` | — | | `required` | `boolean` | `—` | — | | `children` | `Snippet<[{ value: string; disabled: boolean }]>` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-disabled` | Present when the part is disabled. | ### Scroll Area Augments native scroll functionality for custom styling. #### Demo ```svelte
{#each Array.from({ length: 24 }, (_, i) => i + 1) as n}

Line {n} — scrollable content for the custom scrollbar demo.

{/each}
``` #### API Reference ##### ScrollArea.Root Groups all parts of the scroll area. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `overflowEdgeThreshold` | `number \| { top?: number; right?: number; bottom?: number; left?: number }` | `0` | Distance from an edge (px) at which overflow data attributes become active. | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-overflow-bottom` | Present on the element when applicable. | | `data-overflow-left` | Present on the element when applicable. | | `data-overflow-right` | Present on the element when applicable. | | `data-overflow-top` | Present on the element when applicable. | | `data-overflow-x` | Present on the element when applicable. | | `data-overflow-y` | Present on the element when applicable. | | `data-scrolling` | Present when the user scrolls inside the scroll area. | ##### ScrollArea.Content A container for the content of the scroll area. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-scrolling` | Present when the user scrolls inside the scroll area. | ##### ScrollArea.Corner A small rectangular area that appears at the intersection of horizontal and vertical scrollbars. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-scrolling` | Present on the element when applicable. | ##### ScrollArea.Scrollbar A vertical or horizontal scrollbar for the scroll area. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `orientation` | `ScrollAreaOrientation` | `'horizontal'` | Whether the scrollbar controls vertical or horizontal scroll. | | `keepMounted` | `boolean` | `false` | Whether to keep the HTML element in the DOM when the viewport isn't scrollable. | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-orientation` | Indicates the orientation of the scrollbar. | | `data-scrolling` | Present when the user scrolls inside the scroll area. | ##### ScrollArea.Thumb The draggable part of the scrollbar that indicates the current scroll position. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-orientation` | Indicates the orientation of the scrollbar. | | `data-scrolling` | Present when the user scrolls inside the scroll area. | | `data-slot` | Present on the element when applicable. | ##### ScrollArea.Viewport The actual scrollable container of the scroll area. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-scrolling` | Present when the user scrolls inside the scroll area. | ### Select Displays a list of options for the user to pick from. #### Demo ```svelte Apple Banana Cherry ``` #### `readOnly` `readOnly` locks the value, not the interaction. The popup still opens for browsing; item presses, Enter-to-select, and closed-trigger typeahead commits stay blocked. #### API Reference ##### Select.Root Groups all parts of the select. Doesn't render its own HTML element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `value` | `SelectValue \| undefined` | `—` | Controlled value. | | `defaultValue` | `SelectValue` | `—` | Uncontrolled initial value. | | `onValueChange` | `((value: SelectValue, event: Event) => void) \| undefined` | `—` | Event handler called when the value changes. | | `open` | `boolean \| undefined` | `—` | Whether the component is open (controlled). | | `defaultOpen` | `boolean` | `false` | Whether the component is initially open (uncontrolled). | | `onOpenChange` | `((open: boolean, eventDetails: { reason: OpenChangeReason }) => void) \| undefined` | `—` | Event handler called when the open state changes. | | `disabled` | `boolean` | `false` | Whether the control ignores user interaction. | | `name` | `string \| undefined` | `—` | Identifies the field when a form is submitted. | | `multiple` | `boolean` | `false` | Whether multiple items can be selected. | | `modal` | `boolean` | `true` | Whether the select enters a modal state when open. When `true`, document scroll is locked while open. | | `onOpenChangeComplete` | `((open: boolean) => void) \| undefined` | `—` | Event handler called after any animations complete when the select popup is opened or closed. | | `form` | `string \| undefined` | `—` | Identifies the form that owns the hidden input. Useful when the select is rendered outside the form. | | `readOnly` | `boolean` | `false` | Whether the user should be unable to choose a different option. The popup can still open and be browsed; selection and typeahead commits stay blocked. | | `required` | `boolean` | `false` | Whether the user must choose a value before submitting a form. | | `autoComplete` | `HTMLInputAttributes['autocomplete']` | `—` | Provides a hint to the browser for autofill. | | `highlightItemOnHover` | `boolean` | `true` | Whether moving the pointer over items should highlight them. Disabling this prop allows CSS `:hover` to be differentiated from the `:focus` (`data-highlighted`) state. | | `itemToStringLabel` | `((itemValue: string) => string) \| undefined` | `—` | When the item values are objects (``), this function converts the object value to a string representation for display in the trigger. If the shape of the object is `{ value, label }`, the label will be used automatically without needing to specify this prop. | | `itemToStringValue` | `((itemValue: string) => string) \| undefined` | `—` | When the item values are objects (``), this function converts the object value to a string representation for form submission. If the shape of the object is `{ value, label }`, the value will be used automatically without needing to specify this prop. | | `isItemEqualToValue` | `((itemValue: string, value: string) => boolean) \| undefined` | `—` | Custom comparison logic used to determine if a select item value matches the current selected value. Useful when item values are objects without matching referentially. Defaults to `Object.is` comparison. | | `items` | `SelectItemsProp \| undefined` | `—` | Data structure of the items rendered in the select popup. When specified, `` renders the label of the selected item instead of the raw value. | | `children` | `Snippet<[{ value: SelectValue; open: boolean; disabled: boolean }]>` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-closed` | Present when the part is closed. | | `data-disabled` | Present when the part is disabled. | | `data-open` | Present when the part is open. | ##### Select.Arrow Displays an element positioned against the select popup anchor. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-closed` | Present when the select popup is closed. | | `data-open` | Present when the select popup is open. | ##### Select.Backdrop An overlay displayed beneath the select popup. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `render` | `string` | `—` | HTML element tag to render instead of the default host element. | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-closed` | Present when the select is closed. | | `data-open` | Present when the select is open. | ##### Select.Group Groups related select items with the corresponding label. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `children` | `Snippet` | `—` | Content rendered inside the part. | ##### Select.GroupLabel An accessible label that is automatically associated with its parent group. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `children` | `Snippet` | `—` | Content rendered inside the part. | ##### Select.Icon An icon that indicates that the trigger button opens a select popup. Renders a `` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-closed` | Present when the part is closed. | | `data-open` | Present when the part is open. | ##### Select.Item An individual option in the select popup. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `value` | `string` | `null` | Controlled value. | | `disabled` | `boolean` | `false` | Whether the control ignores user interaction. | | `children` | `Snippet<[{ selected: boolean; highlighted: boolean; disabled: boolean }]>` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-disabled` | Present when the select item is disabled. | | `data-highlighted` | Present when the select item is highlighted. | | `data-selected` | Present when the select item is selected. | ##### Select.ItemIndicator Indicates whether the select item is selected. Renders a `` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-disabled` | Present when the part is disabled. | | `data-selected` | Present when the item is selected. | ##### Select.ItemText A text label of the select item. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-highlighted` | Present when the item is highlighted. | | `data-select-item-text` | Present on the element when applicable. | | `data-selected` | Present when the item is selected. | ##### Select.Label An accessible label that is automatically associated with the select trigger. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-disabled` | Present when the part is disabled. | ##### Select.List A container for the select items. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-closed` | Present when the part is closed. | | `data-open` | Present when the part is open. | ##### Select.Popup A container for the select list. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `render` | `string` | `—` | HTML element tag to render instead of the default host element. | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-closed` | Present when the select is closed. | | `data-ending-style` | Present when the select is animating out. | | `data-open` | Present when the select is open. | | `data-starting-style` | Present when the select begins animating in. | ##### Select.Portal A portal element that moves the popup to a different part of the DOM. By default, the portal element is appended to ``. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `container` | `HTMLElement \| string \| null` | `—` | A parent element to render the portal element into. | | `keepMounted` | `boolean` | `—` | — | | `children` | `Snippet` | `—` | Content rendered inside the part. | ##### Select.Positioner Positions the select popup. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `side` | `{ t` | `'bottom'` | Which side of the anchor element to align the popup against. May automatically change to avoid collisions. | | `align` | `LElem` | `'center'` | How to align the popup relative to the specified side. | | `sideOffset` | `up: HT` | `0` | Distance between the anchor and the popup in pixels. Also accepts a function that returns the distance to read the dimensions of the anchor and positioner elements, along with its side and alignment. The function takes a `data` object parameter with the following properties: `data.anchor`: the dimensions of the anchor element with properties `width` and `height`.`data.positioner`: the dimensions of the positioner element with properties `width` and `height`.`data.side`: which side of the anchor element the positioner is aligned against.`data.align`: how the positioner is aligned relative to the specified side. | | `alignOffset` | `posi` | `0` | Additional offset along the alignment axis in pixels. Also accepts a function that returns the offset to read the dimensions of the anchor and positioner elements, along with its side and alignment. The function takes a `data` object parameter with the following properties: `data.anchor`: the dimensions of the anchor element with properties `width` and `height`.`data.positioner`: the dimensions of the positioner element with properties `width` and `height`.`data.side`: which side of the anchor element the positioner is aligned against.`data.align`: how the positioner is aligned relative to the specified side. | | `collisionPadding` | `null; list: HTMLElement \| null; arro` | `5` | Additional space to maintain from the edge of the collision boundary. | | `collisionBoundary` | `}; export type` | `'clipping-ancestors'` | An element or a rectangle that delimits the area that the popup is confined to. | | `collisionAvoidance` | `only value: Select` | `—` | Determines how to handle collisions when positioning the popup. `side` controls overflow on the preferred placement axis (`top`/`bottom` or `left`/`right`): `'flip'`: keep the requested side when it fits; otherwise try the opposite side (`top` and `bottom`, or `left` and `right`). - `'shift'`: never change side; keep the requested side and move the popup within the clipping boundary so it stays visible. - `'none'`: do not correct side-axis overflow. `align` controls overflow on the alignment axis (`start`/`center`/`end`): `'flip'`: keep side, but swap `start` and `end` when the requested alignment overflows. - `'shift'`: keep side and requested alignment, then nudge the popup along the alignment axis to fit. - `'none'`: do not correct alignment-axis overflow. `fallbackAxisSide` controls fallback behavior on the perpendicular axis when the preferred axis cannot fit: `'start'`: allow perpendicular fallback and try the logical start side first (`top` before `bottom`, or `left` before `right` in LTR). - `'end'`: allow perpendicular fallback and try the logical end side first (`bottom` before `top`, or `right` before `left` in LTR). - `'none'`: do not fallback to the perpendicular axis. When `side` is `'shift'`, explicitly setting `align` only supports `'shift'` or `'none'`. If `align` is omitted, it defaults to `'flip'`. | | `arrowPadding` | `alue:` | `5` | Minimum distance to maintain between the arrow and the edges of the popup. Use it to prevent the arrow element from hanging out of the rounded corners of a popup. | | `sticky` | `event:` | `false` | Whether to maintain the popup in the viewport after the anchor element was scrolled out of view. | | `positionMethod` | `eReason): void; r` | `'absolute'` | Maps to Floating UI strategy (`absolute` \| `fixed`). | | `strategy` | `ing, label: string` | `—` | — | | `anchor` | `l): void; readonly items: Sele` | `—` | Override the positioning anchor (element or virtual element). | | `disableAnchorTracking` | `string` | `false` | When `true`, skip continuous layout tracking of the anchor (position once; no resize/scroll auto-updates beyond the initial compute). | | `alignItemWithTrigger` | `boolean` | `true` | Whether the positioner overlaps the trigger so the selected item's text is aligned with the trigger's value text. This only applies to mouse input and is automatically disabled if there is not enough space. | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-closed` | Present when the select popup is closed. | | `data-open` | Present when the select popup is open. | ##### Select.ScrollDownArrow An element that scrolls the select popup down when hovered. Does not render when using touch input. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-direction` | Indicates the direction of the scroll arrow. | | `data-hidden` | Present on the element when applicable. | ##### Select.ScrollUpArrow An element that scrolls the select popup up when hovered. Does not render when using touch input. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-direction` | Indicates the direction of the scroll arrow. | | `data-hidden` | Present on the element when applicable. | ##### Select.Separator A visual separator between items or groups. Renders a `
` element. No component-specific props — HTML attributes and children only. ##### Select.Trigger A button that opens the select popup. Renders a `
{#each toaster.toasts as toast (toast.id)}
Dismiss
{/each}
``` #### Updating toasts `useToastManager().update` accepts a partial object or a function of the current toast. Omitted fields are preserved: ```ts const toastManager = Toast.useToastManager(); toastManager.update(id, (prev) => ({ title: 'Upload complete', description: prev.description })); ``` #### API Reference ##### Toast.Root Groups all parts of an individual toast. Renders a `
` element. | Property | Type | Default | Description | | --- | --- | --- | --- | | `toast` | `ToastData` | `—` | — | | `swipeDirection` | `ToastSwipeDirection \| ToastSwipeDirection[] \| undefined` | `['down', 'right']` | Direction(s) in which the toast can be swiped to dismiss. | | `children` | `Snippet` | `—` | Content rendered inside the part. | | Data attribute | Description | | --- | --- | | `data-closed` | Present when the part is closed. | | `data-ending-style` | Present when the toast is animating out. | | `data-expanded` | Present when the toast is expanded in the viewport. | | `data-limited` | Present when the toast was limited because the toast limit was exceeded. | | `data-open` | Present when the part is open. | | `data-starting-style` | Present when the toast begins animating in. | | `data-swipe-direction` | The direction the toast was swiped. | | `data-swiping` | Present when the toast is being swiped. | | `data-type` | The type of the toast. | ##### Toast.Provider Provides a context for creating and managing toasts. | Property | Type | Default | Description | | --- | --- | --- | --- | | `toaster` | `ToastManager \| undefined` | `—` | — | | `timeout` | `number \| undefined` | `5000` | The default amount of time (in ms) before a toast is auto dismissed. A value of `0` will prevent the toast from being dismissed automatically. | | `limit` | `number \| undefined` | `3` | The maximum number of toasts that can be displayed at once. When the limit is exceeded, the oldest toasts are marked as `limited` (via the `data-limited` attribute) rather than removed, so they can be hidden or animated out. | | `children` | `Snippet` | `—` | Content rendered inside the part. | ##### Toast.Action Performs an action when clicked. Renders a `