@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":"file-upload.agent-DYFnqdxw.js","sources":["../../node_modules/lucide-react/dist/esm/icons/cloud-upload.js","../../node_modules/lucide-react/dist/esm/icons/file-archive.js","../../node_modules/lucide-react/dist/esm/icons/file-image.js","../../node_modules/lucide-react/dist/esm/icons/file-spreadsheet.js","../../node_modules/lucide-react/dist/esm/icons/file.js","../../node_modules/lucide-react/dist/esm/icons/loader-circle.js","../../node_modules/lucide-react/dist/esm/icons/upload.js","../../src/components/file-upload/file-upload.tsx","../../src/components/file-upload/file-upload.agent.ts"],"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 [\"path\", { d: \"M12 13v8\", key: \"1l5pq0\" }],\n [\"path\", { d: \"M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242\", key: \"1pljnt\" }],\n [\"path\", { d: \"m8 17 4-4 4 4\", key: \"1quai1\" }]\n];\nconst CloudUpload = createLucideIcon(\"cloud-upload\", __iconNode);\n\nexport { __iconNode, CloudUpload as default };\n//# sourceMappingURL=cloud-upload.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: \"M13.659 22H18a2 2 0 0 0 2-2V8a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 14 2H6a2 2 0 0 0-2 2v11.5\",\n key: \"4pqfef\"\n }\n ],\n [\"path\", { d: \"M14 2v5a1 1 0 0 0 1 1h5\", key: \"wfsgrz\" }],\n [\"path\", { d: \"M8 12v-1\", key: \"1ej8lb\" }],\n [\"path\", { d: \"M8 18v-2\", key: \"qcmpov\" }],\n [\"path\", { d: \"M8 7V6\", key: \"1nbb54\" }],\n [\"circle\", { cx: \"8\", cy: \"20\", r: \"2\", key: \"ckkr5m\" }]\n];\nconst FileArchive = createLucideIcon(\"file-archive\", __iconNode);\n\nexport { __iconNode, FileArchive as default };\n//# sourceMappingURL=file-archive.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: \"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\",\n key: \"1oefj6\"\n }\n ],\n [\"path\", { d: \"M14 2v5a1 1 0 0 0 1 1h5\", key: \"wfsgrz\" }],\n [\"circle\", { cx: \"10\", cy: \"12\", r: \"2\", key: \"737tya\" }],\n [\"path\", { d: \"m20 17-1.296-1.296a2.41 2.41 0 0 0-3.408 0L9 22\", key: \"wt3hpn\" }]\n];\nconst FileImage = createLucideIcon(\"file-image\", __iconNode);\n\nexport { __iconNode, FileImage as default };\n//# sourceMappingURL=file-image.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: \"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\",\n key: \"1oefj6\"\n }\n ],\n [\"path\", { d: \"M14 2v5a1 1 0 0 0 1 1h5\", key: \"wfsgrz\" }],\n [\"path\", { d: \"M8 13h2\", key: \"yr2amv\" }],\n [\"path\", { d: \"M14 13h2\", key: \"un5t4a\" }],\n [\"path\", { d: \"M8 17h2\", key: \"2yhykz\" }],\n [\"path\", { d: \"M14 17h2\", key: \"10kma7\" }]\n];\nconst FileSpreadsheet = createLucideIcon(\"file-spreadsheet\", __iconNode);\n\nexport { __iconNode, FileSpreadsheet as default };\n//# sourceMappingURL=file-spreadsheet.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: \"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\",\n key: \"1oefj6\"\n }\n ],\n [\"path\", { d: \"M14 2v5a1 1 0 0 0 1 1h5\", key: \"wfsgrz\" }]\n];\nconst File = createLucideIcon(\"file\", __iconNode);\n\nexport { __iconNode, File as default };\n//# sourceMappingURL=file.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 = [[\"path\", { d: \"M21 12a9 9 0 1 1-6.219-8.56\", key: \"13zald\" }]];\nconst LoaderCircle = createLucideIcon(\"loader-circle\", __iconNode);\n\nexport { __iconNode, LoaderCircle as default };\n//# sourceMappingURL=loader-circle.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 [\"path\", { d: \"M12 3v12\", key: \"1x0j5s\" }],\n [\"path\", { d: \"m17 8-5-5-5 5\", key: \"7q97r8\" }],\n [\"path\", { d: \"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\", key: \"ih7n3h\" }]\n];\nconst Upload = createLucideIcon(\"upload\", __iconNode);\n\nexport { __iconNode, Upload as default };\n//# sourceMappingURL=upload.js.map\n","import {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type ClipboardEvent,\n type ReactNode,\n} from 'react';\nimport { useDropzone, type FileRejection } from 'react-dropzone';\nimport { cva } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport {\n AlertCircle,\n CheckCircle2,\n CloudUpload,\n File as FileIcon,\n FileArchive,\n FileImage,\n FileSpreadsheet,\n FileText,\n Loader2,\n Upload,\n X,\n} from 'lucide-react';\nimport { useFormField } from '../form-field/form-field-context';\n\n/* -------------------------------------------------------------------------- */\n/* Types */\n/* -------------------------------------------------------------------------- */\n\nexport interface FileUploadFile {\n file: File;\n id: string;\n status: 'pending' | 'uploading' | 'complete' | 'error';\n progress: number;\n preview?: string;\n error?: string;\n}\n\nexport interface FileUploadRejection {\n file: File;\n reason:\n | 'file-too-large'\n | 'file-too-small'\n | 'file-invalid-type'\n | 'too-many-files';\n}\n\nexport interface FileUploadProps {\n accept?: Record<string, string[]>;\n maxSize?: number;\n minSize?: number;\n maxFiles?: number;\n multiple?: boolean;\n disabled?: boolean;\n strictAccept?: boolean;\n onDrop?: (accepted: File[], rejected: FileUploadRejection[]) => void;\n onUpload?: (\n file: File,\n helpers: {\n signal: AbortSignal;\n onProgress: (percent: number) => void;\n },\n ) => Promise<void>;\n onRemove?: (file: FileUploadFile) => void;\n onReject?: (rejections: FileUploadRejection[]) => void;\n variant?: 'dropzone' | 'button' | 'both';\n showPreview?: boolean;\n className?: string;\n}\n\n/* -------------------------------------------------------------------------- */\n/* CVA */\n/* -------------------------------------------------------------------------- */\n\nconst dropzoneVariants = cva(\n [\n 'ds:relative ds:flex ds:flex-col ds:items-center ds:justify-center',\n 'ds:min-h-48 ds:px-[var(--spacing-lg)] ds:py-[var(--spacing-xl)]',\n 'ds:rounded-[var(--radius-lg)] ds:border-2 ds:border-dashed',\n 'ds:bg-background',\n 'ds:transition-all ds:duration-[var(--animation-duration)] 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-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:cursor-pointer',\n 'ds:group',\n ].join(' '),\n {\n variants: {\n isDragActive: {\n true: 'ds:border-primary ds:bg-primary/10 ds:scale-[1.01]',\n false: 'ds:border-border ds:hover:border-muted-foreground/40 ds:hover:bg-muted/5',\n },\n hasError: {\n true: 'ds:border-destructive ds:bg-destructive/5 ds:hover:border-destructive',\n false: '',\n },\n isDisabled: {\n true: 'ds:cursor-not-allowed ds:opacity-50 ds:hover:border-border ds:hover:bg-background',\n false: '',\n },\n },\n defaultVariants: {\n isDragActive: false,\n hasError: false,\n isDisabled: false,\n },\n },\n);\n\nconst browseButtonVariants = cva(\n [\n 'ds:inline-flex ds:items-center ds:justify-center ds:gap-[var(--spacing-xs)]',\n 'ds:min-h-[var(--min-target-size)] ds:min-w-[var(--min-target-size)]',\n 'ds:rounded-[var(--radius-md)] ds:border ds:border-primary/30 ds:bg-primary/5',\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:py-[var(--spacing-sm)]',\n 'ds:text-primary ds:text-[var(--font-size-sm)] ds:font-medium',\n 'ds:transition-all ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:hover:bg-primary/10 ds:hover:border-primary/50',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:disabled:cursor-not-allowed ds:disabled:opacity-50',\n ].join(' '),\n);\n\nconst fileItemVariants = cva(\n [\n 'ds:flex ds:items-center ds:gap-[var(--spacing-md)]',\n 'ds:rounded-[var(--radius-md)] ds:border ds:bg-background',\n 'ds:p-[var(--spacing-md)]',\n 'ds:text-[var(--font-size-sm)] ds:text-foreground',\n 'ds:transition-all ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n ].join(' '),\n {\n variants: {\n status: {\n pending: 'ds:border-border',\n uploading: 'ds:border-primary/30 ds:bg-primary/[0.02]',\n complete: 'ds:border-[var(--success)]/30 ds:bg-[var(--success)]/[0.02]',\n error: 'ds:border-destructive/30 ds:bg-destructive/[0.02]',\n },\n },\n defaultVariants: {\n status: 'pending',\n },\n },\n);\n\nconst actionButtonVariants = cva(\n [\n 'ds:inline-flex ds:items-center ds:justify-center',\n 'ds:min-h-[var(--min-target-size)] ds:min-w-[var(--min-target-size)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:text-muted-foreground',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:hover:text-foreground ds:hover:bg-muted/40',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n ].join(' '),\n);\n\n/* -------------------------------------------------------------------------- */\n/* Helpers */\n/* -------------------------------------------------------------------------- */\n\nfunction generateId(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;\n}\n\nfunction isImageFile(file: File): boolean {\n return file.type.startsWith('image/');\n}\n\nfunction getFileIcon(file: File): ReactNode {\n const ext = file.name.split('.').pop()?.toLowerCase() ?? '';\n if (['pdf', 'doc', 'docx', 'txt', 'rtf'].includes(ext)) {\n return <FileText aria-hidden=\"true\" className=\"ds:size-10 ds:shrink-0 ds:text-muted-foreground\" />;\n }\n if (['zip', 'rar', '7z', 'tar', 'gz'].includes(ext)) {\n return <FileArchive aria-hidden=\"true\" className=\"ds:size-10 ds:shrink-0 ds:text-muted-foreground\" />;\n }\n if (['xls', 'xlsx', 'csv'].includes(ext)) {\n return <FileSpreadsheet aria-hidden=\"true\" className=\"ds:size-10 ds:shrink-0 ds:text-muted-foreground\" />;\n }\n if (['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg', 'bmp'].includes(ext)) {\n return <FileImage aria-hidden=\"true\" className=\"ds:size-10 ds:shrink-0 ds:text-muted-foreground\" />;\n }\n return <FileIcon aria-hidden=\"true\" className=\"ds:size-10 ds:shrink-0 ds:text-muted-foreground\" />;\n}\n\nfunction getStatusIcon(status: FileUploadFile['status']): ReactNode {\n switch (status) {\n case 'uploading':\n return <Loader2 aria-hidden=\"true\" className=\"ds:size-4 ds:shrink-0 ds:text-primary ds:animate-spin\" />;\n case 'complete':\n return <CheckCircle2 aria-hidden=\"true\" className=\"ds:size-4 ds:shrink-0 ds:text-[var(--success)]\" />;\n case 'error':\n return <AlertCircle aria-hidden=\"true\" className=\"ds:size-4 ds:shrink-0 ds:text-destructive\" />;\n default:\n return null;\n }\n}\n\nconst UNIT_KEYS = [\n 'ui.inputs.fileUpload.units.bytes',\n 'ui.inputs.fileUpload.units.kilobytes',\n 'ui.inputs.fileUpload.units.megabytes',\n 'ui.inputs.fileUpload.units.gigabytes',\n] as const;\n\nconst UNIT_FALLBACKS = ['B', 'KB', 'MB', 'GB'] as const;\n\nfunction formatFileSize(\n bytes: number,\n locale: string,\n t: (key: string, fallback: string) => string,\n): string {\n let value = bytes;\n let unitIndex = 0;\n while (value >= 1024 && unitIndex < UNIT_FALLBACKS.length - 1) {\n value /= 1024;\n unitIndex++;\n }\n const formatted = new Intl.NumberFormat(locale, {\n maximumFractionDigits: unitIndex === 0 ? 0 : 1,\n }).format(value);\n const unit = t(UNIT_KEYS[unitIndex], UNIT_FALLBACKS[unitIndex]);\n return `${formatted} ${unit}`;\n}\n\nfunction mapRejectionCode(\n code: string,\n): FileUploadRejection['reason'] {\n switch (code) {\n case 'file-too-large':\n return 'file-too-large';\n case 'file-too-small':\n return 'file-too-small';\n case 'file-invalid-type':\n return 'file-invalid-type';\n case 'too-many-files':\n return 'too-many-files';\n default:\n return 'file-invalid-type';\n }\n}\n\nfunction getExtensionFromName(name: string): string {\n const parts = name.split('.');\n return parts.length > 1 ? `.${parts.pop()!.toLowerCase()}` : '';\n}\n\nfunction formatAcceptHint(accept: Record<string, string[]>): string {\n const extensions: string[] = [];\n for (const exts of Object.values(accept)) {\n for (const ext of exts) {\n extensions.push(ext.toUpperCase().replace('.', ''));\n }\n }\n if (extensions.length > 0) return extensions.join(', ');\n const mimeLabels: string[] = [];\n for (const mime of Object.keys(accept)) {\n if (mime.endsWith('/*')) {\n mimeLabels.push(mime.replace('/*', '').split('/').pop() ?? mime);\n } else {\n mimeLabels.push(mime.split('/').pop() ?? mime);\n }\n }\n return mimeLabels.join(', ');\n}\n\n/* -------------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------------- */\n\nexport const FileUpload = forwardRef<HTMLDivElement, FileUploadProps>(\n (\n {\n accept,\n maxSize,\n minSize,\n maxFiles = 1,\n multiple = false,\n disabled,\n strictAccept = false,\n onDrop: onDropProp,\n onUpload,\n onRemove,\n onReject,\n variant = 'both',\n showPreview = true,\n className,\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation();\n const ctx = useFormField();\n const fallbackId = useId();\n\n const effectiveDisabled = ctx.disabled || disabled;\n const hasError = ctx.invalid;\n const inputId = ctx.id || fallbackId;\n\n const [files, setFiles] = useState<FileUploadFile[]>([]);\n const [rejections, setRejections] = useState<FileUploadRejection[]>([]);\n const abortControllers = useRef<Map<string, AbortController>>(new Map());\n const statusRef = useRef<HTMLSpanElement>(null);\n const filesRef = useRef<FileUploadFile[]>(files);\n filesRef.current = files;\n\n const announceStatus = useCallback((message: string) => {\n if (statusRef.current) {\n statusRef.current.textContent = message;\n }\n }, []);\n\n const validateStrictAccept = useCallback(\n (file: File): boolean => {\n if (!strictAccept || !accept) return true;\n for (const [mime, extensions] of Object.entries(accept)) {\n const mimeMatch =\n mime === '*/*' ||\n (mime.endsWith('/*') && file.type.startsWith(mime.replace('/*', '/'))) ||\n file.type === mime;\n const fileExt = getExtensionFromName(file.name);\n const extMatch =\n extensions.length === 0 ||\n extensions.some((ext) => ext.toLowerCase() === fileExt);\n if (mimeMatch && extMatch) return true;\n }\n return false;\n },\n [strictAccept, accept],\n );\n\n const uploadFile = useCallback(\n async (uploadFileState: FileUploadFile) => {\n if (!onUpload) return;\n const controller = new AbortController();\n abortControllers.current.set(uploadFileState.id, controller);\n\n setFiles((prev) =>\n prev.map((f) =>\n f.id === uploadFileState.id ? { ...f, status: 'uploading', progress: 0 } : f,\n ),\n );\n announceStatus(t('ui.inputs.fileUpload.uploading', 'Uploading\\u2026'));\n\n try {\n await onUpload(uploadFileState.file, {\n signal: controller.signal,\n onProgress: (percent: number) => {\n setFiles((prev) =>\n prev.map((f) =>\n f.id === uploadFileState.id ? { ...f, progress: percent } : f,\n ),\n );\n announceStatus(\n t('ui.inputs.fileUpload.progress', '{{percent}}% uploaded', {\n percent,\n }),\n );\n },\n });\n setFiles((prev) =>\n prev.map((f) =>\n f.id === uploadFileState.id\n ? { ...f, status: 'complete', progress: 100 }\n : f,\n ),\n );\n announceStatus(t('ui.inputs.fileUpload.complete', 'Upload complete'));\n } catch (err: unknown) {\n if (controller.signal.aborted) {\n setFiles((prev) => prev.filter((f) => f.id !== uploadFileState.id));\n return;\n }\n const errorMessage =\n err instanceof Error ? err.message : t('ui.inputs.fileUpload.errors.uploadFailed', 'Upload failed');\n setFiles((prev) =>\n prev.map((f) =>\n f.id === uploadFileState.id\n ? { ...f, status: 'error', error: errorMessage }\n : f,\n ),\n );\n } finally {\n abortControllers.current.delete(uploadFileState.id);\n }\n },\n [onUpload, announceStatus, t],\n );\n\n const handleDrop = useCallback(\n (accepted: File[], fileRejections: FileRejection[]) => {\n const mapped: FileUploadRejection[] = fileRejections.flatMap((r) =>\n r.errors.map((e) => ({\n file: r.file,\n reason: mapRejectionCode(e.code),\n })),\n );\n\n const strictRejected: FileUploadRejection[] = [];\n const strictAccepted: File[] = [];\n for (const file of accepted) {\n if (!validateStrictAccept(file)) {\n strictRejected.push({ file, reason: 'file-invalid-type' });\n } else {\n strictAccepted.push(file);\n }\n }\n\n const allRejections = [...mapped, ...strictRejected];\n setRejections(allRejections);\n\n if (allRejections.length > 0) {\n onReject?.(allRejections);\n }\n\n const newFiles: FileUploadFile[] = strictAccepted.map((file) => ({\n file,\n id: generateId(),\n status: 'pending' as const,\n progress: 0,\n preview: isImageFile(file) ? URL.createObjectURL(file) : undefined,\n }));\n\n setFiles((prev) => {\n if (!multiple && maxFiles === 1) {\n for (const f of prev) {\n if (f.preview) URL.revokeObjectURL(f.preview);\n }\n return newFiles;\n }\n return [...prev, ...newFiles];\n });\n\n onDropProp?.(strictAccepted, allRejections);\n announceStatus(\n t('ui.inputs.fileUpload.filesSelected', '{{count}} file(s) selected', {\n count: strictAccepted.length,\n }),\n );\n\n for (const nf of newFiles) {\n void uploadFile(nf);\n }\n },\n [\n multiple,\n maxFiles,\n onDropProp,\n onReject,\n validateStrictAccept,\n announceStatus,\n uploadFile,\n t,\n ],\n );\n\n const { getRootProps, getInputProps, isDragActive, open } = useDropzone({\n accept,\n maxSize,\n minSize,\n maxFiles: multiple ? maxFiles : 1,\n multiple,\n disabled: effectiveDisabled,\n onDrop: handleDrop,\n noClick: variant === 'button',\n noKeyboard: variant === 'button',\n });\n\n const handleCancel = useCallback(\n (fileId: string) => {\n const controller = abortControllers.current.get(fileId);\n controller?.abort();\n setFiles((prev) => {\n const file = prev.find((f) => f.id === fileId);\n if (file?.preview) URL.revokeObjectURL(file.preview);\n return prev.filter((f) => f.id !== fileId);\n });\n },\n [],\n );\n\n const handleRemove = useCallback(\n (fileId: string) => {\n const removed = filesRef.current.find((f) => f.id === fileId);\n if (removed?.preview) URL.revokeObjectURL(removed.preview);\n setFiles((prev) => prev.filter((f) => f.id !== fileId));\n if (removed) {\n onRemove?.(removed);\n }\n },\n [onRemove],\n );\n\n const validatePastedFiles = useCallback(\n (pastedFiles: File[]): { accepted: File[]; rejected: FileUploadRejection[] } => {\n const accepted: File[] = [];\n const rejected: FileUploadRejection[] = [];\n const effectiveMaxFiles = multiple ? maxFiles : 1;\n\n for (const file of pastedFiles) {\n if (accepted.length >= effectiveMaxFiles) {\n rejected.push({ file, reason: 'too-many-files' });\n continue;\n }\n if (maxSize !== undefined && file.size > maxSize) {\n rejected.push({ file, reason: 'file-too-large' });\n continue;\n }\n if (minSize !== undefined && file.size < minSize) {\n rejected.push({ file, reason: 'file-too-small' });\n continue;\n }\n if (accept) {\n const fileExt = getExtensionFromName(file.name);\n const typeMatch = Object.entries(accept).some(([mime, extensions]) => {\n const mimeOk =\n mime === '*/*' ||\n (mime.endsWith('/*') && file.type.startsWith(mime.replace('/*', '/'))) ||\n file.type === mime;\n const extOk =\n extensions.length > 0 &&\n extensions.some((ext) => ext.toLowerCase() === fileExt);\n return mimeOk || extOk;\n });\n if (!typeMatch) {\n rejected.push({ file, reason: 'file-invalid-type' });\n continue;\n }\n }\n accepted.push(file);\n }\n return { accepted, rejected };\n },\n [accept, maxSize, minSize, maxFiles, multiple],\n );\n\n const handlePaste = useCallback(\n (event: ClipboardEvent<HTMLDivElement>) => {\n if (effectiveDisabled) return;\n const pastedFiles = Array.from(event.clipboardData.files);\n if (pastedFiles.length > 0) {\n event.preventDefault();\n const { accepted, rejected } = validatePastedFiles(pastedFiles);\n const fileRejections: FileRejection[] = rejected.map((r) => ({\n file: r.file,\n errors: [{ code: r.reason, message: r.reason }],\n }));\n handleDrop(accepted, fileRejections);\n }\n },\n [effectiveDisabled, handleDrop, validatePastedFiles],\n );\n\n useEffect(() => {\n return () => {\n for (const f of filesRef.current) {\n if (f.preview) URL.revokeObjectURL(f.preview);\n }\n };\n }, []);\n\n const constraintHints = useMemo(() => {\n const hints: string[] = [];\n if (accept) {\n hints.push(formatAcceptHint(accept));\n }\n if (maxSize) {\n hints.push(\n t('ui.inputs.fileUpload.maxSizeHint', 'Max {{size}}', {\n size: formatFileSize(maxSize, i18n.language, t),\n }),\n );\n }\n if (multiple && maxFiles > 1) {\n hints.push(\n t('ui.inputs.fileUpload.maxFilesHint', 'Up to {{count}} files', {\n count: maxFiles,\n }),\n );\n }\n return hints;\n }, [accept, maxSize, multiple, maxFiles, t, i18n.language]);\n\n const errorMessages = useMemo(() => {\n return rejections.map((r) => {\n switch (r.reason) {\n case 'file-too-large':\n return t('ui.inputs.fileUpload.errors.fileTooLarge', 'File exceeds {{maxSize}}', {\n maxSize: maxSize ? formatFileSize(maxSize, i18n.language, t) : '',\n });\n case 'file-too-small':\n return t('ui.inputs.fileUpload.errors.fileTooSmall', 'File is smaller than {{minSize}}', {\n minSize: minSize ? formatFileSize(minSize, i18n.language, t) : '',\n });\n case 'file-invalid-type':\n return t('ui.inputs.fileUpload.errors.fileInvalidType', 'File type not accepted');\n case 'too-many-files':\n return t('ui.inputs.fileUpload.errors.tooManyFiles', 'Maximum {{maxFiles}} files allowed', {\n maxFiles,\n });\n }\n });\n }, [rejections, t, maxSize, minSize, maxFiles, i18n.language]);\n\n const renderFileList = () => {\n if (files.length === 0) return null;\n\n return (\n <ul className=\"ds:mt-[var(--spacing-md)] ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:list-none ds:p-0 ds:m-0\">\n {files.map((f) => (\n <li key={f.id} className={fileItemVariants({ status: f.status })}>\n {showPreview && f.preview ? (\n <img\n src={f.preview}\n alt=\"\"\n aria-hidden=\"true\"\n className=\"ds:size-12 ds:shrink-0 ds:rounded-[var(--radius-md)] ds:object-cover ds:border ds:border-border\"\n />\n ) : (\n getFileIcon(f.file)\n )}\n\n <div className=\"ds:flex-1 ds:min-w-0\">\n <div className=\"ds:flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <p className=\"ds:truncate type-label ds:m-0\">{f.file.name}</p>\n {getStatusIcon(f.status)}\n </div>\n <p className=\"type-meta ds:text-muted-foreground ds:m-0 ds:mt-0.5\">\n {formatFileSize(f.file.size, i18n.language, t)}\n {f.status === 'uploading' && (\n <span className=\"ds:ms-[var(--spacing-sm)] ds:text-primary ds:font-medium\">\n {f.progress}%\n </span>\n )}\n {f.status === 'complete' && (\n <span className=\"ds:ms-[var(--spacing-sm)] ds:text-[var(--success)] ds:font-medium\">\n {t('ui.inputs.fileUpload.complete', 'Complete')}\n </span>\n )}\n </p>\n\n {f.status === 'uploading' && (\n <div\n role=\"progressbar\"\n aria-label={f.file.name}\n aria-valuenow={f.progress}\n aria-valuemin={0}\n aria-valuemax={100}\n className=\"ds:mt-[var(--spacing-sm)] ds:h-1.5 ds:w-full ds:rounded-[var(--radius-full)] ds:bg-muted ds:overflow-hidden\"\n >\n <div\n className=\"ds:h-full ds:rounded-[var(--radius-full)] ds:bg-primary ds:transition-[inline-size] ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none\"\n style={{ inlineSize: `${f.progress}%` }}\n />\n </div>\n )}\n\n {f.status === 'error' && f.error && (\n <p role=\"alert\" className=\"type-meta ds:text-destructive ds:m-0 ds:mt-[var(--spacing-xs)]\">\n {f.error}\n </p>\n )}\n </div>\n\n {f.status === 'uploading' && (\n <button\n type=\"button\"\n onClick={() => handleCancel(f.id)}\n aria-label={t('ui.inputs.fileUpload.cancel', 'Cancel upload')}\n className={actionButtonVariants()}\n >\n <X aria-hidden=\"true\" className=\"ds:size-4\" />\n </button>\n )}\n {(f.status === 'complete' || f.status === 'pending' || f.status === 'error') && (\n <button\n type=\"button\"\n onClick={() => handleRemove(f.id)}\n aria-label={t('ui.inputs.fileUpload.remove', 'Remove file')}\n className={actionButtonVariants()}\n >\n <X aria-hidden=\"true\" className=\"ds:size-4\" />\n </button>\n )}\n </li>\n ))}\n </ul>\n );\n };\n\n const renderDropzone = () => {\n if (variant === 'button') return null;\n\n const rootProps = getRootProps({\n className: dropzoneVariants({\n isDragActive,\n hasError: hasError ?? false,\n isDisabled: effectiveDisabled ?? false,\n className,\n }),\n tabIndex: effectiveDisabled ? -1 : 0,\n });\n\n return (\n <div\n {...rootProps}\n ref={ref}\n onPaste={handlePaste}\n id={inputId}\n aria-label={t('ui.inputs.fileUpload.dropHere', 'Drop files here or click to browse')}\n aria-describedby={ctx.describedBy || undefined}\n aria-invalid={ctx.invalid || undefined}\n aria-required={ctx.required || undefined}\n data-testid=\"file-upload-dropzone\"\n >\n <input {...getInputProps()} />\n\n <div className=\"ds:flex ds:flex-col ds:items-center ds:gap-[var(--spacing-sm)]\">\n <div className=\"ds:flex ds:items-center ds:justify-center ds:size-14 ds:rounded-[var(--radius-full)] ds:bg-primary/10 ds:text-primary ds:transition-colors ds:duration-[var(--animation-duration)] ds:group-hover:bg-primary/15 ds:motion-reduce:transition-none\">\n {isDragActive ? (\n <CloudUpload aria-hidden=\"true\" className=\"ds:size-7\" />\n ) : (\n <Upload aria-hidden=\"true\" className=\"ds:size-7\" />\n )}\n </div>\n\n <div className=\"ds:flex ds:flex-col ds:items-center ds:gap-[var(--spacing-xs)]\">\n <p className=\"type-label ds:text-foreground ds:text-center ds:m-0\">\n {isDragActive\n ? t('ui.inputs.fileUpload.dropActive', 'Drop files here')\n : t('ui.inputs.fileUpload.dropHere', 'Drop files here or click to browse')}\n </p>\n\n {constraintHints.length > 0 && !isDragActive && (\n <p className=\"type-meta ds:text-muted-foreground ds:text-center ds:m-0\">\n {constraintHints.join(' \\u00b7 ')}\n </p>\n )}\n </div>\n\n {variant === 'both' && !isDragActive && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n open();\n }}\n disabled={effectiveDisabled}\n className={browseButtonVariants({ className: 'mt-[var(--spacing-xs)]' })}\n >\n <Upload aria-hidden=\"true\" className=\"ds:size-4\" />\n {t('ui.inputs.fileUpload.browse', 'Browse files')}\n </button>\n )}\n </div>\n </div>\n );\n };\n\n const renderButton = () => {\n if (variant === 'dropzone') return null;\n\n if (variant === 'button') {\n return (\n <div onPaste={handlePaste} ref={ref}>\n <input {...getInputProps()} />\n <button\n type=\"button\"\n onClick={open}\n disabled={effectiveDisabled}\n className={browseButtonVariants({ className })}\n id={variant === 'button' ? inputId : undefined}\n aria-describedby={variant === 'button' ? (ctx.describedBy || undefined) : undefined}\n aria-invalid={variant === 'button' ? (ctx.invalid || undefined) : undefined}\n aria-required={variant === 'button' ? (ctx.required || undefined) : undefined}\n >\n <Upload aria-hidden=\"true\" className=\"ds:size-4\" />\n {t('ui.inputs.fileUpload.browse', 'Browse files')}\n </button>\n </div>\n );\n }\n\n return null;\n };\n\n return (\n <div>\n {renderDropzone()}\n {renderButton()}\n {renderFileList()}\n\n {errorMessages.length > 0 && (\n <div role=\"alert\" className=\"ds:mt-[var(--spacing-sm)] ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\">\n {errorMessages.map((msg, i) => (\n <div key={i} className=\"ds:flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <AlertCircle aria-hidden=\"true\" className=\"ds:size-3.5 ds:shrink-0 ds:text-destructive\" />\n <p className=\"type-meta ds:text-destructive ds:m-0\">{msg}</p>\n </div>\n ))}\n </div>\n )}\n\n <span\n ref={statusRef}\n role=\"status\"\n aria-live=\"polite\"\n className=\"ds:sr-only\"\n />\n </div>\n );\n },\n);\n\nFileUpload.displayName = 'FileUpload';\n","import type { AgentAdapter } from '../../agent/types';\n\nexport const fileUploadAgent: AgentAdapter<unknown> = {\n id: 'file-upload',\n capabilities: ['submit', 'dismiss'],\n state: {},\n actions: {},\n domHooks: {\n root: { attr: 'data-component', value: 'file-upload' },\n },\n};\n"],"names":["__iconNode","CloudUpload","createLucideIcon","FileArchive","FileImage","FileSpreadsheet","File","LoaderCircle","Upload","dropzoneVariants","cva","browseButtonVariants","fileItemVariants","actionButtonVariants","generateId","isImageFile","file","getFileIcon","ext","_a","jsx","FileText","FileIcon","getStatusIcon","status","Loader2","CheckCircle2","AlertCircle","UNIT_KEYS","UNIT_FALLBACKS","formatFileSize","bytes","locale","t","value","unitIndex","formatted","unit","mapRejectionCode","code","getExtensionFromName","name","parts","formatAcceptHint","accept","extensions","exts","mimeLabels","mime","FileUpload","forwardRef","maxSize","minSize","maxFiles","multiple","disabled","strictAccept","onDropProp","onUpload","onRemove","onReject","variant","showPreview","className","ref","i18n","useTranslation","ctx","useFormField","fallbackId","useId","effectiveDisabled","hasError","inputId","files","setFiles","useState","rejections","setRejections","abortControllers","useRef","statusRef","filesRef","announceStatus","useCallback","message","validateStrictAccept","mimeMatch","fileExt","extMatch","uploadFile","uploadFileState","controller","prev","f","percent","err","errorMessage","handleDrop","accepted","fileRejections","mapped","r","e","strictRejected","strictAccepted","allRejections","newFiles","nf","getRootProps","getInputProps","isDragActive","open","useDropzone","handleCancel","fileId","handleRemove","removed","validatePastedFiles","pastedFiles","rejected","effectiveMaxFiles","mimeOk","extOk","handlePaste","event","useEffect","constraintHints","useMemo","hints","errorMessages","renderFileList","jsxs","X","renderDropzone","rootProps","renderButton","msg","i","fileUploadAgent"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5,6]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"floating-action-button-RigP2E7o.js","sources":["../../src/components/floating-action-button/floating-action-button.tsx"],"sourcesContent":["import {\n forwardRef,\n type ButtonHTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\n\nconst fabVariants = cva(\n [\n // `relative` anchors the `::before` hit-target expansion on `sm`.\n 'ds:relative ds:inline-flex ds:items-center ds:justify-center',\n 'ds:font-medium ds:whitespace-nowrap',\n 'ds:rounded-full',\n 'ds:shadow-[var(--shadow-lg)] ds:hover:shadow-[var(--shadow-xl)] ds:active:shadow-[var(--shadow-md)]',\n 'ds:transition-[box-shadow,background-color,transform]',\n 'ds:duration-[var(--animation-duration)]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n // Under Windows High Contrast Mode the `shadow-*` affordance is stripped.\n // Repaint a solid edge + swap the focus ring to CanvasText so the FAB\n // remains identifiable and its focus state stays visible.\n 'ds:forced-colors:border ds:forced-colors:border-[ButtonBorder] ds:forced-colors:focus-visible:outline-[CanvasText]',\n 'ds:disabled:opacity-50 ds:disabled:cursor-not-allowed ds:disabled:shadow-[var(--shadow-md)]',\n 'ds:motion-reduce:transition-none',\n ].join(' '),\n {\n variants: {\n variant: {\n primary:\n 'ds:bg-primary ds:text-primary-foreground ds:hover:bg-primary-hover',\n secondary:\n 'ds:bg-accent ds:text-accent-foreground ds:hover:bg-accent-hover',\n },\n size: {\n // `sm` is 40x40 which sits below the 44/48 px WCAG 2.5.5 target.\n // Mirror Button's pseudo-expansion pattern: below the `sm:` (640 px)\n // breakpoint, a `::before` rectangle enlarges the hit area to\n // `--min-target-size` (44 default, 48 accessible). Above the\n // breakpoint (desktop / trackpad), the physical 40 px circle is\n // enough — the pseudo hides.\n sm: 'ds:h-10 ds:w-10 ds:text-[var(--font-size-sm)] ds:[&_svg]:size-5 ds:before:absolute ds:before:inset-x-[calc((var(--min-target-size)-100%)/-2)] ds:before:inset-y-[calc((var(--min-target-size)-100%)/-2)] ds:before:content-[\"\"] ds:sm:before:hidden',\n md: 'ds:h-14 ds:w-14 ds:text-[var(--font-size-base)] ds:[&_svg]:size-6',\n lg: 'ds:h-16 ds:w-16 ds:text-[var(--font-size-lg)] ds:[&_svg]:size-7',\n },\n extended: {\n true: 'ds:w-auto ds:gap-[var(--spacing-sm)]',\n false: '',\n },\n position: {\n 'bottom-end':\n 'ds:fixed ds:z-[var(--z-fixed)] ds:bottom-[calc(var(--spacing-lg)+env(safe-area-inset-bottom,0px))] ds:end-[var(--spacing-lg)]',\n 'bottom-start':\n 'ds:fixed ds:z-[var(--z-fixed)] ds:bottom-[calc(var(--spacing-lg)+env(safe-area-inset-bottom,0px))] ds:start-[var(--spacing-lg)]',\n 'top-end':\n 'ds:fixed ds:z-[var(--z-fixed)] ds:top-[calc(var(--spacing-lg)+env(safe-area-inset-top,0px))] ds:end-[var(--spacing-lg)]',\n 'top-start':\n 'ds:fixed ds:z-[var(--z-fixed)] ds:top-[calc(var(--spacing-lg)+env(safe-area-inset-top,0px))] ds:start-[var(--spacing-lg)]',\n static: '',\n },\n },\n compoundVariants: [\n { extended: true, size: 'sm', class: 'ds:ps-3 ds:pe-4' },\n { extended: true, size: 'md', class: 'ds:ps-4 ds:pe-5' },\n { extended: true, size: 'lg', class: 'ds:ps-5 ds:pe-6' },\n ],\n defaultVariants: {\n variant: 'primary',\n size: 'md',\n extended: false,\n position: 'bottom-end',\n },\n },\n);\n\ntype FabBaseProps = ButtonHTMLAttributes<HTMLButtonElement> &\n VariantProps<typeof fabVariants>;\n\ninterface CircularFabProps extends FabBaseProps {\n extended?: false;\n icon: ReactNode;\n 'aria-label': string;\n children?: never;\n}\n\ninterface ExtendedFabProps extends FabBaseProps {\n extended: true;\n icon?: ReactNode;\n children: ReactNode;\n}\n\nexport type FloatingActionButtonProps = CircularFabProps | ExtendedFabProps;\n\nexport const FloatingActionButton = forwardRef<\n HTMLButtonElement,\n FloatingActionButtonProps\n>((props, ref) => {\n const {\n variant,\n size,\n extended,\n position,\n className,\n icon,\n children,\n type,\n ...rest\n } = props;\n const { t } = useTranslation();\n\n const ariaLabel =\n rest['aria-label'] ??\n (!extended ? t('ui.common.add', { defaultValue: 'Add' }) : undefined);\n\n return (\n <button\n ref={ref}\n type={type ?? 'button'}\n className={fabVariants({ variant, size, extended, position, className })}\n {...rest}\n aria-label={ariaLabel}\n >\n {icon ? (\n <span aria-hidden=\"true\" className=\"ds:inline-flex ds:items-center ds:justify-center\">\n {icon}\n </span>\n ) : null}\n {extended ? <span className=\"ds:inline-flex\">{children}</span> : null}\n </button>\n );\n});\n\nFloatingActionButton.displayName = 'FloatingActionButton';\n"],"names":["fabVariants","cva","FloatingActionButton","forwardRef","props","ref","variant","size","extended","position","className","icon","children","type","rest","t","useTranslation","ariaLabel","jsxs","jsx"],"mappings":";;;;AAQA,MAAMA,IAAcC;AAAA,EAClB;AAAA;AAAA,IAEE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,GAAG;AAAA,EACV;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SACE;AAAA,QACF,WACE;AAAA,MAAA;AAAA,MAEJ,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAOJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MAAA;AAAA,MAEN,UAAU;AAAA,QACR,MAAM;AAAA,QACN,OAAO;AAAA,MAAA;AAAA,MAET,UAAU;AAAA,QACR,cACE;AAAA,QACF,gBACE;AAAA,QACF,WACE;AAAA,QACF,aACE;AAAA,QACF,QAAQ;AAAA,MAAA;AAAA,IACV;AAAA,IAEF,kBAAkB;AAAA,MAChB,EAAE,UAAU,IAAM,MAAM,MAAM,OAAO,kBAAA;AAAA,MACrC,EAAE,UAAU,IAAM,MAAM,MAAM,OAAO,kBAAA;AAAA,MACrC,EAAE,UAAU,IAAM,MAAM,MAAM,OAAO,kBAAA;AAAA,IAAkB;AAAA,IAEzD,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,MAAM;AAAA,MACN,UAAU;AAAA,MACV,UAAU;AAAA,IAAA;AAAA,EACZ;AAEJ,GAoBaC,IAAuBC,EAGlC,CAACC,GAAOC,MAAQ;AAChB,QAAM;AAAA,IACJ,SAAAC;AAAA,IACA,MAAAC;AAAA,IACA,UAAAC;AAAA,IACA,UAAAC;AAAA,IACA,WAAAC;AAAA,IACA,MAAAC;AAAA,IACA,UAAAC;AAAA,IACA,MAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,IACDV,GACE,EAAE,GAAAW,EAAA,IAAMC,EAAA,GAERC,IACJH,EAAK,YAAY,MACfN,IAAyD,SAA9CO,EAAE,iBAAiB,EAAE,cAAc,MAAA,CAAO;AAEzD,SACE,gBAAAG;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAAb;AAAA,MACA,MAAMQ,KAAQ;AAAA,MACd,WAAWb,EAAY,EAAE,SAAAM,GAAS,MAAAC,GAAM,UAAAC,GAAU,UAAAC,GAAU,WAAAC,GAAW;AAAA,MACtE,GAAGI;AAAA,MACJ,cAAYG;AAAA,MAEX,UAAA;AAAA,QAAAN,sBACE,QAAA,EAAK,eAAY,QAAO,WAAU,oDAChC,aACH,IACE;AAAA,QACHH,IAAW,gBAAAW,EAAC,QAAA,EAAK,WAAU,kBAAkB,UAAAP,GAAS,IAAU;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGvE,CAAC;AAEDV,EAAqB,cAAc;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"multi-select.agent-BUKYZJfp.js","sources":["../../src/components/multi-select/multi-select.tsx","../../src/components/multi-select/multi-select.agent.ts"],"sourcesContent":["import {\n forwardRef,\n useContext,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type KeyboardEvent,\n type MouseEvent,\n type ReactElement,\n type Ref,\n} from 'react';\nimport * as Popover from '@radix-ui/react-popover';\nimport { Command } from 'cmdk';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Check, X } from 'lucide-react';\nimport {\n FormFieldContext,\n useFormField,\n} from '../form-field/form-field-context';\nimport { Tooltip } from '../tooltip';\nimport type { OptionShape } from '../_shared/option';\nimport { composeRefs } from '../_shared/compose-refs';\nimport { groupOptions } from '../_shared/group-options';\nimport {\n INPUT_SURFACE_CHROME,\n INPUT_SURFACE_TEXT,\n} from '../_shared/input-surface';\n\n// MultiSelect uses `min-h-*` (not `h-*`) because the wrapper grows vertically\n// as chips wrap to additional lines. The height floor per size mirrors the\n// other inputs' fixed heights in _shared/input-surface.ts.\nconst multiSelectVariants = cva(\n [\n 'ds:inline-flex ds:flex-wrap ds:items-center ds:gap-1 ds:w-full',\n INPUT_SURFACE_CHROME,\n 'ds:aria-[invalid=true]:border-destructive',\n 'ds:aria-disabled:cursor-not-allowed ds:aria-disabled:opacity-50',\n ],\n {\n variants: {\n size: {\n sm: `ds:min-h-8 ds:ps-2 ds:pe-2 ds:py-1 ${INPUT_SURFACE_TEXT.sm}`,\n md: `ds:min-h-[var(--min-target-size)] ds:ps-3 ds:pe-3 ds:py-1.5 ${INPUT_SURFACE_TEXT.md}`,\n lg: `ds:min-h-12 ds:ps-4 ds:pe-4 ds:py-2 ${INPUT_SURFACE_TEXT.lg}`,\n },\n },\n defaultVariants: { size: 'md' },\n },\n);\n\nconst chipVariants = cva(\n [\n 'ds:inline-flex ds:items-center ds:gap-1',\n 'ds:rounded-[var(--radius-sm)] ds:border ds:border-border ds:bg-muted',\n 'ds:text-foreground ds:select-none',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] 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-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n ],\n {\n variants: {\n size: {\n sm: 'ds:ps-2 ds:pe-1 ds:py-0.5 ds:text-[var(--font-size-xs)]',\n md: 'ds:ps-2 ds:pe-1 ds:py-0.5 ds:text-[var(--font-size-sm)]',\n lg: 'ds:ps-3 ds:pe-1.5 ds:py-1 ds:text-[var(--font-size-base)]',\n },\n },\n defaultVariants: { size: 'md' },\n },\n);\n\nconst chipDismissClasses = [\n 'inline-flex items-center justify-center shrink-0',\n 'rounded-[var(--radius-sm)]',\n 'text-muted-foreground hover:text-foreground',\n 'transition-colors duration-[var(--animation-duration)] motion-reduce:transition-none',\n 'focus-visible:outline-[length:var(--focus-ring-width)] focus-visible:outline-solid',\n 'focus-visible:outline-ring focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'size-4',\n 'relative before:absolute before:inset-[calc((var(--min-target-size)-100%)/-2)] before:content-[\"\"]',\n].join(' ');\n\nconst popoverContentClasses = [\n 'z-[var(--z-dropdown)] overflow-hidden',\n 'min-w-[var(--radix-popover-trigger-width)]',\n 'rounded-[var(--radius-md)] border border-border bg-background text-foreground',\n 'shadow-[var(--shadow-lg)]',\n 'animate-in fade-in zoom-in-95',\n 'data-[state=closed]:animate-out data-[state=closed]:fade-out',\n 'data-[state=closed]:zoom-out-95',\n 'data-[side=bottom]:slide-in-from-top-2',\n 'data-[side=top]:slide-in-from-bottom-2',\n 'motion-reduce:animate-none',\n].join(' ');\n\nconst commandItemClasses = [\n 'relative flex cursor-pointer items-center',\n 'rounded-[var(--radius-sm)] ps-2 pe-2 py-1.5',\n 'text-[var(--font-size-sm)] text-foreground outline-none select-none',\n 'data-[selected=true]:bg-muted data-[selected=true]:text-foreground',\n 'aria-[disabled=true]:pointer-events-none aria-[disabled=true]:opacity-50',\n 'data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50',\n].join(' ');\n\nconst actionItemClasses = [\n 'relative flex cursor-pointer items-center',\n 'rounded-[var(--radius-sm)] ps-2 pe-2 py-1.5',\n 'text-[var(--font-size-sm)] font-medium text-primary outline-none select-none',\n 'data-[selected=true]:bg-muted',\n].join(' ');\n\nconst SELECT_ALL_VALUE = '__ui-multiselect-select-all__';\nconst CLEAR_ALL_VALUE = '__ui-multiselect-clear-all__';\n\ntype HTMLDivAttributes = HTMLAttributes<HTMLDivElement>;\n\nexport interface MultiSelectProps<T extends string = string>\n extends Omit<HTMLDivAttributes, 'onChange'>,\n VariantProps<typeof multiSelectVariants> {\n options: OptionShape<T>[];\n value?: T[];\n defaultValue?: T[];\n onChange?: (next: T[]) => void;\n onComplete?: (values: T[]) => void;\n placeholder?: string;\n maxSelections?: number;\n allowSelectAll?: boolean;\n allowClear?: boolean;\n filter?: (query: string, option: OptionShape<T>) => boolean;\n size?: 'sm' | 'md' | 'lg';\n disabled?: boolean;\n}\n\nconst MultiSelectImpl = forwardRef<HTMLDivElement, MultiSelectProps>(\n function MultiSelect(\n {\n options,\n value,\n defaultValue,\n onChange,\n onComplete,\n placeholder,\n maxSelections,\n allowSelectAll = false,\n allowClear = false,\n filter,\n size = 'md',\n disabled,\n className,\n id,\n ...divProps\n },\n ref,\n ) {\n const { t } = useTranslation();\n const ctx = useFormField();\n const inFormField = useContext(FormFieldContext) !== null;\n\n const [internalValue, setInternalValue] = useState<string[]>(\n defaultValue ?? [],\n );\n const isControlled = value !== undefined;\n const currentValue = isControlled ? value : internalValue;\n\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n\n const inputRef = useRef<HTMLInputElement>(null);\n const chipRefs = useRef<Array<HTMLSpanElement | null>>([]);\n const triggerRef = useRef<HTMLDivElement>(null);\n const composedRef = composeRefs<HTMLDivElement>(ref, triggerRef);\n\n const effectiveDisabled =\n (inFormField && ctx.disabled) || Boolean(disabled);\n const effectiveRequired = inFormField && ctx.required;\n const effectiveInvalid = inFormField && ctx.invalid;\n const describedBy =\n inFormField && ctx.describedBy ? ctx.describedBy : undefined;\n const triggerId = id ?? (inFormField ? ctx.id : undefined);\n\n const labelByValue = useMemo(() => {\n const map = new Map<string, string>();\n for (const option of options) map.set(option.value, option.label);\n return map;\n }, [options]);\n\n const atCap =\n typeof maxSelections === 'number' && currentValue.length >= maxSelections;\n\n const commit = (next: string[]): void => {\n if (!isControlled) setInternalValue(next);\n onChange?.(next);\n };\n\n const toggle = (val: string): void => {\n if (currentValue.includes(val)) {\n commit(currentValue.filter((v) => v !== val));\n return;\n }\n if (atCap) return;\n commit([...currentValue, val]);\n };\n\n const removeAt = (index: number): string[] => {\n const next = currentValue.filter((_, i) => i !== index);\n commit(next);\n return next;\n };\n\n const handleSelectAll = (): void => {\n const selectable = options\n .filter((o) => !o.disabled)\n .map((o) => o.value);\n const cap =\n typeof maxSelections === 'number' ? maxSelections : selectable.length;\n commit(selectable.slice(0, cap));\n };\n\n const handleClearAll = (): void => {\n commit([]);\n };\n\n const resolvedPlaceholder =\n placeholder ?? t('ui.inputs.multiSelect.placeholder', 'Select…');\n\n const filteredOptions = useMemo(() => {\n if (!query) return options;\n const needle = query.toLowerCase();\n return options.filter((option) => {\n if (filter) return filter(query, option);\n return option.label.toLowerCase().includes(needle);\n });\n }, [options, query, filter]);\n\n const groups = useMemo(\n () => groupOptions(filteredOptions),\n [filteredOptions],\n );\n\n const handleInputKeyDown = (\n e: KeyboardEvent<HTMLInputElement>,\n ): void => {\n const target = e.currentTarget;\n if (e.key === 'Backspace' && query === '' && currentValue.length > 0) {\n e.preventDefault();\n const removedIndex = currentValue.length - 1;\n const next = removeAt(removedIndex);\n const newLast = next.length - 1;\n if (newLast >= 0) {\n requestAnimationFrame(() => {\n chipRefs.current[newLast]?.focus();\n });\n }\n return;\n }\n const caretAtStart =\n target.selectionStart === 0 && target.selectionEnd === 0;\n if (\n (e.key === 'ArrowLeft' || e.key === 'ArrowRight') &&\n caretAtStart &&\n currentValue.length > 0\n ) {\n const isRTL = document.dir === 'rtl' || target.dir === 'rtl';\n const shouldNavigate =\n (isRTL && e.key === 'ArrowRight') ||\n (!isRTL && e.key === 'ArrowLeft');\n if (shouldNavigate) {\n e.preventDefault();\n const lastIdx = currentValue.length - 1;\n chipRefs.current[lastIdx]?.focus();\n }\n return;\n }\n if (e.key === 'Escape') {\n setOpen(false);\n return;\n }\n if (!open && (e.key === 'ArrowDown' || e.key === 'Enter')) {\n setOpen(true);\n }\n };\n\n const handleChipKeyDown =\n (index: number) =>\n (e: KeyboardEvent<HTMLSpanElement>): void => {\n if (\n e.key === 'Backspace' ||\n e.key === 'Delete' ||\n e.key === 'Enter' ||\n e.key === ' '\n ) {\n e.preventDefault();\n e.stopPropagation();\n const next = removeAt(index);\n if (next.length === 0) {\n requestAnimationFrame(() => inputRef.current?.focus());\n return;\n }\n const focusIdx = Math.min(index, next.length - 1);\n requestAnimationFrame(() => {\n chipRefs.current[focusIdx]?.focus();\n });\n return;\n }\n const isRTL = document.dir === 'rtl';\n const prevKey = isRTL ? 'ArrowRight' : 'ArrowLeft';\n const nextKey = isRTL ? 'ArrowLeft' : 'ArrowRight';\n if (e.key === prevKey) {\n e.preventDefault();\n const newIdx = Math.max(0, index - 1);\n chipRefs.current[newIdx]?.focus();\n return;\n }\n if (e.key === nextKey) {\n e.preventDefault();\n if (index < currentValue.length - 1) {\n chipRefs.current[index + 1]?.focus();\n } else {\n inputRef.current?.focus();\n }\n return;\n }\n if (e.key === 'Escape') {\n setOpen(false);\n inputRef.current?.focus();\n }\n };\n\n // ----- Chip overflow measurement -----\n const [visibleCount, setVisibleCount] = useState<number>(\n Number.POSITIVE_INFINITY,\n );\n\n useLayoutEffect(() => {\n const el = triggerRef.current;\n if (!el) return;\n\n const measure = (): void => {\n const chipEls = Array.from(\n el.querySelectorAll<HTMLElement>('[data-ui-chip=\"true\"]'),\n );\n if (chipEls.length === 0) {\n setVisibleCount(Number.POSITIVE_INFINITY);\n return;\n }\n const firstTop = chipEls[0].offsetTop;\n let firstRowCount = 0;\n for (const chip of chipEls) {\n if (chip.offsetTop === firstTop) firstRowCount++;\n else break;\n }\n if (firstRowCount === chipEls.length) {\n setVisibleCount(Number.POSITIVE_INFINITY);\n } else {\n setVisibleCount(Math.max(1, firstRowCount - 1));\n }\n };\n\n measure();\n const ro = new ResizeObserver(measure);\n ro.observe(el);\n return () => ro.disconnect();\n }, [currentValue.length, size]);\n\n const chips = currentValue.map((val) => ({\n value: val,\n label: labelByValue.get(val) ?? val,\n }));\n\n const showAllChips =\n visibleCount === Number.POSITIVE_INFINITY ||\n visibleCount >= chips.length;\n const visibleChips = showAllChips ? chips : chips.slice(0, visibleCount);\n const overflowChips = showAllChips ? [] : chips.slice(visibleCount);\n const overflowCount = overflowChips.length;\n\n const handleTriggerClick = (event: MouseEvent<HTMLDivElement>): void => {\n if (effectiveDisabled) return;\n // Ignore clicks on chips/buttons so they can manage their own focus.\n const target = event.target as HTMLElement;\n if (target.closest('[data-ui-chip=\"true\"]')) return;\n if (target.closest('[data-ui-chip-dismiss=\"true\"]')) return;\n setOpen(true);\n inputRef.current?.focus();\n };\n\n const handleOpenChange = (next: boolean): void => {\n if (effectiveDisabled) {\n setOpen(false);\n return;\n }\n setOpen(next);\n if (!next) {\n setQuery('');\n onComplete?.(currentValue);\n }\n };\n\n const hasActionRow = allowSelectAll || allowClear;\n\n const counterMessage = t('ui.inputs.multiSelect.selected', {\n count: currentValue.length,\n defaultValue: `${currentValue.length} selected`,\n });\n\n const { onClick: onClickProp, ...restDivProps } = divProps;\n\n return (\n <Command shouldFilter={false} label={counterMessage}>\n <Popover.Root open={open} onOpenChange={handleOpenChange}>\n <Popover.Anchor asChild>\n <div\n ref={composedRef}\n className={multiSelectVariants({ size, className })}\n aria-disabled={effectiveDisabled || undefined}\n aria-invalid={effectiveInvalid || undefined}\n onClick={(event) => {\n onClickProp?.(event);\n handleTriggerClick(event);\n }}\n {...restDivProps}\n >\n {visibleChips.map((chip, idx) => (\n <span\n key={chip.value}\n ref={(el) => {\n chipRefs.current[idx] = el;\n }}\n tabIndex={effectiveDisabled ? -1 : 0}\n data-ui-chip=\"true\"\n className={chipVariants({ size })}\n onKeyDown={handleChipKeyDown(idx)}\n aria-label={chip.label}\n >\n <span>{chip.label}</span>\n <button\n type=\"button\"\n tabIndex={-1}\n data-ui-chip-dismiss=\"true\"\n aria-label={t('ui.inputs.multiSelect.remove', {\n label: chip.label,\n defaultValue: `Remove ${chip.label}`,\n })}\n disabled={effectiveDisabled}\n onClick={(event) => {\n event.stopPropagation();\n removeAt(idx);\n requestAnimationFrame(() => inputRef.current?.focus());\n }}\n className={chipDismissClasses}\n >\n <X aria-hidden=\"true\" className=\"ds:size-3.5\" />\n </button>\n </span>\n ))}\n {overflowCount > 0 ? (\n <Tooltip\n label={overflowChips.map((c) => c.label).join(', ')}\n delayDuration={200}\n >\n <span\n className={chipVariants({ size })}\n tabIndex={0}\n role=\"button\"\n aria-label={t('ui.inputs.multiSelect.overflow', {\n count: overflowCount,\n defaultValue: `+${overflowCount} more`,\n })}\n >\n <span>\n {t('ui.inputs.multiSelect.overflow', {\n count: overflowCount,\n defaultValue: `+${overflowCount} more`,\n })}\n </span>\n </span>\n </Tooltip>\n ) : null}\n <Command.Input\n ref={inputRef}\n value={query}\n onValueChange={setQuery}\n onKeyDown={handleInputKeyDown}\n onFocus={() => {\n if (!effectiveDisabled) setOpen(true);\n }}\n placeholder={\n currentValue.length === 0 ? resolvedPlaceholder : ''\n }\n id={triggerId}\n aria-describedby={describedBy}\n aria-invalid={effectiveInvalid || undefined}\n aria-required={effectiveRequired || undefined}\n disabled={effectiveDisabled}\n className={[\n 'ds:flex-1 ds:min-w-[6rem] ds:bg-transparent ds:outline-none',\n 'ds:placeholder:text-muted-foreground ds:text-start',\n 'ds:disabled:cursor-not-allowed',\n ].join(' ')}\n />\n </div>\n </Popover.Anchor>\n <Popover.Portal>\n <Popover.Content\n onOpenAutoFocus={(e) => e.preventDefault()}\n onCloseAutoFocus={(e) => e.preventDefault()}\n align=\"start\"\n sideOffset={4}\n className={popoverContentClasses}\n >\n <Command.List\n role=\"listbox\"\n aria-multiselectable=\"true\"\n aria-label={resolvedPlaceholder}\n className=\"ds:max-h-[20rem] ds:overflow-y-auto ds:p-1\"\n >\n {hasActionRow ? (\n <Command.Group>\n {allowSelectAll ? (\n <Command.Item\n value={SELECT_ALL_VALUE}\n onSelect={handleSelectAll}\n className={actionItemClasses}\n >\n {t('ui.inputs.multiSelect.selectAll', 'Select all')}\n </Command.Item>\n ) : null}\n {allowClear ? (\n <Command.Item\n value={CLEAR_ALL_VALUE}\n onSelect={handleClearAll}\n className={actionItemClasses}\n >\n {t('ui.inputs.multiSelect.clearAll', 'Clear all')}\n </Command.Item>\n ) : null}\n </Command.Group>\n ) : null}\n <Command.Empty className=\"ds:ps-2 ds:pe-2 ds:py-2 type-body-sm ds:text-muted-foreground\">\n {t('ui.inputs.multiSelect.noOptions', 'No options found')}\n </Command.Empty>\n {groups.map(({ group, items }, gi) => {\n const body = items.map((option) => {\n const isSelected = currentValue.includes(option.value);\n const isCapped = !isSelected && atCap;\n const isDisabled =\n Boolean(option.disabled) || isCapped;\n const item = (\n <Command.Item\n key={option.value}\n value={option.value}\n disabled={isDisabled}\n onSelect={() => {\n if (isDisabled) return;\n toggle(option.value);\n }}\n aria-selected={isSelected}\n aria-disabled={isDisabled || undefined}\n className={commandItemClasses}\n >\n <span\n className={[\n 'ds:inline-flex ds:items-center ds:justify-center ds:me-2 ds:shrink-0',\n 'ds:size-4 ds:rounded-[var(--radius-sm)] ds:border ds:border-border',\n isSelected\n ? 'ds:bg-primary ds:border-primary ds:text-primary-foreground'\n : 'ds:bg-background',\n ].join(' ')}\n aria-hidden=\"true\"\n >\n {isSelected ? <Check className=\"ds:size-3.5\" /> : null}\n </span>\n <span className=\"ds:flex-1 ds:text-start\">{option.label}</span>\n </Command.Item>\n );\n if (isCapped) {\n return (\n <Tooltip\n key={option.value}\n label={t('ui.inputs.multiSelect.maxReached', {\n count: maxSelections,\n defaultValue: `Maximum ${maxSelections} selections`,\n })}\n delayDuration={200}\n >\n {item}\n </Tooltip>\n );\n }\n return item;\n });\n if (!group) {\n return (\n <Command.Group key={`group-${gi}`}>{body}</Command.Group>\n );\n }\n return (\n <Command.Group\n key={`group-${group}`}\n heading={group}\n className=\"ds:[&_[cmdk-group-heading]]:ps-2 ds:[&_[cmdk-group-heading]]:pe-2 ds:[&_[cmdk-group-heading]]:py-1 ds:[&_[cmdk-group-heading]]:type-eyebrow ds:[&_[cmdk-group-heading]]:text-muted-foreground\"\n >\n {body}\n </Command.Group>\n );\n })}\n </Command.List>\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n </Command>\n );\n },\n);\nMultiSelectImpl.displayName = 'MultiSelect';\n\ninterface MultiSelectComponent {\n <T extends string = string>(\n props: MultiSelectProps<T> & { ref?: Ref<HTMLDivElement> },\n ): ReactElement | null;\n displayName?: string;\n}\n\nexport const MultiSelect = MultiSelectImpl as unknown as MultiSelectComponent;\n\nexport { multiSelectVariants };\n","import type { AgentAdapter } from '../../agent/types';\n\nexport const multiSelectAgent: AgentAdapter<unknown> = {\n id: 'multi-select',\n capabilities: ['select_multiple', 'filter', 'open', 'close'],\n state: {},\n actions: {},\n domHooks: {\n root: { attr: 'data-component', value: 'multi-select' },\n item: {\n attr: 'data-option-id',\n description: 'Each option emits its value as data-option-id.',\n },\n },\n};\n"],"names":["multiSelectVariants","cva","INPUT_SURFACE_CHROME","INPUT_SURFACE_TEXT","chipVariants","chipDismissClasses","popoverContentClasses","commandItemClasses","actionItemClasses","SELECT_ALL_VALUE","CLEAR_ALL_VALUE","MultiSelectImpl","forwardRef","options","value","defaultValue","onChange","onComplete","placeholder","maxSelections","allowSelectAll","allowClear","filter","size","disabled","className","id","divProps","ref","t","useTranslation","ctx","useFormField","inFormField","useContext","FormFieldContext","internalValue","setInternalValue","useState","isControlled","currentValue","open","setOpen","query","setQuery","inputRef","useRef","chipRefs","triggerRef","composedRef","composeRefs","effectiveDisabled","effectiveRequired","effectiveInvalid","describedBy","triggerId","labelByValue","useMemo","map","option","atCap","commit","next","toggle","val","v","removeAt","index","_","i","handleSelectAll","selectable","o","cap","handleClearAll","resolvedPlaceholder","filteredOptions","needle","groups","groupOptions","handleInputKeyDown","target","removedIndex","newLast","_a","caretAtStart","isRTL","lastIdx","handleChipKeyDown","e","focusIdx","prevKey","nextKey","newIdx","_b","_c","_d","visibleCount","setVisibleCount","useLayoutEffect","el","measure","chipEls","firstTop","firstRowCount","chip","ro","chips","showAllChips","visibleChips","overflowChips","overflowCount","handleTriggerClick","event","handleOpenChange","hasActionRow","counterMessage","onClickProp","restDivProps","jsx","Command","jsxs","Popover","idx","X","Tooltip","c","group","items","gi","body","isSelected","isCapped","isDisabled","item","Check","MultiSelect","multiSelectAgent"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"number-input-D7rSa_ef.js","sources":["../../src/components/number-input/use-locale-number.ts","../../src/components/number-input/number-input.tsx"],"sourcesContent":["import { useMemo } from 'react';\n\nexport type NumberInputMode = 'integer' | 'decimal' | 'currency' | 'percentage';\n\nexport interface LocaleNumber {\n /** Format a JS number for display (e.g. `1234.5` → `1.234,5` in de-DE). */\n format: (value: number) => string;\n /** Parse a locale-formatted string back to a JS number. Returns `NaN` for invalid input. */\n parse: (text: string) => number;\n /** The decimal separator for this locale (e.g. `.` or `,`). */\n decimalSeparator: string;\n /** The grouping separator for this locale (e.g. `,` or `.` or ` `). */\n groupingSeparator: string;\n /** The correct `inputMode` for the virtual keyboard. */\n inputMode: 'numeric' | 'decimal';\n}\n\nfunction normalizeDigits(text: string): string {\n let result = '';\n for (const ch of text) {\n const code = ch.codePointAt(0);\n if (code === undefined) continue;\n if (code >= 0x0660 && code <= 0x0669) {\n result += String.fromCodePoint(0x30 + (code - 0x0660));\n } else if (code >= 0x06f0 && code <= 0x06f9) {\n result += String.fromCodePoint(0x30 + (code - 0x06f0));\n } else {\n result += ch;\n }\n }\n return result;\n}\n\nexport function useLocaleNumber(\n locale: string,\n mode: NumberInputMode,\n currency?: string,\n): LocaleNumber {\n return useMemo(() => {\n const parts = new Intl.NumberFormat(locale).formatToParts(1234.5);\n const decimalSeparator =\n parts.find((p) => p.type === 'decimal')?.value ?? '.';\n const groupingSeparator =\n parts.find((p) => p.type === 'group')?.value ?? ',';\n\n const displayFormatter: Intl.NumberFormat = (() => {\n if (mode === 'currency') {\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency: currency ?? 'USD',\n });\n }\n if (mode === 'percentage') {\n return new Intl.NumberFormat(locale, {\n style: 'percent',\n maximumFractionDigits: 4,\n });\n }\n if (mode === 'integer') {\n return new Intl.NumberFormat(locale, { maximumFractionDigits: 0 });\n }\n return new Intl.NumberFormat(locale, { maximumFractionDigits: 10 });\n })();\n\n const format = (value: number): string => {\n if (!Number.isFinite(value)) return '';\n return displayFormatter.format(value);\n };\n\n const parse = (text: string): number => {\n if (!text) return NaN;\n const normalized = normalizeDigits(text);\n const trimmed = normalized.trim();\n const hasMinus =\n trimmed.startsWith('-') || trimmed.startsWith('\\u2212');\n\n let cleaned = '';\n for (const ch of normalized) {\n if (ch >= '0' && ch <= '9') {\n cleaned += ch;\n } else if (ch === decimalSeparator) {\n cleaned += '.';\n }\n }\n if (!cleaned || cleaned === '.') return NaN;\n\n let n = Number(cleaned);\n if (!Number.isFinite(n)) return NaN;\n if (hasMinus) n = -n;\n if (mode === 'percentage') n = n / 100;\n return n;\n };\n\n let inputMode: 'numeric' | 'decimal' = 'decimal';\n if (mode === 'integer') {\n inputMode = 'numeric';\n } else if (mode === 'currency') {\n try {\n const { maximumFractionDigits } = new Intl.NumberFormat(locale, {\n style: 'currency',\n currency: currency ?? 'USD',\n }).resolvedOptions();\n inputMode = maximumFractionDigits === 0 ? 'numeric' : 'decimal';\n } catch {\n inputMode = 'decimal';\n }\n }\n\n return {\n format,\n parse,\n decimalSeparator,\n groupingSeparator,\n inputMode,\n };\n }, [locale, mode, currency]);\n}\n","import {\n forwardRef,\n useCallback,\n useEffect,\n useRef,\n useState,\n type ChangeEvent,\n type FocusEvent,\n type InputHTMLAttributes,\n type KeyboardEvent,\n type MouseEvent,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { ChevronDown, ChevronUp } from 'lucide-react';\nimport { useFormField } from '../form-field/form-field-context';\nimport {\n useLocaleNumber,\n type NumberInputMode,\n} from './use-locale-number';\n\nconst numberInputVariants = cva(\n [\n 'ds:flex ds:items-center ds:w-full ds:rounded-[var(--radius-sm)]',\n 'ds:border ds:bg-background ds:text-foreground',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:focus-within:outline-[length:var(--focus-ring-width)] ds:focus-within:outline-solid',\n 'ds:focus-within:outline-ring ds:focus-within:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:has-[:disabled]:cursor-not-allowed ds:has-[:disabled]:opacity-50',\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'ds:h-8 ds:text-[var(--font-size-sm)]',\n md: 'ds:h-[var(--min-target-size)] ds:text-[var(--font-size-base)]',\n lg: 'ds:h-12 ds:text-[var(--font-size-lg)]',\n },\n tone: {\n default: 'ds:border-border',\n error: 'ds:border-destructive ds:focus-within:outline-destructive',\n },\n },\n defaultVariants: { size: 'md', tone: 'default' },\n },\n);\n\nconst spinnerButton = [\n 'inline-flex items-center justify-center',\n 'h-full shrink-0',\n 'text-muted-foreground hover:text-foreground',\n 'transition-colors duration-[var(--animation-duration)] motion-reduce:transition-none',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n].join(' ');\n\nexport type { NumberInputMode };\n\nexport interface NumberInputProps\n extends Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'type' | 'onChange' | 'value' | 'defaultValue' | 'size'\n >,\n VariantProps<typeof numberInputVariants> {\n /** Current numeric value (controlled). */\n value?: number | null;\n /** Initial value (uncontrolled). */\n defaultValue?: number;\n /** Fires with the parsed number (not a string). `null` when the field is empty. */\n onChange?: (value: number | null) => void;\n /** Minimum allowed value. Maps to `aria-valuemin`. */\n min?: number;\n /** Maximum allowed value. Maps to `aria-valuemax`. */\n max?: number;\n /** Increment step. Defaults to `1`. */\n step?: number;\n /** Display/parse mode. Defaults to `'integer'`. */\n mode?: NumberInputMode;\n /** ISO 4217 currency code, required when `mode='currency'`. */\n currency?: string;\n /** BCP 47 locale. Defaults to `navigator.language` or `'en-US'`. */\n locale?: string;\n /** Size variant. */\n size?: 'sm' | 'md' | 'lg';\n /** Additional class names on the wrapper. */\n className?: string;\n}\n\nconst resolveDefaultLocale = (): string => {\n if (typeof navigator !== 'undefined' && navigator.language) {\n return navigator.language;\n }\n return 'en-US';\n};\n\nfunction decimalPlaces(n: number): number {\n if (!Number.isFinite(n)) return 0;\n const s = String(n);\n const dot = s.indexOf('.');\n if (dot === -1) return 0;\n return s.length - dot - 1;\n}\n\nfunction roundToStep(value: number, step: number): number {\n if (step <= 0 || !Number.isFinite(step)) return value;\n const precision = decimalPlaces(step);\n const factor = 10 ** precision;\n return Math.round(value * factor) / factor;\n}\n\nexport const NumberInput = forwardRef<HTMLInputElement, NumberInputProps>(\n (\n {\n value,\n defaultValue,\n onChange,\n min,\n max,\n step = 1,\n mode = 'integer',\n currency,\n locale,\n size = 'md',\n tone,\n className,\n id,\n disabled,\n onFocus,\n onBlur,\n onKeyDown,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n const ctx = useFormField();\n const inputId = id ?? ctx.id;\n const effectiveDisabled = Boolean(ctx.disabled || disabled);\n\n const resolvedLocale = locale ?? resolveDefaultLocale();\n const localeNumber = useLocaleNumber(resolvedLocale, mode, currency);\n const { decimalSeparator, format: localeFormat, parse: localeParse } =\n localeNumber;\n\n const isControlled = value !== undefined;\n const [internalValue, setInternalValue] = useState<number | null>(\n defaultValue ?? null,\n );\n const currentValue: number | null = isControlled\n ? (value ?? null)\n : internalValue;\n\n const formatForEdit = useCallback(\n (n: number): string => {\n const displayed = mode === 'percentage' ? n * 100 : n;\n const raw = Number.isInteger(displayed)\n ? String(displayed)\n : displayed.toString();\n return raw.replace('.', decimalSeparator);\n },\n [mode, decimalSeparator],\n );\n\n const formatCurrent = useCallback(\n (n: number | null | undefined): string =>\n n === null || n === undefined || Number.isNaN(n) ? '' : localeFormat(n),\n [localeFormat],\n );\n\n const [inputText, setInputText] = useState<string>(() =>\n formatCurrent(currentValue),\n );\n const isFocusedRef = useRef(false);\n const [crossedBounds, setCrossedBounds] = useState(false);\n\n useEffect(() => {\n if (!isFocusedRef.current) {\n setInputText(formatCurrent(currentValue));\n }\n }, [currentValue, formatCurrent]);\n\n const computedInvalid =\n crossedBounds ||\n (currentValue !== null &&\n ((min !== undefined && currentValue < min) ||\n (max !== undefined && currentValue > max)));\n const ariaInvalid = ctx.invalid || computedInvalid;\n const effectiveTone: 'default' | 'error' = ariaInvalid\n ? 'error'\n : tone ?? 'default';\n\n const commitValue = (next: number | null) => {\n if (!isControlled) setInternalValue(next);\n onChange?.(next);\n };\n\n const applyDelta = (multiplier: number) => {\n const base = currentValue ?? 0;\n let next = base + step * multiplier;\n if (min !== undefined) next = Math.max(min, next);\n if (max !== undefined) next = Math.min(max, next);\n next = roundToStep(next, step);\n commitValue(next);\n setCrossedBounds(false);\n setInputText(\n isFocusedRef.current ? formatForEdit(next) : formatCurrent(next),\n );\n };\n\n const jumpTo = (target: number) => {\n commitValue(target);\n setCrossedBounds(false);\n setInputText(\n isFocusedRef.current ? formatForEdit(target) : formatCurrent(target),\n );\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n onKeyDown?.(event);\n if (event.defaultPrevented) return;\n if (effectiveDisabled) return;\n\n const { key, shiftKey } = event;\n if (key === 'ArrowUp') {\n event.preventDefault();\n applyDelta(shiftKey ? 10 : 1);\n } else if (key === 'ArrowDown') {\n event.preventDefault();\n applyDelta(shiftKey ? -10 : -1);\n } else if (key === 'PageUp') {\n event.preventDefault();\n applyDelta(100);\n } else if (key === 'PageDown') {\n event.preventDefault();\n applyDelta(-100);\n } else if (key === 'Home' && min !== undefined) {\n event.preventDefault();\n jumpTo(min);\n } else if (key === 'End' && max !== undefined) {\n event.preventDefault();\n jumpTo(max);\n }\n };\n\n const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n const text = event.target.value;\n setInputText(text);\n if (text.trim() === '') {\n commitValue(null);\n setCrossedBounds(false);\n return;\n }\n const parsed = localeParse(text);\n if (!Number.isNaN(parsed)) {\n commitValue(parsed);\n }\n };\n\n const handleFocus = (event: FocusEvent<HTMLInputElement>) => {\n onFocus?.(event);\n isFocusedRef.current = true;\n if (currentValue !== null && currentValue !== undefined) {\n setInputText(formatForEdit(currentValue));\n }\n };\n\n const handleBlur = (event: FocusEvent<HTMLInputElement>) => {\n onBlur?.(event);\n isFocusedRef.current = false;\n\n if (inputText.trim() === '') {\n commitValue(null);\n setCrossedBounds(false);\n setInputText('');\n return;\n }\n const parsed = localeParse(inputText);\n if (Number.isNaN(parsed)) {\n setInputText(formatCurrent(currentValue));\n return;\n }\n const crossed =\n (min !== undefined && parsed < min) ||\n (max !== undefined && parsed > max);\n setCrossedBounds(crossed);\n commitValue(parsed);\n setInputText(formatCurrent(parsed));\n };\n\n const preventButtonBlur = (event: MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n };\n\n const handleIncrement = () => applyDelta(1);\n const handleDecrement = () => applyDelta(-1);\n\n const decrementDisabled =\n effectiveDisabled ||\n (min !== undefined && currentValue !== null && currentValue <= min);\n const incrementDisabled =\n effectiveDisabled ||\n (max !== undefined && currentValue !== null && currentValue >= max);\n\n const valueNow = currentValue ?? undefined;\n const valueTextNeeded =\n (mode === 'currency' || mode === 'percentage') && currentValue !== null;\n const valueText =\n valueTextNeeded && currentValue !== null\n ? localeFormat(currentValue)\n : undefined;\n\n const patternAttr =\n localeNumber.inputMode === 'numeric' ? '[0-9]*' : undefined;\n\n return (\n <div\n className={numberInputVariants({\n size,\n tone: effectiveTone,\n className,\n })}\n data-mode={mode}\n >\n <button\n type=\"button\"\n tabIndex={-1}\n aria-label={t('ui.inputs.number.decrement', 'Decrement')}\n onClick={handleDecrement}\n onMouseDown={preventButtonBlur}\n disabled={decrementDisabled}\n className={`${spinnerButton} ds:ps-2 ds:pe-1`}\n >\n <ChevronDown aria-hidden=\"true\" className=\"ds:size-4\" />\n </button>\n <input\n ref={ref}\n id={inputId}\n type=\"text\"\n role=\"spinbutton\"\n inputMode={localeNumber.inputMode}\n pattern={patternAttr}\n autoComplete=\"off\"\n value={inputText}\n disabled={effectiveDisabled}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-valuenow={valueNow}\n aria-valuetext={valueText}\n aria-invalid={ariaInvalid || undefined}\n aria-required={ctx.required || undefined}\n aria-describedby={ctx.describedBy || undefined}\n onChange={handleInputChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n className=\"ds:flex-1 ds:w-full ds:min-w-0 ds:bg-transparent ds:outline-none ds:ps-2 ds:pe-2 ds:text-start ds:tabular-nums ds:disabled:cursor-not-allowed\"\n {...rest}\n />\n <button\n type=\"button\"\n tabIndex={-1}\n aria-label={t('ui.inputs.number.increment', 'Increment')}\n onClick={handleIncrement}\n onMouseDown={preventButtonBlur}\n disabled={incrementDisabled}\n className={`${spinnerButton} ds:ps-1 ds:pe-2`}\n >\n <ChevronUp aria-hidden=\"true\" className=\"ds:size-4\" />\n </button>\n </div>\n );\n },\n);\n\nNumberInput.displayName = 'NumberInput';\n"],"names":["normalizeDigits","text","result","ch","code","useLocaleNumber","locale","mode","currency","useMemo","parts","decimalSeparator","_a","p","groupingSeparator","_b","displayFormatter","format","value","parse","normalized","trimmed","hasMinus","cleaned","n","inputMode","maximumFractionDigits","numberInputVariants","cva","spinnerButton","resolveDefaultLocale","decimalPlaces","s","dot","roundToStep","step","factor","NumberInput","forwardRef","defaultValue","onChange","min","max","size","tone","className","id","disabled","onFocus","onBlur","onKeyDown","rest","ref","t","useTranslation","ctx","useFormField","inputId","effectiveDisabled","resolvedLocale","localeNumber","localeFormat","localeParse","isControlled","internalValue","setInternalValue","useState","currentValue","formatForEdit","useCallback","displayed","formatCurrent","inputText","setInputText","isFocusedRef","useRef","crossedBounds","setCrossedBounds","useEffect","computedInvalid","ariaInvalid","effectiveTone","commitValue","next","applyDelta","multiplier","jumpTo","target","handleKeyDown","event","key","shiftKey","handleInputChange","parsed","handleFocus","handleBlur","crossed","preventButtonBlur","handleIncrement","handleDecrement","decrementDisabled","incrementDisabled","valueNow","valueText","patternAttr","jsxs","jsx","ChevronDown","ChevronUp"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"otp-input-C9R9sC74.js","sources":["../../src/components/otp-input/otp-input.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n type ChangeEvent,\n type ClipboardEvent,\n type FocusEvent,\n type KeyboardEvent,\n} from 'react';\nimport { cva } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { useFormField } from '../form-field/form-field-context';\n\nconst wrapperVariants = cva('ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]');\n\nconst boxVariants = cva(\n [\n 'ds:w-[var(--min-target-size)] ds:h-[var(--min-target-size)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:border ds:bg-background ds:text-foreground ds:text-center ds:font-medium ds:text-[var(--font-size-lg)]',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] 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-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:disabled:cursor-not-allowed ds:disabled:opacity-50',\n ].join(' '),\n {\n variants: {\n tone: {\n default: 'ds:border-border',\n error: 'ds:border-destructive',\n },\n },\n defaultVariants: { tone: 'default' },\n },\n);\n\nexport interface OTPInputProps {\n length?: 4 | 6 | 8;\n value?: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n onComplete?: (code: string) => void;\n disabled?: boolean;\n error?: boolean;\n label?: string;\n className?: string;\n}\n\nfunction normaliseDigits(str: string): string {\n return str\n .replace(/[\\u0660-\\u0669]/g, (c) => String(c.charCodeAt(0) - 0x0660))\n .replace(/[\\u06F0-\\u06F9]/g, (c) => String(c.charCodeAt(0) - 0x06f0));\n}\n\nfunction packValue(value: string, length: number): string {\n return normaliseDigits(value).replace(/\\D/g, '').slice(0, length);\n}\n\nfunction valueToArray(value: string, length: number): string[] {\n const packed = packValue(value, length);\n const arr = new Array<string>(length).fill('');\n for (let i = 0; i < packed.length; i += 1) {\n arr[i] = packed[i];\n }\n return arr;\n}\n\nexport const OTPInput = forwardRef<HTMLDivElement, OTPInputProps>(\n (\n {\n length = 6,\n value,\n defaultValue,\n onChange,\n onComplete,\n disabled,\n error,\n label,\n className,\n },\n ref,\n ) => {\n const { t } = useTranslation();\n const ctx = useFormField();\n const generatedLabelId = useId();\n const labelId = label ? generatedLabelId : undefined;\n\n const isControlled = value !== undefined;\n const [internalValue, setInternalValue] = useState<string>(() =>\n packValue(defaultValue ?? '', length),\n );\n const currentValue = packValue(isControlled ? value : internalValue, length);\n const digits = valueToArray(currentValue, length);\n\n const effectiveDisabled = ctx.disabled || Boolean(disabled);\n const effectiveError = ctx.invalid || Boolean(error);\n const effectiveTone = effectiveError ? 'error' : 'default';\n\n const inputsRef = useRef<Array<HTMLInputElement | null>>([]);\n const completedRef = useRef(currentValue.length === length);\n const valueRef = useRef(currentValue);\n valueRef.current = currentValue;\n\n const computeInitialIndex = () => {\n const firstEmpty = currentValue.length;\n if (firstEmpty >= length) return length - 1;\n return firstEmpty;\n };\n const [activeIndex, setActiveIndex] = useState<number>(computeInitialIndex);\n\n useEffect(() => {\n if (activeIndex >= length) setActiveIndex(length - 1);\n }, [activeIndex, length]);\n\n const focusBox = useCallback(\n (index: number) => {\n const clamped = Math.max(0, Math.min(length - 1, index));\n setActiveIndex(clamped);\n const node = inputsRef.current[clamped];\n if (node) {\n node.focus();\n node.select();\n }\n },\n [length],\n );\n\n const commit = useCallback(\n (next: string) => {\n const packed = packValue(next, length);\n if (!isControlled) setInternalValue(packed);\n valueRef.current = packed;\n onChange?.(packed);\n if (packed.length === length) {\n if (!completedRef.current) {\n completedRef.current = true;\n onComplete?.(packed);\n }\n } else {\n completedRef.current = false;\n }\n },\n [isControlled, length, onChange, onComplete],\n );\n\n const handleChange =\n (index: number) => (event: ChangeEvent<HTMLInputElement>) => {\n const raw = event.target.value;\n const norm = normaliseDigits(raw).replace(/\\D/g, '');\n const current = valueRef.current;\n\n if (norm.length === 0) {\n if (raw === '' && index < current.length) {\n const newValue = current.slice(0, index) + current.slice(index + 1);\n commit(newValue);\n }\n return;\n }\n\n const before = current.slice(0, index);\n const after = current.slice(index + norm.length);\n const newValue = (before + norm + after).slice(0, length);\n commit(newValue);\n\n const focusTarget = Math.min(index + norm.length, length - 1);\n focusBox(focusTarget);\n };\n\n const handleKeyDown =\n (index: number) => (event: KeyboardEvent<HTMLInputElement>) => {\n const current = valueRef.current;\n if (event.key === 'Backspace') {\n if (current[index]) {\n event.preventDefault();\n const newValue = current.slice(0, index) + current.slice(index + 1);\n commit(newValue);\n return;\n }\n if (index > 0) {\n event.preventDefault();\n const newValue = current.slice(0, index - 1) + current.slice(index);\n commit(newValue);\n focusBox(index - 1);\n }\n return;\n }\n if (event.key === 'ArrowLeft') {\n event.preventDefault();\n if (index > 0) focusBox(index - 1);\n return;\n }\n if (event.key === 'ArrowRight') {\n event.preventDefault();\n if (index < length - 1) focusBox(index + 1);\n return;\n }\n if (event.key === 'Home') {\n event.preventDefault();\n focusBox(0);\n return;\n }\n if (event.key === 'End') {\n event.preventDefault();\n focusBox(length - 1);\n }\n };\n\n const handlePaste =\n (index: number) => (event: ClipboardEvent<HTMLInputElement>) => {\n const text = event.clipboardData.getData('text');\n const stripped = text.replace(/\\s+/g, '');\n const norm = normaliseDigits(stripped);\n if (!/^[0-9]+$/.test(norm)) return;\n event.preventDefault();\n const current = valueRef.current;\n const before = current.slice(0, index);\n const after = current.slice(index + norm.length);\n const newValue = (before + norm + after).slice(0, length);\n commit(newValue);\n const focusTarget = Math.min(index + norm.length, length - 1);\n focusBox(focusTarget);\n };\n\n const handleFocus =\n (index: number) => (event: FocusEvent<HTMLInputElement>) => {\n setActiveIndex(index);\n event.currentTarget.select();\n };\n\n const baseId = ctx.id;\n\n return (\n <div className={wrapperVariants({ className })}>\n {label ? (\n <label\n id={labelId}\n htmlFor={`${baseId}-0`}\n className=\"type-label ds:text-foreground\"\n >\n {label}\n </label>\n ) : null}\n <div\n ref={ref}\n role=\"group\"\n dir=\"ltr\"\n aria-labelledby={labelId}\n aria-invalid={effectiveError || undefined}\n aria-describedby={ctx.describedBy || undefined}\n aria-disabled={effectiveDisabled || undefined}\n className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-sm)]\"\n >\n {digits.map((digit, index) => {\n const isTabbable = !effectiveDisabled && index === activeIndex;\n return (\n <input\n key={index}\n ref={(node) => {\n inputsRef.current[index] = node;\n }}\n id={`${baseId}-${index}`}\n type=\"text\"\n inputMode=\"numeric\"\n pattern=\"[0-9]*\"\n autoComplete={index === 0 ? 'one-time-code' : 'off'}\n maxLength={1}\n value={digit}\n disabled={effectiveDisabled}\n tabIndex={isTabbable ? 0 : -1}\n aria-label={t('ui.inputs.otp.digitLabel', {\n current: index + 1,\n total: length,\n })}\n onChange={handleChange(index)}\n onKeyDown={handleKeyDown(index)}\n onPaste={handlePaste(index)}\n onFocus={handleFocus(index)}\n className={boxVariants({ tone: effectiveTone })}\n />\n );\n })}\n </div>\n </div>\n );\n },\n);\n\nOTPInput.displayName = 'OTPInput';\n"],"names":["wrapperVariants","cva","boxVariants","normaliseDigits","str","c","packValue","value","length","valueToArray","packed","arr","i","OTPInput","forwardRef","defaultValue","onChange","onComplete","disabled","error","label","className","ref","t","useTranslation","ctx","useFormField","generatedLabelId","useId","labelId","isControlled","internalValue","setInternalValue","useState","currentValue","digits","effectiveDisabled","effectiveError","effectiveTone","inputsRef","useRef","completedRef","valueRef","computeInitialIndex","firstEmpty","activeIndex","setActiveIndex","useEffect","focusBox","useCallback","index","clamped","node","commit","next","handleChange","event","raw","norm","current","newValue","before","after","focusTarget","handleKeyDown","handlePaste","stripped","handleFocus","baseId","jsx","digit","isTabbable"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pagination.agent-D75FB6XP.js","sources":["../../src/components/pagination/pagination.tsx","../../src/components/pagination/pagination.agent.ts"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useState,\n type ComponentPropsWithoutRef,\n} from 'react';\nimport * as RadixSelect from '@radix-ui/react-select';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport {\n ChevronLeft,\n ChevronRight,\n ChevronsLeft,\n ChevronsRight,\n MoreHorizontal,\n Check,\n} from 'lucide-react';\n\n/* -------------------------------------------------------------------- */\n/* Sizes */\n/* -------------------------------------------------------------------- */\n\ntype PaginationSize = 'sm' | 'md' | 'lg';\n\nconst buttonBase = [\n 'inline-flex items-center justify-center',\n 'rounded-[var(--radius-sm)]',\n 'border border-transparent',\n 'font-[var(--font-weight-medium)]',\n 'text-[var(--foreground)]',\n 'select-none',\n 'transition-colors duration-[var(--animation-duration)] motion-reduce:transition-none',\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 'disabled:cursor-not-allowed disabled:opacity-50',\n 'aria-disabled:cursor-not-allowed aria-disabled:opacity-50',\n].join(' ');\n\nconst paginationButtonVariants = cva(buttonBase, {\n variants: {\n size: {\n sm: 'ds:min-w-[var(--min-target-size)] ds:min-h-[var(--min-target-size)] ds:text-[var(--font-size-sm)] ds:ps-[var(--spacing-xs)] ds:pe-[var(--spacing-xs)]',\n md: 'ds:min-w-[var(--min-target-size)] ds:min-h-[var(--min-target-size)] ds:text-[var(--font-size-base)] ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)]',\n lg: 'ds:min-w-[3rem] ds:min-h-[3rem] ds:text-[var(--font-size-lg)] ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)]',\n },\n active: {\n true: 'ds:bg-[var(--primary)] ds:text-[var(--primary-foreground)] ds:font-[var(--font-weight-bold)] ds:outline ds:outline-1 ds:outline-[var(--primary)] ds:hover:bg-[var(--primary-hover)]',\n false: '',\n },\n },\n defaultVariants: { size: 'md', active: false },\n});\n\n/* -------------------------------------------------------------------- */\n/* Range helper */\n/* -------------------------------------------------------------------- */\n\ntype PageToken = number | 'ellipsis-start' | 'ellipsis-end';\n\nfunction range(start: number, end: number): number[] {\n const out: number[] = [];\n for (let i = start; i <= end; i++) out.push(i);\n return out;\n}\n\nexport function buildPageRange(\n current: number,\n totalPages: number,\n siblingCount = 1,\n boundaryCount = 1,\n): PageToken[] {\n if (totalPages <= 0) return [];\n // Clamp to sensible minima so extreme consumer inputs don't surface\n // ranges like `[1, 3, 5]` with no ellipsis between boundaries.\n siblingCount = Math.max(0, siblingCount);\n boundaryCount = Math.max(1, boundaryCount);\n const totalNumbers = boundaryCount * 2 + siblingCount * 2 + 3;\n if (totalNumbers >= totalPages) return range(1, totalPages);\n\n const startPages = range(1, boundaryCount);\n const endPages = range(totalPages - boundaryCount + 1, totalPages);\n\n const siblingStart = Math.max(\n Math.min(current - siblingCount, totalPages - boundaryCount - siblingCount * 2 - 1),\n boundaryCount + 2,\n );\n const siblingEnd = Math.min(\n Math.max(current + siblingCount, boundaryCount + siblingCount * 2 + 2),\n endPages[0] - 2,\n );\n\n const tokens: PageToken[] = [...startPages];\n\n if (siblingStart > boundaryCount + 2) tokens.push('ellipsis-start');\n else if (boundaryCount + 1 < totalPages - boundaryCount) tokens.push(boundaryCount + 1);\n\n tokens.push(...range(siblingStart, siblingEnd));\n\n if (siblingEnd < totalPages - boundaryCount - 1) tokens.push('ellipsis-end');\n else if (totalPages - boundaryCount > boundaryCount) tokens.push(totalPages - boundaryCount);\n\n tokens.push(...endPages);\n return tokens;\n}\n\n/* -------------------------------------------------------------------- */\n/* Root */\n/* -------------------------------------------------------------------- */\n\nexport interface PaginationProps extends ComponentPropsWithoutRef<'nav'> {\n /** Total number of pages. */\n totalPages: number;\n /** Controlled current page (1-indexed). */\n page?: number;\n /** Default current page for uncontrolled use. */\n defaultPage?: number;\n /** Fires when the current page changes. */\n onPageChange?: (page: number) => void;\n /** Siblings shown on either side of the active page. @default 1 */\n siblingCount?: number;\n /** Boundary pages kept at each end. @default 1 */\n boundaryCount?: number;\n /** Visual size. @default 'md' */\n size?: PaginationSize;\n /** Show \"first\"/\"last\" chevrons alongside prev/next. @default false */\n showEndpoints?: boolean;\n /** Horizontal alignment of the pagination within its container. @default 'center' */\n align?: 'start' | 'center' | 'end';\n /** Optional page-size select config. */\n pageSize?: {\n value: number;\n options?: number[];\n onChange: (size: number) => void;\n };\n /** Use `Intl.NumberFormat` for page numbers (Arabic-Indic digits, etc.). */\n useLocaleDigits?: boolean;\n /** Locale override for digit formatting. */\n locale?: string;\n}\n\nconst Pagination = forwardRef<HTMLElement, PaginationProps>(\n (\n {\n totalPages,\n page: controlledPage,\n defaultPage = 1,\n onPageChange,\n siblingCount = 1,\n boundaryCount = 1,\n size = 'md',\n showEndpoints = false,\n align = 'center',\n pageSize,\n useLocaleDigits = false,\n locale,\n className,\n ...rest\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation();\n\n const isControlled = controlledPage !== undefined;\n const [uncontrolledPage, setUncontrolledPage] = useState(defaultPage);\n const currentPage = isControlled ? controlledPage! : uncontrolledPage;\n\n useEffect(() => {\n if (isControlled && defaultPage !== 1) {\n // eslint-disable-next-line no-console\n console.warn(\n '[Pagination] Both `page` and `defaultPage` were supplied. The `page` prop wins; remove `defaultPage` for controlled usage.',\n );\n }\n }, [isControlled, defaultPage]);\n\n const handleChange = useCallback(\n (next: number) => {\n const clamped = Math.min(Math.max(next, 1), Math.max(1, totalPages));\n if (!isControlled) setUncontrolledPage(clamped);\n onPageChange?.(clamped);\n },\n [isControlled, onPageChange, totalPages],\n );\n\n const formatNumber = useCallback(\n (n: number) => {\n if (!useLocaleDigits) return String(n);\n try {\n return new Intl.NumberFormat(locale ?? i18n.language).format(n);\n } catch {\n return String(n);\n }\n },\n [i18n.language, locale, useLocaleDigits],\n );\n\n const tokens = useMemo(\n () => buildPageRange(currentPage, totalPages, siblingCount, boundaryCount),\n [currentPage, totalPages, siblingCount, boundaryCount],\n );\n\n const atFirst = currentPage <= 1;\n const atLast = currentPage >= totalPages;\n\n const justifyClass =\n align === 'start'\n ? 'justify-start'\n : align === 'end'\n ? 'justify-end'\n : 'justify-center';\n\n return (\n <nav\n ref={ref}\n aria-label={t('ui.navigation.pagination.label')}\n className={[\n 'ds:flex ds:items-center',\n justifyClass,\n 'ds:gap-[var(--spacing-sm)]',\n 'ds:flex-wrap',\n className ?? '',\n ]\n .filter(Boolean)\n .join(' ')}\n {...rest}\n >\n <PaginationList size={size}>\n {showEndpoints ? (\n <PaginationItem>\n <PaginationEndpoint\n type=\"first\"\n size={size}\n disabled={atFirst}\n onClick={() => handleChange(1)}\n />\n </PaginationItem>\n ) : null}\n <PaginationItem>\n <PaginationPrevious\n size={size}\n disabled={atFirst}\n onClick={() => handleChange(currentPage - 1)}\n />\n </PaginationItem>\n {tokens.map((token, i) => {\n if (token === 'ellipsis-start' || token === 'ellipsis-end') {\n return (\n <PaginationItem key={`e-${i}`}>\n <PaginationEllipsis />\n </PaginationItem>\n );\n }\n return (\n <PaginationItem key={`p-${token}`}>\n <PaginationLink\n size={size}\n isActive={token === currentPage}\n aria-label={t('ui.navigation.pagination.pageN', { n: token })}\n onClick={() => handleChange(token)}\n >\n {formatNumber(token)}\n </PaginationLink>\n </PaginationItem>\n );\n })}\n <PaginationItem>\n <PaginationNext\n size={size}\n disabled={atLast}\n onClick={() => handleChange(currentPage + 1)}\n />\n </PaginationItem>\n {showEndpoints ? (\n <PaginationItem>\n <PaginationEndpoint\n type=\"last\"\n size={size}\n disabled={atLast}\n onClick={() => handleChange(totalPages)}\n />\n </PaginationItem>\n ) : null}\n </PaginationList>\n {pageSize ? (\n <PageSizeSelect\n size={size}\n value={pageSize.value}\n options={pageSize.options ?? [10, 25, 50, 100]}\n onChange={pageSize.onChange}\n formatNumber={formatNumber}\n />\n ) : null}\n </nav>\n );\n },\n);\nPagination.displayName = 'Pagination';\n\n/* -------------------------------------------------------------------- */\n/* List + item */\n/* -------------------------------------------------------------------- */\n\nexport interface PaginationListProps extends ComponentPropsWithoutRef<'ul'> {\n size?: PaginationSize;\n}\n\nconst PaginationList = forwardRef<HTMLUListElement, PaginationListProps>(\n ({ children, className, ...rest }, ref) => (\n <ul\n ref={ref}\n className={[\n 'ds:flex ds:items-center',\n 'ds:gap-[var(--spacing-xs)]',\n 'ds:m-0 ds:ps-0',\n 'ds:list-none',\n className ?? '',\n ]\n .filter(Boolean)\n .join(' ')}\n {...rest}\n >\n {children}\n </ul>\n ),\n);\nPaginationList.displayName = 'PaginationList';\n\nexport interface PaginationItemProps extends ComponentPropsWithoutRef<'li'> {}\n\nconst PaginationItem = forwardRef<HTMLLIElement, PaginationItemProps>(\n ({ children, className, ...rest }, ref) => (\n <li ref={ref} className={className} {...rest}>\n {children}\n </li>\n ),\n);\nPaginationItem.displayName = 'PaginationItem';\n\n/* -------------------------------------------------------------------- */\n/* Link */\n/* -------------------------------------------------------------------- */\n\nexport interface PaginationLinkProps\n extends Omit<ComponentPropsWithoutRef<'button'>, 'size'>,\n VariantProps<typeof paginationButtonVariants> {\n isActive?: boolean;\n size?: PaginationSize;\n}\n\nconst PaginationLink = forwardRef<HTMLButtonElement, PaginationLinkProps>(\n ({ isActive = false, size = 'md', className, children, ...rest }, ref) => (\n <button\n ref={ref}\n type=\"button\"\n aria-current={isActive ? 'page' : undefined}\n className={paginationButtonVariants({\n size,\n active: isActive,\n className,\n })}\n {...rest}\n >\n {children}\n </button>\n ),\n);\nPaginationLink.displayName = 'PaginationLink';\n\n/* -------------------------------------------------------------------- */\n/* Previous / Next / Endpoint buttons */\n/* -------------------------------------------------------------------- */\n\ninterface NavButtonProps {\n size?: PaginationSize;\n disabled?: boolean;\n onClick?: () => void;\n}\n\nconst chevronClasses = 'size-4 rtl:-scale-x-100';\n\nconst PaginationPrevious = forwardRef<HTMLButtonElement, NavButtonProps>(\n ({ size = 'md', disabled, onClick }, ref) => {\n const { t } = useTranslation();\n const label = t('ui.navigation.pagination.previous');\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label={label}\n aria-disabled={disabled || undefined}\n disabled={disabled}\n onClick={onClick}\n className={paginationButtonVariants({ size })}\n >\n <ChevronLeft aria-hidden=\"true\" className={chevronClasses} />\n </button>\n );\n },\n);\nPaginationPrevious.displayName = 'PaginationPrevious';\n\nconst PaginationNext = forwardRef<HTMLButtonElement, NavButtonProps>(\n ({ size = 'md', disabled, onClick }, ref) => {\n const { t } = useTranslation();\n const label = t('ui.navigation.pagination.next');\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label={label}\n aria-disabled={disabled || undefined}\n disabled={disabled}\n onClick={onClick}\n className={paginationButtonVariants({ size })}\n >\n <ChevronRight aria-hidden=\"true\" className={chevronClasses} />\n </button>\n );\n },\n);\nPaginationNext.displayName = 'PaginationNext';\n\ninterface EndpointProps extends NavButtonProps {\n type: 'first' | 'last';\n}\n\nconst PaginationEndpoint = forwardRef<HTMLButtonElement, EndpointProps>(\n ({ type, size = 'md', disabled, onClick }, ref) => {\n const { t } = useTranslation();\n const label =\n type === 'first'\n ? t('ui.navigation.pagination.first')\n : t('ui.navigation.pagination.last');\n const Icon = type === 'first' ? ChevronsLeft : ChevronsRight;\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label={label}\n aria-disabled={disabled || undefined}\n disabled={disabled}\n onClick={onClick}\n className={paginationButtonVariants({ size })}\n >\n <Icon aria-hidden=\"true\" className={chevronClasses} />\n </button>\n );\n },\n);\nPaginationEndpoint.displayName = 'PaginationEndpoint';\n\n/* -------------------------------------------------------------------- */\n/* Ellipsis */\n/* -------------------------------------------------------------------- */\n\nexport interface PaginationEllipsisProps extends ComponentPropsWithoutRef<'span'> {}\n\nconst PaginationEllipsis = forwardRef<HTMLSpanElement, PaginationEllipsisProps>(\n ({ className, ...rest }, ref) => (\n <span\n ref={ref}\n aria-hidden=\"true\"\n role=\"presentation\"\n className={[\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:text-[var(--muted-foreground)]',\n className ?? '',\n ]\n .filter(Boolean)\n .join(' ')}\n {...rest}\n >\n <MoreHorizontal aria-hidden=\"true\" className=\"ds:size-4\" />\n </span>\n ),\n);\nPaginationEllipsis.displayName = 'PaginationEllipsis';\n\n/* -------------------------------------------------------------------- */\n/* Page-size select */\n/* -------------------------------------------------------------------- */\n\ninterface PageSizeSelectProps {\n size: PaginationSize;\n value: number;\n options: number[];\n onChange: (size: number) => void;\n formatNumber: (n: number) => string;\n}\n\nconst selectTriggerClasses = [\n 'inline-flex items-center justify-between gap-[var(--spacing-xs)]',\n 'rounded-[var(--radius-sm)] border border-[var(--border)] bg-[var(--background)]',\n 'text-[var(--foreground)]',\n 'min-h-[var(--min-target-size)] min-w-[6rem]',\n 'ps-[var(--spacing-sm)] pe-[var(--spacing-sm)]',\n 'text-[var(--font-size-sm)]',\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].join(' ');\n\nconst selectContentClasses = [\n 'z-[var(--z-dropdown)] overflow-hidden',\n 'rounded-[var(--radius-md)] border border-[var(--border)]',\n 'bg-[var(--background)] text-[var(--foreground)]',\n 'shadow-[var(--shadow-lg)]',\n 'animate-in fade-in zoom-in-95 motion-reduce:animate-none',\n].join(' ');\n\nconst selectItemClasses = [\n 'relative flex cursor-pointer items-center',\n 'min-h-[var(--min-target-size)]',\n 'ps-[var(--spacing-xl)] pe-[var(--spacing-sm)]',\n 'rounded-[var(--radius-sm)]',\n 'text-[var(--foreground)] outline-none select-none',\n 'data-[highlighted]:bg-[var(--muted)]/20',\n 'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n].join(' ');\n\nfunction PageSizeSelect({ value, options, onChange, formatNumber }: PageSizeSelectProps) {\n const { t } = useTranslation();\n const labelId = useId();\n return (\n <div className=\"ds:flex ds:items-center ds:gap-[var(--spacing-sm)]\">\n <span\n id={labelId}\n className=\"type-label ds:text-[var(--muted-foreground)]\"\n >\n {t('ui.navigation.pagination.rowsPerPage')}\n </span>\n <RadixSelect.Root\n value={String(value)}\n onValueChange={(v) => onChange(Number(v))}\n >\n <RadixSelect.Trigger\n aria-labelledby={labelId}\n className={selectTriggerClasses}\n >\n <RadixSelect.Value />\n <RadixSelect.Icon asChild>\n <ChevronRight aria-hidden=\"true\" className=\"ds:size-3 ds:rotate-90\" />\n </RadixSelect.Icon>\n </RadixSelect.Trigger>\n <RadixSelect.Portal>\n <RadixSelect.Content className={selectContentClasses} position=\"popper\">\n <RadixSelect.Viewport className=\"ds:p-[var(--spacing-xs)]\">\n {options.map((o) => (\n <RadixSelect.Item\n key={o}\n value={String(o)}\n className={selectItemClasses}\n >\n <RadixSelect.ItemIndicator className=\"ds:absolute ds:inline-flex ds:items-center ds:justify-center ds:start-[var(--spacing-sm)]\">\n <Check aria-hidden=\"true\" className=\"ds:size-3.5\" />\n </RadixSelect.ItemIndicator>\n <RadixSelect.ItemText>{formatNumber(o)}</RadixSelect.ItemText>\n </RadixSelect.Item>\n ))}\n </RadixSelect.Viewport>\n </RadixSelect.Content>\n </RadixSelect.Portal>\n </RadixSelect.Root>\n </div>\n );\n}\n\n/* -------------------------------------------------------------------- */\n/* Exports */\n/* -------------------------------------------------------------------- */\n\nexport {\n Pagination,\n PaginationList,\n PaginationItem,\n PaginationLink,\n PaginationPrevious,\n PaginationNext,\n PaginationEllipsis,\n};\n","import type { AgentAdapter } from '../../agent/types';\n\nexport const paginationAgent: AgentAdapter<unknown> = {\n id: 'pagination',\n capabilities: ['paginate', 'range_navigate'],\n state: {},\n actions: {},\n domHooks: {\n root: { attr: 'data-component', value: 'pagination' },\n },\n};\n"],"names":["buttonBase","paginationButtonVariants","cva","range","start","end","out","i","buildPageRange","current","totalPages","siblingCount","boundaryCount","startPages","endPages","siblingStart","siblingEnd","tokens","Pagination","forwardRef","controlledPage","defaultPage","onPageChange","size","showEndpoints","align","pageSize","useLocaleDigits","locale","className","rest","ref","t","i18n","useTranslation","isControlled","uncontrolledPage","setUncontrolledPage","useState","currentPage","useEffect","handleChange","useCallback","next","clamped","formatNumber","n","useMemo","atFirst","atLast","justifyClass","jsxs","PaginationList","PaginationItem","jsx","PaginationEndpoint","PaginationPrevious","token","PaginationEllipsis","PaginationLink","PaginationNext","PageSizeSelect","children","isActive","chevronClasses","disabled","onClick","label","ChevronLeft","ChevronRight","type","Icon","ChevronsLeft","ChevronsRight","MoreHorizontal","selectTriggerClasses","selectContentClasses","selectItemClasses","value","options","onChange","labelId","useId","RadixSelect","v","o","Check","paginationAgent"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"payment-form-l3j-gA-t.js","sources":["../../src/tokens/themes/bridges/stripe-appearance.ts","../../src/components/payment-form/payment-form.tsx"],"sourcesContent":["import type { Appearance } from '@stripe/stripe-js';\n\n/**\n * Reads the current design-system tokens from a theme-root element and maps\n * them to Stripe Elements' Appearance API. `root` defaults to\n * `document.documentElement` but consumers can pass a scoped theme wrapper\n * (e.g. a modal with its own `.theme-accessible` override) so that Stripe\n * iframes pick up the right token set.\n *\n * Tokens referenced: --primary, --background, --foreground, --muted,\n * --muted-foreground, --border, --destructive, --radius-md, --font-sans,\n * --font-size-base, --spacing-sm, --animation-duration, --focus-ring-width,\n * --ring.\n *\n * No hex / rgb / hsl literals — every value flows from the token layer.\n */\n\nfunction isBrowser(): boolean {\n return typeof document !== 'undefined' && typeof window !== 'undefined';\n}\n\nexport function getStripeAppearance(root?: HTMLElement): Appearance {\n if (!isBrowser()) {\n return { theme: 'stripe' };\n }\n\n const target = root ?? document.documentElement;\n const styles = getComputedStyle(target);\n const read = (token: string) => styles.getPropertyValue(token).trim();\n const isDark = target.classList.contains('theme-dark');\n\n return {\n theme: isDark ? 'night' : 'stripe',\n variables: {\n colorPrimary: read('--primary'),\n colorBackground: read('--background'),\n colorText: read('--foreground'),\n colorDanger: read('--destructive'),\n colorTextSecondary: read('--muted-foreground'),\n colorTextPlaceholder: read('--muted-foreground'),\n borderRadius: read('--radius-md'),\n fontFamily: read('--font-sans'),\n fontSizeBase: read('--font-size-base'),\n // Stripe multiplies spacingUnit throughout every Element; --spacing-sm\n // gives readable density. Keep this in sync with the JSDoc above.\n spacingUnit: read('--spacing-sm'),\n },\n rules: {\n '.Input': {\n backgroundColor: read('--background'),\n border: `1px solid ${read('--border')}`,\n color: read('--foreground'),\n padding: read('--spacing-sm'),\n transition: `border-color ${read('--animation-duration')} ease-out`,\n },\n '.Input:focus': {\n borderColor: read('--primary'),\n boxShadow: `0 0 0 ${read('--focus-ring-width')} ${read('--ring')}`,\n outline: 'none',\n },\n '.Input--invalid': {\n borderColor: read('--destructive'),\n color: read('--foreground'),\n },\n '.Label': {\n color: read('--foreground'),\n fontWeight: read('--font-weight-medium'),\n fontSize: read('--font-size-sm'),\n },\n '.Error': {\n color: read('--destructive'),\n fontSize: read('--font-size-sm'),\n },\n '.Tab': {\n border: `1px solid ${read('--border')}`,\n backgroundColor: read('--background'),\n color: read('--foreground'),\n },\n '.Tab--selected': {\n borderColor: read('--primary'),\n backgroundColor: read('--background'),\n color: read('--primary'),\n },\n },\n };\n}\n\n/**\n * Calls `onChange(getStripeAppearance(root))` whenever the theme root's\n * class list mutates (theme switch) or the user toggles\n * `prefers-color-scheme` / `prefers-reduced-motion`. Returns an\n * unsubscribe function.\n */\nexport function subscribeStripeAppearance(\n onChange: (next: Appearance) => void,\n root?: HTMLElement,\n): () => void {\n if (!isBrowser()) return () => undefined;\n\n const target = root ?? document.documentElement;\n const emit = () => onChange(getStripeAppearance(root));\n\n const observer = new MutationObserver(emit);\n observer.observe(target, {\n attributes: true,\n attributeFilter: ['class', 'dir', 'lang'],\n });\n\n const schemeMql = window.matchMedia('(prefers-color-scheme: dark)');\n const motionMql = window.matchMedia('(prefers-reduced-motion: reduce)');\n schemeMql.addEventListener('change', emit);\n motionMql.addEventListener('change', emit);\n\n return () => {\n observer.disconnect();\n schemeMql.removeEventListener('change', emit);\n motionMql.removeEventListener('change', emit);\n };\n}\n","/* ------------------------------------------------------------------ */\n/* PaymentForm — Stripe Elements wrapper (PCI DSS SAQ-A). */\n/* */\n/* - Library: `@stripe/react-stripe-js` + `@stripe/stripe-js` (see */\n/* `src/docs/08-third-party.mdx §Payments`). Card number, expiry, */\n/* CVC, and postal code all live inside Stripe-hosted iframes on */\n/* `js.stripe.com` — raw PAN never touches our origin, keeping us */\n/* inside PCI DSS SAQ-A scope. */\n/* */\n/* - Theming: the `stripe-appearance` bridge snapshots our tokens into */\n/* Stripe's Appearance API (`variables`, `rules`). A */\n/* `MutationObserver` on `<html class>` re-runs the snapshot when */\n/* the user flips theme so the embedded iframes repaint. */\n/* */\n/* - Security invariants enforced in this file: */\n/* 1. No `<input type=\"tel\" name=\"card\">` anywhere. */\n/* 2. Error strings are sanitised via `stripCardLikeDigits` before */\n/* forwarding to `onError` (replaces any `\\b\\d{4,}\\b` with */\n/* `****`). */\n/* 3. Element change events are never logged; any dev-only logging */\n/* is gated behind `import.meta.env.DEV` — never runs in prod. */\n/* */\n/* TODO: */\n/* - Stripe's `direction: 'rtl'` is not part of the current */\n/* `Appearance` TypeScript type; we rely on CSS mirroring of our */\n/* chrome via logical properties and let Stripe lay out the iframe */\n/* ltr for now. Revisit when @stripe/stripe-js publishes the type. */\n/* - No `<CardNumberElement>` / split-fields story — `PaymentElement` */\n/* handles accordion + card-only modes via its own `layout` option.*/\n/* ------------------------------------------------------------------ */\n\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type FormEvent,\n} from 'react';\nimport { cva } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Spinner } from '../spinner';\nimport { Alert } from '../alert';\nimport {\n loadStripe,\n type Stripe,\n type Appearance,\n type StripeElementLocale,\n} from '@stripe/stripe-js';\nimport {\n Elements,\n PaymentElement,\n AddressElement,\n useElements,\n useStripe,\n} from '@stripe/react-stripe-js';\n\nimport {\n getStripeAppearance,\n subscribeStripeAppearance,\n} from '../../tokens/themes/bridges/stripe-appearance';\n\n/* ------------------------------------------------------------------ */\n/* Public types */\n/* ------------------------------------------------------------------ */\n\nexport type PaymentCurrency = string; // ISO-4217\n\nexport interface PaymentFormProps {\n /** Required — from your server, created via the PaymentIntents API. */\n clientSecret: string;\n /** Stripe publishable key (`pk_test_…` / `pk_live_…`). */\n publishableKey: string;\n /** ISO-4217 currency code (e.g. 'EUR', 'USD', 'JPY'). */\n currency: PaymentCurrency;\n /** Amount in the currency's smallest unit (cents for EUR/USD, yen for JPY). */\n amount: number;\n /** Called with the PaymentIntent id on successful confirmation. */\n onSuccess?: (paymentIntentId: string) => void;\n /** Called with a sanitised error (no PAN digits, no Stripe English strings). */\n onError?: (error: { code: string; translatedMessage: string }) => void;\n /** Show the billing-address collector below the payment fields. */\n billingAddress?: boolean;\n /** Locale override — defaults to the active i18next locale. */\n locale?: string;\n /** Accessible label for the form. */\n ariaLabel?: string;\n /** URL Stripe redirects to when a payment method requires it. */\n returnUrl?: string;\n /** Pre-injected Stripe instance — used by tests + stories to bypass the network. */\n stripePromise?: Promise<Stripe | null> | null;\n className?: string;\n}\n\nexport interface PaymentFormHandle {\n /** Programmatically submit the form (same flow as the Pay button). */\n submit: () => Promise<void>;\n /** Reset the form to its initial state. */\n reset: () => void;\n}\n\n/* ------------------------------------------------------------------ */\n/* Currency helpers */\n/* ------------------------------------------------------------------ */\n\n/**\n * Currencies that Stripe bills in their base unit (no decimals). Source:\n * https://stripe.com/docs/currencies#zero-decimal — list pinned per\n * 08-third-party.mdx.\n */\nconst ZERO_DECIMAL_CURRENCIES = new Set<string>([\n 'BIF',\n 'CLP',\n 'DJF',\n 'GNF',\n 'IDR',\n 'JPY',\n 'KMF',\n 'KRW',\n 'MGA',\n 'PYG',\n 'RWF',\n 'UGX',\n 'VND',\n 'VUV',\n 'XAF',\n 'XOF',\n 'XPF',\n]);\n\nexport function formatPaymentAmount(\n amount: number,\n currency: string,\n locale: string,\n): string {\n const iso = currency.toUpperCase();\n const major = ZERO_DECIMAL_CURRENCIES.has(iso) ? amount : amount / 100;\n try {\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency: iso,\n }).format(major);\n } catch {\n // Invalid locale/currency pair — fall back to a safe format so we\n // never leak raw amount integers into the UI.\n return new Intl.NumberFormat('en', {\n style: 'currency',\n currency: iso,\n }).format(major);\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* Return URL validation */\n/* ------------------------------------------------------------------ */\n\n/**\n * Resolve `returnUrl` against the current origin. Accepts:\n * - absolute URLs on the same origin as `window.location`\n * - relative paths (resolved against the current origin)\n * Rejects (returns `null`):\n * - cross-origin URLs — would leak `payment_intent_client_secret`\n * - `javascript:` / `data:` / `file:` / `blob:` schemes\n * - SSR contexts (no `window`) — the submit path requires a browser\n * anyway, so rejecting here is the safer default.\n * See security-hardening.mdx.\n */\nexport function validateReturnUrl(\n returnUrl: string | undefined,\n): string | null {\n if (returnUrl === undefined) return null;\n const raw = returnUrl.trim();\n if (raw === '') return null;\n if (typeof window === 'undefined') return null;\n try {\n const resolved = new URL(raw, window.location.href);\n const allowedSchemes = new Set(['http:', 'https:']);\n if (!allowedSchemes.has(resolved.protocol)) return null;\n if (resolved.origin !== window.location.origin) return null;\n return resolved.toString();\n } catch {\n return null;\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* Error sanitisation */\n/* ------------------------------------------------------------------ */\n\n/**\n * Replace any run of 4+ consecutive digits with `****`. Called before any\n * error text leaves the wrapper. Defensive: even though Stripe's error\n * strings don't normally contain PANs, a future SDK change could, and we\n * want a hard guarantee that `console` / analytics / Sentry breadcrumbs\n * stay clear of anything that looks like card data.\n */\nexport function stripCardLikeDigits(message: string): string {\n if (!message) return message;\n // Deliberately no word boundaries: a PAN run embedded between word\n // characters (e.g. \"CARD4242424242424242DECLINED\") must still be masked.\n return message.replace(/\\d{4,}/g, '****');\n}\n\n/**\n * Map a Stripe error code (e.g. `card_declined`, `incorrect_number`) to a\n * translation key under `payment.error.*`. Unknown codes fall through to\n * `payment.error.generic`.\n */\nexport function stripeErrorCodeToI18nKey(code: string | undefined): string {\n switch (code) {\n case 'incorrect_number':\n case 'invalid_number':\n return 'payment.error.cardNumber';\n case 'invalid_expiry_month':\n case 'invalid_expiry_year':\n case 'expired_card':\n return 'payment.error.expiry';\n case 'invalid_cvc':\n case 'incorrect_cvc':\n return 'payment.error.cvc';\n case 'incorrect_zip':\n case 'invalid_zip':\n return 'payment.error.postalCode';\n case 'card_declined':\n case 'do_not_honor':\n case 'generic_decline':\n return 'payment.error.declined';\n case 'network_error':\n case 'api_connection_error':\n return 'payment.error.network';\n default:\n return 'payment.error.generic';\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst formVariants = cva(\n [\n 'ds:payment-form-alfadocs ds:flex ds:flex-col',\n 'ds:gap-[var(--spacing-md)]',\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-md)]',\n 'ds:aria-disabled:opacity-[var(--opacity-50)] ds:aria-disabled:cursor-not-allowed',\n ].join(' '),\n);\n\nconst fieldLabelVariants = cva(\n ['ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]'].join(' '),\n);\n\nconst labelTextVariants = cva(\n [\n 'type-label',\n 'ds:text-[var(--foreground)]',\n ].join(' '),\n);\n\nconst amountSummaryVariants = cva(\n [\n 'ds:flex ds:items-baseline ds:justify-between',\n 'ds:gap-[var(--spacing-sm)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)]',\n 'ds:pt-[var(--spacing-xs)] ds:pb-[var(--spacing-xs)]',\n 'ds:bg-[var(--muted)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:text-[var(--foreground)]',\n ].join(' '),\n);\n\nconst submitButtonVariants = cva(\n [\n 'ds:inline-flex ds:items-center ds:justify-center ds:gap-[var(--spacing-xs)]',\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-base)] 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 'ds:aria-busy:cursor-wait',\n ].join(' '),\n);\n\n/* ------------------------------------------------------------------ */\n/* Inner form — lives inside the <Elements> provider */\n/* ------------------------------------------------------------------ */\n\ninterface InnerPaymentFormProps {\n amount: number;\n currency: string;\n locale: string;\n billingAddress: boolean;\n returnUrl: string | undefined;\n onSuccess: PaymentFormProps['onSuccess'];\n onError: PaymentFormProps['onError'];\n}\n\nfunction InnerPaymentForm(props: InnerPaymentFormProps): JSX.Element {\n const {\n amount,\n currency,\n locale,\n billingAddress,\n returnUrl,\n onSuccess,\n onError,\n } = props;\n\n const { t } = useTranslation();\n const stripe = useStripe();\n const elements = useElements();\n\n const rawId = useId();\n const idSafe = useMemo(\n () => `pay-${rawId.replace(/[^a-zA-Z0-9-_]/g, '')}`,\n [rawId],\n );\n const paymentFieldId = `${idSafe}-payment`;\n const addressFieldId = `${idSafe}-address`;\n const errorId = `${idSafe}-error`;\n\n const [processing, setProcessing] = useState(false);\n const [elementComplete, setElementComplete] = useState(false);\n const [errorKey, setErrorKey] = useState<string | null>(null);\n const [errorMessage, setErrorMessage] = useState<string>('');\n\n const onSuccessRef = useRef(onSuccess);\n const onErrorRef = useRef(onError);\n useEffect(() => {\n onSuccessRef.current = onSuccess;\n onErrorRef.current = onError;\n }, [onSuccess, onError]);\n\n const handleSubmit = useCallback(\n async (event?: FormEvent<HTMLFormElement>): Promise<void> => {\n if (event) event.preventDefault();\n if (!stripe || !elements) return;\n if (processing) return;\n\n setProcessing(true);\n setErrorKey(null);\n setErrorMessage('');\n\n // Validate returnUrl at the boundary so even a careless consumer\n // cannot leak payment_intent_client_secret to a third-party origin.\n const safeReturnUrl = validateReturnUrl(returnUrl);\n if (returnUrl !== undefined && safeReturnUrl === null) {\n setErrorKey('payment.error.invalidReturnUrl');\n setErrorMessage(t('payment.error.invalidReturnUrl'));\n onErrorRef.current?.({\n code: 'invalid_return_url',\n translatedMessage: t('payment.error.invalidReturnUrl'),\n });\n setProcessing(false);\n return;\n }\n try {\n const result = await stripe.confirmPayment({\n elements,\n confirmParams: safeReturnUrl ? { return_url: safeReturnUrl } : {},\n redirect: 'if_required',\n });\n\n if (result.error) {\n const code = result.error.code ?? 'generic';\n const key = stripeErrorCodeToI18nKey(code);\n // CRITICAL: sanitise before storing OR forwarding.\n const safe = stripCardLikeDigits(result.error.message ?? '');\n setErrorKey(key);\n setErrorMessage(t(key));\n onErrorRef.current?.({\n code,\n translatedMessage: safe || t(key),\n });\n return;\n }\n\n // Success path — only the PaymentIntent id leaves the wrapper.\n if (result.paymentIntent) {\n onSuccessRef.current?.(result.paymentIntent.id);\n }\n } catch (err: unknown) {\n const raw = err instanceof Error ? err.message : '';\n const safe = stripCardLikeDigits(raw);\n setErrorKey('payment.error.generic');\n setErrorMessage(t('payment.error.generic'));\n onErrorRef.current?.({\n code: 'unexpected',\n translatedMessage: safe || t('payment.error.generic'),\n });\n } finally {\n setProcessing(false);\n }\n },\n [stripe, elements, processing, returnUrl, t],\n );\n\n // Imperative submit hook used by the outer component's ref handle.\n useEffect(() => {\n const host = document.getElementById(idSafe);\n if (!host) return;\n const submitter = () => {\n void handleSubmit();\n };\n host.addEventListener('payment-form:submit', submitter);\n return () => host.removeEventListener('payment-form:submit', submitter);\n }, [idSafe, handleSubmit]);\n\n const submitDisabled = !stripe || !elements || !elementComplete || processing;\n\n return (\n <form\n id={idSafe}\n onSubmit={handleSubmit}\n aria-label={t('payment.ariaLabel')}\n aria-busy={processing || undefined}\n noValidate\n >\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n <div className={amountSummaryVariants()}>\n <span className={labelTextVariants()}>{t('payment.amountLabel')}</span>\n <span\n className=\"type-title-card\"\n data-testid=\"payment-amount\"\n >\n {formatPaymentAmount(amount, currency, locale)}\n </span>\n </div>\n\n <label\n htmlFor={paymentFieldId}\n className={fieldLabelVariants()}\n data-testid=\"payment-field\"\n >\n <span className={labelTextVariants()}>{t('payment.fields.card')}</span>\n <PaymentElement\n id={paymentFieldId}\n options={{\n layout: { type: 'accordion', defaultCollapsed: false },\n }}\n onChange={(ev) => {\n // NOTE: never log `ev` — change events may include hints\n // about field contents. Keep only the boolean completeness.\n setElementComplete(ev.complete === true);\n if (ev.complete) {\n setErrorKey(null);\n setErrorMessage('');\n }\n }}\n />\n </label>\n\n {billingAddress ? (\n <label\n htmlFor={addressFieldId}\n className={fieldLabelVariants()}\n data-testid=\"payment-address\"\n >\n <span className={labelTextVariants()}>\n {t('payment.billingAddress')}\n </span>\n <AddressElement\n id={addressFieldId}\n options={{ mode: 'billing' }}\n />\n </label>\n ) : null}\n\n {errorKey ? (\n <Alert\n id={errorId}\n variant=\"error\"\n live=\"polite\"\n data-testid=\"payment-error\"\n >\n <Alert.Description>{errorMessage}</Alert.Description>\n </Alert>\n ) : null}\n\n <button\n type=\"submit\"\n aria-disabled={submitDisabled || undefined}\n aria-busy={processing || undefined}\n aria-describedby={errorKey ? errorId : undefined}\n className={submitButtonVariants()}\n data-testid=\"payment-submit\"\n >\n {processing ? (\n <>\n <Spinner size=\"sm\" label={t('payment.processing')} />\n <span>{t('payment.processing')}</span>\n </>\n ) : (\n <span>\n {t('payment.submit', {\n amount: formatPaymentAmount(amount, currency, locale),\n })}\n </span>\n )}\n </button>\n </div>\n </form>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* PaymentForm — outer wrapper */\n/* ------------------------------------------------------------------ */\n\n/**\n * Stripe ships a closed union of supported locales; anything outside it\n * must fall through to `'auto'` (Stripe picks the best match from the\n * browser). We also normalise the legacy `cn` code to `zh` per\n * `src/docs/06-i18n.mdx`.\n */\nconst STRIPE_LOCALES = new Set<StripeElementLocale>([\n 'auto', 'ar', 'bg', 'cs', 'da', 'de', 'el', 'en', 'en-AU', 'en-CA',\n 'en-NZ', 'en-GB', 'es', 'es-ES', 'es-419', 'et', 'fi', 'fil', 'fr',\n 'fr-CA', 'fr-FR', 'he', 'hu', 'hr', 'id', 'it', 'it-IT', 'ja', 'ko',\n 'lt', 'lv', 'ms', 'mt', 'nb', 'nl', 'no', 'pl', 'pt', 'pt-BR', 'ro',\n 'ru', 'sk', 'sl', 'sv', 'th', 'tr', 'vi', 'zh', 'zh-HK', 'zh-TW',\n]);\n\nfunction normaliseLocale(input: string): StripeElementLocale {\n if (!input) return 'auto';\n const candidate = input === 'cn' ? 'zh' : input;\n if ((STRIPE_LOCALES as Set<string>).has(candidate)) {\n return candidate as StripeElementLocale;\n }\n // Try stripping region (\"en-US\" → \"en\") before giving up.\n const base = candidate.split('-')[0];\n if ((STRIPE_LOCALES as Set<string>).has(base)) {\n return base as StripeElementLocale;\n }\n return 'auto';\n}\n\nexport const PaymentForm = forwardRef<PaymentFormHandle, PaymentFormProps>(\n (\n {\n clientSecret,\n publishableKey,\n currency,\n amount,\n onSuccess,\n onError,\n billingAddress = false,\n locale,\n ariaLabel,\n returnUrl,\n stripePromise: injectedStripe,\n className,\n },\n ref,\n ) => {\n const { i18n } = useTranslation();\n const activeLocale = normaliseLocale(locale ?? i18n.language ?? 'en');\n\n // Stripe instance — pre-injected (tests/stories) or lazily loaded.\n const [stripeInstance, setStripeInstance] = useState<Promise<Stripe | null> | null>(\n injectedStripe ?? null,\n );\n\n useEffect(() => {\n if (injectedStripe !== undefined) {\n setStripeInstance(injectedStripe);\n return;\n }\n if (!publishableKey) {\n setStripeInstance(null);\n return;\n }\n // `loadStripe` is cached by the SDK — safe to call per mount.\n setStripeInstance(loadStripe(publishableKey));\n }, [injectedStripe, publishableKey]);\n\n // Appearance bridge — snapshot + subscribe.\n const [appearance, setAppearance] = useState<Appearance>(() =>\n getStripeAppearance(),\n );\n useEffect(() => {\n setAppearance(getStripeAppearance());\n const unsubscribe = subscribeStripeAppearance(setAppearance);\n return unsubscribe;\n }, []);\n\n // Imperative handle — dispatch a custom event at the inner form so we\n // can trigger the same submit path as the button without leaking refs\n // through the Stripe `<Elements>` provider (which owns its own tree).\n const hostRef = useRef<HTMLDivElement>(null);\n useImperativeHandle(\n ref,\n (): PaymentFormHandle => ({\n submit: async () => {\n const form = hostRef.current?.querySelector('form');\n if (form) {\n form.dispatchEvent(\n new CustomEvent('payment-form:submit', { bubbles: true }),\n );\n }\n },\n reset: () => {\n const form = hostRef.current?.querySelector('form');\n if (form instanceof HTMLFormElement) {\n form.reset();\n }\n },\n }),\n [],\n );\n\n const elementsOptions = useMemo(\n () => ({\n clientSecret,\n appearance,\n locale: activeLocale,\n }),\n [clientSecret, appearance, activeLocale],\n );\n\n return (\n <div\n ref={hostRef}\n aria-label={ariaLabel}\n className={[formVariants(), className].filter(Boolean).join(' ')}\n data-component=\"payment-form\"\n data-testid=\"payment-form-root\"\n >\n {stripeInstance && clientSecret ? (\n <Elements\n stripe={stripeInstance}\n options={elementsOptions}\n key={clientSecret}\n >\n <InnerPaymentForm\n amount={amount}\n currency={currency}\n locale={activeLocale}\n billingAddress={billingAddress}\n returnUrl={returnUrl}\n onSuccess={onSuccess}\n onError={onError}\n />\n </Elements>\n ) : (\n <PaymentFormSkeleton\n amount={amount}\n currency={currency}\n locale={activeLocale}\n billingAddress={billingAddress}\n />\n )}\n </div>\n );\n },\n);\n\nPaymentForm.displayName = 'PaymentForm';\n\n/* ------------------------------------------------------------------ */\n/* Skeleton — visual chrome when Stripe hasn't loaded yet */\n/* ------------------------------------------------------------------ */\n\ninterface PaymentFormSkeletonProps {\n amount: number;\n currency: string;\n locale: string;\n billingAddress: boolean;\n}\n\nfunction PaymentFormSkeleton(props: PaymentFormSkeletonProps): JSX.Element {\n const { amount, currency, locale, billingAddress } = props;\n const { t } = useTranslation();\n\n return (\n <div\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\"\n data-testid=\"payment-skeleton\"\n aria-busy=\"true\"\n >\n <div className={amountSummaryVariants()}>\n <span className={labelTextVariants()}>{t('payment.amountLabel')}</span>\n <span className=\"type-title-card\">\n {formatPaymentAmount(amount, currency, locale)}\n </span>\n </div>\n <div className={fieldLabelVariants()}>\n <span className={labelTextVariants()}>{t('payment.fields.card')}</span>\n <div\n className=\"ds:min-block-size-[var(--min-target-size)] ds:rounded-[var(--radius-sm)] ds:border ds:border-[color:var(--border)] ds:bg-[var(--muted)]\"\n aria-hidden=\"true\"\n />\n </div>\n {billingAddress ? (\n <div className={fieldLabelVariants()}>\n <span className={labelTextVariants()}>\n {t('payment.billingAddress')}\n </span>\n <div\n className=\"ds:min-block-size-[calc(var(--min-target-size)*2)] ds:rounded-[var(--radius-sm)] ds:border ds:border-[color:var(--border)] ds:bg-[var(--muted)]\"\n aria-hidden=\"true\"\n />\n </div>\n ) : null}\n <button\n type=\"button\"\n aria-disabled=\"true\"\n className={submitButtonVariants()}\n disabled\n >\n <Spinner size=\"sm\" label={t('payment.processing')} />\n <span>{t('payment.processing')}</span>\n </button>\n </div>\n );\n}\n\nexport {\n formVariants as paymentFormVariants,\n submitButtonVariants as paymentSubmitButtonVariants,\n};\n"],"names":["isBrowser","getStripeAppearance","root","target","styles","read","token","subscribeStripeAppearance","onChange","emit","observer","schemeMql","motionMql","ZERO_DECIMAL_CURRENCIES","formatPaymentAmount","amount","currency","locale","iso","major","validateReturnUrl","returnUrl","raw","resolved","stripCardLikeDigits","message","stripeErrorCodeToI18nKey","code","formVariants","cva","fieldLabelVariants","labelTextVariants","amountSummaryVariants","submitButtonVariants","InnerPaymentForm","props","billingAddress","onSuccess","onError","t","useTranslation","stripe","useStripe","elements","useElements","rawId","useId","idSafe","useMemo","paymentFieldId","addressFieldId","errorId","processing","setProcessing","useState","elementComplete","setElementComplete","errorKey","setErrorKey","errorMessage","setErrorMessage","onSuccessRef","useRef","onErrorRef","useEffect","handleSubmit","useCallback","event","safeReturnUrl","_a","result","key","safe","_b","_c","err","_d","host","submitter","submitDisabled","jsx","jsxs","PaymentElement","ev","AddressElement","Alert","Fragment","Spinner","STRIPE_LOCALES","normaliseLocale","input","candidate","base","PaymentForm","forwardRef","clientSecret","publishableKey","ariaLabel","injectedStripe","className","ref","i18n","activeLocale","stripeInstance","setStripeInstance","loadStripe","appearance","setAppearance","hostRef","useImperativeHandle","form","elementsOptions","Elements","PaymentFormSkeleton"],"mappings":"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"}
|