@aglyn/besigner-ui 1.0.0-beta.231 → 1.0.0-beta.232
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.
- package/package.json +19 -18
- package/src/lib/components/aside-panel.component.js +30 -3
- package/src/lib/components/aside-panel.component.js.map +1 -1
- package/src/lib/components/besigner-dnd-context.component.js +31 -2
- package/src/lib/components/besigner-dnd-context.component.js.map +1 -1
- package/src/lib/components/component-accordion-list.js +4 -2
- package/src/lib/components/component-accordion-list.js.map +1 -1
- package/src/lib/components/component-picker.js +42 -2
- package/src/lib/components/component-picker.js.map +1 -1
- package/src/lib/components/device-preview-controls.component.d.ts +2 -0
- package/src/lib/components/device-preview-controls.component.js +11 -5
- package/src/lib/components/device-preview-controls.component.js.map +1 -1
- package/src/lib/components/dnd/draggable-droppable.js +39 -0
- package/src/lib/components/dnd/draggable-droppable.js.map +1 -1
- package/src/lib/components/node-quick-actions.js +210 -174
- package/src/lib/components/node-quick-actions.js.map +1 -1
- package/src/lib/components/node-tree-view.js +11 -1
- package/src/lib/components/node-tree-view.js.map +1 -1
- package/src/lib/components/panel-controls.component.d.ts +6 -0
- package/src/lib/components/panel-controls.component.js +10 -6
- package/src/lib/components/panel-controls.component.js.map +1 -1
- package/src/lib/components/viewport-canvas.component.js +8 -0
- package/src/lib/components/viewport-canvas.component.js.map +1 -1
- package/src/lib/components/workspace-editor.component.js +131 -16
- package/src/lib/components/workspace-editor.component.js.map +1 -1
- package/src/lib/components/workspace-panel.component.d.ts +18 -0
- package/src/lib/components/workspace-panel.component.js +53 -3
- package/src/lib/components/workspace-panel.component.js.map +1 -1
|
@@ -24,13 +24,14 @@ import { LOADING_OVERLAY_ELEMENT } from "@aglyn/shared-ui-jsx/const/prebuilt-com
|
|
|
24
24
|
import { generateComponentClassKeys, styled } from "@aglyn/shared-ui-theme";
|
|
25
25
|
import { _isFnT } from "@aglyn/shared-util-tools";
|
|
26
26
|
import { useDndMonitor } from "@dnd-kit/core";
|
|
27
|
-
import {
|
|
27
|
+
import { getEventCoordinates } from "@dnd-kit/utilities";
|
|
28
|
+
import { Stack, useMediaQuery, useTheme } from "@mui/material";
|
|
28
29
|
import clsx from "clsx";
|
|
29
30
|
import dynamic from "next/dynamic";
|
|
30
|
-
import { forwardRef, useCallback, useRef } from "react";
|
|
31
|
-
import { useMouse } from "react-use";
|
|
31
|
+
import { forwardRef, useCallback, useEffect, useRef, useState } from "react";
|
|
32
32
|
import useAglynBesignerPanelValue from "../hooks/use-aglyn-besigner-panel-value.js";
|
|
33
33
|
import AppBarBreadcrumbsComponent from "./app-bar-breadcrumbs.component.js";
|
|
34
|
+
import { WorkspacePanelDragContext } from "./workspace-panel.component.js";
|
|
34
35
|
import ViewportZoomControls from "./viewport-zoom-controls.js";
|
|
35
36
|
const classKeys = generateComponentClassKeys('AglynViewport', [
|
|
36
37
|
'panelLeftOpen',
|
|
@@ -41,6 +42,47 @@ const PanelLeftComponent = dynamic(()=>import("./aside-panel.component.js").then
|
|
|
41
42
|
ssr: false,
|
|
42
43
|
loading: ()=>LOADING_OVERLAY_ELEMENT
|
|
43
44
|
});
|
|
45
|
+
/**
|
|
46
|
+
* The last viewport-relative position of whatever is pointing — mouse, pen or
|
|
47
|
+
* finger. Kept in a ref rather than state: it is read once per drag move, and
|
|
48
|
+
* re-rendering the whole workspace on every pointer move bought nothing.
|
|
49
|
+
*
|
|
50
|
+
* Touch needs `touchmove` as well as `pointermove`: once a touch drag is
|
|
51
|
+
* active the sensor cancels the touch's default action, and some browsers
|
|
52
|
+
* stop reporting that finger as a pointer from then on.
|
|
53
|
+
*/ function useLastClientPoint() {
|
|
54
|
+
const point = useRef(null);
|
|
55
|
+
useEffect(()=>{
|
|
56
|
+
const onPointer = (e)=>{
|
|
57
|
+
point.current = {
|
|
58
|
+
x: e.clientX,
|
|
59
|
+
y: e.clientY
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
const onTouch = (e)=>{
|
|
63
|
+
const touch = e.touches[0];
|
|
64
|
+
if (touch) point.current = {
|
|
65
|
+
x: touch.clientX,
|
|
66
|
+
y: touch.clientY
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
const options = {
|
|
70
|
+
capture: true,
|
|
71
|
+
passive: true
|
|
72
|
+
};
|
|
73
|
+
document.addEventListener('pointerdown', onPointer, options);
|
|
74
|
+
document.addEventListener('pointermove', onPointer, options);
|
|
75
|
+
document.addEventListener('touchstart', onTouch, options);
|
|
76
|
+
document.addEventListener('touchmove', onTouch, options);
|
|
77
|
+
return ()=>{
|
|
78
|
+
document.removeEventListener('pointerdown', onPointer, options);
|
|
79
|
+
document.removeEventListener('pointermove', onPointer, options);
|
|
80
|
+
document.removeEventListener('touchstart', onTouch, options);
|
|
81
|
+
document.removeEventListener('touchmove', onTouch, options);
|
|
82
|
+
};
|
|
83
|
+
}, []);
|
|
84
|
+
return point;
|
|
85
|
+
}
|
|
44
86
|
const WorkspaceEditor = styled('div', {
|
|
45
87
|
name: 'AglynWorkspaceEditor'
|
|
46
88
|
})({
|
|
@@ -66,14 +108,63 @@ const WorkspaceEditorComponent = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
66
108
|
"children",
|
|
67
109
|
"className"
|
|
68
110
|
]);
|
|
69
|
-
const [leftToggled] = useAglynBesignerPanelValue('panelLeft', 'toggled');
|
|
70
|
-
const [rightToggled] = useAglynBesignerPanelValue('panelRight', 'toggled');
|
|
111
|
+
const [leftToggled, setLeftToggled] = useAglynBesignerPanelValue('panelLeft', 'toggled');
|
|
112
|
+
const [rightToggled, setRightToggled] = useAglynBesignerPanelValue('panelRight', 'toggled');
|
|
71
113
|
const [bottomToggled] = useAglynBesignerPanelValue('panelBottom', 'toggled');
|
|
72
114
|
const elemClassName = clsx({
|
|
73
115
|
[classKeys.panelLeftOpen]: Boolean(leftToggled),
|
|
74
116
|
[classKeys.panelRightOpen]: Boolean(rightToggled),
|
|
75
117
|
[classKeys.panelBottomOpen]: Boolean(bottomToggled)
|
|
76
118
|
}, className);
|
|
119
|
+
// Below `md` the panels overlay the canvas (see AsidePanelComponent), so
|
|
120
|
+
// the open-by-default a docked panel gets would greet a phone with a
|
|
121
|
+
// covered canvas. They start closed there, and the toolbar opens them.
|
|
122
|
+
// Only the live panel state changes — the defaults a wide screen starts
|
|
123
|
+
// from are untouched.
|
|
124
|
+
const theme = useTheme();
|
|
125
|
+
const compact = useMediaQuery(theme.breakpoints.down('md'), {
|
|
126
|
+
noSsr: true
|
|
127
|
+
});
|
|
128
|
+
const closedForCompact = useRef(false);
|
|
129
|
+
useEffect(()=>{
|
|
130
|
+
if (!compact) {
|
|
131
|
+
closedForCompact.current = false;
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (closedForCompact.current) return;
|
|
135
|
+
closedForCompact.current = true;
|
|
136
|
+
setLeftToggled(false);
|
|
137
|
+
setRightToggled(false);
|
|
138
|
+
// The setters are rebuilt every render; the guard is what matters.
|
|
139
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
140
|
+
}, [
|
|
141
|
+
compact
|
|
142
|
+
]);
|
|
143
|
+
// Two overlays at once is one hidden behind the other, so below `md`
|
|
144
|
+
// opening a panel closes the one that was already open.
|
|
145
|
+
const lastToggled = useRef({
|
|
146
|
+
left: leftToggled,
|
|
147
|
+
right: rightToggled
|
|
148
|
+
});
|
|
149
|
+
useEffect(()=>{
|
|
150
|
+
const last = lastToggled.current;
|
|
151
|
+
lastToggled.current = {
|
|
152
|
+
left: leftToggled,
|
|
153
|
+
right: rightToggled
|
|
154
|
+
};
|
|
155
|
+
if (!compact || !leftToggled || !rightToggled) return;
|
|
156
|
+
if (last.left) setLeftToggled(false);
|
|
157
|
+
else setRightToggled(false);
|
|
158
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
159
|
+
}, [
|
|
160
|
+
compact,
|
|
161
|
+
leftToggled,
|
|
162
|
+
rightToggled
|
|
163
|
+
]);
|
|
164
|
+
// Only a palette drag hides the overlay panels: it starts in a drawer
|
|
165
|
+
// and ends on the canvas that drawer covers. A hierarchy row is dropped
|
|
166
|
+
// within the hierarchy, so that drawer stays in view and stays open.
|
|
167
|
+
const [dragging, setDragging] = useState(false);
|
|
77
168
|
const pannerRef = useRef(null);
|
|
78
169
|
const handleZoomReset = useCallback((e)=>{
|
|
79
170
|
var _pannerRef_current;
|
|
@@ -94,20 +185,21 @@ const WorkspaceEditorComponent = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
94
185
|
}
|
|
95
186
|
}, []);
|
|
96
187
|
const localRef = useRef(null);
|
|
97
|
-
const
|
|
188
|
+
const pointer = useLastClientPoint();
|
|
98
189
|
// Null-safe: surfaces render without a snackbar provider in tests.
|
|
99
190
|
const { enqueueSnackbar } = (_useSnackbar = useSnackbar()) != null ? _useSnackbar : {};
|
|
100
191
|
useDndMonitor({
|
|
101
192
|
onDragMove (event) {
|
|
102
193
|
var _event_over;
|
|
103
194
|
let region = null;
|
|
104
|
-
|
|
195
|
+
// A keyboard drag has no pointer of its own; it keeps reading the
|
|
196
|
+
// last place the pointer was, as it always has.
|
|
197
|
+
const at = pointer.current;
|
|
198
|
+
if (event.over && at) {
|
|
105
199
|
var _event_over_data_current;
|
|
106
|
-
// dnd-kit rects
|
|
107
|
-
// document-relative — subtract the page scroll so region hit
|
|
108
|
-
// tests keep working when the page is scrolled.
|
|
200
|
+
// Both viewport-relative: dnd-kit rects and client coordinates.
|
|
109
201
|
const overNode = (_event_over_data_current = event.over.data.current) == null ? void 0 : _event_over_data_current.node;
|
|
110
|
-
region = Besigner.determineDropRegion(event.over.rect,
|
|
202
|
+
region = Besigner.determineDropRegion(event.over.rect, at.x, at.y, // Leaves (self-closing / text-editable) never offer a CHILDREN
|
|
111
203
|
// region — the center reads as a sibling insert, matching where
|
|
112
204
|
// the drop actually lands (see dnd-manager onDragEnd).
|
|
113
205
|
overNode ? canvas.nodeAcceptsChildren(overNode) : true);
|
|
@@ -117,12 +209,29 @@ const WorkspaceEditorComponent = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
117
209
|
Besigner.dnd.setDropNode((_event_over = event.over) == null ? void 0 : _event_over.data.current.node);
|
|
118
210
|
event.activatorEvent.stopPropagation();
|
|
119
211
|
},
|
|
120
|
-
onDragStart ({ active }) {
|
|
212
|
+
onDragStart ({ active, activatorEvent }) {
|
|
213
|
+
var _active_data_current;
|
|
214
|
+
// The gesture that started the drag is the freshest position there
|
|
215
|
+
// is — a touch hold may not have moved since it went down.
|
|
216
|
+
const start = getEventCoordinates(activatorEvent);
|
|
217
|
+
if (start) pointer.current = start;
|
|
121
218
|
const node = active == null ? void 0 : active.data.current.node;
|
|
122
219
|
Besigner.dnd.setDragNode(node);
|
|
220
|
+
setDragging((active == null ? void 0 : (_active_data_current = active.data.current) == null ? void 0 : _active_data_current.type) === Besigner.DragType.PRESET);
|
|
221
|
+
},
|
|
222
|
+
onDragCancel () {
|
|
223
|
+
setDragging(false);
|
|
123
224
|
},
|
|
124
225
|
onDragEnd (e) {
|
|
226
|
+
var _e_active_data_current;
|
|
125
227
|
e.activatorEvent.stopPropagation();
|
|
228
|
+
setDragging(false);
|
|
229
|
+
// Below `md` the palette's drawer overlays the canvas; after a drop
|
|
230
|
+
// from it the canvas is what the author wants to see.
|
|
231
|
+
if (compact && e.over && ((_e_active_data_current = e.active.data.current) == null ? void 0 : _e_active_data_current.type) === Besigner.DragType.PRESET) {
|
|
232
|
+
setLeftToggled(false);
|
|
233
|
+
setRightToggled(false);
|
|
234
|
+
}
|
|
126
235
|
// Compute before completing the drag — onDragEnd clears dnd state.
|
|
127
236
|
const rejection = Besigner.dnd.describeDropRejection();
|
|
128
237
|
Besigner.dnd.onDragEnd();
|
|
@@ -152,8 +261,11 @@ const WorkspaceEditorComponent = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
152
261
|
zIndex: 0
|
|
153
262
|
},
|
|
154
263
|
children: [
|
|
155
|
-
/*#__PURE__*/ _jsx(
|
|
156
|
-
|
|
264
|
+
/*#__PURE__*/ _jsx(WorkspacePanelDragContext.Provider, {
|
|
265
|
+
value: dragging,
|
|
266
|
+
children: /*#__PURE__*/ _jsx(PanelLeftComponent, {
|
|
267
|
+
panel: 'panelLeft'
|
|
268
|
+
})
|
|
157
269
|
}),
|
|
158
270
|
/*#__PURE__*/ _jsxs(Stack, {
|
|
159
271
|
direction: "column",
|
|
@@ -177,8 +289,11 @@ const WorkspaceEditorComponent = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
177
289
|
/*#__PURE__*/ _jsx(AppBarBreadcrumbsComponent, {})
|
|
178
290
|
]
|
|
179
291
|
}),
|
|
180
|
-
/*#__PURE__*/ _jsx(
|
|
181
|
-
|
|
292
|
+
/*#__PURE__*/ _jsx(WorkspacePanelDragContext.Provider, {
|
|
293
|
+
value: dragging,
|
|
294
|
+
children: /*#__PURE__*/ _jsx(PanelLeftComponent, {
|
|
295
|
+
panel: 'panelRight'
|
|
296
|
+
})
|
|
182
297
|
})
|
|
183
298
|
]
|
|
184
299
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../../libs/besigner/feature/designer/src/lib/components/workspace-editor.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { canvas } from '@aglyn/aglyn'\nimport * as Besigner from '@aglyn/besigner'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport { useMergeRefs } from '@aglyn/shared-ui-jsx'\nimport { LOADING_OVERLAY_ELEMENT } from '@aglyn/shared-ui-jsx/const/prebuilt-components'\nimport { generateComponentClassKeys, styled } from '@aglyn/shared-ui-theme'\nimport { _isFnT } from '@aglyn/shared-util-tools'\nimport {\n DragEndEvent,\n DragMoveEvent,\n DragStartEvent,\n useDndMonitor,\n} from '@dnd-kit/core'\nimport { Stack } from '@mui/material'\nimport clsx from 'clsx'\nimport dynamic from 'next/dynamic'\nimport type { ComponentProps } from 'react'\nimport { ChangeEvent, forwardRef, useCallback, useRef } from 'react'\nimport { useMouse } from 'react-use'\nimport useAglynBesignerPanelValue from '../hooks/use-aglyn-besigner-panel-value'\nimport AppBarBreadcrumbsComponent from './app-bar-breadcrumbs.component'\nimport type { AsidePanelComponentProps } from './aside-panel.component'\nimport ViewportZoomControls from './viewport-zoom-controls'\n\nconst classKeys = generateComponentClassKeys('AglynViewport', [\n 'panelLeftOpen',\n 'panelBottomOpen',\n 'panelRightOpen',\n])\nconst PanelLeftComponent = dynamic<AsidePanelComponentProps>(\n () =>\n import('./aside-panel.component').then((mod) => mod.AsidePanelComponent),\n { ssr: false, loading: () => LOADING_OVERLAY_ELEMENT },\n)\n\nconst WorkspaceEditor = styled('div', {\n name: 'AglynWorkspaceEditor',\n})({\n // position: 'absolute',\n left: 0,\n right: 0,\n top: 0,\n bottom: 0,\n height: '100%',\n width: '100%',\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column',\n alignContent: 'stretch',\n alignItems: 'stretch',\n [`&.${classKeys.panelLeftOpen}`]: {},\n [`&.${classKeys.panelBottomOpen}`]: {},\n [`&.${classKeys.panelRightOpen}`]: {},\n})\n\nexport interface WorkspaceEditorComponentProps\n extends ComponentProps<typeof WorkspaceEditor> {}\n\nconst WorkspaceEditorComponent = forwardRef<any, WorkspaceEditorComponentProps>(\n (props, ref) => {\n const { children, className, ...rest } = props\n\n const [leftToggled] = useAglynBesignerPanelValue('panelLeft', 'toggled')\n const [rightToggled] = useAglynBesignerPanelValue('panelRight', 'toggled')\n const [bottomToggled] = useAglynBesignerPanelValue('panelBottom', 'toggled')\n\n const elemClassName = clsx(\n {\n [classKeys.panelLeftOpen]: Boolean(leftToggled),\n [classKeys.panelRightOpen]: Boolean(rightToggled),\n [classKeys.panelBottomOpen]: Boolean(bottomToggled),\n },\n className,\n )\n\n const pannerRef = useRef<any>(null)\n\n const handleZoomReset = useCallback((e: ChangeEvent<unknown>) => {\n if (_isFnT(pannerRef.current?.reset)) {\n pannerRef.current.reset()\n }\n }, [])\n\n const handleZoomDecrease = useCallback((e: ChangeEvent<unknown>) => {\n if (_isFnT(pannerRef.current?.zoomOut)) {\n pannerRef.current.zoomOut()\n }\n }, [])\n\n const handleZoomIncrease = useCallback((e: ChangeEvent<unknown>) => {\n if (_isFnT(pannerRef.current?.zoomIn)) {\n pannerRef.current.zoomIn()\n }\n }, [])\n\n const localRef = useRef(null)\n const mouse = useMouse(localRef)\n // Null-safe: surfaces render without a snackbar provider in tests.\n const { enqueueSnackbar } = useSnackbar() ?? {}\n\n useDndMonitor({\n onDragMove(event: DragMoveEvent): void {\n let region: Besigner.DropRegion = null\n if (event.over) {\n // dnd-kit rects are viewport-relative; useMouse coords are\n // document-relative — subtract the page scroll so region hit\n // tests keep working when the page is scrolled.\n const overNode = event.over.data.current?.node\n region = Besigner.determineDropRegion(\n event.over.rect,\n mouse.docX - window.scrollX,\n mouse.docY - window.scrollY,\n // Leaves (self-closing / text-editable) never offer a CHILDREN\n // region — the center reads as a sibling insert, matching where\n // the drop actually lands (see dnd-manager onDragEnd).\n overNode ? canvas.nodeAcceptsChildren(overNode) : true,\n )\n event.over.data.current.region = region\n }\n Besigner.dnd.setDropRegion(region)\n Besigner.dnd.setDropNode(event.over?.data.current.node)\n\n event.activatorEvent.stopPropagation()\n },\n onDragStart({ active }: DragStartEvent) {\n const node = active?.data.current.node\n Besigner.dnd.setDragNode(node)\n },\n onDragEnd(e: DragEndEvent) {\n e.activatorEvent.stopPropagation()\n // Compute before completing the drag — onDragEnd clears dnd state.\n const rejection = Besigner.dnd.describeDropRejection()\n Besigner.dnd.onDragEnd()\n if (rejection) {\n enqueueSnackbar?.(rejection, { variant: 'warning', persist: false })\n }\n },\n })\n\n return (\n <WorkspaceEditor\n ref={useMergeRefs(ref, localRef)}\n id=\"aglyn:besigner-workspace\"\n className={elemClassName}\n {...rest}\n >\n <Stack\n direction=\"row\"\n id=\"aglyn:besigner-main\"\n component=\"main\"\n spacing={0}\n sx={{\n alignItems: \"stretch\",\n justifyContent: \"space-between\",\n flexGrow: 1,\n overflow: 'hidden',\n zIndex: 0\n }}>\n <PanelLeftComponent panel={'panelLeft'} />\n <Stack\n direction=\"column\"\n id=\"aglyn:besigner-viewport\"\n component=\"main\"\n spacing={0}\n sx={{\n alignItems: \"stretch\",\n justifyContent: \"space-between\",\n flexGrow: 1,\n overflow: 'hidden',\n zIndex: 0\n }}>\n {children}\n <ViewportZoomControls\n onZoomReset={handleZoomReset}\n onZoomDecrease={handleZoomDecrease}\n onZoomIncrease={handleZoomIncrease}\n />\n <AppBarBreadcrumbsComponent />\n </Stack>\n <PanelLeftComponent panel={'panelRight'} />\n </Stack>\n </WorkspaceEditor>\n );\n },\n)\n\nWorkspaceEditorComponent.displayName = 'WorkspaceEditorComponent'\n\nexport { WorkspaceEditorComponent }\nexport default WorkspaceEditorComponent\n"],"names":["canvas","Besigner","useSnackbar","useMergeRefs","LOADING_OVERLAY_ELEMENT","generateComponentClassKeys","styled","_isFnT","useDndMonitor","Stack","clsx","dynamic","forwardRef","useCallback","useRef","useMouse","useAglynBesignerPanelValue","AppBarBreadcrumbsComponent","ViewportZoomControls","classKeys","PanelLeftComponent","then","mod","AsidePanelComponent","ssr","loading","WorkspaceEditor","name","left","right","top","bottom","height","width","overflow","display","flexDirection","alignContent","alignItems","panelLeftOpen","panelBottomOpen","panelRightOpen","WorkspaceEditorComponent","props","ref","children","className","rest","leftToggled","rightToggled","bottomToggled","elemClassName","Boolean","pannerRef","handleZoomReset","e","current","reset","handleZoomDecrease","zoomOut","handleZoomIncrease","zoomIn","localRef","mouse","enqueueSnackbar","onDragMove","event","region","over","overNode","data","node","determineDropRegion","rect","docX","window","scrollX","docY","scrollY","nodeAcceptsChildren","dnd","setDropRegion","setDropNode","activatorEvent","stopPropagation","onDragStart","active","setDragNode","onDragEnd","rejection","describeDropRejection","variant","persist","id","direction","component","spacing","sx","justifyContent","flexGrow","zIndex","panel","onZoomReset","onZoomDecrease","onZoomIncrease","displayName"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/besigner/feature/designer/src/lib/components/workspace-editor.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { canvas } from '@aglyn/aglyn'\nimport * as Besigner from '@aglyn/besigner'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport { useMergeRefs } from '@aglyn/shared-ui-jsx'\nimport { LOADING_OVERLAY_ELEMENT } from '@aglyn/shared-ui-jsx/const/prebuilt-components'\nimport { generateComponentClassKeys, styled } from '@aglyn/shared-ui-theme'\nimport { _isFnT } from '@aglyn/shared-util-tools'\nimport {\n DragEndEvent,\n DragMoveEvent,\n DragStartEvent,\n useDndMonitor,\n} from '@dnd-kit/core'\nimport { getEventCoordinates } from '@dnd-kit/utilities'\nimport { Stack, useMediaQuery, useTheme } from '@mui/material'\nimport clsx from 'clsx'\nimport dynamic from 'next/dynamic'\nimport type { ComponentProps } from 'react'\nimport {\n ChangeEvent,\n forwardRef,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react'\nimport useAglynBesignerPanelValue from '../hooks/use-aglyn-besigner-panel-value'\nimport AppBarBreadcrumbsComponent from './app-bar-breadcrumbs.component'\nimport type { AsidePanelComponentProps } from './aside-panel.component'\nimport { WorkspacePanelDragContext } from './workspace-panel.component'\nimport ViewportZoomControls from './viewport-zoom-controls'\n\nconst classKeys = generateComponentClassKeys('AglynViewport', [\n 'panelLeftOpen',\n 'panelBottomOpen',\n 'panelRightOpen',\n])\nconst PanelLeftComponent = dynamic<AsidePanelComponentProps>(\n () =>\n import('./aside-panel.component').then((mod) => mod.AsidePanelComponent),\n { ssr: false, loading: () => LOADING_OVERLAY_ELEMENT },\n)\n\ntype ClientPoint = { x: number; y: number }\n\n/**\n * The last viewport-relative position of whatever is pointing — mouse, pen or\n * finger. Kept in a ref rather than state: it is read once per drag move, and\n * re-rendering the whole workspace on every pointer move bought nothing.\n *\n * Touch needs `touchmove` as well as `pointermove`: once a touch drag is\n * active the sensor cancels the touch's default action, and some browsers\n * stop reporting that finger as a pointer from then on.\n */\nfunction useLastClientPoint() {\n const point = useRef<ClientPoint | null>(null)\n useEffect(() => {\n const onPointer = (e: PointerEvent) => {\n point.current = { x: e.clientX, y: e.clientY }\n }\n const onTouch = (e: TouchEvent) => {\n const touch = e.touches[0]\n if (touch) point.current = { x: touch.clientX, y: touch.clientY }\n }\n const options = { capture: true, passive: true }\n document.addEventListener('pointerdown', onPointer, options)\n document.addEventListener('pointermove', onPointer, options)\n document.addEventListener('touchstart', onTouch, options)\n document.addEventListener('touchmove', onTouch, options)\n return () => {\n document.removeEventListener('pointerdown', onPointer, options)\n document.removeEventListener('pointermove', onPointer, options)\n document.removeEventListener('touchstart', onTouch, options)\n document.removeEventListener('touchmove', onTouch, options)\n }\n }, [])\n return point\n}\n\nconst WorkspaceEditor = styled('div', {\n name: 'AglynWorkspaceEditor',\n})({\n // position: 'absolute',\n left: 0,\n right: 0,\n top: 0,\n bottom: 0,\n height: '100%',\n width: '100%',\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column',\n alignContent: 'stretch',\n alignItems: 'stretch',\n [`&.${classKeys.panelLeftOpen}`]: {},\n [`&.${classKeys.panelBottomOpen}`]: {},\n [`&.${classKeys.panelRightOpen}`]: {},\n})\n\nexport interface WorkspaceEditorComponentProps\n extends ComponentProps<typeof WorkspaceEditor> {}\n\nconst WorkspaceEditorComponent = forwardRef<any, WorkspaceEditorComponentProps>(\n (props, ref) => {\n const { children, className, ...rest } = props\n\n const [leftToggled, setLeftToggled] = useAglynBesignerPanelValue(\n 'panelLeft',\n 'toggled',\n )\n const [rightToggled, setRightToggled] = useAglynBesignerPanelValue(\n 'panelRight',\n 'toggled',\n )\n const [bottomToggled] = useAglynBesignerPanelValue('panelBottom', 'toggled')\n\n const elemClassName = clsx(\n {\n [classKeys.panelLeftOpen]: Boolean(leftToggled),\n [classKeys.panelRightOpen]: Boolean(rightToggled),\n [classKeys.panelBottomOpen]: Boolean(bottomToggled),\n },\n className,\n )\n\n // Below `md` the panels overlay the canvas (see AsidePanelComponent), so\n // the open-by-default a docked panel gets would greet a phone with a\n // covered canvas. They start closed there, and the toolbar opens them.\n // Only the live panel state changes — the defaults a wide screen starts\n // from are untouched.\n const theme = useTheme()\n const compact = useMediaQuery(theme.breakpoints.down('md'), {\n noSsr: true,\n })\n const closedForCompact = useRef(false)\n useEffect(() => {\n if (!compact) {\n closedForCompact.current = false\n return\n }\n if (closedForCompact.current) return\n closedForCompact.current = true\n setLeftToggled(false)\n setRightToggled(false)\n // The setters are rebuilt every render; the guard is what matters.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [compact])\n\n // Two overlays at once is one hidden behind the other, so below `md`\n // opening a panel closes the one that was already open.\n const lastToggled = useRef({ left: leftToggled, right: rightToggled })\n useEffect(() => {\n const last = lastToggled.current\n lastToggled.current = { left: leftToggled, right: rightToggled }\n if (!compact || !leftToggled || !rightToggled) return\n if (last.left) setLeftToggled(false)\n else setRightToggled(false)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [compact, leftToggled, rightToggled])\n\n // Only a palette drag hides the overlay panels: it starts in a drawer\n // and ends on the canvas that drawer covers. A hierarchy row is dropped\n // within the hierarchy, so that drawer stays in view and stays open.\n const [dragging, setDragging] = useState(false)\n\n const pannerRef = useRef<any>(null)\n\n const handleZoomReset = useCallback((e: ChangeEvent<unknown>) => {\n if (_isFnT(pannerRef.current?.reset)) {\n pannerRef.current.reset()\n }\n }, [])\n\n const handleZoomDecrease = useCallback((e: ChangeEvent<unknown>) => {\n if (_isFnT(pannerRef.current?.zoomOut)) {\n pannerRef.current.zoomOut()\n }\n }, [])\n\n const handleZoomIncrease = useCallback((e: ChangeEvent<unknown>) => {\n if (_isFnT(pannerRef.current?.zoomIn)) {\n pannerRef.current.zoomIn()\n }\n }, [])\n\n const localRef = useRef(null)\n const pointer = useLastClientPoint()\n // Null-safe: surfaces render without a snackbar provider in tests.\n const { enqueueSnackbar } = useSnackbar() ?? {}\n\n useDndMonitor({\n onDragMove(event: DragMoveEvent): void {\n let region: Besigner.DropRegion = null\n // A keyboard drag has no pointer of its own; it keeps reading the\n // last place the pointer was, as it always has.\n const at = pointer.current\n if (event.over && at) {\n // Both viewport-relative: dnd-kit rects and client coordinates.\n const overNode = event.over.data.current?.node\n region = Besigner.determineDropRegion(\n event.over.rect,\n at.x,\n at.y,\n // Leaves (self-closing / text-editable) never offer a CHILDREN\n // region — the center reads as a sibling insert, matching where\n // the drop actually lands (see dnd-manager onDragEnd).\n overNode ? canvas.nodeAcceptsChildren(overNode) : true,\n )\n event.over.data.current.region = region\n }\n Besigner.dnd.setDropRegion(region)\n Besigner.dnd.setDropNode(event.over?.data.current.node)\n\n event.activatorEvent.stopPropagation()\n },\n onDragStart({ active, activatorEvent }: DragStartEvent) {\n // The gesture that started the drag is the freshest position there\n // is — a touch hold may not have moved since it went down.\n const start = getEventCoordinates(activatorEvent)\n if (start) pointer.current = start\n const node = active?.data.current.node\n Besigner.dnd.setDragNode(node)\n setDragging(active?.data.current?.type === Besigner.DragType.PRESET)\n },\n onDragCancel() {\n setDragging(false)\n },\n onDragEnd(e: DragEndEvent) {\n e.activatorEvent.stopPropagation()\n setDragging(false)\n // Below `md` the palette's drawer overlays the canvas; after a drop\n // from it the canvas is what the author wants to see.\n if (\n compact &&\n e.over &&\n e.active.data.current?.type === Besigner.DragType.PRESET\n ) {\n setLeftToggled(false)\n setRightToggled(false)\n }\n // Compute before completing the drag — onDragEnd clears dnd state.\n const rejection = Besigner.dnd.describeDropRejection()\n Besigner.dnd.onDragEnd()\n if (rejection) {\n enqueueSnackbar?.(rejection, { variant: 'warning', persist: false })\n }\n },\n })\n\n return (\n <WorkspaceEditor\n ref={useMergeRefs(ref, localRef)}\n id=\"aglyn:besigner-workspace\"\n className={elemClassName}\n {...rest}\n >\n <Stack\n direction=\"row\"\n id=\"aglyn:besigner-main\"\n component=\"main\"\n spacing={0}\n sx={{\n alignItems: \"stretch\",\n justifyContent: \"space-between\",\n flexGrow: 1,\n overflow: 'hidden',\n zIndex: 0\n }}>\n <WorkspacePanelDragContext.Provider value={dragging}>\n <PanelLeftComponent panel={'panelLeft'} />\n </WorkspacePanelDragContext.Provider>\n <Stack\n direction=\"column\"\n id=\"aglyn:besigner-viewport\"\n component=\"main\"\n spacing={0}\n sx={{\n alignItems: \"stretch\",\n justifyContent: \"space-between\",\n flexGrow: 1,\n overflow: 'hidden',\n zIndex: 0\n }}>\n {children}\n <ViewportZoomControls\n onZoomReset={handleZoomReset}\n onZoomDecrease={handleZoomDecrease}\n onZoomIncrease={handleZoomIncrease}\n />\n <AppBarBreadcrumbsComponent />\n </Stack>\n <WorkspacePanelDragContext.Provider value={dragging}>\n <PanelLeftComponent panel={'panelRight'} />\n </WorkspacePanelDragContext.Provider>\n </Stack>\n </WorkspaceEditor>\n );\n },\n)\n\nWorkspaceEditorComponent.displayName = 'WorkspaceEditorComponent'\n\nexport { WorkspaceEditorComponent }\nexport default WorkspaceEditorComponent\n"],"names":["canvas","Besigner","useSnackbar","useMergeRefs","LOADING_OVERLAY_ELEMENT","generateComponentClassKeys","styled","_isFnT","useDndMonitor","getEventCoordinates","Stack","useMediaQuery","useTheme","clsx","dynamic","forwardRef","useCallback","useEffect","useRef","useState","useAglynBesignerPanelValue","AppBarBreadcrumbsComponent","WorkspacePanelDragContext","ViewportZoomControls","classKeys","PanelLeftComponent","then","mod","AsidePanelComponent","ssr","loading","useLastClientPoint","point","onPointer","e","current","x","clientX","y","clientY","onTouch","touch","touches","options","capture","passive","document","addEventListener","removeEventListener","WorkspaceEditor","name","left","right","top","bottom","height","width","overflow","display","flexDirection","alignContent","alignItems","panelLeftOpen","panelBottomOpen","panelRightOpen","WorkspaceEditorComponent","props","ref","children","className","rest","leftToggled","setLeftToggled","rightToggled","setRightToggled","bottomToggled","elemClassName","Boolean","theme","compact","breakpoints","down","noSsr","closedForCompact","lastToggled","last","dragging","setDragging","pannerRef","handleZoomReset","reset","handleZoomDecrease","zoomOut","handleZoomIncrease","zoomIn","localRef","pointer","enqueueSnackbar","onDragMove","event","region","at","over","overNode","data","node","determineDropRegion","rect","nodeAcceptsChildren","dnd","setDropRegion","setDropNode","activatorEvent","stopPropagation","onDragStart","active","start","setDragNode","type","DragType","PRESET","onDragCancel","onDragEnd","rejection","describeDropRejection","variant","persist","id","direction","component","spacing","sx","justifyContent","flexGrow","zIndex","Provider","value","panel","onZoomReset","onZoomDecrease","onZoomIncrease","displayName"],"mappings":";;;AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,MAAM,QAAQ,eAAc;AACrC,YAAYC,cAAc,kBAAiB;AAC3C,SAASC,WAAW,QAAQ,8BAA6B;AACzD,SAASC,YAAY,QAAQ,uBAAsB;AACnD,SAASC,uBAAuB,QAAQ,iDAAgD;AACxF,SAASC,0BAA0B,EAAEC,MAAM,QAAQ,yBAAwB;AAC3E,SAASC,MAAM,QAAQ,2BAA0B;AACjD,SAIEC,aAAa,QACR,gBAAe;AACtB,SAASC,mBAAmB,QAAQ,qBAAoB;AACxD,SAASC,KAAK,EAAEC,aAAa,EAAEC,QAAQ,QAAQ,gBAAe;AAC9D,OAAOC,UAAU,OAAM;AACvB,OAAOC,aAAa,eAAc;AAElC,SAEEC,UAAU,EACVC,WAAW,EACXC,SAAS,EACTC,MAAM,EACNC,QAAQ,QACH,QAAO;AACd,OAAOC,gCAAgC,6CAAyC;AAChF,OAAOC,gCAAgC,qCAAiC;AAExE,SAASC,yBAAyB,QAAQ,iCAA6B;AACvE,OAAOC,0BAA0B,8BAA0B;AAE3D,MAAMC,YAAYnB,2BAA2B,iBAAiB;IAC5D;IACA;IACA;CACD;AACD,MAAMoB,qBAAqBX,QACzB,IACE,MAAM,CAAC,8BAA2BY,IAAI,CAAC,CAACC,MAAQA,IAAIC,mBAAmB,GACzE;IAAEC,KAAK;IAAOC,SAAS,IAAM1B;AAAwB;AAKvD;;;;;;;;CAQC,GACD,SAAS2B;IACP,MAAMC,QAAQd,OAA2B;IACzCD,UAAU;QACR,MAAMgB,YAAY,CAACC;YACjBF,MAAMG,OAAO,GAAG;gBAAEC,GAAGF,EAAEG,OAAO;gBAAEC,GAAGJ,EAAEK,OAAO;YAAC;QAC/C;QACA,MAAMC,UAAU,CAACN;YACf,MAAMO,QAAQP,EAAEQ,OAAO,CAAC,EAAE;YAC1B,IAAID,OAAOT,MAAMG,OAAO,GAAG;gBAAEC,GAAGK,MAAMJ,OAAO;gBAAEC,GAAGG,MAAMF,OAAO;YAAC;QAClE;QACA,MAAMI,UAAU;YAAEC,SAAS;YAAMC,SAAS;QAAK;QAC/CC,SAASC,gBAAgB,CAAC,eAAed,WAAWU;QACpDG,SAASC,gBAAgB,CAAC,eAAed,WAAWU;QACpDG,SAASC,gBAAgB,CAAC,cAAcP,SAASG;QACjDG,SAASC,gBAAgB,CAAC,aAAaP,SAASG;QAChD,OAAO;YACLG,SAASE,mBAAmB,CAAC,eAAef,WAAWU;YACvDG,SAASE,mBAAmB,CAAC,eAAef,WAAWU;YACvDG,SAASE,mBAAmB,CAAC,cAAcR,SAASG;YACpDG,SAASE,mBAAmB,CAAC,aAAaR,SAASG;QACrD;IACF,GAAG,EAAE;IACL,OAAOX;AACT;AAEA,MAAMiB,kBAAkB3C,OAAO,OAAO;IACpC4C,MAAM;AACR,GAAG;IACD,wBAAwB;IACxBC,MAAM;IACNC,OAAO;IACPC,KAAK;IACLC,QAAQ;IACRC,QAAQ;IACRC,OAAO;IACPC,UAAU;IACVC,SAAS;IACTC,eAAe;IACfC,cAAc;IACdC,YAAY;IACZ,CAAC,CAAC,EAAE,EAAErC,UAAUsC,aAAa,EAAE,CAAC,EAAE,CAAC;IACnC,CAAC,CAAC,EAAE,EAAEtC,UAAUuC,eAAe,EAAE,CAAC,EAAE,CAAC;IACrC,CAAC,CAAC,EAAE,EAAEvC,UAAUwC,cAAc,EAAE,CAAC,EAAE,CAAC;AACtC;AAKA,MAAMC,yCAA2BlD,WAC/B,CAACmD,OAAOC;QAqFsBjE;IApF5B,MAAM,EAAEkE,QAAQ,EAAEC,SAAS,EAAW,GAAGH,OAATI,wCAASJ;;;;IAEzC,MAAM,CAACK,aAAaC,eAAe,GAAGpD,2BACpC,aACA;IAEF,MAAM,CAACqD,cAAcC,gBAAgB,GAAGtD,2BACtC,cACA;IAEF,MAAM,CAACuD,cAAc,GAAGvD,2BAA2B,eAAe;IAElE,MAAMwD,gBAAgB/D,KACpB;QACE,CAACW,UAAUsC,aAAa,CAAC,EAAEe,QAAQN;QACnC,CAAC/C,UAAUwC,cAAc,CAAC,EAAEa,QAAQJ;QACpC,CAACjD,UAAUuC,eAAe,CAAC,EAAEc,QAAQF;IACvC,GACAN;IAGF,yEAAyE;IACzE,qEAAqE;IACrE,uEAAuE;IACvE,wEAAwE;IACxE,sBAAsB;IACtB,MAAMS,QAAQlE;IACd,MAAMmE,UAAUpE,cAAcmE,MAAME,WAAW,CAACC,IAAI,CAAC,OAAO;QAC1DC,OAAO;IACT;IACA,MAAMC,mBAAmBjE,OAAO;IAChCD,UAAU;QACR,IAAI,CAAC8D,SAAS;YACZI,iBAAiBhD,OAAO,GAAG;YAC3B;QACF;QACA,IAAIgD,iBAAiBhD,OAAO,EAAE;QAC9BgD,iBAAiBhD,OAAO,GAAG;QAC3BqC,eAAe;QACfE,gBAAgB;IAChB,mEAAmE;IACnE,uDAAuD;IACzD,GAAG;QAACK;KAAQ;IAEZ,qEAAqE;IACrE,wDAAwD;IACxD,MAAMK,cAAclE,OAAO;QAAEiC,MAAMoB;QAAanB,OAAOqB;IAAa;IACpExD,UAAU;QACR,MAAMoE,OAAOD,YAAYjD,OAAO;QAChCiD,YAAYjD,OAAO,GAAG;YAAEgB,MAAMoB;YAAanB,OAAOqB;QAAa;QAC/D,IAAI,CAACM,WAAW,CAACR,eAAe,CAACE,cAAc;QAC/C,IAAIY,KAAKlC,IAAI,EAAEqB,eAAe;aACzBE,gBAAgB;IACrB,uDAAuD;IACzD,GAAG;QAACK;QAASR;QAAaE;KAAa;IAEvC,sEAAsE;IACtE,wEAAwE;IACxE,qEAAqE;IACrE,MAAM,CAACa,UAAUC,YAAY,GAAGpE,SAAS;IAEzC,MAAMqE,YAAYtE,OAAY;IAE9B,MAAMuE,kBAAkBzE,YAAY,CAACkB;YACxBsD;QAAX,IAAIjF,QAAOiF,qBAAAA,UAAUrD,OAAO,qBAAjBqD,mBAAmBE,KAAK,GAAG;YACpCF,UAAUrD,OAAO,CAACuD,KAAK;QACzB;IACF,GAAG,EAAE;IAEL,MAAMC,qBAAqB3E,YAAY,CAACkB;YAC3BsD;QAAX,IAAIjF,QAAOiF,qBAAAA,UAAUrD,OAAO,qBAAjBqD,mBAAmBI,OAAO,GAAG;YACtCJ,UAAUrD,OAAO,CAACyD,OAAO;QAC3B;IACF,GAAG,EAAE;IAEL,MAAMC,qBAAqB7E,YAAY,CAACkB;YAC3BsD;QAAX,IAAIjF,QAAOiF,qBAAAA,UAAUrD,OAAO,qBAAjBqD,mBAAmBM,MAAM,GAAG;YACrCN,UAAUrD,OAAO,CAAC2D,MAAM;QAC1B;IACF,GAAG,EAAE;IAEL,MAAMC,WAAW7E,OAAO;IACxB,MAAM8E,UAAUjE;IAChB,mEAAmE;IACnE,MAAM,EAAEkE,eAAe,EAAE,IAAG/F,eAAAA,yBAAAA,eAAiB,CAAC;IAE9CM,cAAc;QACZ0F,YAAWC,KAAoB;gBAoBJA;YAnBzB,IAAIC,SAA8B;YAClC,kEAAkE;YAClE,gDAAgD;YAChD,MAAMC,KAAKL,QAAQ7D,OAAO;YAC1B,IAAIgE,MAAMG,IAAI,IAAID,IAAI;oBAEHF;gBADjB,gEAAgE;gBAChE,MAAMI,YAAWJ,2BAAAA,MAAMG,IAAI,CAACE,IAAI,CAACrE,OAAO,qBAAvBgE,yBAAyBM,IAAI;gBAC9CL,SAASnG,SAASyG,mBAAmB,CACnCP,MAAMG,IAAI,CAACK,IAAI,EACfN,GAAGjE,CAAC,EACJiE,GAAG/D,CAAC,EACJ,+DAA+D;gBAC/D,gEAAgE;gBAChE,uDAAuD;gBACvDiE,WAAWvG,OAAO4G,mBAAmB,CAACL,YAAY;gBAEpDJ,MAAMG,IAAI,CAACE,IAAI,CAACrE,OAAO,CAACiE,MAAM,GAAGA;YACnC;YACAnG,SAAS4G,GAAG,CAACC,aAAa,CAACV;YAC3BnG,SAAS4G,GAAG,CAACE,WAAW,EAACZ,cAAAA,MAAMG,IAAI,qBAAVH,YAAYK,IAAI,CAACrE,OAAO,CAACsE,IAAI;YAEtDN,MAAMa,cAAc,CAACC,eAAe;QACtC;QACAC,aAAY,EAAEC,MAAM,EAAEH,cAAc,EAAkB;gBAOxCG;YANZ,mEAAmE;YACnE,2DAA2D;YAC3D,MAAMC,QAAQ3G,oBAAoBuG;YAClC,IAAII,OAAOpB,QAAQ7D,OAAO,GAAGiF;YAC7B,MAAMX,OAAOU,0BAAAA,OAAQX,IAAI,CAACrE,OAAO,CAACsE,IAAI;YACtCxG,SAAS4G,GAAG,CAACQ,WAAW,CAACZ;YACzBlB,YAAY4B,CAAAA,2BAAAA,uBAAAA,OAAQX,IAAI,CAACrE,OAAO,qBAApBgF,qBAAsBG,IAAI,MAAKrH,SAASsH,QAAQ,CAACC,MAAM;QACrE;QACAC;YACElC,YAAY;QACd;QACAmC,WAAUxF,CAAe;gBAQrBA;YAPFA,EAAE8E,cAAc,CAACC,eAAe;YAChC1B,YAAY;YACZ,oEAAoE;YACpE,sDAAsD;YACtD,IACER,WACA7C,EAAEoE,IAAI,IACNpE,EAAAA,yBAAAA,EAAEiF,MAAM,CAACX,IAAI,CAACrE,OAAO,qBAArBD,uBAAuBoF,IAAI,MAAKrH,SAASsH,QAAQ,CAACC,MAAM,EACxD;gBACAhD,eAAe;gBACfE,gBAAgB;YAClB;YACA,mEAAmE;YACnE,MAAMiD,YAAY1H,SAAS4G,GAAG,CAACe,qBAAqB;YACpD3H,SAAS4G,GAAG,CAACa,SAAS;YACtB,IAAIC,WAAW;gBACb1B,mCAAAA,gBAAkB0B,WAAW;oBAAEE,SAAS;oBAAWC,SAAS;gBAAM;YACpE;QACF;IACF;IAEA,qBACE,KAAC7E;QACCkB,KAAKhE,aAAagE,KAAK4B;QACvBgC,IAAG;QACH1D,WAAWO;OACPN;kBAEJ,cAAA,MAAC5D;YACCsH,WAAU;YACVD,IAAG;YACHE,WAAU;YACVC,SAAS;YACTC,IAAI;gBACFtE,YAAY;gBACZuE,gBAAgB;gBAChBC,UAAU;gBACV5E,UAAU;gBACV6E,QAAQ;YACV;;8BACA,KAAChH,0BAA0BiH,QAAQ;oBAACC,OAAOlD;8BACzC,cAAA,KAAC7D;wBAAmBgH,OAAO;;;8BAE7B,MAAC/H;oBACCsH,WAAU;oBACVD,IAAG;oBACHE,WAAU;oBACVC,SAAS;oBACTC,IAAI;wBACFtE,YAAY;wBACZuE,gBAAgB;wBAChBC,UAAU;wBACV5E,UAAU;wBACV6E,QAAQ;oBACV;;wBACClE;sCACD,KAAC7C;4BACCmH,aAAajD;4BACbkD,gBAAgBhD;4BAChBiD,gBAAgB/C;;sCAElB,KAACxE;;;8BAEH,KAACC,0BAA0BiH,QAAQ;oBAACC,OAAOlD;8BACzC,cAAA,KAAC7D;wBAAmBgH,OAAO;;;;;;AAKrC;AAGFxE,yBAAyB4E,WAAW,GAAG;AAEvC,SAAS5E,wBAAwB,GAAE;AACnC,eAAeA,yBAAwB"}
|
|
@@ -23,6 +23,24 @@ export interface WorkspacePanelComponentProps extends WorkspacePanelProps {
|
|
|
23
23
|
DrawerProps?: MuiDrawerProps;
|
|
24
24
|
open?: boolean;
|
|
25
25
|
anchor?: MuiDrawerProps['anchor'];
|
|
26
|
+
/**
|
|
27
|
+
* Overlay the workspace instead of sitting beside it. A screen too narrow
|
|
28
|
+
* for a docked panel AND a usable canvas gets the panel as a temporary
|
|
29
|
+
* drawer: it covers the canvas while open and gives all of it back when
|
|
30
|
+
* dismissed, rather than squeezing the canvas to nothing.
|
|
31
|
+
*/
|
|
32
|
+
temporary?: boolean;
|
|
33
|
+
/** Where the temporary drawer comes from; `anchor` when unset. */
|
|
34
|
+
temporaryAnchor?: MuiDrawerProps['anchor'];
|
|
35
|
+
/** The temporary drawer asks to close (backdrop tap, swipe, Escape). */
|
|
36
|
+
onClose?: () => void;
|
|
37
|
+
/** The temporary drawer asks to open. */
|
|
38
|
+
onOpen?: () => void;
|
|
26
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* True while a drag is in flight. A temporary (overlay) panel hides for the
|
|
42
|
+
* length of it: the drop targets are on the canvas it covers.
|
|
43
|
+
*/
|
|
44
|
+
export declare const WorkspacePanelDragContext: import("react").Context<boolean>;
|
|
27
45
|
export declare const WorkspacePanelComponent: import("react").ForwardRefExoticComponent<Omit<WorkspacePanelComponentProps, "ref"> & import("react").RefAttributes<any>>;
|
|
28
46
|
export default WorkspacePanelComponent;
|
|
@@ -19,8 +19,9 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
19
19
|
*/ import { generateComponentClassKeys, styled } from "@aglyn/shared-ui-theme";
|
|
20
20
|
import { _isEqualitySameType } from "@aglyn/shared-util-tools";
|
|
21
21
|
import MuiDrawer from "@mui/material/Drawer";
|
|
22
|
+
import MuiSwipeableDrawer from "@mui/material/SwipeableDrawer";
|
|
22
23
|
import clsx from "clsx";
|
|
23
|
-
import { forwardRef } from "react";
|
|
24
|
+
import { createContext, forwardRef, useContext } from "react";
|
|
24
25
|
import { DEFAULT_LEFT_DRAWER_WIDTH } from "../constants/shared.js";
|
|
25
26
|
const classKeys = generateComponentClassKeys('AglynWorkspacePanel', [
|
|
26
27
|
'drawer',
|
|
@@ -102,16 +103,25 @@ const WorkspacePanel = styled('div', {
|
|
|
102
103
|
}
|
|
103
104
|
};
|
|
104
105
|
});
|
|
106
|
+
/**
|
|
107
|
+
* True while a drag is in flight. A temporary (overlay) panel hides for the
|
|
108
|
+
* length of it: the drop targets are on the canvas it covers.
|
|
109
|
+
*/ export const WorkspacePanelDragContext = /*#__PURE__*/ createContext(false);
|
|
105
110
|
export const WorkspacePanelComponent = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
106
|
-
const { children, className: classNameProp, DrawerProps, size, open: openProp, anchor = 'left', id } = props, rest = _object_without_properties_loose(props, [
|
|
111
|
+
const { children, className: classNameProp, DrawerProps, size, open: openProp, anchor = 'left', id, temporary, temporaryAnchor, onClose, onOpen } = props, rest = _object_without_properties_loose(props, [
|
|
107
112
|
"children",
|
|
108
113
|
"className",
|
|
109
114
|
"DrawerProps",
|
|
110
115
|
"size",
|
|
111
116
|
"open",
|
|
112
117
|
"anchor",
|
|
113
|
-
"id"
|
|
118
|
+
"id",
|
|
119
|
+
"temporary",
|
|
120
|
+
"temporaryAnchor",
|
|
121
|
+
"onClose",
|
|
122
|
+
"onOpen"
|
|
114
123
|
]);
|
|
124
|
+
const dragging = useContext(WorkspacePanelDragContext);
|
|
115
125
|
const open = Boolean(openProp);
|
|
116
126
|
const _extends1 = _extends({}, DrawerProps), { className: drawerClassName, open: _ } = _extends1, drawerProps = _object_without_properties_loose(_extends1, [
|
|
117
127
|
"className",
|
|
@@ -124,6 +134,46 @@ export const WorkspacePanelComponent = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
124
134
|
[classKeys.anchorTop]: anchor === 'top',
|
|
125
135
|
[classKeys.anchorBottom]: anchor === 'bottom'
|
|
126
136
|
}, classNameProp);
|
|
137
|
+
if (temporary) {
|
|
138
|
+
const sheetAnchor = temporaryAnchor != null ? temporaryAnchor : anchor;
|
|
139
|
+
const sheet = sheetAnchor === 'top' || sheetAnchor === 'bottom';
|
|
140
|
+
const { component, 'aria-label': ariaLabel } = rest;
|
|
141
|
+
const { onClose: _onDrawerClose } = drawerProps, sheetProps = _object_without_properties_loose(drawerProps, [
|
|
142
|
+
"onClose"
|
|
143
|
+
]);
|
|
144
|
+
return /*#__PURE__*/ _jsx(MuiSwipeableDrawer, _extends({}, sheetProps, {
|
|
145
|
+
open: open,
|
|
146
|
+
anchor: sheetAnchor,
|
|
147
|
+
onClose: ()=>onClose == null ? void 0 : onClose(),
|
|
148
|
+
onOpen: ()=>onOpen == null ? void 0 : onOpen(),
|
|
149
|
+
// The toolbar opens these; an edge swipe would fight the canvas
|
|
150
|
+
// scrolling under the same finger. Swiping one closed still works.
|
|
151
|
+
disableSwipeToOpen: true,
|
|
152
|
+
className: clsx(classKeys.drawer, drawerClassName),
|
|
153
|
+
// Hidden, not closed: closing would unmount the card being dragged
|
|
154
|
+
// and end the drag with it.
|
|
155
|
+
sx: dragging ? {
|
|
156
|
+
visibility: 'hidden'
|
|
157
|
+
} : undefined,
|
|
158
|
+
slotProps: {
|
|
159
|
+
paper: {
|
|
160
|
+
ref,
|
|
161
|
+
id,
|
|
162
|
+
component,
|
|
163
|
+
'aria-label': ariaLabel,
|
|
164
|
+
sx: sheet ? {
|
|
165
|
+
height: '75dvh',
|
|
166
|
+
borderTopLeftRadius: 12,
|
|
167
|
+
borderTopRightRadius: 12
|
|
168
|
+
} : {
|
|
169
|
+
width: size || DEFAULT_LEFT_DRAWER_WIDTH,
|
|
170
|
+
maxWidth: '88vw'
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
children: children
|
|
175
|
+
}));
|
|
176
|
+
}
|
|
127
177
|
return /*#__PURE__*/ _jsx(WorkspacePanel, _extends({
|
|
128
178
|
ref: ref,
|
|
129
179
|
id: id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../../libs/besigner/feature/designer/src/lib/components/workspace-panel.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2024 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { generateComponentClassKeys, styled } from '@aglyn/shared-ui-theme'\nimport { _isEqualitySameType } from '@aglyn/shared-util-tools'\nimport { type BoxProps as MuiBoxProps } from '@mui/material/Box'\nimport MuiDrawer, {\n type DrawerProps as MuiDrawerProps,\n} from '@mui/material/Drawer'\nimport clsx from 'clsx'\nimport { forwardRef } from 'react'\nimport { DEFAULT_LEFT_DRAWER_WIDTH } from '../constants/shared'\n\nconst classKeys = generateComponentClassKeys('AglynWorkspacePanel', [\n 'drawer',\n 'open',\n 'anchorLeft',\n 'anchorRight',\n 'anchorTop',\n 'anchorBottom',\n])\n\ninterface WorkspacePanelProps extends MuiBoxProps {\n size?: string | number\n}\n\nconst WorkspacePanel = styled('div', {\n name: 'AglynWorkspacePanel',\n shouldForwardProp(propName: any) {\n return !_isEqualitySameType(propName, null, 'size')\n },\n})<WorkspacePanelProps>(({ theme, size }) => {\n const calcSize = size || DEFAULT_LEFT_DRAWER_WIDTH\n\n return {\n zIndex: theme.zIndex.appBar,\n transition: theme.transitions.create('margin', {\n easing: theme.transitions.easing.sharp,\n duration: theme.transitions.duration.leavingScreen,\n }),\n [`&.${classKeys.open}`]: {\n transition: theme.transitions.create('margin', {\n easing: theme.transitions.easing.easeOut,\n duration: theme.transitions.duration.enteringScreen,\n }),\n },\n\n [`&.${classKeys.anchorLeft}`]: {\n marginLeft: -calcSize,\n [`&.${classKeys.open}`]: {\n marginLeft: 0,\n },\n },\n [`&.${classKeys.anchorRight}`]: {\n marginRight: -calcSize,\n [`&.${classKeys.open}`]: {\n marginRight: 0,\n },\n },\n [`&.${classKeys.anchorTop}`]: {\n marginTop: -calcSize,\n [`&.${classKeys.open}`]: {\n marginTop: 0,\n },\n },\n [`&.${classKeys.anchorBottom}`]: {\n marginBottom: -calcSize,\n [`&.${classKeys.open}`]: {\n marginBottom: 0,\n },\n },\n\n [`&.${classKeys.anchorTop}, &.${classKeys.anchorBottom}`]: {\n [`& .${classKeys.drawer}`]: {\n height: calcSize,\n width: '100%',\n [`& .MuiDrawer-paper`]: {\n height: calcSize,\n width: '100%',\n },\n },\n },\n [`&.${classKeys.anchorLeft}, &.${classKeys.anchorRight}`]: {\n [`& .${classKeys.drawer}`]: {\n width: calcSize,\n height: '100%',\n [`& .MuiDrawer-paper`]: {\n width: calcSize,\n height: '100%',\n },\n },\n },\n [`& .${classKeys.drawer}`]: {\n flexShrink: 0,\n [`& .MuiDrawer-paper`]: {\n boxSizing: 'border-box',\n position: 'unset',\n },\n },\n }\n})\n\nexport interface WorkspacePanelComponentProps extends WorkspacePanelProps {\n DrawerProps?: MuiDrawerProps\n open?: boolean\n anchor?: MuiDrawerProps['anchor']\n}\n\nexport const WorkspacePanelComponent = forwardRef<\n any,\n WorkspacePanelComponentProps\n>((props, ref) => {\n const {\n children,\n className: classNameProp,\n DrawerProps,\n size,\n open: openProp,\n anchor = 'left',\n id,\n ...rest\n } = props\n const open = Boolean(openProp)\n const {\n className: drawerClassName,\n open: _,\n ...drawerProps\n } = { ...DrawerProps }\n const className = clsx(\n {\n [classKeys.open]: open,\n [classKeys.anchorLeft]: anchor === 'left',\n [classKeys.anchorRight]: anchor === 'right',\n [classKeys.anchorTop]: anchor === 'top',\n [classKeys.anchorBottom]: anchor === 'bottom',\n },\n classNameProp,\n )\n\n return (\n <WorkspacePanel\n ref={ref}\n id={id}\n size={size}\n className={className}\n {...rest}\n >\n <MuiDrawer\n variant=\"persistent\"\n open={open}\n anchor={anchor}\n className={clsx(classKeys.drawer, drawerClassName)}\n {...drawerProps}\n >\n {children}\n </MuiDrawer>\n </WorkspacePanel>\n )\n})\n\nWorkspacePanelComponent.displayName = 'WorkspacePanelComponent'\nWorkspacePanelComponent.aglyn = true\n\nexport default WorkspacePanelComponent\n"],"names":["generateComponentClassKeys","styled","_isEqualitySameType","MuiDrawer","clsx","forwardRef","DEFAULT_LEFT_DRAWER_WIDTH","classKeys","WorkspacePanel","name","shouldForwardProp","propName","theme","size","calcSize","zIndex","appBar","transition","transitions","create","easing","sharp","duration","leavingScreen","open","easeOut","enteringScreen","anchorLeft","marginLeft","anchorRight","marginRight","anchorTop","marginTop","anchorBottom","marginBottom","drawer","height","width","flexShrink","boxSizing","position","WorkspacePanelComponent","props","ref","children","className","classNameProp","DrawerProps","openProp","anchor","id","rest","Boolean","drawerClassName","_","drawerProps","variant","displayName","aglyn"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/besigner/feature/designer/src/lib/components/workspace-panel.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2024 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { generateComponentClassKeys, styled } from '@aglyn/shared-ui-theme'\nimport { _isEqualitySameType } from '@aglyn/shared-util-tools'\nimport { type BoxProps as MuiBoxProps } from '@mui/material/Box'\nimport MuiDrawer, {\n type DrawerProps as MuiDrawerProps,\n} from '@mui/material/Drawer'\nimport MuiSwipeableDrawer from '@mui/material/SwipeableDrawer'\nimport clsx from 'clsx'\nimport { createContext, forwardRef, useContext } from 'react'\nimport { DEFAULT_LEFT_DRAWER_WIDTH } from '../constants/shared'\n\nconst classKeys = generateComponentClassKeys('AglynWorkspacePanel', [\n 'drawer',\n 'open',\n 'anchorLeft',\n 'anchorRight',\n 'anchorTop',\n 'anchorBottom',\n])\n\ninterface WorkspacePanelProps extends MuiBoxProps {\n size?: string | number\n}\n\nconst WorkspacePanel = styled('div', {\n name: 'AglynWorkspacePanel',\n shouldForwardProp(propName: any) {\n return !_isEqualitySameType(propName, null, 'size')\n },\n})<WorkspacePanelProps>(({ theme, size }) => {\n const calcSize = size || DEFAULT_LEFT_DRAWER_WIDTH\n\n return {\n zIndex: theme.zIndex.appBar,\n transition: theme.transitions.create('margin', {\n easing: theme.transitions.easing.sharp,\n duration: theme.transitions.duration.leavingScreen,\n }),\n [`&.${classKeys.open}`]: {\n transition: theme.transitions.create('margin', {\n easing: theme.transitions.easing.easeOut,\n duration: theme.transitions.duration.enteringScreen,\n }),\n },\n\n [`&.${classKeys.anchorLeft}`]: {\n marginLeft: -calcSize,\n [`&.${classKeys.open}`]: {\n marginLeft: 0,\n },\n },\n [`&.${classKeys.anchorRight}`]: {\n marginRight: -calcSize,\n [`&.${classKeys.open}`]: {\n marginRight: 0,\n },\n },\n [`&.${classKeys.anchorTop}`]: {\n marginTop: -calcSize,\n [`&.${classKeys.open}`]: {\n marginTop: 0,\n },\n },\n [`&.${classKeys.anchorBottom}`]: {\n marginBottom: -calcSize,\n [`&.${classKeys.open}`]: {\n marginBottom: 0,\n },\n },\n\n [`&.${classKeys.anchorTop}, &.${classKeys.anchorBottom}`]: {\n [`& .${classKeys.drawer}`]: {\n height: calcSize,\n width: '100%',\n [`& .MuiDrawer-paper`]: {\n height: calcSize,\n width: '100%',\n },\n },\n },\n [`&.${classKeys.anchorLeft}, &.${classKeys.anchorRight}`]: {\n [`& .${classKeys.drawer}`]: {\n width: calcSize,\n height: '100%',\n [`& .MuiDrawer-paper`]: {\n width: calcSize,\n height: '100%',\n },\n },\n },\n [`& .${classKeys.drawer}`]: {\n flexShrink: 0,\n [`& .MuiDrawer-paper`]: {\n boxSizing: 'border-box',\n position: 'unset',\n },\n },\n }\n})\n\nexport interface WorkspacePanelComponentProps extends WorkspacePanelProps {\n DrawerProps?: MuiDrawerProps\n open?: boolean\n anchor?: MuiDrawerProps['anchor']\n /**\n * Overlay the workspace instead of sitting beside it. A screen too narrow\n * for a docked panel AND a usable canvas gets the panel as a temporary\n * drawer: it covers the canvas while open and gives all of it back when\n * dismissed, rather than squeezing the canvas to nothing.\n */\n temporary?: boolean\n /** Where the temporary drawer comes from; `anchor` when unset. */\n temporaryAnchor?: MuiDrawerProps['anchor']\n /** The temporary drawer asks to close (backdrop tap, swipe, Escape). */\n onClose?: () => void\n /** The temporary drawer asks to open. */\n onOpen?: () => void\n}\n\n/**\n * True while a drag is in flight. A temporary (overlay) panel hides for the\n * length of it: the drop targets are on the canvas it covers.\n */\nexport const WorkspacePanelDragContext = createContext(false)\n\nexport const WorkspacePanelComponent = forwardRef<\n any,\n WorkspacePanelComponentProps\n>((props, ref) => {\n const {\n children,\n className: classNameProp,\n DrawerProps,\n size,\n open: openProp,\n anchor = 'left',\n id,\n temporary,\n temporaryAnchor,\n onClose,\n onOpen,\n ...rest\n } = props\n const dragging = useContext(WorkspacePanelDragContext)\n const open = Boolean(openProp)\n const {\n className: drawerClassName,\n open: _,\n ...drawerProps\n } = { ...DrawerProps }\n const className = clsx(\n {\n [classKeys.open]: open,\n [classKeys.anchorLeft]: anchor === 'left',\n [classKeys.anchorRight]: anchor === 'right',\n [classKeys.anchorTop]: anchor === 'top',\n [classKeys.anchorBottom]: anchor === 'bottom',\n },\n classNameProp,\n )\n\n if (temporary) {\n const sheetAnchor = temporaryAnchor ?? anchor\n const sheet = sheetAnchor === 'top' || sheetAnchor === 'bottom'\n const {\n component,\n 'aria-label': ariaLabel,\n } = rest as { component?: string; 'aria-label'?: string }\n const { onClose: _onDrawerClose, ...sheetProps } = drawerProps\n return (\n <MuiSwipeableDrawer\n {...sheetProps}\n open={open}\n anchor={sheetAnchor}\n onClose={() => onClose?.()}\n onOpen={() => onOpen?.()}\n // The toolbar opens these; an edge swipe would fight the canvas\n // scrolling under the same finger. Swiping one closed still works.\n disableSwipeToOpen\n className={clsx(classKeys.drawer, drawerClassName)}\n // Hidden, not closed: closing would unmount the card being dragged\n // and end the drag with it.\n sx={dragging ? { visibility: 'hidden' } : undefined}\n slotProps={{\n paper: {\n ref,\n id,\n component,\n 'aria-label': ariaLabel,\n sx: sheet\n ? {\n height: '75dvh',\n borderTopLeftRadius: 12,\n borderTopRightRadius: 12,\n }\n : { width: size || DEFAULT_LEFT_DRAWER_WIDTH, maxWidth: '88vw' },\n } as object,\n }}\n >\n {children}\n </MuiSwipeableDrawer>\n )\n }\n\n return (\n <WorkspacePanel\n ref={ref}\n id={id}\n size={size}\n className={className}\n {...rest}\n >\n <MuiDrawer\n variant=\"persistent\"\n open={open}\n anchor={anchor}\n className={clsx(classKeys.drawer, drawerClassName)}\n {...drawerProps}\n >\n {children}\n </MuiDrawer>\n </WorkspacePanel>\n )\n})\n\nWorkspacePanelComponent.displayName = 'WorkspacePanelComponent'\nWorkspacePanelComponent.aglyn = true\n\nexport default WorkspacePanelComponent\n"],"names":["generateComponentClassKeys","styled","_isEqualitySameType","MuiDrawer","MuiSwipeableDrawer","clsx","createContext","forwardRef","useContext","DEFAULT_LEFT_DRAWER_WIDTH","classKeys","WorkspacePanel","name","shouldForwardProp","propName","theme","size","calcSize","zIndex","appBar","transition","transitions","create","easing","sharp","duration","leavingScreen","open","easeOut","enteringScreen","anchorLeft","marginLeft","anchorRight","marginRight","anchorTop","marginTop","anchorBottom","marginBottom","drawer","height","width","flexShrink","boxSizing","position","WorkspacePanelDragContext","WorkspacePanelComponent","props","ref","children","className","classNameProp","DrawerProps","openProp","anchor","id","temporary","temporaryAnchor","onClose","onOpen","rest","dragging","Boolean","drawerClassName","_","drawerProps","sheetAnchor","sheet","component","ariaLabel","_onDrawerClose","sheetProps","disableSwipeToOpen","sx","visibility","undefined","slotProps","paper","borderTopLeftRadius","borderTopRightRadius","maxWidth","variant","displayName","aglyn"],"mappings":"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"}
|