@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.
Files changed (28) hide show
  1. package/package.json +19 -18
  2. package/src/lib/components/aside-panel.component.js +30 -3
  3. package/src/lib/components/aside-panel.component.js.map +1 -1
  4. package/src/lib/components/besigner-dnd-context.component.js +31 -2
  5. package/src/lib/components/besigner-dnd-context.component.js.map +1 -1
  6. package/src/lib/components/component-accordion-list.js +4 -2
  7. package/src/lib/components/component-accordion-list.js.map +1 -1
  8. package/src/lib/components/component-picker.js +42 -2
  9. package/src/lib/components/component-picker.js.map +1 -1
  10. package/src/lib/components/device-preview-controls.component.d.ts +2 -0
  11. package/src/lib/components/device-preview-controls.component.js +11 -5
  12. package/src/lib/components/device-preview-controls.component.js.map +1 -1
  13. package/src/lib/components/dnd/draggable-droppable.js +39 -0
  14. package/src/lib/components/dnd/draggable-droppable.js.map +1 -1
  15. package/src/lib/components/node-quick-actions.js +210 -174
  16. package/src/lib/components/node-quick-actions.js.map +1 -1
  17. package/src/lib/components/node-tree-view.js +11 -1
  18. package/src/lib/components/node-tree-view.js.map +1 -1
  19. package/src/lib/components/panel-controls.component.d.ts +6 -0
  20. package/src/lib/components/panel-controls.component.js +10 -6
  21. package/src/lib/components/panel-controls.component.js.map +1 -1
  22. package/src/lib/components/viewport-canvas.component.js +8 -0
  23. package/src/lib/components/viewport-canvas.component.js.map +1 -1
  24. package/src/lib/components/workspace-editor.component.js +131 -16
  25. package/src/lib/components/workspace-editor.component.js.map +1 -1
  26. package/src/lib/components/workspace-panel.component.d.ts +18 -0
  27. package/src/lib/components/workspace-panel.component.js +53 -3
  28. 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 { Stack } from "@mui/material";
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 mouse = useMouse(localRef);
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
- if (event.over) {
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 are viewport-relative; useMouse coords are
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, mouse.docX - window.scrollX, mouse.docY - window.scrollY, // Leaves (self-closing / text-editable) never offer a CHILDREN
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(PanelLeftComponent, {
156
- panel: 'panelLeft'
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(PanelLeftComponent, {
181
- panel: 'panelRight'
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":"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"}
@@ -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":";;;AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,0BAA0B,EAAEC,MAAM,QAAQ,yBAAwB;AAC3E,SAASC,mBAAmB,QAAQ,2BAA0B;AAE9D,OAAOC,eAEA,uBAAsB;AAC7B,OAAOC,wBAAwB,gCAA+B;AAC9D,OAAOC,UAAU,OAAM;AACvB,SAASC,aAAa,EAAEC,UAAU,EAAEC,UAAU,QAAQ,QAAO;AAC7D,SAASC,yBAAyB,QAAQ,yBAAqB;AAE/D,MAAMC,YAAYV,2BAA2B,uBAAuB;IAClE;IACA;IACA;IACA;IACA;IACA;CACD;AAMD,MAAMW,iBAAiBV,OAAO,OAAO;IACnCW,MAAM;IACNC,mBAAkBC,QAAa;QAC7B,OAAO,CAACZ,oBAAoBY,UAAU,MAAM;IAC9C;AACF,GAAwB,CAAC,EAAEC,KAAK,EAAEC,IAAI,EAAE;IACtC,MAAMC,WAAWD,QAAQP;IAEzB,OAAO;QACLS,QAAQH,MAAMG,MAAM,CAACC,MAAM;QAC3BC,YAAYL,MAAMM,WAAW,CAACC,MAAM,CAAC,UAAU;YAC7CC,QAAQR,MAAMM,WAAW,CAACE,MAAM,CAACC,KAAK;YACtCC,UAAUV,MAAMM,WAAW,CAACI,QAAQ,CAACC,aAAa;QACpD;QACA,CAAC,CAAC,EAAE,EAAEhB,UAAUiB,IAAI,EAAE,CAAC,EAAE;YACvBP,YAAYL,MAAMM,WAAW,CAACC,MAAM,CAAC,UAAU;gBAC7CC,QAAQR,MAAMM,WAAW,CAACE,MAAM,CAACK,OAAO;gBACxCH,UAAUV,MAAMM,WAAW,CAACI,QAAQ,CAACI,cAAc;YACrD;QACF;QAEA,CAAC,CAAC,EAAE,EAAEnB,UAAUoB,UAAU,EAAE,CAAC,EAAE;YAC7BC,YAAY,CAACd;YACb,CAAC,CAAC,EAAE,EAAEP,UAAUiB,IAAI,EAAE,CAAC,EAAE;gBACvBI,YAAY;YACd;QACF;QACA,CAAC,CAAC,EAAE,EAAErB,UAAUsB,WAAW,EAAE,CAAC,EAAE;YAC9BC,aAAa,CAAChB;YACd,CAAC,CAAC,EAAE,EAAEP,UAAUiB,IAAI,EAAE,CAAC,EAAE;gBACvBM,aAAa;YACf;QACF;QACA,CAAC,CAAC,EAAE,EAAEvB,UAAUwB,SAAS,EAAE,CAAC,EAAE;YAC5BC,WAAW,CAAClB;YACZ,CAAC,CAAC,EAAE,EAAEP,UAAUiB,IAAI,EAAE,CAAC,EAAE;gBACvBQ,WAAW;YACb;QACF;QACA,CAAC,CAAC,EAAE,EAAEzB,UAAU0B,YAAY,EAAE,CAAC,EAAE;YAC/BC,cAAc,CAACpB;YACf,CAAC,CAAC,EAAE,EAAEP,UAAUiB,IAAI,EAAE,CAAC,EAAE;gBACvBU,cAAc;YAChB;QACF;QAEA,CAAC,CAAC,EAAE,EAAE3B,UAAUwB,SAAS,CAAC,IAAI,EAAExB,UAAU0B,YAAY,EAAE,CAAC,EAAE;YACzD,CAAC,CAAC,GAAG,EAAE1B,UAAU4B,MAAM,EAAE,CAAC,EAAE;gBAC1BC,QAAQtB;gBACRuB,OAAO;gBACP,CAAC,CAAC,kBAAkB,CAAC,CAAC,EAAE;oBACtBD,QAAQtB;oBACRuB,OAAO;gBACT;YACF;QACF;QACA,CAAC,CAAC,EAAE,EAAE9B,UAAUoB,UAAU,CAAC,IAAI,EAAEpB,UAAUsB,WAAW,EAAE,CAAC,EAAE;YACzD,CAAC,CAAC,GAAG,EAAEtB,UAAU4B,MAAM,EAAE,CAAC,EAAE;gBAC1BE,OAAOvB;gBACPsB,QAAQ;gBACR,CAAC,CAAC,kBAAkB,CAAC,CAAC,EAAE;oBACtBC,OAAOvB;oBACPsB,QAAQ;gBACV;YACF;QACF;QACA,CAAC,CAAC,GAAG,EAAE7B,UAAU4B,MAAM,EAAE,CAAC,EAAE;YAC1BG,YAAY;YACZ,CAAC,CAAC,kBAAkB,CAAC,CAAC,EAAE;gBACtBC,WAAW;gBACXC,UAAU;YACZ;QACF;IACF;AACF;AAqBA;;;CAGC,GACD,OAAO,MAAMC,0CAA4BtC,cAAc,OAAM;AAE7D,OAAO,MAAMuC,wCAA0BtC,WAGrC,CAACuC,OAAOC;IACR,MAAM,EACJC,QAAQ,EACRC,WAAWC,aAAa,EACxBC,WAAW,EACXnC,IAAI,EACJW,MAAMyB,QAAQ,EACdC,SAAS,MAAM,EACfC,EAAE,EACFC,SAAS,EACTC,eAAe,EACfC,OAAO,EACPC,MAAM,EAEP,GAAGZ,OADCa,wCACDb;;;;;;;;;;;;;IACJ,MAAMc,WAAWpD,WAAWoC;IAC5B,MAAMjB,OAAOkC,QAAQT;IACrB,MAII,YAAA,aAAKD,cAJH,EACJF,WAAWa,eAAe,EAC1BnC,MAAMoC,CAAC,EAER,GAAG,WADCC,+CACD;;;;IACJ,MAAMf,YAAY5C,KAChB;QACE,CAACK,UAAUiB,IAAI,CAAC,EAAEA;QAClB,CAACjB,UAAUoB,UAAU,CAAC,EAAEuB,WAAW;QACnC,CAAC3C,UAAUsB,WAAW,CAAC,EAAEqB,WAAW;QACpC,CAAC3C,UAAUwB,SAAS,CAAC,EAAEmB,WAAW;QAClC,CAAC3C,UAAU0B,YAAY,CAAC,EAAEiB,WAAW;IACvC,GACAH;IAGF,IAAIK,WAAW;QACb,MAAMU,cAAcT,0BAAAA,kBAAmBH;QACvC,MAAMa,QAAQD,gBAAgB,SAASA,gBAAgB;QACvD,MAAM,EACJE,SAAS,EACT,cAAcC,SAAS,EACxB,GAAGT;QACJ,MAAM,EAAEF,SAASY,cAAc,EAAiB,GAAGL,aAAfM,8CAAeN;;;QACnD,qBACE,KAAC5D,iCACKkE;YACJ3C,MAAMA;YACN0B,QAAQY;YACRR,SAAS,IAAMA,2BAAAA;YACfC,QAAQ,IAAMA,0BAAAA;YACd,gEAAgE;YAChE,mEAAmE;YACnEa,kBAAkB;YAClBtB,WAAW5C,KAAKK,UAAU4B,MAAM,EAAEwB;YAClC,mEAAmE;YACnE,4BAA4B;YAC5BU,IAAIZ,WAAW;gBAAEa,YAAY;YAAS,IAAIC;YAC1CC,WAAW;gBACTC,OAAO;oBACL7B;oBACAO;oBACAa;oBACA,cAAcC;oBACdI,IAAIN,QACA;wBACE3B,QAAQ;wBACRsC,qBAAqB;wBACrBC,sBAAsB;oBACxB,IACA;wBAAEtC,OAAOxB,QAAQP;wBAA2BsE,UAAU;oBAAO;gBACnE;YACF;sBAEC/B;;IAGP;IAEA,qBACE,KAACrC;QACCoC,KAAKA;QACLO,IAAIA;QACJtC,MAAMA;QACNiC,WAAWA;OACPU;kBAEJ,cAAA,KAACxD;YACC6E,SAAQ;YACRrD,MAAMA;YACN0B,QAAQA;YACRJ,WAAW5C,KAAKK,UAAU4B,MAAM,EAAEwB;WAC9BE;sBAEHhB;;;AAIT,GAAE;AAEFH,wBAAwBoC,WAAW,GAAG;AACtCpC,wBAAwBqC,KAAK,GAAG;AAEhC,eAAerC,wBAAuB"}