This document contains the full documentation.

It starts with an index of all pages, followed by the complete content of each page below.

---

---
title: "Getting Started · Silk"
description: "Learn how to install and set up Silk in your React project."
Source: https://silkhq.com/docs/getting-started.md
---

Note that commercial use of Silk requires a commercial license. More information [here](https://silkhq.com/access).

## Install the package

To get started with Silk, install its npm package using your terminal.

```bash
npm install @silk-hq/components
```

## Import the styles

Silk makes use of low-level styles that must be imported into your project.

For convenience and flexibility, these styles are available in two versions: unlayered and layered. The layered version wraps Silk’s default styles into a CSS `@layer {}`.

### Basic

In a project that doesn’t make use of CSS layers, it is best to use the unlayered version. You can import it in different ways:

#### Import into a CSS file

You can import the styles directly into your global CSS file.

```css
/* ./global.css */

@import "@silk-hq/components/unlayered-styles.css";
```

#### Import into a JavaScript file

You can also import the styles in a JavaScript or TypeScript file at the root of your project.

```tsx
// ./index.tsx

import "@silk-hq/components/unlayered-styles.css";
```

### In a project using CSS layers (e.g. Tailwind V4)

In a project that makes use of CSS layers (e.g. using Tailwind V4), you can use both the unlayered and the layered version. In any case, Silk’s layer declaration must occur before that of your normal styles. You can import it in different ways:

#### Import into a CSS file

- You can import the **unlayered styles** into a layer directly into your global CSS, before your normal styles.

```css
/* ./global.css */

@import "@silk-hq/components/unlayered-styles.css" layer(silk);
/* @import "tailwindcss"; */
```

<aside>

**Important note**: Some frameworks (e.g. Next.js, TanStack Start) have bugs surrounding layered imports. After installation, please check that Silk’s styles are indeed imported within a layer. If your framework fails to properly layer the styles, import layered styles directly, as explained below.

</aside>

- Or you can import the **layered styles** directly into your global CSS, before your normal styles. This is useful for framework that have issues with CSS layered imports (e.g. Next.js).

```css
/* ./global.css */

@import "@silk-hq/components/layered-styles.css";
/* @import "tailwindcss"; */
```

#### Import into a JavaScript file

You can also import the layered styles in a JavaScript or TypeScript file at the root of your project, before importing any normal styles.

```tsx
/* ./index.tsx */

import "@silk-hq/components/layered-styles.css";
```

## Import and use the components

You can now import the components that you want to use anywhere in your code.

Creating a bottom sheet component:

```tsx
// BottomSheet.tsx

import { Sheet } from "@silk-hq/components";
import "./BottomSheet.css";

const BottomSheet = () => (
  <Sheet.Root license="commercial">
    <Sheet.Trigger>Open</Sheet.Trigger>
    <Sheet.Portal>
      <Sheet.View className="BottomSheet-view" nativeEdgeSwipePrevention={true}>
        <Sheet.Backdrop themeColorDimming="auto" />
        <Sheet.Content className="BottomSheet-content">
          <Sheet.BleedingBackground className="BottomSheet-bleedingBackground" />
          Some content
        </Sheet.Content>
      </Sheet.View>
    </Sheet.Portal>
  </Sheet.Root>
);

export { BottomSheet };
```

```css
/* BottomSheet.css */

.BottomSheet-view {
  height: var(--silk-100-lvh-dvh-pct);
}

.BottomSheet-content {
  box-sizing: border-box;
  max-width: 700px;
  padding-block: 25vh;
  text-align: center;
}

.BottomSheet-bleedingBackground {
  border-radius: 24px;
  background-color: white;
  box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
}
```

Using the bottom sheet:

```tsx
// Home.tsx

import { BottomSheet } from "./BottomSheet/BottomSheet";

export default function Home() {
	return (
		<BottomSheet />
	);
}
```

This is what you should see:

![Frame 438753.png](https://silkhq.com/docs-images/getting-started/Frame_438753.png)

Next, check the [examples](https://silkhq.com/docs/examples.md) for a wide variety of usage examples.

<aside>

**Enjoying Silk?** Spread the word on social media! It helps a lot.

</aside>

---

---
title: "Examples · Silk"
description: "Explore usage examples for Silk components."
Source: https://silkhq.com/docs/examples.md
---

## Basic examples

Find all 12 basic examples in the [dedicated GitHub directory](https://github.com/silk-hq/silk/tree/main/examples) in the Silk repository.

See them in action in the [CodeSandbox](https://codesandbox.io/p/sandbox/github/silk-hq/silk/tree/main/examples/css).

## Advanced examples

4 advanced examples are made available upon purchase of a Commercial License:

- [SheetWithDepth](https://silkhq.com/#example-sheet-with-depth-h1)
- PersistentSheetWithDetent
- [LightBox](https://silkhq.com/#example-lightbox)
- [ParallaxPage](https://silkhq.com/#example-parallax-page-h1)

<aside>

**Enjoying Silk?** Spread the word on social media! It helps a lot.

</aside>

---

---
title: "Styling · Silk"
description: "Learn how to style Silk components using className, style props, and CSS custom properties."
Source: https://silkhq.com/docs/styling.md
---

## Normal Styling

Silk components underlying elements can be styled using any method you wish.

You can pass a `className`, `style` or any other attribute to all sub-components with underlying elements to assign CSS styles to them.

## Default styles

Some components underlying elements come with very basic default styles. They are likely to match your needs and provide a useful base at the beginning of the development. They can be fully overridden.

- Defaults styles are identifiable by their declaration: they make use of the `css:--silk-defaults` custom property (e.g. `css:background-color: var(--silk-defaults, #fafafa);`).
- Defaults styles can be individually overridden with a selector of any specificity.
- To remove all defaults styles for one element, set `css:--silk-defaults: silk-reset;` on this element.

## Required styles

Most components underlying elements have required styles, already set for you. Those are necessary for the proper functioning of the components. They must not be overridden in any case.

- Required styles are identifiable by their declaration: they use the `css:!important` marker.
- Sometimes, a `css:--NOTE` is also present to provide further informations on specific CSS properties.

## Custom properties

### `css:--silk-100-lvh-dvh-pct`

##### Description

In iOS SFSafariViewController (i.e. iOS standard in-app browser) the CSS `css:vh` and `css:lvh` units wrongly reflect the same size as the `css:svh` unit. See [https://bugs.webkit.org/show_bug.cgi?id=255708](https://bugs.webkit.org/show_bug.cgi?id=255708).

As a consequence, when using either of these units, we end up with a size which is shorter than expected. In particular, it is often desirable to set the `css:height` CSS property of `<Scroll.View />` underlying element to `css:100lvh` or `css:calc(100lvh + 60px)` so that `<Scroll.Content />` underlying element overflows the layout viewport, and does not resize when the user expands or collapses manually iOS Safari's UI. It is also useful so it appears below iOS Safari's semi-transparent UI.

To address this issue, we expose globally the `css:--silk-100-lvh-dvh-pct` CSS custom property, which provides the best compromise to work around the iOS SFSafariViewController bug.

Normally, this CSS custom property returns `100lvh` (or `100vh` if the `lvh` unit is not supported). However, if `css:100lvh` happens to be smaller than `css:100dvh` (or `css:100%` if `css:dvh` is not supported), which can only happen when the bug is present, it falls back to `css:100dvh` (or `css:100%` if `css:dvh` is not supported).

That way, in a normal situation we get the desired `css:100lvh` value, and if the bug is present, we get `css:100dvh`, which fills the viewport and is subject to resize, but will not cause the view to be improperly sized to `css:100svh` as it would without this fallback, due to the bug.

##### Underlying value

```css
:root {
    --silk-100-lvh-dvh-pct: max(100%, 100vh);
}
@supports (width: 1dvh) {
    :root {
        --silk-100-lvh-dvh-pct: max(100dvh, 100lvh);
    }
}
```

##### Example

```css
.MySheet_view {
	height: var(--silk-100-lvh-dvh-pct);
}
```

---

---
title: "Composition · Silk"
description: "Understand how to compose Silk components with your own UI."
Source: https://silkhq.com/docs/composition.md
---

Silk components are made up of several sub-components, most of which render one or several underlying elements. Silk allows to easily substitute those underlying elements with your own elements or React components.

## asChild

The `asChild` prop is available on all sub-components rendering an underlying elements.

When it is present (i.e. set to `true`) the sub-component expects exactly one child (with any number of descendants). It can be either an element, or a React component rendering one element, and will be used in lieu of the default underlying element.

When in use, the element normally rendered by the sub-component will not be rendered. Instead, the element received as child will be used, and it will automatically receive the HTML attributes required for the proper functioning of the Silk sub-component.

### Usage with an element

When used with an element, all you need to do is set the `asChild` prop on the Silk sub-component, and pass the element as child of this sub-component.

```tsx
<Sheet.Trigger asChild>
	<a href="/my-page">Open the sheet</a>
</Sheet.Trigger>
```

### Usage with a React component

When used with a React component, the process is similar, but it requires an additional step. First, you need the React component to accept props and spread them onto the underlying element.

```tsx
// MyButton.tsx

const MyButton = (props) => <button {...props} />;
```

- **Usage with React 18 or earlier**
  If you’re using React 18 or earlier, the React component must also accept a ref that you also have to pass to the underlying element, as well as use forwardRef so your component properly forwards the ref.

   ```tsx
   // MyButton.tsx

   const MyButton = React.forwardRef((props, forwardedRef) =>
   	<button ref={forwardedRef} {...props} />
   );
   ```

   **Note:** Read more about React.forwardRef in [React’s documentation](https://react.dev/reference/react/forwardRef).

Then, you can to set the `asChild` prop on the Silk sub-component, and pass the React component as child of this sub-component.

```tsx
// Usage

<Sheet.Trigger asChild>
	<MyButton>Open the sheet</MyButton>
</Sheet.Trigger>
```

#### Nested asChild

It is possible to nest several Silk sub-components using `asChild`, as long as it ends up containing a single element that will receive the props and refs of all the nested sub-components.

```tsx
// Sheet.Content, Scroll.Root and Scroll.View will only render one element

<Sheet.Root>
   <Sheet.View>
      <Sheet.Content asChild>
         <Scroll.Root asChild>
            <Scroll.View>
               <Scroll.Content>
                  ...
               </Scroll.Content>
            </Scroll.View>
         </Scroll.Root>
      </Sheet.Content>
   </Sheet.View>
</Sheet.Root>
```

### Acknowledgment

Silk `asChild` prop is similar to [Radix’s](https://www.radix-ui.com/primitives/docs/composition) and uses most of the same code. We thank the Radix team for introducing this pattern to the React ecosystem.

---

---
title: "Controlled Sheet · Silk"
description: "Guide to building a controlled sheet with Silk."
Source: https://silkhq.com/docs/controlled-sheet.md
---

Silk’s components are designed to be used declaratively first, ensuring ease of use and automatic accessibility handling. If you want your Sheet component to react to button clicks, we recommend you do it with the `<Sheet.Trigger>` sub-component.

Sometimes you do need to control your sheet programmatically though, like when responding to an async operation, a URL change, or simply a different event than the `<Sheet.Trigger>` `press` event. For such scenarios, Silk allows you to use a Sheet as a controlled component.

A Sheet has two pairs of props allowing you to control internal state: the `presented` and `onPresentedChange` props, and the `activeDetent` and `onActiveDetentChange` props.

## The `presented` and `onPresentedChange` props

This pair of props allows you to present and dismiss a Sheet programmatically.

When setting `presented` to `true`, it will present the sheet, when setting it to `false`, it will dismiss it. You also need to pass a function allowing to update the value to `onPresentedChange`, so it can be updated by the component itself as a result of a user interactions—like dismissing the Sheet with a swipe, or pressing the escape key.

```tsx
import { useState } from "react";
import { Sheet } from "@silk-hq/components";

export default function ControlledSheet() {
  const [presented, setPresented] = useState(false);

  useEffect(() => {
    const timer = setTimeout(() => {
      setPresented(true);
    }, 3000); // Presents the Sheet after 3 seconds

    return () => clearTimeout(timer);
  }, []);

  return (
    <Sheet.Root presented={presented} onPresentedChange={setPresented}>
      <Sheet.Portal>
        <Sheet.View>
          <Sheet.Backdrop />
          <Sheet.Content>
            <Sheet.Title>Controlled Sheet</Sheet.Title>
            <Sheet.Description>This Sheet is controlled by state.</Sheet.Description>
          </Sheet.Content>
        </Sheet.View>
      </Sheet.Portal>
    </Sheet.Root>
  );
}
```

These props come with some limitations at the moment. Read more about the `presented` and `onPresentedChange` props on the [Sheet documentation page](https://silkhq.com/docs/sheet.md).

## The `activeDetent` and `onActiveDetent` props

This pair of props allows you to set the index of the detent the Sheet rests on programmatically.

Detent are numbered from `0` to `n`, where `0` is the index of the detent the Sheet is resting on when it is fully outside of the view, and `n` the index of the detent the Sheet is resting on when it is fully expanded inside of the view. When you add one intermediary detent to your sheet using the [`detents`](https://silkhq.com/docs/sheet.md) prop on the `<Sheet.View>` sub-component, this detent has the index `1`, and the last detent the index `2`.

When setting the value of `activeDetent` to the index of a detent, the Sheet will step to that detent, and rest on it. You also need to pass a function allowing to update the value to `onActiveDetent`, so it can be updated by the component itself as a result of a user interaction—like a swipe, or using a `<Sheet.Trigger>`.

```tsx
import { useState } from "react";
import { Sheet } from "@silk-hq/components";

export default function ControlledDetentSheet() {
  const [activeDetent, setActiveDetent] = useState(1);

  useEffect(() => {
    const timer = setTimeout(() => {
      setActiveDetent(2);
    }, 3000); // Steps to the last detent after 3 seconds

    return () => clearTimeout(timer);
  }, []);

  return (
    <Sheet.Root activeDetent={activeDetent} onActiveDetentChange={setActiveDetent}>
      <Sheet.Portal>
        <Sheet.View detents="60lvh">
          <Sheet.Backdrop />
          <Sheet.Content>
            <Sheet.Title>Controlled Detent Sheet</Sheet.Title>
            <Sheet.Description>This sheet active detent is controlled by state.</Sheet.Description>
          </Sheet.Content>
        </Sheet.View>
      </Sheet.Portal>
    </Sheet.Root>
  );
}
```

These props come with some limitations at the moment. Read more about the `activeDetent` and `onActiveDetentChange` props on the [Sheet documentation page](https://silkhq.com/docs/sheet.md).

---

---
title: "Third-Party Overlays · Silk"
description: "Learn how to use Silk alongside other overlay libraries."
Source: https://silkhq.com/docs/third-party-overlays.md
---

Third-party “overlay” components are components that are displayed over the current content, and can implement modality features, such as making all elements outside of their bounds non-interactive.

The Sheet component is designed to work seamlessly with such third-party components. However, depending on how they are implemented, you may have to take some steps to ensure compatibility, especially when the `inertOutside` prop of the `<Sheet.View>` is set to `true`.

## Automatic detection

In most cases, a third-party overlay will work automatically with the Sheet component. In particular, if:

- it is rendered directly inside of the `<Sheet.View>` underlying element; or
- it is appended to the `<body>` element using a React portal; or
- it is rendered inside the `<html>` element.

In these cases, the third-party overlay underlying elements will be considered as part of the frontmost presented Sheet.

## Wrap in `<ExternalOverlay.Root>`

If the third-party overlay renders in other parts of the DOM, or if its modality mechanism is not automatically compatible with the Sheet’s own, you will need to use the `ExternalOverlay` component to ensure compatibility.

### Basic usage

If the third-party overlay is not automatically compatible with the Sheet component, you can wrap it inside of a `<ExternalOverlay.Root>` to signal its presence and make it part of the frontmost presented Sheet.

```tsx
import { Menu } from "third-party-lib";
import { ExternalOverlay } from "@silk-hq/components";

const MyMenu = () => (
	<Menu.Root>
	   <Menu.Portal>
	      <ExternalOverlay.Root asChild>
	         <Menu.Content>
	            ...
	         </Menu.Content>
	      </ExternalOverlay.Root>
	   </Menu.Portal>
	</Menu.Root>
);
```

### Using the `contentGetter` prop

If the third-party overlay is out of reach and you cannot wrap it inside of an `<ExternalOverlay.Root>`, you can use the `contentGetter` prop.

This prop accepts either a CSS selector that will be used to get the first matched element, or a function that returns one element.

#### With a CSS selector

```tsx
import { Sheet, ExternalOverlay } from "@silk-hq/components";

const BottomSheet = () => (
	<Sheet.Root>
		<Sheet.Trigger>Open</Sheet.Trigger>
		<Sheet.Portal>
			<Sheet.View>
				<Sheet.Backdrop />
				<Sheet.Content>
					...
					<ExternalOverlay.Root contentGetter=".chat-plugin" />
				</Sheet.Content>
			</Sheet.View>
		</Sheet.Portal>
  </Sheet.Root>
);
```

#### With a function

```tsx
import { Sheet, ExternalOverlay } from "@silk-hq/components";

const BottomSheet = ({ chatPluginRef }) => (
	<Sheet.Root>
		<Sheet.Trigger>Open</Sheet.Trigger>
		<Sheet.Portal>
			<Sheet.View>
				<Sheet.Backdrop />
				<Sheet.Content>
					...
					<ExternalOverlay.Root contentGetter={() => chatPluginRef.current} />
				</Sheet.Content>
			</Sheet.View>
		</Sheet.Portal>
  </Sheet.Root>
);
```

### Using the `selfManagedInertOutside` prop

Some third-party overlay modality features may conflict with that of the Sheet component.

To avoid any risk of conflict, you can set the `selfManagedInertOutside` to `true` on `<ExternalOverlay.Root>`. This will indicate to the frontmost Sheet that the external overlay has its own inert outside mechanism. As a consequence, the Sheet will disable its own mechanism as soon as `<ExternalOverlay.Root>` child gets rendered.

```tsx
import { Menu } from "third-party-lib";
import { ExternalOverlay } from "@silk-hq/components";

const MyMenu = () => (
	<Menu.Root>
	   <Menu.Portal>
	      <ExternalOverlay.Root selfManagedInertOutside={true} asChild>
	         <Menu.Content>
	            ...
	         </Menu.Content>
	      </ExternalOverlay.Root>
	   </Menu.Portal>
	</Menu.Root>
);
```

### Using the `disabled` prop for more control

If the external overlay underlying elements are always rendered in the DOM, then the `ExternalOverlay` will always be active and its content considered as part of any presented Sheet.

To avoid this, you can use set the `disabled` prop to `false` when the external overlay is hidden.

```tsx
import { Menu } from "third-party-lib";
import { ExternalOverlay } from "@silk-hq/components";

const MyMenu = () => {
	const [open, setOpen] = useState(false);

return (
	<Menu.Root open={open} onOpenChange={setOpen}>
	   <Menu.Portal>
	      <ExternalOverlay.Root
		      selfManagedInertOutside={true}
		      disabled={!open}
		      asChild
		     >
	         <Menu.Content forceMount={true}>
	            ...
	         </Menu.Content>
	      </ExternalOverlay.Root>
	   </Menu.Portal>
	</Menu.Root>
)
};
```

---

---
title: "Sheet · Silk"
description: "API reference for the Sheet component."
Source: https://silkhq.com/docs/sheet.md
---

## Description

A primitive component for building advanced swipeable modal and non-modal overlay components such as bottom sheets, drawers, sidebars, dialogs, pages, lightboxes, toasts and more.

Built with a compound component architecture, it exposes a set of sub-components that give you full control over structure, behavior, and styling.

## Anatomy

### Basic

```tsx
import { Sheet } from "@silk-hq/components";

export default () => (
	<Sheet.Root>
		<Sheet.Trigger />
		<Sheet.Portal>
			<Sheet.View>
				<Sheet.Backdrop />
				<Sheet.Content>
					<Sheet.BleedingBackground />
					<Sheet.Title />
					<Sheet.Description />
				</Sheet.Content>
			</Sheet.View>
		</Sheet.Portal>
	</Sheet.Root>
);
```

### With a component id

```tsx
import { Sheet, createComponentId } from "@silk-hq/components";

const mySheetId = createComponentId();

export default () => {
	return (
		<Sheet.Root componentId={mySheetId}>
			<Sheet.Root>
				<Sheet.Trigger />
				<Sheet.Portal>
					<Sheet.View>
						<Sheet.Backdrop />
						<Sheet.Content>
							<Sheet.BleedingBackground />
							<Sheet.Title />
							<Sheet.Description />
							<Sheet.Trigger forComponent={mySheetId} />
						</Sheet.Content>
					</Sheet.View>
				</Sheet.Portal>
			</Sheet.Root>

			<Sheet.Trigger forComponent={mySheetId} />
			<Sheet.Portal>
				<Sheet.View forComponent={mySheetId}>
					<Sheet.Backdrop />
					<Sheet.Content>
						<Sheet.BleedingBackground />
						<Sheet.Title />
						<Sheet.Description />
					</Sheet.Content>
				</Sheet.View>
			</Sheet.Portal>
		</Sheet.Root>
	)
}
```

### With related components

```tsx
import { Sheet, Island, AutoFocusTarget } from "@silk-hq/components";

export default () => (
	<Sheet.Root>
		<Island.Root>
			<Island.Content />
		</Island.Root>

		<Sheet.Outlet />
		<Sheet.Trigger />

		<Sheet.Portal>
			<Sheet.View>
				<Sheet.Backdrop />
				<Sheet.Content>
					<Sheet.BleedingBackground />
					<Sheet.Handle />
					<Sheet.Trigger />
					<Sheet.Title />
					<Sheet.Description />
					<AutoFocusTarget.Root />
				</Sheet.Content>
			</Sheet.View>
		</Sheet.Portal>
	</Sheet.Root>
);
```

### With SpecialWrapper

```tsx
import { Sheet } from "@silk-hq/components";

export default () => (
	<Sheet.Root>
		<Sheet.Trigger />
		<Sheet.Portal>
			<Sheet.View>
				<Sheet.Backdrop />
				<Sheet.Content>
					<Sheet.SpecialWrapper.Root>
						<Sheet.SpecialWrapper.Content>
							<Sheet.BleedingBackground />
							<Sheet.Title />
							<Sheet.Description />
						</Sheet.SpecialWrapper.Content>
					</Sheet.SpecialWrapper.Root>
				</Sheet.Content>
			</Sheet.View>
		</Sheet.Portal>
	</Sheet.Root>
);
```

## Sub-components

### `<Sheet.Root>`

| Characteristic     | Details                                                                                                                           |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------- |
| Presence           | Required                                                                                                                          |
| Composition        | Contains all Sheet sub-components that belong to this Sheet instance, except for `<Sheet.Portal>` which can be positioned outside |
| Underlying element | `<div>`                                                                                                                           |

##### Description

The Root sub-component wraps all other Sheet sub-components that belong to the same Sheet instance (except for `<Sheet.Portal>` which can be used around it), as it contains logic that is shared with all of them.

##### Notes

If you don’t want the underlying element to affect the layout, you can apply the CSS `css:display: contents` to it.

#### `license`

| Characteristic | Details                            |
| -------------- | ---------------------------------- |
| **Presence**   | Required                           |
| **Type**       | `"commercial" \| "non-commercial"` |
| **Default**    | `undefined`                        |

##### Description

Indicates under what license you are using the library.

##### Values description

| Value              | Description                                                     |
| ------------------ | --------------------------------------------------------------- |
| `"commercial"`     | You declare using the library under the commercial license.     |
| `"non-commercial"` | You declare using the library under the non-commercial license. |

##### Notes

The purchase of a commercial license is needed for commercial use. More information [here](https://silkhq.com/access).

#### `asChild`

| Characteristic | Details     |
| -------------- | ----------- |
| **Presence**   | Optional    |
| **Type**       | `boolean`   |
| **Default**    | `undefined` |

##### Description

Defines whether the sub-component underlying element is the default one or the one passed as child of the sub-component.

##### Values description

| Value                | Description                                         |
| -------------------- | --------------------------------------------------- |
| `true`               | The underlying element rendered is the child.       |
| `false \| undefined` | The underlying element rendered is the default one. |

##### Notes

- If the child is a React component rendering an element:
   - it must accept props and spread all received props onto the rendered element;
   - in React < 19, it must use `React.forwardRef()` and pass the received ref to the rendered element.
- See [Composition](https://silkhq.com/docs/composition.md) for more information.

#### `componentId`

| Characteristic | Details     |
| -------------- | ----------- |
| **Presence**   | Optional    |
| **Type**       | `SheetId`   |
| **Default**    | `undefined` |

##### Description

Defines the id of this Sheet. This id can then be passed to other Sheet sub-components `forComponent` prop to associate them with it.

#### `forComponent`

| Characteristic | Details                     |
| -------------- | --------------------------- |
| **Presence**   | Optional                    |
| **Type**       | `SheetStackId \| "closest"` |
| **Default**    | `undefined`                 |

##### Description

Associates this Sheet instance with the desired SheetStack instance.

##### Values description

| Value          | Description                                                   |
| -------------- | ------------------------------------------------------------- |
| `undefined`    | This Sheet is not associated with any SheetStack.             |
| `SheetStackId` | Associates this Sheet with the SheetStack whose id is passed. |
| `"closest"`    | Associates this Sheet with the closest ancestor SheetStack.   |

#### `sheetRole`

| Characteristic     | Details                                 |
| ------------------ | --------------------------------------- |
| **Presence**       | Optional                                |
| **Type**           | `React.AriaRole`                        |
| **Default**        | `undefined`                             |
| **Example values** | `"dialog"`, `"alertdialog"`, `"status"` |

##### Description

Defines the WAI-ARIA role attribute set on the `<Sheet.View>` underlying element.

This value is also used to define the presence of the `html:aria-haspopup` attribute on the `<Sheet.Trigger>` underlying element.

##### Notes

- If `sheetRole` is set to `"alertdialog"`, then on `<Sheet.View>`:
   - `swipeDismissal` computes to `false`;
   - `onClickOutside` computes to `{ dismiss: false, stopOverlayPropagation: true }`;
   - `onEscapeKeyDown` computes to `{ dismiss: false, stopOverlayPropagation: true }`.

#### `defaultPresented`

| Characteristic | Details   |
| -------------- | --------- |
| **Presence**   | Optional  |
| **Type**       | `boolean` |
| **Default**    | `false`   |

##### Description

Defines whether the Sheet is initially presented or not.

##### Notes

On page load, it is presented **after** hydration occurs when set to `true`.

#### `presented`

| Characteristic   | Details                                                                                                |
| ---------------- | ------------------------------------------------------------------------------------------------------ |
| **Presence**     | Optional                                                                                               |
| **Type**         | `boolean`                                                                                              |
| **Default**      | `undefined`                                                                                            |
| **Requirements** | When this prop is used, passing the state setter function to the `onPresentedChange` is also required. |

##### Description

Controls the presented state of the Sheet.

##### Values description

| Value       | Description                                                                                                                                                            |
| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `undefined` | The presented state is uncontrolled, the Sheet will only be presented and dismissed based on user interactions handled internally (e.g. press on a `<Sheet.Trigger>`). |
| `true`      | Will cause the Sheet to be presented if it is not currently.                                                                                                           |
| `false`     | Will cause the Sheet to be dismissed if it is currently presented.                                                                                                     |

##### Notes

- This is an alternative method to the `defaultPresented` prop.
- Currently Sheet doesn’t support interruption during entering & exiting, and cannot be closed when it is not frontmost in a SheetStack (i.e. a sheet is stacked on top of it). Therefore, if `presented` is set to `false` during entering or when not frontmost in a SheetStack, or to `true` during exiting, nothing will happen, and onPresentedChange will be called with the current value of `presented` to avoid any mismatch between the controlled state and the internal one. **This limitation will be lifted in the future**.

#### `onPresentedChange`

| Characteristic | Details                         |
| -------------- | ------------------------------- |
| **Presence**   | Required if `presented` is used |
| **Type**       | `(presented: boolean) => void`  |
| **Default**    | `undefined`                     |

##### Description

Setter for the state passed in the `presented` prop. It will be called with the `presented` state value as parameter when it is changed internally (e.g. press on a `<Sheet.Trigger>` sub-component).

##### Notes

This is an alternative method to the `defaultPresented` prop.

#### `defaultActiveDetent`

| Characteristic | Details     |
| -------------- | ----------- |
| **Presence**   | Optional    |
| **Type**       | `number`    |
| **Default**    | `undefined` |

##### Description

Defines the index of the detent the Sheet should initially rest on after it gets presented.

##### Notes

- Detents indexes are defined as follow:
   - when the Sheet is fully outside of the view, it rests on the detent with index `0`;
   - all declared intermediate detents indexes go from `1` to `n-1`;
   - when the Sheet is fully expanded inside of `<Sheet.View>`, it rests on the last detent, numbered `n` (e.g. index `1` if there is no intermediate detents; index `2` if there is one intermediate detent).
- If `defaultActiveDetent` is set to `undefined`, the initial detent the Sheet rests on is the detent with the index `1`.

##### Example

```tsx
<Sheet.Root defaultActiveDetent={2}>
	...
</Sheet.Root>
```

#### `activeDetent`

| Characteristic | Details     |
| -------------- | ----------- |
| **Presence**   | Optional    |
| **Type**       | `number`    |
| **Default**    | `undefined` |

##### Description

Controls the `activeDetent` underlying state of the Sheet.

##### Values description

| Value       | Description                                                                                                                                                |
| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `undefined` | The `activeDetent` state is uncontrolled, it will only change based on user interactions handled internally (e.g. swipe, or press on a `<Sheet.Trigger>`). |
| `number`    | The `activeDetent` state is controlled, and this value reflects the index of the detent the Sheet is resting on or traveling towards.                      |

##### Notes

- This is an alternative method to the `defaultActiveDetent` prop.
- Currently it is not possible to step to a detent while stepping is already occurring. So if detent is changed during that state, nothing will occur, but there will be a mismatch between detent and the actual detent the sheet is resting on. So, before updating detent, you should check whether travelStatus ≠ “stepping”. **This limitation will be lifted in the future**.

#### `onActiveDetentChange`

| Characteristic | Details                            |
| -------------- | ---------------------------------- |
| **Presence**   | Required if `activeDetent` is used |
| **Type**       | `(activeDetent: number) => void`   |
| **Default**    | `undefined`                        |

##### Description

Setter for the state passed in the `activeDetent` prop. It will be called with the `activeDetent` state value as parameter when it is changed internally (e.g. swipe, or press on a `<Sheet.Trigger>`).

##### Notes

This is an alternative method to the `defaultActiveDetent` prop.

### `<Sheet.Trigger>`

| Characteristic     | Details                      |
| ------------------ | ---------------------------- |
| Presence           | Optional                     |
| Composition        | Descendant of `<Sheet.Root>` |
| Underlying element | `<button>`                   |

##### Description

A Trigger sub-component that allows to run specific actions related to the Sheet as a result of a press event.

##### Example

```tsx
const MyTrigger = () => (
	<Sheet.Trigger
		action={{ type: "step", direction: "down" }}
		onPress={{ forceFocus: false }}
	>
		Step down
	</Sheet.Trigger>
)
```

#### `asChild`

See [asChild](https://silkhq.com/docs/sheet.md#root-aschild) on `<Sheet.Root>`.

#### `forComponent`

| Characteristic | Details                                               |
| -------------- | ----------------------------------------------------- |
| **Presence**   | Optional                                              |
| **Type**       | `SheetId`                                             |
| **Default**    | The `SheetId` of the closest `<Sheet.Root>` ancestor. |

##### Description

Associates this sub-component with the desired Sheet instance.

#### `action`

| Characteristic | Details                                                                                                    |
| -------------- | ---------------------------------------------------------------------------------------------------------- |
| **Presence**   | Optional                                                                                                   |
| **Type**       | `ts:\| "present" \| "dismiss" \| "step" \| { type: "step"; direction?: "up" \| "down"; detent?: number; }` |
| **Default**    | `"present"`                                                                                                |

##### Description

Defines the action that will execute when the Trigger is pressed.

##### Values description

| Value                                                               | Description                                                                                                                                                                                                                                                  |
| ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `"present"`                                                         | The Sheet will be presented.                                                                                                                                                                                                                                 |
| `"dismiss"`                                                         | The Sheet will be dismissed.                                                                                                                                                                                                                                 |
| `"step"`                                                            | The Sheet will step to the next detent in the upward direction, and cycle after reaching the last detent.                                                                                                                                                    |
| `ts:{ type: "step"; direction?: "up" \| "down"; detent?: number; }` | The Sheet will step to a detent: <br>- if the `direction` key is used, it will step to the next detent in that direction and cycle after reaching the last detent; <br>- if the `detent` key is used, it will step to the detent matching that detent index. |

#### `onPress`

| Characteristic | Details                                                                                                                                                                                                                        |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Presence**   | Optional                                                                                                                                                                                                                       |
| **Type**       | `ts:{ forceFocus?: boolean; runAction?: boolean;} \| ((customEvent: {changeDefault: (changedBehavior: {forceFocus?: boolean;runAction?: boolean;}) => void;nativeEvent: React.MouseEvent<HTMLElement, MouseEvent>;}) => void)` |
| **Default**    | `{ forceFocus: true, runAction: true }`                                                                                                                                                                                        |

##### Description

An event handler that runs when the Trigger is pressed (equivalent to clicked).

The underlying custom event has a default behavior that can be changed either by calling its `changeDefault` method with an option object as parameter, or by directly passing the option object to the prop.

##### Values description

| Value                   | Description                                                                                                                                                               |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `{ forceFocus: true }`  | The underlying element will be focused on press in all browsers (by default Safari doesn’t do it, causing issues with focus management). This is the recommended setting. |
| `{ forceFocus: false }` | The underlying element will only receive focus on press in browsers where this is the default behavior (i.e. Safari will not do it).                                      |
| `{ runAction: true }`   | The Trigger action will be run.                                                                                                                                           |
| `{ runAction: false }`  | The Trigger action will not be run.                                                                                                                                       |

##### Example

```tsx
<Sheet.Trigger onPress={{ forceFocus: false }}>
	...
</Sheet.Trigger>
```

```tsx
<Sheet.Trigger
  onPress={(event) => event.changeDefault({ forceFocus: false })}
 >
	...
</Sheet.Trigger>
```

#### `travelAnimation`

See [travelAnimation](https://silkhq.com/docs/sheet.md#outlet-travelanimation) on `<Sheet.Outlet>`.

#### `stackingAnimation`

See [stackingAnimation](https://silkhq.com/docs/sheet.md#outlet-stackinganimation) on `<Sheet.Outlet>`.

### `<Sheet.Outlet>`

| Characteristic     | Details                     |
| ------------------ | --------------------------- |
| Presence           | Optional                    |
| Composition        | Child of the `<Sheet.Root>` |
| Underlying element | `<div>`                     |

##### Description

A sub-component that allows to declaratively define animations for the underlying element based on the travel and stacking progress of the associated Sheet.

#### `asChild`

See [asChild](https://silkhq.com/docs/sheet.md#root-aschild) on `<Sheet.Root>`.

#### `forComponent`

| Characteristic | Details                                               |
| -------------- | ----------------------------------------------------- |
| **Presence**   | Optional                                              |
| **Type**       | `SheetId`                                             |
| **Default**    | The `SheetId` of the closest `<Sheet.Root>` ancestor. |

##### Description

Associates this sub-component with the desired Sheet instance.

#### `travelAnimation`

| Characteristic | Details                                                                                                                                                                                                          |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Presence**   | Optional                                                                                                                                                                                                         |
| **Type**       | `ts:{ [property: string]: [string \| number, string \| number] \| ((args: { progress: number; tween: (start: string \| number, end: string \| number) => string }) => string \| number \| null \| undefined); }` |
| **Default**    | `undefined`                                                                                                                                                                                                      |

##### Description

Declaratively defines animations on any CSS property of the underlying element driven by the Sheet’s travel.

##### Values description for each key

| Value                                                                                                                     | Description                                                                                                                                                                                                                                                                 |
| ------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `[string \| number, string \| number]`                                                                                    | **Keyframes array syntax.** As the Sheet travels from its first detent (index 0) to its last detent, the underlying element will have its related CSS property animated from the first to the second value in the array, each value in-between being interpolated linearly. |
| `ts:(args: { progress: number; tween: (start: number \| string, end: number \| string) => string; }) => string \| number` | **Function syntax.** As the Sheet travels from its first detent (index 0) to its last detent, the underlying element will have its related CSS property animated based on the value returned by the function. The progress value goes from 0 to 1.                          |
| `string`                                                                                                                  | **String syntax.** As the Sheet travels, the underlying element will have its related CSS property set to the defined value.                                                                                                                                                |
| `null \| undefined`                                                                                                       | The underlying element related CSS property will not be animated or set.                                                                                                                                                                                                    |

##### Notes

- CSS properties must be written in camelcase form (e.g. `borderRadius`).
- All individual components of the `transform` CSS property can be used separately.
   - **List**
      ```ts
      | "translate"
      | "translateX"
      | "translateY"
      | "translateZ"
      | "scale"
      | "scaleX"
      | "scaleY"
      | "scaleZ"
      | "rotate"
      | "rotateX"
      | "rotateY"
      | "rotateZ"
      | "skew"
      | "skewX"
      | "skewY"
      ```
- The keyframes array syntax is only supported with individual `transform` properties and `opacity`.
   - **List**. Note that, apart from `opacity`, all of the following keys will be incorporated into a single `transform` declaration.
      ```ts
      | "opacity"
      | "translate"
      | "translateX"
      | "translateY"
      | "translateZ"
      | "scale"
      | "scaleX"
      | "scaleY"
      | "scaleZ"
      | "rotate"
      | "rotateX"
      | "rotateY"
      | "rotateZ"
      | "skew"
      | "skewX"
      | "skewY"
      ```
- Three special CSS properties related to clipping are available:
   - `clipBoundary` accepts only one value: `"layout-viewport"`. This special CSS property clips the underlying element where the layout viewport is drawn. Therefore, if the element is overflowing the layout viewport, it will be cut off. You can then use apply a transformation to it like `scale` and reveal its clipping.
   - `clipBorderRadius` accepts the same value as the `borderRadius` CSS property. It defines a border radius for the clip area when used in combination with the `clipBoundary` special CSS property.
   - `clipTransformOrigin` accept the same value as the `transformOrigin` CSS property. It defines the origin for the CSS transform applied to the element when used in combination with the `clipBoundary` special CSS property.
- Updating `travelAnimation` won't immediately reflect visually. The new value will only apply on the next travel. This limitation will be lifted in the future.
- `travelAnimation` is short for "travel-driven animation".

##### Examples

```tsx
<Sheet.Outlet
	travelAnimation={{
		opacity: [0, 0.5],
	}}
/>
```

```tsx
<Sheet.Outlet
	travelAnimation={{
		opacity: ({ progress }) => progress * 0.5,
	}}
/>
```

```tsx
<Sheet.Outlet
   travelAnimation={{
      backgroundColor: ({ tween }) =>
         `rgb(${tween(100, 0)}, ${tween(100, 0)}, ${tween(100, 0)})`,
   }}
/>
```

#### `stackingAnimation`

| Characteristic | Details                                                                                                                                                                                                          |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Presence**   | Optional                                                                                                                                                                                                         |
| **Type**       | `ts:{ [property: string]: [string \| number, string \| number] \| ((args: { progress: number; tween: (start: number \| string, end: number \| string) => string; }) => string \| number \| null \| undefined);}` |
| **Default**    | `undefined`                                                                                                                                                                                                      |

##### Description

Declaratively defines animations on any CSS property of the underlying element driven by the aggregated travel of Sheets stacked above the Sheet associated with this Outlet and belonging to the same SheetStack.

##### Values description for each key

| Value                                                                                                                    | Description                                                                                                                                                                                                                                                                                                      |
| ------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `[string \| number, string \| number]`                                                                                   | **Keyframes array syntax.** As Sheets travel and get stacked on top of the associated Sheet, the underlying element will have its related CSS property animated from the first to the second value in the array, each value in-between being interpolated linearly.                                              |
| `ts:(args: { progress:number; tween: (start: number \| string, end: number \| string) => string; }) => string \| number` | **Function syntax.** As Sheets travel and get stacked on top of the associated Sheet, the underlying element will have its related CSS property animated based on the value returned by the function. The progress value goes from 0 to n (n being the number of Sheets stacked on top of the associated Sheet). |
| `string`                                                                                                                 | **String syntax.** As Sheets get stacked on top of the associated Sheet, the underlying element will have its related CSS property set to the defined value.                                                                                                                                                     |
| `null \| undefined`                                                                                                      | The underlying element related CSS property will not be animated or set.                                                                                                                                                                                                                                         |

##### Notes

- CSS properties must be written in camelcase form (e.g. `borderRadius`).
- All individual components of the `transform` CSS property can be used separately.
   - **List**
      ```tsx
      | "translate"
      | "translateX"
      | "translateY"
      | "translateZ"
      | "scale"
      | "scaleX"
      | "scaleY"
      | "scaleZ"
      | "rotate"
      | "rotateX"
      | "rotateY"
      | "rotateZ"
      | "skew"
      | "skewX"
      | "skewY"
      ```
- The keyframes array syntax is only supported with individual `transform` properties and `opacity`.
   - **List**. Note that, apart from `opacity`, all of the following keys will be incorporated into a single `transform` declaration.
      ```tsx
      | "opacity"
      | "translate"
      | "translateX"
      | "translateY"
      | "translateZ"
      | "scale"
      | "scaleX"
      | "scaleY"
      | "scaleZ"
      | "rotate"
      | "rotateX"
      | "rotateY"
      | "rotateZ"
      | "skew"
      | "skewX"
      | "skewY"
      ```
- Updating `stackingAnimation` won't immediately reflect visually. The new value will only apply on the next travel. This limitation will be lifted in the future.
- `stackingAnimation` is short for "stacking-driven animation".

##### Examples

```tsx
<Sheet.Outlet stackingAnimation={{translateX: ["0px", "100px"], }} />
```

```tsx
<Sheet.Outlet stackingAnimation={{ translateX: ({ progress }) => progress * 100 + "px", }} />
```

```tsx
<Sheet.Outlet stackingAnimation={{ backgroundColor: ({ tween }) => `rgb(${tween(10, 0)}, ${tween(10, 0)}, ${tween(10, 0)})`, }}/>
```

### `<Sheet.Portal>`

| Characteristic     | Details  |
| ------------------ | -------- |
| Presence           | Optional |
| Composition        | Anywhere |
| Underlying element | None     |

##### Description

A sub-component that allows to render its child into any element, including the `document.body`. It is typically used to render the `<Sheet.Content>` in a high level element to make sure it appears above all other elements.

#### `container`

| Characteristic | Details               |
| -------------- | --------------------- |
| **Presence**   | Optional              |
| **Type**       | `HTMLElement \| null` |
| **Default**    | `document.body`       |

##### Description

Defines inside of which element the Portal’s child will be rendered.

### `<Sheet.View>`

| Characteristic     | Details                     |
| ------------------ | --------------------------- |
| Presence           | Required                    |
| Composition        | Child of the `<Sheet.Root>` |
| Underlying element | `<div>`                     |

##### Description

The View sub-component underlying element is the view inside of which the `<Sheet.Content>` underlying element can travel.

It also holds the HTML `role` attribute for the Sheet.

#### `forComponent`

| Characteristic | Details                                               |
| -------------- | ----------------------------------------------------- |
| **Presence**   | Optional                                              |
| **Type**       | `SheetId`                                             |
| **Default**    | The `SheetId` of the closest `<Sheet.Root>` ancestor. |

##### Description

Associates this sub-component with the desired Sheet instance.

#### `contentPlacement`

| Characteristic | Details                                                                                 |
| -------------- | --------------------------------------------------------------------------------------- |
| **Presence**   | Optional                                                                                |
| **Type**       | `"top" \| "bottom" \| "left" \| "right" \| "center"`                                    |
| **Default**    | `"bottom"` if `tracks` is not set, otherwise it matches the value of the `tracks` prop. |

##### Description

Defines the placement of `<Sheet.Content>` inside of `<Sheet.View>` on the travel axis. On the cross axis, it is always centered.

#### `tracks`

| Characteristic | Details                                                                                                |
| -------------- | ------------------------------------------------------------------------------------------------------ |
| **Presence**   | Optional                                                                                               |
| **Type**       | `"top" \| "bottom" \| "left" \| "right" \| ["top", "bottom"] \| ["left", "right"]`                     |
| **Default**    | `"bottom"` if `contentPlacement` is not set, otherwise it matches the value of the `contentPlacement`. |

##### Description

Defines the track(s) `<Sheet.Content>` can travel on, from its last detent (index `n`) to its origin detent (index `0`).

#### `detents`

| Characteristic | Details                                                                                   |
| -------------- | ----------------------------------------------------------------------------------------- |
| **Presence**   | Optional                                                                                  |
| **Type**       | `string \| Array<string>` where `string` is a CSS length which does not use the `%` unit. |
| **Default**    | `undefined`                                                                               |

##### Description

Defines one or several intermediate detents on which `<Sheet.Content>` can rest on the track between the origin detent (index `0`) and the last detent (index `n`).

#### `swipeTrap`

| Characteristic | Details                                                                      |
| -------------- | ---------------------------------------------------------------------------- |
| **Presence**   | Optional                                                                     |
| **Type**       | `boolean \| { x?: boolean; y?: boolean }`                                    |
| **Default**    | `{ x: true, y: false }` on Android in non-standalone mode, `true` otherwise. |

##### Description

Defines whether swipes on the specified axis or axes are trapped within `<Sheet.View>` or not.

When not trapped, when swiping in a direction where further travel is not possible, the swipe will propagate to the closest ancestor Sheet, scroll container, or window (triggering swipe to go back in history in browsers that support it).

##### Values description

| Value         | Description                                |
| ------------- | ------------------------------------------ |
| `true`        | Traps swipe both on both the x and y axis. |
| `{ x: true }` | Traps swipe on the x axis.                 |
| `{ y: true }` | Traps swipe on the y axis.                 |

##### Notes

- Always computes to `true` if `inertOutside` is set to `true`.
- On Android in non-standalone mode, `swipeTrap` on the y axis always computes to `false` not to prevent the browser UI from being revealed.
- If `swipeOvershoot` is set to `false`, `swipeTrap` on the travel axis always computes to `true`.
- Safari has a bug causing swipe to always be trapped when swiping over a vertically swipeable Sheet or Scroll which is inside of a horizontally swipeable Sheet or Scroll (and vice versa). We hope to see that issue resolved quickly.

#### `swipeOvershoot`

| Characteristic | Details   |
| -------------- | --------- |
| **Presence**   | Optional  |
| **Type**       | `boolean` |
| **Default**    | `true`    |

##### Description

Defines the behavior when the user performs a swipe that would cause `<Sheet.Content>` to move further than its last detent (index `n`).

##### Values description

| Value   | Description                                                                                                                   |
| ------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `true`  | Overshoot will occur, causing `<Sheet.Content>` to move further than the last detent, and snap back into place when released. |
| `false` | Overshoot will not occur, `<Sheet.Content>` will stop right away when being swiped past the last detent.                      |

##### Notes

Overshoot only works in browsers that support elastic overscroll (i.e. Safari, and Firefox on macOS).

#### `swipeDismissal`

| Characteristic | Details                                                             |
| -------------- | ------------------------------------------------------------------- |
| **Presence**   | Optional                                                            |
| **Type**       | `boolean`                                                           |
| **Default**    | `false` if `sheetRole` is set to `"alertdialog"`, `true` otherwise. |

##### Description

Defines whether it is possible to swipe `<Sheet.Content>` out of the `<Sheet.View>` and cause the Sheet to be dismissed.

##### Notes

- Always computes to `false` if `sheetRole` is set to `"alertdialog"`.
- When set to `false` and `swipeOvershoot` is set to `true`, the Sheet remains swipeable but will snap back into place when a swipe occurs.

#### `swipe`

| Characteristic | Details   |
| -------------- | --------- |
| **Presence**   | Optional  |
| **Type**       | `boolean` |
| **Default**    | `true`    |

##### Description

Defines whether swiping along the travel axis over `<Sheet.Content>` — or `<Sheet.Backdrop>` if swipeable — causes the Sheet to travel.

##### Notes

The value can only be updated when the Sheet is resting on a detent, not while it is traveling.

#### `nativeEdgeSwipePrevention`

| Characteristic | Details   |
| -------------- | --------- |
| **Presence**   | Optional  |
| **Type**       | `boolean` |
| **Default**    | `false`   |

##### Description

Defines whether a horizontal swipe from the left edge of the screen on iOS Safari triggers the browser’s “go back” navigation gesture.

##### Notes

- This mechanism relies on a `28px`-wide element positioned at the left edge of the screen. By default it appears above all elements inside `<Sheet.View>`, blocking interaction with anything underneath. If this causes issues, you can lift your elements above it by applying `css:position: relative` (or any non-static positioning) and a `css:z-index` value greater than `0`.
- This element will also capture click outside events, preventing dismissal if the user clicks on it, even if visually outside of `<View.Content>`.
- This mechanism is not foolproof — in rare cases, quick gestures may still slip through and trigger the browser’s back navigation.
   - For more reliable prevention in standalone mode on iOS, we recommend avoiding the addition of new history entries. Instead, replace the current entry. This way, Safari won’t allow swiping back, as there’s no previous page in the history.
- It is not based on a web standard, so there’s no guarantee it will continue to work in the future.

#### `enteringAnimationSettings`

| Characteristic | Details                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Presence**   | Optional                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| **Type**       | `ts:"gentle" \| "smooth" \| "snappy" \| "brisk" \| "bouncy" \| "elastic" \| { preset?: "gentle" \| "smooth" \| "snappy" \| "brisk" \| "bouncy" \| "elastic" \| { track?: Track; contentMove?: boolean; skip?: boolean; } \| { easing: "spring"; stiffness: number; damping: number; mass: number; initialVelocity?: number; precision?: number; delay?: number; track?: Track; contentMove?: boolean; skip?: boolean; } \| { easing: "ease" \| "ease-in" \| "ease-out" \| "ease-in-out" \| "linear"; duration: number; delay?: number; track?: Track; contentMove?: boolean; skip?: boolean; }; }` |
| **Default**    | `ts:{ preset: "smooth", contentMove: true, skip: prefersReducedMotion, /* computes to true if prefers reduced motion */ }`                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |

##### Description

Defines the configuration for the programmatic entering travel animation.

##### Values description

| Value                              | Description                                                                                                                                                                                         |
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `"gentle" \| { preset: "gentle" }` | Use the `"gentle"` preset.                                                                                                                                                                          |
| `{ track: "top" }`                 | For Sheet with two tracks defined, picks the track on which travel occurs (e.g. the `"top"` track here).                                                                                            |
| `{ contentMove: false }`           | The `<Sheet.Content>` underlying element will not be animated, instead it will be placed on its destination detent immediately. All other sub-components underlying elements are animated normally. |
| `{ skip: true }`                   | The animation is skipped entirely and the Sheet doesn’t go through the corresponding state.                                                                                                         |

##### Notes

- **Presets definitions**
   ```tsx
   const presets = {
   	gentle: {
   	  easing: "spring",
       stiffness: 560,
       damping: 68,
       mass: 1.85,
     },
     smooth: {
   	  easing: "spring",
       stiffness: 580,
       damping: 60,
       mass: 1.35,
     },
     snappy: {
   	  easing: "spring",
       stiffness: 350,
       damping: 34,
       mass: 0.9,
     },
     brisk: {
   	  easing: "spring",
       stiffness: 350,
       damping: 28,
       mass: 0.65,
     },
     bouncy: {
   	  easing: "spring",
       stiffness: 240,
       damping: 19,
       mass: 0.7,
     },
     elastic: {
   	  easing: "spring",
       stiffness: 260,
       damping: 20,
       mass: 1,
     },
   }
   ```

#### `exitingAnimationSettings`

| Characteristic | Details                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Presence**   | Optional                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| **Type**       | `ts:"gentle" \| "smooth" \| "snappy" \| "brisk" \| "bouncy" \| "elastic" \| { preset?: "gentle" \| "smooth" \| "snappy" \| "brisk" \| "bouncy" \| "elastic" \| { track?: Track; contentMove?: boolean; skip?: boolean; } \| { easing: "spring"; stiffness: number; damping: number; mass: number; initialVelocity?: number; precision?: number; delay?: number; track?: Track; contentMove?: boolean; skip?: boolean; } \| { easing: "ease" \| "ease-in" \| "ease-out" \| "ease-in-out" \| "linear"; duration: number; delay?: number; track?: Track; contentMove?: boolean; skip?: boolean; }; }` |
| **Default**    | `ts:{ preset: "smooth", contentMove: true, skip: prefersReducedMotion, /* computes to true if prefers reduced motion */ }`                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |

##### Description

Defines the configuration for the programmatic exiting travel animation.

##### Values description

| Value                              | Description                                                                                                                                                                      |
| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `"gentle" \| { preset: "gentle" }` | Use the `"gentle"` preset.                                                                                                                                                       |
| `{ track: "top" }`                 | For Sheet with two tracks defined, picks the track on which travel occurs (e.g. the `"top"` track here).                                                                         |
| `{ contentMove: false }`           | The `<Sheet.Content>` underlying element will not be animated, instead it will remain on its current detent. All other sub-components underlying elements are animated normally. |
| `{ skip: true }`                   | The animation is skipped entirely and the Sheet doesn’t go through the corresponding state.                                                                                      |

#### `steppingAnimationSettings`

##### Description

Defines the configuration for the programmatic stepping travel animation.

See [enteringAnimationSettings](https://silkhq.com/docs/sheet.md#view-enteringanimationsettings).

##### Notes

The `track` and `contentMove` keys do not apply here.

#### `onTravelStatusChange`

| Characteristic | Details                                                                            |
| -------------- | ---------------------------------------------------------------------------------- |
| **Presence**   | Optional                                                                           |
| **Type**       | `("idleOutside" \| "entering" \| "idleInside" \| "stepping" \| "exiting") => void` |
| **Default**    | `undefined`                                                                        |

##### Description

An event handler that runs when the travel status changes.

#### `onTravelRangeChange`

| Characteristic | Details                                     |
| -------------- | ------------------------------------------- |
| **Presence**   | Optional                                    |
| **Type**       | `({ start: number; end: number; }) => void` |
| **Default**    | `undefined`                                 |

##### Description

An event handler that runs when the travel range changes.

##### Notes

- A range is defined by a start detent and an end detent.
- The Sheet is considered to be within a range when the side of `<Sheet.Content>` opposite to the dismiss direction is located between the start and end detent of that range.
- When the Sheet is resting on a specific detent, the start and end detent are equal to the index of that detent.
- The range does not reflect overshoot. Therefore, if the Sheet is overshooting after the detent with index `1`, its travel range will be `{ start: 1, end: 1 }`.

#### `onTravel`

| Characteristic | Details                                                                                                             |
| -------------- | ------------------------------------------------------------------------------------------------------------------- |
| **Presence**   | Optional                                                                                                            |
| **Type**       | `ts:(args: { progress: number; range: { start: number; end: number }; progressAtDetents: Array<number>; }) => void` |
| **Default**    | `undefined`                                                                                                         |

##### Description

An event handler that runs on every frame when travel occurs, whether it is caused by swipe or programmatically.

##### Parameters description

| Value               | Description                                                                                                                                          |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `progress`          | The progress value of the Sheet travel, going from `0` to `1`. It is `0` when the Sheet is fully out, and `1` when it is resting on the last detent. |
| `range`             | The travel range the Sheet is currently within.                                                                                                      |
| `progressAtDetents` | The equivalent progress value for each detent. It is useful to make calculations and apply effects only within specific ranges.                      |

#### `onTravelStart`

| Characteristic | Details      |
| -------------- | ------------ |
| **Presence**   | Optional     |
| **Type**       | `() => void` |
| **Default**    | `undefined`  |

##### Description

An event handler that runs when the Sheet starts traveling, whether it is caused by swipe or programmatically.

##### Notes

It runs before the first `onTravel` event handler call.

#### `onTravelEnd`

| Characteristic | Details      |
| -------------- | ------------ |
| **Presence**   | Optional     |
| **Type**       | `() => void` |
| **Default**    | `undefined`  |

##### Description

An event handler that runs after the Sheet finishes traveling, whether it is caused by swipe or programmatically.

##### Notes

It runs before the last `onTravel` event handler call.

#### `inertOutside`

| Characteristic | Details   |
| -------------- | --------- |
| **Presence**   | Optional  |
| **Type**       | `boolean` |
| **Default**    | `true`    |

##### Description

Defines whether all interactions outside of `<Sheet.View>` and all associated `<Island.Content>` should be prevented.

##### Notes

- In other words, this prop defines whether the Sheet is modal or not.
- It prevents `<body>` from being scrollable, as expected. As a result, scrollbars are removed, and a CSS padding is added to compensate for it. In order to adjust the position of elements using `fixed` positioning, please use the Fixed component. See [Fixed](https://silkhq.com/docs/fixed.md).
- Use the Island component to wrap any element that you want the user to be able to interact with when this prop is set to `true`. See [Island](https://silkhq.com/docs/island.md).
- Due to a Safari bug, when this prop is set to `false` and you are not using `<Sheet.Backdrop>`, you need to use `<Sheet.SpecialWrapper.Root>` and `<Sheet.SpecialWrapper.Content>` inside of `<Sheet.Content>`, otherwise the Sheet will not be swipeable.

#### `onPresentAutoFocus`

| Characteristic | Details                                                                                                                                      |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| **Presence**   | Optional                                                                                                                                     |
| **Type**       | `ts:{ focus?: boolean; } \| ((customEvent: { changeDefault: (changedBehavior: { focus?: boolean; }) => void; nativeEvent: null; }) => void)` |
| **Default**    | `{ focus: true }`                                                                                                                            |

##### Description

An event handler that runs when the auto-focus mechanism is executed when the Sheet gets presented, at the end of the entering animation if there is one.

The underlying custom event has a default behavior that can be changed either by calling its `changeDefault` method with an option object as parameter, or by directly passing the option object to the prop.

##### Values description

| Value              | Description                                                                                                                                                                       |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `{ focus: true }`  | Causes the first `<AutoFocusTarget>` underlying element if there is one, or the first focusable element within the `<Sheet.View>` to receive focus when the Sheet gets presented. |
| `{ focus: false }` | Prevents the auto-focus mechanism from focusing any element when the Sheet gets presented.                                                                                        |

##### Example

```tsx
<Sheet.View onPresentAutoFocus={{ focus: false }}>
	...
</Sheet.View>
```

```tsx
<Sheet.View
  onPresentAutoFocus={(event) => event.changeDefault({ focus: false })}
 >
	...
</Sheet.View>
```

#### `onDismissAutoFocus`

| Characteristic | Details                                                                                                                                      |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| **Presence**   | Optional                                                                                                                                     |
| **Type**       | `ts:{ focus?: boolean; } \| ((customEvent: { changeDefault: (changedBehavior: { focus?: boolean; }) => void; nativeEvent: null; }) => void)` |
| **Default**    | `{ focus: true }`                                                                                                                            |

##### Description

An event handler that runs when the auto-focus mechanism is executed when the Sheet gets dismissed, at the end of the exiting animation if there is one.

The underlying custom event has a default behavior that can be changed either by calling its `changeDefault` method with an option object as parameter, or by directly passing the option object to the prop.

##### Values description

| Value              | Description                                                                                                                                                                       |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `{ focus: true }`  | Causes the first `<AutoFocusTarget>` underlying element if there is one, or the first focusable element within the `<Sheet.View>` to receive focus when the Sheet gets dismissed. |
| `{ focus: false }` | Prevents the auto-focus mechanism from focusing any element when the Sheet gets dismissed.                                                                                        |

##### Example

```tsx
<Sheet.View onDismissAutoFocus={{ focus: false }}>
	...
</Sheet.View>
```

```tsx
<Sheet.View
  onDismissAutoFocus={(event) => event.changeDefault({ focus: false })}
 >
	...
</Sheet.View>
```

#### `onClickOutside`

| Characteristic | Details                                                                                                                                                                                                                              |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Presence**   | Optional                                                                                                                                                                                                                             |
| **Type**       | `ts:{ dismiss?: boolean; stopOverlayPropagation?: boolean; } \| ((customEvent: { changeDefault: (changedBehavior: { dismiss?: boolean; stopOverlayPropagation?: boolean; }) => void; nativeEvent: React.SyntheticEvent; }) => void)` |
| **Default**    | `{ dismiss: true, stopOverlayPropagation: true }`                                                                                                                                                                                    |

##### Description

An event handler that runs when a click occurs outside of `<Sheet.View>` and all associated `<Island.Content>`.

The underlying custom event has a default behavior that can be changed either by calling its `changeDefault` method with an option object as parameter, or by directly passing the option object to the prop.

##### Values description

| Value                               | Description                                                                                                                                               |
| ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `{ dismiss: true }`                 | If `sheetRole` is not set to `"alertdialog"`, then the Sheet will get dismissed when a click occurs outside.                                              |
| `{ dismiss: false }`                | Inverse of `true`.                                                                                                                                        |
| `{ stopOverlayPropagation: true }`  | The `clickoutside` custom event will not propagate to overlays (i.e. Sheets) that are presented below this one. Only this Sheet will deal with the event. |
| `{ stopOverlayPropagation: false }` | Inverse of `true`.                                                                                                                                        |

##### Notes

- Click events performed on `<Sheet.Backdrop>` underlying element are considered as outside. `<Sheet.View>` underlying element is click-through, so click events performed directly over it are considered as outside.
- This prop always computes to `{ dismiss: false, stopOverlayPropagation: true }` if the `sheetRole` prop is set to `"alertdialog"`.
- `{ dismiss: false, stopOverlayPropagation: false }` is useful for example in combination with the `inertOutside` prop set to `false` in the case of a toast or sidebar component which may be presented on top of another Sheet. In that case you don’t want the toast or sidebar component to get dismissed when a click outside occurs, but may want the Sheet below to do so. Because the `clickoutside` custom event will be propagated to the Sheet below, it will get dismissed if its `onClickOutside` prop is set to `{ dismiss: true }`.

##### Example

```tsx
<Sheet.View onClickOutside={{ dismiss: false }}>
	...
</Sheet.View>
```

```tsx
<Sheet.View
  onClickOutside={(event) => event.changeDefault({ dismiss: false })}
 >
	...
</Sheet.View>
```

#### `onEscapeKeyDown`

| Characteristic | Details                                                                                                                                                                                                                                                                                              |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Presence**   | Optional                                                                                                                                                                                                                                                                                             |
| **Type**       | `ts:{ nativePreventDefault?: boolean; dismiss?: boolean; stopOverlayPropagation?: boolean; } \| ((customEvent: { changeDefault: (changedBehavior: { nativePreventDefault?: boolean; dismiss?: boolean; stopOverlayPropagation?: boolean; }) => void; nativeEvent: React.SyntheticEvent; }) => void)` |
| **Default**    | `{ nativePreventDefault: true, dismiss: true, stopOverlayPropagation: true }`                                                                                                                                                                                                                        |

##### Description

An event handler that runs when the escape key is pressed.

The underlying custom event has a default behavior that can be changed either by calling its `changeDefault` method with an option object as parameter, or by directly passing the option object to the prop.

##### Values description

| Value                               | Description                                                                                                                                  |
| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `{ nativePreventDefault: true }`    | The user-agent default action run when the escape key is pressed is prevented. (Safari macOS default action is escaping full-screen mode.)   |
| `{ nativePreventDefault: false }`   | Inverse of `true`.                                                                                                                           |
| `{ dismiss: true }`                 | The Sheet will get dismissed when the escape key is pressed.                                                                                 |
| `{ dismiss: false }`                | Inverse of `true`.                                                                                                                           |
| `{ stopOverlayPropagation: true }`  | The keydown event will not propagate to overlays (i.e. Sheets) that are presented below this one. Only this Sheet will deal with this event. |
| `{ stopOverlayPropagation: false }` | Inverse of `true`.                                                                                                                           |

##### Notes

- Always computes to `{ dismiss: false, stopOverlayPropagation: true }` if `sheetRole` is set to `"alertdialog"`.
- `{ dismiss: false, stopOverlayPropagation: false }` is useful for example in combination with the `inertOutside` prop set to `false` in the case of a toast or sidebar component which may be presented on top of another Sheet. In that case you don’t want the toast or sidebar component to get dismissed when the escape key is pressed, but may want the Sheet below to do so. Because the keydown event will be propagated to the Sheet below, it will get dismissed if its `onEscapeKeyDown` prop is set to `{ dismiss: true }`.

##### Example

```tsx
<Sheet.View onEscapeKeyDown={{ dismiss: false }}>
	...
</Sheet.View>
```

```tsx
<Sheet.View
  onEscapeKeyDown={(event) => event.changeDefault({ dismiss: false })}
 >
	...
</Sheet.View>
```

#### `onFocusInside`

| Characteristic | Details                                          |
| -------------- | ------------------------------------------------ |
| **Presence**   | Optional                                         |
| **Type**       | `(customEvent: { nativeEvent: Event; }) => void` |
| **Default**    | `undefined`                                      |

##### Description

An event handler that runs when focus occurs inside of `<Sheet.View>`.

#### `nativeFocusScrollPrevention`

| Characteristic | Details   |
| -------------- | --------- |
| **Presence**   | Optional  |
| **Type**       | `boolean` |
| **Default**    | `true`    |

##### Description

Defines whether the native browser scroll into view mechanism should be prevented or not when an element inside `<Sheet.View>` receives focus.

When an element receives focus on mobile, the browser shifts the viewport up or down to try and keep it in view. Unfortunately, this native mechanism doesn’t work well in most situations, so we let you prevent it and properly deal with the position of the focused element.

If the focused element ends up being covered by the on-screen keyboard, we recommend using the Scroll component so it gets scrolled into view automatically.

##### Notes

- The prevention doesn’t work when the inputs are inside of an `<iframe>` element.
- When the user clicks on text present in a text input, the caret will always be put back at its previous position when set to `true`.
- In iOS Safari, the prevention may not be effective with password inputs whose `autoComplete` html attribute is set to anything else than `"current-password"`. Therefore, we strongly recommend always using this value. Safari won’t suggest a new password directly, but the user can still get a suggested password by tapping the “Password” button in the suggestion bar and asking the password manager to provide a new password.
- Due to a Chrome Android bug, the prevention may not be effective when the focus is moved with the on-screen keyboard “next input” button.
- Due to a Chrome Android bug, for inputs causing the suggestion bar of the keyboard to be shown, a distance of at least 48px between the last text input and the bottom of the viewport is required to avoid a layout shift.

### `<Sheet.Backdrop>`

| Characteristic     | Details                 |
| ------------------ | ----------------------- |
| Presence           | Optional                |
| Composition        | Child of `<Sheet.View>` |
| Underlying element | `<div>`                 |

##### Description

The Backdrop sub-component prevents user interactions with the content below and can be used to dim it.

#### `asChild`

See [asChild](https://silkhq.com/docs/sheet.md#root-aschild) on `<Sheet.Root>`.

#### `swipeable`

| Characteristic | Details   |
| -------------- | --------- |
| **Presence**   | Optional  |
| **Type**       | `boolean` |
| **Default**    | `true`    |

##### Description

Defines whether swiping over the Backdrop causes the Sheet to travel.

##### Notes

When set to `false`, using the SpecialWrapper sub-component is required in Safari due to a bug.

#### `themeColorDimming`

| Characteristic | Details           |
| -------------- | ----------------- |
| **Presence**   | Optional          |
| **Type**       | `false \| "auto"` |
| **Default**    | `false`           |

##### Description

Defines whether the `html:theme-color` of the page gets dimmed using the CSS `css:background-color` and `css:opacity` of `<Sheet.Backdrop>`, so the Backdrop and the OS status bar blend together.

##### Values description

| Value    | Description                                                                                   |
| -------- | --------------------------------------------------------------------------------------------- |
| `"auto"` | Computes to `true` in WebKit-based browsers. When `true`, the `html:theme-color` gets dimmed. |
| `false`  | The `html:theme-color` does not get dimmed.                                                   |

##### Notes

- The HTML `html:theme-color` meta-tag must be set, and its value declared using the hexadecimal format (e.g. `css:#ffffff`) or the RGB format (`css:rgb(<integer>, <integer>, <integer>)`).
- The `<Sheet.Backdrop>` underlying element CSS `css:background-color` value must not include the alpha channel.
- `<Sheet.Backdrop>` must have a `travelAnimation` declared for its `css:opacity`, and its value must either use the keyframes array syntax with `number`s as values (not `string`), or the function syntax and return a `number`.
- If you need to update the `html:theme-color` while the Sheet is presented, you must use the [`updateThemeColor`](https://silkhq.com/docs/update-theme-color.md) function so only the underlying color gets updated, preserving the dimming.

#### `travelAnimation`

| Characteristic | Details                                             |
| -------------- | --------------------------------------------------- |
| **Default**    | `({ progress }) => Math.min(progress * 0.33, 0.33)` |

See [travelAnimation](https://silkhq.com/docs/sheet.md#outlet-travelanimation) on `<Sheet.Outlet>`.

##### Notes

You can remove the default value by setting it to `{ opacity: null }`.

#### `stackingAnimation`

See [stackingAnimation](https://silkhq.com/docs/sheet.md#outlet-stackinganimation) on `<Sheet.Outlet>`.

### `<Sheet.Content>`

| Characteristic     | Details                 |
| ------------------ | ----------------------- |
| Presence           | Required                |
| Composition        | Child of `<Sheet.View>` |
| Underlying element | `<div>`                 |

##### Description

The Content sub-component represents the panel which contains the content of the sheet and moves during travel.

##### Notes

Its position is determined by the `contentPlacement` prop on `<Sheet.View>`. You cannot define its position in any other way.

#### `asChild`

See [asChild](https://silkhq.com/docs/sheet.md#root-aschild) on `<Sheet.Root>`.

#### `travelAnimation`

See [travelAnimation](https://silkhq.com/docs/sheet.md#outlet-travelanimation) on `<Sheet.Outlet>`.

#### `stackingAnimation`

See [stackingAnimation](https://silkhq.com/docs/sheet.md#outlet-stackinganimation) on `<Sheet.Outlet>`.

### `<Sheet.BleedingBackground>`

| Characteristic     | Details                         |
| ------------------ | ------------------------------- |
| Presence           | Optional                        |
| Composition        | Descendant of `<Sheet.Content>` |
| Underlying element | `div`                           |

##### Description

The BleedingBackground sub-component renders an element which is automatically sized and positioned to fully occupy the `<Sheet.Content>` and bleed out of it in the swipe dismissal direction so it looks like it is expanded during swipe overshoot.

The underlying element can be styled freely to customize its appearance.

##### Notes

As a performance optimization, the underlying element is resized during entering and exiting animations. This can cause visual shifts when using gradient or images as background when their size is based on the size of the element. To avoid such shifts, prefer sizing based on absolute values (e.g. `px` or `svh`).

#### `asChild`

See [asChild](https://silkhq.com/docs/sheet.md#root-aschild) on `<Sheet.Root>`.

#### `travelAnimation`

See [travelAnimation](https://silkhq.com/docs/sheet.md#outlet-travelanimation) on `<Sheet.Outlet>`.

#### `stackingAnimation`

See [stackingAnimation](https://silkhq.com/docs/sheet.md#outlet-stackinganimation) on `<Sheet.Outlet>`.

### `<Sheet.Handle>`

| Characteristic     | Details                      |
| ------------------ | ---------------------------- |
| Presence           | Optional                     |
| Composition        | Descendant of `<Sheet.Root>` |
| Underlying element | `button`                     |

##### Description

A Handle sub-component representing a "handle" signifier used to indicate to the user that swiping the sheet is possible.

Internally, it renders a `<Sheet.Trigger>` sub-component wrapping a `<VisuallyHidden>` component. Therefore, any textual content passed to it will only be accessible to screen-readers and visually hidden.

A `::before` pseudo-element is used to expand the interactive area of the underlying Trigger.

#### `asChild`

See [asChild](https://silkhq.com/docs/sheet.md#root-aschild) on `<Sheet.Root>`.

#### `forComponent`

| Characteristic | Details                                               |
| -------------- | ----------------------------------------------------- |
| **Presence**   | Optional                                              |
| **Type**       | `SheetId`                                             |
| **Default**    | The `SheetId` of the closest `<Sheet.Root>` ancestor. |

##### Description

Associates this sub-component with the desired Sheet instance.

#### `action`

| Characteristic | Details                                                                                    |
| -------------- | ------------------------------------------------------------------------------------------ |
| **Presence**   | Optional                                                                                   |
| **Type**       | `ts:"dismiss" \| "step" \| { type: "step"; direction?: "up" \| "down"; detent?: number; }` |
| **Default**    | `"step"`                                                                                   |

##### Description

Defines the action that will execute when the Handle is pressed.

##### Values description

| Value                                                               | Description                                                                                               |
| ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `"dismiss"`                                                         | The Sheet will be dismissed.                                                                              |
| `"step"`                                                            | The Sheet will step to the next detent in the upward direction, and cycle after reaching the last detent. |
| `ts:{ type: "step"; direction?: "up" \| "down"; detent?: number; }` | The Sheet will step to a detent:                                                                          |

- if the `direction` key is used, it will step to the next detent in that direction and cycle after reaching the last detent;
- if the `detent` key is used, it will step to the detent matching that detent index. |

#### `onPress`

See [onPress](https://silkhq.com/docs/sheet.md#trigger-onpress) on `<Sheet.Trigger>`.

#### `travelAnimation`

See [travelAnimation](https://silkhq.com/docs/sheet.md#outlet-travelanimation) on `<Sheet.Outlet>`.

#### `stackingAnimation`

See [stackingAnimation](https://silkhq.com/docs/sheet.md#outlet-stackinganimation) on `<Sheet.Outlet>`.

### `<Sheet.Title>`

| Characteristic     | Details                                                     |
| ------------------ | ----------------------------------------------------------- |
| Presence           | Required if `sheetRole` is set to `dialog` or `alertdialog` |
| Composition        | Descendant of `<Sheet.View>`                                |
| Underlying element | `h2`                                                        |

##### Description

A sub-component used to define a title for the Sheet.

The `html:aria-labelledby` HTML attribute is set automatically on `<Sheet.View>` underlying element.

#### `asChild`

See [asChild](https://silkhq.com/docs/sheet.md#root-aschild) on `<Sheet.Root>`.

#### `travelAnimation`

See [travelAnimation](https://silkhq.com/docs/sheet.md#outlet-travelanimation) on `<Sheet.Outlet>`.

#### `stackingAnimation`

See [stackingAnimation](https://silkhq.com/docs/sheet.md#outlet-stackinganimation) on `<Sheet.Outlet>`.

### `<Sheet.Description>`

| Characteristic     | Details                                                     |
| ------------------ | ----------------------------------------------------------- |
| Presence           | Required if `sheetRole` is set to `dialog` or `alertdialog` |
| Composition        | Descendant of `<Sheet.View>`                                |
| Underlying element | `p`                                                         |

##### Description

A sub-component used to define a title for the Sheet.

The `html:aria-describedby` HTML attribute is set automatically on `<Sheet.View>` underlying element.

#### `asChild`

See [asChild](https://silkhq.com/docs/sheet.md#root-aschild) on `<Sheet.Root>`.

#### `travelAnimation`

See [travelAnimation](https://silkhq.com/docs/sheet.md#outlet-travelanimation) on `<Sheet.Outlet>`.

#### `stackingAnimation`

See [stackingAnimation](https://silkhq.com/docs/sheet.md#outlet-stackinganimation) on `<Sheet.Outlet>`.

### `<Sheet.SpecialWrapper.Root>`

| Characteristic     | Details                                          |
| ------------------ | ------------------------------------------------ |
| Presence           | Required when using the SpecialWrapper component |
| Composition        | Child of `<Sheet.Content>`                       |
| Underlying element | `<div>`                                          |

##### Description

This sub-component allows to workaround a bug that prevents swiping in Safari when both:

- the `inertOutside` prop on `<Sheet.View>` is set to `false`;
- the Backdrop sub-component is not present, or it is present but its `swipeable` prop is set to `false`.

##### Notes

- There is two limitations caused by the use this sub-component:
   - The underlying element makes use of the `overflow` CSS property with a value other than `visible`, causing any content overflowing its bound to be clipped.
   - When swiping over the underlying element in the cross axis of the Sheet, and then in the travel axis without initiating a new swipe, sheet travel will not occur.

#### `asChild`

See [asChild](https://silkhq.com/docs/sheet.md#root-aschild) on `<Sheet.Root>`.

### `<Sheet.SpecialWrapper.Content>`

| Characteristic     | Details                                          |
| ------------------ | ------------------------------------------------ |
| Presence           | Required when using the SpecialWrapper component |
| Composition        | Child of `<Sheet.SpecialWrapper.Root>`           |
| Underlying element | `<div>`                                          |

##### Description

The Content sub-component to be used in combination with `<Sheet.SpecialWrapper.Root>`.

#### `asChild`

See [asChild](https://silkhq.com/docs/sheet.md#root-aschild) on `<Sheet.Root>`.

---

---
title: "Scroll · Silk"
description: "API reference for the Scroll component."
Source: https://silkhq.com/docs/scroll.md
---

## Description

A primitive component for building advanced scrolling experiences. It provides extra features compared to normal scroll containers, as well as performance optimizations when used inside or around a Sheet component.

We recommend using the Scroll component for all scrolling across your app.

## Anatomy

```tsx
import { Scroll } from "@silk-hq/sheet";

export default () => (
	<Scroll.Root>
		<Scroll.View>
			<Scroll.Content>
				...
			</Scroll.Content>
		</Scroll.View>

		<Scroll.Trigger />
	</Scroll.Root>
);
```

## Sub-components

### `<Scroll.Root>`

| Characteristic     | Details                                 |
| ------------------ | --------------------------------------- |
| Presence           | Required                                |
| Composition        | Contain all other Scroll sub-components |
| Underlying element | `<div>`                                 |

##### Description

The Root sub-component wraps all other Scroll sub-components of the same Scroll instance, as it contains logic shared among all.

#### `asChild`

| Characteristic | Details                |
| -------------- | ---------------------- |
| **Presence**   | Optional               |
| **Type**       | `boolean \| undefined` |
| **Default**    | `undefined`            |

##### Description

Defines whether the sub-component underlying element is the default one or the one passed as child of the sub-component.

##### Values description

| Value                | Description                                         |
| -------------------- | --------------------------------------------------- |
| `true`               | The underlying element rendered is the child.       |
| `false \| undefined` | The underlying element rendered is the default one. |

##### Notes

- If the child is a React component rendering an element:
   - it must accept props and spread all received props onto the rendered element;
   - in React < 19, it must use `React.forwardRef()` and pass the received ref to the rendered element.
- See [Composition](https://silkhq.com/docs/composition.md) for more information.

#### `componentId`

| Characteristic | Details     |
| -------------- | ----------- |
| **Presence**   | Optional    |
| **Type**       | `ScrollId`  |
| **Default**    | `undefined` |

##### Description

Defines the id of the Scroll component instance. This id can then be passed to other Scroll sub-components `forComponent` prop to associate them with it.

#### `componentRef`

| Characteristic | Details                                                                                                                                                                                                                                                                                                                                                                                                                   |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Presence**   | Optional                                                                                                                                                                                                                                                                                                                                                                                                                  |
| **Type**       | `React.RefObject<ScrollRef>` where `ScrollRef` is:<br>`ts:{ getProgress: () => number; getDistance: () => number; getAvailableDistance: () => number; scrollTo: (options: ScrollToOptions) => void; scrollBy: (options: ScrollByOptions) => void; }` <br>where `ts:ScrollToOptions = ScrollByOptions` is: <br>`ts:{progress?: number; distance?: number; animationSettings?: { skip: "default" \| "auto" \| boolean }; }` |
| **Default**    | `undefined`                                                                                                                                                                                                                                                                                                                                                                                                               |

##### Description

Associates a `React.RefObject` to `<Scroll.Root>` which can then be used to control the Scroll component imperatively by calling the methods stored in it.

##### Methods description

| Value                  | Description                                                                                                                                                                                                          |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `getProgress`          | Returns the scroll progress from `0` to `1`. When `<Scroll.Content>` start edge is aligned with `<Scroll.View>` start edge, scroll progress is `0`. When they are aligned on their end edge, scroll progress is `1`. |
| `getDistance`          | Returns the distance in pixels traveled by `<Scroll.Content>` from its start position.                                                                                                                               |
| `getAvailableDistance` | Returns the distance in pixels that `<Scroll.Content>` can travel in total, from its start position to its end position.                                                                                             |
| `scrollTo`             | Make `<Scroll.Content>` travel so it ends up at the defined `progress` or `distance`.                                                                                                                                |

If the `animationSettings` `skip` key value computes to `false`, then animation occurs; if it computes to `true` the animation is skipped. `"default"` computes to the value provided in the `scrollAnimationSettings` prop on `<Scroll.View>`. `"auto"` computes to `true` when the user has prefers-reduced-motion enabled, and computes to `false` otherwise. |
| `scrollBy` | Make the `<Scroll.Content>` travel by the defined `progress` or `distance`.

If the `animationSettings` `skip` key value computes to `false`, then animation occurs; if it computes to `true` the animation is skipped. `"default"` computes to the value provided in the `scrollAnimationSettings` prop on `<Scroll.View>`. `"auto"` computes to `true` when the user has prefers-reduced-motion enabled, and computes to `false` otherwise. |

### `<Scroll.Trigger>`

| Characteristic     | Details                       |
| ------------------ | ----------------------------- |
| Presence           | Required                      |
| Composition        | Descendant of `<Scroll.Root>` |
| Underlying element | `<button>`                    |

##### Description

A Trigger sub-component that allows to run specific actions related to the Scroll instance as a result of a press event.

#### `asChild`

See [asChild](https://silkhq.com/docs/scroll.md#root-aschild) on `<Scroll.Root>`.

#### `forComponent`

| Characteristic | Details                                                 |
| -------------- | ------------------------------------------------------- |
| **Presence**   | Optional                                                |
| **Type**       | `ScrollId`                                              |
| **Default**    | The `ScrollId` of the closest `<Scroll.Root>` ancestor. |

##### Description

Associates this sub-component with the desired Scroll instance.

#### `action`

| Characteristic | Details                                                                                                                                        |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| **Presence**   | Optional                                                                                                                                       |
| **Type**       | `ts:{ type: "scroll-to" \| "scroll-by"; progress?: number; distance?: number; animationSettings?: { skip: "default" \| "auto" \| boolean }; }` |
| **Default**    | `undefined`                                                                                                                                    |

##### Description

Defines the action that will execute when the Trigger is pressed.

##### Values description

| Value         | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `"scroll-to"` | Make `<Scroll.Content>` travel so it ends up at the defined `progress` or `distance`. <br><br>If the `animationSettings` `skip` key value computes to `false`, then animation occurs, if it computes to `false` the animation is skipped. `"default"` computes to the value provided in the `scrollAnimationSettings` prop on `<Scroll.View>`. `"auto"` computes to `true` when the user has prefers-reduced-motion enabled, it computes to `false` otherwise. |
| `"scroll-by"` | Make `<Scroll.Content>` travel by the defined `progress` or `distance`. <br><br>If the `animationSettings` `skip` key value computes to `false`, then animation occurs, if it computes to `false` the animation is skipped. `"default"` computes to the value provided in the `scrollAnimationSettings` prop on `<Scroll.View>`. `"auto"` computes to `true` when the user has prefers-reduced-motion enabled, and computes to `false` otherwise.              |

#### `onPress`

| Characteristic | Details                                                                                                                                                                                                                            |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Presence**   | Optional                                                                                                                                                                                                                           |
| **Type**       | `ts:{ forceFocus?: boolean; runAction?: boolean } \| ((customEvent: { changeDefault: (changedBehavior: { forceFocus?: boolean; runAction?: boolean }) => void; nativeEvent: React.MouseEvent<HTMLElement, MouseEvent> }) => void)` |
| **Default**    | `{ forceFocus: true, runAction: true }`                                                                                                                                                                                            |

##### Description

An event handler that runs when the Trigger is pressed (equivalent to clicked).

The underlying custom event has a default behavior that can be changed either by calling its `changeDefault` method with an option object as parameter, or by directly passing the option object to the prop.

##### Values description

| Value                   | Description                                                                                                                                                               |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `{ forceFocus: true }`  | The underlying element will be focused on press in all browsers (by default Safari doesn’t do it, causing issues with focus management). This is the recommended setting. |
| `{ forceFocus: false }` | Inverse of `true`.                                                                                                                                                        |
| `{ runAction: true }`   | The Trigger action will be run.                                                                                                                                           |
| `{ runAction: false }`  | Inverse of `true`.                                                                                                                                                        |

##### Example

```tsx
<Scroll.Trigger onPress={{ forceFocus: false }}>
	...
</Scroll.Trigger>
```

```tsx
<Scroll.Trigger
  onPress={(event) => event.changeDefault({ forceFocus: false })}
 >
	...
</Scroll.Trigger>
```

### `<Scroll.View>`

| Characteristic     | Details                       |
| ------------------ | ----------------------------- |
| Presence           | Required                      |
| Composition        | Descendant of `<Scroll.Root>` |
| Underlying element | `<div>`                       |

##### Description

The View sub-component is the area inside of which the `<Scroll.Content>` can travel.

##### Notes

- Elements put directly inside of this sub-component will not move along the content as scroll occurs.
- If you are using this component inside of nested CSS grid or flex containers, you may need to add `css:min-width: 0px` and/or `css:min-height: 0px` on these containers’ children to prevent `<Scroll.View>` being sized based on `<Scroll.Content>` size on the scroll axis, thus causing visible overflow instead of a scrollable overflow.

#### `asChild`

See [asChild](https://silkhq.com/docs/scroll.md#root-aschild) on `<Scroll.Root>`.

#### `forComponent`

| Characteristic | Details                                                 |
| -------------- | ------------------------------------------------------- |
| **Presence**   | Optional                                                |
| **Type**       | `ScrollId`                                              |
| **Default**    | The `ScrollId` of the closest `<Scroll.Root>` ancestor. |

##### Description

Associates this sub-component with the desired Scroll instance.

#### `axis`

| Characteristic | Details      |
| -------------- | ------------ |
| **Presence**   | Optional     |
| **Type**       | `"x" \| "y"` |
| **Default**    | `"y"`        |

##### Description

Defines the axis on which `<Scroll.Content>` can travel.

##### Notes

In macOS Safari, when `pageScroll` is set to `true` and `nativePageScrollReplacement` computes to `false`, it is possible to cause scroll overshoot on the non-scrolling axis with a scroll gesture. The only way to prevent this behavior is to set `nativePageScrollReplacement` to `true`.

#### `pageScroll`

| Characteristic | Details                                                                 |
| -------------- | ----------------------------------------------------------------------- |
| **Presence**   | Required if `nativePageScrollReplacement` is set to `true` or `"auto"`. |
| **Type**       | `boolean`                                                               |
| **Default**    | `false`                                                                 |

##### Description

Defines whether this Scroll component is considered as a page.

When set to `true`, this Scroll can be used to control page scrolling (no matter whether it is native or replaced). Therefore, you can use a `<Scroll.Trigger>`, or imperative methods to get scroll informations or cause scrolling. You can therefore use the exact same API to control any scroll container and page scrolling.

##### Values description

| Value   | Description                                                                                                                                                                                                                                                                                                                                                                                                                |
| ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `false` | The underlying element acts a scroll container.                                                                                                                                                                                                                                                                                                                                                                            |
| `true`  | Page scrolling can be controlled through this Scroll component instance. <br><br>- If `nativePageScrollReplacement` computes to `false`, the `<Scroll.View>` underlying element does not act as a scroll container, instead it acts as a simple element. <br><br>- If `nativePageScrollReplacement` computes to `true`, the `<Scroll.View>` underlying element acts as a scroll container replacing native page scrolling. |

#### `nativePageScrollReplacement`

| Characteristic   | Details                                                                                                                                                                                              |
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Presence**     | Optional                                                                                                                                                                                             |
| **Type**         | `"auto" \| boolean`                                                                                                                                                                                  |
| **Default**      | `false`                                                                                                                                                                                              |
| **Requirements** | - `pageScroll` must be set to `true` to use this prop with a value of `true` or `"auto"`. <br>- With SSG or SSR, when set to `true` or `"auto"`, `suppressHydrationWarning` must be set on `<html>`. |

##### Description

Defines whether native page scrolling (a.k.a. “body scrolling”) is being replaced by the Scroll component scroll container.

##### Values description

| Value    | Description                                                                                                                       |
| -------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `true`   | Native page scrolling is replaced by the Scroll component scroll container.                                                       |
| `false`  | Inverse of `true`.                                                                                                                |
| `"auto"` | Computes to `false` in mobile browsers (i.e. Android, iOS iPadOS), except in standalone mode; computes to `true` everywhere else. |

##### Notes

- When computing to `true`:
   - **Benefits**:
      - Prevents elements viewport shift when the on-screen keyboard appears.
      - Prevents native pull-down to refresh on iOS.
      - Prevents scroll overshoot on the non-scrolling axis in macOS Safari.
      - Improves animation performance when animating `<Scroll.View>` or ancestors.
      - Swiping over elements with `css:position: fixed` doesn’t cause page scrolling.
   - **Limitations** (use `"auto"` to work around them in mobile browsers):
      - Native scroll into view for text fragments (e.g. `#:~:text=example`) does not work.
      - Native scroll into view for anchors (e.g. `#anchor-id`) does not work.
      - Native scroll to top by tapping the status bar does not work on iOS.
      - Native pull-down to refresh does not work on iOS.
      - Mobile browser UIs don't collapse as the user scrolls.
- The [`useNativePageScrollReplaced`](https://silkhq.com/docs/use-page-scroll-data.md) hook returns a `boolean` indicating whether native page scroll is currently replaced.

#### `safeArea`

| Characteristic | Details                                            |
| -------------- | -------------------------------------------------- |
| **Presence**   | Optional                                           |
| **Type**       | `"none" \| "layout-viewport" \| "visual-viewport"` |
| **Default**    | `"visual-viewport"`                                |

##### Description

Defines the area of the viewport that is considered safe for `<Scroll.Content>` to travel within. If `<Scroll.View>` overflows this area, then the available scroll distance is increased so that `<Scroll.Content>` can travel as much as required for it to be fully accessible to the user.

For example, if `<Scroll.View>` fills the entire layout viewport, then when the on-screen keyboard appears and the visual viewport shrinks, the bottom part of the `<Scroll.View>` underlying HTML will be hidden behind the on-screen keyboard, and the `<Scroll.Content>` will not be fully accessible to the user. By setting this prop to `"visual-viewport"`, the scrolling distance gets expanded so `<Scroll.Content>` can travel as much as needed to be entirely visible above the on-screen keyboard.

##### Values description

| Value               | Description                                                                                                                                         |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `"none"`            | No safe area is defined.                                                                                                                            |
| `"layout-viewport"` | The safe area is defined by the bounds of the layout viewport (i.e. the browser window excluding the browser interface).                            |
| `"visual-viewport"` | The safe area is defined by the bounds of the visual viewport (i.e. the browser window excluding the browser interface and the on-screen keyboard). |

#### `scrollGestureTrap`

| Characteristic | Details                                                                                                                  |
| -------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **Presence**   | Optional                                                                                                                 |
| **Type**       | `ts:boolean \| { x?: boolean; y?: boolean; } \| { xStart?: boolean; xEnd?: boolean; yStart?: boolean; yEnd?: boolean; }` |
| **Default**    | `false`                                                                                                                  |

##### Description

Defines whether scroll gestures performed in a direction where further scrolling cannot occur (because the edge has been reached, or because there is no overflow) should be trapped inside of `<Scroll.View>`, or propagate to the page, ancestor scroll containers, or Sheets, causing swipe.

##### Notes

- Contrary to the `css:overscroll-behavior` CSS property in most browsers, this mechanism works even when there is no scroll overflow.
- When trapping is enabled, native overscroll actions are prevented (except when using native page scrolling in Safari). For example, if trapping is enabled on `yStart`, pull to refresh in mobile browsers is prevented; if it is enabled on `xStart`, swipe to go back in history in desktop browsers is prevented.
- If `scrollGestureOvershoot` is set to `false`, then `scrollGestureTrap` always computes to `true`.
- Due to a Safari bug, trapping is always enabled when swiping over a vertical Scroll component wrapped in an horizontally swipeable Sheet itself wrapped in a vertically swipeable Sheet component. We hope to see that bug resolved quickly.

#### `scrollGestureOvershoot`

| Characteristic | Details   |
| -------------- | --------- |
| **Presence**   | Optional  |
| **Type**       | `boolean` |
| **Default**    | `true`    |

##### Description

Defines the visual behavior of `<Scroll.Content>` when the user performs a scroll gesture in a direction where scrolling cannot occur (because the edge has been reached).

##### Values description

| Value   | Description          |
| ------- | -------------------- |
| `true`  | Overshooting occurs. |
| `false` | Inverse of `true`.   |

##### Notes

- Only iOS/iPadOS browsers and Safari and Firefox on macOS support overshooting.
- If `scrollGestureOvershoot` is set to `false`, then `scrollGestureTrap` always computes to `true`.

#### `scrollGesture`

| Characteristic | Details   |
| -------------- | --------- |
| **Presence**   | Optional  |
| **Type**       | `boolean` |
| **Default**    | `"auto"`  |

##### Description

Defines whether scrolling occurs as a result of user scroll gestures (`mousewheel` events, `touchmove` events, direction keys, start/end keys, dragging the scrollbar, etc.).

##### Values description

| Value    | Description                                                                                           |
| -------- | ----------------------------------------------------------------------------------------------------- |
| `"auto"` | Scrolling occurs as a result of user scroll gestures if `<Scroll.Content>` overflows `<Scroll.View>`. |
| `false`  | Scrolling does not occur as a result of user scroll gestures.                                         |

##### Notes

In iOS browsers (all using WebKit under the hood), when `pageScroll` is set to `true` and `nativePageScrollReplacement` computes to `false`, Apple is intentionnally preventing `scrollGesture={false}` from working reliably. You can use `nativePageScrollReplacement={true}` to work around this limitation.

#### `onScroll`

| Characteristic | Details                                                                                                                             |
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| **Presence**   | Optional                                                                                                                            |
| **Type**       | `ts:(args: { progress: number; distance: number; availableDistance: number; nativeEvent: React.UIEvent<HTMLDivElement>; }) => void` |
| **Default**    | `undefined`                                                                                                                         |

##### Description

An event handler that runs asynchronously on every frame when scrolling occurs, whether it is caused by a scroll gesture or programmatically.

##### Parameters description

| Value               | Description                                                                                                                                                                                                  |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `progress`          | The scroll progress from `0` to `1`. When `<Scroll.Content>` start edge is aligned with `<Scroll.View>` start edge, scroll progress is `0`. When they are aligned on their end edge, scroll progress is `1`. |
| `distance`          | The distance in pixels traveled by `<Scroll.Content>` from its start position.                                                                                                                               |
| `availableDistance` | The distance in pixels that `<Scroll.Content>` can travel in total, from its start position to its end position.                                                                                             |
| `nativeEvent`       | The underlying native scroll event.                                                                                                                                                                          |

#### `onScrollStart`

| Characteristic | Details                                                                                                                                                                                                                                                      |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Presence**   | Optional                                                                                                                                                                                                                                                     |
| **Type**       | `ts:{ dismissKeyboard: boolean } \| ((customEvent: ScrollStartCustomEvent) => void` <br>where `ScrollStartCustomEvent` is <br>`ts:{ changeDefault: (changedBehavior: { dismissKeyboard: boolean; }) => void; dismissKeyboard: boolean; nativeEvent: null; }` |
| **Default**    | `{ dismissKeyboard: false }`                                                                                                                                                                                                                                 |

##### Description

An event handler that runs when scrolling starts, whether it is initiated by a scroll gesture or programmatically.

The underlying custom event has a default behavior that can be changed either by calling its `changeDefault` method with an option object as parameter, or by directly passing the option object to the prop.

##### Values description

| Value                        | Description                                                                               |
| ---------------------------- | ----------------------------------------------------------------------------------------- |
| `{ dismissKeyboard: true }`  | Causes the on-screen keyboard to be dismissed if it is presented when the event is fired. |
| `{ dismissKeyboard: false }` | Inverse of `{ dismissKeyboard: true }`.                                                   |

##### Example

```tsx
<Scroll.View onFocusInside={{ dismissKeyboard: true }}>
	...
</Scroll.View>
```

```tsx
<Sheet.View
  onFocusInside={(event) => event.changeDefault({ dismissKeyboard: true })}
 >
	...
</Sheet.View>
```

#### `onScrollEnd`

| Characteristic | Details                               |
| -------------- | ------------------------------------- |
| **Presence**   | Optional                              |
| **Type**       | `ts:({ nativeEvent: Event }) => void` |
| **Default**    | `undefined`                           |

##### Description

An event handler that runs when scrolling ends, whether it was initiated by a scroll gesture or programmatically.

#### `nativeFocusScrollPrevention`

| Characteristic | Details   |
| -------------- | --------- |
| **Presence**   | Optional  |
| **Type**       | `boolean` |
| **Default**    | `true`    |

##### Description

Defines whether the native scroll into view mechanism should be prevented or not when a `<Scroll.View>` descendant element receives focus.

When an element receives focus on mobile, the browser shifts the viewport up or down to try and keep it in view. Unfortunately, this native mechanism doesn’t work well in most situations, so we let you prevent the default behavior to properly deal with the position of the focused element. We recommend using the `onFocusInside` to do so.

##### Notes

- The prevention doesn’t work when the inputs are inside of an `<iframe>` element.
- When the user clicks on text present in a text input, the caret will always be put back at its previous position when set to `true`.
- In iOS Safari, the prevention may not be effective with password inputs whose `autoComplete` html attribute is set to anything else than `"current-password"`. Therefore, we strongly recommend always using this value. Safari won’t suggest a new password directly, but the user can still get a suggested password by tapping the “Password” button in the suggestion bar and asking the password manager to provide a new password.
- Due to a Chromium Android bug, the prevention won’t work when the `scrollIntoView` option on `onFocusInside` is set to `false`. Please consider voting and commenting on the [Chromium issue](https://issues.chromium.org/issues/41492445) so it gets prioritized.
- Due to a Chromium Android bug, the prevention may not be effective when the focus is moved with the on-screen keyboard “next input” button. Please consider voting and commenting on the [Chromium issue](https://issues.chromium.org/issues/41492445) so it gets prioritized.
- Due to a Chrome Android bug, for inputs causing the suggestion bar of the keyboard to be shown, a distance of at least 48px between the last text input and the bottom of the viewport is required to avoid a layout shift.

#### `onFocusInside`

| Characteristic | Details                                                                                                                                                                                                                                                                          |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Presence**   | Optional                                                                                                                                                                                                                                                                         |
| **Type**       | `ts:{ scrollIntoView: boolean; } \| ((customEvent: ScrollViewFocusInsideCustomEvent) => void);` <br>where `ScrollViewFocusInsideCustomEvent` is <br>`ts:{ changeDefault: (changedBehavior: { scrollIntoView: boolean }) => void; scrollIntoView: boolean; nativeEvent: Event; }` |
| **Default**    | `{ scrollIntoView: true }`                                                                                                                                                                                                                                                       |

##### Description

An event handler that runs when a `<Scroll.View>` descendant element receives focus.

The underlying custom event has a default behavior that can be changed either by calling its `changeDefault` method with an option object as parameter, or by directly passing the option object to the prop.

##### Values description

| Value                       | Description                                                               |
| --------------------------- | ------------------------------------------------------------------------- |
| `{ scrollIntoView: true }`  | The element receiving focus is scrolled into view so it is fully visible. |
| `{ scrollIntoView: false }` | Inverse of `{ scrollIntoView: true }`.                                    |

##### Notes

- The `scrollIntoView` option is a reliable alternative to the native scroll into view on focus mechanism that can disabled with `nativeFocusScrollPrevention`.
- The `scrollIntoView` option takes the `safeArea` into account.
- Due to a Chrome Android bug, the `nativeFocusScrollPrevention` mechanism won’t work when using `{ scrollIntoView: false }`. Please consider voting and commenting on the [Chromium issue](https://issues.chromium.org/issues/41492445) so it gets prioritized.

##### Example

```tsx
<Scroll.View onFocusInside={{ scrollIntoView: false }}>
	...
</Scroll.View>
```

```tsx
<Sheet.View
  onFocusInside={(event) => event.changeDefault({ scrollIntoView: false })}
 >
	...
</Sheet.View>
```

#### `scrollAnimationSettings`

| Characteristic | Details                       |
| -------------- | ----------------------------- |
| **Presence**   | no                            |
| **Type**       | `{ skip: "auto" \| boolean }` |
| **Default**    | `{ skip: "auto" }`            |

##### Description

Defines the animation settings for programmatic scrolling (i.e. scroll caused by `<Scroll.Trigger>` or an imperative call).

##### Values description

| Value              | Description                                                                           |
| ------------------ | ------------------------------------------------------------------------------------- |
| `{ skip: "auto" }` | Programmatic scrolling is animated only if the user does not prefer “reduced motion”. |
| `{ skip: false }`  | Programmatic scrolling is animated.                                                   |
| `{ skip: true }`   | Inverse of `{ skip: false }`.                                                         |

#### `scrollAnchoring`

| Characteristic | Details   |
| -------------- | --------- |
| **Presence**   | Optional  |
| **Type**       | `boolean` |
| **Default**    | `true`    |

##### Description

Defines whether the scroll position should be adjusted to prevent sudden changes when a layout shift occurs inside of `<Scroll.Content>`.

##### Notes

- Uses the [`css:overflow-anchor` CSS property](https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-anchor) under the hood.
- Not yet supported in Safari.

#### `scrollSnapType`

| Characteristic | Details                                |
| -------------- | -------------------------------------- |
| **Presence**   | Optional                               |
| **Type**       | `"none" \| "proximity" \| "mandatory"` |
| **Default**    | `"none"`                               |

##### Description

Defines the value for the [`css:scroll-snap-type` CSS property](https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-snap-type).

#### `scrollPadding`

| Characteristic | Details                         |
| -------------- | ------------------------------- |
| **Presence**   | Optional                        |
| **Type**       | `"auto" \| string` (CSS length) |
| **Default**    | `"auto"`                        |

##### Description

Defines the value for the [`css:scroll-padding`](https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-padding) [CSS property](https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-snap-type).

#### `scrollTimelineName`

| Characteristic | Details                                 |
| -------------- | --------------------------------------- |
| **Presence**   | Optional                                |
| **Type**       | `"none" \| string` (prefixed with "--") |
| **Default**    | `"none"`                                |

##### Description

Defines the value for the [`css:scroll-timeline-name`](https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-timeline-name) [CSS property](https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-snap-type).

#### `nativeScrollbar`

| Characteristic | Details   |
| -------------- | --------- |
| **Presence**   | Optional  |
| **Type**       | `boolean` |
| **Default**    | `true`    |

##### Description

Defines whether the native scrollbar should be displayed or not.

### `<Scroll.Content>`

| Characteristic     | Details                       |
| ------------------ | ----------------------------- |
| Presence           | Required                      |
| Composition        | Descendant of `<Scroll.View>` |
| Underlying element | `<div>`                       |

##### Description

The Content sub-component represents the content that moves as scroll occurs.

#### `asChild`

See [asChild](https://silkhq.com/docs/scroll.md#root-aschild) on `<Scroll.Root>`.

## Imperative handling

You can manipulate imperatively the Scroll component by passing a React ref to the `<Scroll.Root>` sub-component `componentRef` prop and then calling the methods stored on it.

#### `getProgress`

| Characteristic | Details        |
| -------------- | -------------- |
| **Type**       | `() => number` |

##### Description

Returns the scroll progress from `0` to `1`. When `<Scroll.Content>` start edge is aligned with `<Scroll.View>` start edge, scroll progress is `0`. When they are aligned on their end edge, scroll progress is `1`.

#### `getDistance`

| Characteristic | Details        |
| -------------- | -------------- |
| **Type**       | `() => number` |

##### Description

Returns the distance in pixels traveled by `<Scroll.Content>` from its start position.

#### `getAvailableDistance`

| Characteristic | Details        |
| -------------- | -------------- |
| **Type**       | `() => number` |

##### Description

Returns the distance in pixels that `<Scroll.Content>` can travel in total, from its start position to its end position.

#### `scrollTo`

| Characteristic | Details                                                                                                                                                                                        |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Type**       | `scrollTo: (options: ScrollToOptions) => void` <br>where `ScrollToOptions` is <br>`ts:{ progress?: number; distance?: number; animationSettings?: { skip: "default" \| "auto" \| boolean }; }` |

##### Description

Make `<Scroll.Content>` travel so it ends up at the defined `progress` or `distance`.

If the `animationSettings` `skip` key value computes to `false`, then animation occurs; if it computes to `true` the animation is skipped. `"default"` computes to the value provided in the `scrollAnimationSettings` prop on `<Scroll.View>`. `"auto"` computes to `true` when the user has prefers-reduced-motion enabled, and computes to `false` otherwise.

#### `scrollBy`

| Characteristic | Details                                                                                                                                                                                        |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Type**       | `scrollTo: (options: ScrollByOptions) => void` <br>where `ScrollByOptions` is <br>`ts:{ progress?: number; distance?: number; animationSettings?: { skip: "default" \| "auto" \| boolean }; }` |

##### Description

Make `<Scroll.Content>` travel by the defined `progress` or `distance`.

If the `animationSettings` `skip` key value computes to `false`, then animation occurs; if it computes to `true` the animation is skipped. `"default"` computes to the value provided in the `scrollAnimationSettings` prop on `<Scroll.View>`. `"auto"` computes to `true` when the user has prefers-reduced-motion enabled, and computes to `false` otherwise.

---

---
title: "SheetStack · Silk"
description: "API reference for the SheetStack component."
Source: https://silkhq.com/docs/sheet-stack.md
---

## Description

A component that groups together several Sheets and enable the definition of stacking-driven animations (i.e. animations based on the travel of Sheets stacked on top of each other).

##### Notes

The Sheets can be either siblings or nested.

##### Current limitation

- Sheets which are part of a SheetStack can only be dismissed when they are frontmost (i.e. at the top of the stack). This limitation will be lifted in the future.

## Anatomy

### Sibling sheets

```tsx
import { Sheet, SheetStack } from "@silk-hq/components";

export default () => (
	<SheetStack.Root>
		<SheetStack.Outlet />

		<Sheet.Root>
			<Sheet.Trigger />
			<Sheet.Portal>
				<Sheet.View>
					<Sheet.Backdrop />
					<Sheet.Content>
						<Sheet.Title />
						<Sheet.Description />
					</Sheet.Content>
				</Sheet.View>
			</Sheet.Portal>
		</Sheet.Root>

		<Sheet.Root>
			<Sheet.Trigger />
			<Sheet.Portal>
				<Sheet.View>
					<Sheet.Backdrop />
					<Sheet.Content>
						<Sheet.Title />
						<Sheet.Description />
					</Sheet.Content>
				</Sheet.View>
			</Sheet.Portal>
		</Sheet.Root>
	</SheetStack.Root>
);
```

### Nested sheets

```tsx
import { Sheet, SheetStack } from "@silk-hq/components";

export default () => (
	<SheetStack.Root>
		<SheetStack.Outlet />

		<Sheet.Root>
			<Sheet.Trigger />
			<Sheet.Portal>
				<Sheet.View>
					<Sheet.Backdrop />
					<Sheet.Content>
						<Sheet.Title />
						<Sheet.Description />

						{/* Nested sheet */}
						<Sheet.Root>
							<Sheet.Trigger />
							<Sheet.Portal>
								<Sheet.View>
									<Sheet.Backdrop />
									<Sheet.Content>
										<Sheet.Title />
										<Sheet.Description />
									</Sheet.Content>
								</Sheet.View>
							</Sheet.Portal>
						</Sheet.Root>

					</Sheet.Content>
				</Sheet.View>
			</Sheet.Portal>
		</Sheet.Root>
   </SheetStack.Root>
);
```

## Sub-components

### `<SheetStack.Root>`

| Characteristic     | Details                                                                              |
| ------------------ | ------------------------------------------------------------------------------------ |
| Presence           | Required                                                                             |
| Composition        | - Contains all SheetStack sub-components<br>- contains all associated `<Sheet.Root>` |
| Underlying element | `<div>`                                                                              |

##### Description

The Root sub-component wraps all other sub-components of the same SheetStack instance as well as the associated Sheet instances’ `<Sheet.Root>` sub-components.

#### `asChild`

| Characteristic | Details                |
| -------------- | ---------------------- |
| **Presence**   | Optional               |
| **Type**       | `boolean \| undefined` |
| **Default**    | `undefined`            |

##### Description

Defines whether the sub-component underlying element is the default one or the one passed as child of the sub-component.

##### Values description

| Value                | Description                                         |
| -------------------- | --------------------------------------------------- |
| `true`               | The underlying element rendered is the child.       |
| `false \| undefined` | The underlying element rendered is the default one. |

##### Notes

- If the child is a React component rendering an element:
   - it must accept props and spread all received props onto the rendered element;
   - in React < 19, it must use `React.forwardRef()` and pass the received ref to the rendered element.
- See [Composition](https://silkhq.com/docs/composition.md) for more information.

#### `componentId`

| Characteristic | Details        |
| -------------- | -------------- |
| **Presence**   | Optional       |
| **Type**       | `SheetStackId` |
| **Default**    | `undefined`    |

##### Description

Defines the id of this SheetStack. This id can then be passed to `<Sheet.Root>`, or `<Island.Root>` `forComponent` prop to associate them with this SheetStack.

### `<SheetStack.Outlet>`

| Characteristic     | Details                      |
| ------------------ | ---------------------------- |
| Presence           | Optional                     |
| Composition        | Child of `<SheetStack.Root>` |
| Underlying element | `<div>`                      |

##### Description

A sub-component that allows to declaratively define animations for the underlying element based on the stacking progress of the associated SheetStack.

#### `asChild`

See [asChild](https://silkhq.com/docs/sheet-stack.md#root-aschild) on `<SheetStack.Root>`.

#### `forComponent`

| Characteristic | Details                                                        |
| -------------- | -------------------------------------------------------------- |
| **Presence**   | Optional                                                       |
| **Type**       | `SheetStackId \| "closest"`                                    |
| **Default**    | The `SheetStackId` of the closest `<SheetStack.Root>` ancestor |

##### Description

Associates this sub-component with the desired SheetStack instance.

#### `stackingAnimation`

| Characteristic | Details                                                                                                                                                                                                           |
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Presence**   | Optional                                                                                                                                                                                                          |
| **Type**       | `ts:{ [property: string]: [string \| number, string \| number] \| ((args: { progress: number; tween: (start: number \| string, end: number \| string) => string; }) => string \| number \| null \| undefined); }` |
| **Default**    | `undefined`                                                                                                                                                                                                       |

##### Description

Declaratively defines animations on any CSS property of the underlying element driven by the aggregated travel of Sheets stacked above the first Sheet belonging to the associated SheetStack.

##### Values description for each key

| Value                                                                                                   | Description                                                                                                                                                                                                                                                                                                                         |
| ------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `[string \| number, string \| number]`                                                                  | **Keyframes array syntax.** As Sheets travel and get stacked on top of the first Sheet added to the SheetStack, the underlying element will have its related CSS property animated from the first to the second value in the array, each value in-between being interpolated linearly.                                              |
| `ts:(args: { tween: (start: number \| string, end: number \| string) => string; }) => string \| number` | **Function syntax.** As Sheets travel and get stacked on top of the first Sheet added to the SheetStack, the underlying element will have its related CSS property animated based on the value returned by the function. The progress value goes from 0 to n (n being the number of Sheets stacked on top of the associated Sheet). |
| `string`                                                                                                | **String syntax.** As Sheets get stacked on top of the first Sheet added to the SheetStack, the underlying element will have its related CSS property set to the defined value.                                                                                                                                                     |
| `null \| undefined`                                                                                     | The underlying element related CSS property will not be animated or set.                                                                                                                                                                                                                                                            |

##### Notes

- CSS properties must be written in camelcase form (e.g. `borderRadius`).
- All individual components of the `transform` CSS property can be used separately.
   - **List**
      ```tsx
      | "translate"
      | "translateX"
      | "translateY"
      | "translateZ"
      | "scale"
      | "scaleX"
      | "scaleY"
      | "scaleZ"
      | "rotate"
      | "rotateX"
      | "rotateY"
      | "rotateZ"
      | "skew"
      | "skewX"
      | "skewY"
      ```
- The keyframes array syntax is only supported with individual `transform` properties and `opacity`.
   - **List**. Note that, apart from `opacity`, all of the following keys will be incorporated into a single `transform` declaration.
      ```tsx
      | "opacity"
      | "translate"
      | "translateX"
      | "translateY"
      | "translateZ"
      | "scale"
      | "scaleX"
      | "scaleY"
      | "scaleZ"
      | "rotate"
      | "rotateX"
      | "rotateY"
      | "rotateZ"
      | "skew"
      | "skewX"
      | "skewY"
      ```
- Updating `stackingAnimation` won't immediately reflect visually. The new value will only apply on the next travel. This limitation will be lifted in the future.
- `stackingAnimation` is short for "stacking-driven animation".

##### Examples

```tsx
<SheetStack.Outlet
	stackingAnimation={{
		translateX: ["0px", "100px"],
	}}
/>
```

```tsx
<SheetStack.Outlet
	stackingAnimation={{
		translateX: ({ progress }) => progress * 100 + "px",
	}}
/>
```

```tsx
<SheetStack.Outlet
	stackingAnimation={{
		backgroundColor:
			({ tween }) =>
				`rgb(${tween(10, 0)}, ${tween(10, 0)}, ${tween(10, 0)})`,
	}}
/>
```

---

---
title: "AutoFocusTarget · Silk"
description: "API reference for the AutoFocusTarget component."
Source: https://silkhq.com/docs/auto-focus-target.md
---

## Description

A component that gives focus priority to a specific element when the Silk-controlled auto-focus mechanism is executed.

## Sub-components

### `<AutoFocusTarget.Root>`

| Characteristic     | Details  |
| ------------------ | -------- |
| Presence           | Required |
| Composition        | Anywhere |
| Underlying element | `<div>`  |

##### Description

The Root sub-component underlying element will receive focus in priority when the Silk-controlled auto-focus mechanism is executed, if the timing matches its `timing` prop value.

If several `<AutoFocusTarget.Root>` are present on the page and match the required criteria to receive focus, the first focusable one (i.e. whose not `disabled`, not `inert`, not outside an inertOutside Sheet, etc) is the one which will receive focus.

#### `asChild`

| Characteristic | Details                |
| -------------- | ---------------------- |
| **Presence**   | Optional               |
| **Type**       | `boolean \| undefined` |
| **Default**    | `undefined`            |

##### Description

Defines whether the sub-component underlying element is the default one or the one passed as child of the sub-component.

##### Values description

| Value                | Description                                         |
| -------------------- | --------------------------------------------------- |
| `true`               | The underlying element rendered is the child.       |
| `false \| undefined` | The underlying element rendered is the default one. |

##### Notes

- If the child is a React component rendering an element:
   - it must accept props and spread all received props onto the rendered element;
   - in React < 19, it must use `React.forwardRef()` and pass the received ref to the rendered element.
- See [Composition](https://silkhq.com/docs/composition.md) for more information.

#### `forComponent`

| Characteristic | Details     |
| -------------- | ----------- |
| **Presence**   | Optional    |
| **Type**       | `SheetId`   |
| **Default**    | `undefined` |

##### Description

Associates the AutoFocusTarget instance with the desired Sheet instance.

##### Values description

| Value       | Description                                                         |
| ----------- | ------------------------------------------------------------------- |
| `undefined` | Associates the AutoFocusTarget with all the Sheets present on page. |
| `SheetId`   | Associates the AutoFocusTarget with the Sheet whose id is passed.   |

#### `timing`

| Characteristic | Details                                                   |
| -------------- | --------------------------------------------------------- |
| **Presence**   | Required                                                  |
| **Type**       | `"present" \| "dismiss" \| Array<"present" \| "dismiss">` |

##### Description

Defines when the `<AutoFocusTarget.Root>` should be considered a target for the associated Sheet auto-focus mechanism.

##### Values description

| Value       | Description                                                                                        |
| ----------- | -------------------------------------------------------------------------------------------------- |
| `"present"` | The `<AutoFocusTarget.Root>` will be considered a target when the associated Sheet gets presented. |
| `"dismiss"` | The `<AutoFocusTarget.Root>` will be considered a target when the associated Sheet gets dismissed. |

---

---
title: "Island · Silk"
description: "API reference for the Island component."
Source: https://silkhq.com/docs/island.md
---

## Description

A component, positioned outside any `<Sheet.View>`, that allows its descendants elements to be interactive when a Sheet inert-outside mechanism is applied.

When a `<Sheet.View>` sub-component has its `inertOutside` prop set to `true`, only descendant DOM elements of its underlying element can be interacted with. This component allows to make its descendant elements interactive as well. As such, it creates “islands of interactivity” outside of the Sheet.

For example, this is useful to keep a navigation bar accessible even though a Sheet is presented.

## Anatomy

```tsx
import { Sheet, Island } from "@silk-hq/sheet";

export default () => (
   <>
      <Island.Root>
         <Island.Content>
            {* Interactive content *}
         </Island.Content>
      </Island.Root>

      <Sheet.Root>
         <Sheet.Trigger />
         <Sheet.Portal>
            <Sheet.View inertOutside={true}>
               <Sheet.Backdrop />
               <Sheet.Content>
                  {* Interactive content *}
               </Sheet.Content>
            </Sheet.View>
         </Sheet.Portal>
      </Sheet.Root>
   </>
);
```

## Sub-components

### `<Island.Root>`

| Characteristic     | Details                     |
| ------------------ | --------------------------- |
| Presence           | Required                    |
| Composition        | Contains `<Island.Content>` |
| Underlying element | `<div>`                     |

##### Description

The Root sub-component wraps and shares logic with `<Island.Content>`.

#### `asChild`

| Characteristic | Details                |
| -------------- | ---------------------- |
| **Presence**   | Optional               |
| **Type**       | `boolean \| undefined` |
| **Default**    | `undefined`            |

##### Description

Defines whether the sub-component underlying element is the default one or the one passed as child of the sub-component.

##### Values description

| Value                | Description                                         |
| -------------------- | --------------------------------------------------- |
| `true`               | The underlying element rendered is the child.       |
| `false \| undefined` | The underlying element rendered is the default one. |

##### Notes

- If the child is a React component rendering an element:
   - it must accept props and spread all received props onto the rendered element;
   - in React < 19, it must use `React.forwardRef()` and pass the received ref to the rendered element.
- See [Composition](https://silkhq.com/docs/composition.md) for more information.

#### `forComponent`

| Characteristic | Details                                                     |
| -------------- | ----------------------------------------------------------- |
| **Presence**   | Optional                                                    |
| **Type**       | `SheetId \| SheetStackId \| Array<SheetId \| SheetStackId>` |
| **Default**    | `undefined`                                                 |

##### Description

Associates the Island instance with the desired Sheet instance(s).

##### Values description

| Value                                                       | Description                                                                                       |
| ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| `undefined`                                                 | Associates the Island with all the Sheets present on page.                                        |
| `SheetId \| SheetStackId \| Array<SheetId \| SheetStackId>` | Associates the Island with the Sheet(s) and/or SheetStack(s) matching the component ids provided. |

#### `disabled`

| Characteristic | Details   |
| -------------- | --------- |
| **Presence**   | Optional  |
| **Type**       | `boolean` |
| **Default**    | `false`   |

##### Description

Defines whether the Island is disabled. If it is, it will have no effect.

#### `contentGetter`

| Characteristic | Details                                                         |
| -------------- | --------------------------------------------------------------- |
| **Presence**   | Required if `<Island.Content>` is not used                      |
| **Type**       | `(() => HTMLElement \| Element \| null \| undefined) \| string` |
| **Default**    | `undefined`                                                     |

##### Description

Defines the content of the Island with either a CSS selector or a function that returns an element instead of using `<Island.Content>`.

##### Values description

| Value                                                 | Description                                                                                                                           |
| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `(() => HTMLElement \| Element \| null \| undefined)` | A function that returns an element.                                                                                                   |
| `string` (CSS selector)                               | A `string` containing a CSS selector matching at least one element. If several element match the CSS selector, the first one is used. |

##### Notes

- This prop is useful when you are not able to wrap the element inside of `<Island.Content>`. One possible reason is that it is created outside of React (e.g. a chat plugin’s bubble).
- When using this prop, scroll is not trapped inside of the Island instance, so it is up to the element to implement some scroll trapping mechanism.

### `<Island.Content>`

| Characteristic     | Details                                                    |
| ------------------ | ---------------------------------------------------------- |
| Presence           | Required if `contentGetter` is not used on `<Island.Root>` |
| Composition        | Child of `<Island.Root>`                                   |
| Underlying element | `<div>`                                                    |

##### Description

The Content sub-component allows its descendant elements to remain interactive when associated Sheets are presented and their `inertOutside` props are set to `true`.

##### Notes

Swipe and scroll gestures are trapped inside of the underlying element.

#### `asChild`

See [asChild](https://silkhq.com/docs/island.md#root-aschild) on `<Island.Root>`.

---

---
title: "Fixed · Silk"
description: "API reference for the Fixed component."
Source: https://silkhq.com/docs/fixed.md
---

## Description

A primitive component that handles positioning in relation to the viewport. It provides extra features compared to normal CSS `css:position: fixed`.

##### Features

- Traps scrolling occurring on the underlying elements, preventing page scrolling when used in combination with a Sheet component for example.
- Preserves the visual position of the underlying element when it is a descendant of `<Sheet.Outlet>` or `<SheetStack.Outlet>` underlying elements and those have their `transform` CSS property animated during a travel or stacking animation.
- Exposes `css:--x-collapsed-scrollbar-thickness` and `css:--y-collapsed-scrollbar-thickness` CSS custom properties when page scrolling is temporarily disabled, allowing to adjust the position of the underlying elements and descendant elements to avoid visual position changes caused by the removal of the page scrollbars.

##### Notes

`<Sheet.View>` is internally wrapped inside of a Fixed component, so you can use it in the same way without having to wrap it yourself.

## Anatomy

### Basic

```tsx
import { Fixed } from "@silk-hq/sheet";

export default () => (
	<Fixed.Root>
		<Fixed.Content>
			...
		</Fixed.Content>
	</Fixed.Root>
);
```

### With `<Sheet.Outlet>`

```tsx
import { Sheet, Fixed } from "@silk-hq/sheet";

export default () => (
	<Sheet.Outlet>
		<Fixed.Root>
			<Fixed.Content>
				...
			</Fixed.Content>
		</Fixed.Root>
	</Sheet.Outlet>
);
```

## Sub-components

### `<Fixed.Root>`

| Characteristic     | Details                    |
| ------------------ | -------------------------- |
| Presence           | Required                   |
| Composition        | Contains `<Fixed.Content>` |
| Underlying element | `<div>`                    |

##### Description

The Root sub-component wraps the `<Fixed.Content>` of the same Fixed instance, as it contains shared logic.

##### Notes

- If you are setting a value to the `bottom` CSS property without using the `top` property, and/or the `right` property without using the `left` CSS property, you have to declare the property used in the `css:--silk-fixed-side` value.
   ##### Example
         ```css
         .my-fixed-element {
         	bottom: 16px;
         	right: 16px;
         	--silk-fixed-side: bottom right;
         }
         ```
- Under the hood we use CSS transform styles to maintain the position of the element. If you need to apply CSS transform styles yourself, you should do it on a descendant element to avoid any conflict.

#### `asChild`

| Characteristic | Details                |
| -------------- | ---------------------- |
| **Presence**   | Optional               |
| **Type**       | `boolean \| undefined` |
| **Default**    | `undefined`            |

##### Description

Defines whether the sub-component underlying element is the default one or the one passed as child of the sub-component.

##### Values description

| Value                | Description                                         |
| -------------------- | --------------------------------------------------- |
| `true`               | The underlying element rendered is the child.       |
| `false \| undefined` | The underlying element rendered is the default one. |

##### Notes

- If the child is a React component rendering an element:
   - it must accept props and spread all received props onto the rendered element;
   - in React < 19, it must use `React.forwardRef()` and pass the received ref to the rendered element.
- See [Composition](https://silkhq.com/docs/composition.md) for more information.

### `<Fixed.Content>`

| Characteristic     | Details                 |
| ------------------ | ----------------------- |
| Presence           | Required                |
| Composition        | Child of `<Fixed.Root>` |
| Underlying element | `<div>`                 |

##### Description

The Content sub-component represents the content of the Fixed component.

##### Notes

Scrolling is trapped inside of the underlying element.

#### `asChild`

See [asChild](https://silkhq.com/docs/fixed.md#root-aschild) on `<Fixed.Root>`.

---

---
title: "VisuallyHidden · Silk"
description: "API reference for the VisuallyHidden component."
Source: https://silkhq.com/docs/visually-hidden.md
---

## Description

A component that visually hides elements and their content but keep them accessible to screen-readers. This is useful for example in combination with `<Sheet.Title>` or a `<Sheet.Description>`.

## Sub-components

### `<VisuallyHidden.Root>`

| Characteristic     | Details  |
| ------------------ | -------- |
| Presence           | Required |
| Composition        | Anywhere |
| Underlying element | `<span>` |

##### Description

The Root sub-component wraps content to be made visually hidden.

#### `asChild`

| Characteristic | Details                |
| -------------- | ---------------------- |
| **Presence**   | Optional               |
| **Type**       | `boolean \| undefined` |
| **Default**    | `undefined`            |

##### Description

Defines whether the sub-component underlying element is the default one or the one passed as child of the sub-component.

##### Values description

| Value                | Description                                         |
| -------------------- | --------------------------------------------------- |
| `true`               | The underlying element rendered is the child.       |
| `false \| undefined` | The underlying element rendered is the default one. |

##### Notes

- If the child is a React component rendering an element:
   - it must accept props and spread all received props onto the rendered element;
   - in React < 19, it must use `React.forwardRef()` and pass the received ref to the rendered element.
- See [Composition](https://silkhq.com/docs/composition.md) for more information.

---

---
title: "ExternalOverlay · Silk"
description: "API reference for the ExternalOverlay component."
Source: https://silkhq.com/docs/external-overlay.md
---

## Description

The ExternalOverlay component communicates to the presented Sheets that an overlay component out of Silk’s control is present.

The external overlay can either be included inside of the inert-outside mechanism of the Sheets, or cause the mechanism to be disabled to avoid any potential conflict.

## Sub-components

### `<ExternalOverlay.Root>`

| Characteristic     | Details  |
| ------------------ | -------- |
| Presence           | Required |
| Composition        | Anywhere |
| Underlying element | `<div>`  |

##### Description

The Root sub-component wraps an external overlay component and allows it to either be included in associated Sheets inert-outside mechanism, or have them disable their mechanism to avoid conflicts with its own.

##### Notes

It should be mounted or have its `disabled` prop set to `false` at the same time as the wrapped overlay component gets mounted, or its own inert-outside mechanism gets set up.

#### `asChild`

| Characteristic | Details                |
| -------------- | ---------------------- |
| **Presence**   | Optional               |
| **Type**       | `boolean \| undefined` |
| **Default**    | `undefined`            |

##### Description

Defines whether the sub-component underlying element is the default one or the one passed as child of the sub-component.

##### Values description

| Value                | Description                                         |
| -------------------- | --------------------------------------------------- |
| `true`               | The underlying element rendered is the child.       |
| `false \| undefined` | The underlying element rendered is the default one. |

##### Notes

- If the child is a React component rendering an element:
   - it must accept props and spread all received props onto the rendered element;
   - in React < 19, it must use `React.forwardRef()` and pass the received ref to the rendered element.
- See [Composition](https://silkhq.com/docs/composition.md) for more information.

#### `disabled`

| Characteristic | Details   |
| -------------- | --------- |
| **Presence**   | Optional  |
| **Type**       | `boolean` |
| **Default**    | `false`   |

##### Description

Defines whether the ExternalOverlay is disabled. If it is, it will have no effect.

#### `selfManagedInertOutside`

| Characteristic | Details   |
| -------------- | --------- |
| **Presence**   | Optional  |
| **Type**       | `boolean` |
| **Default**    | `true`    |

##### Description

Indicates whether the component used inside the ExternalOverlay sets up its own inert-outside mechanism (i.e. it prevents interaction with elements outside of its bounds). If `true`, the Sheet(s) present on the page will disable their own inert-outside mechanism to avoid any conflict.

##### Notes

We run the change in a React layout effect when `<ExternalOverlay.Root>` gets mounted, or the value of the `disabled` prop changes. If the wrapped component sets up/cleans up it own mechanism in a React layout effect as well, there may be a conflict. It should be performed in a normal effect instead.

#### `contentGetter`

| Characteristic | Details                                                         |
| -------------- | --------------------------------------------------------------- |
| **Presence**   | Required if the `children` prop is not used                     |
| **Type**       | `(() => HTMLElement \| Element \| null \| undefined) \| string` |

##### Description

Defines the content of the ExternalOverlay with either a CSS selector or a function that returns an element instead of using the `children` prop.

##### Values description

| Value                                                 | Description                                                                                                                           |
| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `(() => HTMLElement \| Element \| null \| undefined)` | A function that returns an element.                                                                                                   |
| `string` (CSS selector)                               | A `string` containing a CSS selector matching at least one element. If several element match the CSS selector, the first one is used. |

##### Notes

This prop is useful when you are not able to wrap the element inside of `<ExternalOverlay.Root>`. One possible reason is that it is created outside of React (e.g. a chat plugin’s bubble).

---

---
title: "createComponentId · Silk"
description: "API reference for the createComponentId function."
Source: https://silkhq.com/docs/create-component-id.md
---

## Description

A function that returns a `ComponentId` which identifies a component instance when passed to its Root sub-component `componentId` prop. It can then be passed to the `forComponent` prop of other sub-components to associates them to the same component instance.

This allows to disambiguate the association of a sub-component that is the descendant of several nested Root sub-components.

##### Notes

- `componentId` must always be passed to the Root sub-component of the component instance that is to be identified.
- Only sub-components or components positioned inside of the Root sub-component bearing the `componentId` in the virtual DOM can be linked to it.
- To avoid any HMR issue `createComponentId` must always be called outside of component functions or classes, inside of a file dedicated to component ids and/or React contexts.
- createComponentId is short for “create component instance id”.

##### Example

```tsx
const loginSheetId = createComponentId();
```

```tsx
<Sheet.Root componentId={loginSheetId}>
	...
	<Sheet.Root>
		...
		<Sheet.Trigger forComponent={loginSheetId} />
		...
	</Sheet.Root>
	...
</Sheet.Root>
```

---

---
title: "usePageScrollData · Silk"
description: "API reference for the usePageScrollData hook."
Source: https://silkhq.com/docs/use-page-scroll-data.md
---

## Description

A hook which returns an object with two keys: `{ pageScrollContainer, nativePageScrollReplaced }`. On page load, both values are `undefined`. After hydration, if native page scroll is currently replaced by a scroll container as a result of the action of the [`nativePageScrollReplacement` prop on `<Scroll.View>`](https://silkhq.com/docs/scroll.md), `nativePageScrollReplaced` is `true` and `pageScrollContainer` contains the element used as page scroll container instead. Otherwise, `nativePageScrollReplaced` is `false` and `pageScrollContainer` contains `document.body`

This is useful to adapt the logic, styling or animations of certain components and elements in one case or the other.

## Usage

##### Example

```tsx
import { Sheet, usePageScrollData } from "@silk-hq/components";

const MySheetOutlet = () => {
   const { nativePageScrollReplaced } = usePageScrollData();

   return (
      <Sheet.Outlet
         travelAnimation={
            nativePageScrollReplaced
               ? {
                    borderRadius: ["0px", "20px"],
                    transformOrigin: "50% 0",
                 }
               : {
                    clipBoundary: "layout-viewport",
                    clipBorderRadius: ["0px", "20px"],
                    clipTransformOrigin: "50% 0",
                 }
         }
      />
   );
};
```

```tsx
import { Sheet, usePageScrollData } from "@silk-hq/components";
import { useScroll } from "framer-motion";

const MyComponent = () => {
   const ref = useRef<HTMLDivElement>(null);
   const { pageScrollContainer, nativePageScrollReplaced } = usePageScrollData();

   const { scrollYProgress } = useScroll({
      container: nativePageScrollReplaced ? { current: pageScrollContainer } : undefined,
      target: ref,
      offset: ["start end", "end end"],
   });
};
```

---

---
title: "useClientMediaQuery · Silk"
description: "API reference for the useClientMediaQuery hook."
Source: https://silkhq.com/docs/use-client-media-query.md
---

## useClientMediaQuery

##### Description

A hook returning a React state whose value is `true` when the CSS media query passed as parameter matches, `false` when it does not match. It gets updated if the value changes during the lifetime of the component where it is used.

It only works on the client (i.e. in the browser), and always returns `false` on the server.

##### Parameters

| **Type**                   | **Description**                                                                                                   |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `string` (CSS media query) | A required parameter defining the CSS media query whose matching result is desired. (e.g. `"(min-width: 500px)"`) |

##### Examples

```tsx
const largeViewport = useClientMediaQuery("(min-width: 500px)");
```

---

---
title: "updateThemeColor · Silk"
description: "API reference for the updateThemeColor function."
Source: https://silkhq.com/docs/update-theme-color.md
---

## updateThemeColor (v0.9.10)

##### Description

A function that updates the `html:theme-color` of the page by setting the `html:content` attribute on the HTML `html:theme-color` meta-tag.

If a `<Sheet.Backdrop>` with `themeColorDimming="auto"` is presented when the update is made, only the underlying `html:theme-color` will be updated, preserving the dimming.

##### Parameters

| **Type**                                                                   | **Description**                                            |
| -------------------------------------------------------------------------- | ---------------------------------------------------------- |
| `string` (color expressed in the `rgb()`, `rgba()`, or hexadecimal format) | Required. The color the `html:theme-color` will be set to. |

##### Example

```tsx
updateThemeColor("#000000");
```

---

---
title: "useThemeColorDimmingOverlay · Silk"
description: "API reference for the useThemeColorDimmingOverlay hook."
Source: https://silkhq.com/docs/use-theme-color-dimming-overlay.md
---

## useThemeColorDimmingOverlay

##### Description

A hook which registers a theme color dimming overlay, possibly associated with an element. It returns an object containing two functions allowing to adjust the element opacity and the associated theme color dimming overlay alpha value at the same time.

`setDimmingOverlayOpacity` allows to set the overlay opacity.

`animateDimmingOverlayOpacity` allows to animate the overlay opacity.

##### Parameters

| **Type**                                                                  | **Description**                                                                                                                                                                                                                                                                                                           |
| ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ts:{ elementRef?: React.RefObject<HTMLElement>; dimmingColor: string; }` | - The `elementRef` key must contain the ref of the element used as theme color dimming overlay. <br><br>- The `dimmingColor` key must contain a color declaration in the RGB format (e.g. `"rgb(0, 0, 0)"`) which matches the background-color CSS property value of the element and will be used to dim the theme color. |
|                                                                           |

##### Returned values

| **Type**                                                                                                                                                                          | **Description**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ts:{ setDimmingOverlayOpacity: (opacity: number ) => void; animateDimmingOverlayOpacity: (args: { keyframes: [number, number]; duration?: number; easing?: string; }) => void }` | - The `setDimmingOverlayOpacity` key contains a function allowing to set the opacity of both the element and the associated theme color dimming overlay. <br><br>- The `animateDimmingOverlayOpacity` key contains a function allowing to animate the opacity of both the element and the associated theme color dimming overlay. <br>&nbsp;&nbsp;&nbsp;&nbsp;- The `keyframes` key represents the start and end values (between 0 and 1) for the opacity animation. <br>&nbsp;&nbsp;&nbsp;&nbsp;- The `duration` key represents the duration of animation, expressed in milliseconds. The default value is `500`. <br>&nbsp;&nbsp;&nbsp;&nbsp;- The `easing` key represents the easing function for the animation. Only supports cubic-bezier() functions. The default value is `"cubic-bezier(0.25, 1, 0.25, 1)"`. |
|                                                                                                                                                                                   |

##### Example

```tsx
const { setDimmingOverlayOpacity, animateDimmingOverlayOpacity } =
  useThemeColorDimmingOverlay({
      elementRef: stackBackgroundRef,
      dimmingColor: "rgb(0, 0, 0)",
  });

setDimmingOverlayOpacity(0.5);
animateDimmingOverlayOpacity({ keyframes: [0, 0.5] });
```

---

---
title: "animate · Silk"
description: "API reference for the animate function."
Source: https://silkhq.com/docs/animate.md
---

## animate

##### Description

A function that runs a WAAPI animation on the specified element and persists its final styles as inline styles on the element at the end of the animation.

##### Parameters

| **Type**                                                      | **Description**                                                                                                                                                                                                                                |
| ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `HTMLElement \| null`                                         | Required. The element whose CSS properties are to be animated.                                                                                                                                                                                 |
| `ts:{ [keys: string]: [string \| number, string \| number] }` | Required. An object whose keys are the CSS properties to be animated and their values the keyframes (the initial one and the final one) to be used for the animation of their respective values. (e.g. `{ opacity: [0, 1] }`).                 |
| `ts:{ duration?: number; easing?: string; }`                  | Optional. The options for the animation. The `duration` is expressed in millisecond. The `easing` must be a CSS easing function (e.g. `"ease"`). <br><br>The default values are `{ duration: 500, easing: "cubic-bezier(0.25, 1, 0.25, 1)" }`. |

##### Example

```tsx
animate(
  elementRef.current,
  { opacity: [0, 1] },
  {
    duration: 600,
    easing: "cubic-bezier(0, 0, 0.58, 1)",
  }
);
```

---

---
title: "Usage with Tailwind V4 · Silk"
description: "Learn how to use Silk alongside Tailwind CSS V4."
Source: https://silkhq.com/docs/usage-with-tailwind-v4.md
---

In Tailwind V4, Tailwind generated styles are wrapped inside of CSS `@layer {}`. As a consequence, unlayered styles—that is styled that are not themselves wrapped that way— take precedence over them.

To avoid any conflict with Silk’s default styles, you must follow the “Import the styles in a project using CSS layers” on the [Getting Started](https://silkhq.com/docs/getting-started.md) page.

---

---
title: "Usage with AI Tools · Silk"
description: "Tips for using Silk with AI coding tools."
Source: https://silkhq.com/docs/usage-with-ai-tools.md
---

AI tools work best when they can read documentation in a structured, efficient format. Silk provides several ways to do that:

- an [`llms.txt`](https://silkhq.com/llms.txt) file listing the main pages and documentation entry points;
- a bundled Markdown version of the full documentation, [`docs-full.md`](https://silkhq.com/docs-full.md);
- a Markdown version of every documentation page at the same URL with `.md`.

## Start with `llms.txt`

If your AI tool supports [`llms.txt`](https://silkhq.com/llms.txt), this is the best place to start.

It gives the tool a structured overview of the Silk website and documentation, and helps it fetch only the pages it actually needs. This usually leads to better results while using less context than providing the full documentation up front.

The [`llms.txt`](https://silkhq.com/llms.txt) file includes:

- a summary of what Silk is;
- links to the main website pages;
- links to the documentation pages;
- a link to the bundled full documentation.

## Use a specific Markdown page

If you want to give an AI tool a single documentation page, each docs page is also available as Markdown by adding `.md` to its URL.

For example:

- `/docs/getting-started` → `/docs/getting-started.md`
- `/docs/sheet` → `/docs/sheet.md`
- `/docs/scroll` → `/docs/scroll.md`

This is the best option when you need help with one specific component, hook, or guide.

## Use the full bundled documentation

If your AI tool needs broader context, Silk also provides the full documentation as a single bundled Markdown file, [`docs-full.md`](https://silkhq.com/docs-full.md).

This is useful when the tool needs a wider view of the library, or when it does not support [`llms.txt`](https://silkhq.com/llms.txt) but can ingest a larger documentation source.

---

---
title: "Migration v0.8.x to v0.9.x · Silk"
description: "Migration guide from Silk v0.8.x to v0.9.x."
Source: https://silkhq.com/docs/from-v0-8-x-to-v0-9-x.md
---

In v0.8.x, Silk’s low-lever styles where imported directly in the JS within the package. Starting with version 0.9.0, Silk requires you to import the styles yourself. This makes it much more flexible and compatible with a wider variety of build tools.

When Migration v0.8.x to v0.9.x, you will need to import the styles in your project. Here is how you can do it.

For convenience and flexibility, these styles are available in two versions: unlayered and layered. The layered version wraps Silk’s default styles into a CSS `@layer {}`.

### Basic

In a project that doesn’t make use of CSS layers, it is best to use the unlayered version. You can import it in two ways:

#### Import into a CSS file

You can import the styles directly into your global CSS file.

```css
/* ./global.css */

@import "@silk-hq/components/unlayered-styles";
```

#### Import into a JavaScript file

You can also import the styles in a JavaScript or TypeScript file at the root of your project.

```tsx
// ./index.tsx

import "@silk-hq/components/unlayered-styles";
```

### In a project using CSS layers (e.g. Tailwind V4)

In a project that makes use of CSS layers (e.g. using Tailwind V4), you can use both the unlayered and the layered version. In any case, Silk’s layer declaration must occur before that of your normal styles. You can import it in two ways:

#### Import into a CSS file

- You can import the unlayered styles into a layer directly into your global CSS, before your normal styles.

```css
/* ./global.css */

@import "@silk-hq/components/unlayered-styles" layer(silk);
/* @import "tailwindcss"; */
```

- Or you can import the layered styles directly into your global CSS, before your normal styles. This is useful for framework that have issues with CSS layered imports (e.g. Next.js).

```css
/* ./global.css */

@import "@silk-hq/components/unlayered-styles" layer(silk);
/* @import "tailwindcss"; */
```

#### Import into a JavaScript file

You can also import the layered styles in a JavaScript or TypeScript file at the root of your project, before importing any normal styles.

```tsx
/* ./index.tsx */

import "@silk-hq/components/layered-styles";
```