@vuu-ui/vuu-ui-controls 3.5.5 → 3.5.6

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.
Files changed (150) hide show
  1. package/package.json +10 -10
  2. package/src/index.js +1 -0
  3. package/src/split-pane/SplitPane.css.js +82 -0
  4. package/src/split-pane/SplitPane.js +60 -0
  5. package/src/split-pane/Splitter.js +82 -0
  6. package/src/split-pane/index.js +1 -0
  7. package/src/split-pane/useSplitPane.js +101 -0
  8. package/types/index.d.ts +1 -0
  9. package/types/split-pane/SplitPane.d.ts +44 -0
  10. package/types/split-pane/Splitter.d.ts +10 -0
  11. package/types/split-pane/index.d.ts +2 -0
  12. package/types/split-pane/useSplitPane.d.ts +18 -0
  13. package/types/src/calendar/Calendar.d.ts +0 -13
  14. package/types/src/calendar/index.d.ts +0 -4
  15. package/types/src/calendar/internal/CalendarCarousel.d.ts +0 -3
  16. package/types/src/calendar/internal/CalendarContext.d.ts +0 -8
  17. package/types/src/calendar/internal/CalendarDay.d.ts +0 -14
  18. package/types/src/calendar/internal/CalendarMonth.d.ts +0 -10
  19. package/types/src/calendar/internal/CalendarNavigation.d.ts +0 -16
  20. package/types/src/calendar/internal/CalendarWeekHeader.d.ts +0 -3
  21. package/types/src/calendar/internal/useFocusManagement.d.ts +0 -9
  22. package/types/src/calendar/internal/utils.d.ts +0 -15
  23. package/types/src/calendar/useCalendar.d.ts +0 -54
  24. package/types/src/calendar/useCalendarDay.d.ts +0 -22
  25. package/types/src/calendar/useSelection.d.ts +0 -78
  26. package/types/src/column-picker/ColumnPicker.d.ts +0 -7
  27. package/types/src/column-picker/ColumnSearch.d.ts +0 -12
  28. package/types/src/column-picker/index.d.ts +0 -2
  29. package/types/src/column-picker/moving-window.d.ts +0 -14
  30. package/types/src/common-hooks/index.d.ts +0 -3
  31. package/types/src/common-hooks/selectionTypes.d.ts +0 -70
  32. package/types/src/common-hooks/use-resize-observer.d.ts +0 -16
  33. package/types/src/common-hooks/useControlled.d.ts +0 -24
  34. package/types/src/context-panel-provider/ContextPanelProvider.d.ts +0 -17
  35. package/types/src/cycle-state-button/CycleStateButton.d.ts +0 -11
  36. package/types/src/cycle-state-button/index.d.ts +0 -1
  37. package/types/src/date-input/DateInput.d.ts +0 -60
  38. package/types/src/date-input/index.d.ts +0 -1
  39. package/types/src/date-picker/DatePicker.d.ts +0 -66
  40. package/types/src/date-picker/DatePickerContext.d.ts +0 -19
  41. package/types/src/date-picker/DatePickerPanel.d.ts +0 -10
  42. package/types/src/date-picker/index.d.ts +0 -1
  43. package/types/src/drag-drop/DragDropProvider.d.ts +0 -38
  44. package/types/src/drag-drop/DragDropState.d.ts +0 -15
  45. package/types/src/drag-drop/Draggable.d.ts +0 -13
  46. package/types/src/drag-drop/DropIndicator.d.ts +0 -5
  47. package/types/src/drag-drop/dragDropTypes.d.ts +0 -100
  48. package/types/src/drag-drop/drop-target-utils.d.ts +0 -82
  49. package/types/src/drag-drop/index.d.ts +0 -6
  50. package/types/src/drag-drop/useAutoScroll.d.ts +0 -11
  51. package/types/src/drag-drop/useDragDisplacers.d.ts +0 -17
  52. package/types/src/drag-drop/useDragDrop.d.ts +0 -2
  53. package/types/src/drag-drop/useDragDropCopy.d.ts +0 -6
  54. package/types/src/drag-drop/useDragDropIndicator.d.ts +0 -2
  55. package/types/src/drag-drop/useDragDropNaturalMovement.d.ts +0 -2
  56. package/types/src/drag-drop/useDropIndicator.d.ts +0 -8
  57. package/types/src/drag-drop/useGlobalDragDrop.d.ts +0 -11
  58. package/types/src/drag-drop/useTransition.d.ts +0 -3
  59. package/types/src/editable/index.d.ts +0 -1
  60. package/types/src/editable/useEditableText.d.ts +0 -21
  61. package/types/src/editable-label/EditableLabel.d.ts +0 -19
  62. package/types/src/editable-label/index.d.ts +0 -1
  63. package/types/src/expando-input/ExpandoInput.d.ts +0 -6
  64. package/types/src/expando-input/index.d.ts +0 -1
  65. package/types/src/highlighter/Highlighter.d.ts +0 -6
  66. package/types/src/highlighter/index.d.ts +0 -1
  67. package/types/src/hover-overlay/HoverOverlay.d.ts +0 -8
  68. package/types/src/icon-button/Icon.d.ts +0 -6
  69. package/types/src/icon-button/IconButton.d.ts +0 -6
  70. package/types/src/icon-button/ToggleIconButton.d.ts +0 -5
  71. package/types/src/icon-button/index.d.ts +0 -3
  72. package/types/src/index.d.ts +0 -33
  73. package/types/src/instrument-picker/SearchCell.d.ts +0 -2
  74. package/types/src/instrument-picker/TablePicker.d.ts +0 -11
  75. package/types/src/instrument-picker/index.d.ts +0 -1
  76. package/types/src/instrument-picker/moving-window.d.ts +0 -14
  77. package/types/src/instrument-picker/useDataSource.d.ts +0 -6
  78. package/types/src/instrument-picker/useTablePicker.d.ts +0 -47
  79. package/types/src/item-picker/ItemPicker.d.ts +0 -14
  80. package/types/src/item-picker/useItemPicker.d.ts +0 -35
  81. package/types/src/measured-container/MeasuredContainer.d.ts +0 -16
  82. package/types/src/measured-container/index.d.ts +0 -2
  83. package/types/src/measured-container/useMeasuredContainer.d.ts +0 -23
  84. package/types/src/modal-provider/ModalProvider.d.ts +0 -13
  85. package/types/src/overflow-container/OverflowContainer.d.ts +0 -15
  86. package/types/src/overflow-container/index.d.ts +0 -2
  87. package/types/src/overflow-container/overflow-utils.d.ts +0 -48
  88. package/types/src/overflow-container/useOverflowContainer.d.ts +0 -19
  89. package/types/src/price-ticker/PriceTicker.d.ts +0 -7
  90. package/types/src/price-ticker/index.d.ts +0 -1
  91. package/types/src/prompt/Prompt.d.ts +0 -53
  92. package/types/src/sortable-list/SortableList.d.ts +0 -8
  93. package/types/src/split-button/SplitButton.d.ts +0 -11
  94. package/types/src/split-button/SplitStateButton.d.ts +0 -5
  95. package/types/src/split-button/index.d.ts +0 -2
  96. package/types/src/split-button/useSplitButton.d.ts +0 -311
  97. package/types/src/table-search/SearchCell.d.ts +0 -2
  98. package/types/src/table-search/TableSearch.d.ts +0 -9
  99. package/types/src/table-search/index.d.ts +0 -1
  100. package/types/src/table-search/moving-window.d.ts +0 -14
  101. package/types/src/table-search/useTableSearch.d.ts +0 -15
  102. package/types/src/tabs-next/TabBar.d.ts +0 -12
  103. package/types/src/tabs-next/TabListNext.d.ts +0 -12
  104. package/types/src/tabs-next/TabNext.d.ts +0 -12
  105. package/types/src/tabs-next/TabNextAction.d.ts +0 -5
  106. package/types/src/tabs-next/TabNextContext.d.ts +0 -12
  107. package/types/src/tabs-next/TabNextPanel.d.ts +0 -8
  108. package/types/src/tabs-next/TabNextTrigger.d.ts +0 -5
  109. package/types/src/tabs-next/TabOverflowList.d.ts +0 -11
  110. package/types/src/tabs-next/TabsNext.d.ts +0 -17
  111. package/types/src/tabs-next/TabsNextContext.d.ts +0 -21
  112. package/types/src/tabs-next/hooks/useCollection.d.ts +0 -18
  113. package/types/src/tabs-next/hooks/useFocusOutside.d.ts +0 -2
  114. package/types/src/tabs-next/hooks/useOverflow.d.ts +0 -11
  115. package/types/src/tabs-next/index.d.ts +0 -7
  116. package/types/src/tabstrip/Tab.d.ts +0 -27
  117. package/types/src/tabstrip/TabMenu.d.ts +0 -23
  118. package/types/src/tabstrip/TabMenuOptions.d.ts +0 -10
  119. package/types/src/tabstrip/TabsTypes.d.ts +0 -127
  120. package/types/src/tabstrip/Tabstrip.d.ts +0 -3
  121. package/types/src/tabstrip/index.d.ts +0 -5
  122. package/types/src/tabstrip/tabstrip-dom-utils.d.ts +0 -2
  123. package/types/src/tabstrip/useAnimatedSelectionThumb.d.ts +0 -7
  124. package/types/src/tabstrip/useKeyboardNavigation.d.ts +0 -29
  125. package/types/src/tabstrip/useSelection.d.ts +0 -13
  126. package/types/src/tabstrip/useTabstrip.d.ts +0 -55
  127. package/types/src/time-input/MaskedInput.d.ts +0 -49
  128. package/types/src/time-input/TimeInput.d.ts +0 -5
  129. package/types/src/time-input/useTimeInput.d.ts +0 -21
  130. package/types/src/toolbar/Toolbar.d.ts +0 -20
  131. package/types/src/toolbar/index.d.ts +0 -1
  132. package/types/src/toolbar/toolbar-dom-utils.d.ts +0 -3
  133. package/types/src/toolbar/useKeyboardNavigation.d.ts +0 -32
  134. package/types/src/toolbar/useSelection.d.ts +0 -22
  135. package/types/src/toolbar/useToolbar.d.ts +0 -28
  136. package/types/src/utils/deprecated-types.d.ts +0 -2
  137. package/types/src/utils/escapeRegExp.d.ts +0 -1
  138. package/types/src/utils/forwardCallbackProps.d.ts +0 -3
  139. package/types/src/utils/index.d.ts +0 -5
  140. package/types/src/utils/isOverflowElement.d.ts +0 -1
  141. package/types/src/utils/isPlainObject.d.ts +0 -1
  142. package/types/src/vuu-date-picker/VuuDatePicker.d.ts +0 -7
  143. package/types/src/vuu-date-picker/index.d.ts +0 -1
  144. package/types/src/vuu-input/VuuInput.d.ts +0 -18
  145. package/types/src/vuu-input/index.d.ts +0 -1
  146. package/types/src/vuu-time-picker/TimeRangePicker.d.ts +0 -0
  147. package/types/src/vuu-time-picker/VuuTimePicker.d.ts +0 -7
  148. package/types/src/vuu-typeahead-input/VuuTypeaheadInput.d.ts +0 -6
  149. package/types/src/vuu-typeahead-input/index.d.ts +0 -1
  150. package/types/src/vuu-typeahead-input/useVuuTypeaheadInput.d.ts +0 -49
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "3.5.5",
2
+ "version": "3.5.6",
3
3
  "description": "VUU UI Controls",
4
4
  "main": "./src/index.js",
5
5
  "author": "heswell",
@@ -10,17 +10,17 @@
10
10
  "type-defs": "node ../../scripts/build-type-defs.mjs"
11
11
  },
12
12
  "devDependencies": {
13
- "@vuu-ui/vuu-data-types": "3.5.5",
14
- "@vuu-ui/vuu-protocol-types": "3.5.5",
15
- "@vuu-ui/vuu-table-types": "3.5.5"
13
+ "@vuu-ui/vuu-data-types": "3.5.6",
14
+ "@vuu-ui/vuu-protocol-types": "3.5.6",
15
+ "@vuu-ui/vuu-table-types": "3.5.6"
16
16
  },
17
17
  "dependencies": {
18
- "@vuu-ui/vuu-context-menu": "3.5.5",
19
- "@vuu-ui/vuu-data-react": "3.5.5",
20
- "@vuu-ui/vuu-layout": "3.5.5",
21
- "@vuu-ui/vuu-popups": "3.5.5",
22
- "@vuu-ui/vuu-table": "3.5.5",
23
- "@vuu-ui/vuu-utils": "3.5.5",
18
+ "@vuu-ui/vuu-context-menu": "3.5.6",
19
+ "@vuu-ui/vuu-data-react": "3.5.6",
20
+ "@vuu-ui/vuu-layout": "3.5.6",
21
+ "@vuu-ui/vuu-popups": "3.5.6",
22
+ "@vuu-ui/vuu-table": "3.5.6",
23
+ "@vuu-ui/vuu-utils": "3.5.6",
24
24
  "@salt-ds/core": "1.54.1",
25
25
  "@salt-ds/icons": "1.16.0",
26
26
  "@salt-ds/styles": "0.2.1",
package/src/index.js CHANGED
@@ -14,6 +14,7 @@ export * from "./measured-container/index.js";
14
14
  export * from "./overflow-container/index.js";
15
15
  export * from "./price-ticker/index.js";
16
16
  export * from "./split-button/index.js";
17
+ export * from "./split-pane/index.js";
17
18
  export * from "./table-search/index.js";
18
19
  export * from "./tabs-next/index.js";
19
20
  export * from "./tabstrip/index.js";
@@ -0,0 +1,82 @@
1
+ const css = `
2
+ .vuuSplitPane {
3
+ --vuuSplitPane-align: stretch;
4
+ --vuuSplitPane-direction: row;
5
+ --vuuSplitPane-gap: 0;
6
+ --vuuSplitPane-justify: flex-start;
7
+ --vuuSplitPane-margin: 0;
8
+ --vuuSplitPane-padding: 0;
9
+ --vuuSplitPane-splitterSize: 3px;
10
+ --vuuSplitPane-splitter-background: var(--salt-separable-secondary-borderColor);
11
+ --vuuSplitPane-splitter-background-active: var(--salt-separable-primary-borderColor);
12
+ --vuuSplitPane-splitter-grabZone: 4px;
13
+ align-items: var(--vuuSplitPane-align);
14
+ box-sizing: border-box;
15
+ flex-direction: var(--vuuSplitPane-direction);
16
+ gap: var(--vuuSplitPane-gap);
17
+ justify-content: var(--vuuSplitPane-justify);
18
+ margin: var(--vuuSplitPane-margin);
19
+ min-width: 0;
20
+ min-height: 0;
21
+ padding: var(--vuuSplitPane-padding);
22
+ flex-wrap: nowrap;
23
+ display: flex;
24
+ overflow: hidden;
25
+ }
26
+
27
+ :where(.vuuSplitPane) > :where(:not(.vuuSplitPane-splitter)) {
28
+ box-sizing: border-box;
29
+ }
30
+
31
+ :where(.vuuSplitPane-row) > :where(:not(.vuuSplitPane-splitter)) {
32
+ min-width: 0;
33
+ }
34
+
35
+ :where(.vuuSplitPane-column) > :where(:not(.vuuSplitPane-splitter)) {
36
+ min-height: 0;
37
+ }
38
+
39
+ .vuuSplitPane-splitter {
40
+ background-color: var(--vuuSplitPane-splitter-background);
41
+ flex: 0 0 var(--vuuSplitPane-splitterSize);
42
+ touch-action: none;
43
+ z-index: 1;
44
+ outline: none;
45
+ position: relative;
46
+ }
47
+
48
+ .vuuSplitPane-splitter:before {
49
+ content: "";
50
+ position: absolute;
51
+ inset: 0;
52
+ }
53
+
54
+ .vuuSplitPane-row > .vuuSplitPane-splitter {
55
+ cursor: ew-resize;
56
+ }
57
+
58
+ .vuuSplitPane-row > .vuuSplitPane-splitter:before {
59
+ left: calc(-1 * var(--vuuSplitPane-splitter-grabZone));
60
+ right: calc(-1 * var(--vuuSplitPane-splitter-grabZone));
61
+ }
62
+
63
+ .vuuSplitPane-column > .vuuSplitPane-splitter {
64
+ cursor: ns-resize;
65
+ }
66
+
67
+ .vuuSplitPane-column > .vuuSplitPane-splitter:before {
68
+ bottom: calc(-1 * var(--vuuSplitPane-splitter-grabZone));
69
+ top: calc(-1 * var(--vuuSplitPane-splitter-grabZone));
70
+ }
71
+
72
+ .vuuSplitPane-splitter:hover, .vuuSplitPane-splitter-active {
73
+ --vuuSplitPane-splitter-background: var(--vuuSplitPane-splitter-background-active);
74
+ }
75
+
76
+ .vuuSplitPane-splitter:focus-visible {
77
+ outline: var(--salt-focused-outline);
78
+ }
79
+
80
+
81
+ `;
82
+ export default css;
@@ -0,0 +1,60 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { resolveResponsiveValue, useBreakpoint, useForkRef } from "@salt-ds/core";
3
+ import { useComponentCssInjection } from "@salt-ds/styles";
4
+ import { useWindow } from "@salt-ds/window";
5
+ import clsx from "clsx";
6
+ import { Children, forwardRef } from "react";
7
+ import { Splitter } from "./Splitter.js";
8
+ import { useSplitPane } from "./useSplitPane.js";
9
+ import SplitPane_0 from "./SplitPane.css";
10
+ const classBase = "vuuSplitPane";
11
+ const parseSpacing = (value)=>"number" == typeof value ? `calc(var(--salt-spacing-100) * ${value})` : value;
12
+ const parseAlignment = (value)=>"start" === value || "end" === value ? `flex-${value}` : value;
13
+ const SplitPane_SplitPane = /*#__PURE__*/ forwardRef(function({ align, children, className, direction = "row", gap = 0, justify, margin = 0, onSplitterMoved, padding = 0, splitterSize, style, ...htmlAttributes }, forwardedRef) {
14
+ const targetWindow = useWindow();
15
+ useComponentCssInjection({
16
+ testId: "vuu-split-pane",
17
+ css: SplitPane_0,
18
+ window: targetWindow
19
+ });
20
+ const { matchedBreakpoints } = useBreakpoint();
21
+ const flexDirection = resolveResponsiveValue(direction, matchedBreakpoints) ?? "row";
22
+ const flexGap = resolveResponsiveValue(gap, matchedBreakpoints);
23
+ const flexMargin = resolveResponsiveValue(margin, matchedBreakpoints);
24
+ const flexPadding = resolveResponsiveValue(padding, matchedBreakpoints);
25
+ const panes = Children.toArray(children);
26
+ if (panes.length > 2) throw Error(`[SplitPane] supports a maximum of two children, ${panes.length} were provided`);
27
+ const { beginResize, endResize, resize, rootRef, splitterPosition } = useSplitPane({
28
+ direction: flexDirection,
29
+ onSplitterMoved,
30
+ paneCount: panes.length
31
+ });
32
+ const splitPaneStyle = {
33
+ ...style,
34
+ "--vuuSplitPane-align": parseAlignment(align),
35
+ "--vuuSplitPane-direction": flexDirection,
36
+ "--vuuSplitPane-gap": parseSpacing(flexGap),
37
+ "--vuuSplitPane-justify": parseAlignment(justify),
38
+ "--vuuSplitPane-margin": parseSpacing(flexMargin),
39
+ "--vuuSplitPane-padding": parseSpacing(flexPadding),
40
+ "--vuuSplitPane-splitterSize": void 0 === splitterSize ? void 0 : `${splitterSize}px`
41
+ };
42
+ return /*#__PURE__*/ jsxs("div", {
43
+ ...htmlAttributes,
44
+ className: clsx(classBase, `${classBase}-${flexDirection}`, className),
45
+ ref: useForkRef(rootRef, forwardedRef),
46
+ style: splitPaneStyle,
47
+ children: [
48
+ panes[0],
49
+ 2 === panes.length ? /*#__PURE__*/ jsx(Splitter, {
50
+ direction: flexDirection,
51
+ onResize: resize,
52
+ onResizeEnd: endResize,
53
+ onResizeStart: beginResize,
54
+ position: splitterPosition
55
+ }) : null,
56
+ panes[1]
57
+ ]
58
+ });
59
+ });
60
+ export { SplitPane_SplitPane as SplitPane };
@@ -0,0 +1,82 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import clsx from "clsx";
3
+ import { useCallback, useRef, useState } from "react";
4
+ const classBase = "vuuSplitPane-splitter";
5
+ const KEYBOARD_STEP = 1;
6
+ const KEYBOARD_STEP_LARGE = 10;
7
+ const Splitter = ({ className, direction, onResize, onResizeEnd, onResizeStart, position, ...htmlAttributes })=>{
8
+ const startPosRef = useRef(void 0);
9
+ const [active, setActive] = useState(false);
10
+ const isColumn = "column" === direction;
11
+ const getPointerPos = useCallback((e)=>isColumn ? e.clientY : e.clientX, [
12
+ isColumn
13
+ ]);
14
+ const handlePointerDown = useCallback((e)=>{
15
+ if (0 === e.button && onResizeStart()) {
16
+ e.preventDefault();
17
+ e.currentTarget.focus();
18
+ e.currentTarget.setPointerCapture(e.pointerId);
19
+ startPosRef.current = getPointerPos(e);
20
+ setActive(true);
21
+ }
22
+ }, [
23
+ getPointerPos,
24
+ onResizeStart
25
+ ]);
26
+ const handlePointerMove = useCallback((e)=>{
27
+ if (void 0 !== startPosRef.current) onResize(getPointerPos(e) - startPosRef.current);
28
+ }, [
29
+ getPointerPos,
30
+ onResize
31
+ ]);
32
+ const handlePointerEnd = useCallback(()=>{
33
+ if (void 0 !== startPosRef.current) {
34
+ startPosRef.current = void 0;
35
+ setActive(false);
36
+ onResizeEnd();
37
+ }
38
+ }, [
39
+ onResizeEnd
40
+ ]);
41
+ const handleKeyDown = useCallback((e)=>{
42
+ const step = e.shiftKey ? KEYBOARD_STEP_LARGE : KEYBOARD_STEP;
43
+ const [decrementKey, incrementKey] = isColumn ? [
44
+ "ArrowUp",
45
+ "ArrowDown"
46
+ ] : [
47
+ "ArrowLeft",
48
+ "ArrowRight"
49
+ ];
50
+ const distance = e.key === decrementKey ? -step : e.key === incrementKey ? step : "Home" === e.key ? -1 / 0 : "End" === e.key ? 1 / 0 : void 0;
51
+ if (void 0 !== distance && onResizeStart()) {
52
+ e.preventDefault();
53
+ onResize(distance);
54
+ onResizeEnd();
55
+ }
56
+ }, [
57
+ isColumn,
58
+ onResize,
59
+ onResizeEnd,
60
+ onResizeStart
61
+ ]);
62
+ return /*#__PURE__*/ jsx("div", {
63
+ "aria-label": "Resize",
64
+ ...htmlAttributes,
65
+ "aria-orientation": isColumn ? "horizontal" : "vertical",
66
+ "aria-valuemax": 100,
67
+ "aria-valuemin": 0,
68
+ "aria-valuenow": position,
69
+ className: clsx(classBase, className, {
70
+ [`${classBase}-active`]: active
71
+ }),
72
+ onKeyDown: handleKeyDown,
73
+ onLostPointerCapture: handlePointerEnd,
74
+ onPointerCancel: handlePointerEnd,
75
+ onPointerDown: handlePointerDown,
76
+ onPointerMove: handlePointerMove,
77
+ onPointerUp: handlePointerEnd,
78
+ role: "separator",
79
+ tabIndex: 0
80
+ });
81
+ };
82
+ export { Splitter };
@@ -0,0 +1 @@
1
+ export * from "./SplitPane.js";
@@ -0,0 +1,101 @@
1
+ import { useCallback, useLayoutEffect, useRef, useState } from "react";
2
+ const parsePx = (value, defaultValue)=>value.endsWith("px") ? parseFloat(value) : defaultValue;
3
+ const measurePane = (el, dimension)=>{
4
+ const { [dimension]: size } = el.getBoundingClientRect();
5
+ const style = getComputedStyle(el);
6
+ return {
7
+ size,
8
+ minSize: parsePx(style.getPropertyValue(`min-${dimension}`), 0),
9
+ maxSize: parsePx(style.getPropertyValue(`max-${dimension}`), 1 / 0)
10
+ };
11
+ };
12
+ const getPanes = (root)=>{
13
+ const pane1 = root?.children[0];
14
+ const pane2 = root?.children[2];
15
+ if (pane1 && pane2) return [
16
+ pane1,
17
+ pane2
18
+ ];
19
+ };
20
+ const toPercentage = ([size1, size2])=>{
21
+ const total = size1 + size2;
22
+ return 0 === total ? 0 : Math.round(size1 / total * 100);
23
+ };
24
+ const useSplitPane = ({ direction, onSplitterMoved, paneCount })=>{
25
+ const rootRef = useRef(null);
26
+ const resizeStateRef = useRef(void 0);
27
+ const [splitterPosition, setSplitterPosition] = useState(void 0);
28
+ const dimension = "column" === direction ? "height" : "width";
29
+ const hasSplitter = 2 === paneCount;
30
+ useLayoutEffect(()=>{
31
+ const panes = hasSplitter ? getPanes(rootRef.current) : void 0;
32
+ if (panes) {
33
+ const [pane1, pane2] = panes;
34
+ setSplitterPosition(toPercentage([
35
+ pane1.getBoundingClientRect()[dimension],
36
+ pane2.getBoundingClientRect()[dimension]
37
+ ]));
38
+ }
39
+ }, [
40
+ dimension,
41
+ hasSplitter
42
+ ]);
43
+ const beginResize = useCallback(()=>{
44
+ const panes = getPanes(rootRef.current);
45
+ if (panes) {
46
+ const [pane1, pane2] = panes;
47
+ const measurements = [
48
+ measurePane(pane1, dimension),
49
+ measurePane(pane2, dimension)
50
+ ];
51
+ resizeStateRef.current = {
52
+ panes,
53
+ measurements,
54
+ sizes: [
55
+ measurements[0].size,
56
+ measurements[1].size
57
+ ]
58
+ };
59
+ return true;
60
+ }
61
+ return false;
62
+ }, [
63
+ dimension
64
+ ]);
65
+ const resize = useCallback((distance)=>{
66
+ const resizeState = resizeStateRef.current;
67
+ if (resizeState) {
68
+ const { panes: [pane1, pane2], measurements: [m1, m2] } = resizeState;
69
+ const total = m1.size + m2.size;
70
+ const lowerBound = Math.max(m1.minSize, total - m2.maxSize);
71
+ const upperBound = Math.min(m1.maxSize, total - m2.minSize);
72
+ const size1 = Math.max(lowerBound, Math.min(upperBound, m1.size + distance));
73
+ const size2 = total - size1;
74
+ pane1.style.flexBasis = `${size1}px`;
75
+ pane2.style.flexBasis = `${size2}px`;
76
+ resizeState.sizes = [
77
+ size1,
78
+ size2
79
+ ];
80
+ }
81
+ }, []);
82
+ const endResize = useCallback(()=>{
83
+ const resizeState = resizeStateRef.current;
84
+ if (resizeState) {
85
+ resizeStateRef.current = void 0;
86
+ const { measurements, sizes } = resizeState;
87
+ setSplitterPosition(toPercentage(sizes));
88
+ if (sizes[0] !== measurements[0].size || sizes[1] !== measurements[1].size) onSplitterMoved?.(sizes);
89
+ }
90
+ }, [
91
+ onSplitterMoved
92
+ ]);
93
+ return {
94
+ beginResize,
95
+ endResize,
96
+ resize,
97
+ rootRef,
98
+ splitterPosition
99
+ };
100
+ };
101
+ export { useSplitPane };
package/types/index.d.ts CHANGED
@@ -21,6 +21,7 @@ export * from "./price-ticker";
21
21
  export { Prompt, type PromptProps } from "./prompt/Prompt";
22
22
  export { SortableList, SortableOption } from "./sortable-list/SortableList";
23
23
  export * from "./split-button";
24
+ export * from "./split-pane";
24
25
  export * from "./table-search";
25
26
  export * from "./tabs-next";
26
27
  export * from "./tabstrip";
@@ -0,0 +1,44 @@
1
+ import { type FlexAlignment, type FlexContentAlignment, type ResponsiveProp } from "@salt-ds/core";
2
+ import { type HTMLAttributes, type ReactElement, type ReactNode } from "react";
3
+ import { type SplitPaneDirection, type SplitterMovedHandler } from "./useSplitPane";
4
+ export interface SplitPaneProps extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
5
+ /**
6
+ * Defines the default behavior for how flex items are laid out along the cross axis, default is "stretch".
7
+ */
8
+ align?: FlexAlignment | "stretch" | "baseline";
9
+ /**
10
+ * Exactly two children, typically Salt `FlexItem` components. A Splitter
11
+ * will be rendered between them. A single child is also accepted (e.g. when
12
+ * one pane is conditionally rendered), in which case no Splitter is rendered.
13
+ */
14
+ children: ReactElement | [ReactNode, ReactNode];
15
+ /**
16
+ * Establishes the main-axis, defining the direction children are placed. Default is "row".
17
+ */
18
+ direction?: ResponsiveProp<SplitPaneDirection>;
19
+ /**
20
+ * Controls the space between each item and the Splitter, default is 0.
21
+ */
22
+ gap?: ResponsiveProp<number | string>;
23
+ /**
24
+ * Defines the alignment along the main axis, default is "start".
25
+ */
26
+ justify?: FlexContentAlignment;
27
+ /**
28
+ * Defines the margin around the component. It can be specified as a number (which acts as a multiplier) or a string representing the margin value. Default is `0`.
29
+ */
30
+ margin?: ResponsiveProp<number | string>;
31
+ /**
32
+ * Invoked when user has finished moving the Splitter, receives the new sizes (px) of both panes.
33
+ */
34
+ onSplitterMoved?: SplitterMovedHandler;
35
+ /**
36
+ * Defines the padding within the component. It can be specified as a number (which acts as a multiplier) or a string representing the padding value. Default is `0`.
37
+ */
38
+ padding?: ResponsiveProp<number | string>;
39
+ /**
40
+ * Size (thickness) of the Splitter, in px. Default is 3.
41
+ */
42
+ splitterSize?: number;
43
+ }
44
+ export declare const SplitPane: import("react").ForwardRefExoticComponent<SplitPaneProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,10 @@
1
+ import { type HTMLAttributes } from "react";
2
+ import type { SplitPaneDirection } from "./useSplitPane";
3
+ export interface SplitterProps extends Omit<HTMLAttributes<HTMLDivElement>, "onResize"> {
4
+ direction: SplitPaneDirection;
5
+ onResizeStart: () => boolean;
6
+ onResize: (distance: number) => void;
7
+ onResizeEnd: () => void;
8
+ position?: number;
9
+ }
10
+ export declare const Splitter: ({ className, direction, onResize, onResizeEnd, onResizeStart, position, ...htmlAttributes }: SplitterProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export * from "./SplitPane";
2
+ export type { SplitPaneDirection, SplitPaneSizes, SplitterMovedHandler, } from "./useSplitPane";
@@ -0,0 +1,18 @@
1
+ export type SplitPaneDirection = "row" | "column";
2
+ /**
3
+ * Sizes (in px) of the two panes, measured along the main axis.
4
+ */
5
+ export type SplitPaneSizes = [number, number];
6
+ export type SplitterMovedHandler = (sizes: SplitPaneSizes) => void;
7
+ export interface SplitPaneHookProps {
8
+ direction: SplitPaneDirection;
9
+ onSplitterMoved?: SplitterMovedHandler;
10
+ paneCount: number;
11
+ }
12
+ export declare const useSplitPane: ({ direction, onSplitterMoved, paneCount, }: SplitPaneHookProps) => {
13
+ beginResize: () => boolean;
14
+ endResize: () => void;
15
+ resize: (distance: number) => void;
16
+ rootRef: import("react").RefObject<HTMLDivElement | null>;
17
+ splitterPosition: number | undefined;
18
+ };
@@ -1,13 +0,0 @@
1
- import { type CalendarCarouselProps } from "./internal/CalendarCarousel";
2
- import { type CalendarNavigationProps } from "./internal/CalendarNavigation";
3
- import { type useCalendarProps } from "./useCalendar";
4
- export type CalendarProps = useCalendarProps & {
5
- className?: string;
6
- id?: string;
7
- renderDayContents?: CalendarCarouselProps["renderDayContents"];
8
- hideYearDropdown?: CalendarNavigationProps["hideYearDropdown"];
9
- borderedDropdown?: CalendarNavigationProps["borderedDropdown"];
10
- TooltipProps?: CalendarCarouselProps["TooltipProps"];
11
- hideOutOfRangeDates?: CalendarCarouselProps["hideOutOfRangeDates"];
12
- };
13
- export declare const Calendar: import("react").ForwardRefExoticComponent<CalendarProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -1,4 +0,0 @@
1
- export * from "./Calendar";
2
- export * from "./useCalendarDay";
3
- export * from "./useCalendar";
4
- export * from "./useSelection";
@@ -1,3 +0,0 @@
1
- import { type CalendarMonthProps } from "./CalendarMonth";
2
- export type CalendarCarouselProps = Omit<CalendarMonthProps, "date">;
3
- export declare const CalendarCarousel: import("react").ForwardRefExoticComponent<Omit<CalendarCarouselProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
@@ -1,8 +0,0 @@
1
- import type { useCalendar } from "../useCalendar";
2
- interface CalendarState {
3
- state: ReturnType<typeof useCalendar>["state"];
4
- helpers: ReturnType<typeof useCalendar>["helpers"];
5
- }
6
- declare const CalendarContext: import("react").Context<CalendarState | null>;
7
- declare function useCalendarContext(): CalendarState;
8
- export { CalendarContext, useCalendarContext };
@@ -1,14 +0,0 @@
1
- import type { DateValue } from "@internationalized/date";
2
- import { type TooltipProps } from "@salt-ds/core";
3
- import { type ComponentPropsWithRef, type ReactElement } from "react";
4
- import { type DayStatus } from "../useCalendarDay";
5
- export type DateFormatter = (day: Date) => string | undefined;
6
- export interface CalendarDayProps extends Omit<ComponentPropsWithRef<"button">, "children"> {
7
- day: DateValue;
8
- formatDate?: DateFormatter;
9
- renderDayContents?: (date: DateValue, status: DayStatus) => ReactElement;
10
- status?: DayStatus;
11
- month: DateValue;
12
- TooltipProps?: Partial<TooltipProps>;
13
- }
14
- export declare const CalendarDay: import("react").ForwardRefExoticComponent<Omit<CalendarDayProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
@@ -1,10 +0,0 @@
1
- import type { DateValue } from "@internationalized/date";
2
- import { type ComponentPropsWithRef } from "react";
3
- import { type CalendarDayProps } from "./CalendarDay";
4
- export interface CalendarMonthProps extends ComponentPropsWithRef<"div"> {
5
- date: DateValue;
6
- hideOutOfRangeDates?: boolean;
7
- renderDayContents?: CalendarDayProps["renderDayContents"];
8
- TooltipProps?: CalendarDayProps["TooltipProps"];
9
- }
10
- export declare const CalendarMonth: import("react").ForwardRefExoticComponent<Omit<CalendarMonthProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
@@ -1,16 +0,0 @@
1
- import { type ButtonProps, type DropdownProps } from "@salt-ds/core";
2
- import { type ComponentPropsWithRef } from "react";
3
- import { type DateValue } from "@internationalized/date";
4
- type dateDropdownProps = DropdownProps<DateValue>;
5
- export interface CalendarNavigationProps extends ComponentPropsWithRef<"div"> {
6
- MonthDropdownProps?: dateDropdownProps;
7
- YearDropdownProps?: dateDropdownProps;
8
- onMonthSelect?: dateDropdownProps["onChange"];
9
- onYearSelect?: dateDropdownProps["onChange"];
10
- borderedDropdown?: dateDropdownProps["bordered"];
11
- onNavigateNext?: ButtonProps["onClick"];
12
- onNavigatePrevious?: ButtonProps["onClick"];
13
- hideYearDropdown?: boolean;
14
- }
15
- export declare const CalendarNavigation: import("react").ForwardRefExoticComponent<Omit<CalendarNavigationProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
16
- export {};
@@ -1,3 +0,0 @@
1
- import { type ComponentPropsWithRef } from "react";
2
- export type CalendarWeekHeaderProps = ComponentPropsWithRef<"div">;
3
- export declare const CalendarWeekHeader: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
@@ -1,9 +0,0 @@
1
- import { type DateValue } from "@internationalized/date";
2
- import type { FocusEventHandler, KeyboardEventHandler, MouseEventHandler } from "react";
3
- export declare function useFocusManagement({ date }: {
4
- date: DateValue;
5
- }): {
6
- handleClick: MouseEventHandler<HTMLButtonElement>;
7
- handleKeyDown: KeyboardEventHandler<HTMLButtonElement>;
8
- handleFocus: FocusEventHandler<HTMLButtonElement>;
9
- };
@@ -1,15 +0,0 @@
1
- import { DateFormatter, type DateValue } from "@internationalized/date";
2
- export declare function getCurrentLocale(): string;
3
- export declare function getDateFormatter(options?: Intl.DateTimeFormatOptions): DateFormatter;
4
- export declare function formatDate(date: DateValue, options?: Intl.DateTimeFormatOptions): string;
5
- export declare function getCalender(): import("@internationalized/date").Calendar;
6
- type WeekdayFormat = Intl.DateTimeFormatOptions["weekday"];
7
- export declare function daysForLocale(weekday?: WeekdayFormat): string[];
8
- export declare function monthsForLocale(currentYear: DateValue): (import("@internationalized/date").CalendarDate | import("@internationalized/date").CalendarDateTime | import("@internationalized/date").ZonedDateTime)[];
9
- export declare function generateVisibleDays(currentMonth: DateValue): {
10
- date: DateValue;
11
- dateOfMonth: number;
12
- isCurrentMonth: boolean;
13
- }[];
14
- export declare function monthDiff(a: DateValue, b: DateValue): number;
15
- export {};
@@ -1,54 +0,0 @@
1
- import { type DateValue } from "@internationalized/date";
2
- import { type SyntheticEvent } from "react";
3
- import { type UseMultiSelectionCalendarProps, type UseOffsetSelectionCalendarProps, type UseRangeSelectionCalendarProps, type UseSingleSelectionCalendarProps } from "./useSelection";
4
- interface BaseUseCalendarProps {
5
- defaultVisibleMonth?: DateValue;
6
- onVisibleMonthChange?: (event: SyntheticEvent, visibleMonth: DateValue) => void;
7
- isDayUnselectable?: (date: DateValue) => string | false | undefined;
8
- isDayHighlighted?: (date: DateValue) => string | false | undefined;
9
- isDayDisabled?: (date: DateValue) => boolean;
10
- visibleMonth?: DateValue;
11
- hideOutOfRangeDates?: boolean;
12
- hideYearDropdown?: boolean;
13
- minDate?: DateValue;
14
- maxDate?: DateValue;
15
- }
16
- export type useCalendarProps = (Omit<UseSingleSelectionCalendarProps, "isDaySelectable"> | Omit<UseMultiSelectionCalendarProps, "isDaySelectable"> | Omit<UseRangeSelectionCalendarProps, "isDaySelectable"> | Omit<UseOffsetSelectionCalendarProps, "isDaySelectable">) & BaseUseCalendarProps;
17
- export declare function useCalendar(props: useCalendarProps): {
18
- state: {
19
- selectedDate: DateValue[] | {
20
- startDate?: DateValue;
21
- endDate?: DateValue;
22
- } | import("./useSelection").RangeSelectionValueType | DateValue | null | undefined;
23
- hoveredDate: import("@internationalized/date").CalendarDate | import("@internationalized/date").CalendarDateTime | import("@internationalized/date").ZonedDateTime | null | undefined;
24
- visibleMonth: DateValue;
25
- focusedDate: DateValue;
26
- minDate: DateValue | undefined;
27
- maxDate: DateValue | undefined;
28
- selectionVariant: "default" | "multiselect" | "offset" | "range";
29
- hideOutOfRangeDates: boolean | undefined;
30
- calendarFocused: boolean;
31
- };
32
- helpers: {
33
- setSelectedDate: (event: SyntheticEvent<HTMLButtonElement>, newSelectedDate: DateValue) => void;
34
- isSelected: (date: DateValue) => boolean;
35
- setHoveredDate: (event: SyntheticEvent, date: DateValue | null) => void;
36
- isHovered: (date: DateValue) => boolean;
37
- isSelectedSpan: (date: DateValue) => boolean;
38
- isHoveredSpan: (date: DateValue) => boolean;
39
- isSelectedStart: (date: DateValue) => boolean;
40
- isSelectedEnd: (date: DateValue) => boolean;
41
- isHoveredOffset: (date: DateValue) => boolean;
42
- setVisibleMonth: (event: SyntheticEvent, newVisibleMonth: DateValue) => void;
43
- setFocusedDate: (event: SyntheticEvent, date: DateValue) => void;
44
- setCalendarFocused: import("react").Dispatch<import("react").SetStateAction<boolean>>;
45
- isDayUnselectable: (date: DateValue) => string | false | undefined;
46
- isDayHighlighted: (date: DateValue) => string | false | undefined;
47
- isDayDisabled: (date: DateValue) => boolean;
48
- isDayVisible: (date: DateValue) => boolean;
49
- isOutsideAllowedDates: (date: DateValue) => boolean;
50
- isOutsideAllowedMonths: (date: DateValue) => boolean;
51
- isOutsideAllowedYears: (date: DateValue) => boolean;
52
- };
53
- };
54
- export {};
@@ -1,22 +0,0 @@
1
- import { type DateValue } from "@internationalized/date";
2
- import { type ComponentPropsWithoutRef, type RefObject } from "react";
3
- export interface DayStatus {
4
- outOfRange?: boolean;
5
- selected?: boolean;
6
- today?: boolean;
7
- unselectable?: string | false;
8
- highlighted?: string | false;
9
- focused?: boolean;
10
- disabled?: boolean;
11
- hidden?: boolean;
12
- }
13
- export interface useCalendarDayProps {
14
- date: DateValue;
15
- month: DateValue;
16
- }
17
- export declare function useCalendarDay({ date, month }: useCalendarDayProps, ref: RefObject<HTMLElement | null>): {
18
- status: DayStatus;
19
- dayProps: ComponentPropsWithoutRef<"button">;
20
- unselectableReason: string | false | undefined;
21
- highlightedReason: string | false | undefined;
22
- };