The heart of Skeleton is our framework agnostic core package. This adapts and extends Tailwind to introduce our global styles, color
system, typography, and more. This section details all available Skeleton-provided utility classes and theme properties.
}
---
## @base
Extends Tailwind's base layer with a set of opinionated global styles.
...
...
...
```
## Optional
### Presets
Provides a canned set of styles for use with buttons, badges, cards, and more.
Skeleton is comprised of three pillars - the design system, our extensions to Tailwind, and an optional suite of framework-specific
components. Together these form a comprehensive solution for designing and implementing complex web interfaces at scale.
}
---
## Design System
### Figma UI Kit
A fully featured [Figma UI Kit](/figma) is available to designers, allowing them to quickly draft visual concept of your project.
### Iconography
Skeleton is icon agnostic, meaning you may bring your own iconography solution. However, we highly recommend [Lucide](https://lucide.dev/) and utilize it for all examples in our documentation. Refer to our integration guides for [React](/docs/integrations/iconography/react) and [Svelte](/docs/integrations/iconography/svelte).
### Core Features
The following features fall under the umbrella of our design system. Provided via the Skeleton core.
` in this example.
3. Override the `hidden` attribute to `false` to prevent it from showing/hiding the element too soon.
4. Add the `transition:slide` and configure your preferred options.
5. Then implement the wrapping `#if` block that triggers transitions when `attribute.hidden` is toggled.
### Provider Pattern
Most Skeleton components also support the Provider Pattern. This utilizes a provider component that replaces the root, and provides access to the inner component APIs. In practice, this allows direct access to Zag.js API features, such as programmatic control for overlay components, the ability to clear input components, and more.
```svelte
tooltip().setOpen(!tooltip().open)}>Trigger
Anchor
Content
```
### Learn More
For a comprehensive guide to how Skeleton implements components, refer to our [contribution guidelines](/docs/resources/contribute/components).
---
# Installation
Learn how to install and setup Skeleton for your project.
## Mixing UI Libraries
Skeleton's design system is perfect for complementing headless component libraries, such as [Bits UI](/docs/headless/bits-ui), [Melt UI](/docs/headless/melt-ui), [Radix](/docs/headless/radix-ui), and [Zag.js](https://zagjs.com/). As well as "Tailwind component" libraries such as the [Tailwind Plus](https://tailwindcss.com/plus). Supporting any component system that supports Tailwind, but very specifically allows you to insert or substitute Skeleton-provided utility classes.
### Unsupported Libraries
Unfortunately, Skeleton cannot integrate with [Flowbite React](https://flowbite-react.com/), [Flowbite Svelte](https://flowbite-svelte.com/), or [Daisy UI](https://daisyui.com/) at this time. Similar to Skeleton, these libraries make changes to Tailwind that directly overlaps with many of our core features, including class names and color values.
---
# Introduction
Skeleton integrates with Tailwind to provide an opinionated solution for generating adaptive design systems. Including easy to use components for your favorite web frameworks.
VIDEO
## Our Philosophy
Skeleton provides a uniform design language and structured framework for controlling the look and feel of your product and user experience. It serves as an opinionated design system that aims to greatly reduce the amount of time spent managing design elements and patterns, allowing you to more quickly build and manage your frontend interfaces at scale.
{
Framework Agnostic
Skeleton's core features are framework agnostic, only requiring the use of{' '}
Tailwind CSS
. This provides full access to all design system features, while enabling you to standardize the design process for your framework of
choice.
Native-First
We aim to embrace the interface of the web, not replace it. This is why Skeleton defaults to semantic HTML elements and native browser
APIs. Beyond ease of use, we feel this offers a huge advantages to accessibility.
Simple Standards
We aim to standardize the design process, providing common conventions that are easy to learn and retain, whether you work alone or in
a team environment. Covering common fixtures such as themes, colors, typography, spacing, and more.
Utility-First
Skeleton embraces the{' '}
utility-first
{' '}
methodology for styling, supporting all features provided by{' '}
Tailwind
, while extending it's capabilities in meaningful ways. Providing full support for the encapsulated components of the modern web.
Opt-In by Default
Most features in Skeleton are modular and opt-in by default. Enabling interface features like buttons and typography via dedicated
utility classes. This allows for a simple escape hatch when you need to draw outside the lines and generate custom interfaces.
Adaptive
Skeleton is intended to adapt to the design and aesthetic of your project, while still providing reasonable defaults. Providing a
powerful{' '}
theme generator
{' '}
for custom themes, while also supplying a curated set of themes for those less design savvy.
}
## Additional Benefits
{
Functional Components
Skeleton provides an optional suite of functional components built atop the foundation of Zag.js . These components automatically adapt to the Skeleton design system out of the box. We currently support React and Svelte, with plans for other frameworks in the future.
Frequent Updates
Skeleton has maintained a frequent release cadence over for years. Just take a look at our changelog .
Figma UI Kit
Skeleton provides access to a fully featured Figma UI Kit to assist designers in drafting a visual concept of upcoming projects.
}
---
## Get Started
### Using Skeleton
Ready to get started? Check out our comprehensive [installation guides](/docs/get-started/installation) and begin [learning the fundamentals](/docs/get-started/fundamentals).
### Contributing
Please refer to our dedicated [Contribution Guidelines](/docs/resources/contribute) if you wish to contribute directly.
---
# Migrate from v2
Learn how to migrate from Skeleton v2 to the latest version.
## Introduction
Version 3 represents a major overhaul to Skeleton. This includes a ground up rewrite of quite literally every feature in the library. We have provided a migration CLI to help automate this process. However, some portions of this migration will still required manual intervention. This is not a trivial migration from prior versions, so please use caution when updating and ensure you follow this guide very carefully.
## Prerequisites
While Skeleton v3 introduces support for multiple frameworks, we’ve historically only supported SvelteKit. As such, this guide is only intended for users migrating from Skeleton v2 and SvelteKit. If you you are coming from another meta-framework, this will be outside the scope of this guide. However, this may still provide a valuable insight to the primary objectives for migration.
### Create a Migration Branch
We recommend you handle all migration changes on a dedicated feature branch. This ensures you can easily drop or revert changes if something goes wrong.
```shell
git checkout -b migration
```
### Prepare Your Skeleton App
Please make sure you have accounted for the following:
- Your app is running the latest release of Skeleton v2.x
- All critical dependencies have been updated (optional but recommended)
- Your app is in a functional state before you proceed
---
## Migrate Core Technologies
Skeleton is built on top of the following technologies. These must be migrated individually before proceeding with the Skeleton-specific migration. Note that Svelte and Tailwind provide dedicated CLIs to automate this process.
### Svelte v5
Migrate to the latest release of Svelte v5.
Svelte v5 Migration →
### SvelteKit v2
Migrate to the latest release of SvelteKit v2.
SvelteKit v2 Migration →
### Tailwind v4
Before migration to tailwind v4 using their upgrade guide some manual steps are required:
1. Remove the `skeleton` plugin from your `tailwind.config` file.
2. Rename your `app.postcss` or `app.pcss` to `app.css`.
3. Remove the `purgecss` (`vite-plugin-tailwind-purgecss`) vite plugin from your `vite.config` (if installed).
Migrate to the latest release of Tailwind v4.
> TIP: Having trouble running Tailwind's automated migration script due to `@apply`? Remove the classes temporarily, then follow [these steps](/docs/get-started/migrate-from-v2#replacing-apply) to adapt to native CSS custom properties and Tailwind's new utilities.
Tailwind v4 Migration →
---
## Migrate to the Tailwind Vite Plugin
Use the following steps to migrate to from PostCSS to the Vite plugin:
1. Delete `postcss.config.mjs`
2. Run `npm uninstall postcss @tailwindcss/postcss`
3. Run `npm install @tailwindcss/vite`
4. Open your `vite.config` in the root of your project
5. Import the following at the top of the file: `import tailwindcss from '@tailwindcss/vite'`
6. Finally, add the Vite plugin ABOVE your specific framework plugin:
```ts
plugins: [
tailwindcss(),
sveltekit(), // or svelte()
];
```
---
## Automated Migration
We’ve provided a dedicated migration script as part of the Skeleton CLI to help automate much of this process.
> TIP: Please ensure you've committed all pending changes before proceeding.
```console
npx skeleton migrate skeleton-3
```
What WILL be migrated...
- Update all required `package.json` dependencies
- Implement all required Skeleton imports in your global stylesheet `app.css`
- Modify `data-theme` in `app.html` if you’re using a Skeleton preset theme.
- Temporarily disable custom theme imports to allow for theme migration.
- Migrate all modified Skeleton utility classes (ex: `variant-*` to `preset-*`)
- Update all Skeleton imports throughout your entire project
- Renames all relevant Skeleton components
- Some Component imports will also be pruned as they are no longer supported. We’ll cover these features in detail below.
What will NOT be migrated...
- Component props will not be updated. Unfortunately there’s too many permutations.
- Most v2 Utility features will not be migrated (ex: popovers, code blocks, etc)
Make sure to consult your local Git Diff to compare what has been modified before progressing forward or committing these automated changes.
---
## Additional Migration
With automated migration complete, please follow the remaining manual migration steps.
### Migrate Themes
#### For Preset Themes
Your preset theme should be automatically migrated by the CLI, you're all set!
#### For Custom Themes
1. Use the [Import feature](https://themes.skeleton.dev/themes/import) provided by the new Theme Generator.
2. Drag and Drop your v2 theme into the file upload field.
3. Your theme will be automatically converted to the newest format.
4. Update and modify any theme settings in the live preview.
5. Make sure to set a valid theme name in the right-hand panel.
6. Tap the “Code” tab to preview your generated theme code.
7. Copy the theme code, then following our [custom theme instructions](/docs/design/themes#custom-themes).
8. Similar to preset themes, you will need to both register and set an active theme.
### Replace AppShell with Custom Layouts
Skeleton has sunset the ([troublesome](https://github.com/skeletonlabs/skeleton/issues/2383)) `
` component in favor of user-defined custom layouts. We've provided a [Layouts](/docs/guides/layouts) guide for replicating common page structures using only semantic HTML and Tailwind - no Skeleton specific features needed!
### Migrating Components
Components have undergone the biggest update in Skeleton v3. Given the sheer number of changes, we recommend you compare each component to it's equivalent v3 documentation. We’ve highlighted a few of the key changes below:
- Changes to adopt the new [Svelte 5 APIs](https://svelte.dev/docs/svelte/v5-migration-guide) like runes, snippets, event handlers, etc.
- Changes to support [Zag.js](https://zagjs.com/), which serves as a foundation of our cross-framework components.
- Changes to the import path: `@skeletonlabs/skeleton-svelte`.
- Changes to the component name and/or structure (including sub-components)
- Changes based on newly introduces features and properties.
- Changes to adopt the new [style prop conventions](/docs/get-started/fundamentals#style-props) and cross-framework standardization.
Here's an example of changes for a single component from v2 to the new equivalent:
```svelte
```
```svelte
(value = e.value)} markers={[25, 50, 75]} />
```
We’ve denoted the most notable changes to each component in the table below:
| Name | v2 | v3 | Notes |
| ------------------ | ----------------------------------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `` | [Link](https://v2.skeleton.dev/components/app-rail) | [Link](/docs/components/navigation/svelte) | Renamed `` - greatly expanded features |
| `` | [Link](https://v2.skeleton.dev/components/file-buttons) | [Link](/docs/components/file-upload/svelte) | Renamed `` - merges `` features |
| `` | [Link](https://v2.skeleton.dev/components/file-buttons) | [Link](/docs/components/file-upload/svelte) | Renamed `` - merges `` features |
| `` | [Link](https://v2.skeleton.dev/components/input-chips) | [Link](/docs/components/tags-input/svelte) | Renamed `` |
| `` | [Link](https://v2.skeleton.dev/components/paginators) | [Link](/docs/components/pagination/svelte) | Renamed `` |
| `` | [Link](https://v2.skeleton.dev/components/progress-bars) | [Link](/docs/components/progress/svelte) | Renamed `` |
| `` | [Link](https://v2.skeleton.dev/components/progress-radials) | [Link](/docs/components/progress-ring/svelte) | Renamed `` |
| `` | [Link](https://v2.skeleton.dev/components/radio-groups) | [Link](/docs/components/segment/svelte) | Renamed `` (aka Segmented Control) |
| `` | [Link](https://v2.skeleton.dev/components/range-sliders) | [Link](/docs/components/slider/svelte) | Renamed `` |
| `` | [Link](https://v2.skeleton.dev/components/slide-toggles) | [Link](/docs/components/switch/svelte) | Renamed `` |
| `` | [Link](https://v2.skeleton.dev/components/tabs) | [Link](/docs/components/tabs/svelte) | Renamed `` |
| `` | [Link](https://v2.skeleton.dev/components/tree-views) | -- | Coming soon - [Track progress](https://github.com/skeletonlabs/skeleton/issues/2358#issuecomment-2313215789) |
### Tailwind v4 Changes
Taliwind v4 represents a major update for Tailwind. We've detailed the most notable features as they may relate to your Skeleton project. Please consult the [Tailwind v4 announcement](https://tailwindcss.com/blog/tailwindcss-v4) post for the full roster of changes.
- The `tailwing.config` has been removed in favor of [CSS-base configuration](https://tailwindcss.com/blog/tailwindcss-v4#css-first-configuration) in your global stylesheet.
- Make sure you’re using the newest strategies for supporting [Dark Mode](/docs/guides/mode).
- You are still required to implement the [Tailwind Forms Plugin](/docs/tailwind/forms#prerequisites) to use Skeleton form elements.
- The Skeleton `data-theme` attribute has moved from `` to ``
- Themes colors are now stored in the [oklch format](https://evilmartians.com/chronicles/oklch-in-css-why-quit-rgb-hsl), but optionally support any format.
### Replacing @apply
We strongly encourage you take this opportunity to move away from any usage of `@apply`. Tailwind has long since advocated against heavy use of this, and Tailwind v4 introduces new directives and functions that make this much easier to avoid. Here's a trivial example:
```css
/* Before */
.foo {
@apply bg-surface-50-950 text-surface-950 dark:text-surface-50 p-4;
}
```
```css
/* After */
.foo {
background-color: var(--color-surface-50-950);
color: var(--color-surface-950);
padding: --spacing(4);
@variant dark {
color: var(--color-surface-50);
}
}
```
- Usage of `@apply` may be found in your global stylesheet or component `
```
## How It Works
This is enabled by the native [Dialog](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog) element, which includes a dedicated Javascript API for toggling the display.
## Animations
Animating `display: none` with CSS alone has limited browser support. However, per the video below, we can use progressive enhancement our dialog to ensure animations degrade gracefully for unsupported browsers.
VIDEO
## Alternatives
If you need finer grain control, consider Skeleton's integration guides for [Floating UI](https://floating-ui.com/).
- [React Popovers](/docs/integrations/popover/react) - powered by Floating UI React.
- [Svelte Popovers](/docs/integrations/popover/svelte) - powered by Floating UI Svelte.
---
# Dynamic Theme Loading
Load skeleton themes on demand.
## About Themes
The most common way to load skeleton themes is by importing them in your root stylesheet.
```css title="app/globals.css"
@import 'tailwindcss';
@import '@skeletonlabs/skeleton';
@import '@skeletonlabs/skeleton/themes/cerberus';
@import '@skeletonlabs/skeleton/themes/catppuccin';
```
```css title="src/app.css"
@import 'tailwindcss';
@import '@skeletonlabs/skeleton';
@import '@skeletonlabs/skeleton/themes/cerberus';
@import '@skeletonlabs/skeleton/themes/catppuccin';
```
This will bundle your themes when you build your application, for that reason you should only import the themes you need because they will increase your CSS bundle size.
While this is sufficient for most applications this might not be flexible enough for your needs, you may want themes to be
user specific, editable, organization specific and so on, since skeleton themes are just CSS variables there are many ways
you can load themes on demand, read further to see how.
## Creating Stylesheets on layout load
This approach assumes the CSS variables of the skeleton theme you want is available during the load function (eg: on your database or in memory).
In this example we will add a default theme that that can be used as a fallback.
```css title="app/globals.css"
@import 'tailwindcss';
@import '@skeletonlabs/skeleton';
@import './default.css';
```
```css title="src/app.css"
@import 'tailwindcss';
@import '@skeletonlabs/skeleton';
@import './default.css';
```
```css title="app/default.css"
[data-theme='default'] {
/* ... */
}
```
```css title="src/default.css"
[data-theme='default'] {
/* ... */
}
```
To load your themes we will utilize the [NextJS `getServerSideProps` function](https://nextjs.org/docs/pages/building-your-application/data-fetching/get-server-side-props) function in combination with [Head component](https://nextjs.org/docs/pages/api-reference/components/head):
```tsx title="app/layout.tsx"
import Head from 'next/head';
import type { InferGetServerSidePropsType, GetServerSideProps } from 'next';
const getThemes = async () => {
return [
{
name: 'theme-1',
css: `[data-theme='theme-1'] { /* ... */ }`
},
{
name: 'theme-2',
css: `[data-theme='theme-2'] { /* ... */ }`
}
];
};
export const getServerSideProps = (async () => {
const themes = getThemes();
return {
props: {
themes: ['default', ...themes.map((t) => t.name)],
css: themes.map((theme) => theme.css).join('\n\n')
}
};
}) satisfies GetServerSideProps<{ repo: Repo }>;
export default function Page({ repo }: InferGetServerSidePropsType) {
return (
<>
{repo.stargazers_count}
>
);
}
```
To load your themes we will utilize the [SvelteKit `load` function](https://svelte.dev/docs/kit/load) function in combination with [``](https://svelte.dev/docs/svelte/svelte-head):
```ts title="src/route/+layout.server.ts"
import type { PageLoad } from './$types';
const getThemes = async () => {
return [
{
name: 'theme-1',
css: `[data-theme='theme-1'] { /* ... */ }`
},
{
name: 'theme-2',
css: `[data-theme='theme-2'] { /* ... */ }`
}
];
};
export const load: PageLoad = async (event) => {
const themes = getThemes();
return {
themes: ['default', ...themes.map((t) => t.name)],
css: themes.map((theme) => theme.css).join('\n\n')
};
};
```
```svelte title="src/routes/+layout.svelte"
{@html ``}
```
> ⚠️ _Important_ make sure you sanitize the CSS before inserting it or you'll be vulnerable to CSS injection.
After doing so you should be able to toggle themes on demand by changing the `data-theme` attribute on the `html` tag.
Note that there are multiple ways to go about this problem, another way could be to generate CSS files with
the same content as the one in this example and then load only the css files you want, while this
is more complex than storing and retrieving themes as JSON on a database this approach could benefit
from the browser caching mechanism.
---
# Floating UI Attachments
A Svelte-focused guide around integrating Floating UI and Svelte attachments.
Please note that this is a Svelte-only guide based around the [attachments](https://svelte.dev/docs/svelte/svelte-attachments) feature introduced in Svelte `v5.29`.
### Summary
The following will guide you through integrating [Floating UI](https://floating-ui.com/) in Svelte and generating a baseline [attachment](https://svelte.dev/docs/svelte/svelte-attachments) that can be used to scaffold any number of custom popover interfaces, including but not limited to: popovers, tooltips, dialogs, drawers, combobox, context menus, and more.
### Accessibility Warning
This guide is not a drop-in replacement for Skeleton's [Svelte Popovers](/docs/integrations/popover/svelte) as it does not replicate all recommended accessbility features out of the box (such as ARIA attributes, focus states, keyboard interactions, etc). These features are out of scope of this guide. It will be your responsibility to handle these features before using this in a production environment.
### Target Audience
This guide is intended for advanced Svelte users that wish to integrate directly with Floating UI, build custom floating interfaces, and go beyond the scope of Skeleton's [Svelte Popovers](/docs/integrations/popover/svelte). This can be used to generate interfaces not covered by Skeleton's Popover components.
## Installing Floating UI
To begin, install the standard version of Floating UI.
```console
npm install @floating-ui/dom
```
If this is your first time using Floating UI, we recommend following the [guided tutorial](https://floating-ui.com/docs/tutorial) to learn the basics.
## Creating a Svelte Attachment
Next, let's generate our custom attachment. If you're working with SvelteKit, we recommend adding this to `/src/lib/attachments/floating.svelte.ts`.
This attachment will handle the following critical functionality:
1. This imports the Svelte attachment and Floating UI dependencies.
2. Scaffolds a simple `PopoverOptions` interface, which defines our configuraton options.
3. Implement the `Popover` class, which handles all the business logic for creating and using the attachment.
4. And of course sets the default configuration via `options`.
We'll cover each additional method below.
### reference()
When implemented, this is spread to the **Trigger** element and handles interaction such as `click` and `hover`.
### floating()
When implemented, this is spread to the **Popover** element itself. This uses [createAttachmentKey](https://svelte.dev/docs/svelte/svelte-attachments#createAttachmentKey) to generate the attachment relationship itself.
### isOpen()
Returns the current `open` state as a boolean value. We'll use this to show and hide the popover on demand.
### #updatePosition()
This scaffolds [computePosition](https://floating-ui.com/docs/computePosition), which handles most of Floating UI's functionality.
## Making the Tooltip Float
Floating UI [requires these CSS styles](https://floating-ui.com/docs/tutorial#making-the-tooltip-float) to ensure the popover element "floats" over other UI. For this guide we'll handle this with a convention by adding the following your to global stylesheet. For SvelteKit this is located in `/src/app.css`.
```css
[data-floating] {
width: max-content;
position: absolute;
top: 0;
left: 0;
}
```
## Usage
### Popover
Add the following to any page within your application to generate a basic popover.
1. First, import the Popover attachment and generate an instance using `new Popover()`.
2. Next, create a wrapping `` to ensure your popover is not affected by the flow of the document.
3. Add your trigger button and spread the `popover.reference()`
4. Add your popover element and spread the `popover.floating()`
5. Apply `data-floating` to the popover element.
6. Wrap the popover element with `#if popover.isOpen()` to show/hide the popover.
> TIP: you can optionally import a [Svelte transition](https://svelte.dev/docs/svelte/svelte-transition), such as `slide`. Then use this to trigger animations on the open/close state for the popover.
### Tooltip
Add the following to any page within your application to generate a basic tooltip.
1. Similar to the Popover - we import, initialize, and scaffold the common attachment requirements.
2. Unlike the Popover though, we configure `new Popover({ ... })` to adjust `interaction` and `placement` settings.
3. We can also use a different transition, such as `fade`, as shown above.
## Handling Accessibility
We recommend you follow the [Aria APG patterns](https://www.w3.org/WAI/ARIA/apg/patterns/) when generating popover interfaces for production use. We've linked a few of the common patterns below to help you get started. This covers `aria` and `role` attributes, keyboard interactions, and other best practices.
- [Alert and Message Dialogs Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/alertdialog/)
- [Alert Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/alert/)
- [Combobox Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/)
- [Dialog (Modal) Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/)
- [Menu and Menubar Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/menubar/)
- [Tooltip](https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/)
---
# Image Layouts
Layouts for displaying sets of images.
## Grid
```html
```
## Quad
```html
```
## Masonry
```html
```
## Featured
```html
```
## Attribution
Images courtesy of [Lorem Picsum](https://picsum.photos/). Markup and styles inspired by [Flowbite](https://flowbite.com/docs/components/gallery/#masonry-grid).
---
# Light Switch
Learn how to create a Light Switch toggle.
Use [Dark Mode](/docs/guides/mode) to make use of either a base or `dark:` variant for your utility class styles. By default, Tailwind uses the `prefers-color-scheme` media query to determine and match the user's operating system settings. However, if you wish to provide your users manual control, you'll need to adjust the Dark Mode strategy for Tailwind, as well as provide the toggle interface (aka a light switch). This guide will show you how to fulfill both requirements.
## Adjust the Dark Mode Strategy
Open your global stylesheet and set the following variant:
```css
@custom-variant dark (&:where([data-mode="dark"], [data-mode="dark"] *));
```
Then set the following data attribute on your application's `` element for light mode:
```html
```
Or for dark mode:
```html
```
## Create the Component
We'll create a implementation of the Switch component that can toggle the mode on demand.
```html
// const [checked, setChecked] = useState(false);
// useEffect(() => {
// const mode = localStorage.getItem('mode') || 'light';
// setChecked(mode === 'dark');
// }, []);
// const onCheckedChange = (event: { checked: boolean }) => {
// const mode = event.checked ? 'dark' : 'light';
// document.documentElement.setAttribute('data-mode', mode);
// localStorage.setItem('mode', mode);
// setChecked(event.checked);
// };
// return (
// <>
//
//
// >
// );
}
```
## Import the Component
We'll then add the component to our app. Make sure to set the correct path and file extension.
```ts
import Lightswitch from './path/to/Lightswitch.{tsx|svelte}';
```
```svelte
```
## User Interface
While we utilize a primitive Switch for the minimal example above, feel free to adjust the logic and interface to your preference. We provide a more detailed Switch example for [React](/docs/components/switch/react#light-switch) and [Svelte](/docs/components/switch/svelte#light-switch) respectively.
## Next.js Users
For Next.js users, you will need to [suppressHydrationWarning](https://nextjs.org/docs/messages/react-hydration-error#solution-3-using-suppresshydrationwarning) to `true` on the root `` element. This will suppress hydration warnings.
---
# Logo Clouds
Provides a grid for presenting a set of logos, brands, or sponsors.
```html
Twitch
YouTube
TicTok
```
## Rows
```html
Optimize
Brand
Mesh
Matrix
Utilize
Syndicate
Incubate
Orchestrate
```
---
# Scroll Containers
Create scrolling containers using the scroll snap features from Tailwind.
## Scroll Snap
Implements Tailwind's [Scroll Snap Alignment](https://tailwindcss.com/docs/scroll-snap-align) utility classes.
```html
```
## Carousels
Using Scroll Containers, we can create a fully functional carousel, complete with thumbnail selection.
```html
---
const generatedArray = Array.from({ length: 6 });
---
{
generatedArray.map((_, i: number) => (
))
}
```
## Multi-Column
Using Scroll Containers, we can scroll sets of items.
```html
---
interface Movie {
name: string;
imageUrl: string;
url: string;
}
// Data and images via: https://www.themoviedb.org/
{
name: 'The Flash',
imageUrl: 'https://www.themoviedb.org/t/p/w600_and_h900_bestv2/rktDFPbfHfUbArZ6OOOKsXcv0Bm.jpg',
url: 'https://www.themoviedb.org/movie/298618-the-flash',
},
{
name: 'Guardians of the Galaxy Vol. 3',
imageUrl: 'https://www.themoviedb.org/t/p/w600_and_h900_bestv2/r2J02Z2OpNTctfOSN1Ydgii51I3.jpg',
url: 'https://www.themoviedb.org/movie/447365-guardians-of-the-galaxy-vol-3',
},
{
name: 'Black Panther: Wakanda Forever',
imageUrl: 'https://www.themoviedb.org/t/p/w600_and_h900_bestv2/sv1xJUazXeYqALzczSZ3O6nkH75.jpg',
url: 'https://www.themoviedb.org/movie/505642-black-panther-wakanda-forever',
},
{
name: 'Avengers: Infinity War',
imageUrl: 'https://www.themoviedb.org/t/p/w600_and_h900_bestv2/7WsyChQLEftFiDOVTGkv3hFpyyt.jpg',
url: 'https://www.themoviedb.org/movie/299536-avengers-infinity-war',
},
{
name: 'Spider-Man: No Way Home',
imageUrl: 'https://www.themoviedb.org/t/p/w600_and_h900_bestv2/1g0dhYtq4irTY1GPXvft6k4YLjm.jpg',
url: 'https://www.themoviedb.org/movie/634649-spider-man-no-way-home',
},
{
name: 'The Batman',
imageUrl: 'https://www.themoviedb.org/t/p/w600_and_h900_bestv2/74xTEgt7R36Fpooo50r9T25onhq.jpg',
url: 'https://www.themoviedb.org/movie/414906-the-batman',
},
{
name: 'Iron Man',
imageUrl: 'https://www.themoviedb.org/t/p/w600_and_h900_bestv2/78lPtwv72eTNqFW9COBYI0dWDJa.jpg',
url: 'https://www.themoviedb.org/movie/1726-iron-man',
},
{
name: 'Venom: Let There Be Carnage',
imageUrl: 'https://www.themoviedb.org/t/p/w600_and_h900_bestv2/rjkmN1dniUHVYAtwuV3Tji7FsDO.jpg',
url: 'https://www.themoviedb.org/movie/580489-venom-let-there-be-carnage',
},
{
name: 'Deadpool',
imageUrl: 'https://www.themoviedb.org/t/p/w600_and_h900_bestv2/3E53WEZJqP6aM84D8CckXx4pIHw.jpg',
url: 'https://www.themoviedb.org/movie/293660-deadpool',
},
];
---
```
> Images courtesy of [The Movie Database](https://www.themoviedb.org/)
## API Reference
Learn more about Tailwind's utility classes for scroll behavior and scroll snap.
| Feature | Description |
| ------------------------------------------------------------------- | ------------------------------------------------------------------- |
| [scroll-behavior](https://tailwindcss.com/docs/scroll-behavior) | Controls the scroll behavior of an element. |
| [scroll-margin](https://tailwindcss.com/docs/scroll-margin) | Controls the scroll offset around items in a snap container. |
| [scroll-padding](https://tailwindcss.com/docs/scroll-padding) | Controls an element's scroll offset within a snap container. |
| [scroll-snap-align](https://tailwindcss.com/docs/scroll-snap-align) | Controls the scroll snap alignment of an element. |
| [scroll-snap-stop](https://tailwindcss.com/docs/scroll-snap-stop) | Controls whether you can skip past possible snap positions. |
| [scroll-snap-type](https://tailwindcss.com/docs/scroll-snap-type) | Controls how strictly snap points are enforced in a snap container. |
---
# Stepper
Divide and present content in sequenced steps.
## Using Components
Optionally, you can substitute primitive data for components and props.
---
# SVG Filters
Apply filter effects to elements and images.
## How It Works
This feature is enabled by [SVG filters](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/filter) paired with [feColorMatrix](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/feColorMatrix) transformations.
## Usage
Apply a filter to any element using the Filter style property and passing the unique SVG Filter ID.
```astro
...
```
We've provided a curated collection of SVG Filters to choose from below.
```html
```
## Create a Filter
We recommend [SVG Color Matrix Mixer](https://fecolormatrix.com/) by [Rik Schennink](https://x.com/rikschennink/) to create your own filters.
## Tips
- The SVG must be in the same scope as the elements you wish to filter. Global scope is acceptable.
- Consder storing your SVGs within your local project for quick and reusable imports.
- All Vite-based frameworks support [SVG imports](https://vite.dev/guide/assets.html#importing-asset-as-url).
- Optionally you can embed the SVG within a imported component (ex: `Apollo.svelte`, `Apollo.tsx`).
- Filter SVGs are affected by the flow DOM, including class styles such as `space-{x|y}`.
---
# Table of Contents
Navigate the hierarchy of headings for the current page.
```html
---
interface PageHeadings {
/** The text value within the heading tag; stripped of HTML. */
text: string;
/** A generated slug value based on the text. */
slug: string;
/** Depth indicates headings H1-H6. */
depth: number;
}
/** The generated list of page headings, slugs, and depth. */
const headings: PageHeadings[] = [
{ text: 'Real World Example', slug: 'real-world-example', depth: 1 },
{ text: 'Semantic Markup', slug: 'semantic-markup', depth: 1 },
{ text: 'Utilities', slug: 'utilities', depth: 1 },
{ text: 'Grid', slug: 'grid', depth: 2 },
{ text: 'Alignment', slug: 'alignment', depth: 2 },
{ text: 'Responsive Design', slug: 'responsive-design', depth: 2 },
{ text: 'In Conclusion', slug: 'in-conclusion', depth: 1 },
];
/** Provide a padding-left class based on the depth. */
function setIndentationClass(depth: number) {
// prettier-ignore
switch(depth) {
case(6): { return 'pl-12';
}
case(5): { return 'pl-10';
}
case(4): { return 'pl-8';
}
case(3): { return 'pl-6';
}
case(2): { return 'pl-4';
}
case(1): { return 'pl-2';
}
default: { return 'pl-0';
}
}
}
---
```
## Deep Linking
Browsers allow you to deep link to any element via the ID. This is accomplished with an anchor tag and hashed (`#`) href value. When interacting with these anchors, the viewport will automatically attempt to scroll the `` element and bring the element into view.
```html
Some Example Heading
```
```html
Some Example Heading
```
> TIP: If you abstract scrolling away from the `` element, this will not work.
## Scroll Behavior
You may optionally choose to implement a smooth [scroll behavior](https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior) using CSS.
```html
```
```css
body {
scroll-behavior: smooth;
}
```
## Generate a Slug
The following provides a barebones implementation for generating a slug based on a heading text value.
```ts
function generateSlug(text: string, prefix?: string = '', suffix?: string = '') {
// Format the slug from the text value.
const slug = text
.toLowerCase()
.replaceAll(/[^a-zA-Z0-9 ]/g, '')
.replaceAll(' ', '-')
.toLowerCase();
// Note that you can optionally apply a prefix/suffix.
return `${prefix}${slug}${suffix}`;
}
// Usage
generateSlug('An Example Header'); // result: an-example-header
generateSlug('An Example Header', 'skeleton-'); // result: skeleton-an-example-header
generateSlug('An Example Header', '', '-skeleton'); // result: an-example-header-skeleton
```
## Guides
Specific instructions for generating headings will differ based on your meta-framework and your application architecture. Below are a few suggestions, but this is neither a definitive or exhaustive list of all available options.
- [Astro](https://kld.dev/building-table-of-contents/) - enables you to automatically generate headings using built-in MDX features.
- [Svelte](https://www.melt-ui.com/docs/builders/table-of-contents) - Melt UI provides a headless component solution for Svelte.
- [Next.js](https://nextra.site/docs/docs-theme/theme-configuration#toc-sidebar) - Nextra provides a headless component solution for Next.js + MDX.
- [Rehype Plugin](https://github.com/stefanprobst/rehype-extract-toc) - a general purpose Rehype plugin for generating a table of contents.
---
# Design
# Colors
The Skeleton color system.
## Color Palette
Supports all standard Tailwind color utility classes using the following pattern.
```
{property}-{color}-{shade}
```
| Key | Accepted Values |
| -------- | ---------------------------------------------------------------------------------------------------------------- |
| Property | `accent`, `bg`, `border`, `caret`, `decoration`, `divide`, `fill`, `outline`, `ring`, `shadow`, `stroke`, `text` |
| Color | `primary`, `secondary`, `tertiary`, `success`, `warning`, `error`, `surface` |
| Shade | `50`, `100`, `200`, `300`, `400`, `500`, `600`, `700`, `800`, `900`, `950` |
```html
...
...
...
```
---
## Contrast Colors
Contrast color values are available for every shade. Use these to set accessible text color and icon fill values.
```
{property}-{color}-contrast-{shade}
```
```html
```
See the [Preset system](/docs/design/presets) for additional utility classes that automatically mix each color and contrast tone.
---
## Color Pairings
Provides a condensed syntax of dual-tone color values balanced to swap between light and dark mode. These are supported for all the same properties standard colors support (`bg`, `border`, `fill`, etc).
```
{property}-{color}-{lightModeShade}-{darkModeShade}
```
For example:
- `bg-surface-200-800`
- `text-primary-400-600`
- `border-secondary-50-950`
### How Pairings Work
Color Pairing are enabled through the use of the CSS [light-dark](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/light-dark) function. For example, the `text-primary-300-700` pairing will be implemented in your CSS bundle as follows:
```css
.text-primary-300-700 {
color: light-dark(var(--color-primary-300), var(--color-primary-700));
}
```
This roughly equivalent to the following, just more compact, and enabling support for Tailwind's [Color Scheme](https://tailwindcss.com/docs/color-scheme) utilities.
```html
...
```
By default, Skeleton sets the overall app's color scheme to match light or dark mode.
### Pairing Previews
The following is a static representation of each pairing. Only `primary` is shown, but all Skeleton colors are supported.
The following shows actual Color Pairings. Toggle this website between light and dark mode to see how these react.
### When to use Pairings
Color Parings are useful for generating a hierarchy of visual layers, ranging from foreground to background elements. Each reuse the same color ramp but, but inverts the order when toggling from light to dark mode.
```html
Foreground
...
...
...
...
Branding
...
...
...
...
Background
```
- We can use shade `950` for light mode and `50` from dark mode to represent our body text color.
- Then use shade `50` from light mode and `950` from dark mode to represent our app background.
- Use the static `500` shade for key branding elements, such as buttons or banners.
- Then reserve multiple layers between for elements such as cards, inputs, and more.
---
## Transparency
Both Skeleton Colors and Color Pairings support Tailwind's color transparency syntax.
```html
Primary Color @ 25% transparency
Surface Pairing 50/950 @ 60% transparency
```
---
# Presets
Canned styles for your interface elements.
{
Presets are pre-defined styles that allow you to quickly and easily style buttons, badges, cards, and more. Create by mixing Skeleton and
Tailwind primitives.
}
```html
```
1. **Filled** - a filled preset of the primary brand color.
2. **Tonal** - a tonal preset of the primary brand color.
3. **Outlined** - an outlined preset of the primary brand color.
4. **Glass** - a custom preset using background transparency and backdrop blur.
5. **Elevated** - mixes a filled preset with a shadow.
6. **Ghost** - has no style by default, but shows a tonal preset on hover.
7. **Ghost Icon** - has no style by default, but shows a branded tonal preset on hover.
8. **Gradient** - a custom preset generated using Tailwind gradient primitives.
## Skeleton Presets
Skeleton's provides the following opinionated set of styles, including accessible backgrounds and text colors.
### Filled
```
preset-filled-{color}-{lightModeShade}-{darkModeShade}
```
```html
(neutral)
950-50
900-100
800-200
700-300
600-400
500
400-600
300-700
200-800
100-900
50-950
```
### Tonal
```
preset-tonal-{color}
```
```html
(neutral)
primary
secondary
tertiary
success
warning
error
surface
```
### Outlined
```
preset-outlined-{color}-{shade}-{shade}
```
```html
(neutral)
950-50
900-100
800-200
700-300
600-400
500
400-600
300-700
200-800
100-900
50-950
```
## Custom Presets
Consider these best practices when creating presets:
- Custom presets are only limited by your imagination.
- Use any combination of Skeleton or Tailwind-provided primitive to generate a preset.
- Apply presets to any relevant element, including: buttons, cards, inputs, and more.
- Use a set naming convention, such as `preset-{foo}` to keep things standardized.
- Implement all presets in using Tailwind's [@utility directive](https://tailwindcss.com/docs/functions-and-directives#utility-directive) in your global stylesheet.
- Abstrast presets to a stylesheet or NPM package for shared used between projects.
Please be aware the following presets are not included by Skeleton. Rather, these are examples of how you might utilize the Preset pattern.
### Input Presets
```html
```
### Gradient Presets
Tailwind provides a number of powerful [Gradient](https://tailwindcss.com/docs/gradient-color-stops) utility classes that can be used to generate presets.
```html
```
### Glass Presets
```html
---
const baseClasses = 'card p-4 text-white text-center flex justify-start items-center';
---
Neutral
Primary
Secondary
Tertiary
Success
Warning
Error
Surface
```
---
# Spacing
Set a dynamic scale for application whitespace.
This is enabled by the [Tailwind spacing system](https://tailwindcss.com/blog/tailwindcss-v4#dynamic-utility-values-and-variants).
Scaling can be adjusted by modifying the [type scale](/docs/get-started/core-api#typography) theme property.
```css
[data-theme='cerberus'] {
--spacing: 0.25rem;
}
```
This affects the following utilities.
- `padding`
- `margin`
- `width`
- `minWidth`
- `maxWidth`
- `height`
- `minHeight`
- `maxHeight`
- `gap`
- `inset`
- `space`
- `translate`
---
# Themes
The Skeleton theme system.
{
Skeleton themes utilize{' '}
CSS custom properties
{' '}
to define core settings for your design system. Provided with a number of presets theme out of the box, as well as a powerful theme
generator to create your own. Enable one or more and quickly switch on-demand.
}
---
## Preset Themes
Skeleton is provided with high quality set of hand curated themes, as shown below.
Tap the theme preview above to copy the theme name to your clipboard. Then implement any desired theme in your app's global stylesheet.
```css title="app.css" {3}
/* @import '@skeletonlabs/skeleton'; */
@import '@skeletonlabs/skeleton/themes/{theme-name}';
```
> Make sure to replace `{theme-name}` with your desired theme names.
## Custom Themes
Use our powerful Theme Generator app to create your own themes.
Theme Generator
1. Open the Theme Generator and customize to your preference.
2. Make sure to set a unique name for your theme.
3. Tap the "code" view from the menu at top-right corner.
4. Tap the "copy" button at the top of copy the theme contents.
5. Paste the contents into a new file at your project root, such as `my-theme-name.css` (any name is fine).
Follow the step below to register any number of custom themes. Take care to match each theme's file name.
## Register Themes
You may register any number of themes by adding addition theme imports to your global stylesheet. Please note that each theme will slightly increase the final CSS bundle size.
```css
/* @import '@skeletonlabs/skeleton'; */
/* Register Preset Themes */
@import '@skeletonlabs/skeleton/themes/cerberus';
@import '@skeletonlabs/skeleton/themes/mona';
@import '@skeletonlabs/skeleton/themes/vox';
/* Register a Custom Themes */
/* Make sure to resolve the relative path. */
/* Note the .css extension is optional. */
@import '../{my-theme-name}';
```
## Activate a Theme
You may define the active theme using the `data-theme` attribute on your `` element.
```html
...
```
> TIP: If you wish to create a theme switcher, this is the value you should aim to modify.
---
## Customize and Extend
### Modify Properties
You can modify any [theme property](/docs/get-started/core-api) on demand using the following technique. Simply add this to your global stylesheet, following all Tailwind and Skeleton configuration. Use this to override preset theme properties.
```css title="app.css"
[data-theme='cerberus'] {
--spacing: 0.22rem;
--radius-container: 0.375rem;
--heading-font-weight: bolder;
}
```
### Target Themes
If your application supports multiple themes, you may isolate selection using the `data-theme` attribute. Just make sure to account for light and dark mode color values.
```css title="app.css"
/** Target only Cerberus .h1 elements. */
[data-theme='cerberus'] .h1 {
color: red;
@variant dark {
color: green;
}
}
/** Target only Mona .h1 elements. */
[data-theme='mona'] .h1 {
color: blue;
@variant dark {
color: yellow;
}
}
```
### Backgrounds
Your app's light and dark mode background color values can be adjusted using the following [theme properties](/docs/get-started/core-api#colors).
```css title="app.css"
[data-theme='cerberus'] body {
--body-background-color: pink;
--body-background-color-dark: green;
}
```
Background images are supported, including CSS mesh gradients. The following example adheres to theme colors.
```css title="app.css"
[data-theme='cerberus'] body {
background-image:
radial-gradient(at 24% 25%, color-mix(in oklab, var(--color-primary-500) 30%, transparent) 0px, transparent 30%),
radial-gradient(at 35% 13%, color-mix(in oklab, var(--color-success-500) 18%, transparent) 0px, transparent 30%),
radial-gradient(at 100% 64%, color-mix(in oklab, var(--color-error-500) 3%, transparent) 0px, transparent 40%);
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
```
We recommend Mesher for generating custom mesh gradients. This will generate colors using RGB, but can be migrated to utilize `var()` for colors and `color-mix()` for transparency, per the example above.
Mesher by CSS Hero
### Custom Fonts
Skeleton recommends the use of [Fontsource](https://fontsource.org/) for installing and managing custom fonts.
Browse Fontsource
Install your font of choice.
```console
npm install @fontsource/open-sans
```
Then import each font at the top of your global stylesheet, but below your Tailwind configuration.
```css title="app.css"
@import '@fontsource/open-sans';
```
Finally, use the following [theme properties](/docs/get-started/core-api#base-1) to set each respective font-family property. Note that for custom themes, these settings are can be defined directly within each respective theme file.
```css title="app.css"
[data-theme='cerberus'] {
--heading-font-family: 'Open Sans', sans-serif;
--base-font-family: 'Open Sans', sans-serif;
--anchor-font-family: 'inherit';
}
```
## Core API
For more information, please refer to the full [Core API](/docs/get-started/core-api) documentation.
---
# Typography
The Skeleton typography system.
{
Skeleton provides an array of opt-in utility classes for common typographic elements, with a fully functional typography scale based on
your theme settings. As well as a number of primitives for generating a semantic typography set for your project's individual needs.
}
## Typographic Scale
Skeleton introduces customizable [Typographic Scale](https://designcode.io/typographic-scales) to Tailwind's [font-size](https://tailwindcss.com/docs/font-size) properties.
Scaling can be adjusted by modifying the [type scale](/docs/get-started/core-api#typography) theme property.
```css
[data-theme='cerberus'] {
--text-scaling: 1.067;
}
```
This affects the following text sizes.
```html
text-xs
text-sm
text-base
text-lg
text-xl
text-2xl
text-3xl
text-4xl
text-5xl
text-6xl
text-7xl
text-8xl
text-9xl
```
## Utility Classes
Use the following utility classes to quickly style semantic HTML elements. These classes are opt-in by default, providing a simple escape hatch when you need to break from convention.
### Headings
```html
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
```
### Paragraphs
```html
The quick brown fox jumps over the lazy dog
```
### Blockquotes
```html
"Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nesciunt, aliquid. Molestias, odio illum voluptatibus natus dignissimos, quidem
est unde aspernatur veniam pariatur fuga distinctio esse in quas, repellendus neque reiciendis!"
```
### Anchor
```html
Anchor
```
### Pre-Formatted
```html
The quick brown fox jumps over the lazy dog.
```
### Code
```html
Insert the .example
class here.
```
### Keyboard
```html
Press ⌘ + C to copy.
```
### Insert & Delete
```html
Always Gonna Give You Up
Never Gonna Give You Up
```
### Mark
```html
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nesciunt, aliquid . Molestias, odio illum voluptatibus natus dignissimos , quidem est unde aspernatur veniam pariatur fuga.
```
## Lists
Skeleton defers to Tailwind's built-in utility classes for common list styles.
### Unordered
```html
Id maxime optio soluta placeat ea eaque similique consectetur dicta tempore.
Repellat veritatis et harum ad sint reprehenderit tenetur, possimus tempora.
Lorem ipsum dolor sit amet consectetur adipisicing elit harum ad sint.
```
### Ordered
```html
Id maxime optio soluta placeat ea eaque similique consectetur dicta tempore.
Repellat veritatis et harum ad sint reprehenderit tenetur, possimus tempora.
Lorem ipsum dolor sit amet consectetur adipisicing elit harum ad sint.
```
### Basic
```html
Id maxime optio soluta placeat ea eaque similique consectetur dicta tempore.
Repellat veritatis et harum ad sint reprehenderit tenetur, possimus tempora.
Lorem ipsum dolor sit amet consectetur adipisicing elit harum ad sint.
```
### Description
```html
Item A
Id maxime optio soluta placeat ea eaque similique consectetur dicta tempore.
Item B
Repellat veritatis et harum ad sint reprehenderit tenetur, possimus tempora.
Item C
Lorem ipsum dolor sit amet consectetur adipisicing elit harum ad sint.
```
### Navigation
```html
Explore
```
## Semantic Typography
When working with your designers, they may craft a semantic typography set for your project. To handle this, we recommend implementing [custom presets](/docs/design/presets#custom-presets) that mix CSS primitives with semantic HTML elements to replicate all desired styles. Feel free to use the boilerplate below, adding each style to your global stylesheet.
```html
Class
Preview
preset-typo-display-4
Aa
preset-typo-display-3
Aa
preset-typo-display-2
Aa
preset-typo-display-1
Aa
preset-typo-headline
Headline
preset-typo-title
Title
preset-typo-subtitle
Subtitle
preset-typo-body-1
Body 1
preset-typo-body-2
Body 2
preset-typo-caption
Caption
preset-typo-menu
preset-typo-button
Button
```
---
# Tailwind
# Badges
Provides a robust set of non-interactive badge styles.
```html
---
---
Badge
Badge
```
## Presets
Provides full support of [Presets](/docs/design/presets).
```html
Badge
Badge
Badge
Badge
Badge
Badge
Badge
Badge
Badge
Badge
Badge
Badge
Badge
Badge
Badge
Badge
Badge
Badge
Badge
Badge
Badge
```
## Overlap
Use `badge-icon` to create overlapping numeric or icon badges.
```html
---
const imgSrc =
'https://images.unsplash.com/photo-1620122303020-87ec826cf70d?q=80&w=256&h=256&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D';
---
2
```
---
# Buttons
Provide a variety of button, including customizable sizes and types.
```html
---
---
Button
Button
```
## Presets
Provides full support of [Presets](/docs/design/presets).
```html
Button
Button
Button
Button
Button
Button
Button
Button
Button
Button
Button
Button
Button
Button
Button
Button
Button
Button
Button
Button
Button
```
## Sizes
```html
Small
Base
Large
```
## Disabled
When applied to a `` element, you can use the `disabled` attribute.
```html
Button
```
## Group
```html
January
February
March
```
---
# Cards
Provides container elements that wrap and separate content.
```html
```
```html
---
const imgSrc =
'https://images.unsplash.com/photo-1463171515643-952cee54d42a?q=80&w=450&h=190&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D';
---
Announcements
Skeleton is Awesome
Lorem ipsum dolor sit amet consectetur adipisicing elit. Numquam aspernatur provident eveniet eligendi cumque consequatur tempore sint
nisi sapiente. Iste beatae laboriosam iure molestias cum expedita architecto itaque quae rem.
By Alex
On {new Date().toLocaleDateString()}
```
## Presets
Provides full support of [Presets](/docs/design/presets).
```html
Card
Card
Card
Card
Card
Card
Card
Card
Card
Card
Card
Card
Card
Card
Card
Card
Card
Card
Card
Card
Card
```
---
# Chips
Provides a robust set of interactive chip styles.
```html
---
---
Chip
Chip
```
## Presets
Provides full support of [Presets](/docs/design/presets).
```html
Chip
Chip
Chip
Chip
Chip
Chip
Chip
Chip
Chip
Chip
Chip
Chip
Chip
Chip
Chip
Chip
Chip
Chip
Chip
Chip
Chip
```
## Disabled
When applied to a `` element, you can use the `disabled` attribute.
```html
Chip
```
## Selection
```html
const colors = ['red', 'blue', 'green'];
const [color, setColor] = useState(colors[0]);
return (
{color &&
colors.map((c) => (
// On selection, set the color state, dynamically update classes
setColor(c)} key={c}>
{c}
))}
);
};
```
---
# Dividers
Horizontal and vertical rule styling.
```html
Above the divider.
Below the divider.
```
## Size
Use Tailwind's [border width](https://tailwindcss.com/docs/border-width) utilities to adjust thickness.
```html
Default
border-t-2
border-t-4
border-t-8
```
## Style
Use Tailwind's [border style](https://tailwindcss.com/docs/border-style) utilities to adjust visual style.
```html
border-solid
border-dashed
border-dotted
border-double
```
## Colors
Use any Tailwind or Skeleton [colors or pairing](/docs/design/colors).
```html
border-primary-500
border-secondary-500
border-tertiary-500
border-success-500
border-warning-500
border-error-500
border-surface-950-50
```
## Vertical
Use `vr` for a vertical rule, which supports all above styles. Make sure to set the height.
```html
Default
→
← border-l-8
```
---
# Forms and Inputs
Various form and input styles.
```html
Input
```
## Prerequisites
### Tailwind Forms
Skeleton relies on the official [Tailwind Forms](https://github.com/tailwindlabs/tailwindcss-forms) plugin to normalize form styling. This plugin is required if you wish to make use of any utility classes provided on this page.
Plugin Doc
Install the `@tailwindcss/forms` package.
```sh
npm install -D @tailwindcss/forms
```
Implement the plugin using the `@plugin` directive immediately following the `tailwindcss` import.
```css {2}
@import 'tailwindcss';
@plugin '@tailwindcss/forms';
/* ...Skeleton config here... */
```
### Browser Support
The display of native and semantic HTML form elements can vary between both operating systems and browsers. Skeleton does it's best to adhere to progressive enhancement best practices. However, we advise you validate support for each element per your target audience.
## Inputs
```html
```
## Select
```html
```
## Checkboxes
```html
```
## Radio Groups
```html
```
## Kitchen Sink
Display and functionality of these elements may vary greatly between devices and browsers.
```html
```
## Groups
Input groups support a subset of form elements and button styles. These pair well with [Presets](/docs/design/presets).
```html
---
---
```
| Class | Usage |
| ------------- | --------------------------------------- |
| `input-group` | Defines the parent input group set. |
| `ig-cell` | Defines a child cell for text or icons. |
| `ig-input` | Defines a child input of `type="text"`. |
| `ig-select` | Defines a child select element. |
| `ig-btn` | Defines a child button. |
---
# Placeholders
Provides "skeleton" placeholders that can display while content loads.
```html
```
## Animated
```html
...
```
---
# Tables
Provides a set of styles for native HTML table elements.
```html
---
const tableData = [
{ position: '0', name: 'Iron', symbol: 'Fe', atomic_no: '26' },
{ position: '1', name: 'Rhodium', symbol: 'Rh', atomic_no: '45' },
{ position: '2', name: 'Iodine', symbol: 'I', atomic_no: '53' },
{ position: '3', name: 'Radon', symbol: 'Rn', atomic_no: '86' },
{ position: '4', name: 'Technetium', symbol: 'Tc', atomic_no: '43' },
];
---
{
tableData.map((row) => (
{row.position}
{row.symbol}
{row.name}
{row.atomic_no}
))
}
```
## Extras
Optionally add a header, footer, and caption.
```html
---
const tableData = [
{ position: '0', name: 'Iron', symbol: 'Fe', atomic_no: '26' },
{ position: '1', name: 'Rhodium', symbol: 'Rh', atomic_no: '45' },
{ position: '2', name: 'Iodine', symbol: 'I', atomic_no: '53' },
{ position: '3', name: 'Radon', symbol: 'Rn', atomic_no: '86' },
{ position: '4', name: 'Technetium', symbol: 'Tc', atomic_no: '43' },
];
---
A list of elements from the periodic table.
Position
Symbol
Name
Weight
{
tableData.map((row) => (
{row.position}
{row.symbol}
{row.name}
{row.atomic_no}
))
}
Total
{tableData.length} Elements
```
## Navigation
Native HTML tables do not support interaction. For accessibility, use anchors or buttons within the last cell.
```html
---
const tableData = [
{ first: 'Liam', last: 'Steele', email: 'liam@email.com' },
{ first: 'Athena', last: 'Marks', email: 'athena@email.com' },
{ first: 'Angela', last: 'Rivers', email: 'angela@email.com' },
];
---
First Name
Last Name
Email
{
tableData.map((row) => (
{row.first}
{row.last}
{row.email}
View →
))
}
```
## Layout
See [Tailwind's utility classes](https://tailwindcss.com/docs/table-layout) for adjusting the table layout algorithm. Apply this to the Table element.
## Hover Rows
Add a visual hover effect using the following Tailwind syntax.
```html
...
```
## Pagination
Pair with the Skeleton [Pagination](/docs/components/pagination/react) component for large data sets.
---
# Components
# Accordion
Divide content into collapsible sections.
```svelte
Club
{#snippet children(accordion)}
{accordion().value.includes('item-1') ? '-' : '+'}
{/snippet}
{lorem}
Diamond
{#snippet children(accordion)}
{accordion().value.includes('item-2') ? '-' : '+'}
{/snippet}
{lorem}
Heart
{#snippet children(accordion)}
{accordion().value.includes('item-3') ? '-' : '+'}
{/snippet}
{lorem}
Spade
{#snippet children(accordion)}
{accordion().value.includes('item-4') ? '-' : '+'}
{/snippet}
{lorem}
```
## Controlled
Use `value` and `onValueChange` to control the value of the Accordion.
```svelte
(value = e.value)}>
Item 1
Content for Item 1
Item 2
Content for Item 2
Item 3
Content for Item 3
```
## Collapsible
By default you can't close open items. Adding `collapsible` changes this behavior.
```svelte
Item 1
Content for Item 1
Item 2
Content for Item 2
Item 3
Content for Item 3
```
## Multiple
Adding `multiple` allows items to open independently.
```svelte
Item 1
Content for Item 1
Item 2
Content for Item 2
Item 3
Content for Item 3
```
## Grid Columns
Use the [grid-cols-\*](https://tailwindcss.com/docs/grid-template-columns) utility to adjust the layout of the Trigger component.
```svelte
Club
Content for Item 1
Diamond
Content for Item 2
Heart
Content for Item 3
Spade
Content for Item 4
```
## Direction
```svelte
Item 1
Content for Item 1
Item 2
Content for Item 2
Item 3
Content for Item 3
```
## API Reference
### AccordionRoot
| Property | Type | Description |
| --- | --- | --- |
| `ids` | Partial<{ root: string; item: (value: string) => string; itemContent: (value: string) => string; itemTrigger: (value: string) => string; }> | undefined | The ids of the elements in the accordion. Useful for composition. |
| `multiple` | boolean | undefined | Whether multiple accordion items can be expanded at the same time. Default: false |
| `collapsible` | boolean | undefined | Whether an accordion item can be closed after it has been expanded. Default: false |
| `value` | string[] | undefined | The controlled value of the expanded accordion items. |
| `defaultValue` | string[] | undefined | The initial value of the expanded accordion items. Use when you don't need to control the value of the accordion. |
| `disabled` | boolean | undefined | Whether the accordion items are disabled |
| `onValueChange` | ((details: ValueChangeDetails) => void) | undefined | The callback fired when the state of expanded/collapsed accordion items changes. |
| `onFocusChange` | ((details: FocusChangeDetails) => void) | undefined | The callback fired when the focused accordion item changes. |
| `orientation` | "horizontal" | "vertical" | undefined | The orientation of the accordion items. Default: "vertical" |
| `dir` | "ltr" | "rtl" | undefined | The document's text/writing direction. Default: "ltr" |
| `getRootNode` | (() => ShadowRoot | Node | Document) | undefined | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### AccordionRootProvider
| Property | Type | Description |
| --- | --- | --- |
| `value`* | () => AccordionApi | |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### AccordionRootContext
| Property | Type | Description |
| --- | --- | --- |
| `children`* | Snippet<[() => AccordionApi]> | |
### AccordionItem
| Property | Type | Description |
| --- | --- | --- |
| `value`* | string | The value of the accordion item. |
| `disabled` | boolean | undefined | Whether the accordion item is disabled. |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### AccordionItemTrigger
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"button">]> | undefined | Render the element yourself |
### AccordionItemIndicator
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### AccordionItemContent
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
---
# App Bar
A header element for the top of your page layout.
```svelte
Headline
```
## Centered
Control the layout using a [grid-cols-\*](https://tailwindcss.com/docs/grid-column) utility class.
```svelte
Headline
```
## Extended
Move the `` to a new row within the root.
```svelte
Headline
```
## Responsive
```svelte
Headline
Headline
```
## API Reference
### AppBarRoot
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"header">]> | undefined | Render the element yourself |
### AppBarToolbar
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### AppBarLead
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"nav">]> | undefined | Render the element yourself |
### AppBarHeadline
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### AppBarTrail
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"nav">]> | undefined | Render the element yourself |
---
# Avatar
An image with a fallback for representing the user.
```svelte
SK
```
## Fallback
Use `` to provide initials, icons, or a framework-specific image component.
```svelte
SK
```
## Filter
Avatars can implement [SVG Filters](/docs/guides/cookbook/svg-filters) using the image `class` attribute.
```svelte
SK
```
## API Reference
### AvatarRoot
| Property | Type | Description |
| --- | --- | --- |
| `onStatusChange` | ((details: StatusChangeDetails) => void) | undefined | Functional called when the image loading status changes. |
| `ids` | Partial<{ root: string; image: string; fallback: string; }> | undefined | The ids of the elements in the avatar. Useful for composition. |
| `getRootNode` | (() => ShadowRoot | Node | Document) | undefined | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. |
| `dir` | "ltr" | "rtl" | undefined | The document's text/writing direction. Default: "ltr" |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### AvatarRootProvider
| Property | Type | Description |
| --- | --- | --- |
| `value`* | () => AvatarApi | |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### AvatarRootContext
| Property | Type | Description |
| --- | --- | --- |
| `children`* | Snippet<[() => AvatarApi]> | |
### AvatarImage
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"img">]> | undefined | Render the element yourself |
### AvatarFallback
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"span">]> | undefined | Render the element yourself |
---
# Combobox
A combobox is an input widget with an associated popup that enables users to select a value from a collection of possible values.
```svelte
Label
{#each items as item (item.value)}
{item.label}
{/each}
```
## Groups
Create labelled groups for your items.
```svelte
{#each collection.group() as [type, items] (type)}
{type}
{#each items as item (item.value)}
{item.label}
{/each}
{/each}
```
## Auto Highlight
Search for any option, then tap Enter on your keyboard to automatically select it.
```svelte
{#each items as item (item.value)}
{item.label}
{/each}
```
## Multiple
To maintain filtering functionality and improve clarity for users, we recommend displaying each selected value outside the perimeter of the Combobox component.
```svelte
{#each items as item (item.value)}
{item.label}
{/each}
{#each value as item (item)}
{item}
{/each}
```
## Disabled Item
```svelte
{#each items as item (item.value)}
{item.label}
{/each}
```
## Custom Filter
Try mistyping `apple` or `banana` to see the custom filter using the fuzzy search from [Fuse.js](https://fusejs.io/) in action.
```svelte
{#each items as item (item.value)}
{item.label}
{/each}
```
## Direction
```svelte
Label
{#each items as item (item.value)}
{item.label}
{/each}
```
## Guidelines
### Z-Index
By default we do not take an opinionated stance regarding z-index stacking. The result is the component can sometimes be occluded beneath other elements with a higher index. The Z-Index can controlled by applying a utility class to the Positioner component part.
```svelte
{#each items as item (item.value)}
{item.label}
{/each}
```
### Max Items
We recommend no more than 500 items max. For normal usage, a few dozen will provide the best performance.
## API Reference
### ComboboxRoot
| Property | Type | Description |
| --- | --- | --- |
| `open` | boolean | undefined | The controlled open state of the combobox |
| `defaultOpen` | boolean | undefined | The initial open state of the combobox when rendered. Use when you don't need to control the open state of the combobox. |
| `ids` | Partial<{ root: string; label: string; control: string; input: string; content: string; trigger: string; clearTrigger: string; item: (id: string, index?: number | undefined) => string; positioner: string; itemGroup: (id: string | number) => string; itemGroupLabel: (id: string | number) => string; }> | undefined | The ids of the elements in the combobox. Useful for composition. |
| `inputValue` | string | undefined | The controlled value of the combobox's input |
| `defaultInputValue` | string | undefined | The initial value of the combobox's input when rendered. Use when you don't need to control the value of the combobox's input. Default: "" |
| `name` | string | undefined | The `name` attribute of the combobox's input. Useful for form submission |
| `form` | string | undefined | The associate form of the combobox. |
| `disabled` | boolean | undefined | Whether the combobox is disabled |
| `readOnly` | boolean | undefined | Whether the combobox is readonly. This puts the combobox in a "non-editable" mode but the user can still interact with it |
| `invalid` | boolean | undefined | Whether the combobox is invalid |
| `required` | boolean | undefined | Whether the combobox is required |
| `placeholder` | string | undefined | The placeholder text of the combobox's input |
| `defaultHighlightedValue` | string | null | undefined | The initial highlighted value of the combobox when rendered. Use when you don't need to control the highlighted value of the combobox. |
| `highlightedValue` | string | null | undefined | The controlled highlighted value of the combobox |
| `value` | string[] | undefined | The controlled value of the combobox's selected items |
| `defaultValue` | string[] | undefined | The initial value of the combobox's selected items when rendered. Use when you don't need to control the value of the combobox's selected items. Default: [] |
| `inputBehavior` | "autohighlight" | "autocomplete" | "none" | undefined | Defines the auto-completion behavior of the combobox. - `autohighlight`: The first focused item is highlighted as the user types - `autocomplete`: Navigating the listbox with the arrow keys selects the item and the input is updated Default: "none" |
| `selectionBehavior` | "clear" | "replace" | "preserve" | undefined | The behavior of the combobox input when an item is selected - `replace`: The selected item string is set as the input value - `clear`: The input value is cleared - `preserve`: The input value is preserved Default: "replace" |
| `autoFocus` | boolean | undefined | Whether to autofocus the input on mount |
| `openOnClick` | boolean | undefined | Whether to open the combobox popup on initial click on the input Default: false |
| `openOnChange` | boolean | ((details: InputValueChangeDetails) => boolean) | undefined | Whether to show the combobox when the input value changes Default: true |
| `allowCustomValue` | boolean | undefined | Whether to allow typing custom values in the input |
| `alwaysSubmitOnEnter` | boolean | undefined | Whether to always submit on Enter key press, even if popup is open. Useful for single-field autocomplete forms where Enter should submit the form. Default: false |
| `loopFocus` | boolean | undefined | Whether to loop the keyboard navigation through the items Default: true |
| `positioning` | PositioningOptions | undefined | The positioning options to dynamically position the menu Default: { placement: "bottom-start" } |
| `onInputValueChange` | ((details: InputValueChangeDetails) => void) | undefined | Function called when the input's value changes |
| `onValueChange` | ((details: ValueChangeDetails) => void) | undefined | Function called when a new item is selected |
| `onHighlightChange` | ((details: HighlightChangeDetails) => void) | undefined | Function called when an item is highlighted using the pointer or keyboard navigation. |
| `onSelect` | ((details: SelectionDetails) => void) | undefined | Function called when an item is selected |
| `onOpenChange` | ((details: OpenChangeDetails) => void) | undefined | Function called when the popup is opened |
| `translations` | IntlTranslations | undefined | Specifies the localized strings that identifies the accessibility elements and their states |
| `collection` | ListCollection | undefined | The collection of items |
| `multiple` | boolean | undefined | Whether to allow multiple selection. **Good to know:** When `multiple` is `true`, the `selectionBehavior` is automatically set to `clear`. It is recommended to render the selected items in a separate container. |
| `closeOnSelect` | boolean | undefined | Whether to close the combobox when an item is selected. |
| `openOnKeyPress` | boolean | undefined | Whether to open the combobox on arrow key press Default: true |
| `scrollToIndexFn` | ((details: ScrollToIndexDetails) => void) | undefined | Function to scroll to a specific index |
| `composite` | boolean | undefined | Whether the combobox is a composed with other composite widgets like tabs Default: true |
| `disableLayer` | boolean | undefined | Whether to disable registering this a dismissable layer |
| `navigate` | ((details: NavigateDetails) => void) | null | undefined | Function to navigate to the selected item |
| `dir` | "ltr" | "rtl" | undefined | The document's text/writing direction. Default: "ltr" |
| `getRootNode` | (() => ShadowRoot | Node | Document) | undefined | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. |
| `onPointerDownOutside` | ((event: PointerDownOutsideEvent) => void) | undefined | Function called when the pointer is pressed down outside the component |
| `onFocusOutside` | ((event: FocusOutsideEvent) => void) | undefined | Function called when the focus is moved outside the component |
| `onInteractOutside` | ((event: InteractOutsideEvent) => void) | undefined | Function called when an interaction happens outside the component |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### ComboboxRootProvider
| Property | Type | Description |
| --- | --- | --- |
| `value`* | () => ComboboxApi | |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### ComboboxRootContext
| Property | Type | Description |
| --- | --- | --- |
| `children`* | Snippet<[() => ComboboxApi]> | |
### ComboboxLabel
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"label">]> | undefined | Render the element yourself |
### ComboboxControl
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### ComboboxInput
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"input">]> | undefined | Render the element yourself |
### ComboboxTrigger
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"button">]> | undefined | Render the element yourself |
### ComboboxPositioner
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### ComboboxContent
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"ul">]> | undefined | Render the element yourself |
### ComboboxItemGroup
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### ComboboxItemGroupLabel
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### ComboboxItem
| Property | Type | Description |
| --- | --- | --- |
| `persistFocus` | boolean | undefined | Whether hovering outside should clear the highlighted state |
| `item`* | any | The item to render |
| `element` | Snippet<[HTMLAttributes<"li">]> | undefined | Render the element yourself |
### ComboboxItemText
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"span">]> | undefined | Render the element yourself |
### ComboboxItemIndicator
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
---
# Dialog
A modal dialog for displaying content and actions.
```svelte
Trigger
Hello World
This is an example of a basic dialog.
Close
```
## Alert Dialog
The [alertdialog](https://w3c.github.io/aria/#alertdialog) role enables assistive technologies and browsers to distinguish alert dialogs from other dialogs so they have the option of giving alert dialogs special treatment, such as playing a system alert sound.
```svelte
Trigger
Alert
Something important has happened!
Close
```
## Interaction
If desired, you can disable click to close interactions for the backdrop. We recommend using this sparingly, as this traps the
user in this experience.
```svelte
Trigger
Dialog Title
This dialog will only close with the Close button or via programmatic controls.
Close
```
## Drawer
This example repurposes the Dialog for use as a side-panel Drawer. It also introduces basic transition animations.
```svelte
Trigger
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Nulla, soluta optio assumenda nobis dignissimos minus doloremque in
aliquid amet laboriosam! Soluta recusandae facilis provident ratione a! Vitae expedita rerum magni.
```
## Z-Index
By default we do not take an opinionated stance regarding z-index stacking. The result is the component can sometimes be occluded beneath other elements with a higher index. The Z-Index can controlled by applying a utility class to the `Positioner` component part.
```svelte
Trigger
Setting Z-Index
This dialog will have a z-index value of 50.
Close
```
## Direction
```svelte
Trigger
Hello World
This is an example of a basic dialog.
Close
```
## Headless
Unlike most components in Skeleton, this feature is provided "headless". This means no default styles are applied out of the box. This ensures you retain full control of all styling.
```svelte
Three spooky skeletons!
```
The benefits are as follows:
- You can make the `Trigger` surround any element, including an icon, button, image, etc.
- You can modify the entire structure within `Content`, including custom markup and styling.
- You may place the `CloseTrigger` anywhere, and use it as an X close option.
## API Reference
### DialogRoot
| Property | Type | Description |
| --- | --- | --- |
| `dir` | "ltr" | "rtl" | undefined | The document's text/writing direction. Default: "ltr" |
| `role` | "dialog" | "alertdialog" | undefined | The dialog's role Default: "dialog" |
| `aria-label` | string | undefined | Human readable label for the dialog, in event the dialog title is not rendered |
| `ids` | Partial<{ trigger: string; positioner: string; backdrop: string; content: string; closeTrigger: string; title: string; description: string; }> | undefined | The ids of the elements in the dialog. Useful for composition. |
| `trapFocus` | boolean | undefined | Whether to trap focus inside the dialog when it's opened Default: true |
| `preventScroll` | boolean | undefined | Whether to prevent scrolling behind the dialog when it's opened Default: true |
| `modal` | boolean | undefined | Whether to prevent pointer interaction outside the element and hide all content below it Default: true |
| `initialFocusEl` | (() => MaybeElement) | undefined | Element to receive focus when the dialog is opened |
| `finalFocusEl` | (() => MaybeElement) | undefined | Element to receive focus when the dialog is closed |
| `restoreFocus` | boolean | undefined | Whether to restore focus to the element that had focus before the dialog was opened |
| `closeOnInteractOutside` | boolean | undefined | Whether to close the dialog when the outside is clicked Default: true |
| `closeOnEscape` | boolean | undefined | Whether to close the dialog when the escape key is pressed Default: true |
| `open` | boolean | undefined | The controlled open state of the dialog |
| `defaultOpen` | boolean | undefined | The initial open state of the dialog when rendered. Use when you don't need to control the open state of the dialog. Default: false |
| `onOpenChange` | ((details: OpenChangeDetails) => void) | undefined | Function to call when the dialog's open state changes |
| `getRootNode` | (() => Node | ShadowRoot | Document) | undefined | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. |
| `onEscapeKeyDown` | ((event: KeyboardEvent) => void) | undefined | Function called when the escape key is pressed |
| `onRequestDismiss` | ((event: LayerDismissEvent) => void) | undefined | Function called when this layer is closed due to a parent layer being closed |
| `onPointerDownOutside` | ((event: PointerDownOutsideEvent) => void) | undefined | Function called when the pointer is pressed down outside the component |
| `onFocusOutside` | ((event: FocusOutsideEvent) => void) | undefined | Function called when the focus is moved outside the component |
| `onInteractOutside` | ((event: InteractOutsideEvent) => void) | undefined | Function called when an interaction happens outside the component |
| `persistentElements` | (() => Element | null)[] | undefined | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event |
| `children` | Snippet<[]> | undefined | The default slot content to be rendered within the component. |
### DialogRootProvider
| Property | Type | Description |
| --- | --- | --- |
| `value`* | () => DialogApi | |
| `children` | Snippet<[]> | undefined | The default slot content to be rendered within the component. |
### DialogRootContext
| Property | Type | Description |
| --- | --- | --- |
| `children`* | Snippet<[() => DialogApi]> | |
### DialogTrigger
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"button">]> | undefined | Render the element yourself |
### DialogBackdrop
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### DialogPositioner
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### DialogContent
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### DialogTitle
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### DialogDescription
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### DialogCloseTrigger
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"button">]> | undefined | Render the element yourself |
---
# File Upload
A component for uploading files with drag-and-drop and browse support.
```svelte
Label
Browse Files
{#snippet children(fileUpload)}
{#each fileUpload().acceptedFiles as file (file.name)}
{file.name}
{file.size} bytes
{/each}
{/snippet}
```
## Custom Content
Supply your own text and icons within the dropzone.
```svelte
Select file or drag here.
Browse Files
{#snippet children(fileUpload)}
{#each fileUpload().acceptedFiles as file (file.name)}
{file.name}
{file.size} bytes
{/each}
{/snippet}
```
## Disabled
```svelte
Browse Files
{#snippet children(fileUpload)}
{#each fileUpload().acceptedFiles as file (file.name)}
{file.name}
{file.size} bytes
{/each}
{/snippet}
```
## Button Only
```svelte
Browse Files
```
## Clear Files
Use the `Provider` pattern to access the `clearFiles` method.
```svelte
Browse Files
{#snippet children(fileUpload)}
{#each fileUpload().acceptedFiles as file (file.name)}
{file.name}
{file.size} bytes
{/each}
{/snippet}
fileUpload().clearFiles()}>Clear Files
```
## Direction
```svelte
Label
Browse Files
{#snippet children(fileUpload)}
{#each fileUpload().acceptedFiles as file (file.name)}
{file.name}
{file.size} bytes
{/each}
{/snippet}
```
## API Reference
### FileUploadRoot
| Property | Type | Description |
| --- | --- | --- |
| `name` | string | undefined | The name of the underlying file input |
| `ids` | Partial<{ root: string; dropzone: string; hiddenInput: string; trigger: string; label: string; item: (id: string) => string; itemName: (id: string) => string; itemSizeText: (id: string) => string; itemPreview: (id: string) => string; }> | undefined | The ids of the elements. Useful for composition. |
| `translations` | IntlTranslations | undefined | The localized messages to use. |
| `accept` | Record | FileMimeType | FileMimeType[] | undefined | The accept file types |
| `disabled` | boolean | undefined | Whether the file input is disabled |
| `required` | boolean | undefined | Whether the file input is required |
| `allowDrop` | boolean | undefined | Whether to allow drag and drop in the dropzone element Default: true |
| `maxFileSize` | number | undefined | The maximum file size in bytes Default: Infinity |
| `minFileSize` | number | undefined | The minimum file size in bytes Default: 0 |
| `maxFiles` | number | undefined | The maximum number of files Default: 1 |
| `preventDocumentDrop` | boolean | undefined | Whether to prevent the drop event on the document Default: true |
| `validate` | ((file: File, details: FileValidateDetails) => FileError[] | null) | undefined | Function to validate a file |
| `defaultAcceptedFiles` | File[] | undefined | The default accepted files when rendered. Use when you don't need to control the accepted files of the input. |
| `acceptedFiles` | File[] | undefined | The controlled accepted files |
| `onFileChange` | ((details: FileChangeDetails) => void) | undefined | Function called when the value changes, whether accepted or rejected |
| `onFileAccept` | ((details: FileAcceptDetails) => void) | undefined | Function called when the file is accepted |
| `onFileReject` | ((details: FileRejectDetails) => void) | undefined | Function called when the file is rejected |
| `capture` | "user" | "environment" | undefined | The default camera to use when capturing media |
| `directory` | boolean | undefined | Whether to accept directories, only works in webkit browsers |
| `invalid` | boolean | undefined | Whether the file input is invalid |
| `transformFiles` | ((files: File[]) => Promise) | undefined | Function to transform the accepted files to apply transformations |
| `locale` | string | undefined | The current locale. Based on the BCP 47 definition. Default: "en-US" |
| `dir` | "ltr" | "rtl" | undefined | The document's text/writing direction. Default: "ltr" |
| `getRootNode` | (() => ShadowRoot | Node | Document) | undefined | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### FileUploadRootProvider
| Property | Type | Description |
| --- | --- | --- |
| `value`* | () => FileUploadApi | |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### FileUploadRootContext
| Property | Type | Description |
| --- | --- | --- |
| `children`* | Snippet<[() => FileUploadApi]> | |
### FileUploadLabel
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"label">]> | undefined | Render the element yourself |
### FileUploadDropzone
| Property | Type | Description |
| --- | --- | --- |
| `disableClick` | boolean | undefined | Whether to disable the click event on the dropzone |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### FileUploadTrigger
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"button">]> | undefined | Render the element yourself |
### FileUploadHiddenInput
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"input">]> | undefined | Render the element yourself |
### FileUploadItemGroup
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"ul">]> | undefined | Render the element yourself |
### FileUploadItem
| Property | Type | Description |
| --- | --- | --- |
| `file`* | File | |
| `type` | ItemType | undefined | |
| `element` | Snippet<[HTMLAttributes<"li">]> | undefined | Render the element yourself |
### FileUploadItemName
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### FileUploadItemSizeText
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### FileUploadItemDeleteTrigger
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"button">]> | undefined | Render the element yourself |
---
# Navigation
A flexible navigation interface for large, medium, and small screens.
## Bar
```svelte
{#each links as link (link)}
{@const Icon = link.icon}
{link.label}
{/each}
```
- Recommended for small sized screens (ex: mobile).
- Ideal for vertical screen layouts.
- Should be fixed to the bottom of the viewport.
- Supports 3-5 tiles based on contents and viewport width.
- Consider progressive enhancement with the [Virtual Keyboard API](https://developer.mozilla.org/en-US/docs/Web/API/VirtualKeyboard_API).
## Rail
```svelte
{#each links as link (link)}
{@const Icon = link.icon}
{link.label}
{/each}
```
- Recommended for medium sized screens (ex: tablet).
- Ideal for horizontal screen layouts.
- Should be fixed to the left or right of the viewport.
- Supports 3-7 tiles based on contents and viewport height.
## Sidebar
```svelte
{#each Object.entries(linksSidebar) as [category, links]}
{category}
{#each links as link (link)}
{@const Icon = link.icon}
{/each}
{/each}
```
- Recommended for large sized screens (ex: desktop).
- Ideal for horizontal screen layouts.
- Should be fixed to the left or right of the viewport.
- Supports multiple groups of links for deep navigation.
- Supports a label field per each group.
- Can scroll vertically if contents extend beyond the viewport height.
## Toggle Layout
Using reactive state we can dynamically switch between multiple layouts. Tap the double arrow icon to toggle.
```svelte
{#each links as link (link)}
{@const Icon = link.icon}
{link.label}
{/each}
{#if !layoutRail}Resize {/if}
Layout: {layoutRail ? 'Rail' : 'Sidebar'}
```
## API Reference
### NavigationRoot
| Property | Type | Description |
| --- | --- | --- |
| `layout` | "bar" | "rail" | "sidebar" | undefined | Sets the data-layout attribute, which modifies the visual presentation of the component set. Default: bar |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### NavigationHeader
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"header">]> | undefined | Render the element yourself |
### NavigationContent
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### NavigationGroup
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### NavigationLabel
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### NavigationMenu
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### NavigationFooter
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"footer">]> | undefined | Render the element yourself |
---
# Pagination
Navigate between multiple pages of content.
```svelte
ID
Name
Email
Country
{#each data as user}
{user.id}
{user.name}
{user.email}
{user.country}
{/each}
(page = event.page)}>
{#snippet children(pagination)}
{#each pagination().pages as page, index (page)}
{#if page.type === 'page'}
{page.value}
{:else}
…
{/if}
{/each}
{/snippet}
```
## Page Size
```svelte
ID
Name
Email
Country
{#each data as user}
{user.id}
{user.name}
{user.email}
{user.country}
{/each}
Page Size
(pageSize = Number(e.currentTarget.value))}>
5
10
20
(page = event.page)}>
{#snippet children(pagination)}
{#each pagination().pages as page, index (page)}
{#if page.type === 'page'}
{page.value}
{:else}
…
{/if}
{/each}
{/snippet}
```
## Direction
```svelte
ID
Name
Email
Country
{#each data as user}
{user.id}
{user.name}
{user.email}
{user.country}
{/each}
(page = event.page)} dir="rtl">
{#snippet children(pagination)}
{#each pagination().pages as page, index (page)}
{#if page.type === 'page'}
{page.value}
{:else}
…
{/if}
{/each}
{/snippet}
```
## Total Count
For server-side pagination, your data source may be truncated. Make sure to specify the total records using `count`.
```json
{
"data": [...],
"pagination": {
"page": 1,
"limit": 10,
"count": 500,
}
}
```
```svelte
...
```
## API Reference
### PaginationRoot
| Property | Type | Description |
| --- | --- | --- |
| `ids` | Partial<{ root: string; ellipsis: (index: number) => string; prevTrigger: string; nextTrigger: string; item: (page: number) => string; }> | undefined | The ids of the elements in the accordion. Useful for composition. |
| `translations` | IntlTranslations | undefined | Specifies the localized strings that identifies the accessibility elements and their states |
| `count` | number | undefined | Total number of data items |
| `pageSize` | number | undefined | The controlled number of data items per page |
| `defaultPageSize` | number | undefined | The initial number of data items per page when rendered. Use when you don't need to control the page size of the pagination. Default: 10 |
| `siblingCount` | number | undefined | Number of pages to show beside active page Default: 1 |
| `page` | number | undefined | The controlled active page |
| `defaultPage` | number | undefined | The initial active page when rendered. Use when you don't need to control the active page of the pagination. Default: 1 |
| `onPageChange` | ((details: PageChangeDetails) => void) | undefined | Called when the page number is changed |
| `onPageSizeChange` | ((details: PageSizeChangeDetails) => void) | undefined | Called when the page size is changed |
| `type` | "button" | "link" | undefined | The type of the trigger element Default: "button" |
| `getPageUrl` | ((details: PageUrlDetails) => string) | undefined | Function to generate href attributes for pagination links. Only used when `type` is set to "link". |
| `dir` | "ltr" | "rtl" | undefined | The document's text/writing direction. Default: "ltr" |
| `getRootNode` | (() => ShadowRoot | Node | Document) | undefined | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### PaginationRootProvider
| Property | Type | Description |
| --- | --- | --- |
| `value`* | () => PaginationApi | |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### PaginationRootContext
| Property | Type | Description |
| --- | --- | --- |
| `children`* | Snippet<[() => PaginationApi]> | |
### PaginationPrevTrigger
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"button">]> | undefined | Render the element yourself |
### PaginationItem
| Property | Type | Description |
| --- | --- | --- |
| `type`* | "page" | |
| `value`* | number | |
| `element` | Snippet<[HTMLAttributes<"a">]> | undefined | Render the element yourself |
### PaginationEllipsis
| Property | Type | Description |
| --- | --- | --- |
| `index`* | number | |
| `element` | Snippet<[HTMLAttributes<"span">]> | undefined | Render the element yourself |
### PaginationNextTrigger
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"button">]> | undefined | Render the element yourself |
---
# Popover
A component that displays content in a floating panel, triggered by user interaction.
```svelte
Trigger
Example
This is a basic example of a popover.
Close
```
## Arrow
You may optionally enable arrows via the `Arrow` and `ArrowTip` component parts. Note that Zag.js opts to style these with CSS custom properties, which can be adjusted using a `style` attribute.
```svelte
Trigger
This example will have a small arrow.
```
## Z-Index
By default we do not take an opinionated stance regarding z-index stacking. The result is the component can sometimes be occluded beneath other elements with a higher index. The Z-Index can controlled by applying a utility class to the `Positioner` component part.
> NOTE: This will need to be forced using `!` for `!important` to override the Zag.js defaults.
```svelte
Default (auto)
This example will be below the sibling.
Above (20)
This example will be above the sibling.
```
## Programmatic Control
This is made possible via the Provider Pattern.
```svelte
Show for 3 seconds
Anchor
This popover will appear, stay open for three seconds, then close on it's own.
```
## Direction
```svelte
Trigger
Example
This is a basic example of a popover.
Close
```
## Headless
Unlike most components in Skeleton, this feature is provided "headless". This means no default styles are applied out of the box. This ensures you retain full control of all styling.
```svelte
Three spooky skeletons!
```
The benefits are as follows:
- You can make the `Trigger` surround any element, including an icon, button, image, etc.
- You can modify the entire structure within `Content`, including custom markup and styling.
- You may place the `CloseTrigger` anywhere, and use it as an X close option.
## API Reference
### PopoverRoot
| Property | Type | Description |
| --- | --- | --- |
| `dir` | "ltr" | "rtl" | undefined | The document's text/writing direction. Default: "ltr" |
| `ids` | Partial<{ anchor: string; trigger: string; content: string; title: string; description: string; closeTrigger: string; positioner: string; arrow: string; }> | undefined | The ids of the elements in the popover. Useful for composition. |
| `modal` | boolean | undefined | Whether the popover should be modal. When set to `true`: - interaction with outside elements will be disabled - only popover content will be visible to screen readers - scrolling is blocked - focus is trapped within the popover Default: false |
| `portalled` | boolean | undefined | Whether the popover is portalled. This will proxy the tabbing behavior regardless of the DOM position of the popover content. Default: true |
| `autoFocus` | boolean | undefined | Whether to automatically set focus on the first focusable content within the popover when opened. Default: true |
| `initialFocusEl` | (() => HTMLElement | null) | undefined | The element to focus on when the popover is opened. |
| `closeOnInteractOutside` | boolean | undefined | Whether to close the popover when the user clicks outside of the popover. Default: true |
| `closeOnEscape` | boolean | undefined | Whether to close the popover when the escape key is pressed. Default: true |
| `onOpenChange` | ((details: OpenChangeDetails) => void) | undefined | Function invoked when the popover opens or closes |
| `positioning` | PositioningOptions | undefined | The user provided options used to position the popover content |
| `open` | boolean | undefined | The controlled open state of the popover |
| `defaultOpen` | boolean | undefined | The initial open state of the popover when rendered. Use when you don't need to control the open state of the popover. |
| `getRootNode` | (() => Node | ShadowRoot | Document) | undefined | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. |
| `onEscapeKeyDown` | ((event: KeyboardEvent) => void) | undefined | Function called when the escape key is pressed |
| `onRequestDismiss` | ((event: LayerDismissEvent) => void) | undefined | Function called when this layer is closed due to a parent layer being closed |
| `onPointerDownOutside` | ((event: PointerDownOutsideEvent) => void) | undefined | Function called when the pointer is pressed down outside the component |
| `onFocusOutside` | ((event: FocusOutsideEvent) => void) | undefined | Function called when the focus is moved outside the component |
| `onInteractOutside` | ((event: InteractOutsideEvent) => void) | undefined | Function called when an interaction happens outside the component |
| `persistentElements` | (() => Element | null)[] | undefined | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event |
| `children` | Snippet<[]> | undefined | The default slot content to be rendered within the component. |
### PopoverRootProvider
| Property | Type | Description |
| --- | --- | --- |
| `value`* | () => PopoverApi | |
| `children` | Snippet<[]> | undefined | The default slot content to be rendered within the component. |
### PopoverRootContext
| Property | Type | Description |
| --- | --- | --- |
| `children`* | Snippet<[() => PopoverApi]> | |
### PopoverTrigger
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"button">]> | undefined | Render the element yourself |
### PopoverPositioner
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### PopoverContent
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### PopoverArrow
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### PopoverArrowTip
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### PopoverTitle
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### PopoverDescription
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### PopoverCloseTrigger
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"button">]> | undefined | Render the element yourself |
---
# Portal
Renders children into a DOM node that exists outside the DOM hierarchy.
```svelte
(disabled = !disabled)}>
{disabled ? 'Enable' : 'Disable'}
```
When enabled, the content will move from the source to the target element.
## API Reference
### PortalRoot
| Property | Type | Description |
| --- | --- | --- |
| `disabled` | boolean | undefined | If true, the portal functionality is disabled and children are rendered in place. Default: false |
| `target` | HTMLElement | undefined | The HTML element to which the portal content will be appended. Default: document.body |
| `children`* | Snippet<[]> | The default slot content to be rendered within the component. |
---
# Progress Circular
An indicator showing the progress or completion of a task.
```svelte
Label
(value = e.value[0])} step={10}>
```
## Size
```svelte
```
## Color
```svelte
```
## Centered Content
```svelte
```
## Indeterminate
Set the value to `null` to make the progress indeterminate.
```svelte
```
## Format
Use the `format` prop to customize the output of the `ValueText` component, options are:
- `percentage` (default) - shows the percentage value
- `decimal` - shows the decimal value (0.0 - 1.0)
- Provide formatting using the [Intl API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl)
```svelte
```
## Custom Value Text
```svelte
{#snippet children(progress)}
{progress().value} of {progress().max}
{/snippet}
```
## API Reference
---
# Progress Linear
An indicator showing the progress or completion of a task.
```svelte
{value}%
```
## Color
Provide background color values for the track and range to customize the colors.
```svelte
```
## Height
```svelte
```
## Orientation
For vertical orieintation, a height must be defined on the Track component. The default is `h-[100px]`.
```svelte
```
## Indeterminate
You must explicitely specify a `null` value to trigger indeterminate mode.
```svelte
```
### Custom Animation
```svelte
```
Consider using following variants to target the orientation and state.
- `data-[orientation=horizontal]:my-custom-animation` - target the horizontal orientation.
- `data-[orientation=vertical]:my-custom-animation` - target the vertical orientation.
- `data-[state=indeterminate]:my-custom-animation` - target the indeterminate state.
## Native Alternative
The native [`progress`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress) element is available cross browser, but does not support indeterminate animations.
```svelte
```
## Direction
```svelte
Label
```
## API Reference
---
# Rating Group
Rating Group allows users to rate something
```svelte
{#snippet children(ratingGroup)}
{#each ratingGroup().items as index (index)}
{/each}
{/snippet}
```
## Allow Half
```svelte
{#snippet children(ratingGroup)}
{#each ratingGroup().items as index (index)}
{/each}
{/snippet}
```
## Custom Icons
```svelte
{#snippet children(ratingGroup)}
{#each ratingGroup().items as index (index)}
{#snippet empty()}
{/snippet}
{#snippet full()}
{/snippet}
{/each}
{/snippet}
```
## Label
```svelte
Rate us:
{#snippet children(ratingGroup)}
{#each ratingGroup().items as index (index)}
{/each}
{/snippet}
```
## Disabled
```svelte
{#snippet children(ratingGroup)}
{#each ratingGroup().items as index (index)}
{/each}
{/snippet}
```
## Direction
```svelte
Label
{#snippet children(ratingGroup)}
{#each ratingGroup().items as index (index)}
{/each}
{/snippet}
```
## API Reference
### RatingGroupRoot
| Property | Type | Description |
| --- | --- | --- |
| `ids` | Partial<{ root: string; label: string; hiddenInput: string; control: string; item: (id: string) => string; }> | undefined | The ids of the elements in the rating. Useful for composition. |
| `translations` | IntlTranslations | undefined | Specifies the localized strings that identifies the accessibility elements and their states |
| `count` | number | undefined | The total number of ratings. Default: 5 |
| `name` | string | undefined | The name attribute of the rating element (used in forms). |
| `form` | string | undefined | The associate form of the underlying input element. |
| `value` | number | undefined | The controlled value of the rating |
| `defaultValue` | number | undefined | The initial value of the rating when rendered. Use when you don't need to control the value of the rating. |
| `readOnly` | boolean | undefined | Whether the rating is readonly. |
| `disabled` | boolean | undefined | Whether the rating is disabled. |
| `required` | boolean | undefined | Whether the rating is required. |
| `allowHalf` | boolean | undefined | Whether to allow half stars. |
| `autoFocus` | boolean | undefined | Whether to autofocus the rating. |
| `onValueChange` | ((details: ValueChangeDetails) => void) | undefined | Function to be called when the rating value changes. |
| `onHoverChange` | ((details: HoverChangeDetails) => void) | undefined | Function to be called when the rating value is hovered. |
| `dir` | "ltr" | "rtl" | undefined | The document's text/writing direction. Default: "ltr" |
| `getRootNode` | (() => ShadowRoot | Node | Document) | undefined | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### RatingGroupRootProvider
| Property | Type | Description |
| --- | --- | --- |
| `value`* | () => RatingGroupApi | |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### RatingGroupRootContext
| Property | Type | Description |
| --- | --- | --- |
| `children`* | Snippet<[() => RatingGroupApi]> | |
### RatingGroupLabel
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"label">]> | undefined | Render the element yourself |
### RatingGroupControl
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### RatingGroupItem
| Property | Type | Description |
| --- | --- | --- |
| `empty` | Snippet<[]> | undefined | The content to render when the item is in the empty state. Default: StarEmpty (SVG) |
| `half` | Snippet<[]> | undefined | The content to render when the item is in the half state. Default: StarHalf (SVG) |
| `full` | Snippet<[]> | undefined | The content to render when the item is in the full state. Default: StarFull (SVG) |
| `index`* | number | |
| `element` | Snippet<[HTMLAttributes<"span">]> | undefined | Render the element yourself |
### RatingGroupHiddenInput
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"input">]> | undefined | Render the element yourself |
---
# Segmented Control
Capture input for a limited set of options.
```svelte
Label
Item 1
Item 2
Item 3
```
## Icons
```svelte
```
## Orientation
```svelte
Item 1
Item 2
Item 3
```
## Read Only
```svelte
Item 1
Item 2
Item 3
```
## Disabled
```svelte
Item 1
Item 2
Item 3
```
## Disabled Item
```svelte
Item 1
Item 2
Item 3
```
## Direction
```svelte
Label
Item 1
Item 2
Item 3
```
## API Reference
### SegmentedControlRoot
| Property | Type | Description |
| --- | --- | --- |
| `ids` | Partial<{ root: string; label: string; indicator: string; item: (value: string) => string; itemLabel: (value: string) => string; itemControl: (value: string) => string; itemHiddenInput: (value: string) => string; }> | undefined | The ids of the elements in the radio. Useful for composition. |
| `value` | string | null | undefined | The controlled value of the radio group |
| `defaultValue` | string | null | undefined | The initial value of the checked radio when rendered. Use when you don't need to control the value of the radio group. |
| `name` | string | undefined | The name of the input fields in the radio (Useful for form submission). |
| `form` | string | undefined | The associate form of the underlying input. |
| `disabled` | boolean | undefined | If `true`, the radio group will be disabled |
| `readOnly` | boolean | undefined | Whether the checkbox is read-only |
| `onValueChange` | ((details: ValueChangeDetails) => void) | undefined | Function called once a radio is checked |
| `orientation` | "horizontal" | "vertical" | undefined | Orientation of the radio group |
| `dir` | "ltr" | "rtl" | undefined | The document's text/writing direction. Default: "ltr" |
| `getRootNode` | (() => ShadowRoot | Node | Document) | undefined | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### SegmentedControlRootProvider
| Property | Type | Description |
| --- | --- | --- |
| `value`* | () => RadioGroupApi | |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### SegmentedControlRootContext
| Property | Type | Description |
| --- | --- | --- |
| `children`* | Snippet<[() => RadioGroupApi]> | |
### SegmentedControlLabel
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"span">]> | undefined | Render the element yourself |
### SegmentedControlControl
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### SegmentedControlIndicator
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### SegmentedControlItem
| Property | Type | Description |
| --- | --- | --- |
| `value`* | string | |
| `disabled` | boolean | undefined | |
| `invalid` | boolean | undefined | |
| `element` | Snippet<[HTMLAttributes<"label">]> | undefined | Render the element yourself |
### SegmentedControlItemText
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"span">]> | undefined | Render the element yourself |
### SegmentedControlItemHiddenInput
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"input">]> | undefined | Render the element yourself |
---
# Slider
Capture input from a range of values.
```svelte
Label
```
## Color
```svelte
```
## Disabled
```svelte
```
## Readonly
```svelte
```
## Multiple Thumbs
```svelte
```
## Direction
```svelte
Label
```
## API Reference
### SliderRoot
| Property | Type | Description |
| --- | --- | --- |
| `ids` | Partial<{ root: string; thumb: (index: number) => string; hiddenInput: (index: number) => string; control: string; track: string; range: string; label: string; valueText: string; marker: (index: number) => string; }> | undefined | The ids of the elements in the slider. Useful for composition. |
| `aria-label` | string[] | undefined | The aria-label of each slider thumb. Useful for providing an accessible name to the slider |
| `aria-labelledby` | string[] | undefined | The `id` of the elements that labels each slider thumb. Useful for providing an accessible name to the slider |
| `name` | string | undefined | The name associated with each slider thumb (when used in a form) |
| `form` | string | undefined | The associate form of the underlying input element. |
| `value` | number[] | undefined | The controlled value of the slider |
| `defaultValue` | number[] | undefined | The initial value of the slider when rendered. Use when you don't need to control the value of the slider. |
| `disabled` | boolean | undefined | Whether the slider is disabled |
| `readOnly` | boolean | undefined | Whether the slider is read-only |
| `invalid` | boolean | undefined | Whether the slider is invalid |
| `onValueChange` | ((details: ValueChangeDetails) => void) | undefined | Function invoked when the value of the slider changes |
| `onValueChangeEnd` | ((details: ValueChangeDetails) => void) | undefined | Function invoked when the slider value change is done |
| `onFocusChange` | ((details: FocusChangeDetails) => void) | undefined | Function invoked when the slider's focused index changes |
| `getAriaValueText` | ((details: ValueTextDetails) => string) | undefined | Function that returns a human readable value for the slider thumb |
| `min` | number | undefined | The minimum value of the slider Default: 0 |
| `max` | number | undefined | The maximum value of the slider Default: 100 |
| `step` | number | undefined | The step value of the slider Default: 1 |
| `minStepsBetweenThumbs` | number | undefined | The minimum permitted steps between multiple thumbs. `minStepsBetweenThumbs` * `step` should reflect the gap between the thumbs. - `step: 1` and `minStepsBetweenThumbs: 10` => gap is `10` - `step: 10` and `minStepsBetweenThumbs: 2` => gap is `20` Default: 0 |
| `orientation` | "vertical" | "horizontal" | undefined | The orientation of the slider Default: "horizontal" |
| `origin` | "start" | "center" | "end" | undefined | The origin of the slider range. The track is filled from the origin to the thumb for single values. - "start": Useful when the value represents an absolute value - "center": Useful when the value represents an offset (relative) - "end": Useful when the value represents an offset from the end Default: "start" |
| `thumbAlignment` | "center" | "contain" | undefined | The alignment of the slider thumb relative to the track - `center`: the thumb will extend beyond the bounds of the slider track. - `contain`: the thumb will be contained within the bounds of the track. Default: "contain" |
| `thumbSize` | { width: number; height: number; } | undefined | The slider thumbs dimensions |
| `dir` | "ltr" | "rtl" | undefined | The document's text/writing direction. Default: "ltr" |
| `getRootNode` | (() => ShadowRoot | Node | Document) | undefined | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### SliderRootProvider
| Property | Type | Description |
| --- | --- | --- |
| `value`* | () => SliderApi | |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### SliderRootContext
| Property | Type | Description |
| --- | --- | --- |
| `children`* | Snippet<[() => SliderApi]> | |
### SliderLabel
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"label">]> | undefined | Render the element yourself |
### SliderValueText
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"output">]> | undefined | Render the element yourself |
### SliderControl
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### SliderTrack
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### SliderRange
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### SliderThumb
| Property | Type | Description |
| --- | --- | --- |
| `index`* | number | |
| `name` | string | undefined | |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### SliderHiddenInput
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"input">]> | undefined | Render the element yourself |
### SliderMarkerGroup
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### SliderMarker
| Property | Type | Description |
| --- | --- | --- |
| `value`* | number | |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
---
# Switch
Toggle between two states, such as on/off.
```svelte
Label
```
## List
```svelte
{#each ['Label 1', 'Label 2', 'Label 3'] as label, i (label)}
{label}
{#if i < 2}
{/if}
{/each}
```
## Icons
```svelte
{#snippet children(switch_)}
{#if switch_().checked}
{:else}
{/if}
{/snippet}
```
## Direction
```svelte
Label
```
## API Reference
### SwitchRoot
| Property | Type | Description |
| --- | --- | --- |
| `ids` | Partial<{ root: string; hiddenInput: string; control: string; label: string; thumb: string; }> | undefined | The ids of the elements in the switch. Useful for composition. |
| `label` | string | undefined | Specifies the localized strings that identifies the accessibility elements and their states |
| `disabled` | boolean | undefined | Whether the switch is disabled. |
| `invalid` | boolean | undefined | If `true`, the switch is marked as invalid. |
| `required` | boolean | undefined | If `true`, the switch input is marked as required, |
| `readOnly` | boolean | undefined | Whether the switch is read-only |
| `onCheckedChange` | ((details: CheckedChangeDetails) => void) | undefined | Function to call when the switch is clicked. |
| `checked` | boolean | undefined | The controlled checked state of the switch |
| `defaultChecked` | boolean | undefined | The initial checked state of the switch when rendered. Use when you don't need to control the checked state of the switch. |
| `name` | string | undefined | The name of the input field in a switch (Useful for form submission). |
| `form` | string | undefined | The id of the form that the switch belongs to |
| `value` | string | number | undefined | The value of switch input. Useful for form submission. Default: "on" |
| `dir` | "ltr" | "rtl" | undefined | The document's text/writing direction. Default: "ltr" |
| `getRootNode` | (() => ShadowRoot | Node | Document) | undefined | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. |
| `element` | Snippet<[HTMLAttributes<"label">]> | undefined | Render the element yourself |
### SwitchRootProvider
| Property | Type | Description |
| --- | --- | --- |
| `value`* | () => SwitchApi | |
| `element` | Snippet<[HTMLAttributes<"label">]> | undefined | Render the element yourself |
### SwitchRootContext
| Property | Type | Description |
| --- | --- | --- |
| `children`* | Snippet<[() => SwitchApi]> | |
### SwitchControl
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"span">]> | undefined | Render the element yourself |
### SwitchThumb
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"span">]> | undefined | Render the element yourself |
### SwitchLabel
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"span">]> | undefined | Render the element yourself |
### SwitchHiddenInput
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"input">]> | undefined | Render the element yourself |
---
# Tabs
Use tabs to quickly switch between different views and pages.
```svelte
Tab 1
Tab 2
Tab 3
Content for Tab 1
Content for Tab 2
Content for Tab 3
```
## Fluid Width
```svelte
Tab 1
Tab 2
Tab 3
Content for Tab 1
Content for Tab 2
Content for Tab 3
```
## Vertical
```svelte
Tab 1
Tab 2
Tab 3
Content for Tab 1
Content for Tab 2
Content for Tab 3
```
## Direction
```svelte
Tab 1
Tab 2
Tab 3
Content for Tab 1
Content for Tab 2
Content for Tab 3
```
## API Reference
### TabsRoot
| Property | Type | Description |
| --- | --- | --- |
| `ids` | Partial<{ root: string; trigger: (value: string) => string; list: string; content: (value: string) => string; indicator: string; }> | undefined | The ids of the elements in the tabs. Useful for composition. |
| `translations` | IntlTranslations | undefined | Specifies the localized strings that identifies the accessibility elements and their states |
| `loopFocus` | boolean | undefined | Whether the keyboard navigation will loop from last tab to first, and vice versa. Default: true |
| `value` | string | null | undefined | The controlled selected tab value |
| `defaultValue` | string | null | undefined | The initial selected tab value when rendered. Use when you don't need to control the selected tab value. |
| `orientation` | "horizontal" | "vertical" | undefined | The orientation of the tabs. Can be `horizontal` or `vertical` - `horizontal`: only left and right arrow key navigation will work. - `vertical`: only up and down arrow key navigation will work. Default: "horizontal" |
| `activationMode` | "manual" | "automatic" | undefined | The activation mode of the tabs. Can be `manual` or `automatic` - `manual`: Tabs are activated when clicked or press `enter` key. - `automatic`: Tabs are activated when receiving focus Default: "automatic" |
| `onValueChange` | ((details: ValueChangeDetails) => void) | undefined | Callback to be called when the selected/active tab changes |
| `onFocusChange` | ((details: FocusChangeDetails) => void) | undefined | Callback to be called when the focused tab changes |
| `composite` | boolean | undefined | Whether the tab is composite |
| `deselectable` | boolean | undefined | Whether the active tab can be deselected when clicking on it. |
| `navigate` | ((details: NavigateDetails) => void) | null | undefined | Function to navigate to the selected tab when clicking on it. Useful if tab triggers are anchor elements. |
| `dir` | "ltr" | "rtl" | undefined | The document's text/writing direction. Default: "ltr" |
| `getRootNode` | (() => ShadowRoot | Node | Document) | undefined | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### TabsRootProvider
| Property | Type | Description |
| --- | --- | --- |
| `value`* | () => TabsApi | |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### TabsRootContext
| Property | Type | Description |
| --- | --- | --- |
| `children`* | Snippet<[() => TabsApi]> | |
### TabsList
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### TabsTrigger
| Property | Type | Description |
| --- | --- | --- |
| `value`* | string | The value of the tab |
| `disabled` | boolean | undefined | Whether the tab is disabled |
| `element` | Snippet<[HTMLAttributes<"button">]> | undefined | Render the element yourself |
### TabsIndicator
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### TabsContent
| Property | Type | Description |
| --- | --- | --- |
| `value`* | string | The value of the tab |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
---
# Tags Input
Allows input of multiple values.
```svelte
Label
{#snippet children(tagsInput)}
{#each tagsInput().value as value, index (index)}
{value}
{/each}
{/snippet}
Clear All
```
## Custom Icon
```svelte
{#snippet children(tagsInput)}
{#each tagsInput().value as value, index (index)}
{value}
{/each}
{/snippet}
```
## Color
```svelte
{#snippet children(tagsInput)}
{#each tagsInput().value as value, index (index)}
{value}
{/each}
{/snippet}
```
## Direction
```svelte
Label
{#snippet children(tagsInput)}
{#each tagsInput().value as value, index (index)}
{value}
{/each}
{/snippet}
Clear All
```
## API Reference
### TagsInputRoot
| Property | Type | Description |
| --- | --- | --- |
| `ids` | Partial<{ root: string; input: string; hiddenInput: string; clearBtn: string; label: string; control: string; item: (opts: ItemProps) => string; itemDeleteTrigger: (opts: ItemProps) => string; itemInput: (opts: ItemProps) => string; }> | undefined | The ids of the elements in the tags input. Useful for composition. |
| `translations` | IntlTranslations | undefined | Specifies the localized strings that identifies the accessibility elements and their states |
| `maxLength` | number | undefined | The max length of the input. |
| `delimiter` | string | RegExp | undefined | The character that serves has: - event key to trigger the addition of a new tag - character used to split tags when pasting into the input Default: "," |
| `autoFocus` | boolean | undefined | Whether the input should be auto-focused |
| `disabled` | boolean | undefined | Whether the tags input should be disabled |
| `readOnly` | boolean | undefined | Whether the tags input should be read-only |
| `invalid` | boolean | undefined | Whether the tags input is invalid |
| `required` | boolean | undefined | Whether the tags input is required |
| `editable` | boolean | undefined | Whether a tag can be edited after creation, by pressing `Enter` or double clicking. Default: true |
| `inputValue` | string | undefined | The controlled tag input's value |
| `defaultInputValue` | string | undefined | The initial tag input value when rendered. Use when you don't need to control the tag input value. |
| `value` | string[] | undefined | The controlled tag value |
| `defaultValue` | string[] | undefined | The initial tag value when rendered. Use when you don't need to control the tag value. |
| `onValueChange` | ((details: ValueChangeDetails) => void) | undefined | Callback fired when the tag values is updated |
| `onInputValueChange` | ((details: InputValueChangeDetails) => void) | undefined | Callback fired when the input value is updated |
| `onHighlightChange` | ((details: HighlightChangeDetails) => void) | undefined | Callback fired when a tag is highlighted by pointer or keyboard navigation |
| `onValueInvalid` | ((details: ValidityChangeDetails) => void) | undefined | Callback fired when the max tag count is reached or the `validateTag` function returns `false` |
| `validate` | ((details: ValidateArgs) => boolean) | undefined | Returns a boolean that determines whether a tag can be added. Useful for preventing duplicates or invalid tag values. |
| `blurBehavior` | "clear" | "add" | undefined | The behavior of the tags input when the input is blurred - `"add"`: add the input value as a new tag - `"clear"`: clear the input value |
| `addOnPaste` | boolean | undefined | Whether to add a tag when you paste values into the tag input Default: false |
| `max` | number | undefined | The max number of tags Default: Infinity |
| `allowOverflow` | boolean | undefined | Whether to allow tags to exceed max. In this case, we'll attach `data-invalid` to the root |
| `name` | string | undefined | The name attribute for the input. Useful for form submissions |
| `form` | string | undefined | The associate form of the underlying input element. |
| `dir` | "ltr" | "rtl" | undefined | The document's text/writing direction. Default: "ltr" |
| `getRootNode` | (() => ShadowRoot | Node | Document) | undefined | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. |
| `onPointerDownOutside` | ((event: PointerDownOutsideEvent) => void) | undefined | Function called when the pointer is pressed down outside the component |
| `onFocusOutside` | ((event: FocusOutsideEvent) => void) | undefined | Function called when the focus is moved outside the component |
| `onInteractOutside` | ((event: InteractOutsideEvent) => void) | undefined | Function called when an interaction happens outside the component |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### TagsInputRootProvider
| Property | Type | Description |
| --- | --- | --- |
| `value`* | () => TagsInputApi | |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### TagsInputRootContext
| Property | Type | Description |
| --- | --- | --- |
| `children`* | Snippet<[() => TagsInputApi]> | |
### TagsInputLabel
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"label">]> | undefined | Render the element yourself |
### TagsInputControl
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### TagsInputItem
| Property | Type | Description |
| --- | --- | --- |
| `index`* | string | number | |
| `value`* | string | |
| `disabled` | boolean | undefined | |
| `element` | Snippet<[HTMLAttributes<"span">]> | undefined | Render the element yourself |
### TagsInputItemPreview
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### TagsInputItemText
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"span">]> | undefined | Render the element yourself |
### TagsInputItemDeleteTrigger
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"button">]> | undefined | Render the element yourself |
### TagsInputItemInput
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"input">]> | undefined | Render the element yourself |
### TagsInputInput
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"input">]> | undefined | Render the element yourself |
### TagsInputClearTrigger
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"button">]> | undefined | Render the element yourself |
### TagsInputHiddenInput
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"input">]> | undefined | Render the element yourself |
---
# Toast
Display brief messages to users.
```svelte
toaster.info({
title: 'Title',
description: 'This is a description.',
})}
>
Toast
{#snippet children(toast)}
{toast.title}
{toast.description}
{/snippet}
```
## Usage
This component can act as a Singleton - meaning you you only implement a single instance (typically at the root scope of your app) and then reused it over and over. To do this, implement the `` at the root scope of your app (for SvelteKit this would be your root `+layout.svelte`), and use a shared `createToaster()` instance to trigger messages to that group from anywhere in your application.
## Type
```svelte
toaster.info({
title: 'Info',
description: 'This is an info toast.',
})}
>
Info
toaster.success({
title: 'Success',
description: 'This is a success toast.',
})}
>
Success
toaster.warning({
title: 'Warning',
description: 'This is a warning toast.',
})}
>
Warning
toaster.error({
title: 'Error',
description: 'This is an error toast.',
})}
>
Error
{#snippet children(toast)}
{toast.title}
{toast.description}
{/snippet}
```
Types can be specified in one of two ways:
- Via a trigger method: `toaster.{info|success|warning|error}()`
- Via the object key: `type: {info|success|warning|error}`
## Action
Include an optional action button.
```svelte
toaster.info({
title: 'Toast',
description: 'This is a toast message.',
duration: Infinity,
action: {
label: 'Undo',
onClick: () => {
toaster.success({
title: 'Task undone',
description: 'The task has been undone.',
});
},
},
})}
>
Toast
{#snippet children(toast)}
{toast.title}
{toast.description}
{#if toast.action}
{toast.action.label}
{/if}
{/snippet}
```
## Closable
By passing `closable: false` you can disable the close button.
```svelte
toaster.info({
title: 'Title',
description: 'This is a description.',
closable: false,
})}
>
Toast
{#snippet children(toast)}
{toast.title}
{toast.description}
{#if toast.closable}
{/if}
{/snippet}
```
## Placement
```svelte
toaster.info({
title: 'Title',
description: 'This is a description.',
})}
>
Toast
{#snippet children(toast)}
{toast.title}
{toast.description}
{/snippet}
```
## Meta
Use the `meta` key to provide arbitrary data. Then use this to modify your Toast template.
```svelte
{#snippet skull()}
{/snippet}
toaster.info({
title: 'Title',
description: 'This is a description.',
meta: {
icon: skull,
},
})}
>
Toast
{#snippet children(toast)}
{@render toast.meta!.icon()}
{toast.title}
{toast.description} {toast.meta?.foo}
{/snippet}
```
## Promise
```svelte
toaster.promise(generatePositiveNumber(), {
loading: {
title: 'Loading...',
description: 'Please wait while generating your number',
},
success: (number) => ({
title: 'Success',
description: `Your number is ${number}`,
}),
error: (number) => ({
title: 'Error',
description: `Your number is ${number}`,
}),
})}
>
Toast
{#snippet children(toast)}
{toast.title}
{toast.description}
{/snippet}
```
## API Reference
### ToastRoot
| Property | Type | Description |
| --- | --- | --- |
| `toast`* | Options | |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### ToastRootContext
| Property | Type | Description |
| --- | --- | --- |
| `children`* | Snippet<[() => ToastApi]> | |
### ToastGroup
| Property | Type | Description |
| --- | --- | --- |
| `toaster`* | ToastStore | |
| `children` | Snippet<[ToastProps]> | undefined | |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### ToastMessage
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### ToastTitle
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### ToastDescription
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### ToastActionTrigger
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"button">]> | undefined | Render the element yourself |
### ToastCloseTrigger
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"button">]> | undefined | Render the element yourself |
---
# Tooltip
A floating label that appears on hover or focus, providing additional context.
```svelte
Hover Me
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Sapiente magni distinctio explicabo quisquam. Rerum impedit culpa nesciunt
enim.
```
## Arrow
You may optionally enable arrows via the `Arrow` and `ArrowTip` component parts. Note that Zag.js opts to style these with CSS custom properties, which can be adjusted using a `style` attribute.
```svelte
Hover Me
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Sapiente magni distinctio explicabo quisquam. Rerum impedit culpa nesciunt
enim.
```
## Z-Index
By default we do not take an opinionated stance regarding z-index stacking. The result is the component can sometimes be occluded beneath other elements with a higher index. The Z-Index can controlled by applying a utility class to the `Positioner` component part.
```svelte
Default (auto)
This example will be below the sibling.
Above (20)
This example will be above the sibling.
```
## Programmatic Control
This is made possible via the Provider Pattern.
```svelte
tooltip().setOpen(!tooltip().open)}>Trigger
Anchor ({tooltip().open ? 'open' : 'closed'})
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Sapiente magni distinctio explicabo quisquam. Rerum impedit culpa
nesciunt enim.
```
## Direction
```svelte
Hover Me
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Sapiente magni distinctio explicabo quisquam. Rerum impedit culpa nesciunt
enim.
```
## Headless
Unlike most components in Skeleton, this feature is provided "headless". This means no default styles are applied out of the box. This ensures you retain full control of all styling.
```svelte
Hover Me
Three spooky skeletons!
```
The benefits are as follows:
- You can make the `Trigger` surround any element, including an icon, button, image, etc.
- You can modify the entire structure within `Content`, including custom markup and styling.
- You may place the `CloseTrigger` anywhere, and use it as an X close option.
## API Reference
### TooltipRoot
| Property | Type | Description |
| --- | --- | --- |
| `dir` | "ltr" | "rtl" | undefined | The document's text/writing direction. Default: "ltr" |
| `aria-label` | string | undefined | Custom label for the tooltip. |
| `ids` | Partial<{ trigger: string; content: string; arrow: string; positioner: string; }> | undefined | The ids of the elements in the tooltip. Useful for composition. |
| `openDelay` | number | undefined | The open delay of the tooltip. Default: 400 |
| `closeDelay` | number | undefined | The close delay of the tooltip. Default: 150 |
| `closeOnPointerDown` | boolean | undefined | Whether to close the tooltip on pointerdown. Default: true |
| `closeOnEscape` | boolean | undefined | Whether to close the tooltip when the Escape key is pressed. Default: true |
| `closeOnScroll` | boolean | undefined | Whether the tooltip should close on scroll Default: true |
| `closeOnClick` | boolean | undefined | Whether the tooltip should close on click Default: true |
| `interactive` | boolean | undefined | Whether the tooltip's content is interactive. In this mode, the tooltip will remain open when user hovers over the content. Default: false |
| `onOpenChange` | ((details: OpenChangeDetails) => void) | undefined | Function called when the tooltip is opened. |
| `positioning` | PositioningOptions | undefined | The user provided options used to position the popover content |
| `disabled` | boolean | undefined | Whether the tooltip is disabled |
| `open` | boolean | undefined | The controlled open state of the tooltip |
| `defaultOpen` | boolean | undefined | The initial open state of the tooltip when rendered. Use when you don't need to control the open state of the tooltip. |
| `getRootNode` | (() => Node | ShadowRoot | Document) | undefined | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. |
| `children` | Snippet<[]> | undefined | The default slot content to be rendered within the component. |
### TooltipRootProvider
| Property | Type | Description |
| --- | --- | --- |
| `value`* | () => TooltipApi | |
| `children` | Snippet<[]> | undefined | The default slot content to be rendered within the component. |
### TooltipRootContext
| Property | Type | Description |
| --- | --- | --- |
| `children`* | Snippet<[() => TooltipApi]> | |
### TooltipTrigger
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"button">]> | undefined | Render the element yourself |
### TooltipPositioner
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### TooltipContent
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### TooltipArrow
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
### TooltipArrowTip
| Property | Type | Description |
| --- | --- | --- |
| `element` | Snippet<[HTMLAttributes<"div">]> | undefined | Render the element yourself |
---
# Integrations
# Code Block
Learn how to integrate Shiki, a beautiful yet powerful syntax highlighter.
Shiki (式, a Japanese word for "Style") is a beautiful and powerful syntax highlighter based on TextMate grammar and themes, the same
engine as VS Code's syntax highlighting. It provides accurate and fast syntax highlighting for almost any mainstream programming language.
Shiki Documentation →
## Installation
[Install Shiki](https://shiki.style/guide/install) with your preferred package manager.
```console
npm install -D shiki
```
## Create a Component
A reusable component should suffice in most projects. Tap the `code` tab below to access the source, then follow the steps below.
1. Implement a new `` component in `/src/lib/components/CodeBlock/CodeBlock.svelte`.
2. Implement the required component prop types in `/src/lib/components/CodeBlock/types.ts`.
3. Implement several variations of our `` component in any SvelteKit route `+page.svelte`.
```svelte
{@html generatedHtml}
```
A few things of note about this component:
- You will need to import and configure any number of [Shiki themes](https://shiki.style/themes).
- You will need to import and configure any number of [supported languages](https://shiki.style/languages).
- The component has been implemented using Skeleton's [component style guidelines](http://localhost:4321/docs/resources/contribute/components).
- This provides a number of style props for easy customization via Skeleton's standard conventions.
- The component exposes `code`, `lang`, and `theme` properties to configure on-the-fly.
- The Code Block `` tag is auto-generated by Shiki; target utility classes with: `[&>pre]:myClassHere`.
## Programmatic Usage
This use case falls outside the scope of Skeleton. The following is provided merely as guidance.
In some cases you may not have direct access to the source code, such as content from a blog posts or CMS pages. In fact the code may even come pre-baked with surrounding `` or `` elements. For this, you'll need to follow the general steps below. Specific implementation may differ based on your app and meta-framework.
1. Query all `` or `` blocks using Javascript tools like `document.querySelectorAll()`. Be as specific as possible.
2. Ensure you have a clean instance of the source code itself, with no extra markup injected within.
3. Use Shiki's [codeToHtml](https://shiki.style/guide/install#shorthands) feature to parse the code as styled HTML markup.
4. Then append each instance of the code blocks in your DOM.
For more instructions, please refer to this guide by [Joy of Code](https://joyofcode.xyz/) explaining how to [implement Shiki via MDX](https://joyofcode.xyz/sveltekit-markdown-blog#using-components-inside-markdown).
## Custom Themes
Shiki provides support for generating a custom highlighter theme:
- [Loading Custom Themes](https://shiki.style/guide/load-theme)
- [List of Bundled Themes](https://shiki.style/themes)
Shiki theme values can be defined using Skeleton custom theme properties, such as `rgba(--color-primary-500)`.
## Accessibility
See [Salma Alam-Naylor's](https://whitep4nth3r.com/about/) guidelines for [creating accessible code blocks](https://whitep4nth3r.com/blog/how-to-make-your-code-blocks-accessible-on-your-website/) that meet WGAC standards.
---
# Iconography
Learn how to integrate Lucide for iconography in Skeleton.
Skeleton takes an agnostic approach to icons, meaning you can use any combination of SVGs, emoji, unicode, or dedicated icon libraries.
Mix and match to fulfill your project's unique requirements.
## Lucide
If you're looking for an opinionated solution, Skeleton recommends [Lucide](https://lucide.dev/). This provides a huge selection of icons that are available to all popular frameworks and feature a clean and modern style. All code examples in this documentation site implement Lucide, but feel free to replace with any alternative.
### Installation
Follow the official instructions to install [Lucide for Svelte](https://lucide.dev/guide/packages/lucide-svelte).
## Usage
For optimal performance we recommend importing each icon using the full path.
```svelte
```
## Alternatives
- [Iconify](https://iconify.design/) - provides a vast array of icon sets supported by popular icon libraries.
- [Font Awesome](https://fontawesome.com/) - provides a huge variety of icons in their free tier.
- [SimpleIcons](https://simpleicons.org/) - provides an excellent selection of brand icons.
---