themelia-react-ui 2.0.1 → 2.0.3
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/CHANGELOG.md +317 -131
- package/README.md +25 -9
- package/THIRD_PARTY_NOTICES.md +7 -0
- package/dist/{accordion-B6a3vVgA.js → accordion-Cjb6sx0G.js} +14 -13
- package/dist/accordion-Cjb6sx0G.js.map +1 -0
- package/dist/action-menu-CllU52Mm.js +280 -0
- package/dist/action-menu-CllU52Mm.js.map +1 -0
- package/dist/affordance-geometry.generated-tF36bREk.js +140 -0
- package/dist/affordance-geometry.generated-tF36bREk.js.map +1 -0
- package/dist/ai-artifact-DvTwDVyL.js +1148 -0
- package/dist/ai-artifact-DvTwDVyL.js.map +1 -0
- package/dist/{app-shell-ZK5RWdo6.js → app-shell-C4FhvCqF.js} +5 -5
- package/dist/{app-shell-ZK5RWdo6.js.map → app-shell-C4FhvCqF.js.map} +1 -1
- package/dist/attachment-BxDfL2mw.js +246 -0
- package/dist/attachment-BxDfL2mw.js.map +1 -0
- package/dist/{auth-CYxKfo69.js → auth-BGua8ouh.js} +58 -54
- package/dist/auth-BGua8ouh.js.map +1 -0
- package/dist/{avatar-BBnEJIx8.js → avatar-DAPlDvhJ.js} +7 -7
- package/dist/avatar-DAPlDvhJ.js.map +1 -0
- package/dist/{badge-MrKVNzW9.js → badge-HpFqoqSY.js} +40 -40
- package/dist/badge-HpFqoqSY.js.map +1 -0
- package/dist/base/accordion.js +1 -1
- package/dist/base/action-menu.js +1 -1
- package/dist/base/attachment.js +1 -1
- package/dist/base/avatar.js +1 -1
- package/dist/base/badge.js +1 -1
- package/dist/base/batch-action-bar.js +1 -1
- package/dist/base/buttons.js +1 -1
- package/dist/base/cards.js +2 -2
- package/dist/base/carousel.js +40 -36
- package/dist/base/carousel.js.map +1 -1
- package/dist/base/cascader.js +92 -92
- package/dist/base/cascader.js.map +1 -1
- package/dist/base/chart.js +1 -1
- package/dist/base/choice-inputs.js +2 -2
- package/dist/base/code-block.js +1 -1
- package/dist/base/combobox.js +2 -2
- package/dist/base/command.js +1 -1
- package/dist/base/copyable.js +1 -1
- package/dist/base/date-pickers.js +2 -2
- package/dist/base/display.js +6 -6
- package/dist/base/feedback.js +3 -3
- package/dist/base/forms-numeric.js +1 -1
- package/dist/base/forms.js +2 -2
- package/dist/base/inline-edit.js +14 -14
- package/dist/base/inline-edit.js.map +1 -1
- package/dist/base/item.js +1 -1
- package/dist/base/media-gallery.js +1 -1
- package/dist/base/metadata-list.js +1 -1
- package/dist/base/navigation.js +6 -6
- package/dist/base/popover-menu.js +1 -1
- package/dist/base/popover.js +1 -1
- package/dist/base/qr-code.js +1 -1
- package/dist/base/repeaters.js +171 -176
- package/dist/base/repeaters.js.map +1 -1
- package/dist/base/sheet.js +1 -1
- package/dist/base/sidebar.js +1 -1
- package/dist/base/signature-pad.js +6 -6
- package/dist/base/skeleton.js +1 -1
- package/dist/base/spinner.js +79 -2
- package/dist/base/spinner.js.map +1 -0
- package/dist/base/structure.js +1 -1
- package/dist/base/table.js +1 -1
- package/dist/base/text-inputs.js +2 -2
- package/dist/base/toaster.js +46 -45
- package/dist/base/toaster.js.map +1 -1
- package/dist/base/tree.js +1 -1
- package/dist/base/upload-queue.js +1 -1
- package/dist/base/upload.js +3 -3
- package/dist/base/value-inputs.js +1 -1
- package/dist/{batch-action-bar-BZGDG-Si.js → batch-action-bar-DnUJ21NQ.js} +6 -5
- package/dist/batch-action-bar-DnUJ21NQ.js.map +1 -0
- package/dist/blocks/admin.js +42 -42
- package/dist/blocks/admin.js.map +1 -1
- package/dist/blocks/ai.js +260 -240
- package/dist/blocks/ai.js.map +1 -1
- package/dist/blocks/analytics/usage-card.js +1 -1
- package/dist/blocks/analytics.js +620 -585
- package/dist/blocks/analytics.js.map +1 -1
- package/dist/blocks/collaboration.js +1 -1
- package/dist/blocks/commerce/receipt.js +1 -1
- package/dist/blocks/commerce.js +1152 -1109
- package/dist/blocks/commerce.js.map +1 -1
- package/dist/blocks/data-display.js +2 -2
- package/dist/blocks/onboarding.js +48 -39
- package/dist/blocks/onboarding.js.map +1 -1
- package/dist/blocks/planning.js +13 -12
- package/dist/blocks/planning.js.map +1 -1
- package/dist/blocks/timelines.js +1 -1
- package/dist/{breadcrumbs-D5t7I023.js → breadcrumbs-C-oqs1sQ.js} +5 -5
- package/dist/breadcrumbs-C-oqs1sQ.js.map +1 -0
- package/dist/{button-QYwiyhD2.js → button-DVzspB_G.js} +2 -2
- package/dist/{button-QYwiyhD2.js.map → button-DVzspB_G.js.map} +1 -1
- package/dist/{buttons-SbIcm1HJ.js → buttons-DPZekJFu.js} +20 -15
- package/dist/buttons-DPZekJFu.js.map +1 -0
- package/dist/cards-BaBZR-AU.js +68 -0
- package/dist/cards-BaBZR-AU.js.map +1 -0
- package/dist/{chart-QfrARkXl.js → chart-ZOYyK2xG.js} +58 -55
- package/dist/chart-ZOYyK2xG.js.map +1 -0
- package/dist/{checkbox-DhB6K0bK.js → checkbox-AWIhNhmo.js} +2 -2
- package/dist/{checkbox-DhB6K0bK.js.map → checkbox-AWIhNhmo.js.map} +1 -1
- package/dist/{choice-inputs-t6w3ATNz.js → choice-inputs-CNHvARCJ.js} +49 -45
- package/dist/choice-inputs-CNHvARCJ.js.map +1 -0
- package/dist/{code-block-Dgbu-CU3.js → code-block-DeneBJR_.js} +8 -8
- package/dist/code-block-DeneBJR_.js.map +1 -0
- package/dist/{collapsible-D8AEGU1-.js → collapsible-C-_l4hpy.js} +3 -3
- package/dist/{collapsible-D8AEGU1-.js.map → collapsible-C-_l4hpy.js.map} +1 -1
- package/dist/{collection-content-uK16Grv0.js → collection-content-By56pLog.js} +3 -3
- package/dist/{collection-content-uK16Grv0.js.map → collection-content-By56pLog.js.map} +1 -1
- package/dist/combobox-DaHESuiL.js +355 -0
- package/dist/combobox-DaHESuiL.js.map +1 -0
- package/dist/{combobox-DLl0bfiq.js → combobox-Dxo2fAYQ.js} +289 -279
- package/dist/combobox-Dxo2fAYQ.js.map +1 -0
- package/dist/{command-kNR20o7x.js → command-C25VMRII.js} +7 -7
- package/dist/{command-kNR20o7x.js.map → command-C25VMRII.js.map} +1 -1
- package/dist/{comments-BpDuCUUu.js → comments-DD0DUPwJ.js} +114 -105
- package/dist/comments-DD0DUPwJ.js.map +1 -0
- package/dist/components/base/badge/badge.recipes.d.ts +1 -1
- package/dist/components/base/buttons/loader-button.d.ts +2 -1
- package/dist/components/base/cards/card.recipes.d.ts +2 -3
- package/dist/components/base/cards/partials/smart-card-skeleton.d.ts +3 -13
- package/dist/components/base/cards/smart-card.types.d.ts +11 -4
- package/dist/components/base/chart/chart.d.ts +2 -5
- package/dist/components/base/combobox/combobox-field.d.ts +16 -0
- package/dist/components/base/combobox/combobox.strings.d.ts +7 -0
- package/dist/components/base/combobox/index.d.ts +30 -4
- package/dist/components/base/forms/form-sizing.d.ts +11 -3
- package/dist/components/base/navigation/pagination.d.ts +5 -2
- package/dist/components/base/popover/popover.recipes.d.ts +15 -1
- package/dist/components/base/table/index.d.ts +9 -2
- package/dist/components/base/text-inputs/input-group.d.ts +2 -2
- package/dist/components/blocks/ai/ai-shimmer/ai-shimmer.d.ts +1 -1
- package/dist/components/blocks/ai/ai-shimmer/types.d.ts +3 -0
- package/dist/components/blocks/commerce/fulfillment-group/types.d.ts +3 -1
- package/dist/components/blocks/data-display/inline-stat/inline-stat.d.ts +16 -8
- package/dist/components/features/activities/partials/activity-marker.d.ts +6 -3
- package/dist/components/features/appointment-calendar/appointment-calendar.d.ts +5 -0
- package/dist/components/features/appointment-calendar/appointment-calendar.types.d.ts +220 -0
- package/dist/components/features/appointment-calendar/appointment-calendar.utils.d.ts +41 -0
- package/dist/components/features/appointment-calendar/index.d.ts +3 -0
- package/dist/components/features/appointment-calendar/partials/appointment-agenda.d.ts +32 -0
- package/dist/components/features/appointment-calendar/partials/appointment-month.d.ts +13 -0
- package/dist/components/features/combobox/combobox.strings.d.ts +15 -1
- package/dist/components/features/combobox/types.d.ts +4 -0
- package/dist/components/features/media-library/media-library.strings.d.ts +2 -0
- package/dist/components/features/rich-text-editor/index.d.ts +1 -1
- package/dist/components/features/rich-text-editor/rich-text-editor.recipes.d.ts +6 -0
- package/dist/components/features/rich-text-editor/rich-text-editor.types.d.ts +9 -1
- package/dist/components/features/table/table-header.d.ts +1 -1
- package/dist/components/features/table/table.strings.d.ts +55 -1
- package/dist/components/features/table/table.types.d.ts +17 -4
- package/dist/components/features/theme-tweaker/theme-tweaker.types.d.ts +5 -0
- package/dist/components/primitives/number.d.ts +4 -2
- package/dist/components/primitives/value.d.ts +3 -1
- package/dist/components/typography/text-link.d.ts +4 -0
- package/dist/components/ui/combobox-dismiss.d.ts +16 -0
- package/dist/components/ui/combobox.d.ts +16 -7
- package/dist/components/ui/dialog.d.ts +1 -1
- package/dist/components/ui/item.d.ts +8 -8
- package/dist/components/ui/popover.d.ts +1 -1
- package/dist/components/ui/sheet.d.ts +1 -1
- package/dist/components/ui/tabs.d.ts +1 -1
- package/dist/{containers-DmWiJa2I.js → containers-Mu1LMGV1.js} +2 -2
- package/dist/{containers-DmWiJa2I.js.map → containers-Mu1LMGV1.js.map} +1 -1
- package/dist/{copyable-B3Gwgdqc.js → copyable-ClBuk_UK.js} +4 -4
- package/dist/{copyable-B3Gwgdqc.js.map → copyable-ClBuk_UK.js.map} +1 -1
- package/dist/{data-display-DafIvCl5.js → data-display-DT_khPl_.js} +98 -87
- package/dist/data-display-DT_khPl_.js.map +1 -0
- package/dist/{date-BgK3bTdo.js → date-DCrsDTZc.js} +5 -5
- package/dist/{date-BgK3bTdo.js.map → date-DCrsDTZc.js.map} +1 -1
- package/dist/{date-picker-CF-DtUpF.js → date-picker-B2K3ucWn.js} +594 -593
- package/dist/date-picker-B2K3ucWn.js.map +1 -0
- package/dist/date-pickers-Ds8gLaoP.js +175 -0
- package/dist/date-pickers-Ds8gLaoP.js.map +1 -0
- package/dist/{display-DsQTVzMz.js → display-hAc1HjpI.js} +49 -49
- package/dist/display-hAc1HjpI.js.map +1 -0
- package/dist/dropdown-menu-Cl4X7L5S.js +193 -0
- package/dist/dropdown-menu-Cl4X7L5S.js.map +1 -0
- package/dist/editable-text-recipe-Cn61kEcv.js +10 -0
- package/dist/editable-text-recipe-Cn61kEcv.js.map +1 -0
- package/dist/features/activities.js +398 -375
- package/dist/features/activities.js.map +1 -1
- package/dist/features/ai-chat.js +188 -179
- package/dist/features/ai-chat.js.map +1 -1
- package/dist/features/appointment-calendar.js +683 -0
- package/dist/features/appointment-calendar.js.map +1 -0
- package/dist/features/async-preview.js +109 -107
- package/dist/features/async-preview.js.map +1 -1
- package/dist/features/combobox.js +1 -1
- package/dist/features/comments.js +1 -1
- package/dist/features/data-view.js +137 -137
- package/dist/features/data-view.js.map +1 -1
- package/dist/features/email-composer.js +255 -255
- package/dist/features/email-composer.js.map +1 -1
- package/dist/features/event-calendar.js +254 -248
- package/dist/features/event-calendar.js.map +1 -1
- package/dist/features/filters.js +1 -1
- package/dist/features/global-search.js +35 -32
- package/dist/features/global-search.js.map +1 -1
- package/dist/features/kanban.js +118 -117
- package/dist/features/kanban.js.map +1 -1
- package/dist/features/map.js +233 -231
- package/dist/features/map.js.map +1 -1
- package/dist/features/media-library.js +789 -775
- package/dist/features/media-library.js.map +1 -1
- package/dist/features/mentions.js +1 -1
- package/dist/features/overlays.js +1 -1
- package/dist/features/products.js +922 -902
- package/dist/features/products.js.map +1 -1
- package/dist/features/questionnaire.js +28 -24
- package/dist/features/questionnaire.js.map +1 -1
- package/dist/features/resource-assignment.js +18 -15
- package/dist/features/resource-assignment.js.map +1 -1
- package/dist/features/resource.js +12 -12
- package/dist/features/resource.js.map +1 -1
- package/dist/features/rich-text-editor.js +2 -2
- package/dist/features/schema-form.js +15 -13
- package/dist/features/schema-form.js.map +1 -1
- package/dist/features/suggestions.js +3 -3
- package/dist/features/sync.js +11 -5
- package/dist/features/sync.js.map +1 -1
- package/dist/features/table.js +1 -1
- package/dist/features/theme-tweaker.js +493 -489
- package/dist/features/theme-tweaker.js.map +1 -1
- package/dist/feedback-BYIhtitP.js +239 -0
- package/dist/feedback-BYIhtitP.js.map +1 -0
- package/dist/{field-affordance-recipes-qQeIf4lG.js → field-affordance-recipes-DZhnIL_Y.js} +11 -18
- package/dist/field-affordance-recipes-DZhnIL_Y.js.map +1 -0
- package/dist/{filters-BkHH53uv.js → filters-DJVAveHA.js} +589 -580
- package/dist/filters-DJVAveHA.js.map +1 -0
- package/dist/{form-field-DUt4UxSV.js → form-field-CwH9y77i.js} +6 -5
- package/dist/form-field-CwH9y77i.js.map +1 -0
- package/dist/{form-sizing-By94KzXE.js → form-sizing-BdP_Mf5p.js} +39 -44
- package/dist/form-sizing-BdP_Mf5p.js.map +1 -0
- package/dist/{forms-Bzha-Y3B.js → forms-B9G_xwzi.js} +8 -8
- package/dist/{forms-Bzha-Y3B.js.map → forms-B9G_xwzi.js.map} +1 -1
- package/dist/{forms-numeric-C0bvjRPZ.js → forms-numeric-B_jraJaQ.js} +309 -309
- package/dist/forms-numeric-B_jraJaQ.js.map +1 -0
- package/dist/{header-BOefOKd1.js → header-BSfIEWbI.js} +160 -153
- package/dist/header-BSfIEWbI.js.map +1 -0
- package/dist/{hooks-9k_TtmKh.js → hooks-ClH9thn4.js} +2 -2
- package/dist/{hooks-9k_TtmKh.js.map → hooks-ClH9thn4.js.map} +1 -1
- package/dist/{icon-badge-CAuKupo9.js → icon-badge-DYKIwvOV.js} +4 -4
- package/dist/{icon-badge-CAuKupo9.js.map → icon-badge-DYKIwvOV.js.map} +1 -1
- package/dist/index.js +3 -3
- package/dist/input-CZw8iU99.js +21 -0
- package/dist/input-CZw8iU99.js.map +1 -0
- package/dist/input-DQdEd0YD.js +263 -0
- package/dist/input-DQdEd0YD.js.map +1 -0
- package/dist/{interaction-recipes-CHr0dJUs.js → interaction-recipes-XR9ZpVYL.js} +2 -1
- package/dist/interaction-recipes-XR9ZpVYL.js.map +1 -0
- package/dist/item-K5_ghvze.js +275 -0
- package/dist/item-K5_ghvze.js.map +1 -0
- package/dist/layout/app-shell.js +1 -1
- package/dist/layout/auth.js +1 -1
- package/dist/layout/containers.js +1 -1
- package/dist/layout/header.js +1 -1
- package/dist/layout/hooks.js +1 -1
- package/dist/layout/navigation.js +1 -1
- package/dist/layout/page.js +1 -1
- package/dist/layout/settings.js +1 -1
- package/dist/layout/sidebar.js +2 -2
- package/dist/layout/workspace.js +1 -1
- package/dist/layout.js +10 -10
- package/dist/lib/affordance-geometry.generated.d.ts +71 -0
- package/dist/lib/editable-text-recipe.d.ts +4 -4
- package/dist/lib/field-affordance-recipes.d.ts +2 -2
- package/dist/lib/interaction-recipes.d.ts +5 -0
- package/dist/lib/theme-mode-css.d.ts +7 -0
- package/dist/lib/tone-recipes.d.ts +8 -0
- package/dist/lib/ui-provider/types.d.ts +2 -2
- package/dist/lib/use-popup-focus-recovery.d.ts +8 -0
- package/dist/lib/utils.js +1 -1
- package/dist/{media-gallery-DcTtAaeC.js → media-gallery-3zIVLMWH.js} +8 -8
- package/dist/media-gallery-3zIVLMWH.js.map +1 -0
- package/dist/{mentions-D-uyCh01.js → mentions-CGlEJ15c.js} +144 -142
- package/dist/mentions-CGlEJ15c.js.map +1 -0
- package/dist/{message-CdHgIWKf.js → message-DZ_ruyUV.js} +6 -5
- package/dist/message-DZ_ruyUV.js.map +1 -0
- package/dist/{metadata-list-X5rYAKSB.js → metadata-list-8N16ZMW_.js} +130 -119
- package/dist/metadata-list-8N16ZMW_.js.map +1 -0
- package/dist/{navigation-D3KwXmaq.js → navigation-Bnotn4AQ.js} +19 -19
- package/dist/navigation-Bnotn4AQ.js.map +1 -0
- package/dist/{navigation-HJf5zxlH.js → navigation-BzhHI3lo.js} +36 -35
- package/dist/navigation-BzhHI3lo.js.map +1 -0
- package/dist/{navigation-row-recipes-BVowojQw.js → navigation-row-recipes-BFLCk_Aq.js} +2 -2
- package/dist/{navigation-row-recipes-BVowojQw.js.map → navigation-row-recipes-BFLCk_Aq.js.map} +1 -1
- package/dist/{number-DMhe-Vsk.js → number-DbV1Dija.js} +36 -34
- package/dist/{number-DMhe-Vsk.js.map → number-DbV1Dija.js.map} +1 -1
- package/dist/{overflow-tab-bar-sQHXLlwQ.js → overflow-tab-bar-CWY7Nogn.js} +105 -103
- package/dist/overflow-tab-bar-CWY7Nogn.js.map +1 -0
- package/dist/{overlays-I0axtYA6.js → overlays-tMkF-VAN.js} +282 -278
- package/dist/overlays-tMkF-VAN.js.map +1 -0
- package/dist/{page-B5dTH9gE.js → page-CL9YeH_V.js} +8 -8
- package/dist/{page-B5dTH9gE.js.map → page-CL9YeH_V.js.map} +1 -1
- package/dist/{page-header-commands-DjzFEq3E.js → page-header-commands-DOb6WsfD.js} +5 -5
- package/dist/{page-header-commands-DjzFEq3E.js.map → page-header-commands-DOb6WsfD.js.map} +1 -1
- package/dist/pagination-BL25hu2s.js +158 -0
- package/dist/pagination-BL25hu2s.js.map +1 -0
- package/dist/{popover-Di55PyAI.js → popover-gnTOhbFM.js} +69 -66
- package/dist/popover-gnTOhbFM.js.map +1 -0
- package/dist/popover-menu-Cn9rUkdc.js +100 -0
- package/dist/popover-menu-Cn9rUkdc.js.map +1 -0
- package/dist/{popover.recipes-Bdyhj2db.js → popover.recipes-D3j8R8Yp.js} +17 -10
- package/dist/popover.recipes-D3j8R8Yp.js.map +1 -0
- package/dist/{primitives-B-CkiEMU.js → primitives-BFK08r9M.js} +45 -44
- package/dist/primitives-BFK08r9M.js.map +1 -0
- package/dist/primitives.js +4 -4
- package/dist/{progress-rnS8-uAW.js → progress-B1VnCT0K.js} +5 -5
- package/dist/{progress-rnS8-uAW.js.map → progress-B1VnCT0K.js.map} +1 -1
- package/dist/{receipt-D0oswZ0p.js → receipt-BVSOH3Xo.js} +9 -6
- package/dist/{receipt-D0oswZ0p.js.map → receipt-BVSOH3Xo.js.map} +1 -1
- package/dist/{rich-text-DvGulsNJ.js → rich-text-GOUyKQ-s.js} +3 -3
- package/dist/{rich-text-DvGulsNJ.js.map → rich-text-GOUyKQ-s.js.map} +1 -1
- package/dist/{rich-text-editor-sMU_Scqm.js → rich-text-editor-cRLC-eBK.js} +418 -426
- package/dist/rich-text-editor-cRLC-eBK.js.map +1 -0
- package/dist/rich-text-editor-toolbar-DfXg0-VC.js +94 -0
- package/dist/rich-text-editor-toolbar-DfXg0-VC.js.map +1 -0
- package/dist/{scroll-area-Bt_vXY2b.js → scroll-area-DcI-M1UT.js} +2 -2
- package/dist/{scroll-area-Bt_vXY2b.js.map → scroll-area-DcI-M1UT.js.map} +1 -1
- package/dist/{separator-C8DlRGwF.js → separator-BDV-Y648.js} +3 -3
- package/dist/{separator-C8DlRGwF.js.map → separator-BDV-Y648.js.map} +1 -1
- package/dist/{separator-CYHnjsAb.js → separator-Bom7NsGO.js} +2 -2
- package/dist/{separator-CYHnjsAb.js.map → separator-Bom7NsGO.js.map} +1 -1
- package/dist/services/actions.js +1 -1
- package/dist/{settings-CQW3b-Cu.js → settings-ybnjVwbd.js} +20 -19
- package/dist/settings-ybnjVwbd.js.map +1 -0
- package/dist/{sheet-4SEvVYzA.js → sheet-ijlsjq-n.js} +76 -73
- package/dist/sheet-ijlsjq-n.js.map +1 -0
- package/dist/{sidebar-C7WWR29L.js → sidebar-Db6gkh3U.js} +183 -182
- package/dist/sidebar-Db6gkh3U.js.map +1 -0
- package/dist/{sidebar-d7Dg80ln.js → sidebar-DkTO4VTO.js} +14 -13
- package/dist/{sidebar-d7Dg80ln.js.map → sidebar-DkTO4VTO.js.map} +1 -1
- package/dist/{skeleton-Cz890JZF.js → skeleton-Byjnt7qr.js} +3 -3
- package/dist/{skeleton-Cz890JZF.js.map → skeleton-Byjnt7qr.js.map} +1 -1
- package/dist/smart-card-DiC5aac3.js +604 -0
- package/dist/smart-card-DiC5aac3.js.map +1 -0
- package/dist/{structure-DC2dygdA.js → structure-BmisBK-3.js} +2 -2
- package/dist/{structure-DC2dygdA.js.map → structure-BmisBK-3.js.map} +1 -1
- package/dist/style.css +1 -1
- package/dist/table-BweFy_P9.js +1530 -0
- package/dist/table-BweFy_P9.js.map +1 -0
- package/dist/{table-CIKyLUsy.js → table-DsfzoUia.js} +75 -63
- package/dist/table-DsfzoUia.js.map +1 -0
- package/dist/{tabs-DwBJfjxX.js → tabs-CDocW5D1.js} +14 -13
- package/dist/tabs-CDocW5D1.js.map +1 -0
- package/dist/text-inputs-f9Ia-aCi.js +353 -0
- package/dist/text-inputs-f9Ia-aCi.js.map +1 -0
- package/dist/theme-mode-css-BB-_RYab.js +14 -0
- package/dist/theme-mode-css-BB-_RYab.js.map +1 -0
- package/dist/theme-scope-BJ6eE2xt.js +50 -0
- package/dist/theme-scope-BJ6eE2xt.js.map +1 -0
- package/dist/theme.css +285 -228
- package/dist/themes/green.css +16 -12
- package/dist/timelines-CwM_9IhD.js +457 -0
- package/dist/timelines-CwM_9IhD.js.map +1 -0
- package/dist/{tone-recipes-CPoExcTE.js → tone-recipes-BPsRAvhu.js} +5 -2
- package/dist/tone-recipes-BPsRAvhu.js.map +1 -0
- package/dist/{tooltip-CsfgrfS7.js → tooltip-yiRJUFjp.js} +4 -4
- package/dist/{tooltip-CsfgrfS7.js.map → tooltip-yiRJUFjp.js.map} +1 -1
- package/dist/{tree-BiKhg8AY.js → tree-WnKQzwbq.js} +9 -9
- package/dist/{tree-BiKhg8AY.js.map → tree-WnKQzwbq.js.map} +1 -1
- package/dist/typography/rich-text.js +1 -1
- package/dist/{typography-DTRkE9zL.js → typography-UTnveOEy.js} +6 -6
- package/dist/typography-UTnveOEy.js.map +1 -0
- package/dist/typography.js +2 -2
- package/dist/{ui-provider-1D_NSYzO.js → ui-provider-C_U0Xma4.js} +3 -3
- package/dist/ui-provider-C_U0Xma4.js.map +1 -0
- package/dist/ui-provider.js +2 -2
- package/dist/{upload-BO8-CLN6.js → upload-CXyxmQBP.js} +13 -12
- package/dist/upload-CXyxmQBP.js.map +1 -0
- package/dist/{upload-queue-EOC8g1gf.js → upload-queue-Boscubn9.js} +11 -9
- package/dist/upload-queue-Boscubn9.js.map +1 -0
- package/dist/{usage-card-obRaBskq.js → usage-card-BhO5eqkX.js} +53 -37
- package/dist/usage-card-BhO5eqkX.js.map +1 -0
- package/dist/use-popup-focus-recovery-C0QPvgOR.js +36 -0
- package/dist/use-popup-focus-recovery-C0QPvgOR.js.map +1 -0
- package/dist/{utils-l5LpDw2z.js → utils-BRhFDwuU.js} +59 -44
- package/dist/utils-BRhFDwuU.js.map +1 -0
- package/dist/{value-inputs-TAYMX111.js → value-inputs-TaX4OjNk.js} +268 -252
- package/dist/value-inputs-TaX4OjNk.js.map +1 -0
- package/dist/{value-typography-b8wpz1eX.js → value-typography-BP8OG6h5.js} +2 -2
- package/dist/{value-typography-b8wpz1eX.js.map → value-typography-BP8OG6h5.js.map} +1 -1
- package/dist/{workspace-DH0v0KcB.js → workspace-B-OEm3Kf.js} +34 -33
- package/dist/workspace-B-OEm3Kf.js.map +1 -0
- package/docs/consumer-skill/SKILL.md +3 -3
- package/docs/consumer-skill/references/agents-md.md +1 -1
- package/docs/consumer-skill/references/composition.md +8 -6
- package/docs/consumer-skill/references/installation.md +6 -0
- package/docs/consumer-skill/references/integration.md +4 -3
- package/docs/consumer-skill/references/public-api.json +105 -2
- package/docs/consumer-skill/references/review.md +7 -0
- package/docs/consumer-skill/references/theming.md +71 -6
- package/docs/consumer-skill/references/tokens.json +1 -1
- package/docs/consumer-skill/references/workflows.md +26 -0
- package/docs/consumer-skill/scripts/composition-policy.mjs +3 -2
- package/docs/consumer-skill/scripts/surface-policy.mjs +11 -0
- package/package.json +8 -4
- package/dist/accordion-B6a3vVgA.js.map +0 -1
- package/dist/action-menu-TzCoSlwL.js +0 -280
- package/dist/action-menu-TzCoSlwL.js.map +0 -1
- package/dist/affordance-geometry.generated-B5iu-Mkr.js +0 -69
- package/dist/affordance-geometry.generated-B5iu-Mkr.js.map +0 -1
- package/dist/ai-artifact-BMJdv-6q.js +0 -1115
- package/dist/ai-artifact-BMJdv-6q.js.map +0 -1
- package/dist/attachment-BtfhGm8i.js +0 -245
- package/dist/attachment-BtfhGm8i.js.map +0 -1
- package/dist/auth-CYxKfo69.js.map +0 -1
- package/dist/avatar-BBnEJIx8.js.map +0 -1
- package/dist/badge-MrKVNzW9.js.map +0 -1
- package/dist/batch-action-bar-BZGDG-Si.js.map +0 -1
- package/dist/breadcrumbs-D5t7I023.js.map +0 -1
- package/dist/buttons-SbIcm1HJ.js.map +0 -1
- package/dist/cards-CiiHpKYd.js +0 -66
- package/dist/cards-CiiHpKYd.js.map +0 -1
- package/dist/chart-QfrARkXl.js.map +0 -1
- package/dist/choice-inputs-t6w3ATNz.js.map +0 -1
- package/dist/code-block-Dgbu-CU3.js.map +0 -1
- package/dist/combobox-2Ic8N9bL.js +0 -278
- package/dist/combobox-2Ic8N9bL.js.map +0 -1
- package/dist/combobox-DLl0bfiq.js.map +0 -1
- package/dist/comments-BpDuCUUu.js.map +0 -1
- package/dist/data-display-DafIvCl5.js.map +0 -1
- package/dist/date-picker-CF-DtUpF.js.map +0 -1
- package/dist/date-pickers-BmzxJl5l.js +0 -174
- package/dist/date-pickers-BmzxJl5l.js.map +0 -1
- package/dist/display-DsQTVzMz.js.map +0 -1
- package/dist/dropdown-menu-E2qmdC7o.js +0 -193
- package/dist/dropdown-menu-E2qmdC7o.js.map +0 -1
- package/dist/editable-text-recipe-Bkm6wKHp.js +0 -10
- package/dist/editable-text-recipe-Bkm6wKHp.js.map +0 -1
- package/dist/feedback-qNuMBtRH.js +0 -233
- package/dist/feedback-qNuMBtRH.js.map +0 -1
- package/dist/field-affordance-recipes-qQeIf4lG.js.map +0 -1
- package/dist/filters-BkHH53uv.js.map +0 -1
- package/dist/form-field-DUt4UxSV.js.map +0 -1
- package/dist/form-sizing-By94KzXE.js.map +0 -1
- package/dist/forms-numeric-C0bvjRPZ.js.map +0 -1
- package/dist/header-BOefOKd1.js.map +0 -1
- package/dist/input-DWhBBBww.js +0 -262
- package/dist/input-DWhBBBww.js.map +0 -1
- package/dist/input-Ddi_LSYv.js +0 -20
- package/dist/input-Ddi_LSYv.js.map +0 -1
- package/dist/interaction-recipes-CHr0dJUs.js.map +0 -1
- package/dist/item-DEmDiTlD.js +0 -265
- package/dist/item-DEmDiTlD.js.map +0 -1
- package/dist/media-gallery-DcTtAaeC.js.map +0 -1
- package/dist/mentions-D-uyCh01.js.map +0 -1
- package/dist/message-CdHgIWKf.js.map +0 -1
- package/dist/metadata-list-X5rYAKSB.js.map +0 -1
- package/dist/navigation-D3KwXmaq.js.map +0 -1
- package/dist/navigation-HJf5zxlH.js.map +0 -1
- package/dist/overflow-tab-bar-sQHXLlwQ.js.map +0 -1
- package/dist/overlays-I0axtYA6.js.map +0 -1
- package/dist/pagination-3bPA_a6K.js +0 -149
- package/dist/pagination-3bPA_a6K.js.map +0 -1
- package/dist/popover-Di55PyAI.js.map +0 -1
- package/dist/popover-menu-B71Tn2Qz.js +0 -99
- package/dist/popover-menu-B71Tn2Qz.js.map +0 -1
- package/dist/popover.recipes-Bdyhj2db.js.map +0 -1
- package/dist/primitives-B-CkiEMU.js.map +0 -1
- package/dist/rich-text-editor-sMU_Scqm.js.map +0 -1
- package/dist/rich-text-editor.recipes-CadiF_Uu.js +0 -88
- package/dist/rich-text-editor.recipes-CadiF_Uu.js.map +0 -1
- package/dist/settings-CQW3b-Cu.js.map +0 -1
- package/dist/sheet-4SEvVYzA.js.map +0 -1
- package/dist/sidebar-C7WWR29L.js.map +0 -1
- package/dist/smart-card-lFKxn5Hu.js +0 -595
- package/dist/smart-card-lFKxn5Hu.js.map +0 -1
- package/dist/spinner-fa3h1Aif.js +0 -80
- package/dist/spinner-fa3h1Aif.js.map +0 -1
- package/dist/table-CIKyLUsy.js.map +0 -1
- package/dist/table-CrcLN9Io.js +0 -1458
- package/dist/table-CrcLN9Io.js.map +0 -1
- package/dist/tabs-DwBJfjxX.js.map +0 -1
- package/dist/text-inputs-aaK9wcDT.js +0 -326
- package/dist/text-inputs-aaK9wcDT.js.map +0 -1
- package/dist/theme-scope-kStaAer0.js +0 -39
- package/dist/theme-scope-kStaAer0.js.map +0 -1
- package/dist/timelines-C_SBwHNP.js +0 -442
- package/dist/timelines-C_SBwHNP.js.map +0 -1
- package/dist/tone-recipes-CPoExcTE.js.map +0 -1
- package/dist/typography-DTRkE9zL.js.map +0 -1
- package/dist/ui-provider-1D_NSYzO.js.map +0 -1
- package/dist/upload-BO8-CLN6.js.map +0 -1
- package/dist/upload-queue-EOC8g1gf.js.map +0 -1
- package/dist/usage-card-obRaBskq.js.map +0 -1
- package/dist/utils-l5LpDw2z.js.map +0 -1
- package/dist/value-inputs-TAYMX111.js.map +0 -1
- package/dist/workspace-DH0v0KcB.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"item-DEmDiTlD.js","names":["ItemGroup","ItemSeparator","Item","ItemMedia","ItemContent","ItemTitle","ItemDescription","ItemActions","ItemHeader","ItemFooter","_Fragment","BaseItem","BaseItemGroup","BaseItemSeparator","BaseItemMedia","BaseItemContent","BaseItemActions","BaseItemHeader","BaseItemFooter","BaseItemTitle","BaseItemDescription","useItemConfig","useDensityConfig","resolveComponentScale","cn","Separator","RunningTextContext","Text","focusRecipes","ICON_DESCENDANT_SIZE_CLASSNAMES","rowBlockPaddingClasses","Fragment$1","ItemGroup$1","props","className","ItemSeparator$1","itemVariants","cva","Item$1","useRender","mergeProps","itemMediaVariants","ItemMedia$1","variant","ItemContent$1","ItemTitle$1","ItemDescription$1","ItemActions$1","ItemHeader$1","ItemFooter$1","Item","forwardRef","convenienceMode","itemProps","resolvedSize","size","defaultScale","primitiveSize","resolvedVariant","defaultVariant","textSizeClass","paddingClass","padding","flushEdgeClass","borderClass","resolvedChildren","media","ItemMedia","mediaVariant","ItemContent","ItemTitle","titleBold","title","description","ItemDescription","descriptionClamp","trailing","actions","ItemActions","children","density","ItemGroup","ItemSeparator","baseVariant","iconClass","textGap","ItemHeader","ItemFooter","isSimpleText","bold","CLAMP_CLASS","clamp"],"sources":["../src/components/ui/item.tsx","../src/components/base/item/item.tsx"],"sourcesContent":["import * as React from \"react\"\nimport { mergeProps } from \"@base-ui/react/merge-props\"\nimport { useRender } from \"@base-ui/react/use-render\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../../lib/utils\"\nimport { rowBlockPaddingClasses } from \"../../lib/row-recipes\"\nimport { Separator } from \"./separator\"\nimport { focusRecipes } from \"../../lib/focus-recipes\"\n\nfunction ItemGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n role=\"list\"\n data-slot=\"item-group\"\n className={cn(\n \"group/item-group flex w-full flex-col\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction ItemSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof Separator>) {\n return (\n <Separator\n data-slot=\"item-separator\"\n orientation=\"horizontal\"\n className={cn(\"my-space-md\", className)}\n {...props}\n />\n )\n}\n\nconst itemVariants = cva(\n `group/item flex w-full flex-wrap items-center rounded-inner border text-sm transition-colors outline-none ${focusRecipes.frame} [a]:transition-colors [a]:hover:bg-accent [a]:hover:text-accent-foreground`,\n {\n variants: {\n variant: {\n default: \"border-transparent\",\n outline: \"border-border\",\n muted: \"border-transparent bg-muted/50\",\n },\n size: {\n default: cn(\"gap-space-lg px-row-x\", rowBlockPaddingClasses.comfortable),\n sm: cn(\"gap-space-lg px-row-x\", rowBlockPaddingClasses.default),\n xs: cn(\"gap-space-md px-row-x in-data-[slot=dropdown-menu-content]:p-0\", rowBlockPaddingClasses.compact),\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Item({\n className,\n variant = \"default\",\n size = \"default\",\n render,\n ...props\n}: useRender.ComponentProps<\"div\"> & VariantProps<typeof itemVariants>) {\n return useRender({\n defaultTagName: \"div\",\n props: mergeProps<\"div\">(\n {\n className: cn(itemVariants({ variant, size, className })),\n },\n props\n ),\n render,\n state: {\n slot: \"item\",\n variant,\n size,\n },\n })\n}\n\nconst itemMediaVariants = cva(\n \"flex shrink-0 items-center justify-center gap-space-md group-has-data-[slot=item-description]/item:translate-y-0.5 group-has-data-[slot=item-description]/item:self-start [&_svg]:pointer-events-none\",\n {\n variants: {\n variant: {\n default: \"bg-transparent\",\n icon: \"[&_svg:not([class*='size-'])]:size-4\",\n image:\n \"size-10 overflow-hidden rounded-inner group-data-[size=sm]/item:size-8 group-data-[size=xs]/item:size-6 group-data-[size=xs]/item:rounded-inner [&_img]:size-full [&_img]:object-cover\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nfunction ItemMedia({\n className,\n variant = \"default\",\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof itemMediaVariants>) {\n return (\n <div\n data-slot=\"item-media\"\n data-variant={variant}\n className={cn(itemMediaVariants({ variant, className }))}\n {...props}\n />\n )\n}\n\nfunction ItemContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"item-content\"\n className={cn(\n \"flex flex-1 flex-col [&+[data-slot=item-content]]:flex-none\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction ItemTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"item-title\"\n className={cn(\n \"line-clamp-1 flex w-fit items-center gap-space-md text-sm leading-snug font-medium underline-offset-4\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction ItemDescription({ className, ...props }: React.ComponentProps<\"p\">) {\n return (\n <p\n data-slot=\"item-description\"\n className={cn(\n \"m-0 line-clamp-2 text-start text-sm font-normal text-muted-foreground [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction ItemActions({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"item-actions\"\n className={cn(\"flex items-center\", className)}\n {...props}\n />\n )\n}\n\nfunction ItemHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"item-header\"\n className={cn(\n \"flex basis-full items-center justify-between gap-space-md\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction ItemFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"item-footer\"\n className={cn(\n \"flex basis-full items-center justify-between gap-space-md\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n Item,\n ItemMedia,\n ItemContent,\n ItemActions,\n ItemGroup,\n ItemSeparator,\n ItemTitle,\n ItemDescription,\n ItemHeader,\n ItemFooter,\n}\n","/**\n * Item — base wrapper around the shadcn `Item` primitive.\n *\n * Why this wrapper exists (rules 1, 8, 12, 17):\n * - Resolves `size` and `variant` against `<UIProvider>` (`useItemConfig()`),\n * so consumers set library-wide density once.\n * - Routes `ItemTitle` / `ItemDescription` text through our `<Text>` typography\n * so a title is always `weight=\"semibold\"` and secondary copy follows the\n * shared control/display tokens — no rogue `<div className=\"text-sm font-medium\">`\n * blobs at call sites.\n * - Re-exports every compound part untouched, so `<Item>` keeps working as a\n * drop-in replacement for hand-rolled \"icon-left + text-stack + actions\" rows.\n *\n * Layer rule: import from `@/components/base/item`, never from `@/components/ui/item`.\n */\nimport { forwardRef, type ComponentRef } from 'react';\n\nimport {\n\tItem as BaseItem,\n\tItemActions as BaseItemActions,\n\tItemContent as BaseItemContent,\n\tItemDescription as BaseItemDescription,\n\tItemFooter as BaseItemFooter,\n\tItemGroup as BaseItemGroup,\n\tItemHeader as BaseItemHeader,\n\tItemMedia as BaseItemMedia,\n\tItemSeparator as BaseItemSeparator,\n\tItemTitle as BaseItemTitle,\n} from '../../ui/item';\nimport { ICON_DESCENDANT_SIZE_CLASSNAMES } from '../display/icon-size';\nimport { Text } from '../../typography';\nimport { RunningTextContext } from '../../typography/running-text';\nimport { useDensityConfig, useItemConfig } from '../../../lib/ui-provider';\nimport { resolveComponentScale } from '../../../lib/ui-provider/scale';\nimport { cn } from '../../../lib/utils';\nimport { rowBlockPaddingClasses } from '../../../lib/row-recipes';\nimport { focusRecipes } from '../../../lib/focus-recipes';\n\nimport type {\n\tItemActionsProps,\n\tItemContentProps,\n\tItemDescriptionProps,\n\tItemFooterProps,\n\tItemGroupProps,\n\tItemHeaderProps,\n\tItemMediaProps,\n\tItemProps,\n\tItemTitleProps,\n} from './item.types';\n\nconst Item = forwardRef<ComponentRef<typeof BaseItem>, ItemProps>(function Item(\n\titemProps,\n\tref,\n) {\n\tconst convenienceMode = 'title' in itemProps;\n\tconst {\n\t\tsize,\n\t\tdensity = 'default',\n\t\tvariant,\n\t\tpadding = 'none',\n\t\ttextGap = 'dense',\n\t\trender,\n\t\tclassName,\n\t\tchildren,\n\t\tmedia,\n\t\tmediaVariant,\n\t\ttitle,\n\t\tdescription,\n\t\ttrailing,\n\t\tactions,\n\t\ttitleBold,\n\t\tdescriptionClamp,\n\t\t...props\n\t} = itemProps;\n\tconst { defaultVariant = 'default' } = useItemConfig();\n\tconst { defaultScale } = useDensityConfig();\n\tconst resolvedSize = resolveComponentScale(size, defaultScale);\n\tconst primitiveSize = resolvedSize === 'sm' ? 'xs' : 'sm';\n\tconst resolvedVariant = variant ?? defaultVariant;\n\tconst textSizeClass = resolvedSize === 'sm' ? 'text-pxs' : resolvedSize === 'lg' ? 'text-base' : 'text-sm';\n\tconst paddingClass = padding === 'default' ? 'px-row-x' : 'px-0';\n\t// A plain flush row draws no box, so in a group its outer edges sit on the group's\n\t// edges and the parent's gap or surface padding owns the space around the list.\n\tconst flushEdgeClass = resolvedVariant === 'default' && padding === 'none'\n\t\t? 'in-data-[slot=item-group]:first:pt-0 in-data-[slot=item-group]:last:pb-0'\n\t\t: undefined;\n\t// The default variant draws no box; a transparent 1px border only nudged its text off the shared edge.\n\t// Without a border, an interactive row draws its focus edge inset instead.\n\tconst borderClass = resolvedVariant === 'default' ? `border-0 ${focusRecipes.edge}` : undefined;\n\tconst resolvedChildren = convenienceMode ? (\n\t\t<>\n\t\t\t{media != null ? <ItemMedia variant={mediaVariant}>{media}</ItemMedia> : null}\n\t\t\t<ItemContent textGap={textGap} className=\"basis-48\">\n\t\t\t\t<ItemTitle bold={titleBold}>{title}</ItemTitle>\n\t\t\t\t{description != null ? (\n\t\t\t\t\t<ItemDescription clamp={descriptionClamp}>{description}</ItemDescription>\n\t\t\t\t) : null}\n\t\t\t</ItemContent>\n\t\t\t{trailing != null || actions != null ? (\n\t\t\t\t<ItemActions>\n\t\t\t\t\t{trailing}\n\t\t\t\t\t{actions}\n\t\t\t\t</ItemActions>\n\t\t\t) : null}\n\t\t</>\n\t) : children;\n\treturn (\n\t\t<BaseItem\n\t\t\tref={ref}\n\t\t\tsize={primitiveSize}\n\t\t\tvariant={resolvedVariant}\n\t\t\trender={render}\n\t\t\tclassName={cn(\n\t\t\t\t'item--component box-border font-sans gap-space-lg rounded-inner',\n\t\t\t\trowBlockPaddingClasses[density],\n\t\t\t\tpaddingClass,\n\t\t\t\tflushEdgeClass,\n\t\t\t\tborderClass,\n\t\t\t\ttextSizeClass,\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{resolvedChildren}\n\t\t</BaseItem>\n\t);\n});\nItem.displayName = 'Item';\n\nconst ItemGroup = forwardRef<ComponentRef<typeof BaseItemGroup>, ItemGroupProps>(function ItemGroup(\n\t{ className, role, ...props },\n\tref,\n) {\n\treturn (\n\t\t<BaseItemGroup\n\t\t\tref={ref}\n\t\t\trole={role}\n\t\t\t// Boxed rows (outline/muted) keep a small gap between boxes. Plain rows touch,\n\t\t\t// so their own density padding is the only space between them.\n\t\t\tclassName={cn('item-group--component gap-space-sm has-[>[data-slot=item][data-variant=default]]:gap-0', className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n});\nItemGroup.displayName = 'ItemGroup';\n\nconst ItemSeparator = forwardRef<\n\tComponentRef<typeof BaseItemSeparator>,\n\tParameters<typeof BaseItemSeparator>[0]\n>(function ItemSeparator({ className, ...props }, ref) {\n\treturn <BaseItemSeparator ref={ref} className={cn('item--separator', className)} {...props} />;\n});\nItemSeparator.displayName = 'ItemSeparator';\n\nconst ItemMedia = forwardRef<ComponentRef<typeof BaseItemMedia>, ItemMediaProps>(function ItemMedia(\n\t{ variant = 'default', className, ...props },\n\tref,\n) {\n\tconst baseVariant = variant === 'image' || variant === 'avatar' ? 'image' : 'default';\n\tconst iconClass =\n\t\tvariant === 'icon'\n\t\t\t? cn(\n\t\t\t\t\tICON_DESCENDANT_SIZE_CLASSNAMES.md,\n\t\t\t\t\t\"group-data-[size=xs]/item:[&_svg:not([class*='size-'])]:size-icon-sm\",\n\t\t\t\t)\n\t\t\t: undefined;\n\tconst avatarClass =\n\t\tvariant === 'avatar'\n\t\t\t? 'rounded-full group-data-[size=sm]/item:rounded-full group-data-[size=xs]/item:rounded-full'\n\t\t\t: undefined;\n\treturn (\n\t\t<BaseItemMedia\n\t\t\tref={ref}\n\t\t\tvariant={baseVariant}\n\t\t\tclassName={cn(\n\t\t\t\t'item--media',\n\t\t\t\t'group-has-data-[slot=item-description]/item:translate-y-0',\n\t\t\t\ticonClass,\n\t\t\t\tavatarClass,\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n});\nItemMedia.displayName = 'ItemMedia';\n\nconst ItemContent = forwardRef<ComponentRef<typeof BaseItemContent>, ItemContentProps>(function ItemContent(\n\t{ className, textGap = 'dense', ...props },\n\tref,\n) {\n\treturn (\n\t\t<BaseItemContent\n\t\t\tref={ref}\n\t\t\tclassName={cn('item--content min-w-0', textGap === 'dense' ? 'gap-dense group-data-[size=xs]/item:gap-dense' : 'gap-normal group-data-[size=xs]/item:gap-normal', className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n});\nItemContent.displayName = 'ItemContent';\n\nconst ItemActions = forwardRef<ComponentRef<typeof BaseItemActions>, ItemActionsProps>(function ItemActions(\n\t{ className, ...props },\n\tref,\n) {\n\treturn <BaseItemActions ref={ref} className={cn('item--actions max-w-full flex-wrap shrink-0 gap-space-xs', className)} {...props} />;\n});\nItemActions.displayName = 'ItemActions';\n\nconst ItemHeader = forwardRef<ComponentRef<typeof BaseItemHeader>, ItemHeaderProps>(function ItemHeader(\n\t{ className, ...props },\n\tref,\n) {\n\treturn <BaseItemHeader ref={ref} className={cn('item--header', className)} {...props} />;\n});\nItemHeader.displayName = 'ItemHeader';\n\nconst ItemFooter = forwardRef<ComponentRef<typeof BaseItemFooter>, ItemFooterProps>(function ItemFooter(\n\t{ className, ...props },\n\tref,\n) {\n\treturn <BaseItemFooter ref={ref} className={cn('item--footer', className)} {...props} />;\n});\nItemFooter.displayName = 'ItemFooter';\n\nconst ItemTitle = forwardRef<ComponentRef<typeof BaseItemTitle>, ItemTitleProps>(function ItemTitle(\n\t{ bold = true, className, children, ...props },\n\tref,\n) {\n\tconst isSimpleText = typeof children === 'string' || typeof children === 'number' || typeof children === 'bigint';\n\treturn (\n\t\t<BaseItemTitle\n\t\t\tref={ref}\n\t\t\tclassName={cn('item--title min-w-0 max-w-full overflow-hidden m-0 text-inherit [&>p]:m-0 [&>p]:text-start', className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{isSimpleText ? (\n\t\t\t\t// The title is a flex row, where text-overflow has no effect: the text itself\n\t\t\t\t// shrinks and ends in an ellipsis instead of clipping a long token mid-glyph.\n\t\t\t\t<Text tag=\"span\" size=\"inherit\" weight={bold ? 'semibold' : 'regular'} lineHeight=\"tight\" className=\"min-w-0 overflow-hidden text-ellipsis text-inherit\">\n\t\t\t\t\t{children}\n\t\t\t\t</Text>\n\t\t\t) : <RunningTextContext.Provider value>{children}</RunningTextContext.Provider>}\n\t\t</BaseItemTitle>\n\t);\n});\nItemTitle.displayName = 'ItemTitle';\n\nconst CLAMP_CLASS: Record<NonNullable<ItemDescriptionProps['clamp']>, string> = {\n\t1: 'line-clamp-1',\n\t2: 'line-clamp-2',\n\t3: 'line-clamp-3',\n\t4: 'line-clamp-4',\n\tnone: 'line-clamp-none',\n};\n\nconst ItemDescription = forwardRef<ComponentRef<typeof BaseItemDescription>, ItemDescriptionProps>(\n\tfunction ItemDescription({ clamp = 2, className, children, ...props }, ref) {\n\t\tconst isSimpleText = typeof children === 'string' || typeof children === 'number' || typeof children === 'bigint';\n\t\treturn (\n\t\t\t<BaseItemDescription\n\t\t\t\tref={ref}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'item--description',\n\t\t\t\t\t'm-0',\n\t\t\t\t\t!isSimpleText && 'text-xs text-muted-foreground leading-tight',\n\t\t\t\t\tCLAMP_CLASS[clamp],\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{isSimpleText ? (\n\t\t\t\t\t<Text tag=\"span\" size=\"xs\" type=\"secondary\" lineHeight=\"tight\">\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</Text>\n\t\t\t\t) : <RunningTextContext.Provider value>{children}</RunningTextContext.Provider>}\n\t\t\t</BaseItemDescription>\n\t\t);\n\t},\n);\nItemDescription.displayName = 'ItemDescription';\n\nexport {\n\tItem,\n\tItemGroup,\n\tItemSeparator,\n\tItemMedia,\n\tItemContent,\n\tItemTitle,\n\tItemDescription,\n\tItemActions,\n\tItemHeader,\n\tItemFooter,\n};\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"media-gallery-DcTtAaeC.js","names":["Text","focusRecipes","Grid","Stack","toneRecipes","Badge","fieldAffordanceRecipes","useFileDropTarget","uploadDropTargetRecipes","defaultMediaGalleryStrings","counter","makeId","SortableTile","useSortable","item","style","CSS","transform","setNodeRef","cn","isDragging","disabled","tileClassName","setActivatorNodeRef","attributes","listeners","isFirst","strings","onRemove","X","MediaGallery","forwardRef","stringsProp","useStrings","inputId","useId","inputRef","useRef","items","setItems","useState","sensors","useSensors","useSensor","PointerSensor","KeyboardSensor","sortableKeyboardCoordinates","itemsRef","useEffect","value","prev","index","remaining","next","file","it","commit","useCallback","onValueChange","addFiles","rules","accept","rule","accepted","incoming","limit","maxFiles","additions","remove","target","id","onPickerChange","list","onDragEnd","event","over","active","from","to","moved","announce","template","overId","announcements","tileIds","useMemo","isFull","className","DndContext","SortableContext","rectSortingStrategy","i","dropTargetProps","invalid","ImagePlus"],"sources":["../src/components/base/media-gallery/media-gallery.tsx"],"sourcesContent":["/**\n * MediaGallery — multi-image upload + sortable thumbnail grid. Drop a batch\n * of images onto the dashed top tile or click to open the picker; tiles\n * appear inline and can be reordered via drag (`@dnd-kit/sortable`). The\n * first tile is implicitly the \"cover\" and is marked with a small chip;\n * each tile has a hover-revealed remove button.\n *\n * Use for product galleries, mood boards, or any collection where the order\n * matters and the consumer needs the final `File[]` (and the order of those\n * files) on submit.\n *\n * Strings overridable for i18n.\n */\nimport { forwardRef, useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';\nimport type { ChangeEvent } from 'react';\nimport {\n\tDndContext,\n\ttype DragEndEvent,\n\ttype Announcements,\n\tPointerSensor,\n\tKeyboardSensor,\n\tuseSensor,\n\tuseSensors,\n} from '@dnd-kit/core';\nimport {\n\tSortableContext,\n\trectSortingStrategy,\n\tsortableKeyboardCoordinates,\n\tuseSortable,\n} from '@dnd-kit/sortable';\nimport { CSS } from '@dnd-kit/utilities';\nimport { ImagePlus, X } from 'lucide-react';\nimport { Badge } from '../badge';\nimport { Text } from '../../typography';\nimport { Grid, Stack } from '../structure';\nimport { useStrings, type StringsProp } from '../../../lib/strings';\nimport { cn } from '../../../lib/utils';\nimport { fieldAffordanceRecipes } from '../../../lib/field-affordance-recipes';\nimport { useFileDropTarget } from '../upload/use-file-drop-target';\nimport { focusRecipes } from '../../../lib/focus-recipes';\nimport { uploadDropTargetRecipes } from '../upload/upload.recipes';\nimport { toneRecipes } from '../../../lib/tone-recipes';\n\nexport interface MediaGalleryStrings {\n\taddInstruction: string;\n\thelper: string;\n\tdragOver: string;\n\tcover: string;\n\tremoveAria: string;\n\tmaxReached: string;\n\t/** Sort announcements; {name} is the filename and {position} is its one-based position. */\n\tpickedUp?: string;\n\tmovedTo?: string;\n\tdropped?: string;\n\tcancelled?: string;\n}\n\nexport const defaultMediaGalleryStrings = {\n\taddInstruction: 'Drop or click to add images',\n\thelper: '',\n\tdragOver: 'Release to select',\n\tcover: 'Cover',\n\tremoveAria: 'Remove image',\n\tmaxReached: 'You have reached the maximum number of images.',\n\tpickedUp: 'Picked up {name}.',\n\tmovedTo: '{name} moved to position {position}.',\n\tdropped: 'Dropped {name}.',\n\tcancelled: 'Sorting cancelled for {name}.',\n} satisfies MediaGalleryStrings;\n\nexport interface MediaGalleryProps {\n\t/** Selected files. Controlled. */\n\tvalue?: File[];\n\tonValueChange?: (files: File[]) => void;\n\t/** Accepted MIME types or extensions. */\n\taccept?: string;\n\t/** Caps how many files may be added. */\n\tmaxFiles?: number;\n\t/** Disables the control and blocks drops. */\n\tdisabled?: boolean;\n\t/** Applies the invalid styling. */\n\tinvalid?: boolean;\n\tclassName?: string;\n\t/** Merged onto each media tile. */\n\ttileClassName?: string;\n\t/** Overrides the upload, remove, and empty copy. */\n\tstrings?: StringsProp<MediaGalleryStrings>;\n}\n\ninterface InternalItem {\n\tid: string;\n\tfile: File;\n\tpreviewUrl: string;\n}\n\nlet counter = 0;\nconst makeId = () => `media-${Date.now().toString(36)}-${(counter++).toString(36)}`;\n\nfunction SortableTile({\n\titem,\n\tisFirst,\n\tdisabled,\n\tonRemove,\n\tstrings,\n\ttileClassName,\n}: {\n\titem: InternalItem;\n\tisFirst: boolean;\n\t/** Disables the control and blocks drops. */\n\tdisabled: boolean;\n\tonRemove: () => void;\n\t/** Overrides the upload, remove, and empty copy. */\n\tstrings: MediaGalleryStrings;\n\t/** Merged onto each media tile. */\n\ttileClassName?: string;\n}) {\n\tconst { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition, isDragging } =\n\t\tuseSortable({ id: item.id, disabled });\n\tconst style = {\n\t\ttransform: CSS.Transform.toString(transform),\n\t\ttransition,\n\t} as React.CSSProperties;\n\n\treturn (\n\t\t<div\n\t\t\tref={setNodeRef}\n\t\t\tstyle={style}\n\t\t\tclassName={cn(\n\t\t\t\t'media-gallery--item',\n\t\t\t\t'group relative aspect-square overflow-hidden rounded-radius border border-border/60 bg-muted/30',\n\t\t\t\tisDragging && `z-10 shadow-lg ring-2 ${toneRecipes.primary.halo}`,\n\t\t\t\tdisabled && 'opacity-50',\n\t\t\t\ttileClassName,\n\t\t\t)}\n\t\t>\n\t\t\t<div\n\t\t\t\tref={setActivatorNodeRef}\n\t\t\t\taria-label={item.file.name}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t`absolute inset-0 cursor-grab outline-none active:cursor-grabbing ${focusRecipes.inset}`,\n\t\t\t\t\tdisabled && 'pointer-events-none',\n\t\t\t\t)}\n\t\t\t\t{...attributes}\n\t\t\t\t{...listeners}\n\t\t\t>\n\t\t\t\t<img\n\t\t\t\t\tsrc={item.previewUrl}\n\t\t\t\t\talt={item.file.name}\n\t\t\t\t\tclassName=\"absolute inset-0 size-full object-cover\"\n\t\t\t\t\tdraggable={false}\n\t\t\t\t/>\n\t\t\t\t{isFirst && (\n\t\t\t\t\t<Badge\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\ttone=\"secondary\"\n\t\t\t\t\t\tclassName=\"media-gallery--cover absolute start-space-sm top-space-sm bg-card shadow-sm ring-1 ring-border\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{strings.cover}\n\t\t\t\t\t</Badge>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\taria-label={`${strings.removeAria}: ${item.file.name}`}\n\t\t\t\tdisabled={disabled}\n\t\t\t\tonPointerDown={(e) => e.stopPropagation()}\n\t\t\t\tonClick={(e) => {\n\t\t\t\t\te.stopPropagation();\n\t\t\t\t\tonRemove();\n\t\t\t\t}}\n\t\t\t\tclassName={cn(\n\t\t\t\t\tfieldAffordanceRecipes.target,\n\t\t\t\t\tfieldAffordanceRecipes.focus,\n\t\t\t\t\t'absolute end-space-sm top-space-sm z-10 bg-card text-foreground shadow-sm ring-1 ring-border',\n\t\t\t\t\t'opacity-100 transition-opacity sm:opacity-0 sm:group-hover:opacity-100 group-focus-within:opacity-100 focus-visible:opacity-100',\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t<X className={fieldAffordanceRecipes.icon} />\n\t\t\t</button>\n\t\t</div>\n\t);\n}\n\nexport const MediaGallery = forwardRef<HTMLDivElement, MediaGalleryProps>(function MediaGallery({\n\tvalue,\n\tonValueChange,\n\taccept = '.png,.jpg,.jpeg,.gif,.webp',\n\tmaxFiles,\n\tdisabled = false,\n\tinvalid = false,\n\tclassName,\n\ttileClassName,\n\tstrings: stringsProp,\n}: MediaGalleryProps, ref) {\n\tconst strings = useStrings(defaultMediaGalleryStrings, stringsProp);\n\tconst inputId = useId();\n\tconst inputRef = useRef<HTMLInputElement | null>(null);\n\tconst [items, setItems] = useState<InternalItem[]>([]);\n\n\tconst sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 6 } }), useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }));\n\n\t// Track the live preview-URL set in a ref so the unmount cleanup sees the\n\t// latest values without depending on render-time `items`. Without this,\n\t// the cleanup closes over the initial empty array and any object URLs\n\t// created during the lifetime of the component leak (the browser will\n\t// still hold them until the document unloads).\n\tconst itemsRef = useRef<InternalItem[]>([]);\n\titemsRef.current = items;\n\n\t// Reconcile by file identity so order changes preserve sortable ids and URLs.\n\tuseEffect(() => {\n\t\tif (!value) return;\n\t\tconst prev = itemsRef.current;\n\t\tif (prev.length === value.length && prev.every((item, index) => item.file === value[index])) return;\n\t\tconst remaining = [...prev];\n\t\tconst next = value.map((file) => {\n\t\t\tconst index = remaining.findIndex((item) => item.file === file);\n\t\t\tif (index >= 0) return remaining.splice(index, 1)[0];\n\t\t\treturn { id: makeId(), file, previewUrl: URL.createObjectURL(file) };\n\t\t});\n\t\tremaining.forEach((item) => URL.revokeObjectURL(item.previewUrl));\n\t\titemsRef.current = next;\n\t\tsetItems(next);\n\t}, [value]);\n\n\t// Cleanup on unmount — revoke whatever previews were live at the time.\n\tuseEffect(() => {\n\t\treturn () => {\n\t\t\titemsRef.current.forEach((it) => URL.revokeObjectURL(it.previewUrl));\n\t\t\titemsRef.current = [];\n\t\t};\n\t}, []);\n\n\tconst commit = useCallback((next: InternalItem[]) => {\n\t\titemsRef.current = next;\n\t\tsetItems(next);\n\t\tonValueChange?.(next.map((item) => item.file));\n\t}, [onValueChange]);\n\n\tconst addFiles = useCallback((incoming: File[]) => {\n\t\tif (disabled) return;\n\t\tconst prev = itemsRef.current;\n\t\tconst rules = accept.split(',').map((rule) => rule.trim().toLowerCase()).filter(Boolean);\n\t\tconst accepted = incoming.filter((file) => rules.length === 0 || rules.some((rule) => {\n\t\t\tif (rule.startsWith('.')) return file.name.toLowerCase().endsWith(rule);\n\t\t\tif (rule.endsWith('/*')) return file.type.toLowerCase().startsWith(rule.slice(0, -1));\n\t\t\treturn file.type.toLowerCase() === rule;\n\t\t}));\n\t\tconst limit = maxFiles !== undefined && Number.isFinite(maxFiles) ? Math.max(0, Math.floor(maxFiles) - prev.length) : accepted.length;\n\t\tconst additions = accepted.slice(0, limit).map((file) => ({ id: makeId(), file, previewUrl: URL.createObjectURL(file) }));\n\t\tif (additions.length > 0) commit([...prev, ...additions]);\n\t}, [accept, commit, disabled, maxFiles]);\n\n\tconst remove = useCallback((id: string) => {\n\t\tif (disabled) return;\n\t\tconst prev = itemsRef.current;\n\t\tconst target = prev.find((item) => item.id === id);\n\t\tif (!target) return;\n\t\tURL.revokeObjectURL(target.previewUrl);\n\t\tcommit(prev.filter((item) => item.id !== id));\n\t}, [commit, disabled]);\n\n\tconst onPickerChange = useCallback(\n\t\t(e: ChangeEvent<HTMLInputElement>) => {\n\t\t\tconst list = e.target.files;\n\t\t\tif (!list || list.length === 0) return;\n\t\t\taddFiles(Array.from(list));\n\t\t\tif (inputRef.current) inputRef.current.value = '';\n\t\t},\n\t\t[addFiles],\n\t);\n\n\tconst { isDragging, dropTargetProps } = useFileDropTarget({ disabled, onFiles: addFiles });\n\tconst onDragEnd = useCallback((event: DragEndEvent) => {\n\t\tif (disabled) return;\n\t\tconst { active, over } = event;\n\t\tif (!over || active.id === over.id) return;\n\t\tconst prev = itemsRef.current;\n\t\tconst from = prev.findIndex((item) => item.id === active.id);\n\t\tconst to = prev.findIndex((item) => item.id === over.id);\n\t\tif (from < 0 || to < 0) return;\n\t\tconst next = [...prev];\n\t\tconst [moved] = next.splice(from, 1);\n\t\tnext.splice(to, 0, moved);\n\t\tcommit(next);\n\t}, [commit, disabled]);\n\n\tconst announce = (template: string, id: string | number, overId?: string | number) => template\n\t\t.replace('{name}', items.find(item => item.id === id)?.file.name ?? strings.removeAria)\n\t\t.replace('{position}', String(items.findIndex(item => item.id === (overId ?? id)) + 1));\n\tconst announcements: Announcements = {\n\t\tonDragStart: ({ active }) => announce(strings.pickedUp ?? defaultMediaGalleryStrings.pickedUp, active.id),\n\t\tonDragOver: ({ active, over }) => over ? announce(strings.movedTo ?? defaultMediaGalleryStrings.movedTo, active.id, over.id) : undefined,\n\t\tonDragEnd: ({ active }) => announce(strings.dropped ?? defaultMediaGalleryStrings.dropped, active.id),\n\t\tonDragCancel: ({ active }) => announce(strings.cancelled ?? defaultMediaGalleryStrings.cancelled, active.id),\n\t};\n\tconst tileIds = useMemo(() => items.map((it) => it.id), [items]);\n\tconst isFull = maxFiles !== undefined && items.length >= maxFiles;\n\n\treturn (\n\t\t<Stack ref={ref} gap=\"lg\" className={cn('media-gallery--component', className)}>\n\t\t\t<DndContext sensors={sensors} onDragEnd={onDragEnd} accessibility={{ announcements }}>\n\t\t\t\t<SortableContext items={tileIds} strategy={rectSortingStrategy}>\n\t\t\t\t\t<Grid columns={{ base: 2, sm: 3, md: 4 }} gap=\"md\">\n\t\t\t\t\t\t{items.map((item, i) => (\n\t\t\t\t\t\t\t<SortableTile\n\t\t\t\t\t\t\t\tkey={item.id}\n\t\t\t\t\t\t\t\titem={item}\n\t\t\t\t\t\t\t\tisFirst={i === 0}\n\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\tonRemove={() => remove(item.id)}\n\t\t\t\t\t\t\t\tstrings={strings}\n\t\t\t\t\t\t\t\ttileClassName={tileClassName}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t))}\n\n\t\t\t\t\t\t{!isFull && (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t{...dropTargetProps}\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t'relative flex aspect-square items-center justify-center rounded-radius border border-dashed text-center outline-none transition-colors',\n\t\t\t\t\t\t\t\t\tuploadDropTargetRecipes.hover,\n\t\t\t\t\t\t\t\t\t// Keyboard focus on the file input frames the tile like any field; an\n\t\t\t\t\t\t\t\t\t// invalid tile keeps its destructive border and tints the halo.\n\t\t\t\t\t\t\t\t\t'has-[input:focus-visible]:ring-3',\n\t\t\t\t\t\t\t\t\tinvalid ? cn(uploadDropTargetRecipes.invalid, uploadDropTargetRecipes.focus.input.invalid) : cn(uploadDropTargetRecipes.idle, uploadDropTargetRecipes.focus.input.valid),\n\t\t\t\t\t\t\t\t\tdisabled && 'cursor-not-allowed opacity-50',\n\t\t\t\t\t\t\t\t\t!disabled && isDragging && uploadDropTargetRecipes.dragging,\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<input\n\t\t\t\t\t\t\t\t\tid={inputId}\n\t\t\t\t\t\t\t\t\tref={inputRef}\n\t\t\t\t\t\t\t\t\ttype=\"file\"\n\t\t\t\t\t\t\t\t\tclassName=\"absolute inset-0 z-10 size-full cursor-pointer opacity-0 disabled:cursor-not-allowed\"\n\t\t\t\t\t\t\t\t\taria-label={strings.addInstruction}\n\t\t\t\t\t\t\t\t\taria-invalid={invalid || undefined}\n\t\t\t\t\t\t\t\t\taccept={accept}\n\t\t\t\t\t\t\t\t\tmultiple\n\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\tonChange={onPickerChange}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<Stack align=\"center\" gap=\"sm\" className=\"px-space-sm\">\n\t\t\t\t\t\t\t\t\t<ImagePlus className=\"size-icon-lg text-muted-foreground\" aria-hidden=\"true\" />\n\t\t\t\t\t\t\t\t\t<Text weight=\"medium\" align=\"center\">\n\t\t\t\t\t\t\t\t\t\t{isDragging ? strings.dragOver : strings.addInstruction}\n\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</Grid>\n\t\t\t\t</SortableContext>\n\t\t\t</DndContext>\n\n\t\t\t{!!isFull && (\n\t\t\t\t<Text size=\"xs\" type=\"secondary\">\n\t\t\t\t\t{strings.maxReached}\n\t\t\t\t</Text>\n\t\t\t)}\n\t\t\t{!isFull && !!strings.helper && (\n\t\t\t\t<Text size=\"xs\" type=\"secondary\">\n\t\t\t\t\t{strings.helper}\n\t\t\t\t</Text>\n\t\t\t)}\n\t\t</Stack>\n\t);\n});\n\nMediaGallery.displayName = 'MediaGallery';\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mentions-D-uyCh01.js","names":["_Fragment","_Fragment","DisplayLabel","Text","TextLink","focusRecipes","Stack","surfaceDividerRecipes","collectionRowClasses","popoverRecipes","collectionRecipes","interactionRecipes","sanitizeHtml","contentTypographyClassName","Badge","CommandItem","CommandInput","CommandEmpty","CommandList","CommandGroup","Command","PopoverHeader","PopoverContent","useDebouncedCallback","Fragment$1","isAbortError","error","useMentionsSearch","options","kindsKey","resources","kinds","useMemo","activeKind","setActiveKindState","useState","manualKindOverride","setManualKindOverride","query","setQueryState","suggestionsByKind","setSuggestionsByKind","isLoading","setIsLoading","setError","errorsByKind","setErrorsByKind","retryTick","setRetryTick","mentions","setMentionsState","initialMentions","requestIdRef","useRef","abortControllerRef","resourcesRef","onResourceSearchRef","onResourceSearch","onErrorRef","onError","useEffect","activeResource","searchOneKind","useCallback","config","kind","q","s","stat","runSearch","entries","searchKinds","nextQuery","signal","searchError","requestId","next","nextErrors","firstError","entry","debounceMs","controller","detach","retry","current","first","k","setActiveKind","setQuery","addMention","prev","m","mention","removeMention","id","setMentions","reset","selectSuggestion","suggestion","cfg","href","buildMentionHtml","safeLabel","tone","trigger","useMentions","search","pickerOpen","setPickerOpenState","triggerActive","setTriggerActive","triggerStateRef","lastTriggerCharRef","setPickerOpen","open","editorRef","handleCaretChange","triggerMap","trig","ctx","triggers","c","re","match","triggerChar","needle","consumedLength","pickSuggestion","html","TONE_TO_VARIANT","MentionChip","resource","variant","Icon","inner","cn","className","trailing","asLink","onClick","MENTION_RE","splitHtmlByMentions","segments","lastIndex","full","refId","before","tail","DEFAULT_PROSE_CLASS","MentionContent","resourcesProp","props","sanitized","sanitizer","mentionsById","renderRef","renderMention","body","segment","Fragment","index","prose","MentionKindToggles","active","count","counts","Button","onKindChange","defaultMentionPickerStrings","defaultMentionInlineSuggestionsStrings","MentionPicker","stringsProp","strings","useStrings","loading","Loader2","suggestions","onSelect","MentionInlineSuggestions","onManualKindChange","REF_RE","KIND_ATTR_RE","parseMentionsFromHtml","out","seen","tagText","label"],"sources":["../src/components/features/mentions/hooks/use-mentions-search.ts","../src/components/features/mentions/utils/build-mention-html.ts","../src/components/features/mentions/hooks/use-mentions.ts","../src/components/features/mentions/partials/mention-chip.tsx","../src/components/features/mentions/utils/split-html-by-mentions.ts","../src/components/features/mentions/partials/mention-content.tsx","../src/components/features/mentions/partials/mention-kind-toggles.tsx","../src/components/features/mentions/mentions.strings.ts","../src/components/features/mentions/partials/mention-picker.tsx","../src/components/features/mentions/partials/mention-inline-suggestions.tsx","../src/components/features/mentions/utils/parse-mentions-from-html.ts"],"sourcesContent":["/**\n * useMentionsSearch — pure search state for the mention picker.\n *\n * Runs **all registered kinds in parallel** for the same needle so the\n * caller can render mixed results in tabs and the picker can auto-\n * switch when the active kind has zero matches but another does. The\n * caller still controls which kind is *active* (the one whose\n * suggestions render); manual switches are remembered and not\n * overridden by subsequent caret-driven re-detections.\n *\n * Suggestion lookup order per kind:\n * 1. `resources[kind].search(needle)` — per-kind callback\n * 2. `resources[kind].suggestions` — static catalogue\n * 3. global `onResourceSearch(needle, kind)` — fallback\n */\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { DEFAULT_DEBOUNCE_MS, useDebouncedCallback } from '../../../../hooks/use-debounced-callback';\n\nimport type {\n\tMention,\n\tMentionResource,\n\tMentionSuggestion,\n\tMentionsResourceSearch,\n\tMentionsSearchErrorHandler,\n} from '../mentions.types';\n\nfunction isAbortError(error: unknown): boolean {\n\treturn Boolean(error && (error as { name?: string }).name === 'AbortError');\n}\n\nexport interface UseMentionsSearchOptions<TResource extends string = string> {\n\tresources?: Partial<Record<TResource, MentionResource<TResource>>>;\n\tonResourceSearch?: MentionsResourceSearch<TResource>;\n\tinitialMentions?: ReadonlyArray<Mention<TResource>>;\n\t/** Debounce window for async search. Defaults to `DEFAULT_DEBOUNCE_MS`. */\n\tdebounceMs?: number;\n\t/** Receives non-abort failures for each resource kind that could not be searched. */\n\tonError?: MentionsSearchErrorHandler<TResource>;\n}\n\nexport interface UseMentionsSearchReturn<TResource extends string = string> {\n\tkinds: ReadonlyArray<TResource>;\n\tactiveKind: TResource | null;\n\tsetActiveKind: (kind: TResource | null) => void;\n\tactiveResource: MentionResource<TResource> | null;\n\n\tquery: string;\n\tsetQuery: (q: string) => void;\n\n\t/** Suggestions for the active kind (`suggestionsByKind[activeKind]`). */\n\tsuggestions: ReadonlyArray<MentionSuggestion<TResource>>;\n\t/** Per-kind suggestion buckets — useful for cross-kind UIs. */\n\tsuggestionsByKind: Readonly<Record<string, ReadonlyArray<MentionSuggestion<TResource>>>>;\n\t/** Replaces the content with the loading state. */\n\tisLoading: boolean;\n\terror: unknown | null;\n\tisError: boolean;\n\terrorsByKind: Readonly<Partial<Record<TResource, unknown>>>;\n\tretry: () => void;\n\n\tmentions: ReadonlyArray<Mention<TResource>>;\n\taddMention: (mention: Mention<TResource>) => void;\n\tremoveMention: (id: string) => void;\n\tsetMentions: (next: ReadonlyArray<Mention<TResource>>) => void;\n\treset: () => void;\n\n\tselectSuggestion: (\n\t\tsuggestion: MentionSuggestion<TResource>,\n\t) => Mention<TResource>;\n\n\t/** True if the consumer manually picked a tab. The trigger detector\n\t * checks this and refuses to override the active kind on next caret\n\t * change while it's true. Reset on `setManualKindOverride(false)` or\n\t * `reset()`. */\n\tmanualKindOverride: boolean;\n\tsetManualKindOverride: (override: boolean) => void;\n}\n\nexport function useMentionsSearch<TResource extends string = string>(\n\toptions: UseMentionsSearchOptions<TResource> = {},\n): UseMentionsSearchReturn<TResource> {\n\tconst {\n\t\tresources,\n\t\tonResourceSearch,\n\t\tinitialMentions,\n\t\tdebounceMs = DEFAULT_DEBOUNCE_MS,\n\t\tonError,\n\t} = options;\n\n\tconst kindsKey = JSON.stringify(Object.keys(resources ?? {}));\n\tconst kinds = useMemo<ReadonlyArray<TResource>>(\n\t\t() => JSON.parse(kindsKey) as TResource[],\n\t\t[kindsKey],\n\t);\n\n\tconst [activeKind, setActiveKindState] = useState<TResource | null>(\n\t\t() => kinds[0] ?? null,\n\t);\n\tconst [manualKindOverride, setManualKindOverride] = useState(false);\n\tconst [query, setQueryState] = useState('');\n\tconst [suggestionsByKind, setSuggestionsByKind] = useState<\n\t\tRecord<string, ReadonlyArray<MentionSuggestion<TResource>>>\n\t>({});\n\tconst [isLoading, setIsLoading] = useState(false);\n\tconst [error, setError] = useState<unknown | null>(null);\n\tconst [errorsByKind, setErrorsByKind] = useState<\n\t\tPartial<Record<TResource, unknown>>\n\t>({});\n\tconst [retryTick, setRetryTick] = useState(0);\n\tconst [mentions, setMentionsState] = useState<Mention<TResource>[]>(() =>\n\t\tinitialMentions ? [...initialMentions] : [],\n\t);\n\n\tconst requestIdRef = useRef(0);\n\tconst abortControllerRef = useRef<AbortController | null>(null);\n\tconst resourcesRef = useRef(resources);\n\tconst onResourceSearchRef = useRef(onResourceSearch);\n\tconst onErrorRef = useRef(onError);\n\tresourcesRef.current = resources;\n\tonResourceSearchRef.current = onResourceSearch;\n\tonErrorRef.current = onError;\n\n\tuseEffect(() => {\n\t\tif (kinds.length === 0) {\n\t\t\tsetActiveKindState(null);\n\t\t\treturn;\n\t\t}\n\t\tif (!activeKind || !kinds.includes(activeKind)) {\n\t\t\tsetActiveKindState(kinds[0]);\n\t\t}\n\t}, [activeKind, kinds]);\n\n\tconst activeResource = useMemo(\n\t\t() => (activeKind && resources ? resources[activeKind] ?? null : null),\n\t\t[activeKind, resources],\n\t);\n\n\t/**\n\t * Search a single kind. Per-kind `search` wins, then static\n\t * `suggestions`, then the global `onResourceSearch` fallback.\n\t */\n\tconst searchOneKind = useCallback(\n\t\tasync (\n\t\t\tkind: TResource,\n\t\t\tq: string,\n\t\t\tsignal: AbortSignal,\n\t\t): Promise<ReadonlyArray<MentionSuggestion<TResource>>> => {\n\t\t\tconst config = resourcesRef.current?.[kind];\n\t\t\tif (config?.search) {\n\t\t\t\tconst result = await config.search(q, { kind, signal });\n\t\t\t\treturn result.map((s) => ({ ...s, kind }));\n\t\t\t}\n\t\t\tif (config?.suggestions) {\n\t\t\t\tconst stat = config.suggestions;\n\t\t\t\tconst filtered =\n\t\t\t\t\tq.trim().length === 0\n\t\t\t\t\t\t? stat\n\t\t\t\t\t\t: stat.filter((s) =>\n\t\t\t\t\t\t\t\ts.label.toLowerCase().includes(q.toLowerCase()),\n\t\t\t\t\t\t\t);\n\t\t\t\treturn filtered.map((s) => ({ ...s, kind }));\n\t\t\t}\n\t\t\tif (onResourceSearchRef.current) {\n\t\t\t\tconst result = await onResourceSearchRef.current(\n\t\t\t\t\tq,\n\t\t\t\t\tkind,\n\t\t\t\t\t{ kind, signal },\n\t\t\t\t);\n\t\t\t\treturn result.map((s) => ({ ...s, kind }));\n\t\t\t}\n\t\t\treturn [];\n\t\t},\n\t\t[],\n\t);\n\n\t// Debounced cross-kind search runner. Populates `suggestionsByKind`\n\t// for every registered kind in parallel.\n\tconst runSearch = useDebouncedCallback(\n\t\t(\n\t\t\tsearchKinds: ReadonlyArray<TResource>,\n\t\t\tnextQuery: string,\n\t\t\trequestId: number,\n\t\t\tsignal: AbortSignal,\n\t\t) => {\n\t\t\tvoid (async () => {\n\t\t\t\tsetIsLoading(true);\n\t\t\t\ttry {\n\t\t\t\t\tconst entries = await Promise.all(\n\t\t\t\t\t\tsearchKinds.map(async (kind) => {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst list = await searchOneKind(kind, nextQuery, signal);\n\t\t\t\t\t\t\t\treturn { kind, list, error: null };\n\t\t\t\t\t\t\t} catch (searchError) {\n\t\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t\tkind,\n\t\t\t\t\t\t\t\t\tlist: [] as ReadonlyArray<MentionSuggestion<TResource>>,\n\t\t\t\t\t\t\t\t\terror: searchError,\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t\tif (requestId !== requestIdRef.current || signal.aborted) return;\n\t\t\t\t\tconst next: Record<string, ReadonlyArray<MentionSuggestion<TResource>>> = {};\n\t\t\t\t\tconst nextErrors: Partial<Record<TResource, unknown>> = {};\n\t\t\t\t\tlet firstError: unknown | null = null;\n\t\t\t\t\tfor (const entry of entries) {\n\t\t\t\t\t\tnext[entry.kind] = entry.list;\n\t\t\t\t\t\tif (entry.error !== null && !isAbortError(entry.error)) {\n\t\t\t\t\t\t\tnextErrors[entry.kind] = entry.error;\n\t\t\t\t\t\t\tfirstError ??= entry.error;\n\t\t\t\t\t\t\tonErrorRef.current?.(entry.error, {\n\t\t\t\t\t\t\t\tquery: nextQuery,\n\t\t\t\t\t\t\t\tkind: entry.kind,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tsetSuggestionsByKind(next);\n\t\t\t\t\tsetErrorsByKind(nextErrors);\n\t\t\t\t\tsetError(firstError);\n\t\t\t\t} finally {\n\t\t\t\t\tif (requestId === requestIdRef.current && !signal.aborted) {\n\t\t\t\t\t\tsetIsLoading(false);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})();\n\t\t},\n\t\tdebounceMs,\n\t);\n\n\tuseEffect(() => {\n\t\tconst controller = new AbortController();\n\t\tabortControllerRef.current = controller;\n\n\t\tconst detach = () => {\n\t\t\tcontroller.abort();\n\t\t\tif (abortControllerRef.current === controller) {\n\t\t\t\tabortControllerRef.current = null;\n\t\t\t}\n\t\t};\n\n\t\tif (kinds.length === 0) {\n\t\t\tsetSuggestionsByKind({});\n\t\t\tsetIsLoading(false);\n\t\t\tsetError(null);\n\t\t\tsetErrorsByKind({});\n\t\t\treturn detach;\n\t\t}\n\n\t\tconst requestId = ++requestIdRef.current;\n\t\tsetError(null);\n\t\tsetErrorsByKind({});\n\t\trunSearch(kinds, query, requestId, controller.signal);\n\n\t\treturn () => {\n\t\t\trunSearch.cancel();\n\t\t\tdetach();\n\t\t};\n\t}, [kinds, query, retryTick, runSearch]);\n\n\tconst retry = useCallback(() => {\n\t\tsetRetryTick((current) => current + 1);\n\t}, []);\n\n\t/**\n\t * Auto-switch behaviour: when the active kind has zero results but\n\t * another kind has matches, jump to the first kind with results.\n\t * Skipped while `manualKindOverride` is true so the consumer's tab\n\t * choice sticks.\n\t */\n\tuseEffect(() => {\n\t\tif (manualKindOverride) return;\n\t\tif (!activeKind) return;\n\t\tconst activeList = suggestionsByKind[activeKind] ?? [];\n\t\tif (activeList.length > 0) return;\n\t\tconst first = kinds.find((k) => (suggestionsByKind[k]?.length ?? 0) > 0);\n\t\tif (first && first !== activeKind) {\n\t\t\tsetActiveKindState(first);\n\t\t}\n\t}, [activeKind, kinds, manualKindOverride, suggestionsByKind]);\n\n\t/**\n\t * Set the active kind. **Does not** toggle `manualKindOverride` —\n\t * the picker UI is responsible for calling\n\t * `setManualKindOverride(true)` when the user explicitly clicks a\n\t * tab so the auto-switch / auto-detect logic respects their choice.\n\t */\n\tconst setActiveKind = useCallback((kind: TResource | null) => {\n\t\tsetActiveKindState(kind);\n\t}, []);\n\n\tconst setQuery = useCallback((q: string) => {\n\t\tsetQueryState(q);\n\t}, []);\n\n\tconst addMention = useCallback((mention: Mention<TResource>) => {\n\t\tsetMentionsState((prev) => {\n\t\t\tif (prev.some((m) => m.id === mention.id)) return prev;\n\t\t\treturn [...prev, mention];\n\t\t});\n\t}, []);\n\n\tconst removeMention = useCallback((id: string) => {\n\t\tsetMentionsState((prev) => prev.filter((m) => m.id !== id));\n\t}, []);\n\n\tconst setMentions = useCallback(\n\t\t(next: ReadonlyArray<Mention<TResource>>) => {\n\t\t\tsetMentionsState([...next]);\n\t\t},\n\t\t[],\n\t);\n\n\tconst reset = useCallback(() => {\n\t\tabortControllerRef.current?.abort();\n\t\tsetMentionsState([]);\n\t\tsetQueryState('');\n\t\tsetManualKindOverride(false);\n\t\tsetSuggestionsByKind({});\n\t\tsetIsLoading(false);\n\t\tsetError(null);\n\t\tsetErrorsByKind({});\n\t\trequestIdRef.current++;\n\t}, []);\n\n\tconst selectSuggestion = useCallback(\n\t\t(suggestion: MentionSuggestion<TResource>) => {\n\t\t\tconst kind = (suggestion.kind ?? activeKind) as TResource;\n\t\t\tconst id = `${kind}:${suggestion.id}`;\n\t\t\tconst cfg = resources?.[kind];\n\t\t\tconst href = suggestion.href ?? cfg?.buildHref?.(suggestion);\n\t\t\tconst mention: Mention<TResource> = {\n\t\t\t\tid,\n\t\t\t\tkind,\n\t\t\t\tlabel: suggestion.label,\n\t\t\t\thref,\n\t\t\t\tdata: suggestion.data,\n\t\t\t};\n\t\t\taddMention(mention);\n\t\t\treturn mention;\n\t\t},\n\t\t[activeKind, addMention, resources],\n\t);\n\n\tconst suggestions = useMemo<ReadonlyArray<MentionSuggestion<TResource>>>(\n\t\t() => (activeKind ? suggestionsByKind[activeKind] ?? [] : []),\n\t\t[activeKind, suggestionsByKind],\n\t);\n\n\treturn {\n\t\tkinds,\n\t\tactiveKind,\n\t\tsetActiveKind,\n\t\tactiveResource,\n\t\tquery,\n\t\tsetQuery,\n\t\tsuggestions,\n\t\tsuggestionsByKind,\n\t\tisLoading,\n\t\terror,\n\t\tisError: error !== null,\n\t\terrorsByKind,\n\t\tretry,\n\t\tmentions,\n\t\taddMention,\n\t\tremoveMention,\n\t\tsetMentions,\n\t\treset,\n\t\tselectSuggestion,\n\t\tmanualKindOverride,\n\t\tsetManualKindOverride,\n\t};\n}\n","import type { Mention, MentionTone } from '../mentions.types';\n\n/**\n * Serialize a `Mention` into the HTML span that gets inserted into a\n * rich-text body. The structure mirrors `<MentionChip>` so the editor\n * can style it via the `.rsc-mention` / `[data-ref-tone]` rules (see\n * mention-chip.css, co-located in this feature) and the read-time\n * renderer (`<MentionContent>`) can find it again.\n *\n * <span class=\"rsc-mention\" data-ref-id=\"kind:id\" data-ref-kind=\"kind\"\n * data-ref-tone=\"info\" contenteditable=\"false\">@Maria Petrova</span> \n *\n * `data-ref-tone` is what drives the badge colour in both the editor\n * (CSS-only, since contenteditable can't host React) and the read-time\n * renderer (which respects it as a hint when the resource registry\n * isn't available).\n *\n * `contenteditable=\"false\"` tells the browser to treat the chip as an\n * atomic glyph — backspace deletes the whole span, the cursor moves\n * past it, and the inner label can't be edited character-by-character.\n */\nexport function buildMentionHtml<TKind extends string = string>(\n\tmention: Mention<TKind>,\n\toptions?: { triggerChar?: string; tone?: MentionTone },\n): string {\n\tconst safeLabel = String(mention.label ?? '')\n\t\t.replace(/&/g, '&')\n\t\t.replace(/</g, '<')\n\t\t.replace(/>/g, '>');\n\tconst id = String(mention.id).replace(/\"/g, '"');\n\tconst kind = String(mention.kind).replace(/\"/g, '"');\n\tconst tone = options?.tone ? String(options.tone).replace(/\"/g, '"') : '';\n\tconst trigger =\n\t\toptions?.triggerChar ?? (mention.kind === 'user' ? '@' : '');\n\tconst toneAttr = tone ? ` data-ref-tone=\"${tone}\"` : '';\n\treturn (\n\t\t`<span class=\"rsc-mention\" data-ref-id=\"${id}\" data-ref-kind=\"${kind}\"${toneAttr} contenteditable=\"false\">` +\n\t\t`${trigger}${safeLabel}` +\n\t\t`</span> `\n\t);\n}\n","/**\n * useMentions — picker state + caret-trigger detection bound to an editor.\n *\n * Composes `useMentionsSearch` (suggestion state) with caret-watch\n * logic. The editor it binds to must implement the minimal handle\n * surface in `MentionEditorHandle` — `<RichTextEditor>` from\n * `features/rich-text-editor` already does. Other editors (Slate,\n * Lexical, ProseMirror, plain contenteditable, …) can be plugged in by\n * implementing the same four methods on their imperative handle.\n *\n * Behaviour summary:\n * - On every editor `onCaretChange`, the hook reads `getCaretContext()`\n * and looks for a registered trigger char (`@`, `#`, …) preceded by\n * start-of-line / whitespace and followed by `\\p{L}\\p{N}_-` chars.\n * - On match, the picker opens, `activeKind` is seeded from the\n * trigger char (only on a *fresh* trigger session — manual tab\n * switches survive subsequent keystrokes), and `query` syncs from\n * the typed needle.\n * - All registered kinds are searched in parallel; the active kind\n * auto-switches to the first kind with results when the current\n * active is empty (skipped if `manualKindOverride` is true).\n * - `pickSuggestion` deletes the trigger range and inserts the chip\n * atomically via `replaceBeforeCaret` — selection-extension means\n * no manual text mutation, no race between delete + insert.\n * - When opened via the manual button (no trigger detected), the\n * selection runs `insertHTML` instead — caret stays where it was.\n *\n * Returned API:\n * pickerOpen, setPickerOpen, triggerActive,\n * kinds, activeKind, setActiveKind, manualKindOverride, setManualKindOverride,\n * query, setQuery, suggestions, suggestionsByKind, isLoading,\n * mentions, addMention, removeMention, setMentions, reset,\n * handleCaretChange() — wire to the editor's `onCaretChange`\n * pickSuggestion(s) — convert suggestion → Mention + insert chip\n *\n * @example\n * const editorRef = useRef<RichTextEditorHandle>(null);\n * const mentions = useMentions<'user' | 'order'>({ editorRef });\n *\n * <RichTextEditor ref={editorRef} onCaretChange={mentions.handleCaretChange} />\n * <MentionInlineSuggestions\n * open={mentions.triggerActive && mentions.pickerOpen}\n * activeKind={mentions.activeKind}\n * setActiveKind={mentions.setActiveKind}\n * onManualKindChange={() => mentions.setManualKindOverride(true)}\n * {...mentions}\n * onSelect={mentions.pickSuggestion}\n * />\n */\nimport { useCallback, useRef, useState } from 'react';\nimport type { RefObject } from 'react';\n\nimport type {\n\tMention,\n\tMentionResource,\n\tMentionSuggestion,\n\tMentionsResourceSearch,\n} from '../mentions.types';\nimport { buildMentionHtml } from '../utils/build-mention-html';\nimport {\n\tuseMentionsSearch,\n\ttype UseMentionsSearchOptions,\n\ttype UseMentionsSearchReturn,\n} from './use-mentions-search';\n\n/**\n * Minimal editor handle the trigger detector needs. Compatible with the\n * library's `<RichTextEditor>` handle — implement these on any custom\n * editor to plug in.\n */\nexport interface MentionEditorHandle {\n\tgetCaretContext(): { textBefore: string } | null;\n\tinsertHTML(html: string): void;\n\treplaceBeforeCaret(length: number, html: string): void;\n\tfocus(): void;\n}\n\nexport interface UseMentionsOptions<TResource extends string = string>\n\textends UseMentionsSearchOptions<TResource> {\n\t/** Ref to the editor surface the trigger detector reads from. */\n\teditorRef?: RefObject<MentionEditorHandle | null>;\n}\n\nexport interface UseMentionsReturn<TResource extends string = string>\n\textends UseMentionsSearchReturn<TResource> {\n\tpickerOpen: boolean;\n\tsetPickerOpen: (open: boolean) => void;\n\t/** True while the picker is open from an inline `@`/`#` trigger. */\n\ttriggerActive: boolean;\n\t/** Wire to the editor's `onCaretChange` to enable inline triggers. */\n\thandleCaretChange: () => void;\n\t/**\n\t * Convert a suggestion into a Mention, register it, insert the chip\n\t * into the editor (replacing the trigger range when one is active),\n\t * and close the picker. Returns the Mention.\n\t */\n\tpickSuggestion: (\n\t\tsuggestion: MentionSuggestion<TResource>,\n\t) => Mention<TResource>;\n}\n\ninterface TriggerState {\n\tkind: string;\n\ttriggerChar: string;\n\tconsumedLength: number;\n}\n\nexport function useMentions<TResource extends string = string>(\n\toptions: UseMentionsOptions<TResource> = {},\n): UseMentionsReturn<TResource> {\n\tconst resources = options.resources;\n\tconst onResourceSearch: MentionsResourceSearch<TResource> | undefined =\n\t\toptions.onResourceSearch;\n\n\tconst search = useMentionsSearch<TResource>({\n\t\t...options,\n\t\tresources,\n\t\tonResourceSearch,\n\t});\n\n\tconst [pickerOpen, setPickerOpenState] = useState(false);\n\tconst [triggerActive, setTriggerActive] = useState(false);\n\tconst triggerStateRef = useRef<TriggerState | null>(null);\n\t/** Tracks the trigger char from the most recent detection — lets us\n\t * set the initial active kind on a fresh trigger without overriding\n\t * the user's manual tab switch on every subsequent keystroke. */\n\tconst lastTriggerCharRef = useRef<string | null>(null);\n\n\tconst setPickerOpen = useCallback((open: boolean) => {\n\t\tsetPickerOpenState(open);\n\t\tif (!open) {\n\t\t\ttriggerStateRef.current = null;\n\t\t\tlastTriggerCharRef.current = null;\n\t\t\tsetTriggerActive(false);\n\t\t\tsearch.setManualKindOverride(false);\n\t\t}\n\t}, [search]);\n\n\tconst editorRef = options.editorRef;\n\n\tconst handleCaretChange = useCallback(() => {\n\t\tif (!resources) return;\n\t\tconst triggerMap: Record<string, string> = {};\n\t\tfor (const [kind, cfg] of Object.entries(resources)) {\n\t\t\tconst trig = (cfg as MentionResource | undefined)?.trigger;\n\t\t\tif (typeof trig === 'string' && trig.length > 0) {\n\t\t\t\ttriggerMap[trig] = kind;\n\t\t\t}\n\t\t}\n\t\tif (Object.keys(triggerMap).length === 0) return;\n\n\t\tconst ctx = editorRef?.current?.getCaretContext();\n\t\tif (!ctx) {\n\t\t\tif (triggerStateRef.current) {\n\t\t\t\ttriggerStateRef.current = null;\n\t\t\t\tsetPickerOpen(false);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tconst triggers = Object.keys(triggerMap)\n\t\t\t.map((c) => c.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'))\n\t\t\t.join('');\n\t\tconst re = new RegExp(`(?:^|\\\\s)([${triggers}])([\\\\p{L}\\\\p{N}_-]*)$`, 'u');\n\t\tconst match = ctx.textBefore.match(re);\n\t\tif (!match) {\n\t\t\tif (triggerStateRef.current) {\n\t\t\t\ttriggerStateRef.current = null;\n\t\t\t\tsetPickerOpen(false);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tconst triggerChar = match[1];\n\t\tconst needle = match[2] ?? '';\n\t\tconst kind = triggerMap[triggerChar];\n\t\tconst consumedLength = triggerChar.length + needle.length;\n\n\t\ttriggerStateRef.current = { kind, triggerChar, consumedLength };\n\t\tsetTriggerActive(true);\n\n\t\t// Only seed the initial active kind on a *fresh* trigger session.\n\t\t// If the user has already picked a tab in the panel,\n\t\t// `manualKindOverride` is true and we skip — their choice sticks\n\t\t// even as they keep typing or deleting characters.\n\t\tconst isNewTriggerSession = lastTriggerCharRef.current !== triggerChar;\n\t\tif (isNewTriggerSession) {\n\t\t\tif (search.activeKind !== kind) {\n\t\t\t\tsearch.setActiveKind(kind as TResource);\n\t\t\t}\n\t\t\tsearch.setManualKindOverride(false);\n\t\t\tlastTriggerCharRef.current = triggerChar;\n\t\t}\n\n\t\tif (search.query !== needle) {\n\t\t\tsearch.setQuery(needle);\n\t\t}\n\t\tsetPickerOpenState(true);\n\t}, [editorRef, resources, search, setPickerOpen]);\n\n\tconst pickSuggestion = useCallback(\n\t\t(suggestion: MentionSuggestion<TResource>) => {\n\t\t\tconst mention = search.selectSuggestion(suggestion);\n\t\t\tconst trigger = triggerStateRef.current;\n\t\t\tconst tone = (resources?.[mention.kind] as MentionResource | undefined)?.tone;\n\t\t\tconst html = buildMentionHtml(mention, {\n\t\t\t\ttriggerChar: trigger?.triggerChar,\n\t\t\t\ttone,\n\t\t\t});\n\n\t\t\tif (trigger && trigger.consumedLength > 0 && editorRef?.current) {\n\t\t\t\teditorRef.current.replaceBeforeCaret(trigger.consumedLength, html);\n\t\t\t\ttriggerStateRef.current = null;\n\t\t\t} else if (editorRef?.current) {\n\t\t\t\teditorRef.current.insertHTML(html);\n\t\t\t}\n\t\t\tsetPickerOpen(false);\n\t\t\treturn mention;\n\t\t},\n\t\t[editorRef, resources, search, setPickerOpen],\n\t);\n\n\treturn {\n\t\t...search,\n\t\tpickerOpen,\n\t\tsetPickerOpen,\n\t\ttriggerActive,\n\t\thandleCaretChange,\n\t\tpickSuggestion,\n\t};\n}\n","/**\n * MentionChip — default rendering for an inline mention/reference.\n *\n * Wraps the lib's `<Badge>` base component with the variant driven by\n * the resource registry's `tone` field. The mapping between the\n * mentions module's `MentionTone` and the badge's variant lives below\n * (`TONE_TO_VARIANT`) so consumers can rebrand by editing one table.\n *\n * Override paths:\n * - `renderMention` on `<MentionContent>` — full takeover\n * - `resources.<kind>.renderChip(mention)` — per-kind takeover\n * - `resources.<kind>.tone` — quickest \"just change the color\" override\n */\nimport type { FC, ReactNode } from 'react';\n\nimport { Badge, type BadgeTone } from '../../../base/badge';\nimport { Text, TextLink } from '../../../typography';\nimport { cn } from '../../../../lib/utils';\n\nimport type {\n\t\tMention,\n\t\tMentionResource,\n\t\tMentionTone,\n} from '../mentions.types';\n\nexport interface MentionChipProps {\n\t\t/** The mention this chip represents. */\n\t\tmention: Mention;\n\t\t/** The referenced resource. */\n\t\tresource?: MentionResource<string>;\n\t\t/** Force-disable the chip's link (useful inside the composer draft list). */\n\t\tasLink?: boolean;\n\t\tonClick?: () => void;\n\t\t/** Trailing slot — typically a remove button when shown in the composer. */\n\t\ttrailing?: ReactNode;\n\t\t/** Merged onto the outermost node. */\n\t\tclassName?: string;\n}\n\n/**\n * Single source of truth for `MentionTone → Badge variant`. Edit here\n * to rebrand all chips library-wide; override per-kind via\n * `resources.<kind>.tone`.\n */\nconst TONE_TO_VARIANT: Record<MentionTone, BadgeTone> = {\n\t\tprimary: 'secondary', // calm primary — saturated `primary` overwhelms body copy\n\t\tsuccess: 'success',\n\t\twarning: 'warning',\n\t\tdestructive: 'destructive',\n\t\tinfo: 'info',\n\t\tsecondary: 'secondary',\n};\n\nexport const MentionChip: FC<MentionChipProps> = ({\n\t\tmention,\n\t\tresource,\n\t\tasLink = true,\n\t\tonClick,\n\t\ttrailing,\n\t\tclassName,\n}) => {\n\t\tif (resource?.renderChip) {\n\t\t\t\treturn <>{resource.renderChip(mention)}</>;\n\t\t}\n\n\t\tconst tone = resource?.tone ?? 'secondary';\n\t\tconst variant = TONE_TO_VARIANT[tone] ?? TONE_TO_VARIANT.secondary;\n\t\tconst Icon = resource?.icon;\n\n\t\tconst inner = (\n\t\t\t\t<Badge\n\t\t\t\t\t\ttone={variant}\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tinline\n\t\t\t\t\t\tdata-ref-id={mention.id}\n\t\t\t\t\t\tdata-ref-kind={mention.kind}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t'mention-chip--component',\n\t\t\t\t\t\t\t\t/* Inline-flow tweaks: align to the surrounding text baseline\n\t\t\t\t\t\t\t\t\t instead of the line's mid-point, which causes wobble next\n\t\t\t\t\t\t\t\t\t to text. Keep the badge as `inline-flex` (from `inline`),\n\t\t\t\t\t\t\t\t\t add a subtle vertical offset via translate so the icon\n\t\t\t\t\t\t\t\t\t sits on the cap-height. */\n\t\t\t\t\t\t\t\t'align-[-0.15em] cursor-default whitespace-nowrap',\n\t\t\t\t\t\t\t\tclassName,\n\t\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t\t{Icon ? <Icon className=\"size-icon-sm shrink-0\" aria-hidden /> : null}\n\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\t\ttag=\"span\"\n\t\t\t\t\t\t\t\tsize=\"inherit\"\n\t\t\t\t\t\t\t\tweight=\"medium\"\n\t\t\t\t\t\t\t\tlineHeight=\"none\"\n\t\t\t\t\t\t\t\tclassName=\"max-w-[14rem] truncate text-inherit\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{mention.label}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t{trailing}\n\t\t\t\t</Badge>\n\t\t);\n\n\t\tif (asLink && mention.href) {\n\t\treturn (\n\t\t\t<TextLink\n\t\t\t\thref={mention.href}\n\t\t\t\tsize=\"inherit\"\n\t\t\t\tunderline={false}\n\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\trel=\"noreferrer noopener\"\n\t\t\t\t\t\t\t\tonClick={onClick}\n\t\t\t\t\t\t\t\tclassName=\"inline align-baseline no-underline hover:opacity-90\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{inner}\n\t\t\t</TextLink>\n\t\t);\n\t\t}\n\n\t\tif (onClick) {\n\t\t\t\treturn (\n\t\t\t\t\t\t<span onClick={onClick} className=\"inline align-baseline\">\n\t\t\t\t\t\t\t\t{inner}\n\t\t\t\t\t\t</span>\n\t\t\t\t);\n\t\t}\n\n\t\treturn inner;\n};\n","/**\n * Split an HTML string into a list of `html` chunks and `mention`\n * placeholders, keyed by the `data-ref-id` attribute the writer set.\n *\n * Used by `<MentionContent>` to render the body once with React chips\n * for the references and `dangerouslySetInnerHTML` for everything else.\n */\nexport type MentionHtmlSegment =\n\t| { kind: 'html'; value: string }\n\t| { kind: 'mention'; refId: string; fallback: string };\n\nconst MENTION_RE =\n\t/<(span|a)\\b([^>]*?)data-ref-id\\s*=\\s*\"([^\"]+)\"([^>]*)>([\\s\\S]*?)<\\/\\1>/gi;\n\nexport function splitHtmlByMentions(html: string): MentionHtmlSegment[] {\n\tif (!html) return [];\n\n\tconst segments: MentionHtmlSegment[] = [];\n\tlet lastIndex = 0;\n\tlet match: RegExpExecArray | null;\n\tMENTION_RE.lastIndex = 0;\n\n\twhile ((match = MENTION_RE.exec(html)) !== null) {\n\t\tconst [full, , , refId] = match;\n\t\tconst before = html.slice(lastIndex, match.index);\n\t\tif (before.length > 0) {\n\t\t\tsegments.push({ kind: 'html', value: before });\n\t\t}\n\t\tsegments.push({\n\t\t\tkind: 'mention',\n\t\t\trefId,\n\t\t\tfallback: full,\n\t\t});\n\t\tlastIndex = match.index + full.length;\n\t}\n\n\tconst tail = html.slice(lastIndex);\n\tif (tail.length > 0) {\n\t\tsegments.push({ kind: 'html', value: tail });\n\t}\n\n\treturn segments;\n}\n","/**\n * MentionContent — render an HTML body that may contain inline mention\n * spans (`<span data-ref-id=\"kind:id\">…</span>`) by swapping each ref\n * for a React `<MentionChip>` while leaving the rest of the HTML\n * untouched.\n *\n * Used by:\n * - `features/comments` — comment bodies\n * - `features/activities` — activity descriptions\n * - any other surface that renders rich-text with embedded refs\n *\n * Consumer can override per-mention rendering via `renderMention`, or\n * per-kind via the resource registry's `renderChip`.\n */\nimport { Fragment } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { contentTypographyClassName } from '../../../typography/content-typography';\n\nimport { Text } from '../../../typography';\nimport { sanitizeHtml } from '../../../../lib/sanitize-html';\nimport { cn } from '../../../../lib/utils';\n\nimport type {\n\tMention,\n\tMentionResource,\n\tMentionsConfig,\n} from '../mentions.types';\nimport { splitHtmlByMentions } from '../utils/split-html-by-mentions';\nimport { MentionChip } from './mention-chip';\n\nexport interface MentionContentProps<TResource extends string = string> {\n\t/** HTML body to render. */\n\thtml: string;\n\t/** Mentions resolved on the data — keyed by `data-ref-id`. */\n\tmentions?: ReadonlyArray<Mention<TResource>>;\n\t/** Resource registry — pass at the call site. */\n\tresources?: MentionsConfig<TResource>['resources'];\n\t/** Custom per-mention renderer — overrides resource.renderChip. */\n\trenderMention?: (mention: Mention<TResource>) => ReactNode;\n\t/** Optional sanitizer override. The package safe allowlist is the default. */\n\tsanitizer?: (html: string) => string;\n\t/** Outer wrapper class. Defaults to a tight prose surface. */\n\tclassName?: string;\n\t/**\n\t * Set to `false` to skip the default prose wrapper — useful when\n\t * embedding inside an existing typed surface (e.g. timeline rows).\n\t */\n\tprose?: boolean;\n}\n\nconst DEFAULT_PROSE_CLASS = contentTypographyClassName;\n\nexport function MentionContent<TResource extends string = string>(\n\tprops: MentionContentProps<TResource>,\n): ReactNode {\n\tconst {\n\t\thtml,\n\t\tmentions,\n\t\tresources: resourcesProp,\n\t\trenderMention,\n\t\tsanitizer,\n\t\tclassName,\n\t\tprose = true,\n\t} = props;\n\n\tconst resources = resourcesProp;\n\n\tconst sanitized = sanitizer\n\t\t? sanitizer(html ?? '')\n\t\t: sanitizeHtml(html ?? '');\n\n\tconst mentionsById = new Map<string, Mention<TResource>>();\n\tfor (const m of mentions ?? []) mentionsById.set(m.id, m);\n\n\tconst hasMentions = mentionsById.size > 0;\n\tconst segments = hasMentions\n\t\t? splitHtmlByMentions(sanitized)\n\t\t: [{ kind: 'html' as const, value: sanitized }];\n\n\tconst renderRef = (mention: Mention<TResource>): ReactNode => {\n\t\tif (renderMention) return renderMention(mention);\n\t\tconst resource = resources?.[mention.kind] as\n\t\t\t| MentionResource<string>\n\t\t\t| undefined;\n\t\treturn <MentionChip mention={mention} resource={resource} />;\n\t};\n\n\tconst body = segments.map((segment, index) => {\n\t\tif (segment.kind === 'mention') {\n\t\t\tconst mention = mentionsById.get(segment.refId);\n\t\t\tif (!mention) {\n\t\t\t\treturn (\n\t\t\t\t\t<span\n\t\t\t\t\t\tkey={`fallback-${index}`}\n\t\t\t\t\t\tdangerouslySetInnerHTML={{ __html: segment.fallback }}\n\t\t\t\t\t/>\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn (\n\t\t\t\t<Fragment key={`ref-${index}-${segment.refId}`}>\n\t\t\t\t\t{renderRef(mention)}\n\t\t\t\t</Fragment>\n\t\t\t);\n\t\t}\n\t\t// Segments have already passed through the package allowlist (or the\n\t\t// consumer's explicit sanitizer override) before mention extraction.\n\t\treturn (\n\t\t\t<span\n\t\t\t\tkey={`html-${index}`}\n\t\t\t\tdangerouslySetInnerHTML={{ __html: segment.value }}\n\t\t\t/>\n\t\t);\n\t});\n\n\tif (!prose) {\n\t\treturn <>{body}</>;\n\t}\n\n\treturn (\n\t\t<Text tag=\"div\" className={cn('mention-content--component', DEFAULT_PROSE_CLASS, className)}>{body}</Text>\n\t);\n}\n","import { Button } from '../../../base/buttons';\nimport { Text } from '../../../typography';\nimport { interactionRecipes } from '../../../../lib/interaction-recipes';\n\nimport type { MentionResource, MentionSuggestion } from '../mentions.types';\n\ninterface MentionKindTogglesProps<TResource extends string> {\n\tkinds: ReadonlyArray<TResource>;\n\tactiveKind: TResource | null;\n\tresources?: Partial<Record<TResource, MentionResource<TResource>>>;\n\t/** Per-kind results; a count follows the label when present. */\n\tcounts?: Readonly<Record<string, ReadonlyArray<MentionSuggestion<TResource>>>>;\n\tonKindChange: (kind: TResource) => void;\n}\n\n/**\n * The resource-kind filter shared by the inline suggestions and the picker:\n * compact toggles that press with the accent fill and hover with muted, like\n * every other toggle, rather than a primary command fill.\n */\nexport function MentionKindToggles<TResource extends string>({\n\tkinds,\n\tactiveKind,\n\tresources,\n\tcounts,\n\tonKindChange,\n}: MentionKindTogglesProps<TResource>) {\n\treturn (\n\t\t<div className=\"mention-kind-toggles--component flex flex-wrap gap-space-xs\">\n\t\t\t{kinds.map((kind) => {\n\t\t\t\tconst cfg = resources?.[kind];\n\t\t\t\tconst Icon = cfg?.icon;\n\t\t\t\tconst active = kind === activeKind;\n\t\t\t\tconst count = counts?.[kind as string]?.length ?? 0;\n\t\t\t\treturn (\n\t\t\t\t\t<Button\n\t\t\t\t\t\tkey={kind}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\taria-pressed={active}\n\t\t\t\t\t\ttone=\"secondary\"\n\t\t\t\t\t\tbuttonStyle=\"ghost\"\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tclassName={active ? interactionRecipes.togglePressed : interactionRecipes.toggleHoverButton}\n\t\t\t\t\t\tonClick={() => onKindChange(kind)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{Icon ? <Icon className=\"size-icon-sm\" /> : null}\n\t\t\t\t\t\t<Text tag=\"span\" size=\"inherit\" weight=\"medium\" className=\"text-inherit\">\n\t\t\t\t\t\t\t{cfg?.label ?? String(kind)}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t{count > 0 && (\n\t\t\t\t\t\t\t<Text tag=\"span\" size=\"xs\" type=\"secondary\" className=\"tabular-nums\">\n\t\t\t\t\t\t\t\t{count}\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</Button>\n\t\t\t\t);\n\t\t\t})}\n\t\t</div>\n\t);\n}\n","/**\n * Default user-facing strings for the `features/mentions` partials.\n *\n * Both `<MentionPicker>` and `<MentionInlineSuggestions>` consume their\n * respective slice; `<MentionInlineSuggestions>` is a strict subset.\n * Consumers wire backend i18n at the call site:\n *\n * <MentionPicker strings={{ empty: t('mentions.empty') }} … />\n */\n\nexport interface MentionPickerStrings {\n\t/** Surface title. */\n\ttitle: string;\n\tsearchPlaceholder: string;\n\t/** Shown in place of the collection when it has no entries. */\n\tempty: string;\n\tloading: string;\n}\n\nexport const defaultMentionPickerStrings: MentionPickerStrings = {\n\ttitle: 'Insert reference',\n\tsearchPlaceholder: 'Search…',\n\tempty: 'No matches.',\n\tloading: 'Searching…',\n};\n\nexport interface MentionInlineSuggestionsStrings {\n\t/** Surface title. */\n\ttitle: string;\n\t/** Shown in place of the collection when it has no entries. */\n\tempty: string;\n\tloading: string;\n}\n\nexport const defaultMentionInlineSuggestionsStrings: MentionInlineSuggestionsStrings = {\n\ttitle: 'Insert reference',\n\tempty: 'No matches.',\n\tloading: 'Searching…',\n};\n","/**\n * MentionPicker — popover content for the mention/reference picker.\n *\n * Pure UI: takes the state from `useMentions` (or any equivalent hook)\n * and renders kind tabs + a cmdk search list. Wrapped in `<Popover>` by\n * the consumer:\n *\n * <Popover open={mentions.pickerOpen} onOpenChange={mentions.setPickerOpen}>\n * <PopoverTrigger ... />\n * <MentionPicker ... />\n * </Popover>\n */\nimport { Loader2 } from 'lucide-react';\n\nimport {\n\tCommand,\n\tCommandEmpty,\n\tCommandGroup,\n\tCommandInput,\n\tCommandItem,\n\tCommandList,\n} from '../../../base/command';\nimport { PopoverHeader, PopoverContent } from '../../../base/popover';\nimport { DisplayLabel, Text } from '../../../typography';\nimport { useStrings, type StringsProp } from '../../../../lib/strings';\nimport { Stack } from '../../../base/structure';\nimport { cn } from '../../../../lib/utils';\nimport { MentionKindToggles } from './mention-kind-toggles';\n\nimport {\n\tdefaultMentionPickerStrings,\n\ttype MentionPickerStrings,\n} from '../mentions.strings';\nimport type {\n\tMentionResource,\n\tMentionSuggestion,\n} from '../mentions.types';\n\nexport type { MentionPickerStrings };\n\nexport interface MentionPickerProps<TResource extends string = string> {\n\t/** Whether the picker is showing. */\n\topen: boolean;\n\t/** Resource kind currently being browsed. */\n\tactiveKind: TResource | null;\n\t/** Switches which resource kind is browsed. */\n\tsetActiveKind: (kind: TResource | null) => void;\n\t/** Resource kinds offered as tabs. */\n\tkinds: ReadonlyArray<TResource>;\n\t/** Resource definitions supplying each kind's label and icon. */\n\tresources?: Partial<Record<TResource, MentionResource<TResource>>>;\n\t/** Current search text. */\n\tquery: string;\n\t/** Updates the search text. */\n\tsetQuery: (query: string) => void;\n\t/** Matches for the current query. */\n\tsuggestions: ReadonlyArray<MentionSuggestion<TResource>>;\n\t/** Replaces the content with the loading state. */\n\tloading: boolean;\n\t/** Fired when an entry is activated. */\n\tonSelect: (suggestion: MentionSuggestion<TResource>) => void;\n\t/** Overrides this surface's own copy. */\n\tstrings?: StringsProp<MentionPickerStrings>;\n\t/** Merged onto the outermost node. */\n\tclassName?: string;\n}\n\nexport function MentionPicker<TResource extends string = string>({\n\topen,\n\tactiveKind,\n\tsetActiveKind,\n\tkinds,\n\tresources,\n\tquery,\n\tsetQuery,\n\tsuggestions,\n\tloading,\n\tonSelect,\n\tstrings: stringsProp,\n\tclassName,\n}: MentionPickerProps<TResource>) {\n\tconst strings = useStrings(defaultMentionPickerStrings, stringsProp);\n\tif (!open) return null;\n\n\treturn (\n\t\t<PopoverContent\n\t\t\talign=\"start\"\n\t\t\tinset=\"flush\"\n type=\"menu\"\n\t\t\tclassName={cn('mention-picker--component', 'w-72 gap-0 overflow-hidden', className)}\n\t\t>\n\t\t\t<PopoverHeader>\n\t\t\t\t<Stack gap=\"sm\">\n\t\t\t\t\t<DisplayLabel>\n\t\t\t\t\t\t{strings.title}\n\t\t\t\t\t</DisplayLabel>\n\t\t\t\t\t{kinds.length > 1 && (\n\t\t\t\t\t\t<MentionKindToggles kinds={kinds} activeKind={activeKind} resources={resources} onKindChange={setActiveKind} />\n\t\t\t\t\t)}\n\t\t\t\t</Stack>\n\t\t\t</PopoverHeader>\n\n\t\t\t<Command shouldFilter={false} inset=\"flush\" className=\"rounded-none\">\n\t\t\t\t<CommandInput\n\t\t\t\t\tplaceholder={strings.searchPlaceholder}\n\t\t\t\t\tvalue={query}\n\t\t\t\t\tonValueChange={setQuery}\n\t\t\t\t/>\n\t\t\t\t<CommandList>\n\t\t\t\t\t{loading ? (\n\t\t\t\t\t\t<Stack direction=\"horizontal\" align=\"center\" gap=\"sm\" className=\"px-row-x py-row-y text-muted-foreground\">\n\t\t\t\t\t\t\t<Loader2 className=\"size-icon-sm animate-spin\" aria-hidden />\n\t\t\t\t\t\t\t<Text tag=\"span\" size=\"xs\" type=\"secondary\">\n\t\t\t\t\t\t\t\t{strings.loading}\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t</Stack>\n\t\t\t\t\t) : null}\n\t\t\t\t\t<CommandEmpty>{strings.empty}</CommandEmpty>\n\t\t\t\t\t<CommandGroup>\n\t\t\t\t\t\t{suggestions.map((suggestion) => {\n\t\t\t\t\t\t\tconst kind = suggestion.kind ?? activeKind ?? '';\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<CommandItem\n\t\t\t\t\t\t\t\t\tkey={`${kind}:${suggestion.id}`}\n\t\t\t\t\t\t\t\t\tvalue={`${kind}:${suggestion.id}`}\n\t\t\t\t\t\t\t\t\tonSelect={() => onSelect(suggestion)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Stack gap=\"dense\" className=\"flex min-w-0 flex-1 flex-col leading-tight\">\n\t\t\t\t\t\t\t\t\t\t<Text tag=\"span\" weight=\"medium\" className=\"truncate\">\n\t\t\t\t\t\t\t\t\t\t\t{suggestion.label}\n\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t\t{suggestion.description ? (\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\tclassName=\"truncate\"\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{suggestion.description}\n\t\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t\t\t</CommandItem>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\t\t\t\t\t</CommandGroup>\n\t\t\t\t</CommandList>\n\t\t\t</Command>\n\t\t</PopoverContent>\n\t);\n}\n","/**\n * MentionInlineSuggestions — non-focus-stealing suggestion list.\n *\n * Used in the *inline-trigger* flow (user typed `@` / `#` / …): the\n * editor stays focused while this panel renders below the surface and\n * updates live as the user keeps typing. No popover, no focus trap,\n * no CommandInput — the editor IS the input, we read the needle from\n * the caret context and stream results in.\n *\n * Position is \"anchored to a wrapping element\" — the consumer puts this\n * inside a `relative`-positioned wrapper around the editor and we\n * absolute-position ourselves below it.\n */\nimport { Loader2 } from 'lucide-react';\n\nimport { DisplayLabel, Text } from '../../../typography';\nimport { useStrings, type StringsProp } from '../../../../lib/strings';\nimport { Stack } from '../../../base/structure';\nimport { cn } from '../../../../lib/utils';\n\nimport {\n\t\tdefaultMentionInlineSuggestionsStrings,\n\t\ttype MentionInlineSuggestionsStrings,\n} from '../mentions.strings';\nimport type {\n\t\tMentionResource,\n\t\tMentionSuggestion,\n} from '../mentions.types';\nimport { focusRecipes } from '../../../../lib/focus-recipes';\nimport { interactionRecipes } from '../../../../lib/interaction-recipes';\nimport { surfaceDividerRecipes } from '../../../../lib/surface-recipes';\nimport { collectionRecipes, collectionRowClasses, popoverRecipes } from '../../../base/popover/popover.recipes';\nimport { MentionKindToggles } from './mention-kind-toggles';\n\nexport type { MentionInlineSuggestionsStrings };\n\nexport interface MentionInlineSuggestionsProps<TResource extends string = string> {\n\t\t/** Whether the inline list is showing. */\n\t\topen: boolean;\n\t\t/** Resource kind currently being matched. */\n\t\tactiveKind: TResource | null;\n\t\t/** Switches which resource kind is matched. */\n\t\tsetActiveKind: (kind: TResource | null) => void;\n\t\t/** Resource kinds available to match. */\n\t\tkinds: ReadonlyArray<TResource>;\n\t\t/** Resource definitions supplying each kind's label and icon. */\n\t\tresources?: Partial<Record<TResource, MentionResource<TResource>>>;\n\t\t/** Per-kind suggestion buckets — used to render result counts on tabs. */\n\t\tsuggestionsByKind?: Readonly<Record<string, ReadonlyArray<MentionSuggestion<TResource>>>>;\n\t\t/** Matches for the text typed after the trigger character. */\n\t\tsuggestions: ReadonlyArray<MentionSuggestion<TResource>>;\n\t\t/** Replaces the content with the loading state. */\n\t\tloading: boolean;\n\t\t/** Live query the panel echoes in the header; the consumer owns the editor input. */\n\t\tquery?: string;\n\t\t/**\n\t\t * Notifies the consumer that the user manually picked a tab, so it\n\t\t * can flip the `manualKindOverride` flag on `useMentionsSearch`.\n\t\t */\n\t\tonManualKindChange?: () => void;\n\t\t/** Fired when an entry is activated. */\n\t\tonSelect: (suggestion: MentionSuggestion<TResource>) => void;\n\t\t/** Overrides this surface's own copy. */\n\t\tstrings?: StringsProp<MentionInlineSuggestionsStrings>;\n\t\t/** Merged onto the outermost node. */\n\t\tclassName?: string;\n}\n\nexport function MentionInlineSuggestions<TResource extends string = string>({\n\t\topen,\n\t\tactiveKind,\n\t\tsetActiveKind,\n\t\tkinds,\n\t\tresources,\n\t\tsuggestionsByKind,\n\t\tsuggestions,\n\t\tloading,\n\t\tquery,\n\t\tonManualKindChange,\n\t\tonSelect,\n\t\tstrings: stringsProp,\n\t\tclassName,\n}: MentionInlineSuggestionsProps<TResource>) {\n\t\tconst strings = useStrings(defaultMentionInlineSuggestionsStrings, stringsProp);\n\t\tif (!open) return null;\n\n\t\treturn (\n\t\t\t\t<div\n\t\t\t\t\t\t// `mousedown.preventDefault` keeps focus in the editor when\n\t\t\t\t\t\t// the user clicks inside the panel — clicks still bubble to\n\t\t\t\t\t\t// the underlying button so selection works normally.\n\t\t\t\t\t\tonMouseDown={(e) => e.preventDefault()}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t'mention-inline-suggestions--component',\n\t\t\t\t\t\t\t\t// An anchored popup: the shared popover chrome on the popup layer.\n\t\t\t\t\t\t\t\tpopoverRecipes.surface,\n\t\t\t\t\t\t\t\t'absolute left-0 top-full z-50 mt-space-xs w-80 max-w-[min(theme(spacing.96),100%)]',\n\t\t\t\t\t\t\t\t'overflow-hidden',\n\t\t\t\t\t\t\t\tclassName,\n\t\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t\t{/* The compact menu header band, as PopoverHeader draws it in a flush menu surface. */}\n\t\t\t\t\t\t<div className={cn('mention-inline-suggestions--header', popoverRecipes.menuRegion, surfaceDividerRecipes.anchored.header)}>\n\t\t\t\t\t\t\t\t<Stack gap=\"sm\" className=\"px-row-x\">\n\t\t\t\t\t\t\t\t\t\t<Stack direction=\"horizontal\" align=\"baseline\" justify=\"between\" gap=\"md\">\n\t\t\t\t\t\t\t\t\t\t\t\t<DisplayLabel>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{strings.title}\n\t\t\t\t\t\t\t\t\t\t\t\t</DisplayLabel>\n\t\t\t\t\t\t\t\t\t\t\t\t{query ? (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Text\n\t\t\t\t\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\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\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\t\t\t\t\tclassName=\"truncate font-mono\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t“{query}”\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t\t\t\t\t{kinds.length > 1 && (\n\t\t\t\t\t\t\t\t\t\t\t\t<MentionKindToggles\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tkinds={kinds}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tactiveKind={activeKind}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tresources={resources}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tcounts={suggestionsByKind}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tonKindChange={(kind) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetActiveKind(kind);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonManualKindChange?.();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\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</Stack>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName={cn('mention-inline-suggestions--list max-h-72 overflow-y-auto', popoverRecipes.menu)}\n\t\t\t\t\t\t\t\t{...(suggestions.length > 0\n\t\t\t\t\t\t\t\t\t\t? { role: 'listbox', 'aria-label': strings.title }\n\t\t\t\t\t\t\t\t\t\t: {})}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{loading ? (\n\t\t\t\t\t\t\t\t\t\t<Stack direction=\"horizontal\" align=\"center\" gap=\"sm\" className=\"px-row-x py-row-y text-muted-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t\t<Loader2 className=\"size-icon-sm animate-spin\" aria-hidden />\n\t\t\t\t\t\t\t\t\t\t\t\t<Text tag=\"span\" size=\"xs\" type=\"secondary\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{strings.loading}\n\t\t\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t\t\t) : null}\n\n\t\t\t\t\t\t\t\t{!loading && suggestions.length === 0 ? (\n\t\t\t\t\t\t\t\t\t\t<Text tag=\"div\" size=\"xs\" type=\"secondary\" className=\"px-row-x py-row-y\">\n\t\t\t\t\t\t\t\t\t\t\t\t{strings.empty}\n\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t) : null}\n\n\t\t\t\t\t\t\t\t{suggestions.map((suggestion) => {\n\t\t\t\t\t\t\t\t\t\tconst kind = suggestion.kind ?? activeKind ?? '';\n\t\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t\t\t// One shared collection row: the menu row height, inset and highlight.\n\t\t\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tkey={`${kind}:${suggestion.id}`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\trole=\"option\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\taria-selected={false}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata-ref-id={`${kind}:${suggestion.id}`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tonClick={() => onSelect(suggestion)}\n\t\t\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\t\t\t'mention-inline-suggestions--option w-full min-w-0 cursor-pointer border-0 bg-transparent text-left',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcollectionRowClasses('compact'),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcollectionRecipes.interactive,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tinteractionRecipes.rowHover,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tfocusRecipes.inset,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t)}\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\t\t\t<Stack gap=\"dense\" className=\"min-w-0 flex-1\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Text tag=\"span\" weight=\"medium\" className=\"truncate\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{suggestion.label}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{suggestion.description ? (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Text tag=\"span\" size=\"xs\" type=\"secondary\" className=\"truncate\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{suggestion.description}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t);\n}\n","/**\n * Walk an HTML string and extract `data-ref-id=\"kind:id\"` spans /\n * anchors as a list of `Mention` records. Used by the comment composer\n * to keep its `mentions` state in sync with what's actually present in\n * the editor — when the user backspaces a chip out of the body, the\n * draft's mentions list shrinks too.\n *\n * The output preserves first-occurrence order and deduplicates by id.\n * Caller can merge the resulting Mentions with previously known ones to\n * preserve `href` / `data` payloads that aren't expressible in HTML.\n */\nimport type { Mention } from '../mentions.types';\n\nconst REF_RE =\n\t/<(?:span|a)\\b[^>]*?data-ref-id\\s*=\\s*\"([^\"]+)\"[^>]*?>([\\s\\S]*?)<\\/(?:span|a)>/gi;\nconst KIND_ATTR_RE = /data-ref-kind\\s*=\\s*\"([^\"]+)\"/i;\n\nexport function parseMentionsFromHtml<TKind extends string = string>(\n\thtml: string,\n): Array<Mention<TKind>> {\n\tconst out: Mention<TKind>[] = [];\n\tif (!html) return out;\n\n\tconst seen = new Set<string>();\n\tlet match: RegExpExecArray | null;\n\tREF_RE.lastIndex = 0;\n\n\twhile ((match = REF_RE.exec(html)) !== null) {\n\t\tconst [tagText, id, inner] = match;\n\t\tif (seen.has(id)) continue;\n\t\tseen.add(id);\n\n\t\tconst kindMatch = tagText.match(KIND_ATTR_RE);\n\t\tconst kind = (kindMatch?.[1] ?? id.split(':')[0] ?? '') as TKind;\n\t\tconst label = (inner ?? '')\n\t\t\t.replace(/<[^>]*>/g, '')\n\t\t\t.replace(/ /g, ' ')\n\t\t\t.replace(/^[@#$&%!~]\\s*/, '')\n\t\t\t.trim();\n\n\t\tout.push({ id, kind, label });\n\t}\n\n\treturn out;\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"message-CdHgIWKf.js","names":["Text","Stack","surfaceDividerRecipes","defaultMessageStrings","hasMessageMedia","media","messageColumns","messageContentColumn","MessageContent","forwardRef","props","cn","className","MessageHeader","MessageActions","MessageBubble","scalar","children","tone","MessageStatus","Message","stringsProp","strings","useStrings","hasAvatar","avatar","align","loading","typing","author","timestamp","status","actions"],"sources":["../src/components/blocks/collaboration/message/message.types.ts","../src/components/blocks/collaboration/message/message.recipes.ts","../src/components/blocks/collaboration/message/message.tsx"],"sourcesContent":["import type { ComponentPropsWithoutRef, ReactNode } from 'react';\nimport type { StringsProp } from '../../../../lib/strings';\nexport interface MessageStrings { typing: string; loading: string }\nexport const defaultMessageStrings: MessageStrings = { typing: 'Typing…', loading: 'Loading message…' };\nexport interface MessageProps extends ComponentPropsWithoutRef<'div'> {\n /** Message direction, independent of author or service role. */\n align?: 'start' | 'end';\n /** Bubble treatment. @default muted */\n tone?: 'muted' | 'primary' | 'plain' | 'surface';\n avatar?: ReactNode;\n author?: ReactNode;\n /** Caller-formatted time; datetime supplies machine-readable time when available. */\n timestamp?: ReactNode;\n dateTime?: string;\n actions?: ReactNode;\n status?: ReactNode;\n loading?: boolean;\n typing?: boolean;\n strings?: StringsProp<MessageStrings>;\n}\nexport interface MessagePartProps extends ComponentPropsWithoutRef<'div'> {}\nexport interface MessageBubbleProps extends MessagePartProps { tone?: 'muted' | 'primary' | 'plain' | 'surface' }\nexport interface MessageStatusProps extends ComponentPropsWithoutRef<'span'> {}\n","import type { ReactNode } from 'react';\n\n/** Obvious empty slot values have no media track; rich React nodes remain untouched. */\nexport function hasMessageMedia(media: ReactNode): boolean {\n\tif (Array.isArray(media)) return media.some(hasMessageMedia);\n\treturn media !== null && media !== undefined && typeof media !== 'boolean' && media !== '';\n}\n\n/** Transcript rows and their continuation regions share the actual media track. */\nexport const messageColumns = {\n\tstart: 'grid-cols-[auto_minmax(0,1fr)]',\n\tend: 'grid-cols-[minmax(0,1fr)_auto]',\n} as const;\n\nexport const messageContentColumn = {\n\tstart: 'col-start-2',\n\tend: 'col-start-1',\n} as const;\n","import { forwardRef } from 'react';\nimport { Stack } from '../../../base/structure';\nimport { Text } from '../../../typography';\nimport { surfaceDividerRecipes } from '../../../../lib/surface-recipes';\nimport { cn } from '../../../../lib/utils';\nimport { useStrings } from '../../../../lib/strings';\nimport { defaultMessageStrings, type MessageProps, type MessagePartProps, type MessageBubbleProps, type MessageStatusProps } from './message.types';\nimport { hasMessageMedia, messageColumns, messageContentColumn } from './message.recipes';\nexport const MessageContent = forwardRef<HTMLDivElement, MessagePartProps>(function MessageContent({ className, ...props }, ref) { return <Stack {...props} ref={ref} gap=\"dense\" className={cn('message--content min-w-0 max-w-full flex-1', className)} />; });\nexport const MessageHeader = forwardRef<HTMLDivElement, MessagePartProps>(function MessageHeader({ className, ...props }, ref) { return <Stack {...props} ref={ref} direction=\"horizontal\" align=\"baseline\" gap=\"sm\" wrap className={cn('message--header', className)} />; });\nexport const MessageActions = forwardRef<HTMLDivElement, MessagePartProps>(function MessageActions({ className, ...props }, ref) { return <Stack {...props} ref={ref} direction=\"horizontal\" align=\"center\" gap=\"xs\" wrap className={cn('message--actions', className)} />; });\nexport const MessageBubble = forwardRef<HTMLDivElement, MessageBubbleProps>(function MessageBubble({ tone = 'muted', className, children, ...props }, ref) {\n const scalar = typeof children === 'string' || typeof children === 'number' || typeof children === 'bigint';\n return <div {...props} ref={ref} data-tone={tone} className={cn('message--bubble min-w-0 max-w-full rounded-radius p-surface-xs break-words', tone === 'primary' ? 'bg-primary text-primary-foreground' : tone === 'muted' ? 'bg-muted text-muted-foreground' : tone === 'surface' ? cn('bg-card text-card-foreground', surfaceDividerRecipes.frame.shell) : 'text-foreground', className)}>{scalar ? <Text className=\"text-inherit whitespace-pre-wrap\" lineHeight=\"relaxed\">{children}</Text> : children}</div>;\n});\nexport const MessageStatus = forwardRef<HTMLSpanElement, MessageStatusProps>(function MessageStatus({ children, className, ...props }, ref) { return <span {...props} ref={ref} role=\"status\" className={cn('message--status', className)}><Text tag=\"span\" size=\"xs\" type=\"secondary\">{children}</Text></span>; });\n/** Callback-free transcript presentation. Consumers own rich text, requests and delivery state. */\nexport const Message = forwardRef<HTMLDivElement, MessageProps>(function Message({ align = 'start', tone = 'muted', avatar, author, timestamp, dateTime, actions, status, loading = false, typing = false, strings: stringsProp, children, className, ...props }, ref) {\n const strings = useStrings(defaultMessageStrings, stringsProp);\n const hasAvatar = hasMessageMedia(avatar);\n return <Stack {...props} ref={ref} direction=\"horizontal\" align=\"start\" gap=\"md\" data-align={align} aria-busy={loading || typing || undefined} className={cn('message--component grid w-full min-w-0', hasAvatar ? messageColumns[align] : 'grid-cols-1', className)}>\n {hasAvatar && <Stack direction=\"horizontal\" align=\"start\" gap=\"md\" wrap={false} className=\"message--avatar shrink-0\">{avatar}</Stack>}\n <MessageContent className={cn('row-start-1', hasAvatar && messageContentColumn[align], align === 'end' && 'items-end')}>\n {(author !== undefined || timestamp !== undefined) && <MessageHeader>\n {author !== undefined && <Text tag=\"span\" weight=\"medium\">{author}</Text>}\n {timestamp !== undefined && <time dateTime={dateTime}><Text tag=\"span\" size=\"xs\" type=\"secondary\" className=\"tabular-nums\">{timestamp}</Text></time>}\n </MessageHeader>}\n <MessageBubble tone={tone}>{children}</MessageBubble>\n {(typing || loading || status !== undefined) && <MessageStatus>{typing ? strings.typing : loading ? strings.loading : status}</MessageStatus>}\n {actions !== undefined && <MessageActions>{actions}</MessageActions>}\n </MessageContent>\n </Stack>;\n});\nMessage.displayName = 'Message';\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"metadata-list-X5rYAKSB.js","names":["_Fragment","Link","DateValue","_Fragment","DisplayLabel","Text","textVariants","TooltipTrigger","TooltipContent","Tooltip","Grid","Stack","Value","Phone","Url","MonoValue","Email","EmptyValue","Link$1","Money","Time","DateTime","DatePrimitive","Badge","Separator","fieldAffordanceRecipes","React","Fragment$1","defaultMetadataListStrings","label","isEmpty","value","renderEmptyValue","cn","className","emptyLabel","assertNever","MetadataValue","props","metadataColumnRecipes","resolveMetadataColumns","columns","MetadataLabel","resolveKey","item","index","isPrimitiveMetadataValue","isMetadataValueDescriptor","renderMetadataValue","valueBase","isEmptyValue","renderItemValue","Tag","renderedClassName","MetadataInfoTrigger","triggerProps","ariaLabel","Info","MetadataItemInfo","strings","MetadataItemIcon","Icon","isCompact","MetadataList","stringsProp","useStrings","list","items","density","hasTitle","title","shouldShowSeparator","titleSeparator","rootClassName","head","layout","itemSeparatorText","itemSeparator","showItemSeparator","separator","rowPaddingY","isEndAligned","valueAlign","rowTrack","valueAlignClassName"],"sources":["../src/components/base/metadata-list/metadata-list.strings.ts","../src/components/base/metadata-list/metadata-value.tsx","../src/components/base/metadata-list/metadata-list.tsx"],"sourcesContent":["/**\n * Default user-facing strings for `<MetadataList>`.\n *\n * Consumers wire backend i18n at the call site:\n *\n * <MetadataList strings={{ infoFallback: t('metadata.info') }} … />\n */\n\nexport interface MetadataListStrings {\n\t/**\n\t * Suffix appended to the label when generating the tooltip-trigger\n\t * `aria-label` (\"<label> info\"). Receives the label as the first arg\n\t * so consumers can localise the full template.\n\t */\n\tformatInfoAriaLabel: (label: string) => string;\n\t/** Fallback `aria-label` used when the field label is not a plain string. */\n\tinfoFallback: string;\n}\n\nexport const defaultMetadataListStrings: MetadataListStrings = {\n\tformatInfoAriaLabel: (label) => `${label} info`,\n\tinfoFallback: 'Info',\n};\n","/**\n * MetadataValue — primitive-backed adapter for typed label/value facts.\n *\n * Each descriptor kind exposes only the fields its primitive consumes. Custom\n * `node` values remain untouched so app-owned composition keeps its identity.\n */\nimport type { ReactNode } from 'react';\nimport type { Locale } from 'date-fns';\n\nimport { Badge, type BadgeProps } from '../badge';\nimport {\n\tDate as DateValue,\n\tDateTime,\n\tEmail,\n\tEmptyValue,\n\tLink,\n\tMoney,\n\tMonoValue,\n\tPhone,\n\tTime,\n\tUrl,\n\tValue,\n\ttype DateInput,\n\ttype DatePreset,\n\ttype MoneyProps,\n\ttype TimeProps,\n} from '../../primitives';\nimport { EMPTY } from '../../../lib/format';\nimport { cn } from '../../../lib/utils';\n\nexport type MetadataValueKind =\n\t| 'text'\n\t| 'mono'\n\t| 'email'\n\t| 'phone'\n\t| 'url'\n\t| 'link'\n\t| 'date'\n\t| 'time'\n\t| 'datetime'\n\t| 'money'\n\t| 'badge'\n\t| 'node'\n\t| 'empty';\n\ntype MetadataDisplayValue = Exclude<ReactNode, null | undefined>;\ntype MetadataDateInput = Exclude<DateInput, null | undefined>;\n/** Styling hook shared by every descriptor. */\ntype MetadataDescriptorBase = {\n\t/** Merged onto the rendered value. */\n\tclassName?: string;\n};\n/** Empty handling shared by every descriptor that can receive a blank value. */\ntype MetadataValueFallback = {\n\t/** Copy shown when the value is empty. Defaults to an em dash. */\n\temptyLabel?: ReactNode;\n};\n/** Escape hatch for descriptors whose value can be rendered by the caller. */\ntype MetadataDisplayOverride = {\n\t/** Pre-rendered content used verbatim, bypassing this descriptor's formatting. */\n\tdisplay?: ReactNode;\n};\n\nexport type MetadataTextValueDescriptor = MetadataDescriptorBase & MetadataValueFallback & MetadataDisplayOverride & {\n\t/** Plain text. The default when `kind` is omitted. */\n\tkind?: 'text';\n\t/** The value to show. */\n\tvalue: MetadataDisplayValue;\n};\n\nexport type MetadataMonoValueDescriptor = MetadataDescriptorBase & MetadataValueFallback & MetadataDisplayOverride & {\n\t/** Monospace, for ids, hashes, and codes. */\n\tkind: 'mono';\n\t/** The value to show. */\n\tvalue: MetadataDisplayValue;\n};\n\nexport type MetadataContactValueDescriptor = MetadataDescriptorBase & MetadataValueFallback & MetadataDisplayOverride & {\n\t/** Contact value, rendered as the matching `mailto:`, `tel:`, or external link. */\n\tkind: 'email' | 'phone' | 'url';\n\t/** The address, number, or URL. */\n\tvalue: string;\n};\n\nexport type MetadataLinkValueDescriptor = MetadataDescriptorBase & MetadataValueFallback & MetadataDisplayOverride & {\n\t/** An arbitrary link, where text and destination differ. */\n\tkind: 'link';\n\t/** Destination for the entry, when it navigates. */\n\thref: string;\n\t/** Link text. Falls back to `href` when omitted. */\n\tvalue?: MetadataDisplayValue;\n};\n\nexport type MetadataDateValueDescriptor = MetadataDescriptorBase & MetadataValueFallback & {\n\t/** A calendar date. */\n\tkind: 'date';\n\t/** The date to format. */\n\tvalue: MetadataDateInput;\n\t/** date-fns `Locale` for formatting. */\n\tdateLocale?: Locale;\n\t/** date-fns pattern, overriding `datePreset`. */\n\tdateFormat?: string;\n\t/** Named date length. */\n\tdatePreset?: DatePreset;\n};\n\nexport type MetadataTimeValueDescriptor = MetadataDescriptorBase & MetadataValueFallback & {\n\t/** A time of day. */\n\tkind: 'time';\n\t/** The time to format. */\n\tvalue: MetadataDateInput;\n\t/** date-fns `Locale` for formatting. */\n\tdateLocale?: Locale;\n\t/** date-fns pattern, overriding `timePreset`. */\n\ttimeFormat?: string;\n\t/** Named time length. */\n\ttimePreset?: TimeProps['preset'];\n};\n\nexport type MetadataDateTimeValueDescriptor = MetadataDescriptorBase & MetadataValueFallback & {\n\tkind: 'datetime';\n\t/** The instant to format. */\n\tvalue: MetadataDateInput;\n\t/** date-fns `Locale` for formatting. */\n\tdateLocale?: Locale;\n\t/** date-fns pattern for the date portion. */\n\tdateFormat?: string;\n\t/** date-fns pattern for the time portion. */\n\ttimeFormat?: string;\n\t/** Named date length, used when `dateFormat` is omitted. */\n\tdatePreset?: DatePreset;\n};\n\nexport type MetadataMoneyValueDescriptor = MetadataDescriptorBase & MetadataValueFallback & {\n\t/** A monetary amount. */\n\tkind: 'money';\n\t/** The amount, in major units unless `minorUnitScale` says otherwise. */\n\tvalue: number | string;\n\t/** ISO currency code. */\n\tcurrency?: MoneyProps['currency'];\n\t/** Unit label shown after the amount. */\n\tunit?: MoneyProps['unit'];\n\t/** Divisor applied when the value arrives in minor units, e.g. `100` for cents. */\n\tminorUnitScale?: MoneyProps['minorUnitScale'];\n\t/** Explicit currency symbol, overriding the one derived from `currency`. */\n\tsymbol?: MoneyProps['symbol'];\n\t/** Whether the currency shows as a symbol, code, or name. */\n\tcurrencyDisplay?: MoneyProps['currencyDisplay'];\n\t/** Selects the compact or full presentation. */\n\tformatMode?: MoneyProps['formatMode'];\n\t/** Smallest number of decimals to show. */\n\tminimumFractionDigits?: MoneyProps['minimumFractionDigits'];\n\t/** Largest number of decimals to show. */\n\tmaximumFractionDigits?: MoneyProps['maximumFractionDigits'];\n\t/** BCP 47 locale for the amount. */\n\tlocale?: MoneyProps['locale'];\n};\n\nexport type MetadataBadgeValueDescriptor = MetadataDescriptorBase & MetadataValueFallback & MetadataDisplayOverride & {\n\t/** A status chip. */\n\tkind: 'badge';\n\t/** Badge text. */\n\tvalue: MetadataDisplayValue;\n\t/** Badge tone. */\n\tbadgeTone?: BadgeProps['tone'];\n\t/** Badge size. */\n\tbadgeSize?: BadgeProps['size'];\n};\n\nexport type MetadataNodeValueDescriptor = {\n\t/** Arbitrary content, bypassing every formatting path. */\n\tkind: 'node';\n\t/** The content to render. */\n\tnode: ReactNode;\n};\n\nexport type MetadataEmptyValueDescriptor = MetadataDescriptorBase & MetadataValueFallback & {\n\t/** A known-absent value, rendered as the empty label rather than omitted. */\n\tkind: 'empty';\n};\n\nexport type MetadataValueDescriptor =\n\t| MetadataTextValueDescriptor\n\t| MetadataMonoValueDescriptor\n\t| MetadataContactValueDescriptor\n\t| MetadataLinkValueDescriptor\n\t| MetadataDateValueDescriptor\n\t| MetadataTimeValueDescriptor\n\t| MetadataDateTimeValueDescriptor\n\t| MetadataMoneyValueDescriptor\n\t| MetadataBadgeValueDescriptor\n\t| MetadataNodeValueDescriptor\n\t| MetadataEmptyValueDescriptor;\n\nexport type MetadataValueProps = MetadataValueDescriptor;\n\nfunction isEmpty(value: unknown) {\n\treturn value === null || value === undefined || value === '';\n}\n\nfunction renderEmptyValue(className: string | undefined, emptyLabel: ReactNode = EMPTY) {\n\treturn (\n\t\t<EmptyValue className={cn('metadata-value--component', className)}>\n\t\t\t{emptyLabel}\n\t\t</EmptyValue>\n\t);\n}\n\nfunction assertNever(_value: never): never {\n\tthrow new Error('Unsupported metadata value descriptor.');\n}\n\nexport function MetadataValue(props: MetadataValueProps) {\n\tif (props.kind === 'node') return <>{props.node}</>;\n\tif (props.kind === 'empty') return renderEmptyValue(props.className, props.emptyLabel);\n\n\tif (props.kind !== 'link' && isEmpty(props.value)) {\n\t\treturn renderEmptyValue(props.className, props.emptyLabel);\n\t}\n\n\tswitch (props.kind) {\n\t\tcase undefined:\n\t\tcase 'text':\n\t\t\treturn (\n\t\t\t\t<Value className={cn('metadata-value--component', props.className)}>\n\t\t\t\t\t{props.display ?? props.value}\n\t\t\t\t</Value>\n\t\t\t);\n\t\tcase 'mono':\n\t\t\treturn (\n\t\t\t\t<MonoValue className={cn('metadata-value--component', props.className)}>\n\t\t\t\t\t{props.display ?? props.value}\n\t\t\t\t</MonoValue>\n\t\t\t);\n\t\tcase 'email':\n\t\t\treturn <Email value={props.value} display={props.display} emptyLabel={props.emptyLabel} className={cn('metadata-value--component', props.className)} />;\n\t\tcase 'phone':\n\t\t\treturn <Phone value={props.value} display={props.display} emptyLabel={props.emptyLabel} className={cn('metadata-value--component', props.className)} />;\n\t\tcase 'url':\n\t\t\treturn <Url value={props.value} display={props.display} emptyLabel={props.emptyLabel} className={cn('metadata-value--component', props.className)} />;\n\t\tcase 'link':\n\t\t\treturn (\n\t\t\t\t<Link href={props.href} emptyLabel={props.emptyLabel} className={cn('metadata-value--component', props.className)}>\n\t\t\t\t\t{props.display ?? props.value ?? props.href}\n\t\t\t\t</Link>\n\t\t\t);\n\t\tcase 'date':\n\t\t\treturn <DateValue value={props.value} format={props.dateFormat} preset={props.datePreset} locale={props.dateLocale} emptyLabel={props.emptyLabel} className={cn('metadata-value--component', props.className)} />;\n\t\tcase 'time':\n\t\t\treturn <Time value={props.value} format={props.timeFormat} preset={props.timePreset} locale={props.dateLocale} emptyLabel={props.emptyLabel} className={cn('metadata-value--component', props.className)} />;\n\t\tcase 'datetime':\n\t\t\treturn <DateTime value={props.value} format={props.dateFormat} timeFormat={props.timeFormat} preset={props.datePreset} locale={props.dateLocale} emptyLabel={props.emptyLabel} className={cn('metadata-value--component', props.className)} />;\n\t\tcase 'money':\n\t\t\treturn (\n\t\t\t\t<Money\n\t\t\t\t\tamount={props.value}\n\t\t\t\t\tcurrency={props.currency}\n\t\t\t\t\tunit={props.unit}\n\t\t\t\t\tminorUnitScale={props.minorUnitScale}\n\t\t\t\t\tsymbol={props.symbol}\n\t\t\t\t\tcurrencyDisplay={props.currencyDisplay}\n\t\t\t\t\tformatMode={props.formatMode}\n\t\t\t\t\tminimumFractionDigits={props.minimumFractionDigits}\n\t\t\t\t\tmaximumFractionDigits={props.maximumFractionDigits}\n\t\t\t\t\tlocale={props.locale}\n\t\t\t\t\temptyLabel={props.emptyLabel}\n\t\t\t\t\tclassName={cn('metadata-value--component', props.className)}\n\t\t\t\t/>\n\t\t\t);\n\t\tcase 'badge':\n\t\t\treturn (\n\t\t\t\t<Badge\n\t\t\t\t\ttone={props.badgeTone ?? 'secondary'}\n\t\t\t\t\tsize={props.badgeSize}\n\t\t\t\t\tinline\n\t\t\t\t\tclassName={cn('metadata-value--component self-start justify-self-start', props.className)}\n\t\t\t\t>\n\t\t\t\t\t{props.display ?? props.value}\n\t\t\t\t</Badge>\n\t\t\t);\n\t\tdefault:\n\t\t\treturn assertNever(props);\n\t}\n}\n\nMetadataValue.displayName = 'MetadataValue';\n","/**\n * MetadataList — flexible label/value list for entity metadata.\n *\n * Three layouts:\n * - `grid` (default): label-on-top, value-below cells for entity details.\n * - `rows`: a two-column definition list (`<dl>`) on proportional tracks.\n * Rules between rows are opt-in through `itemSeparator`.\n * - `inline`: label/separator/value pairs that wrap, suitable for\n * pill-style summaries (e.g. \"Created Jan 4 · By Alice · v3.2\").\n *\n * Each item supports an optional icon, tooltip, React-node value, custom\n * `render`, and per-item `emptyLabel`. Falls back to the shared `EMPTY` when\n * both are missing. Returns `null` when the list is empty so callers can render\n * unconditionally.\n */\nimport { Info } from 'lucide-react';\nimport React from 'react';\n\nimport { Separator } from '../display/separator';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../display/tooltip';\nimport { Grid, Stack, type ResponsiveValue } from '../structure';\nimport { DisplayLabel } from '../../typography/display-label';\nimport { Text } from '../../typography/text';\nimport { textVariants } from '../../typography/text.styles';\nimport { EMPTY } from '../../../lib/format';\nimport { fieldAffordanceRecipes } from '../../../lib/field-affordance-recipes';\nimport { useStrings, type StringsProp } from '../../../lib/strings';\nimport { cn } from '../../../lib/utils';\n\nimport {\n\tdefaultMetadataListStrings,\n\ttype MetadataListStrings,\n} from './metadata-list.strings';\nimport {\n\tMetadataValue,\n\ttype MetadataValueDescriptor,\n} from './metadata-value';\n\nexport type { MetadataListStrings };\nexport { defaultMetadataListStrings };\n\nexport type MetadataListItem = {\n\t/** Stable identity for this entry. Without one the label and index stand in. */\n\tid?: string;\n\t/** Display label. */\n\tlabel: React.ReactNode;\n\t/** A node, or a descriptor that names the fact's kind. */\n\tvalue?: React.ReactNode | MetadataValueDescriptor | null;\n\t/** Supporting copy shown under the value. */\n\tdescription?: React.ReactNode | null;\n\t/** Shown from an info trigger beside the label, named after the label through `strings.formatInfoAriaLabel`. */\n\ttooltip?: React.ReactNode;\n\t/** Leading glyph. Any component that accepts `className`, including Lucide icons. */\n\ticon?: React.ComponentType<{ className?: string }>;\n\t/** Shown when this item's value is absent, in place of the list's `emptyLabel`. */\n\temptyLabel?: React.ReactNode;\n\t/** Takes over the value. The output sits in the value box, so it inherits the value's type role. */\n\trender?: (item: MetadataListItem) => React.ReactNode;\n};\n\nexport type MetadataInlineListItem = Omit<MetadataListItem, 'description'> & {\n\tdescription?: never;\n};\n\nexport type MetadataLayout = 'grid' | 'rows' | 'inline';\nexport type MetadataDensity = 'default' | 'compact';\n\ntype MetadataListSharedProps = {\n\t/** How many columns the grid layout uses. Accepts a per-breakpoint value. */\n\tcolumns?: ResponsiveValue<1 | 2 | 3 | 4>;\n\t/** Row spacing. `compact` tightens the list for dense panels. */\n\tdensity?: MetadataDensity;\n\t/** Copy shown for an item whose value is empty. Defaults to an em dash. */\n\temptyLabel?: React.ReactNode;\n\t/** Surface title. */\n\ttitle?: React.ReactNode;\n\t/** Draws a rule between the title and the first item. */\n\ttitleSeparator?: boolean;\n\t/** Merged onto the outermost node. */\n\tclassName?: string;\n\t/** Character placed between a label and its value. Defaults to a colon. */\n\tseparator?: string;\n\t/**\n\t * Divider between items, off by default. In `rows`, any truthy value draws a\n\t * rule between rows (never at the ends). In `inline`, `true` places a middle\n\t * dot (`·`) and a string places that character.\n\t */\n\titemSeparator?: boolean | string;\n\t/** Per-instance string overrides (deep-merged over `defaultMetadataListStrings`). */\n\tstrings?: StringsProp<MetadataListStrings>;\n};\n\ntype MetadataGridRowsProps = MetadataListSharedProps & {\n\t/** Label/value pairs to render. */\n\titems: MetadataListItem[];\n\t/** `grid` flows items into `columns`; `rows` stacks them one per line. Default: `grid`. */\n\tlayout?: 'grid' | 'rows';\n\t/**\n\t * Rows layout only. `start` (default) places values and descriptions at the\n\t * start of proportional label/value tracks; `end` pins them to the row's end\n\t * edge, for figures that read down a column.\n\t */\n\tvalueAlign?: 'start' | 'end';\n};\n\ntype MetadataInlineProps = MetadataListSharedProps & {\n\t/** Label/value pairs run together on wrapping lines. Inline items take no description. */\n\titems: MetadataInlineListItem[];\n\t/** Runs the label/value pairs together on one line, separated by `itemSeparator`. */\n\tlayout: 'inline';\n\t/** Not used by the inline layout. */\n\tvalueAlign?: never;\n};\n\nexport type MetadataListProps =\n\t| MetadataGridRowsProps\n\t| MetadataInlineProps;\n\nconst metadataColumnRecipes: Record<1 | 2 | 3 | 4, ResponsiveValue<1 | 2 | 3 | 4>> = {\n\t1: 1,\n\t2: { base: 1, md: 2 },\n\t3: { base: 1, sm: 2, lg: 3 },\n\t4: { base: 1, sm: 2, lg: 3, xl: 4 },\n};\n\nfunction resolveMetadataColumns(\n\tcolumns: ResponsiveValue<1 | 2 | 3 | 4>,\n): ResponsiveValue<1 | 2 | 3 | 4> {\n\treturn typeof columns === 'object' ? columns : metadataColumnRecipes[columns];\n}\n\n/**\n * Item labels keep the display-label role (default size, tight leading,\n * foreground) at semibold: medium weight does not separate a label from its\n * value on every font, and the label is what a reader scans for. Labels wrap in\n * every layout, breaking long unspaced words rather than overflowing.\n */\nfunction MetadataLabel({ children }: { children: React.ReactNode }) {\n\treturn (\n\t\t<Text tag=\"span\" size=\"sm\" weight=\"semibold\" lineHeight=\"tight\" className=\"metadata-list--label metadata--field min-w-0 text-left [overflow-wrap:anywhere]\">\n\t\t\t{children}\n\t\t</Text>\n\t);\n}\n\nconst resolveKey = (item: MetadataListItem, index: number): string => {\n\tif (item.id) {\n\t\treturn item.id;\n\t}\n\n\tconst rawLabel = typeof item.label === 'string' ? item.label : `${index}`;\n\treturn `metadata-${rawLabel}-${index}`;\n};\n\nfunction isPrimitiveMetadataValue(value: React.ReactNode): value is string | number {\n\treturn typeof value === 'string' || typeof value === 'number';\n}\n\nfunction isMetadataValueDescriptor(value: unknown): value is MetadataValueDescriptor {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\t!React.isValidElement(value) &&\n\t\t!Array.isArray(value) &&\n\t\t('kind' in value || 'node' in value || 'value' in value)\n\t);\n}\n\nfunction renderMetadataValue({\n\tvalue,\n\tisEmptyValue,\n\temptyLabel,\n\tvalueBase,\n}: {\n\tvalue: React.ReactNode | MetadataValueDescriptor;\n\tisEmptyValue: boolean;\n\temptyLabel: React.ReactNode;\n\tvalueBase: string;\n}) {\n\tif (isMetadataValueDescriptor(value)) {\n\t\tif (value.kind === 'node') return <MetadataValue {...value} />;\n\t\treturn (\n\t\t\t<MetadataValue\n\t\t\t\t{...value}\n\t\t\t\temptyLabel={value.emptyLabel ?? emptyLabel}\n\t\t\t\tclassName={cn(valueBase, value.className)}\n\t\t\t/>\n\t\t);\n\t}\n\n\tif (isPrimitiveMetadataValue(value)) {\n\t\treturn (\n\t\t\t<MetadataValue\n\t\t\t\tvalue={value}\n\t\t\t\tkind={isEmptyValue ? 'empty' : 'text'}\n\t\t\t\temptyLabel={emptyLabel}\n\t\t\t\tclassName={valueBase}\n\t\t\t/>\n\t\t);\n\t}\n\n\treturn value;\n}\n\n/**\n * Generated values go through `MetadataValue`. A custom renderer's output sits\n * in the value box, so it takes the value's type role (size, leading,\n * foreground) like a generated value.\n */\nfunction renderItemValue({\n\titem,\n\tvalueBase,\n\trenderedClassName,\n\ttag: Tag = 'div',\n\temptyLabel,\n}: {\n\titem: MetadataListItem;\n\tvalueBase: string;\n\trenderedClassName: string;\n\ttag?: 'div' | 'span';\n\temptyLabel: React.ReactNode;\n}) {\n\tif (typeof item.render === 'function') {\n\t\treturn <Tag className={renderedClassName}>{item.render(item)}</Tag>;\n\t}\n\treturn renderMetadataValue({\n\t\tvalue: item.value ?? emptyLabel,\n\t\tisEmptyValue: item.value === null || item.value === undefined,\n\t\temptyLabel,\n\t\tvalueBase,\n\t});\n}\n\n/**\n * The trigger keeps the shared clear-target size for pointer comfort, while\n * negative block margins pull its box back to the glyph, so a tooltip never\n * makes its label line taller than its neighbours'.\n */\nfunction MetadataInfoTrigger({\n\ttriggerProps,\n\tariaLabel,\n}: {\n\ttriggerProps: React.ComponentProps<'button'>;\n\tariaLabel: string;\n}) {\n\tconst { className, ...props } = triggerProps;\n\treturn (\n\t\t<button\n\t\t\t{...props}\n\t\t\ttype=\"button\"\n\t\t\tclassName={cn(\n\t\t\t\t'metadata-list--info-trigger',\n\t\t\t\tfieldAffordanceRecipes.target,\n\t\t\t\tfieldAffordanceRecipes.focus,\n\t\t\t\tfieldAffordanceRecipes.clear,\n\t\t\t\t'-my-[calc((var(--spacing-control-clear)-var(--spacing-control-clear-icon))/2)] cursor-help self-center',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\taria-label={ariaLabel}\n\t\t>\n\t\t\t<Info className={fieldAffordanceRecipes.icon} aria-hidden=\"true\" />\n\t\t</button>\n\t);\n}\n\nfunction MetadataItemInfo({\n\titem,\n\tstrings,\n}: {\n\titem: MetadataListItem;\n\tstrings: MetadataListStrings;\n}) {\n\tif (item.tooltip === null || item.tooltip === undefined) return null;\n\treturn (\n\t\t<Tooltip>\n\t\t\t<TooltipTrigger\n\t\t\t\trender={(triggerProps) => (\n\t\t\t\t\t<MetadataInfoTrigger\n\t\t\t\t\t\ttriggerProps={triggerProps}\n\t\t\t\t\t\tariaLabel={typeof item.label === 'string' ? strings.formatInfoAriaLabel(item.label) : strings.infoFallback}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t/>\n\t\t\t<TooltipContent side=\"top\" align=\"start\" className=\"max-w-80\">\n\t\t\t\t<Text type=\"inverse\" size=\"xs\">{item.tooltip}</Text>\n\t\t\t</TooltipContent>\n\t\t</Tooltip>\n\t);\n}\n\nfunction MetadataItemIcon({ item, isCompact }: { item: MetadataListItem; isCompact: boolean }) {\n\tconst Icon = item.icon;\n\tif (!Icon) return null;\n\treturn (\n\t\t<Icon\n\t\t\tclassName={cn(\n\t\t\t\t'flex-shrink-0 self-center text-muted-foreground',\n\t\t\t\tisCompact ? 'size-icon-sm' : 'size-icon',\n\t\t\t)}\n\t\t/>\n\t);\n}\n\nexport function MetadataList({\n\titems,\n\tcolumns = 2,\n\tdensity = 'default',\n\temptyLabel = EMPTY,\n\ttitle,\n\ttitleSeparator = false,\n\tclassName,\n\tlayout = 'grid',\n\tseparator = ': ',\n\titemSeparator = false,\n\tvalueAlign = 'start',\n\tstrings: stringsProp,\n}: MetadataListProps) {\n\tconst strings = useStrings(defaultMetadataListStrings, stringsProp);\n\tconst list = React.useMemo(() => (items as MetadataListItem[]).filter(Boolean), [items]);\n\n\tif (list.length === 0) {\n\t\treturn null;\n\t}\n\n\tconst isCompact = density === 'compact';\n\tconst valueBase = 'metadata-list--value text-sm';\n\tconst hasTitle = title !== null && title !== undefined;\n\tconst shouldShowSeparator = hasTitle && titleSeparator;\n\tconst rootClassName = cn('metadata-list--component', 'metadata-list-container @container/metadata-list', className);\n\tconst head = (\n\t\t<>\n\t\t\t{!!hasTitle && (\n\t\t\t\t<DisplayLabel tag=\"div\" className=\"metadata-list--title block\">\n\t\t\t\t\t{title}\n\t\t\t\t</DisplayLabel>\n\t\t\t)}\n\t\t\t{!!shouldShowSeparator && <Separator className=\"metadata-list--title-separator\" />}\n\t\t</>\n\t);\n\n\tif (layout === 'inline') {\n\t\tconst itemSeparatorText =\n\t\t\ttypeof itemSeparator === 'string'\n\t\t\t\t? itemSeparator\n\t\t\t\t: itemSeparator\n\t\t\t\t\t? '·'\n\t\t\t\t\t: '';\n\n\t\treturn (\n\t\t\t<Stack gap=\"sm\" data-metadata-density={density} className={rootClassName}>\n\t\t\t\t{head}\n\n\t\t\t\t<Stack\n\t\t\t\t\tdirection=\"horizontal\"\n\t\t\t\t\talign=\"baseline\"\n\t\t\t\t\tgap={isCompact ? 'sm' : 'md'}\n\t\t\t\t\tclassName=\"metadata-list--inline\"\n\t\t\t\t>\n\t\t\t\t\t{list.map((item, index) => {\n\t\t\t\t\t\tconst showItemSeparator = itemSeparatorText && index < list.length - 1;\n\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<React.Fragment key={resolveKey(item, index)}>\n\t\t\t\t\t\t\t\t<Stack direction=\"horizontal\" align=\"baseline\" gap=\"xs\" className=\"metadata-list--item min-w-0 [&>*]:max-w-full [&>*]:min-w-0 [&>.badge--component]:self-center\">\n\t\t\t\t\t\t\t\t\t<MetadataItemIcon item={item} isCompact={isCompact} />\n\n\t\t\t\t\t\t\t\t\t{/* Label, optional info trigger, and the separator are one\n\t\t\t\t\t\t\t\t\t unit that never wraps apart: the item Stack's gap would\n\t\t\t\t\t\t\t\t\t otherwise fall between the label and the colon and render\n\t\t\t\t\t\t\t\t\t \"SKU : value\" — French spacing — instead of \"SKU: value\".\n\t\t\t\t\t\t\t\t\t The label itself still wraps inside the unit. */}\n\t\t\t\t\t\t\t\t\t<Stack direction=\"horizontal\" gap=\"none\" align=\"baseline\" wrap={false} className=\"max-w-full shrink-0\">\n\t\t\t\t\t\t\t\t\t\t<MetadataLabel>\n\t\t\t\t\t\t\t\t\t\t\t{item.label}\n\t\t\t\t\t\t\t\t\t\t</MetadataLabel>\n\n\t\t\t\t\t\t\t\t\t\t<MetadataItemInfo item={item} strings={strings} />\n\n\t\t\t\t\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\t\t\t\t\ttag=\"span\"\n\t\t\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\t\t\ttype=\"secondary\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{separator}\n\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t</Stack>\n\n\t\t\t\t\t\t\t\t\t{renderItemValue({\n\t\t\t\t\t\t\t\t\t\titem,\n\t\t\t\t\t\t\t\t\t\ttag: 'span',\n\t\t\t\t\t\t\t\t\t\temptyLabel: item.emptyLabel ?? emptyLabel,\n\t\t\t\t\t\t\t\t\t\tvalueBase: cn(valueBase, 'leading-tight'),\n\t\t\t\t\t\t\t\t\t\trenderedClassName: cn(valueBase, textVariants({ size: 'sm', lineHeight: 'tight' })),\n\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t</Stack>\n\n\t\t\t\t\t\t\t\t{!!showItemSeparator && (\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=\"sm\"\n\t\t\t\t\t\t\t\t\t\ttype=\"secondary\"\n\t\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"metadata-list--item-separator select-none\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{itemSeparatorText}\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</React.Fragment>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t</Stack>\n\t\t\t</Stack>\n\t\t);\n\t}\n\n\tif (layout === 'rows') {\n\t\tconst rowPaddingY = isCompact ? 'py-row-y-sm' : 'py-row-y';\n\t\tconst isEndAligned = valueAlign === 'end';\n\t\t// `start` uses proportional tracks, so values line up down the list\n\t\t// without a label min-width that would crowd phones. `end` keeps the\n\t\t// label track flexible and pins a content-sized value to the row end.\n\t\tconst rowTrack = isEndAligned\n\t\t\t? 'grid-cols-[minmax(0,1fr)_fit-content(60%)] gap-x-space-md'\n\t\t\t: cn('grid-cols-[minmax(0,2fr)_minmax(0,3fr)]', isCompact ? 'gap-x-space-lg' : 'gap-x-space-xl');\n\t\tconst valueAlignClassName = isEndAligned ? 'text-end' : 'text-start';\n\t\treturn (\n\t\t\t<Stack gap=\"sm\" data-metadata-density={density} className={rootClassName}>\n\t\t\t\t{head}\n\t\t\t\t<Stack\n\t\t\t\t\trender={<dl />}\n\t\t\t\t\tgap=\"none\"\n\t\t\t\t\tdata-value-align={valueAlign}\n\t\t\t\t\tclassName={cn('metadata-list--rows m-0', !!itemSeparator && 'divide-y divide-border/60')}\n\t\t\t\t>\n\t\t\t\t\t{list.map((item, index) => (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tkey={resolveKey(item, index)}\n\t\t\t\t\t\t\tclassName={cn('metadata-list--item grid items-baseline', rowTrack, rowPaddingY)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<dt className=\"flex min-w-0 items-center gap-space-sm\">\n\t\t\t\t\t\t\t\t<MetadataItemIcon item={item} isCompact={isCompact} />\n\t\t\t\t\t\t\t\t<MetadataLabel>\n\t\t\t\t\t\t\t\t\t{item.label}\n\t\t\t\t\t\t\t\t</MetadataLabel>\n\t\t\t\t\t\t\t\t<MetadataItemInfo item={item} strings={strings} />\n\t\t\t\t\t\t\t</dt>\n\t\t\t\t\t\t\t<dd\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t'm-0 grid min-w-0 gap-dense break-words [overflow-wrap:anywhere] [&>*]:max-w-full [&>*]:min-w-0',\n\t\t\t\t\t\t\t\t\tvalueAlignClassName,\n\t\t\t\t\t\t\t\t\tisEndAligned\n\t\t\t\t\t\t\t\t\t\t? 'justify-items-end [&>.badge--component]:justify-self-end'\n\t\t\t\t\t\t\t\t\t\t: 'justify-items-start [&>.badge--component]:justify-self-start',\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{renderItemValue({\n\t\t\t\t\t\t\t\t\titem,\n\t\t\t\t\t\t\t\t\temptyLabel: item.emptyLabel ?? emptyLabel,\n\t\t\t\t\t\t\t\t\tvalueBase: cn(valueBase, valueAlignClassName, 'break-words leading-tight'),\n\t\t\t\t\t\t\t\t\trenderedClassName: cn(valueBase, 'break-words', textVariants({ size: 'sm', lineHeight: 'tight', align: isEndAligned ? 'right' : 'left' })),\n\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t{!!item.description && (\n\t\t\t\t\t\t\t\t\t<Text size=\"xs\" type=\"secondary\" align={isEndAligned ? 'right' : 'left'} lineHeight=\"snug\" className=\"metadata-list--description\">\n\t\t\t\t\t\t\t\t\t\t{item.description}\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</dd>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t))}\n\t\t\t\t</Stack>\n\t\t\t</Stack>\n\t\t);\n\t}\n\n\treturn (\n\t\t<Stack gap=\"sm\" data-metadata-density={density} className={rootClassName}>\n\t\t\t{head}\n\n\t\t\t<Grid\n\t\t\t\tcolumns={resolveMetadataColumns(columns)}\n\t\t\t\tgap={isCompact ? 'md' : 'xl'}\n\t\t\t\talign=\"start\"\n\t\t\t\tclassName=\"metadata-list--grid\"\n\t\t\t>\n\t\t\t\t{list.map((item, index) => (\n\t\t\t\t\t<Stack\n\t\t\t\t\t\tkey={resolveKey(item, index)}\n\t\t\t\t\t\tgap={isCompact ? 'dense' : 'normal'}\n\t\t\t\t\t\tclassName=\"metadata-list--item min-w-0 items-start [&>*]:max-w-full [&>*]:min-w-0 [&>.badge--component]:self-start\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<div className=\"flex min-w-0 items-center gap-space-sm\">\n\t\t\t\t\t\t\t<MetadataItemIcon item={item} isCompact={isCompact} />\n\n\t\t\t\t\t\t\t<MetadataLabel>\n\t\t\t\t\t\t\t\t{item.label}\n\t\t\t\t\t\t\t</MetadataLabel>\n\n\t\t\t\t\t\t\t<MetadataItemInfo item={item} strings={strings} />\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t{renderItemValue({\n\t\t\t\t\t\t\titem,\n\t\t\t\t\t\t\temptyLabel: item.emptyLabel ?? emptyLabel,\n\t\t\t\t\t\t\tvalueBase: cn(valueBase, 'leading-tight'),\n\t\t\t\t\t\t\trenderedClassName: cn(valueBase, textVariants({ size: 'sm', lineHeight: 'tight' })),\n\t\t\t\t\t\t})}\n\n\t\t\t\t\t\t{!!item.description && (\n\t\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\ttype=\"secondary\"\n\t\t\t\t\t\t\t\tlineHeight=\"snug\"\n\t\t\t\t\t\t\t\tclassName=\"metadata-list--description\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{item.description}\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</Stack>\n\t\t\t\t))}\n\t\t\t</Grid>\n\t\t</Stack>\n\t);\n}\n\nMetadataList.displayName = 'MetadataList';\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"navigation-D3KwXmaq.js","names":["Text","focusRecipes","Stack","interactionRecipes","Badge","TabScrollViewport","LanguageSwitcher","handleSelect","useCallback","isActive","onSelect","value","locales","variant","Globe","label","onRenderLabel","locale","Fragment","cn","index","Button","defaultNavigationTabsStrings","normalizePath","hashRouteIndex","rawUrl","origin","NavigationTabs","forwardRef","stringsProp","strings","useStrings","activePath","currentPath","prominent","list","items","item","Icon","scrollable","className","scrollStrings"],"sources":["../src/components/base/navigation/language-switcher.tsx","../src/components/base/navigation/navigation-tabs.tsx"],"sourcesContent":["/**\n * LanguageSwitcher — locale picker with two layouts: `buttons` (chunky\n * primary buttons) and `inline` (small text links separated by dots, prefixed\n * with a globe icon). Defaults to `buttons`.\n *\n * The library never navigates on its own. The consumer wires routing /\n * locale switching by passing `onSelect` (e.g. a Tanstack Router\n * `navigate(...)` or Inertia `router.visit(...)`). When `onSelect` is\n * absent the click is a no-op.\n */\nimport { Globe } from 'lucide-react';\nimport { Fragment, useCallback } from 'react';\n\nimport { Button } from '../buttons';\nimport { Text } from '../../typography';\nimport { Stack } from '../structure';\nimport { cn } from '../../../lib/utils';\nimport type { LocaleOption } from '../../../types/locale.types';\nimport { focusRecipes } from '../../../lib/focus-recipes';\n\nexport interface LanguageSwitcherProps {\n\t/** Locales to offer, in order. The entry with `active: true` is marked as current. */\n\tlocales: LocaleOption[];\n\t/** Custom label for each locale. Defaults to `nativeLabel`. */\n\tonRenderLabel?: (options: LocaleOption) => string;\n\t/** Layout: `buttons` (default) for a row of buttons, `inline` for compact dot-separated text links. */\n\tvariant?: 'buttons' | 'inline';\n\t/** Called with the chosen locale's value. Not called for the current locale. */\n\tonSelect?: (value: string) => void;\n}\n\nexport function LanguageSwitcher({\n\tlocales,\n\tonRenderLabel,\n\tvariant = 'buttons',\n\tonSelect,\n}: LanguageSwitcherProps) {\n\tconst handleSelect = useCallback((value: string, isActive: boolean) => {\n\t\tif (isActive) {\n\t\t\treturn;\n\t\t}\n\n\t\tonSelect?.(value);\n\t}, [onSelect]);\n\n\tif (locales.length === 0) {\n\t\treturn null;\n\t}\n\n\tif (variant === 'inline') {\n\t\treturn (\n\t\t\t<Stack direction=\"horizontal\" align=\"center\" justify=\"center\" gap=\"md\" wrap={false} className=\"language-switcher--component\">\n\t\t\t\t<Globe className=\"size-icon shrink-0 text-muted-foreground\" aria-hidden=\"true\" />\n\t\t\t\t<Stack direction=\"horizontal\" align=\"center\" justify=\"center\" gap=\"md\" wrap className=\"min-w-0\">\n\t\t\t\t\t{locales.map((locale, index) => {\n\t\t\t\t\t\tconst label = onRenderLabel\n\t\t\t\t\t\t\t? onRenderLabel(locale)\n\t\t\t\t\t\t\t: locale.nativeLabel;\n\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<Fragment key={locale.value}>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\taria-current={locale.active ? 'true' : undefined}\n\t\t\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\t\t\thandleSelect(locale.value, locale.active)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t`cursor-pointer rounded-inner border-0 bg-transparent p-0 font-sans text-pxs outline-none transition-colors ${focusRecipes.text}`,\n\t\t\t\t\t\t\t\t\t\tlocale.active\n\t\t\t\t\t\t\t\t\t\t\t? 'text-primary-accent font-medium'\n\t\t\t\t\t\t\t\t\t\t\t: 'text-muted-foreground hover:text-foreground',\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Text tag=\"span\" size=\"pxs\" weight={locale.active ? 'medium' : 'regular'} className=\"text-inherit\">\n\t\t\t\t\t\t\t\t\t\t{label}\n\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t{index < locales.length - 1 && (\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"size-1 rounded-full bg-border\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</Fragment>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t</Stack>\n\t\t\t</Stack>\n\t\t);\n\t}\n\n\treturn (\n\t\t<Stack direction=\"horizontal\" align=\"center\" justify=\"center\" wrap gap=\"md\">\n\t\t\t{locales.map((locale) => {\n\t\t\t\tconst label = onRenderLabel ? onRenderLabel(locale) : locale.nativeLabel;\n\n\t\t\t\treturn (\n\t\t\t\t\t<Button\n\t\t\t\t\t\tkey={locale.value}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\ttone=\"secondary\"\n\t\t\t\t\t\tbuttonStyle={locale.active ? 'solid' : 'ghost'}\n\t\t\t\t\t\taria-current={locale.active ? 'true' : undefined}\n\t\t\t\t\t\tonClick={() => handleSelect(locale.value, locale.active)}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t'min-w-18 justify-center transition-colors',\n\t\t\t\t\t\t\tlocale.active ? 'text-foreground' : 'text-muted-foreground',\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{label}\n\t\t\t\t\t</Button>\n\t\t\t\t);\n\t\t\t})}\n\t\t</Stack>\n\t);\n}\n\nLanguageSwitcher.displayName = 'LanguageSwitcher';\n","/**\n * NavigationTabs — canonical route-tab navigation.\n *\n * The default compact treatment works for ordinary application navigation;\n * `variant=\"prominent\"` provides the stronger filled treatment without\n * introducing a second component or item vocabulary.\n */\nimport { forwardRef, type ReactNode } from 'react';\nimport type { LucideIcon } from 'lucide-react';\n\nimport { Badge } from '../badge';\nimport { Button } from '../buttons';\nimport { Stack } from '../structure';\nimport { Text } from '../../typography';\nimport { useStrings, type StringsProp } from '../../../lib/strings';\nimport { cn } from '../../../lib/utils';\nimport { TabScrollViewport, type TabsScrollStrings } from './tab-scroll-viewport';\nimport { interactionRecipes } from '../../../lib/interaction-recipes';\n\nexport interface NavigationTabItem {\n\ttitle: string;\n\thref: string;\n\ticon?: LucideIcon | string;\n\tbadge?: ReactNode;\n\tactive?: boolean;\n\tdisabled?: boolean;\n}\n\nexport interface NavigationTabsStrings {\n\ttabsAria: string;\n}\n\nexport const defaultNavigationTabsStrings: NavigationTabsStrings = {\n\ttabsAria: 'Tab navigation',\n};\n\nexport type NavigationTabsVariant = 'default' | 'prominent';\n\nexport interface NavigationTabsProps {\n\t/** Tabs to render, in order. */\n\titems: readonly NavigationTabItem[];\n\t/** Path of the active route, used to mark the current tab. */\n\tcurrentPath?: string;\n\t/** Visual treatment of the tab row. */\n\tvariant?: NavigationTabsVariant;\n\t/** Show previous/next controls when route tabs overflow. Defaults to true. */\n\tscrollable?: boolean;\n\t/** Accessible labels for the previous/next scroll controls. */\n\tscrollStrings?: StringsProp<TabsScrollStrings>;\n\t/** Overrides the tab row's own copy. */\n\tstrings?: StringsProp<NavigationTabsStrings>;\n\tclassName?: string;\n}\n\nfunction normalizePath(rawUrl: string): string {\n\tconst hashRouteIndex = rawUrl.indexOf('#/');\n\tif (hashRouteIndex >= 0) {\n\t\treturn rawUrl.slice(hashRouteIndex).split('?')[0]?.replace(/\\/+$/, '') || '#/';\n\t}\n\n\ttry {\n\t\tconst origin = typeof window !== 'undefined' ? window.location.origin : 'http://localhost';\n\t\tconst parsed = new URL(rawUrl, origin);\n\t\treturn parsed.pathname.replace(/\\/+$/, '') || '/';\n\t} catch {\n\t\treturn rawUrl.split('?')[0]?.replace(/\\/+$/, '') || '/';\n\t}\n}\n\nexport const NavigationTabs = forwardRef<HTMLDivElement, NavigationTabsProps>(function NavigationTabs({\n\titems,\n\tcurrentPath,\n\tvariant = 'default',\n\tscrollable = true,\n\tscrollStrings,\n\tstrings: stringsProp,\n\tclassName,\n}: NavigationTabsProps, ref) {\n\tconst strings = useStrings(defaultNavigationTabsStrings, stringsProp);\n\tconst activePath = normalizePath(\n\t\tcurrentPath ?? (typeof window !== 'undefined' ? window.location.pathname : '/'),\n\t);\n\tconst prominent = variant === 'prominent';\n\n\tconst list = <Stack\n\t\t\t\trender={<nav aria-label={strings.tabsAria} />}\n\t\t\t\tdirection=\"horizontal\"\n\t\t\t\tgap=\"2xs\"\n\t\t\t\twrap={false}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'navigation-tabs--list w-max rounded-inner bg-muted p-space-2xs',\n\t\t\t\t\tprominent && 'rounded-inner bg-muted',\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t{items.map((item) => {\n\t\t\t\t\tconst isActive = item.active ?? activePath === normalizePath(item.href);\n\t\t\t\t\tconst Icon = typeof item.icon === 'string' ? undefined : item.icon;\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tkey={item.href}\n\t\t\t\t\t\t\thref={item.href}\n\t\t\t\t\t\t\tdisabled={item.disabled}\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\ttone={isActive && prominent ? 'primary' : 'secondary'}\n\t\t\t\t\t\t\tbuttonStyle={isActive && prominent ? 'solid' : 'ghost'}\n\t\t\t\t\t\t\ticon={Icon}\n\t\t\t\t\t\t\taria-current={isActive ? 'page' : undefined}\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t'navigation-tabs--item shrink-0',\n\t\t\t\t\t\t\t\t'rounded-inner',\n\t\t\t\t\t\t\t\t// Shared segmented recipe (Tabs, OverflowTabBar): a lifted card-coloured\n\t\t\t\t\t\t\t\t// active tab on the muted track, in light and dark alike. The current tab\n\t\t\t\t\t\t\t\t// holds its state under hover and press; the others change colour only.\n\t\t\t\t\t\t\t\t!prominent && isActive && interactionRecipes.segmentActiveButton,\n\t\t\t\t\t\t\t\t!prominent && !isActive && interactionRecipes.segmentInactiveButton,\n\t\t\t\t\t\t\t\tprominent && isActive && interactionRecipes.currentButtonHold,\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{typeof item.icon === 'string' && (\n\t\t\t\t\t\t\t\t<span className=\"navigation-tabs--icon text-inherit\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t\t{item.icon}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\t\ttag=\"span\"\n\t\t\t\t\t\t\t\tsize=\"inherit\"\n\t\t\t\t\t\t\t\tweight=\"medium\"\n\t\t\t\t\t\t\t\tlineHeight=\"none\"\n\t\t\t\t\t\t\t\tclassName=\"navigation-tabs--title text-inherit\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{item.title}\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t{item.badge !== undefined && item.badge !== null && (\n\t\t\t\t\t\t\t\t<Badge\n\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\ttone=\"secondary\"\n\t\t\t\t\t\t\t\t\tclassName=\"navigation-tabs--badge\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{item.badge}\n\t\t\t\t\t\t\t\t</Badge>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</Stack>;\n\treturn <div ref={ref} className={cn('navigation-tabs--component', 'w-full min-w-0', !scrollable && 'overflow-x-auto', className)}>\n\t\t{scrollable ? <TabScrollViewport strings={scrollStrings}>{list}</TabScrollViewport> : list}\n\t</div>;\n});\n\nNavigationTabs.displayName = 'NavigationTabs';\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"navigation-HJf5zxlH.js","names":["DisplayLabel","Text","focusRecipes","Stack","toneRecipes","interactionRecipes","Percent","Badge","ItemMedia","ItemDescription","ItemActions","ItemGroup","ItemContent","Item","ItemTitle","defaultBreadcrumbProgressStrings","BreadcrumbProgress","stringsProp","strings","useStrings","cn","className","currentIndex","steps","isCompleted","idx","isCurrent","isClickable","onStepClick","Button","step","Check","CategoryNav","title","items","Icon","it","active","activeId","onSelect","ChevronRight","defaultSectionNavStrings","SectionNav","forwardRef","ariaLabel","rootProps","setActive","useState","useEffect","obs","visible","entries","el","rootMargin","isActive","e","defaultSideNavStrings","normalizePath","rawUrl","baseOrigin","trimmed","isSimpleText","value","SideNav","groupsProp","groups","useMemo","activePath","currentPath","activeNormalized","g","item","normalizedPath","b","a","collapsed","setCollapsed","toggleGroup","prev","id","resolvedActive","activeItemClassName","isCollapsed","group","showLabel","shouldRenderItems","ChevronDown","itemClassName"],"sources":["../src/components/layout/navigation/breadcrumb-progress/types.ts","../src/components/layout/navigation/breadcrumb-progress/breadcrumb-progress.tsx","../src/components/layout/navigation/category-nav/category-nav.tsx","../src/components/layout/navigation/section-nav/section-nav.tsx","../src/components/layout/navigation/side-nav.tsx"],"sourcesContent":["import type { StringsProp } from '../../../../lib/strings';\n\nexport interface BreadcrumbProgressStep {\n\t/** Stable identity for this entry. */\n\tid: string;\n\t/** Display label. */\n\tlabel: string;\n\t/** Short guidance shown beneath the control. */\n\thint?: string;\n}\n\nexport interface BreadcrumbProgressStrings {\n\tstepLabel: string;\n\tofLabel: string;\n}\n\nexport const defaultBreadcrumbProgressStrings: BreadcrumbProgressStrings = {\n\tstepLabel: 'Step',\n\tofLabel: 'of',\n};\n\nexport interface BreadcrumbProgressProps {\n\t/** Steps in the flow, in order. */\n\tsteps: BreadcrumbProgressStep[];\n\t/** Zero-based position of the active step. */\n\tcurrentIndex: number;\n\tonStepClick?: (id: string, index: number) => void;\n\tclassName?: string;\n\t/** Overrides this surface's own copy. */\n\tstrings?: StringsProp<BreadcrumbProgressStrings>;\n}\n","/**\n * BreadcrumbProgress — wizard / multi-step navigation with completed,\n * current, and upcoming states. Click any completed step to jump back.\n */\nimport { Check } from 'lucide-react';\nimport { Button } from '../../../base/buttons';\nimport { Percent } from '../../../primitives';\nimport { DisplayLabel, Text } from '../../../typography';\nimport { useStrings } from '../../../../lib/strings';\nimport { cn } from '../../../../lib/utils';\n\nimport {\n\tdefaultBreadcrumbProgressStrings,\n\ttype BreadcrumbProgressProps,\n} from './types';\nimport { interactionRecipes } from '../../../../lib/interaction-recipes';\nimport { toneRecipes } from '../../../../lib/tone-recipes';\n\nexport function BreadcrumbProgress({ steps, currentIndex, onStepClick, className, strings: stringsProp }: BreadcrumbProgressProps) {\n\tconst strings = useStrings(defaultBreadcrumbProgressStrings, stringsProp);\n\n\treturn (\n\t\t<div className={cn('breadcrumb-progress--component', 'w-full', className)}>\n\t\t\t<div className=\"flex items-center justify-between mb-space-md\">\n\t\t\t\t<DisplayLabel>\n\t\t\t\t\t{strings.stepLabel} {currentIndex + 1} {strings.ofLabel} {steps.length}\n\t\t\t\t</DisplayLabel>\n\t\t\t\t<Percent value={Math.round(((currentIndex + 1) / steps.length) * 100)} scaled size=\"xs\" weight=\"semibold\" />\n\t\t\t</div>\n\t\t\t<ol className=\"m-0 list-none p-0 font-sans flex items-center gap-space-md\">\n\t\t\t\t{steps.map((step, idx) => {\n\t\t\t\t\tconst isCompleted = idx < currentIndex;\n\t\t\t\t\tconst isCurrent = idx === currentIndex;\n\t\t\t\t\tconst isClickable = onStepClick && (isCompleted || isCurrent);\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<li key={step.id} className=\"flex min-w-0 flex-1 items-center gap-space-md\">\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\taria-label={`${strings.stepLabel} ${idx + 1}: ${step.label}`}\n\t\t\t\t\t\t\t\tonClick={() => isClickable && onStepClick?.(step.id, idx)}\n\t\t\t\t\t\t\t\tdisabled={!isClickable}\n\t\t\t\t\t\t\t\ttone=\"secondary\"\n\t\t\t\t\t\t\t\tbuttonStyle=\"ghost\"\n\t\t\t\t\t\t\t\tsize=\"md\"\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t'min-w-0 justify-start gap-space-md text-left transition-colors',\n\t\t\t\t\t\t\t\t\tisClickable && interactionRecipes.rowHover,\n\t\t\t\t\t\t\t\t\t!isClickable && 'cursor-default',\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\tweight=\"semibold\"\n\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t'flex size-6 shrink-0 items-center justify-center rounded-full tabular-nums',\n\t\t\t\t\t\t\t\t\t\tisCompleted && 'bg-success text-success-foreground',\n\t\t\t\t\t\t\t\t\t\tisCurrent && `bg-primary text-primary-foreground ring-4 ${toneRecipes.primary.halo}`,\n\t\t\t\t\t\t\t\t\t\t!isCompleted && !isCurrent && 'bg-muted text-muted-foreground',\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{isCompleted ? <Check className=\"size-icon-md\" /> : idx + 1}\n\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t<div className=\"hidden min-w-0 lg:block\">\n\t\t\t\t\t\t\t\t\t<Text weight=\"semibold\" className={cn(!isCurrent && !isCompleted && 'text-muted-foreground')}>{step.label}</Text>\n\t\t\t\t\t\t\t\t\t{!!step.hint && <Text size=\"xs\" type=\"discrete\" className=\"truncate\">{step.hint}</Text>}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t{idx < steps.length - 1 && (\n\t\t\t\t\t\t\t\t<div className={cn('h-px flex-1', isCompleted ? 'bg-success' : 'bg-border')} />\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</li>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</ol>\n\t\t</div>\n\t);\n}\n\nBreadcrumbProgress.displayName = 'BreadcrumbProgress';\n","/**\n * CategoryNav — vertical icon + label list with optional count badge per row.\n * Use as a sidebar nav for filtering or category browsing.\n */\nimport { ChevronRight } from 'lucide-react';\nimport { Badge } from '../../../base/badge';\nimport {\n\tItem,\n\tItemActions,\n\tItemContent,\n\tItemDescription,\n\tItemGroup,\n\tItemMedia,\n\tItemTitle,\n} from '../../../base/item';\nimport { cn } from '../../../../lib/utils';\n\nimport type { CategoryNavProps } from './types';\nimport { interactionRecipes } from '../../../../lib/interaction-recipes';\n\nexport function CategoryNav({ title, items, activeId, onSelect, className }: CategoryNavProps) {\n\treturn (\n\t\t<nav\n\t\t\tdata-component=\"category-nav\"\n\t\t\tdata-slot=\"category-nav\"\n\t\t\taria-label={title}\n\t\t\tclassName={cn('category-nav--component min-w-0', className)}\n\t\t>\n\t\t\t<ItemGroup>\n\t\t\t\t{items.map((it) => {\n\t\t\t\t\tconst Icon = it.icon;\n\t\t\t\t\tconst active = it.id === activeId;\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<Item\n\t\t\t\t\t\t\tkey={it.id}\n\t\t\t\t\t\t\t// Not `size=\"sm\"`. That maps to the primitive `xs` scale, which\n\t\t\t\t\t\t\t// shrinks media icons to 12px for a genuinely compact row — but\n\t\t\t\t\t\t\t// this row carries a title, a description and a badge and stands\n\t\t\t\t\t\t\t// 58px tall. The result was a 12px leading icon beside a 16px\n\t\t\t\t\t\t\t// chevron, because a `size-` class opts an icon out of that\n\t\t\t\t\t\t\t// scaling rule. The default scale matches `base/item`'s own\n\t\t\t\t\t\t\t// reference row at the same height.\n\t\t\t\t\t\t\tonClick={() => onSelect?.(it.id)}\n\t\t\t\t\t\t\tdata-state={active ? 'active' : 'inactive'}\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t// The selected tint spans the row, so the row needs horizontal\n\t\t\t\t\t\t\t\t// padding of its own or the icon sits 1px from the tint's edge.\n\t\t\t\t\t\t\t\t// `px-space-md` is what `SectionNav` uses for the same job.\n\t\t\t\t\t\t\t\t'cursor-pointer rounded-inner px-space-md transition-colors',\n\t\t\t\t\t\t\t\tactive ? interactionRecipes.rowCurrent : interactionRecipes.rowHover,\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{!!Icon && (\n\t\t\t\t\t\t\t\t<ItemMedia variant=\"icon\" className={cn(active ? 'text-accent-foreground' : 'text-muted-foreground')}>\n\t\t\t\t\t\t\t\t\t<Icon />\n\t\t\t\t\t\t\t\t</ItemMedia>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t<ItemContent>\n\t\t\t\t\t\t\t\t<ItemTitle bold={active}>{it.label}</ItemTitle>\n\t\t\t\t\t\t\t\t{!!it.hint && <ItemDescription clamp={1}>{it.hint}</ItemDescription>}\n\t\t\t\t\t\t\t</ItemContent>\n\t\t\t\t\t\t\t<ItemActions>\n\t\t\t\t\t\t\t\t{typeof it.count === 'number' && (\n\t\t\t\t\t\t\t\t\t<Badge tone=\"secondary\" className=\"tabular-nums\">\n\t\t\t\t\t\t\t\t\t\t{it.count}\n\t\t\t\t\t\t\t\t\t</Badge>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t<ChevronRight\n\t\t\t\t\t\t\t\t\tclassName={cn('size-icon shrink-0 text-muted-foreground', active && 'text-accent-foreground')}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</ItemActions>\n\t\t\t\t\t\t</Item>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</ItemGroup>\n\t\t</nav>\n\t);\n}\n\nCategoryNav.displayName = 'CategoryNav';\n","/**\n * SectionNav — sticky in-page anchor nav. Pass a list of section ids; the active one\n * is tracked via IntersectionObserver and the matching item is highlighted. Click to\n * scroll to that section. Pure JS — no router required.\n */\nimport { forwardRef, useEffect, useState, type ComponentPropsWithoutRef } from 'react';\nimport type { LucideIcon } from 'lucide-react';\nimport { Text } from '../../../typography';\nimport { Stack } from '../../../base/structure';\nimport { useStrings, type StringsProp } from '../../../../lib/strings';\nimport { cn } from '../../../../lib/utils';\nimport { interactionRecipes } from '../../../../lib/interaction-recipes';\nimport { focusRecipes } from '../../../../lib/focus-recipes';\n\nexport interface SectionNavStrings {\n\tnavigationLabel: string;\n}\n\nexport const defaultSectionNavStrings: SectionNavStrings = {\n\tnavigationLabel: 'Section navigation',\n};\n\nexport interface SectionNavItem {\n\t/** Stable identity for this entry. */\n\tid: string;\n\t/** Display label. */\n\tlabel: string;\n\t/** Leading glyph. */\n\ticon?: LucideIcon;\n}\n\nexport interface SectionNavProps extends Omit<ComponentPropsWithoutRef<'nav'>, 'children' | 'onSelect'> {\n\t/** Entries to render, in order. */\n\titems: SectionNavItem[];\n\trootMargin?: string;\n\tonSelect?: (id: string) => void;\n\t/** Overrides this surface's own copy. */\n\tstrings?: StringsProp<SectionNavStrings>;\n}\n\nexport const SectionNav = forwardRef<HTMLElement, SectionNavProps>(function SectionNav({\n\titems,\n\trootMargin = '-40% 0px -50% 0px',\n\tclassName,\n\tonSelect,\n\tstrings: stringsProp,\n\t'aria-label': ariaLabel,\n\t...rootProps\n}, ref) {\n\tconst strings = useStrings(defaultSectionNavStrings, stringsProp);\n\tconst [active, setActive] = useState<string | null>(items[0]?.id ?? null);\n\n\tuseEffect(() => {\n\t\tconst obs = new IntersectionObserver(\n\t\t\t(entries) => {\n\t\t\t\tconst visible = entries.find((e) => e.isIntersecting);\n\t\t\t\tif (visible?.target.id) setActive(visible.target.id);\n\t\t\t},\n\t\t\t{ rootMargin, threshold: 0 },\n\t\t);\n\t\titems.forEach((it) => {\n\t\t\tconst el = document.getElementById(it.id);\n\t\t\tif (el) obs.observe(el);\n\t\t});\n\t\treturn () => obs.disconnect();\n\t}, [items, rootMargin]);\n\n\treturn (\n\t\t<nav\n\t\t\tref={ref}\n\t\t\tclassName={cn('section-nav--component', className)}\n\t\t\taria-label={ariaLabel ?? strings.navigationLabel}\n\t\t\t{...rootProps}\n\t\t>\n\t\t\t<Stack gap=\"2xs\" className=\"section-nav--items\">\n\t\t\t\t{items.map((it) => {\n\t\t\t\tconst Icon = it.icon;\n\t\t\t\tconst isActive = active === it.id;\n\t\t\t\treturn (\n\t\t\t\t\t<a\n\t\t\t\t\t\tkey={it.id}\n\t\t\t\t\t\thref={`#${it.id}`}\n\t\t\t\t\t\taria-current={isActive ? 'location' : undefined}\n\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\tdocument.getElementById(it.id)?.scrollIntoView({ behavior: 'smooth', block: 'start' });\n\t\t\t\t\t\t\tsetActive(it.id);\n\t\t\t\t\t\t\tonSelect?.(it.id);\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t`flex items-center gap-space-md rounded-inner px-space-md py-row-y transition-colors outline-none ${focusRecipes.edge}`,\n\t\t\t\t\t\t\tisActive ? interactionRecipes.rowCurrent : `text-muted-foreground ${interactionRecipes.rowHover}`,\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{!!Icon && <Icon className=\"size-icon-md shrink-0\" />}\n\t\t\t\t\t\t<Text tag=\"span\" weight={isActive ? 'semibold' : 'medium'}>{it.label}</Text>\n\t\t\t\t\t</a>\n\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</Stack>\n\t\t</nav>\n\t);\n});\n\nSectionNav.displayName = 'SectionNav';\n","/**\n * SideNav — collapsible vertical sidebar navigation. Items can be grouped\n * with a heading and optionally collapsed; each item supports an icon, badge,\n * and active-state highlight. The active item is matched by deepest path\n * prefix so nested routes still highlight their parent group.\n *\n * Pass `items` for the short flat-list default. Use `groups` only when the\n * navigation needs headings or collapsible sections.\n */\nimport { ChevronDown, type LucideIcon } from 'lucide-react';\nimport { forwardRef, useMemo, useState, type ComponentPropsWithoutRef, type ReactNode } from 'react';\n\nimport { Badge } from '../../base/badge';\nimport { Button } from '../../base/buttons';\nimport { Stack } from '../../base/structure';\nimport { DisplayLabel, Text } from '../../typography';\nimport { useStrings, type StringsProp } from '../../../lib/strings';\nimport { cn } from '../../../lib/utils';\nimport { focusRecipes } from '../../../lib/focus-recipes';\nimport { interactionRecipes } from '../../../lib/interaction-recipes';\n\nexport interface SideNavStrings {\n\tnavigationLabel: string;\n}\n\nexport const defaultSideNavStrings: SideNavStrings = {\n\tnavigationLabel: 'Side navigation',\n};\n\nexport interface SideNavItem {\n\t/** Display label. */\n\tlabel: ReactNode;\n\t/** Destination for the entry, when it navigates. */\n\thref: string;\n\t/** Leading glyph. */\n\ticon?: LucideIcon;\n\t/** Chip rendered beside the label. */\n\tbadge?: ReactNode;\n\t/** Disables the control. */\n\tdisabled?: boolean;\n}\n\nexport interface SideNavGroup {\n\t/** Stable identity for this entry. */\n\tid: string;\n\t/** Display label. */\n\tlabel?: ReactNode;\n\t/** Entries to render, in order. */\n\titems: SideNavItem[];\n\tdefaultCollapsed?: boolean;\n\tcollapsible?: boolean;\n}\n\ninterface SideNavSharedProps extends Omit<ComponentPropsWithoutRef<'nav'>, 'children'> {\n\t/** Path of the active route, used to mark the current entry. */\n\tcurrentPath?: string;\n\titemClassName?: string;\n\tactiveItemClassName?: string;\n\t/** Overrides this surface's own copy. */\n\tstrings?: StringsProp<SideNavStrings>;\n}\n\nexport type SideNavProps = SideNavSharedProps & (\n\t| {\n\t\t/** Short default for one flat navigation list. */\n\t\titems: SideNavItem[];\n\t\t/** Sections of the settings navigation. */\n\t\tgroups?: never;\n\t}\n\t| {\n\t\t/** Grouped navigation with optional headings and collapse behavior. */\n\t\tgroups: SideNavGroup[];\n\t\titems?: never;\n\t}\n);\n\nfunction normalizePath(rawUrl: string): string {\n\tif (rawUrl.length === 0) return '/';\n\ttry {\n\t\tconst baseOrigin = typeof window !== 'undefined' ? window.location.origin : 'http://localhost';\n\t\tconst parsed = new URL(rawUrl, baseOrigin);\n\t\tconst trimmed = parsed.pathname.replace(/\\/+$/, '');\n\t\treturn trimmed.length > 0 ? trimmed : '/';\n\t} catch {\n\t\tconst clean = rawUrl.split('?')[0] ?? rawUrl;\n\t\tconst trimmed = clean.replace(/\\/+$/, '');\n\t\treturn trimmed.length > 0 ? trimmed : '/';\n\t}\n}\n\nfunction isSimpleText(value: ReactNode): value is string | number | bigint {\n\treturn typeof value === 'string' || typeof value === 'number' || typeof value === 'bigint';\n}\n\nexport const SideNav = forwardRef<HTMLElement, SideNavProps>(function SideNav({\n\titems,\n\tgroups: groupsProp,\n\tcurrentPath,\n\tclassName,\n\titemClassName,\n\tactiveItemClassName,\n\tstrings: stringsProp,\n\t'aria-label': ariaLabel,\n\t...rootProps\n}, ref) {\n\tconst strings = useStrings(defaultSideNavStrings, stringsProp);\n\tconst groups = useMemo<SideNavGroup[]>(\n\t\t() => groupsProp ?? [\n\t\t\t{ id: 'side-nav-items', items: items ?? [], collapsible: false },\n\t\t],\n\t\t[groupsProp, items],\n\t);\n\tconst rawActivePath = currentPath ?? (typeof window !== 'undefined' ? window.location.pathname : '');\n\tconst activePath = normalizePath(rawActivePath);\n\n\tconst allNormalized = useMemo(() => {\n\t\treturn groups.flatMap((g) =>\n\t\t\tg.items.map((item) => ({ groupId: g.id, normalizedPath: normalizePath(item.href) })),\n\t\t);\n\t}, [groups]);\n\n\tconst activeNormalized =\n\t\tallNormalized\n\t\t\t.filter(\n\t\t\t\t({ normalizedPath }) =>\n\t\t\t\t\tactivePath === normalizedPath || activePath.startsWith(`${normalizedPath}/`),\n\t\t\t)\n\t\t\t.sort((a, b) => b.normalizedPath.length - a.normalizedPath.length)[0]?.normalizedPath ??\n\t\tnull;\n\n\tconst [collapsed, setCollapsed] = useState<Record<string, boolean>>(() =>\n\t\tObject.fromEntries(groups.map((g) => [g.id, Boolean(g.defaultCollapsed)])),\n\t);\n\n\tconst toggleGroup = (id: string) =>\n\t\tsetCollapsed((prev) => ({ ...prev, [id]: !prev[id] }));\n\n\tconst resolvedActive =\n\t\tactiveItemClassName && activeItemClassName.length > 0\n\t\t\t? activeItemClassName\n\t\t\t: interactionRecipes.rowCurrent;\n\n\treturn (\n\t\t<nav\n\t\t\tref={ref}\n\t\t\taria-label={ariaLabel ?? strings.navigationLabel}\n\t\t\tclassName={cn('side-nav--component', className)}\n\t\t\t{...rootProps}\n\t\t>\n\t\t\t<Stack gap=\"xl\" className=\"side-nav--groups\">\n\t\t\t\t{groups.map((group) => {\n\t\t\t\tconst isCollapsed = group.collapsible !== false && collapsed[group.id];\n\t\t\t\tconst showLabel = !!group.label;\n\t\t\t\tconst shouldRenderItems = !isCollapsed;\n\n\t\t\t\treturn (\n\t\t\t\t\t<Stack key={group.id} gap=\"2xs\" className=\"side-nav--group\">\n\t\t\t\t\t\t{!!showLabel && (\n\t\t\t\t\t\t\tgroup.collapsible !== false ? (\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\ttone=\"secondary\"\n\t\t\t\t\t\t\t\t\tbuttonStyle=\"ghost\"\n\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\tfullWidth\n\t\t\t\t\t\t\t\t\tonClick={() => toggleGroup(group.id)}\n\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t'h-auto min-h-action-sm justify-between px-row-x py-row-y',\n\t\t\t\t\t\t\t\t\t\t'text-muted-foreground',\n\t\t\t\t\t\t\t\t\t\t'hover:text-foreground transition-colors',\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\taria-expanded={!isCollapsed}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{isSimpleText(group.label) ? (\n\t\t\t\t\t\t\t\t\t\t<DisplayLabel tag=\"span\">\n\t\t\t\t\t\t\t\t\t\t\t{group.label}\n\t\t\t\t\t\t\t\t\t\t</DisplayLabel>\n\t\t\t\t\t\t\t\t\t) : group.label}\n\t\t\t\t\t\t\t\t\t<ChevronDown\n\t\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\t'size-icon-md transition-transform',\n\t\t\t\t\t\t\t\t\t\t\tisCollapsed && '-rotate-90',\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\tisSimpleText(group.label) ? (\n\t\t\t\t\t\t\t\t\t<DisplayLabel tag=\"div\" className=\"px-row-x py-row-y\">\n\t\t\t\t\t\t\t\t\t\t{group.label}\n\t\t\t\t\t\t\t\t\t</DisplayLabel>\n\t\t\t\t\t\t\t\t) : group.label\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{!!shouldRenderItems && (\n\t\t\t\t\t\t\t<Stack gap=\"2xs\" className=\"side-nav--items\">\n\t\t\t\t\t\t\t\t{group.items.map((item) => {\n\t\t\t\t\t\t\t\t\tconst Icon = item.icon;\n\t\t\t\t\t\t\t\t\tconst itemPath = normalizePath(item.href);\n\t\t\t\t\t\t\t\t\tconst isActive = itemPath === activeNormalized;\n\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\t\t\tkey={item.href}\n\t\t\t\t\t\t\t\t\t\t\thref={item.disabled ? undefined : item.href}\n\t\t\t\t\t\t\t\t\t\t\taria-current={isActive ? 'page' : undefined}\n\t\t\t\t\t\t\t\t\t\t\taria-disabled={item.disabled || undefined}\n\t\t\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\t'group flex items-center gap-space-md rounded-inner px-row-x py-row-y',\n\t\t\t\t\t\t\t\t\t\t\t\t'text-sm transition-colors',\n\t\t\t\t\t\t\t\t\t\t\t\t`focus-visible:outline-none ${focusRecipes.edge}`,\n\t\t\t\t\t\t\t\t\t\t\t\tinteractionRecipes.rowHover,\n\t\t\t\t\t\t\t\t\t\t\t\titem.disabled && 'pointer-events-none opacity-50',\n\t\t\t\t\t\t\t\t\t\t\t\tisActive && resolvedActive,\n\t\t\t\t\t\t\t\t\t\t\t\titemClassName,\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{!!Icon && (\n\t\t\t\t\t\t\t\t\t\t\t\t<Icon\n\t\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\t'size-icon shrink-0',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tisActive ? 'text-accent-foreground' : 'text-muted-foreground',\n\t\t\t\t\t\t\t\t\t\t\t\t\t)}\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{isSimpleText(item.label) ? (\n\t\t\t\t\t\t\t\t\t\t\t\t<Text tag=\"span\" size=\"inherit\" weight=\"medium\" lineHeight=\"tight\" className=\"min-w-0 flex-1 truncate text-inherit\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t{item.label}\n\t\t\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t\t) : item.label}\n\t\t\t\t\t\t\t\t\t\t\t{!!item.badge && (\n\t\t\t\t\t\t\t\t\t\t\t\t<Badge\n\t\t\t\t\t\t\t\t\t\t\t\t\ttone=\"secondary\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"shrink-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\t\t{item.badge}\n\t\t\t\t\t\t\t\t\t\t\t\t</Badge>\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</Stack>\n\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</Stack>\n\t\t</nav>\n\t);\n});\n\nSideNav.displayName = 'SideNav';\n"],"mappings":"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"}
|