@kerfjs/ui 5.0.0-beta.104 → 5.0.0-beta.106
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 +155 -116
- package/ai/application-ui-profile.defaults.json +125 -4
- package/ai/compile-time-contracts-v1.json +11 -11
- package/ai/component-catalog.json +2606 -628
- package/ai/component-composition-rules.json +10 -10
- package/ai/component-composition.json +1688 -300
- package/ai/components/README.md +66 -48
- package/ai/components/application-tabs.md +4 -4
- package/ai/components/badge.md +1 -0
- package/ai/components/button.md +91 -0
- package/ai/components/checkbox.md +89 -0
- package/ai/components/choice-chips.md +9 -3
- package/ai/components/color-field.md +92 -0
- package/ai/components/color-picker.md +90 -0
- package/ai/components/color-swatches.md +82 -0
- package/ai/components/combobox.md +6 -4
- package/ai/components/content-item.md +5 -2
- package/ai/components/disclosure.md +83 -0
- package/ai/components/file-picker.md +1 -0
- package/ai/components/foundation.md +1 -1
- package/ai/components/list-action-row.md +3 -3
- package/ai/components/list-detail-dialog.md +90 -0
- package/ai/components/list.md +2 -0
- package/ai/components/lucide-icon.md +2 -0
- package/ai/components/{composer.md → message-composer.md} +17 -16
- package/ai/components/pane.md +3 -1
- package/ai/components/popup-menu.md +12 -9
- package/ai/components/progress-bar.md +82 -0
- package/ai/components/progress-ring.md +80 -0
- package/ai/components/radio-group.md +88 -0
- package/ai/components/recipe-list-detail-dialog.md +5 -5
- package/ai/components/{token-search-field.md → search-field.md} +23 -23
- package/ai/components/select.md +15 -13
- package/ai/components/slider.md +84 -0
- package/ai/components/surface-scaffold.md +16 -13
- package/ai/components/switch.md +81 -0
- package/ai/components/tab-bar.md +6 -6
- package/ai/components/tab-navigator.md +2 -2
- package/ai/components/tabs.md +7 -7
- package/ai/components/tag-field.md +86 -0
- package/ai/components/text-field.md +98 -0
- package/ai/components/text.md +1 -0
- package/ai/components/toast.md +85 -0
- package/ai/components/toolbar-control-group.md +3 -3
- package/ai/components/tooltip.md +81 -0
- package/ai/components/wa-accordion-item.md +11 -5
- package/ai/components/wa-accordion.md +11 -5
- package/ai/components/wa-animated-image.md +2 -1
- package/ai/components/wa-animation.md +1 -0
- package/ai/components/wa-avatar.md +1 -0
- package/ai/components/wa-badge.md +10 -3
- package/ai/components/wa-breadcrumb-item.md +1 -0
- package/ai/components/wa-breadcrumb.md +1 -0
- package/ai/components/wa-button-group.md +6 -4
- package/ai/components/wa-button.md +7 -5
- package/ai/components/wa-callout.md +7 -5
- package/ai/components/wa-card.md +12 -4
- package/ai/components/wa-carousel-item.md +1 -0
- package/ai/components/wa-carousel.md +1 -0
- package/ai/components/wa-checkbox-group.md +11 -4
- package/ai/components/wa-checkbox.md +10 -4
- package/ai/components/wa-color-picker.md +13 -5
- package/ai/components/wa-comparison.md +2 -1
- package/ai/components/wa-copy-button.md +1 -0
- package/ai/components/wa-details.md +11 -5
- package/ai/components/wa-dialog.md +10 -4
- package/ai/components/wa-divider.md +1 -0
- package/ai/components/wa-drawer.md +12 -5
- package/ai/components/wa-dropdown-item.md +8 -6
- package/ai/components/wa-dropdown.md +8 -6
- package/ai/components/wa-format-bytes.md +1 -0
- package/ai/components/wa-format-date.md +1 -0
- package/ai/components/wa-format-number.md +1 -0
- package/ai/components/wa-icon.md +2 -1
- package/ai/components/wa-include.md +6 -4
- package/ai/components/wa-input.md +9 -6
- package/ai/components/wa-intersection-observer.md +1 -0
- package/ai/components/wa-known-date.md +1 -0
- package/ai/components/wa-markdown.md +1 -0
- package/ai/components/wa-mutation-observer.md +1 -0
- package/ai/components/wa-number-input.md +1 -0
- package/ai/components/wa-option.md +7 -5
- package/ai/components/wa-otp-input.md +1 -0
- package/ai/components/wa-page.md +13 -4
- package/ai/components/wa-pagination.md +1 -0
- package/ai/components/wa-popover.md +11 -5
- package/ai/components/wa-popup.md +11 -4
- package/ai/components/wa-progress-bar.md +11 -4
- package/ai/components/wa-progress-ring.md +11 -4
- package/ai/components/wa-qr-code.md +1 -0
- package/ai/components/wa-radio-group.md +12 -4
- package/ai/components/wa-radio.md +10 -4
- package/ai/components/wa-random-content.md +1 -0
- package/ai/components/wa-rating.md +1 -0
- package/ai/components/wa-relative-time.md +1 -0
- package/ai/components/wa-resize-observer.md +1 -0
- package/ai/components/wa-scroller.md +12 -4
- package/ai/components/wa-select.md +7 -5
- package/ai/components/wa-skeleton.md +10 -3
- package/ai/components/wa-slider.md +11 -5
- package/ai/components/wa-spinner.md +7 -5
- package/ai/components/wa-split-panel.md +7 -5
- package/ai/components/wa-step.md +56 -0
- package/ai/components/wa-stepper.md +56 -0
- package/ai/components/wa-switch.md +10 -3
- package/ai/components/wa-tab-group.md +8 -6
- package/ai/components/wa-tab-panel.md +7 -5
- package/ai/components/wa-tab.md +8 -6
- package/ai/components/wa-tag-input.md +62 -0
- package/ai/components/wa-tag.md +9 -6
- package/ai/components/wa-textarea.md +10 -3
- package/ai/components/wa-time-input.md +1 -0
- package/ai/components/wa-toast-item.md +9 -7
- package/ai/components/wa-toast.md +9 -7
- package/ai/components/wa-tooltip.md +11 -5
- package/ai/components/wa-tree-item.md +2 -1
- package/ai/components/wa-tree.md +2 -1
- package/ai/components/wa-zoomable-frame.md +2 -1
- package/ai/components/workbench-dialog.md +90 -0
- package/ai/public-api-signatures-v1.md +1579 -247
- package/ai/skill.md +83 -50
- package/ai/webawesome-jsx-signatures-v1.md +4 -1
- package/dist/badge.d.ts +9 -1
- package/dist/badge.js +1 -1
- package/dist/browser/button.js +5 -0
- package/dist/browser/catalog.js +3 -2
- package/dist/browser/{icon-button.js → checkbox.js} +2 -2
- package/dist/browser/color-field.js +4 -0
- package/dist/browser/color-picker.js +5 -0
- package/dist/browser/color-swatches.js +3 -0
- package/dist/browser/disclosure.js +5 -0
- package/dist/browser/list-action-row.js +1 -0
- package/dist/browser/list-detail-dialog.js +14 -0
- package/dist/browser/message-composer.js +5 -0
- package/dist/browser/popup-menu.js +1 -0
- package/dist/browser/progress-bar.js +3 -0
- package/dist/browser/progress-ring.js +3 -0
- package/dist/browser/radio-group.js +3 -0
- package/dist/browser/search-field.js +4 -0
- package/dist/browser/slider.js +3 -0
- package/dist/browser/surface-scaffold.js +1 -0
- package/dist/browser/switch.js +3 -0
- package/dist/browser/tab-bar-item.js +4 -0
- package/dist/browser/tag-field.js +5 -0
- package/dist/browser/text-field.js +4 -0
- package/dist/browser/workbench-dialog.js +15 -0
- package/dist/button.d.ts +108 -0
- package/dist/button.js +7 -0
- package/dist/button.js.map +1 -0
- package/dist/catalog-resources.d.ts +1 -1
- package/dist/catalog.d.ts +3 -3
- package/dist/catalog.js +57 -27
- package/dist/catalog.js.map +1 -1
- package/dist/checkbox.d.ts +45 -0
- package/dist/checkbox.js +6 -0
- package/dist/checkbox.js.map +1 -0
- package/dist/choice-chips.d.ts +49 -15
- package/dist/choice-chips.js +1 -1
- package/dist/chunk-23PPPNH6.js +93 -0
- package/dist/chunk-23PPPNH6.js.map +1 -0
- package/dist/{chunk-FNZQOUZ5.js → chunk-2FW7D4IG.js} +2 -2
- package/dist/{chunk-FNZQOUZ5.js.map → chunk-2FW7D4IG.js.map} +1 -1
- package/dist/{chunk-ZYU5WRC3.js → chunk-3GLYIIFR.js} +2 -2
- package/dist/{chunk-ZYU5WRC3.js.map → chunk-3GLYIIFR.js.map} +1 -1
- package/dist/{chunk-5NQF35VO.js → chunk-4RECPEHI.js} +2 -2
- package/dist/{chunk-5NQF35VO.js.map → chunk-4RECPEHI.js.map} +1 -1
- package/dist/{chunk-7IUEBNCO.js → chunk-5USKCWGL.js} +8 -3
- package/dist/chunk-5USKCWGL.js.map +1 -0
- package/dist/chunk-6VVIW7VB.js +69 -0
- package/dist/chunk-6VVIW7VB.js.map +1 -0
- package/dist/{chunk-LL45C7BB.js → chunk-7K6U6FCN.js} +1 -1
- package/dist/chunk-7K6U6FCN.js.map +1 -0
- package/dist/{chunk-HQZYKJ56.js → chunk-7W3GKMN4.js} +110 -74
- package/dist/chunk-7W3GKMN4.js.map +1 -0
- package/dist/chunk-ACUKTVS3.js +371 -0
- package/dist/chunk-ACUKTVS3.js.map +1 -0
- package/dist/{chunk-YQ2AC4E2.js → chunk-AMIHGFLP.js} +2 -2
- package/dist/{chunk-YQ2AC4E2.js.map → chunk-AMIHGFLP.js.map} +1 -1
- package/dist/chunk-ATGAJVZ6.js +268 -0
- package/dist/chunk-ATGAJVZ6.js.map +1 -0
- package/dist/chunk-AYPGXR2E.js +20 -0
- package/dist/chunk-AYPGXR2E.js.map +1 -0
- package/dist/{chunk-ETCWQLJV.js → chunk-BKUMG2KB.js} +38 -28
- package/dist/chunk-BKUMG2KB.js.map +1 -0
- package/dist/chunk-C26Q6P4Q.js +76 -0
- package/dist/chunk-C26Q6P4Q.js.map +1 -0
- package/dist/chunk-C3RLKKFQ.js +452 -0
- package/dist/chunk-C3RLKKFQ.js.map +1 -0
- package/dist/{chunk-T5BJBMW7.js → chunk-CIAUILRR.js} +5 -5
- package/dist/chunk-CIAUILRR.js.map +1 -0
- package/dist/chunk-CNM6ZWP2.js +38 -0
- package/dist/chunk-CNM6ZWP2.js.map +1 -0
- package/dist/{chunk-LPHU44S3.js → chunk-CTQUDCY5.js} +3 -1
- package/dist/chunk-CTQUDCY5.js.map +1 -0
- package/dist/{chunk-MXNIVEVL.js → chunk-D4MXSAMI.js} +5 -3
- package/dist/chunk-D4MXSAMI.js.map +1 -0
- package/dist/{chunk-YBWQR2OK.js → chunk-DDSCVEO5.js} +10 -9
- package/dist/chunk-DDSCVEO5.js.map +1 -0
- package/dist/{chunk-SIW64V65.js → chunk-DF2YKGIX.js} +3 -3
- package/dist/{chunk-SIW64V65.js.map → chunk-DF2YKGIX.js.map} +1 -1
- package/dist/{chunk-3SKAEPPZ.js → chunk-ECFCAKWE.js} +4 -4
- package/dist/{chunk-3SKAEPPZ.js.map → chunk-ECFCAKWE.js.map} +1 -1
- package/dist/chunk-EKBMUXFV.js +298 -0
- package/dist/chunk-EKBMUXFV.js.map +1 -0
- package/dist/{chunk-IXLUZHGT.js → chunk-FG6U7KQQ.js} +5 -5
- package/dist/{chunk-IXLUZHGT.js.map → chunk-FG6U7KQQ.js.map} +1 -1
- package/dist/chunk-FKKJHGN5.js +147 -0
- package/dist/chunk-FKKJHGN5.js.map +1 -0
- package/dist/{chunk-FDZNYD4C.js → chunk-GCAK23PU.js} +34 -3
- package/dist/chunk-GCAK23PU.js.map +1 -0
- package/dist/chunk-GXSX6Q6O.js +42 -0
- package/dist/chunk-GXSX6Q6O.js.map +1 -0
- package/dist/{chunk-LOSRXZAH.js → chunk-HJXVVFBT.js} +14 -6
- package/dist/chunk-HJXVVFBT.js.map +1 -0
- package/dist/{chunk-M5KZ26VV.js → chunk-HQZG3OFL.js} +11 -1
- package/dist/chunk-HQZG3OFL.js.map +1 -0
- package/dist/{chunk-ELCMSQNJ.js → chunk-HTERKONR.js} +8 -8
- package/dist/chunk-HTERKONR.js.map +1 -0
- package/dist/chunk-HYORKKYP.js +8 -0
- package/dist/chunk-HYORKKYP.js.map +1 -0
- package/dist/chunk-IO27YTL3.js +73 -0
- package/dist/chunk-IO27YTL3.js.map +1 -0
- package/dist/chunk-ITUQC4FW.js +163 -0
- package/dist/chunk-ITUQC4FW.js.map +1 -0
- package/dist/chunk-K57NINLH.js +137 -0
- package/dist/chunk-K57NINLH.js.map +1 -0
- package/dist/chunk-KC6WUSNS.js +34 -0
- package/dist/chunk-KC6WUSNS.js.map +1 -0
- package/dist/{chunk-W4IK7AWD.js → chunk-KDQZ3E5C.js} +3 -1
- package/dist/chunk-KDQZ3E5C.js.map +1 -0
- package/dist/{chunk-2MSPNRWJ.js → chunk-KK3S5OTW.js} +27 -11
- package/dist/chunk-KK3S5OTW.js.map +1 -0
- package/dist/chunk-LTBVP6VN.js +59 -0
- package/dist/chunk-LTBVP6VN.js.map +1 -0
- package/dist/chunk-OHPYT2BH.js +82 -0
- package/dist/chunk-OHPYT2BH.js.map +1 -0
- package/dist/{chunk-HZPHCSCS.js → chunk-OY2MXIBB.js} +8 -2
- package/dist/chunk-OY2MXIBB.js.map +1 -0
- package/dist/chunk-PE2KPZDW.js +85 -0
- package/dist/chunk-PE2KPZDW.js.map +1 -0
- package/dist/{chunk-QTSMHH5J.js → chunk-QPTJ5DOO.js} +5 -3
- package/dist/chunk-QPTJ5DOO.js.map +1 -0
- package/dist/{chunk-JOR5LGYE.js → chunk-RFLW4FPL.js} +1 -1
- package/dist/chunk-RFLW4FPL.js.map +1 -0
- package/dist/{chunk-U6QYTMDB.js → chunk-RMWNO6BA.js} +6 -2
- package/dist/chunk-RMWNO6BA.js.map +1 -0
- package/dist/{chunk-TDMHA7C3.js → chunk-SQ2Q3OQI.js} +112 -63
- package/dist/chunk-SQ2Q3OQI.js.map +1 -0
- package/dist/{chunk-K4AT3V3J.js → chunk-T74YB76U.js} +13 -11
- package/dist/chunk-T74YB76U.js.map +1 -0
- package/dist/{chunk-BYFTHA4I.js → chunk-TAHR457X.js} +53 -6
- package/dist/chunk-TAHR457X.js.map +1 -0
- package/dist/{chunk-3VXDSIBJ.js → chunk-TKNVL53O.js} +2 -2
- package/dist/{chunk-3VXDSIBJ.js.map → chunk-TKNVL53O.js.map} +1 -1
- package/dist/chunk-TNJLNLVE.js +115 -0
- package/dist/chunk-TNJLNLVE.js.map +1 -0
- package/dist/chunk-TUID42UE.js +15 -0
- package/dist/chunk-TUID42UE.js.map +1 -0
- package/dist/{chunk-CR5U5FV6.js → chunk-UMNHJSIO.js} +93 -80
- package/dist/chunk-UMNHJSIO.js.map +1 -0
- package/dist/chunk-UTCAOOXU.js +116 -0
- package/dist/chunk-UTCAOOXU.js.map +1 -0
- package/dist/{chunk-ZJC5ND3M.js → chunk-VEME3D7K.js} +35 -35
- package/dist/chunk-VEME3D7K.js.map +1 -0
- package/dist/{chunk-HLDRH23D.js → chunk-WJKHLOP5.js} +2 -2
- package/dist/{chunk-HLDRH23D.js.map → chunk-WJKHLOP5.js.map} +1 -1
- package/dist/chunk-WU57BYYM.js +115 -0
- package/dist/chunk-WU57BYYM.js.map +1 -0
- package/dist/{chunk-TGLUDQP2.js → chunk-ZCDRLN3B.js} +11 -11
- package/dist/chunk-ZCDRLN3B.js.map +1 -0
- package/dist/chunk-ZX2QQJXD.js +249 -0
- package/dist/chunk-ZX2QQJXD.js.map +1 -0
- package/dist/{chunk-6E2H2E5A.js → chunk-ZXZAECHZ.js} +6 -6
- package/dist/{chunk-6E2H2E5A.js.map → chunk-ZXZAECHZ.js.map} +1 -1
- package/dist/collapsible-panel.js +3 -3
- package/dist/color-field.d.ts +51 -0
- package/dist/color-field.js +92 -0
- package/dist/color-field.js.map +1 -0
- package/dist/color-picker.d.ts +88 -0
- package/dist/color-picker.js +8 -0
- package/dist/color-picker.js.map +1 -0
- package/dist/color-swatches.d.ts +56 -0
- package/dist/color-swatches.js +4 -0
- package/dist/color-swatches.js.map +1 -0
- package/dist/combobox.js +1 -1
- package/dist/content-item.d.ts +13 -1
- package/dist/content-item.js +1 -1
- package/dist/disclosure-arrow.js +1 -1
- package/dist/disclosure.d.ts +57 -0
- package/dist/disclosure.js +51 -0
- package/dist/disclosure.js.map +1 -0
- package/dist/file-picker.d.ts +7 -0
- package/dist/file-picker.js +1 -1
- package/dist/help-tags-register.d.ts +8 -8
- package/dist/help-tags-register.js +3 -2
- package/dist/help-tags-register.js.map +1 -1
- package/dist/index.d.ts +16 -9
- package/dist/index.js +58 -46
- package/dist/list-action-row.js +4 -1
- package/dist/list-detail-dialog.d.ts +117 -0
- package/dist/list-detail-dialog.js +165 -0
- package/dist/list-detail-dialog.js.map +1 -0
- package/dist/list-header.js +1 -1
- package/dist/list-item.js +1 -1
- package/dist/list.d.ts +17 -2
- package/dist/list.js +1 -1
- package/dist/lucide-icon.d.ts +9 -1
- package/dist/lucide-icon.js +1 -1
- package/dist/{composer.d.ts → message-composer.d.ts} +20 -12
- package/dist/message-composer.js +6 -0
- package/dist/message-composer.js.map +1 -0
- package/dist/nav-stack.js +1 -1
- package/dist/pane.d.ts +36 -3
- package/dist/pane.js +1 -1
- package/dist/popup-menu-register.d.ts +6 -5
- package/dist/popup-menu-register.js +3 -326
- package/dist/popup-menu-register.js.map +1 -1
- package/dist/popup-menu.d.ts +41 -23
- package/dist/popup-menu.js +5 -1
- package/dist/progress-bar.d.ts +52 -0
- package/dist/progress-bar.js +68 -0
- package/dist/progress-bar.js.map +1 -0
- package/dist/progress-ring.d.ts +44 -0
- package/dist/progress-ring.js +73 -0
- package/dist/progress-ring.js.map +1 -0
- package/dist/radio-group.d.ts +62 -0
- package/dist/radio-group.js +4 -0
- package/dist/radio-group.js.map +1 -0
- package/dist/row.js +1 -1
- package/dist/{token-search-model-JA1i8z4D.d.ts → search-field-CrGTN5sa.d.ts} +45 -45
- package/dist/search-field-model.d.ts +3 -0
- package/dist/search-field-model.js +3 -0
- package/dist/search-field-model.js.map +1 -0
- package/dist/search-field.d.ts +3 -0
- package/dist/search-field.js +5 -0
- package/dist/search-field.js.map +1 -0
- package/dist/select-register.d.ts +6 -3
- package/dist/select-register.js +383 -241
- package/dist/select-register.js.map +1 -1
- package/dist/select.d.ts +30 -6
- package/dist/select.js +3 -1
- package/dist/selection.d.ts +54 -0
- package/dist/selection.js +3 -0
- package/dist/selection.js.map +1 -0
- package/dist/slider.d.ts +74 -0
- package/dist/slider.js +103 -0
- package/dist/slider.js.map +1 -0
- package/dist/split-button.js +1 -1
- package/dist/split-view.d.ts +5 -2
- package/dist/split-view.js +18 -159
- package/dist/split-view.js.map +1 -1
- package/dist/state-banner.js +1 -1
- package/dist/styles/badge.css +18 -6
- package/dist/styles/button.css +230 -0
- package/dist/styles/catalog/components/catalog-example.css +13 -4
- package/dist/styles/checkbox.css +121 -0
- package/dist/styles/choice-chips.css +58 -7
- package/dist/styles/color-field.css +125 -0
- package/dist/styles/color-picker.css +331 -0
- package/dist/styles/color-swatches.css +122 -0
- package/dist/styles/combobox.css +7 -5
- package/dist/styles/components/actions/button/button.css +230 -0
- package/dist/styles/components/actions/popup-menu/popup-menu.css +326 -198
- package/dist/styles/components/actions/toolbar/toolbar.css +10 -3
- package/dist/styles/components/actions/toolbar-control-group/toolbar-control-group.css +67 -104
- package/dist/styles/components/actions/toolbar-text/toolbar-text.css +5 -18
- package/dist/styles/components/collections/list/list.css +37 -0
- package/dist/styles/components/feedback/badge/badge.css +18 -6
- package/dist/styles/components/feedback/progress-bar/progress-bar.css +168 -0
- package/dist/styles/components/feedback/progress-ring/progress-ring.css +91 -0
- package/dist/styles/components/feedback/state-banner/state-banner.css +18 -3
- package/dist/styles/components/forms/checkbox/checkbox.css +121 -0
- package/dist/styles/components/forms/choice-chips/choice-chips.css +58 -7
- package/dist/styles/components/forms/color-field/color-field.css +125 -0
- package/dist/styles/components/forms/color-picker/color-picker.css +331 -0
- package/dist/styles/components/forms/color-swatches/color-swatches.css +122 -0
- package/dist/styles/components/forms/combobox/combobox.css +7 -5
- package/dist/styles/components/forms/{composer/composer.css → message-composer/message-composer.css} +17 -33
- package/dist/styles/components/forms/radio-group/radio-group.css +156 -0
- package/dist/styles/{token-search-field.css → components/forms/search-field/search-field.css} +111 -102
- package/dist/styles/components/forms/select/select.css +370 -249
- package/dist/styles/components/forms/slider/slider.css +241 -0
- package/dist/styles/components/forms/switch/switch.css +132 -0
- package/dist/styles/components/forms/tag-field/tag-field.css +8 -0
- package/dist/styles/components/forms/text-field/text-field.css +193 -0
- package/dist/styles/components/layout/pane/pane.css +254 -0
- package/dist/styles/components/layout/resizable-region/resizable-region.css +3 -2
- package/dist/styles/components/layout/row/row.css +11 -0
- package/dist/styles/components/layout/split-view/split-view.css +25 -0
- package/dist/styles/components/layout/workbench/workbench.css +12 -4
- package/dist/styles/components/navigation/disclosure-arrow/disclosure-arrow.css +20 -0
- package/dist/styles/components/navigation/tab-bar/tab-bar.css +7 -7
- package/dist/styles/components/navigation/{app-tab/app-tab.css → tab-bar-item/tab-bar-item.css} +95 -90
- package/dist/styles/components/surfaces/disclosure/disclosure.css +98 -0
- package/dist/styles/components/surfaces/surface-scaffold/surface-scaffold.css +263 -116
- package/dist/styles/components/typography/text/text.css +14 -12
- package/dist/styles/disclosure-arrow.css +20 -0
- package/dist/styles/disclosure.css +98 -0
- package/dist/styles/foundation.css +6 -4
- package/dist/styles/list-detail-dialog.css +11 -0
- package/dist/styles/list.css +37 -0
- package/dist/styles/{composer.css → message-composer.css} +17 -33
- package/dist/styles/overlay-toast.css +149 -0
- package/dist/styles/overlay-tooltip.css +55 -0
- package/dist/styles/pane.css +254 -0
- package/dist/styles/popup-menu.css +326 -198
- package/dist/styles/progress-bar.css +168 -0
- package/dist/styles/progress-ring.css +91 -0
- package/dist/styles/radio-group.css +156 -0
- package/dist/styles/resizable-region.css +3 -2
- package/dist/styles/row.css +11 -0
- package/dist/styles/{components/forms/token-search-field/token-search-field.css → search-field.css} +111 -102
- package/dist/styles/select.css +370 -249
- package/dist/styles/slider.css +241 -0
- package/dist/styles/split-view.css +25 -0
- package/dist/styles/state-banner.css +18 -3
- package/dist/styles/styles.css +16 -5
- package/dist/styles/surface-scaffold.css +263 -116
- package/dist/styles/switch.css +132 -0
- package/dist/styles/{app-tab.css → tab-bar-item.css} +95 -90
- package/dist/styles/tab-bar.css +7 -7
- package/dist/styles/tag-field.css +8 -0
- package/dist/styles/text-field.css +193 -0
- package/dist/styles/text.css +14 -12
- package/dist/styles/toolbar-control-group.css +67 -104
- package/dist/styles/toolbar-text.css +5 -18
- package/dist/styles/toolbar.css +10 -3
- package/dist/styles/webawesome.css +9 -0
- package/dist/styles/workbench-dialog.css +10 -0
- package/dist/styles/workbench.css +12 -4
- package/dist/surface-scaffold-register.d.ts +7 -5
- package/dist/surface-scaffold-register.js +2 -246
- package/dist/surface-scaffold-register.js.map +1 -1
- package/dist/surface-scaffold.d.ts +70 -7
- package/dist/surface-scaffold.js +5 -1
- package/dist/switch.d.ts +38 -0
- package/dist/switch.js +4 -0
- package/dist/switch.js.map +1 -0
- package/dist/{app-tab.d.ts → tab-bar-item.d.ts} +11 -11
- package/dist/tab-bar-item.js +6 -0
- package/dist/tab-bar-item.js.map +1 -0
- package/dist/tab-bar.d.ts +3 -3
- package/dist/tab-bar.js +1 -1
- package/dist/tab-navigator.js +1 -1
- package/dist/tag-field.d.ts +52 -0
- package/dist/tag-field.js +6 -0
- package/dist/tag-field.js.map +1 -0
- package/dist/text-field.d.ts +83 -0
- package/dist/text-field.js +6 -0
- package/dist/text-field.js.map +1 -0
- package/dist/text.d.ts +6 -1
- package/dist/text.js +1 -1
- package/dist/{types-CVgIwSdq.d.ts → types-DmHWkSd6.d.ts} +19 -1
- package/dist/webawesome.d.ts +3 -0
- package/dist/wire-catalog.d.ts +8 -2
- package/dist/wire-catalog.js +16 -4
- package/dist/wire-catalog.js.map +1 -1
- package/dist/wire-checkboxes.d.ts +10 -0
- package/dist/wire-checkboxes.js +3 -0
- package/dist/{wire-composers.js.map → wire-checkboxes.js.map} +1 -1
- package/dist/wire-choice-chips.d.ts +17 -0
- package/dist/wire-choice-chips.js +4 -0
- package/dist/{wire-token-search-fields.js.map → wire-choice-chips.js.map} +1 -1
- package/dist/wire-color-fields.d.ts +33 -0
- package/dist/wire-color-fields.js +82 -0
- package/dist/wire-color-fields.js.map +1 -0
- package/dist/wire-color-pickers.d.ts +34 -0
- package/dist/wire-color-pickers.js +9 -0
- package/dist/wire-color-pickers.js.map +1 -0
- package/dist/wire-comboboxes.js +2 -1
- package/dist/wire-content-items.d.ts +5 -1
- package/dist/wire-content-items.js +84 -15
- package/dist/wire-content-items.js.map +1 -1
- package/dist/wire-file-pickers.d.ts +3 -2
- package/dist/wire-file-pickers.js +1 -1
- package/dist/{wire-composers.d.ts → wire-message-composers.d.ts} +5 -4
- package/dist/wire-message-composers.js +3 -0
- package/dist/wire-message-composers.js.map +1 -0
- package/dist/wire-overlay-sheets.js +1 -1
- package/dist/wire-pane-chrome.d.ts +21 -0
- package/dist/wire-pane-chrome.js +67 -0
- package/dist/wire-pane-chrome.js.map +1 -0
- package/dist/{wire-token-search-fields.d.ts → wire-search-fields.d.ts} +25 -25
- package/dist/wire-search-fields.js +6 -0
- package/dist/wire-search-fields.js.map +1 -0
- package/dist/wire-sliders.d.ts +12 -0
- package/dist/wire-sliders.js +31 -0
- package/dist/wire-sliders.js.map +1 -0
- package/dist/wire-tab-bars.js +1 -1
- package/dist/wire-tag-fields.d.ts +41 -0
- package/dist/wire-tag-fields.js +258 -0
- package/dist/wire-tag-fields.js.map +1 -0
- package/dist/wire-text-fields.d.ts +12 -0
- package/dist/wire-text-fields.js +3 -0
- package/dist/wire-text-fields.js.map +1 -0
- package/dist/workbench-dialog.d.ts +97 -0
- package/dist/workbench-dialog.js +124 -0
- package/dist/workbench-dialog.js.map +1 -0
- package/dist/workbench.d.ts +5 -0
- package/dist/workbench.js +1 -1
- package/docs/accessibility.md +181 -97
- package/docs/anchored-surface.md +8 -7
- package/docs/app-layouts.md +28 -0
- package/docs/catalog.md +14 -5
- package/docs/color-field.md +65 -0
- package/docs/color-picker.md +71 -0
- package/docs/color-swatches.md +46 -0
- package/docs/component-contract.md +31 -32
- package/docs/component-selection.md +228 -164
- package/docs/design/templates/button/emphasis-dark.svg +1 -0
- package/docs/design/templates/button/emphasis.svg +1 -0
- package/docs/design/templates/button/icons-dark.svg +1 -0
- package/docs/design/templates/button/icons.svg +1 -0
- package/docs/design/templates/button/pill-dark.svg +1 -0
- package/docs/design/templates/button/pill.svg +1 -0
- package/docs/design/templates/button/states-dark.svg +1 -0
- package/docs/design/templates/button/states.svg +1 -0
- package/docs/design/templates/button/toggles-dark.svg +1 -0
- package/docs/design/templates/button/toggles.svg +1 -0
- package/docs/design/templates/button/tones-dark.svg +1 -0
- package/docs/design/templates/button/tones.svg +1 -0
- package/docs/design/templates/button-dark.svg +1 -0
- package/docs/design/templates/button.svg +1 -0
- package/docs/design/templates/checkbox/compact-dark.svg +1 -0
- package/docs/design/templates/checkbox/compact.svg +1 -0
- package/docs/design/templates/checkbox/error-dark.svg +1 -0
- package/docs/design/templates/checkbox/error.svg +1 -0
- package/docs/design/templates/checkbox/mixed-dark.svg +1 -0
- package/docs/design/templates/checkbox/mixed.svg +1 -0
- package/docs/design/templates/checkbox/states-dark.svg +1 -0
- package/docs/design/templates/checkbox/states.svg +1 -0
- package/docs/design/templates/checkbox-dark.svg +1 -0
- package/docs/design/templates/checkbox.svg +1 -0
- package/docs/design/templates/choice-chips/color-palette-dark.svg +1 -1
- package/docs/design/templates/choice-chips/color-palette.svg +1 -1
- package/docs/design/templates/choice-chips/compact-icons-dark.svg +1 -1
- package/docs/design/templates/choice-chips/compact-icons.svg +1 -1
- package/docs/design/templates/choice-chips/multiple-dark.svg +1 -1
- package/docs/design/templates/choice-chips/multiple.svg +1 -1
- package/docs/design/templates/choice-chips-dark.svg +1 -1
- package/docs/design/templates/choice-chips.svg +1 -1
- package/docs/design/templates/color-field/compact-dark.svg +1 -0
- package/docs/design/templates/color-field/compact.svg +1 -0
- package/docs/design/templates/color-field/error-dark.svg +1 -0
- package/docs/design/templates/color-field/error.svg +1 -0
- package/docs/design/templates/color-field/hint-dark.svg +1 -0
- package/docs/design/templates/color-field/hint.svg +1 -0
- package/docs/design/templates/color-field-dark.svg +1 -0
- package/docs/design/templates/color-field.svg +1 -0
- package/docs/design/templates/color-picker/gray-dark.svg +1 -0
- package/docs/design/templates/color-picker/gray.svg +1 -0
- package/docs/design/templates/color-picker/rgb-dark.svg +1 -0
- package/docs/design/templates/color-picker/rgb.svg +1 -0
- package/docs/design/templates/color-picker-dark.svg +1 -0
- package/docs/design/templates/color-picker.svg +1 -0
- package/docs/design/templates/color-swatches/palette-dark.svg +1 -0
- package/docs/design/templates/color-swatches/palette.svg +1 -0
- package/docs/design/templates/color-swatches-dark.svg +1 -0
- package/docs/design/templates/color-swatches.svg +1 -0
- package/docs/design/templates/disclosure/framed-sunken-dark.svg +1 -0
- package/docs/design/templates/disclosure/framed-sunken.svg +1 -0
- package/docs/design/templates/disclosure/plain-dark.svg +1 -0
- package/docs/design/templates/disclosure/plain.svg +1 -0
- package/docs/design/templates/disclosure-dark.svg +1 -0
- package/docs/design/templates/disclosure.svg +1 -0
- package/docs/design/templates/list-header/size-l-dark.svg +1 -1
- package/docs/design/templates/list-header/size-l.svg +1 -1
- package/docs/design/templates/list-header/size-m-dark.svg +1 -1
- package/docs/design/templates/list-header/size-m.svg +1 -1
- package/docs/design/templates/list-header/size-xl-dark.svg +1 -1
- package/docs/design/templates/list-header/size-xl.svg +1 -1
- package/docs/design/templates/list-header-dark.svg +1 -1
- package/docs/design/templates/list-header.svg +1 -1
- package/docs/design/templates/message-composer/chat-dark.svg +1 -0
- package/docs/design/templates/message-composer/chat.svg +1 -0
- package/docs/design/templates/{composer → message-composer}/prompt-dark.svg +1 -1
- package/docs/design/templates/{composer → message-composer}/prompt.svg +1 -1
- package/docs/design/templates/message-composer-dark.svg +1 -0
- package/docs/design/templates/message-composer.svg +1 -0
- package/docs/design/templates/progress-bar/determinate-dark.svg +1 -0
- package/docs/design/templates/progress-bar/determinate.svg +1 -0
- package/docs/design/templates/progress-bar/tones-dark.svg +1 -0
- package/docs/design/templates/progress-bar/tones.svg +1 -0
- package/docs/design/templates/progress-bar-dark.svg +1 -0
- package/docs/design/templates/progress-bar.svg +1 -0
- package/docs/design/templates/progress-ring/sizes-dark.svg +1 -0
- package/docs/design/templates/progress-ring/sizes.svg +1 -0
- package/docs/design/templates/progress-ring/tones-dark.svg +1 -0
- package/docs/design/templates/progress-ring/tones.svg +1 -0
- package/docs/design/templates/progress-ring-dark.svg +1 -0
- package/docs/design/templates/progress-ring.svg +1 -0
- package/docs/design/templates/radio-group/horizontal-dark.svg +1 -0
- package/docs/design/templates/radio-group/horizontal.svg +1 -0
- package/docs/design/templates/radio-group/vertical-dark.svg +1 -0
- package/docs/design/templates/radio-group/vertical.svg +1 -0
- package/docs/design/templates/radio-group-dark.svg +1 -0
- package/docs/design/templates/radio-group.svg +1 -0
- package/docs/design/templates/segmented-control/equal-dark.svg +1 -1
- package/docs/design/templates/segmented-control/equal.svg +1 -1
- package/docs/design/templates/segmented-control/pill-small-dark.svg +1 -1
- package/docs/design/templates/segmented-control/pill-small.svg +1 -1
- package/docs/design/templates/segmented-control-dark.svg +1 -1
- package/docs/design/templates/segmented-control.svg +1 -1
- package/docs/design/templates/select/compact-dark.svg +1 -0
- package/docs/design/templates/select/compact.svg +1 -0
- package/docs/design/templates/select/form-dark.svg +1 -0
- package/docs/design/templates/select/form.svg +1 -0
- package/docs/design/templates/select/icons-dark.svg +1 -0
- package/docs/design/templates/select/icons.svg +1 -0
- package/docs/design/templates/select-dark.svg +1 -0
- package/docs/design/templates/select.svg +1 -0
- package/docs/design/templates/slider/compact-dark.svg +1 -0
- package/docs/design/templates/slider/compact.svg +1 -0
- package/docs/design/templates/slider/readout-dark.svg +1 -0
- package/docs/design/templates/slider/readout.svg +1 -0
- package/docs/design/templates/slider/ticks-dark.svg +1 -0
- package/docs/design/templates/slider/ticks.svg +1 -0
- package/docs/design/templates/slider-dark.svg +1 -0
- package/docs/design/templates/slider.svg +1 -0
- package/docs/design/templates/switch/compact-dark.svg +1 -0
- package/docs/design/templates/switch/compact.svg +1 -0
- package/docs/design/templates/switch/states-dark.svg +1 -0
- package/docs/design/templates/switch/states.svg +1 -0
- package/docs/design/templates/switch-dark.svg +1 -0
- package/docs/design/templates/switch.svg +1 -0
- package/docs/design/templates/tag-field/error-dark.svg +1 -0
- package/docs/design/templates/tag-field/error.svg +1 -0
- package/docs/design/templates/tag-field/tags-dark.svg +1 -0
- package/docs/design/templates/tag-field/tags.svg +1 -0
- package/docs/design/templates/tag-field-dark.svg +1 -0
- package/docs/design/templates/tag-field.svg +1 -0
- package/docs/design/templates/text-field/compact-dark.svg +1 -0
- package/docs/design/templates/text-field/compact.svg +1 -0
- package/docs/design/templates/text-field/error-dark.svg +1 -0
- package/docs/design/templates/text-field/error.svg +1 -0
- package/docs/design/templates/text-field/labeled-dark.svg +1 -0
- package/docs/design/templates/text-field/labeled.svg +1 -0
- package/docs/design/templates/text-field/multiline-dark.svg +1 -0
- package/docs/design/templates/text-field/multiline.svg +1 -0
- package/docs/design/templates/text-field/search-dark.svg +1 -0
- package/docs/design/templates/text-field/search.svg +1 -0
- package/docs/design/templates/text-field-dark.svg +1 -0
- package/docs/design/templates/text-field.svg +1 -0
- package/docs/design/templates/toolbar/title-and-actions-dark.svg +1 -1
- package/docs/design/templates/toolbar/title-and-actions.svg +1 -1
- package/docs/design/templates/toolbar/width-visibility-320-dark.svg +1 -1
- package/docs/design/templates/toolbar/width-visibility-320.svg +1 -1
- package/docs/design/templates/toolbar/width-visibility-600-dark.svg +1 -1
- package/docs/design/templates/toolbar/width-visibility-600.svg +1 -1
- package/docs/design/templates/toolbar-dark.svg +1 -1
- package/docs/design/templates/toolbar.svg +1 -1
- package/docs/design/templates/value-table/details-dark.svg +1 -1
- package/docs/design/templates/value-table/details.svg +1 -1
- package/docs/design/templates/value-table-dark.svg +1 -1
- package/docs/design/templates/value-table.svg +1 -1
- package/docs/design/templates.md +19 -6
- package/docs/design-philosophy.md +6 -6
- package/docs/disclosure.md +63 -0
- package/docs/examples/component-catalog-extension.json +2 -2
- package/docs/layout.md +16 -7
- package/docs/list-detail-dialog.md +96 -0
- package/docs/manual-test-plan.md +1 -1
- package/docs/{composer.md → message-composer.md} +41 -28
- package/docs/overlay-toast.md +62 -0
- package/docs/overlay-tooltip.md +53 -0
- package/docs/progress.md +62 -0
- package/docs/recipes.md +15 -21
- package/docs/slider.md +64 -0
- package/docs/surface-scaffold.md +155 -88
- package/docs/tag-field.md +66 -0
- package/docs/type-contracts.md +8 -8
- package/docs/ui-analyzer.md +1 -1
- package/docs/ui-doctor.md +11 -6
- package/docs/ux-demo.md +6 -6
- package/docs/webawesome-migration.md +80 -0
- package/docs/webawesome-theme.md +57 -35
- package/docs/workbench-dialog.md +85 -0
- package/docs/workbench.md +10 -6
- package/docs/writing.md +10 -8
- package/doctor/copy-capitalization-checks.mjs +18 -9
- package/llms.txt +127 -57
- package/package.json +156 -39
- package/ux-demo/recipes/composer-form.tsx +18 -19
- package/ux-demo/recipes/list-detail-dialog.tsx +55 -162
- package/ux-demo/recipes/mount-recipe.ts +7 -6
- package/ux-demo/recipes/types.ts +1 -0
- package/ai/components/icon-button.md +0 -82
- package/ai/components/icon-toggle-button.md +0 -80
- package/dist/app-tab.js +0 -6
- package/dist/app-tab.js.map +0 -1
- package/dist/browser/app-tab.js +0 -4
- package/dist/browser/composer.js +0 -4
- package/dist/browser/icon-toggle-button.js +0 -4
- package/dist/browser/token-search-field.js +0 -4
- package/dist/chunk-2MSPNRWJ.js.map +0 -1
- package/dist/chunk-7IUEBNCO.js.map +0 -1
- package/dist/chunk-AV7CPAPT.js +0 -82
- package/dist/chunk-AV7CPAPT.js.map +0 -1
- package/dist/chunk-BYFTHA4I.js.map +0 -1
- package/dist/chunk-CA7LNX3J.js +0 -44
- package/dist/chunk-CA7LNX3J.js.map +0 -1
- package/dist/chunk-CR5U5FV6.js.map +0 -1
- package/dist/chunk-ELCMSQNJ.js.map +0 -1
- package/dist/chunk-ETCWQLJV.js.map +0 -1
- package/dist/chunk-FDZNYD4C.js.map +0 -1
- package/dist/chunk-FR76ZJQC.js +0 -90
- package/dist/chunk-FR76ZJQC.js.map +0 -1
- package/dist/chunk-HQZYKJ56.js.map +0 -1
- package/dist/chunk-HZPHCSCS.js.map +0 -1
- package/dist/chunk-JOR5LGYE.js.map +0 -1
- package/dist/chunk-K4AT3V3J.js.map +0 -1
- package/dist/chunk-LL45C7BB.js.map +0 -1
- package/dist/chunk-LOSRXZAH.js.map +0 -1
- package/dist/chunk-LPHU44S3.js.map +0 -1
- package/dist/chunk-M5KZ26VV.js.map +0 -1
- package/dist/chunk-MXNIVEVL.js.map +0 -1
- package/dist/chunk-NS762OVM.js +0 -222
- package/dist/chunk-NS762OVM.js.map +0 -1
- package/dist/chunk-QTSMHH5J.js.map +0 -1
- package/dist/chunk-T5BJBMW7.js.map +0 -1
- package/dist/chunk-TDMHA7C3.js.map +0 -1
- package/dist/chunk-TGLUDQP2.js.map +0 -1
- package/dist/chunk-U6QYTMDB.js.map +0 -1
- package/dist/chunk-VFYO3UGZ.js +0 -45
- package/dist/chunk-VFYO3UGZ.js.map +0 -1
- package/dist/chunk-W4IK7AWD.js.map +0 -1
- package/dist/chunk-YBWQR2OK.js.map +0 -1
- package/dist/chunk-ZJC5ND3M.js.map +0 -1
- package/dist/composer.js +0 -5
- package/dist/composer.js.map +0 -1
- package/dist/icon-button.d.ts +0 -46
- package/dist/icon-button.js +0 -6
- package/dist/icon-button.js.map +0 -1
- package/dist/icon-toggle-button.d.ts +0 -42
- package/dist/icon-toggle-button.js +0 -6
- package/dist/icon-toggle-button.js.map +0 -1
- package/dist/styles/components/actions/icon-button/icon-button.css +0 -22
- package/dist/styles/components/actions/icon-toggle-button/icon-toggle-button.css +0 -83
- package/dist/styles/icon-button.css +0 -22
- package/dist/styles/icon-toggle-button.css +0 -83
- package/dist/token-search-field.d.ts +0 -3
- package/dist/token-search-field.js +0 -5
- package/dist/token-search-field.js.map +0 -1
- package/dist/token-search-model.d.ts +0 -3
- package/dist/token-search-model.js +0 -3
- package/dist/token-search-model.js.map +0 -1
- package/dist/wire-composers.js +0 -3
- package/dist/wire-token-search-fields.js +0 -6
- package/docs/design/templates/composer/chat-dark.svg +0 -1
- package/docs/design/templates/composer/chat.svg +0 -1
- package/docs/design/templates/composer-dark.svg +0 -1
- package/docs/design/templates/composer.svg +0 -1
- /package/docs/design/templates/{token-search-field → search-field}/empty-dark.svg +0 -0
- /package/docs/design/templates/{token-search-field → search-field}/empty.svg +0 -0
- /package/docs/design/templates/{token-search-field → search-field}/tokens-dark.svg +0 -0
- /package/docs/design/templates/{token-search-field → search-field}/tokens.svg +0 -0
- /package/docs/design/templates/{token-search-field-dark.svg → search-field-dark.svg} +0 -0
- /package/docs/design/templates/{token-search-field.svg → search-field.svg} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"wire-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"wire-choice-chips.js"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ColorPickerMode, ColorPickerProps } from './color-picker.js';
|
|
2
|
+
import 'kerfjs';
|
|
3
|
+
import './color-swatches.js';
|
|
4
|
+
import './css-values.js';
|
|
5
|
+
|
|
6
|
+
/** Reported to {@link WireColorFieldsOptions.onInput} and `onChange`. */
|
|
7
|
+
interface ColorFieldChange {
|
|
8
|
+
id: string;
|
|
9
|
+
/** `#rrggbb`, or `#rrggbbaa` below full opacity. */
|
|
10
|
+
value: string;
|
|
11
|
+
mode: ColorPickerMode;
|
|
12
|
+
}
|
|
13
|
+
/** The picker options a field's popup takes beyond its value, model, and opacity. */
|
|
14
|
+
type ColorFieldPickerOptions = Pick<ColorPickerProps, 'presets' | 'samples' | 'addSampleAction' | 'eyedropper'>;
|
|
15
|
+
interface WireColorFieldsOptions {
|
|
16
|
+
/** Every live edit in the open picker. */
|
|
17
|
+
onInput?: (change: ColorFieldChange) => void;
|
|
18
|
+
/** A committed edit: apply it and re-render the ColorField with it. */
|
|
19
|
+
onChange?: (change: ColorFieldChange) => void;
|
|
20
|
+
/** Per-field picker options (presets, samples, the sampler), keyed by field id. */
|
|
21
|
+
pickers?: Readonly<Record<string, ColorFieldPickerOptions>>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Wire every ColorField under `root`: pressing a field's trigger opens a
|
|
25
|
+
* ColorPicker in an AnchoredSurface below it, with the field's value, model,
|
|
26
|
+
* and opacity, plus any `pickers[id]` options. Edits preview at once on the
|
|
27
|
+
* trigger's swatch and hex and go to `onInput`; committed edits go to
|
|
28
|
+
* `onChange`. Escape or a press outside closes the picker and returns focus
|
|
29
|
+
* to the trigger. Returns a disposer that also closes an open picker.
|
|
30
|
+
*/
|
|
31
|
+
declare function wireColorFields(root: HTMLElement, { onInput, onChange, pickers }?: WireColorFieldsOptions): () => void;
|
|
32
|
+
|
|
33
|
+
export { type ColorFieldChange, type ColorFieldPickerOptions, type WireColorFieldsOptions, wireColorFields };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { wireColorPickers } from './chunk-ACUKTVS3.js';
|
|
2
|
+
import { ColorPicker } from './chunk-EKBMUXFV.js';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
import { openAnchoredSurface } from './chunk-3WYREXW4.js';
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
import { signal } from 'kerfjs';
|
|
10
|
+
import { jsx } from 'kerfjs/jsx-runtime';
|
|
11
|
+
|
|
12
|
+
function wireColorFields(root, { onInput, onChange, pickers = {} } = {}) {
|
|
13
|
+
const open = /* @__PURE__ */ new Map();
|
|
14
|
+
const preview = (field, value) => {
|
|
15
|
+
field.querySelector(".kui-color-field__swatch").style.setProperty("--_kui-color-field-color", value);
|
|
16
|
+
field.querySelector(".kui-color-field__hex").textContent = value.slice(1).toUpperCase();
|
|
17
|
+
const hidden = field.querySelector(
|
|
18
|
+
'input[type="hidden"]'
|
|
19
|
+
);
|
|
20
|
+
if (hidden) hidden.value = value;
|
|
21
|
+
};
|
|
22
|
+
const onClick = (event) => {
|
|
23
|
+
const trigger = event.target.closest(
|
|
24
|
+
".kui-color-field__trigger"
|
|
25
|
+
);
|
|
26
|
+
const field = trigger?.closest(
|
|
27
|
+
'[data-component="color-field"]'
|
|
28
|
+
);
|
|
29
|
+
if (!trigger || !field || trigger.disabled || open.has(field)) return;
|
|
30
|
+
const id = field.dataset.colorFieldId;
|
|
31
|
+
const value = signal(field.dataset.value);
|
|
32
|
+
const mode = signal(field.dataset.mode);
|
|
33
|
+
const label = root.ownerDocument.getElementById(`${id}-label`)?.textContent?.trim() || "Color";
|
|
34
|
+
const handle = openAnchoredSurface(
|
|
35
|
+
trigger,
|
|
36
|
+
() => /* @__PURE__ */ jsx(
|
|
37
|
+
ColorPicker,
|
|
38
|
+
{
|
|
39
|
+
...pickers[id],
|
|
40
|
+
id: `${id}-picker`,
|
|
41
|
+
label,
|
|
42
|
+
value: value.value,
|
|
43
|
+
mode: mode.value,
|
|
44
|
+
alpha: field.hasAttribute("data-alpha")
|
|
45
|
+
}
|
|
46
|
+
),
|
|
47
|
+
{ label, placement: "bottom", align: "start" }
|
|
48
|
+
);
|
|
49
|
+
trigger.setAttribute("aria-expanded", "true");
|
|
50
|
+
const report = (committed) => (change) => {
|
|
51
|
+
preview(field, change.value);
|
|
52
|
+
const payload = { id, value: change.value, mode: change.mode };
|
|
53
|
+
if (committed) {
|
|
54
|
+
field.dataset.value = change.value;
|
|
55
|
+
field.dataset.mode = change.mode;
|
|
56
|
+
value.value = change.value;
|
|
57
|
+
mode.value = change.mode;
|
|
58
|
+
onChange?.(payload);
|
|
59
|
+
} else onInput?.(payload);
|
|
60
|
+
};
|
|
61
|
+
const stopPicker = wireColorPickers(handle.el, {
|
|
62
|
+
onInput: report(false),
|
|
63
|
+
onChange: report(true)
|
|
64
|
+
});
|
|
65
|
+
const close = () => handle.close();
|
|
66
|
+
open.set(field, close);
|
|
67
|
+
void handle.result.then(() => {
|
|
68
|
+
stopPicker();
|
|
69
|
+
open.delete(field);
|
|
70
|
+
trigger.setAttribute("aria-expanded", "false");
|
|
71
|
+
});
|
|
72
|
+
};
|
|
73
|
+
root.addEventListener("click", onClick);
|
|
74
|
+
return () => {
|
|
75
|
+
root.removeEventListener("click", onClick);
|
|
76
|
+
for (const close of open.values()) close();
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export { wireColorFields };
|
|
81
|
+
|
|
82
|
+
//# sourceMappingURL=wire-color-fields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/forms/color-field/wiring/wire-color-fields.tsx"],"names":[],"mappings":"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","file":"wire-color-fields.js","sourcesContent":["import { signal } from 'kerfjs';\n\nimport { openAnchoredSurface } from '../../../feedback/anchored-surface/anchored-surface.js';\nimport {\n ColorPicker,\n type ColorPickerMode,\n type ColorPickerProps,\n} from '../../color-picker/color-picker.js';\nimport { wireColorPickers } from '../../color-picker/wiring/wire-color-pickers.js';\n\n/** Reported to {@link WireColorFieldsOptions.onInput} and `onChange`. */\nexport interface ColorFieldChange {\n id: string;\n /** `#rrggbb`, or `#rrggbbaa` below full opacity. */\n value: string;\n mode: ColorPickerMode;\n}\n\n/** The picker options a field's popup takes beyond its value, model, and opacity. */\nexport type ColorFieldPickerOptions = Pick<\n ColorPickerProps,\n 'presets' | 'samples' | 'addSampleAction' | 'eyedropper'\n>;\n\nexport interface WireColorFieldsOptions {\n /** Every live edit in the open picker. */\n onInput?: (change: ColorFieldChange) => void;\n /** A committed edit: apply it and re-render the ColorField with it. */\n onChange?: (change: ColorFieldChange) => void;\n /** Per-field picker options (presets, samples, the sampler), keyed by field id. */\n pickers?: Readonly<Record<string, ColorFieldPickerOptions>>;\n}\n\n/**\n * Wire every ColorField under `root`: pressing a field's trigger opens a\n * ColorPicker in an AnchoredSurface below it, with the field's value, model,\n * and opacity, plus any `pickers[id]` options. Edits preview at once on the\n * trigger's swatch and hex and go to `onInput`; committed edits go to\n * `onChange`. Escape or a press outside closes the picker and returns focus\n * to the trigger. Returns a disposer that also closes an open picker.\n */\nexport function wireColorFields(\n root: HTMLElement,\n { onInput, onChange, pickers = {} }: WireColorFieldsOptions = {},\n): () => void {\n const open = new Map<HTMLElement, () => void>();\n\n const preview = (field: HTMLElement, value: string) => {\n field\n .querySelector<HTMLElement>('.kui-color-field__swatch')!\n .style.setProperty('--_kui-color-field-color', value);\n field.querySelector('.kui-color-field__hex')!.textContent = value\n .slice(1)\n .toUpperCase();\n const hidden = field.querySelector<HTMLInputElement>(\n 'input[type=\"hidden\"]',\n );\n if (hidden) hidden.value = value;\n };\n\n const onClick = (event: MouseEvent) => {\n const trigger = (event.target as Element).closest<HTMLButtonElement>(\n '.kui-color-field__trigger',\n );\n const field = trigger?.closest<HTMLElement>(\n '[data-component=\"color-field\"]',\n );\n if (!trigger || !field || trigger.disabled || open.has(field)) return;\n const id = field.dataset.colorFieldId!;\n const value = signal(field.dataset.value!);\n const mode = signal(field.dataset.mode as ColorPickerMode);\n const label =\n root.ownerDocument.getElementById(`${id}-label`)?.textContent?.trim() ||\n 'Color';\n const handle = openAnchoredSurface(\n trigger,\n () => (\n <ColorPicker\n {...pickers[id]}\n id={`${id}-picker`}\n label={label}\n value={value.value}\n mode={mode.value}\n alpha={field.hasAttribute('data-alpha')}\n />\n ),\n { label, placement: 'bottom', align: 'start' },\n );\n trigger.setAttribute('aria-expanded', 'true');\n const report =\n (committed: boolean) =>\n (change: { value: string; mode: ColorPickerMode }) => {\n preview(field, change.value);\n const payload = { id, value: change.value, mode: change.mode };\n if (committed) {\n // Until the app re-renders, the next open starts from this edit.\n field.dataset.value = change.value;\n field.dataset.mode = change.mode;\n value.value = change.value;\n mode.value = change.mode;\n onChange?.(payload);\n } else onInput?.(payload);\n };\n const stopPicker = wireColorPickers(handle.el, {\n onInput: report(false),\n onChange: report(true),\n });\n const close = () => handle.close();\n open.set(field, close);\n void handle.result.then(() => {\n stopPicker();\n open.delete(field);\n trigger.setAttribute('aria-expanded', 'false');\n });\n };\n\n root.addEventListener('click', onClick);\n return () => {\n root.removeEventListener('click', onClick);\n for (const close of open.values()) close();\n };\n}\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ColorPickerMode } from './color-picker.js';
|
|
2
|
+
import 'kerfjs';
|
|
3
|
+
import './color-swatches.js';
|
|
4
|
+
import './css-values.js';
|
|
5
|
+
|
|
6
|
+
/** Reported to {@link WireColorPickersOptions.onInput} and `onChange`. */
|
|
7
|
+
interface ColorPickerChange {
|
|
8
|
+
id: string;
|
|
9
|
+
/** `#rrggbb`, or `#rrggbbaa` below full opacity. */
|
|
10
|
+
value: string;
|
|
11
|
+
mode: ColorPickerMode;
|
|
12
|
+
element: HTMLElement;
|
|
13
|
+
}
|
|
14
|
+
interface WireColorPickersOptions {
|
|
15
|
+
/** Every live change: a drag, an arrow key, a field edit. */
|
|
16
|
+
onInput?: (change: ColorPickerChange) => void;
|
|
17
|
+
/** A committed change: a drag or key run ending, a field or swatch commit, a mode switch. */
|
|
18
|
+
onChange?: (change: ColorPickerChange) => void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Make every ColorPicker under `root` interactive. The area takes pointer
|
|
22
|
+
* drags and the arrow keys (Shift for steps of 10%); the hue and opacity
|
|
23
|
+
* sliders are native ranges; channel, hex, and opacity fields commit on Enter
|
|
24
|
+
* or blur; the model menu switches the channel fields; the screen sampler
|
|
25
|
+
* opens the EyeDropper where the browser has it; preset and sample swatches
|
|
26
|
+
* apply their color. Each change updates the picker at once, dispatches a
|
|
27
|
+
* bubbling `kui-color-input` (or `kui-color-change` when committed) event
|
|
28
|
+
* with `{ value, mode }`, and calls `onInput` / `onChange`. When the app
|
|
29
|
+
* re-renders a picker with a different `value`, the picker adopts it.
|
|
30
|
+
* Returns a disposer.
|
|
31
|
+
*/
|
|
32
|
+
declare function wireColorPickers(root: HTMLElement, { onInput, onChange }?: WireColorPickersOptions): () => void;
|
|
33
|
+
|
|
34
|
+
export { type ColorPickerChange, type WireColorPickersOptions, wireColorPickers };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"wire-color-pickers.js"}
|
package/dist/wire-comboboxes.js
CHANGED
|
@@ -4,7 +4,11 @@ declare function isContentItemActivation(event: Event, item: HTMLElement): boole
|
|
|
4
4
|
* Give interactive ContentItems native-like Enter/Space activation with one
|
|
5
5
|
* delegated listener pair. Space activates on release and is cancelled if
|
|
6
6
|
* focus moves; the item's own `data-action` still goes through the app's
|
|
7
|
-
* ordinary delegated click handler.
|
|
7
|
+
* ordinary delegated click handler. The activation click mirrors the Shift,
|
|
8
|
+
* Ctrl, and Meta state of the activating key (Space uses the state at press),
|
|
9
|
+
* so the click handler can read `shiftKey` / `metaKey` / `ctrlKey` for
|
|
10
|
+
* keyboard range and toggle selection. Alt-modified keys are left to the
|
|
11
|
+
* platform. Returns a disposer.
|
|
8
12
|
*/
|
|
9
13
|
declare function wireContentItems(root: HTMLElement): () => void;
|
|
10
14
|
|
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
var ITEM_SELECTOR = '[data-component="content-item"][data-interactive="true"]';
|
|
3
3
|
var NESTED_CONTROL_SELECTOR = 'button, a[href], input, select, textarea, [contenteditable="true"], [role="button"]';
|
|
4
4
|
var MULTI_GRID_SELECTOR = '[role="grid"][aria-multiselectable="true"]';
|
|
5
|
+
var MULTI_ROW_SELECTOR = `${ITEM_SELECTOR}[data-selection-mode="multiple"]`;
|
|
6
|
+
function gridRows(grid) {
|
|
7
|
+
return Array.from(
|
|
8
|
+
grid.querySelectorAll(
|
|
9
|
+
`${MULTI_ROW_SELECTOR}:not([data-disabled="true"])`
|
|
10
|
+
)
|
|
11
|
+
).filter((row) => row.closest(MULTI_GRID_SELECTOR) === grid);
|
|
12
|
+
}
|
|
5
13
|
function nextTile(item, rows, key) {
|
|
6
14
|
const current = item.getBoundingClientRect();
|
|
7
15
|
const centerX = current.left + current.width / 2;
|
|
@@ -46,18 +54,73 @@ function actionItem(root, event) {
|
|
|
46
54
|
function isContentItemActivation(event, item) {
|
|
47
55
|
return actionItem(item, event) === item;
|
|
48
56
|
}
|
|
57
|
+
function activate(item, modifiers) {
|
|
58
|
+
item.dispatchEvent(
|
|
59
|
+
new MouseEvent("click", {
|
|
60
|
+
bubbles: true,
|
|
61
|
+
cancelable: true,
|
|
62
|
+
composed: true,
|
|
63
|
+
view: item.ownerDocument.defaultView,
|
|
64
|
+
shiftKey: modifiers.shiftKey,
|
|
65
|
+
ctrlKey: modifiers.ctrlKey,
|
|
66
|
+
metaKey: modifiers.metaKey
|
|
67
|
+
})
|
|
68
|
+
);
|
|
69
|
+
}
|
|
49
70
|
function wireContentItems(root) {
|
|
71
|
+
const activeRows = /* @__PURE__ */ new WeakMap();
|
|
72
|
+
const rove = (grid) => {
|
|
73
|
+
const rows = gridRows(grid);
|
|
74
|
+
const remembered = activeRows.get(grid);
|
|
75
|
+
const stop = remembered && rows.includes(remembered) ? remembered : rows.find((row) => row.getAttribute("aria-selected") === "true") ?? rows[0];
|
|
76
|
+
for (const row of rows) {
|
|
77
|
+
const want = row === stop ? "0" : "-1";
|
|
78
|
+
if (row.getAttribute("tabindex") !== want)
|
|
79
|
+
row.setAttribute("tabindex", want);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
const grids = () => [
|
|
83
|
+
...root.matches(MULTI_GRID_SELECTOR) ? [root] : [],
|
|
84
|
+
...root.querySelectorAll(MULTI_GRID_SELECTOR)
|
|
85
|
+
];
|
|
86
|
+
let roving = false;
|
|
87
|
+
const scheduleRove = () => {
|
|
88
|
+
if (roving) return;
|
|
89
|
+
roving = true;
|
|
90
|
+
globalThis.queueMicrotask(() => {
|
|
91
|
+
roving = false;
|
|
92
|
+
for (const grid of grids()) rove(grid);
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
const View = root.ownerDocument.defaultView;
|
|
96
|
+
const observer = View && "MutationObserver" in View ? new View.MutationObserver(scheduleRove) : null;
|
|
97
|
+
observer?.observe(root, {
|
|
98
|
+
childList: true,
|
|
99
|
+
subtree: true,
|
|
100
|
+
attributes: true,
|
|
101
|
+
attributeFilter: ["tabindex", "aria-selected", "data-disabled"]
|
|
102
|
+
});
|
|
103
|
+
for (const grid of grids()) rove(grid);
|
|
104
|
+
const focusin = (event) => {
|
|
105
|
+
const target = event.target;
|
|
106
|
+
if (!(target instanceof Element)) return;
|
|
107
|
+
const row = target.closest(MULTI_ROW_SELECTOR);
|
|
108
|
+
const grid = row?.closest(MULTI_GRID_SELECTOR);
|
|
109
|
+
if (!row || !grid || !root.contains(grid)) return;
|
|
110
|
+
activeRows.set(grid, row);
|
|
111
|
+
rove(grid);
|
|
112
|
+
};
|
|
50
113
|
let pendingSpace = null;
|
|
51
114
|
const clearSpace = () => {
|
|
52
|
-
pendingSpace?.removeAttribute("data-kui-pressed");
|
|
115
|
+
pendingSpace?.item.removeAttribute("data-kui-pressed");
|
|
53
116
|
pendingSpace = null;
|
|
54
117
|
};
|
|
55
118
|
const keydown = (event) => {
|
|
56
|
-
if (event.defaultPrevented || event.altKey
|
|
57
|
-
return;
|
|
119
|
+
if (event.defaultPrevented || event.altKey) return;
|
|
58
120
|
const item = actionItem(root, event);
|
|
59
121
|
if (!item) return;
|
|
60
|
-
|
|
122
|
+
const commandKey = event.ctrlKey || event.metaKey;
|
|
123
|
+
if (!commandKey && item.dataset.selectionMode === "multiple" && [
|
|
61
124
|
"ArrowDown",
|
|
62
125
|
"ArrowUp",
|
|
63
126
|
"ArrowLeft",
|
|
@@ -67,11 +130,7 @@ function wireContentItems(root) {
|
|
|
67
130
|
].includes(event.key)) {
|
|
68
131
|
const grid = item.closest(MULTI_GRID_SELECTOR);
|
|
69
132
|
if (!grid) return;
|
|
70
|
-
const rows =
|
|
71
|
-
grid.querySelectorAll(
|
|
72
|
-
`${ITEM_SELECTOR}[data-selection-mode="multiple"]:not([data-disabled="true"])`
|
|
73
|
-
)
|
|
74
|
-
).filter((row) => row.closest(MULTI_GRID_SELECTOR) === grid);
|
|
133
|
+
const rows = gridRows(grid);
|
|
75
134
|
const index = rows.indexOf(item);
|
|
76
135
|
if (index < 0) return;
|
|
77
136
|
const isTileGrid = grid.getAttribute("data-component") === "grid";
|
|
@@ -100,34 +159,44 @@ function wireContentItems(root) {
|
|
|
100
159
|
}
|
|
101
160
|
if (event.key === "Enter") {
|
|
102
161
|
event.preventDefault();
|
|
103
|
-
item
|
|
162
|
+
activate(item, event);
|
|
104
163
|
return;
|
|
105
164
|
}
|
|
106
165
|
if (event.key === " " || event.key === "Spacebar") {
|
|
107
166
|
event.preventDefault();
|
|
108
167
|
if (event.repeat) return;
|
|
109
168
|
clearSpace();
|
|
110
|
-
pendingSpace =
|
|
169
|
+
pendingSpace = {
|
|
170
|
+
item,
|
|
171
|
+
modifiers: {
|
|
172
|
+
shiftKey: event.shiftKey,
|
|
173
|
+
ctrlKey: event.ctrlKey,
|
|
174
|
+
metaKey: event.metaKey
|
|
175
|
+
}
|
|
176
|
+
};
|
|
111
177
|
item.setAttribute("data-kui-pressed", "true");
|
|
112
178
|
}
|
|
113
179
|
};
|
|
114
180
|
const keyup = (event) => {
|
|
115
181
|
if (event.key !== " " && event.key !== "Spacebar") return;
|
|
116
|
-
|
|
117
|
-
|
|
182
|
+
if (!pendingSpace) return;
|
|
183
|
+
const { item, modifiers } = pendingSpace;
|
|
118
184
|
event.preventDefault();
|
|
119
185
|
clearSpace();
|
|
120
186
|
if (item === actionItem(root, event) && item.ownerDocument.activeElement === item)
|
|
121
|
-
item
|
|
187
|
+
activate(item, modifiers);
|
|
122
188
|
};
|
|
123
189
|
const focusout = (event) => {
|
|
124
|
-
if (event.target === pendingSpace) clearSpace();
|
|
190
|
+
if (event.target === pendingSpace?.item) clearSpace();
|
|
125
191
|
};
|
|
126
192
|
root.addEventListener("keydown", keydown);
|
|
127
193
|
root.addEventListener("keyup", keyup);
|
|
128
194
|
root.addEventListener("focusout", focusout);
|
|
195
|
+
root.addEventListener("focusin", focusin);
|
|
129
196
|
return () => {
|
|
130
197
|
clearSpace();
|
|
198
|
+
observer?.disconnect();
|
|
199
|
+
root.removeEventListener("focusin", focusin);
|
|
131
200
|
root.removeEventListener("keydown", keydown);
|
|
132
201
|
root.removeEventListener("keyup", keyup);
|
|
133
202
|
root.removeEventListener("focusout", focusout);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/surfaces/content-item/wiring/wire-content-items.ts"],"names":[],"mappings":"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","file":"wire-content-items.js","sourcesContent":["const ITEM_SELECTOR =\n '[data-component=\"content-item\"][data-interactive=\"true\"]';\nconst NESTED_CONTROL_SELECTOR =\n 'button, a[href], input, select, textarea, [contenteditable=\"true\"], [role=\"button\"]';\nconst MULTI_GRID_SELECTOR = '[role=\"grid\"][aria-multiselectable=\"true\"]';\n\nfunction nextTile(\n item: HTMLElement,\n rows: HTMLElement[],\n key: string,\n): HTMLElement | undefined {\n const current = item.getBoundingClientRect();\n const centerX = current.left + current.width / 2;\n const candidates = rows\n .filter((row) => row !== item)\n .map((row) => {\n const rect = row.getBoundingClientRect();\n return { row, x: rect.left + rect.width / 2, y: rect.top };\n });\n const sameLine = (y: number) => Math.abs(y - current.top) < 1;\n const directed = candidates.filter(({ x, y }) => {\n switch (key) {\n case 'ArrowLeft':\n return sameLine(y) && x < centerX;\n case 'ArrowRight':\n return sameLine(y) && x > centerX;\n case 'ArrowUp':\n return y < current.top - 1;\n default:\n return y > current.top + 1;\n }\n });\n directed.sort((a, b) => {\n if (key === 'ArrowLeft') return b.x - a.x;\n if (key === 'ArrowRight') return a.x - b.x;\n const vertical = Math.abs(a.y - current.top) - Math.abs(b.y - current.top);\n return vertical || Math.abs(a.x - centerX) - Math.abs(b.x - centerX);\n });\n return directed[0]?.row;\n}\n\nfunction actionItem(root: HTMLElement, event: Event) {\n const target = event.target;\n if (!(target instanceof Element)) return null;\n const item = target.closest<HTMLElement>(ITEM_SELECTOR);\n if (!item || !root.contains(item) || item.dataset.disabled === 'true')\n return null;\n // Composed events expose native controls inside a custom element's shadow\n // root even though event.target is retargeted to its host here.\n for (const node of event.composedPath()) {\n if (node === item) break;\n if (node instanceof Element && node.matches(NESTED_CONTROL_SELECTOR))\n return null;\n }\n return item;\n}\n\n/** True when a card action originated on the card rather than a nested control. */\nexport function isContentItemActivation(\n event: Event,\n item: HTMLElement,\n): boolean {\n return actionItem(item, event) === item;\n}\n\n/**\n * Give interactive ContentItems native-like Enter/Space activation with one\n * delegated listener pair. Space activates on release and is cancelled if\n * focus moves; the item's own `data-action` still goes through the app's\n * ordinary delegated click handler. Returns a disposer.\n */\nexport function wireContentItems(root: HTMLElement): () => void {\n let pendingSpace: HTMLElement | null = null;\n\n const clearSpace = () => {\n pendingSpace?.removeAttribute('data-kui-pressed');\n pendingSpace = null;\n };\n\n const keydown = (event: KeyboardEvent) => {\n if (\n event.defaultPrevented ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey\n )\n return;\n const item = actionItem(root, event);\n if (!item) return;\n if (\n item.dataset.selectionMode === 'multiple' &&\n [\n 'ArrowDown',\n 'ArrowUp',\n 'ArrowLeft',\n 'ArrowRight',\n 'Home',\n 'End',\n ].includes(event.key)\n ) {\n const grid = item.closest(MULTI_GRID_SELECTOR);\n if (!grid) return;\n const rows = Array.from(\n grid.querySelectorAll<HTMLElement>(\n `${ITEM_SELECTOR}[data-selection-mode=\"multiple\"]:not([data-disabled=\"true\"])`,\n ),\n ).filter((row) => row.closest(MULTI_GRID_SELECTOR) === grid);\n const index = rows.indexOf(item);\n if (index < 0) return;\n const isTileGrid = grid.getAttribute('data-component') === 'grid';\n let next: HTMLElement | undefined;\n switch (event.key) {\n case 'Home':\n next = rows[0];\n break;\n case 'End':\n next = rows[rows.length - 1];\n break;\n case 'ArrowDown':\n case 'ArrowUp':\n next = isTileGrid\n ? nextTile(item, rows, event.key)\n : rows[index + (event.key === 'ArrowDown' ? 1 : -1)];\n break;\n case 'ArrowLeft':\n case 'ArrowRight':\n next = isTileGrid ? nextTile(item, rows, event.key) : undefined;\n break;\n }\n if (next) {\n event.preventDefault();\n next.focus();\n }\n return;\n }\n if (event.key === 'Enter') {\n event.preventDefault();\n item.click();\n return;\n }\n if (event.key === ' ' || event.key === 'Spacebar') {\n event.preventDefault();\n if (event.repeat) return;\n clearSpace();\n pendingSpace = item;\n item.setAttribute('data-kui-pressed', 'true');\n }\n };\n\n const keyup = (event: KeyboardEvent) => {\n if (event.key !== ' ' && event.key !== 'Spacebar') return;\n const item = pendingSpace;\n if (!item) return;\n event.preventDefault();\n clearSpace();\n if (\n item === actionItem(root, event) &&\n item.ownerDocument.activeElement === item\n )\n item.click();\n };\n\n const focusout = (event: FocusEvent) => {\n if (event.target === pendingSpace) clearSpace();\n };\n\n root.addEventListener('keydown', keydown);\n root.addEventListener('keyup', keyup);\n root.addEventListener('focusout', focusout);\n return () => {\n clearSpace();\n root.removeEventListener('keydown', keydown);\n root.removeEventListener('keyup', keyup);\n root.removeEventListener('focusout', focusout);\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/surfaces/content-item/wiring/wire-content-items.ts"],"names":[],"mappings":"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","file":"wire-content-items.js","sourcesContent":["const ITEM_SELECTOR =\n '[data-component=\"content-item\"][data-interactive=\"true\"]';\nconst NESTED_CONTROL_SELECTOR =\n 'button, a[href], input, select, textarea, [contenteditable=\"true\"], [role=\"button\"]';\nconst MULTI_GRID_SELECTOR = '[role=\"grid\"][aria-multiselectable=\"true\"]';\nconst MULTI_ROW_SELECTOR = `${ITEM_SELECTOR}[data-selection-mode=\"multiple\"]`;\n\n/** The enabled selectable rows of one multi-select grid, in order. */\nfunction gridRows(grid: Element): HTMLElement[] {\n return Array.from(\n grid.querySelectorAll<HTMLElement>(\n `${MULTI_ROW_SELECTOR}:not([data-disabled=\"true\"])`,\n ),\n ).filter((row) => row.closest(MULTI_GRID_SELECTOR) === grid);\n}\n\nfunction nextTile(\n item: HTMLElement,\n rows: HTMLElement[],\n key: string,\n): HTMLElement | undefined {\n const current = item.getBoundingClientRect();\n const centerX = current.left + current.width / 2;\n const candidates = rows\n .filter((row) => row !== item)\n .map((row) => {\n const rect = row.getBoundingClientRect();\n return { row, x: rect.left + rect.width / 2, y: rect.top };\n });\n const sameLine = (y: number) => Math.abs(y - current.top) < 1;\n const directed = candidates.filter(({ x, y }) => {\n switch (key) {\n case 'ArrowLeft':\n return sameLine(y) && x < centerX;\n case 'ArrowRight':\n return sameLine(y) && x > centerX;\n case 'ArrowUp':\n return y < current.top - 1;\n default:\n return y > current.top + 1;\n }\n });\n directed.sort((a, b) => {\n if (key === 'ArrowLeft') return b.x - a.x;\n if (key === 'ArrowRight') return a.x - b.x;\n const vertical = Math.abs(a.y - current.top) - Math.abs(b.y - current.top);\n return vertical || Math.abs(a.x - centerX) - Math.abs(b.x - centerX);\n });\n return directed[0]?.row;\n}\n\nfunction actionItem(root: HTMLElement, event: Event) {\n const target = event.target;\n if (!(target instanceof Element)) return null;\n const item = target.closest<HTMLElement>(ITEM_SELECTOR);\n if (!item || !root.contains(item) || item.dataset.disabled === 'true')\n return null;\n // Composed events expose native controls inside a custom element's shadow\n // root even though event.target is retargeted to its host here.\n for (const node of event.composedPath()) {\n if (node === item) break;\n if (node instanceof Element && node.matches(NESTED_CONTROL_SELECTOR))\n return null;\n }\n return item;\n}\n\n/** True when a card action originated on the card rather than a nested control. */\nexport function isContentItemActivation(\n event: Event,\n item: HTMLElement,\n): boolean {\n return actionItem(item, event) === item;\n}\n\ntype ActivationModifiers = Pick<\n KeyboardEvent,\n 'shiftKey' | 'ctrlKey' | 'metaKey'\n>;\n\n/**\n * Activate an item with a click that carries the activating key's modifier\n * state, so one delegated click handler serves pointer and keyboard\n * multi-selection alike (Shift extends a range, Cmd/Ctrl toggles one item).\n */\nfunction activate(item: HTMLElement, modifiers: ActivationModifiers) {\n item.dispatchEvent(\n new MouseEvent('click', {\n bubbles: true,\n cancelable: true,\n composed: true,\n view: item.ownerDocument.defaultView,\n shiftKey: modifiers.shiftKey,\n ctrlKey: modifiers.ctrlKey,\n metaKey: modifiers.metaKey,\n }),\n );\n}\n\n/**\n * Give interactive ContentItems native-like Enter/Space activation with one\n * delegated listener pair. Space activates on release and is cancelled if\n * focus moves; the item's own `data-action` still goes through the app's\n * ordinary delegated click handler. The activation click mirrors the Shift,\n * Ctrl, and Meta state of the activating key (Space uses the state at press),\n * so the click handler can read `shiftKey` / `metaKey` / `ctrlKey` for\n * keyboard range and toggle selection. Alt-modified keys are left to the\n * platform. Returns a disposer.\n */\nexport function wireContentItems(root: HTMLElement): () => void {\n // Roving tabindex: each multi-select grid is one Tab stop, on the last\n // focused row, else the first selected, else the first enabled row.\n const activeRows = new WeakMap<Element, HTMLElement>();\n const rove = (grid: Element) => {\n const rows = gridRows(grid);\n const remembered = activeRows.get(grid);\n const stop =\n remembered && rows.includes(remembered)\n ? remembered\n : (rows.find((row) => row.getAttribute('aria-selected') === 'true') ??\n rows[0]);\n for (const row of rows) {\n const want = row === stop ? '0' : '-1';\n if (row.getAttribute('tabindex') !== want)\n row.setAttribute('tabindex', want);\n }\n };\n const grids = () =>\n [\n ...(root.matches(MULTI_GRID_SELECTOR) ? [root] : []),\n ...root.querySelectorAll(MULTI_GRID_SELECTOR),\n ] as Element[];\n // A re-render resets every row's tabindex to its template value, so the\n // roving stop is restored after each change (deduplicated per task).\n let roving = false;\n const scheduleRove = () => {\n if (roving) return;\n roving = true;\n globalThis.queueMicrotask(() => {\n roving = false;\n for (const grid of grids()) rove(grid);\n });\n };\n const View = root.ownerDocument.defaultView;\n const observer =\n View && 'MutationObserver' in View\n ? new View.MutationObserver(scheduleRove)\n : null;\n observer?.observe(root, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['tabindex', 'aria-selected', 'data-disabled'],\n });\n for (const grid of grids()) rove(grid);\n\n const focusin = (event: FocusEvent) => {\n const target = event.target;\n if (!(target instanceof Element)) return;\n const row = target.closest<HTMLElement>(MULTI_ROW_SELECTOR);\n const grid = row?.closest(MULTI_GRID_SELECTOR);\n if (!row || !grid || !root.contains(grid)) return;\n activeRows.set(grid, row);\n rove(grid);\n };\n\n let pendingSpace: {\n item: HTMLElement;\n modifiers: ActivationModifiers;\n } | null = null;\n\n const clearSpace = () => {\n pendingSpace?.item.removeAttribute('data-kui-pressed');\n pendingSpace = null;\n };\n\n const keydown = (event: KeyboardEvent) => {\n if (event.defaultPrevented || event.altKey) return;\n const item = actionItem(root, event);\n if (!item) return;\n const commandKey = event.ctrlKey || event.metaKey;\n if (\n !commandKey &&\n item.dataset.selectionMode === 'multiple' &&\n [\n 'ArrowDown',\n 'ArrowUp',\n 'ArrowLeft',\n 'ArrowRight',\n 'Home',\n 'End',\n ].includes(event.key)\n ) {\n const grid = item.closest(MULTI_GRID_SELECTOR);\n if (!grid) return;\n const rows = gridRows(grid);\n const index = rows.indexOf(item);\n if (index < 0) return;\n const isTileGrid = grid.getAttribute('data-component') === 'grid';\n let next: HTMLElement | undefined;\n switch (event.key) {\n case 'Home':\n next = rows[0];\n break;\n case 'End':\n next = rows[rows.length - 1];\n break;\n case 'ArrowDown':\n case 'ArrowUp':\n next = isTileGrid\n ? nextTile(item, rows, event.key)\n : rows[index + (event.key === 'ArrowDown' ? 1 : -1)];\n break;\n case 'ArrowLeft':\n case 'ArrowRight':\n next = isTileGrid ? nextTile(item, rows, event.key) : undefined;\n break;\n }\n if (next) {\n event.preventDefault();\n next.focus();\n }\n return;\n }\n if (event.key === 'Enter') {\n event.preventDefault();\n activate(item, event);\n return;\n }\n if (event.key === ' ' || event.key === 'Spacebar') {\n event.preventDefault();\n if (event.repeat) return;\n clearSpace();\n pendingSpace = {\n item,\n modifiers: {\n shiftKey: event.shiftKey,\n ctrlKey: event.ctrlKey,\n metaKey: event.metaKey,\n },\n };\n item.setAttribute('data-kui-pressed', 'true');\n }\n };\n\n const keyup = (event: KeyboardEvent) => {\n if (event.key !== ' ' && event.key !== 'Spacebar') return;\n if (!pendingSpace) return;\n const { item, modifiers } = pendingSpace;\n event.preventDefault();\n clearSpace();\n if (\n item === actionItem(root, event) &&\n item.ownerDocument.activeElement === item\n )\n activate(item, modifiers);\n };\n\n const focusout = (event: FocusEvent) => {\n if (event.target === pendingSpace?.item) clearSpace();\n };\n\n root.addEventListener('keydown', keydown);\n root.addEventListener('keyup', keyup);\n root.addEventListener('focusout', focusout);\n root.addEventListener('focusin', focusin);\n return () => {\n clearSpace();\n observer?.disconnect();\n root.removeEventListener('focusin', focusin);\n root.removeEventListener('keydown', keydown);\n root.removeEventListener('keyup', keyup);\n root.removeEventListener('focusout', focusout);\n };\n}\n"]}
|
|
@@ -15,8 +15,9 @@ interface WireFilePickersOptions {
|
|
|
15
15
|
declare function fileMatchesAccept(file: File, accept: string): boolean;
|
|
16
16
|
/**
|
|
17
17
|
* Report files chosen through any `FilePickerTrigger` or `FileDropZone` below
|
|
18
|
-
* root, or dropped on a `FileDropZone
|
|
19
|
-
*
|
|
18
|
+
* root, or dropped on a `FileDropZone` (or anywhere in the enclosing element
|
|
19
|
+
* its `dropScope` names), and mark a zone `data-dragging` while files are
|
|
20
|
+
* dragged over it or its scope. Dropped files are filtered by the input's
|
|
20
21
|
* `accept` (and to one when it is not `multiple`); a disabled picker ignores
|
|
21
22
|
* drops. The input is reset after each report, so choosing the same file again
|
|
22
23
|
* reports again. Dispose with the owning application.
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
type Root = HTMLElement | Document;
|
|
2
2
|
/**
|
|
3
|
-
* Enter-to-send for every `
|
|
3
|
+
* Enter-to-send for every `MessageComposer` rendered with `submitOnEnter` below
|
|
4
4
|
* root. In its field, Enter (alone or with Cmd or Ctrl) activates the
|
|
5
5
|
* composer's first trailing action, so a keyboard send runs the same
|
|
6
6
|
* delegated handler as a click. Shift+Enter and Alt+Enter insert a newline.
|
|
7
7
|
* Nothing is sent, and no newline is inserted, when the message is empty or
|
|
8
8
|
* whitespace-only, the key is auto-repeating, or the first action is
|
|
9
|
-
* disabled, loading
|
|
9
|
+
* disabled, loading (a busy `Button` reports `aria-busy`), or
|
|
10
|
+
* `aria-disabled`. An Enter that commits an IME
|
|
10
11
|
* composition (`isComposing`, keyCode 229, or between `compositionstart` and
|
|
11
12
|
* `compositionend`) is left to the input method. Dispose with the owning
|
|
12
13
|
* application.
|
|
13
14
|
*/
|
|
14
|
-
declare function
|
|
15
|
+
declare function wireMessageComposers(root: Root): () => void;
|
|
15
16
|
|
|
16
|
-
export {
|
|
17
|
+
export { wireMessageComposers };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"wire-message-composers.js"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Signal } from 'kerfjs';
|
|
2
|
+
|
|
3
|
+
/** The app-owned open state of a Pane's `overlay` compact chrome. */
|
|
4
|
+
interface WirePaneChromeOptions {
|
|
5
|
+
/** The signal the Pane renders as `compactChromeOpen.header`. */
|
|
6
|
+
header?: Signal<boolean>;
|
|
7
|
+
/** The signal the Pane renders as `compactChromeOpen.footer`. */
|
|
8
|
+
footer?: Signal<boolean>;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Make a Pane's open `overlay` compact chrome transient, like a Workbench's
|
|
12
|
+
* overlay rail: Escape, or a press that starts and ends outside the open
|
|
13
|
+
* chrome, sets its signal back to false, and focus left inside the closed
|
|
14
|
+
* chrome returns to the control that had focus when it opened. `root` holds
|
|
15
|
+
* the Pane (its NavStack, dialog, or Workbench); the app still opens the
|
|
16
|
+
* chrome from its own control, and a press on that control toggles as usual
|
|
17
|
+
* because the dismissal is decided at the click. Returns a disposer.
|
|
18
|
+
*/
|
|
19
|
+
declare function wirePaneChrome(root: HTMLElement, { header, footer }: WirePaneChromeOptions): () => void;
|
|
20
|
+
|
|
21
|
+
export { type WirePaneChromeOptions, wirePaneChrome };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { effect } from 'kerfjs';
|
|
2
|
+
|
|
3
|
+
// src/components/layout/pane/wiring/wire-pane-chrome.ts
|
|
4
|
+
function wirePaneChrome(root, { header, footer }) {
|
|
5
|
+
const doc = root.ownerDocument;
|
|
6
|
+
const slots = [
|
|
7
|
+
["header", header],
|
|
8
|
+
["footer", footer]
|
|
9
|
+
].filter((entry) => entry[1] !== void 0);
|
|
10
|
+
const elementOf = (slot) => root.querySelector(
|
|
11
|
+
`.kui-pane[data-compact-${slot}="overlay"] > .kui-pane__${slot}`
|
|
12
|
+
);
|
|
13
|
+
const open = () => slots.filter(([, state]) => state.peek());
|
|
14
|
+
const openers = /* @__PURE__ */ new Map();
|
|
15
|
+
const stops = slots.map(([slot, state]) => {
|
|
16
|
+
let was = state.peek();
|
|
17
|
+
return effect(() => {
|
|
18
|
+
const now = state.value;
|
|
19
|
+
if (now && !was) openers.set(slot, doc.activeElement);
|
|
20
|
+
if (!now && was) {
|
|
21
|
+
const element = elementOf(slot);
|
|
22
|
+
const opener = openers.get(slot);
|
|
23
|
+
if (element?.contains(doc.activeElement) && opener instanceof HTMLElement)
|
|
24
|
+
opener.focus({ preventScroll: true });
|
|
25
|
+
openers.delete(slot);
|
|
26
|
+
}
|
|
27
|
+
was = now;
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
const onKeydown = (event) => {
|
|
31
|
+
if (event.key !== "Escape" || event.defaultPrevented) return;
|
|
32
|
+
const shown = open();
|
|
33
|
+
if (shown.length === 0) return;
|
|
34
|
+
event.preventDefault();
|
|
35
|
+
const [, state] = shown.find(([slot]) => elementOf(slot)?.contains(doc.activeElement)) ?? shown[shown.length - 1];
|
|
36
|
+
state.value = false;
|
|
37
|
+
};
|
|
38
|
+
let pressed = [];
|
|
39
|
+
const outside = (slot, path) => {
|
|
40
|
+
const element = elementOf(slot);
|
|
41
|
+
return !element || !path.includes(element);
|
|
42
|
+
};
|
|
43
|
+
const onPointerdown = (event) => {
|
|
44
|
+
const path = event.composedPath();
|
|
45
|
+
pressed = open().map(([slot]) => slot).filter((slot) => outside(slot, path));
|
|
46
|
+
};
|
|
47
|
+
const onClick = (event) => {
|
|
48
|
+
const candidates = pressed;
|
|
49
|
+
pressed = [];
|
|
50
|
+
const path = event.composedPath();
|
|
51
|
+
for (const [slot, state] of open())
|
|
52
|
+
if (candidates.includes(slot) && outside(slot, path)) state.value = false;
|
|
53
|
+
};
|
|
54
|
+
doc.addEventListener("keydown", onKeydown);
|
|
55
|
+
doc.addEventListener("pointerdown", onPointerdown, true);
|
|
56
|
+
doc.addEventListener("click", onClick);
|
|
57
|
+
return () => {
|
|
58
|
+
for (const stop of stops) stop();
|
|
59
|
+
doc.removeEventListener("keydown", onKeydown);
|
|
60
|
+
doc.removeEventListener("pointerdown", onPointerdown, true);
|
|
61
|
+
doc.removeEventListener("click", onClick);
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export { wirePaneChrome };
|
|
66
|
+
|
|
67
|
+
//# sourceMappingURL=wire-pane-chrome.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/layout/pane/wiring/wire-pane-chrome.ts"],"names":[],"mappings":"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","file":"wire-pane-chrome.js","sourcesContent":["import { effect, type Signal } from 'kerfjs';\n\n/** The app-owned open state of a Pane's `overlay` compact chrome. */\nexport interface WirePaneChromeOptions {\n /** The signal the Pane renders as `compactChromeOpen.header`. */\n header?: Signal<boolean>;\n /** The signal the Pane renders as `compactChromeOpen.footer`. */\n footer?: Signal<boolean>;\n}\n\ntype Slot = 'header' | 'footer';\n\n/**\n * Make a Pane's open `overlay` compact chrome transient, like a Workbench's\n * overlay rail: Escape, or a press that starts and ends outside the open\n * chrome, sets its signal back to false, and focus left inside the closed\n * chrome returns to the control that had focus when it opened. `root` holds\n * the Pane (its NavStack, dialog, or Workbench); the app still opens the\n * chrome from its own control, and a press on that control toggles as usual\n * because the dismissal is decided at the click. Returns a disposer.\n */\nexport function wirePaneChrome(\n root: HTMLElement,\n { header, footer }: WirePaneChromeOptions,\n): () => void {\n const doc = root.ownerDocument;\n const slots = (\n [\n ['header', header],\n ['footer', footer],\n ] as const\n ).filter((entry): entry is [Slot, Signal<boolean>] => entry[1] !== undefined);\n const elementOf = (slot: Slot) =>\n root.querySelector<HTMLElement>(\n `.kui-pane[data-compact-${slot}=\"overlay\"] > .kui-pane__${slot}`,\n );\n const open = () => slots.filter(([, state]) => state.peek());\n const openers = new Map<Slot, Element | null>();\n\n const stops = slots.map(([slot, state]) => {\n let was = state.peek();\n return effect(() => {\n const now = state.value;\n if (now && !was) openers.set(slot, doc.activeElement);\n if (!now && was) {\n // Focus stranded in the closed chrome goes back to its opener.\n const element = elementOf(slot);\n const opener = openers.get(slot);\n if (\n element?.contains(doc.activeElement) &&\n opener instanceof HTMLElement\n )\n opener.focus({ preventScroll: true });\n openers.delete(slot);\n }\n was = now;\n });\n });\n\n const onKeydown = (event: KeyboardEvent) => {\n if (event.key !== 'Escape' || event.defaultPrevented) return;\n const shown = open();\n if (shown.length === 0) return;\n event.preventDefault();\n // The chrome holding focus closes first; otherwise the last one opened.\n const [, state] =\n shown.find(([slot]) => elementOf(slot)?.contains(doc.activeElement)) ??\n shown[shown.length - 1]!;\n state.value = false;\n };\n\n let pressed: Slot[] = [];\n const outside = (slot: Slot, path: EventTarget[]) => {\n const element = elementOf(slot);\n return !element || !path.includes(element);\n };\n const onPointerdown = (event: PointerEvent) => {\n const path = event.composedPath();\n pressed = open()\n .map(([slot]) => slot)\n .filter((slot) => outside(slot, path));\n };\n const onClick = (event: MouseEvent) => {\n const candidates = pressed;\n pressed = [];\n const path = event.composedPath();\n for (const [slot, state] of open())\n if (candidates.includes(slot) && outside(slot, path)) state.value = false;\n };\n\n doc.addEventListener('keydown', onKeydown);\n doc.addEventListener('pointerdown', onPointerdown, true);\n doc.addEventListener('click', onClick);\n return () => {\n for (const stop of stops) stop();\n doc.removeEventListener('keydown', onKeydown);\n doc.removeEventListener('pointerdown', onPointerdown, true);\n doc.removeEventListener('click', onClick);\n };\n}\n"]}
|