@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
package/README.md ADDED
@@ -0,0 +1 @@
1
+ This is a regular package
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@vuu-ui/vuu-layout",
3
+ "version": "0.0.27",
4
+ "description": "VUU Layout Components",
5
+ "main": "src/index.ts",
6
+ "author": "heswell",
7
+ "license": "Apache-2.0",
8
+ "scripts": {
9
+ "build": "node ../../scripts/run-build.mjs",
10
+ "type-defs": "tsc --project tsconfig-emit-types.json"
11
+ },
12
+ "files": [
13
+ "index.js",
14
+ "index.css",
15
+ "index.js.map",
16
+ "index.css.map",
17
+ "/src"
18
+ ],
19
+ "types": "src/index.ts",
20
+ "peerDependencies": {
21
+ "@heswell/uitk-core": "0.8.0-vuu.1",
22
+ "@heswell/uitk-icons": "0.7.0-vuu.1",
23
+ "@heswell/uitk-lab": "0.8.0-vuu.1",
24
+ "@vuu-ui/ui-controls": "0.0.27",
25
+ "@vuu-ui/vuu-utils": "0.0.27",
26
+ "classnames": "^2.2.6",
27
+ "react": "^17.0.2",
28
+ "react-dom": "^17.0.2"
29
+ }
30
+ }
@@ -0,0 +1,2 @@
1
+ .Component {
2
+ }
@@ -0,0 +1,20 @@
1
+ import React, { forwardRef, HTMLAttributes } from 'react';
2
+ import { registerComponent } from './registry/ComponentRegistry';
3
+
4
+ import './Component.css';
5
+
6
+ export interface ComponentProps extends HTMLAttributes<HTMLDivElement> {
7
+ resizeable?: boolean;
8
+ }
9
+
10
+ const Component = forwardRef(function Component(
11
+ { resizeable, ...props }: ComponentProps,
12
+ ref: React.ForwardedRef<HTMLDivElement>
13
+ ) {
14
+ return <div {...props} className="Component" ref={ref} />;
15
+ }) as React.FunctionComponent<ComponentProps>;
16
+ Component.displayName = 'Component';
17
+
18
+ export default Component;
19
+
20
+ registerComponent('Component', Component);
@@ -0,0 +1,18 @@
1
+ .DraggableLayout {
2
+ display: inline-block;
3
+ outline: none;
4
+ }
5
+
6
+ [data-dragging='true'] {
7
+ position: absolute !important;
8
+ z-index: 100;
9
+ }
10
+
11
+ .vuuSimpleDraggableWrapper {
12
+ background-color: white;
13
+ box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.2);
14
+ }
15
+ .vuuSimpleDraggableWrapper > * {
16
+ height: 100%;
17
+ width: 100%;
18
+ }
@@ -0,0 +1,29 @@
1
+ import classnames from 'classnames';
2
+ import React, { useRef } from 'react';
3
+ import { registerComponent } from './registry/ComponentRegistry';
4
+
5
+ import './DraggableLayout.css';
6
+
7
+ // We need to add props to restrict drag behaviour to, for example, popups only
8
+ export const DraggableLayout = function DraggableLayout(props) {
9
+ // We shouldn't need this but somewhere the customDispatcher/handleDragStart callback is not
10
+ // being updated and preserves stale ref to props.children, so DragDrop from within a nested
11
+ // LatoutContext (Stack or DraggableLayout) fails.
12
+ const sourceRef = useRef();
13
+ sourceRef.current = props;
14
+
15
+ const { className: classNameProp, id, style } = props;
16
+
17
+ const className = classnames('DraggableLayout', classNameProp);
18
+ return (
19
+ <div className={className} id={id} style={style}>
20
+ {props.children}
21
+ </div>
22
+ );
23
+ };
24
+
25
+ const componentName = 'DraggableLayout';
26
+
27
+ DraggableLayout.displayName = componentName;
28
+
29
+ registerComponent(componentName, DraggableLayout, 'container');
@@ -0,0 +1,90 @@
1
+ import {
2
+ findSplitterAndPlaceholderPositions,
3
+ PLACEHOLDER,
4
+ SPLITTER
5
+ } from '../flexbox/flexbox-utils';
6
+
7
+ describe('findSplitterAndPlaceholderPositions', () => {
8
+ let positions;
9
+ describe('WHEN there are less than 2 items', () => {
10
+ it('THEN no splitters are inserted', () => {
11
+ positions = findSplitterAndPlaceholderPositions([]);
12
+ expect(positions).toEqual([]);
13
+
14
+ positions = findSplitterAndPlaceholderPositions([{ resizeable: true }]);
15
+ expect(positions).toEqual([0]);
16
+
17
+ positions = findSplitterAndPlaceholderPositions([{ resizeable: false }]);
18
+ expect(positions).toEqual([0]);
19
+ });
20
+ });
21
+
22
+ describe('WHEN there are no resizeable items', () => {
23
+ it('THEN no splitters are inserted', () => {
24
+ positions = findSplitterAndPlaceholderPositions([
25
+ { resizeable: false },
26
+ { resizeable: false }
27
+ ]);
28
+ expect(positions).toEqual([0, 0]);
29
+
30
+ positions = findSplitterAndPlaceholderPositions([
31
+ { resizeable: false },
32
+ { resizeable: false },
33
+ { resizeable: false }
34
+ ]);
35
+ expect(positions).toEqual([0, 0, 0]);
36
+
37
+ positions = findSplitterAndPlaceholderPositions([
38
+ { resizeable: false },
39
+ { resizeable: false },
40
+ { resizeable: false },
41
+ { resizeable: false }
42
+ ]);
43
+ expect(positions).toEqual([0, 0, 0, 0]);
44
+ });
45
+ });
46
+
47
+ describe('WHEN all items are resizeable', () => {
48
+ it('THEN splitters are inserted between items', () => {
49
+ positions = findSplitterAndPlaceholderPositions([{ resizeable: true }, { resizeable: true }]);
50
+ expect(positions).toEqual([1, 0]);
51
+
52
+ positions = findSplitterAndPlaceholderPositions([
53
+ { resizeable: true },
54
+ { resizeable: true },
55
+ { resizeable: true }
56
+ ]);
57
+ expect(positions).toEqual([1, 1, 0]);
58
+
59
+ positions = findSplitterAndPlaceholderPositions([
60
+ { resizeable: true },
61
+ { resizeable: true },
62
+ { resizeable: true },
63
+ { resizeable: true }
64
+ ]);
65
+ expect(positions).toEqual([1, 1, 1, 0]);
66
+ });
67
+ });
68
+
69
+ describe('WHEN some items are resizeable', () => {
70
+ it('THEN splitters are inserted where appropriate between items', () => {
71
+ // positions = findSplitterAndPlaceholderPositions([{resizeable: true},{resizeable: true}]);
72
+ // expect(positions).toEqual([1,0])
73
+
74
+ positions = findSplitterAndPlaceholderPositions([
75
+ { resizeable: false },
76
+ { resizeable: true },
77
+ { resizeable: true }
78
+ ]);
79
+ expect(positions).toEqual([0, 1, 0]);
80
+
81
+ positions = findSplitterAndPlaceholderPositions([
82
+ { resizeable: false },
83
+ { resizeable: true },
84
+ { resizeable: true },
85
+ { resizeable: true }
86
+ ]);
87
+ expect(positions).toEqual([0, 1, 1, 0]);
88
+ });
89
+ });
90
+ });
@@ -0,0 +1,12 @@
1
+ .hwActionButton {
2
+ border-width: 0;
3
+ border-radius: 0;
4
+ min-height: 28px;
5
+ min-width: 28px;
6
+ padding: 0;
7
+ }
8
+
9
+ .hwActionButton svg {
10
+ width: 12px;
11
+ height: 12px;
12
+ }
@@ -0,0 +1,30 @@
1
+ import React from "react";
2
+ import {
3
+ ChevronDoubleLeftIcon,
4
+ ChevronDoubleRightIcon,
5
+ } from "@vuu-ui/ui-controls";
6
+ import { Button, ButtonProps } from "@heswell/uitk-core";
7
+
8
+ import "./action-buttons.css";
9
+
10
+ export const ChevronDoubleLeftButton = (props: ButtonProps) => (
11
+ <Button
12
+ className="hwActionButton"
13
+ variant="secondary"
14
+ aria-label="Close"
15
+ {...props}
16
+ >
17
+ <ChevronDoubleLeftIcon />
18
+ </Button>
19
+ );
20
+
21
+ export const ChevronDoubleRightButton = (props: ButtonProps) => (
22
+ <Button
23
+ className="hwActionButton"
24
+ variant="secondary"
25
+ aria-label="Close"
26
+ {...props}
27
+ >
28
+ <ChevronDoubleRightIcon />
29
+ </Button>
30
+ );
@@ -0,0 +1 @@
1
+ export * from './action-buttons';
@@ -0,0 +1,36 @@
1
+ .hwChest {
2
+ --chest-bg: var(--hw-chest-bg, inherit);
3
+ --drawer-bg: var(--hw-drawer-bg, inherit);
4
+ --drawer-size: var(--hw-drawer-size, 200px);
5
+ --drawer-peek-size: var(--hw-drawer-peek-size, 32px);
6
+ --drawer-transition-duration: var(--hw-drawer-transition-duration, 0.4s);
7
+ background-color: var(--chest-bg);
8
+ display: flex;
9
+ }
10
+
11
+ .hwChest-horizontal {
12
+ flex-direction: row;
13
+ }
14
+
15
+ .hwChest-vertical {
16
+ flex-direction: column;
17
+ }
18
+
19
+ .hwChest-content {
20
+ background-color: var(--chest-bg);
21
+ flex-grow: 1;
22
+ flex-shrink: 1;
23
+ overflow: hidden;
24
+ /* position: relative; */
25
+ display: flex;
26
+ align-items: center;
27
+ justify-content: center;
28
+ }
29
+
30
+ .hwChest-horizontal .hwChest-content {
31
+ flex-basis: 100%;
32
+ }
33
+
34
+ .hwChest-vertical .hwChest-content {
35
+ flex-basis: 100%;
36
+ }
@@ -0,0 +1,42 @@
1
+ import React, { HTMLAttributes, ReactElement } from "react";
2
+ import cx from "classnames";
3
+ import Drawer from "./Drawer";
4
+ import { partition } from "@vuu-ui/vuu-utils";
5
+ import { registerComponent } from "../registry/ComponentRegistry";
6
+
7
+ import "./Chest.css";
8
+
9
+ const isDrawer = (component: ReactElement) => component.type === Drawer;
10
+ const isVertical = ({ props: { position = "left" } }: ReactElement) =>
11
+ position.match(/top|bottom/);
12
+
13
+ export interface ChestProps extends HTMLAttributes<HTMLDivElement> {
14
+ children: ReactElement[];
15
+ }
16
+
17
+ const Chest = (props: ChestProps) => {
18
+ const { children, className: classNameProp, id, style } = props;
19
+ const classBase = "hwChest";
20
+ const [drawers, content] = partition(children, isDrawer);
21
+ const [verticalDrawers, horizontalDrawers] = partition(drawers, isVertical);
22
+ const orientation =
23
+ verticalDrawers.length === 0
24
+ ? "horizontal"
25
+ : horizontalDrawers.length === 0
26
+ ? "vertical"
27
+ : "both";
28
+
29
+ const className = cx(classBase, classNameProp, `${classBase}-${orientation}`);
30
+
31
+ return (
32
+ <div className={className} id={id} style={style}>
33
+ {drawers}
34
+ <div className={`${classBase}-content`}>{content}</div>
35
+ </div>
36
+ );
37
+ };
38
+ Chest.displayName = "Chest";
39
+
40
+ export default Chest;
41
+
42
+ registerComponent("Chest", Chest, "container");
@@ -0,0 +1,153 @@
1
+ .hwDrawer {
2
+ --drawer-leading-edge-border: solid 1px var(--uitk-container-borderColor-medium, none);
3
+ transition: flex-basis;
4
+ transition-duration: var(--drawer-transition-duration);
5
+ position: relative;
6
+ z-index: 1;
7
+ flex-basis: 0;
8
+ flex-grow: 1;
9
+ flex-shrink: 1;
10
+ min-width: 0;
11
+ min-height: 0;
12
+ display: flex;
13
+ }
14
+
15
+ .hwDrawer-peekaboo {
16
+ flex-basis: var(--drawer-peek-size);
17
+ flex-grow: 0;
18
+ flex-shrink: 0;
19
+ }
20
+
21
+ .hwDrawer-inline.hwDrawer-open {
22
+ flex-basis: var(--drawer-size);
23
+ flex-grow: 0;
24
+ flex-shrink: 0;
25
+ }
26
+
27
+ .hwDrawer-liner {
28
+ background-color: var(--drawer-bg);
29
+ overflow: hidden;
30
+ position: relative;
31
+ }
32
+
33
+ .hwDrawer-content {
34
+ height: 100%;
35
+ overflow: hidden;
36
+ position: absolute;
37
+ top: 0;
38
+ right: var(--drawer-peek-size);
39
+ transition: right;
40
+ transition-duration: var(--drawer-transition-duration);
41
+ width: 100%;
42
+ flex: 1 1 100%;
43
+ }
44
+
45
+ .hwDrawer-open .hwDrawer-content {
46
+ right: 0;
47
+ }
48
+
49
+ /* .hwDrawer:not(.hwDrawer-open) .hwDrawer-liner > * {
50
+ display: none;
51
+ } */
52
+
53
+ .hwDrawer-left {
54
+ border-right: var(--drawer-leading-edge-border);
55
+ }
56
+ .hwDrawer-right {
57
+ border-left: var(--drawer-leading-edge-border);
58
+ }
59
+ .hwDrawer-top {
60
+ border-bottom: var(--drawer-leading-edge-border);
61
+ }
62
+ .hwDrawer-bottom {
63
+ border-top: var(--drawer-leading-edge-border);
64
+ }
65
+
66
+ .hwDrawer-left .hwDrawer-liner,
67
+ .hwDrawer-right .hwDrawer-liner {
68
+ height: 100%;
69
+ transition: width;
70
+ }
71
+
72
+ .hwDrawer-top .hwDrawer-liner,
73
+ .hwDrawer-bottom .hwDrawer-liner {
74
+ width: 100%;
75
+ transition: height;
76
+ }
77
+
78
+ .hwDrawer-inline .hwDrawer-liner {
79
+ width: 100%;
80
+ height: 100%;
81
+ }
82
+
83
+ .hwDrawer-over .hwDrawer-liner {
84
+ position: absolute;
85
+ transition-duration: 0.4s;
86
+ }
87
+
88
+ .hwDrawer-over.hwDrawer-left .hwDrawer-liner {
89
+ top: 0;
90
+ left: 0;
91
+ width: 0;
92
+ }
93
+
94
+ .hwDrawer-over.hwDrawer-right .hwDrawer-liner {
95
+ top: 0;
96
+ right: 0;
97
+ width: 0;
98
+ }
99
+
100
+ .hwDrawer-over.hwDrawer-top .hwDrawer-liner {
101
+ height: 0;
102
+ top: 0;
103
+ left: 0;
104
+ }
105
+
106
+ .hwDrawer-over.hwDrawer-bottom .hwDrawer-liner {
107
+ bottom: 0;
108
+ height: 0;
109
+ left: 0;
110
+ }
111
+
112
+ .hwDrawer-left.hwDrawer-over.hwDrawer-peekaboo .hwDrawer-liner,
113
+ .hwDrawer-right.hwDrawer-over.hwDrawer-peekaboo .hwDrawer-liner {
114
+ width: var(--drawer-peek-size);
115
+ }
116
+
117
+ .hwDrawer-top.hwDrawer-over.hwDrawer-peekaboo .hwDrawer-liner,
118
+ .hwDrawer-bottom.hwDrawer-over.hwDrawer-peekaboo .hwDrawer-liner {
119
+ height: var(--drawer-peek-size);
120
+ }
121
+
122
+ .hwDrawer-left.hwDrawer-over.hwDrawer-open .hwDrawer-liner,
123
+ .hwDrawer-right.hwDrawer-over.hwDrawer-open .hwDrawer-liner {
124
+ width: var(--drawer-size);
125
+ }
126
+
127
+ .hwDrawer-top.hwDrawer-over.hwDrawer-open .hwDrawer-liner,
128
+ .hwDrawer-bottom.hwDrawer-over.hwDrawer-open .hwDrawer-liner {
129
+ height: var(--drawer-size);
130
+ }
131
+
132
+ .hwDrawer-top,
133
+ .hwDrawer-left {
134
+ order: 0;
135
+ }
136
+
137
+ .hwDrawer-bottom,
138
+ .hwDrawer-right {
139
+ order: 99;
140
+ }
141
+
142
+ .hwDrawer-left,
143
+ .hwDrawer-right {
144
+ flex-direction: column;
145
+ }
146
+
147
+ .hwToggleButton-container {
148
+ --uitkButton-height: 28px;
149
+ --uitkButton-width: 28px;
150
+ --vuu-icon-size: 12px;
151
+ --vuu-icon-svg: var(--svg-chevron-double-left);
152
+ flex: 0 0 28px;
153
+ }
@@ -0,0 +1,118 @@
1
+ import React, { CSSProperties, HTMLAttributes, useCallback } from "react";
2
+ import cx from "classnames";
3
+ import { Button, useControlled } from "@heswell/uitk-core";
4
+
5
+ import "./Drawer.css";
6
+
7
+ const sizeAttribute = (value: string | number) => {
8
+ return typeof value === "string" ? value : value + "px";
9
+ };
10
+
11
+ const getStyle = (
12
+ styleProp?: CSSProperties,
13
+ sizeOpen?: number,
14
+ sizeClosed?: number
15
+ ) => {
16
+ const hasSizeOpen = sizeOpen !== undefined;
17
+ const hasSizeClosed = sizeClosed !== undefined;
18
+
19
+ if (!styleProp && !hasSizeClosed && !hasSizeOpen) {
20
+ return undefined;
21
+ }
22
+
23
+ if (!hasSizeClosed && !hasSizeOpen) {
24
+ return styleProp;
25
+ }
26
+
27
+ return {
28
+ ...styleProp,
29
+ "--drawer-size": hasSizeOpen ? sizeAttribute(sizeOpen) : undefined,
30
+ "--drawer-peek-size": hasSizeClosed ? sizeAttribute(sizeClosed) : undefined,
31
+ };
32
+ };
33
+
34
+ export interface DrawerProps extends HTMLAttributes<HTMLDivElement> {
35
+ clickToOpen?: boolean;
36
+ defaultOpen: boolean;
37
+ inline?: boolean;
38
+ open?: boolean;
39
+ peekaboo?: boolean;
40
+ position?: "left" | "right" | "top" | "bottom";
41
+ sizeOpen?: number;
42
+ sizeClosed?: number;
43
+ toggleButton?: "start" | "end";
44
+ }
45
+ const Drawer = ({
46
+ children,
47
+ className: classNameProp,
48
+ clickToOpen,
49
+ defaultOpen,
50
+ sizeOpen,
51
+ sizeClosed,
52
+ style: styleProp,
53
+ open: openProp,
54
+ position = "left",
55
+ inline,
56
+ onClick,
57
+ peekaboo = false,
58
+ toggleButton,
59
+ ...props
60
+ }: DrawerProps) => {
61
+ const [open, setOpen] = useControlled({
62
+ controlled: openProp,
63
+ default: defaultOpen ?? false,
64
+ name: "Drawer",
65
+ state: "open",
66
+ });
67
+
68
+ const classBase = "hwDrawer";
69
+
70
+ const className = cx(classBase, classNameProp, `${classBase}-${position}`, {
71
+ [`${classBase}-open`]: open,
72
+ [`${classBase}-inline`]: inline,
73
+ [`${classBase}-over`]: !inline,
74
+ [`${classBase}-peekaboo`]: peekaboo,
75
+ });
76
+
77
+ const toggleDrawer = useCallback(() => {
78
+ console.log("toggleDrawer");
79
+ setOpen(!open);
80
+ }, [open, setOpen]);
81
+
82
+ const style = getStyle(styleProp, sizeOpen, sizeClosed);
83
+
84
+ const handleClick = clickToOpen ? toggleDrawer : onClick;
85
+
86
+ const renderToggleButton = () => (
87
+ <div className={cx("hwToggleButton-container")}>
88
+ {open ? (
89
+ <Button
90
+ aria-label="close"
91
+ onClick={toggleDrawer}
92
+ data-icon="close"
93
+ variant="secondary"
94
+ />
95
+ ) : (
96
+ <Button
97
+ aria-label="open"
98
+ onClick={toggleDrawer}
99
+ data-icon="close"
100
+ variant="secondary"
101
+ />
102
+ )}
103
+ </div>
104
+ );
105
+
106
+ return (
107
+ <div {...props} className={className} onClick={handleClick} style={style}>
108
+ {toggleButton == "start" ? renderToggleButton() : null}
109
+ <div className={`${classBase}-liner`}>
110
+ <div className={`${classBase}-content`}>{children}</div>
111
+ </div>
112
+ {toggleButton == "end" ? renderToggleButton() : null}
113
+ </div>
114
+ );
115
+ };
116
+ Drawer.displayName = "Drawer";
117
+
118
+ export default Drawer;
@@ -0,0 +1,2 @@
1
+ export { default as Chest } from './Chest';
2
+ export { default as Drawer } from './Drawer';
@@ -0,0 +1,9 @@
1
+ export interface rect {
2
+ bottom: number;
3
+ left: number;
4
+ right: number;
5
+ top: number;
6
+ }
7
+ export type rectTuple = [number, number, number, number];
8
+
9
+ export type dimension = 'width' | 'height';
package/src/debug.ts ADDED
@@ -0,0 +1,16 @@
1
+ import { ReactElement } from 'react';
2
+ import { typeOf } from './utils';
3
+
4
+ export const tree = (el: ReactElement, depth = 0) => {
5
+ const type = typeOf(el);
6
+ const spaces = ' ';
7
+ let str = `\n${spaces.slice(0, depth)}${type}`;
8
+ if (type !== 'View') {
9
+ const els = el.props.children || [];
10
+ (Array.isArray(els) ? els : [els]).forEach((child) => {
11
+ str += tree(child, depth + 1);
12
+ });
13
+ }
14
+
15
+ return str;
16
+ };
@@ -0,0 +1,16 @@
1
+ .hwDialog {
2
+ --dialog-border: var(--hw-dialog-border, solid 1px #ccc);
3
+ --dialog-padding: var(--hw-dialog-padding, 0);
4
+ --dialog-shadow: var(--hw-dialog-shadow, none);
5
+ --vuuView-margin: 0;
6
+ --vuuView-flex-wrap: none;
7
+
8
+ border: var(--dialog-border);
9
+ margin: var(--hwDialog-margin, 200px auto 0 auto);
10
+ padding: var(--dialog-padding);
11
+ box-shadow: var(--dialog-shadow);
12
+ }
13
+
14
+ .hwDialog::backdrop {
15
+ background-color: var(--hw-dialog-backdrop);
16
+ }