@gfazioli/mantine-split-pane 1.1.6 → 2.0.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.
@@ -3,6 +3,7 @@
3
3
 
4
4
  var React = require('react');
5
5
  var core = require('@mantine/core');
6
+ var Split_context = require('../Split.context.cjs');
6
7
  var SplitPaneResizer_module = require('./SplitPaneResizer.module.css.cjs');
7
8
 
8
9
  const varsResolver = core.createVarsResolver(
@@ -33,14 +34,23 @@ const varsResolver = core.createVarsResolver(
33
34
  theme
34
35
  });
35
36
  const hoverColorDarkParsed = core.parseThemeColor({
36
- color: hoverColor || "dark.3",
37
+ color: hoverColor || theme.primaryColor,
37
38
  theme
38
39
  });
39
40
  const hoverColorLightParsed = core.parseThemeColor({
40
- color: hoverColor || "gray.4",
41
+ color: hoverColor || theme.primaryColor,
42
+ theme
43
+ });
44
+ const knobColorParsed = core.parseThemeColor({
45
+ color: knobColor || theme.primaryColor,
46
+ theme
47
+ });
48
+ const knobHoverColorParsed = core.parseThemeColor({
49
+ color: knobHoverColor || "white",
41
50
  theme
42
51
  });
43
52
  const knobVariant = variant === "dotted" || variant === "dashed";
53
+ const forceKnobOpacityValue = withKnob && knobAlwaysOn && !knobVariant ? knobOpacity : "0";
44
54
  return {
45
55
  root: {
46
56
  "--split-resizer-size": core.getSize(size, "split-resizer-size"),
@@ -51,11 +61,11 @@ const varsResolver = core.createVarsResolver(
51
61
  "--split-resizer-hover-color-dark": core.rgba(hoverColorDarkParsed.value, 1),
52
62
  "--split-resizer-radius": core.getRadius(radius),
53
63
  "--split-resizer-knob-size": core.getSize(knobSize, "split-resizer-knob-size"),
54
- "--split-resizer-knob-opacity": withKnob && knobAlwaysOn && !knobVariant ? knobOpacity : "0",
64
+ "--split-resizer-knob-opacity": forceKnobOpacityValue,
55
65
  "--split-resizer-knob-hover-opacity": withKnob || knobVariant ? "1" : "0",
56
66
  "--split-resizer-knob-radius": core.getRadius(knobRadius),
57
- "--split-resizer-knob-color": core.getThemeColor(knobColor, theme),
58
- "--split-resizer-knob-hover-color": core.getThemeColor(knobHoverColor, theme),
67
+ "--split-resizer-knob-color": core.rgba(knobColorParsed.value, Number(forceKnobOpacityValue)),
68
+ "--split-resizer-knob-hover-color": core.rgba(knobHoverColorParsed.value, 1),
59
69
  "--split-resizer-spacing": core.getSize(spacing, "split-resizer-spacing"),
60
70
  "--split-resizer-cursor-vertical": cursorVertical || "col-resize",
61
71
  "--split-resizer-cursor-horizontal": cursorHorizontal || "row-resize"
@@ -64,55 +74,52 @@ const varsResolver = core.createVarsResolver(
64
74
  }
65
75
  );
66
76
  const defaultProps = {
67
- size: "md",
77
+ orientation: "vertical",
68
78
  opacity: 0.8,
79
+ size: "sm",
69
80
  radius: "xs",
70
- knobColor: "blue",
81
+ withKnob: false,
82
+ knobAlwaysOn: true,
71
83
  knobSize: "sm",
72
84
  knobOpacity: 0.5,
73
85
  knobRadius: "sm",
74
- minWidth: 20,
75
- minHeight: 20,
76
- orientation: "vertical",
77
- paneRef: { current: null },
78
- variant: "default",
79
- withKnob: false,
80
- knobAlwaysOn: true,
86
+ knobColor: "white",
87
+ knobHoverColor: "white",
88
+ spacing: "xs",
81
89
  step: 8,
82
90
  shiftStep: 64,
83
91
  cursorVertical: "col-resize",
84
92
  cursorHorizontal: "row-resize"
85
93
  };
86
- const SplitPaneResizer = core.factory((_props, ref) => {
87
- const props = core.useProps("Resizer", defaultProps, _props);
94
+ const SplitPaneResizer = core.factory((_props, _) => {
95
+ const ctx = Split_context.useSplitContext();
96
+ const props = core.useProps("SplitPaneResizer", { ...defaultProps, ...ctx }, _props);
88
97
  const {
89
- size,
98
+ orientation,
90
99
  opacity,
100
+ size,
91
101
  radius,
92
- color,
93
- hoverColor,
102
+ withKnob,
103
+ knobAlwaysOn,
94
104
  knobSize,
95
105
  knobOpacity,
96
106
  knobRadius,
97
107
  knobColor,
98
108
  knobHoverColor,
99
- minWidth,
100
- minHeight,
101
- maxWidth,
102
- maxHeight,
103
- orientation,
104
- onResizeStart,
105
- onResizing,
106
- onResizeEnd,
107
- paneRef,
108
- variant,
109
- withKnob,
110
- knobAlwaysOn,
111
109
  spacing,
112
110
  step,
113
111
  shiftStep,
114
112
  cursorVertical,
115
113
  cursorHorizontal,
114
+ color,
115
+ hoverColor,
116
+ variant,
117
+ onResizeStart,
118
+ onResizing,
119
+ onResizeEnd,
120
+ onDoubleClick,
121
+ __beforeRef: beforeRef,
122
+ __afterRef: afterRef,
116
123
  className,
117
124
  style,
118
125
  classNames,
@@ -120,7 +127,7 @@ const SplitPaneResizer = core.factory((_props, ref) => {
120
127
  unstyled,
121
128
  vars,
122
129
  mod,
123
- ...others
130
+ ...rest
124
131
  } = props;
125
132
  const getStyles = core.useStyles({
126
133
  name: "SplitPaneResizer",
@@ -135,6 +142,150 @@ const SplitPaneResizer = core.factory((_props, ref) => {
135
142
  varsResolver
136
143
  });
137
144
  const containerRef = React.useRef(null);
145
+ const processVerticalSize = (deltaX = 0) => {
146
+ const minBeforeWidth = beforeRef.current.getMinWidth();
147
+ const maxBeforeWidth = beforeRef.current.getMaxWidth();
148
+ const minAfterWidth = afterRef.current.getMinWidth();
149
+ const maxAfterWidth = afterRef.current.getMaxWidth();
150
+ const beforePane = beforeRef.current.splitPane;
151
+ const afterPane = afterRef.current.splitPane;
152
+ let beforeWidth = beforePane.getBoundingClientRect().width;
153
+ let afterWidth = afterPane.getBoundingClientRect().width;
154
+ const isBeforeWidthMaxExceeded = maxBeforeWidth && beforeWidth + deltaX > maxBeforeWidth;
155
+ const isAfterWidthMaxExceeded = maxAfterWidth && afterWidth - deltaX > maxAfterWidth;
156
+ const isBeforeWidthMinExceeded = minBeforeWidth && beforeWidth + deltaX < minBeforeWidth;
157
+ const isAfterWidthMinExceeded = minAfterWidth && afterWidth - deltaX < minAfterWidth;
158
+ const isBeforeWidthNegative = beforeWidth + deltaX < 0;
159
+ const isAfterWidthNegative = afterWidth - deltaX < 0;
160
+ function setVerticalSize() {
161
+ const beforeWidthString = `${beforeWidth}px`;
162
+ const afterWidthString = `${afterWidth}px`;
163
+ const beforePaneSizes = {
164
+ width: beforeWidth,
165
+ height: beforePane.getBoundingClientRect().height
166
+ };
167
+ const afterPaneSizes = {
168
+ width: afterWidth,
169
+ height: afterPane.getBoundingClientRect().height
170
+ };
171
+ beforeRef.current.onResizing?.(beforePaneSizes);
172
+ afterRef.current.onResizing?.(afterPaneSizes);
173
+ onResizing?.({
174
+ beforePane: beforePaneSizes,
175
+ afterPane: afterPaneSizes
176
+ });
177
+ beforePane.style.width = beforeWidthString;
178
+ afterPane.style.width = afterWidthString;
179
+ }
180
+ if (!isAfterWidthMaxExceeded && isBeforeWidthMinExceeded) {
181
+ afterWidth += beforeWidth - minBeforeWidth;
182
+ beforeWidth = minBeforeWidth;
183
+ return setVerticalSize();
184
+ }
185
+ if (!isAfterWidthMaxExceeded && isBeforeWidthNegative) {
186
+ afterWidth += beforeWidth;
187
+ beforeWidth = 0;
188
+ return setVerticalSize();
189
+ }
190
+ if (!isAfterWidthMinExceeded && !isAfterWidthNegative && isBeforeWidthMaxExceeded) {
191
+ afterWidth -= maxBeforeWidth - beforeWidth;
192
+ beforeWidth = maxBeforeWidth;
193
+ return setVerticalSize();
194
+ }
195
+ if (!isBeforeWidthMaxExceeded && isAfterWidthMinExceeded) {
196
+ beforeWidth += afterWidth - minAfterWidth;
197
+ afterWidth = minAfterWidth;
198
+ return setVerticalSize();
199
+ }
200
+ if (!isBeforeWidthMaxExceeded && isAfterWidthNegative) {
201
+ beforeWidth += afterWidth;
202
+ afterWidth = 0;
203
+ return setVerticalSize();
204
+ }
205
+ if (!isBeforeWidthMinExceeded && !isBeforeWidthNegative && isAfterWidthMaxExceeded) {
206
+ beforeWidth -= maxAfterWidth - afterWidth;
207
+ afterWidth = maxAfterWidth;
208
+ return setVerticalSize();
209
+ }
210
+ if (isBeforeWidthNegative || isAfterWidthNegative || isBeforeWidthMaxExceeded || isAfterWidthMaxExceeded || isBeforeWidthMinExceeded || isAfterWidthMinExceeded) {
211
+ return;
212
+ }
213
+ beforeWidth += deltaX;
214
+ afterWidth -= deltaX;
215
+ setVerticalSize();
216
+ };
217
+ const processHorizontalSize = (deltaY = 0) => {
218
+ const minBeforeHeight = beforeRef.current.getMinHeight();
219
+ const maxBeforeHeight = beforeRef.current.getMaxHeight();
220
+ const minAfterHeight = afterRef.current.getMinHeight();
221
+ const maxAfterHeight = afterRef.current.getMaxHeight();
222
+ const beforePane = beforeRef.current.splitPane;
223
+ const afterPane = afterRef.current.splitPane;
224
+ let beforeHeight = beforePane.getBoundingClientRect().height;
225
+ let afterHeight = afterPane.getBoundingClientRect().height;
226
+ const isBeforeHeightMaxExceeded = maxBeforeHeight && beforeHeight + deltaY > maxBeforeHeight;
227
+ const isAfterHeightMaxExceeded = maxAfterHeight && afterHeight - deltaY > maxAfterHeight;
228
+ const isBeforeHeightMinExceeded = minBeforeHeight && beforeHeight + deltaY < minBeforeHeight;
229
+ const isAfterHeightMinExceeded = minAfterHeight && afterHeight - deltaY < minAfterHeight;
230
+ const isBeforeHeightNegative = beforeHeight + deltaY < 0;
231
+ const isAfterHeightNegative = afterHeight - deltaY < 0;
232
+ function setHorizontalSize() {
233
+ const beforeHeightString = `${beforeHeight}px`;
234
+ const afterHeightString = `${afterHeight}px`;
235
+ const beforePaneSizes = {
236
+ width: beforePane.getBoundingClientRect().width,
237
+ height: beforeHeight
238
+ };
239
+ const afterPaneSizes = {
240
+ width: afterPane.getBoundingClientRect().width,
241
+ height: afterHeight
242
+ };
243
+ onResizing?.({
244
+ beforePane: beforePaneSizes,
245
+ afterPane: afterPaneSizes
246
+ });
247
+ beforeRef.current.onResizing?.(beforePaneSizes);
248
+ afterRef.current.onResizing?.(afterPaneSizes);
249
+ beforePane.style.height = beforeHeightString;
250
+ afterPane.style.height = afterHeightString;
251
+ }
252
+ if (!isAfterHeightMaxExceeded && isBeforeHeightMinExceeded) {
253
+ afterHeight += beforeHeight - minBeforeHeight;
254
+ beforeHeight = minBeforeHeight;
255
+ return setHorizontalSize();
256
+ }
257
+ if (!isAfterHeightMaxExceeded && isBeforeHeightNegative) {
258
+ afterHeight += beforeHeight;
259
+ beforeHeight = 0;
260
+ return setHorizontalSize();
261
+ }
262
+ if (!isAfterHeightMinExceeded && !isAfterHeightNegative && isBeforeHeightMaxExceeded) {
263
+ afterHeight -= maxBeforeHeight - beforeHeight;
264
+ beforeHeight = maxBeforeHeight;
265
+ return setHorizontalSize();
266
+ }
267
+ if (!isBeforeHeightMaxExceeded && isAfterHeightMinExceeded) {
268
+ beforeHeight += afterHeight - minAfterHeight;
269
+ afterHeight = minAfterHeight;
270
+ return setHorizontalSize();
271
+ }
272
+ if (!isBeforeHeightMaxExceeded && isAfterHeightNegative) {
273
+ beforeHeight += afterHeight;
274
+ afterHeight = 0;
275
+ return setHorizontalSize();
276
+ }
277
+ if (!isBeforeHeightMinExceeded && !isBeforeHeightNegative && isAfterHeightMaxExceeded) {
278
+ beforeHeight -= maxAfterHeight - afterHeight;
279
+ afterHeight = maxAfterHeight;
280
+ return setHorizontalSize();
281
+ }
282
+ if (isBeforeHeightNegative || isAfterHeightNegative || isBeforeHeightMaxExceeded || isAfterHeightMaxExceeded || isBeforeHeightMinExceeded || isAfterHeightMinExceeded) {
283
+ return;
284
+ }
285
+ beforeHeight += deltaY;
286
+ afterHeight -= deltaY;
287
+ setHorizontalSize();
288
+ };
138
289
  const handleStart = (event) => {
139
290
  event.preventDefault();
140
291
  event.stopPropagation();
@@ -149,110 +300,127 @@ const SplitPaneResizer = core.factory((_props, ref) => {
149
300
  document.addEventListener("touchend", handleTouchEnd);
150
301
  }
151
302
  onResizeStart?.();
152
- document.body.style.cursor = "col-resize";
303
+ beforeRef.current.onResizeStart?.();
304
+ afterRef.current.onResizeStart?.();
305
+ document.body.style.cursor = orientation === "vertical" ? cursorVertical : cursorHorizontal;
153
306
  };
154
307
  const handleMove = (event) => {
155
- if (!paneRef.current) return;
308
+ if (!beforeRef.current || !afterRef.current) {
309
+ throw new Error("beforeRef or afterRef is not defined");
310
+ }
156
311
  event.preventDefault();
157
312
  event.stopPropagation();
158
313
  const computedStyle = window.getComputedStyle(containerRef.current);
159
- const clientX = "clientX" in event ? event.clientX : event.touches[0].clientX;
160
- const clientY = "clientY" in event ? event.clientY : event.touches[0].clientY;
161
314
  if (orientation === "vertical") {
162
- const margin = parseFloat(computedStyle.getPropertyValue("margin-left")) + 1;
163
- const delta = clientX - paneRef.current.getBoundingClientRect().right - margin;
164
- const width = paneRef.current.getBoundingClientRect().width + delta;
165
- const widthString = `${width}px`;
166
- if (minWidth && width < minWidth) return;
167
- if (maxWidth && width > maxWidth) return;
168
- onResizing?.({
169
- width: widthString,
170
- height: paneRef.current.style.height
171
- });
172
- paneRef.current.style.width = widthString;
173
- } else {
174
- const margin = parseFloat(computedStyle.getPropertyValue("margin-top")) + 1;
175
- const delta = clientY - paneRef.current.getBoundingClientRect().bottom - margin;
176
- const height = paneRef.current.getBoundingClientRect().height + delta;
177
- const heightString = `${height}px`;
178
- if (minHeight && height < minHeight) return;
179
- if (maxHeight && height > maxHeight) return;
180
- onResizing?.({
181
- width: paneRef.current.style.width,
182
- height: heightString
183
- });
184
- paneRef.current.style.height = heightString;
315
+ const margin = parseFloat(computedStyle.getPropertyValue("margin-right")) - 1;
316
+ const clientX = "clientX" in event ? event.clientX : event.touches[0].clientX;
317
+ const deltaX = clientX - containerRef.current.getBoundingClientRect().left - margin;
318
+ return processVerticalSize(deltaX);
319
+ }
320
+ if (orientation === "horizontal") {
321
+ const margin = parseFloat(computedStyle.getPropertyValue("margin-bottom")) - 1;
322
+ const clientY = "clientY" in event ? event.clientY : event.touches[0].clientY;
323
+ const deltaY = clientY - containerRef.current.getBoundingClientRect().top - margin;
324
+ return processHorizontalSize(deltaY);
185
325
  }
186
326
  };
187
327
  const handleMouseUp = () => {
188
- if (!paneRef.current) return;
328
+ if (!beforeRef.current || !afterRef.current) {
329
+ throw new Error("beforeRef or afterRef is not defined");
330
+ }
189
331
  document.body.style.userSelect = "initial";
190
332
  document.body.style.webkitUserSelect = "initial";
191
333
  document.removeEventListener("mousemove", handleMove);
192
334
  document.removeEventListener("mouseup", handleMouseUp);
193
335
  document.body.style.cursor = "initial";
194
- const { width, height } = paneRef.current.style || {};
195
- onResizeEnd?.({ width, height });
336
+ const beforePane = beforeRef.current.splitPane;
337
+ const afterPane = afterRef.current.splitPane;
338
+ const beforePaneSizes = {
339
+ width: beforePane.getBoundingClientRect().width,
340
+ height: beforePane.getBoundingClientRect().height
341
+ };
342
+ const afterPaneSizes = {
343
+ width: afterPane.getBoundingClientRect().width,
344
+ height: afterPane.getBoundingClientRect().height
345
+ };
346
+ onResizeEnd?.({
347
+ beforePane: beforePaneSizes,
348
+ afterPane: afterPaneSizes
349
+ });
350
+ beforeRef.current.onResizeEnd?.(beforePaneSizes);
351
+ afterRef.current.onResizeEnd?.(afterPaneSizes);
196
352
  };
197
353
  const handleTouchEnd = () => {
198
- if (!paneRef.current) return;
354
+ if (!beforeRef.current || !afterRef.current) {
355
+ throw new Error("beforeRef or afterRef is not defined");
356
+ }
199
357
  document.removeEventListener("touchmove", handleMove);
200
358
  document.removeEventListener("touchend", handleTouchEnd);
201
359
  document.body.style.cursor = "initial";
202
- const { width, height } = paneRef.current.style || {};
203
- onResizeEnd?.({ width, height });
360
+ const beforePane = beforeRef.current.splitPane;
361
+ const afterPane = afterRef.current.splitPane;
362
+ const beforePaneSizes = {
363
+ width: beforePane.getBoundingClientRect().width,
364
+ height: beforePane.getBoundingClientRect().height
365
+ };
366
+ const afterPaneSizes = {
367
+ width: afterPane.getBoundingClientRect().width,
368
+ height: afterPane.getBoundingClientRect().height
369
+ };
370
+ onResizeEnd?.({
371
+ beforePane: beforePaneSizes,
372
+ afterPane: afterPaneSizes
373
+ });
374
+ beforeRef.current.onResizeEnd?.(beforePaneSizes);
375
+ afterRef.current.onResizeEnd?.(afterPaneSizes);
204
376
  };
205
377
  const handleKeyUp = (event) => {
206
378
  if (containerRef.current !== document.activeElement) {
207
379
  return;
208
380
  }
381
+ const code = event.nativeEvent.code;
382
+ const arrowLeftRight = code === "ArrowRight" || code === "ArrowLeft";
383
+ const arrowUpDown = code === "ArrowUp" || code === "ArrowDown";
209
384
  const delta = event.shiftKey ? shiftStep : step;
210
- if (orientation === "vertical" && (event.nativeEvent.code === "ArrowRight" || event.nativeEvent.code === "ArrowLeft")) {
385
+ if (orientation === "vertical" && arrowLeftRight) {
211
386
  event.preventDefault();
212
387
  event.stopPropagation();
213
- const deltaSign = event.nativeEvent.code === "ArrowRight" ? 1 : -1;
214
- const width = paneRef.current.getBoundingClientRect().width + delta * deltaSign;
215
- const widthString = `${width}px`;
216
- if (minWidth && width < minWidth) return;
217
- if (maxWidth && width > maxWidth) return;
218
- onResizing?.({
219
- width: widthString,
220
- height: paneRef.current.style.height
221
- });
222
- paneRef.current.style.width = widthString;
388
+ const deltaSign = code === "ArrowRight" ? 1 : -1;
389
+ const deltaX = delta * deltaSign;
390
+ return processVerticalSize(deltaX);
223
391
  }
224
- if (orientation === "horizontal" && (event.nativeEvent.code === "ArrowUp" || event.nativeEvent.code === "ArrowDown")) {
392
+ if (orientation === "horizontal" && arrowUpDown) {
225
393
  event.preventDefault();
226
394
  event.stopPropagation();
227
- const deltaSign = event.nativeEvent.code === "ArrowDown" ? 1 : -1;
228
- const height = paneRef.current.getBoundingClientRect().height + delta * deltaSign;
229
- const heightString = `${height}px`;
230
- if (minHeight && height < minHeight) return;
231
- if (maxHeight && height > maxHeight) return;
232
- onResizing?.({
233
- width: paneRef.current.style.width,
234
- height: heightString
235
- });
236
- paneRef.current.style.height = heightString;
395
+ const deltaSign = code === "ArrowDown" ? 1 : -1;
396
+ const deltaY = delta * deltaSign;
397
+ return processHorizontalSize(deltaY);
237
398
  }
238
- if (event.nativeEvent.code === "Escape") {
399
+ if (code === "Escape") {
239
400
  event.preventDefault();
240
401
  event.stopPropagation();
241
402
  containerRef.current.blur();
242
403
  }
243
404
  };
405
+ const handleDoubleClick = (e) => {
406
+ e.preventDefault();
407
+ e.stopPropagation();
408
+ beforeRef.current.resetInitialSize(e);
409
+ afterRef.current.resetInitialSize(e);
410
+ onDoubleClick?.(e);
411
+ };
244
412
  return /* @__PURE__ */ React.createElement(
245
413
  core.UnstyledButton,
246
414
  {
247
- onDoubleClick: props?.onDoubleClick,
248
415
  ref: containerRef,
249
416
  mod: { orientation },
250
417
  onMouseDown: handleStart,
251
418
  onKeyDown: handleKeyUp,
252
419
  onTouchStart: handleStart,
420
+ onDoubleClick: handleDoubleClick,
253
421
  "aria-label": "Resize",
254
- ...getStyles("root", { variant }),
255
- ...others
422
+ ...getStyles("root", { variant: variant || "default" }),
423
+ ...rest
256
424
  }
257
425
  );
258
426
  });
@@ -260,4 +428,5 @@ SplitPaneResizer.classes = SplitPaneResizer_module;
260
428
  SplitPaneResizer.displayName = "SplitPaneResizer";
261
429
 
262
430
  exports.SplitPaneResizer = SplitPaneResizer;
431
+ exports.defaultProps = defaultProps;
263
432
  //# sourceMappingURL=SplitPaneResizer.cjs.map