@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
package/lib/path.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"path.js","names":[],"sources":["../../src/kit/lib/path.ts"],"sourcesContent":["/**\n * Immutable path helpers. A path addresses any value inside a document/block:\n * [\"items\", 1, \"answer\"] · [\"tabs\", 0, \"content\", 2, \"heading\"] · [\"title\", \"@history\"]\n * Writes share structure (only the spine is copied), so callers can diff top-level keys by identity.\n */\nimport type { FieldPath } from \"../schema/types\";\n\ntype Obj = Record<string, unknown>;\n\nexport const isObj = (v: unknown): v is Obj => !!v && typeof v === \"object\" && !Array.isArray(v);\n\nexport function getIn(root: unknown, path: FieldPath): unknown {\n let cur: unknown = root;\n for (const seg of path) {\n if (cur == null) return undefined;\n if (typeof seg === \"number\") cur = Array.isArray(cur) ? cur[seg] : undefined;\n else cur = isObj(cur) ? cur[seg] : undefined;\n }\n return cur;\n}\n\nexport function setIn<T>(root: T, path: FieldPath, value: unknown): T {\n if (path.length === 0) return value as T;\n const [head, ...rest] = path;\n if (typeof head === \"number\") {\n const arr = Array.isArray(root) ? root.slice() : [];\n arr[head] = setIn(arr[head], rest, value);\n return arr as unknown as T;\n }\n const obj: Obj = isObj(root) ? { ...root } : {};\n obj[head] = setIn(obj[head], rest, value);\n return obj as T;\n}\n\n/** \"items.1.answer\" — stable string key for maps (issues, presence, comments, history). */\nexport const pathKey = (p: FieldPath) => p.join(\".\");\n/**\n * The key of a frame (AnimatePresence key, `data-frame-body`, scroll memory, crumb key): \"root\" for the root frame,\n * else the path key. V2 used `pathKey(p) || \"root\"`, which collides when a root field is itself named `root`; that one\n * case gets \".root\", which no field path can produce (kit deviation, identical output for every other path).\n */\nexport const frameKeyOf = (p: FieldPath) => (p.length === 0 ? \"root\" : p.length === 1 && p[0] === \"root\" ? \".root\" : pathKey(p));\nexport const pathEq = (a: FieldPath, b: FieldPath) => a.length === b.length && a.every((s, i) => s === b[i]);\n/** `prefix` is an ancestor of (or equal to) `p`. */\nexport const isPrefix = (prefix: FieldPath, p: FieldPath) => prefix.length <= p.length && prefix.every((s, i) => s === p[i]);\nexport const keyStartsWith = (key: string, prefix: string) => prefix === \"\" || key === prefix || key.startsWith(`${prefix}.`);\n\nexport const same = (a: unknown, b: unknown) => {\n if (a === b) return true;\n try {\n return JSON.stringify(a ?? null) === JSON.stringify(b ?? null);\n } catch {\n return false;\n }\n};\n\nlet seq = 0;\nexport const newKey = () => `k${Date.now().toString(36).slice(-4)}${(seq++).toString(36)}${Math.random().toString(36).slice(2, 5)}`;\n\n/** Give every object item a `_key` (stable identity for drag and layout animation). Returns the same array when nothing changed. */\nexport function ensureKeys<T>(items: T[]): T[] {\n let changed = false;\n const out = items.map((it) => {\n if (isObj(it) && typeof it._key !== \"string\") {\n changed = true;\n return { _key: newKey(), ...it } as T;\n }\n return it;\n });\n return changed ? out : items;\n}\n\n/** A stable React/dnd id for an item (objects use `_key`, primitives their index). */\nexport const itemId = (it: unknown, i: number) => (isObj(it) && typeof it._key === \"string\" ? it._key : `i${i}`);\n"],"mappings":";AASA,IAAa,SAAS,MAAyB,CAAC,CAAC,KAAK,OAAO,MAAM,YAAY,CAAC,MAAM,QAAQ,EAAE;AAEhG,SAAgB,MAAM,MAAe,MAA0B;CAC7D,IAAI,MAAe;AACnB,MAAK,MAAM,OAAO,MAAM;AACtB,MAAI,OAAO,KAAM,QAAO,KAAA;AACxB,MAAI,OAAO,QAAQ,SAAU,OAAM,MAAM,QAAQ,IAAI,GAAG,IAAI,OAAO,KAAA;MAC9D,OAAM,MAAM,IAAI,GAAG,IAAI,OAAO,KAAA;;AAErC,QAAO;;AAGT,SAAgB,MAAS,MAAS,MAAiB,OAAmB;AACpE,KAAI,KAAK,WAAW,EAAG,QAAO;CAC9B,MAAM,CAAC,MAAM,GAAG,QAAQ;AACxB,KAAI,OAAO,SAAS,UAAU;EAC5B,MAAM,MAAM,MAAM,QAAQ,KAAK,GAAG,KAAK,OAAO,GAAG,EAAE;AACnD,MAAI,QAAQ,MAAM,IAAI,OAAO,MAAM,MAAM;AACzC,SAAO;;CAET,MAAM,MAAW,MAAM,KAAK,GAAG,EAAE,GAAG,MAAM,GAAG,EAAE;AAC/C,KAAI,QAAQ,MAAM,IAAI,OAAO,MAAM,MAAM;AACzC,QAAO;;;AAIT,IAAa,WAAW,MAAiB,EAAE,KAAK,IAAI;;;;;;AAMpD,IAAa,cAAc,MAAkB,EAAE,WAAW,IAAI,SAAS,EAAE,WAAW,KAAK,EAAE,OAAO,SAAS,UAAU,QAAQ,EAAE;AAC/H,IAAa,UAAU,GAAc,MAAiB,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,GAAG,MAAM,MAAM,EAAE,GAAG;AAG5G,IAAa,iBAAiB,KAAa,WAAmB,WAAW,MAAM,QAAQ,UAAU,IAAI,WAAW,GAAG,OAAO,GAAG;AAE7H,IAAa,QAAQ,GAAY,MAAe;AAC9C,KAAI,MAAM,EAAG,QAAO;AACpB,KAAI;AACF,SAAO,KAAK,UAAU,KAAK,KAAK,KAAK,KAAK,UAAU,KAAK,KAAK;SACxD;AACN,SAAO;;;AAIX,IAAI,MAAM;AACV,IAAa,eAAe,IAAI,KAAK,KAAK,CAAC,SAAS,GAAG,CAAC,MAAM,GAAG,IAAI,OAAO,SAAS,GAAG,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,GAAG,EAAE;;AAGjI,SAAgB,WAAc,OAAiB;CAC7C,IAAI,UAAU;CACd,MAAM,MAAM,MAAM,KAAK,OAAO;AAC5B,MAAI,MAAM,GAAG,IAAI,OAAO,GAAG,SAAS,UAAU;AAC5C,aAAU;AACV,UAAO;IAAE,MAAM,QAAQ;IAAE,GAAG;IAAI;;AAElC,SAAO;GACP;AACF,QAAO,UAAU,MAAM;;;AAIzB,IAAa,UAAU,IAAa,MAAe,MAAM,GAAG,IAAI,OAAO,GAAG,SAAS,WAAW,GAAG,OAAO,IAAI"}
|
package/lib/schema.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","names":[],"sources":["../../src/kit/lib/schema.ts"],"sourcesContent":["/**\n * Schema helpers — pure functions the engine uses to decide HOW a field is edited and WHAT a row shows.\n */\nimport type { Condition, FieldSchema, OpenMode, PrimitiveType, SchemaType, TypeSchema } from \"../schema/types\";\nimport { getIn, isObj, newKey } from \"./path\";\nimport { cellValue, isEmptyCell, isTableValue, tableSummary } from \"../schema/table\";\n\nconst PRIMITIVES: ReadonlySet<SchemaType> = new Set<PrimitiveType>([\n \"string\", \"text\", \"richtext\", \"number\", \"boolean\", \"slug\", \"url\", \"email\", \"date\", \"datetime\", \"color\", \"select\", \"multiselect\",\n \"tags\", \"image\", \"file\", \"video\", \"icon\", \"link\", \"button\", \"reference\", \"code\", \"json\", \"geopoint\", \"rating\", \"table\",\n]);\nexport const isPrimitive = (t: SchemaType) => PRIMITIVES.has(t);\n/** Types whose value is plain text (counters, AI rewrite, copy/paste as text). */\nexport const isTextual = (t: SchemaType) => t === \"string\" || t === \"text\" || t === \"richtext\" || t === \"slug\" || t === \"url\" || t === \"email\";\n/** Types that are cheap to show inline inside a small object (no heavy surfaces). */\nconst INLINE_OK: ReadonlySet<SchemaType> = new Set([\"string\", \"number\", \"boolean\", \"select\", \"color\", \"icon\", \"url\", \"email\", \"date\", \"rating\", \"slug\"]);\n\nexport const itemSchemas = (f: FieldSchema): FieldSchema[] => (Array.isArray(f.of) ? f.of : []);\nexport const slotAllow = (f: FieldSchema): string[] | undefined => (f.of && !Array.isArray(f.of) ? f.of.allow : undefined);\nexport const itemSchemaFor = (f: FieldSchema, item: unknown): FieldSchema | undefined => {\n const of = itemSchemas(f);\n if (isObj(item) && typeof item._type === \"string\") return of.find((o) => o.name === item._type) ?? of[0];\n return of[0];\n};\n/** An array whose single item type is a primitive (tags, gallery, references, list of strings). */\nexport const primitiveItem = (f: FieldSchema): FieldSchema | undefined => {\n const of = itemSchemas(f);\n return of.length === 1 && isPrimitive(of[0].type) ? of[0] : undefined;\n};\nexport const isSmallObject = (fields: FieldSchema[] = []) => fields.length > 0 && fields.length <= 3 && fields.every((f) => INLINE_OK.has(f.type));\n\n/** How an object field / array item opens (CPO D8: inline for ≤3 primitives, else drill). */\nexport function objectOpenMode(f: FieldSchema): OpenMode {\n if (f.openMode) return f.openMode;\n return isSmallObject(f.fields) ? \"inline\" : \"drill\";\n}\n/**\n * CPO D43 — one rule for rows: an item of ≤3 simple fields (text, number, switch, select, colour, icon, url, email,\n * date, rating, slug) EXPANDS inline under its row; anything bigger, nested or rich DRILLS into its own frame.\n * `openMode` on the array still wins (developer override). Several item types → drill (they rarely share a shape).\n */\nexport function itemOpenMode(arrayField: FieldSchema): OpenMode {\n if (arrayField.openMode) return arrayField.openMode;\n const of = itemSchemas(arrayField);\n return of.length === 1 && isSmallObject(of[0].fields) ? \"inline\" : \"drill\";\n}\n\nexport function emptyFor(f: FieldSchema): unknown {\n switch (f.type) {\n case \"boolean\": return false;\n case \"number\": case \"rating\": return null;\n case \"multiselect\": case \"tags\": case \"array\": case \"slot\": return [];\n case \"object\": return objectInitial(f.fields ?? []);\n case \"image\": case \"file\": case \"video\": case \"reference\": case \"link\": case \"button\": case \"geopoint\": case \"json\": case \"table\": return null;\n default: return \"\";\n }\n}\nexport const initialFor = (f: FieldSchema) => (f.initialValue !== undefined ? structuredCloneSafe(f.initialValue) : emptyFor(f));\nexport function objectInitial(fields: FieldSchema[]): Record<string, unknown> {\n const o: Record<string, unknown> = {};\n for (const f of fields) if (f.initialValue !== undefined) o[f.name] = structuredCloneSafe(f.initialValue);\n return o;\n}\n/** A new array item for `itemSchema` (stamped with `_key` and, when the array allows several types, `_type`). */\nexport function newItem(arrayField: FieldSchema, itemSchema: FieldSchema): unknown {\n if (isPrimitive(itemSchema.type)) return initialFor(itemSchema);\n const base = itemSchema.initialValue && isObj(itemSchema.initialValue) ? structuredCloneSafe(itemSchema.initialValue) : objectInitial(itemSchema.fields ?? []);\n const multi = itemSchemas(arrayField).length > 1;\n return { _key: newKey(), ...(multi ? { _type: itemSchema.name } : {}), ...(base as object) };\n}\nexport function newBlock(block: TypeSchema, settings?: FieldSchema[]): Record<string, unknown> {\n const init = block.initialValue ? structuredCloneSafe(block.initialValue) : objectInitial(block.fields);\n const s = settings?.length ? { _settings: objectInitial(settings) } : {};\n return { _key: newKey(), _type: block.name, ...(block.variants?.[0] ? { _variant: block.variants[0].id } : {}), ...s, ...(init as object) };\n}\nexport function structuredCloneSafe<T>(v: T): T {\n try {\n return structuredClone(v);\n } catch {\n return JSON.parse(JSON.stringify(v)) as T;\n }\n}\n\n/* ── Conditions ───────────────────────────────────────────────────────── */\n/** `hidden: true` hides; a Condition SHOWS the field only when the sibling matches (types.ts contract). */\nexport function isHidden(f: FieldSchema, parent: unknown): boolean {\n if (f.hidden === true) return true;\n if (!f.hidden) return false;\n const c = f.hidden as Condition;\n const sib = isObj(parent) ? parent[c.field] : undefined;\n if (c.notEmpty) return isEmptyValue(sib);\n if (c.equals !== undefined) {\n const list = Array.isArray(c.equals) ? c.equals : [c.equals];\n return !list.includes(sib as never);\n }\n return false;\n}\n\n/* ── Values → text ────────────────────────────────────────────────────── */\n/** Portable Text blocks' text, one block per space; \"\" when the array holds no blocks (a list of items). */\nconst blocksText = (v: unknown[]): string =>\n v\n .map((b) => (isObj(b) && Array.isArray(b.children) ? b.children.map((c) => (isObj(c) && typeof c.text === \"string\" ? c.text : \"\")).join(\"\") : \"\"))\n .filter(Boolean)\n .join(\" \")\n .replace(/\\s+/g, \" \")\n .trim();\n/**\n * A value as one line of text. Stored rich text reads as its words in every shape production keeps: an html string,\n * Portable Text blocks, and the component props envelope `{ content: { version, content: blocks }, html }`.\n */\nexport const plainText = (v: unknown): string => {\n if (typeof v === \"string\") return v.replace(/<[^>]*>/g, \" \").replace(/ /g, \" \").replace(/\\s+/g, \" \").trim();\n if (typeof v === \"number\") return String(v);\n if (Array.isArray(v)) return blocksText(v);\n if (isObj(v)) {\n if (typeof v.label === \"string\" && v.label) return v.label;\n if (typeof v.title === \"string\") return v.title;\n if (typeof v.href === \"string\") return v.href;\n if (typeof v.name === \"string\") return v.name;\n // the envelope's blocks first: their text is unescaped (the html holds `&`)\n if (\"content\" in v && typeof v.content === \"object\" && v.content !== null) {\n const t = plainText(v.content);\n if (t) return t;\n }\n if (typeof v.html === \"string\") return plainText(v.html);\n }\n return \"\";\n};\nexport function isEmptyValue(v: unknown): boolean {\n if (v == null) return true;\n if (typeof v === \"string\") return plainText(v) === \"\" && !/<img|<hr|<table|data-block|data-embed/.test(v);\n if (Array.isArray(v)) return v.length === 0;\n if (isTableValue(v)) return !v.caption?.trim() && v.rows.every((r) => Object.values(r.cells ?? {}).every((c) => isEmptyCell(cellValue(c))));\n if (isObj(v)) {\n if (\"url\" in v) return !v.url;\n if (\"href\" in v && !(\"label\" in v)) return !v.href;\n if (\"label\" in v && \"href\" in v) return !v.label && !v.href;\n return Object.keys(v).filter((k) => !k.startsWith(\"_\")).every((k) => isEmptyValue(v[k]));\n }\n return false;\n}\nexport const imageUrl = (v: unknown): string | undefined =>\n typeof v === \"string\" && /^(https?:|blob:|data:image|\\/)/.test(v) ? v : isObj(v) && typeof v.url === \"string\" && v.url ? v.url : undefined;\n\n/** Singular noun for an array's items: itemNoun → item title → field title minus \"s\". */\nexport function itemNoun(f: FieldSchema): string {\n if (f.itemNoun) return f.itemNoun;\n const of = itemSchemas(f);\n if (of.length === 1 && of[0].title && !isPrimitive(of[0].type)) return of[0].title.toLowerCase();\n const t = f.title.toLowerCase();\n return t.endsWith(\"ies\") ? `${t.slice(0, -3)}y` : t.endsWith(\"s\") ? t.slice(0, -1) : \"item\";\n}\n\n/* ── Previews (array rows, slot rows, crumbs) ─────────────────────────── */\nexport interface Preview {\n title: string;\n subtitle?: string;\n media?: string;\n icon?: string;\n empty: boolean;\n}\n/** Display text of one field value (select → option label). */\nfunction fieldText(f: FieldSchema | undefined, v: unknown): string {\n if (f?.type === \"select\") return f.options?.find((o) => o.value === v)?.label ?? plainText(v);\n return plainText(v);\n}\nfunction firstText(fields: FieldSchema[], v: Record<string, unknown>, skip?: string) {\n for (const f of fields) {\n if (f.name === skip) continue;\n if (f.type === \"select\") {\n const t = fieldText(f, v[f.name]);\n if (t) return { name: f.name, text: t };\n }\n if (f.type === \"string\" || f.type === \"text\" || f.type === \"richtext\" || f.type === \"number\") {\n const t = plainText(v[f.name]);\n if (t) return { name: f.name, text: t };\n }\n if (f.type === \"button\" || f.type === \"link\") {\n const t = plainText(v[f.name]);\n if (t) return { name: f.name, text: t };\n }\n }\n // no prose anywhere: a URL or address still beats \"Item 3\" (D47 — item titles use the first text value)\n for (const f of fields) {\n if (f.name === skip || (f.type !== \"url\" && f.type !== \"email\" && f.type !== \"slug\")) continue;\n const t = plainText(v[f.name]);\n if (t) return { name: f.name, text: t };\n }\n return undefined;\n}\nexport function previewOf(itemSchema: FieldSchema | TypeSchema | undefined, item: unknown, index: number, fallbackTitle?: string): Preview {\n const v = isObj(item) ? item : {};\n const fields = (itemSchema && \"fields\" in itemSchema ? itemSchema.fields : undefined) ?? [];\n const cfg = itemSchema?.preview;\n const at = (p: string) => fieldText(fields.find((f) => f.name === p), getIn(v, p.split(\".\")));\n let title = cfg?.title ? at(cfg.title) : \"\";\n let titleField = cfg?.title;\n if (!title) {\n const t = firstText(fields, v);\n title = t?.text ?? \"\";\n titleField = t?.name;\n }\n let subtitle = cfg?.subtitle ? at(cfg.subtitle) : \"\";\n if (!subtitle && !cfg?.subtitle) subtitle = firstText(fields, v, titleField)?.text ?? \"\";\n let media = cfg?.media ? imageUrl(getIn(v, cfg.media.split(\".\"))) : undefined;\n if (!media && !cfg?.media) {\n const img = fields.find((f) => f.type === \"image\");\n if (img) media = imageUrl(v[img.name]);\n }\n const empty = !title;\n const noun = fallbackTitle ?? (itemSchema?.title ?? \"Item\");\n return {\n title: title || cfg?.fallback || `${noun} ${index + 1}`,\n subtitle: subtitle ? (subtitle.length > 90 ? `${subtitle.slice(0, 88)}…` : subtitle) : undefined,\n media,\n icon: cfg?.icon ?? (itemSchema as FieldSchema | undefined)?.icon,\n empty,\n };\n}\n\n/** \"Cast iron · 4 items\" — one-line summary of an object for collapsed rows and fieldset headers. */\nexport function summarize(fields: FieldSchema[], v: unknown, max = 2): string {\n if (!isObj(v)) return \"\";\n const parts: string[] = [];\n for (const f of fields) {\n if (parts.length >= max) break;\n const x = v[f.name];\n if (isEmptyValue(x)) continue;\n if (f.type === \"reference\" || f.type === \"json\" || f.type === \"code\" || f.type === \"image\" || f.type === \"file\") continue; // ids and blobs read badly\n if (f.type === \"table\") {\n parts.push(tableSummary(x));\n continue;\n }\n if (f.type === \"rating\" && typeof x === \"number\") {\n parts.push(`${x} / 5`);\n continue;\n }\n if (Array.isArray(x)) parts.push(`${x.length} ${x.length === 1 ? itemNounSafe(f) : `${itemNounSafe(f)}s`}`);\n else if (typeof x === \"boolean\") parts.push(`${f.title}: ${x ? \"on\" : \"off\"}`);\n else {\n const t = fieldText(f, x);\n if (t) parts.push(t.length > 40 ? `${t.slice(0, 38)}…` : t);\n }\n }\n return parts.join(\" · \");\n}\nconst itemNounSafe = (f: FieldSchema) => (f.type === \"array\" || f.type === \"slot\" ? itemNoun(f) : \"item\");\n"],"mappings":"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"}
|
package/lib/utils.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","names":[],"sources":["../../src/kit/lib/utils.ts"],"sourcesContent":["export const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));\nexport const uid = (p = \"id\") => `${p}_${Math.random().toString(36).slice(2, 9)}`;\nexport function formatNumber(n: number) {\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(n >= 10_000_000 ? 0 : 1)}M`;\n if (n >= 1000) return `${(n / 1000).toFixed(n >= 10000 ? 0 : 1)}k`;\n return `${n}`;\n}\nexport function plural(n: number, one: string, many = `${one}s`) {\n return `${n} ${n === 1 ? one : many}`;\n}\nexport function initials(name: string) {\n return name.split(/\\s+/).map((p) => p[0]).slice(0, 2).join(\"\").toUpperCase();\n}\nexport function relTime(iso: string | number | Date) {\n const d = new Date(iso).getTime();\n const s = Math.round((Date.now() - d) / 1000);\n if (s < 45) return \"just now\";\n const m = Math.round(s / 60); if (m < 60) return `${m}m ago`;\n const h = Math.round(m / 60); if (h < 24) return `${h}h ago`;\n const days = Math.round(h / 24); if (days < 7) return `${days}d ago`;\n const w = Math.round(days / 7); if (w < 5) return `${w}w ago`;\n return new Date(iso).toLocaleDateString(\"en-US\", { month: \"short\", day: \"numeric\", year: \"numeric\" });\n}\nexport const slugify = (s: string) => s.toLowerCase().trim().replace(/[^a-z0-9]+/g, \"-\").replace(/^-|-$/g, \"\");\n"],"mappings":";AAAA,IAAa,SAAS,OAAe,IAAI,SAAS,MAAM,WAAW,GAAG,GAAG,CAAC;AAC1E,IAAa,OAAO,IAAI,SAAS,GAAG,EAAE,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,GAAG,EAAE;AAC/E,SAAgB,aAAa,GAAW;AACtC,KAAI,KAAK,IAAW,QAAO,IAAI,IAAI,KAAW,QAAQ,KAAK,MAAa,IAAI,EAAE,CAAC;AAC/E,KAAI,KAAK,IAAM,QAAO,IAAI,IAAI,KAAM,QAAQ,KAAK,MAAQ,IAAI,EAAE,CAAC;AAChE,QAAO,GAAG;;AAEZ,SAAgB,OAAO,GAAW,KAAa,OAAO,GAAG,IAAI,IAAI;AAC/D,QAAO,GAAG,EAAE,GAAG,MAAM,IAAI,MAAM;;AAEjC,SAAgB,SAAS,MAAc;AACrC,QAAO,KAAK,MAAM,MAAM,CAAC,KAAK,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,KAAK,GAAG,CAAC,aAAa;;AAE9E,SAAgB,QAAQ,KAA6B;CACnD,MAAM,IAAI,IAAI,KAAK,IAAI,CAAC,SAAS;CACjC,MAAM,IAAI,KAAK,OAAO,KAAK,KAAK,GAAG,KAAK,IAAK;AAC7C,KAAI,IAAI,GAAI,QAAO;CACnB,MAAM,IAAI,KAAK,MAAM,IAAI,GAAG;AAAE,KAAI,IAAI,GAAI,QAAO,GAAG,EAAE;CACtD,MAAM,IAAI,KAAK,MAAM,IAAI,GAAG;AAAE,KAAI,IAAI,GAAI,QAAO,GAAG,EAAE;CACtD,MAAM,OAAO,KAAK,MAAM,IAAI,GAAG;AAAE,KAAI,OAAO,EAAG,QAAO,GAAG,KAAK;CAC9D,MAAM,IAAI,KAAK,MAAM,OAAO,EAAE;AAAE,KAAI,IAAI,EAAG,QAAO,GAAG,EAAE;AACvD,QAAO,IAAI,KAAK,IAAI,CAAC,mBAAmB,SAAS;EAAE,OAAO;EAAS,KAAK;EAAW,MAAM;EAAW,CAAC;;AAEvG,IAAa,WAAW,MAAc,EAAE,aAAa,CAAC,MAAM,CAAC,QAAQ,eAAe,IAAI,CAAC,QAAQ,UAAU,GAAG"}
|
package/lib/validate.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"validate.js","names":[],"sources":["../../src/kit/lib/validate.ts"],"sourcesContent":["/**\n * Validation — rules live in the schema (`validation`), messages state the rule in plain words.\n * Two kinds: \"required\" (shown after blur or a publish attempt) and \"rule\" (shown on blur too, never while\n * typing for the first time — the shell decides). Warnings (recommendedMax, missing alt) never block publish.\n */\nimport type { FieldPath, FieldSchema, TypeSchema } from \"../schema/types\";\nimport { isObj, pathKey } from \"./path\";\nimport { tableIssues } from \"../schema/table\";\nimport { isEmptyValue, isHidden, itemSchemaFor, plainText, primitiveItem } from \"./schema\";\n\nexport interface KitIssue {\n key: string;\n path: FieldPath;\n level: \"error\" | \"warning\";\n kind: \"required\" | \"rule\";\n message: string;\n}\ntype Raw = Omit<KitIssue, \"key\" | \"path\">;\n\nexport const textLength = (v: unknown) => plainText(v).length;\nconst counted = (f: FieldSchema) => f.type === \"string\" || f.type === \"text\" || f.type === \"richtext\";\n\n/** Validate one value against its field (not recursing into children). */\nexport function validateValue(f: FieldSchema, v: unknown): Raw | null {\n const r = f.validation ?? {};\n const label = f.title;\n if (r.required && isEmptyValue(v)) {\n const msg =\n f.type === \"image\" ? `Add an image for ${label.toLowerCase()}` :\n f.type === \"reference\" ? `Choose ${label.toLowerCase()}` :\n f.type === \"array\" || f.type === \"slot\" ? `Add at least one item to ${label.toLowerCase()}` :\n `${label} is required`;\n return { level: \"error\", kind: \"required\", message: msg };\n }\n if (isEmptyValue(v)) return null;\n\n if (counted(f)) {\n const n = textLength(v);\n if (r.max && n > r.max) return { level: \"error\", kind: \"rule\", message: `Keep it under ${r.max} characters (${n - r.max} over)` };\n if (r.min && n < r.min) return { level: \"error\", kind: \"rule\", message: `Use at least ${r.min} characters` };\n if (r.recommendedMax && n > r.recommendedMax)\n return { level: \"warning\", kind: \"rule\", message: `Longer than the recommended ${r.recommendedMax} characters. It may get cut off.` };\n }\n if ((f.type === \"array\" || f.type === \"slot\" || f.type === \"tags\" || f.type === \"multiselect\") && Array.isArray(v)) {\n if (r.min && v.length < r.min) return { level: \"error\", kind: \"rule\", message: `Add at least ${r.min} ${r.min === 1 ? \"item\" : \"items\"}` };\n if (r.max && v.length > r.max) return { level: \"error\", kind: \"rule\", message: `Use at most ${r.max} items` };\n }\n if (f.type === \"number\" && typeof v === \"number\") {\n const lo = r.min ?? f.numeric?.min;\n const hi = r.max ?? f.numeric?.max;\n if (lo != null && v < lo) return { level: \"error\", kind: \"rule\", message: `Use ${lo} or more` };\n if (hi != null && v > hi) return { level: \"error\", kind: \"rule\", message: `Use ${hi} or less` };\n }\n if (typeof v === \"string\") {\n if (f.type === \"email\" && !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(v)) return { level: \"error\", kind: \"rule\", message: \"Use a full email address, like hello@caldera.com\" };\n if (f.type === \"url\" && !/^(https?:\\/\\/|\\/|#|mailto:|tel:)[^\\s]*$/.test(v)) return { level: \"error\", kind: \"rule\", message: \"Use a full URL, like https://example.com, or a path like /shop\" };\n if (f.type === \"url\" && /^(javascript|data):/i.test(v)) return { level: \"error\", kind: \"rule\", message: \"This kind of link isn't allowed\" };\n if (f.type === \"slug\" && !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(v)) return { level: \"error\", kind: \"rule\", message: \"Use lowercase letters, numbers and hyphens\" };\n if (f.type === \"json\") {\n try {\n JSON.parse(v);\n } catch {\n return { level: \"error\", kind: \"rule\", message: \"Invalid JSON\" };\n }\n }\n if (r.pattern && !new RegExp(r.pattern).test(v)) return { level: \"error\", kind: \"rule\", message: r.patternMessage ?? \"This doesn't match the expected format\" };\n }\n if (f.type === \"table\") {\n // caption, header labels, typed cells, row limits, markup readiness (src/schema/table.ts) — first error wins\n const issues = tableIssues(v, { ...f.table, minRows: f.table?.minRows ?? r.min, maxRows: f.table?.maxRows ?? r.max });\n const first = issues.find((i) => i.level === \"error\") ?? issues[0];\n if (first) return { level: first.level, kind: \"rule\", message: first.message };\n }\n if (f.type === \"image\" && isObj(v) && v.url && !v.alt && r.required) return { level: \"warning\", kind: \"rule\", message: \"No alt text. Describe the image for accessibility.\" };\n return null;\n}\n\n/** Walk fields under `obj` and collect every issue, recursing into objects, array items and slot blocks. */\nexport function collectIssues(\n fields: FieldSchema[],\n obj: unknown,\n base: FieldPath,\n resolveSchema?: (t: string) => TypeSchema | undefined,\n out: KitIssue[] = [],\n): KitIssue[] {\n const v = isObj(obj) ? obj : {};\n for (const f of fields) {\n if (isHidden(f, v)) continue;\n const p = [...base, f.name];\n const val = v[f.name];\n const raw = validateValue(f, val);\n if (raw) out.push({ ...raw, key: pathKey(p), path: p });\n if (f.type === \"object\" && f.fields) collectIssues(f.fields, val, p, resolveSchema, out);\n if (f.type === \"array\" && Array.isArray(val) && !primitiveItem(f)) {\n val.forEach((it, i) => {\n const s = itemSchemaFor(f, it);\n if (s?.fields) collectIssues(s.fields, it, [...p, i], resolveSchema, out);\n });\n }\n if (f.type === \"slot\" && Array.isArray(val) && resolveSchema) {\n val.forEach((it, i) => {\n const b = isObj(it) && typeof it._type === \"string\" ? resolveSchema(it._type) : undefined;\n if (b) collectIssues(b.fields, it, [...p, i], resolveSchema, out);\n if (f.slotSettings && isObj(it)) collectIssues(f.slotSettings, it._settings, [...p, i, \"_settings\"], resolveSchema, out);\n });\n }\n }\n return out;\n}\n"],"mappings":"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"}
|
package/schema/adapters.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"adapters.js","names":[],"sources":["../../src/kit/schema/adapters.ts"],"sourcesContent":["/**\n * ADAPTERS — today's field definitions → the Block Kit schema, so each editor switches to <SchemaForm> in one line.\n *\n * Visuals inspector: <SchemaForm schema={blockDefToSchema(def)} value={block.props} onChange={…} />\n * Content editor: <SchemaForm schema={fieldDefsToSchema(collection.fields, { values })} … />\n *\n * Both catalogs are loose (repeaters without item fields, links stored as strings); the adapters infer item\n * fields from sample values and mark legacy string values with `valueShape: \"string\"` so data round-trips\n * unchanged.\n */\nimport type { BlockDef, FieldDef, FieldType, PropDef } from \"./sources\";\nimport type { FieldGroup, FieldSchema, Option, TypeSchema } from \"./types\";\n\ntype Obj = Record<string, unknown>;\nconst isObj = (v: unknown): v is Obj => !!v && typeof v === \"object\" && !Array.isArray(v);\nconst options = (o?: string[]): Option[] | undefined => o?.map((x) => ({ value: x, label: x }));\n\n/** Nice titles for inferred keys (\"q\" → \"Question\"). */\nconst TITLES: Record<string, string> = {\n q: \"Question\", a: \"Answer\", href: \"Link\", url: \"Link\", cta: \"Button\", img: \"Image\", desc: \"Description\", qty: \"Amount\",\n featured: \"Highlighted\", note: \"Note\", links: \"Links\", price: \"Price\", name: \"Name\", title: \"Title\", label: \"Label\",\n};\nexport const titleFromKey = (k: string) => TITLES[k] ?? (k.charAt(0).toUpperCase() + k.slice(1)).replace(/([a-z])([A-Z])/g, \"$1 $2\").replace(/[_-]/g, \" \").replace(/ (\\w)/g, (m) => m.toLowerCase());\nconst looksLikeImage = (k: string, v: unknown) => typeof v === \"string\" && (/\\b(image|img|photo|cover|avatar|logo)\\b/i.test(k) || /picsum|\\.(jpe?g|png|webp|avif|svg)(\\?|$)/.test(v));\n\n/** Infer a field from a sample value (used for repeaters/groups without declared fields). */\nexport function inferField(key: string, sample: unknown): FieldSchema {\n const title = titleFromKey(key);\n if (Array.isArray(sample)) {\n const first = sample[0];\n if (isObj(first)) return { name: key, title, type: \"array\", of: [inferItem(key, first)] };\n if (typeof first === \"string\" && sample.every((x) => looksLikeImage(key, x)) && sample.length)\n return { name: key, title, type: \"array\", of: [{ name: \"image\", title: \"Image\", type: \"image\", valueShape: \"string\" }] };\n return { name: key, title, type: \"array\", layout: \"list\", of: [{ name: \"value\", title: singular(title), type: \"string\" }] };\n }\n if (typeof sample === \"boolean\") return { name: key, title, type: \"boolean\" };\n if (typeof sample === \"number\") return { name: key, title, type: \"number\" };\n if (looksLikeImage(key, sample)) return { name: key, title, type: \"image\", valueShape: \"string\" };\n if (isObj(sample)) {\n if (\"href\" in sample && \"label\" in sample) return { name: key, title, type: \"button\" };\n if (\"href\" in sample) return { name: key, title, type: \"link\" };\n if (\"url\" in sample) return { name: key, title, type: \"image\" };\n return { name: key, title, type: \"object\", fields: Object.entries(sample).filter(([k]) => !k.startsWith(\"_\")).map(([k, v]) => inferField(k, v)) };\n }\n if (key === \"href\" || key === \"link\") return { name: key, title, type: \"link\", valueShape: \"string\" };\n if (typeof sample === \"string\" && /<\\/?(p|h\\d|ul|ol|strong|em)\\b/.test(sample)) return { name: key, title, type: \"richtext\" };\n if (typeof sample === \"string\" && sample.length > 60) return { name: key, title, type: \"text\" };\n return { name: key, title, type: \"string\" };\n}\nfunction inferItem(arrayKey: string, sample: Obj): FieldSchema {\n const fields = Object.entries(sample).filter(([k]) => !k.startsWith(\"_\")).map(([k, v]) => inferField(k, v));\n const first = fields.find((f) => f.type === \"string\" || f.type === \"text\");\n const second = fields.find((f) => f !== first && (f.type === \"string\" || f.type === \"text\" || f.type === \"richtext\"));\n const media = fields.find((f) => f.type === \"image\");\n return {\n name: `${arrayKey}Item`,\n title: singular(titleFromKey(arrayKey)),\n type: \"object\",\n fields,\n preview: { title: first?.name, subtitle: second?.name, media: media?.name },\n };\n}\nconst cap = (t: string) => t.charAt(0).toUpperCase() + t.slice(1);\nconst singular = (t: string) => (t.endsWith(\"ies\") ? `${t.slice(0, -3)}y` : t.endsWith(\"s\") && !t.endsWith(\"ss\") ? t.slice(0, -1) : t);\n\n/* ── Visuals catalog (PropDef) → FieldSchema ─────────────────────────── */\nexport function propDefToField(p: PropDef, sample?: unknown): FieldSchema {\n const f = propDefToFieldBase(p, sample);\n // D45 organisation + conditions + array nouns ride along on every type\n return {\n ...f,\n ...(p.fieldset ? { fieldset: p.fieldset } : {}),\n ...(p.showIf ? { hidden: { field: p.showIf.key, equals: p.showIf.equals } } : {}),\n ...(p.itemNoun ? { itemNoun: p.itemNoun } : {}),\n ...(p.placeholder ? { placeholder: p.placeholder } : {}),\n ...(p.min != null && f.type === \"array\" ? { validation: { ...f.validation, min: p.min } } : {}),\n ...(p.max != null && f.type === \"array\" ? { validation: { ...f.validation, max: p.max } } : {}),\n };\n}\n\nfunction propDefToFieldBase(p: PropDef, sample?: unknown): FieldSchema {\n const base = { name: p.key, title: p.label, description: p.help, helpMore: p.helpMore, group: p.group?.toLowerCase() } satisfies Partial<FieldSchema>;\n const max = p.max ? { max: p.max } : undefined;\n switch (p.type) {\n case \"list\":\n // D47: one-line items are an array of strings, never tags\n return { ...base, type: \"array\", layout: \"list\", of: [{ name: \"value\", title: p.itemNoun ? cap(p.itemNoun) : singular(p.label), type: \"string\" }] };\n case \"icon\":\n return { ...base, type: \"icon\" };\n case \"boolean\":\n return { ...base, type: \"boolean\" };\n case \"references\":\n return { ...base, type: \"array\", validation: { unique: true }, of: [{ name: `${p.key}Ref`, title: singular(p.label), type: \"reference\", reference: { to: [p.reference ?? \"page\"] } }] };\n case \"group\": {\n const first = isObj(sample) ? sample : undefined;\n if (!p.item?.length) break;\n return { ...base, type: \"object\", fields: p.item.map((x) => propDefToField(x, first?.[x.key])) };\n }\n case \"text\":\n return { ...base, type: \"string\", validation: max, ai: true };\n case \"textarea\":\n return { ...base, type: \"text\", validation: max, ai: true };\n case \"richtext\":\n return { ...base, type: \"richtext\", ai: true };\n case \"image\":\n return { ...base, type: \"image\", valueShape: typeof sample === \"string\" ? \"string\" : undefined };\n case \"gallery\":\n return { ...base, type: \"array\", of: [{ name: \"image\", title: \"Image\", type: \"image\", valueShape: \"string\" }] };\n case \"link\":\n return { ...base, type: \"link\", valueShape: typeof sample === \"string\" ? \"string\" : undefined };\n case \"button\":\n return { ...base, type: \"button\" };\n case \"tags\":\n return { ...base, type: \"tags\" };\n case \"select\":\n return { ...base, type: \"select\", options: options(p.options) };\n case \"number\":\n return { ...base, type: \"number\" };\n case \"table\":\n return { ...base, type: \"table\", validation: { required: true } };\n case \"reference\":\n return { ...base, type: \"reference\", reference: { to: [p.reference ?? (p.key === \"form\" ? \"form\" : p.key === \"collection\" ? \"collection\" : \"page\")] } };\n case \"repeater\": {\n const items = Array.isArray(sample) ? sample : [];\n const first = items.find(isObj);\n const fields = p.item?.length ? p.item.map((x) => propDefToField(x, first?.[x.key])) : first ? inferItem(p.key, first).fields! : [{ name: \"label\", title: \"Label\", type: \"string\" as const }];\n const t = fields.find((f) => f.type === \"string\" || f.type === \"text\");\n const s = fields.find((f) => f !== t && (f.type === \"string\" || f.type === \"text\" || f.type === \"richtext\"));\n return {\n ...base,\n type: \"array\",\n of: [{ name: `${p.key}Item`, title: p.itemNoun ? cap(p.itemNoun) : singular(p.label), type: \"object\", fields, icon: undefined, preview: { title: t?.name, subtitle: s?.name, media: fields.find((f) => f.type === \"image\")?.name } }],\n };\n }\n default:\n break;\n }\n return { ...base, ...inferField(p.key, sample), title: p.label };\n}\n\n/** A visual-editor block definition → TypeSchema. Groups appear only when props use more than one group. */\nexport function blockDefToSchema(def: BlockDef): TypeSchema {\n const fields = def.content.map((p) => propDefToField(p, def.defaults[p.key]));\n const used = Array.from(new Set(fields.map((f) => f.group ?? \"content\")));\n const groups: FieldGroup[] | undefined =\n used.length > 1 ? used.map((g, i) => ({ name: g, title: g.charAt(0).toUpperCase() + g.slice(1), default: g === \"content\" || i === 0 })) : undefined;\n return {\n name: def.type,\n title: def.name,\n kind: def.global ? \"global\" : \"block\",\n icon: def.icon,\n category: def.category,\n ...(def.placement ? { placement: def.placement } : {}),\n description: def.description,\n variants: def.variants,\n initialValue: def.defaults,\n groups,\n ...(def.fieldsets?.length ? { fieldsets: def.fieldsets.map((f) => ({ name: f.name, title: f.title, collapsed: f.collapsed, columns: f.columns })) } : {}),\n fields: groups ? fields.map((f) => ({ ...f, group: f.group ?? \"content\" })) : fields.map(({ group: _g, ...f }) => f),\n };\n}\n\n/* ── Content collections (FieldDef) → FieldSchema ────────────────────── */\nconst SIMPLE: Partial<Record<FieldType, FieldSchema[\"type\"]>> = {\n text: \"string\", textarea: \"text\", richtext: \"richtext\", slug: \"slug\", boolean: \"boolean\", date: \"date\", datetime: \"datetime\",\n image: \"image\", file: \"file\", video: \"video\", link: \"link\", button: \"button\", color: \"color\", json: \"json\", code: \"code\",\n email: \"email\", url: \"url\", location: \"geopoint\", rating: \"rating\", tags: \"tags\", table: \"table\",\n};\n\nexport function fieldDefToSchema(def: FieldDef, sample?: unknown): FieldSchema {\n const base: FieldSchema = {\n name: def.id,\n title: def.name,\n type: \"string\",\n description: def.help,\n helpMore: def.helpMore,\n localized: def.localized,\n validation: def.required || def.max ? { required: def.required, max: def.max } : undefined,\n };\n const simple = SIMPLE[def.type];\n if (simple) {\n const f: FieldSchema = { ...base, type: simple };\n if (simple === \"string\" || simple === \"text\" || simple === \"richtext\") f.ai = true;\n if (simple === \"image\" && typeof sample === \"string\") f.valueShape = \"string\";\n if (simple === \"link\" && typeof sample === \"string\") f.valueShape = \"string\";\n return f;\n }\n switch (def.type) {\n case \"number\": {\n const unit = def.help && def.help.length < 14 ? def.help : def.id === \"price\" ? \"USD\" : undefined;\n return { ...base, type: \"number\", description: unit ? undefined : def.help, numeric: unit ? { unit } : undefined };\n }\n case \"select\":\n return { ...base, type: \"select\", options: options(def.options) };\n case \"multiselect\":\n return { ...base, type: \"multiselect\", options: options(def.options) };\n case \"reference\":\n return { ...base, type: \"reference\", reference: { to: [def.id === \"form\" ? \"form\" : def.id === \"collection\" && !def.reference ? \"collection\" : def.reference ?? \"page\"] } };\n case \"references\":\n return { ...base, type: \"array\", of: [{ name: `${def.id}Ref`, title: singular(def.name), type: \"reference\", reference: { to: [def.reference ?? \"page\"] } }] };\n case \"gallery\":\n return { ...base, type: \"array\", arrayLayout: \"grid\", of: [{ name: \"image\", title: \"Image\", type: \"image\" }] };\n case \"group\":\n return { ...base, type: \"object\", fields: (def.fields ?? []).map((f) => fieldDefToSchema(f, isObj(sample) ? sample[f.id] : undefined)) };\n case \"repeater\": {\n const items = Array.isArray(sample) ? sample : [];\n const first = items.find(isObj);\n const fields = def.fields?.length\n ? def.fields.map((f) => fieldDefToSchema(f, first?.[f.id]))\n : first\n ? inferItem(def.id, first).fields!\n : def.id === \"ingredients\"\n ? [{ name: \"item\", title: \"Ingredient\", type: \"string\" as const }, { name: \"qty\", title: \"Amount\", type: \"string\" as const }]\n : [{ name: \"label\", title: \"Label\", type: \"string\" as const }, { name: \"value\", title: \"Value\", type: \"string\" as const }];\n const t = fields.find((f) => f.type === \"string\" || f.type === \"text\");\n const s = fields.find((f) => f !== t && (f.type === \"string\" || f.type === \"text\"));\n return { ...base, type: \"array\", validation: def.required ? { required: true } : undefined, of: [{ name: `${def.id}Item`, title: singular(def.name), type: \"object\", fields, preview: { title: t?.name, subtitle: s?.name } }] };\n }\n default:\n return { ...base, ...inferField(def.id, sample), title: def.name };\n }\n}\n\n/** A collection's (or page's) field list → TypeSchema for the document editor. */\nexport function fieldDefsToSchema(fields: FieldDef[], opts: { name?: string; title?: string; values?: Obj; kind?: TypeSchema[\"kind\"] } = {}): TypeSchema {\n return {\n name: opts.name ?? \"document\",\n title: opts.title ?? \"Fields\",\n kind: opts.kind ?? \"entry\",\n fields: fields.map((f) => fieldDefToSchema(f, opts.values?.[f.id])),\n };\n}\n"],"mappings":"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"}
|
package/schema/help.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"help.js","names":[],"sources":["../../src/kit/schema/help.ts"],"sourcesContent":["/**\n * FIELD HELP — CPO D39, narrowed by D51 \"Help text is the exception\". One place for the grey line under a label.\n *\n * Precedence (first match wins):\n * 1. `field.description` written on the schema. `\"\"` opts out on purpose.\n * 2. A computed line from the field's own settings (slug before publish, number ranges).\n * 3. A convention from this file, matched on field NAME + TYPE. Only facts that are true for that field in every\n * block live here, and only facts the editor cannot see from the label and the control.\n *\n * The rule (D51, enforced by scripts/brain/check-help.ts):\n * - Most fields get NO help. Ask: \"Does the editor need this to type the right value?\" If no, no help.\n * - Allowed: a non-obvious format or unit (\"In minutes.\", \"A .vtt file.\"), where it shows when the canvas can't\n * show it (\"Shown in search results.\"), a real constraint or consequence (\"Changing it once live breaks links.\"),\n * a fallback (\"Leave empty to use the page title.\").\n * - Never: restating the label, writing advice (\"Keep it short\", \"Start with a verb\", \"2–4 words\"), marketing\n * theory, internal or design-system notes (\"Label and link are one unit\"), examples that belong in `placeholder`.\n * - Length guidance is a counter (`validation.max` / `recommendedMax`), never a sentence.\n * - One short sentence, under 90 characters, no em dash. Anything longer goes in `helpMore` (the ⓘ), sparingly.\n * - No type-wide defaults: a heading, a button or an image gets nothing just for being one.\n */\nimport type { FieldSchema } from \"./types\";\n\ntype Rule = { names: string[]; types?: FieldSchema[\"type\"][]; help: string };\n\nconst TEXT: FieldSchema[\"type\"][] = [\"string\", \"text\"];\n\n/** Conventions by field name. Each says something the label and the control cannot. */\nconst RULES: Rule[] = [\n { names: [\"excerpt\", \"summary\"], types: TEXT, help: \"Shown on cards and in search results.\" },\n { names: [\"alt\"], types: TEXT, help: \"Not shown. Read by screen readers and search engines.\" },\n // No SEO conventions (metaTitle, metaDescription, canonical, noindex, schemaType): SEO is native, never a modelled field.\n { names: [\"anchor\"], types: TEXT, help: \"Lowercase, no spaces. Links like /about#team jump here.\" },\n { names: [\"coverImage\", \"cover\"], types: [\"image\"], help: \"Also used on cards and in link previews.\" },\n { names: [\"published\", \"publishedAt\", \"publishDate\"], types: [\"date\", \"datetime\"], help: \"Also used to sort lists.\" },\n { names: [\"readingTime\"], types: [\"number\"], help: \"In minutes.\" },\n];\n\n/** Conventions by field TYPE (any name). Only consequences the editor cannot see; no advice, no restating. */\nconst BY_TYPE: Partial<Record<FieldSchema[\"type\"], string>> = {\n slug: \"Once live, changing it offers a redirect from the old address.\",\n};\n\n/** The convention for a field, or undefined. Does not look at `description`; callers decide precedence. */\nexport function conventionalHelp(field: Pick<FieldSchema, \"name\" | \"type\">): string | undefined {\n const rule = RULES.find((r) => r.names.includes(field.name) && (!r.types || r.types.includes(field.type)));\n return rule?.help ?? BY_TYPE[field.type];\n}\n\n/** Help for a field following D39 precedence. `computed` is the field's own derived line (slug, number range). */\nexport function resolveHelp(field: FieldSchema, computed?: string): string | undefined {\n if (field.description !== undefined) return field.description || undefined; // \"\" = deliberately none\n return computed ?? conventionalHelp(field);\n}\n"],"mappings":";AAwBA,IAAM,OAA8B,CAAC,UAAU,OAAO;;AAGtD,IAAM,QAAgB;CACpB;EAAE,OAAO,CAAC,WAAW,UAAU;EAAE,OAAO;EAAM,MAAM;EAAyC;CAC7F;EAAE,OAAO,CAAC,MAAM;EAAE,OAAO;EAAM,MAAM;EAAyD;CAE9F;EAAE,OAAO,CAAC,SAAS;EAAE,OAAO;EAAM,MAAM;EAA2D;CACnG;EAAE,OAAO,CAAC,cAAc,QAAQ;EAAE,OAAO,CAAC,QAAQ;EAAE,MAAM;EAA4C;CACtG;EAAE,OAAO;GAAC;GAAa;GAAe;GAAc;EAAE,OAAO,CAAC,QAAQ,WAAW;EAAE,MAAM;EAA4B;CACrH;EAAE,OAAO,CAAC,cAAc;EAAE,OAAO,CAAC,SAAS;EAAE,MAAM;EAAe;CACnE;;AAGD,IAAM,UAAwD,EAC5D,MAAM,kEACP;;AAGD,SAAgB,iBAAiB,OAA+D;AAE9F,QADa,MAAM,MAAM,MAAM,EAAE,MAAM,SAAS,MAAM,KAAK,KAAK,CAAC,EAAE,SAAS,EAAE,MAAM,SAAS,MAAM,KAAK,EAAE,EAC7F,QAAQ,QAAQ,MAAM;;;AAIrC,SAAgB,YAAY,OAAoB,UAAuC;AACrF,KAAI,MAAM,gBAAgB,KAAA,EAAW,QAAO,MAAM,eAAe,KAAA;AACjE,QAAO,YAAY,iBAAiB,MAAM"}
|
package/schema/scale.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scale.js","names":[],"sources":["../../src/kit/schema/scale.ts"],"sourcesContent":["/**\n * SCALES (CPO D41) — the logic behind \"fixed steps, with an optional custom escape hatch\".\n * Pure functions: the Block Kit control, the Visuals Design tab and site renderers all read values through here,\n * so a token, a stepped number and a custom size resolve the same way everywhere.\n *\n * Stored shapes (see `ScaleValue` in ./types):\n * \"xl\" → token (developers map it to their design system)\n * 15 → number on a stepped range, in the scale's default unit\n * { value: 200, unit: \"px\" } → custom (only when the field allows custom)\n */\nimport type { FieldSchema, ScaleCustomValue, ScaleRange, ScaleSchema, ScaleStep, ScaleUnit, ScaleValue } from \"./types\";\n\nexport const SCALE_UNITS: ScaleUnit[] = [\"px\", \"%\", \"rem\", \"em\", \"vw\", \"vh\"];\nconst isUnit = (u: unknown): u is ScaleUnit => typeof u === \"string\" && (SCALE_UNITS as string[]).includes(u);\n\n/** Spoken unit names for aria-valuetext (\"48 pixels\"). */\nconst UNIT_WORDS: Record<ScaleUnit, [one: string, many: string]> = {\n px: [\"pixel\", \"pixels\"],\n \"%\": [\"percent\", \"percent\"],\n rem: [\"rem\", \"rem\"],\n em: [\"em\", \"em\"],\n vw: [\"percent of the screen width\", \"percent of the screen width\"],\n vh: [\"percent of the screen height\", \"percent of the screen height\"],\n};\nexport const UNIT_NAMES: Record<ScaleUnit, string> = { px: \"Pixels\", \"%\": \"Percent\", rem: \"Root em\", em: \"Em\", vw: \"Screen width\", vh: \"Screen height\" };\n\nexport const isCustomValue = (v: unknown): v is ScaleCustomValue =>\n !!v && typeof v === \"object\" && typeof (v as ScaleCustomValue).value === \"number\" && isUnit((v as ScaleCustomValue).unit);\nexport const isTokenScale = (s: ScaleSchema): s is ScaleSchema & { steps: ScaleStep[] } => Array.isArray(s.steps);\nexport const rangeOf = (s: ScaleSchema): ScaleRange | null => (Array.isArray(s.steps) ? null : s.steps);\n\n/** Back-compat: `layout: \"slider\"` + `numeric: { min, max, step, unit }` → a fixed-only range scale. */\nexport function fieldScale(field: Pick<FieldSchema, \"scale\" | \"layout\" | \"numeric\">): ScaleSchema | null {\n if (field.scale) return field.scale;\n const n = field.numeric;\n if (field.layout === \"slider\" && n?.min != null && n?.max != null) {\n return { steps: { min: n.min, max: n.max, step: n.step ?? 1 }, units: isUnit(n.unit) ? [n.unit] : undefined };\n }\n return null;\n}\n\nexport const defaultUnit = (s: ScaleSchema): ScaleUnit | undefined => s.defaultUnit ?? s.units?.[0];\n\n/** The custom rules, or null when the field is fixed only. */\nexport function customRules(s: ScaleSchema) {\n if (!s.allowCustom) return null;\n const c = s.allowCustom === true ? {} : s.allowCustom;\n const units = c.units ?? s.units ?? [\"px\"];\n const pick = (b: typeof c.min, u: ScaleUnit) => (typeof b === \"number\" ? b : b?.[u]);\n return {\n units,\n step: c.step ?? 1,\n min: (u: ScaleUnit) => pick(c.min, u),\n max: (u: ScaleUnit) => pick(c.max, u),\n };\n}\n\nconst decimals = (n: number) => (String(n).split(\".\")[1] ?? \"\").length;\nexport function roundTo(n: number, step: number) {\n return Number((Math.round(n / step) * step).toFixed(Math.max(decimals(step), 0)));\n}\n\n/** Readable number + unit: \"200px\", \"15%\", \"1.5rem\", \"4.9\". */\nexport function formatNumber(n: number, unit?: string) {\n const t = Number.isInteger(n) ? String(n) : String(Number(n.toFixed(3)));\n if (!unit) return t;\n return isUnit(unit) ? `${t}${unit}` : `${t} ${unit}`;\n}\n\n/** px for a custom value when it can be known without layout (px, rem/em at 16). */\nexport function customPx(v: ScaleCustomValue): number | undefined {\n if (v.unit === \"px\") return v.value;\n if (v.unit === \"rem\" || v.unit === \"em\") return v.value * 16;\n return undefined;\n}\n\nexport interface ResolvedScale {\n kind: \"token\" | \"number\" | \"custom\" | \"empty\";\n /** short readout: \"XL\", \"15%\", \"200px\" */\n label: string;\n /** long name: \"Extra large\", \"15%\", \"Custom\" */\n title: string;\n /** CSS to emit (\"48px\", \"15%\", \"200px\", or a step's css) */\n css?: string;\n px?: number;\n /** token index (token scales) */\n index?: number;\n /** spoken value for aria-valuetext: \"Extra large, 48 pixels\" */\n spoken: string;\n}\n\nfunction spokenNumber(n: number, unit?: string) {\n if (!unit) return String(n);\n if (!isUnit(unit)) return `${n} ${unit}`;\n const [one, many] = UNIT_WORDS[unit];\n return `${n} ${n === 1 ? one : many}`;\n}\n\n/** Resolve any stored value against its scale. Unknown tokens fall back to \"empty\" (never throws). */\nexport function resolveScale(s: ScaleSchema, v: unknown, legacyUnit?: string): ResolvedScale {\n if (isCustomValue(v)) {\n const px = customPx(v);\n return { kind: \"custom\", label: formatNumber(v.value, v.unit), title: \"Custom\", css: `${v.value}${v.unit}`, px, spoken: `Custom, ${spokenNumber(v.value, v.unit)}` };\n }\n if (isTokenScale(s)) {\n const i = s.steps.findIndex((st) => st.value === v);\n if (i < 0) return { kind: \"empty\", label: \"—\", title: \"Not set\", spoken: \"Not set\" };\n const st = s.steps[i];\n const title = st.title ?? st.label;\n const css = st.css ?? (st.px != null ? `${st.px}px` : undefined);\n return { kind: \"token\", label: st.label, title, css, px: st.px, index: i, spoken: st.px != null ? `${title}, ${spokenNumber(st.px, \"px\")}` : st.css ? `${title}, ${st.css}` : title };\n }\n const unit = defaultUnit(s) ?? legacyUnit;\n const n = typeof v === \"number\" ? v : typeof v === \"string\" && v.trim() !== \"\" && !Number.isNaN(Number(v)) ? Number(v) : null;\n if (n == null) return { kind: \"empty\", label: \"—\", title: \"Not set\", spoken: \"Not set\" };\n const css = isUnit(unit) ? `${n}${unit}` : String(n);\n return { kind: \"number\", label: formatNumber(n, unit), title: formatNumber(n, unit), css, px: unit === \"px\" ? n : undefined, spoken: spokenNumber(n, unit) };\n}\n\n/** CSS for a stored value — what a site renderer emits. */\nexport const scaleCss = (s: ScaleSchema, v: unknown) => resolveScale(s, v).css;\n\n/** \"XL · 48px\" — the hint shown for a token. */\nexport function scaleHint(r: ResolvedScale) {\n if (r.kind === \"token\") return r.css ? `${r.title} · ${r.css}` : r.title;\n if (r.kind === \"custom\") return `Custom · ${r.label}`;\n return r.title;\n}\n\n/** Index of the token nearest to a custom value (by px), or -1 when it can't be placed. */\nexport function nearestTokenIndex(s: ScaleSchema, v: ScaleCustomValue): number {\n if (!isTokenScale(s)) return -1;\n const px = customPx(v);\n if (px == null) return -1;\n let best = -1;\n let d = Infinity;\n s.steps.forEach((st, i) => {\n if (st.px == null) return;\n const dd = Math.abs(st.px - px);\n if (dd < d) (d = dd), (best = i);\n });\n return best;\n}\n\nexport type ParseResult = { ok: true; value: ScaleValue } | { ok: false; error: string };\n\n/** Validate a custom value against the field's custom rules. Returns a plain-words error or null. */\nexport function validateCustom(s: ScaleSchema, v: ScaleCustomValue): string | null {\n const c = customRules(s);\n if (!c) return \"Pick a value on the scale.\";\n if (!c.units.includes(v.unit)) return `Use ${listUnits(c.units)}.`;\n const lo = c.min(v.unit);\n const hi = c.max(v.unit);\n if ((lo != null && v.value < lo) || (hi != null && v.value > hi)) {\n if (lo != null && hi != null) return `Use ${formatNumber(lo)}–${formatNumber(hi, v.unit)}.`;\n if (lo != null) return `Use ${formatNumber(lo, v.unit)} or more.`;\n return `Use ${formatNumber(hi!, v.unit)} or less.`;\n }\n return null;\n}\n\nconst listUnits = (u: ScaleUnit[]) => (u.length === 1 ? u[0] : `${u.slice(0, -1).join(\", \")} or ${u[u.length - 1]}`);\n\n/**\n * Parse what an editor typed: a token (\"xl\", \"XL\", \"Extra large\"), a number (\"240\" → default unit) or a number with\n * a unit (\"200px\", \"75 %\", \"1.5rem\"). Exact px matches of a token snap to the token, so the design system wins.\n */\nexport function parseScaleInput(s: ScaleSchema, text: string, unitHint?: ScaleUnit): ParseResult {\n const t = text.trim();\n if (!t) return { ok: false, error: \"Type a value, like 240px.\" };\n const low = t.toLowerCase();\n if (isTokenScale(s)) {\n const st = s.steps.find((x) => x.value.toLowerCase() === low || x.label.toLowerCase() === low || x.title?.toLowerCase() === low);\n if (st) return { ok: true, value: st.value };\n }\n const m = /^(-?(?:\\d+(?:\\.\\d+)?|\\.\\d+))\\s*(px|%|rem|em|vw|vh)?$/i.exec(t);\n if (!m) {\n const tokens = isTokenScale(s) ? ` or a size like ${s.steps[Math.min(2, s.steps.length - 1)].label}` : \"\";\n return { ok: false, error: `Type a number like 240px${tokens}.` };\n }\n const n = Number(m[1]);\n const typedUnit = m[2]?.toLowerCase() as ScaleUnit | undefined;\n const c = customRules(s);\n const range = rangeOf(s);\n if (range) {\n const base = defaultUnit(s);\n const sameUnit = !typedUnit || typedUnit === base;\n const step = range.step ?? 1;\n const onGrid = Math.abs((n - range.min) / step - Math.round((n - range.min) / step)) < 1e-9;\n if (sameUnit && n >= range.min && n <= range.max && (onGrid || !c)) return { ok: true, value: onGrid ? n : roundTo(n, step) };\n if (!c) return { ok: false, error: `Use ${formatNumber(range.min)}–${formatNumber(range.max, base)}.` };\n const unit = typedUnit ?? unitHint ?? base ?? c.units[0];\n const cv = { value: n, unit };\n const err = validateCustom(s, cv);\n return err ? { ok: false, error: err } : { ok: true, value: cv };\n }\n if (!c) return { ok: false, error: \"Pick a value on the scale.\" };\n const unit = typedUnit ?? unitHint ?? c.units[0];\n const cv: ScaleCustomValue = { value: n, unit };\n if (isTokenScale(s) && unit === \"px\") {\n const exact = s.steps.find((st) => st.px === n && !st.css);\n if (exact) return { ok: true, value: exact.value };\n }\n const err = validateCustom(s, cv);\n return err ? { ok: false, error: err } : { ok: true, value: cv };\n}\n"],"mappings":"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"}
|
package/schema/sources.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sources.js","names":[],"sources":["../../src/kit/schema/sources.ts"],"sourcesContent":["/**\n * The V2 shapes the schema layer reads, copied type for type so @/kit owns them and imports nothing from\n * the app. Sources at V2 HEAD 9829bf1:\n * - Cap: src/lib/access/registry.ts (CAP_IDS, the permission keys a field's `access` names)\n * - FieldType, FieldDef: src/data/types.ts (content collection fields)\n * - BlockCategory, PropType, PropDef, BlockFieldset, BlockDef: src/features/visuals/model/catalog.ts\n * The production adapters (src/kit/adapters) map production models onto these; nothing here is wired yet.\n */\n\nexport const CAP_IDS = [\n // content\n \"content.view\",\n \"content.create\",\n \"content.edit\",\n \"content.delete\",\n \"content.review\",\n \"content.publish\",\n // pages and collections\n \"pages.organize\",\n \"collections.manage\",\n // schema\n \"schema.view\",\n \"schema.manage\",\n // components\n \"components.use\",\n \"components.manage\",\n // media\n \"media.upload\",\n \"media.manage\",\n // seo\n \"seo.edit\",\n \"seo.manage\",\n // forms\n \"forms.view\",\n \"forms.manage\",\n \"forms.submissions\",\n // analytics\n \"analytics.view\",\n // visuals and design\n \"visuals.edit\",\n \"design.edit\",\n \"design.manage\",\n // publish and branches\n \"publish.deploy\",\n \"publish.workflow\",\n \"branches.create\",\n \"branches.merge\",\n // agents and AI\n \"agents.run\",\n \"agents.build\",\n \"agents.manage\",\n \"ai.use\",\n \"ai.manage\",\n // comments\n \"comments.create\",\n \"comments.moderate\",\n // settings and audit\n \"settings.project\",\n \"settings.workspace\",\n \"settings.security\",\n \"audit.view\",\n // members\n \"members.view\",\n \"members.invite\",\n \"members.manage\",\n \"members.viewAs\",\n // billing and domains\n \"billing.view\",\n \"billing.manage\",\n \"domains.manage\",\n // api, integrations, projects\n \"api.view\",\n \"api.manage\",\n \"integrations.manage\",\n \"projects.create\",\n \"projects.delete\",\n] as const;\n\nexport type Cap = (typeof CAP_IDS)[number];\n\nexport type FieldType =\n | \"text\"\n | \"textarea\"\n | \"richtext\"\n | \"slug\"\n | \"number\"\n | \"boolean\"\n | \"date\"\n | \"datetime\"\n | \"select\"\n | \"multiselect\"\n | \"image\"\n | \"gallery\"\n | \"file\"\n | \"video\"\n | \"link\"\n | \"button\"\n | \"reference\"\n | \"references\"\n | \"color\"\n | \"json\"\n | \"code\"\n | \"repeater\"\n | \"group\"\n | \"email\"\n | \"url\"\n | \"location\"\n | \"rating\"\n | \"tags\"\n | \"table\";\n\nexport interface FieldDef {\n id: string;\n name: string;\n type: FieldType;\n required?: boolean;\n /** Help under the label (CPO D39). Unset → house convention by id/type; \"\" = none. */\n help?: string;\n /** Longer explanation behind the ⓘ next to the label. */\n helpMore?: string;\n options?: string[];\n reference?: string;\n max?: number;\n localized?: boolean;\n fields?: FieldDef[];\n}\n\n\nexport type BlockCategory = \"Navigation\" | \"Hero\" | \"Content\" | \"Social proof\" | \"Commerce\" | \"Conversion\" | \"Collection\" | \"Media\" | \"Footer\" | \"Basic\" | \"Blog\";\n\n/**\n * Prop types: every FieldType, plus two shapes only blocks need — \"list\" (an array of one-line strings: bullets,\n * features, \"what's included\"; never tags, D47) and \"icon\" (a Tabler icon name, picked from the icon picker).\n */\nexport type PropType = FieldType | \"list\" | \"icon\";\n\nexport interface PropDef {\n key: string;\n label: string;\n type: PropType;\n /** Help under the label (CPO D39). Unset → house convention by key/type; \"\" = none. */\n help?: string;\n /** Longer explanation behind the ⓘ next to the label. */\n helpMore?: string;\n options?: string[];\n max?: number;\n item?: PropDef[]; // for repeater\n group?: \"Content\" | \"Media\" | \"Links\" | \"Data\";\n /** reference props: the collection id the picker lists (e.g. \"col_journal\"); default = pages */\n reference?: string;\n /** D45: the fieldset (BlockDef.fieldsets) this prop sits in. */\n fieldset?: string;\n /** Show only when a sibling prop equals one of these values (the form hides it otherwise). */\n showIf?: { key: string; equals: unknown };\n /** Arrays: the noun for \"Add {noun}\". */\n itemNoun?: string;\n placeholder?: string;\n /** Arrays: the most and fewest items. */\n min?: number;\n}\n\n/** D45 fieldset: siblings with one purpose (\"Buttons\", \"Newsletter\"), optionally collapsed. */\nexport interface BlockFieldset {\n name: string;\n title: string;\n collapsed?: boolean;\n columns?: 1 | 2;\n}\n\nexport interface BlockDef {\n type: string;\n name: string;\n category: BlockCategory;\n description: string;\n icon: string; // lucide icon name\n variants: { id: string; name: string; description?: string }[];\n content: PropDef[];\n /** D45 fieldsets the content props sit in (PropDef.fieldset). */\n fieldsets?: BlockFieldset[];\n defaults: Record<string, unknown>;\n /** Global blocks (nav, footer, announcement) are synced across every page. */\n global?: boolean;\n /**\n * PLACEMENT (CPO D55): where the block fits. \"inline\" = it fits a text column, so a rich-text body offers it in the\n * Insert menu's Article group. \"section\" (the default) = page-width; a body reaches it only through More components.\n * \"page\" = a whole page or a feed of other content (Blog post, Recipe, Journal grid, Rich text); never inside a body.\n */\n placement?: \"inline\" | \"section\" | \"page\";\n /** Developer-only lock: marketers can edit content but not swap/remove. */\n tags?: string[];\n /**\n * SLOTS (CPO D8, added by the canvas team) — named areas that hold nested blocks (Tabs panels, Bento cells…).\n * Instances keep them in `BlockInstance.children[slot]`. `accepts` limits which block types can be dropped in.\n */\n slots?: { name: string; label: string; accepts?: string[] }[];\n /** Nested blocks created with a fresh instance: slot → [type, variant?, props override?][] */\n childDefaults?: Record<string, [string, string?, Record<string, unknown>?][]>;\n}\n"],"mappings":";;;;;;;;;AASA,IAAa,UAAU;CAErB;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CAEA;CACA;CAEA;CACA;CAEA;CACA;CAEA;CACA;CAEA;CACA;CACA;CAEA;CAEA;CACA;CACA;CAEA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CAEA;CACA;CAEA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CAEA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CACD"}
|
package/schema/table.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"table.js","names":[],"sources":["../../src/kit/schema/table.ts"],"sourcesContent":["/**\n * TABLE — the first-class `table` value of the schema language (CPO D42, SCHEMA_GAPS gap 12).\n *\n * One model, three places: a Table block on a page, a table island inside rich text, a Table block inside a slot.\n * One renderer: `renderTableHtml()` writes the semantic HTML every surface shows (site canvas, Journal body, published\n * preview, stored rich text); `<TableView>` (src/components/table) wraps it for live pages with visitor sort/filter.\n *\n * Why this shape (vs. Sanity's rows › cells › value, Storyblok's thead/tbody strings, Prismic's head/body):\n * - Columns are TYPED and KEYED (`_key`). Cells are keyed by column key, so reordering a column never misaligns a row.\n * - A cell is a bare value (string, number, boolean, link, reference) or `{ value, type?, note? }` when it needs a\n * per-cell type (a \"limit\" in a boolean pricing column) or a footnote.\n * - Header row + optional header column (row headers), column groups (`colgroup` headers), row groups (`tbody` with a\n * `rowgroup` header), footer rows (`tfoot`), caption (required), notes, footnotes. Body cells never merge: merged body\n * cells break sorting, Markdown and screen readers. Only group headers span (`colspan` + `scope=\"colgroup\"`).\n *\n * Stored rich-text form (lossless, so the HTML IS the model — no JSON blob to drift):\n * <figure data-rt=\"table\" data-id data-header-row data-header-col data-responsive data-sticky data-filter data-jsonld…>\n * <table aria-describedby=\"…-notes\">\n * <caption>…</caption>\n * <colgroup><col data-key data-type data-unit data-currency …></colgroup>\n * <thead>[<tr data-groups><th scope=\"colgroup\" colspan data-group>…</th>…</tr>]<tr><th scope=\"col\" data-col>…</th>…</tr></thead>\n * <tbody [data-key data-label]>[<tr data-group-row><th scope=\"rowgroup\" colspan>…</th></tr>]\n * <tr data-key><th scope=\"row\" data-col>…</th><td data-col data-label [data-value] [data-type] [data-note]>…</td></tr></tbody>\n * <tfoot>…</tfoot>\n * </table>\n * <p data-notes id=\"…-notes\">…</p><ol data-footnotes><li id=\"…-fn-1\" data-key>…</li></ol>\n * </figure>\n * Pure string work (no DOM) except `parseTableElement`, which reads a DOM element (ours or any site's).\n */\n\n/* ── Types ─────────────────────────────────────────────────────────── */\nexport type TableColumnType = \"text\" | \"number\" | \"money\" | \"boolean\" | \"rating\" | \"link\" | \"richtext-inline\" | \"reference\";\nexport const TABLE_COLUMN_TYPES: { value: TableColumnType; label: string; description: string }[] = [\n { value: \"text\", label: \"Text\", description: \"Plain words\" },\n { value: \"number\", label: \"Number\", description: \"With an optional unit (kg, %, min)\" },\n { value: \"money\", label: \"Money\", description: \"An amount in one currency\" },\n { value: \"boolean\", label: \"Yes / no\", description: \"Written as Included / Not included\" },\n { value: \"rating\", label: \"Rating\", description: \"Out of 5\" },\n { value: \"link\", label: \"Link\", description: \"Label + URL\" },\n { value: \"richtext-inline\", label: \"Rich text\", description: \"Bold, italic, links, code\" },\n { value: \"reference\", label: \"Reference\", description: \"A page or entry, by id\" },\n];\n\nexport interface TableColumn {\n _key: string;\n /** Header text (plain). Required when the header row is on. */\n label: string;\n type: TableColumnType;\n /** Explains the column; written as the header's title and in the notes of the Markdown twin. */\n description?: string;\n /** number: unit after the value (\"kg\", \"%\", \"min\"). */\n unit?: string;\n /** money: ISO 4217 code. Default USD. */\n currency?: string;\n /** number / money: fixed decimals. */\n decimals?: number;\n /** Default: numbers, money and ratings align end, everything else start (WAI: right-align numbers). */\n align?: \"start\" | \"center\" | \"end\";\n /** Visitors may sort by this column (live pages only). */\n sortable?: boolean;\n /** Column group key (a spanning header above this column). */\n group?: string;\n /** boolean: what the words say. Defaults \"Included\" / \"Not included\". */\n trueLabel?: string;\n falseLabel?: string;\n /** rating: scale. Default 5. */\n max?: number;\n /** reference: allowed targets (collection ids or \"page\"). */\n refTo?: string[];\n /** Tint the column (the recommended plan). Visual only. */\n highlight?: boolean;\n}\nexport interface TableGroup {\n _key: string;\n label: string;\n}\nexport interface TableLink {\n label: string;\n href: string;\n /** set by the global link element (D57) */\n newTab?: boolean;\n rel?: \"follow\" | \"nofollow\" | \"ugc\" | \"sponsored\";\n}\nexport interface TableRef {\n ref: string;\n label?: string;\n href?: string;\n}\nexport type TableCellValue = string | number | boolean | null | TableLink | TableRef;\nexport interface TableCellObject {\n value: TableCellValue;\n /** Per-cell type (wins over the row's and the column's). */\n type?: TableColumnType;\n /** Footnote key. */\n note?: string;\n /**\n * The body's own footnote markers after the cell's text (`<sup data-footnote=\"key\">n</sup>`, a rich-text table's),\n * kept as written: the table editor does not edit them, and the cell writes them back after its text.\n */\n marks?: string;\n}\nexport type TableCell = TableCellValue | TableCellObject;\nexport interface TableRow {\n _key: string;\n cells: Record<string, TableCell | undefined>;\n /** Row group key. */\n group?: string;\n /** Totals / summary rows → <tfoot>. */\n footer?: boolean;\n /** Per-row type: pricing matrices mix yes/no rows with limit rows in the same plan columns. */\n type?: TableColumnType;\n /** Tint the row (the bestseller). Visual only — say WHY in a footnote, colour alone means nothing to a reader. */\n highlight?: boolean;\n}\nexport interface TableFootnote {\n _key: string;\n text: string;\n}\nexport type TableResponsive = \"scroll\" | \"stack\" | \"cards\";\nexport type TableJsonLdType = \"none\" | \"ItemList\" | \"Dataset\" | \"Offers\";\nexport interface TableValue {\n /** Stable id for anchors (footnotes, aria). */\n id?: string;\n /** What the table shows. Required: it names the table for screen readers, crawlers and AI answers. */\n caption: string;\n /** One or two sentences under the table: source, method, date. Linked with aria-describedby. */\n notes?: string;\n headerRow: boolean;\n /** First column holds row headers (th scope=row). */\n headerColumn: boolean;\n columns: TableColumn[];\n columnGroups?: TableGroup[];\n rowGroups?: TableGroup[];\n rows: TableRow[];\n footnotes?: TableFootnote[];\n /** Visitor UI on live pages: a filter box above the table. */\n filterable?: boolean;\n /** hideCaption: the caption stays in the HTML (screen readers, crawlers) but isn't drawn — when a heading above says it. */\n design?: { responsive?: TableResponsive; sticky?: boolean; striped?: boolean; density?: \"compact\" | \"comfortable\"; hideCaption?: boolean };\n /** Structured data from the table. Off by default: JSON-LD must describe what the page really offers. */\n jsonLd?: { type: TableJsonLdType; axis?: \"rows\" | \"columns\"; priceRow?: string };\n}\n\n/** Field-level settings (`FieldSchema.table`). */\nexport interface TableFieldOptions {\n /** Column types an editor may choose. Default: all. */\n columnTypes?: TableColumnType[];\n /** Developer-defined columns: editors fill rows but can't add, remove, retype or reorder columns. */\n lockColumns?: boolean;\n minRows?: number;\n maxRows?: number;\n maxColumns?: number;\n /** Default true. */\n requireCaption?: boolean;\n /** Row groups: \"Add group\" in the row list. Default true. */\n allowGroups?: boolean;\n /** Footnotes on cells, edited at the cell. Default true. */\n allowFootnotes?: boolean;\n /**\n * CPO D52: what Table settings offers. Each key turns one setting on or off for this table kind, so the editor only sees\n * what applies. Defaults: header row + first column, totals row, on phones (all three), highlight column ON; visitor\n * sort and search OFF; JSON-LD only when `jsonLd` lists types.\n */\n settings?: TableSettingsOptions;\n /** \"Note under the table\" (the source line, `notes`). Default true. Turn off when the block has its own source field. */\n allowNote?: boolean;\n /** JSON-LD types offered in Table settings (\"Help search engines read this as\"). Default: none offered. */\n jsonLd?: TableJsonLdType[];\n}\n\n/**\n * CPO D52: a table with no `table` options (a rich-text table, the Visuals Table block, a schema field without `table`) is a\n * general table of any kind, so every setting is offered. Setting `table` on a field narrows it to that kind.\n */\nexport const GENERAL_TABLE: TableFieldOptions = { jsonLd: [\"ItemList\", \"Dataset\", \"Offers\"], settings: { sort: true, search: true } };\n\n/** CPO D52: the settings a table kind offers (`FieldSchema.table.settings`). */\nexport interface TableSettingsOptions {\n /** \"Show column names\" (header row) and \"First column names each row\" (row headers). Default true. */\n headers?: boolean;\n /** \"Totals row\": a footer row group at the end of the row list. Default true. */\n totals?: boolean;\n /** \"On phones\": the layouts offered. Default all three; one value fixes it, [] hides the setting. */\n phones?: TableResponsive[];\n /** \"Highlight column\": one column stands out (the recommended plan, your product). Default true. */\n highlight?: boolean;\n /** \"Keep column names in view\" (developer-only, `design.sticky`). Default true; off when the block owns a sticky-header field. */\n sticky?: boolean;\n /** \"Visitors can sort columns\". Default false (data tables turn it on). */\n sort?: boolean;\n /** \"Visitors can search rows\". Default false (long data tables turn it on). */\n search?: boolean;\n}\n\n/* ── Keys + defaults ───────────────────────────────────────────────── */\nlet seq = 0;\nexport const tkey = (p: string) => `${p}${Date.now().toString(36).slice(-4)}${(seq++).toString(36)}${Math.random().toString(36).slice(2, 5)}`;\n\nexport function emptyTable(cols = 3, rows = 2): TableValue {\n const columns = Array.from({ length: cols }, () => ({ _key: tkey(\"c\"), label: \"\", type: \"text\" as const }));\n return {\n id: tkey(\"tbl\"),\n caption: \"\",\n headerRow: true,\n headerColumn: false,\n columns,\n rows: Array.from({ length: rows }, () => ({ _key: tkey(\"r\"), cells: {} })),\n design: { responsive: \"scroll\" },\n };\n}\n\nexport const isObjLike = (v: unknown): v is Record<string, unknown> => !!v && typeof v === \"object\" && !Array.isArray(v);\nexport const isCellObject = (c: unknown): c is TableCellObject => isObjLike(c) && \"value\" in c;\nexport const isTableValue = (v: unknown): v is TableValue => isObjLike(v) && Array.isArray(v.columns) && Array.isArray(v.rows);\n\n/** Repair anything loaded (missing keys, missing arrays) so editors and renderers can trust the shape. */\nexport function normalizeTable(v: unknown): TableValue {\n if (!isTableValue(v)) return emptyTable();\n const used = new Set<string>();\n const uniq = (k: unknown, p: string) => {\n let key = typeof k === \"string\" && k ? k : tkey(p);\n while (used.has(key)) key = tkey(p);\n used.add(key);\n return key;\n };\n const columns = v.columns.filter(isObjLike).map((c) => ({ ...c, _key: uniq(c._key, \"c\"), label: String(c.label ?? \"\"), type: (TABLE_COLUMN_TYPES.some((t) => t.value === c.type) ? c.type : \"text\") as TableColumnType }));\n const rows = v.rows.filter(isObjLike).map((r) => ({ ...r, _key: uniq(r._key, \"r\"), cells: isObjLike(r.cells) ? (r.cells as TableRow[\"cells\"]) : {} }));\n return {\n ...v,\n id: typeof v.id === \"string\" && v.id ? v.id : tkey(\"tbl\"),\n caption: String(v.caption ?? \"\"),\n headerRow: v.headerRow !== false,\n headerColumn: !!v.headerColumn,\n columns,\n rows,\n columnGroups: (v.columnGroups ?? []).filter(isObjLike).map((g) => ({ ...g, _key: uniq(g._key, \"g\") })),\n rowGroups: (v.rowGroups ?? []).filter(isObjLike).map((g) => ({ ...g, _key: uniq(g._key, \"rg\") })),\n footnotes: (v.footnotes ?? []).filter(isObjLike).map((f) => ({ ...f, _key: uniq(f._key, \"f\") })),\n };\n}\n\n/* ── Cells: type, value, text ──────────────────────────────────────── */\nexport const cellValue = (c: TableCell | undefined): TableCellValue => (c === undefined ? null : isCellObject(c) ? c.value : c);\nexport const cellNote = (c: TableCell | undefined): string | undefined => (isCellObject(c) ? c.note : undefined);\nexport const cellType = (col: TableColumn, row?: TableRow, c?: TableCell): TableColumnType => (isCellObject(c) && c.type) || row?.type || col.type;\n\n/** Write a value back, keeping the cell's per-cell type and footnote. */\nexport function withValue(c: TableCell | undefined, value: TableCellValue): TableCell {\n if (isCellObject(c)) return { ...c, value };\n return value;\n}\n\nexport const isEmptyCell = (v: TableCellValue) => v == null || v === \"\" || (isObjLike(v) && !(\"ref\" in v ? v.ref : (v as TableLink).label || (v as TableLink).href));\n\nconst strip = (s: string) => s.replace(/<[^>]*>/g, \"\").replace(/ /g, \" \").replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\").replace(/"/g, '\"').replace(/'/g, \"'\");\n\nexport function boolLabels(col: TableColumn) {\n return { yes: col.trueLabel || \"Included\", no: col.falseLabel || \"Not included\" };\n}\n// V2 also had an unused `symbol(currency)` helper here; dropped because the dashboard compiles with noUnusedLocals.\nexport function formatNumber(n: number, decimals?: number) {\n return new Intl.NumberFormat(\"en-US\", decimals != null ? { minimumFractionDigits: decimals, maximumFractionDigits: decimals } : { maximumFractionDigits: 6 }).format(n);\n}\nexport function formatMoney(n: number, currency = \"USD\", decimals?: number) {\n try {\n const whole = Number.isInteger(n) && decimals == null;\n return new Intl.NumberFormat(\"en-US\", { style: \"currency\", currency, minimumFractionDigits: whole ? 0 : decimals ?? 2, maximumFractionDigits: whole ? 0 : decimals ?? 2 }).format(n);\n } catch {\n return `${formatNumber(n, decimals)} ${currency}`;\n }\n}\nexport const toNumber = (v: unknown): number | null => {\n if (typeof v === \"number\") return Number.isFinite(v) ? v : null;\n if (typeof v !== \"string\") return null;\n const s = v.replace(/[,\\s]/g, \"\").replace(/[^\\d.+-]/g, \"\");\n if (!s || !/^[+-]?\\d*\\.?\\d+$/.test(s)) return null;\n return Number(s);\n};\n\n/** The words a cell says, for Markdown, CSV, sorting, search and screen readers. Empty → \"\". */\nexport function cellText(col: TableColumn, row: TableRow | undefined, c: TableCell | undefined, resolveRef?: RefResolver): string {\n const v = cellValue(c);\n if (isEmptyCell(v)) return \"\";\n const t = cellType(col, row, c);\n switch (t) {\n case \"boolean\": {\n const b = toBool(v);\n return b == null ? strip(String(v)) : b ? boolLabels(col).yes : boolLabels(col).no;\n }\n case \"number\": {\n const n = toNumber(v);\n return n == null ? strip(String(v)) : `${formatNumber(n, col.decimals)}${col.unit ? (/^[%°]/.test(col.unit) ? col.unit : ` ${col.unit}`) : \"\"}`;\n }\n case \"money\": {\n const n = toNumber(v);\n return n == null ? strip(String(v)) : formatMoney(n, col.currency || \"USD\", col.decimals);\n }\n case \"rating\": {\n const n = toNumber(v);\n return n == null ? strip(String(v)) : `${formatNumber(n, 1).replace(/\\.0$/, \"\")} out of ${col.max ?? 5}`;\n }\n case \"link\":\n return isObjLike(v) ? String((v as TableLink).label || (v as TableLink).href || \"\") : strip(String(v));\n case \"reference\": {\n if (!isObjLike(v)) return strip(String(v));\n const r = v as TableRef;\n return resolveRef?.(r.ref)?.label ?? r.label ?? r.ref;\n }\n default:\n return isObjLike(v) ? String((v as TableLink).label ?? \"\") : strip(String(v)).replace(/\\s+/g, \" \").trim();\n }\n}\n\nexport function toBool(v: unknown): boolean | null {\n if (typeof v === \"boolean\") return v;\n if (typeof v !== \"string\") return null;\n const s = strip(v).trim().toLowerCase();\n if (TRUE_WORDS.has(s)) return true;\n if (FALSE_WORDS.has(s)) return false;\n return null;\n}\nconst TRUE_WORDS = new Set([\"✓\", \"✔\", \"✔️\", \"☑\", \"✅\", \"yes\", \"y\", \"true\", \"included\", \"available\", \"supported\", \"x ✓\", \"check\", \"●\"]);\nconst FALSE_WORDS = new Set([\"✗\", \"✕\", \"✖\", \"❌\", \"×\", \"x\", \"no\", \"n\", \"false\", \"not included\", \"unavailable\", \"not available\", \"unsupported\", \"—\", \"–\", \"-\", \"○\"]);\n\n/* ── Render (the ONE renderer) ─────────────────────────────────────── */\nexport type RefResolver = (id: string) => { label: string; href?: string } | undefined;\nexport interface RenderOptions {\n /** Resolve reference cells to their current label + URL. */\n resolveRef?: RefResolver;\n /** Live-page visitor UI: sortable headers become buttons with aria-sort. Never stored. */\n sort?: { key: string; dir: 1 | -1 } | null;\n interactive?: boolean;\n /** Rows to show (filter). Keys. */\n visibleRows?: Set<string>;\n /** Write the editing marks (`data-*` model attributes). Off for clean published HTML. Default true. */\n marks?: boolean;\n}\n\nconst esc = (s: string) => s.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\nconst escAttr = (s: string) => esc(s).replace(/\"/g, \""\");\nconst safeHref = (h: string) => (/^\\s*(javascript|vbscript|data):/i.test(h) ? \"#\" : h);\nconst INLINE_TAGS = new Set([\"strong\", \"b\", \"em\", \"i\", \"u\", \"s\", \"del\", \"code\", \"a\", \"br\", \"sup\", \"sub\", \"mark\", \"small\", \"abbr\"]);\n/** Inline rich text in a cell: only inline marks and safe links survive (string-based, no DOM). */\nexport function sanitizeInline(html: string): string {\n return html\n .replace(/<(script|style|iframe|object|embed|template)\\b[\\s\\S]*?<\\/\\1>/gi, \"\")\n .replace(/<\\/?([a-z][a-z0-9]*)\\b([^>]*)>/gi, (m, tag: string, attrs: string) => {\n const t = tag.toLowerCase();\n if (!INLINE_TAGS.has(t)) return \"\";\n if (m.startsWith(\"</\")) return `</${t === \"b\" ? \"strong\" : t === \"i\" ? \"em\" : t}>`;\n if (t === \"a\") {\n const href = attrs.match(/href\\s*=\\s*(\"([^\"]*)\"|'([^']*)')/i);\n const h = href ? href[2] ?? href[3] ?? \"\" : \"\";\n return `<a href=\"${escAttr(safeHref(h))}\">`;\n }\n if (t === \"abbr\") {\n const title = attrs.match(/title\\s*=\\s*\"([^\"]*)\"/i);\n return title ? `<abbr title=\"${escAttr(title[1])}\">` : \"<abbr>\";\n }\n return `<${t === \"b\" ? \"strong\" : t === \"i\" ? \"em\" : t}>`;\n });\n}\n\nconst alignOf = (col: TableColumn, t: TableColumnType) => col.align ?? (t === \"number\" || t === \"money\" || t === \"rating\" ? \"end\" : \"start\");\nconst footnoteIndex = (t: TableValue) => new Map((t.footnotes ?? []).map((f, i) => [f._key, i + 1]));\n\n/** Inner HTML of one cell + its typed attributes. */\nfunction cellHtml(t: TableValue, col: TableColumn, row: TableRow | undefined, c: TableCell | undefined, o: RenderOptions, fn: Map<string, number>, asHeader: boolean): { inner: string; attrs: string } {\n const v = cellValue(c);\n const type = cellType(col, row, c);\n const marks = o.marks !== false;\n const typeAttr = marks && isCellObject(c) && c.type ? ` data-type=\"${c.type}\"` : \"\";\n const note = cellNote(c);\n const n = note ? fn.get(note) : undefined;\n const sup = n ? `<sup><a href=\"#${escAttr(t.id ?? \"tbl\")}-fn-${n}\" aria-label=\"Note ${n}\">${n}</a></sup>` : \"\";\n const noteAttr = marks && note ? ` data-note=\"${escAttr(note)}\"` : \"\";\n let inner = \"\";\n let valueAttr = \"\";\n if (isEmptyCell(v)) {\n inner = asHeader ? \"\" : `<span aria-hidden=\"true\" class=\"bt-dash\">—</span><span class=\"bt-sr\">No value</span>`;\n valueAttr = marks ? ` data-empty=\"\"` : \"\";\n } else\n switch (type) {\n case \"boolean\": {\n const b = toBool(v);\n if (b == null) inner = esc(strip(String(v)));\n else {\n const { yes, no } = boolLabels(col);\n inner = `<span aria-hidden=\"true\" class=\"bt-bool\" data-bool=\"${b}\">${b ? \"✓\" : \"–\"}</span><span class=\"bt-sr\">${esc(b ? yes : no)}</span>`;\n valueAttr = marks ? ` data-value=\"${b}\"` : \"\";\n }\n break;\n }\n case \"number\":\n case \"money\": {\n const num = toNumber(v);\n inner = esc(cellText(col, row, c));\n if (num != null && marks) valueAttr = ` data-value=\"${num}\"`;\n break;\n }\n case \"rating\": {\n const num = toNumber(v);\n if (num == null) inner = esc(strip(String(v)));\n else {\n const max = col.max ?? 5;\n // one reading for everyone: \"4.7 / 5\" (the star is decoration)\n inner = `<span aria-hidden=\"true\" class=\"bt-star\">★</span> ${esc(formatNumber(num, 1).replace(/\\.0$/, \"\"))}<span class=\"bt-dim\"> / ${max}</span>`;\n if (marks) valueAttr = ` data-value=\"${num}\"`;\n }\n break;\n }\n case \"link\": {\n const l = isObjLike(v) ? (v as TableLink) : { label: String(v), href: \"\" };\n const rel = [l.newTab ? \"noopener\" : \"\", l.rel && l.rel !== \"follow\" ? l.rel : \"\"].filter(Boolean).join(\" \");\n inner = l.href ? `<a href=\"${escAttr(safeHref(l.href))}\"${l.newTab ? ' target=\"_blank\"' : \"\"}${rel ? ` rel=\"${rel}\"` : \"\"}>${esc(l.label || l.href)}</a>` : esc(l.label);\n break;\n }\n case \"reference\": {\n const r: TableRef = isObjLike(v) ? (v as TableRef) : { ref: String(v) };\n const live = o.resolveRef?.(r.ref);\n const label = live?.label ?? r.label ?? r.ref;\n const href = live?.href ?? r.href;\n inner = href ? `<a href=\"${escAttr(safeHref(href))}\">${esc(label)}</a>` : esc(label);\n if (marks) valueAttr = ` data-ref=\"${escAttr(r.ref)}\"`;\n break;\n }\n case \"richtext-inline\":\n inner = sanitizeInline(String(isObjLike(v) ? (v as TableLink).label ?? \"\" : v));\n break;\n default:\n inner = esc(isObjLike(v) ? String((v as TableLink).label ?? \"\") : strip(String(v)));\n }\n const align = alignOf(col, type);\n const alignAttr = align !== \"start\" ? ` data-align=\"${align}\"` : \"\";\n return { inner: inner + sup, attrs: `${typeAttr}${valueAttr}${noteAttr}${alignAttr}` };\n}\n\n/** Rows in display order: body rows (ungrouped first, then each row group in its order), footer rows. */\nexport function orderedRows(t: TableValue) {\n const groups = t.rowGroups ?? [];\n const known = new Set(groups.map((g) => g._key));\n const body = t.rows.filter((r) => !r.footer);\n const loose = body.filter((r) => !r.group || !known.has(r.group));\n const bodies: { group?: TableGroup; rows: TableRow[] }[] = [];\n if (loose.length || !groups.length) bodies.push({ rows: loose });\n for (const g of groups) {\n const rows = body.filter((r) => r.group === g._key);\n if (rows.length) bodies.push({ group: g, rows });\n }\n return { bodies, foot: t.rows.filter((r) => r.footer) };\n}\n\n/** Sort comparator over a column (numbers numerically, booleans true first, text by locale). */\nexport function sortRows(t: TableValue, rows: TableRow[], key: string, dir: 1 | -1): TableRow[] {\n const col = t.columns.find((c) => c._key === key);\n if (!col) return rows;\n const val = (r: TableRow) => {\n const c = r.cells[key];\n const ty = cellType(col, r, c);\n const v = cellValue(c);\n if (ty === \"number\" || ty === \"money\" || ty === \"rating\") return toNumber(v);\n if (ty === \"boolean\") return toBool(v) == null ? null : toBool(v) ? 1 : 0;\n return cellText(col, r, c).toLowerCase() || null;\n };\n return [...rows].sort((a, b) => {\n const x = val(a);\n const y = val(b);\n if (x == null && y == null) return 0;\n if (x == null) return 1; // empty last, whichever direction\n if (y == null) return -1;\n return (typeof x === \"number\" && typeof y === \"number\" ? x - y : String(x).localeCompare(String(y), \"en\", { numeric: true })) * dir;\n });\n}\n\n/** The table as semantic HTML: <figure data-rt=\"table\"> › <table> (caption, colgroup, thead, tbody…, tfoot) + notes. */\nexport function renderTableHtml(input: TableValue, o: RenderOptions = {}): string {\n const t = normalizeTable(input);\n const marks = o.marks !== false;\n const id = t.id!;\n const cols = t.columns;\n const n = cols.length;\n const fn = footnoteIndex(t);\n const groups = (t.columnGroups ?? []).filter((g) => cols.some((c) => c.group === g._key));\n const describedBy = t.notes || (t.footnotes ?? []).length ? ` aria-describedby=\"${escAttr(id)}-notes\"` : \"\";\n const fig: string[] = [];\n const figAttrs = [\n `data-rt=\"table\"`,\n `data-id=\"${escAttr(id)}\"`,\n `class=\"bt-table\"`,\n marks ? `data-header-row=\"${t.headerRow}\"` : \"\",\n t.headerColumn ? `data-header-col=\"true\"` : \"\",\n `data-responsive=\"${t.design?.responsive ?? \"scroll\"}\"`,\n t.design?.sticky ? `data-sticky=\"true\"` : \"\",\n t.design?.striped ? `data-striped=\"true\"` : \"\",\n t.design?.density === \"compact\" ? `data-density=\"compact\"` : \"\",\n t.design?.hideCaption ? `data-caption=\"hidden\"` : \"\",\n marks && t.filterable ? `data-filter=\"true\"` : \"\",\n marks && t.jsonLd && t.jsonLd.type !== \"none\" ? `data-jsonld=\"${t.jsonLd.type}\"${t.jsonLd.axis ? ` data-jsonld-axis=\"${t.jsonLd.axis}\"` : \"\"}${t.jsonLd.priceRow ? ` data-jsonld-price=\"${escAttr(t.jsonLd.priceRow)}\"` : \"\"}` : \"\",\n ].filter(Boolean);\n fig.push(`<figure ${figAttrs.join(\" \")}>`);\n // the scroll region names itself after the caption; the table keeps its own (implicit) role\n fig.push(`<div class=\"bt-scroll\" role=\"region\" tabindex=\"0\" aria-labelledby=\"${escAttr(id)}-caption\">`);\n fig.push(`<table${describedBy}>`);\n fig.push(`<caption id=\"${escAttr(id)}-caption\"${t.design?.hideCaption ? ` class=\"bt-sr\"` : \"\"}>${esc(t.caption || \"Table\")}</caption>`);\n if (marks || groups.length) {\n fig.push(\n `<colgroup>${cols\n .map((c) => {\n if (!marks) return \"<col>\";\n const a = [\n `data-key=\"${escAttr(c._key)}\"`,\n `data-type=\"${c.type}\"`,\n c.unit ? `data-unit=\"${escAttr(c.unit)}\"` : \"\",\n c.currency ? `data-currency=\"${escAttr(c.currency)}\"` : \"\",\n c.decimals != null ? `data-decimals=\"${c.decimals}\"` : \"\",\n c.align ? `data-align=\"${c.align}\"` : \"\",\n c.sortable ? `data-sortable=\"true\"` : \"\",\n c.group ? `data-group=\"${escAttr(c.group)}\"` : \"\",\n c.trueLabel ? `data-true=\"${escAttr(c.trueLabel)}\"` : \"\",\n c.falseLabel ? `data-false=\"${escAttr(c.falseLabel)}\"` : \"\",\n c.max != null ? `data-max=\"${c.max}\"` : \"\",\n c.refTo?.length ? `data-ref-to=\"${escAttr(c.refTo.join(\",\"))}\"` : \"\",\n c.description ? `data-description=\"${escAttr(c.description)}\"` : \"\",\n c.highlight ? `data-highlight=\"true\"` : \"\",\n ].filter(Boolean);\n return `<col ${a.join(\" \")}>`;\n })\n .join(\"\")}</colgroup>`,\n );\n }\n // header\n if (t.headerRow) {\n fig.push(\"<thead>\");\n if (groups.length) {\n const cells: string[] = [];\n for (let i = 0; i < n; ) {\n const g = cols[i].group && groups.find((x) => x._key === cols[i].group);\n if (!g) {\n cells.push(`<td></td>`);\n i++;\n continue;\n }\n let span = 1;\n while (i + span < n && cols[i + span].group === g._key) span++;\n cells.push(`<th scope=\"colgroup\"${span > 1 ? ` colspan=\"${span}\"` : \"\"}${marks ? ` data-group=\"${escAttr(g._key)}\"` : \"\"}>${esc(g.label)}</th>`);\n i += span;\n }\n fig.push(`<tr${marks ? \" data-groups\" : \"\"}>${cells.join(\"\")}</tr>`);\n }\n fig.push(\n `<tr>${cols\n .map((c, i) => {\n const type = c.type;\n const align = alignOf(c, type);\n const sortable = o.interactive && c.sortable;\n const dir = o.sort?.key === c._key ? o.sort.dir : 0;\n const ariaSort = sortable ? ` aria-sort=\"${dir === 1 ? \"ascending\" : dir === -1 ? \"descending\" : \"none\"}\"` : \"\";\n // an unnamed corner over the row headers is a plain cell, not an empty header\n if (i === 0 && t.headerColumn && !c.label.trim()) return `<td${marks ? ` data-col=\"${escAttr(c._key)}\"` : \"\"}></td>`;\n const label = esc(c.label || `Column ${i + 1}`);\n const title = c.description ? ` title=\"${escAttr(c.description)}\"` : \"\";\n const content = sortable ? `<button type=\"button\" class=\"bt-sort\" data-sort-key=\"${escAttr(c._key)}\">${label}<span aria-hidden=\"true\" class=\"bt-sort-icon\">${dir === 1 ? \"↑\" : dir === -1 ? \"↓\" : \"↕\"}</span></button>` : label;\n return `<th scope=\"col\"${marks ? ` data-col=\"${escAttr(c._key)}\"` : \"\"}${align !== \"start\" ? ` data-align=\"${align}\"` : \"\"}${c.highlight ? ` data-highlight=\"true\"` : \"\"}${title}${ariaSort}>${content}</th>`;\n })\n .join(\"\")}</tr>`,\n );\n fig.push(\"</thead>\");\n }\n const rowHtml = (r: TableRow) => {\n const cells = cols.map((c, i) => {\n const asTh = t.headerColumn && i === 0;\n const { inner, attrs } = cellHtml(t, c, r, r.cells[c._key], o, fn, asTh);\n const label = ` data-label=\"${escAttr(c.label || `Column ${i + 1}`)}\"${c.highlight ? ` data-highlight=\"true\"` : \"\"}`;\n return asTh ? `<th scope=\"row\"${marks ? ` data-col=\"${escAttr(c._key)}\"` : \"\"}${attrs}>${inner}</th>` : `<td${marks ? ` data-col=\"${escAttr(c._key)}\"` : \"\"}${label}${attrs}>${inner}</td>`;\n });\n return `<tr${marks ? ` data-key=\"${escAttr(r._key)}\"` : \"\"}${marks && r.type ? ` data-type=\"${r.type}\"` : \"\"}${r.highlight ? ` data-highlight=\"true\"` : \"\"}>${cells.join(\"\")}</tr>`;\n };\n const { bodies, foot } = orderedRows(t);\n const vis = (rows: TableRow[]) => {\n const kept = o.visibleRows ? rows.filter((r) => o.visibleRows!.has(r._key)) : rows;\n return o.sort ? sortRows(t, kept, o.sort.key, o.sort.dir) : kept;\n };\n for (const b of bodies) {\n const rows = vis(b.rows);\n if (b.group) {\n fig.push(`<tbody${marks ? ` data-key=\"${escAttr(b.group._key)}\" data-label=\"${escAttr(b.group.label)}\"` : \"\"}>`);\n fig.push(`<tr class=\"bt-group\"${marks ? \" data-group-row\" : \"\"}><th scope=\"rowgroup\" colspan=\"${n}\">${esc(b.group.label)}</th></tr>`);\n } else fig.push(\"<tbody>\");\n fig.push(rows.map(rowHtml).join(\"\"));\n fig.push(\"</tbody>\");\n }\n if (foot.length) fig.push(`<tfoot>${foot.map(rowHtml).join(\"\")}</tfoot>`);\n fig.push(\"</table></div>\");\n if (t.notes || (t.footnotes ?? []).length) {\n fig.push(`<div class=\"bt-notes\" id=\"${escAttr(id)}-notes\">`);\n if (t.notes) fig.push(`<p${marks ? \" data-notes\" : \"\"}>${esc(t.notes)}</p>`);\n if ((t.footnotes ?? []).length)\n fig.push(`<ol${marks ? \" data-footnotes\" : \"\"}>${t.footnotes!.map((f, i) => `<li id=\"${escAttr(id)}-fn-${i + 1}\"${marks ? ` data-key=\"${escAttr(f._key)}\"` : \"\"}>${esc(f.text)}</li>`).join(\"\")}</ol>`);\n fig.push(\"</div>\");\n }\n fig.push(\"</figure>\");\n const html = fig.join(\"\");\n return t.design?.responsive === \"stack\" || t.design?.responsive === \"cards\" ? withTableRoles(html) : html;\n}\n\n/**\n * Stack / Cards change `display` on table parts, which makes some engines drop table semantics. The fix (Adrian\n * Roselli, \"Tables, CSS Display Properties, and ARIA\") restates the SAME roles explicitly — semantics unchanged.\n * Cell contents are sanitized inline HTML, so these tag patterns only ever match the table's own structure.\n */\nfunction withTableRoles(html: string) {\n return html\n .replace(/<table(?=[\\s>])/, '<table role=\"table\"')\n .replace(/<(thead|tbody|tfoot)(?=[\\s>])/g, '<$1 role=\"rowgroup\"')\n .replace(/<tr(?=[\\s>])/g, '<tr role=\"row\"')\n .replace(/<th scope=\"(col|colgroup)\"/g, '<th role=\"columnheader\" scope=\"$1\"')\n .replace(/<th scope=\"(row|rowgroup)\"/g, '<th role=\"rowheader\" scope=\"$1\"')\n .replace(/<td(?=[\\s>])/g, '<td role=\"cell\"');\n}\n\n/* ── Markdown (GFM) ────────────────────────────────────────────────── */\nconst mdCell = (s: string) => s.replace(/\\\\/g, \"\\\\\\\\\").replace(/\\|/g, \"\\\\|\").replace(/\\s*\\n\\s*/g, \" \").trim();\nfunction inlineMd(html: string): string {\n return strip(\n sanitizeInline(html)\n .replace(/<(strong)>([\\s\\S]*?)<\\/\\1>/g, \"**$2**\")\n .replace(/<(em)>([\\s\\S]*?)<\\/\\1>/g, \"_$2_\")\n .replace(/<code>([\\s\\S]*?)<\\/code>/g, \"`$1`\")\n .replace(/<a href=\"([^\"]*)\">([\\s\\S]*?)<\\/a>/g, (_m, h: string, l: string) => `[${l}](${h.replace(/&/g, \"&\")})`)\n .replace(/<br>/g, \" \"),\n );\n}\n/**\n * GFM has one header row and no spans, so: column groups prefix their columns (\"Sizes · Chest\"), row groups become a\n * bold label row, the caption is a bold line above, notes and footnotes follow. Booleans say their words, never ✓.\n */\nexport function tableToMarkdown(input: TableValue, o: { resolveRef?: RefResolver; abs?: (href: string) => string } = {}): string {\n const t = normalizeTable(input);\n const cols = t.columns;\n if (!cols.length) return \"\";\n const groups = new Map((t.columnGroups ?? []).map((g) => [g._key, g.label]));\n const fn = footnoteIndex(t);\n const pfx = (t.id ?? \"t\").replace(/[^\\w-]/g, \"\");\n const head = cols.map((c, i) => mdCell([c.group && groups.get(c.group), c.label || (i === 0 && t.headerColumn ? \"\" : `Column ${i + 1}`)].filter(Boolean).join(\" · \")) || \" \");\n const sep = cols.map((c) => (alignOf(c, c.type) === \"end\" ? \"---:\" : alignOf(c, c.type) === \"center\" ? \":---:\" : \"---\"));\n const line = (cells: string[]) => `| ${cells.join(\" | \")} |`;\n const row = (r: TableRow) =>\n line(\n cols.map((c, i) => {\n const cell = r.cells[c._key];\n const v = cellValue(cell);\n const ty = cellType(c, r, cell);\n let s = ty === \"richtext-inline\" && typeof v === \"string\" ? inlineMd(v) : cellText(c, r, cell, o.resolveRef);\n if (ty === \"link\" && isObjLike(v) && (v as TableLink).href) s = `[${s}](${o.abs ? o.abs((v as TableLink).href) : (v as TableLink).href})`;\n if (ty === \"reference\" && isObjLike(v)) {\n const href = o.resolveRef?.((v as TableRef).ref)?.href ?? (v as TableRef).href;\n if (href) s = `[${s}](${o.abs ? o.abs(href) : href})`;\n }\n if (!s && !(t.headerColumn && i === 0)) s = \"—\";\n if (t.headerColumn && i === 0 && s) s = `**${s}**`;\n const note = cellNote(cell);\n if (note && fn.get(note)) s += `[^${pfx}-${fn.get(note)}]`;\n return mdCell(s) || \" \";\n }),\n );\n const out: string[] = [];\n out.push(`**${mdCell(t.caption || \"Table\")}**`, \"\");\n out.push(line(head), line(sep));\n const { bodies, foot } = orderedRows(t);\n for (const b of bodies) {\n if (b.group) out.push(line([`**${mdCell(b.group.label)}**`, ...cols.slice(1).map(() => \" \")]));\n b.rows.forEach((r) => out.push(row(r)));\n }\n foot.forEach((r) => out.push(row(r)));\n const after: string[] = [];\n if (t.notes) after.push(t.notes);\n const described = cols.filter((c) => c.description);\n if (described.length) after.push(described.map((c) => `${c.label}: ${c.description}`).join(\". \") + \".\");\n if ((t.footnotes ?? []).length) after.push(t.footnotes!.map((f, i) => `[^${pfx}-${i + 1}]: ${f.text}`).join(\"\\n\"));\n return [out.join(\"\\n\"), ...after].join(\"\\n\\n\");\n}\n\n/* ── CSV / TSV ─────────────────────────────────────────────────────── */\n/** RFC 4180 parser; the delimiter is a tab when the text has one (Excel / Sheets copy), else `;` or `,` by count. */\nexport function parseDelimited(text: string, delim?: string): string[][] {\n const src = text.replace(/\\r\\n?/g, \"\\n\").replace(/\\n+$/, \"\");\n if (!src.trim()) return [];\n const firstLine = src.split(\"\\n\")[0];\n const d = delim ?? (firstLine.includes(\"\\t\") ? \"\\t\" : (firstLine.match(/;/g)?.length ?? 0) > (firstLine.match(/,/g)?.length ?? 0) ? \";\" : \",\");\n const rows: string[][] = [];\n let row: string[] = [];\n let cell = \"\";\n let q = false;\n for (let i = 0; i < src.length; i++) {\n const ch = src[i];\n if (q) {\n if (ch === '\"' && src[i + 1] === '\"') {\n cell += '\"';\n i++;\n } else if (ch === '\"') q = false;\n else cell += ch;\n } else if (ch === '\"' && cell === \"\") q = true;\n else if (ch === d) {\n row.push(cell);\n cell = \"\";\n } else if (ch === \"\\n\") {\n row.push(cell);\n rows.push(row);\n row = [];\n cell = \"\";\n } else cell += ch;\n }\n row.push(cell);\n rows.push(row);\n const w = Math.max(...rows.map((r) => r.length));\n return rows.map((r) => [...r.map((c) => c.trim()), ...Array(w - r.length).fill(\"\")]);\n}\nexport function toDelimited(rows: string[][], delim = \",\"): string {\n return rows.map((r) => r.map((c) => (/[\",\\n\\t;]/.test(c) ? `\"${c.replace(/\"/g, '\"\"')}\"` : c)).join(delim)).join(\"\\n\");\n}\n/** Header + body rows as text (CSV export, \"Copy as CSV\"). */\nexport function tableToRows(input: TableValue, resolveRef?: RefResolver): string[][] {\n const t = normalizeTable(input);\n const { bodies, foot } = orderedRows(t);\n const all = [...bodies.flatMap((b) => b.rows), ...foot];\n return [t.columns.map((c) => c.label), ...all.map((r) => t.columns.map((c) => cellText(c, r, r.cells[c._key], resolveRef)))];\n}\n\n/* ── Type inference (CSV, paste, HTML import) ──────────────────────── */\nconst CURRENCY: Record<string, string> = { $: \"USD\", \"€\": \"EUR\", \"£\": \"GBP\", \"¥\": \"JPY\", \"₹\": \"INR\", \"A$\": \"AUD\", \"C$\": \"CAD\", \"CHF\": \"CHF\" };\nconst MONEY_RX = /^(A\\$|C\\$|CHF|[$€£¥₹])\\s?-?[\\d,]*\\.?\\d+$|^-?[\\d,]*\\.?\\d+\\s?(USD|EUR|GBP|JPY|INR|AUD|CAD|CHF)$/i;\nconst NUM_RX = /^([+-]?[\\d,]*\\.?\\d+)\\s?([a-zA-Z%°][a-zA-Z%°²³/]*)?$/;\nconst RATING_RX = /^(\\d(?:\\.\\d)?)\\s?(?:\\/\\s?(5|10)|★|stars?|out of (5|10))$/i;\n\nexport interface InferredColumn {\n type: TableColumnType;\n unit?: string;\n currency?: string;\n max?: number;\n}\n/** Look at a column's non-empty values and pick the narrowest type every value fits. */\nexport function inferColumn(values: string[]): InferredColumn {\n const vs = values.map((v) => v.trim()).filter(Boolean);\n if (!vs.length) return { type: \"text\" };\n const txt = vs.map((v) => strip(v).trim());\n if (txt.every((v) => toBool(v) != null) && txt.some((v) => toBool(v) === true)) return { type: \"boolean\" };\n if (txt.every((v) => MONEY_RX.test(v))) {\n const sym = txt[0].match(/^(A\\$|C\\$|CHF|[$€£¥₹])/)?.[1] ?? txt[0].match(/(USD|EUR|GBP|JPY|INR|AUD|CAD|CHF)$/i)?.[1]?.toUpperCase();\n const cur = sym ? CURRENCY[sym] ?? sym : \"USD\";\n if (txt.every((v) => (v.match(/^(A\\$|C\\$|CHF|[$€£¥₹])/)?.[1] ?? v.match(/(USD|EUR|GBP|JPY|INR|AUD|CAD|CHF)$/i)?.[1]?.toUpperCase()) === sym)) return { type: \"money\", currency: cur };\n }\n const rating = txt.map((v) => v.match(RATING_RX));\n if (rating.every(Boolean)) return { type: \"rating\", max: Number(rating[0]![2] || rating[0]![3] || 5) };\n const nums = txt.map((v) => v.match(NUM_RX));\n if (nums.every(Boolean)) {\n const units = new Set(nums.map((m) => m![2] ?? \"\"));\n if (units.size === 1) return { type: \"number\", ...([...units][0] ? { unit: [...units][0] } : {}) };\n }\n if (vs.every((v) => /^<a\\s[^>]*href=/i.test(v) && /<\\/a>\\s*$/i.test(v) && (v.match(/<a\\s/gi)?.length ?? 0) === 1)) return { type: \"link\" };\n if (vs.some((v) => /<(strong|b|em|i|a|code|sup|sub|br)\\b/i.test(v))) return { type: \"richtext-inline\" };\n return { type: \"text\" };\n}\n/** A raw string (CSV / paste / HTML cell) → a value of `type`. */\nexport function coerce(raw: string, col: Pick<TableColumn, \"type\" | \"max\">): TableCellValue {\n const s = raw.trim();\n const plain = strip(s).trim();\n if (!plain && col.type !== \"richtext-inline\") return null;\n switch (col.type) {\n case \"boolean\":\n return toBool(plain) ?? plain;\n case \"number\":\n case \"money\":\n return toNumber(plain.replace(/(USD|EUR|GBP|JPY|INR|AUD|CAD|CHF)$/i, \"\")) ?? plain;\n case \"rating\": {\n const m = plain.match(/(\\d+(?:\\.\\d+)?)/);\n return m ? Number(m[1]) : plain;\n }\n case \"link\": {\n const m = s.match(/<a\\s[^>]*href\\s*=\\s*\"([^\"]*)\"[^>]*>([\\s\\S]*?)<\\/a>/i);\n if (m) return { label: strip(m[2]).trim(), href: m[1].replace(/&/g, \"&\") };\n return /^(https?:|\\/|mailto:)/.test(plain) ? { label: plain, href: plain } : { label: plain, href: \"\" };\n }\n case \"richtext-inline\":\n return sanitizeInline(s);\n default:\n return plain;\n }\n}\n\n/** Text rows (CSV, TSV, a pasted range) → a table. `header`: first row holds the column labels. */\nexport function tableFromRows(rows: string[][], opts: { header?: boolean; caption?: string } = {}): TableValue {\n const header = opts.header ?? true;\n const width = Math.max(1, ...rows.map((r) => r.length));\n const labels = header ? rows[0] ?? [] : [];\n const body = header ? rows.slice(1) : rows;\n const columns: TableColumn[] = Array.from({ length: width }, (_, i) => {\n const inf = inferColumn(body.map((r) => r[i] ?? \"\"));\n return { _key: tkey(\"c\"), label: strip(labels[i] ?? \"\").trim(), ...inf };\n });\n const out = emptyTable(0, 0);\n out.caption = opts.caption ?? \"\";\n out.columns = columns;\n // an empty top-left header over a text column = the first column names the rows (\"\", Carbon steel, Cast iron)\n out.headerColumn = header && !!rows.length && !strip(labels[0] ?? \"\").trim() && columns[0]?.type === \"text\" && width > 1;\n out.rows = body.filter((r) => r.some((c) => c.trim())).map((r) => ({ _key: tkey(\"r\"), cells: Object.fromEntries(columns.map((c, i) => [c._key, coerce(r[i] ?? \"\", c)])) }));\n return out;\n}\n\n/** Paste a text range into a table at (row, col), growing rows / columns as needed. Values coerce to column types. */\nexport function pasteRange(input: TableValue, at: { row: number; col: number }, grid: string[][], opts: { lockColumns?: boolean } = {}): TableValue {\n const t = normalizeTable(input);\n const columns = [...t.columns];\n const rows = t.rows.map((r) => ({ ...r, cells: { ...r.cells } }));\n let r0 = at.row;\n let g = grid;\n if (r0 < 0) {\n // pasted on the header row: the first line is labels\n const labels = g[0] ?? [];\n labels.forEach((l, j) => {\n const ci = at.col + j;\n if (ci >= columns.length) {\n if (opts.lockColumns) return;\n columns.push({ _key: tkey(\"c\"), label: \"\", type: \"text\" });\n }\n columns[ci] = { ...columns[ci], label: strip(l).trim() };\n });\n g = g.slice(1);\n r0 = 0;\n }\n const need = at.col + Math.max(0, ...g.map((r) => r.length));\n while (!opts.lockColumns && columns.length < need) columns.push({ _key: tkey(\"c\"), label: \"\", type: \"text\" });\n g.forEach((line, i) => {\n const ri = r0 + i;\n while (rows.length <= ri) rows.push({ _key: tkey(\"r\"), cells: {} });\n line.forEach((raw, j) => {\n const col = columns[at.col + j];\n if (!col) return;\n rows[ri].cells[col._key] = withValue(rows[ri].cells[col._key], coerce(raw, { type: cellType(col, rows[ri], rows[ri].cells[col._key]), max: col.max }));\n });\n });\n return { ...t, columns, rows };\n}\n\n/* ── HTML → table (ours, or any site's) ────────────────────────────── */\n/**\n * Read a DOM <table> (or our <figure data-rt=\"table\">) into the model. Our own data-* marks round-trip losslessly;\n * any other table is inferred: header rows from thead / th, row headers from tbody th[scope=row] or a th first cell,\n * caption from <caption> / figcaption / aria-label, groups from thead colspans and multiple <tbody> / rowgroup rows,\n * footer from <tfoot>, types from cell text (✓/✗ → boolean, $ → money, 4.5/5 → rating), footnote marks kept as notes.\n * Body cells with colspan/rowspan are expanded (copied) — the model has no merged body cells.\n */\nexport function parseTableElement(el: Element): TableValue {\n const fig = el.matches(\"figure\") ? el : el.closest(\"figure[data-rt=table]\");\n const table = (el.matches(\"table\") ? el : el.querySelector(\"table\")) as HTMLTableElement | null;\n const out = emptyTable(0, 0);\n if (!table) return emptyTable();\n const ds = (fig as HTMLElement | null)?.dataset ?? {};\n out.id = ds.id || out.id;\n out.caption = (table.querySelector(\":scope > caption\")?.textContent ?? fig?.querySelector(\":scope > figcaption\")?.textContent ?? table.getAttribute(\"aria-label\") ?? \"\").trim();\n out.notes = (fig?.querySelector(\"[data-notes]\")?.textContent ?? \"\").trim() || undefined;\n const fnEls = Array.from(fig?.querySelectorAll(\"[data-footnotes] > li\") ?? []);\n out.footnotes = fnEls.map((li) => ({ _key: (li as HTMLElement).dataset.key || tkey(\"f\"), text: (li.textContent ?? \"\").trim() }));\n if (!out.footnotes.length) delete out.footnotes;\n const fnByIndex = new Map((out.footnotes ?? []).map((f, i) => [i + 1, f._key]));\n if (ds.responsive === \"stack\" || ds.responsive === \"cards\") out.design = { ...out.design, responsive: ds.responsive };\n if (ds.sticky === \"true\") out.design = { ...out.design, sticky: true };\n if (ds.striped === \"true\") out.design = { ...out.design, striped: true };\n if (ds.density === \"compact\") out.design = { ...out.design, density: \"compact\" };\n if (ds.caption === \"hidden\") out.design = { ...out.design, hideCaption: true };\n if (ds.filter === \"true\") out.filterable = true;\n if (ds.jsonld) out.jsonLd = { type: ds.jsonld as TableJsonLdType, ...(ds.jsonldAxis ? { axis: ds.jsonldAxis as \"rows\" | \"columns\" } : {}), ...(ds.jsonldPrice ? { priceRow: ds.jsonldPrice } : {}) };\n\n // grid expansion (handles colspan / rowspan in any section)\n type Cell = { el: HTMLTableCellElement; th: boolean; origin: boolean };\n const expand = (trs: HTMLTableRowElement[]) => {\n const grid: Cell[][] = [];\n trs.forEach((tr, ri) => {\n grid[ri] ??= [];\n let ci = 0;\n for (const c of Array.from(tr.cells)) {\n while (grid[ri][ci]) ci++;\n const cs = Math.max(1, Math.min(50, c.colSpan || 1));\n const rs = Math.max(1, Math.min(200, c.rowSpan || 1));\n for (let dr = 0; dr < rs; dr++)\n for (let dc = 0; dc < cs; dc++) {\n grid[ri + dr] ??= [];\n grid[ri + dr][ci + dc] = { el: c, th: c.tagName === \"TH\", origin: dr === 0 && dc === 0 };\n }\n ci += cs;\n }\n });\n return grid;\n };\n const theadRows = Array.from(table.tHead?.rows ?? []);\n const bodies = Array.from(table.tBodies);\n const footRows = Array.from(table.tFoot?.rows ?? []);\n let bodyRows = bodies.flatMap((b) => Array.from(b.rows).map((tr) => ({ tr, body: b })));\n // no thead: leading rows made only of th are the header\n const head = [...theadRows];\n if (!head.length) {\n while (bodyRows.length && Array.from(bodyRows[0].tr.cells).every((c) => c.tagName === \"TH\") && bodyRows[0].tr.cells.length > 1) {\n head.push(bodyRows[0].tr);\n bodyRows = bodyRows.slice(1);\n }\n }\n const hgrid = expand(head);\n const width = Math.max(1, ...hgrid.map((r) => r.length), ...expand(bodyRows.map((b) => b.tr)).map((r) => r.length));\n out.headerRow = head.length > 0;\n const cols = Array.from(table.querySelectorAll(\":scope > colgroup > col\"));\n const lastHead = hgrid[hgrid.length - 1] ?? [];\n const columns: TableColumn[] = Array.from({ length: width }, (_, i) => {\n const col = cols[i] as HTMLElement | undefined;\n const d = col?.dataset ?? {};\n const hc = lastHead[i]?.el;\n const label = hc ? cleanText(hc) : \"\";\n const c: TableColumn = { _key: d.key || (hc as HTMLElement | undefined)?.dataset?.col || tkey(\"c\"), label, type: (d.type as TableColumnType) || \"text\" };\n if (d.unit) c.unit = d.unit;\n if (d.currency) c.currency = d.currency;\n if (d.decimals) c.decimals = Number(d.decimals);\n if (d.align) c.align = d.align as TableColumn[\"align\"];\n if (d.sortable === \"true\") c.sortable = true;\n if (d.true) c.trueLabel = d.true;\n if (d.false) c.falseLabel = d.false;\n if (d.max) c.max = Number(d.max);\n if (d.refTo) c.refTo = d.refTo.split(\",\");\n if (d.highlight === \"true\") c.highlight = true;\n if (d.description) c.description = d.description;\n else if (hc?.getAttribute(\"title\")) c.description = hc.getAttribute(\"title\")!;\n return c;\n });\n // column groups: a header row above the last whose cells span several columns\n if (hgrid.length > 1) {\n const top = hgrid[0];\n const groups: TableGroup[] = [];\n for (let i = 0; i < width; ) {\n const cell = top[i];\n let span = 1;\n while (cell && i + span < width && top[i + span]?.el === cell.el) span++;\n const text = cell && cell.el !== lastHead[i]?.el ? cleanText(cell.el) : \"\";\n if (text) {\n const key = (cell.el as HTMLElement).dataset.group || tkey(\"g\");\n groups.push({ _key: key, label: text });\n for (let k = 0; k < span; k++) columns[i + k].group = key;\n }\n i += span;\n }\n if (groups.length) out.columnGroups = groups;\n }\n // body\n const rowGroups: TableGroup[] = [];\n const known = !!cols.length && cols.some((c) => (c as HTMLElement).dataset.type);\n const rawRows: { key: string; group?: string; footer?: boolean; type?: TableColumnType; highlight?: boolean; cells: (Cell | undefined)[] }[] = [];\n let currentGroup: string | undefined;\n let lastBody: HTMLTableSectionElement | null = null;\n const bgrid = expand(bodyRows.map((b) => b.tr));\n bodyRows.forEach(({ tr, body }, ri) => {\n if (body !== lastBody) {\n lastBody = body;\n const label = (body as HTMLElement).dataset.label;\n currentGroup = label ? ((body as HTMLElement).dataset.key || tkey(\"rg\")) : undefined;\n if (label && currentGroup) rowGroups.push({ _key: currentGroup, label });\n }\n const cells = bgrid[ri] ?? [];\n // a row that is one cell spanning the table (th scope=rowgroup, or a lone th/td colspan=all) opens a row group\n const only = tr.cells.length === 1 && (tr.cells[0].colSpan >= width || tr.cells[0].getAttribute(\"scope\") === \"rowgroup\");\n if (only || tr.hasAttribute(\"data-group-row\")) {\n // our own group row repeats its <tbody data-label>; anyone else's opens a new group\n if (!(tr.hasAttribute(\"data-group-row\") && (body as HTMLElement).dataset.label)) {\n currentGroup = tkey(\"rg\");\n rowGroups.push({ _key: currentGroup, label: cleanText(tr.cells[0]) });\n }\n return;\n }\n rawRows.push({ key: (tr as HTMLElement).dataset.key || tkey(\"r\"), group: currentGroup, type: ((tr as HTMLElement).dataset.type as TableColumnType) || undefined, highlight: (tr as HTMLElement).dataset.highlight === \"true\", cells });\n });\n expand(footRows).forEach((cells, i) => rawRows.push({ key: (footRows[i] as HTMLElement).dataset.key || tkey(\"r\"), footer: true, cells }));\n // header column: our mark, or every body row starts with a th\n out.headerColumn = ds.headerCol === \"true\" || (rawRows.length > 0 && rawRows.every((r) => r.cells[0]?.th && r.cells[0].el.getAttribute(\"scope\") !== \"col\"));\n // infer types for unmarked columns\n if (!known) {\n columns.forEach((c, i) => {\n if (out.headerColumn && i === 0) return;\n const inf = inferColumn(rawRows.map((r) => (r.cells[i] ? cellSource(r.cells[i]!.el) : \"\")));\n Object.assign(c, inf);\n });\n }\n out.columns = columns;\n out.rows = rawRows.map((r) => ({\n _key: r.key,\n ...(r.group ? { group: r.group } : {}),\n ...(r.footer ? { footer: true } : {}),\n ...(r.type ? { type: r.type } : {}),\n ...(r.highlight ? { highlight: true } : {}),\n cells: Object.fromEntries(\n columns.map((c, i) => {\n const cell = r.cells[i];\n if (!cell) return [c._key, null];\n return [c._key, readCell(cell.el, c, r.type, fnByIndex)];\n }),\n ),\n }));\n if (rowGroups.length) out.rowGroups = rowGroups;\n return out;\n}\n\n/** Visible text of a header/cell minus visually-hidden helpers and footnote marks. */\nfunction cleanText(el: Element): string {\n const c = el.cloneNode(true) as HTMLElement;\n c.querySelectorAll(\"sup, .bt-sort-icon, [aria-hidden=true]\").forEach((n) => n.remove());\n return (c.textContent ?? \"\").replace(/\\s+/g, \" \").trim();\n}\n/** A cell's source for inference: inner HTML minus footnote marks, decorative icons and sr helpers kept as words. */\nfunction cellSource(el: Element): string {\n const c = el.cloneNode(true) as HTMLElement;\n c.querySelectorAll(\"sup\").forEach((n) => n.remove());\n // an icon-only cell with a visually-hidden label reads as its label (\"Included\"); an svg/img with aria-label too\n const sr = c.querySelector(\".bt-sr, .sr-only, .visually-hidden, .screen-reader-text\");\n if (sr && !(c.textContent ?? \"\").replace(sr.textContent ?? \"\", \"\").replace(/[✓✔✗✕–—\\s]/g, \"\")) return (sr.textContent ?? \"\").trim();\n const labelled = c.querySelector(\"[aria-label]\");\n if (labelled && !(c.textContent ?? \"\").trim()) return labelled.getAttribute(\"aria-label\") ?? \"\";\n const img = c.querySelector(\"img[alt]\");\n if (img && !(c.textContent ?? \"\").trim()) return img.getAttribute(\"alt\") ?? \"\";\n c.querySelectorAll(\"[aria-hidden=true]\").forEach((n) => n.remove());\n const html = c.innerHTML.trim();\n return /<(a|strong|b|em|i|code|br)\\b/i.test(html) ? html : (c.textContent ?? \"\").replace(/\\s+/g, \" \").trim();\n}\nfunction readCell(el: HTMLTableCellElement, col: TableColumn, rowType: TableColumnType | undefined, fn: Map<number, string>): TableCell {\n const d = (el as HTMLElement).dataset;\n const type = (d.type as TableColumnType) || rowType || col.type;\n let value: TableCellValue;\n if (d.empty != null) value = null;\n else if (d.ref) value = { ref: d.ref, label: cleanText(el) || undefined, href: el.querySelector(\"a\")?.getAttribute(\"href\") ?? undefined };\n else if (d.value != null && (type === \"boolean\" || type === \"number\" || type === \"money\" || type === \"rating\")) value = type === \"boolean\" ? d.value === \"true\" : Number(d.value);\n else if (type === \"richtext-inline\") {\n const c = el.cloneNode(true) as HTMLElement;\n c.querySelectorAll(\"sup\").forEach((n) => n.remove());\n value = sanitizeInline(c.innerHTML.trim());\n } else value = coerce(cellSource(el), { type, max: col.max });\n const supN = Number(el.querySelector(\"sup a, sup\")?.textContent?.trim());\n const note = d.note || (supN ? fn.get(supN) : undefined);\n if (d.type || note) return { value, ...(d.type ? { type: d.type as TableColumnType } : {}), ...(note ? { note } : {}) };\n return value;\n}\n\n/* ── JSON-LD (opt-in) ──────────────────────────────────────────────── */\n/**\n * Dataset — a report or spec table (name = caption, description = notes, variableMeasured = columns).\n * ItemList — a comparison: the things compared (row headers, or column labels) in order.\n * Offers — a pricing matrix: one Offer per plan (columns), price from the money row `priceRow`.\n * Returns null when the table can't honestly support the type (no caption, no items, no prices).\n */\nexport function tableJsonLd(input: TableValue, o: { url?: string; resolveRef?: RefResolver } = {}): Record<string, unknown> | null {\n const t = normalizeTable(input);\n const kind = t.jsonLd?.type ?? \"none\";\n if (kind === \"none\" || !t.caption.trim()) return null;\n const body = t.rows.filter((r) => !r.footer);\n if (kind === \"Dataset\") {\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"Dataset\",\n name: t.caption,\n description: t.notes || t.caption,\n ...(o.url ? { url: o.url } : {}),\n variableMeasured: t.columns.filter((_c, i) => !(t.headerColumn && i === 0)).map((c) => ({ \"@type\": \"PropertyValue\", name: c.label, ...(c.unit ? { unitText: c.unit } : {}), ...(c.description ? { description: c.description } : {}) })),\n };\n }\n const axis = t.jsonLd?.axis ?? \"rows\";\n if (kind === \"ItemList\") {\n const names = axis === \"rows\" ? body.map((r) => cellText(t.columns[0], r, r.cells[t.columns[0]._key], o.resolveRef)) : t.columns.slice(t.headerColumn ? 1 : 0).map((c) => c.label);\n const items = names.filter(Boolean);\n if (!items.length) return null;\n return { \"@context\": \"https://schema.org\", \"@type\": \"ItemList\", name: t.caption, numberOfItems: items.length, itemListElement: items.map((name, i) => ({ \"@type\": \"ListItem\", position: i + 1, name })) };\n }\n // Offers: plans are columns; the price row holds money\n const priceRow = t.rows.find((r) => r._key === t.jsonLd?.priceRow) ?? body.find((r) => t.columns.some((c) => cellType(c, r, r.cells[c._key]) === \"money\"));\n if (!priceRow) return null;\n const offers = t.columns\n .slice(t.headerColumn ? 1 : 0)\n .map((c) => {\n const cell = priceRow.cells[c._key];\n const n = toNumber(cellValue(cell));\n return n == null ? null : { \"@type\": \"Offer\", name: c.label, price: n, priceCurrency: c.currency || \"USD\", ...(o.url ? { url: o.url } : {}) };\n })\n .filter(Boolean) as { price: number; priceCurrency: string }[];\n if (!offers.length) return null;\n const prices = offers.map((x) => x.price);\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"Product\",\n name: t.caption,\n ...(t.notes ? { description: t.notes } : {}),\n offers: { \"@type\": \"AggregateOffer\", lowPrice: Math.min(...prices), highPrice: Math.max(...prices), priceCurrency: offers[0].priceCurrency, offerCount: offers.length, offers },\n };\n}\n\n/* ── Validation (the kit engine + docs + MCP all use these words) ──── */\nexport interface TableIssue {\n level: \"error\" | \"warning\";\n message: string;\n /** where: \"caption\" · \"col:<key>\" · \"row:<key>\" · \"cell:<row>:<col>\" */\n at?: string;\n}\nexport function tableIssues(input: unknown, opts: TableFieldOptions = {}): TableIssue[] {\n if (!isTableValue(input)) return [];\n const t = input;\n const out: TableIssue[] = [];\n if (!t.caption?.trim() && opts.requireCaption !== false) out.push({ level: \"error\", message: \"Give the table a title that says what it compares.\", at: \"caption\" });\n if (!t.headerRow) out.push({ level: \"warning\", message: \"Show the column names: turn on Show column names in Table settings.\" });\n if (t.headerRow) {\n const empty = t.columns.filter((c, i) => !c.label.trim() && !(t.headerColumn && i === 0));\n if (empty.length) out.push({ level: \"error\", message: `Name ${empty.length === 1 ? \"the empty column\" : `the ${empty.length} empty columns`}.`, at: `col:${empty[0]._key}` });\n }\n const keys = new Set<string>();\n for (const c of t.columns) {\n if (keys.has(c._key)) out.push({ level: \"error\", message: \"Two columns are the same column. Delete one and add it again.\", at: `col:${c._key}` });\n keys.add(c._key);\n }\n if (opts.maxColumns && t.columns.length > opts.maxColumns) out.push({ level: \"error\", message: `Use at most ${opts.maxColumns} columns.` });\n const body = t.rows.filter((r) => !r.footer);\n if (opts.minRows && body.length < opts.minRows) out.push({ level: \"error\", message: `Add at least ${opts.minRows} rows.` });\n if (opts.maxRows && body.length > opts.maxRows) out.push({ level: \"error\", message: `Use at most ${opts.maxRows} rows.` });\n let mismatch: { row: string; col: string; label: string } | null = null;\n let mismatches = 0;\n for (const r of t.rows)\n for (const c of t.columns) {\n const cell = r.cells?.[c._key];\n const v = cellValue(cell);\n if (isEmptyCell(v)) continue;\n const ty = cellType(c, r, cell);\n const bad = ((ty === \"number\" || ty === \"money\" || ty === \"rating\") && toNumber(v) == null) || (ty === \"boolean\" && toBool(v) == null);\n if (bad) {\n mismatches++;\n mismatch ??= { row: r._key, col: c._key, label: c.label };\n }\n }\n if (mismatch)\n out.push({ level: \"warning\", message: `${mismatches} ${mismatches === 1 ? \"cell doesn't\" : \"cells don't\"} match the column type (first in “${mismatch.label || \"a column\"}”). Change the column type or set the cell's own type.`, at: `cell:${mismatch.row}:${mismatch.col}` });\n if (t.headerColumn && body.some((r) => isEmptyCell(cellValue(r.cells?.[t.columns[0]?._key])))) out.push({ level: \"warning\", message: \"Every row needs a name in the first column.\" });\n if (t.jsonLd?.type === \"Dataset\" && (t.notes ?? \"\").length < 50) out.push({ level: \"warning\", message: \"To be read as a data report, write a note under the table (a sentence or two).\" });\n if (t.jsonLd?.type === \"Offers\" && !tableJsonLd(t)) out.push({ level: \"warning\", message: \"To be read as a price list, add a row of prices, one per plan column.\" });\n if (t.columns.length > 8 && t.design?.responsive !== \"scroll\") out.push({ level: \"warning\", message: \"More than 8 columns don't fit on phones as a list. In Table settings, set On phones to Scroll.\" });\n return out;\n}\n\n/** \"4 rows × 3 columns\" (array rows, summaries, breadcrumbs). */\nexport function tableSummary(v: unknown): string {\n if (!isTableValue(v)) return \"\";\n const r = v.rows.length;\n const c = v.columns.length;\n return [v.caption?.trim(), `${r} ${r === 1 ? \"row\" : \"rows\"} × ${c} ${c === 1 ? \"column\" : \"columns\"}`].filter(Boolean).join(\" · \");\n}\n\n/** Build a table in code (seed data, Kit Library, migrations): header labels + rows of display strings. */\nexport function tableFrom(\n caption: string,\n columns: (Partial<TableColumn> & { label: string })[],\n rows: (TableCell[] | { cells: TableCell[]; group?: string; footer?: boolean; type?: TableColumnType; highlight?: boolean })[],\n extra: Partial<Omit<TableValue, \"columns\" | \"rows\" | \"caption\">> = {},\n): TableValue {\n const cols: TableColumn[] = columns.map((c, i) => ({ type: \"text\", ...c, _key: c._key ?? `c${i + 1}` }));\n return {\n id: extra.id ?? `tbl_${caption.toLowerCase().replace(/[^a-z0-9]+/g, \"-\").slice(0, 32).replace(/-$/, \"\")}`,\n caption,\n headerRow: true,\n headerColumn: false,\n design: { responsive: \"scroll\" },\n ...extra,\n columns: cols,\n rows: rows.map((r, ri) => {\n const def = Array.isArray(r) ? { cells: r } : r;\n return {\n _key: `r${ri + 1}`,\n ...(def.group ? { group: def.group } : {}),\n ...(def.footer ? { footer: true } : {}),\n ...(def.type ? { type: def.type } : {}),\n ...(def.highlight ? { highlight: true } : {}),\n cells: Object.fromEntries(cols.map((c, ci) => [c._key, def.cells[ci] ?? null])),\n };\n }),\n };\n}\n"],"mappings":"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"}
|
package/schema/types.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","names":[],"sources":["../../src/kit/schema/types.ts"],"sourcesContent":["/**\n * BETTERCMS SCHEMA — the long-term contract for every editable thing (blocks, pages, entries, globals).\n * One schema language → one form engine (`@/components/kit`) → used by BOTH the Visuals inspector and the\n * Content document editor. Modelled on Sanity's schema (types, fieldsets, groups, previews, validation,\n * conditional fields) plus BetterCMS's block slots for nested layouts.\n *\n * Design principles (CPO D8):\n * - Scales to deep nesting without inline-accordion soup: arrays render compact preview rows; opening an item\n * DRILLS IN (panel slides, breadcrumb grows). Small objects may render inline; lightweight settings open in a POPOVER.\n * - Every field has the same chrome: label · help · required · validation · counter · ⋯ menu · presence · comments.\n * - Blocks can contain blocks (slots) → complex layouts (tabs, columns, bento, mega menus, carousels).\n */\n\nimport type { Cap } from \"./sources\";\nimport type { TableFieldOptions } from \"./table\";\n\nexport type PrimitiveType =\n | \"string\" // single line\n | \"text\" // multi line, auto-grow\n | \"richtext\" // portable-text style rich text\n | \"number\"\n | \"boolean\"\n | \"slug\"\n | \"url\"\n | \"email\"\n | \"date\"\n | \"datetime\"\n | \"color\"\n | \"select\" // options: single\n | \"multiselect\"\n | \"tags\"\n | \"image\"\n | \"file\"\n | \"video\"\n | \"icon\" // icon picker (Tabler name)\n | \"link\" // url | page ref + target + rel (one unit)\n | \"button\" // label + link + style (one unit — founder rule)\n | \"reference\" // to a collection entry / page / form\n | \"code\"\n | \"json\"\n | \"geopoint\"\n | \"rating\"\n | \"table\"; // typed columns × keyed rows (CPO D42) — value: TableValue (src/schema/table.ts)\n\nexport type CompoundType =\n | \"object\" // nested fields\n | \"array\" // list of `of` (objects, primitives or references)\n | \"slot\"; // list of nested BLOCKS (block-in-block layouts)\n\nexport type SchemaType = PrimitiveType | CompoundType;\n\nexport interface Option {\n value: string;\n label: string;\n icon?: string;\n description?: string;\n}\n\nexport interface Validation {\n required?: boolean;\n min?: number; // chars for strings, items for arrays, value for numbers\n max?: number;\n /** soft limit: warning (amber) instead of error — e.g. SEO title 60 */\n recommendedMax?: number;\n pattern?: string;\n patternMessage?: string;\n unique?: boolean;\n}\n\n/** How a compound field is edited when opened. */\nexport type OpenMode =\n | \"inline\" // render fields in place (small objects, ≤3 primitives)\n | \"drill\" // slide the panel to a child view; breadcrumb grows (default for array items & objects)\n | \"popover\" // anchored popover (link settings, image crop/alt, small option sets)\n | \"dialog\"; // centered modal for heavy editors (rich text full screen, code, table)\n\nexport interface PreviewConfig {\n /** dotted paths into the item value */\n title?: string;\n subtitle?: string;\n media?: string;\n /** Fallback label, e.g. \"Untitled question\" */\n fallback?: string;\n /** Tabler icon name (kebab-case, e.g. \"help-circle\") shown when there is no media. */\n icon?: string;\n}\n\nexport interface Condition {\n /** show this field only when another sibling field equals one of the values */\n field: string;\n equals?: unknown | unknown[];\n notEmpty?: boolean;\n}\n\nexport interface FieldSchema {\n name: string; // key in the value object\n title: string; // label (sentence case)\n type: SchemaType;\n /** Help text under the label (CPO D39). Unset → a house convention from `@/schema/help` may apply; \"\" = none. */\n description?: string;\n /** Longer explanation behind the ⓘ next to the label (tooltip). Use when one line can't carry it. */\n helpMore?: string;\n placeholder?: string;\n initialValue?: unknown;\n validation?: Validation;\n options?: Option[]; // select / multiselect / radio-like\n layout?: \"dropdown\" | \"radio\" | \"segmented\" | \"cards\" | \"switch\" | \"checkbox\" | \"slider\" | \"grid\" | \"list\";\n /** compound */\n fields?: FieldSchema[]; // object\n of?: FieldSchema[] | { type: \"block\"; allow?: string[] }; // array items / slot allowed block types\n openMode?: OpenMode;\n preview?: PreviewConfig;\n /** organisation */\n fieldset?: string; // groups fields into a collapsible fieldset\n group?: string; // which tab (Content / Media / Settings / SEO…)\n /** behaviour */\n hidden?: Condition | boolean;\n /** true = never editable in the form (computed or system values). Who may see or change a field is `access`. */\n readOnly?: boolean;\n /**\n * D58 field-level access. `view` missing → everyone who can open the form sees it; `edit` missing → the form's own\n * rule (the host's content.edit). A field the lens can't `view` is not rendered; one it can't `edit` renders as plain\n * text. Fields in the `seo` group default to `{ edit: \"seo.edit\" }`.\n */\n access?: FieldAccess;\n localized?: boolean;\n advanced?: boolean; // tucked into the \"Advanced\" fieldset by default (calm UX)\n ai?: boolean; // show the AI assist sparkle\n reference?: { to: string[]; filter?: string }; // reference targets (collection ids, \"page\", \"form\")\n numeric?: { unit?: string; step?: number; min?: number; max?: number }; // number / slider\n /** number: a developer-controlled SCALE (tokens or a stepped range) with an optional custom escape hatch (CPO D41).\n * Value shape → `ScaleValue`. Takes precedence over `layout: \"slider\"` + `numeric` (which still work, fixed-only). */\n scale?: ScaleSchema;\n /** table: column types allowed, developer-locked columns, row limits, caption rule, JSON-LD offered (CPO D42). */\n table?: TableFieldOptions;\n\n /* ── additive (Block Kit v1) ─────────────────────────────────────────── */\n /** Tabler icon name (kebab-case) used on rows, crumbs and the block picker. */\n icon?: string;\n /** text: minimum visible rows. */\n rows?: number;\n /** Value is synced from a global block (\"Navigation\") — edits apply everywhere it is used. */\n synced?: { from: string };\n /** slot: per-child layout settings stored on each child under `_settings` (e.g. bento span). */\n slotSettings?: FieldSchema[];\n /** array: singular noun for \"Add {noun}\" and empty states (\"question\"). Defaults from the item title. */\n itemNoun?: string;\n /** array: how rows render. \"grid\" = tiles (good for images / logos). */\n arrayLayout?: \"list\" | \"grid\";\n /** Help line shown under a field the lens can see but not change (\"Set by the developer in code.\"). Never a key or a lock. */\n lockReason?: string;\n /** link / image / button: store a plain string (href or URL) instead of the object — for legacy data. */\n valueShape?: \"string\" | \"object\";\n /**\n * date / datetime: time zone handling (CPO D43). true = the editor picks a zone (defaults to the site's) · \"site\" = always\n * the site's zone · \"fixed:<IANA>\" = always that zone · false = no zone. Default: true for datetime, false for date.\n * Zoned values store ISO with offset + the IANA zone: \"2026-10-14T09:00:00+05:30[Asia/Kolkata]\" (RFC 9557).\n */\n timezone?: boolean | \"site\" | `fixed:${string}`;\n /** code: the field's own language and the only languages its picker offers (prod config.language / languages). */\n language?: string;\n languages?: string[];\n}\n\n/** D58: the caps that let someone see / change one field. */\nexport interface FieldAccess {\n view?: Cap;\n edit?: Cap;\n}\n/** Developer-owned values (anchors, custom CSS, ids): only people who can change the schema edit them. */\nexport const DEV_FIELD: FieldAccess = { edit: \"schema.manage\" };\n/** Developer-only settings: hidden unless you can see the schema. */\nexport const DEV_ONLY_FIELD: FieldAccess = { view: \"schema.view\", edit: \"schema.manage\" };\n\n/* ── Scales (CPO D41) ─────────────────────────────────────────────────── */\nexport type ScaleUnit = \"px\" | \"%\" | \"rem\" | \"em\" | \"vw\" | \"vh\";\n\n/** One allowed value of a token scale. `value` is what is stored; `label` is the short readout (\"XL\"). */\nexport interface ScaleStep {\n value: string;\n label: string;\n /** Long name for screen readers and tooltips (\"Extra large\"). Defaults to `label`. */\n title?: string;\n /** Resolved size in px, shown as \"XL · 48px\" and used to place custom values on the track. */\n px?: number;\n /** Resolved CSS when it isn't px (e.g. \"100vh\", \"var(--space-xl)\"). */\n css?: string;\n}\n\n/** A stepped numeric range (continuous with snapping). The stored value is a bare number in `defaultUnit`. */\nexport interface ScaleRange {\n min: number;\n max: number;\n step?: number;\n}\n\n/** Bounds for the custom escape hatch. min / max may be one number or per unit ({ px: 0, \"%\": 0 }). */\nexport interface ScaleCustom {\n min?: number | Partial<Record<ScaleUnit, number>>;\n max?: number | Partial<Record<ScaleUnit, number>>;\n /** Units the editor may type. Defaults to the scale's `units`. */\n units?: ScaleUnit[];\n /** Arrow-key nudge (Shift ×10, Alt ×0.1). Default 1. */\n step?: number;\n}\n\nexport interface ScaleSchema {\n /** Token steps (S M L XL 2XL) or a numeric range ({ min, max, step }). */\n steps: ScaleStep[] | ScaleRange;\n /** Units of the scale; the first is the default. A range with no units is unitless. */\n units?: ScaleUnit[];\n defaultUnit?: ScaleUnit;\n /** false (default) = fixed only: the editor can pick only the allowed values. true / object = fixed + custom. */\n allowCustom?: boolean | ScaleCustom;\n /** Quick picks in the unit menu when custom is allowed (\"50%\", \"100vh\"). */\n presets?: { label?: string; value: ScaleValue }[];\n}\n\n/**\n * How a scale value is STORED — three shapes, told apart by `typeof`, so tokens and custom values never collide and\n * older data (bare token strings, bare numbers) is already valid:\n * - token → the step's value string (\"xl\")\n * - range → a bare number in the default unit (15 → 15%)\n * - custom → an object ({ value: 200, unit: \"px\" })\n */\nexport type ScaleValue = string | number | ScaleCustomValue;\nexport interface ScaleCustomValue {\n value: number;\n unit: ScaleUnit;\n}\n\nexport interface Fieldset {\n name: string;\n title: string;\n description?: string;\n collapsed?: boolean; // collapsed by default\n columns?: 1 | 2; // short fields side by side\n /** CPO D45: the header toggles the section (default true). false = a static heading for 2–3 fields that are always needed. */\n collapsible?: boolean;\n /**\n * CPO D45: \"breakpoints\" = the members are objects, one per screen size (desktop · tablet · phone), shown as ONE group with a\n * segmented switcher instead of three stacked groups. Sibling objects named desktop / laptop / tablet / mobile / phone get\n * this automatically.\n */\n layout?: \"stack\" | \"breakpoints\";\n}\n\nexport interface FieldGroup {\n name: string;\n title: string;\n icon?: string;\n default?: boolean;\n}\n\n/** A developer-defined layout of a block (swap without losing content). */\nexport interface BlockVariant {\n id: string;\n name: string;\n description?: string;\n}\n\n/** A document/block type. */\nexport interface TypeSchema {\n name: string; // e.g. \"hero\", \"journalStory\"\n title: string;\n kind: \"block\" | \"page\" | \"entry\" | \"global\" | \"object\";\n icon?: string;\n description?: string;\n fields: FieldSchema[];\n fieldsets?: Fieldset[];\n groups?: FieldGroup[];\n preview?: PreviewConfig;\n /* ── additive (Block Kit v1) ── */\n /** Block variants (layouts) — shown as a chip on slot rows and a switcher in the block frame. */\n variants?: BlockVariant[];\n /** Block picker category (\"Layout\", \"Content\", \"Media\"…). */\n category?: string;\n /**\n * kind \"block\" only (CPO D55): where the block fits. \"inline\" = it fits a text column, so a rich-text body lists it in\n * the Insert menu's Article group. \"section\" (default) = page-width, reachable in a body only through More components.\n * \"page\" = a whole page or a feed of other content; never inside a body.\n */\n placement?: \"inline\" | \"section\" | \"page\";\n /** Starting value for a new instance (block added to a slot, new document). */\n initialValue?: Record<string, unknown>;\n}\n\n/** Every array item / slot child carries a stable key. Slot children also carry their block type. */\nexport interface KeyedItem {\n _key?: string;\n /** item type name (arrays with several `of` types) or block type (slots) */\n _type?: string;\n}\n/** A block inside a slot: its own props at the root, plus variant and per-slot layout settings. */\nexport interface SlotChild extends KeyedItem {\n _type: string;\n _variant?: string;\n _settings?: Record<string, unknown>;\n [prop: string]: unknown;\n}\n\n/** Path from the root document/block to the field being edited, e.g. [\"items\", 1, \"answer\"] */\nexport type FieldPath = (string | number)[];\n\n/** One crumb in the inspector/editor breadcrumb (drill-in navigation stack). */\nexport interface Crumb {\n path: FieldPath;\n title: string;\n icon?: string;\n /** tableGroup / tableRow / tableColumn: a table field's rows and columns drill like array items (D50) */\n kind: \"root\" | \"object\" | \"item\" | \"block\" | \"button\" | \"history\" | \"tableGroup\" | \"tableRow\" | \"tableColumn\";\n}\n\n/** Reserved path segment: the field's version history as a stacked panel, e.g. [\"title\", \"@history\"]. */\nexport const HISTORY_SEGMENT = \"@history\";\n"],"mappings":";;AA0KA,IAAa,YAAyB,EAAE,MAAM,iBAAiB;;AAE/D,IAAa,iBAA8B;CAAE,MAAM;CAAe,MAAM;CAAiB;;AA8IzF,IAAa,kBAAkB"}
|
package/ui/action-tray.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"action-tray.js","names":[],"sources":["../../src/kit/ui/action-tray.tsx"],"sourcesContent":["/**\n * ACTION TRAY: Figma 61014:66265 \"Bottom\". The soft, slightly raised bar at the bottom of editors, inspectors,\n * sheets and dialogs: surface → light grey gradient, 1px top hairline, 12px side padding, 6px vertical, 44px tall +\n * hairline (a 32px button fits exactly). No blur (D21).\n *\n * <ActionTray meta={<TrayMeta name=\"Priya Nair\" at={iso} onClick={openHistory} />}>\n * <Button variant=\"primary\" leftIcon={<IconUpload />}>Publish</Button>\n * <TrayMore>…menu items…</TrayMore>\n * </ActionTray>\n *\n * Use for sticky bottom ACTION bars only, never on cards or content areas.\n */\nimport * as React from \"react\";\nimport { IconDots } from \"@tabler/icons-react\";\nimport { cn } from \"../lib/cn\";\nimport { HintTooltip, IconButton } from \"./button\";\nimport { Avatar, AvatarStack } from \"./display\";\nimport { Menu, MenuContent, MenuTrigger } from \"./overlay\";\nimport { TRAY } from \"./surfaces\";\n\n/* ── Toasts clear the tray (S1: a toast covered the schema draft bar's Apply) ─────────────────────────────────────────\n A tray with `clearToasts` lifts the app's bottom toasts above itself while it is mounted: it writes\n `--toast-offset-bottom` on the root (the host's Toaster reads it as its bottom offset), the highest tray winning. */\nconst clearing = new Set<HTMLElement>();\nfunction syncToastOffset() {\n if (typeof document === \"undefined\") return;\n let lift = 0;\n for (const el of clearing) {\n const r = el.getBoundingClientRect();\n if (r.height) lift = Math.max(lift, window.innerHeight - r.top + 12);\n }\n if (lift > 0) document.documentElement.style.setProperty(\"--toast-offset-bottom\", `${Math.round(lift)}px`);\n else document.documentElement.style.removeProperty(\"--toast-offset-bottom\");\n}\nfunction useToastClearance(ref: React.RefObject<HTMLElement | null>, on: boolean) {\n React.useLayoutEffect(() => {\n const el = ref.current;\n if (!on || !el) return;\n clearing.add(el);\n syncToastOffset();\n const ro = typeof ResizeObserver !== \"undefined\" ? new ResizeObserver(syncToastOffset) : null;\n ro?.observe(el);\n window.addEventListener(\"resize\", syncToastOffset);\n return () => {\n clearing.delete(el);\n ro?.disconnect();\n window.removeEventListener(\"resize\", syncToastOffset);\n syncToastOffset();\n };\n }, [ref, on]);\n}\n\n/** Class string for footers that can't take the component (e.g. a shared footer primitive). */\nexport const actionTrayClass = cn(\"shrink-0 border-t\", TRAY);\n\nexport function ActionTray({\n meta,\n children,\n className,\n as: Tag = \"div\",\n clearToasts = false,\n ...props\n}: Omit<React.HTMLAttributes<HTMLElement>, \"children\"> & {\n /** Left slot, usually <TrayMeta>. */\n meta?: React.ReactNode;\n /** Right slot: actions (primary last-but-one, ⋯ last). */\n children?: React.ReactNode;\n as?: \"div\" | \"footer\";\n /** a page-level bar at the bottom of the window: bottom toasts sit above it, never over its buttons */\n clearToasts?: boolean;\n}) {\n const ref = React.useRef<HTMLElement>(null);\n useToastClearance(ref, clearToasts);\n return (\n <Tag\n ref={ref as React.Ref<HTMLDivElement>}\n data-action-tray=\"\"\n className={cn(actionTrayClass, \"@container/tray flex min-h-[45px] items-center justify-between gap-2 px-3 py-1.5\", className)}\n {...props}\n >\n <div className=\"flex min-w-0 flex-1 items-center gap-2\">{meta}</div>\n {children ? <div className=\"flex shrink-0 items-center gap-[5px]\">{children}</div> : null}\n </Tag>\n );\n}\n\n/** V2 relTime: \"just now\", \"5m ago\", \"3h ago\", \"2d ago\", \"1w ago\", then a date. */\nexport function relTime(at: string | number | Date, now = Date.now()) {\n const s = Math.round((now - new Date(at).getTime()) / 1000);\n if (s < 45) return \"just now\";\n const m = Math.round(s / 60);\n if (m < 60) return `${m}m ago`;\n const h = Math.round(m / 60);\n if (h < 24) return `${h}h ago`;\n const days = Math.round(h / 24);\n if (days < 7) return `${days}d ago`;\n const w = Math.round(days / 7);\n if (w < 5) return `${w}w ago`;\n return new Date(at).toLocaleDateString(\"en-US\", { month: \"short\", day: \"numeric\", year: \"numeric\" });\n}\n\nconst fullStamp = (at: string | number | Date) =>\n new Date(at).toLocaleString(\"en-US\", { weekday: \"short\", month: \"short\", day: \"numeric\", year: \"numeric\", hour: \"numeric\", minute: \"2-digit\" });\n\n/**\n * Left meta: avatar 20 · name 13/500 · \"Edited 3h ago\" 13 muted (Figma). The tooltip carries the full timestamp;\n * when `onClick` is set the whole line is a button (opens History).\n */\nexport function TrayMeta({\n name,\n avatarName,\n src,\n people,\n at,\n verb = \"Edited\",\n note,\n onClick,\n actionHint = \"Open history\",\n}: {\n name: string;\n /** Full name for the avatar when `name` is shortened (\"You\", first names). */\n avatarName?: string;\n src?: string;\n /** Several editors → avatar stack (first is the last editor). */\n people?: { name: string; src?: string }[];\n /** When it was edited; omit for \"just now\" states you phrase yourself via `note`. */\n at?: string | number | Date;\n verb?: string;\n /** Overrides the relative-time text, e.g. \"Edited just now\". */\n note?: string;\n onClick?: () => void;\n actionHint?: string;\n}) {\n const when = note ?? (at ? `${verb} ${relTime(at).replace(\"just now\", \"a moment ago\")}` : verb);\n const inner = (\n <>\n <span className=\"flex shrink-0 items-center gap-1\">\n {people && people.length > 1 ? (\n <AvatarStack people={people} size={20} max={3} />\n ) : (\n <Avatar name={avatarName ?? name} src={src} size={20} decorative />\n )}\n {/* narrow trays (the grid drawer): just the avatar, the words move into the tooltip; never a clipped \"Edit…\" */}\n <span className=\"hidden whitespace-nowrap text-kit-sm font-medium text-kit-fg @[34rem]/tray:inline\">{name}</span>\n </span>\n <span className=\"hidden min-w-0 truncate text-kit-sm text-kit-fg-3 @[34rem]/tray:inline\">{when}</span>\n </>\n );\n const tip = at\n ? `${name} · ${verb} ${fullStamp(at)}${onClick ? ` · ${actionHint}` : \"\"}`\n : onClick\n ? `${name} · ${when} · ${actionHint}`\n : `${name} · ${when}`;\n const body = onClick ? (\n <button\n type=\"button\"\n onClick={onClick}\n aria-label={`${name}, ${when}. ${actionHint}`}\n className=\"-mx-1 flex min-w-0 items-center gap-2 rounded-kit-md px-1 py-0.5 transition-colors hover:bg-kit-hover\"\n >\n {inner}\n </button>\n ) : (\n <span className=\"flex min-w-0 items-center gap-2\">\n {inner}\n {/* the words hide in narrow trays; screen readers always get them */}\n <span className=\"sr-only @[34rem]/tray:hidden\">{`${name}, ${when}`}</span>\n </span>\n );\n return <HintTooltip content={tip}>{body}</HintTooltip>;\n}\n\n/** The tray's \"⋯\" (32×32 ghost, Figma \"Button - Modal actions\") opening a menu above the bar. Children are menu items. */\nexport function TrayMore({\n label = \"More options\",\n children,\n menuClassName,\n}: {\n label?: string;\n children: React.ReactNode;\n menuClassName?: string;\n}) {\n return (\n // the kit Menu: §12 dismiss guards, the modal-layer marker (an open tooltip closes) and V2's non-looping arrows\n <Menu>\n <MenuTrigger\n render={\n <IconButton label={label} size=\"md\">\n <IconDots aria-hidden />\n </IconButton>\n }\n />\n <MenuContent side=\"top\" align=\"end\" className={cn(\"w-60 font-kit-sans\", menuClassName)}>\n {children}\n </MenuContent>\n </Menu>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAuBA,IAAM,2BAAW,IAAI,KAAkB;AACvC,SAAS,kBAAkB;AACzB,KAAI,OAAO,aAAa,YAAa;CACrC,IAAI,OAAO;AACX,MAAK,MAAM,MAAM,UAAU;EACzB,MAAM,IAAI,GAAG,uBAAuB;AACpC,MAAI,EAAE,OAAQ,QAAO,KAAK,IAAI,MAAM,OAAO,cAAc,EAAE,MAAM,GAAG;;AAEtE,KAAI,OAAO,EAAG,UAAS,gBAAgB,MAAM,YAAY,yBAAyB,GAAG,KAAK,MAAM,KAAK,CAAC,IAAI;KACrG,UAAS,gBAAgB,MAAM,eAAe,wBAAwB;;AAE7E,SAAS,kBAAkB,KAA0C,IAAa;AAChF,OAAM,sBAAsB;EAC1B,MAAM,KAAK,IAAI;AACf,MAAI,CAAC,MAAM,CAAC,GAAI;AAChB,WAAS,IAAI,GAAG;AAChB,mBAAiB;EACjB,MAAM,KAAK,OAAO,mBAAmB,cAAc,IAAI,eAAe,gBAAgB,GAAG;AACzF,MAAI,QAAQ,GAAG;AACf,SAAO,iBAAiB,UAAU,gBAAgB;AAClD,eAAa;AACX,YAAS,OAAO,GAAG;AACnB,OAAI,YAAY;AAChB,UAAO,oBAAoB,UAAU,gBAAgB;AACrD,oBAAiB;;IAElB,CAAC,KAAK,GAAG,CAAC;;;AAIf,IAAa,kBAAkB,GAAG,qBAAqB,KAAK;AAE5D,SAAgB,WAAW,EACzB,MACA,UACA,WACA,IAAI,MAAM,OACV,cAAc,OACd,GAAG,SASF;CACD,MAAM,MAAM,MAAM,OAAoB,KAAK;AAC3C,mBAAkB,KAAK,YAAY;AACnC,QACE,qBAAC,KAAD;EACO;EACL,oBAAiB;EACjB,WAAW,GAAG,iBAAiB,oFAAoF,UAAU;EAC7H,GAAI;YAJN,CAME,oBAAC,OAAD;GAAK,WAAU;aAA0C;GAAW,CAAA,EACnE,WAAW,oBAAC,OAAD;GAAK,WAAU;GAAwC;GAAe,CAAA,GAAG,KACjF;;;;AAKV,SAAgB,QAAQ,IAA4B,MAAM,KAAK,KAAK,EAAE;CACpE,MAAM,IAAI,KAAK,OAAO,MAAM,IAAI,KAAK,GAAG,CAAC,SAAS,IAAI,IAAK;AAC3D,KAAI,IAAI,GAAI,QAAO;CACnB,MAAM,IAAI,KAAK,MAAM,IAAI,GAAG;AAC5B,KAAI,IAAI,GAAI,QAAO,GAAG,EAAE;CACxB,MAAM,IAAI,KAAK,MAAM,IAAI,GAAG;AAC5B,KAAI,IAAI,GAAI,QAAO,GAAG,EAAE;CACxB,MAAM,OAAO,KAAK,MAAM,IAAI,GAAG;AAC/B,KAAI,OAAO,EAAG,QAAO,GAAG,KAAK;CAC7B,MAAM,IAAI,KAAK,MAAM,OAAO,EAAE;AAC9B,KAAI,IAAI,EAAG,QAAO,GAAG,EAAE;AACvB,QAAO,IAAI,KAAK,GAAG,CAAC,mBAAmB,SAAS;EAAE,OAAO;EAAS,KAAK;EAAW,MAAM;EAAW,CAAC;;AAGtG,IAAM,aAAa,OACjB,IAAI,KAAK,GAAG,CAAC,eAAe,SAAS;CAAE,SAAS;CAAS,OAAO;CAAS,KAAK;CAAW,MAAM;CAAW,MAAM;CAAW,QAAQ;CAAW,CAAC;;;;;AAMjJ,SAAgB,SAAS,EACvB,MACA,YACA,KACA,QACA,IACA,OAAO,UACP,MACA,SACA,aAAa,kBAeZ;CACD,MAAM,OAAO,SAAS,KAAK,GAAG,KAAK,GAAG,QAAQ,GAAG,CAAC,QAAQ,YAAY,eAAe,KAAK;CAC1F,MAAM,QACJ,qBAAA,UAAA,EAAA,UAAA,CACE,qBAAC,QAAD;EAAM,WAAU;YAAhB,CACG,UAAU,OAAO,SAAS,IACzB,oBAAC,aAAD;GAAqB;GAAQ,MAAM;GAAI,KAAK;GAAK,CAAA,GAEjD,oBAAC,QAAD;GAAQ,MAAM,cAAc;GAAW;GAAK,MAAM;GAAI,YAAA;GAAa,CAAA,EAGrE,oBAAC,QAAD;GAAM,WAAU;aAAqF;GAAY,CAAA,CAC5G;KACP,oBAAC,QAAD;EAAM,WAAU;YAA0E;EAAY,CAAA,CACrG,EAAA,CAAA;AAuBL,QAAO,oBAAC,aAAD;EAAa,SArBR,KACR,GAAG,KAAK,KAAK,KAAK,GAAG,UAAU,GAAG,GAAG,UAAU,MAAM,eAAe,OACpE,UACE,GAAG,KAAK,KAAK,KAAK,KAAK,eACvB,GAAG,KAAK,KAAK;YACN,UACX,oBAAC,UAAD;GACE,MAAK;GACI;GACT,cAAY,GAAG,KAAK,IAAI,KAAK,IAAI;GACjC,WAAU;aAET;GACM,CAAA,GAET,qBAAC,QAAD;GAAM,WAAU;aAAhB,CACG,OAED,oBAAC,QAAD;IAAM,WAAU;cAAgC,GAAG,KAAK,IAAI;IAAc,CAAA,CACrE;;EAE6C,CAAA;;;AAIxD,SAAgB,SAAS,EACvB,QAAQ,gBACR,UACA,iBAKC;AACD,QAEE,qBAAC,MAAD,EAAA,UAAA,CACE,oBAAC,aAAD,EACE,QACE,oBAAC,YAAD;EAAmB;EAAO,MAAK;YAC7B,oBAAC,UAAD,EAAU,eAAA,MAAc,CAAA;EACb,CAAA,EAEf,CAAA,EACF,oBAAC,aAAD;EAAa,MAAK;EAAM,OAAM;EAAM,WAAW,GAAG,sBAAsB,cAAc;EACnF;EACW,CAAA,CACT,EAAA,CAAA"}
|