@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,19 @@
|
|
|
1
|
+
import { cropPreset, cropRect, isCropRect } from "../adapters/values.js";
|
|
1
2
|
import { cn } from "../lib/cn.js";
|
|
2
|
-
import { isObj } from "../lib/path.js";
|
|
3
3
|
import { useKitEnv, useKitServices } from "../context.js";
|
|
4
|
-
import {
|
|
4
|
+
import { isObj } from "../lib/path.js";
|
|
5
|
+
import { Button, IconButton } from "../ui/button.js";
|
|
5
6
|
import { Progress } from "../ui/controls.js";
|
|
6
7
|
import { Menu, MenuContent, MenuItem, MenuSeparator, MenuTrigger, Popover, PopoverAnchor, PopoverContent, Tooltip } from "../ui/overlay.js";
|
|
8
|
+
import { RowChrome } from "../engine/bits.js";
|
|
9
|
+
import { isIconImage } from "../lib/icon-image.js";
|
|
7
10
|
import { Input, Textarea } from "../ui/input.js";
|
|
11
|
+
import { Select } from "../ui/select.js";
|
|
8
12
|
import { useDragReorder } from "../engine/item-list.js";
|
|
9
13
|
import * as React from "react";
|
|
10
|
-
import { IconAlertTriangle, IconDots, IconDownload, IconExternalLink, IconFileText, IconFocusCentered, IconLink, IconPhoto, IconPlayerPlay, IconPlus, IconReplace, IconTrash, IconUpload, IconVideo, IconWorld, IconX } from "@tabler/icons-react";
|
|
11
14
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
12
|
-
|
|
15
|
+
import { IconAlertTriangle, IconCrop, IconDots, IconDownload, IconExternalLink, IconFileText, IconFocusCentered, IconLink, IconPhoto, IconPlayerPlay, IconPlus, IconRefresh, IconReplace, IconTrash, IconUpload, IconVideo, IconWorld, IconX } from "@tabler/icons-react";
|
|
16
|
+
//#region src/controls/media.tsx
|
|
13
17
|
/**
|
|
14
18
|
* MEDIA — image · gallery · file · video (V2 HEAD 9829bf1 kit/controls/media.tsx, DESIGN.md 8.15).
|
|
15
19
|
*
|
|
@@ -19,8 +23,9 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
19
23
|
* (media-services.ts): the kit never imports a feature, and a missing service is named in words, never faked.
|
|
20
24
|
*
|
|
21
25
|
* Kit deviations from V2, each because of what the backend stores (adapters/values.ts):
|
|
22
|
-
* -
|
|
23
|
-
* the
|
|
26
|
+
* - "Crop for this placement" is V2's five-crop dropdown, stored as the rect prod keeps (cut from the picture's own size,
|
|
27
|
+
* centred on the focal point); a stored rect reads back as its preset when the size is known, and is kept as it is
|
|
28
|
+
* otherwise. With no size yet, the dropdown waits, and says why;
|
|
24
29
|
* - a picked asset's width / height / size are read for the caption, never written into the value (prod rebuilds the
|
|
25
30
|
* value from url, id, name, altText and focal; the rest would be refused);
|
|
26
31
|
* - where the host stores the URL string only (`imageStoresUrl`, the dock's top-level image props) the value stays a
|
|
@@ -31,11 +36,15 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
31
36
|
* refuses a half-typed address.
|
|
32
37
|
*/
|
|
33
38
|
var fileNameFromUrl = (url) => {
|
|
34
|
-
const
|
|
39
|
+
const inline = /^data:image\/([a-z0-9.+-]+)/i.exec(url.trim());
|
|
40
|
+
if (inline) return `Embedded ${inline[1].replace(/\+xml$/i, "").replace(/^jpeg$/i, "jpg").toUpperCase()} image`;
|
|
35
41
|
try {
|
|
36
|
-
|
|
42
|
+
const u = new URL(url, typeof window === "undefined" ? "https://x.invalid" : window.location.href);
|
|
43
|
+
if (u.protocol === "data:" || u.protocol === "blob:") return "Image";
|
|
44
|
+
const file = u.pathname.split("/").filter(Boolean).reverse().find((x) => /\.[a-z0-9]{2,5}$/i.test(x));
|
|
45
|
+
return file ? decodeURIComponent(file) : `Image from ${u.hostname.replace(/^www\./, "")}`;
|
|
37
46
|
} catch {
|
|
38
|
-
return
|
|
47
|
+
return "Image";
|
|
39
48
|
}
|
|
40
49
|
};
|
|
41
50
|
var normImage = (v) => {
|
|
@@ -44,10 +53,10 @@ var normImage = (v) => {
|
|
|
44
53
|
};
|
|
45
54
|
/** What an asset becomes in a value: the keys prod keeps (url, id, name, alt), nothing measured. */
|
|
46
55
|
var fromAsset = (a) => {
|
|
47
|
-
const out = {
|
|
56
|
+
const out = a.id ? {
|
|
48
57
|
url: a.url,
|
|
49
58
|
id: a.id
|
|
50
|
-
};
|
|
59
|
+
} : { url: a.url };
|
|
51
60
|
if (a.name) out.name = a.name;
|
|
52
61
|
if (a.alt) out.alt = a.alt;
|
|
53
62
|
return out;
|
|
@@ -57,6 +66,7 @@ var HTTP = /^https?:\/\/\S+$/i;
|
|
|
57
66
|
/** An http(s) URL or a site path: what prod's video value takes (video-value.ts isVideoUrl). */
|
|
58
67
|
var isVideoUrl = (s) => s === "" || HTTP.test(s.trim()) || /^\/(?!\/)\S*$/.test(s.trim());
|
|
59
68
|
var NO_ASSET = () => void 0;
|
|
69
|
+
var NO_ICONS = () => [];
|
|
60
70
|
var NO_SRC = (u) => u;
|
|
61
71
|
/** The services the media controls read, each hook stable across renders. */
|
|
62
72
|
function useMedia() {
|
|
@@ -183,8 +193,8 @@ function DropWell({ id, title, hint, accept, multiple, icon, disabled, onFiles,
|
|
|
183
193
|
className: "text-kit-xs text-kit-fg-3",
|
|
184
194
|
children: hint
|
|
185
195
|
}) : null] }),
|
|
186
|
-
urlMode && onUrl ? /* @__PURE__ */ jsxs("form", {
|
|
187
|
-
className: "flex w-full max-w-sm
|
|
196
|
+
urlMode && onUrl ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("form", {
|
|
197
|
+
className: "flex w-full max-w-sm items-center gap-1.5",
|
|
188
198
|
onSubmit: (e) => {
|
|
189
199
|
e.preventDefault();
|
|
190
200
|
e.stopPropagation();
|
|
@@ -203,26 +213,22 @@ function DropWell({ id, title, hint, accept, multiple, icon, disabled, onFiles,
|
|
|
203
213
|
setUrlError(null);
|
|
204
214
|
}
|
|
205
215
|
},
|
|
206
|
-
children: [/* @__PURE__ */
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
children: "Add"
|
|
223
|
-
})]
|
|
224
|
-
}), urlError ? /* @__PURE__ */ jsx(Reason, { children: urlError }) : null]
|
|
225
|
-
}) : /* @__PURE__ */ jsxs("div", {
|
|
216
|
+
children: [/* @__PURE__ */ jsx(Input, {
|
|
217
|
+
autoFocus: true,
|
|
218
|
+
size: "sm",
|
|
219
|
+
value: url,
|
|
220
|
+
"aria-label": "Image URL",
|
|
221
|
+
"aria-invalid": urlError ? true : void 0,
|
|
222
|
+
onChange: (e) => setUrl(e.target.value),
|
|
223
|
+
placeholder: "https://…/photo.jpg",
|
|
224
|
+
leading: /* @__PURE__ */ jsx(IconLink, { stroke: 1.5 })
|
|
225
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
226
|
+
size: "sm",
|
|
227
|
+
type: "submit",
|
|
228
|
+
variant: "primary",
|
|
229
|
+
children: "Add"
|
|
230
|
+
})]
|
|
231
|
+
}), urlError ? /* @__PURE__ */ jsx(Reason, { children: urlError }) : null] }) : /* @__PURE__ */ jsxs("div", {
|
|
226
232
|
className: "flex flex-wrap justify-center gap-1.5",
|
|
227
233
|
children: [
|
|
228
234
|
onLibrary || refuse ? /* @__PURE__ */ jsx(Button, {
|
|
@@ -289,19 +295,114 @@ function DropWell({ id, title, hint, accept, multiple, icon, disabled, onFiles,
|
|
|
289
295
|
var NO_SOURCE = "No media library or upload is connected to this editor, so nothing can be chosen here.";
|
|
290
296
|
var NO_LIBRARY = "No media library is connected to this editor, so nothing can be picked from it here.";
|
|
291
297
|
var NO_UPLOAD = "No upload is connected to this editor, so files can't be uploaded here.";
|
|
292
|
-
|
|
298
|
+
/** Transparency checker on the kit tokens (white in light, dimmed in dark), as the media grid draws it. */
|
|
299
|
+
var CHECKER = "bg-kit-checker-a [background-image:conic-gradient(var(--kit-checker-b)_25%,var(--kit-checker-a)_0_50%,var(--kit-checker-b)_0_75%,var(--kit-checker-a)_0)] [background-size:12px_12px]";
|
|
300
|
+
/** The preview frame's shape bounds: a tall or panoramic picture never makes the dock tall or a sliver. */
|
|
301
|
+
var FRAME_MIN = 1;
|
|
302
|
+
var FRAME_MAX = 2;
|
|
303
|
+
/**
|
|
304
|
+
* How a preview frames a picture of any shape: the frame follows the picture's ratio between square and 2:1, and the
|
|
305
|
+
* picture fits inside it WHOLE, filling the frame's width or height (a portrait is boxed at the sides, a panorama above
|
|
306
|
+
* and below, on the checker). With no known size (still loading, or an SVG with no intrinsic size) the frame is 16:9
|
|
307
|
+
* and the picture is contained. Before 2026-10-16 every picture was cropped to a fixed 16:9 (`object-cover`).
|
|
308
|
+
*/
|
|
309
|
+
function frameFit(size) {
|
|
310
|
+
if (!size || !(size.w > 0) || !(size.h > 0)) return {
|
|
311
|
+
frame: 16 / 9,
|
|
312
|
+
image: null,
|
|
313
|
+
fill: "contain"
|
|
314
|
+
};
|
|
315
|
+
const image = size.w / size.h;
|
|
316
|
+
const frame = Math.min(FRAME_MAX, Math.max(FRAME_MIN, image));
|
|
317
|
+
return {
|
|
318
|
+
frame,
|
|
319
|
+
image,
|
|
320
|
+
fill: image < frame ? "height" : "width"
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
/** The picture's classes for a fit: it keeps its own ratio and the frame's width or height, never cut. */
|
|
324
|
+
var FIT_CLASS = {
|
|
325
|
+
width: "h-auto max-h-full w-full object-contain",
|
|
326
|
+
height: "h-full w-auto max-w-full object-contain",
|
|
327
|
+
contain: "size-full object-contain"
|
|
328
|
+
};
|
|
329
|
+
/** V2's five crops (kit media.tsx CROPS, D46). */
|
|
330
|
+
var CROPS = [
|
|
331
|
+
{
|
|
332
|
+
value: "original",
|
|
333
|
+
label: "Original",
|
|
334
|
+
ratio: "auto",
|
|
335
|
+
description: "Keep the uploaded shape"
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
value: "16:9",
|
|
339
|
+
label: "16:9",
|
|
340
|
+
ratio: "16/9",
|
|
341
|
+
description: "Widescreen"
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
value: "4:3",
|
|
345
|
+
label: "4:3",
|
|
346
|
+
ratio: "4/3",
|
|
347
|
+
description: "Landscape"
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
value: "1:1",
|
|
351
|
+
label: "1:1",
|
|
352
|
+
ratio: "1/1",
|
|
353
|
+
description: "Square"
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
value: "4:5",
|
|
357
|
+
label: "4:5",
|
|
358
|
+
ratio: "4/5",
|
|
359
|
+
description: "Portrait"
|
|
360
|
+
}
|
|
361
|
+
];
|
|
362
|
+
var CUSTOM_CROP = "custom";
|
|
363
|
+
/** The crop a value shows: its preset, a stored rect read against the picture's size, or a rect that is none of them. */
|
|
364
|
+
function cropChoice(crop, size) {
|
|
365
|
+
if (!crop) return "original";
|
|
366
|
+
if (typeof crop === "string") return crop;
|
|
367
|
+
if (!isCropRect(crop)) return "original";
|
|
368
|
+
return size && cropPreset(crop, size.w, size.h) || CUSTOM_CROP;
|
|
369
|
+
}
|
|
370
|
+
/** A custom rect's own shape (its fractions of the picture, in pixels), when the picture's size is known. */
|
|
371
|
+
function customRatio(crop, size) {
|
|
372
|
+
if (!size || !crop || typeof crop === "string" || !isCropRect(crop)) return void 0;
|
|
373
|
+
const w = (1 - crop.left - crop.right) * size.w;
|
|
374
|
+
const h = (1 - crop.top - crop.bottom) * size.h;
|
|
375
|
+
return w > 0 && h > 0 ? String(w / h) : void 0;
|
|
376
|
+
}
|
|
377
|
+
/** The value with `choice` cut from the picture (centred on its focal point), or with no crop for Original. */
|
|
378
|
+
function withCrop(v, choice, size) {
|
|
379
|
+
const next = { ...v };
|
|
380
|
+
delete next.crop;
|
|
381
|
+
const rect = choice === "original" ? void 0 : cropRect(choice, size.w, size.h, v.focal);
|
|
382
|
+
if (rect) next.crop = rect;
|
|
383
|
+
return next;
|
|
384
|
+
}
|
|
385
|
+
function ImageDetails({ v, onChange, readOnly, label, urlOnly, altOnly = false, size, asset }) {
|
|
293
386
|
const { src } = useMedia();
|
|
294
387
|
const focal = v.focal ?? {
|
|
295
388
|
x: 50,
|
|
296
389
|
y: 50
|
|
297
390
|
};
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
391
|
+
const choice = cropChoice(v.crop, size);
|
|
392
|
+
const crop = CROPS.find((c) => c.value === choice);
|
|
393
|
+
const own = choice === "original" && size ? frameFit(size) : null;
|
|
394
|
+
const pad = own?.image ? own : null;
|
|
395
|
+
const padRatio = crop && crop.ratio !== "auto" ? crop.ratio : pad ? String(pad.image) : customRatio(v.crop, size) ?? "3/2";
|
|
396
|
+
const setFocal = (x, y) => {
|
|
397
|
+
const next = {
|
|
398
|
+
...v,
|
|
399
|
+
focal: {
|
|
400
|
+
x: Math.round(Math.min(100, Math.max(0, x))),
|
|
401
|
+
y: Math.round(Math.min(100, Math.max(0, y)))
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
onChange(crop && crop.value !== "original" && size ? withCrop(next, crop.value, size) : next);
|
|
405
|
+
};
|
|
305
406
|
const fromPointer = (e) => {
|
|
306
407
|
const r = e.currentTarget.getBoundingClientRect();
|
|
307
408
|
if (!r.width || !r.height) return;
|
|
@@ -356,21 +457,29 @@ function ImageDetails({ v, onChange, readOnly, label, urlOnly, size, asset }) {
|
|
|
356
457
|
className: "min-h-14 text-kit-sm",
|
|
357
458
|
"aria-label": `${label} alt text`
|
|
358
459
|
})]
|
|
359
|
-
}), /* @__PURE__ */
|
|
460
|
+
}), altOnly ? /* @__PURE__ */ jsx(Reason, {
|
|
461
|
+
tone: "muted",
|
|
462
|
+
children: "This image block keeps its address and alt text. A crop or focal point isn't stored with it."
|
|
463
|
+
}) : /* @__PURE__ */ jsxs("div", {
|
|
360
464
|
className: "flex flex-col gap-1.5",
|
|
361
465
|
children: [
|
|
362
466
|
/* @__PURE__ */ jsxs("div", {
|
|
363
467
|
className: "flex items-center justify-between",
|
|
364
468
|
children: [/* @__PURE__ */ jsxs("span", {
|
|
365
469
|
className: "flex items-center gap-1 text-kit-xs text-kit-fg-3",
|
|
366
|
-
children: [/* @__PURE__ */ jsx(
|
|
470
|
+
children: [/* @__PURE__ */ jsx(IconCrop, {
|
|
367
471
|
className: "size-3.5",
|
|
368
472
|
stroke: 1.5,
|
|
369
473
|
"aria-hidden": true
|
|
370
|
-
}), "
|
|
474
|
+
}), "Crop for this placement"]
|
|
371
475
|
}), /* @__PURE__ */ jsxs("span", {
|
|
372
|
-
className: "
|
|
476
|
+
className: "flex items-center gap-1 text-kit-2xs text-kit-fg-3",
|
|
373
477
|
children: [
|
|
478
|
+
/* @__PURE__ */ jsx(IconFocusCentered, {
|
|
479
|
+
className: "size-3",
|
|
480
|
+
stroke: 1.5,
|
|
481
|
+
"aria-hidden": true
|
|
482
|
+
}),
|
|
374
483
|
"Focal ",
|
|
375
484
|
focal.x,
|
|
376
485
|
"%, ",
|
|
@@ -379,43 +488,71 @@ function ImageDetails({ v, onChange, readOnly, label, urlOnly, size, asset }) {
|
|
|
379
488
|
]
|
|
380
489
|
})]
|
|
381
490
|
}),
|
|
382
|
-
/* @__PURE__ */
|
|
383
|
-
|
|
384
|
-
"aria-label":
|
|
385
|
-
|
|
386
|
-
"
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
"aria-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
491
|
+
/* @__PURE__ */ jsx(Select, {
|
|
492
|
+
size: "sm",
|
|
493
|
+
"aria-label": `${label} crop`,
|
|
494
|
+
disabled: readOnly || !size,
|
|
495
|
+
triggerClassName: "w-full",
|
|
496
|
+
value: choice,
|
|
497
|
+
onValueChange: (c) => size && c !== CUSTOM_CROP && onChange(withCrop(v, c, size)),
|
|
498
|
+
options: [...CROPS.map((c) => ({
|
|
499
|
+
value: c.value,
|
|
500
|
+
label: c.label,
|
|
501
|
+
meta: c.description
|
|
502
|
+
})), ...choice === CUSTOM_CROP ? [{
|
|
503
|
+
value: CUSTOM_CROP,
|
|
504
|
+
label: "Custom",
|
|
505
|
+
meta: "Cut elsewhere",
|
|
506
|
+
disabled: true
|
|
507
|
+
}] : []]
|
|
508
|
+
}),
|
|
509
|
+
!size && !readOnly ? /* @__PURE__ */ jsx("span", {
|
|
510
|
+
className: "text-kit-2xs text-kit-fg-3",
|
|
511
|
+
children: "The crop is cut from the picture's size, which is still loading."
|
|
512
|
+
}) : null,
|
|
513
|
+
/* @__PURE__ */ jsx("div", {
|
|
514
|
+
className: cn(pad ? "mt-1 flex items-center justify-center overflow-hidden rounded-kit-md border border-kit-line" : "contents", pad && CHECKER),
|
|
515
|
+
style: pad ? { aspectRatio: pad.frame } : void 0,
|
|
516
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
517
|
+
role: "slider",
|
|
518
|
+
"aria-label": "Focal point. Click the subject.",
|
|
519
|
+
"aria-valuetext": `${focal.x}% across, ${focal.y}% down`,
|
|
520
|
+
"aria-valuenow": focal.x,
|
|
521
|
+
"aria-valuemin": 0,
|
|
522
|
+
"aria-valuemax": 100,
|
|
523
|
+
"aria-readonly": readOnly || void 0,
|
|
524
|
+
tabIndex: 0,
|
|
525
|
+
onPointerDown: (e) => !readOnly && fromPointer(e),
|
|
526
|
+
onKeyDown: (e) => {
|
|
527
|
+
const d = e.shiftKey ? 10 : 2;
|
|
528
|
+
const step = {
|
|
529
|
+
ArrowLeft: [-d, 0],
|
|
530
|
+
ArrowRight: [d, 0],
|
|
531
|
+
ArrowUp: [0, -d],
|
|
532
|
+
ArrowDown: [0, d]
|
|
533
|
+
}[e.key];
|
|
534
|
+
if (!step || readOnly) return;
|
|
535
|
+
e.preventDefault();
|
|
536
|
+
setFocal(focal.x + step[0], focal.y + step[1]);
|
|
537
|
+
},
|
|
538
|
+
"data-pad-ratio": padRatio,
|
|
539
|
+
className: pad ? cn("relative cursor-crosshair overflow-hidden", pad.fill === "height" ? "h-full" : "w-full") : "relative mt-1 cursor-crosshair overflow-hidden rounded-kit-md border border-kit-line bg-kit-muted",
|
|
540
|
+
style: { aspectRatio: padRatio },
|
|
541
|
+
children: [/* @__PURE__ */ jsx("img", {
|
|
542
|
+
src: src(v.url),
|
|
543
|
+
alt: "",
|
|
544
|
+
draggable: false,
|
|
545
|
+
className: "pointer-events-none size-full select-none object-cover transition-[object-position] duration-200",
|
|
546
|
+
style: { objectPosition: `${focal.x}% ${focal.y}%` }
|
|
547
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
548
|
+
"aria-hidden": true,
|
|
549
|
+
className: "pointer-events-none absolute size-5 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-kit-media-handle bg-kit-media-handle-ring shadow-kit-md transition-[left,top] duration-150",
|
|
550
|
+
style: {
|
|
551
|
+
left: `${focal.x}%`,
|
|
552
|
+
top: `${focal.y}%`
|
|
553
|
+
}
|
|
554
|
+
})]
|
|
555
|
+
})
|
|
419
556
|
}),
|
|
420
557
|
/* @__PURE__ */ jsx("span", {
|
|
421
558
|
className: "text-kit-2xs text-kit-fg-3",
|
|
@@ -423,7 +560,7 @@ function ImageDetails({ v, onChange, readOnly, label, urlOnly, size, asset }) {
|
|
|
423
560
|
})
|
|
424
561
|
]
|
|
425
562
|
})] }),
|
|
426
|
-
/* @__PURE__ */ jsxs("div", {
|
|
563
|
+
urlOnly || altOnly ? /* @__PURE__ */ jsxs("div", {
|
|
427
564
|
className: "flex flex-col gap-1.5",
|
|
428
565
|
children: [/* @__PURE__ */ jsx("span", {
|
|
429
566
|
className: "text-kit-xs text-kit-fg-3",
|
|
@@ -432,6 +569,26 @@ function ImageDetails({ v, onChange, readOnly, label, urlOnly, size, asset }) {
|
|
|
432
569
|
className: "truncate font-kit-mono text-kit-xs text-kit-fg",
|
|
433
570
|
children: asset?.name ?? v.name ?? fileNameFromUrl(v.url)
|
|
434
571
|
})]
|
|
572
|
+
}) : /* @__PURE__ */ jsxs("label", {
|
|
573
|
+
className: "flex flex-col gap-1.5",
|
|
574
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
575
|
+
className: "text-kit-xs text-kit-fg-3",
|
|
576
|
+
children: "File name"
|
|
577
|
+
}), /* @__PURE__ */ jsx(Input, {
|
|
578
|
+
size: "sm",
|
|
579
|
+
value: v.name ?? asset?.name ?? fileNameFromUrl(v.url),
|
|
580
|
+
readOnly,
|
|
581
|
+
spellCheck: false,
|
|
582
|
+
autoComplete: "off",
|
|
583
|
+
onChange: (e) => {
|
|
584
|
+
const next = { ...v };
|
|
585
|
+
if (e.target.value) next.name = e.target.value;
|
|
586
|
+
else delete next.name;
|
|
587
|
+
onChange(next);
|
|
588
|
+
},
|
|
589
|
+
className: "font-kit-mono [&_input]:font-kit-mono",
|
|
590
|
+
"aria-label": `${label} file name`
|
|
591
|
+
})]
|
|
435
592
|
})
|
|
436
593
|
]
|
|
437
594
|
});
|
|
@@ -445,19 +602,105 @@ function storedSize(value) {
|
|
|
445
602
|
h: height
|
|
446
603
|
} : void 0;
|
|
447
604
|
}
|
|
448
|
-
|
|
605
|
+
/**
|
|
606
|
+
* V2's icon control shape (controls/icon.tsx): ONE button — a 24px glyph tile, the field's name, a quiet replace cue —
|
|
607
|
+
* that opens the library. No Replace pill, no ×, no alt text, crop or details: an icon's alt text is "" (aria-hidden on
|
|
608
|
+
* the page) and Remove sits in the picker's footer. Empty: a dashed tile, "Add icon", and an SVG dropped on it uploads.
|
|
609
|
+
*/
|
|
610
|
+
function IconImageRow({ id, title, url, readOnly, onOpen, onFiles, busy, pickerOpen }) {
|
|
611
|
+
const row = React.useRef(null);
|
|
612
|
+
const [over, setOver] = React.useState(false);
|
|
613
|
+
const wasOpen = React.useRef(false);
|
|
614
|
+
React.useEffect(() => {
|
|
615
|
+
if (wasOpen.current && !pickerOpen) row.current?.focus({ preventScroll: true });
|
|
616
|
+
wasOpen.current = pickerOpen;
|
|
617
|
+
}, [pickerOpen]);
|
|
618
|
+
const empty = !url;
|
|
619
|
+
const inert = readOnly || busy || !onOpen;
|
|
620
|
+
const droppable = empty && !inert && !!onFiles;
|
|
621
|
+
const chrome = React.useContext(RowChrome);
|
|
622
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
623
|
+
className: cn("flex h-8 min-w-0 items-center rounded-kit-md border bg-kit-field-bg pointer-coarse:min-h-11", "transition-colors duration-[120ms] ease-out motion-reduce:transition-none", over ? "border-kit-emphasis-line bg-kit-hover" : "border-kit-line-strong", inert ? "opacity-60" : "[@media(hover:hover)]:hover:bg-kit-hover"),
|
|
624
|
+
children: [/* @__PURE__ */ jsx(Tooltip, {
|
|
625
|
+
content: title,
|
|
626
|
+
children: /* @__PURE__ */ jsxs("button", {
|
|
627
|
+
ref: row,
|
|
628
|
+
id,
|
|
629
|
+
type: "button",
|
|
630
|
+
"data-slot": "kit-icon-row",
|
|
631
|
+
disabled: inert,
|
|
632
|
+
onClick: onOpen,
|
|
633
|
+
"aria-label": empty ? `Add icon, ${title}` : `Replace ${title}`,
|
|
634
|
+
onDragOver: droppable ? (e) => {
|
|
635
|
+
e.preventDefault();
|
|
636
|
+
setOver(true);
|
|
637
|
+
} : void 0,
|
|
638
|
+
onDragLeave: droppable ? () => setOver(false) : void 0,
|
|
639
|
+
onDrop: droppable ? (e) => {
|
|
640
|
+
e.preventDefault();
|
|
641
|
+
setOver(false);
|
|
642
|
+
onFiles(Array.from(e.dataTransfer.files));
|
|
643
|
+
} : void 0,
|
|
644
|
+
className: "flex min-w-0 flex-1 touch-manipulation items-center gap-3 self-stretch rounded-[5px] pl-[3px] pr-2 text-left text-kit-sm focus-visible:-outline-offset-2 disabled:cursor-not-allowed",
|
|
645
|
+
children: [
|
|
646
|
+
/* @__PURE__ */ jsx("span", {
|
|
647
|
+
"aria-hidden": true,
|
|
648
|
+
className: cn("grid size-6 shrink-0 place-items-center overflow-hidden rounded-kit-sm border", empty ? "border-dashed border-kit-emphasis-line" : cn("border-kit-line p-1", CHECKER)),
|
|
649
|
+
children: empty ? /* @__PURE__ */ jsx(IconPlus, {
|
|
650
|
+
className: "size-3.5 text-kit-fg-3",
|
|
651
|
+
stroke: 1.5
|
|
652
|
+
}) : /* @__PURE__ */ jsx("img", {
|
|
653
|
+
src: url,
|
|
654
|
+
alt: "",
|
|
655
|
+
className: "size-full object-contain"
|
|
656
|
+
})
|
|
657
|
+
}),
|
|
658
|
+
/* @__PURE__ */ jsx("span", {
|
|
659
|
+
"aria-hidden": true,
|
|
660
|
+
className: cn("min-w-0 flex-1 truncate", empty ? "text-kit-fg-3" : "text-kit-fg"),
|
|
661
|
+
children: empty ? busy ? "Uploading…" : "Add icon" : title
|
|
662
|
+
}),
|
|
663
|
+
empty ? null : /* @__PURE__ */ jsx(IconRefresh, {
|
|
664
|
+
"aria-hidden": true,
|
|
665
|
+
className: "size-3.5 shrink-0 text-kit-fg-3",
|
|
666
|
+
stroke: 1.5
|
|
667
|
+
})
|
|
668
|
+
]
|
|
669
|
+
})
|
|
670
|
+
}), chrome ? /* @__PURE__ */ jsx("span", {
|
|
671
|
+
"data-slot": "kit-icon-row-chrome",
|
|
672
|
+
className: "flex shrink-0 items-center gap-0.5 pr-1 empty:hidden",
|
|
673
|
+
children: chrome
|
|
674
|
+
}) : null]
|
|
675
|
+
});
|
|
676
|
+
}
|
|
449
677
|
function ImageControl({ field, value, onChange: write, readOnly, id, path }) {
|
|
450
678
|
const { s, useAsset, src } = useMedia();
|
|
451
679
|
const env = useKitEnv();
|
|
452
680
|
const urlOnly = !!s.imageStoresUrl?.(path);
|
|
681
|
+
const altOnly = !urlOnly && !!s.imageAltOnly?.(path);
|
|
453
682
|
const legacyString = typeof value === "string" || field.valueShape === "string";
|
|
454
683
|
const v = normImage(value);
|
|
455
684
|
const asset = useAsset({
|
|
456
685
|
id: v?.id,
|
|
457
686
|
url: v?.url ?? ""
|
|
458
687
|
});
|
|
459
|
-
const
|
|
460
|
-
|
|
688
|
+
const accept = field.svgOnly ? "image/svg+xml" : "image/*";
|
|
689
|
+
const kinds = field.svgOnly ? ["svg"] : ["image", "svg"];
|
|
690
|
+
const [loaded, setLoaded] = React.useState();
|
|
691
|
+
const natural = loaded && v && loaded.url === v.url ? {
|
|
692
|
+
w: loaded.w,
|
|
693
|
+
h: loaded.h
|
|
694
|
+
} : void 0;
|
|
695
|
+
const readNatural = (img) => {
|
|
696
|
+
if (!img || !v || !img.complete || !img.naturalWidth || !img.naturalHeight) return;
|
|
697
|
+
const next = {
|
|
698
|
+
url: v.url,
|
|
699
|
+
w: img.naturalWidth,
|
|
700
|
+
h: img.naturalHeight
|
|
701
|
+
};
|
|
702
|
+
setLoaded((prev) => prev && prev.url === next.url && prev.w === next.w && prev.h === next.h ? prev : next);
|
|
703
|
+
};
|
|
461
704
|
const stored = storedSize(value);
|
|
462
705
|
const size = asset?.width && asset.height ? {
|
|
463
706
|
w: asset.width,
|
|
@@ -466,13 +709,68 @@ function ImageControl({ field, value, onChange: write, readOnly, id, path }) {
|
|
|
466
709
|
const onChange = (n) => {
|
|
467
710
|
if (!n) return write(urlOnly ? "" : null);
|
|
468
711
|
if (urlOnly) return write(n.url);
|
|
469
|
-
if (legacyString && !n.alt && !n.focal) return write(n.url);
|
|
712
|
+
if (legacyString && !n.alt && !n.focal && !n.crop && !n.name && !n.id) return write(n.url);
|
|
470
713
|
write(n);
|
|
471
714
|
};
|
|
472
715
|
const [picker, setPicker] = React.useState(false);
|
|
473
716
|
const [details, setDetails] = React.useState(false);
|
|
474
|
-
const up = useUpload(
|
|
717
|
+
const up = useUpload(accept, "image", (a) => a[0] && onChange(fromAsset(a[0])));
|
|
475
718
|
const library = s.MediaPicker && !readOnly ? () => setPicker(true) : void 0;
|
|
719
|
+
const known = (s.useSiteIcons ?? NO_ICONS)();
|
|
720
|
+
if (isIconImage(field, value)) {
|
|
721
|
+
const icons = s.useSiteIcons ? [...v ? [{
|
|
722
|
+
url: v.url,
|
|
723
|
+
value,
|
|
724
|
+
current: true
|
|
725
|
+
}] : [], ...known.filter((i) => i.url !== v?.url && !(v?.id && i.assetId === v.id)).map(({ url, value: stored }) => ({
|
|
726
|
+
url,
|
|
727
|
+
value: stored
|
|
728
|
+
}))] : void 0;
|
|
729
|
+
const pickIcon = (stored) => {
|
|
730
|
+
const n = normImage(stored);
|
|
731
|
+
if (n) onChange(fromAsset({
|
|
732
|
+
id: n.id ?? "",
|
|
733
|
+
url: n.url,
|
|
734
|
+
name: n.name,
|
|
735
|
+
alt: n.alt ?? (typeof n.altText === "string" ? n.altText : void 0),
|
|
736
|
+
kind: "svg"
|
|
737
|
+
}));
|
|
738
|
+
setPicker(false);
|
|
739
|
+
};
|
|
740
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
741
|
+
className: "flex flex-col gap-1.5",
|
|
742
|
+
children: [
|
|
743
|
+
/* @__PURE__ */ jsx(IconImageRow, {
|
|
744
|
+
id,
|
|
745
|
+
title: field.title,
|
|
746
|
+
url: v ? src(v.url) : void 0,
|
|
747
|
+
readOnly,
|
|
748
|
+
onOpen: library,
|
|
749
|
+
onFiles: up.run,
|
|
750
|
+
busy: up.progress != null,
|
|
751
|
+
pickerOpen: picker
|
|
752
|
+
}),
|
|
753
|
+
up.error ? /* @__PURE__ */ jsx(Reason, { children: up.error }) : null,
|
|
754
|
+
!readOnly && !library ? /* @__PURE__ */ jsx(Reason, {
|
|
755
|
+
tone: "muted",
|
|
756
|
+
children: NO_LIBRARY
|
|
757
|
+
}) : null,
|
|
758
|
+
/* @__PURE__ */ jsx(MediaPicker, {
|
|
759
|
+
open: picker,
|
|
760
|
+
onOpenChange: setPicker,
|
|
761
|
+
accept: ["svg"],
|
|
762
|
+
title: v ? "Replace icon" : "Select an icon",
|
|
763
|
+
onPick: (a) => a[0] && onChange(fromAsset(a[0])),
|
|
764
|
+
onRemove: v && !readOnly ? () => {
|
|
765
|
+
onChange(null);
|
|
766
|
+
setPicker(false);
|
|
767
|
+
} : void 0,
|
|
768
|
+
icons,
|
|
769
|
+
onPickIcon: readOnly ? void 0 : pickIcon
|
|
770
|
+
})
|
|
771
|
+
]
|
|
772
|
+
});
|
|
773
|
+
}
|
|
476
774
|
if (!v) return /* @__PURE__ */ jsxs("div", {
|
|
477
775
|
className: "flex flex-col gap-1.5",
|
|
478
776
|
children: [
|
|
@@ -480,7 +778,7 @@ function ImageControl({ field, value, onChange: write, readOnly, id, path }) {
|
|
|
480
778
|
id,
|
|
481
779
|
title: "Add an image",
|
|
482
780
|
hint: "Or drop or paste one here",
|
|
483
|
-
accept
|
|
781
|
+
accept,
|
|
484
782
|
icon: /* @__PURE__ */ jsx(IconPhoto, { stroke: 1.5 }),
|
|
485
783
|
onFiles: up.run,
|
|
486
784
|
onLibrary: library,
|
|
@@ -496,15 +794,14 @@ function ImageControl({ field, value, onChange: write, readOnly, id, path }) {
|
|
|
496
794
|
/* @__PURE__ */ jsx(MediaPicker, {
|
|
497
795
|
open: picker,
|
|
498
796
|
onOpenChange: setPicker,
|
|
499
|
-
accept:
|
|
797
|
+
accept: kinds,
|
|
500
798
|
onPick: (a) => a[0] && onChange(fromAsset(a[0]))
|
|
501
799
|
})
|
|
502
800
|
]
|
|
503
801
|
});
|
|
504
|
-
const
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
};
|
|
802
|
+
const fit = frameFit(size);
|
|
803
|
+
const vector = asset?.kind === "svg" || !!field.svgOnly || /\.svg(?:$|[?#])/i.test(v.url);
|
|
804
|
+
const cap = fit.image && size && !vector ? size : void 0;
|
|
508
805
|
const alt = urlOnly ? asset?.alt : v.alt;
|
|
509
806
|
const name = asset?.name ?? v.name ?? fileNameFromUrl(v.url);
|
|
510
807
|
const replace = (a) => {
|
|
@@ -529,7 +826,10 @@ function ImageControl({ field, value, onChange: write, readOnly, id, path }) {
|
|
|
529
826
|
},
|
|
530
827
|
children: [
|
|
531
828
|
/* @__PURE__ */ jsxs("div", {
|
|
532
|
-
|
|
829
|
+
"data-slot": "kit-image-frame",
|
|
830
|
+
"data-frame-ratio": String(fit.frame),
|
|
831
|
+
className: cn("group/img relative overflow-hidden rounded-kit-lg border border-kit-line", CHECKER),
|
|
832
|
+
style: { aspectRatio: fit.frame },
|
|
533
833
|
children: [
|
|
534
834
|
/* @__PURE__ */ jsx("button", {
|
|
535
835
|
id,
|
|
@@ -537,19 +837,23 @@ function ImageControl({ field, value, onChange: write, readOnly, id, path }) {
|
|
|
537
837
|
disabled: readOnly,
|
|
538
838
|
onClick: () => library ? library() : openDetails(),
|
|
539
839
|
"aria-label": library ? `Replace ${field.title}` : `${field.title} details`,
|
|
540
|
-
className: "
|
|
840
|
+
className: "flex size-full items-center justify-center outline-none 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-none",
|
|
541
841
|
children: /* @__PURE__ */ jsx("img", {
|
|
542
842
|
src: src(v.url),
|
|
543
843
|
alt: alt ?? "",
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
844
|
+
ref: readNatural,
|
|
845
|
+
onLoad: (e) => readNatural(e.currentTarget),
|
|
846
|
+
"data-fill": fit.fill,
|
|
847
|
+
"data-image-ratio": fit.image ?? void 0,
|
|
848
|
+
"data-cap": cap ? `${cap.w}x${cap.h}` : void 0,
|
|
849
|
+
className: FIT_CLASS[fit.fill],
|
|
850
|
+
style: fit.image ? {
|
|
851
|
+
aspectRatio: fit.image,
|
|
852
|
+
...cap ? {
|
|
853
|
+
maxWidth: `min(100%, ${cap.w}px)`,
|
|
854
|
+
maxHeight: `min(100%, ${cap.h}px)`
|
|
855
|
+
} : {}
|
|
856
|
+
} : void 0
|
|
553
857
|
})
|
|
554
858
|
}),
|
|
555
859
|
readOnly ? null : /* @__PURE__ */ jsxs("div", {
|
|
@@ -557,7 +861,7 @@ function ImageControl({ field, value, onChange: write, readOnly, id, path }) {
|
|
|
557
861
|
children: [library ? /* @__PURE__ */ jsxs("button", {
|
|
558
862
|
type: "button",
|
|
559
863
|
onClick: library,
|
|
560
|
-
className:
|
|
864
|
+
className: "flex h-7 items-center gap-1 rounded-full border border-kit-swatch-ring bg-kit-media-control px-2.5 text-kit-xs font-medium text-kit-media-control-fg shadow-kit-sm",
|
|
561
865
|
children: [/* @__PURE__ */ jsx(IconReplace, {
|
|
562
866
|
className: "size-3.5",
|
|
563
867
|
stroke: 1.5,
|
|
@@ -569,7 +873,7 @@ function ImageControl({ field, value, onChange: write, readOnly, id, path }) {
|
|
|
569
873
|
type: "button",
|
|
570
874
|
"aria-label": "Remove image",
|
|
571
875
|
onClick: () => onChange(null),
|
|
572
|
-
className:
|
|
876
|
+
className: "flex size-7 items-center justify-center rounded-full border border-kit-swatch-ring bg-kit-media-control text-kit-media-control-fg shadow-kit-sm",
|
|
573
877
|
children: /* @__PURE__ */ jsx(IconX, {
|
|
574
878
|
className: "size-3.5",
|
|
575
879
|
stroke: 1.5,
|
|
@@ -634,22 +938,25 @@ function ImageControl({ field, value, onChange: write, readOnly, id, path }) {
|
|
|
634
938
|
onClick: openDetails,
|
|
635
939
|
children: "Alt text and details"
|
|
636
940
|
}),
|
|
637
|
-
|
|
941
|
+
/* @__PURE__ */ jsx(MenuItem, {
|
|
638
942
|
icon: /* @__PURE__ */ jsx(IconReplace, { stroke: 1.5 }),
|
|
943
|
+
disabled: !library,
|
|
639
944
|
onClick: library,
|
|
640
945
|
children: "Replace"
|
|
641
|
-
})
|
|
946
|
+
}),
|
|
642
947
|
/* @__PURE__ */ jsx(MenuItem, {
|
|
643
948
|
icon: /* @__PURE__ */ jsx(IconExternalLink, { stroke: 1.5 }),
|
|
644
949
|
onClick: () => window.open(src(v.url), "_blank", "noopener"),
|
|
645
950
|
children: "Open original"
|
|
646
951
|
}),
|
|
647
|
-
|
|
952
|
+
/* @__PURE__ */ jsx(MenuSeparator, {}),
|
|
953
|
+
/* @__PURE__ */ jsx(MenuItem, {
|
|
648
954
|
danger: true,
|
|
649
955
|
icon: /* @__PURE__ */ jsx(IconTrash, { stroke: 1.5 }),
|
|
650
|
-
|
|
956
|
+
disabled: readOnly,
|
|
957
|
+
onClick: () => !readOnly && onChange(null),
|
|
651
958
|
children: "Remove"
|
|
652
|
-
})
|
|
959
|
+
})
|
|
653
960
|
]
|
|
654
961
|
})] })]
|
|
655
962
|
}),
|
|
@@ -666,6 +973,7 @@ function ImageControl({ field, value, onChange: write, readOnly, id, path }) {
|
|
|
666
973
|
readOnly,
|
|
667
974
|
label: field.title,
|
|
668
975
|
urlOnly,
|
|
976
|
+
altOnly,
|
|
669
977
|
size,
|
|
670
978
|
asset
|
|
671
979
|
})
|
|
@@ -673,7 +981,7 @@ function ImageControl({ field, value, onChange: write, readOnly, id, path }) {
|
|
|
673
981
|
/* @__PURE__ */ jsx(MediaPicker, {
|
|
674
982
|
open: picker,
|
|
675
983
|
onOpenChange: setPicker,
|
|
676
|
-
accept:
|
|
984
|
+
accept: kinds,
|
|
677
985
|
onPick: (a) => a[0] && replace(a[0])
|
|
678
986
|
})
|
|
679
987
|
]
|
|
@@ -686,10 +994,11 @@ function Thumb({ item, label, readOnly, sort, onRemove, onOpen }) {
|
|
|
686
994
|
ref: sort.register(item.key),
|
|
687
995
|
role: "listitem",
|
|
688
996
|
style: sort.style(item.key),
|
|
689
|
-
className: cn("group/thumb relative aspect-square overflow-hidden rounded-kit-md border border-kit-line
|
|
997
|
+
className: cn("group/thumb relative aspect-square cursor-grab touch-none overflow-hidden rounded-kit-md border border-kit-line active:cursor-grabbing", CHECKER, sort.active === item.key && "z-10 opacity-90 shadow-kit-lg ring-2 ring-kit-line-strong"),
|
|
690
998
|
children: [
|
|
691
999
|
/* @__PURE__ */ jsx("div", {
|
|
692
1000
|
...readOnly ? {} : handle,
|
|
1001
|
+
role: void 0,
|
|
693
1002
|
tabIndex: 0,
|
|
694
1003
|
"aria-label": readOnly ? label : `${label}, drag to reorder`,
|
|
695
1004
|
onDoubleClick: onOpen,
|
|
@@ -706,11 +1015,12 @@ function Thumb({ item, label, readOnly, sort, onRemove, onOpen }) {
|
|
|
706
1015
|
}
|
|
707
1016
|
if (!readOnly) handle.onKeyDown(e);
|
|
708
1017
|
},
|
|
709
|
-
className:
|
|
1018
|
+
className: "size-full outline-none 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-none",
|
|
710
1019
|
children: /* @__PURE__ */ jsx("img", {
|
|
711
1020
|
src: src(item.v.url),
|
|
712
1021
|
alt: item.v.alt ?? "",
|
|
713
|
-
|
|
1022
|
+
"data-slot": "kit-gallery-thumb",
|
|
1023
|
+
className: "pointer-events-none size-full select-none object-contain",
|
|
714
1024
|
draggable: false
|
|
715
1025
|
})
|
|
716
1026
|
}),
|
|
@@ -721,10 +1031,13 @@ function Thumb({ item, label, readOnly, sort, onRemove, onOpen }) {
|
|
|
721
1031
|
}) : null,
|
|
722
1032
|
readOnly ? null : /* @__PURE__ */ jsx("button", {
|
|
723
1033
|
type: "button",
|
|
724
|
-
"aria-label":
|
|
1034
|
+
"aria-label": (() => {
|
|
1035
|
+
const what = item.v.alt || item.v.name || fileNameFromUrl(item.v.url);
|
|
1036
|
+
return what ? `Remove ${what}` : "Remove image";
|
|
1037
|
+
})(),
|
|
725
1038
|
onPointerDown: (e) => e.stopPropagation(),
|
|
726
1039
|
onClick: onRemove,
|
|
727
|
-
className: "absolute right-1 top-1 flex size-6 items-center justify-center rounded-kit-md bg-kit-inverse/80 text-kit-fg-inverse opacity-0 transition-opacity focus-visible:opacity-100 group-hover/thumb:opacity-100
|
|
1040
|
+
className: "absolute right-1 top-1 flex size-6 items-center justify-center rounded-kit-md bg-kit-inverse/80 text-kit-fg-inverse opacity-0 transition-opacity focus-visible:opacity-100 group-hover/thumb:opacity-100 pointer-coarse:opacity-100",
|
|
728
1041
|
children: /* @__PURE__ */ jsx(IconX, {
|
|
729
1042
|
className: "size-3.5",
|
|
730
1043
|
stroke: 1.5,
|
|
@@ -735,8 +1048,9 @@ function Thumb({ item, label, readOnly, sort, onRemove, onOpen }) {
|
|
|
735
1048
|
});
|
|
736
1049
|
}
|
|
737
1050
|
/** An array of images: a sortable grid of tiles with a dashed "Add images" tile last (hidden at `max`). */
|
|
738
|
-
function GalleryControl({ value, onChange, readOnly, field, id }) {
|
|
1051
|
+
function GalleryControl({ value, onChange, readOnly, field, id, path }) {
|
|
739
1052
|
const { s, src } = useMedia();
|
|
1053
|
+
const env = useKitEnv();
|
|
740
1054
|
const raw = Array.isArray(value) ? value : [];
|
|
741
1055
|
const seen = /* @__PURE__ */ new Map();
|
|
742
1056
|
const items = raw.map((x) => {
|
|
@@ -756,7 +1070,8 @@ function GalleryControl({ value, onChange, readOnly, field, id }) {
|
|
|
756
1070
|
const add = (assets) => write([...raw, ...assets.map((a) => out(fromAsset(a)))]);
|
|
757
1071
|
const [picker, setPicker] = React.useState(false);
|
|
758
1072
|
const up = useUpload("image/*", "image", add);
|
|
759
|
-
const
|
|
1073
|
+
const keys = items.map((it) => it.key);
|
|
1074
|
+
const sort = useDragReorder(keys, (from, to) => {
|
|
760
1075
|
const next = [...raw];
|
|
761
1076
|
const [moved] = next.splice(from, 1);
|
|
762
1077
|
next.splice(to, 0, moved);
|
|
@@ -781,7 +1096,11 @@ function GalleryControl({ value, onChange, readOnly, field, id }) {
|
|
|
781
1096
|
label: noun(i, it),
|
|
782
1097
|
readOnly,
|
|
783
1098
|
sort,
|
|
784
|
-
onOpen: () =>
|
|
1099
|
+
onOpen: () => s.editImage && !readOnly ? s.editImage({
|
|
1100
|
+
docId: env.docId,
|
|
1101
|
+
path: [...path, i],
|
|
1102
|
+
title: noun(i, it)
|
|
1103
|
+
}) : window.open(src(it.v.url), "_blank", "noopener"),
|
|
785
1104
|
onRemove: () => write(raw.filter((_, j) => j !== i))
|
|
786
1105
|
}, it.key)), canAdd ? /* @__PURE__ */ jsx("div", {
|
|
787
1106
|
role: "listitem",
|
|
@@ -894,58 +1213,59 @@ function FileControl({ value, onChange, readOnly, id }) {
|
|
|
894
1213
|
const ext = (name.includes(".") ? name.split(".").pop() : "")?.toUpperCase() || "FILE";
|
|
895
1214
|
const meta = [ext.toLowerCase(), asset?.size ? formatBytes(asset.size) : null].filter(Boolean).join(" · ");
|
|
896
1215
|
return /* @__PURE__ */ jsxs("div", {
|
|
897
|
-
className: "flex
|
|
898
|
-
children: [
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
/* @__PURE__ */
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
1216
|
+
className: "flex items-center gap-3 rounded-kit-lg border border-kit-line bg-kit-control-bg p-2",
|
|
1217
|
+
children: [
|
|
1218
|
+
/* @__PURE__ */ jsx("span", {
|
|
1219
|
+
"aria-hidden": true,
|
|
1220
|
+
className: "flex size-14 shrink-0 items-center justify-center rounded-kit-md border border-kit-line bg-kit-subtle font-kit-mono text-kit-2xs font-medium text-kit-fg-2",
|
|
1221
|
+
children: ext
|
|
1222
|
+
}),
|
|
1223
|
+
/* @__PURE__ */ jsxs("div", {
|
|
1224
|
+
className: "min-w-0 flex-1",
|
|
1225
|
+
children: [/* @__PURE__ */ jsx("a", {
|
|
1226
|
+
id,
|
|
1227
|
+
href: src(v.url),
|
|
1228
|
+
target: "_blank",
|
|
1229
|
+
rel: "noreferrer",
|
|
1230
|
+
className: "block truncate text-kit-sm font-medium text-kit-accent-fg hover:underline",
|
|
1231
|
+
children: name
|
|
1232
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
1233
|
+
className: "text-kit-xs text-kit-fg-3",
|
|
1234
|
+
children: meta
|
|
1235
|
+
})]
|
|
1236
|
+
}),
|
|
1237
|
+
library ? /* @__PURE__ */ jsx(Button, {
|
|
1238
|
+
size: "sm",
|
|
1239
|
+
variant: "ghost",
|
|
1240
|
+
onClick: library,
|
|
1241
|
+
children: "Replace"
|
|
1242
|
+
}) : null,
|
|
1243
|
+
/* @__PURE__ */ jsxs(Menu, { children: [/* @__PURE__ */ jsx(MenuTrigger, {
|
|
1244
|
+
render: /* @__PURE__ */ jsx(IconButton, {
|
|
1245
|
+
label: "File actions",
|
|
1246
|
+
size: "sm"
|
|
919
1247
|
}),
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
}) : null,
|
|
926
|
-
/* @__PURE__ */ jsxs(Menu, { children: [/* @__PURE__ */ jsx(MenuTrigger, {
|
|
927
|
-
"aria-label": "File actions",
|
|
928
|
-
className: "flex size-7 shrink-0 items-center justify-center rounded-kit-md text-kit-fg-3 hover:bg-kit-hover hover:text-kit-fg data-[popup-open]:bg-kit-hover",
|
|
929
|
-
children: /* @__PURE__ */ jsx(IconDots, {
|
|
930
|
-
className: "size-4",
|
|
931
|
-
stroke: 1.5,
|
|
932
|
-
"aria-hidden": true
|
|
933
|
-
})
|
|
934
|
-
}), /* @__PURE__ */ jsxs(MenuContent, {
|
|
935
|
-
align: "end",
|
|
936
|
-
children: [/* @__PURE__ */ jsx(MenuItem, {
|
|
1248
|
+
children: /* @__PURE__ */ jsx(IconDots, { stroke: 1.5 })
|
|
1249
|
+
}), /* @__PURE__ */ jsxs(MenuContent, {
|
|
1250
|
+
align: "end",
|
|
1251
|
+
children: [
|
|
1252
|
+
/* @__PURE__ */ jsx(MenuItem, {
|
|
937
1253
|
icon: /* @__PURE__ */ jsx(IconDownload, { stroke: 1.5 }),
|
|
938
1254
|
onClick: () => window.open(src(v.url), "_blank", "noopener"),
|
|
939
1255
|
children: "Open"
|
|
940
|
-
}),
|
|
1256
|
+
}),
|
|
1257
|
+
/* @__PURE__ */ jsx(MenuSeparator, {}),
|
|
1258
|
+
/* @__PURE__ */ jsx(MenuItem, {
|
|
941
1259
|
danger: true,
|
|
942
1260
|
icon: /* @__PURE__ */ jsx(IconTrash, { stroke: 1.5 }),
|
|
943
|
-
|
|
1261
|
+
disabled: readOnly,
|
|
1262
|
+
onClick: () => !readOnly && onChange(null),
|
|
944
1263
|
children: "Remove"
|
|
945
|
-
})
|
|
946
|
-
|
|
947
|
-
]
|
|
948
|
-
|
|
1264
|
+
})
|
|
1265
|
+
]
|
|
1266
|
+
})] }),
|
|
1267
|
+
pickerEl
|
|
1268
|
+
]
|
|
949
1269
|
});
|
|
950
1270
|
}
|
|
951
1271
|
var videoProvider = (url) => /youtu/.test(url) ? "YouTube" : /vimeo/.test(url) ? "Vimeo" : /loom/.test(url) ? "Loom" : /\.(mp4|webm|mov)(\?|$)/i.test(url) ? "MP4" : url ? "Link" : "";
|
|
@@ -968,11 +1288,11 @@ function VideoPreview({ url, poster, title }) {
|
|
|
968
1288
|
poster: thumb,
|
|
969
1289
|
controls: true,
|
|
970
1290
|
autoPlay: true,
|
|
971
|
-
className: "aspect-video w-full rounded-kit-lg border border-kit-line bg-kit-
|
|
1291
|
+
className: "aspect-video w-full rounded-kit-lg border border-kit-line bg-kit-media-backdrop"
|
|
972
1292
|
});
|
|
973
1293
|
const playable = !!yt || isFileVideo(url);
|
|
974
1294
|
return /* @__PURE__ */ jsxs("div", {
|
|
975
|
-
className: "relative aspect-video overflow-hidden rounded-kit-lg border border-kit-line bg-kit-
|
|
1295
|
+
className: "relative aspect-video overflow-hidden rounded-kit-lg border border-kit-line bg-kit-media-backdrop",
|
|
976
1296
|
children: [
|
|
977
1297
|
thumb ? /* @__PURE__ */ jsx("img", {
|
|
978
1298
|
src: thumb,
|
|
@@ -983,7 +1303,7 @@ function VideoPreview({ url, poster, title }) {
|
|
|
983
1303
|
type: "button",
|
|
984
1304
|
"aria-label": playable ? "Play preview" : "Open video link",
|
|
985
1305
|
onClick: () => playable ? setPlaying(true) : window.open(src(url), "_blank", "noopener"),
|
|
986
|
-
className: "absolute inset-0 m-auto flex size-12 items-center justify-center rounded-full bg-kit-control
|
|
1306
|
+
className: "absolute inset-0 m-auto flex size-12 items-center justify-center rounded-full bg-kit-media-control text-kit-media-control-fg shadow-kit-lg transition-transform hover:scale-105",
|
|
987
1307
|
children: playable ? /* @__PURE__ */ jsx(IconPlayerPlay, {
|
|
988
1308
|
className: "size-5",
|
|
989
1309
|
stroke: 1.5,
|
|
@@ -995,7 +1315,7 @@ function VideoPreview({ url, poster, title }) {
|
|
|
995
1315
|
})
|
|
996
1316
|
}),
|
|
997
1317
|
/* @__PURE__ */ jsxs("span", {
|
|
998
|
-
className: "absolute left-2 top-2 inline-flex items-center gap-1 rounded-kit-md bg-kit-
|
|
1318
|
+
className: "absolute left-2 top-2 inline-flex items-center gap-1 rounded-kit-md bg-kit-scrim px-1.5 py-0.5 text-kit-xs text-kit-on-scrim",
|
|
999
1319
|
children: [/* @__PURE__ */ jsx(IconVideo, {
|
|
1000
1320
|
className: "size-3.5",
|
|
1001
1321
|
stroke: 1.5,
|
|
@@ -1071,6 +1391,6 @@ function VideoControl({ field, value, onChange, readOnly, id, onBlur }) {
|
|
|
1071
1391
|
});
|
|
1072
1392
|
}
|
|
1073
1393
|
//#endregion
|
|
1074
|
-
export { FileControl, GalleryControl, ImageControl, VideoControl };
|
|
1394
|
+
export { FileControl, GalleryControl, ImageControl, MediaPicker, VideoControl, VideoPreview, acceptsFile, cropChoice, fileNameFromUrl, formatBytes, frameFit, fromAsset, isVideoUrl, normImage, useUpload, videoProvider, withCrop, youTubeId };
|
|
1075
1395
|
|
|
1076
1396
|
//# sourceMappingURL=media.js.map
|