@allxsmith/bestax-bulma 5.48.1 → 5.49.1
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.
- package/README.md +2 -3
- package/dist/bestax.css +1 -1
- package/dist/bestax.css.map +1 -1
- package/dist/esm/form/_pickerInternals/segmentMap.js +7 -7
- package/dist/esm/form/_pickerInternals/segmentMap.js.map +1 -1
- package/dist/esm/helpers/splitterLayout.js +166 -0
- package/dist/esm/helpers/splitterLayout.js.map +1 -0
- package/dist/esm/layout/Splitter.js +374 -0
- package/dist/esm/layout/Splitter.js.map +1 -0
- package/dist/extras.css +1 -1
- package/dist/extras.css.map +1 -1
- package/dist/index.cjs +533 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +1 -0
- package/dist/index.esm.js.map +1 -1
- package/dist/types/helpers/splitterLayout.d.ts +62 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/layout/Splitter.d.ts +125 -0
- package/dist/types-cjs/helpers/splitterLayout.d.ts +62 -0
- package/dist/types-cjs/index.d.ts +1 -0
- package/dist/types-cjs/layout/Splitter.d.ts +125 -0
- package/dist/versions/bestax-no-dark-mode.css +1 -1
- package/dist/versions/bestax-no-dark-mode.css.map +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
- package/dist/versions/bestax-no-helpers.css +1 -1
- package/dist/versions/bestax-no-helpers.css.map +1 -1
- package/dist/versions/bestax-prefixed.css +1 -1
- package/dist/versions/bestax-prefixed.css.map +1 -1
- package/package.json +2 -2
- package/src/scss/CLAUDE.md +1 -1
- package/src/scss/bestax.scss +1 -0
- package/src/scss/extras.scss +3 -0
- package/src/scss/layout/_index.scss +5 -0
- package/src/scss/layout/_splitter.scss +184 -0
- package/src/scss/versions/bestax-no-dark-mode.scss +1 -0
- package/src/scss/versions/bestax-no-helpers-prefixed.scss +1 -0
- package/src/scss/versions/bestax-no-helpers.scss +1 -0
- package/src/scss/versions/bestax-prefixed.scss +1 -0
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import React, { createContext, forwardRef, useContext, useId, useState, useRef, useCallback, useEffect } from 'react';
|
|
4
|
+
import { usePrefixedClassNames, classNames } from '../helpers/classNames.js';
|
|
5
|
+
import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
|
|
6
|
+
import { flattenChildren } from '../helpers/flattenChildren.js';
|
|
7
|
+
import { withSubComponents } from '../helpers/withSubComponents.js';
|
|
8
|
+
import { useClientLayoutEffect } from '../helpers/useClientLayoutEffect.js';
|
|
9
|
+
import { warnOnce } from '../helpers/devWarnings.js';
|
|
10
|
+
import { limitToPercent, defaultSizes, fitSizes, primaryOf, primaryRange, resizePair, sameSizes } from '../helpers/splitterLayout.js';
|
|
11
|
+
|
|
12
|
+
const PaneContext = createContext(null);
|
|
13
|
+
/**
|
|
14
|
+
* One pane of a Splitter, sized by the splitter around it.
|
|
15
|
+
*
|
|
16
|
+
* @function
|
|
17
|
+
* @param {SplitterPaneProps} props - Props for Splitter.Pane.
|
|
18
|
+
* @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the pane's `<div>`.
|
|
19
|
+
* @returns {JSX.Element} The rendered pane.
|
|
20
|
+
*/
|
|
21
|
+
const SplitterPane = forwardRef(({ className, textColor, bgColor, label: _label, defaultSize: _defaultSize, minSize: _minSize, maxSize: _maxSize, collapsible: _collapsible, collapsed: _collapsed, defaultCollapsed: _defaultCollapsed, onCollapsedChange: _onCollapsedChange, style, children, ...props }, ref) => {
|
|
22
|
+
const state = useContext(PaneContext);
|
|
23
|
+
const { bulmaHelperClasses, rest } = useBulmaClasses({
|
|
24
|
+
color: textColor,
|
|
25
|
+
backgroundColor: bgColor,
|
|
26
|
+
...props,
|
|
27
|
+
});
|
|
28
|
+
const paneClass = usePrefixedClassNames('splitter-pane', {
|
|
29
|
+
'is-collapsed': !!state?.collapsed,
|
|
30
|
+
});
|
|
31
|
+
return (jsx("div", { ref: ref, className: classNames(paneClass, bulmaHelperClasses, className), ...rest, id: state?.id ?? rest.id,
|
|
32
|
+
// A percentage over a zero basis, so the server and the client lay
|
|
33
|
+
// it out the same, with no measuring.
|
|
34
|
+
style: state ? { ...style, flex: `${state.size} 1 0px` } : style, hidden: state?.collapsed || rest.hidden, children: children }));
|
|
35
|
+
});
|
|
36
|
+
SplitterPane.displayName = 'Splitter.Pane';
|
|
37
|
+
const isPane = (child) => React.isValidElement(child) && child.type === SplitterPane;
|
|
38
|
+
/** The bounds with pane `i`'s changed, for a move that mustn't snap it shut. */
|
|
39
|
+
const withBound = (bounds, i, change) => bounds.map((bound, j) => (j === i ? { ...bound, ...change } : bound));
|
|
40
|
+
/** The bounds with neither pane beside handle `h` able to shut. */
|
|
41
|
+
const opened = (bounds, h) => withBound(withBound(bounds, h, { collapsible: false }), h + 1, {
|
|
42
|
+
collapsible: false,
|
|
43
|
+
});
|
|
44
|
+
/**
|
|
45
|
+
* The handle a pane's collapse goes through: the one that speaks for it. A
|
|
46
|
+
* collapsible pane that isn't last always has the handle after it, so the
|
|
47
|
+
* one left without is a last pane whose neighbour can collapse too, and it
|
|
48
|
+
* goes through the handle before it.
|
|
49
|
+
*/
|
|
50
|
+
const handleFor = (pane, bounds) => pane < bounds.length - 1 && primaryOf(pane, bounds) === pane
|
|
51
|
+
? pane
|
|
52
|
+
: pane - 1;
|
|
53
|
+
/**
|
|
54
|
+
* The `Splitter` component lays out two or more panes side by side or one above the other, with a handle between each pair to drag or move by keyboard.
|
|
55
|
+
*
|
|
56
|
+
* Each handle is a focusable `separator`, named by the `label` of the pane
|
|
57
|
+
* it speaks for. Sizes are percentages, so the server renders the layout
|
|
58
|
+
* the browser does, and `minSize` and `maxSize` also take `px` and `rem`. A
|
|
59
|
+
* `collapsible` pane shuts when dragged below half its minimum, and Enter on
|
|
60
|
+
* its handle shuts it and brings it back. It doesn't store sizes itself:
|
|
61
|
+
* keep them with `sizes` and `onSizesChange`.
|
|
62
|
+
*
|
|
63
|
+
* @function
|
|
64
|
+
* @param {SplitterProps} props - Props for the Splitter component.
|
|
65
|
+
* @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the root `<div>`.
|
|
66
|
+
* @returns {JSX.Element} The rendered splitter.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* <Splitter height={480}>
|
|
70
|
+
* <Splitter.Pane label="Files" defaultSize={25} minSize="12rem">…</Splitter.Pane>
|
|
71
|
+
* <Splitter.Pane label="Editor">…</Splitter.Pane>
|
|
72
|
+
* </Splitter>
|
|
73
|
+
*/
|
|
74
|
+
const SplitterRoot = forwardRef(({ className, style, textColor, bgColor, orientation = 'horizontal', height, sizes: sizesProp, onSizesChange, step = 1, children, ...props }, ref) => {
|
|
75
|
+
const { bulmaHelperClasses, rest } = useBulmaClasses({
|
|
76
|
+
color: textColor,
|
|
77
|
+
backgroundColor: bgColor,
|
|
78
|
+
...props,
|
|
79
|
+
});
|
|
80
|
+
const vertical = orientation === 'vertical';
|
|
81
|
+
const rootClass = usePrefixedClassNames('splitter', {
|
|
82
|
+
'is-vertical': vertical,
|
|
83
|
+
});
|
|
84
|
+
const handleClass = usePrefixedClassNames('splitter-handle');
|
|
85
|
+
const activeClass = usePrefixedClassNames('is-active');
|
|
86
|
+
const panes = flattenChildren(children).filter(isPane);
|
|
87
|
+
const baseId = useId();
|
|
88
|
+
const ids = panes.map((pane, i) => pane.props.id ?? `${baseId}-pane-${i}`);
|
|
89
|
+
// The room the panes share, in pixels, and a rem, both measured in the
|
|
90
|
+
// browser. Until then, only percentage limits apply.
|
|
91
|
+
const [length, setLength] = useState(null);
|
|
92
|
+
const [remPx, setRemPx] = useState(16);
|
|
93
|
+
const bounds = panes.map(({ props: pane }) => ({
|
|
94
|
+
min: Math.max(0, limitToPercent(pane.minSize, length, remPx) ?? 0),
|
|
95
|
+
max: Math.min(100, limitToPercent(pane.maxSize, length, remPx) ?? 100),
|
|
96
|
+
collapsible: !!pane.collapsible,
|
|
97
|
+
}));
|
|
98
|
+
const boundsKey = JSON.stringify(bounds);
|
|
99
|
+
// Shuts pane `i`, giving its room to the pane across the handle that
|
|
100
|
+
// speaks for it, when that pane can take it within its maximum, as a
|
|
101
|
+
// drag would. A lone pane has no handle and nowhere to give its room.
|
|
102
|
+
const collapseIn = (current, i) => {
|
|
103
|
+
if (current.length < 2)
|
|
104
|
+
return current;
|
|
105
|
+
const h = handleFor(i, bounds);
|
|
106
|
+
const across = h === i ? i + 1 : h;
|
|
107
|
+
if (current[across] + current[i] > bounds[across].max + 1e-6) {
|
|
108
|
+
return current;
|
|
109
|
+
}
|
|
110
|
+
const next = [...current];
|
|
111
|
+
next[across] += next[i];
|
|
112
|
+
next[i] = 0;
|
|
113
|
+
return next;
|
|
114
|
+
};
|
|
115
|
+
const startSizes = () => {
|
|
116
|
+
const base = defaultSizes(panes.map(pane => pane.props.defaultSize));
|
|
117
|
+
let next = fitSizes(base, bounds);
|
|
118
|
+
panes.forEach(({ props: pane }, i) => {
|
|
119
|
+
if (pane.collapsible && (pane.collapsed ?? pane.defaultCollapsed)) {
|
|
120
|
+
next = collapseIn(next, i);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
return next;
|
|
124
|
+
};
|
|
125
|
+
const paneKey = ids.join('|');
|
|
126
|
+
const [state, setState] = useState(() => ({
|
|
127
|
+
key: paneKey,
|
|
128
|
+
sizes: startSizes(),
|
|
129
|
+
}));
|
|
130
|
+
// A different set of panes starts over from the defaults.
|
|
131
|
+
let uncontrolled = state.sizes;
|
|
132
|
+
if (state.key !== paneKey) {
|
|
133
|
+
uncontrolled = startSizes();
|
|
134
|
+
setState({ key: paneKey, sizes: uncontrolled });
|
|
135
|
+
}
|
|
136
|
+
const sizes = sizesProp && sizesProp.length === panes.length ? sizesProp : uncontrolled;
|
|
137
|
+
// The size each pane comes back at after it's shut: the last size it had
|
|
138
|
+
// open, or its default.
|
|
139
|
+
const restoreRef = useRef([]);
|
|
140
|
+
const defaults = defaultSizes(panes.map(pane => pane.props.defaultSize));
|
|
141
|
+
sizes.forEach((size, i) => {
|
|
142
|
+
var _a;
|
|
143
|
+
if (size > 0)
|
|
144
|
+
restoreRef.current[i] = size;
|
|
145
|
+
else
|
|
146
|
+
(_a = restoreRef.current)[i] ?? (_a[i] = defaults[i]);
|
|
147
|
+
});
|
|
148
|
+
const collapsedAt = (layout) => layout.map((size, i) => bounds[i].collapsible && size <= 1e-6);
|
|
149
|
+
// Moves the layout on, telling the app and each pane whose collapse
|
|
150
|
+
// changed, unless the change came from its own `collapsed`. A move that
|
|
151
|
+
// would collapse or open a pane whose `collapsed` the app holds only
|
|
152
|
+
// asks: the app's answer comes back through `collapsed`.
|
|
153
|
+
const sizesRef = useRef(sizes);
|
|
154
|
+
sizesRef.current = sizes;
|
|
155
|
+
const panesRef = useRef(panes);
|
|
156
|
+
panesRef.current = panes;
|
|
157
|
+
const commit = (next, fromProp = false) => {
|
|
158
|
+
const previous = sizesRef.current;
|
|
159
|
+
if (sameSizes(previous, next))
|
|
160
|
+
return;
|
|
161
|
+
const before = collapsedAt(previous);
|
|
162
|
+
const after = collapsedAt(next);
|
|
163
|
+
const flipped = after.flatMap((shut, i) => shut !== before[i] ? [i] : []);
|
|
164
|
+
if (!fromProp &&
|
|
165
|
+
flipped.some(i => panesRef.current[i].props.collapsed !== undefined)) {
|
|
166
|
+
flipped.forEach(i => panesRef.current[i].props.onCollapsedChange?.(after[i]));
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
sizesRef.current = next;
|
|
170
|
+
if (!sizesProp)
|
|
171
|
+
setState(current => ({ ...current, sizes: next }));
|
|
172
|
+
onSizesChange?.(next);
|
|
173
|
+
if (!fromProp) {
|
|
174
|
+
flipped.forEach(i => panesRef.current[i].props.onCollapsedChange?.(after[i]));
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
// Brings pane `i` back at its restore size, taken from across the handle
|
|
178
|
+
// that speaks for it.
|
|
179
|
+
// A lone pane never shuts, so there's always a handle here.
|
|
180
|
+
const expand = (current, i) => {
|
|
181
|
+
const h = handleFor(i, bounds);
|
|
182
|
+
const target = restoreRef.current[i];
|
|
183
|
+
const total = current[h] + current[h + 1];
|
|
184
|
+
return resizePair(current, h, h === i ? target : total - target,
|
|
185
|
+
// Opening one pane snaps neither shut: it stops at the limits.
|
|
186
|
+
opened(bounds, h));
|
|
187
|
+
};
|
|
188
|
+
// A pane's own `collapsed` moving: shut it or bring it back, before the
|
|
189
|
+
// browser paints.
|
|
190
|
+
const collapsedProps = panes.map(pane => pane.props.collapsible ? pane.props.collapsed : undefined);
|
|
191
|
+
const collapsedKey = JSON.stringify(collapsedProps);
|
|
192
|
+
useClientLayoutEffect(() => {
|
|
193
|
+
const current = sizesRef.current;
|
|
194
|
+
const shut = collapsedAt(current);
|
|
195
|
+
let next = current;
|
|
196
|
+
collapsedProps.forEach((wanted, i) => {
|
|
197
|
+
if (wanted === undefined || wanted === shut[i])
|
|
198
|
+
return;
|
|
199
|
+
next = wanted ? collapseIn(next, i) : expand(next, i);
|
|
200
|
+
});
|
|
201
|
+
commit(next, true);
|
|
202
|
+
// collapsedKey stands for collapsedProps.
|
|
203
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
204
|
+
}, [collapsedKey]);
|
|
205
|
+
// Measuring: the room the panes share, so `px` and `rem` limits can turn
|
|
206
|
+
// into percentages, then the layout fitted to them.
|
|
207
|
+
const rootRef = useRef(null);
|
|
208
|
+
const setRefs = useCallback((node) => {
|
|
209
|
+
rootRef.current = node;
|
|
210
|
+
if (typeof ref === 'function')
|
|
211
|
+
return ref(node);
|
|
212
|
+
if (ref)
|
|
213
|
+
ref.current = node;
|
|
214
|
+
}, [ref]);
|
|
215
|
+
// The room the panes share: the root's length less its handles'.
|
|
216
|
+
const roomOf = useCallback(() => {
|
|
217
|
+
const root = rootRef.current;
|
|
218
|
+
/* istanbul ignore next: measuring only runs while it's mounted */
|
|
219
|
+
if (!root)
|
|
220
|
+
return null;
|
|
221
|
+
const along = (el) => {
|
|
222
|
+
const rect = el.getBoundingClientRect();
|
|
223
|
+
return vertical ? rect.height : rect.width;
|
|
224
|
+
};
|
|
225
|
+
const handles = Array.from(root.children).filter(child => child.matches('[role="separator"]'));
|
|
226
|
+
const room = along(root) - handles.reduce((sum, handle) => sum + along(handle), 0);
|
|
227
|
+
return room > 0 ? room : null;
|
|
228
|
+
}, [vertical]);
|
|
229
|
+
const measure = useCallback(() => {
|
|
230
|
+
setLength(roomOf());
|
|
231
|
+
setRemPx(parseFloat(getComputedStyle(document.documentElement).fontSize) || 16);
|
|
232
|
+
}, [roomOf]);
|
|
233
|
+
useClientLayoutEffect(() => {
|
|
234
|
+
measure();
|
|
235
|
+
const root = rootRef.current;
|
|
236
|
+
if (!root || typeof ResizeObserver === 'undefined')
|
|
237
|
+
return;
|
|
238
|
+
const resizes = new ResizeObserver(measure);
|
|
239
|
+
resizes.observe(root);
|
|
240
|
+
return () => resizes.disconnect();
|
|
241
|
+
}, [measure]);
|
|
242
|
+
// Limits that changed, from measuring or from props: fit the layout.
|
|
243
|
+
useClientLayoutEffect(() => {
|
|
244
|
+
commit(fitSizes(sizesRef.current, bounds));
|
|
245
|
+
// boundsKey stands for bounds.
|
|
246
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
247
|
+
}, [boundsKey]);
|
|
248
|
+
const rtl = () => !vertical &&
|
|
249
|
+
!!rootRef.current &&
|
|
250
|
+
getComputedStyle(rootRef.current).direction === 'rtl';
|
|
251
|
+
// ---- Dragging ----
|
|
252
|
+
const [dragging, setDragging] = useState(null);
|
|
253
|
+
const dragRef = useRef(null);
|
|
254
|
+
const onPointerDown = (h) => (event) => {
|
|
255
|
+
if (event.button !== 0)
|
|
256
|
+
return;
|
|
257
|
+
const pixels = roomOf();
|
|
258
|
+
if (!pixels)
|
|
259
|
+
return;
|
|
260
|
+
event.currentTarget.setPointerCapture?.(event.pointerId);
|
|
261
|
+
dragRef.current = {
|
|
262
|
+
handle: h,
|
|
263
|
+
start: vertical ? event.clientY : event.clientX,
|
|
264
|
+
startSizes: sizesRef.current,
|
|
265
|
+
pixels,
|
|
266
|
+
flip: rtl(),
|
|
267
|
+
};
|
|
268
|
+
setDragging(h);
|
|
269
|
+
};
|
|
270
|
+
const onPointerMove = (event) => {
|
|
271
|
+
const drag = dragRef.current;
|
|
272
|
+
if (!drag)
|
|
273
|
+
return;
|
|
274
|
+
const moved = (vertical ? event.clientY : event.clientX) - drag.start;
|
|
275
|
+
const delta = ((drag.flip ? -moved : moved) / drag.pixels) * 100;
|
|
276
|
+
commit(resizePair(sizesRef.current, drag.handle, drag.startSizes[drag.handle] + delta, bounds));
|
|
277
|
+
};
|
|
278
|
+
const endDrag = (event) => {
|
|
279
|
+
if (!dragRef.current)
|
|
280
|
+
return;
|
|
281
|
+
dragRef.current = null;
|
|
282
|
+
event.currentTarget.releasePointerCapture?.(event.pointerId);
|
|
283
|
+
setDragging(null);
|
|
284
|
+
};
|
|
285
|
+
// While dragging, the resize cursor shows wherever the pointer goes.
|
|
286
|
+
useEffect(() => {
|
|
287
|
+
if (dragging === null)
|
|
288
|
+
return;
|
|
289
|
+
const body = document.body.style;
|
|
290
|
+
const { cursor, userSelect } = body;
|
|
291
|
+
body.cursor = vertical ? 'row-resize' : 'col-resize';
|
|
292
|
+
body.userSelect = 'none';
|
|
293
|
+
return () => {
|
|
294
|
+
body.cursor = cursor;
|
|
295
|
+
body.userSelect = userSelect;
|
|
296
|
+
};
|
|
297
|
+
}, [dragging, vertical]);
|
|
298
|
+
// Double-click: the two panes back to their default share of the room.
|
|
299
|
+
const onDoubleClick = (h) => () => {
|
|
300
|
+
const current = sizesRef.current;
|
|
301
|
+
const total = current[h] + current[h + 1];
|
|
302
|
+
const pair = defaults[h] + defaults[h + 1];
|
|
303
|
+
const target = pair > 0 ? (defaults[h] / pair) * total : total / 2;
|
|
304
|
+
const next = [...current];
|
|
305
|
+
next[h] = target;
|
|
306
|
+
next[h + 1] = total - target;
|
|
307
|
+
commit(fitSizes(next, bounds));
|
|
308
|
+
};
|
|
309
|
+
// ---- Keys ----
|
|
310
|
+
const onKeyDown = (h) => (event) => {
|
|
311
|
+
const current = sizesRef.current;
|
|
312
|
+
const primary = primaryOf(h, bounds);
|
|
313
|
+
const by = event.shiftKey ? step * 10 : step;
|
|
314
|
+
const back = vertical ? 'ArrowUp' : 'ArrowLeft';
|
|
315
|
+
const forward = vertical ? 'ArrowDown' : 'ArrowRight';
|
|
316
|
+
// The line moves the way the key points, so right to left, moving
|
|
317
|
+
// right shrinks the pane before, which sits on the right.
|
|
318
|
+
const sign = rtl() ? -1 : 1;
|
|
319
|
+
// Keys move within the limits; Enter is what shuts a pane.
|
|
320
|
+
const open = opened(bounds, h);
|
|
321
|
+
let next = null;
|
|
322
|
+
if (event.key === back || event.key === forward) {
|
|
323
|
+
const direction = (event.key === forward ? 1 : -1) * sign;
|
|
324
|
+
next = resizePair(current, h, current[h] + direction * by, open);
|
|
325
|
+
}
|
|
326
|
+
else if (event.key === 'Home' || event.key === 'End') {
|
|
327
|
+
const range = primaryRange(current, h, primary, open);
|
|
328
|
+
const size = event.key === 'Home' ? range.min : range.max;
|
|
329
|
+
const total = current[h] + current[h + 1];
|
|
330
|
+
next = resizePair(current, h, primary === h ? size : total - size, open);
|
|
331
|
+
}
|
|
332
|
+
else if (event.key === 'Enter' && bounds[primary].collapsible) {
|
|
333
|
+
next =
|
|
334
|
+
current[primary] > 1e-6
|
|
335
|
+
? collapseIn(current, primary)
|
|
336
|
+
: expand(current, primary);
|
|
337
|
+
}
|
|
338
|
+
if (!next)
|
|
339
|
+
return;
|
|
340
|
+
event.preventDefault();
|
|
341
|
+
commit(next);
|
|
342
|
+
};
|
|
343
|
+
// A handle names its pane, so a pane without a label leaves it nameless.
|
|
344
|
+
const unnamed = panes
|
|
345
|
+
.slice(0, -1)
|
|
346
|
+
.some((_, h) => !panes[primaryOf(h, bounds)].props.label);
|
|
347
|
+
useEffect(() => {
|
|
348
|
+
if (unnamed) {
|
|
349
|
+
warnOnce('Splitter:unlabelled', '[bestax-bulma] <Splitter> has a handle whose pane has no label. ' +
|
|
350
|
+
'Give each Splitter.Pane a label, so a screen reader can say ' +
|
|
351
|
+
'which pane a handle resizes.');
|
|
352
|
+
}
|
|
353
|
+
}, [unnamed]);
|
|
354
|
+
const collapsed = collapsedAt(sizes);
|
|
355
|
+
const items = [];
|
|
356
|
+
panes.forEach((pane, i) => {
|
|
357
|
+
items.push(jsx(PaneContext.Provider
|
|
358
|
+
// Children.toArray, under flattenChildren, keys every child.
|
|
359
|
+
, { value: { id: ids[i], size: sizes[i], collapsed: collapsed[i] }, children: pane }, `pane-${String(pane.key)}`));
|
|
360
|
+
if (i === panes.length - 1)
|
|
361
|
+
return;
|
|
362
|
+
const primary = primaryOf(i, bounds);
|
|
363
|
+
const range = primaryRange(sizes, i, primary, bounds);
|
|
364
|
+
items.push(jsx("div", { className: classNames(handleClass, dragging === i && activeClass), role: "separator", tabIndex: 0, "aria-orientation": vertical ? 'horizontal' : 'vertical', "aria-valuenow": Math.round(range.now), "aria-valuemin": Math.round(range.min), "aria-valuemax": Math.round(range.max), "aria-controls": ids[primary], "aria-label": panes[primary].props.label, onPointerDown: onPointerDown(i), onPointerMove: onPointerMove, onPointerUp: endDrag, onPointerCancel: endDrag, onDoubleClick: onDoubleClick(i), onKeyDown: onKeyDown(i) }, `handle-${i}`));
|
|
365
|
+
});
|
|
366
|
+
return (jsx("div", { ref: setRefs, className: classNames(rootClass, bulmaHelperClasses, className), style: height !== undefined ? { ...style, height } : style, ...rest, children: items }));
|
|
367
|
+
});
|
|
368
|
+
SplitterRoot.displayName = 'Splitter';
|
|
369
|
+
const Splitter = withSubComponents(SplitterRoot, {
|
|
370
|
+
Pane: SplitterPane,
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
export { Splitter, SplitterPane };
|
|
374
|
+
//# sourceMappingURL=Splitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Splitter.js","sources":["../../../src/layout/Splitter.tsx"],"sourcesContent":["import React, {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useId,\n useRef,\n useState,\n} from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport { flattenChildren } from '../helpers/flattenChildren';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { useClientLayoutEffect } from '../helpers/useClientLayoutEffect';\nimport { warnOnce } from '../helpers/devWarnings';\nimport {\n defaultSizes,\n fitSizes,\n limitToPercent,\n PaneBounds,\n primaryOf,\n primaryRange,\n resizePair,\n sameSizes,\n SplitterLimit,\n} from '../helpers/splitterLayout';\n\n/** The way the panes run: side by side, or one above the other. */\nexport type SplitterOrientation = 'horizontal' | 'vertical';\n\n/**\n * Props for Splitter.Pane, one of the panes. The helper props, the other\n * attributes and the `ref` land on its `<div>`.\n *\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the pane's `<div>`.\n * @extraProp {string} [id] - The pane's id, which its handle's `aria-controls` points at. The splitter makes one when there's none.\n */\nexport interface SplitterPaneProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /**\n * What the pane is, such as \"Files\". It names the handle that speaks for\n * this pane, which is announced as \"Files, separator, 25\". That's the\n * handle after it, or the one before it when only this pane, of the two\n * beside that handle, can collapse. A development build warns when a\n * handle's pane has none.\n */\n label?: string;\n /**\n * Its starting size, in percent of the room the panes share. Panes without\n * one share what's left equally, and a total over 100 is scaled down.\n */\n defaultSize?: number;\n /**\n * The smallest it can be dragged: a percentage, or a CSS length in `px` or\n * `rem` such as `\"12rem\"`. A length applies once the splitter has measured\n * itself in the browser, so the server renders the default size.\n */\n minSize?: SplitterLimit;\n /** The largest it can be dragged, in the same units as `minSize`. */\n maxSize?: SplitterLimit;\n /**\n * Lets it collapse: dragging it below half its `minSize` shuts it, and\n * Enter on its handle shuts it and brings it back at the size it had. It\n * collapses only when the pane across its handle can take its room within\n * that pane's `maxSize`, since a handle moves only the two panes beside it.\n * A collapsed pane stays mounted, hidden, so it keeps its state.\n */\n collapsible?: boolean;\n /**\n * Whether it's collapsed, for a `collapsible` pane. With it, the state is\n * yours: a drag, a key or a double-click that would collapse it or bring\n * it back calls `onCollapsedChange` and leaves it as it is, and it changes\n * when `collapsed` does.\n */\n collapsed?: boolean;\n /** Whether a `collapsible` pane starts collapsed. */\n defaultCollapsed?: boolean;\n /**\n * Called when a drag, a key or a double-click collapses it or brings it\n * back, or, with `collapsed`, would. Not called for a change you made with\n * `collapsed`.\n */\n onCollapsedChange?: (collapsed: boolean) => void;\n /** What's in it. Content that scrolls belongs in a `ScrollArea`, so a keyboard can reach it. */\n children?: React.ReactNode;\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Background color helper. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n}\n\n/**\n * Props for the Splitter component. The helper props, the other attributes\n * and the `ref` land on the root `<div>`.\n *\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the root `<div>`.\n */\nexport interface SplitterProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /**\n * `Splitter.Pane`s, two or more, each a direct child, with Fragments\n * opened up. A handle goes between each pair. Changing which panes there\n * are puts every pane back to its default size.\n */\n children?: React.ReactNode;\n /**\n * The way the panes run: side by side (`horizontal`) or one above the\n * other (`vertical`).\n */\n orientation?: SplitterOrientation;\n /**\n * The splitter's height. A number is pixels, and a string any CSS length.\n * A vertical splitter needs a height to split.\n */\n height?: number | string;\n /**\n * Each pane's size, in percent, in order, adding up to 100. With it, the\n * sizes are yours: update them from `onSizesChange`. Without it, each\n * pane starts at its `defaultSize`.\n */\n sizes?: number[];\n /**\n * Called with every pane's size, in percent, whenever they change: on\n * each step of a drag or a key, on a collapse and on a reset.\n */\n onSizesChange?: (sizes: number[]) => void;\n /**\n * How far an arrow key moves a handle, in percent. Shift moves ten times\n * as far.\n */\n step?: number;\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Background color helper. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n}\n\n/** What the splitter tells each pane it renders. */\ninterface PaneState {\n id: string;\n size: number;\n collapsed: boolean;\n}\n\nconst PaneContext = createContext<PaneState | null>(null);\n\n/**\n * One pane of a Splitter, sized by the splitter around it.\n *\n * @function\n * @param {SplitterPaneProps} props - Props for Splitter.Pane.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the pane's `<div>`.\n * @returns {JSX.Element} The rendered pane.\n */\nexport const SplitterPane = forwardRef<HTMLDivElement, SplitterPaneProps>(\n (\n {\n className,\n textColor,\n bgColor,\n label: _label,\n defaultSize: _defaultSize,\n minSize: _minSize,\n maxSize: _maxSize,\n collapsible: _collapsible,\n collapsed: _collapsed,\n defaultCollapsed: _defaultCollapsed,\n onCollapsedChange: _onCollapsedChange,\n style,\n children,\n ...props\n },\n ref\n ) => {\n const state = useContext(PaneContext);\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n const paneClass = usePrefixedClassNames('splitter-pane', {\n 'is-collapsed': !!state?.collapsed,\n });\n return (\n <div\n ref={ref}\n className={classNames(paneClass, bulmaHelperClasses, className)}\n {...rest}\n id={state?.id ?? rest.id}\n // A percentage over a zero basis, so the server and the client lay\n // it out the same, with no measuring.\n style={state ? { ...style, flex: `${state.size} 1 0px` } : style}\n hidden={state?.collapsed || rest.hidden}\n >\n {children}\n </div>\n );\n }\n);\n\nSplitterPane.displayName = 'Splitter.Pane';\n\n/** A pane's props as the splitter reads them off its child. */\ntype PaneElement = React.ReactElement<SplitterPaneProps>;\n\nconst isPane = (child: React.ReactNode): child is PaneElement =>\n React.isValidElement(child) && child.type === SplitterPane;\n\n/** The bounds with pane `i`'s changed, for a move that mustn't snap it shut. */\nconst withBound = (\n bounds: PaneBounds[],\n i: number,\n change: Partial<PaneBounds>\n) => bounds.map((bound, j) => (j === i ? { ...bound, ...change } : bound));\n\n/** The bounds with neither pane beside handle `h` able to shut. */\nconst opened = (bounds: PaneBounds[], h: number) =>\n withBound(withBound(bounds, h, { collapsible: false }), h + 1, {\n collapsible: false,\n });\n\n/**\n * The handle a pane's collapse goes through: the one that speaks for it. A\n * collapsible pane that isn't last always has the handle after it, so the\n * one left without is a last pane whose neighbour can collapse too, and it\n * goes through the handle before it.\n */\nconst handleFor = (pane: number, bounds: PaneBounds[]) =>\n pane < bounds.length - 1 && primaryOf(pane, bounds) === pane\n ? pane\n : pane - 1;\n\n/**\n * The `Splitter` component lays out two or more panes side by side or one above the other, with a handle between each pair to drag or move by keyboard.\n *\n * Each handle is a focusable `separator`, named by the `label` of the pane\n * it speaks for. Sizes are percentages, so the server renders the layout\n * the browser does, and `minSize` and `maxSize` also take `px` and `rem`. A\n * `collapsible` pane shuts when dragged below half its minimum, and Enter on\n * its handle shuts it and brings it back. It doesn't store sizes itself:\n * keep them with `sizes` and `onSizesChange`.\n *\n * @function\n * @param {SplitterProps} props - Props for the Splitter component.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the root `<div>`.\n * @returns {JSX.Element} The rendered splitter.\n *\n * @example\n * <Splitter height={480}>\n * <Splitter.Pane label=\"Files\" defaultSize={25} minSize=\"12rem\">…</Splitter.Pane>\n * <Splitter.Pane label=\"Editor\">…</Splitter.Pane>\n * </Splitter>\n */\nconst SplitterRoot = forwardRef<HTMLDivElement, SplitterProps>(\n (\n {\n className,\n style,\n textColor,\n bgColor,\n orientation = 'horizontal',\n height,\n sizes: sizesProp,\n onSizesChange,\n step = 1,\n children,\n ...props\n },\n ref\n ) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n const vertical = orientation === 'vertical';\n const rootClass = usePrefixedClassNames('splitter', {\n 'is-vertical': vertical,\n });\n const handleClass = usePrefixedClassNames('splitter-handle');\n const activeClass = usePrefixedClassNames('is-active');\n\n const panes = flattenChildren(children).filter(isPane);\n const baseId = useId();\n const ids = panes.map((pane, i) => pane.props.id ?? `${baseId}-pane-${i}`);\n\n // The room the panes share, in pixels, and a rem, both measured in the\n // browser. Until then, only percentage limits apply.\n const [length, setLength] = useState<number | null>(null);\n const [remPx, setRemPx] = useState(16);\n const bounds: PaneBounds[] = panes.map(({ props: pane }) => ({\n min: Math.max(0, limitToPercent(pane.minSize, length, remPx) ?? 0),\n max: Math.min(100, limitToPercent(pane.maxSize, length, remPx) ?? 100),\n collapsible: !!pane.collapsible,\n }));\n const boundsKey = JSON.stringify(bounds);\n\n // Shuts pane `i`, giving its room to the pane across the handle that\n // speaks for it, when that pane can take it within its maximum, as a\n // drag would. A lone pane has no handle and nowhere to give its room.\n const collapseIn = (current: number[], i: number) => {\n if (current.length < 2) return current;\n const h = handleFor(i, bounds);\n const across = h === i ? i + 1 : h;\n if (current[across] + current[i] > bounds[across].max + 1e-6) {\n return current;\n }\n const next = [...current];\n next[across] += next[i];\n next[i] = 0;\n return next;\n };\n\n const startSizes = () => {\n const base = defaultSizes(panes.map(pane => pane.props.defaultSize));\n let next = fitSizes(base, bounds);\n panes.forEach(({ props: pane }, i) => {\n if (pane.collapsible && (pane.collapsed ?? pane.defaultCollapsed)) {\n next = collapseIn(next, i);\n }\n });\n return next;\n };\n\n const paneKey = ids.join('|');\n const [state, setState] = useState(() => ({\n key: paneKey,\n sizes: startSizes(),\n }));\n // A different set of panes starts over from the defaults.\n let uncontrolled = state.sizes;\n if (state.key !== paneKey) {\n uncontrolled = startSizes();\n setState({ key: paneKey, sizes: uncontrolled });\n }\n const sizes =\n sizesProp && sizesProp.length === panes.length ? sizesProp : uncontrolled;\n\n // The size each pane comes back at after it's shut: the last size it had\n // open, or its default.\n const restoreRef = useRef<number[]>([]);\n const defaults = defaultSizes(panes.map(pane => pane.props.defaultSize));\n sizes.forEach((size, i) => {\n if (size > 0) restoreRef.current[i] = size;\n else restoreRef.current[i] ??= defaults[i];\n });\n\n const collapsedAt = (layout: number[]) =>\n layout.map((size, i) => bounds[i].collapsible && size <= 1e-6);\n\n // Moves the layout on, telling the app and each pane whose collapse\n // changed, unless the change came from its own `collapsed`. A move that\n // would collapse or open a pane whose `collapsed` the app holds only\n // asks: the app's answer comes back through `collapsed`.\n const sizesRef = useRef(sizes);\n sizesRef.current = sizes;\n const panesRef = useRef(panes);\n panesRef.current = panes;\n const commit = (next: number[], fromProp = false) => {\n const previous = sizesRef.current;\n if (sameSizes(previous, next)) return;\n const before = collapsedAt(previous);\n const after = collapsedAt(next);\n const flipped = after.flatMap((shut, i) =>\n shut !== before[i] ? [i] : []\n );\n if (\n !fromProp &&\n flipped.some(i => panesRef.current[i].props.collapsed !== undefined)\n ) {\n flipped.forEach(i =>\n panesRef.current[i].props.onCollapsedChange?.(after[i])\n );\n return;\n }\n sizesRef.current = next;\n if (!sizesProp) setState(current => ({ ...current, sizes: next }));\n onSizesChange?.(next);\n if (!fromProp) {\n flipped.forEach(i =>\n panesRef.current[i].props.onCollapsedChange?.(after[i])\n );\n }\n };\n\n // Brings pane `i` back at its restore size, taken from across the handle\n // that speaks for it.\n // A lone pane never shuts, so there's always a handle here.\n const expand = (current: number[], i: number) => {\n const h = handleFor(i, bounds);\n const target = restoreRef.current[i];\n const total = current[h] + current[h + 1];\n return resizePair(\n current,\n h,\n h === i ? target : total - target,\n // Opening one pane snaps neither shut: it stops at the limits.\n opened(bounds, h)\n );\n };\n\n // A pane's own `collapsed` moving: shut it or bring it back, before the\n // browser paints.\n const collapsedProps = panes.map(pane =>\n pane.props.collapsible ? pane.props.collapsed : undefined\n );\n const collapsedKey = JSON.stringify(collapsedProps);\n useClientLayoutEffect(() => {\n const current = sizesRef.current;\n const shut = collapsedAt(current);\n let next = current;\n collapsedProps.forEach((wanted, i) => {\n if (wanted === undefined || wanted === shut[i]) return;\n next = wanted ? collapseIn(next, i) : expand(next, i);\n });\n commit(next, true);\n // collapsedKey stands for collapsedProps.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [collapsedKey]);\n\n // Measuring: the room the panes share, so `px` and `rem` limits can turn\n // into percentages, then the layout fitted to them.\n const rootRef = useRef<HTMLDivElement | null>(null);\n const setRefs = useCallback(\n (node: HTMLDivElement | null) => {\n rootRef.current = node;\n if (typeof ref === 'function') return ref(node);\n if (ref) ref.current = node;\n },\n [ref]\n );\n // The room the panes share: the root's length less its handles'.\n const roomOf = useCallback(() => {\n const root = rootRef.current;\n /* istanbul ignore next: measuring only runs while it's mounted */\n if (!root) return null;\n const along = (el: Element) => {\n const rect = el.getBoundingClientRect();\n return vertical ? rect.height : rect.width;\n };\n const handles = Array.from(root.children).filter(child =>\n child.matches('[role=\"separator\"]')\n );\n const room =\n along(root) - handles.reduce((sum, handle) => sum + along(handle), 0);\n return room > 0 ? room : null;\n }, [vertical]);\n const measure = useCallback(() => {\n setLength(roomOf());\n setRemPx(\n parseFloat(getComputedStyle(document.documentElement).fontSize) || 16\n );\n }, [roomOf]);\n useClientLayoutEffect(() => {\n measure();\n const root = rootRef.current;\n if (!root || typeof ResizeObserver === 'undefined') return;\n const resizes = new ResizeObserver(measure);\n resizes.observe(root);\n return () => resizes.disconnect();\n }, [measure]);\n // Limits that changed, from measuring or from props: fit the layout.\n useClientLayoutEffect(() => {\n commit(fitSizes(sizesRef.current, bounds));\n // boundsKey stands for bounds.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [boundsKey]);\n\n const rtl = () =>\n !vertical &&\n !!rootRef.current &&\n getComputedStyle(rootRef.current).direction === 'rtl';\n\n // ---- Dragging ----\n const [dragging, setDragging] = useState<number | null>(null);\n const dragRef = useRef<{\n handle: number;\n start: number;\n startSizes: number[];\n pixels: number;\n flip: boolean;\n } | null>(null);\n const onPointerDown =\n (h: number) => (event: React.PointerEvent<HTMLDivElement>) => {\n if (event.button !== 0) return;\n const pixels = roomOf();\n if (!pixels) return;\n event.currentTarget.setPointerCapture?.(event.pointerId);\n dragRef.current = {\n handle: h,\n start: vertical ? event.clientY : event.clientX,\n startSizes: sizesRef.current,\n pixels,\n flip: rtl(),\n };\n setDragging(h);\n };\n const onPointerMove = (event: React.PointerEvent<HTMLDivElement>) => {\n const drag = dragRef.current;\n if (!drag) return;\n const moved = (vertical ? event.clientY : event.clientX) - drag.start;\n const delta = ((drag.flip ? -moved : moved) / drag.pixels) * 100;\n commit(\n resizePair(\n sizesRef.current,\n drag.handle,\n drag.startSizes[drag.handle] + delta,\n bounds\n )\n );\n };\n const endDrag = (event: React.PointerEvent<HTMLDivElement>) => {\n if (!dragRef.current) return;\n dragRef.current = null;\n event.currentTarget.releasePointerCapture?.(event.pointerId);\n setDragging(null);\n };\n // While dragging, the resize cursor shows wherever the pointer goes.\n useEffect(() => {\n if (dragging === null) return;\n const body = document.body.style;\n const { cursor, userSelect } = body;\n body.cursor = vertical ? 'row-resize' : 'col-resize';\n body.userSelect = 'none';\n return () => {\n body.cursor = cursor;\n body.userSelect = userSelect;\n };\n }, [dragging, vertical]);\n\n // Double-click: the two panes back to their default share of the room.\n const onDoubleClick = (h: number) => () => {\n const current = sizesRef.current;\n const total = current[h] + current[h + 1];\n const pair = defaults[h] + defaults[h + 1];\n const target = pair > 0 ? (defaults[h] / pair) * total : total / 2;\n const next = [...current];\n next[h] = target;\n next[h + 1] = total - target;\n commit(fitSizes(next, bounds));\n };\n\n // ---- Keys ----\n const onKeyDown =\n (h: number) => (event: React.KeyboardEvent<HTMLDivElement>) => {\n const current = sizesRef.current;\n const primary = primaryOf(h, bounds);\n const by = event.shiftKey ? step * 10 : step;\n const back = vertical ? 'ArrowUp' : 'ArrowLeft';\n const forward = vertical ? 'ArrowDown' : 'ArrowRight';\n // The line moves the way the key points, so right to left, moving\n // right shrinks the pane before, which sits on the right.\n const sign = rtl() ? -1 : 1;\n // Keys move within the limits; Enter is what shuts a pane.\n const open = opened(bounds, h);\n let next: number[] | null = null;\n if (event.key === back || event.key === forward) {\n const direction = (event.key === forward ? 1 : -1) * sign;\n next = resizePair(current, h, current[h] + direction * by, open);\n } else if (event.key === 'Home' || event.key === 'End') {\n const range = primaryRange(current, h, primary, open);\n const size = event.key === 'Home' ? range.min : range.max;\n const total = current[h] + current[h + 1];\n next = resizePair(\n current,\n h,\n primary === h ? size : total - size,\n open\n );\n } else if (event.key === 'Enter' && bounds[primary].collapsible) {\n next =\n current[primary] > 1e-6\n ? collapseIn(current, primary)\n : expand(current, primary);\n }\n if (!next) return;\n event.preventDefault();\n commit(next);\n };\n\n // A handle names its pane, so a pane without a label leaves it nameless.\n const unnamed = panes\n .slice(0, -1)\n .some((_, h) => !panes[primaryOf(h, bounds)].props.label);\n useEffect(() => {\n if (unnamed) {\n warnOnce(\n 'Splitter:unlabelled',\n '[bestax-bulma] <Splitter> has a handle whose pane has no label. ' +\n 'Give each Splitter.Pane a label, so a screen reader can say ' +\n 'which pane a handle resizes.'\n );\n }\n }, [unnamed]);\n\n const collapsed = collapsedAt(sizes);\n const items: React.ReactNode[] = [];\n panes.forEach((pane, i) => {\n items.push(\n <PaneContext.Provider\n // Children.toArray, under flattenChildren, keys every child.\n key={`pane-${String(pane.key)}`}\n value={{ id: ids[i], size: sizes[i], collapsed: collapsed[i] }}\n >\n {pane}\n </PaneContext.Provider>\n );\n if (i === panes.length - 1) return;\n const primary = primaryOf(i, bounds);\n const range = primaryRange(sizes, i, primary, bounds);\n items.push(\n <div\n key={`handle-${i}`}\n className={classNames(handleClass, dragging === i && activeClass)}\n role=\"separator\"\n tabIndex={0}\n aria-orientation={vertical ? 'horizontal' : 'vertical'}\n aria-valuenow={Math.round(range.now)}\n aria-valuemin={Math.round(range.min)}\n aria-valuemax={Math.round(range.max)}\n aria-controls={ids[primary]}\n aria-label={panes[primary].props.label}\n onPointerDown={onPointerDown(i)}\n onPointerMove={onPointerMove}\n onPointerUp={endDrag}\n onPointerCancel={endDrag}\n onDoubleClick={onDoubleClick(i)}\n onKeyDown={onKeyDown(i)}\n />\n );\n });\n\n return (\n <div\n ref={setRefs}\n className={classNames(rootClass, bulmaHelperClasses, className)}\n style={height !== undefined ? { ...style, height } : style}\n {...rest}\n >\n {items}\n </div>\n );\n }\n);\n\nSplitterRoot.displayName = 'Splitter';\n\nexport const Splitter = withSubComponents(SplitterRoot, {\n Pane: SplitterPane,\n});\n\nexport default Splitter;\n"],"names":["_jsx"],"mappings":"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"}
|