# or
yarn add @zag-js/splitter @zag-js/solid
```

## Anatomy

To set up the slider correctly, you'll need to understand its anatomy and how we
name its parts.

> Each part includes a `data-part` attribute to help identify them in the DOM.



## Usage

First, import the splitter package into your project

```jsx
import * as splitter from "@zag-js/splitter"
```

The splitter package exports two key functions:

- `machine` â The state machine logic for the splitter widget.
- `connect` â The function that translates the machine's state to JSX attributes
  and event handlers.

> You'll also need to provide a unique `id` to the `useMachine` hook. This is
> used to ensure that every part has a unique identifier.

Next, import the required hooks and functions for your framework and use the
splitter machine in your project ð¥

```jsx
import * as splitter from "@zag-js/splitter"
import { normalizeProps, useMachine } from "@zag-js/solid"
import { createMemo, createUniqueId } from "solid-js"

export function Splitter() {
  const service = useMachine(splitter.machine, {
    id: createUniqueId(),
    defaultSize: [80, 20],
    panels: [
      { id: "a", minSize: 10 },
      { id: "b", minSize: 10 },
    ],
  })

  const api = createMemo(() => splitter.connect(service, normalizeProps))

  return (
    <div {...api().getRootProps()}>
      <div {...api().getPanelProps({ id: "a" })}>
        <p>A</p>
      </div>
      <div {...api().getResizeTriggerProps({ id: "a:b" })} />
      <div {...api().getPanelProps({ id: "b" })}>
        <p>B</p>
      </div>
    </div>
  )
}
```

### Setting the initial size

To set the initial size of the splitter panels, use the `defaultSize` property.
Ensure the `defaultSize` totals to `100`.

> Note: The splitter only supports setting percentage values.

```jsx {3}
const service = useMachine(splitter.machine, {
  // ...
  defaultSize: [40, 60],
})
```

### Listening for resize events

When the resize trigger is dragged, the `onResize`, `onResizeStart` and
`onResizeEnd` callback is invoked.

```jsx {3-10}
const service = useMachine(splitter.machine, {
  // ...
  onResize(detail) {
    console.log("resize", detail)
  },
  onResizeStart(detail) {
    console.log("change start", detail)
  },
  onResizeEnd(detail) {
    console.log("change end", detail)
  },
})
```

### Changing the orientation

By default, the splitter is assumed to be horizontal. To change the orientation
to vertical, set the `orientation` property in the machine's context to
`vertical`.

```jsx {3}
const service = useMachine(splitter.machine, {
  // ...
  orientation: "vertical",
})
```

## Specifying constraints

Use the `panels` property to specify constraints like `minSize` and `maxSize`
for the splitter panels.

```jsx {3-6}
const service = useMachine(splitter.machine, {
  // ...
  panels: [
    { id: "a", minSize: 100, maxSize: 300 },
    { id: "b", minSize: 100, maxSize: 300 },
  ],
})
```

### Setting the collapsed size

Set the `collapsedSize` and `collapsible` of a panel to specify the collapsed
size of the panel.

> For best results, ensure you also set the `minSize` of the panel

```jsx {4}
const service = useMachine(splitter.machine, {
  // ...
  panels: [
    { id: "a", collapsible: true, collapsedSize: 5, minSize: 10, maxSize: 20 },
    { id: "b", minSize: 50 },
  ],
})
```

This allows the user to drag the splitter to collapse the panel to the
`collapsedSize`.

### Listening for collapse events

When the splitter panel is collapsed, the `onCollapse` callback is invoked.
Alternatively, the `onExpand` callback is invoked when the panel is expanded.

```jsx {3-8}
const service = useMachine(splitter.machine, {
  // ...
  onCollapse(detail) {
    console.log("collapse", detail)
  },
  onExpand(detail) {
    console.log("expand", detail)
  },
})
```

## Styling guide

Earlier, we mentioned that each accordion part has a `data-part` attribute added
to them to select and style them in the DOM.

### Resize trigger

When an splitter item is horizontal or vertical, a `data-state` attribute is set
on the item and content elements.

```css
[data-scope="splitter"][data-part="resize-trigger"] {
  /* styles for the item */
}

[data-scope="splitter"][data-part="resize-trigger"][data-orientation="horizontal"] {
  /* styles for the item is horizontal state */
}

[data-scope="splitter"][data-part="resize-trigger"][data-orientation="vertical"] {
  /* styles for the item is horizontal state */
}

[data-scope="splitter"][data-part="resize-trigger"][data-focus] {
  /* styles for the item is focus state */
}

[data-scope="splitter"][data-part="resize-trigger"]:active {
  /* styles for the item is active state */
}

[data-scope="splitter"][data-part="resize-trigger"][data-disabled] {
  /* styles for the item is disabled state */
}
```

## Methods and Properties

The splitter's `api` exposes the following methods and properties:

### Machine Context

The splitter machine exposes the following context properties:

**`orientation`**
Type: `"horizontal" | "vertical"`
Description: The orientation of the splitter. Can be `horizontal` or `vertical`

**`size`**
Type: `number[]`
Description: The controlled size data of the panels

**`defaultSize`**
Type: `number[]`
Description: The initial size of the panels when rendered.
Use when you don't need to control the size of the panels.

**`panels`**
Type: `PanelData[]`
Description: The size constraints of the panels.

**`onResize`**
Type: `(details: ResizeDetails) => void`
Description: Function called when the splitter is resized.

**`onResizeStart`**
Type: `() => void`
Description: Function called when the splitter resize starts.

**`onResizeEnd`**
Type: `(details: ResizeEndDetails) => void`
Description: Function called when the splitter resize ends.

**`ids`**
Type: `Partial<{ root: string; resizeTrigger: (id: string) => string; label: (id: string) => string; panel: (id: string | number) => string; }>`
Description: The ids of the elements in the splitter. Useful for composition.

**`keyboardResizeBy`**
Type: `number`
Description: The number of pixels to resize the panel by when the keyboard is used.

**`nonce`**
Type: `string`
Description: The nonce for the injected splitter cursor stylesheet.

**`onCollapse`**
Type: `(details: ExpandCollapseDetails) => void`
Description: Function called when a panel is collapsed.

**`onExpand`**
Type: `(details: ExpandCollapseDetails) => void`
Description: Function called when a panel is expanded.

**`dir`**
Type: `"ltr" | "rtl"`
Description: The document's text/writing direction.

**`id`**
Type: `string`
Description: The unique identifier of the machine.

**`getRootNode`**
Type: `() => ShadowRoot | Node | Document`
Description: A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron.

### Machine API

The splitter `api` exposes the following methods:

**`dragging`**
Type: `boolean`
Description: Whether the splitter is currently being resized.

**`orientation`**
Type: `"horizontal" | "vertical"`
Description: The orientation of the splitter.

**`getSizes`**
Type: `() => number[]`
Description: Returns the current sizes of the panels.

**`setSizes`**
Type: `(size: number[]) => void`
Description: Sets the sizes of the panels.

**`getItems`**
Type: `() => SplitterItem[]`
Description: Returns the items of the splitter.

**`getPanels`**
Type: `() => PanelData[]`
Description: Returns the panels of the splitter.

**`getPanelById`**
Type: `(id: string) => PanelData`
Description: Returns the panel with the specified id.

**`getPanelSize`**
Type: `(id: string) => number`
Description: Returns the size of the specified panel.

**`isPanelCollapsed`**
Type: `(id: string) => boolean`
Description: Returns whether the specified panel is collapsed.

**`isPanelExpanded`**
Type: `(id: string) => boolean`
Description: Returns whether the specified panel is expanded.

**`collapsePanel`**
Type: `(id: string) => void`
Description: Collapses the specified panel.

**`expandPanel`**
Type: `(id: string, minSize?: number) => void`
Description: Expands the specified panel.

**`resizePanel`**
Type: `(id: string, unsafePanelSize: number) => void`
Description: Resizes the specified panel.

**`getLayout`**
Type: `() => string`
Description: Returns the layout of the splitter.

**`resetSizes`**
Type: `VoidFunction`
Description: Resets the splitter to its initial state.

**`getResizeTriggerState`**
Type: `(props: ResizeTriggerProps) => ResizeTriggerState`
Description: Returns the state of the resize trigger.

### Data Attributes

**`Root`**

**`data-scope`**: splitter
**`data-part`**: root
**`data-orientation`**: The orientation of the splitter
**`data-dragging`**: Present when in the dragging state

**`Panel`**

**`data-scope`**: splitter
**`data-part`**: panel
**`data-orientation`**: The orientation of the panel
**`data-dragging`**: Present when in the dragging state
**`data-id`**: 
**`data-index`**: The index of the item

**`ResizeTrigger`**

**`data-scope`**: splitter
**`data-part`**: resize-trigger
**`data-id`**: 
**`data-orientation`**: The orientation of the resizetrigger
**`data-focus`**: Present when focused
**`data-dragging`**: Present when in the dragging state
**`data-disabled`**: Present when disabled
Steps are used to guide users through a series of steps in a process. It's a
great way to break down a complex process into smaller, more manageable steps.

## Resources


[Latest version: v1.33.1](https://www.npmjs.com/package/@zag-js/steps)
[Logic Visualizer](https://zag-visualizer.vercel.app/steps)
[Source Code](https://github.com/chakra-ui/zag/tree/main/packages/machines/steps)



**Features**

- Supports horizontal and vertical orientations
- Support for changing the active step with the keyboard and pointer
- Support for linear and non-linear steps

## Installation

To use the steps machine in your project, run the following command in your
command line:

```bash
npm install @zag-js/steps @zag-js/solid