@bettercms-ai/kit 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -0
- package/dist/adapters/dock-values.d.ts +28 -0
- package/dist/adapters/dock-values.js +41 -0
- package/dist/adapters/dock-values.js.map +1 -0
- package/{adapters → dist/adapters}/icons.js +2 -2
- package/dist/adapters/icons.js.map +1 -0
- package/{adapters → dist/adapters}/lossy.d.ts +90 -31
- package/dist/adapters/lossy.js +414 -0
- package/dist/adapters/lossy.js.map +1 -0
- package/{adapters → dist/adapters}/prod-types.d.ts +82 -4
- package/{adapters → dist/adapters}/prod-types.js +71 -3
- package/dist/adapters/prod-types.js.map +1 -0
- package/{adapters → dist/adapters}/schema.d.ts +40 -1
- package/{adapters → dist/adapters}/schema.js +996 -179
- package/dist/adapters/schema.js.map +1 -0
- package/{adapters → dist/adapters}/values.d.ts +26 -5
- package/{adapters → dist/adapters}/values.js +87 -17
- package/dist/adapters/values.js.map +1 -0
- package/dist/brand/logo.js +96 -0
- package/dist/brand/logo.js.map +1 -0
- package/{context.d.ts → dist/context.d.ts} +92 -2
- package/{context.js → dist/context.js} +5 -2
- package/dist/context.js.map +1 -0
- package/{controls → dist/controls}/button.d.ts +19 -5
- package/{controls → dist/controls}/button.js +125 -54
- package/dist/controls/button.js.map +1 -0
- package/{controls → dist/controls}/c1.js +1 -1
- package/dist/controls/c1.js.map +1 -0
- package/{controls → dist/controls}/c2.js +1 -1
- package/dist/controls/c2.js.map +1 -0
- package/{controls → dist/controls}/choice.d.ts +7 -2
- package/{controls → dist/controls}/choice.js +71 -18
- package/dist/controls/choice.js.map +1 -0
- package/{controls → dist/controls}/code-register.js +1 -1
- package/dist/controls/code-register.js.map +1 -0
- package/{controls → dist/controls}/code.js +10 -9
- package/dist/controls/code.js.map +1 -0
- package/{controls → dist/controls}/color.js +8 -8
- package/dist/controls/color.js.map +1 -0
- package/{controls → dist/controls}/component-services.d.ts +42 -0
- package/dist/controls/component-services.js +7 -0
- package/dist/controls/component-services.js.map +1 -0
- package/{controls → dist/controls}/date-register.js +1 -1
- package/dist/controls/date-register.js.map +1 -0
- package/{controls → dist/controls}/date-zone.js +8 -2
- package/dist/controls/date-zone.js.map +1 -0
- package/{controls → dist/controls}/date.js +32 -24
- package/dist/controls/date.js.map +1 -0
- package/{controls → dist/controls}/form-picker-register.js +1 -1
- package/dist/controls/form-picker-register.js.map +1 -0
- package/{controls → dist/controls}/form-picker.js +11 -9
- package/dist/controls/form-picker.js.map +1 -0
- package/{controls → dist/controls}/icon-register.js +1 -1
- package/dist/controls/icon-register.js.map +1 -0
- package/{controls → dist/controls}/icon.d.ts +4 -2
- package/{controls → dist/controls}/icon.js +32 -27
- package/dist/controls/icon.js.map +1 -0
- package/{controls → dist/controls}/index.d.ts +1 -1
- package/{controls → dist/controls}/index.js +4 -3
- package/dist/controls/index.js.map +1 -0
- package/{controls → dist/controls}/json-register.js +1 -1
- package/dist/controls/json-register.js.map +1 -0
- package/{controls → dist/controls}/json.js +13 -3
- package/dist/controls/json.js.map +1 -0
- package/{controls → dist/controls}/link.js +6 -6
- package/dist/controls/link.js.map +1 -0
- package/{controls → dist/controls}/location-register.js +1 -1
- package/dist/controls/location-register.js.map +1 -0
- package/{controls → dist/controls}/location.js +64 -40
- package/dist/controls/location.js.map +1 -0
- package/{controls → dist/controls}/media-register.js +1 -1
- package/dist/controls/media-register.js.map +1 -0
- package/{controls → dist/controls}/media-services.d.ts +6 -0
- package/dist/controls/media-services.js +0 -0
- package/{controls → dist/controls}/media.d.ts +35 -4
- package/{controls → dist/controls}/media.js +491 -171
- package/dist/controls/media.js.map +1 -0
- package/{controls → dist/controls}/number.js +10 -9
- package/dist/controls/number.js.map +1 -0
- package/{controls → dist/controls}/reference-register.js +1 -1
- package/dist/controls/reference-register.js.map +1 -0
- package/{controls → dist/controls}/reference-services.d.ts +4 -0
- package/dist/controls/reference-services.js +0 -0
- package/{controls → dist/controls}/reference.d.ts +1 -1
- package/{controls → dist/controls}/reference.js +93 -77
- package/dist/controls/reference.js.map +1 -0
- package/dist/controls/rich-text/blocks.d.ts +49 -0
- package/{controls → dist/controls}/rich-text/blocks.js +471 -144
- package/dist/controls/rich-text/blocks.js.map +1 -0
- package/{controls → dist/controls}/rich-text/catalog.d.ts +4 -1
- package/{controls → dist/controls}/rich-text/catalog.js +75 -65
- package/dist/controls/rich-text/catalog.js.map +1 -0
- package/{controls → dist/controls}/rich-text/codec.d.ts +9 -1
- package/{controls → dist/controls}/rich-text/codec.js +3 -1
- package/dist/controls/rich-text/codec.js.map +1 -0
- package/{controls → dist/controls}/rich-text/component-card.d.ts +1 -1
- package/{controls → dist/controls}/rich-text/component-card.js +417 -99
- package/dist/controls/rich-text/component-card.js.map +1 -0
- package/dist/controls/rich-text/component-panel.d.ts +47 -0
- package/dist/controls/rich-text/component-panel.js +141 -0
- package/dist/controls/rich-text/component-panel.js.map +1 -0
- package/{controls → dist/controls}/rich-text/control.d.ts +1 -2
- package/{controls → dist/controls}/rich-text/control.js +84 -42
- package/dist/controls/rich-text/control.js.map +1 -0
- package/{controls → dist/controls}/rich-text/dom.d.ts +52 -9
- package/{controls → dist/controls}/rich-text/dom.js +379 -50
- package/dist/controls/rich-text/dom.js.map +1 -0
- package/{controls → dist/controls}/rich-text/editor.d.ts +7 -0
- package/{controls → dist/controls}/rich-text/editor.js +148 -48
- package/dist/controls/rich-text/editor.js.map +1 -0
- package/{controls → dist/controls}/rich-text/floating.d.ts +6 -1
- package/{controls → dist/controls}/rich-text/floating.js +35 -18
- package/dist/controls/rich-text/floating.js.map +1 -0
- package/{controls → dist/controls}/rich-text/index.js +1 -1
- package/dist/controls/rich-text/index.js.map +1 -0
- package/dist/controls/rich-text/link-form.js +147 -0
- package/dist/controls/rich-text/link-form.js.map +1 -0
- package/{controls → dist/controls}/rich-text/markdown.js +4 -2
- package/dist/controls/rich-text/markdown.js.map +1 -0
- package/{controls → dist/controls}/rich-text/ops.js +17 -15
- package/dist/controls/rich-text/ops.js.map +1 -0
- package/dist/controls/rich-text/plain.d.ts +17 -0
- package/dist/controls/rich-text/plain.js +44 -0
- package/dist/controls/rich-text/plain.js.map +1 -0
- package/{controls → dist/controls}/rich-text/toolbar.d.ts +6 -2
- package/{controls → dist/controls}/rich-text/toolbar.js +12 -7
- package/dist/controls/rich-text/toolbar.js.map +1 -0
- package/{controls → dist/controls}/scale.js +5 -5
- package/dist/controls/scale.js.map +1 -0
- package/{controls → dist/controls}/slot-register.js +1 -1
- package/dist/controls/slot-register.js.map +1 -0
- package/{controls → dist/controls}/slot-services.d.ts +25 -0
- package/dist/controls/slot-services.js +155 -0
- package/dist/controls/slot-services.js.map +1 -0
- package/{controls → dist/controls}/slot.js +42 -24
- package/dist/controls/slot.js.map +1 -0
- package/{controls → dist/controls}/table/index.js +1 -1
- package/dist/controls/table/index.js.map +1 -0
- package/{controls → dist/controls}/table/prod.js +3 -3
- package/dist/controls/table/prod.js.map +1 -0
- package/{controls → dist/controls}/table/refs.js +13 -2
- package/dist/controls/table/refs.js.map +1 -0
- package/{controls → dist/controls}/table/stored.js +1 -1
- package/dist/controls/table/stored.js.map +1 -0
- package/{controls → dist/controls}/table/table-editor.js +51 -48
- package/dist/controls/table/table-editor.js.map +1 -0
- package/{controls → dist/controls}/table/table-link.js +3 -3
- package/dist/controls/table/table-link.js.map +1 -0
- package/{controls → dist/controls}/table/table.js +3 -3
- package/dist/controls/table/table.js.map +1 -0
- package/{controls → dist/controls}/text.d.ts +2 -2
- package/{controls → dist/controls}/text.js +78 -43
- package/dist/controls/text.js.map +1 -0
- package/dist/controls/unknown-value.d.ts +17 -0
- package/dist/controls/unknown-value.js +66 -0
- package/dist/controls/unknown-value.js.map +1 -0
- package/dist/core/core.d.ts +63 -0
- package/dist/core/core.js +171 -0
- package/dist/core/core.js.map +1 -0
- package/dist/core/facets.d.ts +347 -0
- package/dist/core/facets.js +334 -0
- package/dist/core/facets.js.map +1 -0
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.js +3 -0
- package/{engine → dist/engine}/array.js +34 -21
- package/dist/engine/array.js.map +1 -0
- package/{engine → dist/engine}/bits.js +1 -1
- package/dist/engine/bits.js.map +1 -0
- package/{engine → dist/engine}/breadcrumb.d.ts +3 -3
- package/{engine → dist/engine}/breadcrumb.js +12 -36
- package/dist/engine/breadcrumb.js.map +1 -0
- package/{engine → dist/engine}/expand.d.ts +2 -4
- package/{engine → dist/engine}/expand.js +5 -22
- package/dist/engine/expand.js.map +1 -0
- package/{engine → dist/engine}/field-list.js +1 -1
- package/dist/engine/field-list.js.map +1 -0
- package/{engine → dist/engine}/field-shell.js +249 -121
- package/dist/engine/field-shell.js.map +1 -0
- package/{engine → dist/engine}/frame.d.ts +3 -1
- package/{engine → dist/engine}/frame.js +16 -14
- package/dist/engine/frame.js.map +1 -0
- package/{engine → dist/engine}/group-summary.d.ts +2 -1
- package/{engine → dist/engine}/group-summary.js +7 -3
- package/dist/engine/group-summary.js.map +1 -0
- package/{engine → dist/engine}/grouping.d.ts +19 -5
- package/{engine → dist/engine}/grouping.js +193 -21
- package/dist/engine/grouping.js.map +1 -0
- package/{engine → dist/engine}/item-list.d.ts +11 -1
- package/{engine → dist/engine}/item-list.js +35 -13
- package/dist/engine/item-list.js.map +1 -0
- package/{engine → dist/engine}/kit-field.js +45 -10
- package/dist/engine/kit-field.js.map +1 -0
- package/{engine → dist/engine}/schema-form.d.ts +27 -2
- package/{engine → dist/engine}/schema-form.js +182 -40
- package/dist/engine/schema-form.js.map +1 -0
- package/{engine → dist/engine}/slot.js +5 -15
- package/dist/engine/slot.js.map +1 -0
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -0
- package/{kit.css → dist/kit.css} +19 -0
- package/{lib → dist/lib}/cn.js +7 -4
- package/dist/lib/cn.js.map +1 -0
- package/{lib → dist/lib}/columns.js +4 -1
- package/dist/lib/columns.js.map +1 -0
- package/{lib → dist/lib}/frames.js +2 -2
- package/dist/lib/frames.js.map +1 -0
- package/dist/lib/icon-image.d.ts +10 -0
- package/dist/lib/icon-image.js +8 -0
- package/dist/lib/icon-image.js.map +1 -0
- package/{lib → dist/lib}/icons.js +4 -3
- package/dist/lib/icons.js.map +1 -0
- package/dist/lib/input-modality.d.ts +11 -0
- package/dist/lib/input-modality.js +47 -0
- package/dist/lib/input-modality.js.map +1 -0
- package/dist/lib/key-event.d.ts +11 -0
- package/dist/lib/key-event.js +16 -0
- package/dist/lib/key-event.js.map +1 -0
- package/{lib → dist/lib}/path.js +4 -2
- package/dist/lib/path.js.map +1 -0
- package/{lib → dist/lib}/schema.d.ts +34 -3
- package/{lib → dist/lib}/schema.js +110 -13
- package/dist/lib/schema.js.map +1 -0
- package/{lib → dist/lib}/utils.js +1 -1
- package/dist/lib/utils.js.map +1 -0
- package/{lib → dist/lib}/validate.d.ts +11 -1
- package/{lib → dist/lib}/validate.js +85 -11
- package/dist/lib/validate.js.map +1 -0
- package/dist/library/analysis.d.ts +23 -0
- package/dist/library/analysis.js +160 -0
- package/dist/library/analysis.js.map +1 -0
- package/dist/library/catalog.d.ts +57 -0
- package/dist/library/catalog.js +307 -0
- package/dist/library/catalog.js.map +1 -0
- package/dist/library/coreNotes.d.ts +8 -0
- package/dist/library/coreNotes.js +111 -0
- package/dist/library/coreNotes.js.map +1 -0
- package/dist/library/coverage.d.ts +40 -0
- package/dist/library/coverage.js +59 -0
- package/dist/library/coverage.js.map +1 -0
- package/dist/library/entries/advanced.entries.d.ts +2 -0
- package/dist/library/entries/advanced.entries.js +6579 -0
- package/dist/library/entries/advanced.entries.js.map +1 -0
- package/dist/library/entries/commerce.entries.d.ts +2 -0
- package/dist/library/entries/commerce.entries.js +4140 -0
- package/dist/library/entries/commerce.entries.js.map +1 -0
- package/dist/library/entries/company.entries.d.ts +2 -0
- package/dist/library/entries/company.entries.js +2731 -0
- package/dist/library/entries/company.entries.js.map +1 -0
- package/dist/library/entries/conversion.entries.d.ts +2 -0
- package/dist/library/entries/conversion.entries.js +3707 -0
- package/dist/library/entries/conversion.entries.js.map +1 -0
- package/dist/library/entries/data.entries.d.ts +7 -0
- package/dist/library/entries/data.entries.js +4613 -0
- package/dist/library/entries/data.entries.js.map +1 -0
- package/dist/library/entries/events.entries.d.ts +2 -0
- package/dist/library/entries/events.entries.js +3428 -0
- package/dist/library/entries/events.entries.js.map +1 -0
- package/dist/library/entries/features.entries.d.ts +2 -0
- package/dist/library/entries/features.entries.js +3157 -0
- package/dist/library/entries/features.entries.js.map +1 -0
- package/dist/library/entries/heroes.entries.d.ts +2 -0
- package/dist/library/entries/heroes.entries.js +3401 -0
- package/dist/library/entries/heroes.entries.js.map +1 -0
- package/dist/library/entries/index.d.ts +3 -0
- package/dist/library/entries/index.js +35 -0
- package/dist/library/entries/index.js.map +1 -0
- package/dist/library/entries/listings.entries.d.ts +2 -0
- package/dist/library/entries/listings.entries.js +2976 -0
- package/dist/library/entries/listings.entries.js.map +1 -0
- package/dist/library/entries/longform.entries.d.ts +2 -0
- package/dist/library/entries/longform.entries.js +4227 -0
- package/dist/library/entries/longform.entries.js.map +1 -0
- package/dist/library/entries/media.entries.d.ts +2 -0
- package/dist/library/entries/media.entries.js +2781 -0
- package/dist/library/entries/media.entries.js.map +1 -0
- package/dist/library/entries/navigation.entries.d.ts +2 -0
- package/dist/library/entries/navigation.entries.js +4011 -0
- package/dist/library/entries/navigation.entries.js.map +1 -0
- package/dist/library/entries/pricing.entries.d.ts +2 -0
- package/dist/library/entries/pricing.entries.js +2383 -0
- package/dist/library/entries/pricing.entries.js.map +1 -0
- package/dist/library/entries/social-proof.entries.d.ts +2 -0
- package/dist/library/entries/social-proof.entries.js +2297 -0
- package/dist/library/entries/social-proof.entries.js.map +1 -0
- package/dist/library/examples/bento.d.ts +92 -0
- package/dist/library/examples/bento.js +201 -0
- package/dist/library/examples/bento.js.map +1 -0
- package/dist/library/examples/blocks.d.ts +14 -0
- package/dist/library/examples/blocks.js +313 -0
- package/dist/library/examples/blocks.js.map +1 -0
- package/dist/library/examples/faq.d.ts +28 -0
- package/dist/library/examples/faq.js +230 -0
- package/dist/library/examples/faq.js.map +1 -0
- package/dist/library/examples/hero.d.ts +43 -0
- package/dist/library/examples/hero.js +222 -0
- package/dist/library/examples/hero.js.map +1 -0
- package/dist/library/examples/index.d.ts +36 -0
- package/dist/library/examples/index.js +109 -0
- package/dist/library/examples/index.js.map +1 -0
- package/dist/library/examples/journalStory.d.ts +93 -0
- package/dist/library/examples/journalStory.js +338 -0
- package/dist/library/examples/journalStory.js.map +1 -0
- package/dist/library/examples/megaMenu.d.ts +134 -0
- package/dist/library/examples/megaMenu.js +442 -0
- package/dist/library/examples/megaMenu.js.map +1 -0
- package/dist/library/examples/pricing.d.ts +103 -0
- package/dist/library/examples/pricing.js +479 -0
- package/dist/library/examples/pricing.js.map +1 -0
- package/dist/library/examples/tabs.d.ts +87 -0
- package/dist/library/examples/tabs.js +180 -0
- package/dist/library/examples/tabs.js.map +1 -0
- package/dist/library/export.d.ts +42 -0
- package/dist/library/export.js +80 -0
- package/dist/library/export.js.map +1 -0
- package/dist/library/index.d.ts +13 -0
- package/dist/library/index.js +6 -0
- package/dist/library/kit-catalog.json +1510 -0
- package/dist/library/types.d.ts +42 -0
- package/dist/library/types.js +0 -0
- package/{schema → dist/schema}/adapters.js +1 -2
- package/dist/schema/adapters.js.map +1 -0
- package/{schema → dist/schema}/help.d.ts +2 -0
- package/{schema → dist/schema}/help.js +6 -4
- package/dist/schema/help.js.map +1 -0
- package/{schema → dist/schema}/scale.js +1 -1
- package/dist/schema/scale.js.map +1 -0
- package/{schema → dist/schema}/sources.js +1 -1
- package/dist/schema/sources.js.map +1 -0
- package/{schema → dist/schema}/table.js +11 -10
- package/dist/schema/table.js.map +1 -0
- package/{schema → dist/schema}/types.d.ts +29 -1
- package/{schema → dist/schema}/types.js +1 -1
- package/dist/schema/types.js.map +1 -0
- package/dist/styles.css +2 -0
- package/dist/table/table-view.d.ts +14 -0
- package/dist/table/table-view.js +140 -0
- package/dist/table/table-view.js.map +1 -0
- package/dist/table/table.css +73 -0
- package/dist/testing/corpus.d.ts +63 -0
- package/dist/testing/corpus.js +129 -0
- package/dist/testing/corpus.js.map +1 -0
- package/dist/testing/test-form.d.ts +11 -0
- package/dist/testing/test-form.js +38 -0
- package/dist/testing/test-form.js.map +1 -0
- package/dist/theme.css +345 -0
- package/dist/theme.d.ts +22 -0
- package/dist/theme.js +43 -0
- package/dist/theme.js.map +1 -0
- package/dist/tokens.css +542 -0
- package/dist/types.js +0 -0
- package/{ui → dist/ui}/action-tray.d.ts +1 -1
- package/{ui → dist/ui}/action-tray.js +20 -19
- package/dist/ui/action-tray.js.map +1 -0
- package/dist/ui/autocomplete.d.ts +30 -0
- package/dist/ui/autocomplete.js +139 -0
- package/dist/ui/autocomplete.js.map +1 -0
- package/{ui → dist/ui}/button.d.ts +3 -3
- package/{ui → dist/ui}/button.js +6 -7
- package/dist/ui/button.js.map +1 -0
- package/{ui → dist/ui}/choice-switch.js +1 -1
- package/dist/ui/choice-switch.js.map +1 -0
- package/{ui → dist/ui}/controls.js +51 -39
- package/dist/ui/controls.js.map +1 -0
- package/{ui → dist/ui}/display.d.ts +10 -3
- package/{ui → dist/ui}/display.js +57 -46
- package/dist/ui/display.js.map +1 -0
- package/{ui → dist/ui}/expanded-editor-modal.d.ts +2 -2
- package/{ui → dist/ui}/expanded-editor-modal.js +6 -6
- package/dist/ui/expanded-editor-modal.js.map +1 -0
- package/{ui → dist/ui}/field-context.js +1 -1
- package/dist/ui/field-context.js.map +1 -0
- package/{ui → dist/ui}/floating-panel.d.ts +1 -1
- package/{ui → dist/ui}/floating-panel.js +28 -12
- package/dist/ui/floating-panel.js.map +1 -0
- package/{ui → dist/ui}/index.d.ts +4 -0
- package/dist/ui/index.js +18 -0
- package/{ui → dist/ui}/input.d.ts +1 -1
- package/{ui → dist/ui}/input.js +9 -9
- package/dist/ui/input.js.map +1 -0
- package/{ui → dist/ui}/mode-bar.js +3 -3
- package/dist/ui/mode-bar.js.map +1 -0
- package/{ui → dist/ui}/overlay.d.ts +77 -5
- package/dist/ui/overlay.js +697 -0
- package/dist/ui/overlay.js.map +1 -0
- package/{ui → dist/ui}/path-crumbs.js +37 -3
- package/dist/ui/path-crumbs.js.map +1 -0
- package/{ui → dist/ui}/presence.js +2 -2
- package/dist/ui/presence.js.map +1 -0
- package/{ui → dist/ui}/select.js +89 -87
- package/dist/ui/select.js.map +1 -0
- package/{ui → dist/ui}/shortcut-hint.js +1 -1
- package/dist/ui/shortcut-hint.js.map +1 -0
- package/dist/ui/spinner.d.ts +24 -0
- package/dist/ui/spinner.js +42 -0
- package/dist/ui/spinner.js.map +1 -0
- package/dist/ui/split-button.d.ts +32 -0
- package/dist/ui/split-button.js +60 -0
- package/dist/ui/split-button.js.map +1 -0
- package/{ui → dist/ui}/surfaces.js +1 -1
- package/dist/ui/surfaces.js.map +1 -0
- package/dist/ui/tab.d.ts +38 -0
- package/dist/ui/tab.js +87 -0
- package/dist/ui/tab.js.map +1 -0
- package/dist/ui/toast.d.ts +20 -0
- package/dist/ui/toast.js +115 -0
- package/dist/ui/toast.js.map +1 -0
- package/{ui → dist/ui}/tooltip-root.d.ts +4 -3
- package/{ui → dist/ui}/tooltip-root.js +9 -8
- package/dist/ui/tooltip-root.js.map +1 -0
- package/{ui → dist/ui}/variants.js +1 -1
- package/dist/ui/variants.js.map +1 -0
- package/package.json +77 -23
- package/adapters/icons.js.map +0 -1
- package/adapters/lossy.js +0 -233
- package/adapters/lossy.js.map +0 -1
- package/adapters/prod-types.js.map +0 -1
- package/adapters/schema.js.map +0 -1
- package/adapters/values.js.map +0 -1
- package/brand/logo.js +0 -9
- package/brand/logo.js.map +0 -1
- package/context.js.map +0 -1
- package/controls/button.js.map +0 -1
- package/controls/c1.js.map +0 -1
- package/controls/c2.js.map +0 -1
- package/controls/choice.js.map +0 -1
- package/controls/code-register.js.map +0 -1
- package/controls/code.js.map +0 -1
- package/controls/color.js.map +0 -1
- package/controls/date-register.js.map +0 -1
- package/controls/date-zone.js.map +0 -1
- package/controls/date.js.map +0 -1
- package/controls/form-picker-register.js.map +0 -1
- package/controls/form-picker.js.map +0 -1
- package/controls/icon-register.js.map +0 -1
- package/controls/icon.js.map +0 -1
- package/controls/index.js.map +0 -1
- package/controls/json-register.js.map +0 -1
- package/controls/json.js.map +0 -1
- package/controls/link.js.map +0 -1
- package/controls/location-register.js.map +0 -1
- package/controls/location.js.map +0 -1
- package/controls/media-register.js.map +0 -1
- package/controls/media.js.map +0 -1
- package/controls/number.js.map +0 -1
- package/controls/reference-register.js.map +0 -1
- package/controls/reference.js.map +0 -1
- package/controls/rich-text/blocks.d.ts +0 -28
- package/controls/rich-text/blocks.js.map +0 -1
- package/controls/rich-text/catalog.js.map +0 -1
- package/controls/rich-text/codec.js.map +0 -1
- package/controls/rich-text/component-card.js.map +0 -1
- package/controls/rich-text/control.js.map +0 -1
- package/controls/rich-text/dom.js.map +0 -1
- package/controls/rich-text/editor.js.map +0 -1
- package/controls/rich-text/floating.js.map +0 -1
- package/controls/rich-text/index.js.map +0 -1
- package/controls/rich-text/link-form.js +0 -111
- package/controls/rich-text/link-form.js.map +0 -1
- package/controls/rich-text/markdown.js.map +0 -1
- package/controls/rich-text/ops.js.map +0 -1
- package/controls/rich-text/toolbar.js.map +0 -1
- package/controls/scale.js.map +0 -1
- package/controls/slot-register.js.map +0 -1
- package/controls/slot-services.js +0 -38
- package/controls/slot-services.js.map +0 -1
- package/controls/slot.js.map +0 -1
- package/controls/table/index.js.map +0 -1
- package/controls/table/prod.js.map +0 -1
- package/controls/table/refs.js.map +0 -1
- package/controls/table/stored.js.map +0 -1
- package/controls/table/table-editor.js.map +0 -1
- package/controls/table/table-link.js.map +0 -1
- package/controls/table/table.js.map +0 -1
- package/controls/text.js.map +0 -1
- package/engine/array.js.map +0 -1
- package/engine/bits.js.map +0 -1
- package/engine/breadcrumb.js.map +0 -1
- package/engine/expand.js.map +0 -1
- package/engine/field-list.js.map +0 -1
- package/engine/field-shell.js.map +0 -1
- package/engine/frame.js.map +0 -1
- package/engine/group-summary.js.map +0 -1
- package/engine/grouping.js.map +0 -1
- package/engine/item-list.js.map +0 -1
- package/engine/kit-field.js.map +0 -1
- package/engine/schema-form.js.map +0 -1
- package/engine/slot.js.map +0 -1
- package/index.js +0 -55
- package/index.js.map +0 -1
- package/lib/cn.js.map +0 -1
- package/lib/columns.js.map +0 -1
- package/lib/frames.js.map +0 -1
- package/lib/icons.js.map +0 -1
- package/lib/path.js.map +0 -1
- package/lib/schema.js.map +0 -1
- package/lib/utils.js.map +0 -1
- package/lib/validate.js.map +0 -1
- package/schema/adapters.js.map +0 -1
- package/schema/help.js.map +0 -1
- package/schema/scale.js.map +0 -1
- package/schema/sources.js.map +0 -1
- package/schema/table.js.map +0 -1
- package/schema/types.js.map +0 -1
- package/ui/action-tray.js.map +0 -1
- package/ui/button.js.map +0 -1
- package/ui/choice-switch.js.map +0 -1
- package/ui/controls.js.map +0 -1
- package/ui/display.js.map +0 -1
- package/ui/expanded-editor-modal.js.map +0 -1
- package/ui/field-context.js.map +0 -1
- package/ui/floating-panel.js.map +0 -1
- package/ui/index.js +0 -13
- package/ui/input.js.map +0 -1
- package/ui/mode-bar.js.map +0 -1
- package/ui/overlay.js +0 -378
- package/ui/overlay.js.map +0 -1
- package/ui/path-crumbs.js.map +0 -1
- package/ui/presence.js.map +0 -1
- package/ui/select.js.map +0 -1
- package/ui/shortcut-hint.js.map +0 -1
- package/ui/surfaces.js.map +0 -1
- package/ui/tooltip-root.js.map +0 -1
- package/ui/variants.js.map +0 -1
- /package/{_virtual → dist/_virtual}/_rolldown/runtime.js +0 -0
- /package/{adapters → dist/adapters}/icons.d.ts +0 -0
- /package/{brand → dist/brand}/logo.d.ts +0 -0
- /package/{controls → dist/controls}/c1.d.ts +0 -0
- /package/{controls → dist/controls}/c2.d.ts +0 -0
- /package/{controls → dist/controls}/code-register.d.ts +0 -0
- /package/{controls → dist/controls}/code.d.ts +0 -0
- /package/{controls → dist/controls}/color.d.ts +0 -0
- /package/{controls → dist/controls}/date-register.d.ts +0 -0
- /package/{controls → dist/controls}/date-zone.d.ts +0 -0
- /package/{controls → dist/controls}/date.d.ts +0 -0
- /package/{controls → dist/controls}/form-picker-register.d.ts +0 -0
- /package/{controls → dist/controls}/form-picker.d.ts +0 -0
- /package/{controls → dist/controls}/icon-register.d.ts +0 -0
- /package/{controls → dist/controls}/json-register.d.ts +0 -0
- /package/{controls → dist/controls}/json.d.ts +0 -0
- /package/{controls → dist/controls}/link.d.ts +0 -0
- /package/{controls → dist/controls}/location-register.d.ts +0 -0
- /package/{controls → dist/controls}/location.d.ts +0 -0
- /package/{controls → dist/controls}/media-register.d.ts +0 -0
- /package/{controls → dist/controls}/number.d.ts +0 -0
- /package/{controls → dist/controls}/reference-register.d.ts +0 -0
- /package/{controls → dist/controls}/rich-text/index.d.ts +0 -0
- /package/{controls → dist/controls}/rich-text/link-form.d.ts +0 -0
- /package/{controls → dist/controls}/rich-text/markdown.d.ts +0 -0
- /package/{controls → dist/controls}/rich-text/ops.d.ts +0 -0
- /package/{controls → dist/controls}/scale.d.ts +0 -0
- /package/{controls → dist/controls}/slot-register.d.ts +0 -0
- /package/{controls → dist/controls}/slot.d.ts +0 -0
- /package/{controls → dist/controls}/table/index.d.ts +0 -0
- /package/{controls → dist/controls}/table/prod.d.ts +0 -0
- /package/{controls → dist/controls}/table/refs.d.ts +0 -0
- /package/{controls → dist/controls}/table/stored.d.ts +0 -0
- /package/{controls → dist/controls}/table/table-editor.d.ts +0 -0
- /package/{controls → dist/controls}/table/table-link.d.ts +0 -0
- /package/{controls → dist/controls}/table/table.d.ts +0 -0
- /package/{engine → dist/engine}/array.d.ts +0 -0
- /package/{engine → dist/engine}/bits.d.ts +0 -0
- /package/{engine → dist/engine}/field-list.d.ts +0 -0
- /package/{engine → dist/engine}/field-shell.d.ts +0 -0
- /package/{engine → dist/engine}/kit-field.d.ts +0 -0
- /package/{engine → dist/engine}/slot.d.ts +0 -0
- /package/{index.d.ts → dist/index.d.ts} +0 -0
- /package/{lib → dist/lib}/cn.d.ts +0 -0
- /package/{lib → dist/lib}/columns.d.ts +0 -0
- /package/{lib → dist/lib}/frames.d.ts +0 -0
- /package/{lib → dist/lib}/icons.d.ts +0 -0
- /package/{lib → dist/lib}/path.d.ts +0 -0
- /package/{lib → dist/lib}/utils.d.ts +0 -0
- /package/{schema → dist/schema}/adapters.d.ts +0 -0
- /package/{schema → dist/schema}/scale.d.ts +0 -0
- /package/{schema → dist/schema}/sources.d.ts +0 -0
- /package/{schema → dist/schema}/table.d.ts +0 -0
- /package/{types.d.ts → dist/types.d.ts} +0 -0
- /package/{ui → dist/ui}/choice-switch.d.ts +0 -0
- /package/{ui → dist/ui}/controls.d.ts +0 -0
- /package/{ui → dist/ui}/field-context.d.ts +0 -0
- /package/{ui → dist/ui}/mode-bar.d.ts +0 -0
- /package/{ui → dist/ui}/path-crumbs.d.ts +0 -0
- /package/{ui → dist/ui}/presence.d.ts +0 -0
- /package/{ui → dist/ui}/select.d.ts +0 -0
- /package/{ui → dist/ui}/shortcut-hint.d.ts +0 -0
- /package/{ui → dist/ui}/surfaces.d.ts +0 -0
- /package/{ui → dist/ui}/variants.d.ts +0 -0
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { cn } from "../lib/cn.js";
|
|
2
|
-
import { newKey, pathKey } from "../lib/path.js";
|
|
3
2
|
import { useForm, useKitServices } from "../context.js";
|
|
3
|
+
import { newKey, pathKey } from "../lib/path.js";
|
|
4
4
|
import { Button } from "../ui/button.js";
|
|
5
5
|
import { Menu, MenuContent, MenuItem, MenuSeparator, MenuTrigger } from "../ui/overlay.js";
|
|
6
6
|
import { itemNoun } from "../lib/schema.js";
|
|
7
7
|
import { Textarea } from "../ui/input.js";
|
|
8
8
|
import * as React from "react";
|
|
9
|
-
import { IconArrowDown, IconArrowUp, IconCopy, IconDots, IconGripVertical, IconPlus, IconTrash } from "@tabler/icons-react";
|
|
10
9
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
import { IconArrowDown, IconArrowUp, IconCopy, IconDots, IconGripVertical, IconLock, IconPlus, IconTrash } from "@tabler/icons-react";
|
|
11
11
|
import { useReducedMotion } from "framer-motion";
|
|
12
|
-
//#region src/
|
|
12
|
+
//#region src/engine/item-list.tsx
|
|
13
13
|
/**
|
|
14
14
|
* ITEM LIST — arrays of one line each (CPO D47): feature lists, bullets, "what's included", key points
|
|
15
15
|
* (V2 HEAD 9829bf1 kit/engine/item-list.tsx).
|
|
@@ -51,6 +51,7 @@ function toValue(kind, text) {
|
|
|
51
51
|
}
|
|
52
52
|
return kind === "url" || kind === "email" ? text.trim() : text;
|
|
53
53
|
}
|
|
54
|
+
var AT_REST = { transition: "transform 0ms linear" };
|
|
54
55
|
/** Tiles on the first row of a grid at pick-up (↑ / ↓ jump by this many, like sortableKeyboardCoordinates). */
|
|
55
56
|
var columns = (rects) => {
|
|
56
57
|
const top = rects[0]?.top;
|
|
@@ -64,7 +65,7 @@ var columns = (rects) => {
|
|
|
64
65
|
* a row of tiles) move it one slot; Space / Enter / Tab drops it as ONE reorder; Escape (or leaving the grip) cancels
|
|
65
66
|
* with nothing written. Focus stays on the grip.
|
|
66
67
|
*/
|
|
67
|
-
function useDragReorder(ids, onReorder, { axis = "y", disabled = false, distance = 4 } = {}) {
|
|
68
|
+
function useDragReorder(ids, onReorder, { axis = "y", disabled = false, distance = 4, rest = "dnd" } = {}) {
|
|
68
69
|
const [drag, setDrag] = React.useState(null);
|
|
69
70
|
const [announcement, setOwnAnnouncement] = React.useState("");
|
|
70
71
|
const ownId = React.useId();
|
|
@@ -259,13 +260,14 @@ function useDragReorder(ids, onReorder, { axis = "y", disabled = false, distance
|
|
|
259
260
|
onPointerDown: onPointerDown(id),
|
|
260
261
|
onKeyDown: onKeyDown(id),
|
|
261
262
|
onBlur: onBlur(id),
|
|
263
|
+
role: "button",
|
|
262
264
|
"aria-pressed": drag?.id === id ? true : void 0,
|
|
263
265
|
"aria-roledescription": "sortable",
|
|
264
266
|
"aria-describedby": describedBy,
|
|
265
267
|
"data-drag-handle": id
|
|
266
268
|
});
|
|
267
269
|
const style = (id) => {
|
|
268
|
-
if (!drag) return void 0;
|
|
270
|
+
if (!drag) return rest === "dnd" ? AT_REST : void 0;
|
|
269
271
|
if (id === drag.id) return {
|
|
270
272
|
transform: `translate3d(${axis === "grid" ? drag.dx : 0}px, ${drag.dy}px, 0)`,
|
|
271
273
|
zIndex: 10,
|
|
@@ -410,8 +412,9 @@ function ItemList({ field, path, list, readOnly, adapter, inputId }) {
|
|
|
410
412
|
if (take.length < values.length) toast?.("Some lines were left out", { description: `${field.title} allows ${max} at most, so ${values.length - take.length} didn't fit.` });
|
|
411
413
|
const items = take.map((v) => adapter.write(v));
|
|
412
414
|
const newKeys = items.map((it) => adapter.keyOf?.(it) ?? newKey());
|
|
415
|
+
const head = current === void 0 ? list.slice(0, i + 1) : [...list.slice(0, i), current];
|
|
413
416
|
commit([
|
|
414
|
-
...
|
|
417
|
+
...head,
|
|
415
418
|
...items,
|
|
416
419
|
...list.slice(i + 1)
|
|
417
420
|
], [
|
|
@@ -473,7 +476,11 @@ function ItemList({ field, path, list, readOnly, adapter, inputId }) {
|
|
|
473
476
|
const at = caret === "start" ? 0 : el.value.length;
|
|
474
477
|
el.setSelectionRange(at, at);
|
|
475
478
|
};
|
|
476
|
-
const
|
|
479
|
+
const orderLocked = !!field.orderLocked;
|
|
480
|
+
const sort = useDragReorder(keys, (from, to) => commit(move(list, from, to), move(keys, from, to)), {
|
|
481
|
+
disabled: readOnly || orderLocked,
|
|
482
|
+
rest: "none"
|
|
483
|
+
});
|
|
477
484
|
const n = list.length;
|
|
478
485
|
return /* @__PURE__ */ jsxs("div", {
|
|
479
486
|
className: "flex flex-col gap-1.5",
|
|
@@ -489,6 +496,7 @@ function ItemList({ field, path, list, readOnly, adapter, inputId }) {
|
|
|
489
496
|
item,
|
|
490
497
|
adapter,
|
|
491
498
|
readOnly,
|
|
499
|
+
orderLocked,
|
|
492
500
|
fieldKey: pathKey([...path, ...adapter.valuePath(i)]),
|
|
493
501
|
invalid: !!form.visibleIssue(pathKey([...path, ...adapter.valuePath(i)])),
|
|
494
502
|
inputId: i === 0 ? inputId : void 0,
|
|
@@ -559,7 +567,7 @@ function ItemList({ field, path, list, readOnly, adapter, inputId }) {
|
|
|
559
567
|
})]
|
|
560
568
|
});
|
|
561
569
|
}
|
|
562
|
-
function ItemRow({ rowKey, sort, index, count, noun, item, adapter, readOnly, fieldKey, invalid, inputId, canAdd, canRemove, min, register, onChange, onBlur, onEnter, onBackspaceEmpty, onPasteLines, onMove, onStep, onDuplicate, onRemove, onMenuMove }) {
|
|
570
|
+
function ItemRow({ rowKey, sort, index, count, noun, item, adapter, readOnly, orderLocked, fieldKey, invalid, inputId, canAdd, canRemove, min, register, onChange, onBlur, onEnter, onBackspaceEmpty, onPasteLines, onMove, onStep, onDuplicate, onRemove, onMenuMove }) {
|
|
563
571
|
const isDragging = sort.active === rowKey;
|
|
564
572
|
const text = adapter.read(item);
|
|
565
573
|
const [draft, setDraft] = React.useState(null);
|
|
@@ -572,7 +580,7 @@ function ItemRow({ rowKey, sort, index, count, noun, item, adapter, readOnly, fi
|
|
|
572
580
|
"data-field-key": fieldKey,
|
|
573
581
|
className: cn("group/il relative flex items-start gap-1", isDragging && "z-10 rounded-kit-md bg-kit-surface shadow-kit-lg"),
|
|
574
582
|
children: [
|
|
575
|
-
readOnly ? null : /* @__PURE__ */ jsx("button", {
|
|
583
|
+
readOnly ? null : orderLocked ? /* @__PURE__ */ jsx(OrderLockSlot, { className: "mt-1.5" }) : /* @__PURE__ */ jsx("button", {
|
|
576
584
|
type: "button",
|
|
577
585
|
"aria-label": `Reorder ${name}`,
|
|
578
586
|
...sort.handle(rowKey),
|
|
@@ -636,7 +644,7 @@ function ItemRow({ rowKey, sort, index, count, noun, item, adapter, readOnly, fi
|
|
|
636
644
|
onBackspaceEmpty();
|
|
637
645
|
} else if (e.altKey && (e.key === "ArrowUp" || e.key === "ArrowDown")) {
|
|
638
646
|
e.preventDefault();
|
|
639
|
-
onMove(e.key === "ArrowUp" ? -1 : 1);
|
|
647
|
+
if (!orderLocked) onMove(e.key === "ArrowUp" ? -1 : 1);
|
|
640
648
|
} else if (e.key === "ArrowUp" && atStart && !e.shiftKey) {
|
|
641
649
|
if (index > 0) {
|
|
642
650
|
e.preventDefault();
|
|
@@ -672,14 +680,14 @@ function ItemRow({ rowKey, sort, index, count, noun, item, adapter, readOnly, fi
|
|
|
672
680
|
/* @__PURE__ */ jsx(MenuSeparator, {}),
|
|
673
681
|
/* @__PURE__ */ jsx(MenuItem, {
|
|
674
682
|
icon: /* @__PURE__ */ jsx(IconArrowUp, { stroke: 1.5 }),
|
|
675
|
-
disabled: index === 0,
|
|
683
|
+
disabled: orderLocked || index === 0,
|
|
676
684
|
shortcut: "⌥↑",
|
|
677
685
|
onClick: () => onMenuMove(-1),
|
|
678
686
|
children: "Move up"
|
|
679
687
|
}),
|
|
680
688
|
/* @__PURE__ */ jsx(MenuItem, {
|
|
681
689
|
icon: /* @__PURE__ */ jsx(IconArrowDown, { stroke: 1.5 }),
|
|
682
|
-
disabled: index === count - 1,
|
|
690
|
+
disabled: orderLocked || index === count - 1,
|
|
683
691
|
shortcut: "⌥↓",
|
|
684
692
|
onClick: () => onMenuMove(1),
|
|
685
693
|
children: "Move down"
|
|
@@ -697,7 +705,21 @@ function ItemRow({ rowKey, sort, index, count, noun, item, adapter, readOnly, fi
|
|
|
697
705
|
]
|
|
698
706
|
});
|
|
699
707
|
}
|
|
708
|
+
/**
|
|
709
|
+
* The grip slot of a list whose order the site's code sets (identity rule 36): V2 content/editor/page-sections.tsx:155,
|
|
710
|
+
* a lock where the grip was, not interactive.
|
|
711
|
+
*/
|
|
712
|
+
function OrderLockSlot({ className }) {
|
|
713
|
+
return /* @__PURE__ */ jsx("span", {
|
|
714
|
+
"data-order-locked": "",
|
|
715
|
+
className: cn("flex w-5 shrink-0 justify-center text-kit-fg-4", className),
|
|
716
|
+
children: /* @__PURE__ */ jsx(IconLock, {
|
|
717
|
+
className: "size-3.5",
|
|
718
|
+
stroke: 1.5
|
|
719
|
+
})
|
|
720
|
+
});
|
|
721
|
+
}
|
|
700
722
|
//#endregion
|
|
701
|
-
export { ItemList, SharedSortProvider, arrayMove, useDragReorder, useSharedSort };
|
|
723
|
+
export { ItemList, OrderLockSlot, SharedSortProvider, arrayMove, useDragReorder, useSharedSort };
|
|
702
724
|
|
|
703
725
|
//# sourceMappingURL=item-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"item-list.js","names":[],"sources":["../../src/engine/item-list.tsx"],"sourcesContent":["/**\n * ITEM LIST — arrays of one line each (CPO D47): feature lists, bullets, \"what's included\", key points\n * (V2 HEAD 9829bf1 kit/engine/item-list.tsx).\n * Each item is a row you type into directly: grip · auto-growing input (founder rule: the whole text shows) · ⋯.\n * No drill frame, no expand. Keyboard: Enter adds the next item, Backspace on an empty row removes it, a multi-line\n * paste becomes several items, ⌥↑ / ⌥↓ move the row, ↑ / ↓ at the edges of the text step between rows. None of these\n * keys are printed on screen (D44); they live in aria labels and the ⋯ menu.\n *\n * Works for arrays of primitives (string / text / url / email / number) AND arrays of one-field objects\n * (`[{ _key, text }]`), which read and write that one field and keep their `_key`.\n *\n * Kit deviation: V2 sorts with @dnd-kit, which is not on the kit's package allow-list. `useDragReorder` below is the\n * kit's sortable: pointer drag on the grip (4px activation, siblings slide out of the way like dnd-kit's vertical\n * strategy), and dnd-kit's KeyboardSensor + sortableKeyboardCoordinates on a focused grip: Space / Enter picks the row\n * up, the arrow keys move it (siblings slide, nothing is written yet), Space / Enter / Tab drops it as ONE reorder\n * (one undo step), Escape puts it back. `sort.a11y` is dnd-kit's accessibility markup (hidden instructions + a visually\n * hidden `role=\"status\"` live region), rendered where V2's DndContext rendered it: right after the sortable children.\n */\nimport * as React from \"react\";\nimport { useReducedMotion } from \"framer-motion\";\nimport { IconArrowDown, IconArrowUp, IconCopy, IconDots, IconGripVertical, IconLock, IconPlus, IconTrash } from \"@tabler/icons-react\";\nimport { Button } from \"../ui/button\";\nimport { Textarea } from \"../ui/input\";\nimport { Menu, MenuContent, MenuItem, MenuSeparator, MenuTrigger } from \"../ui/overlay\";\nimport { cn } from \"../lib/cn\";\nimport type { FieldPath, FieldSchema } from \"../schema/types\";\nimport { useForm, useKitServices } from \"../context\";\nimport { newKey, pathKey } from \"../lib/path\";\nimport { itemNoun } from \"../lib/schema\";\n\nexport type ItemKind = \"text\" | \"number\" | \"url\" | \"email\";\n\nexport interface ItemListAdapter {\n kind: ItemKind;\n /** the text shown in the row */\n read: (item: unknown) => string;\n /** a new list item holding `value` (objects keep `prev`'s other keys and `_key`) */\n write: (value: unknown, prev?: unknown) => unknown;\n /** the stable key of an item, when it carries one (`_key` on objects) */\n keyOf?: (item: unknown) => string | undefined;\n /** the path of the editable value inside item `i` (canvas anchoring, issues) */\n valuePath: (i: number) => FieldPath;\n placeholder?: string;\n}\n\n/** V2 controls/text TEXT_FOCUS: a list row's input shows the field focus border only, no ring shadow. */\nconst TEXT_FOCUS = \"focus:shadow-none focus-visible:shadow-none\";\nconst EASE = \"cubic-bezier(0.22, 1, 0.36, 1)\";\n\n\nconst cap = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);\n/** \"- Net-30\", \"• Net-30\", \"1. Net-30\", \"[x] Net-30\" → \"Net-30\" */\nconst stripBullet = (s: string) => s.replace(/^\\s*(?:[-*•‣◦▪–—]|\\d+[.)]|\\[[ xX]\\])\\s+/, \"\").trim();\nconst move = <T,>(list: T[], from: number, to: number): T[] => {\n const next = list.slice();\n const [it] = next.splice(from, 1);\n next.splice(to, 0, it);\n return next;\n};\n/** dnd-kit's arrayMove, for callers that reorder lists. */\nexport const arrayMove = move;\n\nfunction toValue(kind: ItemKind, text: string): unknown {\n if (kind === \"number\") {\n const t = text.trim();\n if (!t) return null;\n const n = Number(t.replace(/,/g, \"\"));\n return Number.isFinite(n) ? n : undefined;\n }\n return kind === \"url\" || kind === \"email\" ? text.trim() : text;\n}\n\n/* ── Sortable (the kit's stand-in for @dnd-kit) ─────────────────────── */\ninterface DragState {\n id: string;\n from: number;\n over: number;\n dx: number;\n dy: number;\n /** how far a sibling slides to make room (dragged height + the list gap) */\n shift: number;\n /** item rects at pick-up (grid tiles slide into their neighbour's rect) */\n rects: (DOMRect | undefined)[];\n /** picked up from the keyboard: the row glides between slots instead of following a pointer */\n keyboard?: boolean;\n}\n\n/* dnd-kit useSortable at rest returns its disabledTransition (\"transform 0ms linear\"), never `transition: all` (V2 rows\n compute transition-property transform, timing linear) */\nconst AT_REST: React.CSSProperties = { transition: \"transform 0ms linear\" };\n\n/** Tiles on the first row of a grid at pick-up (↑ / ↓ jump by this many, like sortableKeyboardCoordinates). */\nconst columns = (rects: (DOMRect | undefined)[]) => {\n const top = rects[0]?.top;\n return top == null ? 1 : Math.max(1, rects.filter((r) => r?.top === top).length);\n};\n\n/**\n * Sortable rows by id. `register(id)` goes on the element that moves, `handle(id)` on its grip. Pointer: drag past\n * `distance` px to pick up; the row follows the pointer, siblings slide (list axis by one row, grid into the\n * neighbour's rect), the drop commits ONE reorder.\n * Keyboard on the grip (dnd-kit KeyboardSensor): Space / Enter picks up; ↑ / ↓ (← / → too in a grid, where ↑ / ↓ jump\n * a row of tiles) move it one slot; Space / Enter / Tab drops it as ONE reorder; Escape (or leaving the grip) cancels\n * with nothing written. Focus stays on the grip.\n */\nexport function useDragReorder(\n ids: string[],\n onReorder: (from: number, to: number) => void,\n {\n axis = \"y\",\n disabled = false,\n distance = 4,\n rest = \"dnd\",\n }: {\n axis?: \"y\" | \"grid\";\n disabled?: boolean;\n distance?: number;\n /** the row style at rest: dnd-kit's disabledTransition (V2 object rows, chips), or none (V2 item-list rows) */\n rest?: \"dnd\" | \"none\";\n } = {},\n) {\n const [drag, setDrag] = React.useState<DragState | null>(null);\n const [announcement, setOwnAnnouncement] = React.useState(\"\");\n const ownId = React.useId();\n /* inside a shared sort (V2's one DndContext over several lists) the instructions and live region are the context's */\n const shared = React.useContext(SharedSortContext);\n const describedBy = shared?.id ?? ownId;\n const setAnnouncement = shared?.announce ?? setOwnAnnouncement;\n /* reduced motion: the keyboard glide and the neighbours' slide jump straight to their place */\n const glide = useReducedMotion() ? \"none\" : `transform 200ms ${EASE}`;\n const els = React.useRef(new Map<string, HTMLElement>());\n const grips = React.useRef(new Map<string, HTMLElement>());\n const refocus = React.useRef<string | null>(null);\n /* the keyboard drag, read synchronously by key handlers (state lags a render behind) */\n const kb = React.useRef<DragState | null>(null);\n const setKb = (s: DragState | null) => {\n kb.current = s;\n setDrag(s);\n };\n const latest = React.useRef({ ids, onReorder });\n latest.current = { ids, onReorder };\n\n React.useLayoutEffect(() => {\n const id = refocus.current;\n if (!id) return;\n refocus.current = null;\n const g = grips.current.get(id);\n if (g && document.activeElement !== g) g.focus();\n });\n\n const register = (id: string) => (el: HTMLElement | null) => {\n if (el) els.current.set(id, el);\n else els.current.delete(id);\n };\n\n const onPointerDown = (id: string) => (e: React.PointerEvent) => {\n if (disabled || e.button !== 0 || kb.current) return;\n e.stopPropagation();\n const from = latest.current.ids.indexOf(id);\n if (from < 0) return;\n const x0 = e.clientX;\n const y0 = e.clientY;\n let rects: (DOMRect | undefined)[] = [];\n let state: DragState | null = null;\n const userSelect = document.body.style.userSelect;\n const onMove = (ev: PointerEvent) => {\n const dx = ev.clientX - x0;\n const dy = ev.clientY - y0;\n if (!state) {\n if (Math.hypot(dx, dy) < distance) return;\n rects = latest.current.ids.map((k) => els.current.get(k)?.getBoundingClientRect());\n const r = rects[from];\n const next = rects[from + 1] ?? rects[from - 1];\n const gap = r && next ? Math.max(0, next.top > r.top ? next.top - r.bottom : r.top - next.bottom) : 0;\n state = { id, from, over: from, dx, dy, shift: (r?.height ?? 0) + gap, rects };\n document.body.style.userSelect = \"none\";\n setAnnouncement(`Picked up item ${from + 1} of ${latest.current.ids.length}.`);\n }\n const hit = rects.findIndex((r) => r && ev.clientY >= r.top && ev.clientY <= r.bottom && (axis === \"y\" || (ev.clientX >= r.left && ev.clientX <= r.right)));\n state = { ...state, dx, dy, over: hit >= 0 ? hit : state.over };\n setDrag(state);\n };\n const end = (commit: boolean) => {\n window.removeEventListener(\"pointermove\", onMove);\n window.removeEventListener(\"pointerup\", onUp);\n window.removeEventListener(\"pointercancel\", onCancel);\n document.body.style.userSelect = userSelect;\n const s = state;\n setDrag(null);\n if (!s) return;\n /* the click that ends a drag never opens the row under it */\n const swallow = (ce: MouseEvent) => {\n ce.stopPropagation();\n ce.preventDefault();\n };\n window.addEventListener(\"click\", swallow, { capture: true, once: true });\n window.setTimeout(() => window.removeEventListener(\"click\", swallow, { capture: true }), 0);\n if (commit && s.over !== s.from) latest.current.onReorder(s.from, s.over);\n setAnnouncement(commit ? `Item dropped at position ${s.over + 1} of ${latest.current.ids.length}.` : `Dragging was cancelled. Item ${s.from + 1} was dropped.`);\n };\n const onUp = () => end(true);\n const onCancel = () => end(false);\n window.addEventListener(\"pointermove\", onMove);\n window.addEventListener(\"pointerup\", onUp);\n window.addEventListener(\"pointercancel\", onCancel);\n };\n\n /** where the picked-up row sits over slot `over` (the sortable strategies' target rect) */\n const offset = (s: DragState, over: number) => {\n const a = s.rects[s.from];\n const b = s.rects[over];\n if (!a || !b || over === s.from) return { dx: 0, dy: 0 };\n if (axis === \"grid\") return { dx: b.left - a.left, dy: b.top - a.top };\n return { dx: 0, dy: over > s.from ? b.bottom - a.bottom : b.top - a.top };\n };\n\n const onKeyDown = (id: string) => (e: React.KeyboardEvent) => {\n if (disabled || e.nativeEvent.isComposing) return;\n const { ids: list, onReorder: commit } = latest.current;\n const n = list.length;\n const s = kb.current;\n if (!s) {\n if (e.key !== \" \" && e.key !== \"Enter\") return;\n const from = list.indexOf(id);\n if (from < 0 || drag) return;\n e.preventDefault();\n e.stopPropagation();\n const rects = list.map((k) => els.current.get(k)?.getBoundingClientRect());\n const r = rects[from];\n const next = rects[from + 1] ?? rects[from - 1];\n const gap = r && next ? Math.max(0, next.top > r.top ? next.top - r.bottom : r.top - next.bottom) : 0;\n setKb({ id, from, over: from, dx: 0, dy: 0, shift: (r?.height ?? 0) + gap, rects, keyboard: true });\n setAnnouncement(`Picked up item ${from + 1} of ${n}.`);\n return;\n }\n if (s.id !== id) return;\n if (e.key === \" \" || e.key === \"Enter\" || e.key === \"Tab\") {\n if (e.key !== \"Tab\") {\n e.preventDefault();\n refocus.current = id;\n }\n e.stopPropagation();\n setKb(null);\n // the list changed under the drag (another writer): nothing is moved, and the reason is announced\n if (list[s.from] !== id) return setAnnouncement(`The list changed while moving. Item ${s.from + 1} was not moved.`);\n if (s.over !== s.from) commit(s.from, s.over);\n setAnnouncement(`Item dropped at position ${s.over + 1} of ${n}.`);\n return;\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n e.stopPropagation();\n refocus.current = id;\n setKb(null);\n setAnnouncement(`Dragging was cancelled. Item ${s.from + 1} was dropped.`);\n return;\n }\n const rowStep = axis === \"grid\" ? columns(s.rects) : 1;\n const step =\n e.key === \"ArrowDown\" ? rowStep : e.key === \"ArrowUp\" ? -rowStep :\n axis === \"grid\" && e.key === \"ArrowRight\" ? 1 : axis === \"grid\" && e.key === \"ArrowLeft\" ? -1 : 0;\n if (!step) return;\n e.preventDefault();\n e.stopPropagation();\n const to = s.over + step;\n if (to < 0 || to >= n) return;\n setKb({ ...s, over: to, ...offset(s, to) });\n setAnnouncement(`Item moved to position ${to + 1} of ${n}.`);\n };\n\n /* focus leaving a picked-up grip (a click elsewhere) puts the row back, like Escape */\n const onBlur = (id: string) => () => {\n const s = kb.current;\n if (!s || s.id !== id) return;\n setKb(null);\n setAnnouncement(`Dragging was cancelled. Item ${s.from + 1} was dropped.`);\n };\n\n const handle = (id: string) => ({\n ref: (el: HTMLElement | null) => {\n if (el) grips.current.set(id, el);\n else grips.current.delete(id);\n },\n onPointerDown: onPointerDown(id),\n onKeyDown: onKeyDown(id),\n onBlur: onBlur(id),\n /* dnd-kit's sortable attributes (V2): role \"button\" on the grip */\n role: \"button\",\n \"aria-pressed\": drag?.id === id ? true : undefined,\n \"aria-roledescription\": \"sortable\",\n \"aria-describedby\": describedBy,\n \"data-drag-handle\": id,\n });\n\n const style = (id: string): React.CSSProperties | undefined => {\n if (!drag) return rest === \"dnd\" ? AT_REST : undefined;\n if (id === drag.id) return { transform: `translate3d(${axis === \"grid\" ? drag.dx : 0}px, ${drag.dy}px, 0)`, zIndex: 10, position: \"relative\", transition: drag.keyboard ? glide : \"none\" };\n const i = ids.indexOf(id);\n const { from, over, shift } = drag;\n if (axis === \"grid\") {\n /* dnd-kit rectSortingStrategy (V2 grid lists): each tile between the pick-up and the hover slot slides into its\n neighbour's rect, so the gap opens where the tile will land */\n const to = from < over && i > from && i <= over ? i - 1 : from > over && i >= over && i < from ? i + 1 : i;\n const a = drag.rects[i];\n const b = drag.rects[to];\n const t = to !== i && a && b ? `translate3d(${b.left - a.left}px, ${b.top - a.top}px, 0)` : undefined;\n return { transform: t, transition: glide };\n }\n const dy = from < over && i > from && i <= over ? -shift : from > over && i >= over && i < from ? shift : 0;\n return { transform: dy ? `translate3d(0, ${dy}px, 0)` : undefined, transition: glide };\n };\n\n const a11y = shared ? null : <SortAnnouncer id={describedBy} announcement={announcement} />;\n return { register, handle, style, active: drag?.id ?? null, over: drag ? ids[drag.over] ?? null : null, a11y };\n}\n\nconst SharedSortContext = React.createContext<{ id: string; announce: (message: string) => void } | null>(null);\n\n/**\n * One announcer for several sortable lists, as V2 has where ONE DndContext wraps them (a table's row groups): the\n * lists under `SharedSortProvider value={value}` describe their grips with its instructions and announce into its live region, and `a11y`\n * renders once where V2's DndContext rendered it (after its children).\n */\nexport function useSharedSort() {\n const [announcement, setAnnouncement] = React.useState(\"\");\n const id = React.useId();\n const value = React.useMemo(() => ({ id, announce: setAnnouncement }), [id]);\n return { value, a11y: <SortAnnouncer id={id} announcement={announcement} /> };\n}\nexport const SharedSortProvider = SharedSortContext.Provider;\n\n/* dnd-kit's LiveRegion style: visually hidden, still read by screen readers */\nconst LIVE_REGION: React.CSSProperties = {\n position: \"fixed\", top: 0, left: 0, width: 1, height: 1, margin: -1, border: 0, padding: 0, overflow: \"hidden\",\n clip: \"rect(0 0 0 0)\", clipPath: \"inset(100%)\", whiteSpace: \"nowrap\",\n};\n/**\n * dnd-kit's <Accessibility> (V2 got it from every DndContext): the drag instructions (display: none, named by each\n * handle's aria-describedby) and an assertive `role=\"status\"` live region with the last move. Like dnd-kit it renders\n * only after mount.\n */\nfunction SortAnnouncer({ id, announcement }: { id: string; announcement: string }) {\n const [mounted, setMounted] = React.useState(false);\n React.useEffect(() => setMounted(true), []);\n if (!mounted) return null;\n return (\n <>\n <div id={id} style={{ display: \"none\" }}>\n To pick up a draggable item, press the space bar or enter. While dragging, use the arrow keys to move the item. Press space or enter again to drop the item in its new position, or press escape to cancel.\n </div>\n <div style={LIVE_REGION} role=\"status\" aria-live=\"assertive\" aria-atomic>\n {announcement}\n </div>\n </>\n );\n}\n\n/** Keys for list items that have none (primitives): stable across our own edits, regenerated on outside changes. */\nfunction useRowKeys(list: unknown[], keyOf?: (item: unknown) => string | undefined) {\n const local = React.useRef<string[]>([]);\n if (keyOf) return { keys: list.map((it, i) => keyOf(it) ?? `i${i}`), set: (_: string[]) => {} };\n if (local.current.length !== list.length) {\n const next = local.current.slice(0, list.length);\n while (next.length < list.length) next.push(newKey());\n local.current = next;\n }\n return { keys: local.current, set: (k: string[]) => (local.current = k) };\n}\n\nexport function ItemList({\n field,\n path,\n list,\n readOnly,\n adapter,\n inputId,\n}: {\n field: FieldSchema;\n path: FieldPath;\n list: unknown[];\n readOnly: boolean;\n adapter: ItemListAdapter;\n /** the field label's `htmlFor` lands on the first row */\n inputId?: string;\n}) {\n const form = useForm()!;\n const { toast } = useKitServices();\n const { min, max } = field.validation ?? {};\n const noun = itemNoun(field);\n const { keys, set: setKeys } = useRowKeys(list, adapter.keyOf);\n const inputs = React.useRef(new Map<string, HTMLTextAreaElement>());\n const addRef = React.useRef<HTMLButtonElement>(null);\n const focusReq = React.useRef<{ key: string; caret: \"start\" | \"end\" | number } | null>(null);\n const atMax = max != null && list.length >= max;\n const atMin = min != null && list.length <= min;\n\n // Apply a pending focus after the list re-renders (add / remove / move / paste).\n React.useLayoutEffect(() => {\n const req = focusReq.current;\n if (!req) return;\n const el = inputs.current.get(req.key);\n if (!el) return;\n focusReq.current = null;\n el.focus({ preventScroll: false });\n const at = req.caret === \"start\" ? 0 : req.caret === \"end\" ? el.value.length : Math.min(req.caret, el.value.length);\n el.setSelectionRange(at, at);\n el.scrollIntoView?.({ block: \"nearest\" });\n });\n\n const commit = (next: unknown[], nextKeys: string[]) => {\n setKeys(nextKeys);\n form.setAt(path, next);\n };\n const limitToast = () => toast?.(\"Limit reached\", { description: `${field.title} allows ${max} at most.` });\n\n /** Insert `values` after row i (and optionally replace row i itself in the same write). */\n const insertAfter = (i: number, values: unknown[], caret: \"start\" | \"end\" = \"end\", current?: unknown) => {\n const room = max == null ? values.length : Math.max(0, max - list.length);\n if (room === 0) return limitToast();\n const take = values.slice(0, room);\n if (take.length < values.length) toast?.(\"Some lines were left out\", { description: `${field.title} allows ${max} at most, so ${values.length - take.length} didn't fit.` });\n const items = take.map((v) => adapter.write(v));\n const newKeys = items.map((it) => adapter.keyOf?.(it) ?? newKey());\n const head = current === undefined ? list.slice(0, i + 1) : [...list.slice(0, i), current];\n commit([...head, ...items, ...list.slice(i + 1)], [...keys.slice(0, i + 1), ...newKeys, ...keys.slice(i + 1)]);\n focusReq.current = { key: newKeys[newKeys.length - 1], caret };\n };\n const add = () => {\n if (atMax) return limitToast();\n insertAfter(list.length - 1, [adapter.kind === \"number\" ? null : \"\"]);\n };\n const removeAt = (i: number, opts: { undo?: boolean; focus?: \"prev\" | \"none\" } = {}) => {\n if (atMin) return toast?.(`At least ${min} required`, { description: `${field.title} needs ${min} or more.` });\n const prevList = list;\n const prevKeys = keys;\n commit(list.filter((_, j) => j !== i), keys.filter((_, j) => j !== i));\n if (opts.focus !== \"none\") {\n const target = i > 0 ? keys[i - 1] : keys[i + 1];\n if (target) focusReq.current = { key: target, caret: i > 0 ? \"end\" : \"start\" };\n else window.setTimeout(() => addRef.current?.focus(), 0);\n }\n if (opts.undo) {\n const text = adapter.read(prevList[i]);\n toast?.(text ? `“${text.length > 40 ? `${text.slice(0, 38)}…` : text}” removed` : `${cap(noun)} removed`, {\n action: { label: \"Undo\", onClick: () => commit(prevList, prevKeys) },\n duration: 10_000,\n });\n }\n };\n const moveRow = (i: number, d: -1 | 1, keepFocus = false) => {\n const to = i + d;\n if (to < 0 || to >= list.length) return;\n const caret = inputs.current.get(keys[i])?.selectionStart ?? \"end\";\n commit(move(list, i, to), move(keys, i, to));\n if (keepFocus) focusReq.current = { key: keys[i], caret };\n };\n const duplicate = (i: number) => {\n if (atMax) return limitToast();\n insertAfter(i, [toValue(adapter.kind, adapter.read(list[i])) ?? adapter.read(list[i])]);\n };\n const focusRow = (i: number, caret: \"start\" | \"end\") => {\n const el = inputs.current.get(keys[i]);\n if (!el) return;\n el.focus();\n const at = caret === \"start\" ? 0 : el.value.length;\n el.setSelectionRange(at, at);\n };\n\n // The site's code sets the order (identity rule 36): rows stay editable, nothing reorders them.\n const orderLocked = !!field.orderLocked;\n /* V2's item-list rows carry no transition at rest (computed `all 0s ease`), unlike its object rows and chips */\n const sort = useDragReorder(keys, (from, to) => commit(move(list, from, to), move(keys, from, to)), { disabled: readOnly || orderLocked, rest: \"none\" });\n\n const n = list.length;\n return (\n <div className=\"flex flex-col gap-1.5\">\n {n ? (\n <>\n <ul className=\"flex flex-col gap-1.5\" aria-label={field.title}>\n {list.map((item, i) => (\n <ItemRow\n key={keys[i]}\n rowKey={keys[i]}\n sort={sort}\n index={i}\n count={n}\n noun={noun}\n item={item}\n adapter={adapter}\n readOnly={readOnly}\n orderLocked={orderLocked}\n fieldKey={pathKey([...path, ...adapter.valuePath(i)])}\n invalid={!!form.visibleIssue(pathKey([...path, ...adapter.valuePath(i)]))}\n inputId={i === 0 ? inputId : undefined}\n canAdd={!atMax}\n canRemove={!atMin}\n min={min}\n register={(el) => (el ? inputs.current.set(keys[i], el) : inputs.current.delete(keys[i]))}\n onChange={(v) => form.setAt([...path, i], adapter.write(v, item))}\n onBlur={() => form.touch(pathKey([...path, ...adapter.valuePath(i)]))}\n onEnter={(caretAtStart) => {\n if (!adapter.read(item).trim() && i === n - 1) return; // an empty last row doesn't spawn another\n if (atMax) return limitToast();\n // caret at the very start of a filled row: insert ABOVE (like a list in a doc)\n if (caretAtStart && adapter.read(item)) {\n const k = adapter.write(adapter.kind === \"number\" ? null : \"\");\n const nk = adapter.keyOf?.(k) ?? newKey();\n commit([...list.slice(0, i), k, ...list.slice(i)], [...keys.slice(0, i), nk, ...keys.slice(i)]);\n focusReq.current = { key: keys[i], caret: \"start\" };\n return;\n }\n insertAfter(i, [adapter.kind === \"number\" ? null : \"\"]);\n }}\n onBackspaceEmpty={() => removeAt(i, { focus: \"prev\" })}\n onPasteLines={(first, rest, caret) => {\n const items = rest.map((t) => toValue(adapter.kind, t)).filter((v) => v !== undefined);\n const current = adapter.write(toValue(adapter.kind, first) ?? first, item);\n if (items.length && !atMax) insertAfter(i, items, \"end\", current);\n else {\n if (items.length) limitToast();\n form.setAt([...path, i], current);\n focusReq.current = { key: keys[i], caret };\n }\n }}\n onMove={(d) => moveRow(i, d, true)}\n onStep={(d) => {\n const j = i + d;\n if (j >= 0 && j < n) focusRow(j, d < 0 ? \"end\" : \"start\");\n }}\n onDuplicate={() => duplicate(i)}\n onRemove={() => removeAt(i, { undo: true })}\n onMenuMove={(d) => moveRow(i, d)}\n />\n ))}\n </ul>\n {sort.a11y}\n </>\n ) : null}\n {readOnly ? (n ? null : <span className=\"text-kit-sm text-kit-fg-3\">Nothing here yet.</span>) : (\n <Button ref={addRef} size=\"sm\" variant=\"ghost\" className=\"-ml-1 self-start text-kit-fg-2\" leftIcon={<IconPlus stroke={1.5} />} disabled={atMax} onClick={add}>\n Add {noun}\n </Button>\n )}\n </div>\n );\n}\n\nfunction ItemRow({\n rowKey, sort, index, count, noun, item, adapter, readOnly, orderLocked, fieldKey, invalid, inputId, canAdd, canRemove, min, register,\n onChange, onBlur, onEnter, onBackspaceEmpty, onPasteLines, onMove, onStep, onDuplicate, onRemove, onMenuMove,\n}: {\n rowKey: string; sort: ReturnType<typeof useDragReorder>; index: number; count: number; noun: string; item: unknown; adapter: ItemListAdapter; readOnly: boolean; orderLocked?: boolean;\n fieldKey: string; invalid: boolean; inputId?: string; canAdd: boolean; canRemove: boolean; min?: number;\n register: (el: HTMLTextAreaElement | null) => void;\n onChange: (v: unknown) => void; onBlur: () => void; onEnter: (caretAtStart: boolean) => void; onBackspaceEmpty: () => void;\n onPasteLines: (first: string, rest: string[], caret: number) => void; onMove: (d: -1 | 1) => void; onStep: (d: -1 | 1) => void;\n onDuplicate: () => void; onRemove: () => void; onMenuMove: (d: -1 | 1) => void;\n}) {\n const isDragging = sort.active === rowKey;\n const text = adapter.read(item);\n // numbers keep what you're typing (\"1.\", \"-\") until it parses\n const [draft, setDraft] = React.useState<string | null>(null);\n const shown = draft ?? text;\n const label = `${cap(noun)} ${index + 1} of ${count}`;\n const name = text ? `“${text.length > 32 ? `${text.slice(0, 30)}…` : text}”` : `${noun} ${index + 1}`;\n return (\n <li\n ref={sort.register(rowKey)}\n style={sort.style(rowKey)}\n data-field-key={fieldKey}\n className={cn(\"group/il relative flex items-start gap-1\", isDragging && \"z-10 rounded-kit-md bg-kit-surface shadow-kit-lg\")}\n >\n {readOnly ? null : orderLocked ? (\n <OrderLockSlot className=\"mt-1.5\" />\n ) : (\n <button\n type=\"button\"\n aria-label={`Reorder ${name}`}\n {...sort.handle(rowKey)}\n className=\"relative mt-1.5 flex h-5 w-4 shrink-0 cursor-grab touch-none items-center justify-center rounded-kit-sm text-kit-fg-4 transition-colors before:absolute before:-inset-1.5 hover:text-kit-fg-2 active:cursor-grabbing\"\n >\n <IconGripVertical className=\"size-3.5\" stroke={1.5} />\n </button>\n )}\n <div className=\"min-w-0 flex-1\">\n <Textarea\n ref={register}\n id={inputId}\n rows={1}\n value={shown}\n readOnly={readOnly}\n aria-label={label}\n aria-invalid={invalid || undefined}\n placeholder={adapter.placeholder ?? cap(noun)}\n inputMode={adapter.kind === \"number\" ? \"decimal\" : adapter.kind === \"url\" ? \"url\" : adapter.kind === \"email\" ? \"email\" : undefined}\n spellCheck={adapter.kind === \"text\"}\n onBlur={() => {\n setDraft(null);\n onBlur();\n }}\n onChange={(e) => {\n const raw = e.target.value.replace(/\\r?\\n/g, \" \");\n if (adapter.kind === \"number\") {\n setDraft(raw);\n const v = toValue(\"number\", raw);\n if (v !== undefined) onChange(v);\n return;\n }\n onChange(toValue(adapter.kind, raw));\n }}\n onPaste={(e) => {\n if (readOnly) return;\n const clip = e.clipboardData.getData(\"text/plain\");\n if (!/\\r?\\n/.test(clip.trim())) return; // one line: the browser pastes it\n const lines = clip.split(/\\r?\\n/).map(stripBullet).filter(Boolean);\n if (lines.length < 2) return;\n e.preventDefault();\n const el = e.currentTarget;\n const before = el.value.slice(0, el.selectionStart);\n const after = el.value.slice(el.selectionEnd);\n const rest = lines.slice(1);\n rest[rest.length - 1] = `${rest[rest.length - 1]}${after}`;\n onPasteLines(`${before}${lines[0]}`, rest, before.length + lines[0].length);\n }}\n onKeyDown={(e) => {\n if (readOnly || e.nativeEvent.isComposing) return;\n const el = e.currentTarget;\n const atStart = el.selectionStart === 0 && el.selectionEnd === 0;\n const atEnd = el.selectionStart === el.value.length && el.selectionEnd === el.value.length;\n if (e.key === \"Enter\" && !e.shiftKey && !e.metaKey && !e.ctrlKey) {\n e.preventDefault();\n onEnter(atStart && el.value.length > 0);\n } else if (e.key === \"Backspace\" && !el.value && canRemove) {\n e.preventDefault();\n onBackspaceEmpty();\n } else if (e.altKey && (e.key === \"ArrowUp\" || e.key === \"ArrowDown\")) {\n e.preventDefault();\n if (!orderLocked) onMove(e.key === \"ArrowUp\" ? -1 : 1);\n } else if (e.key === \"ArrowUp\" && atStart && !e.shiftKey) {\n if (index > 0) {\n e.preventDefault();\n onStep(-1);\n }\n } else if (e.key === \"ArrowDown\" && atEnd && !e.shiftKey) {\n if (index < count - 1) {\n e.preventDefault();\n onStep(1);\n }\n }\n }}\n className={cn(TEXT_FOCUS, \"min-h-8 py-1.5 leading-5\")}\n />\n </div>\n {readOnly ? null : (\n <Menu>\n <MenuTrigger\n aria-label={`${cap(noun)} ${index + 1} actions`}\n className=\"mt-0.5 flex size-7 shrink-0 items-center justify-center rounded-kit-md text-kit-fg-4 transition-colors hover:bg-kit-hover hover:text-kit-fg group-focus-within/il:text-kit-fg-3 group-hover/il:text-kit-fg-3 data-[popup-open]:bg-kit-hover data-[popup-open]:text-kit-fg\"\n >\n <IconDots className=\"size-4\" stroke={1.5} />\n </MenuTrigger>\n <MenuContent align=\"end\" className=\"w-48\">\n <MenuItem icon={<IconCopy stroke={1.5} />} disabled={!canAdd} onClick={onDuplicate}>{canAdd ? \"Duplicate\" : \"Duplicate · limit reached\"}</MenuItem>\n <MenuSeparator />\n <MenuItem icon={<IconArrowUp stroke={1.5} />} disabled={orderLocked || index === 0} shortcut=\"⌥↑\" onClick={() => onMenuMove(-1)}>Move up</MenuItem>\n <MenuItem icon={<IconArrowDown stroke={1.5} />} disabled={orderLocked || index === count - 1} shortcut=\"⌥↓\" onClick={() => onMenuMove(1)}>Move down</MenuItem>\n <MenuSeparator />\n <MenuItem danger icon={<IconTrash stroke={1.5} />} disabled={!canRemove} onClick={onRemove}>{canRemove ? \"Delete\" : `Delete · at least ${min} required`}</MenuItem>\n </MenuContent>\n </Menu>\n )}\n </li>\n );\n}\n\n/**\n * The grip slot of a list whose order the site's code sets (identity rule 36): V2 content/editor/page-sections.tsx:155,\n * a lock where the grip was, not interactive.\n */\nexport function OrderLockSlot({ className }: { className?: string }) {\n return (\n <span data-order-locked=\"\" className={cn(\"flex w-5 shrink-0 justify-center text-kit-fg-4\", className)}>\n <IconLock className=\"size-3.5\" stroke={1.5} />\n </span>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { cn } from "../lib/cn.js";
|
|
2
|
+
import { resolveFieldAccess, useForm, useKitEnv, useKitServices } from "../context.js";
|
|
2
3
|
import { isObj, pathKey } from "../lib/path.js";
|
|
3
4
|
import { KitIcon } from "../lib/icons.js";
|
|
4
|
-
import { resolveFieldAccess, useForm, useKitEnv, useKitServices } from "../context.js";
|
|
5
5
|
import { Button } from "../ui/button.js";
|
|
6
6
|
import { Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, Popover, PopoverContent, PopoverTrigger } from "../ui/overlay.js";
|
|
7
|
-
import { isHidden, objectOpenMode, plainText, summarize } from "../lib/schema.js";
|
|
7
|
+
import { condCtx, isHidden, objectOpenMode, plainText, summarize } from "../lib/schema.js";
|
|
8
8
|
import { IssueDot, RowChrome } from "./bits.js";
|
|
9
9
|
import { resolveHelp } from "../schema/help.js";
|
|
10
10
|
import { FieldShell } from "./field-shell.js";
|
|
11
11
|
import { groupSummary } from "./group-summary.js";
|
|
12
|
+
import { isIconImage } from "../lib/icon-image.js";
|
|
12
13
|
import { FieldInset, FieldRun, useInsetDepth } from "./grouping.js";
|
|
13
14
|
import { FieldList } from "./field-list.js";
|
|
14
15
|
import { ArrayField } from "./array.js";
|
|
@@ -17,9 +18,9 @@ import { SchemaForm } from "./schema-form.js";
|
|
|
17
18
|
import { SlotField } from "./slot.js";
|
|
18
19
|
import { JsonControl } from "../controls/json.js";
|
|
19
20
|
import * as React from "react";
|
|
20
|
-
import { IconChevronRight } from "@tabler/icons-react";
|
|
21
21
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
22
|
-
|
|
22
|
+
import { IconChevronRight } from "@tabler/icons-react";
|
|
23
|
+
//#region src/engine/kit-field.tsx
|
|
23
24
|
/**
|
|
24
25
|
* KitField — renders ONE field of the schema at `path` (must be inside <SchemaForm>): the shell + the control for its
|
|
25
26
|
* type (V2 HEAD 9829bf1 kit/engine/kit-field.tsx).
|
|
@@ -37,11 +38,12 @@ var CONTROLS = {};
|
|
|
37
38
|
* the types in ACTION_WHEN_READ_ONLY, whose action takes `readOnly` and decides for itself (slug Generate).
|
|
38
39
|
*/
|
|
39
40
|
var ACTIONS = {};
|
|
40
|
-
var ACTION_WHEN_READ_ONLY = new Set(["slug"]);
|
|
41
|
+
var ACTION_WHEN_READ_ONLY = /* @__PURE__ */ new Set(["slug"]);
|
|
41
42
|
/** D58: the field for the lens: read-only (plain text) when it can't edit it. Hidden fields never reach here
|
|
42
43
|
* (SchemaForm drops them from the schema). */
|
|
43
44
|
function useFieldAccess(field) {
|
|
44
|
-
|
|
45
|
+
const env = useKitEnv();
|
|
46
|
+
return { readOnly: resolveFieldAccess(field, env).readOnly };
|
|
45
47
|
}
|
|
46
48
|
/** CPO D39: the field's help line — schema text first, then a line computed from its settings, then the house convention. */
|
|
47
49
|
function withDefaultHelp(field, isPublished, readOnly) {
|
|
@@ -50,7 +52,7 @@ function withDefaultHelp(field, isPublished, readOnly) {
|
|
|
50
52
|
...field,
|
|
51
53
|
description: field.lockReason.replace(/\.?$/, ".")
|
|
52
54
|
};
|
|
53
|
-
if (field.type === "slug" && isPublished
|
|
55
|
+
if (field.type === "slug" && !isPublished) computed = "Follows the title until you change it or publish.";
|
|
54
56
|
else if (field.type === "number" && !field.scale && field.layout !== "slider" && field.numeric?.unit) {
|
|
55
57
|
const { min, max, unit } = field.numeric;
|
|
56
58
|
computed = unit.startsWith("/") || max != null && unit.includes(String(max)) || min == null && max == null ? "" : min != null && max != null ? `Between ${min} and ${max} ${unit}.` : min != null ? `${min} ${unit} or more.` : `Up to ${max} ${unit}.`;
|
|
@@ -70,6 +72,36 @@ function KitField({ field, path, parent }) {
|
|
|
70
72
|
const id = React.useId();
|
|
71
73
|
const { readOnly } = useFieldAccess(field);
|
|
72
74
|
if (!form) return null;
|
|
75
|
+
const Custom = env.controls?.[pathKey(path)];
|
|
76
|
+
if (Custom) {
|
|
77
|
+
const ck = pathKey(path);
|
|
78
|
+
const cissue = form.visibleIssue(ck);
|
|
79
|
+
const cf = withDefaultHelp(field, env.isPublished, readOnly);
|
|
80
|
+
return /* @__PURE__ */ jsx(FieldShell, {
|
|
81
|
+
field: cf,
|
|
82
|
+
path,
|
|
83
|
+
id,
|
|
84
|
+
value: form.getAt(path),
|
|
85
|
+
onChange: (v) => form.setAt(path, v),
|
|
86
|
+
readOnly,
|
|
87
|
+
issue: cissue,
|
|
88
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
89
|
+
onBlur: () => form.touch(ck),
|
|
90
|
+
className: "min-w-0",
|
|
91
|
+
children: /* @__PURE__ */ jsx(Custom, {
|
|
92
|
+
field: cf,
|
|
93
|
+
value: form.getAt(path),
|
|
94
|
+
onChange: (v) => form.setAt(path, v),
|
|
95
|
+
id,
|
|
96
|
+
invalid: cissue?.level === "error",
|
|
97
|
+
readOnly,
|
|
98
|
+
path,
|
|
99
|
+
parent,
|
|
100
|
+
onBlur: () => form.touch(ck)
|
|
101
|
+
})
|
|
102
|
+
})
|
|
103
|
+
});
|
|
104
|
+
}
|
|
73
105
|
if (field.type === "array") return /* @__PURE__ */ jsx(ArrayField, {
|
|
74
106
|
field,
|
|
75
107
|
path,
|
|
@@ -93,6 +125,7 @@ function KitField({ field, path, parent }) {
|
|
|
93
125
|
const f = withDefaultHelp(field, env.isPublished, readOnly);
|
|
94
126
|
const plain = readOnly && PLAIN_TYPES.has(field.type);
|
|
95
127
|
const card = field.type === "boolean" && field.layout !== "checkbox";
|
|
128
|
+
const iconRow = isIconImage(field, value);
|
|
96
129
|
const expand = plain || Action ? null : expandSpecFor(field, {
|
|
97
130
|
readOnly,
|
|
98
131
|
hasKitControl: !!CONTROLS[field.type],
|
|
@@ -119,7 +152,7 @@ function KitField({ field, path, parent }) {
|
|
|
119
152
|
onChange,
|
|
120
153
|
readOnly,
|
|
121
154
|
issue,
|
|
122
|
-
layout: card ? "card" : "stack",
|
|
155
|
+
layout: card ? "card" : iconRow ? "row" : "stack",
|
|
123
156
|
action,
|
|
124
157
|
children: [plain ? card ? null : /* @__PURE__ */ jsx(PlainValue, {
|
|
125
158
|
field: f,
|
|
@@ -247,11 +280,13 @@ function ObjectField({ field, path }) {
|
|
|
247
280
|
children: control
|
|
248
281
|
});
|
|
249
282
|
if (mode === "inline") {
|
|
250
|
-
const
|
|
283
|
+
const cc = condCtx(form, path);
|
|
284
|
+
const visible = fields.filter((f) => !isHidden(f, obj, cc));
|
|
251
285
|
return shell(/* @__PURE__ */ jsx(FieldInset, {
|
|
252
286
|
label: field.title,
|
|
253
287
|
children: /* @__PURE__ */ jsx(FieldRun, {
|
|
254
288
|
fields: visible,
|
|
289
|
+
values: obj,
|
|
255
290
|
render: (f) => /* @__PURE__ */ jsx(KitField, {
|
|
256
291
|
field: f,
|
|
257
292
|
path: [...path, f.name],
|
|
@@ -387,7 +422,7 @@ function NestedForm({ fields, title, icon, path, navRef }) {
|
|
|
387
422
|
}
|
|
388
423
|
});
|
|
389
424
|
}
|
|
390
|
-
var PLAIN_TYPES = new Set([
|
|
425
|
+
var PLAIN_TYPES = /* @__PURE__ */ new Set([
|
|
391
426
|
"string",
|
|
392
427
|
"text",
|
|
393
428
|
"richtext",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kit-field.js","names":[],"sources":["../../src/engine/kit-field.tsx"],"sourcesContent":["/**\n * KitField — renders ONE field of the schema at `path` (must be inside <SchemaForm>): the shell + the control for its\n * type (V2 HEAD 9829bf1 kit/engine/kit-field.tsx).\n *\n * Arrays (array.tsx) and slots (slot.tsx) get their rows; objects open inline (FieldInset), drill (NavRow -> a frame),\n * popover or dialog (NestedForm: its own navigation stack). Primitive types dispatch through the CONTROLS table, which\n * the controls lanes fill. Every SchemaType has a control there; a type that is none of them (a schema newer than this\n * kit) edits its raw value in the JSON control (FallbackControl), never nothing and never a stand-in.\n */\nimport * as React from \"react\";\nimport type { ComponentType } from \"react\";\nimport { IconChevronRight } from \"@tabler/icons-react\";\nimport { KitIcon } from \"../lib/icons\";\nimport { cn } from \"../lib/cn\";\nimport type { FieldPath, FieldSchema, PrimitiveType, SchemaType } from \"../schema/types\";\nimport { resolveHelp } from \"../schema/help\";\nimport type { ControlProps } from \"../types\";\nimport { resolveFieldAccess, useForm, useKitEnv, useKitServices, type KitPeer } from \"../context\";\nimport { Button } from \"../ui/button\";\nimport { Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, Popover, PopoverContent, PopoverTrigger } from \"../ui/overlay\";\nimport { isObj, pathKey } from \"../lib/path\";\nimport { condCtx, isHidden, objectOpenMode, plainText, summarize } from \"../lib/schema\";\nimport { isIconImage } from \"../lib/icon-image\";\nimport { ArrayField, type NestedFormProps } from \"./array\";\nimport { ExpandAction, ExpandedField, expandKey, expandSpecFor, isExpandShortcut, openExpanded } from \"./expand\";\nimport { FieldShell } from \"./field-shell\";\nimport { FieldList } from \"./field-list\";\nimport { IssueDot, RowChrome } from \"./bits\";\nimport { FieldInset, FieldRun, groupSummary, useInsetDepth } from \"./grouping\";\nimport { SchemaForm } from \"./schema-form\";\nimport { SlotField } from \"./slot\";\nimport { JsonControl } from \"../controls/json\";\n\nexport interface KitFieldProps {\n field: FieldSchema;\n path: (string | number)[];\n parent?: Record<string, unknown>;\n}\n\n/** Type → control. Registered by the controls lane; a type with no entry edits its raw value (FallbackControl). */\nexport const CONTROLS: Partial<Record<SchemaType, ComponentType<ControlProps>>> = {};\n\n/**\n * Type → label-row action (DESIGN 4.4: slug Generate, rich text expand, table Edit in full screen), registered by the\n * controls lane next to its control. It gets the control's props. V2 draws it only while the field is editable, except\n * the types in ACTION_WHEN_READ_ONLY, whose action takes `readOnly` and decides for itself (slug Generate).\n */\nexport const ACTIONS: Partial<Record<SchemaType, ComponentType<ControlProps>>> = {};\nexport const ACTION_WHEN_READ_ONLY = new Set<SchemaType>([\"slug\"]);\n\n/** D58: the field for the lens: read-only (plain text) when it can't edit it. Hidden fields never reach here\n * (SchemaForm drops them from the schema). */\nexport function useFieldAccess(field: FieldSchema) {\n const env = useKitEnv();\n return { readOnly: resolveFieldAccess(field, env).readOnly };\n}\n\n/** CPO D39: the field's help line — schema text first, then a line computed from its settings, then the house convention. */\nexport function withDefaultHelp(field: FieldSchema, isPublished?: boolean, readOnly?: boolean): FieldSchema {\n let computed: string | undefined;\n /* a value set elsewhere says where, in one plain line (never a lock or a key) */\n if (readOnly && field.lockReason) return { ...field, description: field.lockReason.replace(/\\.?$/, \".\") };\n if (field.type === \"slug\" && !isPublished) computed = \"Follows the title until you change it or publish.\";\n else if (field.type === \"number\" && !field.scale && field.layout !== \"slider\" && field.numeric?.unit) {\n /* D63: the unit sits in the input (\"/ 5\", \"min\"), so a line that only restates it or its range is noise. A range\n still earns a line when the unit does not already say it (\"Between 1 and 12 items.\"). */\n const { min, max, unit } = field.numeric;\n const said = unit.startsWith(\"/\") || (max != null && unit.includes(String(max)));\n computed = said || (min == null && max == null) ? \"\" : min != null && max != null ? `Between ${min} and ${max} ${unit}.` : min != null ? `${min} ${unit} or more.` : `Up to ${max} ${unit}.`;\n } else if (field.type === \"number\" && !field.scale && field.layout !== \"slider\" && (field.numeric?.min != null || field.numeric?.max != null)) {\n const { min, max } = field.numeric ?? {};\n computed = min != null && max != null ? `Between ${min} and ${max}.` : min != null ? `${min} or more.` : `Up to ${max}.`;\n }\n /* resolve here so the computed line wins over the house convention; \"\" survives as \"deliberately none\" */\n const help = resolveHelp(field, computed) ?? \"\";\n return help === field.description ? field : { ...field, description: help };\n}\n\nexport function KitField({ field, path, parent }: KitFieldProps) {\n const form = useForm();\n const env = useKitEnv();\n const id = React.useId();\n const { readOnly } = useFieldAccess(field);\n if (!form) return null;\n\n /* a host's own control for this field (KitEnv.controls), inside the usual shell */\n const Custom = env.controls?.[pathKey(path)];\n if (Custom) {\n const ck = pathKey(path);\n const cissue = form.visibleIssue(ck);\n const cf = withDefaultHelp(field, env.isPublished, readOnly);\n return (\n <FieldShell field={cf} path={path} id={id} value={form.getAt(path)} onChange={(v) => form.setAt(path, v)} readOnly={readOnly} issue={cissue}>\n <div onBlur={() => form.touch(ck)} className=\"min-w-0\">\n <Custom field={cf} value={form.getAt(path)} onChange={(v) => form.setAt(path, v)} id={id} invalid={cissue?.level === \"error\"} readOnly={readOnly} path={path} parent={parent} onBlur={() => form.touch(ck)} />\n </div>\n </FieldShell>\n );\n }\n\n if (field.type === \"array\") return <ArrayField field={field} path={path} parent={parent} />;\n if (field.type === \"slot\") return <SlotField field={field} path={path} />;\n if (field.type === \"object\") return <ObjectField field={field} path={path} />;\n\n const key = pathKey(path);\n const value = form.getAt(path);\n const onChange = (v: unknown) => form.setAt(path, v);\n const onBlur = () => form.touch(key);\n const issue = form.visibleIssue(key);\n const Control = CONTROLS[field.type] ?? FallbackControl;\n const Action = ACTIONS[field.type];\n const f = withDefaultHelp(field, env.isPublished, readOnly);\n const plain = readOnly && PLAIN_TYPES.has(field.type as PrimitiveType);\n const card = field.type === \"boolean\" && field.layout !== \"checkbox\";\n /* an icon's row carries its own name (controls/media.tsx IconImageRow): no label above it as well */\n const iconRow = isIconImage(field, value);\n /* D49: rich text, code and tables open the shared expanded editor (expand.tsx). A lane that registers its\n own ACTIONS[type] owns its expansion too (rich text's editor modal, the table's spreadsheet): the engine draws no\n second modal and binds no second ⌘↵ for it. */\n const expand = plain || Action ? null : expandSpecFor(field, { readOnly, hasKitControl: !!CONTROLS[field.type], variant: env.variant });\n const action =\n Action && (!readOnly || ACTION_WHEN_READ_ONLY.has(field.type)) ? (\n <Action field={f} value={value} onChange={onChange} id={id} readOnly={readOnly} path={path} parent={parent} />\n ) : expand ? (\n <ExpandAction field={f} path={path} spec={expand} />\n ) : undefined;\n return (\n <FieldShell field={f} path={path} id={id} value={value} onChange={onChange} readOnly={readOnly} issue={issue} layout={card ? \"card\" : iconRow ? \"row\" : \"stack\"} action={action}>\n {plain ? (\n card ? null /* the switch card already reads On / Off */ : <PlainValue field={f} value={value} id={id} />\n ) : (\n <div\n onBlur={onBlur}\n onKeyDown={\n expand\n ? (e) => {\n if (!isExpandShortcut(e)) return;\n e.preventDefault();\n openExpanded(expandKey(env.docId, path));\n }\n : undefined\n }\n className=\"min-w-0\"\n >\n <Control field={f} value={value} onChange={onChange} id={id} invalid={issue?.level === \"error\"} readOnly={readOnly} path={path} parent={parent} onBlur={onBlur} />\n </div>\n )}\n {expand ? (\n <ExpandedField field={f} path={path} spec={expand} Control={Control} value={value} onChange={onChange} onBlur={onBlur} invalid={issue?.level === \"error\"} id={id} parent={parent} />\n ) : null}\n </FieldShell>\n );\n}\n\n/**\n * A row that opens something (V2 NavRow): type tile, title over a summary line, the field's chrome (from RowChrome),\n * the issue rollup and a chevron.\n * Like V2 it always draws its button and chevron, also with no `onClick` (a popover trigger around it opens on the\n * click). Only `inert` (the form draws no frames, so nothing can open) leaves both out.\n */\nexport function NavRow({\n icon,\n title,\n subtitle,\n path,\n onClick,\n inert,\n className,\n trailing,\n}: {\n icon?: string;\n title: string;\n subtitle?: string;\n path?: FieldPath;\n onClick?: () => void;\n inert?: boolean;\n className?: string;\n trailing?: React.ReactNode;\n}) {\n const form = useForm();\n const roll = path && form ? form.rollup(path) : { errors: 0, warnings: 0 };\n const subId = React.useId();\n const chrome = React.useContext(RowChrome);\n const text = (\n <>\n <span className=\"block truncate text-kit-sm text-kit-fg\">{title}</span>\n <span id={subId} className=\"block truncate text-kit-xs text-kit-fg-3\">\n {subtitle || \"Nothing set yet\"}\n </span>\n </>\n );\n return (\n <div\n className={cn(\n \"group/nav relative flex min-h-11 w-full min-w-0 items-center gap-2.5 rounded-kit-lg border border-kit-line bg-kit-control-bg py-1.5 pl-2 pr-2 text-left transition-colors hover:border-kit-line-strong hover:bg-kit-subtle\",\n className,\n )}\n >\n <span className=\"flex size-7 shrink-0 items-center justify-center rounded-kit-md bg-kit-muted text-kit-fg-2\">\n <KitIcon name={icon} fallback=\"folder\" className=\"size-4\" />\n </span>\n {!inert ? (\n <button\n type=\"button\"\n data-nav-main\n onClick={onClick}\n aria-label={`Open ${title}${roll.errors ? `, ${roll.errors} ${roll.errors === 1 ? \"issue\" : \"issues\"}` : \"\"}`}\n aria-describedby={subId}\n className=\"min-w-0 flex-1 text-left outline-none after:absolute after:inset-0 after:rounded-kit-lg after:content-[''] focus-visible:after:outline-2 focus-visible:after:outline-offset-2 focus-visible:after:outline-kit-focus-ring focus-visible:after:[outline-style:solid] [html[data-input-modality=pointer]_&]:focus-visible:after:outline-none\"\n >\n {text}\n </button>\n ) : (\n <div data-nav-main className=\"min-w-0 flex-1 text-left\">\n {text}\n </div>\n )}\n <IssueDot errors={roll.errors} warnings={roll.warnings} className=\"relative\" />\n {chrome ? <span className=\"relative z-[1] flex shrink-0 items-center gap-0.5 empty:hidden\">{chrome}</span> : null}\n {trailing}\n {!inert ? <IconChevronRight aria-hidden className=\"pointer-events-none size-4 shrink-0 text-kit-fg-3 transition-transform group-hover/nav:translate-x-0.5\" stroke={1.5} /> : null}\n </div>\n );\n}\n\n/* ── Object: inline · drill · popover · dialog (V2 ObjectField) ───── */\n\nfunction ObjectField({ field, path }: { field: FieldSchema; path: FieldPath }) {\n const form = useForm()!;\n const id = React.useId();\n const { readOnly } = useFieldAccess(field);\n const depth = useInsetDepth();\n const value = form.getAt(path);\n const obj = isObj(value) ? value : {};\n const fields = field.fields ?? [];\n /* D45 nesting rule: one container per level. Inside an inset (or an expanded row) an \"inline\" object would be a box in a\n box, so it drills instead — level 3+ is always a new frame, never more indentation. */\n const wanted = objectOpenMode(field);\n const mode = wanted === \"inline\" && depth > 0 ? \"drill\" : wanted;\n const [open, setOpen] = React.useState(false);\n const sum = groupSummary(fields, obj) || summarize(fields, obj);\n const nav = React.useRef<{ back: () => boolean }>(null);\n const shell = (control: React.ReactNode, layout?: \"row\") => (\n <FieldShell field={field} path={path} id={id} value={value} onChange={(v) => form.setAt(path, v)} readOnly={readOnly} issue={form.visibleIssue(pathKey(path))} layout={layout}>\n {control}\n </FieldShell>\n );\n if (mode === \"inline\") {\n const cc = condCtx(form, path);\n const visible = fields.filter((f) => !isHidden(f, obj, cc));\n /* D63: label, then the children behind one inset line; short neighbours pair up only on a wide form */\n return shell(\n <FieldInset label={field.title}>\n <FieldRun fields={visible} values={obj} render={(f) => <KitField field={f} path={[...path, f.name]} parent={obj} />} />\n </FieldInset>,\n );\n }\n const help = resolveHelp(field) ?? \"\";\n if (mode === \"popover\")\n /* V2: Radix <PopoverTrigger asChild><div> — the whole row is the trigger (aria-expanded, aria-haspopup=\"dialog\");\n NavRow gets no onClick but still draws its button (\"Open <title>\") and chevron, whose click opens the popover. */\n return shell(\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger nativeButton={false} render={<div />}>\n <NavRow icon={field.icon} title={field.title} subtitle={sum || help} path={path} />\n </PopoverTrigger>\n <PopoverContent className=\"w-[340px] p-3\" align=\"start\">\n <FieldList fields={fields} basePath={path} memoryKey={`pop:${pathKey(path)}`} />\n </PopoverContent>\n </Popover>,\n \"row\",\n );\n if (mode === \"dialog\")\n return shell(\n <>\n <NavRow icon={field.icon} title={field.title} subtitle={sum || help} path={path} onClick={() => setOpen(true)} />\n <Modal\n open={open}\n onOpenChange={(o, d) => {\n // Escape steps back inside the dialog's own frames first (V2: onEscapeKeyDown + nav.back())\n if (!o && d.reason === \"escape-key\" && nav.current?.back()) return d.cancel();\n setOpen(o);\n }}\n >\n <ModalContent size=\"lg\">\n <ModalHeader title={field.title} description={field.description} icon={<KitIcon name={field.icon} fallback=\"folder\" />} />\n <ModalBody className=\"flex min-h-[320px] flex-col gap-5\">\n <NestedForm fields={fields} title={field.title} icon={field.icon} path={path} navRef={nav} />\n </ModalBody>\n <ModalFooter>\n <span className=\"mr-auto text-kit-xs text-kit-fg-3\">Changes save as you type</span>\n <Button variant=\"primary\" onClick={() => setOpen(false)}>\n Done\n </Button>\n </ModalFooter>\n </ModalContent>\n </Modal>\n </>,\n \"row\",\n );\n return shell(<NavRow icon={field.icon} title={field.title} subtitle={sum || help} path={path} onClick={() => form.navigate(path)} inert={!form.canNavigate} />, \"row\");\n}\n\n/**\n * A dialog gets its OWN navigation stack: lists inside it drill inside the dialog (breadcrumb, Esc, stepper), never the\n * panel behind. Writes go straight into the parent form at `path`.\n */\nexport function NestedForm({ fields, title, icon, path, navRef }: NestedFormProps) {\n const form = useForm()!;\n const env = useKitEnv();\n const key = pathKey(path);\n const schema = React.useMemo(() => ({ name: key || \"nested\", title, icon, kind: \"object\" as const, fields }), [key, title, icon, fields]);\n const raw = form.getAt(path);\n const pub = form.hasPublished ? form.publishedAt(path) : undefined;\n const presence = React.useMemo(() => {\n const out: Record<string, KitPeer[]> = {};\n for (const [k, v] of Object.entries(env.presence)) if (k.startsWith(`${key}.`)) out[k.slice(key.length + 1)] = v;\n return out;\n }, [env.presence, key]);\n return (\n <SchemaForm\n schema={schema}\n value={isObj(raw) ? raw : {}}\n onChange={(v) => form.setAt(path, v)}\n variant=\"document\"\n scroll={false}\n navRef={navRef}\n resolveSchema={form.resolveSchema}\n blockLibrary={form.blockLibrary}\n published={isObj(pub) ? pub : undefined}\n presence={presence}\n readOnly={env.readOnly}\n showErrors={form.showAllErrors}\n onOpenReference={env.onOpenReference}\n env={{ docId: `${env.docId}:${key}`, docTitle: env.docTitle, urlPrefix: env.urlPrefix, isPublished: env.isPublished, palette: env.palette, helpDisplay: env.helpDisplay }}\n />\n );\n}\n\n/* ── Read-only as plain text (D58 §0): no greyed input, just the value ── */\nconst PLAIN_TYPES = new Set<PrimitiveType>([\"string\", \"text\", \"richtext\", \"number\", \"slug\", \"url\", \"email\", \"date\", \"datetime\", \"select\", \"multiselect\", \"tags\", \"boolean\", \"rating\"]);\nexport function plainOf(field: FieldSchema, value: unknown): string {\n if (value == null || value === \"\") return \"\";\n const label = (v: unknown) => field.options?.find((o) => o.value === v)?.label ?? String(v);\n if (field.type === \"boolean\") return value ? \"On\" : \"Off\";\n if (field.type === \"select\") return label(value);\n // before the list arm: stored rich text may be a Portable Text block array\n if (field.type === \"richtext\") return plainText(value);\n if (Array.isArray(value)) return value.map(label).join(\", \");\n if (field.type === \"date\" || field.type === \"datetime\") {\n const d = new Date(String(value).replace(/\\[.*\\]$/, \"\"));\n return Number.isNaN(+d) ? String(value) : d.toLocaleString(\"en-US\", field.type === \"date\" ? { month: \"short\", day: \"numeric\", year: \"numeric\" } : { month: \"short\", day: \"numeric\", year: \"numeric\", hour: \"numeric\", minute: \"2-digit\" });\n }\n if (field.type === \"number\" && isObj(value)) return String((value as { value?: unknown }).value ?? \"\");\n return typeof value === \"object\" ? \"\" : String(value);\n}\nfunction PlainValue({ field, value, id }: { field: FieldSchema; value: unknown; id: string }) {\n const text = plainOf(field, value);\n return (\n <p id={id} tabIndex={0} data-slot=\"kit-plain\" className={cn(\"min-w-0 whitespace-pre-wrap break-words text-kit-sm leading-6 text-kit-fg outline-none\", (field.type === \"slug\" || field.type === \"url\") && \"font-kit-mono text-kit-xs leading-6\")}>\n {text || <span className=\"text-kit-fg-3\">Empty</span>}\n </p>\n );\n}\n\n/* ── Unknown type: the raw value, in the JSON control ── */\n/**\n * Every SchemaType has a kit control (kit-field.test checks CONTROLS against the type list in schema/types.ts). A field\n * whose type is none of them edits its raw stored value in the JSON control, tagged `data-kit-fallback=\"<type>\"`: the\n * value is shown and kept, and an edit is written only once it parses.\n */\nexport function FallbackControl(props: ControlProps) {\n return (\n <div data-kit-fallback={props.field.type} className=\"min-w-0\">\n <JsonControl {...props} />\n </div>\n );\n}\n\n/* ── Hand-off: the host's own control for a value the kit refuses ── */\n/**\n * A control that cannot carry a stored value unchanged (rich text holding formatting its editor would drop) hands that\n * value to the host's control for the type (KitServices.LegacyControl: the dashboard's FieldRenderer arm), bare inside\n * the kit FieldShell, which owns the label and the help; the control names its reason above it. The box carries\n * `data-kit-legacy=\"<type>\"`, so the parity harness counts it (mismatch class `legacy-control`). A host with no legacy\n * service, or a control that throws while rendering, says why in words; the form around it keeps working.\n */\nexport function LegacyFallback(props: ControlProps) {\n const { LegacyControl } = useKitServices();\n const { field, id } = props;\n return (\n <div data-kit-legacy={field.type} className=\"min-w-0\">\n {LegacyControl ? (\n // keyed by the schema's content: a schema edit remounts the control (KitField hands over a fresh field object on\n // every render, so identity would remount on every keystroke). A value change retries in place (componentDidUpdate).\n <LegacyBoundary key={JSON.stringify(field)} field={field} id={id} value={props.value}>\n <LegacyControl {...props} />\n </LegacyBoundary>\n ) : (\n <LegacyRefusal id={id}>This view has no control for {field.type} fields.</LegacyRefusal>\n )}\n </div>\n );\n}\n\n/**\n * An `<output>`: a labelable element, so the FieldShell label's `for` lands on it, and focusable, so a keyboard user\n * reaches the reason. The neutral focus ring shows under keyboard modality only.\n */\nfunction LegacyRefusal({ id, children }: { id: string; children: React.ReactNode }) {\n return (\n <output\n id={id}\n role=\"note\"\n tabIndex={0}\n data-slot=\"kit-legacy-refusal\"\n className=\"block rounded-kit-sm text-kit-xs text-kit-fg-3 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-kit-focus-ring focus-visible:[outline-style:solid] [html[data-input-modality=pointer]_&]:focus-visible:outline-0\"\n >\n {children}\n </output>\n );\n}\n\n/** Retries the control once its field or value changes (a schema edit, a save from elsewhere, an undo). */\nclass LegacyBoundary extends React.Component<{ field: FieldSchema; id: string; value: unknown; children: React.ReactNode }, { reason: string | null }> {\n state = { reason: null as string | null };\n static getDerivedStateFromError(error: unknown) {\n return { reason: error instanceof Error ? error.message : String(error) };\n }\n componentDidUpdate(prev: { field: FieldSchema; value: unknown }) {\n if (this.state.reason === null) return;\n // by content: KitField hands over a fresh field object (withDefaultHelp) on every render\n if (prev.value !== this.props.value || JSON.stringify(prev.field) !== JSON.stringify(this.props.field)) this.setState({ reason: null });\n }\n render() {\n if (this.state.reason === null) return this.props.children;\n return (\n <LegacyRefusal id={this.props.id}>\n The {this.props.field.title} control could not load: {this.state.reason}\n </LegacyRefusal>\n );\n }\n}\n"],"mappings":"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"}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* dark host scope is never reset to light inside it.
|
|
14
14
|
*/
|
|
15
15
|
import * as React from "react";
|
|
16
|
-
import type { FieldPath, TypeSchema } from "../schema/types";
|
|
16
|
+
import type { FieldPath, FieldSchema, TypeSchema } from "../schema/types";
|
|
17
17
|
import { type KitEnv, type KitPeer, type Swatch } from "../context";
|
|
18
18
|
import { type KitIssue } from "../lib/validate";
|
|
19
19
|
import { type KitCrumb } from "./breadcrumb";
|
|
@@ -50,6 +50,8 @@ export interface SchemaFormProps {
|
|
|
50
50
|
onComment?: KitEnv["onComment"];
|
|
51
51
|
/** "Open {title}" on a reference: the host opens the referenced entry (e.g. a stacked panel) */
|
|
52
52
|
onOpenReference?: KitEnv["onOpenReference"];
|
|
53
|
+
/** D61: the host's Review changes markers (while its History panel is open) */
|
|
54
|
+
review?: KitEnv["review"];
|
|
53
55
|
/** the whole form is read-only for the lens (fields with their own `access.edit` still follow `env.can`) */
|
|
54
56
|
readOnly?: boolean;
|
|
55
57
|
/** validate everything now (after a publish attempt) */
|
|
@@ -60,13 +62,35 @@ export interface SchemaFormProps {
|
|
|
60
62
|
docTitle?: string;
|
|
61
63
|
urlPrefix?: string;
|
|
62
64
|
isPublished?: boolean;
|
|
65
|
+
/** the slug is the document's address (KitEnv.slugIsAddress) */
|
|
66
|
+
slugIsAddress?: boolean;
|
|
63
67
|
palette?: Swatch[];
|
|
64
68
|
syncedFrom?: string;
|
|
65
69
|
/** D58: the host's access check (`useCan` at the host). Omitted → allow-all (staff tools, demos). */
|
|
66
70
|
can?: KitEnv["can"];
|
|
67
71
|
/** CPO D39: "tooltip" moves help lines behind the ⓘ (dense hosts) */
|
|
68
72
|
helpDisplay?: KitEnv["helpDisplay"];
|
|
73
|
+
/** "quiet" field chrome for meta-forms (see `KitEnv.fieldChrome`) */
|
|
74
|
+
fieldChrome?: KitEnv["fieldChrome"];
|
|
75
|
+
/** the host's own controls by path key (see `KitEnv.controls`); keep it stable */
|
|
76
|
+
controls?: KitEnv["controls"];
|
|
77
|
+
/** the host's chip summary for collapsed fieldsets (see `KitEnv.sectionSummary`); keep it stable */
|
|
78
|
+
sectionSummary?: KitEnv["sectionSummary"];
|
|
69
79
|
};
|
|
80
|
+
/**
|
|
81
|
+
* Issues the host computes itself (a live check the schema can't express), merged with the form's own. A host issue on a
|
|
82
|
+
* path the form already flags is dropped; `live` ones show while typing; `fix` adds one action after the message.
|
|
83
|
+
*/
|
|
84
|
+
extraIssues?: KitIssue[];
|
|
85
|
+
/** The host's access check (V2 `KitEnv.can`), the same as `env.can`; `env.can` wins when both are set. */
|
|
86
|
+
can?: KitEnv["can"];
|
|
87
|
+
/**
|
|
88
|
+
* D70 (V2 `KitEnv.hiddenLine`): keep the fields that would leave the form in place as the host's line instead. `why`
|
|
89
|
+
* says what hid it: "rule" (its condition doesn't hold for the current value) or "access" (the lens can't `view` it).
|
|
90
|
+
* The schema preview draws its dashed "Hidden for Editor" / "Hidden: …" lines with it. Absent: hidden fields leave the
|
|
91
|
+
* form, as in every editor. Keep it stable (a new function re-renders the form).
|
|
92
|
+
*/
|
|
93
|
+
hiddenLine?: (field: FieldSchema, path: FieldPath, why: HiddenWhy) => React.ReactNode;
|
|
70
94
|
/** own scroll container (default: panel yes, document no) */
|
|
71
95
|
scroll?: boolean;
|
|
72
96
|
/** rendered above the breadcrumb (e.g. a block header) */
|
|
@@ -88,4 +112,5 @@ export interface SchemaFormProps {
|
|
|
88
112
|
}
|
|
89
113
|
export declare const COALESCE_MS = 900;
|
|
90
114
|
export declare const UNDO_STEPS = 50;
|
|
91
|
-
export
|
|
115
|
+
export type HiddenWhy = "rule" | "access";
|
|
116
|
+
export declare function SchemaForm({ schema: schemaIn, value, onChange, path: controlledPath, defaultPath, onPathChange, variant, resolveSchema: resolveIn, blockLibrary, published, inherited, presence, comments, onComment, onOpenReference, review, readOnly, showErrors, env: envIn, scroll, header, rootLabel, onCrumbs, onIssuesChange, navRef, className, can: canIn, hiddenLine, extraIssues, }: SchemaFormProps): import("react/jsx-runtime").JSX.Element;
|