@alfadocs/ui-kit 0.1.1 → 0.1.2
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/dist/_chunks/{agenda-card-Bld47Eul.js → agenda-card-DXOgg8IX.js} +3 -3
- package/dist/_chunks/{agenda-card-Bld47Eul.js.map → agenda-card-DXOgg8IX.js.map} +1 -1
- package/dist/_chunks/{agenda-tray-D86cNIJ0.js → agenda-tray-DEO8XL8V.js} +4 -4
- package/dist/_chunks/{agenda-tray-D86cNIJ0.js.map → agenda-tray-DEO8XL8V.js.map} +1 -1
- package/dist/_chunks/{ai-prompt-input-CdYwt2VP.js → ai-prompt-input-8IShJ-GX.js} +3 -3
- package/dist/_chunks/{ai-prompt-input-CdYwt2VP.js.map → ai-prompt-input-8IShJ-GX.js.map} +1 -1
- package/dist/_chunks/{audio-recorder-D2UEBF9B.js → audio-recorder-BvisG0Wt.js} +4 -4
- package/dist/_chunks/{audio-recorder-D2UEBF9B.js.map → audio-recorder-BvisG0Wt.js.map} +1 -1
- package/dist/_chunks/{autocomplete.agent-Bi6CiRKa.js → autocomplete.agent-BmrpzsfW.js} +2 -2
- package/dist/_chunks/autocomplete.agent-BmrpzsfW.js.map +1 -0
- package/dist/_chunks/{avatar-BAhxbDEu.js → avatar-DTQY5qIZ.js} +16 -16
- package/dist/_chunks/avatar-DTQY5qIZ.js.map +1 -0
- package/dist/_chunks/{badge-zDghajh8.js → badge-BbbBRweN.js} +2 -2
- package/dist/_chunks/badge-BbbBRweN.js.map +1 -0
- package/dist/_chunks/{balance-cell-renderer-BGyvZWjB.js → balance-cell-renderer-DjR0rPS6.js} +7 -7
- package/dist/_chunks/{balance-cell-renderer-BGyvZWjB.js.map → balance-cell-renderer-DjR0rPS6.js.map} +1 -1
- package/dist/_chunks/{button-DmiGFnNA.js → button-7dTew-IV.js} +4 -4
- package/dist/_chunks/button-7dTew-IV.js.map +1 -0
- package/dist/_chunks/{chat-container-Co8HpB64.js → chat-container-ChdJTH0J.js} +2 -2
- package/dist/_chunks/{chat-container-Co8HpB64.js.map → chat-container-ChdJTH0J.js.map} +1 -1
- package/dist/_chunks/{chat-input-3rstZhHR.js → chat-input-C-B4snVJ.js} +2 -2
- package/dist/_chunks/{chat-input-3rstZhHR.js.map → chat-input-C-B4snVJ.js.map} +1 -1
- package/dist/_chunks/{chat-message-dDMVSYBs.js → chat-message-cFNbQYRH.js} +3 -3
- package/dist/_chunks/{chat-message-dDMVSYBs.js.map → chat-message-cFNbQYRH.js.map} +1 -1
- package/dist/_chunks/{color-picker-OKKF3Dww.js → color-picker-DkMFcK2m.js} +74 -74
- package/dist/_chunks/color-picker-DkMFcK2m.js.map +1 -0
- package/dist/_chunks/{combobox.agent-CfeB-IZ1.js → combobox.agent-9w6W1Jct.js} +20 -20
- package/dist/_chunks/combobox.agent-9w6W1Jct.js.map +1 -0
- package/dist/_chunks/{command-palette.agent-XLfSGHCL.js → command-palette.agent-Dg7jhOIc.js} +2 -2
- package/dist/_chunks/command-palette.agent-Dg7jhOIc.js.map +1 -0
- package/dist/_chunks/{date-picker-DXx8oSJb.js → date-picker-0WQ98ZC0.js} +2 -2
- package/dist/_chunks/{date-picker-DXx8oSJb.js.map → date-picker-0WQ98ZC0.js.map} +1 -1
- package/dist/_chunks/{date-range-picker-C3CbY__H.js → date-range-picker-CtwEwoyr.js} +2 -2
- package/dist/_chunks/{date-range-picker-C3CbY__H.js.map → date-range-picker-CtwEwoyr.js.map} +1 -1
- package/dist/_chunks/{date-time-picker-Bn3FPeAc.js → date-time-picker-Df3OJ2_C.js} +6 -6
- package/dist/_chunks/date-time-picker-Df3OJ2_C.js.map +1 -0
- package/dist/_chunks/{description-list-B1CL3RTG.js → description-list-Bk3p71qY.js} +2 -2
- package/dist/_chunks/{description-list-B1CL3RTG.js.map → description-list-Bk3p71qY.js.map} +1 -1
- package/dist/_chunks/{dialog.agent-D9WeIWi2.js → dialog.agent-CtMkDinJ.js} +2 -2
- package/dist/_chunks/{dialog.agent-D9WeIWi2.js.map → dialog.agent-CtMkDinJ.js.map} +1 -1
- package/dist/_chunks/{empty-state-DV96gCnp.js → empty-state-DPUnQp0A.js} +2 -2
- package/dist/_chunks/{empty-state-DV96gCnp.js.map → empty-state-DPUnQp0A.js.map} +1 -1
- package/dist/_chunks/{file-upload.agent-DYFnqdxw.js → file-upload.agent-DVMxMeDA.js} +3 -3
- package/dist/_chunks/file-upload.agent-DVMxMeDA.js.map +1 -0
- package/dist/_chunks/{floating-action-button-RigP2E7o.js → floating-action-button-DjRhFQdd.js} +4 -4
- package/dist/_chunks/floating-action-button-DjRhFQdd.js.map +1 -0
- package/dist/_chunks/{freemium-paywall-D0GiUFOe.js → freemium-paywall-CCsX3GhK.js} +3 -3
- package/dist/_chunks/{freemium-paywall-D0GiUFOe.js.map → freemium-paywall-CCsX3GhK.js.map} +1 -1
- package/dist/_chunks/{header-CW2oRd5H.js → header-CVQxeLc_.js} +2 -2
- package/dist/_chunks/{header-CW2oRd5H.js.map → header-CVQxeLc_.js.map} +1 -1
- package/dist/_chunks/{icon-button-C482ii4y.js → icon-button-SWpSs9S6.js} +2 -2
- package/dist/_chunks/{icon-button-C482ii4y.js.map → icon-button-SWpSs9S6.js.map} +1 -1
- package/dist/_chunks/{key-value-pair-DDhSYdDL.js → key-value-pair-Cm-pSE6k.js} +2 -2
- package/dist/_chunks/{key-value-pair-DDhSYdDL.js.map → key-value-pair-Cm-pSE6k.js.map} +1 -1
- package/dist/_chunks/{leo-sidebar-gXXcGPKk.js → leo-sidebar-SqGAp1vx.js} +9 -9
- package/dist/_chunks/{leo-sidebar-gXXcGPKk.js.map → leo-sidebar-SqGAp1vx.js.map} +1 -1
- package/dist/_chunks/{message-card-DID3cXUW.js → message-card-B0oGrI3i.js} +4 -4
- package/dist/_chunks/{message-card-DID3cXUW.js.map → message-card-B0oGrI3i.js.map} +1 -1
- package/dist/_chunks/{message-tray-CVMLBnVp.js → message-tray-DZ6oZ0cs.js} +4 -4
- package/dist/_chunks/{message-tray-CVMLBnVp.js.map → message-tray-DZ6oZ0cs.js.map} +1 -1
- package/dist/_chunks/{multi-select.agent-BUKYZJfp.js → multi-select.agent-BDEVGMmW.js} +19 -19
- package/dist/_chunks/multi-select.agent-BDEVGMmW.js.map +1 -0
- package/dist/_chunks/{notification-card-BZ33fq8H.js → notification-card-C73GqjHH.js} +3 -3
- package/dist/_chunks/{notification-card-BZ33fq8H.js.map → notification-card-C73GqjHH.js.map} +1 -1
- package/dist/_chunks/{notification-tray-CnEd7B2q.js → notification-tray-a8a_nut-.js} +4 -4
- package/dist/_chunks/{notification-tray-CnEd7B2q.js.map → notification-tray-a8a_nut-.js.map} +1 -1
- package/dist/_chunks/{number-input-D7rSa_ef.js → number-input-DFQtl5K2.js} +4 -4
- package/dist/_chunks/number-input-DFQtl5K2.js.map +1 -0
- package/dist/_chunks/{otp-input-C9R9sC74.js → otp-input-C2FdizHh.js} +14 -14
- package/dist/_chunks/otp-input-C2FdizHh.js.map +1 -0
- package/dist/_chunks/{pagination.agent-D75FB6XP.js → pagination.agent-sxokDphY.js} +15 -15
- package/dist/_chunks/pagination.agent-sxokDphY.js.map +1 -0
- package/dist/_chunks/{patient-shell-CGsmI5LJ.js → patient-shell-B4vKnuOf.js} +4 -4
- package/dist/_chunks/{patient-shell-CGsmI5LJ.js.map → patient-shell-B4vKnuOf.js.map} +1 -1
- package/dist/_chunks/{payment-form-l3j-gA-t.js → payment-form-175AzK-1.js} +20 -20
- package/dist/_chunks/payment-form-175AzK-1.js.map +1 -0
- package/dist/_chunks/{phone-input-ZWa_FU4R.js → phone-input-BavVyXxZ.js} +39 -39
- package/dist/_chunks/phone-input-BavVyXxZ.js.map +1 -0
- package/dist/_chunks/{popover-CMr1pTPO.js → popover-BWgOopjI.js} +3 -3
- package/dist/_chunks/popover-BWgOopjI.js.map +1 -0
- package/dist/_chunks/{privacy-lock-DdpkKNM2.js → privacy-lock-DWL7m_VT.js} +10 -11
- package/dist/_chunks/{privacy-lock-DdpkKNM2.js.map → privacy-lock-DWL7m_VT.js.map} +1 -1
- package/dist/_chunks/{react-day-picker-d0MHsyCj.js → react-day-picker-C04L_28V.js} +5 -5
- package/dist/_chunks/{react-day-picker-d0MHsyCj.js.map → react-day-picker-C04L_28V.js.map} +1 -1
- package/dist/_chunks/{rich-text-editor.agent-C1_E7_7t.js → rich-text-editor.agent-COSb5_2D.js} +4 -4
- package/dist/_chunks/rich-text-editor.agent-COSb5_2D.js.map +1 -0
- package/dist/_chunks/{select-DbxWF3O_.js → select-CQxhOXVE.js} +7 -7
- package/dist/_chunks/select-CQxhOXVE.js.map +1 -0
- package/dist/_chunks/{sheet-DyWqluiS.js → sheet-CKsuHuHB.js} +2 -2
- package/dist/_chunks/{sheet-DyWqluiS.js.map → sheet-CKsuHuHB.js.map} +1 -1
- package/dist/_chunks/{sidebar-B52iGGNV.js → sidebar-CiEpSH9e.js} +6 -6
- package/dist/_chunks/sidebar-CiEpSH9e.js.map +1 -0
- package/dist/_chunks/{sign-in-with-alfadocs-button-BU7MP5Hg.js → sign-in-with-alfadocs-button-BDErAgG2.js} +2 -2
- package/dist/_chunks/{sign-in-with-alfadocs-button-BU7MP5Hg.js.map → sign-in-with-alfadocs-button-BDErAgG2.js.map} +1 -1
- package/dist/_chunks/{signature-capture.agent-4htVctJ2.js → signature-capture.agent-C38VPXxg.js} +19 -19
- package/dist/_chunks/signature-capture.agent-C38VPXxg.js.map +1 -0
- package/dist/_chunks/{slider-n8JWpJvT.js → slider-BVBlOW_l.js} +2 -2
- package/dist/_chunks/slider-BVBlOW_l.js.map +1 -0
- package/dist/_chunks/{slot-grid-BRAkqChA.js → slot-grid-B4WvLEwT.js} +55 -55
- package/dist/_chunks/slot-grid-B4WvLEwT.js.map +1 -0
- package/dist/_chunks/{sparkline.agent-BLY1IMyW.js → sparkline.agent-C_xp3NRB.js} +2 -2
- package/dist/_chunks/{sparkline.agent-BLY1IMyW.js.map → sparkline.agent-C_xp3NRB.js.map} +1 -1
- package/dist/_chunks/{stepper-calendar-vtWwa2bY.js → stepper-calendar-BZUJpj8i.js} +6 -6
- package/dist/_chunks/stepper-calendar-BZUJpj8i.js.map +1 -0
- package/dist/_chunks/{tabs.agent-BDUlyPbJ.js → tabs.agent-sQAHxebC.js} +5 -5
- package/dist/_chunks/tabs.agent-sQAHxebC.js.map +1 -0
- package/dist/_chunks/{task-tray-BnpiodZ4.js → task-tray-CWvVxWM0.js} +3 -3
- package/dist/_chunks/{task-tray-BnpiodZ4.js.map → task-tray-CWvVxWM0.js.map} +1 -1
- package/dist/_chunks/{text-area-BqbruBWx.js → text-area-iPDv7Nah.js} +10 -10
- package/dist/_chunks/text-area-iPDv7Nah.js.map +1 -0
- package/dist/_chunks/{theme-toggle-BHKMiORD.js → theme-toggle-CEaPghpm.js} +2 -2
- package/dist/_chunks/{theme-toggle-BHKMiORD.js.map → theme-toggle-CEaPghpm.js.map} +1 -1
- package/dist/_chunks/{time-picker-DbpAmPux.js → time-picker-Crc87DU3.js} +67 -67
- package/dist/_chunks/time-picker-Crc87DU3.js.map +1 -0
- package/dist/_chunks/{timeline-vjsUeuq1.js → timeline-Ym2DRmtu.js} +2 -2
- package/dist/_chunks/{timeline-vjsUeuq1.js.map → timeline-Ym2DRmtu.js.map} +1 -1
- package/dist/_chunks/{toast-DllSITLf.js → toast-DoMNrzwm.js} +2 -2
- package/dist/_chunks/{toast-DllSITLf.js.map → toast-DoMNrzwm.js.map} +1 -1
- package/dist/_chunks/{tooth-scheme.agent-BRqxWa1D.js → tooth-scheme.agent-BlDyu-Gx.js} +2 -2
- package/dist/_chunks/{tooth-scheme.agent-BRqxWa1D.js.map → tooth-scheme.agent-BlDyu-Gx.js.map} +1 -1
- package/dist/_chunks/{warning-stack-B9N9yWet.js → warning-stack-5KROOw9M.js} +2 -2
- package/dist/_chunks/{warning-stack-B9N9yWet.js.map → warning-stack-5KROOw9M.js.map} +1 -1
- package/dist/_chunks/{workflow-map-gBhL_Wrs.js → workflow-map-D4sjYv2d.js} +6 -6
- package/dist/_chunks/{workflow-map-gBhL_Wrs.js.map → workflow-map-D4sjYv2d.js.map} +1 -1
- package/dist/agent-catalog.json +1 -1
- package/dist/components/agenda-card/index.js +1 -1
- package/dist/components/agenda-tray/index.js +1 -1
- package/dist/components/ai-prompt-input/index.js +1 -1
- package/dist/components/audio-recorder/index.js +1 -1
- package/dist/components/autocomplete/index.js +1 -1
- package/dist/components/avatar/index.js +1 -1
- package/dist/components/badge/index.js +1 -1
- package/dist/components/button/index.js +2 -2
- package/dist/components/chat-container/index.js +1 -1
- package/dist/components/chat-input/index.js +1 -1
- package/dist/components/chat-message/index.js +1 -1
- package/dist/components/color-picker/index.js +1 -1
- package/dist/components/combobox/index.js +1 -1
- package/dist/components/command-palette/index.js +1 -1
- package/dist/components/data-table/index.js +1 -1
- package/dist/components/date-picker/index.js +1 -1
- package/dist/components/date-range-picker/index.js +1 -1
- package/dist/components/date-time-picker/index.js +1 -1
- package/dist/components/description-list/index.js +1 -1
- package/dist/components/dialog/index.js +1 -1
- package/dist/components/empty-state/index.js +1 -1
- package/dist/components/file-upload/index.js +1 -1
- package/dist/components/floating-action-button/index.js +1 -1
- package/dist/components/freemium-paywall/index.js +1 -1
- package/dist/components/header/index.js +1 -1
- package/dist/components/icon-button/index.js +1 -1
- package/dist/components/key-value-pair/index.js +1 -1
- package/dist/components/message-card/index.js +1 -1
- package/dist/components/message-tray/index.js +1 -1
- package/dist/components/multi-select/index.js +1 -1
- package/dist/components/notification-card/index.js +1 -1
- package/dist/components/notification-tray/index.js +1 -1
- package/dist/components/number-input/index.js +1 -1
- package/dist/components/otp-input/index.js +1 -1
- package/dist/components/pagination/index.js +1 -1
- package/dist/components/payment-form/index.js +1 -1
- package/dist/components/phone-input/index.js +1 -1
- package/dist/components/popover/index.js +1 -1
- package/dist/components/privacy-lock/index.js +1 -1
- package/dist/components/privacy-lock/privacy-lock.d.ts.map +1 -1
- package/dist/components/rich-text-editor/index.js +1 -1
- package/dist/components/select/index.js +1 -1
- package/dist/components/sheet/index.js +1 -1
- package/dist/components/sidebar/index.js +1 -1
- package/dist/components/sign-in-with-alfadocs-button/index.js +1 -1
- package/dist/components/signature-capture/index.js +1 -1
- package/dist/components/slider/index.js +1 -1
- package/dist/components/slot-grid/index.js +1 -1
- package/dist/components/sparkline/index.js +1 -1
- package/dist/components/stepper-calendar/index.js +1 -1
- package/dist/components/tabs/index.js +1 -1
- package/dist/components/task-tray/index.js +1 -1
- package/dist/components/text-area/index.js +1 -1
- package/dist/components/theme-toggle/index.js +1 -1
- package/dist/components/time-picker/index.js +1 -1
- package/dist/components/timeline/index.js +1 -1
- package/dist/components/toast/index.js +1 -1
- package/dist/components/tooth-scheme/index.js +1 -1
- package/dist/components/warning-stack/index.js +1 -1
- package/dist/components/workflow/index.js +1 -1
- package/dist/index.js +61 -61
- package/dist/patterns/leo-assistant/index.js +1 -1
- package/dist/patterns/patient-shell/index.js +1 -1
- package/dist/tokens.css +1 -1
- package/package.json +1 -1
- package/dist/_chunks/autocomplete.agent-Bi6CiRKa.js.map +0 -1
- package/dist/_chunks/avatar-BAhxbDEu.js.map +0 -1
- package/dist/_chunks/badge-zDghajh8.js.map +0 -1
- package/dist/_chunks/button-DmiGFnNA.js.map +0 -1
- package/dist/_chunks/color-picker-OKKF3Dww.js.map +0 -1
- package/dist/_chunks/combobox.agent-CfeB-IZ1.js.map +0 -1
- package/dist/_chunks/command-palette.agent-XLfSGHCL.js.map +0 -1
- package/dist/_chunks/date-time-picker-Bn3FPeAc.js.map +0 -1
- package/dist/_chunks/file-upload.agent-DYFnqdxw.js.map +0 -1
- package/dist/_chunks/floating-action-button-RigP2E7o.js.map +0 -1
- package/dist/_chunks/multi-select.agent-BUKYZJfp.js.map +0 -1
- package/dist/_chunks/number-input-D7rSa_ef.js.map +0 -1
- package/dist/_chunks/otp-input-C9R9sC74.js.map +0 -1
- package/dist/_chunks/pagination.agent-D75FB6XP.js.map +0 -1
- package/dist/_chunks/payment-form-l3j-gA-t.js.map +0 -1
- package/dist/_chunks/phone-input-ZWa_FU4R.js.map +0 -1
- package/dist/_chunks/popover-CMr1pTPO.js.map +0 -1
- package/dist/_chunks/rich-text-editor.agent-C1_E7_7t.js.map +0 -1
- package/dist/_chunks/select-DbxWF3O_.js.map +0 -1
- package/dist/_chunks/sidebar-B52iGGNV.js.map +0 -1
- package/dist/_chunks/signature-capture.agent-4htVctJ2.js.map +0 -1
- package/dist/_chunks/slider-n8JWpJvT.js.map +0 -1
- package/dist/_chunks/slot-grid-BRAkqChA.js.map +0 -1
- package/dist/_chunks/stepper-calendar-vtWwa2bY.js.map +0 -1
- package/dist/_chunks/tabs.agent-BDUlyPbJ.js.map +0 -1
- package/dist/_chunks/text-area-BqbruBWx.js.map +0 -1
- package/dist/_chunks/time-picker-DbpAmPux.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sidebar-B52iGGNV.js","sources":["../../node_modules/lucide-react/dist/esm/icons/grip-vertical.js","../../node_modules/lucide-react/dist/esm/icons/panel-left-close.js","../../node_modules/lucide-react/dist/esm/icons/panel-left-open.js","../../node_modules/lucide-react/dist/esm/icons/star.js","../../src/components/sidebar/sidebar.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"circle\", { cx: \"9\", cy: \"12\", r: \"1\", key: \"1vctgf\" }],\n [\"circle\", { cx: \"9\", cy: \"5\", r: \"1\", key: \"hp0tcf\" }],\n [\"circle\", { cx: \"9\", cy: \"19\", r: \"1\", key: \"fkjjf6\" }],\n [\"circle\", { cx: \"15\", cy: \"12\", r: \"1\", key: \"1tmaij\" }],\n [\"circle\", { cx: \"15\", cy: \"5\", r: \"1\", key: \"19l28e\" }],\n [\"circle\", { cx: \"15\", cy: \"19\", r: \"1\", key: \"f4zoj3\" }]\n];\nconst GripVertical = createLucideIcon(\"grip-vertical\", __iconNode);\n\nexport { __iconNode, GripVertical as default };\n//# sourceMappingURL=grip-vertical.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M9 3v18\", key: \"fh3hqa\" }],\n [\"path\", { d: \"m16 15-3-3 3-3\", key: \"14y99z\" }]\n];\nconst PanelLeftClose = createLucideIcon(\"panel-left-close\", __iconNode);\n\nexport { __iconNode, PanelLeftClose as default };\n//# sourceMappingURL=panel-left-close.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M9 3v18\", key: \"fh3hqa\" }],\n [\"path\", { d: \"m14 9 3 3-3 3\", key: \"8010ee\" }]\n];\nconst PanelLeftOpen = createLucideIcon(\"panel-left-open\", __iconNode);\n\nexport { __iconNode, PanelLeftOpen as default };\n//# sourceMappingURL=panel-left-open.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z\",\n key: \"r04s7s\"\n }\n ]\n];\nconst Star = createLucideIcon(\"star\", __iconNode);\n\nexport { __iconNode, Star as default };\n//# sourceMappingURL=star.js.map\n","import {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type AnchorHTMLAttributes,\n type ComponentPropsWithoutRef,\n type KeyboardEvent as ReactKeyboardEvent,\n type MouseEvent as ReactMouseEvent,\n type ReactNode,\n} from 'react';\nimport * as RadixDialog from '@radix-ui/react-dialog';\nimport * as RadixCollapsible from '@radix-ui/react-collapsible';\nimport * as RadixAccordion from '@radix-ui/react-accordion';\nimport * as RadixTooltip from '@radix-ui/react-tooltip';\nimport { AccordionContent } from '../accordion';\nimport { Slot } from '@radix-ui/react-slot';\nimport { cva } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport {\n ChevronRight,\n GripVertical,\n PanelLeftClose,\n PanelLeftOpen,\n Star,\n X,\n} from 'lucide-react';\n\n/* -------------------------------------------------------------------- */\n/* Types & context */\n/* -------------------------------------------------------------------- */\n\nexport type SidebarMode = 'expanded' | 'icon' | 'overlay';\nexport type SidebarDensity = 'default' | 'compact';\n\nexport interface SidebarContextValue {\n mode: SidebarMode;\n density: SidebarDensity;\n /** Transition the sidebar to a new mode from an internal toggle. */\n transitionTo?: (next: SidebarMode) => void;\n}\n\nconst SidebarContext = createContext<SidebarContextValue>({\n mode: 'expanded',\n density: 'default',\n});\n\nexport const useSidebar = () => useContext(SidebarContext);\n\n/* -------------------------------------------------------------------- */\n/* localStorage helpers (SSR-safe) */\n/* -------------------------------------------------------------------- */\n\nconst STORAGE_KEY = 'ui.sidebar.state';\n\nfunction readStoredState(defaultMode: SidebarMode): SidebarMode {\n if (typeof window === 'undefined') return defaultMode;\n try {\n const v = window.localStorage.getItem(STORAGE_KEY);\n if (v === 'expanded' || v === 'icon' || v === 'overlay') return v;\n } catch {\n /* noop */\n }\n return defaultMode;\n}\n\nfunction writeStoredState(value: SidebarMode) {\n if (typeof window === 'undefined') return;\n try {\n window.localStorage.setItem(STORAGE_KEY, value);\n } catch {\n /* noop */\n }\n}\n\n/* -------------------------------------------------------------------- */\n/* usePersistentState */\n/* */\n/* Drop-in `useState` replacement that mirrors its value to */\n/* `localStorage` under the given key. Same signature as `useState`, so */\n/* consumers can wire favourites / accordion / any sidebar preference to */\n/* survive reloads without plumbing effects by hand: */\n/* */\n/* const [pinnedIds, setPinnedIds] = */\n/* usePersistentState<string[]>('ui.sidebar.favorites', */\n/* ['dashboard', 'calendar']); */\n/* */\n/* SSR-safe and quota-safe (swallows serialize / storage errors). */\n/* -------------------------------------------------------------------- */\n\nexport function usePersistentState<T>(\n storageKey: string,\n initial: T | (() => T),\n): [T, (value: T | ((prev: T) => T)) => void] {\n const [value, setValue] = useState<T>(() => {\n if (typeof window === 'undefined') {\n return typeof initial === 'function' ? (initial as () => T)() : initial;\n }\n try {\n const raw = window.localStorage.getItem(storageKey);\n if (raw !== null) return JSON.parse(raw) as T;\n } catch {\n /* noop */\n }\n return typeof initial === 'function' ? (initial as () => T)() : initial;\n });\n\n useEffect(() => {\n if (typeof window === 'undefined') return;\n try {\n window.localStorage.setItem(storageKey, JSON.stringify(value));\n } catch {\n /* noop */\n }\n }, [storageKey, value]);\n\n return [value, setValue];\n}\n\n/* -------------------------------------------------------------------- */\n/* Root */\n/* -------------------------------------------------------------------- */\n\nconst railClasses = cva(\n [\n 'ds:flex ds:flex-col',\n // Sidebar sits at the page background in light mode (white-on-white\n // chrome separated by the inline-end border + --shadow-md). In dark\n // mode the Header already blends with --background, so we step the\n // sidebar one layer down (blue-600) to keep it visually distinct from\n // the header band — matches the PDF dark mockups' \"flat Dark Blue\n // surface with subtle depth via layering\" recipe.\n 'ds:bg-[var(--background)] ds:[.theme-dark_&]:bg-[color:var(--color-blue-600)] ds:text-[var(--foreground)]',\n 'ds:border-inline-end ds:border-[var(--border)]',\n // Resting-surface elevation — `--shadow-md` is deliberately lighter\n // than `--shadow-card` so it reads as chrome, not a floating card,\n // while still separating the rail from the page content on light\n // backgrounds. Forced-colors strips shadows globally, so the\n // `border-inline-end` above carries the separation cue for HCM.\n //\n // `relative z-[1]` lifts the rail above any sibling that paints a\n // solid background (e.g. AppFrame's `<main>` surface), otherwise\n // the shadow that projects towards the inline-end gets covered.\n 'ds:relative ds:z-[1] ds:shadow-[var(--shadow-md)]',\n 'ds:h-full',\n 'ds:transition-[inline-size] ds:duration-[var(--animation-duration)]',\n 'ds:motion-reduce:transition-none',\n ].join(' '),\n {\n variants: {\n mode: {\n // Tokenised widths modelled on Linear / Jira proportions.\n expanded: 'ds:w-[var(--sidebar-modern-expanded-size)]',\n icon: 'ds:w-[var(--sidebar-modern-icon-size)]',\n overlay: 'ds:w-[var(--sidebar-modern-expanded-size)]',\n },\n density: {\n default: '',\n compact: '',\n },\n },\n defaultVariants: { mode: 'expanded', density: 'default' },\n },\n);\n\nexport interface SidebarProps extends ComponentPropsWithoutRef<'nav'> {\n /** Visual mode. Controlled via `onStateChange`. @default 'expanded' */\n state?: SidebarMode;\n /** Uncontrolled default mode. @default 'expanded' */\n defaultState?: SidebarMode;\n /** Fires when the mode changes (user toggle or overlay open/close). */\n onStateChange?: (state: SidebarMode) => void;\n /** Compact density shrinks inline padding. @default 'default' */\n density?: SidebarDensity;\n /** Overlay-only: controlled open state. */\n open?: boolean;\n /** Overlay-only: fires when the dialog opens/closes. */\n onOpenChange?: (open: boolean) => void;\n /** Override the nav aria-label. */\n 'aria-label'?: string;\n}\n\nconst Sidebar = forwardRef<HTMLElement, SidebarProps>(\n (\n {\n state,\n defaultState = 'expanded',\n onStateChange,\n density = 'default',\n open,\n onOpenChange,\n 'aria-label': ariaLabel,\n className,\n children,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n const isControlled = state !== undefined;\n const [internalState, setInternalState] = useState<SidebarMode>(() =>\n isControlled ? state! : readStoredState(defaultState),\n );\n const resolved = isControlled ? state! : internalState;\n\n useEffect(() => {\n if (!isControlled) writeStoredState(internalState);\n }, [internalState, isControlled]);\n\n // Transition handler used by internal toggles. In controlled mode we\n // only fire `onStateChange` — the parent is responsible for updating\n // the `state` prop. In uncontrolled mode we also update local state.\n // Note: we intentionally do NOT echo the incoming `state` prop back to\n // `onStateChange` — that caused a feedback loop in controlled consumers.\n const transitionTo = useCallback(\n (next: SidebarMode) => {\n if (!isControlled) setInternalState(next);\n onStateChange?.(next);\n },\n [isControlled, onStateChange],\n );\n\n const label = ariaLabel ?? t('ui.navigation.sidebar.label');\n\n if (resolved === 'overlay') {\n return (\n <SidebarContext.Provider value={{ mode: 'overlay', density, transitionTo }}>\n <RadixDialog.Root open={open} onOpenChange={onOpenChange}>\n <RadixDialog.Portal>\n <RadixDialog.Overlay\n className={[\n 'ds:fixed ds:inset-0 ds:z-[var(--z-modal-backdrop)]',\n 'ds:bg-[var(--foreground)]/20 ds:backdrop-blur-sm',\n 'ds:data-[state=open]:animate-in ds:data-[state=open]:fade-in',\n 'ds:data-[state=closed]:animate-out ds:data-[state=closed]:fade-out',\n 'ds:motion-reduce:animate-none',\n ].join(' ')}\n />\n <RadixDialog.Content\n aria-label={label}\n className={[\n 'ds:fixed ds:z-[var(--z-modal)]',\n 'ds:inset-inline-start-0 ds:inset-block-start-0',\n 'ds:h-dvh',\n railClasses({ mode: 'overlay', density }),\n 'ds:shadow-[var(--shadow-xl)]',\n 'ds:data-[state=open]:animate-in ds:data-[state=closed]:animate-out',\n 'ds:data-[state=open]:slide-in-from-left ds:data-[state=closed]:slide-out-to-left',\n 'ds:rtl:data-[state=open]:slide-in-from-right ds:rtl:data-[state=closed]:slide-out-to-right',\n 'ds:motion-reduce:animate-none',\n 'ds:focus:outline-none',\n className ?? '',\n ]\n .filter(Boolean)\n .join(' ')}\n >\n <nav ref={ref} aria-label={label} className=\"ds:flex ds:flex-col ds:h-full\" {...rest}>\n {children}\n </nav>\n <RadixDialog.Close asChild>\n <button\n type=\"button\"\n aria-label={t('ui.navigation.sidebar.close')}\n className={[\n 'ds:absolute ds:top-[var(--spacing-sm)] ds:end-[var(--spacing-sm)]',\n 'ds:inline-flex ds:items-center ds:justify-center',\n 'ds:min-w-[var(--min-target-size)] ds:min-h-[var(--min-target-size)]',\n 'ds:rounded-[var(--radius-sm)] ds:text-[var(--muted-foreground)]',\n 'ds:hover:bg-[var(--muted)]/20 ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid ds:focus-visible:outline-[var(--ring)]',\n 'ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n ].join(' ')}\n >\n <X aria-hidden=\"true\" className=\"ds:size-4\" />\n </button>\n </RadixDialog.Close>\n </RadixDialog.Content>\n </RadixDialog.Portal>\n </RadixDialog.Root>\n </SidebarContext.Provider>\n );\n }\n\n return (\n <SidebarContext.Provider value={{ mode: resolved, density, transitionTo }}>\n <RadixTooltip.Provider delayDuration={300}>\n <nav\n ref={ref}\n aria-label={label}\n data-mode={resolved}\n data-density={density}\n className={[\n railClasses({ mode: resolved, density }),\n density === 'compact' ? 'ds:density-compact' : '',\n className ?? '',\n ]\n .filter(Boolean)\n .join(' ')}\n {...rest}\n >\n {children}\n </nav>\n </RadixTooltip.Provider>\n </SidebarContext.Provider>\n );\n },\n);\nSidebar.displayName = 'Sidebar';\n\n/* -------------------------------------------------------------------- */\n/* Header / Body / Footer */\n/* -------------------------------------------------------------------- */\n\nconst SidebarHeader = forwardRef<HTMLDivElement, ComponentPropsWithoutRef<'div'>>(\n ({ className, ...rest }, ref) => {\n const { mode } = useSidebar();\n return (\n <div\n ref={ref}\n className={[\n 'ds:relative ds:flex ds:items-center ds:gap-[var(--spacing-xs)]',\n 'ds:min-h-[var(--min-target-size)]',\n // Icon-rail is 64px — shrink horizontal padding so a 44×44\n // control fits centred inside the header.\n mode === 'icon'\n ? 'ds:justify-center ds:ps-[var(--spacing-xs)] ds:pe-[var(--spacing-xs)]'\n : 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)]',\n 'ds:py-[var(--spacing-sm)]',\n // Hairline border + downward chrome shadow cast the header as a\n // sticky top band above the scrolling body.\n 'ds:border-block-end ds:border-[var(--border)]',\n 'ds:shadow-[var(--shadow-chrome-down)]',\n className ?? '',\n ]\n .filter(Boolean)\n .join(' ')}\n {...rest}\n />\n );\n },\n);\nSidebarHeader.displayName = 'SidebarHeader';\n\nconst SidebarBody = forwardRef<HTMLDivElement, ComponentPropsWithoutRef<'div'>>(\n ({ className, ...rest }, ref) => (\n <div\n ref={ref}\n className={[\n 'ds:flex-1 ds:overflow-auto',\n 'ds:ps-[var(--spacing-xs)] ds:pe-[var(--spacing-xs)]',\n 'ds:py-[var(--spacing-sm)]',\n className ?? '',\n ]\n .filter(Boolean)\n .join(' ')}\n {...rest}\n />\n ),\n);\nSidebarBody.displayName = 'SidebarBody';\n\nconst SidebarFooter = forwardRef<HTMLDivElement, ComponentPropsWithoutRef<'div'>>(\n ({ className, ...rest }, ref) => {\n const { mode } = useSidebar();\n return (\n <div\n ref={ref}\n className={[\n 'ds:relative ds:flex ds:items-center ds:gap-[var(--spacing-xs)]',\n // Icon-rail is 64px — two 44×44 controls can't sit side-by-side,\n // so switch to a vertical stack and let each row self-centre.\n mode === 'icon'\n ? 'ds:flex-col ds:ps-[var(--spacing-xs)] ds:pe-[var(--spacing-xs)]'\n : 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)]',\n 'ds:min-h-[var(--min-target-size)]',\n 'ds:py-[var(--spacing-sm)]',\n // Hairline border + upward chrome shadow cast the footer as a\n // sticky bottom band below the scrolling body.\n 'ds:border-block-start ds:border-[var(--border)]',\n 'ds:shadow-[var(--shadow-chrome-up)]',\n className ?? '',\n ]\n .filter(Boolean)\n .join(' ')}\n {...rest}\n />\n );\n },\n);\nSidebarFooter.displayName = 'SidebarFooter';\n\n/* -------------------------------------------------------------------- */\n/* Section */\n/* -------------------------------------------------------------------- */\n\nexport interface SidebarSectionProps extends ComponentPropsWithoutRef<'div'> {\n /** Section label shown in expanded / overlay modes. */\n label?: string;\n /**\n * Optional leading glyph rendered inline with the section label. Stays\n * visible in `icon` mode (when the label collapses to `sr-only`) so the\n * user still has a visual grouping cue. Decorative — the label carries\n * the accessible name, so the icon slot is `aria-hidden`.\n */\n icon?: ReactNode;\n /**\n * Make the label an accordion trigger that collapses its children.\n * @default true\n */\n collapsible?: boolean;\n /** Uncontrolled default open state for the accordion. @default true */\n defaultOpen?: boolean;\n /** Controlled open state. */\n open?: boolean;\n /** Fires when the accordion opens / closes. */\n onOpenChange?: (open: boolean) => void;\n}\n\nconst sectionLabelClasses = [\n 'group/section-label flex w-full items-center',\n 'type-eyebrow',\n 'text-[var(--muted-foreground)]',\n 'ps-[var(--spacing-sm)] pe-[var(--spacing-sm)]',\n 'py-[var(--spacing-xs)]',\n 'hover:text-[var(--foreground)]',\n 'focus-visible:outline-[length:var(--focus-ring-width)] focus-visible:outline-solid',\n 'focus-visible:outline-[var(--ring)] focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'transition-colors duration-[var(--animation-duration)] motion-reduce:transition-none',\n].join(' ');\n\n// Leading icon rendered inside a section header (accordion trigger or plain\n// heading). `--accent` keeps it in the same tint as item-level icons so the\n// header reads as a grouping cue, not a control. `aria-hidden` because the\n// label carries the accessible name.\nconst sectionIconClasses = [\n 'inline-flex shrink-0 items-center justify-center',\n 'size-4',\n 'text-[var(--accent)]',\n 'me-[var(--spacing-xs)]',\n].join(' ');\n\nconst SidebarSection = forwardRef<HTMLDivElement, SidebarSectionProps>(\n (\n {\n label,\n icon,\n collapsible = true,\n defaultOpen = true,\n open,\n onOpenChange,\n className,\n children,\n ...rest\n },\n ref,\n ) => {\n const { mode } = useSidebar();\n const isIconMode = mode === 'icon';\n // Collapsing the section in icon mode hides icons the user needs for\n // navigation — skip the accordion behaviour there.\n const isAccordion = collapsible && !isIconMode && Boolean(label);\n\n const wrapperClasses = [\n 'flex flex-col',\n 'gap-[var(--spacing-xs)]',\n 'mt-[var(--spacing-sm)]',\n className ?? '',\n ]\n .filter(Boolean)\n .join(' ');\n\n if (!isAccordion) {\n // In icon mode, if there's no icon and no label to render, skip the\n // heading altogether. If there is an icon, it stays visible as the\n // grouping cue and the label collapses to sr-only.\n const hasHeading = Boolean(label) || Boolean(icon);\n return (\n <div ref={ref} className={wrapperClasses} {...rest}>\n {hasHeading ? (\n <span\n className={[\n 'ds:flex ds:items-center',\n 'type-eyebrow',\n 'ds:text-[var(--muted-foreground)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)]',\n 'ds:py-[var(--spacing-xs)]',\n isIconMode && !icon ? 'ds:sr-only' : '',\n ]\n .filter(Boolean)\n .join(' ')}\n >\n {icon ? (\n <span aria-hidden=\"true\" className={sectionIconClasses}>\n {icon}\n </span>\n ) : null}\n {label ? (\n <span className={isIconMode ? 'ds:sr-only' : ''}>{label}</span>\n ) : null}\n </span>\n ) : null}\n {children}\n </div>\n );\n }\n\n // Use the Radix Accordion primitive + the DS `AccordionContent`\n // component so the sidebar inherits the exact open/close animation\n // defined in `accordion.tsx` (`accordion-down` / `accordion-up`\n // keyframes). Any tweak there propagates here automatically.\n const accordionValue = 'section';\n return (\n <RadixAccordion.Root\n type=\"single\"\n collapsible\n defaultValue={\n open === undefined && defaultOpen ? accordionValue : undefined\n }\n value={open === undefined ? undefined : open ? accordionValue : ''}\n onValueChange={\n onOpenChange ? (v) => onOpenChange(v === accordionValue) : undefined\n }\n asChild\n >\n <div ref={ref} className={wrapperClasses} {...rest}>\n <RadixAccordion.Item value={accordionValue}>\n <RadixAccordion.Header className=\"ds:flex\">\n <RadixAccordion.Trigger className={sectionLabelClasses}>\n {icon ? (\n <span aria-hidden=\"true\" className={sectionIconClasses}>\n {icon}\n </span>\n ) : null}\n <span className=\"ds:flex-1 ds:text-start\">{label}</span>\n <ChevronRight\n aria-hidden=\"true\"\n className=\"ds:size-3 ds:transition-transform ds:group-data-[state=open]/section-label:rotate-90 ds:rtl:-scale-x-100 ds:motion-reduce:transition-none\"\n />\n </RadixAccordion.Trigger>\n </RadixAccordion.Header>\n <AccordionContent\n aria-label={label}\n // Flatten the inner padding wrapper AccordionContent adds —\n // the sidebar sections don't want the 16px padding block\n // that Accordion cards use. `display: contents` strips the\n // wrapper from layout so our children flow directly into\n // the flex column with the gap we set here.\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)] ds:[&>div]:contents\"\n >\n {children}\n </AccordionContent>\n </RadixAccordion.Item>\n </div>\n </RadixAccordion.Root>\n );\n },\n);\nSidebarSection.displayName = 'SidebarSection';\n\n/* -------------------------------------------------------------------- */\n/* Group (collapsible) */\n/* -------------------------------------------------------------------- */\n\nexport interface SidebarGroupProps\n extends ComponentPropsWithoutRef<typeof RadixCollapsible.Root> {\n /** Visible label for the group trigger. */\n label: string;\n /** Optional leading icon. */\n icon?: ReactNode;\n}\n\nconst groupTriggerClasses = [\n 'group flex w-full items-center gap-[var(--spacing-sm)]',\n 'min-h-[var(--min-target-size)]',\n 'ps-[var(--spacing-sm)] pe-[var(--spacing-sm)]',\n 'rounded-[var(--radius-sm)]',\n 'text-[var(--foreground)] text-[var(--font-size-sm)]',\n 'font-[var(--font-weight-medium)]',\n 'hover:bg-[var(--muted)]/20',\n 'focus-visible:outline-[length:var(--focus-ring-width)] focus-visible:outline-solid',\n 'focus-visible:outline-[var(--ring)] focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'transition-colors duration-[var(--animation-duration)] motion-reduce:transition-none',\n].join(' ');\n\nconst SidebarGroup = forwardRef<HTMLDivElement, SidebarGroupProps>(\n ({ label, icon, children, className, defaultOpen, open, onOpenChange, ...rest }, ref) => {\n const { mode } = useSidebar();\n return (\n <RadixCollapsible.Root\n ref={ref}\n defaultOpen={defaultOpen}\n open={open}\n onOpenChange={onOpenChange}\n className={className}\n {...rest}\n >\n <RadixCollapsible.Trigger className={groupTriggerClasses}>\n {icon ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:inline-flex ds:items-center ds:text-[var(--accent)]\"\n >\n {icon}\n </span>\n ) : null}\n <span\n className={[\n 'ds:flex-1 ds:text-start',\n mode === 'icon' ? 'ds:sr-only' : '',\n ].join(' ')}\n >\n {label}\n </span>\n {mode !== 'icon' ? (\n <ChevronRight\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:transition-transform ds:group-data-[state=open]:rotate-90 ds:rtl:-scale-x-100 ds:motion-reduce:transition-none\"\n />\n ) : null}\n </RadixCollapsible.Trigger>\n <RadixCollapsible.Content\n className={[\n 'ds:overflow-hidden',\n 'ds:data-[state=open]:animate-in ds:data-[state=closed]:animate-out',\n 'ds:motion-reduce:animate-none',\n 'ds:ps-[var(--spacing-md)]',\n ].join(' ')}\n >\n {children}\n </RadixCollapsible.Content>\n </RadixCollapsible.Root>\n );\n },\n);\nSidebarGroup.displayName = 'SidebarGroup';\n\n/* -------------------------------------------------------------------- */\n/* Item */\n/* -------------------------------------------------------------------- */\n\nconst itemClasses = cva(\n [\n // Every row is a pin-hover parent so inline pin / reorder affordances can\n // fade in on hover of the whole row — keep `group/item` on this selector.\n // `!text-[var(--foreground)]` forces the label colour over the browser's\n // default `<a>` link colour (blue-violet) and any inherited hue. The\n // active variant also uses `!text-*` so it still wins when needed.\n 'ds:group/item ds:relative ds:flex ds:items-center',\n 'ds:gap-[var(--spacing-sm)]',\n 'ds:no-underline ds:!text-[var(--foreground)] ds:text-[length:var(--font-size-sm)]',\n 'ds:hover:bg-[var(--muted)]/12',\n 'ds:transition-colors ds:duration-[var(--animation-duration)]',\n 'ds:motion-reduce:transition-none',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n ].join(' '),\n {\n variants: {\n mode: {\n expanded: [\n 'ds:min-h-[var(--min-target-size)] ds:rounded-[var(--radius-sm)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)]',\n ].join(' '),\n // Icon-only: each item is a 44×44 pill tile centered in the rail.\n // The active / hover background fills just the tile rather than the\n // whole row — matching Linear / Asana chrome.\n icon: [\n 'ds:justify-center ds:ms-auto ds:me-auto',\n 'ds:w-[var(--min-target-size)] ds:h-[var(--min-target-size)]',\n 'ds:ps-0 ds:pe-0 ds:rounded-[var(--radius-md)]',\n ].join(' '),\n overlay: [\n 'ds:min-h-[var(--min-target-size)] ds:rounded-[var(--radius-sm)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)]',\n ].join(' '),\n },\n density: {\n default: '',\n compact: 'ds:ps-[var(--spacing-xs)] ds:pe-[var(--spacing-xs)]',\n },\n isActive: {\n // Filled pill — multi-carrier (bg + text + weight + aria-current at\n // render time) so colour is never the sole identifier. `!text-*`\n // forces the foreground over any inherited / base rule so the icon\n // and label read clearly against the primary fill in every theme.\n true: [\n 'ds:bg-[var(--primary)] ds:!text-[var(--primary-foreground)]',\n 'ds:font-[var(--font-weight-semibold)]',\n // Keep hover from dimming the active fill.\n 'ds:hover:bg-[var(--primary)]',\n ].join(' '),\n false: '',\n },\n },\n defaultVariants: {\n mode: 'expanded',\n density: 'default',\n isActive: false,\n },\n },\n);\n\nexport interface SidebarItemProps extends AnchorHTMLAttributes<HTMLAnchorElement> {\n /** Mark the item as the current page (`aria-current='page'`). */\n isActive?: boolean;\n /** Render through Radix `Slot` so a router link can take over. */\n asChild?: boolean;\n /**\n * Whether this item is currently pinned to Favourites. Only consulted\n * when `onPinChange` is supplied.\n */\n isPinned?: boolean;\n /**\n * Fires with the new pinned state when the user clicks the star. Passing\n * this prop opts the row into the always-on pin affordance — a star\n * outline fades in on row hover / focus and fills when pinned. Hidden in\n * icon-only mode where there is no room for trailing controls.\n */\n onPinChange?: (next: boolean) => void;\n /** Accessible label for the pin button. Defaults to the item's `aria-label`. */\n pinLabel?: string;\n}\n\nconst SidebarItem = forwardRef<HTMLAnchorElement, SidebarItemProps>(\n (\n {\n asChild = false,\n isActive = false,\n isPinned = false,\n onPinChange,\n pinLabel,\n className,\n children,\n 'aria-label': ariaLabel,\n ...rest\n },\n ref,\n ) => {\n const { mode, density } = useSidebar();\n const Comp = asChild ? Slot : 'a';\n const showPin = onPinChange !== undefined && mode !== 'icon';\n\n const anchor = (\n <Comp\n ref={ref as never}\n aria-current={isActive ? 'page' : undefined}\n aria-label={ariaLabel}\n className={itemClasses({\n mode,\n density,\n isActive,\n className: showPin ? 'flex-1 min-w-0' : className,\n })}\n {...rest}\n >\n {children}\n </Comp>\n );\n\n const body = showPin ? (\n <div\n className={[\n 'ds:group/item ds:flex ds:items-center ds:gap-[var(--spacing-2xs)]',\n className ?? '',\n ]\n .filter(Boolean)\n .join(' ')}\n >\n {anchor}\n <SidebarPinButton\n isPinned={isPinned}\n label={pinLabel ?? ariaLabel ?? ''}\n onPinChange={onPinChange}\n />\n </div>\n ) : (\n anchor\n );\n\n // In icon-only mode, wrap the item in a Radix Tooltip showing the label.\n if (mode === 'icon' && ariaLabel) {\n return (\n <RadixTooltip.Root>\n <RadixTooltip.Trigger asChild>{body}</RadixTooltip.Trigger>\n <RadixTooltip.Portal>\n <RadixTooltip.Content\n side=\"right\"\n sideOffset={6}\n className={[\n 'ds:z-[var(--z-tooltip)] ds:max-w-[16rem]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:bg-[var(--foreground)] ds:text-[var(--background)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)] ds:py-[var(--spacing-xs)] ds:text-[var(--font-size-xs)]',\n 'ds:animate-in ds:fade-in ds:zoom-in-95 ds:motion-reduce:animate-none',\n ].join(' ')}\n >\n {ariaLabel}\n <RadixTooltip.Arrow className=\"ds:fill-[var(--foreground)]\" />\n </RadixTooltip.Content>\n </RadixTooltip.Portal>\n </RadixTooltip.Root>\n );\n }\n\n return body;\n },\n);\nSidebarItem.displayName = 'SidebarItem';\n\n/* -------------------------------------------------------------------- */\n/* Item slots — Icon, Label, Badge */\n/* -------------------------------------------------------------------- */\n\nconst SidebarItemIcon = forwardRef<HTMLSpanElement, ComponentPropsWithoutRef<'span'>>(\n ({ className, children, ...rest }, ref) => (\n <span\n ref={ref}\n aria-hidden=\"true\"\n className={[\n 'ds:inline-flex ds:shrink-0 ds:items-center ds:justify-center',\n 'ds:size-5',\n // Icons carry the accent tint by default so the rail reads less\n // monotone against the violet active pill. The active row sets\n // `aria-current=\"page\"` on the anchor (which is `group/item`), so\n // the icon flips to the primary-foreground (white) on the filled\n // pill — keeping it readable on the primary background.\n 'ds:text-[var(--accent)]',\n 'ds:group-aria-[current=page]/item:text-[var(--primary-foreground)]',\n className ?? '',\n ]\n .filter(Boolean)\n .join(' ')}\n {...rest}\n >\n {children}\n </span>\n ),\n);\nSidebarItemIcon.displayName = 'SidebarItemIcon';\n\nconst SidebarItemLabel = forwardRef<HTMLSpanElement, ComponentPropsWithoutRef<'span'>>(\n ({ className, children, ...rest }, ref) => {\n const { mode } = useSidebar();\n return (\n <span\n ref={ref}\n className={[\n 'ds:flex-1',\n 'ds:overflow-hidden ds:text-ellipsis ds:whitespace-nowrap ds:break-normal',\n 'ds:text-start',\n mode === 'icon' ? 'ds:sr-only' : '',\n className ?? '',\n ]\n .filter(Boolean)\n .join(' ')}\n {...rest}\n >\n {children}\n </span>\n );\n },\n);\nSidebarItemLabel.displayName = 'SidebarItemLabel';\n\nconst SidebarItemBadge = forwardRef<HTMLSpanElement, ComponentPropsWithoutRef<'span'>>(\n ({ className, children, ...rest }, ref) => {\n const { mode } = useSidebar();\n const isIcon = mode === 'icon';\n // --accent on a light surface is magenta-500 (~3.2:1 on white) and\n // fails WCAG AA for `--font-size-xs` text per 05-accessibility §Accent.\n // Use --primary + its token-paired foreground so contrast is preserved\n // in every theme.\n //\n // In icon mode the pill collapses to a compact presence indicator: a\n // 10×10 dot perched on the top-end of the icon tile with a background-\n // coloured ring so it reads against any row fill. The numeric count is\n // hidden visually but stays in the accessible name via an sr-only span.\n return (\n <span\n ref={ref}\n aria-hidden={isIcon ? 'true' : undefined}\n className={[\n 'ds:inline-flex ds:items-center ds:justify-center',\n 'ds:font-[var(--font-weight-semibold)]',\n isIcon\n ? [\n 'ds:absolute ds:top-[2px] ds:end-[2px]',\n 'ds:min-w-0 ds:size-[10px] ds:ps-0 ds:pe-0',\n 'ds:rounded-[var(--radius-full)]',\n 'ds:bg-[var(--primary)] ds:text-transparent',\n 'ds:ring-2 ds:ring-[var(--background)]',\n 'ds:pointer-events-none',\n ].join(' ')\n : [\n 'ds:min-w-[var(--spacing-lg)] ds:h-[var(--spacing-lg)]',\n 'ds:rounded-[var(--radius-full)]',\n 'ds:bg-[var(--primary)] ds:text-[var(--primary-foreground)]',\n 'ds:text-[length:var(--font-size-xs)]',\n 'ds:ps-[var(--spacing-xs)] ds:pe-[var(--spacing-xs)]',\n ].join(' '),\n className ?? '',\n ]\n .filter(Boolean)\n .join(' ')}\n {...rest}\n >\n {children}\n </span>\n );\n },\n);\nSidebarItemBadge.displayName = 'SidebarItemBadge';\n\n/* -------------------------------------------------------------------- */\n/* Modern-only compound pieces */\n/* */\n/* These components ship styling that matches the modern aesthetic. */\n/* They are INTERACTION STUBS — they render the correct chrome but do */\n/* not open a DropdownMenu, because the DS <DropdownMenu> wrapper does */\n/* not exist yet (see review-findings/component-cohesion.mdx). Consumers */\n/* wire their own Radix DropdownMenu around these triggers until the DS */\n/* wrapper lands. Do NOT add aria-haspopup here — it would announce a */\n/* menu that never opens (screen-reader lie). */\n/* -------------------------------------------------------------------- */\n\nconst workspaceSwitcherClasses = cva(\n [\n 'ds:flex ds:items-center ds:gap-[var(--spacing-sm)]',\n 'ds:min-h-[var(--min-target-size)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)]',\n 'ds:rounded-[var(--radius-md)]',\n 'ds:text-[var(--foreground)] ds:text-[var(--font-size-sm)]',\n 'ds:hover:bg-[var(--muted)]/20',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n 'ds:no-underline',\n ].join(' '),\n);\n\nexport interface SidebarWorkspaceSwitcherProps\n extends ComponentPropsWithoutRef<'button'> {\n /** Workspace glyph — square <Avatar>, <img>, or <svg>. Required. */\n logo: ReactNode;\n /** Workspace name. Hidden in icon mode; always the accessible name. */\n name: string;\n /** Trailing chevron for the dropdown affordance. Defaults to true. */\n showChevron?: boolean;\n}\n\nconst SidebarWorkspaceSwitcher = forwardRef<\n HTMLButtonElement,\n SidebarWorkspaceSwitcherProps\n>(({ logo, name, showChevron = true, className, ...rest }, ref) => {\n const { mode } = useSidebar();\n const showLabel = mode !== 'icon';\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label={name}\n className={[workspaceSwitcherClasses(), className].filter(Boolean).join(' ')}\n {...rest}\n >\n <span aria-hidden=\"true\" className=\"ds:inline-flex ds:items-center ds:shrink-0\">\n {logo}\n </span>\n {showLabel ? (\n <>\n <span\n className=\"ds:truncate ds:flex-1 ds:text-start ds:max-w-[var(--header-workspace-max-inline-size)]\"\n >\n {name}\n </span>\n {showChevron ? (\n <ChevronRight\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:shrink-0 ds:rotate-90\"\n />\n ) : null}\n </>\n ) : null}\n </button>\n );\n});\nSidebarWorkspaceSwitcher.displayName = 'SidebarWorkspaceSwitcher';\n\n/* -- Primary action slot -------------------------------------------- */\n\nconst primaryActionClasses = cva(\n [\n 'ds:flex ds:items-center ds:justify-center ds:gap-[var(--spacing-xs)]',\n 'ds:min-h-[var(--min-target-size)]',\n 'ds:rounded-[var(--radius-md)]',\n 'ds:bg-[var(--primary)] ds:text-[var(--primary-foreground)]',\n 'ds:font-[var(--font-weight-semibold)] ds:text-[var(--font-size-sm)]',\n 'ds:hover:bg-[var(--primary-hover)]',\n 'ds:transition-colors ds:motion-reduce:transition-none',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n ].join(' '),\n {\n variants: {\n mode: {\n expanded: 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)]',\n icon: 'ds:ps-0 ds:pe-0 ds:w-[var(--sidebar-modern-tile)] ds:h-[var(--sidebar-modern-tile)] ds:ms-auto ds:me-auto',\n overlay: 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)]',\n },\n },\n defaultVariants: { mode: 'expanded' },\n },\n);\n\nexport interface SidebarPrimaryActionProps\n extends ComponentPropsWithoutRef<'button'> {\n icon: ReactNode;\n /** Button label — hidden in icon mode, always the accessible name. */\n label: string;\n /** Optional keyboard shortcut displayed on inline-end in expanded mode. */\n shortcut?: string;\n}\n\nconst SidebarPrimaryAction = forwardRef<\n HTMLButtonElement,\n SidebarPrimaryActionProps\n>(({ icon, label, shortcut, className, ...rest }, ref) => {\n const { mode } = useSidebar();\n const showLabel = mode !== 'icon';\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label={label}\n aria-keyshortcuts={shortcut}\n className={[primaryActionClasses({ mode }), className]\n .filter(Boolean)\n .join(' ')}\n {...rest}\n >\n <span aria-hidden=\"true\" className=\"ds:inline-flex ds:size-4 ds:items-center ds:justify-center\">\n {icon}\n </span>\n {showLabel ? (\n <>\n <span className=\"ds:truncate\">{label}</span>\n {shortcut ? (\n <kbd className=\"ds:ms-auto ds:text-[length:var(--font-size-xs)] ds:font-[family-name:var(--font-mono)] ds:opacity-80\">\n {shortcut}\n </kbd>\n ) : null}\n </>\n ) : null}\n </button>\n );\n});\nSidebarPrimaryAction.displayName = 'SidebarPrimaryAction';\n\n/* -- Pin button ----------------------------------------------------- */\n\n/**\n * Toggleable star button used to pin / unpin a nav item to the Favorites\n * section. Rendered inline alongside a `SidebarItem`'s content — hidden in\n * icon mode (pin affordances only make sense when the full row is visible).\n *\n * Controlled via `isPinned` + `onPinChange`. The consumer owns the list of\n * pinned items and mirrors them into `<SidebarFavorites>`.\n */\nexport interface SidebarPinButtonProps\n extends Omit<ComponentPropsWithoutRef<'button'>, 'onChange'> {\n /** Whether the associated item is currently pinned. */\n isPinned: boolean;\n /** Fires with the new pinned state. */\n onPinChange?: (next: boolean) => void;\n /**\n * Accessible label that names what is being pinned — e.g. the item's\n * label. Required so screen-readers can tell pin buttons apart.\n */\n label: string;\n}\n\nconst pinButtonClasses = [\n 'inline-flex items-center justify-center shrink-0',\n 'size-6 rounded-[var(--radius-sm)]',\n // Pin stars carry the accent tint to match every other icon in the rail.\n // Stays quiet via opacity — reveals only on row hover / focus.\n 'text-[var(--accent)]',\n 'opacity-0 group-hover/item:opacity-100 focus-visible:opacity-100',\n 'hover:bg-[var(--muted)]/20',\n 'focus-visible:outline-[length:var(--focus-ring-width)] focus-visible:outline-solid',\n 'focus-visible:outline-[var(--ring)] focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'forced-colors:focus-visible:outline-[CanvasText]',\n 'transition-[color,opacity,background-color] duration-[var(--animation-duration)]',\n 'motion-reduce:transition-none',\n].join(' ');\n\nconst SidebarPinButton = forwardRef<HTMLButtonElement, SidebarPinButtonProps>(\n (\n { isPinned, onPinChange, label, className, onClick, ...rest },\n ref,\n ) => {\n const { t } = useTranslation();\n const { mode } = useSidebar();\n if (mode === 'icon') return null;\n const accessibleLabel = isPinned\n ? t('ui.navigation.sidebar.unpinItem', 'Unpin {{label}}', { label })\n : t('ui.navigation.sidebar.pinItem', 'Pin {{label}}', { label });\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label={accessibleLabel}\n aria-pressed={isPinned}\n className={[pinButtonClasses, className].filter(Boolean).join(' ')}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n onPinChange?.(!isPinned);\n onClick?.(event);\n }}\n {...rest}\n >\n <Star\n aria-hidden=\"true\"\n className=\"ds:size-4\"\n fill={isPinned ? 'currentColor' : 'none'}\n />\n </button>\n );\n },\n);\nSidebarPinButton.displayName = 'SidebarPinButton';\n\n/* -- Favorites — reorderable section -------------------------------- */\n\ninterface SidebarFavoritesContextValue {\n onReorder?: (from: number, to: number) => void;\n count: number;\n dragSource: number | null;\n setDragSource: (index: number | null) => void;\n announce: (message: string) => void;\n}\n\nconst SidebarFavoritesContext =\n createContext<SidebarFavoritesContextValue | null>(null);\n\nconst useFavoritesContext = () => useContext(SidebarFavoritesContext);\n\n/**\n * Renders `<SidebarSection heading={t('ui.sidebar.favorites')}>` with an\n * empty-state prompt when no children are supplied. When `onReorder` is\n * provided, children rendered as `<SidebarFavoriteItem>` become drag-and-drop\n * and keyboard reorderable (Alt+↑ / Alt+↓).\n */\nexport interface SidebarFavoritesProps extends ComponentPropsWithoutRef<'div'> {\n heading?: string;\n /** Shown when `children` is empty. */\n emptyMessage?: string;\n /**\n * Called when a favorite item is moved from `from` index to `to` index.\n * Providing this opts the section into drag-and-drop + keyboard reorder.\n */\n onReorder?: (from: number, to: number) => void;\n}\n\nconst SidebarFavorites = forwardRef<HTMLDivElement, SidebarFavoritesProps>(\n (\n { heading, emptyMessage, onReorder, className, children, ...rest },\n ref,\n ) => {\n const { t } = useTranslation();\n const resolvedHeading =\n heading ?? t('ui.navigation.sidebar.favorites', 'Favourites');\n const childArray = Array.isArray(children)\n ? children.filter(Boolean)\n : children\n ? [children]\n : [];\n const count = childArray.length;\n const hasChildren = count > 0;\n const [dragSource, setDragSource] = useState<number | null>(null);\n const [liveMessage, setLiveMessage] = useState('');\n // Re-emit identical announcements by toggling an invisible suffix so\n // screen-readers treat repeated moves as distinct.\n const announceToggle = useRef(false);\n const announce = useCallback((message: string) => {\n announceToggle.current = !announceToggle.current;\n setLiveMessage(\n announceToggle.current ? message : `${message}\\u200b`,\n );\n }, []);\n\n const value = useMemo<SidebarFavoritesContextValue>(\n () => ({ onReorder, count, dragSource, setDragSource, announce }),\n [onReorder, count, dragSource, announce],\n );\n\n // When there are no pinned items, render nothing by default — no\n // heading, no empty-state copy. Consumers that want an explicit empty\n // state can pass `emptyMessage` to opt in.\n if (!hasChildren && !emptyMessage) return null;\n\n return (\n <SidebarFavoritesContext.Provider value={value}>\n <SidebarSection\n ref={ref}\n label={resolvedHeading}\n className={className}\n {...rest}\n >\n {hasChildren ? (\n childArray\n ) : (\n <p className=\"ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)] type-meta ds:text-[color:var(--muted-foreground)]\">\n {emptyMessage}\n </p>\n )}\n <span role=\"status\" aria-live=\"polite\" className=\"ds:sr-only\">\n {liveMessage}\n </span>\n </SidebarSection>\n </SidebarFavoritesContext.Provider>\n );\n },\n);\nSidebarFavorites.displayName = 'SidebarFavorites';\n\n/* -- Favorite item with drag handle + keyboard reorder -------------- */\n\nexport interface SidebarFavoriteItemProps extends SidebarItemProps {\n /** Zero-based position of this item within its `<SidebarFavorites>`. */\n index: number;\n /**\n * Accessible name used by the drag handle and live-region announcements.\n * Defaults to the `aria-label` of the underlying `SidebarItem`.\n */\n reorderLabel?: string;\n}\n\nconst favoriteRowClasses = cva(\n [\n 'ds:group/item ds:relative ds:flex ds:items-center ds:gap-[var(--spacing-2xs)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n ].join(' '),\n {\n variants: {\n dragging: {\n true: 'ds:opacity-60',\n false: '',\n },\n dropTarget: {\n true: 'ds:outline-[length:var(--focus-ring-width)] ds:outline-dashed ds:outline-[var(--primary)] ds:outline-offset-[-2px]',\n false: '',\n },\n },\n defaultVariants: { dragging: false, dropTarget: false },\n },\n);\n\nconst dragHandleClasses = [\n 'inline-flex items-center justify-center shrink-0',\n 'size-6 rounded-[var(--radius-sm)]',\n 'cursor-grab active:cursor-grabbing',\n 'text-[var(--muted-foreground)]',\n // Quiet chrome — only reveal the grip when the row is hovered or the\n // handle itself is focused (keyboard / AT). Matches the pin-star's\n // reveal-on-hover behaviour so the two siblings appear together.\n 'opacity-0 group-hover/item:opacity-100 focus-visible:opacity-100',\n 'hover:bg-[var(--muted)]/20 hover:text-[var(--foreground)]',\n 'focus-visible:outline-[length:var(--focus-ring-width)] focus-visible:outline-solid',\n 'focus-visible:outline-[var(--ring)] focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'forced-colors:focus-visible:outline-[CanvasText]',\n 'transition-[color,opacity,background-color] duration-[var(--animation-duration)] motion-reduce:transition-none',\n].join(' ');\n\nconst SidebarFavoriteItem = forwardRef<\n HTMLAnchorElement,\n SidebarFavoriteItemProps\n>(\n (\n {\n index,\n isActive = false,\n asChild = false,\n reorderLabel,\n isPinned = false,\n onPinChange,\n pinLabel,\n 'aria-label': ariaLabel,\n className,\n children,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n const { mode } = useSidebar();\n const favorites = useFavoritesContext();\n const [isDropTarget, setIsDropTarget] = useState(false);\n const canReorder = Boolean(favorites?.onReorder) && mode !== 'icon';\n const label = reorderLabel ?? ariaLabel ?? '';\n const handleId = useId();\n\n const moveFromTo = (from: number, to: number) => {\n if (!favorites?.onReorder) return;\n const clamped = Math.max(0, Math.min(favorites.count - 1, to));\n if (clamped === from) return;\n favorites.onReorder(from, clamped);\n favorites.announce(\n t(\n 'ui.navigation.sidebar.reorderAnnounce',\n '{{label}} moved to position {{to}} of {{total}}',\n { label, to: clamped + 1, total: favorites.count },\n ),\n );\n };\n\n const onHandleKeyDown = (event: ReactKeyboardEvent<HTMLButtonElement>) => {\n if (!canReorder) return;\n if (event.altKey && event.key === 'ArrowUp') {\n event.preventDefault();\n moveFromTo(index, index - 1);\n } else if (event.altKey && event.key === 'ArrowDown') {\n event.preventDefault();\n moveFromTo(index, index + 1);\n } else if (event.key === 'Home' && event.altKey) {\n event.preventDefault();\n moveFromTo(index, 0);\n } else if (event.key === 'End' && event.altKey) {\n event.preventDefault();\n moveFromTo(index, favorites!.count - 1);\n }\n };\n\n const onDragStart = (event: ReactMouseEvent & { dataTransfer?: DataTransfer }) => {\n if (!canReorder) return;\n favorites?.setDragSource(index);\n if (event.dataTransfer) {\n event.dataTransfer.effectAllowed = 'move';\n // Firefox requires data to initiate a drag.\n event.dataTransfer.setData('text/plain', String(index));\n }\n };\n\n const onDragEnd = () => {\n favorites?.setDragSource(null);\n setIsDropTarget(false);\n };\n\n const onDragOver = (event: ReactMouseEvent & { dataTransfer?: DataTransfer }) => {\n if (!canReorder || favorites?.dragSource === null) return;\n event.preventDefault();\n if (event.dataTransfer) event.dataTransfer.dropEffect = 'move';\n setIsDropTarget(true);\n };\n\n const onDragLeave = () => setIsDropTarget(false);\n\n const onDrop = (event: ReactMouseEvent) => {\n if (!canReorder) return;\n event.preventDefault();\n const source = favorites?.dragSource;\n setIsDropTarget(false);\n if (source === null || source === undefined || source === index) return;\n moveFromTo(source, index);\n };\n\n const isDragging = favorites?.dragSource === index;\n\n return (\n <div\n className={favoriteRowClasses({\n dragging: isDragging,\n dropTarget: isDropTarget && !isDragging,\n })}\n // Drag the whole row — the grip is a visual + keyboard affordance,\n // not the sole drag target. Buttons don't start HTML5 drags reliably\n // in every browser, so we mount the drag events on the row wrapper.\n draggable={canReorder || undefined}\n onDragStart={\n canReorder\n ? (onDragStart as unknown as (e: ReactMouseEvent<HTMLDivElement>) => void)\n : undefined\n }\n onDragEnd={canReorder ? onDragEnd : undefined}\n onDragOver={onDragOver as unknown as (e: ReactMouseEvent<HTMLDivElement>) => void}\n onDragLeave={onDragLeave}\n onDrop={onDrop}\n >\n <SidebarItem\n ref={ref}\n isActive={isActive}\n asChild={asChild}\n aria-label={ariaLabel}\n aria-describedby={canReorder ? handleId : undefined}\n // Links and images are `draggable=auto` by default — without this\n // the browser would fire its native link-drag before our row-level\n // drag, and our reorder would never start.\n draggable={canReorder ? false : undefined}\n className={[\n canReorder ? 'ds:flex-1 ds:min-w-0' : '',\n className ?? '',\n ]\n .filter(Boolean)\n .join(' ')}\n {...rest}\n >\n {children}\n </SidebarItem>\n {canReorder ? (\n <button\n type=\"button\"\n id={handleId}\n aria-label={t(\n 'ui.navigation.sidebar.reorderHandle',\n 'Reorder {{label}}. Press Alt + Up or Alt + Down to move.',\n { label },\n )}\n className={dragHandleClasses}\n onKeyDown={onHandleKeyDown}\n >\n <GripVertical aria-hidden=\"true\" className=\"ds:size-4\" />\n </button>\n ) : null}\n {onPinChange && mode !== 'icon' ? (\n <SidebarPinButton\n isPinned={isPinned}\n label={pinLabel ?? ariaLabel ?? ''}\n onPinChange={onPinChange}\n />\n ) : null}\n </div>\n );\n },\n);\nSidebarFavoriteItem.displayName = 'SidebarFavoriteItem';\n\n/* -- Profile pill at the block-end --------------------------------- */\n\nconst profilePillClasses = cva(\n [\n 'ds:flex ds:items-center ds:gap-[var(--spacing-sm)]',\n 'ds:min-h-[var(--min-target-size)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)]',\n 'ds:rounded-[var(--radius-md)]',\n 'ds:text-[var(--foreground)] ds:text-[var(--font-size-sm)]',\n 'ds:hover:bg-[var(--muted)]/20',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n 'ds:no-underline',\n ].join(' '),\n);\n\nexport interface SidebarProfilePillProps\n extends ComponentPropsWithoutRef<'button'> {\n /** Avatar or other identifying glyph. Required. */\n avatar: ReactNode;\n /** User's display name — hidden in icon mode, always the accessible name. */\n name: string;\n /**\n * Secondary line (e.g. selected studio, \"Owner\", \"Admin\"). Accepts arbitrary\n * JSX so an icon can sit inline with the text. Hidden in icon mode.\n */\n subtitle?: ReactNode;\n /**\n * Plain-text form of the subtitle for the accessible name. Required when\n * `subtitle` is not a string; ignored otherwise.\n */\n subtitleLabel?: string;\n}\n\nconst SidebarProfilePill = forwardRef<\n HTMLButtonElement,\n SidebarProfilePillProps\n>(({ avatar, name, subtitle, subtitleLabel, className, ...rest }, ref) => {\n const { mode } = useSidebar();\n const showLabel = mode !== 'icon';\n const accessibleSubtitle =\n typeof subtitle === 'string' ? subtitle : subtitleLabel;\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label={\n accessibleSubtitle ? `${name}, ${accessibleSubtitle}` : name\n }\n // No `aria-haspopup` here until a DropdownMenu is wired — announcing\n // a menu that never opens is a screen-reader lie. Consumers wrap\n // this trigger in their own Radix DropdownMenu.\n className={[profilePillClasses(), className].filter(Boolean).join(' ')}\n {...rest}\n >\n <span aria-hidden=\"true\" className=\"ds:inline-flex ds:items-center ds:shrink-0\">\n {avatar}\n </span>\n {showLabel ? (\n <span className=\"ds:flex-1 ds:min-w-0 ds:text-start\">\n <span className=\"ds:block ds:truncate type-label\">{name}</span>\n {subtitle ? (\n typeof subtitle === 'string' ? (\n <span className=\"ds:block ds:truncate type-meta ds:text-[color:var(--muted-foreground)]\">\n {subtitle}\n </span>\n ) : (\n <span className=\"ds:flex ds:items-center ds:gap-[length:var(--spacing-xs)] ds:min-w-0 type-meta ds:text-[color:var(--muted-foreground)]\">\n {subtitle}\n </span>\n )\n ) : null}\n </span>\n ) : null}\n </button>\n );\n});\nSidebarProfilePill.displayName = 'SidebarProfilePill';\n\n/* -------------------------------------------------------------------- */\n/* Collapse trigger */\n/* */\n/* Full-width nav-item-style toggle that swaps between `expanded` and */\n/* `icon` modes. A compact 44×44 icon-only button — drop it inline next */\n/* to the profile pill, Settings row, or anywhere else. Accessible name */\n/* comes from the i18n collapse / expand string; a tooltip shows the */\n/* same text on hover / focus so sighted users don't have to guess. */\n/* */\n/* Hidden in `overlay` mode (overlay has its own close button). */\n/* -------------------------------------------------------------------- */\n\nexport interface SidebarCollapseTriggerProps\n extends ComponentPropsWithoutRef<'button'> {\n /** Override the accessible label. Defaults to the i18n collapse/expand string. */\n 'aria-label'?: string;\n}\n\nconst collapseTriggerClasses = [\n 'inline-flex items-center justify-center shrink-0',\n 'min-w-[var(--min-target-size)] min-h-[var(--min-target-size)]',\n 'rounded-[var(--radius-sm)]',\n 'text-[var(--muted-foreground)]',\n 'hover:bg-[var(--muted)]/20 hover:text-[var(--foreground)]',\n 'focus-visible:outline-[length:var(--focus-ring-width)] focus-visible:outline-solid',\n 'focus-visible:outline-[var(--ring)] focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'forced-colors:focus-visible:outline-[CanvasText]',\n 'transition-colors duration-[var(--animation-duration)] motion-reduce:transition-none',\n].join(' ');\n\nconst SidebarCollapseTrigger = forwardRef<\n HTMLButtonElement,\n SidebarCollapseTriggerProps\n>(\n (\n { className, 'aria-label': ariaLabel, onClick, ...rest },\n ref,\n ) => {\n const { t } = useTranslation();\n const { mode, transitionTo } = useSidebar();\n\n if (mode === 'overlay') return null;\n\n const isExpanded = mode === 'expanded';\n const accessibleLabel =\n ariaLabel ??\n (isExpanded\n ? t('ui.navigation.sidebar.collapse', 'Collapse sidebar')\n : t('ui.navigation.sidebar.expand', 'Expand sidebar'));\n\n const button = (\n <button\n ref={ref}\n type=\"button\"\n aria-label={accessibleLabel}\n aria-expanded={isExpanded}\n onClick={(event) => {\n transitionTo?.(isExpanded ? 'icon' : 'expanded');\n onClick?.(event);\n }}\n className={[collapseTriggerClasses, className].filter(Boolean).join(' ')}\n {...rest}\n >\n {isExpanded ? (\n <PanelLeftClose aria-hidden=\"true\" className=\"ds:size-4 ds:rtl:-scale-x-100\" />\n ) : (\n <PanelLeftOpen aria-hidden=\"true\" className=\"ds:size-4 ds:rtl:-scale-x-100\" />\n )}\n </button>\n );\n\n return (\n <RadixTooltip.Root>\n <RadixTooltip.Trigger asChild>{button}</RadixTooltip.Trigger>\n <RadixTooltip.Portal>\n <RadixTooltip.Content\n side={mode === 'icon' ? 'right' : 'top'}\n sideOffset={6}\n className={[\n 'ds:z-[var(--z-tooltip)] ds:max-w-[16rem]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:bg-[var(--foreground)] ds:text-[var(--background)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)] ds:py-[var(--spacing-xs)] ds:text-[var(--font-size-xs)]',\n 'ds:animate-in ds:fade-in ds:zoom-in-95 ds:motion-reduce:animate-none',\n ].join(' ')}\n >\n {accessibleLabel}\n <RadixTooltip.Arrow className=\"ds:fill-[var(--foreground)]\" />\n </RadixTooltip.Content>\n </RadixTooltip.Portal>\n </RadixTooltip.Root>\n );\n },\n);\nSidebarCollapseTrigger.displayName = 'SidebarCollapseTrigger';\n\nexport {\n Sidebar,\n SidebarHeader,\n SidebarBody,\n SidebarFooter,\n SidebarSection,\n SidebarGroup,\n SidebarItem,\n SidebarItemIcon,\n SidebarItemLabel,\n SidebarItemBadge,\n SidebarWorkspaceSwitcher,\n SidebarPrimaryAction,\n SidebarFavorites,\n SidebarFavoriteItem,\n SidebarPinButton,\n SidebarProfilePill,\n SidebarCollapseTrigger,\n};\n"],"names":["__iconNode","GripVertical","createLucideIcon","PanelLeftClose","PanelLeftOpen","Star","SidebarContext","createContext","useSidebar","useContext","STORAGE_KEY","readStoredState","defaultMode","v","writeStoredState","value","usePersistentState","storageKey","initial","setValue","useState","raw","useEffect","railClasses","cva","Sidebar","forwardRef","state","defaultState","onStateChange","density","open","onOpenChange","ariaLabel","className","children","rest","ref","t","useTranslation","isControlled","internalState","setInternalState","resolved","transitionTo","useCallback","next","label","jsx","RadixDialog","jsxs","X","RadixTooltip","SidebarHeader","mode","SidebarBody","SidebarFooter","sectionLabelClasses","sectionIconClasses","SidebarSection","icon","collapsible","defaultOpen","isIconMode","isAccordion","wrapperClasses","accordionValue","RadixAccordion","ChevronRight","AccordionContent","groupTriggerClasses","SidebarGroup","RadixCollapsible","itemClasses","SidebarItem","asChild","isActive","isPinned","onPinChange","pinLabel","Comp","Slot","showPin","anchor","body","SidebarPinButton","SidebarItemIcon","SidebarItemLabel","SidebarItemBadge","isIcon","workspaceSwitcherClasses","SidebarWorkspaceSwitcher","logo","name","showChevron","showLabel","Fragment","primaryActionClasses","SidebarPrimaryAction","shortcut","pinButtonClasses","onClick","accessibleLabel","event","SidebarFavoritesContext","useFavoritesContext","SidebarFavorites","heading","emptyMessage","onReorder","resolvedHeading","childArray","count","hasChildren","dragSource","setDragSource","liveMessage","setLiveMessage","announceToggle","useRef","announce","message","useMemo","favoriteRowClasses","dragHandleClasses","SidebarFavoriteItem","index","reorderLabel","favorites","isDropTarget","setIsDropTarget","canReorder","handleId","useId","moveFromTo","from","to","clamped","onHandleKeyDown","onDragStart","onDragEnd","onDragOver","onDragLeave","onDrop","source","isDragging","profilePillClasses","SidebarProfilePill","avatar","subtitle","subtitleLabel","accessibleSubtitle","collapseTriggerClasses","SidebarCollapseTrigger","isExpanded","button"],"mappings":"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","x_google_ignoreList":[0,1,2,3]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"signature-capture.agent-4htVctJ2.js","sources":["../../src/components/signature-capture/signature-capture.tsx","../../src/components/signature-capture/signature-capture.agent.ts"],"sourcesContent":["/* ------------------------------------------------------------------ */\n/* SignatureCapture — thin React wrapper over signature_pad. */\n/* */\n/* - Library: `signature_pad` (08-third-party §Signature Pad). We */\n/* instantiate one pad per mounted canvas and expose imperative */\n/* clear / undo / isEmpty / confirm verbs to the consumer. */\n/* - Colors: `penColor` / `backgroundColor` default to */\n/* `--foreground` / `--background` via `getComputedStyle()`. Theme */\n/* switches are observed via a MutationObserver on `<html class>` */\n/* so the ink recolours when the theme flips. */\n/* - DPR scaling: canvas attribute `width/height = cssSize * DPR`; the */\n/* 2D context is scaled by the same factor. A `ResizeObserver` */\n/* replays strokes via `fromData()` on re-scale so nothing is lost. */\n/* - Typed fallback: keyboard-only path renders a text input styled in */\n/* italic `var(--font-sans)` (per 23-constraints §10 — serif is */\n/* marketing only). On confirm we render the string to an offscreen */\n/* canvas for the PNG/SVG export. */\n/* - Confirm payload: `{ png, svg, widthMm, heightMm, capturedAt, */\n/* sha256, strokes? }`. `sha256` is the SubtleCrypto digest of the */\n/* PNG bytes — tamper-evident for audit trails. */\n/* - Security: no `fetch` / `XMLHttpRequest` / `localStorage` / */\n/* `sessionStorage` in this file — the consumer owns persistence. */\n/* */\n/* TODO: */\n/* - 3× DPI re-render for print: currently `toDataURL('image/png')` */\n/* exports the live canvas (already at DPR). A proper 300-DPI */\n/* pipeline would create an offscreen canvas at `cssSize × 3` and */\n/* replay strokes via `fromData()` — deferred pending the print */\n/* bridge landing. */\n/* - Typed-fallback canvas font can't read CSS variables directly */\n/* (Canvas2D resolves fonts at paint time and won't expand */\n/* `var(--font-size-2xl)`); we use a fixed `32px italic` + the */\n/* user's font stack, which is visually close but not */\n/* theme-reactive. Will migrate once the typography tokens expose */\n/* a resolved `font` shorthand. */\n/* ------------------------------------------------------------------ */\n\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n} from 'react';\nimport SignaturePad from 'signature_pad';\nimport type { PointGroup } from 'signature_pad';\nimport { cva } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\n\n/* ------------------------------------------------------------------ */\n/* Public types */\n/* ------------------------------------------------------------------ */\n\nexport interface SignatureConfirmPayload {\n /** Data URL of the captured signature rendered as PNG. */\n png: string;\n /** SVG string trimmed to the stroke bounding box. */\n svg: string;\n /** Physical width in millimetres, derived from CSS px. */\n widthMm: number;\n /** Physical height in millimetres, derived from CSS px. */\n heightMm: number;\n /** ISO-8601 UTC timestamp for when `confirm()` resolved. */\n capturedAt: string;\n /** Hex-encoded SHA-256 digest of the PNG bytes. */\n sha256: string;\n /** Raw stroke data from `signature_pad.toData()` — optional for replays. */\n strokes?: PointGroup[];\n}\n\nexport interface SignatureCaptureProps {\n /** Called with the export payload when the user confirms the signature. */\n onConfirm?: (payload: SignatureConfirmPayload) => void;\n /** Called after the pad is cleared (explicit user action). */\n onClear?: () => void;\n /** Called when the user starts drawing a new stroke. */\n onStart?: () => void;\n /** CSS width of the pad. Default 400. */\n width?: number | string;\n /** CSS height of the pad. Default 200. */\n height?: number | string;\n /** Pen colour override — defaults to `var(--foreground)`. */\n penColor?: string;\n /** Background override — defaults to `var(--background)`. */\n backgroundColor?: string;\n /** Show the typed-name fallback toggle. Default `true`. */\n allowTypedFallback?: boolean;\n /** Disable the entire component. */\n disabled?: boolean;\n /** Accessible label for the pad region. */\n ariaLabel?: string;\n /** Extra class names on the wrapper. */\n className?: string;\n}\n\nexport interface SignatureCaptureHandle {\n clear: () => void;\n undo: () => void;\n isEmpty: () => boolean;\n confirm: () => Promise<SignatureConfirmPayload | null>;\n}\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst wrapperVariants = cva(\n [\n 'ds:signature-capture-alfadocs ds:flex ds:flex-col',\n 'ds:gap-[var(--spacing-sm)]',\n 'ds:bg-[var(--background)] ds:text-[var(--foreground)]',\n 'ds:rounded-[var(--radius-md)] ds:border ds:border-[color:var(--border)]',\n 'ds:p-[var(--spacing-sm)]',\n 'ds:aria-disabled:opacity-[var(--opacity-50)] ds:aria-disabled:cursor-not-allowed',\n ].join(' '),\n);\n\nconst padFrameVariants = cva(\n [\n 'ds:relative ds:block',\n 'ds:inline-size-[var(--signature-width)]',\n 'ds:block-size-[var(--signature-height)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:border ds:border-[color:var(--border)]',\n 'ds:bg-[var(--background)]',\n 'ds:overflow-hidden',\n 'ds:touch-none',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--ring)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n ].join(' '),\n);\n\nconst canvasVariants = cva(\n [\n 'ds:block',\n 'ds:inline-size-full',\n 'ds:block-size-full',\n 'ds:touch-none',\n 'ds:select-none',\n ].join(' '),\n);\n\nconst toolbarVariants = cva(\n ['ds:flex ds:items-center ds:flex-wrap ds:gap-[var(--spacing-xs)]'].join(' '),\n);\n\nconst actionButtonVariants = cva(\n [\n 'ds:inline-flex ds:items-center ds:justify-center',\n 'ds:min-block-size-[var(--min-target-size)]',\n 'ds:min-inline-size-[var(--min-target-size)]',\n 'ds:gap-[var(--spacing-xs)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:border ds:border-[color:var(--border)]',\n 'ds:bg-transparent ds:text-[var(--foreground)]',\n 'ds:text-[var(--font-size-sm)] ds:font-medium',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:hover:bg-[var(--muted)]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--ring)]',\n 'ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n 'ds:aria-disabled:opacity-[var(--opacity-50)] ds:aria-disabled:cursor-not-allowed',\n ].join(' '),\n);\n\nconst confirmButtonVariants = cva(\n [\n 'ds:inline-flex ds:items-center ds:justify-center',\n 'ds:min-block-size-[var(--min-target-size)]',\n 'ds:min-inline-size-[var(--min-target-size)]',\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:bg-[var(--primary)] ds:text-[var(--primary-foreground)]',\n 'ds:text-[var(--font-size-sm)] ds:font-medium',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:hover:bg-[var(--primary-hover)]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--ring)]',\n 'ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n 'ds:aria-disabled:opacity-[var(--opacity-50)] ds:aria-disabled:cursor-not-allowed',\n ].join(' '),\n);\n\nconst typedInputVariants = cva(\n [\n 'ds:block ds:inline-size-full',\n 'ds:min-block-size-[var(--min-target-size)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:border ds:border-[color:var(--border)]',\n 'ds:bg-[var(--background)] ds:text-[var(--foreground)]',\n 'ds:font-[family-name:var(--font-sans)]',\n 'ds:italic',\n 'ds:tracking-[0.1em]',\n 'ds:text-[var(--font-size-lg)]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--ring)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n ].join(' '),\n);\n\nconst typedPreviewVariants = cva(\n [\n 'ds:flex ds:items-center ds:justify-center',\n 'ds:inline-size-[var(--signature-width)]',\n 'ds:block-size-[var(--signature-height)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:border ds:border-[color:var(--border)]',\n 'ds:bg-[var(--background)] ds:text-[var(--foreground)]',\n 'ds:font-[family-name:var(--font-sans)]',\n 'ds:italic',\n 'ds:tracking-[0.1em]',\n 'ds:text-[var(--font-size-2xl)]',\n 'ds:p-[var(--spacing-md)]',\n ].join(' '),\n);\n\n/* ------------------------------------------------------------------ */\n/* Helpers */\n/* ------------------------------------------------------------------ */\n\ntype SignatureState = 'empty' | 'drawing' | 'captured' | 'cleared';\n\n/**\n * Resolve a CSS custom property against `document.documentElement`. We\n * can't pass `var(--foreground)` to signature_pad directly — the lib\n * stamps the string straight into `ctx.strokeStyle`, which only accepts\n * concrete colour values. Looking the variable up at runtime keeps the\n * component in tokens-only compliance.\n */\nfunction resolveCssVar(name: string): string {\n if (typeof document === 'undefined') return '';\n const value = getComputedStyle(document.documentElement)\n .getPropertyValue(name)\n .trim();\n return value;\n}\n\nfunction toCssSize(v: number | string | undefined, fallback: string): string {\n if (typeof v === 'number') return `${v}px`;\n if (typeof v === 'string' && v.length > 0) return v;\n return fallback;\n}\n\nfunction parsePxValue(v: string, fallback: number): number {\n const n = parseFloat(v);\n if (!Number.isFinite(n)) return fallback;\n return n;\n}\n\n/** Hex-encode a Uint8Array. */\nfunction toHex(bytes: Uint8Array): string {\n let out = '';\n for (let i = 0; i < bytes.length; i += 1) {\n const b = bytes[i];\n out += b.toString(16).padStart(2, '0');\n }\n return out;\n}\n\n/** Decode a base64 string into bytes without `atob` polyfills. */\nfunction base64ToBytes(b64: string): Uint8Array {\n if (typeof atob === 'function') {\n const bin = atob(b64);\n const bytes = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i += 1) bytes[i] = bin.charCodeAt(i);\n return bytes;\n }\n // Fallback — node-style Buffer, gated behind a runtime check.\n const g = globalThis as { Buffer?: { from: (s: string, enc: string) => Uint8Array } };\n if (g.Buffer) return g.Buffer.from(b64, 'base64');\n return new Uint8Array();\n}\n\nasync function sha256Hex(bytes: Uint8Array): Promise<string> {\n const g = globalThis as { crypto?: Crypto };\n if (g.crypto?.subtle) {\n // Copy the bytes into a fresh ArrayBuffer so the slice is always an\n // ArrayBuffer (never a SharedArrayBuffer) — SubtleCrypto's BufferSource\n // narrowing doesn't accept the latter.\n const copy = new Uint8Array(bytes.byteLength);\n copy.set(bytes);\n const digest = await g.crypto.subtle.digest('SHA-256', copy.buffer);\n return toHex(new Uint8Array(digest));\n }\n // No subtle crypto — return empty so callers can still use the rest\n // of the payload. Test env is expected to stub crypto.subtle.\n return '';\n}\n\n/**\n * Render the typed fallback string onto an offscreen canvas and return\n * it. Used by the confirm path when the user has typed their name\n * instead of drawing. Size is fixed at `32px italic` because Canvas2D\n * resolves fonts eagerly and can't expand `var(--font-size-*)`.\n */\nfunction renderTypedSignatureToCanvas(\n text: string,\n cssWidth: number,\n cssHeight: number,\n penColor: string,\n backgroundColor: string,\n): HTMLCanvasElement {\n const dpr = Math.max(1, typeof window !== 'undefined' ? window.devicePixelRatio : 1);\n const canvas = document.createElement('canvas');\n canvas.width = Math.floor(cssWidth * dpr);\n canvas.height = Math.floor(cssHeight * dpr);\n const ctx = canvas.getContext('2d');\n if (!ctx) return canvas;\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n // Fill background with the token-resolved colour.\n ctx.fillStyle = backgroundColor || 'transparent';\n ctx.fillRect(0, 0, cssWidth, cssHeight);\n // Draw the typed signature centred.\n ctx.fillStyle = penColor || 'currentColor';\n ctx.font = '32px italic sans-serif';\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n ctx.fillText(text, cssWidth / 2, cssHeight / 2, cssWidth - 16);\n return canvas;\n}\n\n/* ------------------------------------------------------------------ */\n/* SignatureCapture */\n/* ------------------------------------------------------------------ */\n\nexport const SignatureCapture = forwardRef<\n SignatureCaptureHandle,\n SignatureCaptureProps\n>(\n (\n {\n onConfirm,\n onClear,\n onStart,\n width = 400,\n height = 200,\n penColor,\n backgroundColor,\n allowTypedFallback = true,\n disabled = false,\n ariaLabel,\n className,\n },\n ref,\n ) => {\n const { t } = useTranslation();\n const rawId = useId();\n const idSafe = useMemo(\n () => `sig-${rawId.replace(/[^a-zA-Z0-9-_]/g, '')}`,\n [rawId],\n );\n const liveRegionId = `${idSafe}-live`;\n\n const padFrameRef = useRef<HTMLDivElement>(null);\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const signaturePadRef = useRef<SignaturePad | null>(null);\n\n const [mode, setMode] = useState<'draw' | 'typed'>('draw');\n const [typedValue, setTypedValue] = useState('');\n // Retained state — consumers may subscribe to the pad's lifecycle via\n // `onConfirm`/`onClear`/`onStart`; we still track the machine internally\n // so the live region + confirm button stay coherent.\n const signatureStateRef = useRef<SignatureState>('empty');\n const [announcement, setAnnouncement] = useState<string>('');\n const [resolvedPen, setResolvedPen] = useState<string>('');\n const [resolvedBg, setResolvedBg] = useState<string>('');\n\n // Stable callback refs so we can wire signature_pad once without\n // re-instantiating on every render.\n const onStartRef = useRef<SignatureCaptureProps['onStart']>(onStart);\n const onClearRef = useRef<SignatureCaptureProps['onClear']>(onClear);\n const onConfirmRef = useRef<SignatureCaptureProps['onConfirm']>(onConfirm);\n useEffect(() => {\n onStartRef.current = onStart;\n onClearRef.current = onClear;\n onConfirmRef.current = onConfirm;\n }, [onStart, onClear, onConfirm]);\n\n /* ---- Announce helper ---------------------------------------- */\n const announce = useCallback(\n (next: SignatureState) => {\n signatureStateRef.current = next;\n setAnnouncement(t(`signature.state.${next}`));\n },\n [t],\n );\n\n /* ---- Resolve tokens ----------------------------------------- */\n useEffect(() => {\n if (typeof document === 'undefined') return undefined;\n function resolveAll(): void {\n const pen = penColor ?? resolveCssVar('--foreground');\n const bg = backgroundColor ?? resolveCssVar('--background');\n // Fall back to `currentColor` / `transparent` — keyword literals\n // are token-neutral and honour the surrounding theme even when\n // the CSS variable is briefly unavailable (SSR, initial paint).\n setResolvedPen(pen || 'currentColor');\n setResolvedBg(bg || 'transparent');\n }\n resolveAll();\n // Watch for theme-class changes on <html>.\n const mo = new MutationObserver(() => {\n resolveAll();\n });\n mo.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['class'],\n });\n return () => mo.disconnect();\n }, [penColor, backgroundColor]);\n\n /* ---- Apply colour changes to an existing pad ---------------- */\n useEffect(() => {\n const pad = signaturePadRef.current;\n if (!pad) return;\n if (resolvedPen) pad.penColor = resolvedPen;\n if (resolvedBg) pad.backgroundColor = resolvedBg;\n }, [resolvedPen, resolvedBg]);\n\n /* ---- Instantiate signature_pad ------------------------------ */\n useEffect(() => {\n if (mode !== 'draw') return undefined;\n const canvas = canvasRef.current;\n if (!canvas) return undefined;\n\n const pad = new SignaturePad(canvas, {\n penColor: resolvedPen || 'currentColor',\n backgroundColor: resolvedBg || 'transparent',\n minWidth: 0.5,\n maxWidth: 2.5,\n velocityFilterWeight: 0.7,\n });\n signaturePadRef.current = pad;\n\n const handleBegin = (): void => {\n announce('drawing');\n onStartRef.current?.();\n };\n const handleEnd = (): void => {\n // Keep state as 'drawing' — transition to 'captured' on confirm.\n };\n pad.addEventListener('beginStroke', handleBegin);\n pad.addEventListener('endStroke', handleEnd);\n\n // Initial DPR scale + announcement.\n scaleCanvas(canvas);\n announce('empty');\n\n return () => {\n pad.removeEventListener('beginStroke', handleBegin);\n pad.removeEventListener('endStroke', handleEnd);\n // Clear strokes from memory; 08-third-party §Signature Pad.\n pad.clear();\n pad.off();\n signaturePadRef.current = null;\n };\n // We intentionally re-create the pad only when switching between\n // typed and draw modes. Color updates flow through the effect above.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [mode]);\n\n /* ---- Disabled state ----------------------------------------- */\n useEffect(() => {\n const pad = signaturePadRef.current;\n if (!pad) return;\n if (disabled) pad.off();\n else pad.on();\n }, [disabled, mode]);\n\n /* ---- DPR + ResizeObserver ----------------------------------- */\n // Hard-cap backing-store dimensions to bound memory. 4096 px × 4096 px at\n // 4 bytes per pixel is ~67 MB — generous for any realistic signature, but\n // well under the multi-GB allocation a careless or malicious prop could\n // request on a high-DPR display. See security-hardening.mdx.\n const MAX_CANVAS_PX = 4096;\n const scaleCanvas = useCallback((canvas: HTMLCanvasElement) => {\n const rect = canvas.getBoundingClientRect();\n const dpr = Math.max(\n 1,\n typeof window !== 'undefined' ? window.devicePixelRatio : 1,\n );\n const rawWidth = Math.max(1, Math.floor(rect.width * dpr));\n const rawHeight = Math.max(1, Math.floor(rect.height * dpr));\n const targetWidth = Math.min(rawWidth, MAX_CANVAS_PX);\n const targetHeight = Math.min(rawHeight, MAX_CANVAS_PX);\n if (\n import.meta.env.DEV &&\n (rawWidth !== targetWidth || rawHeight !== targetHeight)\n ) {\n // Silent in production; a consumer shipping 10k × 10k probably wants\n // the nudge.\n console.warn(\n `[SignatureCapture] clamped canvas backing store from ${rawWidth}x${rawHeight} to ${targetWidth}x${targetHeight} (cap = ${MAX_CANVAS_PX}px).`,\n );\n }\n if (canvas.width === targetWidth && canvas.height === targetHeight) return;\n\n const pad = signaturePadRef.current;\n const prior = pad ? pad.toData() : null;\n canvas.width = targetWidth;\n canvas.height = targetHeight;\n const ctx = canvas.getContext('2d');\n if (ctx) ctx.scale(dpr, dpr);\n if (pad) {\n if (resolvedBg) pad.backgroundColor = resolvedBg;\n if (resolvedPen) pad.penColor = resolvedPen;\n pad.clear();\n if (prior && prior.length > 0) {\n pad.fromData(prior);\n }\n }\n }, [resolvedBg, resolvedPen]);\n\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return undefined;\n if (typeof ResizeObserver === 'undefined') {\n scaleCanvas(canvas);\n return undefined;\n }\n const ro = new ResizeObserver(() => {\n scaleCanvas(canvas);\n });\n ro.observe(canvas);\n return () => ro.disconnect();\n }, [scaleCanvas]);\n\n /* ---- Imperative handle -------------------------------------- */\n const clear = useCallback(() => {\n const pad = signaturePadRef.current;\n if (pad) pad.clear();\n setTypedValue('');\n announce('cleared');\n onClearRef.current?.();\n }, [announce]);\n\n const undo = useCallback(() => {\n const pad = signaturePadRef.current;\n if (!pad) return;\n const data = pad.toData();\n if (!data || data.length === 0) return;\n data.pop();\n pad.fromData(data);\n if (data.length === 0) announce('empty');\n }, [announce]);\n\n const isEmpty = useCallback((): boolean => {\n if (mode === 'typed') return typedValue.trim().length === 0;\n const pad = signaturePadRef.current;\n return pad ? pad.isEmpty() : true;\n }, [mode, typedValue]);\n\n const confirm = useCallback(async (): Promise<SignatureConfirmPayload | null> => {\n const cssWidth = parsePxValue(\n typeof width === 'number' ? `${width}` : String(width),\n 400,\n );\n const cssHeight = parsePxValue(\n typeof height === 'number' ? `${height}` : String(height),\n 200,\n );\n\n let pngDataUrl = '';\n let svgString = '';\n let strokes: PointGroup[] | undefined;\n\n if (mode === 'draw') {\n const pad = signaturePadRef.current;\n if (!pad || pad.isEmpty()) return null;\n pngDataUrl = pad.toDataURL('image/png');\n svgString = pad.toSVG();\n strokes = pad.toData();\n } else {\n const value = typedValue.trim();\n if (value.length === 0) return null;\n const offscreen = renderTypedSignatureToCanvas(\n value,\n cssWidth,\n cssHeight,\n resolvedPen || 'currentColor',\n resolvedBg || 'transparent',\n );\n pngDataUrl = offscreen.toDataURL('image/png');\n // Inline SVG — we can't call toSVG() because signature_pad isn't\n // driving the canvas. Build a minimal SVG with the rendered text.\n const safeText = value\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n svgString =\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${cssWidth} ${cssHeight}\" width=\"${cssWidth}\" height=\"${cssHeight}\">` +\n `<text x=\"50%\" y=\"50%\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"sans-serif\" font-style=\"italic\" font-size=\"32\" fill=\"${resolvedPen || 'currentColor'}\" letter-spacing=\"3\">${safeText}</text>` +\n `</svg>`;\n }\n\n // 96 CSS px = 25.4 mm (per W3C CSS absolute length definition).\n const widthMm = (cssWidth * 25.4) / 96;\n const heightMm = (cssHeight * 25.4) / 96;\n const capturedAt = new Date().toISOString();\n\n // Compute SHA-256 of the PNG bytes.\n let sha256 = '';\n if (pngDataUrl) {\n const commaIx = pngDataUrl.indexOf(',');\n const b64 = commaIx >= 0 ? pngDataUrl.slice(commaIx + 1) : '';\n const bytes = base64ToBytes(b64);\n sha256 = await sha256Hex(bytes);\n }\n\n const payload: SignatureConfirmPayload = {\n png: pngDataUrl,\n svg: svgString,\n widthMm,\n heightMm,\n capturedAt,\n sha256,\n strokes,\n };\n\n announce('captured');\n onConfirmRef.current?.(payload);\n return payload;\n }, [\n mode,\n typedValue,\n width,\n height,\n resolvedPen,\n resolvedBg,\n announce,\n ]);\n\n useImperativeHandle(\n ref,\n () => ({\n clear,\n undo,\n isEmpty,\n confirm,\n }),\n [clear, undo, isEmpty, confirm],\n );\n\n /* ---- Derived UI state --------------------------------------- */\n const confirmDisabled = disabled || isEmpty();\n // Inline style — permitted per 23-constraints §Runtime-computed\n // dimensions (CSS custom property setter for dynamic width/height\n // from consumer props; the width rule lives in Tailwind arbitrary\n // values that read --signature-width / --signature-height).\n const sizeStyle: CSSProperties = {\n ['--signature-width' as unknown as keyof CSSProperties]: toCssSize(width, 'var(--signature-default-width)'),\n ['--signature-height' as unknown as keyof CSSProperties]: toCssSize(height, 'var(--signature-default-height)'),\n } as CSSProperties;\n\n /* ---- Render -------------------------------------------------- */\n return (\n <div\n role=\"region\"\n aria-label={ariaLabel ?? t('signature.padLabel')}\n aria-disabled={disabled || undefined}\n className={[wrapperVariants(), className].filter(Boolean).join(' ')}\n style={sizeStyle}\n data-component=\"signature-capture\"\n >\n {mode === 'draw' ? (\n <div\n ref={padFrameRef}\n className={padFrameVariants()}\n >\n <canvas\n ref={canvasRef}\n role=\"img\"\n aria-label={t('signature.padLabel')}\n className={canvasVariants()}\n data-testid=\"signature-canvas\"\n />\n </div>\n ) : (\n <label className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\">\n <span className=\"type-body-sm ds:text-[var(--muted-foreground)]\">\n {t('signature.typedFallback.label')}\n </span>\n <input\n type=\"text\"\n value={typedValue}\n onChange={(e) => {\n setTypedValue(e.target.value);\n if (e.target.value.length > 0) announce('drawing');\n else announce('empty');\n }}\n placeholder={t('signature.typedFallback.placeholder')}\n aria-label={t('signature.typedFallback.label')}\n disabled={disabled}\n className={typedInputVariants()}\n data-testid=\"signature-typed-input\"\n />\n {typedValue ? (\n <div\n className={typedPreviewVariants()}\n aria-hidden=\"true\"\n >\n {typedValue}\n </div>\n ) : null}\n </label>\n )}\n\n {/* Live region — state transitions (empty, drawing, captured, cleared) */}\n <div\n id={liveRegionId}\n aria-live=\"polite\"\n aria-atomic=\"true\"\n className=\"ds:sr-only\"\n data-testid=\"signature-live\"\n >\n {announcement}\n </div>\n\n <div className={toolbarVariants()} role=\"group\" aria-label={t('signature.padLabel')}>\n <button\n type=\"button\"\n onClick={() => {\n if (disabled) return;\n clear();\n }}\n aria-disabled={disabled || undefined}\n className={actionButtonVariants()}\n >\n {t('signature.clear')}\n </button>\n {mode === 'draw' ? (\n <button\n type=\"button\"\n onClick={() => {\n if (disabled) return;\n undo();\n }}\n aria-disabled={disabled || undefined}\n className={actionButtonVariants()}\n >\n {t('signature.undo')}\n </button>\n ) : null}\n {allowTypedFallback ? (\n <button\n type=\"button\"\n onClick={() => {\n if (disabled) return;\n setTypedValue('');\n setMode((m) => (m === 'draw' ? 'typed' : 'draw'));\n announce('cleared');\n }}\n aria-disabled={disabled || undefined}\n className={actionButtonVariants()}\n aria-pressed={mode === 'typed'}\n >\n {mode === 'draw'\n ? t('signature.typedFallback.toggle')\n : t('signature.typedFallback.toggleDraw')}\n </button>\n ) : null}\n <button\n type=\"button\"\n onClick={() => {\n if (confirmDisabled) return;\n void confirm();\n }}\n aria-disabled={confirmDisabled || undefined}\n aria-describedby={liveRegionId}\n className={confirmButtonVariants()}\n data-testid=\"signature-confirm\"\n >\n {t('signature.confirm')}\n </button>\n </div>\n </div>\n );\n },\n);\n\nSignatureCapture.displayName = 'SignatureCapture';\n\nexport {\n wrapperVariants as signatureWrapperVariants,\n actionButtonVariants as signatureActionButtonVariants,\n confirmButtonVariants as signatureConfirmButtonVariants,\n};\n","import type { AgentAdapter } from '../../agent/types';\nimport type { SignatureCaptureHandle } from './signature-capture';\n\nexport const signatureCaptureAgent: AgentAdapter<SignatureCaptureHandle> = {\n id: 'signature-capture',\n capabilities: ['edit_inline', 'submit'],\n state: {\n isEmpty: {\n type: 'boolean',\n description: 'True when no signature has been drawn or typed.',\n read: (handle) => handle.isEmpty(),\n },\n },\n actions: {\n clear: {\n safety: 'destructive',\n description: 'Erase the current signature. Loses unsaved input.',\n invoke: (handle) => {\n handle.clear();\n },\n },\n undo: {\n safety: 'write',\n description: 'Undo the last stroke.',\n invoke: (handle) => {\n handle.undo();\n },\n },\n confirm: {\n safety: 'write',\n description: 'Commit the signature and return its serialised payload.',\n invoke: (handle) => handle.confirm(),\n },\n },\n domHooks: {\n root: { attr: 'data-component', value: 'signature-capture' },\n },\n};\n"],"names":["wrapperVariants","cva","padFrameVariants","canvasVariants","toolbarVariants","actionButtonVariants","confirmButtonVariants","typedInputVariants","typedPreviewVariants","resolveCssVar","name","toCssSize","v","fallback","parsePxValue","n","toHex","bytes","out","i","b","base64ToBytes","b64","bin","g","sha256Hex","_a","copy","digest","renderTypedSignatureToCanvas","text","cssWidth","cssHeight","penColor","backgroundColor","dpr","canvas","ctx","SignatureCapture","forwardRef","onConfirm","onClear","onStart","width","height","allowTypedFallback","disabled","ariaLabel","className","ref","t","useTranslation","rawId","useId","liveRegionId","useMemo","padFrameRef","useRef","canvasRef","signaturePadRef","mode","setMode","useState","typedValue","setTypedValue","signatureStateRef","announcement","setAnnouncement","resolvedPen","setResolvedPen","resolvedBg","setResolvedBg","onStartRef","onClearRef","onConfirmRef","useEffect","announce","useCallback","next","resolveAll","pen","bg","mo","pad","SignaturePad","handleBegin","handleEnd","scaleCanvas","MAX_CANVAS_PX","rect","rawWidth","rawHeight","targetWidth","targetHeight","prior","ro","clear","undo","data","isEmpty","confirm","pngDataUrl","svgString","strokes","value","safeText","widthMm","heightMm","capturedAt","sha256","commaIx","payload","useImperativeHandle","confirmDisabled","sizeStyle","jsxs","jsx","m","signatureCaptureAgent","handle"],"mappings":";;;;;AA8GA,MAAMA,KAAkBC;AAAA,EACtB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,GAAG;AACZ,GAEMC,KAAmBD;AAAA,EACvB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,GAAG;AACZ,GAEME,KAAiBF;AAAA,EACrB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,GAAG;AACZ,GAEMG,KAAkBH;AAAA,EACtB,CAAC,iEAAiE,EAAE,KAAK,GAAG;AAC9E,GAEMI,IAAuBJ;AAAA,EAC3B;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,GAAG;AACZ,GAEMK,KAAwBL;AAAA,EAC5B;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,GAAG;AACZ,GAEMM,KAAqBN;AAAA,EACzB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,GAAG;AACZ,GAEMO,KAAuBP;AAAA,EAC3B;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,GAAG;AACZ;AAeA,SAASQ,EAAcC,GAAsB;AAC3C,SAAI,OAAO,WAAa,MAAoB,KAC9B,iBAAiB,SAAS,eAAe,EACpD,iBAAiBA,CAAI,EACrB,KAAA;AAEL;AAEA,SAASC,EAAUC,GAAgCC,GAA0B;AAC3E,SAAI,OAAOD,KAAM,WAAiB,GAAGA,CAAC,OAClC,OAAOA,KAAM,YAAYA,EAAE,SAAS,IAAUA,IAC3CC;AACT;AAEA,SAASC,GAAaF,GAAWC,GAA0B;AACzD,QAAME,IAAI,WAAWH,CAAC;AACtB,SAAK,OAAO,SAASG,CAAC,IACfA,IADyBF;AAElC;AAGA,SAASG,GAAMC,GAA2B;AACxC,MAAIC,IAAM;AACV,WAASC,IAAI,GAAGA,IAAIF,EAAM,QAAQE,KAAK,GAAG;AACxC,UAAMC,IAAIH,EAAME,CAAC;AACjB,IAAAD,KAAOE,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AAAA,EACvC;AACA,SAAOF;AACT;AAGA,SAASG,GAAcC,GAAyB;AAC9C,MAAI,OAAO,QAAS,YAAY;AAC9B,UAAMC,IAAM,KAAKD,CAAG,GACdL,IAAQ,IAAI,WAAWM,EAAI,MAAM;AACvC,aAASJ,IAAI,GAAGA,IAAII,EAAI,QAAQJ,KAAK,EAAG,CAAAF,EAAME,CAAC,IAAII,EAAI,WAAWJ,CAAC;AACnE,WAAOF;AAAA,EACT;AAEA,QAAMO,IAAI;AACV,SAAIA,EAAE,SAAeA,EAAE,OAAO,KAAKF,GAAK,QAAQ,IACzC,IAAI,WAAA;AACb;AAEA,eAAeG,GAAUR,GAAoC;;AAC3D,QAAMO,IAAI;AACV,OAAIE,IAAAF,EAAE,WAAF,QAAAE,EAAU,QAAQ;AAIpB,UAAMC,IAAO,IAAI,WAAWV,EAAM,UAAU;AAC5C,IAAAU,EAAK,IAAIV,CAAK;AACd,UAAMW,IAAS,MAAMJ,EAAE,OAAO,OAAO,OAAO,WAAWG,EAAK,MAAM;AAClE,WAAOX,GAAM,IAAI,WAAWY,CAAM,CAAC;AAAA,EACrC;AAGA,SAAO;AACT;AAQA,SAASC,GACPC,GACAC,GACAC,GACAC,GACAC,GACmB;AACnB,QAAMC,IAAM,KAAK,IAAI,GAAG,OAAO,SAAW,MAAc,OAAO,mBAAmB,CAAC,GAC7EC,IAAS,SAAS,cAAc,QAAQ;AAC9C,EAAAA,EAAO,QAAQ,KAAK,MAAML,IAAWI,CAAG,GACxCC,EAAO,SAAS,KAAK,MAAMJ,IAAYG,CAAG;AAC1C,QAAME,IAAMD,EAAO,WAAW,IAAI;AAClC,SAAKC,MACLA,EAAI,aAAaF,GAAK,GAAG,GAAGA,GAAK,GAAG,CAAC,GAErCE,EAAI,YAAYH,GAChBG,EAAI,SAAS,GAAG,GAAGN,GAAUC,CAAS,GAEtCK,EAAI,YAAYJ,GAChBI,EAAI,OAAO,0BACXA,EAAI,YAAY,UAChBA,EAAI,eAAe,UACnBA,EAAI,SAASP,GAAMC,IAAW,GAAGC,IAAY,GAAGD,IAAW,EAAE,IACtDK;AACT;AAMO,MAAME,KAAmBC;AAAA,EAI9B,CACE;AAAA,IACE,WAAAC;AAAA,IACA,SAAAC;AAAA,IACA,SAAAC;AAAA,IACA,OAAAC,IAAQ;AAAA,IACR,QAAAC,IAAS;AAAA,IACT,UAAAX;AAAA,IACA,iBAAAC;AAAA,IACA,oBAAAW,IAAqB;AAAA,IACrB,UAAAC,IAAW;AAAA,IACX,WAAAC;AAAA,IACA,WAAAC;AAAA,EAAA,GAEFC,OACG;AACH,UAAM,EAAE,GAAAC,EAAA,IAAMC,GAAA,GACRC,IAAQC,GAAA,GAKRC,IAAe,GAJNC;AAAA,MACb,MAAM,OAAOH,EAAM,QAAQ,mBAAmB,EAAE,CAAC;AAAA,MACjD,CAACA,CAAK;AAAA,IAAA,CAEsB,SAExBI,KAAcC,EAAuB,IAAI,GACzCC,IAAYD,EAA0B,IAAI,GAC1CE,IAAkBF,EAA4B,IAAI,GAElD,CAACG,GAAMC,EAAO,IAAIC,EAA2B,MAAM,GACnD,CAACC,GAAYC,CAAa,IAAIF,EAAS,EAAE,GAIzCG,KAAoBR,EAAuB,OAAO,GAClD,CAACS,IAAcC,EAAe,IAAIL,EAAiB,EAAE,GACrD,CAACM,GAAaC,EAAc,IAAIP,EAAiB,EAAE,GACnD,CAACQ,GAAYC,EAAa,IAAIT,EAAiB,EAAE,GAIjDU,IAAaf,EAAyCf,CAAO,GAC7D+B,IAAahB,EAAyChB,CAAO,GAC7DiC,IAAejB,EAA2CjB,CAAS;AACzE,IAAAmC,EAAU,MAAM;AACd,MAAAH,EAAW,UAAU9B,GACrB+B,EAAW,UAAUhC,GACrBiC,EAAa,UAAUlC;AAAA,IACzB,GAAG,CAACE,GAASD,GAASD,CAAS,CAAC;AAGhC,UAAMoC,IAAWC;AAAA,MACf,CAACC,MAAyB;AACxB,QAAAb,GAAkB,UAAUa,GAC5BX,GAAgBjB,EAAE,mBAAmB4B,CAAI,EAAE,CAAC;AAAA,MAC9C;AAAA,MACA,CAAC5B,CAAC;AAAA,IAAA;AAIJ,IAAAyB,EAAU,MAAM;AACd,UAAI,OAAO,WAAa,IAAa;AACrC,eAASI,IAAmB;AAC1B,cAAMC,IAAM/C,KAAYxB,EAAc,cAAc,GAC9CwE,IAAK/C,KAAmBzB,EAAc,cAAc;AAI1D,QAAA4D,GAAeW,KAAO,cAAc,GACpCT,GAAcU,KAAM,aAAa;AAAA,MACnC;AACA,MAAAF,EAAA;AAEA,YAAMG,IAAK,IAAI,iBAAiB,MAAM;AACpC,QAAAH,EAAA;AAAA,MACF,CAAC;AACD,aAAAG,EAAG,QAAQ,SAAS,iBAAiB;AAAA,QACnC,YAAY;AAAA,QACZ,iBAAiB,CAAC,OAAO;AAAA,MAAA,CAC1B,GACM,MAAMA,EAAG,WAAA;AAAA,IAClB,GAAG,CAACjD,GAAUC,CAAe,CAAC,GAG9ByC,EAAU,MAAM;AACd,YAAMQ,IAAMxB,EAAgB;AAC5B,MAAKwB,MACDf,QAAiB,WAAWA,IAC5BE,QAAgB,kBAAkBA;AAAA,IACxC,GAAG,CAACF,GAAaE,CAAU,CAAC,GAG5BK,EAAU,MAAM;AACd,UAAIf,MAAS,OAAQ;AACrB,YAAMxB,IAASsB,EAAU;AACzB,UAAI,CAACtB,EAAQ;AAEb,YAAM+C,IAAM,IAAIC,GAAahD,GAAQ;AAAA,QACnC,UAAUgC,KAAe;AAAA,QACzB,iBAAiBE,KAAc;AAAA,QAC/B,UAAU;AAAA,QACV,UAAU;AAAA,QACV,sBAAsB;AAAA,MAAA,CACvB;AACD,MAAAX,EAAgB,UAAUwB;AAE1B,YAAME,IAAc,MAAY;;AAC9B,QAAAT,EAAS,SAAS,IAClBlD,IAAA8C,EAAW,YAAX,QAAA9C,EAAA,KAAA8C;AAAA,MACF,GACMc,IAAY,MAAY;AAAA,MAE9B;AACA,aAAAH,EAAI,iBAAiB,eAAeE,CAAW,GAC/CF,EAAI,iBAAiB,aAAaG,CAAS,GAG3CC,EAAYnD,CAAM,GAClBwC,EAAS,OAAO,GAET,MAAM;AACX,QAAAO,EAAI,oBAAoB,eAAeE,CAAW,GAClDF,EAAI,oBAAoB,aAAaG,CAAS,GAE9CH,EAAI,MAAA,GACJA,EAAI,IAAA,GACJxB,EAAgB,UAAU;AAAA,MAC5B;AAAA,IAIF,GAAG,CAACC,CAAI,CAAC,GAGTe,EAAU,MAAM;AACd,YAAMQ,IAAMxB,EAAgB;AAC5B,MAAKwB,MACDrC,MAAc,IAAA,MACT,GAAA;AAAA,IACX,GAAG,CAACA,GAAUc,CAAI,CAAC;AAOnB,UAAM4B,IAAgB,MAChBD,IAAcV,EAAY,CAACzC,MAA8B;AAC7D,YAAMqD,IAAOrD,EAAO,sBAAA,GACdD,IAAM,KAAK;AAAA,QACf;AAAA,QACA,OAAO,SAAW,MAAc,OAAO,mBAAmB;AAAA,MAAA,GAEtDuD,IAAW,KAAK,IAAI,GAAG,KAAK,MAAMD,EAAK,QAAQtD,CAAG,CAAC,GACnDwD,IAAY,KAAK,IAAI,GAAG,KAAK,MAAMF,EAAK,SAAStD,CAAG,CAAC,GACrDyD,IAAc,KAAK,IAAIF,GAAUF,CAAa,GAC9CK,IAAe,KAAK,IAAIF,GAAWH,CAAa;AAWtD,UAAIpD,EAAO,UAAUwD,KAAexD,EAAO,WAAWyD,EAAc;AAEpE,YAAMV,IAAMxB,EAAgB,SACtBmC,IAAQX,IAAMA,EAAI,OAAA,IAAW;AACnC,MAAA/C,EAAO,QAAQwD,GACfxD,EAAO,SAASyD;AAChB,YAAMxD,IAAMD,EAAO,WAAW,IAAI;AAClC,MAAIC,KAAKA,EAAI,MAAMF,GAAKA,CAAG,GACvBgD,MACEb,QAAgB,kBAAkBA,IAClCF,QAAiB,WAAWA,IAChCe,EAAI,MAAA,GACAW,KAASA,EAAM,SAAS,KAC1BX,EAAI,SAASW,CAAK;AAAA,IAGxB,GAAG,CAACxB,GAAYF,CAAW,CAAC;AAE5B,IAAAO,EAAU,MAAM;AACd,YAAMvC,IAASsB,EAAU;AACzB,UAAI,CAACtB,EAAQ;AACb,UAAI,OAAO,iBAAmB,KAAa;AACzC,QAAAmD,EAAYnD,CAAM;AAClB;AAAA,MACF;AACA,YAAM2D,IAAK,IAAI,eAAe,MAAM;AAClC,QAAAR,EAAYnD,CAAM;AAAA,MACpB,CAAC;AACD,aAAA2D,EAAG,QAAQ3D,CAAM,GACV,MAAM2D,EAAG,WAAA;AAAA,IAClB,GAAG,CAACR,CAAW,CAAC;AAGhB,UAAMS,IAAQnB,EAAY,MAAM;;AAC9B,YAAMM,IAAMxB,EAAgB;AAC5B,MAAIwB,OAAS,MAAA,GACbnB,EAAc,EAAE,GAChBY,EAAS,SAAS,IAClBlD,IAAA+C,EAAW,YAAX,QAAA/C,EAAA,KAAA+C;AAAA,IACF,GAAG,CAACG,CAAQ,CAAC,GAEPqB,IAAOpB,EAAY,MAAM;AAC7B,YAAMM,IAAMxB,EAAgB;AAC5B,UAAI,CAACwB,EAAK;AACV,YAAMe,IAAOf,EAAI,OAAA;AACjB,MAAI,CAACe,KAAQA,EAAK,WAAW,MAC7BA,EAAK,IAAA,GACLf,EAAI,SAASe,CAAI,GACbA,EAAK,WAAW,KAAGtB,EAAS,OAAO;AAAA,IACzC,GAAG,CAACA,CAAQ,CAAC,GAEPuB,IAAUtB,EAAY,MAAe;AACzC,UAAIjB,MAAS,QAAS,QAAOG,EAAW,KAAA,EAAO,WAAW;AAC1D,YAAMoB,IAAMxB,EAAgB;AAC5B,aAAOwB,IAAMA,EAAI,QAAA,IAAY;AAAA,IAC/B,GAAG,CAACvB,GAAMG,CAAU,CAAC,GAEfqC,IAAUvB,EAAY,YAAqD;;AAC/E,YAAM9C,IAAWjB;AAAA,QACf,OAAO6B,KAAU,WAAW,GAAGA,CAAK,KAAK,OAAOA,CAAK;AAAA,QACrD;AAAA,MAAA,GAEIX,IAAYlB;AAAA,QAChB,OAAO8B,KAAW,WAAW,GAAGA,CAAM,KAAK,OAAOA,CAAM;AAAA,QACxD;AAAA,MAAA;AAGF,UAAIyD,IAAa,IACbC,IAAY,IACZC;AAEJ,UAAI3C,MAAS,QAAQ;AACnB,cAAMuB,IAAMxB,EAAgB;AAC5B,YAAI,CAACwB,KAAOA,EAAI,QAAA,EAAW,QAAO;AAClC,QAAAkB,IAAalB,EAAI,UAAU,WAAW,GACtCmB,IAAYnB,EAAI,MAAA,GAChBoB,IAAUpB,EAAI,OAAA;AAAA,MAChB,OAAO;AACL,cAAMqB,IAAQzC,EAAW,KAAA;AACzB,YAAIyC,EAAM,WAAW,EAAG,QAAO;AAQ/B,QAAAH,IAPkBxE;AAAA,UAChB2E;AAAA,UACAzE;AAAA,UACAC;AAAA,UACAoC,KAAe;AAAA,UACfE,KAAc;AAAA,QAAA,EAEO,UAAU,WAAW;AAG5C,cAAMmC,IAAWD,EACd,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ,EACtB,QAAQ,MAAM,OAAO;AACxB,QAAAF,IACE,wDAAwDvE,CAAQ,IAAIC,CAAS,YAAYD,CAAQ,aAAaC,CAAS,6IACoBoC,KAAe,cAAc,wBAAwBqC,CAAQ;AAAA,MAE5M;AAGA,YAAMC,IAAW3E,IAAW,OAAQ,IAC9B4E,IAAY3E,IAAY,OAAQ,IAChC4E,KAAa,oBAAI,KAAA,GAAO,YAAA;AAG9B,UAAIC,IAAS;AACb,UAAIR,GAAY;AACd,cAAMS,IAAUT,EAAW,QAAQ,GAAG,GAChC/E,IAAMwF,KAAW,IAAIT,EAAW,MAAMS,IAAU,CAAC,IAAI,IACrD7F,IAAQI,GAAcC,CAAG;AAC/B,QAAAuF,IAAS,MAAMpF,GAAUR,CAAK;AAAA,MAChC;AAEA,YAAM8F,IAAmC;AAAA,QACvC,KAAKV;AAAA,QACL,KAAKC;AAAA,QACL,SAAAI;AAAA,QACA,UAAAC;AAAA,QACA,YAAAC;AAAA,QACA,QAAAC;AAAA,QACA,SAAAN;AAAA,MAAA;AAGF,aAAA3B,EAAS,UAAU,IACnBlD,IAAAgD,EAAa,YAAb,QAAAhD,EAAA,KAAAgD,GAAuBqC,IAChBA;AAAA,IACT,GAAG;AAAA,MACDnD;AAAA,MACAG;AAAA,MACApB;AAAA,MACAC;AAAA,MACAwB;AAAA,MACAE;AAAA,MACAM;AAAA,IAAA,CACD;AAED,IAAAoC;AAAA,MACE/D;AAAA,MACA,OAAO;AAAA,QACL,OAAA+C;AAAA,QACA,MAAAC;AAAA,QACA,SAAAE;AAAA,QACA,SAAAC;AAAA,MAAA;AAAA,MAEF,CAACJ,GAAOC,GAAME,GAASC,CAAO;AAAA,IAAA;AAIhC,UAAMa,IAAkBnE,KAAYqD,EAAA,GAK9Be,KAA2B;AAAA,MAC9B,qBAAwDvG,EAAUgC,GAAO,gCAAgC;AAAA,MACzG,sBAAyDhC,EAAUiC,GAAQ,iCAAiC;AAAA,IAAA;AAI/G,WACE,gBAAAuE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,cAAYpE,MAAaG,EAAE,oBAAoB;AAAA,QAC/C,iBAAeJ,KAAY;AAAA,QAC3B,WAAW,CAAC9C,GAAA,GAAmBgD,EAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,QAClE,OAAOkE;AAAA,QACP,kBAAe;AAAA,QAEd,UAAA;AAAA,UAAAtD,MAAS,SACR,gBAAAwD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,KAAK5D;AAAA,cACL,WAAWtD,GAAA;AAAA,cAEX,UAAA,gBAAAkH;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,KAAK1D;AAAA,kBACL,MAAK;AAAA,kBACL,cAAYR,EAAE,oBAAoB;AAAA,kBAClC,WAAW/C,GAAA;AAAA,kBACX,eAAY;AAAA,gBAAA;AAAA,cAAA;AAAA,YACd;AAAA,UAAA,IAGF,gBAAAgH,EAAC,SAAA,EAAM,WAAU,kDACf,UAAA;AAAA,YAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,kDACb,UAAAlE,EAAE,+BAA+B,GACpC;AAAA,YACA,gBAAAkE;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAOrD;AAAA,gBACP,UAAU,CAAC,MAAM;AACf,kBAAAC,EAAc,EAAE,OAAO,KAAK,GACxB,EAAE,OAAO,MAAM,SAAS,MAAY,SAAS,MACnC,OAAO;AAAA,gBACvB;AAAA,gBACA,aAAad,EAAE,qCAAqC;AAAA,gBACpD,cAAYA,EAAE,+BAA+B;AAAA,gBAC7C,UAAAJ;AAAA,gBACA,WAAWvC,GAAA;AAAA,gBACX,eAAY;AAAA,cAAA;AAAA,YAAA;AAAA,YAEbwD,IACC,gBAAAqD;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,WAAW5G,GAAA;AAAA,gBACX,eAAY;AAAA,gBAEX,UAAAuD;AAAA,cAAA;AAAA,YAAA,IAED;AAAA,UAAA,GACN;AAAA,UAIF,gBAAAqD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,IAAI9D;AAAA,cACJ,aAAU;AAAA,cACV,eAAY;AAAA,cACZ,WAAU;AAAA,cACV,eAAY;AAAA,cAEX,UAAAY;AAAA,YAAA;AAAA,UAAA;AAAA,UAGH,gBAAAiD,EAAC,OAAA,EAAI,WAAW/G,GAAA,GAAmB,MAAK,SAAQ,cAAY8C,EAAE,oBAAoB,GAChF,UAAA;AAAA,YAAA,gBAAAkE;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAAS,MAAM;AACb,kBAAItE,KACJkD,EAAA;AAAA,gBACF;AAAA,gBACA,iBAAelD,KAAY;AAAA,gBAC3B,WAAWzC,EAAA;AAAA,gBAEV,YAAE,iBAAiB;AAAA,cAAA;AAAA,YAAA;AAAA,YAErBuD,MAAS,SACR,gBAAAwD;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAAS,MAAM;AACb,kBAAItE,KACJmD,EAAA;AAAA,gBACF;AAAA,gBACA,iBAAenD,KAAY;AAAA,gBAC3B,WAAWzC,EAAA;AAAA,gBAEV,YAAE,gBAAgB;AAAA,cAAA;AAAA,YAAA,IAEnB;AAAA,YACHwC,IACC,gBAAAuE;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAAS,MAAM;AACb,kBAAItE,MACJkB,EAAc,EAAE,GAChBH,GAAQ,CAACwD,MAAOA,MAAM,SAAS,UAAU,MAAO,GAChDzC,EAAS,SAAS;AAAA,gBACpB;AAAA,gBACA,iBAAe9B,KAAY;AAAA,gBAC3B,WAAWzC,EAAA;AAAA,gBACX,gBAAcuD,MAAS;AAAA,gBAEtB,UACGV,QADM,SACJ,mCACA,oCADgC;AAAA,cACI;AAAA,YAAA,IAE1C;AAAA,YACJ,gBAAAkE;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAAS,MAAM;AACb,kBAAIH,KACCb,EAAA;AAAA,gBACP;AAAA,gBACA,iBAAea,KAAmB;AAAA,gBAClC,oBAAkB3D;AAAA,gBAClB,WAAWhD,GAAA;AAAA,gBACX,eAAY;AAAA,gBAEX,YAAE,mBAAmB;AAAA,cAAA;AAAA,YAAA;AAAA,UACxB,GACF;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AACF;AAEAgC,GAAiB,cAAc;ACxxBxB,MAAMgF,KAA8D;AAAA,EACzE,IAAI;AAAA,EACJ,cAAc,CAAC,eAAe,QAAQ;AAAA,EACtC,OAAO;AAAA,IACL,SAAS;AAAA,MACP,MAAM;AAAA,MACN,aAAa;AAAA,MACb,MAAM,CAACC,MAAWA,EAAO,QAAA;AAAA,IAAQ;AAAA,EACnC;AAAA,EAEF,SAAS;AAAA,IACP,OAAO;AAAA,MACL,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,QAAQ,CAACA,MAAW;AAClB,QAAAA,EAAO,MAAA;AAAA,MACT;AAAA,IAAA;AAAA,IAEF,MAAM;AAAA,MACJ,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,QAAQ,CAACA,MAAW;AAClB,QAAAA,EAAO,KAAA;AAAA,MACT;AAAA,IAAA;AAAA,IAEF,SAAS;AAAA,MACP,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,QAAQ,CAACA,MAAWA,EAAO,QAAA;AAAA,IAAQ;AAAA,EACrC;AAAA,EAEF,UAAU;AAAA,IACR,MAAM,EAAE,MAAM,kBAAkB,OAAO,oBAAA;AAAA,EAAoB;AAE/D;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"slider-n8JWpJvT.js","sources":["../../src/components/slider/slider.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useRef,\n useState,\n type CSSProperties,\n type ComponentPropsWithoutRef,\n type ElementRef,\n type KeyboardEvent,\n} from 'react';\nimport * as RadixSlider from '@radix-ui/react-slider';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { useFormField } from '../form-field/form-field-context';\nimport { useDirection } from '../_shared/use-direction';\nimport { composeRefs } from '../_shared/compose-refs';\n\nexport interface SliderMark {\n value: number;\n label?: string;\n}\n\nconst sliderVariants = cva(\n [\n 'ds:relative ds:flex ds:touch-none ds:select-none ds:items-center',\n 'ds:data-[orientation=horizontal]:w-full',\n 'ds:data-[orientation=vertical]:flex-col ds:data-[orientation=vertical]:h-full',\n 'ds:data-[disabled]:cursor-not-allowed ds:data-[disabled]:opacity-50',\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'ds:data-[orientation=horizontal]:h-1 ds:data-[orientation=vertical]:w-1',\n md: 'ds:data-[orientation=horizontal]:h-2 ds:data-[orientation=vertical]:w-2',\n lg: 'ds:data-[orientation=horizontal]:h-3 ds:data-[orientation=vertical]:w-3',\n },\n },\n defaultVariants: { size: 'md' },\n },\n);\n\nconst trackVariants = cva(\n [\n 'ds:relative ds:grow ds:overflow-hidden ds:rounded-[var(--radius-full)] ds:bg-muted',\n 'ds:data-[orientation=horizontal]:h-full',\n 'ds:data-[orientation=vertical]:w-full',\n ].join(' '),\n);\n\nconst rangeVariants = cva(\n [\n 'ds:absolute ds:bg-primary ds:rounded-[var(--radius-full)]',\n 'ds:data-[orientation=horizontal]:h-full',\n 'ds:data-[orientation=vertical]:w-full',\n ].join(' '),\n);\n\nconst thumbVariants = cva(\n [\n 'ds:group/thumb',\n 'ds:relative ds:block ds:rounded-full',\n 'ds:bg-background ds:border-2 ds:border-primary ds:shadow-[var(--shadow-sm)]',\n 'ds:transition-[transform,box-shadow] ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:outline-none',\n 'ds:focus-visible:shadow-[var(--shadow-focus),var(--shadow-sm)]',\n 'ds:active:shadow-[var(--shadow-sm)]',\n 'ds:data-[disabled]:cursor-not-allowed ds:data-[disabled]:opacity-50',\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'ds:size-4',\n md: 'ds:size-5',\n lg: 'ds:size-6',\n },\n },\n defaultVariants: { size: 'md' },\n },\n);\n\nconst hitAreaVariants = cva('ds:absolute ds:rounded-full', {\n variants: {\n size: {\n sm: 'ds:-inset-[calc((var(--min-target-size)-1rem)/2)]',\n md: 'ds:-inset-[calc((var(--min-target-size)-1.25rem)/2)]',\n lg: 'ds:-inset-[calc((var(--min-target-size)-1.5rem)/2)]',\n },\n },\n defaultVariants: { size: 'md' },\n});\n\nconst tooltipWrapperVariants = cva(\n 'ds:absolute ds:flex ds:pointer-events-none ds:items-center ds:justify-center',\n {\n variants: {\n orientation: {\n horizontal: 'ds:start-0 ds:end-0 ds:bottom-full',\n vertical: 'ds:top-0 ds:bottom-0 ds:start-full',\n },\n },\n defaultVariants: { orientation: 'horizontal' },\n },\n);\n\nconst tooltipBubbleVariants = cva(\n [\n 'ds:whitespace-nowrap ds:bg-foreground ds:text-background',\n 'ds:px-[var(--spacing-sm)] ds:py-[var(--spacing-xs)]',\n 'ds:rounded-[var(--radius-sm)] ds:text-[var(--font-size-xs)] ds:tabular-nums',\n 'ds:shadow-[var(--shadow-sm)]',\n 'ds:transition-opacity ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n ].join(' '),\n {\n variants: {\n orientation: {\n horizontal: 'ds:mb-[var(--spacing-xs)]',\n vertical: 'ds:ms-[var(--spacing-xs)]',\n },\n alwaysShow: {\n true: 'ds:opacity-100',\n false:\n 'ds:opacity-0 ds:group-hover/thumb:opacity-100 ds:group-focus-visible/thumb:opacity-100',\n },\n },\n defaultVariants: { orientation: 'horizontal', alwaysShow: false },\n },\n);\n\nconst marksContainerVariants = cva('ds:absolute ds:pointer-events-none', {\n variants: {\n orientation: {\n horizontal: 'ds:start-0 ds:end-0 ds:top-full',\n vertical: 'ds:top-0 ds:bottom-0 ds:start-full',\n },\n },\n defaultVariants: { orientation: 'horizontal' },\n});\n\nconst markVariants = cva('ds:absolute ds:flex ds:items-center', {\n variants: {\n orientation: {\n horizontal: 'ds:flex-col ds:-translate-x-1/2 ds:rtl:translate-x-1/2',\n vertical: 'ds:flex-row ds:-translate-y-1/2 ds:ps-[var(--spacing-xs)]',\n },\n },\n defaultVariants: { orientation: 'horizontal' },\n});\n\nconst tickVariants = cva('ds:bg-border', {\n variants: {\n orientation: {\n horizontal: 'ds:w-px ds:h-1',\n vertical: 'ds:h-px ds:w-1',\n },\n },\n defaultVariants: { orientation: 'horizontal' },\n});\n\nconst markLabelVariants = cva(\n 'ds:text-muted-foreground type-meta ds:mt-[var(--spacing-xs)]',\n);\n\nconst endpointWrapperVariants = cva(\n 'ds:flex ds:items-center ds:gap-[var(--spacing-sm)]',\n {\n variants: {\n orientation: {\n horizontal: 'ds:w-full ds:flex-row',\n vertical: 'ds:h-full ds:flex-col-reverse',\n },\n },\n defaultVariants: { orientation: 'horizontal' },\n },\n);\n\nconst endpointLabelVariants = cva(\n 'ds:text-muted-foreground type-meta ds:tabular-nums ds:shrink-0',\n);\n\ntype RadixSliderRootProps = ComponentPropsWithoutRef<typeof RadixSlider.Root>;\n\nexport interface SliderProps\n extends Omit<RadixSliderRootProps, 'children'>,\n VariantProps<typeof sliderVariants> {\n value?: number[];\n defaultValue?: number[];\n marks?: SliderMark[];\n minLabel?: string;\n maxLabel?: string;\n formatValue?: (value: number) => string;\n alwaysShowValue?: boolean;\n step?: number;\n largeStep?: number;\n thumbLabels?: string[];\n size?: 'sm' | 'md' | 'lg';\n orientation?: 'horizontal' | 'vertical';\n onValueChange?: (value: number[]) => void;\n onValueCommit?: (value: number[]) => void;\n className?: string;\n}\n\nexport const Slider = forwardRef<\n ElementRef<typeof RadixSlider.Root>,\n SliderProps\n>((props, ref) => {\n const {\n value,\n defaultValue,\n marks,\n minLabel,\n maxLabel,\n formatValue,\n alwaysShowValue = false,\n step = 1,\n largeStep = 10,\n thumbLabels,\n size = 'md',\n orientation = 'horizontal',\n min = 0,\n max = 100,\n disabled,\n dir,\n id,\n className,\n onValueChange,\n onValueCommit,\n onKeyDown,\n ...rest\n } = props;\n\n const { t, i18n } = useTranslation();\n const ctx = useFormField();\n\n const isControlled = value !== undefined;\n const [internalValue, setInternalValue] = useState<number[]>(\n value ?? defaultValue ?? [min],\n );\n const currentValue: number[] = isControlled\n ? (value as number[])\n : internalValue;\n\n const handleValueChange = (next: number[]) => {\n if (!isControlled) setInternalValue(next);\n onValueChange?.(next);\n };\n\n const effectiveDisabled = Boolean(ctx.disabled || disabled);\n const describedBy = ctx.describedBy || undefined;\n const sliderId = id ?? ctx.id;\n\n const defaultFormat = useCallback(\n (n: number) => new Intl.NumberFormat(i18n.language).format(n),\n [i18n.language],\n );\n const format = formatValue ?? defaultFormat;\n\n const defaultMinThumbLabel = t('ui.inputs.slider.minLabel', 'Minimum');\n const defaultMaxThumbLabel = t('ui.inputs.slider.maxLabel', 'Maximum');\n const labelForThumb = (i: number): string | undefined => {\n if (thumbLabels?.[i]) return thumbLabels[i];\n if (currentValue.length === 2) {\n return i === 0 ? defaultMinThumbLabel : defaultMaxThumbLabel;\n }\n return undefined;\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n if (event.defaultPrevented) return;\n if (effectiveDisabled) return;\n if (event.key !== 'PageUp' && event.key !== 'PageDown') return;\n\n event.preventDefault();\n const thumbs = Array.from(\n event.currentTarget.querySelectorAll<HTMLElement>('[role=\"slider\"]'),\n );\n const activeIndex = Math.max(\n 0,\n thumbs.indexOf(document.activeElement as HTMLElement),\n );\n const delta = event.key === 'PageUp' ? largeStep : -largeStep;\n const next = currentValue.map((v, i) =>\n i === activeIndex ? Math.max(min, Math.min(max, v + delta)) : v,\n );\n handleValueChange(next);\n onValueCommit?.(next);\n };\n\n const denom = max - min || 1;\n const percentFor = (n: number) => ((n - min) / denom) * 100;\n\n const rootRef = useRef<HTMLSpanElement>(null);\n const composedRef = composeRefs(ref, rootRef);\n const autoDir = useDirection(rootRef);\n\n const root = (\n <RadixSlider.Root\n ref={composedRef}\n id={sliderId}\n dir={dir ?? autoDir}\n orientation={orientation}\n min={min}\n max={max}\n step={step}\n disabled={effectiveDisabled}\n value={isControlled ? value : undefined}\n defaultValue={!isControlled ? (defaultValue ?? [min]) : undefined}\n onValueChange={handleValueChange}\n onValueCommit={onValueCommit}\n onKeyDown={handleKeyDown}\n aria-describedby={describedBy}\n aria-invalid={ctx.invalid || undefined}\n aria-required={ctx.required || undefined}\n className={sliderVariants({ size, className })}\n {...rest}\n >\n <RadixSlider.Track className={trackVariants()}>\n <RadixSlider.Range className={rangeVariants()} />\n </RadixSlider.Track>\n {marks && marks.length > 0 ? (\n <span\n aria-hidden=\"true\"\n className={marksContainerVariants({ orientation })}\n >\n {marks.map((m) => {\n const p = percentFor(m.value);\n const positionStyle: CSSProperties =\n orientation === 'vertical'\n ? { insetBlockEnd: `${p}%` }\n : { insetInlineStart: `${p}%` };\n return (\n <span\n key={`${m.value}-${m.label ?? ''}`}\n className={markVariants({ orientation })}\n style={positionStyle}\n >\n <span className={tickVariants({ orientation })} />\n {m.label ? (\n <span className={markLabelVariants()}>{m.label}</span>\n ) : null}\n </span>\n );\n })}\n </span>\n ) : null}\n {currentValue.map((v, i) => (\n <RadixSlider.Thumb\n key={i}\n aria-label={labelForThumb(i)}\n aria-valuetext={format(v)}\n className={thumbVariants({ size })}\n >\n <span aria-hidden=\"true\" className={hitAreaVariants({ size })} />\n <span\n aria-hidden=\"true\"\n className={tooltipWrapperVariants({ orientation })}\n >\n <span\n className={tooltipBubbleVariants({\n orientation,\n alwaysShow: alwaysShowValue,\n })}\n >\n {format(v)}\n </span>\n </span>\n </RadixSlider.Thumb>\n ))}\n </RadixSlider.Root>\n );\n\n if (minLabel !== undefined || maxLabel !== undefined) {\n return (\n <div className={endpointWrapperVariants({ orientation })}>\n {minLabel !== undefined ? (\n <span className={endpointLabelVariants()}>{minLabel}</span>\n ) : null}\n {root}\n {maxLabel !== undefined ? (\n <span className={endpointLabelVariants()}>{maxLabel}</span>\n ) : null}\n </div>\n );\n }\n\n return root;\n});\n\nSlider.displayName = 'Slider';\n"],"names":["sliderVariants","cva","trackVariants","rangeVariants","thumbVariants","hitAreaVariants","tooltipWrapperVariants","tooltipBubbleVariants","marksContainerVariants","markVariants","tickVariants","markLabelVariants","endpointWrapperVariants","endpointLabelVariants","Slider","forwardRef","props","ref","value","defaultValue","marks","minLabel","maxLabel","formatValue","alwaysShowValue","step","largeStep","thumbLabels","size","orientation","min","max","disabled","dir","id","className","onValueChange","onValueCommit","onKeyDown","rest","t","i18n","useTranslation","ctx","useFormField","isControlled","internalValue","setInternalValue","useState","currentValue","handleValueChange","next","effectiveDisabled","describedBy","sliderId","defaultFormat","useCallback","n","format","defaultMinThumbLabel","defaultMaxThumbLabel","labelForThumb","i","handleKeyDown","event","thumbs","activeIndex","delta","v","denom","percentFor","rootRef","useRef","composedRef","composeRefs","autoDir","useDirection","root","jsxs","RadixSlider","jsx","m","p","positionStyle"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"slot-grid-BRAkqChA.js","sources":["../../node_modules/date-fns/parseISO.js","../../src/components/slot-grid/slot-grid.tsx"],"sourcesContent":["import {\n millisecondsInHour,\n millisecondsInMinute,\n} from \"./constants.js\";\nimport { constructFrom } from \"./constructFrom.js\";\nimport { toDate } from \"./toDate.js\";\n\n/**\n * The {@link parseISO} function options.\n */\n\n/**\n * @name parseISO\n * @category Common Helpers\n * @summary Parse ISO string\n *\n * @description\n * Parse the given string in ISO 8601 format and return an instance of Date.\n *\n * Function accepts complete ISO 8601 formats as well as partial implementations.\n * ISO 8601: http://en.wikipedia.org/wiki/ISO_8601\n *\n * If the argument isn't a string, the function cannot parse the string or\n * the values are invalid, it returns Invalid Date.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.\n *\n * @param argument - The value to convert\n * @param options - An object with options\n *\n * @returns The parsed date in the local time zone\n *\n * @example\n * // Convert string '2014-02-11T11:30:30' to date:\n * const result = parseISO('2014-02-11T11:30:30')\n * //=> Tue Feb 11 2014 11:30:30\n *\n * @example\n * // Convert string '+02014101' to date,\n * // if the additional number of digits in the extended year format is 1:\n * const result = parseISO('+02014101', { additionalDigits: 1 })\n * //=> Fri Apr 11 2014 00:00:00\n */\nexport function parseISO(argument, options) {\n const invalidDate = () => constructFrom(options?.in, NaN);\n\n const additionalDigits = options?.additionalDigits ?? 2;\n const dateStrings = splitDateString(argument);\n\n let date;\n if (dateStrings.date) {\n const parseYearResult = parseYear(dateStrings.date, additionalDigits);\n date = parseDate(parseYearResult.restDateString, parseYearResult.year);\n }\n\n if (!date || isNaN(+date)) return invalidDate();\n\n const timestamp = +date;\n let time = 0;\n let offset;\n\n if (dateStrings.time) {\n time = parseTime(dateStrings.time);\n if (isNaN(time)) return invalidDate();\n }\n\n if (dateStrings.timezone) {\n offset = parseTimezone(dateStrings.timezone);\n if (isNaN(offset)) return invalidDate();\n } else {\n const tmpDate = new Date(timestamp + time);\n const result = toDate(0, options?.in);\n result.setFullYear(\n tmpDate.getUTCFullYear(),\n tmpDate.getUTCMonth(),\n tmpDate.getUTCDate(),\n );\n result.setHours(\n tmpDate.getUTCHours(),\n tmpDate.getUTCMinutes(),\n tmpDate.getUTCSeconds(),\n tmpDate.getUTCMilliseconds(),\n );\n return result;\n }\n\n return toDate(timestamp + time + offset, options?.in);\n}\n\nconst patterns = {\n dateTimeDelimiter: /[T ]/,\n timeZoneDelimiter: /[Z ]/i,\n timezone: /([Z+-].*)$/,\n};\n\nconst dateRegex =\n /^-?(?:(\\d{3})|(\\d{2})(?:-?(\\d{2}))?|W(\\d{2})(?:-?(\\d{1}))?|)$/;\nconst timeRegex =\n /^(\\d{2}(?:[.,]\\d*)?)(?::?(\\d{2}(?:[.,]\\d*)?))?(?::?(\\d{2}(?:[.,]\\d*)?))?$/;\nconst timezoneRegex = /^([+-])(\\d{2})(?::?(\\d{2}))?$/;\n\nfunction splitDateString(dateString) {\n const dateStrings = {};\n const array = dateString.split(patterns.dateTimeDelimiter);\n let timeString;\n\n // The regex match should only return at maximum two array elements.\n // [date], [time], or [date, time].\n if (array.length > 2) {\n return dateStrings;\n }\n\n if (/:/.test(array[0])) {\n timeString = array[0];\n } else {\n dateStrings.date = array[0];\n timeString = array[1];\n if (patterns.timeZoneDelimiter.test(dateStrings.date)) {\n dateStrings.date = dateString.split(patterns.timeZoneDelimiter)[0];\n timeString = dateString.substr(\n dateStrings.date.length,\n dateString.length,\n );\n }\n }\n\n if (timeString) {\n const token = patterns.timezone.exec(timeString);\n if (token) {\n dateStrings.time = timeString.replace(token[1], \"\");\n dateStrings.timezone = token[1];\n } else {\n dateStrings.time = timeString;\n }\n }\n\n return dateStrings;\n}\n\nfunction parseYear(dateString, additionalDigits) {\n const regex = new RegExp(\n \"^(?:(\\\\d{4}|[+-]\\\\d{\" +\n (4 + additionalDigits) +\n \"})|(\\\\d{2}|[+-]\\\\d{\" +\n (2 + additionalDigits) +\n \"})$)\",\n );\n\n const captures = dateString.match(regex);\n // Invalid ISO-formatted year\n if (!captures) return { year: NaN, restDateString: \"\" };\n\n const year = captures[1] ? parseInt(captures[1]) : null;\n const century = captures[2] ? parseInt(captures[2]) : null;\n\n // either year or century is null, not both\n return {\n year: century === null ? year : century * 100,\n restDateString: dateString.slice((captures[1] || captures[2]).length),\n };\n}\n\nfunction parseDate(dateString, year) {\n // Invalid ISO-formatted year\n if (year === null) return new Date(NaN);\n\n const captures = dateString.match(dateRegex);\n // Invalid ISO-formatted string\n if (!captures) return new Date(NaN);\n\n const isWeekDate = !!captures[4];\n const dayOfYear = parseDateUnit(captures[1]);\n const month = parseDateUnit(captures[2]) - 1;\n const day = parseDateUnit(captures[3]);\n const week = parseDateUnit(captures[4]);\n const dayOfWeek = parseDateUnit(captures[5]) - 1;\n\n if (isWeekDate) {\n if (!validateWeekDate(year, week, dayOfWeek)) {\n return new Date(NaN);\n }\n return dayOfISOWeekYear(year, week, dayOfWeek);\n } else {\n const date = new Date(0);\n if (\n !validateDate(year, month, day) ||\n !validateDayOfYearDate(year, dayOfYear)\n ) {\n return new Date(NaN);\n }\n date.setUTCFullYear(year, month, Math.max(dayOfYear, day));\n return date;\n }\n}\n\nfunction parseDateUnit(value) {\n return value ? parseInt(value) : 1;\n}\n\nfunction parseTime(timeString) {\n const captures = timeString.match(timeRegex);\n if (!captures) return NaN; // Invalid ISO-formatted time\n\n const hours = parseTimeUnit(captures[1]);\n const minutes = parseTimeUnit(captures[2]);\n const seconds = parseTimeUnit(captures[3]);\n\n if (!validateTime(hours, minutes, seconds)) {\n return NaN;\n }\n\n return (\n hours * millisecondsInHour + minutes * millisecondsInMinute + seconds * 1000\n );\n}\n\nfunction parseTimeUnit(value) {\n return (value && parseFloat(value.replace(\",\", \".\"))) || 0;\n}\n\nfunction parseTimezone(timezoneString) {\n if (timezoneString === \"Z\") return 0;\n\n const captures = timezoneString.match(timezoneRegex);\n if (!captures) return 0;\n\n const sign = captures[1] === \"+\" ? -1 : 1;\n const hours = parseInt(captures[2]);\n const minutes = (captures[3] && parseInt(captures[3])) || 0;\n\n if (!validateTimezone(hours, minutes)) {\n return NaN;\n }\n\n return sign * (hours * millisecondsInHour + minutes * millisecondsInMinute);\n}\n\nfunction dayOfISOWeekYear(isoWeekYear, week, day) {\n const date = new Date(0);\n date.setUTCFullYear(isoWeekYear, 0, 4);\n const fourthOfJanuaryDay = date.getUTCDay() || 7;\n const diff = (week - 1) * 7 + day + 1 - fourthOfJanuaryDay;\n date.setUTCDate(date.getUTCDate() + diff);\n return date;\n}\n\n// Validation functions\n\n// February is null to handle the leap year (using ||)\nconst daysInMonths = [31, null, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\nfunction isLeapYearIndex(year) {\n return year % 400 === 0 || (year % 4 === 0 && year % 100 !== 0);\n}\n\nfunction validateDate(year, month, date) {\n return (\n month >= 0 &&\n month <= 11 &&\n date >= 1 &&\n date <= (daysInMonths[month] || (isLeapYearIndex(year) ? 29 : 28))\n );\n}\n\nfunction validateDayOfYearDate(year, dayOfYear) {\n return dayOfYear >= 1 && dayOfYear <= (isLeapYearIndex(year) ? 366 : 365);\n}\n\nfunction validateWeekDate(_year, week, day) {\n return week >= 1 && week <= 53 && day >= 0 && day <= 6;\n}\n\nfunction validateTime(hours, minutes, seconds) {\n if (hours === 24) {\n return minutes === 0 && seconds === 0;\n }\n\n return (\n seconds >= 0 &&\n seconds < 60 &&\n minutes >= 0 &&\n minutes < 60 &&\n hours >= 0 &&\n hours < 25\n );\n}\n\nfunction validateTimezone(_hours, minutes) {\n return minutes >= 0 && minutes <= 59;\n}\n\n// Fallback for modularized imports:\nexport default parseISO;\n","/* ------------------------------------------------------------------ */\n/* SlotGrid — multi-day time-slot picker for patient booking. */\n/* */\n/* Renders N day columns side-by-side. Each column shows a day header */\n/* (formatted via `Intl.DateTimeFormat(locale)`) plus a vertical list */\n/* of slot buttons. Long days collapse to `maxInitialSlotsPerDay` and */\n/* reveal the rest via a \"Show more\" button (progressive disclosure). */\n/* */\n/* Navigation arrows (`onPreviousDays` / `onNextDays`) let the consumer */\n/* page the window of days; the optional \"Next available\" CTA jumps to */\n/* the first day with an open slot. */\n/* */\n/* Purely presentational — no business logic, no data fetching. Date */\n/* comparisons use `date-fns` (never moment.js) and the rendered labels */\n/* come exclusively from `Intl.DateTimeFormat` or the `ui.slotGrid` */\n/* namespace via `useTranslation()`. */\n/* ------------------------------------------------------------------ */\n\nimport {\n forwardRef,\n useCallback,\n useId,\n useState,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { isSameDay, parseISO } from 'date-fns';\nimport { Button } from '../button/button';\nimport { IconButton } from '../button/icon-button';\nimport { EmptyState } from '../empty-state/empty-state';\nimport { Skeleton } from '../skeleton/skeleton';\n\n/* ------------------------------------------------------------------ */\n/* Public types */\n/* ------------------------------------------------------------------ */\n\nexport type SlotGridState = 'default' | 'loading' | 'disabled' | 'empty';\n\nexport type SlotGridSize = 'sm' | 'md' | 'lg';\n\nexport interface SlotGridSlot {\n /** Stable identity — used by consumers to resolve selection. */\n id: string;\n /** Slot start — ISO string or `Date`. Rendered via `Intl.DateTimeFormat`. */\n start: string | Date;\n /** Optional slot end — if omitted only the start time is announced. */\n end?: string | Date;\n /** Defaults to `true`. Unavailable slots render disabled and are not focusable. */\n available?: boolean;\n /** Override the default `Intl`-formatted time label. */\n label?: string;\n /** Override the accessible name of the slot button. */\n ariaLabel?: string;\n}\n\nexport interface SlotGridDay {\n /** The calendar day the column represents. */\n date: string | Date;\n /** Slots for this day, in chronological order. Empty array ⇒ empty day. */\n slots: SlotGridSlot[];\n /** Override the default `Intl`-formatted day header. */\n label?: string;\n}\n\nexport interface SlotGridProps\n extends Omit<HTMLAttributes<HTMLDivElement>, 'aria-label' | 'onSelect'>,\n VariantProps<typeof slotGridVariants> {\n /** Days to render, one column per entry. */\n days: SlotGridDay[];\n /** Visual / interactive state. Defaults to `'default'`. */\n state?: SlotGridState;\n /** Density of the slot buttons and day headers. Defaults to `'md'`. */\n size?: SlotGridSize;\n /** Id of the currently selected slot (controlled). */\n selectedSlotId?: string;\n /**\n * Initial number of slots to render per day before the \"Show more\"\n * progressive-disclosure control collapses the rest. Defaults to `6`.\n */\n maxInitialSlotsPerDay?: number;\n /**\n * BCP-47 locale tag for `Intl.DateTimeFormat`. Defaults to the active\n * i18next language.\n */\n locale?: string;\n /** IANA time zone for `Intl.DateTimeFormat`. Optional. */\n timeZone?: string;\n /** Whether the \"previous days\" navigation arrow should be enabled. */\n hasPrevious?: boolean;\n /** Whether the \"next days\" navigation arrow should be enabled. */\n hasNext?: boolean;\n /**\n * When `true`, renders the \"Next available\" CTA at the end of the\n * toolbar. Only emits a callback — the consumer owns the navigation.\n */\n showNextAvailable?: boolean;\n /** Accessible label for the outer grid region. */\n ariaLabel?: string;\n /** Fires when the user selects an available slot. */\n onSlotSelect?: (slot: SlotGridSlot, day: SlotGridDay) => void;\n /** Fires when the user clicks the \"previous days\" arrow. */\n onPreviousDays?: () => void;\n /** Fires when the user clicks the \"next days\" arrow. */\n onNextDays?: () => void;\n /** Fires when the user clicks a day's \"Show more\" button. */\n onShowMore?: (day: SlotGridDay) => void;\n /** Fires when the user clicks the \"Next available\" CTA. */\n onJumpToNextAvailable?: () => void;\n}\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst slotGridVariants = cva(\n [\n 'ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]',\n 'ds:text-[var(--foreground)]',\n 'ds:w-full',\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'ds:text-[var(--font-size-sm)]',\n md: 'ds:text-[var(--font-size-base)]',\n lg: 'ds:text-[var(--font-size-lg)]',\n },\n },\n defaultVariants: { size: 'md' },\n },\n);\n\nconst toolbarVariants = cva(\n 'ds:flex ds:items-center ds:justify-between ds:gap-[var(--spacing-sm)] ds:w-full',\n);\n\n/**\n * Column-count is dynamic (1–12), so it is declared as a full CVA variant —\n * this keeps every `grid-cols-N` string statically visible to Tailwind's\n * JIT and keeps the variant table inside CVA rather than hand-rolled.\n */\nconst COLS_MAX = 12;\n\nconst columnsVariants = cva(\n 'ds:grid ds:gap-[var(--spacing-sm)] ds:w-full ds:auto-rows-min ds:items-start',\n {\n variants: {\n cols: {\n 1: 'ds:grid-cols-1',\n 2: 'ds:grid-cols-2',\n 3: 'ds:grid-cols-3',\n 4: 'ds:grid-cols-4',\n 5: 'ds:grid-cols-5',\n 6: 'ds:grid-cols-6',\n 7: 'ds:grid-cols-7',\n 8: 'ds:grid-cols-8',\n 9: 'ds:grid-cols-9',\n 10: 'ds:grid-cols-10',\n 11: 'ds:grid-cols-11',\n 12: 'ds:grid-cols-12',\n },\n },\n defaultVariants: { cols: 1 },\n },\n);\n\ntype ColumnsCount = NonNullable<VariantProps<typeof columnsVariants>['cols']>;\n\nfunction clampCols(count: number): ColumnsCount {\n return Math.max(1, Math.min(count, COLS_MAX)) as ColumnsCount;\n}\n\nconst columnVariants = cva(\n [\n 'ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)]',\n 'ds:pt-[var(--spacing-sm)] ds:pb-[var(--spacing-sm)]',\n 'ds:rounded-[var(--radius-md)]',\n 'ds:bg-[var(--card)]',\n 'ds:border ds:border-[var(--border)]',\n 'ds:min-w-0',\n ].join(' '),\n);\n\nconst dayHeaderVariants = cva(\n [\n 'ds:font-[var(--font-weight-semibold)]',\n 'ds:text-[var(--foreground)]',\n 'ds:text-start',\n 'ds:truncate',\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'ds:text-[var(--font-size-xs)]',\n md: 'ds:text-[var(--font-size-sm)]',\n lg: 'ds:text-[var(--font-size-base)]',\n },\n },\n defaultVariants: { size: 'md' },\n },\n);\n\nconst slotListVariants = cva(\n 'ds:flex ds:flex-col ds:gap-[var(--spacing-xs)] ds:w-full ds:m-0 ds:p-0 ds:list-none',\n);\n\nconst slotButtonVariants = cva(\n [\n 'ds:inline-flex ds:items-center ds:justify-center',\n 'ds:w-full',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:font-[var(--font-weight-medium)]',\n 'ds:border ds:border-[var(--border)]',\n 'ds:bg-[var(--background)]',\n 'ds:text-[var(--foreground)]',\n 'ds:transition-colors',\n 'ds:focus-visible:outline-[var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--ring)]',\n 'ds:focus-visible:outline-offset-[var(--focus-ring-offset)]',\n 'ds:min-h-[var(--min-target-size)]',\n 'ds:disabled:opacity-50 ds:disabled:cursor-not-allowed',\n 'ds:aria-disabled:opacity-50 ds:aria-disabled:cursor-not-allowed',\n 'ds:hover:bg-[var(--muted)] ds:hover:text-[var(--foreground)]',\n 'ds:aria-pressed:bg-[var(--primary)] ds:aria-pressed:text-[var(--primary-foreground)]',\n 'ds:aria-pressed:border-[var(--primary)]',\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)] ds:text-[var(--font-size-xs)] ds:h-8',\n md: 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:text-[var(--font-size-sm)] ds:h-10',\n lg: 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:text-[var(--font-size-base)] ds:h-12',\n },\n },\n defaultVariants: { size: 'md' },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* Helpers */\n/* ------------------------------------------------------------------ */\n\nfunction toDate(value: string | Date): Date {\n return value instanceof Date ? value : parseISO(value);\n}\n\n/** Is `a` the same calendar day as `b`? Uses `date-fns`, locale-agnostic. */\nexport function isSameDate(a: string | Date, b: string | Date): boolean {\n return isSameDay(toDate(a), toDate(b));\n}\n\n/** Find the first day in a list that has at least one available slot. */\nexport function findFirstAvailable(\n days: SlotGridDay[],\n): { day: SlotGridDay; slot: SlotGridSlot } | undefined {\n for (const day of days) {\n const slot = day.slots.find((s) => s.available !== false);\n if (slot) return { day, slot };\n }\n return undefined;\n}\n\nfunction formatDayHeader(date: Date, locale: string, timeZone?: string): string {\n try {\n return new Intl.DateTimeFormat(locale, {\n weekday: 'short',\n month: 'short',\n day: 'numeric',\n timeZone,\n }).format(date);\n } catch {\n return new Intl.DateTimeFormat('en', {\n weekday: 'short',\n month: 'short',\n day: 'numeric',\n }).format(date);\n }\n}\n\nfunction formatSlotTime(\n slot: SlotGridSlot,\n locale: string,\n timeZone?: string,\n): string {\n if (slot.label !== undefined) return slot.label;\n const start = toDate(slot.start);\n try {\n const fmt = new Intl.DateTimeFormat(locale, {\n hour: 'numeric',\n minute: '2-digit',\n timeZone,\n });\n if (slot.end) {\n const end = toDate(slot.end);\n if (typeof fmt.formatRange === 'function') {\n try {\n return fmt.formatRange(start, end);\n } catch {\n /* fall through */\n }\n }\n return `${fmt.format(start)} – ${fmt.format(end)}`;\n }\n return fmt.format(start);\n } catch {\n return start.toISOString();\n }\n}\n\nfunction formatSlotAriaLabel(\n slot: SlotGridSlot,\n day: SlotGridDay,\n locale: string,\n timeZone: string | undefined,\n template: (opts: { time: string; day: string }) => string,\n): string {\n if (slot.ariaLabel !== undefined) return slot.ariaLabel;\n const time = formatSlotTime(slot, locale, timeZone);\n const dayLabel =\n day.label !== undefined ? day.label : formatDayHeader(toDate(day.date), locale, timeZone);\n return template({ time, day: dayLabel });\n}\n\n/* ------------------------------------------------------------------ */\n/* Glyphs — logical-direction arrows */\n/* ------------------------------------------------------------------ */\n\nfunction ChevronStartIcon() {\n return (\n <svg\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"ds:size-4\"\n >\n <path d=\"M15 18l-6-6 6-6\" />\n </svg>\n );\n}\n\nfunction ChevronEndIcon() {\n return (\n <svg\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"ds:size-4\"\n >\n <path d=\"M9 6l6 6-6 6\" />\n </svg>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const SlotGrid = forwardRef<HTMLDivElement, SlotGridProps>(\n (\n {\n days,\n state = 'default',\n size = 'md',\n selectedSlotId,\n maxInitialSlotsPerDay = 6,\n locale: localeProp,\n timeZone,\n hasPrevious = false,\n hasNext = false,\n showNextAvailable = false,\n ariaLabel,\n onSlotSelect,\n onPreviousDays,\n onNextDays,\n onShowMore,\n onJumpToNextAvailable,\n className,\n ...rest\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation();\n const locale = localeProp ?? i18n.language ?? 'en';\n const idBase = useId();\n\n const [expanded, setExpanded] = useState<Record<string, boolean>>({});\n\n const isLoading = state === 'loading';\n const isDisabled = state === 'disabled';\n const isInteractionSuppressed = isLoading || isDisabled;\n const isEmpty =\n state === 'empty' ||\n days.length === 0 ||\n days.every((day) => day.slots.length === 0);\n\n const resolvedAriaLabel = ariaLabel ?? t('slotGrid.ariaLabel');\n\n const handleSlotClick = useCallback(\n (slot: SlotGridSlot, day: SlotGridDay) => {\n if (isInteractionSuppressed) return;\n if (slot.available === false) return;\n onSlotSelect?.(slot, day);\n },\n [isInteractionSuppressed, onSlotSelect],\n );\n\n const handleShowMore = useCallback(\n (day: SlotGridDay, key: string) => {\n setExpanded((prev) => ({ ...prev, [key]: true }));\n onShowMore?.(day);\n },\n [onShowMore],\n );\n\n const handleSlotKeyDown = useCallback(\n (event: KeyboardEvent<HTMLButtonElement>, slot: SlotGridSlot, day: SlotGridDay) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n handleSlotClick(slot, day);\n }\n },\n [handleSlotClick],\n );\n\n const columnCount = clampCols(days.length || 1);\n const columnsClass = columnsVariants({ cols: columnCount });\n\n /* ---- Rendered content ------------------------------------------ */\n\n let body: ReactNode;\n if (isLoading) {\n body = (\n <div\n className={columnsClass}\n data-state=\"loading\"\n role=\"status\"\n aria-live=\"polite\"\n aria-label={t('common.loading')}\n >\n {Array.from({ length: columnCount }, (_, colIdx) => (\n <div key={`loading-col-${colIdx}`} className={columnVariants()}>\n <Skeleton variant=\"text\" size={size} width=\"60%\" />\n <div className={slotListVariants()}>\n {Array.from({ length: Math.min(maxInitialSlotsPerDay, 4) }, (_, rowIdx) => (\n <Skeleton\n key={`loading-slot-${colIdx}-${rowIdx}`}\n variant=\"rounded\"\n size={size}\n height=\"40px\"\n />\n ))}\n </div>\n </div>\n ))}\n </div>\n );\n } else if (isEmpty) {\n body = (\n <div data-state=\"empty\">\n <EmptyState variant=\"no-results\" title={t('slotGrid.noSlots')} />\n </div>\n );\n } else {\n body = (\n <div\n className={columnsClass}\n data-state={isDisabled ? 'disabled' : 'default'}\n >\n {days.map((day, dayIdx) => {\n const dayKey = `${toDate(day.date).toISOString()}-${dayIdx}`;\n const headerLabel =\n day.label ?? formatDayHeader(toDate(day.date), locale, timeZone);\n const headerId = `${idBase}-day-${dayIdx}-header`;\n const isExpanded = expanded[dayKey] ?? false;\n const visibleSlots = isExpanded\n ? day.slots\n : day.slots.slice(0, maxInitialSlotsPerDay);\n const hiddenCount = day.slots.length - visibleSlots.length;\n\n const isDayEmpty = day.slots.length === 0;\n\n return (\n <section\n key={dayKey}\n className={columnVariants()}\n aria-labelledby={headerId}\n data-empty={isDayEmpty || undefined}\n >\n <h3 id={headerId} className={dayHeaderVariants({ size })}>\n {headerLabel}\n </h3>\n {isDayEmpty ? (\n <p className=\"type-body-sm ds:text-[var(--muted-foreground)] ds:m-0\">\n {t('slotGrid.noSlots')}\n </p>\n ) : null}\n <ul className={slotListVariants()}>\n {visibleSlots.map((slot) => {\n const ariaLabelSlot = formatSlotAriaLabel(\n slot,\n day,\n locale,\n timeZone,\n ({ time, day: dayLabel }) =>\n t('slotGrid.slotLabel', { time, day: dayLabel }),\n );\n const isSelected = selectedSlotId === slot.id;\n const isSlotDisabled =\n slot.available === false || isInteractionSuppressed;\n return (\n <li key={slot.id}>\n <button\n type=\"button\"\n className={slotButtonVariants({ size })}\n aria-label={ariaLabelSlot}\n aria-pressed={isSelected}\n disabled={isSlotDisabled}\n aria-disabled={isSlotDisabled || undefined}\n data-slot-id={slot.id}\n onClick={() => handleSlotClick(slot, day)}\n onKeyDown={(event) => handleSlotKeyDown(event, slot, day)}\n >\n {formatSlotTime(slot, locale, timeZone)}\n </button>\n </li>\n );\n })}\n </ul>\n {hiddenCount > 0 ? (\n <Button\n intent=\"ghost\"\n size={size === 'lg' ? 'md' : 'sm'}\n onClick={() => handleShowMore(day, dayKey)}\n disabled={isInteractionSuppressed}\n >\n {t('slotGrid.showMore', { count: hiddenCount })}\n </Button>\n ) : null}\n </section>\n );\n })}\n </div>\n );\n }\n\n return (\n <div\n ref={ref}\n role=\"region\"\n aria-label={resolvedAriaLabel}\n className={slotGridVariants({ size, className })}\n data-state={state}\n {...rest}\n >\n <div className={toolbarVariants()}>\n <IconButton\n icon={<ChevronStartIcon />}\n aria-label={t('slotGrid.previousDays')}\n size={size === 'lg' ? 'md' : 'sm'}\n intent=\"ghost\"\n flipIconInRtl\n disabled={!hasPrevious || isInteractionSuppressed}\n onClick={onPreviousDays}\n />\n {showNextAvailable ? (\n <Button\n intent=\"secondary\"\n size={size === 'lg' ? 'md' : 'sm'}\n disabled={isInteractionSuppressed}\n onClick={onJumpToNextAvailable}\n >\n {t('slotGrid.nextAvailable')}\n </Button>\n ) : (\n <span aria-hidden=\"true\" />\n )}\n <IconButton\n icon={<ChevronEndIcon />}\n aria-label={t('slotGrid.nextDays')}\n size={size === 'lg' ? 'md' : 'sm'}\n intent=\"ghost\"\n flipIconInRtl\n disabled={!hasNext || isInteractionSuppressed}\n onClick={onNextDays}\n />\n </div>\n\n {body}\n </div>\n );\n },\n);\n\nSlotGrid.displayName = 'SlotGrid';\n"],"names":["parseISO","argument","options","invalidDate","constructFrom","dateStrings","splitDateString","date","parseYearResult","parseYear","parseDate","timestamp","time","offset","parseTime","parseTimezone","tmpDate","result","toDate","patterns","dateRegex","timeRegex","timezoneRegex","dateString","array","timeString","token","additionalDigits","regex","captures","year","century","isWeekDate","dayOfYear","parseDateUnit","month","day","week","dayOfWeek","validateWeekDate","dayOfISOWeekYear","validateDate","validateDayOfYearDate","value","hours","parseTimeUnit","minutes","seconds","validateTime","millisecondsInHour","millisecondsInMinute","timezoneString","sign","validateTimezone","isoWeekYear","fourthOfJanuaryDay","diff","daysInMonths","isLeapYearIndex","_year","_hours","slotGridVariants","cva","toolbarVariants","COLS_MAX","columnsVariants","clampCols","count","columnVariants","dayHeaderVariants","slotListVariants","slotButtonVariants","isSameDate","a","b","isSameDay","findFirstAvailable","days","slot","s","formatDayHeader","locale","timeZone","formatSlotTime","start","fmt","end","formatSlotAriaLabel","template","dayLabel","ChevronStartIcon","jsx","ChevronEndIcon","SlotGrid","forwardRef","state","size","selectedSlotId","maxInitialSlotsPerDay","localeProp","hasPrevious","hasNext","showNextAvailable","ariaLabel","onSlotSelect","onPreviousDays","onNextDays","onShowMore","onJumpToNextAvailable","className","rest","ref","t","i18n","useTranslation","idBase","useId","expanded","setExpanded","useState","isLoading","isDisabled","isInteractionSuppressed","isEmpty","resolvedAriaLabel","handleSlotClick","useCallback","handleShowMore","key","prev","handleSlotKeyDown","event","columnCount","columnsClass","body","_","colIdx","jsxs","Skeleton","rowIdx","EmptyState","dayIdx","dayKey","headerLabel","headerId","visibleSlots","hiddenCount","isDayEmpty","ariaLabelSlot","isSelected","isSlotDisabled","Button","IconButton"],"mappings":"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","x_google_ignoreList":[0]}
|