@bettercms-ai/kit 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -0
- package/dist/adapters/dock-values.d.ts +28 -0
- package/dist/adapters/dock-values.js +41 -0
- package/dist/adapters/dock-values.js.map +1 -0
- package/{adapters → dist/adapters}/icons.js +2 -2
- package/dist/adapters/icons.js.map +1 -0
- package/{adapters → dist/adapters}/lossy.d.ts +90 -31
- package/dist/adapters/lossy.js +414 -0
- package/dist/adapters/lossy.js.map +1 -0
- package/{adapters → dist/adapters}/prod-types.d.ts +82 -4
- package/{adapters → dist/adapters}/prod-types.js +71 -3
- package/dist/adapters/prod-types.js.map +1 -0
- package/{adapters → dist/adapters}/schema.d.ts +40 -1
- package/{adapters → dist/adapters}/schema.js +996 -179
- package/dist/adapters/schema.js.map +1 -0
- package/{adapters → dist/adapters}/values.d.ts +26 -5
- package/{adapters → dist/adapters}/values.js +87 -17
- package/dist/adapters/values.js.map +1 -0
- package/dist/brand/logo.js +96 -0
- package/dist/brand/logo.js.map +1 -0
- package/{context.d.ts → dist/context.d.ts} +92 -2
- package/{context.js → dist/context.js} +5 -2
- package/dist/context.js.map +1 -0
- package/{controls → dist/controls}/button.d.ts +19 -5
- package/{controls → dist/controls}/button.js +125 -54
- package/dist/controls/button.js.map +1 -0
- package/{controls → dist/controls}/c1.js +1 -1
- package/dist/controls/c1.js.map +1 -0
- package/{controls → dist/controls}/c2.js +1 -1
- package/dist/controls/c2.js.map +1 -0
- package/{controls → dist/controls}/choice.d.ts +7 -2
- package/{controls → dist/controls}/choice.js +71 -18
- package/dist/controls/choice.js.map +1 -0
- package/{controls → dist/controls}/code-register.js +1 -1
- package/dist/controls/code-register.js.map +1 -0
- package/{controls → dist/controls}/code.js +10 -9
- package/dist/controls/code.js.map +1 -0
- package/{controls → dist/controls}/color.js +8 -8
- package/dist/controls/color.js.map +1 -0
- package/{controls → dist/controls}/component-services.d.ts +42 -0
- package/dist/controls/component-services.js +7 -0
- package/dist/controls/component-services.js.map +1 -0
- package/{controls → dist/controls}/date-register.js +1 -1
- package/dist/controls/date-register.js.map +1 -0
- package/{controls → dist/controls}/date-zone.js +8 -2
- package/dist/controls/date-zone.js.map +1 -0
- package/{controls → dist/controls}/date.js +32 -24
- package/dist/controls/date.js.map +1 -0
- package/{controls → dist/controls}/form-picker-register.js +1 -1
- package/dist/controls/form-picker-register.js.map +1 -0
- package/{controls → dist/controls}/form-picker.js +11 -9
- package/dist/controls/form-picker.js.map +1 -0
- package/{controls → dist/controls}/icon-register.js +1 -1
- package/dist/controls/icon-register.js.map +1 -0
- package/{controls → dist/controls}/icon.d.ts +4 -2
- package/{controls → dist/controls}/icon.js +32 -27
- package/dist/controls/icon.js.map +1 -0
- package/{controls → dist/controls}/index.d.ts +1 -1
- package/{controls → dist/controls}/index.js +4 -3
- package/dist/controls/index.js.map +1 -0
- package/{controls → dist/controls}/json-register.js +1 -1
- package/dist/controls/json-register.js.map +1 -0
- package/{controls → dist/controls}/json.js +13 -3
- package/dist/controls/json.js.map +1 -0
- package/{controls → dist/controls}/link.js +6 -6
- package/dist/controls/link.js.map +1 -0
- package/{controls → dist/controls}/location-register.js +1 -1
- package/dist/controls/location-register.js.map +1 -0
- package/{controls → dist/controls}/location.js +64 -40
- package/dist/controls/location.js.map +1 -0
- package/{controls → dist/controls}/media-register.js +1 -1
- package/dist/controls/media-register.js.map +1 -0
- package/{controls → dist/controls}/media-services.d.ts +6 -0
- package/dist/controls/media-services.js +0 -0
- package/{controls → dist/controls}/media.d.ts +35 -4
- package/{controls → dist/controls}/media.js +491 -171
- package/dist/controls/media.js.map +1 -0
- package/{controls → dist/controls}/number.js +10 -9
- package/dist/controls/number.js.map +1 -0
- package/{controls → dist/controls}/reference-register.js +1 -1
- package/dist/controls/reference-register.js.map +1 -0
- package/{controls → dist/controls}/reference-services.d.ts +4 -0
- package/dist/controls/reference-services.js +0 -0
- package/{controls → dist/controls}/reference.d.ts +1 -1
- package/{controls → dist/controls}/reference.js +93 -77
- package/dist/controls/reference.js.map +1 -0
- package/dist/controls/rich-text/blocks.d.ts +49 -0
- package/{controls → dist/controls}/rich-text/blocks.js +471 -144
- package/dist/controls/rich-text/blocks.js.map +1 -0
- package/{controls → dist/controls}/rich-text/catalog.d.ts +4 -1
- package/{controls → dist/controls}/rich-text/catalog.js +75 -65
- package/dist/controls/rich-text/catalog.js.map +1 -0
- package/{controls → dist/controls}/rich-text/codec.d.ts +9 -1
- package/{controls → dist/controls}/rich-text/codec.js +3 -1
- package/dist/controls/rich-text/codec.js.map +1 -0
- package/{controls → dist/controls}/rich-text/component-card.d.ts +1 -1
- package/{controls → dist/controls}/rich-text/component-card.js +417 -99
- package/dist/controls/rich-text/component-card.js.map +1 -0
- package/dist/controls/rich-text/component-panel.d.ts +47 -0
- package/dist/controls/rich-text/component-panel.js +141 -0
- package/dist/controls/rich-text/component-panel.js.map +1 -0
- package/{controls → dist/controls}/rich-text/control.d.ts +1 -2
- package/{controls → dist/controls}/rich-text/control.js +84 -42
- package/dist/controls/rich-text/control.js.map +1 -0
- package/{controls → dist/controls}/rich-text/dom.d.ts +52 -9
- package/{controls → dist/controls}/rich-text/dom.js +379 -50
- package/dist/controls/rich-text/dom.js.map +1 -0
- package/{controls → dist/controls}/rich-text/editor.d.ts +7 -0
- package/{controls → dist/controls}/rich-text/editor.js +148 -48
- package/dist/controls/rich-text/editor.js.map +1 -0
- package/{controls → dist/controls}/rich-text/floating.d.ts +6 -1
- package/{controls → dist/controls}/rich-text/floating.js +35 -18
- package/dist/controls/rich-text/floating.js.map +1 -0
- package/{controls → dist/controls}/rich-text/index.js +1 -1
- package/dist/controls/rich-text/index.js.map +1 -0
- package/dist/controls/rich-text/link-form.js +147 -0
- package/dist/controls/rich-text/link-form.js.map +1 -0
- package/{controls → dist/controls}/rich-text/markdown.js +4 -2
- package/dist/controls/rich-text/markdown.js.map +1 -0
- package/{controls → dist/controls}/rich-text/ops.js +17 -15
- package/dist/controls/rich-text/ops.js.map +1 -0
- package/dist/controls/rich-text/plain.d.ts +17 -0
- package/dist/controls/rich-text/plain.js +44 -0
- package/dist/controls/rich-text/plain.js.map +1 -0
- package/{controls → dist/controls}/rich-text/toolbar.d.ts +6 -2
- package/{controls → dist/controls}/rich-text/toolbar.js +12 -7
- package/dist/controls/rich-text/toolbar.js.map +1 -0
- package/{controls → dist/controls}/scale.js +5 -5
- package/dist/controls/scale.js.map +1 -0
- package/{controls → dist/controls}/slot-register.js +1 -1
- package/dist/controls/slot-register.js.map +1 -0
- package/{controls → dist/controls}/slot-services.d.ts +25 -0
- package/dist/controls/slot-services.js +155 -0
- package/dist/controls/slot-services.js.map +1 -0
- package/{controls → dist/controls}/slot.js +42 -24
- package/dist/controls/slot.js.map +1 -0
- package/{controls → dist/controls}/table/index.js +1 -1
- package/dist/controls/table/index.js.map +1 -0
- package/{controls → dist/controls}/table/prod.js +3 -3
- package/dist/controls/table/prod.js.map +1 -0
- package/{controls → dist/controls}/table/refs.js +13 -2
- package/dist/controls/table/refs.js.map +1 -0
- package/{controls → dist/controls}/table/stored.js +1 -1
- package/dist/controls/table/stored.js.map +1 -0
- package/{controls → dist/controls}/table/table-editor.js +51 -48
- package/dist/controls/table/table-editor.js.map +1 -0
- package/{controls → dist/controls}/table/table-link.js +3 -3
- package/dist/controls/table/table-link.js.map +1 -0
- package/{controls → dist/controls}/table/table.js +3 -3
- package/dist/controls/table/table.js.map +1 -0
- package/{controls → dist/controls}/text.d.ts +2 -2
- package/{controls → dist/controls}/text.js +78 -43
- package/dist/controls/text.js.map +1 -0
- package/dist/controls/unknown-value.d.ts +17 -0
- package/dist/controls/unknown-value.js +66 -0
- package/dist/controls/unknown-value.js.map +1 -0
- package/dist/core/core.d.ts +63 -0
- package/dist/core/core.js +171 -0
- package/dist/core/core.js.map +1 -0
- package/dist/core/facets.d.ts +347 -0
- package/dist/core/facets.js +334 -0
- package/dist/core/facets.js.map +1 -0
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.js +3 -0
- package/{engine → dist/engine}/array.js +34 -21
- package/dist/engine/array.js.map +1 -0
- package/{engine → dist/engine}/bits.js +1 -1
- package/dist/engine/bits.js.map +1 -0
- package/{engine → dist/engine}/breadcrumb.d.ts +3 -3
- package/{engine → dist/engine}/breadcrumb.js +12 -36
- package/dist/engine/breadcrumb.js.map +1 -0
- package/{engine → dist/engine}/expand.d.ts +2 -4
- package/{engine → dist/engine}/expand.js +5 -22
- package/dist/engine/expand.js.map +1 -0
- package/{engine → dist/engine}/field-list.js +1 -1
- package/dist/engine/field-list.js.map +1 -0
- package/{engine → dist/engine}/field-shell.js +249 -121
- package/dist/engine/field-shell.js.map +1 -0
- package/{engine → dist/engine}/frame.d.ts +3 -1
- package/{engine → dist/engine}/frame.js +16 -14
- package/dist/engine/frame.js.map +1 -0
- package/{engine → dist/engine}/group-summary.d.ts +2 -1
- package/{engine → dist/engine}/group-summary.js +7 -3
- package/dist/engine/group-summary.js.map +1 -0
- package/{engine → dist/engine}/grouping.d.ts +19 -5
- package/{engine → dist/engine}/grouping.js +193 -21
- package/dist/engine/grouping.js.map +1 -0
- package/{engine → dist/engine}/item-list.d.ts +11 -1
- package/{engine → dist/engine}/item-list.js +35 -13
- package/dist/engine/item-list.js.map +1 -0
- package/{engine → dist/engine}/kit-field.js +45 -10
- package/dist/engine/kit-field.js.map +1 -0
- package/{engine → dist/engine}/schema-form.d.ts +27 -2
- package/{engine → dist/engine}/schema-form.js +182 -40
- package/dist/engine/schema-form.js.map +1 -0
- package/{engine → dist/engine}/slot.js +5 -15
- package/dist/engine/slot.js.map +1 -0
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -0
- package/{kit.css → dist/kit.css} +19 -0
- package/{lib → dist/lib}/cn.js +7 -4
- package/dist/lib/cn.js.map +1 -0
- package/{lib → dist/lib}/columns.js +4 -1
- package/dist/lib/columns.js.map +1 -0
- package/{lib → dist/lib}/frames.js +2 -2
- package/dist/lib/frames.js.map +1 -0
- package/dist/lib/icon-image.d.ts +10 -0
- package/dist/lib/icon-image.js +8 -0
- package/dist/lib/icon-image.js.map +1 -0
- package/{lib → dist/lib}/icons.js +4 -3
- package/dist/lib/icons.js.map +1 -0
- package/dist/lib/input-modality.d.ts +11 -0
- package/dist/lib/input-modality.js +47 -0
- package/dist/lib/input-modality.js.map +1 -0
- package/dist/lib/key-event.d.ts +11 -0
- package/dist/lib/key-event.js +16 -0
- package/dist/lib/key-event.js.map +1 -0
- package/{lib → dist/lib}/path.js +4 -2
- package/dist/lib/path.js.map +1 -0
- package/{lib → dist/lib}/schema.d.ts +34 -3
- package/{lib → dist/lib}/schema.js +110 -13
- package/dist/lib/schema.js.map +1 -0
- package/{lib → dist/lib}/utils.js +1 -1
- package/dist/lib/utils.js.map +1 -0
- package/{lib → dist/lib}/validate.d.ts +11 -1
- package/{lib → dist/lib}/validate.js +85 -11
- package/dist/lib/validate.js.map +1 -0
- package/dist/library/analysis.d.ts +23 -0
- package/dist/library/analysis.js +160 -0
- package/dist/library/analysis.js.map +1 -0
- package/dist/library/catalog.d.ts +57 -0
- package/dist/library/catalog.js +307 -0
- package/dist/library/catalog.js.map +1 -0
- package/dist/library/coreNotes.d.ts +8 -0
- package/dist/library/coreNotes.js +111 -0
- package/dist/library/coreNotes.js.map +1 -0
- package/dist/library/coverage.d.ts +40 -0
- package/dist/library/coverage.js +59 -0
- package/dist/library/coverage.js.map +1 -0
- package/dist/library/entries/advanced.entries.d.ts +2 -0
- package/dist/library/entries/advanced.entries.js +6579 -0
- package/dist/library/entries/advanced.entries.js.map +1 -0
- package/dist/library/entries/commerce.entries.d.ts +2 -0
- package/dist/library/entries/commerce.entries.js +4140 -0
- package/dist/library/entries/commerce.entries.js.map +1 -0
- package/dist/library/entries/company.entries.d.ts +2 -0
- package/dist/library/entries/company.entries.js +2731 -0
- package/dist/library/entries/company.entries.js.map +1 -0
- package/dist/library/entries/conversion.entries.d.ts +2 -0
- package/dist/library/entries/conversion.entries.js +3707 -0
- package/dist/library/entries/conversion.entries.js.map +1 -0
- package/dist/library/entries/data.entries.d.ts +7 -0
- package/dist/library/entries/data.entries.js +4613 -0
- package/dist/library/entries/data.entries.js.map +1 -0
- package/dist/library/entries/events.entries.d.ts +2 -0
- package/dist/library/entries/events.entries.js +3428 -0
- package/dist/library/entries/events.entries.js.map +1 -0
- package/dist/library/entries/features.entries.d.ts +2 -0
- package/dist/library/entries/features.entries.js +3157 -0
- package/dist/library/entries/features.entries.js.map +1 -0
- package/dist/library/entries/heroes.entries.d.ts +2 -0
- package/dist/library/entries/heroes.entries.js +3401 -0
- package/dist/library/entries/heroes.entries.js.map +1 -0
- package/dist/library/entries/index.d.ts +3 -0
- package/dist/library/entries/index.js +35 -0
- package/dist/library/entries/index.js.map +1 -0
- package/dist/library/entries/listings.entries.d.ts +2 -0
- package/dist/library/entries/listings.entries.js +2976 -0
- package/dist/library/entries/listings.entries.js.map +1 -0
- package/dist/library/entries/longform.entries.d.ts +2 -0
- package/dist/library/entries/longform.entries.js +4227 -0
- package/dist/library/entries/longform.entries.js.map +1 -0
- package/dist/library/entries/media.entries.d.ts +2 -0
- package/dist/library/entries/media.entries.js +2781 -0
- package/dist/library/entries/media.entries.js.map +1 -0
- package/dist/library/entries/navigation.entries.d.ts +2 -0
- package/dist/library/entries/navigation.entries.js +4011 -0
- package/dist/library/entries/navigation.entries.js.map +1 -0
- package/dist/library/entries/pricing.entries.d.ts +2 -0
- package/dist/library/entries/pricing.entries.js +2383 -0
- package/dist/library/entries/pricing.entries.js.map +1 -0
- package/dist/library/entries/social-proof.entries.d.ts +2 -0
- package/dist/library/entries/social-proof.entries.js +2297 -0
- package/dist/library/entries/social-proof.entries.js.map +1 -0
- package/dist/library/examples/bento.d.ts +92 -0
- package/dist/library/examples/bento.js +201 -0
- package/dist/library/examples/bento.js.map +1 -0
- package/dist/library/examples/blocks.d.ts +14 -0
- package/dist/library/examples/blocks.js +313 -0
- package/dist/library/examples/blocks.js.map +1 -0
- package/dist/library/examples/faq.d.ts +28 -0
- package/dist/library/examples/faq.js +230 -0
- package/dist/library/examples/faq.js.map +1 -0
- package/dist/library/examples/hero.d.ts +43 -0
- package/dist/library/examples/hero.js +222 -0
- package/dist/library/examples/hero.js.map +1 -0
- package/dist/library/examples/index.d.ts +36 -0
- package/dist/library/examples/index.js +109 -0
- package/dist/library/examples/index.js.map +1 -0
- package/dist/library/examples/journalStory.d.ts +93 -0
- package/dist/library/examples/journalStory.js +338 -0
- package/dist/library/examples/journalStory.js.map +1 -0
- package/dist/library/examples/megaMenu.d.ts +134 -0
- package/dist/library/examples/megaMenu.js +442 -0
- package/dist/library/examples/megaMenu.js.map +1 -0
- package/dist/library/examples/pricing.d.ts +103 -0
- package/dist/library/examples/pricing.js +479 -0
- package/dist/library/examples/pricing.js.map +1 -0
- package/dist/library/examples/tabs.d.ts +87 -0
- package/dist/library/examples/tabs.js +180 -0
- package/dist/library/examples/tabs.js.map +1 -0
- package/dist/library/export.d.ts +42 -0
- package/dist/library/export.js +80 -0
- package/dist/library/export.js.map +1 -0
- package/dist/library/index.d.ts +13 -0
- package/dist/library/index.js +6 -0
- package/dist/library/kit-catalog.json +1510 -0
- package/dist/library/types.d.ts +42 -0
- package/dist/library/types.js +0 -0
- package/{schema → dist/schema}/adapters.js +1 -2
- package/dist/schema/adapters.js.map +1 -0
- package/{schema → dist/schema}/help.d.ts +2 -0
- package/{schema → dist/schema}/help.js +6 -4
- package/dist/schema/help.js.map +1 -0
- package/{schema → dist/schema}/scale.js +1 -1
- package/dist/schema/scale.js.map +1 -0
- package/{schema → dist/schema}/sources.js +1 -1
- package/dist/schema/sources.js.map +1 -0
- package/{schema → dist/schema}/table.js +11 -10
- package/dist/schema/table.js.map +1 -0
- package/{schema → dist/schema}/types.d.ts +29 -1
- package/{schema → dist/schema}/types.js +1 -1
- package/dist/schema/types.js.map +1 -0
- package/dist/styles.css +2 -0
- package/dist/table/table-view.d.ts +14 -0
- package/dist/table/table-view.js +140 -0
- package/dist/table/table-view.js.map +1 -0
- package/dist/table/table.css +73 -0
- package/dist/testing/corpus.d.ts +63 -0
- package/dist/testing/corpus.js +129 -0
- package/dist/testing/corpus.js.map +1 -0
- package/dist/testing/test-form.d.ts +11 -0
- package/dist/testing/test-form.js +38 -0
- package/dist/testing/test-form.js.map +1 -0
- package/dist/theme.css +345 -0
- package/dist/theme.d.ts +22 -0
- package/dist/theme.js +43 -0
- package/dist/theme.js.map +1 -0
- package/dist/tokens.css +542 -0
- package/dist/types.js +0 -0
- package/{ui → dist/ui}/action-tray.d.ts +1 -1
- package/{ui → dist/ui}/action-tray.js +20 -19
- package/dist/ui/action-tray.js.map +1 -0
- package/dist/ui/autocomplete.d.ts +30 -0
- package/dist/ui/autocomplete.js +139 -0
- package/dist/ui/autocomplete.js.map +1 -0
- package/{ui → dist/ui}/button.d.ts +3 -3
- package/{ui → dist/ui}/button.js +6 -7
- package/dist/ui/button.js.map +1 -0
- package/{ui → dist/ui}/choice-switch.js +1 -1
- package/dist/ui/choice-switch.js.map +1 -0
- package/{ui → dist/ui}/controls.js +51 -39
- package/dist/ui/controls.js.map +1 -0
- package/{ui → dist/ui}/display.d.ts +10 -3
- package/{ui → dist/ui}/display.js +57 -46
- package/dist/ui/display.js.map +1 -0
- package/{ui → dist/ui}/expanded-editor-modal.d.ts +2 -2
- package/{ui → dist/ui}/expanded-editor-modal.js +6 -6
- package/dist/ui/expanded-editor-modal.js.map +1 -0
- package/{ui → dist/ui}/field-context.js +1 -1
- package/dist/ui/field-context.js.map +1 -0
- package/{ui → dist/ui}/floating-panel.d.ts +1 -1
- package/{ui → dist/ui}/floating-panel.js +28 -12
- package/dist/ui/floating-panel.js.map +1 -0
- package/{ui → dist/ui}/index.d.ts +4 -0
- package/dist/ui/index.js +18 -0
- package/{ui → dist/ui}/input.d.ts +1 -1
- package/{ui → dist/ui}/input.js +9 -9
- package/dist/ui/input.js.map +1 -0
- package/{ui → dist/ui}/mode-bar.js +3 -3
- package/dist/ui/mode-bar.js.map +1 -0
- package/{ui → dist/ui}/overlay.d.ts +77 -5
- package/dist/ui/overlay.js +697 -0
- package/dist/ui/overlay.js.map +1 -0
- package/{ui → dist/ui}/path-crumbs.js +37 -3
- package/dist/ui/path-crumbs.js.map +1 -0
- package/{ui → dist/ui}/presence.js +2 -2
- package/dist/ui/presence.js.map +1 -0
- package/{ui → dist/ui}/select.js +89 -87
- package/dist/ui/select.js.map +1 -0
- package/{ui → dist/ui}/shortcut-hint.js +1 -1
- package/dist/ui/shortcut-hint.js.map +1 -0
- package/dist/ui/spinner.d.ts +24 -0
- package/dist/ui/spinner.js +42 -0
- package/dist/ui/spinner.js.map +1 -0
- package/dist/ui/split-button.d.ts +32 -0
- package/dist/ui/split-button.js +60 -0
- package/dist/ui/split-button.js.map +1 -0
- package/{ui → dist/ui}/surfaces.js +1 -1
- package/dist/ui/surfaces.js.map +1 -0
- package/dist/ui/tab.d.ts +38 -0
- package/dist/ui/tab.js +87 -0
- package/dist/ui/tab.js.map +1 -0
- package/dist/ui/toast.d.ts +20 -0
- package/dist/ui/toast.js +115 -0
- package/dist/ui/toast.js.map +1 -0
- package/{ui → dist/ui}/tooltip-root.d.ts +4 -3
- package/{ui → dist/ui}/tooltip-root.js +9 -8
- package/dist/ui/tooltip-root.js.map +1 -0
- package/{ui → dist/ui}/variants.js +1 -1
- package/dist/ui/variants.js.map +1 -0
- package/package.json +77 -23
- package/adapters/icons.js.map +0 -1
- package/adapters/lossy.js +0 -233
- package/adapters/lossy.js.map +0 -1
- package/adapters/prod-types.js.map +0 -1
- package/adapters/schema.js.map +0 -1
- package/adapters/values.js.map +0 -1
- package/brand/logo.js +0 -9
- package/brand/logo.js.map +0 -1
- package/context.js.map +0 -1
- package/controls/button.js.map +0 -1
- package/controls/c1.js.map +0 -1
- package/controls/c2.js.map +0 -1
- package/controls/choice.js.map +0 -1
- package/controls/code-register.js.map +0 -1
- package/controls/code.js.map +0 -1
- package/controls/color.js.map +0 -1
- package/controls/date-register.js.map +0 -1
- package/controls/date-zone.js.map +0 -1
- package/controls/date.js.map +0 -1
- package/controls/form-picker-register.js.map +0 -1
- package/controls/form-picker.js.map +0 -1
- package/controls/icon-register.js.map +0 -1
- package/controls/icon.js.map +0 -1
- package/controls/index.js.map +0 -1
- package/controls/json-register.js.map +0 -1
- package/controls/json.js.map +0 -1
- package/controls/link.js.map +0 -1
- package/controls/location-register.js.map +0 -1
- package/controls/location.js.map +0 -1
- package/controls/media-register.js.map +0 -1
- package/controls/media.js.map +0 -1
- package/controls/number.js.map +0 -1
- package/controls/reference-register.js.map +0 -1
- package/controls/reference.js.map +0 -1
- package/controls/rich-text/blocks.d.ts +0 -28
- package/controls/rich-text/blocks.js.map +0 -1
- package/controls/rich-text/catalog.js.map +0 -1
- package/controls/rich-text/codec.js.map +0 -1
- package/controls/rich-text/component-card.js.map +0 -1
- package/controls/rich-text/control.js.map +0 -1
- package/controls/rich-text/dom.js.map +0 -1
- package/controls/rich-text/editor.js.map +0 -1
- package/controls/rich-text/floating.js.map +0 -1
- package/controls/rich-text/index.js.map +0 -1
- package/controls/rich-text/link-form.js +0 -111
- package/controls/rich-text/link-form.js.map +0 -1
- package/controls/rich-text/markdown.js.map +0 -1
- package/controls/rich-text/ops.js.map +0 -1
- package/controls/rich-text/toolbar.js.map +0 -1
- package/controls/scale.js.map +0 -1
- package/controls/slot-register.js.map +0 -1
- package/controls/slot-services.js +0 -38
- package/controls/slot-services.js.map +0 -1
- package/controls/slot.js.map +0 -1
- package/controls/table/index.js.map +0 -1
- package/controls/table/prod.js.map +0 -1
- package/controls/table/refs.js.map +0 -1
- package/controls/table/stored.js.map +0 -1
- package/controls/table/table-editor.js.map +0 -1
- package/controls/table/table-link.js.map +0 -1
- package/controls/table/table.js.map +0 -1
- package/controls/text.js.map +0 -1
- package/engine/array.js.map +0 -1
- package/engine/bits.js.map +0 -1
- package/engine/breadcrumb.js.map +0 -1
- package/engine/expand.js.map +0 -1
- package/engine/field-list.js.map +0 -1
- package/engine/field-shell.js.map +0 -1
- package/engine/frame.js.map +0 -1
- package/engine/group-summary.js.map +0 -1
- package/engine/grouping.js.map +0 -1
- package/engine/item-list.js.map +0 -1
- package/engine/kit-field.js.map +0 -1
- package/engine/schema-form.js.map +0 -1
- package/engine/slot.js.map +0 -1
- package/index.js +0 -55
- package/index.js.map +0 -1
- package/lib/cn.js.map +0 -1
- package/lib/columns.js.map +0 -1
- package/lib/frames.js.map +0 -1
- package/lib/icons.js.map +0 -1
- package/lib/path.js.map +0 -1
- package/lib/schema.js.map +0 -1
- package/lib/utils.js.map +0 -1
- package/lib/validate.js.map +0 -1
- package/schema/adapters.js.map +0 -1
- package/schema/help.js.map +0 -1
- package/schema/scale.js.map +0 -1
- package/schema/sources.js.map +0 -1
- package/schema/table.js.map +0 -1
- package/schema/types.js.map +0 -1
- package/ui/action-tray.js.map +0 -1
- package/ui/button.js.map +0 -1
- package/ui/choice-switch.js.map +0 -1
- package/ui/controls.js.map +0 -1
- package/ui/display.js.map +0 -1
- package/ui/expanded-editor-modal.js.map +0 -1
- package/ui/field-context.js.map +0 -1
- package/ui/floating-panel.js.map +0 -1
- package/ui/index.js +0 -13
- package/ui/input.js.map +0 -1
- package/ui/mode-bar.js.map +0 -1
- package/ui/overlay.js +0 -378
- package/ui/overlay.js.map +0 -1
- package/ui/path-crumbs.js.map +0 -1
- package/ui/presence.js.map +0 -1
- package/ui/select.js.map +0 -1
- package/ui/shortcut-hint.js.map +0 -1
- package/ui/surfaces.js.map +0 -1
- package/ui/tooltip-root.js.map +0 -1
- package/ui/variants.js.map +0 -1
- /package/{_virtual → dist/_virtual}/_rolldown/runtime.js +0 -0
- /package/{adapters → dist/adapters}/icons.d.ts +0 -0
- /package/{brand → dist/brand}/logo.d.ts +0 -0
- /package/{controls → dist/controls}/c1.d.ts +0 -0
- /package/{controls → dist/controls}/c2.d.ts +0 -0
- /package/{controls → dist/controls}/code-register.d.ts +0 -0
- /package/{controls → dist/controls}/code.d.ts +0 -0
- /package/{controls → dist/controls}/color.d.ts +0 -0
- /package/{controls → dist/controls}/date-register.d.ts +0 -0
- /package/{controls → dist/controls}/date-zone.d.ts +0 -0
- /package/{controls → dist/controls}/date.d.ts +0 -0
- /package/{controls → dist/controls}/form-picker-register.d.ts +0 -0
- /package/{controls → dist/controls}/form-picker.d.ts +0 -0
- /package/{controls → dist/controls}/icon-register.d.ts +0 -0
- /package/{controls → dist/controls}/json-register.d.ts +0 -0
- /package/{controls → dist/controls}/json.d.ts +0 -0
- /package/{controls → dist/controls}/link.d.ts +0 -0
- /package/{controls → dist/controls}/location-register.d.ts +0 -0
- /package/{controls → dist/controls}/location.d.ts +0 -0
- /package/{controls → dist/controls}/media-register.d.ts +0 -0
- /package/{controls → dist/controls}/number.d.ts +0 -0
- /package/{controls → dist/controls}/reference-register.d.ts +0 -0
- /package/{controls → dist/controls}/rich-text/index.d.ts +0 -0
- /package/{controls → dist/controls}/rich-text/link-form.d.ts +0 -0
- /package/{controls → dist/controls}/rich-text/markdown.d.ts +0 -0
- /package/{controls → dist/controls}/rich-text/ops.d.ts +0 -0
- /package/{controls → dist/controls}/scale.d.ts +0 -0
- /package/{controls → dist/controls}/slot-register.d.ts +0 -0
- /package/{controls → dist/controls}/slot.d.ts +0 -0
- /package/{controls → dist/controls}/table/index.d.ts +0 -0
- /package/{controls → dist/controls}/table/prod.d.ts +0 -0
- /package/{controls → dist/controls}/table/refs.d.ts +0 -0
- /package/{controls → dist/controls}/table/stored.d.ts +0 -0
- /package/{controls → dist/controls}/table/table-editor.d.ts +0 -0
- /package/{controls → dist/controls}/table/table-link.d.ts +0 -0
- /package/{controls → dist/controls}/table/table.d.ts +0 -0
- /package/{engine → dist/engine}/array.d.ts +0 -0
- /package/{engine → dist/engine}/bits.d.ts +0 -0
- /package/{engine → dist/engine}/field-list.d.ts +0 -0
- /package/{engine → dist/engine}/field-shell.d.ts +0 -0
- /package/{engine → dist/engine}/kit-field.d.ts +0 -0
- /package/{engine → dist/engine}/slot.d.ts +0 -0
- /package/{index.d.ts → dist/index.d.ts} +0 -0
- /package/{lib → dist/lib}/cn.d.ts +0 -0
- /package/{lib → dist/lib}/columns.d.ts +0 -0
- /package/{lib → dist/lib}/frames.d.ts +0 -0
- /package/{lib → dist/lib}/icons.d.ts +0 -0
- /package/{lib → dist/lib}/path.d.ts +0 -0
- /package/{lib → dist/lib}/utils.d.ts +0 -0
- /package/{schema → dist/schema}/adapters.d.ts +0 -0
- /package/{schema → dist/schema}/scale.d.ts +0 -0
- /package/{schema → dist/schema}/sources.d.ts +0 -0
- /package/{schema → dist/schema}/table.d.ts +0 -0
- /package/{types.d.ts → dist/types.d.ts} +0 -0
- /package/{ui → dist/ui}/choice-switch.d.ts +0 -0
- /package/{ui → dist/ui}/controls.d.ts +0 -0
- /package/{ui → dist/ui}/field-context.d.ts +0 -0
- /package/{ui → dist/ui}/mode-bar.d.ts +0 -0
- /package/{ui → dist/ui}/path-crumbs.d.ts +0 -0
- /package/{ui → dist/ui}/presence.d.ts +0 -0
- /package/{ui → dist/ui}/select.d.ts +0 -0
- /package/{ui → dist/ui}/shortcut-hint.d.ts +0 -0
- /package/{ui → dist/ui}/surfaces.d.ts +0 -0
- /package/{ui → dist/ui}/variants.d.ts +0 -0
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { type IslandEl, type IslandKind, type IslandModels } from "./dom";
|
|
2
|
-
export interface IslandCtx {
|
|
3
|
-
readOnly?: boolean;
|
|
4
|
-
dense?: boolean;
|
|
5
|
-
emit: () => void;
|
|
6
|
-
remove: (el: IslandEl) => void;
|
|
7
|
-
/** Leave the block: caret to the start of the next line. */
|
|
8
|
-
exit: (el: IslandEl) => void;
|
|
9
|
-
/** CPO D54: an island write joins the body field's ONE undo history (`before` = the model it replaces) */
|
|
10
|
-
record?: (el: IslandEl, before: IslandModels[IslandKind], label: string, coalesce?: boolean) => void;
|
|
11
|
-
/** a refusal the author must see (an address the image cannot use) */
|
|
12
|
-
notify: (message: string, description?: string) => void;
|
|
13
|
-
duplicate?: (el: IslandEl) => void;
|
|
14
|
-
move?: (el: IslandEl, dir: -1 | 1) => void;
|
|
15
|
-
/** the body field's one history (D54): ⌘Z on a focused block or in its panel */
|
|
16
|
-
undo?: () => boolean;
|
|
17
|
-
/**
|
|
18
|
-
* One action as ONE undo step, in the host's history when it keeps one (the dock's toolbar Undo), else the body's
|
|
19
|
-
* own. `write` makes the change and answers the island it changed; `before` is that island's model before it. Answers
|
|
20
|
-
* the step's undo (an Undo toast): true, or the sentence saying why nothing was undone.
|
|
21
|
-
*/
|
|
22
|
-
step?: (label: string, write: () => IslandEl | null, before?: IslandModels[IslandKind]) => () => true | string;
|
|
23
|
-
redo?: () => boolean;
|
|
24
|
-
}
|
|
25
|
-
export declare function Island({ el, ctx }: {
|
|
26
|
-
el: IslandEl;
|
|
27
|
-
ctx: IslandCtx;
|
|
28
|
-
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"blocks.js","names":[],"sources":["../../../src/kit/controls/rich-text/blocks.tsx"],"sourcesContent":["/**\n * RICH TEXT · rich blocks (\"islands\", V2 HEAD controls/rich-text/blocks.tsx). Each renders through a portal into a\n * contenteditable=false element inside the editor surface; its model lives on that element (`el.__rt`) so serialize()\n * can write it back as static HTML.\n *\n * The image block is V2's: the toolbar (Replace · Align · Size S/M/L/Full · Link · Alt text · Remove) and the caption\n * under it, each stored on production's image block (see dom.ts). The callout (tone · title · message), toggle, video,\n * file and embedded component blocks are V2's too, limited to what their stored blocks keep: a callout's message and a\n * toggle's body are plain text (production stores them as text), a component is a linked card (its fields are edited\n * on the component itself).\n *\n * The table block is V2's TableBlock: the kit's table editor on the island's table value. The pull quote is V2's article\n * block (article-blocks.tsx ArticleBlock + PullQuotePreview): drawn as the reader sees it, edited in the floating\n * properties panel (4 settings → panel, CPO D54) through the kit SchemaForm. Key takeaways are V2's article block too,\n * written in the text itself (article-blocks.tsx TakeawaysEditor, surface \"inline\"): a title line and a line per point.\n */\nimport * as React from \"react\";\nimport {\n IconAlertTriangle, IconAlt, IconArrowsHorizontal, IconArrowsMove, IconBulb, IconCheck, IconChevronDown, IconChevronRight, IconComponents, IconCopy,\n IconDimensions, IconDots, IconFileText, IconInfoCircle, IconLayoutAlignCenter, IconLayoutAlignLeft, IconLayoutAlignRight, IconLayoutSidebar,\n IconLayoutSidebarRight, IconLibraryPhoto, IconLink, IconPhoto, IconQuote, IconReplace, IconSettings, IconTrash, IconVideo, IconWorld, IconX,\n} from \"@tabler/icons-react\";\nimport { cn } from \"../../lib/cn\";\nimport { useKitServices } from \"../../context\";\nimport { Button, IconButton } from \"../../ui/button\";\nimport { Input, Textarea } from \"../../ui/input\";\nimport { Menu, MenuContent, MenuItem, MenuSeparator, MenuTrigger, Popover, PopoverContent, PopoverTrigger, Tooltip } from \"../../ui/overlay\";\nimport { FloatingPanel, type FloatingPanelHandle } from \"../../ui/floating-panel\";\nimport { SchemaForm } from \"../../engine/schema-form\";\nimport type { TypeSchema } from \"../../schema/types\";\nimport type { TableFieldOptions } from \"../../schema/table\";\nimport { TableEditor } from \"../table/table-editor\";\nimport {\n CALLOUT_TONES, placeCaret, type CalloutModel, type CalloutTone, type ComponentModel, type FileModel, type ImageAlign, type ImageModel, type ImageSize,\n type IslandEl, type IslandKind, type IslandModels, type PullQuoteModel, type TableModel, type TakeawaysModel, type ToggleModel, type VideoModel,\n} from \"./dom\";\nimport { LinkForm } from \"./link-form\";\nimport { ComponentCard } from \"./component-card\";\n\nexport interface IslandCtx {\n readOnly?: boolean;\n dense?: boolean;\n emit: () => void;\n remove: (el: IslandEl) => void;\n /** Leave the block: caret to the start of the next line. */\n exit: (el: IslandEl) => void;\n /** CPO D54: an island write joins the body field's ONE undo history (`before` = the model it replaces) */\n record?: (el: IslandEl, before: IslandModels[IslandKind], label: string, coalesce?: boolean) => void;\n /** a refusal the author must see (an address the image cannot use) */\n notify: (message: string, description?: string) => void;\n duplicate?: (el: IslandEl) => void;\n move?: (el: IslandEl, dir: -1 | 1) => void;\n /** the body field's one history (D54): ⌘Z on a focused block or in its panel */\n undo?: () => boolean;\n /**\n * One action as ONE undo step, in the host's history when it keeps one (the dock's toolbar Undo), else the body's\n * own. `write` makes the change and answers the island it changed; `before` is that island's model before it. Answers\n * the step's undo (an Undo toast): true, or the sentence saying why nothing was undone.\n */\n step?: (label: string, write: () => IslandEl | null, before?: IslandModels[IslandKind]) => () => true | string;\n redo?: () => boolean;\n}\n\n/* ── Island host ───────────────────────────────────────────────────── */\n/** `label` names the step in the editor's one undo history (\"Edit alt text\"). */\ntype Setter<K extends IslandKind> = (patch: Partial<IslandModels[K]> | ((m: IslandModels[K]) => IslandModels[K]), label?: string, record?: boolean) => void;\ninterface BlockProps<K extends IslandKind> {\n m: IslandModels[K];\n set: Setter<K>;\n el: IslandEl;\n ctx: IslandCtx;\n autoFocus: boolean;\n}\n\nexport function Island({ el, ctx }: { el: IslandEl; ctx: IslandCtx }) {\n const kind = el.getAttribute(\"data-rt-island\") as IslandKind;\n const [model, setModel] = React.useState(() => el.__rt!);\n const [autoFocus] = React.useState(() => !!el.__rtFocus);\n React.useEffect(() => {\n el.__rtFocus = false;\n }, [el]);\n const set = React.useCallback(\n (patch: unknown, label = \"Edit block\", record = true) => {\n const prev = el.__rt as IslandModels[IslandKind];\n const next = typeof patch === \"function\" ? (patch as (m: object) => object)(prev) : { ...prev, ...(patch as object) };\n // `record` false: the caller records the step itself (IslandCtx.step)\n if (record) ctx.record?.(el, prev, label, typeof patch !== \"function\");\n el.__rt = next as IslandModels[IslandKind];\n setModel(next as IslandModels[IslandKind]);\n ctx.emit();\n },\n [el, ctx],\n );\n React.useEffect(() => {\n el.__rtSet = (m) => {\n el.__rt = m;\n setModel(m);\n ctx.emit();\n };\n return () => {\n if (el.__rtSet) delete el.__rtSet;\n };\n }, [el, ctx]);\n const onKeyDown = (e: React.KeyboardEvent) => {\n if (!e.currentTarget.contains(e.target as Node)) return;\n if (e.key === \"Escape\" && (e.target as HTMLElement).isContentEditable) {\n e.preventDefault();\n e.stopPropagation();\n ctx.exit(el);\n }\n };\n return (\n <div className=\"relative select-text\" onKeyDown={onKeyDown} data-island-kind={kind}>\n {kind === \"image\" ? <ImageBlock el={el} ctx={ctx} autoFocus={autoFocus} m={model as ImageModel} set={set as Setter<\"image\">} />\n : kind === \"table\" ? <TableBlock el={el} ctx={ctx} autoFocus={autoFocus} m={model as TableModel} set={set as Setter<\"table\">} />\n : kind === \"pullquote\" ? <PullQuoteBlock el={el} ctx={ctx} autoFocus={autoFocus} m={model as PullQuoteModel} set={set as Setter<\"pullquote\">} />\n : kind === \"takeaways\" ? <TakeawaysBlock el={el} ctx={ctx} autoFocus={autoFocus} m={model as TakeawaysModel} set={set as Setter<\"takeaways\">} />\n : kind === \"callout\" ? <CalloutBlock el={el} ctx={ctx} autoFocus={autoFocus} m={model as CalloutModel} set={set as Setter<\"callout\">} />\n : kind === \"toggle\" ? <ToggleBlock el={el} ctx={ctx} autoFocus={autoFocus} m={model as ToggleModel} set={set as Setter<\"toggle\">} />\n : kind === \"video\" ? <VideoBlock el={el} ctx={ctx} autoFocus={autoFocus} m={model as VideoModel} set={set as Setter<\"video\">} />\n : kind === \"file\" ? <FileBlock el={el} ctx={ctx} autoFocus={autoFocus} m={model as FileModel} set={set as Setter<\"file\">} />\n : kind === \"component\" ? <ComponentBlock el={el} ctx={ctx} autoFocus={autoFocus} m={model as ComponentModel} set={set as Setter<\"component\">} />\n : null}\n </div>\n );\n}\n\nconst Sep = () => <span aria-hidden className=\"mx-0.5 h-4 w-px shrink-0 bg-kit-line\" />;\n/** An address an image can be shown from: http(s) or a site path. */\nconst imageUrlOk = (u: string) => /^(https?:)?\\/\\/[^\\s]+$/i.test(u) || /^\\/(?!\\/)\\S*$/.test(u);\n\n/* ── plain text inside a block (V2 Editable, `plain`): a caption, a title, a message ── */\nfunction PlainEditable({\n value,\n onChange,\n label,\n placeholder,\n readOnly,\n autoFocus,\n multiline,\n onEnter,\n onBackspaceEmpty,\n className,\n}: {\n value: string;\n onChange: (v: string) => void;\n label: string;\n placeholder?: string;\n readOnly?: boolean;\n autoFocus?: boolean;\n /** Enter adds a line (else Enter calls `onEnter`) */\n multiline?: boolean;\n onEnter?: () => void;\n /** Backspace in an empty line (V2 PlainLine: removes the line) */\n onBackspaceEmpty?: () => void;\n className?: string;\n}) {\n const ref = React.useRef<HTMLDivElement>(null);\n React.useLayoutEffect(() => {\n const el = ref.current;\n if (!el || document.activeElement === el) return;\n if (el.textContent !== value) el.textContent = value;\n }, [value]);\n React.useEffect(() => {\n if (!autoFocus || !ref.current || readOnly) return;\n ref.current.focus({ preventScroll: false });\n placeCaret(ref.current);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n return (\n <div\n ref={ref}\n role=\"textbox\"\n aria-label={label}\n aria-multiline={multiline || undefined}\n aria-readonly={readOnly || undefined}\n tabIndex={readOnly ? -1 : 0}\n contentEditable={readOnly ? false : \"plaintext-only\"}\n suppressContentEditableWarning\n spellCheck\n data-placeholder={placeholder}\n onInput={(e) => onChange((e.currentTarget.textContent ?? \"\").replace(/\\u200b/g, \"\"))}\n onPaste={(e) => {\n e.preventDefault();\n const t = e.clipboardData.getData(\"text/plain\");\n document.execCommand(\"insertText\", false, multiline ? t : t.replace(/\\s*\\n\\s*/g, \" \"));\n }}\n onKeyDown={(e) => {\n if (e.key === \"Backspace\" && onBackspaceEmpty && !(e.currentTarget.textContent ?? \"\").replace(/\\u200b/g, \"\")) {\n e.preventDefault();\n onBackspaceEmpty();\n return;\n }\n if (e.key !== \"Enter\") return;\n // in a multi-line field Enter adds a line; ⌘↵ leaves it\n if (multiline && !(e.metaKey || e.ctrlKey)) return;\n e.preventDefault();\n onEnter?.();\n }}\n className={cn(\n \"min-w-0 cursor-text whitespace-pre-wrap break-words outline-none empty:before:pointer-events-none empty:before:text-kit-fg-4 empty:before:content-[attr(data-placeholder)]\",\n className,\n )}\n />\n );\n}\n\nconst RemoveBtn = ({ onClick, label }: { onClick: () => void; label: string }) => (\n <IconButton size=\"xs\" label={label} onClick={onClick} className=\"hover:text-kit-danger-fg\">\n <IconTrash stroke={1.5} />\n </IconButton>\n);\n\n/* ── Image ─────────────────────────────────────────────────────────── */\n/** Production's image layout (lib/richtext/imageLayout.ts): a size sets the column share; with none, the alignment does. */\nconst SIZES: { v: ImageSize; label: string; w: string }[] = [\n { v: \"s\", label: \"S\", w: \"33%\" },\n { v: \"m\", label: \"M\", w: \"50%\" },\n { v: \"l\", label: \"L\", w: \"75%\" },\n { v: \"full\", label: \"Full\", w: \"100%\" },\n];\nconst ALIGN_WIDTH: Record<ImageAlign, string> = { full: \"100%\", center: \"78%\", left: \"62%\", right: \"62%\" };\nconst ALIGNS: { v: ImageAlign; label: string; icon: React.ReactNode }[] = [\n { v: \"full\", label: \"Full width\", icon: <IconArrowsHorizontal stroke={1.5} /> },\n { v: \"center\", label: \"Center\", icon: <IconLayoutAlignCenter stroke={1.5} /> },\n { v: \"left\", label: \"Left\", icon: <IconLayoutAlignLeft stroke={1.5} /> },\n { v: \"right\", label: \"Right\", icon: <IconLayoutAlignRight stroke={1.5} /> },\n];\n\nfunction ImageBlock({ m, set, el, ctx }: BlockProps<\"image\">) {\n const { MediaPicker } = useKitServices();\n const [picker, setPicker] = React.useState(false);\n const [urlMode, setUrlMode] = React.useState(false);\n const [url, setUrl] = React.useState(\"\");\n const [busy, setBusy] = React.useState(false);\n const [linkOpen, setLinkOpen] = React.useState(false);\n const ro = ctx.readOnly;\n const pickerEl = MediaPicker ? (\n <MediaPicker\n open={picker}\n onOpenChange={setPicker}\n accept={[\"image\", \"svg\"]}\n onPick={(a) => a[0] && set({ src: a[0].url, alt: a[0].alt || m.alt || \"\" }, \"Replace image\")}\n />\n ) : null;\n\n if (!m.src)\n return (\n <div className=\"group/blk rounded-kit-lg border border-dashed border-kit-line-strong bg-kit-subtle px-4 py-4\">\n <div className=\"flex items-start gap-3\">\n <span className=\"flex size-8 shrink-0 items-center justify-center rounded-kit-md border border-kit-line bg-kit-control-bg text-kit-fg-2\">\n <IconPhoto className=\"size-4\" stroke={1.5} aria-hidden />\n </span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-kit-sm font-medium text-kit-fg\">Add an image</div>\n <p className=\"text-kit-xs text-kit-fg-3\">{MediaPicker ? \"Pick one from the media library or paste a link.\" : \"Paste a link to the image.\"}</p>\n </div>\n {ro ? null : (\n <Tooltip content=\"Remove image\">\n <button type=\"button\" aria-label=\"Remove image\" onClick={() => ctx.remove(el)} className=\"flex size-6 items-center justify-center rounded-kit-md text-kit-fg-3 hover:bg-kit-hover hover:text-kit-danger-fg\">\n <IconTrash className=\"size-3.5\" stroke={1.5} aria-hidden />\n </button>\n </Tooltip>\n )}\n </div>\n {ro ? null : urlMode || !MediaPicker ? (\n <form\n className=\"mt-3 flex items-center gap-2\"\n onSubmit={(e) => {\n e.preventDefault();\n const u = url.trim();\n if (!imageUrlOk(u)) return ctx.notify(\"Paste a full image link that starts with https://\", \"Or a path on this site, like /images/hero.jpg.\");\n set({ src: u, alt: m.alt ?? \"\" }, \"Add image\");\n ctx.exit(el);\n }}\n >\n <Input autoFocus size=\"sm\" value={url} onChange={(e) => setUrl(e.target.value)} placeholder=\"https://…\" aria-label=\"Image URL\" leading={<IconLink stroke={1.5} />} className=\"flex-1\" />\n <Button size=\"sm\" variant=\"primary\" type=\"submit\" disabled={!url.trim()}>\n Add\n </Button>\n {MediaPicker ? (\n <Button size=\"sm\" variant=\"ghost\" onClick={() => setUrlMode(false)}>\n Cancel\n </Button>\n ) : null}\n </form>\n ) : (\n <div className=\"mt-3 flex flex-wrap gap-2\">\n <Button size=\"sm\" leftIcon={<IconLibraryPhoto stroke={1.5} />} onClick={() => setPicker(true)}>\n Media library\n </Button>\n <Button size=\"sm\" variant=\"ghost\" leftIcon={<IconLink stroke={1.5} />} onClick={() => setUrlMode(true)}>\n Paste URL\n </Button>\n </div>\n )}\n {pickerEl}\n </div>\n );\n\n const align: ImageAlign = m.align ?? \"full\";\n const size = m.size;\n const width = size ? (SIZES.find((x) => x.v === size)?.w ?? \"100%\") : ALIGN_WIDTH[align];\n const justify = align === \"left\" ? \"justify-start\" : align === \"right\" ? \"justify-end\" : \"justify-center\";\n const alignItem = ALIGNS.find((a) => a.v === align)!;\n const toolBtn =\n \"flex h-7 shrink-0 items-center gap-1 rounded-kit-md px-1.5 text-kit-xs text-kit-fg-2 hover:bg-kit-hover hover:text-kit-fg data-[popup-open]:bg-kit-hover data-[popup-open]:text-kit-fg [&_svg]:size-3.5\";\n return (\n <figure className=\"group/blk relative m-0\">\n {ro ? null : (\n <div\n role=\"toolbar\"\n aria-label=\"Image tools\"\n data-kit-scope=\"\"\n className={cn(\n \"absolute left-1/2 top-2 z-[3] flex h-8 max-w-[calc(100%-16px)] -translate-x-1/2 items-center gap-0.5 overflow-x-auto rounded-kit-lg border border-kit-line bg-kit-surface px-1 opacity-0 shadow-kit-sm transition-opacity duration-150 motion-reduce:transition-none\",\n \"group-hover/blk:opacity-100 group-focus-within/blk:opacity-100 pointer-coarse:opacity-100\",\n busy && \"opacity-100\",\n )}\n >\n {MediaPicker ? (\n <>\n <Tooltip content=\"Replace image\">\n <button type=\"button\" aria-label=\"Replace image\" className={toolBtn} onClick={() => setPicker(true)}>\n <IconReplace stroke={1.5} aria-hidden />\n {ctx.dense ? null : \"Replace\"}\n </button>\n </Tooltip>\n <Sep />\n </>\n ) : null}\n <Menu onOpenChange={setBusy}>\n <MenuTrigger\n render={\n <button type=\"button\" aria-label={`Align: ${alignItem.label}`} className={toolBtn}>\n {alignItem.icon}\n <IconChevronDown className=\"!size-3 text-kit-fg-3\" stroke={1.5} aria-hidden />\n </button>\n }\n />\n <MenuContent className=\"w-40\">\n {ALIGNS.map((a) => (\n <MenuItem\n key={a.v}\n icon={a.icon}\n onClick={() => set({ align: a.v, ...(a.v === \"full\" ? { size: \"full\" as const } : size === \"full\" || !size ? { size: \"l\" as const } : {}) }, \"Align image\")}\n >\n <span className=\"flex w-full items-center justify-between\">\n {a.label}\n {align === a.v ? <IconCheck className=\"size-3.5 text-kit-fg-2\" stroke={2} aria-hidden /> : null}\n </span>\n </MenuItem>\n ))}\n </MenuContent>\n </Menu>\n <div role=\"group\" aria-label=\"Size\" className=\"flex items-center\">\n {SIZES.map((x) => {\n const on = (size ?? (align === \"full\" ? \"full\" : null)) === x.v;\n return (\n <button\n key={x.v}\n type=\"button\"\n aria-pressed={on}\n aria-label={`Size ${x.label}`}\n onClick={() => set({ size: x.v, ...(x.v === \"full\" ? { align: \"full\" as const } : align === \"full\" ? { align: \"center\" as const } : {}) }, \"Resize image\")}\n className={cn(\"h-7 min-w-6 rounded-kit-md px-1 text-kit-xs text-kit-fg-3 hover:bg-kit-hover hover:text-kit-fg\", on && \"bg-kit-selected font-medium text-kit-fg\")}\n >\n {x.label}\n </button>\n );\n })}\n </div>\n <Sep />\n <Popover\n open={linkOpen}\n onOpenChange={(o) => {\n setLinkOpen(o);\n setBusy(o);\n }}\n >\n <Tooltip content={m.href ? `Links to ${m.href}` : \"Link the image\"}>\n <PopoverTrigger aria-label=\"Link the image\" className={cn(toolBtn, m.href && \"text-kit-accent-fg\")}>\n <IconLink stroke={1.5} aria-hidden />\n </PopoverTrigger>\n </Tooltip>\n <PopoverContent className=\"w-[340px] p-3\" finalFocus={false}>\n <p className=\"mb-2 text-kit-xs font-medium text-kit-fg-2\">Link the image to</p>\n <LinkForm\n initial={{ href: m.href ?? \"\" }}\n allowNewTab={false}\n onSave={(v) => {\n set({ href: v.href }, \"Link image\");\n setLinkOpen(false);\n setBusy(false);\n }}\n onCancel={() => {\n setLinkOpen(false);\n setBusy(false);\n }}\n onDetach={\n m.href\n ? () => {\n set((x) => {\n const { href: _gone, ...rest } = x;\n void _gone;\n return rest;\n }, \"Unlink image\");\n setLinkOpen(false);\n setBusy(false);\n }\n : undefined\n }\n />\n </PopoverContent>\n </Popover>\n <AltPopover alt={m.alt ?? \"\"} onSave={(alt) => set({ alt }, \"Edit alt text\")} onOpen={setBusy} btnClass={toolBtn} />\n <Sep />\n <Tooltip content=\"Remove image\">\n <button type=\"button\" aria-label=\"Remove image\" className={cn(toolBtn, \"hover:text-kit-danger-fg\")} onClick={() => ctx.remove(el)}>\n <IconTrash stroke={1.5} aria-hidden />\n </button>\n </Tooltip>\n </div>\n )}\n <div className={cn(\"flex\", justify)}>\n <img src={m.src} alt={m.alt ?? \"\"} style={{ width }} className=\"block h-auto max-w-full rounded-kit-lg border border-kit-line\" draggable={false} />\n </div>\n {ro && !m.caption ? null : (\n <PlainEditable\n value={m.caption ?? \"\"}\n label=\"Image caption\"\n readOnly={ro}\n placeholder={ro ? \"\" : \"Add a caption…\"}\n onChange={(caption) => set({ caption }, \"Edit caption\")}\n onEnter={() => ctx.exit(el)}\n className=\"mt-1.5 text-center text-kit-sm text-kit-fg-3\"\n />\n )}\n {pickerEl}\n </figure>\n );\n}\n\nfunction AltPopover({ alt, onSave, onOpen, btnClass }: { alt: string; onSave: (a: string) => void; onOpen: (o: boolean) => void; btnClass: string }) {\n const [open, setOpen] = React.useState(false);\n const [v, setV] = React.useState(alt);\n const id = React.useId();\n return (\n <Popover\n open={open}\n onOpenChange={(o) => {\n setOpen(o);\n onOpen(o);\n if (o) setV(alt);\n }}\n >\n <Tooltip content={alt ? \"Alt text\" : \"Add alt text\"}>\n <PopoverTrigger aria-label=\"Alt text\" className={cn(btnClass, !alt && \"text-kit-warning-fg\")}>\n <IconAlt stroke={1.5} aria-hidden />\n </PopoverTrigger>\n </Tooltip>\n <PopoverContent className=\"w-72\" finalFocus={false}>\n <form\n onSubmit={(e) => {\n e.preventDefault();\n onSave(v.trim());\n setOpen(false);\n onOpen(false);\n }}\n className=\"flex flex-col gap-2\"\n >\n <label className=\"text-kit-xs font-medium text-kit-fg-2\" htmlFor={id}>\n Alt text\n </label>\n <Textarea id={id} autoFocus value={v} onChange={(e) => setV(e.target.value)} placeholder=\"Describe the image\" rows={2} />\n <p className=\"text-kit-2xs text-kit-fg-3\">Read aloud by screen readers and used by search engines.</p>\n <div className=\"flex justify-end\">\n <Button size=\"xs\" variant=\"primary\" type=\"submit\">\n Done\n </Button>\n </div>\n </form>\n </PopoverContent>\n </Popover>\n );\n}\n\n/* ── Callout (V2 CalloutBlock): tone · title · message ─────────────── */\nconst TONES: Record<CalloutTone, { label: string; icon: React.ReactNode; box: string; chip: string }> = {\n info: { label: \"Info\", icon: <IconInfoCircle stroke={1.5} />, box: \"border-kit-info-line bg-kit-info-soft\", chip: \"text-kit-info-fg\" },\n tip: { label: \"Tip\", icon: <IconBulb stroke={1.5} />, box: \"border-kit-success-line bg-kit-success-soft\", chip: \"text-kit-success-fg\" },\n warning: { label: \"Warning\", icon: <IconAlertTriangle stroke={1.5} />, box: \"border-kit-warning-line bg-kit-warning-soft\", chip: \"text-kit-warning-fg\" },\n};\nfunction CalloutBlock({ m, set, el, ctx, autoFocus }: BlockProps<\"callout\">) {\n // a stored tone the editor does not offer is kept as it is, and drawn as Info\n const tone: CalloutTone = (CALLOUT_TONES as readonly string[]).includes(m.tone ?? \"\") ? (m.tone as CalloutTone) : \"info\";\n const t = TONES[tone];\n const body = React.useRef<HTMLDivElement>(null);\n const ro = ctx.readOnly;\n return (\n <div className={cn(\"group/blk relative rounded-kit-lg border px-3.5 py-3\", t.box)} data-rt-isolate=\"\">\n <div className=\"flex items-center gap-1\">\n <Menu>\n <MenuTrigger\n disabled={ro}\n render={\n <button\n type=\"button\"\n aria-label={`Callout tone: ${t.label}`}\n className={cn(\"-ml-1 flex h-6 items-center gap-1 rounded-kit-md px-1.5 text-kit-xs font-medium hover:bg-kit-hover data-[popup-open]:bg-kit-hover [&_svg]:size-3.5\", t.chip)}\n >\n {t.icon}\n {t.label}\n {ro ? null : <IconChevronDown className=\"!size-3 opacity-70\" stroke={1.5} aria-hidden />}\n </button>\n }\n />\n <MenuContent className=\"w-36\">\n {CALLOUT_TONES.map((k) => (\n <MenuItem key={k} icon={TONES[k].icon} onClick={() => set({ tone: k }, \"Change callout tone\")}>\n <span className=\"flex w-full items-center justify-between\">\n {TONES[k].label}\n {tone === k ? <IconCheck className=\"size-3.5 text-kit-fg-2\" stroke={2} aria-hidden /> : null}\n </span>\n </MenuItem>\n ))}\n </MenuContent>\n </Menu>\n <span className=\"flex-1\" />\n {ro ? null : (\n <div className=\"opacity-0 transition-opacity motion-reduce:transition-none group-hover/blk:opacity-100 group-focus-within/blk:opacity-100 pointer-coarse:opacity-100\">\n <RemoveBtn onClick={() => ctx.remove(el)} label=\"Remove callout\" />\n </div>\n )}\n </div>\n <PlainEditable\n value={m.title ?? \"\"}\n label=\"Callout title\"\n readOnly={ro}\n autoFocus={autoFocus}\n placeholder=\"Title\"\n onChange={(title) => set({ title }, \"Edit callout title\")}\n onEnter={() => {\n const b = body.current?.querySelector<HTMLElement>(\"[role=textbox]\");\n b?.focus();\n if (b) placeCaret(b, false);\n }}\n className=\"mt-1 font-medium text-kit-fg\"\n />\n <div ref={body}>\n <PlainEditable\n multiline\n value={m.body ?? \"\"}\n label=\"Callout message\"\n readOnly={ro}\n placeholder=\"Write a message…\"\n onChange={(b) => set({ body: b }, \"Edit callout message\")}\n className=\"mt-0.5 text-kit-fg-2\"\n />\n </div>\n </div>\n );\n}\n\n/* ── Toggle (V2 ToggleBlock): title · body. A saved toggle shows closed, like V2; a just-inserted one shows open. Open or closed is the editor's view only. ── */\nfunction ToggleBlock({ m, set, el, ctx, autoFocus }: BlockProps<\"toggle\">) {\n const [open, setOpen] = React.useState(!!autoFocus);\n const body = React.useRef<HTMLDivElement>(null);\n const bodyId = React.useId();\n const ro = ctx.readOnly;\n return (\n <div className=\"group/blk relative rounded-kit-md\" data-rt-isolate=\"\">\n <div className=\"flex items-start gap-1\">\n <button\n type=\"button\"\n aria-expanded={open}\n aria-controls={bodyId}\n aria-label={open ? \"Collapse toggle\" : \"Expand toggle\"}\n onClick={() => setOpen((o) => !o)}\n className=\"mt-0.5 flex size-6 shrink-0 items-center justify-center rounded-kit-md text-kit-fg-2 hover:bg-kit-hover hover:text-kit-fg\"\n >\n <IconChevronRight className={cn(\"size-4 transition-transform duration-150 motion-reduce:transition-none\", open && \"rotate-90\")} stroke={1.5} aria-hidden />\n </button>\n <PlainEditable\n value={m.title ?? \"\"}\n label=\"Toggle title\"\n readOnly={ro}\n autoFocus={autoFocus}\n placeholder=\"Toggle title\"\n onChange={(title) => set({ title }, \"Edit toggle title\")}\n onEnter={() => {\n setOpen(true);\n requestAnimationFrame(() => {\n const b = body.current?.querySelector<HTMLElement>(\"[role=textbox]\");\n b?.focus();\n if (b) placeCaret(b, false);\n });\n }}\n className=\"flex-1 py-0.5 font-medium text-kit-fg\"\n />\n {ro ? null : (\n <div className=\"opacity-0 transition-opacity motion-reduce:transition-none group-hover/blk:opacity-100 group-focus-within/blk:opacity-100 pointer-coarse:opacity-100\">\n <RemoveBtn onClick={() => ctx.remove(el)} label=\"Remove toggle\" />\n </div>\n )}\n </div>\n <div ref={body} id={bodyId} hidden={!open} className=\"ml-3 mt-1 border-l border-kit-line pl-4\">\n <PlainEditable\n multiline\n value={m.body ?? \"\"}\n label=\"Toggle body\"\n readOnly={ro}\n placeholder=\"Hidden content. Click to write…\"\n onChange={(b) => set({ body: b }, \"Edit toggle body\")}\n className=\"py-0.5 text-kit-fg-2\"\n />\n </div>\n </div>\n );\n}\n\n/* ── Video (V2 VideoBlock): a link to a video file or a provider's page ─── */\nconst videoUrlOk = (u: string) => /^https?:\\/\\/\\S+$/i.test(u) || /^\\/(?!\\/)\\S*$/.test(u);\nfunction videoEmbedSrc(url: string): string | null {\n const yt = /(?:youtube\\.com\\/(?:watch\\?(?:.*&)?v=|embed\\/|shorts\\/|live\\/)|youtu\\.be\\/)([\\w-]{6,})/i.exec(url);\n if (yt) return `https://www.youtube-nocookie.com/embed/${yt[1]}`;\n const vimeo = /vimeo\\.com\\/(?:video\\/)?(\\d+)/i.exec(url);\n if (vimeo) return `https://player.vimeo.com/video/${vimeo[1]}`;\n return null;\n}\nfunction VideoBlock({ m, set, el, ctx, autoFocus }: BlockProps<\"video\">) {\n const [draft, setDraft] = React.useState(m.url ?? \"\");\n React.useEffect(() => setDraft(m.url ?? \"\"), [m.url]);\n const [error, setError] = React.useState<string | null>(null);\n const errId = React.useId();\n const commit = () => {\n const u = draft.trim();\n if (u === (m.url ?? \"\")) return setError(null);\n if (u && !videoUrlOk(u)) return setError(\"Paste a full link that starts with https://, or a path on this site.\");\n setError(null);\n set({ url: u }, \"Set video link\");\n };\n const ro = ctx.readOnly;\n const frame = m.url ? videoEmbedSrc(m.url) : null;\n return (\n <div className=\"group/blk rounded-kit-lg border border-kit-line bg-kit-subtle p-2.5\" data-rt-isolate=\"\">\n {ro ? null : (\n <div className=\"mb-2 flex items-center gap-1.5\">\n <Input\n size=\"sm\"\n autoFocus={autoFocus}\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n onBlur={commit}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n commit();\n }\n }}\n placeholder=\"Paste a YouTube, Vimeo or video file link\"\n aria-label=\"Video URL\"\n aria-invalid={!!error || undefined}\n aria-describedby={error ? errId : undefined}\n spellCheck={false}\n autoComplete=\"off\"\n leading={<IconWorld stroke={1.5} />}\n className=\"min-w-0 flex-1\"\n />\n <RemoveBtn onClick={() => ctx.remove(el)} label=\"Remove video\" />\n </div>\n )}\n {error ? (\n <p id={errId} role=\"alert\" className=\"mb-2 px-1 text-kit-xs text-kit-danger-fg\">\n {error}\n </p>\n ) : null}\n {frame ? (\n <iframe\n src={frame}\n title={m.title || \"Video preview\"}\n loading=\"lazy\"\n tabIndex={-1}\n sandbox=\"allow-scripts allow-same-origin allow-presentation\"\n referrerPolicy=\"strict-origin-when-cross-origin\"\n className=\"pointer-events-none aspect-video w-full rounded-kit-md border-0 bg-kit-muted\"\n />\n ) : m.url ? (\n <video src={m.url} title={m.title || \"Video preview\"} controls preload=\"metadata\" className=\"aspect-video w-full rounded-kit-md bg-kit-muted\" />\n ) : (\n <p className=\"flex items-center gap-1.5 px-1 pb-0.5 text-kit-xs text-kit-fg-3\">\n <IconVideo className=\"size-3.5\" stroke={1.5} aria-hidden />\n No video yet.\n </p>\n )}\n </div>\n );\n}\n\n/* ── File (V2 FileBlock): a downloadable document ─────────────────── */\nconst formatBytes = (n: number) => (n < 1024 ? `${n} B` : n < 1024 * 1024 ? `${(n / 1024).toFixed(0)} KB` : `${(n / 1024 / 1024).toFixed(1)} MB`);\nfunction FileBlock({ m, set, el, ctx, autoFocus }: BlockProps<\"file\">) {\n const { MediaPicker } = useKitServices();\n const [picker, setPicker] = React.useState(false);\n const [url, setUrl] = React.useState(\"\");\n const [name, setName] = React.useState(\"\");\n const ro = ctx.readOnly;\n const has = !!(m.url && m.name);\n const pickerEl = MediaPicker ? (\n <MediaPicker open={picker} onOpenChange={setPicker} accept={[\"file\"]} onPick={(a) => a[0] && set({ url: a[0].url, name: a[0].name ?? a[0].url.split(\"/\").pop() ?? \"Download\", ...(a[0].size ? { size: a[0].size } : {}) }, \"Choose file\")} />\n ) : null;\n if (has)\n return (\n <div className=\"group/blk flex items-center gap-3 rounded-kit-lg border border-kit-line bg-kit-surface px-3 py-2.5\" data-rt-isolate=\"\">\n <span className=\"flex size-9 shrink-0 items-center justify-center rounded-kit-md bg-kit-muted text-kit-fg-2\">\n <IconFileText className=\"size-[18px]\" stroke={1.5} aria-hidden />\n </span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate text-kit-sm font-medium text-kit-fg\">{m.name}</div>\n <div className=\"truncate text-kit-xs text-kit-fg-3\">\n {m.size ? `${formatBytes(m.size)} · ` : \"\"}\n {(m.name!.includes(\".\") ? m.name!.split(\".\").pop()! : \"file\").toUpperCase()}\n </div>\n </div>\n {ro ? null : (\n <>\n {MediaPicker ? (\n <Button size=\"xs\" variant=\"ghost\" onClick={() => setPicker(true)}>\n Replace\n </Button>\n ) : null}\n <RemoveBtn onClick={() => ctx.remove(el)} label=\"Remove file\" />\n </>\n )}\n {pickerEl}\n </div>\n );\n return (\n <div className=\"group/blk rounded-kit-lg border border-dashed border-kit-line-strong bg-kit-subtle px-3 py-2.5\" data-rt-isolate=\"\">\n <div className=\"flex items-center gap-3\">\n <span className=\"flex size-9 shrink-0 items-center justify-center rounded-kit-md border border-kit-line bg-kit-control-bg text-kit-fg-3\">\n <IconFileText className=\"size-[18px]\" stroke={1.5} aria-hidden />\n </span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-kit-sm font-medium text-kit-fg\">File</div>\n <p className=\"text-kit-xs text-kit-fg-3\">No file yet.</p>\n </div>\n {ro ? null : (\n <>\n {MediaPicker ? (\n <Button size=\"sm\" leftIcon={<IconLibraryPhoto stroke={1.5} />} onClick={() => setPicker(true)}>\n Choose file\n </Button>\n ) : null}\n <RemoveBtn onClick={() => ctx.remove(el)} label=\"Remove file\" />\n </>\n )}\n </div>\n {ro ? null : (\n <form\n className=\"mt-2.5 flex flex-wrap items-center gap-2\"\n onSubmit={(e) => {\n e.preventDefault();\n const u = url.trim();\n if (!/^https?:\\/\\/\\S+$/i.test(u) && !/^\\/(?!\\/)\\S*$/.test(u)) return ctx.notify(\"Paste a full file link that starts with https://\", \"Or a path on this site, like /files/spec.pdf.\");\n set({ url: u, name: name.trim() || u.split(\"/\").pop() || \"Download\" }, \"Add file\");\n ctx.exit(el);\n }}\n >\n <Input autoFocus={autoFocus && !MediaPicker} size=\"sm\" value={url} onChange={(e) => setUrl(e.target.value)} placeholder=\"https://…/guide.pdf\" aria-label=\"File URL\" spellCheck={false} autoComplete=\"off\" leading={<IconLink stroke={1.5} />} className=\"min-w-40 flex-1\" />\n <Input size=\"sm\" value={name} onChange={(e) => setName(e.target.value)} placeholder=\"Link text\" aria-label=\"File name shown to readers\" className=\"min-w-28 flex-1\" />\n <Button size=\"sm\" variant=\"primary\" type=\"submit\" disabled={!url.trim()}>\n Add\n </Button>\n </form>\n )}\n {pickerEl}\n </div>\n );\n}\n\n/* ── Embedded component (CPO D28): a linked instance, shown as its card ─────────── */\nfunction ComponentBlock({ m, el, ctx, set }: BlockProps<\"component\">) {\n const { useComponentInfo } = useKitServices();\n const overrides = React.useMemo<Record<string, unknown>>(() => {\n try {\n const v = m.overrides ? (JSON.parse(m.overrides) as unknown) : {};\n return v && typeof v === \"object\" && !Array.isArray(v) ? (v as Record<string, unknown>) : {};\n } catch {\n return {};\n }\n }, [m.overrides]);\n // the host's component library answers → V2's instance card; none → the compact linked row (no state made up)\n if (useComponentInfo) return <ComponentCard m={m} el={el} ctx={ctx} use={useComponentInfo} overrides={overrides} set={set} />;\n const count = Object.keys(overrides).length;\n const name = m.name || \"Component\";\n return (\n <div\n role=\"group\"\n aria-label={`${name}, ${m.detached ? \"separate copy\" : \"linked component\"}`}\n className=\"group/blk flex items-center gap-3 rounded-kit-lg border border-kit-line bg-kit-surface px-3 py-2.5\"\n data-rt-isolate=\"\"\n >\n <span className=\"flex size-9 shrink-0 items-center justify-center rounded-kit-md bg-kit-muted text-kit-fg-2\">\n <IconComponents className=\"size-[18px]\" stroke={1.5} aria-hidden />\n </span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate text-kit-sm font-medium text-kit-fg\">{name}</div>\n <div className=\"truncate text-kit-xs text-kit-fg-3\">\n {m.detached ? (\n \"Separate copy · edits to the component don't reach it\"\n ) : (\n <>\n {m.ref ? \"Linked component\" : \"Component with no source\"}\n {count ? ` · ${count} ${count === 1 ? \"override\" : \"overrides\"}` : \"\"} · edits to the component show here too\n </>\n )}\n </div>\n </div>\n {ctx.readOnly ? null : (\n <div className=\"flex items-center gap-0.5 opacity-0 transition-opacity motion-reduce:transition-none group-hover/blk:opacity-100 group-focus-within/blk:opacity-100 pointer-coarse:opacity-100\">\n {ctx.duplicate ? (\n <IconButton size=\"xs\" label={`Duplicate ${name}`} onClick={() => ctx.duplicate?.(el)}>\n <IconCopy stroke={1.5} />\n </IconButton>\n ) : null}\n <RemoveBtn onClick={() => ctx.remove(el)} label={`Remove ${name}`} />\n </div>\n )}\n </div>\n );\n}\n\n/* ── Table (V2 TableBlock, CPO D42: the table value, edited with the shared table editor) ─────────── */\n/**\n * What production's rich-text table keeps: text and link cells, the header row and row headers, an optional caption,\n * the note under the table and row groups (`caption`, `notes`, `rowGroups`). Footnotes have no place there.\n */\nconst STORED_TABLE: TableFieldOptions = {\n columnTypes: [\"text\", \"link\"],\n requireCaption: false,\n allowGroups: true,\n allowFootnotes: false,\n allowNote: true,\n settings: { headers: true, totals: false, phones: [], highlight: false, sticky: false, sort: false, search: false },\n};\nfunction TableBlock({ m, set, el, ctx }: BlockProps<\"table\">) {\n return (\n <div className=\"group/blk\" data-rt-isolate=\"\">\n <TableEditor\n value={m}\n onChange={(next) => set(() => next, \"Edit table\")}\n readOnly={ctx.readOnly}\n options={STORED_TABLE}\n label=\"Table\"\n actions={ctx.readOnly ? null : <RemoveBtn onClick={() => ctx.remove(el)} label=\"Remove table\" />}\n />\n </div>\n );\n}\n\n/* ── Pull quote (V2 article-blocks.tsx ArticleBlock, surface \"panel\") ─────────── */\nconst PULL_QUOTE_LABEL = \"Pull quote\";\n/** V2 article.ts ARTICLE_SCHEMAS.pullquote: the properties panel is built from it. */\nconst PULL_QUOTE_SCHEMA: TypeSchema = {\n name: \"pullQuote\",\n title: PULL_QUOTE_LABEL,\n kind: \"object\",\n icon: \"quote\",\n fields: [\n { name: \"quote\", title: \"Quote\", type: \"text\", rows: 3, validation: { required: true, recommendedMax: 200 } },\n { name: \"name\", title: \"Name\", type: \"string\", validation: { max: 60 } },\n { name: \"role\", title: \"Role or source\", type: \"string\", validation: { max: 80 } },\n { name: \"link\", title: \"Source link\", type: \"url\", description: \"The name links here.\" },\n ],\n};\n\n/* one article panel open at a time (V2 useOpenArticle) */\nlet openArticle: { id: string; focusKey: string | null; nonce: number } | null = null;\nconst articleSubs = new Set<() => void>();\nconst setOpenArticle = (next: typeof openArticle) => {\n openArticle = next;\n articleSubs.forEach((f) => f());\n};\nfunction useOpenArticle() {\n return React.useSyncExternalStore(\n (cb) => (articleSubs.add(cb), () => void articleSubs.delete(cb)),\n () => openArticle,\n () => openArticle,\n );\n}\n\nconst controlOf = (el: HTMLElement) =>\n Array.from(el.querySelectorAll<HTMLElement>(\"textarea, input:not([type=hidden]), [contenteditable=true], [role=combobox]\")).find((n) => n.getClientRects().length) ??\n Array.from(el.querySelectorAll<HTMLElement>(\":scope > :not(:first-child) button\")).find((n) => n.getClientRects().length);\nfunction focusField(root: HTMLElement | null, key: string | null) {\n if (!root) return;\n const rows = Array.from(root.querySelectorAll<HTMLElement>(\"[data-field-key]\"));\n const row = (key && rows.find((r) => r.getAttribute(\"data-field-key\") === key)) || rows[0];\n if (!row) return;\n row.scrollIntoView({ block: \"nearest\" });\n controlOf(row)?.focus({ preventScroll: true });\n}\n\nfunction PullQuoteBlock({ m, set, el, ctx, autoFocus }: BlockProps<\"pullquote\">) {\n const label = PULL_QUOTE_LABEL;\n const uid = React.useId();\n const card = React.useRef<HTMLDivElement | null>(null);\n const [cardEl, setCardEl] = React.useState<HTMLDivElement | null>(null);\n const open = useOpenArticle();\n const editing = open?.id === uid;\n // a stable ref: a new callback each render would pass null for a moment and remount the panel\n const cardRef = React.useCallback((n: HTMLDivElement | null) => {\n card.current = n;\n if (n) setCardEl(n);\n }, []);\n const ro = !!ctx.readOnly;\n const modelRef = React.useRef(m);\n modelRef.current = m;\n\n const openPanel = React.useCallback((k?: string | null) => {\n if (!ro) setOpenArticle({ id: uid, focusKey: k ?? null, nonce: (openArticle?.nonce ?? 0) + 1 });\n }, [uid, ro]);\n const close = React.useCallback(() => {\n if (openArticle?.id === uid) setOpenArticle(null);\n }, [uid]);\n const focusCard = React.useCallback(() => requestAnimationFrame(() => card.current?.focus({ preventScroll: true })), []);\n React.useEffect(() => () => {\n if (openArticle?.id === uid) setOpenArticle(null);\n }, [uid]);\n React.useEffect(() => {\n // a fresh insert opens its form\n if (autoFocus && !ro) openPanel();\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n /** a form edit joins the body's one undo history (D54); typing coalesces per field */\n const commit = (next: PullQuoteModel) => {\n const prev = modelRef.current;\n const field = (Object.keys(next) as (keyof PullQuoteModel)[]).find((k) => next[k] !== prev[k]) ?? \"\";\n set(() => next, `Edit ${label.toLowerCase()} ${field}`);\n };\n\n const onKeyDown = (e: React.KeyboardEvent) => {\n if (e.defaultPrevented || e.target !== card.current) return;\n const mod = e.metaKey || e.ctrlKey;\n const k = e.key.toLowerCase();\n if (mod && k === \"z\") {\n e.preventDefault();\n e.stopPropagation();\n if (e.shiftKey) ctx.redo?.();\n else ctx.undo?.();\n return;\n }\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n openPanel();\n return;\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n e.stopPropagation();\n if (editing) close();\n else ctx.exit(el);\n return;\n }\n if (ro) return;\n if (mod && k === \"d\" && ctx.duplicate) {\n e.preventDefault();\n e.stopPropagation();\n ctx.duplicate(el);\n } else if (e.altKey && (e.key === \"ArrowUp\" || e.key === \"ArrowDown\") && ctx.move) {\n e.preventDefault();\n ctx.move(el, e.key === \"ArrowUp\" ? -1 : 1);\n focusCard();\n } else if (e.key === \"Backspace\" || e.key === \"Delete\") {\n e.preventDefault();\n ctx.remove(el);\n }\n };\n\n const actions = ro ? null : (\n <div\n className={cn(\n // sits on the block's top edge, so it never covers the block's own text\n \"absolute -top-3.5 right-2 z-[2] flex items-center gap-0.5 rounded-kit-md border border-kit-line bg-kit-surface-raised p-0.5 opacity-0 shadow-kit-sm transition-opacity\",\n \"group-hover/art:opacity-100 group-focus-within/art:opacity-100 pointer-coarse:opacity-100\",\n editing && \"opacity-100\",\n )}\n >\n <IconButton size=\"xs\" label={`Edit ${label.toLowerCase()}`} onClick={() => (editing ? close() : openPanel())}>\n <IconSettings stroke={1.5} />\n </IconButton>\n <IconButton size=\"xs\" label={`Remove ${label.toLowerCase()}`} onClick={() => ctx.remove(el)} className=\"hover:text-kit-danger-fg\">\n <IconTrash stroke={1.5} />\n </IconButton>\n </div>\n );\n\n return (\n <>\n <div\n ref={cardRef}\n role=\"group\"\n tabIndex={0}\n aria-label={`${label}${editing ? \", editing\" : \"\"}`}\n aria-roledescription=\"block\"\n aria-haspopup=\"dialog\"\n aria-expanded={editing}\n data-rt-isolate=\"\"\n data-article-block=\"pullquote\"\n onKeyDown={onKeyDown}\n onClick={(e) => {\n if (ro || !e.currentTarget.contains(e.target as Node)) return;\n const t = e.target as HTMLElement;\n if (t.closest(\"button,a,[role=menuitem]\")) return;\n openPanel(t.closest<HTMLElement>(\"[data-field]\")?.getAttribute(\"data-field\") ?? null);\n }}\n className={cn(\n \"group/art relative rounded-kit-lg outline-none transition-shadow duration-150\",\n !ro && \"cursor-pointer\",\n \"focus-visible:shadow-[0_0_0_1px_var(--kit-line-strong)]\",\n editing ? \"shadow-[0_0_0_2px_var(--kit-accent)] focus-visible:shadow-[0_0_0_2px_var(--kit-accent)]\" : !ro && \"hover:shadow-[0_0_0_1px_var(--kit-line)]\",\n )}\n >\n <PullQuotePreview m={m} />\n {actions}\n </div>\n {editing ? (\n <ArticlePanel label={label} anchor={cardEl} nonce={open!.nonce} focusKey={open!.focusKey} onClose={close} focusBack={focusCard} ctx={ctx} el={el}>\n <div data-article-form=\"\" className=\"min-w-0\">\n <SchemaForm\n schema={PULL_QUOTE_SCHEMA}\n value={m as unknown as Record<string, unknown>}\n onChange={(v) => commit(v as unknown as PullQuoteModel)}\n variant=\"panel\"\n scroll={false}\n readOnly={ro}\n rootLabel={label}\n env={{ docId: `article:${PULL_QUOTE_SCHEMA.name}`, docTitle: label }}\n />\n <style>{`[data-article-form] [data-kit-form] section:first-of-type { border-top-width: 0; margin-top: 0; padding-top: 0; }`}</style>\n </div>\n </ArticlePanel>\n ) : null}\n </>\n );\n}\n\n/* ── Key takeaways (V2 article-blocks.tsx ArticleBlock, surface \"inline\" + TakeawaysEditor) ─────────── */\nconst TAKEAWAYS_LABEL = \"Key takeaways\";\n/** V2 article.ts ARTICLE_SCHEMAS.takeaways `points` max (the stored block's limit, key_takeaways_limit_exceeded) */\nconst MAX_POINTS = 8;\n/** V2 article.ts ARTICLE_SCHEMAS.takeaways `title` max */\nconst MAX_TITLE = 40;\n\nfunction TakeawaysBlock({ m, set, el, ctx, autoFocus }: BlockProps<\"takeaways\">) {\n const label = TAKEAWAYS_LABEL;\n const card = React.useRef<HTMLDivElement>(null);\n const box = React.useRef<HTMLUListElement>(null);\n const ro = !!ctx.readOnly;\n const focusCard = () => requestAnimationFrame(() => card.current?.focus({ preventScroll: true }));\n const focusPoint = (i: number, atEnd = true) =>\n requestAnimationFrame(() => {\n const t = box.current?.querySelectorAll<HTMLElement>(\"[role=textbox]\")[i];\n if (!t) return;\n t.focus();\n placeCaret(t, atEnd);\n });\n const setPoint = (i: number, v: string) => set({ points: m.points.map((p, j) => (j === i ? v : p)) }, `Edit key takeaways point ${i + 1}`);\n\n /** V2 ArticleBlock onKeyDown, on the block itself (its lines handle their own keys) */\n const onKeyDown = (e: React.KeyboardEvent) => {\n if (e.defaultPrevented || e.target !== card.current) return;\n const mod = e.metaKey || e.ctrlKey;\n const k = e.key.toLowerCase();\n if (mod && k === \"z\") {\n e.preventDefault();\n e.stopPropagation();\n if (e.shiftKey) ctx.redo?.();\n else ctx.undo?.();\n return;\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n e.stopPropagation();\n ctx.exit(el);\n return;\n }\n if (ro) return;\n if (mod && k === \"d\" && ctx.duplicate) {\n e.preventDefault();\n e.stopPropagation();\n ctx.duplicate(el);\n } else if (e.altKey && (e.key === \"ArrowUp\" || e.key === \"ArrowDown\") && ctx.move) {\n e.preventDefault();\n ctx.move(el, e.key === \"ArrowUp\" ? -1 : 1);\n focusCard();\n } else if (e.key === \"Backspace\" || e.key === \"Delete\") {\n e.preventDefault();\n ctx.remove(el);\n }\n };\n\n return (\n <div\n ref={card}\n role=\"group\"\n tabIndex={0}\n aria-label={label}\n aria-roledescription=\"block\"\n data-rt-isolate=\"\"\n data-article-block=\"takeaways\"\n onKeyDown={onKeyDown}\n className=\"group/art relative rounded-kit-lg outline-none transition-shadow duration-150 focus-visible:shadow-[0_0_0_1px_var(--kit-line-strong)]\"\n >\n <aside className=\"rounded-kit-lg border border-kit-line bg-kit-subtle px-4 py-3\" aria-label={m.title || label}>\n <PlainEditable\n label=\"Key takeaways title\"\n value={m.title}\n placeholder=\"Key takeaways\"\n readOnly={ro}\n onChange={(title) => {\n // V2 ARTICLE_SCHEMAS.takeaways title max: said the moment it is crossed, not first at save (key_takeaways_limit_exceeded)\n if (title.length > MAX_TITLE && m.title.length <= MAX_TITLE)\n ctx.notify(`A key takeaways title holds at most ${MAX_TITLE} characters.`, \"Shorten it, or the change will not save.\");\n set({ title }, \"Edit key takeaways title\");\n }}\n onEnter={() => focusPoint(0, false)}\n className=\"text-kit-sm font-semibold text-kit-fg\"\n />\n <ul ref={box} className=\"m-0 mt-1.5 flex flex-col gap-1 p-0\">\n {m.points.map((p, i) => (\n <li key={i} className=\"flex list-none items-baseline gap-2 text-[15px] leading-relaxed text-kit-fg\">\n <span aria-hidden className=\"mt-[0.55em] size-1.5 shrink-0 self-start rounded-full bg-kit-accent\" />\n <PlainEditable\n label={`Point ${i + 1}`}\n value={p}\n placeholder={i === 0 ? \"The first thing to remember\" : \"Another point\"}\n readOnly={ro}\n autoFocus={autoFocus && i === 0}\n onChange={(v) => setPoint(i, v)}\n onEnter={() => {\n if (m.points.length >= MAX_POINTS) {\n ctx.notify(`Key takeaways hold at most ${MAX_POINTS} points.`, \"Merge two points, or move this one into the text.\");\n return;\n }\n set((x) => ({ ...x, points: [...x.points.slice(0, i + 1), \"\", ...x.points.slice(i + 1)] }), \"Add a key takeaways point\");\n focusPoint(i + 1);\n }}\n onBackspaceEmpty={\n m.points.length > 1\n ? () => {\n set((x) => ({ ...x, points: x.points.filter((_, j) => j !== i) }), \"Remove a key takeaways point\");\n focusPoint(Math.max(0, i - 1));\n }\n : undefined\n }\n className=\"flex-1\"\n />\n </li>\n ))}\n </ul>\n </aside>\n {ro ? null : (\n <div\n className={cn(\n // sits on the block's top edge, so it never covers the block's own text\n \"absolute -top-3.5 right-2 z-[2] flex items-center gap-0.5 rounded-kit-md border border-kit-line bg-kit-surface-raised p-0.5 opacity-0 shadow-kit-sm transition-opacity\",\n \"group-hover/art:opacity-100 group-focus-within/art:opacity-100 pointer-coarse:opacity-100\",\n )}\n >\n <IconButton size=\"xs\" label={`Remove ${label.toLowerCase()}`} onClick={() => ctx.remove(el)} className=\"hover:text-kit-danger-fg\">\n <IconTrash stroke={1.5} />\n </IconButton>\n </div>\n )}\n </div>\n );\n}\n\n/* ── Floating properties panel (D54 primitive; V2 ArticlePanel) ─────────────── */\nfunction ArticlePanel({\n label, anchor, nonce, focusKey, onClose, focusBack, ctx, el, children,\n}: {\n label: string;\n anchor: HTMLElement | null;\n nonce: number;\n focusKey: string | null;\n onClose: () => void;\n focusBack: () => void;\n ctx: IslandCtx;\n el: IslandEl;\n children: React.ReactNode;\n}) {\n const panel = React.useRef<FloatingPanelHandle>(null);\n const titleId = React.useId();\n const container = anchor?.closest<HTMLElement>(\"[data-expanded-editor]\") ?? null;\n React.useEffect(() => {\n // the panel mounts (and, inside the expanded editor, docks) over a few frames; focus lands on the field asked for,\n // and is put back while it is lost (never taken from somewhere the person went)\n const timers: number[] = [];\n let landed = false;\n for (const ms of [40, 90, 160, 260, 420, 640]) {\n timers.push(\n window.setTimeout(() => {\n const root = panel.current?.el() ?? null;\n if (!root?.querySelector(\"[data-field-key]\")) return;\n const a = document.activeElement as HTMLElement | null;\n const lost = !a || a === document.body || a.hasAttribute(\"data-expanded-editor\") || a.hasAttribute(\"data-article-block\");\n if (root.contains(a)) return void (landed = true);\n if (!landed || lost) focusField(root, focusKey);\n if (root.contains(document.activeElement)) landed = true;\n }, ms),\n );\n }\n return () => timers.forEach((t) => window.clearTimeout(t));\n }, [nonce]); // eslint-disable-line react-hooks/exhaustive-deps\n React.useEffect(() => panel.current?.announce(`${label} properties.`), [label]);\n const header = (\n <>\n <span id={titleId} className=\"min-w-0 flex-1 truncate text-kit-sm font-medium text-kit-fg\">{label}</span>\n <Menu>\n <MenuTrigger\n render={\n <IconButton size=\"sm\" label={`${label} actions`}>\n <IconDots stroke={1.5} />\n </IconButton>\n }\n />\n <MenuContent align=\"end\" className=\"w-52\">\n {ctx.readOnly || !ctx.duplicate ? null : (\n <>\n <MenuItem icon={<IconCopy stroke={1.5} />} onClick={() => ctx.duplicate?.(el)}>Duplicate</MenuItem>\n <MenuSeparator />\n </>\n )}\n <MenuItem icon={<IconArrowsMove stroke={1.5} />} onClick={() => panel.current?.keyboard(\"move\")}>Move panel</MenuItem>\n <MenuItem icon={<IconDimensions stroke={1.5} />} onClick={() => panel.current?.keyboard(\"resize\")}>Resize panel</MenuItem>\n <MenuItem icon={<IconLayoutSidebar stroke={1.5} />} onClick={() => panel.current?.dock(\"left\")}>Dock left</MenuItem>\n <MenuItem icon={<IconLayoutSidebarRight stroke={1.5} />} onClick={() => panel.current?.dock(\"right\")}>Dock right</MenuItem>\n {ctx.readOnly ? null : (\n <>\n <MenuSeparator />\n <MenuItem danger icon={<IconTrash stroke={1.5} />} onClick={() => ctx.remove(el)}>Remove</MenuItem>\n </>\n )}\n </MenuContent>\n </Menu>\n <IconButton size=\"sm\" label=\"Close properties\" tooltip=\"Close\" onClick={() => (onClose(), focusBack())}>\n <IconX stroke={1.5} />\n </IconButton>\n </>\n );\n return (\n <FloatingPanel\n ref={panel}\n id=\"article-properties\"\n labelledBy={titleId}\n anchor={anchor}\n container={container}\n header={header}\n onClose={onClose}\n focusBack={focusBack}\n onPanelKeyDown={(e) => {\n if ((e.metaKey || e.ctrlKey) && !e.altKey && e.key.toLowerCase() === \"z\" && !e.defaultPrevented) {\n e.preventDefault();\n if (e.shiftKey) ctx.redo?.();\n else ctx.undo?.();\n }\n }}\n sheetFooter={\n <Button size=\"sm\" variant=\"primary\" onClick={() => (onClose(), focusBack())}>\n Done\n </Button>\n }\n >\n <div className=\"pb-3 pt-1\">{children}</div>\n </FloatingPanel>\n );\n}\n\n/* ── Preview (what the reader sees; V2 PullQuotePreview) ───────────── */\nfunction PullQuotePreview({ m }: { m: PullQuoteModel }) {\n return (\n <figure className=\"m-0 py-2 pl-5 pr-10\">\n <IconQuote className=\"mb-1 size-6 text-kit-accent-fg\" stroke={1.5} aria-hidden />\n <blockquote data-field=\"quote\" className={cn(\"m-0 text-[22px] font-medium leading-snug tracking-[-0.01em]\", m.quote ? \"text-kit-fg\" : \"text-kit-fg-4\")}>\n {m.quote || \"Write the quote\"}\n </blockquote>\n {m.name || m.role ? (\n <figcaption className=\"mt-3 text-kit-sm text-kit-fg-2\">\n {m.name ? (\n <span data-field=\"name\" className={cn(\"font-medium text-kit-fg\", m.link && \"underline decoration-kit-line-strong underline-offset-2\")}>\n {m.name}\n </span>\n ) : null}\n {m.name && m.role ? \", \" : null}\n {m.role ? <span data-field=\"role\">{m.role}</span> : null}\n </figcaption>\n ) : (\n <figcaption data-field=\"name\" className=\"mt-3 text-kit-sm text-kit-fg-4\">Who said it</figcaption>\n )}\n </figure>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.js","names":[],"sources":["../../../src/kit/controls/rich-text/catalog.tsx"],"sourcesContent":["/**\n * RICH TEXT · the block catalogue shared by the toolbar Insert menu, the gutter \"+\" and the \"/\" slash menu (V2 HEAD\n * controls/rich-text/catalog.tsx, CPO D55).\n *\n * browse Text · Media · Data, grouped, then one quiet \"More components N\" row that opens the components the\n * field may embed (V2 HEAD catalog.tsx MORE), with its own search and a way back (\"All blocks\")\n * search every block and every embeddable component in one list: recently used first among the strong matches,\n * then by match (label, aliases, then description)\n * no match \"No match.\"\n *\n * Only the blocks the field accepts are offered (`features`, from the host's codec: each block is offered only where\n * the field's stored shape has a place for it). Not in this catalogue, and why:\n * Footnote, Gallery, Embed, Columns, Checklist, Button, Table of contents, Related posts, Author bio\n * production's rich text has no stored block for them (a checklist renders as a bulleted list; production's embed\n * frames the raw link, which providers refuse, so Video is the one media link offered)\n *\n * Components come from the host (KitServices.useInsertableComponents: the project's components, narrowed to the ones\n * the field's config accepts), handed in through CatalogComponentsProvider. Without that service none is offered.\n * Deviation from V2: the library has no inline / page-section placement, so every component sits in one\n * \"Components\" group (V2: \"Article\" and \"Page sections\"), and no live preview flyout is drawn beside a row.\n */\nimport * as React from \"react\";\nimport {\n IconArrowLeft, IconBlockquote, IconChevronRight, IconComponents, IconFileText, IconH1, IconH2, IconH3, IconH4, IconH5, IconH6, IconInfoCircle, IconLayoutNavbarCollapse, IconList, IconListDetails, IconListNumbers, IconPhoto,\n IconPilcrow, IconQuote, IconSearch, IconSeparatorHorizontal, IconTable, IconTerminal2, IconVideo,\n} from \"@tabler/icons-react\";\nimport { cn } from \"../../lib/cn\";\nimport { PopoverContent } from \"../../ui/overlay\";\nimport type { RichTextFeature } from \"./codec\";\nimport type { KitInsertableComponent } from \"../component-services\";\n\nexport type BasicId =\n | \"p\" | \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"quote\" | \"pullquote\" | \"callout\" | \"toggle\" | \"takeaways\" | \"ul\" | \"ol\" | \"code\" | \"hr\"\n | \"image\" | \"video\" | \"file\" | \"table\";\n\nexport interface CatalogItem {\n key: string;\n /** a basic block (absent on a component, the More components row and the way back) */\n id?: BasicId;\n /** component: embeds `component`; folder: opens More components; back: returns to every block */\n kind?: \"component\" | \"folder\" | \"back\";\n component?: KitInsertableComponent;\n /** the folder row's component count */\n count?: number;\n label: string;\n description: string;\n icon: React.ReactNode;\n /** extra words that find it */\n aliases?: string[];\n}\n\nconst i = (I: React.ComponentType<{ stroke?: number }>) => <I stroke={1.5} />;\ntype Row = [BasicId, string, string, React.ReactNode, string[]?];\nconst rows = (list: Row[]): CatalogItem[] => list.map(([id, label, description, icon, aliases]) => ({ key: id, id, label, description, icon, aliases }));\n\nconst TEXT = rows([\n [\"p\", \"Text\", \"Plain body text\", i(IconPilcrow), [\"paragraph\", \"body\"]],\n [\"h2\", \"Heading 2\", \"Section heading\", i(IconH2), [\"title\", \"subtitle\"]],\n [\"h3\", \"Heading 3\", \"Subsection heading\", i(IconH3)],\n [\"h4\", \"Heading 4\", \"Minor heading\", i(IconH4)],\n [\"quote\", \"Quote\", \"A quoted passage\", i(IconBlockquote), [\"blockquote\"]],\n [\"pullquote\", \"Pull quote\", \"A highlighted line with who said it\", i(IconQuote), [\"pq\", \"testimonial\", \"attribution\"]],\n [\"ul\", \"List\", \"Bulleted list\", i(IconList), [\"bullets\", \"bulleted list\", \"unordered\"]],\n [\"ol\", \"Numbered list\", \"Ordered steps\", i(IconListNumbers), [\"ordered\", \"steps\"]],\n [\"toggle\", \"Toggle\", \"Collapsible title and body\", i(IconLayoutNavbarCollapse), [\"accordion\", \"details\", \"collapse\"]],\n [\"callout\", \"Callout\", \"A highlighted note with a tone\", i(IconInfoCircle), [\"note\", \"tip\", \"warning\", \"aside\"]],\n [\"takeaways\", \"Key takeaways\", \"The story in a few points\", i(IconListDetails), [\"summary\", \"tldr\", \"tl;dr\", \"highlights\"]],\n [\"hr\", \"Divider\", \"A line between parts\", i(IconSeparatorHorizontal), [\"line\", \"separator\", \"rule\"]],\n [\"code\", \"Code\", \"Monospaced snippet\", i(IconTerminal2), [\"code block\", \"snippet\", \"pre\"]],\n]);\nconst MEDIA = rows([\n [\"image\", \"Image\", \"Image with alt text and caption\", i(IconPhoto), [\"img\", \"picture\", \"photo\"]],\n [\"video\", \"Video\", \"A YouTube, Vimeo or video file link\", i(IconVideo), [\"mp4\", \"youtube\", \"yt\", \"vimeo\", \"clip\", \"movie\"]],\n [\"file\", \"File\", \"A downloadable PDF or file\", i(IconFileText), [\"pdf\", \"download\", \"attachment\"]],\n]);\nconst DATA = rows([[\"table\", \"Table\", \"Rows and columns\", i(IconTable), [\"grid\", \"data\", \"comparison\", \"spreadsheet\"]]]);\n/** Found by search, not listed: rare in a body (H1 is the page title). */\nconst SEARCH_ONLY = rows([\n [\"h1\", \"Heading 1\", \"Largest heading\", i(IconH1)],\n [\"h5\", \"Heading 5\", \"Smallest heading\", i(IconH5)],\n [\"h6\", \"Heading 6\", \"Eyebrow heading\", i(IconH6)],\n]);\n\n/** The feature a block needs (Text needs none). */\nconst NEEDS: Record<BasicId, RichTextFeature | null> = {\n p: null, h1: \"h1\", h2: \"h2\", h3: \"h3\", h4: \"h4\", h5: \"h5\", h6: \"h6\", quote: \"blockquote\", ul: \"ul\", ol: \"ol\", code: \"pre\", hr: \"hr\", image: \"image\",\n pullquote: \"pullquote\", takeaways: \"takeaways\", callout: \"callout\", toggle: \"toggle\", video: \"video\", file: \"file\", table: \"table\",\n};\nconst MORE: CatalogItem = { key: \"more\", kind: \"folder\", label: \"More components\", description: \"Shared across your site\", icon: i(IconComponents) };\nconst BACK: CatalogItem = { key: \"back\", kind: \"back\", label: \"All blocks\", description: \"\", icon: i(IconArrowLeft) };\nconst componentRow = (c: KitInsertableComponent): CatalogItem => ({\n key: `c:${c.id}`,\n kind: \"component\",\n component: c,\n label: c.name,\n description: c.description || \"Shared across your site\",\n icon: i(IconComponents),\n});\n\n/** The components this field may embed, as the host answered (KitServices.useInsertableComponents). */\nexport interface CatalogComponents {\n components: KitInsertableComponent[];\n loading?: boolean;\n error?: string;\n}\nconst ComponentsContext = React.createContext<CatalogComponents | null>(null);\nexport const CatalogComponentsProvider = ComponentsContext.Provider;\n\nexport const blockAllowed = (id: BasicId, allows: (f: RichTextFeature) => boolean) => {\n const need = NEEDS[id];\n return !need || allows(need);\n};\n\n/* ── Recently used (per person, CPO D55): this browser's storage; a browser that keeps none just has no recents ── */\nconst RECENTS_KEY = \"kit-rt-insert-recents\";\nlet recents: string[] = (() => {\n try {\n const v = JSON.parse(globalThis.localStorage?.getItem(RECENTS_KEY) ?? \"[]\") as unknown;\n return Array.isArray(v) ? v.filter((x): x is string => typeof x === \"string\") : [];\n } catch {\n return [];\n }\n})();\nconst recentSubs = new Set<() => void>();\n/** Remember a pick so search ranks it first next time. */\nexport function noteRecent(it: CatalogItem) {\n recents = [it.key, ...recents.filter((k) => k !== it.key)].slice(0, 12);\n try {\n globalThis.localStorage?.setItem(RECENTS_KEY, JSON.stringify(recents));\n } catch {\n /* storage is off: recents last for this session */\n }\n recentSubs.forEach((s) => s());\n}\nfunction useRecents() {\n return React.useSyncExternalStore(\n (cb) => {\n recentSubs.add(cb);\n return () => recentSubs.delete(cb);\n },\n () => recents,\n () => recents,\n );\n}\n\nexport interface CatalogSection {\n title: string | null;\n items: CatalogItem[];\n}\n\n/** 5 exact (label, id or alias) · 4 label or alias starts with it · 3 a word of the label starts with it · 2 inside the\n * label · 1 the description. */\nconst score = (q: string, it: CatalogItem) => {\n const l = it.label.toLowerCase();\n const al = it.aliases ?? [];\n if (l === q || it.id === q || al.includes(q)) return 5;\n if (l.startsWith(q) || al.some((a) => a.startsWith(q))) return 4;\n if (l.split(/[\\s-]+/).some((w) => w.startsWith(q))) return 3;\n if (l.includes(q)) return 2;\n return it.description.toLowerCase().includes(q) ? 1 : 0;\n};\n/** Ranked by recently used among the strong matches, then by match, then catalogue order. */\nconst rank = (q: string, list: CatalogItem[], recent: string[]) =>\n list\n .map((it, i) => {\n const s = score(q, it);\n const r = recent.indexOf(it.key);\n return { it, s, strong: s >= 3 ? 1 : 0, r: s >= 3 && r >= 0 ? r : 999, i };\n })\n .filter((x) => x.s > 0)\n .sort((a, b) => b.strong - a.strong || a.r - b.r || b.s - a.s || a.i - b.i)\n .map((x) => x.it);\n\n/** `folder`: the More components view (its way back first, then the components, searched by `query`). */\nexport function useCatalog(query: string, allows: (f: RichTextFeature) => boolean, folder = false, own?: CatalogComponents | null) {\n const recent = useRecents();\n const provided = React.useContext(ComponentsContext);\n // the editor reads its own list (it renders the provider, so cannot read it)\n const lib = own === undefined ? provided : own;\n return React.useMemo(() => {\n const q = query.trim().toLowerCase().replace(/^\\//, \"\");\n const keep = (list: CatalogItem[]) => list.filter((it) => !it.id || blockAllowed(it.id, allows));\n const comps = (lib?.components ?? []).map(componentRow);\n let sections: CatalogSection[];\n let noMatch = false;\n let emptyText = \"No match.\";\n if (folder) {\n const found = q ? rank(q, comps, recent) : comps;\n noMatch = !!q && !!comps.length && !found.length;\n if (!comps.length) emptyText = lib?.error ?? (lib?.loading ? \"Loading components…\" : \"This field takes no components.\");\n sections = [{ title: null, items: [BACK] }, { title: \"Components\", items: found }];\n } else if (q) {\n const found = rank(q, [...keep(TEXT), ...keep(MEDIA), ...keep(DATA), ...keep(SEARCH_ONLY), ...comps], recent);\n noMatch = !found.length;\n sections = [{ title: null, items: found }];\n } else\n sections = [\n { title: \"Text\", items: keep(TEXT) },\n { title: \"Media\", items: keep(MEDIA) },\n { title: \"Data\", items: keep(DATA) },\n // offered while the list loads or failed too: opening it says which\n { title: null, items: lib && (comps.length || lib.loading || lib.error) ? [{ ...MORE, ...(comps.length ? { count: comps.length } : {}) }] : [] },\n ];\n sections = sections.filter((s) => s.items.length);\n const flat = sections.flatMap((s) => s.items);\n const empty = !flat.some((it) => it.kind !== \"back\");\n return { sections, flat, empty, noMatch, emptyText };\n }, [query, allows, recent, lib, folder]);\n}\n\n/* ── The list ───────────────────────────────────────────────────────────\n * Browsing: compact one-line rows (icon · name), grouped. Search results add the one-line description. */\nexport function CatalogList({\n sections,\n flat,\n active,\n onHover,\n onPick,\n empty,\n emptyText = \"No match.\",\n noMatch,\n detail,\n listId,\n className,\n}: {\n sections: CatalogSection[];\n flat: CatalogItem[];\n active: number;\n onHover: (i: number) => void;\n onPick: (it: CatalogItem) => void;\n empty: boolean;\n /** what an empty list says (\"No match.\", or why More components has none) */\n emptyText?: string;\n noMatch?: boolean;\n /** show each row's description (search results, More components) */\n detail?: boolean;\n listId: string;\n className?: string;\n}) {\n const box = React.useRef<HTMLDivElement>(null);\n React.useEffect(() => {\n // scroll only the list (scrollIntoView would also scroll the page behind a floating menu)\n const b = box.current;\n const row = b?.querySelector<HTMLElement>(`[data-idx=\"${active}\"]`);\n if (!b || !row) return;\n if (row.offsetTop < b.scrollTop) b.scrollTop = row.offsetTop - 6;\n else if (row.offsetTop + row.offsetHeight > b.scrollTop + b.clientHeight) b.scrollTop = row.offsetTop + row.offsetHeight - b.clientHeight + 6;\n }, [active]);\n return (\n <div ref={box} id={listId} role=\"listbox\" aria-label=\"Blocks\" className={cn(\"relative max-h-[320px] overflow-y-auto p-1.5\", className)}>\n {sections.map((s, si) => (\n <div\n key={s.title ?? `s${si}`}\n role=\"group\"\n aria-label={s.title ?? undefined}\n className={cn(!s.title && si > 0 && s.items[0]?.kind === \"folder\" && \"mt-1.5 border-t border-kit-line-subtle pt-1.5\")}\n >\n {s.title ? <div className=\"px-2 pb-0.5 pt-2 text-kit-2xs font-medium text-kit-fg-3\">{s.title}</div> : null}\n {s.items.map((it) => {\n const idx = flat.indexOf(it);\n const on = idx === active;\n const desc = detail && it.kind !== \"back\" && it.kind !== \"folder\" ? it.description : \"\";\n return (\n <button\n key={it.key}\n type=\"button\"\n role=\"option\"\n aria-selected={on}\n aria-description={!desc && it.description ? it.description : undefined}\n data-idx={idx}\n id={`${listId}-${idx}`}\n onMouseDown={(e) => e.preventDefault()}\n onMouseMove={() => !on && onHover(idx)}\n onClick={() => onPick(it)}\n className={cn(\n \"flex w-full items-center gap-2 rounded-kit-md px-2 text-left transition-colors\",\n desc ? \"py-1.5\" : \"h-8\",\n it.kind === \"back\" ? \"text-kit-fg-2\" : \"text-kit-fg\",\n on && \"bg-kit-hover text-kit-fg\",\n )}\n >\n <span className={cn(\"flex shrink-0 items-center justify-center text-kit-fg-2 [&_svg]:size-4\", desc ? \"size-7 rounded-kit-md border border-kit-line bg-kit-control-bg\" : \"size-5\")}>\n {it.icon}\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-kit-sm\">{it.label}</span>\n {desc ? <span className=\"block truncate text-kit-xs text-kit-fg-3\">{desc}</span> : null}\n </span>\n {it.count != null ? <span className=\"text-kit-2xs tabular-nums text-kit-fg-3\">{it.count}</span> : null}\n {it.kind === \"folder\" ? <IconChevronRight className=\"size-3.5 shrink-0 text-kit-fg-3\" stroke={1.5} aria-hidden /> : null}\n </button>\n );\n })}\n </div>\n ))}\n {empty || noMatch ? <div className=\"px-2 py-6 text-center text-kit-sm text-kit-fg-3\">{noMatch ? \"No match.\" : emptyText}</div> : null}\n </div>\n );\n}\n\nconst Footer = () => (\n <div data-hint=\"shortcuts\" className=\"flex h-7 shrink-0 items-center border-t border-kit-line px-3 text-kit-2xs text-kit-fg-3\">\n <span>\n <kbd className=\"font-kit-sans\">↵</kbd> select · type to search\n </span>\n </div>\n);\n\n/** Shared keyboard model: ↑↓ wrap, Home/End, Enter / Tab, → into More components. Returns true when handled. */\nexport function catalogKey(\n e: React.KeyboardEvent | KeyboardEvent,\n flat: CatalogItem[],\n active: number,\n setActive: (i: number) => void,\n pick: (it: CatalogItem) => void,\n homeEnd = true,\n) {\n const n = flat.length;\n if (!n) return false;\n if (e.key === \"ArrowDown\") return setActive((active + 1) % n), true;\n if (e.key === \"ArrowUp\") return setActive((active - 1 + n) % n), true;\n if (homeEnd && e.key === \"Home\") return setActive(0), true;\n if (homeEnd && e.key === \"End\") return setActive(n - 1), true;\n if (e.key === \"ArrowRight\" && flat[active]?.kind === \"folder\") return pick(flat[active]), true;\n if (e.key === \"Enter\" || e.key === \"Tab\") {\n const it = flat[active];\n if (it) pick(it);\n return true;\n }\n return false;\n}\n\n/* ── Insert menu (popover content for the toolbar \"Insert\" and the gutter \"+\") ─ */\nexport function InsertMenuContent({\n onInsert,\n allows,\n keepFocusOnClose,\n align = \"start\",\n side = \"bottom\",\n}: {\n onInsert: (it: CatalogItem) => void;\n allows: (f: RichTextFeature) => boolean;\n /** after an insert the caret stays in the editor: the menu gives no focus back to its trigger */\n keepFocusOnClose?: () => boolean;\n align?: \"start\" | \"center\" | \"end\";\n side?: \"top\" | \"bottom\" | \"left\" | \"right\";\n}) {\n const [q, setQ] = React.useState(\"\");\n const [active, setActive] = React.useState(0);\n const input = React.useRef<HTMLInputElement>(null);\n const listId = React.useId();\n const [folder, setFolder] = React.useState(false);\n const { sections, flat, empty, emptyText, noMatch } = useCatalog(q, allows, folder);\n // in More components the first row is the way back: the first component starts active\n React.useEffect(() => setActive(folder && flat.length > 1 ? 1 : 0), [q, folder]); // eslint-disable-line react-hooks/exhaustive-deps\n const leave = () => {\n setFolder(false);\n setQ(\"\");\n input.current?.focus();\n };\n const pick = (it: CatalogItem) => {\n if (it.kind === \"folder\") {\n setFolder(true);\n setQ(\"\");\n input.current?.focus();\n } else if (it.kind === \"back\") leave();\n else onInsert(it);\n };\n return (\n <PopoverContent\n side={side}\n align={align}\n className=\"flex max-h-[420px] w-[320px] flex-col overflow-hidden p-0\"\n initialFocus={input}\n finalFocus={keepFocusOnClose ? () => !keepFocusOnClose() : undefined}\n // Esc in More components steps back to every block, wherever focus sits in the menu (the list scrolls, so the\n // browser can focus it): caught before the popover's own Esc, which would close it\n onKeyDownCapture={(e) => {\n if (!folder || e.key !== \"Escape\") return;\n e.preventDefault();\n e.stopPropagation();\n leave();\n }}\n >\n <div className=\"flex h-10 shrink-0 items-center gap-2 border-b border-kit-line px-3\">\n <IconSearch className=\"size-4 shrink-0 text-kit-fg-3\" stroke={1.5} aria-hidden />\n <input\n ref={input}\n value={q}\n onChange={(e) => setQ(e.target.value)}\n onKeyDown={(e) => {\n if (folder && e.key === \"Backspace\" && !q) {\n // ⌫ in an empty search steps back to every block (Esc: the popup's capture above)\n e.preventDefault();\n e.stopPropagation();\n leave();\n } else if (catalogKey(e, flat, active, setActive, pick, !q)) e.preventDefault();\n }}\n role=\"combobox\"\n aria-expanded\n aria-controls={listId}\n aria-activedescendant={flat.length ? `${listId}-${active}` : undefined}\n aria-label={folder ? \"Search components\" : \"Search or pick a block\"}\n placeholder={folder ? \"Search components\" : \"Search or pick a block\"}\n className=\"h-full min-w-0 flex-1 bg-transparent text-kit-sm text-kit-fg outline-none placeholder:text-kit-fg-3\"\n />\n </div>\n <CatalogList\n sections={sections}\n flat={flat}\n active={active}\n onHover={setActive}\n onPick={pick}\n empty={empty}\n emptyText={emptyText}\n noMatch={noMatch}\n detail={!!q || folder}\n listId={listId}\n className=\"min-h-0 flex-1\"\n />\n <Footer />\n </PopoverContent>\n );\n}\n\n/* ── Slash menu panel (positioned by the editor; never takes focus) ── */\nexport function SlashMenuPanel({\n query,\n folder = false,\n active,\n setActive,\n onPick,\n allows,\n maxHeight,\n}: {\n /** the room the editor found for the menu (collision-aware); the list scrolls inside it */\n maxHeight?: number;\n query: string;\n /** the More components view (the editor keeps it with the rest of the slash state) */\n folder?: boolean;\n active: number;\n setActive: (i: number) => void;\n onPick: (it: CatalogItem) => void;\n allows: (f: RichTextFeature) => boolean;\n}) {\n const listId = React.useId();\n const { sections, flat, empty, emptyText, noMatch } = useCatalog(query, allows, folder);\n return (\n <div\n data-kit-scope=\"\"\n className=\"flex w-[320px] flex-col overflow-hidden rounded-kit-xl border border-kit-line bg-kit-surface text-kit-fg shadow-[0_1px_2px_rgb(16_16_16/0.04),0_8px_24px_-6px_rgb(16_16_16/0.12)] [.dark_&]:border-kit-line-strong [.dark_&]:bg-[#252528]\"\n style={maxHeight ? { maxHeight } : undefined}\n onMouseDown={(e) => e.preventDefault()}\n >\n <div className=\"flex h-8 shrink-0 items-center gap-2 border-b border-kit-line px-3 text-kit-sm\">\n <span className={cn(\"flex-1 truncate\", query ? \"text-kit-fg\" : \"text-kit-fg-3\")}>{query ? `${folder ? \"More components · \" : \"\"}/${query}` : folder ? \"More components\" : \"Type to search\"}</span>\n <kbd data-hint=\"shortcuts\" className=\"font-kit-sans text-kit-2xs text-kit-fg-3\">\n esc\n </kbd>\n </div>\n <CatalogList\n sections={sections}\n flat={flat}\n active={active}\n onHover={setActive}\n onPick={onPick}\n empty={empty}\n emptyText={emptyText}\n noMatch={noMatch}\n detail={!!query || folder}\n listId={listId}\n className=\"max-h-[300px] min-h-0 flex-1\"\n />\n <Footer />\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"codec.js","names":[],"sources":["../../../src/kit/controls/rich-text/codec.ts"],"sourcesContent":["/**\n * RICH TEXT · the storage contract between the kit editor and its host.\n *\n * The V2 editor edits HTML (contentEditable). Production stores Portable Text, in the shape the classic editor of the\n * same surface writes (a block array for an entry field, the `{ content, html }` envelope for a component prop). The\n * conversion lives in the host, which owns the real converters, schema conformance and the field's Accept config; the\n * kit never imports them. A host with no codec gets its own control for rich text (LegacyFallback), never a guess.\n *\n * The control opens a value only when it survives the trip editor → codec unchanged (`same`), so nothing the HTML\n * editor cannot hold (a checklist's ticks, a link's rel, an image's layout) is dropped by a first keystroke: such a\n * value is edited by the host's own control instead, with the reason named.\n */\nimport type { FieldPath, FieldSchema } from \"../../schema/types\";\n\n/** What a field may hold, in the editor's vocabulary. The editor offers nothing outside it. */\nexport type RichTextFeature =\n | \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\"\n | \"blockquote\" | \"ul\" | \"ol\" | \"pre\" | \"hr\"\n | \"bold\" | \"italic\" | \"underline\" | \"strike\" | \"code\"\n | \"link\" | \"image\"\n /* blocks, each stored as its own Portable Text block (see dom.ts) */\n | \"table\" | \"pullquote\" | \"takeaways\" | \"callout\" | \"toggle\" | \"video\" | \"file\";\n\nexport const ALL_FEATURES: readonly RichTextFeature[] = [\n \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\", \"blockquote\", \"ul\", \"ol\", \"pre\", \"hr\", \"bold\", \"italic\", \"underline\", \"strike\", \"code\", \"link\", \"image\",\n \"table\", \"pullquote\", \"takeaways\", \"callout\", \"toggle\", \"video\", \"file\",\n];\n\nexport interface RichTextRead {\n /** the HTML the editor opens on */\n html: string;\n /** the stored value as the classic editor would open it (compared against the editor's round trip) */\n seed: unknown;\n /** what this value already cannot carry from an earlier editor, in words (\"2 links\"); shown before the first edit */\n losses: string[];\n /** what the field accepts */\n features: RichTextFeature[];\n /** one paragraph, stored inline (allowMultipleParagraphs: false) */\n single: boolean;\n /** links may open in a new tab */\n newTab: boolean;\n}\n\nexport interface RichTextWrite {\n /** the value to store, in the surface's own shape */\n value: unknown;\n /** what the stored shape would drop from this HTML, in words; non-empty = the write is refused */\n losses: string[];\n}\n\nexport interface RichTextAt {\n field: FieldSchema;\n path: FieldPath;\n}\n\nexport interface KitRichTextCodec {\n read(value: unknown, at: RichTextAt): RichTextRead;\n /** `prev` is the stored value being replaced (its keys are reused so an edit does not re-key the document) */\n write(html: string, at: RichTextAt, prev: unknown): RichTextWrite;\n /** the same document, ignoring keys, span splits and storage wrapper */\n same(a: unknown, b: unknown): boolean;\n}\n\ndeclare module \"../../context\" {\n interface KitServices {\n /**\n * Stored rich text ↔ the HTML the kit editor edits (see controls/rich-text/codec.ts). Absent → a rich text field\n * draws the host's own control for it (LegacyControl).\n */\n richText?: KitRichTextCodec;\n }\n}\n"],"mappings":";AAuBA,IAAa,eAA2C;CACtD;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAc;CAAM;CAAM;CAAO;CAAM;CAAQ;CAAU;CAAa;CAAU;CAAQ;CAAQ;CACpI;CAAS;CAAa;CAAa;CAAW;CAAU;CAAS;CAClE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"component-card.js","names":[],"sources":["../../../src/kit/controls/rich-text/component-card.tsx"],"sourcesContent":["/**\n * The embedded component card (V2 features/blocks/instance-card.tsx + instance-ui.tsx StateChip / MissingNote / dialogs),\n * drawn when the host can look the component up (KitServices.useComponentInfo, component-services.ts):\n *\n * ┌ [icon] Inline CTA 🔗 2 places · ● Edited here ⋯ ┐ 36px strip\n * ├ ⚠ The original \"Product card\" was deleted. … [Keep as a separate copy] [Remove] ┤ missing only\n * │ the component itself, drawn live with this place's values (KitServices.ComponentPreview), else │\n * │ its snapshot where this place shows exactly that, else its fields; at most 240px, faded │\n * └──────────────────────────────────────────────────────────────────────────────┘\n *\n * Every state comes from the lookup or the stored copy: \"Missing component\" only when the library says there is no\n * such component, the count only when the host measured it, \"Edited here\" only for overrides of fields the component\n * has, \"Detached\" for a separate copy (V2 instances.ts `detached`), and \"Shared version changed\" only when the\n * component's current version (`info.publishedAt`) differs from the one the copy was taken from.\n *\n * A separate copy is made through the host (`copyComponent`, which answers what readers see now) and written as ONE\n * undo step (V2 detachNow: \"Make a separate copy\"); \"Use shared version again\" (V2 RelinkDialog) keeps this place's\n * edits as overrides or drops them, also one step. A host without `copyComponent` offers neither.\n *\n * Deviation from V2: V2 shows \"Shared version changed\" on a LINKED instance after a breaking release (instances.ts\n * `pending`). A linked instance here follows every publish of its component, so there is nothing to review; the\n * notice is drawn on a separate copy instead, whose source moved on, and it opens \"Use shared version again\".\n */\nimport * as React from \"react\";\nimport {\n IconAlertTriangle, IconArrowDown, IconArrowUp, IconComponents, IconCopy, IconDots, IconLayoutNavbarCollapse, IconLayoutNavbarExpand, IconLink,\n IconRefresh, IconTrash, IconUnlink,\n} from \"@tabler/icons-react\";\nimport { cn } from \"../../lib/cn\";\nimport { useKitServices, type KitServices } from \"../../context\";\nimport { Button, IconButton } from \"../../ui/button\";\nimport { Menu, MenuContent, MenuItem, MenuSeparator, MenuTrigger, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, Tooltip } from \"../../ui/overlay\";\nimport type { KitComponentField, KitComponentPreviewProps } from \"../component-services\";\nimport type { ComponentModel, IslandEl } from \"./dom\";\nimport type { IslandCtx } from \"./blocks\";\n\n/** V2 NARROW: at or under this card width the scope chip shows its icon only. */\nconst NARROW = 480;\n/** V2 PREVIEW_CAP: the preview at rest is at most this tall, faded when its content is taller. */\nconst PREVIEW_H = 240;\n\nconst placesShort = (n: number) => `${n} ${n === 1 ? \"place\" : \"places\"}`;\n\nfunction useWidth(ref: React.RefObject<HTMLElement | null>) {\n const [w, setW] = React.useState(0);\n React.useLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n setW(el.clientWidth);\n if (typeof ResizeObserver === \"undefined\") return;\n const ro = new ResizeObserver(() => setW(el.clientWidth));\n ro.observe(el);\n return () => ro.disconnect();\n }, [ref]);\n return w;\n}\n\n/** A stored value as one line of reading text, or null when it has none (lists, empty values, flags). */\nfunction readable(v: unknown): string | null {\n if (typeof v === \"number\") return String(v);\n if (typeof v === \"string\") {\n const t = v.replace(/<[^>]+>/g, \" \").replace(/ /g, \" \").replace(/\\s+/g, \" \").trim();\n return t || null;\n }\n if (v && typeof v === \"object\" && !Array.isArray(v)) {\n const o = v as { label?: unknown; text?: unknown; title?: unknown; href?: unknown };\n return readable(o.label ?? o.text ?? o.title ?? o.href);\n }\n return null;\n}\n\nconst parseObj = (s: string | undefined): Record<string, unknown> => {\n try {\n const v = s ? (JSON.parse(s) as unknown) : {};\n return v && typeof v === \"object\" && !Array.isArray(v) ? (v as Record<string, unknown>) : {};\n } catch {\n return {};\n }\n};\n/** True when `a` is a later instant than `b`; false when either is absent or unreadable (never a made-up \"changed\"). */\nconst laterThan = (a: string | null | undefined, b: string | undefined) => {\n const x = a ? Date.parse(a) : NaN;\n const y = b ? Date.parse(b) : NaN;\n return Number.isFinite(x) && Number.isFinite(y) && x > y;\n};\nconst same = (a: unknown, b: unknown) => a === b || JSON.stringify(a) === JSON.stringify(b);\n\ntype UseComponentInfo = NonNullable<KitServices[\"useComponentInfo\"]>;\ntype SetComponent = (patch: (m: ComponentModel) => ComponentModel, label: string, record?: boolean) => void;\n\nexport function ComponentCard({\n m, el, ctx, use, overrides, set,\n}: { m: ComponentModel; el: IslandEl; ctx: IslandCtx; use: UseComponentInfo; overrides: Record<string, unknown>; set: SetComponent }) {\n const { copyComponent, toast, ComponentPreview } = useKitServices();\n const { info, loading, error } = use(m.ref ?? \"\");\n const card = React.useRef<HTMLDivElement>(null);\n const width = useWidth(card);\n const narrow = !!width && width <= NARROW;\n const [collapsed, setCollapsed] = React.useState(false);\n const [dialog, setDialog] = React.useState<null | \"detach\" | \"relink\">(null);\n const [busy, setBusy] = React.useState(false);\n const detached = !!m.detached;\n const own = React.useMemo(() => parseObj(m.props), [m.props]);\n const missing = !m.ref || !!info?.missing;\n const name = info && !info.missing ? info.name : m.name || info?.name || \"Component\";\n const fieldKeys = new Set((info?.fields ?? []).map((f) => f.key));\n const edited = missing || detached ? 0 : Object.keys(overrides).filter((k) => fieldKeys.has(k)).length;\n const places = info?.places;\n const known = !!info || missing;\n // compared as instants, not strings: the same publish can be spelled two ways (precision, offset)\n const changed = detached && !missing && laterThan(info?.publishedAt, m.sourcePublishedAt);\n const state = detached ? `Detached${changed ? \", Shared version changed\" : \"\"}` : missing ? \"Missing component\" : edited ? \"Edited here\" : \"Shared\";\n const label = `${name} component${known ? `, ${state}` : \"\"}${known && !missing && !detached && places != null ? `, ${placesShort(places)}` : \"\"}`;\n const rows = detached ? copyRows(own, info?.fields, m.variant) : previewRows(missing, info?.fields, overrides, m.variant);\n // the picture is the component with its own values (the host's snapshot): drawn only where this place shows exactly\n // that. A separate copy, an edited place or another layout would be shown content it doesn't have, so those list\n // their values instead.\n const image = missing || detached || edited || m.variant ? null : info?.image || null;\n // V2 draws the component itself in the card, with this place's values (linked, edited or a separate copy): the host's\n // live renderer where it has one. Another layout lists its values (the renderer draws the component's own layout).\n const liveProps = React.useMemo(\n () => (detached ? own : { ...Object.fromEntries((info?.fields ?? []).flatMap((f) => (f.value !== undefined ? [[f.key, f.value]] : []))), ...overrides }),\n [detached, own, info?.fields, overrides],\n );\n const live = ComponentPreview && m.ref && info && !missing && !m.variant ? { Preview: ComponentPreview, ref: m.ref } : null;\n const preview = live ? (\n <LivePreview Preview={live.Preview} componentId={live.ref} title={name} props={liveProps} rows={rows} />\n ) : image || rows.length ? (\n <PreviewWindow image={image} rows={rows} />\n ) : null;\n const canCopy = !!copyComponent && !!m.ref && !ctx.readOnly;\n\n /**\n * The change as ONE undo step (IslandCtx.step: the dock's toolbar Undo, this toast's Undo and ⌘Z in the body are one\n * undo), and the toast that offers it back.\n */\n const commit = (patch: (cur: ComponentModel) => ComponentModel, label: string, title: string, description: string) => {\n const before = el.__rt as ComponentModel | undefined;\n const undo = ctx.step\n ? ctx.step(label, () => (set(patch, label, false), el), before)\n : (set(patch, label), () => (ctx.undo?.() ? (true as const) : \"Changes made after it come first. Press ⌘Z to undo them.\"));\n toast?.(title, {\n description,\n action: {\n label: \"Undo\",\n onClick: () => {\n const r = undo();\n if (r !== true) ctx.notify(\"Nothing was undone\", r);\n },\n },\n });\n };\n\n /** V2 detachNow: this place keeps what readers see now and stops following the component, as one undo step. */\n const detach = async (title: string) => {\n if (!copyComponent || !m.ref || busy) return;\n setBusy(true);\n try {\n const copy = await copyComponent(m.ref, { overrides, ...(m.variant ? { variant: m.variant } : {}) });\n commit(\n (cur) => ({\n id: cur.id,\n ref: cur.ref,\n ...(cur.name !== undefined || info?.name ? { name: cur.name ?? info?.name } : {}),\n ...(cur.variant !== undefined ? { variant: cur.variant } : {}),\n detached: true,\n props: JSON.stringify(copy.props),\n ...(copy.blocks !== undefined ? { blocks: copy.blocks } : {}),\n ...(copy.sourcePublishedAt ? { sourcePublishedAt: copy.sourcePublishedAt } : {}),\n ...(cur.extra !== undefined ? { extra: cur.extra } : {}),\n }),\n \"Make a separate copy\",\n title,\n \"It keeps its content and no longer follows the shared component.\",\n );\n } catch (e) {\n ctx.notify(\"This place couldn't keep its own copy\", e instanceof Error ? e.message : String(e));\n } finally {\n setBusy(false);\n }\n };\n\n /** V2 instanceOps.relink: keep = what differs from the component becomes overrides; reset = the component's content. */\n const relink = (mode: \"keep\" | \"reset\") => {\n const kept = copyEdits(m, own, info?.fields);\n const n = Object.keys(kept).length;\n commit(\n (cur) => ({\n id: cur.id,\n ref: cur.ref,\n ...(cur.name !== undefined ? { name: info?.name ?? cur.name } : {}),\n ...(mode === \"keep\" && Object.keys(kept).length ? { overrides: JSON.stringify(kept) } : {}),\n ...(mode === \"keep\" && cur.variant !== undefined ? { variant: cur.variant } : {}),\n ...(cur.extra !== undefined ? { extra: cur.extra } : {}),\n }),\n \"Use shared version again\",\n `${name} is shared again`,\n mode === \"keep\" && n ? `${n} ${n === 1 ? \"edit\" : \"edits\"} kept here.` : \"It shows the component's content.\",\n );\n };\n\n return (\n <div\n ref={card}\n role=\"group\"\n aria-label={label}\n aria-roledescription=\"component\"\n aria-busy={busy || undefined}\n data-instance-card=\"\"\n data-rt-isolate=\"\"\n data-state={detached ? \"detached\" : missing ? \"missing\" : known ? \"linked\" : undefined}\n className={cn(\n \"group/inst relative rounded-kit-lg border bg-kit-control-bg text-left transition-colors duration-150 motion-reduce:transition-none\",\n missing && !detached ? \"border-kit-warning-line\" : \"border-kit-line hover:border-kit-line-strong\",\n )}\n >\n <div className=\"flex h-9 select-none items-center gap-1.5 pl-1 pr-1\">\n <span className=\"w-1\" />\n <IconComponents size={15} stroke={1.5} className=\"shrink-0 text-kit-fg-2\" aria-hidden />\n <span className=\"min-w-0 shrink truncate text-kit-sm font-medium text-kit-fg\">{name}</span>\n {detached ? (\n <>\n <DetachedChip name={name} compact={narrow} />\n {changed ? <ChangedChip name={name} compact={narrow} onReview={canCopy ? () => setDialog(\"relink\") : undefined} /> : null}\n </>\n ) : known ? (\n <StateChip missing={missing} places={places} edited={edited} compact={narrow} />\n ) : null}\n <span className=\"flex-1\" />\n {ctx.readOnly ? null : (\n <Menu>\n <MenuTrigger\n render={\n <IconButton size=\"sm\" className=\"shrink-0\" label={`${name} actions`}>\n <IconDots stroke={1.5} />\n </IconButton>\n }\n />\n <MenuContent align=\"end\" className=\"w-56\">\n {preview ? (\n <MenuItem icon={collapsed ? <IconLayoutNavbarExpand stroke={1.5} /> : <IconLayoutNavbarCollapse stroke={1.5} />} onClick={() => setCollapsed(!collapsed)}>\n {collapsed ? \"Show preview\" : \"Collapse preview\"}\n </MenuItem>\n ) : null}\n {canCopy && info && !missing && !detached ? (\n <MenuItem icon={<IconUnlink stroke={1.5} />} disabled={busy} onClick={() => setDialog(\"detach\")}>\n Make a separate copy\n </MenuItem>\n ) : null}\n {canCopy && missing && !detached ? (\n <MenuItem icon={<IconUnlink stroke={1.5} />} disabled={busy} onClick={() => void detach(\"Kept as a separate copy\")}>\n Keep as a separate copy\n </MenuItem>\n ) : null}\n {canCopy && info && !missing && detached ? (\n <MenuItem icon={<IconLink stroke={1.5} />} onClick={() => setDialog(\"relink\")}>\n Use shared version again\n </MenuItem>\n ) : null}\n {ctx.duplicate ? (\n <MenuItem icon={<IconCopy stroke={1.5} />} onClick={() => ctx.duplicate?.(el)}>\n Duplicate\n </MenuItem>\n ) : null}\n {ctx.move ? (\n <>\n <MenuItem icon={<IconArrowUp stroke={1.5} />} disabled={!el.previousElementSibling} onClick={() => ctx.move?.(el, -1)}>\n Move up\n </MenuItem>\n <MenuItem icon={<IconArrowDown stroke={1.5} />} disabled={!el.nextElementSibling} onClick={() => ctx.move?.(el, 1)}>\n Move down\n </MenuItem>\n </>\n ) : null}\n <MenuSeparator />\n <MenuItem danger icon={<IconTrash stroke={1.5} />} onClick={() => ctx.remove(el)}>\n Remove\n </MenuItem>\n </MenuContent>\n </Menu>\n )}\n </div>\n {error ? (\n <div role=\"alert\" className=\"flex items-center gap-2 border-t border-kit-line-subtle px-3 py-2.5 text-kit-sm text-kit-fg-2\">\n <IconAlertTriangle className=\"size-4 shrink-0 text-kit-warning-fg\" stroke={1.5} aria-hidden />\n <span className=\"min-w-0 flex-1\">{error}</span>\n </div>\n ) : null}\n {missing && !detached && !loading ? (\n <div className=\"flex flex-wrap items-center gap-2 border-t border-kit-line-subtle px-3 py-2.5 text-kit-sm\" role=\"note\">\n <IconAlertTriangle className=\"size-4 shrink-0 text-kit-warning-fg\" stroke={1.5} aria-hidden />\n <span className=\"min-w-0 flex-1 text-kit-fg-2\">The original “{name}” was deleted. Readers see nothing in this place.</span>\n {ctx.readOnly ? null : (\n <span className=\"flex shrink-0 items-center gap-1.5\">\n {canCopy ? (\n <Button size=\"xs\" variant=\"secondary\" loading={busy} onClick={() => void detach(\"Kept as a separate copy\")}>\n Keep as a separate copy\n </Button>\n ) : null}\n <Button size=\"xs\" variant=\"danger-ghost\" onClick={() => ctx.remove(el)}>\n Remove\n </Button>\n </span>\n )}\n </div>\n ) : null}\n {collapsed ? null : preview}\n {canCopy ? (\n <>\n <DetachDialog\n open={dialog === \"detach\"}\n name={name}\n places={places}\n onClose={() => setDialog(null)}\n onConfirm={() => {\n setDialog(null);\n void detach(`Separate copy of ${name}`);\n }}\n />\n <RelinkDialog\n open={dialog === \"relink\"}\n name={name}\n kept={Object.keys(copyEdits(m, own, info?.fields)).length}\n onClose={() => setDialog(null)}\n onConfirm={(mode) => {\n setDialog(null);\n relink(mode);\n }}\n />\n </>\n ) : null}\n </div>\n );\n}\n\n/**\n * A separate copy's EDITS, which it keeps as overrides when it follows the component again: its values that differ from\n * the snapshot taken when the copy was made, never from the component as it is now (a republish since is not an edit\n * of this place; the owner saw \"2 fields stay as they are\" with nothing edited).\n *\n * A copy made here stores that snapshot: its values (`props`) with the blocks drawn from them (`blocks`), and no\n * surface edits a copy's values afterwards, so it has no edits. Copy markup from V2 stores no snapshot (no `blocks`):\n * its values that differ from the component's, on fields the component has (V2 instanceOps.relink).\n */\nfunction copyEdits(m: ComponentModel, own: Record<string, unknown>, fields: KitComponentField[] | undefined): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n if (m.blocks !== undefined) return out;\n for (const f of fields ?? []) if (f.key in own && !same(own[f.key], f.value)) out[f.key] = own[f.key];\n return out;\n}\n\n/** V2 StateChip: 13px, neutral, not a pill; the missing chip is the one tinted state. */\nfunction StateChip({ missing, places, edited, compact }: { missing: boolean; places?: number; edited: number; compact: boolean }) {\n const base = CHIP;\n if (missing) {\n return (\n <Tooltip content=\"The component was deleted. Readers see nothing in this place.\">\n <span className={cn(base, \"bg-kit-warning-soft px-1.5 text-kit-warning-fg\")}>\n <IconAlertTriangle className=\"size-3.5 shrink-0\" stroke={1.5} aria-hidden />\n {compact ? <span className=\"sr-only\">Missing component</span> : \"Missing component\"}\n </span>\n </Tooltip>\n );\n }\n const count = places ? placesShort(places) : null;\n const tip = `Changes here apply only to this place. Edit the component to change ${places && places > 1 ? `all ${places}` : \"it everywhere\"}.${\n edited ? ` ${edited} ${edited === 1 ? \"field\" : \"fields\"} edited here.` : \"\"\n }`;\n return (\n <Tooltip content={tip}>\n <span className={cn(base, \"px-1 text-kit-fg-2\")} tabIndex={-1}>\n <IconLink className=\"size-3.5 shrink-0\" stroke={1.5} aria-hidden />\n {compact ? <span className=\"sr-only\">Shared{count ? `, ${count}` : \"\"}</span> : count ?? \"Shared\"}\n {!compact && count ? <span className=\"sr-only\">, shared</span> : null}\n {edited ? (\n <>\n <span className=\"ml-1 size-1.5 shrink-0 rounded-full bg-kit-accent\" aria-hidden />\n {compact ? <span className=\"sr-only\">, edited here</span> : <span>Edited here</span>}\n </>\n ) : null}\n </span>\n </Tooltip>\n );\n}\n\nconst CHIP = \"inline-flex h-6 shrink-0 items-center gap-1 rounded-kit-md text-[13px] leading-none whitespace-nowrap\";\n\n/** V2 StateChip, detached: fg-3, the unlink glyph. */\nfunction DetachedChip({ name, compact }: { name: string; compact: boolean }) {\n return (\n <Tooltip content={`A separate copy. Changes to ${name} don't reach it.`}>\n <span className={cn(CHIP, \"px-1 text-kit-fg-3\")} tabIndex={-1}>\n <IconUnlink className=\"size-3.5 shrink-0\" stroke={1.5} aria-hidden />\n {compact ? <span className=\"sr-only\">Detached</span> : \"Detached\"}\n </span>\n </Tooltip>\n );\n}\n\n/** V2 StateChip, update: a quiet button that opens the way back to the shared version. */\nfunction ChangedChip({ name, compact, onReview }: { name: string; compact: boolean; onReview?: () => void }) {\n return (\n <Tooltip content={`${name} changed since this copy was made.`}>\n <button\n type=\"button\"\n onClick={onReview}\n disabled={!onReview}\n className={cn(CHIP, \"px-1 text-kit-fg-2 hover:bg-kit-hover hover:text-kit-fg disabled:hover:bg-transparent\")}\n >\n <IconRefresh className=\"size-3.5 shrink-0\" stroke={1.5} aria-hidden />\n {compact ? <span className=\"sr-only\">Shared version changed</span> : \"Shared version changed\"}\n </button>\n </Tooltip>\n );\n}\n\n/** V2 useInstanceDialogs \"detach\": confirm before this place stops following the component. */\nfunction DetachDialog({ open, name, places, onClose, onConfirm }: { open: boolean; name: string; places?: number; onClose: () => void; onConfirm: () => void }) {\n const others = places != null ? places - 1 : null;\n return (\n <Modal open={open} onOpenChange={(o) => !o && onClose()}>\n <ModalContent size=\"sm\">\n <ModalHeader title={`Make a separate copy of ${name}?`} description=\"This place keeps its current content and stops following the shared component.\" />\n {others != null ? (\n <ModalBody className=\"pt-2 text-kit-sm text-kit-fg-2\">\n {others > 0 ? `The other ${others === 1 ? \"place stays\" : `${others} places stay`} shared.` : \"No other place uses it.\"}\n </ModalBody>\n ) : null}\n <ModalFooter>\n <Button variant=\"ghost\" onClick={onClose}>\n Cancel\n </Button>\n <Button variant=\"primary\" autoFocus onClick={onConfirm}>\n Make a copy\n </Button>\n </ModalFooter>\n </ModalContent>\n </Modal>\n );\n}\n\n/** V2 RelinkDialog: keep this place's edits as overrides, or take the component's content. */\nfunction RelinkDialog({ open, name, kept, onClose, onConfirm }: { open: boolean; name: string; kept: number; onClose: () => void; onConfirm: (mode: \"keep\" | \"reset\") => void }) {\n const [mode, setMode] = React.useState<\"keep\" | \"reset\">(\"keep\");\n React.useEffect(() => {\n if (open) setMode(\"keep\");\n }, [open]);\n const rows: { v: \"keep\" | \"reset\"; title: string; line: string }[] = [\n {\n v: \"keep\",\n title: \"Keep my edits here\",\n line: kept ? `${kept} ${kept === 1 ? \"field stays\" : \"fields stay\"} as ${kept === 1 ? \"it is\" : \"they are\"}; everything else follows ${name} again.` : `Nothing differs, so it simply follows ${name} again.`,\n },\n { v: \"reset\", title: `Use ${name}'s content`, line: \"Drops the edits made here. Undo is one click away.\" },\n ];\n return (\n <Modal open={open} onOpenChange={(o) => !o && onClose()}>\n <ModalContent size=\"sm\">\n <ModalHeader title={`Use the shared ${name} again?`} description=\"This place follows the shared component again.\" />\n <ModalBody className=\"pt-3\">\n <div\n role=\"radiogroup\"\n aria-label=\"Use shared version again\"\n className=\"flex flex-col divide-y divide-kit-line overflow-hidden rounded-kit-lg border border-kit-line\"\n onKeyDown={(e) => {\n // a radio group moves with the arrow keys (one tab stop, the checked row)\n if (![\"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"].includes(e.key)) return;\n e.preventDefault();\n const next = mode === \"keep\" ? \"reset\" : \"keep\";\n setMode(next);\n (e.currentTarget.querySelector(`[data-mode=\"${next}\"]`) as HTMLElement | null)?.focus();\n }}\n >\n {rows.map((row) => (\n <button\n key={row.v}\n type=\"button\"\n role=\"radio\"\n data-mode={row.v}\n tabIndex={mode === row.v ? 0 : -1}\n aria-checked={mode === row.v}\n onClick={() => setMode(row.v)}\n className={cn(\"flex min-h-14 items-start gap-3 px-3 py-2.5 text-left transition-colors hover:bg-kit-hover\", mode === row.v && \"bg-kit-subtle\")}\n >\n <span className={cn(\"mt-0.5 flex size-4 shrink-0 items-center justify-center rounded-full border\", mode === row.v ? \"border-kit-control-checked\" : \"border-kit-line-strong\")}>\n {mode === row.v ? <span className=\"size-2 rounded-full bg-kit-fg\" /> : null}\n </span>\n <span className=\"min-w-0\">\n <span className=\"block text-kit-sm font-medium text-kit-fg\">{row.title}</span>\n <span className=\"block text-kit-xs text-kit-fg-3\">{row.line}</span>\n </span>\n </button>\n ))}\n </div>\n </ModalBody>\n <ModalFooter>\n <Button variant=\"ghost\" onClick={onClose}>\n Cancel\n </Button>\n <Button variant=\"primary\" onClick={() => onConfirm(mode)}>\n Use shared version\n </Button>\n </ModalFooter>\n </ModalContent>\n </Modal>\n );\n}\n\ninterface Row {\n key: string;\n label: string;\n text: string;\n}\n\n/**\n * What the window lists when there is no picture: each field's value as this place shows it (its override, else the\n * component's own), then the layout this place draws it in. A missing component has only what this place stored: its\n * overrides, named by their keys, and its layout.\n */\nfunction previewRows(missing: boolean, fields: KitComponentField[] | undefined, overrides: Record<string, unknown>, variant?: string): Row[] {\n const out: Row[] = [];\n if (missing || !fields) {\n for (const [key, v] of Object.entries(overrides)) {\n const text = readable(v);\n if (text) out.push({ key, label: key, text });\n }\n } else {\n for (const f of fields) {\n const text = readable(f.key in overrides ? overrides[f.key] : f.value);\n if (text) out.push({ key: f.key, label: f.label, text });\n }\n }\n if (variant) out.push({ key: \"__variant\", label: \"Layout\", text: variant });\n return out;\n}\n\n/**\n * A separate copy's values (V2 `props`) in the component's field order. A field the copy doesn't hold draws the\n * component's value for it, as V2's renderer does for a copy (it draws the def with `props`, defaults for the rest);\n * a value the component no longer has a field for follows, under its key. Then its layout.\n */\nfunction copyRows(own: Record<string, unknown>, fields: KitComponentField[] | undefined, variant?: string): Row[] {\n const out: Row[] = [];\n const push = (key: string, label: string, v: unknown) => {\n const text = readable(v);\n if (text) out.push({ key, label, text });\n };\n for (const f of fields ?? []) push(f.key, f.label, f.key in own ? own[f.key] : f.value);\n for (const [key, v] of Object.entries(own)) if (!fields?.some((f) => f.key === key)) push(key, key, v);\n if (variant) out.push({ key: \"__variant\", label: \"Layout\", text: variant });\n return out;\n}\n\n/** The preview's frame: under the card's header, at most PREVIEW_H tall. */\nconst PREVIEW_CHROME = \"relative overflow-hidden rounded-b-kit-lg border-t border-kit-line-subtle bg-kit-subtle\";\n\nfunction PreviewWindow({ image, rows }: { image: string | null; rows: Row[] }) {\n return (\n <div data-instance-preview=\"\" className={PREVIEW_CHROME} style={{ maxHeight: PREVIEW_H }}>\n <PreviewBody image={image} rows={rows} />\n </div>\n );\n}\n\n/**\n * The component drawn live by the host (KitServices.ComponentPreview), mounted once the card is on screen. Its height is\n * reserved from the start (PREVIEW_H), so the card never moves while it loads; where the host cannot draw it, the values\n * are listed under the reason.\n */\nfunction LivePreview({\n Preview,\n componentId,\n title,\n props,\n rows,\n}: {\n Preview: React.ComponentType<KitComponentPreviewProps>;\n componentId: string;\n title: string;\n props: Record<string, unknown>;\n rows: Row[];\n}) {\n const box = React.useRef<HTMLDivElement>(null);\n const [seen, setSeen] = React.useState(() => typeof IntersectionObserver === \"undefined\");\n React.useEffect(() => {\n const el = box.current;\n if (seen || !el) return;\n const io = new IntersectionObserver((entries) => {\n if (entries.some((e) => e.isIntersecting)) setSeen(true);\n });\n io.observe(el);\n return () => io.disconnect();\n }, [seen]);\n return (\n <div ref={box} data-instance-preview=\"\" data-live=\"\" className={PREVIEW_CHROME}>\n {seen ? (\n <Preview componentId={componentId} title={title} props={props} fallback={(reason) => <PreviewBody image={null} rows={rows} note={reason} />} />\n ) : (\n <div aria-hidden style={{ height: PREVIEW_H }} />\n )}\n </div>\n );\n}\n\nfunction PreviewBody({ image, rows, note }: { image: string | null; rows: Row[]; note?: string }) {\n const inner = React.useRef<HTMLDivElement>(null);\n const [tall, setTall] = React.useState(false);\n // a picture's height is unknown until it loads: the cap is held until then, so the card doesn't jump when it lands\n const [loaded, setLoaded] = React.useState(!image);\n React.useLayoutEffect(() => {\n const el = inner.current;\n if (!el) return;\n const on = () => setTall(el.scrollHeight > PREVIEW_H + 1);\n on();\n if (typeof ResizeObserver === \"undefined\") return;\n const ro = new ResizeObserver(on);\n ro.observe(el);\n return () => ro.disconnect();\n }, []);\n return (\n <div\n ref={inner}\n className={cn(tall && \"[mask-image:linear-gradient(to_bottom,black_calc(100%-24px),transparent)]\")}\n style={tall || !loaded ? { height: PREVIEW_H } : undefined}\n >\n {image ? (\n // the whole width, scaled to the card like V2's frame (top-left origin): never cropped at the sides\n <img src={image} alt=\"\" className=\"block h-auto w-full\" draggable={false} onLoad={() => setLoaded(true)} onError={() => setLoaded(true)} />\n ) : (\n <>\n {note ? <p className=\"px-4 pt-3 text-kit-xs text-kit-fg-3\">{note}</p> : null}\n <dl className=\"flex flex-col gap-3 px-4 py-3.5\">\n {rows.map((r) => (\n <div key={r.key} className=\"min-w-0\">\n <dt className=\"truncate text-kit-xs text-kit-fg-3\">{r.label}</dt>\n <dd className=\"mt-0.5 line-clamp-3 text-kit-sm text-kit-fg\">{r.text}</dd>\n </div>\n ))}\n </dl>\n </>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"control.js","names":[],"sources":["../../../src/kit/controls/rich-text/control.tsx"],"sourcesContent":["/**\n * Rich text field (V2 HEAD controls/richtext.tsx, CPO D49).\n * - The editor stays in place: the document variant is the full editor in the column, the panel variant (inspector)\n * the same editor height-capped.\n * - Expanding (the toolbar's expand button, ⌘↵, or the expand icon in the field's label row at rest) opens the shared\n * ExpandedEditorModal: breadcrumb \"Section › Item › Field\", word count, Done. Esc closes and focus returns.\n *\n * STORAGE. The editor edits HTML; the stored value stays what production stores for the field, through the host's\n * codec (KitServices.richText, see ./codec.ts):\n * - read: stored value → the HTML the editor opens on (+ what the field accepts)\n * - write: edited HTML → the stored value, in the surface's own shape; a write that would drop something is refused,\n * named, and nothing is stored\n * - probe: a value the editor cannot carry unchanged (open → no edit → write ≠ stored) is not opened here at all: the\n * host's own control edits it (LegacyFallback), with the reason above it. Opening never writes.\n */\nimport * as React from \"react\";\nimport { IconArrowsMaximize } from \"@tabler/icons-react\";\nimport { cn } from \"../../lib/cn\";\nimport { useForm, useKitEnv, useKitServices } from \"../../context\";\nimport { resolveFrames } from \"../../lib/frames\";\nimport { pathKey } from \"../../lib/path\";\nimport type { ControlProps } from \"../../types\";\nimport { Tooltip } from \"../../ui/overlay\";\nimport { LegacyFallback } from \"../../engine/kit-field\";\nimport type { KitRichTextCodec, RichTextRead } from \"./codec\";\nimport { editorRoundTrip } from \"./dom\";\nimport { RichTextEditor } from \"./editor\";\n\n/* ── which rich-text field (docKey) has its full editor open — shared with the label-row action ── */\nlet openKey: string | null = null;\nconst subs = new Set<() => void>();\nexport function setFullEditor(key: string | null) {\n openKey = key;\n subs.forEach((s) => s());\n}\nfunction useFullEditorKey() {\n return React.useSyncExternalStore(\n (cb) => {\n subs.add(cb);\n return () => subs.delete(cb);\n },\n () => openKey,\n () => openKey,\n );\n}\n\n/* ── fields whose value went to the host's own control: the label-row expand button is not theirs to draw ── */\nconst handedOff = new Set<string>();\nfunction setHandedOff(key: string, on: boolean) {\n if (handedOff.has(key) === on) return;\n if (on) handedOff.add(key);\n else handedOff.delete(key);\n subs.forEach((s) => s());\n}\nfunction useHandedOff(key: string) {\n return React.useSyncExternalStore(\n (cb) => {\n subs.add(cb);\n return () => subs.delete(cb);\n },\n () => handedOff.has(key),\n () => handedOff.has(key),\n );\n}\n\n/** The expanded editor's breadcrumb: the form's frames (root › drilled items) and this field. */\nfunction useExpandCrumbs(fieldTitle: string): string[] {\n const form = useForm();\n const env = useKitEnv();\n if (!form) return [env.docTitle, fieldTitle].filter(Boolean) as string[];\n const { frames } = resolveFrames(form.schema, form.value, form.path, form.resolveSchema);\n const titles = frames.filter((f) => f.kind !== \"history\").map((f, i) => (i === 0 ? env.docTitle || f.title : f.title));\n return [...titles, fieldTitle];\n}\n\n/** A stored block array, or the `{ content }` / `{ format, value }` envelope around one, holding a pull quote block. */\nconst holdsPullQuote = (seed: unknown): boolean =>\n Array.isArray(seed)\n ? seed.some((b) => !!b && typeof b === \"object\" && (b as { _type?: unknown })._type === \"pullQuote\")\n : !!seed && typeof seed === \"object\" && holdsPullQuote((seed as { content?: unknown; value?: unknown }).content ?? (seed as { value?: unknown }).value);\n\n/** What the control decided for one stored value. */\ntype Opened =\n | { ok: true; read: RichTextRead; html: string }\n | { ok: false; reason: string };\n\n/**\n * Open a stored value: read it, then prove the editor carries it unchanged (load → serialize → write === stored).\n * A codec that throws, or a value that does not survive, is handed to the host's own control with the reason.\n */\nexport function openValue(codec: KitRichTextCodec, value: unknown, at: Parameters<KitRichTextCodec[\"read\"]>[1]): Opened {\n let read: RichTextRead;\n try {\n read = codec.read(value, at);\n } catch (err) {\n return { ok: false, reason: `the stored text could not be read (${err instanceof Error ? err.message : String(err)})` };\n }\n // a pull quote (V2 D55 article block) opens as the editor's pull-quote island, but only when the codec renders the\n // stored block as its markup: a codec that renders nothing for it would lose it, so the standard editor edits it\n if (holdsPullQuote(read.seed) && !/data-rt=\"pullquote\"/.test(read.html))\n return { ok: false, reason: \"it holds a pull quote, which the standard editor edits\" };\n // tables and pull quotes are islands (V2 TableBlock, PullQuote); the probe below proves they survive unchanged\n const html = editorRoundTrip(read.html);\n try {\n const back = codec.write(html, at, value);\n if (back.losses.length) return { ok: false, reason: `this editor would drop ${back.losses.join(\", \")}` };\n if (!codec.same(back.value, read.seed)) return { ok: false, reason: \"it holds formatting this editor cannot keep\" };\n } catch (err) {\n return { ok: false, reason: `the text could not be checked (${err instanceof Error ? err.message : String(err)})` };\n }\n return { ok: true, read, html };\n}\n\nexport function RichTextControl(props: ControlProps) {\n const { richText } = useKitServices();\n if (!richText) return <LegacyFallback {...props} />;\n return <CodecRichText codec={richText} {...props} />;\n}\n\nfunction CodecRichText({ codec, field, value, onChange, readOnly, path, id, invalid }: ControlProps & { codec: KitRichTextCodec }) {\n const env = useKitEnv();\n const docKey = `${env.docId}:${pathKey(path)}`;\n const open = useFullEditorKey() === docKey;\n const crumbs = useExpandCrumbs(field.title);\n const at = React.useMemo(() => ({ field, path }), [field, path]);\n // the components this field may embed (More components): a hook with one identity for the form's life, so calling it\n // only when the host provides it keeps the hook order fixed\n const { useInsertableComponents } = useKitServices();\n const insertable = useInsertableComponents?.(at);\n /* our own last write: its value comes back as `value`, and the editor keeps the HTML it emitted (no reload, no probe) */\n const mine = React.useRef<{ value: unknown; html: string } | null>(null);\n const [refusal, setRefusal] = React.useState<string | null>(null);\n const opened = React.useMemo<Opened>(() => {\n if (mine.current && mine.current.value === value) {\n try {\n return { ok: true, read: codec.read(value, at), html: mine.current.html };\n } catch {\n /* judged afresh below, which names the failure */\n }\n }\n return openValue(codec, value, at);\n // `at` changes identity with the field object; the field's content is what matters\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [codec, value, JSON.stringify(field), pathKey(path)]);\n\n // close when this field goes away (block deselected, drilled elsewhere)\n React.useEffect(\n () => () => {\n if (openKey === docKey) setFullEditor(null);\n setHandedOff(docKey, false);\n },\n [docKey],\n );\n React.useLayoutEffect(() => {\n setHandedOff(docKey, !opened.ok);\n if (!opened.ok && openKey === docKey) setFullEditor(null);\n }, [docKey, opened.ok]);\n\n if (!opened.ok)\n return (\n <div className=\"flex min-w-0 flex-col gap-1.5\">\n <p role=\"note\" data-slot=\"kit-richtext-handoff\" className=\"rounded-kit-md bg-kit-subtle px-2.5 py-1.5 text-kit-xs text-kit-fg-2\">\n Edited with the standard editor: {opened.reason}.\n </p>\n <LegacyFallback field={field} value={value} onChange={onChange} readOnly={readOnly} path={path} id={id} invalid={invalid} />\n </div>\n );\n\n const { read, html } = opened;\n const write = (next: string) => {\n let res;\n try {\n res = codec.write(next, at, value);\n } catch (err) {\n setRefusal(`Not saved: the text could not be stored (${err instanceof Error ? err.message : String(err)}). Undo the last change with ⌘Z; leaving the field puts back the saved text.`);\n return;\n }\n if (res.losses.length) {\n setRefusal(`Not saved: this field cannot keep ${res.losses.join(\", \")}. Undo the last change with ⌘Z; leaving the field puts back the saved text.`);\n return;\n }\n setRefusal(null);\n if (codec.same(res.value, value)) return;\n mine.current = { value: res.value, html: next };\n onChange(res.value);\n };\n\n return (\n <div className=\"flex min-w-0 flex-col gap-1.5\">\n {read.losses.length ? (\n <p role=\"status\" className=\"rounded-kit-md bg-kit-warning-soft px-2.5 py-1.5 text-kit-xs text-kit-warning-fg\">\n Saved by an earlier editor. Editing here would drop {read.losses.join(\", \")}. Nothing changes until you edit.\n </p>\n ) : null}\n <RichTextEditor\n value={html}\n onChange={write}\n readOnly={readOnly}\n placeholder={field.placeholder}\n docKey={docKey}\n id={id}\n invalid={invalid || !!refusal}\n features={read.features}\n single={read.single}\n allowNewTab={read.newTab}\n components={insertable && !read.single && !readOnly ? insertable : undefined}\n variant={env.variant === \"document\" ? \"document\" : \"panel\"}\n maxHeight={env.variant === \"document\" ? undefined : 320}\n expandCrumbs={crumbs}\n expandedOpen={open}\n onExpandedOpenChange={(o) => setFullEditor(o ? docKey : null)}\n onComment={env.onComment ? () => env.onComment!(path, field) : undefined}\n />\n {refusal ? (\n <p role=\"alert\" className=\"text-kit-xs text-kit-danger-fg\">\n {refusal}\n </p>\n ) : null}\n </div>\n );\n}\n\n/** Label-row action (at rest): the field's toolbar holds the same button while it's open. */\nexport function RichTextExpandAction({ path, field }: ControlProps) {\n const env = useKitEnv();\n const { richText } = useKitServices();\n const handed = useHandedOff(`${env.docId}:${pathKey(path)}`);\n // the host's own control (no codec, or a value handed to it) has its own full-screen button\n if (env.variant === \"document\" || !richText || handed) return null;\n return (\n <Tooltip content=\"Expand editor\" shortcut=\"⌘↵\">\n <button\n type=\"button\"\n aria-label={`Expand ${field.title}`}\n onClick={() => setFullEditor(`${env.docId}:${pathKey(path)}`)}\n className={cn(\n \"-my-0.5 hidden size-6 items-center justify-center rounded-kit-md text-kit-fg-3 hover:bg-kit-hover hover:text-kit-fg\",\n \"group-hover/field:inline-flex group-focus-within/field:!hidden [@media(pointer:coarse)]:inline-flex\",\n )}\n >\n <IconArrowsMaximize className=\"size-3.5\" stroke={1.5} aria-hidden />\n </button>\n </Tooltip>\n );\n}\n"],"mappings":"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"}
|