@vuu-ui/vuu-layout 0.5.4 → 0.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 (147) hide show
  1. package/README.md +1 -0
  2. package/cjs/index.js +4 -7379
  3. package/cjs/index.js.map +7 -0
  4. package/esm/index.js +20 -0
  5. package/esm/index.js.map +7 -0
  6. package/index.css +1 -951
  7. package/index.css.map +3 -3
  8. package/package.json +5 -9
  9. package/src/Component.css +0 -2
  10. package/src/Component.tsx +0 -20
  11. package/src/DraggableLayout.css +0 -18
  12. package/src/DraggableLayout.tsx +0 -29
  13. package/src/__tests__/flexbox-utils.spec.js +0 -90
  14. package/src/action-buttons/index.ts +0 -1
  15. package/src/chest-of-drawers/Chest.css +0 -36
  16. package/src/chest-of-drawers/Chest.tsx +0 -42
  17. package/src/chest-of-drawers/Drawer.css +0 -159
  18. package/src/chest-of-drawers/Drawer.tsx +0 -118
  19. package/src/chest-of-drawers/index.ts +0 -2
  20. package/src/common-types.ts +0 -9
  21. package/src/debug.ts +0 -16
  22. package/src/dialog/Dialog.css +0 -16
  23. package/src/dialog/Dialog.tsx +0 -59
  24. package/src/dialog/index.ts +0 -1
  25. package/src/drag-drop/BoxModel.ts +0 -546
  26. package/src/drag-drop/DragState.ts +0 -222
  27. package/src/drag-drop/Draggable.ts +0 -282
  28. package/src/drag-drop/DropMenu.css +0 -71
  29. package/src/drag-drop/DropMenu.tsx +0 -61
  30. package/src/drag-drop/DropTarget.ts +0 -392
  31. package/src/drag-drop/DropTargetRenderer.css +0 -40
  32. package/src/drag-drop/DropTargetRenderer.tsx +0 -279
  33. package/src/drag-drop/dragDropTypes.ts +0 -49
  34. package/src/drag-drop/index.ts +0 -4
  35. package/src/editable-label/EditableLabel.css +0 -28
  36. package/src/editable-label/EditableLabel.tsx +0 -99
  37. package/src/editable-label/index.ts +0 -1
  38. package/src/flexbox/Flexbox.css +0 -45
  39. package/src/flexbox/Flexbox.tsx +0 -70
  40. package/src/flexbox/FlexboxLayout.jsx +0 -26
  41. package/src/flexbox/FluidGrid.css +0 -134
  42. package/src/flexbox/FluidGrid.tsx +0 -84
  43. package/src/flexbox/FluidGridLayout.tsx +0 -10
  44. package/src/flexbox/Splitter.css +0 -140
  45. package/src/flexbox/Splitter.tsx +0 -135
  46. package/src/flexbox/flexbox-utils.ts +0 -128
  47. package/src/flexbox/flexboxTypes.ts +0 -63
  48. package/src/flexbox/index.ts +0 -4
  49. package/src/flexbox/useResponsiveSizing.ts +0 -85
  50. package/src/flexbox/useSplitterResizing.ts +0 -272
  51. package/src/index.ts +0 -21
  52. package/src/layout-action.ts +0 -21
  53. package/src/layout-header/ActionButton.tsx +0 -23
  54. package/src/layout-header/Header.css +0 -8
  55. package/src/layout-header/Header.tsx +0 -222
  56. package/src/layout-header/index.ts +0 -1
  57. package/src/layout-provider/LayoutProvider.tsx +0 -160
  58. package/src/layout-provider/LayoutProviderContext.ts +0 -17
  59. package/src/layout-provider/index.ts +0 -2
  60. package/src/layout-provider/useLayoutDragDrop.ts +0 -241
  61. package/src/layout-reducer/flexUtils.ts +0 -281
  62. package/src/layout-reducer/index.ts +0 -4
  63. package/src/layout-reducer/insert-layout-element.ts +0 -365
  64. package/src/layout-reducer/layout-reducer.ts +0 -255
  65. package/src/layout-reducer/layoutTypes.ts +0 -151
  66. package/src/layout-reducer/layoutUtils.ts +0 -302
  67. package/src/layout-reducer/remove-layout-element.ts +0 -240
  68. package/src/layout-reducer/replace-layout-element.ts +0 -118
  69. package/src/layout-reducer/resize-flex-children.ts +0 -56
  70. package/src/layout-reducer/wrap-layout-element.ts +0 -317
  71. package/src/layout-view/View.css +0 -61
  72. package/src/layout-view/View.tsx +0 -149
  73. package/src/layout-view/ViewContext.ts +0 -31
  74. package/src/layout-view/index.ts +0 -4
  75. package/src/layout-view/useView.tsx +0 -104
  76. package/src/layout-view/useViewActionDispatcher.ts +0 -133
  77. package/src/layout-view/useViewResize.ts +0 -53
  78. package/src/layout-view/viewTypes.ts +0 -37
  79. package/src/menu/ContextMenu.css +0 -22
  80. package/src/menu/ContextMenu.jsx +0 -121
  81. package/src/menu/MenuList.css +0 -150
  82. package/src/menu/MenuList.jsx +0 -179
  83. package/src/menu/aim/aim.js +0 -92
  84. package/src/menu/aim/corners.js +0 -114
  85. package/src/menu/aim/point-in-polygon.js +0 -25
  86. package/src/menu/aim/utils.js +0 -19
  87. package/src/menu/context-menu-provider.jsx +0 -135
  88. package/src/menu/index.js +0 -4
  89. package/src/menu/key-code.js +0 -61
  90. package/src/menu/list-dom-utils.js +0 -22
  91. package/src/menu/use-cascade.js +0 -292
  92. package/src/menu/use-click-away.js +0 -22
  93. package/src/menu/use-items-with-ids.js +0 -75
  94. package/src/menu/use-keyboard-navigation.js +0 -162
  95. package/src/menu/utils.js +0 -5
  96. package/src/palette/Palette.css +0 -37
  97. package/src/palette/Palette.tsx +0 -140
  98. package/src/palette/PaletteSalt.css +0 -9
  99. package/src/palette/PaletteSalt.tsx +0 -79
  100. package/src/palette/index.ts +0 -2
  101. package/src/placeholder/Placeholder.css +0 -10
  102. package/src/placeholder/Placeholder.tsx +0 -39
  103. package/src/placeholder/index.ts +0 -1
  104. package/src/popup/index.js +0 -2
  105. package/src/popup/popup-provider.js +0 -0
  106. package/src/popup/popup-service.css +0 -15
  107. package/src/popup/popup-service.js +0 -281
  108. package/src/portal/Portal.jsx +0 -50
  109. package/src/portal/index.ts +0 -3
  110. package/src/portal/render-portal.jsx +0 -68
  111. package/src/portal/utils.js +0 -16
  112. package/src/registry/ComponentRegistry.ts +0 -35
  113. package/src/registry/index.ts +0 -1
  114. package/src/responsive/OverflowMenu.css +0 -31
  115. package/src/responsive/OverflowMenu.jsx +0 -56
  116. package/src/responsive/breakpoints.ts +0 -62
  117. package/src/responsive/index.ts +0 -4
  118. package/src/responsive/measureMinimumNodeSize.ts +0 -23
  119. package/src/responsive/overflowUtils.js +0 -14
  120. package/src/responsive/use-breakpoints.ts +0 -100
  121. package/src/responsive/useOverflowObserver.ts +0 -606
  122. package/src/responsive/useResizeObserver.ts +0 -154
  123. package/src/responsive/utils.ts +0 -37
  124. package/src/stack/Stack.css +0 -39
  125. package/src/stack/Stack.tsx +0 -161
  126. package/src/stack/StackLayout.tsx +0 -137
  127. package/src/stack/index.ts +0 -3
  128. package/src/stack/stackTypes.ts +0 -19
  129. package/src/tabs/TabPanel.css +0 -12
  130. package/src/tabs/TabPanel.tsx +0 -17
  131. package/src/tabs/index.ts +0 -1
  132. package/src/tools/config-wrapper/ConfigWrapper.jsx +0 -53
  133. package/src/tools/config-wrapper/index.js +0 -1
  134. package/src/tools/devtools-box/layout-configurator.css +0 -112
  135. package/src/tools/devtools-box/layout-configurator.jsx +0 -369
  136. package/src/tools/devtools-tree/layout-tree-viewer.css +0 -15
  137. package/src/tools/devtools-tree/layout-tree-viewer.jsx +0 -36
  138. package/src/tools/index.js +0 -3
  139. package/src/use-persistent-state.ts +0 -115
  140. package/src/utils/apply-handlers.js +0 -15
  141. package/src/utils/componentFromLayout.tsx +0 -30
  142. package/src/utils/index.ts +0 -6
  143. package/src/utils/pathUtils.ts +0 -294
  144. package/src/utils/propUtils.ts +0 -24
  145. package/src/utils/refUtils.ts +0 -16
  146. package/src/utils/styleUtils.ts +0 -14
  147. package/src/utils/typeOf.ts +0 -22
@@ -1,317 +0,0 @@
1
- import React, { ReactElement } from "react";
2
- import { uuid } from "@vuu-ui/vuu-utils";
3
- import { getProp, getProps, nextStep, resetPath, typeOf } from "../utils";
4
- import { ComponentRegistry } from "../registry/ComponentRegistry";
5
- import {
6
- createFlexbox,
7
- createPlaceHolder,
8
- flexDirection,
9
- getFlexStyle,
10
- getIntrinsicSize,
11
- wrapIntrinsicSizeComponentWithFlexbox,
12
- } from "./flexUtils";
13
- import { applyLayoutProps, LayoutProps } from "./layoutUtils";
14
- import { LayoutModel } from "./layoutTypes";
15
- import { DropPos } from "../drag-drop/dragDropTypes";
16
- import { rectTuple } from "../common-types";
17
- import { DropTarget } from "../drag-drop/DropTarget";
18
-
19
- export interface LayoutSpec {
20
- type: "Stack" | "Flexbox";
21
- flexDirection: "column" | "row";
22
- showTabs?: boolean;
23
- }
24
-
25
- const isHtmlElement = (component: LayoutModel) => {
26
- const [firstLetter] = typeOf(component) as string;
27
- return firstLetter === firstLetter.toLowerCase();
28
- };
29
-
30
- // newComponent has been dropped onto an existingComponent. A wrapper container will be inserted
31
- // into the layout tree, wrapping the existingComponent. newComponent will be injected into the
32
- // new wrapper, so existingComponent and newComponent will be siblings. Putting it another way,
33
- // wrapper will replace existingComponent in the layout tree and it will contain existingComponent
34
- // and newComponent.
35
- export function wrap(
36
- container: ReactElement,
37
- existingComponent: any,
38
- newComponent: any,
39
- pos: DropPos,
40
- clientRect?: DropTarget["clientRect"],
41
- dropRect?: DropTarget["dropRect"]
42
- ): ReactElement {
43
- const { children: containerChildren, path: containerPath } =
44
- getProps(container);
45
-
46
- const existingComponentPath = getProp(existingComponent, "path");
47
- const { idx, finalStep } = nextStep(containerPath, existingComponentPath);
48
- const children = finalStep
49
- ? updateChildren(
50
- container,
51
- containerChildren,
52
- existingComponent,
53
- newComponent,
54
- pos,
55
- clientRect,
56
- dropRect
57
- )
58
- : containerChildren.map((child: ReactElement, index: number) =>
59
- index === idx
60
- ? wrap(
61
- child,
62
- existingComponent,
63
- newComponent,
64
- pos,
65
- clientRect,
66
- dropRect
67
- )
68
- : child
69
- );
70
-
71
- return React.cloneElement(container, undefined, children);
72
- }
73
-
74
- function updateChildren(
75
- container: LayoutModel,
76
- containerChildren: ReactElement[],
77
- existingComponent: ReactElement,
78
- newComponent: ReactElement,
79
- pos: DropPos,
80
- clientRect?: DropTarget["clientRect"],
81
- dropRect?: rectTuple
82
- ) {
83
- const intrinsicSize = getIntrinsicSize(newComponent);
84
-
85
- if (intrinsicSize?.width && intrinsicSize?.height) {
86
- if (clientRect === undefined || dropRect === undefined) {
87
- throw Error(
88
- "wrap-layout-element, updateChildren clientRect and dropRect must both be available"
89
- );
90
- }
91
- return wrapIntrinsicSizedComponent(
92
- containerChildren,
93
- existingComponent,
94
- newComponent,
95
- pos,
96
- clientRect,
97
- dropRect
98
- );
99
- } else {
100
- return wrapFlexComponent(
101
- container,
102
- containerChildren,
103
- existingComponent,
104
- newComponent,
105
- pos
106
- );
107
- }
108
- }
109
-
110
- function wrapFlexComponent(
111
- container: LayoutModel,
112
- containerChildren: ReactElement[],
113
- existingComponent: ReactElement,
114
- newComponent: ReactElement,
115
- pos: DropPos
116
- ) {
117
- const { version = 0 } = getProps(newComponent);
118
- const existingComponentPath = getProp(existingComponent, "path");
119
- const {
120
- type,
121
- flexDirection,
122
- showTabs: showTabsProp,
123
- } = getLayoutSpecForWrapper(pos);
124
- const [style, existingComponentStyle, newComponentStyle] =
125
- getWrappedFlexStyles(
126
- type,
127
- existingComponent,
128
- newComponent,
129
- flexDirection,
130
- pos
131
- );
132
- const targetFirst = isTargetFirst(pos);
133
- const active = targetFirst ? 1 : 0; // double check this
134
-
135
- // TODO how do we decide whether children should be resizable ?
136
- const newComponentProps = {
137
- resizeable: true,
138
- style: newComponentStyle,
139
- version: version + 1,
140
- };
141
- const resizeProp = isHtmlElement(existingComponent)
142
- ? "data-resizeable"
143
- : "resizeable";
144
- const existingComponentProps = {
145
- [resizeProp]: true,
146
- style: existingComponentStyle,
147
- };
148
-
149
- const showTabs = type === "Stack" ? { showTabs: showTabsProp } : undefined;
150
- const splitterSize =
151
- type === "Flexbox"
152
- ? {
153
- splitterSize:
154
- (typeOf(container) === "Flexbox" && container.props.splitterSize) ??
155
- undefined,
156
- }
157
- : undefined;
158
-
159
- const id = uuid();
160
- var wrapper = React.createElement(
161
- ComponentRegistry[type],
162
- {
163
- active,
164
- id,
165
- key: id,
166
- path: getProp(existingComponent, "path"),
167
- flexFill: getProp(existingComponent, "flexFill"),
168
- // TODO we should be able to configure this in setDefaultLayoutProps
169
- ...splitterSize,
170
- ...showTabs,
171
- style,
172
- resizeable: getProp(existingComponent, "resizeable"),
173
- } as LayoutProps,
174
- targetFirst
175
- ? [
176
- resetPath(
177
- existingComponent,
178
- `${existingComponentPath}.0`,
179
- existingComponentProps
180
- ),
181
- // resetPath(newComponent, `${existingComponentPath}.1`, newComponentProps),
182
- applyLayoutProps(
183
- React.cloneElement(newComponent, newComponentProps),
184
- `${existingComponentPath}.1`
185
- ),
186
- ]
187
- : [
188
- applyLayoutProps(
189
- React.cloneElement(newComponent, newComponentProps),
190
- `${existingComponentPath}.0`
191
- ),
192
- // resetPath(newComponent, `${existingComponentPath}.0`, newComponentProps),
193
- resetPath(
194
- existingComponent,
195
- `${existingComponentPath}.1`,
196
- existingComponentProps
197
- ),
198
- ]
199
- );
200
- return containerChildren.map((child: ReactElement) =>
201
- child === existingComponent ? wrapper : child
202
- );
203
- }
204
-
205
- function wrapIntrinsicSizedComponent(
206
- containerChildren: ReactElement[],
207
- existingComponent: ReactElement,
208
- newComponent: ReactElement,
209
- pos: DropPos,
210
- clientRect: DropTarget["clientRect"],
211
- dropRect: rectTuple
212
- ) {
213
- const { flexDirection } = getLayoutSpecForWrapper(pos);
214
- const contraDirection = flexDirection === "column" ? "row" : "column";
215
- const targetFirst = isTargetFirst(pos);
216
-
217
- const [dropLeft, dropTop, dropRight, dropBottom] = dropRect;
218
- const [startPlaceholder, endPlaceholder] =
219
- flexDirection === "column"
220
- ? [dropTop - clientRect.top, clientRect.bottom - dropBottom]
221
- : [dropLeft - clientRect.left, clientRect.right - dropRight];
222
- const pathRoot = getProp(existingComponent, "path");
223
- let pathIndex = 0;
224
-
225
- const resizeProp = isHtmlElement(existingComponent)
226
- ? "data-resizeable"
227
- : "resizeable";
228
-
229
- const wrappedChildren = [];
230
- if (startPlaceholder) {
231
- wrappedChildren.push(
232
- targetFirst
233
- ? resetPath(existingComponent, `${pathRoot}.${pathIndex++}`, {
234
- [resizeProp]: true,
235
- style: { flexBasis: startPlaceholder, flexGrow: 1, flexShrink: 1 },
236
- })
237
- : createPlaceHolder(`${pathRoot}.${pathIndex++}`, startPlaceholder, {
238
- flexGrow: 0,
239
- flexShrink: 0,
240
- })
241
- );
242
- }
243
- wrappedChildren.push(
244
- wrapIntrinsicSizeComponentWithFlexbox(
245
- newComponent,
246
- contraDirection,
247
- `${pathRoot}.${pathIndex++}`,
248
- clientRect,
249
- dropRect
250
- )
251
- );
252
- if (endPlaceholder) {
253
- wrappedChildren.push(
254
- targetFirst
255
- ? createPlaceHolder(`${pathRoot}.${pathIndex++}`, 0)
256
- : resetPath(existingComponent, `${pathRoot}.${pathIndex++}`, {
257
- [resizeProp]: true,
258
- style: { flexBasis: 0, flexGrow: 1, flexShrink: 1 },
259
- })
260
- );
261
- }
262
-
263
- const wrapper = createFlexbox(
264
- flexDirection,
265
- existingComponent.props,
266
- wrappedChildren,
267
- pathRoot
268
- );
269
- return containerChildren.map((child) =>
270
- child === existingComponent ? wrapper : child
271
- );
272
- }
273
-
274
- //TODO we need to respect styles on the source, full-on flex might not be appropriate
275
- function getWrappedFlexStyles(
276
- type: string,
277
- existingComponent: ReactElement,
278
- newComponent: ReactElement,
279
- flexDirection: flexDirection,
280
- pos: DropPos
281
- ) {
282
- const style = {
283
- ...existingComponent.props.style,
284
- flexDirection,
285
- };
286
-
287
- const dimension =
288
- type === "Flexbox" && flexDirection === "column" ? "height" : "width";
289
- const newComponentStyle = getFlexStyle(newComponent, dimension, pos);
290
- const existingComponentStyle = getFlexStyle(existingComponent, dimension);
291
-
292
- return [style, existingComponentStyle, newComponentStyle];
293
- }
294
-
295
- const isTargetFirst = (pos: DropPos) =>
296
- pos.position.SouthOrEast
297
- ? true
298
- : pos?.tab?.positionRelativeToTab === "before"
299
- ? false
300
- : pos.position.Header
301
- ? true
302
- : false;
303
-
304
- function getLayoutSpecForWrapper(pos: DropPos): LayoutSpec {
305
- if (pos.position.Header) {
306
- return {
307
- type: "Stack",
308
- flexDirection: "column",
309
- showTabs: true,
310
- };
311
- } else {
312
- return {
313
- type: "Flexbox",
314
- flexDirection: pos.position.EastOrWest ? "row" : "column",
315
- };
316
- }
317
- }
@@ -1,61 +0,0 @@
1
- .vuuView {
2
- border-color: var(--vuuView-borderColor, var(--salt-container-primary-borderColor));
3
- border-width: var(--vuuView-borderWidth, 1px);
4
- border-style: var(--vuuView-borderStyle, none);
5
-
6
- display: flex;
7
- flex-direction: column;
8
- margin: var(--vuuView-margin, 0px);
9
- min-height: 50px;
10
- min-width: 50px;
11
- outline: none;
12
- overflow: hidden;
13
- position: relative;
14
- }
15
-
16
- .vuuView.focus-visible:after {
17
- content: '';
18
- position: absolute;
19
- top: 0;
20
- left: 0;
21
- right: 0;
22
- bottom: 0;
23
- border: dotted cornflowerblue 2px;
24
- }
25
-
26
- .vuuView.dragging {
27
- box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
28
- }
29
-
30
- .vuuView-main {
31
- /* height: var(--view-content-height);
32
- width: var(--view-content-width); */
33
- display: flex;
34
- flex-direction: var(--vuuView-flexDirection, column);
35
- flex-wrap: var(--vuuView-flex-wrap, nowrap);
36
- flex: 1;
37
- overflow: hidden;
38
- position: relative;
39
- }
40
-
41
- .vuuView-main > * {
42
- flex-basis: auto;
43
- flex-grow: var(--vuuView-flex-grow, 1);
44
- flex-shrink: var(--vuuView-flex-shrink, 1);
45
- }
46
-
47
- .vuuView-collapsed .vuuView-main {
48
- display: none;
49
- }
50
-
51
- .vuuView-collapsed + .Splitter {
52
- display: none;
53
- }
54
-
55
- .vuuView-collapsed .Toolbar-vertical {
56
- border-right: solid 1px var(--grey40);
57
- }
58
-
59
- .vuuView-collapsed .Toolbar-vertical .toolbar-title {
60
- display: none;
61
- }
@@ -1,149 +0,0 @@
1
- import { useForkRef, useIdMemo as useId } from "@salt-ds/core";
2
- import cx from "classnames";
3
- import React, { ForwardedRef, forwardRef, useMemo, useRef } from "react";
4
- import { Header } from "../layout-header/Header";
5
- import { registerComponent } from "../registry/ComponentRegistry";
6
- import { ViewContext } from "./ViewContext";
7
- import { ViewProps } from "./viewTypes";
8
- import { useView } from "./useView";
9
- import { useViewResize } from "./useViewResize";
10
-
11
- import "./View.css";
12
-
13
- const View = forwardRef(function View(
14
- props: ViewProps,
15
- forwardedRef: ForwardedRef<HTMLDivElement>
16
- ) {
17
- const {
18
- children,
19
- className,
20
- collapsed, // "vertical" | "horizontal" | false | undefined
21
- closeable,
22
- "data-resizeable": dataResizeable,
23
- dropTargets,
24
- expanded,
25
- flexFill, // use data-flexfill instead
26
- id: idProp,
27
- header,
28
- orientation = "horizontal",
29
- path,
30
- resize = "responsive", // maybe throttle or debounce ?
31
- resizeable = dataResizeable,
32
- tearOut,
33
- style = {},
34
- title: titleProp,
35
- ...restProps
36
- } = props;
37
-
38
- // A View within a managed layout will always be passed an id
39
- const id = useId(idProp);
40
- const rootRef = useRef<HTMLDivElement>(null);
41
- const mainRef = useRef<HTMLDivElement>(null);
42
-
43
- const {
44
- contributions,
45
- dispatchViewAction,
46
- load,
47
- loadSession,
48
- onConfigChange,
49
- onEditTitle,
50
- purge,
51
- restoredState,
52
- save,
53
- saveSession,
54
- title,
55
- } = useView({
56
- id,
57
- rootRef,
58
- path,
59
- dropTargets,
60
- title: titleProp,
61
- });
62
-
63
- useViewResize({ mainRef, resize, rootRef });
64
-
65
- const classBase = "vuuView";
66
-
67
- const getContent = () => {
68
- // We only inject restored state as props if child is a single element. Maybe we
69
- // should take this further and only do it if the component has opted into this
70
- // behaviour.
71
- if (React.isValidElement(children) && restoredState) {
72
- return React.cloneElement(children, restoredState);
73
- } else {
74
- return children;
75
- }
76
- };
77
-
78
- const viewContextValue = useMemo(
79
- () => ({
80
- dispatch: dispatchViewAction,
81
- id,
82
- path,
83
- title,
84
- load,
85
- loadSession,
86
- onConfigChange,
87
- purge,
88
- save,
89
- saveSession,
90
- }),
91
- [
92
- dispatchViewAction,
93
- id,
94
- load,
95
- loadSession,
96
- onConfigChange,
97
- path,
98
- purge,
99
- save,
100
- saveSession,
101
- title,
102
- ]
103
- );
104
-
105
- const headerProps = typeof header === "object" ? header : {};
106
-
107
- return (
108
- <div
109
- {...restProps}
110
- className={cx(classBase, className, {
111
- [`${classBase}-collapsed`]: collapsed,
112
- [`${classBase}-expanded`]: expanded,
113
- [`${classBase}-resize-defer`]: resize === "defer",
114
- })}
115
- data-resizeable={resizeable}
116
- id={id}
117
- ref={useForkRef(forwardedRef, rootRef)}
118
- style={style}
119
- tabIndex={-1}
120
- >
121
- <ViewContext.Provider value={viewContextValue}>
122
- {header ? (
123
- <Header
124
- {...headerProps}
125
- collapsed={collapsed}
126
- contributions={contributions}
127
- expanded={expanded}
128
- closeable={closeable}
129
- onEditTitle={onEditTitle}
130
- orientation={/*collapsed || */ orientation}
131
- tearOut={tearOut}
132
- // title={`${title} v${version} #${id}`}
133
- title={title}
134
- />
135
- ) : null}
136
- <div className={`${classBase}-main`} ref={mainRef}>
137
- {getContent()}
138
- </div>
139
- </ViewContext.Provider>
140
- </div>
141
- );
142
- });
143
- View.displayName = "View";
144
-
145
- const MemoView = React.memo(View) as React.FunctionComponent<ViewProps>;
146
- MemoView.displayName = "View";
147
- registerComponent("View", MemoView, "view");
148
-
149
- export { MemoView as View };
@@ -1,31 +0,0 @@
1
- import path from "path";
2
- import React, { SyntheticEvent, useContext } from "react";
3
- import { ViewAction } from "./viewTypes";
4
-
5
- export type ViewDispatch = <Action extends ViewAction = ViewAction>(
6
- action: Action,
7
- evt?: SyntheticEvent
8
- ) => Promise<boolean | void>;
9
-
10
- export interface ViewContextProps {
11
- dispatch: ViewDispatch | null;
12
- id: string;
13
- load: (key?: string) => any;
14
- loadSession: (key?: string) => any;
15
- onConfigChange?: (config: any) => void;
16
- path?: string;
17
- purge: (key: string) => void;
18
- save: (state: any, key: string) => void;
19
- saveSession: (state: any, key: string) => void;
20
- title?: string;
21
- }
22
-
23
- const NO_CONTEXT = { dispatch: null } as ViewContextProps;
24
- export const ViewContext = React.createContext<ViewContextProps>(NO_CONTEXT);
25
-
26
- export const useViewDispatch = () => {
27
- const context = useContext(ViewContext);
28
- return context?.dispatch ?? null;
29
- };
30
-
31
- export const useViewContext = () => useContext(ViewContext);
@@ -1,4 +0,0 @@
1
- export * from './ViewContext';
2
- export * from './View';
3
- export * from './useViewActionDispatcher';
4
- export * from './viewTypes';
@@ -1,104 +0,0 @@
1
- import { RefObject, useCallback, useMemo } from "react";
2
- import { useLayoutProviderDispatch } from "../layout-provider";
3
- import { usePersistentState } from "../use-persistent-state";
4
- import { useViewActionDispatcher } from "./useViewActionDispatcher";
5
-
6
- export interface ViewHookProps {
7
- id: string;
8
- rootRef: RefObject<HTMLDivElement>;
9
- path?: string;
10
- dropTargets?: string[];
11
- title?: string;
12
- }
13
-
14
- export const useView = ({
15
- id,
16
- rootRef,
17
- path,
18
- dropTargets,
19
- title: titleProp,
20
- }: ViewHookProps) => {
21
- const layoutDispatch = useLayoutProviderDispatch();
22
-
23
- const {
24
- loadState,
25
- loadSessionState,
26
- purgeState,
27
- saveState,
28
- saveSessionState,
29
- } = usePersistentState();
30
-
31
- const [dispatchViewAction, contributions] = useViewActionDispatcher(
32
- id,
33
- rootRef,
34
- path,
35
- dropTargets
36
- );
37
-
38
- const title = useMemo(
39
- () => loadState("view-title") ?? titleProp,
40
- [loadState, titleProp]
41
- );
42
-
43
- const onEditTitle = useCallback(
44
- (title: string) => {
45
- if (path) {
46
- layoutDispatch({ type: "set-title", path, title });
47
- }
48
- },
49
- [layoutDispatch, path]
50
- );
51
-
52
- const restoredState = useMemo(() => loadState(id), [id, loadState]);
53
-
54
- const load = useCallback(
55
- (key?: string) => loadState(id, key),
56
- [id, loadState]
57
- );
58
-
59
- const purge = useCallback(
60
- (key) => {
61
- purgeState(id, key);
62
- layoutDispatch({ type: "save" });
63
- },
64
- [id, purgeState]
65
- );
66
-
67
- const save = useCallback(
68
- (state, key) => {
69
- saveState(id, key, state);
70
- layoutDispatch({ type: "save" });
71
- },
72
- [id, layoutDispatch, saveState]
73
- );
74
- const loadSession = useCallback(
75
- (key?: string) => loadSessionState(id, key),
76
- [id, loadSessionState]
77
- );
78
- const saveSession = useCallback(
79
- (state, key) => saveSessionState(id, key, state),
80
- [id, saveSessionState]
81
- );
82
-
83
- const onConfigChange = useCallback(
84
- ({ type: key, ...config }) => {
85
- const { [key]: data } = config;
86
- save(data, key);
87
- },
88
- [save]
89
- );
90
-
91
- return {
92
- contributions,
93
- dispatchViewAction,
94
- load,
95
- loadSession,
96
- onConfigChange,
97
- onEditTitle,
98
- purge,
99
- restoredState,
100
- save,
101
- saveSession,
102
- title,
103
- };
104
- };