@techzyapp/ui-library 1.0.40 → 1.0.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -8
- package/dist/AdminRoot-DufZpgdm.js +100 -0
- package/dist/AdminRoot-DufZpgdm.js.map +1 -0
- package/dist/AdminRoot-DwJ5jdXr.cjs +2 -0
- package/dist/AdminRoot-DwJ5jdXr.cjs.map +1 -0
- package/dist/Alert-C8BBxL_7.cjs +2 -0
- package/dist/Alert-C8BBxL_7.cjs.map +1 -0
- package/dist/Alert-D6oBxBdP.js +70 -0
- package/dist/Alert-D6oBxBdP.js.map +1 -0
- package/dist/AuthLayout-exuNQicH.cjs.map +1 -1
- package/dist/AuthLayout-q8pbCGdt.js.map +1 -1
- package/dist/{Breadcrumbs-hi6dJhfN.cjs → Breadcrumbs-B-olYVdw.cjs} +2 -2
- package/dist/Breadcrumbs-B-olYVdw.cjs.map +1 -0
- package/dist/{Breadcrumbs-Dqhk-dY2.js → Breadcrumbs-cXET6OM5.js} +3 -3
- package/dist/Breadcrumbs-cXET6OM5.js.map +1 -0
- package/dist/{Button-Bst_NtPJ.js → Button-0ZgdNjX-.js} +2 -2
- package/dist/{Button-Bst_NtPJ.js.map → Button-0ZgdNjX-.js.map} +1 -1
- package/dist/{Button-CYZoF18-.cjs → Button-CwrDiZek.cjs} +2 -2
- package/dist/{Button-CYZoF18-.cjs.map → Button-CwrDiZek.cjs.map} +1 -1
- package/dist/{Calendar-OYXsfuWz.js → Calendar-CxzdnzdK.js} +3 -3
- package/dist/{Calendar-OYXsfuWz.js.map → Calendar-CxzdnzdK.js.map} +1 -1
- package/dist/{Calendar-CMNBHtvY.cjs → Calendar-d3CX5UJp.cjs} +2 -2
- package/dist/{Calendar-CMNBHtvY.cjs.map → Calendar-d3CX5UJp.cjs.map} +1 -1
- package/dist/Card-CjqStov5.js +129 -0
- package/dist/Card-CjqStov5.js.map +1 -0
- package/dist/Card-CxnUoWsi.cjs +2 -0
- package/dist/Card-CxnUoWsi.cjs.map +1 -0
- package/dist/{Chip-B7cAHjlx.cjs → Chip-BkU3yx6G.cjs} +2 -2
- package/dist/Chip-BkU3yx6G.cjs.map +1 -0
- package/dist/{Chip-D5ZZs3QH.js → Chip-CzJjbaKx.js} +2 -2
- package/dist/Chip-CzJjbaKx.js.map +1 -0
- package/dist/ChoiceCardGroup-C7Eengyd.cjs +2 -0
- package/dist/ChoiceCardGroup-C7Eengyd.cjs.map +1 -0
- package/dist/ChoiceCardGroup-q0yN-TeQ.js +180 -0
- package/dist/{ChoiceCardGroup-143hR0v_.cjs.map → ChoiceCardGroup-q0yN-TeQ.js.map} +1 -1
- package/dist/{CodeBlock-DrWRSRmO.js → CodeBlock-BHcvQrs9.js} +3 -3
- package/dist/CodeBlock-BHcvQrs9.js.map +1 -0
- package/dist/{CodeBlock-C3mG_seZ.cjs → CodeBlock-DRBQ_S5t.cjs} +2 -2
- package/dist/CodeBlock-DRBQ_S5t.cjs.map +1 -0
- package/dist/{ColorPicker-w7NdprlW.js → ColorPicker-BQKFdTNr.js} +51 -51
- package/dist/{ColorPicker-w7NdprlW.js.map → ColorPicker-BQKFdTNr.js.map} +1 -1
- package/dist/ColorPicker-BzCEMN7B.cjs +2 -0
- package/dist/{ColorPicker-C1pDI4su.cjs.map → ColorPicker-BzCEMN7B.cjs.map} +1 -1
- package/dist/{ColorPickerPanel-CKMd-dqd.js → ColorPickerPanel-DKTKC9KH.js} +2 -2
- package/dist/{ColorPickerPanel-CKMd-dqd.js.map → ColorPickerPanel-DKTKC9KH.js.map} +1 -1
- package/dist/{ColorPickerPanel-BbgujQ3X.cjs → ColorPickerPanel-kl2jUix-.cjs} +2 -2
- package/dist/{ColorPickerPanel-BbgujQ3X.cjs.map → ColorPickerPanel-kl2jUix-.cjs.map} +1 -1
- package/dist/{ColorRamp-D9_5JULy.cjs → ColorRamp-n7muILK3.cjs} +2 -2
- package/dist/{ColorRamp-D9_5JULy.cjs.map → ColorRamp-n7muILK3.cjs.map} +1 -1
- package/dist/{ColorRamp-Mp_ddhmb.js → ColorRamp-yfMyJCyx.js} +2 -2
- package/dist/{ColorRamp-Mp_ddhmb.js.map → ColorRamp-yfMyJCyx.js.map} +1 -1
- package/dist/ConfigProvider-BaiTKZKC.cjs +2 -0
- package/dist/ConfigProvider-BaiTKZKC.cjs.map +1 -0
- package/dist/ConfigProvider-D61cpCz-.js +379 -0
- package/dist/ConfigProvider-D61cpCz-.js.map +1 -0
- package/dist/{CopyButton-DZeYcG68.cjs → CopyButton-DlSi82gv.cjs} +2 -2
- package/dist/{CopyButton-DZeYcG68.cjs.map → CopyButton-DlSi82gv.cjs.map} +1 -1
- package/dist/{CopyButton-Yg5ZVTiX.js → CopyButton-ecxn-ghi.js} +3 -3
- package/dist/{CopyButton-Yg5ZVTiX.js.map → CopyButton-ecxn-ghi.js.map} +1 -1
- package/dist/DatePicker-BjZ_P21i.cjs +2 -0
- package/dist/{DatePicker-CXRsT-lt.cjs.map → DatePicker-BjZ_P21i.cjs.map} +1 -1
- package/dist/{DatePicker-BMJlfCKB.js → DatePicker-CAGpJbDi.js} +42 -42
- package/dist/{DatePicker-BMJlfCKB.js.map → DatePicker-CAGpJbDi.js.map} +1 -1
- package/dist/{DateTimePicker-B-Jjejzm.js → DateTimePicker-BJmF0Su6.js} +50 -50
- package/dist/DateTimePicker-BJmF0Su6.js.map +1 -0
- package/dist/DateTimePicker-DZqWQeUL.cjs +2 -0
- package/dist/DateTimePicker-DZqWQeUL.cjs.map +1 -0
- package/dist/{DescriptionList-S9C6Tp90.cjs → DescriptionList-CvPDn-kh.cjs} +2 -2
- package/dist/DescriptionList-CvPDn-kh.cjs.map +1 -0
- package/dist/{DescriptionList-CG08_qwT.js → DescriptionList-Knq5eCiY.js} +4 -4
- package/dist/DescriptionList-Knq5eCiY.js.map +1 -0
- package/dist/{Dropdown-DYYhzKSo.cjs → Dropdown-CMjURWYd.cjs} +2 -2
- package/dist/{Dropdown-DYYhzKSo.cjs.map → Dropdown-CMjURWYd.cjs.map} +1 -1
- package/dist/{Dropdown-CcC-Hwx4.js → Dropdown-CnDBlB02.js} +2 -2
- package/dist/{Dropdown-CcC-Hwx4.js.map → Dropdown-CnDBlB02.js.map} +1 -1
- package/dist/{EmptyState-DnGds1ch.cjs → EmptyState-CX1g47y_.cjs} +2 -2
- package/dist/{EmptyState-DnGds1ch.cjs.map → EmptyState-CX1g47y_.cjs.map} +1 -1
- package/dist/{EmptyState-BCoPw8jf.js → EmptyState-Dqtpmtje.js} +2 -2
- package/dist/{EmptyState-BCoPw8jf.js.map → EmptyState-Dqtpmtje.js.map} +1 -1
- package/dist/{ErrorBoundary-JCNa0_Ys.cjs → ErrorBoundary-B8KwWXXp.cjs} +2 -2
- package/dist/{ErrorBoundary-JCNa0_Ys.cjs.map → ErrorBoundary-B8KwWXXp.cjs.map} +1 -1
- package/dist/{ErrorBoundary-BILk_3fM.js → ErrorBoundary-Dos7VLb-.js} +3 -3
- package/dist/{ErrorBoundary-BILk_3fM.js.map → ErrorBoundary-Dos7VLb-.js.map} +1 -1
- package/dist/{ErrorState-MQBeyF2n.cjs → ErrorState-CwCqd2PU.cjs} +2 -2
- package/dist/{ErrorState-MQBeyF2n.cjs.map → ErrorState-CwCqd2PU.cjs.map} +1 -1
- package/dist/{ErrorState-DI28ZCJN.js → ErrorState-KhzrGIJ-.js} +7 -7
- package/dist/{ErrorState-DI28ZCJN.js.map → ErrorState-KhzrGIJ-.js.map} +1 -1
- package/dist/{FileCard-Cl88Gu6L.cjs → FileCard-DEc10T2G.cjs} +2 -2
- package/dist/FileCard-DEc10T2G.cjs.map +1 -0
- package/dist/{FileCard-5QvVkO1-.js → FileCard-SSuFS13E.js} +3 -3
- package/dist/FileCard-SSuFS13E.js.map +1 -0
- package/dist/{FileUploader-FMVbj7rz.cjs → FileUploader-D58_6kDA.cjs} +2 -2
- package/dist/FileUploader-D58_6kDA.cjs.map +1 -0
- package/dist/{FileUploader-DwAl3UXI.js → FileUploader-DfYOBFa4.js} +5 -5
- package/dist/FileUploader-DfYOBFa4.js.map +1 -0
- package/dist/{Flag-Do7x-AhS.cjs → Flag-B1ZvZVXi.cjs} +2 -2
- package/dist/{Flag-Do7x-AhS.cjs.map → Flag-B1ZvZVXi.cjs.map} +1 -1
- package/dist/{Flag-DfA2t0yd.js → Flag-BEIqYQZg.js} +2 -2
- package/dist/{Flag-DfA2t0yd.js.map → Flag-BEIqYQZg.js.map} +1 -1
- package/dist/FloatingPanel-C5c_eMQ0.js.map +1 -1
- package/dist/FloatingPanel-tGCG2nhA.cjs.map +1 -1
- package/dist/{FullscreenToggle-DM6wWZ1a.js → FullscreenToggle-I_In47BB.js} +3 -3
- package/dist/{FullscreenToggle-DM6wWZ1a.js.map → FullscreenToggle-I_In47BB.js.map} +1 -1
- package/dist/{FullscreenToggle-Bbb_z2xj.cjs → FullscreenToggle-Po769CoC.cjs} +2 -2
- package/dist/{FullscreenToggle-Bbb_z2xj.cjs.map → FullscreenToggle-Po769CoC.cjs.map} +1 -1
- package/dist/{IconButton-CQ25TtBc.cjs → IconButton-CxSXEYce.cjs} +2 -2
- package/dist/{IconButton-CQ25TtBc.cjs.map → IconButton-CxSXEYce.cjs.map} +1 -1
- package/dist/{IconButton-06pmftMo.js → IconButton-D9MCwRK_.js} +2 -2
- package/dist/{IconButton-06pmftMo.js.map → IconButton-D9MCwRK_.js.map} +1 -1
- package/dist/{List-CwuAJDTi.js → List-2Y3ktTcF.js} +2 -2
- package/dist/{List-CwuAJDTi.js.map → List-2Y3ktTcF.js.map} +1 -1
- package/dist/{List-B5Ppe9R1.cjs → List-CKoNx21F.cjs} +2 -2
- package/dist/{List-B5Ppe9R1.cjs.map → List-CKoNx21F.cjs.map} +1 -1
- package/dist/{ListItem-BWNIbyTh.js → ListItem-2Lr5_NRY.js} +15 -15
- package/dist/{ListItem-BWNIbyTh.js.map → ListItem-2Lr5_NRY.js.map} +1 -1
- package/dist/ListItem-DkCYXucd.cjs +2 -0
- package/dist/{ListItem-Qo1Tt6Fi.cjs.map → ListItem-DkCYXucd.cjs.map} +1 -1
- package/dist/{Loader-B5Pm8AaT.cjs → Loader-5zp2MPm5.cjs} +2 -2
- package/dist/{Loader-B5Pm8AaT.cjs.map → Loader-5zp2MPm5.cjs.map} +1 -1
- package/dist/{Loader-Bj5uwVR9.js → Loader-Bluu6z0-.js} +2 -2
- package/dist/{Loader-Bj5uwVR9.js.map → Loader-Bluu6z0-.js.map} +1 -1
- package/dist/{LocationPicker-D-sT4rSe.cjs → LocationPicker-CGHXTIml.cjs} +2 -2
- package/dist/{LocationPicker-D-sT4rSe.cjs.map → LocationPicker-CGHXTIml.cjs.map} +1 -1
- package/dist/{LocationPicker-Ce8aLubZ.js → LocationPicker-hULpHBVG.js} +7 -7
- package/dist/{LocationPicker-Ce8aLubZ.js.map → LocationPicker-hULpHBVG.js.map} +1 -1
- package/dist/{Modal-DTnB_mGg.js → Modal-C6Zgwz_6.js} +3 -3
- package/dist/Modal-C6Zgwz_6.js.map +1 -0
- package/dist/{Modal-DjSOhZqd.cjs → Modal-D9_OG53G.cjs} +2 -2
- package/dist/Modal-D9_OG53G.cjs.map +1 -0
- package/dist/{MultiSelect-C4RvohFY.cjs → MultiSelect-BdPvjiTj.cjs} +2 -2
- package/dist/{MultiSelect-C4RvohFY.cjs.map → MultiSelect-BdPvjiTj.cjs.map} +1 -1
- package/dist/{MultiSelect-Dn8l5z52.js → MultiSelect-CHLMpim4.js} +4 -4
- package/dist/{MultiSelect-Dn8l5z52.js.map → MultiSelect-CHLMpim4.js.map} +1 -1
- package/dist/{NumberField-DvQ5UP1R.js → NumberField-BlpFmetF.js} +3 -3
- package/dist/{NumberField-DvQ5UP1R.js.map → NumberField-BlpFmetF.js.map} +1 -1
- package/dist/{NumberField-C3TLdAgT.cjs → NumberField-C-FZ-uRI.cjs} +2 -2
- package/dist/{NumberField-C3TLdAgT.cjs.map → NumberField-C-FZ-uRI.cjs.map} +1 -1
- package/dist/OtpField-D4-r7I0A.js +174 -0
- package/dist/OtpField-D4-r7I0A.js.map +1 -0
- package/dist/OtpField-Drjy2wwq.cjs +2 -0
- package/dist/OtpField-Drjy2wwq.cjs.map +1 -0
- package/dist/{PageError-aUV0vUfB.cjs → PageError-DXUOkE14.cjs} +2 -2
- package/dist/{PageError-aUV0vUfB.cjs.map → PageError-DXUOkE14.cjs.map} +1 -1
- package/dist/{PageError-BORFaxGW.js → PageError-DyDj1wQZ.js} +5 -5
- package/dist/{PageError-BORFaxGW.js.map → PageError-DyDj1wQZ.js.map} +1 -1
- package/dist/{PageLayout-rtEl8uqS.cjs → PageLayout-CoG0AaUs.cjs} +2 -2
- package/dist/PageLayout-CoG0AaUs.cjs.map +1 -0
- package/dist/{PageLayout-ojiBEcxI.js → PageLayout-nsJa8CbT.js} +4 -4
- package/dist/PageLayout-nsJa8CbT.js.map +1 -0
- package/dist/{PageNotFound-D536Tshv.js → PageNotFound-BNNwMkwE.js} +5 -5
- package/dist/{PageNotFound-D536Tshv.js.map → PageNotFound-BNNwMkwE.js.map} +1 -1
- package/dist/{PageNotFound-f-dxrnol.cjs → PageNotFound-CGSxT_n9.cjs} +2 -2
- package/dist/{PageNotFound-f-dxrnol.cjs.map → PageNotFound-CGSxT_n9.cjs.map} +1 -1
- package/dist/Pagination-CZtewveA.cjs +2 -0
- package/dist/Pagination-CZtewveA.cjs.map +1 -0
- package/dist/Pagination-tuWRnGwR.js +139 -0
- package/dist/Pagination-tuWRnGwR.js.map +1 -0
- package/dist/PaletteField-CTPl3D43.js +56 -0
- package/dist/PaletteField-CTPl3D43.js.map +1 -0
- package/dist/PaletteField-PDcu2vUp.cjs +2 -0
- package/dist/PaletteField-PDcu2vUp.cjs.map +1 -0
- package/dist/{PhoneField-DzLTXJcw.cjs → PhoneField-BPYg5ZHW.cjs} +2 -2
- package/dist/{PhoneField-DzLTXJcw.cjs.map → PhoneField-BPYg5ZHW.cjs.map} +1 -1
- package/dist/{PhoneField-CjYw-Unw.js → PhoneField-pdWDCszb.js} +4 -4
- package/dist/{PhoneField-CjYw-Unw.js.map → PhoneField-pdWDCszb.js.map} +1 -1
- package/dist/{Popconfirm-B3GhhrRM.js → Popconfirm-CMVzLaC_.js} +3 -3
- package/dist/{Popconfirm-B3GhhrRM.js.map → Popconfirm-CMVzLaC_.js.map} +1 -1
- package/dist/{Popconfirm-CYc8ywDI.cjs → Popconfirm-cNpJmkuR.cjs} +2 -2
- package/dist/{Popconfirm-CYc8ywDI.cjs.map → Popconfirm-cNpJmkuR.cjs.map} +1 -1
- package/dist/Popover-DsYUT23r.cjs.map +1 -1
- package/dist/Popover-WaVH3jsN.js.map +1 -1
- package/dist/{Progress-ZNQrxw_Q.js → Progress-BNEFGn-O.js} +2 -2
- package/dist/{Progress-ZNQrxw_Q.js.map → Progress-BNEFGn-O.js.map} +1 -1
- package/dist/{Progress-BABBBG2y.cjs → Progress-x12Rkh06.cjs} +2 -2
- package/dist/{Progress-BABBBG2y.cjs.map → Progress-x12Rkh06.cjs.map} +1 -1
- package/dist/QrCode-CrNJZV_8.js +81 -0
- package/dist/QrCode-CrNJZV_8.js.map +1 -0
- package/dist/QrCode-TcQQE0h7.cjs +2 -0
- package/dist/QrCode-TcQQE0h7.cjs.map +1 -0
- package/dist/{RemoveDialog-ayAfGXpB.js → RemoveDialog-ARFp1UJM.js} +5 -5
- package/dist/{RemoveDialog-ayAfGXpB.js.map → RemoveDialog-ARFp1UJM.js.map} +1 -1
- package/dist/{RemoveDialog-B_Y18MeJ.cjs → RemoveDialog-IWOAQFNK.cjs} +2 -2
- package/dist/{RemoveDialog-B_Y18MeJ.cjs.map → RemoveDialog-IWOAQFNK.cjs.map} +1 -1
- package/dist/RichTextEditor-C9jT2cLl.cjs +2 -0
- package/dist/RichTextEditor-C9jT2cLl.cjs.map +1 -0
- package/dist/{RichTextEditor-itYD1PfE.js → RichTextEditor-DrwJUEYz.js} +148 -148
- package/dist/RichTextEditor-DrwJUEYz.js.map +1 -0
- package/dist/RootLayout-CZ2GQ8XA.js +647 -0
- package/dist/RootLayout-CZ2GQ8XA.js.map +1 -0
- package/dist/RootLayout-DStUP263.cjs +2 -0
- package/dist/RootLayout-DStUP263.cjs.map +1 -0
- package/dist/{Select-1FWkryTK.cjs → Select-C2DIfuoB.cjs} +2 -2
- package/dist/{Select-1FWkryTK.cjs.map → Select-C2DIfuoB.cjs.map} +1 -1
- package/dist/{Select-K0a_7ROf.js → Select-KGsA8PbI.js} +3 -3
- package/dist/{Select-K0a_7ROf.js.map → Select-KGsA8PbI.js.map} +1 -1
- package/dist/{Sidebar-Dg15hPpM.js → Sidebar-_pcwxdd8.js} +133 -131
- package/dist/{Sidebar-Dg15hPpM.js.map → Sidebar-_pcwxdd8.js.map} +1 -1
- package/dist/Sidebar-wK1_xaY_.cjs +2 -0
- package/dist/{Sidebar-C3-u3Agj.cjs.map → Sidebar-wK1_xaY_.cjs.map} +1 -1
- package/dist/Slider-CXAz9SUY.cjs +2 -0
- package/dist/Slider-CXAz9SUY.cjs.map +1 -0
- package/dist/Slider-Cpc5_dPl.js +185 -0
- package/dist/Slider-Cpc5_dPl.js.map +1 -0
- package/dist/{SpeedDial-D6me6w_m.cjs → SpeedDial-BT_boD06.cjs} +2 -2
- package/dist/{SpeedDial-D6me6w_m.cjs.map → SpeedDial-BT_boD06.cjs.map} +1 -1
- package/dist/{SpeedDial-CEBAWIYo.js → SpeedDial-SMMfes9f.js} +2 -2
- package/dist/{SpeedDial-CEBAWIYo.js.map → SpeedDial-SMMfes9f.js.map} +1 -1
- package/dist/{Stepper-wPPs57uZ.cjs → Stepper-BmA_DjTS.cjs} +2 -2
- package/dist/Stepper-BmA_DjTS.cjs.map +1 -0
- package/dist/{Stepper-BN0GsRZW.js → Stepper-CR0Mlkq7.js} +2 -2
- package/dist/Stepper-CR0Mlkq7.js.map +1 -0
- package/dist/{Table-CFl3OYlo.cjs → Table-BkjY1Lwt.cjs} +2 -2
- package/dist/Table-BkjY1Lwt.cjs.map +1 -0
- package/dist/{Table-DChIfjqj.js → Table-D-F68lcm.js} +18 -18
- package/dist/Table-D-F68lcm.js.map +1 -0
- package/dist/{Tabs-BAKPWO4g.cjs → Tabs-Cgp6D1WP.cjs} +2 -2
- package/dist/{Tabs-BAKPWO4g.cjs.map → Tabs-Cgp6D1WP.cjs.map} +1 -1
- package/dist/{Tabs-DfVFgOfs.js → Tabs-DP0aZ5TB.js} +2 -2
- package/dist/{Tabs-DfVFgOfs.js.map → Tabs-DP0aZ5TB.js.map} +1 -1
- package/dist/TagsField-9nKu6ZW4.cjs +2 -0
- package/dist/TagsField-9nKu6ZW4.cjs.map +1 -0
- package/dist/{TagsField-CoBRqcjW.js → TagsField-CcY9MTMw.js} +64 -64
- package/dist/TagsField-CcY9MTMw.js.map +1 -0
- package/dist/{TextField-0gFvIFs8.js → TextField-0WvJsHhA.js} +3 -3
- package/dist/{TextField-0gFvIFs8.js.map → TextField-0WvJsHhA.js.map} +1 -1
- package/dist/{TextField-BL6OAJcP.cjs → TextField-C5MgCQIV.cjs} +2 -2
- package/dist/{TextField-BL6OAJcP.cjs.map → TextField-C5MgCQIV.cjs.map} +1 -1
- package/dist/{ThemeToggle-BgKfcb02.cjs → ThemeToggle-BvcCxRpF.cjs} +2 -2
- package/dist/{ThemeToggle-BgKfcb02.cjs.map → ThemeToggle-BvcCxRpF.cjs.map} +1 -1
- package/dist/ThemeToggle-DmCePuTy.js +28 -0
- package/dist/{ThemeToggle-_SUmLxmU.js.map → ThemeToggle-DmCePuTy.js.map} +1 -1
- package/dist/{TimeColumns-DkJsIu1w.cjs → TimeColumns-Q-vsHFZU.cjs} +2 -2
- package/dist/{TimeColumns-DkJsIu1w.cjs.map → TimeColumns-Q-vsHFZU.cjs.map} +1 -1
- package/dist/{TimeColumns-BE1sLoRV.js → TimeColumns-WJRHQuFv.js} +2 -2
- package/dist/{TimeColumns-BE1sLoRV.js.map → TimeColumns-WJRHQuFv.js.map} +1 -1
- package/dist/TimePicker-CvbQFzBf.cjs +2 -0
- package/dist/{TimePicker-6nHQx0P5.cjs.map → TimePicker-CvbQFzBf.cjs.map} +1 -1
- package/dist/{TimePicker-Bv2qIFf9.js → TimePicker-DJDuSxAg.js} +54 -54
- package/dist/{TimePicker-Bv2qIFf9.js.map → TimePicker-DJDuSxAg.js.map} +1 -1
- package/dist/{Toaster-Fq6-ImDJ.js → Toaster-Bb5YEN5j.js} +2 -2
- package/dist/{Toaster-Fq6-ImDJ.js.map → Toaster-Bb5YEN5j.js.map} +1 -1
- package/dist/{Toaster-Brcspf7v.cjs → Toaster-Dy1AonLa.cjs} +2 -2
- package/dist/{Toaster-Brcspf7v.cjs.map → Toaster-Dy1AonLa.cjs.map} +1 -1
- package/dist/TranslatedFields-CuK5KKzE.cjs +2 -0
- package/dist/TranslatedFields-CuK5KKzE.cjs.map +1 -0
- package/dist/TranslatedFields-DKXznBtD.js +86 -0
- package/dist/TranslatedFields-DKXznBtD.js.map +1 -0
- package/dist/{UserCard-1ubnvBV6.cjs → UserCard-DbudGMvG.cjs} +2 -2
- package/dist/UserCard-DbudGMvG.cjs.map +1 -0
- package/dist/{UserCard-DcTLEHFu.js → UserCard-UG_Cwe-Y.js} +3 -3
- package/dist/UserCard-UG_Cwe-Y.js.map +1 -0
- package/dist/app/AdminRoot.d.cts +13 -3
- package/dist/app/AdminRoot.d.ts +13 -3
- package/dist/components/Alert/Alert.d.cts +1 -1
- package/dist/components/Alert/Alert.d.ts +1 -1
- package/dist/components/Alert/index.cjs +1 -1
- package/dist/components/Alert/index.js +1 -1
- package/dist/components/AuthLayout/AuthLayout.d.cts +2 -2
- package/dist/components/AuthLayout/AuthLayout.d.ts +2 -2
- package/dist/components/Breadcrumbs/Breadcrumbs.d.cts +2 -1
- package/dist/components/Breadcrumbs/Breadcrumbs.d.ts +2 -1
- package/dist/components/Breadcrumbs/index.cjs +1 -1
- package/dist/components/Breadcrumbs/index.js +1 -1
- package/dist/components/Button/index.cjs +1 -1
- package/dist/components/Button/index.js +1 -1
- package/dist/components/Card/Card.d.cts +1 -1
- package/dist/components/Card/Card.d.ts +1 -1
- package/dist/components/Card/index.cjs +1 -1
- package/dist/components/Card/index.js +1 -1
- package/dist/components/Chip/Chip.d.cts +1 -1
- package/dist/components/Chip/Chip.d.ts +1 -1
- package/dist/components/Chip/index.cjs +1 -1
- package/dist/components/Chip/index.js +1 -1
- package/dist/components/ChoiceCard/ChoiceCard.d.cts +1 -1
- package/dist/components/ChoiceCard/ChoiceCard.d.ts +1 -1
- package/dist/components/ChoiceCard/index.cjs +1 -1
- package/dist/components/ChoiceCard/index.js +1 -1
- package/dist/components/CodeBlock/CodeBlock.d.cts +1 -1
- package/dist/components/CodeBlock/CodeBlock.d.ts +1 -1
- package/dist/components/CodeBlock/index.cjs +1 -1
- package/dist/components/CodeBlock/index.js +1 -1
- package/dist/components/ColorPicker/index.cjs +1 -1
- package/dist/components/ColorPicker/index.js +1 -1
- package/dist/components/ColorRamp/index.cjs +1 -1
- package/dist/components/ColorRamp/index.js +1 -1
- package/dist/components/CopyButton/index.cjs +1 -1
- package/dist/components/CopyButton/index.js +1 -1
- package/dist/components/DatePicker/index.cjs +1 -1
- package/dist/components/DatePicker/index.js +1 -1
- package/dist/components/DateTimePicker/DateTimePicker.d.cts +2 -2
- package/dist/components/DateTimePicker/DateTimePicker.d.ts +2 -2
- package/dist/components/DateTimePicker/index.cjs +1 -1
- package/dist/components/DateTimePicker/index.js +1 -1
- package/dist/components/DescriptionList/DescriptionList.d.cts +1 -1
- package/dist/components/DescriptionList/DescriptionList.d.ts +1 -1
- package/dist/components/DescriptionList/index.cjs +1 -1
- package/dist/components/DescriptionList/index.js +1 -1
- package/dist/components/Dropdown/index.cjs +1 -1
- package/dist/components/Dropdown/index.js +1 -1
- package/dist/components/EmptyState/index.cjs +1 -1
- package/dist/components/EmptyState/index.js +1 -1
- package/dist/components/ErrorState/index.cjs +1 -1
- package/dist/components/ErrorState/index.js +2 -2
- package/dist/components/FileCard/FileCard.d.cts +5 -2
- package/dist/components/FileCard/FileCard.d.ts +5 -2
- package/dist/components/FileCard/index.cjs +1 -1
- package/dist/components/FileCard/index.js +1 -1
- package/dist/components/FileUploader/FileUploader.d.cts +5 -5
- package/dist/components/FileUploader/FileUploader.d.ts +5 -5
- package/dist/components/FileUploader/index.cjs +1 -1
- package/dist/components/FileUploader/index.js +1 -1
- package/dist/components/Flag/index.cjs +1 -1
- package/dist/components/Flag/index.js +1 -1
- package/dist/components/FloatingPanel/FloatingPanel.d.cts +6 -5
- package/dist/components/FloatingPanel/FloatingPanel.d.ts +6 -5
- package/dist/components/FullscreenToggle/index.cjs +1 -1
- package/dist/components/FullscreenToggle/index.js +1 -1
- package/dist/components/IconButton/index.cjs +1 -1
- package/dist/components/IconButton/index.js +1 -1
- package/dist/components/List/index.cjs +1 -1
- package/dist/components/List/index.js +2 -2
- package/dist/components/Loader/Loader.d.cts +1 -1
- package/dist/components/Loader/Loader.d.ts +1 -1
- package/dist/components/Loader/index.cjs +1 -1
- package/dist/components/Loader/index.js +1 -1
- package/dist/components/LocationPicker/index.cjs +1 -1
- package/dist/components/LocationPicker/index.js +1 -1
- package/dist/components/Modal/Modal.d.cts +1 -1
- package/dist/components/Modal/Modal.d.ts +1 -1
- package/dist/components/Modal/index.cjs +1 -1
- package/dist/components/Modal/index.js +1 -1
- package/dist/components/MultiSelect/index.cjs +1 -1
- package/dist/components/MultiSelect/index.js +1 -1
- package/dist/components/NumberField/index.cjs +1 -1
- package/dist/components/NumberField/index.js +1 -1
- package/dist/components/OtpField/OtpField.d.cts +1 -1
- package/dist/components/OtpField/OtpField.d.ts +1 -1
- package/dist/components/OtpField/index.cjs +1 -1
- package/dist/components/OtpField/index.js +1 -1
- package/dist/components/PageError/index.cjs +1 -1
- package/dist/components/PageError/index.js +1 -1
- package/dist/components/PageLayout/PageLayout.d.cts +2 -2
- package/dist/components/PageLayout/PageLayout.d.ts +2 -2
- package/dist/components/PageLayout/index.cjs +1 -1
- package/dist/components/PageLayout/index.js +1 -1
- package/dist/components/PageNotFound/index.cjs +1 -1
- package/dist/components/PageNotFound/index.js +1 -1
- package/dist/components/Pagination/index.cjs +1 -1
- package/dist/components/Pagination/index.js +1 -1
- package/dist/components/PaletteField/PaletteField.d.cts +8 -2
- package/dist/components/PaletteField/PaletteField.d.ts +8 -2
- package/dist/components/PaletteField/index.cjs +1 -1
- package/dist/components/PaletteField/index.js +1 -1
- package/dist/components/PhoneField/index.cjs +1 -1
- package/dist/components/PhoneField/index.js +1 -1
- package/dist/components/Popconfirm/index.cjs +1 -1
- package/dist/components/Popconfirm/index.js +1 -1
- package/dist/components/Popover/Popover.d.cts +1 -1
- package/dist/components/Popover/Popover.d.ts +1 -1
- package/dist/components/Progress/index.cjs +1 -1
- package/dist/components/Progress/index.js +1 -1
- package/dist/components/QrCode/QrCode.d.cts +5 -2
- package/dist/components/QrCode/QrCode.d.ts +5 -2
- package/dist/components/QrCode/index.cjs +1 -1
- package/dist/components/QrCode/index.js +1 -1
- package/dist/components/RemoveDialog/index.cjs +1 -1
- package/dist/components/RemoveDialog/index.js +1 -1
- package/dist/components/RichTextEditor/RichTextEditor.d.cts +1 -1
- package/dist/components/RichTextEditor/RichTextEditor.d.ts +1 -1
- package/dist/components/RichTextEditor/index.cjs +1 -1
- package/dist/components/RichTextEditor/index.js +1 -1
- package/dist/components/RootLayout/RootLayout.d.cts +26 -6
- package/dist/components/RootLayout/RootLayout.d.ts +26 -6
- package/dist/components/RootLayout/SettingsDrawer.d.cts +8 -2
- package/dist/components/RootLayout/SettingsDrawer.d.ts +8 -2
- package/dist/components/RootLayout/index.cjs +1 -1
- package/dist/components/RootLayout/index.d.cts +1 -1
- package/dist/components/RootLayout/index.d.ts +1 -1
- package/dist/components/RootLayout/index.js +1 -1
- package/dist/components/Select/index.cjs +1 -1
- package/dist/components/Select/index.js +1 -1
- package/dist/components/Sidebar/index.cjs +1 -1
- package/dist/components/Sidebar/index.js +1 -1
- package/dist/components/Slider/Slider.d.cts +2 -2
- package/dist/components/Slider/Slider.d.ts +2 -2
- package/dist/components/Slider/index.cjs +1 -1
- package/dist/components/Slider/index.js +1 -1
- package/dist/components/SpeedDial/index.cjs +1 -1
- package/dist/components/SpeedDial/index.js +1 -1
- package/dist/components/Stepper/Stepper.d.cts +2 -2
- package/dist/components/Stepper/Stepper.d.ts +2 -2
- package/dist/components/Stepper/index.cjs +1 -1
- package/dist/components/Stepper/index.js +1 -1
- package/dist/components/Table/Table.d.cts +1 -1
- package/dist/components/Table/Table.d.ts +1 -1
- package/dist/components/Table/index.cjs +1 -1
- package/dist/components/Table/index.js +1 -1
- package/dist/components/Tabs/index.cjs +1 -1
- package/dist/components/Tabs/index.js +1 -1
- package/dist/components/TagsField/TagsField.d.cts +1 -1
- package/dist/components/TagsField/TagsField.d.ts +1 -1
- package/dist/components/TagsField/index.cjs +1 -1
- package/dist/components/TagsField/index.js +1 -1
- package/dist/components/TextField/index.cjs +1 -1
- package/dist/components/TextField/index.js +1 -1
- package/dist/components/ThemeToggle/index.cjs +1 -1
- package/dist/components/ThemeToggle/index.js +1 -1
- package/dist/components/TimePicker/index.cjs +1 -1
- package/dist/components/TimePicker/index.js +1 -1
- package/dist/components/Toast/index.cjs +1 -1
- package/dist/components/Toast/index.js +1 -1
- package/dist/components/TranslatedFields/TranslatedFields.d.cts +1 -1
- package/dist/components/TranslatedFields/TranslatedFields.d.ts +1 -1
- package/dist/components/TranslatedFields/index.cjs +1 -1
- package/dist/components/TranslatedFields/index.js +1 -1
- package/dist/components/UserCard/UserCard.d.cts +6 -5
- package/dist/components/UserCard/UserCard.d.ts +6 -5
- package/dist/components/UserCard/index.cjs +1 -1
- package/dist/components/UserCard/index.js +1 -1
- package/dist/entries/app.cjs +1 -1
- package/dist/entries/app.js +1 -1
- package/dist/entries/components.cjs +1 -1
- package/dist/entries/components.js +56 -56
- package/dist/entries/i18n.cjs +1 -1
- package/dist/entries/i18n.js +2 -2
- package/dist/entries/theme.cjs +1 -1
- package/dist/entries/theme.d.cts +2 -2
- package/dist/entries/theme.d.ts +2 -2
- package/dist/entries/theme.js +12 -11
- package/dist/form/useForm.d.cts +1 -1
- package/dist/form/useForm.d.ts +1 -1
- package/dist/hooks/useMediaQuery.d.cts +3 -3
- package/dist/hooks/useMediaQuery.d.ts +3 -3
- package/dist/i18n/messages.d.cts +26 -0
- package/dist/i18n/messages.d.ts +26 -0
- package/dist/index.cjs +1 -1
- package/dist/index.css +3 -3
- package/dist/index.js +232 -231
- package/dist/{messages-CMgYU5p6.js → messages-BiRLMy1E.js} +228 -46
- package/dist/messages-BiRLMy1E.js.map +1 -0
- package/dist/messages-C_fRRCg6.cjs +36 -0
- package/dist/messages-C_fRRCg6.cjs.map +1 -0
- package/dist/theme/ConfigProvider.d.cts +47 -7
- package/dist/theme/ConfigProvider.d.ts +47 -7
- package/dist/theme/index.d.cts +2 -2
- package/dist/theme/index.d.ts +2 -2
- package/dist/useForm-CGbJ44Gp.js.map +1 -1
- package/dist/useForm-CSw6r1n1.cjs.map +1 -1
- package/dist/{useHomeTo-MfvJxziQ.cjs → useHomeTo-BaM7kBDh.cjs} +2 -2
- package/dist/{useHomeTo-MfvJxziQ.cjs.map → useHomeTo-BaM7kBDh.cjs.map} +1 -1
- package/dist/{useHomeTo-Ckq7scIY.js → useHomeTo-DQj9tVZI.js} +2 -2
- package/dist/{useHomeTo-Ckq7scIY.js.map → useHomeTo-DQj9tVZI.js.map} +1 -1
- package/dist/useMediaQuery-CHMrI6Dy.cjs.map +1 -1
- package/dist/useMediaQuery-DrDUrkmJ.js.map +1 -1
- package/dist/{useOptionMenu-3YlvxPAM.cjs → useOptionMenu-BKC1y6oj.cjs} +2 -2
- package/dist/{useOptionMenu-3YlvxPAM.cjs.map → useOptionMenu-BKC1y6oj.cjs.map} +1 -1
- package/dist/{useOptionMenu-BBsyUow1.js → useOptionMenu-Dom1-bqm.js} +5 -5
- package/dist/{useOptionMenu-BBsyUow1.js.map → useOptionMenu-Dom1-bqm.js.map} +1 -1
- package/package.json +1 -1
- package/dist/AdminRoot-CRTBGUxq.cjs +0 -2
- package/dist/AdminRoot-CRTBGUxq.cjs.map +0 -1
- package/dist/AdminRoot-JOgiNkJA.js +0 -107
- package/dist/AdminRoot-JOgiNkJA.js.map +0 -1
- package/dist/Alert-CY8iU1zd.cjs +0 -2
- package/dist/Alert-CY8iU1zd.cjs.map +0 -1
- package/dist/Alert-CtUr-0s8.js +0 -70
- package/dist/Alert-CtUr-0s8.js.map +0 -1
- package/dist/Breadcrumbs-Dqhk-dY2.js.map +0 -1
- package/dist/Breadcrumbs-hi6dJhfN.cjs.map +0 -1
- package/dist/Card-B91LGIzF.js +0 -128
- package/dist/Card-B91LGIzF.js.map +0 -1
- package/dist/Card-CkZtVNyV.cjs +0 -2
- package/dist/Card-CkZtVNyV.cjs.map +0 -1
- package/dist/Chip-B7cAHjlx.cjs.map +0 -1
- package/dist/Chip-D5ZZs3QH.js.map +0 -1
- package/dist/ChoiceCardGroup-143hR0v_.cjs +0 -2
- package/dist/ChoiceCardGroup-Cx8CtmPl.js +0 -180
- package/dist/ChoiceCardGroup-Cx8CtmPl.js.map +0 -1
- package/dist/CodeBlock-C3mG_seZ.cjs.map +0 -1
- package/dist/CodeBlock-DrWRSRmO.js.map +0 -1
- package/dist/ColorPicker-C1pDI4su.cjs +0 -2
- package/dist/ConfigProvider-B_Bb6pk1.cjs +0 -2
- package/dist/ConfigProvider-B_Bb6pk1.cjs.map +0 -1
- package/dist/ConfigProvider-DeMASTVo.js +0 -347
- package/dist/ConfigProvider-DeMASTVo.js.map +0 -1
- package/dist/DatePicker-CXRsT-lt.cjs +0 -2
- package/dist/DateTimePicker-B-Jjejzm.js.map +0 -1
- package/dist/DateTimePicker-BuTIRTUX.cjs +0 -2
- package/dist/DateTimePicker-BuTIRTUX.cjs.map +0 -1
- package/dist/DescriptionList-CG08_qwT.js.map +0 -1
- package/dist/DescriptionList-S9C6Tp90.cjs.map +0 -1
- package/dist/FileCard-5QvVkO1-.js.map +0 -1
- package/dist/FileCard-Cl88Gu6L.cjs.map +0 -1
- package/dist/FileUploader-DwAl3UXI.js.map +0 -1
- package/dist/FileUploader-FMVbj7rz.cjs.map +0 -1
- package/dist/ListItem-Qo1Tt6Fi.cjs +0 -2
- package/dist/Modal-DTnB_mGg.js.map +0 -1
- package/dist/Modal-DjSOhZqd.cjs.map +0 -1
- package/dist/OtpField-Dy4O1MeD.js +0 -174
- package/dist/OtpField-Dy4O1MeD.js.map +0 -1
- package/dist/OtpField-OdkuKKcV.cjs +0 -2
- package/dist/OtpField-OdkuKKcV.cjs.map +0 -1
- package/dist/PageLayout-ojiBEcxI.js.map +0 -1
- package/dist/PageLayout-rtEl8uqS.cjs.map +0 -1
- package/dist/Pagination-DoDGKGpQ.js +0 -139
- package/dist/Pagination-DoDGKGpQ.js.map +0 -1
- package/dist/Pagination-Ffv6IFIU.cjs +0 -2
- package/dist/Pagination-Ffv6IFIU.cjs.map +0 -1
- package/dist/PaletteField-ChG2VQtS.js +0 -54
- package/dist/PaletteField-ChG2VQtS.js.map +0 -1
- package/dist/PaletteField-DQ1OvXqe.cjs +0 -2
- package/dist/PaletteField-DQ1OvXqe.cjs.map +0 -1
- package/dist/QrCode-B9YbQNVc.js +0 -80
- package/dist/QrCode-B9YbQNVc.js.map +0 -1
- package/dist/QrCode-CNVYpz9j.cjs +0 -2
- package/dist/QrCode-CNVYpz9j.cjs.map +0 -1
- package/dist/RichTextEditor-DSvSaszc.cjs +0 -2
- package/dist/RichTextEditor-DSvSaszc.cjs.map +0 -1
- package/dist/RichTextEditor-itYD1PfE.js.map +0 -1
- package/dist/RootLayout-BlYjYAYk.js +0 -582
- package/dist/RootLayout-BlYjYAYk.js.map +0 -1
- package/dist/RootLayout-D5nlzYlH.cjs +0 -2
- package/dist/RootLayout-D5nlzYlH.cjs.map +0 -1
- package/dist/Sidebar-C3-u3Agj.cjs +0 -2
- package/dist/Slider-0joKXhPo.cjs +0 -2
- package/dist/Slider-0joKXhPo.cjs.map +0 -1
- package/dist/Slider-CwZYxDO0.js +0 -184
- package/dist/Slider-CwZYxDO0.js.map +0 -1
- package/dist/Stepper-BN0GsRZW.js.map +0 -1
- package/dist/Stepper-wPPs57uZ.cjs.map +0 -1
- package/dist/Table-CFl3OYlo.cjs.map +0 -1
- package/dist/Table-DChIfjqj.js.map +0 -1
- package/dist/TagsField-5mbyaFQZ.cjs +0 -2
- package/dist/TagsField-5mbyaFQZ.cjs.map +0 -1
- package/dist/TagsField-CoBRqcjW.js.map +0 -1
- package/dist/ThemeToggle-_SUmLxmU.js +0 -28
- package/dist/TimePicker-6nHQx0P5.cjs +0 -2
- package/dist/TranslatedFields-CVc0NvXa.cjs +0 -2
- package/dist/TranslatedFields-CVc0NvXa.cjs.map +0 -1
- package/dist/TranslatedFields-CmRhRGC_.js +0 -86
- package/dist/TranslatedFields-CmRhRGC_.js.map +0 -1
- package/dist/UserCard-1ubnvBV6.cjs.map +0 -1
- package/dist/UserCard-DcTLEHFu.js.map +0 -1
- package/dist/messages-CMgYU5p6.js.map +0 -1
- package/dist/messages-h22vS9zn.cjs +0 -36
- package/dist/messages-h22vS9zn.cjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Stepper-BN0GsRZW.js","sources":["../src/components/Stepper/Stepper.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useEffect,\n useRef,\n useState,\n type CSSProperties,\n type ReactNode,\n} from 'react'\nimport { clsx } from 'clsx'\nimport { removeQueryParam, useClearUrlOnUnmount } from '../../hooks/useClearUrlOnUnmount'\nimport { useStepQueryKey, type ThemeColor } from '../../theme'\nimport { ICON_NAMES, type IconName } from '../../icons/names'\nimport { Icon } from '../Icon'\nimport styles from './Stepper.module.css'\n\nconst ICON_NAME_SET = new Set<string>(ICON_NAMES)\n\nexport type StepperOrientation = 'horizontal' | 'vertical'\nexport type StepperSize = 'sm' | 'md' | 'lg'\n\nexport interface StepItem {\n /** Step label. */\n label?: ReactNode\n /** Muted secondary line under the label. */\n description?: ReactNode\n /** Muted caption under the label (e.g. `\"Optional\"`). */\n optional?: ReactNode\n /** Override the step's number indicator with an icon — a known `IconName` or any node. */\n icon?: IconName | ReactNode\n /** Force the **completed** look regardless of the active step (e.g. an already-saved step). */\n completed?: boolean\n /** Marks the step **invalid** — a red indicator + label (e.g. its form section failed validation). */\n error?: boolean\n /** Disables the step — dimmed, (when clickable) not selectable, and skipped by the URL restore. */\n disabled?: boolean\n /**\n * Panel content rendered while this step is active — **below the strip** in horizontal mode, and\n * **inline under the step** (indented beside the rail) in vertical mode. Optional.\n */\n content?: ReactNode\n}\n\nexport interface StepperProps {\n /** The steps, in order. */\n steps: StepItem[]\n /**\n * Controlled current step index (**0-based**). Steps before it read **completed**, the one at it is\n * **active**, and those after it are **upcoming**. Omit for uncontrolled (see `defaultStep`).\n */\n activeStep?: number\n /**\n * Initial step index (uncontrolled). Falls back to the URL query (when URL sync is active and the\n * param is present) and otherwise the first enabled step.\n */\n defaultStep?: number\n /**\n * Fires with the next step index whenever the stepper itself changes the step — a clicked step head,\n * or a Back/Forward `popstate` restore. In controlled mode apply it to your `activeStep` state.\n */\n onStepChange?: (index: number) => void\n /**\n * **Opt-in** URL sync — **off by default** (the URL is never touched when omitted). Pass the bare\n * prop (**`queryKey`** / `true`) to sync the active step under the configured `keys.stepQueryKey`\n * (else `'step'`), or a **string** for a custom param name. The URL value is **1-based**\n * (`?step=2` = index 1) and a page refresh restores it. Two synced steppers on one page need\n * distinct keys.\n */\n queryKey?: boolean | string\n /**\n * Push a history entry on each step change, so the browser **Back** button returns to the previous\n * step. Defaults to `false` — step changes **replace** the URL, so Back leaves the page instead of\n * stepping back through the wizard (and `popstate` still restores a step when one is in the query).\n */\n pushHistory?: boolean\n /**\n * With `queryKey` sync on, remove the step param when the stepper unmounts **on the same page** — a wizard\n * in a closing `Modal`, a finished flow swapped out — so `?step=3` doesn't outlive it. After a navigation to\n * another pathname nothing is touched. Defaults to `true`.\n */\n clearUrlOnUnmount?: boolean\n /**\n * Layout direction. `horizontal` (default) centers each label **under** its circle and **scrolls\n * sideways** when the steps don't fit (so it fits a phone as-is); `vertical` stacks the steps along\n * a rail connector.\n */\n orientation?: StepperOrientation\n /** Preset size. Defaults to `'md'`. */\n size?: StepperSize\n /** Theme palette token tinting the active / completed steps. Defaults to `'primary'`. */\n color?: ThemeColor\n /**\n * Makes steps **clickable** — each step head becomes a `<button>` that fires this with the step index\n * (a `disabled` step never fires); an uncontrolled stepper also selects the clicked step itself. Omit\n * for a display-only progress indicator.\n */\n onStepClick?: (index: number) => void\n /** Accessible label for the stepper list. */\n 'aria-label'?: string\n className?: string\n style?: CSSProperties\n}\n\n/**\n * A step progress indicator. Data-driven via `steps` (each: `label`, `description`, `optional`, `icon`,\n * `completed`, `error`, `disabled`, `content`) — controlled (`activeStep`, 0-based) or uncontrolled\n * (`defaultStep`). **Opt-in URL sync:** pass **`queryKey`** (bare/`true` = the configured\n * `keys.stepQueryKey`, else `'step'`; or a custom string) and the active step syncs to that query param\n * (**1-based** — `?step=2`) so a refresh restores it; with no `queryKey` the URL is never touched. A synced\n * stepper that unmounts on the same page removes its param again (`clearUrlOnUnmount`, default `true`).\n * Synced step changes **replace** the URL (Back doesn't walk the wizard); pass **`pushHistory`** to\n * step back with Back.\n * Horizontal (labels centered under the circles) or `vertical` (a rail); when the horizontal steps\n * don't fit, the strip **scrolls sideways** (scrollbar hidden, the active step kept in view) — so it\n * fits a phone as-is. The active step's **`content`** renders below the strip (horizontal) or inline\n * under the step (vertical). Pass **`onStepClick`** to make the steps navigable. Tinted by `color` via\n * the shared `--tz-btn-rgb` pattern; the list is an `<ol>` with `aria-current=\"step\"` on the active step.\n */\nexport const Stepper = forwardRef<HTMLDivElement, StepperProps>(function Stepper(\n {\n steps,\n activeStep,\n defaultStep,\n onStepChange,\n queryKey,\n pushHistory = false,\n clearUrlOnUnmount = true,\n orientation = 'horizontal',\n size = 'md',\n color = 'primary',\n onStepClick,\n 'aria-label': ariaLabel,\n className,\n style,\n },\n ref,\n) {\n const vertical = orientation === 'vertical'\n const clickable = onStepClick != null\n\n // resolve the URL-sync key — OPT-IN: omitted/false = no sync (URL untouched); the bare/`true` form\n // uses the configured default (`keys.stepQueryKey`, else 'step'); a string is a custom param name\n const stepQueryKey = useStepQueryKey()\n const syncKey = queryKey === true ? stepQueryKey : queryKey || undefined\n\n const isSelectable = useCallback(\n (i: number | null | undefined): i is number =>\n i != null && Number.isInteger(i) && i >= 0 && i < steps.length && !steps[i].disabled,\n [steps],\n )\n\n // the URL carries the step 1-based (`?step=2` = index 1) — human-friendly, like Table's page param\n const readQuery = useCallback((): number | null => {\n if (!syncKey || typeof window === 'undefined') return null\n const raw = new URLSearchParams(window.location.search).get(syncKey)\n return raw != null && /^\\d+$/.test(raw) ? Number(raw) - 1 : null\n }, [syncKey])\n\n const firstEnabled = Math.max(\n steps.findIndex((s) => !s.disabled),\n 0,\n )\n\n const [internal, setInternal] = useState<number>(() => {\n const q = readQuery()\n if (isSelectable(q)) return q\n return isSelectable(defaultStep) ? defaultStep : firstEnabled\n })\n const isControlled = activeStep !== undefined\n // controlled mode renders the given index verbatim (even past the last step — the \"all completed\"\n // pattern); only the URL/popstate restores are gated by `isSelectable`\n const active = isControlled ? activeStep : internal\n\n // keep the latest active / onStepChange / push-intent for the stable effects + popstate listener\n const activeRef = useRef(active)\n activeRef.current = active\n const onStepChangeRef = useRef(onStepChange)\n onStepChangeRef.current = onStepChange\n const pushIntent = useRef(false)\n\n const writeQuery = useCallback(\n (next: number, push: boolean) => {\n if (!syncKey || typeof window === 'undefined') return\n const params = new URLSearchParams(window.location.search)\n const value = String(next + 1)\n if (params.get(syncKey) === value) return\n params.set(syncKey, value)\n const url = `${window.location.pathname}?${params.toString()}${window.location.hash}`\n window.history[push ? 'pushState' : 'replaceState'](window.history.state, '', url)\n },\n [syncKey],\n )\n\n const select = (next: number) => {\n if (next === activeRef.current) return\n pushIntent.current = true\n if (!isControlled) setInternal(next)\n onStepChange?.(next)\n }\n\n // mirror the active step into the URL whenever it changes (and on mount = canonicalize). A\n // user-driven change `push`es when `pushHistory`; programmatic / popstate changes just `replace`.\n useEffect(() => {\n if (!syncKey || typeof window === 'undefined') return\n // an out-of-range active (e.g. `steps.length` = \"all done\") isn't a step — leave the URL alone\n if (!Number.isInteger(active) || active < 0 || active >= steps.length) return\n const push = pushIntent.current && pushHistory\n pushIntent.current = false\n writeQuery(active, push)\n }, [syncKey, active, pushHistory, writeQuery, steps.length])\n\n // unmount on the same page → drop the step param (shared rule: not after a navigation, StrictMode-safe)\n useClearUrlOnUnmount(syncKey, clearUrlOnUnmount, () => {\n if (syncKey) removeQueryParam(syncKey)\n })\n\n // Back/Forward → restore the step from the query\n useEffect(() => {\n if (!syncKey || typeof window === 'undefined') return\n const onPopState = () => {\n const q = readQuery()\n if (isSelectable(q) && q !== activeRef.current) {\n if (activeStep === undefined) setInternal(q)\n onStepChangeRef.current?.(q)\n }\n }\n window.addEventListener('popstate', onPopState)\n return () => window.removeEventListener('popstate', onPopState)\n }, [syncKey, readQuery, isSelectable, activeStep])\n\n const activeContent = steps[active]?.content\n\n // when the horizontal strip overflows (scrolls sideways), keep the active step in view — by moving\n // the strip's own scrollLeft only. (scrollIntoView would also scroll every scrollable ancestor —\n // i.e. the page itself — yanking the viewport down to the stepper on mount.)\n const listRef = useRef<HTMLOListElement | null>(null)\n useEffect(() => {\n if (orientation === 'vertical') return // the vertical rail never scrolls sideways\n const list = listRef.current\n const el = list?.children[active] as HTMLElement | undefined\n if (!list || !el) return\n const listRect = list.getBoundingClientRect()\n const elRect = el.getBoundingClientRect()\n const left = elRect.left - listRect.left + list.scrollLeft\n const right = left + elRect.width\n if (left < list.scrollLeft) list.scrollLeft = left\n else if (right > list.scrollLeft + list.clientWidth) list.scrollLeft = right - list.clientWidth\n }, [active, orientation])\n\n const renderIcon = (icon: StepItem['icon']) =>\n typeof icon === 'string' && ICON_NAME_SET.has(icon) ? (\n <Icon name={icon as IconName} size={size} />\n ) : (\n icon\n )\n\n return (\n <div\n ref={ref}\n className={clsx(styles.root, styles[orientation], styles[size], className)}\n style={\n {\n '--tz-btn-rgb': `var(--tz-color-${color}-rgb)`,\n '--tz-btn-on': `var(--tz-color-${color}-contrast, #fff)`,\n ...style,\n } as CSSProperties\n }\n >\n <ol ref={listRef} aria-label={ariaLabel} className={styles.list}>\n {steps.map((step, i) => {\n const isError = !!step.error\n const isCompleted = !isError && (step.completed || i < active)\n const isActive = !isError && !isCompleted && i === active\n const state = isError\n ? 'error'\n : isCompleted\n ? 'completed'\n : isActive\n ? 'active'\n : 'upcoming'\n const isLast = i === steps.length - 1\n\n const icon = renderIcon(step.icon)\n const indicator =\n icon != null ? (\n icon\n ) : isCompleted ? (\n <Icon name=\"Check\" size={size} />\n ) : (\n <span className={styles.number}>{i + 1}</span>\n )\n\n const hasText = step.label != null || step.description != null || step.optional != null\n const head = (\n <>\n <span\n className={styles.indicator}\n aria-hidden={icon == null && !isCompleted ? undefined : true}\n >\n {indicator}\n </span>\n {hasText && (\n <span className={styles.text}>\n {step.label != null && <span className={styles.label}>{step.label}</span>}\n {step.description != null && (\n <span className={styles.description}>{step.description}</span>\n )}\n {step.optional != null && (\n <span className={styles.optional}>{step.optional}</span>\n )}\n </span>\n )}\n </>\n )\n\n return (\n <li\n key={i}\n className={clsx(styles.step, styles[state], step.disabled && styles.disabled)}\n >\n {clickable ? (\n <button\n type=\"button\"\n className={styles.main}\n disabled={step.disabled}\n aria-current={isActive ? 'step' : undefined}\n onClick={() => {\n onStepClick?.(i)\n select(i)\n }}\n >\n {head}\n </button>\n ) : (\n <div className={styles.main} aria-current={isActive ? 'step' : undefined}>\n {head}\n </div>\n )}\n {!isLast && (\n <span\n className={clsx(styles.connector, i < active && styles.done)}\n aria-hidden=\"true\"\n />\n )}\n {/* vertical: the active step's content sits inline, indented beside the rail */}\n {vertical && i === active && step.content != null && (\n <div className={styles.stepContent}>{step.content}</div>\n )}\n </li>\n )\n })}\n </ol>\n {/* horizontal: the active step's content renders as a panel below the strip */}\n {!vertical && activeContent != null && <div className={styles.panel}>{activeContent}</div>}\n </div>\n )\n})\n"],"names":["ICON_NAME_SET","ICON_NAMES","Stepper","forwardRef","steps","activeStep","defaultStep","onStepChange","queryKey","pushHistory","clearUrlOnUnmount","orientation","size","color","onStepClick","ariaLabel","className","style","ref","vertical","clickable","stepQueryKey","useStepQueryKey","syncKey","isSelectable","useCallback","i","readQuery","raw","firstEnabled","s","internal","setInternal","useState","q","isControlled","active","activeRef","useRef","onStepChangeRef","pushIntent","writeQuery","next","push","params","value","url","select","useEffect","useClearUrlOnUnmount","onPopState","_a","activeContent","listRef","list","el","listRect","elRect","left","right","renderIcon","icon","jsx","Icon","jsxs","clsx","styles","step","isError","isCompleted","isActive","state","isLast","indicator","hasText","head","Fragment"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Stepper-wPPs57uZ.cjs","sources":["../src/components/Stepper/Stepper.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useEffect,\n useRef,\n useState,\n type CSSProperties,\n type ReactNode,\n} from 'react'\nimport { clsx } from 'clsx'\nimport { removeQueryParam, useClearUrlOnUnmount } from '../../hooks/useClearUrlOnUnmount'\nimport { useStepQueryKey, type ThemeColor } from '../../theme'\nimport { ICON_NAMES, type IconName } from '../../icons/names'\nimport { Icon } from '../Icon'\nimport styles from './Stepper.module.css'\n\nconst ICON_NAME_SET = new Set<string>(ICON_NAMES)\n\nexport type StepperOrientation = 'horizontal' | 'vertical'\nexport type StepperSize = 'sm' | 'md' | 'lg'\n\nexport interface StepItem {\n /** Step label. */\n label?: ReactNode\n /** Muted secondary line under the label. */\n description?: ReactNode\n /** Muted caption under the label (e.g. `\"Optional\"`). */\n optional?: ReactNode\n /** Override the step's number indicator with an icon — a known `IconName` or any node. */\n icon?: IconName | ReactNode\n /** Force the **completed** look regardless of the active step (e.g. an already-saved step). */\n completed?: boolean\n /** Marks the step **invalid** — a red indicator + label (e.g. its form section failed validation). */\n error?: boolean\n /** Disables the step — dimmed, (when clickable) not selectable, and skipped by the URL restore. */\n disabled?: boolean\n /**\n * Panel content rendered while this step is active — **below the strip** in horizontal mode, and\n * **inline under the step** (indented beside the rail) in vertical mode. Optional.\n */\n content?: ReactNode\n}\n\nexport interface StepperProps {\n /** The steps, in order. */\n steps: StepItem[]\n /**\n * Controlled current step index (**0-based**). Steps before it read **completed**, the one at it is\n * **active**, and those after it are **upcoming**. Omit for uncontrolled (see `defaultStep`).\n */\n activeStep?: number\n /**\n * Initial step index (uncontrolled). Falls back to the URL query (when URL sync is active and the\n * param is present) and otherwise the first enabled step.\n */\n defaultStep?: number\n /**\n * Fires with the next step index whenever the stepper itself changes the step — a clicked step head,\n * or a Back/Forward `popstate` restore. In controlled mode apply it to your `activeStep` state.\n */\n onStepChange?: (index: number) => void\n /**\n * **Opt-in** URL sync — **off by default** (the URL is never touched when omitted). Pass the bare\n * prop (**`queryKey`** / `true`) to sync the active step under the configured `keys.stepQueryKey`\n * (else `'step'`), or a **string** for a custom param name. The URL value is **1-based**\n * (`?step=2` = index 1) and a page refresh restores it. Two synced steppers on one page need\n * distinct keys.\n */\n queryKey?: boolean | string\n /**\n * Push a history entry on each step change, so the browser **Back** button returns to the previous\n * step. Defaults to `false` — step changes **replace** the URL, so Back leaves the page instead of\n * stepping back through the wizard (and `popstate` still restores a step when one is in the query).\n */\n pushHistory?: boolean\n /**\n * With `queryKey` sync on, remove the step param when the stepper unmounts **on the same page** — a wizard\n * in a closing `Modal`, a finished flow swapped out — so `?step=3` doesn't outlive it. After a navigation to\n * another pathname nothing is touched. Defaults to `true`.\n */\n clearUrlOnUnmount?: boolean\n /**\n * Layout direction. `horizontal` (default) centers each label **under** its circle and **scrolls\n * sideways** when the steps don't fit (so it fits a phone as-is); `vertical` stacks the steps along\n * a rail connector.\n */\n orientation?: StepperOrientation\n /** Preset size. Defaults to `'md'`. */\n size?: StepperSize\n /** Theme palette token tinting the active / completed steps. Defaults to `'primary'`. */\n color?: ThemeColor\n /**\n * Makes steps **clickable** — each step head becomes a `<button>` that fires this with the step index\n * (a `disabled` step never fires); an uncontrolled stepper also selects the clicked step itself. Omit\n * for a display-only progress indicator.\n */\n onStepClick?: (index: number) => void\n /** Accessible label for the stepper list. */\n 'aria-label'?: string\n className?: string\n style?: CSSProperties\n}\n\n/**\n * A step progress indicator. Data-driven via `steps` (each: `label`, `description`, `optional`, `icon`,\n * `completed`, `error`, `disabled`, `content`) — controlled (`activeStep`, 0-based) or uncontrolled\n * (`defaultStep`). **Opt-in URL sync:** pass **`queryKey`** (bare/`true` = the configured\n * `keys.stepQueryKey`, else `'step'`; or a custom string) and the active step syncs to that query param\n * (**1-based** — `?step=2`) so a refresh restores it; with no `queryKey` the URL is never touched. A synced\n * stepper that unmounts on the same page removes its param again (`clearUrlOnUnmount`, default `true`).\n * Synced step changes **replace** the URL (Back doesn't walk the wizard); pass **`pushHistory`** to\n * step back with Back.\n * Horizontal (labels centered under the circles) or `vertical` (a rail); when the horizontal steps\n * don't fit, the strip **scrolls sideways** (scrollbar hidden, the active step kept in view) — so it\n * fits a phone as-is. The active step's **`content`** renders below the strip (horizontal) or inline\n * under the step (vertical). Pass **`onStepClick`** to make the steps navigable. Tinted by `color` via\n * the shared `--tz-btn-rgb` pattern; the list is an `<ol>` with `aria-current=\"step\"` on the active step.\n */\nexport const Stepper = forwardRef<HTMLDivElement, StepperProps>(function Stepper(\n {\n steps,\n activeStep,\n defaultStep,\n onStepChange,\n queryKey,\n pushHistory = false,\n clearUrlOnUnmount = true,\n orientation = 'horizontal',\n size = 'md',\n color = 'primary',\n onStepClick,\n 'aria-label': ariaLabel,\n className,\n style,\n },\n ref,\n) {\n const vertical = orientation === 'vertical'\n const clickable = onStepClick != null\n\n // resolve the URL-sync key — OPT-IN: omitted/false = no sync (URL untouched); the bare/`true` form\n // uses the configured default (`keys.stepQueryKey`, else 'step'); a string is a custom param name\n const stepQueryKey = useStepQueryKey()\n const syncKey = queryKey === true ? stepQueryKey : queryKey || undefined\n\n const isSelectable = useCallback(\n (i: number | null | undefined): i is number =>\n i != null && Number.isInteger(i) && i >= 0 && i < steps.length && !steps[i].disabled,\n [steps],\n )\n\n // the URL carries the step 1-based (`?step=2` = index 1) — human-friendly, like Table's page param\n const readQuery = useCallback((): number | null => {\n if (!syncKey || typeof window === 'undefined') return null\n const raw = new URLSearchParams(window.location.search).get(syncKey)\n return raw != null && /^\\d+$/.test(raw) ? Number(raw) - 1 : null\n }, [syncKey])\n\n const firstEnabled = Math.max(\n steps.findIndex((s) => !s.disabled),\n 0,\n )\n\n const [internal, setInternal] = useState<number>(() => {\n const q = readQuery()\n if (isSelectable(q)) return q\n return isSelectable(defaultStep) ? defaultStep : firstEnabled\n })\n const isControlled = activeStep !== undefined\n // controlled mode renders the given index verbatim (even past the last step — the \"all completed\"\n // pattern); only the URL/popstate restores are gated by `isSelectable`\n const active = isControlled ? activeStep : internal\n\n // keep the latest active / onStepChange / push-intent for the stable effects + popstate listener\n const activeRef = useRef(active)\n activeRef.current = active\n const onStepChangeRef = useRef(onStepChange)\n onStepChangeRef.current = onStepChange\n const pushIntent = useRef(false)\n\n const writeQuery = useCallback(\n (next: number, push: boolean) => {\n if (!syncKey || typeof window === 'undefined') return\n const params = new URLSearchParams(window.location.search)\n const value = String(next + 1)\n if (params.get(syncKey) === value) return\n params.set(syncKey, value)\n const url = `${window.location.pathname}?${params.toString()}${window.location.hash}`\n window.history[push ? 'pushState' : 'replaceState'](window.history.state, '', url)\n },\n [syncKey],\n )\n\n const select = (next: number) => {\n if (next === activeRef.current) return\n pushIntent.current = true\n if (!isControlled) setInternal(next)\n onStepChange?.(next)\n }\n\n // mirror the active step into the URL whenever it changes (and on mount = canonicalize). A\n // user-driven change `push`es when `pushHistory`; programmatic / popstate changes just `replace`.\n useEffect(() => {\n if (!syncKey || typeof window === 'undefined') return\n // an out-of-range active (e.g. `steps.length` = \"all done\") isn't a step — leave the URL alone\n if (!Number.isInteger(active) || active < 0 || active >= steps.length) return\n const push = pushIntent.current && pushHistory\n pushIntent.current = false\n writeQuery(active, push)\n }, [syncKey, active, pushHistory, writeQuery, steps.length])\n\n // unmount on the same page → drop the step param (shared rule: not after a navigation, StrictMode-safe)\n useClearUrlOnUnmount(syncKey, clearUrlOnUnmount, () => {\n if (syncKey) removeQueryParam(syncKey)\n })\n\n // Back/Forward → restore the step from the query\n useEffect(() => {\n if (!syncKey || typeof window === 'undefined') return\n const onPopState = () => {\n const q = readQuery()\n if (isSelectable(q) && q !== activeRef.current) {\n if (activeStep === undefined) setInternal(q)\n onStepChangeRef.current?.(q)\n }\n }\n window.addEventListener('popstate', onPopState)\n return () => window.removeEventListener('popstate', onPopState)\n }, [syncKey, readQuery, isSelectable, activeStep])\n\n const activeContent = steps[active]?.content\n\n // when the horizontal strip overflows (scrolls sideways), keep the active step in view — by moving\n // the strip's own scrollLeft only. (scrollIntoView would also scroll every scrollable ancestor —\n // i.e. the page itself — yanking the viewport down to the stepper on mount.)\n const listRef = useRef<HTMLOListElement | null>(null)\n useEffect(() => {\n if (orientation === 'vertical') return // the vertical rail never scrolls sideways\n const list = listRef.current\n const el = list?.children[active] as HTMLElement | undefined\n if (!list || !el) return\n const listRect = list.getBoundingClientRect()\n const elRect = el.getBoundingClientRect()\n const left = elRect.left - listRect.left + list.scrollLeft\n const right = left + elRect.width\n if (left < list.scrollLeft) list.scrollLeft = left\n else if (right > list.scrollLeft + list.clientWidth) list.scrollLeft = right - list.clientWidth\n }, [active, orientation])\n\n const renderIcon = (icon: StepItem['icon']) =>\n typeof icon === 'string' && ICON_NAME_SET.has(icon) ? (\n <Icon name={icon as IconName} size={size} />\n ) : (\n icon\n )\n\n return (\n <div\n ref={ref}\n className={clsx(styles.root, styles[orientation], styles[size], className)}\n style={\n {\n '--tz-btn-rgb': `var(--tz-color-${color}-rgb)`,\n '--tz-btn-on': `var(--tz-color-${color}-contrast, #fff)`,\n ...style,\n } as CSSProperties\n }\n >\n <ol ref={listRef} aria-label={ariaLabel} className={styles.list}>\n {steps.map((step, i) => {\n const isError = !!step.error\n const isCompleted = !isError && (step.completed || i < active)\n const isActive = !isError && !isCompleted && i === active\n const state = isError\n ? 'error'\n : isCompleted\n ? 'completed'\n : isActive\n ? 'active'\n : 'upcoming'\n const isLast = i === steps.length - 1\n\n const icon = renderIcon(step.icon)\n const indicator =\n icon != null ? (\n icon\n ) : isCompleted ? (\n <Icon name=\"Check\" size={size} />\n ) : (\n <span className={styles.number}>{i + 1}</span>\n )\n\n const hasText = step.label != null || step.description != null || step.optional != null\n const head = (\n <>\n <span\n className={styles.indicator}\n aria-hidden={icon == null && !isCompleted ? undefined : true}\n >\n {indicator}\n </span>\n {hasText && (\n <span className={styles.text}>\n {step.label != null && <span className={styles.label}>{step.label}</span>}\n {step.description != null && (\n <span className={styles.description}>{step.description}</span>\n )}\n {step.optional != null && (\n <span className={styles.optional}>{step.optional}</span>\n )}\n </span>\n )}\n </>\n )\n\n return (\n <li\n key={i}\n className={clsx(styles.step, styles[state], step.disabled && styles.disabled)}\n >\n {clickable ? (\n <button\n type=\"button\"\n className={styles.main}\n disabled={step.disabled}\n aria-current={isActive ? 'step' : undefined}\n onClick={() => {\n onStepClick?.(i)\n select(i)\n }}\n >\n {head}\n </button>\n ) : (\n <div className={styles.main} aria-current={isActive ? 'step' : undefined}>\n {head}\n </div>\n )}\n {!isLast && (\n <span\n className={clsx(styles.connector, i < active && styles.done)}\n aria-hidden=\"true\"\n />\n )}\n {/* vertical: the active step's content sits inline, indented beside the rail */}\n {vertical && i === active && step.content != null && (\n <div className={styles.stepContent}>{step.content}</div>\n )}\n </li>\n )\n })}\n </ol>\n {/* horizontal: the active step's content renders as a panel below the strip */}\n {!vertical && activeContent != null && <div className={styles.panel}>{activeContent}</div>}\n </div>\n )\n})\n"],"names":["ICON_NAME_SET","ICON_NAMES","Stepper","forwardRef","steps","activeStep","defaultStep","onStepChange","queryKey","pushHistory","clearUrlOnUnmount","orientation","size","color","onStepClick","ariaLabel","className","style","ref","vertical","clickable","stepQueryKey","useStepQueryKey","syncKey","isSelectable","useCallback","i","readQuery","raw","firstEnabled","s","internal","setInternal","useState","q","isControlled","active","activeRef","useRef","onStepChangeRef","pushIntent","writeQuery","next","push","params","value","url","select","useEffect","useClearUrlOnUnmount","onPopState","_a","activeContent","listRef","list","el","listRect","elRect","left","right","renderIcon","icon","jsx","Icon","jsxs","clsx","styles","step","isError","isCompleted","isActive","state","isLast","indicator","hasText","head","Fragment"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Table-CFl3OYlo.cjs","sources":["../src/components/Table/tableFilter.ts","../src/components/Table/TableFilters.tsx","../src/components/Table/Table.tsx"],"sourcesContent":["// Table filters — the declarative filter model + the pure local matcher. `applyFilters` is used by the\n// Table in local mode (client-side) and is pure/testable; server mode just emits the filter state in\n// `onChange`. Core filter types only (text / number / range / select / radio / multi / boolean / date / dateRange).\nimport type { TableQueryConfig } from '../../theme'\nimport type { SelectOption } from '../Select'\n\n/** Which control + matching logic a filter uses. */\nexport type TableFilterType =\n | 'text'\n | 'number'\n | 'numberRange'\n | 'numberRangeSlider'\n | 'select'\n | 'radio'\n | 'multiSelect'\n | 'boolean'\n | 'date'\n | 'dateRange'\n | 'time'\n | 'timeRange'\n | 'dateTime'\n | 'dateTimeRange'\n\n/** The value a single filter holds — shape depends on its `type` (see each control). `null` / empty = off. */\nexport type TableFilterValue =\n | string // text · select · radio · date · time · dateTime\n | number // number\n | boolean // boolean\n | string[] // multiSelect\n | [number | null, number | null] // numberRange · numberRangeSlider [min, max]\n | [string, string] // dateRange · timeRange · dateTimeRange [from, to]\n | null\n\n/** A declarative filter definition — like a column, but for the filter panel. */\nexport interface TableFilter {\n /** Field key on the row — the local accessor + the key in the emitted filter state. */\n key: string\n /** Label shown in the filter panel. */\n label: string\n /** The filter's control + matching logic. */\n type: TableFilterType\n /** Options for `select` / `radio` / `multiSelect` (`radio` uses each option's `value` / `label` / `disabled`). */\n options?: SelectOption[]\n /** Placeholder for the input(s). */\n placeholder?: string\n /**\n * Param name this filter serializes to in the **server-request** query (`state.query`). Defaults to\n * `key`. Set it to rename or bake in an operator — e.g. `'name_like'`, `'q'`, `'status'`. Range filters\n * append the `rangeMin/MaxSuffix` to this.\n */\n queryKey?: string\n /** `numberRange` slider bounds + step (defaults `0` / `100` / `1`) — set to match the column's data range. */\n min?: number\n max?: number\n step?: number\n /**\n * Labels for a `boolean` filter's three radios (defaults `Any` / `Yes` / `No`) — e.g.\n * `{ any: 'All', yes: 'In stock', no: 'Sold out' }`.\n */\n booleanLabels?: { any?: string; yes?: string; no?: string }\n /**\n * `radio` only — the label of the leading \"no filter\" radio (defaults to the localized `Any`), e.g.\n * `'All'` / `'All Statuses'`.\n */\n anyLabel?: string\n /**\n * `radio` only — how the radios are laid out. Defaults to `vertical` (a list reads best stacked); set\n * `horizontal` to keep a short list on one line.\n */\n orientation?: 'horizontal' | 'vertical'\n}\n\n/** The active filter values, keyed by filter `key`. */\nexport type TableFilterState = Record<string, TableFilterValue>\n\n/** Whether a filter value is \"set\" (should actually filter) — an empty string / array / all-null range is off. */\nexport function isFilterActive(\n type: TableFilterType,\n value: TableFilterValue | undefined,\n): boolean {\n if (value == null) return false\n switch (type) {\n case 'number':\n return typeof value === 'number' && !Number.isNaN(value)\n case 'boolean':\n return typeof value === 'boolean'\n case 'multiSelect':\n return Array.isArray(value) && value.length > 0\n case 'numberRange':\n case 'numberRangeSlider':\n return Array.isArray(value) && (value[0] != null || value[1] != null)\n case 'dateRange':\n case 'timeRange':\n case 'dateTimeRange':\n return Array.isArray(value) && Boolean(value[0] || value[1])\n default: // text · select · radio · date · time · dateTime\n return typeof value === 'string' && value.trim() !== ''\n }\n}\n\n/** Number of filters currently set — drives the count badge on the Filters button. */\nexport function activeFilterCount(filters: TableFilter[], state: TableFilterState): number {\n return filters.reduce((n, f) => (isFilterActive(f.type, state[f.key]) ? n + 1 : n), 0)\n}\n\n// Comparable substrings of an ISO-ish value, normalized to the viewer's LOCAL calendar so both the\n// row and the filter are reduced the same way (lexical compare then works). Without this, a UTC\n// timestamp near midnight (`…T23:30:00Z`) slices to a different day than the local day the user picked\n// and silently drops out. A full timestamp (with `Z`/offset) converts to local; a bare date/time is\n// read as local wall-clock (so it stays on the day/minute picked); anything unparseable falls back to\n// the raw slice. `date` → day, `dateTime` → to the minute, `time` → HH:mm.\nconst pad = (n: number) => String(n).padStart(2, '0')\nconst localDay = (d: Date) => `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`\nconst localMinute = (d: Date) => `${localDay(d)}T${pad(d.getHours())}:${pad(d.getMinutes())}`\nconst localTime = (d: Date) => `${pad(d.getHours())}:${pad(d.getMinutes())}`\n\n/** Parse an ISO-ish value to a Date; a bare `YYYY-MM-DD` is read as LOCAL midnight (not UTC). */\nconst toLocalDate = (s: string): Date | null => {\n if (!s) return null\n const iso = /^\\d{4}-\\d{2}-\\d{2}$/.test(s) ? `${s}T00:00:00` : s\n const d = new Date(iso)\n return Number.isNaN(d.getTime()) ? null : d\n}\n\nconst datePart = (s: string) => {\n const d = toLocalDate(s)\n return d ? localDay(d) : s.slice(0, 10)\n}\nconst dateTimePart = (s: string) => {\n const d = toLocalDate(s)\n return d ? localMinute(d) : s.slice(0, 16)\n}\nconst timePart = (s: string) => {\n // a full timestamp → its local HH:mm; a bare `HH:mm[:ss]` → its own HH:mm\n if (/\\d{4}-\\d{2}-\\d{2}/.test(s)) {\n const d = toLocalDate(s)\n if (d) return localTime(d)\n }\n return (s.includes('T') ? s.slice(s.indexOf('T') + 1) : s).slice(0, 5)\n}\n\n/** Does one row's cell value match one active filter? */\nfunction matchOne(type: TableFilterType, cell: unknown, value: TableFilterValue): boolean {\n const s = String(cell ?? '')\n switch (type) {\n case 'text':\n return s.toLowerCase().includes(String(value).toLowerCase())\n case 'number':\n return Number(cell) === value\n case 'numberRange':\n case 'numberRangeSlider': {\n const [min, max] = value as [number | null, number | null]\n const n = Number(cell)\n return (min == null || n >= min) && (max == null || n <= max)\n }\n case 'select':\n case 'radio':\n return s === value\n case 'multiSelect':\n return (value as string[]).includes(s)\n case 'boolean':\n return Boolean(cell) === value\n case 'date':\n return datePart(s) === datePart(String(value))\n case 'dateTime':\n return dateTimePart(s) === dateTimePart(String(value))\n case 'time':\n return timePart(s) === timePart(String(value))\n case 'dateRange':\n case 'dateTimeRange': {\n const part = type === 'dateRange' ? datePart : dateTimePart\n const [from, to] = value as [string, string]\n const d = part(s) // ISO strings compare lexicographically at the same precision\n return (!from || d >= part(from)) && (!to || d <= part(to))\n }\n case 'timeRange': {\n const [from, to] = value as [string, string]\n const t = timePart(s)\n return (!from || t >= timePart(from)) && (!to || t <= timePart(to))\n }\n default:\n return true\n }\n}\n\n/**\n * Filter rows client-side against the active filter values (local mode). A row is kept only when it matches\n * **every** active filter (AND). Filters that aren't set are skipped, so an empty state returns all rows.\n * Pure — no React, no mutation.\n */\nexport function applyFilters<T>(rows: T[], filters: TableFilter[], state: TableFilterState): T[] {\n const active = filters.filter((f) => isFilterActive(f.type, state[f.key]))\n if (active.length === 0) return rows\n return rows.filter((row) =>\n active.every((f) => matchOne(f.type, (row as Record<string, unknown>)[f.key], state[f.key]!)),\n )\n}\n\n// ── server-request query (⇄ URL) ───────────────────────────────────────────────────\n/**\n * Serialize the active filters into **server-request** params (folded into `state.query` alongside\n * page/size/search/sort). Each filter uses its `queryKey ?? key`; scalars emit `param=value`, a\n * `multiSelect` emits repeated / CSV / indexed params (`multiSelectFormat`), and ranges emit two params\n * `<param><rangeMinSuffix>` / `<param><rangeMaxSuffix>` (defaults `Min`/`Max`) — only for the set bound.\n * Config-driven via the shared `TableQueryConfig`; inactive filters are skipped.\n */\nexport function buildFilterQuery(\n filters: TableFilter[],\n state: TableFilterState,\n mapping: TableQueryConfig = {},\n): URLSearchParams {\n const params = new URLSearchParams()\n const minSuffix = mapping.rangeMinSuffix ?? 'Min'\n const maxSuffix = mapping.rangeMaxSuffix ?? 'Max'\n const multiFormat = mapping.multiSelectFormat ?? 'repeat'\n\n for (const f of filters) {\n const value = state[f.key]\n if (!isFilterActive(f.type, value)) continue\n const param = f.queryKey ?? f.key\n switch (f.type) {\n case 'multiSelect': {\n const arr = value as string[]\n if (multiFormat === 'csv')\n params.set(param, arr.join(',')) // cat=a,b\n else if (multiFormat === 'indexed')\n arr.forEach((v, i) => params.set(`${param}[${i}]`, v)) // cat[0]=a&cat[1]=b\n else arr.forEach((v) => params.append(param, v)) // repeat → cat=a&cat=b\n break\n }\n case 'numberRange':\n case 'numberRangeSlider': {\n const [min, max] = value as [number | null, number | null]\n if (min != null) params.set(param + minSuffix, String(min))\n if (max != null) params.set(param + maxSuffix, String(max))\n break\n }\n case 'dateRange':\n case 'timeRange':\n case 'dateTimeRange': {\n const [from, to] = value as [string, string]\n if (from) params.set(param + minSuffix, from)\n if (to) params.set(param + maxSuffix, to)\n break\n }\n default: // text · number · select · radio · boolean · date · time · dateTime\n params.set(param, String(value))\n }\n }\n return params\n}\n\n/**\n * Read the active filter values back out of URL / request params — the **inverse of `buildFilterQuery`** for\n * the same `mapping` + filter defs (each filter's `queryKey ?? key`, the `multiSelectFormat`, the range\n * suffixes). Used by `<Table>` to restore URL-synced filters on mount / Back-Forward. Only present params\n * produce a value; the rest stay unset.\n */\nexport function parseFilterQuery(\n filters: TableFilter[],\n params: URLSearchParams,\n mapping: TableQueryConfig = {},\n): TableFilterState {\n const minSuffix = mapping.rangeMinSuffix ?? 'Min'\n const maxSuffix = mapping.rangeMaxSuffix ?? 'Max'\n const multiFormat = mapping.multiSelectFormat ?? 'repeat'\n const state: TableFilterState = {}\n\n for (const f of filters) {\n const param = f.queryKey ?? f.key\n switch (f.type) {\n case 'multiSelect': {\n let arr: string[] = []\n if (multiFormat === 'csv') {\n const v = params.get(param)\n if (v) arr = v.split(',').filter(Boolean)\n } else if (multiFormat === 'indexed') {\n for (let i = 0; params.has(`${param}[${i}]`); i++) arr.push(params.get(`${param}[${i}]`)!)\n } else {\n arr = params.getAll(param)\n }\n if (arr.length) state[f.key] = arr\n break\n }\n case 'numberRange':\n case 'numberRangeSlider': {\n const lo = params.get(param + minSuffix)\n const hi = params.get(param + maxSuffix)\n if (lo != null || hi != null) {\n state[f.key] = [lo != null ? Number(lo) : null, hi != null ? Number(hi) : null]\n }\n break\n }\n case 'dateRange':\n case 'timeRange':\n case 'dateTimeRange': {\n const from = params.get(param + minSuffix)\n const to = params.get(param + maxSuffix)\n if (from != null || to != null) state[f.key] = [from ?? '', to ?? '']\n break\n }\n case 'number': {\n const v = params.get(param)\n if (v != null) {\n const n = Number(v)\n if (!Number.isNaN(n)) state[f.key] = n\n }\n break\n }\n case 'boolean': {\n const v = params.get(param)\n if (v === 'true') state[f.key] = true\n else if (v === 'false') state[f.key] = false\n break\n }\n default: {\n // text · select · radio · date · time · dateTime\n const v = params.get(param)\n if (v) state[f.key] = v\n }\n }\n }\n return state\n}\n","import { useId, useState, type ReactNode } from 'react'\nimport { useT, type Translator } from '../../theme'\nimport { Badge } from '../Badge'\nimport { Button } from '../Button'\nimport { DatePicker } from '../DatePicker'\nimport { DateTimePicker } from '../DateTimePicker'\nimport { Icon } from '../Icon'\nimport { IconButton } from '../IconButton'\nimport { Modal } from '../Modal'\nimport { MultiSelect } from '../MultiSelect'\nimport { NumberField } from '../NumberField'\nimport { RadioGroup } from '../Radio'\nimport { Select } from '../Select'\nimport { Slider } from '../Slider'\nimport { TextField } from '../TextField'\nimport { TimePicker } from '../TimePicker'\nimport { Typography } from '../Typography'\nimport {\n activeFilterCount,\n type TableFilter,\n type TableFilterState,\n type TableFilterValue,\n} from './tableFilter'\nimport styles from './TableFilters.module.css'\n\n/** The three boolean-filter radios, mapped to off / `true` / `false` — labels overridable per filter. */\nconst boolOptions = (labels: TableFilter['booleanLabels'], t: Translator) => [\n { value: '', label: labels?.any ?? t('common.any') },\n { value: 'true', label: labels?.yes ?? t('common.yes') },\n { value: 'false', label: labels?.no ?? t('common.no') },\n]\nconst boolToStr = (v: TableFilterValue | undefined): string =>\n v === true ? 'true' : v === false ? 'false' : ''\nconst strToBool = (s: string): boolean | null =>\n s === 'true' ? true : s === 'false' ? false : null\n\n/**\n * A range field — a label over two inputs (From/To, Min/Max). Side by side split by a `–` separator, or\n * **`stacked`** (each on its own line, no separator) for wide inputs that don't fit two-up (dateTimeRange).\n */\nfunction RangeField({\n label,\n from,\n to,\n stacked,\n}: {\n label: ReactNode\n from: ReactNode\n to: ReactNode\n stacked?: boolean\n}) {\n return (\n <div className={styles.field}>\n <Typography variant=\"bodySmall\" className={styles.rangeLabel}>\n {label}\n </Typography>\n {stacked ? (\n <div className={styles.stack}>\n {from}\n {to}\n </div>\n ) : (\n <div className={styles.row}>\n {from}\n <span className={styles.rangeSep} aria-hidden>\n –\n </span>\n {to}\n </div>\n )}\n </div>\n )\n}\n\n/** One field in the filter panel — the control matches the filter's `type`. */\nfunction FilterField({\n filter,\n value,\n onChange,\n}: {\n filter: TableFilter\n value: TableFilterValue | undefined\n onChange: (value: TableFilterValue) => void\n}) {\n const t = useT()\n const { type, label, options = [], placeholder } = filter\n\n switch (type) {\n case 'text':\n return (\n <TextField\n label={label}\n placeholder={placeholder}\n value={(value as string) ?? ''}\n onChange={(e) => onChange(e.target.value)}\n />\n )\n case 'number':\n return (\n <NumberField\n label={label}\n placeholder={placeholder}\n value={(value as number) ?? null}\n onChange={(v) => onChange(v)}\n />\n )\n case 'numberRange': {\n // two open-bounded inputs (Min / Max — either can be left empty)\n const [min, max] = (value as [number | null, number | null] | undefined) ?? [null, null]\n return (\n <RangeField\n label={label}\n from={\n <NumberField\n placeholder={t('common.min')}\n value={min}\n onChange={(v) => onChange([v, max])}\n />\n }\n to={\n <NumberField\n placeholder={t('common.max')}\n value={max}\n onChange={(v) => onChange([min, v])}\n />\n }\n />\n )\n }\n case 'numberRangeSlider': {\n // two-thumb range slider. Bounds come from the filter def (`min`/`max`/`step`); a thumb at an extent\n // maps back to `null` (open bound) so a full-range slider reads as \"not filtering\" (no count, no-op).\n const lo = filter.min ?? 0\n const hi = filter.max ?? 100\n const [low, high] = (value as [number | null, number | null] | undefined) ?? [null, null]\n return (\n <Slider\n range\n label={label}\n min={lo}\n max={hi}\n step={filter.step ?? 1}\n value={[low ?? lo, high ?? hi]}\n valueLabel={(v) => {\n const [a, b] = v as [number, number]\n return `${a} – ${b}`\n }}\n onChange={(v) => {\n const [a, b] = v as [number, number]\n onChange([a <= lo ? null : a, b >= hi ? null : b])\n }}\n />\n )\n }\n case 'select':\n return (\n <Select\n label={label}\n placeholder={placeholder}\n options={options}\n value={(value as string) ?? ''}\n onChange={(v) => onChange(v)}\n />\n )\n case 'radio':\n // a single choice like `select`, but every option visible at once: a leading \"Any\" (`''` = off) +\n // one radio per option. Stacked by default; `orientation: 'horizontal'` keeps a short list on one line.\n return (\n <RadioGroup\n label={label}\n orientation={filter.orientation ?? 'vertical'}\n options={[\n { value: '', label: filter.anyLabel ?? t('common.any') },\n ...options.map(({ value, label, disabled }) => ({ value, label, disabled })),\n ]}\n value={(value as string) ?? ''}\n onChange={(v) => onChange(v)}\n />\n )\n case 'multiSelect':\n return (\n <MultiSelect\n label={label}\n placeholder={placeholder}\n options={options}\n value={(value as string[]) ?? []}\n onChange={(v) => onChange(v)}\n />\n )\n case 'boolean':\n // tri-state as radios (Any / Yes / No, labels overridable via `booleanLabels`) — all visible at once\n return (\n <RadioGroup\n label={label}\n orientation=\"horizontal\"\n options={boolOptions(filter.booleanLabels, t)}\n value={boolToStr(value)}\n onChange={(v) => onChange(strToBool(v))}\n />\n )\n case 'date':\n return (\n <DatePicker\n label={label}\n value={(value as string) ?? ''}\n onChange={(v) => onChange(v ?? '')}\n />\n )\n case 'dateRange': {\n const [from, to] = (value as [string, string] | undefined) ?? ['', '']\n return (\n <RangeField\n label={label}\n from={\n <DatePicker\n placeholder={t('common.from')}\n value={from}\n onChange={(v) => onChange([v ?? '', to])}\n />\n }\n to={\n <DatePicker\n placeholder={t('common.to')}\n value={to}\n onChange={(v) => onChange([from, v ?? ''])}\n />\n }\n />\n )\n }\n case 'time':\n return (\n <TimePicker\n label={label}\n value={(value as string) ?? ''}\n onChange={(v) => onChange(v ?? '')}\n />\n )\n case 'timeRange': {\n const [from, to] = (value as [string, string] | undefined) ?? ['', '']\n return (\n <RangeField\n label={label}\n from={\n <TimePicker\n placeholder={t('common.from')}\n value={from}\n onChange={(v) => onChange([v ?? '', to])}\n />\n }\n to={\n <TimePicker\n placeholder={t('common.to')}\n value={to}\n onChange={(v) => onChange([from, v ?? ''])}\n />\n }\n />\n )\n }\n case 'dateTime':\n return (\n <DateTimePicker\n label={label}\n value={(value as string) ?? ''}\n onChange={(v) => onChange(v ?? '')}\n />\n )\n case 'dateTimeRange': {\n const [from, to] = (value as [string, string] | undefined) ?? ['', '']\n return (\n <RangeField\n label={label}\n stacked\n from={\n <DateTimePicker\n placeholder={t('common.from')}\n value={from}\n onChange={(v) => onChange([v ?? '', to])}\n />\n }\n to={\n <DateTimePicker\n placeholder={t('common.to')}\n value={to}\n onChange={(v) => onChange([from, v ?? ''])}\n />\n }\n />\n )\n }\n default:\n return null\n }\n}\n\nexport interface TableFiltersProps {\n /** The declarative filter definitions. */\n filters: TableFilter[]\n /** The committed filter values. */\n value: TableFilterState\n /** Commit new filter values (Apply / Clear). */\n onChange: (value: TableFilterState) => void\n}\n\n/**\n * The Table's filter control — a toolbar **Filters** button (with a count `Badge`) that opens a right\n * **drawer** (`Modal placement=\"right\"`) of fields (one per `filter` def). Edits a **draft** committed only\n * on **Apply**; **Clear** resets. A `Modal` (not a popover) so nested `Select` / `DatePicker` popovers work\n * inside it.\n */\nexport function TableFilters({ filters, value, onChange }: TableFiltersProps) {\n const t = useT()\n const [open, setOpen] = useState(false)\n const [draft, setDraft] = useState<TableFilterState>(value)\n const count = activeFilterCount(filters, value)\n const formId = useId() // links the footer Apply (submit) to the body form, so Enter also applies\n\n const openPanel = () => {\n setDraft(value) // seed the draft from the committed values each time the panel opens\n setOpen(true)\n }\n const commit = () => {\n onChange(draft)\n setOpen(false)\n }\n\n return (\n <>\n <Badge content={count} color=\"primary\">\n <IconButton variant=\"filled\" size=\"sm\" aria-label={t('table.filters')} onClick={openPanel}>\n <Icon name=\"Filter\" />\n </IconButton>\n </Badge>\n <Modal\n open={open}\n onClose={() => setOpen(false)}\n placement=\"right\"\n size=\"sm\"\n icon=\"Filter\"\n title={t('table.filters')}\n description={t('table.filtersDescription')}\n footer={\n // right-aligned: Clear (reset the draft fields) + Apply (commit). No Cancel — the Modal's × /\n // Escape / backdrop dismiss the drawer, discarding the uncommitted draft.\n <div className={styles.footer}>\n <div className={styles.footerEnd}>\n <Button\n variant=\"text\"\n size=\"sm\"\n startIcon={<Icon name=\"Trash\" />}\n onClick={() => setDraft({})}\n >\n {t('common.clear')}\n </Button>\n {/* submits the body form (`formId`) — so clicking Apply OR pressing Enter in a field commits */}\n <Button type=\"submit\" size=\"sm\" form={formId} startIcon={<Icon name=\"Filter\" />}>\n {t('common.apply')}\n </Button>\n </div>\n </div>\n }\n >\n <form\n id={formId}\n className={styles.fields}\n onSubmit={(e) => {\n e.preventDefault()\n commit()\n }}\n >\n {filters.map((filter) => (\n <FilterField\n key={filter.key}\n filter={filter}\n value={draft[filter.key]}\n onChange={(v) => setDraft((prev) => ({ ...prev, [filter.key]: v }))}\n />\n ))}\n </form>\n </Modal>\n </>\n )\n}\n","import {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type ForwardedRef,\n type HTMLAttributes,\n type ReactElement,\n type ReactNode,\n} from 'react'\nimport { clsx } from 'clsx'\nimport {\n getCoreRowModel,\n getFilteredRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n useReactTable,\n type ColumnDef,\n type PaginationState,\n type SortingState,\n type Updater,\n} from '@tanstack/react-table'\nimport {\n DndContext,\n KeyboardSensor,\n PointerSensor,\n closestCenter,\n useSensor,\n useSensors,\n type ClientRect,\n type DragEndEvent,\n type Modifier,\n} from '@dnd-kit/core'\nimport {\n SortableContext,\n arrayMove,\n useSortable,\n sortableKeyboardCoordinates,\n verticalListSortingStrategy,\n} from '@dnd-kit/sortable'\nimport { CSS, type Transform } from '@dnd-kit/utilities'\nimport { useT, useTableQueryConfig, type TableQueryConfig } from '../../theme'\nimport { buildTableQuery, parseTableQuery } from '../../helpers/table'\nimport {\n applyFilters,\n buildFilterQuery,\n parseFilterQuery,\n type TableFilter,\n type TableFilterState,\n} from './tableFilter'\nimport { TableFilters } from './TableFilters'\nimport { Badge } from '../Badge'\nimport { Dropdown } from '../Dropdown'\nimport { EmptyState } from '../EmptyState'\nimport { Icon } from '../Icon'\nimport { IconButton } from '../IconButton'\nimport { ListItem } from '../List'\nimport { Loader } from '../Loader'\nimport { Pagination } from '../Pagination'\nimport { Select } from '../Select'\nimport { Skeleton } from '../Skeleton'\nimport { TextField } from '../TextField'\nimport { Typography } from '../Typography'\nimport { isDev } from '../ErrorState/errorMessage'\nimport styles from './Table.module.css'\n\nexport type TableAlign = 'left' | 'center' | 'right'\nexport type TableSortDirection = 'asc' | 'desc'\n\n/** Sentinel page size for the \"All\" rows-per-page choice — larger than any real dataset, so everything\n * lands on a single page. Emitted verbatim in `onChange` (server consumers should treat it as unbounded). */\nconst ALL_ROWS = Number.MAX_SAFE_INTEGER\n\n// skeleton cell widths — cycled per (row, column) so the placeholder reads like varied real content. In\n// `em` (not %): an empty cell has no width of its own, so a % of it collapses — an em width gives the\n// column a real, font-relative size (capped at the cell by the skeleton's `max-width: 100%`)\nconst SKELETON_WIDTHS = ['8em', '5.5em', '7em', '10em', '4.5em', '6.5em']\n\n/** Default max width for a `wrap` column with no explicit `maxWidth` — a readable text width, so `wrap`\n * alone caps + wraps without the consumer having to pick a number. */\nconst DEFAULT_WRAP_MAX_WIDTH = 280\n\n/** A single column definition — the simple, engine-agnostic shape a consumer writes. */\nexport interface TableColumn<T> {\n /** Field key on the row — the column id, the default cell accessor, and the local sort/search key. */\n key: string\n /** Header content. */\n header: ReactNode\n /** Custom cell renderer. Defaults to the row's `key` value stringified. */\n cell?: (row: T, index: number) => ReactNode\n /** Enable sorting on this column (click the header to toggle asc → desc → none). Defaults to `false`. */\n sortable?: boolean\n /** Fixed column width — a px `number` or any CSS width string. Opts the column out of the default cap. */\n width?: number | string\n /**\n * Cap the column's width (px `number` or CSS string) — long content **wraps** within it onto 2+ lines\n * (the row grows) instead of stretching the table. **Implies `wrap`.** Only needed to override the\n * default wrap cap (`280px`); otherwise plain `wrap` is enough.\n */\n maxWidth?: number | string\n /**\n * Let this column's content **wrap** onto multiple lines (rows grow) instead of the single-line default —\n * a long unbroken token breaks too. On its own it caps the column at a readable **`280px`** (set\n * `maxWidth` for a different cap). Cells are single-line by default (the table scrolls horizontally); opt\n * a long-text column (name / note / address) in with `wrap`.\n */\n wrap?: boolean\n /** Cell + header text alignment. Defaults to `left`. */\n align?: TableAlign\n /**\n * Pin the column to an edge so it stays visible while the rest scrolls horizontally (e.g. an actions\n * column pinned `'right'`). One column per edge; a hairline separates it from the scrolling body. A\n * pinned column with **no `width`** shrinks to its content (so an actions column fits its buttons); set\n * `width` to override.\n */\n pinned?: 'left' | 'right'\n}\n\n/** The current sort — the column `key` + direction, or `null` when unsorted. */\nexport interface TableSortState {\n key: string\n direction: TableSortDirection\n}\n\n/** Details of a single row-reorder drag, passed to `onReorder` alongside the reordered rows. */\nexport interface TableReorderMeta {\n /** The stable row id (from `getRowId`) of the dragged row. */\n id: string\n /** The dragged row's original index in `data`. */\n from: number\n /** The index the row was dropped at (its new position in the reordered array). */\n to: number\n}\n\n/** The table's live state, emitted on every change — the server-mode fetch driver. */\nexport interface TableChangeState {\n /** 1-based page number. */\n page: number\n /** Rows per page. */\n size: number\n /** Current search query. */\n search: string\n /** Active sort, or `null`. */\n sort: TableSortState | null\n /** Active filter values, keyed by filter `key` (empty when none set). */\n filters: TableFilterState\n /**\n * The **built server-request params** for this state, from the query mapping (`config.table.query`\n * merged with the `queryMapping` prop) — ready to append to your endpoint, so you don't hand-map\n * page/size/search/sort. E.g. `fetch(`/products?${state.query}`)`.\n */\n params: URLSearchParams\n /** `params.toString()` — e.g. `\"skip=0&limit=10&q=phone&sortBy=price&order=desc\"`. */\n query: string\n}\n\n/** Props shared by both table modes (everything except the mode-specific `manualPagination` / `rowCount`). */\ninterface TableBaseProps<T> extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'title'> {\n /** Column definitions — keep them simple: a `key` + `header`, plus an optional `cell` renderer. */\n columns: TableColumn<T>[]\n /**\n * Row data. **Local mode** (default): the full dataset — the table searches / sorts / paginates it\n * client-side. **Server mode** (`manualPagination`): only the current page's rows — you fetch them in\n * `onChange` and pass `rowCount` for the total.\n */\n data: T[]\n /**\n * Stable row id from a row — used as the React key, so a row keeps its DOM identity (and any focus /\n * in-cell state) across sort / filter / refetch. Defaults to the row **index**, which is fine for static\n * data but reuses DOM by position when rows reorder or a server page swaps in — pass a real id (e.g.\n * `(row) => row.id`) for any table with row interactions or changing data.\n */\n getRowId?: (row: T, index: number) => string\n /** Optional heading shown at the top-left of the toolbar. */\n title?: ReactNode\n /** Extra toolbar content (e.g. future filter controls), rendered in the right group before sort/export. */\n toolbar?: ReactNode\n /** Show the search box in the toolbar. Defaults to `false`. */\n searchable?: boolean\n /** Placeholder for the search box. Defaults to `\"Search…\"`. */\n searchPlaceholder?: string\n /** Initial search query. */\n defaultSearch?: string\n /** Debounce (ms) before a typed search commits (local filter + `onChange`). Defaults to `300`. */\n debounceMs?: number\n /** Initial page (1-based). Defaults to `1` (overridden by the URL param when `urlSync`). */\n defaultPage?: number\n /** Initial rows per page. Defaults to `10` (overridden by the URL param when `urlSync`). */\n defaultPageSize?: number\n /** Rows-per-page choices in the footer `Select`. Defaults to `[10, 20, 50, 100, 200]`. */\n pageSizeOptions?: number[]\n /**\n * Add an **\"All\"** rows-per-page choice that puts every row on one page. Defaults to `true` — pass\n * `false` to hide it (e.g. for a large server dataset where fetching everything is undesirable).\n */\n allowAllRows?: boolean\n /**\n * Show the rows-per-page `Select` in the footer. Defaults to `'auto'`: shown only when the total exceeds\n * the smallest page size on offer (the numeric `pageSizeOptions` plus the current size — \"All\" never\n * counts), i.e. when another size could actually split or merge pages; a 2-row table shows none. `true`\n * always shows it, `false` never does. Hiding it never changes the page size. With no Select and a single\n * page, the whole footer (range text included) is dropped.\n */\n showPageSize?: boolean | 'auto'\n /** Show the jump-to-first-page (⏮) button in the pagination. Defaults to `false`. */\n showFirstButton?: boolean\n /** Show the jump-to-last-page (⏭) button in the pagination. Defaults to `false`. */\n showLastButton?: boolean\n /** Initial sort. */\n defaultSort?: TableSortState | null\n /**\n * Fires with the full `{ page, size, search, sort, params, query }` state on mount and whenever it\n * changes — wire this to your fetch in server mode (append `state.query` to your endpoint). Search\n * changes are debounced (`debounceMs`).\n */\n onChange?: (state: TableChangeState) => void\n /**\n * Per-table override for how `state.params` / `state.query` are built (param names, `page` vs `offset`\n * pagination, sort format) — merged over the app-wide `config.table.query`. Use it when one table hits a\n * differently-shaped endpoint (e.g. `{ pageParam: 'skip', sizeParam: 'limit', searchParam: 'q', pagination: 'offset' }`).\n */\n queryMapping?: TableQueryConfig\n /**\n * Handler for the toolbar **export** menu's built-in **\"Send on Email\"** item (label + icon are baked in).\n * Set it to show the export `Dropdown`; on click it fires with the current `TableChangeState` (incl.\n * `query`), so you just wire your endpoint — e.g. `onExportToEmail={(s) => exportCustomers(s.query)}`. Omit it\n * to hide the export menu.\n */\n onExportToEmail?: (state: TableChangeState) => void\n /**\n * Declarative filters — each renders a field in a toolbar **Filters** panel (a `Modal`). In **local**\n * mode the table filters `data` client-side; in **server** mode the active values ride in `onChange`\n * (`state.filters`). Core types: `text` / `number` / `numberRange` / `select` / `multiSelect` /\n * `boolean` / `date` / `dateRange` (`select` / `multiSelect` take `options`).\n */\n filters?: TableFilter[]\n /** Initial filter values, keyed by filter `key`. */\n defaultFilters?: TableFilterState\n /** Called when a body row is clicked (makes rows interactive). */\n onRowClick?: (row: T, index: number) => void\n /**\n * Per-row actions — return the action UI (your own `IconButton`s / menu / etc.) for a row and the table\n * renders it in a **pinned-right actions column** it adds for you (no column boilerplate). The cell is\n * `stopPropagation`-wrapped, so clicks inside it never fire the row's `onClick` — you don't handle that.\n */\n actions?: (row: T, index: number) => ReactNode\n /**\n * Enable **row drag-and-drop reordering** — a leading **drag-handle** column (a grip icon) is prepended,\n * and dragging it (or keyboard: focus the handle → Space → Arrows → Space) reorders the rows, firing\n * **`onReorder`**. **Local mode only**, and best with no active sort (a sort fights a manual order);\n * **requires `getRowId`** (dnd needs stable row ids). Built on `@dnd-kit`. Defaults to `false`.\n */\n reorderable?: boolean\n /**\n * Fired after a drag reorder with the **full `data` reordered** — you own `data`, so set it from this\n * (e.g. `onReorder={setRows}`). A second **`meta`** arg carries the drag details (`{ id, from, to }` —\n * the dragged row's id + its old/new index). Only fires while `reorderable`.\n */\n onReorder?: (rows: T[], meta: TableReorderMeta) => void\n /**\n * Loading state. With no rows yet (first load) the body shows **skeleton rows** shaped like the real\n * columns; while refetching with rows already shown, they're dimmed under a spinner overlay instead\n * (so the table doesn't jump). Defaults to `false`.\n */\n loading?: boolean\n /** Number of skeleton rows on the first load. Defaults to the page size, capped at 10. */\n loadingRows?: number\n /** Custom content for the empty state (replaces the default `EmptyState`). */\n empty?: ReactNode\n /**\n * Mirror page + rows-per-page + search + sort + filters to the URL query, using the **same shape as the\n * server request** (`config.table.query` merged with `queryMapping`) — so the address bar matches\n * `state.query` exactly (e.g. `?page=1&size=10&sortBy=rating&orderBy=desc`). Read back on mount + restored\n * on Back/Forward. Defaults to `true`; pass `false` to opt out entirely. (Two synced tables on one page\n * need distinct param names via their `queryMapping`, since both write the same params otherwise.) When the\n * table **unmounts while the page stays** (a tab switch, a closing sheet, a conditional render) it removes\n * its params again — see `clearUrlOnUnmount`.\n */\n urlSync?: boolean\n /**\n * With `urlSync`, remove the table's own URL params (page / size / search / sort / its filters) when it\n * unmounts **on the same page** — the pathname it last wrote under is still showing, so a tab switch or a\n * closing sheet doesn't leave `?page=1&size=20` describing a table that's gone. Params it doesn't own\n * (`?tab=…`) and the hash are kept; after a navigation to another pathname nothing is touched (the URL\n * belongs to the new page). A table that mounts again on the same page therefore starts from its\n * `default*` values. Defaults to `true`; pass `false` to leave the params behind.\n */\n clearUrlOnUnmount?: boolean\n // ── Controlled state ─────────────────────────────────────────────────────────\n // Each pairs with its `default*` counterpart: pass the controlled prop (with its `on*Change`) to own the\n // state from outside; omit it to let the table manage that piece internally (seeded from `default*`). Mix\n // freely — e.g. control only `filterValues` while page/sort stay uncontrolled. Pass **stable** values.\n /** Controlled 1-based page (pair with `onPageChange`); omit for uncontrolled (`defaultPage`). */\n page?: number\n /** Fired with the new 1-based page — on user paging, or a reset to page 1 from a size/sort/search/filter change. */\n onPageChange?: (page: number) => void\n /** Controlled rows-per-page (pair with `onPageSizeChange`); omit for uncontrolled (`defaultPageSize`). */\n pageSize?: number\n /** Fired with the new rows-per-page. */\n onPageSizeChange?: (size: number) => void\n /** Controlled (committed, debounced) search query (pair with `onSearchChange`); omit for uncontrolled (`defaultSearch`). */\n search?: string\n /** Fired with the committed (debounced) search query. */\n onSearchChange?: (search: string) => void\n /** Controlled sort, or `null` (pair with `onSortChange`); omit for uncontrolled (`defaultSort`). */\n sort?: TableSortState | null\n /** Fired with the new sort (or `null` when cleared). */\n onSortChange?: (sort: TableSortState | null) => void\n /** Controlled filter values, keyed by filter `key` (pair with `onFiltersChange`); omit for uncontrolled (`defaultFilters`). */\n filterValues?: TableFilterState\n /** Fired with the filter values on Apply / Clear. */\n onFiltersChange?: (filters: TableFilterState) => void\n /** Pin the header row while the body scrolls. Defaults to `false`. */\n stickyHeader?: boolean\n /** Zebra-stripe alternate rows. Defaults to `false`. */\n striped?: boolean\n /** Highlight rows on hover. Defaults to `true`. */\n hoverable?: boolean\n}\n\n/**\n * `Table` props. A discriminated union on `manualPagination` so the type enforces the server-mode contract:\n * **local mode** (default) needs no `rowCount`; **server mode** (`manualPagination`) **requires** it (the\n * table can't derive the total page count from a single fetched page).\n */\nexport type TableProps<T> =\n | (TableBaseProps<T> & {\n /** Local mode (default) — the table slices / sorts / filters `data` itself. */\n manualPagination?: false\n /** Ignored in local mode (the table knows the full count from `data`). */\n rowCount?: number\n })\n | (TableBaseProps<T> & {\n /**\n * **Server mode** — the table doesn't slice / sort / filter `data`; it tracks state and fires\n * `onChange`. Pass the current page's rows in `data` and the total in `rowCount`.\n */\n manualPagination: true\n /** Total row count across all pages — **required** in server mode to compute the page count. */\n rowCount: number\n })\n\n/** Resolve a TanStack `Updater` (a value or an `(old) => next` function) against the current value. */\nfunction resolveUpdater<S>(updater: Updater<S>, old: S): S {\n return typeof updater === 'function' ? (updater as (o: S) => S)(old) : updater\n}\n\n/**\n * A wrap column's width cap — its own `maxWidth`, else the readable default when it just sets `wrap`, else\n * none. Used as BOTH the preferred `width` and the `max-width` so the column sits at that width and its\n * content wraps within it (without a preferred width, `overflow-wrap` would starve it to near-zero as the\n * unbounded single-line columns grab the table's spare width).\n */\nfunction wrapCap<T>(col: TableColumn<T>): number | string | undefined {\n return col.maxWidth ?? (col.wrap ? DEFAULT_WRAP_MAX_WIDTH : undefined)\n}\n\n/** Stringify a primitive cell value; complex values should use a column `cell` renderer. */\nfunction formatCell(value: unknown): ReactNode {\n if (value == null) return ''\n if (typeof value === 'object') return ''\n return String(value)\n}\n\n/**\n * Wrap a cell's rendered content: a blank cell (`null` / `undefined` / `''` / `false`, from an empty value\n * or a `cell` renderer that returned nothing) shows a muted \"—\" placeholder so it reads as \"no value\" rather\n * than a rendering glitch. A `0` / `'0'` is a real value and stays as-is (not treated as empty).\n */\nfunction renderCellContent(content: ReactNode): ReactNode {\n if (content == null || content === '' || content === false) {\n return (\n <span className={styles.empty} aria-hidden>\n —\n </span>\n )\n }\n return content\n}\n\n/**\n * `URLSearchParams.toString()`, but with the commonly-unencoded chars `,` `:` `[` `]` left raw — all read\n * cleanly in a query and are accepted by servers in practice (`brand=a,b`, `created=…T09:00:00`,\n * `cat[0]=a`). Non-ASCII (e.g. Georgian text) stays percent-encoded — that's unavoidable in a URL. This\n * makes `state.query` pretty; `state.params.toString()` stays strictly encoded for consumers who want that.\n */\nfunction prettyQuery(params: URLSearchParams): string {\n return params\n .toString()\n .replace(/%2C/gi, ',')\n .replace(/%3A/gi, ':')\n .replace(/%5B/gi, '[')\n .replace(/%5D/gi, ']')\n}\n\n/**\n * Whether a URL param belongs to this table — the names it writes under its resolved mapping: the page /\n * size / search / sort / sort-order params, and every filter's `queryKey ?? key` with its range-suffix and\n * indexed (`key[0]`) forms. Shared by the URL write (clear ours before copying the new state in) and the\n * unmount cleanup (strip ours), so the two can't drift.\n */\nfunction tableOwnsParam(\n mapping: TableQueryConfig,\n filters: TableFilter[] | undefined,\n): (param: string) => boolean {\n const m = {\n pageParam: 'page',\n sizeParam: 'size',\n searchParam: 'search',\n sortParam: 'sort',\n sortOrderParam: 'order',\n ...mapping,\n }\n const minSuffix = mapping.rangeMinSuffix ?? 'Min'\n const maxSuffix = mapping.rangeMaxSuffix ?? 'Max'\n const owned = [m.pageParam, m.sizeParam, m.searchParam, m.sortParam, m.sortOrderParam]\n for (const f of filters ?? []) {\n const p = f.queryKey ?? f.key\n owned.push(p, p + minSuffix, p + maxSuffix)\n }\n return (param) => owned.includes(param) || owned.some((b) => param.startsWith(`${b}[`))\n}\n\n/** Clamp a transform so the dragged node stays within a bounding rect (dnd-kit's `restrictToBoundingRect`). */\nfunction restrictToBoundingRect(\n transform: Transform,\n rect: ClientRect,\n boundingRect: ClientRect,\n): Transform {\n const value = { ...transform }\n if (rect.top + transform.y <= boundingRect.top) {\n value.y = boundingRect.top - rect.top\n } else if (rect.bottom + transform.y >= boundingRect.top + boundingRect.height) {\n value.y = boundingRect.top + boundingRect.height - rect.bottom\n }\n if (rect.left + transform.x <= boundingRect.left) {\n value.x = boundingRect.left - rect.left\n } else if (rect.right + transform.x >= boundingRect.left + boundingRect.width) {\n value.x = boundingRect.left + boundingRect.width - rect.right\n }\n return value\n}\n\n// dnd-kit modifiers for row drag (inlined — no `@dnd-kit/modifiers` dep): keep the drag on the **vertical\n// axis**, and **clamp it to the parent** (`<tbody>`) so a row dragged past the table's top/bottom can't\n// extend beyond it and grow the scroll container / add a scrollbar.\nconst restrictToVerticalAxis: Modifier = ({ transform }) => ({ ...transform, x: 0 })\nconst restrictToParentElement: Modifier = ({ containerNodeRect, draggingNodeRect, transform }) =>\n draggingNodeRect && containerNodeRect\n ? restrictToBoundingRect(transform, draggingNodeRect, containerNodeRect)\n : transform\nconst rowDragModifiers = [restrictToVerticalAxis, restrictToParentElement]\n\n/**\n * A reorderable body row — wraps `useSortable` (dnd-kit) and renders a leading **drag-handle** cell (the\n * grip `IconButton`) before the row's data cells. The handle carries the drag listeners; the rest of the\n * row stays clickable (`onRowClick`). Only rendered when the table is `reorderable`.\n */\nfunction SortableRow({\n id,\n cells,\n clickable,\n onClick,\n}: {\n id: string\n cells: ReactNode\n clickable: boolean\n onClick?: () => void\n}) {\n const t = useT()\n const { setNodeRef, transform, transition, isDragging, attributes, listeners } = useSortable({\n id,\n })\n return (\n <tr\n ref={setNodeRef}\n className={clsx(styles.tr, clickable && styles.clickable, isDragging && styles.dragging)}\n style={\n {\n // Translate (not Transform) — skip dnd-kit's scaleX/scaleY, which would squish/stretch the\n // dragged row to the target's size when rows have different heights; keep the row's own size\n transform: CSS.Translate.toString(transform),\n transition,\n position: isDragging ? 'relative' : undefined,\n zIndex: isDragging ? 1 : undefined,\n } as CSSProperties\n }\n onClick={onClick}\n >\n <td className={clsx(styles.td, styles.dragHandleCell)}>\n <button\n type=\"button\"\n className={styles.dragHandle}\n aria-label={t('table.dragHandle')}\n {...attributes}\n {...listeners}\n onClick={(e) => e.stopPropagation()}\n >\n <Icon name=\"Menu\" size=\"sm\" />\n </button>\n </td>\n {cells}\n </tr>\n )\n}\n\n/** Wraps the table body in a dnd-kit `DndContext` only when reordering is on — a passthrough otherwise. */\nfunction ReorderProvider({\n enabled,\n sensors,\n onDragEnd,\n children,\n}: {\n enabled: boolean\n sensors: ReturnType<typeof useSensors>\n onDragEnd: (event: DragEndEvent) => void\n children: ReactNode\n}) {\n if (!enabled) return <>{children}</>\n return (\n <DndContext\n sensors={sensors}\n collisionDetection={closestCenter}\n modifiers={rowDragModifiers}\n onDragEnd={onDragEnd}\n >\n {children}\n </DndContext>\n )\n}\n\n/**\n * A data table built on **TanStack Table** (headless — an optional peer, `external`) styled entirely with\n * `--tz-*` tokens. Pass `columns` + `data` and it renders a sortable, paginated, searchable table. Works\n * two ways: **local** (hand it the full `data` — it searches / sorts / paginates client-side) or **server**\n * (`manualPagination` — pass the current page in `data` + the total in `rowCount`, and fetch in `onChange`).\n * Composes the library's `TextField` (search), `Select` (rows per page), `Pagination`, `EmptyState`, and\n * `Loader`; syncs page + size to the URL (`?page=1&size=10`) by default. The ref points at the root.\n *\n * @example\n * <Table data={users} columns={[\n * { key: 'name', header: 'Name', sortable: true },\n * { key: 'role', header: 'Role', cell: (u) => <Chip>{u.role}</Chip> },\n * ]} searchable />\n */\nexport const Table = forwardRef(function Table<T>(\n {\n columns,\n data,\n getRowId,\n title,\n toolbar,\n searchable = false,\n searchPlaceholder,\n defaultSearch = '',\n debounceMs = 300,\n defaultPage = 1,\n defaultPageSize = 10,\n pageSizeOptions = [10, 20, 50, 100, 200],\n allowAllRows = true,\n showPageSize = 'auto',\n showFirstButton = false,\n showLastButton = false,\n manualPagination = false,\n rowCount,\n defaultSort = null,\n onChange,\n queryMapping,\n onExportToEmail,\n filters,\n defaultFilters,\n onRowClick,\n actions,\n reorderable = false,\n onReorder,\n loading = false,\n loadingRows,\n empty,\n urlSync = true,\n clearUrlOnUnmount = true,\n page,\n onPageChange,\n pageSize,\n onPageSizeChange,\n search,\n onSearchChange,\n sort,\n onSortChange,\n filterValues,\n onFiltersChange,\n stickyHeader = false,\n striped = false,\n hoverable = true,\n className,\n ...props\n }: TableProps<T>,\n ref: ForwardedRef<HTMLDivElement>,\n) {\n const t = useT()\n // the query mapping — the app-wide `config.table.query` merged with this table's override. It drives BOTH\n // the server-request query (`state.query`) AND the browser-URL sync, so the two share one shape.\n const configQueryMapping = useTableQueryConfig()\n const queryMappingRef = useRef<TableQueryConfig>({})\n queryMappingRef.current = { ...configQueryMapping, ...queryMapping }\n\n // keep the latest onChange for the stable emit effect (avoids re-subscribing)\n const onChangeRef = useRef(onChange)\n onChangeRef.current = onChange\n // filter defs for the stable URL write / popstate closures\n const filtersRef = useRef(filters)\n filtersRef.current = filters\n\n // horizontal-scroll state → a soft shadow on a pinned column's inner edge when content is hidden under\n // it (so it reads as \"content scrolls under here\", not a hard cut)\n const scrollRef = useRef<HTMLDivElement | null>(null)\n const tableRef = useRef<HTMLTableElement | null>(null)\n const [pinShadow, setPinShadow] = useState({ start: false, end: false })\n\n // seed the URL-synced state once, parsing the browser query with the SAME mapping the request uses (so the\n // URL the table writes round-trips). `page` / `size` fall back to the defaults when absent from the URL.\n const [urlSeed] = useState(() => {\n const params =\n urlSync && typeof window !== 'undefined' ? new URLSearchParams(window.location.search) : null\n if (!params) {\n return {\n page: null as number | null,\n size: null as number | null,\n search: '',\n sort: null as TableSortState | null,\n filters: {} as TableFilterState,\n }\n }\n return {\n ...parseTableQuery(params, queryMappingRef.current),\n filters: filters?.length ? parseFilterQuery(filters, params, queryMappingRef.current) : {},\n }\n })\n\n const [pagination, setPagination] = useState<PaginationState>(() => ({\n pageIndex: (urlSeed.page ?? defaultPage) - 1,\n pageSize: urlSeed.size ?? defaultPageSize,\n }))\n // `searchInput` is the immediate input value; `globalFilter` is the committed (debounced) query — both\n // seed from the URL when synced, else `defaultSearch`\n const [searchInput, setSearchInput] = useState(urlSeed.search || defaultSearch)\n const [globalFilter, setGlobalFilter] = useState(urlSeed.search || defaultSearch)\n const [sorting, setSorting] = useState<SortingState>(() => {\n if (urlSeed.sort) return [{ id: urlSeed.sort.key, desc: urlSeed.sort.direction === 'desc' }]\n return defaultSort ? [{ id: defaultSort.key, desc: defaultSort.direction === 'desc' }] : []\n })\n const [filterState, setFilterState] = useState<TableFilterState>(() => ({\n ...defaultFilters,\n ...urlSeed.filters,\n }))\n\n const manual = manualPagination\n\n // ── controlled-or-uncontrolled resolution ──────────────────────────────────────\n // Each piece reads its controlled prop when provided, else the internal state above. Every mutation goes\n // through a `commit*` helper, which fires the `on*Change` callback AND updates the internal fallback (only\n // for the pieces that aren't controlled) — so controlled + uncontrolled behave identically downstream.\n const pageControlled = page !== undefined\n const sizeControlled = pageSize !== undefined\n const searchControlled = search !== undefined\n const sortControlled = sort !== undefined\n const filtersControlled = filterValues !== undefined\n\n const resolvedPagination: PaginationState = {\n pageIndex: pageControlled ? page - 1 : pagination.pageIndex,\n pageSize: sizeControlled ? pageSize : pagination.pageSize,\n }\n const resolvedGlobalFilter = searchControlled ? search : globalFilter\n const resolvedSorting = useMemo<SortingState>(\n () =>\n sortControlled ? (sort ? [{ id: sort.key, desc: sort.direction === 'desc' }] : []) : sorting,\n [sortControlled, sort, sorting],\n )\n const resolvedFilterState = useMemo<TableFilterState>(\n () => (filtersControlled ? filterValues : filterState),\n [filtersControlled, filterValues, filterState],\n )\n\n // commit a pagination change: notify the controlled page/size callbacks + update the internal fallback for\n // whichever piece is uncontrolled. A pagination change never resets the page (that's the point of paging).\n const commitPagination = (updater: Updater<PaginationState>) => {\n const cur = resolvedPagination\n const next = resolveUpdater(updater, cur)\n if (next.pageIndex !== cur.pageIndex) onPageChange?.(next.pageIndex + 1)\n if (next.pageSize !== cur.pageSize) onPageSizeChange?.(next.pageSize)\n setPagination((p) => ({\n pageIndex: pageControlled ? p.pageIndex : next.pageIndex,\n pageSize: sizeControlled ? p.pageSize : next.pageSize,\n }))\n }\n // resetting to the first page is the shared side effect of a size / search / sort / filter change\n const resetToFirstPage = () =>\n commitPagination((p) => (p.pageIndex === 0 ? p : { ...p, pageIndex: 0 }))\n\n const commitSearch = (value: string, resetPage = true) => {\n if (!searchControlled) setGlobalFilter(value)\n onSearchChange?.(value)\n if (resetPage) resetToFirstPage()\n }\n const commitSorting = (updater: Updater<SortingState>, resetPage = true) => {\n const next = resolveUpdater(updater, resolvedSorting)\n if (!sortControlled) setSorting(next)\n onSortChange?.(next[0] ? { key: next[0].id, direction: next[0].desc ? 'desc' : 'asc' } : null)\n if (resetPage) resetToFirstPage()\n }\n const commitFilters = (next: TableFilterState, resetPage = true) => {\n if (!filtersControlled) setFilterState(next)\n onFiltersChange?.(next)\n if (resetPage) resetToFirstPage()\n }\n\n // local mode: filter `data` client-side before TanStack (search / sort / paginate then run on the result);\n // server mode: pass it through — the consumer fetches per the emitted `state.filters`\n const filteredData = useMemo(\n () =>\n filters && filters.length > 0 && !manual\n ? applyFilters(data, filters, resolvedFilterState)\n : data,\n [filters, manual, data, resolvedFilterState],\n )\n // applying / clearing filters resets to the first page (the filtered set changes what \"page 1\" means)\n const handleFiltersChange = commitFilters\n\n const tanstackColumns = useMemo<ColumnDef<T>[]>(\n () =>\n columns.map((col) => ({\n id: col.key,\n accessorFn: (row: T) => (row as Record<string, unknown>)[col.key],\n enableSorting: !!col.sortable,\n })),\n [columns],\n )\n\n // rows-per-page choices + an optional trailing \"All\"\n const pageSizeChoices = useMemo(() => {\n const opts = pageSizeOptions.map((n) => ({ value: String(n), label: String(n) }))\n return allowAllRows ? [...opts, { value: 'all', label: t('common.all') }] : opts\n }, [pageSizeOptions, allowAllRows])\n\n // the columns actually rendered — the consumer's, plus an auto-built pinned-right actions column when\n // `actions` is given (display-only, so it stays out of `tanstackColumns` / sort / filter)\n const renderColumns = useMemo<TableColumn<T>[]>(() => {\n if (!actions) return columns\n const actionsColumn: TableColumn<T> = {\n key: '__actions',\n header: '',\n align: 'right',\n pinned: 'right',\n // render the consumer's action UI right-aligned; the wrapper swallows clicks so they never reach\n // the row's `onClick` — the consumer's own handlers don't need to `stopPropagation`\n cell: (row, index) => (\n <div className={styles.rowActions} onClick={(e) => e.stopPropagation()}>\n {actions(row, index)}\n </div>\n ),\n }\n return [...columns, actionsColumn]\n }, [columns, actions])\n\n // the sortable columns drive the toolbar sort menu — each lists an explicit ascending + descending entry\n const sortableColumns = useMemo(() => columns.filter((c) => c.sortable), [columns])\n // one row per sortable column; clicking cycles that column through ascending → descending → unsorted\n const cycleSort = (key: string) =>\n commitSorting((prev) => {\n const cur = prev[0]\n if (!cur || cur.id !== key) return [{ id: key, desc: false }] // → ascending\n if (!cur.desc) return [{ id: key, desc: true }] // ascending → descending\n return [] // descending → unsorted\n })\n\n const table = useReactTable<T>({\n data: filteredData,\n columns: tanstackColumns,\n state: {\n pagination: resolvedPagination,\n globalFilter: resolvedGlobalFilter,\n sorting: resolvedSorting,\n },\n onPaginationChange: commitPagination,\n onGlobalFilterChange: (updater) =>\n commitSearch(resolveUpdater(updater as Updater<string>, resolvedGlobalFilter)),\n onSortingChange: commitSorting,\n globalFilterFn: 'includesString',\n // first click always sorts ascending (A→Z / 0→9), for every column type — the intuitive default\n sortDescFirst: false,\n getCoreRowModel: getCoreRowModel(),\n getRowId,\n manualPagination: manual,\n manualFiltering: manual,\n manualSorting: manual,\n ...(manual\n ? { rowCount: rowCount ?? data.length }\n : {\n getPaginationRowModel: getPaginationRowModel(),\n getFilteredRowModel: getFilteredRowModel(),\n getSortedRowModel: getSortedRowModel(),\n }),\n })\n\n const rows = table.getRowModel().rows\n\n // row drag-and-drop reordering (dnd-kit) — pointer (5px activation) + keyboard sensors; the sortable ids\n // are the TanStack row ids (= `getRowId`), and a drop moves the item within the full `data` and emits it\n const sensors = useSensors(\n useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),\n useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),\n )\n const rowIdOf = (row: T, index: number) => (getRowId ? getRowId(row, index) : String(index))\n const handleReorder = (event: DragEndEvent) => {\n const { active, over } = event\n if (!over || active.id === over.id || !onReorder) return\n const from = data.findIndex((r, i) => rowIdOf(r, i) === active.id)\n const to = data.findIndex((r, i) => rowIdOf(r, i) === over.id)\n if (from < 0 || to < 0) return\n onReorder(arrayMove(data, from, to), { id: String(active.id), from, to })\n }\n\n const totalRows = manual ? (rowCount ?? data.length) : table.getFilteredRowModel().rows.length\n const { pageIndex, pageSize: resolvedPageSize } = resolvedPagination\n const pageCount = Math.max(1, Math.ceil(totalRows / resolvedPageSize))\n // 'auto' rows-per-page: only worth showing when some size would paginate differently — i.e. the total\n // exceeds the smallest numeric choice (the current size counts, in case it's below every option; \"All\"\n // doesn't). Purely presentational: the page size itself is never touched. `totalRows` is the server's\n // `rowCount` in server mode, so it holds steady through a placeholder refetch (no blink).\n const smallestPageSize = Math.min(\n ...pageSizeOptions,\n ...(resolvedPageSize < ALL_ROWS ? [resolvedPageSize] : []),\n )\n const showSizeSelect = showPageSize === 'auto' ? totalRows > smallestPageSize : showPageSize\n const currentPage = pageIndex + 1\n const rangeStart = totalRows === 0 ? 0 : pageIndex * resolvedPageSize + 1\n const rangeEnd = manual\n ? Math.min(totalRows, pageIndex * resolvedPageSize + rows.length)\n : Math.min(totalRows, currentPage * resolvedPageSize)\n\n // keep the search box in sync when `search` is controlled externally (e.g. cleared from a parent button)\n useEffect(() => {\n if (search !== undefined) setSearchInput(search)\n }, [search])\n\n // debounce a typed search into the committed query, resetting to the first page when it actually changes\n useEffect(() => {\n if (searchInput === resolvedGlobalFilter) return\n const handle = setTimeout(() => commitSearch(searchInput), debounceMs)\n return () => clearTimeout(handle)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [searchInput, resolvedGlobalFilter, debounceMs])\n\n // clamp the page if the row count shrank beneath it (e.g. a local search filtered rows away). In\n // SERVER mode, skip while `rowCount` is still 0/unknown — on a deep-linked `?page=2` the data for that\n // page hasn't loaded yet, so `pageCount` is a stale `1`; clamping here would reset page 2 → 1 and fire a\n // second (wrong) request. The server owns the total, so only clamp once it's known (`rowCount > 0`).\n useEffect(() => {\n if (manual && totalRows === 0) return\n if (pageIndex > 0 && pageIndex >= pageCount) {\n commitPagination((p) => ({ ...p, pageIndex: pageCount - 1 }))\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [pageCount, pageIndex, manual, totalRows])\n\n const sortState: TableSortState | null = resolvedSorting[0]\n ? { key: resolvedSorting[0].id, direction: resolvedSorting[0].desc ? 'desc' : 'asc' }\n : null\n // the current table state, with the ready-to-use server-request params built from the query mapping (so a\n // consumer fetch / export is a one-liner). Rebuilt on demand — the emit effect + the export actions share it.\n const getTableState = (): TableChangeState => {\n const currentPageNum = pageIndex + 1\n const size = resolvedPageSize\n const params = buildTableQuery(\n { page: currentPageNum, size, search: resolvedGlobalFilter, sort: sortState },\n queryMappingRef.current,\n )\n // fold the active filters into the same server-request query (config-driven param names/format)\n if (filters?.length) {\n buildFilterQuery(filters, resolvedFilterState, queryMappingRef.current).forEach((v, k) =>\n params.append(k, v),\n )\n }\n return {\n page: currentPageNum,\n size,\n search: resolvedGlobalFilter,\n sort: sortState,\n filters: resolvedFilterState,\n params,\n query: prettyQuery(params),\n }\n }\n // emit the full state on mount + whenever it changes — the server-mode fetch driver\n useEffect(() => {\n onChangeRef.current?.(getTableState())\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [pageIndex, resolvedPageSize, resolvedGlobalFilter, resolvedSorting, resolvedFilterState])\n\n const hasExport = onExportToEmail != null\n const hasFilters = filters != null && filters.length > 0\n\n // mirror the table's state to the URL using the SAME builder as the server request (`state.query`), so the\n // address bar matches the request shape (e.g. `?page=1&size=10&sortBy=rating&orderBy=desc`). `replaceState`\n // (no history spam); canonicalizes on mount; params the table doesn't own are preserved. Gated by `urlSync`.\n // the pathname this table's params were last written on (read by the unmount cleanup below)\n const urlPathRef = useRef<string | null>(null)\n const writeQuery = useCallback(\n (\n page: number,\n pageSize: number,\n search: string,\n sort: TableSortState | null,\n activeFilters: TableFilterState,\n ) => {\n if (typeof window === 'undefined' || !urlSync) return\n urlPathRef.current = window.location.pathname // the page this table's params now live on\n const mapping = queryMappingRef.current\n const defs = filtersRef.current\n // build the same params the request uses (page/size/search/sort + the active filters)\n const built = buildTableQuery({ page, size: pageSize, search, sort }, mapping)\n if (defs?.length) {\n buildFilterQuery(defs, activeFilters, mapping).forEach((v, k) => built.append(k, v))\n }\n // the params the table owns are cleared before copying `built` in, so a now-empty piece (cleared\n // search, unset filter, \"All\" dropping page/size) drops out of the URL too; unrelated params (another\n // widget's `?tab=…`) are kept\n const owns = tableOwnsParam(mapping, defs)\n const params = new URLSearchParams(window.location.search)\n for (const key of [...params.keys()]) if (owns(key)) params.delete(key)\n built.forEach((v, k) => params.append(k, v))\n\n const query = prettyQuery(params)\n const url = `${window.location.pathname}${query ? `?${query}` : ''}${window.location.hash}`\n // skip a no-op write (e.g. the mount canonicalization when the URL already matches)\n if (url === `${window.location.pathname}${window.location.search}${window.location.hash}`)\n return\n window.history.replaceState(window.history.state, '', url)\n },\n [urlSync],\n )\n useEffect(() => {\n writeQuery(\n pageIndex + 1,\n resolvedPageSize,\n resolvedGlobalFilter,\n sortState,\n resolvedFilterState,\n )\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n pageIndex,\n resolvedPageSize,\n resolvedGlobalFilter,\n resolvedSorting,\n resolvedFilterState,\n writeQuery,\n ])\n\n // On unmount, strip the table's own params — but only while the page it wrote them on is still showing\n // (same pathname: a tab switch / closing sheet / conditional render). After a navigation the URL belongs to\n // the new page, which may use the same names for its own table, so it's left alone. Mount-once with refs\n // (not deps), so toggling a prop never strips a live table's params. StrictMode's simulated unmount strips\n // them too, but its re-run of the write effect above puts the current state straight back.\n const urlSyncRef = useRef(urlSync)\n urlSyncRef.current = urlSync\n const clearUrlRef = useRef(clearUrlOnUnmount)\n clearUrlRef.current = clearUrlOnUnmount\n useEffect(() => {\n if (typeof window === 'undefined') return\n urlPathRef.current ??= window.location.pathname\n return () => {\n if (!urlSyncRef.current || !clearUrlRef.current) return\n if (window.location.pathname !== urlPathRef.current) return\n const owns = tableOwnsParam(queryMappingRef.current, filtersRef.current)\n const params = new URLSearchParams(window.location.search)\n const keys = [...params.keys()].filter(owns)\n if (keys.length === 0) return\n for (const key of keys) params.delete(key)\n const query = prettyQuery(params)\n window.history.replaceState(\n window.history.state,\n '',\n `${window.location.pathname}${query ? `?${query}` : ''}${window.location.hash}`,\n )\n }\n }, [])\n\n // Back/Forward → restore state from the query (parsed with the same mapping). Kept fresh behind a stable\n // ref (the commit* helpers + resolved values change each render), so the listener never re-subscribes. It\n // restores WITHOUT resetting the page (the URL carries the intended page) and routes through the commit*\n // helpers so a controlled parent is notified of the Back/Forward navigation too.\n const popStateRef = useRef<() => void>(() => {})\n popStateRef.current = () => {\n const params = new URLSearchParams(window.location.search)\n const mapping = queryMappingRef.current\n const parsed = parseTableQuery(params, mapping)\n commitPagination(() => ({\n pageIndex: (parsed.page ?? defaultPage) - 1,\n pageSize: parsed.size ?? resolvedPageSize,\n }))\n setSearchInput(parsed.search)\n commitSearch(parsed.search, false)\n commitSorting(\n () => (parsed.sort ? [{ id: parsed.sort.key, desc: parsed.sort.direction === 'desc' }] : []),\n false,\n )\n const defs = filtersRef.current\n if (defs?.length) commitFilters(parseFilterQuery(defs, params, mapping), false)\n }\n useEffect(() => {\n if (typeof window === 'undefined' || !urlSync) return\n const handler = () => popStateRef.current()\n window.addEventListener('popstate', handler)\n return () => window.removeEventListener('popstate', handler)\n }, [urlSync])\n\n // dev-only: a row-interactive table that relies on the index as its React key can misplace row DOM (and\n // in-cell focus / state) when rows reorder or a server page swaps in — hint to pass `getRowId`. Fires once.\n useEffect(() => {\n if (isDev() && !getRowId && (onRowClick != null || actions != null || reorderable)) {\n console.warn(\n '[Table] No `getRowId` provided, so the row index is used as the React key. For a table with row ' +\n 'interactions or changing / paged data, pass `getRowId` (e.g. `(row) => row.id`) so each row keeps ' +\n 'its identity across sort / filter / refetch.',\n )\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n // track horizontal scroll so a pinned column shows its shadow only while content is hidden under it\n useEffect(() => {\n const el = scrollRef.current\n if (!el) return\n const update = () => {\n const canScroll = el.scrollWidth > el.clientWidth + 1\n const atStart = el.scrollLeft <= 0\n const atEnd = el.scrollLeft >= el.scrollWidth - el.clientWidth - 1\n const next = { start: canScroll && !atStart, end: canScroll && !atEnd }\n setPinShadow((s) => (s.start === next.start && s.end === next.end ? s : next))\n }\n update()\n el.addEventListener('scroll', update, { passive: true })\n const ro = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(update) : null\n ro?.observe(el)\n if (ro && tableRef.current) ro.observe(tableRef.current)\n return () => {\n el.removeEventListener('scroll', update)\n ro?.disconnect()\n }\n }, [])\n\n const hasToolbar =\n title != null ||\n toolbar != null ||\n searchable ||\n hasFilters ||\n sortableColumns.length > 0 ||\n hasExport\n\n // the data `<td>`s for one row — shared by the plain and the reorderable (`SortableRow`) row paths\n const rowCells = (row: (typeof rows)[number]) =>\n renderColumns.map((col) => (\n <td\n key={col.key}\n className={clsx(\n styles.td,\n col.pinned === 'left' && styles.pinnedLeft,\n col.pinned === 'right' && styles.pinnedRight,\n (col.wrap || col.maxWidth != null) && styles.wrapCell,\n )}\n style={\n {\n width: col.width ?? (col.pinned ? 1 : wrapCap(col)),\n maxWidth: wrapCap(col),\n textAlign: col.align,\n } as CSSProperties\n }\n >\n {renderCellContent(\n col.cell ? col.cell(row.original, row.index) : formatCell(row.getValue(col.key)),\n )}\n </td>\n ))\n\n return (\n <div ref={ref} className={clsx(styles.root, className)} {...props}>\n {hasToolbar && (\n <div className={styles.toolbar}>\n {/* left group — title + search */}\n <div className={styles.toolbarStart}>\n {title != null && (\n <Typography variant=\"h4\" as=\"div\" className={styles.title}>\n {title}\n </Typography>\n )}\n {searchable && (\n <TextField\n className={styles.search}\n fullWidth={false}\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n placeholder={searchPlaceholder ?? t('common.search')}\n adornment={<Icon name=\"SearchNormal\" />}\n aria-label={t('common.search')}\n />\n )}\n </div>\n {/* right group — custom toolbar content + filters + sort + export */}\n <div className={styles.toolbarEnd}>\n {toolbar}\n {hasExport && (\n // export menu — a baked \"Send on Email\" item; the consumer only wires `onExportToEmail`\n <Dropdown\n placement=\"bottom-end\"\n trigger={\n <IconButton variant=\"filled\" size=\"sm\" aria-label={t('table.export')}>\n <Icon name=\"ExportArrow\" />\n </IconButton>\n }\n >\n <Typography\n as=\"div\"\n variant=\"caption\"\n color=\"muted\"\n uppercase\n className={styles.menuTitle}\n >\n {t('table.export')}\n </Typography>\n <ListItem clickable icon=\"Sms\" onClick={() => onExportToEmail?.(getTableState())}>\n {t('table.sendOnEmail')}\n </ListItem>\n </Dropdown>\n )}\n {sortableColumns.length > 0 && (\n // sort menu — one row per sortable column; clicking cycles that column asc → desc → unsorted.\n // The menu **stays open** (`closeOnSelect={false}`) so you can cycle without reopening; the\n // active row shows a `selected` tint + a direction arrow, and a dot `Badge` on the trigger\n // flags that a sort is applied.\n <Dropdown\n placement=\"bottom-end\"\n closeOnSelect={false}\n trigger={\n <Badge dot={resolvedSorting.length > 0} color=\"primary\">\n <IconButton variant=\"filled\" size=\"sm\" aria-label={t('table.sort')}>\n <Icon name=\"Sort\" />\n </IconButton>\n </Badge>\n }\n >\n <Typography\n as=\"div\"\n variant=\"caption\"\n color=\"muted\"\n uppercase\n className={styles.menuTitle}\n >\n {t('table.sortBy')}\n </Typography>\n {sortableColumns.map((col) => {\n const active = sortState?.key === col.key\n return (\n <ListItem\n key={col.key}\n clickable\n selected={active}\n // active column shows its direction (↑ asc / ↓ desc); clicking cycles asc → desc → off\n trailing={\n active ? (\n <Icon name={sortState?.direction === 'desc' ? 'ArrowDown' : 'ArrowUp2'} />\n ) : undefined\n }\n onClick={() => cycleSort(col.key)}\n >\n {col.header}\n </ListItem>\n )\n })}\n </Dropdown>\n )}\n {hasFilters && (\n <TableFilters\n filters={filters}\n value={resolvedFilterState}\n onChange={handleFiltersChange}\n />\n )}\n </div>\n </div>\n )}\n\n <ReorderProvider enabled={reorderable} sensors={sensors} onDragEnd={handleReorder}>\n <div\n ref={scrollRef}\n className={styles.scroll}\n data-pin-start={pinShadow.start ? 'true' : 'false'}\n data-pin-end={pinShadow.end ? 'true' : 'false'}\n >\n <table\n ref={tableRef}\n className={clsx(\n styles.table,\n striped && styles.striped,\n hoverable && styles.hoverable,\n stickyHeader && styles.sticky,\n )}\n aria-busy={loading || undefined}\n >\n <thead>\n <tr>\n {reorderable && (\n <th className={clsx(styles.th, styles.dragHandleCell)} scope=\"col\" aria-hidden />\n )}\n {renderColumns.map((col) => {\n // look the column up only when sortable (for aria-sort) — the synthetic `__actions`\n // column isn't registered with TanStack, and getColumn would warn on its id\n const sorted = (col.sortable && table.getColumn(col.key)?.getIsSorted()) || false\n return (\n <th\n key={col.key}\n scope=\"col\"\n className={clsx(\n styles.th,\n col.pinned === 'left' && styles.pinnedLeft,\n col.pinned === 'right' && styles.pinnedRight,\n (col.wrap || col.maxWidth != null) && styles.wrapCell,\n )}\n style={\n {\n // a pinned column with no explicit width shrinks to its content (the `width: 1px`\n // min-content trick); a wrap column sits at its cap (so it doesn't get starved),\n // others size to content\n width: col.width ?? (col.pinned ? 1 : wrapCap(col)),\n maxWidth: wrapCap(col),\n textAlign: col.align,\n } as CSSProperties\n }\n aria-sort={\n col.sortable\n ? sorted === 'asc'\n ? 'ascending'\n : sorted === 'desc'\n ? 'descending'\n : 'none'\n : undefined\n }\n >\n {/* sorting lives in the toolbar's sort menu, not the header; `aria-sort` above still\n reflects the current sort for a11y */}\n {col.header}\n </th>\n )\n })}\n </tr>\n </thead>\n <tbody>\n {rows.length > 0 ? (\n reorderable ? (\n // dnd-kit sortable rows — each `SortableRow` renders a leading drag-handle cell + `rowCells`\n <SortableContext\n items={rows.map((row) => row.id)}\n strategy={verticalListSortingStrategy}\n >\n {rows.map((row) => (\n <SortableRow\n key={row.id}\n id={row.id}\n clickable={!!onRowClick}\n onClick={onRowClick ? () => onRowClick(row.original, row.index) : undefined}\n cells={rowCells(row)}\n />\n ))}\n </SortableContext>\n ) : (\n rows.map((row) => (\n <tr\n key={row.id}\n className={clsx(styles.tr, onRowClick && styles.clickable)}\n onClick={onRowClick ? () => onRowClick(row.original, row.index) : undefined}\n >\n {rowCells(row)}\n </tr>\n ))\n )\n ) : // no rows yet: skeleton rows shaped like the real columns while fetching (first load),\n // otherwise the empty state\n loading ? (\n Array.from(\n {\n length:\n loadingRows ??\n Math.min(resolvedPageSize === ALL_ROWS ? 10 : resolvedPageSize, 10),\n },\n (_, r) => (\n <tr key={r} className={styles.tr} aria-hidden=\"true\">\n {reorderable && <td className={clsx(styles.td, styles.dragHandleCell)} />}\n {renderColumns.map((col, c) => (\n <td\n key={col.key}\n className={clsx(\n styles.td,\n col.pinned === 'left' && styles.pinnedLeft,\n col.pinned === 'right' && styles.pinnedRight,\n col.key === '__actions' && styles.skeletonActionsCell,\n )}\n style={{ width: col.width, textAlign: col.align } as CSSProperties}\n >\n {col.key === '__actions' ? (\n // the auto actions column — two small squares (26px, 8px apart), right-aligned\n <span className={clsx(styles.rowActions, styles.skeletonActions)}>\n <Skeleton\n variant=\"rect\"\n width=\"calc(var(--tz-control-height-sm) - var(--tz-space-xs))\"\n height=\"calc(var(--tz-control-height-sm) - var(--tz-space-xs))\"\n radius=\"xs\"\n />\n <Skeleton\n variant=\"rect\"\n width=\"calc(var(--tz-control-height-sm) - var(--tz-space-xs))\"\n height=\"calc(var(--tz-control-height-sm) - var(--tz-space-xs))\"\n radius=\"xs\"\n />\n </span>\n ) : (\n <Skeleton\n width={SKELETON_WIDTHS[(r * 3 + c) % SKELETON_WIDTHS.length]}\n className={styles.skeletonCell}\n />\n )}\n </td>\n ))}\n </tr>\n ),\n )\n ) : (\n <tr>\n <td\n colSpan={Math.max(1, renderColumns.length + (reorderable ? 1 : 0))}\n className={styles.stateCell}\n >\n {empty ?? <EmptyState />}\n </td>\n </tr>\n )}\n </tbody>\n </table>\n {/* while refetching with rows already shown, dim them + spinner; the no-rows case is handled in\n the body above (skeleton rows), not this overlay */}\n {loading && rows.length > 0 && (\n <div className={styles.loadingOverlay}>\n <Loader size=\"lg\" />\n </div>\n )}\n </div>\n </ReorderProvider>\n\n {/* the footer only exists to carry the rows-per-page select and/or the page navigator — with\n neither (no useful / allowed size Select AND a single page — e.g. a 2-row detail table), drop it\n entirely, the \"1–N of N\" range included */}\n {totalRows > 0 && (showSizeSelect || pageCount > 1) && (\n <div className={styles.footer}>\n {/* the range count sits on its own row at the top */}\n <Typography variant=\"bodySmall\" color=\"muted\" as=\"span\" className={styles.rangeText}>\n {t('table.range', { from: rangeStart, to: rangeEnd, total: totalRows })}\n </Typography>\n {/* below it: rows-per-page (left) + the page navigator (right). The navigator is pointless with\n a single page (few rows / the \"All\" size) — hidden then. */}\n <div className={styles.footerMain}>\n {showSizeSelect && (\n <div className={styles.pageSize}>\n <Typography variant=\"bodySmall\" color=\"muted\" as=\"span\">\n {t('table.rowsPerPage')}\n </Typography>\n <Select\n className={styles.pageSizeSelect}\n fullWidth={false}\n clearable={false}\n showSelectedTick={false}\n value={resolvedPageSize >= ALL_ROWS ? 'all' : String(resolvedPageSize)}\n onChange={(value) =>\n commitPagination(() => ({\n pageIndex: 0,\n pageSize: value === 'all' ? ALL_ROWS : Number(value),\n }))\n }\n options={pageSizeChoices}\n />\n </div>\n )}\n {pageCount > 1 && (\n <Pagination\n count={pageCount}\n page={currentPage}\n onChange={(nextPage) =>\n commitPagination((p) => ({ ...p, pageIndex: nextPage - 1 }))\n }\n showFirstButton={showFirstButton}\n showLastButton={showLastButton}\n disabled={loading}\n />\n )}\n </div>\n </div>\n )}\n </div>\n )\n}) as <T>(props: TableProps<T> & { ref?: ForwardedRef<HTMLDivElement> }) => ReactElement\n"],"names":["isFilterActive","type","value","activeFilterCount","filters","state","n","f","pad","localDay","d","localMinute","localTime","toLocalDate","s","iso","datePart","dateTimePart","timePart","matchOne","cell","min","max","part","from","to","t","applyFilters","rows","active","row","buildFilterQuery","mapping","params","minSuffix","maxSuffix","multiFormat","param","arr","v","i","parseFilterQuery","lo","hi","boolOptions","labels","boolToStr","strToBool","RangeField","label","stacked","jsxs","styles","jsx","Typography","FilterField","filter","onChange","useT","options","placeholder","TextField","e","NumberField","low","high","Slider","a","b","Select","RadioGroup","disabled","MultiSelect","DatePicker","TimePicker","DateTimePicker","TableFilters","open","setOpen","useState","draft","setDraft","count","formId","useId","openPanel","commit","Fragment","Badge","IconButton","Icon","Modal","Button","prev","ALL_ROWS","SKELETON_WIDTHS","DEFAULT_WRAP_MAX_WIDTH","resolveUpdater","updater","old","wrapCap","col","formatCell","renderCellContent","content","prettyQuery","tableOwnsParam","m","owned","p","restrictToBoundingRect","transform","rect","boundingRect","restrictToVerticalAxis","restrictToParentElement","containerNodeRect","draggingNodeRect","rowDragModifiers","SortableRow","id","cells","clickable","onClick","setNodeRef","transition","isDragging","attributes","listeners","useSortable","clsx","CSS","ReorderProvider","enabled","sensors","onDragEnd","children","DndContext","closestCenter","Table","forwardRef","columns","data","getRowId","title","toolbar","searchable","searchPlaceholder","defaultSearch","debounceMs","defaultPage","defaultPageSize","pageSizeOptions","allowAllRows","showPageSize","showFirstButton","showLastButton","manualPagination","rowCount","defaultSort","queryMapping","onExportToEmail","defaultFilters","onRowClick","actions","reorderable","onReorder","loading","loadingRows","empty","urlSync","clearUrlOnUnmount","page","onPageChange","pageSize","onPageSizeChange","search","onSearchChange","sort","onSortChange","filterValues","onFiltersChange","stickyHeader","striped","hoverable","className","props","ref","configQueryMapping","useTableQueryConfig","queryMappingRef","useRef","onChangeRef","filtersRef","scrollRef","tableRef","pinShadow","setPinShadow","urlSeed","parseTableQuery","pagination","setPagination","searchInput","setSearchInput","globalFilter","setGlobalFilter","sorting","setSorting","filterState","setFilterState","manual","pageControlled","sizeControlled","searchControlled","sortControlled","filtersControlled","resolvedPagination","resolvedGlobalFilter","resolvedSorting","useMemo","resolvedFilterState","commitPagination","cur","next","resetToFirstPage","commitSearch","resetPage","commitSorting","commitFilters","filteredData","handleFiltersChange","tanstackColumns","pageSizeChoices","opts","renderColumns","actionsColumn","index","sortableColumns","c","cycleSort","key","table","useReactTable","getCoreRowModel","getPaginationRowModel","getFilteredRowModel","getSortedRowModel","useSensors","useSensor","PointerSensor","KeyboardSensor","sortableKeyboardCoordinates","rowIdOf","handleReorder","event","over","r","arrayMove","totalRows","pageIndex","resolvedPageSize","pageCount","smallestPageSize","showSizeSelect","currentPage","rangeStart","rangeEnd","useEffect","handle","sortState","getTableState","currentPageNum","size","buildTableQuery","k","_a","hasExport","hasFilters","urlPathRef","writeQuery","useCallback","activeFilters","defs","built","owns","query","url","urlSyncRef","clearUrlRef","keys","popStateRef","parsed","handler","isDev","el","update","canScroll","atStart","atEnd","ro","hasToolbar","rowCells","Dropdown","ListItem","sorted","SortableContext","verticalListSortingStrategy","_","Skeleton","EmptyState","Loader","Pagination","nextPage"],"mappings":"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"}
|