@vuu-ui/vuu-layout 2.1.19-beta.1 → 2.1.19-beta.2

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 (89) hide show
  1. package/package.json +12 -13
  2. package/src/Component.js +14 -0
  3. package/src/LayoutContainer.css.js +24 -0
  4. package/src/LayoutContainer.js +26 -0
  5. package/src/debug.js +16 -0
  6. package/src/dock-layout/DockLayout.css.js +36 -0
  7. package/src/dock-layout/DockLayout.js +43 -0
  8. package/src/dock-layout/Drawer.css.js +150 -0
  9. package/src/dock-layout/Drawer.js +82 -0
  10. package/src/dock-layout/index.js +2 -0
  11. package/src/drag-drop/BoxModel.js +337 -0
  12. package/src/drag-drop/DragState.js +119 -0
  13. package/src/drag-drop/Draggable.js +140 -0
  14. package/src/drag-drop/DropTarget.js +286 -0
  15. package/src/drag-drop/DropTargetRenderer.js +275 -0
  16. package/src/drag-drop/dragDropTypes.js +0 -0
  17. package/src/drag-drop/index.js +3 -0
  18. package/src/flexbox/Flexbox.css.js +45 -0
  19. package/src/flexbox/Flexbox.js +45 -0
  20. package/src/flexbox/FlexboxLayout.js +27 -0
  21. package/src/flexbox/Splitter.css.js +57 -0
  22. package/src/flexbox/Splitter.js +112 -0
  23. package/src/flexbox/flexbox-utils.js +92 -0
  24. package/src/flexbox/flexboxTypes.js +0 -0
  25. package/src/flexbox/index.js +2 -0
  26. package/src/flexbox/useSplitterResizing.js +181 -0
  27. package/src/index.js +20 -0
  28. package/src/layout-action.js +20 -0
  29. package/src/layout-header/ActionButton.js +15 -0
  30. package/src/layout-header/Header.css.js +32 -0
  31. package/src/layout-header/Header.js +99 -0
  32. package/src/layout-header/index.js +1 -0
  33. package/src/layout-header/useHeader.js +76 -0
  34. package/src/layout-provider/LayoutProvider.js +242 -0
  35. package/src/layout-provider/LayoutProviderContext.js +13 -0
  36. package/src/layout-provider/index.js +2 -0
  37. package/src/layout-provider/useLayoutDragDrop.js +147 -0
  38. package/src/layout-reducer/flexUtils.js +186 -0
  39. package/src/layout-reducer/index.js +4 -0
  40. package/src/layout-reducer/insert-layout-element.js +179 -0
  41. package/src/layout-reducer/layout-reducer.js +121 -0
  42. package/src/layout-reducer/layoutTypes.js +34 -0
  43. package/src/layout-reducer/layoutUtils.js +178 -0
  44. package/src/layout-reducer/move-layout-element.js +18 -0
  45. package/src/layout-reducer/remove-layout-element.js +161 -0
  46. package/src/layout-reducer/replace-layout-element.js +70 -0
  47. package/src/layout-reducer/resize-flex-children.js +48 -0
  48. package/src/layout-reducer/wrap-layout-element.js +134 -0
  49. package/src/layout-view/View.css.js +76 -0
  50. package/src/layout-view/View.js +116 -0
  51. package/src/layout-view/useView.js +69 -0
  52. package/src/layout-view/useViewBroadcastChannel.js +29 -0
  53. package/src/layout-view/useViewResize.js +27 -0
  54. package/src/layout-view/viewTypes.js +0 -0
  55. package/src/layout-view-actions/ViewContext.js +11 -0
  56. package/src/layout-view-actions/useViewActionDispatcher.js +116 -0
  57. package/src/layout-view-actions/useViewContributions.js +31 -0
  58. package/src/palette/Palette.css.js +31 -0
  59. package/src/palette/Palette.js +85 -0
  60. package/src/palette/index.js +1 -0
  61. package/src/placeholder/LayoutStartPanel.css.js +35 -0
  62. package/src/placeholder/LayoutStartPanel.js +57 -0
  63. package/src/placeholder/Placeholder.css.js +20 -0
  64. package/src/placeholder/Placeholder.js +33 -0
  65. package/src/placeholder/index.js +1 -0
  66. package/src/responsive/index.js +2 -0
  67. package/src/responsive/measureMinimumNodeSize.js +24 -0
  68. package/src/responsive/useResizeObserver.js +109 -0
  69. package/src/responsive/utils.js +27 -0
  70. package/src/stack/Stack.css.js +44 -0
  71. package/src/stack/Stack.js +98 -0
  72. package/src/stack/StackLayout.js +116 -0
  73. package/src/stack/index.js +3 -0
  74. package/src/stack/stackTypes.js +0 -0
  75. package/src/tabs/TabPanel.css.js +17 -0
  76. package/src/tabs/TabPanel.js +11 -0
  77. package/src/tabs/index.js +1 -0
  78. package/src/tools/config-wrapper/ConfigWrapper.js +55 -0
  79. package/src/tools/config-wrapper/index.js +1 -0
  80. package/src/tools/devtools-box/layout-configurator.css.js +113 -0
  81. package/src/tools/devtools-tree/layout-tree-viewer.css.js +17 -0
  82. package/src/tools/index.js +3 -0
  83. package/src/use-persistent-state.js +43 -0
  84. package/src/utils/index.js +5 -0
  85. package/src/utils/pathUtils.js +212 -0
  86. package/src/utils/propUtils.js +15 -0
  87. package/src/utils/refUtils.js +5 -0
  88. package/src/utils/styleUtils.js +9 -0
  89. package/src/utils/typeOf.js +15 -0
@@ -0,0 +1,57 @@
1
+ const css = `
2
+ .vuuSplitter {
3
+ --splitter-background: var(--salt-separable-secondary-borderColor);
4
+ --splitter-borderColor: var(--salt-separable-secondary-borderColor);
5
+ --splitter-borderStyle: none;
6
+ --splitter-borderWidth: 0;
7
+ --splitter-size: 3px;
8
+ background-color: var(--splitter-background);
9
+ border-color: var(--splitter-borderColor);
10
+ border-style: var(--splitter-borderStyle);
11
+ border-width: var(--splitter-borderWidth);
12
+ box-sizing: border-box;
13
+ z-index: 1;
14
+ outline: none;
15
+ justify-content: center;
16
+ align-items: center;
17
+ display: flex;
18
+ position: relative;
19
+ }
20
+
21
+ .vuuSplitter:hover, .vuuSplitter-active {
22
+ --splitter-background: var(--salt-separable-primary-borderColor);
23
+ }
24
+
25
+ .vuuSplitter-column {
26
+ cursor: ns-resize;
27
+ height: var(--splitter-size);
28
+ }
29
+
30
+ .vuuSplitter:not(.vuuSplitter-column) {
31
+ cursor: ew-resize;
32
+ width: var(--splitter-size);
33
+ }
34
+
35
+ .vuuSplitter-grab-zone {
36
+ cursor: inherit;
37
+ background-color: #ff000003;
38
+ position: absolute;
39
+ }
40
+
41
+ .vuuSplitter-column .vuuSplitter-grab-zone {
42
+ inset: -5px 0;
43
+ }
44
+
45
+ .vuuSplitter:not(.vuuSplitter-column) .vuuSplitter-grab-zone {
46
+ inset: 0 -5px;
47
+ }
48
+
49
+ .vuuSplitter-active:not(.vuuSplitter-column) .vuuSplitter-grab-zone {
50
+ background-color: #ffffff03;
51
+ left: -150px;
52
+ right: -150px;
53
+ }
54
+
55
+
56
+ `;
57
+ export default css;
@@ -0,0 +1,112 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useComponentCssInjection } from "@salt-ds/styles";
3
+ import { useWindow } from "@salt-ds/window";
4
+ import clsx from "clsx";
5
+ import react, { useCallback, useRef, useState } from "react";
6
+ import Splitter_0 from "./Splitter.css";
7
+ const classBase = "vuuSplitter";
8
+ const Splitter_Splitter = /*#__PURE__*/ react.memo(function({ column, index, onDrag, onDragEnd, onDragStart, style }) {
9
+ const targetWindow = useWindow();
10
+ useComponentCssInjection({
11
+ testId: "vuu-splitter",
12
+ css: Splitter_0,
13
+ window: targetWindow
14
+ });
15
+ const ignoreClick = useRef(void 0);
16
+ const rootRef = useRef(null);
17
+ const lastPos = useRef(0);
18
+ const [active, setActive] = useState(false);
19
+ const handleKeyDownDrag = useCallback(({ key, shiftKey })=>{
20
+ const distance = shiftKey ? 10 : 1;
21
+ if (column && "ArrowDown" === key) onDrag(index, distance);
22
+ else if (column && "ArrowUp" === key) onDrag(index, -distance);
23
+ else if (column || "ArrowLeft" !== key) {
24
+ if (!column && "ArrowRight" === key) onDrag(index, distance);
25
+ } else onDrag(index, -distance);
26
+ }, [
27
+ column,
28
+ index,
29
+ onDrag
30
+ ]);
31
+ const handleKeyDownInitDrag = useCallback((evt)=>{
32
+ const { key } = evt;
33
+ const horizontalMove = "ArrowLeft" === key || "ArrowRight" === key;
34
+ const verticalMove = "ArrowUp" === key || "ArrowDown" === key;
35
+ if (column && verticalMove || !column && horizontalMove) {
36
+ onDragStart(index);
37
+ handleKeyDownDrag(evt);
38
+ keyDownHandlerRef.current = handleKeyDownDrag;
39
+ }
40
+ }, [
41
+ column,
42
+ handleKeyDownDrag,
43
+ index,
44
+ onDragStart
45
+ ]);
46
+ const keyDownHandlerRef = useRef(handleKeyDownInitDrag);
47
+ const handleKeyDown = (evt)=>keyDownHandlerRef.current(evt);
48
+ const handleMouseMove = useCallback((e)=>{
49
+ ignoreClick.current = true;
50
+ const pos = e[column ? "clientY" : "clientX"];
51
+ const diff = pos - lastPos.current;
52
+ if (pos && pos !== lastPos.current) onDrag(index, diff);
53
+ lastPos.current = pos;
54
+ }, [
55
+ column,
56
+ index,
57
+ onDrag
58
+ ]);
59
+ const handleMouseUp = useCallback(()=>{
60
+ window.removeEventListener("mousemove", handleMouseMove, false);
61
+ window.removeEventListener("mouseup", handleMouseUp, false);
62
+ onDragEnd();
63
+ setActive(false);
64
+ rootRef.current?.focus();
65
+ }, [
66
+ handleMouseMove,
67
+ onDragEnd,
68
+ setActive
69
+ ]);
70
+ const handleMouseDown = useCallback((e)=>{
71
+ lastPos.current = column ? e.clientY : e.clientX;
72
+ onDragStart(index);
73
+ window.addEventListener("mousemove", handleMouseMove, false);
74
+ window.addEventListener("mouseup", handleMouseUp, false);
75
+ e.preventDefault();
76
+ setActive(true);
77
+ }, [
78
+ column,
79
+ handleMouseMove,
80
+ handleMouseUp,
81
+ index,
82
+ onDragStart,
83
+ setActive
84
+ ]);
85
+ const handleClick = ()=>{
86
+ if (ignoreClick.current) ignoreClick.current = false;
87
+ else rootRef.current?.focus();
88
+ };
89
+ const handleBlur = ()=>{
90
+ keyDownHandlerRef.current = handleKeyDownInitDrag;
91
+ };
92
+ const className = clsx(classBase, {
93
+ [`${classBase}-active`]: active,
94
+ [`${classBase}-column`]: column
95
+ });
96
+ return /*#__PURE__*/ jsx("div", {
97
+ className: className,
98
+ "data-splitter": true,
99
+ ref: rootRef,
100
+ role: "separator",
101
+ style: style,
102
+ onBlur: handleBlur,
103
+ onClick: handleClick,
104
+ onKeyDown: handleKeyDown,
105
+ onMouseDown: handleMouseDown,
106
+ tabIndex: 0,
107
+ children: /*#__PURE__*/ jsx("div", {
108
+ className: `${classBase}-grab-zone`
109
+ })
110
+ });
111
+ });
112
+ export { Splitter_Splitter as Splitter };
@@ -0,0 +1,92 @@
1
+ import { getIntrinsicSize, hasUnboundedFlexStyle } from "../layout-reducer/flexUtils.js";
2
+ import { getProp } from "../utils/index.js";
3
+ const NO_INTRINSIC_SIZE = {};
4
+ const SPLITTER = 1;
5
+ const PLACEHOLDER = 2;
6
+ const isIntrinsicallySized = (item)=>"number" == typeof item.intrinsicSize;
7
+ const getBreakPointValues = (breakPoints, component)=>{
8
+ const values = {};
9
+ breakPoints.forEach((breakPoint)=>{
10
+ values[breakPoint] = getProp(component, breakPoint);
11
+ });
12
+ return values;
13
+ };
14
+ const gatherChildMeta = (children, dimension, breakPoints)=>children.map((child, index)=>{
15
+ const resizeable = getProp(child, "resizeable");
16
+ const { [dimension]: intrinsicSize } = getIntrinsicSize(child) ?? NO_INTRINSIC_SIZE;
17
+ const flexOpen = hasUnboundedFlexStyle(child);
18
+ if (breakPoints) return {
19
+ index,
20
+ flexOpen,
21
+ intrinsicSize,
22
+ resizeable,
23
+ ...getBreakPointValues(breakPoints, child)
24
+ };
25
+ return {
26
+ index,
27
+ flexOpen,
28
+ intrinsicSize,
29
+ resizeable
30
+ };
31
+ });
32
+ const findSplitterAndPlaceholderPositions = (childMeta)=>{
33
+ const count = childMeta.length;
34
+ const allIntrinsic = childMeta.every(isIntrinsicallySized);
35
+ const splitterPositions = Array(count).fill(0);
36
+ if (allIntrinsic && count > 0) {
37
+ splitterPositions[0] = PLACEHOLDER;
38
+ splitterPositions[count - 1] = PLACEHOLDER;
39
+ }
40
+ if (count < 2) return splitterPositions;
41
+ for(let i = 0, resizeablesLeft = 0; i < count - 1; i++){
42
+ if (childMeta[i].resizeable && !resizeablesLeft) resizeablesLeft = SPLITTER;
43
+ splitterPositions[i] += resizeablesLeft;
44
+ }
45
+ for(let i = count - 1; i > 0; i--){
46
+ if (splitterPositions[i] & SPLITTER) splitterPositions[i] -= SPLITTER;
47
+ if (childMeta[i].resizeable) break;
48
+ }
49
+ return splitterPositions;
50
+ };
51
+ const identifyResizeParties = (contentMeta, idx)=>{
52
+ const idx1 = getLeadingResizeablePos(contentMeta, idx);
53
+ const idx2 = getTrailingResizeablePos(contentMeta, idx);
54
+ const participants = -1 !== idx1 && -1 !== idx2 ? [
55
+ idx1,
56
+ idx2
57
+ ] : void 0;
58
+ const bystanders = identifyResizeBystanders(contentMeta, participants);
59
+ return [
60
+ participants,
61
+ bystanders
62
+ ];
63
+ };
64
+ function identifyResizeBystanders(contentMeta, participants) {
65
+ if (participants) {
66
+ const bystanders = [];
67
+ for(let i = 0; i < contentMeta.length; i++)if (contentMeta[i].flexOpen && !participants.includes(i)) bystanders.push(i);
68
+ return bystanders;
69
+ }
70
+ }
71
+ function getLeadingResizeablePos(contentMeta, idx) {
72
+ let pos = idx, resizeable = false;
73
+ while(pos >= 1 && !resizeable){
74
+ pos -= 1;
75
+ resizeable = isResizeable(contentMeta, pos);
76
+ }
77
+ return pos;
78
+ }
79
+ function getTrailingResizeablePos(contentMeta, idx) {
80
+ let pos = idx, resizeable = false;
81
+ const count = contentMeta.length;
82
+ while(pos < count - 1 && !resizeable){
83
+ pos += 1;
84
+ resizeable = isResizeable(contentMeta, pos);
85
+ }
86
+ return pos === count ? -1 : pos;
87
+ }
88
+ function isResizeable(contentMeta, idx) {
89
+ const { placeholder, splitter, resizeable, intrinsicSize } = contentMeta[idx];
90
+ return Boolean(!splitter && !intrinsicSize && (placeholder || resizeable));
91
+ }
92
+ export { PLACEHOLDER, SPLITTER, findSplitterAndPlaceholderPositions, gatherChildMeta, identifyResizeParties };
File without changes
@@ -0,0 +1,2 @@
1
+ export * from "./FlexboxLayout.js";
2
+ export { default as Flexbox } from "./Flexbox.js";
@@ -0,0 +1,181 @@
1
+ import { getUniqueId } from "@vuu-ui/vuu-utils";
2
+ import react, { useCallback, useMemo, useRef } from "react";
3
+ import { Placeholder } from "../placeholder/index.js";
4
+ import { Splitter } from "./Splitter.js";
5
+ import { PLACEHOLDER, SPLITTER, findSplitterAndPlaceholderPositions, gatherChildMeta, identifyResizeParties } from "./flexbox-utils.js";
6
+ const originalContentOnly = (meta)=>!meta.splitter && !meta.placeholder;
7
+ const useSplitterResizing = ({ children: childrenProp, onSplitterMoved, style })=>{
8
+ const rootRef = useRef(null);
9
+ const flexElementsRef = useRef(void 0);
10
+ const metaRef = useRef(void 0);
11
+ const contentRef = useRef(void 0);
12
+ const assignedKeys = useRef([]);
13
+ const isColumn = style?.flexDirection === "column";
14
+ const dimension = isColumn ? "height" : "width";
15
+ const children = useMemo(()=>Array.isArray(childrenProp) ? childrenProp : react.isValidElement(childrenProp) ? [
16
+ childrenProp
17
+ ] : [], [
18
+ childrenProp
19
+ ]);
20
+ const handleDragStart = useCallback((index)=>{
21
+ const { current: contentMeta } = metaRef;
22
+ if (contentMeta) {
23
+ const [participants, bystanders] = identifyResizeParties(contentMeta, index);
24
+ if (participants) {
25
+ participants.forEach((index)=>{
26
+ const el = rootRef.current?.childNodes[index];
27
+ if (el) {
28
+ const { size, minSize } = measureElement(el, dimension);
29
+ contentMeta[index].currentSize = size;
30
+ contentMeta[index].minSize = minSize;
31
+ }
32
+ });
33
+ if (bystanders) bystanders.forEach((index)=>{
34
+ const el = rootRef.current?.childNodes[index];
35
+ if (el) {
36
+ const { [dimension]: size } = el.getBoundingClientRect();
37
+ contentMeta[index].flexBasis = size;
38
+ }
39
+ });
40
+ if (rootRef.current) {
41
+ rootRef.current.classList.add("vuuSplitterResizing");
42
+ flexElementsRef.current = Array.from(rootRef.current.querySelectorAll(":scope > div"));
43
+ }
44
+ }
45
+ }
46
+ }, [
47
+ dimension
48
+ ]);
49
+ const handleDrag = useCallback((idx, distance)=>{
50
+ const { current: flexElements = [] } = flexElementsRef;
51
+ if (contentRef.current && metaRef.current) resizeElements(flexElements, metaRef.current, distance);
52
+ }, []);
53
+ const handleDragEnd = useCallback(()=>{
54
+ const contentMeta = metaRef.current;
55
+ if (contentMeta) {
56
+ onSplitterMoved?.(contentMeta.filter(originalContentOnly));
57
+ if (rootRef.current) rootRef.current.classList.remove("vuuSplitterResizing");
58
+ }
59
+ contentMeta?.forEach((meta)=>{
60
+ meta.currentSize = void 0;
61
+ meta.flexBasis = void 0;
62
+ meta.flexOpen = false;
63
+ });
64
+ }, [
65
+ onSplitterMoved
66
+ ]);
67
+ const createSplitter = useCallback((i)=>react.createElement(Splitter, {
68
+ column: isColumn,
69
+ index: i,
70
+ key: `splitter-${i}`,
71
+ onDrag: handleDrag,
72
+ onDragEnd: handleDragEnd,
73
+ onDragStart: handleDragStart
74
+ }), [
75
+ handleDrag,
76
+ handleDragEnd,
77
+ handleDragStart,
78
+ isColumn
79
+ ]);
80
+ useMemo(()=>{
81
+ const [content, meta] = buildContent(children, dimension, createSplitter, assignedKeys.current);
82
+ metaRef.current = meta;
83
+ contentRef.current = content;
84
+ }, [
85
+ children,
86
+ createSplitter,
87
+ dimension
88
+ ]);
89
+ return {
90
+ content: contentRef.current || [],
91
+ rootRef
92
+ };
93
+ };
94
+ function buildContent(children, dimension, createSplitter, keys) {
95
+ const childMeta = gatherChildMeta(children, dimension);
96
+ const splitterAndPlaceholderPositions = findSplitterAndPlaceholderPositions(childMeta);
97
+ const content = [];
98
+ const meta = [];
99
+ for(let i = 0; i < children.length; i++){
100
+ const child = children[i];
101
+ if (0 === i && splitterAndPlaceholderPositions[i] & PLACEHOLDER) {
102
+ content.push(createPlaceholder(i));
103
+ meta.push({
104
+ placeholder: true,
105
+ shim: true
106
+ });
107
+ }
108
+ if (null == child.key) {
109
+ const key = keys[i] || (keys[i] = getUniqueId());
110
+ content.push(react.cloneElement(child, {
111
+ key
112
+ }));
113
+ } else content.push(child);
114
+ meta.push(childMeta[i]);
115
+ if (i > 0 && splitterAndPlaceholderPositions[i] & PLACEHOLDER) {
116
+ content.push(createPlaceholder(i));
117
+ meta.push({
118
+ placeholder: true
119
+ });
120
+ } else if (splitterAndPlaceholderPositions[i] & SPLITTER) {
121
+ content.push(createSplitter(content.length));
122
+ meta.push({
123
+ splitter: true
124
+ });
125
+ }
126
+ }
127
+ return [
128
+ content,
129
+ meta
130
+ ];
131
+ }
132
+ function resizeElements(flexElements, contentMeta, distance) {
133
+ const metaUpdated = updateMeta(contentMeta, distance);
134
+ if (!metaUpdated) return;
135
+ flexElements.forEach((element, idx)=>{
136
+ const meta = contentMeta[idx];
137
+ const { currentSize, flexOpen, flexBasis, splitter } = meta;
138
+ const hasCurrentSize = void 0 !== currentSize;
139
+ if (!splitter && (hasCurrentSize || flexOpen)) {
140
+ const size = hasCurrentSize ? meta.currentSize : flexBasis;
141
+ element.style.flexBasis = `${size}px`;
142
+ }
143
+ });
144
+ }
145
+ function updateMeta(contentMeta, distance) {
146
+ const resizeTargets = [];
147
+ contentMeta.forEach((meta, idx)=>{
148
+ if (void 0 !== meta.currentSize) resizeTargets.push(idx);
149
+ });
150
+ const target1 = distance < 0 ? resizeTargets[0] : resizeTargets[1];
151
+ const { currentSize = 0, minSize = 0 } = contentMeta[target1];
152
+ if (currentSize === minSize) return false;
153
+ if (Math.abs(distance) > currentSize - minSize) {
154
+ const multiplier = distance < 0 ? -1 : 1;
155
+ distance = Math.max(0, currentSize - minSize) * multiplier;
156
+ }
157
+ const leadingItem = contentMeta[resizeTargets[0]];
158
+ const { currentSize: leadingSize = 0 } = leadingItem;
159
+ leadingItem.currentSize = leadingSize + distance;
160
+ const trailingItem = contentMeta[resizeTargets[1]];
161
+ const { currentSize: trailingSize = 0 } = trailingItem;
162
+ trailingItem.currentSize = trailingSize - distance;
163
+ return true;
164
+ }
165
+ function createPlaceholder(index) {
166
+ return react.createElement(Placeholder, {
167
+ shim: 0 === index,
168
+ key: `placeholder-${index}`
169
+ });
170
+ }
171
+ function measureElement(el, dimension) {
172
+ const { [dimension]: size } = el.getBoundingClientRect();
173
+ const style = getComputedStyle(el);
174
+ const minSizeVal = style.getPropertyValue(`min-${dimension}`);
175
+ const minSize = minSizeVal.endsWith("px") ? parseInt(minSizeVal, 10) : 0;
176
+ return {
177
+ size,
178
+ minSize
179
+ };
180
+ }
181
+ export { useSplitterResizing };
package/src/index.js ADDED
@@ -0,0 +1,20 @@
1
+ export * from "./dock-layout/index.js";
2
+ export * from "./drag-drop/index.js";
3
+ export * from "./flexbox/index.js";
4
+ export * from "./layout-header/index.js";
5
+ export * from "./layout-provider/index.js";
6
+ export * from "./layout-reducer/index.js";
7
+ export * from "./LayoutContainer.js";
8
+ export * from "./palette/index.js";
9
+ export * from "./placeholder/index.js";
10
+ export * from "./responsive/index.js";
11
+ export * from "./stack/index.js";
12
+ export * from "./use-persistent-state.js";
13
+ export * from "./utils/index.js";
14
+ export * from "./layout-view/viewTypes.js";
15
+ export * from "./layout-view/View.js";
16
+ export * from "./layout-view/useViewBroadcastChannel.js";
17
+ export { default as Component } from "./Component.js";
18
+ export { Action } from "./layout-action.js";
19
+ export { useViewActionDispatcher } from "./layout-view-actions/useViewActionDispatcher.js";
20
+ export { ViewContext, useViewContext, useViewDispatch } from "./layout-view-actions/ViewContext.js";
@@ -0,0 +1,20 @@
1
+ const Action = {
2
+ ADD: "add",
3
+ BLUR: "blur",
4
+ BLUR_SPLITTER: "blur-splitter",
5
+ DRAG_START: "drag-start",
6
+ DRAG_STARTED: "drag-started",
7
+ DRAG_DROP: "drag-drop",
8
+ FOCUS: "focus",
9
+ FOCUS_SPLITTER: "focus-splitter",
10
+ INITIALIZE: "initialize",
11
+ LAYOUT_RESIZE: "layout-resize",
12
+ MAXIMIZE: "maximize",
13
+ MINIMIZE: "minimize",
14
+ REMOVE: "remove",
15
+ REPLACE: "replace",
16
+ RESTORE: "restore",
17
+ SAVE: "save",
18
+ SPLITTER_RESIZE: "splitter-resize"
19
+ };
20
+ export { Action };
@@ -0,0 +1,15 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import clsx from "clsx";
3
+ const ActionButton = ({ actionId, className, iconName, onClick, ...props })=>{
4
+ const handleClick = (evt)=>{
5
+ onClick(evt, actionId);
6
+ };
7
+ return /*#__PURE__*/ jsx("button", {
8
+ ...props,
9
+ className: clsx("ActionButton", className),
10
+ onClick: handleClick,
11
+ title: "Close View"
12
+ });
13
+ };
14
+ var layout_header_ActionButton = ActionButton;
15
+ export default layout_header_ActionButton;
@@ -0,0 +1,32 @@
1
+ const css = `
2
+ .vuuHeader {
3
+ --saltButton-height: 24px;
4
+ --saltButton-width: 24px;
5
+ padding: 0 var(--salt-spacing-100);
6
+
7
+ & [data-align="end"] {
8
+ margin-left: auto;
9
+ }
10
+
11
+ & [data-align="end"] ~ [data-align="end"] {
12
+ margin-left: 0;
13
+ }
14
+
15
+ &:hover {
16
+ & .vuuHeader-edit {
17
+ visibility: visible;
18
+ }
19
+ }
20
+ }
21
+
22
+ .vuuHeader-edit {
23
+ visibility: hidden;
24
+ }
25
+
26
+ .salt-density-high .vuuHeader {
27
+ --saltToolbarField-marginTop: 0;
28
+ }
29
+
30
+
31
+ `;
32
+ export default css;
@@ -0,0 +1,99 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useComponentCssInjection } from "@salt-ds/styles";
3
+ import { useWindow } from "@salt-ds/window";
4
+ import { EditableLabel, IconButton } from "@vuu-ui/vuu-ui-controls";
5
+ import clsx from "clsx";
6
+ import { cloneElement } from "react";
7
+ import { useHeader } from "./useHeader.js";
8
+ import Header from "./Header.css";
9
+ const classBase = "vuuHeader";
10
+ const Header_Header = ({ allowRename = false, className: classNameProp, contributions, collapsed, closeable, onCollapse, onEditTitle, onExpand, orientation: orientationProp = "horizontal", style, title = "Untitled" })=>{
11
+ const targetWindow = useWindow();
12
+ useComponentCssInjection({
13
+ testId: "vuu-header",
14
+ css: Header,
15
+ window: targetWindow
16
+ });
17
+ const { editing, focusTitle, labelFieldRef, onClickEdit, onClose, onExitEditMode, onMouseDown, onTitleKeyDown, onToggleCollapse, onToggleExpand, setValue, value } = useHeader({
18
+ onCollapse,
19
+ onEditTitle,
20
+ onExpand,
21
+ title
22
+ });
23
+ const handleButtonMouseDown = (evt)=>{
24
+ evt.stopPropagation();
25
+ };
26
+ const orientation = collapsed || orientationProp;
27
+ const className = clsx(classBase, classNameProp, `${classBase}-${orientation}`);
28
+ const toolbarItems = [];
29
+ const postTitleContributedItems = [];
30
+ const actionButtons = [];
31
+ const allowCollapse = "boolean" == typeof collapsed || "string" == typeof collapsed;
32
+ contributions?.forEach((contribution, i)=>{
33
+ switch(contribution.location){
34
+ case "pre-title":
35
+ toolbarItems.push(/*#__PURE__*/ cloneElement(contribution.content, {
36
+ key: i
37
+ }));
38
+ break;
39
+ default:
40
+ postTitleContributedItems.push(/*#__PURE__*/ cloneElement(contribution.content, {
41
+ key: i
42
+ }));
43
+ }
44
+ });
45
+ allowCollapse && toolbarItems.push(/*#__PURE__*/ jsx(IconButton, {
46
+ className: clsx(`${classBase}-toggle`, {
47
+ [`${classBase}-collapsed`]: collapsed
48
+ }),
49
+ "data-embedded": true,
50
+ icon: collapsed ? "chevron-open" : "chevron-down",
51
+ onClick: collapsed ? onToggleExpand : onToggleCollapse,
52
+ size: 20,
53
+ tabIndex: 0,
54
+ appearance: "transparent",
55
+ sentiment: "neutral"
56
+ }, "collapse-button"));
57
+ title && toolbarItems.push(/*#__PURE__*/ jsx(EditableLabel, {
58
+ className: `${classBase}-title`,
59
+ editing: editing,
60
+ value: value,
61
+ onChange: setValue,
62
+ onMouseDownCapture: focusTitle,
63
+ onExitEditMode: onExitEditMode,
64
+ onKeyDown: onTitleKeyDown,
65
+ ref: labelFieldRef
66
+ }, "title"));
67
+ allowRename && toolbarItems.push(/*#__PURE__*/ jsx(IconButton, {
68
+ className: `${classBase}-edit`,
69
+ "data-embedded": true,
70
+ icon: "edit",
71
+ onClick: onClickEdit,
72
+ onMouseDown: handleButtonMouseDown,
73
+ tabIndex: 0,
74
+ variant: "secondary"
75
+ }, "edit-button"));
76
+ closeable && actionButtons.push(/*#__PURE__*/ jsx(IconButton, {
77
+ appearance: "transparent",
78
+ "data-embedded": true,
79
+ icon: "close",
80
+ onClick: onClose,
81
+ onMouseDown: handleButtonMouseDown,
82
+ sentiment: "neutral"
83
+ }, "close"));
84
+ postTitleContributedItems.length > 0 && toolbarItems.push(/*#__PURE__*/ jsx("div", {
85
+ "data-align": "end",
86
+ children: postTitleContributedItems
87
+ }, "contributions"));
88
+ actionButtons.length > 0 && toolbarItems.push(/*#__PURE__*/ jsx("div", {
89
+ "data-align": "end",
90
+ children: actionButtons
91
+ }, "actions"));
92
+ return /*#__PURE__*/ jsx("div", {
93
+ className: clsx("vuuToolbarProxy", className),
94
+ style: style,
95
+ onMouseDown: onMouseDown,
96
+ children: toolbarItems
97
+ });
98
+ };
99
+ export { Header_Header as Header };
@@ -0,0 +1 @@
1
+ export * from "./Header.js";