@bettercms-ai/kit 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -0
- package/dist/adapters/dock-values.d.ts +28 -0
- package/dist/adapters/dock-values.js +41 -0
- package/dist/adapters/dock-values.js.map +1 -0
- package/{adapters → dist/adapters}/icons.js +2 -2
- package/dist/adapters/icons.js.map +1 -0
- package/{adapters → dist/adapters}/lossy.d.ts +90 -31
- package/dist/adapters/lossy.js +414 -0
- package/dist/adapters/lossy.js.map +1 -0
- package/{adapters → dist/adapters}/prod-types.d.ts +82 -4
- package/{adapters → dist/adapters}/prod-types.js +71 -3
- package/dist/adapters/prod-types.js.map +1 -0
- package/{adapters → dist/adapters}/schema.d.ts +40 -1
- package/{adapters → dist/adapters}/schema.js +996 -179
- package/dist/adapters/schema.js.map +1 -0
- package/{adapters → dist/adapters}/values.d.ts +26 -5
- package/{adapters → dist/adapters}/values.js +87 -17
- package/dist/adapters/values.js.map +1 -0
- package/dist/brand/logo.js +96 -0
- package/dist/brand/logo.js.map +1 -0
- package/{context.d.ts → dist/context.d.ts} +92 -2
- package/{context.js → dist/context.js} +5 -2
- package/dist/context.js.map +1 -0
- package/{controls → dist/controls}/button.d.ts +19 -5
- package/{controls → dist/controls}/button.js +125 -54
- package/dist/controls/button.js.map +1 -0
- package/{controls → dist/controls}/c1.js +1 -1
- package/dist/controls/c1.js.map +1 -0
- package/{controls → dist/controls}/c2.js +1 -1
- package/dist/controls/c2.js.map +1 -0
- package/{controls → dist/controls}/choice.d.ts +7 -2
- package/{controls → dist/controls}/choice.js +71 -18
- package/dist/controls/choice.js.map +1 -0
- package/{controls → dist/controls}/code-register.js +1 -1
- package/dist/controls/code-register.js.map +1 -0
- package/{controls → dist/controls}/code.js +10 -9
- package/dist/controls/code.js.map +1 -0
- package/{controls → dist/controls}/color.js +8 -8
- package/dist/controls/color.js.map +1 -0
- package/{controls → dist/controls}/component-services.d.ts +42 -0
- package/dist/controls/component-services.js +7 -0
- package/dist/controls/component-services.js.map +1 -0
- package/{controls → dist/controls}/date-register.js +1 -1
- package/dist/controls/date-register.js.map +1 -0
- package/{controls → dist/controls}/date-zone.js +8 -2
- package/dist/controls/date-zone.js.map +1 -0
- package/{controls → dist/controls}/date.js +32 -24
- package/dist/controls/date.js.map +1 -0
- package/{controls → dist/controls}/form-picker-register.js +1 -1
- package/dist/controls/form-picker-register.js.map +1 -0
- package/{controls → dist/controls}/form-picker.js +11 -9
- package/dist/controls/form-picker.js.map +1 -0
- package/{controls → dist/controls}/icon-register.js +1 -1
- package/dist/controls/icon-register.js.map +1 -0
- package/{controls → dist/controls}/icon.d.ts +4 -2
- package/{controls → dist/controls}/icon.js +32 -27
- package/dist/controls/icon.js.map +1 -0
- package/{controls → dist/controls}/index.d.ts +1 -1
- package/{controls → dist/controls}/index.js +4 -3
- package/dist/controls/index.js.map +1 -0
- package/{controls → dist/controls}/json-register.js +1 -1
- package/dist/controls/json-register.js.map +1 -0
- package/{controls → dist/controls}/json.js +13 -3
- package/dist/controls/json.js.map +1 -0
- package/{controls → dist/controls}/link.js +6 -6
- package/dist/controls/link.js.map +1 -0
- package/{controls → dist/controls}/location-register.js +1 -1
- package/dist/controls/location-register.js.map +1 -0
- package/{controls → dist/controls}/location.js +64 -40
- package/dist/controls/location.js.map +1 -0
- package/{controls → dist/controls}/media-register.js +1 -1
- package/dist/controls/media-register.js.map +1 -0
- package/{controls → dist/controls}/media-services.d.ts +6 -0
- package/dist/controls/media-services.js +0 -0
- package/{controls → dist/controls}/media.d.ts +35 -4
- package/{controls → dist/controls}/media.js +491 -171
- package/dist/controls/media.js.map +1 -0
- package/{controls → dist/controls}/number.js +10 -9
- package/dist/controls/number.js.map +1 -0
- package/{controls → dist/controls}/reference-register.js +1 -1
- package/dist/controls/reference-register.js.map +1 -0
- package/{controls → dist/controls}/reference-services.d.ts +4 -0
- package/dist/controls/reference-services.js +0 -0
- package/{controls → dist/controls}/reference.d.ts +1 -1
- package/{controls → dist/controls}/reference.js +93 -77
- package/dist/controls/reference.js.map +1 -0
- package/dist/controls/rich-text/blocks.d.ts +49 -0
- package/{controls → dist/controls}/rich-text/blocks.js +471 -144
- package/dist/controls/rich-text/blocks.js.map +1 -0
- package/{controls → dist/controls}/rich-text/catalog.d.ts +4 -1
- package/{controls → dist/controls}/rich-text/catalog.js +75 -65
- package/dist/controls/rich-text/catalog.js.map +1 -0
- package/{controls → dist/controls}/rich-text/codec.d.ts +9 -1
- package/{controls → dist/controls}/rich-text/codec.js +3 -1
- package/dist/controls/rich-text/codec.js.map +1 -0
- package/{controls → dist/controls}/rich-text/component-card.d.ts +1 -1
- package/{controls → dist/controls}/rich-text/component-card.js +417 -99
- package/dist/controls/rich-text/component-card.js.map +1 -0
- package/dist/controls/rich-text/component-panel.d.ts +47 -0
- package/dist/controls/rich-text/component-panel.js +141 -0
- package/dist/controls/rich-text/component-panel.js.map +1 -0
- package/{controls → dist/controls}/rich-text/control.d.ts +1 -2
- package/{controls → dist/controls}/rich-text/control.js +84 -42
- package/dist/controls/rich-text/control.js.map +1 -0
- package/{controls → dist/controls}/rich-text/dom.d.ts +52 -9
- package/{controls → dist/controls}/rich-text/dom.js +379 -50
- package/dist/controls/rich-text/dom.js.map +1 -0
- package/{controls → dist/controls}/rich-text/editor.d.ts +7 -0
- package/{controls → dist/controls}/rich-text/editor.js +148 -48
- package/dist/controls/rich-text/editor.js.map +1 -0
- package/{controls → dist/controls}/rich-text/floating.d.ts +6 -1
- package/{controls → dist/controls}/rich-text/floating.js +35 -18
- package/dist/controls/rich-text/floating.js.map +1 -0
- package/{controls → dist/controls}/rich-text/index.js +1 -1
- package/dist/controls/rich-text/index.js.map +1 -0
- package/dist/controls/rich-text/link-form.js +147 -0
- package/dist/controls/rich-text/link-form.js.map +1 -0
- package/{controls → dist/controls}/rich-text/markdown.js +4 -2
- package/dist/controls/rich-text/markdown.js.map +1 -0
- package/{controls → dist/controls}/rich-text/ops.js +17 -15
- package/dist/controls/rich-text/ops.js.map +1 -0
- package/dist/controls/rich-text/plain.d.ts +17 -0
- package/dist/controls/rich-text/plain.js +44 -0
- package/dist/controls/rich-text/plain.js.map +1 -0
- package/{controls → dist/controls}/rich-text/toolbar.d.ts +6 -2
- package/{controls → dist/controls}/rich-text/toolbar.js +12 -7
- package/dist/controls/rich-text/toolbar.js.map +1 -0
- package/{controls → dist/controls}/scale.js +5 -5
- package/dist/controls/scale.js.map +1 -0
- package/{controls → dist/controls}/slot-register.js +1 -1
- package/dist/controls/slot-register.js.map +1 -0
- package/{controls → dist/controls}/slot-services.d.ts +25 -0
- package/dist/controls/slot-services.js +155 -0
- package/dist/controls/slot-services.js.map +1 -0
- package/{controls → dist/controls}/slot.js +42 -24
- package/dist/controls/slot.js.map +1 -0
- package/{controls → dist/controls}/table/index.js +1 -1
- package/dist/controls/table/index.js.map +1 -0
- package/{controls → dist/controls}/table/prod.js +3 -3
- package/dist/controls/table/prod.js.map +1 -0
- package/{controls → dist/controls}/table/refs.js +13 -2
- package/dist/controls/table/refs.js.map +1 -0
- package/{controls → dist/controls}/table/stored.js +1 -1
- package/dist/controls/table/stored.js.map +1 -0
- package/{controls → dist/controls}/table/table-editor.js +51 -48
- package/dist/controls/table/table-editor.js.map +1 -0
- package/{controls → dist/controls}/table/table-link.js +3 -3
- package/dist/controls/table/table-link.js.map +1 -0
- package/{controls → dist/controls}/table/table.js +3 -3
- package/dist/controls/table/table.js.map +1 -0
- package/{controls → dist/controls}/text.d.ts +2 -2
- package/{controls → dist/controls}/text.js +78 -43
- package/dist/controls/text.js.map +1 -0
- package/dist/controls/unknown-value.d.ts +17 -0
- package/dist/controls/unknown-value.js +66 -0
- package/dist/controls/unknown-value.js.map +1 -0
- package/dist/core/core.d.ts +63 -0
- package/dist/core/core.js +171 -0
- package/dist/core/core.js.map +1 -0
- package/dist/core/facets.d.ts +347 -0
- package/dist/core/facets.js +334 -0
- package/dist/core/facets.js.map +1 -0
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.js +3 -0
- package/{engine → dist/engine}/array.js +34 -21
- package/dist/engine/array.js.map +1 -0
- package/{engine → dist/engine}/bits.js +1 -1
- package/dist/engine/bits.js.map +1 -0
- package/{engine → dist/engine}/breadcrumb.d.ts +3 -3
- package/{engine → dist/engine}/breadcrumb.js +12 -36
- package/dist/engine/breadcrumb.js.map +1 -0
- package/{engine → dist/engine}/expand.d.ts +2 -4
- package/{engine → dist/engine}/expand.js +5 -22
- package/dist/engine/expand.js.map +1 -0
- package/{engine → dist/engine}/field-list.js +1 -1
- package/dist/engine/field-list.js.map +1 -0
- package/{engine → dist/engine}/field-shell.js +249 -121
- package/dist/engine/field-shell.js.map +1 -0
- package/{engine → dist/engine}/frame.d.ts +3 -1
- package/{engine → dist/engine}/frame.js +16 -14
- package/dist/engine/frame.js.map +1 -0
- package/{engine → dist/engine}/group-summary.d.ts +2 -1
- package/{engine → dist/engine}/group-summary.js +7 -3
- package/dist/engine/group-summary.js.map +1 -0
- package/{engine → dist/engine}/grouping.d.ts +19 -5
- package/{engine → dist/engine}/grouping.js +193 -21
- package/dist/engine/grouping.js.map +1 -0
- package/{engine → dist/engine}/item-list.d.ts +11 -1
- package/{engine → dist/engine}/item-list.js +35 -13
- package/dist/engine/item-list.js.map +1 -0
- package/{engine → dist/engine}/kit-field.js +45 -10
- package/dist/engine/kit-field.js.map +1 -0
- package/{engine → dist/engine}/schema-form.d.ts +27 -2
- package/{engine → dist/engine}/schema-form.js +182 -40
- package/dist/engine/schema-form.js.map +1 -0
- package/{engine → dist/engine}/slot.js +5 -15
- package/dist/engine/slot.js.map +1 -0
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -0
- package/{kit.css → dist/kit.css} +19 -0
- package/{lib → dist/lib}/cn.js +7 -4
- package/dist/lib/cn.js.map +1 -0
- package/{lib → dist/lib}/columns.js +4 -1
- package/dist/lib/columns.js.map +1 -0
- package/{lib → dist/lib}/frames.js +2 -2
- package/dist/lib/frames.js.map +1 -0
- package/dist/lib/icon-image.d.ts +10 -0
- package/dist/lib/icon-image.js +8 -0
- package/dist/lib/icon-image.js.map +1 -0
- package/{lib → dist/lib}/icons.js +4 -3
- package/dist/lib/icons.js.map +1 -0
- package/dist/lib/input-modality.d.ts +11 -0
- package/dist/lib/input-modality.js +47 -0
- package/dist/lib/input-modality.js.map +1 -0
- package/dist/lib/key-event.d.ts +11 -0
- package/dist/lib/key-event.js +16 -0
- package/dist/lib/key-event.js.map +1 -0
- package/{lib → dist/lib}/path.js +4 -2
- package/dist/lib/path.js.map +1 -0
- package/{lib → dist/lib}/schema.d.ts +34 -3
- package/{lib → dist/lib}/schema.js +110 -13
- package/dist/lib/schema.js.map +1 -0
- package/{lib → dist/lib}/utils.js +1 -1
- package/dist/lib/utils.js.map +1 -0
- package/{lib → dist/lib}/validate.d.ts +11 -1
- package/{lib → dist/lib}/validate.js +85 -11
- package/dist/lib/validate.js.map +1 -0
- package/dist/library/analysis.d.ts +23 -0
- package/dist/library/analysis.js +160 -0
- package/dist/library/analysis.js.map +1 -0
- package/dist/library/catalog.d.ts +57 -0
- package/dist/library/catalog.js +307 -0
- package/dist/library/catalog.js.map +1 -0
- package/dist/library/coreNotes.d.ts +8 -0
- package/dist/library/coreNotes.js +111 -0
- package/dist/library/coreNotes.js.map +1 -0
- package/dist/library/coverage.d.ts +40 -0
- package/dist/library/coverage.js +59 -0
- package/dist/library/coverage.js.map +1 -0
- package/dist/library/entries/advanced.entries.d.ts +2 -0
- package/dist/library/entries/advanced.entries.js +6579 -0
- package/dist/library/entries/advanced.entries.js.map +1 -0
- package/dist/library/entries/commerce.entries.d.ts +2 -0
- package/dist/library/entries/commerce.entries.js +4140 -0
- package/dist/library/entries/commerce.entries.js.map +1 -0
- package/dist/library/entries/company.entries.d.ts +2 -0
- package/dist/library/entries/company.entries.js +2731 -0
- package/dist/library/entries/company.entries.js.map +1 -0
- package/dist/library/entries/conversion.entries.d.ts +2 -0
- package/dist/library/entries/conversion.entries.js +3707 -0
- package/dist/library/entries/conversion.entries.js.map +1 -0
- package/dist/library/entries/data.entries.d.ts +7 -0
- package/dist/library/entries/data.entries.js +4613 -0
- package/dist/library/entries/data.entries.js.map +1 -0
- package/dist/library/entries/events.entries.d.ts +2 -0
- package/dist/library/entries/events.entries.js +3428 -0
- package/dist/library/entries/events.entries.js.map +1 -0
- package/dist/library/entries/features.entries.d.ts +2 -0
- package/dist/library/entries/features.entries.js +3157 -0
- package/dist/library/entries/features.entries.js.map +1 -0
- package/dist/library/entries/heroes.entries.d.ts +2 -0
- package/dist/library/entries/heroes.entries.js +3401 -0
- package/dist/library/entries/heroes.entries.js.map +1 -0
- package/dist/library/entries/index.d.ts +3 -0
- package/dist/library/entries/index.js +35 -0
- package/dist/library/entries/index.js.map +1 -0
- package/dist/library/entries/listings.entries.d.ts +2 -0
- package/dist/library/entries/listings.entries.js +2976 -0
- package/dist/library/entries/listings.entries.js.map +1 -0
- package/dist/library/entries/longform.entries.d.ts +2 -0
- package/dist/library/entries/longform.entries.js +4227 -0
- package/dist/library/entries/longform.entries.js.map +1 -0
- package/dist/library/entries/media.entries.d.ts +2 -0
- package/dist/library/entries/media.entries.js +2781 -0
- package/dist/library/entries/media.entries.js.map +1 -0
- package/dist/library/entries/navigation.entries.d.ts +2 -0
- package/dist/library/entries/navigation.entries.js +4011 -0
- package/dist/library/entries/navigation.entries.js.map +1 -0
- package/dist/library/entries/pricing.entries.d.ts +2 -0
- package/dist/library/entries/pricing.entries.js +2383 -0
- package/dist/library/entries/pricing.entries.js.map +1 -0
- package/dist/library/entries/social-proof.entries.d.ts +2 -0
- package/dist/library/entries/social-proof.entries.js +2297 -0
- package/dist/library/entries/social-proof.entries.js.map +1 -0
- package/dist/library/examples/bento.d.ts +92 -0
- package/dist/library/examples/bento.js +201 -0
- package/dist/library/examples/bento.js.map +1 -0
- package/dist/library/examples/blocks.d.ts +14 -0
- package/dist/library/examples/blocks.js +313 -0
- package/dist/library/examples/blocks.js.map +1 -0
- package/dist/library/examples/faq.d.ts +28 -0
- package/dist/library/examples/faq.js +230 -0
- package/dist/library/examples/faq.js.map +1 -0
- package/dist/library/examples/hero.d.ts +43 -0
- package/dist/library/examples/hero.js +222 -0
- package/dist/library/examples/hero.js.map +1 -0
- package/dist/library/examples/index.d.ts +36 -0
- package/dist/library/examples/index.js +109 -0
- package/dist/library/examples/index.js.map +1 -0
- package/dist/library/examples/journalStory.d.ts +93 -0
- package/dist/library/examples/journalStory.js +338 -0
- package/dist/library/examples/journalStory.js.map +1 -0
- package/dist/library/examples/megaMenu.d.ts +134 -0
- package/dist/library/examples/megaMenu.js +442 -0
- package/dist/library/examples/megaMenu.js.map +1 -0
- package/dist/library/examples/pricing.d.ts +103 -0
- package/dist/library/examples/pricing.js +479 -0
- package/dist/library/examples/pricing.js.map +1 -0
- package/dist/library/examples/tabs.d.ts +87 -0
- package/dist/library/examples/tabs.js +180 -0
- package/dist/library/examples/tabs.js.map +1 -0
- package/dist/library/export.d.ts +42 -0
- package/dist/library/export.js +80 -0
- package/dist/library/export.js.map +1 -0
- package/dist/library/index.d.ts +13 -0
- package/dist/library/index.js +6 -0
- package/dist/library/kit-catalog.json +1510 -0
- package/dist/library/types.d.ts +42 -0
- package/dist/library/types.js +0 -0
- package/{schema → dist/schema}/adapters.js +1 -2
- package/dist/schema/adapters.js.map +1 -0
- package/{schema → dist/schema}/help.d.ts +2 -0
- package/{schema → dist/schema}/help.js +6 -4
- package/dist/schema/help.js.map +1 -0
- package/{schema → dist/schema}/scale.js +1 -1
- package/dist/schema/scale.js.map +1 -0
- package/{schema → dist/schema}/sources.js +1 -1
- package/dist/schema/sources.js.map +1 -0
- package/{schema → dist/schema}/table.js +11 -10
- package/dist/schema/table.js.map +1 -0
- package/{schema → dist/schema}/types.d.ts +29 -1
- package/{schema → dist/schema}/types.js +1 -1
- package/dist/schema/types.js.map +1 -0
- package/dist/styles.css +2 -0
- package/dist/table/table-view.d.ts +14 -0
- package/dist/table/table-view.js +140 -0
- package/dist/table/table-view.js.map +1 -0
- package/dist/table/table.css +73 -0
- package/dist/testing/corpus.d.ts +63 -0
- package/dist/testing/corpus.js +129 -0
- package/dist/testing/corpus.js.map +1 -0
- package/dist/testing/test-form.d.ts +11 -0
- package/dist/testing/test-form.js +38 -0
- package/dist/testing/test-form.js.map +1 -0
- package/dist/theme.css +345 -0
- package/dist/theme.d.ts +22 -0
- package/dist/theme.js +43 -0
- package/dist/theme.js.map +1 -0
- package/dist/tokens.css +542 -0
- package/dist/types.js +0 -0
- package/{ui → dist/ui}/action-tray.d.ts +1 -1
- package/{ui → dist/ui}/action-tray.js +20 -19
- package/dist/ui/action-tray.js.map +1 -0
- package/dist/ui/autocomplete.d.ts +30 -0
- package/dist/ui/autocomplete.js +139 -0
- package/dist/ui/autocomplete.js.map +1 -0
- package/{ui → dist/ui}/button.d.ts +3 -3
- package/{ui → dist/ui}/button.js +6 -7
- package/dist/ui/button.js.map +1 -0
- package/{ui → dist/ui}/choice-switch.js +1 -1
- package/dist/ui/choice-switch.js.map +1 -0
- package/{ui → dist/ui}/controls.js +51 -39
- package/dist/ui/controls.js.map +1 -0
- package/{ui → dist/ui}/display.d.ts +10 -3
- package/{ui → dist/ui}/display.js +57 -46
- package/dist/ui/display.js.map +1 -0
- package/{ui → dist/ui}/expanded-editor-modal.d.ts +2 -2
- package/{ui → dist/ui}/expanded-editor-modal.js +6 -6
- package/dist/ui/expanded-editor-modal.js.map +1 -0
- package/{ui → dist/ui}/field-context.js +1 -1
- package/dist/ui/field-context.js.map +1 -0
- package/{ui → dist/ui}/floating-panel.d.ts +1 -1
- package/{ui → dist/ui}/floating-panel.js +28 -12
- package/dist/ui/floating-panel.js.map +1 -0
- package/{ui → dist/ui}/index.d.ts +4 -0
- package/dist/ui/index.js +18 -0
- package/{ui → dist/ui}/input.d.ts +1 -1
- package/{ui → dist/ui}/input.js +9 -9
- package/dist/ui/input.js.map +1 -0
- package/{ui → dist/ui}/mode-bar.js +3 -3
- package/dist/ui/mode-bar.js.map +1 -0
- package/{ui → dist/ui}/overlay.d.ts +77 -5
- package/dist/ui/overlay.js +697 -0
- package/dist/ui/overlay.js.map +1 -0
- package/{ui → dist/ui}/path-crumbs.js +37 -3
- package/dist/ui/path-crumbs.js.map +1 -0
- package/{ui → dist/ui}/presence.js +2 -2
- package/dist/ui/presence.js.map +1 -0
- package/{ui → dist/ui}/select.js +89 -87
- package/dist/ui/select.js.map +1 -0
- package/{ui → dist/ui}/shortcut-hint.js +1 -1
- package/dist/ui/shortcut-hint.js.map +1 -0
- package/dist/ui/spinner.d.ts +24 -0
- package/dist/ui/spinner.js +42 -0
- package/dist/ui/spinner.js.map +1 -0
- package/dist/ui/split-button.d.ts +32 -0
- package/dist/ui/split-button.js +60 -0
- package/dist/ui/split-button.js.map +1 -0
- package/{ui → dist/ui}/surfaces.js +1 -1
- package/dist/ui/surfaces.js.map +1 -0
- package/dist/ui/tab.d.ts +38 -0
- package/dist/ui/tab.js +87 -0
- package/dist/ui/tab.js.map +1 -0
- package/dist/ui/toast.d.ts +20 -0
- package/dist/ui/toast.js +115 -0
- package/dist/ui/toast.js.map +1 -0
- package/{ui → dist/ui}/tooltip-root.d.ts +4 -3
- package/{ui → dist/ui}/tooltip-root.js +9 -8
- package/dist/ui/tooltip-root.js.map +1 -0
- package/{ui → dist/ui}/variants.js +1 -1
- package/dist/ui/variants.js.map +1 -0
- package/package.json +77 -23
- package/adapters/icons.js.map +0 -1
- package/adapters/lossy.js +0 -233
- package/adapters/lossy.js.map +0 -1
- package/adapters/prod-types.js.map +0 -1
- package/adapters/schema.js.map +0 -1
- package/adapters/values.js.map +0 -1
- package/brand/logo.js +0 -9
- package/brand/logo.js.map +0 -1
- package/context.js.map +0 -1
- package/controls/button.js.map +0 -1
- package/controls/c1.js.map +0 -1
- package/controls/c2.js.map +0 -1
- package/controls/choice.js.map +0 -1
- package/controls/code-register.js.map +0 -1
- package/controls/code.js.map +0 -1
- package/controls/color.js.map +0 -1
- package/controls/date-register.js.map +0 -1
- package/controls/date-zone.js.map +0 -1
- package/controls/date.js.map +0 -1
- package/controls/form-picker-register.js.map +0 -1
- package/controls/form-picker.js.map +0 -1
- package/controls/icon-register.js.map +0 -1
- package/controls/icon.js.map +0 -1
- package/controls/index.js.map +0 -1
- package/controls/json-register.js.map +0 -1
- package/controls/json.js.map +0 -1
- package/controls/link.js.map +0 -1
- package/controls/location-register.js.map +0 -1
- package/controls/location.js.map +0 -1
- package/controls/media-register.js.map +0 -1
- package/controls/media.js.map +0 -1
- package/controls/number.js.map +0 -1
- package/controls/reference-register.js.map +0 -1
- package/controls/reference.js.map +0 -1
- package/controls/rich-text/blocks.d.ts +0 -28
- package/controls/rich-text/blocks.js.map +0 -1
- package/controls/rich-text/catalog.js.map +0 -1
- package/controls/rich-text/codec.js.map +0 -1
- package/controls/rich-text/component-card.js.map +0 -1
- package/controls/rich-text/control.js.map +0 -1
- package/controls/rich-text/dom.js.map +0 -1
- package/controls/rich-text/editor.js.map +0 -1
- package/controls/rich-text/floating.js.map +0 -1
- package/controls/rich-text/index.js.map +0 -1
- package/controls/rich-text/link-form.js +0 -111
- package/controls/rich-text/link-form.js.map +0 -1
- package/controls/rich-text/markdown.js.map +0 -1
- package/controls/rich-text/ops.js.map +0 -1
- package/controls/rich-text/toolbar.js.map +0 -1
- package/controls/scale.js.map +0 -1
- package/controls/slot-register.js.map +0 -1
- package/controls/slot-services.js +0 -38
- package/controls/slot-services.js.map +0 -1
- package/controls/slot.js.map +0 -1
- package/controls/table/index.js.map +0 -1
- package/controls/table/prod.js.map +0 -1
- package/controls/table/refs.js.map +0 -1
- package/controls/table/stored.js.map +0 -1
- package/controls/table/table-editor.js.map +0 -1
- package/controls/table/table-link.js.map +0 -1
- package/controls/table/table.js.map +0 -1
- package/controls/text.js.map +0 -1
- package/engine/array.js.map +0 -1
- package/engine/bits.js.map +0 -1
- package/engine/breadcrumb.js.map +0 -1
- package/engine/expand.js.map +0 -1
- package/engine/field-list.js.map +0 -1
- package/engine/field-shell.js.map +0 -1
- package/engine/frame.js.map +0 -1
- package/engine/group-summary.js.map +0 -1
- package/engine/grouping.js.map +0 -1
- package/engine/item-list.js.map +0 -1
- package/engine/kit-field.js.map +0 -1
- package/engine/schema-form.js.map +0 -1
- package/engine/slot.js.map +0 -1
- package/index.js +0 -55
- package/index.js.map +0 -1
- package/lib/cn.js.map +0 -1
- package/lib/columns.js.map +0 -1
- package/lib/frames.js.map +0 -1
- package/lib/icons.js.map +0 -1
- package/lib/path.js.map +0 -1
- package/lib/schema.js.map +0 -1
- package/lib/utils.js.map +0 -1
- package/lib/validate.js.map +0 -1
- package/schema/adapters.js.map +0 -1
- package/schema/help.js.map +0 -1
- package/schema/scale.js.map +0 -1
- package/schema/sources.js.map +0 -1
- package/schema/table.js.map +0 -1
- package/schema/types.js.map +0 -1
- package/ui/action-tray.js.map +0 -1
- package/ui/button.js.map +0 -1
- package/ui/choice-switch.js.map +0 -1
- package/ui/controls.js.map +0 -1
- package/ui/display.js.map +0 -1
- package/ui/expanded-editor-modal.js.map +0 -1
- package/ui/field-context.js.map +0 -1
- package/ui/floating-panel.js.map +0 -1
- package/ui/index.js +0 -13
- package/ui/input.js.map +0 -1
- package/ui/mode-bar.js.map +0 -1
- package/ui/overlay.js +0 -378
- package/ui/overlay.js.map +0 -1
- package/ui/path-crumbs.js.map +0 -1
- package/ui/presence.js.map +0 -1
- package/ui/select.js.map +0 -1
- package/ui/shortcut-hint.js.map +0 -1
- package/ui/surfaces.js.map +0 -1
- package/ui/tooltip-root.js.map +0 -1
- package/ui/variants.js.map +0 -1
- /package/{_virtual → dist/_virtual}/_rolldown/runtime.js +0 -0
- /package/{adapters → dist/adapters}/icons.d.ts +0 -0
- /package/{brand → dist/brand}/logo.d.ts +0 -0
- /package/{controls → dist/controls}/c1.d.ts +0 -0
- /package/{controls → dist/controls}/c2.d.ts +0 -0
- /package/{controls → dist/controls}/code-register.d.ts +0 -0
- /package/{controls → dist/controls}/code.d.ts +0 -0
- /package/{controls → dist/controls}/color.d.ts +0 -0
- /package/{controls → dist/controls}/date-register.d.ts +0 -0
- /package/{controls → dist/controls}/date-zone.d.ts +0 -0
- /package/{controls → dist/controls}/date.d.ts +0 -0
- /package/{controls → dist/controls}/form-picker-register.d.ts +0 -0
- /package/{controls → dist/controls}/form-picker.d.ts +0 -0
- /package/{controls → dist/controls}/icon-register.d.ts +0 -0
- /package/{controls → dist/controls}/json-register.d.ts +0 -0
- /package/{controls → dist/controls}/json.d.ts +0 -0
- /package/{controls → dist/controls}/link.d.ts +0 -0
- /package/{controls → dist/controls}/location-register.d.ts +0 -0
- /package/{controls → dist/controls}/location.d.ts +0 -0
- /package/{controls → dist/controls}/media-register.d.ts +0 -0
- /package/{controls → dist/controls}/number.d.ts +0 -0
- /package/{controls → dist/controls}/reference-register.d.ts +0 -0
- /package/{controls → dist/controls}/rich-text/index.d.ts +0 -0
- /package/{controls → dist/controls}/rich-text/link-form.d.ts +0 -0
- /package/{controls → dist/controls}/rich-text/markdown.d.ts +0 -0
- /package/{controls → dist/controls}/rich-text/ops.d.ts +0 -0
- /package/{controls → dist/controls}/scale.d.ts +0 -0
- /package/{controls → dist/controls}/slot-register.d.ts +0 -0
- /package/{controls → dist/controls}/slot.d.ts +0 -0
- /package/{controls → dist/controls}/table/index.d.ts +0 -0
- /package/{controls → dist/controls}/table/prod.d.ts +0 -0
- /package/{controls → dist/controls}/table/refs.d.ts +0 -0
- /package/{controls → dist/controls}/table/stored.d.ts +0 -0
- /package/{controls → dist/controls}/table/table-editor.d.ts +0 -0
- /package/{controls → dist/controls}/table/table-link.d.ts +0 -0
- /package/{controls → dist/controls}/table/table.d.ts +0 -0
- /package/{engine → dist/engine}/array.d.ts +0 -0
- /package/{engine → dist/engine}/bits.d.ts +0 -0
- /package/{engine → dist/engine}/field-list.d.ts +0 -0
- /package/{engine → dist/engine}/field-shell.d.ts +0 -0
- /package/{engine → dist/engine}/kit-field.d.ts +0 -0
- /package/{engine → dist/engine}/slot.d.ts +0 -0
- /package/{index.d.ts → dist/index.d.ts} +0 -0
- /package/{lib → dist/lib}/cn.d.ts +0 -0
- /package/{lib → dist/lib}/columns.d.ts +0 -0
- /package/{lib → dist/lib}/frames.d.ts +0 -0
- /package/{lib → dist/lib}/icons.d.ts +0 -0
- /package/{lib → dist/lib}/path.d.ts +0 -0
- /package/{lib → dist/lib}/utils.d.ts +0 -0
- /package/{schema → dist/schema}/adapters.d.ts +0 -0
- /package/{schema → dist/schema}/scale.d.ts +0 -0
- /package/{schema → dist/schema}/sources.d.ts +0 -0
- /package/{schema → dist/schema}/table.d.ts +0 -0
- /package/{types.d.ts → dist/types.d.ts} +0 -0
- /package/{ui → dist/ui}/choice-switch.d.ts +0 -0
- /package/{ui → dist/ui}/controls.d.ts +0 -0
- /package/{ui → dist/ui}/field-context.d.ts +0 -0
- /package/{ui → dist/ui}/mode-bar.d.ts +0 -0
- /package/{ui → dist/ui}/path-crumbs.d.ts +0 -0
- /package/{ui → dist/ui}/presence.d.ts +0 -0
- /package/{ui → dist/ui}/select.d.ts +0 -0
- /package/{ui → dist/ui}/shortcut-hint.d.ts +0 -0
- /package/{ui → dist/ui}/surfaces.d.ts +0 -0
- /package/{ui → dist/ui}/variants.d.ts +0 -0
package/ui/button.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"button.js","names":[],"sources":["../../src/kit/ui/button.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Tooltip as TooltipPrimitive } from \"@base-ui/react/tooltip\";\nimport { IconLoader2, IconPlus } from \"@tabler/icons-react\";\nimport { cn } from \"../lib/cn\";\nimport { SPARKLE_PATH } from \"../brand/logo\";\nimport { TooltipLayer, TooltipRoot } from \"./tooltip-root\";\nimport { variants, type VariantProps } from \"./variants\";\n\n/**\n * Button: the only button in the kit.\n * Heights: xs 24 · sm 28 · md 32 (default) · lg 36 · xl 40. Radius 6.\n * Variants: primary (ink) · accent (violet, reserved for the ONE create action per screen)\n * secondary (bordered) · ghost · soft · danger · danger-ghost · link · ai (gradient sparkle)\n * The keyboard focus ring is the global :focus-visible outline, suppressed under pointer modality (DESIGN.md 3.7).\n */\nexport const buttonVariants = variants(\n \"relative inline-flex items-center justify-center gap-1.5 whitespace-nowrap font-medium tracking-[-0.01em] select-none transition-[background-color,border-color,color,box-shadow,opacity] duration-150 ease-out disabled:pointer-events-none disabled:opacity-45 [&_svg]:shrink-0 [&_svg]:opacity-90\",\n {\n variants: {\n variant: {\n primary:\n \"bg-kit-inverse text-kit-fg-inverse shadow-[var(--kit-shadow-button-primary)] hover:bg-kit-inverse-hover active:bg-kit-inverse\",\n accent: \"bg-kit-accent text-kit-accent-on shadow-kit-xs hover:bg-kit-accent-hover\",\n secondary: \"border border-kit-line-strong bg-kit-control-bg text-kit-fg shadow-kit-xs hover:bg-kit-subtle active:bg-kit-hover\",\n ghost: \"text-kit-fg-2 hover:bg-kit-hover hover:text-kit-fg active:bg-kit-selected\",\n soft: \"bg-kit-muted text-kit-fg hover:bg-kit-selected\",\n danger: \"bg-kit-danger text-kit-danger-on shadow-kit-xs hover:brightness-95\",\n \"danger-ghost\": \"text-kit-danger-fg hover:bg-kit-danger-soft\",\n link: \"text-kit-accent-fg underline-offset-4 hover:underline px-0 h-auto active:scale-100\",\n ai: \"border border-kit-line bg-kit-control-bg text-kit-fg shadow-kit-xs hover:border-kit-accent-line hover:bg-kit-accent-softer\",\n },\n size: {\n xs: \"h-6 rounded-kit-md px-2 text-kit-xs [&_svg]:size-3.5\",\n sm: \"h-7 rounded-kit-md px-2.5 text-kit-sm [&_svg]:size-3.5\",\n md: \"h-8 rounded-kit-md px-3 text-kit-sm [&_svg]:size-4\",\n lg: \"h-9 rounded-kit-md px-3.5 text-kit-base [&_svg]:size-4\",\n xl: \"h-10 rounded-kit-md px-4 text-kit-base [&_svg]:size-[18px]\",\n },\n },\n compoundVariants: [{ variant: \"link\", className: \"h-auto px-0\" }],\n defaultVariants: { variant: \"secondary\", size: \"md\" },\n },\n);\n\n/* .btn-solid (V2): in dark a disabled primary/accent takes the solid disabled pair instead of the opacity dim. */\nconst SOLID_DISABLED = \"[.dark_&]:disabled:bg-[#2a2a2d] [.dark_&]:disabled:text-[#9e9ea1] [.dark_&]:disabled:opacity-100 [.dark_&]:disabled:shadow-none\";\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {\n /** Render the single child element (a link, say) with the button's classes and props. */\n asChild?: boolean;\n loading?: boolean;\n leftIcon?: React.ReactNode;\n rightIcon?: React.ReactNode;\n}\n\ntype ChildProps = { className?: string; ref?: React.Ref<unknown> };\n\nfunction mergeRefs<T>(...refs: (React.Ref<T> | undefined)[]) {\n return (node: T | null) => {\n for (const ref of refs) {\n if (typeof ref === \"function\") ref(node);\n else if (ref) (ref as React.RefObject<T | null>).current = node;\n }\n };\n}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild, loading, leftIcon, rightIcon, children, disabled, ...props }, ref) => {\n const classes = cn(buttonVariants({ variant, size }), (variant === \"primary\" || variant === \"accent\") && SOLID_DISABLED, className);\n if (asChild && React.isValidElement<ChildProps>(children)) {\n return React.cloneElement(children, {\n ...props,\n ...children.props,\n className: cn(classes, children.props.className),\n ref: mergeRefs(ref as React.Ref<unknown>, children.props.ref),\n });\n }\n return (\n <button ref={ref} type={props.type ?? \"button\"} disabled={disabled || loading} aria-busy={loading || undefined} className={classes} {...props}>\n {loading ? <IconLoader2 className=\"animate-spin\" aria-hidden /> : leftIcon}\n {variant === \"ai\" && !leftIcon && !loading ? <Sparkle /> : null}\n {children}\n {rightIcon}\n </button>\n );\n },\n);\nButton.displayName = \"Button\";\n\n/** Square icon-only button. Always pass `label` (used for aria-label + tooltip). */\nexport const iconButtonVariants = variants(\n \"relative inline-flex items-center justify-center shrink-0 text-kit-fg-2 transition-colors duration-150 hover:bg-kit-hover hover:text-kit-fg active:scale-[0.96] disabled:opacity-40 disabled:pointer-events-none data-[active=true]:bg-kit-selected data-[active=true]:text-kit-fg data-[popup-open]:bg-kit-selected data-[popup-open]:text-kit-fg\",\n {\n variants: {\n size: {\n xs: \"size-6 rounded-kit-md [&_svg]:size-3.5\",\n sm: \"size-7 rounded-kit-md [&_svg]:size-4\",\n md: \"size-8 rounded-kit-md [&_svg]:size-4\",\n lg: \"size-9 rounded-kit-md [&_svg]:size-[18px]\",\n },\n variant: {\n ghost: \"\",\n outline: \"border border-kit-line bg-kit-control-bg shadow-kit-xs hover:border-kit-line-strong\",\n soft: \"bg-kit-muted\",\n },\n },\n defaultVariants: { size: \"md\", variant: \"ghost\" },\n },\n);\n\n/**\n * a11y: true while rendering inside a tooltip (or a surface that manages its own hints), so an IconButton nested\n * there doesn't add a second tooltip. Provided by HintTooltip and overlay.tsx's <Tooltip>.\n */\nexport const TooltipScope = React.createContext(false);\n\n/**\n * The plain ink hint (DESIGN.md 8.23: top, 6px offset, 8px collision padding, portalled, z 90, 350ms). The child\n * element is the trigger and must take a ref and DOM props. input, display and action-tray use it so they never\n * import overlay.tsx; overlay's <Tooltip> adds the shortcut slot on top of the same layer.\n */\nexport function HintTooltip({\n content,\n side = \"top\",\n delay = 350,\n children,\n}: {\n content: React.ReactNode;\n side?: \"top\" | \"bottom\" | \"left\" | \"right\";\n delay?: number;\n children: React.ReactElement;\n}) {\n return (\n <TooltipScope.Provider value>\n <TooltipRoot>\n <TooltipPrimitive.Trigger delay={delay} render={children} />\n <TooltipLayer side={side}>\n <span className=\"line-clamp-[8] min-w-0 whitespace-normal [overflow-wrap:anywhere]\">{content}</span>\n </TooltipLayer>\n </TooltipRoot>\n </TooltipScope.Provider>\n );\n}\n\nexport interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof iconButtonVariants> {\n label: string;\n active?: boolean;\n /** Hover/focus hint. Defaults to `label`; pass `false` to opt out, or a node to customise. */\n tooltip?: React.ReactNode | false;\n tooltipSide?: \"top\" | \"bottom\" | \"left\" | \"right\";\n}\n\nexport const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(\n ({ className, size, variant, label, active, children, tooltip, tooltipSide = \"top\", ...props }, ref) => {\n const inTooltip = React.useContext(TooltipScope);\n const btn = (\n <button\n ref={ref}\n type=\"button\"\n aria-label={label}\n data-active={active ? \"true\" : undefined}\n className={cn(iconButtonVariants({ size, variant }), className)}\n {...props}\n >\n {children}\n </button>\n );\n // Every icon-only button gets a visible hint on hover AND keyboard focus (brief §11), unless a\n // parent tooltip already provides one or the caller opted out.\n if (inTooltip || tooltip === false || !label) return btn;\n return (\n <HintTooltip content={tooltip ?? label} side={tooltipSide}>\n {btn}\n </HintTooltip>\n );\n },\n);\nIconButton.displayName = \"IconButton\";\n\n/** The AI sparkle in the official brand gradient. Used everywhere AI appears. */\nexport function Sparkle({ className, size = 16 }: { className?: string; size?: number }) {\n const id = React.useId().replace(/:/g, \"\");\n return (\n <svg width={size} height={size} viewBox=\"2 2 16 16\" className={cn(\"shrink-0\", className)} aria-hidden>\n <defs>\n <linearGradient id={`sp${id}`} x1=\"6.89\" y1=\"4.59\" x2=\"18\" y2=\"23.67\" gradientUnits=\"userSpaceOnUse\">\n <stop offset=\"0.0817\" style={{ stopColor: \"var(--kit-brand-violet)\" }} />\n <stop offset=\"0.4667\" style={{ stopColor: \"var(--kit-brand-coral)\" }} />\n <stop offset=\"1\" style={{ stopColor: \"var(--kit-brand-rose)\" }} />\n </linearGradient>\n </defs>\n <path d={SPARKLE_PATH} fill={`url(#sp${id})`} />\n </svg>\n );\n}\n\n/** D15 progressive disclosure: \"+ Add a message\" / \"+ Limit to specific sites\": reveals an optional input. */\nexport function RevealLink({ className, children, ...props }: React.ButtonHTMLAttributes<HTMLButtonElement>) {\n return (\n <button\n type=\"button\"\n className={cn(\n \"inline-flex h-7 items-center gap-1 rounded-kit-md text-kit-sm font-medium text-kit-fg-2 transition-colors hover:text-kit-fg [&_svg]:size-3.5\",\n className,\n )}\n {...props}\n >\n <IconPlus stroke={2} aria-hidden />\n {children}\n </button>\n );\n}\n"],"mappings":"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"}
|
package/ui/choice-switch.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"choice-switch.js","names":[],"sources":["../../src/kit/ui/choice-switch.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Segmented } from \"./controls\";\nimport { Select, nodeText } from \"./select\";\n\n/* ── Pickers: segmented vs dropdown (D46) ──────────────────────────────────\n A tab-style switch is for 2–3 short options people flip often. Four or more options, or labels that would wrap or\n truncate in a 340px inspector, become a dropdown (the D34 Select, with a one-line description where an option\n isn't self-explanatory). `fitsSegmented` is the single test; `ChoiceSwitch` applies it for dynamic lists\n (variants, schema options, presets) so call sites never have to count. */\n\n/** Most options a segmented switch may hold. */\nexport const SEGMENTED_MAX = 3;\n/**\n * Longest label (characters) that stays on one line when the row shares a 340px inspector:\n * two options get ~134px each (about 18 characters at 13px), three get ~84px (about 12).\n */\nexport const SEGMENTED_MAX_LABEL = { 2: 18, 3: 12 } as const;\n\nexport function fitsSegmented(labels: React.ReactNode[]): boolean {\n const n = labels.length;\n if (n < 2 || n > SEGMENTED_MAX) return false;\n const max = SEGMENTED_MAX_LABEL[n as 2 | 3];\n return labels.every((l) => nodeText(l).trim().length <= max);\n}\n\nexport interface ChoiceSwitchItem<T extends string> {\n value: T;\n label: React.ReactNode;\n /** one line under the option in the dropdown; ignored while it renders as a segmented switch */\n description?: string;\n icon?: React.ReactNode;\n disabled?: boolean;\n}\n\nexport function ChoiceSwitch<T extends string>({\n value,\n onChange,\n items,\n \"aria-label\": ariaLabel,\n size = \"sm\",\n layout = \"auto\",\n disabled,\n className,\n segmentedClassName,\n selectClassName,\n layoutId,\n placeholder,\n}: {\n value: T;\n onChange: (v: T) => void;\n items: ChoiceSwitchItem<T>[];\n \"aria-label\"?: string;\n size?: \"sm\" | \"md\";\n /** \"auto\" applies D46; force a look only when a design reason overrides the rule */\n layout?: \"auto\" | \"segmented\" | \"dropdown\";\n disabled?: boolean;\n /** applied to whichever control renders */\n className?: string;\n segmentedClassName?: string;\n selectClassName?: string;\n layoutId?: string;\n placeholder?: string;\n}) {\n const segmented = layout === \"segmented\" || (layout === \"auto\" && fitsSegmented(items.map((i) => i.label)));\n if (segmented)\n return (\n <Segmented<T>\n size={size}\n aria-label={ariaLabel}\n value={value}\n onChange={(v) => !disabled && onChange(v)}\n layoutId={layoutId}\n className={[className, segmentedClassName].filter(Boolean).join(\" \") || undefined}\n items={items.map((i) => ({ value: i.value, label: i.label, icon: i.icon, disabled: disabled || i.disabled }))}\n />\n );\n return (\n <Select\n size={size}\n aria-label={ariaLabel}\n value={value || undefined}\n disabled={disabled}\n placeholder={placeholder}\n onValueChange={(v) => onChange(v as T)}\n className={[className, selectClassName].filter(Boolean).join(\" \") || undefined}\n options={items.map((i) => ({ value: i.value, label: i.label, description: i.description, icon: i.icon, disabled: i.disabled }))}\n />\n );\n}\n"],"mappings":";;;;;;AAWA,IAAa,gBAAgB;;;;;AAK7B,IAAa,sBAAsB;CAAE,GAAG;CAAI,GAAG;CAAI;AAEnD,SAAgB,cAAc,QAAoC;CAChE,MAAM,IAAI,OAAO;AACjB,KAAI,IAAI,KAAK,IAAA,EAAmB,QAAO;CACvC,MAAM,MAAM,oBAAoB;AAChC,QAAO,OAAO,OAAO,MAAM,SAAS,EAAE,CAAC,MAAM,CAAC,UAAU,IAAI;;AAY9D,SAAgB,aAA+B,EAC7C,OACA,UACA,OACA,cAAc,WACd,OAAO,MACP,SAAS,QACT,UACA,WACA,oBACA,iBACA,UACA,eAgBC;AAED,KADkB,WAAW,eAAgB,WAAW,UAAU,cAAc,MAAM,KAAK,MAAM,EAAE,MAAM,CAAC,CAExG,QACE,oBAAC,WAAD;EACQ;EACN,cAAY;EACL;EACP,WAAW,MAAM,CAAC,YAAY,SAAS,EAAE;EAC/B;EACV,WAAW,CAAC,WAAW,mBAAmB,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI,IAAI,KAAA;EACxE,OAAO,MAAM,KAAK,OAAO;GAAE,OAAO,EAAE;GAAO,OAAO,EAAE;GAAO,MAAM,EAAE;GAAM,UAAU,YAAY,EAAE;GAAU,EAAE;EAC7G,CAAA;AAEN,QACE,oBAAC,QAAD;EACQ;EACN,cAAY;EACZ,OAAO,SAAS,KAAA;EACN;EACG;EACb,gBAAgB,MAAM,SAAS,EAAO;EACtC,WAAW,CAAC,WAAW,gBAAgB,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI,IAAI,KAAA;EACrE,SAAS,MAAM,KAAK,OAAO;GAAE,OAAO,EAAE;GAAO,OAAO,EAAE;GAAO,aAAa,EAAE;GAAa,MAAM,EAAE;GAAM,UAAU,EAAE;GAAU,EAAE;EAC/H,CAAA"}
|
package/ui/controls.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"controls.js","names":[],"sources":["../../src/kit/ui/controls.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Switch as SwitchPrimitive } from \"@base-ui/react/switch\";\nimport { Checkbox as CheckboxPrimitive } from \"@base-ui/react/checkbox\";\nimport { RadioGroup as RadioGroupPrimitive } from \"@base-ui/react/radio-group\";\nimport { Radio as RadioPrimitive } from \"@base-ui/react/radio\";\nimport { Tooltip as TooltipPrimitive } from \"@base-ui/react/tooltip\";\nimport { Slider as SliderPrimitive } from \"@base-ui/react/slider\";\nimport { ToggleGroup as ToggleGroupPrimitive } from \"@base-ui/react/toggle-group\";\nimport { Toggle as TogglePrimitive } from \"@base-ui/react/toggle\";\nimport { Progress as ProgressPrimitive } from \"@base-ui/react/progress\";\nimport { IconCheck, IconMinus } from \"@tabler/icons-react\";\nimport { AnimatePresence, motion, useReducedMotion } from \"framer-motion\";\nimport { cn } from \"../lib/cn\";\nimport { useFieldLabelledBy, useLabelFor } from \"./field-context\";\nimport { TooltipScope } from \"./button\";\nimport { useShortcutHints } from \"./shortcut-hint\";\nimport { TooltipLayer, TooltipRoot } from \"./tooltip-root\";\nimport { INK_ACTIVE } from \"./surfaces\";\n\n/* Underlines and selected pills share one spring (DESIGN.md 3.6). */\nconst PILL_SPRING = { type: \"spring\", stiffness: 520, damping: 42 } as const;\n\n/* ── Switch ─────────────────────────────────────────────────────────────── */\nexport function Switch({\n className,\n size = \"md\",\n ...props\n}: SwitchPrimitive.Root.Props & { size?: \"sm\" | \"md\" }) {\n const sm = size === \"sm\";\n const labelledBy = useFieldLabelledBy();\n const labelFor = useLabelFor(props.id);\n return (\n <SwitchPrimitive.Root\n className={cn(\n \"group relative inline-flex shrink-0 items-center rounded-full bg-kit-switch-off transition-colors duration-200 data-[checked]:bg-kit-success data-[disabled]:opacity-40\",\n sm ? \"h-4 w-7\" : \"h-5 w-9\",\n className,\n )}\n aria-labelledby={props[\"aria-labelledby\"] ?? (props[\"aria-label\"] ? undefined : (labelFor ?? (props.id ? undefined : labelledBy)))}\n {...props}\n >\n <SwitchPrimitive.Thumb\n className={cn(\n \"pointer-events-none block rounded-full bg-kit-control-thumb shadow-kit-sm transition-transform duration-200 ease-kit-spring\",\n sm ? \"size-3 translate-x-0.5 data-[checked]:translate-x-[14px]\" : \"size-4 translate-x-0.5 data-[checked]:translate-x-[18px]\",\n )}\n />\n </SwitchPrimitive.Root>\n );\n}\n\n/* ── Checkbox ───────────────────────────────────────────────────────────── */\n/** `checked` keeps V2's tri-state value: true, false or \"indeterminate\". */\nexport function Checkbox({\n className,\n checked,\n ...props\n}: Omit<CheckboxPrimitive.Root.Props, \"checked\" | \"indeterminate\"> & { checked?: boolean | \"indeterminate\" }) {\n const indeterminate = checked === \"indeterminate\";\n const labelFor = useLabelFor(props.id);\n return (\n <CheckboxPrimitive.Root\n aria-labelledby={props[\"aria-labelledby\"] ?? (props[\"aria-label\"] ? undefined : labelFor)}\n className={cn(\n \"peer flex size-4 shrink-0 items-center justify-center rounded-kit-sm border border-kit-line-strong bg-kit-control-bg shadow-kit-xs transition-colors hover:border-[var(--kit-emphasis-line)] data-[checked]:border-kit-inverse data-[checked]:bg-kit-inverse data-[indeterminate]:border-kit-inverse data-[indeterminate]:bg-kit-inverse data-[disabled]:opacity-40\",\n className,\n )}\n checked={checked === undefined ? undefined : checked === true}\n indeterminate={indeterminate}\n {...props}\n >\n <CheckboxPrimitive.Indicator className=\"text-kit-fg-inverse\">\n {indeterminate ? <IconMinus className=\"size-3\" stroke={3} /> : <IconCheck className=\"size-3\" stroke={3} />}\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n );\n}\n\n/* ── Radio ──────────────────────────────────────────────────────────────── */\nexport const RadioGroup = RadioGroupPrimitive;\nexport function Radio({ className, ...props }: RadioPrimitive.Root.Props) {\n return (\n <RadioPrimitive.Root\n className={cn(\n \"flex size-4 shrink-0 items-center justify-center rounded-full border border-kit-line-strong bg-kit-control-bg shadow-kit-xs transition-colors hover:border-[var(--kit-emphasis-line)] data-[checked]:border-kit-accent data-[disabled]:opacity-40\",\n className,\n )}\n {...props}\n >\n <RadioPrimitive.Indicator className=\"block size-2 rounded-full bg-kit-accent\" />\n </RadioPrimitive.Root>\n );\n}\n\n/** Large selectable card used for choices (plans, project kinds, roles). */\nexport function ChoiceCard({\n selected,\n onSelect,\n icon,\n title,\n description,\n badge,\n className,\n children,\n}: {\n selected: boolean;\n onSelect: () => void;\n icon?: React.ReactNode;\n title: React.ReactNode;\n description?: React.ReactNode;\n badge?: React.ReactNode;\n className?: string;\n children?: React.ReactNode;\n}) {\n return (\n <button\n type=\"button\"\n onClick={onSelect}\n aria-pressed={selected}\n className={cn(\n \"group relative flex w-full flex-col gap-1.5 rounded-kit-lg border bg-kit-control-bg px-3 py-2.5 text-left transition-[border-color,box-shadow,background-color] duration-150 focus-visible:outline-offset-[-2px]\", // inset: option cards often sit in a clipped, gapless list\n selected\n ? \"border-[var(--kit-emphasis-line)] shadow-kit-ring-field\"\n : \"border-kit-line hover:border-kit-line-strong hover:shadow-kit-sm\",\n className,\n )}\n >\n <div className=\"flex items-start gap-3\">\n {icon ? (\n <span className={cn(\"mt-0.5 flex shrink-0 items-center justify-center text-kit-fg-2 [&_svg]:size-4\", selected && \"text-kit-fg\")}>\n {icon}\n </span>\n ) : null}\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2 text-kit-sm font-medium text-kit-fg\">\n {title}\n {badge}\n </div>\n {description ? <p className=\"mt-0.5 text-[13px] leading-[18px] text-kit-fg-2\">{description}</p> : null}\n </div>\n <span\n className={cn(\n \"mt-0.5 flex size-4 shrink-0 items-center justify-center rounded-full border transition-colors\",\n selected ? \"border-kit-inverse bg-kit-inverse text-kit-fg-inverse\" : \"border-kit-line-strong\",\n )}\n >\n {selected ? <IconCheck className=\"size-2.5\" stroke={3.5} /> : null}\n </span>\n </div>\n {children}\n </button>\n );\n}\n\n/** D15: 2–4 choices → one hairline list of compact rows. Wrap <ChoiceCard>s in it; they lose their own card chrome. */\nexport function ChoiceList({ className, children, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n role=\"group\"\n className={cn(\n \"flex flex-col divide-y divide-kit-line-subtle overflow-hidden rounded-kit-lg border border-kit-line\",\n \"[&>*]:rounded-none [&>*]:border-0 [&>*]:shadow-none [&>*]:hover:shadow-none [&>*]:hover:bg-kit-hover [&>[aria-pressed=true]]:bg-kit-selected [&>[aria-pressed=true]]:shadow-none\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n );\n}\n\n/* ── Slider ─────────────────────────────────────────────────────────────── */\nexport function Slider({\n className,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledby,\n label,\n ...props\n}: Omit<SliderPrimitive.Root.Props<number | readonly number[]>, \"className\"> & {\n className?: string;\n /** accessible name for the thumb(s) */\n label?: string;\n}) {\n const name = ariaLabel ?? label;\n const v = props.value ?? props.defaultValue ?? [0];\n const thumbs = Array.isArray(v) ? v.length : 1;\n return (\n <SliderPrimitive.Root className={cn(\"w-full\", className)} {...props}>\n <SliderPrimitive.Control className=\"relative flex h-5 w-full touch-none select-none items-center\">\n {/* Figma §4.3 slider: 4px track, --fg-2 fill, 12px light thumb with a border (control-thumb lifts off the dark track) */}\n <SliderPrimitive.Track className=\"relative h-1 w-full grow overflow-hidden rounded-full bg-[var(--kit-track-line)]\">\n <SliderPrimitive.Indicator className=\"absolute h-full bg-kit-fg-2\" />\n </SliderPrimitive.Track>\n {Array.from({ length: thumbs }, (_, i) => (\n <SliderPrimitive.Thumb\n key={i}\n index={thumbs > 1 ? i : undefined}\n getAriaLabel={name ? () => name : undefined}\n aria-labelledby={name ? undefined : ariaLabelledby}\n className=\"block size-3 rounded-full border border-kit-line-strong bg-kit-control-thumb shadow-kit-md transition-transform hover:scale-110 has-[:focus-visible]:scale-110 has-[:focus-visible]:outline-2 has-[:focus-visible]:outline-offset-2 has-[:focus-visible]:outline-kit-focus-ring has-[:focus-visible]:[outline-style:solid]\"\n />\n ))}\n </SliderPrimitive.Control>\n </SliderPrimitive.Root>\n );\n}\n\n/* V2's overlay <Tooltip> (side bottom, 350ms) for collapsed and icon-only segments, built on the shared ink layer. */\nfunction SegmentTooltip({ content, shortcut, children }: { content: React.ReactNode; shortcut?: string; children: React.ReactElement }) {\n const hints = useShortcutHints();\n return (\n <TooltipScope.Provider value>\n <TooltipRoot>\n <TooltipPrimitive.Trigger delay={350} render={children} />\n <TooltipLayer side=\"bottom\">\n <span className=\"line-clamp-[8] min-w-0 whitespace-normal [overflow-wrap:anywhere]\">{content}</span>\n {shortcut && hints ? (\n <kbd data-hint=\"shortcuts\" className={cn(\"mt-px shrink-0 rounded-kit-sm px-1 font-kit-sans text-kit-2xs\", INK_ACTIVE)}>\n {shortcut}\n </kbd>\n ) : null}\n </TooltipLayer>\n </TooltipRoot>\n </TooltipScope.Provider>\n );\n}\n\n/* ── Segmented ───────────────────────────────────────────────────────────\n Two deliberate looks (founder: no \"AI-sloppy\" grey pills with counts inside):\n • variant=\"tabs\" (opt-in) — quiet text tabs, muted tabular count, 1.5px animated underline.\n Use for filters, view sections, panel tabs.\n • variant=\"toggle\" (default) — slim hairline-bordered control, subtle selected fill, no shadow.\n Use for binary/ternary switches: list|grid, light|dark, desktop|tablet|mobile.\n Pass `count` on items instead of baking numbers into labels. */\nexport type SegmentedItem<T extends string> = {\n value: T;\n label: React.ReactNode;\n icon?: React.ReactNode;\n disabled?: boolean;\n count?: number;\n tooltip?: React.ReactNode;\n shortcut?: string;\n name?: string;\n};\n\nexport function Segmented<T extends string>({\n value,\n onChange,\n items,\n size = \"md\",\n className,\n layoutId,\n iconOnly,\n collapseInactive,\n variant,\n bordered,\n \"aria-label\": ariaLabel,\n}: {\n \"aria-label\"?: string;\n value: T;\n onChange: (v: T) => void;\n items: SegmentedItem<T>[];\n /** Toggle variant: only the selected item shows its label; the others collapse to icon + tooltip. */\n collapseInactive?: boolean;\n size?: \"sm\" | \"md\";\n className?: string;\n layoutId?: string;\n iconOnly?: boolean;\n variant?: \"tabs\" | \"toggle\";\n /** tabs only: draw a hairline under the whole tab row */\n bordered?: boolean;\n}) {\n const id = React.useId();\n const v = variant ?? \"toggle\";\n const reduceMotion = useReducedMotion();\n const pillTransition = reduceMotion ? { duration: 0 } : PILL_SPRING;\n const onKey = (e: React.KeyboardEvent, i: number) => {\n const enabled = items.filter((x) => !x.disabled);\n const idx = enabled.findIndex((x) => x.value === items[i].value);\n const fwd = e.key === \"ArrowRight\" || e.key === \"ArrowDown\";\n const back = e.key === \"ArrowLeft\" || e.key === \"ArrowUp\";\n const next = fwd\n ? enabled[(idx + 1) % enabled.length]\n : back\n ? enabled[(idx - 1 + enabled.length) % enabled.length]\n : e.key === \"Home\"\n ? enabled[0]\n : e.key === \"End\"\n ? enabled[enabled.length - 1]\n : null;\n if (next) {\n e.preventDefault();\n onChange(next.value);\n // roving tabindex: keep keyboard focus on the newly selected item\n const group = (e.currentTarget as HTMLElement).closest(\"[data-segmented]\");\n requestAnimationFrame(() => group?.querySelector<HTMLElement>(`[data-seg-value=\"${CSS.escape(next.value)}\"]`)?.focus());\n }\n };\n\n if (v === \"tabs\") {\n return (\n <div role=\"tablist\" aria-label={ariaLabel} data-segmented className={cn(\"inline-flex items-center gap-5\", bordered && \"border-b border-kit-line\", className)}>\n {items.map((it, i) => {\n const active = it.value === value;\n return (\n <button\n key={it.value}\n role=\"tab\"\n type=\"button\"\n data-seg-value={it.value}\n aria-selected={active}\n tabIndex={active ? 0 : -1}\n disabled={it.disabled}\n onKeyDown={(e) => onKey(e, i)}\n onClick={() => onChange(it.value)}\n className={cn(\n \"group relative inline-flex items-center justify-center gap-1.5 whitespace-nowrap font-medium tracking-[-0.01em] transition-colors duration-150 disabled:opacity-40 [&_svg]:size-4\",\n size === \"sm\" ? \"h-7 text-kit-xs [&_svg]:size-3.5\" : \"h-8 text-kit-sm\",\n active ? \"text-kit-fg\" : \"text-kit-fg-3 hover:text-kit-fg-2\",\n )}\n >\n {it.icon}\n {iconOnly ? null : it.label}\n {typeof it.count === \"number\" ? (\n <span className={cn(\"text-kit-xs font-normal tabular-nums\", active ? \"text-kit-fg-2\" : \"text-kit-fg-4\")}>{it.count}</span>\n ) : null}\n {active ? (\n <motion.span\n layoutId={layoutId ?? `tab-${id}`}\n transition={pillTransition}\n data-seg-indicator=\"\"\n className={cn(\"absolute inset-x-0 h-[1.5px] rounded-full bg-kit-fg\", bordered ? \"-bottom-px\" : \"bottom-0\")}\n />\n ) : null}\n </button>\n );\n })}\n </div>\n );\n }\n\n return (\n /* Toggle metrics (D29, founder): container 1px border + 2px padding, 2px between items, pill radius = container (6) − 2.\n md items are 28px tall and icon-only items exactly 28×28; sm items 24px. Collapsing items keep the icon at the same\n inset in both states (6px md / 5px sm) — only the label wrapper animates its width, with the icon→label gap inside it. */\n <div role=\"radiogroup\" aria-label={ariaLabel} data-segmented className={cn(\"inline-flex items-center gap-[2px] rounded-kit-md border border-kit-line bg-kit-field-bg p-[2px]\", className)}>\n {items.map((it, i) => {\n const active = it.value === value;\n const sm = size === \"sm\";\n const hasLabel = !iconOnly && it.label !== \"\" && it.label != null;\n const showLabel = hasLabel && (!collapseInactive || active);\n const btn = (\n <button\n key={it.value}\n role=\"radio\"\n type=\"button\"\n data-seg-value={it.value}\n aria-checked={active}\n aria-label={iconOnly && typeof it.label === \"string\" ? it.label : collapseInactive ? it.name : undefined}\n tabIndex={active ? 0 : -1}\n disabled={it.disabled}\n onKeyDown={(e) => onKey(e, i)}\n onClick={() => onChange(it.value)}\n className={cn(\n \"relative inline-flex shrink-0 items-center justify-center whitespace-nowrap rounded-kit-sm font-medium transition-[color,background-color,padding] duration-150 disabled:opacity-40 [&_svg]:size-4 [&_svg]:shrink-0\",\n sm ? \"h-6 text-kit-xs [&_svg]:size-3.5\" : \"h-7 text-kit-sm\",\n iconOnly || !hasLabel\n ? sm ? \"w-6 px-0\" : \"w-7 px-0\"\n : collapseInactive\n ? sm ? (active ? \"pl-[5px] pr-2\" : \"px-[5px]\") : active ? \"pl-1.5 pr-2.5\" : \"px-1.5\"\n : sm ? \"px-2\" : \"px-2.5\",\n active ? \"text-kit-fg\" : \"text-kit-fg-3 hover:bg-kit-hover hover:text-kit-fg\",\n )}\n >\n {active ? (\n <motion.span\n layoutId={layoutId ?? `seg-${id}`}\n transition={pillTransition}\n data-seg-indicator=\"\"\n className=\"absolute inset-0 rounded-kit-sm bg-kit-selected\"\n />\n ) : null}\n <span className={cn(\"relative z-[1] inline-flex items-center\", !collapseInactive && \"gap-1.5\")}>\n {it.icon}\n {!hasLabel ? null : collapseInactive ? (\n <AnimatePresence initial={false}>\n {showLabel ? (\n <motion.span\n key=\"label\"\n initial={{ width: 0, opacity: 0 }}\n animate={{ width: \"auto\", opacity: 1 }}\n exit={{ width: 0, opacity: 0 }}\n transition={reduceMotion ? { duration: 0 } : { duration: 0.18, ease: [0.2, 0, 0, 1] }}\n className=\"inline-flex overflow-hidden\"\n >\n <span className={sm ? \"pl-1\" : \"pl-1.5\"}>{it.label}</span>\n </motion.span>\n ) : null}\n </AnimatePresence>\n ) : (\n it.label\n )}\n {typeof it.count === \"number\" ? <span className=\"text-kit-xs font-normal tabular-nums text-kit-fg-3\">{it.count}</span> : null}\n </span>\n </button>\n );\n if (collapseInactive && it.tooltip)\n return (\n <SegmentTooltip key={it.value} content={it.tooltip} shortcut={it.shortcut}>\n {btn}\n </SegmentTooltip>\n );\n return iconOnly && typeof it.label === \"string\" ? (\n <SegmentTooltip key={it.value} content={it.label}>\n {btn}\n </SegmentTooltip>\n ) : (\n btn\n );\n })}\n </div>\n );\n}\n\n/* ── Toggle group (toolbar style) ─────────────────────────────────────── */\nexport function ToggleGroup({ className, ...props }: Omit<ToggleGroupPrimitive.Props, \"className\"> & { className?: string }) {\n return (\n <ToggleGroupPrimitive\n className={cn(\"inline-flex items-center gap-px rounded-kit-md border border-kit-line bg-kit-field-bg p-[2px]\", className)}\n {...props}\n />\n );\n}\nexport function ToggleItem({ className, ...props }: Omit<TogglePrimitive.Props, \"className\"> & { className?: string }) {\n return (\n <TogglePrimitive\n className={cn(\n \"inline-flex h-6 min-w-6 items-center justify-center gap-1 rounded-kit-sm px-1.5 text-kit-xs font-medium text-kit-fg-3 transition-colors hover:bg-kit-hover hover:text-kit-fg data-[pressed]:bg-kit-selected data-[pressed]:text-kit-fg [&_svg]:size-3.5\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/* ── Progress ──────────────────────────────────────────────────────────── */\nconst progressTones = {\n success: \"bg-kit-success\",\n accent: \"bg-kit-accent\",\n warning: \"bg-kit-warning\",\n danger: \"bg-kit-danger\",\n // --bar-fill: ink in light, a quiet grey in dark (no near-white glare on a dark track)\n ink: \"bg-[var(--kit-bar-fill)]\",\n brand: \"bg-[var(--kit-bar-fill)]\",\n};\nexport function Progress({\n value,\n className,\n tone = \"success\",\n size = \"md\",\n label = \"Progress\",\n}: {\n value: number;\n className?: string;\n /** accessible name, e.g. \"AI credits used\" */\n label?: string;\n tone?: keyof typeof progressTones;\n size?: \"sm\" | \"md\";\n}) {\n const pct = Math.min(100, Math.max(0, value));\n return (\n <ProgressPrimitive.Root\n value={pct}\n aria-label={label}\n className={cn(\n \"relative w-full overflow-hidden rounded-full bg-[var(--kit-track)]\",\n size === \"sm\" ? \"h-1\" : \"h-1.5\",\n className,\n )}\n >\n <ProgressPrimitive.Indicator\n className={cn(\"block h-full rounded-full transition-[width] duration-500 ease-kit-out-soft\", progressTones[tone])}\n style={{ width: `${pct}%` }}\n />\n </ProgressPrimitive.Root>\n );\n}\n"],"mappings":"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"}
|
package/ui/display.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"display.js","names":[],"sources":["../../src/kit/ui/display.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Avatar as AvatarPrimitive } from \"@base-ui/react/avatar\";\nimport { cn } from \"../lib/cn\";\nimport { HintTooltip } from \"./button\";\n\n/* ── Badge ─────────────────────────────────────────────────────────────── */\nconst badgeTones = {\n neutral: \"bg-kit-muted text-kit-fg-2\",\n outline: \"border border-kit-line bg-kit-control-bg text-kit-fg-2\",\n accent: \"bg-kit-accent-soft text-kit-accent-fg\",\n success: \"bg-kit-success-soft text-kit-success-fg\",\n warning: \"bg-kit-warning-soft text-kit-warning-fg\",\n danger: \"bg-kit-danger-soft text-kit-danger-fg\",\n info: \"bg-kit-info-soft text-kit-info-fg\",\n // --chip-ink: calm in dark (#343437, = selected), not a white slab\n ink: \"bg-[var(--kit-chip-ink-bg)] text-[var(--kit-chip-ink-fg)]\",\n};\nconst badgeSizes = { sm: \"h-[18px] px-1.5 text-kit-2xs\", md: \"h-5 px-1.5 text-kit-xs\", lg: \"h-6 px-2 text-kit-xs\" };\nexport type BadgeTone = keyof typeof badgeTones;\nexport type BadgeSize = keyof typeof badgeSizes;\n\nexport function badgeVariants({ tone, size }: { tone?: BadgeTone | null; size?: BadgeSize | null } = {}) {\n return cn(\n \"inline-flex shrink-0 items-center gap-1 whitespace-nowrap rounded-kit-sm font-medium [&_svg]:size-3\",\n badgeTones[tone ?? \"neutral\"],\n badgeSizes[size ?? \"md\"],\n );\n}\n\nexport function Badge({\n className,\n tone,\n size,\n dot,\n children,\n ...props\n}: React.HTMLAttributes<HTMLSpanElement> & { tone?: BadgeTone | null; size?: BadgeSize | null; dot?: boolean }) {\n return (\n <span className={cn(badgeVariants({ tone, size }), className)} {...props}>\n {dot ? <span aria-hidden className=\"size-1.5 rounded-full bg-current\" /> : null}\n {children}\n </span>\n );\n}\n\n/* ── Status pill: the single source for publish states ─────────────────── */\nexport type PublishStatus =\n | \"published\"\n | \"draft\"\n | \"changed\"\n | \"held\"\n | \"scheduled\"\n | \"review\"\n | \"archived\"\n | \"error\"\n | \"building\"\n | \"live\"\n | \"offline\";\nexport const statusMap: Record<PublishStatus, { label: string; tone: BadgeTone }> = {\n published: { label: \"Published\", tone: \"success\" },\n live: { label: \"Live\", tone: \"success\" },\n draft: { label: \"Draft\", tone: \"neutral\" },\n changed: { label: \"Edited\", tone: \"warning\" },\n /** D53: live, with changes kept as draft (left out of whole-site publishes). */\n held: { label: \"Edits held\", tone: \"neutral\" },\n scheduled: { label: \"Scheduled\", tone: \"info\" },\n review: { label: \"In review\", tone: \"info\" },\n archived: { label: \"Archived\", tone: \"outline\" },\n error: { label: \"Failed\", tone: \"danger\" },\n building: { label: \"Building\", tone: \"info\" },\n offline: { label: \"Offline\", tone: \"neutral\" },\n};\nexport function StatusPill({\n status,\n label,\n className,\n size = \"md\",\n}: {\n status: PublishStatus;\n label?: string;\n className?: string;\n size?: BadgeSize;\n}) {\n const s = statusMap[status];\n return (\n <Badge tone={s.tone} size={size} className={className}>\n <span\n aria-hidden\n data-pulse={status === \"building\" || status === \"live\" ? \"\" : undefined}\n className={cn(\n \"size-1.5 rounded-full bg-current\",\n // V2 pulse-dot: opacity 1 → .45 and scale 1 → .85, 1.8s ease-in-out (keyframe kit-pulse-dot in kit.css)\n (status === \"building\" || status === \"live\") && \"animate-[kit-pulse-dot_1.8s_ease-in-out_infinite] motion-reduce:animate-none\",\n )}\n />\n {label ?? s.label}\n </Badge>\n );\n}\n\n/* ── Kbd ───────────────────────────────────────────────────────────────── */\nexport function Kbd({ className, ...props }: React.HTMLAttributes<HTMLElement>) {\n return (\n <kbd\n className={cn(\n \"inline-flex h-5 min-w-5 items-center justify-center rounded-kit-sm border border-[var(--kit-kbd-line)] bg-[var(--kit-kbd)] px-1 font-kit-sans text-kit-2xs font-medium text-kit-fg-2 shadow-[inset_0_-1px_0_var(--kit-kbd-line)]\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/* ── Avatar (used by TrayMeta) ─────────────────────────────────────────── */\n// --kit-avatar-1…10: deep tones with white initials in light, calm lifted tones with dark initials in dark\n// (--kit-avatar-on, ≥ 5:1 both), set in kit.css. colorFor() keeps the light hex as a fallback for a value used outside a kit scope.\nconst AVATAR_LIGHT = [\"#c2410c\", \"#be185d\", \"#7e22ce\", \"#4338ca\", \"#1d4ed8\", \"#047857\", \"#b45309\", \"#0369a1\", \"#a21caf\", \"#6d28d9\"];\nconst avatarPalette = AVATAR_LIGHT.map((hex, i) => `var(--kit-avatar-${i + 1}, ${hex})`);\n/** One literal class per slot (Tailwind only sees whole class names); kit.css swaps the tone in dark. */\nconst AVATAR_BG = [\n \"bg-[var(--kit-avatar-1)]\",\n \"bg-[var(--kit-avatar-2)]\",\n \"bg-[var(--kit-avatar-3)]\",\n \"bg-[var(--kit-avatar-4)]\",\n \"bg-[var(--kit-avatar-5)]\",\n \"bg-[var(--kit-avatar-6)]\",\n \"bg-[var(--kit-avatar-7)]\",\n \"bg-[var(--kit-avatar-8)]\",\n \"bg-[var(--kit-avatar-9)]\",\n \"bg-[var(--kit-avatar-10)]\",\n];\nconst AVATAR_ON = \"text-[var(--kit-avatar-on)]\";\nfunction slotFor(seed: string) {\n let h = 0;\n for (let i = 0; i < seed.length; i++) h = (h * 31 + seed.charCodeAt(i)) >>> 0;\n return h % AVATAR_LIGHT.length;\n}\n/** The person's avatar colour as a CSS value (the light hex is the fallback outside a kit scope). */\nexport function colorFor(seed: string) {\n return avatarPalette[slotFor(seed)];\n}\nexport function initials(name: string) {\n return name\n .split(/\\s+/)\n .map((p) => p[0])\n .slice(0, 2)\n .join(\"\")\n .toUpperCase();\n}\n/** How far an Avatar's box-shadow ring reaches past the face (0 without a ring). The Avatar pads itself by this. */\nexport function avatarRingSpread({ ring, ringWidth = 2, ringAccent }: { ring?: string; ringWidth?: number; ringAccent?: string }) {\n return ring ? ringWidth + (ringAccent ? 1 : 0) : 0;\n}\nexport function Avatar({\n name,\n src,\n size = 24,\n className,\n ring,\n ringWidth = 2,\n ringAccent,\n square,\n status,\n decorative,\n}: {\n name: string;\n /** a11y: true when the person's name is already shown as text next to the avatar */\n decorative?: boolean;\n src?: string;\n size?: number;\n className?: string;\n /** separating ring colour, drawn as box-shadow so the image keeps its full size (D34) */\n ring?: string;\n ringWidth?: number;\n /** optional 1px outer ring outside `ring` (e.g. a presence colour) */\n ringAccent?: string;\n square?: boolean;\n status?: \"online\" | \"away\" | \"offline\";\n}) {\n // The ring is a box-shadow, which paints OUTSIDE the element's box. The wrapper reserves that band with padding, so\n // the face and ring sit wholly inside the avatar's layout box and a clipping ancestor never shaves them.\n const spread = avatarRingSpread({ ring, ringWidth, ringAccent });\n return (\n <span className=\"relative inline-flex shrink-0\" style={spread ? { padding: spread } : undefined}>\n <AvatarPrimitive.Root\n style={{\n width: size,\n height: size,\n boxShadow: ring ? `0 0 0 ${ringWidth}px ${ring}${ringAccent ? `, 0 0 0 ${ringWidth + 1}px ${ringAccent}` : \"\"}` : undefined,\n }}\n className={cn(\n \"inline-flex select-none items-center justify-center overflow-hidden bg-kit-muted\",\n square ? \"rounded-kit-md\" : \"rounded-full\",\n className,\n )}\n >\n {src ? <AvatarPrimitive.Image src={src} alt={decorative ? \"\" : name} className=\"size-full object-cover\" /> : null}\n <AvatarPrimitive.Fallback\n delay={src ? 300 : undefined}\n aria-hidden={decorative || undefined}\n style={{ fontSize: Math.max(9, Math.round(size * 0.4)) }}\n className={cn(\"flex size-full items-center justify-center font-semibold\", AVATAR_BG[slotFor(name)], AVATAR_ON)}\n >\n {initials(name)}\n </AvatarPrimitive.Fallback>\n </AvatarPrimitive.Root>\n {status ? (\n <span\n // inside the box (never -1px outside it), offset past any reserved ring band\n style={spread ? { right: spread, bottom: spread } : undefined}\n className={cn(\n \"absolute bottom-0 right-0 size-2.5 rounded-full border-2 border-kit-surface\",\n status === \"online\" ? \"bg-kit-success\" : status === \"away\" ? \"bg-kit-warning\" : \"bg-kit-fg-4\",\n )}\n />\n ) : null}\n </span>\n );\n}\n\n/**\n * AvatarStack (D34). Same-size faces, 25% overlap, a 2px box-shadow ring in the colour of the surface the stack\n * sits on; first face on top; a +N pill names the rest on hover.\n */\nexport function AvatarStack({\n people,\n max = 4,\n size = 24,\n ringColor = \"var(--kit-avatar-ring, var(--kit-surface))\",\n className,\n label,\n}: {\n people: { name: string; src?: string; color?: string }[];\n max?: number;\n size?: number;\n ringColor?: string;\n className?: string;\n label?: string;\n}) {\n const shown = people.slice(0, max);\n const hidden = people.slice(shown.length);\n const step = Math.round(size * 0.25);\n const band = avatarRingSpread({ ring: ringColor });\n const box = size + band * 2;\n const vars = {\n \"--stack-ov\": `-${step + band * 2}px`,\n \"--stack-ov-open\": `-${Math.max(1, Math.round(step * 0.35)) + band * 2}px`,\n } as React.CSSProperties;\n const slot =\n \"relative inline-flex shrink-0 rounded-full transition-[margin,transform] duration-150 ease-out [&:not(:first-child)]:ml-[var(--stack-ov)] group-hover/stack:[&:not(:first-child)]:ml-[var(--stack-ov-open)] hover:!z-30 hover:-translate-y-0.5 motion-reduce:transition-none\";\n return (\n <div\n role=\"group\"\n aria-label={label ?? `${people.length} ${people.length === 1 ? \"person\" : \"people\"}: ${people.map((p) => p.name).join(\", \")}`}\n style={vars}\n className={cn(\"group/stack isolate flex shrink-0 items-center\", className)}\n >\n {shown.map((p, i) => (\n <HintTooltip key={p.name + i} content={p.name}>\n <span style={{ zIndex: shown.length - i + 1, width: box, height: box }} className={slot}>\n <Avatar name={p.name} src={p.src} size={size} ring={ringColor} decorative />\n </span>\n </HintTooltip>\n ))}\n {hidden.length ? (\n <HintTooltip content={hidden.map((p) => p.name).join(\", \")}>\n <span style={{ zIndex: 1, width: box, height: box, padding: band }} className={slot}>\n <span\n style={{ width: size, height: size, boxShadow: `0 0 0 ${band}px ${ringColor}`, fontSize: Math.max(9, Math.round(size * 0.38)) }}\n className=\"inline-flex items-center justify-center rounded-full bg-kit-muted font-medium leading-none tabular-nums text-kit-fg-2\"\n >\n +{hidden.length}\n </span>\n </span>\n </HintTooltip>\n ) : null}\n </div>\n );\n}\n\n/* ── Card ──────────────────────────────────────────────────────────────── */\nexport function Card({ className, interactive, ...props }: React.HTMLAttributes<HTMLDivElement> & { interactive?: boolean }) {\n return (\n <div\n className={cn(\n \"rounded-kit-xl border border-kit-line bg-kit-surface\",\n interactive && \"cursor-pointer transition-[border-color,box-shadow,transform] duration-150 hover:border-kit-line-strong hover:shadow-kit-md\",\n className,\n )}\n {...props}\n />\n );\n}\nexport function CardHeader({\n title,\n description,\n actions,\n icon,\n className,\n}: {\n title: React.ReactNode;\n description?: React.ReactNode;\n actions?: React.ReactNode;\n icon?: React.ReactNode;\n className?: string;\n}) {\n return (\n <div className={cn(\"flex items-start justify-between gap-3 px-4 pt-4\", className)}>\n <div className=\"flex min-w-0 items-start gap-2.5\">\n {icon ? <span className=\"mt-0.5 flex text-kit-fg-2 [&_svg]:size-4\">{icon}</span> : null}\n <div className=\"min-w-0\">\n <h2 className=\"text-kit-base font-semibold text-kit-fg\">{title}</h2>\n {description ? <p className=\"mt-0.5 text-kit-sm text-kit-fg-2\">{description}</p> : null}\n </div>\n </div>\n {actions ? <div className=\"flex shrink-0 items-center gap-1.5\">{actions}</div> : null}\n </div>\n );\n}\n\n/* ── Separator ─────────────────────────────────────────────────────────── */\nexport function Separator({ vertical, className }: { vertical?: boolean; className?: string }) {\n return (\n <div\n role=\"separator\"\n aria-orientation={vertical ? \"vertical\" : undefined}\n className={cn(vertical ? \"h-4 w-px bg-kit-line\" : \"h-px w-full bg-kit-line\", className)}\n />\n );\n}\n\n/* ── Skeleton ──────────────────────────────────────────────────────────── */\n/** V2 .skeleton: a --skeleton → --skeleton-shine sweep (800px wide, 1.6s linear; keyframe kit-shimmer in kit.css). */\nexport const SKELETON =\n \"bg-[linear-gradient(90deg,var(--kit-skeleton)_0,var(--kit-skeleton-shine)_40%,var(--kit-skeleton)_80%)] bg-[length:800px_100%] animate-[kit-shimmer_1.6s_linear_infinite] motion-reduce:animate-none\";\nexport function Skeleton({ className }: { className?: string }) {\n return <div aria-hidden className={cn(SKELETON, \"rounded-kit-md\", className)} />;\n}\n\n/* ── Empty state ───────────────────────────────────────────────────────── */\nexport function EmptyState({\n icon,\n title,\n description,\n actions,\n className,\n compact,\n}: {\n icon?: React.ReactNode;\n title: React.ReactNode;\n description?: React.ReactNode;\n actions?: React.ReactNode;\n className?: string;\n compact?: boolean;\n}) {\n return (\n // D15: compact = 16px icon (no tile), two lines, one action.\n <div className={cn(\"flex flex-col items-center justify-center text-center\", compact ? \"gap-2 py-8\" : \"gap-2.5 py-12\", className)}>\n {icon ? <span className=\"flex text-kit-fg-3 [&_svg]:size-4\">{icon}</span> : null}\n <div className=\"max-w-sm\">\n <h2 className=\"text-kit-base font-medium text-kit-fg\">{title}</h2>\n {description ? <p className=\"mt-0.5 text-kit-sm text-kit-fg-2\">{description}</p> : null}\n </div>\n {actions ? <div className=\"mt-1 flex flex-wrap items-center justify-center gap-2\">{actions}</div> : null}\n </div>\n );\n}\n\n/* ── Page header (inside main surface) ─────────────────────────────────── */\nexport function PageHeader({\n title,\n description,\n actions,\n meta,\n className,\n eyebrow,\n as: Heading = \"h1\",\n}: {\n title: React.ReactNode;\n description?: React.ReactNode;\n actions?: React.ReactNode;\n meta?: React.ReactNode;\n className?: string;\n eyebrow?: React.ReactNode;\n /** Heading level: h1 in the app; demos nested in documentation pass a lower level. */\n as?: \"h1\" | \"h2\" | \"h3\" | \"h4\";\n}) {\n return (\n <div className={cn(\"flex flex-wrap items-end justify-between gap-x-6 gap-y-3\", className)}>\n <div className=\"min-w-0\">\n {eyebrow ? <div className=\"mb-1.5 text-kit-xs font-medium text-kit-fg-3\">{eyebrow}</div> : null}\n <div className=\"flex items-center gap-2.5\">\n <Heading className=\"truncate text-kit-xl font-semibold tracking-[-0.015em] text-kit-fg\">{title}</Heading>\n {meta}\n </div>\n {description ? <p className=\"mt-0.5 text-kit-sm text-kit-fg-2\">{description}</p> : null}\n </div>\n {actions ? <div className=\"flex shrink-0 flex-wrap items-center gap-2\">{actions}</div> : null}\n </div>\n );\n}\n\n/** Section header used inside settings and long pages: title INSIDE the card (founder rule). */\nexport function SettingsSection({\n title,\n description,\n children,\n footer,\n className,\n danger,\n actions,\n}: {\n title: React.ReactNode;\n description?: React.ReactNode;\n children?: React.ReactNode;\n footer?: React.ReactNode;\n className?: string;\n danger?: boolean;\n actions?: React.ReactNode;\n}) {\n return (\n <section className={cn(\"overflow-hidden rounded-kit-xl border bg-kit-surface\", danger ? \"border-kit-danger-line\" : \"border-kit-line\", className)}>\n <div className=\"flex items-start justify-between gap-4 px-5 pt-5\">\n <div>\n <h2 className={cn(\"text-kit-base font-semibold\", danger ? \"text-kit-danger-fg\" : \"text-kit-fg\")}>{title}</h2>\n {description ? <p className=\"mt-0.5 max-w-xl text-kit-sm text-kit-fg-2\">{description}</p> : null}\n </div>\n {actions}\n </div>\n {children ? <div className=\"flex flex-col gap-4 px-5 pb-5 pt-4\">{children}</div> : <div className=\"h-5\" />}\n {footer ? (\n // --subtle-2: half a step between surface and subtle\n <div className=\"flex items-center justify-between gap-3 border-t border-kit-line bg-[var(--kit-subtle-2)] px-5 py-3 text-kit-sm text-kit-fg-2\">\n {footer}\n </div>\n ) : null}\n </section>\n );\n}\n\n/* ── Stat ──────────────────────────────────────────────────────────────── */\nexport function Stat({\n label,\n value,\n delta,\n hint,\n className,\n}: {\n label: React.ReactNode;\n value: React.ReactNode;\n delta?: { value: string; positive?: boolean };\n hint?: React.ReactNode;\n className?: string;\n}) {\n return (\n <div className={cn(\"flex flex-col gap-1\", className)}>\n <span className=\"text-kit-sm text-kit-fg-2\">{label}</span>\n <div className=\"flex items-baseline gap-2\">\n <span className=\"text-kit-xl font-semibold tabular-nums tracking-[-0.01em] text-kit-fg\">{value}</span>\n {delta ? (\n <span className={cn(\"text-kit-xs font-medium tabular-nums\", delta.positive ? \"text-kit-success-fg\" : \"text-kit-danger-fg\")}>\n {delta.positive ? \"↑\" : \"↓\"} {delta.value}\n </span>\n ) : null}\n </div>\n {hint ? <span className=\"text-kit-xs text-kit-fg-3\">{hint}</span> : null}\n </div>\n );\n}\n\n/* ── Table (simple, styled) ────────────────────────────────────────────── */\nexport function Table({ className, ...props }: React.TableHTMLAttributes<HTMLTableElement>) {\n return <table className={cn(\"w-full border-separate border-spacing-0 text-kit-sm\", className)} {...props} />;\n}\nexport function Th({ className, children, ...props }: React.ThHTMLAttributes<HTMLTableCellElement>) {\n // a11y: an icon/action column header still needs text for screen readers (empty-table-header)\n const empty = children == null || children === false || children === \"\";\n return (\n <th\n className={cn(\n \"sticky top-0 z-[1] h-10 border-b border-kit-line bg-kit-surface px-3 text-left text-kit-sm font-normal text-kit-fg-3 first:pl-4 last:pr-4\",\n className,\n )}\n {...props}\n >\n {empty ? <span className=\"sr-only\">{props[\"aria-label\"] ?? \"Actions\"}</span> : children}\n </th>\n );\n}\nexport function Td({ className, ...props }: React.TdHTMLAttributes<HTMLTableCellElement>) {\n return <td className={cn(\"h-14 border-b border-kit-line-subtle px-3 text-kit-fg first:pl-4 last:pr-4\", className)} {...props} />;\n}\nexport function Tr({ className, selected, ...props }: React.HTMLAttributes<HTMLTableRowElement> & { selected?: boolean }) {\n return (\n <tr\n data-selected={selected ? \"true\" : undefined}\n className={cn(\"group/row transition-colors hover:bg-kit-subtle data-[selected=true]:bg-kit-accent-softer\", className)}\n {...props}\n />\n );\n}\n\n/* ── Dot / live indicator ──────────────────────────────────────────────── */\nconst dotTones = {\n success: \"bg-kit-success\",\n warning: \"bg-kit-warning\",\n danger: \"bg-kit-danger\",\n neutral: \"bg-kit-fg-4\",\n accent: \"bg-kit-accent\",\n info: \"bg-kit-info\",\n};\nexport function Dot({ tone = \"success\", pulse, className }: { tone?: keyof typeof dotTones; pulse?: boolean; className?: string }) {\n const c = dotTones[tone];\n return (\n <span className={cn(\"relative inline-flex size-2 shrink-0\", className)}>\n {pulse ? <span className={cn(\"absolute inset-0 animate-ping rounded-full opacity-50 motion-reduce:animate-none\", c)} /> : null}\n <span className={cn(\"relative inline-flex size-2 rounded-full\", c)} />\n </span>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"expanded-editor-modal.js","names":[],"sources":["../../src/kit/ui/expanded-editor-modal.tsx"],"sourcesContent":["/**\n * ExpandedEditorModal (CPO D49): the ONE surface for \"expand this editor\": rich-text fields (⤢ in the toolbar / label row)\n * and the table editor's Full screen. A focused dialog over a dimmed app: inset 32 to 48px from the viewport, at most 1100px\n * wide, header = breadcrumb (… › Field) + a quiet meta line (word count, rows) + Done. Esc closes (menus and popovers\n * inside close first), focus is trapped and returns to whatever opened it. The body edits the SAME value as the field\n * underneath, so both stay in sync. Inline editors stay in place; only expanded editors open here.\n * D54: a component's properties panel opens INSIDE this modal; docked, it takes the right 340px and the reading column\n * shifts left (`data-floating-dock`). Esc closes that panel before the modal.\n */\nimport * as React from \"react\";\nimport { Dialog as DialogPrimitive } from \"@base-ui/react/dialog\";\nimport { IconChevronRight } from \"@tabler/icons-react\";\nimport { cn } from \"../lib/cn\";\nimport { Button } from \"./button\";\nimport { FLOATING_LAYER, Tooltip } from \"./overlay\";\nimport { FLOATING_LINE, KIT_SCOPE, SURFACE_RAISED } from \"./surfaces\";\nimport { MODAL_LAYER } from \"./tooltip-root\";\n\nexport interface ExpandedEditorModalProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** root → current, e.g. [\"Alternating feature rows\", \"Thin walls…\", \"Body\"]; the last one is the title */\n crumbs: string[];\n /** quiet right-side line in the header (\"312 words\", \"6 rows · 4 columns\") */\n meta?: React.ReactNode;\n /** \"reading\" centres a ~720px column (rich text); \"wide\" uses the full dialog width (tables) */\n layout?: \"reading\" | \"wide\";\n /** where focus lands on open (defaults to the first editable surface) */\n initialFocus?: () => HTMLElement | null | undefined;\n /** where focus goes on close when the opener is gone or hidden (e.g. the field's own editor) */\n returnFocus?: () => HTMLElement | null | undefined;\n children: React.ReactNode;\n}\n\n/** Elements inside the editor that own Escape while open (a cell with a draft, a floating layer). Menus and listboxes\n * count only while they are OPEN popups: a list the editor always renders (tags, a static picker) never blocks Escape. */\nconst OWNS_ESCAPE = `[data-cell-editing],${FLOATING_LAYER}`;\nconst LIST = \"[role=menu],[role=listbox]\";\n\n/** An open popup: Base UI marks it data-open, Radix data-state=open; otherwise its controller says aria-expanded. */\nfunction isOpenList(el: Element) {\n if (el.matches(\"[data-open],[data-state=open]\")) return true;\n return !!el.id && !!document.querySelector(`[aria-controls~=\"${CSS.escape(el.id)}\"][aria-expanded=true]`);\n}\nconst openListIn = (root: ParentNode | null | undefined) => !!root && Array.from(root.querySelectorAll(LIST)).some(isOpenList);\n\nexport function ExpandedEditorModal({ open, onOpenChange, crumbs, meta, layout = \"reading\", initialFocus, returnFocus, children }: ExpandedEditorModalProps) {\n const title = crumbs[crumbs.length - 1] ?? \"Editor\";\n const parents = crumbs.slice(0, -1);\n const body = React.useRef<HTMLDivElement>(null);\n const opener = React.useRef<HTMLElement | null>(null);\n React.useLayoutEffect(() => {\n if (open) opener.current = document.activeElement as HTMLElement | null;\n }, [open]);\n\n const change = (next: boolean, details: DialogPrimitive.Root.ChangeEventDetails) => {\n if (!next && details.reason === \"outside-press\") {\n // the editor's own floating layers (selection toolbar, slash menu) are portalled to <body>, outside this dialog:\n // clicks there belong to the editor, so they never close the modal\n const t = details.event.target;\n if (t instanceof Element && t.closest(FLOATING_LAYER)) return details.cancel();\n }\n if (!next && details.reason === \"escape-key\") {\n const e = details.event;\n const t = e.target instanceof Element ? e.target : null;\n // an open slash menu / block picker inside the editor, or a floating menu over it, closes first\n const list = t?.closest(LIST);\n const inner = openListIn(body.current) || Array.from(document.querySelectorAll(FLOATING_LAYER)).some(openListIn);\n if (e.defaultPrevented || t?.closest(OWNS_ESCAPE) || (list && isOpenList(list)) || inner) return details.cancel();\n // then a component's properties panel open in here (D54): it closes, the modal stays\n const panel = body.current?.parentElement?.querySelector(\"[data-floating-panel]\");\n if (panel) {\n details.cancel();\n (e as KeyboardEvent & { bcmsPanelHandled?: boolean }).bcmsPanelHandled = true;\n panel.dispatchEvent(new CustomEvent(\"floatingpanel:escape\"));\n return;\n }\n }\n onOpenChange(next);\n };\n\n return (\n <DialogPrimitive.Root open={open} onOpenChange={change}>\n <DialogPrimitive.Portal>\n <DialogPrimitive.Backdrop\n {...KIT_SCOPE}\n className=\"fixed inset-0 z-[70] bg-kit-overlay backdrop-blur-[2px] data-[open]:animate-kit-fade-in\"\n />\n <DialogPrimitive.Popup\n {...KIT_SCOPE}\n {...{ [MODAL_LAYER]: \"\" }}\n aria-describedby={undefined}\n initialFocus={() => {\n // focus lands INSIDE at once (so the trap has a home), then moves to the editor once it has mounted.\n // Base UI focuses the returned element in a frame of its own, so the editor waits one frame longer.\n requestAnimationFrame(() =>\n requestAnimationFrame(() => {\n const el = initialFocus?.() ?? body.current?.querySelector<HTMLElement>(\"[contenteditable=true], [data-cell], input, textarea\");\n el?.focus({ preventScroll: true });\n }),\n );\n return body.current;\n }}\n finalFocus={() => {\n // back to whatever opened it, or, when that is gone or hidden, to the host's fallback (the field itself)\n const o = opener.current;\n const target = o && o.isConnected && o !== document.body && o.getClientRects().length ? o : (returnFocus?.() ?? o);\n requestAnimationFrame(() => target?.focus({ preventScroll: true }));\n return false;\n }}\n // keys typed in the editor never reach the app behind it (canvas shortcuts, form Esc); F6 still moves to a panel\n onKeyDown={(e) => {\n if (e.key !== \"Escape\" && e.key !== \"F6\") e.stopPropagation();\n }}\n data-expanded-editor=\"\"\n className={cn(\n \"fixed inset-4 z-[71] mx-auto flex max-w-[1100px] flex-col overflow-hidden rounded-kit-xl border text-kit-fg shadow-kit-xl outline-none sm:inset-8 lg:inset-x-12 lg:inset-y-10\",\n FLOATING_LINE,\n SURFACE_RAISED,\n \"data-[floating-dock=right]:[&>[data-expanded-body]]:pr-[340px]\",\n \"data-[open]:animate-kit-pop-in\",\n )}\n >\n <header className=\"flex h-12 shrink-0 items-center gap-2 border-b border-kit-line pl-4 pr-3\">\n <nav aria-label=\"Field path\" className=\"flex min-w-0 flex-1 items-center gap-1 text-kit-sm\">\n {parents.map((c, i) => (\n <React.Fragment key={`${c}-${i}`}>\n <Tooltip content={c} side=\"bottom\">\n <span className=\"max-w-[220px] truncate text-kit-fg-3\">{c}</span>\n </Tooltip>\n <IconChevronRight className=\"size-3 shrink-0 text-kit-fg-4\" stroke={1.5} aria-hidden />\n </React.Fragment>\n ))}\n {/* the field title names the dialog (\"Body\"), not the nav's \"Field path\" */}\n <DialogPrimitive.Title render={<span aria-current=\"location\" />} className=\"min-w-0 truncate font-medium text-kit-fg\">\n {title}\n </DialogPrimitive.Title>\n </nav>\n {meta ? <span className=\"hidden shrink-0 text-kit-xs tabular-nums text-kit-fg-3 sm:inline\">{meta}</span> : null}\n <DialogPrimitive.Close render={<Button size=\"sm\" variant=\"primary\" />}>Done</DialogPrimitive.Close>\n </header>\n <div ref={body} tabIndex={-1} data-expanded-body=\"\" className=\"min-h-0 flex-1 overflow-y-auto overscroll-contain outline-none\">\n {layout === \"reading\" ? (\n <div className=\"mx-auto w-full max-w-[720px] px-6 py-8 sm:px-10\">{children}</div>\n ) : (\n <div className=\"flex h-full min-h-0 flex-col p-4\">{children}</div>\n )}\n </div>\n </DialogPrimitive.Popup>\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n );\n}\n"],"mappings":"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"}
|
package/ui/field-context.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"field-context.js","names":[],"sources":["../../src/kit/ui/field-context.ts"],"sourcesContent":["import * as React from \"react\";\n\n/* The Field wrapper (input.tsx) publishes its label wiring here, so controls in other files (Switch, Select) can read it\n without importing input.tsx. V2 keeps these contexts inside ui/input.tsx; input.tsx should import them from this file. */\n\nexport const FieldIdContext = React.createContext<string | undefined>(undefined);\nexport function useFieldId() {\n return React.useContext(FieldIdContext);\n}\n\nexport const FieldLabelledByContext = React.createContext<string | undefined>(undefined);\nexport function useFieldLabelledBy() {\n return React.useContext(FieldLabelledByContext);\n}\n\nexport const FieldDescribedByContext = React.createContext<string | undefined>(undefined);\nexport function useFieldDescribedBy() {\n return React.useContext(FieldDescribedByContext);\n}\n\n/* `<label for>` without a <label> element. V2 draws no label on an inline-list row, so the row publishes its sr-only\n name here and the kit control whose id is `htmlFor` (Input, Textarea, Select, Switch, Checkbox) points its\n aria-labelledby at `labelId`, unless the control carries its own aria-label / aria-labelledby. */\nexport const FieldLabelForContext = React.createContext<{ htmlFor: string; labelId: string } | undefined>(undefined);\nexport function useLabelFor(id: string | undefined) {\n const ctx = React.useContext(FieldLabelForContext);\n return ctx && id && ctx.htmlFor === id ? ctx.labelId : undefined;\n}\n"],"mappings":";;AAKA,IAAa,iBAAiB,MAAM,cAAkC,KAAA,EAAU;AAChF,SAAgB,aAAa;AAC3B,QAAO,MAAM,WAAW,eAAe;;AAGzC,IAAa,yBAAyB,MAAM,cAAkC,KAAA,EAAU;AACxF,SAAgB,qBAAqB;AACnC,QAAO,MAAM,WAAW,uBAAuB;;AAGjD,IAAa,0BAA0B,MAAM,cAAkC,KAAA,EAAU;AACzF,SAAgB,sBAAsB;AACpC,QAAO,MAAM,WAAW,wBAAwB;;AAMlD,IAAa,uBAAuB,MAAM,cAAgE,KAAA,EAAU;AACpH,SAAgB,YAAY,IAAwB;CAClD,MAAM,MAAM,MAAM,WAAW,qBAAqB;AAClD,QAAO,OAAO,MAAM,IAAI,YAAY,KAAK,IAAI,UAAU,KAAA"}
|
package/ui/floating-panel.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"floating-panel.js","names":[],"sources":["../../src/kit/ui/floating-panel.tsx"],"sourcesContent":["/**\n * FloatingPanel (CPO D54): ONE primitive for every non-modal window over the work surface. It owns drag, magnetic snap,\n * resize and \"remember where I put it\"; the ⌘J assistant (D30) and the component properties panel both use it.\n *\n * geometry track() · snapRect() · <SnapGuides> · <ResizeEdges> (4 edges + 4 corners) · <ResizeGrip> (keyboard)\n * (the low-level pieces, shared with the assistant's floating window)\n * <FloatingPanel> a small properties window anchored to the thing it edits:\n * float (≥768 with a mouse) docks in the editor column's right gutter (≥356px), else the left gutter, else it\n * overlays the right edge; avoids a floating assistant, the Publish tray and the 56px navbar. While docked\n * it follows the anchor's top (sticky between 72px from the top and 16px from the bottom); once dragged it\n * stays where it was put. 340 × auto (≤560), resizable 300×240 … 520 × (viewport − 96). Header = drag\n * handle; double-click resets it to its docked default. Side, offset and size persist per user and per\n * width bucket (≥1280 · 768–1279).\n * side (768–1279 on touch) a 340px right sheet, no scrim.\n * sheet (<768) a bottom sheet, 50% or 90% tall; drag the grabber down to close.\n * modal inside a D49 ExpandedEditorModal (`container`): docked into the modal's right 340px (the reading column\n * shifts left), or over the modal's edge when it is narrow.\n * Non-modal: `role=\"dialog\"` + `aria-modal=\"false\"`, no focus trap, outside clicks never close it. Esc closes (menus,\n * pickers and field drafts first), F6 moves focus between the panel and `focusBack()`. Marked `data-floating-layer`.\n * Layering: canvas toolbars < panel 52 (= the D30 window) < sheets 55 < dialogs 60 < menus 80 < tooltips 90.\n */\nimport * as React from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { motion, useMotionValue, useReducedMotion, type MotionValue } from \"framer-motion\";\nimport { cn } from \"../lib/cn\";\nimport { FLOATING_LINE, KIT_SCOPE, SURFACE_RAISED } from \"./surfaces\";\n\n/* V2 --shadow-sheet-r / --shadow-sheet-b, light and dark (kit.css has no sheet shadows yet). */\nconst SHADOW_SHEET_R = \"shadow-[-12px_0_32px_-16px_rgb(0_0_0/0.18)] [.dark_&]:shadow-[-12px_0_32px_-16px_oklch(0.12_0.01_286/0.5)]\";\nconst SHADOW_SHEET_B = \"shadow-[0_-16px_40px_-12px_rgb(0_0_0/0.2)] [.dark_&]:shadow-[0_-16px_40px_-12px_oklch(0.12_0.01_286/0.5)]\";\n\n/* ── Geometry (shared with the D30 assistant window) ─────────────────────────────────────────── */\nexport const NAV = 56;\nexport const SNAP = 16;\nexport const EDGE = 16;\nexport const Z_FLOAT = \"z-[52]\";\nexport const EASE = [0.32, 0.72, 0, 1] as const;\n\nexport type Rect = { x: number; y: number; w: number; h: number };\n/** Where a window may sit and how big it may get. `top` is the smallest y (under the navbar), `pad` the inset elsewhere. */\nexport interface Bounds {\n minW: number;\n minH: number;\n maxW: () => number;\n maxH: () => number;\n top: number;\n pad: number;\n}\n/** Magnetic lines in viewport px: `v` = x positions (left/right edges snap to them), `h` = y positions. */\nexport interface SnapLines {\n v: number[];\n h: number[];\n}\n/** 1px guide lines to draw (viewport px). */\nexport interface Guides {\n v: number[];\n h: number[];\n}\nexport const NO_GUIDES: Guides = { v: [], h: [] };\nexport interface Geom {\n x: MotionValue<number>;\n y: MotionValue<number>;\n w: MotionValue<number>;\n h: MotionValue<number>;\n}\n\nexport const vw = () => window.innerWidth;\nexport const vh = () => window.innerHeight;\nexport const clampN = (n: number, lo: number, hi: number) => Math.max(lo, Math.min(hi, n));\n\nexport function fitRect(g: Rect, b: Bounds): Rect {\n const w = clampN(g.w, b.minW, Math.max(b.minW, b.maxW()));\n const h = clampN(g.h, b.minH, Math.max(b.minH, b.maxH()));\n return { w, h, x: clampN(g.x, b.pad, Math.max(b.pad, vw() - w - b.pad)), y: clampN(g.y, b.top, Math.max(b.top, vh() - h - b.pad)) };\n}\n\n/** Clamp to the viewport, then pull any edge within SNAP px of a line onto it (the nearest wins). */\nexport function snapRect(x: number, y: number, w: number, h: number, lines: SnapLines, b: Bounds): { x: number; y: number; g: Guides } {\n let nx = clampN(x, b.pad, Math.max(b.pad, vw() - w - b.pad));\n let ny = clampN(y, b.top, Math.max(b.top, vh() - h - b.pad));\n const g: Guides = { v: [], h: [] };\n let best = SNAP + 1;\n let gx: number | null = null;\n let sx = nx;\n for (const L of lines.v) {\n const a = Math.abs(nx - L);\n if (a <= SNAP && a < best) (best = a), (sx = L), (gx = L - 1);\n const z = Math.abs(nx + w - L);\n if (z <= SNAP && z < best) (best = z), (sx = L - w), (gx = L);\n }\n nx = sx;\n if (gx != null) g.v.push(gx);\n best = SNAP + 1;\n let gy: number | null = null;\n let sy = ny;\n for (const L of lines.h) {\n const a = Math.abs(ny - L);\n if (a <= SNAP && a < best) (best = a), (sy = L), (gy = L - 1);\n const z = Math.abs(ny + h - L);\n if (z <= SNAP && z < best) (best = z), (sy = L - h), (gy = L);\n }\n ny = sy;\n if (gy != null) g.h.push(gy);\n return { x: nx, y: ny, g };\n}\n\n/** Runs a pointer drag on window-level listeners (works from any handle, survives leaving the element). */\nexport function track(e: React.PointerEvent, onMove: (dx: number, dy: number) => void, onEnd: (moved: boolean) => void, cursor?: string) {\n const sx = e.clientX;\n const sy = e.clientY;\n let moved = false;\n if (cursor) document.body.style.cursor = cursor;\n document.body.style.userSelect = \"none\";\n const move = (ev: PointerEvent) => {\n const dx = ev.clientX - sx;\n const dy = ev.clientY - sy;\n if (!moved && Math.abs(dx) + Math.abs(dy) < 3) return;\n moved = true;\n onMove(dx, dy);\n };\n const up = () => {\n window.removeEventListener(\"pointermove\", move);\n window.removeEventListener(\"pointerup\", up);\n window.removeEventListener(\"pointercancel\", up);\n document.body.style.cursor = \"\";\n document.body.style.userSelect = \"\";\n onEnd(moved);\n };\n window.addEventListener(\"pointermove\", move);\n window.addEventListener(\"pointerup\", up);\n window.addEventListener(\"pointercancel\", up);\n}\n\n/** Magnetic guides: a 1px hairline along each line the window is snapped to. */\nexport function SnapGuides({ guides }: { guides: Guides }) {\n // --brand (V2): #a878d2, dark #b792db\n const line = cn(\"pointer-events-none fixed bg-[var(--kit-brand)]\", Z_FLOAT);\n return (\n <>\n {guides.v.map((p) => (\n <span key={`v${p}`} aria-hidden className={line} style={{ left: p, top: 8, bottom: 8, width: 1 }} />\n ))}\n {guides.h.map((p) => (\n <span key={`h${p}`} aria-hidden className={line} style={{ top: p, left: 8, right: 8, height: 1 }} />\n ))}\n </>\n );\n}\n\nexport type ResizeDir = \"n\" | \"s\" | \"e\" | \"w\" | \"nw\" | \"ne\" | \"sw\" | \"se\";\nconst HANDLES: { d: ResizeDir; cls: string; cursor: string }[] = [\n { d: \"n\", cls: \"inset-x-3 top-0 h-1.5\", cursor: \"ns-resize\" },\n { d: \"s\", cls: \"inset-x-3 bottom-0 h-1.5\", cursor: \"ns-resize\" },\n { d: \"w\", cls: \"inset-y-3 left-0 w-1.5\", cursor: \"ew-resize\" },\n { d: \"e\", cls: \"inset-y-3 right-0 w-1.5\", cursor: \"ew-resize\" },\n { d: \"nw\", cls: \"left-0 top-0 size-3\", cursor: \"nwse-resize\" },\n { d: \"se\", cls: \"bottom-0 right-0 size-3\", cursor: \"nwse-resize\" },\n { d: \"ne\", cls: \"right-0 top-0 size-3\", cursor: \"nesw-resize\" },\n { d: \"sw\", cls: \"bottom-0 left-0 size-3\", cursor: \"nesw-resize\" },\n];\n\n/** Resize from 4 edges and 4 corners. `onStart` runs before the first read (e.g. turn an auto height into a number). */\nexport function ResizeEdges({ geom, bounds, onStart, onEnd }: { geom: Geom; bounds: Bounds; onStart?: () => void; onEnd: (dir: ResizeDir) => void }) {\n const { x, y, w, h } = geom;\n return (\n <>\n {HANDLES.map((hd) => (\n <div\n key={hd.d}\n aria-hidden\n style={{ cursor: hd.cursor }}\n className={cn(\"absolute z-30 touch-none\", hd.cls)}\n onPointerDown={(e) => {\n if (e.button !== 0) return;\n e.preventDefault();\n e.stopPropagation();\n onStart?.();\n const o = { x: x.get(), y: y.get(), w: w.get(), h: h.get() };\n const maxW = bounds.maxW();\n const maxH = bounds.maxH();\n track(\n e,\n (dx, dy) => {\n let nw = o.w;\n let nh = o.h;\n if (hd.d.includes(\"e\")) nw = o.w + dx;\n if (hd.d.includes(\"w\")) nw = o.w - dx;\n if (hd.d.includes(\"s\")) nh = o.h + dy;\n if (hd.d.includes(\"n\")) nh = o.h - dy;\n nw = clampN(nw, bounds.minW, maxW);\n nh = clampN(nh, bounds.minH, maxH);\n const nx = clampN(hd.d.includes(\"w\") ? o.x + o.w - nw : o.x, bounds.pad, vw() - nw - bounds.pad);\n const ny = clampN(hd.d.includes(\"n\") ? o.y + o.h - nh : o.y, bounds.top, vh() - nh - bounds.pad);\n x.set(nx);\n y.set(ny);\n w.set(nw);\n h.set(nh);\n },\n (moved) => moved && onEnd(hd.d),\n hd.cursor,\n );\n }}\n />\n ))}\n </>\n );\n}\n\n/** Keyboard resize: a focusable grip (role=\"separator\"). ←/→ width, ↑/↓ height (±16, Shift ±64); grows toward the open side. */\nexport function ResizeGrip({ geom, bounds, label, onStart, onEnd, className }: { geom: Geom; bounds: Bounds; label: string; onStart?: () => void; onEnd: () => void; className?: string }) {\n const { x, y, w, h } = geom;\n const [size, setSize] = React.useState(() => ({ w: Math.round(w.get()), h: Math.round(h.get()) }));\n return (\n <div\n role=\"separator\"\n tabIndex={0}\n aria-label={label}\n aria-valuetext={`${size.w} by ${size.h} pixels`}\n aria-keyshortcuts=\"ArrowLeft ArrowRight ArrowUp ArrowDown\"\n onFocus={() => setSize({ w: Math.round(w.get()), h: Math.round(h.get()) })}\n onKeyDown={(e) => {\n const step = e.shiftKey ? 64 : 16;\n const dw = e.key === \"ArrowRight\" ? step : e.key === \"ArrowLeft\" ? -step : 0;\n const dh = e.key === \"ArrowDown\" ? step : e.key === \"ArrowUp\" ? -step : 0;\n if (!dw && !dh) return;\n e.preventDefault();\n e.stopPropagation();\n onStart?.();\n const nw = clampN(w.get() + dw, bounds.minW, bounds.maxW());\n const nh = clampN(h.get() + dh, bounds.minH, bounds.maxH());\n x.set(clampN(x.get(), bounds.pad, Math.max(bounds.pad, vw() - nw - bounds.pad)));\n y.set(clampN(y.get(), bounds.top, Math.max(bounds.top, vh() - nh - bounds.pad)));\n w.set(nw);\n h.set(nh);\n setSize({ w: Math.round(nw), h: Math.round(nh) });\n onEnd();\n }}\n className={cn(\n \"group/kgrip pointer-events-none absolute bottom-0.5 right-0.5 z-40 flex size-4 items-end justify-end rounded-kit-sm outline-none\",\n className,\n )}\n >\n <svg aria-hidden viewBox=\"0 0 10 10\" className=\"size-2.5 text-kit-fg-4 opacity-0 transition-opacity group-focus-visible/kgrip:opacity-100\">\n <path d=\"M9 3 3 9M9 6 6 9\" stroke=\"currentColor\" strokeWidth=\"1.2\" strokeLinecap=\"round\" />\n </svg>\n </div>\n );\n}\n\n/* ── Remembered placement: per user, per panel, per width bucket ─────────────────────────────── */\nexport interface PanelPref {\n side?: \"left\" | \"right\";\n /** set once the person drags it: the panel stays here instead of following its anchor */\n pos?: { x: number; y: number };\n w?: number;\n /** set once the person resizes the height; otherwise the height follows the content */\n h?: number;\n}\ninterface PanelPrefState {\n prefs: Record<string, PanelPref>;\n patch: (key: string, p: Partial<PanelPref> | null) => void;\n}\n/* Remembered per browser in localStorage (the kit carries no state library). A blocked or full storage only loses the\n memory: the panel still docks at its default. */\nconst PREFS_KEY = \"bcms-kit-floating-panel\";\nconst prefListeners = new Set<() => void>();\nfunction readPrefs(): Record<string, PanelPref> {\n try {\n const raw = typeof localStorage === \"undefined\" ? null : localStorage.getItem(PREFS_KEY);\n const parsed = raw ? (JSON.parse(raw) as unknown) : null;\n return parsed && typeof parsed === \"object\" ? (parsed as Record<string, PanelPref>) : {};\n } catch {\n return {};\n }\n}\nconst prefState: PanelPrefState = {\n prefs: readPrefs(),\n patch: (key, p) => {\n const next: PanelPref = p === null ? {} : { ...prefState.prefs[key], ...p };\n for (const k of Object.keys(next) as (keyof PanelPref)[]) if (next[k] === undefined) delete next[k];\n prefState.prefs = { ...prefState.prefs, [key]: next };\n try {\n localStorage.setItem(PREFS_KEY, JSON.stringify(prefState.prefs));\n } catch {\n /* storage blocked: placement is remembered for this session only */\n }\n prefListeners.forEach((l) => l());\n },\n};\nconst subscribePrefs = (l: () => void) => {\n prefListeners.add(l);\n return () => prefListeners.delete(l);\n};\n/** Read the remembered placements with a selector; `useFloatingPanelPrefs.getState()` for imperative reads and writes. */\nexport function useFloatingPanelPrefs<T>(select: (s: PanelPrefState) => T): T {\n return React.useSyncExternalStore(\n subscribePrefs,\n () => select(prefState),\n () => select(prefState),\n );\n}\nuseFloatingPanelPrefs.getState = (): PanelPrefState => prefState;\nexport type WidthBucket = \"wide\" | \"mid\";\nconst bucketNow = (): WidthBucket => (vw() >= 1280 ? \"wide\" : \"mid\");\n\nexport type PanelMode = \"float\" | \"side\" | \"sheet\" | \"modal\";\nfunction useMedia(q: string) {\n const [ok, setOk] = React.useState(() => typeof window !== \"undefined\" && window.matchMedia(q).matches);\n React.useEffect(() => {\n const m = window.matchMedia(q);\n const on = () => setOk(m.matches);\n on();\n m.addEventListener(\"change\", on);\n return () => m.removeEventListener(\"change\", on);\n }, [q]);\n return ok;\n}\n/** How a panel presents at this width and pointer: float · side (tablet touch) · sheet (phones) · modal (inside a D49 modal). */\nexport function usePanelMode(inModal?: boolean): PanelMode {\n const phone = useMedia(\"(max-width: 767px)\");\n const touchTablet = useMedia(\"(max-width: 1279px) and (pointer: coarse)\");\n if (inModal) return \"modal\";\n return phone ? \"sheet\" : touchTablet ? \"side\" : \"float\";\n}\n\n/* ── helpers ──────────────────────────────────────────────────────────────────────────────────── */\nfunction scrollParent(el: HTMLElement | null): HTMLElement | null {\n let p = el?.parentElement ?? null;\n while (p && p !== document.body && p !== document.documentElement) {\n const o = getComputedStyle(p).overflowY;\n if ((o === \"auto\" || o === \"scroll\") && p.scrollHeight > p.clientHeight) return p;\n p = p.parentElement;\n }\n return null;\n}\n/** Things a panel never covers by default: a floating or docked assistant, anything marked `data-floating-avoid`. */\nconst AVOID = \"#assistant-panel, [data-floating-avoid]\";\n/** Right-side panels of the page (the editor's Publishing · History · Comments): the panel takes the other side. */\nconst SIDE_PANELS = \"[data-doc-settings], [data-side-panel]\";\n/** A menu, picker, popover or another dialog is open: it takes Esc first. */\n/** An open Base UI popup (popover, menu, select, combobox): it carries data-open and data-side. Kit tooltips don't count. */\nconst POPUP_OPEN = \"[data-open][data-side]:not([data-kit-tooltip])\";\nconst OWNS_ESCAPE = `[role=menu],[role=listbox],[data-cell-editing],${POPUP_OPEN}`;\nfunction layerOpen(self: HTMLElement | null) {\n // a popover, menu or select (tooltips don't count), a cell with a draft\n if (document.querySelector(`${POPUP_OPEN}, [data-cell-editing]`)) return true;\n // a floating menu or picker (the slash menu); page-level listboxes (a sidebar list) don't count\n const floating = (n: HTMLElement) => n.getAttribute(\"role\") === \"menu\" || !!n.closest(\"[data-floating-layer]:not([data-floating-panel])\");\n if (Array.from(document.querySelectorAll<HTMLElement>(\"[role=menu], [role=listbox]\")).some((n) => n.getClientRects().length && floating(n))) return true;\n return Array.from(document.querySelectorAll<HTMLElement>(\"[role=dialog]:is([data-open],[data-state=open])\")).some(\n (d) => d !== self && !d.hasAttribute(\"data-expanded-editor\") && !d.hasAttribute(\"data-floating-panel\") && d.id !== \"assistant-panel\" && !d.hasAttribute(\"data-doc-panel\"),\n );\n}\nconst FOCUSABLE = \"input:not([type=hidden]):not([disabled]), textarea:not([disabled]), [contenteditable=true], select:not([disabled]), button:not([disabled]), [tabindex]:not([tabindex='-1'])\";\n\n/** Events from the panel never reach the React tree it was rendered from (the card, the editor around it). */\nconst stop = (e: React.SyntheticEvent) => e.stopPropagation();\nconst FENCE = {\n onFocus: stop, onBlur: stop, onClick: stop, onDoubleClick: stop, onMouseDown: stop, onMouseUp: stop, onMouseMove: stop,\n onInput: stop, onPaste: stop, onCut: stop, onCopy: stop, onKeyUp: stop, onContextMenu: stop,\n} as const;\n\n/* ── The panel ────────────────────────────────────────────────────────────────────────────────── */\nexport const PANEL_W = 340;\nconst PANEL_MAX_AUTO_H = 560;\nconst TOP_LIMIT = 72;\nconst BOTTOM_GAP = 16;\nconst FLOAT_BOUNDS: Bounds = { minW: 300, minH: 240, maxW: () => Math.min(520, vw() - 32), maxH: () => vh() - 96, top: NAV + 4, pad: 8 };\n\nexport interface FloatingPanelHandle {\n dock: (side: \"left\" | \"right\") => void;\n /** back to the docked default (position and size) */\n reset: () => void;\n /** keyboard move / resize: arrows ±16 (Shift ±64), Enter commits, Esc cancels */\n keyboard: (mode: \"move\" | \"resize\") => void;\n /** a polite announcement from the panel's own live region */\n announce: (text: string) => void;\n el: () => HTMLElement | null;\n}\nexport interface FloatingPanelProps {\n /** remembered placement key (one per kind of panel) */\n id: string;\n /** id of the element that names the panel (the header title) */\n labelledBy: string;\n /** the thing it edits: the panel follows it and docks beside its column (`[data-rt-editor]`) */\n anchor: HTMLElement | null;\n /** render inside this element instead of <body> (the D49 modal) */\n container?: HTMLElement | null;\n header: React.ReactNode;\n children: React.ReactNode;\n /** bottom-sheet footer (Done) */\n sheetFooter?: React.ReactNode;\n onClose: () => void;\n /** F6 / Esc: where focus goes back to (the card) */\n focusBack?: () => void;\n /** a refill (another component picked while open): no entrance animation */\n instant?: boolean;\n bodyClassName?: string;\n /** keys anywhere in the panel, before its own handling (⌘Z joins the host's undo) */\n onPanelKeyDown?: (e: KeyboardEvent) => void;\n}\n\nexport const FloatingPanel = React.forwardRef<FloatingPanelHandle, FloatingPanelProps>(function FloatingPanel(\n { id, labelledBy, anchor, container, header, children, sheetFooter, onClose, focusBack, instant, bodyClassName, onPanelKeyDown },\n handle,\n) {\n const reduce = useReducedMotion();\n const mode = usePanelMode(!!container);\n const root = React.useRef<HTMLDivElement>(null);\n const live = React.useRef<HTMLDivElement>(null);\n const [bucket, setBucket] = React.useState<WidthBucket>(bucketNow);\n const key = `${id}:${bucket}`;\n const pref = useFloatingPanelPrefs((s) => s.prefs[key]) ?? EMPTY;\n const patch = (p: Partial<PanelPref> | null) => {\n useFloatingPanelPrefs.getState().patch(key, p);\n // layout may run before React re-renders with the new prefs\n prefRef.current = useFloatingPanelPrefs.getState().prefs[key] ?? EMPTY;\n };\n const x = useMotionValue(-9999);\n const y = useMotionValue(-9999);\n const w = useMotionValue(pref.w ?? PANEL_W);\n const h = useMotionValue(pref.h ?? 0);\n const geom = React.useMemo<Geom>(() => ({ x, y, w, h }), [x, y, w, h]);\n const [explicitH, setExplicitH] = React.useState(!!pref.h);\n const [maxAuto, setMaxAuto] = React.useState(PANEL_MAX_AUTO_H);\n const [guides, setGuides] = React.useState<Guides>(NO_GUIDES);\n const [kbd, setKbd] = React.useState<null | { mode: \"move\" | \"resize\"; start: Rect; explicit: boolean }>(null);\n const [sheetH, setSheetH] = React.useState<50 | 90>(50);\n const busy = React.useRef(false); // dragging / resizing: layout pauses\n const prefRef = React.useRef(pref);\n prefRef.current = pref;\n const kbdRef = React.useRef(kbd);\n kbdRef.current = kbd;\n const closeRef = React.useRef(onClose);\n closeRef.current = onClose;\n const backRef = React.useRef(focusBack);\n backRef.current = focusBack;\n\n // a new width bucket brings its own remembered placement\n React.useEffect(() => {\n const on = () => setBucket(bucketNow());\n window.addEventListener(\"resize\", on);\n return () => window.removeEventListener(\"resize\", on);\n }, []);\n React.useEffect(() => {\n w.set(pref.w ?? PANEL_W);\n setExplicitH(!!pref.h);\n if (pref.h) h.set(pref.h);\n }, [key]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const column = React.useCallback(() => (anchor?.closest<HTMLElement>(\"[data-rt-editor]\") ?? anchor)?.getBoundingClientRect() ?? null, [anchor]);\n\n /** Where the panel sits now (float mode): its remembered spot, or docked beside the column, following the anchor. */\n const layout = React.useCallback(() => {\n const el = root.current;\n if (!el || !anchor || mode !== \"float\" || busy.current || kbdRef.current) return;\n const p = prefRef.current;\n const sc = scrollParent(anchor)?.getBoundingClientRect();\n const top = Math.max(TOP_LIMIT, (sc?.top ?? 0) + 8);\n let bottom = vh() - BOTTOM_GAP;\n const tray = document.querySelector<HTMLElement>(\"[data-action-tray]\")?.getBoundingClientRect();\n if (tray && tray.height && tray.top > top + 240) bottom = Math.min(bottom, tray.top - 8);\n if (sc && sc.bottom > top + 240) bottom = Math.min(bottom, sc.bottom - 8);\n const room = Math.max(FLOAT_BOUNDS.minH, bottom - top);\n const nextMax = Math.min(PANEL_MAX_AUTO_H, room);\n setMaxAuto((m) => (m === nextMax ? m : nextMax));\n const ww = w.get();\n const ph = Math.min(el.offsetHeight || 320, room);\n if (p.pos) {\n x.set(clampN(p.pos.x, 8, Math.max(8, vw() - ww - 8)));\n y.set(clampN(p.pos.y, NAV + 4, Math.max(NAV + 4, vh() - ph - 8)));\n return;\n }\n const col = column();\n const a = anchor.getBoundingClientRect();\n if (!col) return;\n let L = Math.max(8, sc?.left ?? 0);\n let R = Math.min(vw() - 8, sc?.right ?? vw());\n for (const o of Array.from(document.querySelectorAll<HTMLElement>(AVOID))) {\n if (o === el || el.contains(o)) continue;\n const r = o.getBoundingClientRect();\n if (!r.width || !r.height || r.bottom < top || r.top > bottom) continue;\n if (r.left + r.width / 2 < col.left + col.width / 2) L = Math.max(L, r.right);\n else R = Math.min(R, r.left);\n }\n const need = ww + 16;\n const fits = { right: R - col.right >= need, left: col.left - L >= need };\n // an open right-side panel (Publishing · History · Comments) sends it to the other side\n const rightBusy = Array.from(document.querySelectorAll<HTMLElement>(SIDE_PANELS)).some((n) => n.getBoundingClientRect().width > 40);\n const side = p.side ?? (rightBusy ? \"left\" : fits.right ? \"right\" : fits.left ? \"left\" : \"right\");\n const nx = side === \"right\" ? (fits.right ? col.right + 16 : R - ww - 8) : fits.left ? col.left - 16 - ww : L + 8;\n x.set(clampN(nx, 8, Math.max(8, vw() - ww - 8)));\n y.set(clampN(a.top, top, Math.max(top, bottom - ph)));\n }, [anchor, mode, column, w, x, y]);\n\n React.useLayoutEffect(() => {\n layout();\n }, [layout, pref.pos, pref.side, pref.w, explicitH]);\n React.useEffect(() => {\n if (mode !== \"float\") return;\n let raf = 0;\n let settle = 0;\n const on = () => {\n cancelAnimationFrame(raf);\n raf = requestAnimationFrame(layout);\n // once more after things stop moving (a side panel's exit animation ends after the last resize)\n window.clearTimeout(settle);\n settle = window.setTimeout(layout, 320);\n };\n window.addEventListener(\"scroll\", on, true);\n window.addEventListener(\"resize\", on);\n // something it avoids may have moved (the assistant window dropped somewhere else)\n window.addEventListener(\"pointerup\", on);\n const ro = new ResizeObserver(on);\n if (root.current) ro.observe(root.current);\n if (anchor) ro.observe(anchor);\n // the work surface narrowing (a side panel opening) moves the column without resizing the anchor\n const sc = scrollParent(anchor);\n if (sc) ro.observe(sc);\n return () => {\n cancelAnimationFrame(raf);\n window.clearTimeout(settle);\n window.removeEventListener(\"scroll\", on, true);\n window.removeEventListener(\"resize\", on);\n window.removeEventListener(\"pointerup\", on);\n ro.disconnect();\n };\n }, [mode, layout, anchor]);\n\n // modal: dock into the modal's right 340px (the reading column shifts left), or overlay its edge when narrow\n const [modalFit, setModalFit] = React.useState<\"dock\" | \"overlay\" | \"bottom\">(\"dock\");\n React.useLayoutEffect(() => {\n if (mode !== \"modal\" || !container) return;\n const fit = () => {\n const cw = container.clientWidth;\n const next = cw < 560 ? \"bottom\" : cw >= PANEL_W + 680 ? \"dock\" : \"overlay\";\n setModalFit(next);\n if (next === \"dock\") container.setAttribute(\"data-floating-dock\", \"right\");\n else container.removeAttribute(\"data-floating-dock\");\n };\n fit();\n const ro = new ResizeObserver(fit);\n ro.observe(container);\n return () => {\n ro.disconnect();\n container.removeAttribute(\"data-floating-dock\");\n };\n }, [mode, container]);\n\n const toExplicit = () => {\n if (explicitH || !root.current) return;\n h.set(root.current.offsetHeight);\n setExplicitH(true);\n };\n const say = (text: string) => {\n const el = live.current;\n if (!el) return;\n el.textContent = \"\";\n window.setTimeout(() => {\n if (live.current) live.current.textContent = text;\n }, 60);\n };\n\n const reset = () => {\n patch(null);\n setExplicitH(false);\n w.set(PANEL_W);\n };\n React.useImperativeHandle(handle, () => ({\n dock: (side) => patch({ side, pos: undefined }),\n reset,\n keyboard: (m) => {\n if (mode !== \"float\") return;\n if (m === \"resize\") toExplicit();\n setKbd({ mode: m, start: { x: x.get(), y: y.get(), w: w.get(), h: root.current?.offsetHeight ?? h.get() }, explicit: explicitH });\n // after the ⋯ menu has handed focus back to its trigger\n window.setTimeout(() => root.current?.focus({ preventScroll: true }), 80);\n say(m === \"move\" ? \"Moving the panel. Arrow keys move it, Enter keeps it there, Escape cancels.\" : \"Resizing the panel. Arrow keys resize it, Enter keeps the size, Escape cancels.\");\n },\n announce: say,\n el: () => root.current,\n }));\n\n /** Esc: keyboard mode cancels first, then the panel closes and focus goes back to the card. */\n const escape = React.useCallback(() => {\n const k = kbdRef.current;\n if (k) {\n x.set(k.start.x);\n y.set(k.start.y);\n w.set(k.start.w);\n if (!k.explicit) setExplicitH(false);\n else h.set(k.start.h);\n setKbd(null);\n say(\"Cancelled\");\n return;\n }\n closeRef.current();\n backRef.current?.();\n }, [x, y, w, h]);\n\n // Esc / F6 from OUTSIDE the panel (the text, the page); the modal forwards its Esc through \"floatingpanel:escape\"\n React.useEffect(() => {\n const el = root.current;\n const onKey = (e: KeyboardEvent) => {\n if (el?.contains(e.target as Node)) return;\n if (e.key === \"F6\") {\n e.preventDefault();\n const f = Array.from(el?.querySelectorAll<HTMLElement>(`[data-panel-body] :is(${FOCUSABLE})`) ?? []).find((n) => n.getClientRects().length) ?? el;\n f?.focus({ preventScroll: true });\n return;\n }\n if (e.key !== \"Escape\" || e.defaultPrevented || layerOpen(el)) return;\n if (!container && document.querySelector(\"[data-expanded-editor]\")) return; // a D49 modal over us owns Esc\n e.preventDefault();\n escape();\n };\n const onForward = () => escape();\n window.addEventListener(\"keydown\", onKey);\n el?.addEventListener(\"floatingpanel:escape\", onForward);\n return () => {\n window.removeEventListener(\"keydown\", onKey);\n el?.removeEventListener(\"floatingpanel:escape\", onForward);\n };\n }, [container, escape]);\n\n // Keys inside the panel\n /* Keys inside the panel run on a NATIVE listener on the panel itself: it sees them first, wherever the panel is\n portalled (inside a modal, React's own listeners sit on other containers). */\n const keyRef = React.useRef<(e: KeyboardEvent) => void>(() => {});\n keyRef.current = (e: KeyboardEvent) => {\n const native = e as KeyboardEvent & { bcmsPanelHandled?: boolean };\n onPanelKeyDown?.(e);\n const k = kbdRef.current;\n if (k) {\n const step = e.shiftKey ? 64 : 16;\n const dx = e.key === \"ArrowRight\" ? step : e.key === \"ArrowLeft\" ? -step : 0;\n const dy = e.key === \"ArrowDown\" ? step : e.key === \"ArrowUp\" ? -step : 0;\n if (dx || dy) {\n e.preventDefault();\n if (k.mode === \"move\") {\n x.set(clampN(x.get() + dx, 8, vw() - w.get() - 8));\n y.set(clampN(y.get() + dy, NAV + 4, vh() - h.get() - 8));\n } else {\n w.set(clampN(w.get() + dx, FLOAT_BOUNDS.minW, FLOAT_BOUNDS.maxW()));\n h.set(clampN(h.get() + dy, FLOAT_BOUNDS.minH, FLOAT_BOUNDS.maxH()));\n x.set(clampN(x.get(), 8, vw() - w.get() - 8));\n }\n return;\n }\n if (e.key === \"Enter\") {\n e.preventDefault();\n patch(k.mode === \"move\" ? { pos: { x: x.get(), y: y.get() } } : { w: w.get(), h: h.get(), pos: { x: x.get(), y: y.get() } });\n setKbd(null);\n say(k.mode === \"move\" ? \"Panel moved\" : \"Panel resized\");\n return;\n }\n }\n if (e.key === \"F6\") {\n e.preventDefault();\n backRef.current?.();\n } else if (e.key === \"Escape\" && !native.bcmsPanelHandled && !(e.target as HTMLElement).closest?.(OWNS_ESCAPE) && !layerOpen(root.current)) {\n e.preventDefault();\n native.bcmsPanelHandled = true;\n escape();\n }\n };\n React.useEffect(() => {\n const el = root.current;\n if (!el) return;\n const on = (e: KeyboardEvent) => keyRef.current(e);\n el.addEventListener(\"keydown\", on);\n return () => el.removeEventListener(\"keydown\", on);\n }, [mode]);\n // keep keys away from the card / editor this panel was rendered from (modified keys still reach app shortcuts)\n const onKeyDown = (e: React.KeyboardEvent) => {\n if (!(e.metaKey || e.ctrlKey) || e.key.toLowerCase() === \"z\") e.stopPropagation();\n };\n\n const onHeaderDown = (e: React.PointerEvent) => {\n if (mode !== \"float\" || e.button !== 0 || (e.target as HTMLElement).closest(\"button, a, input, textarea, [role=menuitem], [contenteditable]\")) return;\n e.preventDefault();\n const ox = x.get();\n const oy = y.get();\n const ww = w.get();\n const hh = root.current?.offsetHeight ?? h.get();\n const col = column();\n const lines: SnapLines = { v: [EDGE, vw() - EDGE, ...(col ? [col.left, col.right] : [])], h: [TOP_LIMIT, vh() - EDGE] };\n busy.current = true;\n track(\n e,\n (dx, dy) => {\n const r = snapRect(ox + dx, oy + dy, ww, hh, lines, FLOAT_BOUNDS);\n x.set(r.x);\n y.set(r.y);\n setGuides((g) => (g.v.join() === r.g.v.join() && g.h.join() === r.g.h.join() ? g : r.g));\n },\n (moved) => {\n busy.current = false;\n setGuides(NO_GUIDES);\n if (moved) patch({ pos: { x: x.get(), y: y.get() } });\n },\n \"grabbing\",\n );\n };\n\n const headerEl = (\n <div\n data-panel-header=\"\"\n onPointerDown={onHeaderDown}\n onDoubleClick={(e) => {\n if (mode !== \"float\" || (e.target as HTMLElement).closest(\"button, a, input, [role=menuitem]\")) return;\n reset();\n }}\n className={cn(\"flex h-10 shrink-0 items-center gap-1 border-b border-kit-line-subtle pl-3 pr-1.5\", mode === \"float\" && \"cursor-grab touch-none select-none active:cursor-grabbing\")}\n >\n {header}\n </div>\n );\n const body = (\n <div data-panel-body=\"\" className={cn(\"min-h-0 flex-1 overflow-y-auto overscroll-contain\", bodyClassName)}>\n {children}\n </div>\n );\n const liveEl = <div ref={live} aria-live=\"polite\" className=\"sr-only\" />;\n const common = {\n ref: root,\n role: \"dialog\",\n \"aria-modal\": false as const,\n \"aria-labelledby\": labelledBy,\n tabIndex: -1,\n ...KIT_SCOPE,\n \"data-floating-layer\": \"\",\n \"data-floating-panel\": \"\",\n \"data-state\": \"open\",\n \"data-kbd\": kbd ? kbd.mode : undefined,\n onKeyDown,\n ...FENCE,\n };\n const fade = reduce || instant ? { duration: 0 } : { duration: 0.16, ease: EASE };\n\n let node: React.ReactNode;\n if (mode === \"sheet\") {\n node = (\n <motion.div\n {...common}\n initial={{ y: reduce || instant ? 0 : \"100%\" }}\n animate={{ y: 0 }}\n transition={reduce || instant ? { duration: 0 } : { duration: 0.24, ease: EASE }}\n style={{ height: `${sheetH}dvh` }}\n className={cn(\n \"fixed inset-x-0 bottom-0 z-[55] flex flex-col overflow-hidden rounded-t-kit-xl border-t border-kit-line pb-[env(safe-area-inset-bottom)] text-kit-fg outline-none\",\n SURFACE_RAISED,\n SHADOW_SHEET_B,\n )}\n >\n <SheetGrabber height={sheetH} onHeight={setSheetH} onClose={() => escape()} />\n {headerEl}\n {body}\n {sheetFooter ? <div className=\"flex shrink-0 justify-end border-t border-kit-line-subtle px-3 py-2\">{sheetFooter}</div> : null}\n {liveEl}\n </motion.div>\n );\n } else if (mode === \"side\") {\n node = (\n <motion.div\n {...common}\n initial={{ x: reduce || instant ? 0 : \"100%\" }}\n animate={{ x: 0 }}\n transition={reduce || instant ? { duration: 0 } : { duration: 0.22, ease: EASE }}\n style={{ width: PANEL_W, top: NAV }}\n className={cn(\"fixed bottom-0 right-0 z-[55] flex flex-col border-l border-kit-line text-kit-fg outline-none\", SURFACE_RAISED, SHADOW_SHEET_R)}\n >\n {headerEl}\n {body}\n {liveEl}\n </motion.div>\n );\n } else if (mode === \"modal\") {\n node = (\n <motion.div\n {...common}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={fade}\n style={modalFit === \"dock\" ? { width: PANEL_W, top: 48, right: 0, bottom: 0 } : modalFit === \"overlay\" ? { width: PANEL_W, top: 56, right: 8, bottom: 8 } : { left: 0, right: 0, bottom: 0, height: \"55%\" }}\n className={cn(\n \"absolute z-[20] flex flex-col overflow-hidden text-kit-fg outline-none\",\n SURFACE_RAISED,\n modalFit === \"dock\"\n ? \"border-l border-kit-line\"\n : modalFit === \"overlay\"\n ? cn(\"rounded-kit-xl border shadow-kit-lg\", FLOATING_LINE)\n : cn(\"rounded-t-kit-xl border-t border-kit-line\", SHADOW_SHEET_B),\n )}\n >\n {headerEl}\n {body}\n {liveEl}\n </motion.div>\n );\n } else {\n node = (\n <>\n <SnapGuides guides={guides} />\n <motion.div\n {...common}\n style={{ x, y, width: w, height: explicitH ? h : undefined, maxHeight: explicitH ? undefined : maxAuto, left: 0, top: 0 }}\n initial={{ opacity: 0, scale: reduce || instant ? 1 : 0.98 }}\n animate={{ opacity: 1, scale: 1 }}\n transition={fade}\n className={cn(\n \"fixed flex flex-col overflow-hidden rounded-kit-xl border text-kit-fg shadow-kit-xl outline-none\",\n SURFACE_RAISED,\n // floating = level 2: --line in light, the stronger hairline in dark (DARK_MODE §5)\n kbd ? \"border-dashed border-[var(--kit-emphasis-line)]\" : FLOATING_LINE,\n Z_FLOAT,\n )}\n >\n <ResizeEdges\n geom={geom}\n bounds={FLOAT_BOUNDS}\n onStart={() => {\n busy.current = true;\n toExplicit();\n }}\n onEnd={(dir) => {\n busy.current = false;\n const moved = dir.includes(\"w\") || dir.includes(\"n\") || !!prefRef.current.pos;\n patch({ w: w.get(), h: h.get(), ...(moved ? { pos: { x: x.get(), y: y.get() } } : {}) });\n }}\n />\n {headerEl}\n {body}\n <ResizeGrip\n geom={geom}\n bounds={FLOAT_BOUNDS}\n label=\"Resize panel\"\n onStart={toExplicit}\n onEnd={() => patch({ w: w.get(), h: h.get(), pos: { x: x.get(), y: y.get() } })}\n />\n {liveEl}\n </motion.div>\n </>\n );\n }\n return createPortal(node, container ?? document.body);\n});\nconst EMPTY: PanelPref = {};\n\n/** Bottom-sheet grabber: drag down to close, up for 90%; a tap toggles 50% ↔ 90%. */\nfunction SheetGrabber({ height, onHeight, onClose }: { height: 50 | 90; onHeight: (h: 50 | 90) => void; onClose: () => void }) {\n const dy = React.useRef(0);\n const dragged = React.useRef(false);\n return (\n <button\n type=\"button\"\n aria-label={height === 50 ? \"Expand panel\" : \"Shrink panel\"}\n onPointerDown={(e) => {\n dy.current = 0;\n dragged.current = false;\n track(\n e,\n (_dx, d) => {\n dy.current = d;\n dragged.current = true;\n },\n (moved) => {\n if (!moved) return;\n if (dy.current > 80) onClose();\n else if (dy.current < -40) onHeight(90);\n else if (dy.current > 40 && height === 90) onHeight(50);\n },\n );\n }}\n onClick={() => {\n if (dragged.current) return void (dragged.current = false);\n onHeight(height === 50 ? 90 : 50);\n }}\n className=\"flex h-5 w-full shrink-0 touch-none items-center justify-center\"\n >\n <span className=\"h-1 w-9 rounded-full bg-kit-line-strong\" />\n </button>\n );\n}\n"],"mappings":"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"}
|
package/ui/index.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import "./field-context.js";
|
|
2
|
-
import "./button.js";
|
|
3
|
-
import "./shortcut-hint.js";
|
|
4
|
-
import "./controls.js";
|
|
5
|
-
import "./overlay.js";
|
|
6
|
-
import "./display.js";
|
|
7
|
-
import "./input.js";
|
|
8
|
-
import "./presence.js";
|
|
9
|
-
import "./select.js";
|
|
10
|
-
import "./expanded-editor-modal.js";
|
|
11
|
-
import "./choice-switch.js";
|
|
12
|
-
import "./action-tray.js";
|
|
13
|
-
import "./mode-bar.js";
|
package/ui/input.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"input.js","names":[],"sources":["../../src/kit/ui/input.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { IconInfoCircle, IconSearch, IconX } from \"@tabler/icons-react\";\nimport { cn } from \"../lib/cn\";\nimport { HintTooltip } from \"./button\";\nimport { useShortcutHints } from \"./shortcut-hint\";\n\n/**\n * Inputs — CPO D19: white field + 1px --field-border at rest (default \"outline\"), border darkens on hover, halo on focus.\n * \"filled\" (grey, borderless) is kept only for search fields, which Figma draws grey.\n * Heights follow buttons: sm 28 · md 32 · lg 36.\n */\nimport {\n FieldDescribedByContext,\n FieldIdContext,\n FieldLabelledByContext,\n useFieldDescribedBy,\n useFieldId,\n useFieldLabelledBy,\n useLabelFor,\n} from \"./field-context\";\n/* The Field contexts live in field-context.ts so controls in other files (Switch, Select) read the same ones. */\nexport { FieldDescribedByContext, FieldLabelledByContext, useFieldDescribedBy, useFieldId, useFieldLabelledBy };\n\nconst joinIds = (...ids: (string | undefined)[]) => ids.filter(Boolean).join(\" \") || undefined;\n\nconst base =\n \"w-full min-w-0 rounded-kit-md border border-kit-field-border bg-kit-field-bg text-kit-fg shadow-kit-field placeholder:text-kit-fg-4 transition-[border-color,box-shadow] duration-150 hover:border-kit-field-border-hover focus:border-kit-field-border-focus focus:shadow-kit-ring-field disabled:cursor-not-allowed disabled:bg-kit-subtle disabled:opacity-60 aria-[invalid=true]:border-[var(--kit-field-invalid)]\";\n\nexport interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"size\" | \"prefix\"> {\n size?: \"sm\" | \"md\" | \"lg\";\n leading?: React.ReactNode;\n trailing?: React.ReactNode;\n variant?: \"filled\" | \"outline\";\n}\n\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, size = \"md\", leading, trailing, variant = \"outline\", ...rest }, ref) => {\n const fieldId = useFieldId();\n const labelledBy = useFieldLabelledBy();\n const named = rest.id ?? fieldId ?? rest[\"aria-label\"] ?? rest[\"aria-labelledby\"];\n const labelFor = useLabelFor(rest.id ?? fieldId);\n const describedBy = useFieldDescribedBy();\n const props = {\n ...rest,\n id: rest.id ?? fieldId,\n \"aria-labelledby\": rest[\"aria-labelledby\"] ?? (rest[\"aria-label\"] ? undefined : (labelFor ?? (named ? undefined : labelledBy))),\n \"aria-describedby\": joinIds(rest[\"aria-describedby\"], describedBy),\n };\n const h = size === \"sm\" ? \"h-7 text-kit-sm\" : size === \"lg\" ? \"h-9 text-kit-base\" : \"h-8 text-kit-sm\";\n const v = variant === \"filled\" ? \"bg-kit-muted border-transparent shadow-none hover:border-kit-line-strong placeholder:text-kit-fg-3\" : \"\";\n if (!leading && !trailing) return <input ref={ref} className={cn(base, h, v, \"px-2.5\", className)} {...props} />;\n return (\n <div className={cn(\"relative flex items-center\", className)}>\n {leading ? (\n <span className=\"pointer-events-none absolute left-2.5 flex text-kit-fg-3 [&_svg]:size-4\">{leading}</span>\n ) : null}\n <input ref={ref} className={cn(base, h, v, leading ? \"pl-8\" : \"pl-2.5\", trailing ? \"pr-8\" : \"pr-2.5\")} {...props} />\n {trailing ? <span className=\"absolute right-2 flex items-center text-kit-fg-3 [&_svg]:size-4\">{trailing}</span> : null}\n </div>\n );\n },\n);\nInput.displayName = \"Input\";\n\nexport type TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement> & { autoGrow?: boolean; variant?: \"filled\" | \"outline\" };\n\nexport const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(\n ({ className, autoGrow = true, variant = \"outline\", onInput, ...rest }, ref) => {\n const fieldId = useFieldId();\n const labelFor = useLabelFor(rest.id ?? fieldId);\n const describedBy = useFieldDescribedBy();\n const props = {\n ...rest,\n id: rest.id ?? fieldId,\n \"aria-labelledby\": rest[\"aria-labelledby\"] ?? (rest[\"aria-label\"] ? undefined : labelFor),\n \"aria-describedby\": joinIds(rest[\"aria-describedby\"], describedBy),\n };\n const inner = React.useRef<HTMLTextAreaElement | null>(null);\n React.useImperativeHandle(ref, () => inner.current as HTMLTextAreaElement);\n const grow = () => {\n const el = inner.current;\n if (!el || !autoGrow || !el.clientWidth) return; // hidden / zero-width: measuring now would be wrong\n el.style.height = \"auto\";\n el.style.height = `${el.scrollHeight + 2}px`;\n };\n React.useLayoutEffect(grow, [props.value, autoGrow]); // eslint-disable-line react-hooks/exhaustive-deps\n /* Re-measure when the WIDTH changes (a panel resize or a panel that mounts mid-animation): a height measured at a\n narrower width is stale and leaves single-line fields hundreds of px tall. Height-only changes are ignored, so\n the observer never feeds itself. */\n React.useEffect(() => {\n const el = inner.current;\n if (!el || !autoGrow || typeof ResizeObserver === \"undefined\") return;\n let w = el.clientWidth;\n let raf = 0;\n const ro = new ResizeObserver(() => {\n const nw = el.clientWidth;\n if (nw === w) return;\n w = nw;\n cancelAnimationFrame(raf);\n raf = requestAnimationFrame(grow);\n });\n ro.observe(el);\n return () => {\n cancelAnimationFrame(raf);\n ro.disconnect();\n };\n }, [autoGrow]); // eslint-disable-line react-hooks/exhaustive-deps\n return (\n <textarea\n ref={inner}\n rows={props.rows ?? 2}\n onInput={(e) => {\n grow();\n onInput?.(e);\n }}\n className={cn(\n base,\n \"min-h-16 resize-none px-2.5 py-2 text-kit-sm leading-[20px]\",\n variant === \"filled\" && \"bg-kit-muted border-transparent shadow-none placeholder:text-kit-fg-3\",\n className,\n )}\n {...props}\n />\n );\n },\n);\nTextarea.displayName = \"Textarea\";\n\nexport function SearchInput({\n value,\n onChange,\n placeholder = \"Search…\",\n className,\n size = \"md\",\n autoFocus,\n shortcut,\n variant = \"filled\",\n count,\n onKeyDown,\n inputRef,\n \"aria-label\": ariaLabel,\n}: {\n \"aria-label\"?: string;\n value: string;\n onChange: (v: string) => void;\n placeholder?: string;\n className?: string;\n size?: \"sm\" | \"md\" | \"lg\";\n autoFocus?: boolean;\n /** Shown only while the D44 keyboard hints switch is on. */\n shortcut?: string;\n /**\n * \"filled\" (grey) for search on white surfaces (menus, sidebars, lists); \"outline\" is the standard field (field-bg,\n * field-border) for search that sits on a grey plane, where a grey fill reads as a pill, not a field (D70, the schema desk).\n */\n variant?: \"filled\" | \"outline\";\n /** a result count shown inside the field while there is a query (\"3 matches\", \"2 of 5\"); announced politely */\n count?: string;\n onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>;\n inputRef?: React.Ref<HTMLInputElement>;\n}) {\n const hints = useShortcutHints();\n return (\n <Input\n ref={inputRef}\n variant={variant}\n size={size}\n autoFocus={autoFocus}\n value={value}\n placeholder={placeholder}\n aria-label={ariaLabel ?? placeholder.replace(/…$/, \"\")}\n onChange={(e) => onChange(e.target.value)}\n onKeyDown={onKeyDown}\n leading={<IconSearch aria-hidden />}\n className={cn(className, value && count ? \"[&_input]:pr-28\" : undefined)}\n trailing={\n value ? (\n <span className=\"flex items-center gap-1.5\">\n {count ? (\n <span aria-live=\"polite\" className=\"whitespace-nowrap text-kit-xs tabular-nums text-kit-fg-3\">\n {count}\n </span>\n ) : null}\n <button\n type=\"button\"\n aria-label=\"Clear search\"\n onClick={() => onChange(\"\")}\n className=\"flex size-5 items-center justify-center rounded-kit-sm text-kit-fg-3 hover:bg-kit-selected hover:text-kit-fg [&_svg]:size-3.5\"\n >\n <IconX aria-hidden />\n </button>\n </span>\n ) : shortcut && hints ? (\n <kbd data-hint=\"shortcuts\" className=\"font-kit-sans text-kit-2xs text-kit-fg-3\">\n {shortcut}\n </kbd>\n ) : undefined\n }\n />\n );\n}\n\nexport function Label({ className, ...props }: React.LabelHTMLAttributes<HTMLLabelElement>) {\n return <label className={cn(\"text-kit-sm font-medium text-kit-fg\", className)} {...props} />;\n}\n\n/**\n * Field = label row · help · control · error. CPO D39, the one help system (same spec as the Block Kit FieldShell):\n * [Label *] [hint] [i helpMore] …… [counter] [actions]\n * help: 12/16, --fg-3 (≥4.5:1 light + dark), 4px under the label, 1–2 lines\n * control\n * error: replaces the help, danger colour, under the control\n * The control gets `aria-describedby` → help + ⓘ text + error.\n * Required marker is --fg-2 with an sr-only \"(required)\" (DESIGN.md 13 #13, step 2).\n */\nexport function Field({\n label,\n htmlFor,\n hint,\n help,\n helpMore,\n error,\n required,\n counter,\n actions,\n children,\n className,\n}: {\n label?: React.ReactNode;\n htmlFor?: string;\n /** short, quiet aside on the label row (\"Optional\", \"Shown publicly\") */\n hint?: React.ReactNode;\n /** the help line under the label */\n help?: React.ReactNode;\n /** longer explanation behind the ⓘ next to the label */\n helpMore?: React.ReactNode;\n error?: React.ReactNode;\n required?: boolean;\n counter?: { value: number; max: number };\n actions?: React.ReactNode;\n children: React.ReactNode;\n className?: string;\n}) {\n const autoId = React.useId();\n const id = htmlFor ?? autoId;\n const helpId = `${id}-help`;\n const moreId = `${id}-more`;\n const errId = `${id}-error`;\n const describedBy = [error ? errId : help ? helpId : null, helpMore ? moreId : null].filter(Boolean).join(\" \") || undefined;\n return (\n <div className={cn(\"flex flex-col gap-1.5\", className)}>\n {label || actions || counter ? (\n <div className=\"flex min-h-5 items-center justify-between gap-2\">\n <span className=\"flex min-w-0 items-center gap-1\">\n <Label htmlFor={label ? id : undefined} className=\"flex items-center gap-1.5 text-kit-sm text-kit-fg-2\">\n {label}\n {required ? (\n <>\n <span aria-hidden className=\"text-kit-fg-2\">*</span>\n <span className=\"sr-only\">(required)</span>\n </>\n ) : null}\n {hint ? <span className=\"font-normal text-kit-fg-3\">{hint}</span> : null}\n </Label>\n {helpMore ? (\n <HelpMore id={moreId} label={typeof label === \"string\" ? label : undefined}>\n {helpMore}\n </HelpMore>\n ) : null}\n </span>\n <div className=\"flex items-center gap-1\">\n {counter ? (\n <span\n className={cn(\n \"tabular-nums text-kit-xs\",\n counter.value > counter.max\n ? \"text-kit-danger-fg\"\n : counter.value > counter.max * 0.9\n ? \"text-kit-warning-fg\"\n : \"text-kit-fg-3\",\n )}\n >\n {counter.value}/{counter.max}\n </span>\n ) : null}\n {actions}\n </div>\n </div>\n ) : null}\n {help && !error ? (\n <p id={helpId} data-slot=\"field-help\" className=\"-mt-0.5 text-kit-xs leading-4 text-kit-fg-3\">\n {help}\n </p>\n ) : null}\n <FieldIdContext.Provider value={label ? id : undefined}>\n <FieldDescribedByContext.Provider value={describedBy}>{children}</FieldDescribedByContext.Provider>\n </FieldIdContext.Provider>\n {error ? (\n <p id={errId} role=\"alert\" className=\"text-kit-xs leading-4 text-kit-danger-fg\">\n {error}\n </p>\n ) : null}\n </div>\n );\n}\n\n/** The ⓘ next to a label: longer help in a tooltip, also read by screen readers through aria-describedby (D39). */\nexport function HelpMore({ id, label, children }: { id?: string; label?: string; children: React.ReactNode }) {\n return (\n <HintTooltip content={<span className=\"block max-w-[260px] whitespace-normal font-normal leading-4\">{children}</span>}>\n <button\n type=\"button\"\n aria-label={label ? `About ${label}` : \"More about this field\"}\n className=\"inline-flex size-4 shrink-0 items-center justify-center rounded-kit-sm text-kit-fg-4 hover:text-kit-fg-2\"\n >\n <IconInfoCircle className=\"size-3.5\" stroke={1.5} aria-hidden />\n <span id={id} className=\"sr-only\">\n {children}\n </span>\n </button>\n </HintTooltip>\n );\n}\n"],"mappings":"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"}
|
package/ui/mode-bar.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mode-bar.js","names":[],"sources":["../../src/kit/ui/mode-bar.tsx"],"sourcesContent":["/**\n * MODE BAR (D61 §3.7, shared with D58 view-as). One 36px strip that says \"you are in a mode\": an icon, a sentence and\n * its actions, with a polite live-region announcement. The primitive is shared; the placement is not:\n *\n * - View as (D58): app-wide, above the top bar (it changes who you are). `tone=\"info\"`, centred. Esc does not exit.\n * - Revision preview (D61): inside the editor, under its header (it changes what you are looking at).\n * `tone=\"raised\"`, start-aligned. Esc goes back to current (the host wires it).\n *\n * If both apply, both show: view-as on top. Tokens only, both themes (D56).\n * The strip sits in the app shell, outside any kit host, so its root carries the kit scope itself (like the portalled layers).\n */\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { KIT_SCOPE, SURFACE_RAISED } from \"./surfaces\";\n\nexport type ModeBarTone = \"info\" | \"raised\";\n\nconst TONE: Record<ModeBarTone, string> = {\n info: \"border-kit-info-line bg-kit-info-soft\",\n raised: cn(\"border-kit-line\", SURFACE_RAISED),\n};\n\nexport interface ModeBarProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"role\"> {\n /** the region's accessible name (\"View as\", \"Version preview\") */\n label: string;\n /** a 16px glyph, decorative */\n icon?: React.ReactNode;\n tone?: ModeBarTone;\n /** \"center\" (view-as) or \"start\" (revision preview) */\n align?: \"center\" | \"start\";\n /** polite announcement, read once when it changes */\n announce?: string;\n}\n\nexport const ModeBar = React.forwardRef<HTMLDivElement, ModeBarProps>(function ModeBar(\n { label, icon, tone = \"info\", align = \"center\", announce, className, children, ...rest },\n ref,\n) {\n return (\n <div\n ref={ref}\n role=\"region\"\n aria-label={label}\n data-mode-bar={tone}\n {...KIT_SCOPE}\n className={cn(\n \"relative flex h-9 shrink-0 items-center gap-2 border-b px-4 text-kit-sm text-kit-fg\",\n align === \"center\" ? \"justify-center\" : \"justify-start\",\n TONE[tone],\n className,\n )}\n {...rest}\n >\n <span aria-live=\"polite\" className=\"sr-only\">{announce ?? \"\"}</span>\n {icon ? <span aria-hidden className=\"flex shrink-0 text-kit-fg-2 [&>svg]:size-4\">{icon}</span> : null}\n {children}\n </div>\n );\n});\n\n/** The quiet \"·\" between parts of a mode bar sentence. */\nexport function ModeBarDot({ className }: { className?: string }) {\n return <span aria-hidden className={cn(\"text-kit-fg-3\", className)}>·</span>;\n}\n\n/** A text action in a mode bar (\"Exit\"): underlined, not a button chip. */\nexport const ModeBarLink = React.forwardRef<HTMLButtonElement, React.ButtonHTMLAttributes<HTMLButtonElement>>(function ModeBarLink(\n { className, ...rest },\n ref,\n) {\n return (\n <button\n ref={ref}\n type=\"button\"\n className={cn(\n \"shrink-0 rounded-kit-sm px-1 font-medium text-kit-fg underline decoration-kit-fg-3 underline-offset-2 hover:decoration-kit-fg\",\n className,\n )}\n {...rest}\n />\n );\n});\n"],"mappings":";;;;;;;;;;;;;;;;AAiBA,IAAM,OAAoC;CACxC,MAAM;CACN,QAAQ,GAAG,mBAAmB,eAAe;CAC9C;AAcD,IAAa,UAAU,MAAM,WAAyC,SAAS,QAC7E,EAAE,OAAO,MAAM,OAAO,QAAQ,QAAQ,UAAU,UAAU,WAAW,UAAU,GAAG,QAClF,KACA;AACA,QACE,qBAAC,OAAD;EACO;EACL,MAAK;EACL,cAAY;EACZ,iBAAe;EACf,GAAI;EACJ,WAAW,GACT,uFACA,UAAU,WAAW,mBAAmB,iBACxC,KAAK,OACL,UACD;EACD,GAAI;YAZN;GAcE,oBAAC,QAAD;IAAM,aAAU;IAAS,WAAU;cAAW,YAAY;IAAU,CAAA;GACnE,OAAO,oBAAC,QAAD;IAAM,eAAA;IAAY,WAAU;cAA8C;IAAY,CAAA,GAAG;GAChG;GACG;;EAER;;AAGF,SAAgB,WAAW,EAAE,aAAqC;AAChE,QAAO,oBAAC,QAAD;EAAM,eAAA;EAAY,WAAW,GAAG,iBAAiB,UAAU;YAAE;EAAQ,CAAA;;;AAI9E,IAAa,cAAc,MAAM,WAA6E,SAAS,YACrH,EAAE,WAAW,GAAG,QAChB,KACA;AACA,QACE,oBAAC,UAAD;EACO;EACL,MAAK;EACL,WAAW,GACT,iIACA,UACD;EACD,GAAI;EACJ,CAAA;EAEJ"}
|