@next-buildr/editor 0.0.0-stage → 2.0.1
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/README.md +4 -2
- 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 +67 -3
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// @vitest-environment jsdom
|
|
3
|
+
import { assertDocumentInvariants, createRegistryMeta, createSeededIdGenerator, p, s, } from '@next-buildr/core';
|
|
4
|
+
import { act } from 'react';
|
|
5
|
+
import { createRoot } from 'react-dom/client';
|
|
6
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
7
|
+
import { MessagesProvider } from '../messages/index.js';
|
|
8
|
+
import { ShortcutProvider } from '../shortcuts/index.js';
|
|
9
|
+
import { createEditorStore, EditorStoreProvider } from '../store/index.js';
|
|
10
|
+
import { ToastProvider } from '../ui/index.js';
|
|
11
|
+
import { createClipboard } from './clipboard.js';
|
|
12
|
+
import { CLIPBOARD_MARKER, MAX_CLIPBOARD_BYTES, parseClipboardText, serializeFragment, } from './format.js';
|
|
13
|
+
import { ClipboardProvider, useClipboardActions } from './react.js';
|
|
14
|
+
globalThis.IS_REACT_ACT_ENVIRONMENT = true;
|
|
15
|
+
const base = {
|
|
16
|
+
type: 'buildr/leaf',
|
|
17
|
+
version: 1,
|
|
18
|
+
label: 'Leaf',
|
|
19
|
+
category: 'content',
|
|
20
|
+
props: {},
|
|
21
|
+
contentCategories: ['flow'],
|
|
22
|
+
styles: { groups: [] },
|
|
23
|
+
runtime: 'shared',
|
|
24
|
+
};
|
|
25
|
+
const box = { ...base, type: 'buildr/box', label: 'Box', slots: { default: {} } };
|
|
26
|
+
const page = (max) => ({
|
|
27
|
+
...base,
|
|
28
|
+
type: 'buildr/page',
|
|
29
|
+
label: 'Page',
|
|
30
|
+
capabilities: { root: true },
|
|
31
|
+
slots: { default: max === undefined ? {} : { max } },
|
|
32
|
+
});
|
|
33
|
+
const registryOf = (max, leafVersion = 1) => createRegistryMeta({ components: [page(max), box, { ...base, version: leafVersion }] });
|
|
34
|
+
const fixture = () => ({
|
|
35
|
+
schemaVersion: 1,
|
|
36
|
+
root: 'root',
|
|
37
|
+
nodes: {
|
|
38
|
+
root: { id: 'root', type: 'buildr/page', slots: { default: ['boxAAAAAA1', 'leafBBBBB1'] } },
|
|
39
|
+
boxAAAAAA1: { id: 'boxAAAAAA1', type: 'buildr/box', slots: { default: ['leafCCCCC1'] } },
|
|
40
|
+
leafBBBBB1: { id: 'leafBBBBB1', type: 'buildr/leaf' },
|
|
41
|
+
leafCCCCC1: { id: 'leafCCCCC1', type: 'buildr/leaf' },
|
|
42
|
+
},
|
|
43
|
+
components: { 'buildr/page': 1, 'buildr/box': 1, 'buildr/leaf': 1 },
|
|
44
|
+
});
|
|
45
|
+
const newStore = (options = {}) => createEditorStore({
|
|
46
|
+
doc: options.doc ?? fixture(),
|
|
47
|
+
registry: registryOf(options.max, options.leafVersion),
|
|
48
|
+
generateId: createSeededIdGenerator(11),
|
|
49
|
+
validationDelayMs: null,
|
|
50
|
+
});
|
|
51
|
+
/** A system clipboard that remembers the text. */
|
|
52
|
+
function memoryIO() {
|
|
53
|
+
const io = {
|
|
54
|
+
text: '',
|
|
55
|
+
writeText: async (text) => {
|
|
56
|
+
io.text = text;
|
|
57
|
+
},
|
|
58
|
+
readText: async () => io.text,
|
|
59
|
+
};
|
|
60
|
+
return io;
|
|
61
|
+
}
|
|
62
|
+
const rootOrder = (store) => store.getState().doc.nodes['root']?.slots?.['default'] ?? [];
|
|
63
|
+
const fragmentOf = (store, ids) => {
|
|
64
|
+
const clip = memoryIO();
|
|
65
|
+
return {
|
|
66
|
+
clip,
|
|
67
|
+
ready: (async () => {
|
|
68
|
+
store.setSelection(ids);
|
|
69
|
+
await createClipboard({ store, io: clip }).copy();
|
|
70
|
+
return clip.text;
|
|
71
|
+
})(),
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
describe('copy and paste', () => {
|
|
75
|
+
it('copies the selection as marked text and pastes it after the selected node', async () => {
|
|
76
|
+
const store = newStore();
|
|
77
|
+
const io = memoryIO();
|
|
78
|
+
const clipboard = createClipboard({ store, io, generateId: createSeededIdGenerator(21) });
|
|
79
|
+
store.select('leafBBBBB1');
|
|
80
|
+
expect(await clipboard.copy()).toEqual({ ok: true });
|
|
81
|
+
expect(io.text.startsWith(`${CLIPBOARD_MARKER}\n`)).toBe(true);
|
|
82
|
+
expect(await clipboard.paste()).toEqual({ ok: true });
|
|
83
|
+
const order = rootOrder(store);
|
|
84
|
+
expect(order).toHaveLength(3);
|
|
85
|
+
expect(order[1]).toBe('leafBBBBB1');
|
|
86
|
+
const [, , pasted] = [order[0], order[1], order[2]];
|
|
87
|
+
expect(pasted).not.toBe('leafBBBBB1');
|
|
88
|
+
expect(order[0]).toBe('boxAAAAAA1');
|
|
89
|
+
expect(store.getState().selectedIds).toEqual([order[2]]);
|
|
90
|
+
assertDocumentInvariants(store.getState().doc);
|
|
91
|
+
});
|
|
92
|
+
it('gives every paste its own ids', async () => {
|
|
93
|
+
const store = newStore();
|
|
94
|
+
const clipboard = createClipboard({ store, io: memoryIO() });
|
|
95
|
+
store.select('boxAAAAAA1');
|
|
96
|
+
await clipboard.copy();
|
|
97
|
+
await clipboard.paste();
|
|
98
|
+
await clipboard.paste();
|
|
99
|
+
const ids = Object.keys(store.getState().doc.nodes);
|
|
100
|
+
expect(new Set(ids).size).toBe(ids.length);
|
|
101
|
+
expect(ids).toHaveLength(4 + 2 * 2);
|
|
102
|
+
assertDocumentInvariants(store.getState().doc);
|
|
103
|
+
});
|
|
104
|
+
it('copies a container with its content, and never a node twice', async () => {
|
|
105
|
+
const store = newStore();
|
|
106
|
+
const io = memoryIO();
|
|
107
|
+
const clipboard = createClipboard({ store, io });
|
|
108
|
+
store.setSelection(['leafCCCCC1', 'boxAAAAAA1']);
|
|
109
|
+
await clipboard.copy();
|
|
110
|
+
const parsed = parseClipboardText(io.text);
|
|
111
|
+
expect(parsed.ok && parsed.fragment.roots).toEqual(['boxAAAAAA1']);
|
|
112
|
+
expect(parsed.ok && Object.keys(parsed.fragment.nodes).sort()).toEqual([
|
|
113
|
+
'boxAAAAAA1',
|
|
114
|
+
'leafCCCCC1',
|
|
115
|
+
]);
|
|
116
|
+
});
|
|
117
|
+
it('cuts to the clipboard, and the cut can be undone', async () => {
|
|
118
|
+
const store = newStore();
|
|
119
|
+
const clipboard = createClipboard({ store, io: memoryIO() });
|
|
120
|
+
store.select('leafBBBBB1');
|
|
121
|
+
expect(await clipboard.cut()).toEqual({ ok: true });
|
|
122
|
+
expect(rootOrder(store)).toEqual(['boxAAAAAA1']);
|
|
123
|
+
store.select('boxAAAAAA1');
|
|
124
|
+
await clipboard.paste();
|
|
125
|
+
expect(rootOrder(store)).toHaveLength(2);
|
|
126
|
+
act(() => {
|
|
127
|
+
store.undo();
|
|
128
|
+
store.undo();
|
|
129
|
+
});
|
|
130
|
+
expect(rootOrder(store)).toEqual(['boxAAAAAA1', 'leafBBBBB1']);
|
|
131
|
+
});
|
|
132
|
+
it('pastes into a container when the selection cannot have a neighbour there', async () => {
|
|
133
|
+
const store = newStore({ max: 2 });
|
|
134
|
+
const clipboard = createClipboard({ store, io: memoryIO() });
|
|
135
|
+
store.select('leafBBBBB1');
|
|
136
|
+
await clipboard.copy();
|
|
137
|
+
// The page holds its two nodes already: after the selection is refused, inside a leaf is
|
|
138
|
+
// impossible, so the paste fails as a whole.
|
|
139
|
+
const result = await clipboard.paste();
|
|
140
|
+
expect(result.ok).toBe(false);
|
|
141
|
+
expect(rootOrder(store)).toHaveLength(2);
|
|
142
|
+
// Selecting the box gives another place: inside it.
|
|
143
|
+
store.select('boxAAAAAA1');
|
|
144
|
+
expect(await clipboard.paste()).toEqual({ ok: true });
|
|
145
|
+
expect(store.getState().doc.nodes['boxAAAAAA1']?.slots?.['default']).toHaveLength(2);
|
|
146
|
+
});
|
|
147
|
+
it('pastes at the end of the page with nothing selected', async () => {
|
|
148
|
+
const store = newStore();
|
|
149
|
+
const clipboard = createClipboard({ store, io: memoryIO() });
|
|
150
|
+
store.select('leafBBBBB1');
|
|
151
|
+
await clipboard.copy();
|
|
152
|
+
store.clearSelection();
|
|
153
|
+
await clipboard.paste();
|
|
154
|
+
expect(rootOrder(store)).toHaveLength(3);
|
|
155
|
+
});
|
|
156
|
+
it('refuses copying nothing, and cutting or pasting in a read-only document', async () => {
|
|
157
|
+
const store = newStore();
|
|
158
|
+
const clipboard = createClipboard({ store, io: memoryIO() });
|
|
159
|
+
expect(await clipboard.copy()).toEqual({ ok: false, error: { code: 'empty' } });
|
|
160
|
+
store.select('leafBBBBB1');
|
|
161
|
+
await clipboard.copy();
|
|
162
|
+
store.setReadOnly(true);
|
|
163
|
+
expect(await clipboard.cut()).toEqual({ ok: false, error: { code: 'readOnly' } });
|
|
164
|
+
expect(await clipboard.paste()).toEqual({ ok: false, error: { code: 'readOnly' } });
|
|
165
|
+
expect(rootOrder(store)).toHaveLength(2);
|
|
166
|
+
});
|
|
167
|
+
it('works within the window when the system clipboard cannot be used', async () => {
|
|
168
|
+
const denied = {
|
|
169
|
+
writeText: () => Promise.reject(new Error('denied')),
|
|
170
|
+
readText: () => Promise.reject(new Error('denied')),
|
|
171
|
+
};
|
|
172
|
+
for (const io of [denied, undefined]) {
|
|
173
|
+
const store = newStore();
|
|
174
|
+
const clipboard = createClipboard({ store, io });
|
|
175
|
+
store.select('leafBBBBB1');
|
|
176
|
+
expect(await clipboard.copy()).toEqual({ ok: true });
|
|
177
|
+
expect(await clipboard.paste()).toEqual({ ok: true });
|
|
178
|
+
expect(rootOrder(store)).toHaveLength(3);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
it('pastes what was copied in another document', async () => {
|
|
182
|
+
const source = newStore();
|
|
183
|
+
const { clip, ready } = fragmentOf(source, ['boxAAAAAA1']);
|
|
184
|
+
await ready;
|
|
185
|
+
const other = newStore({
|
|
186
|
+
doc: {
|
|
187
|
+
schemaVersion: 1,
|
|
188
|
+
root: 'root',
|
|
189
|
+
nodes: { root: { id: 'root', type: 'buildr/page' } },
|
|
190
|
+
components: { 'buildr/page': 1 },
|
|
191
|
+
},
|
|
192
|
+
});
|
|
193
|
+
const clipboard = createClipboard({ store: other, io: clip });
|
|
194
|
+
expect(await clipboard.paste()).toEqual({ ok: true });
|
|
195
|
+
expect(Object.keys(other.getState().doc.nodes)).toHaveLength(3);
|
|
196
|
+
assertDocumentInvariants(other.getState().doc);
|
|
197
|
+
});
|
|
198
|
+
it('refuses a fragment whose components are of another version', async () => {
|
|
199
|
+
const source = newStore();
|
|
200
|
+
const { clip, ready } = fragmentOf(source, ['leafBBBBB1']);
|
|
201
|
+
await ready;
|
|
202
|
+
const newer = newStore({
|
|
203
|
+
leafVersion: 2,
|
|
204
|
+
doc: { ...fixture(), components: { ...fixture().components, 'buildr/leaf': 2 } },
|
|
205
|
+
});
|
|
206
|
+
const clipboard = createClipboard({ store: newer, io: clip });
|
|
207
|
+
const result = await clipboard.paste();
|
|
208
|
+
expect(result.ok).toBe(false);
|
|
209
|
+
expect(rootOrder(newer)).toHaveLength(2);
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
describe('hostile clipboard content', () => {
|
|
213
|
+
const marked = (body) => `${CLIPBOARD_MARKER}\n${body}`;
|
|
214
|
+
const valid = () => ({
|
|
215
|
+
format: 'buildr/fragment',
|
|
216
|
+
schemaVersion: 1,
|
|
217
|
+
components: { 'buildr/leaf': 1 },
|
|
218
|
+
roots: ['leafZZZZZ1'],
|
|
219
|
+
nodes: { leafZZZZZ1: { id: 'leafZZZZZ1', type: 'buildr/leaf' } },
|
|
220
|
+
});
|
|
221
|
+
const pasteText = async (text) => {
|
|
222
|
+
const store = newStore();
|
|
223
|
+
const before = JSON.stringify(store.getState().doc);
|
|
224
|
+
const io = memoryIO();
|
|
225
|
+
io.text = text;
|
|
226
|
+
const result = await createClipboard({ store, io }).paste();
|
|
227
|
+
expect(JSON.stringify(store.getState().doc)).toBe(before);
|
|
228
|
+
return result;
|
|
229
|
+
};
|
|
230
|
+
const code = (result) => result.ok ? 'ok' : result.error.code;
|
|
231
|
+
it('rejects text that is not ours', async () => {
|
|
232
|
+
expect(code(await pasteText('hello'))).toBe('notFragment');
|
|
233
|
+
expect(code(await pasteText('{"format":"buildr/fragment"}'))).toBe('notFragment');
|
|
234
|
+
expect(code(await pasteText(''))).toBe('notFragment');
|
|
235
|
+
});
|
|
236
|
+
it('rejects broken JSON, wrong shapes and other versions', async () => {
|
|
237
|
+
expect(code(await pasteText(marked('{not json')))).toBe('invalid');
|
|
238
|
+
expect(code(await pasteText(marked('null')))).toBe('invalid');
|
|
239
|
+
expect(code(await pasteText(marked('[]')))).toBe('invalid');
|
|
240
|
+
expect(code(await pasteText(marked('{"format":"buildr/fragment"}')))).toBe('invalid');
|
|
241
|
+
expect(code(await pasteText('buildr-fragment/2\n{}'))).toBe('unsupported');
|
|
242
|
+
expect(code(await pasteText('buildr-fragment/0\n{}'))).toBe('unsupported');
|
|
243
|
+
expect(code(await pasteText('buildr-fragment/'))).toBe('unsupported');
|
|
244
|
+
});
|
|
245
|
+
it('rejects content over the size limit before parsing it', async () => {
|
|
246
|
+
const huge = marked(`"${'x'.repeat(MAX_CLIPBOARD_BYTES)}"`);
|
|
247
|
+
expect(code(await pasteText(huge))).toBe('tooLarge');
|
|
248
|
+
});
|
|
249
|
+
it('rejects a fragment with a dangling child, without changing the document', async () => {
|
|
250
|
+
const fragment = {
|
|
251
|
+
format: 'buildr/fragment',
|
|
252
|
+
schemaVersion: 1,
|
|
253
|
+
components: { 'buildr/box': 1 },
|
|
254
|
+
roots: ['boxZZZZZZ1'],
|
|
255
|
+
nodes: {
|
|
256
|
+
boxZZZZZZ1: { id: 'boxZZZZZZ1', type: 'buildr/box', slots: { default: ['leafMISSING'] } },
|
|
257
|
+
},
|
|
258
|
+
};
|
|
259
|
+
expect(code(await pasteText(serializeFragment(fragment)))).toBe('invalid');
|
|
260
|
+
});
|
|
261
|
+
it('refuses an unknown component type as incompatible', async () => {
|
|
262
|
+
const fragment = {
|
|
263
|
+
format: 'buildr/fragment',
|
|
264
|
+
schemaVersion: 1,
|
|
265
|
+
components: { 'evil/script': 1 },
|
|
266
|
+
roots: ['evilAAAAA1'],
|
|
267
|
+
nodes: { evilAAAAA1: { id: 'evilAAAAA1', type: 'evil/script', props: { html: '<script>' } } },
|
|
268
|
+
};
|
|
269
|
+
// Unknown to the registry and with nothing to migrate it: refused before any command runs.
|
|
270
|
+
expect(code(await pasteText(serializeFragment(fragment)))).toBe('outdated');
|
|
271
|
+
});
|
|
272
|
+
it('rejects a known type that breaks the rules of the target through the command checks', async () => {
|
|
273
|
+
const fragment = {
|
|
274
|
+
format: 'buildr/fragment',
|
|
275
|
+
schemaVersion: 1,
|
|
276
|
+
components: { 'buildr/leaf': 1, 'buildr/page': 1 },
|
|
277
|
+
roots: ['pageEVIL01'],
|
|
278
|
+
nodes: { pageEVIL01: { id: 'pageEVIL01', type: 'buildr/page' } },
|
|
279
|
+
};
|
|
280
|
+
expect(code(await pasteText(serializeFragment(fragment)))).toBe('rejected');
|
|
281
|
+
});
|
|
282
|
+
it('is not moved by prototype pollution attempts', async () => {
|
|
283
|
+
const text = marked('{"format":"buildr/fragment","schemaVersion":1,"components":{},"roots":["leafAAAAA1"],' +
|
|
284
|
+
'"nodes":{"__proto__":{"polluted":true},"leafAAAAA1":{"id":"leafAAAAA1","type":"buildr/leaf"}},' +
|
|
285
|
+
'"__proto__":{"polluted":true}}');
|
|
286
|
+
await pasteText(text);
|
|
287
|
+
expect({}['polluted']).toBeUndefined();
|
|
288
|
+
});
|
|
289
|
+
it('keeps the document valid whatever is thrown at it', async () => {
|
|
290
|
+
const base = valid();
|
|
291
|
+
// The unchanged fragment is fine, so each variant below fails for its own change.
|
|
292
|
+
const fine = newStore();
|
|
293
|
+
const io = memoryIO();
|
|
294
|
+
io.text = marked(JSON.stringify(base));
|
|
295
|
+
expect(await createClipboard({ store: fine, io }).paste()).toEqual({ ok: true });
|
|
296
|
+
const variants = [
|
|
297
|
+
{ ...base, roots: [] },
|
|
298
|
+
{ ...base, roots: ['root'] },
|
|
299
|
+
{ ...base, extra: 1 },
|
|
300
|
+
{ ...base, schemaVersion: 2 },
|
|
301
|
+
{ ...base, nodes: {} },
|
|
302
|
+
];
|
|
303
|
+
for (const variant of variants) {
|
|
304
|
+
const result = await pasteText(marked(JSON.stringify(variant)));
|
|
305
|
+
expect(result.ok).toBe(false);
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
describe('paste of an outdated fragment', () => {
|
|
310
|
+
const textProps = { text: s('old') };
|
|
311
|
+
const fragmentOfLeaf = (type, version) => serializeFragment({
|
|
312
|
+
schemaVersion: 1,
|
|
313
|
+
format: 'buildr/fragment',
|
|
314
|
+
roots: ['leafOld001'],
|
|
315
|
+
nodes: { leafOld001: { id: 'leafOld001', type, props: textProps } },
|
|
316
|
+
components: { [type]: version },
|
|
317
|
+
});
|
|
318
|
+
const migrations = {
|
|
319
|
+
'buildr/leaf': {
|
|
320
|
+
currentVersion: 2,
|
|
321
|
+
steps: [
|
|
322
|
+
{
|
|
323
|
+
from: 1,
|
|
324
|
+
to: 2,
|
|
325
|
+
migrate: (props) => ({ ...props, migrated: { kind: 'static', value: true } }),
|
|
326
|
+
},
|
|
327
|
+
],
|
|
328
|
+
replaces: {
|
|
329
|
+
'buildr/retired': {
|
|
330
|
+
fromVersion: 1,
|
|
331
|
+
toVersion: 1,
|
|
332
|
+
migrate: (node) => ({ ...node, props: { ...node.props } }),
|
|
333
|
+
},
|
|
334
|
+
},
|
|
335
|
+
},
|
|
336
|
+
};
|
|
337
|
+
const setup = (text, withMigrations) => {
|
|
338
|
+
const store = createEditorStore({
|
|
339
|
+
doc: { ...fixture(), components: { ...fixture().components, 'buildr/leaf': 2 } },
|
|
340
|
+
registry: createRegistryMeta({
|
|
341
|
+
components: [
|
|
342
|
+
page(),
|
|
343
|
+
box,
|
|
344
|
+
{
|
|
345
|
+
...base,
|
|
346
|
+
version: 2,
|
|
347
|
+
props: { text: p.text({ default: '' }), migrated: p.boolean({ default: false }) },
|
|
348
|
+
},
|
|
349
|
+
],
|
|
350
|
+
}),
|
|
351
|
+
generateId: createSeededIdGenerator(11),
|
|
352
|
+
validationDelayMs: null,
|
|
353
|
+
});
|
|
354
|
+
const clipboard = createClipboard({
|
|
355
|
+
store,
|
|
356
|
+
io: { writeText: async () => undefined, readText: async () => text },
|
|
357
|
+
generateId: createSeededIdGenerator(31),
|
|
358
|
+
migrations: withMigrations,
|
|
359
|
+
});
|
|
360
|
+
return { store, clipboard };
|
|
361
|
+
};
|
|
362
|
+
const pastedNode = (store) => {
|
|
363
|
+
const id = rootOrder(store).at(-1);
|
|
364
|
+
return store.getState().doc.nodes[id];
|
|
365
|
+
};
|
|
366
|
+
it('migrates a fragment copied under an older version before inserting it', async () => {
|
|
367
|
+
const { store, clipboard } = setup(fragmentOfLeaf('buildr/leaf', 1), migrations);
|
|
368
|
+
expect(await clipboard.paste()).toEqual({ ok: true });
|
|
369
|
+
expect(pastedNode(store)?.props).toMatchObject({ migrated: { value: true } });
|
|
370
|
+
expect(store.getState().doc.components['buildr/leaf']).toBe(2);
|
|
371
|
+
});
|
|
372
|
+
it('migrates a fragment of a retired type into the type that replaces it', async () => {
|
|
373
|
+
const { store, clipboard } = setup(fragmentOfLeaf('buildr/retired', 1), migrations);
|
|
374
|
+
expect(await clipboard.paste()).toEqual({ ok: true });
|
|
375
|
+
expect(pastedNode(store)?.type).toBe('buildr/leaf');
|
|
376
|
+
expect(pastedNode(store)?.props).toMatchObject({ migrated: { value: true } });
|
|
377
|
+
});
|
|
378
|
+
it('migrates a retired node whose type is missing from the components map', async () => {
|
|
379
|
+
const { store, clipboard } = setup(fragmentOfLeaf('buildr/retired', 1).replace('{"buildr/retired":1}', '{}'), migrations);
|
|
380
|
+
expect(await clipboard.paste()).toEqual({ ok: true });
|
|
381
|
+
expect(pastedNode(store)?.type).toBe('buildr/leaf');
|
|
382
|
+
});
|
|
383
|
+
it('refuses it without migrations and leaves the document as it was', async () => {
|
|
384
|
+
const { store, clipboard } = setup(fragmentOfLeaf('buildr/leaf', 1));
|
|
385
|
+
const before = store.getState().doc;
|
|
386
|
+
expect(await clipboard.paste()).toEqual({ ok: false, error: { code: 'outdated' } });
|
|
387
|
+
expect(store.getState().doc).toBe(before);
|
|
388
|
+
});
|
|
389
|
+
it('refuses it when the migration cannot be applied', async () => {
|
|
390
|
+
const { store, clipboard } = setup(fragmentOfLeaf('buildr/leaf', 3), migrations);
|
|
391
|
+
const before = store.getState().doc;
|
|
392
|
+
expect(await clipboard.paste()).toEqual({ ok: false, error: { code: 'outdated' } });
|
|
393
|
+
expect(store.getState().doc).toBe(before);
|
|
394
|
+
});
|
|
395
|
+
it('refuses a type the registry does not know without migrations', async () => {
|
|
396
|
+
const { store, clipboard } = setup(fragmentOfLeaf('buildr/unknown', 1), {});
|
|
397
|
+
const before = store.getState().doc;
|
|
398
|
+
expect(await clipboard.paste()).toEqual({ ok: false, error: { code: 'outdated' } });
|
|
399
|
+
expect(store.getState().doc).toBe(before);
|
|
400
|
+
});
|
|
401
|
+
});
|
|
402
|
+
describe('ClipboardProvider', () => {
|
|
403
|
+
let container;
|
|
404
|
+
let root;
|
|
405
|
+
function Bridge() {
|
|
406
|
+
return _jsx("input", { "aria-label": "field" });
|
|
407
|
+
}
|
|
408
|
+
function Shortcuts(props) {
|
|
409
|
+
const actions = useClipboardActions();
|
|
410
|
+
return (_jsx(ShortcutProvider, { platform: "other", actions: actions, children: props.children }));
|
|
411
|
+
}
|
|
412
|
+
async function mount(io) {
|
|
413
|
+
const store = newStore();
|
|
414
|
+
await act(async () => root.render(_jsx(MessagesProvider, { locale: "en", children: _jsx(ToastProvider, { children: _jsx(EditorStoreProvider, { store: store, children: _jsx(ClipboardProvider, { io: io, children: _jsx(Shortcuts, { children: _jsx(Bridge, {}) }) }) }) }) })));
|
|
415
|
+
return store;
|
|
416
|
+
}
|
|
417
|
+
const key = (target, init) => act(async () => {
|
|
418
|
+
target.dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, cancelable: true, ...init }));
|
|
419
|
+
});
|
|
420
|
+
beforeEach(() => {
|
|
421
|
+
container = document.createElement('div');
|
|
422
|
+
document.body.append(container);
|
|
423
|
+
root = createRoot(container);
|
|
424
|
+
});
|
|
425
|
+
afterEach(() => {
|
|
426
|
+
act(() => root.unmount());
|
|
427
|
+
document.body.innerHTML = '';
|
|
428
|
+
});
|
|
429
|
+
it('copies and pastes with the keyboard', async () => {
|
|
430
|
+
const io = memoryIO();
|
|
431
|
+
const store = await mount(io);
|
|
432
|
+
act(() => store.select('leafBBBBB1'));
|
|
433
|
+
await key(document.body, { key: 'c', ctrlKey: true });
|
|
434
|
+
expect(io.text.startsWith(CLIPBOARD_MARKER)).toBe(true);
|
|
435
|
+
await key(document.body, { key: 'v', ctrlKey: true });
|
|
436
|
+
expect(rootOrder(store)).toHaveLength(3);
|
|
437
|
+
await key(document.body, { key: 'x', ctrlKey: true });
|
|
438
|
+
expect(rootOrder(store)).toHaveLength(2);
|
|
439
|
+
});
|
|
440
|
+
it('says why a paste was refused', async () => {
|
|
441
|
+
const io = memoryIO();
|
|
442
|
+
io.text = 'just some text';
|
|
443
|
+
const store = await mount(io);
|
|
444
|
+
act(() => store.select('leafBBBBB1'));
|
|
445
|
+
await key(document.body, { key: 'v', ctrlKey: true });
|
|
446
|
+
expect(container.parentElement?.querySelector('[role=status]')?.textContent).toContain('nothing copied from the editor');
|
|
447
|
+
expect(rootOrder(store)).toHaveLength(2);
|
|
448
|
+
});
|
|
449
|
+
it('leaves copy and paste to a text field that has focus', async () => {
|
|
450
|
+
const io = memoryIO();
|
|
451
|
+
const store = await mount(io);
|
|
452
|
+
act(() => store.select('leafBBBBB1'));
|
|
453
|
+
const field = container.querySelector('input');
|
|
454
|
+
await key(field, { key: 'c', ctrlKey: true });
|
|
455
|
+
expect(io.text).toBe('');
|
|
456
|
+
});
|
|
457
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type BuilderFragment } from '@next-buildr/core';
|
|
2
|
+
/** The first line of what the editor puts on the clipboard; it says which format follows. */
|
|
3
|
+
export declare const CLIPBOARD_MARKER = "buildr-fragment/1";
|
|
4
|
+
/** More than this is not a copied selection but something else (or an attack); it is not parsed. */
|
|
5
|
+
export declare const MAX_CLIPBOARD_BYTES = 1000000;
|
|
6
|
+
export type ClipboardErrorCode = 'empty' | 'readOnly' | 'notFragment' | 'tooLarge' | 'unsupported' | 'invalid' | 'rejected' | 'outdated';
|
|
7
|
+
export interface ClipboardError {
|
|
8
|
+
readonly code: ClipboardErrorCode;
|
|
9
|
+
/** The reason the editor's rules gave, for `rejected`; the text for the others is in the message catalog. */
|
|
10
|
+
readonly detail?: string | undefined;
|
|
11
|
+
}
|
|
12
|
+
export type ParseResult = {
|
|
13
|
+
readonly ok: true;
|
|
14
|
+
readonly fragment: BuilderFragment;
|
|
15
|
+
} | {
|
|
16
|
+
readonly ok: false;
|
|
17
|
+
readonly error: ClipboardError;
|
|
18
|
+
};
|
|
19
|
+
/** The clipboard text of a fragment: the marker, a line break, JSON. */
|
|
20
|
+
export declare function serializeFragment(fragment: BuilderFragment): string;
|
|
21
|
+
/**
|
|
22
|
+
* Reads clipboard text as a fragment. The text is untrusted: it is checked for the marker, its size
|
|
23
|
+
* and version, parsed as JSON and validated with `fragmentSchema` before anything else sees it.
|
|
24
|
+
* Never throws.
|
|
25
|
+
*/
|
|
26
|
+
export declare function parseClipboardText(text: string): ParseResult;
|
|
27
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/clipboard/format.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAAkB,MAAM,mBAAmB,CAAC;AAEzE,6FAA6F;AAC7F,eAAO,MAAM,gBAAgB,sBAAsB,CAAC;AAGpD,oGAAoG;AACpG,eAAO,MAAM,mBAAmB,UAAY,CAAC;AAE7C,MAAM,MAAM,kBAAkB,GAC1B,OAAO,GACP,UAAU,GACV,aAAa,GACb,UAAU,GACV,aAAa,GACb,SAAS,GACT,UAAU,GACV,UAAU,CAAC;AAEf,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,6GAA6G;IAC7G,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAED,MAAM,MAAM,WAAW,GACnB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAA;CAAE,GACzD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAA;CAAE,CAAC;AAE3D,wEAAwE;AACxE,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAEnE;AAID;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAe5D"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { fragmentSchema } from '@next-buildr/core';
|
|
2
|
+
/** The first line of what the editor puts on the clipboard; it says which format follows. */
|
|
3
|
+
export const CLIPBOARD_MARKER = 'buildr-fragment/1';
|
|
4
|
+
const MARKER_PREFIX = 'buildr-fragment/';
|
|
5
|
+
/** More than this is not a copied selection but something else (or an attack); it is not parsed. */
|
|
6
|
+
export const MAX_CLIPBOARD_BYTES = 1_000_000;
|
|
7
|
+
/** The clipboard text of a fragment: the marker, a line break, JSON. */
|
|
8
|
+
export function serializeFragment(fragment) {
|
|
9
|
+
return `${CLIPBOARD_MARKER}\n${JSON.stringify(fragment)}`;
|
|
10
|
+
}
|
|
11
|
+
const byteLength = (text) => new TextEncoder().encode(text).length;
|
|
12
|
+
/**
|
|
13
|
+
* Reads clipboard text as a fragment. The text is untrusted: it is checked for the marker, its size
|
|
14
|
+
* and version, parsed as JSON and validated with `fragmentSchema` before anything else sees it.
|
|
15
|
+
* Never throws.
|
|
16
|
+
*/
|
|
17
|
+
export function parseClipboardText(text) {
|
|
18
|
+
if (!text.startsWith(MARKER_PREFIX))
|
|
19
|
+
return { ok: false, error: { code: 'notFragment' } };
|
|
20
|
+
if (byteLength(text) > MAX_CLIPBOARD_BYTES)
|
|
21
|
+
return { ok: false, error: { code: 'tooLarge' } };
|
|
22
|
+
const lineEnd = text.indexOf('\n');
|
|
23
|
+
const marker = lineEnd === -1 ? text : text.slice(0, lineEnd);
|
|
24
|
+
if (marker !== CLIPBOARD_MARKER)
|
|
25
|
+
return { ok: false, error: { code: 'unsupported' } };
|
|
26
|
+
let raw;
|
|
27
|
+
try {
|
|
28
|
+
raw = JSON.parse(lineEnd === -1 ? '' : text.slice(lineEnd + 1));
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return { ok: false, error: { code: 'invalid' } };
|
|
32
|
+
}
|
|
33
|
+
const parsed = fragmentSchema.safeParse(raw);
|
|
34
|
+
if (!parsed.success)
|
|
35
|
+
return { ok: false, error: { code: 'invalid' } };
|
|
36
|
+
return { ok: true, fragment: parsed.data };
|
|
37
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type { Clipboard, ClipboardIO, ClipboardOptions, ClipboardResult } from './clipboard.ts';
|
|
2
|
+
export { browserClipboard, createClipboard } from './clipboard.ts';
|
|
3
|
+
export type { ClipboardError, ClipboardErrorCode, ParseResult } from './format.ts';
|
|
4
|
+
export { CLIPBOARD_MARKER, MAX_CLIPBOARD_BYTES, parseClipboardText, serializeFragment, } from './format.ts';
|
|
5
|
+
export { ClipboardProvider, NOTICE_MS, useClipboard, useClipboardActions } from './react.tsx';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/clipboard/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAChG,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACnE,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACnF,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ComponentMigrations } from '@next-buildr/core';
|
|
2
|
+
import { type ReactNode } from 'react';
|
|
3
|
+
import type { ExternalActions } from '../shortcuts/index.ts';
|
|
4
|
+
import { type Clipboard, type ClipboardIO } from './clipboard.ts';
|
|
5
|
+
/** How long a refusal stays on screen. */
|
|
6
|
+
export declare const NOTICE_MS = 6000;
|
|
7
|
+
export declare function useClipboard(): Clipboard;
|
|
8
|
+
/** The clipboard's actions in the shape `<ShortcutProvider actions>` takes: each starts the work and claims the key. */
|
|
9
|
+
export declare function useClipboardActions(): Pick<ExternalActions, 'copy' | 'cut' | 'paste'>;
|
|
10
|
+
/**
|
|
11
|
+
* Gives the editor's clipboard to the tree below and shows why a copy, cut or paste was refused in
|
|
12
|
+
* the toast region (there is no dialog: a refused paste is not an emergency). `io` is the system
|
|
13
|
+
* clipboard; by default `navigator.clipboard`, with the last copy kept in memory as a fallback.
|
|
14
|
+
*/
|
|
15
|
+
export declare function ClipboardProvider(props: {
|
|
16
|
+
readonly io?: ClipboardIO | undefined;
|
|
17
|
+
readonly migrations?: ComponentMigrations | undefined;
|
|
18
|
+
readonly children: ReactNode;
|
|
19
|
+
}): import("react").JSX.Element;
|
|
20
|
+
//# sourceMappingURL=react.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../src/clipboard/react.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAiB,KAAK,SAAS,EAAuB,MAAM,OAAO,CAAC;AAE3E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG7D,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,WAAW,EAGjB,MAAM,gBAAgB,CAAC;AAKxB,0CAA0C;AAC1C,eAAO,MAAM,SAAS,OAAW,CAAC;AAalC,wBAAgB,YAAY,IAAI,SAAS,CAKxC;AAED,wHAAwH;AACxH,wBAAgB,mBAAmB,IAAI,IAAI,CAAC,eAAe,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC,CAcrF;AAID;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IACvC,QAAQ,CAAC,EAAE,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,UAAU,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC;IACtD,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;CAC9B,+BAoCA"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext, useMemo } from 'react';
|
|
3
|
+
import { useT } from '../messages/index.js';
|
|
4
|
+
import { useEditor } from '../store/index.js';
|
|
5
|
+
import { TOAST_MS, useToast } from '../ui/index.js';
|
|
6
|
+
import { browserClipboard, createClipboard, } from './clipboard.js';
|
|
7
|
+
const ClipboardContext = createContext(undefined);
|
|
8
|
+
/** How long a refusal stays on screen. */
|
|
9
|
+
export const NOTICE_MS = TOAST_MS;
|
|
10
|
+
const MESSAGES = {
|
|
11
|
+
empty: 'clipboard.error.empty',
|
|
12
|
+
readOnly: 'clipboard.error.readOnly',
|
|
13
|
+
notFragment: 'clipboard.error.notFragment',
|
|
14
|
+
tooLarge: 'clipboard.error.tooLarge',
|
|
15
|
+
unsupported: 'clipboard.error.unsupported',
|
|
16
|
+
invalid: 'clipboard.error.invalid',
|
|
17
|
+
rejected: 'clipboard.error.rejected',
|
|
18
|
+
outdated: 'clipboard.outdated',
|
|
19
|
+
};
|
|
20
|
+
export function useClipboard() {
|
|
21
|
+
const clipboard = useContext(ClipboardContext);
|
|
22
|
+
if (clipboard === undefined)
|
|
23
|
+
throw new Error('useClipboard must be used inside <ClipboardProvider>');
|
|
24
|
+
return clipboard;
|
|
25
|
+
}
|
|
26
|
+
/** The clipboard's actions in the shape `<ShortcutProvider actions>` takes: each starts the work and claims the key. */
|
|
27
|
+
export function useClipboardActions() {
|
|
28
|
+
const clipboard = useClipboard();
|
|
29
|
+
const report = useContext(ReportContext);
|
|
30
|
+
return useMemo(() => {
|
|
31
|
+
const run = (action) => () => {
|
|
32
|
+
void action().then(report);
|
|
33
|
+
return true;
|
|
34
|
+
};
|
|
35
|
+
return {
|
|
36
|
+
copy: run(clipboard.copy),
|
|
37
|
+
cut: run(clipboard.cut),
|
|
38
|
+
paste: run(clipboard.paste),
|
|
39
|
+
};
|
|
40
|
+
}, [clipboard, report]);
|
|
41
|
+
}
|
|
42
|
+
const ReportContext = createContext(() => undefined);
|
|
43
|
+
/**
|
|
44
|
+
* Gives the editor's clipboard to the tree below and shows why a copy, cut or paste was refused in
|
|
45
|
+
* the toast region (there is no dialog: a refused paste is not an emergency). `io` is the system
|
|
46
|
+
* clipboard; by default `navigator.clipboard`, with the last copy kept in memory as a fallback.
|
|
47
|
+
*/
|
|
48
|
+
export function ClipboardProvider(props) {
|
|
49
|
+
const store = useEditor();
|
|
50
|
+
const t = useT();
|
|
51
|
+
const toast = useToast();
|
|
52
|
+
const io = props.io ?? browserClipboard();
|
|
53
|
+
const clipboard = useMemo(() => createClipboard({ store, io, migrations: props.migrations }), [store, io, props.migrations]);
|
|
54
|
+
const report = useMemo(() => (result) => {
|
|
55
|
+
if (result.ok) {
|
|
56
|
+
toast.dismiss('clipboard');
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const { error } = result;
|
|
60
|
+
toast.show({
|
|
61
|
+
id: 'clipboard',
|
|
62
|
+
variant: error.code === 'invalid' || error.code === 'rejected' || error.code === 'outdated'
|
|
63
|
+
? 'error'
|
|
64
|
+
: 'warning',
|
|
65
|
+
message: t(MESSAGES[error.code]),
|
|
66
|
+
detail: error.detail,
|
|
67
|
+
duration: NOTICE_MS,
|
|
68
|
+
});
|
|
69
|
+
}, [toast, t]);
|
|
70
|
+
return (_jsx(ClipboardContext.Provider, { value: clipboard, children: _jsx(ReportContext.Provider, { value: report, children: props.children }) }));
|
|
71
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dialogs/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './media-picker/index.js';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type { MediaLibrary, MediaLibraryProviderProps } from './library.tsx';
|
|
2
|
+
export { MediaLibraryProvider, useMediaLibrary } from './library.tsx';
|
|
3
|
+
export type { MediaPickerProps } from './media-picker.tsx';
|
|
4
|
+
export { MediaPicker } from './media-picker.tsx';
|
|
5
|
+
export type { MediaKind, MediaRef } from './media-ref.ts';
|
|
6
|
+
export { kindsFor, MEDIA_KINDS, mediaRefSchema, mimeTypesFor, parseMediaRef, toMediaRef, } from './media-ref.ts';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dialogs/media-picker/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACtE,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EACL,QAAQ,EACR,WAAW,EACX,cAAc,EACd,YAAY,EACZ,aAAa,EACb,UAAU,GACX,MAAM,gBAAgB,CAAC"}
|