@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select.js","names":[],"sources":["../../src/ui/select.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Select as SelectPrimitive } from \"@base-ui/react/select\";\nimport { Combobox as ComboboxPrimitive } from \"@base-ui/react/combobox\";\nimport type { BaseUIEvent } from \"@base-ui/react/types\";\nimport { IconCheck, IconChevronDown, IconSearch } from \"@tabler/icons-react\";\nimport { cn } from \"../lib/cn\";\nimport { useFieldId, useFieldLabelledBy, useLabelFor } from \"./field-context\";\nimport { Avatar } from \"./display\";\nimport { KIT_SCOPE } from \"./surfaces\";\n\n/* ── Select ─────────────────────────────────────────────────────────────────\n D34 — one Select for every dropdown. Up to SEARCH_THRESHOLD options it is a plain Base UI Select; past that (or\n with `searchable`) the same trigger opens a Base UI Combobox: sticky search at the top, type-to-filter with\n fuzzy-ish matching and highlighted matches, ↑↓ / Enter / Esc, typing on the closed trigger starts a search,\n groups, avatars / icons, secondary text, \"No matches\". Call sites don't change — long lists just get search. */\n\nexport const SEARCH_THRESHOLD = 7;\n\nexport type SelectOption = {\n value: string;\n label: React.ReactNode;\n /** leading visual (16px icon); ignored when `avatar` is set */\n icon?: React.ReactNode;\n /** a person: renders a 20px avatar before the label */\n avatar?: { name: string; src?: string };\n /** secondary line under the label (e.g. an email) — searchable */\n description?: string;\n /** muted right-aligned text (e.g. \"UTC+1\", a count) — searchable */\n meta?: string;\n /** extra words that should match (aliases, ids) */\n keywords?: string[];\n /** group heading; options with the same group render together, in first-seen order */\n group?: string;\n disabled?: boolean;\n};\n\n/* ── Matching (exported so custom pickers can share it) ─────────────────── */\n\n/** Plain text of a React node — lets `label` stay a ReactNode while still being searchable. */\nexport function nodeText(node: React.ReactNode): string {\n if (node == null || typeof node === \"boolean\") return \"\";\n if (typeof node === \"string\" || typeof node === \"number\") return String(node);\n if (Array.isArray(node)) return node.map(nodeText).join(\"\");\n if (React.isValidElement<{ children?: React.ReactNode }>(node)) return nodeText(node.props.children);\n return \"\";\n}\n\nconst SEP = /[\\s\\-_/.(@+]/;\nconst norm = (s: string) => s.normalize(\"NFD\").replace(/[̀-ͯ]/g, \"\").toLowerCase();\n\n/**\n * Score how well `query` matches `text` (0 = no match). Every whitespace-separated term must match.\n * Prefix > word start > substring > in-order characters (\"nyk\" → \"New York\").\n */\nexport function matchScore(text: string, query: string, { fuzzy = true }: { fuzzy?: boolean } = {}): number {\n const t = norm(text);\n const terms = norm(query).trim().split(/\\s+/).filter(Boolean);\n if (!terms.length) return 1;\n let score = 0;\n for (const term of terms) {\n const at = t.indexOf(term);\n if (at === 0) score += 4;\n else if (at > 0) score += SEP.test(t[at - 1]) ? 3 : 2;\n else if (fuzzy && fuzzyPositions(t, term)) score += 1;\n else return 0;\n }\n return score;\n}\n\n/** In-order characters of `term` in `t`, tight enough to be intended (\"nyk\" → New York, not across a paragraph). */\nfunction fuzzyPositions(t: string, term: string): number[] | null {\n if (term.length < 2) return null;\n // start at a word boundary (\"nyk\" → New York, not \"krasnoyarsk\"); try each so a tighter run wins\n for (let start = t.indexOf(term[0]); start >= 0; start = t.indexOf(term[0], start + 1)) {\n if (start > 0 && !SEP.test(t[start - 1])) continue;\n const out = [start];\n let i = start + 1;\n for (const ch of term.slice(1)) {\n i = t.indexOf(ch, i);\n if (i < 0) break;\n out.push(i++);\n }\n if (out.length === term.length && out[out.length - 1] - start + 1 <= term.length * 3) return out;\n }\n return null;\n}\n\n/** Character indexes of `text` to emphasise for `query` (substring per term, else in-order characters). */\nexport function matchPositions(text: string, query: string): Set<number> {\n const t = norm(text);\n const hits = new Set<number>();\n for (const term of norm(query).trim().split(/\\s+/).filter(Boolean)) {\n const at = t.indexOf(term);\n if (at >= 0) for (let k = 0; k < term.length; k++) hits.add(at + k);\n else fuzzyPositions(t, term)?.forEach((k) => hits.add(k));\n }\n return hits;\n}\n\n/** Renders `text` with the characters that match `query` emphasised. */\nexport function Highlight({ text, query }: { text: string; query: string }) {\n if (!query.trim()) return <>{text}</>;\n // NFD normalisation can change length for accented text; only highlight when indexes line up.\n if (norm(text).length !== text.length) return <>{text}</>;\n const hits = matchPositions(text, query);\n if (!hits.size) return <>{text}</>;\n const parts: React.ReactNode[] = [];\n let run = \"\";\n let on = false;\n const flush = (k: number) => {\n if (!run) return;\n parts.push(on ? <mark key={k} className=\"rounded-[2px] bg-transparent font-semibold text-kit-fg\">{run}</mark> : run);\n run = \"\";\n };\n for (let k = 0; k < text.length; k++) {\n const h = hits.has(k);\n if (h !== on) {\n flush(k);\n on = h;\n }\n run += text[k];\n }\n flush(text.length);\n return <>{parts}</>;\n}\n\n/** Filter + rank options for `query` (stable within equal scores). */\nexport function filterOptions<T extends SelectOption>(options: T[], query: string): T[] {\n if (!query.trim()) return options;\n return options\n .map((o, i) => {\n const label = nodeText(o.label);\n const main = matchScore(label, query);\n // secondary text (email, region, aliases) matches on whole substrings only — fuzzy there is noise\n const rest = matchScore([label, o.description, o.meta, ...(o.keywords ?? [])].filter(Boolean).join(\" \"), query, { fuzzy: false });\n // a hit in the label outranks a hit only in secondary text\n // an alias typed exactly (\"IST\", \"PT\", a tag) is as good as a label prefix\n const exact = o.keywords?.some((k) => norm(k) === norm(query.trim())) ? 9 : 0;\n return { o, i, s: Math.max(main ? main * 2 + 1 : rest, exact), len: label.length };\n })\n .filter((x) => x.s > 0)\n .sort((a, b) => b.s - a.s || a.len - b.len || a.i - b.i)\n .map((x) => x.o);\n}\n\nfunction grouped<T extends SelectOption>(options: T[]): { group?: string; items: T[] }[] {\n if (!options.some((o) => o.group)) return [{ items: options }];\n const out: { group?: string; items: T[] }[] = [];\n for (const o of options) {\n const g = out.find((x) => x.group === o.group);\n if (g) g.items.push(o);\n else out.push({ group: o.group, items: [o] });\n }\n return out;\n}\n\n/* ── Shared look ────────────────────────────────────────────────────────── */\n\nfunction triggerClass(variant: \"filled\" | \"outline\" | \"ghost\", size: \"sm\" | \"md\" | \"lg\") {\n const h = size === \"sm\" ? \"h-7 text-kit-sm\" : size === \"lg\" ? \"h-9 text-kit-base\" : \"h-8 text-kit-sm\";\n return cn(\n \"group inline-flex w-full min-w-0 items-center justify-between gap-2 rounded-kit-md border px-2.5 text-left text-kit-fg transition-colors data-[placeholder]:text-kit-fg-3 disabled:cursor-not-allowed disabled:opacity-60 data-[disabled]:cursor-not-allowed data-[disabled]:opacity-60\",\n variant === \"filled\" && \"border-kit-field-border bg-kit-field-bg shadow-kit-field hover:border-kit-field-border-hover\",\n variant === \"outline\" && \"border-kit-line bg-kit-field-bg shadow-kit-xs hover:border-kit-line-strong\",\n variant === \"ghost\" && \"w-auto border-transparent bg-transparent px-2 text-kit-fg-2 hover:bg-kit-hover hover:text-kit-fg\",\n h,\n );\n}\n\n/** The Select trigger look, for controls that open their own picker but must read as a Select (D57: one look per job). */\nexport const selectTriggerClass = triggerClass;\n\n/* V2 select.tsx:174-178. Base UI marks the highlighted and disabled rows of both the Select and the Combobox with\n data-highlighted / data-disabled, so the two lists share itemClass (V2's cmdk list used data-selected=true). */\nconst itemBase =\n \"relative flex cursor-pointer select-none items-center gap-2 rounded-kit-md py-1.5 pl-2 pr-8 text-kit-sm text-kit-fg outline-none [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-kit-fg-2\";\nconst itemClass = cn(itemBase, \"data-[disabled]:pointer-events-none data-[disabled]:opacity-40 data-[highlighted]:bg-kit-hover\");\n\nconst groupHeading = \"px-2 pb-1 pt-2 text-kit-xs font-medium text-kit-fg-3\";\n\nfunction Lead({ o }: { o: SelectOption }) {\n if (o.avatar) return <Avatar name={o.avatar.name} src={o.avatar.src} size={20} decorative />;\n return o.icon ? <>{o.icon}</> : null;\n}\n\n/* ── Select ─────────────────────────────────────────────────────────────── */\n\nexport interface SelectProps {\n id?: string;\n \"aria-label\"?: string;\n value?: string;\n /** uncontrolled starting value (leave `value` undefined) */\n defaultValue?: string;\n onValueChange?: (v: string) => void;\n options: SelectOption[];\n placeholder?: string;\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n triggerClassName?: string;\n variant?: \"filled\" | \"outline\" | \"ghost\";\n align?: \"start\" | \"center\" | \"end\";\n disabled?: boolean;\n /** \"auto\" (default): search appears when there are more than 7 options. */\n searchable?: boolean | \"auto\";\n searchPlaceholder?: string;\n /** popover width for the searchable menu (defaults to the trigger, at least 240px) */\n menuClassName?: string;\n}\n\nexport function Select(props: SelectProps) {\n const { searchable = \"auto\", options } = props;\n const search = searchable === true || (searchable === \"auto\" && options.length > SEARCH_THRESHOLD);\n return search ? <SearchSelect {...props} /> : <PlainSelect {...props} />;\n}\n\nfunction useTriggerA11y(id: string | undefined, ariaLabel: string | undefined, placeholder: React.ReactNode) {\n const fieldId = useFieldId();\n const labelledBy = useFieldLabelledBy();\n const labelFor = useLabelFor(id ?? fieldId);\n return {\n id: id ?? fieldId,\n \"aria-label\": ariaLabel ?? (fieldId || labelledBy || labelFor ? undefined : typeof placeholder === \"string\" && placeholder !== \"Select…\" ? placeholder : undefined),\n \"aria-labelledby\": ariaLabel ? undefined : (labelFor ?? (id || fieldId ? undefined : labelledBy)),\n };\n}\n\n/** Value that is controlled when `value` is passed and internal otherwise. */\nfunction useSelectValue(value: string | undefined, defaultValue: string | undefined, onValueChange?: (v: string) => void) {\n const [inner, setInner] = React.useState(defaultValue);\n const controlled = value !== undefined;\n const current = controlled ? value : inner;\n const set = (v: string) => {\n if (!controlled) setInner(v);\n onValueChange?.(v);\n };\n return [current, set] as const;\n}\n\nfunction PlainSelect({\n value,\n defaultValue,\n onValueChange,\n options,\n placeholder = \"Select…\",\n size = \"md\",\n className,\n triggerClassName,\n variant = \"filled\",\n align = \"start\",\n disabled,\n id,\n \"aria-label\": ariaLabel,\n}: SelectProps) {\n const a11y = useTriggerA11y(id, ariaLabel, placeholder);\n const [current, setCurrent] = useSelectValue(value, defaultValue, onValueChange);\n const [open, setOpen] = React.useState(false);\n const items = React.useMemo(() => options.map((o) => ({ value: o.value, label: o.label })), [options]);\n const renderItem = (o: SelectOption) => (\n <SelectPrimitive.Item key={o.value} value={o.value} disabled={o.disabled} className={itemClass}>\n <Lead o={o} />\n <div className=\"min-w-0 flex-1\">\n <SelectPrimitive.ItemText>{o.label}</SelectPrimitive.ItemText>\n {o.description ? <div className=\"text-kit-xs text-kit-fg-3\">{o.description}</div> : null}\n </div>\n {o.meta ? <span className=\"shrink-0 text-kit-xs tabular-nums text-kit-fg-3\">{o.meta}</span> : null}\n <SelectPrimitive.ItemIndicator className=\"absolute right-2\">\n <IconCheck className=\"size-4 text-kit-fg\" />\n </SelectPrimitive.ItemIndicator>\n </SelectPrimitive.Item>\n );\n return (\n <SelectPrimitive.Root<string>\n items={items}\n value={current ?? null}\n onValueChange={(v) => v != null && setCurrent(v)}\n onOpenChange={setOpen}\n disabled={disabled}\n >\n <SelectPrimitive.Trigger\n {...a11y}\n data-state={open ? \"open\" : \"closed\"}\n className={cn(triggerClass(variant, size), triggerClassName, className)}\n >\n <span className=\"flex min-w-0 items-center gap-2 truncate [&_svg]:size-4 [&_svg]:text-kit-fg-3\">\n <SelectPrimitive.Value placeholder={placeholder} />\n </span>\n <SelectPrimitive.Icon>\n <IconChevronDown className=\"size-3.5 text-kit-fg-3 transition-transform group-data-[popup-open]:rotate-180\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n <SelectPrimitive.Portal>\n <SelectPrimitive.Positioner align={align} sideOffset={6} alignItemWithTrigger={false} className=\"z-[var(--kit-z-menu,80)]\" data-floating-layer=\"\" {...KIT_SCOPE}>\n <SelectPrimitive.Popup\n className=\"glass max-h-[min(360px,var(--available-height))] min-w-[var(--anchor-width)] overflow-y-auto rounded-kit-lg border p-1 data-[open]:animate-kit-pop-in\"\n >\n <SelectPrimitive.List>\n {grouped(options).map((g, gi) =>\n g.group ? (\n <SelectPrimitive.Group key={g.group + gi}>\n <SelectPrimitive.GroupLabel className={groupHeading}>{g.group}</SelectPrimitive.GroupLabel>\n {g.items.map(renderItem)}\n </SelectPrimitive.Group>\n ) : (\n g.items.map(renderItem)\n ),\n )}\n </SelectPrimitive.List>\n </SelectPrimitive.Popup>\n </SelectPrimitive.Positioner>\n </SelectPrimitive.Portal>\n </SelectPrimitive.Root>\n );\n}\n\n/** V2 scrollIntoContainer (block \"nearest\", 4px margin): scroll `el` into view inside `list` ONLY, never the shell behind it.\n * Rects are transformed while the menu pops in (scaled), so measure in layout pixels. */\nfunction revealInList(list: HTMLElement, el: HTMLElement | null, margin = 4) {\n if (!el) return;\n const br = list.getBoundingClientRect();\n const er = el.getBoundingClientRect();\n const k = list.offsetHeight ? br.height / list.offsetHeight || 1 : 1;\n const top = (er.top - br.top) / k + list.scrollTop;\n const h = er.height / k;\n let next = list.scrollTop;\n if (top < list.scrollTop) next = top - margin;\n else if (top + h > list.scrollTop + list.clientHeight) next = top + h - list.clientHeight + margin;\n next = Math.max(0, Math.min(next, list.scrollHeight - list.clientHeight));\n if (Math.abs(next - list.scrollTop) > 0.5) list.scrollTop = next;\n}\n\nfunction SearchSelect({\n value,\n defaultValue,\n onValueChange,\n options,\n placeholder = \"Select…\",\n size = \"md\",\n className,\n triggerClassName,\n variant = \"filled\",\n align = \"start\",\n disabled,\n id,\n \"aria-label\": ariaLabel,\n searchPlaceholder = \"Search…\",\n menuClassName,\n}: SelectProps) {\n const a11y = useTriggerA11y(id, ariaLabel, placeholder);\n const [current, setCurrent] = useSelectValue(value, defaultValue, onValueChange);\n const [open, setOpen] = React.useState(false);\n const [query, setQuery] = React.useState(\"\");\n const selected = options.find((o) => o.value === current);\n const shown = React.useMemo(() => filterOptions(options, query), [options, query]);\n const shownValues = React.useMemo(() => shown.map((o) => o.value), [shown]);\n const listRef = React.useRef<HTMLDivElement>(null);\n\n /* Reveal the current option on open, inside the list only: scrollIntoView would also scroll the app shell behind the\n menu (V2 S1). The popup sizes itself a frame or two after it opens, so wait until the list is constrained (it\n scrolls) before revealing (the list portals in, so it may not exist on the first frame either). */\n React.useEffect(() => {\n if (!open) return;\n let raf = 0;\n const reveal = (tries: number) => {\n const list = listRef.current;\n const settled = list && list.scrollHeight > list.clientHeight;\n if (!settled && tries > 0) return void (raf = requestAnimationFrame(() => reveal(tries - 1)));\n if (list) revealInList(list, list.querySelector<HTMLElement>('[data-checked=\"true\"]'));\n };\n reveal(6);\n return () => cancelAnimationFrame(raf);\n }, [open]);\n\n const openWith = (q: string) => {\n setQuery(q);\n setOpen(true);\n };\n\n return (\n <ComboboxPrimitive.Root<string>\n value={current ?? null}\n onValueChange={(v) => {\n if (v == null) return;\n setCurrent(v);\n setOpen(false);\n }}\n open={open}\n onOpenChange={(o) => (o ? openWith(\"\") : setOpen(false))}\n inputValue={query}\n onInputValueChange={(q, details) => {\n // only typing filters; Base UI also writes the picked option's value into the input on selection\n if (details.reason === \"input-change\" || details.reason === \"input-clear\") setQuery(q);\n }}\n items={shownValues}\n filter={null}\n autoHighlight\n loopFocus\n disabled={disabled}\n >\n <ComboboxPrimitive.Trigger\n {...a11y}\n data-state={open ? \"open\" : \"closed\"}\n data-placeholder={selected ? undefined : \"\"}\n className={cn(triggerClass(variant, size), triggerClassName, className)}\n onKeyDown={(e: BaseUIEvent<React.KeyboardEvent<HTMLButtonElement>>) => {\n if (e.metaKey || e.ctrlKey || e.altKey) return;\n if (e.key.length === 1 && e.key !== \" \") {\n e.preventDefault();\n e.preventBaseUIHandler();\n openWith(e.key); // typing on the closed trigger starts a search\n } else if (e.key === \"ArrowDown\" || e.key === \"ArrowUp\") {\n e.preventDefault();\n e.preventBaseUIHandler();\n openWith(\"\");\n }\n }}\n >\n <span className=\"flex min-w-0 items-center gap-2 truncate [&_svg]:size-4 [&_svg]:text-kit-fg-3\">\n {selected ? (\n <>\n {selected.avatar ? <Avatar name={selected.avatar.name} src={selected.avatar.src} size={16} decorative /> : null}\n <span className=\"truncate\">{selected.label}</span>\n </>\n ) : (\n <span className=\"truncate\">{placeholder}</span>\n )}\n </span>\n <IconChevronDown aria-hidden className=\"size-3.5 shrink-0 text-kit-fg-3 transition-transform group-data-[popup-open]:rotate-180\" />\n </ComboboxPrimitive.Trigger>\n <ComboboxPrimitive.Portal>\n <ComboboxPrimitive.Positioner align={align} sideOffset={6} collisionPadding={12} className=\"z-[var(--kit-z-menu,80)]\" data-floating-layer=\"\" {...KIT_SCOPE}>\n <ComboboxPrimitive.Popup\n className={cn(\n \"glass flex max-h-[min(400px,var(--available-height))] w-[max(var(--anchor-width),240px)] max-w-[min(400px,calc(100vw-24px))] flex-col overflow-hidden rounded-kit-lg border text-kit-fg outline-none data-[open]:animate-kit-pop-in\",\n menuClassName,\n )}\n >\n {/* V2's <Command> root (select.tsx:403) */}\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"flex h-9 shrink-0 items-center gap-2 border-b border-kit-line-subtle px-2.5 text-kit-fg-3\">\n <IconSearch aria-hidden className=\"size-4 shrink-0\" />\n <ComboboxPrimitive.Input\n aria-label={typeof a11y[\"aria-label\"] === \"string\" ? a11y[\"aria-label\"] : \"Options\"}\n placeholder={searchPlaceholder}\n className=\"h-full min-w-0 flex-1 bg-transparent text-kit-sm text-kit-fg outline-none placeholder:text-kit-fg-4\"\n />\n </div>\n {shown.length === 0 ? <div className=\"px-2 py-6 text-center text-kit-sm text-kit-fg-3\">No matches</div> : null}\n <ComboboxPrimitive.List ref={listRef} className=\"min-h-0 flex-1 overflow-y-auto overscroll-contain p-1 empty:hidden\">\n {grouped(shown).map((g, gi) => {\n const items = g.items.map((o) => {\n const text = nodeText(o.label);\n const checked = o.value === current;\n return (\n <ComboboxPrimitive.Item key={o.value} value={o.value} disabled={o.disabled} data-checked={checked} className={itemClass}>\n <Lead o={o} />\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate\">{typeof o.label === \"string\" ? <Highlight text={text} query={query} /> : o.label}</div>\n {o.description ? (\n <div className=\"truncate text-kit-xs text-kit-fg-3\">\n <Highlight text={o.description} query={query} />\n </div>\n ) : null}\n </div>\n {o.meta ? <span className=\"shrink-0 text-kit-xs tabular-nums text-kit-fg-3\">{o.meta}</span> : null}\n {checked ? <IconCheck aria-hidden className=\"absolute right-2 size-4 !text-kit-fg\" /> : null}\n </ComboboxPrimitive.Item>\n );\n });\n return g.group ? (\n <ComboboxPrimitive.Group key={g.group + gi}>\n <ComboboxPrimitive.GroupLabel className={groupHeading}>{g.group}</ComboboxPrimitive.GroupLabel>\n {items}\n </ComboboxPrimitive.Group>\n ) : (\n <React.Fragment key={\"g\" + gi}>{items}</React.Fragment>\n );\n })}\n </ComboboxPrimitive.List>\n </div>\n </ComboboxPrimitive.Popup>\n </ComboboxPrimitive.Positioner>\n </ComboboxPrimitive.Portal>\n </ComboboxPrimitive.Root>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { Fragment, jsx } from "react/jsx-runtime";
|
|
3
|
-
//#region src/
|
|
3
|
+
//#region src/ui/shortcut-hint.tsx
|
|
4
4
|
var ShortcutHintsContext = React.createContext(false);
|
|
5
5
|
var current = false;
|
|
6
6
|
function ShortcutHintsProvider({ on = false, children }) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shortcut-hint.js","names":[],"sources":["../../src/ui/shortcut-hint.tsx"],"sourcesContent":["import * as React from \"react\";\n\n/* D44: keyboard-shortcut hints are OFF by default (founder: \"genuinely irritating\").\n Account > Preferences > \"Show keyboard hints\" turns them back on; the host passes that preference to\n <ShortcutHintsProvider on={...}>.\n - <ShortcutHint>…</ShortcutHint> renders nothing while off (use it for every new inline hint strip).\n - `as` keeps the wrapper element when the hint needs one (span by default; `fragment` for none).\n - For markup you cannot wrap, add data-hint=\"shortcuts\": the provider mirrors the switch on\n <html data-shortcut-hints=\"on|off\"> and the stylesheet hides it while off.\n - For strings (toasts, placeholders) use useShortcutHints() / shortcutHintsOn().\n NOT hints (always shown): menu shortcut columns, the command palette's key labels, the help sheet. */\n\nconst ShortcutHintsContext = React.createContext(false);\nlet current = false;\n\nexport function ShortcutHintsProvider({ on = false, children }: { on?: boolean; children: React.ReactNode }) {\n React.useLayoutEffect(() => {\n current = on;\n if (typeof document !== \"undefined\") document.documentElement.dataset.shortcutHints = on ? \"on\" : \"off\";\n }, [on]);\n return <ShortcutHintsContext.Provider value={on}>{children}</ShortcutHintsContext.Provider>;\n}\n\nexport function useShortcutHints() {\n return React.useContext(ShortcutHintsContext);\n}\n\n/** Non-hook read for toasts and other imperative call sites. */\nexport function shortcutHintsOn() {\n return current;\n}\n\ntype Props = React.HTMLAttributes<HTMLElement> & { as?: \"span\" | \"div\" | \"p\" | \"li\" | \"fragment\"; children: React.ReactNode };\n\nexport function ShortcutHint({ as = \"span\", children, ...rest }: Props) {\n const on = useShortcutHints();\n if (!on) return null;\n if (as === \"fragment\") return <>{children}</>;\n const Tag = as as \"span\";\n return (\n <Tag data-hint=\"shortcuts\" {...rest}>\n {children}\n </Tag>\n );\n}\n"],"mappings":";;;AAYA,IAAM,uBAAuB,MAAM,cAAc,KAAK;AACtD,IAAI,UAAU;AAEd,SAAgB,sBAAsB,EAAE,KAAK,OAAO,YAAyD;CAC3G,MAAM,sBAAsB;EAC1B,UAAU;EACV,IAAI,OAAO,aAAa,aAAa,SAAS,gBAAgB,QAAQ,gBAAgB,KAAK,OAAO;CACpG,GAAG,CAAC,EAAE,CAAC;CACP,OAAO,oBAAC,qBAAqB,UAAtB;EAA+B,OAAO;EAAK;CAAwC,CAAA;AAC5F;AAEA,SAAgB,mBAAmB;CACjC,OAAO,MAAM,WAAW,oBAAoB;AAC9C;;AAGA,SAAgB,kBAAkB;CAChC,OAAO;AACT;AAIA,SAAgB,aAAa,EAAE,KAAK,QAAQ,UAAU,GAAG,QAAe;CAEtE,IAAI,CADO,iBACN,GAAI,OAAO;CAChB,IAAI,OAAO,YAAY,OAAO,oBAAA,UAAA,EAAG,SAAW,CAAA;CAE5C,OACE,oBAAC,IAAD;EAAK,aAAU;EAAY,GAAI;EAC5B;CACE,CAAA;AAET"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
declare const sizes: {
|
|
3
|
+
readonly xs: "size-3";
|
|
4
|
+
readonly sm: "size-3.5";
|
|
5
|
+
readonly md: "size-4";
|
|
6
|
+
readonly lg: "size-5";
|
|
7
|
+
};
|
|
8
|
+
declare const tones: {
|
|
9
|
+
readonly current: "";
|
|
10
|
+
readonly muted: "text-kit-fg-3";
|
|
11
|
+
readonly accent: "text-kit-accent";
|
|
12
|
+
readonly info: "text-kit-info";
|
|
13
|
+
};
|
|
14
|
+
export interface SpinnerProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, "children"> {
|
|
15
|
+
/** 12 · 14 · 16 (default) · 20 */
|
|
16
|
+
size?: keyof typeof sizes;
|
|
17
|
+
variant?: "icon" | "ring";
|
|
18
|
+
/** icon colour; the ring keeps V2's line-strong / fg-2 pair */
|
|
19
|
+
tone?: keyof typeof tones;
|
|
20
|
+
/** set → role="status" named by it; unset → aria-hidden */
|
|
21
|
+
label?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function Spinner({ size, variant, tone, label, className, ...rest }: SpinnerProps): import("react/jsx-runtime").JSX.Element;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { cn } from "../lib/cn.js";
|
|
2
|
+
import "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
import { IconLoader2 } from "@tabler/icons-react";
|
|
5
|
+
//#region src/ui/spinner.tsx
|
|
6
|
+
var sizes = {
|
|
7
|
+
xs: "size-3",
|
|
8
|
+
sm: "size-3.5",
|
|
9
|
+
md: "size-4",
|
|
10
|
+
lg: "size-5"
|
|
11
|
+
};
|
|
12
|
+
var tones = {
|
|
13
|
+
current: "",
|
|
14
|
+
muted: "text-kit-fg-3",
|
|
15
|
+
accent: "text-kit-accent",
|
|
16
|
+
info: "text-kit-info"
|
|
17
|
+
};
|
|
18
|
+
function Spinner({ size = "md", variant = "icon", tone = "current", label, className, ...rest }) {
|
|
19
|
+
const a11y = label ? {
|
|
20
|
+
role: "status",
|
|
21
|
+
"aria-label": label
|
|
22
|
+
} : { "aria-hidden": true };
|
|
23
|
+
const spin = "animate-spin motion-reduce:animate-none";
|
|
24
|
+
if (variant === "ring") return /* @__PURE__ */ jsx("span", {
|
|
25
|
+
...a11y,
|
|
26
|
+
...rest,
|
|
27
|
+
className: cn("inline-block shrink-0 rounded-full border-2 border-kit-line-strong border-t-kit-fg-2", sizes[size], spin, className)
|
|
28
|
+
});
|
|
29
|
+
return /* @__PURE__ */ jsx("span", {
|
|
30
|
+
...a11y,
|
|
31
|
+
...rest,
|
|
32
|
+
className: cn("inline-flex shrink-0", tones[tone], className),
|
|
33
|
+
children: /* @__PURE__ */ jsx(IconLoader2, {
|
|
34
|
+
"aria-hidden": true,
|
|
35
|
+
className: cn(sizes[size], spin)
|
|
36
|
+
})
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
export { Spinner };
|
|
41
|
+
|
|
42
|
+
//# sourceMappingURL=spinner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spinner.js","names":[],"sources":["../../src/ui/spinner.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { IconLoader2 } from \"@tabler/icons-react\";\nimport { cn } from \"../lib/cn\";\n\n/* ── Spinner ─────────────────────────────────────────────────────────────\n V2 has no Spinner component, only the pattern (kit-ports-spec.md §1):\n • icon: tabler IconLoader2 + animate-spin (button.tsx:73 and ~25 call sites; size-4 text-fg-3 the most common)\n • ring: size-5 border-2 border-line-strong border-t-fg-2 (schema/index.tsx:355, the Suspense panel fallback)\n Decorative by default (the host says what is loading, e.g. Button's aria-busy); `label` makes it a polite status. */\nconst sizes = { xs: \"size-3\", sm: \"size-3.5\", md: \"size-4\", lg: \"size-5\" } as const;\nconst tones = { current: \"\", muted: \"text-kit-fg-3\", accent: \"text-kit-accent\", info: \"text-kit-info\" } as const;\n\nexport interface SpinnerProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, \"children\"> {\n /** 12 · 14 · 16 (default) · 20 */\n size?: keyof typeof sizes;\n variant?: \"icon\" | \"ring\";\n /** icon colour; the ring keeps V2's line-strong / fg-2 pair */\n tone?: keyof typeof tones;\n /** set → role=\"status\" named by it; unset → aria-hidden */\n label?: string;\n}\n\nexport function Spinner({ size = \"md\", variant = \"icon\", tone = \"current\", label, className, ...rest }: SpinnerProps) {\n const a11y = label ? { role: \"status\", \"aria-label\": label } : { \"aria-hidden\": true };\n const spin = \"animate-spin motion-reduce:animate-none\";\n if (variant === \"ring\") {\n return (\n <span\n {...a11y}\n {...rest}\n className={cn(\"inline-block shrink-0 rounded-full border-2 border-kit-line-strong border-t-kit-fg-2\", sizes[size], spin, className)}\n />\n );\n }\n return (\n <span {...a11y} {...rest} className={cn(\"inline-flex shrink-0\", tones[tone], className)}>\n <IconLoader2 aria-hidden className={cn(sizes[size], spin)} />\n </span>\n );\n}\n"],"mappings":";;;;;AASA,IAAM,QAAQ;CAAE,IAAI;CAAU,IAAI;CAAY,IAAI;CAAU,IAAI;AAAS;AACzE,IAAM,QAAQ;CAAE,SAAS;CAAI,OAAO;CAAiB,QAAQ;CAAmB,MAAM;AAAgB;AAYtG,SAAgB,QAAQ,EAAE,OAAO,MAAM,UAAU,QAAQ,OAAO,WAAW,OAAO,WAAW,GAAG,QAAsB;CACpH,MAAM,OAAO,QAAQ;EAAE,MAAM;EAAU,cAAc;CAAM,IAAI,EAAE,eAAe,KAAK;CACrF,MAAM,OAAO;CACb,IAAI,YAAY,QACd,OACE,oBAAC,QAAD;EACE,GAAI;EACJ,GAAI;EACJ,WAAW,GAAG,wFAAwF,MAAM,OAAO,MAAM,SAAS;CACnI,CAAA;CAGL,OACE,oBAAC,QAAD;EAAM,GAAI;EAAM,GAAI;EAAM,WAAW,GAAG,wBAAwB,MAAM,OAAO,SAAS;EACpF,UAAA,oBAAC,aAAD;GAAa,eAAA;GAAY,WAAW,GAAG,MAAM,OAAO,IAAI;EAAI,CAAA;CACxD,CAAA;AAEV"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPLIT BUTTON: one action plus its menu, as ONE visual unit (founder, D57: one element per job).
|
|
3
|
+
*
|
|
4
|
+
* <SplitButton label="Publish" icon={<IconFileUpload />} onClick={publish} menuLabel="More publish options">
|
|
5
|
+
* <MenuItem …>Schedule…</MenuItem>
|
|
6
|
+
* </SplitButton>
|
|
7
|
+
*
|
|
8
|
+
* - Two segments, same height, a 1px divider between them, rounded on the outer edge only.
|
|
9
|
+
* - Each segment is its own button with its own keyboard focus ring (the global :focus-visible outline).
|
|
10
|
+
* - The chevron segment carries aria-haspopup="menu" and `menuLabel`. No children → no chevron (the primary stands alone).
|
|
11
|
+
* - Tokens only (D56): the primary variant is bg-inverse / fg-inverse; secondary is the bordered control.
|
|
12
|
+
*/
|
|
13
|
+
import * as React from "react";
|
|
14
|
+
export interface SplitButtonProps {
|
|
15
|
+
label: React.ReactNode;
|
|
16
|
+
icon?: React.ReactNode;
|
|
17
|
+
onClick?: () => void;
|
|
18
|
+
/** Menu items for the chevron segment. Omit (or pass nothing renderable) to hide the chevron. */
|
|
19
|
+
children?: React.ReactNode;
|
|
20
|
+
/** Accessible name of the chevron segment. */
|
|
21
|
+
menuLabel?: string;
|
|
22
|
+
variant?: "primary" | "secondary";
|
|
23
|
+
size?: "sm" | "md";
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
/** Menu placement (footers open upward). */
|
|
26
|
+
side?: "top" | "bottom";
|
|
27
|
+
menuClassName?: string;
|
|
28
|
+
/** The menu opened or closed (a caller that reads data only while the menu is open). */
|
|
29
|
+
onMenuOpenChange?: (open: boolean) => void;
|
|
30
|
+
className?: string;
|
|
31
|
+
}
|
|
32
|
+
export declare const SplitButton: React.ForwardRefExoticComponent<SplitButtonProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { cn } from "../lib/cn.js";
|
|
2
|
+
import { buttonVariants } from "./button.js";
|
|
3
|
+
import { Menu, MenuContent, MenuTrigger } from "./overlay.js";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { IconChevronDown } from "@tabler/icons-react";
|
|
7
|
+
//#region src/ui/split-button.tsx
|
|
8
|
+
/**
|
|
9
|
+
* SPLIT BUTTON: one action plus its menu, as ONE visual unit (founder, D57: one element per job).
|
|
10
|
+
*
|
|
11
|
+
* <SplitButton label="Publish" icon={<IconFileUpload />} onClick={publish} menuLabel="More publish options">
|
|
12
|
+
* <MenuItem …>Schedule…</MenuItem>
|
|
13
|
+
* </SplitButton>
|
|
14
|
+
*
|
|
15
|
+
* - Two segments, same height, a 1px divider between them, rounded on the outer edge only.
|
|
16
|
+
* - Each segment is its own button with its own keyboard focus ring (the global :focus-visible outline).
|
|
17
|
+
* - The chevron segment carries aria-haspopup="menu" and `menuLabel`. No children → no chevron (the primary stands alone).
|
|
18
|
+
* - Tokens only (D56): the primary variant is bg-inverse / fg-inverse; secondary is the bordered control.
|
|
19
|
+
*/
|
|
20
|
+
var SplitButton = React.forwardRef(function SplitButton({ label, icon, onClick, children, menuLabel = "More options", variant = "primary", size = "md", disabled, side = "top", menuClassName, onMenuOpenChange, className }, ref) {
|
|
21
|
+
const hasMenu = React.Children.toArray(children).some(Boolean);
|
|
22
|
+
const divider = variant === "primary" ? "before:bg-kit-fg-inverse/25" : "before:bg-kit-line-strong";
|
|
23
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
24
|
+
ref,
|
|
25
|
+
role: "group",
|
|
26
|
+
"data-slot": "split-button",
|
|
27
|
+
className: cn("inline-flex shrink-0 items-stretch", className),
|
|
28
|
+
children: [/* @__PURE__ */ jsxs("button", {
|
|
29
|
+
type: "button",
|
|
30
|
+
disabled,
|
|
31
|
+
onClick,
|
|
32
|
+
className: cn(buttonVariants({
|
|
33
|
+
variant,
|
|
34
|
+
size
|
|
35
|
+
}), hasMenu && "rounded-r-none", "pl-2.5 pr-3"),
|
|
36
|
+
children: [icon, label]
|
|
37
|
+
}), hasMenu ? /* @__PURE__ */ jsxs(Menu, {
|
|
38
|
+
onOpenChange: onMenuOpenChange,
|
|
39
|
+
children: [/* @__PURE__ */ jsx(MenuTrigger, {
|
|
40
|
+
disabled,
|
|
41
|
+
"aria-label": menuLabel,
|
|
42
|
+
"aria-haspopup": "menu",
|
|
43
|
+
className: cn(buttonVariants({
|
|
44
|
+
variant,
|
|
45
|
+
size
|
|
46
|
+
}), "relative rounded-l-none px-0", size === "sm" ? "w-7" : "w-8", variant === "secondary" && "border-l-0", "before:absolute before:inset-y-1.5 before:left-0 before:w-px before:content-['']", divider),
|
|
47
|
+
children: /* @__PURE__ */ jsx(IconChevronDown, { stroke: 1.75 })
|
|
48
|
+
}), /* @__PURE__ */ jsx(MenuContent, {
|
|
49
|
+
align: "end",
|
|
50
|
+
side,
|
|
51
|
+
className: cn("w-60", menuClassName),
|
|
52
|
+
children
|
|
53
|
+
})]
|
|
54
|
+
}) : null]
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
//#endregion
|
|
58
|
+
export { SplitButton };
|
|
59
|
+
|
|
60
|
+
//# sourceMappingURL=split-button.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"split-button.js","names":[],"sources":["../../src/ui/split-button.tsx"],"sourcesContent":["/**\n * SPLIT BUTTON: one action plus its menu, as ONE visual unit (founder, D57: one element per job).\n *\n * <SplitButton label=\"Publish\" icon={<IconFileUpload />} onClick={publish} menuLabel=\"More publish options\">\n * <MenuItem …>Schedule…</MenuItem>\n * </SplitButton>\n *\n * - Two segments, same height, a 1px divider between them, rounded on the outer edge only.\n * - Each segment is its own button with its own keyboard focus ring (the global :focus-visible outline).\n * - The chevron segment carries aria-haspopup=\"menu\" and `menuLabel`. No children → no chevron (the primary stands alone).\n * - Tokens only (D56): the primary variant is bg-inverse / fg-inverse; secondary is the bordered control.\n */\nimport * as React from \"react\";\nimport { IconChevronDown } from \"@tabler/icons-react\";\nimport { cn } from \"../lib/cn\";\nimport { buttonVariants } from \"./button\";\nimport { Menu, MenuContent, MenuTrigger } from \"./overlay\";\n\nexport interface SplitButtonProps {\n label: React.ReactNode;\n icon?: React.ReactNode;\n onClick?: () => void;\n /** Menu items for the chevron segment. Omit (or pass nothing renderable) to hide the chevron. */\n children?: React.ReactNode;\n /** Accessible name of the chevron segment. */\n menuLabel?: string;\n variant?: \"primary\" | \"secondary\";\n size?: \"sm\" | \"md\";\n disabled?: boolean;\n /** Menu placement (footers open upward). */\n side?: \"top\" | \"bottom\";\n menuClassName?: string;\n /** The menu opened or closed (a caller that reads data only while the menu is open). */\n onMenuOpenChange?: (open: boolean) => void;\n className?: string;\n}\n\nexport const SplitButton = React.forwardRef<HTMLDivElement, SplitButtonProps>(function SplitButton(\n { label, icon, onClick, children, menuLabel = \"More options\", variant = \"primary\", size = \"md\", disabled, side = \"top\", menuClassName, onMenuOpenChange, className },\n ref,\n) {\n const hasMenu = React.Children.toArray(children).some(Boolean);\n const divider = variant === \"primary\" ? \"before:bg-kit-fg-inverse/25\" : \"before:bg-kit-line-strong\";\n return (\n <div ref={ref} role=\"group\" data-slot=\"split-button\" className={cn(\"inline-flex shrink-0 items-stretch\", className)}>\n <button\n type=\"button\"\n disabled={disabled}\n onClick={onClick}\n className={cn(buttonVariants({ variant, size }), hasMenu && \"rounded-r-none\", \"pl-2.5 pr-3\")}\n >\n {icon}\n {label}\n </button>\n {hasMenu ? (\n <Menu onOpenChange={onMenuOpenChange}>\n <MenuTrigger\n disabled={disabled}\n aria-label={menuLabel}\n aria-haspopup=\"menu\"\n className={cn(\n buttonVariants({ variant, size }),\n \"relative rounded-l-none px-0\",\n size === \"sm\" ? \"w-7\" : \"w-8\",\n variant === \"secondary\" && \"border-l-0\",\n // the 1px divider between the segments (inset top and bottom, like the production control)\n \"before:absolute before:inset-y-1.5 before:left-0 before:w-px before:content-['']\",\n divider,\n )}\n >\n <IconChevronDown stroke={1.75} />\n </MenuTrigger>\n <MenuContent align=\"end\" side={side} className={cn(\"w-60\", menuClassName)}>\n {children}\n </MenuContent>\n </Menu>\n ) : null}\n </div>\n );\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAqCA,IAAa,cAAc,MAAM,WAA6C,SAAS,YACrF,EAAE,OAAO,MAAM,SAAS,UAAU,YAAY,gBAAgB,UAAU,WAAW,OAAO,MAAM,UAAU,OAAO,OAAO,eAAe,kBAAkB,aACzJ,KACA;CACA,MAAM,UAAU,MAAM,SAAS,QAAQ,QAAQ,CAAC,CAAC,KAAK,OAAO;CAC7D,MAAM,UAAU,YAAY,YAAY,gCAAgC;CACxE,OACE,qBAAC,OAAD;EAAU;EAAK,MAAK;EAAQ,aAAU;EAAe,WAAW,GAAG,sCAAsC,SAAS;EAAlH,UAAA,CACE,qBAAC,UAAD;GACE,MAAK;GACK;GACD;GACT,WAAW,GAAG,eAAe;IAAE;IAAS;GAAK,CAAC,GAAG,WAAW,kBAAkB,aAAa;GAJ7F,UAAA,CAMG,MACA,KACK;EACP,CAAA,GAAA,UACC,qBAAC,MAAD;GAAM,cAAc;GAApB,UAAA,CACE,oBAAC,aAAD;IACY;IACV,cAAY;IACZ,iBAAc;IACd,WAAW,GACT,eAAe;KAAE;KAAS;IAAK,CAAC,GAChC,gCACA,SAAS,OAAO,QAAQ,OACxB,YAAY,eAAe,cAE3B,oFACA,OACF;IAEA,UAAA,oBAAC,iBAAD,EAAiB,QAAQ,KAAO,CAAA;GACrB,CAAA,GACb,oBAAC,aAAD;IAAa,OAAM;IAAY;IAAM,WAAW,GAAG,QAAQ,aAAa;IACrE;GACU,CAAA,CACT;EACJ,CAAA,IAAA,IACD;;AAET,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//#region src/
|
|
1
|
+
//#region src/ui/surfaces.ts
|
|
2
2
|
/**
|
|
3
3
|
* V2's floating-surface recipes (src/styles/index.css .glass, .glass-ink, .bg-tray, --surface-raised, --floating-line),
|
|
4
4
|
* as class strings. kit.css has no tokens for these yet, so the V2 values are written out here, light and dark
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"surfaces.js","names":[],"sources":["../../src/ui/surfaces.ts"],"sourcesContent":["/**\n * V2's floating-surface recipes (src/styles/index.css .glass, .glass-ink, .bg-tray, --surface-raised, --floating-line),\n * as class strings. kit.css has no tokens for these yet, so the V2 values are written out here, light and dark\n * (`[.dark_&]` = the app is dark). Each one is a single constant so the integrator can swap it for a kit token later.\n *\n * Portalled layers render outside [data-kit-scope], where every --kit-* value is undefined. Every layer root here\n * therefore carries KIT_SCOPE (data-kit-scope) itself.\n */\nexport const KIT_SCOPE = { \"data-kit-scope\": \"\" } as const;\n\n/** .glass: popovers, menus, hover cards. */\nexport const GLASS =\n \"bg-kit-surface border-kit-line shadow-[0_1px_2px_rgb(16_16_16/0.04),0_8px_24px_-6px_rgb(16_16_16/0.12)] [.dark_&]:bg-[#252528] [.dark_&]:border-kit-line-strong [.dark_&]:shadow-[inset_0_1px_0_oklch(1_0_0/0.04),0_12px_32px_-8px_oklch(0.12_0.01_286/0.5)]\";\n\n/** .glass-ink: tooltips (ink is dark in both themes). */\nexport const INK =\n \"bg-[#1c1c1e] text-[#f5f5f5] shadow-[0_10px_28px_-8px_rgb(0_0_0/0.35)] [.dark_&]:bg-[#3d3d40] [.dark_&]:text-[#ececef] [.dark_&]:shadow-[inset_0_1px_0_oklch(1_0_0/0.06),0_0_0_1px_rgb(255_255_255/0.12),0_14px_36px_-8px_oklch(0.12_0.01_286/0.55)]\";\n\n/** --ink-active: the kbd chip on ink. */\nexport const INK_ACTIVE = \"bg-[rgb(255_255_255/0.15)] [.dark_&]:bg-[rgb(255_255_255/0.13)]\";\n\n/** --surface-raised: dialogs, sheets, expanded editors. */\nexport const SURFACE_RAISED = \"bg-[var(--kit-surface-raised)]\";\n\n/** --floating-line: the edge of modals, sheets, expanded editors (= line; dark = line-strong). */\nexport const FLOATING_LINE = \"border-kit-line [.dark_&]:border-kit-line-strong\";\n\n/** .bg-tray + --tray-line: the action tray under a dialog. */\nexport const TRAY =\n \"bg-kit-surface bg-[linear-gradient(180deg,rgb(216_216_216/0)_16.105%,rgb(216_216_216/0.6)_123.57%)] border-[#ededed] [.dark_&]:bg-[linear-gradient(180deg,oklch(0.32_0.005_286/0)_16.105%,oklch(0.32_0.005_286/0.6)_123.57%)] [.dark_&]:border-[#3a3a3d]\";\n"],"mappings":";;;;;;;;;AAQA,IAAa,YAAY,EAAE,kBAAkB,GAAG;;AAGhD,IAAa,QACX;;AAGF,IAAa,MACX;;AAGF,IAAa,aAAa;;AAG1B,IAAa,iBAAiB;;AAG9B,IAAa,gBAAgB;;AAG7B,IAAa,OACX"}
|
package/dist/ui/tab.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export interface TabsProps<T extends string> {
|
|
3
|
+
value?: T;
|
|
4
|
+
defaultValue?: T;
|
|
5
|
+
onValueChange?: (value: T) => void;
|
|
6
|
+
className?: string;
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
export declare function Tabs<T extends string>({ value, defaultValue, onValueChange, className, children }: TabsProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export interface TabListProps {
|
|
11
|
+
"aria-label"?: string;
|
|
12
|
+
size?: "sm" | "md";
|
|
13
|
+
/** draw a hairline under the whole tab row (the underline then sits on it) */
|
|
14
|
+
bordered?: boolean;
|
|
15
|
+
/** framer layoutId for the underline; defaults to one per list */
|
|
16
|
+
layoutId?: string;
|
|
17
|
+
className?: string;
|
|
18
|
+
children: React.ReactNode;
|
|
19
|
+
}
|
|
20
|
+
export declare function TabList({ "aria-label": ariaLabel, size, bordered, layoutId, className, children }: TabListProps): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
export interface TabProps<T extends string> {
|
|
22
|
+
value: T;
|
|
23
|
+
icon?: React.ReactNode;
|
|
24
|
+
/** a muted tabular count after the label; pass it here, never baked into the label */
|
|
25
|
+
count?: number;
|
|
26
|
+
disabled?: boolean;
|
|
27
|
+
className?: string;
|
|
28
|
+
children?: React.ReactNode;
|
|
29
|
+
}
|
|
30
|
+
export declare function Tab<T extends string>({ value, icon, count, disabled, className, children }: TabProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
export interface TabPanelProps<T extends string> {
|
|
32
|
+
value: T;
|
|
33
|
+
/** keep the inactive panel in the DOM (hidden); V2 renders only the active one */
|
|
34
|
+
keepMounted?: boolean;
|
|
35
|
+
className?: string;
|
|
36
|
+
children: React.ReactNode;
|
|
37
|
+
}
|
|
38
|
+
export declare function TabPanel<T extends string>({ value, keepMounted, className, children }: TabPanelProps<T>): import("react/jsx-runtime").JSX.Element;
|
package/dist/ui/tab.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { cn } from "../lib/cn.js";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
import { motion, useReducedMotion } from "framer-motion";
|
|
5
|
+
import { Tabs as Tabs$1 } from "@base-ui/react/tabs";
|
|
6
|
+
//#region src/ui/tab.tsx
|
|
7
|
+
var PILL_SPRING = {
|
|
8
|
+
type: "spring",
|
|
9
|
+
stiffness: 520,
|
|
10
|
+
damping: 42
|
|
11
|
+
};
|
|
12
|
+
var ListLookContext = React.createContext({
|
|
13
|
+
size: "md",
|
|
14
|
+
bordered: false,
|
|
15
|
+
layoutId: "kit-tab"
|
|
16
|
+
});
|
|
17
|
+
function Tabs({ value, defaultValue, onValueChange, className, children }) {
|
|
18
|
+
return /* @__PURE__ */ jsx(Tabs$1.Root, {
|
|
19
|
+
value,
|
|
20
|
+
defaultValue,
|
|
21
|
+
onValueChange: (v) => onValueChange?.(v),
|
|
22
|
+
className,
|
|
23
|
+
children
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function TabList({ "aria-label": ariaLabel, size = "md", bordered = false, layoutId, className, children }) {
|
|
27
|
+
const id = React.useId();
|
|
28
|
+
const look = React.useMemo(() => ({
|
|
29
|
+
size,
|
|
30
|
+
bordered,
|
|
31
|
+
layoutId: layoutId ?? `tab-${id}`
|
|
32
|
+
}), [
|
|
33
|
+
size,
|
|
34
|
+
bordered,
|
|
35
|
+
layoutId,
|
|
36
|
+
id
|
|
37
|
+
]);
|
|
38
|
+
return /* @__PURE__ */ jsx(ListLookContext.Provider, {
|
|
39
|
+
value: look,
|
|
40
|
+
children: /* @__PURE__ */ jsx(Tabs$1.List, {
|
|
41
|
+
"aria-label": ariaLabel,
|
|
42
|
+
activateOnFocus: true,
|
|
43
|
+
loopFocus: true,
|
|
44
|
+
className: cn("inline-flex items-center gap-5", bordered && "border-b border-kit-line", className),
|
|
45
|
+
children
|
|
46
|
+
})
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function Tab({ value, icon, count, disabled, className, children }) {
|
|
50
|
+
const { size, bordered, layoutId } = React.useContext(ListLookContext);
|
|
51
|
+
const reduceMotion = useReducedMotion();
|
|
52
|
+
return /* @__PURE__ */ jsx(Tabs$1.Tab, {
|
|
53
|
+
value,
|
|
54
|
+
disabled,
|
|
55
|
+
className: cn("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 data-[disabled]:opacity-40 [&_svg]:size-4", size === "sm" ? "h-7 text-kit-xs [&_svg]:size-3.5" : "h-8 text-kit-sm", "text-kit-fg-3 not-data-[active]:hover:text-kit-fg-2 data-[active]:text-kit-fg", className),
|
|
56
|
+
render: (props, state) => /* @__PURE__ */ jsxs("button", {
|
|
57
|
+
...props,
|
|
58
|
+
children: [
|
|
59
|
+
icon,
|
|
60
|
+
props.children,
|
|
61
|
+
typeof count === "number" ? /* @__PURE__ */ jsx("span", {
|
|
62
|
+
className: "text-kit-xs font-normal tabular-nums text-kit-fg-4 group-data-[active]:text-kit-fg-2",
|
|
63
|
+
children: count
|
|
64
|
+
}) : null,
|
|
65
|
+
state.active ? /* @__PURE__ */ jsx(motion.span, {
|
|
66
|
+
layoutId,
|
|
67
|
+
transition: reduceMotion ? { duration: 0 } : PILL_SPRING,
|
|
68
|
+
"data-tab-indicator": "",
|
|
69
|
+
className: cn("absolute inset-x-0 h-[1.5px] rounded-full bg-kit-fg", bordered ? "-bottom-px" : "bottom-0")
|
|
70
|
+
}) : null
|
|
71
|
+
]
|
|
72
|
+
}),
|
|
73
|
+
children
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
function TabPanel({ value, keepMounted, className, children }) {
|
|
77
|
+
return /* @__PURE__ */ jsx(Tabs$1.Panel, {
|
|
78
|
+
value,
|
|
79
|
+
keepMounted,
|
|
80
|
+
className,
|
|
81
|
+
children
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
//#endregion
|
|
85
|
+
export { Tab, TabList, TabPanel, Tabs };
|
|
86
|
+
|
|
87
|
+
//# sourceMappingURL=tab.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tab.js","names":[],"sources":["../../src/ui/tab.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Tabs as TabsPrimitive } from \"@base-ui/react/tabs\";\nimport { motion, useReducedMotion } from \"framer-motion\";\nimport { cn } from \"../lib/cn\";\n\n/* ── Tabs ────────────────────────────────────────────────────────────────\n Real tabs (tablist + tab + tabpanel with aria-controls / aria-labelledby) in the look of V2's\n Segmented variant=\"tabs\" (controls.tsx:179-273): quiet text tabs, muted tabular count, a 1.5px underline that springs\n between tabs (layoutId, stiffness 520 / damping 42, instant under reduced motion). Selection follows focus and the\n arrows wrap, as V2's onKey does. kit-ports-spec.md §3. Segmented stays the tabs look for rows that have no panels. */\nconst PILL_SPRING = { type: \"spring\", stiffness: 520, damping: 42 } as const;\n\ntype ListLook = { size: \"sm\" | \"md\"; bordered: boolean; layoutId: string };\nconst ListLookContext = React.createContext<ListLook>({ size: \"md\", bordered: false, layoutId: \"kit-tab\" });\n\nexport interface TabsProps<T extends string> {\n value?: T;\n defaultValue?: T;\n onValueChange?: (value: T) => void;\n className?: string;\n children: React.ReactNode;\n}\n\nexport function Tabs<T extends string>({ value, defaultValue, onValueChange, className, children }: TabsProps<T>) {\n return (\n <TabsPrimitive.Root value={value} defaultValue={defaultValue} onValueChange={(v) => onValueChange?.(v as T)} className={className}>\n {children}\n </TabsPrimitive.Root>\n );\n}\n\nexport interface TabListProps {\n \"aria-label\"?: string;\n size?: \"sm\" | \"md\";\n /** draw a hairline under the whole tab row (the underline then sits on it) */\n bordered?: boolean;\n /** framer layoutId for the underline; defaults to one per list */\n layoutId?: string;\n className?: string;\n children: React.ReactNode;\n}\n\nexport function TabList({ \"aria-label\": ariaLabel, size = \"md\", bordered = false, layoutId, className, children }: TabListProps) {\n const id = React.useId();\n const look = React.useMemo(() => ({ size, bordered, layoutId: layoutId ?? `tab-${id}` }), [size, bordered, layoutId, id]);\n return (\n <ListLookContext.Provider value={look}>\n <TabsPrimitive.List\n aria-label={ariaLabel}\n activateOnFocus\n loopFocus\n className={cn(\"inline-flex items-center gap-5\", bordered && \"border-b border-kit-line\", className)}\n >\n {children}\n </TabsPrimitive.List>\n </ListLookContext.Provider>\n );\n}\n\nexport interface TabProps<T extends string> {\n value: T;\n icon?: React.ReactNode;\n /** a muted tabular count after the label; pass it here, never baked into the label */\n count?: number;\n disabled?: boolean;\n className?: string;\n children?: React.ReactNode;\n}\n\nexport function Tab<T extends string>({ value, icon, count, disabled, className, children }: TabProps<T>) {\n const { size, bordered, layoutId } = React.useContext(ListLookContext);\n const reduceMotion = useReducedMotion();\n return (\n <TabsPrimitive.Tab\n value={value}\n disabled={disabled}\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 data-[disabled]:opacity-40 [&_svg]:size-4\",\n size === \"sm\" ? \"h-7 text-kit-xs [&_svg]:size-3.5\" : \"h-8 text-kit-sm\",\n \"text-kit-fg-3 not-data-[active]:hover:text-kit-fg-2 data-[active]:text-kit-fg\",\n className,\n )}\n render={(props, state) => (\n <button {...props}>\n {icon}\n {props.children}\n {typeof count === \"number\" ? (\n <span className=\"text-kit-xs font-normal tabular-nums text-kit-fg-4 group-data-[active]:text-kit-fg-2\">{count}</span>\n ) : null}\n {state.active ? (\n <motion.span\n layoutId={layoutId}\n transition={reduceMotion ? { duration: 0 } : PILL_SPRING}\n data-tab-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 {children}\n </TabsPrimitive.Tab>\n );\n}\n\nexport interface TabPanelProps<T extends string> {\n value: T;\n /** keep the inactive panel in the DOM (hidden); V2 renders only the active one */\n keepMounted?: boolean;\n className?: string;\n children: React.ReactNode;\n}\n\nexport function TabPanel<T extends string>({ value, keepMounted, className, children }: TabPanelProps<T>) {\n return (\n <TabsPrimitive.Panel value={value} keepMounted={keepMounted} className={className}>\n {children}\n </TabsPrimitive.Panel>\n );\n}\n"],"mappings":";;;;;;AAUA,IAAM,cAAc;CAAE,MAAM;CAAU,WAAW;CAAK,SAAS;AAAG;AAGlE,IAAM,kBAAkB,MAAM,cAAwB;CAAE,MAAM;CAAM,UAAU;CAAO,UAAU;AAAU,CAAC;AAU1G,SAAgB,KAAuB,EAAE,OAAO,cAAc,eAAe,WAAW,YAA0B;CAChH,OACE,oBAAC,OAAc,MAAf;EAA2B;EAAqB;EAAc,gBAAgB,MAAM,gBAAgB,CAAM;EAAc;EACrH;CACiB,CAAA;AAExB;AAaA,SAAgB,QAAQ,EAAE,cAAc,WAAW,OAAO,MAAM,WAAW,OAAO,UAAU,WAAW,YAA0B;CAC/H,MAAM,KAAK,MAAM,MAAM;CACvB,MAAM,OAAO,MAAM,eAAe;EAAE;EAAM;EAAU,UAAU,YAAY,OAAO;CAAK,IAAI;EAAC;EAAM;EAAU;EAAU;CAAE,CAAC;CACxH,OACE,oBAAC,gBAAgB,UAAjB;EAA0B,OAAO;EAC/B,UAAA,oBAAC,OAAc,MAAf;GACE,cAAY;GACZ,iBAAA;GACA,WAAA;GACA,WAAW,GAAG,kCAAkC,YAAY,4BAA4B,SAAS;GAEhG;EACiB,CAAA;CACI,CAAA;AAE9B;AAYA,SAAgB,IAAsB,EAAE,OAAO,MAAM,OAAO,UAAU,WAAW,YAAyB;CACxG,MAAM,EAAE,MAAM,UAAU,aAAa,MAAM,WAAW,eAAe;CACrE,MAAM,eAAe,iBAAiB;CACtC,OACE,oBAAC,OAAc,KAAf;EACS;EACG;EACV,WAAW,GACT,gNACA,SAAS,OAAO,qCAAqC,mBACrD,iFACA,SACF;EACA,SAAS,OAAO,UACd,qBAAC,UAAD;GAAQ,GAAI;GAAZ,UAAA;IACG;IACA,MAAM;IACN,OAAO,UAAU,WAChB,oBAAC,QAAD;KAAM,WAAU;KAAwF,UAAA;IAAY,CAAA,IAClH;IACH,MAAM,SACL,oBAAC,OAAO,MAAR;KACY;KACV,YAAY,eAAe,EAAE,UAAU,EAAE,IAAI;KAC7C,sBAAmB;KACnB,WAAW,GAAG,uDAAuD,WAAW,eAAe,UAAU;IAC1G,CAAA,IACC;GACE;;EAGT;CACgB,CAAA;AAEvB;AAUA,SAAgB,SAA2B,EAAE,OAAO,aAAa,WAAW,YAA8B;CACxG,OACE,oBAAC,OAAc,OAAf;EAA4B;EAAoB;EAAwB;EACrE;CACkB,CAAA;AAEzB"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { KitToast, KitToastOptions } from "../context";
|
|
2
|
+
export declare const kitToastManager: import("@base-ui/react").ToastManager<any>;
|
|
3
|
+
/** KitServices.toast backed by kitToastManager, plus V2's other sonner calls. */
|
|
4
|
+
export declare const kitToast: KitToast & {
|
|
5
|
+
error: (message: string, opts?: KitToastOptions) => void;
|
|
6
|
+
warning: (message: string, opts?: KitToastOptions) => void;
|
|
7
|
+
info: (message: string, opts?: KitToastOptions) => void;
|
|
8
|
+
/** stays until dismissed or updated; returns its id */
|
|
9
|
+
loading: (message: string, opts?: KitToastOptions) => string;
|
|
10
|
+
dismiss: (id?: string) => void;
|
|
11
|
+
};
|
|
12
|
+
export interface KitToasterProps {
|
|
13
|
+
/** toasts kept on screen (sonner visibleToasts) */
|
|
14
|
+
limit?: number;
|
|
15
|
+
/** ms before a toast closes; a toast's own `duration` wins; loading toasts stay */
|
|
16
|
+
timeout?: number;
|
|
17
|
+
className?: string;
|
|
18
|
+
}
|
|
19
|
+
/** Mount once per document, at the root. Its layer carries KIT_SCOPE (a portal sits outside every kit island). */
|
|
20
|
+
export declare function KitToaster({ limit, timeout, className }: KitToasterProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/ui/toast.js
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { cn } from "../lib/cn.js";
|
|
2
|
+
import { KIT_SCOPE } from "./surfaces.js";
|
|
3
|
+
import { Spinner } from "./spinner.js";
|
|
4
|
+
import "react";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { Toast } from "@base-ui/react/toast";
|
|
7
|
+
//#region src/ui/toast.tsx
|
|
8
|
+
var kitToastManager = Toast.createToastManager();
|
|
9
|
+
var seq = 0;
|
|
10
|
+
function add(type, message, opts = {}) {
|
|
11
|
+
const id = `kit-toast-${++seq}`;
|
|
12
|
+
const { action } = opts;
|
|
13
|
+
return kitToastManager.add({
|
|
14
|
+
id,
|
|
15
|
+
type,
|
|
16
|
+
title: message,
|
|
17
|
+
description: opts.description,
|
|
18
|
+
timeout: opts.duration,
|
|
19
|
+
priority: type === "error" ? "high" : "low",
|
|
20
|
+
data: { icon: opts.icon },
|
|
21
|
+
actionProps: action ? {
|
|
22
|
+
children: action.label,
|
|
23
|
+
onClick: () => (action.onClick(), kitToastManager.close(id))
|
|
24
|
+
} : void 0
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/** KitServices.toast backed by kitToastManager, plus V2's other sonner calls. */
|
|
28
|
+
var kitToast = Object.assign((message, opts) => void add("default", message, opts), {
|
|
29
|
+
success: (message, opts) => void add("success", message, opts),
|
|
30
|
+
error: (message, opts) => void add("error", message, opts),
|
|
31
|
+
warning: (message, opts) => void add("warning", message, opts),
|
|
32
|
+
info: (message, opts) => void add("info", message, opts),
|
|
33
|
+
loading: (message, opts) => add("loading", message, opts),
|
|
34
|
+
dismiss: (id) => kitToastManager.close(id)
|
|
35
|
+
});
|
|
36
|
+
function SonnerGlyph({ viewBox, d }) {
|
|
37
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
38
|
+
viewBox,
|
|
39
|
+
fill: "currentColor",
|
|
40
|
+
width: "16",
|
|
41
|
+
height: "16",
|
|
42
|
+
"data-toast-glyph": "",
|
|
43
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
44
|
+
fillRule: "evenodd",
|
|
45
|
+
d,
|
|
46
|
+
clipRule: "evenodd"
|
|
47
|
+
})
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
var TYPE_ICON = {
|
|
51
|
+
success: /* @__PURE__ */ jsx(SonnerGlyph, {
|
|
52
|
+
viewBox: "0 0 20 20",
|
|
53
|
+
d: "M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z"
|
|
54
|
+
}),
|
|
55
|
+
warning: /* @__PURE__ */ jsx(SonnerGlyph, {
|
|
56
|
+
viewBox: "0 0 24 24",
|
|
57
|
+
d: "M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z"
|
|
58
|
+
}),
|
|
59
|
+
info: /* @__PURE__ */ jsx(SonnerGlyph, {
|
|
60
|
+
viewBox: "0 0 20 20",
|
|
61
|
+
d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z"
|
|
62
|
+
}),
|
|
63
|
+
error: /* @__PURE__ */ jsx(SonnerGlyph, {
|
|
64
|
+
viewBox: "0 0 20 20",
|
|
65
|
+
d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-5a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 0110 5zm0 10a1 1 0 100-2 1 1 0 000 2z"
|
|
66
|
+
}),
|
|
67
|
+
loading: /* @__PURE__ */ jsx(Spinner, { size: "md" })
|
|
68
|
+
};
|
|
69
|
+
var VIEWPORT = "fixed bottom-[var(--toast-offset-bottom,16px)] right-4 z-[var(--z-toast,500)] w-[356px] outline-none max-[600px]:left-4 max-[600px]:w-auto";
|
|
70
|
+
var ROOT = cn("[--gap:8px] [--scale:calc(1-var(--toast-index)*0.05)] [--height:var(--toast-frontmost-height,var(--toast-height))]", "[--offset-y:calc(var(--toast-offset-y)*-1+var(--toast-index)*var(--gap)*-1+var(--toast-swipe-movement-y))]", "absolute bottom-0 right-0 z-[calc(1000-var(--toast-index))] w-full origin-bottom select-none", "h-[var(--height)] [transform:translateX(var(--toast-swipe-movement-x))_translateY(calc(var(--toast-swipe-movement-y)-var(--toast-index)*var(--gap)))_scale(var(--scale))]", "data-[expanded]:h-[var(--toast-height)] data-[expanded]:[transform:translateX(var(--toast-swipe-movement-x))_translateY(var(--offset-y))]", "data-[starting-style]:opacity-0 data-[starting-style]:[transform:translateY(100%)]", "data-[ending-style]:opacity-0 data-[limited]:opacity-0", "[&[data-ending-style]:not([data-limited]):not([data-swipe-direction])]:[transform:translateY(100%)]", "data-[ending-style]:data-[swipe-direction=down]:[transform:translateY(calc(var(--toast-swipe-movement-y)+100%))]", "data-[ending-style]:data-[swipe-direction=right]:[transform:translateX(calc(var(--toast-swipe-movement-x)+100%))_translateY(var(--offset-y))]", "[transition:transform_400ms_ease,opacity_400ms,height_400ms,box-shadow_200ms]", "after:absolute after:left-0 after:top-full after:h-[calc(var(--gap)+1px)] after:w-full after:content-['']", "flex items-center rounded-kit-xl border border-kit-tray-line bg-kit-surface-raised bg-clip-padding p-4 font-sans text-kit-sm text-kit-fg shadow-[0_4px_12px_rgba(0,0,0,0.1)] [.dark_&]:border-kit-line-strong");
|
|
71
|
+
var CONTENT = "flex min-w-0 flex-1 items-center gap-1.5 transition-opacity duration-[400ms] data-[behind]:opacity-0 data-[expanded]:opacity-100";
|
|
72
|
+
var ACTION = "ml-auto inline-flex h-6 shrink-0 cursor-pointer items-center rounded-kit-md bg-kit-inverse px-2 text-kit-xs font-medium text-kit-fg-inverse hover:bg-kit-inverse-hover [transition:opacity_400ms,box-shadow_200ms,background-color_150ms]";
|
|
73
|
+
function KitToastItem({ toast }) {
|
|
74
|
+
const icon = toast.data?.icon ?? TYPE_ICON[toast.type ?? ""];
|
|
75
|
+
return /* @__PURE__ */ jsx(Toast.Root, {
|
|
76
|
+
toast,
|
|
77
|
+
className: ROOT,
|
|
78
|
+
children: /* @__PURE__ */ jsxs(Toast.Content, {
|
|
79
|
+
className: CONTENT,
|
|
80
|
+
children: [
|
|
81
|
+
icon ? /* @__PURE__ */ jsx("span", {
|
|
82
|
+
"aria-hidden": true,
|
|
83
|
+
className: "flex size-4 shrink-0 items-center [&_svg]:size-4",
|
|
84
|
+
children: icon
|
|
85
|
+
}) : null,
|
|
86
|
+
/* @__PURE__ */ jsxs("div", {
|
|
87
|
+
className: "min-w-0 flex-1",
|
|
88
|
+
children: [/* @__PURE__ */ jsx(Toast.Title, { className: "font-medium leading-[1.5]" }), toast.description ? /* @__PURE__ */ jsx(Toast.Description, { className: "leading-[1.4] text-kit-fg-2" }) : null]
|
|
89
|
+
}),
|
|
90
|
+
toast.actionProps ? /* @__PURE__ */ jsx(Toast.Action, { className: ACTION }) : null
|
|
91
|
+
]
|
|
92
|
+
})
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
function KitToastList() {
|
|
96
|
+
const { toasts } = Toast.useToastManager();
|
|
97
|
+
return toasts.map((t) => /* @__PURE__ */ jsx(KitToastItem, { toast: t }, t.id));
|
|
98
|
+
}
|
|
99
|
+
/** Mount once per document, at the root. Its layer carries KIT_SCOPE (a portal sits outside every kit island). */
|
|
100
|
+
function KitToaster({ limit = 3, timeout = 4e3, className }) {
|
|
101
|
+
return /* @__PURE__ */ jsx(Toast.Provider, {
|
|
102
|
+
toastManager: kitToastManager,
|
|
103
|
+
limit,
|
|
104
|
+
timeout,
|
|
105
|
+
children: /* @__PURE__ */ jsx(Toast.Portal, { children: /* @__PURE__ */ jsx(Toast.Viewport, {
|
|
106
|
+
...KIT_SCOPE,
|
|
107
|
+
className: cn(VIEWPORT, className),
|
|
108
|
+
children: /* @__PURE__ */ jsx(KitToastList, {})
|
|
109
|
+
}) })
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
//#endregion
|
|
113
|
+
export { KitToaster, kitToast, kitToastManager };
|
|
114
|
+
|
|
115
|
+
//# sourceMappingURL=toast.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toast.js","names":[],"sources":["../../src/ui/toast.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Toast } from \"@base-ui/react/toast\";\nimport type { KitToast, KitToastOptions } from \"../context\";\nimport { cn } from \"../lib/cn\";\nimport { Spinner } from \"./spinner\";\nimport { KIT_SCOPE } from \"./surfaces\";\n\n/* ── Toast ───────────────────────────────────────────────────────────────\n V2's toaster (app/root.tsx:24-46: sonner bottom-right, 16px offsets, gap 8, the --toast-offset-bottom lift an\n ActionTray with clearToasts writes) rebuilt on Base UI Toast. kit-ports-spec.md §4.\n Kit code never mounts this on its own: it calls KitServices.toast. A host without a toaster of its own mounts\n <KitToaster /> once and passes `toast: kitToast`; a host with one (the dashboard's sonner) keeps it, so nothing\n renders twice.\n The success / error / warning / info glyphs are sonner's own SVG paths (sonner 2.0.8 dist/index.mjs:43-90), copied\n verbatim. sonner is MIT licensed, Copyright (c) 2023 Emil Kowalski (https://github.com/emilkowalski/sonner). */\n\nexport const kitToastManager = Toast.createToastManager();\n\ntype ToastType = \"default\" | \"success\" | \"error\" | \"warning\" | \"info\" | \"loading\";\nlet seq = 0;\n\nfunction add(type: ToastType, message: string, opts: KitToastOptions = {}): string {\n const id = `kit-toast-${++seq}`;\n const { action } = opts;\n return kitToastManager.add({\n id,\n type,\n title: message,\n description: opts.description,\n timeout: opts.duration,\n priority: type === \"error\" ? \"high\" : \"low\",\n data: { icon: opts.icon },\n // sonner closes the toast when its action runs; so does this\n actionProps: action ? { children: action.label, onClick: () => (action.onClick(), kitToastManager.close(id)) } : undefined,\n });\n}\n\n/** KitServices.toast backed by kitToastManager, plus V2's other sonner calls. */\nexport const kitToast: KitToast & {\n error: (message: string, opts?: KitToastOptions) => void;\n warning: (message: string, opts?: KitToastOptions) => void;\n info: (message: string, opts?: KitToastOptions) => void;\n /** stays until dismissed or updated; returns its id */\n loading: (message: string, opts?: KitToastOptions) => string;\n dismiss: (id?: string) => void;\n} = Object.assign((message: string, opts?: KitToastOptions) => void add(\"default\", message, opts), {\n success: (message: string, opts?: KitToastOptions) => void add(\"success\", message, opts),\n error: (message: string, opts?: KitToastOptions) => void add(\"error\", message, opts),\n warning: (message: string, opts?: KitToastOptions) => void add(\"warning\", message, opts),\n info: (message: string, opts?: KitToastOptions) => void add(\"info\", message, opts),\n loading: (message: string, opts?: KitToastOptions) => add(\"loading\", message, opts),\n dismiss: (id?: string) => kitToastManager.close(id),\n});\n\n/* sonner's type glyphs, drawn in the toast's text colour (V2 runs without richColors), at the 16px icon slot */\nfunction SonnerGlyph({ viewBox, d }: { viewBox: string; d: string }) {\n return (\n <svg viewBox={viewBox} fill=\"currentColor\" width=\"16\" height=\"16\" data-toast-glyph=\"\">\n <path fillRule=\"evenodd\" d={d} clipRule=\"evenodd\" />\n </svg>\n );\n}\nconst TYPE_ICON: Partial<Record<string, React.ReactNode>> = {\n success: (\n <SonnerGlyph\n viewBox=\"0 0 20 20\"\n d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z\"\n />\n ),\n warning: (\n <SonnerGlyph\n viewBox=\"0 0 24 24\"\n d=\"M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z\"\n />\n ),\n info: (\n <SonnerGlyph\n viewBox=\"0 0 20 20\"\n d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z\"\n />\n ),\n error: (\n <SonnerGlyph\n viewBox=\"0 0 20 20\"\n d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-5a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 0110 5zm0 10a1 1 0 100-2 1 1 0 000 2z\"\n />\n ),\n loading: <Spinner size=\"md\" />,\n};\n\n/* Viewport: bottom-right, 16px from the edges; the bottom offset follows an ActionTray's --toast-offset-bottom lift.\n Under 600px it spans the width less 16px a side (sonner's mobile layout). */\nconst VIEWPORT =\n \"fixed bottom-[var(--toast-offset-bottom,16px)] right-4 z-[var(--z-toast,500)] w-[356px] outline-none max-[600px]:left-4 max-[600px]:w-auto\";\n\n/* sonner's motion in Base UI's stacked-toast variables: 400ms transform/opacity/height; enter and exit 100% down;\n collapsed, each toast behind the front lifts gap × index, shrinks 5% per index and takes the front toast's height;\n hovered or focused, the stack opens to full heights 8px apart. Reduced motion collapses it (kit base rule). */\nconst ROOT = cn(\n \"[--gap:8px] [--scale:calc(1-var(--toast-index)*0.05)] [--height:var(--toast-frontmost-height,var(--toast-height))]\",\n \"[--offset-y:calc(var(--toast-offset-y)*-1+var(--toast-index)*var(--gap)*-1+var(--toast-swipe-movement-y))]\",\n \"absolute bottom-0 right-0 z-[calc(1000-var(--toast-index))] w-full origin-bottom select-none\",\n \"h-[var(--height)] [transform:translateX(var(--toast-swipe-movement-x))_translateY(calc(var(--toast-swipe-movement-y)-var(--toast-index)*var(--gap)))_scale(var(--scale))]\",\n \"data-[expanded]:h-[var(--toast-height)] data-[expanded]:[transform:translateX(var(--toast-swipe-movement-x))_translateY(var(--offset-y))]\",\n \"data-[starting-style]:opacity-0 data-[starting-style]:[transform:translateY(100%)]\",\n \"data-[ending-style]:opacity-0 data-[limited]:opacity-0\",\n \"[&[data-ending-style]:not([data-limited]):not([data-swipe-direction])]:[transform:translateY(100%)]\",\n \"data-[ending-style]:data-[swipe-direction=down]:[transform:translateY(calc(var(--toast-swipe-movement-y)+100%))]\",\n \"data-[ending-style]:data-[swipe-direction=right]:[transform:translateX(calc(var(--toast-swipe-movement-x)+100%))_translateY(var(--offset-y))]\",\n \"[transition:transform_400ms_ease,opacity_400ms,height_400ms,box-shadow_200ms]\",\n // the hover bridge between stacked toasts, so the stack stays open while the pointer crosses a gap\n \"after:absolute after:left-0 after:top-full after:h-[calc(var(--gap)+1px)] after:w-full after:content-['']\",\n // V2's effective look: --surface-raised, tray-line edge (line-strong in dark), 12px radius, sonner's own shadow\n \"flex items-center rounded-kit-xl border border-kit-tray-line bg-kit-surface-raised bg-clip-padding p-4 font-sans text-kit-sm text-kit-fg shadow-[0_4px_12px_rgba(0,0,0,0.1)] [.dark_&]:border-kit-line-strong\",\n);\n/* the toasts behind the front hide their content while the stack is collapsed (sonner data-front=false > * opacity 0) */\nconst CONTENT = \"flex min-w-0 flex-1 items-center gap-1.5 transition-opacity duration-[400ms] data-[behind]:opacity-0 data-[expanded]:opacity-100\";\nconst ACTION =\n \"ml-auto inline-flex h-6 shrink-0 cursor-pointer items-center rounded-kit-md bg-kit-inverse px-2 text-kit-xs font-medium text-kit-fg-inverse hover:bg-kit-inverse-hover [transition:opacity_400ms,box-shadow_200ms,background-color_150ms]\";\n\nfunction KitToastItem({ toast }: { toast: Toast.Root.ToastObject }) {\n const icon = (toast.data as { icon?: React.ReactNode } | undefined)?.icon ?? TYPE_ICON[toast.type ?? \"\"];\n return (\n <Toast.Root toast={toast} className={ROOT}>\n <Toast.Content className={CONTENT}>\n {icon ? (\n <span aria-hidden className=\"flex size-4 shrink-0 items-center [&_svg]:size-4\">\n {icon}\n </span>\n ) : null}\n <div className=\"min-w-0 flex-1\">\n <Toast.Title className=\"font-medium leading-[1.5]\" />\n {toast.description ? <Toast.Description className=\"leading-[1.4] text-kit-fg-2\" /> : null}\n </div>\n {toast.actionProps ? <Toast.Action className={ACTION} /> : null}\n </Toast.Content>\n </Toast.Root>\n );\n}\n\nfunction KitToastList() {\n const { toasts } = Toast.useToastManager();\n return toasts.map((t) => <KitToastItem key={t.id} toast={t} />);\n}\n\nexport interface KitToasterProps {\n /** toasts kept on screen (sonner visibleToasts) */\n limit?: number;\n /** ms before a toast closes; a toast's own `duration` wins; loading toasts stay */\n timeout?: number;\n className?: string;\n}\n\n/** Mount once per document, at the root. Its layer carries KIT_SCOPE (a portal sits outside every kit island). */\nexport function KitToaster({ limit = 3, timeout = 4000, className }: KitToasterProps) {\n return (\n <Toast.Provider toastManager={kitToastManager} limit={limit} timeout={timeout}>\n <Toast.Portal>\n <Toast.Viewport {...KIT_SCOPE} className={cn(VIEWPORT, className)}>\n <KitToastList />\n </Toast.Viewport>\n </Toast.Portal>\n </Toast.Provider>\n );\n}\n"],"mappings":"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"}
|