admin-ui-starter-kit 0.1.2 → 0.1.4
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/.agents/skills/admin-ui-consumer-migration/SKILL.md +135 -0
- package/.agents/skills/component-library-rules/SKILL.md +13 -2
- package/.agents/skills/component-library-rules/references/components/INDEX.json +1 -0
- package/.agents/skills/component-library-rules/references/components/INDEX.md +1 -0
- package/.agents/skills/component-library-rules/references/components/base__buttons.md +18 -6
- package/.agents/skills/component-library-rules/references/components/base__combobox.md +1 -1
- package/.agents/skills/component-library-rules/references/components/base__event-calendar.md +1 -1
- package/.agents/skills/component-library-rules/references/components/base__forms.md +10 -7
- package/.agents/skills/component-library-rules/references/components/base__item.md +1 -1
- package/.agents/skills/component-library-rules/references/components/base__map.md +7 -7
- package/.agents/skills/component-library-rules/references/components/base__navigation.md +8 -8
- package/.agents/skills/component-library-rules/references/components/base__table.md +2 -2
- package/.agents/skills/component-library-rules/references/components/base__typography.md +6 -4
- package/.agents/skills/component-library-rules/references/components/composed__ai-elements.md +4 -4
- package/.agents/skills/component-library-rules/references/components/composed__api-key-list.md +4 -4
- package/.agents/skills/component-library-rules/references/components/composed__commerce-extras.md +107 -113
- package/.agents/skills/component-library-rules/references/components/composed__commerce.md +49 -48
- package/.agents/skills/component-library-rules/references/components/composed__navigation.md +6 -2
- package/.agents/skills/component-library-rules/references/components/composed__timelines.md +21 -7
- package/.agents/skills/component-library-rules/references/components/features__comments.md +12 -4
- package/.agents/skills/component-library-rules/references/components/features__enhanced-activities.md +4 -2
- package/.agents/skills/component-library-rules/references/components/features__event-log.md +6 -2
- package/.agents/skills/component-library-rules/references/components/features__overlays.md +8 -6
- package/.agents/skills/component-library-rules/references/components/layout__layout-app-shell.md +552 -0
- package/.agents/skills/component-library-rules/references/components/layout__layout-header.md +2 -2
- package/.agents/skills/component-library-rules/references/components/layout__layout-sidebar.md +2 -2
- package/.agents/skills/component-library-rules/references/components/layout__layout-users.md +7 -7
- package/.agents/skills/component-library-rules/references/components/ui__toggles-group.md +7 -7
- package/.agents/skills/component-library-rules/references/components/ui__toggles.md +1 -1
- package/AGENTS.md +6 -4
- package/CHANGELOG.md +27 -1
- package/COMPONENT_SELECTION.md +115 -0
- package/INTEGRATION.md +10 -0
- package/MIGRATION.md +239 -0
- package/PUBLISHING.md +6 -1
- package/README.md +31 -8
- package/dist/_shared/accordion-BnxO7Is4.js +130 -0
- package/dist/_shared/accordion-BnxO7Is4.js.map +1 -0
- package/dist/_shared/accordion-RIN0MjPz.cjs +2 -0
- package/dist/_shared/accordion-RIN0MjPz.cjs.map +1 -0
- package/dist/_shared/action-menu-IIO9KtJ2.js +96 -0
- package/dist/_shared/action-menu-IIO9KtJ2.js.map +1 -0
- package/dist/_shared/action-menu-RAyg3cvM.cjs +2 -0
- package/dist/_shared/action-menu-RAyg3cvM.cjs.map +1 -0
- package/dist/_shared/ai-artifact--MqIfP-8.js +1068 -0
- package/dist/_shared/ai-artifact--MqIfP-8.js.map +1 -0
- package/dist/_shared/ai-artifact-D1dBeEz1.cjs +3 -0
- package/dist/_shared/ai-artifact-D1dBeEz1.cjs.map +1 -0
- package/dist/_shared/alert-D3gRd7RK.cjs +2 -0
- package/dist/_shared/alert-D3gRd7RK.cjs.map +1 -0
- package/dist/_shared/alert-DQ-tV8b-.js +48 -0
- package/dist/_shared/alert-DQ-tV8b-.js.map +1 -0
- package/dist/_shared/app-shell-C4d7kCCd.cjs +2 -0
- package/dist/_shared/app-shell-C4d7kCCd.cjs.map +1 -0
- package/dist/_shared/app-shell-CKxcpPTc.js +94 -0
- package/dist/_shared/app-shell-CKxcpPTc.js.map +1 -0
- package/dist/_shared/avatar-0spfQEHG.cjs +2 -0
- package/dist/_shared/avatar-0spfQEHG.cjs.map +1 -0
- package/dist/_shared/avatar-CBi4LGxy.js +52 -0
- package/dist/_shared/avatar-CBi4LGxy.js.map +1 -0
- package/dist/_shared/badge-BK5VvEgg.js +108 -0
- package/dist/_shared/badge-BK5VvEgg.js.map +1 -0
- package/dist/_shared/badge-kS_XtN-z.cjs +2 -0
- package/dist/_shared/badge-kS_XtN-z.cjs.map +1 -0
- package/dist/_shared/breadcrumbs-Dqp2qAmo.cjs +2 -0
- package/dist/_shared/breadcrumbs-Dqp2qAmo.cjs.map +1 -0
- package/dist/_shared/breadcrumbs-bJ-J0oCd.js +111 -0
- package/dist/_shared/breadcrumbs-bJ-J0oCd.js.map +1 -0
- package/dist/_shared/button-683R5quQ.js +46 -0
- package/dist/_shared/button-683R5quQ.js.map +1 -0
- package/dist/_shared/button-CjZrRLzR.cjs +2 -0
- package/dist/_shared/button-CjZrRLzR.cjs.map +1 -0
- package/dist/_shared/button-LZWDn-aU.cjs +2 -0
- package/dist/_shared/button-LZWDn-aU.cjs.map +1 -0
- package/dist/_shared/button-cnkCF8q8.js +177 -0
- package/dist/_shared/button-cnkCF8q8.js.map +1 -0
- package/dist/_shared/buttons-DHV2eZAf.cjs +2 -0
- package/dist/_shared/buttons-DHV2eZAf.cjs.map +1 -0
- package/dist/_shared/buttons-ehfMSkwP.js +143 -0
- package/dist/_shared/buttons-ehfMSkwP.js.map +1 -0
- package/dist/_shared/card-radio-group-Bf03M6c5.js +158 -0
- package/dist/_shared/card-radio-group-Bf03M6c5.js.map +1 -0
- package/dist/_shared/card-radio-group-SqPUL0Je.cjs +2 -0
- package/dist/_shared/card-radio-group-SqPUL0Je.cjs.map +1 -0
- package/dist/_shared/chunk-CMqjfN_6.cjs +1 -0
- package/dist/_shared/combobox-Cvs70ic4.js +808 -0
- package/dist/_shared/combobox-Cvs70ic4.js.map +1 -0
- package/dist/_shared/combobox-Dos9YWjk.cjs +2 -0
- package/dist/_shared/combobox-Dos9YWjk.cjs.map +1 -0
- package/dist/_shared/command-Bxe_FmGD.cjs +2 -0
- package/dist/_shared/command-Bxe_FmGD.cjs.map +1 -0
- package/dist/_shared/command-CAI-BCSR.js +123 -0
- package/dist/_shared/command-CAI-BCSR.js.map +1 -0
- package/dist/_shared/command-DRIySU26.cjs +2 -0
- package/dist/_shared/command-DRIySU26.cjs.map +1 -0
- package/dist/_shared/command-DwRnPIGs.js +39 -0
- package/dist/_shared/command-DwRnPIGs.js.map +1 -0
- package/dist/_shared/comments-DD2aeZVz.js +946 -0
- package/dist/_shared/comments-DD2aeZVz.js.map +1 -0
- package/dist/_shared/comments-DzwU4sNE.cjs +2 -0
- package/dist/_shared/comments-DzwU4sNE.cjs.map +1 -0
- package/dist/_shared/containers-D7oZE4XI.cjs +2 -0
- package/dist/_shared/containers-D7oZE4XI.cjs.map +1 -0
- package/dist/_shared/containers-anBivbL9.js +19 -0
- package/dist/_shared/containers-anBivbL9.js.map +1 -0
- package/dist/_shared/content-container-CVUJCLhn.cjs +2 -0
- package/dist/_shared/content-container-CVUJCLhn.cjs.map +1 -0
- package/dist/_shared/content-container-Dv8XsAw4.js +33 -0
- package/dist/_shared/content-container-Dv8XsAw4.js.map +1 -0
- package/dist/_shared/copyable-D7WhgEzJ.js +38 -0
- package/dist/_shared/copyable-D7WhgEzJ.js.map +1 -0
- package/dist/_shared/copyable-DDjT505-.cjs +2 -0
- package/dist/_shared/copyable-DDjT505-.cjs.map +1 -0
- package/dist/_shared/date-picker-3G3C-sIq.cjs +2 -0
- package/dist/_shared/date-picker-3G3C-sIq.cjs.map +1 -0
- package/dist/_shared/date-picker-7yuMHPYs.js +1362 -0
- package/dist/_shared/date-picker-7yuMHPYs.js.map +1 -0
- package/dist/_shared/date-pickers-B_VUgjvY.cjs +2 -0
- package/dist/_shared/date-pickers-B_VUgjvY.cjs.map +1 -0
- package/dist/_shared/date-pickers-DZXi0di0.js +330 -0
- package/dist/_shared/date-pickers-DZXi0di0.js.map +1 -0
- package/dist/_shared/dialog-A95-614f.js +101 -0
- package/dist/_shared/dialog-A95-614f.js.map +1 -0
- package/dist/_shared/dialog-ivDByBmO.cjs +2 -0
- package/dist/_shared/dialog-ivDByBmO.cjs.map +1 -0
- package/dist/_shared/display-Cuj4td-V.js +1237 -0
- package/dist/_shared/display-Cuj4td-V.js.map +1 -0
- package/dist/_shared/display-D2q93jiS.cjs +8 -0
- package/dist/_shared/display-D2q93jiS.cjs.map +1 -0
- package/dist/_shared/dropdown-menu-CHQzQWUK.cjs +2 -0
- package/dist/_shared/dropdown-menu-CHQzQWUK.cjs.map +1 -0
- package/dist/_shared/dropdown-menu-CoWmrjYX.js +147 -0
- package/dist/_shared/dropdown-menu-CoWmrjYX.js.map +1 -0
- package/dist/_shared/form-field-BNuCBym1.js +319 -0
- package/dist/_shared/form-field-BNuCBym1.js.map +1 -0
- package/dist/_shared/form-field-C4fQYsqv.cjs +2 -0
- package/dist/_shared/form-field-C4fQYsqv.cjs.map +1 -0
- package/dist/_shared/form-sizing-D74IS9KG.js +21 -0
- package/dist/_shared/form-sizing-D74IS9KG.js.map +1 -0
- package/dist/_shared/form-sizing-aVwVuF-w.cjs +2 -0
- package/dist/_shared/form-sizing-aVwVuF-w.cjs.map +1 -0
- package/dist/_shared/format-BTtJC6oz.cjs +2 -0
- package/dist/_shared/format-BTtJC6oz.cjs.map +1 -0
- package/dist/_shared/format-BX3QestD.js +48 -0
- package/dist/_shared/format-BX3QestD.js.map +1 -0
- package/dist/_shared/forms-BV4fHeRx.cjs +2 -0
- package/dist/_shared/forms-BV4fHeRx.cjs.map +1 -0
- package/dist/_shared/forms-DjAdYxme.js +3378 -0
- package/dist/_shared/forms-DjAdYxme.js.map +1 -0
- package/dist/_shared/header-D4Oz-mCv.cjs +2 -0
- package/dist/_shared/header-D4Oz-mCv.cjs.map +1 -0
- package/dist/_shared/header-X5DZ8vmO.js +360 -0
- package/dist/_shared/header-X5DZ8vmO.js.map +1 -0
- package/dist/_shared/heading-C7mNh03X.cjs +2 -0
- package/dist/_shared/heading-C7mNh03X.cjs.map +1 -0
- package/dist/_shared/heading-CrNpYcUr.js +39 -0
- package/dist/_shared/heading-CrNpYcUr.js.map +1 -0
- package/dist/_shared/hooks-CKXPg30g.js +118 -0
- package/dist/_shared/hooks-CKXPg30g.js.map +1 -0
- package/dist/_shared/hooks-CTiEImZp.cjs +2 -0
- package/dist/_shared/hooks-CTiEImZp.cjs.map +1 -0
- package/dist/_shared/icon-badge-BAWl1oOe.cjs +2 -0
- package/dist/_shared/icon-badge-BAWl1oOe.cjs.map +1 -0
- package/dist/_shared/icon-badge-zTBVtgt9.js +52 -0
- package/dist/_shared/icon-badge-zTBVtgt9.js.map +1 -0
- package/dist/_shared/input-Cw2uICc1.cjs +2 -0
- package/dist/_shared/input-Cw2uICc1.cjs.map +1 -0
- package/dist/_shared/input-D43_IMWW.cjs +2 -0
- package/dist/_shared/input-D43_IMWW.cjs.map +1 -0
- package/dist/_shared/input-DJo8d1Rr.js +182 -0
- package/dist/_shared/input-DJo8d1Rr.js.map +1 -0
- package/dist/_shared/input-R8c90tNY.js +17 -0
- package/dist/_shared/input-R8c90tNY.js.map +1 -0
- package/dist/_shared/item-BxlP5TO3.js +224 -0
- package/dist/_shared/item-BxlP5TO3.js.map +1 -0
- package/dist/_shared/item-X18HIqR7.cjs +2 -0
- package/dist/_shared/item-X18HIqR7.cjs.map +1 -0
- package/dist/_shared/mentions-DE9aDOMu.cjs +2 -0
- package/dist/_shared/mentions-DE9aDOMu.cjs.map +1 -0
- package/dist/_shared/mentions-DjjYmMLc.js +493 -0
- package/dist/_shared/mentions-DjjYmMLc.js.map +1 -0
- package/dist/_shared/metadata-C5MSNo7y.js +236 -0
- package/dist/_shared/metadata-C5MSNo7y.js.map +1 -0
- package/dist/_shared/metadata-Cw3Kj2Ug.cjs +2 -0
- package/dist/_shared/metadata-Cw3Kj2Ug.cjs.map +1 -0
- package/dist/_shared/money-display-B7AKxxNt.js +198 -0
- package/dist/_shared/money-display-B7AKxxNt.js.map +1 -0
- package/dist/_shared/money-display-E22wbM21.cjs +2 -0
- package/dist/_shared/money-display-E22wbM21.cjs.map +1 -0
- package/dist/_shared/navigation-B9VAXqLL.cjs +2 -0
- package/dist/_shared/navigation-B9VAXqLL.cjs.map +1 -0
- package/dist/_shared/navigation-CxoJVgfo.js +420 -0
- package/dist/_shared/navigation-CxoJVgfo.js.map +1 -0
- package/dist/_shared/overlays-C-T8RnJz.cjs +2 -0
- package/dist/_shared/overlays-C-T8RnJz.cjs.map +1 -0
- package/dist/_shared/overlays-DfRsQzD3.js +633 -0
- package/dist/_shared/overlays-DfRsQzD3.js.map +1 -0
- package/dist/_shared/page-C4jEULwi.js +263 -0
- package/dist/_shared/page-C4jEULwi.js.map +1 -0
- package/dist/_shared/page-DX3pA_tJ.cjs +2 -0
- package/dist/_shared/page-DX3pA_tJ.cjs.map +1 -0
- package/dist/_shared/popover-CaHvG8Vj.cjs +2 -0
- package/dist/_shared/popover-CaHvG8Vj.cjs.map +1 -0
- package/dist/_shared/popover-L37RqoRO.js +83 -0
- package/dist/_shared/popover-L37RqoRO.js.map +1 -0
- package/dist/_shared/popover-menu-CVAr985u.js +95 -0
- package/dist/_shared/popover-menu-CVAr985u.js.map +1 -0
- package/dist/_shared/popover-menu-Cq-LnAMh.cjs +2 -0
- package/dist/_shared/popover-menu-Cq-LnAMh.cjs.map +1 -0
- package/dist/_shared/rich-text-editor-C3gVBm-v.cjs +2 -0
- package/dist/_shared/rich-text-editor-C3gVBm-v.cjs.map +1 -0
- package/dist/_shared/rich-text-editor-Cylb-lkv.js +616 -0
- package/dist/_shared/rich-text-editor-Cylb-lkv.js.map +1 -0
- package/dist/_shared/scroll-area-BH5CPQh4.js +41 -0
- package/dist/_shared/scroll-area-BH5CPQh4.js.map +1 -0
- package/dist/_shared/scroll-area-u46BOVcC.cjs +2 -0
- package/dist/_shared/scroll-area-u46BOVcC.cjs.map +1 -0
- package/dist/_shared/select-BwUUXpsb.js +85 -0
- package/dist/_shared/select-BwUUXpsb.js.map +1 -0
- package/dist/_shared/select-CG5Yq-6A.cjs +2 -0
- package/dist/_shared/select-CG5Yq-6A.cjs.map +1 -0
- package/dist/_shared/separator-B8FBp-7E.js +16 -0
- package/dist/_shared/separator-B8FBp-7E.js.map +1 -0
- package/dist/_shared/separator-q42IlFFA.cjs +2 -0
- package/dist/_shared/separator-q42IlFFA.cjs.map +1 -0
- package/dist/_shared/sheet-BKEfwhCn.js +100 -0
- package/dist/_shared/sheet-BKEfwhCn.js.map +1 -0
- package/dist/_shared/sheet-D4yWgkwC.cjs +2 -0
- package/dist/_shared/sheet-D4yWgkwC.cjs.map +1 -0
- package/dist/_shared/sidebar-BeWLjIRR.js +537 -0
- package/dist/_shared/sidebar-BeWLjIRR.js.map +1 -0
- package/dist/_shared/sidebar-Bl_KRk-S.cjs +2 -0
- package/dist/_shared/sidebar-Bl_KRk-S.cjs.map +1 -0
- package/dist/_shared/sidebar-DzzdJ2xk.cjs +2 -0
- package/dist/_shared/sidebar-DzzdJ2xk.cjs.map +1 -0
- package/dist/_shared/sidebar-ux-yk-Ph.js +382 -0
- package/dist/_shared/sidebar-ux-yk-Ph.js.map +1 -0
- package/dist/_shared/skeleton-CGQMeno1.js +14 -0
- package/dist/_shared/skeleton-CGQMeno1.js.map +1 -0
- package/dist/_shared/skeleton-D1c5OHXa.cjs +2 -0
- package/dist/_shared/skeleton-D1c5OHXa.cjs.map +1 -0
- package/dist/_shared/slot-C5EJicOc.js +18 -0
- package/dist/_shared/slot-C5EJicOc.js.map +1 -0
- package/dist/_shared/slot-D-Rwlrz2.cjs +2 -0
- package/dist/_shared/slot-D-Rwlrz2.cjs.map +1 -0
- package/dist/_shared/smart-card-DL7esK_y.cjs +2 -0
- package/dist/_shared/smart-card-DL7esK_y.cjs.map +1 -0
- package/dist/_shared/smart-card-eBfUvQ9r.js +360 -0
- package/dist/_shared/smart-card-eBfUvQ9r.js.map +1 -0
- package/dist/_shared/spinner-Bvjs1ybK.cjs +2 -0
- package/dist/_shared/spinner-Bvjs1ybK.cjs.map +1 -0
- package/dist/_shared/spinner-XcfVYbbp.js +67 -0
- package/dist/_shared/spinner-XcfVYbbp.js.map +1 -0
- package/dist/_shared/switch-BBP3u1z5.js +55 -0
- package/dist/_shared/switch-BBP3u1z5.js.map +1 -0
- package/dist/_shared/switch-zFZhhOEP.cjs +2 -0
- package/dist/_shared/switch-zFZhhOEP.cjs.map +1 -0
- package/dist/_shared/text-DzKt9cyb.cjs +2 -0
- package/dist/_shared/text-DzKt9cyb.cjs.map +1 -0
- package/dist/_shared/text-qsEg5GdP.js +74 -0
- package/dist/_shared/text-qsEg5GdP.js.map +1 -0
- package/dist/_shared/textarea-BAKapsLQ.cjs +2 -0
- package/dist/_shared/textarea-BAKapsLQ.cjs.map +1 -0
- package/dist/_shared/textarea-Bfv1KxBm.js +119 -0
- package/dist/_shared/textarea-Bfv1KxBm.js.map +1 -0
- package/dist/_shared/tooltip-CLr_sPX8.js +49 -0
- package/dist/_shared/tooltip-CLr_sPX8.js.map +1 -0
- package/dist/_shared/tooltip-mvxZV_Lu.cjs +2 -0
- package/dist/_shared/tooltip-mvxZV_Lu.cjs.map +1 -0
- package/dist/_shared/typography-4CSyoCj9.js +102 -0
- package/dist/_shared/typography-4CSyoCj9.js.map +1 -0
- package/dist/_shared/typography-DKn7P4wX.cjs +2 -0
- package/dist/_shared/typography-DKn7P4wX.cjs.map +1 -0
- package/dist/_shared/ui-provider-CQJ1glwN.js +85 -0
- package/dist/_shared/ui-provider-CQJ1glwN.js.map +1 -0
- package/dist/_shared/ui-provider-RIYE7O_V.cjs +2 -0
- package/dist/_shared/ui-provider-RIYE7O_V.cjs.map +1 -0
- package/dist/components/base/accordion/index.cjs +1 -1
- package/dist/components/base/accordion/index.js +2 -2
- package/dist/components/base/badge/badge.d.ts +1 -1
- package/dist/components/base/badge/badge.d.ts.map +1 -1
- package/dist/components/base/badge/index.cjs +1 -1
- package/dist/components/base/badge/index.js +1 -1
- package/dist/components/base/buttons/google-button.d.ts +1 -1
- package/dist/components/base/buttons/google-button.d.ts.map +1 -1
- package/dist/components/base/buttons/index.cjs +1 -1
- package/dist/components/base/buttons/index.js +2 -2
- package/dist/components/base/buttons/shopify-button.d.ts +1 -1
- package/dist/components/base/buttons/shopify-button.d.ts.map +1 -1
- package/dist/components/base/buttons/tooltip-button.d.ts.map +1 -1
- package/dist/components/base/cards/index.cjs +1 -1
- package/dist/components/base/cards/index.js +1 -1
- package/dist/components/base/cards/partials/card-primitives.d.ts +6 -6
- package/dist/components/base/cards/partials/card-primitives.d.ts.map +1 -1
- package/dist/components/base/cards/partials/smart-card-actions-menu.d.ts +1 -1
- package/dist/components/base/cards/partials/smart-card-actions-menu.d.ts.map +1 -1
- package/dist/components/base/cards/partials/smart-card-alert.d.ts +1 -1
- package/dist/components/base/cards/partials/smart-card-alert.d.ts.map +1 -1
- package/dist/components/base/cards/partials/smart-card-header-row.d.ts +1 -1
- package/dist/components/base/cards/partials/smart-card-header-row.d.ts.map +1 -1
- package/dist/components/base/cards/partials/smart-card-skeleton.d.ts +1 -1
- package/dist/components/base/cards/partials/smart-card-skeleton.d.ts.map +1 -1
- package/dist/components/base/cards/smart-card.tokens.d.ts +1 -1
- package/dist/components/base/combobox/combobox.strings.d.ts.map +1 -1
- package/dist/components/base/combobox/components/highlighted-text.d.ts.map +1 -1
- package/dist/components/base/combobox/enhanced-combobox.d.ts.map +1 -1
- package/dist/components/base/combobox/index.cjs +1 -1
- package/dist/components/base/combobox/index.js +1 -1
- package/dist/components/base/combobox/types.d.ts +2 -0
- package/dist/components/base/combobox/types.d.ts.map +1 -1
- package/dist/components/base/command/command.d.ts +5 -5
- package/dist/components/base/command/command.d.ts.map +1 -1
- package/dist/components/base/command/index.cjs +1 -1
- package/dist/components/base/command/index.js +2 -2
- package/dist/components/base/copyable/copyable.d.ts +1 -1
- package/dist/components/base/copyable/copyable.d.ts.map +1 -1
- package/dist/components/base/copyable/index.cjs +1 -1
- package/dist/components/base/copyable/index.js +1 -1
- package/dist/components/base/currency/currency-pair-preview.d.ts +1 -1
- package/dist/components/base/currency/currency-pair-preview.d.ts.map +1 -1
- package/dist/components/base/currency/index.cjs +1 -1
- package/dist/components/base/currency/index.js +1 -1
- package/dist/components/base/date-pickers/date-picker-footer.d.ts +2 -1
- package/dist/components/base/date-pickers/date-picker-footer.d.ts.map +1 -1
- package/dist/components/base/date-pickers/date-picker-header.d.ts +1 -1
- package/dist/components/base/date-pickers/date-picker-header.d.ts.map +1 -1
- package/dist/components/base/date-pickers/date-picker-helpers.d.ts +5 -1
- package/dist/components/base/date-pickers/date-picker-helpers.d.ts.map +1 -1
- package/dist/components/base/date-pickers/date-picker.d.ts +2 -1
- package/dist/components/base/date-pickers/date-picker.d.ts.map +1 -1
- package/dist/components/base/date-pickers/date-range-picker.d.ts +2 -1
- package/dist/components/base/date-pickers/date-range-picker.d.ts.map +1 -1
- package/dist/components/base/date-pickers/index.cjs +1 -1
- package/dist/components/base/date-pickers/index.js +3 -3
- package/dist/components/base/date-pickers/month-year-picker.d.ts +2 -1
- package/dist/components/base/date-pickers/month-year-picker.d.ts.map +1 -1
- package/dist/components/base/date-pickers/segmented-time-input.d.ts +2 -1
- package/dist/components/base/date-pickers/segmented-time-input.d.ts.map +1 -1
- package/dist/components/base/display/boolean-indicator.d.ts +1 -1
- package/dist/components/base/display/boolean-indicator.d.ts.map +1 -1
- package/dist/components/base/display/date-block.d.ts +1 -1
- package/dist/components/base/display/date-block.d.ts.map +1 -1
- package/dist/components/base/display/empty-state/partials/illustrations/document-stack.d.ts +1 -1
- package/dist/components/base/display/empty-state/partials/illustrations/document-stack.d.ts.map +1 -1
- package/dist/components/base/display/empty-state/partials/illustrations/inbox-clean.d.ts +1 -1
- package/dist/components/base/display/empty-state/partials/illustrations/inbox-clean.d.ts.map +1 -1
- package/dist/components/base/display/empty-state/partials/illustrations/search-glass.d.ts +1 -1
- package/dist/components/base/display/empty-state/partials/illustrations/search-glass.d.ts.map +1 -1
- package/dist/components/base/display/empty-state/partials/illustrations/stacked-cards.d.ts +1 -1
- package/dist/components/base/display/empty-state/partials/illustrations/stacked-cards.d.ts.map +1 -1
- package/dist/components/base/display/empty-state/partials/illustrations/users-circle.d.ts +1 -1
- package/dist/components/base/display/empty-state/partials/illustrations/users-circle.d.ts.map +1 -1
- package/dist/components/base/display/fields/email-display.d.ts +1 -1
- package/dist/components/base/display/fields/email-display.d.ts.map +1 -1
- package/dist/components/base/display/fields/phone-display.d.ts +1 -1
- package/dist/components/base/display/fields/phone-display.d.ts.map +1 -1
- package/dist/components/base/display/fields/url-display.d.ts +1 -1
- package/dist/components/base/display/fields/url-display.d.ts.map +1 -1
- package/dist/components/base/display/icon-badge/icon-badge.d.ts +1 -1
- package/dist/components/base/display/icon-badge/icon-badge.d.ts.map +1 -1
- package/dist/components/base/display/index.cjs +1 -1
- package/dist/components/base/display/index.js +12 -12
- package/dist/components/base/display/inline-stat/inline-stat.d.ts +1 -1
- package/dist/components/base/display/inline-stat/inline-stat.d.ts.map +1 -1
- package/dist/components/base/display/metadata/index.cjs +1 -1
- package/dist/components/base/display/metadata/index.js +1 -1
- package/dist/components/base/display/metadata/metadata-list.d.ts +1 -1
- package/dist/components/base/display/metadata/metadata-list.d.ts.map +1 -1
- package/dist/components/base/display/money-display.d.ts +1 -1
- package/dist/components/base/display/money-display.d.ts.map +1 -1
- package/dist/components/base/display/money-input.d.ts +1 -1
- package/dist/components/base/display/money-input.d.ts.map +1 -1
- package/dist/components/base/display/notification-banner.d.ts +1 -1
- package/dist/components/base/display/notification-banner.d.ts.map +1 -1
- package/dist/components/base/display/numeric-value/numeric-value.d.ts +1 -1
- package/dist/components/base/display/numeric-value/numeric-value.d.ts.map +1 -1
- package/dist/components/base/display/placeholder-pattern.d.ts +1 -1
- package/dist/components/base/display/placeholder-pattern.d.ts.map +1 -1
- package/dist/components/base/display/qr-code.d.ts +1 -1
- package/dist/components/base/display/qr-code.d.ts.map +1 -1
- package/dist/components/base/display/section-header/section-header.d.ts +1 -1
- package/dist/components/base/display/section-header/section-header.d.ts.map +1 -1
- package/dist/components/base/display/stacked-avatars.d.ts +1 -1
- package/dist/components/base/display/stacked-avatars.d.ts.map +1 -1
- package/dist/components/base/display/throttle-alert.d.ts +1 -1
- package/dist/components/base/display/throttle-alert.d.ts.map +1 -1
- package/dist/components/base/display/user-cell/user-cell.d.ts +1 -1
- package/dist/components/base/display/user-cell/user-cell.d.ts.map +1 -1
- package/dist/components/base/display/visually-hidden.d.ts +1 -1
- package/dist/components/base/display/visually-hidden.d.ts.map +1 -1
- package/dist/components/base/event-calendar/event-calendar-day-cell.d.ts +1 -1
- package/dist/components/base/event-calendar/event-calendar-day-cell.d.ts.map +1 -1
- package/dist/components/base/event-calendar/event-calendar-event-badge.d.ts +1 -1
- package/dist/components/base/event-calendar/event-calendar-event-badge.d.ts.map +1 -1
- package/dist/components/base/event-calendar/event-calendar-event-card.d.ts +1 -1
- package/dist/components/base/event-calendar/event-calendar-event-card.d.ts.map +1 -1
- package/dist/components/base/event-calendar/event-calendar-header.d.ts +1 -1
- package/dist/components/base/event-calendar/event-calendar-header.d.ts.map +1 -1
- package/dist/components/base/event-calendar/event-calendar-legend.d.ts +1 -1
- package/dist/components/base/event-calendar/event-calendar-legend.d.ts.map +1 -1
- package/dist/components/base/event-calendar/event-calendar.d.ts +1 -1
- package/dist/components/base/event-calendar/event-calendar.d.ts.map +1 -1
- package/dist/components/base/event-calendar/index.cjs +1 -1
- package/dist/components/base/event-calendar/index.cjs.map +1 -1
- package/dist/components/base/event-calendar/index.js +12 -12
- package/dist/components/base/event-calendar/index.js.map +1 -1
- package/dist/components/base/forms/fields/avatar-upload.d.ts.map +1 -1
- package/dist/components/base/forms/fields/card-checkbox-group.d.ts +1 -1
- package/dist/components/base/forms/fields/card-checkbox-group.d.ts.map +1 -1
- package/dist/components/base/forms/fields/card-radio-group.d.ts +1 -1
- package/dist/components/base/forms/fields/card-radio-group.d.ts.map +1 -1
- package/dist/components/base/forms/fields/coordinates-input.d.ts +1 -1
- package/dist/components/base/forms/fields/coordinates-input.d.ts.map +1 -1
- package/dist/components/base/forms/fields/date-time-input.d.ts +1 -1
- package/dist/components/base/forms/fields/date-time-input.d.ts.map +1 -1
- package/dist/components/base/forms/fields/dimensions-input.d.ts +1 -1
- package/dist/components/base/forms/fields/dimensions-input.d.ts.map +1 -1
- package/dist/components/base/forms/fields/key-value-editor.d.ts +1 -1
- package/dist/components/base/forms/fields/key-value-editor.d.ts.map +1 -1
- package/dist/components/base/forms/fields/list-radio-group.d.ts +1 -1
- package/dist/components/base/forms/fields/list-radio-group.d.ts.map +1 -1
- package/dist/components/base/forms/fields/list.d.ts +1 -1
- package/dist/components/base/forms/fields/list.d.ts.map +1 -1
- package/dist/components/base/forms/fields/localized-object-field.d.ts +1 -1
- package/dist/components/base/forms/fields/localized-object-field.d.ts.map +1 -1
- package/dist/components/base/forms/fields/localized-string-field.d.ts +1 -1
- package/dist/components/base/forms/fields/localized-string-field.d.ts.map +1 -1
- package/dist/components/base/forms/fields/localized-string-repeater.d.ts +1 -1
- package/dist/components/base/forms/fields/localized-string-repeater.d.ts.map +1 -1
- package/dist/components/base/forms/fields/media-gallery.d.ts +1 -1
- package/dist/components/base/forms/fields/media-gallery.d.ts.map +1 -1
- package/dist/components/base/forms/fields/object-repeater.d.ts +1 -1
- package/dist/components/base/forms/fields/object-repeater.d.ts.map +1 -1
- package/dist/components/base/forms/fields/pill-radio-group.d.ts +11 -1
- package/dist/components/base/forms/fields/pill-radio-group.d.ts.map +1 -1
- package/dist/components/base/forms/fields/repeater.d.ts +1 -1
- package/dist/components/base/forms/fields/repeater.d.ts.map +1 -1
- package/dist/components/base/forms/fields/rounding-mode-select.d.ts +1 -1
- package/dist/components/base/forms/fields/rounding-mode-select.d.ts.map +1 -1
- package/dist/components/base/forms/fields/string-repeater.d.ts +1 -1
- package/dist/components/base/forms/fields/string-repeater.d.ts.map +1 -1
- package/dist/components/base/forms/fields/switch-card.d.ts +2 -1
- package/dist/components/base/forms/fields/switch-card.d.ts.map +1 -1
- package/dist/components/base/forms/fields/switch.d.ts.map +1 -1
- package/dist/components/base/forms/fields/tags-input.d.ts +1 -1
- package/dist/components/base/forms/fields/tags-input.d.ts.map +1 -1
- package/dist/components/base/forms/fields/time-picker.d.ts +2 -1
- package/dist/components/base/forms/fields/time-picker.d.ts.map +1 -1
- package/dist/components/base/forms/fields/toggle-field.d.ts +1 -1
- package/dist/components/base/forms/fields/toggle-field.d.ts.map +1 -1
- package/dist/components/base/forms/fields/upload-progress-list.d.ts +1 -1
- package/dist/components/base/forms/fields/upload-progress-list.d.ts.map +1 -1
- package/dist/components/base/forms/fields/weight-input.d.ts +2 -1
- package/dist/components/base/forms/fields/weight-input.d.ts.map +1 -1
- package/dist/components/base/forms/form-field.d.ts +63 -2
- package/dist/components/base/forms/form-field.d.ts.map +1 -1
- package/dist/components/base/forms/index.cjs +1 -1
- package/dist/components/base/forms/index.js +6 -6
- package/dist/components/base/forms/operation-password-form.d.ts +1 -1
- package/dist/components/base/forms/operation-password-form.d.ts.map +1 -1
- package/dist/components/base/item/index.cjs +1 -1
- package/dist/components/base/item/index.js +1 -1
- package/dist/components/base/map/index.cjs +1 -1
- package/dist/components/base/map/index.cjs.map +1 -1
- package/dist/components/base/map/index.js +104 -85
- package/dist/components/base/map/index.js.map +1 -1
- package/dist/components/base/map/map.d.ts +31 -30
- package/dist/components/base/map/map.d.ts.map +1 -1
- package/dist/components/base/map/place-autocomplete.d.ts +1 -1
- package/dist/components/base/map/place-autocomplete.d.ts.map +1 -1
- package/dist/components/base/navigation/action-menu.d.ts +1 -1
- package/dist/components/base/navigation/aside-navigation-menu.d.ts +1 -1
- package/dist/components/base/navigation/aside-navigation-menu.d.ts.map +1 -1
- package/dist/components/base/navigation/breadcrumbs.d.ts +1 -1
- package/dist/components/base/navigation/breadcrumbs.d.ts.map +1 -1
- package/dist/components/base/navigation/index.cjs +1 -1
- package/dist/components/base/navigation/index.js +4 -4
- package/dist/components/base/navigation/language-switcher.d.ts +1 -1
- package/dist/components/base/navigation/language-switcher.d.ts.map +1 -1
- package/dist/components/base/navigation/navigation-tabs.d.ts +1 -1
- package/dist/components/base/navigation/navigation-tabs.d.ts.map +1 -1
- package/dist/components/base/navigation/overflow-tab-bar.d.ts +1 -1
- package/dist/components/base/navigation/overflow-tab-bar.d.ts.map +1 -1
- package/dist/components/base/navigation/page-header/page-header.d.ts +1 -1
- package/dist/components/base/navigation/page-header/page-header.d.ts.map +1 -1
- package/dist/components/base/navigation/section-nav/section-nav.d.ts +1 -1
- package/dist/components/base/navigation/section-nav/section-nav.d.ts.map +1 -1
- package/dist/components/base/navigation/side-nav.d.ts +1 -1
- package/dist/components/base/navigation/side-nav.d.ts.map +1 -1
- package/dist/components/base/navigation/tab-navigation-menu.d.ts +1 -1
- package/dist/components/base/navigation/tab-navigation-menu.d.ts.map +1 -1
- package/dist/components/base/popover/index.cjs +1 -1
- package/dist/components/base/popover/index.js +1 -1
- package/dist/components/base/popover/popover.d.ts +1 -1
- package/dist/components/base/popover/popover.d.ts.map +1 -1
- package/dist/components/base/popover-menu/index.cjs +1 -1
- package/dist/components/base/popover-menu/index.js +1 -1
- package/dist/components/base/popover-menu/popover-menu.d.ts +1 -1
- package/dist/components/base/popover-menu/popover-menu.d.ts.map +1 -1
- package/dist/components/base/sheet/index.cjs +1 -1
- package/dist/components/base/sheet/index.js +1 -1
- package/dist/components/base/sidebar/index.cjs +1 -1
- package/dist/components/base/sidebar/index.js +2 -2
- package/dist/components/base/sidebar/sidebar.d.ts +10 -9
- package/dist/components/base/sidebar/sidebar.d.ts.map +1 -1
- package/dist/components/base/spinner/index.cjs +1 -1
- package/dist/components/base/spinner/index.js +1 -1
- package/dist/components/base/table/column-visibility-toggle.d.ts +1 -1
- package/dist/components/base/table/column-visibility-toggle.d.ts.map +1 -1
- package/dist/components/base/table/data-table.d.ts +1 -1
- package/dist/components/base/table/data-table.d.ts.map +1 -1
- package/dist/components/base/table/filter-bar.d.ts +1 -1
- package/dist/components/base/table/filter-bar.d.ts.map +1 -1
- package/dist/components/base/table/index.cjs +1 -1
- package/dist/components/base/table/index.cjs.map +1 -1
- package/dist/components/base/table/index.js +23 -23
- package/dist/components/base/table/index.js.map +1 -1
- package/dist/components/base/table/pagination.d.ts +1 -1
- package/dist/components/base/table/pagination.d.ts.map +1 -1
- package/dist/components/base/table/partials/cell-renderers.d.ts +4 -4
- package/dist/components/base/table/partials/cell-renderers.d.ts.map +1 -1
- package/dist/components/base/table/partials/cell-value.d.ts +1 -1
- package/dist/components/base/table/partials/cell-value.d.ts.map +1 -1
- package/dist/components/base/table/partials/density-toggle.d.ts +1 -1
- package/dist/components/base/table/partials/density-toggle.d.ts.map +1 -1
- package/dist/components/base/table/partials/table-link.d.ts +1 -1
- package/dist/components/base/table/partials/table-link.d.ts.map +1 -1
- package/dist/components/base/table/table-actions.d.ts +1 -1
- package/dist/components/base/table/table-actions.d.ts.map +1 -1
- package/dist/components/base/table/table-body.d.ts +1 -1
- package/dist/components/base/table/table-body.d.ts.map +1 -1
- package/dist/components/base/table/table-header.d.ts +2 -1
- package/dist/components/base/table/table-header.d.ts.map +1 -1
- package/dist/components/base/table/table-helpers.d.ts +2 -2
- package/dist/components/base/table/table-helpers.d.ts.map +1 -1
- package/dist/components/base/table/table-pagination.d.ts +1 -1
- package/dist/components/base/table/table-pagination.d.ts.map +1 -1
- package/dist/components/base/table/table-toolbar.d.ts +1 -1
- package/dist/components/base/table/table-toolbar.d.ts.map +1 -1
- package/dist/components/base/toaster/index.cjs +1 -1
- package/dist/components/base/toaster/index.cjs.map +1 -1
- package/dist/components/base/toaster/index.js +1 -1
- package/dist/components/base/toaster/index.js.map +1 -1
- package/dist/components/base/toaster/toaster.d.ts +1 -1
- package/dist/components/base/toaster/toaster.d.ts.map +1 -1
- package/dist/components/composed/admin/conversation-row/conversation-row.d.ts +1 -1
- package/dist/components/composed/admin/conversation-row/conversation-row.d.ts.map +1 -1
- package/dist/components/composed/admin/index.cjs +1 -1
- package/dist/components/composed/admin/index.cjs.map +1 -1
- package/dist/components/composed/admin/index.js +159 -155
- package/dist/components/composed/admin/index.js.map +1 -1
- package/dist/components/composed/admin/inventory-level/inventory-level.d.ts +1 -1
- package/dist/components/composed/admin/inventory-level/inventory-level.d.ts.map +1 -1
- package/dist/components/composed/admin/role-permission/role-permission.d.ts +1 -1
- package/dist/components/composed/admin/role-permission/role-permission.d.ts.map +1 -1
- package/dist/components/composed/admin/settings-toggle/settings-toggle.d.ts +1 -1
- package/dist/components/composed/admin/settings-toggle/settings-toggle.d.ts.map +1 -1
- package/dist/components/composed/admin/team-member/team-member.d.ts +1 -1
- package/dist/components/composed/admin/team-member/team-member.d.ts.map +1 -1
- package/dist/components/composed/ai/ai-agent/ai-agent.d.ts +1 -1
- package/dist/components/composed/ai/ai-agent/ai-agent.d.ts.map +1 -1
- package/dist/components/composed/ai/ai-artifact/ai-artifact.d.ts +1 -1
- package/dist/components/composed/ai/ai-artifact/ai-artifact.d.ts.map +1 -1
- package/dist/components/composed/ai/ai-attachment/ai-attachment.d.ts +1 -1
- package/dist/components/composed/ai/ai-attachment/ai-attachment.d.ts.map +1 -1
- package/dist/components/composed/ai/ai-chain-of-thought/ai-chain-of-thought.d.ts +1 -1
- package/dist/components/composed/ai/ai-chain-of-thought/ai-chain-of-thought.d.ts.map +1 -1
- package/dist/components/composed/ai/ai-citation/ai-citation.d.ts +1 -1
- package/dist/components/composed/ai/ai-citation/ai-citation.d.ts.map +1 -1
- package/dist/components/composed/ai/ai-classification/ai-classification.d.ts +1 -1
- package/dist/components/composed/ai/ai-classification/ai-classification.d.ts.map +1 -1
- package/dist/components/composed/ai/ai-code-block/ai-code-block.d.ts +1 -1
- package/dist/components/composed/ai/ai-code-block/ai-code-block.d.ts.map +1 -1
- package/dist/components/composed/ai/ai-confidence/ai-confidence.d.ts +1 -1
- package/dist/components/composed/ai/ai-confidence/ai-confidence.d.ts.map +1 -1
- package/dist/components/composed/ai/ai-confirmation/ai-confirmation.d.ts +1 -1
- package/dist/components/composed/ai/ai-confirmation/ai-confirmation.d.ts.map +1 -1
- package/dist/components/composed/ai/ai-feedback/ai-feedback.d.ts +1 -1
- package/dist/components/composed/ai/ai-feedback/ai-feedback.d.ts.map +1 -1
- package/dist/components/composed/ai/ai-file-tree/ai-file-tree.d.ts +1 -1
- package/dist/components/composed/ai/ai-file-tree/ai-file-tree.d.ts.map +1 -1
- package/dist/components/composed/ai/ai-inline-citation/ai-inline-citation.d.ts +1 -1
- package/dist/components/composed/ai/ai-inline-citation/ai-inline-citation.d.ts.map +1 -1
- package/dist/components/composed/ai/ai-message-bubble/ai-message-bubble.d.ts +1 -1
- package/dist/components/composed/ai/ai-message-bubble/ai-message-bubble.d.ts.map +1 -1
- package/dist/components/composed/ai/ai-package-info/ai-package-info.d.ts +1 -1
- package/dist/components/composed/ai/ai-package-info/ai-package-info.d.ts.map +1 -1
- package/dist/components/composed/ai/ai-prompt-suggestions/ai-prompt-suggestions.d.ts +1 -1
- package/dist/components/composed/ai/ai-prompt-suggestions/ai-prompt-suggestions.d.ts.map +1 -1
- package/dist/components/composed/ai/ai-reasoning/ai-reasoning.d.ts +1 -1
- package/dist/components/composed/ai/ai-reasoning/ai-reasoning.d.ts.map +1 -1
- package/dist/components/composed/ai/ai-shimmer/ai-shimmer.d.ts +1 -1
- package/dist/components/composed/ai/ai-shimmer/ai-shimmer.d.ts.map +1 -1
- package/dist/components/composed/ai/ai-sources/ai-sources.d.ts +1 -1
- package/dist/components/composed/ai/ai-sources/ai-sources.d.ts.map +1 -1
- package/dist/components/composed/ai/ai-summary/ai-summary.d.ts +1 -1
- package/dist/components/composed/ai/ai-summary/ai-summary.d.ts.map +1 -1
- package/dist/components/composed/ai/ai-task/ai-task.d.ts +1 -1
- package/dist/components/composed/ai/ai-task/ai-task.d.ts.map +1 -1
- package/dist/components/composed/ai/ai-token-usage/ai-token-usage.d.ts +1 -1
- package/dist/components/composed/ai/ai-token-usage/ai-token-usage.d.ts.map +1 -1
- package/dist/components/composed/ai/ai-tool-call/ai-tool-call.d.ts +1 -1
- package/dist/components/composed/ai/ai-tool-call/ai-tool-call.d.ts.map +1 -1
- package/dist/components/composed/ai/index.cjs +1 -1
- package/dist/components/composed/ai/index.cjs.map +1 -1
- package/dist/components/composed/ai/index.js +34 -36
- package/dist/components/composed/ai/index.js.map +1 -1
- package/dist/components/composed/analytics/activity-heatmap/activity-heatmap.d.ts +1 -1
- package/dist/components/composed/analytics/activity-heatmap/activity-heatmap.d.ts.map +1 -1
- package/dist/components/composed/analytics/atoms/metric-skeleton.d.ts +1 -1
- package/dist/components/composed/analytics/atoms/metric-skeleton.d.ts.map +1 -1
- package/dist/components/composed/analytics/atoms/metric-sparkline.d.ts +1 -1
- package/dist/components/composed/analytics/atoms/metric-sparkline.d.ts.map +1 -1
- package/dist/components/composed/analytics/atoms/metric-trend-chip.d.ts +1 -1
- package/dist/components/composed/analytics/atoms/metric-trend-chip.d.ts.map +1 -1
- package/dist/components/composed/analytics/index.cjs +1 -1
- package/dist/components/composed/analytics/index.cjs.map +1 -1
- package/dist/components/composed/analytics/index.js +100 -111
- package/dist/components/composed/analytics/index.js.map +1 -1
- package/dist/components/composed/analytics/metric/metric.d.ts +1 -1
- package/dist/components/composed/analytics/metric/metric.d.ts.map +1 -1
- package/dist/components/composed/analytics/metric-bar/metric-bar.d.ts +1 -1
- package/dist/components/composed/analytics/metric-bar/metric-bar.d.ts.map +1 -1
- package/dist/components/composed/analytics/metric-comparison/metric-comparison.d.ts +1 -1
- package/dist/components/composed/analytics/metric-comparison/metric-comparison.d.ts.map +1 -1
- package/dist/components/composed/analytics/metric-gradient/metric-gradient.d.ts +1 -1
- package/dist/components/composed/analytics/metric-gradient/metric-gradient.d.ts.map +1 -1
- package/dist/components/composed/analytics/metric-grid/metric-grid.d.ts +1 -1
- package/dist/components/composed/analytics/metric-grid/metric-grid.d.ts.map +1 -1
- package/dist/components/composed/analytics/metric-micro-grid/metric-micro-grid.d.ts +1 -1
- package/dist/components/composed/analytics/metric-micro-grid/metric-micro-grid.d.ts.map +1 -1
- package/dist/components/composed/cards/contact-card/contact-card.d.ts +1 -1
- package/dist/components/composed/cards/contact-card/contact-card.d.ts.map +1 -1
- package/dist/components/composed/cards/course-card/course-card.d.ts +1 -1
- package/dist/components/composed/cards/course-card/course-card.d.ts.map +1 -1
- package/dist/components/composed/cards/feature-announcement/feature-announcement.d.ts +1 -1
- package/dist/components/composed/cards/feature-announcement/feature-announcement.d.ts.map +1 -1
- package/dist/components/composed/cards/giftcard-card/partials/giftcard-compact.d.ts +1 -1
- package/dist/components/composed/cards/giftcard-card/partials/giftcard-compact.d.ts.map +1 -1
- package/dist/components/composed/cards/giftcard-card/partials/giftcard-dark.d.ts +1 -1
- package/dist/components/composed/cards/giftcard-card/partials/giftcard-dark.d.ts.map +1 -1
- package/dist/components/composed/cards/giftcard-card/partials/giftcard-full.d.ts +1 -1
- package/dist/components/composed/cards/giftcard-card/partials/giftcard-full.d.ts.map +1 -1
- package/dist/components/composed/cards/giftcard-card/partials/giftcard-illustrated.d.ts +1 -1
- package/dist/components/composed/cards/giftcard-card/partials/giftcard-illustrated.d.ts.map +1 -1
- package/dist/components/composed/cards/giftcard-card/partials/giftcard-minimal.d.ts +1 -1
- package/dist/components/composed/cards/giftcard-card/partials/giftcard-minimal.d.ts.map +1 -1
- package/dist/components/composed/cards/gradient-card/gradient-card.d.ts +2 -2
- package/dist/components/composed/cards/gradient-card/gradient-card.d.ts.map +1 -1
- package/dist/components/composed/cards/index.cjs +1 -1
- package/dist/components/composed/cards/index.cjs.map +1 -1
- package/dist/components/composed/cards/index.js +492 -512
- package/dist/components/composed/cards/index.js.map +1 -1
- package/dist/components/composed/cards/vendor-profile/vendor-profile.d.ts +1 -1
- package/dist/components/composed/cards/vendor-profile/vendor-profile.d.ts.map +1 -1
- package/dist/components/composed/commerce/address-card/address-card.d.ts +1 -1
- package/dist/components/composed/commerce/address-card/address-card.d.ts.map +1 -1
- package/dist/components/composed/commerce/cart-summary/cart-summary.d.ts +1 -1
- package/dist/components/composed/commerce/cart-summary/cart-summary.d.ts.map +1 -1
- package/dist/components/composed/commerce/coupon-input/coupon-input.d.ts +1 -1
- package/dist/components/composed/commerce/coupon-input/coupon-input.d.ts.map +1 -1
- package/dist/components/composed/commerce/discount-stack/discount-stack.d.ts +1 -1
- package/dist/components/composed/commerce/discount-stack/discount-stack.d.ts.map +1 -1
- package/dist/components/composed/commerce/index.cjs +1 -1
- package/dist/components/composed/commerce/index.cjs.map +1 -1
- package/dist/components/composed/commerce/index.js +94 -98
- package/dist/components/composed/commerce/index.js.map +1 -1
- package/dist/components/composed/commerce/loyalty-points/loyalty-points.d.ts +1 -1
- package/dist/components/composed/commerce/loyalty-points/loyalty-points.d.ts.map +1 -1
- package/dist/components/composed/commerce/order-status/order-status.d.ts +1 -1
- package/dist/components/composed/commerce/order-status/order-status.d.ts.map +1 -1
- package/dist/components/composed/commerce/payment-method/payment-method.d.ts +1 -1
- package/dist/components/composed/commerce/payment-method/payment-method.d.ts.map +1 -1
- package/dist/components/composed/commerce/refund-status/refund-status.d.ts +1 -1
- package/dist/components/composed/commerce/refund-status/refund-status.d.ts.map +1 -1
- package/dist/components/composed/commerce/shipment-tracking/shipment-tracking.d.ts +1 -1
- package/dist/components/composed/commerce/shipment-tracking/shipment-tracking.d.ts.map +1 -1
- package/dist/components/composed/commerce/subscription-summary/subscription-summary.d.ts +1 -1
- package/dist/components/composed/commerce/subscription-summary/subscription-summary.d.ts.map +1 -1
- package/dist/components/composed/commerce/tax-breakdown/tax-breakdown.d.ts +1 -1
- package/dist/components/composed/commerce/tax-breakdown/tax-breakdown.d.ts.map +1 -1
- package/dist/components/composed/commerce/upcoming-booking/upcoming-booking.d.ts +1 -1
- package/dist/components/composed/commerce/upcoming-booking/upcoming-booking.d.ts.map +1 -1
- package/dist/components/composed/commerce/voucher-entry/voucher-entry.d.ts +1 -1
- package/dist/components/composed/commerce/voucher-entry/voucher-entry.d.ts.map +1 -1
- package/dist/components/composed/dark-surfaces/booking-receipt/booking-receipt.d.ts +1 -1
- package/dist/components/composed/dark-surfaces/booking-receipt/booking-receipt.d.ts.map +1 -1
- package/dist/components/composed/dark-surfaces/dark-info-panel/dark-info-panel.d.ts +1 -1
- package/dist/components/composed/dark-surfaces/dark-info-panel/dark-info-panel.d.ts.map +1 -1
- package/dist/components/composed/dark-surfaces/dark-payment/dark-payment.d.ts +1 -1
- package/dist/components/composed/dark-surfaces/dark-payment/dark-payment.d.ts.map +1 -1
- package/dist/components/composed/dark-surfaces/index.cjs +1 -1
- package/dist/components/composed/dark-surfaces/index.cjs.map +1 -1
- package/dist/components/composed/dark-surfaces/index.js +30 -27
- package/dist/components/composed/dark-surfaces/index.js.map +1 -1
- package/dist/components/composed/dark-surfaces/order-items/order-items.d.ts +1 -1
- package/dist/components/composed/dark-surfaces/order-items/order-items.d.ts.map +1 -1
- package/dist/components/composed/dark-surfaces/outstanding-balance/outstanding-balance.d.ts +1 -1
- package/dist/components/composed/dark-surfaces/outstanding-balance/outstanding-balance.d.ts.map +1 -1
- package/dist/components/composed/data-display/dense-info-card/helpers.d.ts +2 -2
- package/dist/components/composed/data-display/dense-info-card/helpers.d.ts.map +1 -1
- package/dist/components/composed/data-display/dense-info-card/partials/dense-info-classification.d.ts +1 -1
- package/dist/components/composed/data-display/dense-info-card/partials/dense-info-classification.d.ts.map +1 -1
- package/dist/components/composed/data-display/dense-info-card/partials/dense-info-dashboard.d.ts +1 -1
- package/dist/components/composed/data-display/dense-info-card/partials/dense-info-dashboard.d.ts.map +1 -1
- package/dist/components/composed/data-display/dense-info-card/partials/dense-info-financial.d.ts +1 -1
- package/dist/components/composed/data-display/dense-info-card/partials/dense-info-financial.d.ts.map +1 -1
- package/dist/components/composed/data-display/dense-info-card/partials/dense-info-project.d.ts +1 -1
- package/dist/components/composed/data-display/dense-info-card/partials/dense-info-project.d.ts.map +1 -1
- package/dist/components/composed/data-display/dense-info-card/partials/dense-info-score.d.ts +1 -1
- package/dist/components/composed/data-display/dense-info-card/partials/dense-info-score.d.ts.map +1 -1
- package/dist/components/composed/data-display/index.cjs +1 -1
- package/dist/components/composed/data-display/index.cjs.map +1 -1
- package/dist/components/composed/data-display/index.js +344 -319
- package/dist/components/composed/data-display/index.js.map +1 -1
- package/dist/components/composed/data-display/inline-metric/inline-metric.d.ts +1 -1
- package/dist/components/composed/data-display/inline-metric/inline-metric.d.ts.map +1 -1
- package/dist/components/composed/data-display/invoice-header/invoice-header.d.ts +1 -1
- package/dist/components/composed/data-display/invoice-header/invoice-header.d.ts.map +1 -1
- package/dist/components/composed/data-display/invoice-items/invoice-items.d.ts +3 -3
- package/dist/components/composed/data-display/invoice-items/invoice-items.d.ts.map +1 -1
- package/dist/components/composed/data-display/invoice-mini/invoice-mini.d.ts +1 -1
- package/dist/components/composed/data-display/invoice-mini/invoice-mini.d.ts.map +1 -1
- package/dist/components/composed/data-display/invoice-table/invoice-table.d.ts +1 -1
- package/dist/components/composed/data-display/invoice-table/invoice-table.d.ts.map +1 -1
- package/dist/components/composed/data-display/mini-kpi/mini-kpi.d.ts +1 -1
- package/dist/components/composed/data-display/mini-kpi/mini-kpi.d.ts.map +1 -1
- package/dist/components/composed/navigation/breadcrumb-progress/breadcrumb-progress.d.ts +1 -1
- package/dist/components/composed/navigation/breadcrumb-progress/breadcrumb-progress.d.ts.map +1 -1
- package/dist/components/composed/navigation/category-nav/category-nav.d.ts +1 -1
- package/dist/components/composed/navigation/category-nav/category-nav.d.ts.map +1 -1
- package/dist/components/composed/navigation/experience-activity/experience-activity.d.ts +1 -1
- package/dist/components/composed/navigation/experience-activity/experience-activity.d.ts.map +1 -1
- package/dist/components/composed/navigation/experience-activity/experience-activity.strings.d.ts +8 -0
- package/dist/components/composed/navigation/experience-activity/experience-activity.strings.d.ts.map +1 -0
- package/dist/components/composed/navigation/experience-activity/index.d.ts +1 -0
- package/dist/components/composed/navigation/experience-activity/index.d.ts.map +1 -1
- package/dist/components/composed/navigation/experience-activity/types.d.ts +2 -0
- package/dist/components/composed/navigation/experience-activity/types.d.ts.map +1 -1
- package/dist/components/composed/navigation/index.cjs +1 -1
- package/dist/components/composed/navigation/index.cjs.map +1 -1
- package/dist/components/composed/navigation/index.js +42 -35
- package/dist/components/composed/navigation/index.js.map +1 -1
- package/dist/components/composed/navigation/kanban-board/kanban-board.d.ts +1 -1
- package/dist/components/composed/navigation/kanban-board/kanban-board.d.ts.map +1 -1
- package/dist/components/composed/navigation/tab-switcher/tab-switcher.d.ts +1 -1
- package/dist/components/composed/navigation/tab-switcher/tab-switcher.d.ts.map +1 -1
- package/dist/components/composed/navigation/time-ruler/time-ruler.d.ts +1 -1
- package/dist/components/composed/navigation/time-ruler/time-ruler.d.ts.map +1 -1
- package/dist/components/composed/navigation/vendor-performance/vendor-performance.d.ts +1 -1
- package/dist/components/composed/navigation/vendor-performance/vendor-performance.d.ts.map +1 -1
- package/dist/components/composed/onboarding/checklist/checklist.d.ts.map +1 -1
- package/dist/components/composed/onboarding/checklist/partials/step-status-indicator.d.ts +1 -1
- package/dist/components/composed/onboarding/checklist/partials/step-status-indicator.d.ts.map +1 -1
- package/dist/components/composed/onboarding/index.cjs +1 -1
- package/dist/components/composed/onboarding/index.cjs.map +1 -1
- package/dist/components/composed/onboarding/index.js +60 -60
- package/dist/components/composed/onboarding/index.js.map +1 -1
- package/dist/components/composed/timelines/activity-stream/activity-stream.d.ts +1 -1
- package/dist/components/composed/timelines/activity-stream/activity-stream.d.ts.map +1 -1
- package/dist/components/composed/timelines/changelog/changelog-timeline.d.ts +1 -1
- package/dist/components/composed/timelines/changelog/changelog-timeline.d.ts.map +1 -1
- package/dist/components/composed/timelines/index.cjs +1 -1
- package/dist/components/composed/timelines/index.cjs.map +1 -1
- package/dist/components/composed/timelines/index.js +34 -7
- package/dist/components/composed/timelines/index.js.map +1 -1
- package/dist/components/composed/timelines/milestones/milestones-timeline.d.ts +1 -1
- package/dist/components/composed/timelines/milestones/milestones-timeline.d.ts.map +1 -1
- package/dist/components/composed/timelines/order-timeline/order-timeline.d.ts +1 -1
- package/dist/components/composed/timelines/order-timeline/order-timeline.d.ts.map +1 -1
- package/dist/components/composed/timelines/payment-timeline/payment-timeline.d.ts +1 -1
- package/dist/components/composed/timelines/payment-timeline/payment-timeline.d.ts.map +1 -1
- package/dist/components/composed/timelines/shared/timeline.d.ts +1 -1
- package/dist/components/composed/timelines/shared/timeline.d.ts.map +1 -1
- package/dist/components/composed/timelines/steps-card/steps-card.d.ts +2 -2
- package/dist/components/composed/timelines/steps-card/steps-card.d.ts.map +1 -1
- package/dist/components/features/activities/activities-feed.d.ts +1 -1
- package/dist/components/features/activities/activities-feed.d.ts.map +1 -1
- package/dist/components/features/activities/index.cjs +1 -1
- package/dist/components/features/activities/index.cjs.map +1 -1
- package/dist/components/features/activities/index.js +7 -7
- package/dist/components/features/activities/index.js.map +1 -1
- package/dist/components/features/activities/partials/activities-feed-card.d.ts +1 -1
- package/dist/components/features/activities/partials/activities-feed-card.d.ts.map +1 -1
- package/dist/components/features/activities/partials/activity-actions-menu.d.ts +1 -1
- package/dist/components/features/activities/partials/activity-actions-menu.d.ts.map +1 -1
- package/dist/components/features/activities/partials/activity-changes.d.ts +1 -1
- package/dist/components/features/activities/partials/activity-changes.d.ts.map +1 -1
- package/dist/components/features/activities/partials/activity-date-label.d.ts +1 -1
- package/dist/components/features/activities/partials/activity-date-label.d.ts.map +1 -1
- package/dist/components/features/activities/partials/activity-empty-state.d.ts +1 -1
- package/dist/components/features/activities/partials/activity-empty-state.d.ts.map +1 -1
- package/dist/components/features/activities/partials/activity-headline.d.ts +1 -1
- package/dist/components/features/activities/partials/activity-headline.d.ts.map +1 -1
- package/dist/components/features/activities/partials/activity-marker.d.ts +1 -1
- package/dist/components/features/activities/partials/activity-marker.d.ts.map +1 -1
- package/dist/components/features/activities/partials/activity-resource-tag.d.ts +1 -1
- package/dist/components/features/activities/partials/activity-resource-tag.d.ts.map +1 -1
- package/dist/components/features/activities/partials/activity-row.d.ts +1 -1
- package/dist/components/features/activities/partials/activity-row.d.ts.map +1 -1
- package/dist/components/features/ai-chat/ai-chat.d.ts +1 -1
- package/dist/components/features/ai-chat/ai-chat.d.ts.map +1 -1
- package/dist/components/features/ai-chat/index.cjs +1 -1
- package/dist/components/features/ai-chat/index.cjs.map +1 -1
- package/dist/components/features/ai-chat/index.js +7 -7
- package/dist/components/features/ai-chat/index.js.map +1 -1
- package/dist/components/features/ai-chat/partials/ai-chat-attachments-strip.d.ts +1 -1
- package/dist/components/features/ai-chat/partials/ai-chat-attachments-strip.d.ts.map +1 -1
- package/dist/components/features/ai-chat/partials/ai-chat-conversation.d.ts +1 -1
- package/dist/components/features/ai-chat/partials/ai-chat-conversation.d.ts.map +1 -1
- package/dist/components/features/ai-chat/partials/ai-chat-empty-state.d.ts +1 -1
- package/dist/components/features/ai-chat/partials/ai-chat-empty-state.d.ts.map +1 -1
- package/dist/components/features/ai-chat/partials/ai-chat-message.d.ts +1 -1
- package/dist/components/features/ai-chat/partials/ai-chat-message.d.ts.map +1 -1
- package/dist/components/features/ai-chat/partials/ai-chat-prompt-input.d.ts +1 -1
- package/dist/components/features/ai-chat/partials/ai-chat-prompt-input.d.ts.map +1 -1
- package/dist/components/features/ai-chat/partials/ai-chat-queue.d.ts +1 -1
- package/dist/components/features/ai-chat/partials/ai-chat-queue.d.ts.map +1 -1
- package/dist/components/features/ai-chat/partials/ai-chat-suggestions-row.d.ts +1 -1
- package/dist/components/features/ai-chat/partials/ai-chat-suggestions-row.d.ts.map +1 -1
- package/dist/components/features/card/booking-calendar-event-card.d.ts +1 -1
- package/dist/components/features/card/booking-calendar-event-card.d.ts.map +1 -1
- package/dist/components/features/card/index.cjs +1 -1
- package/dist/components/features/card/index.cjs.map +1 -1
- package/dist/components/features/card/index.js +4 -4
- package/dist/components/features/card/index.js.map +1 -1
- package/dist/components/features/card/partials/default-shared-resource-partials.d.ts +4 -4
- package/dist/components/features/card/partials/default-shared-resource-partials.d.ts.map +1 -1
- package/dist/components/features/card/shared-resource-card.d.ts +1 -1
- package/dist/components/features/card/shared-resource-card.d.ts.map +1 -1
- package/dist/components/features/comments/comments.d.ts +1 -1
- package/dist/components/features/comments/comments.d.ts.map +1 -1
- package/dist/components/features/comments/index.cjs +1 -1
- package/dist/components/features/comments/index.js +2 -2
- package/dist/components/features/comments/partials/comment-composer.d.ts.map +1 -1
- package/dist/components/features/event-log/event-log.d.ts +1 -1
- package/dist/components/features/event-log/event-log.d.ts.map +1 -1
- package/dist/components/features/event-log/index.cjs +1 -1
- package/dist/components/features/event-log/index.cjs.map +1 -1
- package/dist/components/features/event-log/index.js +5 -5
- package/dist/components/features/event-log/index.js.map +1 -1
- package/dist/components/features/filters/facets/async-select-facet.d.ts +1 -1
- package/dist/components/features/filters/facets/async-select-facet.d.ts.map +1 -1
- package/dist/components/features/filters/facets/date-facet.d.ts +1 -1
- package/dist/components/features/filters/facets/date-facet.d.ts.map +1 -1
- package/dist/components/features/filters/facets/range-facet.d.ts +1 -1
- package/dist/components/features/filters/facets/range-facet.d.ts.map +1 -1
- package/dist/components/features/filters/facets/search-facet.d.ts +1 -1
- package/dist/components/features/filters/facets/search-facet.d.ts.map +1 -1
- package/dist/components/features/filters/facets/select-facet.d.ts +1 -1
- package/dist/components/features/filters/facets/select-facet.d.ts.map +1 -1
- package/dist/components/features/filters/facets/tags-facet.d.ts +1 -1
- package/dist/components/features/filters/facets/tags-facet.d.ts.map +1 -1
- package/dist/components/features/filters/filter-context.d.ts +1 -1
- package/dist/components/features/filters/filter-context.d.ts.map +1 -1
- package/dist/components/features/filters/filter-layout.d.ts +1 -1
- package/dist/components/features/filters/filter-layout.d.ts.map +1 -1
- package/dist/components/features/filters/filters.strings.d.ts +1 -0
- package/dist/components/features/filters/filters.strings.d.ts.map +1 -1
- package/dist/components/features/filters/filters.types.d.ts +1 -1
- package/dist/components/features/filters/index.cjs +1 -1
- package/dist/components/features/filters/index.cjs.map +1 -1
- package/dist/components/features/filters/index.js +195 -188
- package/dist/components/features/filters/index.js.map +1 -1
- package/dist/components/features/filters/partials/active-filter-item.d.ts +2 -1
- package/dist/components/features/filters/partials/active-filter-item.d.ts.map +1 -1
- package/dist/components/features/filters/partials/async-filter-content.d.ts +1 -1
- package/dist/components/features/filters/partials/async-filter-content.d.ts.map +1 -1
- package/dist/components/features/filters/partials/date-filter-content.d.ts +1 -1
- package/dist/components/features/filters/partials/date-filter-content.d.ts.map +1 -1
- package/dist/components/features/filters/partials/filter-error-boundary.d.ts +1 -1
- package/dist/components/features/filters/partials/filter-error-boundary.d.ts.map +1 -1
- package/dist/components/features/filters/partials/filter-list-content.d.ts +1 -1
- package/dist/components/features/filters/partials/filter-list-content.d.ts.map +1 -1
- package/dist/components/features/filters/partials/filter-list-item.d.ts +1 -1
- package/dist/components/features/filters/partials/filter-list-item.d.ts.map +1 -1
- package/dist/components/features/filters/partials/filter-operator-select.d.ts +2 -1
- package/dist/components/features/filters/partials/filter-operator-select.d.ts.map +1 -1
- package/dist/components/features/filters/partials/filter-pill.d.ts +1 -1
- package/dist/components/features/filters/partials/filter-pill.d.ts.map +1 -1
- package/dist/components/features/filters/partials/filter-popover-content.d.ts +1 -1
- package/dist/components/features/filters/partials/filter-popover-content.d.ts.map +1 -1
- package/dist/components/features/filters/partials/filter-tabs.d.ts +1 -1
- package/dist/components/features/filters/partials/filter-tabs.d.ts.map +1 -1
- package/dist/components/features/filters/partials/filter-value-display.d.ts +1 -1
- package/dist/components/features/filters/partials/filter-value-display.d.ts.map +1 -1
- package/dist/components/features/filters/partials/filters-button.d.ts +1 -1
- package/dist/components/features/filters/partials/filters-button.d.ts.map +1 -1
- package/dist/components/features/filters/partials/regular-filter-content.d.ts +1 -1
- package/dist/components/features/filters/partials/regular-filter-content.d.ts.map +1 -1
- package/dist/components/features/filters/partials/search-filters-list.d.ts +1 -1
- package/dist/components/features/filters/partials/search-filters-list.d.ts.map +1 -1
- package/dist/components/features/filters/partials/tags-filter-content.d.ts +1 -1
- package/dist/components/features/filters/partials/tags-filter-content.d.ts.map +1 -1
- package/dist/components/features/global-search/global-search.d.ts +22 -1
- package/dist/components/features/global-search/global-search.d.ts.map +1 -1
- package/dist/components/features/global-search/index.cjs +1 -1
- package/dist/components/features/global-search/index.cjs.map +1 -1
- package/dist/components/features/global-search/index.js +3 -3
- package/dist/components/features/global-search/index.js.map +1 -1
- package/dist/components/features/global-search/partials/global-search-empty-state.d.ts +1 -1
- package/dist/components/features/global-search/partials/global-search-empty-state.d.ts.map +1 -1
- package/dist/components/features/global-search/partials/global-search-footer.d.ts +1 -1
- package/dist/components/features/global-search/partials/global-search-footer.d.ts.map +1 -1
- package/dist/components/features/global-search/partials/global-search-idle-state.d.ts +1 -1
- package/dist/components/features/global-search/partials/global-search-idle-state.d.ts.map +1 -1
- package/dist/components/features/global-search/partials/global-search-result-row.d.ts +2 -1
- package/dist/components/features/global-search/partials/global-search-result-row.d.ts.map +1 -1
- package/dist/components/features/global-search/partials/global-search-tabs.d.ts +1 -1
- package/dist/components/features/global-search/partials/global-search-tabs.d.ts.map +1 -1
- package/dist/components/features/kanban/index.cjs +1 -1
- package/dist/components/features/kanban/index.cjs.map +1 -1
- package/dist/components/features/kanban/index.js +2 -2
- package/dist/components/features/kanban/index.js.map +1 -1
- package/dist/components/features/kanban/kanban.d.ts +7 -7
- package/dist/components/features/kanban/kanban.d.ts.map +1 -1
- package/dist/components/features/mentions/index.cjs +1 -1
- package/dist/components/features/mentions/index.js +1 -1
- package/dist/components/features/mentions/partials/mention-inline-suggestions.d.ts +1 -1
- package/dist/components/features/mentions/partials/mention-inline-suggestions.d.ts.map +1 -1
- package/dist/components/features/mentions/partials/mention-picker.d.ts +1 -1
- package/dist/components/features/mentions/partials/mention-picker.d.ts.map +1 -1
- package/dist/components/features/overlays/alert-dialog.d.ts +1 -1
- package/dist/components/features/overlays/alert-dialog.d.ts.map +1 -1
- package/dist/components/features/overlays/dialog.d.ts +1 -1
- package/dist/components/features/overlays/dialog.d.ts.map +1 -1
- package/dist/components/features/overlays/drawer.d.ts +1 -1
- package/dist/components/features/overlays/drawer.d.ts.map +1 -1
- package/dist/components/features/overlays/index.cjs +1 -1
- package/dist/components/features/overlays/index.js +1 -1
- package/dist/components/features/rich-text-editor/form-rich-text-editor.d.ts +1 -1
- package/dist/components/features/rich-text-editor/form-rich-text-editor.d.ts.map +1 -1
- package/dist/components/features/rich-text-editor/index.cjs +1 -1
- package/dist/components/features/rich-text-editor/index.cjs.map +1 -1
- package/dist/components/features/rich-text-editor/index.js +1 -1
- package/dist/components/features/rich-text-editor/index.js.map +1 -1
- package/dist/components/features/rich-text-editor/partials/counts-footer.d.ts +2 -2
- package/dist/components/features/rich-text-editor/partials/counts-footer.d.ts.map +1 -1
- package/dist/components/features/rich-text-editor/partials/rich-text-editor-fallback.d.ts.map +1 -1
- package/dist/components/features/rich-text-editor/partials/rich-text-editor-tiptap.d.ts.map +1 -1
- package/dist/components/features/rich-text-editor/partials/rich-text-editor-toolbar.d.ts +1 -1
- package/dist/components/features/rich-text-editor/partials/rich-text-editor-toolbar.d.ts.map +1 -1
- package/dist/components/features/rich-text-editor/rich-text-editor.strings.d.ts +4 -0
- package/dist/components/features/rich-text-editor/rich-text-editor.strings.d.ts.map +1 -1
- package/dist/components/features/suggestions/index.cjs +1 -1
- package/dist/components/features/suggestions/index.cjs.map +1 -1
- package/dist/components/features/suggestions/index.js +1 -1
- package/dist/components/features/suggestions/index.js.map +1 -1
- package/dist/components/features/suggestions/suggestions.d.ts +1 -1
- package/dist/components/features/suggestions/suggestions.d.ts.map +1 -1
- package/dist/components/features/sync/index.cjs +1 -1
- package/dist/components/features/sync/index.cjs.map +1 -1
- package/dist/components/features/sync/index.js +3 -3
- package/dist/components/features/sync/index.js.map +1 -1
- package/dist/components/features/sync/sync-range-dialog-form.d.ts +1 -1
- package/dist/components/layout/app-shell/app-shell.types.d.ts +65 -0
- package/dist/components/layout/app-shell/app-shell.types.d.ts.map +1 -0
- package/dist/components/layout/app-shell/index.cjs +1 -0
- package/dist/components/layout/app-shell/index.d.ts +3 -0
- package/dist/components/layout/app-shell/index.d.ts.map +1 -0
- package/dist/components/layout/app-shell/index.js +2 -0
- package/dist/components/layout/app-shell/topbar-sidebar-layout.d.ts +3 -0
- package/dist/components/layout/app-shell/topbar-sidebar-layout.d.ts.map +1 -0
- package/dist/components/layout/containers/content-container.d.ts +1 -1
- package/dist/components/layout/containers/content-container.d.ts.map +1 -1
- package/dist/components/layout/containers/index.cjs +1 -1
- package/dist/components/layout/containers/index.js +2 -2
- package/dist/components/layout/containers/section.d.ts +1 -1
- package/dist/components/layout/containers/section.d.ts.map +1 -1
- package/dist/components/layout/header/header.d.ts +1 -1
- package/dist/components/layout/header/header.d.ts.map +1 -1
- package/dist/components/layout/header/index.cjs +1 -1
- package/dist/components/layout/header/index.js +1 -1
- package/dist/components/layout/header/partials/header-breadcrumbs.d.ts +3 -1
- package/dist/components/layout/header/partials/header-breadcrumbs.d.ts.map +1 -1
- package/dist/components/layout/header/partials/header-notifications.d.ts +1 -1
- package/dist/components/layout/header/partials/header-notifications.d.ts.map +1 -1
- package/dist/components/layout/header/partials/header-search.d.ts +1 -1
- package/dist/components/layout/header/partials/header-search.d.ts.map +1 -1
- package/dist/components/layout/header/partials/header-user-menu.d.ts +1 -1
- package/dist/components/layout/header/partials/header-user-menu.d.ts.map +1 -1
- package/dist/components/layout/hooks/index.cjs +1 -1
- package/dist/components/layout/hooks/index.js +1 -1
- package/dist/components/layout/index.cjs +1 -1
- package/dist/components/layout/index.d.ts +1 -0
- package/dist/components/layout/index.d.ts.map +1 -1
- package/dist/components/layout/index.js +8 -7
- package/dist/components/layout/page/index.cjs +1 -1
- package/dist/components/layout/page/index.js +1 -1
- package/dist/components/layout/page/page-content.d.ts +1 -1
- package/dist/components/layout/page/page-content.d.ts.map +1 -1
- package/dist/components/layout/page/page.d.ts +1 -1
- package/dist/components/layout/page/page.d.ts.map +1 -1
- package/dist/components/layout/page/partials/page-actions.d.ts +1 -1
- package/dist/components/layout/page/partials/page-actions.d.ts.map +1 -1
- package/dist/components/layout/page/partials/page-header.d.ts +1 -1
- package/dist/components/layout/page/partials/page-header.d.ts.map +1 -1
- package/dist/components/layout/sidebar/app-sidebar.d.ts +6 -1
- package/dist/components/layout/sidebar/app-sidebar.d.ts.map +1 -1
- package/dist/components/layout/sidebar/components/sidebar-grouped-navigation.d.ts +1 -1
- package/dist/components/layout/sidebar/components/sidebar-grouped-navigation.d.ts.map +1 -1
- package/dist/components/layout/sidebar/components/sidebar-logo.d.ts +1 -1
- package/dist/components/layout/sidebar/components/sidebar-logo.d.ts.map +1 -1
- package/dist/components/layout/sidebar/components/sidebar-navigation-footer.d.ts +1 -1
- package/dist/components/layout/sidebar/components/sidebar-navigation-footer.d.ts.map +1 -1
- package/dist/components/layout/sidebar/components/sidebar-navigation-user.d.ts +1 -1
- package/dist/components/layout/sidebar/components/sidebar-navigation-user.d.ts.map +1 -1
- package/dist/components/layout/sidebar/components/sidebar-navigation.d.ts +3 -1
- package/dist/components/layout/sidebar/components/sidebar-navigation.d.ts.map +1 -1
- package/dist/components/layout/sidebar/components/sidebar-workspace-dropdown.d.ts +1 -1
- package/dist/components/layout/sidebar/components/sidebar-workspace-dropdown.d.ts.map +1 -1
- package/dist/components/layout/sidebar/index.cjs +1 -1
- package/dist/components/layout/sidebar/index.js +2 -2
- package/dist/components/layout/sidebar/sidebar.context.d.ts +1 -1
- package/dist/components/layout/sidebar/sidebar.context.d.ts.map +1 -1
- package/dist/components/layout/sidebar/sidebar.d.ts +1 -1
- package/dist/components/layout/sidebar/sidebar.d.ts.map +1 -1
- package/dist/components/layout/sidebar/sidebar.utils.d.ts +2 -2
- package/dist/components/layout/sidebar/sidebar.utils.d.ts.map +1 -1
- package/dist/components/typography/heading.d.ts +1 -1
- package/dist/components/typography/heading.d.ts.map +1 -1
- package/dist/components/typography/index.cjs +1 -1
- package/dist/components/typography/index.js +3 -3
- package/dist/components/typography/label.d.ts +1 -1
- package/dist/components/typography/label.d.ts.map +1 -1
- package/dist/components/typography/text-link.d.ts +1 -1
- package/dist/components/typography/text-link.d.ts.map +1 -1
- package/dist/components/typography/text.d.ts +1 -1
- package/dist/components/typography/text.d.ts.map +1 -1
- package/dist/components/typography/typography.d.ts +3 -3
- package/dist/components/typography/typography.d.ts.map +1 -1
- package/dist/components/ui/accordion.d.ts +4 -4
- package/dist/components/ui/accordion.d.ts.map +1 -1
- package/dist/components/ui/alert.d.ts +4 -4
- package/dist/components/ui/alert.d.ts.map +1 -1
- package/dist/components/ui/avatar.d.ts +6 -6
- package/dist/components/ui/avatar.d.ts.map +1 -1
- package/dist/components/ui/badge.d.ts +1 -1
- package/dist/components/ui/badge.d.ts.map +1 -1
- package/dist/components/ui/breadcrumb.d.ts +7 -7
- package/dist/components/ui/breadcrumb.d.ts.map +1 -1
- package/dist/components/ui/button-group.d.ts +2 -2
- package/dist/components/ui/button-group.d.ts.map +1 -1
- package/dist/components/ui/button.d.ts +1 -1
- package/dist/components/ui/button.d.ts.map +1 -1
- package/dist/components/ui/calendar.d.ts +2 -2
- package/dist/components/ui/calendar.d.ts.map +1 -1
- package/dist/components/ui/card.d.ts +7 -7
- package/dist/components/ui/card.d.ts.map +1 -1
- package/dist/components/ui/chart.d.ts +4 -4
- package/dist/components/ui/chart.d.ts.map +1 -1
- package/dist/components/ui/checkbox.d.ts +1 -1
- package/dist/components/ui/checkbox.d.ts.map +1 -1
- package/dist/components/ui/collapsible.d.ts +4 -3
- package/dist/components/ui/collapsible.d.ts.map +1 -1
- package/dist/components/ui/combobox.d.ts +20 -20
- package/dist/components/ui/combobox.d.ts.map +1 -1
- package/dist/components/ui/command.d.ts +9 -9
- package/dist/components/ui/command.d.ts.map +1 -1
- package/dist/components/ui/context-menu.d.ts +15 -15
- package/dist/components/ui/context-menu.d.ts.map +1 -1
- package/dist/components/ui/dialog.d.ts +10 -10
- package/dist/components/ui/dialog.d.ts.map +1 -1
- package/dist/components/ui/dropdown-menu.d.ts +16 -16
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -1
- package/dist/components/ui/empty.d.ts +6 -6
- package/dist/components/ui/empty.d.ts.map +1 -1
- package/dist/components/ui/hover-card.d.ts +3 -3
- package/dist/components/ui/hover-card.d.ts.map +1 -1
- package/dist/components/ui/input-group.d.ts +6 -6
- package/dist/components/ui/input-group.d.ts.map +1 -1
- package/dist/components/ui/input.d.ts +1 -1
- package/dist/components/ui/input.d.ts.map +1 -1
- package/dist/components/ui/item.d.ts +9 -9
- package/dist/components/ui/item.d.ts.map +1 -1
- package/dist/components/ui/pagination.d.ts +7 -7
- package/dist/components/ui/pagination.d.ts.map +1 -1
- package/dist/components/ui/popover.d.ts +7 -7
- package/dist/components/ui/popover.d.ts.map +1 -1
- package/dist/components/ui/progress.d.ts +5 -5
- package/dist/components/ui/progress.d.ts.map +1 -1
- package/dist/components/ui/radio-group.d.ts +2 -2
- package/dist/components/ui/radio-group.d.ts.map +1 -1
- package/dist/components/ui/scroll-area.d.ts +2 -2
- package/dist/components/ui/scroll-area.d.ts.map +1 -1
- package/dist/components/ui/select.d.ts +9 -9
- package/dist/components/ui/select.d.ts.map +1 -1
- package/dist/components/ui/separator.d.ts +1 -1
- package/dist/components/ui/separator.d.ts.map +1 -1
- package/dist/components/ui/sheet.d.ts +8 -8
- package/dist/components/ui/sheet.d.ts.map +1 -1
- package/dist/components/ui/sidebar.d.ts +19 -19
- package/dist/components/ui/sidebar.d.ts.map +1 -1
- package/dist/components/ui/skeleton.d.ts +1 -1
- package/dist/components/ui/skeleton.d.ts.map +1 -1
- package/dist/components/ui/slider.d.ts +2 -1
- package/dist/components/ui/slider.d.ts.map +1 -1
- package/dist/components/ui/sonner.d.ts +1 -1
- package/dist/components/ui/sonner.d.ts.map +1 -1
- package/dist/components/ui/spinner.d.ts +1 -1
- package/dist/components/ui/spinner.d.ts.map +1 -1
- package/dist/components/ui/switch.d.ts +1 -1
- package/dist/components/ui/switch.d.ts.map +1 -1
- package/dist/components/ui/table.d.ts +8 -8
- package/dist/components/ui/table.d.ts.map +1 -1
- package/dist/components/ui/tabs.d.ts +4 -4
- package/dist/components/ui/tabs.d.ts.map +1 -1
- package/dist/components/ui/textarea.d.ts +1 -1
- package/dist/components/ui/textarea.d.ts.map +1 -1
- package/dist/components/ui/toggle-group.d.ts +3 -2
- package/dist/components/ui/toggle-group.d.ts.map +1 -1
- package/dist/components/ui/toggle.d.ts +1 -1
- package/dist/components/ui/toggle.d.ts.map +1 -1
- package/dist/components/ui/tooltip.d.ts +4 -4
- package/dist/components/ui/tooltip.d.ts.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/strings.cjs +1 -1
- package/dist/lib/strings.cjs.map +1 -1
- package/dist/lib/strings.js.map +1 -1
- package/dist/lib/ui-provider/index.cjs +1 -1
- package/dist/lib/ui-provider/index.js +1 -1
- package/dist/lib/ui-provider/provider.d.ts +1 -1
- package/dist/lib/ui-provider/provider.d.ts.map +1 -1
- package/dist/lib/utils.cjs +1 -1
- package/dist/lib/utils.cjs.map +1 -1
- package/dist/lib/utils.js.map +1 -1
- package/dist/showcase/assets/AreaChart-CzBEYPbz.js +6 -0
- package/dist/showcase/assets/CSPContext-ImKusJJ_.js +1 -0
- package/dist/showcase/assets/CompositeItem-C-DIOBdJ.js +1 -0
- package/dist/showcase/assets/CompositeRoot-Ce4ORgG2.js +1 -0
- package/dist/showcase/assets/Control.FullScreen-CwLQ1MMK.js +1 -0
- package/dist/showcase/assets/DialogTrigger-DWvMs7dp.js +1 -0
- package/dist/showcase/assets/FormContext-BeC1MJpT.js +1 -0
- package/dist/showcase/assets/PreviewLayout-N1PTTyZK.js +1 -0
- package/dist/showcase/assets/RadioGroup-DAWaa26D.js +1 -0
- package/dist/showcase/assets/Separator-guDkmky0.js +1 -0
- package/dist/showcase/assets/ToolbarRootContext-BJ7hWga8.js +1 -0
- package/dist/showcase/assets/accordion-CiM9WhkT.js +172 -0
- package/dist/showcase/assets/accordion-variants-C_sHrQ7C.js +1 -0
- package/dist/showcase/assets/action-menu-mlWlGE5P.js +1 -0
- package/dist/showcase/assets/activities-YWR4wh4f.js +501 -0
- package/dist/showcase/assets/activities-feed-card-Cglnf5as.js +1 -0
- package/dist/showcase/assets/admin-BtOtzPd4.js +80 -0
- package/dist/showcase/assets/ai-8iNe0R1M.js +41 -0
- package/dist/showcase/assets/ai-artifact-CQL5krnJ.js +2 -0
- package/dist/showcase/assets/ai-chat-BzCdOOc6.js +568 -0
- package/dist/showcase/assets/ai-elements-CBHy2xWU.js +379 -0
- package/dist/showcase/assets/ai-new-CgL5NeVs.js +167 -0
- package/dist/showcase/assets/ai-tool-call-D9AsaWJF.js +1 -0
- package/dist/showcase/assets/alert-B2BuF4vZ.js +59 -0
- package/dist/showcase/assets/alert-BkVaTONJ.js +1 -0
- package/dist/showcase/assets/api-key-list-C-_59dli.js +73 -0
- package/dist/showcase/assets/app-sidebar-BdOu5rVn.js +1 -0
- package/dist/showcase/assets/arrow-down-BpVaq9-H.js +1 -0
- package/dist/showcase/assets/arrow-left-C40rxfqj.js +1 -0
- package/dist/showcase/assets/arrow-right-BclouSfP.js +1 -0
- package/dist/showcase/assets/arrow-up-BpWEnkdX.js +1 -0
- package/dist/showcase/assets/arrow-up-right-Z5sMa1HH.js +1 -0
- package/dist/showcase/assets/avatar-CDNhh3rv.js +57 -0
- package/dist/showcase/assets/avatar-QBwg3fvR.js +1 -0
- package/dist/showcase/assets/badge-check-DXDQ3SaL.js +1 -0
- package/dist/showcase/assets/badge-tAdYt--9.js +28 -0
- package/dist/showcase/assets/bell-CVEeEWw4.js +1 -0
- package/dist/showcase/assets/bot-Bcx5mNAQ.js +1 -0
- package/dist/showcase/assets/box-Dgy2Xc70.js +1 -0
- package/dist/showcase/assets/brain-DsoOsd7m.js +1 -0
- package/dist/showcase/assets/brand-DAyuXNUz.js +40 -0
- package/dist/showcase/assets/breadcrumb-CC4Z8eMY.js +1 -0
- package/dist/showcase/assets/breadcrumb-DCbAzeMs.js +52 -0
- package/dist/showcase/assets/breadcrumbs-DGZMpIoQ.js +1 -0
- package/dist/showcase/assets/briefcase-2uLXCvAZ.js +1 -0
- package/dist/showcase/assets/button-DhQ6rMPU.js +44 -0
- package/dist/showcase/assets/button-group-Ce9vnZ1H.js +1 -0
- package/dist/showcase/assets/buttons-CHja0LUL.js +270 -0
- package/dist/showcase/assets/calendar-BbiK8AMZ.js +16 -0
- package/dist/showcase/assets/calendar-BhZpIjCo.js +1 -0
- package/dist/showcase/assets/calendar-oKaDsUIy.js +1 -0
- package/dist/showcase/assets/card-DoU1VD79.js +1 -0
- package/dist/showcase/assets/cards-3OgH8m3F.js +328 -0
- package/dist/showcase/assets/chart-column-6Tn3WAT9.js +1 -0
- package/dist/showcase/assets/chevron-down-x7TQsvYY.js +1 -0
- package/dist/showcase/assets/chevron-left-CglzJgA2.js +1 -0
- package/dist/showcase/assets/chevron-right-CDDMIkYP.js +1 -0
- package/dist/showcase/assets/chevron-up-Dc3aAaGH.js +1 -0
- package/dist/showcase/assets/chevrons-up-down-DJNnSBAj.js +1 -0
- package/dist/showcase/assets/circle-BBmNFtO8.js +1 -0
- package/dist/showcase/assets/circle-alert-DJevf3tT.js +1 -0
- package/dist/showcase/assets/circle-check-BCxORlAM.js +1 -0
- package/dist/showcase/assets/circle-check-big-tiuK2w0-.js +1 -0
- package/dist/showcase/assets/circle-dot-BEVVQjgN.js +1 -0
- package/dist/showcase/assets/circle-question-mark-BQrUUiKD.js +1 -0
- package/dist/showcase/assets/circle-x-CoV_AUtZ.js +1 -0
- package/dist/showcase/assets/clock-Bn2R4aDX.js +1 -0
- package/dist/showcase/assets/code-xml-BVYp_JDX.js +1 -0
- package/dist/showcase/assets/collapsible-Co2Y739_.js +27 -0
- package/dist/showcase/assets/collapsible-DPbftgrO.js +1 -0
- package/dist/showcase/assets/combobox-Cm4__LnJ.js +622 -0
- package/dist/showcase/assets/command-DQFIxPN9.js +45 -0
- package/dist/showcase/assets/command-KNncGgZW.js +1 -0
- package/dist/showcase/assets/comment-composer-DTJtqYGP.js +1 -0
- package/dist/showcase/assets/comment-item-DIEYMmV_.js +1 -0
- package/dist/showcase/assets/comments-B0BbDp-3.js +357 -0
- package/dist/showcase/assets/commerce-BOWBCLA-.js +79 -0
- package/dist/showcase/assets/commerce-extras-C6CWYfpC.js +173 -0
- package/dist/showcase/assets/composite-YicTVAO0.js +1 -0
- package/dist/showcase/assets/contact-card-DQPRIlnJ.js +65 -0
- package/dist/showcase/assets/content-container-CHXwWViz.js +1 -0
- package/dist/showcase/assets/copyable-CjTwco9O.js +96 -0
- package/dist/showcase/assets/course-card-CTQScd2C.js +113 -0
- package/dist/showcase/assets/cpu-D52NjUWq.js +1 -0
- package/dist/showcase/assets/credit-card-BoDfW0R8.js +1 -0
- package/dist/showcase/assets/currency-BPREbpDA.js +149 -0
- package/dist/showcase/assets/dark-surfaces-BCG45K2m.js +90 -0
- package/dist/showcase/assets/database-DeGR0hed.js +1 -0
- package/dist/showcase/assets/date-block-Bl1kXJrM.js +1 -0
- package/dist/showcase/assets/date-picker-BHbZa4ML.js +1 -0
- package/dist/showcase/assets/date-pickers-DumwUEXE.js +110 -0
- package/dist/showcase/assets/dense-info-DxfgBw9Z.js +106 -0
- package/dist/showcase/assets/dialog-BYHZvlL8.js +1 -0
- package/dist/showcase/assets/display-BXMGOjL3.js +392 -0
- package/dist/showcase/assets/dist-CnonIdcR.js +1 -0
- package/dist/showcase/assets/dollar-sign-BipUTVXC.js +1 -0
- package/dist/showcase/assets/download-CxspQgIc.js +1 -0
- package/dist/showcase/assets/dropdown-menu-Q1BV3wPP.js +1 -0
- package/dist/showcase/assets/dropzone-OivkuTPF.js +1 -0
- package/dist/showcase/assets/ellipsis-Bn-XgoA7.js +1 -0
- package/dist/showcase/assets/ellipsis-vertical-Bcl9HX9k.js +1 -0
- package/dist/showcase/assets/empty-CcafLcw-.js +1 -0
- package/dist/showcase/assets/empty-item-CiJeS8ZV.js +49 -0
- package/dist/showcase/assets/empty-state-B1RYYjUP.js +188 -0
- package/dist/showcase/assets/enhanced-activities-IB811DS6.js +361 -0
- package/dist/showcase/assets/esm-CAF_uoYd.js +2 -0
- package/dist/showcase/assets/event-calendar-C2VCfcUz.js +138 -0
- package/dist/showcase/assets/event-log-ckmsCPmG.js +330 -0
- package/dist/showcase/assets/example-C6-_Sy6B.js +1 -0
- package/dist/showcase/assets/external-link-Bg-_8Uq7.js +1 -0
- package/dist/showcase/assets/eye-JVsUA85G.js +1 -0
- package/dist/showcase/assets/feature-announcement-C4aRXesF.js +34 -0
- package/dist/showcase/assets/fetchers-DHuMQ6PN.js +1 -0
- package/dist/showcase/assets/file-4pOq58jl.js +1 -0
- package/dist/showcase/assets/file-text-BIi71mZ1.js +1 -0
- package/dist/showcase/assets/filters-CxrcnmLU.js +78 -0
- package/dist/showcase/assets/flag-DeiJmomk.js +1 -0
- package/dist/showcase/assets/folder-open-zMXBpVNs.js +1 -0
- package/dist/showcase/assets/form-sizing-B8jbL5tL.js +1 -0
- package/dist/showcase/assets/format-BG4laCmp.js +1 -0
- package/dist/showcase/assets/format-metric-value-B94EDo8X.js +1 -0
- package/dist/showcase/assets/forms-PsN5zTLx.js +793 -0
- package/dist/showcase/assets/generic-BH5YLC_H.js +1 -0
- package/dist/showcase/assets/getPseudoElementBounds-B7wr19E1.js +1 -0
- package/dist/showcase/assets/gift-CKFIh1Wh.js +1 -0
- package/dist/showcase/assets/giftcard-cards-BfOlIHmA.js +85 -0
- package/dist/showcase/assets/git-branch-BO9i8XkJ.js +1 -0
- package/dist/showcase/assets/global-search-CNmUraNa.js +90 -0
- package/dist/showcase/assets/global-search-DkJkQ0Vs.js +1 -0
- package/dist/showcase/assets/globe-47T22W56.js +1 -0
- package/dist/showcase/assets/gradient-card-CXSY29TZ.js +58 -0
- package/dist/showcase/assets/header-eZHN-s6P.js +1 -0
- package/dist/showcase/assets/header-notifications-Caa9i87J.js +1 -0
- package/dist/showcase/assets/heart-DjKkkUsX.js +1 -0
- package/dist/showcase/assets/house-DKxCiHyB.js +1 -0
- package/dist/showcase/assets/icon-badge-Bcm8TlJi.js +1 -0
- package/dist/showcase/assets/image-r-gMI33G.js +1 -0
- package/dist/showcase/assets/inbox-ZxSy1pgX.js +1 -0
- package/dist/showcase/assets/index-B8DVXCmf.js +10 -0
- package/dist/showcase/assets/index-DbLs6mcj.css +2 -0
- package/dist/showcase/assets/inertValue-i0cAMG-0.js +1 -0
- package/dist/showcase/assets/info-B1KV2DkO.js +1 -0
- package/dist/showcase/assets/inline-stat-D0sE-A4C.js +1 -0
- package/dist/showcase/assets/input-25epjsiD.js +1 -0
- package/dist/showcase/assets/input-CnwMt9Sr.js +1 -0
- package/dist/showcase/assets/input-group-DSKyV7we.js +47 -0
- package/dist/showcase/assets/input-group-x5eWeAZg.js +1 -0
- package/dist/showcase/assets/inputs-B2Maxr14.js +49 -0
- package/dist/showcase/assets/invoice-header-Gxl--yFu.js +36 -0
- package/dist/showcase/assets/invoice-items-BtoaGNjE.js +36 -0
- package/dist/showcase/assets/invoice-mini-DHFSZegy.js +14 -0
- package/dist/showcase/assets/invoice-table-6dmU_KrL.js +30 -0
- package/dist/showcase/assets/isSameDay-BrDHfKHm.js +1 -0
- package/dist/showcase/assets/isToday-VtoSc1IH.js +1 -0
- package/dist/showcase/assets/italic-CXkAsf6H.js +1 -0
- package/dist/showcase/assets/item-CGOThKAx.js +1 -0
- package/dist/showcase/assets/item-CMRbW6s-.js +1 -0
- package/dist/showcase/assets/item-sw6fAZcn.js +117 -0
- package/dist/showcase/assets/kanban-CKGYTXji.js +175 -0
- package/dist/showcase/assets/label-BmKD22pm.js +1 -0
- package/dist/showcase/assets/layout-app-shell-CeMHzVNn.js +501 -0
- package/dist/showcase/assets/layout-containers-8Drow5f9.js +96 -0
- package/dist/showcase/assets/layout-header-BlBw4JAV.js +170 -0
- package/dist/showcase/assets/layout-page-BQfgHFau.js +122 -0
- package/dist/showcase/assets/layout-sidebar-DZer5Uuh.js +224 -0
- package/dist/showcase/assets/layout-users-nuioUkeu.js +104 -0
- package/dist/showcase/assets/leaflet-src-S_KZeH2q.js +1 -0
- package/dist/showcase/assets/lib-DMGme4uo.js +1 -0
- package/dist/showcase/assets/lock-DQcZ9cEj.js +1 -0
- package/dist/showcase/assets/mail-yNXDtmNr.js +1 -0
- package/dist/showcase/assets/map-JMM1F9VR.js +124 -0
- package/dist/showcase/assets/map-pin-2WS7oVo3.js +1 -0
- package/dist/showcase/assets/menus-mK-FeNki.js +89 -0
- package/dist/showcase/assets/message-square-DGTAjNJG.js +1 -0
- package/dist/showcase/assets/metadata-list-CBxuQjVO.js +278 -0
- package/dist/showcase/assets/metric-BWGrmyD6.js +1 -0
- package/dist/showcase/assets/metric-grid-CewIJQvo.js +1 -0
- package/dist/showcase/assets/metric-trend-chip-kLBN8u5z.js +1 -0
- package/dist/showcase/assets/metrics-analytics-bar-COnc7VN9.js +44 -0
- package/dist/showcase/assets/metrics-analytics-cards-BR83UVqi.js +77 -0
- package/dist/showcase/assets/metrics-comparison-C0SUjdMg.js +76 -0
- package/dist/showcase/assets/metrics-heatmap-Orq1hLk-.js +27 -0
- package/dist/showcase/assets/metrics-inline-badge-C924q2Xx.js +17 -0
- package/dist/showcase/assets/metrics-kpi-row-Cwi05ruK.js +31 -0
- package/dist/showcase/assets/metrics-micro-grid-D97nkrge.js +42 -0
- package/dist/showcase/assets/metrics-overview-BOc8y3QX.js +192 -0
- package/dist/showcase/assets/metrics-stat-cards-Cilh-A5D.js +54 -0
- package/dist/showcase/assets/minus-DvrDGcTv.js +1 -0
- package/dist/showcase/assets/money-display-0egZ_O76.js +1 -0
- package/dist/showcase/assets/month-year-picker-2cWfwnmP.js +1 -0
- package/dist/showcase/assets/navigation-BnYme-Wj.js +90 -0
- package/dist/showcase/assets/navigation-CLQWl32A.js +230 -0
- package/dist/showcase/assets/navigation-extras-BPDoAdXF.js +43 -0
- package/dist/showcase/assets/onboarding-checklist-26XVWgDF.js +119 -0
- package/dist/showcase/assets/overlays-2sVGhanu.js +88 -0
- package/dist/showcase/assets/overlays-BaR6HDwB.js +394 -0
- package/dist/showcase/assets/package-CUNvdlBi.js +1 -0
- package/dist/showcase/assets/page-action-button-DgvZVtzx.js +1 -0
- package/dist/showcase/assets/page-header-4F_iaFPW.js +1 -0
- package/dist/showcase/assets/pagination-CDjZ6jiZ.js +42 -0
- package/dist/showcase/assets/pagination-g1NQaN42.js +1 -0
- package/dist/showcase/assets/paperclip-CDxdf8Os.js +1 -0
- package/dist/showcase/assets/pencil-Ddc5JwBe.js +1 -0
- package/dist/showcase/assets/phone-NIZ5SwgK.js +1 -0
- package/dist/showcase/assets/plus-C9kwz7rW.js +1 -0
- package/dist/showcase/assets/popover-DtnuOBgr.js +1 -0
- package/dist/showcase/assets/popover-T85aV4zW.js +1 -0
- package/dist/showcase/assets/popover-menu-BRGSZe4f.js +1 -0
- package/dist/showcase/assets/progress-CcZjuzK3.js +1 -0
- package/dist/showcase/assets/progress-DbouniUl.js +18 -0
- package/dist/showcase/assets/props-table-CM_1cocj.js +1 -0
- package/dist/showcase/assets/props.generated-Bg627Jai.json +32829 -0
- package/dist/showcase/assets/quote-vjygm2-7.js +1 -0
- package/dist/showcase/assets/react-dom-Bz4cALsF.js +1 -0
- package/dist/showcase/assets/receipt-CfMgwFPl.js +1 -0
- package/dist/showcase/assets/refresh-cw-Tu5E_cGA.js +1 -0
- package/dist/showcase/assets/resolveValueLabel-CipUZh6i.js +1 -0
- package/dist/showcase/assets/rich-text-editor-BMZUyuQX.js +143 -0
- package/dist/showcase/assets/rich-text-editor-HwYIeWYW.js +124 -0
- package/dist/showcase/assets/rotate-ccw-B4Wi4ws7.js +1 -0
- package/dist/showcase/assets/scroll-area-CuB_woqF.js +1 -0
- package/dist/showcase/assets/scroll-area-I4mSIpRq.js +32 -0
- package/dist/showcase/assets/select-CF3cKjCo.js +1 -0
- package/dist/showcase/assets/send-Blu_n6xl.js +1 -0
- package/dist/showcase/assets/separator-9mrRf_DZ.js +28 -0
- package/dist/showcase/assets/separator-DUKleOvU.js +1 -0
- package/dist/showcase/assets/settings-DlKX-bZT.js +1 -0
- package/dist/showcase/assets/sheet-CwcLVoF3.js +1 -0
- package/dist/showcase/assets/shield-BD0Y8Jj3.js +1 -0
- package/dist/showcase/assets/shield-alert-DNOTmkwG.js +1 -0
- package/dist/showcase/assets/shield-check-Sbul0dUK.js +1 -0
- package/dist/showcase/assets/shopping-bag-EDVpxI9n.js +1 -0
- package/dist/showcase/assets/sidebar-JWZ88xw5.js +1 -0
- package/dist/showcase/assets/sidebar.context-D3P7qppn.js +1 -0
- package/dist/showcase/assets/skeleton-CIS1Kaas.js +1 -0
- package/dist/showcase/assets/skeleton-CJCJDQFt.js +29 -0
- package/dist/showcase/assets/smart-card-7szg_qSt.js +1 -0
- package/dist/showcase/assets/sonner-DMHXr9Ce.js +22 -0
- package/dist/showcase/assets/sortable.esm-DVuzVA1U.js +5 -0
- package/dist/showcase/assets/sparkles-BEa1AgNq.js +1 -0
- package/dist/showcase/assets/spinner-Bi-T9etI.js +30 -0
- package/dist/showcase/assets/spinner-C77XIUVf.js +1 -0
- package/dist/showcase/assets/spinner-DK9BAT6K.js +49 -0
- package/dist/showcase/assets/square-pen-N0mq-vPu.js +1 -0
- package/dist/showcase/assets/stacked-avatars-DORVEni2.js +1 -0
- package/dist/showcase/assets/star-Dbtxr60S.js +1 -0
- package/dist/showcase/assets/startOfDay-BJgxz4yq.js +1 -0
- package/dist/showcase/assets/styles-CwW4IBUg.js +1 -0
- package/dist/showcase/assets/switch-B4iRxZFU.js +1 -0
- package/dist/showcase/assets/switch-B_rnbXwy.js +1 -0
- package/dist/showcase/assets/table-BJ9HSK6H.js +1 -0
- package/dist/showcase/assets/table-IB0MEYf4.js +389 -0
- package/dist/showcase/assets/tabs-D02JL-Fa.js +1 -0
- package/dist/showcase/assets/tabs-XpsVS3ff.js +19 -0
- package/dist/showcase/assets/text-button-BWCgXGnr.js +1 -0
- package/dist/showcase/assets/text-link-TzuDnSCF.js +1 -0
- package/dist/showcase/assets/textarea-B7DUIiH_.js +1 -0
- package/dist/showcase/assets/textarea-CV5gNzXf.js +1 -0
- package/dist/showcase/assets/timelines-CF0UYhwm.js +200 -0
- package/dist/showcase/assets/toggle-group-CK8mBx6E.js +1 -0
- package/dist/showcase/assets/toggles-CqJSApnF.js +71 -0
- package/dist/showcase/assets/toggles-group-v0JijMzG.js +32 -0
- package/dist/showcase/assets/trash-2-_xF5j-Ya.js +1 -0
- package/dist/showcase/assets/trending-up-BCzmjYzm.js +1 -0
- package/dist/showcase/assets/truck-CryH-5dx.js +1 -0
- package/dist/showcase/assets/typography-D3PFbRpb.js +215 -0
- package/dist/showcase/assets/ui-badge-ByyFPLOB.js +28 -0
- package/dist/showcase/assets/ui-card-DYLLiD89.js +30 -0
- package/dist/showcase/assets/ui-table-DW4QIwxK.js +42 -0
- package/dist/showcase/assets/upload-tray-ZdL_dzc0.js +138 -0
- package/dist/showcase/assets/useAnchoredPopupScrollLock-AFPLx3SZ.js +1 -0
- package/dist/showcase/assets/useCollapsiblePanel-CeHRY8U2.js +1 -0
- package/dist/showcase/assets/useCompositeItem-C-1zP8zD.js +1 -0
- package/dist/showcase/assets/useCompositeListItem-D4ugfKLB.js +1 -0
- package/dist/showcase/assets/useControlled-Cpg8gDqb.js +1 -0
- package/dist/showcase/assets/useLabelableId-CSxAHpU-.js +1 -0
- package/dist/showcase/assets/useOpenInteractionType-BLV8Pa2n.js +1 -0
- package/dist/showcase/assets/useRender-DparzvOu.js +1 -0
- package/dist/showcase/assets/useTriggerFocusGuards-CrYLO2g5.js +1 -0
- package/dist/showcase/assets/useValueChanged-DwgbaueK.js +1 -0
- package/dist/showcase/assets/user-CGcV8Ppb.js +1 -0
- package/dist/showcase/assets/user-plus-iOsntM6P.js +1 -0
- package/dist/showcase/assets/users-DzgXeZbf.js +1 -0
- package/dist/showcase/assets/vendor-profile-DbFPkGn9.js +37 -0
- package/dist/showcase/assets/wrench-1Ra9xb3d.js +1 -0
- package/dist/showcase/assets/x-CE8oevyh.js +1 -0
- package/dist/showcase/assets/zap-se3n2YVD.js +1 -0
- package/dist/showcase/index.html +4 -3
- package/dist/style.css +2 -2
- package/package.json +14 -3
- package/scripts/audit-consumer.mjs +337 -0
- package/scripts/install-skill.mjs +50 -36
- package/src/App.css +28 -0
- package/dist/_shared/accordion-CztqyaIN.js +0 -130
- package/dist/_shared/accordion-CztqyaIN.js.map +0 -1
- package/dist/_shared/accordion-D5uTCLCB.cjs +0 -2
- package/dist/_shared/accordion-D5uTCLCB.cjs.map +0 -1
- package/dist/_shared/action-menu-Yrj6VzFS.js +0 -96
- package/dist/_shared/action-menu-Yrj6VzFS.js.map +0 -1
- package/dist/_shared/action-menu-eVP8GGlv.cjs +0 -2
- package/dist/_shared/action-menu-eVP8GGlv.cjs.map +0 -1
- package/dist/_shared/ai-artifact-DaHXJTKg.cjs +0 -3
- package/dist/_shared/ai-artifact-DaHXJTKg.cjs.map +0 -1
- package/dist/_shared/ai-artifact-DyLn3JAs.js +0 -1068
- package/dist/_shared/ai-artifact-DyLn3JAs.js.map +0 -1
- package/dist/_shared/alert-BVw4Mq6H.js +0 -48
- package/dist/_shared/alert-BVw4Mq6H.js.map +0 -1
- package/dist/_shared/alert-DXSlR9ja.cjs +0 -2
- package/dist/_shared/alert-DXSlR9ja.cjs.map +0 -1
- package/dist/_shared/avatar-CpBz9pTv.js +0 -52
- package/dist/_shared/avatar-CpBz9pTv.js.map +0 -1
- package/dist/_shared/avatar-dg20YFFs.cjs +0 -2
- package/dist/_shared/avatar-dg20YFFs.cjs.map +0 -1
- package/dist/_shared/badge-BVCh_hfL.js +0 -108
- package/dist/_shared/badge-BVCh_hfL.js.map +0 -1
- package/dist/_shared/badge-C49SSz-6.cjs +0 -2
- package/dist/_shared/badge-C49SSz-6.cjs.map +0 -1
- package/dist/_shared/breadcrumbs-Bo7j5Rhv.cjs +0 -2
- package/dist/_shared/breadcrumbs-Bo7j5Rhv.cjs.map +0 -1
- package/dist/_shared/breadcrumbs-Dc93fqqE.js +0 -111
- package/dist/_shared/breadcrumbs-Dc93fqqE.js.map +0 -1
- package/dist/_shared/button-2xglT7yf.cjs +0 -2
- package/dist/_shared/button-2xglT7yf.cjs.map +0 -1
- package/dist/_shared/button-ChCkwoOD.js +0 -176
- package/dist/_shared/button-ChCkwoOD.js.map +0 -1
- package/dist/_shared/button-D0nF99a9.cjs +0 -2
- package/dist/_shared/button-D0nF99a9.cjs.map +0 -1
- package/dist/_shared/button-DBR4QI9E.js +0 -46
- package/dist/_shared/button-DBR4QI9E.js.map +0 -1
- package/dist/_shared/buttons-Bcnt1md_.js +0 -143
- package/dist/_shared/buttons-Bcnt1md_.js.map +0 -1
- package/dist/_shared/buttons-km9xqXJv.cjs +0 -2
- package/dist/_shared/buttons-km9xqXJv.cjs.map +0 -1
- package/dist/_shared/card-radio-group-BGH93O5-.js +0 -158
- package/dist/_shared/card-radio-group-BGH93O5-.js.map +0 -1
- package/dist/_shared/card-radio-group-Vq741uhL.cjs +0 -2
- package/dist/_shared/card-radio-group-Vq741uhL.cjs.map +0 -1
- package/dist/_shared/chunk-D3uCBrYO.cjs +0 -1
- package/dist/_shared/combobox-BgXAxjU2.js +0 -746
- package/dist/_shared/combobox-BgXAxjU2.js.map +0 -1
- package/dist/_shared/combobox-DuIyh3xJ.cjs +0 -2
- package/dist/_shared/combobox-DuIyh3xJ.cjs.map +0 -1
- package/dist/_shared/command-BbiijN61.js +0 -39
- package/dist/_shared/command-BbiijN61.js.map +0 -1
- package/dist/_shared/command-D7zTvyBJ.cjs +0 -2
- package/dist/_shared/command-D7zTvyBJ.cjs.map +0 -1
- package/dist/_shared/command-DGNtTI-V.cjs +0 -2
- package/dist/_shared/command-DGNtTI-V.cjs.map +0 -1
- package/dist/_shared/command-jKbwFRtS.js +0 -123
- package/dist/_shared/command-jKbwFRtS.js.map +0 -1
- package/dist/_shared/comments-CNUsdwGW.cjs +0 -2
- package/dist/_shared/comments-CNUsdwGW.cjs.map +0 -1
- package/dist/_shared/comments-CvmS7zG3.js +0 -945
- package/dist/_shared/comments-CvmS7zG3.js.map +0 -1
- package/dist/_shared/containers-BFDv7cCV.cjs +0 -2
- package/dist/_shared/containers-BFDv7cCV.cjs.map +0 -1
- package/dist/_shared/containers-C1-A_2PT.js +0 -19
- package/dist/_shared/containers-C1-A_2PT.js.map +0 -1
- package/dist/_shared/content-container-CwqFnaI0.cjs +0 -2
- package/dist/_shared/content-container-CwqFnaI0.cjs.map +0 -1
- package/dist/_shared/content-container-D_3JGBSc.js +0 -33
- package/dist/_shared/content-container-D_3JGBSc.js.map +0 -1
- package/dist/_shared/copyable-CHhCGMfW.js +0 -38
- package/dist/_shared/copyable-CHhCGMfW.js.map +0 -1
- package/dist/_shared/copyable-ndaiocYq.cjs +0 -2
- package/dist/_shared/copyable-ndaiocYq.cjs.map +0 -1
- package/dist/_shared/date-picker-B8O_qbik.js +0 -1353
- package/dist/_shared/date-picker-B8O_qbik.js.map +0 -1
- package/dist/_shared/date-picker-BnOjyuKS.cjs +0 -2
- package/dist/_shared/date-picker-BnOjyuKS.cjs.map +0 -1
- package/dist/_shared/date-pickers-Cas9cPlj.js +0 -330
- package/dist/_shared/date-pickers-Cas9cPlj.js.map +0 -1
- package/dist/_shared/date-pickers-Dk-G3RMy.cjs +0 -2
- package/dist/_shared/date-pickers-Dk-G3RMy.cjs.map +0 -1
- package/dist/_shared/dialog-67GmkMLC.js +0 -101
- package/dist/_shared/dialog-67GmkMLC.js.map +0 -1
- package/dist/_shared/dialog-BF_4uAhE.cjs +0 -2
- package/dist/_shared/dialog-BF_4uAhE.cjs.map +0 -1
- package/dist/_shared/display-B9xVWboG.cjs +0 -8
- package/dist/_shared/display-B9xVWboG.cjs.map +0 -1
- package/dist/_shared/display-BM_GxDAo.js +0 -1237
- package/dist/_shared/display-BM_GxDAo.js.map +0 -1
- package/dist/_shared/dropdown-menu-4nxEBMnd.js +0 -147
- package/dist/_shared/dropdown-menu-4nxEBMnd.js.map +0 -1
- package/dist/_shared/dropdown-menu-DZlWHqWS.cjs +0 -2
- package/dist/_shared/dropdown-menu-DZlWHqWS.cjs.map +0 -1
- package/dist/_shared/form-field-BQlki-8s.js +0 -319
- package/dist/_shared/form-field-BQlki-8s.js.map +0 -1
- package/dist/_shared/form-field-DzpwVS99.cjs +0 -2
- package/dist/_shared/form-field-DzpwVS99.cjs.map +0 -1
- package/dist/_shared/form-sizing-CcbB-OHF.js +0 -21
- package/dist/_shared/form-sizing-CcbB-OHF.js.map +0 -1
- package/dist/_shared/form-sizing-Cw12UeI6.cjs +0 -2
- package/dist/_shared/form-sizing-Cw12UeI6.cjs.map +0 -1
- package/dist/_shared/format-B2AdSQVn.cjs +0 -2
- package/dist/_shared/format-B2AdSQVn.cjs.map +0 -1
- package/dist/_shared/format-CP65h1vK.js +0 -48
- package/dist/_shared/format-CP65h1vK.js.map +0 -1
- package/dist/_shared/forms-B8aaNG44.cjs +0 -2
- package/dist/_shared/forms-B8aaNG44.cjs.map +0 -1
- package/dist/_shared/forms-BusuTZZ2.js +0 -3374
- package/dist/_shared/forms-BusuTZZ2.js.map +0 -1
- package/dist/_shared/header-DWfOUjFL.cjs +0 -2
- package/dist/_shared/header-DWfOUjFL.cjs.map +0 -1
- package/dist/_shared/header-KpdoLtP9.js +0 -369
- package/dist/_shared/header-KpdoLtP9.js.map +0 -1
- package/dist/_shared/heading-BprqyzDs.js +0 -39
- package/dist/_shared/heading-BprqyzDs.js.map +0 -1
- package/dist/_shared/heading-mZc_jan1.cjs +0 -2
- package/dist/_shared/heading-mZc_jan1.cjs.map +0 -1
- package/dist/_shared/hooks-C-uWoRq5.cjs +0 -2
- package/dist/_shared/hooks-C-uWoRq5.cjs.map +0 -1
- package/dist/_shared/hooks-D5HJtvvP.js +0 -118
- package/dist/_shared/hooks-D5HJtvvP.js.map +0 -1
- package/dist/_shared/icon-badge-BBqDyAUz.cjs +0 -2
- package/dist/_shared/icon-badge-BBqDyAUz.cjs.map +0 -1
- package/dist/_shared/icon-badge-Bi63T-bj.js +0 -52
- package/dist/_shared/icon-badge-Bi63T-bj.js.map +0 -1
- package/dist/_shared/input-B2YXTHqz.cjs +0 -2
- package/dist/_shared/input-B2YXTHqz.cjs.map +0 -1
- package/dist/_shared/input-BJb10xb9.cjs +0 -2
- package/dist/_shared/input-BJb10xb9.cjs.map +0 -1
- package/dist/_shared/input-CZxP5Xgj.js +0 -17
- package/dist/_shared/input-CZxP5Xgj.js.map +0 -1
- package/dist/_shared/input-DQahu2sm.js +0 -182
- package/dist/_shared/input-DQahu2sm.js.map +0 -1
- package/dist/_shared/item-Cu5JbZyZ.js +0 -224
- package/dist/_shared/item-Cu5JbZyZ.js.map +0 -1
- package/dist/_shared/item-Cx_7QZ2o.cjs +0 -2
- package/dist/_shared/item-Cx_7QZ2o.cjs.map +0 -1
- package/dist/_shared/mentions-CS3rIhze.js +0 -493
- package/dist/_shared/mentions-CS3rIhze.js.map +0 -1
- package/dist/_shared/mentions-D7gnP3Nf.cjs +0 -2
- package/dist/_shared/mentions-D7gnP3Nf.cjs.map +0 -1
- package/dist/_shared/metadata-CRsVWE8Y.cjs +0 -2
- package/dist/_shared/metadata-CRsVWE8Y.cjs.map +0 -1
- package/dist/_shared/metadata-CfG0FdFZ.js +0 -236
- package/dist/_shared/metadata-CfG0FdFZ.js.map +0 -1
- package/dist/_shared/money-display-Bd0rkjc9.js +0 -198
- package/dist/_shared/money-display-Bd0rkjc9.js.map +0 -1
- package/dist/_shared/money-display-DSFft9Mi.cjs +0 -2
- package/dist/_shared/money-display-DSFft9Mi.cjs.map +0 -1
- package/dist/_shared/navigation-Do9k5Xh1.js +0 -420
- package/dist/_shared/navigation-Do9k5Xh1.js.map +0 -1
- package/dist/_shared/navigation-QAAD3HJd.cjs +0 -2
- package/dist/_shared/navigation-QAAD3HJd.cjs.map +0 -1
- package/dist/_shared/overlays-B8AH8fNv.js +0 -633
- package/dist/_shared/overlays-B8AH8fNv.js.map +0 -1
- package/dist/_shared/overlays-DOcoRy8k.cjs +0 -2
- package/dist/_shared/overlays-DOcoRy8k.cjs.map +0 -1
- package/dist/_shared/page-BPCeKX9X.js +0 -263
- package/dist/_shared/page-BPCeKX9X.js.map +0 -1
- package/dist/_shared/page-DMM32sxi.cjs +0 -2
- package/dist/_shared/page-DMM32sxi.cjs.map +0 -1
- package/dist/_shared/popover-B1f_EUQS.cjs +0 -2
- package/dist/_shared/popover-B1f_EUQS.cjs.map +0 -1
- package/dist/_shared/popover-CgRGcFk9.js +0 -83
- package/dist/_shared/popover-CgRGcFk9.js.map +0 -1
- package/dist/_shared/popover-menu-BEKIT3LR.cjs +0 -2
- package/dist/_shared/popover-menu-BEKIT3LR.cjs.map +0 -1
- package/dist/_shared/popover-menu-BHdHLEVL.js +0 -95
- package/dist/_shared/popover-menu-BHdHLEVL.js.map +0 -1
- package/dist/_shared/rich-text-editor-0uoIoYXU.js +0 -608
- package/dist/_shared/rich-text-editor-0uoIoYXU.js.map +0 -1
- package/dist/_shared/rich-text-editor-wTiARGuB.cjs +0 -2
- package/dist/_shared/rich-text-editor-wTiARGuB.cjs.map +0 -1
- package/dist/_shared/scroll-area-Bo17wtZD.cjs +0 -2
- package/dist/_shared/scroll-area-Bo17wtZD.cjs.map +0 -1
- package/dist/_shared/scroll-area-Cj-hmB5D.js +0 -41
- package/dist/_shared/scroll-area-Cj-hmB5D.js.map +0 -1
- package/dist/_shared/select-07RRiTWc.js +0 -85
- package/dist/_shared/select-07RRiTWc.js.map +0 -1
- package/dist/_shared/select-BfiU7a4n.cjs +0 -2
- package/dist/_shared/select-BfiU7a4n.cjs.map +0 -1
- package/dist/_shared/separator-CN9zAJfs.cjs +0 -2
- package/dist/_shared/separator-CN9zAJfs.cjs.map +0 -1
- package/dist/_shared/separator-DR0uUMKa.js +0 -16
- package/dist/_shared/separator-DR0uUMKa.js.map +0 -1
- package/dist/_shared/sheet-B5FoGJAZ.cjs +0 -2
- package/dist/_shared/sheet-B5FoGJAZ.cjs.map +0 -1
- package/dist/_shared/sheet-cUI8cypP.js +0 -100
- package/dist/_shared/sheet-cUI8cypP.js.map +0 -1
- package/dist/_shared/sidebar-Bq7yKLrG.cjs +0 -2
- package/dist/_shared/sidebar-Bq7yKLrG.cjs.map +0 -1
- package/dist/_shared/sidebar-Da20tCUc.cjs +0 -2
- package/dist/_shared/sidebar-Da20tCUc.cjs.map +0 -1
- package/dist/_shared/sidebar-Q6TYE8Ux.js +0 -371
- package/dist/_shared/sidebar-Q6TYE8Ux.js.map +0 -1
- package/dist/_shared/sidebar-WmnQ55YY.js +0 -537
- package/dist/_shared/sidebar-WmnQ55YY.js.map +0 -1
- package/dist/_shared/skeleton-B3HWEc6G.js +0 -14
- package/dist/_shared/skeleton-B3HWEc6G.js.map +0 -1
- package/dist/_shared/skeleton-Cz_l8-fc.cjs +0 -2
- package/dist/_shared/skeleton-Cz_l8-fc.cjs.map +0 -1
- package/dist/_shared/slot-BgnZtKR5.js +0 -18
- package/dist/_shared/slot-BgnZtKR5.js.map +0 -1
- package/dist/_shared/slot-Dac1ipUC.cjs +0 -2
- package/dist/_shared/slot-Dac1ipUC.cjs.map +0 -1
- package/dist/_shared/smart-card-Bm_VxYUG.cjs +0 -2
- package/dist/_shared/smart-card-Bm_VxYUG.cjs.map +0 -1
- package/dist/_shared/smart-card-MT6JjkoI.js +0 -360
- package/dist/_shared/smart-card-MT6JjkoI.js.map +0 -1
- package/dist/_shared/spinner-BQjxJ_Kx.js +0 -67
- package/dist/_shared/spinner-BQjxJ_Kx.js.map +0 -1
- package/dist/_shared/spinner-Dvaa6GUm.cjs +0 -2
- package/dist/_shared/spinner-Dvaa6GUm.cjs.map +0 -1
- package/dist/_shared/switch-C0yyhsXZ.js +0 -51
- package/dist/_shared/switch-C0yyhsXZ.js.map +0 -1
- package/dist/_shared/switch-DozkSQNn.cjs +0 -2
- package/dist/_shared/switch-DozkSQNn.cjs.map +0 -1
- package/dist/_shared/text-DBnY6fcL.cjs +0 -2
- package/dist/_shared/text-DBnY6fcL.cjs.map +0 -1
- package/dist/_shared/text-DIxMTECE.js +0 -74
- package/dist/_shared/text-DIxMTECE.js.map +0 -1
- package/dist/_shared/textarea-Cgl-FPwu.js +0 -119
- package/dist/_shared/textarea-Cgl-FPwu.js.map +0 -1
- package/dist/_shared/textarea-D8wC0XlZ.cjs +0 -2
- package/dist/_shared/textarea-D8wC0XlZ.cjs.map +0 -1
- package/dist/_shared/tooltip-Cws4BiPT.js +0 -49
- package/dist/_shared/tooltip-Cws4BiPT.js.map +0 -1
- package/dist/_shared/tooltip-DyUi-Tac.cjs +0 -2
- package/dist/_shared/tooltip-DyUi-Tac.cjs.map +0 -1
- package/dist/_shared/typography-BW7iZBx7.cjs +0 -2
- package/dist/_shared/typography-BW7iZBx7.cjs.map +0 -1
- package/dist/_shared/typography-a3hydyvI.js +0 -102
- package/dist/_shared/typography-a3hydyvI.js.map +0 -1
- package/dist/_shared/ui-provider-4qKSKMPd.js +0 -85
- package/dist/_shared/ui-provider-4qKSKMPd.js.map +0 -1
- package/dist/_shared/ui-provider-uiQgATj1.cjs +0 -2
- package/dist/_shared/ui-provider-uiQgATj1.cjs.map +0 -1
- package/dist/showcase/assets/AreaChart-CJ57G5Ub.js +0 -6
- package/dist/showcase/assets/CSPContext-BA7DfnCI.js +0 -1
- package/dist/showcase/assets/CompositeItem-PwzgE4va.js +0 -1
- package/dist/showcase/assets/CompositeRoot-Du4CMlK7.js +0 -1
- package/dist/showcase/assets/Control.FullScreen-B9vseC57.js +0 -1
- package/dist/showcase/assets/DialogTrigger-FkENgwo6.js +0 -1
- package/dist/showcase/assets/FormContext-ChygLayp.js +0 -1
- package/dist/showcase/assets/PreviewLayout-z6vpJJGt.js +0 -1
- package/dist/showcase/assets/RadioGroup-CcDmbxOw.js +0 -1
- package/dist/showcase/assets/Separator-Dk4eN76U.js +0 -1
- package/dist/showcase/assets/ToolbarRootContext-D_KAA5hZ.js +0 -1
- package/dist/showcase/assets/accordion-dQszzfmw.js +0 -172
- package/dist/showcase/assets/accordion-variants-Dp4wxic-.js +0 -1
- package/dist/showcase/assets/action-menu-CBi2Eiy0.js +0 -1
- package/dist/showcase/assets/activities-DoXsgP4G.js +0 -501
- package/dist/showcase/assets/activities-feed-card-xz5FtkOm.js +0 -1
- package/dist/showcase/assets/admin-CxklUqAG.js +0 -80
- package/dist/showcase/assets/ai-artifact-DkhUdEbM.js +0 -2
- package/dist/showcase/assets/ai-chat-B6PuqkEu.js +0 -568
- package/dist/showcase/assets/ai-elements-D_rpj_ds.js +0 -379
- package/dist/showcase/assets/ai-new-CUPrAbOK.js +0 -167
- package/dist/showcase/assets/ai-tool-call-CEr-dGVx.js +0 -1
- package/dist/showcase/assets/ai-zxF_msJF.js +0 -41
- package/dist/showcase/assets/alert-771BE3Ny.js +0 -59
- package/dist/showcase/assets/alert-CG42DAlX.js +0 -1
- package/dist/showcase/assets/api-key-list-D6jUN7Fq.js +0 -73
- package/dist/showcase/assets/arrow-down-CUoXUyN1.js +0 -1
- package/dist/showcase/assets/arrow-left-Cdq69X6h.js +0 -1
- package/dist/showcase/assets/arrow-right-i25q9L2H.js +0 -1
- package/dist/showcase/assets/arrow-up-pnezegnF.js +0 -1
- package/dist/showcase/assets/arrow-up-right-CK3XnMah.js +0 -1
- package/dist/showcase/assets/avatar-LPmQqZQv.js +0 -1
- package/dist/showcase/assets/avatar-ZVFIQouy.js +0 -57
- package/dist/showcase/assets/badge-DK4bsgZC.js +0 -28
- package/dist/showcase/assets/badge-check-Cw5gkVcG.js +0 -1
- package/dist/showcase/assets/bell-BvJELoaV.js +0 -1
- package/dist/showcase/assets/bot-DRj6sdSR.js +0 -1
- package/dist/showcase/assets/box-BNND3M2m.js +0 -1
- package/dist/showcase/assets/brain-Cy3o-12l.js +0 -1
- package/dist/showcase/assets/brand-DvipEpFn.js +0 -40
- package/dist/showcase/assets/breadcrumb-B-LNuOyv.js +0 -1
- package/dist/showcase/assets/breadcrumb-Lzpc0yo4.js +0 -52
- package/dist/showcase/assets/breadcrumbs-DD6msKFZ.js +0 -1
- package/dist/showcase/assets/briefcase-LcAwoEmu.js +0 -1
- package/dist/showcase/assets/button-CuwcGzk1.js +0 -44
- package/dist/showcase/assets/button-group-CAImjDrl.js +0 -1
- package/dist/showcase/assets/buttons-DTjNHCMl.js +0 -259
- package/dist/showcase/assets/calendar-B1zW0q6I.js +0 -1
- package/dist/showcase/assets/calendar-Dlv72ytt.js +0 -1
- package/dist/showcase/assets/calendar-ls2A08Pn.js +0 -16
- package/dist/showcase/assets/card-BhtkM1BT.js +0 -1
- package/dist/showcase/assets/cards-BRpRXzGk.js +0 -328
- package/dist/showcase/assets/chart-column-BpQkEi1H.js +0 -1
- package/dist/showcase/assets/chevron-down-DyObdfSb.js +0 -1
- package/dist/showcase/assets/chevron-left-T7dHNxYM.js +0 -1
- package/dist/showcase/assets/chevron-right-D_EcqHpT.js +0 -1
- package/dist/showcase/assets/chevron-up-B38ivdGO.js +0 -1
- package/dist/showcase/assets/chevrons-up-down-SdRARzoq.js +0 -1
- package/dist/showcase/assets/circle-BrCPAmDA.js +0 -1
- package/dist/showcase/assets/circle-alert-DdhzLPY_.js +0 -1
- package/dist/showcase/assets/circle-check-DlA6zidQ.js +0 -1
- package/dist/showcase/assets/circle-check-big-DFGJANQF.js +0 -1
- package/dist/showcase/assets/circle-dot-BKmnVUqM.js +0 -1
- package/dist/showcase/assets/circle-question-mark-BNREvgVC.js +0 -1
- package/dist/showcase/assets/circle-x-C45QjHEs.js +0 -1
- package/dist/showcase/assets/clock-D1nKQzQo.js +0 -1
- package/dist/showcase/assets/code-xml-B8N3GRSu.js +0 -1
- package/dist/showcase/assets/collapsible-4TfcWyNs.js +0 -1
- package/dist/showcase/assets/collapsible-CKbZtvTj.js +0 -27
- package/dist/showcase/assets/combobox-DTdGPaU0.js +0 -622
- package/dist/showcase/assets/command-DymTXwL1.js +0 -1
- package/dist/showcase/assets/command-ksVIHQKJ.js +0 -45
- package/dist/showcase/assets/comment-composer-DC9oS1Yy.js +0 -1
- package/dist/showcase/assets/comment-item-CAmKnJa7.js +0 -1
- package/dist/showcase/assets/comments-Benk-2mV.js +0 -349
- package/dist/showcase/assets/commerce-Qz-mq8mQ.js +0 -78
- package/dist/showcase/assets/commerce-extras-CQRc3Bna.js +0 -179
- package/dist/showcase/assets/composite-DBDXLPyz.js +0 -1
- package/dist/showcase/assets/contact-card-DkL2nI3r.js +0 -65
- package/dist/showcase/assets/content-container-mRm6oJEa.js +0 -1
- package/dist/showcase/assets/copyable-DmLlmwzy.js +0 -96
- package/dist/showcase/assets/course-card-CJJoeZj9.js +0 -113
- package/dist/showcase/assets/cpu-BXJnF2Xy.js +0 -1
- package/dist/showcase/assets/credit-card-BQK3KKb2.js +0 -1
- package/dist/showcase/assets/currency-DBPUh8ee.js +0 -149
- package/dist/showcase/assets/dark-surfaces-LpPuIeYy.js +0 -90
- package/dist/showcase/assets/database-BZerpzGE.js +0 -1
- package/dist/showcase/assets/date-block-iiHUpbNX.js +0 -1
- package/dist/showcase/assets/date-picker-BQeBGL7T.js +0 -1
- package/dist/showcase/assets/date-pickers-CKcUEMMF.js +0 -110
- package/dist/showcase/assets/dense-info-DATmxRU8.js +0 -106
- package/dist/showcase/assets/dialog-Bqu5KDYH.js +0 -1
- package/dist/showcase/assets/display-Bj7uPXD4.js +0 -392
- package/dist/showcase/assets/dist-QK7JxeYv.js +0 -1
- package/dist/showcase/assets/dollar-sign-DFZs6vfz.js +0 -1
- package/dist/showcase/assets/download-5oGw_WbW.js +0 -1
- package/dist/showcase/assets/dropdown-menu-1CJgYn0S.js +0 -1
- package/dist/showcase/assets/dropzone-Co1uhsDn.js +0 -1
- package/dist/showcase/assets/ellipsis-cKRcvuyL.js +0 -1
- package/dist/showcase/assets/ellipsis-vertical-B1RErEkj.js +0 -1
- package/dist/showcase/assets/empty-Y2-4nCBr.js +0 -1
- package/dist/showcase/assets/empty-item-USa6xcUv.js +0 -49
- package/dist/showcase/assets/empty-state-DfhZ9AT5.js +0 -188
- package/dist/showcase/assets/enhanced-activities-DmAPVUSu.js +0 -359
- package/dist/showcase/assets/esm-BeGQ_ZTM.js +0 -2
- package/dist/showcase/assets/event-calendar-D-jGrrZS.js +0 -138
- package/dist/showcase/assets/event-log-tA_i4eR9.js +0 -326
- package/dist/showcase/assets/example-6phCHGsN.js +0 -1
- package/dist/showcase/assets/external-link-BuVHkCy0.js +0 -1
- package/dist/showcase/assets/eye-DC5HfGm6.js +0 -1
- package/dist/showcase/assets/feature-announcement-DwvxLytd.js +0 -34
- package/dist/showcase/assets/fetchers-SLCIqgnM.js +0 -1
- package/dist/showcase/assets/file-D-xM4vLy.js +0 -1
- package/dist/showcase/assets/file-text-tmG5vNbr.js +0 -1
- package/dist/showcase/assets/filters-CrGRXmq6.js +0 -78
- package/dist/showcase/assets/flag-CWrEtkY5.js +0 -1
- package/dist/showcase/assets/folder-open-Br-x1pjP.js +0 -1
- package/dist/showcase/assets/form-sizing-Bb5hiM45.js +0 -1
- package/dist/showcase/assets/format-D_ETCyg4.js +0 -1
- package/dist/showcase/assets/format-metric-value-cyOYS377.js +0 -1
- package/dist/showcase/assets/forms-B_MkQ3rm.js +0 -790
- package/dist/showcase/assets/generic-CdmsyXV3.js +0 -1
- package/dist/showcase/assets/getPseudoElementBounds-CZnCbCFP.js +0 -1
- package/dist/showcase/assets/gift-NkuklfU2.js +0 -1
- package/dist/showcase/assets/giftcard-cards-BAvevZ0i.js +0 -85
- package/dist/showcase/assets/git-branch-B_CBqPeO.js +0 -1
- package/dist/showcase/assets/global-search-D9teAbPe.js +0 -90
- package/dist/showcase/assets/globe-gzw45GU2.js +0 -1
- package/dist/showcase/assets/gradient-card-Xk2r7R5H.js +0 -58
- package/dist/showcase/assets/header-notifications-_aZCpE5A.js +0 -1
- package/dist/showcase/assets/heart-CEMKbRaZ.js +0 -1
- package/dist/showcase/assets/house-BlGXAcMH.js +0 -1
- package/dist/showcase/assets/icon-badge-z6N9reH_.js +0 -1
- package/dist/showcase/assets/image-B8mzmVBr.js +0 -1
- package/dist/showcase/assets/inbox-qdSnP4UV.js +0 -1
- package/dist/showcase/assets/index-B4ubXfly.js +0 -10
- package/dist/showcase/assets/index-Cu3Ssz5r.css +0 -2
- package/dist/showcase/assets/inertValue-D5Q8cLku.js +0 -1
- package/dist/showcase/assets/info-DBvvNjc_.js +0 -1
- package/dist/showcase/assets/inline-stat-Bm1zVT8D.js +0 -1
- package/dist/showcase/assets/input-CBQR0aeX.js +0 -1
- package/dist/showcase/assets/input-OrUzpI55.js +0 -1
- package/dist/showcase/assets/input-group-DhqOen2N.js +0 -47
- package/dist/showcase/assets/input-group-l8xa5nUq.js +0 -1
- package/dist/showcase/assets/inputs-DbiJ0qy2.js +0 -49
- package/dist/showcase/assets/invoice-header-C6youIbL.js +0 -36
- package/dist/showcase/assets/invoice-items-g6dgryF-.js +0 -36
- package/dist/showcase/assets/invoice-mini-0iWhufpt.js +0 -14
- package/dist/showcase/assets/invoice-table-Bvdh3rRq.js +0 -30
- package/dist/showcase/assets/isSameDay-BpZEtJe8.js +0 -1
- package/dist/showcase/assets/isToday-F0CS28oK.js +0 -1
- package/dist/showcase/assets/italic-CJOEwjdc.js +0 -1
- package/dist/showcase/assets/item-BiMm1PPB.js +0 -1
- package/dist/showcase/assets/item-CN0cwdj_.js +0 -1
- package/dist/showcase/assets/item-DNqEUYLT.js +0 -117
- package/dist/showcase/assets/kanban-DxePEUiQ.js +0 -175
- package/dist/showcase/assets/label-Dx4WO-fg.js +0 -1
- package/dist/showcase/assets/layout-containers-DDl8rG8S.js +0 -96
- package/dist/showcase/assets/layout-header-Bu6IcDWu.js +0 -170
- package/dist/showcase/assets/layout-page-D-88Qnoy.js +0 -122
- package/dist/showcase/assets/layout-sidebar-Ctft10pk.js +0 -224
- package/dist/showcase/assets/layout-users-DtbZduBG.js +0 -104
- package/dist/showcase/assets/leaflet-src-9EZQ14iG.js +0 -1
- package/dist/showcase/assets/lib-D9BoOYUd.js +0 -1
- package/dist/showcase/assets/lock-CHurDI0n.js +0 -1
- package/dist/showcase/assets/mail-DZ1o1RLW.js +0 -1
- package/dist/showcase/assets/map-C8xiyT9X.js +0 -124
- package/dist/showcase/assets/map-pin-CAKaoYod.js +0 -1
- package/dist/showcase/assets/menus-C6mnp636.js +0 -89
- package/dist/showcase/assets/message-square-Zo5J_zU1.js +0 -1
- package/dist/showcase/assets/metadata-list-W83-UMhc.js +0 -278
- package/dist/showcase/assets/metric-BSvxidIX.js +0 -1
- package/dist/showcase/assets/metric-grid-Dtqx_3Lg.js +0 -1
- package/dist/showcase/assets/metric-trend-chip-mtvcJ_M9.js +0 -1
- package/dist/showcase/assets/metrics-analytics-bar-DQbyss7i.js +0 -44
- package/dist/showcase/assets/metrics-analytics-cards-CEBu5Uw0.js +0 -77
- package/dist/showcase/assets/metrics-comparison-Bs-R6v4y.js +0 -76
- package/dist/showcase/assets/metrics-heatmap-BKHWH8sM.js +0 -27
- package/dist/showcase/assets/metrics-inline-badge-BxVn0Y2p.js +0 -17
- package/dist/showcase/assets/metrics-kpi-row-DtACYEds.js +0 -31
- package/dist/showcase/assets/metrics-micro-grid-BkwUGOUR.js +0 -42
- package/dist/showcase/assets/metrics-overview-BAtrlzsI.js +0 -192
- package/dist/showcase/assets/metrics-stat-cards-iCRCNyHY.js +0 -54
- package/dist/showcase/assets/minus-C6eBW-2t.js +0 -1
- package/dist/showcase/assets/money-display-DjGRJ16l.js +0 -1
- package/dist/showcase/assets/month-year-picker-DTDebPqf.js +0 -1
- package/dist/showcase/assets/navigation-BrG8Chig.js +0 -86
- package/dist/showcase/assets/navigation-CfXQJbyM.js +0 -230
- package/dist/showcase/assets/navigation-extras-D_gzLlZ5.js +0 -43
- package/dist/showcase/assets/onboarding-checklist-1EerUwAo.js +0 -119
- package/dist/showcase/assets/overlays-2AB9-S1Z.js +0 -88
- package/dist/showcase/assets/overlays-CYt9o3Xq.js +0 -393
- package/dist/showcase/assets/package-BJMP-Fcr.js +0 -1
- package/dist/showcase/assets/page-action-button-BZxJ0X1j.js +0 -1
- package/dist/showcase/assets/page-header-B_rqHJhe.js +0 -1
- package/dist/showcase/assets/pagination-BHiQvvka.js +0 -1
- package/dist/showcase/assets/pagination-Dq0GruQd.js +0 -42
- package/dist/showcase/assets/paperclip-BMYKrUQo.js +0 -1
- package/dist/showcase/assets/pencil-BJ3VS_FO.js +0 -1
- package/dist/showcase/assets/phone-CsRIyvep.js +0 -1
- package/dist/showcase/assets/plus-D2JuXYLg.js +0 -1
- package/dist/showcase/assets/popover-DNT9755r.js +0 -1
- package/dist/showcase/assets/popover-KvGgcPNg.js +0 -1
- package/dist/showcase/assets/popover-menu-CJx30R65.js +0 -1
- package/dist/showcase/assets/progress-B7WuXcJR.js +0 -1
- package/dist/showcase/assets/progress-CweCSAUv.js +0 -18
- package/dist/showcase/assets/props-table-uDY4eIzt.js +0 -1
- package/dist/showcase/assets/props.generated-BqPfiNI-.json +0 -32423
- package/dist/showcase/assets/quote-DAyyfzQd.js +0 -1
- package/dist/showcase/assets/receipt-C0mMZGbF.js +0 -1
- package/dist/showcase/assets/refresh-cw-X06JbXb-.js +0 -1
- package/dist/showcase/assets/resolveValueLabel-Bks7UDko.js +0 -1
- package/dist/showcase/assets/rich-text-editor-QJsb-qIe.js +0 -124
- package/dist/showcase/assets/rich-text-editor-h07VBNI9.js +0 -141
- package/dist/showcase/assets/rotate-ccw-D84bdX_x.js +0 -1
- package/dist/showcase/assets/scroll-area-0rT06pXZ.js +0 -1
- package/dist/showcase/assets/scroll-area-YXwdzGpN.js +0 -32
- package/dist/showcase/assets/select-BoWQDtUf.js +0 -1
- package/dist/showcase/assets/send-DJsk3cr1.js +0 -1
- package/dist/showcase/assets/separator-CLSnRcJa.js +0 -28
- package/dist/showcase/assets/separator-DWv-twD-.js +0 -1
- package/dist/showcase/assets/settings-Cb2MsAmN.js +0 -1
- package/dist/showcase/assets/sheet-Dn1-MYus.js +0 -1
- package/dist/showcase/assets/shield-DwLjF5ch.js +0 -1
- package/dist/showcase/assets/shield-alert-D8i6gzMK.js +0 -1
- package/dist/showcase/assets/shield-check-D5YRSBIz.js +0 -1
- package/dist/showcase/assets/shopping-bag-BqlAP4vn.js +0 -1
- package/dist/showcase/assets/sidebar.context-BAp_pBEB.js +0 -1
- package/dist/showcase/assets/skeleton-CeNPp4hr.js +0 -1
- package/dist/showcase/assets/skeleton-QPsnM_NR.js +0 -29
- package/dist/showcase/assets/smart-card-BisUbLPt.js +0 -1
- package/dist/showcase/assets/sonner-B7GzbBK2.js +0 -22
- package/dist/showcase/assets/sortable.esm-BDcEOHT7.js +0 -5
- package/dist/showcase/assets/sparkles-CF9P5Tqh.js +0 -1
- package/dist/showcase/assets/spinner-BeamEyJd.js +0 -49
- package/dist/showcase/assets/spinner-DoYBfalR.js +0 -1
- package/dist/showcase/assets/spinner-UsLsOYzn.js +0 -30
- package/dist/showcase/assets/square-pen-BGTVdnt1.js +0 -1
- package/dist/showcase/assets/stacked-avatars-BWfVX1Ov.js +0 -1
- package/dist/showcase/assets/star-NsPNO9gR.js +0 -1
- package/dist/showcase/assets/startOfDay-zJBpxLuW.js +0 -1
- package/dist/showcase/assets/styles-DA7a7hVy.js +0 -1
- package/dist/showcase/assets/switch-C62S4U2o.js +0 -1
- package/dist/showcase/assets/switch-CYQcinJZ.js +0 -1
- package/dist/showcase/assets/table-w4IABkpa.js +0 -1
- package/dist/showcase/assets/table-xgB63UrY.js +0 -390
- package/dist/showcase/assets/tabs-BFTEaTXj.js +0 -19
- package/dist/showcase/assets/tabs-oMJn9Ujq.js +0 -1
- package/dist/showcase/assets/text-button-BgcutPuu.js +0 -1
- package/dist/showcase/assets/text-link-CS9thOWL.js +0 -1
- package/dist/showcase/assets/textarea-BOBx4EM6.js +0 -1
- package/dist/showcase/assets/textarea-CTzYZZqa.js +0 -1
- package/dist/showcase/assets/timelines-CK07mEBK.js +0 -186
- package/dist/showcase/assets/toggle-group-CSPdPT6G.js +0 -1
- package/dist/showcase/assets/toggles-DDSdl-gA.js +0 -71
- package/dist/showcase/assets/toggles-group-Y2BdKEFB.js +0 -32
- package/dist/showcase/assets/trash-2-C-FAptQP.js +0 -1
- package/dist/showcase/assets/trending-up-BmLhdF_w.js +0 -1
- package/dist/showcase/assets/truck-pZdUS_as.js +0 -1
- package/dist/showcase/assets/typography-CnBH2z7f.js +0 -214
- package/dist/showcase/assets/ui-badge-Cl6INRO5.js +0 -28
- package/dist/showcase/assets/ui-card-B5P-thNu.js +0 -30
- package/dist/showcase/assets/ui-table-B32RILKk.js +0 -42
- package/dist/showcase/assets/upload-tray-mu6bR2ZE.js +0 -138
- package/dist/showcase/assets/useAnchoredPopupScrollLock-CzDaXxmM.js +0 -1
- package/dist/showcase/assets/useCollapsiblePanel-B0DZvDFu.js +0 -1
- package/dist/showcase/assets/useCompositeItem-BVIVLT9X.js +0 -1
- package/dist/showcase/assets/useCompositeListItem-JEMeTFPx.js +0 -1
- package/dist/showcase/assets/useControlled-ZjqBfPCn.js +0 -1
- package/dist/showcase/assets/useLabelableId-D8CZq8Bm.js +0 -1
- package/dist/showcase/assets/useOpenInteractionType-CopGCf3q.js +0 -1
- package/dist/showcase/assets/useRender-zuKv6JQF.js +0 -1
- package/dist/showcase/assets/useRole-08KeyiD3.js +0 -1
- package/dist/showcase/assets/useTriggerFocusGuards-DEuz5CGe.js +0 -1
- package/dist/showcase/assets/useValueChanged-BxFi_qyj.js +0 -1
- package/dist/showcase/assets/user-Bgc2t2_e.js +0 -1
- package/dist/showcase/assets/user-plus-F_TfagnP.js +0 -1
- package/dist/showcase/assets/users-B7G4yTCR.js +0 -1
- package/dist/showcase/assets/vendor-profile-BTQmsKM6.js +0 -37
- package/dist/showcase/assets/wrench-BdzICmjR.js +0 -1
- package/dist/showcase/assets/x-B156Wr-5.js +0 -1
- package/dist/showcase/assets/zap-B3iByjNV.js +0 -1
- /package/dist/showcase/assets/{analytics.strings-BcotPUad.js → analytics.strings-B9262Jmq.js} +0 -0
- /package/dist/showcase/assets/{chunk-CilyBKbf.js → chunk-QTnfLwEv.js} +0 -0
- /package/dist/showcase/assets/{customers-BETQwFRp.js → customers-DvBxRjHv.js} +0 -0
- /package/dist/showcase/assets/{format-DoQ4Wqkq.js → format-C_LjuBUs.js} +0 -0
- /package/dist/showcase/assets/{isElementDisabled-BLmk_uhf.js → isElementDisabled-KSuuBj8D.js} +0 -0
- /package/dist/showcase/assets/{leaflet.draw-CwFqqsDc.js → leaflet.draw-lpeKTWFs.js} +0 -0
- /package/dist/showcase/assets/{orders-DNn7r9k_.js → orders-BFwWtubb.js} +0 -0
- /package/dist/showcase/assets/{resolveAriaLabelledBy-DmY5COAB.js → resolveAriaLabelledBy-B6CR9UP2.js} +0 -0
- /package/dist/showcase/assets/{valueToPercent-CDF3aNnc.js → valueToPercent-B5BHWU68.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":[],"sources":["../../../../src/components/features/filters/filters.strings.ts","../../../../src/components/features/filters/filters.types.ts","../../../../src/components/features/filters/operator-options.ts","../../../../src/components/features/filters/utils/filter-utils.ts","../../../../src/components/features/filters/filter-context.tsx","../../../../src/components/features/filters/hooks/use-filter-groups.ts","../../../../src/components/features/filters/partials/filter-operator-select.tsx","../../../../src/components/features/filters/partials/filter-value-display.tsx","../../../../src/components/features/filters/partials/active-filter-item.tsx","../../../../src/hooks/use-debounce.ts","../../../../src/components/features/filters/hooks/use-async-options.ts","../../../../src/components/features/filters/partials/async-filter-content.tsx","../../../../src/components/features/filters/facets/date-facet.tsx","../../../../src/components/features/filters/partials/date-filter-content.tsx","../../../../src/components/features/filters/partials/filter-error-boundary.tsx","../../../../src/components/features/filters/partials/filter-list-item.tsx","../../../../src/components/features/filters/partials/filter-list-content.tsx","../../../../src/components/features/filters/partials/regular-filter-content.tsx","../../../../src/components/features/filters/facets/tags-facet.tsx","../../../../src/components/features/filters/partials/tags-filter-content.tsx","../../../../src/components/features/filters/partials/filter-popover-content.tsx","../../../../src/components/features/filters/partials/filter-pill.tsx","../../../../src/components/features/filters/partials/filters-button.tsx","../../../../src/components/features/filters/partials/filter-tabs.tsx","../../../../src/components/features/filters/facets/search-facet.tsx","../../../../src/components/features/filters/partials/search-filters-list.tsx","../../../../src/components/features/filters/filter-layout.tsx","../../../../src/components/features/filters/facets/select-facet.tsx","../../../../src/components/features/filters/facets/async-select-facet.tsx","../../../../src/components/features/filters/facets/range-facet.tsx","../../../../src/components/features/filters/validators.ts"],"sourcesContent":["/**\n * Filter strings — default copy and nested override contract.\n *\n * Consumers localize filters by passing `strings` to `<FilterProvider>`.\n * No routing, framework i18n hook, or backend shared-props contract belongs in\n * this default feature path.\n */\n\nexport interface FilterOperatorStrings {\n contains: string;\n equals: string;\n notContains: string;\n is: string;\n isNot: string;\n greaterThan: string;\n lessThan: string;\n before: string;\n after: string;\n between: string;\n has: string;\n hasAny: string;\n hasAll: string;\n}\n\nexport interface FilterStrings {\n // Filter loading states\n loading: string;\n loadingOptions: string; // \"Loading {filterLabel} options...\"\n\n // Action buttons\n clear: string;\n confirm: string;\n clearFilters: string;\n clearAll: string;\n\n // Date selection\n selectDate: string;\n selectDateRange: string;\n calendar: {\n dateSelected: string;\n notDateSelected: string;\n notDateRangeSelected: string;\n selectedEndDate: string;\n today: string;\n yesterday: string;\n lastSevenDays: string;\n lastThirtyDays: string;\n thisMonth: string;\n lastMonth: string;\n thisYear: string;\n lastYear: string;\n customRange: string;\n };\n\n // Value selection\n selectValues: string;\n searchPlaceholder: string; // \"Search {filterLabel}...\"\n noOptionsFound: string;\n selected: string; // \"{count} {filterLabel} selected\"\n nothingSelected: string; // pill value text when nothing has been picked yet\n\n // Tags\n enterTag: string;\n addTag: string;\n removeTag: string;\n tag: string;\n tags: string;\n enterTags: string;\n\n // Filter list\n searchFilters: string;\n noFiltersAvailable: string;\n availableFilters: string;\n activeFilters: string;\n clearSearch: string;\n backToFilters: string;\n select: string;\n options: string;\n\n // Operator selector (active-filter pill dropdown)\n operator: string;\n operators: FilterOperatorStrings;\n\n // Range filters\n min: string;\n max: string;\n\n // Async select filters\n fetchError: string;\n retryFetch: string;\n minQueryHint: string; // \"Type at least {min} characters...\"\n searching: string;\n\n // Error boundary\n error: {\n title: string;\n descriptionWithKey: string;\n generic: string;\n unknown: string;\n };\n\n // Value validation\n validation: {\n required: string;\n minValue: string;\n maxValue: string;\n invalidFormat: string;\n };\n}\n\n/**\n * Default English strings for the filter system.\n * These serve as fallbacks when no strings are provided.\n */\nexport const defaultFilterStrings: FilterStrings = {\n // Filter loading states\n loading: 'Loading',\n loadingOptions: 'Loading {filterLabel} options...',\n\n // Action buttons\n clear: 'Clear',\n confirm: 'Confirm',\n clearFilters: 'Clear filters',\n clearAll: 'Clear all',\n\n // Date selection\n selectDate: 'Select date',\n selectDateRange: 'Select date range',\n calendar: {\n dateSelected: 'Date selected',\n notDateSelected: 'No date selected',\n notDateRangeSelected: 'No date range selected',\n selectedEndDate: 'Select end date',\n today: 'Today',\n yesterday: 'Yesterday',\n lastSevenDays: 'Last 7 days',\n lastThirtyDays: 'Last 30 days',\n thisMonth: 'This month',\n lastMonth: 'Last month',\n thisYear: 'This year',\n lastYear: 'Last year',\n customRange: 'Custom range',\n },\n\n // Value selection\n selectValues: 'Select values',\n searchPlaceholder: 'Search {filterLabel}...',\n noOptionsFound: 'No options found',\n selected: '{count} {filterLabel} selected',\n nothingSelected: 'Nothing selected',\n\n // Tags\n enterTag: 'Enter tag',\n addTag: 'Add tag',\n removeTag: 'Remove',\n tag: 'tag',\n tags: 'tags',\n enterTags: 'Enter tags',\n\n // Filter list\n searchFilters: 'Search filters...',\n noFiltersAvailable: 'No filters available',\n availableFilters: 'Available Filters',\n activeFilters: 'Active Filters',\n clearSearch: 'Clear search',\n backToFilters: 'Back to filters',\n select: 'Select',\n options: 'options',\n\n // Operator selector (active-filter pill dropdown)\n operator: 'Operator',\n operators: {\n contains: 'contains',\n equals: 'is',\n notContains: 'does not contain',\n is: 'is',\n isNot: 'is not',\n greaterThan: 'greater than',\n lessThan: 'less than',\n before: 'before',\n after: 'after',\n between: 'between',\n has: 'has',\n hasAny: 'has any',\n hasAll: 'has all',\n },\n\n // Range filters\n min: 'Min',\n max: 'Max',\n\n // Async select filters\n fetchError: 'Failed to load options',\n retryFetch: 'Retry',\n minQueryHint: 'Type at least {min} characters...',\n searching: 'Searching...',\n\n // Error boundary\n error: {\n title: 'Filter error',\n descriptionWithKey: 'There was a problem with \"{filterKey}\" filter.',\n generic: 'There was a problem loading this filter.',\n unknown: 'Unknown error',\n },\n\n // Value validation\n validation: {\n required: 'This filter is required',\n minValue: 'Value must be at least {min}',\n maxValue: 'Value must be at most {max}',\n invalidFormat: 'Invalid format',\n },\n};\n\n/**\n * Helper function to interpolate values in strings.\n * Replaces {key} with the corresponding value from the params object.\n */\nexport function interpolateFilterString(\n template: string,\n params: Record<string, string | number>,\n): string {\n const withCurlyPlaceholders = template.replace(/{(\\w+)}/g, (match, key) => {\n return String(params[key] ?? match);\n });\n\n const withColonPlaceholdersReplaced = withCurlyPlaceholders.replace(\n /:(\\w+)/g,\n (match, key) => {\n return params[key] !== undefined ? String(params[key]) : match;\n },\n );\n\n return withColonPlaceholdersReplaced;\n}\n\n/**\n * Helper function to get a string from a strings object\n * with dot notation support.\n */\nexport function getFilterString(\n strings: FilterStrings,\n path: string,\n params?: Record<string, string | number>,\n): string {\n const keys = path.split('.');\n let result: unknown = strings;\n\n for (const key of keys) {\n if (result == null || typeof result !== 'object') {\n return path; // Return the path if the string is not found\n }\n result = (result as Record<string, unknown>)[key];\n }\n\n if (typeof result === 'string') {\n return params ? interpolateFilterString(result, params) : result;\n }\n\n return path; // Return the path if the string is not found\n}\n","import type { ReactNode } from 'react';\n\n/** Shared height class for all filter control elements. */\nexport const FILTER_ELEMENT_HEIGHT = 'h-8';\n\n/**\n * Core type definitions and interfaces for the filters feature.\n *\n * This file defines:\n * - Filter types (SELECT, MULTI_SELECT, SEARCH, RANGE, DATE)\n * - Filter operators (equals, contains, in, etc.)\n * - Configuration interfaces for filters\n * - Context value types for filter state management\n * - Validation and display configuration types\n *\n * These types are used throughout the filters feature to ensure type safety\n * and consistent data structures.\n */\n\nexport const FilterType = {\n SELECT: 'select',\n MULTI_SELECT: 'multi_select',\n ASYNC_SELECT: 'async_select',\n SEARCH: 'search',\n RANGE: 'range',\n DATE: 'date',\n TAGS: 'tags',\n} as const;\n\nexport type FilterType = (typeof FilterType)[keyof typeof FilterType];\n\n// Convert string union to enum for better type safety and autocompletion\n// Note: All enum values are used via the FilterOperator type below, even if not directly referenced\nexport const FilterOperatorEnum = {\n EQUALS: 'equals',\n CONTAINS: 'contains',\n IN: 'in',\n NOT_IN: 'not_in',\n NOT: 'not',\n BEFORE: 'before',\n AFTER: 'after',\n BETWEEN: 'between',\n GT: 'gt',\n LT: 'lt',\n GTE: 'gte',\n LTE: 'lte',\n HAS: 'has',\n HAS_ANY: 'has_any',\n HAS_ALL: 'has_all',\n} as const;\n\n// Strict type for better type safety - using enum values to match backend\nexport type FilterOperator = (typeof FilterOperatorEnum)[keyof typeof FilterOperatorEnum];\n\nexport interface OperatorOption {\n label: string;\n value: FilterOperator;\n}\n\n// Filter display types\n// Accept both 'drawer' and 'collapsed' as synonyms for the collapsed UI\nexport type FilterDisplay = 'always' | 'drawer' | 'collapsed' | 'hidden';\n\nexport const FilterCategory = {\n FILTER: 'filter',\n SORT: 'sort',\n GROUP: 'group',\n} as const;\n\nexport type FilterCategory = (typeof FilterCategory)[keyof typeof FilterCategory];\n\nexport interface FilterOption {\n label: string;\n value: string;\n icon: ReactNode;\n children?: FilterOption[];\n disabled?: boolean;\n description?: string;\n color?: string;\n}\n\nexport interface DisplayConfig {\n renderConfig?: {\n desktop: string;\n mobile?: string;\n tablet?: string;\n };\n display?: FilterDisplay;\n category?: FilterCategory;\n priority?: number;\n hidden?: boolean;\n className?: string; // Simplified config for basic styling needs\n}\n\nexport interface ValidationConfig {\n min?: number;\n max?: number;\n pattern?: RegExp;\n required?: boolean;\n custom?: (value: unknown) => boolean | string;\n}\n\nexport interface FilterDependency {\n key: string;\n operator: FilterOperator;\n value: string | string[];\n}\n\n/**\n * Configuration for ASYNC_SELECT filters that fetch options from the server.\n *\n * Supports two modes:\n * - Declarative: provide `fetchOptions` on FilterConfig (simpler, backward-compatible)\n * - TanStack Query: provide `asyncConfig` for full control over caching, abort, preload\n *\n * When both are provided, `asyncConfig` takes precedence.\n */\nexport interface AsyncSelectConfig<TItem = unknown> {\n /** TanStack Query key factory — receives { query, limit } and returns a stable key */\n queryKey: (args: { query: string; limit: number }) => readonly unknown[];\n /** Fetcher function — receives { query, limit, signal } and returns items */\n fetcher: (args: {\n query: string;\n limit: number;\n signal?: AbortSignal;\n }) => Promise<TItem[]>;\n /** Maps a fetched item to a FilterOption for display */\n mapToOption: (item: TItem) => FilterOption;\n /** Max items to fetch per request (default: 10) */\n limit?: number;\n /** Minimum characters before fetching (default: 0) */\n minQueryLength?: number;\n /** Whether to fetch with empty query on open (default: true) */\n preload?: boolean;\n /** Debounce delay in ms (default: 300) */\n debounceMs?: number;\n /** TanStack Query staleTime in ms (default: 60_000) */\n staleTime?: number;\n /** TanStack Query gcTime in ms (default: 300_000) */\n gcTime?: number;\n}\n\nexport interface FilterConfig {\n key: string;\n label: string;\n /** Plural form of the label, used in \"{count} {label} selected\" when count > 1 */\n pluralLabel?: string;\n type: FilterType;\n description?: string;\n operator?: FilterOperator;\n operators?: OperatorOption[]; // Available operators for this filter\n options?: FilterOption[];\n placeholder?: string;\n delay?: number;\n icon: ReactNode;\n displayConfig: DisplayConfig;\n defaultValue?: string | string[];\n validation?: ValidationConfig;\n dependencies?: FilterDependency[];\n fetchOptions?: (\n dependencyValues: Record<string, string[]>,\n ) => Promise<FilterOption[]>;\n multiple?: boolean;\n closeOnSelect?: boolean;\n maxSelected?: number;\n /** TanStack Query-powered async config for ASYNC_SELECT filters */\n asyncConfig?: AsyncSelectConfig;\n dateFormat?: {\n display?: string; // Format for display (e.g., 'MMM d, yyyy')\n param?: string; // Format for URL parameters (e.g., 'yyyy-MM-dd')\n };\n // Date picker specific options\n datePickerConfig?: {\n showConfirmButton?: boolean;\n showShortcuts?: boolean;\n fullWidth?: boolean;\n noDatePlaceholder?: string;\n noRangePlaceholder?: string;\n autoApply?: boolean; // Whether to automatically apply date selections\n };\n // Optional formatting functions\n format?: (value: unknown) => string;\n parse?: (value: string) => unknown;\n transform?: (value: unknown) => unknown;\n}\n\nexport interface ActiveFilter {\n id: string;\n key: string;\n operator: FilterOperator;\n value: string[];\n}\n\nexport interface FilterGroup {\n label: string;\n filters: FilterConfig[];\n}\n\nexport interface FilterState {\n [key: string]: string[];\n}\n\nexport interface FilterTabPreset {\n key: string;\n value: string[];\n operator?: FilterOperator;\n}\n\nexport interface FilterTab {\n id: string;\n label: string;\n presets: FilterTabPreset[];\n count?: number;\n}\n","import {\n FilterOperatorEnum,\n type FilterOperator,\n type OperatorOption,\n FilterType,\n} from './filters.types';\nimport type { FilterOperatorStrings } from './filters.strings';\n\nexport function getTextOperators(strings: FilterOperatorStrings): OperatorOption[] {\n return [\n { label: strings.contains, value: FilterOperatorEnum.CONTAINS },\n { label: strings.equals, value: FilterOperatorEnum.EQUALS },\n { label: strings.notContains, value: FilterOperatorEnum.NOT },\n ];\n}\n\nexport function getSelectOperators(strings: FilterOperatorStrings): OperatorOption[] {\n return [\n { label: strings.is, value: FilterOperatorEnum.EQUALS },\n { label: strings.isNot, value: FilterOperatorEnum.NOT },\n ];\n}\n\nexport function getNumberOperators(strings: FilterOperatorStrings): OperatorOption[] {\n return [\n { label: strings.equals, value: FilterOperatorEnum.EQUALS },\n { label: strings.greaterThan, value: FilterOperatorEnum.GT },\n { label: strings.lessThan, value: FilterOperatorEnum.LT },\n ];\n}\n\nexport function getDateOperators(strings: FilterOperatorStrings): OperatorOption[] {\n return [\n { label: strings.before, value: FilterOperatorEnum.BEFORE },\n { label: strings.after, value: FilterOperatorEnum.AFTER },\n { label: strings.between, value: FilterOperatorEnum.BETWEEN },\n ];\n}\n\nexport function getBooleanOperators(strings: FilterOperatorStrings): OperatorOption[] {\n return [{ label: strings.equals, value: FilterOperatorEnum.EQUALS }];\n}\n\nexport function getOperatorsForType(\n type: FilterType,\n strings: FilterOperatorStrings,\n): OperatorOption[] {\n switch (type) {\n case FilterType.SEARCH:\n return getTextOperators(strings);\n case FilterType.TAGS:\n return [\n { label: strings.has, value: FilterOperatorEnum.HAS },\n { label: strings.hasAny, value: FilterOperatorEnum.HAS_ANY },\n { label: strings.hasAll, value: FilterOperatorEnum.HAS_ALL },\n ];\n case FilterType.SELECT:\n case FilterType.ASYNC_SELECT:\n return getSelectOperators(strings);\n case FilterType.RANGE:\n return getNumberOperators(strings);\n case FilterType.DATE:\n return getDateOperators(strings);\n default:\n return getTextOperators(strings);\n }\n}\n\nexport function getDefaultOperatorForType(\n type: FilterType,\n): FilterOperator {\n switch (type) {\n case FilterType.SEARCH:\n return FilterOperatorEnum.CONTAINS;\n case FilterType.TAGS:\n // Tags default to array containment semantics\n return FilterOperatorEnum.HAS;\n case FilterType.SELECT:\n case FilterType.ASYNC_SELECT:\n return FilterOperatorEnum.EQUALS;\n case FilterType.RANGE:\n return FilterOperatorEnum.EQUALS;\n case FilterType.DATE:\n return FilterOperatorEnum.BEFORE;\n default:\n return FilterOperatorEnum.EQUALS;\n }\n}\n","import type { ReactNode } from 'react';\nimport type { FilterConfig, FilterDependency } from '../filters.types';\n\n/**\n * Gets the label for a filter option\n */\nexport function getFilterOptionLabel(\n\tfilter: FilterConfig,\n\tvalue: string,\n): string | undefined {\n\treturn filter.options?.find((opt) => opt.value === value)?.label;\n}\n\n/**\n * Gets the icon for a filter option\n */\nexport function getFilterOptionIcon(\n\tfilter: FilterConfig,\n\tvalue: string,\n): ReactNode | undefined {\n\treturn filter.options?.find((opt) => opt.value === value)?.icon;\n}\n\n/**\n * Validates a filter value against the filter configuration\n *\n * @param filter - The filter configuration to validate against\n * @param value - The value to validate\n * @param t\n * @returns true if valid, or an error message string if invalid\n */\nexport function validateFilterValue(\n\tfilter: FilterConfig,\n\tvalue: unknown,\n\tt: (key: string) => string,\n): boolean | string {\n\t// Special case for date filters - always allow date strings\n\tif (filter.type === 'date') {\n\t\t// If the value is a date string array, it's valid\n\t\tif (Array.isArray(value) && value.every((v) => typeof v === 'string')) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t// Require if marked as required\n\tif (\n\t\tfilter.validation?.required &&\n\t\t(!value || (Array.isArray(value) && value.length === 0))\n\t) {\n\t\treturn t('validation.required');\n\t}\n\n\t// Only check min/max for numeric values\n\tif (typeof value === 'number') {\n\t\tif (\n\t\t\tfilter.validation?.min !== undefined &&\n\t\t\tvalue < filter.validation.min\n\t\t) {\n\t\t\treturn t('validation.minValue').replace(\n\t\t\t\t'{min}',\n\t\t\t\tString(filter.validation.min),\n\t\t\t);\n\t\t}\n\n\t\tif (\n\t\t\tfilter.validation?.max !== undefined &&\n\t\t\tvalue > filter.validation.max\n\t\t) {\n\t\t\treturn t('validation.maxValue').replace(\n\t\t\t\t'{max}',\n\t\t\t\tString(filter.validation.max),\n\t\t\t);\n\t\t}\n\t}\n\n\t// Pattern validation for strings only\n\tif (filter.validation?.pattern && typeof value === 'string') {\n\t\tconst regex = new RegExp(filter.validation.pattern);\n\t\tif (!regex.test(value)) {\n\t\t\treturn t('validation.invalidFormat');\n\t\t}\n\t}\n\n\t// Custom validation if provided\n\tif (filter.validation?.custom) {\n\t\tconst customValidation = filter.validation.custom(value);\n\t\tif (typeof customValidation === 'string' || !customValidation) {\n\t\t\treturn customValidation;\n\t\t}\n\t}\n\n\t// If we got here, the value is valid\n\treturn true;\n}\n\n/**\n * Formats a filter value for display using either the format function provided\n * in the filter config, or by looking up option labels\n *\n * @param filter - The filter configuration\n * @param value - The value to format\n * @returns Formatted string representation of the value\n */\nexport function formatFilterValue(\n\tfilter: FilterConfig,\n\tvalue: unknown,\n): string {\n\t// Use custom format function if provided in filter config\n\tif (filter.format && typeof filter.format === 'function') {\n\t\ttry {\n\t\t\treturn filter.format(value);\n\t\t} catch (error) {\n\t\t\tif (import.meta.env?.DEV) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`Error using custom format function for filter ${filter.key}:`,\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Fall back to default formatting\n\t\t}\n\t}\n\n\t// Default formatting behavior\n\tif (Array.isArray(value)) {\n\t\treturn value\n\t\t\t.map((v) => getFilterOptionLabel(filter, String(v)) ?? String(v))\n\t\t\t.join(', ');\n\t}\n\n\treturn getFilterOptionLabel(filter, String(value)) ?? String(value);\n}\n\n/**\n * Gets the values of dependent filters\n */\nexport function getDependentFilterValues(\n\tdependencies: FilterDependency[],\n\tfilterState: Record<string, string[]>,\n): Record<string, string[]> {\n\treturn dependencies.reduce(\n\t\t(acc, dep) => {\n\t\t\tconst values = filterState[dep.key] || [];\n\t\t\tif (values.length > 0) {\n\t\t\t\tacc[dep.key] = values;\n\t\t\t}\n\t\t\treturn acc;\n\t\t},\n\t\t{} as Record<string, string[]>,\n\t);\n}\n\n/**\n * Determines if a filter should be shown based on its dependencies\n */\nexport function shouldShowFilter(\n\tfilter: FilterConfig,\n\tfilterState: Record<string, string[]>,\n): boolean {\n\tif (!filter.dependencies || filter.dependencies.length === 0) {\n\t\treturn true;\n\t}\n\n\treturn filter.dependencies.every((dep) => {\n\t\tconst values = filterState[dep.key] || [];\n\t\tif (values.length === 0) return false;\n\n\t\tswitch (dep.operator) {\n\t\t\tcase 'equals':\n\t\t\t\treturn values.includes(dep.value as string);\n\t\t\tcase 'contains':\n\t\t\t\treturn values.some((v) => (dep.value as string).includes(v));\n\t\t\tcase 'in':\n\t\t\t\treturn Array.isArray(dep.value)\n\t\t\t\t\t? values.some((v) => (dep.value as string[]).includes(v))\n\t\t\t\t\t: values.includes(dep.value);\n\t\t\tdefault:\n\t\t\t\treturn false;\n\t\t}\n\t});\n}\n\nexport function extractFilterDefaults<T extends string = string>(\n\tfilters: FilterConfig[],\n): Record<T, string> {\n\treturn filters.reduce(\n\t\t(acc, filter) => {\n\t\t\t// Force the default value to be treated as a string\n\t\t\tacc[filter.key as T] = (filter.defaultValue as string) || '';\n\t\t\treturn acc;\n\t\t},\n\t\t{} as Record<T, string>,\n\t);\n}\n","import {\n createContext,\n useContext,\n useMemo,\n useCallback,\n type ReactNode,\n useRef,\n useEffect,\n useState,\n} from 'react';\nimport { useStrings, type StringsProp } from '@/lib/strings';\nimport {\n defaultFilterStrings,\n getFilterString,\n type FilterStrings,\n} from './filters.strings';\nimport {\n FilterType,\n type FilterConfig,\n type ActiveFilter,\n type FilterOperator,\n type FilterOption,\n} from './filters.types';\nimport { getDefaultOperatorForType } from './operator-options';\nimport { validateFilterValue } from './utils/filter-utils';\n\ninterface FilterProviderProps {\n children: ReactNode;\n filters: FilterConfig[];\n activeFilters: ActiveFilter[];\n onFilterChange: (filters: ActiveFilter[]) => void;\n isNavigating?: boolean;\n strings?: StringsProp<FilterStrings>;\n locale?: string;\n /** Called when an async fetch / validation / apply step throws.\n * Library DEV-logs the error; consumer wires telemetry here. */\n onError?: (error: unknown, context: { phase: 'fetch-options' | 'apply' | 'validate'; filterKey?: string }) => void;\n}\n\ninterface FilterContextValue {\n activeFilters: ActiveFilter[];\n filters: FilterConfig[];\n addFilter: (filter: ActiveFilter) => void;\n removeFilter: (id: string) => void;\n updateFilter: (id: string, updates: Partial<ActiveFilter>) => void;\n clearFilters: () => void;\n replaceFilters: (filters: ActiveFilter[]) => void;\n getFilterByKey: (key: string) => FilterConfig | undefined;\n getFilterValue: (key: string) => string[];\n setFilterValue: (key: string, value: string[]) => void;\n isFilterActive: (key: string) => boolean;\n getFilterOperator: (key: string) => FilterOperator | undefined;\n setFilterOperator: (key: string, operator: FilterOperator) => void;\n validateFilter: (key: string, value: unknown) => boolean | string;\n getDependentFilters: (key: string) => FilterConfig[];\n getFilterOptions: (key: string) => Promise<FilterOption[]>;\n isNavigating: boolean;\n locale: string;\n strings: FilterStrings;\n /** Cache resolved options for async filters (keyed by filter key → option value → FilterOption) */\n cacheAsyncOptions: (filterKey: string, options: FilterOption[]) => void;\n /** Resolve a cached label for an async filter value */\n getAsyncOptionLabel: (filterKey: string, optionValue: string) => string | undefined;\n}\n\nconst FilterContext = createContext<FilterContextValue | undefined>(undefined);\n\n/**\n * Module-level cache for async filter option labels.\n * Lives outside the component tree so it survives provider remounts.\n */\nconst globalAsyncOptionsCache = new Map<string, Map<string, FilterOption>>();\n\n/**\n * Framework-agnostic filter provider.\n * State, strings, and async option fetchers are passed by the consumer.\n */\nexport function FilterProvider({\n children,\n filters,\n activeFilters,\n onFilterChange,\n isNavigating: isNavigatingProp = false,\n strings: stringsProp,\n locale: localeProp,\n onError,\n}: FilterProviderProps) {\n const filtersRef = useRef(filters);\n const activeFiltersRef = useRef(activeFilters);\n const onFilterChangeRef = useRef(onFilterChange);\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n\n // Trigger re-render when async labels are resolved\n const [, setAsyncCacheVersion] = useState(0);\n\n const locale = localeProp || 'en';\n const strings = useStrings(defaultFilterStrings, stringsProp);\n\n // Update refs when prop change\n useEffect(() => {\n filtersRef.current = filters;\n }, [filters]);\n\n useEffect(() => {\n activeFiltersRef.current = activeFilters;\n }, [activeFilters]);\n\n useEffect(() => {\n onFilterChangeRef.current = onFilterChange;\n }, [onFilterChange]);\n\n const addFilter = useCallback(\n (filter: ActiveFilter) => {\n const newFilters = [...activeFilters, filter];\n onFilterChangeRef.current(newFilters);\n },\n [activeFilters],\n );\n\n const removeFilter = useCallback(\n (id: string) => {\n const newFilters = activeFilters.filter(\n (f: ActiveFilter) => f.id !== id && f.key !== id,\n );\n onFilterChangeRef.current(newFilters);\n },\n [activeFilters],\n );\n\n const updateFilter = useCallback(\n (id: string, updates: Partial<ActiveFilter>) => {\n const newFilters = activeFilters.map((f: ActiveFilter) =>\n f.id === id || f.key === id ? { ...f, ...updates } : f,\n );\n onFilterChangeRef.current(newFilters);\n },\n [activeFilters],\n );\n\n const clearFilters = useCallback(() => {\n onFilterChangeRef.current([]);\n }, []);\n\n const replaceFilters = useCallback((newFilters: ActiveFilter[]) => {\n onFilterChangeRef.current(newFilters);\n }, []);\n\n const getFilterByKey = useCallback(\n (key: string): FilterConfig | undefined => {\n return filtersRef.current.find((f: FilterConfig) => f.key === key);\n },\n [],\n );\n\n const getFilterValue = useCallback(\n (key: string): string[] => {\n const filter = activeFilters.find(\n (f: ActiveFilter) => f.key === key,\n );\n return filter?.value || [];\n },\n [activeFilters],\n );\n\n const setFilterValue = useCallback(\n (key: string, value: string[]) => {\n const existingFilter = activeFilters.find(\n (f: ActiveFilter) => f.key === key,\n );\n\n if (value.length === 0) {\n // Remove filter if the value is empty\n if (existingFilter) {\n removeFilter(key);\n }\n } else {\n // Update or add filter\n if (existingFilter) {\n updateFilter(key, { value });\n } else {\n // Get the filter config to check for default operator\n const filterConfig = filtersRef.current.find(\n (f: FilterConfig) => f.key === key,\n );\n const defaultOperator =\n filterConfig?.operator ??\n filterConfig?.operators?.[0]?.value ??\n (filterConfig\n ? getDefaultOperatorForType(filterConfig.type)\n : 'equals');\n\n addFilter({\n id: key,\n key,\n value,\n operator: defaultOperator,\n });\n }\n }\n },\n [activeFilters, addFilter, removeFilter, updateFilter],\n );\n\n const isFilterActive = useCallback(\n (key: string): boolean => {\n return activeFilters.some(\n (f: ActiveFilter) => f.key === key && f.value.length > 0,\n );\n },\n [activeFilters],\n );\n\n const getFilterOperator = useCallback(\n (key: string): FilterOperator | undefined => {\n const filter = activeFilters.find(\n (f: ActiveFilter) => f.key === key,\n );\n return filter?.operator || 'equals';\n },\n [activeFilters],\n );\n\n const setFilterOperator = useCallback(\n (key: string, operator: FilterOperator) => {\n const existingFilter = activeFilters.find(\n (f: ActiveFilter) => f.key === key,\n );\n if (existingFilter) {\n updateFilter(key, { operator });\n }\n },\n [activeFilters, updateFilter],\n );\n\n const validateFilter = useCallback(\n (key: string, value: unknown): boolean | string => {\n const filter = filtersRef.current.find(\n (f: FilterConfig) => f.key === key,\n );\n if (!filter) return false;\n return validateFilterValue(filter, value, (path) =>\n getFilterString(strings, path),\n );\n },\n [strings],\n );\n\n const getDependentFilters = useCallback((key: string): FilterConfig[] => {\n return filtersRef.current.filter((f: FilterConfig) =>\n f.dependencies?.some((dep: { key: string }) => dep.key === key),\n );\n }, []);\n\n const getFilterOptions = useCallback(\n async (key: string): Promise<FilterOption[]> => {\n const filter = filtersRef.current.find(\n (f: FilterConfig) => f.key === key,\n );\n if (!filter) return [];\n\n if (filter.fetchOptions) {\n const filtersState = activeFiltersRef.current.reduce(\n (acc, current) => {\n acc[current.key] = current.value;\n return acc;\n },\n {} as Record<string, string[]>,\n );\n\n const dependencyValues = (filter.dependencies ?? []).reduce(\n (acc, dep) => {\n const dependencyValue = filtersState[dep.key];\n if (dependencyValue && dependencyValue.length > 0) {\n acc[dep.key] = dependencyValue;\n }\n return acc;\n },\n {} as Record<string, string[]>,\n );\n\n try {\n const dynamicOptions =\n await filter.fetchOptions(dependencyValues);\n if (Array.isArray(dynamicOptions)) {\n return dynamicOptions;\n }\n } catch (error) {\n if (import.meta.env?.DEV) {\n\t console.error(\n\t `Failed fetching options for filter \"${key}\":`,\n\t error,\n\t );\n }\n onErrorRef.current?.(error, { phase: 'fetch-options', filterKey: key });\n }\n }\n\n // Fall back to the static definition if no dynamic options are available\n return filter.options || [];\n },\n [],\n );\n\n const cacheAsyncOptions = useCallback(\n (filterKey: string, options: FilterOption[]) => {\n let filterMap = globalAsyncOptionsCache.get(filterKey);\n if (!filterMap) {\n filterMap = new Map();\n globalAsyncOptionsCache.set(filterKey, filterMap);\n }\n let hasNew = false;\n for (const opt of options) {\n if (!filterMap.has(opt.value)) {\n hasNew = true;\n }\n filterMap.set(opt.value, opt);\n }\n // Trigger re-render if new labels were added so filter pills update\n if (hasNew) {\n setAsyncCacheVersion((v) => v + 1);\n }\n },\n [],\n );\n\n const getAsyncOptionLabel = useCallback(\n (filterKey: string, optionValue: string): string | undefined => {\n return globalAsyncOptionsCache.get(filterKey)?.get(optionValue)?.label;\n },\n [],\n );\n\n // On mount, preload options for any active ASYNC_SELECT filters so that\n // filter pills can display resolved labels instead of raw UUIDs.\n useEffect(() => {\n const controller = new AbortController();\n\n for (const filter of filters) {\n if (filter.type !== FilterType.ASYNC_SELECT) continue;\n\n const active = activeFilters.find((af) => af.key === filter.key);\n if (!active || active.value.length === 0) continue;\n\n // Check if all active values already have cached labels\n const allCached = active.value.every(\n (v) => globalAsyncOptionsCache.get(filter.key)?.has(v),\n );\n if (allCached) continue;\n\n // Preload: fetch with empty query to get default/popular options\n const { asyncConfig, fetchOptions } = filter;\n if (asyncConfig?.fetcher && asyncConfig.mapToOption) {\n void asyncConfig\n .fetcher({\n query: '',\n limit: asyncConfig.limit ?? 10,\n signal: controller.signal,\n })\n .then((items) => {\n if (controller.signal.aborted) return;\n const options = items.map(asyncConfig.mapToOption);\n cacheAsyncOptions(filter.key, options);\n })\n .catch(() => {\n // Silently ignore — labels will fallback to \"N selected\"\n });\n } else if (fetchOptions) {\n void fetchOptions({ q: [''] })\n .then((options) => {\n if (controller.signal.aborted) return;\n cacheAsyncOptions(filter.key, options);\n })\n .catch(() => {\n // Silently ignore\n });\n }\n }\n\n return () => controller.abort();\n // Only run on mount — filters/activeFilters identity may change on every render\n // but we only need to preload once.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const value = useMemo(\n () => ({\n activeFilters,\n filters,\n addFilter,\n removeFilter,\n updateFilter,\n clearFilters,\n replaceFilters,\n getFilterByKey,\n getFilterValue,\n setFilterValue,\n isFilterActive,\n getFilterOperator,\n setFilterOperator,\n validateFilter,\n getDependentFilters,\n getFilterOptions,\n isNavigating: isNavigatingProp,\n locale,\n strings,\n cacheAsyncOptions,\n getAsyncOptionLabel,\n }),\n [\n activeFilters,\n filters,\n addFilter,\n removeFilter,\n updateFilter,\n clearFilters,\n replaceFilters,\n getFilterByKey,\n getFilterValue,\n setFilterValue,\n isFilterActive,\n getFilterOperator,\n setFilterOperator,\n validateFilter,\n getDependentFilters,\n getFilterOptions,\n isNavigatingProp,\n locale,\n strings,\n cacheAsyncOptions,\n getAsyncOptionLabel,\n ],\n );\n\n return (\n <FilterContext.Provider value={value}>\n {children}\n </FilterContext.Provider>\n );\n}\n\nexport function useFilters() {\n const context = useContext(FilterContext);\n if (!context) {\n throw new Error('useFilters must be used within a FilterProvider');\n }\n return context;\n}\n","/**\n * useFilterGroups — headless partitioning of the filter list into the four\n * groups `FilterLayout` (and any custom layout) renders distinctly:\n *\n * - `searchFilters` — `FilterType.SEARCH`, always inline\n * - `alwaysVisibleFilters` — `displayConfig.display === 'always'` and inactive\n * - `activeRegularFilters` — non-search filters that are currently active\n * - `popoverFilters` — non-search, inactive, non-always (live in \"+\" popover)\n *\n * Plus `activeFilterKeys` and `hasActive` helpers. Consumers building a\n * custom strip layout against `<FilterProvider>` can call this and place\n * each group wherever they want without re-implementing the partition\n * logic.\n *\n * `dynamicFilterOptions` (optional) lets consumers swap a filter's option\n * list at render time (e.g. async-loaded options from a parent component)\n * without mutating the provider state.\n */\nimport { useMemo } from 'react';\n\nimport { useFilters } from '../filter-context';\nimport { type FilterConfig, FilterType } from '../filters.types';\n\nexport interface UseFilterGroupsOptions {\n /** Override `filter.options` per-key at render time. */\n dynamicFilterOptions?: Record<string, FilterConfig['options']>;\n}\n\nexport interface UseFilterGroupsResult {\n /** Filters merged with `dynamicFilterOptions`. */\n processedFilters: FilterConfig[];\n searchFilters: FilterConfig[];\n alwaysVisibleFilters: FilterConfig[];\n activeRegularFilters: FilterConfig[];\n popoverFilters: FilterConfig[];\n activeFilterKeys: string[];\n hasActive: boolean;\n}\n\nexport function useFilterGroups(options: UseFilterGroupsOptions = {}): UseFilterGroupsResult {\n const { dynamicFilterOptions } = options;\n const { filters, isFilterActive } = useFilters();\n\n const processedFilters = useMemo(() => {\n if (!dynamicFilterOptions) return filters;\n return filters.map((filter) => {\n const dyn = dynamicFilterOptions[filter.key];\n if (Array.isArray(dyn)) return { ...filter, options: dyn };\n return filter;\n });\n }, [filters, dynamicFilterOptions]);\n\n return useMemo(() => {\n const searchFilters = processedFilters.filter((f) => f.type === FilterType.SEARCH);\n const activeRegularFilters = processedFilters.filter(\n (f) => f.type !== FilterType.SEARCH && isFilterActive(f.key),\n );\n const alwaysVisibleFilters = processedFilters.filter(\n (f) =>\n f.type !== FilterType.SEARCH\n && !isFilterActive(f.key)\n && f.displayConfig?.display === 'always',\n );\n const popoverFilters = processedFilters.filter(\n (f) =>\n f.type !== FilterType.SEARCH\n && !isFilterActive(f.key)\n && f.displayConfig?.display !== 'always',\n );\n const activeFilterKeys = activeRegularFilters.map((f) => f.key);\n\n return {\n processedFilters,\n searchFilters,\n alwaysVisibleFilters,\n activeRegularFilters,\n popoverFilters,\n activeFilterKeys,\n hasActive: activeFilterKeys.length > 0,\n };\n }, [processedFilters, isFilterActive]);\n}\n","import React, { useState } from 'react';\n\nimport { Button } from '@/components/base/buttons';\nimport { PopoverMenu } from '@/components/base/popover-menu';\nimport { Text } from '@/components/typography';\nimport { cn } from '@/lib/utils';\n\nimport { useFilters } from '../filter-context';\nimport type { FilterOperator, OperatorOption } from '../filters.types';\n\ninterface FilterOperatorSelectProps {\n operator: FilterOperator;\n operators: OperatorOption[];\n onOperatorChange: (operator: FilterOperator) => void;\n /** Segment-reset classes forwarded by the parent pill so the trigger\n * drops its base border + focus ring (it lives inside a segmented\n * pill, not as a standalone button). */\n segmentResetClass?: string;\n}\n\n/**\n * FilterOperatorSelect — operator dropdown for an active filter pill.\n *\n * Now delegates the trigger + popover + command-list pattern entirely to\n * `PopoverMenu`. The trigger is rendered in the pill's inline strip, the\n * `header` slot supplies the small \"Operator\" eyebrow, and item rendering\n * stays compact (xs typography, density-tokenized padding from base/command).\n */\nexport function FilterOperatorSelect({\n operator,\n operators,\n onOperatorChange,\n segmentResetClass,\n}: FilterOperatorSelectProps) {\n const [open, setOpen] = useState(false);\n const { strings } = useFilters();\n\n const currentOperatorLabel =\n operators.find((op) => op.value === operator)?.label || operator;\n\n const handleTriggerClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n };\n\n return (\n <PopoverMenu\n open={open}\n onOpenChange={setOpen}\n search={false}\n trigger={\n <Button\n variant=\"secondary\"\n buttonStyle=\"ghost\"\n className={cn(\n segmentResetClass,\n 'text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground h-full px-3 text-xs',\n )}\n onClick={handleTriggerClick}\n type=\"button\"\n >\n {currentOperatorLabel}\n </Button>\n }\n header={\n <Text tag=\"span\" size=\"xs\" weight=\"semibold\">\n {strings.operator}\n </Text>\n }\n contentClassName=\"w-48\"\n items={operators.map((op) => ({\n value: op.value,\n label: op.label,\n selected: op.value === operator,\n }))}\n onSelect={(item) => {\n onOperatorChange(item.value as FilterOperator);\n setOpen(false);\n }}\n />\n );\n}\n","import { format } from 'date-fns';\nimport { CalendarIcon } from 'lucide-react';\nimport { Text } from '@/components/typography';\nimport { useFilters } from '../filter-context';\nimport type { FilterStrings } from '../filters.strings';\nimport { interpolateFilterString } from '../filters.strings';\nimport { FilterType, type FilterConfig } from '../filters.types';\n\ninterface FilterValueDisplayProps {\n filter: FilterConfig;\n value: string[];\n}\n\n/**\n * Filter Value Display Component\n *\n * This component provides the UI for displaying filter values.\n * It handles:\n * - Displaying filter values with appropriate formatting\n * - Showing icons for filter options\n * - Handling date formatting\n * - Supporting internationalization\n *\n * The component is used to show users the current value of a filter\n * in a consistent and informative way.\n */\n\nexport function FilterValueDisplay({ filter, value }: FilterValueDisplayProps) {\n const { strings } = useFilters();\n\n // Empty state — render the localized \"Nothing selected\" instead of an\n // empty cell so the pill never collapses to no-value text.\n if (value.length === 0 && filter.type !== FilterType.DATE) {\n return (\n <Text tag=\"span\" size=\"xs\" type=\"secondary\">\n {strings.nothingSelected}\n </Text>\n );\n }\n\n // For ASYNC_SELECT — always show \"N selected\"\n if (filter.type === FilterType.ASYNC_SELECT && !filter.options?.length) {\n return (\n <Text tag=\"span\" size=\"xs\" weight=\"semibold\">\n {renderAsyncValueText(filter, value, strings)}\n </Text>\n );\n }\n\n if (filter.options && filter.type !== FilterType.DATE) {\n return (\n <div className=\"flex items-center gap-1\">\n {/* Option icons - shown for both single and multi-select cases */}\n <div className=\"relative flex\">\n {value.slice(0, 2).map((val, index) => {\n const option = filter.options?.find(\n (o) => o.value === val,\n );\n if (!option?.icon) return null;\n\n return (\n <div\n key={val}\n className={`${index > 0 ? '-ml-1.5' : ''} border-background bg-background relative rounded-full border`}\n style={{ zIndex: 10 - index }}\n >\n {option.icon}\n </div>\n );\n })}\n {value.length > 2 && (\n <div className=\"bg-muted border-background relative -ml-1.5 flex h-4 w-4 items-center justify-center rounded-full border text-xxs font-medium\">\n +{value.length - 2}\n </div>\n )}\n </div>\n\n {/* Value text */}\n <Text tag=\"span\" size=\"xs\" weight=\"semibold\">\n {renderValueText(filter, value, strings)}\n </Text>\n </div>\n );\n }\n\n // For date filters\n if (filter.type === FilterType.DATE) {\n return (\n <div className=\"flex items-center gap-1\">\n <CalendarIcon className=\"text-muted-foreground h-3.5 w-3.5\" />\n <Text tag=\"span\" size=\"xs\" weight=\"semibold\">\n {renderDateValue(filter, value, strings)}\n </Text>\n </div>\n );\n }\n\n // For other filters\n return (\n <Text tag=\"span\" size=\"xs\" weight=\"semibold\">\n {renderValueText(filter, value, strings)}\n </Text>\n );\n}\n\n// Helper function to render date values\nfunction renderDateValue(\n filter: FilterConfig,\n value: string[],\n strings: FilterStrings,\n) {\n if (filter.operator === 'between' && value.length === 2) {\n return `${formatDateValue(value[0], filter.dateFormat?.display)} - ${formatDateValue(value[1], filter.dateFormat?.display)}`;\n }\n\n if (value.length === 1) {\n return formatDateValue(value[0], filter.dateFormat?.display);\n }\n\n if (value.length === 2) {\n return `${formatDateValue(value[0], filter.dateFormat?.display)} - ${formatDateValue(value[1], filter.dateFormat?.display)}`;\n }\n\n return (\n filter.datePickerConfig?.noDatePlaceholder ||\n strings.calendar.notDateSelected\n );\n}\n\n// Helper function to render text values for async filters — always \"N selected\"\nfunction renderAsyncValueText(\n _filter: FilterConfig,\n value: string[],\n strings: FilterStrings,\n) {\n if (value.length === 0) return '';\n return interpolateFilterString(strings.selected, { count: value.length, filterLabel: (value.length > 1 ? _filter.pluralLabel : _filter.label) ?? _filter.label });\n}\n\n// Helper function to render text values\nfunction renderValueText(\n filter: FilterConfig,\n value: string[],\n strings: FilterStrings,\n) {\n if (value.length > 1) {\n return interpolateFilterString(strings.selected, {\n count: value.length,\n filterLabel: filter.pluralLabel ?? filter.label,\n });\n }\n\n return value\n .map((val) => {\n const option = filter.options?.find((o) => o.value === val);\n return option?.label || val;\n })\n .join(', ');\n}\n\nfunction formatDateValue(rawValue: string, pattern?: string) {\n const parsed = new Date(rawValue);\n\n if (Number.isNaN(parsed.getTime())) {\n return rawValue;\n }\n\n if (pattern) {\n try {\n return format(parsed, pattern);\n } catch {\n // Fall through to locale formatting if the provided pattern is invalid\n }\n }\n\n return parsed.toLocaleDateString();\n}\n","import { ChevronDown, X } from 'lucide-react';\nimport React from 'react';\nimport { Button } from '@/components/base/buttons';\nimport { Text } from '@/components/typography';\nimport { cn } from '@/lib/utils';\nimport { useFilters } from '../filter-context';\nimport {\n FILTER_ELEMENT_HEIGHT,\n type FilterConfig,\n type FilterOperator,\n type OperatorOption,\n} from '../filters.types';\nimport { FilterOperatorSelect } from './filter-operator-select';\nimport { FilterValueDisplay } from './filter-value-display';\n\ninterface ActiveFilterItemProps {\n filter: FilterConfig;\n value: string[];\n isActive: boolean;\n operators: OperatorOption[];\n operator: FilterOperator;\n onOperatorChange: (operator: FilterOperator) => void;\n onFilterClear: () => void;\n onFilterClick: () => void;\n}\n\n/**\n * Active Filter Item Component\n *\n * This component displays a single active filter in the filter list.\n * It provides:\n * - Display of filter label and value\n * - Remove filter functionality\n * - Visual feedback for active state\n * - Support for different filter types\n *\n * The component is used in the filter list to show currently active filters\n * and allow users to remove them.\n */\n\nexport function ActiveFilterItem({\n filter,\n value,\n isActive,\n operators,\n operator,\n onOperatorChange,\n onFilterClear,\n onFilterClick,\n}: ActiveFilterItemProps) {\n const { strings } = useFilters();\n\n // Handle button click to avoid interference with children\n const handleLabelClick = (e: React.MouseEvent) => {\n // Only proceed if this is directly on the button, not a child element\n if (\n e.currentTarget === e.target ||\n (e.target as HTMLElement).tagName !== 'BUTTON'\n ) {\n onFilterClick();\n }\n };\n\n // Inside the pill, segment buttons must not paint their own border or\n // focus ring — the pill itself is the visual container. The global\n // `<Button>` primitive bakes in `border border-transparent\n // focus-visible:border-ring focus-visible:ring-3`, so without these\n // overrides every segment paints a full 1px box (showing as a\n // double-border just inside the pill chrome) and a rounded focus ring\n // when the popover opens.\n const SEGMENT_RESET =\n '!border-0 !rounded-none !shadow-none focus-visible:!ring-0 focus-visible:!border-transparent';\n\n // Explicit 1px divider — the segment buttons use `!border-0` (so they\n // don't paint an inner full-box decoration) which would also wipe a\n // `divide-x` border. A standalone separator div is unambiguous and\n // doesn't fight with the buttons' baseline chrome.\n const Divider = () => <div aria-hidden className=\"w-px self-stretch bg-border\" />;\n\n return (\n <div\n role=\"group\"\n aria-label={filter.label}\n className={cn(\n `border-input bg-background flex ${FILTER_ELEMENT_HEIGHT} items-center overflow-hidden rounded-md border`,\n filter.displayConfig?.className,\n isActive && 'active',\n )}\n >\n {/* Filter icon, label and dropdown button grouped together */}\n <Button\n type=\"button\"\n variant=\"secondary\"\n buttonStyle=\"ghost\"\n className={cn(\n SEGMENT_RESET,\n 'flex h-full items-center px-3 hover:bg-accent hover:text-accent-foreground',\n )}\n onClick={handleLabelClick}\n >\n {!!filter.icon && (\n <span className=\"text-muted-foreground mr-1\">\n {filter.icon}\n </span>\n )}\n <Text tag=\"span\" size=\"xs\" weight=\"semibold\">{filter.label}</Text>\n <ChevronDown className=\"ml-1 h-4 w-4\" />\n </Button>\n\n <Divider />\n\n {/* Operator dropdown */}\n <FilterOperatorSelect\n operator={operator}\n operators={operators}\n onOperatorChange={onOperatorChange}\n segmentResetClass={SEGMENT_RESET}\n />\n\n <Divider />\n\n {/* Value display with icons and count when multiple selected - explicitly non-interactive */}\n <div className=\"pointer-events-none flex flex-1 items-center px-2\">\n <FilterValueDisplay filter={filter} value={value} />\n </div>\n\n <Divider />\n\n {/* Clear button */}\n <Button\n variant=\"secondary\" buttonStyle=\"ghost\"\n className={cn(SEGMENT_RESET, 'h-full w-8 px-0 rounded-r-md')}\n onClick={(e) => {\n e.stopPropagation();\n e.preventDefault();\n onFilterClear();\n }}\n >\n <X className=\"h-4 w-4\" />\n <span className=\"sr-only\">{strings.clear}</span>\n </Button>\n </div>\n );\n}\n","import { useEffect, useState } from 'react';\n\nexport function useDebounce<T>(value: T, delay: number = 500): T {\n const [debouncedValue, setDebouncedValue] = useState<T>(value);\n\n useEffect(() => {\n const handler = setTimeout(() => {\n setDebouncedValue(value);\n }, delay);\n\n return () => {\n clearTimeout(handler);\n };\n }, [value, delay]);\n\n return debouncedValue;\n}","/**\n * useAsyncOptions — peer-dep-free async fetcher for filter facets.\n *\n * Replaces the previous `@tanstack/react-query` integration so the feature\n * stays framework-agnostic. Behaviour preserved:\n * - Debounced search input\n * - Min-query-length gating with an `isBelowMinQuery` flag\n * - Optional preload (empty query) with an `enabled` toggle\n * - AbortController on each new request\n * - In-memory cache keyed by `(filter.key, query)` to avoid refetching\n * identical queries within the cache window (`staleTime`)\n * - `refetch()` for the consumer's retry button\n *\n * Consumers that want react-query semantics can compose `asyncConfig.fetcher`\n * with their own `useQuery` and pass the resulting `FilterOption[]` through\n * a controlled `options` prop on the facet — no integration code needed in\n * this library.\n */\nimport { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport { useDebounce } from '@/hooks/use-debounce';\nimport { useFiltersConfig } from '@/lib/ui-provider';\n\nimport type { FilterConfig, FilterOption } from '../filters.types';\n\ninterface CacheEntry {\n timestamp: number;\n data: FilterOption[];\n}\n\nconst moduleCache = new Map<string, CacheEntry>();\n\nexport interface UseAsyncOptionsResult {\n options: FilterOption[];\n isLoading: boolean;\n isFetching: boolean;\n isError: boolean;\n refetch: () => void;\n isBelowMinQuery: boolean;\n minQueryLength: number;\n}\n\nexport function useAsyncOptions(\n filter: FilterConfig,\n searchInput: string,\n isActive: boolean,\n): UseAsyncOptionsResult {\n const { asyncConfig, fetchOptions } = filter;\n const { debounceMs: configDebounceMs, defaultPageSize } = useFiltersConfig();\n const debounceMs = asyncConfig?.debounceMs ?? filter.delay ?? configDebounceMs ?? 300;\n const debouncedSearch = useDebounce(searchInput, debounceMs);\n const normalisedQuery = (debouncedSearch ?? '').trim();\n\n const limit = asyncConfig?.limit ?? defaultPageSize ?? 10;\n const minQueryLength = asyncConfig?.minQueryLength ?? 0;\n const preload = asyncConfig?.preload ?? true;\n const staleTime = asyncConfig?.staleTime ?? 60_000;\n\n const isPreload = normalisedQuery.length === 0 && preload;\n const meetsMinLength = normalisedQuery.length >= minQueryLength;\n const canFetch =\n isActive && (isPreload || (normalisedQuery.length > 0 && meetsMinLength));\n const isBelowMinQuery =\n isActive &&\n !isPreload &&\n normalisedQuery.length > 0 &&\n normalisedQuery.length < minQueryLength;\n\n const cacheKey = useMemo(() => {\n if (asyncConfig?.queryKey) {\n return JSON.stringify(\n asyncConfig.queryKey({ query: normalisedQuery, limit }),\n );\n }\n return JSON.stringify(['filter', filter.key, normalisedQuery, limit]);\n }, [asyncConfig, filter.key, normalisedQuery, limit]);\n\n const queryFn = useCallback(\n async (signal: AbortSignal): Promise<FilterOption[]> => {\n if (asyncConfig?.fetcher && asyncConfig.mapToOption) {\n const items = await asyncConfig.fetcher({\n query: normalisedQuery,\n limit,\n signal,\n });\n return items.map(asyncConfig.mapToOption);\n }\n if (fetchOptions) {\n return fetchOptions({ q: [normalisedQuery] });\n }\n return [];\n },\n [asyncConfig, fetchOptions, normalisedQuery, limit],\n );\n\n const [state, setState] = useState<{\n data: FilterOption[];\n loading: boolean;\n fetching: boolean;\n error: boolean;\n }>(() => {\n const cached = moduleCache.get(cacheKey);\n return {\n data: cached?.data ?? [],\n loading: false,\n fetching: false,\n error: false,\n };\n });\n\n const [reloadTick, setReloadTick] = useState(0);\n const refetch = useCallback(() => setReloadTick((t) => t + 1), []);\n\n useEffect(() => {\n if (!canFetch) return;\n\n const cached = moduleCache.get(cacheKey);\n const isFresh =\n cached !== undefined && Date.now() - cached.timestamp < staleTime;\n\n const controller = new AbortController();\n\n if (isFresh && reloadTick === 0) {\n setState({\n data: cached.data,\n loading: false,\n fetching: false,\n error: false,\n });\n return () => controller.abort();\n }\n\n setState((prev) => ({\n data: cached?.data ?? prev.data,\n loading: cached === undefined,\n fetching: true,\n error: false,\n }));\n\n let cancelled = false;\n queryFn(controller.signal)\n .then((data) => {\n if (cancelled) return;\n moduleCache.set(cacheKey, { timestamp: Date.now(), data });\n setState({\n data,\n loading: false,\n fetching: false,\n error: false,\n });\n })\n .catch((err) => {\n if (cancelled || controller.signal.aborted) return;\n if (err && (err as { name?: string }).name === 'AbortError') return;\n setState((prev) => ({\n data: prev.data,\n loading: false,\n fetching: false,\n error: true,\n }));\n });\n\n return () => {\n cancelled = true;\n controller.abort();\n };\n }, [cacheKey, queryFn, canFetch, staleTime, reloadTick]);\n\n return {\n options: canFetch ? state.data : [],\n isLoading: canFetch && state.loading,\n isFetching: canFetch && state.fetching,\n isError: canFetch && state.error,\n refetch,\n isBelowMinQuery,\n minQueryLength,\n };\n}\n","import {\n AlertCircle,\n ArrowLeft,\n Check,\n Loader2,\n} from 'lucide-react';\nimport { useMemo, useRef, useState } from 'react';\n\nimport { Button } from '@/components/base/buttons';\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from '@/components/base/command';\nimport { Text } from '@/components/typography';\n\nimport { useFilters } from '../filter-context';\nimport { interpolateFilterString } from '../filters.strings';\nimport type { FilterConfig, FilterOption } from '../filters.types';\nimport { useAsyncOptions } from '../hooks';\n\n// ---------------------------------------------------------------------------\n// Props\n// ---------------------------------------------------------------------------\n\ninterface AsyncFilterContentProps {\n filter: FilterConfig;\n value: string[];\n onFilterChange: (value: string[]) => void;\n onBackToFilterList: () => void;\n onClose: () => void;\n isFromMainFilterButton?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\n/**\n * Async Filter Content – renders inside the popover pipeline.\n *\n * Matches the layout of RegularFilterContent (header + command list + footer)\n * but fetches options asynchronously via TanStack Query.\n */\nexport function AsyncFilterContent({\n filter,\n value,\n onFilterChange,\n onBackToFilterList,\n onClose,\n isFromMainFilterButton = false,\n}: AsyncFilterContentProps) {\n const { strings, cacheAsyncOptions, getAsyncOptionLabel } = useFilters();\n const [searchInput, setSearchInput] = useState('');\n const [tempValue, setTempValue] = useState<string[]>(value ?? []);\n\n // Sync tempValue when external value changes\n const prevValueRef = useRef(value);\n if (value !== prevValueRef.current) {\n prevValueRef.current = value;\n setTempValue(value ?? []);\n }\n\n const {\n options,\n isLoading,\n isFetching,\n isError,\n refetch,\n isBelowMinQuery,\n minQueryLength,\n } = useAsyncOptions(filter, searchInput, true);\n\n // Populate the shared async options cache for label resolution in FilterValueDisplay\n if (options.length > 0) {\n cacheAsyncOptions(filter.key, options);\n }\n\n const isMulti = filter.multiple !== false;\n const maxSelected = filter.maxSelected;\n const showBackButton = Boolean(isFromMainFilterButton);\n\n // Sort options: selected items first, then the rest.\n // Also include cached selected items that may not be in current search results.\n const sortedOptions = useMemo(() => {\n const selectedSet = new Set(tempValue);\n const optionValueSet = new Set(options.map((o) => o.value));\n\n // Resolve selected items missing from current results via the global cache\n const missingSelected: FilterOption[] = [];\n for (const val of tempValue) {\n if (!optionValueSet.has(val)) {\n const label = getAsyncOptionLabel(filter.key, val);\n if (label) {\n missingSelected.push({ value: val, label, icon: filter.icon });\n }\n }\n }\n\n const all = [...missingSelected, ...options];\n return all.sort((a, b) => {\n const aSelected = selectedSet.has(a.value) ? 0 : 1;\n const bSelected = selectedSet.has(b.value) ? 0 : 1;\n return aSelected - bSelected;\n });\n }, [options, tempValue, filter.key, filter.icon, getAsyncOptionLabel]);\n\n const handleValueSelect = (optionValue: string) => {\n if (isMulti) {\n if (tempValue.includes(optionValue)) {\n setTempValue(tempValue.filter((v) => v !== optionValue));\n } else {\n if (maxSelected && tempValue.length >= maxSelected) return;\n setTempValue([...tempValue, optionValue]);\n }\n } else {\n setTempValue([optionValue]);\n if (filter.closeOnSelect === true) {\n onFilterChange([optionValue]);\n onClose();\n }\n }\n };\n\n const handleDone = () => {\n onFilterChange(tempValue);\n onClose();\n };\n\n // Render the status area inside CommandEmpty\n const emptyContent = useMemo(() => {\n if (isLoading || isFetching) {\n return (\n <div className=\"flex items-center justify-center gap-2 py-4\">\n <Loader2 className=\"text-muted-foreground size-4 animate-spin\" />\n <Text tag=\"span\" size=\"xs\" type=\"secondary\">\n {strings.searching}\n </Text>\n </div>\n );\n }\n\n if (isError) {\n return (\n <div className=\"flex flex-col items-center gap-2 py-4\">\n <div className=\"flex items-center gap-1.5\">\n <AlertCircle className=\"text-destructive size-4\" />\n <Text tag=\"span\" size=\"xs\" type=\"secondary\">\n {strings.fetchError}\n </Text>\n </div>\n <Button\n variant=\"secondary\"\n buttonStyle=\"outline\"\n size=\"xs\"\n onClick={(e) => {\n e.stopPropagation();\n void refetch();\n }}\n >\n {strings.retryFetch}\n </Button>\n </div>\n );\n }\n\n if (isBelowMinQuery) {\n return (\n <div className=\"text-muted-foreground flex items-center justify-center py-4\">\n <Text tag=\"span\" size=\"xs\" type=\"secondary\">\n {interpolateFilterString(strings.minQueryHint, {\n min: minQueryLength,\n })}\n </Text>\n </div>\n );\n }\n\n return strings.noOptionsFound;\n }, [\n isLoading,\n isFetching,\n isError,\n isBelowMinQuery,\n minQueryLength,\n strings,\n refetch,\n ]);\n\n return (\n <>\n {/* Header – matches RegularFilterContent */}\n <div className=\"flex items-center border-b p-2\">\n {Boolean(showBackButton) && (\n <Button\n variant=\"secondary\"\n buttonStyle=\"ghost\"\n className=\"mr-2 h-8 w-8 p-0\"\n onClick={onBackToFilterList}\n aria-label={strings.backToFilters}\n >\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n )}\n <div className=\"flex flex-col\">\n <Text tag=\"span\" size=\"xs\" weight=\"semibold\">\n {filter.label}\n </Text>\n <Text tag=\"span\" size=\"xs\" type=\"secondary\">\n {strings.selectValues}\n </Text>\n </div>\n </div>\n\n {/* Command list with async search */}\n <Command shouldFilter={false}>\n <CommandInput\n placeholder={interpolateFilterString(\n strings.searchPlaceholder,\n { filterLabel: filter.label.toLowerCase() },\n )}\n value={searchInput}\n onValueChange={setSearchInput}\n />\n <CommandList>\n {sortedOptions.length === 0 ? (\n <CommandEmpty>{emptyContent}</CommandEmpty>\n ) : (\n <CommandGroup>\n {Boolean(isFetching && !isLoading) && (\n <div className=\"flex items-center gap-1.5 px-2 py-1\">\n <Loader2 className=\"text-muted-foreground size-3 animate-spin\" />\n <Text tag=\"span\" size=\"xs\" type=\"secondary\">\n {strings.searching}\n </Text>\n </div>\n )}\n {sortedOptions.map((option) => (\n <CommandItem\n key={option.value}\n onSelect={() => handleValueSelect(option.value)}\n disabled={\n option.disabled ||\n (!!maxSelected &&\n tempValue.length >= maxSelected &&\n !tempValue.includes(option.value))\n }\n className=\"flex items-center gap-2\"\n >\n {option.icon}\n <Text tag=\"span\" size=\"xs\">\n {option.label}\n </Text>\n {tempValue.includes(option.value) && (\n <span className=\"ml-auto\">\n <Check className=\"h-4 w-4\" />\n </span>\n )}\n </CommandItem>\n ))}\n </CommandGroup>\n )}\n </CommandList>\n </Command>\n\n {/* Footer – matches RegularFilterContent */}\n <div className=\"flex justify-between border-t p-2\">\n <Text tag=\"span\" size=\"xs\" type=\"secondary\">\n {interpolateFilterString(strings.selected, {\n count: tempValue.length,\n filterLabel: (tempValue.length > 1 ? filter.pluralLabel : filter.label) ?? filter.label,\n })}\n </Text>\n <div className=\"flex gap-2\">\n <Button\n variant=\"secondary\"\n buttonStyle=\"outline\"\n size=\"xs\"\n onClick={handleDone}\n >\n {strings.confirm}\n </Button>\n </div>\n </div>\n </>\n );\n}\n","import { isValid } from 'date-fns';\nimport type { DateRange } from 'react-day-picker';\nimport {\n DatePicker,\n type DateOutput,\n type DateRangeOutput,\n type PresetDateRange,\n} from '@/components/base/date-pickers';\nimport { cn } from '@/lib/utils';\nimport { useFilters } from '../filter-context';\nimport type { FilterConfig } from '../filters.types';\n\nconst EMPTY_PRESETS: PresetDateRange[] = [];\n\ninterface DateFacetProps {\n filter: FilterConfig;\n value: { start?: Date; end?: Date };\n onChange: (value: { start?: Date; end?: Date }) => void;\n className?: string;\n}\n\nexport function DateFacet({\n filter,\n value,\n onChange,\n className,\n}: DateFacetProps) {\n const { strings } = useFilters();\n\n const isRangeMode =\n filter.operators?.some((op) => op.value === 'between') ||\n filter.operator === 'between' ||\n filter.key.toLowerCase().includes('range') ||\n filter.key.toLowerCase().includes('between');\n\n const dateFormat = filter.dateFormat?.param ?? 'yyyy-MM-dd';\n const readableFormat = filter.dateFormat?.display ?? 'PPP';\n const placeholder = isRangeMode\n ? (filter.datePickerConfig?.noRangePlaceholder ??\n filter.placeholder ??\n strings.calendar.notDateRangeSelected)\n : (filter.datePickerConfig?.noDatePlaceholder ??\n filter.placeholder ??\n strings.calendar.notDateSelected);\n const withConfirm = Boolean(filter.datePickerConfig?.showConfirmButton);\n const closeOnSelect = filter.datePickerConfig?.autoApply ?? !withConfirm;\n const showShortcuts = filter.datePickerConfig?.showShortcuts ?? true;\n\n const rangeValue: DateRange | undefined =\n isRangeMode && (value.start || value.end)\n ? { from: value.start, to: value.end }\n : undefined;\n\n const singleValue =\n !isRangeMode && value.start && isValid(value.start)\n ? value.start\n : undefined;\n\n const commonProps = {\n format: dateFormat,\n readableFormat,\n placeholder,\n disablePortal: true,\n numberOfMonths: 1,\n className: cn('date-facet--component', 'w-full', className),\n };\n\n const handleSingleChange = (output: DateOutput) => {\n onChange({ start: output.date ?? undefined, end: undefined });\n };\n\n const handleRangeChange = (output: DateRangeOutput) => {\n onChange({\n start: output.range?.from ?? undefined,\n end: output.range?.to ?? undefined,\n });\n };\n\n if (isRangeMode) {\n const presetsProp = showShortcuts ? undefined : EMPTY_PRESETS;\n return (\n <DatePicker\n mode=\"range\"\n value={rangeValue}\n onChange={handleRangeChange}\n withConfirm={withConfirm}\n closeOnSelect={closeOnSelect}\n presets={presetsProp}\n {...commonProps}\n />\n );\n }\n\n return (\n <DatePicker\n mode=\"single\"\n value={singleValue}\n onChange={handleSingleChange}\n closeOnSelect={closeOnSelect}\n {...commonProps}\n />\n );\n}\n","import { format, parse, isValid } from 'date-fns';\nimport { ArrowLeft } from 'lucide-react';\nimport { Button } from '@/components/base/buttons';\nimport { DateFacet } from '../facets/date-facet';\nimport { Text } from '@/components/typography';\nimport { useFilters } from '../filter-context';\nimport type { FilterConfig } from '../filters.types';\n\ninterface DateFilterContentProps {\n filter: FilterConfig;\n value: string[];\n onFilterChange: (value: string[]) => void;\n onBackToFilterList: () => void;\n isFromMainFilterButton?: boolean;\n}\n\nexport function DateFilterContent({\n filter,\n value,\n onFilterChange,\n onBackToFilterList,\n isFromMainFilterButton = false,\n}: DateFilterContentProps) {\n const { strings } = useFilters();\n\n const parseInputDate = (input?: string) => {\n if (!input) {\n return undefined;\n }\n\n if (filter.dateFormat?.param) {\n const parsed = parse(input, filter.dateFormat.param, new Date());\n return isValid(parsed) ? parsed : undefined;\n }\n\n const parsed = new Date(input);\n return isValid(parsed) ? parsed : undefined;\n };\n\n const startDate = parseInputDate(value[0]);\n const endDate = parseInputDate(value[1]);\n\n // Default date format for filter params - matches backend expectations\n const defaultDateFormat = 'yyyy-MM-dd';\n\n const formatOutputDate = (date?: Date) => {\n if (!date || !isValid(date)) {\n return undefined;\n }\n\n return format(date, filter.dateFormat?.param ?? defaultDateFormat);\n };\n\n const handleDateChange = ({ start, end }: { start?: Date; end?: Date }) => {\n const next: string[] = [];\n const formattedStart = formatOutputDate(start);\n const formattedEnd = formatOutputDate(end);\n\n if (formattedStart) {\n next.push(formattedStart);\n }\n\n if (formattedEnd) {\n next.push(formattedEnd);\n }\n\n onFilterChange(next);\n };\n\n const showBackButton = Boolean(isFromMainFilterButton);\n\n const facetValue = { start: startDate, end: endDate };\n\n return (\n <div className=\"flex flex-col\">\n <div className=\"flex items-center gap-2 border-b border-border/60 px-3 py-2.5\">\n {!!showBackButton && (\n <Button\n type=\"button\"\n variant=\"secondary\"\n buttonStyle=\"ghost\"\n size=\"icon-xs\"\n onClick={onBackToFilterList}\n className=\"inline-flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground\"\n aria-label={strings.backToFilters}\n >\n <ArrowLeft className=\"size-3.5\" />\n </Button>\n )}\n <Text tag=\"span\" weight=\"semibold\" className=\"truncate\">\n {filter.label}\n </Text>\n </div>\n\n <div className=\"p-2\">\n <DateFacet\n filter={filter}\n value={facetValue}\n onChange={handleDateChange}\n />\n </div>\n </div>\n );\n}\n","import { X } from 'lucide-react';\nimport { Component, type ErrorInfo, type ReactNode, useMemo } from 'react';\nimport { Button } from '@/components/base/buttons';\nimport { Text } from '@/components/typography';\nimport { useFilters } from '../filter-context';\nimport { interpolateFilterString } from '../filters.strings';\n\ninterface Props {\n children: ReactNode;\n filterKey?: string;\n fallback?: ReactNode;\n}\n\ninterface State {\n hasError: boolean;\n error: Error | null;\n}\n\ninterface FilterErrorBoundaryLabels {\n title: string;\n reset: string;\n getDescription: (filterKey?: string) => string;\n unknownError: string;\n}\n\nclass FilterErrorBoundaryBase extends Component<\n Props & { labels: FilterErrorBoundaryLabels },\n State\n> {\n public state: State = {\n hasError: false,\n error: null,\n };\n\n /**\n * Update state when an error occurs\n */\n public static getDerivedStateFromError(error: Error): State {\n return { hasError: true, error };\n }\n\n /**\n * Log the error to the console and to an error tracking service if available\n */\n public componentDidCatch(error: Error, errorInfo: ErrorInfo) {\n if (import.meta.env?.DEV) {\n\t console.error('Filter error:', error, errorInfo);\n }\n\n // Report to error monitoring service if available\n // This is where you would integrate with services like Sentry\n if (typeof window !== 'undefined' && window.dispatchEvent) {\n window.dispatchEvent(\n new CustomEvent('filter-error', {\n detail: {\n filterKey: this.props.filterKey,\n error,\n errorInfo,\n },\n }),\n );\n }\n }\n\n /**\n * Reset the error state\n */\n private handleReset = () => {\n this.setState({ hasError: false, error: null });\n };\n\n public render() {\n if (this.state.hasError) {\n const { fallback, filterKey, labels } = this.props;\n if (fallback) {\n return fallback;\n }\n\n return (\n <div className=\"rounded-md border border-destructive/30 bg-destructive/10 p-3 text-xs text-destructive\">\n <div className=\"mb-1 flex items-center justify-between\">\n <Text tag=\"span\" weight=\"semibold\">\n {labels.title}\n </Text>\n <Button\n type=\"button\"\n variant=\"error\"\n buttonStyle=\"ghost\"\n size=\"icon-xs\"\n onClick={this.handleReset}\n className=\"size-6 rounded-full p-0\"\n aria-label={labels.reset}\n >\n <X className=\"h-4 w-4\" />\n </Button>\n </div>\n <Text size=\"xs\">{labels.getDescription(filterKey)}</Text>\n <Text size=\"xs\" type=\"error\" className=\"mt-1 font-mono\">\n {this.state.error?.message || labels.unknownError}\n </Text>\n </div>\n );\n }\n\n return this.props.children;\n }\n}\n\nexport function FilterErrorBoundary(props: Props) {\n const { strings } = useFilters();\n\n const labels = useMemo<FilterErrorBoundaryLabels>(\n () => ({\n title: strings.error.title,\n reset: strings.clear,\n getDescription: (filterKey?: string) =>\n filterKey\n ? interpolateFilterString(strings.error.descriptionWithKey, {\n filterKey,\n })\n : strings.error.generic,\n unknownError: strings.error.unknown,\n }),\n [strings],\n );\n\n return <FilterErrorBoundaryBase {...props} labels={labels} />;\n}\n","import { CommandItem } from '@/components/base/command';\nimport { Text } from '@/components/typography';\nimport { useFilters } from '../filter-context';\nimport { FilterType, type FilterConfig } from '../filters.types';\n\ninterface FilterListItemProps {\n filter: FilterConfig;\n onSelect: () => void;\n}\n\n/**\n * FilterListItem — single row inside the Filters-button menu.\n *\n * Shows a leading icon (rendered as-is so its native colour comes through),\n * the filter label as the primary line, and a secondary \"{n} options\" line\n * for SELECT-style filters or the \"select date range\" hint for DATE filters.\n *\n * All typography flows through the base Text component so the global\n * scale + theming applies consistently.\n */\nexport function FilterListItem({ filter, onSelect }: FilterListItemProps) {\n const { strings } = useFilters();\n\n const subtitle =\n filter.type === FilterType.DATE\n ? filter.operator === 'between'\n ? strings?.selectDateRange\n : strings?.selectDate\n : filter.options\n ? `${filter.options.length} ${strings?.options ?? ''}`.trim()\n : null;\n\n return (\n <CommandItem\n key={filter.key}\n onSelect={onSelect}\n className=\"flex items-center gap-3 rounded-none px-3 py-2\"\n >\n {!!filter.icon && (\n <span className=\"shrink-0 text-muted-foreground\">{filter.icon}</span>\n )}\n <div className=\"flex min-w-0 flex-col leading-tight\">\n <Text tag=\"span\" weight=\"semibold\" className=\"truncate\">\n {filter.label}\n </Text>\n {!!subtitle && (\n <Text tag=\"span\" size=\"xs\" type=\"secondary\" className=\"truncate\">\n {subtitle}\n </Text>\n )}\n </div>\n </CommandItem>\n );\n}\n","import {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandList,\n CommandSeparator,\n} from '@/components/base/command';\nimport { useFilters } from '../filter-context';\nimport type { FilterConfig } from '../filters.types';\nimport { FilterListItem } from './filter-list-item';\n\ninterface FilterListContentProps {\n availableFilters: FilterConfig[];\n activeFilters: FilterConfig[];\n onFilterSelect: (filter: FilterConfig) => void;\n}\n\n/**\n * Filter Popover Content Component\n *\n * This component provides the content wrapper for filter popovers.\n * It handles:\n * - Consistent popover styling\n * - Content layout and spacing\n * - Responsive behavior\n * - Animation and transitions\n *\n * The component is used to wrap filter content in a consistent\n * popover interface across different filter types.\n */\n\nexport function FilterListContent({\n availableFilters,\n activeFilters,\n onFilterSelect,\n}: FilterListContentProps) {\n const { strings } = useFilters();\n\n // Handle filter selection with explicit closing of popover\n const handleFilterSelect = (filter: FilterConfig) => {\n // Call the passed onFilterSelect with the filter\n onFilterSelect(filter);\n };\n\n // Group headings get the same px-3 horizontal as items so they all\n // align with the search input above.\n const groupHeadingClasses =\n '[&_[cmdk-group-heading]]:px-3 [&_[cmdk-group-heading]]:pb-1 [&_[cmdk-group-heading]]:pt-2 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:uppercase [&_[cmdk-group-heading]]:tracking-wider [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group-heading]]:font-medium';\n\n return (\n <Command className=\"rounded-none p-0\">\n <div className=\"border-b border-border/50 px-3 py-2\">\n <CommandInput className=\"text-xs\" placeholder={strings.searchFilters} />\n </div>\n <CommandList className=\"max-h-72 py-1\">\n <CommandEmpty className=\"px-3 py-4 text-center text-xs text-muted-foreground\">\n {strings.noFiltersAvailable}\n </CommandEmpty>\n\n {availableFilters.length > 0 && (\n <CommandGroup heading={strings.availableFilters} className={`p-0 ${groupHeadingClasses}`}>\n {availableFilters.map((filter) => (\n <FilterListItem\n key={filter.key}\n filter={filter}\n onSelect={() => handleFilterSelect(filter)}\n />\n ))}\n </CommandGroup>\n )}\n\n {activeFilters.length > 0 && (\n <>\n <CommandSeparator className=\"my-1\" />\n <CommandGroup heading={strings.activeFilters} className={`p-0 ${groupHeadingClasses}`}>\n {activeFilters.map((filter) => (\n <FilterListItem\n key={filter.key}\n filter={filter}\n onSelect={() => handleFilterSelect(filter)}\n />\n ))}\n </CommandGroup>\n </>\n )}\n </CommandList>\n </Command>\n );\n}\n","import { ArrowLeft } from 'lucide-react';\nimport { useState, useEffect } from 'react';\n\nimport { Button } from '@/components/base/buttons';\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from '@/components/base/command';\nimport { Text } from '@/components/typography';\n\nimport { useFilters } from '../filter-context';\nimport { interpolateFilterString } from '../filters.strings';\nimport { FilterType, type FilterConfig } from '../filters.types';\n\ninterface RegularFilterContentProps {\n filter: FilterConfig;\n value: string[];\n onFilterChange: (value: string[]) => void;\n onBackToFilterList: () => void;\n onClose: () => void;\n isFromMainFilterButton?: boolean;\n}\n\n/**\n * RegularFilterContent — popover body for SELECT / MULTI_SELECT filters.\n *\n * Layout:\n * - Compact header: optional back-arrow, label as small uppercase eyebrow.\n * - Inline search input (only if the filter has more than 5 options).\n * - Tight list of options (sm padding, xs font, ml-auto check on the right).\n * - Compact footer: selected count on the leading edge, Confirm button on\n * the trailing edge — only rendered when the user has changed selection.\n *\n * Sizes are tuned to feel like a native menu, not a card. Popover width\n * stays at ~260-300px so labels read at one glance.\n */\nexport function RegularFilterContent({\n filter,\n value,\n onFilterChange,\n onBackToFilterList,\n onClose,\n isFromMainFilterButton = false,\n}: RegularFilterContentProps) {\n const { strings } = useFilters();\n\n const isMultiSelect =\n filter.multiple === true || filter.type === FilterType.MULTI_SELECT;\n const showBackButton = Boolean(isFromMainFilterButton);\n\n const [tempValue, setTempValue] = useState<string[]>(value || []);\n\n useEffect(() => {\n setTempValue(value || []);\n }, [value]);\n\n const handleValueSelect = (optionValue: string) => {\n if (isMultiSelect) {\n const newValue = tempValue.includes(optionValue)\n ? tempValue.filter((v) => v !== optionValue)\n : [...tempValue, optionValue];\n setTempValue(newValue);\n } else {\n setTempValue([optionValue]);\n\n if (filter.closeOnSelect === true) {\n onFilterChange([optionValue]);\n onClose();\n }\n }\n };\n\n const handleDone = () => {\n try {\n onFilterChange(tempValue);\n onClose();\n } catch (error) {\n if (import.meta.env?.DEV) {\n\t console.error('Error applying filter:', error);\n }\n }\n };\n\n const isDirty = JSON.stringify(tempValue.slice().sort()) !== JSON.stringify((value ?? []).slice().sort());\n\n return (\n <div className=\"flex flex-col\">\n {/* SECTION 1 — Label header */}\n <div className=\"flex items-center gap-2 border-b border-border/60 px-3 py-2.5\">\n {!!showBackButton && (\n <Button\n type=\"button\"\n variant=\"secondary\"\n buttonStyle=\"ghost\"\n size=\"icon-xs\"\n onClick={onBackToFilterList}\n className=\"inline-flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground\"\n aria-label={strings.backToFilters}\n >\n <ArrowLeft className=\"size-3.5\" />\n </Button>\n )}\n <Text tag=\"span\" size=\"xs\" weight=\"semibold\" className=\"truncate\">\n {filter.label}\n </Text>\n </div>\n\n <Command className=\"rounded-none p-0\">\n {/* SECTION 2 — Search.\n Same px-3 py-2.5 as the label section. */}\n <div className=\"border-b border-border/50 px-3 py-2.5\">\n <CommandInput\n className=\"text-xs\"\n placeholder={interpolateFilterString(\n strings.searchPlaceholder,\n { filterLabel: filter.label.toLowerCase() },\n )}\n />\n </div>\n\n {/* SECTION 3 — Values list.\n Same px-3 py-2.5 outer padding as the other two sections.\n Items inside have ADDITIONAL inner padding (px-2) so option\n labels are slightly more indented than the section frame —\n that's what tells the eye \"these are list rows, not header\n text\". Total label inset: 12px (section) + 8px (item) = 20px. */}\n <CommandList className=\"max-h-64 px-3 py-2\">\n <CommandEmpty>\n <Text size=\"xs\" type=\"secondary\" align=\"center\" className=\"py-4\">\n {strings.noOptionsFound}\n </Text>\n </CommandEmpty>\n <CommandGroup className=\"p-0 [&_[cmdk-group]]:p-0\">\n {filter.options?.map((option) => {\n const isSelected = tempValue.includes(option.value);\n // data-checked toggles the CommandItem's built-in\n // CheckIcon (rendered after children with ml-auto).\n return (\n <CommandItem\n key={option.value}\n onSelect={() => handleValueSelect(option.value)}\n data-checked={isSelected || undefined}\n disabled={option.disabled}\n className=\"flex items-start gap-2.5 rounded-md px-2 py-2 data-[checked=true]:**:[svg]:text-primary\"\n >\n {!!option.icon && (\n <span className=\"mt-0.5 shrink-0 text-muted-foreground\">\n {option.icon}\n </span>\n )}\n <div className=\"flex min-w-0 flex-1 flex-col leading-tight\">\n <Text\n tag=\"span\"\n size=\"xs\"\n weight={isSelected ? 'medium' : 'regular'}\n className=\"truncate\"\n >\n {option.label}\n </Text>\n {!!option.description && (\n <Text\n tag=\"span\"\n size=\"xxs\"\n type=\"secondary\"\n className=\"truncate mt-0.5\"\n >\n {option.description}\n </Text>\n )}\n </div>\n </CommandItem>\n );\n })}\n </CommandGroup>\n </CommandList>\n </Command>\n\n {/* Compact footer — only shows when dirty */}\n {!!isDirty && (\n <div className=\"flex items-center justify-between gap-2 border-t border-border/60 px-2.5 py-1.5\">\n <Text tag=\"span\" size=\"xxs\" type=\"secondary\" className=\"tabular-nums\">\n {interpolateFilterString(strings.selected, {\n count: tempValue.length,\n filterLabel: (tempValue.length > 1 ? filter.pluralLabel : filter.label) ?? filter.label,\n })}\n </Text>\n <Button variant=\"primary\" size=\"xs\" onClick={handleDone}>\n {strings.confirm}\n </Button>\n </div>\n )}\n </div>\n );\n}\n","import { X, Plus } from 'lucide-react';\nimport React, { useState, useCallback, type KeyboardEvent } from 'react';\nimport { Badge } from '@/components/base/badge';\nimport { Button } from '@/components/base/buttons';\nimport { Input } from '@/components/base/forms';\nimport { Text } from '@/components/typography';\nimport { cn } from '@/lib/utils';\nimport { useFilters } from '../filter-context';\nimport type { FilterConfig } from '../filters.types';\n\ninterface TagsFacetProps {\n filter: FilterConfig;\n value: string[];\n onChange: (value: string[]) => void;\n className?: string;\n}\n\n/**\n * Tags Filter Facet\n *\n * This component implements a tags input filter that allows users to:\n * - Enter tags through an input field\n * - Add tags by pressing Enter or clicking the add button\n * - View all selected tags as removable badges\n * - Remove individual tags by clicking the X on each badge\n *\n * The component is ideal for filtering by multiple tags or keywords\n * where users need to see all selected values at once.\n */\n\nfunction TagsFacetComponent({\n filter,\n value,\n onChange,\n className,\n}: TagsFacetProps) {\n const { strings } = useFilters();\n const [inputValue, setInputValue] = useState('');\n // Handle adding a new tag\n const handleAddTag = useCallback(() => {\n const trimmedValue = inputValue.trim();\n\n // Don't add empty tags or duplicates\n if (!trimmedValue || value.includes(trimmedValue)) {\n return;\n }\n\n onChange([...value, trimmedValue]);\n setInputValue('');\n }, [inputValue, value, onChange]);\n\n // Handle removing a tag\n const handleRemoveTag = useCallback(\n (tagToRemove: string) => {\n onChange(value.filter((tag) => tag !== tagToRemove));\n },\n [value, onChange],\n );\n\n // Handle keyboard events\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n handleAddTag();\n }\n };\n\n // Clear all tags\n const handleClearAll = useCallback(() => {\n onChange([]);\n setInputValue('');\n }, [onChange]);\n\n const hasTags = value.length > 0;\n const tagCountLabel =\n value.length === 1 ? strings.tag : strings.tags;\n const tagSummary = hasTags ? (\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <Text tag=\"span\" size=\"xs\" type=\"secondary\">\n {value.length} {tagCountLabel}\n </Text>\n <Button\n onClick={handleClearAll}\n variant=\"secondary\"\n buttonStyle=\"ghost\"\n size=\"xs\"\n className=\"h-auto px-1 py-0 text-xs text-muted-foreground hover:text-foreground\"\n type=\"button\"\n aria-label={strings.clearAll}\n >\n {strings.clearAll}\n </Button>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n {value.map((tag) => (\n <Badge\n key={tag}\n variant=\"secondary\"\n className=\"flex items-center gap-1 py-1 pl-2 pr-1\"\n >\n <Text tag=\"span\" size=\"xs\">{tag}</Text>\n <Button\n onClick={() => handleRemoveTag(tag)}\n variant=\"secondary\"\n buttonStyle=\"ghost\"\n size=\"icon-xs\"\n className=\"ml-1 size-4 rounded-full p-0 hover:bg-muted-foreground/20\"\n type=\"button\"\n aria-label={`${strings.removeTag} ${tag}`}\n >\n <X className=\"h-3 w-3\" />\n </Button>\n </Badge>\n ))}\n </div>\n </div>\n ) : null;\n\n return (\n <div className={cn('tags-facet--component', 'space-y-3', className)}>\n {/* Input section */}\n <div className=\"flex gap-2\">\n <div className=\"relative flex-1\">\n <Input\n type=\"text\"\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={\n filter.placeholder ?? strings.enterTag\n }\n className=\"h-10\"\n />\n </div>\n <Button\n onClick={handleAddTag}\n disabled={!inputValue.trim()}\n className=\"h-10 px-4\"\n type=\"button\"\n >\n <Plus className=\"h-4 w-4\" />\n <span className=\"sr-only\">{strings.addTag}</span>\n </Button>\n </div>\n\n {/* Tags display section */}\n {tagSummary}\n </div>\n );\n}\n\nexport const TagsFacet = React.memo(TagsFacetComponent);\nTagsFacet.displayName = 'TagsFacet';\n","import { ArrowLeft } from 'lucide-react';\nimport { useState, useEffect } from 'react';\nimport { Button } from '@/components/base/buttons';\nimport { TagsFacet } from '../facets/tags-facet';\nimport { Text } from '@/components/typography';\nimport { useFilters } from '../filter-context';\nimport type { FilterConfig } from '../filters.types';\n\ninterface TagsFilterContentProps {\n filter: FilterConfig;\n value: string[];\n onFilterChange: (value: string[]) => void;\n onBackToFilterList: () => void;\n onClose: () => void;\n isFromMainFilterButton?: boolean;\n}\n\n/**\n * Tags Filter Content Component\n *\n * This component provides the content for tags filter popovers.\n * It handles:\n * - Tag input and management\n * - Multiple tag selection\n * - Displaying and removing tags\n * - Applying filter changes\n *\n * The component wraps the TagsFacet component and provides\n * the popover-specific UI elements like header and action buttons.\n */\n\nexport function TagsFilterContent({\n filter,\n value,\n onFilterChange,\n onBackToFilterList,\n onClose,\n isFromMainFilterButton = false,\n}: TagsFilterContentProps) {\n const { strings } = useFilters();\n\n // Use local state to track temporary values before committing\n const [tempValue, setTempValue] = useState<string[]>(value || []);\n const showBackButton = Boolean(isFromMainFilterButton);\n const tagCountLabel =\n tempValue.length === 1 ? strings.tag : strings.tags;\n\n // Update tempValue when value changes (for initial or external updates)\n useEffect(() => {\n setTempValue(value || []);\n }, [value]);\n\n // Apply changes when Done is clicked\n const handleDone = () => {\n try {\n onFilterChange(tempValue);\n onClose();\n } catch (error) {\n if (import.meta.env?.DEV) {\n\t console.error('Error applying filter:', error);\n }\n }\n };\n\n const isDirty = JSON.stringify(tempValue.slice().sort()) !== JSON.stringify((value ?? []).slice().sort());\n\n return (\n <div className=\"flex flex-col\">\n <div className=\"flex items-center gap-2 border-b border-border/60 px-3 py-2.5\">\n {!!showBackButton && (\n <Button\n type=\"button\"\n variant=\"secondary\"\n buttonStyle=\"ghost\"\n size=\"icon-xs\"\n onClick={onBackToFilterList}\n className=\"inline-flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground\"\n aria-label={strings.backToFilters}\n >\n <ArrowLeft className=\"size-3.5\" />\n </Button>\n )}\n <Text tag=\"span\" weight=\"semibold\" className=\"truncate\">\n {filter.label}\n </Text>\n </div>\n\n <div className=\"p-2\">\n <TagsFacet\n filter={filter}\n value={tempValue}\n onChange={setTempValue}\n />\n </div>\n\n {!!isDirty && (\n <div className=\"flex items-center justify-between gap-2 border-t border-border/60 px-2.5 py-1.5\">\n <Text tag=\"span\" size=\"xxs\" type=\"secondary\" className=\"tabular-nums\">\n {tempValue.length} {tagCountLabel}\n </Text>\n <Button variant=\"primary\" size=\"xs\" onClick={handleDone}>\n {strings.confirm}\n </Button>\n </div>\n )}\n </div>\n );\n}\n","import { PopoverContent } from '@/components/base/popover';\nimport { FilterType, type FilterConfig } from '../filters.types';\nimport { AsyncFilterContent } from './async-filter-content';\nimport { DateFilterContent } from './date-filter-content';\nimport { FilterListContent } from './filter-list-content';\nimport { RegularFilterContent } from './regular-filter-content';\nimport { TagsFilterContent } from './tags-filter-content';\n\ninterface FilterPopoverContentProps {\n activeFilterInPopover: FilterConfig | null;\n availableFilters: FilterConfig[];\n activeFilters: FilterConfig[];\n getFilterValue: (key: string) => string[];\n setFilterValue: (key: string, value: string[]) => void;\n onFilterSelect: (filter: FilterConfig) => void;\n onBackToFilterList: () => void;\n onClose: () => void;\n isFromMainFilterButton?: boolean; // Determines back button behavior\n}\n\n/**\n * Filter Popover Content Component\n *\n * This component provides the content wrapper for filter popovers.\n * It handles:\n * - Consistent popover styling\n * - Content layout and spacing\n * - Responsive behavior\n * - Animation and transitions\n *\n * The component is used to wrap filter content in a consistent\n * popover interface across different filter types.\n */\n\nexport function FilterPopoverContent({\n activeFilterInPopover,\n availableFilters,\n activeFilters,\n getFilterValue,\n setFilterValue,\n onFilterSelect,\n onBackToFilterList,\n onClose,\n isFromMainFilterButton = false,\n}: FilterPopoverContentProps) {\n const popoverWidth =\n activeFilterInPopover?.type === FilterType.DATE ||\n activeFilterInPopover?.type === FilterType.TAGS\n ? 'w-auto min-w-[320px] p-0 overflow-hidden rounded-lg shadow-lg'\n : activeFilterInPopover?.type === FilterType.ASYNC_SELECT\n ? 'w-72 p-0 overflow-hidden rounded-lg shadow-lg'\n : 'w-64 p-0 overflow-hidden rounded-lg shadow-lg';\n\n // Forward values directly so upstream can decide whether to add or clear the filter\n const handleSetFilterValue = (key: string, value: string[]) => {\n setFilterValue(key, value);\n };\n\n return (\n <PopoverContent className={popoverWidth} align=\"start\">\n {activeFilterInPopover ? (\n // Render specific filter content based on type\n activeFilterInPopover.type === FilterType.DATE ? (\n <DateFilterContent\n filter={activeFilterInPopover}\n value={getFilterValue(activeFilterInPopover.key)}\n onFilterChange={(value) =>\n handleSetFilterValue(\n activeFilterInPopover.key,\n value,\n )\n }\n onBackToFilterList={onBackToFilterList}\n isFromMainFilterButton={isFromMainFilterButton}\n />\n ) : activeFilterInPopover.type === FilterType.TAGS ? (\n <TagsFilterContent\n filter={activeFilterInPopover}\n value={getFilterValue(activeFilterInPopover.key)}\n onFilterChange={(value) =>\n handleSetFilterValue(\n activeFilterInPopover.key,\n value,\n )\n }\n onBackToFilterList={onBackToFilterList}\n onClose={onClose}\n isFromMainFilterButton={isFromMainFilterButton}\n />\n ) : activeFilterInPopover.type === FilterType.ASYNC_SELECT ? (\n <AsyncFilterContent\n filter={activeFilterInPopover}\n value={getFilterValue(activeFilterInPopover.key)}\n onFilterChange={(value) =>\n handleSetFilterValue(\n activeFilterInPopover.key,\n value,\n )\n }\n onBackToFilterList={onBackToFilterList}\n onClose={onClose}\n isFromMainFilterButton={isFromMainFilterButton}\n />\n ) : (\n <RegularFilterContent\n filter={activeFilterInPopover}\n value={getFilterValue(activeFilterInPopover.key)}\n onFilterChange={(value) =>\n handleSetFilterValue(\n activeFilterInPopover.key,\n value,\n )\n }\n onBackToFilterList={onBackToFilterList}\n onClose={onClose}\n isFromMainFilterButton={isFromMainFilterButton}\n />\n )\n ) : (\n // Render the list of available filters\n <FilterListContent\n availableFilters={availableFilters}\n activeFilters={activeFilters}\n onFilterSelect={onFilterSelect}\n />\n )}\n </PopoverContent>\n );\n}\n","/**\n * FilterPill — internal partial that wraps a single `ActiveFilterItem` with\n * its popover. Used by `FilterLayout` for both `display: 'always'` filters\n * and `active` regular filters since the rendering is identical except for\n * the `availableFilters` / `activeFilters` lists passed to the popover.\n *\n * Exported from `partials/index.ts` so consumers building a custom strip\n * around `<FilterProvider>` can re-use it without duplicating the popover\n * machinery.\n */\nimport { useRef, useState } from 'react';\n\nimport { Popover, PopoverTrigger } from '@/components/base/popover';\n\nimport type {\n FilterConfig,\n FilterOperator,\n OperatorOption,\n} from '../filters.types';\n\nimport { ActiveFilterItem } from './active-filter-item';\nimport { FilterErrorBoundary } from './filter-error-boundary';\nimport { FilterPopoverContent } from './filter-popover-content';\n\nexport interface FilterPillProps {\n filter: FilterConfig;\n value: string[];\n isActive: boolean;\n operator: FilterOperator;\n operators: OperatorOption[];\n onOperatorChange: (operator: FilterOperator) => void;\n onValueChange: (value: string[]) => void;\n onClear: () => void;\n /** Filters to render in the \"+\" list inside the popover. */\n availableFilters: FilterConfig[];\n /** Active regular filters list (for the popover header / context). */\n activeFilters: FilterConfig[];\n /** External signal to suppress popover open during operator change. */\n operatorChangeRef?: React.MutableRefObject<boolean>;\n}\n\nexport function FilterPill({\n filter,\n value,\n isActive,\n operator,\n operators,\n onOperatorChange,\n onValueChange,\n onClear,\n availableFilters,\n activeFilters,\n operatorChangeRef,\n}: FilterPillProps) {\n const localRef = useRef(false);\n const isOperatorChangeRef = operatorChangeRef ?? localRef;\n\n const [open, setOpen] = useState(false);\n\n return (\n <FilterErrorBoundary filterKey={filter.key}>\n <Popover\n open={open}\n onOpenChange={(isOpen) => {\n if (isOpen && isOperatorChangeRef.current) return;\n setOpen(isOpen);\n }}\n >\n <PopoverTrigger\n nativeButton={false}\n render={\n <div>\n <ActiveFilterItem\n filter={filter}\n value={value}\n isActive={isActive}\n operators={operators}\n operator={operator}\n onOperatorChange={(next) => {\n isOperatorChangeRef.current = true;\n onOperatorChange(next);\n setOpen(false);\n setTimeout(() => {\n isOperatorChangeRef.current = false;\n }, 100);\n }}\n onFilterClear={() => {\n setOpen(false);\n onClear();\n }}\n onFilterClick={() => {\n if (!isOperatorChangeRef.current) {\n setOpen(true);\n }\n }}\n />\n </div>\n }\n />\n\n <FilterPopoverContent\n activeFilterInPopover={filter}\n availableFilters={availableFilters}\n activeFilters={activeFilters}\n getFilterValue={() => value}\n setFilterValue={(_, next) => onValueChange(next)}\n onFilterSelect={() => {}}\n onBackToFilterList={() => {}}\n onClose={() => setOpen(false)}\n isFromMainFilterButton={false}\n />\n </Popover>\n </FilterErrorBoundary>\n );\n}\n\nFilterPill.displayName = 'FilterPill';\n","import { Filter } from 'lucide-react';\nimport { useState, useEffect } from 'react';\nimport { Button } from '@/components/base/buttons';\nimport {\n Popover,\n PopoverTrigger,\n} from '@/components/base/popover';\nimport { FILTER_ELEMENT_HEIGHT, type FilterConfig } from '../filters.types';\nimport { FilterPopoverContent } from './filter-popover-content';\n// import { useFilters } from '../filter-context'; // Currently unused\n\ninterface FiltersButtonProps {\n availableFilters: FilterConfig[];\n activeFilters: FilterConfig[];\n activeFilterInPopover: FilterConfig | null;\n getFilterValue: (key: string) => string[];\n setFilterValue: (key: string, value: string[]) => void;\n setActiveFilterInPopover: (filter: FilterConfig | null) => void;\n locale?: string;\n}\n\n/**\n * Filters Button Component\n *\n * This component provides the main button for adding and managing filters.\n * It handles:\n * - Opening the filter popover\n * - Managing filter selection state\n * - Handling filter actions (select, back, close)\n * - Supporting internationalization\n *\n * The component is used as the primary entry point for users to\n * add and configure filters in the application.\n */\n\nexport function FiltersButton({\n availableFilters,\n activeFilters,\n activeFilterInPopover,\n getFilterValue,\n setFilterValue,\n setActiveFilterInPopover,\n}: FiltersButtonProps) {\n // Control popover state explicitly\n const [isOpen, setIsOpen] = useState(false);\n\n // const { t } = useFilters(); // Currently unused\n\n // Handle filter selection - keep popover open\n const handleFilterSelect = (filter: FilterConfig) => {\n // Set the selected filter without closing the popover\n setActiveFilterInPopover(filter);\n };\n\n // Handle back to filter list action\n const handleBackToFilterList = () => {\n setActiveFilterInPopover(null);\n };\n\n // Handle complete close action - reset everything\n const handleClose = () => {\n setActiveFilterInPopover(null);\n setIsOpen(false);\n };\n\n // Reset active filter when popover closes\n useEffect(() => {\n if (!isOpen) {\n // Reset to filters view when popover is closed\n setActiveFilterInPopover(null);\n }\n }, [isOpen, setActiveFilterInPopover]);\n\n return (\n <Popover open={isOpen} onOpenChange={setIsOpen}>\n <PopoverTrigger\n render={\n <Button\n variant=\"secondary\" buttonStyle=\"outline\"\n className={`flex ${FILTER_ELEMENT_HEIGHT} items-center gap-1.5`}\n >\n <Filter className=\"h-4 w-4\" />\n </Button>\n }\n />\n <FilterPopoverContent\n activeFilterInPopover={activeFilterInPopover}\n availableFilters={availableFilters}\n activeFilters={activeFilters}\n getFilterValue={getFilterValue}\n setFilterValue={setFilterValue}\n onFilterSelect={handleFilterSelect}\n onBackToFilterList={handleBackToFilterList}\n onClose={handleClose}\n isFromMainFilterButton={true}\n />\n </Popover>\n );\n}\n","import { useMemo, useCallback } from 'react';\nimport { Button } from '@/components/base/buttons';\nimport { cn } from '@/lib/utils';\nimport { useFilters } from '../filter-context';\nimport { FilterType, type ActiveFilter, type FilterTab } from '../filters.types';\nimport { getDefaultOperatorForType } from '../operator-options';\n\ninterface FilterTabsProps {\n tabs: FilterTab[];\n}\n\n/**\n * Horizontal tab row for filter presets (Shopify admin style).\n *\n * - \"All\" tab (empty presets): active when zero non-search active filters\n * - Named tabs: active when presets exactly match non-search active filters\n * - Search filters are preserved across tab switches\n */\nexport function FilterTabs({ tabs }: FilterTabsProps) {\n const { activeFilters, filters, replaceFilters } = useFilters();\n\n const nonSearchFilters = useMemo(\n () => activeFilters.filter((f) => {\n const config = filters.find((fc) => fc.key === f.key);\n return config?.type !== FilterType.SEARCH;\n }),\n [activeFilters, filters],\n );\n\n const searchFilters = useMemo(\n () => activeFilters.filter((f) => {\n const config = filters.find((fc) => fc.key === f.key);\n return config?.type === FilterType.SEARCH;\n }),\n [activeFilters, filters],\n );\n\n const activeTabId = useMemo(() => {\n for (const tab of tabs) {\n // \"All\" tab: no presets → active when zero non-search filters\n if (tab.presets.length === 0) {\n if (nonSearchFilters.length === 0) return tab.id;\n continue;\n }\n\n // Named tab: bidirectional exact match\n if (tab.presets.length !== nonSearchFilters.length) continue;\n\n const allMatch = tab.presets.every((preset) => {\n const active = nonSearchFilters.find((f) => f.key === preset.key);\n if (!active) return false;\n\n const sortedPreset = [...preset.value].sort();\n const sortedActive = [...active.value].sort();\n if (sortedPreset.length !== sortedActive.length) return false;\n if (sortedPreset.some((v, i) => v !== sortedActive[i])) return false;\n\n // Check operator if specified in preset\n if (preset.operator && active.operator !== preset.operator) return false;\n\n return true;\n });\n\n if (allMatch) return tab.id;\n }\n\n return null;\n }, [tabs, nonSearchFilters]);\n\n const handleTabClick = useCallback(\n (tab: FilterTab) => {\n if (tab.presets.length === 0) {\n // \"All\" tab — keep only search filters\n replaceFilters([...searchFilters]);\n return;\n }\n\n const presetFilters: ActiveFilter[] = tab.presets.map((preset) => {\n const filterConfig = filters.find((fc) => fc.key === preset.key);\n const operator =\n preset.operator ??\n filterConfig?.operator ??\n (filterConfig\n ? getDefaultOperatorForType(filterConfig.type)\n : 'equals');\n\n return {\n id: preset.key,\n key: preset.key,\n value: preset.value,\n operator,\n };\n });\n\n replaceFilters([...searchFilters, ...presetFilters]);\n },\n [filters, searchFilters, replaceFilters],\n );\n\n if (tabs.length === 0) return null;\n\n return (\n <div className=\"flex flex-wrap gap-1.5\" role=\"tablist\">\n {tabs.map((tab) => {\n const isActive = activeTabId === tab.id;\n\n return (\n <Button\n key={tab.id}\n type=\"button\"\n variant=\"secondary\"\n buttonStyle=\"ghost\"\n size=\"xs\"\n role=\"tab\"\n aria-selected={isActive}\n onClick={() => handleTabClick(tab)}\n className={cn(\n 'rounded-md px-2.5 py-1 text-xs font-semibold transition-colors',\n isActive\n ? 'bg-foreground text-background'\n : 'bg-muted/60 text-muted-foreground hover:bg-muted hover:text-foreground',\n )}\n >\n {tab.label}\n {tab.count !== undefined && (\n <span\n className={cn(\n 'ml-1 tabular-nums',\n isActive\n ? 'text-background/70'\n : 'text-muted-foreground/70',\n )}\n >\n {tab.count}\n </span>\n )}\n </Button>\n );\n })}\n </div>\n );\n}\n","import { Loader2, X } from 'lucide-react';\nimport React, {\n type ChangeEvent,\n useState,\n useEffect,\n useRef,\n useCallback,\n} from 'react';\nimport { Input } from '@/components/base/forms/fields/input';\nimport { Button } from '@/components/base/buttons';\nimport { cn } from '@/lib/utils';\nimport { useFilters } from '../filter-context';\nimport { interpolateFilterString } from '../filters.strings';\nimport { FILTER_ELEMENT_HEIGHT, type FilterConfig } from '../filters.types';\n\ninterface SearchFacetProps {\n filter: FilterConfig;\n value: string[];\n onChange: (value: string[]) => void;\n className?: string;\n}\n\n/**\n * Search Filter Facet\n *\n * This component implements a text search filter that allows users to:\n * - Enter search terms\n * - Configure search behavior (contains, equals, etc.)\n * - Set debounce delay for performance\n * - Customize placeholder text and appearance\n *\n * The component integrates with the filter context to manage the search value\n * and provides a responsive search input interface.\n */\n\nfunction SearchFacetComponent({\n filter,\n value,\n onChange,\n className,\n}: SearchFacetProps) {\n const { strings, isNavigating } = useFilters();\n\n // Use local state for the input value - initialized from value prop\n const [inputValue, setInputValue] = useState(value[0] || '');\n // Ref mirror of inputValue so the sync effect can read it without depending on it\n const inputValueRef = useRef(inputValue);\n inputValueRef.current = inputValue;\n // Track if the component is mounted to avoid unwanted effects\n const mounted = useRef(false);\n // Keep track of timeout ID for cleanup\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n // Tracking the last value we emitted to prevent duplicate emissions\n const lastEmittedValue = useRef<string | null>(value[0] || null);\n // Track if we're currently handling user input to prevent interference\n const isUserTypingRef = useRef(false);\n\n // Set mounted flag on initial render\n useEffect(() => {\n mounted.current = true;\n return () => {\n mounted.current = false;\n // Clear any pending timeout on unmount\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n };\n }, []);\n\n // Update input value when props change (for URL sync/refresh)\n // Guarded by isNavigating to prevent stale prop overwrites during the\n // gap between debounce-fire and Inertia response arriving.\n useEffect(() => {\n // Skip if user is actively typing or navigation is in-flight\n if (isUserTypingRef.current || isNavigating) {\n return;\n }\n\n const currentInput = inputValueRef.current;\n\n // Handle empty value array - this happens when filters are cleared\n if (!value.length || value[0] === '') {\n if (currentInput !== '') {\n setInputValue('');\n lastEmittedValue.current = '';\n }\n return;\n }\n\n // Only update if the value is different from what we have\n // and different from what we last emitted\n if (\n value[0] !== undefined &&\n value[0] !== currentInput &&\n value[0] !== lastEmittedValue.current\n ) {\n setInputValue(value[0]);\n lastEmittedValue.current = value[0];\n }\n }, [value, isNavigating]);\n\n // Debounced update function that consistently handles ALL input changes\n const debouncedUpdate = useCallback(\n (newValue: string) => {\n // Don't emit the same value twice\n if (lastEmittedValue.current === newValue) {\n return;\n }\n\n // Clear previous timeout\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n\n // Set new timeout for debouncing\n timeoutRef.current = setTimeout(() => {\n if (mounted.current) {\n lastEmittedValue.current = newValue;\n isUserTypingRef.current = false;\n onChange([newValue]);\n }\n }, filter.delay ?? 500);\n },\n [onChange, filter.delay],\n );\n\n // Handle input change - works for both typing and deleting characters\n const handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {\n isUserTypingRef.current = true;\n const newValue = e.target.value;\n setInputValue(newValue);\n debouncedUpdate(newValue);\n };\n\n // Handle focusing the input\n const handleFocus = () => {\n isUserTypingRef.current = true;\n };\n\n // Handle blurring the input\n const handleBlur = () => {\n // Set a small delay before clearing the typing flag\n // This prevents immediate sync which could cause issues\n setTimeout(() => {\n isUserTypingRef.current = false;\n }, 100);\n };\n\n // Handle clear button click\n const handleClear = () => {\n isUserTypingRef.current = true;\n setInputValue('');\n debouncedUpdate('');\n };\n\n return (\n <div className={cn('search-facet--component', 'search-facet bg-background relative min-w-80', className)}>\n <Input\n type=\"text\"\n value={inputValue}\n onChange={handleInputChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n placeholder={\n filter.placeholder ??\n (() => {\n const label = filter.label.trim().toLowerCase();\n if (!label || label === 'search') {\n // Collapse \"Search …\" stray space when the\n // filter label would otherwise duplicate the\n // template's leading \"Search\" word.\n return interpolateFilterString(\n strings.searchPlaceholder,\n { filterLabel: '' },\n )\n .replace(/\\s+([….?!])/g, '$1')\n .replace(/\\s{2,}/g, ' ')\n .trim();\n }\n return interpolateFilterString(\n strings.searchPlaceholder,\n { filterLabel: label },\n );\n })()\n }\n className={`w-full px-3 py-1 pr-9 placeholder:leading-1 text-xs md:text-xs placeholder:text-xs ${FILTER_ELEMENT_HEIGHT}`}\n />\n {inputValue.trim() !== '' && !isNavigating && (\n <Button\n type=\"button\"\n variant=\"secondary\"\n buttonStyle=\"ghost\"\n size=\"icon\"\n onClick={handleClear}\n className=\"absolute right-1 top-1/2 h-6 w-6 -translate-y-1/2\"\n aria-label={strings.clearSearch}\n >\n <X className=\"h-3.5 w-3.5\" />\n </Button>\n )}\n {!!isNavigating && (\n <span className=\"text-muted-foreground absolute right-2 top-1/2 -translate-y-1/2\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n </span>\n )}\n </div>\n );\n}\n\nexport const SearchFacet = React.memo(SearchFacetComponent);\nSearchFacet.displayName = 'SearchFacet';\n","import { Text } from '@/components/typography';\nimport { cn } from '@/lib/utils';\nimport { SearchFacet } from '../facets/search-facet';\nimport type { FilterConfig } from '../filters.types';\n\ninterface SearchFiltersListProps {\n filters: FilterConfig[];\n getFilterValue: (key: string) => string[];\n setFilterValue: (key: string, value: string[]) => void;\n className?: string;\n}\n\n/**\n * Search Filters List Component\n *\n * This component provides a list of search filters that are always visible.\n * It handles:\n * - Rendering multiple search filters\n * - Managing filter values\n * - Applying custom styling\n * - Supporting responsive layout\n *\n * The component is used to display search filters that should be\n * immediately accessible to users without requiring a popover.\n */\n\nexport function SearchFiltersList({\n filters,\n getFilterValue,\n setFilterValue,\n className,\n}: SearchFiltersListProps) {\n return (\n <>\n {filters.map((filter) => (\n <div\n key={filter.key}\n className={cn(\n 'space-y-2',\n filter.displayConfig.className,\n className,\n )}\n >\n <SearchFacet\n filter={filter}\n value={getFilterValue(filter.key)}\n onChange={(newValue) =>\n setFilterValue(filter.key, newValue)\n }\n />\n {!!filter.description && (\n <Text size=\"xs\" type=\"secondary\">\n {filter.description}\n </Text>\n )}\n </div>\n ))}\n </>\n );\n}\n","/**\n * FilterLayout — default strip layout: search inputs inline, then either\n * \"always-visible\" or active filter pills, then the \"+\" button for the\n * remaining inactive filters.\n *\n * The heavy lifting now lives in two reusable pieces:\n * - `useFilterGroups()` (hook) — partitions filters into search /\n * always-visible / active / popover groups so consumers building a\n * custom strip can call this and place each group themselves.\n * - `<FilterPill>` (partial) — wraps `<ActiveFilterItem>` + popover so\n * the duplicated rendering between always-visible and active filters\n * collapses to a single component.\n */\nimport { useState } from 'react';\n\nimport { Button } from '@/components/base/buttons';\nimport { cn } from '@/lib/utils';\n\nimport { useFilters } from './filter-context';\nimport { interpolateFilterString } from './filters.strings';\nimport {\n type FilterConfig,\n type FilterTab,\n type FilterOperator,\n} from './filters.types';\nimport { useFilterGroups } from './hooks/use-filter-groups';\nimport { getOperatorsForType } from './operator-options';\n\nimport {\n FilterErrorBoundary,\n FiltersButton,\n FilterPill,\n FilterTabs,\n SearchFiltersList,\n} from './partials';\n\ninterface FilterLayoutProps {\n className?: string;\n /** Per-key dynamic options that override the provider's filter.options. */\n dynamicFilterOptions?: Record<string, FilterConfig['options']>;\n /** Per-key loading states; renders a small spinning chip. */\n loadingFilters?: Record<string, boolean>;\n variant?: 'default' | 'compact';\n showClearFilters?: boolean;\n tabs?: FilterTab[];\n}\n\nexport function FilterLayout({\n className,\n dynamicFilterOptions = {},\n loadingFilters = {},\n variant = 'default',\n showClearFilters = false,\n tabs,\n}: FilterLayoutProps) {\n const {\n getFilterValue,\n setFilterValue,\n isFilterActive,\n clearFilters,\n getFilterOperator,\n setFilterOperator,\n isNavigating,\n strings,\n } = useFilters();\n\n const groups = useFilterGroups({ dynamicFilterOptions });\n const {\n processedFilters,\n searchFilters,\n alwaysVisibleFilters,\n activeRegularFilters,\n popoverFilters,\n hasActive,\n } = groups;\n\n const [activeFilterInPopover, setActiveFilterInPopover] = useState<FilterConfig | null>(null);\n\n function getFilterOperators(filter: FilterConfig) {\n if (filter.operators && filter.operators.length > 0) return filter.operators;\n return getOperatorsForType(filter.type, strings.operators);\n }\n\n function handleOperatorChange(filterKey: string, operator: FilterOperator) {\n setFilterOperator(filterKey, operator);\n }\n\n return (\n <div\n className={cn('filter-layout--component', \n variant === 'compact' ? 'space-y-2' : 'space-y-4',\n className,\n )}\n >\n {!!tabs && tabs.length > 0 && <FilterTabs tabs={tabs} />}\n\n <div\n className={cn(\n 'flex flex-wrap items-center',\n variant === 'compact' ? 'gap-1' : 'gap-2',\n )}\n >\n <FilterErrorBoundary filterKey=\"search-filters\">\n <SearchFiltersList\n filters={searchFilters}\n getFilterValue={getFilterValue}\n setFilterValue={setFilterValue}\n />\n </FilterErrorBoundary>\n\n <div className={cn('contents', isNavigating && 'pointer-events-none opacity-60')}>\n {/* Loading chips for filters being updated */}\n {Object.entries(loadingFilters)\n .filter(([, isLoading]) => isLoading)\n .map(([key]) => {\n const filterLabel =\n processedFilters.find((f) => f.key === key)?.label || key;\n return (\n <div\n key={`loading-${key}`}\n className=\"text-muted-foreground bg-muted/50 flex items-center rounded-md px-2 py-1 text-xs\"\n >\n <div className=\"border-muted-foreground/30 border-t-primary mr-1 size-3 animate-spin rounded-full border-2\"></div>\n {interpolateFilterString(strings.loadingOptions, { filterLabel })}\n </div>\n );\n })}\n\n {/* Always-visible filters (display: 'always') — even when inactive */}\n {alwaysVisibleFilters.map((filter) => (\n <FilterPill\n key={filter.key}\n filter={filter}\n value={getFilterValue(filter.key) ?? []}\n isActive={false}\n operator={getFilterOperator(filter.key) || 'equals'}\n operators={getFilterOperators(filter)}\n onOperatorChange={(operator) => handleOperatorChange(filter.key, operator)}\n onValueChange={(value) => setFilterValue(filter.key, value)}\n onClear={() => setFilterValue(filter.key, [])}\n availableFilters={popoverFilters}\n activeFilters={[...activeRegularFilters, ...alwaysVisibleFilters]}\n />\n ))}\n\n {/* Active regular filters */}\n {activeRegularFilters.map((filter) => (\n <FilterPill\n key={filter.key}\n filter={filter}\n value={getFilterValue(filter.key) ?? []}\n isActive={isFilterActive(filter.key)}\n operator={getFilterOperator(filter.key) || 'equals'}\n operators={getFilterOperators(filter)}\n onOperatorChange={(operator) => handleOperatorChange(filter.key, operator)}\n onValueChange={(value) => setFilterValue(filter.key, value)}\n onClear={() => setFilterValue(filter.key, [])}\n availableFilters={popoverFilters}\n activeFilters={activeRegularFilters}\n />\n ))}\n\n {popoverFilters.length > 0 && (\n <FilterErrorBoundary filterKey=\"filters-button\">\n <FiltersButton\n availableFilters={popoverFilters}\n activeFilters={activeRegularFilters}\n activeFilterInPopover={activeFilterInPopover}\n getFilterValue={getFilterValue}\n setFilterValue={setFilterValue}\n setActiveFilterInPopover={setActiveFilterInPopover}\n />\n </FilterErrorBoundary>\n )}\n\n {!!showClearFilters && hasActive && (\n <Button\n variant=\"secondary\"\n buttonStyle=\"ghost\"\n onClick={clearFilters}\n className=\"text-muted-foreground ml-auto\"\n >\n {strings.clearFilters}\n </Button>\n )}\n </div>\n </div>\n </div>\n );\n}\n","import { ChevronsUpDown } from 'lucide-react';\nimport { useEffect, useMemo, useRef, useState } from 'react';\n\nimport { PopoverMenu, type PopoverMenuItem } from '@/components/base/popover-menu';\nimport { Text } from '@/components/typography';\nimport { Button } from '@/components/base/buttons';\nimport { cn } from '@/lib/utils';\n\nimport { useFilters } from '../filter-context';\nimport { interpolateFilterString } from '../filters.strings';\nimport type { FilterConfig, FilterOption } from '../filters.types';\n\ninterface SelectFacetProps {\n filter: FilterConfig;\n value: string[];\n onChange: (value: string[]) => void;\n className?: string;\n}\n\n/**\n * SelectFacet — single/multi-select dropdown filter.\n *\n * Composes `PopoverMenu` for the popover + searchable list pattern.\n * Multi-select keeps the popover open after a tap; single-select closes\n * unless `closeOnSelect=false` is passed in the filter config.\n */\nexport function SelectFacet({\n filter,\n value,\n onChange,\n className,\n}: SelectFacetProps) {\n const { strings } = useFilters();\n const [open, setOpen] = useState(false);\n const [searchInput, setSearchInput] = useState('');\n const [options, setOptions] = useState<FilterOption[] | undefined>(\n filter.options,\n );\n const [isLoading, setIsLoading] = useState(false);\n const debounceRef = useRef<number | undefined>(undefined);\n const hasSelection = value.length > 0;\n\n const handleSelect = (selectedValue: string) => {\n if (filter.multiple) {\n if (value.includes(selectedValue)) {\n onChange(value.filter((v) => v !== selectedValue));\n } else {\n onChange([...value, selectedValue]);\n }\n } else {\n onChange([selectedValue]);\n if (filter.closeOnSelect !== false) {\n setOpen(false);\n }\n }\n };\n\n const getOptionLabel = (optionValue: string) =>\n (options || filter.options)?.find((opt) => opt.value === optionValue)\n ?.label ?? optionValue;\n\n // Load options (supports async fetchOptions with basic debounce on searchInput)\n const fetchOptionsFn = filter.fetchOptions;\n const fetchDelay = filter.delay;\n useEffect(() => {\n if (!open) return;\n if (!fetchOptionsFn) return; // static options mode\n\n if (debounceRef.current) window.clearTimeout(debounceRef.current);\n const delay = typeof fetchDelay === 'number' ? fetchDelay : 300;\n debounceRef.current = window.setTimeout(async () => {\n setIsLoading(true);\n try {\n const fetched = await fetchOptionsFn({ q: [searchInput] });\n setOptions(fetched);\n } finally {\n setIsLoading(false);\n }\n }, delay);\n\n return () => {\n if (debounceRef.current) window.clearTimeout(debounceRef.current);\n };\n }, [open, searchInput, fetchOptionsFn, fetchDelay]);\n\n const items = useMemo<PopoverMenuItem[]>(() => {\n const source = options || filter.options || [];\n return source.map((option) => ({\n value: option.value,\n label: option.label,\n description: option.description,\n icon: option.icon,\n selected: value.includes(option.value),\n disabled: option.disabled,\n }));\n }, [options, filter.options, value]);\n\n const placeholderInterpolated = interpolateFilterString(\n strings.searchPlaceholder,\n { filterLabel: filter.label.toLowerCase() },\n );\n\n const emptyMessage = isLoading\n ? interpolateFilterString(strings.loadingOptions, {\n filterLabel: filter.label,\n })\n : strings.noOptionsFound;\n\n return (\n <div className={cn('select-facet--component', 'relative', className)}>\n <PopoverMenu\n open={open}\n onOpenChange={setOpen}\n search\n searchValue={searchInput}\n onSearchChange={setSearchInput}\n strings={{\n searchPlaceholder: placeholderInterpolated,\n empty: emptyMessage,\n }}\n contentClassName=\"w-(--radix-popover-trigger-width) min-w-56\"\n trigger={\n <Button\n variant=\"secondary\"\n buttonStyle=\"outline\"\n role=\"combobox\"\n aria-expanded={open}\n className=\"w-full justify-between\"\n >\n {hasSelection ? (\n value.length === 1 ? (\n <Text tag=\"span\" size=\"xs\" weight=\"semibold\" className=\"truncate\">\n {getOptionLabel(value[0])}\n </Text>\n ) : (\n <Text tag=\"span\" size=\"xs\" weight=\"semibold\">\n {interpolateFilterString(strings.selected, {\n count: value.length,\n filterLabel:\n (value.length > 1\n ? filter.pluralLabel\n : filter.label) ?? filter.label,\n })}\n </Text>\n )\n ) : (\n <Text tag=\"span\" size=\"xs\" type=\"secondary\">\n {filter.placeholder ?? strings.select}\n </Text>\n )}\n <ChevronsUpDown className=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n </Button>\n }\n items={items}\n onSelect={(item) => handleSelect(item.value)}\n />\n </div>\n );\n}\n","import { AlertCircle, Check, ChevronsUpDown, Loader2 } from 'lucide-react';\nimport { useMemo, useRef, useState } from 'react';\n\nimport { Button } from '@/components/base/buttons';\nimport {\n\tCommand,\n\tCommandEmpty,\n\tCommandGroup,\n\tCommandInput,\n\tCommandItem,\n\tCommandList,\n} from '@/components/base/command';\nimport {\n\tPopover,\n\tPopoverContent,\n\tPopoverTrigger,\n} from '@/components/base/popover';\nimport { Text } from '@/components/typography';\nimport { cn } from '@/lib/utils';\n\nimport { useFilters } from '../filter-context';\nimport { interpolateFilterString } from '../filters.strings';\nimport type { FilterConfig, FilterOption } from '../filters.types';\nimport { useAsyncOptions } from '../hooks';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface AsyncSelectFacetProps {\n\tfilter: FilterConfig;\n\tvalue: string[];\n\tonChange: (value: string[]) => void;\n\tclassName?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\n/**\n * Async Select Filter Facet\n *\n * A TanStack Query-powered filter facet for server-side option loading.\n * Supports:\n * - Live typeahead search with debounce + AbortSignal\n * - Loading, error, empty, min-query-hint states\n * - Preload (fetch default options on open)\n * - Multi-select with maxSelected enforcement\n * - Options label cache for pill display after popover close\n */\nexport function AsyncSelectFacet({\n\tfilter,\n\tvalue,\n\tonChange,\n\tclassName,\n}: AsyncSelectFacetProps) {\n\tconst { strings, cacheAsyncOptions, getAsyncOptionLabel } = useFilters();\n\tconst [open, setOpen] = useState(false);\n\tconst [searchInput, setSearchInput] = useState('');\n\n\t// Cache resolved option labels so pills can show labels after popover closes\n\tconst labelCacheRef = useRef<Map<string, FilterOption>>(new Map());\n\n\tconst {\n\t\toptions,\n\t\tisLoading,\n\t\tisFetching,\n\t\tisError,\n\t\trefetch,\n\t\tisBelowMinQuery,\n\t\tminQueryLength,\n\t} = useAsyncOptions(filter, searchInput, open);\n\n\t// Update label cache when new options arrive\n\tif (options.length > 0) {\n\t\tfor (const opt of options) {\n\t\t\tlabelCacheRef.current.set(opt.value, opt);\n\t\t}\n\t\tcacheAsyncOptions(filter.key, options);\n\t}\n\n\tconst isMulti = filter.multiple !== false;\n\tconst maxSelected = filter.maxSelected;\n\tconst initialOptions = useMemo(() => filter.options ?? [], [filter.options]);\n\n\t// Sort options: selected items first, then the rest.\n\t// Also include cached selected items that may not be in current search results.\n\tconst sortedOptions = useMemo(() => {\n\t\tconst selectedSet = new Set(value);\n\t\tconst optionValueSet = new Set(\n\t\t\t[...initialOptions, ...options].map((o) => o.value),\n\t\t);\n\n\t\t// Resolve selected items missing from current results via caches\n\t\tconst missingSelected: FilterOption[] = [];\n\t\tfor (const val of value) {\n\t\t\tif (!optionValueSet.has(val)) {\n\t\t\t\tconst cached = labelCacheRef.current.get(val);\n\t\t\t\tif (cached) {\n\t\t\t\t\tmissingSelected.push(cached);\n\t\t\t\t} else {\n\t\t\t\t\tconst initial = initialOptions.find((o) => o.value === val);\n\t\t\t\t\tif (initial) {\n\t\t\t\t\t\tmissingSelected.push(initial);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tconst label = getAsyncOptionLabel(filter.key, val);\n\t\t\t\t\tif (label) {\n\t\t\t\t\t\tmissingSelected.push({ value: val, label, icon: filter.icon });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst all = [...missingSelected, ...initialOptions, ...options];\n\t\treturn all.sort((a, b) => {\n\t\t\tconst aSelected = selectedSet.has(a.value) ? 0 : 1;\n\t\t\tconst bSelected = selectedSet.has(b.value) ? 0 : 1;\n\t\t\treturn aSelected - bSelected;\n\t\t});\n\t}, [initialOptions, options, value, filter.key, filter.icon, getAsyncOptionLabel]);\n\n\tconst handleSelect = (selectedValue: string) => {\n\t\tif (isMulti) {\n\t\t\tif (value.includes(selectedValue)) {\n\t\t\t\tonChange(value.filter((v) => v !== selectedValue));\n\t\t\t} else {\n\t\t\t\tif (maxSelected && value.length >= maxSelected) return;\n\t\t\t\tonChange([...value, selectedValue]);\n\t\t\t}\n\t\t} else {\n\t\t\tonChange([selectedValue]);\n\t\t\tif (filter.closeOnSelect !== false) {\n\t\t\t\tsetOpen(false);\n\t\t\t}\n\t\t}\n\t};\n\n\tconst getOptionLabel = (optionValue: string): string => {\n\t\t// Check current options first, then cache\n\t\tconst fromOptions = options.find((o) => o.value === optionValue);\n\t\tif (fromOptions) return fromOptions.label;\n\t\tconst fromInitialOptions = initialOptions.find((o) => o.value === optionValue);\n\t\tif (fromInitialOptions) return fromInitialOptions.label;\n\t\tconst cached = labelCacheRef.current.get(optionValue);\n\t\tif (cached) return cached.label;\n\t\treturn optionValue;\n\t};\n\n\tconst hasSelection = value.length > 0;\n\n\t// Determine the empty state message\n\tconst emptyMessage = useMemo(() => {\n\t\tif (isLoading || isFetching) {\n\t\t\treturn (\n\t\t\t\t<div className={cn('async-select-facet--component', 'flex items-center justify-center gap-2 py-4')}>\n\t\t\t\t\t<Loader2 className=\"text-muted-foreground size-4 animate-spin\" />\n\t\t\t\t\t<Text\n\t\t\t\t\t\ttag=\"span\"\n\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\ttype=\"secondary\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{strings.searching}\n\t\t\t\t\t</Text>\n\t\t\t\t</div>\n\t\t\t);\n\t\t}\n\n\t\tif (isError) {\n\t\t\treturn (\n\t\t\t\t<div className=\"flex flex-col items-center gap-2 py-4\">\n\t\t\t\t\t<div className=\"flex items-center gap-1.5\">\n\t\t\t\t\t\t<AlertCircle className=\"text-destructive size-4\" />\n\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\ttag=\"span\"\n\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\ttype=\"secondary\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{strings.fetchError}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t</div>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\t\tbuttonStyle=\"outline\"\n\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\tvoid refetch();\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t{strings.retryFetch}\n\t\t\t\t\t</Button>\n\t\t\t\t</div>\n\t\t\t);\n\t\t}\n\n\t\tif (isBelowMinQuery) {\n\t\t\treturn (\n\t\t\t\t<div className=\"text-muted-foreground flex items-center justify-center py-4\">\n\t\t\t\t\t<Text\n\t\t\t\t\t\ttag=\"span\"\n\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\ttype=\"secondary\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{interpolateFilterString(strings.minQueryHint, {\n\t\t\t\t\t\t\tmin: minQueryLength,\n\t\t\t\t\t\t})}\n\t\t\t\t\t</Text>\n\t\t\t\t</div>\n\t\t\t);\n\t\t}\n\n\t\treturn (\n\t\t\t<Text\n\t\t\t\ttag=\"span\"\n\t\t\t\tsize=\"xs\"\n\t\t\t\ttype=\"secondary\"\n\t\t\t>\n\t\t\t\t{strings.noOptionsFound}\n\t\t\t</Text>\n\t\t);\n\t}, [\n\t\tisLoading,\n\t\tisFetching,\n\t\tisError,\n\t\tisBelowMinQuery,\n\t\tminQueryLength,\n\t\tstrings,\n\t\trefetch,\n\t]);\n\n\treturn (\n\t\t<div className={cn('relative', className)}>\n\t\t\t<Popover\n\t\t\t\topen={open}\n\t\t\t\tonOpenChange={(next) => {\n\t\t\t\t\tsetOpen(next);\n\t\t\t\t\tif (!next) setSearchInput('');\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<PopoverTrigger\n\t\t\t\t\trender={\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\t\t\tbuttonStyle=\"outline\"\n\t\t\t\t\t\t\trole=\"combobox\"\n\t\t\t\t\t\t\taria-expanded={open}\n\t\t\t\t\t\t\tclassName=\"w-full justify-between\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{hasSelection ? (\n\t\t\t\t\t\t\t\tvalue.length === 1 ? (\n\t\t\t\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\t\t\t\ttag=\"span\"\n\t\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\t\tweight=\"semibold\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"truncate\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{getOptionLabel(value[0])}\n\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\t\t\t\ttag=\"span\"\n\t\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\t\tweight=\"semibold\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{interpolateFilterString(strings.selected, {\n\t\t\t\t\t\t\t\t\t\t\tcount: value.length,\n\t\t\t\t\t\t\t\t\t\t\tfilterLabel:\n\t\t\t\t\t\t\t\t\t\t\t\t(value.length > 1\n\t\t\t\t\t\t\t\t\t\t\t\t\t? filter.pluralLabel\n\t\t\t\t\t\t\t\t\t\t\t\t\t: filter.label) ?? filter.label,\n\t\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\t\t\ttag=\"span\"\n\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\ttype=\"secondary\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{filter.placeholder ?? strings.select}\n\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t<ChevronsUpDown className=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t}\n\t\t\t\t/>\n\t\t\t\t<PopoverContent className=\"w-full min-w-[280px] p-0\">\n\t\t\t\t\t<Command shouldFilter={false}>\n\t\t\t\t\t\t<CommandInput\n\t\t\t\t\t\t\tplaceholder={interpolateFilterString(\n\t\t\t\t\t\t\t\tstrings.searchPlaceholder,\n\t\t\t\t\t\t\t\t{ filterLabel: filter.label },\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\tvalue={searchInput}\n\t\t\t\t\t\t\tonValueChange={setSearchInput}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<CommandList>\n\t\t\t\t\t\t\t{sortedOptions.length === 0 ? (\n\t\t\t\t\t\t\t\t<CommandEmpty>{emptyMessage}</CommandEmpty>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<CommandGroup>\n\t\t\t\t\t\t\t\t\t{Boolean(isFetching && !isLoading) && (\n\t\t\t\t\t\t\t\t\t\t<div className=\"flex items-center gap-1.5 px-2 py-1\">\n\t\t\t\t\t\t\t\t\t\t\t<Loader2 className=\"text-muted-foreground size-3 animate-spin\" />\n\t\t\t\t\t\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\t\t\t\t\t\ttag=\"span\"\n\t\t\t\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\t\t\t\ttype=\"secondary\"\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{strings.searching}\n\t\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t{sortedOptions.map((option) => (\n\t\t\t\t\t\t\t\t\t\t<CommandItem\n\t\t\t\t\t\t\t\t\t\t\tkey={option.value}\n\t\t\t\t\t\t\t\t\t\t\tvalue={option.value}\n\t\t\t\t\t\t\t\t\t\t\tonSelect={() => handleSelect(option.value)}\n\t\t\t\t\t\t\t\t\t\t\tdisabled={\n\t\t\t\t\t\t\t\t\t\t\t\toption.disabled ||\n\t\t\t\t\t\t\t\t\t\t\t\t(!!maxSelected &&\n\t\t\t\t\t\t\t\t\t\t\t\t\tvalue.length >= maxSelected &&\n\t\t\t\t\t\t\t\t\t\t\t\t\t!value.includes(option.value))\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<Check\n\t\t\t\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\t\t\t'mr-2 h-4 w-4',\n\t\t\t\t\t\t\t\t\t\t\t\t\tvalue.includes(option.value)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t? 'opacity-100'\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t: 'opacity-0',\n\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t{Boolean(option.icon) && (\n\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"mr-1.5\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t{option.icon}\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\t\t\t\t\t\ttag=\"span\"\n\t\t\t\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{option.label}\n\t\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t\t</CommandItem>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</CommandGroup>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</CommandList>\n\t\t\t\t\t</Command>\n\t\t\t\t</PopoverContent>\n\t\t\t</Popover>\n\t\t</div>\n\t);\n}\n\n/**\n * Retrieve the label cache ref from an AsyncSelectFacet instance.\n * This is used by FilterValueDisplay to resolve labels for active async filters.\n */\nexport type AsyncSelectLabelCache = Map<string, FilterOption>;\n","import { useState, useEffect, useId, useRef, type ChangeEvent } from 'react';\nimport { Input } from '@/components/base/forms';\nimport { Label } from '@/components/typography';\nimport { cn } from '@/lib/utils';\nimport { useFilters } from '../filter-context';\nimport type { FilterConfig } from '../filters.types';\n\ninterface RangeFacetProps {\n filter: FilterConfig;\n value: { min?: number; max?: number };\n onChange: (value: { min?: number; max?: number }) => void;\n className?: string;\n}\n\n/**\n * Range Filter Facet\n *\n * This component implements a numeric range filter that allows users to:\n * - Set minimum and maximum values\n * - Configure step size and precision\n * - Set value constraints (min/max allowed values)\n * - Customize the range input appearance\n *\n * The component integrates with the filter context to manage the range values\n * and provides a user-friendly interface for range selection.\n */\n\nexport function RangeFacet({\n filter,\n value,\n onChange,\n className,\n}: RangeFacetProps) {\n const { strings } = useFilters();\n\n const [minValue, setMinValue] = useState<string>(\n value.min?.toString() ?? '',\n );\n const [maxValue, setMaxValue] = useState<string>(\n value.max?.toString() ?? '',\n );\n const instanceId = useId(); // Keep ids unique when multiple range facets render\n\n // Stabilize callback and value refs to keep the effect dep-light\n const onChangeRef = useRef(onChange);\n onChangeRef.current = onChange;\n const valueRef = useRef(value);\n valueRef.current = value;\n\n useEffect(() => {\n const timeout = setTimeout(() => {\n const currentValue = valueRef.current;\n const newValue = {\n min: minValue ? Number(minValue) : undefined,\n max: maxValue ? Number(maxValue) : undefined,\n };\n if (newValue.min !== currentValue.min || newValue.max !== currentValue.max) {\n onChangeRef.current(newValue);\n }\n }, filter.delay ?? 500);\n\n return () => clearTimeout(timeout);\n }, [minValue, maxValue, filter.delay]);\n\n const handleMinChange = (e: ChangeEvent<HTMLInputElement>) => {\n const val = e.target.value;\n if (val === '' || /^\\d*\\.?\\d*$/.test(val)) {\n setMinValue(val);\n }\n };\n\n const handleMaxChange = (e: ChangeEvent<HTMLInputElement>) => {\n const val = e.target.value;\n if (val === '' || /^\\d*\\.?\\d*$/.test(val)) {\n setMaxValue(val);\n }\n };\n\n return (\n <div className={cn('range-facet--component', 'space-y-2', className)}>\n <div className=\"grid grid-cols-2 gap-2\">\n <div className=\"space-y-1\">\n <Label htmlFor={`${instanceId}-min`}>\n {strings.min}\n </Label>\n <Input\n id={`${instanceId}-min`}\n type=\"text\"\n value={minValue}\n onChange={handleMinChange}\n placeholder={strings.min}\n className=\"w-full\"\n />\n </div>\n <div className=\"space-y-1\">\n <Label htmlFor={`${instanceId}-max`}>\n {strings.max}\n </Label>\n <Input\n id={`${instanceId}-max`}\n type=\"text\"\n value={maxValue}\n onChange={handleMaxChange}\n placeholder={strings.max}\n className=\"w-full\"\n />\n </div>\n </div>\n </div>\n );\n}\n","/**\n * Validator helpers for `FilterConfig.validation.custom`.\n *\n * Our `ValidationConfig` accepts `custom: (value) => boolean | string`\n * already (`true` = valid, `false` = generic invalid, `string` = custom\n * error message). These helpers adapt common third-party validators\n * — Zod, Valibot, plain async-safe predicates — to that shape so\n * consumers don't reinvent the bridge.\n *\n * The library does NOT depend on Zod or any specific validation lib.\n * The helpers are written against minimal duck-typed shapes that any\n * library implementing `safeParse` can satisfy.\n */\nimport type { ValidationConfig } from './filters.types';\n\n/**\n * Minimal Zod-compatible interface — a schema with a `safeParse` method\n * that returns `{ success: boolean, error?: { message?: string,\n * issues?: { message: string }[] } }`. Both Zod 3 and Zod 4 satisfy\n * this; Valibot's `safeParse` differs slightly but a thin wrapper\n * works.\n */\nexport interface SafeParseSchema<TInput = unknown> {\n\tsafeParse(value: TInput): {\n\t\tsuccess: boolean;\n\t\terror?: {\n\t\t\tmessage?: string;\n\t\t\tissues?: { message: string }[];\n\t\t};\n\t};\n}\n\n/**\n * Adapter: turn a Zod-like schema into a `ValidationConfig['custom']`.\n *\n * import { z } from 'zod';\n * import { zodValidator } from '@/components/features/filters';\n *\n * const emailSchema = z.string().email();\n * const config: FilterConfig = {\n * …,\n * validation: { custom: zodValidator(emailSchema) },\n * };\n *\n * On parse failure the first issue's `message` is returned (so\n * Zod's `.refine(...).message('Custom')` flows through). On success\n * returns `true`. The empty-string case is bypassed — let\n * `validation.required` handle \"must not be empty\" so error messages\n * stay coherent.\n */\nexport function zodValidator<TInput = unknown>(\n\tschema: SafeParseSchema<TInput>,\n): NonNullable<ValidationConfig['custom']> {\n\treturn (value: unknown): boolean | string => {\n\t\t// Skip empty strings — `validation.required` is the right channel\n\t\t// for \"missing value\" messaging.\n\t\tif (value === undefined || value === null) return true;\n\t\tif (typeof value === 'string' && value.length === 0) return true;\n\t\tconst result = schema.safeParse(value as TInput);\n\t\tif (result.success) return true;\n\t\tconst message =\n\t\t\tresult.error?.issues?.[0]?.message ??\n\t\t\tresult.error?.message ??\n\t\t\tfalse;\n\t\treturn message as string | false;\n\t};\n}\n\n/**\n * Adapter: pair a predicate with a static error message. Useful when\n * the consumer doesn't want to pull a validation library at all.\n *\n * validation: {\n * custom: predicateValidator(\n * (v) => /^https?:\\/\\//.test(String(v)),\n * 'URL must start with http:// or https://',\n * ),\n * }\n */\nexport function predicateValidator(\n\tpredicate: (value: unknown) => boolean,\n\tmessage: string,\n): NonNullable<ValidationConfig['custom']> {\n\treturn (value: unknown) => (predicate(value) ? true : message);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../../../../src/components/features/filters/filters.strings.ts","../../../../src/components/features/filters/filters.types.ts","../../../../src/components/features/filters/operator-options.ts","../../../../src/components/features/filters/utils/filter-utils.ts","../../../../src/components/features/filters/filter-context.tsx","../../../../src/components/features/filters/hooks/use-filter-groups.ts","../../../../src/components/features/filters/partials/filter-operator-select.tsx","../../../../src/components/features/filters/partials/filter-value-display.tsx","../../../../src/components/features/filters/partials/active-filter-item.tsx","../../../../src/hooks/use-debounce.ts","../../../../src/components/features/filters/hooks/use-async-options.ts","../../../../src/components/features/filters/partials/async-filter-content.tsx","../../../../src/components/features/filters/facets/date-facet.tsx","../../../../src/components/features/filters/partials/date-filter-content.tsx","../../../../src/components/features/filters/partials/filter-error-boundary.tsx","../../../../src/components/features/filters/partials/filter-list-item.tsx","../../../../src/components/features/filters/partials/filter-list-content.tsx","../../../../src/components/features/filters/partials/regular-filter-content.tsx","../../../../src/components/features/filters/facets/tags-facet.tsx","../../../../src/components/features/filters/partials/tags-filter-content.tsx","../../../../src/components/features/filters/partials/filter-popover-content.tsx","../../../../src/components/features/filters/partials/filter-pill.tsx","../../../../src/components/features/filters/partials/filters-button.tsx","../../../../src/components/features/filters/partials/filter-tabs.tsx","../../../../src/components/features/filters/facets/search-facet.tsx","../../../../src/components/features/filters/partials/search-filters-list.tsx","../../../../src/components/features/filters/filter-layout.tsx","../../../../src/components/features/filters/facets/select-facet.tsx","../../../../src/components/features/filters/facets/async-select-facet.tsx","../../../../src/components/features/filters/facets/range-facet.tsx","../../../../src/components/features/filters/validators.ts"],"sourcesContent":["/**\n * Filter strings — default copy and nested override contract.\n *\n * Consumers localize filters by passing `strings` to `<FilterProvider>`.\n * No routing, framework i18n hook, or backend shared-props contract belongs in\n * this default feature path.\n */\n\nexport interface FilterOperatorStrings {\n contains: string;\n equals: string;\n notContains: string;\n is: string;\n isNot: string;\n greaterThan: string;\n lessThan: string;\n before: string;\n after: string;\n between: string;\n has: string;\n hasAny: string;\n hasAll: string;\n}\n\nexport interface FilterStrings {\n // Filter loading states\n loading: string;\n loadingOptions: string; // \"Loading {filterLabel} options...\"\n\n // Action buttons\n addFilter: string;\n clear: string;\n confirm: string;\n clearFilters: string;\n clearAll: string;\n\n // Date selection\n selectDate: string;\n selectDateRange: string;\n calendar: {\n dateSelected: string;\n notDateSelected: string;\n notDateRangeSelected: string;\n selectedEndDate: string;\n today: string;\n yesterday: string;\n lastSevenDays: string;\n lastThirtyDays: string;\n thisMonth: string;\n lastMonth: string;\n thisYear: string;\n lastYear: string;\n customRange: string;\n };\n\n // Value selection\n selectValues: string;\n searchPlaceholder: string; // \"Search {filterLabel}...\"\n noOptionsFound: string;\n selected: string; // \"{count} {filterLabel} selected\"\n nothingSelected: string; // pill value text when nothing has been picked yet\n\n // Tags\n enterTag: string;\n addTag: string;\n removeTag: string;\n tag: string;\n tags: string;\n enterTags: string;\n\n // Filter list\n searchFilters: string;\n noFiltersAvailable: string;\n availableFilters: string;\n activeFilters: string;\n clearSearch: string;\n backToFilters: string;\n select: string;\n options: string;\n\n // Operator selector (active-filter pill dropdown)\n operator: string;\n operators: FilterOperatorStrings;\n\n // Range filters\n min: string;\n max: string;\n\n // Async select filters\n fetchError: string;\n retryFetch: string;\n minQueryHint: string; // \"Type at least {min} characters...\"\n searching: string;\n\n // Error boundary\n error: {\n title: string;\n descriptionWithKey: string;\n generic: string;\n unknown: string;\n };\n\n // Value validation\n validation: {\n required: string;\n minValue: string;\n maxValue: string;\n invalidFormat: string;\n };\n}\n\n/**\n * Default English strings for the filter system.\n * These serve as fallbacks when no strings are provided.\n */\nexport const defaultFilterStrings: FilterStrings = {\n // Filter loading states\n loading: 'Loading',\n loadingOptions: 'Loading {filterLabel} options...',\n\n // Action buttons\n addFilter: 'Add filter',\n clear: 'Clear',\n confirm: 'Confirm',\n clearFilters: 'Clear filters',\n clearAll: 'Clear all',\n\n // Date selection\n selectDate: 'Select date',\n selectDateRange: 'Select date range',\n calendar: {\n dateSelected: 'Date selected',\n notDateSelected: 'No date selected',\n notDateRangeSelected: 'No date range selected',\n selectedEndDate: 'Select end date',\n today: 'Today',\n yesterday: 'Yesterday',\n lastSevenDays: 'Last 7 days',\n lastThirtyDays: 'Last 30 days',\n thisMonth: 'This month',\n lastMonth: 'Last month',\n thisYear: 'This year',\n lastYear: 'Last year',\n customRange: 'Custom range',\n },\n\n // Value selection\n selectValues: 'Select values',\n searchPlaceholder: 'Search {filterLabel}...',\n noOptionsFound: 'No options found',\n selected: '{count} {filterLabel} selected',\n nothingSelected: 'Nothing selected',\n\n // Tags\n enterTag: 'Enter tag',\n addTag: 'Add tag',\n removeTag: 'Remove',\n tag: 'tag',\n tags: 'tags',\n enterTags: 'Enter tags',\n\n // Filter list\n searchFilters: 'Search filters...',\n noFiltersAvailable: 'No filters available',\n availableFilters: 'Available Filters',\n activeFilters: 'Active Filters',\n clearSearch: 'Clear search',\n backToFilters: 'Back to filters',\n select: 'Select',\n options: 'options',\n\n // Operator selector (active-filter pill dropdown)\n operator: 'Operator',\n operators: {\n contains: 'contains',\n equals: 'is',\n notContains: 'does not contain',\n is: 'is',\n isNot: 'is not',\n greaterThan: 'greater than',\n lessThan: 'less than',\n before: 'before',\n after: 'after',\n between: 'between',\n has: 'has',\n hasAny: 'has any',\n hasAll: 'has all',\n },\n\n // Range filters\n min: 'Min',\n max: 'Max',\n\n // Async select filters\n fetchError: 'Failed to load options',\n retryFetch: 'Retry',\n minQueryHint: 'Type at least {min} characters...',\n searching: 'Searching...',\n\n // Error boundary\n error: {\n title: 'Filter error',\n descriptionWithKey: 'There was a problem with \"{filterKey}\" filter.',\n generic: 'There was a problem loading this filter.',\n unknown: 'Unknown error',\n },\n\n // Value validation\n validation: {\n required: 'This filter is required',\n minValue: 'Value must be at least {min}',\n maxValue: 'Value must be at most {max}',\n invalidFormat: 'Invalid format',\n },\n};\n\n/**\n * Helper function to interpolate values in strings.\n * Replaces {key} with the corresponding value from the params object.\n */\nexport function interpolateFilterString(\n template: string,\n params: Record<string, string | number>,\n): string {\n const withCurlyPlaceholders = template.replace(/{(\\w+)}/g, (match, key) => {\n return String(params[key] ?? match);\n });\n\n const withColonPlaceholdersReplaced = withCurlyPlaceholders.replace(\n /:(\\w+)/g,\n (match, key) => {\n return params[key] !== undefined ? String(params[key]) : match;\n },\n );\n\n return withColonPlaceholdersReplaced;\n}\n\n/**\n * Helper function to get a string from a strings object\n * with dot notation support.\n */\nexport function getFilterString(\n strings: FilterStrings,\n path: string,\n params?: Record<string, string | number>,\n): string {\n const keys = path.split('.');\n let result: unknown = strings;\n\n for (const key of keys) {\n if (result == null || typeof result !== 'object') {\n return path; // Return the path if the string is not found\n }\n result = (result as Record<string, unknown>)[key];\n }\n\n if (typeof result === 'string') {\n return params ? interpolateFilterString(result, params) : result;\n }\n\n return path; // Return the path if the string is not found\n}\n","import type { ReactNode } from 'react';\n\n/** Shared height class for all filter control elements. */\nexport const FILTER_ELEMENT_HEIGHT = 'h-9';\n\n/**\n * Core type definitions and interfaces for the filters feature.\n *\n * This file defines:\n * - Filter types (SELECT, MULTI_SELECT, SEARCH, RANGE, DATE)\n * - Filter operators (equals, contains, in, etc.)\n * - Configuration interfaces for filters\n * - Context value types for filter state management\n * - Validation and display configuration types\n *\n * These types are used throughout the filters feature to ensure type safety\n * and consistent data structures.\n */\n\nexport const FilterType = {\n SELECT: 'select',\n MULTI_SELECT: 'multi_select',\n ASYNC_SELECT: 'async_select',\n SEARCH: 'search',\n RANGE: 'range',\n DATE: 'date',\n TAGS: 'tags',\n} as const;\n\nexport type FilterType = (typeof FilterType)[keyof typeof FilterType];\n\n// Convert string union to enum for better type safety and autocompletion\n// Note: All enum values are used via the FilterOperator type below, even if not directly referenced\nexport const FilterOperatorEnum = {\n EQUALS: 'equals',\n CONTAINS: 'contains',\n IN: 'in',\n NOT_IN: 'not_in',\n NOT: 'not',\n BEFORE: 'before',\n AFTER: 'after',\n BETWEEN: 'between',\n GT: 'gt',\n LT: 'lt',\n GTE: 'gte',\n LTE: 'lte',\n HAS: 'has',\n HAS_ANY: 'has_any',\n HAS_ALL: 'has_all',\n} as const;\n\n// Strict type for better type safety - using enum values to match backend\nexport type FilterOperator = (typeof FilterOperatorEnum)[keyof typeof FilterOperatorEnum];\n\nexport interface OperatorOption {\n label: string;\n value: FilterOperator;\n}\n\n// Filter display types\n// Accept both 'drawer' and 'collapsed' as synonyms for the collapsed UI\nexport type FilterDisplay = 'always' | 'drawer' | 'collapsed' | 'hidden';\n\nexport const FilterCategory = {\n FILTER: 'filter',\n SORT: 'sort',\n GROUP: 'group',\n} as const;\n\nexport type FilterCategory = (typeof FilterCategory)[keyof typeof FilterCategory];\n\nexport interface FilterOption {\n label: string;\n value: string;\n icon: ReactNode;\n children?: FilterOption[];\n disabled?: boolean;\n description?: string;\n color?: string;\n}\n\nexport interface DisplayConfig {\n renderConfig?: {\n desktop: string;\n mobile?: string;\n tablet?: string;\n };\n display?: FilterDisplay;\n category?: FilterCategory;\n priority?: number;\n hidden?: boolean;\n className?: string; // Simplified config for basic styling needs\n}\n\nexport interface ValidationConfig {\n min?: number;\n max?: number;\n pattern?: RegExp;\n required?: boolean;\n custom?: (value: unknown) => boolean | string;\n}\n\nexport interface FilterDependency {\n key: string;\n operator: FilterOperator;\n value: string | string[];\n}\n\n/**\n * Configuration for ASYNC_SELECT filters that fetch options from the server.\n *\n * Supports two modes:\n * - Declarative: provide `fetchOptions` on FilterConfig (simpler, backward-compatible)\n * - TanStack Query: provide `asyncConfig` for full control over caching, abort, preload\n *\n * When both are provided, `asyncConfig` takes precedence.\n */\nexport interface AsyncSelectConfig<TItem = unknown> {\n /** TanStack Query key factory — receives { query, limit } and returns a stable key */\n queryKey: (args: { query: string; limit: number }) => readonly unknown[];\n /** Fetcher function — receives { query, limit, signal } and returns items */\n fetcher: (args: {\n query: string;\n limit: number;\n signal?: AbortSignal;\n }) => Promise<TItem[]>;\n /** Maps a fetched item to a FilterOption for display */\n mapToOption: (item: TItem) => FilterOption;\n /** Max items to fetch per request (default: 10) */\n limit?: number;\n /** Minimum characters before fetching (default: 0) */\n minQueryLength?: number;\n /** Whether to fetch with empty query on open (default: true) */\n preload?: boolean;\n /** Debounce delay in ms (default: 300) */\n debounceMs?: number;\n /** TanStack Query staleTime in ms (default: 60_000) */\n staleTime?: number;\n /** TanStack Query gcTime in ms (default: 300_000) */\n gcTime?: number;\n}\n\nexport interface FilterConfig {\n key: string;\n label: string;\n /** Plural form of the label, used in \"{count} {label} selected\" when count > 1 */\n pluralLabel?: string;\n type: FilterType;\n description?: string;\n operator?: FilterOperator;\n operators?: OperatorOption[]; // Available operators for this filter\n options?: FilterOption[];\n placeholder?: string;\n delay?: number;\n icon: ReactNode;\n displayConfig: DisplayConfig;\n defaultValue?: string | string[];\n validation?: ValidationConfig;\n dependencies?: FilterDependency[];\n fetchOptions?: (\n dependencyValues: Record<string, string[]>,\n ) => Promise<FilterOption[]>;\n multiple?: boolean;\n closeOnSelect?: boolean;\n maxSelected?: number;\n /** TanStack Query-powered async config for ASYNC_SELECT filters */\n asyncConfig?: AsyncSelectConfig;\n dateFormat?: {\n display?: string; // Format for display (e.g., 'MMM d, yyyy')\n param?: string; // Format for URL parameters (e.g., 'yyyy-MM-dd')\n };\n // Date picker specific options\n datePickerConfig?: {\n showConfirmButton?: boolean;\n showShortcuts?: boolean;\n fullWidth?: boolean;\n noDatePlaceholder?: string;\n noRangePlaceholder?: string;\n autoApply?: boolean; // Whether to automatically apply date selections\n };\n // Optional formatting functions\n format?: (value: unknown) => string;\n parse?: (value: string) => unknown;\n transform?: (value: unknown) => unknown;\n}\n\nexport interface ActiveFilter {\n id: string;\n key: string;\n operator: FilterOperator;\n value: string[];\n}\n\nexport interface FilterGroup {\n label: string;\n filters: FilterConfig[];\n}\n\nexport interface FilterState {\n [key: string]: string[];\n}\n\nexport interface FilterTabPreset {\n key: string;\n value: string[];\n operator?: FilterOperator;\n}\n\nexport interface FilterTab {\n id: string;\n label: string;\n presets: FilterTabPreset[];\n count?: number;\n}\n","import {\n FilterOperatorEnum,\n type FilterOperator,\n type OperatorOption,\n FilterType,\n} from './filters.types';\nimport type { FilterOperatorStrings } from './filters.strings';\n\nexport function getTextOperators(strings: FilterOperatorStrings): OperatorOption[] {\n return [\n { label: strings.contains, value: FilterOperatorEnum.CONTAINS },\n { label: strings.equals, value: FilterOperatorEnum.EQUALS },\n { label: strings.notContains, value: FilterOperatorEnum.NOT },\n ];\n}\n\nexport function getSelectOperators(strings: FilterOperatorStrings): OperatorOption[] {\n return [\n { label: strings.is, value: FilterOperatorEnum.EQUALS },\n { label: strings.isNot, value: FilterOperatorEnum.NOT },\n ];\n}\n\nexport function getNumberOperators(strings: FilterOperatorStrings): OperatorOption[] {\n return [\n { label: strings.equals, value: FilterOperatorEnum.EQUALS },\n { label: strings.greaterThan, value: FilterOperatorEnum.GT },\n { label: strings.lessThan, value: FilterOperatorEnum.LT },\n ];\n}\n\nexport function getDateOperators(strings: FilterOperatorStrings): OperatorOption[] {\n return [\n { label: strings.before, value: FilterOperatorEnum.BEFORE },\n { label: strings.after, value: FilterOperatorEnum.AFTER },\n { label: strings.between, value: FilterOperatorEnum.BETWEEN },\n ];\n}\n\nexport function getBooleanOperators(strings: FilterOperatorStrings): OperatorOption[] {\n return [{ label: strings.equals, value: FilterOperatorEnum.EQUALS }];\n}\n\nexport function getOperatorsForType(\n type: FilterType,\n strings: FilterOperatorStrings,\n): OperatorOption[] {\n switch (type) {\n case FilterType.SEARCH:\n return getTextOperators(strings);\n case FilterType.TAGS:\n return [\n { label: strings.has, value: FilterOperatorEnum.HAS },\n { label: strings.hasAny, value: FilterOperatorEnum.HAS_ANY },\n { label: strings.hasAll, value: FilterOperatorEnum.HAS_ALL },\n ];\n case FilterType.SELECT:\n case FilterType.ASYNC_SELECT:\n return getSelectOperators(strings);\n case FilterType.RANGE:\n return getNumberOperators(strings);\n case FilterType.DATE:\n return getDateOperators(strings);\n default:\n return getTextOperators(strings);\n }\n}\n\nexport function getDefaultOperatorForType(\n type: FilterType,\n): FilterOperator {\n switch (type) {\n case FilterType.SEARCH:\n return FilterOperatorEnum.CONTAINS;\n case FilterType.TAGS:\n // Tags default to array containment semantics\n return FilterOperatorEnum.HAS;\n case FilterType.SELECT:\n case FilterType.ASYNC_SELECT:\n return FilterOperatorEnum.EQUALS;\n case FilterType.RANGE:\n return FilterOperatorEnum.EQUALS;\n case FilterType.DATE:\n return FilterOperatorEnum.BEFORE;\n default:\n return FilterOperatorEnum.EQUALS;\n }\n}\n","import type { ReactNode } from 'react';\nimport type { FilterConfig, FilterDependency } from '../filters.types';\n\n/**\n * Gets the label for a filter option\n */\nexport function getFilterOptionLabel(\n\tfilter: FilterConfig,\n\tvalue: string,\n): string | undefined {\n\treturn filter.options?.find((opt) => opt.value === value)?.label;\n}\n\n/**\n * Gets the icon for a filter option\n */\nexport function getFilterOptionIcon(\n\tfilter: FilterConfig,\n\tvalue: string,\n): ReactNode | undefined {\n\treturn filter.options?.find((opt) => opt.value === value)?.icon;\n}\n\n/**\n * Validates a filter value against the filter configuration\n *\n * @param filter - The filter configuration to validate against\n * @param value - The value to validate\n * @param t\n * @returns true if valid, or an error message string if invalid\n */\nexport function validateFilterValue(\n\tfilter: FilterConfig,\n\tvalue: unknown,\n\tt: (key: string) => string,\n): boolean | string {\n\t// Special case for date filters - always allow date strings\n\tif (filter.type === 'date') {\n\t\t// If the value is a date string array, it's valid\n\t\tif (Array.isArray(value) && value.every((v) => typeof v === 'string')) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t// Require if marked as required\n\tif (\n\t\tfilter.validation?.required &&\n\t\t(!value || (Array.isArray(value) && value.length === 0))\n\t) {\n\t\treturn t('validation.required');\n\t}\n\n\t// Only check min/max for numeric values\n\tif (typeof value === 'number') {\n\t\tif (\n\t\t\tfilter.validation?.min !== undefined &&\n\t\t\tvalue < filter.validation.min\n\t\t) {\n\t\t\treturn t('validation.minValue').replace(\n\t\t\t\t'{min}',\n\t\t\t\tString(filter.validation.min),\n\t\t\t);\n\t\t}\n\n\t\tif (\n\t\t\tfilter.validation?.max !== undefined &&\n\t\t\tvalue > filter.validation.max\n\t\t) {\n\t\t\treturn t('validation.maxValue').replace(\n\t\t\t\t'{max}',\n\t\t\t\tString(filter.validation.max),\n\t\t\t);\n\t\t}\n\t}\n\n\t// Pattern validation for strings only\n\tif (filter.validation?.pattern && typeof value === 'string') {\n\t\tconst regex = new RegExp(filter.validation.pattern);\n\t\tif (!regex.test(value)) {\n\t\t\treturn t('validation.invalidFormat');\n\t\t}\n\t}\n\n\t// Custom validation if provided\n\tif (filter.validation?.custom) {\n\t\tconst customValidation = filter.validation.custom(value);\n\t\tif (typeof customValidation === 'string' || !customValidation) {\n\t\t\treturn customValidation;\n\t\t}\n\t}\n\n\t// If we got here, the value is valid\n\treturn true;\n}\n\n/**\n * Formats a filter value for display using either the format function provided\n * in the filter config, or by looking up option labels\n *\n * @param filter - The filter configuration\n * @param value - The value to format\n * @returns Formatted string representation of the value\n */\nexport function formatFilterValue(\n\tfilter: FilterConfig,\n\tvalue: unknown,\n): string {\n\t// Use custom format function if provided in filter config\n\tif (filter.format && typeof filter.format === 'function') {\n\t\ttry {\n\t\t\treturn filter.format(value);\n\t\t} catch (error) {\n\t\t\tif (import.meta.env?.DEV) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`Error using custom format function for filter ${filter.key}:`,\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Fall back to default formatting\n\t\t}\n\t}\n\n\t// Default formatting behavior\n\tif (Array.isArray(value)) {\n\t\treturn value\n\t\t\t.map((v) => getFilterOptionLabel(filter, String(v)) ?? String(v))\n\t\t\t.join(', ');\n\t}\n\n\treturn getFilterOptionLabel(filter, String(value)) ?? String(value);\n}\n\n/**\n * Gets the values of dependent filters\n */\nexport function getDependentFilterValues(\n\tdependencies: FilterDependency[],\n\tfilterState: Record<string, string[]>,\n): Record<string, string[]> {\n\treturn dependencies.reduce(\n\t\t(acc, dep) => {\n\t\t\tconst values = filterState[dep.key] || [];\n\t\t\tif (values.length > 0) {\n\t\t\t\tacc[dep.key] = values;\n\t\t\t}\n\t\t\treturn acc;\n\t\t},\n\t\t{} as Record<string, string[]>,\n\t);\n}\n\n/**\n * Determines if a filter should be shown based on its dependencies\n */\nexport function shouldShowFilter(\n\tfilter: FilterConfig,\n\tfilterState: Record<string, string[]>,\n): boolean {\n\tif (!filter.dependencies || filter.dependencies.length === 0) {\n\t\treturn true;\n\t}\n\n\treturn filter.dependencies.every((dep) => {\n\t\tconst values = filterState[dep.key] || [];\n\t\tif (values.length === 0) return false;\n\n\t\tswitch (dep.operator) {\n\t\t\tcase 'equals':\n\t\t\t\treturn values.includes(dep.value as string);\n\t\t\tcase 'contains':\n\t\t\t\treturn values.some((v) => (dep.value as string).includes(v));\n\t\t\tcase 'in':\n\t\t\t\treturn Array.isArray(dep.value)\n\t\t\t\t\t? values.some((v) => (dep.value as string[]).includes(v))\n\t\t\t\t\t: values.includes(dep.value);\n\t\t\tdefault:\n\t\t\t\treturn false;\n\t\t}\n\t});\n}\n\nexport function extractFilterDefaults<T extends string = string>(\n\tfilters: FilterConfig[],\n): Record<T, string> {\n\treturn filters.reduce(\n\t\t(acc, filter) => {\n\t\t\t// Force the default value to be treated as a string\n\t\t\tacc[filter.key as T] = (filter.defaultValue as string) || '';\n\t\t\treturn acc;\n\t\t},\n\t\t{} as Record<T, string>,\n\t);\n}\n","import {\n createContext,\n useContext,\n useMemo,\n useCallback,\n type ReactNode,\n useRef,\n useEffect,\n useState,\n} from 'react';\nimport { useStrings, type StringsProp } from '@/lib/strings';\nimport {\n defaultFilterStrings,\n getFilterString,\n type FilterStrings,\n} from './filters.strings';\nimport {\n FilterType,\n type FilterConfig,\n type ActiveFilter,\n type FilterOperator,\n type FilterOption,\n} from './filters.types';\nimport { getDefaultOperatorForType } from './operator-options';\nimport { validateFilterValue } from './utils/filter-utils';\n\ninterface FilterProviderProps {\n children: ReactNode;\n filters: FilterConfig[];\n activeFilters: ActiveFilter[];\n onFilterChange: (filters: ActiveFilter[]) => void;\n isNavigating?: boolean;\n strings?: StringsProp<FilterStrings>;\n locale?: string;\n /** Called when an async fetch / validation / apply step throws.\n * Library DEV-logs the error; consumer wires telemetry here. */\n onError?: (error: unknown, context: { phase: 'fetch-options' | 'apply' | 'validate'; filterKey?: string }) => void;\n}\n\ninterface FilterContextValue {\n activeFilters: ActiveFilter[];\n filters: FilterConfig[];\n addFilter: (filter: ActiveFilter) => void;\n removeFilter: (id: string) => void;\n updateFilter: (id: string, updates: Partial<ActiveFilter>) => void;\n clearFilters: () => void;\n replaceFilters: (filters: ActiveFilter[]) => void;\n getFilterByKey: (key: string) => FilterConfig | undefined;\n getFilterValue: (key: string) => string[];\n setFilterValue: (key: string, value: string[]) => void;\n isFilterActive: (key: string) => boolean;\n getFilterOperator: (key: string) => FilterOperator | undefined;\n setFilterOperator: (key: string, operator: FilterOperator) => void;\n validateFilter: (key: string, value: unknown) => boolean | string;\n getDependentFilters: (key: string) => FilterConfig[];\n getFilterOptions: (key: string) => Promise<FilterOption[]>;\n isNavigating: boolean;\n locale: string;\n strings: FilterStrings;\n /** Cache resolved options for async filters (keyed by filter key → option value → FilterOption) */\n cacheAsyncOptions: (filterKey: string, options: FilterOption[]) => void;\n /** Resolve a cached label for an async filter value */\n getAsyncOptionLabel: (filterKey: string, optionValue: string) => string | undefined;\n}\n\nconst FilterContext = createContext<FilterContextValue | undefined>(undefined);\n\n/**\n * Module-level cache for async filter option labels.\n * Lives outside the component tree so it survives provider remounts.\n */\nconst globalAsyncOptionsCache = new Map<string, Map<string, FilterOption>>();\n\n/**\n * Framework-agnostic filter provider.\n * State, strings, and async option fetchers are passed by the consumer.\n */\nexport function FilterProvider({\n children,\n filters,\n activeFilters,\n onFilterChange,\n isNavigating: isNavigatingProp = false,\n strings: stringsProp,\n locale: localeProp,\n onError,\n}: FilterProviderProps) {\n const filtersRef = useRef(filters);\n const activeFiltersRef = useRef(activeFilters);\n const onFilterChangeRef = useRef(onFilterChange);\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n\n // Trigger re-render when async labels are resolved\n const [, setAsyncCacheVersion] = useState(0);\n\n const locale = localeProp || 'en';\n const strings = useStrings(defaultFilterStrings, stringsProp);\n\n // Update refs when prop change\n useEffect(() => {\n filtersRef.current = filters;\n }, [filters]);\n\n useEffect(() => {\n activeFiltersRef.current = activeFilters;\n }, [activeFilters]);\n\n useEffect(() => {\n onFilterChangeRef.current = onFilterChange;\n }, [onFilterChange]);\n\n const addFilter = useCallback(\n (filter: ActiveFilter) => {\n const newFilters = [...activeFilters, filter];\n onFilterChangeRef.current(newFilters);\n },\n [activeFilters],\n );\n\n const removeFilter = useCallback(\n (id: string) => {\n const newFilters = activeFilters.filter(\n (f: ActiveFilter) => f.id !== id && f.key !== id,\n );\n onFilterChangeRef.current(newFilters);\n },\n [activeFilters],\n );\n\n const updateFilter = useCallback(\n (id: string, updates: Partial<ActiveFilter>) => {\n const newFilters = activeFilters.map((f: ActiveFilter) =>\n f.id === id || f.key === id ? { ...f, ...updates } : f,\n );\n onFilterChangeRef.current(newFilters);\n },\n [activeFilters],\n );\n\n const clearFilters = useCallback(() => {\n onFilterChangeRef.current([]);\n }, []);\n\n const replaceFilters = useCallback((newFilters: ActiveFilter[]) => {\n onFilterChangeRef.current(newFilters);\n }, []);\n\n const getFilterByKey = useCallback(\n (key: string): FilterConfig | undefined => {\n return filtersRef.current.find((f: FilterConfig) => f.key === key);\n },\n [],\n );\n\n const getFilterValue = useCallback(\n (key: string): string[] => {\n const filter = activeFilters.find(\n (f: ActiveFilter) => f.key === key,\n );\n return filter?.value || [];\n },\n [activeFilters],\n );\n\n const setFilterValue = useCallback(\n (key: string, value: string[]) => {\n const existingFilter = activeFilters.find(\n (f: ActiveFilter) => f.key === key,\n );\n\n if (value.length === 0) {\n // Remove filter if the value is empty\n if (existingFilter) {\n removeFilter(key);\n }\n } else {\n // Update or add filter\n if (existingFilter) {\n updateFilter(key, { value });\n } else {\n // Get the filter config to check for default operator\n const filterConfig = filtersRef.current.find(\n (f: FilterConfig) => f.key === key,\n );\n const defaultOperator =\n filterConfig?.operator ??\n filterConfig?.operators?.[0]?.value ??\n (filterConfig\n ? getDefaultOperatorForType(filterConfig.type)\n : 'equals');\n\n addFilter({\n id: key,\n key,\n value,\n operator: defaultOperator,\n });\n }\n }\n },\n [activeFilters, addFilter, removeFilter, updateFilter],\n );\n\n const isFilterActive = useCallback(\n (key: string): boolean => {\n return activeFilters.some(\n (f: ActiveFilter) => f.key === key && f.value.length > 0,\n );\n },\n [activeFilters],\n );\n\n const getFilterOperator = useCallback(\n (key: string): FilterOperator | undefined => {\n const filter = activeFilters.find(\n (f: ActiveFilter) => f.key === key,\n );\n return filter?.operator || 'equals';\n },\n [activeFilters],\n );\n\n const setFilterOperator = useCallback(\n (key: string, operator: FilterOperator) => {\n const existingFilter = activeFilters.find(\n (f: ActiveFilter) => f.key === key,\n );\n if (existingFilter) {\n updateFilter(key, { operator });\n }\n },\n [activeFilters, updateFilter],\n );\n\n const validateFilter = useCallback(\n (key: string, value: unknown): boolean | string => {\n const filter = filtersRef.current.find(\n (f: FilterConfig) => f.key === key,\n );\n if (!filter) return false;\n return validateFilterValue(filter, value, (path) =>\n getFilterString(strings, path),\n );\n },\n [strings],\n );\n\n const getDependentFilters = useCallback((key: string): FilterConfig[] => {\n return filtersRef.current.filter((f: FilterConfig) =>\n f.dependencies?.some((dep: { key: string }) => dep.key === key),\n );\n }, []);\n\n const getFilterOptions = useCallback(\n async (key: string): Promise<FilterOption[]> => {\n const filter = filtersRef.current.find(\n (f: FilterConfig) => f.key === key,\n );\n if (!filter) return [];\n\n if (filter.fetchOptions) {\n const filtersState = activeFiltersRef.current.reduce(\n (acc, current) => {\n acc[current.key] = current.value;\n return acc;\n },\n {} as Record<string, string[]>,\n );\n\n const dependencyValues = (filter.dependencies ?? []).reduce(\n (acc, dep) => {\n const dependencyValue = filtersState[dep.key];\n if (dependencyValue && dependencyValue.length > 0) {\n acc[dep.key] = dependencyValue;\n }\n return acc;\n },\n {} as Record<string, string[]>,\n );\n\n try {\n const dynamicOptions =\n await filter.fetchOptions(dependencyValues);\n if (Array.isArray(dynamicOptions)) {\n return dynamicOptions;\n }\n } catch (error) {\n if (import.meta.env?.DEV) {\n\t console.error(\n\t `Failed fetching options for filter \"${key}\":`,\n\t error,\n\t );\n }\n onErrorRef.current?.(error, { phase: 'fetch-options', filterKey: key });\n }\n }\n\n // Fall back to the static definition if no dynamic options are available\n return filter.options || [];\n },\n [],\n );\n\n const cacheAsyncOptions = useCallback(\n (filterKey: string, options: FilterOption[]) => {\n let filterMap = globalAsyncOptionsCache.get(filterKey);\n if (!filterMap) {\n filterMap = new Map();\n globalAsyncOptionsCache.set(filterKey, filterMap);\n }\n let hasNew = false;\n for (const opt of options) {\n if (!filterMap.has(opt.value)) {\n hasNew = true;\n }\n filterMap.set(opt.value, opt);\n }\n // Trigger re-render if new labels were added so filter pills update\n if (hasNew) {\n setAsyncCacheVersion((v) => v + 1);\n }\n },\n [],\n );\n\n const getAsyncOptionLabel = useCallback(\n (filterKey: string, optionValue: string): string | undefined => {\n return globalAsyncOptionsCache.get(filterKey)?.get(optionValue)?.label;\n },\n [],\n );\n\n // On mount, preload options for any active ASYNC_SELECT filters so that\n // filter pills can display resolved labels instead of raw UUIDs.\n useEffect(() => {\n const controller = new AbortController();\n\n for (const filter of filters) {\n if (filter.type !== FilterType.ASYNC_SELECT) continue;\n\n const active = activeFilters.find((af) => af.key === filter.key);\n if (!active || active.value.length === 0) continue;\n\n // Check if all active values already have cached labels\n const allCached = active.value.every(\n (v) => globalAsyncOptionsCache.get(filter.key)?.has(v),\n );\n if (allCached) continue;\n\n // Preload: fetch with empty query to get default/popular options\n const { asyncConfig, fetchOptions } = filter;\n if (asyncConfig?.fetcher && asyncConfig.mapToOption) {\n void asyncConfig\n .fetcher({\n query: '',\n limit: asyncConfig.limit ?? 10,\n signal: controller.signal,\n })\n .then((items) => {\n if (controller.signal.aborted) return;\n const options = items.map(asyncConfig.mapToOption);\n cacheAsyncOptions(filter.key, options);\n })\n .catch(() => {\n // Silently ignore — labels will fallback to \"N selected\"\n });\n } else if (fetchOptions) {\n void fetchOptions({ q: [''] })\n .then((options) => {\n if (controller.signal.aborted) return;\n cacheAsyncOptions(filter.key, options);\n })\n .catch(() => {\n // Silently ignore\n });\n }\n }\n\n return () => controller.abort();\n // Only run on mount — filters/activeFilters identity may change on every render\n // but we only need to preload once.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const value = useMemo(\n () => ({\n activeFilters,\n filters,\n addFilter,\n removeFilter,\n updateFilter,\n clearFilters,\n replaceFilters,\n getFilterByKey,\n getFilterValue,\n setFilterValue,\n isFilterActive,\n getFilterOperator,\n setFilterOperator,\n validateFilter,\n getDependentFilters,\n getFilterOptions,\n isNavigating: isNavigatingProp,\n locale,\n strings,\n cacheAsyncOptions,\n getAsyncOptionLabel,\n }),\n [\n activeFilters,\n filters,\n addFilter,\n removeFilter,\n updateFilter,\n clearFilters,\n replaceFilters,\n getFilterByKey,\n getFilterValue,\n setFilterValue,\n isFilterActive,\n getFilterOperator,\n setFilterOperator,\n validateFilter,\n getDependentFilters,\n getFilterOptions,\n isNavigatingProp,\n locale,\n strings,\n cacheAsyncOptions,\n getAsyncOptionLabel,\n ],\n );\n\n return (\n <FilterContext.Provider value={value}>\n {children}\n </FilterContext.Provider>\n );\n}\n\nexport function useFilters() {\n const context = useContext(FilterContext);\n if (!context) {\n throw new Error('useFilters must be used within a FilterProvider');\n }\n return context;\n}\n","/**\n * useFilterGroups — headless partitioning of the filter list into the four\n * groups `FilterLayout` (and any custom layout) renders distinctly:\n *\n * - `searchFilters` — `FilterType.SEARCH`, always inline\n * - `alwaysVisibleFilters` — `displayConfig.display === 'always'` and inactive\n * - `activeRegularFilters` — non-search filters that are currently active\n * - `popoverFilters` — non-search, inactive, non-always (live in \"+\" popover)\n *\n * Plus `activeFilterKeys` and `hasActive` helpers. Consumers building a\n * custom strip layout against `<FilterProvider>` can call this and place\n * each group wherever they want without re-implementing the partition\n * logic.\n *\n * `dynamicFilterOptions` (optional) lets consumers swap a filter's option\n * list at render time (e.g. async-loaded options from a parent component)\n * without mutating the provider state.\n */\nimport { useMemo } from 'react';\n\nimport { useFilters } from '../filter-context';\nimport { type FilterConfig, FilterType } from '../filters.types';\n\nexport interface UseFilterGroupsOptions {\n /** Override `filter.options` per-key at render time. */\n dynamicFilterOptions?: Record<string, FilterConfig['options']>;\n}\n\nexport interface UseFilterGroupsResult {\n /** Filters merged with `dynamicFilterOptions`. */\n processedFilters: FilterConfig[];\n searchFilters: FilterConfig[];\n alwaysVisibleFilters: FilterConfig[];\n activeRegularFilters: FilterConfig[];\n popoverFilters: FilterConfig[];\n activeFilterKeys: string[];\n hasActive: boolean;\n}\n\nexport function useFilterGroups(options: UseFilterGroupsOptions = {}): UseFilterGroupsResult {\n const { dynamicFilterOptions } = options;\n const { filters, isFilterActive } = useFilters();\n\n const processedFilters = useMemo(() => {\n if (!dynamicFilterOptions) return filters;\n return filters.map((filter) => {\n const dyn = dynamicFilterOptions[filter.key];\n if (Array.isArray(dyn)) return { ...filter, options: dyn };\n return filter;\n });\n }, [filters, dynamicFilterOptions]);\n\n return useMemo(() => {\n const searchFilters = processedFilters.filter((f) => f.type === FilterType.SEARCH);\n const activeRegularFilters = processedFilters.filter(\n (f) => f.type !== FilterType.SEARCH && isFilterActive(f.key),\n );\n const alwaysVisibleFilters = processedFilters.filter(\n (f) =>\n f.type !== FilterType.SEARCH\n && !isFilterActive(f.key)\n && f.displayConfig?.display === 'always',\n );\n const popoverFilters = processedFilters.filter(\n (f) =>\n f.type !== FilterType.SEARCH\n && !isFilterActive(f.key)\n && f.displayConfig?.display !== 'always',\n );\n const activeFilterKeys = activeRegularFilters.map((f) => f.key);\n\n return {\n processedFilters,\n searchFilters,\n alwaysVisibleFilters,\n activeRegularFilters,\n popoverFilters,\n activeFilterKeys,\n hasActive: activeFilterKeys.length > 0,\n };\n }, [processedFilters, isFilterActive]);\n}\n","import React, { useState } from 'react';\n\nimport { Button } from '@/components/base/buttons';\nimport { PopoverMenu } from '@/components/base/popover-menu';\nimport { Text } from '@/components/typography';\nimport { cn } from '@/lib/utils';\n\nimport { useFilters } from '../filter-context';\nimport type { FilterOperator, OperatorOption } from '../filters.types';\n\ninterface FilterOperatorSelectProps {\n operator: FilterOperator;\n operators: OperatorOption[];\n onOperatorChange: (operator: FilterOperator) => void;\n /** Segment-reset classes forwarded by the parent pill so the trigger\n * drops its base border + focus ring (it lives inside a segmented\n * pill, not as a standalone button). */\n segmentResetClass?: string;\n}\n\n/**\n * FilterOperatorSelect — operator dropdown for an active filter pill.\n *\n * Now delegates the trigger + popover + command-list pattern entirely to\n * `PopoverMenu`. The trigger is rendered in the pill's inline strip, the\n * `header` slot supplies the small \"Operator\" eyebrow, and item rendering\n * stays compact (xs typography, density-tokenized padding from base/command).\n */\nexport function FilterOperatorSelect({\n operator,\n operators,\n onOperatorChange,\n segmentResetClass,\n}: FilterOperatorSelectProps) {\n const [open, setOpen] = useState(false);\n const { strings } = useFilters();\n\n const currentOperatorLabel =\n operators.find((op) => op.value === operator)?.label || operator;\n\n const handleTriggerClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n };\n\n return (\n <PopoverMenu\n open={open}\n onOpenChange={setOpen}\n search={false}\n trigger={\n <Button\n variant=\"secondary\"\n buttonStyle=\"ghost\"\n className={cn(\n segmentResetClass,\n 'text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground h-full px-3 text-xs',\n )}\n onClick={handleTriggerClick}\n type=\"button\"\n >\n {currentOperatorLabel}\n </Button>\n }\n header={\n <Text tag=\"span\" size=\"xs\" weight=\"semibold\">\n {strings.operator}\n </Text>\n }\n contentClassName=\"w-48\"\n items={operators.map((op) => ({\n value: op.value,\n label: op.label,\n selected: op.value === operator,\n }))}\n onSelect={(item) => {\n onOperatorChange(item.value as FilterOperator);\n setOpen(false);\n }}\n />\n );\n}\n","import { format } from 'date-fns';\nimport { CalendarIcon } from 'lucide-react';\nimport { Text } from '@/components/typography';\nimport { useFilters } from '../filter-context';\nimport type { FilterStrings } from '../filters.strings';\nimport { interpolateFilterString } from '../filters.strings';\nimport { FilterType, type FilterConfig } from '../filters.types';\n\ninterface FilterValueDisplayProps {\n filter: FilterConfig;\n value: string[];\n}\n\n/**\n * Filter Value Display Component\n *\n * This component provides the UI for displaying filter values.\n * It handles:\n * - Displaying filter values with appropriate formatting\n * - Showing icons for filter options\n * - Handling date formatting\n * - Supporting internationalization\n *\n * The component is used to show users the current value of a filter\n * in a consistent and informative way.\n */\n\nexport function FilterValueDisplay({ filter, value }: FilterValueDisplayProps) {\n const { strings } = useFilters();\n\n // Empty state — render the localized \"Nothing selected\" instead of an\n // empty cell so the pill never collapses to no-value text.\n if (value.length === 0 && filter.type !== FilterType.DATE) {\n return (\n <Text tag=\"span\" size=\"xs\" type=\"secondary\">\n {strings.nothingSelected}\n </Text>\n );\n }\n\n // For ASYNC_SELECT — always show \"N selected\"\n if (filter.type === FilterType.ASYNC_SELECT && !filter.options?.length) {\n return (\n <Text tag=\"span\" size=\"xs\" weight=\"semibold\">\n {renderAsyncValueText(filter, value, strings)}\n </Text>\n );\n }\n\n if (filter.options && filter.type !== FilterType.DATE) {\n return (\n <div className=\"flex items-center gap-1\">\n {/* Option icons - shown for both single and multi-select cases */}\n <div className=\"relative flex\">\n {value.slice(0, 2).map((val, index) => {\n const option = filter.options?.find(\n (o) => o.value === val,\n );\n if (!option?.icon) return null;\n\n return (\n <div\n key={val}\n className={`${index > 0 ? '-ml-1.5' : ''} border-background bg-background relative rounded-full border`}\n style={{ zIndex: 10 - index }}\n >\n {option.icon}\n </div>\n );\n })}\n {value.length > 2 && (\n <div className=\"bg-muted border-background relative -ml-1.5 flex h-4 w-4 items-center justify-center rounded-full border text-xxs font-medium\">\n +{value.length - 2}\n </div>\n )}\n </div>\n\n {/* Value text */}\n <Text tag=\"span\" size=\"xs\" weight=\"semibold\">\n {renderValueText(filter, value, strings)}\n </Text>\n </div>\n );\n }\n\n // For date filters\n if (filter.type === FilterType.DATE) {\n return (\n <div className=\"flex items-center gap-1\">\n <CalendarIcon className=\"text-muted-foreground h-3.5 w-3.5\" />\n <Text tag=\"span\" size=\"xs\" weight=\"semibold\">\n {renderDateValue(filter, value, strings)}\n </Text>\n </div>\n );\n }\n\n // For other filters\n return (\n <Text tag=\"span\" size=\"xs\" weight=\"semibold\">\n {renderValueText(filter, value, strings)}\n </Text>\n );\n}\n\n// Helper function to render date values\nfunction renderDateValue(\n filter: FilterConfig,\n value: string[],\n strings: FilterStrings,\n) {\n if (filter.operator === 'between' && value.length === 2) {\n return `${formatDateValue(value[0], filter.dateFormat?.display)} - ${formatDateValue(value[1], filter.dateFormat?.display)}`;\n }\n\n if (value.length === 1) {\n return formatDateValue(value[0], filter.dateFormat?.display);\n }\n\n if (value.length === 2) {\n return `${formatDateValue(value[0], filter.dateFormat?.display)} - ${formatDateValue(value[1], filter.dateFormat?.display)}`;\n }\n\n return (\n filter.datePickerConfig?.noDatePlaceholder ||\n strings.calendar.notDateSelected\n );\n}\n\n// Helper function to render text values for async filters — always \"N selected\"\nfunction renderAsyncValueText(\n _filter: FilterConfig,\n value: string[],\n strings: FilterStrings,\n) {\n if (value.length === 0) return '';\n return interpolateFilterString(strings.selected, { count: value.length, filterLabel: (value.length > 1 ? _filter.pluralLabel : _filter.label) ?? _filter.label });\n}\n\n// Helper function to render text values\nfunction renderValueText(\n filter: FilterConfig,\n value: string[],\n strings: FilterStrings,\n) {\n if (value.length > 1) {\n return interpolateFilterString(strings.selected, {\n count: value.length,\n filterLabel: filter.pluralLabel ?? filter.label,\n });\n }\n\n return value\n .map((val) => {\n const option = filter.options?.find((o) => o.value === val);\n return option?.label || val;\n })\n .join(', ');\n}\n\nfunction formatDateValue(rawValue: string, pattern?: string) {\n const parsed = new Date(rawValue);\n\n if (Number.isNaN(parsed.getTime())) {\n return rawValue;\n }\n\n if (pattern) {\n try {\n return format(parsed, pattern);\n } catch {\n // Fall through to locale formatting if the provided pattern is invalid\n }\n }\n\n return parsed.toLocaleDateString();\n}\n","import { ChevronDown, X } from 'lucide-react';\nimport React from 'react';\nimport { Button } from '@/components/base/buttons';\nimport { Text } from '@/components/typography';\nimport { cn } from '@/lib/utils';\nimport { useFilters } from '../filter-context';\nimport {\n FILTER_ELEMENT_HEIGHT,\n type FilterConfig,\n type FilterOperator,\n type OperatorOption,\n} from '../filters.types';\nimport { FilterOperatorSelect } from './filter-operator-select';\nimport { FilterValueDisplay } from './filter-value-display';\n\ninterface ActiveFilterItemProps {\n filter: FilterConfig;\n value: string[];\n isActive: boolean;\n operators: OperatorOption[];\n operator: FilterOperator;\n onOperatorChange: (operator: FilterOperator) => void;\n onFilterClear: () => void;\n onFilterClick: () => void;\n}\n\n/**\n * Active Filter Item Component\n *\n * This component displays a single active filter in the filter list.\n * It provides:\n * - Display of filter label and value\n * - Remove filter functionality\n * - Visual feedback for active state\n * - Support for different filter types\n *\n * The component is used in the filter list to show currently active filters\n * and allow users to remove them.\n */\n\nexport function ActiveFilterItem({\n filter,\n value,\n isActive,\n operators,\n operator,\n onOperatorChange,\n onFilterClear,\n onFilterClick,\n}: ActiveFilterItemProps) {\n const { strings } = useFilters();\n\n // Handle button click to avoid interference with children\n const handleLabelClick = (e: React.MouseEvent) => {\n // Only proceed if this is directly on the button, not a child element\n if (\n e.currentTarget === e.target ||\n (e.target as HTMLElement).tagName !== 'BUTTON'\n ) {\n onFilterClick();\n }\n };\n\n // Inside the pill, segment buttons must not paint their own border or\n // focus ring — the pill itself is the visual container. The global\n // `<Button>` primitive bakes in `border border-transparent\n // focus-visible:border-ring focus-visible:ring-3`, so without these\n // overrides every segment paints a full 1px box (showing as a\n // double-border just inside the pill chrome) and a rounded focus ring\n // when the popover opens.\n const SEGMENT_RESET =\n '!border-0 !rounded-none !shadow-none focus-visible:!ring-0 focus-visible:!border-transparent';\n\n // Explicit 1px divider — the segment buttons use `!border-0` (so they\n // don't paint an inner full-box decoration) which would also wipe a\n // `divide-x` border. A standalone separator div is unambiguous and\n // doesn't fight with the buttons' baseline chrome.\n const Divider = () => <div aria-hidden className=\"w-px self-stretch bg-border\" />;\n\n return (\n <div\n role=\"group\"\n aria-label={filter.label}\n className={cn(\n `border-input bg-background flex ${FILTER_ELEMENT_HEIGHT} items-center overflow-hidden rounded-md border`,\n filter.displayConfig?.className,\n isActive && 'active',\n )}\n >\n {/* Filter icon, label and dropdown button grouped together */}\n <Button\n type=\"button\"\n variant=\"secondary\"\n buttonStyle=\"ghost\"\n className={cn(\n SEGMENT_RESET,\n 'flex h-full items-center px-3 hover:bg-accent hover:text-accent-foreground',\n )}\n onClick={handleLabelClick}\n >\n {!!filter.icon && (\n <span className=\"text-muted-foreground mr-1\">\n {filter.icon}\n </span>\n )}\n <Text tag=\"span\" size=\"xs\" weight=\"semibold\">{filter.label}</Text>\n <ChevronDown className=\"ml-1 h-4 w-4\" />\n </Button>\n\n <Divider />\n\n {/* Operator dropdown */}\n <FilterOperatorSelect\n operator={operator}\n operators={operators}\n onOperatorChange={onOperatorChange}\n segmentResetClass={SEGMENT_RESET}\n />\n\n <Divider />\n\n {/* Value display with icons and count when multiple selected - explicitly non-interactive */}\n <div className=\"pointer-events-none flex flex-1 items-center px-2\">\n <FilterValueDisplay filter={filter} value={value} />\n </div>\n\n <Divider />\n\n {/* Clear button */}\n <Button\n variant=\"secondary\" buttonStyle=\"ghost\"\n className={cn(SEGMENT_RESET, 'h-full w-8 px-0 rounded-r-md')}\n onClick={(e) => {\n e.stopPropagation();\n e.preventDefault();\n onFilterClear();\n }}\n >\n <X className=\"h-4 w-4\" />\n <span className=\"sr-only\">{strings.clear}</span>\n </Button>\n </div>\n );\n}\n","import { useEffect, useState } from 'react';\n\nexport function useDebounce<T>(value: T, delay: number = 500): T {\n const [debouncedValue, setDebouncedValue] = useState<T>(value);\n\n useEffect(() => {\n const handler = setTimeout(() => {\n setDebouncedValue(value);\n }, delay);\n\n return () => {\n clearTimeout(handler);\n };\n }, [value, delay]);\n\n return debouncedValue;\n}","/**\n * useAsyncOptions — peer-dep-free async fetcher for filter facets.\n *\n * Replaces the previous `@tanstack/react-query` integration so the feature\n * stays framework-agnostic. Behaviour preserved:\n * - Debounced search input\n * - Min-query-length gating with an `isBelowMinQuery` flag\n * - Optional preload (empty query) with an `enabled` toggle\n * - AbortController on each new request\n * - In-memory cache keyed by `(filter.key, query)` to avoid refetching\n * identical queries within the cache window (`staleTime`)\n * - `refetch()` for the consumer's retry button\n *\n * Consumers that want react-query semantics can compose `asyncConfig.fetcher`\n * with their own `useQuery` and pass the resulting `FilterOption[]` through\n * a controlled `options` prop on the facet — no integration code needed in\n * this library.\n */\nimport { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport { useDebounce } from '@/hooks/use-debounce';\nimport { useFiltersConfig } from '@/lib/ui-provider';\n\nimport type { FilterConfig, FilterOption } from '../filters.types';\n\ninterface CacheEntry {\n timestamp: number;\n data: FilterOption[];\n}\n\nconst moduleCache = new Map<string, CacheEntry>();\n\nexport interface UseAsyncOptionsResult {\n options: FilterOption[];\n isLoading: boolean;\n isFetching: boolean;\n isError: boolean;\n refetch: () => void;\n isBelowMinQuery: boolean;\n minQueryLength: number;\n}\n\nexport function useAsyncOptions(\n filter: FilterConfig,\n searchInput: string,\n isActive: boolean,\n): UseAsyncOptionsResult {\n const { asyncConfig, fetchOptions } = filter;\n const { debounceMs: configDebounceMs, defaultPageSize } = useFiltersConfig();\n const debounceMs = asyncConfig?.debounceMs ?? filter.delay ?? configDebounceMs ?? 300;\n const debouncedSearch = useDebounce(searchInput, debounceMs);\n const normalisedQuery = (debouncedSearch ?? '').trim();\n\n const limit = asyncConfig?.limit ?? defaultPageSize ?? 10;\n const minQueryLength = asyncConfig?.minQueryLength ?? 0;\n const preload = asyncConfig?.preload ?? true;\n const staleTime = asyncConfig?.staleTime ?? 60_000;\n\n const isPreload = normalisedQuery.length === 0 && preload;\n const meetsMinLength = normalisedQuery.length >= minQueryLength;\n const canFetch =\n isActive && (isPreload || (normalisedQuery.length > 0 && meetsMinLength));\n const isBelowMinQuery =\n isActive &&\n !isPreload &&\n normalisedQuery.length > 0 &&\n normalisedQuery.length < minQueryLength;\n\n const cacheKey = useMemo(() => {\n if (asyncConfig?.queryKey) {\n return JSON.stringify(\n asyncConfig.queryKey({ query: normalisedQuery, limit }),\n );\n }\n return JSON.stringify(['filter', filter.key, normalisedQuery, limit]);\n }, [asyncConfig, filter.key, normalisedQuery, limit]);\n\n const queryFn = useCallback(\n async (signal: AbortSignal): Promise<FilterOption[]> => {\n if (asyncConfig?.fetcher && asyncConfig.mapToOption) {\n const items = await asyncConfig.fetcher({\n query: normalisedQuery,\n limit,\n signal,\n });\n return items.map(asyncConfig.mapToOption);\n }\n if (fetchOptions) {\n return fetchOptions({ q: [normalisedQuery] });\n }\n return [];\n },\n [asyncConfig, fetchOptions, normalisedQuery, limit],\n );\n\n const [state, setState] = useState<{\n data: FilterOption[];\n loading: boolean;\n fetching: boolean;\n error: boolean;\n }>(() => {\n const cached = moduleCache.get(cacheKey);\n return {\n data: cached?.data ?? [],\n loading: false,\n fetching: false,\n error: false,\n };\n });\n\n const [reloadTick, setReloadTick] = useState(0);\n const refetch = useCallback(() => setReloadTick((t) => t + 1), []);\n\n useEffect(() => {\n if (!canFetch) return;\n\n const cached = moduleCache.get(cacheKey);\n const isFresh =\n cached !== undefined && Date.now() - cached.timestamp < staleTime;\n\n const controller = new AbortController();\n\n if (isFresh && reloadTick === 0) {\n setState({\n data: cached.data,\n loading: false,\n fetching: false,\n error: false,\n });\n return () => controller.abort();\n }\n\n setState((prev) => ({\n data: cached?.data ?? prev.data,\n loading: cached === undefined,\n fetching: true,\n error: false,\n }));\n\n let cancelled = false;\n queryFn(controller.signal)\n .then((data) => {\n if (cancelled) return;\n moduleCache.set(cacheKey, { timestamp: Date.now(), data });\n setState({\n data,\n loading: false,\n fetching: false,\n error: false,\n });\n })\n .catch((err) => {\n if (cancelled || controller.signal.aborted) return;\n if (err && (err as { name?: string }).name === 'AbortError') return;\n setState((prev) => ({\n data: prev.data,\n loading: false,\n fetching: false,\n error: true,\n }));\n });\n\n return () => {\n cancelled = true;\n controller.abort();\n };\n }, [cacheKey, queryFn, canFetch, staleTime, reloadTick]);\n\n return {\n options: canFetch ? state.data : [],\n isLoading: canFetch && state.loading,\n isFetching: canFetch && state.fetching,\n isError: canFetch && state.error,\n refetch,\n isBelowMinQuery,\n minQueryLength,\n };\n}\n","import {\n AlertCircle,\n ArrowLeft,\n Check,\n Loader2,\n} from 'lucide-react';\nimport { useMemo, useRef, useState } from 'react';\n\nimport { Button } from '@/components/base/buttons';\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from '@/components/base/command';\nimport { Text } from '@/components/typography';\n\nimport { useFilters } from '../filter-context';\nimport { interpolateFilterString } from '../filters.strings';\nimport type { FilterConfig, FilterOption } from '../filters.types';\nimport { useAsyncOptions } from '../hooks';\n\n// ---------------------------------------------------------------------------\n// Props\n// ---------------------------------------------------------------------------\n\ninterface AsyncFilterContentProps {\n filter: FilterConfig;\n value: string[];\n onFilterChange: (value: string[]) => void;\n onBackToFilterList: () => void;\n onClose: () => void;\n isFromMainFilterButton?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\n/**\n * Async Filter Content – renders inside the popover pipeline.\n *\n * Matches the layout of RegularFilterContent (header + command list + footer)\n * but fetches options asynchronously via TanStack Query.\n */\nexport function AsyncFilterContent({\n filter,\n value,\n onFilterChange,\n onBackToFilterList,\n onClose,\n isFromMainFilterButton = false,\n}: AsyncFilterContentProps) {\n const { strings, cacheAsyncOptions, getAsyncOptionLabel } = useFilters();\n const [searchInput, setSearchInput] = useState('');\n const [tempValue, setTempValue] = useState<string[]>(value ?? []);\n\n // Sync tempValue when external value changes\n const prevValueRef = useRef(value);\n if (value !== prevValueRef.current) {\n prevValueRef.current = value;\n setTempValue(value ?? []);\n }\n\n const {\n options,\n isLoading,\n isFetching,\n isError,\n refetch,\n isBelowMinQuery,\n minQueryLength,\n } = useAsyncOptions(filter, searchInput, true);\n\n // Populate the shared async options cache for label resolution in FilterValueDisplay\n if (options.length > 0) {\n cacheAsyncOptions(filter.key, options);\n }\n\n const isMulti = filter.multiple !== false;\n const maxSelected = filter.maxSelected;\n const showBackButton = Boolean(isFromMainFilterButton);\n\n // Sort options: selected items first, then the rest.\n // Also include cached selected items that may not be in current search results.\n const sortedOptions = useMemo(() => {\n const selectedSet = new Set(tempValue);\n const optionValueSet = new Set(options.map((o) => o.value));\n\n // Resolve selected items missing from current results via the global cache\n const missingSelected: FilterOption[] = [];\n for (const val of tempValue) {\n if (!optionValueSet.has(val)) {\n const label = getAsyncOptionLabel(filter.key, val);\n if (label) {\n missingSelected.push({ value: val, label, icon: filter.icon });\n }\n }\n }\n\n const all = [...missingSelected, ...options];\n return all.sort((a, b) => {\n const aSelected = selectedSet.has(a.value) ? 0 : 1;\n const bSelected = selectedSet.has(b.value) ? 0 : 1;\n return aSelected - bSelected;\n });\n }, [options, tempValue, filter.key, filter.icon, getAsyncOptionLabel]);\n\n const handleValueSelect = (optionValue: string) => {\n if (isMulti) {\n if (tempValue.includes(optionValue)) {\n setTempValue(tempValue.filter((v) => v !== optionValue));\n } else {\n if (maxSelected && tempValue.length >= maxSelected) return;\n setTempValue([...tempValue, optionValue]);\n }\n } else {\n setTempValue([optionValue]);\n if (filter.closeOnSelect === true) {\n onFilterChange([optionValue]);\n onClose();\n }\n }\n };\n\n const handleDone = () => {\n onFilterChange(tempValue);\n onClose();\n };\n\n // Render the status area inside CommandEmpty\n const emptyContent = useMemo(() => {\n if (isLoading || isFetching) {\n return (\n <div className=\"flex items-center justify-center gap-2 py-4\">\n <Loader2 className=\"text-muted-foreground size-4 animate-spin\" />\n <Text tag=\"span\" size=\"xs\" type=\"secondary\">\n {strings.searching}\n </Text>\n </div>\n );\n }\n\n if (isError) {\n return (\n <div className=\"flex flex-col items-center gap-2 py-4\">\n <div className=\"flex items-center gap-1.5\">\n <AlertCircle className=\"text-destructive size-4\" />\n <Text tag=\"span\" size=\"xs\" type=\"secondary\">\n {strings.fetchError}\n </Text>\n </div>\n <Button\n variant=\"secondary\"\n buttonStyle=\"outline\"\n size=\"xs\"\n onClick={(e) => {\n e.stopPropagation();\n void refetch();\n }}\n >\n {strings.retryFetch}\n </Button>\n </div>\n );\n }\n\n if (isBelowMinQuery) {\n return (\n <div className=\"text-muted-foreground flex items-center justify-center py-4\">\n <Text tag=\"span\" size=\"xs\" type=\"secondary\">\n {interpolateFilterString(strings.minQueryHint, {\n min: minQueryLength,\n })}\n </Text>\n </div>\n );\n }\n\n return strings.noOptionsFound;\n }, [\n isLoading,\n isFetching,\n isError,\n isBelowMinQuery,\n minQueryLength,\n strings,\n refetch,\n ]);\n\n return (\n <>\n {/* Header – matches RegularFilterContent */}\n <div className=\"flex items-center border-b p-2\">\n {Boolean(showBackButton) && (\n <Button\n variant=\"secondary\"\n buttonStyle=\"ghost\"\n className=\"mr-2 h-8 w-8 p-0\"\n onClick={onBackToFilterList}\n aria-label={strings.backToFilters}\n >\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n )}\n <div className=\"flex flex-col\">\n <Text tag=\"span\" size=\"xs\" weight=\"semibold\">\n {filter.label}\n </Text>\n <Text tag=\"span\" size=\"xs\" type=\"secondary\">\n {strings.selectValues}\n </Text>\n </div>\n </div>\n\n {/* Command list with async search */}\n <Command shouldFilter={false}>\n <CommandInput\n placeholder={interpolateFilterString(\n strings.searchPlaceholder,\n { filterLabel: filter.label.toLowerCase() },\n )}\n value={searchInput}\n onValueChange={setSearchInput}\n />\n <CommandList>\n {sortedOptions.length === 0 ? (\n <CommandEmpty>{emptyContent}</CommandEmpty>\n ) : (\n <CommandGroup>\n {Boolean(isFetching && !isLoading) && (\n <div className=\"flex items-center gap-1.5 px-2 py-1\">\n <Loader2 className=\"text-muted-foreground size-3 animate-spin\" />\n <Text tag=\"span\" size=\"xs\" type=\"secondary\">\n {strings.searching}\n </Text>\n </div>\n )}\n {sortedOptions.map((option) => (\n <CommandItem\n key={option.value}\n onSelect={() => handleValueSelect(option.value)}\n disabled={\n option.disabled ||\n (!!maxSelected &&\n tempValue.length >= maxSelected &&\n !tempValue.includes(option.value))\n }\n className=\"flex items-center gap-2\"\n >\n {option.icon}\n <Text tag=\"span\" size=\"xs\">\n {option.label}\n </Text>\n {tempValue.includes(option.value) && (\n <span className=\"ml-auto\">\n <Check className=\"h-4 w-4\" />\n </span>\n )}\n </CommandItem>\n ))}\n </CommandGroup>\n )}\n </CommandList>\n </Command>\n\n {/* Footer – matches RegularFilterContent */}\n <div className=\"flex justify-between border-t p-2\">\n <Text tag=\"span\" size=\"xs\" type=\"secondary\">\n {interpolateFilterString(strings.selected, {\n count: tempValue.length,\n filterLabel: (tempValue.length > 1 ? filter.pluralLabel : filter.label) ?? filter.label,\n })}\n </Text>\n <div className=\"flex gap-2\">\n <Button\n variant=\"secondary\"\n buttonStyle=\"outline\"\n size=\"xs\"\n onClick={handleDone}\n >\n {strings.confirm}\n </Button>\n </div>\n </div>\n </>\n );\n}\n","import { isValid } from 'date-fns';\nimport type { DateRange } from 'react-day-picker';\nimport {\n DatePicker,\n type DateOutput,\n type DateRangeOutput,\n type PresetDateRange,\n} from '@/components/base/date-pickers';\nimport { cn } from '@/lib/utils';\nimport { useFilters } from '../filter-context';\nimport type { FilterConfig } from '../filters.types';\n\nconst EMPTY_PRESETS: PresetDateRange[] = [];\n\ninterface DateFacetProps {\n filter: FilterConfig;\n value: { start?: Date; end?: Date };\n onChange: (value: { start?: Date; end?: Date }) => void;\n className?: string;\n}\n\nexport function DateFacet({\n filter,\n value,\n onChange,\n className,\n}: DateFacetProps) {\n const { strings } = useFilters();\n\n const isRangeMode =\n filter.operators?.some((op) => op.value === 'between') ||\n filter.operator === 'between' ||\n filter.key.toLowerCase().includes('range') ||\n filter.key.toLowerCase().includes('between');\n\n const dateFormat = filter.dateFormat?.param ?? 'yyyy-MM-dd';\n const readableFormat = filter.dateFormat?.display ?? 'PPP';\n const placeholder = isRangeMode\n ? (filter.datePickerConfig?.noRangePlaceholder ??\n filter.placeholder ??\n strings.calendar.notDateRangeSelected)\n : (filter.datePickerConfig?.noDatePlaceholder ??\n filter.placeholder ??\n strings.calendar.notDateSelected);\n const withConfirm = Boolean(filter.datePickerConfig?.showConfirmButton);\n const closeOnSelect = filter.datePickerConfig?.autoApply ?? !withConfirm;\n const showShortcuts = filter.datePickerConfig?.showShortcuts ?? true;\n\n const rangeValue: DateRange | undefined =\n isRangeMode && (value.start || value.end)\n ? { from: value.start, to: value.end }\n : undefined;\n\n const singleValue =\n !isRangeMode && value.start && isValid(value.start)\n ? value.start\n : undefined;\n\n const commonProps = {\n format: dateFormat,\n readableFormat,\n placeholder,\n disablePortal: true,\n numberOfMonths: 1,\n className: cn('date-facet--component', 'w-full', className),\n };\n\n const handleSingleChange = (output: DateOutput) => {\n onChange({ start: output.date ?? undefined, end: undefined });\n };\n\n const handleRangeChange = (output: DateRangeOutput) => {\n onChange({\n start: output.range?.from ?? undefined,\n end: output.range?.to ?? undefined,\n });\n };\n\n if (isRangeMode) {\n const presetsProp = showShortcuts ? undefined : EMPTY_PRESETS;\n return (\n <DatePicker\n mode=\"range\"\n value={rangeValue}\n onChange={handleRangeChange}\n withConfirm={withConfirm}\n closeOnSelect={closeOnSelect}\n presets={presetsProp}\n {...commonProps}\n />\n );\n }\n\n return (\n <DatePicker\n mode=\"single\"\n value={singleValue}\n onChange={handleSingleChange}\n closeOnSelect={closeOnSelect}\n {...commonProps}\n />\n );\n}\n","import { format, parse, isValid } from 'date-fns';\nimport { ArrowLeft } from 'lucide-react';\nimport { Button } from '@/components/base/buttons';\nimport { DateFacet } from '../facets/date-facet';\nimport { Text } from '@/components/typography';\nimport { useFilters } from '../filter-context';\nimport type { FilterConfig } from '../filters.types';\n\ninterface DateFilterContentProps {\n filter: FilterConfig;\n value: string[];\n onFilterChange: (value: string[]) => void;\n onBackToFilterList: () => void;\n isFromMainFilterButton?: boolean;\n}\n\nexport function DateFilterContent({\n filter,\n value,\n onFilterChange,\n onBackToFilterList,\n isFromMainFilterButton = false,\n}: DateFilterContentProps) {\n const { strings } = useFilters();\n\n const parseInputDate = (input?: string) => {\n if (!input) {\n return undefined;\n }\n\n if (filter.dateFormat?.param) {\n const parsed = parse(input, filter.dateFormat.param, new Date());\n return isValid(parsed) ? parsed : undefined;\n }\n\n const parsed = new Date(input);\n return isValid(parsed) ? parsed : undefined;\n };\n\n const startDate = parseInputDate(value[0]);\n const endDate = parseInputDate(value[1]);\n\n // Default date format for filter params - matches backend expectations\n const defaultDateFormat = 'yyyy-MM-dd';\n\n const formatOutputDate = (date?: Date) => {\n if (!date || !isValid(date)) {\n return undefined;\n }\n\n return format(date, filter.dateFormat?.param ?? defaultDateFormat);\n };\n\n const handleDateChange = ({ start, end }: { start?: Date; end?: Date }) => {\n const next: string[] = [];\n const formattedStart = formatOutputDate(start);\n const formattedEnd = formatOutputDate(end);\n\n if (formattedStart) {\n next.push(formattedStart);\n }\n\n if (formattedEnd) {\n next.push(formattedEnd);\n }\n\n onFilterChange(next);\n };\n\n const showBackButton = Boolean(isFromMainFilterButton);\n\n const facetValue = { start: startDate, end: endDate };\n\n return (\n <div className=\"flex flex-col\">\n <div className=\"flex items-center gap-2 border-b border-border/60 px-3 py-2.5\">\n {!!showBackButton && (\n <Button\n type=\"button\"\n variant=\"secondary\"\n buttonStyle=\"ghost\"\n size=\"icon-xs\"\n onClick={onBackToFilterList}\n className=\"inline-flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground\"\n aria-label={strings.backToFilters}\n >\n <ArrowLeft className=\"size-3.5\" />\n </Button>\n )}\n <Text tag=\"span\" weight=\"semibold\" className=\"truncate\">\n {filter.label}\n </Text>\n </div>\n\n <div className=\"p-2\">\n <DateFacet\n filter={filter}\n value={facetValue}\n onChange={handleDateChange}\n />\n </div>\n </div>\n );\n}\n","import { X } from 'lucide-react';\nimport { Component, type ErrorInfo, type ReactNode, useMemo } from 'react';\nimport { Button } from '@/components/base/buttons';\nimport { Text } from '@/components/typography';\nimport { useFilters } from '../filter-context';\nimport { interpolateFilterString } from '../filters.strings';\n\ninterface Props {\n children: ReactNode;\n filterKey?: string;\n fallback?: ReactNode;\n}\n\ninterface State {\n hasError: boolean;\n error: Error | null;\n}\n\ninterface FilterErrorBoundaryLabels {\n title: string;\n reset: string;\n getDescription: (filterKey?: string) => string;\n unknownError: string;\n}\n\nclass FilterErrorBoundaryBase extends Component<\n Props & { labels: FilterErrorBoundaryLabels },\n State\n> {\n public state: State = {\n hasError: false,\n error: null,\n };\n\n /**\n * Update state when an error occurs\n */\n public static getDerivedStateFromError(error: Error): State {\n return { hasError: true, error };\n }\n\n /**\n * Log the error to the console and to an error tracking service if available\n */\n public componentDidCatch(error: Error, errorInfo: ErrorInfo) {\n if (import.meta.env?.DEV) {\n\t console.error('Filter error:', error, errorInfo);\n }\n\n // Report to error monitoring service if available\n // This is where you would integrate with services like Sentry\n if (typeof window !== 'undefined' && window.dispatchEvent) {\n window.dispatchEvent(\n new CustomEvent('filter-error', {\n detail: {\n filterKey: this.props.filterKey,\n error,\n errorInfo,\n },\n }),\n );\n }\n }\n\n /**\n * Reset the error state\n */\n private handleReset = () => {\n this.setState({ hasError: false, error: null });\n };\n\n public render() {\n if (this.state.hasError) {\n const { fallback, filterKey, labels } = this.props;\n if (fallback) {\n return fallback;\n }\n\n return (\n <div className=\"rounded-md border border-destructive/30 bg-destructive/10 p-3 text-xs text-destructive\">\n <div className=\"mb-1 flex items-center justify-between\">\n <Text tag=\"span\" weight=\"semibold\">\n {labels.title}\n </Text>\n <Button\n type=\"button\"\n variant=\"error\"\n buttonStyle=\"ghost\"\n size=\"icon-xs\"\n onClick={this.handleReset}\n className=\"size-6 rounded-full p-0\"\n aria-label={labels.reset}\n >\n <X className=\"h-4 w-4\" />\n </Button>\n </div>\n <Text size=\"xs\">{labels.getDescription(filterKey)}</Text>\n <Text size=\"xs\" type=\"error\" className=\"mt-1 font-mono\">\n {this.state.error?.message || labels.unknownError}\n </Text>\n </div>\n );\n }\n\n return this.props.children;\n }\n}\n\nexport function FilterErrorBoundary(props: Props) {\n const { strings } = useFilters();\n\n const labels = useMemo<FilterErrorBoundaryLabels>(\n () => ({\n title: strings.error.title,\n reset: strings.clear,\n getDescription: (filterKey?: string) =>\n filterKey\n ? interpolateFilterString(strings.error.descriptionWithKey, {\n filterKey,\n })\n : strings.error.generic,\n unknownError: strings.error.unknown,\n }),\n [strings],\n );\n\n return <FilterErrorBoundaryBase {...props} labels={labels} />;\n}\n","import { CommandItem } from '@/components/base/command';\nimport { Text } from '@/components/typography';\nimport { useFilters } from '../filter-context';\nimport { FilterType, type FilterConfig } from '../filters.types';\n\ninterface FilterListItemProps {\n filter: FilterConfig;\n onSelect: () => void;\n}\n\n/**\n * FilterListItem — single row inside the Filters-button menu.\n *\n * Shows a leading icon (rendered as-is so its native colour comes through),\n * the filter label as the primary line, and a secondary \"{n} options\" line\n * for SELECT-style filters or the \"select date range\" hint for DATE filters.\n *\n * All typography flows through the base Text component so the global\n * scale + theming applies consistently.\n */\nexport function FilterListItem({ filter, onSelect }: FilterListItemProps) {\n const { strings } = useFilters();\n\n const subtitle =\n filter.type === FilterType.DATE\n ? filter.operator === 'between'\n ? strings?.selectDateRange\n : strings?.selectDate\n : filter.options\n ? `${filter.options.length} ${strings?.options ?? ''}`.trim()\n : null;\n\n return (\n <CommandItem\n key={filter.key}\n onSelect={onSelect}\n className=\"flex items-center gap-3 rounded-none px-3 py-2\"\n >\n {!!filter.icon && (\n <span className=\"shrink-0 text-muted-foreground\">{filter.icon}</span>\n )}\n <div className=\"flex min-w-0 flex-col leading-tight\">\n <Text tag=\"span\" weight=\"semibold\" className=\"truncate\">\n {filter.label}\n </Text>\n {!!subtitle && (\n <Text tag=\"span\" size=\"xs\" type=\"secondary\" className=\"truncate\">\n {subtitle}\n </Text>\n )}\n </div>\n </CommandItem>\n );\n}\n","import {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandList,\n CommandSeparator,\n} from '@/components/base/command';\nimport { useFilters } from '../filter-context';\nimport type { FilterConfig } from '../filters.types';\nimport { FilterListItem } from './filter-list-item';\n\ninterface FilterListContentProps {\n availableFilters: FilterConfig[];\n activeFilters: FilterConfig[];\n onFilterSelect: (filter: FilterConfig) => void;\n}\n\n/**\n * Filter Popover Content Component\n *\n * This component provides the content wrapper for filter popovers.\n * It handles:\n * - Consistent popover styling\n * - Content layout and spacing\n * - Responsive behavior\n * - Animation and transitions\n *\n * The component is used to wrap filter content in a consistent\n * popover interface across different filter types.\n */\n\nexport function FilterListContent({\n availableFilters,\n activeFilters,\n onFilterSelect,\n}: FilterListContentProps) {\n const { strings } = useFilters();\n\n // Handle filter selection with explicit closing of popover\n const handleFilterSelect = (filter: FilterConfig) => {\n // Call the passed onFilterSelect with the filter\n onFilterSelect(filter);\n };\n\n // Group headings get the same px-3 horizontal as items so they all\n // align with the search input above.\n const groupHeadingClasses =\n '[&_[cmdk-group-heading]]:px-3 [&_[cmdk-group-heading]]:pb-1 [&_[cmdk-group-heading]]:pt-2 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:uppercase [&_[cmdk-group-heading]]:tracking-wider [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group-heading]]:font-medium';\n\n return (\n <Command className=\"rounded-none p-0\">\n <div className=\"border-b border-border/50 px-3 py-2\">\n <CommandInput className=\"text-xs\" placeholder={strings.searchFilters} />\n </div>\n <CommandList className=\"max-h-72 py-1\">\n <CommandEmpty className=\"px-3 py-4 text-center text-xs text-muted-foreground\">\n {strings.noFiltersAvailable}\n </CommandEmpty>\n\n {availableFilters.length > 0 && (\n <CommandGroup heading={strings.availableFilters} className={`p-0 ${groupHeadingClasses}`}>\n {availableFilters.map((filter) => (\n <FilterListItem\n key={filter.key}\n filter={filter}\n onSelect={() => handleFilterSelect(filter)}\n />\n ))}\n </CommandGroup>\n )}\n\n {activeFilters.length > 0 && (\n <>\n <CommandSeparator className=\"my-1\" />\n <CommandGroup heading={strings.activeFilters} className={`p-0 ${groupHeadingClasses}`}>\n {activeFilters.map((filter) => (\n <FilterListItem\n key={filter.key}\n filter={filter}\n onSelect={() => handleFilterSelect(filter)}\n />\n ))}\n </CommandGroup>\n </>\n )}\n </CommandList>\n </Command>\n );\n}\n","import { ArrowLeft } from 'lucide-react';\nimport { useState, useEffect } from 'react';\n\nimport { Button } from '@/components/base/buttons';\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from '@/components/base/command';\nimport { Text } from '@/components/typography';\n\nimport { useFilters } from '../filter-context';\nimport { interpolateFilterString } from '../filters.strings';\nimport { FilterType, type FilterConfig } from '../filters.types';\n\ninterface RegularFilterContentProps {\n filter: FilterConfig;\n value: string[];\n onFilterChange: (value: string[]) => void;\n onBackToFilterList: () => void;\n onClose: () => void;\n isFromMainFilterButton?: boolean;\n}\n\n/**\n * RegularFilterContent — popover body for SELECT / MULTI_SELECT filters.\n *\n * Layout:\n * - Compact header: optional back-arrow, label as small uppercase eyebrow.\n * - Inline search input (only if the filter has more than 5 options).\n * - Tight list of options (sm padding, xs font, ml-auto check on the right).\n * - Compact footer: selected count on the leading edge, Confirm button on\n * the trailing edge — only rendered when the user has changed selection.\n *\n * Sizes are tuned to feel like a native menu, not a card. Popover width\n * stays at ~260-300px so labels read at one glance.\n */\nexport function RegularFilterContent({\n filter,\n value,\n onFilterChange,\n onBackToFilterList,\n onClose,\n isFromMainFilterButton = false,\n}: RegularFilterContentProps) {\n const { strings } = useFilters();\n\n const isMultiSelect =\n filter.multiple === true || filter.type === FilterType.MULTI_SELECT;\n const showBackButton = Boolean(isFromMainFilterButton);\n\n const [tempValue, setTempValue] = useState<string[]>(value || []);\n\n useEffect(() => {\n setTempValue(value || []);\n }, [value]);\n\n const handleValueSelect = (optionValue: string) => {\n if (isMultiSelect) {\n const newValue = tempValue.includes(optionValue)\n ? tempValue.filter((v) => v !== optionValue)\n : [...tempValue, optionValue];\n setTempValue(newValue);\n } else {\n setTempValue([optionValue]);\n\n if (filter.closeOnSelect === true) {\n onFilterChange([optionValue]);\n onClose();\n }\n }\n };\n\n const handleDone = () => {\n try {\n onFilterChange(tempValue);\n onClose();\n } catch (error) {\n if (import.meta.env?.DEV) {\n\t console.error('Error applying filter:', error);\n }\n }\n };\n\n const isDirty = JSON.stringify(tempValue.slice().sort()) !== JSON.stringify((value ?? []).slice().sort());\n\n return (\n <div className=\"flex flex-col\">\n {/* SECTION 1 — Label header */}\n <div className=\"flex items-center gap-2 border-b border-border/60 px-3 py-2.5\">\n {!!showBackButton && (\n <Button\n type=\"button\"\n variant=\"secondary\"\n buttonStyle=\"ghost\"\n size=\"icon-xs\"\n onClick={onBackToFilterList}\n className=\"inline-flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground\"\n aria-label={strings.backToFilters}\n >\n <ArrowLeft className=\"size-3.5\" />\n </Button>\n )}\n <Text tag=\"span\" size=\"xs\" weight=\"semibold\" className=\"truncate\">\n {filter.label}\n </Text>\n </div>\n\n <Command className=\"rounded-none p-0\">\n {/* SECTION 2 — Search.\n Same px-3 py-2.5 as the label section. */}\n <div className=\"border-b border-border/50 px-3 py-2.5\">\n <CommandInput\n className=\"text-xs\"\n placeholder={interpolateFilterString(\n strings.searchPlaceholder,\n { filterLabel: filter.label.toLowerCase() },\n )}\n />\n </div>\n\n {/* SECTION 3 — Values list.\n Same px-3 py-2.5 outer padding as the other two sections.\n Items inside have ADDITIONAL inner padding (px-2) so option\n labels are slightly more indented than the section frame —\n that's what tells the eye \"these are list rows, not header\n text\". Total label inset: 12px (section) + 8px (item) = 20px. */}\n <CommandList className=\"max-h-64 px-3 py-2\">\n <CommandEmpty>\n <Text size=\"xs\" type=\"secondary\" align=\"center\" className=\"py-4\">\n {strings.noOptionsFound}\n </Text>\n </CommandEmpty>\n <CommandGroup className=\"p-0 [&_[cmdk-group]]:p-0\">\n {filter.options?.map((option) => {\n const isSelected = tempValue.includes(option.value);\n // data-checked toggles the CommandItem's built-in\n // CheckIcon (rendered after children with ml-auto).\n return (\n <CommandItem\n key={option.value}\n onSelect={() => handleValueSelect(option.value)}\n data-checked={isSelected || undefined}\n disabled={option.disabled}\n className=\"flex items-start gap-2.5 rounded-md px-2 py-2 data-[checked=true]:**:[svg]:text-primary\"\n >\n {!!option.icon && (\n <span className=\"mt-0.5 shrink-0 text-muted-foreground\">\n {option.icon}\n </span>\n )}\n <div className=\"flex min-w-0 flex-1 flex-col leading-tight\">\n <Text\n tag=\"span\"\n size=\"xs\"\n weight={isSelected ? 'medium' : 'regular'}\n className=\"truncate\"\n >\n {option.label}\n </Text>\n {!!option.description && (\n <Text\n tag=\"span\"\n size=\"xxs\"\n type=\"secondary\"\n className=\"truncate mt-0.5\"\n >\n {option.description}\n </Text>\n )}\n </div>\n </CommandItem>\n );\n })}\n </CommandGroup>\n </CommandList>\n </Command>\n\n {/* Compact footer — only shows when dirty */}\n {!!isDirty && (\n <div className=\"flex items-center justify-between gap-2 border-t border-border/60 px-2.5 py-1.5\">\n <Text tag=\"span\" size=\"xxs\" type=\"secondary\" className=\"tabular-nums\">\n {interpolateFilterString(strings.selected, {\n count: tempValue.length,\n filterLabel: (tempValue.length > 1 ? filter.pluralLabel : filter.label) ?? filter.label,\n })}\n </Text>\n <Button variant=\"primary\" size=\"xs\" onClick={handleDone}>\n {strings.confirm}\n </Button>\n </div>\n )}\n </div>\n );\n}\n","import { X, Plus } from 'lucide-react';\nimport React, { useState, useCallback, type KeyboardEvent } from 'react';\nimport { Badge } from '@/components/base/badge';\nimport { Button } from '@/components/base/buttons';\nimport { Input } from '@/components/base/forms';\nimport { Text } from '@/components/typography';\nimport { cn } from '@/lib/utils';\nimport { useFilters } from '../filter-context';\nimport { FILTER_ELEMENT_HEIGHT, type FilterConfig } from '../filters.types';\n\ninterface TagsFacetProps {\n filter: FilterConfig;\n value: string[];\n onChange: (value: string[]) => void;\n className?: string;\n}\n\n/**\n * Tags Filter Facet\n *\n * This component implements a tags input filter that allows users to:\n * - Enter tags through an input field\n * - Add tags by pressing Enter or clicking the add button\n * - View all selected tags as removable badges\n * - Remove individual tags by clicking the X on each badge\n *\n * The component is ideal for filtering by multiple tags or keywords\n * where users need to see all selected values at once.\n */\n\nfunction TagsFacetComponent({\n filter,\n value,\n onChange,\n className,\n}: TagsFacetProps) {\n const { strings } = useFilters();\n const [inputValue, setInputValue] = useState('');\n // Handle adding a new tag\n const handleAddTag = useCallback(() => {\n const trimmedValue = inputValue.trim();\n\n // Don't add empty tags or duplicates\n if (!trimmedValue || value.includes(trimmedValue)) {\n return;\n }\n\n onChange([...value, trimmedValue]);\n setInputValue('');\n }, [inputValue, value, onChange]);\n\n // Handle removing a tag\n const handleRemoveTag = useCallback(\n (tagToRemove: string) => {\n onChange(value.filter((tag) => tag !== tagToRemove));\n },\n [value, onChange],\n );\n\n // Handle keyboard events\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n handleAddTag();\n }\n };\n\n // Clear all tags\n const handleClearAll = useCallback(() => {\n onChange([]);\n setInputValue('');\n }, [onChange]);\n\n const hasTags = value.length > 0;\n const tagCountLabel =\n value.length === 1 ? strings.tag : strings.tags;\n const tagSummary = hasTags ? (\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <Text tag=\"span\" size=\"xs\" type=\"secondary\">\n {value.length} {tagCountLabel}\n </Text>\n <Button\n onClick={handleClearAll}\n variant=\"secondary\"\n buttonStyle=\"ghost\"\n size=\"xs\"\n className=\"h-auto px-1 py-0 text-xs text-muted-foreground hover:text-foreground\"\n type=\"button\"\n aria-label={strings.clearAll}\n >\n {strings.clearAll}\n </Button>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n {value.map((tag) => (\n <Badge\n key={tag}\n variant=\"secondary\"\n className=\"flex items-center gap-1 py-1 pl-2 pr-1\"\n >\n <Text tag=\"span\" size=\"xs\">{tag}</Text>\n <Button\n onClick={() => handleRemoveTag(tag)}\n variant=\"secondary\"\n buttonStyle=\"ghost\"\n size=\"icon-xs\"\n className=\"ml-1 size-4 rounded-full p-0 hover:bg-muted-foreground/20\"\n type=\"button\"\n aria-label={`${strings.removeTag} ${tag}`}\n >\n <X className=\"h-3 w-3\" />\n </Button>\n </Badge>\n ))}\n </div>\n </div>\n ) : null;\n\n return (\n <div className={cn('tags-facet--component', 'space-y-3', className)}>\n {/* Input section */}\n <div className=\"flex gap-2\">\n <div className=\"relative flex-1\">\n <Input\n type=\"text\"\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={\n filter.placeholder ?? strings.enterTag\n }\n className={FILTER_ELEMENT_HEIGHT}\n />\n </div>\n <Button\n onClick={handleAddTag}\n disabled={!inputValue.trim()}\n size=\"default\"\n className={`${FILTER_ELEMENT_HEIGHT} px-4`}\n type=\"button\"\n >\n <Plus className=\"h-4 w-4\" />\n <span className=\"sr-only\">{strings.addTag}</span>\n </Button>\n </div>\n\n {/* Tags display section */}\n {tagSummary}\n </div>\n );\n}\n\nexport const TagsFacet = React.memo(TagsFacetComponent);\nTagsFacet.displayName = 'TagsFacet';\n","import { ArrowLeft } from 'lucide-react';\nimport { useState, useEffect } from 'react';\nimport { Button } from '@/components/base/buttons';\nimport { TagsFacet } from '../facets/tags-facet';\nimport { Text } from '@/components/typography';\nimport { useFilters } from '../filter-context';\nimport type { FilterConfig } from '../filters.types';\n\ninterface TagsFilterContentProps {\n filter: FilterConfig;\n value: string[];\n onFilterChange: (value: string[]) => void;\n onBackToFilterList: () => void;\n onClose: () => void;\n isFromMainFilterButton?: boolean;\n}\n\n/**\n * Tags Filter Content Component\n *\n * This component provides the content for tags filter popovers.\n * It handles:\n * - Tag input and management\n * - Multiple tag selection\n * - Displaying and removing tags\n * - Applying filter changes\n *\n * The component wraps the TagsFacet component and provides\n * the popover-specific UI elements like header and action buttons.\n */\n\nexport function TagsFilterContent({\n filter,\n value,\n onFilterChange,\n onBackToFilterList,\n onClose,\n isFromMainFilterButton = false,\n}: TagsFilterContentProps) {\n const { strings } = useFilters();\n\n // Use local state to track temporary values before committing\n const [tempValue, setTempValue] = useState<string[]>(value || []);\n const showBackButton = Boolean(isFromMainFilterButton);\n const tagCountLabel =\n tempValue.length === 1 ? strings.tag : strings.tags;\n\n // Update tempValue when value changes (for initial or external updates)\n useEffect(() => {\n setTempValue(value || []);\n }, [value]);\n\n // Apply changes when Done is clicked\n const handleDone = () => {\n try {\n onFilterChange(tempValue);\n onClose();\n } catch (error) {\n if (import.meta.env?.DEV) {\n\t console.error('Error applying filter:', error);\n }\n }\n };\n\n const isDirty = JSON.stringify(tempValue.slice().sort()) !== JSON.stringify((value ?? []).slice().sort());\n\n return (\n <div className=\"flex flex-col\">\n <div className=\"flex items-center gap-2 border-b border-border/60 px-3 py-2.5\">\n {!!showBackButton && (\n <Button\n type=\"button\"\n variant=\"secondary\"\n buttonStyle=\"ghost\"\n size=\"icon-xs\"\n onClick={onBackToFilterList}\n className=\"inline-flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground\"\n aria-label={strings.backToFilters}\n >\n <ArrowLeft className=\"size-3.5\" />\n </Button>\n )}\n <Text tag=\"span\" weight=\"semibold\" className=\"truncate\">\n {filter.label}\n </Text>\n </div>\n\n <div className=\"p-2\">\n <TagsFacet\n filter={filter}\n value={tempValue}\n onChange={setTempValue}\n />\n </div>\n\n {!!isDirty && (\n <div className=\"flex items-center justify-between gap-2 border-t border-border/60 px-2.5 py-1.5\">\n <Text tag=\"span\" size=\"xxs\" type=\"secondary\" className=\"tabular-nums\">\n {tempValue.length} {tagCountLabel}\n </Text>\n <Button variant=\"primary\" size=\"xs\" onClick={handleDone}>\n {strings.confirm}\n </Button>\n </div>\n )}\n </div>\n );\n}\n","import { PopoverContent } from '@/components/base/popover';\nimport { FilterType, type FilterConfig } from '../filters.types';\nimport { AsyncFilterContent } from './async-filter-content';\nimport { DateFilterContent } from './date-filter-content';\nimport { FilterListContent } from './filter-list-content';\nimport { RegularFilterContent } from './regular-filter-content';\nimport { TagsFilterContent } from './tags-filter-content';\n\ninterface FilterPopoverContentProps {\n activeFilterInPopover: FilterConfig | null;\n availableFilters: FilterConfig[];\n activeFilters: FilterConfig[];\n getFilterValue: (key: string) => string[];\n setFilterValue: (key: string, value: string[]) => void;\n onFilterSelect: (filter: FilterConfig) => void;\n onBackToFilterList: () => void;\n onClose: () => void;\n isFromMainFilterButton?: boolean; // Determines back button behavior\n}\n\n/**\n * Filter Popover Content Component\n *\n * This component provides the content wrapper for filter popovers.\n * It handles:\n * - Consistent popover styling\n * - Content layout and spacing\n * - Responsive behavior\n * - Animation and transitions\n *\n * The component is used to wrap filter content in a consistent\n * popover interface across different filter types.\n */\n\nexport function FilterPopoverContent({\n activeFilterInPopover,\n availableFilters,\n activeFilters,\n getFilterValue,\n setFilterValue,\n onFilterSelect,\n onBackToFilterList,\n onClose,\n isFromMainFilterButton = false,\n}: FilterPopoverContentProps) {\n const popoverWidth =\n activeFilterInPopover?.type === FilterType.DATE ||\n activeFilterInPopover?.type === FilterType.TAGS\n ? 'w-auto min-w-[320px] p-0 overflow-hidden rounded-lg shadow-lg'\n : activeFilterInPopover?.type === FilterType.ASYNC_SELECT\n ? 'w-72 p-0 overflow-hidden rounded-lg shadow-lg'\n : 'w-64 p-0 overflow-hidden rounded-lg shadow-lg';\n\n // Forward values directly so upstream can decide whether to add or clear the filter\n const handleSetFilterValue = (key: string, value: string[]) => {\n setFilterValue(key, value);\n };\n\n return (\n <PopoverContent className={popoverWidth} align=\"start\">\n {activeFilterInPopover ? (\n // Render specific filter content based on type\n activeFilterInPopover.type === FilterType.DATE ? (\n <DateFilterContent\n filter={activeFilterInPopover}\n value={getFilterValue(activeFilterInPopover.key)}\n onFilterChange={(value) =>\n handleSetFilterValue(\n activeFilterInPopover.key,\n value,\n )\n }\n onBackToFilterList={onBackToFilterList}\n isFromMainFilterButton={isFromMainFilterButton}\n />\n ) : activeFilterInPopover.type === FilterType.TAGS ? (\n <TagsFilterContent\n filter={activeFilterInPopover}\n value={getFilterValue(activeFilterInPopover.key)}\n onFilterChange={(value) =>\n handleSetFilterValue(\n activeFilterInPopover.key,\n value,\n )\n }\n onBackToFilterList={onBackToFilterList}\n onClose={onClose}\n isFromMainFilterButton={isFromMainFilterButton}\n />\n ) : activeFilterInPopover.type === FilterType.ASYNC_SELECT ? (\n <AsyncFilterContent\n filter={activeFilterInPopover}\n value={getFilterValue(activeFilterInPopover.key)}\n onFilterChange={(value) =>\n handleSetFilterValue(\n activeFilterInPopover.key,\n value,\n )\n }\n onBackToFilterList={onBackToFilterList}\n onClose={onClose}\n isFromMainFilterButton={isFromMainFilterButton}\n />\n ) : (\n <RegularFilterContent\n filter={activeFilterInPopover}\n value={getFilterValue(activeFilterInPopover.key)}\n onFilterChange={(value) =>\n handleSetFilterValue(\n activeFilterInPopover.key,\n value,\n )\n }\n onBackToFilterList={onBackToFilterList}\n onClose={onClose}\n isFromMainFilterButton={isFromMainFilterButton}\n />\n )\n ) : (\n // Render the list of available filters\n <FilterListContent\n availableFilters={availableFilters}\n activeFilters={activeFilters}\n onFilterSelect={onFilterSelect}\n />\n )}\n </PopoverContent>\n );\n}\n","/**\n * FilterPill — internal partial that wraps a single `ActiveFilterItem` with\n * its popover. Used by `FilterLayout` for both `display: 'always'` filters\n * and `active` regular filters since the rendering is identical except for\n * the `availableFilters` / `activeFilters` lists passed to the popover.\n *\n * Exported from `partials/index.ts` so consumers building a custom strip\n * around `<FilterProvider>` can re-use it without duplicating the popover\n * machinery.\n */\nimport { useRef, useState } from 'react';\n\nimport { Popover, PopoverTrigger } from '@/components/base/popover';\n\nimport type {\n FilterConfig,\n FilterOperator,\n OperatorOption,\n} from '../filters.types';\n\nimport { ActiveFilterItem } from './active-filter-item';\nimport { FilterErrorBoundary } from './filter-error-boundary';\nimport { FilterPopoverContent } from './filter-popover-content';\n\nexport interface FilterPillProps {\n filter: FilterConfig;\n value: string[];\n isActive: boolean;\n operator: FilterOperator;\n operators: OperatorOption[];\n onOperatorChange: (operator: FilterOperator) => void;\n onValueChange: (value: string[]) => void;\n onClear: () => void;\n /** Filters to render in the \"+\" list inside the popover. */\n availableFilters: FilterConfig[];\n /** Active regular filters list (for the popover header / context). */\n activeFilters: FilterConfig[];\n /** External signal to suppress popover open during operator change. */\n operatorChangeRef?: React.MutableRefObject<boolean>;\n}\n\nexport function FilterPill({\n filter,\n value,\n isActive,\n operator,\n operators,\n onOperatorChange,\n onValueChange,\n onClear,\n availableFilters,\n activeFilters,\n operatorChangeRef,\n}: FilterPillProps) {\n const localRef = useRef(false);\n const isOperatorChangeRef = operatorChangeRef ?? localRef;\n\n const [open, setOpen] = useState(false);\n\n return (\n <FilterErrorBoundary filterKey={filter.key}>\n <Popover\n open={open}\n onOpenChange={(isOpen) => {\n if (isOpen && isOperatorChangeRef.current) return;\n setOpen(isOpen);\n }}\n >\n <PopoverTrigger\n nativeButton={false}\n render={\n <div>\n <ActiveFilterItem\n filter={filter}\n value={value}\n isActive={isActive}\n operators={operators}\n operator={operator}\n onOperatorChange={(next) => {\n isOperatorChangeRef.current = true;\n onOperatorChange(next);\n setOpen(false);\n setTimeout(() => {\n isOperatorChangeRef.current = false;\n }, 100);\n }}\n onFilterClear={() => {\n setOpen(false);\n onClear();\n }}\n onFilterClick={() => {\n if (!isOperatorChangeRef.current) {\n setOpen(true);\n }\n }}\n />\n </div>\n }\n />\n\n <FilterPopoverContent\n activeFilterInPopover={filter}\n availableFilters={availableFilters}\n activeFilters={activeFilters}\n getFilterValue={() => value}\n setFilterValue={(_, next) => onValueChange(next)}\n onFilterSelect={() => {}}\n onBackToFilterList={() => {}}\n onClose={() => setOpen(false)}\n isFromMainFilterButton={false}\n />\n </Popover>\n </FilterErrorBoundary>\n );\n}\n\nFilterPill.displayName = 'FilterPill';\n","import { Filter } from 'lucide-react';\nimport { useState, useEffect } from 'react';\nimport { Button } from '@/components/base/buttons';\nimport {\n Popover,\n PopoverTrigger,\n} from '@/components/base/popover';\nimport { FILTER_ELEMENT_HEIGHT, type FilterConfig } from '../filters.types';\nimport { useFilters } from '../filter-context';\nimport { FilterPopoverContent } from './filter-popover-content';\n\ninterface FiltersButtonProps {\n availableFilters: FilterConfig[];\n activeFilters: FilterConfig[];\n activeFilterInPopover: FilterConfig | null;\n getFilterValue: (key: string) => string[];\n setFilterValue: (key: string, value: string[]) => void;\n setActiveFilterInPopover: (filter: FilterConfig | null) => void;\n locale?: string;\n}\n\n/**\n * Filters Button Component\n *\n * This component provides the main button for adding and managing filters.\n * It handles:\n * - Opening the filter popover\n * - Managing filter selection state\n * - Handling filter actions (select, back, close)\n * - Supporting internationalization\n *\n * The component is used as the primary entry point for users to\n * add and configure filters in the application.\n */\n\nexport function FiltersButton({\n availableFilters,\n activeFilters,\n activeFilterInPopover,\n getFilterValue,\n setFilterValue,\n setActiveFilterInPopover,\n}: FiltersButtonProps) {\n // Control popover state explicitly\n const [isOpen, setIsOpen] = useState(false);\n const { strings } = useFilters();\n\n // Handle filter selection - keep popover open\n const handleFilterSelect = (filter: FilterConfig) => {\n // Set the selected filter without closing the popover\n setActiveFilterInPopover(filter);\n };\n\n // Handle back to filter list action\n const handleBackToFilterList = () => {\n setActiveFilterInPopover(null);\n };\n\n // Handle complete close action - reset everything\n const handleClose = () => {\n setActiveFilterInPopover(null);\n setIsOpen(false);\n };\n\n // Reset active filter when popover closes\n useEffect(() => {\n if (!isOpen) {\n // Reset to filters view when popover is closed\n setActiveFilterInPopover(null);\n }\n }, [isOpen, setActiveFilterInPopover]);\n\n return (\n <Popover open={isOpen} onOpenChange={setIsOpen}>\n <PopoverTrigger\n render={\n <Button\n variant=\"secondary\" buttonStyle=\"outline\"\n size=\"default\"\n aria-label={strings.addFilter}\n className={`flex ${FILTER_ELEMENT_HEIGHT} items-center gap-1.5`}\n >\n <Filter className=\"h-4 w-4\" />\n </Button>\n }\n />\n <FilterPopoverContent\n activeFilterInPopover={activeFilterInPopover}\n availableFilters={availableFilters}\n activeFilters={activeFilters}\n getFilterValue={getFilterValue}\n setFilterValue={setFilterValue}\n onFilterSelect={handleFilterSelect}\n onBackToFilterList={handleBackToFilterList}\n onClose={handleClose}\n isFromMainFilterButton={true}\n />\n </Popover>\n );\n}\n","import { useMemo, useCallback } from 'react';\nimport { Button } from '@/components/base/buttons';\nimport { cn } from '@/lib/utils';\nimport { useFilters } from '../filter-context';\nimport { FilterType, type ActiveFilter, type FilterTab } from '../filters.types';\nimport { getDefaultOperatorForType } from '../operator-options';\n\ninterface FilterTabsProps {\n tabs: FilterTab[];\n}\n\n/**\n * Horizontal tab row for filter presets (Shopify admin style).\n *\n * - \"All\" tab (empty presets): active when zero non-search active filters\n * - Named tabs: active when presets exactly match non-search active filters\n * - Search filters are preserved across tab switches\n */\nexport function FilterTabs({ tabs }: FilterTabsProps) {\n const { activeFilters, filters, replaceFilters } = useFilters();\n\n const nonSearchFilters = useMemo(\n () => activeFilters.filter((f) => {\n const config = filters.find((fc) => fc.key === f.key);\n return config?.type !== FilterType.SEARCH;\n }),\n [activeFilters, filters],\n );\n\n const searchFilters = useMemo(\n () => activeFilters.filter((f) => {\n const config = filters.find((fc) => fc.key === f.key);\n return config?.type === FilterType.SEARCH;\n }),\n [activeFilters, filters],\n );\n\n const activeTabId = useMemo(() => {\n for (const tab of tabs) {\n // \"All\" tab: no presets → active when zero non-search filters\n if (tab.presets.length === 0) {\n if (nonSearchFilters.length === 0) return tab.id;\n continue;\n }\n\n // Named tab: bidirectional exact match\n if (tab.presets.length !== nonSearchFilters.length) continue;\n\n const allMatch = tab.presets.every((preset) => {\n const active = nonSearchFilters.find((f) => f.key === preset.key);\n if (!active) return false;\n\n const sortedPreset = [...preset.value].sort();\n const sortedActive = [...active.value].sort();\n if (sortedPreset.length !== sortedActive.length) return false;\n if (sortedPreset.some((v, i) => v !== sortedActive[i])) return false;\n\n // Check operator if specified in preset\n if (preset.operator && active.operator !== preset.operator) return false;\n\n return true;\n });\n\n if (allMatch) return tab.id;\n }\n\n return null;\n }, [tabs, nonSearchFilters]);\n\n const handleTabClick = useCallback(\n (tab: FilterTab) => {\n if (tab.presets.length === 0) {\n // \"All\" tab — keep only search filters\n replaceFilters([...searchFilters]);\n return;\n }\n\n const presetFilters: ActiveFilter[] = tab.presets.map((preset) => {\n const filterConfig = filters.find((fc) => fc.key === preset.key);\n const operator =\n preset.operator ??\n filterConfig?.operator ??\n (filterConfig\n ? getDefaultOperatorForType(filterConfig.type)\n : 'equals');\n\n return {\n id: preset.key,\n key: preset.key,\n value: preset.value,\n operator,\n };\n });\n\n replaceFilters([...searchFilters, ...presetFilters]);\n },\n [filters, searchFilters, replaceFilters],\n );\n\n if (tabs.length === 0) return null;\n\n return (\n <div className=\"flex flex-wrap gap-1.5\" role=\"tablist\">\n {tabs.map((tab) => {\n const isActive = activeTabId === tab.id;\n\n return (\n <Button\n key={tab.id}\n type=\"button\"\n variant=\"secondary\"\n buttonStyle=\"ghost\"\n size=\"xs\"\n role=\"tab\"\n aria-selected={isActive}\n onClick={() => handleTabClick(tab)}\n className={cn(\n 'rounded-md px-2.5 py-1 text-xs font-semibold transition-colors',\n isActive\n ? 'bg-foreground text-background'\n : 'bg-muted/60 text-muted-foreground hover:bg-muted hover:text-foreground',\n )}\n >\n {tab.label}\n {tab.count !== undefined && (\n <span\n className={cn(\n 'ml-1 tabular-nums',\n isActive\n ? 'text-background/70'\n : 'text-muted-foreground/70',\n )}\n >\n {tab.count}\n </span>\n )}\n </Button>\n );\n })}\n </div>\n );\n}\n","import { Loader2, X } from 'lucide-react';\nimport React, {\n type ChangeEvent,\n useState,\n useEffect,\n useRef,\n useCallback,\n} from 'react';\nimport { Input } from '@/components/base/forms/fields/input';\nimport { Button } from '@/components/base/buttons';\nimport { cn } from '@/lib/utils';\nimport { useFilters } from '../filter-context';\nimport { interpolateFilterString } from '../filters.strings';\nimport type { FilterConfig } from '../filters.types';\n\ninterface SearchFacetProps {\n filter: FilterConfig;\n value: string[];\n onChange: (value: string[]) => void;\n className?: string;\n}\n\n/**\n * Search Filter Facet\n *\n * This component implements a text search filter that allows users to:\n * - Enter search terms\n * - Configure search behavior (contains, equals, etc.)\n * - Set debounce delay for performance\n * - Customize placeholder text and appearance\n *\n * The component integrates with the filter context to manage the search value\n * and provides a responsive search input interface.\n */\n\nfunction SearchFacetComponent({\n filter,\n value,\n onChange,\n className,\n}: SearchFacetProps) {\n const { strings, isNavigating } = useFilters();\n\n // Use local state for the input value - initialized from value prop\n const [inputValue, setInputValue] = useState(value[0] || '');\n // Ref mirror of inputValue so the sync effect can read it without depending on it\n const inputValueRef = useRef(inputValue);\n inputValueRef.current = inputValue;\n // Track if the component is mounted to avoid unwanted effects\n const mounted = useRef(false);\n // Keep track of timeout ID for cleanup\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n // Tracking the last value we emitted to prevent duplicate emissions\n const lastEmittedValue = useRef<string | null>(value[0] || null);\n // Track if we're currently handling user input to prevent interference\n const isUserTypingRef = useRef(false);\n\n // Set mounted flag on initial render\n useEffect(() => {\n mounted.current = true;\n return () => {\n mounted.current = false;\n // Clear any pending timeout on unmount\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n };\n }, []);\n\n // Update input value when props change (for URL sync/refresh)\n // Guarded by isNavigating to prevent stale prop overwrites during the\n // gap between debounce-fire and Inertia response arriving.\n useEffect(() => {\n // Skip if user is actively typing or navigation is in-flight\n if (isUserTypingRef.current || isNavigating) {\n return;\n }\n\n const currentInput = inputValueRef.current;\n\n // Handle empty value array - this happens when filters are cleared\n if (!value.length || value[0] === '') {\n if (currentInput !== '') {\n setInputValue('');\n lastEmittedValue.current = '';\n }\n return;\n }\n\n // Only update if the value is different from what we have\n // and different from what we last emitted\n if (\n value[0] !== undefined &&\n value[0] !== currentInput &&\n value[0] !== lastEmittedValue.current\n ) {\n setInputValue(value[0]);\n lastEmittedValue.current = value[0];\n }\n }, [value, isNavigating]);\n\n // Debounced update function that consistently handles ALL input changes\n const debouncedUpdate = useCallback(\n (newValue: string) => {\n // Don't emit the same value twice\n if (lastEmittedValue.current === newValue) {\n return;\n }\n\n // Clear previous timeout\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n\n // Set new timeout for debouncing\n timeoutRef.current = setTimeout(() => {\n if (mounted.current) {\n lastEmittedValue.current = newValue;\n isUserTypingRef.current = false;\n onChange([newValue]);\n }\n }, filter.delay ?? 500);\n },\n [onChange, filter.delay],\n );\n\n // Handle input change - works for both typing and deleting characters\n const handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {\n isUserTypingRef.current = true;\n const newValue = e.target.value;\n setInputValue(newValue);\n debouncedUpdate(newValue);\n };\n\n // Handle focusing the input\n const handleFocus = () => {\n isUserTypingRef.current = true;\n };\n\n // Handle blurring the input\n const handleBlur = () => {\n // Set a small delay before clearing the typing flag\n // This prevents immediate sync which could cause issues\n setTimeout(() => {\n isUserTypingRef.current = false;\n }, 100);\n };\n\n // Handle clear button click\n const handleClear = () => {\n isUserTypingRef.current = true;\n setInputValue('');\n debouncedUpdate('');\n };\n\n return (\n <div className={cn('search-facet--component', 'search-facet relative w-full min-w-0 bg-background sm:min-w-80', className)}>\n <Input\n type=\"text\"\n value={inputValue}\n onChange={handleInputChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n placeholder={\n filter.placeholder ??\n (() => {\n const label = filter.label.trim().toLowerCase();\n if (!label || label === 'search') {\n // Collapse \"Search …\" stray space when the\n // filter label would otherwise duplicate the\n // template's leading \"Search\" word.\n return interpolateFilterString(\n strings.searchPlaceholder,\n { filterLabel: '' },\n )\n .replace(/\\s+([….?!])/g, '$1')\n .replace(/\\s{2,}/g, ' ')\n .trim();\n }\n return interpolateFilterString(\n strings.searchPlaceholder,\n { filterLabel: label },\n );\n })()\n }\n className=\"w-full pr-9\"\n\t\t\t/>\n {inputValue.trim() !== '' && !isNavigating && (\n <Button\n type=\"button\"\n\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\tbuttonStyle=\"ghost\"\n size=\"icon-sm\"\n\t\t\t\t\tonClick={handleClear}\n className=\"absolute right-1 top-1/2 size-7 -translate-y-1/2\"\n\t\t\t\t\taria-label={strings.clearSearch}\n\t\t\t\t>\n <X className=\"h-3.5 w-3.5\" />\n </Button>\n )}\n {!!isNavigating && (\n <span className=\"text-muted-foreground absolute right-2 top-1/2 -translate-y-1/2\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n </span>\n )}\n </div>\n );\n}\n\nexport const SearchFacet = React.memo(SearchFacetComponent);\nSearchFacet.displayName = 'SearchFacet';\n","import { Text } from '@/components/typography';\nimport { cn } from '@/lib/utils';\nimport { SearchFacet } from '../facets/search-facet';\nimport type { FilterConfig } from '../filters.types';\n\ninterface SearchFiltersListProps {\n filters: FilterConfig[];\n getFilterValue: (key: string) => string[];\n setFilterValue: (key: string, value: string[]) => void;\n className?: string;\n}\n\n/**\n * Search Filters List Component\n *\n * This component provides a list of search filters that are always visible.\n * It handles:\n * - Rendering multiple search filters\n * - Managing filter values\n * - Applying custom styling\n * - Supporting responsive layout\n *\n * The component is used to display search filters that should be\n * immediately accessible to users without requiring a popover.\n */\n\nexport function SearchFiltersList({\n filters,\n getFilterValue,\n setFilterValue,\n className,\n}: SearchFiltersListProps) {\n return (\n <>\n {filters.map((filter) => (\n <div\n key={filter.key}\n className={cn(\n 'space-y-2',\n filter.displayConfig.className,\n className,\n )}\n >\n <SearchFacet\n filter={filter}\n value={getFilterValue(filter.key)}\n onChange={(newValue) =>\n setFilterValue(filter.key, newValue)\n }\n />\n {!!filter.description && (\n <Text size=\"xs\" type=\"secondary\">\n {filter.description}\n </Text>\n )}\n </div>\n ))}\n </>\n );\n}\n","/**\n * FilterLayout — default strip layout: search inputs inline, then either\n * \"always-visible\" or active filter pills, then the \"+\" button for the\n * remaining inactive filters.\n *\n * The heavy lifting now lives in two reusable pieces:\n * - `useFilterGroups()` (hook) — partitions filters into search /\n * always-visible / active / popover groups so consumers building a\n * custom strip can call this and place each group themselves.\n * - `<FilterPill>` (partial) — wraps `<ActiveFilterItem>` + popover so\n * the duplicated rendering between always-visible and active filters\n * collapses to a single component.\n */\nimport { useState } from 'react';\n\nimport { Button } from '@/components/base/buttons';\nimport { cn } from '@/lib/utils';\n\nimport { useFilters } from './filter-context';\nimport { interpolateFilterString } from './filters.strings';\nimport {\n type FilterConfig,\n type FilterTab,\n type FilterOperator,\n} from './filters.types';\nimport { useFilterGroups } from './hooks/use-filter-groups';\nimport { getOperatorsForType } from './operator-options';\n\nimport {\n FilterErrorBoundary,\n FiltersButton,\n FilterPill,\n FilterTabs,\n SearchFiltersList,\n} from './partials';\n\ninterface FilterLayoutProps {\n className?: string;\n /** Per-key dynamic options that override the provider's filter.options. */\n dynamicFilterOptions?: Record<string, FilterConfig['options']>;\n /** Per-key loading states; renders a small spinning chip. */\n loadingFilters?: Record<string, boolean>;\n variant?: 'default' | 'compact';\n showClearFilters?: boolean;\n tabs?: FilterTab[];\n}\n\nexport function FilterLayout({\n className,\n dynamicFilterOptions = {},\n loadingFilters = {},\n variant = 'default',\n showClearFilters = false,\n tabs,\n}: FilterLayoutProps) {\n const {\n getFilterValue,\n setFilterValue,\n isFilterActive,\n clearFilters,\n getFilterOperator,\n setFilterOperator,\n isNavigating,\n strings,\n } = useFilters();\n\n const groups = useFilterGroups({ dynamicFilterOptions });\n const {\n processedFilters,\n searchFilters,\n alwaysVisibleFilters,\n activeRegularFilters,\n popoverFilters,\n hasActive,\n } = groups;\n\n const [activeFilterInPopover, setActiveFilterInPopover] = useState<FilterConfig | null>(null);\n\n function getFilterOperators(filter: FilterConfig) {\n if (filter.operators && filter.operators.length > 0) return filter.operators;\n return getOperatorsForType(filter.type, strings.operators);\n }\n\n function handleOperatorChange(filterKey: string, operator: FilterOperator) {\n setFilterOperator(filterKey, operator);\n }\n\n return (\n <div\n className={cn('filter-layout--component', \n variant === 'compact' ? 'space-y-2' : 'space-y-4',\n className,\n )}\n >\n {!!tabs && tabs.length > 0 && <FilterTabs tabs={tabs} />}\n\n <div\n className={cn(\n 'flex flex-wrap items-center',\n variant === 'compact' ? 'gap-1' : 'gap-2',\n )}\n >\n <FilterErrorBoundary filterKey=\"search-filters\">\n <SearchFiltersList\n filters={searchFilters}\n getFilterValue={getFilterValue}\n setFilterValue={setFilterValue}\n />\n </FilterErrorBoundary>\n\n <div className={cn('contents', isNavigating && 'pointer-events-none opacity-60')}>\n {/* Loading chips for filters being updated */}\n {Object.entries(loadingFilters)\n .filter(([, isLoading]) => isLoading)\n .map(([key]) => {\n const filterLabel =\n processedFilters.find((f) => f.key === key)?.label || key;\n return (\n <div\n key={`loading-${key}`}\n className=\"text-muted-foreground bg-muted/50 flex items-center rounded-md px-2 py-1 text-xs\"\n >\n <div className=\"border-muted-foreground/30 border-t-primary mr-1 size-3 animate-spin rounded-full border-2\"></div>\n {interpolateFilterString(strings.loadingOptions, { filterLabel })}\n </div>\n );\n })}\n\n {/* Always-visible filters (display: 'always') — even when inactive */}\n {alwaysVisibleFilters.map((filter) => (\n <FilterPill\n key={filter.key}\n filter={filter}\n value={getFilterValue(filter.key) ?? []}\n isActive={false}\n operator={getFilterOperator(filter.key) || 'equals'}\n operators={getFilterOperators(filter)}\n onOperatorChange={(operator) => handleOperatorChange(filter.key, operator)}\n onValueChange={(value) => setFilterValue(filter.key, value)}\n onClear={() => setFilterValue(filter.key, [])}\n availableFilters={popoverFilters}\n activeFilters={[...activeRegularFilters, ...alwaysVisibleFilters]}\n />\n ))}\n\n {/* Active regular filters */}\n {activeRegularFilters.map((filter) => (\n <FilterPill\n key={filter.key}\n filter={filter}\n value={getFilterValue(filter.key) ?? []}\n isActive={isFilterActive(filter.key)}\n operator={getFilterOperator(filter.key) || 'equals'}\n operators={getFilterOperators(filter)}\n onOperatorChange={(operator) => handleOperatorChange(filter.key, operator)}\n onValueChange={(value) => setFilterValue(filter.key, value)}\n onClear={() => setFilterValue(filter.key, [])}\n availableFilters={popoverFilters}\n activeFilters={activeRegularFilters}\n />\n ))}\n\n {popoverFilters.length > 0 && (\n <FilterErrorBoundary filterKey=\"filters-button\">\n <FiltersButton\n availableFilters={popoverFilters}\n activeFilters={activeRegularFilters}\n activeFilterInPopover={activeFilterInPopover}\n getFilterValue={getFilterValue}\n setFilterValue={setFilterValue}\n setActiveFilterInPopover={setActiveFilterInPopover}\n />\n </FilterErrorBoundary>\n )}\n\n {!!showClearFilters && hasActive && (\n <Button\n variant=\"secondary\"\n buttonStyle=\"ghost\"\n size=\"default\"\n onClick={clearFilters}\n className=\"text-muted-foreground ml-auto\"\n >\n {strings.clearFilters}\n </Button>\n )}\n </div>\n </div>\n </div>\n );\n}\n","import { ChevronsUpDown } from 'lucide-react';\nimport { useEffect, useMemo, useRef, useState } from 'react';\n\nimport { PopoverMenu, type PopoverMenuItem } from '@/components/base/popover-menu';\nimport { Text } from '@/components/typography';\nimport { Button } from '@/components/base/buttons';\nimport { cn } from '@/lib/utils';\n\nimport { useFilters } from '../filter-context';\nimport { interpolateFilterString } from '../filters.strings';\nimport type { FilterConfig, FilterOption } from '../filters.types';\n\ninterface SelectFacetProps {\n filter: FilterConfig;\n value: string[];\n onChange: (value: string[]) => void;\n className?: string;\n}\n\n/**\n * SelectFacet — single/multi-select dropdown filter.\n *\n * Composes `PopoverMenu` for the popover + searchable list pattern.\n * Multi-select keeps the popover open after a tap; single-select closes\n * unless `closeOnSelect=false` is passed in the filter config.\n */\nexport function SelectFacet({\n filter,\n value,\n onChange,\n className,\n}: SelectFacetProps) {\n const { strings } = useFilters();\n const [open, setOpen] = useState(false);\n const [searchInput, setSearchInput] = useState('');\n const [options, setOptions] = useState<FilterOption[] | undefined>(\n filter.options,\n );\n const [isLoading, setIsLoading] = useState(false);\n const debounceRef = useRef<number | undefined>(undefined);\n const hasSelection = value.length > 0;\n\n const handleSelect = (selectedValue: string) => {\n if (filter.multiple) {\n if (value.includes(selectedValue)) {\n onChange(value.filter((v) => v !== selectedValue));\n } else {\n onChange([...value, selectedValue]);\n }\n } else {\n onChange([selectedValue]);\n if (filter.closeOnSelect !== false) {\n setOpen(false);\n }\n }\n };\n\n const getOptionLabel = (optionValue: string) =>\n (options || filter.options)?.find((opt) => opt.value === optionValue)\n ?.label ?? optionValue;\n\n // Load options (supports async fetchOptions with basic debounce on searchInput)\n const fetchOptionsFn = filter.fetchOptions;\n const fetchDelay = filter.delay;\n useEffect(() => {\n if (!open) return;\n if (!fetchOptionsFn) return; // static options mode\n\n if (debounceRef.current) window.clearTimeout(debounceRef.current);\n const delay = typeof fetchDelay === 'number' ? fetchDelay : 300;\n debounceRef.current = window.setTimeout(async () => {\n setIsLoading(true);\n try {\n const fetched = await fetchOptionsFn({ q: [searchInput] });\n setOptions(fetched);\n } finally {\n setIsLoading(false);\n }\n }, delay);\n\n return () => {\n if (debounceRef.current) window.clearTimeout(debounceRef.current);\n };\n }, [open, searchInput, fetchOptionsFn, fetchDelay]);\n\n const items = useMemo<PopoverMenuItem[]>(() => {\n const source = options || filter.options || [];\n return source.map((option) => ({\n value: option.value,\n label: option.label,\n description: option.description,\n icon: option.icon,\n selected: value.includes(option.value),\n disabled: option.disabled,\n }));\n }, [options, filter.options, value]);\n\n const placeholderInterpolated = interpolateFilterString(\n strings.searchPlaceholder,\n { filterLabel: filter.label.toLowerCase() },\n );\n\n const emptyMessage = isLoading\n ? interpolateFilterString(strings.loadingOptions, {\n filterLabel: filter.label,\n })\n : strings.noOptionsFound;\n\n return (\n <div className={cn('select-facet--component', 'relative', className)}>\n <PopoverMenu\n open={open}\n onOpenChange={setOpen}\n search\n searchValue={searchInput}\n onSearchChange={setSearchInput}\n strings={{\n searchPlaceholder: placeholderInterpolated,\n empty: emptyMessage,\n }}\n contentClassName=\"w-(--radix-popover-trigger-width) min-w-56\"\n trigger={\n <Button\n variant=\"secondary\"\n buttonStyle=\"outline\"\n size=\"default\"\n role=\"combobox\"\n aria-expanded={open}\n className=\"w-full justify-between\"\n >\n {hasSelection ? (\n value.length === 1 ? (\n <Text tag=\"span\" size=\"xs\" weight=\"semibold\" className=\"truncate\">\n {getOptionLabel(value[0])}\n </Text>\n ) : (\n <Text tag=\"span\" size=\"xs\" weight=\"semibold\">\n {interpolateFilterString(strings.selected, {\n count: value.length,\n filterLabel:\n (value.length > 1\n ? filter.pluralLabel\n : filter.label) ?? filter.label,\n })}\n </Text>\n )\n ) : (\n <Text tag=\"span\" size=\"xs\" type=\"secondary\">\n {filter.placeholder ?? strings.select}\n </Text>\n )}\n <ChevronsUpDown className=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n </Button>\n }\n items={items}\n onSelect={(item) => handleSelect(item.value)}\n />\n </div>\n );\n}\n","import { AlertCircle, Check, ChevronsUpDown, Loader2 } from 'lucide-react';\nimport { useMemo, useRef, useState } from 'react';\n\nimport { Button } from '@/components/base/buttons';\nimport {\n\tCommand,\n\tCommandEmpty,\n\tCommandGroup,\n\tCommandInput,\n\tCommandItem,\n\tCommandList,\n} from '@/components/base/command';\nimport {\n\tPopover,\n\tPopoverContent,\n\tPopoverTrigger,\n} from '@/components/base/popover';\nimport { Text } from '@/components/typography';\nimport { cn } from '@/lib/utils';\n\nimport { useFilters } from '../filter-context';\nimport { interpolateFilterString } from '../filters.strings';\nimport type { FilterConfig, FilterOption } from '../filters.types';\nimport { useAsyncOptions } from '../hooks';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface AsyncSelectFacetProps {\n\tfilter: FilterConfig;\n\tvalue: string[];\n\tonChange: (value: string[]) => void;\n\tclassName?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\n/**\n * Async Select Filter Facet\n *\n * A TanStack Query-powered filter facet for server-side option loading.\n * Supports:\n * - Live typeahead search with debounce + AbortSignal\n * - Loading, error, empty, min-query-hint states\n * - Preload (fetch default options on open)\n * - Multi-select with maxSelected enforcement\n * - Options label cache for pill display after popover close\n */\nexport function AsyncSelectFacet({\n\tfilter,\n\tvalue,\n\tonChange,\n\tclassName,\n}: AsyncSelectFacetProps) {\n\tconst { strings, cacheAsyncOptions, getAsyncOptionLabel } = useFilters();\n\tconst [open, setOpen] = useState(false);\n\tconst [searchInput, setSearchInput] = useState('');\n\n\t// Cache resolved option labels so pills can show labels after popover closes\n\tconst labelCacheRef = useRef<Map<string, FilterOption>>(new Map());\n\n\tconst {\n\t\toptions,\n\t\tisLoading,\n\t\tisFetching,\n\t\tisError,\n\t\trefetch,\n\t\tisBelowMinQuery,\n\t\tminQueryLength,\n\t} = useAsyncOptions(filter, searchInput, open);\n\n\t// Update label cache when new options arrive\n\tif (options.length > 0) {\n\t\tfor (const opt of options) {\n\t\t\tlabelCacheRef.current.set(opt.value, opt);\n\t\t}\n\t\tcacheAsyncOptions(filter.key, options);\n\t}\n\n\tconst isMulti = filter.multiple !== false;\n\tconst maxSelected = filter.maxSelected;\n\tconst initialOptions = useMemo(() => filter.options ?? [], [filter.options]);\n\n\t// Sort options: selected items first, then the rest.\n\t// Also include cached selected items that may not be in current search results.\n\tconst sortedOptions = useMemo(() => {\n\t\tconst selectedSet = new Set(value);\n\t\tconst optionValueSet = new Set(\n\t\t\t[...initialOptions, ...options].map((o) => o.value),\n\t\t);\n\n\t\t// Resolve selected items missing from current results via caches\n\t\tconst missingSelected: FilterOption[] = [];\n\t\tfor (const val of value) {\n\t\t\tif (!optionValueSet.has(val)) {\n\t\t\t\tconst cached = labelCacheRef.current.get(val);\n\t\t\t\tif (cached) {\n\t\t\t\t\tmissingSelected.push(cached);\n\t\t\t\t} else {\n\t\t\t\t\tconst initial = initialOptions.find((o) => o.value === val);\n\t\t\t\t\tif (initial) {\n\t\t\t\t\t\tmissingSelected.push(initial);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tconst label = getAsyncOptionLabel(filter.key, val);\n\t\t\t\t\tif (label) {\n\t\t\t\t\t\tmissingSelected.push({ value: val, label, icon: filter.icon });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst all = [...missingSelected, ...initialOptions, ...options];\n\t\treturn all.sort((a, b) => {\n\t\t\tconst aSelected = selectedSet.has(a.value) ? 0 : 1;\n\t\t\tconst bSelected = selectedSet.has(b.value) ? 0 : 1;\n\t\t\treturn aSelected - bSelected;\n\t\t});\n\t}, [initialOptions, options, value, filter.key, filter.icon, getAsyncOptionLabel]);\n\n\tconst handleSelect = (selectedValue: string) => {\n\t\tif (isMulti) {\n\t\t\tif (value.includes(selectedValue)) {\n\t\t\t\tonChange(value.filter((v) => v !== selectedValue));\n\t\t\t} else {\n\t\t\t\tif (maxSelected && value.length >= maxSelected) return;\n\t\t\t\tonChange([...value, selectedValue]);\n\t\t\t}\n\t\t} else {\n\t\t\tonChange([selectedValue]);\n\t\t\tif (filter.closeOnSelect !== false) {\n\t\t\t\tsetOpen(false);\n\t\t\t}\n\t\t}\n\t};\n\n\tconst getOptionLabel = (optionValue: string): string => {\n\t\t// Check current options first, then cache\n\t\tconst fromOptions = options.find((o) => o.value === optionValue);\n\t\tif (fromOptions) return fromOptions.label;\n\t\tconst fromInitialOptions = initialOptions.find((o) => o.value === optionValue);\n\t\tif (fromInitialOptions) return fromInitialOptions.label;\n\t\tconst cached = labelCacheRef.current.get(optionValue);\n\t\tif (cached) return cached.label;\n\t\treturn optionValue;\n\t};\n\n\tconst hasSelection = value.length > 0;\n\n\t// Determine the empty state message\n\tconst emptyMessage = useMemo(() => {\n\t\tif (isLoading || isFetching) {\n\t\t\treturn (\n\t\t\t\t<div className={cn('async-select-facet--component', 'flex items-center justify-center gap-2 py-4')}>\n\t\t\t\t\t<Loader2 className=\"text-muted-foreground size-4 animate-spin\" />\n\t\t\t\t\t<Text\n\t\t\t\t\t\ttag=\"span\"\n\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\ttype=\"secondary\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{strings.searching}\n\t\t\t\t\t</Text>\n\t\t\t\t</div>\n\t\t\t);\n\t\t}\n\n\t\tif (isError) {\n\t\t\treturn (\n\t\t\t\t<div className=\"flex flex-col items-center gap-2 py-4\">\n\t\t\t\t\t<div className=\"flex items-center gap-1.5\">\n\t\t\t\t\t\t<AlertCircle className=\"text-destructive size-4\" />\n\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\ttag=\"span\"\n\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\ttype=\"secondary\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{strings.fetchError}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t</div>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\t\tbuttonStyle=\"outline\"\n\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\tvoid refetch();\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t{strings.retryFetch}\n\t\t\t\t\t</Button>\n\t\t\t\t</div>\n\t\t\t);\n\t\t}\n\n\t\tif (isBelowMinQuery) {\n\t\t\treturn (\n\t\t\t\t<div className=\"text-muted-foreground flex items-center justify-center py-4\">\n\t\t\t\t\t<Text\n\t\t\t\t\t\ttag=\"span\"\n\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\ttype=\"secondary\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{interpolateFilterString(strings.minQueryHint, {\n\t\t\t\t\t\t\tmin: minQueryLength,\n\t\t\t\t\t\t})}\n\t\t\t\t\t</Text>\n\t\t\t\t</div>\n\t\t\t);\n\t\t}\n\n\t\treturn (\n\t\t\t<Text\n\t\t\t\ttag=\"span\"\n\t\t\t\tsize=\"xs\"\n\t\t\t\ttype=\"secondary\"\n\t\t\t>\n\t\t\t\t{strings.noOptionsFound}\n\t\t\t</Text>\n\t\t);\n\t}, [\n\t\tisLoading,\n\t\tisFetching,\n\t\tisError,\n\t\tisBelowMinQuery,\n\t\tminQueryLength,\n\t\tstrings,\n\t\trefetch,\n\t]);\n\n\treturn (\n\t\t<div className={cn('relative', className)}>\n\t\t\t<Popover\n\t\t\t\topen={open}\n\t\t\t\tonOpenChange={(next) => {\n\t\t\t\t\tsetOpen(next);\n\t\t\t\t\tif (!next) setSearchInput('');\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<PopoverTrigger\n\t\t\t\t\trender={\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\t\t\tbuttonStyle=\"outline\"\n\t\t\t\t\t\t\tsize=\"default\"\n\t\t\t\t\t\t\trole=\"combobox\"\n\t\t\t\t\t\t\taria-expanded={open}\n\t\t\t\t\t\t\tclassName=\"w-full justify-between\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{hasSelection ? (\n\t\t\t\t\t\t\t\tvalue.length === 1 ? (\n\t\t\t\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\t\t\t\ttag=\"span\"\n\t\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\t\tweight=\"semibold\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"truncate\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{getOptionLabel(value[0])}\n\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\t\t\t\ttag=\"span\"\n\t\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\t\tweight=\"semibold\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{interpolateFilterString(strings.selected, {\n\t\t\t\t\t\t\t\t\t\t\tcount: value.length,\n\t\t\t\t\t\t\t\t\t\t\tfilterLabel:\n\t\t\t\t\t\t\t\t\t\t\t\t(value.length > 1\n\t\t\t\t\t\t\t\t\t\t\t\t\t? filter.pluralLabel\n\t\t\t\t\t\t\t\t\t\t\t\t\t: filter.label) ?? filter.label,\n\t\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\t\t\ttag=\"span\"\n\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\ttype=\"secondary\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{filter.placeholder ?? strings.select}\n\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t<ChevronsUpDown className=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t}\n\t\t\t\t/>\n\t\t\t\t<PopoverContent className=\"w-full min-w-[280px] p-0\">\n\t\t\t\t\t<Command shouldFilter={false}>\n\t\t\t\t\t\t<CommandInput\n\t\t\t\t\t\t\tplaceholder={interpolateFilterString(\n\t\t\t\t\t\t\t\tstrings.searchPlaceholder,\n\t\t\t\t\t\t\t\t{ filterLabel: filter.label },\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\tvalue={searchInput}\n\t\t\t\t\t\t\tonValueChange={setSearchInput}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<CommandList>\n\t\t\t\t\t\t\t{sortedOptions.length === 0 ? (\n\t\t\t\t\t\t\t\t<CommandEmpty>{emptyMessage}</CommandEmpty>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<CommandGroup>\n\t\t\t\t\t\t\t\t\t{Boolean(isFetching && !isLoading) && (\n\t\t\t\t\t\t\t\t\t\t<div className=\"flex items-center gap-1.5 px-2 py-1\">\n\t\t\t\t\t\t\t\t\t\t\t<Loader2 className=\"text-muted-foreground size-3 animate-spin\" />\n\t\t\t\t\t\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\t\t\t\t\t\ttag=\"span\"\n\t\t\t\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\t\t\t\ttype=\"secondary\"\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{strings.searching}\n\t\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t{sortedOptions.map((option) => (\n\t\t\t\t\t\t\t\t\t\t<CommandItem\n\t\t\t\t\t\t\t\t\t\t\tkey={option.value}\n\t\t\t\t\t\t\t\t\t\t\tvalue={option.value}\n\t\t\t\t\t\t\t\t\t\t\tonSelect={() => handleSelect(option.value)}\n\t\t\t\t\t\t\t\t\t\t\tdisabled={\n\t\t\t\t\t\t\t\t\t\t\t\toption.disabled ||\n\t\t\t\t\t\t\t\t\t\t\t\t(!!maxSelected &&\n\t\t\t\t\t\t\t\t\t\t\t\t\tvalue.length >= maxSelected &&\n\t\t\t\t\t\t\t\t\t\t\t\t\t!value.includes(option.value))\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<Check\n\t\t\t\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\t\t\t'mr-2 h-4 w-4',\n\t\t\t\t\t\t\t\t\t\t\t\t\tvalue.includes(option.value)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t? 'opacity-100'\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t: 'opacity-0',\n\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t{Boolean(option.icon) && (\n\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"mr-1.5\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t{option.icon}\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\t\t\t\t\t\ttag=\"span\"\n\t\t\t\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{option.label}\n\t\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t\t</CommandItem>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</CommandGroup>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</CommandList>\n\t\t\t\t\t</Command>\n\t\t\t\t</PopoverContent>\n\t\t\t</Popover>\n\t\t</div>\n\t);\n}\n\n/**\n * Retrieve the label cache ref from an AsyncSelectFacet instance.\n * This is used by FilterValueDisplay to resolve labels for active async filters.\n */\nexport type AsyncSelectLabelCache = Map<string, FilterOption>;\n","import { useState, useEffect, useId, useRef, type ChangeEvent } from 'react';\nimport { Input } from '@/components/base/forms';\nimport { Label } from '@/components/typography';\nimport { cn } from '@/lib/utils';\nimport { useFilters } from '../filter-context';\nimport type { FilterConfig } from '../filters.types';\n\ninterface RangeFacetProps {\n filter: FilterConfig;\n value: { min?: number; max?: number };\n onChange: (value: { min?: number; max?: number }) => void;\n className?: string;\n}\n\n/**\n * Range Filter Facet\n *\n * This component implements a numeric range filter that allows users to:\n * - Set minimum and maximum values\n * - Configure step size and precision\n * - Set value constraints (min/max allowed values)\n * - Customize the range input appearance\n *\n * The component integrates with the filter context to manage the range values\n * and provides a user-friendly interface for range selection.\n */\n\nexport function RangeFacet({\n filter,\n value,\n onChange,\n className,\n}: RangeFacetProps) {\n const { strings } = useFilters();\n\n const [minValue, setMinValue] = useState<string>(\n value.min?.toString() ?? '',\n );\n const [maxValue, setMaxValue] = useState<string>(\n value.max?.toString() ?? '',\n );\n const instanceId = useId(); // Keep ids unique when multiple range facets render\n\n // Stabilize callback and value refs to keep the effect dep-light\n const onChangeRef = useRef(onChange);\n onChangeRef.current = onChange;\n const valueRef = useRef(value);\n valueRef.current = value;\n\n useEffect(() => {\n const timeout = setTimeout(() => {\n const currentValue = valueRef.current;\n const newValue = {\n min: minValue ? Number(minValue) : undefined,\n max: maxValue ? Number(maxValue) : undefined,\n };\n if (newValue.min !== currentValue.min || newValue.max !== currentValue.max) {\n onChangeRef.current(newValue);\n }\n }, filter.delay ?? 500);\n\n return () => clearTimeout(timeout);\n }, [minValue, maxValue, filter.delay]);\n\n const handleMinChange = (e: ChangeEvent<HTMLInputElement>) => {\n const val = e.target.value;\n if (val === '' || /^\\d*\\.?\\d*$/.test(val)) {\n setMinValue(val);\n }\n };\n\n const handleMaxChange = (e: ChangeEvent<HTMLInputElement>) => {\n const val = e.target.value;\n if (val === '' || /^\\d*\\.?\\d*$/.test(val)) {\n setMaxValue(val);\n }\n };\n\n return (\n <div className={cn('range-facet--component', 'space-y-2', className)}>\n <div className=\"grid grid-cols-2 gap-2\">\n <div className=\"space-y-1\">\n <Label htmlFor={`${instanceId}-min`}>\n {strings.min}\n </Label>\n <Input\n id={`${instanceId}-min`}\n type=\"text\"\n value={minValue}\n onChange={handleMinChange}\n placeholder={strings.min}\n className=\"w-full\"\n />\n </div>\n <div className=\"space-y-1\">\n <Label htmlFor={`${instanceId}-max`}>\n {strings.max}\n </Label>\n <Input\n id={`${instanceId}-max`}\n type=\"text\"\n value={maxValue}\n onChange={handleMaxChange}\n placeholder={strings.max}\n className=\"w-full\"\n />\n </div>\n </div>\n </div>\n );\n}\n","/**\n * Validator helpers for `FilterConfig.validation.custom`.\n *\n * Our `ValidationConfig` accepts `custom: (value) => boolean | string`\n * already (`true` = valid, `false` = generic invalid, `string` = custom\n * error message). These helpers adapt common third-party validators\n * — Zod, Valibot, plain async-safe predicates — to that shape so\n * consumers don't reinvent the bridge.\n *\n * The library does NOT depend on Zod or any specific validation lib.\n * The helpers are written against minimal duck-typed shapes that any\n * library implementing `safeParse` can satisfy.\n */\nimport type { ValidationConfig } from './filters.types';\n\n/**\n * Minimal Zod-compatible interface — a schema with a `safeParse` method\n * that returns `{ success: boolean, error?: { message?: string,\n * issues?: { message: string }[] } }`. Both Zod 3 and Zod 4 satisfy\n * this; Valibot's `safeParse` differs slightly but a thin wrapper\n * works.\n */\nexport interface SafeParseSchema<TInput = unknown> {\n\tsafeParse(value: TInput): {\n\t\tsuccess: boolean;\n\t\terror?: {\n\t\t\tmessage?: string;\n\t\t\tissues?: { message: string }[];\n\t\t};\n\t};\n}\n\n/**\n * Adapter: turn a Zod-like schema into a `ValidationConfig['custom']`.\n *\n * import { z } from 'zod';\n * import { zodValidator } from '@/components/features/filters';\n *\n * const emailSchema = z.string().email();\n * const config: FilterConfig = {\n * …,\n * validation: { custom: zodValidator(emailSchema) },\n * };\n *\n * On parse failure the first issue's `message` is returned (so\n * Zod's `.refine(...).message('Custom')` flows through). On success\n * returns `true`. The empty-string case is bypassed — let\n * `validation.required` handle \"must not be empty\" so error messages\n * stay coherent.\n */\nexport function zodValidator<TInput = unknown>(\n\tschema: SafeParseSchema<TInput>,\n): NonNullable<ValidationConfig['custom']> {\n\treturn (value: unknown): boolean | string => {\n\t\t// Skip empty strings — `validation.required` is the right channel\n\t\t// for \"missing value\" messaging.\n\t\tif (value === undefined || value === null) return true;\n\t\tif (typeof value === 'string' && value.length === 0) return true;\n\t\tconst result = schema.safeParse(value as TInput);\n\t\tif (result.success) return true;\n\t\tconst message =\n\t\t\tresult.error?.issues?.[0]?.message ??\n\t\t\tresult.error?.message ??\n\t\t\tfalse;\n\t\treturn message as string | false;\n\t};\n}\n\n/**\n * Adapter: pair a predicate with a static error message. Useful when\n * the consumer doesn't want to pull a validation library at all.\n *\n * validation: {\n * custom: predicateValidator(\n * (v) => /^https?:\\/\\//.test(String(v)),\n * 'URL must start with http:// or https://',\n * ),\n * }\n */\nexport function predicateValidator(\n\tpredicate: (value: unknown) => boolean,\n\tmessage: string,\n): NonNullable<ValidationConfig['custom']> {\n\treturn (value: unknown) => (predicate(value) ? true : message);\n}\n"],"mappings":"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"}
|