|
| 1 | +--- |
| 2 | +description: A set of resizable panels separated by draggable handles. |
| 3 | +category: layout |
| 4 | +links: |
| 5 | + - label: Splitter |
| 6 | + icon: i-custom-reka-ui |
| 7 | + to: https://reka-ui.com/docs/components/splitter |
| 8 | + - label: GitHub |
| 9 | + icon: i-simple-icons-github |
| 10 | + to: https://github.com/nuxt/ui/blob/v4/src/runtime/components/Splitter.vue |
| 11 | +navigation.badge: Soon |
| 12 | +--- |
| 13 | + |
| 14 | +## Usage |
| 15 | + |
| 16 | +Use the Splitter component to display a list of resizable panels separated by draggable handles. |
| 17 | + |
| 18 | +::component-example |
| 19 | +--- |
| 20 | +collapse: true |
| 21 | +name: 'splitter-example' |
| 22 | +--- |
| 23 | +:: |
| 24 | + |
| 25 | +::note |
| 26 | +The Splitter fills the height of its container, so make sure a parent element defines one. |
| 27 | +:: |
| 28 | + |
| 29 | +### Items |
| 30 | + |
| 31 | +Use the `items` prop as an array of objects with the following properties: |
| 32 | + |
| 33 | +- `defaultSize?: number`{lang="ts-type"} |
| 34 | +- `minSize?: number`{lang="ts-type"} |
| 35 | +- `maxSize?: number`{lang="ts-type"} |
| 36 | +- `collapsible?: boolean`{lang="ts-type"} |
| 37 | +- `collapsedSize?: number`{lang="ts-type"} |
| 38 | +- `sizeUnit?: '%' | 'px'`{lang="ts-type"} |
| 39 | +- `order?: number`{lang="ts-type"} |
| 40 | +- `id?: string`{lang="ts-type"} |
| 41 | +- `slot?: string`{lang="ts-type"} |
| 42 | +- `class?: any`{lang="ts-type"} |
| 43 | +- `ui?: { panel?: ClassNameValue }`{lang="ts-type"} |
| 44 | + |
| 45 | +Use the `slot` key to fill the content of a panel and the `class` key to style it. Items without a `slot` key fall back to a `panel-{index}` slot. Sizes are percentages by default, set `sizeUnit: 'px'` on an item for pixel values. |
| 46 | + |
| 47 | +::caution |
| 48 | +When rendering on the server, set the `id` prop and give `defaultSize` to all items or to none. Ids are generated automatically otherwise and the server and the client can disagree, which breaks the layout on hydration. An item without a `defaultSize` falls back to an equal share on the server, so mixing the two makes panels jump once hydrated. Pixel sizes are measured on the client and always shift a little. |
| 49 | +:: |
| 50 | + |
| 51 | +::component-code |
| 52 | +--- |
| 53 | +collapse: true |
| 54 | +class: 'h-96' |
| 55 | +prettier: true |
| 56 | +ignore: |
| 57 | + - items |
| 58 | + - id |
| 59 | +external: |
| 60 | + - items |
| 61 | +externalTypes: |
| 62 | + - SplitterItem[] |
| 63 | +props: |
| 64 | + id: 'splitter-items' |
| 65 | + items: |
| 66 | + - slot: 'sidebar' |
| 67 | + minSize: 15 |
| 68 | + maxSize: 40 |
| 69 | + defaultSize: 25 |
| 70 | + class: 'bg-elevated/50 border border-default rounded-xl items-center justify-center text-muted font-medium' |
| 71 | + - slot: 'main' |
| 72 | + defaultSize: 75 |
| 73 | + class: 'bg-elevated/50 border border-default rounded-xl items-center justify-center text-muted font-medium' |
| 74 | +slots: |
| 75 | + sidebar: Sidebar |
| 76 | + main: Main |
| 77 | +--- |
| 78 | + |
| 79 | +#sidebar |
| 80 | +Sidebar |
| 81 | + |
| 82 | +#main |
| 83 | +Main |
| 84 | +:: |
| 85 | + |
| 86 | +### Orientation |
| 87 | + |
| 88 | +Use the `orientation` prop to change the direction of the splitter. Defaults to `horizontal`. |
| 89 | + |
| 90 | +::component-code |
| 91 | +--- |
| 92 | +collapse: true |
| 93 | +class: 'h-96' |
| 94 | +prettier: true |
| 95 | +ignore: |
| 96 | + - items |
| 97 | + - id |
| 98 | +external: |
| 99 | + - items |
| 100 | +externalTypes: |
| 101 | + - SplitterItem[] |
| 102 | +props: |
| 103 | + id: 'splitter-orientation' |
| 104 | + orientation: 'vertical' |
| 105 | + items: |
| 106 | + - slot: 'first' |
| 107 | + class: 'bg-elevated/50 border border-default rounded-xl items-center justify-center text-muted font-medium' |
| 108 | + - slot: 'second' |
| 109 | + class: 'bg-elevated/50 border border-default rounded-xl items-center justify-center text-muted font-medium' |
| 110 | +slots: |
| 111 | + first: First |
| 112 | + second: Second |
| 113 | +--- |
| 114 | + |
| 115 | +#first |
| 116 | +First |
| 117 | + |
| 118 | +#second |
| 119 | +Second |
| 120 | +:: |
| 121 | + |
| 122 | +## Examples |
| 123 | + |
| 124 | +### With collapsible panel |
| 125 | + |
| 126 | +Set `collapsible: true` on an item to let it collapse past its `minSize`, and use `collapsedSize` to keep part of the panel visible when collapsed. The panel slot exposes `collapsed`, `collapse` and `expand` so you can control it programmatically, and the `collapse`, `expand` and `resize` events fire with the panel index. |
| 127 | + |
| 128 | +::component-example |
| 129 | +--- |
| 130 | +collapse: true |
| 131 | +name: 'splitter-collapsible-example' |
| 132 | +--- |
| 133 | +:: |
| 134 | + |
| 135 | +### With nested splitters |
| 136 | + |
| 137 | +Nest a `Splitter` inside a panel to build two-dimensional, IDE-style layouts. |
| 138 | + |
| 139 | +::component-example |
| 140 | +--- |
| 141 | +collapse: true |
| 142 | +name: 'splitter-nested-example' |
| 143 | +--- |
| 144 | +:: |
| 145 | + |
| 146 | +### With custom handle |
| 147 | + |
| 148 | +The handle is invisible by default. Use the `ui` prop to restyle it, for example as a visible divider for flush layouts, and the `resize-handle` slot to render content inside it like a grip. |
| 149 | + |
| 150 | +::component-example |
| 151 | +--- |
| 152 | +collapse: true |
| 153 | +name: 'splitter-custom-handle-example' |
| 154 | +--- |
| 155 | +:: |
| 156 | + |
| 157 | +### With persistence |
| 158 | + |
| 159 | +Provide an `auto-save-id` to persist the layout to `localStorage` and restore it on reload. |
| 160 | + |
| 161 | +```vue |
| 162 | +<template> |
| 163 | + <USplitter id="my-layout" auto-save-id="my-layout" :items="items"> |
| 164 | + <!-- ... --> |
| 165 | + </USplitter> |
| 166 | +</template> |
| 167 | +``` |
| 168 | + |
| 169 | +## API |
| 170 | + |
| 171 | +### Props |
| 172 | + |
| 173 | +:component-props |
| 174 | + |
| 175 | +### Slots |
| 176 | + |
| 177 | +:component-slots |
| 178 | + |
| 179 | +### Emits |
| 180 | + |
| 181 | +:component-emits |
| 182 | + |
| 183 | +## Theme |
| 184 | + |
| 185 | +:component-theme |
| 186 | + |
| 187 | +## Changelog |
| 188 | + |
| 189 | +:component-changelog |
0 commit comments