@vuu-ui/vuu-layout 0.0.27

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 (117) hide show
  1. package/README.md +1 -0
  2. package/package.json +30 -0
  3. package/src/Component.css +2 -0
  4. package/src/Component.tsx +20 -0
  5. package/src/DraggableLayout.css +18 -0
  6. package/src/DraggableLayout.tsx +29 -0
  7. package/src/__tests__/flexbox-utils.spec.js +90 -0
  8. package/src/action-buttons/action-buttons.css +12 -0
  9. package/src/action-buttons/action-buttons.tsx +30 -0
  10. package/src/action-buttons/index.ts +1 -0
  11. package/src/chest-of-drawers/Chest.css +36 -0
  12. package/src/chest-of-drawers/Chest.tsx +42 -0
  13. package/src/chest-of-drawers/Drawer.css +153 -0
  14. package/src/chest-of-drawers/Drawer.tsx +118 -0
  15. package/src/chest-of-drawers/index.ts +2 -0
  16. package/src/common-types.ts +9 -0
  17. package/src/debug.ts +16 -0
  18. package/src/dialog/Dialog.css +16 -0
  19. package/src/dialog/Dialog.tsx +59 -0
  20. package/src/dialog/index.ts +1 -0
  21. package/src/drag-drop/BoxModel.ts +546 -0
  22. package/src/drag-drop/DragState.ts +222 -0
  23. package/src/drag-drop/Draggable.ts +282 -0
  24. package/src/drag-drop/DropMenu.css +70 -0
  25. package/src/drag-drop/DropMenu.tsx +68 -0
  26. package/src/drag-drop/DropTarget.ts +392 -0
  27. package/src/drag-drop/DropTargetRenderer.css +40 -0
  28. package/src/drag-drop/DropTargetRenderer.tsx +284 -0
  29. package/src/drag-drop/dragDropTypes.ts +49 -0
  30. package/src/drag-drop/index.ts +4 -0
  31. package/src/editable-label/EditableLabel.css +28 -0
  32. package/src/editable-label/EditableLabel.tsx +99 -0
  33. package/src/editable-label/index.ts +1 -0
  34. package/src/flexbox/Flexbox.css +45 -0
  35. package/src/flexbox/Flexbox.tsx +70 -0
  36. package/src/flexbox/FlexboxLayout.jsx +26 -0
  37. package/src/flexbox/FluidGrid.css +134 -0
  38. package/src/flexbox/FluidGrid.tsx +84 -0
  39. package/src/flexbox/FluidGridLayout.tsx +10 -0
  40. package/src/flexbox/Splitter.css +140 -0
  41. package/src/flexbox/Splitter.tsx +135 -0
  42. package/src/flexbox/flexbox-utils.ts +128 -0
  43. package/src/flexbox/flexboxTypes.ts +63 -0
  44. package/src/flexbox/index.ts +4 -0
  45. package/src/flexbox/useResponsiveSizing.ts +85 -0
  46. package/src/flexbox/useSplitterResizing.ts +272 -0
  47. package/src/index.ts +20 -0
  48. package/src/layout-action.ts +21 -0
  49. package/src/layout-header/ActionButton.tsx +23 -0
  50. package/src/layout-header/Header.css +8 -0
  51. package/src/layout-header/Header.tsx +222 -0
  52. package/src/layout-header/index.ts +1 -0
  53. package/src/layout-provider/LayoutProvider.tsx +160 -0
  54. package/src/layout-provider/LayoutProviderContext.ts +17 -0
  55. package/src/layout-provider/index.ts +2 -0
  56. package/src/layout-provider/useLayoutDragDrop.ts +241 -0
  57. package/src/layout-reducer/flexUtils.ts +281 -0
  58. package/src/layout-reducer/index.ts +4 -0
  59. package/src/layout-reducer/insert-layout-element.ts +365 -0
  60. package/src/layout-reducer/layout-reducer.ts +255 -0
  61. package/src/layout-reducer/layoutTypes.ts +151 -0
  62. package/src/layout-reducer/layoutUtils.ts +302 -0
  63. package/src/layout-reducer/remove-layout-element.ts +240 -0
  64. package/src/layout-reducer/replace-layout-element.ts +118 -0
  65. package/src/layout-reducer/resize-flex-children.ts +56 -0
  66. package/src/layout-reducer/wrap-layout-element.ts +317 -0
  67. package/src/layout-view/View.css +58 -0
  68. package/src/layout-view/View.tsx +149 -0
  69. package/src/layout-view/ViewContext.ts +31 -0
  70. package/src/layout-view/index.ts +4 -0
  71. package/src/layout-view/useView.tsx +104 -0
  72. package/src/layout-view/useViewActionDispatcher.ts +133 -0
  73. package/src/layout-view/useViewResize.ts +53 -0
  74. package/src/layout-view/viewTypes.ts +37 -0
  75. package/src/palette/Palette.css +37 -0
  76. package/src/palette/Palette.tsx +140 -0
  77. package/src/palette/PaletteUitk.css +9 -0
  78. package/src/palette/PaletteUitk.tsx +79 -0
  79. package/src/palette/index.ts +2 -0
  80. package/src/placeholder/Placeholder.css +10 -0
  81. package/src/placeholder/Placeholder.tsx +39 -0
  82. package/src/placeholder/index.ts +1 -0
  83. package/src/registry/ComponentRegistry.ts +35 -0
  84. package/src/registry/index.ts +1 -0
  85. package/src/responsive/OverflowMenu.css +31 -0
  86. package/src/responsive/OverflowMenu.jsx +56 -0
  87. package/src/responsive/breakpoints.ts +48 -0
  88. package/src/responsive/index.ts +4 -0
  89. package/src/responsive/measureMinimumNodeSize.ts +23 -0
  90. package/src/responsive/overflowUtils.js +14 -0
  91. package/src/responsive/use-breakpoints.ts +100 -0
  92. package/src/responsive/useOverflowObserver.ts +606 -0
  93. package/src/responsive/useResizeObserver.ts +154 -0
  94. package/src/responsive/utils.ts +37 -0
  95. package/src/stack/Stack.css +39 -0
  96. package/src/stack/Stack.tsx +160 -0
  97. package/src/stack/StackLayout.tsx +137 -0
  98. package/src/stack/index.ts +3 -0
  99. package/src/stack/stackTypes.ts +19 -0
  100. package/src/tabs/TabPanel.css +12 -0
  101. package/src/tabs/TabPanel.tsx +17 -0
  102. package/src/tabs/index.ts +1 -0
  103. package/src/tools/config-wrapper/ConfigWrapper.jsx +53 -0
  104. package/src/tools/config-wrapper/index.js +1 -0
  105. package/src/tools/devtools-box/layout-configurator.css +112 -0
  106. package/src/tools/devtools-box/layout-configurator.jsx +369 -0
  107. package/src/tools/devtools-tree/layout-tree-viewer.css +15 -0
  108. package/src/tools/devtools-tree/layout-tree-viewer.jsx +36 -0
  109. package/src/tools/index.js +3 -0
  110. package/src/use-persistent-state.ts +115 -0
  111. package/src/utils/componentFromLayout.tsx +30 -0
  112. package/src/utils/index.ts +6 -0
  113. package/src/utils/pathUtils.ts +294 -0
  114. package/src/utils/propUtils.ts +24 -0
  115. package/src/utils/refUtils.ts +16 -0
  116. package/src/utils/styleUtils.ts +14 -0
  117. package/src/utils/typeOf.ts +22 -0
@@ -0,0 +1,133 @@
1
+ import {
2
+ ReactElement,
3
+ RefObject,
4
+ SyntheticEvent,
5
+ useCallback,
6
+ useState,
7
+ } from "react";
8
+ import { useLayoutProviderDispatch } from "../layout-provider";
9
+ import { DragStartAction } from "../layout-reducer";
10
+ import { ViewDispatch } from "./ViewContext";
11
+ import { ViewAction } from "./viewTypes";
12
+ import { usePersistentState } from "../use-persistent-state";
13
+ import { DataSource } from "@vuu-ui/vuu-data";
14
+
15
+ export type Contribution = {
16
+ index?: number;
17
+ location?: string;
18
+ content: ReactElement;
19
+ };
20
+
21
+ export const useViewActionDispatcher = (
22
+ id: string,
23
+ root: RefObject<HTMLDivElement>,
24
+ viewPath?: string,
25
+ dropTargets?: string[]
26
+ ): [ViewDispatch, Contribution[] | undefined] => {
27
+ const { loadSessionState, purgeSessionState, purgeState, saveSessionState } =
28
+ usePersistentState();
29
+
30
+ const [contributions, setContributions] = useState<Contribution[]>(
31
+ loadSessionState(id, "contributions") ?? []
32
+ );
33
+ const dispatchLayoutAction = useLayoutProviderDispatch();
34
+ const updateContributions = useCallback(
35
+ (location: string, content: ReactElement) => {
36
+ const updatedContributions = contributions.concat([
37
+ { location, content },
38
+ ]);
39
+ saveSessionState(id, "contributions", updatedContributions);
40
+ setContributions(updatedContributions);
41
+ },
42
+ [contributions, id, saveSessionState]
43
+ );
44
+
45
+ const clearContributions = useCallback(() => {
46
+ purgeSessionState(id, "contributions");
47
+ setContributions([]);
48
+ }, [id, purgeSessionState]);
49
+
50
+ const handleRemove = useCallback(() => {
51
+ // TODO this requires a bit more thought. I works BECAUSE filteredGrid has
52
+ // stored its datasource in sessionState. It is highly pretty much a
53
+ // requirement for features to do so - how do we enforce it.
54
+ const ds = loadSessionState(id, "data-source") as DataSource;
55
+ if (ds) {
56
+ ds.unsubscribe();
57
+ }
58
+ purgeSessionState(id);
59
+ purgeState(id);
60
+ dispatchLayoutAction({ type: "remove", path: viewPath });
61
+ }, [
62
+ dispatchLayoutAction,
63
+ id,
64
+ loadSessionState,
65
+ purgeSessionState,
66
+ purgeState,
67
+ viewPath,
68
+ ]);
69
+
70
+ const handleMouseDown = useCallback(
71
+ async (evt, index, preDragActivity): Promise<boolean> => {
72
+ evt.stopPropagation();
73
+ const dragRect = root.current?.getBoundingClientRect();
74
+ return new Promise((resolve, reject) => {
75
+ // TODO should we check if we are allowed to drag ?
76
+ dispatchLayoutAction({
77
+ type: "drag-start",
78
+ evt,
79
+ path: index === undefined ? viewPath : `${viewPath}.${index}`,
80
+ dragRect,
81
+ preDragActivity,
82
+ dropTargets,
83
+ resolveDragStart: resolve,
84
+ rejectDragStart: reject,
85
+ } as DragStartAction);
86
+ });
87
+ },
88
+ [root, dispatchLayoutAction, viewPath, dropTargets]
89
+ );
90
+
91
+ // TODO should be event, action, then this method can bea assigned directly to a html element
92
+ // as an event hander
93
+ const dispatchAction = useCallback(
94
+ async <A extends ViewAction = ViewAction>(
95
+ action: A,
96
+ evt?: SyntheticEvent
97
+ ): Promise<boolean | void> => {
98
+ const { type } = action;
99
+ switch (type) {
100
+ case "maximize":
101
+ case "minimize":
102
+ case "restore":
103
+ // case Action.TEAR_OUT:
104
+ return dispatchLayoutAction({ type, path: action.path ?? viewPath });
105
+ case "remove":
106
+ return handleRemove();
107
+ case "mousedown":
108
+ console.log("2) ViewActionDispatch Hook dispatch Action mousedown");
109
+ return handleMouseDown(evt, action.index, action.preDragActivity);
110
+ case "add-toolbar-contribution":
111
+ return updateContributions(action.location, action.content);
112
+ case "remove-toolbar-contribution":
113
+ return clearContributions();
114
+ default: {
115
+ // if (Object.values(Action).includes(type)) {
116
+ // dispatch(action);
117
+ // }
118
+ return undefined;
119
+ }
120
+ }
121
+ },
122
+ [
123
+ dispatchLayoutAction,
124
+ viewPath,
125
+ handleRemove,
126
+ handleMouseDown,
127
+ updateContributions,
128
+ clearContributions,
129
+ ]
130
+ );
131
+
132
+ return [dispatchAction, contributions];
133
+ };
@@ -0,0 +1,53 @@
1
+ import { useResizeObserver, WidthHeight } from "@heswell/uitk-core";
2
+ import { RefObject, useCallback, useRef } from "react";
3
+
4
+ const NO_MEASUREMENT: string[] = [];
5
+
6
+ type size = {
7
+ height?: number;
8
+ width?: number;
9
+ };
10
+
11
+ export interface ViewResizeHookProps {
12
+ mainRef: RefObject<HTMLDivElement>;
13
+ resize?: "defer" | "responsive";
14
+ rootRef: RefObject<HTMLDivElement>;
15
+ }
16
+
17
+ export const useViewResize = ({
18
+ mainRef,
19
+ resize = "responsive",
20
+ rootRef,
21
+ }: ViewResizeHookProps) => {
22
+ const deferResize = resize === "defer";
23
+
24
+ const mainSize = useRef<size>({});
25
+ const resizeHandle = useRef<number>();
26
+
27
+ const setMainSize = useCallback(() => {
28
+ if (mainRef.current) {
29
+ mainRef.current.style.height = mainSize.current.height + "px";
30
+ mainRef.current.style.width = mainSize.current.width + "px";
31
+ }
32
+ resizeHandle.current = undefined;
33
+ }, []);
34
+
35
+ const onResize = useCallback(
36
+ ({ height, width }) => {
37
+ mainSize.current.height = height;
38
+ mainSize.current.width = width;
39
+ if (resizeHandle.current !== null) {
40
+ clearTimeout(resizeHandle.current);
41
+ }
42
+ resizeHandle.current = window.setTimeout(setMainSize, 40);
43
+ },
44
+ [setMainSize]
45
+ );
46
+
47
+ useResizeObserver(
48
+ rootRef,
49
+ deferResize ? WidthHeight : NO_MEASUREMENT,
50
+ onResize,
51
+ deferResize
52
+ );
53
+ };
@@ -0,0 +1,37 @@
1
+ import { HTMLAttributes } from "react";
2
+ import { HeaderProps } from "../layout-header";
3
+ import {
4
+ MaximizeAction,
5
+ MinimizeAction,
6
+ MousedownViewAction,
7
+ RemoveAction,
8
+ RestoreAction,
9
+ TearoutAction,
10
+ AddToolbarContributionViewAction,
11
+ RemoveToolbarContributionViewAction,
12
+ } from "../layout-reducer";
13
+
14
+ export type ViewAction =
15
+ | MaximizeAction
16
+ | MinimizeAction
17
+ | MousedownViewAction
18
+ | RemoveAction
19
+ | RestoreAction
20
+ | TearoutAction
21
+ | AddToolbarContributionViewAction
22
+ | RemoveToolbarContributionViewAction;
23
+
24
+ export interface ViewProps extends HTMLAttributes<HTMLDivElement> {
25
+ closeable?: boolean;
26
+ collapsed?: boolean;
27
+ "data-resizeable"?: boolean;
28
+ dropTargets?: string[];
29
+ expanded?: boolean;
30
+ flexFill?: any;
31
+ header?: boolean | Partial<HeaderProps>;
32
+ orientation?: "vertical" | "horizontal";
33
+ path?: string;
34
+ resize?: "defer" | "responsive";
35
+ resizeable?: boolean;
36
+ tearOut?: boolean;
37
+ }
@@ -0,0 +1,37 @@
1
+ .vuuPalette {
2
+ }
3
+
4
+ .vuuPalette-horizontal {
5
+ align-items: center;
6
+ display: flex;
7
+ }
8
+
9
+ .vuuPalette .vuuComponentIcon {
10
+ }
11
+
12
+ .vuuPaletteItem {
13
+ --vuu-icon-color: var(--uitk-separable-primary-background);
14
+ --vuu-icon-inset: calc(50% - 12px) auto auto -3px;
15
+ --vuu-icon-svg: var(--svg-grab-handle);
16
+ --vuu-icon-height: 24px;
17
+ --vuu-icon-width: 24px;
18
+ padding-left: 20px;
19
+ }
20
+
21
+ .vuuPaletteItem[data-icon]:after {
22
+ --height: var(--vuu-icon-height, var(--vuu-icon-size, 12px));
23
+ --width: var(--vuu-icon-width, var(--vuu-icon-size, 12px));
24
+
25
+ content: "";
26
+ background-color: var(--vuu-icon-color, black);
27
+ height: var(--height);
28
+ inset: var(--vuu-icon-inset,0 auto 0 0);
29
+ mask: var(--vuu-icon-svg) center center/var(--width) var(--height) no-repeat;
30
+ -webkit-mask: var(--vuu-icon-svg) center center/var(--width) var(--height) no-repeat;
31
+ position: absolute;
32
+ width: var(--width);
33
+ }
34
+
35
+ .vuuSimpleDraggableWrapper > .vuuPaletteItem {
36
+ --vuu-icon-color: var(--uitk-selectable-foreground);
37
+ }
@@ -0,0 +1,140 @@
1
+ import { List, ListItem, ListItemProps } from "@heswell/uitk-lab";
2
+ import { uuid } from "@vuu-ui/vuu-utils";
3
+ import cx from "classnames";
4
+ import {
5
+ cloneElement,
6
+ HTMLAttributes,
7
+ memo,
8
+ MouseEvent,
9
+ ReactElement,
10
+ } from "react";
11
+ import { useLayoutProviderDispatch } from "../layout-provider";
12
+ import { View } from "../layout-view";
13
+ import { registerComponent } from "../registry/ComponentRegistry";
14
+
15
+ import "./Palette.css";
16
+
17
+ const clonePaletteItem = (paletteItem: HTMLElement) => {
18
+ const dolly = paletteItem.cloneNode(true) as HTMLElement;
19
+ dolly.id = "";
20
+ delete dolly.dataset.idx;
21
+ return dolly;
22
+ };
23
+
24
+ export interface PaletteItemProps extends ListItemProps {
25
+ children: ReactElement;
26
+ closeable?: boolean;
27
+ header?: boolean;
28
+ idx?: number;
29
+ resize?: "defer";
30
+ resizeable?: boolean;
31
+ }
32
+
33
+ export const PaletteItem = memo(
34
+ ({
35
+ className,
36
+ children: component,
37
+ idx,
38
+ resizeable,
39
+ header,
40
+ closeable,
41
+ ...props
42
+ }: PaletteItemProps) => {
43
+ return (
44
+ <ListItem
45
+ className={cx("vuuPaletteItem", className)}
46
+ data-icon="grab-handle"
47
+ {...props}
48
+ />
49
+ );
50
+ }
51
+ );
52
+
53
+ PaletteItem.displayName = "PaletteItem";
54
+
55
+ export interface PaletteProps
56
+ extends Omit<HTMLAttributes<HTMLDivElement>, "onSelect"> {
57
+ children: ReactElement[];
58
+ orientation: "horizontal" | "vertical";
59
+ selection?: string;
60
+ }
61
+
62
+ export const Palette = ({
63
+ children,
64
+ className,
65
+ orientation = "horizontal",
66
+ ...props
67
+ }: PaletteProps) => {
68
+ const dispatch = useLayoutProviderDispatch();
69
+ const classBase = "vuuPalette";
70
+
71
+ function handleMouseDown(evt: MouseEvent) {
72
+ const target = evt.target as HTMLElement;
73
+ const listItemElement = target.closest(".vuuPaletteItem") as HTMLElement;
74
+ const idx = parseInt(listItemElement.dataset.idx ?? "-1");
75
+ if (idx !== -1) {
76
+ console.log({
77
+ children,
78
+ idx,
79
+ listItemElement,
80
+ });
81
+ }
82
+ const {
83
+ props: { caption, children: payload, template, ...props },
84
+ } = children[idx];
85
+ const { height, left, top, width } =
86
+ listItemElement.getBoundingClientRect();
87
+ const id = uuid();
88
+ const identifiers = { id, key: id };
89
+ const component = template ? (
90
+ payload
91
+ ) : (
92
+ <View {...identifiers} {...props} title={props.label}>
93
+ {payload}
94
+ </View>
95
+ );
96
+
97
+ dispatch({
98
+ dragRect: {
99
+ left,
100
+ top,
101
+ right: left + width,
102
+ bottom: top + 150,
103
+ width,
104
+ height,
105
+ },
106
+ dragElement: clonePaletteItem(listItemElement),
107
+ evt: evt.nativeEvent,
108
+ instructions: {
109
+ DoNotRemove: true,
110
+ DoNotTransform: true,
111
+ RemoveDraggableOnDragEnd: true,
112
+ dragThreshold: 10,
113
+ },
114
+ path: "*",
115
+ payload: component,
116
+ type: "drag-start",
117
+ });
118
+ }
119
+
120
+ return (
121
+ <List
122
+ {...props}
123
+ borderless
124
+ className={cx(classBase, className, `${classBase}-${orientation}`)}
125
+ maxHeight={800}
126
+ selected={null}
127
+ >
128
+ {children.map((child, idx) =>
129
+ child.type === PaletteItem
130
+ ? cloneElement(child, {
131
+ key: idx,
132
+ onMouseDown: handleMouseDown,
133
+ })
134
+ : child
135
+ )}
136
+ </List>
137
+ );
138
+ };
139
+
140
+ registerComponent("Palette", Palette, "view");
@@ -0,0 +1,9 @@
1
+ .vuuPalette {
2
+ --list-item-header-bg: inherit;
3
+ --list-item-header-color: inherit;
4
+ --list-item-padding: 0 6px 0 24px;
5
+ --list-item-header-twisty-color: black;
6
+ --list-item-header-twisty-left: 3px;
7
+ --list-item-header-twisty-right: auto;
8
+ }
9
+
@@ -0,0 +1,79 @@
1
+ import { List, ListItem, ListItemProps, ListProps } from "@heswell/uitk-lab";
2
+ import { uuid } from "@vuu-ui/vuu-utils";
3
+ import cx from "classnames";
4
+ import { MouseEvent, ReactElement } from "react";
5
+ import { useLayoutProviderDispatch } from "../layout-provider";
6
+ import { View } from "../layout-view";
7
+ import { registerComponent } from "../registry/ComponentRegistry";
8
+
9
+ import "./PaletteUitk.css";
10
+
11
+ const classBase = "vuuPalette";
12
+
13
+ export interface PaletteListItemProps extends ListItemProps {
14
+ children: ReactElement;
15
+ ViewProps: {
16
+ header?: boolean;
17
+ closeable?: boolean;
18
+ resizeable?: boolean;
19
+ };
20
+ template: boolean;
21
+ }
22
+
23
+ export const PaletteListItem = (props: PaletteListItemProps) => {
24
+ const { children, ViewProps, label, onMouseDown, template, ...restProps } =
25
+ props;
26
+ const dispatch = useLayoutProviderDispatch();
27
+
28
+ const handleMouseDown = (evt: MouseEvent<HTMLDivElement>) => {
29
+ const { left, top, width } = evt.currentTarget.getBoundingClientRect();
30
+ const id = uuid();
31
+ const identifiers = { id, key: id };
32
+ const component = template ? (
33
+ children
34
+ ) : (
35
+ <View {...identifiers} {...ViewProps} title={props.label}>
36
+ {children}
37
+ </View>
38
+ );
39
+
40
+ dispatch({
41
+ type: "drag-start",
42
+ evt: evt.nativeEvent,
43
+ path: "*",
44
+ payload: component,
45
+ instructions: {
46
+ DoNotRemove: true,
47
+ DoNotTransform: true,
48
+ RemoveDraggableOnDragEnd: true,
49
+ dragThreshold: 10,
50
+ },
51
+ dragRect: {
52
+ left,
53
+ top,
54
+ right: left + width,
55
+ bottom: top + 150,
56
+ width,
57
+ height: 100,
58
+ },
59
+ });
60
+ };
61
+ return (
62
+ <ListItem onMouseDown={handleMouseDown} {...restProps}>
63
+ {label}
64
+ </ListItem>
65
+ );
66
+ };
67
+
68
+ export const PaletteUitk = ({ className, ...props }: ListProps) => {
69
+ return (
70
+ <List
71
+ {...props}
72
+ className={cx(classBase, className)}
73
+ height="100%"
74
+ selectionStrategy="none"
75
+ />
76
+ );
77
+ };
78
+
79
+ registerComponent("PaletteUitk", PaletteUitk, "view");
@@ -0,0 +1,2 @@
1
+ export * from "./Palette";
2
+ export * from "./PaletteUitk";
@@ -0,0 +1,10 @@
1
+ .vuuPlaceholder {
2
+ flex-basis: 0;
3
+ flex-grow: 1;
4
+ flex-shrink: 1;
5
+ }
6
+
7
+ .vuuPlaceholder-shim {
8
+ flex-grow: 0;
9
+ flex-shrink: 0;
10
+ }
@@ -0,0 +1,39 @@
1
+ import React, { HTMLAttributes } from "react";
2
+ import cx from "classnames";
3
+ import { registerComponent } from "../registry/ComponentRegistry";
4
+
5
+ import "./Placeholder.css";
6
+
7
+ const classBase = "vuuPlaceholder";
8
+
9
+ export interface PlaceholderProps extends HTMLAttributes<HTMLDivElement> {
10
+ closeable?: boolean;
11
+ flexFill?: boolean;
12
+ resizeable?: boolean;
13
+ shim?: boolean;
14
+ }
15
+
16
+ export const Placeholder = ({
17
+ className,
18
+ closeable,
19
+ flexFill,
20
+ resizeable,
21
+ shim,
22
+ ...props
23
+ }: PlaceholderProps) => {
24
+ return (
25
+ <div
26
+ className={cx(classBase, className, {
27
+ [`${classBase}-shim`]: shim,
28
+ })}
29
+ {...props}
30
+ data-placeholder
31
+ data-resizeable
32
+ >
33
+ {/* <LayoutProviderVersion /> */}
34
+ </div>
35
+ );
36
+ };
37
+
38
+ Placeholder.displayName = "Placeholder";
39
+ registerComponent("Placeholder", Placeholder);
@@ -0,0 +1 @@
1
+ export * from './Placeholder';
@@ -0,0 +1,35 @@
1
+ import React, { FunctionComponent } from 'react';
2
+
3
+ const _containers: { [key: string]: boolean } = {};
4
+ const _views: { [key: string]: boolean } = {};
5
+
6
+ export type layoutComponentType = 'component' | 'container' | 'view';
7
+
8
+ export const ComponentRegistry: { [key: string]: FunctionComponent } = {};
9
+
10
+ export function isContainer(componentType: string) {
11
+ return _containers[componentType] === true;
12
+ }
13
+
14
+ export function isView(componentType: string) {
15
+ return _views[componentType] === true;
16
+ }
17
+
18
+ export const isLayoutComponent = (type: string) => isContainer(type) || isView(type);
19
+
20
+ export const isRegistered = (className: string) => !!ComponentRegistry[className];
21
+
22
+ // We could check and set displayName in here
23
+ export function registerComponent(
24
+ componentName: string,
25
+ component: FunctionComponent<any>,
26
+ type: layoutComponentType = 'component'
27
+ ) {
28
+ ComponentRegistry[componentName] = component;
29
+
30
+ if (type === 'container') {
31
+ _containers[componentName] = true;
32
+ } else if (type === 'view') {
33
+ _views[componentName] = true;
34
+ }
35
+ }
@@ -0,0 +1 @@
1
+ export * from './ComponentRegistry';
@@ -0,0 +1,31 @@
1
+ .OverflowMenu {
2
+ /* width: 20px;
3
+ height: 20px;
4
+ display: flex;
5
+ align-items: center;
6
+ justify-content: center;
7
+ cursor: pointer;
8
+ margin: 6px 0px 6px 0;
9
+ align-self: flex-end;
10
+ border: none;
11
+ border-radius: 0;
12
+ background-color: inherit;
13
+ padding: 0; */
14
+ }
15
+
16
+ /* .OverflowMenu-open {
17
+ backgroundcolor: active.overflow.background;
18
+ } */
19
+
20
+ /* .OverflowMenu-open .OverflowMenu-icon {
21
+ color: active.overflow.color;
22
+ } */
23
+
24
+ /* .Toolbar .Toolbar-overflow:hover {
25
+ background-color: lightgrey;
26
+ } */
27
+
28
+ [data-overflowed] {
29
+ order: 99;
30
+ /* visibility: hidden; */
31
+ }
@@ -0,0 +1,56 @@
1
+ import React, { forwardRef } from 'react';
2
+ import { MoreSmallListVertButton } from '../action-buttons';
3
+
4
+ import './OverflowMenu.css';
5
+
6
+ const OverflowMenu = forwardRef(function OverflowMenu(
7
+ // eslint-disable-next-line no-unused-vars
8
+ { iconName = 'more', overflowOffsetLeft: left, source = [], ...rest },
9
+ // eslint-disable-next-line no-unused-vars
10
+ ref
11
+ ) {
12
+ return source.length > 0 ? (
13
+ <MoreSmallListVertButton />
14
+ ) : // <Dropdown
15
+ // ListProps={{
16
+ // width: 200,
17
+ // }}
18
+ // ref={ref}
19
+ // source={source}
20
+ // {...rest}
21
+ // >
22
+ // {({ DropdownButtonProps, isOpen }) => {
23
+ // const { style, ...restButtonProps } = DropdownButtonProps;
24
+
25
+ // const {
26
+ // onClick,
27
+ // onKeyDown,
28
+ // onFocus,
29
+ // onBlur,
30
+ // 'aria-expanded': menuOpen, // do we use this or isOpen ?
31
+ // } = DropdownButtonProps;
32
+ // const defaultProps = {
33
+ // 'data-jpmui-test': 'dropdown-button',
34
+ // 'aria-label': 'toggle overflow',
35
+ // 'aria-haspopup': true,
36
+ // className: cx('OverflowMenu-dropdown', {
37
+ // 'OverflowMenu-open': isOpen,
38
+ // }),
39
+ // onBlur,
40
+ // onPress: onClick,
41
+ // onFocus,
42
+ // onKeyDown,
43
+ // title: 'Overflow Menu',
44
+ // type: 'button',
45
+ // variant: 'secondary',
46
+ // };
47
+
48
+ // return (
49
+ // <MoreSmallListVertButton {...defaultProps}/>
50
+ // );
51
+ // }}
52
+ // </Dropdown>
53
+ null;
54
+ });
55
+
56
+ export default OverflowMenu;