@panphora/bevel 0.1.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 +16 -0
- package/README.md +226 -0
- package/bevel-fonts.css +16 -0
- package/bevel.css +3075 -0
- package/bevel.js +2126 -0
- package/dist/react/components/activity-feed.d.ts +89 -0
- package/dist/react/components/activity-feed.js +54 -0
- package/dist/react/components/alert-dialog.d.ts +14 -0
- package/dist/react/components/alert-dialog.js +19 -0
- package/dist/react/components/app-shell.d.ts +98 -0
- package/dist/react/components/app-shell.js +86 -0
- package/dist/react/components/app-toolbar.d.ts +19 -0
- package/dist/react/components/app-toolbar.js +22 -0
- package/dist/react/components/avatar-group.d.ts +67 -0
- package/dist/react/components/avatar-group.js +49 -0
- package/dist/react/components/badge-and-pill.d.ts +34 -0
- package/dist/react/components/badge-and-pill.js +12 -0
- package/dist/react/components/breadcrumbs.d.ts +56 -0
- package/dist/react/components/breadcrumbs.js +44 -0
- package/dist/react/components/bulk-bar.d.ts +22 -0
- package/dist/react/components/bulk-bar.js +59 -0
- package/dist/react/components/button.d.ts +15 -0
- package/dist/react/components/button.js +20 -0
- package/dist/react/components/callout-and-hint.d.ts +17 -0
- package/dist/react/components/callout-and-hint.js +8 -0
- package/dist/react/components/checkbox.d.ts +5 -0
- package/dist/react/components/checkbox.js +13 -0
- package/dist/react/components/chip.d.ts +149 -0
- package/dist/react/components/chip.js +29 -0
- package/dist/react/components/code-block.d.ts +50 -0
- package/dist/react/components/code-block.js +77 -0
- package/dist/react/components/code-editor.d.ts +122 -0
- package/dist/react/components/code-editor.js +695 -0
- package/dist/react/components/column-manager.d.ts +28 -0
- package/dist/react/components/column-manager.js +85 -0
- package/dist/react/components/combobox.d.ts +32 -0
- package/dist/react/components/combobox.js +37 -0
- package/dist/react/components/data-grid.d.ts +108 -0
- package/dist/react/components/data-grid.js +159 -0
- package/dist/react/components/data-table.d.ts +2 -0
- package/dist/react/components/data-table.js +6 -0
- package/dist/react/components/date.d.ts +23 -0
- package/dist/react/components/date.js +11 -0
- package/dist/react/components/details.d.ts +13 -0
- package/dist/react/components/details.js +20 -0
- package/dist/react/components/dialog.d.ts +74 -0
- package/dist/react/components/dialog.js +31 -0
- package/dist/react/components/diff-view.d.ts +73 -0
- package/dist/react/components/diff-view.js +68 -0
- package/dist/react/components/documents.d.ts +70 -0
- package/dist/react/components/documents.js +10 -0
- package/dist/react/components/drawer.d.ts +45 -0
- package/dist/react/components/drawer.js +35 -0
- package/dist/react/components/editable-grid-cells.d.ts +32 -0
- package/dist/react/components/editable-grid-cells.js +116 -0
- package/dist/react/components/eyebrow-kicker-lede-pull-quote.d.ts +39 -0
- package/dist/react/components/eyebrow-kicker-lede-pull-quote.js +12 -0
- package/dist/react/components/field.d.ts +32 -0
- package/dist/react/components/field.js +27 -0
- package/dist/react/components/file-tree.d.ts +75 -0
- package/dist/react/components/file-tree.js +247 -0
- package/dist/react/components/file.d.ts +43 -0
- package/dist/react/components/file.js +73 -0
- package/dist/react/components/files-table.d.ts +174 -0
- package/dist/react/components/files-table.js +237 -0
- package/dist/react/components/filter-builder.d.ts +37 -0
- package/dist/react/components/filter-builder.js +109 -0
- package/dist/react/components/form-error-summary.d.ts +16 -0
- package/dist/react/components/form-error-summary.js +49 -0
- package/dist/react/components/icon-button.d.ts +8 -0
- package/dist/react/components/icon-button.js +14 -0
- package/dist/react/components/icon.d.ts +7 -0
- package/dist/react/components/icon.js +15 -0
- package/dist/react/components/image.d.ts +72 -0
- package/dist/react/components/image.js +24 -0
- package/dist/react/components/inline-edit.d.ts +70 -0
- package/dist/react/components/inline-edit.js +149 -0
- package/dist/react/components/input.d.ts +29 -0
- package/dist/react/components/input.js +20 -0
- package/dist/react/components/kanban-board.d.ts +140 -0
- package/dist/react/components/kanban-board.js +374 -0
- package/dist/react/components/layout.d.ts +51 -0
- package/dist/react/components/layout.js +28 -0
- package/dist/react/components/list.d.ts +28 -0
- package/dist/react/components/list.js +6 -0
- package/dist/react/components/masthead-and-verdict.d.ts +60 -0
- package/dist/react/components/masthead-and-verdict.js +8 -0
- package/dist/react/components/menu.d.ts +26 -0
- package/dist/react/components/menu.js +31 -0
- package/dist/react/components/multi-select-picker.d.ts +49 -0
- package/dist/react/components/multi-select-picker.js +20 -0
- package/dist/react/components/note.d.ts +33 -0
- package/dist/react/components/note.js +8 -0
- package/dist/react/components/number-field.d.ts +16 -0
- package/dist/react/components/number-field.js +17 -0
- package/dist/react/components/pagination.d.ts +45 -0
- package/dist/react/components/pagination.js +87 -0
- package/dist/react/components/persistent-action-banner.d.ts +71 -0
- package/dist/react/components/persistent-action-banner.js +39 -0
- package/dist/react/components/popconfirm.d.ts +42 -0
- package/dist/react/components/popconfirm.js +59 -0
- package/dist/react/components/popover.d.ts +16 -0
- package/dist/react/components/popover.js +21 -0
- package/dist/react/components/progress-and-gauge.d.ts +44 -0
- package/dist/react/components/progress-and-gauge.js +19 -0
- package/dist/react/components/radio.d.ts +7 -0
- package/dist/react/components/radio.js +13 -0
- package/dist/react/components/rich-text-toolbar.d.ts +26 -0
- package/dist/react/components/rich-text-toolbar.js +64 -0
- package/dist/react/components/rows-and-card.d.ts +88 -0
- package/dist/react/components/rows-and-card.js +10 -0
- package/dist/react/components/save-status-indicator.d.ts +11 -0
- package/dist/react/components/save-status-indicator.js +33 -0
- package/dist/react/components/segmented-control.d.ts +21 -0
- package/dist/react/components/segmented-control.js +15 -0
- package/dist/react/components/select.d.ts +29 -0
- package/dist/react/components/select.js +29 -0
- package/dist/react/components/selectable-cards.d.ts +30 -0
- package/dist/react/components/selectable-cards.js +29 -0
- package/dist/react/components/settings-rows.d.ts +51 -0
- package/dist/react/components/settings-rows.js +8 -0
- package/dist/react/components/sidebar-nav.d.ts +77 -0
- package/dist/react/components/sidebar-nav.js +41 -0
- package/dist/react/components/skeleton-and-empty.d.ts +51 -0
- package/dist/react/components/skeleton-and-empty.js +14 -0
- package/dist/react/components/slider.d.ts +19 -0
- package/dist/react/components/slider.js +17 -0
- package/dist/react/components/small-charts.d.ts +60 -0
- package/dist/react/components/small-charts.js +76 -0
- package/dist/react/components/sortable.d.ts +30 -0
- package/dist/react/components/sortable.js +85 -0
- package/dist/react/components/split-button.d.ts +38 -0
- package/dist/react/components/split-button.js +43 -0
- package/dist/react/components/split-panes.d.ts +35 -0
- package/dist/react/components/split-panes.js +102 -0
- package/dist/react/components/stat-tiles.d.ts +54 -0
- package/dist/react/components/stat-tiles.js +8 -0
- package/dist/react/components/steps.d.ts +11 -0
- package/dist/react/components/steps.js +13 -0
- package/dist/react/components/switch.d.ts +6 -0
- package/dist/react/components/switch.js +13 -0
- package/dist/react/components/table.d.ts +61 -0
- package/dist/react/components/table.js +6 -0
- package/dist/react/components/tabs.d.ts +7 -0
- package/dist/react/components/tabs.js +13 -0
- package/dist/react/components/tags.d.ts +33 -0
- package/dist/react/components/tags.js +83 -0
- package/dist/react/components/textarea.d.ts +10 -0
- package/dist/react/components/textarea.js +6 -0
- package/dist/react/components/toast.d.ts +35 -0
- package/dist/react/components/toast.js +90 -0
- package/dist/react/components/tooltip-and-key.d.ts +20 -0
- package/dist/react/components/tooltip-and-key.js +20 -0
- package/dist/react/components/tree-view.d.ts +34 -0
- package/dist/react/components/tree-view.js +118 -0
- package/dist/react/components/upload-dropzone.d.ts +92 -0
- package/dist/react/components/upload-dropzone.js +116 -0
- package/dist/react/components/wizard-shell.d.ts +78 -0
- package/dist/react/components/wizard-shell.js +176 -0
- package/dist/react/fonts.css.d.ts +1 -0
- package/dist/react/index.d.ts +76 -0
- package/dist/react/index.js +77 -0
- package/dist/react/integrations/quickcrop.d.ts +58 -0
- package/dist/react/integrations/quickcrop.js +137 -0
- package/dist/react/integrations/richclay.d.ts +43 -0
- package/dist/react/integrations/richclay.js +129 -0
- package/dist/react/internal/classes.d.ts +3 -0
- package/dist/react/internal/classes.js +10 -0
- package/dist/react/internal/close-mark.d.ts +1 -0
- package/dist/react/internal/close-mark.js +10 -0
- package/dist/react/internal/controllable-state.d.ts +9 -0
- package/dist/react/internal/controllable-state.js +22 -0
- package/dist/react/internal/drop-effect.d.ts +28 -0
- package/dist/react/internal/drop-effect.js +8 -0
- package/dist/react/internal/form-reset.d.ts +2 -0
- package/dist/react/internal/form-reset.js +22 -0
- package/dist/react/internal/format.d.ts +1 -0
- package/dist/react/internal/format.js +14 -0
- package/dist/react/internal/link.d.ts +2 -0
- package/dist/react/internal/link.js +8 -0
- package/dist/react/internal/part.d.ts +20 -0
- package/dist/react/internal/part.js +47 -0
- package/dist/react/internal/pointer-session.d.ts +8 -0
- package/dist/react/internal/pointer-session.js +60 -0
- package/dist/react/internal/refs.d.ts +2 -0
- package/dist/react/internal/refs.js +22 -0
- package/dist/react/internal/rich-text.d.ts +28 -0
- package/dist/react/internal/rich-text.js +4 -0
- package/dist/react/internal/table-context.d.ts +39 -0
- package/dist/react/internal/table-context.js +12 -0
- package/dist/react/internal/use-object-url.d.ts +1 -0
- package/dist/react/internal/use-object-url.js +15 -0
- package/dist/react/layout.css +274 -0
- package/dist/react/layout.css.d.ts +1 -0
- package/dist/react/models/filter.d.ts +31 -0
- package/dist/react/models/filter.js +79 -0
- package/dist/react/models/kanban.d.ts +51 -0
- package/dist/react/models/kanban.js +35 -0
- package/dist/react/models/reorder.d.ts +9 -0
- package/dist/react/models/reorder.js +23 -0
- package/dist/react/models/table.d.ts +85 -0
- package/dist/react/models/table.js +144 -0
- package/dist/react/models/tree.d.ts +16 -0
- package/dist/react/models/tree.js +26 -0
- package/dist/react/provider.d.ts +18 -0
- package/dist/react/provider.js +31 -0
- package/dist/react/recipes/context-hypercms.d.ts +17 -0
- package/dist/react/recipes/context-hypercms.js +71 -0
- package/dist/react/recipes/context-quickcrop.d.ts +8 -0
- package/dist/react/recipes/context-quickcrop.js +49 -0
- package/dist/react/theme.css +8004 -0
- package/dist/react/theme.css.d.ts +1 -0
- package/examples/README.md +34 -0
- package/examples/components/activity-feed.html +28 -0
- package/examples/components/app-shell.html +12 -0
- package/examples/components/app-toolbar.html +38 -0
- package/examples/components/avatar-group.html +27 -0
- package/examples/components/breadcrumbs.html +26 -0
- package/examples/components/bulk-bar.html +22 -0
- package/examples/components/code-block.html +12 -0
- package/examples/components/code-editor.html +25 -0
- package/examples/components/column-manager.html +9 -0
- package/examples/components/combobox.html +13 -0
- package/examples/components/context-hypercms.css +41 -0
- package/examples/components/context-hypercms.html +40 -0
- package/examples/components/context-hypercms.js +62 -0
- package/examples/components/context-quickcrop.html +137 -0
- package/examples/components/diff-view.html +9 -0
- package/examples/components/drawer.html +11 -0
- package/examples/components/editable-grid-cells.html +9 -0
- package/examples/components/file-browser.html +53 -0
- package/examples/components/file-tree.html +34 -0
- package/examples/components/files-table.html +80 -0
- package/examples/components/filter-builder.html +11 -0
- package/examples/components/form-error-summary.html +11 -0
- package/examples/components/index.html +51 -0
- package/examples/components/inline-edit.html +42 -0
- package/examples/components/kanban-board.html +42 -0
- package/examples/components/manifest.json +3279 -0
- package/examples/components/modal.html +11 -0
- package/examples/components/multi-select-picker.html +13 -0
- package/examples/components/pagination.html +32 -0
- package/examples/components/persistent-action-banner.html +23 -0
- package/examples/components/popconfirm.html +13 -0
- package/examples/components/popover-menu.html +13 -0
- package/examples/components/reference/baseline/DECISIONS.md +85 -0
- package/examples/components/reference/baseline/README.md +58 -0
- package/examples/components/reference/baseline/bevel-fonts.css +16 -0
- package/examples/components/reference/baseline/bevel.css +1339 -0
- package/examples/components/reference/baseline/bevel.js +496 -0
- package/examples/components/reference/baseline/fonts/LICENSE-ibm-plex-mono.txt +93 -0
- package/examples/components/reference/baseline/fonts/LICENSE-ibm-plex-sans.txt +93 -0
- package/examples/components/reference/baseline/fonts/LICENSE-newsreader.txt +93 -0
- package/examples/components/reference/baseline/fonts/ibm-plex-mono-latin-400-normal.woff2 +0 -0
- package/examples/components/reference/baseline/fonts/ibm-plex-mono-latin-500-normal.woff2 +0 -0
- package/examples/components/reference/baseline/fonts/ibm-plex-mono-latin-600-normal.woff2 +0 -0
- package/examples/components/reference/baseline/fonts/ibm-plex-sans-latin-400-italic.woff2 +0 -0
- package/examples/components/reference/baseline/fonts/ibm-plex-sans-latin-400-normal.woff2 +0 -0
- package/examples/components/reference/baseline/fonts/ibm-plex-sans-latin-500-normal.woff2 +0 -0
- package/examples/components/reference/baseline/fonts/ibm-plex-sans-latin-600-normal.woff2 +0 -0
- package/examples/components/reference/baseline/fonts/newsreader-latin-opsz-italic.woff2 +0 -0
- package/examples/components/reference/baseline/fonts/newsreader-latin-opsz-normal.woff2 +0 -0
- package/examples/components/reference/fable/IMPROVEMENTS.md +106 -0
- package/examples/components/reference/fable/PARENT-REPAIRS.md +17 -0
- package/examples/components/reference/fable/__pycache__/build_repairs.cpython-311.pyc +0 -0
- package/examples/components/reference/fable/__pycache__/kanban.cpython-311.pyc +0 -0
- package/examples/components/reference/fable/as-authored/IMPROVEMENTS-completed.md +106 -0
- package/examples/components/reference/fable/as-authored/base-astra.css +17 -0
- package/examples/components/reference/fable/as-authored/base-parent.css +416 -0
- package/examples/components/reference/fable/as-authored/build.py +858 -0
- package/examples/components/reference/fable/as-authored/fable.css +823 -0
- package/examples/components/reference/fable/as-authored/kanban-completed.css +235 -0
- package/examples/components/reference/fable/as-authored/kanban-completed.html +53 -0
- package/examples/components/reference/fable/as-authored/kanban-completed.py +212 -0
- package/examples/components/reference/fable/as-authored/kanban.py +207 -0
- package/examples/components/reference/fable/base-astra.css +17 -0
- package/examples/components/reference/fable/base-parent.css +416 -0
- package/examples/components/reference/fable/build.py +858 -0
- package/examples/components/reference/fable/build_repairs.py +25 -0
- package/examples/components/reference/fable/components/activity-feed.html +3 -0
- package/examples/components/reference/fable/components/app-toolbar.html +3 -0
- package/examples/components/reference/fable/components/avatar-group.html +4 -0
- package/examples/components/reference/fable/components/breadcrumbs.html +3 -0
- package/examples/components/reference/fable/components/code-block.html +9 -0
- package/examples/components/reference/fable/components/column-manager.html +3 -0
- package/examples/components/reference/fable/components/combobox.html +6 -0
- package/examples/components/reference/fable/components/context-hypercms.html +3 -0
- package/examples/components/reference/fable/components/context-quickcrop.html +4 -0
- package/examples/components/reference/fable/components/diff-view.html +13 -0
- package/examples/components/reference/fable/components/drawer.html +3 -0
- package/examples/components/reference/fable/components/editable-grid-cells.html +3 -0
- package/examples/components/reference/fable/components/filter-builder.html +3 -0
- package/examples/components/reference/fable/components/form-error-summary.html +4 -0
- package/examples/components/reference/fable/components/inline-edit.html +3 -0
- package/examples/components/reference/fable/components/kanban-board.html +53 -0
- package/examples/components/reference/fable/components/modal.html +3 -0
- package/examples/components/reference/fable/components/multi-select-picker.html +5 -0
- package/examples/components/reference/fable/components/pagination.html +3 -0
- package/examples/components/reference/fable/components/persistent-action-banner.html +4 -0
- package/examples/components/reference/fable/components/popconfirm.html +5 -0
- package/examples/components/reference/fable/components/popover-menu.html +3 -0
- package/examples/components/reference/fable/components/rich-text-toolbar.html +3 -0
- package/examples/components/reference/fable/components/save-status-indicator.html +2 -0
- package/examples/components/reference/fable/components/selectable-cards.html +3 -0
- package/examples/components/reference/fable/components/settings-rows.html +3 -0
- package/examples/components/reference/fable/components/sidebar-nav.html +4 -0
- package/examples/components/reference/fable/components/small-charts.html +5 -0
- package/examples/components/reference/fable/components/split-button.html +4 -0
- package/examples/components/reference/fable/components/split-panes.html +8 -0
- package/examples/components/reference/fable/components/stat-tiles.html +3 -0
- package/examples/components/reference/fable/components/toast-stack.html +5 -0
- package/examples/components/reference/fable/components/tree-view.html +4 -0
- package/examples/components/reference/fable/components/upload-dropzone.html +6 -0
- package/examples/components/reference/fable/components/wizard-shell.html +3 -0
- package/examples/components/reference/fable/coverage.json +414 -0
- package/examples/components/reference/fable/fable.css +823 -0
- package/examples/components/reference/fable/index.html +5 -0
- package/examples/components/reference/fable/kanban.css +237 -0
- package/examples/components/reference/fable/kanban.py +212 -0
- package/examples/components/reference/fable/parent-repairs.css +9 -0
- package/examples/components/reference/fixtures/data.json +102 -0
- package/examples/components/reference/fixtures/host.js +47 -0
- package/examples/components/reference/fixtures/static-host.js +39 -0
- package/examples/components/reference/fixtures/workspace.jpg +0 -0
- package/examples/components/reference/parent/CHANGES.md +179 -0
- package/examples/components/reference/parent/__pycache__/kanban.cpython-311.pyc +0 -0
- package/examples/components/reference/parent/base-astra.css +17 -0
- package/examples/components/reference/parent/base-parent.css +416 -0
- package/examples/components/reference/parent/build.py +148 -0
- package/examples/components/reference/parent/components/activity-feed.html +2 -0
- package/examples/components/reference/parent/components/app-toolbar.html +2 -0
- package/examples/components/reference/parent/components/avatar-group.html +4 -0
- package/examples/components/reference/parent/components/breadcrumbs.html +2 -0
- package/examples/components/reference/parent/components/code-block.html +8 -0
- package/examples/components/reference/parent/components/column-manager.html +2 -0
- package/examples/components/reference/parent/components/combobox.html +6 -0
- package/examples/components/reference/parent/components/context-hypercms.html +2 -0
- package/examples/components/reference/parent/components/context-quickcrop.html +4 -0
- package/examples/components/reference/parent/components/diff-view.html +4 -0
- package/examples/components/reference/parent/components/drawer.html +2 -0
- package/examples/components/reference/parent/components/editable-grid-cells.html +2 -0
- package/examples/components/reference/parent/components/filter-builder.html +2 -0
- package/examples/components/reference/parent/components/form-error-summary.html +2 -0
- package/examples/components/reference/parent/components/inline-edit.html +2 -0
- package/examples/components/reference/parent/components/kanban-board.html +84 -0
- package/examples/components/reference/parent/components/modal.html +2 -0
- package/examples/components/reference/parent/components/multi-select-picker.html +5 -0
- package/examples/components/reference/parent/components/pagination.html +2 -0
- package/examples/components/reference/parent/components/persistent-action-banner.html +4 -0
- package/examples/components/reference/parent/components/popconfirm.html +5 -0
- package/examples/components/reference/parent/components/popover-menu.html +2 -0
- package/examples/components/reference/parent/components/rich-text-toolbar.html +2 -0
- package/examples/components/reference/parent/components/save-status-indicator.html +2 -0
- package/examples/components/reference/parent/components/selectable-cards.html +2 -0
- package/examples/components/reference/parent/components/settings-rows.html +2 -0
- package/examples/components/reference/parent/components/sidebar-nav.html +4 -0
- package/examples/components/reference/parent/components/small-charts.html +2 -0
- package/examples/components/reference/parent/components/split-button.html +5 -0
- package/examples/components/reference/parent/components/split-panes.html +8 -0
- package/examples/components/reference/parent/components/stat-tiles.html +2 -0
- package/examples/components/reference/parent/components/toast-stack.html +5 -0
- package/examples/components/reference/parent/components/tree-view.html +4 -0
- package/examples/components/reference/parent/components/upload-dropzone.html +6 -0
- package/examples/components/reference/parent/components/wizard-shell.html +2 -0
- package/examples/components/reference/parent/coverage.json +414 -0
- package/examples/components/reference/parent/index.html +1 -0
- package/examples/components/reference/parent/kanban.css +114 -0
- package/examples/components/reference/parent/kanban.py +55 -0
- package/examples/components/reference/parent/refinement.css +53 -0
- package/examples/components/reference/selected/build.py +70 -0
- package/examples/components/reference/selected/components/activity-feed.html +3 -0
- package/examples/components/reference/selected/components/app-toolbar.html +3 -0
- package/examples/components/reference/selected/components/avatar-group.html +4 -0
- package/examples/components/reference/selected/components/breadcrumbs.html +3 -0
- package/examples/components/reference/selected/components/code-block.html +9 -0
- package/examples/components/reference/selected/components/column-manager.html +3 -0
- package/examples/components/reference/selected/components/combobox.html +6 -0
- package/examples/components/reference/selected/components/context-hypercms.html +3 -0
- package/examples/components/reference/selected/components/context-quickcrop.html +4 -0
- package/examples/components/reference/selected/components/diff-view.html +13 -0
- package/examples/components/reference/selected/components/drawer.html +3 -0
- package/examples/components/reference/selected/components/editable-grid-cells.html +3 -0
- package/examples/components/reference/selected/components/filter-builder.html +3 -0
- package/examples/components/reference/selected/components/form-error-summary.html +4 -0
- package/examples/components/reference/selected/components/inline-edit.html +3 -0
- package/examples/components/reference/selected/components/kanban-board.html +53 -0
- package/examples/components/reference/selected/components/modal.html +2 -0
- package/examples/components/reference/selected/components/multi-select-picker.html +5 -0
- package/examples/components/reference/selected/components/pagination.html +3 -0
- package/examples/components/reference/selected/components/persistent-action-banner.html +4 -0
- package/examples/components/reference/selected/components/popconfirm.html +5 -0
- package/examples/components/reference/selected/components/popover-menu.html +3 -0
- package/examples/components/reference/selected/components/rich-text-toolbar.html +3 -0
- package/examples/components/reference/selected/components/save-status-indicator.html +2 -0
- package/examples/components/reference/selected/components/selectable-cards.html +3 -0
- package/examples/components/reference/selected/components/settings-rows.html +3 -0
- package/examples/components/reference/selected/components/sidebar-nav.html +4 -0
- package/examples/components/reference/selected/components/small-charts.html +5 -0
- package/examples/components/reference/selected/components/split-button.html +4 -0
- package/examples/components/reference/selected/components/split-panes.html +8 -0
- package/examples/components/reference/selected/components/stat-tiles.html +3 -0
- package/examples/components/reference/selected/components/toast-stack.html +5 -0
- package/examples/components/reference/selected/components/tree-view.html +4 -0
- package/examples/components/reference/selected/components/upload-dropzone.html +6 -0
- package/examples/components/reference/selected/components/wizard-shell.html +3 -0
- package/examples/components/reference/selected/corrections.css +11 -0
- package/examples/components/reference/selected/coverage.json +413 -0
- package/examples/components/reference/selected/gallery-build.mjs +49 -0
- package/examples/components/reference/selected/gallery-spec.json +12 -0
- package/examples/components/reference/selected/index.html +1 -0
- package/examples/components/reference/selected/kanban-comparison.json +6 -0
- package/examples/components/reference/selected/manifest.json +476 -0
- package/examples/components/reference/sha256.json +142 -0
- package/examples/components/reference/sources/diagonal-close.svg +1 -0
- package/examples/components/reference/sources/hyperclay/public-assets/css/hyperclay-app-source.css +614 -0
- package/examples/components/reference/sources/hyperclay/public-assets/js/app.js +94 -0
- package/examples/components/reference/sources/hyperclayjs/src/ui/theModal.js +897 -0
- package/examples/components/reference/sources/hypercms/scripts/build-theme.js +203 -0
- package/examples/components/reference/sources/hypercms/src/anchor.js +24 -0
- package/examples/components/reference/sources/hypercms/src/apply-loop.js +167 -0
- package/examples/components/reference/sources/hypercms/src/diagnostics.js +44 -0
- package/examples/components/reference/sources/hypercms/src/enhance.js +173 -0
- package/examples/components/reference/sources/hypercms/src/events.js +955 -0
- package/examples/components/reference/sources/hypercms/src/form-builder.js +518 -0
- package/examples/components/reference/sources/hypercms/src/form-rules.js +208 -0
- package/examples/components/reference/sources/hypercms/src/hooks.js +100 -0
- package/examples/components/reference/sources/hypercms/src/hypercms-bundle.js +10 -0
- package/examples/components/reference/sources/hypercms/src/hypercms.js +347 -0
- package/examples/components/reference/sources/hypercms/src/morph.js +10 -0
- package/examples/components/reference/sources/hypercms/src/path.js +61 -0
- package/examples/components/reference/sources/hypercms/src/place.js +131 -0
- package/examples/components/reference/sources/hypercms/src/platform.js +131 -0
- package/examples/components/reference/sources/hypercms/src/refresh.js +87 -0
- package/examples/components/reference/sources/hypercms/src/richclay-bridge.js +140 -0
- package/examples/components/reference/sources/hypercms/src/row-identity.js +111 -0
- package/examples/components/reference/sources/hypercms/src/scaffold.js +10 -0
- package/examples/components/reference/sources/hypercms/src/session.js +303 -0
- package/examples/components/reference/sources/hypercms/src/shell.js +248 -0
- package/examples/components/reference/sources/hypercms/src/styles.css +298 -0
- package/examples/components/reference/sources/hypercms/src/targets.js +144 -0
- package/examples/components/reference/sources/hypercms/src/templates.js +656 -0
- package/examples/components/reference/sources/hypercms/src/theme/pixel-quiet.overrides.css +761 -0
- package/examples/components/reference/sources/hypercms/src/theme.generated.css +1772 -0
- package/examples/components/reference/sources/hypercms/src/toggle.js +666 -0
- package/examples/components/reference/sources/hypercms/src/unresolved.js +211 -0
- package/examples/components/reference/sources/hypercms/src/vendor/mirk.vendor.js +212 -0
- package/examples/components/reference/sources/hypercms/src/views/inline-layer.js +421 -0
- package/examples/components/reference/sources/hypercms/src/views/inline.js +1072 -0
- package/examples/components/reference/sources/hypercms/src/views/sidebar.js +97 -0
- package/examples/components/reference/sources/modal-reference.html +301 -0
- package/examples/components/reference/sources/quickcrop/quickcrop.css +124 -0
- package/examples/components/reference/sources/quickcrop/quickcrop.js +400 -0
- package/examples/components/reference/sources/richclay/richclay.css +416 -0
- package/examples/components/reference/sources/richclay/richclay.js +2962 -0
- package/examples/components/reference/sources/richclay/src/a11y.js +67 -0
- package/examples/components/reference/sources/richclay/src/browser-global.js +7 -0
- package/examples/components/reference/sources/richclay/src/buttons.js +254 -0
- package/examples/components/reference/sources/richclay/src/hyperclay.js +470 -0
- package/examples/components/reference/sources/richclay/src/normalize.js +380 -0
- package/examples/components/reference/sources/richclay/src/richclay.js +1356 -0
- package/examples/components/reference/sources/richclay/src/sanitize.js +189 -0
- package/examples/components/reference/sources/richclay/src/styles.js +23 -0
- package/examples/components/reference/sources/richclay/src/toolbar-float.js +175 -0
- package/examples/components/reference/sources/richclay/src/toolbar.js +394 -0
- package/examples/components/reference/sources/richclay/src/vendor-bundle.js +15 -0
- package/examples/components/reference/sources/richclay/vendor/DOMPURIFY-LICENSE +202 -0
- package/examples/components/reference/sources/richclay/vendor/DOMPURIFY-LICENSE-MPL +373 -0
- package/examples/components/reference/sources/richclay/vendor/SQUIRE-LICENSE +21 -0
- package/examples/components/reference/sources/richclay/vendor/purify.es.mjs +2249 -0
- package/examples/components/reference/sources/richclay/vendor/purify.min.js +3 -0
- package/examples/components/reference/sources/richclay/vendor/squire.js +22 -0
- package/examples/components/reference/sources/richclay/vendor/squire.mjs +22 -0
- package/examples/components/reference/sources/richclay/vendor/squire.provenance.json +19 -0
- package/examples/components/rich-text-toolbar.html +43 -0
- package/examples/components/save-status-indicator.html +11 -0
- package/examples/components/selectable-cards.html +9 -0
- package/examples/components/settings-rows.html +10 -0
- package/examples/components/sidebar-nav.html +9 -0
- package/examples/components/small-charts.html +21 -0
- package/examples/components/split-button.html +13 -0
- package/examples/components/split-panes-editor.html +6 -0
- package/examples/components/split-panes.html +9 -0
- package/examples/components/stat-tiles.html +23 -0
- package/examples/components/toast-stack.html +21 -0
- package/examples/components/tree-view.html +9 -0
- package/examples/components/upload-dropzone.html +88 -0
- package/examples/components/wizard-shell.html +50 -0
- package/examples/datastar/index.html +38 -0
- package/examples/datastar/server.mjs +31 -0
- package/examples/fixtures/field-guide.pdf +14 -0
- package/examples/fixtures/workspace.jpg +0 -0
- package/examples/setup-peers.mjs +35 -0
- package/fonts/LICENSE-ibm-plex-mono.txt +93 -0
- package/fonts/LICENSE-ibm-plex-sans.txt +93 -0
- package/fonts/LICENSE-newsreader.txt +93 -0
- package/fonts/ibm-plex-mono-latin-400-normal.woff2 +0 -0
- package/fonts/ibm-plex-mono-latin-500-normal.woff2 +0 -0
- package/fonts/ibm-plex-mono-latin-600-normal.woff2 +0 -0
- package/fonts/ibm-plex-sans-latin-400-italic.woff2 +0 -0
- package/fonts/ibm-plex-sans-latin-400-normal.woff2 +0 -0
- package/fonts/ibm-plex-sans-latin-500-normal.woff2 +0 -0
- package/fonts/ibm-plex-sans-latin-600-normal.woff2 +0 -0
- package/fonts/newsreader-latin-opsz-italic.woff2 +0 -0
- package/fonts/newsreader-latin-opsz-normal.woff2 +0 -0
- package/icons/LICENSE +21 -0
- package/icons/house.json +71 -0
- package/icons/icons.d.ts +17 -0
- package/icons/icons.js +648 -0
- package/icons/icons.svg +126 -0
- package/icons/marks/build-tray.source.mjs +45 -0
- package/icons/marks/hyperclay-local.svg +11 -0
- package/icons/phosphor.json +53 -0
- package/icons/round.json +8 -0
- package/integrations/datastar.js +202 -0
- package/integrations/quickcrop.css +26 -0
- package/integrations/quickcrop.js +56 -0
- package/integrations/richclay.css +100 -0
- package/integrations/richclay.js +131 -0
- package/package.json +630 -0
- package/react/README.md +244 -0
- package/src/README.md +83 -0
- package/vendor/datastar/datastar-1.0.3.js +10 -0
- package/vendor/datastar/provenance.json +6 -0
- package/vendor/floating-ui/LICENSE-core +20 -0
- package/vendor/floating-ui/LICENSE-dom +20 -0
- package/vendor/floating-ui/floating-ui.core.umd.min.js +1 -0
- package/vendor/floating-ui/floating-ui.dom.umd.min.js +1 -0
- package/vendor/floating-ui/provenance.json +17 -0
- package/vendor/richclay/LICENSE +16 -0
- package/vendor/richclay/THIRD-PARTY-NOTICES.md +45 -0
- package/vendor/richclay/provenance.json +17 -0
- package/vendor/richclay/richclay.css +404 -0
- package/vendor/richclay/richclay.js +2940 -0
- package/vendor/richclay/vendor/DOMPURIFY-LICENSE +202 -0
- package/vendor/richclay/vendor/DOMPURIFY-LICENSE-MPL +373 -0
- package/vendor/richclay/vendor/SQUIRE-LICENSE +21 -0
- package/vendor/richclay/vendor/purify.min.js +3 -0
- package/vendor/richclay/vendor/squire.js +22 -0
- package/vendor/richclay/vendor/squire.provenance.json +30 -0
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
// Squire assumes a container's children are all block-level. Its fixContainer()
|
|
2
|
+
// gathers any run of inline children into a fresh <div> and gives that <div> a
|
|
3
|
+
// <br>, so a formatting-whitespace text node left over from the page's source
|
|
4
|
+
// indentation becomes a *visible blank line* the first time a delete or a merge
|
|
5
|
+
// runs, and every later split copies it into another block. Card mode never sees
|
|
6
|
+
// this because Squire's setHTML() normalizes on ingress; inline mode skips
|
|
7
|
+
// setHTML() on purpose, so richclay has to establish that invariant itself.
|
|
8
|
+
//
|
|
9
|
+
// Only that invariant. setHTML() would also rewrite STRONG/EM/INS/STRIKE, turn
|
|
10
|
+
// styled spans into semantic tags, and unwrap every element outside Squire's
|
|
11
|
+
// block allowlist, which is exactly the author markup inline mode promises to
|
|
12
|
+
// leave alone.
|
|
13
|
+
|
|
14
|
+
// Mirrors Squire's node categories (source/node/Category.ts). Whitespace is
|
|
15
|
+
// content inside a block and formatting noise inside a container, so richclay
|
|
16
|
+
// has to draw that line where Squire draws it, not where CSS does.
|
|
17
|
+
const INLINE_NODE_NAMES =
|
|
18
|
+
/^(?:#text|A(?:BBR|CRONYM)?|B(?:R|D[IO])?|C(?:ITE|ODE)|D(?:ATA|EL|FN)|EM|FONT|HR|I(?:FRAME|MG|NPUT|NS)?|KBD|Q|R(?:P|T|UBY)|S(?:AMP|MALL|PAN|TR(?:IKE|ONG)|U[BP])?|TIME|U|VAR|WBR)$/;
|
|
19
|
+
const NOT_WHITESPACE = /[^ \t\r\n]/;
|
|
20
|
+
|
|
21
|
+
const ELEMENT_NODE = 1;
|
|
22
|
+
const TEXT_NODE = 3;
|
|
23
|
+
const COMMENT_NODE = 8;
|
|
24
|
+
|
|
25
|
+
const LEAF_NODE_NAMES = new Set(["BR", "HR", "IFRAME", "IMG", "INPUT", "WBR"]);
|
|
26
|
+
|
|
27
|
+
// SVG and MathML roots keep their lowercase nodeName, so they can never match
|
|
28
|
+
// INLINE_NODE_NAMES and would otherwise split a line of prose into three blocks
|
|
29
|
+
// around an inline icon. Their subtrees are foreign content, not HTML, so they
|
|
30
|
+
// are never walked. A deliberate divergence from Squire, which has no such case.
|
|
31
|
+
const FOREIGN_INLINE_ROOTS = new Set(["svg", "math"]);
|
|
32
|
+
|
|
33
|
+
export function isInlineNode(node) {
|
|
34
|
+
const type = node.nodeType;
|
|
35
|
+
if (type === TEXT_NODE || type === COMMENT_NODE) return true;
|
|
36
|
+
if (type !== ELEMENT_NODE) return false;
|
|
37
|
+
if (FOREIGN_INLINE_ROOTS.has(node.nodeName)) return true;
|
|
38
|
+
if (!INLINE_NODE_NAMES.test(node.nodeName)) return false;
|
|
39
|
+
return Array.from(node.childNodes).every(isInlineNode);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function isBlockContainer(element) {
|
|
43
|
+
return Array.from(element.childNodes).some(node => !isInlineNode(node));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const isBlockElement = node =>
|
|
47
|
+
node?.nodeType === ELEMENT_NODE &&
|
|
48
|
+
!FOREIGN_INLINE_ROOTS.has(node.nodeName) &&
|
|
49
|
+
!INLINE_NODE_NAMES.test(node.nodeName);
|
|
50
|
+
|
|
51
|
+
// The exact inverse of Squire's fixContainer(), which gathers every run of inline
|
|
52
|
+
// children into a block. A root that cannot hold blocks needs that undone after an
|
|
53
|
+
// insert, because Squire runs fixContainer on the inserted fragment whatever the
|
|
54
|
+
// root is: pasting even a bare string into <p editable> lands a <div> inside the
|
|
55
|
+
// <p>, and the reload moves everything after the caret out of the region. Both
|
|
56
|
+
// sides read INLINE_NODE_NAMES, so the two stay symmetric by construction.
|
|
57
|
+
//
|
|
58
|
+
// Recursive rather than a querySelector loop because each level's boundary
|
|
59
|
+
// decision has to see its siblings as they were before that level was unwrapped.
|
|
60
|
+
// Flattening <div><p>A</p><p>B</p></div> outside-in loses the A/B boundary.
|
|
61
|
+
export function flattenBlocks(parent, createBoundary) {
|
|
62
|
+
const children = Array.from(parent.childNodes);
|
|
63
|
+
let removed = 0;
|
|
64
|
+
children.forEach((child, index) => {
|
|
65
|
+
if (child.nodeType !== ELEMENT_NODE || FOREIGN_INLINE_ROOTS.has(child.nodeName)) return;
|
|
66
|
+
removed += flattenBlocks(child, createBoundary);
|
|
67
|
+
if (!isBlockElement(child)) return;
|
|
68
|
+
// Only between two blocks. A lone block is the pasted content merging with the
|
|
69
|
+
// text around the caret, which is what a split would have produced, so a break
|
|
70
|
+
// there would be a line the author never asked for.
|
|
71
|
+
if (isBlockElement(children[index - 1])) parent.insertBefore(createBoundary(), child);
|
|
72
|
+
while (child.firstChild) parent.insertBefore(child.firstChild, child);
|
|
73
|
+
child.remove();
|
|
74
|
+
removed += 1;
|
|
75
|
+
});
|
|
76
|
+
return removed;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// The two shapes a browser rearranges on reload, measured against the real parser
|
|
80
|
+
// in both jsdom and Chrome. A <p> ejects a block from any depth below it, so it is
|
|
81
|
+
// the ancestor that matters and not the region's own tag; the table structure
|
|
82
|
+
// foster-parents a stray block out before the table. Everything else keeps an
|
|
83
|
+
// invalid block exactly where it was put, which is all the file format needs.
|
|
84
|
+
//
|
|
85
|
+
// TD and TH are deliberately absent: they are ordinary flow containers.
|
|
86
|
+
const TABLE_STRUCTURE = new Set(["TABLE", "THEAD", "TBODY", "TFOOT", "TR", "COLGROUP"]);
|
|
87
|
+
|
|
88
|
+
export function ejectsBlocks(root) {
|
|
89
|
+
return Boolean(root.closest?.("p")) || TABLE_STRUCTURE.has(root.nodeName);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Elements an author writes as a single line of text, and whose shape richclay
|
|
93
|
+
// therefore leaves alone: <h2 editable>Hello</h2> should still say exactly that
|
|
94
|
+
// after an edit, not <h2 editable><div>Hello</div></h2>. A <div> or a <section> is
|
|
95
|
+
// a container and gets the full editor.
|
|
96
|
+
//
|
|
97
|
+
// Unlike the allowlist round 4 deleted, a wrong entry here costs a hidden toolbar
|
|
98
|
+
// button or a preserved line of markup, never content, so a short list is the
|
|
99
|
+
// right tool rather than a liability.
|
|
100
|
+
const TEXT_LINE_ROOTS = new Set([
|
|
101
|
+
"P", "H1", "H2", "H3", "H4", "H5", "H6", "PRE", "LABEL", "LEGEND",
|
|
102
|
+
"LI", "TD", "TH", "DT", "DD", "FIGCAPTION", "SUMMARY", "CAPTION"
|
|
103
|
+
]);
|
|
104
|
+
|
|
105
|
+
export function keepsTextShape(root) {
|
|
106
|
+
return TEXT_LINE_ROOTS.has(root.nodeName) || isInlineTag(root);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const VOID_ROOTS = new Set([
|
|
110
|
+
"AREA", "BASE", "BR", "COL", "EMBED", "HR", "IMG", "INPUT",
|
|
111
|
+
"LINK", "META", "PARAM", "SOURCE", "TRACK", "WBR"
|
|
112
|
+
]);
|
|
113
|
+
const RAW_TEXT_ROOTS = new Set(["SCRIPT", "STYLE", "TEXTAREA", "TITLE", "IFRAME", "NOSCRIPT", "XMP"]);
|
|
114
|
+
const HTML_NS = "http://www.w3.org/1999/xhtml";
|
|
115
|
+
|
|
116
|
+
// Every family here fails one test: can this element hold HTML children that
|
|
117
|
+
// survive a save and a reload. Table structure foster-parents them out, foreign
|
|
118
|
+
// content breaks out of the SVG, raw-text roots turn them into literal text a
|
|
119
|
+
// reader can see, <template> serializes .content and drops them, and a void
|
|
120
|
+
// element cannot hold anything at all.
|
|
121
|
+
export function isUnsupportedRootTag(root) {
|
|
122
|
+
return (
|
|
123
|
+
TABLE_STRUCTURE.has(root.nodeName) ||
|
|
124
|
+
VOID_ROOTS.has(root.nodeName) ||
|
|
125
|
+
RAW_TEXT_ROOTS.has(root.nodeName) ||
|
|
126
|
+
root.nodeName === "TEMPLATE" ||
|
|
127
|
+
Boolean(root.namespaceURI) && root.namespaceURI !== HTML_NS
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function unsupportedRootReason(root) {
|
|
132
|
+
if (TABLE_STRUCTURE.has(root.nodeName)) {
|
|
133
|
+
return "a table element cannot be an editable region. Move the editable attribute to a <td>, a <th>, or an element inside one.";
|
|
134
|
+
}
|
|
135
|
+
if (root.namespaceURI && root.namespaceURI !== HTML_NS) {
|
|
136
|
+
return "an SVG or MathML element cannot be an editable region: an edit puts an HTML block inside it, and the next page load moves that text out of the graphic entirely. Put a <foreignObject> in the SVG and mark an HTML element inside it instead.";
|
|
137
|
+
}
|
|
138
|
+
if (VOID_ROOTS.has(root.nodeName)) {
|
|
139
|
+
return "this element cannot contain anything, so there is nothing to edit. Move the editable attribute to an element that holds text.";
|
|
140
|
+
}
|
|
141
|
+
if (root.nodeName === "TEMPLATE") {
|
|
142
|
+
return "a <template> keeps its content out of the document, so edits to it are never saved.";
|
|
143
|
+
}
|
|
144
|
+
return "this element treats its content as plain text, so any edit would be saved as visible markup rather than formatting.";
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Shallow tag test, unlike isInlineNode which also walks children. Drives two
|
|
148
|
+
// cosmetic things only: the runtime display fix and the validity warning.
|
|
149
|
+
export function isInlineTag(node) {
|
|
150
|
+
return (
|
|
151
|
+
node.nodeType === ELEMENT_NODE &&
|
|
152
|
+
!FOREIGN_INLINE_ROOTS.has(node.nodeName) &&
|
|
153
|
+
INLINE_NODE_NAMES.test(node.nodeName)
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export function hasBlockDescendant(root) {
|
|
158
|
+
return Array.from(root.querySelectorAll("*")).some(isBlockElement);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export function normalizeEditorRoot(root, options = {}) {
|
|
162
|
+
const {
|
|
163
|
+
blockTag = "DIV",
|
|
164
|
+
wrapBareRoot = false,
|
|
165
|
+
onBareRootWrapped,
|
|
166
|
+
blocksAllowed = !ejectsBlocks(root)
|
|
167
|
+
} = options;
|
|
168
|
+
dropFormattingWhitespace(root);
|
|
169
|
+
if (blocksAllowed) {
|
|
170
|
+
wrapStrayInlineChildren(root, blockTag, wrapBareRoot, onBareRootWrapped);
|
|
171
|
+
}
|
|
172
|
+
return root;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// A comments-only run is left alone by flush(), so counting a comment here would
|
|
176
|
+
// leave the predicate permanently true and re-run the whole pass, plus its
|
|
177
|
+
// selection round trip, on every keystroke. Whitespace-only text nodes still
|
|
178
|
+
// count: those are dropped, not skipped.
|
|
179
|
+
const needsWrapping = node => isInlineNode(node) && node.nodeType !== COMMENT_NODE;
|
|
180
|
+
|
|
181
|
+
// Comments (Hyperclay's region markers) and formatting whitespace are not
|
|
182
|
+
// content, so a region holding only those is empty, not authored.
|
|
183
|
+
const isAuthorContent = node =>
|
|
184
|
+
node.nodeType !== COMMENT_NODE &&
|
|
185
|
+
!(node.nodeType === TEXT_NODE && !NOT_WHITESPACE.test(node.nodeValue));
|
|
186
|
+
|
|
187
|
+
// True while the root still violates Squire's invariant, so the caller can skip
|
|
188
|
+
// the pass, and its selection round trip, on every edit after the first. Mirrors
|
|
189
|
+
// what normalizeEditorRoot actually does, including its walk into nested blocks.
|
|
190
|
+
export function editorRootNeedsNormalization(
|
|
191
|
+
root,
|
|
192
|
+
{ wrapBareRoot = false, blocksAllowed = !ejectsBlocks(root) } = {}
|
|
193
|
+
) {
|
|
194
|
+
if (!blocksAllowed) return false;
|
|
195
|
+
if (!isBlockContainer(root)) return wrapBareRoot;
|
|
196
|
+
return Array.from(root.childNodes).some(needsWrapping) || hasNestedFormattingWhitespace(root);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function hasNestedFormattingWhitespace(element) {
|
|
200
|
+
return Array.from(element.children).some(child => {
|
|
201
|
+
if (!isBlockContainer(child)) return false;
|
|
202
|
+
const ownWhitespace =
|
|
203
|
+
!preservesWhitespace(child) &&
|
|
204
|
+
Array.from(child.childNodes).some(
|
|
205
|
+
node => node.nodeType === TEXT_NODE && !NOT_WHITESPACE.test(node.nodeValue)
|
|
206
|
+
);
|
|
207
|
+
return ownWhitespace || hasNestedFormattingWhitespace(child);
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function dropFormattingWhitespace(element) {
|
|
212
|
+
// A block's own whitespace is content ("a <b>b</b>"), and everything below a
|
|
213
|
+
// block is inline, so there is nothing to walk into either.
|
|
214
|
+
if (!isBlockContainer(element)) return;
|
|
215
|
+
|
|
216
|
+
if (!preservesWhitespace(element)) {
|
|
217
|
+
Array.from(element.childNodes).forEach(child => {
|
|
218
|
+
if (child.nodeType === TEXT_NODE && !NOT_WHITESPACE.test(child.nodeValue)) child.remove();
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
Array.from(element.children).forEach(dropFormattingWhitespace);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// A wholly inline root (<h1 editable>, a bare-text region) is a valid Squire
|
|
225
|
+
// block on its own, so a single-line region is left exactly as authored. A
|
|
226
|
+
// multi-line one is not editable in practice: Squire's Enter, Delete and
|
|
227
|
+
// Backspace all early-return when the caret's block is the root itself, so it
|
|
228
|
+
// gets one bare wrapper and the caller is told, in case the author would rather
|
|
229
|
+
// write their own.
|
|
230
|
+
function wrapStrayInlineChildren(root, blockTag, wrapBareRoot, onBareRootWrapped) {
|
|
231
|
+
if (!isBlockContainer(root)) {
|
|
232
|
+
if (!wrapBareRoot) return;
|
|
233
|
+
const wrapper = root.ownerDocument.createElement(blockTag);
|
|
234
|
+
// An empty region is the ordinary starting state, so it gets the placeholder
|
|
235
|
+
// block beside whatever markers are there, and no warning.
|
|
236
|
+
if (!Array.from(root.childNodes).some(isAuthorContent)) {
|
|
237
|
+
wrapper.appendChild(root.ownerDocument.createElement("BR"));
|
|
238
|
+
root.appendChild(wrapper);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
while (root.firstChild) wrapper.appendChild(root.firstChild);
|
|
242
|
+
root.appendChild(wrapper);
|
|
243
|
+
onBareRootWrapped?.(root, wrapper);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
let run = [];
|
|
248
|
+
const flush = () => {
|
|
249
|
+
const nodes = run;
|
|
250
|
+
run = [];
|
|
251
|
+
// A comments-only run has nothing to render; wrapping it would manufacture
|
|
252
|
+
// the blank line this whole pass exists to prevent.
|
|
253
|
+
if (!nodes.some(node => node.nodeType !== COMMENT_NODE)) return;
|
|
254
|
+
const block = root.ownerDocument.createElement(blockTag);
|
|
255
|
+
root.insertBefore(block, nodes[0]);
|
|
256
|
+
nodes.forEach(node => block.appendChild(node));
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
Array.from(root.childNodes).forEach(child => {
|
|
260
|
+
if (isInlineNode(child)) run.push(child);
|
|
261
|
+
else flush();
|
|
262
|
+
});
|
|
263
|
+
flush();
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Squire decides this on the tag alone, and agreeing with Squire is the point.
|
|
267
|
+
// Reading computed style also cost a forced style resolution per block container
|
|
268
|
+
// on every keystroke, and made a `white-space: pre-wrap` root keep whitespace in
|
|
269
|
+
// the drop pass that the wrap pass then turned into visible blank paragraphs.
|
|
270
|
+
function preservesWhitespace(element) {
|
|
271
|
+
return element.nodeName === "PRE";
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// normalizeEditorRoot only drops whitespace-only text nodes and moves existing
|
|
275
|
+
// nodes into a new wrapper, so a range boundary inside a surviving node stays
|
|
276
|
+
// valid by itself. Two do not survive: one inside a dropped whitespace node, and
|
|
277
|
+
// one anchored on the root, whose child offsets shift when a wrapper is
|
|
278
|
+
// inserted. Both are recovered by remembering the root children on either side
|
|
279
|
+
// and re-anchoring to whichever is still there.
|
|
280
|
+
export function captureRange(root, range) {
|
|
281
|
+
return {
|
|
282
|
+
start: captureBoundary(root, range.startContainer, range.startOffset),
|
|
283
|
+
end: captureBoundary(root, range.endContainer, range.endOffset),
|
|
284
|
+
collapsed: range.collapsed
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export function restoreRange(root, range, saved) {
|
|
289
|
+
applyBoundary(range, "setStart", root, saved.start);
|
|
290
|
+
if (saved.collapsed) range.collapse(true);
|
|
291
|
+
else applyBoundary(range, "setEnd", root, saved.end);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
function captureBoundary(root, container, offset) {
|
|
295
|
+
if (!root.contains(container)) return { scope: root, after: [], before: [] };
|
|
296
|
+
|
|
297
|
+
// Text nodes are moved whole, never split, so a boundary inside a surviving one
|
|
298
|
+
// stays valid by itself. Only a dropped whitespace node needs re-anchoring.
|
|
299
|
+
if (container.nodeType === TEXT_NODE) {
|
|
300
|
+
if (!isDroppedWhitespace(container)) return { container, offset };
|
|
301
|
+
const scope = container.parentNode;
|
|
302
|
+
return siblingAnchor(scope, Array.from(scope.childNodes).indexOf(container));
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// Element container: its children may be dropped, or moved into a new wrapper.
|
|
306
|
+
// Keep both the exact position and a node-based anchor and choose at restore
|
|
307
|
+
// time, so a container whose children never changed keeps the caret exactly
|
|
308
|
+
// where it was instead of being pushed inside its next child.
|
|
309
|
+
return {
|
|
310
|
+
container,
|
|
311
|
+
offset,
|
|
312
|
+
childCount: container.childNodes.length,
|
|
313
|
+
...siblingAnchor(container, offset)
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function siblingAnchor(scope, index) {
|
|
318
|
+
const children = Array.from(scope.childNodes);
|
|
319
|
+
const at = Math.max(0, index);
|
|
320
|
+
return { scope, after: children.slice(at), before: children.slice(0, at).reverse() };
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
function applyBoundary(range, method, root, boundary) {
|
|
324
|
+
const { container, childCount } = boundary;
|
|
325
|
+
if (container && root.contains(container)) {
|
|
326
|
+
if (childCount === undefined || childCount === container.childNodes.length) {
|
|
327
|
+
range[method](container, Math.min(boundary.offset, nodeLength(container)));
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const after = boundary.after?.find(node => root.contains(node));
|
|
333
|
+
if (after) {
|
|
334
|
+
range[method](caretEdge(after, true), 0);
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const before = boundary.before?.find(node => root.contains(node));
|
|
339
|
+
if (before) {
|
|
340
|
+
const edge = caretEdge(before, false);
|
|
341
|
+
range[method](edge, nodeLength(edge));
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
const scope = boundary.scope && root.contains(boundary.scope) ? boundary.scope : root;
|
|
346
|
+
range[method](scope, 0);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
function isDroppedWhitespace(node) {
|
|
350
|
+
return (
|
|
351
|
+
node.nodeType === TEXT_NODE &&
|
|
352
|
+
!NOT_WHITESPACE.test(node.nodeValue) &&
|
|
353
|
+
Boolean(node.parentNode) &&
|
|
354
|
+
node.parentNode.nodeType === ELEMENT_NODE &&
|
|
355
|
+
isBlockContainer(node.parentNode) &&
|
|
356
|
+
!preservesWhitespace(node.parentNode)
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
export const isCaretHost = node =>
|
|
361
|
+
node.nodeType === ELEMENT_NODE || node.nodeType === TEXT_NODE;
|
|
362
|
+
|
|
363
|
+
// Descends to the node a caret should actually live in: the first or last text
|
|
364
|
+
// node, or the element itself when its edge child is a void like the placeholder
|
|
365
|
+
// <br>. Comments are skipped rather than entered, and a foreign root such as
|
|
366
|
+
// <svg> is atomic: a caret does not belong inside either one.
|
|
367
|
+
export function caretEdge(node, first = true) {
|
|
368
|
+
let current = node;
|
|
369
|
+
while (current.nodeType === ELEMENT_NODE && !FOREIGN_INLINE_ROOTS.has(current.nodeName)) {
|
|
370
|
+
const children = Array.from(current.childNodes).filter(isCaretHost);
|
|
371
|
+
const next = first ? children[0] : children[children.length - 1];
|
|
372
|
+
if (!next || LEAF_NODE_NAMES.has(next.nodeName)) break;
|
|
373
|
+
current = next;
|
|
374
|
+
}
|
|
375
|
+
return current;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
export function nodeLength(node) {
|
|
379
|
+
return node.nodeType === TEXT_NODE ? node.nodeValue.length : node.childNodes.length;
|
|
380
|
+
}
|