@aglyn/besigner-ui 1.0.0-beta.143
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/LICENSE +201 -0
- package/README.md +7 -0
- package/package.json +73 -0
- package/src/besigner.d.ts +88 -0
- package/src/besigner.js +89 -0
- package/src/besigner.js.map +1 -0
- package/src/index.d.ts +17 -0
- package/src/index.js +18 -0
- package/src/index.js.map +1 -0
- package/src/lib/box-styler/box-styler.d.ts +57 -0
- package/src/lib/box-styler/box-styler.js +240 -0
- package/src/lib/box-styler/box-styler.js.map +1 -0
- package/src/lib/box-styler/components/box-diagram.d.ts +89 -0
- package/src/lib/box-styler/components/box-diagram.js +661 -0
- package/src/lib/box-styler/components/box-diagram.js.map +1 -0
- package/src/lib/box-styler/components/legend.d.ts +56 -0
- package/src/lib/box-styler/components/legend.js +130 -0
- package/src/lib/box-styler/components/legend.js.map +1 -0
- package/src/lib/box-styler/components/spacing-editor.d.ts +55 -0
- package/src/lib/box-styler/components/spacing-editor.js +347 -0
- package/src/lib/box-styler/components/spacing-editor.js.map +1 -0
- package/src/lib/box-styler/constants.d.ts +17 -0
- package/src/lib/box-styler/constants.js +30 -0
- package/src/lib/box-styler/constants.js.map +1 -0
- package/src/lib/box-styler/index.d.ts +2 -0
- package/src/lib/box-styler/index.js +4 -0
- package/src/lib/box-styler/index.js.map +1 -0
- package/src/lib/box-styler/region-fills.d.ts +107 -0
- package/src/lib/box-styler/region-fills.js +139 -0
- package/src/lib/box-styler/region-fills.js.map +1 -0
- package/src/lib/box-styler/spacing-value.d.ts +104 -0
- package/src/lib/box-styler/spacing-value.js +223 -0
- package/src/lib/box-styler/spacing-value.js.map +1 -0
- package/src/lib/box-styler/types.d.ts +29 -0
- package/src/lib/box-styler/types.js +18 -0
- package/src/lib/box-styler/types.js.map +1 -0
- package/src/lib/components/accordion-list.component.d.ts +50 -0
- package/src/lib/components/accordion-list.component.js +228 -0
- package/src/lib/components/accordion-list.component.js.map +1 -0
- package/src/lib/components/add-controls.component.d.ts +22 -0
- package/src/lib/components/add-controls.component.js +50 -0
- package/src/lib/components/add-controls.component.js.map +1 -0
- package/src/lib/components/app-bar-breadcrumbs.component.d.ts +29 -0
- package/src/lib/components/app-bar-breadcrumbs.component.js +279 -0
- package/src/lib/components/app-bar-breadcrumbs.component.js.map +1 -0
- package/src/lib/components/app-bar-primary.component.d.ts +21 -0
- package/src/lib/components/app-bar-primary.component.js +108 -0
- package/src/lib/components/app-bar-primary.component.js.map +1 -0
- package/src/lib/components/app-bar-secondary.component.d.ts +21 -0
- package/src/lib/components/app-bar-secondary.component.js +94 -0
- package/src/lib/components/app-bar-secondary.component.js.map +1 -0
- package/src/lib/components/aside-panel.component.d.ts +23 -0
- package/src/lib/components/aside-panel.component.js +505 -0
- package/src/lib/components/aside-panel.component.js.map +1 -0
- package/src/lib/components/besigner-conflict-alert.component.d.ts +36 -0
- package/src/lib/components/besigner-conflict-alert.component.js +51 -0
- package/src/lib/components/besigner-conflict-alert.component.js.map +1 -0
- package/src/lib/components/besigner-dnd-context.component.d.ts +32 -0
- package/src/lib/components/besigner-dnd-context.component.js +75 -0
- package/src/lib/components/besigner-dnd-context.component.js.map +1 -0
- package/src/lib/components/besigner-draft-alert.component.d.ts +70 -0
- package/src/lib/components/besigner-draft-alert.component.js +155 -0
- package/src/lib/components/besigner-draft-alert.component.js.map +1 -0
- package/src/lib/components/besigner-root-provider.component.d.ts +33 -0
- package/src/lib/components/besigner-root-provider.component.js +68 -0
- package/src/lib/components/besigner-root-provider.component.js.map +1 -0
- package/src/lib/components/binding-preview-controls.component.d.ts +28 -0
- package/src/lib/components/binding-preview-controls.component.js +63 -0
- package/src/lib/components/binding-preview-controls.component.js.map +1 -0
- package/src/lib/components/closeable-drawer.component.d.ts +32 -0
- package/src/lib/components/closeable-drawer.component.js +134 -0
- package/src/lib/components/closeable-drawer.component.js.map +1 -0
- package/src/lib/components/component-accordion-list.d.ts +28 -0
- package/src/lib/components/component-accordion-list.js +205 -0
- package/src/lib/components/component-accordion-list.js.map +1 -0
- package/src/lib/components/component-icon.component.d.ts +32 -0
- package/src/lib/components/component-icon.component.js +51 -0
- package/src/lib/components/component-icon.component.js.map +1 -0
- package/src/lib/components/component-picker.d.ts +27 -0
- package/src/lib/components/component-picker.js +368 -0
- package/src/lib/components/component-picker.js.map +1 -0
- package/src/lib/components/components-grid-list.component.d.ts +31 -0
- package/src/lib/components/components-grid-list.component.js +162 -0
- package/src/lib/components/components-grid-list.component.js.map +1 -0
- package/src/lib/components/custom-css-form.component.d.ts +115 -0
- package/src/lib/components/custom-css-form.component.js +699 -0
- package/src/lib/components/custom-css-form.component.js.map +1 -0
- package/src/lib/components/device-preview-controls.component.d.ts +22 -0
- package/src/lib/components/device-preview-controls.component.js +150 -0
- package/src/lib/components/device-preview-controls.component.js.map +1 -0
- package/src/lib/components/dnd/canvas-drop-indicator.d.ts +20 -0
- package/src/lib/components/dnd/canvas-drop-indicator.js +61 -0
- package/src/lib/components/dnd/canvas-drop-indicator.js.map +1 -0
- package/src/lib/components/dnd/draggable-droppable.d.ts +31 -0
- package/src/lib/components/dnd/draggable-droppable.js +383 -0
- package/src/lib/components/dnd/draggable-droppable.js.map +1 -0
- package/src/lib/components/dnd/draggable.d.ts +42 -0
- package/src/lib/components/dnd/draggable.js +66 -0
- package/src/lib/components/dnd/draggable.js.map +1 -0
- package/src/lib/components/dnd/drop-indicator.d.ts +31 -0
- package/src/lib/components/dnd/drop-indicator.js +139 -0
- package/src/lib/components/dnd/drop-indicator.js.map +1 -0
- package/src/lib/components/dnd/droppable.d.ts +43 -0
- package/src/lib/components/dnd/droppable.js +63 -0
- package/src/lib/components/dnd/droppable.js.map +1 -0
- package/src/lib/components/element-card.component.d.ts +23 -0
- package/src/lib/components/element-card.component.js +49 -0
- package/src/lib/components/element-card.component.js.map +1 -0
- package/src/lib/components/element-classes-field.component.d.ts +41 -0
- package/src/lib/components/element-classes-field.component.js +140 -0
- package/src/lib/components/element-classes-field.component.js.map +1 -0
- package/src/lib/components/element-detail-overlay.component.d.ts +55 -0
- package/src/lib/components/element-detail-overlay.component.js +157 -0
- package/src/lib/components/element-detail-overlay.component.js.map +1 -0
- package/src/lib/components/element-detail.component.d.ts +56 -0
- package/src/lib/components/element-detail.component.js +171 -0
- package/src/lib/components/element-detail.component.js.map +1 -0
- package/src/lib/components/element-info-details.component.d.ts +18 -0
- package/src/lib/components/element-info-details.component.js +169 -0
- package/src/lib/components/element-info-details.component.js.map +1 -0
- package/src/lib/components/element-interactions-form.component.d.ts +21 -0
- package/src/lib/components/element-interactions-form.component.js +199 -0
- package/src/lib/components/element-interactions-form.component.js.map +1 -0
- package/src/lib/components/element-preview.component.d.ts +75 -0
- package/src/lib/components/element-preview.component.js +346 -0
- package/src/lib/components/element-preview.component.js.map +1 -0
- package/src/lib/components/element-props-form.component.d.ts +565 -0
- package/src/lib/components/element-props-form.component.js +2392 -0
- package/src/lib/components/element-props-form.component.js.map +1 -0
- package/src/lib/components/element-styles-form-template.component.d.ts +27 -0
- package/src/lib/components/element-styles-form-template.component.js +89 -0
- package/src/lib/components/element-styles-form-template.component.js.map +1 -0
- package/src/lib/components/element-styles-form.component.d.ts +52 -0
- package/src/lib/components/element-styles-form.component.js +1350 -0
- package/src/lib/components/element-styles-form.component.js.map +1 -0
- package/src/lib/components/empty-document-slot.d.ts +39 -0
- package/src/lib/components/empty-document-slot.js +121 -0
- package/src/lib/components/empty-document-slot.js.map +1 -0
- package/src/lib/components/empty-results.d.ts +22 -0
- package/src/lib/components/empty-results.js +131 -0
- package/src/lib/components/empty-results.js.map +1 -0
- package/src/lib/components/history-controls.component.d.ts +21 -0
- package/src/lib/components/history-controls.component.js +67 -0
- package/src/lib/components/history-controls.component.js.map +1 -0
- package/src/lib/components/inline-markdown-editor.component.d.ts +17 -0
- package/src/lib/components/inline-markdown-editor.component.js +220 -0
- package/src/lib/components/inline-markdown-editor.component.js.map +1 -0
- package/src/lib/components/inline-text-editor.component.d.ts +48 -0
- package/src/lib/components/inline-text-editor.component.js +905 -0
- package/src/lib/components/inline-text-editor.component.js.map +1 -0
- package/src/lib/components/insert-token-menu.component.d.ts +86 -0
- package/src/lib/components/insert-token-menu.component.js +232 -0
- package/src/lib/components/insert-token-menu.component.js.map +1 -0
- package/src/lib/components/instance-attr-overrides.component.d.ts +50 -0
- package/src/lib/components/instance-attr-overrides.component.js +298 -0
- package/src/lib/components/instance-attr-overrides.component.js.map +1 -0
- package/src/lib/components/interact-controls.component.d.ts +22 -0
- package/src/lib/components/interact-controls.component.js +74 -0
- package/src/lib/components/interact-controls.component.js.map +1 -0
- package/src/lib/components/markdown-attribute-field.component.d.ts +40 -0
- package/src/lib/components/markdown-attribute-field.component.js +103 -0
- package/src/lib/components/markdown-attribute-field.component.js.map +1 -0
- package/src/lib/components/node-card.d.ts +24 -0
- package/src/lib/components/node-card.js +86 -0
- package/src/lib/components/node-card.js.map +1 -0
- package/src/lib/components/node-context-menu.d.ts +25 -0
- package/src/lib/components/node-context-menu.js +558 -0
- package/src/lib/components/node-context-menu.js.map +1 -0
- package/src/lib/components/node-leaf.d.ts +39 -0
- package/src/lib/components/node-leaf.js +628 -0
- package/src/lib/components/node-leaf.js.map +1 -0
- package/src/lib/components/node-outline.d.ts +24 -0
- package/src/lib/components/node-outline.js +156 -0
- package/src/lib/components/node-outline.js.map +1 -0
- package/src/lib/components/node-overlay.d.ts +23 -0
- package/src/lib/components/node-overlay.js +299 -0
- package/src/lib/components/node-overlay.js.map +1 -0
- package/src/lib/components/node-quick-actions.d.ts +24 -0
- package/src/lib/components/node-quick-actions.js +284 -0
- package/src/lib/components/node-quick-actions.js.map +1 -0
- package/src/lib/components/node-tree-view.d.ts +106 -0
- package/src/lib/components/node-tree-view.js +820 -0
- package/src/lib/components/node-tree-view.js.map +1 -0
- package/src/lib/components/panel-controls.component.d.ts +22 -0
- package/src/lib/components/panel-controls.component.js +76 -0
- package/src/lib/components/panel-controls.component.js.map +1 -0
- package/src/lib/components/picker-search-field.d.ts +38 -0
- package/src/lib/components/picker-search-field.js +79 -0
- package/src/lib/components/picker-search-field.js.map +1 -0
- package/src/lib/components/plugin-settings-field.component.d.ts +38 -0
- package/src/lib/components/plugin-settings-field.component.js +264 -0
- package/src/lib/components/plugin-settings-field.component.js.map +1 -0
- package/src/lib/components/properties-dialog.component.d.ts +22 -0
- package/src/lib/components/properties-dialog.component.js +40 -0
- package/src/lib/components/properties-dialog.component.js.map +1 -0
- package/src/lib/components/property-binding-field.component.d.ts +142 -0
- package/src/lib/components/property-binding-field.component.js +325 -0
- package/src/lib/components/property-binding-field.component.js.map +1 -0
- package/src/lib/components/property-values-form.component.d.ts +43 -0
- package/src/lib/components/property-values-form.component.js +223 -0
- package/src/lib/components/property-values-form.component.js.map +1 -0
- package/src/lib/components/scheme-preview-controls.component.d.ts +26 -0
- package/src/lib/components/scheme-preview-controls.component.js +56 -0
- package/src/lib/components/scheme-preview-controls.component.js.map +1 -0
- package/src/lib/components/screen-link-field.component.d.ts +118 -0
- package/src/lib/components/screen-link-field.component.js +282 -0
- package/src/lib/components/screen-link-field.component.js.map +1 -0
- package/src/lib/components/site-theme-color-tokens-provider.component.d.ts +33 -0
- package/src/lib/components/site-theme-color-tokens-provider.component.js +53 -0
- package/src/lib/components/site-theme-color-tokens-provider.component.js.map +1 -0
- package/src/lib/components/subtree-json-dialog.component.d.ts +46 -0
- package/src/lib/components/subtree-json-dialog.component.js +125 -0
- package/src/lib/components/subtree-json-dialog.component.js.map +1 -0
- package/src/lib/components/token-pill.component.d.ts +51 -0
- package/src/lib/components/token-pill.component.js +164 -0
- package/src/lib/components/token-pill.component.js.map +1 -0
- package/src/lib/components/token-text-field.component.d.ts +146 -0
- package/src/lib/components/token-text-field.component.js +603 -0
- package/src/lib/components/token-text-field.component.js.map +1 -0
- package/src/lib/components/tree/tree-list.d.ts +6 -0
- package/src/lib/components/tree/tree-list.js +108 -0
- package/src/lib/components/tree/tree-list.js.map +1 -0
- package/src/lib/components/viewport-canvas.component.d.ts +23 -0
- package/src/lib/components/viewport-canvas.component.js +128 -0
- package/src/lib/components/viewport-canvas.component.js.map +1 -0
- package/src/lib/components/viewport-frame.component.d.ts +47 -0
- package/src/lib/components/viewport-frame.component.js +332 -0
- package/src/lib/components/viewport-frame.component.js.map +1 -0
- package/src/lib/components/viewport-root.component.d.ts +22 -0
- package/src/lib/components/viewport-root.component.js +112 -0
- package/src/lib/components/viewport-root.component.js.map +1 -0
- package/src/lib/components/viewport-zoom-controls.d.ts +29 -0
- package/src/lib/components/viewport-zoom-controls.js +147 -0
- package/src/lib/components/viewport-zoom-controls.js.map +1 -0
- package/src/lib/components/workspace-editor.component.d.ts +23 -0
- package/src/lib/components/workspace-editor.component.js +191 -0
- package/src/lib/components/workspace-editor.component.js.map +1 -0
- package/src/lib/components/workspace-panel.component.d.ts +28 -0
- package/src/lib/components/workspace-panel.component.js +147 -0
- package/src/lib/components/workspace-panel.component.js.map +1 -0
- package/src/lib/constants/sample-data.d.ts +18 -0
- package/src/lib/constants/sample-data.js +106 -0
- package/src/lib/constants/sample-data.js.map +1 -0
- package/src/lib/constants/shared.d.ts +17 -0
- package/src/lib/constants/shared.js +18 -0
- package/src/lib/constants/shared.js.map +1 -0
- package/src/lib/contexts/besigner-app-context.d.ts +30 -0
- package/src/lib/contexts/besigner-app-context.js +41 -0
- package/src/lib/contexts/besigner-app-context.js.map +1 -0
- package/src/lib/contexts/binding-picker-context.d.ts +78 -0
- package/src/lib/contexts/binding-picker-context.js +21 -0
- package/src/lib/contexts/binding-picker-context.js.map +1 -0
- package/src/lib/contexts/canvas-host-tokens-context.d.ts +49 -0
- package/src/lib/contexts/canvas-host-tokens-context.js +63 -0
- package/src/lib/contexts/canvas-host-tokens-context.js.map +1 -0
- package/src/lib/contexts/canvas-reveal-context.d.ts +32 -0
- package/src/lib/contexts/canvas-reveal-context.js +34 -0
- package/src/lib/contexts/canvas-reveal-context.js.map +1 -0
- package/src/lib/contexts/component-promotion-context.d.ts +89 -0
- package/src/lib/contexts/component-promotion-context.js +21 -0
- package/src/lib/contexts/component-promotion-context.js.map +1 -0
- package/src/lib/contexts/components-drawer-context.provider.d.ts +32 -0
- package/src/lib/contexts/components-drawer-context.provider.js +80 -0
- package/src/lib/contexts/components-drawer-context.provider.js.map +1 -0
- package/src/lib/contexts/element-drawer-context.d.ts +1005 -0
- package/src/lib/contexts/element-drawer-context.js +45 -0
- package/src/lib/contexts/element-drawer-context.js.map +1 -0
- package/src/lib/contexts/inspected-selection.d.ts +32 -0
- package/src/lib/contexts/inspected-selection.js +38 -0
- package/src/lib/contexts/inspected-selection.js.map +1 -0
- package/src/lib/contexts/inspector-extras-context.d.ts +56 -0
- package/src/lib/contexts/inspector-extras-context.js +35 -0
- package/src/lib/contexts/inspector-extras-context.js.map +1 -0
- package/src/lib/contexts/interactions-context.d.ts +99 -0
- package/src/lib/contexts/interactions-context.js +22 -0
- package/src/lib/contexts/interactions-context.js.map +1 -0
- package/src/lib/contexts/layout-chrome-context.d.ts +37 -0
- package/src/lib/contexts/layout-chrome-context.js +75 -0
- package/src/lib/contexts/layout-chrome-context.js.map +1 -0
- package/src/lib/contexts/media-asset-facts-context.d.ts +74 -0
- package/src/lib/contexts/media-asset-facts-context.js +27 -0
- package/src/lib/contexts/media-asset-facts-context.js.map +1 -0
- package/src/lib/contexts/media-picker-context.d.ts +88 -0
- package/src/lib/contexts/media-picker-context.js +21 -0
- package/src/lib/contexts/media-picker-context.js.map +1 -0
- package/src/lib/contexts/rendered-canvas-elements.d.ts +42 -0
- package/src/lib/contexts/rendered-canvas-elements.js +79 -0
- package/src/lib/contexts/rendered-canvas-elements.js.map +1 -0
- package/src/lib/contexts/repeat-record-context.d.ts +38 -0
- package/src/lib/contexts/repeat-record-context.js +21 -0
- package/src/lib/contexts/repeat-record-context.js.map +1 -0
- package/src/lib/contexts/repeat-rows-context.d.ts +53 -0
- package/src/lib/contexts/repeat-rows-context.js +38 -0
- package/src/lib/contexts/repeat-rows-context.js.map +1 -0
- package/src/lib/contexts/toolbar-extras-context.d.ts +31 -0
- package/src/lib/contexts/toolbar-extras-context.js +33 -0
- package/src/lib/contexts/toolbar-extras-context.js.map +1 -0
- package/src/lib/drafts/besigner-draft-store.d.ts +110 -0
- package/src/lib/drafts/besigner-draft-store.js +125 -0
- package/src/lib/drafts/besigner-draft-store.js.map +1 -0
- package/src/lib/drafts/besigner-server-draft.d.ts +130 -0
- package/src/lib/drafts/besigner-server-draft.js +211 -0
- package/src/lib/drafts/besigner-server-draft.js.map +1 -0
- package/src/lib/form-fields/components/shared/inline-form-control.d.ts +32 -0
- package/src/lib/form-fields/components/shared/inline-form-control.js +85 -0
- package/src/lib/form-fields/components/shared/inline-form-control.js.map +1 -0
- package/src/lib/form-fields/components/shared/toggle-button-form-control.d.ts +33 -0
- package/src/lib/form-fields/components/shared/toggle-button-form-control.js +83 -0
- package/src/lib/form-fields/components/shared/toggle-button-form-control.js.map +1 -0
- package/src/lib/form-fields/form-fields.d.ts +20 -0
- package/src/lib/form-fields/form-fields.js +21 -0
- package/src/lib/form-fields/form-fields.js.map +1 -0
- package/src/lib/form-fields/index.d.ts +1 -0
- package/src/lib/form-fields/index.js +3 -0
- package/src/lib/form-fields/index.js.map +1 -0
- package/src/lib/hooks/use-add-element-drawer-callback.d.ts +28 -0
- package/src/lib/hooks/use-add-element-drawer-callback.js +112 -0
- package/src/lib/hooks/use-add-element-drawer-callback.js.map +1 -0
- package/src/lib/hooks/use-aglyn-besigner-flag.d.ts +23 -0
- package/src/lib/hooks/use-aglyn-besigner-flag.js +47 -0
- package/src/lib/hooks/use-aglyn-besigner-flag.js.map +1 -0
- package/src/lib/hooks/use-aglyn-besigner-panel-value.d.ts +23 -0
- package/src/lib/hooks/use-aglyn-besigner-panel-value.js +54 -0
- package/src/lib/hooks/use-aglyn-besigner-panel-value.js.map +1 -0
- package/src/lib/hooks/use-aglyn-besigner-panel.d.ts +23 -0
- package/src/lib/hooks/use-aglyn-besigner-panel.js +47 -0
- package/src/lib/hooks/use-aglyn-besigner-panel.js.map +1 -0
- package/src/lib/hooks/use-anchored-rect.d.ts +68 -0
- package/src/lib/hooks/use-anchored-rect.js +131 -0
- package/src/lib/hooks/use-anchored-rect.js.map +1 -0
- package/src/lib/hooks/use-besigner-app-context.d.ts +18 -0
- package/src/lib/hooks/use-besigner-app-context.js +19 -0
- package/src/lib/hooks/use-besigner-app-context.js.map +1 -0
- package/src/lib/hooks/use-besigner-document.d.ts +309 -0
- package/src/lib/hooks/use-besigner-document.js +500 -0
- package/src/lib/hooks/use-besigner-document.js.map +1 -0
- package/src/lib/hooks/use-besigner-draft.d.ts +209 -0
- package/src/lib/hooks/use-besigner-draft.js +429 -0
- package/src/lib/hooks/use-besigner-draft.js.map +1 -0
- package/src/lib/hooks/use-clipboard-callbacks.d.ts +29 -0
- package/src/lib/hooks/use-clipboard-callbacks.js +82 -0
- package/src/lib/hooks/use-clipboard-callbacks.js.map +1 -0
- package/src/lib/hooks/use-clipboard-shortcuts.d.ts +52 -0
- package/src/lib/hooks/use-clipboard-shortcuts.js +102 -0
- package/src/lib/hooks/use-clipboard-shortcuts.js.map +1 -0
- package/src/lib/hooks/use-component-propagation-notice.d.ts +96 -0
- package/src/lib/hooks/use-component-propagation-notice.js +177 -0
- package/src/lib/hooks/use-component-propagation-notice.js.map +1 -0
- package/src/lib/hooks/use-debounced-commit.d.ts +43 -0
- package/src/lib/hooks/use-debounced-commit.js +88 -0
- package/src/lib/hooks/use-debounced-commit.js.map +1 -0
- package/src/lib/hooks/use-delete-element-callback.d.ts +24 -0
- package/src/lib/hooks/use-delete-element-callback.js +82 -0
- package/src/lib/hooks/use-delete-element-callback.js.map +1 -0
- package/src/lib/hooks/use-detail-hover-intent.d.ts +76 -0
- package/src/lib/hooks/use-detail-hover-intent.js +123 -0
- package/src/lib/hooks/use-detail-hover-intent.js.map +1 -0
- package/src/lib/hooks/use-document-repair-callbacks.d.ts +50 -0
- package/src/lib/hooks/use-document-repair-callbacks.js +237 -0
- package/src/lib/hooks/use-document-repair-callbacks.js.map +1 -0
- package/src/lib/hooks/use-insert-token-options.d.ts +52 -0
- package/src/lib/hooks/use-insert-token-options.js +230 -0
- package/src/lib/hooks/use-insert-token-options.js.map +1 -0
- package/src/lib/hooks/use-leaf-drag.d.ts +24 -0
- package/src/lib/hooks/use-leaf-drag.js +28 -0
- package/src/lib/hooks/use-leaf-drag.js.map +1 -0
- package/src/lib/hooks/use-leaf-drop.d.ts +31 -0
- package/src/lib/hooks/use-leaf-drop.js +43 -0
- package/src/lib/hooks/use-leaf-drop.js.map +1 -0
- package/src/lib/hooks/use-markdown-media-picker.d.ts +63 -0
- package/src/lib/hooks/use-markdown-media-picker.js +110 -0
- package/src/lib/hooks/use-markdown-media-picker.js.map +1 -0
- package/src/lib/hooks/use-media-asset-facts-overlay.d.ts +43 -0
- package/src/lib/hooks/use-media-asset-facts-overlay.js +133 -0
- package/src/lib/hooks/use-media-asset-facts-overlay.js.map +1 -0
- package/src/lib/hooks/use-move-node-callbacks.d.ts +22 -0
- package/src/lib/hooks/use-move-node-callbacks.js +57 -0
- package/src/lib/hooks/use-move-node-callbacks.js.map +1 -0
- package/src/lib/hooks/use-node-with-host-tokens.d.ts +42 -0
- package/src/lib/hooks/use-node-with-host-tokens.js +59 -0
- package/src/lib/hooks/use-node-with-host-tokens.js.map +1 -0
- package/src/lib/hooks/use-picker-filter.d.ts +61 -0
- package/src/lib/hooks/use-picker-filter.js +122 -0
- package/src/lib/hooks/use-picker-filter.js.map +1 -0
- package/src/lib/hooks/use-repeat-preview.d.ts +64 -0
- package/src/lib/hooks/use-repeat-preview.js +214 -0
- package/src/lib/hooks/use-repeat-preview.js.map +1 -0
- package/src/lib/hooks/use-repeat-sources.d.ts +17 -0
- package/src/lib/hooks/use-repeat-sources.js +41 -0
- package/src/lib/hooks/use-repeat-sources.js.map +1 -0
- package/src/lib/hooks/use-visible-component-categories.d.ts +37 -0
- package/src/lib/hooks/use-visible-component-categories.js +79 -0
- package/src/lib/hooks/use-visible-component-categories.js.map +1 -0
- package/src/lib/utils/active-host-theme.d.ts +28 -0
- package/src/lib/utils/active-host-theme.js +77 -0
- package/src/lib/utils/active-host-theme.js.map +1 -0
- package/src/lib/utils/attr-target.d.ts +170 -0
- package/src/lib/utils/attr-target.js +229 -0
- package/src/lib/utils/attr-target.js.map +1 -0
- package/src/lib/utils/attribute-field-value.d.ts +21 -0
- package/src/lib/utils/attribute-field-value.js +28 -0
- package/src/lib/utils/attribute-field-value.js.map +1 -0
- package/src/lib/utils/canvas-context-menu.d.ts +28 -0
- package/src/lib/utils/canvas-context-menu.js +56 -0
- package/src/lib/utils/canvas-context-menu.js.map +1 -0
- package/src/lib/utils/canvas-reveal.d.ts +115 -0
- package/src/lib/utils/canvas-reveal.js +165 -0
- package/src/lib/utils/canvas-reveal.js.map +1 -0
- package/src/lib/utils/describe-element.d.ts +72 -0
- package/src/lib/utils/describe-element.js +159 -0
- package/src/lib/utils/describe-element.js.map +1 -0
- package/src/lib/utils/device-preview-styles.d.ts +89 -0
- package/src/lib/utils/device-preview-styles.js +228 -0
- package/src/lib/utils/device-preview-styles.js.map +1 -0
- package/src/lib/utils/docs-help.d.ts +22 -0
- package/src/lib/utils/docs-help.generated.d.ts +47 -0
- package/src/lib/utils/docs-help.generated.js +229 -0
- package/src/lib/utils/docs-help.generated.js.map +1 -0
- package/src/lib/utils/docs-help.js +37 -0
- package/src/lib/utils/docs-help.js.map +1 -0
- package/src/lib/utils/held-answers-store.d.ts +59 -0
- package/src/lib/utils/held-answers-store.js +94 -0
- package/src/lib/utils/held-answers-store.js.map +1 -0
- package/src/lib/utils/in-place-edit-surface.d.ts +118 -0
- package/src/lib/utils/in-place-edit-surface.js +164 -0
- package/src/lib/utils/in-place-edit-surface.js.map +1 -0
- package/src/lib/utils/inline-markdown-edit.store.d.ts +71 -0
- package/src/lib/utils/inline-markdown-edit.store.js +90 -0
- package/src/lib/utils/inline-markdown-edit.store.js.map +1 -0
- package/src/lib/utils/inline-text-edit.store.d.ts +85 -0
- package/src/lib/utils/inline-text-edit.store.js +78 -0
- package/src/lib/utils/inline-text-edit.store.js.map +1 -0
- package/src/lib/utils/instance-leaf-hit.d.ts +39 -0
- package/src/lib/utils/instance-leaf-hit.js +56 -0
- package/src/lib/utils/instance-leaf-hit.js.map +1 -0
- package/src/lib/utils/muted-classes.d.ts +76 -0
- package/src/lib/utils/muted-classes.js +108 -0
- package/src/lib/utils/muted-classes.js.map +1 -0
- package/src/lib/utils/muted-styles.d.ts +125 -0
- package/src/lib/utils/muted-styles.js +193 -0
- package/src/lib/utils/muted-styles.js.map +1 -0
- package/src/lib/utils/numeric-text-value.d.ts +42 -0
- package/src/lib/utils/numeric-text-value.js +47 -0
- package/src/lib/utils/numeric-text-value.js.map +1 -0
- package/src/lib/utils/preset-interactions.d.ts +37 -0
- package/src/lib/utils/preset-interactions.js +87 -0
- package/src/lib/utils/preset-interactions.js.map +1 -0
- package/src/lib/utils/publish-failure-message.d.ts +35 -0
- package/src/lib/utils/publish-failure-message.js +51 -0
- package/src/lib/utils/publish-failure-message.js.map +1 -0
- package/src/lib/utils/rank-picker-results.d.ts +45 -0
- package/src/lib/utils/rank-picker-results.js +136 -0
- package/src/lib/utils/rank-picker-results.js.map +1 -0
- package/src/lib/utils/responsive-sx.d.ts +65 -0
- package/src/lib/utils/responsive-sx.js +129 -0
- package/src/lib/utils/responsive-sx.js.map +1 -0
- package/src/lib/utils/rich-text-commands.d.ts +28 -0
- package/src/lib/utils/rich-text-commands.js +43 -0
- package/src/lib/utils/rich-text-commands.js.map +1 -0
- package/src/lib/utils/sanitize-rich-text.d.ts +52 -0
- package/src/lib/utils/sanitize-rich-text.js +173 -0
- package/src/lib/utils/sanitize-rich-text.js.map +1 -0
- package/src/lib/utils/state-sx.d.ts +255 -0
- package/src/lib/utils/state-sx.js +338 -0
- package/src/lib/utils/state-sx.js.map +1 -0
- package/src/lib/utils/style-field-groups.d.ts +136 -0
- package/src/lib/utils/style-field-groups.js +874 -0
- package/src/lib/utils/style-field-groups.js.map +1 -0
- package/src/lib/utils/style-field-search.d.ts +84 -0
- package/src/lib/utils/style-field-search.js +505 -0
- package/src/lib/utils/style-field-search.js.map +1 -0
- package/src/lib/utils/style-target.d.ts +69 -0
- package/src/lib/utils/style-target.js +203 -0
- package/src/lib/utils/style-target.js.map +1 -0
- package/src/lib/utils/theme-scale-options.d.ts +169 -0
- package/src/lib/utils/theme-scale-options.js +702 -0
- package/src/lib/utils/theme-scale-options.js.map +1 -0
- package/src/lib/utils/token-editable-dom.d.ts +82 -0
- package/src/lib/utils/token-editable-dom.js +280 -0
- package/src/lib/utils/token-editable-dom.js.map +1 -0
- package/src/lib/utils/token-segments.d.ts +111 -0
- package/src/lib/utils/token-segments.js +246 -0
- package/src/lib/utils/token-segments.js.map +1 -0
- package/src/lib/utils/visibility-styles.d.ts +38 -0
- package/src/lib/utils/visibility-styles.js +54 -0
- package/src/lib/utils/visibility-styles.js.map +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/besigner/feature/designer/src/lib/components/node-leaf.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2023 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 {\n buildComponentDefaultIconPaths,\n buildComponentDefaultTokens,\n buildComponentDefaultValues,\n composeReusableComponentNodes,\n displayBindingTokens,\n FORM_COMPONENT_ID,\n hasBindings,\n HostViewType,\n LAYOUT_SLOT_COMPONENT_ID,\n NODE_ROOT_ID,\n placedFormPlacement,\n resolveBindings,\n resolveComponentPropTokens,\n REUSABLE_INSTANCE_COMPONENT_ID,\n} from '@aglyn/aglyn'\nimport {\n Branch,\n Leaf,\n type LeafProps,\n RendererComponents,\n Stem,\n Trunk,\n} from '@aglyn/aglyn-node-renderer'\nimport * as Besigner from '@aglyn/besigner'\nimport { alpha, Box } from '@mui/material'\nimport { observer } from 'mobx-react-lite'\nimport { forwardRef, useCallback, useContext, useMemo, useRef } from 'react'\nimport BindingPickerContext from '../contexts/binding-picker-context'\nimport CanvasRevealContext, {\n CanvasMutedClassesContext,\n} from '../contexts/canvas-reveal-context'\nimport ComponentPromotionContext from '../contexts/component-promotion-context'\nimport { useRenderedCanvasElements } from '../contexts/rendered-canvas-elements'\nimport useAglynBesignerFlag from '../hooks/use-aglyn-besigner-flag'\nimport { useNodeWithMediaAssetFacts } from '../hooks/use-media-asset-facts-overlay'\nimport useNodeWithHostTokens from '../hooks/use-node-with-host-tokens'\nimport {\n useNodeWithRepeatRecord,\n useRepeatCopies,\n useRepeatPreview,\n} from '../hooks/use-repeat-preview'\nimport { RepeatRecordContext } from '../contexts/repeat-record-context'\nimport {\n isNodeHiddenOnSite,\n isNodeRevealedOnCanvas,\n} from '../utils/canvas-reveal'\nimport { stripMutedClasses } from '../utils/muted-classes'\nimport DraggableDroppable from './dnd/draggable-droppable'\nimport EmptyDocumentSlot from './empty-document-slot'\n\n/**\n * The plain `Leaf`, drawing a node the way the published page composes it: its\n * host variables filled in from the site being edited (AGL-2881), and a placed\n * image or film with its DAM asset's current facts (AGL-2838, AGL-2856).\n *\n * For the nodes the canvas renders that are not canvas nodes — a component\n * instance's definition, a placed form's design, the layout chrome — and so\n * never reach `NodeLeaf`. A footer's `{{host.businessName}}` still has to read\n * as the site's name, an asset inside one of them still has to show the shape\n * the published page gives it, and a film its poster.\n */\nexport const MediaFactsLeaf = forwardRef<any, LeafProps>((props, ref) => {\n const { node, ...rest } = props\n const withHostTokens = useNodeWithHostTokens(node)\n const withRecord = useNodeWithRepeatRecord(withHostTokens)\n const shown = useNodeWithMediaAssetFacts(withRecord)\n return <Leaf ref={ref} node={shown} {...rest} />\n})\nMediaFactsLeaf.displayName = 'MediaFactsLeaf'\n\n/**\n * Renderer overrides for the inside of a component instance (AGL-1251).\n *\n * The plain `Leaf` (through `MediaFactsLeaf`), deliberately, where the canvas\n * otherwise uses `NodeLeaf`: the definition's nodes are NOT in the canvas, so\n * anything that made them draggable, selectable or droppable would be reaching\n * for canvas state that has no entry for them. Rendering them inert is not a\n * restriction bolted on afterwards — it is the only thing these nodes can be.\n */\nconst INERT_RENDERER = {\n TrunkComponent: Trunk,\n StemComponent: Stem,\n BranchComponent: Branch,\n LeafComponent: MediaFactsLeaf,\n}\n\n/**\n * Nested-object form of a normalized node map, which is what `Branch` walks\n * (`node.children`). Cycle-safe via `seen`: a definition that somehow\n * referenced an ancestor would otherwise recurse until the stack gave out.\n */\nexport function denormalizeTree(\n nodes: Record<string, any>,\n rootId: string,\n seen: Set<string> = new Set(),\n): any {\n const node = nodes?.[rootId]\n if (!node || seen.has(rootId)) return undefined\n seen.add(rootId)\n const childIds = Array.isArray(node.nodes) ? node.nodes : []\n return {\n ...node,\n children: childIds\n .map((childId: string) => denormalizeTree(nodes, childId, seen))\n .filter(Boolean),\n }\n}\n\nexport interface NodeLeafProps extends LeafProps {}\n\n/**\n * The slot marker is EDITOR CHROME, so it holds the brand accent literally\n * rather than reading `secondary` from the theme: the canvas renders under\n * the host's palette, so a token would repaint the editor's own furniture\n * whenever a subscriber restyles their site — and it already rendered pink\n * instead of the design's blue.\n */\nconst SLOT_ACCENT = '#00B0FF'\n\n/**\n * Visible placement marker for the LayoutSlot while editing a layout. The\n * slot is a passthrough at runtime, so without this it disappears once it\n * has children and designers lose track of where screen content lands.\n */\nconst SlotMarker = ({ caption }: { caption?: string }) => (\n <Box\n aria-hidden\n data-aglyn-slot-marker=\"\"\n sx={{\n m: 1,\n p: 2,\n minHeight: 64,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 0.5,\n borderWidth: 2,\n borderStyle: 'dashed',\n // Brand blue on a faint tint, not a grey dashed box: the slot is the\n // one region the layout does not own, and it should not read as just\n // another empty container.\n borderColor: SLOT_ACCENT,\n backgroundColor: alpha(SLOT_ACCENT, 0.06),\n borderRadius: 1,\n color: 'text.secondary',\n fontSize: 13,\n textAlign: 'center',\n }}\n >\n <Box component=\"span\" sx={{ color: SLOT_ACCENT, fontWeight: 700 }}>\n {'◇ layout-slot'}\n </Box>\n <Box component=\"span\">{caption || 'Screen content renders here'}</Box>\n </Box>\n)\n\n/**\n * The repeat badge (AGL-3111).\n *\n * Editor chrome, so it holds its accent literally for the reason\n * {@link SLOT_ACCENT} does: the canvas renders under the SITE's palette, and a\n * theme token here would repaint the editor's own furniture whenever a\n * subscriber restyled their site.\n *\n * It cannot reach a published page: only `NodeLeaf` draws it, and a published\n * page is composed from stored nodes and rendered through the plain `Leaf`.\n * The stored node is untouched either way — this is a render copy, like every\n * other thing the canvas lays over a node.\n */\nconst REPEAT_ACCENT = '#7C4DFF'\n\n/** The chip's own ink, for the same reason and read against that accent. */\nconst REPEAT_INK = '#FFFFFF'\n\nconst RepeatBadge = ({ label, count }: { label: string; count: number }) => (\n <Box\n aria-hidden\n data-aglyn-repeat-badge=\"\"\n sx={{\n // Out of the element's own layout: a badge that took part in a flex row\n // would move the design it is describing.\n position: 'absolute',\n top: 0,\n right: 0,\n zIndex: 2,\n // Never swallows a click — the element under it stays selectable.\n pointerEvents: 'none',\n px: 0.75,\n py: 0.25,\n maxWidth: '100%',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n borderBottomLeftRadius: 3,\n backgroundColor: REPEAT_ACCENT,\n color: REPEAT_INK,\n fontSize: 11,\n fontWeight: 700,\n lineHeight: 1.6,\n letterSpacing: 0.2,\n }}\n >\n {`⟳ ${label} · ${count} ${count === 1 ? 'record' : 'records'}`}\n </Box>\n)\n\nexport const NodeLeaf = observer(\n forwardRef<any, NodeLeafProps>((props, ref) => {\n const { node, children, ...rest } = props\n const [viewType] = useAglynBesignerFlag('viewType')\n // The canvas element registry, finally given a WRITER (AGL-2486).\n //\n // `RenderedCanvasElementsProvider` has existed since the registry was\n // introduced and `setElementRef`/`deleteElementRef` were called from\n // NOWHERE in the repo — `elements.current` was `{}` for the life of every\n // session. Everything that reads it therefore read an empty map and\n // failed the only way an empty map can: silently.\n //\n // Two features were void because of it, and neither logged anything:\n //\n // `usePresence`'s cursor broadcast resolves the canvas root through\n // this registry and bails with `if (!root) return`, so no editor has\n // EVER written a cursor position. Confirmed against production RTDB on\n // 2026-08-22: three live presence entries across three rooms, not one\n // carrying `cursorX`/`cursorY`.\n //\n // `CollaboratorOverlays` resolves both the canvas root and each peer's\n // selected node here, so `placements` was always empty and the overlay\n // returned null. Confirmed live in the running console: a collaborator\n // entry carrying both a cursor and a selection rendered its avatar and\n // drew no cursor, no selection box and no name label.\n //\n // Registering here rather than in the renderer keeps it to the canvas:\n // `NodeLeaf` is the besigner's leaf component, so component-definition\n // previews (which render the plain `Leaf` through `INERT_RENDERER`) stay\n // out of the registry — they are not in the canvas and must not be\n // addressable as though they were.\n //\n // `NODE_ROOT_ID` and `CANVAS_ROOT_ELEMENT_ID` are the same string\n // (`'_@_'`), so keying on `$id` registers the canvas root under the id\n // the cursor code already looks for, with no special case.\n const { elements, setElementRef, deleteElementRef } =\n useRenderedCanvasElements()\n const $id = node?.$id\n // What THIS leaf last put in the registry. A remount can hand the new\n // element its ref before the old one is cleared, so an unconditional\n // delete on `null` would evict the live registration and put the\n // registry back to the state this whole change exists to fix.\n const registered = useRef<Element | null>(null)\n const registerElement = useCallback(\n (element: unknown) => {\n // Forward FIRST and unconditionally: dnd and the renderer already\n // depend on this ref, and registration must never change what they\n // observe.\n if (typeof ref === 'function') ref(element)\n else if (ref) (ref as { current: unknown }).current = element\n if (!$id) return\n if (element instanceof Element) {\n registered.current = element\n setElementRef($id, {\n $id,\n node: element,\n dragHandle: undefined,\n } as never)\n return\n }\n // Cleared (or never a DOM element — a class instance, say). Only\n // withdraw the registration if it is still OURS.\n const current = elements?.current?.[$id]?.node\n if (!registered.current || current === registered.current) {\n deleteElementRef($id)\n }\n registered.current = null\n },\n [ref, $id, elements, setElementRef, deleteElementRef],\n )\n const showSlotMarker =\n node?.componentId === LAYOUT_SLOT_COMPONENT_ID &&\n viewType === HostViewType.LAYOUT\n // A document with no nodes has nothing to aim at. Wrapped in a shared\n // layout it is worse than empty — the slot passes its children straight\n // through, so the root collapses to a zero-height strip between locked\n // chrome and the nav renders directly into the footer. Hung off the ROOT\n // leaf, which is already inside `DraggableDroppable`, so giving it height\n // is all a drop needs to resolve against the document root.\n const showEmptyDocumentSlot =\n node?.$id === NODE_ROOT_ID &&\n !node?.nodes?.length &&\n viewType !== HostViewType.LAYOUT\n\n // Nodes the author has opened up for designing (AGL-592). Through a\n // context rather than the flag itself: the canvas subscribes once and\n // every leaf reads the result.\n const revealedNodeIds = useContext(CanvasRevealContext)\n const mutedClasses = useContext(CanvasMutedClassesContext)\n\n // WYSIWYG bindings (AGL-97): resolve variable/function tokens\n // live on the rendered copy (selection/dnd keep the original node).\n // Bound nodes are flagged either way so editors can spot them.\n const [resolveFlag] = useAglynBesignerFlag('resolveBindings')\n const { variables, functions, componentProps } = useContext(\n BindingPickerContext,\n )\n const boundProps = useMemo(\n () =>\n Object.entries(node?.props ?? {}).filter(\n ([, value]) => typeof value === 'string' && hasBindings(value),\n ),\n // MobX props are observable; the JSON string keys the memo cheaply.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [node, JSON.stringify(node?.props ?? {})],\n )\n /**\n * A component editor draws with the definition's OWN defaults\n * (AGL-2870), so `{{prop.headline}}` shows the headline and a film with a\n * default source actually plays.\n *\n * Only props that HAVE a default are substituted. One without stays a\n * visible token, which is the signal an author needs: the slot is real\n * and nothing fills it yet. Substituting `''` there would draw an empty\n * component and hide the very thing they still have to decide.\n *\n * On a screen this path does nothing — the props belong to the component\n * route, and an instance is composed through `composeReusableComponentNodes`\n * below, which is the single substitution path a published page uses.\n */\n const defaultPropTokens = useMemo(\n () => buildComponentDefaultTokens(componentProps),\n [componentProps],\n )\n // The paths of the default icons, which a field bound to an icon property\n // draws with — the editor has no reason to have loaded the icon catalog.\n const defaultIconPaths = useMemo(\n () => buildComponentDefaultIconPaths(componentProps),\n [componentProps],\n )\n // The values the defaults hand their bound fields (AGL-2893), so a list\n // stays a list and a theme multiple a number on the editor's canvas too.\n const defaultValues = useMemo(\n () => buildComponentDefaultValues(componentProps),\n [componentProps],\n )\n const renderNode = useMemo(() => {\n const hasDeclaredProps = Boolean(componentProps?.length)\n if (\n !boundProps.length ||\n (!Object.keys(variables ?? {}).length &&\n !Object.keys(functions ?? {}).length &&\n !hasDeclaredProps)\n ) {\n return node\n }\n const resolved: Record<string, unknown> = { ...(node?.props ?? {}) }\n for (const [key, value] of boundProps) {\n // Resolve toggle off → show friendly token text: id tokens map to\n // the referent's CURRENT name (AGL-186), never raw doc ids.\n resolved[key] =\n resolveFlag === false\n ? displayBindingTokens(\n value as string,\n (variables ?? {}) as any,\n (functions ?? {}) as any,\n )\n : resolveBindings(\n value as string,\n (variables ?? {}) as any,\n (functions ?? {}) as any,\n )\n }\n const next = { ...node, props: resolved }\n if (!hasDeclaredProps) return next\n // Through the same substitution a placed instance uses, keyed by this\n // node alone — one code path deciding what a token becomes, never two\n // that could disagree.\n //\n // The raw-token view substitutes no defaults: an author who turned\n // resolution OFF asked to see the tokens, and a default is a resolved\n // value like any other. A field bound to a Yes/no property still\n // receives a yes or a no there, because a switch has no way to show a\n // token and reads the token's text as a yes.\n return (\n resolveComponentPropTokens(\n { [String(node?.$id)]: next as any },\n componentProps,\n resolveFlag === false ? undefined : defaultPropTokens,\n resolveFlag === false ? undefined : defaultIconPaths,\n resolveFlag === false ? undefined : defaultValues,\n )[String(node?.$id)] ?? next\n )\n }, [\n node,\n boundProps,\n resolveFlag,\n variables,\n functions,\n componentProps,\n defaultPropTokens,\n defaultIconPaths,\n defaultValues,\n ])\n\n // Host variables (AGL-2881), filled in on the same render copy and after\n // the bindings and the component's own defaults, which is the order the\n // published page composes in: a default that names the host resolves\n // too. The raw-token view reaches this leaf as no site at all\n // (`CanvasHostTokensProvider`), so its tokens stay as written. Keyed by\n // `boundProps`, which follows the observable props this copy reads.\n const hostResolvedNode = useNodeWithHostTokens(renderNode, boundProps)\n\n // Classes switched off for comparison (AGL-2486). Composed onto the SAME\n // render copy the binding resolution builds, never onto the canvas node:\n // selection, the hierarchy and every save keep reading the element's real\n // class list, and the canvas paints without the switched-off names.\n const renderNodeUnclassed = useMemo(\n () =>\n stripMutedClasses(hostResolvedNode as never, node?.$id, mutedClasses),\n [hostResolvedNode, node, mutedClasses],\n )\n\n /**\n * The record a repeat above this one is drawing (AGL-3111).\n *\n * Applied in the same place, and for the same reason, as the host tokens\n * and the DAM facts above: the published page substitutes `{{item.*}}`\n * when it composes, so the canvas substitutes it on the render copy while\n * the node keeps the tokens every save writes.\n */\n const withRepeatRecord = useNodeWithRepeatRecord(renderNodeUnclassed)\n\n // A placed asset's shape, and a film's length and poster, as its DAM\n // document records them NOW (AGL-2838, AGL-2856). The published page lays\n // the asset over the node when it is composed, so the canvas lays it over\n // the same render copy: a replace shows here as it shows to a visitor,\n // while selection, the panels and every save keep reading the node's\n // stored props.\n const shownNode = useNodeWithMediaAssetFacts(withRepeatRecord)\n\n /**\n * What this element repeats over, and the copies it draws (AGL-3111).\n *\n * The first record's copy is the element's own children — real canvas\n * nodes an author selects, drags and edits — with that record laid over\n * their render copies through {@link RepeatRecordContext}. Records 2..n\n * are inert pictures of the same template, built by the page's own\n * expansion. Editing the template therefore edits every copy, because\n * there is only ever one.\n */\n const repeatPreview = useRepeatPreview(node)\n const repeatCopies = useRepeatCopies(node, repeatPreview)\n const firstRecord = useMemo(\n () =>\n repeatPreview\n ? {\n record: repeatPreview.records[0],\n model: repeatPreview.dataset?.model,\n datasetsByKey: repeatPreview.datasetsByKey,\n }\n : undefined,\n [repeatPreview],\n )\n\n // A component instance renders its definition (AGL-1251) instead of the\n // named dashed box. Authors placed a hero and saw a grey rectangle, so\n // the props they filled in were invisible until Preview.\n //\n // Rendered, never grafted: the definition's nodes stay out of the canvas\n // entirely. That is what makes this safe — there is nothing to lock,\n // nothing to strip before a save, and no way for a definition's node to\n // be persisted into the document that placed it. Same shape as the\n // binding resolution above, which renders a resolved copy while\n // selection and dnd keep the original node.\n const { definitions, formDesigns } = useContext(ComponentPromotionContext)\n const instanceTree = useMemo(() => {\n if (node?.componentId !== REUSABLE_INSTANCE_COMPONENT_ID) {\n return undefined\n }\n // Already expanded into this canvas — the layout-chrome store grafts\n // before it loads (AGL-1218), so its instances arrive with children.\n // Rendering here too would draw the nav twice.\n if (node?.nodes?.length) return undefined\n const props = (node?.props ?? {}) as { refId?: string }\n const definition = props.refId ? definitions?.[props.refId] : undefined\n if (!definition?.nodes || !definition?.rootId) return undefined\n // Plain snapshot: props are MobX observables and the graft reads nested\n // `propValues` off them. The placement's classes stay out of it, as its\n // `sx` does: this leaf already renders both on the element around the\n // preview, and the graft joins a placement's classes onto the root it\n // becomes. Handed them here, the preview's root would apply every class\n // a second time, and keep `aglyn-hidden` collapsed inside a placement\n // the canvas has revealed for designing.\n const { className: _placementClasses, ...snapshotProps } = JSON.parse(\n JSON.stringify(node.props ?? {}),\n ) as Record<string, unknown>\n // Reuse the real graft so the canvas resolves `{{prop.*}}` exactly as\n // the published page will — one substitution path, not a second one\n // that could disagree about which value wins.\n const composed = composeReusableComponentNodes(\n {\n [node.$id]: {\n $id: node.$id,\n componentId: REUSABLE_INSTANCE_COMPONENT_ID,\n props: snapshotProps,\n // Root style overrides (AGL-1306) ride the same snapshot so\n // the canvas renders the SAME merged root sx the published\n // page will — the graft is the one merge point.\n ...(node.styleOverrides && {\n styleOverrides: JSON.parse(JSON.stringify(node.styleOverrides)),\n }),\n // Attribute overrides ride the same snapshot for the same\n // reason (AGL-1899). Leaving them out is invisible rather than\n // broken: Preview and tenant SSR compose from the stored node\n // and WOULD apply them, so the canvas alone would draw the\n // component's own attributes and disagree with both.\n ...(node.attrOverrides && {\n attrOverrides: JSON.parse(JSON.stringify(node.attrOverrides)),\n }),\n nodes: [],\n } as any,\n },\n // The host's WHOLE definitions map, not just this instance's own\n // (AGL-1898). A definition may contain instances of OTHER\n // definitions, and `composeReusableComponentNodes` expands those —\n // but only the ones it is handed. Preview, tenant SSR and the\n // layout-chrome graft all pass the full map, so a one-entry map\n // here made the canvas the only surface that left a nested\n // component as an unexpanded placeholder.\n //\n // It also silently voided propagation for the inner component:\n // publishing a shared button re-rendered every canvas showing it\n // directly and none of the ones showing it through the nav that\n // contains it — which is the case a shared component is usually in.\n //\n // Safe to widen because the `nodes` argument above is this ONE\n // instance: the extra definitions can only be reached from inside\n // the subtree being grafted, never applied to some other node.\n definitions as any,\n )\n // The graft puts the definition's root IN the instance's place rather\n // than under it (AGL-2521), so the component to draw is at the\n // instance's own id. Reading `nodes[0]` here would render the root's\n // FIRST CHILD and drop the component's outer element with its siblings.\n const grafted = composed[node.$id]\n return grafted && grafted.componentId !== REUSABLE_INSTANCE_COMPONENT_ID\n ? denormalizeTree(composed, node.$id)\n : undefined\n // Observable props/overrides: the JSON strings key the memo, as above.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n node,\n JSON.stringify(node?.props ?? {}),\n JSON.stringify(node?.styleOverrides ?? {}),\n JSON.stringify(node?.attrOverrides ?? {}),\n definitions,\n ])\n\n /**\n * A placed form draws its ENTITY'S published fields, not the page's copy\n * of them (`docs/specs/reusable-forms.md`).\n *\n * The same render-copy treatment the instance above gets, and for the same\n * reason: the entity's nodes stay out of the canvas, so there is nothing to\n * lock, nothing to strip before a save, and no way for a form's fields to\n * be persisted into the screen that placed it.\n *\n * It runs the REAL graft rather than reading `design.nodes` directly, so a\n * component nested inside the form design expands here exactly as it will\n * on the published page — one resolution path, not a second that could\n * disagree.\n *\n * When it resolves, the node's own children are not rendered (below): the\n * published page discards them, and a canvas that drew both would show the\n * author a page that does not exist. Where the entity has no published\n * design the memo is `undefined`, the children render, and the form the\n * author drew is the form they see — which is every form built before the\n * entity existed.\n */\n const placedFormTree = useMemo(() => {\n if (node?.componentId !== FORM_COMPONENT_ID) return undefined\n const formId = (node?.props as { formId?: unknown } | undefined)?.formId\n if (typeof formId !== 'string' || !formId) return undefined\n const composed = composeReusableComponentNodes(\n {\n [node.$id]: {\n $id: node.$id,\n componentId: FORM_COMPONENT_ID,\n // Plain snapshot: props are MobX observables, as above.\n props: JSON.parse(JSON.stringify(node.props ?? {})),\n nodes: [],\n } as any,\n },\n // Component definitions ride along so an instance INSIDE the form\n // design expands; the map is safe to pass whole for the reason the\n // instance graft above states — the one node handed in is this form.\n definitions as any,\n [placedFormPlacement(formDesigns as any)],\n )\n const graftedRootId = (composed[node.$id]?.nodes as string[])?.[0]\n return graftedRootId\n ? denormalizeTree(composed, graftedRootId)\n : undefined\n // Observable props: the JSON string keys the memo, as above.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [node, JSON.stringify(node?.props ?? {}), definitions, formDesigns])\n\n return (\n <DraggableDroppable\n node={node}\n type={Besigner.DragType.CANVAS}\n accept={Object.values(Besigner.DragType)}\n disableDragging={!Besigner.dnd.canDragNode(node)}\n >\n <Leaf\n ref={registerElement}\n node={shownNode as typeof node}\n data-aglyn-selected={Besigner.focus.isNodeSelected(node)}\n // Present while the selection lives in this node's subtree (the\n // node itself or any descendant). Canvas-aware components (nav\n // menus, drawers) read this neutral leaf attribute to expand\n // only while they are being authored (AGL-571). Presence-based\n // (''/undefined) so unaffected leaves carry no attribute.\n data-aglyn-selected-within={\n Besigner.focus.isNodeOrDescendantSelected(node) ? '' : undefined\n }\n // Present on an element that carries the hidden class while the\n // canvas is showing it anyway (AGL-592) — the flag the canvas\n // stylesheet checks before collapsing it. Stamped on the hidden\n // element itself, so no wrapper a component renders around its\n // children can come between the two.\n data-aglyn-revealed={\n isNodeHiddenOnSite(node) &&\n isNodeRevealedOnCanvas(node, revealedNodeIds)\n ? ''\n : undefined\n }\n data-aglyn-bound={boundProps.length ? '' : undefined}\n {...rest}\n >\n {/* A resolved form entity REPLACES the page's own fields, exactly\n as the published page composes it — see `placedFormTree`. */}\n {placedFormTree ? null : firstRecord ? (\n // The template IS the first copy: the real children, drawing the\n // first record. Provided around them rather than applied to them,\n // so every descendant leaf resolves its own tokens the way the\n // page's substitution walks the whole cloned subtree.\n <RepeatRecordContext.Provider value={firstRecord}>\n {children}\n </RepeatRecordContext.Provider>\n ) : (\n children\n )}\n {repeatCopies.length ? (\n // Inert and click-through like the component and form previews\n // below, and for the same reason: a copy is a picture of the\n // template, not a document. Selecting one would offer an author\n // an element no save can reach.\n <Box\n sx={{ pointerEvents: 'none' }}\n data-aglyn-repeat-preview=\"\"\n aria-hidden\n >\n <RendererComponents.Provider value={INERT_RENDERER as any}>\n {repeatCopies.map((copy) => (\n <Stem key={copy.$id} node={copy} />\n ))}\n </RendererComponents.Provider>\n </Box>\n ) : null}\n {repeatPreview ? (\n <RepeatBadge\n label={repeatPreview.label}\n count={repeatPreview.records.length}\n />\n ) : null}\n {placedFormTree ? (\n // Inert and click-through like the instance preview below: the\n // fields belong to the form, and they are edited in the form's own\n // besigner, so the only selectable thing here is the placement.\n <Box sx={{ pointerEvents: 'none' }} data-aglyn-form-preview=\"\">\n <RendererComponents.Provider value={INERT_RENDERER as any}>\n <Stem node={placedFormTree} />\n </RendererComponents.Provider>\n </Box>\n ) : null}\n {instanceTree ? (\n // `pointerEvents: none` so a click anywhere on the rendered\n // component still lands on the instance beneath it — the\n // instance is the only thing here that can be selected, and the\n // only thing whose Attributes are editable.\n <Box sx={{ pointerEvents: 'none' }} data-aglyn-component-preview=\"\">\n <RendererComponents.Provider value={INERT_RENDERER as any}>\n <Stem node={instanceTree} />\n </RendererComponents.Provider>\n </Box>\n ) : null}\n {showSlotMarker ? (\n <SlotMarker\n caption={node?.props?.['caption'] as string | undefined}\n />\n ) : null}\n {showEmptyDocumentSlot ? <EmptyDocumentSlot /> : null}\n </Leaf>\n </DraggableDroppable>\n )\n }),\n)\nNodeLeaf.displayName = 'BesignerLeafComponent'\nNodeLeaf.aglyn = true\n\nexport default NodeLeaf\n"],"names":["buildComponentDefaultIconPaths","buildComponentDefaultTokens","buildComponentDefaultValues","composeReusableComponentNodes","displayBindingTokens","FORM_COMPONENT_ID","hasBindings","HostViewType","LAYOUT_SLOT_COMPONENT_ID","NODE_ROOT_ID","placedFormPlacement","resolveBindings","resolveComponentPropTokens","REUSABLE_INSTANCE_COMPONENT_ID","Branch","Leaf","RendererComponents","Stem","Trunk","Besigner","alpha","Box","observer","forwardRef","useCallback","useContext","useMemo","useRef","BindingPickerContext","CanvasRevealContext","CanvasMutedClassesContext","ComponentPromotionContext","useRenderedCanvasElements","useAglynBesignerFlag","useNodeWithMediaAssetFacts","useNodeWithHostTokens","useNodeWithRepeatRecord","useRepeatCopies","useRepeatPreview","RepeatRecordContext","isNodeHiddenOnSite","isNodeRevealedOnCanvas","stripMutedClasses","DraggableDroppable","EmptyDocumentSlot","MediaFactsLeaf","props","ref","node","rest","withHostTokens","withRecord","shown","displayName","INERT_RENDERER","TrunkComponent","StemComponent","BranchComponent","LeafComponent","denormalizeTree","nodes","rootId","seen","Set","has","undefined","add","childIds","Array","isArray","children","map","childId","filter","Boolean","SLOT_ACCENT","SlotMarker","caption","aria-hidden","data-aglyn-slot-marker","sx","m","p","minHeight","display","flexDirection","alignItems","justifyContent","gap","borderWidth","borderStyle","borderColor","backgroundColor","borderRadius","color","fontSize","textAlign","component","fontWeight","REPEAT_ACCENT","REPEAT_INK","RepeatBadge","label","count","data-aglyn-repeat-badge","position","top","right","zIndex","pointerEvents","px","py","maxWidth","overflow","textOverflow","whiteSpace","borderBottomLeftRadius","lineHeight","letterSpacing","NodeLeaf","viewType","elements","setElementRef","deleteElementRef","$id","registered","registerElement","element","current","Element","dragHandle","showSlotMarker","componentId","LAYOUT","showEmptyDocumentSlot","length","revealedNodeIds","mutedClasses","resolveFlag","variables","functions","componentProps","boundProps","Object","entries","value","JSON","stringify","defaultPropTokens","defaultIconPaths","defaultValues","renderNode","hasDeclaredProps","keys","resolved","key","next","String","hostResolvedNode","renderNodeUnclassed","withRepeatRecord","shownNode","repeatPreview","repeatCopies","firstRecord","record","records","model","dataset","datasetsByKey","definitions","formDesigns","instanceTree","definition","refId","parse","className","_placementClasses","snapshotProps","composed","styleOverrides","attrOverrides","grafted","placedFormTree","formId","graftedRootId","type","DragType","CANVAS","accept","values","disableDragging","dnd","canDragNode","data-aglyn-selected","focus","isNodeSelected","data-aglyn-selected-within","isNodeOrDescendantSelected","data-aglyn-revealed","data-aglyn-bound","Provider","data-aglyn-repeat-preview","copy","data-aglyn-form-preview","data-aglyn-component-preview","aglyn"],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import type * as Aglyn from '@aglyn/aglyn';
|
|
18
|
+
import type { ComponentProps } from 'react';
|
|
19
|
+
declare const NodeOutlineRoot: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, Pick<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof import("react").ClassAttributes<HTMLDivElement> | keyof import("react").HTMLAttributes<HTMLDivElement>>, {}>;
|
|
20
|
+
export interface NodeOutlineProps extends ComponentProps<typeof NodeOutlineRoot> {
|
|
21
|
+
node: Aglyn.NodeSchema<any>;
|
|
22
|
+
}
|
|
23
|
+
export declare const NodeOutline: import("react").FunctionComponent<Omit<NodeOutlineProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
24
|
+
export default NodeOutline;
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
17
|
+
import { _ as _object_without_properties_loose } from "@swc/helpers/_/_object_without_properties_loose";
|
|
18
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
19
|
+
import * as Besigner from "@aglyn/besigner";
|
|
20
|
+
import { generateComponentClassKeys } from "@aglyn/shared-ui-theme";
|
|
21
|
+
import { styled } from "@mui/material";
|
|
22
|
+
import clsx from "clsx";
|
|
23
|
+
import { observer } from "mobx-react-lite";
|
|
24
|
+
import { forwardRef } from "react";
|
|
25
|
+
const classKeys = generateComponentClassKeys('NodeOutline', [
|
|
26
|
+
'root',
|
|
27
|
+
'hoveringSelf',
|
|
28
|
+
'selectedSelf',
|
|
29
|
+
'draggingSelf',
|
|
30
|
+
'draggingOver'
|
|
31
|
+
]);
|
|
32
|
+
const NodeOutlineRoot = styled('div', {
|
|
33
|
+
name: 'NodeOutline',
|
|
34
|
+
slot: 'Root'
|
|
35
|
+
})(({ theme })=>{
|
|
36
|
+
const tv = theme.vars || theme;
|
|
37
|
+
// Everything below rides `tv`, so both the outline colour and the fill
|
|
38
|
+
// alphas follow the previewed scheme. `tertiary` carries the generated
|
|
39
|
+
// light/dark/mainChannel tokens (addShadeVariants + the CSS-vars theme),
|
|
40
|
+
// verified against the running console's computed custom properties.
|
|
41
|
+
const slate = tv.palette.tertiary.main;
|
|
42
|
+
const slateChannel = tv.palette.tertiary.mainChannel;
|
|
43
|
+
// The two accents the canvas is allowed, one rule each: pink says WHAT IS
|
|
44
|
+
// SELECTED, blue says WHAT THE POINTER WOULD SELECT. See the rules below
|
|
45
|
+
// for why these two states — and no others — are exempt from the slate;
|
|
46
|
+
// `canvas-chrome-palette.spec.ts` pins each exemption to its declaration.
|
|
47
|
+
const selectionAccent = tv.palette.secondary.main;
|
|
48
|
+
const hoverAccent = tv.palette.primary.main;
|
|
49
|
+
const hoverAccentChannel = tv.palette.primary.mainChannel;
|
|
50
|
+
return {
|
|
51
|
+
pointerEvents: 'none',
|
|
52
|
+
position: 'absolute',
|
|
53
|
+
left: 0,
|
|
54
|
+
top: 0,
|
|
55
|
+
right: 0,
|
|
56
|
+
bottom: 0,
|
|
57
|
+
outlineColor: 'transparent',
|
|
58
|
+
outlineOffset: 1,
|
|
59
|
+
outlineWidth: 1,
|
|
60
|
+
outlineStyle: 'dashed',
|
|
61
|
+
content: '""',
|
|
62
|
+
// Canvas chrome is the SLATE (AGL-1194) for DRAG and DROP-OVER: those
|
|
63
|
+
// are momentary, so they differ by STYLE and WEIGHT on one hue — a fill
|
|
64
|
+
// for the node in flight, and the heaviest treatment for the drop
|
|
65
|
+
// target.
|
|
66
|
+
//
|
|
67
|
+
// The two states that answer "what am I editing" carry an accent
|
|
68
|
+
// instead. Selection (AGL-1221) is a persistent statement about what the
|
|
69
|
+
// panels on the right are editing, it has to survive against an
|
|
70
|
+
// arbitrary subscriber palette, and pink is the one hue on this canvas
|
|
71
|
+
// that never competes with the design being edited.
|
|
72
|
+
//
|
|
73
|
+
// Hover is the pointer's half of that same question, and the slate
|
|
74
|
+
// cannot answer it: the slate is a DESATURATED BLUE, ~17 degrees of hue
|
|
75
|
+
// from `primary`, so on the dark canvas it reads as the disabled version
|
|
76
|
+
// of an affordance rather than a live one. It carries `primary`, which
|
|
77
|
+
// is the same one hue in both schemes.
|
|
78
|
+
//
|
|
79
|
+
// Selection stays the stronger of the two by weight and by style: 2px
|
|
80
|
+
// solid against the 1px dashed the root sets. It claims the border and
|
|
81
|
+
// nothing else, so it never cancels the wash underneath it.
|
|
82
|
+
[`&.${classKeys.selectedSelf}`]: {
|
|
83
|
+
outlineWidth: 2,
|
|
84
|
+
outlineStyle: 'solid',
|
|
85
|
+
outlineColor: selectionAccent
|
|
86
|
+
},
|
|
87
|
+
// The two hover affordances answer different questions, so they are
|
|
88
|
+
// scoped differently.
|
|
89
|
+
//
|
|
90
|
+
// The WASH tracks the POINTER, so it is unconditional: the pointer is
|
|
91
|
+
// over this node whether or not the node is also the selected one, and a
|
|
92
|
+
// selected node that loses its wash gives the pointer no feedback at all.
|
|
93
|
+
[`&.${classKeys.hoveringSelf}`]: {
|
|
94
|
+
backgroundColor: `rgba(${hoverAccentChannel} / 0.08)`
|
|
95
|
+
},
|
|
96
|
+
// The OUTLINE is the one that defers, because selection already owns
|
|
97
|
+
// that border and says something stronger with it. The `:not()` is
|
|
98
|
+
// load-bearing — this rule and the selected rule have equal specificity
|
|
99
|
+
// and this one is declared second, so without it the blue would repaint
|
|
100
|
+
// the pink outline of whichever element the pointer happens to rest on.
|
|
101
|
+
[`&.${classKeys.hoveringSelf}:not(.${classKeys.selectedSelf})`]: {
|
|
102
|
+
outlineColor: hoverAccent
|
|
103
|
+
},
|
|
104
|
+
[`&.${classKeys.draggingSelf}`]: {
|
|
105
|
+
outlineColor: 'transparent',
|
|
106
|
+
backgroundColor: `rgba(${slateChannel} / 0.12)`
|
|
107
|
+
},
|
|
108
|
+
// The drop target is momentary and must be unmistakable, so it keeps
|
|
109
|
+
// the strongest treatment rather than a second hue.
|
|
110
|
+
[`&.${classKeys.draggingOver}`]: {
|
|
111
|
+
outlineWidth: 2,
|
|
112
|
+
outlineStyle: 'solid',
|
|
113
|
+
outlineColor: slate,
|
|
114
|
+
backgroundColor: `rgba(${slateChannel} / 0.16)`
|
|
115
|
+
},
|
|
116
|
+
[`&.${classKeys.draggingOver}.${classKeys.draggingSelf}`]: {
|
|
117
|
+
outlineColor: tv.palette.grey['500'],
|
|
118
|
+
backgroundColor: 'rgba(158 158 158 / 0.64)'
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
});
|
|
122
|
+
export const NodeOutline = observer(/*#__PURE__*/ forwardRef((props, ref)=>{
|
|
123
|
+
const { className, node, style } = props, rest = _object_without_properties_loose(props, [
|
|
124
|
+
"className",
|
|
125
|
+
"node",
|
|
126
|
+
"style"
|
|
127
|
+
]);
|
|
128
|
+
const $id = node == null ? void 0 : node.$id;
|
|
129
|
+
const isSelected = Besigner.focus.isNodeSelected(node);
|
|
130
|
+
const isHovered = Besigner.focus.isNodeHovered(node);
|
|
131
|
+
const isDragging = Besigner.dnd.isDraggingNode(node);
|
|
132
|
+
const isDraggingOver = Besigner.dnd.isDraggingOverDropNode(node);
|
|
133
|
+
return /*#__PURE__*/ _jsx(NodeOutlineRoot, _extends({
|
|
134
|
+
ref: ref,
|
|
135
|
+
"data-aglyn": `outline:${$id}`,
|
|
136
|
+
// Geometry comes from the caller and ONLY from the caller
|
|
137
|
+
// (AGL-2486). This used to take a second, independent
|
|
138
|
+
// `getBoundingClientRect()` of the node and then let `style`
|
|
139
|
+
// override it — a forced layout on every observer tick whose result
|
|
140
|
+
// was always discarded. Now that one outline is drawn per line
|
|
141
|
+
// FRAGMENT that read would happen once per fragment per render, and
|
|
142
|
+
// it could never answer the question anyway: a single rect cannot
|
|
143
|
+
// say which fragment this one is.
|
|
144
|
+
style: style,
|
|
145
|
+
className: clsx({
|
|
146
|
+
[classKeys.selectedSelf]: Boolean(isSelected),
|
|
147
|
+
[classKeys.hoveringSelf]: Boolean(isHovered),
|
|
148
|
+
[classKeys.draggingSelf]: Boolean(isDragging),
|
|
149
|
+
[classKeys.draggingOver]: Boolean(isDraggingOver)
|
|
150
|
+
}, classKeys.root, className)
|
|
151
|
+
}, rest));
|
|
152
|
+
}));
|
|
153
|
+
NodeOutline.displayName = 'NodeOutline';
|
|
154
|
+
export default NodeOutline;
|
|
155
|
+
|
|
156
|
+
//# sourceMappingURL=node-outline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/besigner/feature/designer/src/lib/components/node-outline.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 type * as Aglyn from '@aglyn/aglyn'\nimport * as Besigner from '@aglyn/besigner'\nimport { generateComponentClassKeys } from '@aglyn/shared-ui-theme'\nimport { styled } from '@mui/material'\nimport clsx from 'clsx'\nimport { observer } from 'mobx-react-lite'\nimport type { ComponentProps } from 'react'\nimport { forwardRef } from 'react'\n\nconst classKeys = generateComponentClassKeys('NodeOutline', [\n 'root',\n 'hoveringSelf',\n 'selectedSelf',\n 'draggingSelf',\n 'draggingOver',\n])\n\nconst NodeOutlineRoot = styled('div', {\n name: 'NodeOutline',\n slot: 'Root',\n})(({ theme }) => {\n const tv = (theme as any).vars || theme\n // Everything below rides `tv`, so both the outline colour and the fill\n // alphas follow the previewed scheme. `tertiary` carries the generated\n // light/dark/mainChannel tokens (addShadeVariants + the CSS-vars theme),\n // verified against the running console's computed custom properties.\n const slate = tv.palette.tertiary.main\n const slateChannel = tv.palette.tertiary.mainChannel\n // The two accents the canvas is allowed, one rule each: pink says WHAT IS\n // SELECTED, blue says WHAT THE POINTER WOULD SELECT. See the rules below\n // for why these two states — and no others — are exempt from the slate;\n // `canvas-chrome-palette.spec.ts` pins each exemption to its declaration.\n const selectionAccent = tv.palette.secondary.main\n const hoverAccent = tv.palette.primary.main\n const hoverAccentChannel = tv.palette.primary.mainChannel\n return {\n pointerEvents: 'none',\n position: 'absolute',\n left: 0,\n top: 0,\n right: 0,\n bottom: 0,\n outlineColor: 'transparent',\n outlineOffset: 1,\n outlineWidth: 1,\n outlineStyle: 'dashed',\n content: '\"\"',\n\n // Canvas chrome is the SLATE (AGL-1194) for DRAG and DROP-OVER: those\n // are momentary, so they differ by STYLE and WEIGHT on one hue — a fill\n // for the node in flight, and the heaviest treatment for the drop\n // target.\n //\n // The two states that answer \"what am I editing\" carry an accent\n // instead. Selection (AGL-1221) is a persistent statement about what the\n // panels on the right are editing, it has to survive against an\n // arbitrary subscriber palette, and pink is the one hue on this canvas\n // that never competes with the design being edited.\n //\n // Hover is the pointer's half of that same question, and the slate\n // cannot answer it: the slate is a DESATURATED BLUE, ~17 degrees of hue\n // from `primary`, so on the dark canvas it reads as the disabled version\n // of an affordance rather than a live one. It carries `primary`, which\n // is the same one hue in both schemes.\n //\n // Selection stays the stronger of the two by weight and by style: 2px\n // solid against the 1px dashed the root sets. It claims the border and\n // nothing else, so it never cancels the wash underneath it.\n [`&.${classKeys.selectedSelf}`]: {\n outlineWidth: 2,\n outlineStyle: 'solid',\n outlineColor: selectionAccent,\n },\n // The two hover affordances answer different questions, so they are\n // scoped differently.\n //\n // The WASH tracks the POINTER, so it is unconditional: the pointer is\n // over this node whether or not the node is also the selected one, and a\n // selected node that loses its wash gives the pointer no feedback at all.\n [`&.${classKeys.hoveringSelf}`]: {\n backgroundColor: `rgba(${hoverAccentChannel} / 0.08)`,\n },\n // The OUTLINE is the one that defers, because selection already owns\n // that border and says something stronger with it. The `:not()` is\n // load-bearing — this rule and the selected rule have equal specificity\n // and this one is declared second, so without it the blue would repaint\n // the pink outline of whichever element the pointer happens to rest on.\n [`&.${classKeys.hoveringSelf}:not(.${classKeys.selectedSelf})`]: {\n outlineColor: hoverAccent,\n },\n [`&.${classKeys.draggingSelf}`]: {\n outlineColor: 'transparent',\n backgroundColor: `rgba(${slateChannel} / 0.12)`,\n },\n // The drop target is momentary and must be unmistakable, so it keeps\n // the strongest treatment rather than a second hue.\n [`&.${classKeys.draggingOver}`]: {\n outlineWidth: 2,\n outlineStyle: 'solid',\n outlineColor: slate,\n backgroundColor: `rgba(${slateChannel} / 0.16)`,\n },\n [`&.${classKeys.draggingOver}.${classKeys.draggingSelf}`]: {\n outlineColor: tv.palette.grey['500'],\n backgroundColor: 'rgba(158 158 158 / 0.64)',\n },\n }\n})\n\nexport interface NodeOutlineProps extends ComponentProps<\n typeof NodeOutlineRoot\n> {\n node: Aglyn.NodeSchema<any>\n}\n\nexport const NodeOutline = observer(\n forwardRef<HTMLDivElement, NodeOutlineProps>((props, ref) => {\n const { className, node, style, ...rest } = props\n const $id = node?.$id\n const isSelected = Besigner.focus.isNodeSelected(node)\n const isHovered = Besigner.focus.isNodeHovered(node)\n const isDragging = Besigner.dnd.isDraggingNode(node)\n const isDraggingOver = Besigner.dnd.isDraggingOverDropNode(node)\n\n return (\n <NodeOutlineRoot\n ref={ref}\n data-aglyn={`outline:${$id}`}\n // Geometry comes from the caller and ONLY from the caller\n // (AGL-2486). This used to take a second, independent\n // `getBoundingClientRect()` of the node and then let `style`\n // override it — a forced layout on every observer tick whose result\n // was always discarded. Now that one outline is drawn per line\n // FRAGMENT that read would happen once per fragment per render, and\n // it could never answer the question anyway: a single rect cannot\n // say which fragment this one is.\n style={style}\n className={clsx(\n {\n [classKeys.selectedSelf]: Boolean(isSelected),\n [classKeys.hoveringSelf]: Boolean(isHovered),\n [classKeys.draggingSelf]: Boolean(isDragging),\n [classKeys.draggingOver]: Boolean(isDraggingOver),\n },\n classKeys.root,\n className,\n )}\n {...rest}\n />\n )\n }),\n)\n\nNodeOutline.displayName = 'NodeOutline'\n\nexport default NodeOutline\n"],"names":["Besigner","generateComponentClassKeys","styled","clsx","observer","forwardRef","classKeys","NodeOutlineRoot","name","slot","theme","tv","vars","slate","palette","tertiary","main","slateChannel","mainChannel","selectionAccent","secondary","hoverAccent","primary","hoverAccentChannel","pointerEvents","position","left","top","right","bottom","outlineColor","outlineOffset","outlineWidth","outlineStyle","content","selectedSelf","hoveringSelf","backgroundColor","draggingSelf","draggingOver","grey","NodeOutline","props","ref","className","node","style","rest","$id","isSelected","focus","isNodeSelected","isHovered","isNodeHovered","isDragging","dnd","isDraggingNode","isDraggingOver","isDraggingOverDropNode","data-aglyn","Boolean","root","displayName"],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2023 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import { type PopperProps as MuiPopperProps } from '@mui/material';
|
|
18
|
+
export declare function serializeRect(rect: DOMRect): any;
|
|
19
|
+
export interface NodeOverlayProps extends Partial<MuiPopperProps> {
|
|
20
|
+
variant: 'hovered' | 'selected';
|
|
21
|
+
}
|
|
22
|
+
declare const NodeOverlay: import("react").FunctionComponent<Omit<NodeOverlayProps, "ref"> & import("react").RefAttributes<any>>;
|
|
23
|
+
export default NodeOverlay;
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
2
|
+
import { _ as _object_without_properties_loose } from "@swc/helpers/_/_object_without_properties_loose";
|
|
3
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
4
|
+
/**
|
|
5
|
+
* @license
|
|
6
|
+
* Copyright 2023 Aglyn LLC
|
|
7
|
+
*
|
|
8
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
9
|
+
* you may not use this file except in compliance with the License.
|
|
10
|
+
* You may obtain a copy of the License at
|
|
11
|
+
*
|
|
12
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
*
|
|
14
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
15
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
17
|
+
* See the License for the specific language governing permissions and
|
|
18
|
+
* limitations under the License.
|
|
19
|
+
*/ import { canvas } from "@aglyn/aglyn";
|
|
20
|
+
import * as Besigner from "@aglyn/besigner";
|
|
21
|
+
import { useIsomorphicLayoutEffect } from "@aglyn/shared-ui-jsx";
|
|
22
|
+
import { getElementFragmentRects } from "@aglyn/shared-util-dom";
|
|
23
|
+
import { Popper as MuiPopper } from "@mui/material";
|
|
24
|
+
import { observer } from "mobx-react-lite";
|
|
25
|
+
import { forwardRef, useMemo, useState } from "react";
|
|
26
|
+
import NodeOutline from "./node-outline.js";
|
|
27
|
+
import { isInlineEditWithin } from "../utils/inline-text-edit.store.js";
|
|
28
|
+
import NodeQuickActions from "./node-quick-actions.js";
|
|
29
|
+
const outerModifiers = [
|
|
30
|
+
{
|
|
31
|
+
name: 'flip',
|
|
32
|
+
enabled: false,
|
|
33
|
+
options: {
|
|
34
|
+
altBoundary: false,
|
|
35
|
+
rootBoundary: 'viewport',
|
|
36
|
+
padding: 0
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'preventOverflow',
|
|
41
|
+
enabled: false,
|
|
42
|
+
options: {
|
|
43
|
+
altAxis: false,
|
|
44
|
+
altBoundary: false,
|
|
45
|
+
tether: false,
|
|
46
|
+
rootBoundary: 'viewport',
|
|
47
|
+
padding: 0
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
];
|
|
51
|
+
const innerModifiers = [
|
|
52
|
+
{
|
|
53
|
+
name: 'flip',
|
|
54
|
+
enabled: true,
|
|
55
|
+
options: {
|
|
56
|
+
altBoundary: true,
|
|
57
|
+
rootBoundary: 'viewport',
|
|
58
|
+
padding: 0
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: 'preventOverflow',
|
|
63
|
+
enabled: true,
|
|
64
|
+
options: {
|
|
65
|
+
altAxis: true,
|
|
66
|
+
altBoundary: true,
|
|
67
|
+
tether: true,
|
|
68
|
+
rootBoundary: 'viewport',
|
|
69
|
+
padding: 0
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
];
|
|
73
|
+
const DEFAULT_RECT = {
|
|
74
|
+
top: 0,
|
|
75
|
+
left: 0,
|
|
76
|
+
width: 0,
|
|
77
|
+
height: 0
|
|
78
|
+
};
|
|
79
|
+
export function serializeRect(rect) {
|
|
80
|
+
return JSON.parse(JSON.stringify(rect || DEFAULT_RECT));
|
|
81
|
+
}
|
|
82
|
+
const DEFAULT_GEOMETRY = {
|
|
83
|
+
fragments: [
|
|
84
|
+
DEFAULT_RECT
|
|
85
|
+
],
|
|
86
|
+
union: DEFAULT_RECT,
|
|
87
|
+
first: DEFAULT_RECT
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Whole-pixel identity of a measured geometry (AGL-2486).
|
|
91
|
+
*
|
|
92
|
+
* The measuring callback runs on every scroll event anywhere on the page, on
|
|
93
|
+
* every resize, and on every ResizeObserver tick. Before this it called
|
|
94
|
+
* `setRect(serializeRect(...))` unconditionally — a NEW object each time, so
|
|
95
|
+
* scrolling a side panel re-rendered this observer and everything under it at
|
|
96
|
+
* event rate even though the element had not moved. Fragment sets are larger,
|
|
97
|
+
* and committing a fresh ARRAY every frame is exactly the shape that froze a
|
|
98
|
+
* tab in the collaborator overlay on 2026-08-22.
|
|
99
|
+
*
|
|
100
|
+
* MEASURING is cheap; COMMITTING is not. Rounding first means sub-pixel
|
|
101
|
+
* jitter cannot churn a render on its own. This is strictly less per-event
|
|
102
|
+
* work than the single-rect code did, not more.
|
|
103
|
+
*/ function fingerprintGeometry(geometry) {
|
|
104
|
+
return geometry.fragments.map((rect)=>`${Math.round(rect.left)},${Math.round(rect.top)},` + `${Math.round(rect.width)},${Math.round(rect.height)}`).join(';');
|
|
105
|
+
}
|
|
106
|
+
const NodeOverlay = observer(/*#__PURE__*/ forwardRef((props, ref)=>{
|
|
107
|
+
var _ref;
|
|
108
|
+
const _ref1 = props || {}, { variant } = _ref1, rest = _object_without_properties_loose(_ref1, [
|
|
109
|
+
"variant"
|
|
110
|
+
]);
|
|
111
|
+
const state = variant === 'selected' ? Besigner.focus.getLastSelected() : Besigner.focus.getHovered();
|
|
112
|
+
const $id = state == null ? void 0 : state.$id;
|
|
113
|
+
const node = canvas.getNode($id);
|
|
114
|
+
const elementRef = Besigner.refs.get($id);
|
|
115
|
+
// Node.index throws for parentless nodes (the root, or a node whose
|
|
116
|
+
// parent isn't loaded) — selecting the root via the breadcrumbs must not
|
|
117
|
+
// crash the overlay.
|
|
118
|
+
const nodeIndex = (node == null ? void 0 : node.parent) ? node.index : null;
|
|
119
|
+
/**
|
|
120
|
+
* The selection chrome stands down while this node is being edited in
|
|
121
|
+
* place (AGL-2486).
|
|
122
|
+
*
|
|
123
|
+
* This overlay paints a translucent FILL behind the node as well as an
|
|
124
|
+
* outline (`node-outline.tsx`). While the author is typing, that tint is
|
|
125
|
+
* the one thing standing between the in-place surface and its whole
|
|
126
|
+
* promise — that the text looks exactly as it renders, on the background
|
|
127
|
+
* it renders on. It is redundant during an edit anyway: the caret and the
|
|
128
|
+
* toolbar already say which element is being edited.
|
|
129
|
+
*
|
|
130
|
+
* The geometry is no longer a second reason to suppress it: the
|
|
131
|
+
* chrome below is drawn from `getClientRects()`, one outline per line
|
|
132
|
+
* fragment, so a SELECTED wrapped inline run is outlined correctly too.
|
|
133
|
+
* Standing the fill down during an edit remains right for its own
|
|
134
|
+
* reason — the in-place surface must look exactly as it renders.
|
|
135
|
+
*/ const isBeingEdited = isInlineEditWithin((_ref = elementRef == null ? void 0 : elementRef.current) != null ? _ref : null);
|
|
136
|
+
const isOpen = Boolean(elementRef == null ? void 0 : elementRef.current) && !isBeingEdited;
|
|
137
|
+
const [geometry, setGeometry] = useState(DEFAULT_GEOMETRY);
|
|
138
|
+
const { union: rect, fragments, first } = geometry;
|
|
139
|
+
useIsomorphicLayoutEffect(()=>{
|
|
140
|
+
var _ref;
|
|
141
|
+
var _el_getRootNode;
|
|
142
|
+
const el = elementRef == null ? void 0 : elementRef.current;
|
|
143
|
+
if (!el || !('getBoundingClientRect' in el)) return;
|
|
144
|
+
/**
|
|
145
|
+
* The element's REAL shape, not its bounding box (AGL-2486).
|
|
146
|
+
*
|
|
147
|
+
* A wrapped inline run is a set of line fragments, and one rectangle
|
|
148
|
+
* cannot describe it — see `getElementFragmentRects` for why the union
|
|
149
|
+
* is not merely imprecise but a different shape, and why an outline
|
|
150
|
+
* drawn from it misses the text on the new line. A block yields one
|
|
151
|
+
* fragment that IS the bounding rect, so block geometry is unaffected.
|
|
152
|
+
*/ let committed = '';
|
|
153
|
+
const update = ()=>{
|
|
154
|
+
const next = getElementFragmentRects(el);
|
|
155
|
+
const fingerprint = fingerprintGeometry(next);
|
|
156
|
+
if (fingerprint === committed) return;
|
|
157
|
+
committed = fingerprint;
|
|
158
|
+
setGeometry(next);
|
|
159
|
+
};
|
|
160
|
+
update();
|
|
161
|
+
// Re-sync when the element or its shadow-DOM host resizes (covers prop
|
|
162
|
+
// changes that affect layout, e.g. flexDirection column→row) and when
|
|
163
|
+
// the canvas container resizes or the window resizes.
|
|
164
|
+
// ResizeObserver is not in every jsdom setup, and an unguarded
|
|
165
|
+
// constructor in a layout effect takes the whole overlay down with it.
|
|
166
|
+
// The listeners below still carry scroll and resize. Same guard, for
|
|
167
|
+
// the same reason, as `use-anchored-rect.ts`.
|
|
168
|
+
const ro = typeof ResizeObserver === 'function' ? new ResizeObserver(update) : null;
|
|
169
|
+
ro == null ? void 0 : ro.observe(el);
|
|
170
|
+
const shadowHost = (_ref = (_el_getRootNode = el.getRootNode()) == null ? void 0 : _el_getRootNode.host) != null ? _ref : null;
|
|
171
|
+
if (shadowHost) ro == null ? void 0 : ro.observe(shadowHost);
|
|
172
|
+
window.addEventListener('resize', update, {
|
|
173
|
+
passive: true
|
|
174
|
+
});
|
|
175
|
+
// Scrolling any ancestor (the canvas container, panels, or the page
|
|
176
|
+
// body) shifts getBoundingClientRect() values without triggering a
|
|
177
|
+
// resize — capture-phase listener catches them all.
|
|
178
|
+
window.addEventListener('scroll', update, {
|
|
179
|
+
passive: true,
|
|
180
|
+
capture: true
|
|
181
|
+
});
|
|
182
|
+
return ()=>{
|
|
183
|
+
ro == null ? void 0 : ro.disconnect();
|
|
184
|
+
window.removeEventListener('resize', update);
|
|
185
|
+
window.removeEventListener('scroll', update, {
|
|
186
|
+
capture: true
|
|
187
|
+
});
|
|
188
|
+
};
|
|
189
|
+
// Node?.index changes when the node is reordered among siblings (e.g.
|
|
190
|
+
// "shift up"/"shift down"). Reordering moves the same DOM element to a
|
|
191
|
+
// new position without resizing it, so ResizeObserver won't catch it —
|
|
192
|
+
// this dependency forces a rect recompute when sibling order changes.
|
|
193
|
+
}, [
|
|
194
|
+
elementRef,
|
|
195
|
+
nodeIndex
|
|
196
|
+
]);
|
|
197
|
+
// Popper types its anchor rect as a full `DOMRect`; the measured rects
|
|
198
|
+
// are plain geometry and carry no `toJSON`, which popper never calls.
|
|
199
|
+
const virtualElement = useMemo(()=>{
|
|
200
|
+
return ()=>({
|
|
201
|
+
getBoundingClientRect: ()=>rect
|
|
202
|
+
});
|
|
203
|
+
}, [
|
|
204
|
+
rect
|
|
205
|
+
]);
|
|
206
|
+
/**
|
|
207
|
+
* Where the label chip, the quick actions and the DRAG affordance hang
|
|
208
|
+
* (AGL-2486).
|
|
209
|
+
*
|
|
210
|
+
* They used to hang off the union rect, and a fragment set has no obvious
|
|
211
|
+
* single anchor. The union corner is the wrong one: an inline run that
|
|
212
|
+
* begins mid-line and wraps has a union whose left edge comes from the
|
|
213
|
+
* SECOND line, so a chip placed there floats above a sibling's text
|
|
214
|
+
* rather than above the element it names — and the drag handle would be
|
|
215
|
+
* offered at a point the element does not occupy.
|
|
216
|
+
*
|
|
217
|
+
* The first fragment is where the run STARTS in reading order. It is
|
|
218
|
+
* where the eye already is, it is always on the element, and for a block
|
|
219
|
+
* — every one of which has exactly one fragment — it is the union, so
|
|
220
|
+
* nothing moves for the overwhelming majority of nodes.
|
|
221
|
+
*/ const anchorElement = useMemo(()=>{
|
|
222
|
+
return ()=>({
|
|
223
|
+
getBoundingClientRect: ()=>first
|
|
224
|
+
});
|
|
225
|
+
}, [
|
|
226
|
+
first
|
|
227
|
+
]);
|
|
228
|
+
return /*#__PURE__*/ _jsx(MuiPopper, _extends({
|
|
229
|
+
ref: ref,
|
|
230
|
+
anchorEl: virtualElement,
|
|
231
|
+
placement: "top-start",
|
|
232
|
+
modifiers: outerModifiers,
|
|
233
|
+
open: isOpen,
|
|
234
|
+
keepMounted: true,
|
|
235
|
+
// The anchor rect is viewport-relative; fixed positioning matches it
|
|
236
|
+
// and, unlike the default absolute strategy, cannot extend the
|
|
237
|
+
// document — an overlay past the fold otherwise grows the page,
|
|
238
|
+
// which grows the scroll range, which moves the overlay again
|
|
239
|
+
// (infinite scroll feedback).
|
|
240
|
+
popperOptions: {
|
|
241
|
+
strategy: 'fixed'
|
|
242
|
+
},
|
|
243
|
+
// Overlays belong to the canvas layer: rendering in place (no body
|
|
244
|
+
// portal) keeps them inside the viewport's stacking context, so the
|
|
245
|
+
// designer chrome (app bars, breadcrumbs) always paints above them.
|
|
246
|
+
disablePortal: true
|
|
247
|
+
}, rest, {
|
|
248
|
+
children: /*#__PURE__*/ _jsxs("div", {
|
|
249
|
+
children: [
|
|
250
|
+
fragments.map((fragment, index)=>/*#__PURE__*/ _jsx(NodeOutline, {
|
|
251
|
+
node: node,
|
|
252
|
+
"data-aglyn-fragment": index,
|
|
253
|
+
style: {
|
|
254
|
+
left: fragment.left - rect.left,
|
|
255
|
+
top: fragment.top - rect.top,
|
|
256
|
+
right: 'auto',
|
|
257
|
+
bottom: 'auto',
|
|
258
|
+
width: fragment.width,
|
|
259
|
+
height: fragment.height
|
|
260
|
+
}
|
|
261
|
+
}, index)),
|
|
262
|
+
/*#__PURE__*/ _jsx(MuiPopper, {
|
|
263
|
+
open: isOpen,
|
|
264
|
+
anchorEl: anchorElement,
|
|
265
|
+
placement: variant === 'hovered' ? 'top-start' : undefined,
|
|
266
|
+
modifiers: innerModifiers,
|
|
267
|
+
popperOptions: {
|
|
268
|
+
strategy: 'fixed'
|
|
269
|
+
},
|
|
270
|
+
disablePortal: true,
|
|
271
|
+
// KeepMounted
|
|
272
|
+
// transition
|
|
273
|
+
sx: {
|
|
274
|
+
['&[data-popper-placement^=top] #aglyn\\:element-overlay-label']: {
|
|
275
|
+
borderTopLeftRadius: 3,
|
|
276
|
+
borderTopRightRadius: 3,
|
|
277
|
+
borderBottomLeftRadius: 0,
|
|
278
|
+
borderBottomRightRadius: 0
|
|
279
|
+
},
|
|
280
|
+
['&[data-popper-placement^=bottom] #aglyn\\:element-overlay-label']: {
|
|
281
|
+
borderTopLeftRadius: 0,
|
|
282
|
+
borderTopRightRadius: 0,
|
|
283
|
+
borderBottomLeftRadius: 3,
|
|
284
|
+
borderBottomRightRadius: 3
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
children: /*#__PURE__*/ _jsx(NodeQuickActions, {
|
|
288
|
+
node: node,
|
|
289
|
+
variant: variant === 'selected' ? 'actions' : 'label'
|
|
290
|
+
})
|
|
291
|
+
})
|
|
292
|
+
]
|
|
293
|
+
})
|
|
294
|
+
}));
|
|
295
|
+
}));
|
|
296
|
+
NodeOverlay.displayName = 'NodeOverlay';
|
|
297
|
+
export default NodeOverlay;
|
|
298
|
+
|
|
299
|
+
//# sourceMappingURL=node-overlay.js.map
|