@customafk/lunas-ui 0.2.83 → 0.2.85
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/LoginPage-DGgThT3s.mjs +2 -0
- package/dist/LoginPage-DGgThT3s.mjs.map +1 -0
- package/dist/LoginPage-DPUdRD0r.cjs +2 -0
- package/dist/LoginPage-DPUdRD0r.cjs.map +1 -0
- package/dist/action-submit-B2qFdfi6.cjs +2 -0
- package/dist/{action-submit-B9vHpLoN.cjs.map → action-submit-B2qFdfi6.cjs.map} +1 -1
- package/dist/action-submit-DyNvI-F2.mjs +2 -0
- package/dist/{action-submit-BQdkz4mS.mjs.map → action-submit-DyNvI-F2.mjs.map} +1 -1
- package/dist/actions-form-CB0lZlE6.mjs +2 -0
- package/dist/{actions-form-D4n1W3-X.mjs.map → actions-form-CB0lZlE6.mjs.map} +1 -1
- package/dist/actions-form-DnlpVrgF.cjs +2 -0
- package/dist/{actions-form-DF2eYxGQ.cjs.map → actions-form-DnlpVrgF.cjs.map} +1 -1
- package/dist/checkbox-field-CFPHAcwN.cjs +2 -0
- package/dist/{checkbox-field-ldZRSCca.cjs.map → checkbox-field-CFPHAcwN.cjs.map} +1 -1
- package/dist/checkbox-field-DodKeFS_.mjs +2 -0
- package/dist/{checkbox-field-BRGTLOjq.mjs.map → checkbox-field-DodKeFS_.mjs.map} +1 -1
- package/dist/{cms-layout-BGsf1E4E.cjs → cms-layout-DYEmSqzx.cjs} +2 -2
- package/dist/{cms-layout-BGsf1E4E.cjs.map → cms-layout-DYEmSqzx.cjs.map} +1 -1
- package/dist/combobox-field-D7cZ8fhZ.cjs +2 -0
- package/dist/{combobox-field-ZYr7636s.cjs.map → combobox-field-D7cZ8fhZ.cjs.map} +1 -1
- package/dist/combobox-field-ebIvbhJn.mjs +2 -0
- package/dist/{combobox-field-CvkdZkQE.mjs.map → combobox-field-ebIvbhJn.mjs.map} +1 -1
- package/dist/data-display/country.cjs +1 -1
- package/dist/date-field-CNkxebta.mjs +2 -0
- package/dist/{date-field-DGMTG_hu.mjs.map → date-field-CNkxebta.mjs.map} +1 -1
- package/dist/date-field-Dm367ro9.cjs +2 -0
- package/dist/{date-field-1Hmcv8Zp.cjs.map → date-field-Dm367ro9.cjs.map} +1 -1
- package/dist/dialog-form-D9Bifsx6.cjs +2 -0
- package/dist/{dialog-form-C1qpltYx.cjs.map → dialog-form-D9Bifsx6.cjs.map} +1 -1
- package/dist/dialog-form-zK6Gk9Gk.mjs +2 -0
- package/dist/{dialog-form-BRSZpRTC.mjs.map → dialog-form-zK6Gk9Gk.mjs.map} +1 -1
- package/dist/{dist-DzA--RwW.cjs → dist-CIdWHwhj.cjs} +2 -2
- package/dist/{dist-DzA--RwW.cjs.map → dist-CIdWHwhj.cjs.map} +1 -1
- package/dist/email-field-BVl7u9pR.mjs +2 -0
- package/dist/{email-field-C2Lvl_rQ.mjs.map → email-field-BVl7u9pR.mjs.map} +1 -1
- package/dist/email-field-CqXXRG3w.cjs +2 -0
- package/dist/{email-field-D3nSkHj2.cjs.map → email-field-CqXXRG3w.cjs.map} +1 -1
- package/dist/features/tables/index.d.cts +1 -1
- package/dist/features/tables/index.d.mts +1 -1
- package/dist/features/tanstack-form/index.cjs +1 -1
- package/dist/features/tanstack-form/index.d.cts +1 -1
- package/dist/features/tanstack-form/index.d.mts +1 -1
- package/dist/features/tanstack-form/index.mjs +1 -1
- package/dist/features/text-editor/index.cjs +1 -1
- package/dist/features/text-editor/index.d.cts +1 -1
- package/dist/features/text-editor/index.d.mts +1 -1
- package/dist/features/text-editor/index.mjs +1 -1
- package/dist/{flex-C63_IqSY.d.cts → flex-D6RCsrv1.d.cts} +2 -2
- package/dist/{flex-C63_IqSY.d.mts → flex-D6RCsrv1.d.mts} +2 -2
- package/dist/group-field-8nINgAeO.mjs +2 -0
- package/dist/{group-field-gejvx_Td.mjs.map → group-field-8nINgAeO.mjs.map} +1 -1
- package/dist/group-field-DfGPDLyp.cjs +2 -0
- package/dist/{group-field-sVykO2JZ.cjs.map → group-field-DfGPDLyp.cjs.map} +1 -1
- package/dist/{index-DvC1inRy.d.cts → index-0HuXxgjQ.d.cts} +13 -10
- package/dist/index-6_zytlWu.d.cts +70 -0
- package/dist/index-6_zytlWu.d.mts +70 -0
- package/dist/{index-CrkOhm--.d.mts → index-BCBEYTyA.d.mts} +5 -5
- package/dist/{index--wNkNzCB.d.cts → index-CQPyC0Q2.d.cts} +5 -5
- package/dist/{index-DvC1inRy.d.mts → index-CZ_2KVir.d.mts} +13 -10
- package/dist/{index-DRAyYm8g.d.mts → index-CvFEJoon.d.cts} +12 -3
- package/dist/{index-DRAyYm8g.d.cts → index-CvFEJoon.d.mts} +12 -3
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +6 -6
- package/dist/index.d.mts +6 -6
- package/dist/index.mjs +1 -1
- package/dist/layouts/cms-layout/index.cjs +1 -1
- package/dist/layouts/flex.d.cts +1 -1
- package/dist/layouts/flex.d.mts +1 -1
- package/dist/layouts/payment-layout/index.cjs +1 -1
- package/dist/number-field-BjGl_IiN.cjs +2 -0
- package/dist/{number-field-CWDYA3La.cjs.map → number-field-BjGl_IiN.cjs.map} +1 -1
- package/dist/number-field-CVemIwIg.mjs +2 -0
- package/dist/{number-field-CR5PLX6H.mjs.map → number-field-CVemIwIg.mjs.map} +1 -1
- package/dist/pages/LoginPage/index.cjs +1 -0
- package/dist/pages/LoginPage/index.d.cts +2 -0
- package/dist/pages/LoginPage/index.d.mts +2 -0
- package/dist/pages/LoginPage/index.mjs +1 -0
- package/dist/password-field-Be0Ltlxh.cjs +2 -0
- package/dist/{password-field-BHRhVyZ0.cjs.map → password-field-Be0Ltlxh.cjs.map} +1 -1
- package/dist/password-field-BxYaT8lO.mjs +2 -0
- package/dist/{password-field-B2_kzss6.mjs.map → password-field-BxYaT8lO.mjs.map} +1 -1
- package/dist/{payment-layout-BZtIcu-3.cjs → payment-layout-C38xIc2X.cjs} +2 -2
- package/dist/{payment-layout-BZtIcu-3.cjs.map → payment-layout-C38xIc2X.cjs.map} +1 -1
- package/dist/popover-form-Ba_Nw79b.cjs +2 -0
- package/dist/{popover-form-Ch_iMMSm.cjs.map → popover-form-Ba_Nw79b.cjs.map} +1 -1
- package/dist/popover-form-C9mNInr2.mjs +2 -0
- package/dist/{popover-form-CeRVpy1B.mjs.map → popover-form-C9mNInr2.mjs.map} +1 -1
- package/dist/radio-group-field-BCJWamjd.cjs +2 -0
- package/dist/{radio-group-field-BFhBfzoT.cjs.map → radio-group-field-BCJWamjd.cjs.map} +1 -1
- package/dist/radio-group-field-DYqU_6hW.mjs +2 -0
- package/dist/{radio-group-field-Iwo2Q2Ig.mjs.map → radio-group-field-DYqU_6hW.mjs.map} +1 -1
- package/dist/{resizable-CNqPu4Ck.d.cts → resizable-DTnfCua-.d.cts} +2 -2
- package/dist/{resizable-CNqPu4Ck.d.mts → resizable-DTnfCua-.d.mts} +2 -2
- package/dist/rolldown-runtime-DWNI8pZO.cjs +1 -0
- package/dist/select-field-D7Ny2Qne.mjs +2 -0
- package/dist/{select-field-NJgDDCO2.mjs.map → select-field-D7Ny2Qne.mjs.map} +1 -1
- package/dist/select-field-UWnBMAzL.cjs +2 -0
- package/dist/{select-field-CvDBZQTl.cjs.map → select-field-UWnBMAzL.cjs.map} +1 -1
- package/dist/simple-array-field-BSMxRilE.cjs +2 -0
- package/dist/{simple-array-field-aGXkDZXD.cjs.map → simple-array-field-BSMxRilE.cjs.map} +1 -1
- package/dist/simple-array-field-DJXa_vST.mjs +2 -0
- package/dist/{simple-array-field-BwNCeUnn.mjs.map → simple-array-field-DJXa_vST.mjs.map} +1 -1
- package/dist/simple-boolean-field-CVNT8NBk.mjs +2 -0
- package/dist/{simple-boolean-field-t_XDXqYs.mjs.map → simple-boolean-field-CVNT8NBk.mjs.map} +1 -1
- package/dist/simple-boolean-field-CxAyVQ1w.cjs +2 -0
- package/dist/{simple-boolean-field-BeVkn3c4.cjs.map → simple-boolean-field-CxAyVQ1w.cjs.map} +1 -1
- package/dist/simple-combobox-field-BP4IeDkA.cjs +2 -0
- package/dist/{simple-combobox-field-U0ZAl7VQ.cjs.map → simple-combobox-field-BP4IeDkA.cjs.map} +1 -1
- package/dist/simple-combobox-field-BnAUDfQU.mjs +2 -0
- package/dist/{simple-combobox-field-HCB4A33-.mjs.map → simple-combobox-field-BnAUDfQU.mjs.map} +1 -1
- package/dist/simple-date-field-DIa6UBF2.mjs +2 -0
- package/dist/{simple-date-field-Dj4bJoji.mjs.map → simple-date-field-DIa6UBF2.mjs.map} +1 -1
- package/dist/simple-date-field-NSawlSff.cjs +2 -0
- package/dist/{simple-date-field-DtxEpEZj.cjs.map → simple-date-field-NSawlSff.cjs.map} +1 -1
- package/dist/simple-email-field-2Abh3qZw.cjs +2 -0
- package/dist/{simple-email-field-DK9I_Tc_.cjs.map → simple-email-field-2Abh3qZw.cjs.map} +1 -1
- package/dist/simple-email-field-CKDQgzh5.mjs +2 -0
- package/dist/{simple-email-field-BDyhkmHV.mjs.map → simple-email-field-CKDQgzh5.mjs.map} +1 -1
- package/dist/simple-number-field-BjEYE54F.cjs +2 -0
- package/dist/{simple-number-field-BspqWU-3.cjs.map → simple-number-field-BjEYE54F.cjs.map} +1 -1
- package/dist/simple-number-field-SDbxL6L7.mjs +2 -0
- package/dist/{simple-number-field-hneXMhfJ.mjs.map → simple-number-field-SDbxL6L7.mjs.map} +1 -1
- package/dist/simple-password-field-Cjp6yzWd.cjs +2 -0
- package/dist/{simple-password-field-BEEcleom.cjs.map → simple-password-field-Cjp6yzWd.cjs.map} +1 -1
- package/dist/simple-password-field-Cnj-hf5g.mjs +2 -0
- package/dist/{simple-password-field-vsLRHDk4.mjs.map → simple-password-field-Cnj-hf5g.mjs.map} +1 -1
- package/dist/simple-radio-group-field-4-eWSXY7.mjs +2 -0
- package/dist/{simple-radio-group-field-BURm_BSA.mjs.map → simple-radio-group-field-4-eWSXY7.mjs.map} +1 -1
- package/dist/simple-radio-group-field-CuA0Q-XI.cjs +2 -0
- package/dist/{simple-radio-group-field-Wm8xB0fN.cjs.map → simple-radio-group-field-CuA0Q-XI.cjs.map} +1 -1
- package/dist/simple-select-field-C0ecQx68.mjs +2 -0
- package/dist/{simple-select-field-8cY51U4d.mjs.map → simple-select-field-C0ecQx68.mjs.map} +1 -1
- package/dist/simple-select-field-CXYJcRY2.cjs +2 -0
- package/dist/{simple-select-field-QQ65caBf.cjs.map → simple-select-field-CXYJcRY2.cjs.map} +1 -1
- package/dist/simple-text-field-DJl5SIGn.mjs +2 -0
- package/dist/{simple-text-field-DK72_OA_.mjs.map → simple-text-field-DJl5SIGn.mjs.map} +1 -1
- package/dist/simple-text-field-DPXqNCXh.cjs +2 -0
- package/dist/{simple-text-field-BHkCPiE5.cjs.map → simple-text-field-DPXqNCXh.cjs.map} +1 -1
- package/dist/simple-textarea-field-BcHdUMTK.mjs +2 -0
- package/dist/{simple-textarea-field-B72nNQHv.mjs.map → simple-textarea-field-BcHdUMTK.mjs.map} +1 -1
- package/dist/simple-textarea-field-ZpXPwYz-.cjs +2 -0
- package/dist/{simple-textarea-field-Bu5h7sfH.cjs.map → simple-textarea-field-ZpXPwYz-.cjs.map} +1 -1
- package/dist/switch-field-CCDuDdpf.cjs +2 -0
- package/dist/{switch-field-eLVlQZSI.cjs.map → switch-field-CCDuDdpf.cjs.map} +1 -1
- package/dist/switch-field-DBGFsmEZ.mjs +2 -0
- package/dist/{switch-field-DoPUWb9d.mjs.map → switch-field-DBGFsmEZ.mjs.map} +1 -1
- package/dist/tanstack-form-BhKAn9I0.mjs +2 -0
- package/dist/tanstack-form-BhKAn9I0.mjs.map +1 -0
- package/dist/tanstack-form-DCB2addt.cjs +2 -0
- package/dist/tanstack-form-DCB2addt.cjs.map +1 -0
- package/dist/text-editor-DWZf3yrW.cjs +2 -0
- package/dist/text-editor-DWZf3yrW.cjs.map +1 -0
- package/dist/text-editor-XBOAwJk-.mjs +2 -0
- package/dist/text-editor-XBOAwJk-.mjs.map +1 -0
- package/dist/text-field-Bx_vnc4O.mjs +2 -0
- package/dist/{text-field-Bm-k6Jr7.mjs.map → text-field-Bx_vnc4O.mjs.map} +1 -1
- package/dist/text-field-DMZZ6CND.cjs +2 -0
- package/dist/{text-field-DT50dOVI.cjs.map → text-field-DMZZ6CND.cjs.map} +1 -1
- package/dist/textarea-field-BmImMdg-.cjs +2 -0
- package/dist/{textarea-field-BhqX29CS.cjs.map → textarea-field-BmImMdg-.cjs.map} +1 -1
- package/dist/textarea-field-Cim3l0y8.mjs +2 -0
- package/dist/{textarea-field-DNLyrRH7.mjs.map → textarea-field-Cim3l0y8.mjs.map} +1 -1
- package/dist/title-field-2dABwspv.mjs +2 -0
- package/dist/{title-field-oAqHRw59.mjs.map → title-field-2dABwspv.mjs.map} +1 -1
- package/dist/title-field-CFnSgTGH.cjs +2 -0
- package/dist/{title-field-B2hM3S_S.cjs.map → title-field-CFnSgTGH.cjs.map} +1 -1
- package/dist/ui/breadcrumb.cjs +1 -1
- package/dist/ui/button-group.cjs +1 -1
- package/dist/ui/button.cjs +1 -1
- package/dist/ui/carousel.cjs +1 -1
- package/dist/ui/dropdown-menu.cjs +1 -1
- package/dist/ui/dropdown-menu.cjs.map +1 -1
- package/dist/ui/dropdown-menu.mjs +1 -1
- package/dist/ui/dropdown-menu.mjs.map +1 -1
- package/dist/ui/file-uploader.cjs +1 -1
- package/dist/ui/item.cjs +1 -1
- package/dist/ui/resizable.cjs +1 -1
- package/dist/ui/resizable.d.cts +1 -1
- package/dist/ui/resizable.d.mts +1 -1
- package/package.json +9 -4
- package/styles/text-editor.css +205 -38
- package/dist/LoginPage-DDljzV6A.d.cts +0 -43
- package/dist/LoginPage-DDljzV6A.d.mts +0 -43
- package/dist/action-submit-B9vHpLoN.cjs +0 -2
- package/dist/action-submit-BQdkz4mS.mjs +0 -2
- package/dist/actions-form-D4n1W3-X.mjs +0 -2
- package/dist/actions-form-DF2eYxGQ.cjs +0 -2
- package/dist/checkbox-field-BRGTLOjq.mjs +0 -2
- package/dist/checkbox-field-ldZRSCca.cjs +0 -2
- package/dist/combobox-field-CvkdZkQE.mjs +0 -2
- package/dist/combobox-field-ZYr7636s.cjs +0 -2
- package/dist/date-field-1Hmcv8Zp.cjs +0 -2
- package/dist/date-field-DGMTG_hu.mjs +0 -2
- package/dist/dialog-form-BRSZpRTC.mjs +0 -2
- package/dist/dialog-form-C1qpltYx.cjs +0 -2
- package/dist/email-field-C2Lvl_rQ.mjs +0 -2
- package/dist/email-field-D3nSkHj2.cjs +0 -2
- package/dist/field-BSLi-P0Q.cjs +0 -2
- package/dist/field-BSLi-P0Q.cjs.map +0 -1
- package/dist/field-V2DoD8qL.mjs +0 -2
- package/dist/field-V2DoD8qL.mjs.map +0 -1
- package/dist/group-field-gejvx_Td.mjs +0 -2
- package/dist/group-field-sVykO2JZ.cjs +0 -2
- package/dist/number-field-CR5PLX6H.mjs +0 -2
- package/dist/number-field-CWDYA3La.cjs +0 -2
- package/dist/pages/LoginPage.cjs +0 -2
- package/dist/pages/LoginPage.cjs.map +0 -1
- package/dist/pages/LoginPage.d.cts +0 -2
- package/dist/pages/LoginPage.d.mts +0 -2
- package/dist/pages/LoginPage.mjs +0 -2
- package/dist/pages/LoginPage.mjs.map +0 -1
- package/dist/password-field-B2_kzss6.mjs +0 -2
- package/dist/password-field-BHRhVyZ0.cjs +0 -2
- package/dist/popover-form-CeRVpy1B.mjs +0 -2
- package/dist/popover-form-Ch_iMMSm.cjs +0 -2
- package/dist/radio-group-field-BFhBfzoT.cjs +0 -2
- package/dist/radio-group-field-Iwo2Q2Ig.mjs +0 -2
- package/dist/rolldown-runtime-CMqjfN_6.cjs +0 -1
- package/dist/select-field-CvDBZQTl.cjs +0 -2
- package/dist/select-field-NJgDDCO2.mjs +0 -2
- package/dist/simple-array-field-BwNCeUnn.mjs +0 -2
- package/dist/simple-array-field-aGXkDZXD.cjs +0 -2
- package/dist/simple-boolean-field-BeVkn3c4.cjs +0 -2
- package/dist/simple-boolean-field-t_XDXqYs.mjs +0 -2
- package/dist/simple-combobox-field-HCB4A33-.mjs +0 -2
- package/dist/simple-combobox-field-U0ZAl7VQ.cjs +0 -2
- package/dist/simple-date-field-Dj4bJoji.mjs +0 -2
- package/dist/simple-date-field-DtxEpEZj.cjs +0 -2
- package/dist/simple-email-field-BDyhkmHV.mjs +0 -2
- package/dist/simple-email-field-DK9I_Tc_.cjs +0 -2
- package/dist/simple-number-field-BspqWU-3.cjs +0 -2
- package/dist/simple-number-field-hneXMhfJ.mjs +0 -2
- package/dist/simple-password-field-BEEcleom.cjs +0 -2
- package/dist/simple-password-field-vsLRHDk4.mjs +0 -2
- package/dist/simple-radio-group-field-BURm_BSA.mjs +0 -2
- package/dist/simple-radio-group-field-Wm8xB0fN.cjs +0 -2
- package/dist/simple-select-field-8cY51U4d.mjs +0 -2
- package/dist/simple-select-field-QQ65caBf.cjs +0 -2
- package/dist/simple-text-field-BHkCPiE5.cjs +0 -2
- package/dist/simple-text-field-DK72_OA_.mjs +0 -2
- package/dist/simple-textarea-field-B72nNQHv.mjs +0 -2
- package/dist/simple-textarea-field-Bu5h7sfH.cjs +0 -2
- package/dist/switch-field-DoPUWb9d.mjs +0 -2
- package/dist/switch-field-eLVlQZSI.cjs +0 -2
- package/dist/tanstack-form-C0ab8EEl.cjs +0 -2
- package/dist/tanstack-form-C0ab8EEl.cjs.map +0 -1
- package/dist/tanstack-form-fkaBh9RO.mjs +0 -2
- package/dist/tanstack-form-fkaBh9RO.mjs.map +0 -1
- package/dist/text-editor-BtfyZSgR.cjs +0 -2
- package/dist/text-editor-BtfyZSgR.cjs.map +0 -1
- package/dist/text-editor-CtR27_PR.mjs +0 -2
- package/dist/text-editor-CtR27_PR.mjs.map +0 -1
- package/dist/text-editor-field-B6HEsAHt.mjs +0 -2
- package/dist/text-editor-field-B6HEsAHt.mjs.map +0 -1
- package/dist/text-editor-field-DcEUC0iH.cjs +0 -2
- package/dist/text-editor-field-DcEUC0iH.cjs.map +0 -1
- package/dist/text-field-Bm-k6Jr7.mjs +0 -2
- package/dist/text-field-DT50dOVI.cjs +0 -2
- package/dist/textarea-field-BhqX29CS.cjs +0 -2
- package/dist/textarea-field-DNLyrRH7.mjs +0 -2
- package/dist/title-field-B2hM3S_S.cjs +0 -2
- package/dist/title-field-oAqHRw59.mjs +0 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cms-layout-BGsf1E4E.cjs","names":["TooltipProvider","Input","Separator","Slot","Tooltip","TooltipTrigger","TooltipContent","colorHashLight","Button","MenuIcon","LunasLogo","DropdownMenu","DropdownMenuTrigger","Avatar","AvatarImage","AvatarFallback","UserRoundIcon","DropdownMenuContent","DropdownMenuSeparator","DropdownMenuGroup","DropdownMenuItem","LogOutIcon","EarthIcon","LogOutIcon"],"sources":["../packages/components/layouts/cms-layout/components/sidebar.tsx","../packages/components/layouts/cms-layout/components/header.tsx","../packages/components/layouts/cms-layout/index.tsx"],"sourcesContent":["'use client';\n\nimport { createContext, memo, useCallback, useContext, useEffect, useMemo, useState } from 'react';\n\nimport { PanelLeftIcon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Input } from '@/components/ui/input';\nimport { Separator } from '@/components/ui/separator';\nimport { Skeleton } from '@/components/ui/skeleton';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';\n\nimport { Slot } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nconst SIDEBAR_COOKIE_NAME = 'sidebar_state';\nconst SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;\nconst SIDEBAR_WIDTH = '16rem';\nconst SIDEBAR_WIDTH_ICON = '3rem';\nconst SIDEBAR_KEYBOARD_SHORTCUT = 'b';\n\ntype SidebarContextProps = {\n state: 'expanded' | 'collapsed';\n open: boolean;\n setOpen: (open: boolean) => void;\n toggleSidebar: () => void;\n};\n\nconst SidebarContext = createContext<SidebarContextProps | null>(null);\n\nfunction useSidebar() {\n const context = useContext(SidebarContext);\n if (!context) {\n throw new Error('useSidebar must be used within a SidebarProvider.');\n }\n return context;\n}\n\nfunction CMSLayoutProvider({\n defaultOpen = true,\n open: openProp,\n onOpenChange: setOpenProp,\n className,\n style,\n children,\n ...props\n}: React.ComponentProps<'div'> & {\n defaultOpen?: boolean;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n}) {\n const [_open, _setOpen] = useState(defaultOpen);\n const open = openProp ?? _open;\n const setOpen = useCallback(\n (value: boolean | ((value: boolean) => boolean)) => {\n const openState = typeof value === 'function' ? value(open) : value;\n if (setOpenProp) {\n setOpenProp(openState);\n } else {\n _setOpen(openState);\n }\n // biome-ignore lint/suspicious/noDocumentCookie: persists sidebar state across page loads\n document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;\n },\n [setOpenProp, open]\n );\n\n const toggleSidebar = useCallback(() => {\n setOpen(open => !open);\n }, [setOpen]);\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {\n event.preventDefault();\n toggleSidebar();\n }\n };\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [toggleSidebar]);\n\n const state = open ? 'expanded' : 'collapsed';\n\n const contextValue = useMemo<SidebarContextProps>(() => ({ state, open, setOpen, toggleSidebar }), [state, open, setOpen, toggleSidebar]);\n\n return (\n <SidebarContext.Provider value={contextValue}>\n <TooltipProvider delayDuration={0}>\n <div data-slot=\"layout-scroll-container\" className=\"h-dvh w-full overflow-auto bg-sidebar\">\n <section\n data-slot=\"layout-wrapper\"\n style={{ '--sidebar-width': SIDEBAR_WIDTH, '--sidebar-width-icon': SIDEBAR_WIDTH_ICON, ...style } as React.CSSProperties}\n className={cn(\n 'group/sidebar-wrapper relative grid',\n 'h-dvh min-h-160 w-full min-w-264 max-w-svw',\n 'grid-cols-[auto_1fr] grid-rows-[auto_1fr]',\n className\n )}\n {...props}\n >\n {children}\n </section>\n </div>\n </TooltipProvider>\n </SidebarContext.Provider>\n );\n}\n\nconst CMSLayoutSidebar = memo(\n ({\n side = 'left',\n className,\n children,\n ...props\n }: React.ComponentProps<'div'> & {\n side?: 'left' | 'right';\n }) => {\n const { state } = useSidebar();\n\n return (\n <div\n className=\"group peer relative col-start-1 row-start-2 block bg-card text-sidebar-foreground\"\n data-state={state}\n data-collapsible={state === 'collapsed' ? 'icon' : ''}\n data-side={side}\n data-slot=\"sidebar\"\n >\n <div\n data-slot=\"sidebar-gap\"\n className={cn(\n 'relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear',\n 'group-data-[side=right]:rotate-180',\n 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]'\n )}\n />\n <div\n data-slot=\"sidebar-container\"\n className={cn(\n 'absolute inset-y-0 z-10 flex w-(--sidebar-width) p-2 shadow-nav',\n 'transition-[left,right,width] duration-200 ease-linear',\n 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]',\n side === 'left' ? 'left-0' : 'right-0',\n className\n )}\n {...props}\n >\n <div data-sidebar=\"sidebar\" data-slot=\"sidebar-inner\" className=\"relative flex size-full flex-col\">\n {children}\n </div>\n </div>\n </div>\n );\n }\n);\nCMSLayoutSidebar.displayName = 'CMSLayoutSidebar';\n\nfunction SidebarTrigger({ className, onClick, ...props }: React.ComponentProps<typeof Button>) {\n const { toggleSidebar } = useSidebar();\n\n return (\n <Button\n data-sidebar=\"trigger\"\n data-slot=\"sidebar-trigger\"\n variant=\"ghost\"\n size=\"icon\"\n className={cn('size-7', className)}\n onClick={event => {\n onClick?.(event);\n toggleSidebar();\n }}\n {...props}\n >\n <PanelLeftIcon />\n <span className=\"sr-only\">Toggle Sidebar</span>\n </Button>\n );\n}\n\nfunction SidebarRail({ className, ...props }: React.ComponentProps<'button'>) {\n const { toggleSidebar } = useSidebar();\n\n return (\n <button\n data-sidebar=\"rail\"\n data-slot=\"sidebar-rail\"\n aria-label=\"Toggle Sidebar\"\n tabIndex={-1}\n onClick={toggleSidebar}\n title=\"Toggle Sidebar\"\n className={cn(\n 'absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-0.5 hover:after:bg-sidebar-border group-data-[side=left]:-right-4 group-data-[side=right]:left-0 sm:flex',\n 'in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize',\n '[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize',\n 'group-data-[collapsible=offcanvas]:translate-x-0 hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:after:left-full',\n '[[data-side=left][data-collapsible=offcanvas]_&]:-right-2',\n '[[data-side=right][data-collapsible=offcanvas]_&]:-left-2',\n className\n )}\n {...props}\n />\n );\n}\n\nconst CMSLayoutMain = memo(({ className, children, ...props }: React.ComponentProps<'main'>) => {\n return (\n <main data-slot=\"sidebar-inset\" className={cn('col-start-2 row-start-2 grid min-h-0 min-w-0 grid-rows-1', className)} {...props}>\n <div className=\"relative grid min-h-0 grid-cols-1 overflow-auto\">{children}</div>\n </main>\n );\n});\nCMSLayoutMain.displayName = 'CMSLayoutMain';\n\nconst SidebarInput = memo(({ className, ...props }: React.ComponentProps<typeof Input>) => {\n return <Input data-slot=\"sidebar-input\" data-sidebar=\"input\" className={cn('h-8 w-full bg-background shadow-none', className)} {...props} />;\n});\nSidebarInput.displayName = 'SidebarInput';\n\nconst SidebarHeader = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"sidebar-header\" data-sidebar=\"header\" className={cn('flex flex-col gap-2 p-2', className)} {...props} />;\n});\nSidebarHeader.displayName = 'SidebarHeader';\n\nconst SidebarFooter = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"sidebar-footer\" data-sidebar=\"footer\" className={cn('flex flex-col gap-2', className)} {...props} />;\n});\nSidebarFooter.displayName = 'SidebarFooter';\n\nconst SidebarSeparator = memo(({ className, ...props }: React.ComponentProps<typeof Separator>) => {\n return <Separator data-slot=\"sidebar-separator\" data-sidebar=\"separator\" className={cn('mx-2 w-auto bg-sidebar-border', className)} {...props} />;\n});\nSidebarSeparator.displayName = 'SidebarSeparator';\n\nconst SidebarContent = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return (\n <div\n data-slot=\"sidebar-content\"\n data-sidebar=\"content\"\n className={cn('flex flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden', className)}\n {...props}\n />\n );\n});\nSidebarContent.displayName = 'SidebarContent';\n\nconst SidebarGroup = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"sidebar-group\" data-sidebar=\"group\" className={cn('relative flex w-full flex-col', className)} {...props} />;\n});\nSidebarGroup.displayName = 'SidebarGroup';\n\nconst SidebarGroupLabel = memo(({ className, asChild = false, ...props }: React.ComponentProps<'div'> & { asChild?: boolean }) => {\n const Comp = asChild ? Slot : 'div';\n\n return (\n <Comp\n data-slot=\"sidebar-group-label\"\n data-sidebar=\"group-label\"\n className={cn(\n 'flex h-8 shrink-0 items-center rounded-md px-2 font-medium text-sidebar-foreground/70 text-xs outline-hidden ring-sidebar-ring transition-[margin,opacity,color] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',\n 'group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0',\n className\n )}\n {...props}\n />\n );\n});\nSidebarGroupLabel.displayName = 'SidebarGroupLabel';\n\nfunction SidebarGroupAction({ className, asChild = false, ...props }: React.ComponentProps<'button'> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n data-slot=\"sidebar-group-action\"\n data-sidebar=\"group-action\"\n className={cn(\n 'absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-hidden ring-sidebar-ring transition-[background-color,color,transform] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2',\n '[&>svg]:size-4 [&>svg]:shrink-0',\n // Increases the hit area of the button on mobile.\n 'after:absolute after:-inset-2 md:after:hidden',\n 'group-data-[collapsible=icon]:hidden',\n className\n )}\n {...props}\n />\n );\n}\n\nconst SidebarGroupContent = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"sidebar-group-content\" data-sidebar=\"group-content\" className={cn('w-full text-sm', className)} {...props} />;\n});\nSidebarGroupContent.displayName = 'SidebarGroupContent';\n\nconst SidebarMenu = memo(({ className, ...props }: React.ComponentProps<'ul'>) => {\n return <ul data-slot=\"sidebar-menu\" data-sidebar=\"menu\" className={cn('flex w-full min-w-0 flex-col gap-1', className)} {...props} />;\n});\nSidebarMenu.displayName = 'SidebarMenu';\n\nconst SidebarMenuItem = memo(({ className, ...props }: React.ComponentProps<'li'>) => {\n return <li data-slot=\"sidebar-menu-item\" data-sidebar=\"menu-item\" className={cn('group/menu-item relative', className)} {...props} />;\n});\nSidebarMenuItem.displayName = 'SidebarMenuItem';\n\nconst sidebarMenuButtonVariants = cva(\n [\n 'peer/menu-button',\n 'cursor-pointer',\n 'flex w-full items-center gap-2',\n 'overflow-hidden rounded-md p-2 outline-hidden',\n 'truncate text-left font-normal',\n 'transition-[color,background-color,width,height,padding]',\n 'active:bg-sidebar-accent active:text-sidebar-accent-foreground',\n 'disabled:pointer-events-none disabled:opacity-50',\n 'group-has-data-[sidebar=menu-action]/menu-item:pr-8',\n 'aria-disabled:pointer-events-none aria-disabled:opacity-50',\n 'data-[active=true]:bg-sidebar-primary-muted data-[active=true]:text-sidebar-primary',\n 'data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground',\n 'group-data-[collapsible=icon]:size-12! group-data-[collapsible=icon]:p-3! group-data-[collapsible=icon]:gap-3!',\n '[&>svg]:size-6 [&>svg]:shrink-0',\n '[&>span:last-child]:truncate',\n ],\n {\n variants: {\n variant: {\n default: 'hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground',\n outline:\n 'bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]',\n },\n size: {\n default: 'h-10 text-sm',\n sm: 'h-7 text-xs',\n lg: 'h-12 text-sm group-data-[collapsible=icon]:p-0!',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n }\n);\n\nconst SidebarMenuButton = memo(\n ({\n asChild = false,\n isActive = false,\n variant = 'default',\n size = 'default',\n tooltip,\n className,\n ...props\n }: React.ComponentProps<'button'> & {\n asChild?: boolean;\n isActive?: boolean;\n tooltip?: string | React.ComponentProps<typeof TooltipContent>;\n } & VariantProps<typeof sidebarMenuButtonVariants>) => {\n const Comp = asChild ? Slot : 'button';\n const { state } = useSidebar();\n\n const button = (\n <Comp\n data-slot=\"sidebar-menu-button\"\n data-sidebar=\"menu-button\"\n data-size={size}\n data-active={isActive}\n className={cn(sidebarMenuButtonVariants({ variant, size }), className)}\n {...props}\n />\n );\n\n if (!tooltip) return button;\n\n if (typeof tooltip === 'string') {\n tooltip = { children: tooltip };\n }\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>{button}</TooltipTrigger>\n <TooltipContent side=\"right\" align=\"center\" hidden={state !== 'collapsed'} {...tooltip} />\n </Tooltip>\n );\n }\n);\nSidebarMenuButton.displayName = 'SidebarMenuButton';\n\nfunction SidebarMenuAction({\n className,\n asChild = false,\n showOnHover = false,\n ...props\n}: React.ComponentProps<'button'> & {\n asChild?: boolean;\n showOnHover?: boolean;\n}) {\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n data-slot=\"sidebar-menu-action\"\n data-sidebar=\"menu-action\"\n className={cn(\n 'absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-hidden ring-sidebar-ring transition-[background-color,color,opacity] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-sidebar-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0',\n // Increases the hit area of the button on mobile.\n 'after:absolute after:-inset-2 md:after:hidden',\n 'peer-data-[size=sm]/menu-button:top-1',\n 'peer-data-[size=default]/menu-button:top-1.5',\n 'peer-data-[size=lg]/menu-button:top-2.5',\n 'group-data-[collapsible=icon]:hidden',\n showOnHover &&\n 'group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground md:opacity-0',\n className\n )}\n {...props}\n />\n );\n}\n\nfunction SidebarMenuBadge({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"sidebar-menu-badge\"\n data-sidebar=\"menu-badge\"\n className={cn(\n 'pointer-events-none absolute right-1 flex h-5 min-w-5 select-none items-center justify-center rounded-md px-1 font-medium text-sidebar-foreground text-xs tabular-nums transition-colors',\n 'peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground',\n 'peer-data-[size=sm]/menu-button:top-1',\n 'peer-data-[size=default]/menu-button:top-1.5',\n 'peer-data-[size=lg]/menu-button:top-2.5',\n 'group-data-[collapsible=icon]:hidden',\n className\n )}\n {...props}\n />\n );\n}\n\nfunction SidebarMenuSkeleton({\n className,\n showIcon = false,\n ...props\n}: React.ComponentProps<'div'> & {\n showIcon?: boolean;\n}) {\n const width = useMemo(() => `${Math.floor(Math.random() * 40) + 50}%`, []);\n\n return (\n <div data-slot=\"sidebar-menu-skeleton\" data-sidebar=\"menu-skeleton\" className={cn('flex h-8 items-center gap-2 rounded-md px-2', className)} {...props}>\n {showIcon && <Skeleton className=\"size-4 rounded-md\" data-sidebar=\"menu-skeleton-icon\" />}\n <Skeleton\n className=\"h-4 max-w-(--skeleton-width) flex-1\"\n data-sidebar=\"menu-skeleton-text\"\n style={{ '--skeleton-width': width } as React.CSSProperties}\n />\n </div>\n );\n}\n\nfunction SidebarMenuSub({ className, ...props }: React.ComponentProps<'ul'>) {\n return (\n <ul\n data-slot=\"sidebar-menu-sub\"\n data-sidebar=\"menu-sub\"\n className={cn(\n 'mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5',\n 'group-data-[collapsible=icon]:hidden',\n className\n )}\n {...props}\n />\n );\n}\n\nfunction SidebarMenuSubItem({ className, ...props }: React.ComponentProps<'li'>) {\n return <li data-slot=\"sidebar-menu-sub-item\" data-sidebar=\"menu-sub-item\" className={cn('group/menu-sub-item relative', className)} {...props} />;\n}\n\nfunction SidebarMenuSubButton({\n asChild = false,\n size = 'md',\n isActive = false,\n className,\n ...props\n}: React.ComponentProps<'a'> & {\n asChild?: boolean;\n size?: 'sm' | 'md';\n isActive?: boolean;\n}) {\n const Comp = asChild ? Slot : 'a';\n\n return (\n <Comp\n data-slot=\"sidebar-menu-sub-button\"\n data-sidebar=\"menu-sub-button\"\n data-size={size}\n data-active={isActive}\n className={cn(\n 'flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground outline-hidden ring-sidebar-ring transition-[background-color,color] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground',\n 'data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground',\n size === 'sm' && 'text-xs',\n size === 'md' && 'text-sm',\n 'group-data-[collapsible=icon]:hidden',\n className\n )}\n {...props}\n />\n );\n}\n\nexport {\n CMSLayoutMain,\n CMSLayoutProvider,\n CMSLayoutSidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarInput,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSkeleton,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarRail,\n SidebarSeparator,\n SidebarTrigger,\n // biome-ignore lint/style/useComponentExportOnlyModules: true\n useSidebar,\n};\n","'use client';\n\nimport { useCallback } from 'react';\n\nimport { EarthIcon, LogOutIcon, MenuIcon, UserRoundIcon } from 'lucide-react';\n\nimport { colorHashLight } from '@customafk/react-toolkit/color-hash';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';\nimport { Button } from '@/components/ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu';\nimport { LunasLogo } from '@/components/features/logo';\n\nimport { useSidebar } from './sidebar';\n\nexport type CMSLayoutUser = {\n /** Display name shown in the header and user dropdown. */\n name: string;\n /** Email address shown below the name in the dropdown. */\n email?: string;\n /** Role or position shown as a muted label in the dropdown. */\n role?: string;\n /** Optional avatar image URL; falls back to a color-hashed icon. */\n avatarUrl?: string;\n};\n\nexport const CMSLayoutHeader: React.FC<{\n i18nText?: string;\n onChangeToEnLocale?: () => void;\n onChangeToViLocale?: () => void;\n user?: CMSLayoutUser;\n onLogout?: () => void;\n logoutLabel?: string;\n logo?: React.ReactNode;\n}> = ({ i18nText, onChangeToEnLocale, onChangeToViLocale, user, onLogout, logoutLabel = 'Log out', logo }) => {\n const { toggleSidebar } = useSidebar();\n\n const handleToggleSidebar = useCallback(\n (event: React.MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n toggleSidebar();\n },\n [toggleSidebar]\n );\n\n const handleEnLocale = useCallback(\n (event: React.MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n onChangeToEnLocale?.();\n },\n [onChangeToEnLocale]\n );\n\n const handleViLocale = useCallback(\n (event: React.MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n onChangeToViLocale?.();\n },\n [onChangeToViLocale]\n );\n\n const avatarBg = user ? colorHashLight.hex(user.name) : undefined;\n\n return (\n <header\n data-slot=\"cms-layout-header\"\n className={cn(\n 'bg-card',\n 'h-(--header-height)',\n 'sm:h-(--header-height) sm:px-4 sm:pr-6',\n 'col-span-2 row-start-1 z-20 gap-2 px-2 pr-4.5',\n 'flex items-center shadow-nav',\n 'transition-[height] ease-linear'\n )}\n >\n <Button\n data-sidebar=\"trigger\"\n data-slot=\"sidebar-trigger\"\n variant=\"ghost\"\n color=\"muted\"\n size=\"icon\"\n className=\"size-10 rounded-full transition-all hover:text-text-positive\"\n onClick={handleToggleSidebar}\n >\n <MenuIcon className=\"size-6!\" />\n <span className=\"sr-only\">Toggle Sidebar</span>\n </Button>\n\n <div className=\"flex flex-1 items-center sm:ml-2.5\">{logo ?? <LunasLogo variant=\"horizontal\" size=\"xs\" />}</div>\n\n <div className=\"flex items-center gap-1\">\n {user && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"ghost\" color=\"muted\" className=\"h-9 gap-2.5 rounded-full px-2 transition-all\">\n <Avatar className=\"size-7 shrink-0\">\n <AvatarImage src={user.avatarUrl} alt={user.name} />\n <AvatarFallback style={{ backgroundColor: avatarBg }}>\n <UserRoundIcon size={14} className=\"text-white\" />\n </AvatarFallback>\n </Avatar>\n <div className=\"hidden flex-col items-start sm:flex\">\n <span className=\"max-w-36 truncate text-xs font-semibold leading-tight text-text-positive\">{user.name}</span>\n {user.email && <span className=\"max-w-36 truncate text-xs leading-tight text-text-positive-weak\">{user.email}</span>}\n </div>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-60\">\n <div className=\"flex flex-col items-center gap-2 px-4 py-4 text-center\">\n <Avatar className=\"size-12\">\n <AvatarImage src={user.avatarUrl} alt={user.name} />\n <AvatarFallback style={{ backgroundColor: avatarBg }}>\n <UserRoundIcon size={22} className=\"text-white\" />\n </AvatarFallback>\n </Avatar>\n <div className=\"flex min-w-0 w-full flex-col items-center gap-0.5\">\n <p className=\"truncate text-sm font-semibold text-text-positive\">{user.name}</p>\n {user.email && <p className=\"truncate text-xs text-text-positive-weak\">{user.email}</p>}\n {user.role && (\n <span className=\"mt-1 w-fit rounded-sm border border-border bg-secondary-muted px-2 py-0.5 text-xs font-medium text-text-positive-weak\">\n {user.role}\n </span>\n )}\n </div>\n </div>\n {onLogout && (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem className=\"text-danger focus:text-danger\" onClick={onLogout}>\n <LogOutIcon className=\"size-4\" />\n {logoutLabel}\n </DropdownMenuItem>\n </DropdownMenuGroup>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n\n {user && (onChangeToEnLocale || onChangeToViLocale) && <div className=\"mx-1 h-5 w-px bg-border\" />}\n\n {(onChangeToEnLocale || onChangeToViLocale) && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button data-slot=\"locale-trigger\" variant=\"ghost\" color=\"muted\" className=\"gap-x-1 rounded-full transition-all hover:text-text-positive\">\n <EarthIcon className=\"size-6!\" />\n {i18nText}\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuGroup>\n <DropdownMenuItem onClick={handleEnLocale}>EN - English</DropdownMenuItem>\n <DropdownMenuItem onClick={handleViLocale}>VI - Vietnamese</DropdownMenuItem>\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </div>\n </header>\n );\n};\n","'use client';\n\nimport { memo } from 'react';\n\nimport { LogOutIcon } from 'lucide-react';\n\nimport { CMSLayoutHeader, type CMSLayoutUser } from './components/header';\nimport {\n CMSLayoutMain,\n CMSLayoutProvider,\n CMSLayoutSidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from './components/sidebar';\n\ntype NavItem = {\n /** Unique identifier for the nav item, used as React key and for active-state comparison. */\n id: string;\n /** Human-readable label rendered inside the sidebar button. */\n label: string;\n /** Optional icon element rendered to the left of the label. */\n icon?: React.ReactNode;\n /** Callback fired when the sidebar button is clicked. Use for simple programmatic navigation. */\n onClick?: () => void;\n /**\n * Renders the button as a custom element using the Radix Slot (asChild) pattern.\n * Return a single element (e.g. a TanStack Router `<Link>`) wrapping the icon + label content.\n *\n * @example\n * ```tsx\n * renderAs: ({ icon, label }) => <Link to=\"/dashboard\">{icon}{label}</Link>\n * ```\n */\n renderAs?: (content: { icon?: React.ReactNode; label: string }) => React.ReactElement;\n};\n\ntype NavGroup = {\n /** Unique identifier for the group, used as React key. */\n id: string;\n /** Optional section heading rendered above the group's items. */\n label?: string;\n /** Navigation items that belong to this group. */\n items: NavItem[];\n};\n\nexport type { CMSLayoutUser };\n\nexport type CMSLayoutProps = {\n /** Text label used by the header for language-toggle or i18n display. */\n i18nText?: string;\n /** ID of the currently active navigation item; matched against `NavItem.id` to highlight the active button. */\n activeNavItemId?: string;\n /** Sidebar navigation definition; omitting this prop renders an empty sidebar. */\n sidebar?: { groupcontent: NavGroup[] };\n /** Callback fired when the logout button is clicked. */\n onLogout?: () => void;\n /** Callback fired when the user switches the UI locale to English. */\n onChangeToEnLocale?: () => void;\n /** Callback fired when the user switches the UI locale to Vietnamese. */\n onChangeToViLocale?: () => void;\n /**\n * Label displayed on the logout button.\n * @default 'Log out'\n */\n logoutLabel?: string;\n /**\n * Copyright string shown at the bottom of the sidebar.\n * @default `Copyright © <current year>, Lunas.`\n */\n copyright?: string;\n /** Authenticated user shown in the header avatar dropdown. Omit to hide the user menu. */\n user?: CMSLayoutUser;\n};\n\nconst SidebarContentGroupItem = memo<NavItem & { activeNavItemId?: string }>(({ id, label, icon, activeNavItemId, onClick, renderAs }) => (\n <SidebarMenuItem>\n {renderAs ? (\n <SidebarMenuButton asChild isActive={id === activeNavItemId}>\n {renderAs({ icon, label })}\n </SidebarMenuButton>\n ) : (\n <SidebarMenuButton isActive={id === activeNavItemId} onClick={onClick}>\n {icon}\n {label}\n </SidebarMenuButton>\n )}\n </SidebarMenuItem>\n));\nSidebarContentGroupItem.displayName = 'SidebarContentGroupItem';\n\nconst SidebarContentGroup = memo<React.PropsWithChildren<Omit<NavGroup, 'items'>>>(({ id, label, children }) => (\n <SidebarGroup>\n <SidebarGroupLabel>{label}</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>{children}</SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n));\nSidebarContentGroup.displayName = 'SidebarContentGroup';\n\n/**\n * Full-page CMS application shell with a collapsible inset sidebar, header, and main content area.\n *\n * @example\n * ```tsx\n * import { CMSLayout } from '@customafk/lunas-ui/layouts/cms-layout';\n * import { LayoutDashboardIcon } from 'lucide-react';\n *\n * <CMSLayout\n * activeNavItemId=\"dashboard\"\n * sidebar={{\n * groupcontent: [\n * {\n * id: 'main',\n * label: 'Main',\n * items: [\n * {\n * id: 'dashboard',\n * label: 'Dashboard',\n * icon: <LayoutDashboardIcon />,\n * // Option A — TanStack Router Link (asChild/Slot pattern):\n * renderAs: ({ icon, label }) => <Link to=\"/\">{icon}{label}</Link>,\n * // Option B — simple click handler:\n * // onClick: () => router.navigate({ to: '/' }),\n * },\n * ],\n * },\n * ],\n * }}\n * onLogout={() => signOut()}\n * >\n * <DashboardPage />\n * </CMSLayout>\n * ```\n */\nexport const CMSLayout: React.FC<React.PropsWithChildren<CMSLayoutProps>> = ({\n i18nText,\n activeNavItemId,\n sidebar,\n children,\n onChangeToEnLocale,\n onChangeToViLocale,\n onLogout,\n logoutLabel = 'Log out',\n copyright = `Copyright © ${new Date().getFullYear()}, Lunas.`,\n user,\n}) => {\n const groups = sidebar?.groupcontent ?? [];\n\n return (\n <CMSLayoutProvider>\n <CMSLayoutHeader\n i18nText={i18nText}\n onChangeToEnLocale={onChangeToEnLocale}\n onChangeToViLocale={onChangeToViLocale}\n user={user}\n onLogout={onLogout}\n logoutLabel={logoutLabel}\n />\n <CMSLayoutSidebar>\n <SidebarContent>\n {groups.map(group => (\n <SidebarContentGroup key={group.id} id={group.id} label={group.label}>\n {group.items.map(item => (\n <SidebarContentGroupItem\n key={item.id}\n id={item.id}\n activeNavItemId={activeNavItemId}\n label={item.label}\n icon={item.icon}\n renderAs={item.renderAs}\n onClick={item.onClick}\n />\n ))}\n </SidebarContentGroup>\n ))}\n </SidebarContent>\n <SidebarFooter>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton className=\"border border-border\" onClick={onLogout}>\n <LogOutIcon className=\"text-text-positive-weak\" />\n {logoutLabel}\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem className=\"mt-2 border-t border-t-border\">\n <p className=\"pt-2 text-center text-xs text-text-positive-subtle\">{copyright}</p>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarFooter>\n </CMSLayoutSidebar>\n <CMSLayoutMain>{children}</CMSLayoutMain>\n </CMSLayoutProvider>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cms-layout-DYEmSqzx.cjs","names":["TooltipProvider","Input","Separator","Slot","Tooltip","TooltipTrigger","TooltipContent","colorHashLight","Button","MenuIcon","LunasLogo","DropdownMenu","DropdownMenuTrigger","Avatar","AvatarImage","AvatarFallback","UserRoundIcon","DropdownMenuContent","DropdownMenuSeparator","DropdownMenuGroup","DropdownMenuItem","LogOutIcon","EarthIcon","LogOutIcon"],"sources":["../packages/components/layouts/cms-layout/components/sidebar.tsx","../packages/components/layouts/cms-layout/components/header.tsx","../packages/components/layouts/cms-layout/index.tsx"],"sourcesContent":["'use client';\n\nimport { createContext, memo, useCallback, useContext, useEffect, useMemo, useState } from 'react';\n\nimport { PanelLeftIcon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Input } from '@/components/ui/input';\nimport { Separator } from '@/components/ui/separator';\nimport { Skeleton } from '@/components/ui/skeleton';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';\n\nimport { Slot } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nconst SIDEBAR_COOKIE_NAME = 'sidebar_state';\nconst SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;\nconst SIDEBAR_WIDTH = '16rem';\nconst SIDEBAR_WIDTH_ICON = '3rem';\nconst SIDEBAR_KEYBOARD_SHORTCUT = 'b';\n\ntype SidebarContextProps = {\n state: 'expanded' | 'collapsed';\n open: boolean;\n setOpen: (open: boolean) => void;\n toggleSidebar: () => void;\n};\n\nconst SidebarContext = createContext<SidebarContextProps | null>(null);\n\nfunction useSidebar() {\n const context = useContext(SidebarContext);\n if (!context) {\n throw new Error('useSidebar must be used within a SidebarProvider.');\n }\n return context;\n}\n\nfunction CMSLayoutProvider({\n defaultOpen = true,\n open: openProp,\n onOpenChange: setOpenProp,\n className,\n style,\n children,\n ...props\n}: React.ComponentProps<'div'> & {\n defaultOpen?: boolean;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n}) {\n const [_open, _setOpen] = useState(defaultOpen);\n const open = openProp ?? _open;\n const setOpen = useCallback(\n (value: boolean | ((value: boolean) => boolean)) => {\n const openState = typeof value === 'function' ? value(open) : value;\n if (setOpenProp) {\n setOpenProp(openState);\n } else {\n _setOpen(openState);\n }\n // biome-ignore lint/suspicious/noDocumentCookie: persists sidebar state across page loads\n document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;\n },\n [setOpenProp, open]\n );\n\n const toggleSidebar = useCallback(() => {\n setOpen(open => !open);\n }, [setOpen]);\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {\n event.preventDefault();\n toggleSidebar();\n }\n };\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [toggleSidebar]);\n\n const state = open ? 'expanded' : 'collapsed';\n\n const contextValue = useMemo<SidebarContextProps>(() => ({ state, open, setOpen, toggleSidebar }), [state, open, setOpen, toggleSidebar]);\n\n return (\n <SidebarContext.Provider value={contextValue}>\n <TooltipProvider delayDuration={0}>\n <div data-slot=\"layout-scroll-container\" className=\"h-dvh w-full overflow-auto bg-sidebar\">\n <section\n data-slot=\"layout-wrapper\"\n style={{ '--sidebar-width': SIDEBAR_WIDTH, '--sidebar-width-icon': SIDEBAR_WIDTH_ICON, ...style } as React.CSSProperties}\n className={cn(\n 'group/sidebar-wrapper relative grid',\n 'h-dvh min-h-160 w-full min-w-264 max-w-svw',\n 'grid-cols-[auto_1fr] grid-rows-[auto_1fr]',\n className\n )}\n {...props}\n >\n {children}\n </section>\n </div>\n </TooltipProvider>\n </SidebarContext.Provider>\n );\n}\n\nconst CMSLayoutSidebar = memo(\n ({\n side = 'left',\n className,\n children,\n ...props\n }: React.ComponentProps<'div'> & {\n side?: 'left' | 'right';\n }) => {\n const { state } = useSidebar();\n\n return (\n <div\n className=\"group peer relative col-start-1 row-start-2 block bg-card text-sidebar-foreground\"\n data-state={state}\n data-collapsible={state === 'collapsed' ? 'icon' : ''}\n data-side={side}\n data-slot=\"sidebar\"\n >\n <div\n data-slot=\"sidebar-gap\"\n className={cn(\n 'relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear',\n 'group-data-[side=right]:rotate-180',\n 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]'\n )}\n />\n <div\n data-slot=\"sidebar-container\"\n className={cn(\n 'absolute inset-y-0 z-10 flex w-(--sidebar-width) p-2 shadow-nav',\n 'transition-[left,right,width] duration-200 ease-linear',\n 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]',\n side === 'left' ? 'left-0' : 'right-0',\n className\n )}\n {...props}\n >\n <div data-sidebar=\"sidebar\" data-slot=\"sidebar-inner\" className=\"relative flex size-full flex-col\">\n {children}\n </div>\n </div>\n </div>\n );\n }\n);\nCMSLayoutSidebar.displayName = 'CMSLayoutSidebar';\n\nfunction SidebarTrigger({ className, onClick, ...props }: React.ComponentProps<typeof Button>) {\n const { toggleSidebar } = useSidebar();\n\n return (\n <Button\n data-sidebar=\"trigger\"\n data-slot=\"sidebar-trigger\"\n variant=\"ghost\"\n size=\"icon\"\n className={cn('size-7', className)}\n onClick={event => {\n onClick?.(event);\n toggleSidebar();\n }}\n {...props}\n >\n <PanelLeftIcon />\n <span className=\"sr-only\">Toggle Sidebar</span>\n </Button>\n );\n}\n\nfunction SidebarRail({ className, ...props }: React.ComponentProps<'button'>) {\n const { toggleSidebar } = useSidebar();\n\n return (\n <button\n data-sidebar=\"rail\"\n data-slot=\"sidebar-rail\"\n aria-label=\"Toggle Sidebar\"\n tabIndex={-1}\n onClick={toggleSidebar}\n title=\"Toggle Sidebar\"\n className={cn(\n 'absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-0.5 hover:after:bg-sidebar-border group-data-[side=left]:-right-4 group-data-[side=right]:left-0 sm:flex',\n 'in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize',\n '[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize',\n 'group-data-[collapsible=offcanvas]:translate-x-0 hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:after:left-full',\n '[[data-side=left][data-collapsible=offcanvas]_&]:-right-2',\n '[[data-side=right][data-collapsible=offcanvas]_&]:-left-2',\n className\n )}\n {...props}\n />\n );\n}\n\nconst CMSLayoutMain = memo(({ className, children, ...props }: React.ComponentProps<'main'>) => {\n return (\n <main data-slot=\"sidebar-inset\" className={cn('col-start-2 row-start-2 grid min-h-0 min-w-0 grid-rows-1', className)} {...props}>\n <div className=\"relative grid min-h-0 grid-cols-1 overflow-auto\">{children}</div>\n </main>\n );\n});\nCMSLayoutMain.displayName = 'CMSLayoutMain';\n\nconst SidebarInput = memo(({ className, ...props }: React.ComponentProps<typeof Input>) => {\n return <Input data-slot=\"sidebar-input\" data-sidebar=\"input\" className={cn('h-8 w-full bg-background shadow-none', className)} {...props} />;\n});\nSidebarInput.displayName = 'SidebarInput';\n\nconst SidebarHeader = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"sidebar-header\" data-sidebar=\"header\" className={cn('flex flex-col gap-2 p-2', className)} {...props} />;\n});\nSidebarHeader.displayName = 'SidebarHeader';\n\nconst SidebarFooter = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"sidebar-footer\" data-sidebar=\"footer\" className={cn('flex flex-col gap-2', className)} {...props} />;\n});\nSidebarFooter.displayName = 'SidebarFooter';\n\nconst SidebarSeparator = memo(({ className, ...props }: React.ComponentProps<typeof Separator>) => {\n return <Separator data-slot=\"sidebar-separator\" data-sidebar=\"separator\" className={cn('mx-2 w-auto bg-sidebar-border', className)} {...props} />;\n});\nSidebarSeparator.displayName = 'SidebarSeparator';\n\nconst SidebarContent = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return (\n <div\n data-slot=\"sidebar-content\"\n data-sidebar=\"content\"\n className={cn('flex flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden', className)}\n {...props}\n />\n );\n});\nSidebarContent.displayName = 'SidebarContent';\n\nconst SidebarGroup = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"sidebar-group\" data-sidebar=\"group\" className={cn('relative flex w-full flex-col', className)} {...props} />;\n});\nSidebarGroup.displayName = 'SidebarGroup';\n\nconst SidebarGroupLabel = memo(({ className, asChild = false, ...props }: React.ComponentProps<'div'> & { asChild?: boolean }) => {\n const Comp = asChild ? Slot : 'div';\n\n return (\n <Comp\n data-slot=\"sidebar-group-label\"\n data-sidebar=\"group-label\"\n className={cn(\n 'flex h-8 shrink-0 items-center rounded-md px-2 font-medium text-sidebar-foreground/70 text-xs outline-hidden ring-sidebar-ring transition-[margin,opacity,color] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',\n 'group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0',\n className\n )}\n {...props}\n />\n );\n});\nSidebarGroupLabel.displayName = 'SidebarGroupLabel';\n\nfunction SidebarGroupAction({ className, asChild = false, ...props }: React.ComponentProps<'button'> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n data-slot=\"sidebar-group-action\"\n data-sidebar=\"group-action\"\n className={cn(\n 'absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-hidden ring-sidebar-ring transition-[background-color,color,transform] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2',\n '[&>svg]:size-4 [&>svg]:shrink-0',\n // Increases the hit area of the button on mobile.\n 'after:absolute after:-inset-2 md:after:hidden',\n 'group-data-[collapsible=icon]:hidden',\n className\n )}\n {...props}\n />\n );\n}\n\nconst SidebarGroupContent = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"sidebar-group-content\" data-sidebar=\"group-content\" className={cn('w-full text-sm', className)} {...props} />;\n});\nSidebarGroupContent.displayName = 'SidebarGroupContent';\n\nconst SidebarMenu = memo(({ className, ...props }: React.ComponentProps<'ul'>) => {\n return <ul data-slot=\"sidebar-menu\" data-sidebar=\"menu\" className={cn('flex w-full min-w-0 flex-col gap-1', className)} {...props} />;\n});\nSidebarMenu.displayName = 'SidebarMenu';\n\nconst SidebarMenuItem = memo(({ className, ...props }: React.ComponentProps<'li'>) => {\n return <li data-slot=\"sidebar-menu-item\" data-sidebar=\"menu-item\" className={cn('group/menu-item relative', className)} {...props} />;\n});\nSidebarMenuItem.displayName = 'SidebarMenuItem';\n\nconst sidebarMenuButtonVariants = cva(\n [\n 'peer/menu-button',\n 'cursor-pointer',\n 'flex w-full items-center gap-2',\n 'overflow-hidden rounded-md p-2 outline-hidden',\n 'truncate text-left font-normal',\n 'transition-[color,background-color,width,height,padding]',\n 'active:bg-sidebar-accent active:text-sidebar-accent-foreground',\n 'disabled:pointer-events-none disabled:opacity-50',\n 'group-has-data-[sidebar=menu-action]/menu-item:pr-8',\n 'aria-disabled:pointer-events-none aria-disabled:opacity-50',\n 'data-[active=true]:bg-sidebar-primary-muted data-[active=true]:text-sidebar-primary',\n 'data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground',\n 'group-data-[collapsible=icon]:size-12! group-data-[collapsible=icon]:p-3! group-data-[collapsible=icon]:gap-3!',\n '[&>svg]:size-6 [&>svg]:shrink-0',\n '[&>span:last-child]:truncate',\n ],\n {\n variants: {\n variant: {\n default: 'hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground',\n outline:\n 'bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]',\n },\n size: {\n default: 'h-10 text-sm',\n sm: 'h-7 text-xs',\n lg: 'h-12 text-sm group-data-[collapsible=icon]:p-0!',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n }\n);\n\nconst SidebarMenuButton = memo(\n ({\n asChild = false,\n isActive = false,\n variant = 'default',\n size = 'default',\n tooltip,\n className,\n ...props\n }: React.ComponentProps<'button'> & {\n asChild?: boolean;\n isActive?: boolean;\n tooltip?: string | React.ComponentProps<typeof TooltipContent>;\n } & VariantProps<typeof sidebarMenuButtonVariants>) => {\n const Comp = asChild ? Slot : 'button';\n const { state } = useSidebar();\n\n const button = (\n <Comp\n data-slot=\"sidebar-menu-button\"\n data-sidebar=\"menu-button\"\n data-size={size}\n data-active={isActive}\n className={cn(sidebarMenuButtonVariants({ variant, size }), className)}\n {...props}\n />\n );\n\n if (!tooltip) return button;\n\n if (typeof tooltip === 'string') {\n tooltip = { children: tooltip };\n }\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>{button}</TooltipTrigger>\n <TooltipContent side=\"right\" align=\"center\" hidden={state !== 'collapsed'} {...tooltip} />\n </Tooltip>\n );\n }\n);\nSidebarMenuButton.displayName = 'SidebarMenuButton';\n\nfunction SidebarMenuAction({\n className,\n asChild = false,\n showOnHover = false,\n ...props\n}: React.ComponentProps<'button'> & {\n asChild?: boolean;\n showOnHover?: boolean;\n}) {\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n data-slot=\"sidebar-menu-action\"\n data-sidebar=\"menu-action\"\n className={cn(\n 'absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-hidden ring-sidebar-ring transition-[background-color,color,opacity] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-sidebar-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0',\n // Increases the hit area of the button on mobile.\n 'after:absolute after:-inset-2 md:after:hidden',\n 'peer-data-[size=sm]/menu-button:top-1',\n 'peer-data-[size=default]/menu-button:top-1.5',\n 'peer-data-[size=lg]/menu-button:top-2.5',\n 'group-data-[collapsible=icon]:hidden',\n showOnHover &&\n 'group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground md:opacity-0',\n className\n )}\n {...props}\n />\n );\n}\n\nfunction SidebarMenuBadge({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"sidebar-menu-badge\"\n data-sidebar=\"menu-badge\"\n className={cn(\n 'pointer-events-none absolute right-1 flex h-5 min-w-5 select-none items-center justify-center rounded-md px-1 font-medium text-sidebar-foreground text-xs tabular-nums transition-colors',\n 'peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground',\n 'peer-data-[size=sm]/menu-button:top-1',\n 'peer-data-[size=default]/menu-button:top-1.5',\n 'peer-data-[size=lg]/menu-button:top-2.5',\n 'group-data-[collapsible=icon]:hidden',\n className\n )}\n {...props}\n />\n );\n}\n\nfunction SidebarMenuSkeleton({\n className,\n showIcon = false,\n ...props\n}: React.ComponentProps<'div'> & {\n showIcon?: boolean;\n}) {\n const width = useMemo(() => `${Math.floor(Math.random() * 40) + 50}%`, []);\n\n return (\n <div data-slot=\"sidebar-menu-skeleton\" data-sidebar=\"menu-skeleton\" className={cn('flex h-8 items-center gap-2 rounded-md px-2', className)} {...props}>\n {showIcon && <Skeleton className=\"size-4 rounded-md\" data-sidebar=\"menu-skeleton-icon\" />}\n <Skeleton\n className=\"h-4 max-w-(--skeleton-width) flex-1\"\n data-sidebar=\"menu-skeleton-text\"\n style={{ '--skeleton-width': width } as React.CSSProperties}\n />\n </div>\n );\n}\n\nfunction SidebarMenuSub({ className, ...props }: React.ComponentProps<'ul'>) {\n return (\n <ul\n data-slot=\"sidebar-menu-sub\"\n data-sidebar=\"menu-sub\"\n className={cn(\n 'mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5',\n 'group-data-[collapsible=icon]:hidden',\n className\n )}\n {...props}\n />\n );\n}\n\nfunction SidebarMenuSubItem({ className, ...props }: React.ComponentProps<'li'>) {\n return <li data-slot=\"sidebar-menu-sub-item\" data-sidebar=\"menu-sub-item\" className={cn('group/menu-sub-item relative', className)} {...props} />;\n}\n\nfunction SidebarMenuSubButton({\n asChild = false,\n size = 'md',\n isActive = false,\n className,\n ...props\n}: React.ComponentProps<'a'> & {\n asChild?: boolean;\n size?: 'sm' | 'md';\n isActive?: boolean;\n}) {\n const Comp = asChild ? Slot : 'a';\n\n return (\n <Comp\n data-slot=\"sidebar-menu-sub-button\"\n data-sidebar=\"menu-sub-button\"\n data-size={size}\n data-active={isActive}\n className={cn(\n 'flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground outline-hidden ring-sidebar-ring transition-[background-color,color] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground',\n 'data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground',\n size === 'sm' && 'text-xs',\n size === 'md' && 'text-sm',\n 'group-data-[collapsible=icon]:hidden',\n className\n )}\n {...props}\n />\n );\n}\n\nexport {\n CMSLayoutMain,\n CMSLayoutProvider,\n CMSLayoutSidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarInput,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSkeleton,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarRail,\n SidebarSeparator,\n SidebarTrigger,\n // biome-ignore lint/style/useComponentExportOnlyModules: true\n useSidebar,\n};\n","'use client';\n\nimport { useCallback } from 'react';\n\nimport { EarthIcon, LogOutIcon, MenuIcon, UserRoundIcon } from 'lucide-react';\n\nimport { colorHashLight } from '@customafk/react-toolkit/color-hash';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';\nimport { Button } from '@/components/ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu';\nimport { LunasLogo } from '@/components/features/logo';\n\nimport { useSidebar } from './sidebar';\n\nexport type CMSLayoutUser = {\n /** Display name shown in the header and user dropdown. */\n name: string;\n /** Email address shown below the name in the dropdown. */\n email?: string;\n /** Role or position shown as a muted label in the dropdown. */\n role?: string;\n /** Optional avatar image URL; falls back to a color-hashed icon. */\n avatarUrl?: string;\n};\n\nexport const CMSLayoutHeader: React.FC<{\n i18nText?: string;\n onChangeToEnLocale?: () => void;\n onChangeToViLocale?: () => void;\n user?: CMSLayoutUser;\n onLogout?: () => void;\n logoutLabel?: string;\n logo?: React.ReactNode;\n}> = ({ i18nText, onChangeToEnLocale, onChangeToViLocale, user, onLogout, logoutLabel = 'Log out', logo }) => {\n const { toggleSidebar } = useSidebar();\n\n const handleToggleSidebar = useCallback(\n (event: React.MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n toggleSidebar();\n },\n [toggleSidebar]\n );\n\n const handleEnLocale = useCallback(\n (event: React.MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n onChangeToEnLocale?.();\n },\n [onChangeToEnLocale]\n );\n\n const handleViLocale = useCallback(\n (event: React.MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n onChangeToViLocale?.();\n },\n [onChangeToViLocale]\n );\n\n const avatarBg = user ? colorHashLight.hex(user.name) : undefined;\n\n return (\n <header\n data-slot=\"cms-layout-header\"\n className={cn(\n 'bg-card',\n 'h-(--header-height)',\n 'sm:h-(--header-height) sm:px-4 sm:pr-6',\n 'col-span-2 row-start-1 z-20 gap-2 px-2 pr-4.5',\n 'flex items-center shadow-nav',\n 'transition-[height] ease-linear'\n )}\n >\n <Button\n data-sidebar=\"trigger\"\n data-slot=\"sidebar-trigger\"\n variant=\"ghost\"\n color=\"muted\"\n size=\"icon\"\n className=\"size-10 rounded-full transition-all hover:text-text-positive\"\n onClick={handleToggleSidebar}\n >\n <MenuIcon className=\"size-6!\" />\n <span className=\"sr-only\">Toggle Sidebar</span>\n </Button>\n\n <div className=\"flex flex-1 items-center sm:ml-2.5\">{logo ?? <LunasLogo variant=\"horizontal\" size=\"xs\" />}</div>\n\n <div className=\"flex items-center gap-1\">\n {user && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"ghost\" color=\"muted\" className=\"h-9 gap-2.5 rounded-full px-2 transition-all\">\n <Avatar className=\"size-7 shrink-0\">\n <AvatarImage src={user.avatarUrl} alt={user.name} />\n <AvatarFallback style={{ backgroundColor: avatarBg }}>\n <UserRoundIcon size={14} className=\"text-white\" />\n </AvatarFallback>\n </Avatar>\n <div className=\"hidden flex-col items-start sm:flex\">\n <span className=\"max-w-36 truncate text-xs font-semibold leading-tight text-text-positive\">{user.name}</span>\n {user.email && <span className=\"max-w-36 truncate text-xs leading-tight text-text-positive-weak\">{user.email}</span>}\n </div>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-60\">\n <div className=\"flex flex-col items-center gap-2 px-4 py-4 text-center\">\n <Avatar className=\"size-12\">\n <AvatarImage src={user.avatarUrl} alt={user.name} />\n <AvatarFallback style={{ backgroundColor: avatarBg }}>\n <UserRoundIcon size={22} className=\"text-white\" />\n </AvatarFallback>\n </Avatar>\n <div className=\"flex min-w-0 w-full flex-col items-center gap-0.5\">\n <p className=\"truncate text-sm font-semibold text-text-positive\">{user.name}</p>\n {user.email && <p className=\"truncate text-xs text-text-positive-weak\">{user.email}</p>}\n {user.role && (\n <span className=\"mt-1 w-fit rounded-sm border border-border bg-secondary-muted px-2 py-0.5 text-xs font-medium text-text-positive-weak\">\n {user.role}\n </span>\n )}\n </div>\n </div>\n {onLogout && (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem className=\"text-danger focus:text-danger\" onClick={onLogout}>\n <LogOutIcon className=\"size-4\" />\n {logoutLabel}\n </DropdownMenuItem>\n </DropdownMenuGroup>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n\n {user && (onChangeToEnLocale || onChangeToViLocale) && <div className=\"mx-1 h-5 w-px bg-border\" />}\n\n {(onChangeToEnLocale || onChangeToViLocale) && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button data-slot=\"locale-trigger\" variant=\"ghost\" color=\"muted\" className=\"gap-x-1 rounded-full transition-all hover:text-text-positive\">\n <EarthIcon className=\"size-6!\" />\n {i18nText}\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuGroup>\n <DropdownMenuItem onClick={handleEnLocale}>EN - English</DropdownMenuItem>\n <DropdownMenuItem onClick={handleViLocale}>VI - Vietnamese</DropdownMenuItem>\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </div>\n </header>\n );\n};\n","'use client';\n\nimport { memo } from 'react';\n\nimport { LogOutIcon } from 'lucide-react';\n\nimport { CMSLayoutHeader, type CMSLayoutUser } from './components/header';\nimport {\n CMSLayoutMain,\n CMSLayoutProvider,\n CMSLayoutSidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from './components/sidebar';\n\ntype NavItem = {\n /** Unique identifier for the nav item, used as React key and for active-state comparison. */\n id: string;\n /** Human-readable label rendered inside the sidebar button. */\n label: string;\n /** Optional icon element rendered to the left of the label. */\n icon?: React.ReactNode;\n /** Callback fired when the sidebar button is clicked. Use for simple programmatic navigation. */\n onClick?: () => void;\n /**\n * Renders the button as a custom element using the Radix Slot (asChild) pattern.\n * Return a single element (e.g. a TanStack Router `<Link>`) wrapping the icon + label content.\n *\n * @example\n * ```tsx\n * renderAs: ({ icon, label }) => <Link to=\"/dashboard\">{icon}{label}</Link>\n * ```\n */\n renderAs?: (content: { icon?: React.ReactNode; label: string }) => React.ReactElement;\n};\n\ntype NavGroup = {\n /** Unique identifier for the group, used as React key. */\n id: string;\n /** Optional section heading rendered above the group's items. */\n label?: string;\n /** Navigation items that belong to this group. */\n items: NavItem[];\n};\n\nexport type { CMSLayoutUser };\n\nexport type CMSLayoutProps = {\n /** Text label used by the header for language-toggle or i18n display. */\n i18nText?: string;\n /** ID of the currently active navigation item; matched against `NavItem.id` to highlight the active button. */\n activeNavItemId?: string;\n /** Sidebar navigation definition; omitting this prop renders an empty sidebar. */\n sidebar?: { groupcontent: NavGroup[] };\n /** Callback fired when the logout button is clicked. */\n onLogout?: () => void;\n /** Callback fired when the user switches the UI locale to English. */\n onChangeToEnLocale?: () => void;\n /** Callback fired when the user switches the UI locale to Vietnamese. */\n onChangeToViLocale?: () => void;\n /**\n * Label displayed on the logout button.\n * @default 'Log out'\n */\n logoutLabel?: string;\n /**\n * Copyright string shown at the bottom of the sidebar.\n * @default `Copyright © <current year>, Lunas.`\n */\n copyright?: string;\n /** Authenticated user shown in the header avatar dropdown. Omit to hide the user menu. */\n user?: CMSLayoutUser;\n};\n\nconst SidebarContentGroupItem = memo<NavItem & { activeNavItemId?: string }>(({ id, label, icon, activeNavItemId, onClick, renderAs }) => (\n <SidebarMenuItem>\n {renderAs ? (\n <SidebarMenuButton asChild isActive={id === activeNavItemId}>\n {renderAs({ icon, label })}\n </SidebarMenuButton>\n ) : (\n <SidebarMenuButton isActive={id === activeNavItemId} onClick={onClick}>\n {icon}\n {label}\n </SidebarMenuButton>\n )}\n </SidebarMenuItem>\n));\nSidebarContentGroupItem.displayName = 'SidebarContentGroupItem';\n\nconst SidebarContentGroup = memo<React.PropsWithChildren<Omit<NavGroup, 'items'>>>(({ id, label, children }) => (\n <SidebarGroup>\n <SidebarGroupLabel>{label}</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>{children}</SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n));\nSidebarContentGroup.displayName = 'SidebarContentGroup';\n\n/**\n * Full-page CMS application shell with a collapsible inset sidebar, header, and main content area.\n *\n * @example\n * ```tsx\n * import { CMSLayout } from '@customafk/lunas-ui/layouts/cms-layout';\n * import { LayoutDashboardIcon } from 'lucide-react';\n *\n * <CMSLayout\n * activeNavItemId=\"dashboard\"\n * sidebar={{\n * groupcontent: [\n * {\n * id: 'main',\n * label: 'Main',\n * items: [\n * {\n * id: 'dashboard',\n * label: 'Dashboard',\n * icon: <LayoutDashboardIcon />,\n * // Option A — TanStack Router Link (asChild/Slot pattern):\n * renderAs: ({ icon, label }) => <Link to=\"/\">{icon}{label}</Link>,\n * // Option B — simple click handler:\n * // onClick: () => router.navigate({ to: '/' }),\n * },\n * ],\n * },\n * ],\n * }}\n * onLogout={() => signOut()}\n * >\n * <DashboardPage />\n * </CMSLayout>\n * ```\n */\nexport const CMSLayout: React.FC<React.PropsWithChildren<CMSLayoutProps>> = ({\n i18nText,\n activeNavItemId,\n sidebar,\n children,\n onChangeToEnLocale,\n onChangeToViLocale,\n onLogout,\n logoutLabel = 'Log out',\n copyright = `Copyright © ${new Date().getFullYear()}, Lunas.`,\n user,\n}) => {\n const groups = sidebar?.groupcontent ?? [];\n\n return (\n <CMSLayoutProvider>\n <CMSLayoutHeader\n i18nText={i18nText}\n onChangeToEnLocale={onChangeToEnLocale}\n onChangeToViLocale={onChangeToViLocale}\n user={user}\n onLogout={onLogout}\n logoutLabel={logoutLabel}\n />\n <CMSLayoutSidebar>\n <SidebarContent>\n {groups.map(group => (\n <SidebarContentGroup key={group.id} id={group.id} label={group.label}>\n {group.items.map(item => (\n <SidebarContentGroupItem\n key={item.id}\n id={item.id}\n activeNavItemId={activeNavItemId}\n label={item.label}\n icon={item.icon}\n renderAs={item.renderAs}\n onClick={item.onClick}\n />\n ))}\n </SidebarContentGroup>\n ))}\n </SidebarContent>\n <SidebarFooter>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton className=\"border border-border\" onClick={onLogout}>\n <LogOutIcon className=\"text-text-positive-weak\" />\n {logoutLabel}\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem className=\"mt-2 border-t border-t-border\">\n <p className=\"pt-2 text-center text-xs text-text-positive-subtle\">{copyright}</p>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarFooter>\n </CMSLayoutSidebar>\n <CMSLayoutMain>{children}</CMSLayoutMain>\n </CMSLayoutProvider>\n );\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("./ui/button.cjs"),t=require("./ui/dialog.cjs"),n=require("./ui/command.cjs"),r=require("./ui/popover.cjs"),i=require("./tanstack-form-DCB2addt.cjs");let a=require("lucide-react"),o=require("react"),s=require("@customafk/react-toolkit/utils"),c=require("react/jsx-runtime"),l=require("radix-ui"),u=require("@tanstack/react-form"),d=require("@customafk/react-toolkit/hooks/useMobile");const f=(0,o.memo)(({label:f,description:p,placeholder:m,tooltip:h,helperText:g,orientation:_=`responsive`,options:v,required:y=!1,disabled:b=!1,clearable:x=!1,showErrorMessage:S=!0,modal:C})=>{let w=(0,o.useId)(),T=i.rt(),E=(0,d.useIsMobile)(),[D,O]=(0,o.useState)(!1),[k,A]=(0,o.useState)(!1),j=(0,u.useStore)(T.form.store,({isSubmitting:e})=>e),M=b||j,N=T.state.meta.isDirty||T.state.meta.isTouched,P=N&&!T.state.meta.isValid,F=y&&T.state.value===null,I=x&&!!T.state.value&&!M,L=T.state.meta.errors.length>0,R=v.find(({value:e})=>e===T.state.value)?.label,z=()=>{T.handleChange(null),T.handleBlur()},B=t=>(0,c.jsx)(e.Button,{variant:`outline`,color:`muted`,size:`lg`,disabled:M,"aria-invalid":P?!0:void 0,"aria-describedby":w,className:(0,s.cn)(`flex w-full items-center justify-start rounded outline-border`,`hover:bg-transparent`,`focus-visible:outline-1 focus-visible:outline-primary-strong focus-visible:ring-4 focus-visible:ring-primary-weak`,`data-[state=open]:text-text-positive-muted data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak`,I&&`pr-8`,!T.state.value&&`text-text-positive-muted`,P&&`outline-danger bg-danger-bg-subtle ring-4 ring-danger-weak`),onClick:t,children:R?(0,c.jsx)(`p`,{className:`flex min-w-0 flex-1 items-center gap-2 truncate text-start`,children:R}):(0,c.jsx)(`p`,{className:`flex-1 text-start text-text-positive-muted`,children:m})}),V=e=>(0,c.jsxs)(n.Command,{className:`border-none`,children:[(0,c.jsx)(n.CommandInput,{placeholder:m??`Tìm kiếm…`}),(0,c.jsxs)(n.CommandList,{children:[(0,c.jsx)(n.CommandEmpty,{className:`flex min-h-30 items-center justify-center text-sm text-text-positive-weak`,children:`Không tìm thấy kết quả nào phù hợp.`}),(0,c.jsx)(n.CommandGroup,{className:`max-h-60 overflow-y-auto`,children:v.map(({value:t,label:r})=>(0,c.jsx)(n.CommandItem,{value:r,onSelect:()=>e(t),children:r},t))})]})]});return(0,c.jsxs)(i.X,{className:`gap-y-4 px-4`,children:[(0,c.jsxs)(i.G,{orientation:_,"data-invalid":P,children:[(0,c.jsxs)(i.K,{children:[(0,c.jsxs)(i.Z,{"aria-required":F,htmlFor:T.name,children:[f,h&&(0,c.jsx)(i.nt,{tooltip:h})]}),(0,c.jsx)(i.J,{children:p})]}),(0,c.jsx)(i.q,{className:`flex justify-end`,children:(0,c.jsxs)(`div`,{className:`flex w-full flex-col`,children:[(0,c.jsxs)(`div`,{className:`relative`,children:[E?(0,c.jsxs)(c.Fragment,{children:[B(()=>O(!0)),(0,c.jsx)(t.Dialog,{open:D,onOpenChange:e=>{O(e),e||T.handleBlur()},children:(0,c.jsxs)(t.DialogPortal,{children:[(0,c.jsx)(t.DialogOverlay,{}),(0,c.jsxs)(l.Dialog.Content,{onOpenAutoFocus:e=>e.preventDefault(),className:(0,s.cn)(`fixed inset-x-0 bottom-0 z-50`,`flex flex-col bg-background rounded-t-2xl outline-none`,`max-h-[80dvh] shadow-[0_-4px_24px_rgba(0,0,0,0.08)]`,`data-[state=open]:animate-in data-[state=open]:slide-in-from-bottom data-[state=open]:fade-in-0`,`data-[state=closed]:animate-out data-[state=closed]:slide-out-to-bottom data-[state=closed]:fade-out-0`,`duration-300`),children:[(0,c.jsxs)(`div`,{className:`flex items-center justify-between px-4 py-3 border-b border-border shrink-0`,children:[(0,c.jsx)(`span`,{className:`font-semibold text-sm text-text-positive`,children:f}),(0,c.jsx)(t.DialogClose,{asChild:!0,children:(0,c.jsx)(`button`,{type:`button`,"aria-label":`Đóng`,className:`flex size-7 items-center justify-center rounded-md text-text-positive-weak transition-colors hover:bg-muted-muted hover:text-text-positive`,children:(0,c.jsx)(a.XIcon,{size:16})})})]}),(0,c.jsxs)(`div`,{className:`flex flex-col overflow-y-auto`,children:[I&&(0,c.jsx)(t.DialogClose,{asChild:!0,children:(0,c.jsxs)(`button`,{type:`button`,className:`flex w-full items-center gap-x-2 px-4 py-3 text-left text-sm text-danger-strong transition-colors hover:bg-danger-bg-subtle`,onClick:z,children:[(0,c.jsx)(a.XIcon,{size:14}),`Xóa lựa chọn`]})}),V(e=>{T.handleChange(e),O(!1),T.handleBlur()})]}),(0,c.jsx)(`div`,{className:`shrink-0 h-safe-bottom`})]})]})})]}):(0,c.jsxs)(r.Popover,{open:k,modal:C,onOpenChange:e=>{A(e),e||T.handleBlur()},children:[(0,c.jsx)(r.PopoverTrigger,{asChild:!0,children:B()}),(0,c.jsx)(r.PopoverContent,{align:`end`,side:`bottom`,className:`flex w-fit rounded p-0`,children:V(e=>{T.handleChange(e),A(!1),T.handleBlur()})})]}),I&&(0,c.jsx)(`button`,{type:`button`,"aria-label":`Xóa lựa chọn`,className:`absolute right-2 top-1/2 -translate-y-1/2 flex size-4 cursor-pointer items-center justify-center rounded-md text-text-positive-weak outline-none transition-[color,transform] hover:text-text-positive focus-visible:text-primary-strong focus-visible:[&>svg]:scale-125 [&>svg]:size-3.5 [&>svg]:transition-transform`,onClick:z,children:(0,c.jsx)(a.XIcon,{"aria-hidden":`true`})})]}),N&&S&&L&&(0,c.jsx)(i.Y,{id:w,className:`mt-1`,errors:T.state.meta.errors}),(0,c.jsx)(i.$,{isShow:!!g,children:g})]})})]}),(0,c.jsx)(i.et,{})]})});f.displayName=`ComboboxField`,exports.ComboboxField=f;
|
|
2
|
+
//# sourceMappingURL=combobox-field-D7cZ8fhZ.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"combobox-field-ZYr7636s.cjs","names":["useTanStackFieldContext","Button","Command","CommandInput","CommandList","CommandEmpty","CommandGroup","CommandItem","FieldGroup","Field","FieldContent","FieldLabel","FieldTooltip","FieldDescription","FieldContentMain","Dialog","DialogPortal","DialogOverlay","RadixDialog","DialogClose","XIcon","Popover","PopoverTrigger","PopoverContent","FieldError","FieldNote","FieldSeparator"],"sources":["../packages/components/features/tanstack-form/components/fields/combobox-field.tsx"],"sourcesContent":["'use client';\n\nimport { memo, useId, useState } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { XIcon } from 'lucide-react';\n\nimport { Dialog as RadixDialog } from 'radix-ui';\n\nimport { useIsMobile } from '@customafk/react-toolkit/hooks/useMobile';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command';\nimport { Dialog, DialogClose, DialogOverlay, DialogPortal } from '@/components/ui/dialog';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\n\nimport { useTanStackFieldContext } from '../form-context';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\n\nimport type { ComboboxFieldProps } from '../../types';\n\nexport const ComboboxField = memo<ComboboxFieldProps>(\n ({\n label,\n description,\n placeholder,\n tooltip,\n helperText,\n orientation = 'responsive',\n options,\n required = false,\n disabled = false,\n clearable = false,\n showErrorMessage = true,\n modal,\n }) => {\n const errorId = useId();\n const field = useTanStackFieldContext<string | null>();\n const isMobile = useIsMobile();\n const [dialogOpen, setDialogOpen] = useState(false);\n const [popoverOpen, setPopoverOpen] = useState(false);\n\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n const isDisabled = disabled || isSubmitting;\n\n const _touched = field.state.meta.isDirty || field.state.meta.isTouched;\n const _invalid = _touched && !field.state.meta.isValid;\n const _isEmpty = required && field.state.value === null;\n const _showClear = clearable && !!field.state.value && !isDisabled;\n const _hasErrors = field.state.meta.errors.length > 0;\n\n const selectedLabel = options.find(({ value }) => value === field.state.value)?.label;\n\n const onClear = () => {\n field.handleChange(null);\n field.handleBlur();\n };\n\n const triggerButton = (onClick?: () => void) => (\n <Button\n variant=\"outline\"\n color=\"muted\"\n size=\"lg\"\n disabled={isDisabled}\n aria-invalid={_invalid ? true : undefined}\n aria-describedby={errorId}\n className={cn(\n 'flex w-full items-center justify-start rounded outline-border',\n 'hover:bg-transparent',\n 'focus-visible:outline-1 focus-visible:outline-primary-strong focus-visible:ring-4 focus-visible:ring-primary-weak',\n 'data-[state=open]:text-text-positive-muted data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak',\n _showClear && 'pr-8',\n !field.state.value && 'text-text-positive-muted',\n _invalid && 'outline-danger bg-danger-bg-subtle ring-4 ring-danger-weak'\n )}\n onClick={onClick}\n >\n {selectedLabel ? (\n <p className=\"flex min-w-0 flex-1 items-center gap-2 truncate text-start\">{selectedLabel}</p>\n ) : (\n <p className=\"flex-1 text-start text-text-positive-muted\">{placeholder}</p>\n )}\n </Button>\n );\n\n const renderCommandList = (onSelect: (value: string) => void) => (\n <Command className=\"border-none\">\n <CommandInput placeholder={placeholder ?? 'Tìm kiếm…'} />\n <CommandList>\n <CommandEmpty className=\"flex min-h-30 items-center justify-center text-sm text-text-positive-weak\">Không tìm thấy kết quả nào phù hợp.</CommandEmpty>\n <CommandGroup className=\"max-h-60 overflow-y-auto\">\n {options.map(({ value, label: optLabel }) => (\n <CommandItem key={value} value={optLabel} onSelect={() => onSelect(value)}>\n {optLabel}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n );\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation={orientation} data-invalid={_invalid}>\n <FieldContent>\n <FieldLabel aria-required={_isEmpty} htmlFor={field.name}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n\n <FieldContentMain className=\"flex justify-end\">\n <div className=\"flex w-full flex-col\">\n <div className=\"relative\">\n {isMobile ? (\n <>\n {triggerButton(() => setDialogOpen(true))}\n <Dialog\n open={dialogOpen}\n onOpenChange={open => {\n setDialogOpen(open);\n if (!open) field.handleBlur();\n }}\n >\n <DialogPortal>\n <DialogOverlay />\n <RadixDialog.Content\n onOpenAutoFocus={e => e.preventDefault()}\n className={cn(\n 'fixed inset-x-0 bottom-0 z-50',\n 'flex flex-col bg-background rounded-t-2xl outline-none',\n 'max-h-[80dvh] shadow-[0_-4px_24px_rgba(0,0,0,0.08)]',\n 'data-[state=open]:animate-in data-[state=open]:slide-in-from-bottom data-[state=open]:fade-in-0',\n 'data-[state=closed]:animate-out data-[state=closed]:slide-out-to-bottom data-[state=closed]:fade-out-0',\n 'duration-300'\n )}\n >\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border shrink-0\">\n <span className=\"font-semibold text-sm text-text-positive\">{label}</span>\n <DialogClose asChild>\n <button\n type=\"button\"\n aria-label=\"Đóng\"\n className=\"flex size-7 items-center justify-center rounded-md text-text-positive-weak transition-colors hover:bg-muted-muted hover:text-text-positive\"\n >\n <XIcon size={16} />\n </button>\n </DialogClose>\n </div>\n\n <div className=\"flex flex-col overflow-y-auto\">\n {_showClear && (\n <DialogClose asChild>\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-x-2 px-4 py-3 text-left text-sm text-danger-strong transition-colors hover:bg-danger-bg-subtle\"\n onClick={onClear}\n >\n <XIcon size={14} />\n Xóa lựa chọn\n </button>\n </DialogClose>\n )}\n {renderCommandList(value => {\n field.handleChange(value);\n setDialogOpen(false);\n field.handleBlur();\n })}\n </div>\n\n <div className=\"shrink-0 h-safe-bottom\" />\n </RadixDialog.Content>\n </DialogPortal>\n </Dialog>\n </>\n ) : (\n <Popover\n open={popoverOpen}\n modal={modal}\n onOpenChange={open => {\n setPopoverOpen(open);\n if (!open) field.handleBlur();\n }}\n >\n <PopoverTrigger asChild>{triggerButton()}</PopoverTrigger>\n <PopoverContent align=\"end\" side=\"bottom\" className=\"flex w-fit rounded p-0\">\n {renderCommandList(value => {\n field.handleChange(value);\n setPopoverOpen(false);\n field.handleBlur();\n })}\n </PopoverContent>\n </Popover>\n )}\n\n {_showClear && (\n <button\n type=\"button\"\n aria-label=\"Xóa lựa chọn\"\n className=\"absolute right-2 top-1/2 -translate-y-1/2 flex size-4 cursor-pointer items-center justify-center rounded-md text-text-positive-weak outline-none transition-[color,transform] hover:text-text-positive focus-visible:text-primary-strong focus-visible:[&>svg]:scale-125 [&>svg]:size-3.5 [&>svg]:transition-transform\"\n onClick={onClear}\n >\n <XIcon aria-hidden=\"true\" />\n </button>\n )}\n </div>\n\n {_touched && showErrorMessage && _hasErrors && <FieldError id={errorId} className=\"mt-1\" errors={field.state.meta.errors} />}\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </div>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n }\n);\n\nComboboxField.displayName = 'ComboboxField';\n"],"mappings":"kbAkCA,MAAa,GAAA,EAAA,EAAA,KAAA,EACV,CACC,QACA,cACA,cACA,UACA,aACA,cAAc,aACd,UACA,WAAW,GACX,WAAW,GACX,YAAY,GACZ,mBAAmB,GACnB,WACI,CACJ,IAAM,GAAA,EAAA,EAAA,MAAA,CAAgB,EAChB,EAAQA,EAAAA,EAAuC,EAC/C,GAAA,EAAA,EAAA,YAAA,CAAuB,EACvB,CAAC,EAAY,IAAA,EAAA,EAAA,SAAA,CAA0B,EAAK,EAC5C,CAAC,EAAa,IAAA,EAAA,EAAA,SAAA,CAA2B,EAAK,EAE9C,GAAA,EAAA,EAAA,SAAA,CAAwB,EAAM,KAAK,OAAQ,CAAE,kBAAmB,CAAY,EAC5E,EAAa,GAAY,EAEzB,EAAW,EAAM,MAAM,KAAK,SAAW,EAAM,MAAM,KAAK,UACxD,EAAW,GAAY,CAAC,EAAM,MAAM,KAAK,QACzC,EAAW,GAAY,EAAM,MAAM,QAAU,KAC7C,EAAa,GAAa,CAAC,CAAC,EAAM,MAAM,OAAS,CAAC,EAClD,EAAa,EAAM,MAAM,KAAK,OAAO,OAAS,EAE9C,EAAgB,EAAQ,MAAM,CAAE,WAAY,IAAU,EAAM,MAAM,KAAK,CAAC,EAAE,MAE1E,MAAgB,CACpB,EAAM,aAAa,IAAI,EACvB,EAAM,WAAW,CACnB,EAEM,EAAiB,IACrB,EAAA,EAAA,IAAA,CAACC,EAAAA,OAAD,CACE,QAAQ,UACR,MAAM,QACN,KAAK,KACL,SAAU,EACV,eAAc,EAAW,GAAO,IAAA,GAChC,mBAAkB,EAClB,WAAA,EAAA,EAAA,GAAA,CACE,gEACA,uBACA,oHACA,+KACA,GAAc,OACd,CAAC,EAAM,MAAM,OAAS,2BACtB,GAAY,4DACd,EACS,UAER,SAAA,GACC,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAU,6DAA8D,SAAA,CAAiB,CAAA,GAE5F,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAU,6CAA8C,SAAA,CAAe,CAAA,CAEtE,CAAA,EAGJ,EAAqB,IACzB,EAAA,EAAA,KAAA,CAACC,EAAAA,QAAD,CAAS,UAAU,cAAnB,SAAA,EACE,EAAA,EAAA,IAAA,CAACC,EAAAA,aAAD,CAAc,YAAa,GAAe,WAAc,CAAA,GACxD,EAAA,EAAA,KAAA,CAACC,EAAAA,YAAD,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAACC,EAAAA,aAAD,CAAc,UAAU,4EAA4E,SAAA,qCAAiD,CAAA,GACrJ,EAAA,EAAA,IAAA,CAACC,EAAAA,aAAD,CAAc,UAAU,2BACrB,SAAA,EAAQ,KAAK,CAAE,QAAO,MAAO,MAC5B,EAAA,EAAA,IAAA,CAACC,EAAAA,YAAD,CAAyB,MAAO,EAAU,aAAgB,EAAS,CAAK,EACrE,SAAA,CACU,EAFK,CAEL,CACd,CACW,CAAA,CACH,CAAA,CAAA,CACN,IAGX,OACE,EAAA,EAAA,KAAA,CAACC,EAAAA,WAAD,CAAY,UAAU,eAAtB,SAAA,EACE,EAAA,EAAA,KAAA,CAACC,EAAAA,MAAD,CAAoB,cAAa,eAAc,EAA/C,SAAA,EACE,EAAA,EAAA,KAAA,CAACC,EAAAA,aAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAA,CAACC,EAAAA,WAAD,CAAY,gBAAe,EAAU,QAAS,EAAM,KAApD,SAAA,CACG,EACA,IAAW,EAAA,EAAA,IAAA,CAACC,EAAAA,aAAD,CAAuB,SAAU,CAAA,CACnC,CACZ,CAAA,GAAA,EAAA,EAAA,IAAA,CAACC,EAAAA,iBAAD,CAAA,SAAmB,CAA8B,CAAA,CACrC,CAAA,CAAA,GAEd,EAAA,EAAA,IAAA,CAACC,EAAAA,iBAAD,CAAkB,UAAU,mBAC1B,UAAA,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,uBAAf,SAAA,EACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,WAAf,SAAA,CACG,GACC,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,CACG,MAAoB,EAAc,EAAI,CAAC,GACxC,EAAA,EAAA,IAAA,CAACC,EAAAA,OAAD,CACE,KAAM,EACN,aAAc,GAAQ,CACpB,EAAc,CAAI,EACb,GAAM,EAAM,WAAW,CAC9B,EAEA,UAAA,EAAA,EAAA,KAAA,CAACC,EAAAA,aAAD,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAACC,EAAAA,cAAD,CAAgB,CAAA,GAChB,EAAA,EAAA,KAAA,CAACC,EAAAA,OAAY,QAAb,CACE,gBAAiB,GAAK,EAAE,eAAe,EACvC,WAAA,EAAA,EAAA,GAAA,CACE,gCACA,yDACA,sDACA,kGACA,yGACA,cACF,EATF,SAAA,EAWE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,8EAAf,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,2CAA4C,SAAA,CAAY,CAAA,GACxE,EAAA,EAAA,IAAA,CAACC,EAAAA,YAAD,CAAa,QAAA,GACX,UAAA,EAAA,EAAA,IAAA,CAAC,SAAD,CACE,KAAK,SACL,aAAW,OACX,UAAU,6IAEV,UAAA,EAAA,EAAA,IAAA,CAACC,EAAAA,MAAD,CAAO,KAAM,EAAK,CAAA,CACZ,CAAA,CACG,CAAA,CACV,KAEL,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,gCAAf,SAAA,CACG,IACC,EAAA,EAAA,IAAA,CAACD,EAAAA,YAAD,CAAa,QAAA,GACX,UAAA,EAAA,EAAA,KAAA,CAAC,SAAD,CACE,KAAK,SACL,UAAU,8HACV,QAAS,EAHX,SAAA,EAKE,EAAA,EAAA,IAAA,CAACC,EAAAA,MAAD,CAAO,KAAM,EAAK,CAAA,EAAC,cAEb,GACG,CAAA,EAEd,EAAkB,GAAS,CAC1B,EAAM,aAAa,CAAK,EACxB,EAAc,EAAK,EACnB,EAAM,WAAW,CACnB,CAAC,CACE,KAEL,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,wBAA0B,CAAA,CACtB,CACT,CAAA,CAAA,CAAA,CAAA,CACR,CAAA,CACR,CAAA,CAAA,GAEF,EAAA,EAAA,KAAA,CAACC,EAAAA,QAAD,CACE,KAAM,EACC,QACP,aAAc,GAAQ,CACpB,EAAe,CAAI,EACd,GAAM,EAAM,WAAW,CAC9B,EANF,SAAA,EAQE,EAAA,EAAA,IAAA,CAACC,EAAAA,eAAD,CAAgB,QAAA,GAAS,SAAA,EAAc,CAAkB,CAAA,GACzD,EAAA,EAAA,IAAA,CAACC,EAAAA,eAAD,CAAgB,MAAM,MAAM,KAAK,SAAS,UAAU,yBACjD,SAAA,EAAkB,GAAS,CAC1B,EAAM,aAAa,CAAK,EACxB,EAAe,EAAK,EACpB,EAAM,WAAW,CACnB,CAAC,CACa,CAAA,CACT,CAGV,CAAA,EAAA,IACC,EAAA,EAAA,IAAA,CAAC,SAAD,CACE,KAAK,SACL,aAAW,eACX,UAAU,yTACV,QAAS,EAET,UAAA,EAAA,EAAA,IAAA,CAACH,EAAAA,MAAD,CAAO,cAAY,MAAQ,CAAA,CACrB,CAAA,CAEP,IAEJ,GAAY,GAAoB,IAAc,EAAA,EAAA,IAAA,CAACI,EAAAA,WAAD,CAAY,GAAI,EAAS,UAAU,OAAO,OAAQ,EAAM,MAAM,KAAK,MAAS,CAAA,GAC3H,EAAA,EAAA,IAAA,CAACC,EAAAA,UAAD,CAAW,OAAQ,CAAC,CAAC,EAAa,SAAA,CAAsB,CAAA,CACrD,GACW,CAAA,CACb,CACP,CAAA,GAAA,EAAA,EAAA,IAAA,CAACC,EAAAA,eAAD,CAAiB,CAAA,CACP,GAEhB,CACF,EAEA,EAAc,YAAc"}
|
|
1
|
+
{"version":3,"file":"combobox-field-D7cZ8fhZ.cjs","names":["useTanStackFieldContext","Button","Command","CommandInput","CommandList","CommandEmpty","CommandGroup","CommandItem","FieldGroup","Field","FieldContent","FieldLabel","FieldTooltip","FieldDescription","FieldContentMain","Dialog","DialogPortal","DialogOverlay","RadixDialog","DialogClose","XIcon","Popover","PopoverTrigger","PopoverContent","FieldError","FieldNote","FieldSeparator"],"sources":["../packages/components/features/tanstack-form/components/fields/combobox-field.tsx"],"sourcesContent":["'use client';\n\nimport { memo, useId, useState } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { XIcon } from 'lucide-react';\n\nimport { Dialog as RadixDialog } from 'radix-ui';\n\nimport { useIsMobile } from '@customafk/react-toolkit/hooks/useMobile';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command';\nimport { Dialog, DialogClose, DialogOverlay, DialogPortal } from '@/components/ui/dialog';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\n\nimport { useTanStackFieldContext } from '../form-context';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\n\nimport type { ComboboxFieldProps } from '../../types';\n\nexport const ComboboxField = memo<ComboboxFieldProps>(\n ({\n label,\n description,\n placeholder,\n tooltip,\n helperText,\n orientation = 'responsive',\n options,\n required = false,\n disabled = false,\n clearable = false,\n showErrorMessage = true,\n modal,\n }) => {\n const errorId = useId();\n const field = useTanStackFieldContext<string | null>();\n const isMobile = useIsMobile();\n const [dialogOpen, setDialogOpen] = useState(false);\n const [popoverOpen, setPopoverOpen] = useState(false);\n\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n const isDisabled = disabled || isSubmitting;\n\n const _touched = field.state.meta.isDirty || field.state.meta.isTouched;\n const _invalid = _touched && !field.state.meta.isValid;\n const _isEmpty = required && field.state.value === null;\n const _showClear = clearable && !!field.state.value && !isDisabled;\n const _hasErrors = field.state.meta.errors.length > 0;\n\n const selectedLabel = options.find(({ value }) => value === field.state.value)?.label;\n\n const onClear = () => {\n field.handleChange(null);\n field.handleBlur();\n };\n\n const triggerButton = (onClick?: () => void) => (\n <Button\n variant=\"outline\"\n color=\"muted\"\n size=\"lg\"\n disabled={isDisabled}\n aria-invalid={_invalid ? true : undefined}\n aria-describedby={errorId}\n className={cn(\n 'flex w-full items-center justify-start rounded outline-border',\n 'hover:bg-transparent',\n 'focus-visible:outline-1 focus-visible:outline-primary-strong focus-visible:ring-4 focus-visible:ring-primary-weak',\n 'data-[state=open]:text-text-positive-muted data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak',\n _showClear && 'pr-8',\n !field.state.value && 'text-text-positive-muted',\n _invalid && 'outline-danger bg-danger-bg-subtle ring-4 ring-danger-weak'\n )}\n onClick={onClick}\n >\n {selectedLabel ? (\n <p className=\"flex min-w-0 flex-1 items-center gap-2 truncate text-start\">{selectedLabel}</p>\n ) : (\n <p className=\"flex-1 text-start text-text-positive-muted\">{placeholder}</p>\n )}\n </Button>\n );\n\n const renderCommandList = (onSelect: (value: string) => void) => (\n <Command className=\"border-none\">\n <CommandInput placeholder={placeholder ?? 'Tìm kiếm…'} />\n <CommandList>\n <CommandEmpty className=\"flex min-h-30 items-center justify-center text-sm text-text-positive-weak\">Không tìm thấy kết quả nào phù hợp.</CommandEmpty>\n <CommandGroup className=\"max-h-60 overflow-y-auto\">\n {options.map(({ value, label: optLabel }) => (\n <CommandItem key={value} value={optLabel} onSelect={() => onSelect(value)}>\n {optLabel}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n );\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation={orientation} data-invalid={_invalid}>\n <FieldContent>\n <FieldLabel aria-required={_isEmpty} htmlFor={field.name}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n\n <FieldContentMain className=\"flex justify-end\">\n <div className=\"flex w-full flex-col\">\n <div className=\"relative\">\n {isMobile ? (\n <>\n {triggerButton(() => setDialogOpen(true))}\n <Dialog\n open={dialogOpen}\n onOpenChange={open => {\n setDialogOpen(open);\n if (!open) field.handleBlur();\n }}\n >\n <DialogPortal>\n <DialogOverlay />\n <RadixDialog.Content\n onOpenAutoFocus={e => e.preventDefault()}\n className={cn(\n 'fixed inset-x-0 bottom-0 z-50',\n 'flex flex-col bg-background rounded-t-2xl outline-none',\n 'max-h-[80dvh] shadow-[0_-4px_24px_rgba(0,0,0,0.08)]',\n 'data-[state=open]:animate-in data-[state=open]:slide-in-from-bottom data-[state=open]:fade-in-0',\n 'data-[state=closed]:animate-out data-[state=closed]:slide-out-to-bottom data-[state=closed]:fade-out-0',\n 'duration-300'\n )}\n >\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border shrink-0\">\n <span className=\"font-semibold text-sm text-text-positive\">{label}</span>\n <DialogClose asChild>\n <button\n type=\"button\"\n aria-label=\"Đóng\"\n className=\"flex size-7 items-center justify-center rounded-md text-text-positive-weak transition-colors hover:bg-muted-muted hover:text-text-positive\"\n >\n <XIcon size={16} />\n </button>\n </DialogClose>\n </div>\n\n <div className=\"flex flex-col overflow-y-auto\">\n {_showClear && (\n <DialogClose asChild>\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-x-2 px-4 py-3 text-left text-sm text-danger-strong transition-colors hover:bg-danger-bg-subtle\"\n onClick={onClear}\n >\n <XIcon size={14} />\n Xóa lựa chọn\n </button>\n </DialogClose>\n )}\n {renderCommandList(value => {\n field.handleChange(value);\n setDialogOpen(false);\n field.handleBlur();\n })}\n </div>\n\n <div className=\"shrink-0 h-safe-bottom\" />\n </RadixDialog.Content>\n </DialogPortal>\n </Dialog>\n </>\n ) : (\n <Popover\n open={popoverOpen}\n modal={modal}\n onOpenChange={open => {\n setPopoverOpen(open);\n if (!open) field.handleBlur();\n }}\n >\n <PopoverTrigger asChild>{triggerButton()}</PopoverTrigger>\n <PopoverContent align=\"end\" side=\"bottom\" className=\"flex w-fit rounded p-0\">\n {renderCommandList(value => {\n field.handleChange(value);\n setPopoverOpen(false);\n field.handleBlur();\n })}\n </PopoverContent>\n </Popover>\n )}\n\n {_showClear && (\n <button\n type=\"button\"\n aria-label=\"Xóa lựa chọn\"\n className=\"absolute right-2 top-1/2 -translate-y-1/2 flex size-4 cursor-pointer items-center justify-center rounded-md text-text-positive-weak outline-none transition-[color,transform] hover:text-text-positive focus-visible:text-primary-strong focus-visible:[&>svg]:scale-125 [&>svg]:size-3.5 [&>svg]:transition-transform\"\n onClick={onClear}\n >\n <XIcon aria-hidden=\"true\" />\n </button>\n )}\n </div>\n\n {_touched && showErrorMessage && _hasErrors && <FieldError id={errorId} className=\"mt-1\" errors={field.state.meta.errors} />}\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </div>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n }\n);\n\nComboboxField.displayName = 'ComboboxField';\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{$ as e,G as t,J as n,K as ee,X as te,Y as r,Z as i,et as a,nt as o,q as s,rt as ne}from"./tanstack-form-BhKAn9I0.mjs";import{Button as re}from"./ui/button.mjs";import{Dialog as ie,DialogClose as c,DialogOverlay as l,DialogPortal as u}from"./ui/dialog.mjs";import{Command as d,CommandEmpty as f,CommandGroup as p,CommandInput as m,CommandItem as h,CommandList as g}from"./ui/command.mjs";import{Popover as _,PopoverContent as ae,PopoverTrigger as oe}from"./ui/popover.mjs";import{XIcon as v}from"lucide-react";import{memo as y,useId as se,useState as b}from"react";import{cn as x}from"@customafk/react-toolkit/utils";import{Fragment as S,jsx as C,jsxs as w}from"react/jsx-runtime";import{Dialog as T}from"radix-ui";import{useStore as E}from"@tanstack/react-form";import{useIsMobile as D}from"@customafk/react-toolkit/hooks/useMobile";const O=y(({label:y,description:O,placeholder:k,tooltip:A,helperText:j,orientation:M=`responsive`,options:N,required:P=!1,disabled:F=!1,clearable:ce=!1,showErrorMessage:I=!0,modal:L})=>{let R=se(),z=ne(),B=D(),[V,H]=b(!1),[U,W]=b(!1),G=E(z.form.store,({isSubmitting:e})=>e),K=F||G,q=z.state.meta.isDirty||z.state.meta.isTouched,J=q&&!z.state.meta.isValid,le=P&&z.state.value===null,Y=ce&&!!z.state.value&&!K,ue=z.state.meta.errors.length>0,X=N.find(({value:e})=>e===z.state.value)?.label,Z=()=>{z.handleChange(null),z.handleBlur()},Q=e=>C(re,{variant:`outline`,color:`muted`,size:`lg`,disabled:K,"aria-invalid":J?!0:void 0,"aria-describedby":R,className:x(`flex w-full items-center justify-start rounded outline-border`,`hover:bg-transparent`,`focus-visible:outline-1 focus-visible:outline-primary-strong focus-visible:ring-4 focus-visible:ring-primary-weak`,`data-[state=open]:text-text-positive-muted data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak`,Y&&`pr-8`,!z.state.value&&`text-text-positive-muted`,J&&`outline-danger bg-danger-bg-subtle ring-4 ring-danger-weak`),onClick:e,children:X?C(`p`,{className:`flex min-w-0 flex-1 items-center gap-2 truncate text-start`,children:X}):C(`p`,{className:`flex-1 text-start text-text-positive-muted`,children:k})}),$=e=>w(d,{className:`border-none`,children:[C(m,{placeholder:k??`Tìm kiếm…`}),w(g,{children:[C(f,{className:`flex min-h-30 items-center justify-center text-sm text-text-positive-weak`,children:`Không tìm thấy kết quả nào phù hợp.`}),C(p,{className:`max-h-60 overflow-y-auto`,children:N.map(({value:t,label:n})=>C(h,{value:n,onSelect:()=>e(t),children:n},t))})]})]});return w(te,{className:`gap-y-4 px-4`,children:[w(t,{orientation:M,"data-invalid":J,children:[w(ee,{children:[w(i,{"aria-required":le,htmlFor:z.name,children:[y,A&&C(o,{tooltip:A})]}),C(n,{children:O})]}),C(s,{className:`flex justify-end`,children:w(`div`,{className:`flex w-full flex-col`,children:[w(`div`,{className:`relative`,children:[B?w(S,{children:[Q(()=>H(!0)),C(ie,{open:V,onOpenChange:e=>{H(e),e||z.handleBlur()},children:w(u,{children:[C(l,{}),w(T.Content,{onOpenAutoFocus:e=>e.preventDefault(),className:x(`fixed inset-x-0 bottom-0 z-50`,`flex flex-col bg-background rounded-t-2xl outline-none`,`max-h-[80dvh] shadow-[0_-4px_24px_rgba(0,0,0,0.08)]`,`data-[state=open]:animate-in data-[state=open]:slide-in-from-bottom data-[state=open]:fade-in-0`,`data-[state=closed]:animate-out data-[state=closed]:slide-out-to-bottom data-[state=closed]:fade-out-0`,`duration-300`),children:[w(`div`,{className:`flex items-center justify-between px-4 py-3 border-b border-border shrink-0`,children:[C(`span`,{className:`font-semibold text-sm text-text-positive`,children:y}),C(c,{asChild:!0,children:C(`button`,{type:`button`,"aria-label":`Đóng`,className:`flex size-7 items-center justify-center rounded-md text-text-positive-weak transition-colors hover:bg-muted-muted hover:text-text-positive`,children:C(v,{size:16})})})]}),w(`div`,{className:`flex flex-col overflow-y-auto`,children:[Y&&C(c,{asChild:!0,children:w(`button`,{type:`button`,className:`flex w-full items-center gap-x-2 px-4 py-3 text-left text-sm text-danger-strong transition-colors hover:bg-danger-bg-subtle`,onClick:Z,children:[C(v,{size:14}),`Xóa lựa chọn`]})}),$(e=>{z.handleChange(e),H(!1),z.handleBlur()})]}),C(`div`,{className:`shrink-0 h-safe-bottom`})]})]})})]}):w(_,{open:U,modal:L,onOpenChange:e=>{W(e),e||z.handleBlur()},children:[C(oe,{asChild:!0,children:Q()}),C(ae,{align:`end`,side:`bottom`,className:`flex w-fit rounded p-0`,children:$(e=>{z.handleChange(e),W(!1),z.handleBlur()})})]}),Y&&C(`button`,{type:`button`,"aria-label":`Xóa lựa chọn`,className:`absolute right-2 top-1/2 -translate-y-1/2 flex size-4 cursor-pointer items-center justify-center rounded-md text-text-positive-weak outline-none transition-[color,transform] hover:text-text-positive focus-visible:text-primary-strong focus-visible:[&>svg]:scale-125 [&>svg]:size-3.5 [&>svg]:transition-transform`,onClick:Z,children:C(v,{"aria-hidden":`true`})})]}),q&&I&&ue&&C(r,{id:R,className:`mt-1`,errors:z.state.meta.errors}),C(e,{isShow:!!j,children:j})]})})]}),C(a,{})]})});O.displayName=`ComboboxField`;export{O as ComboboxField};
|
|
2
|
+
//# sourceMappingURL=combobox-field-ebIvbhJn.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"combobox-field-CvkdZkQE.mjs","names":["Dialog","RadixDialog","Popover"],"sources":["../packages/components/features/tanstack-form/components/fields/combobox-field.tsx"],"sourcesContent":["'use client';\n\nimport { memo, useId, useState } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { XIcon } from 'lucide-react';\n\nimport { Dialog as RadixDialog } from 'radix-ui';\n\nimport { useIsMobile } from '@customafk/react-toolkit/hooks/useMobile';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command';\nimport { Dialog, DialogClose, DialogOverlay, DialogPortal } from '@/components/ui/dialog';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\n\nimport { useTanStackFieldContext } from '../form-context';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\n\nimport type { ComboboxFieldProps } from '../../types';\n\nexport const ComboboxField = memo<ComboboxFieldProps>(\n ({\n label,\n description,\n placeholder,\n tooltip,\n helperText,\n orientation = 'responsive',\n options,\n required = false,\n disabled = false,\n clearable = false,\n showErrorMessage = true,\n modal,\n }) => {\n const errorId = useId();\n const field = useTanStackFieldContext<string | null>();\n const isMobile = useIsMobile();\n const [dialogOpen, setDialogOpen] = useState(false);\n const [popoverOpen, setPopoverOpen] = useState(false);\n\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n const isDisabled = disabled || isSubmitting;\n\n const _touched = field.state.meta.isDirty || field.state.meta.isTouched;\n const _invalid = _touched && !field.state.meta.isValid;\n const _isEmpty = required && field.state.value === null;\n const _showClear = clearable && !!field.state.value && !isDisabled;\n const _hasErrors = field.state.meta.errors.length > 0;\n\n const selectedLabel = options.find(({ value }) => value === field.state.value)?.label;\n\n const onClear = () => {\n field.handleChange(null);\n field.handleBlur();\n };\n\n const triggerButton = (onClick?: () => void) => (\n <Button\n variant=\"outline\"\n color=\"muted\"\n size=\"lg\"\n disabled={isDisabled}\n aria-invalid={_invalid ? true : undefined}\n aria-describedby={errorId}\n className={cn(\n 'flex w-full items-center justify-start rounded outline-border',\n 'hover:bg-transparent',\n 'focus-visible:outline-1 focus-visible:outline-primary-strong focus-visible:ring-4 focus-visible:ring-primary-weak',\n 'data-[state=open]:text-text-positive-muted data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak',\n _showClear && 'pr-8',\n !field.state.value && 'text-text-positive-muted',\n _invalid && 'outline-danger bg-danger-bg-subtle ring-4 ring-danger-weak'\n )}\n onClick={onClick}\n >\n {selectedLabel ? (\n <p className=\"flex min-w-0 flex-1 items-center gap-2 truncate text-start\">{selectedLabel}</p>\n ) : (\n <p className=\"flex-1 text-start text-text-positive-muted\">{placeholder}</p>\n )}\n </Button>\n );\n\n const renderCommandList = (onSelect: (value: string) => void) => (\n <Command className=\"border-none\">\n <CommandInput placeholder={placeholder ?? 'Tìm kiếm…'} />\n <CommandList>\n <CommandEmpty className=\"flex min-h-30 items-center justify-center text-sm text-text-positive-weak\">Không tìm thấy kết quả nào phù hợp.</CommandEmpty>\n <CommandGroup className=\"max-h-60 overflow-y-auto\">\n {options.map(({ value, label: optLabel }) => (\n <CommandItem key={value} value={optLabel} onSelect={() => onSelect(value)}>\n {optLabel}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n );\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation={orientation} data-invalid={_invalid}>\n <FieldContent>\n <FieldLabel aria-required={_isEmpty} htmlFor={field.name}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n\n <FieldContentMain className=\"flex justify-end\">\n <div className=\"flex w-full flex-col\">\n <div className=\"relative\">\n {isMobile ? (\n <>\n {triggerButton(() => setDialogOpen(true))}\n <Dialog\n open={dialogOpen}\n onOpenChange={open => {\n setDialogOpen(open);\n if (!open) field.handleBlur();\n }}\n >\n <DialogPortal>\n <DialogOverlay />\n <RadixDialog.Content\n onOpenAutoFocus={e => e.preventDefault()}\n className={cn(\n 'fixed inset-x-0 bottom-0 z-50',\n 'flex flex-col bg-background rounded-t-2xl outline-none',\n 'max-h-[80dvh] shadow-[0_-4px_24px_rgba(0,0,0,0.08)]',\n 'data-[state=open]:animate-in data-[state=open]:slide-in-from-bottom data-[state=open]:fade-in-0',\n 'data-[state=closed]:animate-out data-[state=closed]:slide-out-to-bottom data-[state=closed]:fade-out-0',\n 'duration-300'\n )}\n >\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border shrink-0\">\n <span className=\"font-semibold text-sm text-text-positive\">{label}</span>\n <DialogClose asChild>\n <button\n type=\"button\"\n aria-label=\"Đóng\"\n className=\"flex size-7 items-center justify-center rounded-md text-text-positive-weak transition-colors hover:bg-muted-muted hover:text-text-positive\"\n >\n <XIcon size={16} />\n </button>\n </DialogClose>\n </div>\n\n <div className=\"flex flex-col overflow-y-auto\">\n {_showClear && (\n <DialogClose asChild>\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-x-2 px-4 py-3 text-left text-sm text-danger-strong transition-colors hover:bg-danger-bg-subtle\"\n onClick={onClear}\n >\n <XIcon size={14} />\n Xóa lựa chọn\n </button>\n </DialogClose>\n )}\n {renderCommandList(value => {\n field.handleChange(value);\n setDialogOpen(false);\n field.handleBlur();\n })}\n </div>\n\n <div className=\"shrink-0 h-safe-bottom\" />\n </RadixDialog.Content>\n </DialogPortal>\n </Dialog>\n </>\n ) : (\n <Popover\n open={popoverOpen}\n modal={modal}\n onOpenChange={open => {\n setPopoverOpen(open);\n if (!open) field.handleBlur();\n }}\n >\n <PopoverTrigger asChild>{triggerButton()}</PopoverTrigger>\n <PopoverContent align=\"end\" side=\"bottom\" className=\"flex w-fit rounded p-0\">\n {renderCommandList(value => {\n field.handleChange(value);\n setPopoverOpen(false);\n field.handleBlur();\n })}\n </PopoverContent>\n </Popover>\n )}\n\n {_showClear && (\n <button\n type=\"button\"\n aria-label=\"Xóa lựa chọn\"\n className=\"absolute right-2 top-1/2 -translate-y-1/2 flex size-4 cursor-pointer items-center justify-center rounded-md text-text-positive-weak outline-none transition-[color,transform] hover:text-text-positive focus-visible:text-primary-strong focus-visible:[&>svg]:scale-125 [&>svg]:size-3.5 [&>svg]:transition-transform\"\n onClick={onClear}\n >\n <XIcon aria-hidden=\"true\" />\n </button>\n )}\n </div>\n\n {_touched && showErrorMessage && _hasErrors && <FieldError id={errorId} className=\"mt-1\" errors={field.state.meta.errors} />}\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </div>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n }\n);\n\nComboboxField.displayName = 'ComboboxField';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"combobox-field-ebIvbhJn.mjs","names":["Dialog","RadixDialog","Popover"],"sources":["../packages/components/features/tanstack-form/components/fields/combobox-field.tsx"],"sourcesContent":["'use client';\n\nimport { memo, useId, useState } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { XIcon } from 'lucide-react';\n\nimport { Dialog as RadixDialog } from 'radix-ui';\n\nimport { useIsMobile } from '@customafk/react-toolkit/hooks/useMobile';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command';\nimport { Dialog, DialogClose, DialogOverlay, DialogPortal } from '@/components/ui/dialog';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\n\nimport { useTanStackFieldContext } from '../form-context';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\n\nimport type { ComboboxFieldProps } from '../../types';\n\nexport const ComboboxField = memo<ComboboxFieldProps>(\n ({\n label,\n description,\n placeholder,\n tooltip,\n helperText,\n orientation = 'responsive',\n options,\n required = false,\n disabled = false,\n clearable = false,\n showErrorMessage = true,\n modal,\n }) => {\n const errorId = useId();\n const field = useTanStackFieldContext<string | null>();\n const isMobile = useIsMobile();\n const [dialogOpen, setDialogOpen] = useState(false);\n const [popoverOpen, setPopoverOpen] = useState(false);\n\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n const isDisabled = disabled || isSubmitting;\n\n const _touched = field.state.meta.isDirty || field.state.meta.isTouched;\n const _invalid = _touched && !field.state.meta.isValid;\n const _isEmpty = required && field.state.value === null;\n const _showClear = clearable && !!field.state.value && !isDisabled;\n const _hasErrors = field.state.meta.errors.length > 0;\n\n const selectedLabel = options.find(({ value }) => value === field.state.value)?.label;\n\n const onClear = () => {\n field.handleChange(null);\n field.handleBlur();\n };\n\n const triggerButton = (onClick?: () => void) => (\n <Button\n variant=\"outline\"\n color=\"muted\"\n size=\"lg\"\n disabled={isDisabled}\n aria-invalid={_invalid ? true : undefined}\n aria-describedby={errorId}\n className={cn(\n 'flex w-full items-center justify-start rounded outline-border',\n 'hover:bg-transparent',\n 'focus-visible:outline-1 focus-visible:outline-primary-strong focus-visible:ring-4 focus-visible:ring-primary-weak',\n 'data-[state=open]:text-text-positive-muted data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak',\n _showClear && 'pr-8',\n !field.state.value && 'text-text-positive-muted',\n _invalid && 'outline-danger bg-danger-bg-subtle ring-4 ring-danger-weak'\n )}\n onClick={onClick}\n >\n {selectedLabel ? (\n <p className=\"flex min-w-0 flex-1 items-center gap-2 truncate text-start\">{selectedLabel}</p>\n ) : (\n <p className=\"flex-1 text-start text-text-positive-muted\">{placeholder}</p>\n )}\n </Button>\n );\n\n const renderCommandList = (onSelect: (value: string) => void) => (\n <Command className=\"border-none\">\n <CommandInput placeholder={placeholder ?? 'Tìm kiếm…'} />\n <CommandList>\n <CommandEmpty className=\"flex min-h-30 items-center justify-center text-sm text-text-positive-weak\">Không tìm thấy kết quả nào phù hợp.</CommandEmpty>\n <CommandGroup className=\"max-h-60 overflow-y-auto\">\n {options.map(({ value, label: optLabel }) => (\n <CommandItem key={value} value={optLabel} onSelect={() => onSelect(value)}>\n {optLabel}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n );\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation={orientation} data-invalid={_invalid}>\n <FieldContent>\n <FieldLabel aria-required={_isEmpty} htmlFor={field.name}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n\n <FieldContentMain className=\"flex justify-end\">\n <div className=\"flex w-full flex-col\">\n <div className=\"relative\">\n {isMobile ? (\n <>\n {triggerButton(() => setDialogOpen(true))}\n <Dialog\n open={dialogOpen}\n onOpenChange={open => {\n setDialogOpen(open);\n if (!open) field.handleBlur();\n }}\n >\n <DialogPortal>\n <DialogOverlay />\n <RadixDialog.Content\n onOpenAutoFocus={e => e.preventDefault()}\n className={cn(\n 'fixed inset-x-0 bottom-0 z-50',\n 'flex flex-col bg-background rounded-t-2xl outline-none',\n 'max-h-[80dvh] shadow-[0_-4px_24px_rgba(0,0,0,0.08)]',\n 'data-[state=open]:animate-in data-[state=open]:slide-in-from-bottom data-[state=open]:fade-in-0',\n 'data-[state=closed]:animate-out data-[state=closed]:slide-out-to-bottom data-[state=closed]:fade-out-0',\n 'duration-300'\n )}\n >\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border shrink-0\">\n <span className=\"font-semibold text-sm text-text-positive\">{label}</span>\n <DialogClose asChild>\n <button\n type=\"button\"\n aria-label=\"Đóng\"\n className=\"flex size-7 items-center justify-center rounded-md text-text-positive-weak transition-colors hover:bg-muted-muted hover:text-text-positive\"\n >\n <XIcon size={16} />\n </button>\n </DialogClose>\n </div>\n\n <div className=\"flex flex-col overflow-y-auto\">\n {_showClear && (\n <DialogClose asChild>\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-x-2 px-4 py-3 text-left text-sm text-danger-strong transition-colors hover:bg-danger-bg-subtle\"\n onClick={onClear}\n >\n <XIcon size={14} />\n Xóa lựa chọn\n </button>\n </DialogClose>\n )}\n {renderCommandList(value => {\n field.handleChange(value);\n setDialogOpen(false);\n field.handleBlur();\n })}\n </div>\n\n <div className=\"shrink-0 h-safe-bottom\" />\n </RadixDialog.Content>\n </DialogPortal>\n </Dialog>\n </>\n ) : (\n <Popover\n open={popoverOpen}\n modal={modal}\n onOpenChange={open => {\n setPopoverOpen(open);\n if (!open) field.handleBlur();\n }}\n >\n <PopoverTrigger asChild>{triggerButton()}</PopoverTrigger>\n <PopoverContent align=\"end\" side=\"bottom\" className=\"flex w-fit rounded p-0\">\n {renderCommandList(value => {\n field.handleChange(value);\n setPopoverOpen(false);\n field.handleBlur();\n })}\n </PopoverContent>\n </Popover>\n )}\n\n {_showClear && (\n <button\n type=\"button\"\n aria-label=\"Xóa lựa chọn\"\n className=\"absolute right-2 top-1/2 -translate-y-1/2 flex size-4 cursor-pointer items-center justify-center rounded-md text-text-positive-weak outline-none transition-[color,transform] hover:text-text-positive focus-visible:text-primary-strong focus-visible:[&>svg]:scale-125 [&>svg]:size-3.5 [&>svg]:transition-transform\"\n onClick={onClear}\n >\n <XIcon aria-hidden=\"true\" />\n </button>\n )}\n </div>\n\n {_touched && showErrorMessage && _hasErrors && <FieldError id={errorId} className=\"mt-1\" errors={field.state.meta.errors} />}\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </div>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n }\n);\n\nComboboxField.displayName = 'ComboboxField';\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../rolldown-runtime-
|
|
1
|
+
"use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../rolldown-runtime-DWNI8pZO.cjs"),t=require("../typography/paragraph.cjs"),n=require("../layouts/flex.cjs");let r=require("react"),i=require("react/jsx-runtime"),a=require("react-country-flag");a=e.n(a,1);const o={Vietnam:`VN`,USA:`US`,Japan:`JP`,China:`CN`,Korea:`KR`,Singapore:`SG`,Malaysia:`MY`,Indonesia:`ID`,Taiwan:`TW`,Thailand:`TH`},s={Vietnam:`Vietnam`,USA:`America`,Japan:`Japan`,China:`China`,Korea:`Korea`,Singapore:`Singapore`,Malaysia:`Malaysia`,Indonesia:`Indonesia`,Taiwan:`Taiwan`,Thailand:`Thailand`},c=({country:e})=>{let c=(0,r.useMemo)(()=>e?o[e]:`VN`,[e]);return e?(0,i.jsxs)(n.Flex,{"data-slot":`country-display`,padding:`none`,className:`px-1`,children:[(0,i.jsx)(a.default,{svg:!0,countryCode:c,className:`emojiFlag border`}),(0,i.jsx)(t.Paragraph,{variant:`sm`,children:s[e]})]}):(0,i.jsx)(n.Flex,{"data-slot":`country-display`,padding:`none`,className:`px-1`,children:(0,i.jsx)(t.Paragraph,{variant:`muted`,className:`line-clamp-1 text-xs`,children:`No country`})})};exports.CountryDisplay=c;
|
|
2
2
|
//# sourceMappingURL=country.cjs.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{$ as e,G as t,J as n,K as r,X as i,Y as a,Z as o,et as s,nt as c,q as l,rt as u}from"./tanstack-form-BhKAn9I0.mjs";import{Button as d}from"./ui/button.mjs";import{Popover as f,PopoverContent as p,PopoverTrigger as m}from"./ui/popover.mjs";import{Calendar as h}from"./ui/calendar.mjs";import{CalendarDaysIcon as g}from"lucide-react";import{memo as _,useId as v,useState as y}from"react";import{cn as b}from"@customafk/react-toolkit/utils";import{jsx as x,jsxs as S}from"react/jsx-runtime";import{endOfToday as C,endOfTomorrow as w,endOfYesterday as T,format as E,lastDayOfMonth as D,startOfMonth as O,subDays as k}from"@customafk/react-toolkit/date-fns";import{useStore as A}from"@tanstack/react-form";const j=_(({label:_,description:j,placeholder:M,orientation:N=`responsive`,tooltip:P,helperText:F,showErrorMessage:I=!0,required:L=!1,disabled:R=!1,minDate:z,maxDate:B})=>{let V=v(),H=u(),[U,W]=y(!1),G=A(H.form.store,({isSubmitting:e})=>e),K=R||G,q=H.state.meta.isDirty||H.state.meta.isTouched,J=q&&!H.state.meta.isValid,Y=L&&H.state.value===null,X=q&&H.state.meta.errors.length>0,Z=e=>{H.handleChange(e),W(!1)};return S(i,{className:`px-4`,children:[S(t,{orientation:N,"data-invalid":J,children:[S(r,{children:[S(o,{htmlFor:H.name,"aria-required":Y,children:[_,P&&x(c,{tooltip:P})]}),x(n,{children:j})]}),x(l,{className:`flex flex-col space-y-1`,children:S(`div`,{className:`flex w-full flex-col`,children:[S(f,{open:U,onOpenChange:e=>{W(e),e||H.handleBlur()},children:[x(m,{asChild:!0,children:S(d,{variant:`outline`,color:`muted`,size:`lg`,disabled:K,"aria-invalid":J?!0:void 0,"aria-describedby":V,className:b(`flex items-center justify-between rounded font-normal outline-border`,`hover:bg-transparent`,`focus:outline-1 focus:outline-primary-strong focus:ring-4 focus:ring-primary-weak`,`data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak`,H.state.value===null&&`text-text-positive-muted`,J&&`outline-danger bg-danger-bg-subtle ring-4 ring-danger-weak`),children:[x(`p`,{children:H.state.value===null?M??`Select date`:E(H.state.value,`PPPP`)}),x(g,{strokeWidth:1})]})}),S(p,{align:`start`,side:`bottom`,className:`flex w-fit min-w-0 overflow-y-auto rounded p-0`,children:[S(`div`,{className:`flex h-full flex-col space-y-2 border-r border-r-border p-2 [&>button]:justify-start [&>button]:text-sm`,children:[x(d,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>Z(C()),children:`Hôm nay`}),x(d,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>Z(w()),children:`Ngày mai`}),x(d,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>Z(T()),children:`Hôm qua`}),x(d,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>Z(k(C(),3)),children:`3 ngày qua`}),x(d,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>Z(k(C(),7)),children:`7 ngày qua`}),x(d,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>Z(k(C(),30)),children:`30 ngày qua`}),x(d,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>Z(O(C())),children:`Tháng này`}),x(d,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>Z(D(C())),children:`Tháng trước`})]}),x(`div`,{className:`flex flex-1 flex-col`,children:x(`div`,{className:`min-w-73 border-b border-b-border p-2`,children:x(h,{mode:`single`,selected:H.state.value??void 0,hidden:{before:z??new Date(1900,0,1),after:B??new Date(2100,11,31)},onSelect:e=>{e&&Z(e)}})})})]})]}),q&&I&&X&&x(a,{id:V,className:`mt-1`,errors:H.state.meta.errors}),x(e,{isShow:!!F,children:F})]})})]}),x(s,{})]})});j.displayName=`DateField`;export{j as DateField};
|
|
2
|
+
//# sourceMappingURL=date-field-CNkxebta.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-field-
|
|
1
|
+
{"version":3,"file":"date-field-CNkxebta.mjs","names":[],"sources":["../packages/components/features/tanstack-form/components/fields/date-field.tsx"],"sourcesContent":["'use client';\n\nimport { memo, useId, useState } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { CalendarDaysIcon } from 'lucide-react';\n\nimport { endOfToday, endOfTomorrow, endOfYesterday, format, lastDayOfMonth, startOfMonth, subDays } from '@customafk/react-toolkit/date-fns';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Calendar } from '@/components/ui/calendar';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\n\nimport { useTanStackFieldContext } from '../form-context';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\n\nimport type { DateFieldProps as Props } from '../../types';\n\nexport const DateField = memo<Props>(\n ({\n label,\n description,\n placeholder,\n orientation = 'responsive',\n tooltip,\n helperText,\n showErrorMessage = true,\n required = false,\n disabled = false,\n minDate,\n maxDate,\n }) => {\n const errorId = useId();\n const field = useTanStackFieldContext<Date | null>();\n const [popoverOpen, setPopoverOpen] = useState(false);\n\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n const isDisabled = disabled || isSubmitting;\n\n const _touched = field.state.meta.isDirty || field.state.meta.isTouched;\n const _isInvalid = _touched && !field.state.meta.isValid;\n const _isEmpty = required && field.state.value === null;\n const _hasError = _touched && field.state.meta.errors.length > 0;\n\n const handleSelect = (date: Date) => {\n field.handleChange(date);\n setPopoverOpen(false);\n };\n\n return (\n <FieldGroup className=\"px-4\">\n <Field orientation={orientation} data-invalid={_isInvalid}>\n <FieldContent>\n <FieldLabel htmlFor={field.name} aria-required={_isEmpty}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n\n <FieldContentMain className=\"flex flex-col space-y-1\">\n <div className=\"flex w-full flex-col\">\n <Popover\n open={popoverOpen}\n onOpenChange={open => {\n setPopoverOpen(open);\n if (!open) field.handleBlur();\n }}\n >\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n color=\"muted\"\n size=\"lg\"\n disabled={isDisabled}\n aria-invalid={_isInvalid ? true : undefined}\n aria-describedby={errorId}\n className={cn(\n 'flex items-center justify-between rounded font-normal outline-border',\n 'hover:bg-transparent',\n 'focus:outline-1 focus:outline-primary-strong focus:ring-4 focus:ring-primary-weak',\n 'data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak',\n field.state.value === null && 'text-text-positive-muted',\n _isInvalid && 'outline-danger bg-danger-bg-subtle ring-4 ring-danger-weak'\n )}\n >\n <p>{field.state.value === null ? (placeholder ?? 'Select date') : format(field.state.value, 'PPPP')}</p>\n <CalendarDaysIcon strokeWidth={1} />\n </Button>\n </PopoverTrigger>\n\n <PopoverContent align=\"start\" side=\"bottom\" className=\"flex w-fit min-w-0 overflow-y-auto rounded p-0\">\n <div className=\"flex h-full flex-col space-y-2 border-r border-r-border p-2 [&>button]:justify-start [&>button]:text-sm\">\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(endOfToday())}>\n Hôm nay\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(endOfTomorrow())}>\n Ngày mai\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(endOfYesterday())}>\n Hôm qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(subDays(endOfToday(), 3))}>\n 3 ngày qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(subDays(endOfToday(), 7))}>\n 7 ngày qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(subDays(endOfToday(), 30))}>\n 30 ngày qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(startOfMonth(endOfToday()))}>\n Tháng này\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(lastDayOfMonth(endOfToday()))}>\n Tháng trước\n </Button>\n </div>\n <div className=\"flex flex-1 flex-col\">\n <div className=\"min-w-73 border-b border-b-border p-2\">\n <Calendar\n mode=\"single\"\n selected={field.state.value ?? undefined}\n hidden={{\n before: minDate ?? new Date(1900, 0, 1),\n after: maxDate ?? new Date(2100, 11, 31),\n }}\n onSelect={date => {\n if (!date) return;\n handleSelect(date);\n }}\n />\n </div>\n </div>\n </PopoverContent>\n </Popover>\n\n {_touched && showErrorMessage && _hasError && <FieldError id={errorId} className=\"mt-1\" errors={field.state.meta.errors} />}\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </div>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n }\n);\n\nDateField.displayName = 'DateField';\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("./ui/button.cjs"),t=require("./ui/popover.cjs"),n=require("./tanstack-form-DCB2addt.cjs"),r=require("./ui/calendar.cjs");let i=require("lucide-react"),a=require("react"),o=require("@customafk/react-toolkit/utils"),s=require("react/jsx-runtime"),c=require("@customafk/react-toolkit/date-fns"),l=require("@tanstack/react-form");const u=(0,a.memo)(({label:u,description:d,placeholder:f,orientation:p=`responsive`,tooltip:m,helperText:h,showErrorMessage:g=!0,required:_=!1,disabled:v=!1,minDate:y,maxDate:b})=>{let x=(0,a.useId)(),S=n.rt(),[C,w]=(0,a.useState)(!1),T=(0,l.useStore)(S.form.store,({isSubmitting:e})=>e),E=v||T,D=S.state.meta.isDirty||S.state.meta.isTouched,O=D&&!S.state.meta.isValid,k=_&&S.state.value===null,A=D&&S.state.meta.errors.length>0,j=e=>{S.handleChange(e),w(!1)};return(0,s.jsxs)(n.X,{className:`px-4`,children:[(0,s.jsxs)(n.G,{orientation:p,"data-invalid":O,children:[(0,s.jsxs)(n.K,{children:[(0,s.jsxs)(n.Z,{htmlFor:S.name,"aria-required":k,children:[u,m&&(0,s.jsx)(n.nt,{tooltip:m})]}),(0,s.jsx)(n.J,{children:d})]}),(0,s.jsx)(n.q,{className:`flex flex-col space-y-1`,children:(0,s.jsxs)(`div`,{className:`flex w-full flex-col`,children:[(0,s.jsxs)(t.Popover,{open:C,onOpenChange:e=>{w(e),e||S.handleBlur()},children:[(0,s.jsx)(t.PopoverTrigger,{asChild:!0,children:(0,s.jsxs)(e.Button,{variant:`outline`,color:`muted`,size:`lg`,disabled:E,"aria-invalid":O?!0:void 0,"aria-describedby":x,className:(0,o.cn)(`flex items-center justify-between rounded font-normal outline-border`,`hover:bg-transparent`,`focus:outline-1 focus:outline-primary-strong focus:ring-4 focus:ring-primary-weak`,`data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak`,S.state.value===null&&`text-text-positive-muted`,O&&`outline-danger bg-danger-bg-subtle ring-4 ring-danger-weak`),children:[(0,s.jsx)(`p`,{children:S.state.value===null?f??`Select date`:(0,c.format)(S.state.value,`PPPP`)}),(0,s.jsx)(i.CalendarDaysIcon,{strokeWidth:1})]})}),(0,s.jsxs)(t.PopoverContent,{align:`start`,side:`bottom`,className:`flex w-fit min-w-0 overflow-y-auto rounded p-0`,children:[(0,s.jsxs)(`div`,{className:`flex h-full flex-col space-y-2 border-r border-r-border p-2 [&>button]:justify-start [&>button]:text-sm`,children:[(0,s.jsx)(e.Button,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>j((0,c.endOfToday)()),children:`Hôm nay`}),(0,s.jsx)(e.Button,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>j((0,c.endOfTomorrow)()),children:`Ngày mai`}),(0,s.jsx)(e.Button,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>j((0,c.endOfYesterday)()),children:`Hôm qua`}),(0,s.jsx)(e.Button,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>j((0,c.subDays)((0,c.endOfToday)(),3)),children:`3 ngày qua`}),(0,s.jsx)(e.Button,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>j((0,c.subDays)((0,c.endOfToday)(),7)),children:`7 ngày qua`}),(0,s.jsx)(e.Button,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>j((0,c.subDays)((0,c.endOfToday)(),30)),children:`30 ngày qua`}),(0,s.jsx)(e.Button,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>j((0,c.startOfMonth)((0,c.endOfToday)())),children:`Tháng này`}),(0,s.jsx)(e.Button,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>j((0,c.lastDayOfMonth)((0,c.endOfToday)())),children:`Tháng trước`})]}),(0,s.jsx)(`div`,{className:`flex flex-1 flex-col`,children:(0,s.jsx)(`div`,{className:`min-w-73 border-b border-b-border p-2`,children:(0,s.jsx)(r.Calendar,{mode:`single`,selected:S.state.value??void 0,hidden:{before:y??new Date(1900,0,1),after:b??new Date(2100,11,31)},onSelect:e=>{e&&j(e)}})})})]})]}),D&&g&&A&&(0,s.jsx)(n.Y,{id:x,className:`mt-1`,errors:S.state.meta.errors}),(0,s.jsx)(n.$,{isShow:!!h,children:h})]})})]}),(0,s.jsx)(n.et,{})]})});u.displayName=`DateField`,exports.DateField=u;
|
|
2
|
+
//# sourceMappingURL=date-field-Dm367ro9.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-field-1Hmcv8Zp.cjs","names":["useTanStackFieldContext","FieldGroup","Field","FieldContent","FieldLabel","FieldTooltip","FieldDescription","FieldContentMain","Popover","PopoverTrigger","Button","CalendarDaysIcon","PopoverContent","Calendar","FieldError","FieldNote","FieldSeparator"],"sources":["../packages/components/features/tanstack-form/components/fields/date-field.tsx"],"sourcesContent":["'use client';\n\nimport { memo, useId, useState } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { CalendarDaysIcon } from 'lucide-react';\n\nimport { endOfToday, endOfTomorrow, endOfYesterday, format, lastDayOfMonth, startOfMonth, subDays } from '@customafk/react-toolkit/date-fns';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Calendar } from '@/components/ui/calendar';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\n\nimport { useTanStackFieldContext } from '../form-context';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\n\nimport type { DateFieldProps as Props } from '../../types';\n\nexport const DateField = memo<Props>(\n ({\n label,\n description,\n placeholder,\n orientation = 'responsive',\n tooltip,\n helperText,\n showErrorMessage = true,\n required = false,\n disabled = false,\n minDate,\n maxDate,\n }) => {\n const errorId = useId();\n const field = useTanStackFieldContext<Date | null>();\n const [popoverOpen, setPopoverOpen] = useState(false);\n\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n const isDisabled = disabled || isSubmitting;\n\n const _touched = field.state.meta.isDirty || field.state.meta.isTouched;\n const _isInvalid = _touched && !field.state.meta.isValid;\n const _isEmpty = required && field.state.value === null;\n const _hasError = _touched && field.state.meta.errors.length > 0;\n\n const handleSelect = (date: Date) => {\n field.handleChange(date);\n setPopoverOpen(false);\n };\n\n return (\n <FieldGroup className=\"px-4\">\n <Field orientation={orientation} data-invalid={_isInvalid}>\n <FieldContent>\n <FieldLabel htmlFor={field.name} aria-required={_isEmpty}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n\n <FieldContentMain className=\"flex flex-col space-y-1\">\n <div className=\"flex w-full flex-col\">\n <Popover\n open={popoverOpen}\n onOpenChange={open => {\n setPopoverOpen(open);\n if (!open) field.handleBlur();\n }}\n >\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n color=\"muted\"\n size=\"lg\"\n disabled={isDisabled}\n aria-invalid={_isInvalid ? true : undefined}\n aria-describedby={errorId}\n className={cn(\n 'flex items-center justify-between rounded font-normal outline-border',\n 'hover:bg-transparent',\n 'focus:outline-1 focus:outline-primary-strong focus:ring-4 focus:ring-primary-weak',\n 'data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak',\n field.state.value === null && 'text-text-positive-muted',\n _isInvalid && 'outline-danger bg-danger-bg-subtle ring-4 ring-danger-weak'\n )}\n >\n <p>{field.state.value === null ? (placeholder ?? 'Select date') : format(field.state.value, 'PPPP')}</p>\n <CalendarDaysIcon strokeWidth={1} />\n </Button>\n </PopoverTrigger>\n\n <PopoverContent align=\"start\" side=\"bottom\" className=\"flex w-fit min-w-0 overflow-y-auto rounded p-0\">\n <div className=\"flex h-full flex-col space-y-2 border-r border-r-border p-2 [&>button]:justify-start [&>button]:text-sm\">\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(endOfToday())}>\n Hôm nay\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(endOfTomorrow())}>\n Ngày mai\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(endOfYesterday())}>\n Hôm qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(subDays(endOfToday(), 3))}>\n 3 ngày qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(subDays(endOfToday(), 7))}>\n 7 ngày qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(subDays(endOfToday(), 30))}>\n 30 ngày qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(startOfMonth(endOfToday()))}>\n Tháng này\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(lastDayOfMonth(endOfToday()))}>\n Tháng trước\n </Button>\n </div>\n <div className=\"flex flex-1 flex-col\">\n <div className=\"min-w-73 border-b border-b-border p-2\">\n <Calendar\n mode=\"single\"\n selected={field.state.value ?? undefined}\n hidden={{\n before: minDate ?? new Date(1900, 0, 1),\n after: maxDate ?? new Date(2100, 11, 31),\n }}\n onSelect={date => {\n if (!date) return;\n handleSelect(date);\n }}\n />\n </div>\n </div>\n </PopoverContent>\n </Popover>\n\n {_touched && showErrorMessage && _hasError && <FieldError id={errorId} className=\"mt-1\" errors={field.state.meta.errors} />}\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </div>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n }\n);\n\nDateField.displayName = 'DateField';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"date-field-Dm367ro9.cjs","names":["useTanStackFieldContext","FieldGroup","Field","FieldContent","FieldLabel","FieldTooltip","FieldDescription","FieldContentMain","Popover","PopoverTrigger","Button","CalendarDaysIcon","PopoverContent","Calendar","FieldError","FieldNote","FieldSeparator"],"sources":["../packages/components/features/tanstack-form/components/fields/date-field.tsx"],"sourcesContent":["'use client';\n\nimport { memo, useId, useState } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { CalendarDaysIcon } from 'lucide-react';\n\nimport { endOfToday, endOfTomorrow, endOfYesterday, format, lastDayOfMonth, startOfMonth, subDays } from '@customafk/react-toolkit/date-fns';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Calendar } from '@/components/ui/calendar';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\n\nimport { useTanStackFieldContext } from '../form-context';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\n\nimport type { DateFieldProps as Props } from '../../types';\n\nexport const DateField = memo<Props>(\n ({\n label,\n description,\n placeholder,\n orientation = 'responsive',\n tooltip,\n helperText,\n showErrorMessage = true,\n required = false,\n disabled = false,\n minDate,\n maxDate,\n }) => {\n const errorId = useId();\n const field = useTanStackFieldContext<Date | null>();\n const [popoverOpen, setPopoverOpen] = useState(false);\n\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n const isDisabled = disabled || isSubmitting;\n\n const _touched = field.state.meta.isDirty || field.state.meta.isTouched;\n const _isInvalid = _touched && !field.state.meta.isValid;\n const _isEmpty = required && field.state.value === null;\n const _hasError = _touched && field.state.meta.errors.length > 0;\n\n const handleSelect = (date: Date) => {\n field.handleChange(date);\n setPopoverOpen(false);\n };\n\n return (\n <FieldGroup className=\"px-4\">\n <Field orientation={orientation} data-invalid={_isInvalid}>\n <FieldContent>\n <FieldLabel htmlFor={field.name} aria-required={_isEmpty}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n\n <FieldContentMain className=\"flex flex-col space-y-1\">\n <div className=\"flex w-full flex-col\">\n <Popover\n open={popoverOpen}\n onOpenChange={open => {\n setPopoverOpen(open);\n if (!open) field.handleBlur();\n }}\n >\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n color=\"muted\"\n size=\"lg\"\n disabled={isDisabled}\n aria-invalid={_isInvalid ? true : undefined}\n aria-describedby={errorId}\n className={cn(\n 'flex items-center justify-between rounded font-normal outline-border',\n 'hover:bg-transparent',\n 'focus:outline-1 focus:outline-primary-strong focus:ring-4 focus:ring-primary-weak',\n 'data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak',\n field.state.value === null && 'text-text-positive-muted',\n _isInvalid && 'outline-danger bg-danger-bg-subtle ring-4 ring-danger-weak'\n )}\n >\n <p>{field.state.value === null ? (placeholder ?? 'Select date') : format(field.state.value, 'PPPP')}</p>\n <CalendarDaysIcon strokeWidth={1} />\n </Button>\n </PopoverTrigger>\n\n <PopoverContent align=\"start\" side=\"bottom\" className=\"flex w-fit min-w-0 overflow-y-auto rounded p-0\">\n <div className=\"flex h-full flex-col space-y-2 border-r border-r-border p-2 [&>button]:justify-start [&>button]:text-sm\">\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(endOfToday())}>\n Hôm nay\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(endOfTomorrow())}>\n Ngày mai\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(endOfYesterday())}>\n Hôm qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(subDays(endOfToday(), 3))}>\n 3 ngày qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(subDays(endOfToday(), 7))}>\n 7 ngày qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(subDays(endOfToday(), 30))}>\n 30 ngày qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(startOfMonth(endOfToday()))}>\n Tháng này\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(lastDayOfMonth(endOfToday()))}>\n Tháng trước\n </Button>\n </div>\n <div className=\"flex flex-1 flex-col\">\n <div className=\"min-w-73 border-b border-b-border p-2\">\n <Calendar\n mode=\"single\"\n selected={field.state.value ?? undefined}\n hidden={{\n before: minDate ?? new Date(1900, 0, 1),\n after: maxDate ?? new Date(2100, 11, 31),\n }}\n onSelect={date => {\n if (!date) return;\n handleSelect(date);\n }}\n />\n </div>\n </div>\n </PopoverContent>\n </Popover>\n\n {_touched && showErrorMessage && _hasError && <FieldError id={errorId} className=\"mt-1\" errors={field.state.meta.errors} />}\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </div>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n }\n);\n\nDateField.displayName = 'DateField';\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("./ui/dialog.cjs"),t=require("./tanstack-form-DCB2addt.cjs"),n=require("./ui/separator.cjs"),r=require("./submit-button-CvINfld5.cjs");let i=require("react"),a=require("@customafk/react-toolkit/utils"),o=require("react/jsx-runtime");const s=({title:s,submitText:c,width:l,maxWidth:u,className:d,open:f,onOpenChange:p,children:m})=>{let h=t.it(),g=(0,i.useCallback)(e=>{e||h.reset(),p?.(e)},[h.reset,p]);return(0,o.jsx)(e.Dialog,{open:f,onOpenChange:g,children:(0,o.jsxs)(e.DialogPortal,{"data-slot":`dialog-portal`,children:[(0,o.jsx)(e.DialogOverlay,{}),(0,o.jsxs)(e.DialogContent,{style:{"--width":l,"--max-width":u},className:(0,a.cn)(`flex size-full max-h-dvh max-w-dvw flex-col gap-0 overflow-y-auto rounded-none p-0 shadow-dialog sm:h-auto sm:max-h-[85dvh] sm:max-w-5xl sm:rounded-md`,l&&`sm:w-(--width)`,u&&`sm:max-w-(--max-width)`,d),onOpenAutoFocus:e=>{e.preventDefault()},onInteractOutside:e=>{e.preventDefault()},children:[(0,o.jsx)(`div`,{"data-slot":`dialog-header`,className:`flex items-center justify-center gap-2 px-6 py-5 text-center sm:text-left`,children:(0,o.jsx)(e.DialogTitle,{"data-slot":`dialog-title`,className:`font-semibold text-lg tracking-tight`,children:s})}),(0,o.jsx)(n.Separator,{}),(0,o.jsx)(`div`,{"data-slot":`dialog-content`,className:`relative flex flex-col overflow-y-auto p-0 pt-4 max-sm:flex-1 sm:p-4`,children:m}),(0,o.jsx)(n.Separator,{}),(0,o.jsxs)(`div`,{"data-slot":`dialog-footer`,className:`flex flex-col-reverse items-center justify-end gap-2 px-6 py-4 sm:flex-row max-sm:[&>button]:w-full`,children:[(0,o.jsx)(h.Subscribe,{selector:e=>({disabled:e.isSubmitting}),children:({disabled:e})=>(0,o.jsx)(r.n,{disabled:e,onClick:()=>{h.reset(),g(!1)}})}),(0,o.jsx)(h.Subscribe,{selector:e=>({isSubmitting:e.isSubmitting,disabled:e.isPristine||!e.isValid||e.isValidating||e.isSubmitting||!e.canSubmit}),children:({isSubmitting:e,disabled:t})=>(0,o.jsx)(r.t,{isSubmitting:e,disabled:t,submitText:c,onClick:()=>h.handleSubmit()})})]})]})]})})};exports.TanStackDialogForm=s;
|
|
2
|
+
//# sourceMappingURL=dialog-form-D9Bifsx6.cjs.map
|