@next-buildr/editor 0.0.0-stage → 2.0.0
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 +21 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/app/builder-editor.d.ts +8 -0
- package/dist/app/builder-editor.d.ts.map +1 -0
- package/dist/app/builder-editor.js +14 -0
- package/dist/app/builder-editor.test.d.ts +2 -0
- package/dist/app/builder-editor.test.d.ts.map +1 -0
- package/dist/app/builder-editor.test.js +199 -0
- package/dist/app/config.d.ts +59 -0
- package/dist/app/config.d.ts.map +1 -0
- package/dist/app/config.js +18 -0
- package/dist/app/content-language.test.d.ts +2 -0
- package/dist/app/content-language.test.d.ts.map +1 -0
- package/dist/app/content-language.test.js +157 -0
- package/dist/app/editor-app.d.ts +17 -0
- package/dist/app/editor-app.d.ts.map +1 -0
- package/dist/app/editor-app.js +206 -0
- package/dist/app/editor-app.test.d.ts +2 -0
- package/dist/app/editor-app.test.d.ts.map +1 -0
- package/dist/app/editor-app.test.js +135 -0
- package/dist/app/layout.d.ts +32 -0
- package/dist/app/layout.d.ts.map +1 -0
- package/dist/app/layout.js +82 -0
- package/dist/app/manifest.d.ts +12 -0
- package/dist/app/manifest.d.ts.map +1 -0
- package/dist/app/manifest.js +17 -0
- package/dist/app/shell-panels.d.ts +15 -0
- package/dist/app/shell-panels.d.ts.map +1 -0
- package/dist/app/shell-panels.js +5 -0
- package/dist/app/small-screen.d.ts +12 -0
- package/dist/app/small-screen.d.ts.map +1 -0
- package/dist/app/small-screen.js +33 -0
- package/dist/app/small-screen.test.d.ts +2 -0
- package/dist/app/small-screen.test.d.ts.map +1 -0
- package/dist/app/small-screen.test.js +108 -0
- package/dist/app/status-info.d.ts +14 -0
- package/dist/app/status-info.d.ts.map +1 -0
- package/dist/app/status-info.js +34 -0
- package/dist/app/use-resizable.d.ts +34 -0
- package/dist/app/use-resizable.d.ts.map +1 -0
- package/dist/app/use-resizable.js +84 -0
- package/dist/canvas-host/canvas-frame.d.ts +53 -0
- package/dist/canvas-host/canvas-frame.d.ts.map +1 -0
- package/dist/canvas-host/canvas-frame.js +146 -0
- package/dist/canvas-host/canvas-frame.test.d.ts +2 -0
- package/dist/canvas-host/canvas-frame.test.d.ts.map +1 -0
- package/dist/canvas-host/canvas-frame.test.js +91 -0
- package/dist/canvas-host/host.d.ts +109 -0
- package/dist/canvas-host/host.d.ts.map +1 -0
- package/dist/canvas-host/host.js +293 -0
- package/dist/canvas-host/host.test.d.ts +2 -0
- package/dist/canvas-host/host.test.d.ts.map +1 -0
- package/dist/canvas-host/host.test.js +398 -0
- package/dist/canvas-host/index.d.ts +5 -0
- package/dist/canvas-host/index.d.ts.map +1 -0
- package/dist/canvas-host/index.js +2 -0
- package/dist/clipboard/clipboard.d.ts +38 -0
- package/dist/clipboard/clipboard.d.ts.map +1 -0
- package/dist/clipboard/clipboard.js +160 -0
- package/dist/clipboard/clipboard.test.d.ts +2 -0
- package/dist/clipboard/clipboard.test.d.ts.map +1 -0
- package/dist/clipboard/clipboard.test.js +457 -0
- package/dist/clipboard/format.d.ts +27 -0
- package/dist/clipboard/format.d.ts.map +1 -0
- package/dist/clipboard/format.js +37 -0
- package/dist/clipboard/index.d.ts +6 -0
- package/dist/clipboard/index.d.ts.map +1 -0
- package/dist/clipboard/index.js +3 -0
- package/dist/clipboard/react.d.ts +20 -0
- package/dist/clipboard/react.d.ts.map +1 -0
- package/dist/clipboard/react.js +71 -0
- package/dist/dialogs/index.d.ts +2 -0
- package/dist/dialogs/index.d.ts.map +1 -0
- package/dist/dialogs/index.js +1 -0
- package/dist/dialogs/media-picker/index.d.ts +7 -0
- package/dist/dialogs/media-picker/index.d.ts.map +1 -0
- package/dist/dialogs/media-picker/index.js +3 -0
- package/dist/dialogs/media-picker/library.d.ts +17 -0
- package/dist/dialogs/media-picker/library.d.ts.map +1 -0
- package/dist/dialogs/media-picker/library.js +9 -0
- package/dist/dialogs/media-picker/media-picker.d.ts +18 -0
- package/dist/dialogs/media-picker/media-picker.d.ts.map +1 -0
- package/dist/dialogs/media-picker/media-picker.js +99 -0
- package/dist/dialogs/media-picker/media-picker.test.d.ts +2 -0
- package/dist/dialogs/media-picker/media-picker.test.d.ts.map +1 -0
- package/dist/dialogs/media-picker/media-picker.test.js +161 -0
- package/dist/dialogs/media-picker/media-ref.d.ts +28 -0
- package/dist/dialogs/media-picker/media-ref.d.ts.map +1 -0
- package/dist/dialogs/media-picker/media-ref.js +52 -0
- package/dist/dnd/check.d.ts +8 -0
- package/dist/dnd/check.d.ts.map +1 -0
- package/dist/dnd/check.js +12 -0
- package/dist/dnd/destinations.d.ts +15 -0
- package/dist/dnd/destinations.d.ts.map +1 -0
- package/dist/dnd/destinations.js +43 -0
- package/dist/dnd/dnd-react.test.d.ts +2 -0
- package/dist/dnd/dnd-react.test.d.ts.map +1 -0
- package/dist/dnd/dnd-react.test.js +93 -0
- package/dist/dnd/dnd.test.d.ts +2 -0
- package/dist/dnd/dnd.test.d.ts.map +1 -0
- package/dist/dnd/dnd.test.js +327 -0
- package/dist/dnd/engine.d.ts +85 -0
- package/dist/dnd/engine.d.ts.map +1 -0
- package/dist/dnd/engine.js +185 -0
- package/dist/dnd/fragment.d.ts +6 -0
- package/dist/dnd/fragment.d.ts.map +1 -0
- package/dist/dnd/fragment.js +18 -0
- package/dist/dnd/geometry.d.ts +30 -0
- package/dist/dnd/geometry.d.ts.map +1 -0
- package/dist/dnd/geometry.js +31 -0
- package/dist/dnd/index.d.ts +14 -0
- package/dist/dnd/index.d.ts.map +1 -0
- package/dist/dnd/index.js +7 -0
- package/dist/dnd/move-to-dialog.d.ts +13 -0
- package/dist/dnd/move-to-dialog.d.ts.map +1 -0
- package/dist/dnd/move-to-dialog.js +30 -0
- package/dist/dnd/react.d.ts +43 -0
- package/dist/dnd/react.d.ts.map +1 -0
- package/dist/dnd/react.js +185 -0
- package/dist/dnd/tree-target.d.ts +29 -0
- package/dist/dnd/tree-target.d.ts.map +1 -0
- package/dist/dnd/tree-target.js +97 -0
- package/dist/fonts/LICENSE-inter.txt +93 -0
- package/dist/fonts/inter-latin-400-normal.woff2 +0 -0
- package/dist/fonts/inter-latin-500-normal.woff2 +0 -0
- package/dist/fonts/inter-latin-600-normal.woff2 +0 -0
- package/dist/fonts/inter-latin-ext-400-normal.woff2 +0 -0
- package/dist/fonts/inter-latin-ext-500-normal.woff2 +0 -0
- package/dist/fonts/inter-latin-ext-600-normal.woff2 +0 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/messages/en.d.ts +335 -0
- package/dist/messages/en.d.ts.map +1 -0
- package/dist/messages/en.js +332 -0
- package/dist/messages/index.d.ts +16 -0
- package/dist/messages/index.d.ts.map +1 -0
- package/dist/messages/index.js +22 -0
- package/dist/messages/pl.d.ts +3 -0
- package/dist/messages/pl.d.ts.map +1 -0
- package/dist/messages/pl.js +327 -0
- package/dist/panels/breadcrumbs/breadcrumbs.d.ts +6 -0
- package/dist/panels/breadcrumbs/breadcrumbs.d.ts.map +1 -0
- package/dist/panels/breadcrumbs/breadcrumbs.js +24 -0
- package/dist/panels/breadcrumbs/breadcrumbs.test.d.ts +2 -0
- package/dist/panels/breadcrumbs/breadcrumbs.test.d.ts.map +1 -0
- package/dist/panels/breadcrumbs/breadcrumbs.test.js +56 -0
- package/dist/panels/index.d.ts +9 -0
- package/dist/panels/index.d.ts.map +1 -0
- package/dist/panels/index.js +6 -0
- package/dist/panels/insert/catalog.d.ts +30 -0
- package/dist/panels/insert/catalog.d.ts.map +1 -0
- package/dist/panels/insert/catalog.js +76 -0
- package/dist/panels/insert/catalog.order.test.d.ts +2 -0
- package/dist/panels/insert/catalog.order.test.d.ts.map +1 -0
- package/dist/panels/insert/catalog.order.test.js +17 -0
- package/dist/panels/insert/category-name.d.ts +4 -0
- package/dist/panels/insert/category-name.d.ts.map +1 -0
- package/dist/panels/insert/category-name.js +8 -0
- package/dist/panels/insert/index.d.ts +3 -0
- package/dist/panels/insert/index.d.ts.map +1 -0
- package/dist/panels/insert/index.js +2 -0
- package/dist/panels/insert/insert-panel.d.ts +7 -0
- package/dist/panels/insert/insert-panel.d.ts.map +1 -0
- package/dist/panels/insert/insert-panel.js +155 -0
- package/dist/panels/insert/insert-panel.test.d.ts +2 -0
- package/dist/panels/insert/insert-panel.test.d.ts.map +1 -0
- package/dist/panels/insert/insert-panel.test.js +323 -0
- package/dist/panels/insert/target.d.ts +17 -0
- package/dist/panels/insert/target.d.ts.map +1 -0
- package/dist/panels/insert/target.js +48 -0
- package/dist/panels/inspector/controls/boolean.d.ts +4 -0
- package/dist/panels/inspector/controls/boolean.d.ts.map +1 -0
- package/dist/panels/inspector/controls/boolean.js +4 -0
- package/dist/panels/inspector/controls/compound.d.ts +15 -0
- package/dist/panels/inspector/controls/compound.d.ts.map +1 -0
- package/dist/panels/inspector/controls/compound.js +99 -0
- package/dist/panels/inspector/controls/compound.test.d.ts +2 -0
- package/dist/panels/inspector/controls/compound.test.d.ts.map +1 -0
- package/dist/panels/inspector/controls/compound.test.js +195 -0
- package/dist/panels/inspector/controls/icon.d.ts +5 -0
- package/dist/panels/inspector/controls/icon.d.ts.map +1 -0
- package/dist/panels/inspector/controls/icon.js +6 -0
- package/dist/panels/inspector/controls/index.d.ts +13 -0
- package/dist/panels/inspector/controls/index.d.ts.map +1 -0
- package/dist/panels/inspector/controls/index.js +11 -0
- package/dist/panels/inspector/controls/label.d.ts +4 -0
- package/dist/panels/inspector/controls/label.d.ts.map +1 -0
- package/dist/panels/inspector/controls/label.js +8 -0
- package/dist/panels/inspector/controls/link.d.ts +5 -0
- package/dist/panels/inspector/controls/link.d.ts.map +1 -0
- package/dist/panels/inspector/controls/link.js +6 -0
- package/dist/panels/inspector/controls/media.d.ts +9 -0
- package/dist/panels/inspector/controls/media.d.ts.map +1 -0
- package/dist/panels/inspector/controls/media.js +21 -0
- package/dist/panels/inspector/controls/number.d.ts +10 -0
- package/dist/panels/inspector/controls/number.d.ts.map +1 -0
- package/dist/panels/inspector/controls/number.js +33 -0
- package/dist/panels/inspector/controls/rich-text-model.d.ts +20 -0
- package/dist/panels/inspector/controls/rich-text-model.d.ts.map +1 -0
- package/dist/panels/inspector/controls/rich-text-model.js +91 -0
- package/dist/panels/inspector/controls/rich-text.d.ts +10 -0
- package/dist/panels/inspector/controls/rich-text.d.ts.map +1 -0
- package/dist/panels/inspector/controls/rich-text.js +159 -0
- package/dist/panels/inspector/controls/select.d.ts +5 -0
- package/dist/panels/inspector/controls/select.d.ts.map +1 -0
- package/dist/panels/inspector/controls/select.js +16 -0
- package/dist/panels/inspector/controls/select.test.d.ts +2 -0
- package/dist/panels/inspector/controls/select.test.d.ts.map +1 -0
- package/dist/panels/inspector/controls/select.test.js +43 -0
- package/dist/panels/inspector/controls/text.d.ts +4 -0
- package/dist/panels/inspector/controls/text.d.ts.map +1 -0
- package/dist/panels/inspector/controls/text.js +5 -0
- package/dist/panels/inspector/controls/textarea.d.ts +4 -0
- package/dist/panels/inspector/controls/textarea.d.ts.map +1 -0
- package/dist/panels/inspector/controls/textarea.js +4 -0
- package/dist/panels/inspector/controls/types.d.ts +16 -0
- package/dist/panels/inspector/controls/types.d.ts.map +1 -0
- package/dist/panels/inspector/controls/types.js +1 -0
- package/dist/panels/inspector/index.d.ts +17 -0
- package/dist/panels/inspector/index.d.ts.map +1 -0
- package/dist/panels/inspector/index.js +9 -0
- package/dist/panels/inspector/inspector.d.ts +16 -0
- package/dist/panels/inspector/inspector.d.ts.map +1 -0
- package/dist/panels/inspector/inspector.js +116 -0
- package/dist/panels/inspector/inspector.test.d.ts +2 -0
- package/dist/panels/inspector/inspector.test.d.ts.map +1 -0
- package/dist/panels/inspector/inspector.test.js +328 -0
- package/dist/panels/inspector/props-panel.d.ts +26 -0
- package/dist/panels/inspector/props-panel.d.ts.map +1 -0
- package/dist/panels/inspector/props-panel.js +117 -0
- package/dist/panels/inspector/styles/box-model.d.ts +20 -0
- package/dist/panels/inspector/styles/box-model.d.ts.map +1 -0
- package/dist/panels/inspector/styles/box-model.js +31 -0
- package/dist/panels/inspector/styles/index.d.ts +5 -0
- package/dist/panels/inspector/styles/index.d.ts.map +1 -0
- package/dist/panels/inspector/styles/index.js +2 -0
- package/dist/panels/inspector/styles/model.d.ts +55 -0
- package/dist/panels/inspector/styles/model.d.ts.map +1 -0
- package/dist/panels/inspector/styles/model.js +111 -0
- package/dist/panels/inspector/styles/segments.d.ts +18 -0
- package/dist/panels/inspector/styles/segments.d.ts.map +1 -0
- package/dist/panels/inspector/styles/segments.js +75 -0
- package/dist/panels/inspector/styles/sides-editor.d.ts +34 -0
- package/dist/panels/inspector/styles/sides-editor.d.ts.map +1 -0
- package/dist/panels/inspector/styles/sides-editor.js +86 -0
- package/dist/panels/inspector/styles/style-inspector.d.ts +15 -0
- package/dist/panels/inspector/styles/style-inspector.d.ts.map +1 -0
- package/dist/panels/inspector/styles/style-inspector.js +219 -0
- package/dist/panels/inspector/styles/style-inspector.test.d.ts +2 -0
- package/dist/panels/inspector/styles/style-inspector.test.d.ts.map +1 -0
- package/dist/panels/inspector/styles/style-inspector.test.js +265 -0
- package/dist/panels/inspector/styles/token-picker.d.ts +15 -0
- package/dist/panels/inspector/styles/token-picker.d.ts.map +1 -0
- package/dist/panels/inspector/styles/token-picker.js +23 -0
- package/dist/panels/inspector/styles/use-style-value.d.ts +28 -0
- package/dist/panels/inspector/styles/use-style-value.d.ts.map +1 -0
- package/dist/panels/inspector/styles/use-style-value.js +51 -0
- package/dist/panels/inspector/value.d.ts +20 -0
- package/dist/panels/inspector/value.d.ts.map +1 -0
- package/dist/panels/inspector/value.js +32 -0
- package/dist/panels/inspector/values/analyze.d.ts +49 -0
- package/dist/panels/inspector/values/analyze.d.ts.map +1 -0
- package/dist/panels/inspector/values/analyze.js +115 -0
- package/dist/panels/inspector/values/data.d.ts +18 -0
- package/dist/panels/inspector/values/data.d.ts.map +1 -0
- package/dist/panels/inspector/values/data.js +10 -0
- package/dist/panels/inspector/values/translation.d.ts +20 -0
- package/dist/panels/inspector/values/translation.d.ts.map +1 -0
- package/dist/panels/inspector/values/translation.js +25 -0
- package/dist/panels/inspector/values/value-editor.d.ts +30 -0
- package/dist/panels/inspector/values/value-editor.d.ts.map +1 -0
- package/dist/panels/inspector/values/value-editor.js +191 -0
- package/dist/panels/inspector/values/values.test.d.ts +2 -0
- package/dist/panels/inspector/values/values.test.d.ts.map +1 -0
- package/dist/panels/inspector/values/values.test.js +173 -0
- package/dist/panels/issues/collect.d.ts +70 -0
- package/dist/panels/issues/collect.d.ts.map +1 -0
- package/dist/panels/issues/collect.js +96 -0
- package/dist/panels/issues/index.d.ts +5 -0
- package/dist/panels/issues/index.d.ts.map +1 -0
- package/dist/panels/issues/index.js +2 -0
- package/dist/panels/issues/issues-panel.d.ts +17 -0
- package/dist/panels/issues/issues-panel.d.ts.map +1 -0
- package/dist/panels/issues/issues-panel.js +77 -0
- package/dist/panels/layers/flatten.d.ts +28 -0
- package/dist/panels/layers/flatten.d.ts.map +1 -0
- package/dist/panels/layers/flatten.js +61 -0
- package/dist/panels/layers/layers-panel.d.ts +14 -0
- package/dist/panels/layers/layers-panel.d.ts.map +1 -0
- package/dist/panels/layers/layers-panel.js +428 -0
- package/dist/panels/layers/layers-panel.test.d.ts +2 -0
- package/dist/panels/layers/layers-panel.test.d.ts.map +1 -0
- package/dist/panels/layers/layers-panel.test.js +315 -0
- package/dist/persistence/controller.d.ts +55 -0
- package/dist/persistence/controller.d.ts.map +1 -0
- package/dist/persistence/controller.js +341 -0
- package/dist/persistence/index.d.ts +6 -0
- package/dist/persistence/index.d.ts.map +1 -0
- package/dist/persistence/index.js +3 -0
- package/dist/persistence/load.d.ts +35 -0
- package/dist/persistence/load.d.ts.map +1 -0
- package/dist/persistence/load.js +67 -0
- package/dist/persistence/persistence.test.d.ts +2 -0
- package/dist/persistence/persistence.test.d.ts.map +1 -0
- package/dist/persistence/persistence.test.js +483 -0
- package/dist/persistence/react.d.ts +18 -0
- package/dist/persistence/react.d.ts.map +1 -0
- package/dist/persistence/react.js +105 -0
- package/dist/persistence/types.d.ts +182 -0
- package/dist/persistence/types.d.ts.map +1 -0
- package/dist/persistence/types.js +1 -0
- package/dist/preview/index.d.ts +3 -0
- package/dist/preview/index.d.ts.map +1 -0
- package/dist/preview/index.js +2 -0
- package/dist/preview/prepare.d.ts +16 -0
- package/dist/preview/prepare.d.ts.map +1 -0
- package/dist/preview/prepare.js +21 -0
- package/dist/preview/preview.d.ts +27 -0
- package/dist/preview/preview.d.ts.map +1 -0
- package/dist/preview/preview.js +51 -0
- package/dist/preview/preview.test.d.ts +2 -0
- package/dist/preview/preview.test.d.ts.map +1 -0
- package/dist/preview/preview.test.js +129 -0
- package/dist/shortcuts/actions.d.ts +17 -0
- package/dist/shortcuts/actions.d.ts.map +1 -0
- package/dist/shortcuts/actions.js +85 -0
- package/dist/shortcuts/index.d.ts +11 -0
- package/dist/shortcuts/index.d.ts.map +1 -0
- package/dist/shortcuts/index.js +5 -0
- package/dist/shortcuts/keys.d.ts +29 -0
- package/dist/shortcuts/keys.d.ts.map +1 -0
- package/dist/shortcuts/keys.js +100 -0
- package/dist/shortcuts/map.d.ts +17 -0
- package/dist/shortcuts/map.d.ts.map +1 -0
- package/dist/shortcuts/map.js +31 -0
- package/dist/shortcuts/registry.d.ts +32 -0
- package/dist/shortcuts/registry.d.ts.map +1 -0
- package/dist/shortcuts/registry.js +53 -0
- package/dist/shortcuts/shortcuts.d.ts +32 -0
- package/dist/shortcuts/shortcuts.d.ts.map +1 -0
- package/dist/shortcuts/shortcuts.js +95 -0
- package/dist/shortcuts/shortcuts.test.d.ts +2 -0
- package/dist/shortcuts/shortcuts.test.d.ts.map +1 -0
- package/dist/shortcuts/shortcuts.test.js +263 -0
- package/dist/store/create-store.d.ts +13 -0
- package/dist/store/create-store.d.ts.map +1 -0
- package/dist/store/create-store.js +248 -0
- package/dist/store/index.d.ts +9 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +5 -0
- package/dist/store/locale.d.ts +23 -0
- package/dist/store/locale.d.ts.map +1 -0
- package/dist/store/locale.js +31 -0
- package/dist/store/react.d.ts +17 -0
- package/dist/store/react.d.ts.map +1 -0
- package/dist/store/react.js +32 -0
- package/dist/store/selection.d.ts +32 -0
- package/dist/store/selection.d.ts.map +1 -0
- package/dist/store/selection.js +84 -0
- package/dist/store/selection.test.d.ts +2 -0
- package/dist/store/selection.test.d.ts.map +1 -0
- package/dist/store/selection.test.js +95 -0
- package/dist/store/selectors.d.ts +18 -0
- package/dist/store/selectors.d.ts.map +1 -0
- package/dist/store/selectors.js +39 -0
- package/dist/store/store.test.d.ts +2 -0
- package/dist/store/store.test.d.ts.map +1 -0
- package/dist/store/store.test.js +331 -0
- package/dist/store/types.d.ts +114 -0
- package/dist/store/types.d.ts.map +1 -0
- package/dist/store/types.js +1 -0
- package/dist/styles/tokens.test.d.ts +2 -0
- package/dist/styles/tokens.test.d.ts.map +1 -0
- package/dist/styles/tokens.test.js +199 -0
- package/dist/styles.css +2885 -0
- package/dist/toolbar/brand.d.ts +7 -0
- package/dist/toolbar/brand.d.ts.map +1 -0
- package/dist/toolbar/brand.js +11 -0
- package/dist/toolbar/breakpoint-control.d.ts +9 -0
- package/dist/toolbar/breakpoint-control.d.ts.map +1 -0
- package/dist/toolbar/breakpoint-control.js +23 -0
- package/dist/toolbar/editable-title.d.ts +14 -0
- package/dist/toolbar/editable-title.d.ts.map +1 -0
- package/dist/toolbar/editable-title.js +46 -0
- package/dist/toolbar/editable-title.test.d.ts +2 -0
- package/dist/toolbar/editable-title.test.d.ts.map +1 -0
- package/dist/toolbar/editable-title.test.js +53 -0
- package/dist/toolbar/index.d.ts +12 -0
- package/dist/toolbar/index.d.ts.map +1 -0
- package/dist/toolbar/index.js +5 -0
- package/dist/toolbar/locale-switcher.d.ts +10 -0
- package/dist/toolbar/locale-switcher.d.ts.map +1 -0
- package/dist/toolbar/locale-switcher.js +20 -0
- package/dist/toolbar/more-menu.d.ts +12 -0
- package/dist/toolbar/more-menu.d.ts.map +1 -0
- package/dist/toolbar/more-menu.js +47 -0
- package/dist/toolbar/panel-toggles.d.ts +9 -0
- package/dist/toolbar/panel-toggles.d.ts.map +1 -0
- package/dist/toolbar/panel-toggles.js +19 -0
- package/dist/toolbar/publish-dialog.d.ts +18 -0
- package/dist/toolbar/publish-dialog.d.ts.map +1 -0
- package/dist/toolbar/publish-dialog.js +49 -0
- package/dist/toolbar/publish.test.d.ts +2 -0
- package/dist/toolbar/publish.test.d.ts.map +1 -0
- package/dist/toolbar/publish.test.js +258 -0
- package/dist/toolbar/sample-picker.d.ts +18 -0
- package/dist/toolbar/sample-picker.d.ts.map +1 -0
- package/dist/toolbar/sample-picker.js +72 -0
- package/dist/toolbar/sample-picker.test.d.ts +2 -0
- package/dist/toolbar/sample-picker.test.d.ts.map +1 -0
- package/dist/toolbar/sample-picker.test.js +78 -0
- package/dist/toolbar/save-indicator.d.ts +8 -0
- package/dist/toolbar/save-indicator.d.ts.map +1 -0
- package/dist/toolbar/save-indicator.js +30 -0
- package/dist/toolbar/theme.d.ts +22 -0
- package/dist/toolbar/theme.d.ts.map +1 -0
- package/dist/toolbar/theme.js +46 -0
- package/dist/toolbar/theme.test.d.ts +2 -0
- package/dist/toolbar/theme.test.d.ts.map +1 -0
- package/dist/toolbar/theme.test.js +49 -0
- package/dist/toolbar/toolbar-centre.d.ts +13 -0
- package/dist/toolbar/toolbar-centre.d.ts.map +1 -0
- package/dist/toolbar/toolbar-centre.js +7 -0
- package/dist/toolbar/toolbar-left.d.ts +12 -0
- package/dist/toolbar/toolbar-left.d.ts.map +1 -0
- package/dist/toolbar/toolbar-left.js +16 -0
- package/dist/toolbar/toolbar-right.d.ts +19 -0
- package/dist/toolbar/toolbar-right.d.ts.map +1 -0
- package/dist/toolbar/toolbar-right.js +21 -0
- package/dist/toolbar/toolbar.d.ts +38 -0
- package/dist/toolbar/toolbar.d.ts.map +1 -0
- package/dist/toolbar/toolbar.js +27 -0
- package/dist/toolbar/toolbar.test.d.ts +2 -0
- package/dist/toolbar/toolbar.test.d.ts.map +1 -0
- package/dist/toolbar/toolbar.test.js +289 -0
- package/dist/toolbar/use-overflow-level.d.ts +9 -0
- package/dist/toolbar/use-overflow-level.d.ts.map +1 -0
- package/dist/toolbar/use-overflow-level.js +40 -0
- package/dist/toolbar/zoom-menu.d.ts +10 -0
- package/dist/toolbar/zoom-menu.d.ts.map +1 -0
- package/dist/toolbar/zoom-menu.js +17 -0
- package/dist/ui/icon.d.ts +102 -0
- package/dist/ui/icon.d.ts.map +1 -0
- package/dist/ui/icon.js +182 -0
- package/dist/ui/icon.test.d.ts +2 -0
- package/dist/ui/icon.test.d.ts.map +1 -0
- package/dist/ui/icon.test.js +115 -0
- package/dist/ui/index.d.ts +11 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +5 -0
- package/dist/ui/panel.d.ts +18 -0
- package/dist/ui/panel.d.ts.map +1 -0
- package/dist/ui/panel.js +21 -0
- package/dist/ui/portal.d.ts +14 -0
- package/dist/ui/portal.d.ts.map +1 -0
- package/dist/ui/portal.js +14 -0
- package/dist/ui/primitives.d.ts +190 -0
- package/dist/ui/primitives.d.ts.map +1 -0
- package/dist/ui/primitives.js +164 -0
- package/dist/ui/primitives.test.d.ts +2 -0
- package/dist/ui/primitives.test.d.ts.map +1 -0
- package/dist/ui/primitives.test.js +215 -0
- package/dist/ui/toast.d.ts +39 -0
- package/dist/ui/toast.d.ts.map +1 -0
- package/dist/ui/toast.js +76 -0
- package/dist/ui/toast.test.d.ts +2 -0
- package/dist/ui/toast.test.d.ts.map +1 -0
- package/dist/ui/toast.test.js +95 -0
- package/package.json +66 -3
- package/README.md +0 -3
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
+
import { CanvasFrame } from '../canvas-host/index.js';
|
|
4
|
+
import { ClipboardProvider, useClipboardActions } from '../clipboard/index.js';
|
|
5
|
+
import { MediaLibraryProvider } from '../dialogs/index.js';
|
|
6
|
+
import { DragProvider, useDragEngine, useRegisterCanvas, useRegisterDragHost, } from '../dnd/index.js';
|
|
7
|
+
import { MessagesProvider, useT } from '../messages/index.js';
|
|
8
|
+
import { Breadcrumbs, countIssues, InsertPanel, Inspector, InspectorDataProvider, IssuesPanel, LayersPanel, StyleInspector, useIssues, } from '../panels/index.js';
|
|
9
|
+
import { createPersistence, loadDocument, PersistenceProvider, useSaveAction, } from '../persistence/index.js';
|
|
10
|
+
import { usePreview } from '../preview/index.js';
|
|
11
|
+
import { ShortcutProvider, useForwardedKeys } from '../shortcuts/index.js';
|
|
12
|
+
import { createEditorStore, createLocaleStore, EditorStoreProvider, LocaleProvider, useLocaleState, } from '../store/index.js';
|
|
13
|
+
import { LocaleSwitcher, PublishDialog, SamplePicker, ThemeProvider, Toolbar, useThemePreference, } from '../toolbar/index.js';
|
|
14
|
+
import { PortalContainerProvider, Tabs, ToastProvider, useToast } from '../ui/index.js';
|
|
15
|
+
import { resolveConfig } from './config.js';
|
|
16
|
+
import { EditorLayout } from './layout.js';
|
|
17
|
+
import { ManifestProvider } from './manifest.js';
|
|
18
|
+
import { SmallScreenNotice, useViewportTooNarrow } from './small-screen.js';
|
|
19
|
+
import { StatusInfo } from './status-info.js';
|
|
20
|
+
const SINGLE_LOCALE = {
|
|
21
|
+
locales: ['en'],
|
|
22
|
+
default: 'en',
|
|
23
|
+
fallback: true,
|
|
24
|
+
intl: { en: 'English' },
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* The whole editor (docs/editor.md#the-editor-app): loads the document of `documentRef` through
|
|
28
|
+
* the adapter, creates its store and autosave, and composes the toolbar, the panels, the canvas
|
|
29
|
+
* and the dialogs. `BuilderEditor` is the bare shell; hosts mount this one.
|
|
30
|
+
*/
|
|
31
|
+
export function EditorApp(props) {
|
|
32
|
+
const config = useMemo(() => resolveConfig(props.config), [props.config]);
|
|
33
|
+
const { adapter, documentRef, registry } = props;
|
|
34
|
+
// The host's `config.theme` wins; otherwise the author's remembered light / dark / system choice.
|
|
35
|
+
const theme = useThemePreference(config.theme);
|
|
36
|
+
// Menus, popovers and dialogs render inside the root, so they inherit its `data-theme`.
|
|
37
|
+
const [root, setRoot] = useState(null);
|
|
38
|
+
const [phase, setPhase] = useState({ kind: 'loading' });
|
|
39
|
+
// A window too narrow to edit in keeps the editor from opening (nothing is loaded); one that is
|
|
40
|
+
// already open stays open when the window shrinks, so no work is torn down.
|
|
41
|
+
const narrow = useViewportTooNarrow(config.minViewportWidth);
|
|
42
|
+
// `undefined`: not measured yet (server render, hydration) - show the loading state, load nothing.
|
|
43
|
+
const blocked = narrow === true && phase.kind !== 'ready';
|
|
44
|
+
const waiting = narrow === undefined && phase.kind !== 'ready';
|
|
45
|
+
const refKey = `${documentRef.collection}:${documentRef.id}`;
|
|
46
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: `documentRef` is identified by `refKey`
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
if (blocked || waiting)
|
|
49
|
+
return;
|
|
50
|
+
let cancelled = false;
|
|
51
|
+
setPhase({ kind: 'loading' });
|
|
52
|
+
void (async () => {
|
|
53
|
+
try {
|
|
54
|
+
const [loaded, session] = await Promise.all([
|
|
55
|
+
loadDocument(adapter, documentRef),
|
|
56
|
+
adapter.getSession(documentRef),
|
|
57
|
+
]);
|
|
58
|
+
if (cancelled)
|
|
59
|
+
return;
|
|
60
|
+
const locales = props.locales ?? session.locales ?? SINGLE_LOCALE;
|
|
61
|
+
const store = createEditorStore({
|
|
62
|
+
doc: loaded.document,
|
|
63
|
+
registry,
|
|
64
|
+
readOnly: loaded.readOnly === true,
|
|
65
|
+
locales,
|
|
66
|
+
});
|
|
67
|
+
const persistence = createPersistence({
|
|
68
|
+
store,
|
|
69
|
+
adapter,
|
|
70
|
+
ref: documentRef,
|
|
71
|
+
revision: loaded.revision,
|
|
72
|
+
debounceMs: config.autosave.debounceMs,
|
|
73
|
+
maxWaitMs: config.autosave.maxWaitMs,
|
|
74
|
+
});
|
|
75
|
+
setPhase({
|
|
76
|
+
kind: 'ready',
|
|
77
|
+
loaded,
|
|
78
|
+
store,
|
|
79
|
+
persistence,
|
|
80
|
+
canPublish: session.canPublish,
|
|
81
|
+
localeStore: createLocaleStore(locales),
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
if (!cancelled)
|
|
86
|
+
setPhase({ kind: 'error' });
|
|
87
|
+
}
|
|
88
|
+
})();
|
|
89
|
+
return () => {
|
|
90
|
+
cancelled = true;
|
|
91
|
+
};
|
|
92
|
+
}, [
|
|
93
|
+
adapter,
|
|
94
|
+
refKey,
|
|
95
|
+
registry,
|
|
96
|
+
props.locales,
|
|
97
|
+
blocked,
|
|
98
|
+
waiting,
|
|
99
|
+
config.autosave.debounceMs,
|
|
100
|
+
config.autosave.maxWaitMs,
|
|
101
|
+
]);
|
|
102
|
+
return (_jsx(MessagesProvider, { locale: config.uiLocale, children: _jsx(ThemeProvider, { value: theme, children: _jsx(PortalContainerProvider, { container: root, children: _jsx("div", { ref: setRoot, className: "buildr-editor", lang: config.uiLocale, ...(theme.attribute !== 'system' ? { 'data-theme': theme.attribute } : {}), children: blocked ? (_jsx(SmallScreenNotice, {})) : phase.kind === 'ready' ? (_jsx(Session, { ...props, ready: phase })) : (_jsx(Status, { failed: !waiting && phase.kind === 'error' })) }) }) }) }));
|
|
103
|
+
}
|
|
104
|
+
function Status({ failed }) {
|
|
105
|
+
const t = useT();
|
|
106
|
+
return (_jsx("p", { className: "bd-app-status", role: failed ? 'alert' : 'status', children: t(failed ? 'app.error' : 'app.loading') }));
|
|
107
|
+
}
|
|
108
|
+
function Session(props) {
|
|
109
|
+
const { ready, adapter, manifest } = props;
|
|
110
|
+
const config = useMemo(() => resolveConfig(props.config), [props.config]);
|
|
111
|
+
return (_jsx(ToastProvider, { children: _jsx(EditorStoreProvider, { store: ready.store, children: _jsx(LocaleProvider, { store: ready.localeStore, children: _jsx(ManifestProvider, { manifest: manifest, children: _jsx(PersistenceProvider, { controller: ready.persistence, children: _jsx(MediaLibraryProvider, { media: adapter.media, children: _jsx(DragProvider, { children: _jsx(ClipboardProvider, { migrations: props.migrations, children: _jsx(Keys, { overrides: config.shortcuts, children: _jsx(Shell, { ...props }) }) }) }) }) }) }) }) }) }));
|
|
112
|
+
}
|
|
113
|
+
/** The shortcuts, with the actions the clipboard and the persistence provide. */
|
|
114
|
+
function Keys(props) {
|
|
115
|
+
const clipboard = useClipboardActions();
|
|
116
|
+
const save = useSaveAction();
|
|
117
|
+
const actions = useMemo(() => ({ ...clipboard, save }), [clipboard, save]);
|
|
118
|
+
return (_jsx(ShortcutProvider, { overrides: props.overrides, actions: actions, children: props.children }));
|
|
119
|
+
}
|
|
120
|
+
function useDataContext(adapter, ref) {
|
|
121
|
+
const [schema, setSchema] = useState();
|
|
122
|
+
const [context, setContext] = useState();
|
|
123
|
+
const key = `${ref.collection}:${ref.id}`;
|
|
124
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: `ref` is identified by `key`
|
|
125
|
+
useEffect(() => {
|
|
126
|
+
let cancelled = false;
|
|
127
|
+
void adapter.getDataSchema(ref).then((next) => !cancelled && setSchema(next), () => undefined);
|
|
128
|
+
void adapter.getContext(ref).then((next) => !cancelled && setContext(next), () => undefined);
|
|
129
|
+
return () => {
|
|
130
|
+
cancelled = true;
|
|
131
|
+
};
|
|
132
|
+
}, [adapter, key]);
|
|
133
|
+
return { schema, context };
|
|
134
|
+
}
|
|
135
|
+
function Shell(props) {
|
|
136
|
+
const t = useT();
|
|
137
|
+
const { adapter, documentRef, canvasUrl, manifest, ready } = props;
|
|
138
|
+
const config = useMemo(() => resolveConfig(props.config), [props.config]);
|
|
139
|
+
const locales = useLocaleState((state) => state.config);
|
|
140
|
+
const locale = useLocaleState((state) => state.locale);
|
|
141
|
+
const wireLocales = useMemo(() => ({ ...locales, locales: [...locales.locales], intl: { ...locales.intl } }), [locales]);
|
|
142
|
+
const [host, setHost] = useState(null);
|
|
143
|
+
const [breakpoint, setBreakpoint] = useState(config.breakpoints[0]?.id ?? 'desktop');
|
|
144
|
+
const [zoom, setZoom] = useState('fit');
|
|
145
|
+
const [publishOpen, setPublishOpen] = useState(false);
|
|
146
|
+
const [diagnostics, setDiagnostics] = useState([]);
|
|
147
|
+
const area = useRef(null);
|
|
148
|
+
const engine = useDragEngine();
|
|
149
|
+
const forward = useForwardedKeys();
|
|
150
|
+
const data = useDataContext(adapter, documentRef);
|
|
151
|
+
const preview = usePreview({ adapter, docRef: documentRef });
|
|
152
|
+
const toast = useToast();
|
|
153
|
+
const previewError = preview.error;
|
|
154
|
+
const [title, setTitle] = useState(ready.loaded.title);
|
|
155
|
+
const canRename = adapter.rename !== undefined;
|
|
156
|
+
const changeTitle = useCallback(async (next) => {
|
|
157
|
+
try {
|
|
158
|
+
const saved = await adapter.rename?.(documentRef, next);
|
|
159
|
+
if (saved !== undefined)
|
|
160
|
+
setTitle(saved.title);
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
toast.show({ id: 'rename', variant: 'error', message: t('toolbar.title.renameFailed') });
|
|
164
|
+
throw error;
|
|
165
|
+
}
|
|
166
|
+
}, [adapter, documentRef, toast, t]);
|
|
167
|
+
useEffect(() => {
|
|
168
|
+
if (previewError === '')
|
|
169
|
+
toast.dismiss('preview');
|
|
170
|
+
else
|
|
171
|
+
toast.show({ id: 'preview', variant: 'error', message: previewError });
|
|
172
|
+
}, [previewError, toast]);
|
|
173
|
+
const issueCounts = countIssues(useIssues(diagnostics));
|
|
174
|
+
useRegisterDragHost(host);
|
|
175
|
+
useRegisterCanvas(() => {
|
|
176
|
+
const frame = area.current?.querySelector('iframe');
|
|
177
|
+
if (frame === null || frame === undefined)
|
|
178
|
+
return undefined;
|
|
179
|
+
const box = frame.getBoundingClientRect();
|
|
180
|
+
return {
|
|
181
|
+
frame: { left: box.left, top: box.top, width: box.width, height: box.height },
|
|
182
|
+
scale: frame.offsetWidth > 0 ? box.width / frame.offsetWidth : 1,
|
|
183
|
+
};
|
|
184
|
+
});
|
|
185
|
+
useEffect(() => {
|
|
186
|
+
if (host === null)
|
|
187
|
+
return;
|
|
188
|
+
return host.state.subscribe((state) => {
|
|
189
|
+
setDiagnostics(state.diagnostics);
|
|
190
|
+
setZoom(state.zoom);
|
|
191
|
+
});
|
|
192
|
+
}, [host]);
|
|
193
|
+
const changeBreakpoint = useCallback((id) => {
|
|
194
|
+
setBreakpoint(id);
|
|
195
|
+
host?.setBreakpoint(id);
|
|
196
|
+
}, [host]);
|
|
197
|
+
return (_jsxs(_Fragment, { children: [_jsx(EditorLayout, { toolbar: _jsx(Toolbar, { title: title, onTitleChange: canRename ? changeTitle : undefined, status: ready.loaded.status, breakpoints: config.breakpoints, breakpoint: breakpoint, onBreakpointChange: changeBreakpoint, zoom: zoom, onZoomChange: (next) => host?.setZoom(next), cmsUrl: adapter.cmsUrl?.(documentRef), onPreview: preview.preview, onPublish: () => setPublishOpen(true), canPublish: ready.canPublish, pickers: _jsxs(_Fragment, { children: [_jsx(LocaleSwitcher, { onChange: (next) => host?.setLocale(next) }), _jsx(SamplePicker, { adapter: adapter, docRef: documentRef, onChange: (contextRef) => host?.setContextRef(contextRef ?? ready.loaded.contextRef ?? null) })] }) }), left: _jsx(Tabs, { label: t('editor.leftPanel'), items: [
|
|
198
|
+
{ value: 'insert', label: t('insert.title'), content: _jsx(InsertPanel, {}) },
|
|
199
|
+
{ value: 'layers', label: t('layers.title'), content: _jsx(LayersPanel, {}) },
|
|
200
|
+
] }), center: _jsxs("div", { className: "bd-app-canvas", ref: area, children: [_jsx(CanvasFrame, { canvasUrl: canvasUrl, manifestHash: manifest.hash, locales: wireLocales, locale: locale, breakpoints: config.breakpoints, breakpoint: breakpoint, contextRef: ready.loaded.contextRef ?? null, onHost: setHost, callbacks: {
|
|
201
|
+
onKeyDown: (event) => {
|
|
202
|
+
forward({ key: event.key, mods: event.mods });
|
|
203
|
+
},
|
|
204
|
+
onDropTarget: (event) => engine.receiveTarget(event.target, event.reason),
|
|
205
|
+
} }), _jsx(Breadcrumbs, {})] }), right: _jsx(InspectorDataProvider, { schema: data.schema, context: data.context, children: _jsx(Inspector, { locale: locale, defaultLocale: locales.default, renderStyle: (node) => (_jsx(StyleInspector, { node: node, ...(breakpoint === config.breakpoints[0]?.id ? {} : { breakpoint }) })) }) }), issues: _jsx(IssuesPanel, { canvasDiagnostics: diagnostics }), issueCounts: issueCounts, status: _jsx(StatusInfo, { host: host, breakpoints: config.breakpoints, breakpoint: breakpoint }) }), _jsx(PublishDialog, { open: publishOpen, onOpenChange: setPublishOpen, canvasDiagnostics: diagnostics }), preview.overlay] }));
|
|
206
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editor-app.test.d.ts","sourceRoot":"","sources":["../../src/app/editor-app.test.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// @vitest-environment jsdom
|
|
3
|
+
import { createRegistryMeta, toManifest, } from '@next-buildr/core';
|
|
4
|
+
import { act } from 'react';
|
|
5
|
+
import { createRoot } from 'react-dom/client';
|
|
6
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
7
|
+
import { EditorApp } from './editor-app.js';
|
|
8
|
+
globalThis.IS_REACT_ACT_ENVIRONMENT = true;
|
|
9
|
+
const item = {
|
|
10
|
+
type: 'buildr/item',
|
|
11
|
+
version: 1,
|
|
12
|
+
label: 'Item',
|
|
13
|
+
category: 'content',
|
|
14
|
+
props: {},
|
|
15
|
+
contentCategories: ['flow'],
|
|
16
|
+
styles: { groups: [] },
|
|
17
|
+
runtime: 'shared',
|
|
18
|
+
slots: { default: {} },
|
|
19
|
+
};
|
|
20
|
+
const page = {
|
|
21
|
+
...item,
|
|
22
|
+
type: 'buildr/page',
|
|
23
|
+
label: 'Page',
|
|
24
|
+
capabilities: { root: true },
|
|
25
|
+
};
|
|
26
|
+
const registry = createRegistryMeta({ components: [page, item] });
|
|
27
|
+
const document = {
|
|
28
|
+
schemaVersion: 1,
|
|
29
|
+
root: 'root',
|
|
30
|
+
nodes: {
|
|
31
|
+
root: { id: 'root', type: 'buildr/page', slots: { default: ['itemAAAAA1'] } },
|
|
32
|
+
itemAAAAA1: { id: 'itemAAAAA1', type: 'buildr/item', name: 'First' },
|
|
33
|
+
},
|
|
34
|
+
components: { 'buildr/page': 1, 'buildr/item': 1 },
|
|
35
|
+
};
|
|
36
|
+
const adapter = (overrides = {}) => ({
|
|
37
|
+
getSession: async () => ({ canEdit: true, canPublish: true }),
|
|
38
|
+
load: async () => ({
|
|
39
|
+
title: 'My page',
|
|
40
|
+
status: 'draft',
|
|
41
|
+
updatedAt: '2026-01-01T00:00:00.000Z',
|
|
42
|
+
revision: 1,
|
|
43
|
+
document,
|
|
44
|
+
}),
|
|
45
|
+
save: async (_ref, { baseRevision }) => ({ ok: true, revision: baseRevision + 1, updatedAt: '' }),
|
|
46
|
+
publish: async (_ref, { baseRevision }) => ({
|
|
47
|
+
ok: true,
|
|
48
|
+
revision: baseRevision,
|
|
49
|
+
updatedAt: '',
|
|
50
|
+
}),
|
|
51
|
+
getDataSchema: async () => ({ scopes: {}, entities: {} }),
|
|
52
|
+
getContext: async () => ({
|
|
53
|
+
scopes: {},
|
|
54
|
+
locale: 'en',
|
|
55
|
+
locales: { default: 'en', fallback: true, intl: { en: 'English' } },
|
|
56
|
+
timeZone: 'UTC',
|
|
57
|
+
mode: 'preview',
|
|
58
|
+
}),
|
|
59
|
+
media: { search: async () => ({ items: [] }) },
|
|
60
|
+
previewUrl: () => '/preview',
|
|
61
|
+
...overrides,
|
|
62
|
+
});
|
|
63
|
+
describe('EditorApp', () => {
|
|
64
|
+
let container;
|
|
65
|
+
let root;
|
|
66
|
+
beforeEach(() => {
|
|
67
|
+
container = window.document.createElement('div');
|
|
68
|
+
window.document.body.append(container);
|
|
69
|
+
root = createRoot(container);
|
|
70
|
+
Element.prototype.scrollIntoView ??= () => { };
|
|
71
|
+
});
|
|
72
|
+
afterEach(() => {
|
|
73
|
+
act(() => root.unmount());
|
|
74
|
+
container.remove();
|
|
75
|
+
});
|
|
76
|
+
const props = (a) => ({
|
|
77
|
+
adapter: a,
|
|
78
|
+
manifest: toManifest(registry),
|
|
79
|
+
registry,
|
|
80
|
+
canvasUrl: 'http://localhost:9/canvas',
|
|
81
|
+
documentRef: { collection: 'pages', id: '1' },
|
|
82
|
+
});
|
|
83
|
+
const show = async (a) => {
|
|
84
|
+
await act(async () => root.render(_jsx(EditorApp, { ...props(a) })));
|
|
85
|
+
// The load and the data requests settle after the first render.
|
|
86
|
+
await act(async () => undefined);
|
|
87
|
+
};
|
|
88
|
+
it('says it is loading, then shows the toolbar, the panels and the canvas', async () => {
|
|
89
|
+
let release = () => undefined;
|
|
90
|
+
const gate = new Promise((resolve) => {
|
|
91
|
+
release = resolve;
|
|
92
|
+
});
|
|
93
|
+
const a = adapter({
|
|
94
|
+
getSession: async () => {
|
|
95
|
+
await gate;
|
|
96
|
+
return { canEdit: true, canPublish: true };
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
await act(async () => root.render(_jsx(EditorApp, { ...props(a) })));
|
|
100
|
+
expect(container.querySelector('[role=status]')?.textContent).toContain('Loading');
|
|
101
|
+
await act(async () => {
|
|
102
|
+
release();
|
|
103
|
+
});
|
|
104
|
+
await act(async () => undefined);
|
|
105
|
+
expect(container.querySelector('h1')?.textContent).toBe('My page');
|
|
106
|
+
expect(container.querySelector('iframe')).not.toBeNull();
|
|
107
|
+
expect(container.textContent).toContain('Insert');
|
|
108
|
+
expect(container.textContent).toContain('Publish');
|
|
109
|
+
});
|
|
110
|
+
it('shows an error when the document cannot be opened', async () => {
|
|
111
|
+
await show(adapter({
|
|
112
|
+
load: async () => {
|
|
113
|
+
throw new Error('nope');
|
|
114
|
+
},
|
|
115
|
+
}));
|
|
116
|
+
expect(container.querySelector('[role=alert]')?.textContent).toContain('could not be opened');
|
|
117
|
+
});
|
|
118
|
+
it('offers the Layers tab and does not save an untouched document', async () => {
|
|
119
|
+
vi.useFakeTimers({ toFake: ['setTimeout', 'clearTimeout'] });
|
|
120
|
+
try {
|
|
121
|
+
const save = vi.fn(async (_ref, { baseRevision }) => ({
|
|
122
|
+
ok: true,
|
|
123
|
+
revision: baseRevision + 1,
|
|
124
|
+
updatedAt: '',
|
|
125
|
+
}));
|
|
126
|
+
await show(adapter({ save: save }));
|
|
127
|
+
const layers = [...container.querySelectorAll('[role=tab]')].find((tab) => tab.textContent === 'Layers');
|
|
128
|
+
expect(layers).toBeDefined();
|
|
129
|
+
expect(save).not.toHaveBeenCalled();
|
|
130
|
+
}
|
|
131
|
+
finally {
|
|
132
|
+
vi.useRealTimers();
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
export interface IssueCounts {
|
|
3
|
+
readonly error: number;
|
|
4
|
+
readonly warning: number;
|
|
5
|
+
}
|
|
6
|
+
export interface EditorLayoutProps {
|
|
7
|
+
readonly toolbar?: ReactNode;
|
|
8
|
+
/** The insert and layers panels. */
|
|
9
|
+
readonly left?: ReactNode;
|
|
10
|
+
/** The canvas. */
|
|
11
|
+
readonly center?: ReactNode;
|
|
12
|
+
/** The inspector. */
|
|
13
|
+
readonly right?: ReactNode;
|
|
14
|
+
/** The issues panel's content. */
|
|
15
|
+
readonly issues?: ReactNode;
|
|
16
|
+
/** Error and warning counts shown on the status bar's issues toggle. */
|
|
17
|
+
readonly issueCounts?: IssueCounts | undefined;
|
|
18
|
+
/** Read-only facts on the right of the status bar (breakpoint, zoom, save state). */
|
|
19
|
+
readonly status?: ReactNode;
|
|
20
|
+
}
|
|
21
|
+
/** Below this editor width the side panels become overlays (the editor may be embedded: measured, not a media query). */
|
|
22
|
+
export declare const NARROW_BELOW = 1100;
|
|
23
|
+
/** The canvas never gets narrower than this while the panels sit beside it. */
|
|
24
|
+
export declare const CANVAS_MIN = 480;
|
|
25
|
+
/**
|
|
26
|
+
* The shell's three columns and the status bar: toolbar on top, the left panel, the canvas and
|
|
27
|
+
* the inspector between two splitters, the status bar with the collapsible issues drawer at the
|
|
28
|
+
* bottom. Each region is a landmark with a translated name; the panels themselves are slots the
|
|
29
|
+
* later tasks fill. Below `NARROW_BELOW` the side panels are overlays the toolbar toggles.
|
|
30
|
+
*/
|
|
31
|
+
export declare function EditorLayout({ toolbar, left, center, right, issues, issueCounts, status, }: EditorLayoutProps): import("react").JSX.Element;
|
|
32
|
+
//# sourceMappingURL=layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/app/layout.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,SAAS,EAQf,MAAM,OAAO,CAAC;AAMf,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC;IAC7B,oCAAoC;IACpC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC;IAC1B,kBAAkB;IAClB,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAC5B,qBAAqB;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;IAC3B,kCAAkC;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAC5B,wEAAwE;IACxE,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAC/C,qFAAqF;IACrF,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;CAC7B;AAmCD,yHAAyH;AACzH,eAAO,MAAM,YAAY,OAAO,CAAC;AACjC,+EAA+E;AAC/E,eAAO,MAAM,UAAU,MAAM,CAAC;AAsB9B;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,IAAI,EACJ,MAAM,EACN,KAAK,EACL,MAAM,EACN,WAAW,EACX,MAAM,GACP,EAAE,iBAAiB,+BAiInB"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useId, useMemo, useRef, useState, } from 'react';
|
|
3
|
+
import { useT } from '../messages/index.js';
|
|
4
|
+
import { Button, Icon, Panel } from '../ui/index.js';
|
|
5
|
+
import { ShellPanelsContext } from './shell-panels.js';
|
|
6
|
+
import { useResizable } from './use-resizable.js';
|
|
7
|
+
/**
|
|
8
|
+
* A vertical separator that can be dragged or moved with the keyboard (the WAI-ARIA window
|
|
9
|
+
* splitter); double-click puts it back. It draws a 1px line and has a wider invisible hit area.
|
|
10
|
+
*/
|
|
11
|
+
function Splitter({ resizable, min, max, label, controls }) {
|
|
12
|
+
return (_jsx("div", { role: "separator", "aria-orientation": "vertical", "aria-label": label, "aria-controls": controls, "aria-valuenow": resizable.size, "aria-valuemin": min, "aria-valuemax": max, tabIndex: 0, className: "bd-splitter", "data-dragging": resizable.dragging, ...resizable.bind }));
|
|
13
|
+
}
|
|
14
|
+
const LEFT = { initial: 280, min: 200, max: 480 };
|
|
15
|
+
const RIGHT = { initial: 320, min: 240, max: 520 };
|
|
16
|
+
/** Below this editor width the side panels become overlays (the editor may be embedded: measured, not a media query). */
|
|
17
|
+
export const NARROW_BELOW = 1100;
|
|
18
|
+
/** The canvas never gets narrower than this while the panels sit beside it. */
|
|
19
|
+
export const CANVAS_MIN = 480;
|
|
20
|
+
const SPLITTERS = 2;
|
|
21
|
+
/** The editor's own width, watched with a `ResizeObserver`; 0 while unknown (jsdom). */
|
|
22
|
+
function useEditorWidth(ref) {
|
|
23
|
+
const [width, setWidth] = useState(0);
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
const element = ref.current;
|
|
26
|
+
const root = element?.closest('.buildr-editor') ?? element?.parentElement;
|
|
27
|
+
if (root === null || root === undefined)
|
|
28
|
+
return;
|
|
29
|
+
setWidth(root.clientWidth);
|
|
30
|
+
if (typeof ResizeObserver === 'undefined')
|
|
31
|
+
return;
|
|
32
|
+
const observer = new ResizeObserver((entries) => {
|
|
33
|
+
const box = entries[0]?.contentRect;
|
|
34
|
+
if (box !== undefined)
|
|
35
|
+
setWidth(box.width);
|
|
36
|
+
});
|
|
37
|
+
observer.observe(root);
|
|
38
|
+
return () => observer.disconnect();
|
|
39
|
+
}, [ref]);
|
|
40
|
+
return width;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The shell's three columns and the status bar: toolbar on top, the left panel, the canvas and
|
|
44
|
+
* the inspector between two splitters, the status bar with the collapsible issues drawer at the
|
|
45
|
+
* bottom. Each region is a landmark with a translated name; the panels themselves are slots the
|
|
46
|
+
* later tasks fill. Below `NARROW_BELOW` the side panels are overlays the toolbar toggles.
|
|
47
|
+
*/
|
|
48
|
+
export function EditorLayout({ toolbar, left, center, right, issues, issueCounts, status, }) {
|
|
49
|
+
const t = useT();
|
|
50
|
+
const ids = { left: useId(), right: useId(), issues: useId() };
|
|
51
|
+
const leftSize = useResizable({ ...LEFT, direction: 1, storageKey: 'buildr:editor:left-width' });
|
|
52
|
+
const rightSize = useResizable({
|
|
53
|
+
...RIGHT,
|
|
54
|
+
direction: -1,
|
|
55
|
+
storageKey: 'buildr:editor:right-width',
|
|
56
|
+
});
|
|
57
|
+
const [issuesOpen, setIssuesOpen] = useState(false);
|
|
58
|
+
const [overlay, setOverlay] = useState({ left: false, right: false });
|
|
59
|
+
const toolbarRef = useRef(null);
|
|
60
|
+
const width = useEditorWidth(toolbarRef);
|
|
61
|
+
const narrow = width > 0 && width < NARROW_BELOW;
|
|
62
|
+
const toggle = useCallback((side) => setOverlay((current) => ({
|
|
63
|
+
left: side === 'left' && !current.left,
|
|
64
|
+
right: side === 'right' && !current.right,
|
|
65
|
+
})), []);
|
|
66
|
+
const panels = useMemo(() => ({ narrow, open: overlay, toggle }), [narrow, overlay, toggle]);
|
|
67
|
+
// Beside the canvas, the panels give way so it keeps CANVAS_MIN (never below their own minimum).
|
|
68
|
+
const room = width > 0 && !narrow ? width - CANVAS_MIN - SPLITTERS : Number.POSITIVE_INFINITY;
|
|
69
|
+
const leftShown = Math.max(LEFT.min, Math.min(leftSize.size, room - RIGHT.min));
|
|
70
|
+
const rightShown = Math.max(RIGHT.min, Math.min(rightSize.size, room - leftShown));
|
|
71
|
+
const style = {
|
|
72
|
+
'--bd-left': `${leftShown}px`,
|
|
73
|
+
'--bd-right': `${rightShown}px`,
|
|
74
|
+
};
|
|
75
|
+
const closeOnEscape = (side) => (event) => {
|
|
76
|
+
if (narrow && event.key === 'Escape' && overlay[side]) {
|
|
77
|
+
event.stopPropagation();
|
|
78
|
+
setOverlay((current) => ({ ...current, [side]: false }));
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
return (_jsxs(ShellPanelsContext.Provider, { value: panels, children: [_jsx("div", { className: "bd-toolbar", role: "toolbar", "aria-label": t('editor.toolbar'), ref: toolbarRef, children: toolbar }), _jsxs("div", { className: "bd-body", style: style, "data-narrow": narrow, children: [_jsx(Panel, { as: "aside", id: ids.left, "aria-label": t('editor.leftPanel'), hidden: narrow && !overlay.left, "data-side": "left", onKeyDown: closeOnEscape('left'), children: left }), _jsx(Splitter, { resizable: leftSize, min: LEFT.min, max: LEFT.max, label: t('editor.resize.left'), controls: ids.left }), _jsx("main", { className: "bd-canvas", "aria-label": t('editor.canvas'), children: center }), _jsx(Splitter, { resizable: rightSize, min: RIGHT.min, max: RIGHT.max, label: t('editor.resize.right'), controls: ids.right }), _jsx(Panel, { as: "aside", id: ids.right, "aria-label": t('editor.inspector'), hidden: narrow && !overlay.right, "data-side": "right", onKeyDown: closeOnEscape('right'), children: right })] }), _jsxs("section", { className: "bd-issues", "data-open": issuesOpen, "aria-label": t('editor.issues'), children: [_jsxs("div", { className: "bd-issues-bar", children: [_jsxs(Button, { variant: "ghost", className: "bd-status-toggle", "aria-expanded": issuesOpen, "aria-controls": ids.issues, onClick: () => setIssuesOpen((open) => !open), children: [issueCounts !== undefined && (_jsxs(_Fragment, { children: [_jsxs("span", { className: "bd-status-count", "data-severity": "error", title: t('editor.status.errors'), children: [_jsx(Icon, { name: "circle-alert" }), issueCounts.error] }), _jsxs("span", { className: "bd-status-count", "data-severity": "warning", title: t('editor.status.warnings'), children: [_jsx(Icon, { name: "triangle-alert" }), issueCounts.warning] })] })), issuesOpen ? t('editor.issues.hide') : t('editor.issues.show')] }), _jsx("span", { className: "bd-toolbar-spacer" }), status] }), _jsx("div", { id: ids.issues, hidden: !issuesOpen, children: issues })] })] }));
|
|
82
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ComponentMeta, RegistryManifest } from '@next-buildr/core';
|
|
2
|
+
import { type ReactNode } from 'react';
|
|
3
|
+
/** What the palette, the layers and the inspector know about the components (`toManifest`). */
|
|
4
|
+
export declare function ManifestProvider(props: {
|
|
5
|
+
readonly manifest: RegistryManifest;
|
|
6
|
+
readonly children: ReactNode;
|
|
7
|
+
}): import("react").JSX.Element;
|
|
8
|
+
/** The manifest, or `undefined` outside a `ManifestProvider` (the panels then fall back to the component's type). */
|
|
9
|
+
export declare function useManifest(): RegistryManifest | undefined;
|
|
10
|
+
/** One component's metadata, or `undefined` when the manifest does not have it. */
|
|
11
|
+
export declare function componentMeta(manifest: RegistryManifest | undefined, type: string): ComponentMeta | undefined;
|
|
12
|
+
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/app/manifest.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAiB,KAAK,SAAS,EAAc,MAAM,OAAO,CAAC;AAIlE,+FAA+F;AAC/F,wBAAgB,gBAAgB,CAAC,KAAK,EAAE;IACtC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;CAC9B,+BAIA;AAED,qHAAqH;AACrH,wBAAgB,WAAW,IAAI,gBAAgB,GAAG,SAAS,CAE1D;AAED,mFAAmF;AACnF,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,gBAAgB,GAAG,SAAS,EACtC,IAAI,EAAE,MAAM,GACX,aAAa,GAAG,SAAS,CAI3B"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext } from 'react';
|
|
3
|
+
const ManifestContext = createContext(undefined);
|
|
4
|
+
/** What the palette, the layers and the inspector know about the components (`toManifest`). */
|
|
5
|
+
export function ManifestProvider(props) {
|
|
6
|
+
return (_jsx(ManifestContext.Provider, { value: props.manifest, children: props.children }));
|
|
7
|
+
}
|
|
8
|
+
/** The manifest, or `undefined` outside a `ManifestProvider` (the panels then fall back to the component's type). */
|
|
9
|
+
export function useManifest() {
|
|
10
|
+
return useContext(ManifestContext);
|
|
11
|
+
}
|
|
12
|
+
/** One component's metadata, or `undefined` when the manifest does not have it. */
|
|
13
|
+
export function componentMeta(manifest, type) {
|
|
14
|
+
return manifest !== undefined && Object.hasOwn(manifest.components, type)
|
|
15
|
+
? manifest.components[type]
|
|
16
|
+
: undefined;
|
|
17
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type PanelSide = 'left' | 'right';
|
|
2
|
+
/**
|
|
3
|
+
* The side panels' overlay mode (below 1100px the layout hides them and the toolbar's toggle
|
|
4
|
+
* buttons open one at a time). Provided by `EditorLayout`; without it (a toolbar outside the
|
|
5
|
+
* layout) there is nothing to toggle.
|
|
6
|
+
*/
|
|
7
|
+
export interface ShellPanels {
|
|
8
|
+
/** The editor is narrower than the overlay breakpoint. */
|
|
9
|
+
readonly narrow: boolean;
|
|
10
|
+
readonly open: Readonly<Record<PanelSide, boolean>>;
|
|
11
|
+
toggle(side: PanelSide): void;
|
|
12
|
+
}
|
|
13
|
+
export declare const ShellPanelsContext: import("react").Context<ShellPanels | undefined>;
|
|
14
|
+
export declare function useShellPanels(): ShellPanels | undefined;
|
|
15
|
+
//# sourceMappingURL=shell-panels.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-panels.d.ts","sourceRoot":"","sources":["../../src/app/shell-panels.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;AAEzC;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;IACpD,MAAM,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;CAC/B;AAED,eAAO,MAAM,kBAAkB,kDAAoD,CAAC;AAEpF,wBAAgB,cAAc,IAAI,WAAW,GAAG,SAAS,CAExD"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether the window is narrower than `minWidth` CSS pixels, kept current as it is resized or
|
|
3
|
+
* rotated. `0` (or less) never is; without `matchMedia` (a test) the window is taken as wide enough.
|
|
4
|
+
*
|
|
5
|
+
* `undefined` means "not known yet": the server has no window, and a hydrating client must render
|
|
6
|
+
* what the server rendered, so both start unknown and the client resolves it right after hydration
|
|
7
|
+
* (a plain client render resolves it at once). Callers render a neutral state meanwhile.
|
|
8
|
+
*/
|
|
9
|
+
export declare function useViewportTooNarrow(minWidth: number): boolean | undefined;
|
|
10
|
+
/** Shown instead of the editor in a window too small to edit in (docs/editor.md#small-screens). */
|
|
11
|
+
export declare function SmallScreenNotice(): import("react").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=small-screen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"small-screen.d.ts","sourceRoot":"","sources":["../../src/app/small-screen.tsx"],"names":[],"mappings":"AAOA;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAmB1E;AAED,mGAAmG;AACnG,wBAAgB,iBAAiB,gCAiBhC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useSyncExternalStore } from 'react';
|
|
3
|
+
import { useT } from '../messages/index.js';
|
|
4
|
+
import { BrandMark } from '../toolbar/brand.js';
|
|
5
|
+
import { Icon } from '../ui/index.js';
|
|
6
|
+
const unknownViewport = () => undefined;
|
|
7
|
+
/**
|
|
8
|
+
* Whether the window is narrower than `minWidth` CSS pixels, kept current as it is resized or
|
|
9
|
+
* rotated. `0` (or less) never is; without `matchMedia` (a test) the window is taken as wide enough.
|
|
10
|
+
*
|
|
11
|
+
* `undefined` means "not known yet": the server has no window, and a hydrating client must render
|
|
12
|
+
* what the server rendered, so both start unknown and the client resolves it right after hydration
|
|
13
|
+
* (a plain client render resolves it at once). Callers render a neutral state meanwhile.
|
|
14
|
+
*/
|
|
15
|
+
export function useViewportTooNarrow(minWidth) {
|
|
16
|
+
const query = `(max-width: ${Math.max(minWidth, 1) - 1}px)`;
|
|
17
|
+
const subscribe = useCallback((onChange) => {
|
|
18
|
+
if (minWidth <= 0 || typeof window.matchMedia !== 'function')
|
|
19
|
+
return () => undefined;
|
|
20
|
+
const list = window.matchMedia(query);
|
|
21
|
+
list.addEventListener('change', onChange);
|
|
22
|
+
return () => list.removeEventListener('change', onChange);
|
|
23
|
+
}, [query, minWidth]);
|
|
24
|
+
const getSnapshot = useCallback(() => minWidth > 0 && typeof window.matchMedia === 'function'
|
|
25
|
+
? window.matchMedia(query).matches
|
|
26
|
+
: false, [query, minWidth]);
|
|
27
|
+
return useSyncExternalStore(subscribe, getSnapshot, unknownViewport);
|
|
28
|
+
}
|
|
29
|
+
/** Shown instead of the editor in a window too small to edit in (docs/editor.md#small-screens). */
|
|
30
|
+
export function SmallScreenNotice() {
|
|
31
|
+
const t = useT();
|
|
32
|
+
return (_jsx("main", { className: "bd-small-screen", role: "alert", "aria-labelledby": "bd-small-screen-title", children: _jsxs("div", { className: "bd-small-screen-card", children: [_jsx(BrandMark, { size: 32 }), _jsx("span", { className: "bd-small-screen-icon", children: _jsx(Icon, { name: "monitor", size: "md" }) }), _jsx("h1", { id: "bd-small-screen-title", className: "bd-small-screen-title", children: t('app.smallScreen.title') }), _jsx("p", { className: "bd-small-screen-body", children: t('app.smallScreen.body') }), _jsx("p", { className: "bd-small-screen-hint", children: t('app.smallScreen.hint') })] }) }));
|
|
33
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"small-screen.test.d.ts","sourceRoot":"","sources":["../../src/app/small-screen.test.tsx"],"names":[],"mappings":""}
|