@sveltia/ui 0.32.2 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -22,7 +22,7 @@ declare const CheckboxGroup: import("svelte").Component<{
22
22
  /**
23
23
  * Orientation of the widget.
24
24
  */
25
- orientation?: "vertical" | "horizontal" | undefined;
25
+ orientation?: "horizontal" | "vertical" | undefined;
26
26
  /**
27
27
  * Primary slot content.
28
28
  */
@@ -46,7 +46,7 @@ type Props = {
46
46
  /**
47
47
  * Orientation of the widget.
48
48
  */
49
- orientation?: "vertical" | "horizontal" | undefined;
49
+ orientation?: "horizontal" | "vertical" | undefined;
50
50
  /**
51
51
  * Primary slot content.
52
52
  */
@@ -21,7 +21,7 @@ declare const Divider: import("svelte").Component<{
21
21
  * Orientation of the widget. An alias of the
22
22
  * `aria-orientation` attribute.
23
23
  */
24
- orientation?: "vertical" | "horizontal" | undefined;
24
+ orientation?: "horizontal" | "vertical" | undefined;
25
25
  } & Record<string, any>, {}, "">;
26
26
  type Props = {
27
27
  /**
@@ -37,5 +37,5 @@ type Props = {
37
37
  * Orientation of the widget. An alias of the
38
38
  * `aria-orientation` attribute.
39
39
  */
40
- orientation?: "vertical" | "horizontal" | undefined;
40
+ orientation?: "horizontal" | "vertical" | undefined;
41
41
  };
@@ -41,7 +41,7 @@ declare const RadioGroup: import("svelte").Component<{
41
41
  * Orientation of the widget. An alias of the
42
42
  * `aria-orientation` attribute.
43
43
  */
44
- orientation?: "vertical" | "horizontal" | undefined;
44
+ orientation?: "horizontal" | "vertical" | undefined;
45
45
  /**
46
46
  * Primary slot content.
47
47
  */
@@ -84,7 +84,7 @@ type Props = {
84
84
  * Orientation of the widget. An alias of the
85
85
  * `aria-orientation` attribute.
86
86
  */
87
- orientation?: "vertical" | "horizontal" | undefined;
87
+ orientation?: "horizontal" | "vertical" | undefined;
88
88
  /**
89
89
  * Primary slot content.
90
90
  */
@@ -0,0 +1,312 @@
1
+ <!--
2
+ @component
3
+ A draggable handle for resizing adjacent panes within a `<ResizablePaneGroup>`.
4
+ @see https://w3c.github.io/aria/#separator
5
+ @see https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/
6
+ -->
7
+ <script>
8
+ import { getContext } from 'svelte';
9
+ import { isRTL } from '../../services/i18n.js';
10
+
11
+ /**
12
+ * @import { Snippet } from 'svelte';
13
+ * @import { PaneGroupContext } from '../../typedefs.js';
14
+ */
15
+
16
+ /**
17
+ * @typedef {object} Props
18
+ * @property {boolean} [disabled] Whether to disable the handle.
19
+ * @property {boolean} [showHandleBar] Whether to show the handle bar.
20
+ * @property {string} [class] The `class` attribute on the wrapper element.
21
+ * @property {Snippet} [children] Custom handle content. If omitted, a default visual indicator is
22
+ * rendered.
23
+ * @property {() => void} [onResizeStart] Called when a resize interaction begins (pointer down or
24
+ * first keyboard step).
25
+ * @property {() => void} [onResizeEnd] Called when a resize interaction ends (pointer up/cancel
26
+ * or handle blur).
27
+ */
28
+
29
+ /**
30
+ * @type {Props & Record<string, any>}
31
+ */
32
+ let {
33
+ /* eslint-disable prefer-const */
34
+ disabled = false,
35
+ showHandleBar = false,
36
+ class: className,
37
+ children,
38
+ onResizeStart,
39
+ onResizeEnd,
40
+ ...restProps
41
+ /* eslint-enable prefer-const */
42
+ } = $props();
43
+
44
+ /** @type {PaneGroupContext} */
45
+ const ctx = getContext('paneGroup');
46
+
47
+ if (!ctx) {
48
+ throw new Error('<ResizableHandle> must be used inside a <ResizablePaneGroup>');
49
+ }
50
+
51
+ const handleIndex = ctx.registerHandle();
52
+ const isHorizontal = $derived(ctx.direction === 'horizontal');
53
+ const sizes = $derived(ctx.sizes);
54
+ // The value reported via aria-valuenow is the size of the pane immediately before this handle
55
+ const currentPaneSize = $derived(sizes[handleIndex] ?? 0);
56
+ const currentPaneMin = $derived(
57
+ Math.max(
58
+ ctx.paneDefs[handleIndex]?.minSize ?? 0,
59
+ 100 - ctx.paneDefs.reduce((sum, p, i) => sum + (i !== handleIndex ? p.maxSize : 0), 0),
60
+ ),
61
+ );
62
+ const currentPaneMax = $derived(
63
+ Math.min(
64
+ ctx.paneDefs[handleIndex]?.maxSize ?? 100,
65
+ 100 - ctx.paneDefs.reduce((sum, p, i) => sum + (i !== handleIndex ? p.minSize : 0), 0),
66
+ ),
67
+ );
68
+
69
+ /**
70
+ * A reference to the handle element.
71
+ * @type {HTMLElement | undefined}
72
+ */
73
+ let element = $state();
74
+ let dragging = $state(false);
75
+ let startScreenPos = $state(0);
76
+ let targetPointerId = $state(0);
77
+ /**
78
+ * Whether the handle is being resized via keyboard (at least one step fired).
79
+ */
80
+ let keyResizing = $state(false);
81
+
82
+ /**
83
+ * Get the pane group container element's size in pixels for px→% conversion.
84
+ * @returns {number} Container size in pixels.
85
+ */
86
+ const getContainerSize = () => {
87
+ const container = element?.closest('.resizable-pane-group');
88
+
89
+ if (!container) return 0;
90
+
91
+ return isHorizontal ? container.clientWidth : container.clientHeight;
92
+ };
93
+
94
+ /**
95
+ * Handle pointer move events (attached to `document` while dragging).
96
+ * @param {PointerEvent} event `pointermove` event.
97
+ */
98
+ const onPointerMove = (event) => {
99
+ const { screenX, screenY, pointerId } = event;
100
+
101
+ if (disabled || !dragging || pointerId !== targetPointerId) return;
102
+
103
+ event.preventDefault();
104
+ event.stopPropagation();
105
+
106
+ const screenPos = isHorizontal ? screenX : screenY;
107
+ const pixelDelta = screenPos - startScreenPos;
108
+ const containerSize = getContainerSize();
109
+
110
+ if (!containerSize) return;
111
+
112
+ let percentDelta = (pixelDelta / containerSize) * 100;
113
+
114
+ // In RTL with a horizontal layout, the visual direction is reversed
115
+ if (isHorizontal && $isRTL) {
116
+ percentDelta = -percentDelta;
117
+ }
118
+
119
+ startScreenPos = screenPos;
120
+ ctx.resize(handleIndex, percentDelta);
121
+ };
122
+
123
+ /**
124
+ * Handle pointer up/cancel events (attached to `document` while dragging).
125
+ * @param {PointerEvent} event `pointerup` or `pointercancel` event.
126
+ */
127
+ const onPointerUp = (event) => {
128
+ if (!dragging || event.pointerId !== targetPointerId) return;
129
+
130
+ dragging = false;
131
+ startScreenPos = 0;
132
+ targetPointerId = 0;
133
+
134
+ document.removeEventListener('pointermove', onPointerMove);
135
+ document.removeEventListener('pointerup', onPointerUp);
136
+ document.removeEventListener('pointercancel', onPointerUp);
137
+ onResizeEnd?.();
138
+ };
139
+
140
+ /**
141
+ * Handle pointer down events on the handle.
142
+ * @param {PointerEvent} event `pointerdown` event.
143
+ */
144
+ const onPointerDown = (event) => {
145
+ if (disabled) return;
146
+
147
+ event.preventDefault();
148
+ event.stopPropagation();
149
+
150
+ dragging = true;
151
+ startScreenPos = isHorizontal ? event.screenX : event.screenY;
152
+ targetPointerId = event.pointerId;
153
+ onResizeStart?.();
154
+
155
+ document.addEventListener('pointermove', onPointerMove);
156
+ document.addEventListener('pointerup', onPointerUp);
157
+ document.addEventListener('pointercancel', onPointerUp);
158
+ };
159
+
160
+ /**
161
+ * Handle keyboard events for accessibility. Arrow keys move the handle by 1%; Shift+Arrow moves
162
+ * by 10%. Enter collapses/restores the primary pane. Home/End jump to min/max.
163
+ * @param {KeyboardEvent} event `keydown` event.
164
+ */
165
+ const onKeyDown = (event) => {
166
+ if (disabled) return;
167
+
168
+ const { key, shiftKey } = event;
169
+ const step = shiftKey ? 10 : 1;
170
+ let delta = 0;
171
+
172
+ if (key === 'Enter') {
173
+ event.preventDefault();
174
+ event.stopPropagation();
175
+ ctx.toggleCollapse(handleIndex);
176
+
177
+ return;
178
+ }
179
+
180
+ if (key === 'Home') {
181
+ event.preventDefault();
182
+ event.stopPropagation();
183
+ // Collapse to minimum — clamped internally
184
+ ctx.resize(handleIndex, -100);
185
+
186
+ return;
187
+ }
188
+
189
+ if (key === 'End') {
190
+ event.preventDefault();
191
+ event.stopPropagation();
192
+ // Expand to maximum — clamped internally
193
+ ctx.resize(handleIndex, 100);
194
+
195
+ return;
196
+ }
197
+
198
+ if (isHorizontal) {
199
+ // In RTL, Left/Right directions are visually swapped
200
+ if (key === 'ArrowLeft') {
201
+ delta = $isRTL ? step : -step;
202
+ } else if (key === 'ArrowRight') {
203
+ delta = $isRTL ? -step : step;
204
+ } else {
205
+ return;
206
+ }
207
+ } else if (key === 'ArrowUp') {
208
+ delta = -step;
209
+ } else if (key === 'ArrowDown') {
210
+ delta = step;
211
+ } else {
212
+ return;
213
+ }
214
+
215
+ event.preventDefault();
216
+ event.stopPropagation();
217
+
218
+ if (!keyResizing) {
219
+ keyResizing = true;
220
+ onResizeStart?.();
221
+ }
222
+
223
+ ctx.resize(handleIndex, delta);
224
+ };
225
+
226
+ /**
227
+ * Handle blur to signal keyboard resize end.
228
+ */
229
+ const onBlur = () => {
230
+ if (keyResizing) {
231
+ keyResizing = false;
232
+ onResizeEnd?.();
233
+ }
234
+ };
235
+ </script>
236
+
237
+ <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
238
+ <div
239
+ bind:this={element}
240
+ {...restProps}
241
+ role="separator"
242
+ tabindex={disabled ? -1 : 0}
243
+ aria-orientation={isHorizontal ? 'vertical' : 'horizontal'}
244
+ aria-valuenow={Math.round(currentPaneSize)}
245
+ aria-valuemin={currentPaneMin}
246
+ aria-valuemax={currentPaneMax}
247
+ aria-controls={ctx.paneDefs[handleIndex]?.id}
248
+ aria-disabled={disabled || undefined}
249
+ class="sui resizable-handle {className ?? ''}"
250
+ class:horizontal={isHorizontal}
251
+ class:vertical={!isHorizontal}
252
+ class:disabled
253
+ class:dragging
254
+ onpointerdown={onPointerDown}
255
+ onkeydown={onKeyDown}
256
+ onblur={onBlur}
257
+ >
258
+ {#if children}
259
+ {@render children()}
260
+ {:else if showHandleBar}
261
+ <div role="none" class="handle-bar"></div>
262
+ {/if}
263
+ </div>
264
+
265
+ <style>.resizable-handle {
266
+ position: relative;
267
+ flex: 0 0 auto;
268
+ display: flex;
269
+ align-items: center;
270
+ justify-content: center;
271
+ touch-action: none;
272
+ outline-offset: 0;
273
+ background-color: transparent;
274
+ transition: background-color 200ms;
275
+ }
276
+ .resizable-handle:focus-visible, .resizable-handle:hover, .resizable-handle.dragging {
277
+ outline: none;
278
+ z-index: 1;
279
+ background-color: var(--sui-primary-accent-color-translucent);
280
+ }
281
+ .resizable-handle:focus-visible .handle-bar, .resizable-handle:hover .handle-bar, .resizable-handle.dragging .handle-bar {
282
+ background-color: var(--sui-primary-accent-color);
283
+ }
284
+ .resizable-handle.disabled {
285
+ pointer-events: none;
286
+ opacity: 0.4;
287
+ }
288
+ .resizable-handle.horizontal {
289
+ width: var(--sui-resizable-handle-size, 4px);
290
+ height: 100%;
291
+ cursor: col-resize;
292
+ }
293
+ .resizable-handle.horizontal .handle-bar {
294
+ width: 2px;
295
+ height: 40%;
296
+ min-height: 20px;
297
+ }
298
+ .resizable-handle.vertical {
299
+ width: 100%;
300
+ height: var(--sui-resizable-handle-size, 4px);
301
+ cursor: row-resize;
302
+ }
303
+ .resizable-handle.vertical .handle-bar {
304
+ height: 2px;
305
+ width: 40%;
306
+ min-width: 20px;
307
+ }
308
+ .resizable-handle .handle-bar {
309
+ border-radius: 1px;
310
+ background-color: hsl(var(--sui-border-color-1-hsl));
311
+ transition: background-color 200ms;
312
+ }</style>
@@ -0,0 +1,69 @@
1
+ export default ResizableHandle;
2
+ type ResizableHandle = {
3
+ $on?(type: string, callback: (e: any) => void): () => void;
4
+ $set?(props: Partial<Props & Record<string, any>>): void;
5
+ };
6
+ /**
7
+ * A draggable handle for resizing adjacent panes within a `<ResizablePaneGroup>`.
8
+ * @see https://w3c.github.io/aria/#separator
9
+ * @see https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/
10
+ */
11
+ declare const ResizableHandle: import("svelte").Component<{
12
+ /**
13
+ * Whether to disable the handle.
14
+ */
15
+ disabled?: boolean | undefined;
16
+ /**
17
+ * Whether to show the handle bar.
18
+ */
19
+ showHandleBar?: boolean | undefined;
20
+ /**
21
+ * The `class` attribute on the wrapper element.
22
+ */
23
+ class?: string | undefined;
24
+ /**
25
+ * Custom handle content. If omitted, a default visual indicator is
26
+ * rendered.
27
+ */
28
+ children?: Snippet<[]> | undefined;
29
+ /**
30
+ * Called when a resize interaction begins (pointer down or
31
+ * first keyboard step).
32
+ */
33
+ onResizeStart?: (() => void) | undefined;
34
+ /**
35
+ * Called when a resize interaction ends (pointer up/cancel
36
+ * or handle blur).
37
+ */
38
+ onResizeEnd?: (() => void) | undefined;
39
+ } & Record<string, any>, {}, "">;
40
+ type Props = {
41
+ /**
42
+ * Whether to disable the handle.
43
+ */
44
+ disabled?: boolean | undefined;
45
+ /**
46
+ * Whether to show the handle bar.
47
+ */
48
+ showHandleBar?: boolean | undefined;
49
+ /**
50
+ * The `class` attribute on the wrapper element.
51
+ */
52
+ class?: string | undefined;
53
+ /**
54
+ * Custom handle content. If omitted, a default visual indicator is
55
+ * rendered.
56
+ */
57
+ children?: Snippet<[]> | undefined;
58
+ /**
59
+ * Called when a resize interaction begins (pointer down or
60
+ * first keyboard step).
61
+ */
62
+ onResizeStart?: (() => void) | undefined;
63
+ /**
64
+ * Called when a resize interaction ends (pointer up/cancel
65
+ * or handle blur).
66
+ */
67
+ onResizeEnd?: (() => void) | undefined;
68
+ };
69
+ import type { Snippet } from 'svelte';
@@ -0,0 +1,179 @@
1
+ <!--
2
+ @component
3
+ Container for resizable panes. Panes must be separated by `<ResizableHandle>` components.
4
+ @see https://w3c.github.io/aria/#separator
5
+ @see https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/
6
+ -->
7
+ <script>
8
+ import { setContext } from 'svelte';
9
+
10
+ /**
11
+ * @import { Snippet } from 'svelte';
12
+ * @import { PaneGroupContext } from '../../typedefs.js';
13
+ */
14
+
15
+ /**
16
+ * @typedef {object} Props
17
+ * @property {'horizontal' | 'vertical'} [direction] Layout direction of the panes.
18
+ * @property {string} [class] The `class` attribute on the wrapper element.
19
+ * @property {Snippet} [children] Primary slot content.
20
+ * @property {(detail: { sizes: number[] }) => void} [onResize] `resize` event handler, called
21
+ * whenever the pane sizes change.
22
+ */
23
+
24
+ /**
25
+ * @type {Props & Record<string, any>}
26
+ */
27
+ let {
28
+ /* eslint-disable prefer-const */
29
+ direction = 'horizontal',
30
+ class: className,
31
+ children,
32
+ onResize,
33
+ ...restProps
34
+ /* eslint-enable prefer-const */
35
+ } = $props();
36
+
37
+ /**
38
+ * `ResizablePane` definitions in registration order, populated synchronously by child
39
+ * `<ResizablePane>` components.
40
+ * @type {{ id: string, defaultSize: number | undefined, minSize: number, maxSize: number }[]}
41
+ */
42
+ const _paneDefs = $state([]);
43
+
44
+ /**
45
+ * Current pane sizes as percentages.
46
+ * @type {number[]}
47
+ */
48
+ const sizes = $state([]);
49
+
50
+ /**
51
+ * Per-handle saved sizes before collapse, for Enter key restore.
52
+ * @type {(number | undefined)[]}
53
+ */
54
+ const _savedSizes = $state([]);
55
+
56
+ let _handleCount = 0;
57
+
58
+ /**
59
+ * Initialize pane sizes from `defaultSize` props. Called from `onMount` once all panes have
60
+ * registered. Panes without `defaultSize` share the remaining space equally.
61
+ */
62
+ const initSizes = () => {
63
+ if (!_paneDefs.length) return;
64
+
65
+ const totalSpecified = _paneDefs.reduce((sum, p) => sum + (p.defaultSize ?? 0), 0);
66
+ const unspecifiedCount = _paneDefs.filter((p) => p.defaultSize === undefined).length;
67
+ const remaining = Math.max(0, 100 - totalSpecified);
68
+ const defaultSize = unspecifiedCount > 0 ? remaining / unspecifiedCount : 0;
69
+ const newSizes = _paneDefs.map((p) => p.defaultSize ?? defaultSize);
70
+
71
+ sizes.splice(0, sizes.length, ...newSizes);
72
+ };
73
+
74
+ /**
75
+ * Resize panes around a handle by the given delta (percentage points).
76
+ * @param {number} handleIndex Index of the resize handle.
77
+ * @param {number} deltaPercent Size delta in percentage points.
78
+ */
79
+ const resize = (handleIndex, deltaPercent) => {
80
+ const beforeIdx = handleIndex;
81
+ const afterIdx = handleIndex + 1;
82
+
83
+ if (beforeIdx < 0 || afterIdx >= sizes.length) return;
84
+
85
+ const { minSize: minBefore = 0, maxSize: maxBefore = 100 } = _paneDefs[beforeIdx];
86
+ const { minSize: minAfter = 0, maxSize: maxAfter = 100 } = _paneDefs[afterIdx];
87
+ const prevBefore = sizes[beforeIdx];
88
+ const prevAfter = sizes[afterIdx];
89
+ // Clamp delta so neither pane exceeds its min/max constraints
90
+ const canGrow = Math.min(maxBefore - prevBefore, prevAfter - minAfter);
91
+ const canShrink = Math.min(prevBefore - minBefore, maxAfter - prevAfter);
92
+
93
+ const delta =
94
+ deltaPercent > 0 ? Math.min(deltaPercent, canGrow) : -Math.min(-deltaPercent, canShrink);
95
+
96
+ sizes[beforeIdx] = prevBefore + delta;
97
+ sizes[afterIdx] = prevAfter - delta;
98
+
99
+ onResize?.({ sizes: sizes.map((s) => Number(s.toFixed(1))) });
100
+ };
101
+
102
+ /**
103
+ * Toggle collapse of the primary pane (before the given handle). If the pane is above its minimum
104
+ * size it is collapsed to `minSize`; if already at `minSize` the previous size is restored.
105
+ * @param {number} handleIndex Index of the resize handle.
106
+ */
107
+ const toggleCollapse = (handleIndex) => {
108
+ const { minSize: minBefore = 0 } = _paneDefs[handleIndex];
109
+
110
+ if (_savedSizes[handleIndex] !== undefined) {
111
+ const delta = /** @type {number} */ (_savedSizes[handleIndex]) - sizes[handleIndex];
112
+
113
+ _savedSizes[handleIndex] = undefined;
114
+ resize(handleIndex, delta);
115
+ } else {
116
+ _savedSizes[handleIndex] = sizes[handleIndex];
117
+ resize(handleIndex, -(sizes[handleIndex] - minBefore));
118
+ }
119
+ };
120
+
121
+ setContext(
122
+ 'paneGroup',
123
+ /* eslint-disable jsdoc/require-jsdoc */
124
+ /** @type {PaneGroupContext} */ ({
125
+ get direction() {
126
+ return direction;
127
+ },
128
+ sizes,
129
+ registerPane: ({ id, defaultSize, minSize, maxSize }) => {
130
+ const idx = _paneDefs.length;
131
+
132
+ _paneDefs.push({ id, defaultSize, minSize, maxSize });
133
+
134
+ return { index: idx };
135
+ },
136
+ registerHandle: () => {
137
+ const idx = _handleCount;
138
+
139
+ _handleCount += 1;
140
+
141
+ return idx;
142
+ },
143
+ resize,
144
+ toggleCollapse,
145
+ paneDefs: _paneDefs,
146
+ }),
147
+ /* eslint-enable jsdoc/require-jsdoc */
148
+ );
149
+
150
+ $effect(() => {
151
+ if (_paneDefs.length && !sizes.length) {
152
+ initSizes();
153
+ }
154
+ });
155
+ </script>
156
+
157
+ <div
158
+ {...restProps}
159
+ role="none"
160
+ class="sui resizable-pane-group {direction} {className ?? ''}"
161
+ data-direction={direction}
162
+ >
163
+ {@render children?.()}
164
+ </div>
165
+
166
+ <style>.resizable-pane-group {
167
+ display: flex;
168
+ overflow: hidden;
169
+ }
170
+ .resizable-pane-group.horizontal {
171
+ flex-direction: row;
172
+ width: 100%;
173
+ height: 100%;
174
+ }
175
+ .resizable-pane-group.vertical {
176
+ flex-direction: column;
177
+ width: 100%;
178
+ height: 100%;
179
+ }</style>
@@ -0,0 +1,53 @@
1
+ export default ResizablePaneGroup;
2
+ type ResizablePaneGroup = {
3
+ $on?(type: string, callback: (e: any) => void): () => void;
4
+ $set?(props: Partial<Props & Record<string, any>>): void;
5
+ };
6
+ /**
7
+ * Container for resizable panes. Panes must be separated by `<ResizableHandle>` components.
8
+ * @see https://w3c.github.io/aria/#separator
9
+ * @see https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/
10
+ */
11
+ declare const ResizablePaneGroup: import("svelte").Component<{
12
+ /**
13
+ * Layout direction of the panes.
14
+ */
15
+ direction?: "horizontal" | "vertical" | undefined;
16
+ /**
17
+ * The `class` attribute on the wrapper element.
18
+ */
19
+ class?: string | undefined;
20
+ /**
21
+ * Primary slot content.
22
+ */
23
+ children?: Snippet<[]> | undefined;
24
+ /**
25
+ * `resize` event handler, called
26
+ * whenever the pane sizes change.
27
+ */
28
+ onResize?: ((detail: {
29
+ sizes: number[];
30
+ }) => void) | undefined;
31
+ } & Record<string, any>, {}, "">;
32
+ type Props = {
33
+ /**
34
+ * Layout direction of the panes.
35
+ */
36
+ direction?: "horizontal" | "vertical" | undefined;
37
+ /**
38
+ * The `class` attribute on the wrapper element.
39
+ */
40
+ class?: string | undefined;
41
+ /**
42
+ * Primary slot content.
43
+ */
44
+ children?: Snippet<[]> | undefined;
45
+ /**
46
+ * `resize` event handler, called
47
+ * whenever the pane sizes change.
48
+ */
49
+ onResize?: ((detail: {
50
+ sizes: number[];
51
+ }) => void) | undefined;
52
+ };
53
+ import type { Snippet } from 'svelte';