@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.
Files changed (262) hide show
  1. package/dist/LoginPage-DGgThT3s.mjs +2 -0
  2. package/dist/LoginPage-DGgThT3s.mjs.map +1 -0
  3. package/dist/LoginPage-DPUdRD0r.cjs +2 -0
  4. package/dist/LoginPage-DPUdRD0r.cjs.map +1 -0
  5. package/dist/action-submit-B2qFdfi6.cjs +2 -0
  6. package/dist/{action-submit-B9vHpLoN.cjs.map → action-submit-B2qFdfi6.cjs.map} +1 -1
  7. package/dist/action-submit-DyNvI-F2.mjs +2 -0
  8. package/dist/{action-submit-BQdkz4mS.mjs.map → action-submit-DyNvI-F2.mjs.map} +1 -1
  9. package/dist/actions-form-CB0lZlE6.mjs +2 -0
  10. package/dist/{actions-form-D4n1W3-X.mjs.map → actions-form-CB0lZlE6.mjs.map} +1 -1
  11. package/dist/actions-form-DnlpVrgF.cjs +2 -0
  12. package/dist/{actions-form-DF2eYxGQ.cjs.map → actions-form-DnlpVrgF.cjs.map} +1 -1
  13. package/dist/checkbox-field-CFPHAcwN.cjs +2 -0
  14. package/dist/{checkbox-field-ldZRSCca.cjs.map → checkbox-field-CFPHAcwN.cjs.map} +1 -1
  15. package/dist/checkbox-field-DodKeFS_.mjs +2 -0
  16. package/dist/{checkbox-field-BRGTLOjq.mjs.map → checkbox-field-DodKeFS_.mjs.map} +1 -1
  17. package/dist/{cms-layout-BGsf1E4E.cjs → cms-layout-DYEmSqzx.cjs} +2 -2
  18. package/dist/{cms-layout-BGsf1E4E.cjs.map → cms-layout-DYEmSqzx.cjs.map} +1 -1
  19. package/dist/combobox-field-D7cZ8fhZ.cjs +2 -0
  20. package/dist/{combobox-field-ZYr7636s.cjs.map → combobox-field-D7cZ8fhZ.cjs.map} +1 -1
  21. package/dist/combobox-field-ebIvbhJn.mjs +2 -0
  22. package/dist/{combobox-field-CvkdZkQE.mjs.map → combobox-field-ebIvbhJn.mjs.map} +1 -1
  23. package/dist/data-display/country.cjs +1 -1
  24. package/dist/date-field-CNkxebta.mjs +2 -0
  25. package/dist/{date-field-DGMTG_hu.mjs.map → date-field-CNkxebta.mjs.map} +1 -1
  26. package/dist/date-field-Dm367ro9.cjs +2 -0
  27. package/dist/{date-field-1Hmcv8Zp.cjs.map → date-field-Dm367ro9.cjs.map} +1 -1
  28. package/dist/dialog-form-D9Bifsx6.cjs +2 -0
  29. package/dist/{dialog-form-C1qpltYx.cjs.map → dialog-form-D9Bifsx6.cjs.map} +1 -1
  30. package/dist/dialog-form-zK6Gk9Gk.mjs +2 -0
  31. package/dist/{dialog-form-BRSZpRTC.mjs.map → dialog-form-zK6Gk9Gk.mjs.map} +1 -1
  32. package/dist/{dist-DzA--RwW.cjs → dist-CIdWHwhj.cjs} +2 -2
  33. package/dist/{dist-DzA--RwW.cjs.map → dist-CIdWHwhj.cjs.map} +1 -1
  34. package/dist/email-field-BVl7u9pR.mjs +2 -0
  35. package/dist/{email-field-C2Lvl_rQ.mjs.map → email-field-BVl7u9pR.mjs.map} +1 -1
  36. package/dist/email-field-CqXXRG3w.cjs +2 -0
  37. package/dist/{email-field-D3nSkHj2.cjs.map → email-field-CqXXRG3w.cjs.map} +1 -1
  38. package/dist/features/tables/index.d.cts +1 -1
  39. package/dist/features/tables/index.d.mts +1 -1
  40. package/dist/features/tanstack-form/index.cjs +1 -1
  41. package/dist/features/tanstack-form/index.d.cts +1 -1
  42. package/dist/features/tanstack-form/index.d.mts +1 -1
  43. package/dist/features/tanstack-form/index.mjs +1 -1
  44. package/dist/features/text-editor/index.cjs +1 -1
  45. package/dist/features/text-editor/index.d.cts +1 -1
  46. package/dist/features/text-editor/index.d.mts +1 -1
  47. package/dist/features/text-editor/index.mjs +1 -1
  48. package/dist/{flex-C63_IqSY.d.cts → flex-D6RCsrv1.d.cts} +2 -2
  49. package/dist/{flex-C63_IqSY.d.mts → flex-D6RCsrv1.d.mts} +2 -2
  50. package/dist/group-field-8nINgAeO.mjs +2 -0
  51. package/dist/{group-field-gejvx_Td.mjs.map → group-field-8nINgAeO.mjs.map} +1 -1
  52. package/dist/group-field-DfGPDLyp.cjs +2 -0
  53. package/dist/{group-field-sVykO2JZ.cjs.map → group-field-DfGPDLyp.cjs.map} +1 -1
  54. package/dist/{index-DvC1inRy.d.cts → index-0HuXxgjQ.d.cts} +13 -10
  55. package/dist/index-6_zytlWu.d.cts +70 -0
  56. package/dist/index-6_zytlWu.d.mts +70 -0
  57. package/dist/{index-CrkOhm--.d.mts → index-BCBEYTyA.d.mts} +5 -5
  58. package/dist/{index--wNkNzCB.d.cts → index-CQPyC0Q2.d.cts} +5 -5
  59. package/dist/{index-DvC1inRy.d.mts → index-CZ_2KVir.d.mts} +13 -10
  60. package/dist/{index-DRAyYm8g.d.mts → index-CvFEJoon.d.cts} +12 -3
  61. package/dist/{index-DRAyYm8g.d.cts → index-CvFEJoon.d.mts} +12 -3
  62. package/dist/index.cjs +1 -1
  63. package/dist/index.d.cts +6 -6
  64. package/dist/index.d.mts +6 -6
  65. package/dist/index.mjs +1 -1
  66. package/dist/layouts/cms-layout/index.cjs +1 -1
  67. package/dist/layouts/flex.d.cts +1 -1
  68. package/dist/layouts/flex.d.mts +1 -1
  69. package/dist/layouts/payment-layout/index.cjs +1 -1
  70. package/dist/number-field-BjGl_IiN.cjs +2 -0
  71. package/dist/{number-field-CWDYA3La.cjs.map → number-field-BjGl_IiN.cjs.map} +1 -1
  72. package/dist/number-field-CVemIwIg.mjs +2 -0
  73. package/dist/{number-field-CR5PLX6H.mjs.map → number-field-CVemIwIg.mjs.map} +1 -1
  74. package/dist/pages/LoginPage/index.cjs +1 -0
  75. package/dist/pages/LoginPage/index.d.cts +2 -0
  76. package/dist/pages/LoginPage/index.d.mts +2 -0
  77. package/dist/pages/LoginPage/index.mjs +1 -0
  78. package/dist/password-field-Be0Ltlxh.cjs +2 -0
  79. package/dist/{password-field-BHRhVyZ0.cjs.map → password-field-Be0Ltlxh.cjs.map} +1 -1
  80. package/dist/password-field-BxYaT8lO.mjs +2 -0
  81. package/dist/{password-field-B2_kzss6.mjs.map → password-field-BxYaT8lO.mjs.map} +1 -1
  82. package/dist/{payment-layout-BZtIcu-3.cjs → payment-layout-C38xIc2X.cjs} +2 -2
  83. package/dist/{payment-layout-BZtIcu-3.cjs.map → payment-layout-C38xIc2X.cjs.map} +1 -1
  84. package/dist/popover-form-Ba_Nw79b.cjs +2 -0
  85. package/dist/{popover-form-Ch_iMMSm.cjs.map → popover-form-Ba_Nw79b.cjs.map} +1 -1
  86. package/dist/popover-form-C9mNInr2.mjs +2 -0
  87. package/dist/{popover-form-CeRVpy1B.mjs.map → popover-form-C9mNInr2.mjs.map} +1 -1
  88. package/dist/radio-group-field-BCJWamjd.cjs +2 -0
  89. package/dist/{radio-group-field-BFhBfzoT.cjs.map → radio-group-field-BCJWamjd.cjs.map} +1 -1
  90. package/dist/radio-group-field-DYqU_6hW.mjs +2 -0
  91. package/dist/{radio-group-field-Iwo2Q2Ig.mjs.map → radio-group-field-DYqU_6hW.mjs.map} +1 -1
  92. package/dist/{resizable-CNqPu4Ck.d.cts → resizable-DTnfCua-.d.cts} +2 -2
  93. package/dist/{resizable-CNqPu4Ck.d.mts → resizable-DTnfCua-.d.mts} +2 -2
  94. package/dist/rolldown-runtime-DWNI8pZO.cjs +1 -0
  95. package/dist/select-field-D7Ny2Qne.mjs +2 -0
  96. package/dist/{select-field-NJgDDCO2.mjs.map → select-field-D7Ny2Qne.mjs.map} +1 -1
  97. package/dist/select-field-UWnBMAzL.cjs +2 -0
  98. package/dist/{select-field-CvDBZQTl.cjs.map → select-field-UWnBMAzL.cjs.map} +1 -1
  99. package/dist/simple-array-field-BSMxRilE.cjs +2 -0
  100. package/dist/{simple-array-field-aGXkDZXD.cjs.map → simple-array-field-BSMxRilE.cjs.map} +1 -1
  101. package/dist/simple-array-field-DJXa_vST.mjs +2 -0
  102. package/dist/{simple-array-field-BwNCeUnn.mjs.map → simple-array-field-DJXa_vST.mjs.map} +1 -1
  103. package/dist/simple-boolean-field-CVNT8NBk.mjs +2 -0
  104. package/dist/{simple-boolean-field-t_XDXqYs.mjs.map → simple-boolean-field-CVNT8NBk.mjs.map} +1 -1
  105. package/dist/simple-boolean-field-CxAyVQ1w.cjs +2 -0
  106. package/dist/{simple-boolean-field-BeVkn3c4.cjs.map → simple-boolean-field-CxAyVQ1w.cjs.map} +1 -1
  107. package/dist/simple-combobox-field-BP4IeDkA.cjs +2 -0
  108. package/dist/{simple-combobox-field-U0ZAl7VQ.cjs.map → simple-combobox-field-BP4IeDkA.cjs.map} +1 -1
  109. package/dist/simple-combobox-field-BnAUDfQU.mjs +2 -0
  110. package/dist/{simple-combobox-field-HCB4A33-.mjs.map → simple-combobox-field-BnAUDfQU.mjs.map} +1 -1
  111. package/dist/simple-date-field-DIa6UBF2.mjs +2 -0
  112. package/dist/{simple-date-field-Dj4bJoji.mjs.map → simple-date-field-DIa6UBF2.mjs.map} +1 -1
  113. package/dist/simple-date-field-NSawlSff.cjs +2 -0
  114. package/dist/{simple-date-field-DtxEpEZj.cjs.map → simple-date-field-NSawlSff.cjs.map} +1 -1
  115. package/dist/simple-email-field-2Abh3qZw.cjs +2 -0
  116. package/dist/{simple-email-field-DK9I_Tc_.cjs.map → simple-email-field-2Abh3qZw.cjs.map} +1 -1
  117. package/dist/simple-email-field-CKDQgzh5.mjs +2 -0
  118. package/dist/{simple-email-field-BDyhkmHV.mjs.map → simple-email-field-CKDQgzh5.mjs.map} +1 -1
  119. package/dist/simple-number-field-BjEYE54F.cjs +2 -0
  120. package/dist/{simple-number-field-BspqWU-3.cjs.map → simple-number-field-BjEYE54F.cjs.map} +1 -1
  121. package/dist/simple-number-field-SDbxL6L7.mjs +2 -0
  122. package/dist/{simple-number-field-hneXMhfJ.mjs.map → simple-number-field-SDbxL6L7.mjs.map} +1 -1
  123. package/dist/simple-password-field-Cjp6yzWd.cjs +2 -0
  124. package/dist/{simple-password-field-BEEcleom.cjs.map → simple-password-field-Cjp6yzWd.cjs.map} +1 -1
  125. package/dist/simple-password-field-Cnj-hf5g.mjs +2 -0
  126. package/dist/{simple-password-field-vsLRHDk4.mjs.map → simple-password-field-Cnj-hf5g.mjs.map} +1 -1
  127. package/dist/simple-radio-group-field-4-eWSXY7.mjs +2 -0
  128. package/dist/{simple-radio-group-field-BURm_BSA.mjs.map → simple-radio-group-field-4-eWSXY7.mjs.map} +1 -1
  129. package/dist/simple-radio-group-field-CuA0Q-XI.cjs +2 -0
  130. package/dist/{simple-radio-group-field-Wm8xB0fN.cjs.map → simple-radio-group-field-CuA0Q-XI.cjs.map} +1 -1
  131. package/dist/simple-select-field-C0ecQx68.mjs +2 -0
  132. package/dist/{simple-select-field-8cY51U4d.mjs.map → simple-select-field-C0ecQx68.mjs.map} +1 -1
  133. package/dist/simple-select-field-CXYJcRY2.cjs +2 -0
  134. package/dist/{simple-select-field-QQ65caBf.cjs.map → simple-select-field-CXYJcRY2.cjs.map} +1 -1
  135. package/dist/simple-text-field-DJl5SIGn.mjs +2 -0
  136. package/dist/{simple-text-field-DK72_OA_.mjs.map → simple-text-field-DJl5SIGn.mjs.map} +1 -1
  137. package/dist/simple-text-field-DPXqNCXh.cjs +2 -0
  138. package/dist/{simple-text-field-BHkCPiE5.cjs.map → simple-text-field-DPXqNCXh.cjs.map} +1 -1
  139. package/dist/simple-textarea-field-BcHdUMTK.mjs +2 -0
  140. package/dist/{simple-textarea-field-B72nNQHv.mjs.map → simple-textarea-field-BcHdUMTK.mjs.map} +1 -1
  141. package/dist/simple-textarea-field-ZpXPwYz-.cjs +2 -0
  142. package/dist/{simple-textarea-field-Bu5h7sfH.cjs.map → simple-textarea-field-ZpXPwYz-.cjs.map} +1 -1
  143. package/dist/switch-field-CCDuDdpf.cjs +2 -0
  144. package/dist/{switch-field-eLVlQZSI.cjs.map → switch-field-CCDuDdpf.cjs.map} +1 -1
  145. package/dist/switch-field-DBGFsmEZ.mjs +2 -0
  146. package/dist/{switch-field-DoPUWb9d.mjs.map → switch-field-DBGFsmEZ.mjs.map} +1 -1
  147. package/dist/tanstack-form-BhKAn9I0.mjs +2 -0
  148. package/dist/tanstack-form-BhKAn9I0.mjs.map +1 -0
  149. package/dist/tanstack-form-DCB2addt.cjs +2 -0
  150. package/dist/tanstack-form-DCB2addt.cjs.map +1 -0
  151. package/dist/text-editor-DWZf3yrW.cjs +2 -0
  152. package/dist/text-editor-DWZf3yrW.cjs.map +1 -0
  153. package/dist/text-editor-XBOAwJk-.mjs +2 -0
  154. package/dist/text-editor-XBOAwJk-.mjs.map +1 -0
  155. package/dist/text-field-Bx_vnc4O.mjs +2 -0
  156. package/dist/{text-field-Bm-k6Jr7.mjs.map → text-field-Bx_vnc4O.mjs.map} +1 -1
  157. package/dist/text-field-DMZZ6CND.cjs +2 -0
  158. package/dist/{text-field-DT50dOVI.cjs.map → text-field-DMZZ6CND.cjs.map} +1 -1
  159. package/dist/textarea-field-BmImMdg-.cjs +2 -0
  160. package/dist/{textarea-field-BhqX29CS.cjs.map → textarea-field-BmImMdg-.cjs.map} +1 -1
  161. package/dist/textarea-field-Cim3l0y8.mjs +2 -0
  162. package/dist/{textarea-field-DNLyrRH7.mjs.map → textarea-field-Cim3l0y8.mjs.map} +1 -1
  163. package/dist/title-field-2dABwspv.mjs +2 -0
  164. package/dist/{title-field-oAqHRw59.mjs.map → title-field-2dABwspv.mjs.map} +1 -1
  165. package/dist/title-field-CFnSgTGH.cjs +2 -0
  166. package/dist/{title-field-B2hM3S_S.cjs.map → title-field-CFnSgTGH.cjs.map} +1 -1
  167. package/dist/ui/breadcrumb.cjs +1 -1
  168. package/dist/ui/button-group.cjs +1 -1
  169. package/dist/ui/button.cjs +1 -1
  170. package/dist/ui/carousel.cjs +1 -1
  171. package/dist/ui/dropdown-menu.cjs +1 -1
  172. package/dist/ui/dropdown-menu.cjs.map +1 -1
  173. package/dist/ui/dropdown-menu.mjs +1 -1
  174. package/dist/ui/dropdown-menu.mjs.map +1 -1
  175. package/dist/ui/file-uploader.cjs +1 -1
  176. package/dist/ui/item.cjs +1 -1
  177. package/dist/ui/resizable.cjs +1 -1
  178. package/dist/ui/resizable.d.cts +1 -1
  179. package/dist/ui/resizable.d.mts +1 -1
  180. package/package.json +9 -4
  181. package/styles/text-editor.css +205 -38
  182. package/dist/LoginPage-DDljzV6A.d.cts +0 -43
  183. package/dist/LoginPage-DDljzV6A.d.mts +0 -43
  184. package/dist/action-submit-B9vHpLoN.cjs +0 -2
  185. package/dist/action-submit-BQdkz4mS.mjs +0 -2
  186. package/dist/actions-form-D4n1W3-X.mjs +0 -2
  187. package/dist/actions-form-DF2eYxGQ.cjs +0 -2
  188. package/dist/checkbox-field-BRGTLOjq.mjs +0 -2
  189. package/dist/checkbox-field-ldZRSCca.cjs +0 -2
  190. package/dist/combobox-field-CvkdZkQE.mjs +0 -2
  191. package/dist/combobox-field-ZYr7636s.cjs +0 -2
  192. package/dist/date-field-1Hmcv8Zp.cjs +0 -2
  193. package/dist/date-field-DGMTG_hu.mjs +0 -2
  194. package/dist/dialog-form-BRSZpRTC.mjs +0 -2
  195. package/dist/dialog-form-C1qpltYx.cjs +0 -2
  196. package/dist/email-field-C2Lvl_rQ.mjs +0 -2
  197. package/dist/email-field-D3nSkHj2.cjs +0 -2
  198. package/dist/field-BSLi-P0Q.cjs +0 -2
  199. package/dist/field-BSLi-P0Q.cjs.map +0 -1
  200. package/dist/field-V2DoD8qL.mjs +0 -2
  201. package/dist/field-V2DoD8qL.mjs.map +0 -1
  202. package/dist/group-field-gejvx_Td.mjs +0 -2
  203. package/dist/group-field-sVykO2JZ.cjs +0 -2
  204. package/dist/number-field-CR5PLX6H.mjs +0 -2
  205. package/dist/number-field-CWDYA3La.cjs +0 -2
  206. package/dist/pages/LoginPage.cjs +0 -2
  207. package/dist/pages/LoginPage.cjs.map +0 -1
  208. package/dist/pages/LoginPage.d.cts +0 -2
  209. package/dist/pages/LoginPage.d.mts +0 -2
  210. package/dist/pages/LoginPage.mjs +0 -2
  211. package/dist/pages/LoginPage.mjs.map +0 -1
  212. package/dist/password-field-B2_kzss6.mjs +0 -2
  213. package/dist/password-field-BHRhVyZ0.cjs +0 -2
  214. package/dist/popover-form-CeRVpy1B.mjs +0 -2
  215. package/dist/popover-form-Ch_iMMSm.cjs +0 -2
  216. package/dist/radio-group-field-BFhBfzoT.cjs +0 -2
  217. package/dist/radio-group-field-Iwo2Q2Ig.mjs +0 -2
  218. package/dist/rolldown-runtime-CMqjfN_6.cjs +0 -1
  219. package/dist/select-field-CvDBZQTl.cjs +0 -2
  220. package/dist/select-field-NJgDDCO2.mjs +0 -2
  221. package/dist/simple-array-field-BwNCeUnn.mjs +0 -2
  222. package/dist/simple-array-field-aGXkDZXD.cjs +0 -2
  223. package/dist/simple-boolean-field-BeVkn3c4.cjs +0 -2
  224. package/dist/simple-boolean-field-t_XDXqYs.mjs +0 -2
  225. package/dist/simple-combobox-field-HCB4A33-.mjs +0 -2
  226. package/dist/simple-combobox-field-U0ZAl7VQ.cjs +0 -2
  227. package/dist/simple-date-field-Dj4bJoji.mjs +0 -2
  228. package/dist/simple-date-field-DtxEpEZj.cjs +0 -2
  229. package/dist/simple-email-field-BDyhkmHV.mjs +0 -2
  230. package/dist/simple-email-field-DK9I_Tc_.cjs +0 -2
  231. package/dist/simple-number-field-BspqWU-3.cjs +0 -2
  232. package/dist/simple-number-field-hneXMhfJ.mjs +0 -2
  233. package/dist/simple-password-field-BEEcleom.cjs +0 -2
  234. package/dist/simple-password-field-vsLRHDk4.mjs +0 -2
  235. package/dist/simple-radio-group-field-BURm_BSA.mjs +0 -2
  236. package/dist/simple-radio-group-field-Wm8xB0fN.cjs +0 -2
  237. package/dist/simple-select-field-8cY51U4d.mjs +0 -2
  238. package/dist/simple-select-field-QQ65caBf.cjs +0 -2
  239. package/dist/simple-text-field-BHkCPiE5.cjs +0 -2
  240. package/dist/simple-text-field-DK72_OA_.mjs +0 -2
  241. package/dist/simple-textarea-field-B72nNQHv.mjs +0 -2
  242. package/dist/simple-textarea-field-Bu5h7sfH.cjs +0 -2
  243. package/dist/switch-field-DoPUWb9d.mjs +0 -2
  244. package/dist/switch-field-eLVlQZSI.cjs +0 -2
  245. package/dist/tanstack-form-C0ab8EEl.cjs +0 -2
  246. package/dist/tanstack-form-C0ab8EEl.cjs.map +0 -1
  247. package/dist/tanstack-form-fkaBh9RO.mjs +0 -2
  248. package/dist/tanstack-form-fkaBh9RO.mjs.map +0 -1
  249. package/dist/text-editor-BtfyZSgR.cjs +0 -2
  250. package/dist/text-editor-BtfyZSgR.cjs.map +0 -1
  251. package/dist/text-editor-CtR27_PR.mjs +0 -2
  252. package/dist/text-editor-CtR27_PR.mjs.map +0 -1
  253. package/dist/text-editor-field-B6HEsAHt.mjs +0 -2
  254. package/dist/text-editor-field-B6HEsAHt.mjs.map +0 -1
  255. package/dist/text-editor-field-DcEUC0iH.cjs +0 -2
  256. package/dist/text-editor-field-DcEUC0iH.cjs.map +0 -1
  257. package/dist/text-field-Bm-k6Jr7.mjs +0 -2
  258. package/dist/text-field-DT50dOVI.cjs +0 -2
  259. package/dist/textarea-field-BhqX29CS.cjs +0 -2
  260. package/dist/textarea-field-DNLyrRH7.mjs +0 -2
  261. package/dist/title-field-B2hM3S_S.cjs +0 -2
  262. package/dist/title-field-oAqHRw59.mjs +0 -2
@@ -0,0 +1,2 @@
1
+ import{Button as e}from"./ui/button.mjs";import{LunasLogo as t}from"./features/logo/index.mjs";import{Dialog as n,DialogContent as r,DialogDescription as i,DialogHeader as a,DialogTitle as o}from"./ui/dialog.mjs";import{Input as s}from"./ui/input.mjs";import{n as c,t as l}from"./alert-OD1KJTEV.mjs";import{Label as u}from"./ui/label.mjs";import{Select as d,SelectContent as f,SelectItem as p,SelectTrigger as m,SelectValue as h}from"./ui/select.mjs";import{InputOTP as g,InputOTPGroup as _,InputOTPSeparator as v,InputOTPSlot as y}from"./ui/input-otp.mjs";import{Eye as b,EyeOff as x}from"lucide-react";import{memo as S,useCallback as C,useEffect as w,useId as T,useMemo as E,useRef as D,useState as O}from"react";import{Fragment as k,jsx as A,jsxs as j}from"react/jsx-runtime";import{z as M}from"zod/v4";const N=S(function({emailId:t,passwordId:n,method:r,onMethodChange:i,email:a,onEmailChange:o,password:c,onPasswordChange:l,showPassword:g,onToggleShowPassword:_,fieldErrors:v,isLoading:y,onForgotPassword:S,onRegister:C,onClose:w,onSubmit:T}){return j(k,{children:[j(`form`,{onSubmit:T,noValidate:!0,className:`flex flex-col gap-4`,children:[j(`div`,{className:`flex flex-col gap-1.5`,children:[A(u,{htmlFor:t,children:`Email`}),A(s,{id:t,type:`email`,autoComplete:`email`,placeholder:`nguyenvana@example.com`,value:a,onChange:e=>o(e.target.value),"aria-invalid":!!v.email,disabled:y}),v.email&&A(`p`,{className:`text-danger text-xs`,children:v.email})]}),r===`password`&&j(`div`,{className:`flex flex-col gap-1.5`,children:[j(`div`,{className:`flex items-center justify-between`,children:[A(u,{htmlFor:n,children:`Mật khẩu`}),S&&A(e,{type:`button`,variant:`link`,size:`sm`,className:`h-auto p-0 text-xs ring-0! ring-offset-0!`,onClick:S,children:`Quên mật khẩu?`})]}),j(`div`,{className:`relative`,children:[A(s,{id:n,type:g?`text`:`password`,autoComplete:`current-password`,placeholder:`••••••••`,value:c,onChange:e=>l(e.target.value),"aria-invalid":!!v.password,disabled:y,className:`pr-10`}),A(`button`,{type:`button`,className:`absolute inset-y-0 right-0 flex items-center px-3 text-muted-foreground hover:text-text-positive-strong`,onMouseDown:e=>{e.preventDefault(),_()},"aria-label":g?`Ẩn mật khẩu`:`Hiện mật khẩu`,children:A(g?x:b,{size:16})})]}),v.password&&A(`p`,{className:`text-danger text-xs`,children:v.password})]}),A(e,{type:`submit`,isLoading:y,className:`w-full`,children:r===`password`?`Đăng nhập`:`Gửi mã đăng nhập`}),A(e,{type:`button`,variant:`outline`,className:`w-full`,disabled:y,onClick:w,children:`Đóng hộp thoại`}),j(`div`,{className:`flex flex-col gap-1.5`,children:[A(u,{children:`Phương thức đăng nhập`}),j(d,{value:r,onValueChange:i,disabled:y,children:[A(m,{className:`w-full`,children:A(h,{})}),j(f,{children:[A(p,{value:`otp`,children:`Mã gửi qua email`}),A(p,{value:`password`,children:`Mật khẩu`})]})]})]})]}),C&&j(`div`,{className:`flex justify-center gap-1 text-muted-foreground text-sm`,children:[A(`span`,{children:`Chưa có tài khoản?`}),A(e,{variant:`link`,size:`sm`,className:`h-auto p-0`,onClick:C,children:`Đăng ký`})]})]})}),P=M.object({email:M.email(`Email không hợp lệ`).min(1,`Vui lòng nhập email`),password:M.string().min(1,`Vui lòng nhập mật khẩu`)}),F=M.object({email:M.email(`Email không hợp lệ`).min(1,`Vui lòng nhập email`)}),I=S(function({otp:t,onOtpChange:n,onComplete:r,isLoading:i,resendCooldownSeconds:a,onVerify:o,onResend:s,onBack:c}){let[l,u]=O(a),d=D(null),f=C(e=>{d.current&&clearInterval(d.current),u(e),d.current=setInterval(()=>{u(e=>e<=1?(d.current&&clearInterval(d.current),0):e-1)},1e3)},[]);w(()=>(f(a),()=>{d.current&&clearInterval(d.current)}),[]);let p=C(()=>{f(a),s()},[s,a,f]);return j(`div`,{className:`flex flex-col items-center gap-4`,children:[j(g,{maxLength:8,pattern:`^[ABCDEFGHJKMNPQRSTUVWXYZ23456789abcdefghjkmnpqrstuvwxyz23456789]*$`,inputMode:`text`,value:t,onChange:e=>n(e.toUpperCase()),onComplete:r,disabled:i,containerClassName:`gap-1 sm:gap-2`,children:[j(_,{children:[A(y,{index:0,className:`size-7 text-xs sm:size-9 sm:text-sm`}),A(y,{index:1,className:`size-7 text-xs sm:size-9 sm:text-sm`}),A(y,{index:2,className:`size-7 text-xs sm:size-9 sm:text-sm`}),A(y,{index:3,className:`size-7 text-xs sm:size-9 sm:text-sm`})]}),A(v,{className:`max-sm:[&>svg]:size-3`}),j(_,{children:[A(y,{index:4,className:`size-7 text-xs sm:size-9 sm:text-sm`}),A(y,{index:5,className:`size-7 text-xs sm:size-9 sm:text-sm`}),A(y,{index:6,className:`size-7 text-xs sm:size-9 sm:text-sm`}),A(y,{index:7,className:`size-7 text-xs sm:size-9 sm:text-sm`})]})]}),A(e,{type:`button`,isLoading:i,disabled:t.length<8,className:`w-full`,onClick:o,children:`Đăng nhập`}),j(`div`,{className:`flex items-center gap-1 text-text-positive-weak text-sm`,children:[A(`span`,{children:`Chưa nhận được mã?`}),A(e,{variant:`link`,size:`sm`,className:`h-auto p-0`,disabled:l>0||i,onClick:p,children:l>0?`Gửi lại (${l}s)`:`Gửi lại`})]}),A(e,{type:`button`,variant:`ghost`,size:`sm`,className:`w-full`,disabled:i,onClick:c,children:`Quay lại`})]})}),L=({open:e,onOpenChange:s,onLogin:u,onRequestOtp:d,onVerifyOtp:f,onForgotPassword:p,onRegister:m,isLoading:h=!1,errorMessage:g,title:_=`Đăng nhập`,subtitle:v=`Nhập thông tin để tiếp tục`,resendCooldownSeconds:y=60})=>{let b=T(),x=T(),[S,D]=O(`password`),[M,L]=O(`form`),[R,z]=O(``),[B,V]=O(``),[H,U]=O(``),[W,G]=O(!1),[K,q]=O({});w(()=>{e||(L(`form`),U(``),q({}),D(`password`))},[e]);let J=C(e=>{(e===`password`||e===`otp`)&&(D(e),q({}),V(``))},[]),Y=C(async()=>{let e=P.safeParse({email:R,password:B});if(!e.success){let t=e.error.flatten().fieldErrors;q({email:t.email?.[0],password:t.password?.[0]});return}q({}),await u(R,B)},[R,B,u]),X=C(async()=>{let e=F.safeParse({email:R});if(!e.success){q({email:e.error.flatten().fieldErrors.email?.[0]});return}q({}),await d(R)&&L(`otp-verify`)},[R,d]),Z=C(async e=>{e.preventDefault(),S===`password`?await Y():await X()},[S,Y,X]),Q=C(async()=>{await d(R)},[R,d]),$=C(async()=>{H.length<8||await f(R,H)},[R,H,f]),ee=C(()=>{U(``),L(`form`)},[]),te=C(()=>G(e=>!e),[]),ne=C(()=>s(!1),[s]),re=E(()=>M===`otp-verify`?j(k,{children:[`Nhập mã đăng nhập đã được gửi tới `,A(`span`,{className:`font-medium text-text-positive-weak`,children:R}),`. Mã có hiệu lực trong 10 phút.`]}):v,[M,R,v]);return A(n,{open:e,onOpenChange:s,children:j(r,{showCloseButton:!1,className:`max-sm:data-[state=open]:slide-in-from-bottom max-sm:data-[state=open]:zoom-in-100 max-sm:data-[state=closed]:slide-out-to-bottom max-sm:data-[state=closed]:zoom-out-100 max-sm:top-auto max-sm:right-0 max-sm:bottom-0 max-sm:left-0 max-sm:max-w-full max-sm:translate-x-0 max-sm:translate-y-0 max-sm:rounded-b-none sm:max-w-sm`,children:[j(a,{children:[A(t,{variant:`horizontal`,size:`sm`,className:`mx-auto`}),j(`div`,{className:`flex flex-col gap-0.5 items-center`,children:[A(o,{children:_}),A(i,{children:re})]})]}),g&&A(l,{variant:`destructive`,children:A(c,{children:g})}),M===`form`?A(N,{emailId:b,passwordId:x,method:S,onMethodChange:J,email:R,onEmailChange:z,password:B,onPasswordChange:V,showPassword:W,onToggleShowPassword:te,fieldErrors:K,isLoading:h,onForgotPassword:p,onRegister:m,onClose:ne,onSubmit:Z}):A(I,{otp:H,onOtpChange:U,onComplete:$,isLoading:h,resendCooldownSeconds:y,onVerify:$,onResend:Q,onBack:ee})]})})};export{L as t};
2
+ //# sourceMappingURL=LoginPage-DGgThT3s.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoginPage-DGgThT3s.mjs","names":[],"sources":["../packages/components/pages/LoginPage/components/credentials-form.tsx","../packages/components/pages/LoginPage/constants.ts","../packages/components/pages/LoginPage/components/otp-verify-step.tsx","../packages/components/pages/LoginPage/index.tsx"],"sourcesContent":["'use client';\n\nimport { memo } from 'react';\n\nimport { Eye, EyeOff } from 'lucide-react';\n\nimport { Button } from '../../../ui/button';\nimport { Input } from '../../../ui/input';\nimport { Label } from '../../../ui/label';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../../ui/select';\nimport type { LoginMethod } from '../types';\n\nexport interface CredentialsFormProps {\n emailId: string;\n passwordId: string;\n method: LoginMethod;\n onMethodChange: (value: string) => void;\n email: string;\n onEmailChange: (value: string) => void;\n password: string;\n onPasswordChange: (value: string) => void;\n showPassword: boolean;\n onToggleShowPassword: () => void;\n fieldErrors: { email?: string; password?: string };\n isLoading: boolean;\n onForgotPassword?: () => void;\n onRegister?: () => void;\n onClose: () => void;\n onSubmit: (e: React.FormEvent<HTMLFormElement>) => void;\n}\n\nexport const CredentialsForm = memo(function CredentialsForm({\n emailId,\n passwordId,\n method,\n onMethodChange,\n email,\n onEmailChange,\n password,\n onPasswordChange,\n showPassword,\n onToggleShowPassword,\n fieldErrors,\n isLoading,\n onForgotPassword,\n onRegister,\n onClose,\n onSubmit,\n}: CredentialsFormProps) {\n return (\n <>\n <form onSubmit={onSubmit} noValidate className=\"flex flex-col gap-4\">\n <div className=\"flex flex-col gap-1.5\">\n <Label htmlFor={emailId}>Email</Label>\n <Input\n id={emailId}\n type=\"email\"\n autoComplete=\"email\"\n placeholder=\"nguyenvana@example.com\"\n value={email}\n onChange={e => onEmailChange(e.target.value)}\n aria-invalid={!!fieldErrors.email}\n disabled={isLoading}\n />\n {fieldErrors.email && <p className=\"text-danger text-xs\">{fieldErrors.email}</p>}\n </div>\n\n {method === 'password' && (\n <div className=\"flex flex-col gap-1.5\">\n <div className=\"flex items-center justify-between\">\n <Label htmlFor={passwordId}>Mật khẩu</Label>\n {onForgotPassword && (\n <Button type=\"button\" variant=\"link\" size=\"sm\" className=\"h-auto p-0 text-xs ring-0! ring-offset-0!\" onClick={onForgotPassword}>\n Quên mật khẩu?\n </Button>\n )}\n </div>\n <div className=\"relative\">\n <Input\n id={passwordId}\n type={showPassword ? 'text' : 'password'}\n autoComplete=\"current-password\"\n placeholder=\"••••••••\"\n value={password}\n onChange={e => onPasswordChange(e.target.value)}\n aria-invalid={!!fieldErrors.password}\n disabled={isLoading}\n className=\"pr-10\"\n />\n <button\n type=\"button\"\n className=\"absolute inset-y-0 right-0 flex items-center px-3 text-muted-foreground hover:text-text-positive-strong\"\n onMouseDown={e => {\n e.preventDefault();\n onToggleShowPassword();\n }}\n aria-label={showPassword ? 'Ẩn mật khẩu' : 'Hiện mật khẩu'}\n >\n {showPassword ? <EyeOff size={16} /> : <Eye size={16} />}\n </button>\n </div>\n {fieldErrors.password && <p className=\"text-danger text-xs\">{fieldErrors.password}</p>}\n </div>\n )}\n\n <Button type=\"submit\" isLoading={isLoading} className=\"w-full\">\n {method === 'password' ? 'Đăng nhập' : 'Gửi mã đăng nhập'}\n </Button>\n <Button type=\"button\" variant=\"outline\" className=\"w-full\" disabled={isLoading} onClick={onClose}>\n Đóng hộp thoại\n </Button>\n\n <div className=\"flex flex-col gap-1.5\">\n <Label>Phương thức đăng nhập</Label>\n <Select value={method} onValueChange={onMethodChange} disabled={isLoading}>\n <SelectTrigger className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"otp\">Mã gửi qua email</SelectItem>\n <SelectItem value=\"password\">Mật khẩu</SelectItem>\n </SelectContent>\n </Select>\n </div>\n </form>\n\n {onRegister && (\n <div className=\"flex justify-center gap-1 text-muted-foreground text-sm\">\n <span>Chưa có tài khoản?</span>\n <Button variant=\"link\" size=\"sm\" className=\"h-auto p-0\" onClick={onRegister}>\n Đăng ký\n </Button>\n </div>\n )}\n </>\n );\n});\n","import { z } from 'zod/v4';\n\n// Same alphabet as the backend's generated code — visually confusing\n// characters (0/O, 1/I/L) are excluded.\nexport const OTP_ALPHABET = 'ABCDEFGHJKMNPQRSTUVWXYZ23456789';\n// Accepts both cases at the input level — input-otp validates each keystroke\n// against this pattern *before* our onChange runs, so lowercase must be\n// allowed here too or typing it (the common case, no shift/caps-lock) gets\n// silently rejected. onChange still upper-cases the accepted value.\nexport const OTP_PATTERN = `^[${OTP_ALPHABET}${OTP_ALPHABET.toLowerCase()}]*$`;\nexport const OTP_LENGTH = 8;\n\nexport const passwordLoginSchema = z.object({\n email: z.email('Email không hợp lệ').min(1, 'Vui lòng nhập email'),\n password: z.string().min(1, 'Vui lòng nhập mật khẩu'),\n});\n\nexport const otpRequestSchema = z.object({\n email: z.email('Email không hợp lệ').min(1, 'Vui lòng nhập email'),\n});\n","'use client';\n\nimport { memo, useCallback, useEffect, useRef, useState } from 'react';\n\nimport { Button } from '../../../ui/button';\nimport { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot } from '../../../ui/input-otp';\nimport { OTP_LENGTH, OTP_PATTERN } from '../constants';\n\nexport interface OtpVerifyStepProps {\n otp: string;\n onOtpChange: (value: string) => void;\n onComplete: () => void;\n isLoading: boolean;\n resendCooldownSeconds: number;\n onVerify: () => void;\n onResend: () => void;\n onBack: () => void;\n}\n\nexport const OtpVerifyStep = memo(function OtpVerifyStep({\n otp,\n onOtpChange,\n onComplete,\n isLoading,\n resendCooldownSeconds,\n onVerify,\n onResend,\n onBack,\n}: OtpVerifyStepProps) {\n // Đếm ngược sống hẳn trong component này — tick mỗi giây chỉ re-render\n // OtpVerifyStep, không kéo theo LoginPage cha re-render liên tục.\n const [countdown, setCountdown] = useState(resendCooldownSeconds);\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n const startCountdown = useCallback((seconds: number) => {\n if (intervalRef.current) clearInterval(intervalRef.current);\n setCountdown(seconds);\n intervalRef.current = setInterval(() => {\n setCountdown(prev => {\n if (prev <= 1) {\n if (intervalRef.current) clearInterval(intervalRef.current);\n return 0;\n }\n return prev - 1;\n });\n }, 1000);\n }, []);\n\n // Bắt đầu đếm ngược ngay khi bước này được mount, dừng khi unmount (quay lại/đóng dialog)\n // biome-ignore lint/correctness/useExhaustiveDependencies: chỉ chạy 1 lần lúc mount, không cần re-run khi resendCooldownSeconds/startCountdown đổi\n useEffect(() => {\n startCountdown(resendCooldownSeconds);\n return () => {\n if (intervalRef.current) clearInterval(intervalRef.current);\n };\n }, []);\n\n const handleResendClick = useCallback(() => {\n startCountdown(resendCooldownSeconds);\n onResend();\n }, [onResend, resendCooldownSeconds, startCountdown]);\n\n return (\n <div className=\"flex flex-col items-center gap-4\">\n <InputOTP\n maxLength={OTP_LENGTH}\n pattern={OTP_PATTERN}\n inputMode=\"text\"\n value={otp}\n onChange={value => onOtpChange(value.toUpperCase())}\n onComplete={onComplete}\n disabled={isLoading}\n containerClassName=\"gap-1 sm:gap-2\"\n >\n <InputOTPGroup>\n <InputOTPSlot index={0} className=\"size-7 text-xs sm:size-9 sm:text-sm\" />\n <InputOTPSlot index={1} className=\"size-7 text-xs sm:size-9 sm:text-sm\" />\n <InputOTPSlot index={2} className=\"size-7 text-xs sm:size-9 sm:text-sm\" />\n <InputOTPSlot index={3} className=\"size-7 text-xs sm:size-9 sm:text-sm\" />\n </InputOTPGroup>\n <InputOTPSeparator className=\"max-sm:[&>svg]:size-3\" />\n <InputOTPGroup>\n <InputOTPSlot index={4} className=\"size-7 text-xs sm:size-9 sm:text-sm\" />\n <InputOTPSlot index={5} className=\"size-7 text-xs sm:size-9 sm:text-sm\" />\n <InputOTPSlot index={6} className=\"size-7 text-xs sm:size-9 sm:text-sm\" />\n <InputOTPSlot index={7} className=\"size-7 text-xs sm:size-9 sm:text-sm\" />\n </InputOTPGroup>\n </InputOTP>\n\n <Button type=\"button\" isLoading={isLoading} disabled={otp.length < OTP_LENGTH} className=\"w-full\" onClick={onVerify}>\n Đăng nhập\n </Button>\n\n <div className=\"flex items-center gap-1 text-text-positive-weak text-sm\">\n <span>Chưa nhận được mã?</span>\n <Button variant=\"link\" size=\"sm\" className=\"h-auto p-0\" disabled={countdown > 0 || isLoading} onClick={handleResendClick}>\n {countdown > 0 ? `Gửi lại (${countdown}s)` : 'Gửi lại'}\n </Button>\n </div>\n\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" className=\"w-full\" disabled={isLoading} onClick={onBack}>\n Quay lại\n </Button>\n </div>\n );\n});\n","'use client';\n\nimport { useCallback, useEffect, useId, useMemo, useState } from 'react';\n\nimport { LunasLogo } from '../../features/logo';\nimport { Alert, AlertDescription } from '../../ui/alert';\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../../ui/dialog';\nimport { CredentialsForm } from './components/credentials-form';\nimport { OtpVerifyStep } from './components/otp-verify-step';\nimport { OTP_LENGTH, otpRequestSchema, passwordLoginSchema } from './constants';\nimport type { LoginMethod, LoginPageProps } from './types';\n\nexport type { LoginMethod, LoginPageProps } from './types';\n\n/**\n * Modal login dialog for the client authentication flow. Defaults to\n * email/password credentials; a select at the bottom of the form switches\n * to a passwordless login code sent by email instead. The code flow's\n * request and verify steps are both handled inside this single dialog.\n *\n * @example\n * ```tsx\n * import { LoginPage } from '@customafk/lunas-ui/pages/LoginPage';\n *\n * <LoginPage\n * open={open}\n * onOpenChange={setOpen}\n * onLogin={async (email, password) => {\n * await authService.login(email, password);\n * setOpen(false);\n * }}\n * onRequestOtp={async (email) => {\n * const res = await authService.requestLoginOtp(email);\n * return res.success;\n * }}\n * onVerifyOtp={async (email, otp) => {\n * await authService.verifyLoginOtp(email, otp);\n * setOpen(false);\n * }}\n * onRegister={() => { setOpen(false); setRegisterOpen(true); }}\n * />\n * ```\n */\nexport const LoginPage = ({\n open,\n onOpenChange,\n onLogin,\n onRequestOtp,\n onVerifyOtp,\n onForgotPassword,\n onRegister,\n isLoading = false,\n errorMessage,\n title = 'Đăng nhập',\n subtitle = 'Nhập thông tin để tiếp tục',\n resendCooldownSeconds = 60,\n}: LoginPageProps) => {\n const emailId = useId();\n const passwordId = useId();\n const [method, setMethod] = useState<LoginMethod>('password');\n const [step, setStep] = useState<'form' | 'otp-verify'>('form');\n const [email, setEmail] = useState<string>('');\n const [password, setPassword] = useState<string>('');\n const [otp, setOtp] = useState<string>('');\n const [showPassword, setShowPassword] = useState<boolean>(false);\n const [fieldErrors, setFieldErrors] = useState<{ email?: string; password?: string }>({});\n\n useEffect(() => {\n if (!open) {\n setStep('form');\n setOtp('');\n setFieldErrors({});\n setMethod('password');\n }\n }, [open]);\n\n // Chuyển đổi giữa phương thức \"password\" và \"otp\", xoá lỗi/mật khẩu cũ\n const handleMethodChange = useCallback((value: string) => {\n if (value !== 'password' && value !== 'otp') return;\n setMethod(value as LoginMethod);\n setFieldErrors({});\n setPassword('');\n }, []);\n\n // Validate rồi gọi onLogin khi đăng nhập bằng email/mật khẩu\n const handlePasswordSubmit = useCallback(async () => {\n const result = passwordLoginSchema.safeParse({ email, password });\n if (!result.success) {\n const errors = result.error.flatten().fieldErrors;\n setFieldErrors({ email: errors.email?.[0], password: errors.password?.[0] });\n return;\n }\n setFieldErrors({});\n await onLogin(email, password);\n }, [email, password, onLogin]);\n\n // Validate email rồi gửi yêu cầu OTP, chuyển sang bước nhập mã nếu thành công\n const handleOtpRequestSubmit = useCallback(async () => {\n const result = otpRequestSchema.safeParse({ email });\n if (!result.success) {\n setFieldErrors({ email: result.error.flatten().fieldErrors.email?.[0] });\n return;\n }\n setFieldErrors({});\n const sent = await onRequestOtp(email);\n if (sent) setStep('otp-verify');\n }, [email, onRequestOtp]);\n\n // Submit form ở bước \"form\" — rẽ nhánh theo method đang chọn\n const handleSubmit = useCallback(\n async (e: React.SubmitEvent<HTMLFormElement>) => {\n e.preventDefault();\n if (method === 'password') await handlePasswordSubmit();\n else await handleOtpRequestSubmit();\n },\n [method, handlePasswordSubmit, handleOtpRequestSubmit]\n );\n\n // Gửi lại mã OTP — đếm ngược tự quản lý bên trong OtpVerifyStep\n const handleResend = useCallback(async () => {\n await onRequestOtp(email);\n }, [email, onRequestOtp]);\n\n // Xác thực mã OTP khi đã nhập đủ độ dài\n const handleVerify = useCallback(async () => {\n if (otp.length < OTP_LENGTH) return;\n await onVerifyOtp(email, otp);\n }, [email, otp, onVerifyOtp]);\n\n // Quay lại bước \"form\" từ bước nhập OTP\n const handleBackToForm = useCallback(() => {\n setOtp('');\n setStep('form');\n }, []);\n\n // Đảo trạng thái hiện/ẩn mật khẩu\n const handleToggleShowPassword = useCallback(() => setShowPassword(v => !v), []);\n\n // Đóng dialog đăng nhập\n const handleClose = useCallback(() => onOpenChange(false), [onOpenChange]);\n\n // Nội dung mô tả dialog đổi theo bước hiện tại — chỉ tính lại khi step/email/subtitle đổi\n const dialogDescription = useMemo(\n () =>\n step === 'otp-verify' ? (\n <>\n Nhập mã đăng nhập đã được gửi tới <span className=\"font-medium text-text-positive-weak\">{email}</span>. Mã có hiệu lực trong 10 phút.\n </>\n ) : (\n subtitle\n ),\n [step, email, subtitle]\n );\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent showCloseButton={false} className=\"max-sm:data-[state=open]:slide-in-from-bottom max-sm:data-[state=open]:zoom-in-100 max-sm:data-[state=closed]:slide-out-to-bottom max-sm:data-[state=closed]:zoom-out-100 max-sm:top-auto max-sm:right-0 max-sm:bottom-0 max-sm:left-0 max-sm:max-w-full max-sm:translate-x-0 max-sm:translate-y-0 max-sm:rounded-b-none sm:max-w-sm\">\n <DialogHeader>\n <LunasLogo variant=\"horizontal\" size=\"sm\" className=\"mx-auto\" />\n <div className=\"flex flex-col gap-0.5 items-center\">\n <DialogTitle>{title}</DialogTitle>\n <DialogDescription>{dialogDescription}</DialogDescription>\n </div>\n </DialogHeader>\n\n {errorMessage && (\n <Alert variant=\"destructive\">\n <AlertDescription>{errorMessage}</AlertDescription>\n </Alert>\n )}\n\n {step === 'form' ? (\n <CredentialsForm\n emailId={emailId}\n passwordId={passwordId}\n method={method}\n onMethodChange={handleMethodChange}\n email={email}\n onEmailChange={setEmail}\n password={password}\n onPasswordChange={setPassword}\n showPassword={showPassword}\n onToggleShowPassword={handleToggleShowPassword}\n fieldErrors={fieldErrors}\n isLoading={isLoading}\n onForgotPassword={onForgotPassword}\n onRegister={onRegister}\n onClose={handleClose}\n onSubmit={handleSubmit}\n />\n ) : (\n <OtpVerifyStep\n otp={otp}\n onOtpChange={setOtp}\n onComplete={handleVerify}\n isLoading={isLoading}\n resendCooldownSeconds={resendCooldownSeconds}\n onVerify={handleVerify}\n onResend={handleResend}\n onBack={handleBackToForm}\n />\n )}\n </DialogContent>\n </Dialog>\n );\n};\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ const e=require("./ui/button.cjs"),t=require("./features/logo/index.cjs"),n=require("./ui/dialog.cjs"),r=require("./ui/input.cjs"),i=require("./alert-D31c6DLq.cjs"),a=require("./ui/label.cjs"),o=require("./ui/select.cjs"),s=require("./ui/input-otp.cjs");let c=require("lucide-react"),l=require("react"),u=require("react/jsx-runtime"),d=require("zod/v4");const f=(0,l.memo)(function({emailId:t,passwordId:n,method:i,onMethodChange:s,email:l,onEmailChange:d,password:f,onPasswordChange:p,showPassword:m,onToggleShowPassword:h,fieldErrors:g,isLoading:_,onForgotPassword:v,onRegister:y,onClose:b,onSubmit:x}){return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsxs)(`form`,{onSubmit:x,noValidate:!0,className:`flex flex-col gap-4`,children:[(0,u.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,u.jsx)(a.Label,{htmlFor:t,children:`Email`}),(0,u.jsx)(r.Input,{id:t,type:`email`,autoComplete:`email`,placeholder:`nguyenvana@example.com`,value:l,onChange:e=>d(e.target.value),"aria-invalid":!!g.email,disabled:_}),g.email&&(0,u.jsx)(`p`,{className:`text-danger text-xs`,children:g.email})]}),i===`password`&&(0,u.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,u.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,u.jsx)(a.Label,{htmlFor:n,children:`Mật khẩu`}),v&&(0,u.jsx)(e.Button,{type:`button`,variant:`link`,size:`sm`,className:`h-auto p-0 text-xs ring-0! ring-offset-0!`,onClick:v,children:`Quên mật khẩu?`})]}),(0,u.jsxs)(`div`,{className:`relative`,children:[(0,u.jsx)(r.Input,{id:n,type:m?`text`:`password`,autoComplete:`current-password`,placeholder:`••••••••`,value:f,onChange:e=>p(e.target.value),"aria-invalid":!!g.password,disabled:_,className:`pr-10`}),(0,u.jsx)(`button`,{type:`button`,className:`absolute inset-y-0 right-0 flex items-center px-3 text-muted-foreground hover:text-text-positive-strong`,onMouseDown:e=>{e.preventDefault(),h()},"aria-label":m?`Ẩn mật khẩu`:`Hiện mật khẩu`,children:m?(0,u.jsx)(c.EyeOff,{size:16}):(0,u.jsx)(c.Eye,{size:16})})]}),g.password&&(0,u.jsx)(`p`,{className:`text-danger text-xs`,children:g.password})]}),(0,u.jsx)(e.Button,{type:`submit`,isLoading:_,className:`w-full`,children:i===`password`?`Đăng nhập`:`Gửi mã đăng nhập`}),(0,u.jsx)(e.Button,{type:`button`,variant:`outline`,className:`w-full`,disabled:_,onClick:b,children:`Đóng hộp thoại`}),(0,u.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,u.jsx)(a.Label,{children:`Phương thức đăng nhập`}),(0,u.jsxs)(o.Select,{value:i,onValueChange:s,disabled:_,children:[(0,u.jsx)(o.SelectTrigger,{className:`w-full`,children:(0,u.jsx)(o.SelectValue,{})}),(0,u.jsxs)(o.SelectContent,{children:[(0,u.jsx)(o.SelectItem,{value:`otp`,children:`Mã gửi qua email`}),(0,u.jsx)(o.SelectItem,{value:`password`,children:`Mật khẩu`})]})]})]})]}),y&&(0,u.jsxs)(`div`,{className:`flex justify-center gap-1 text-muted-foreground text-sm`,children:[(0,u.jsx)(`span`,{children:`Chưa có tài khoản?`}),(0,u.jsx)(e.Button,{variant:`link`,size:`sm`,className:`h-auto p-0`,onClick:y,children:`Đăng ký`})]})]})}),p=d.z.object({email:d.z.email(`Email không hợp lệ`).min(1,`Vui lòng nhập email`),password:d.z.string().min(1,`Vui lòng nhập mật khẩu`)}),m=d.z.object({email:d.z.email(`Email không hợp lệ`).min(1,`Vui lòng nhập email`)}),h=(0,l.memo)(function({otp:t,onOtpChange:n,onComplete:r,isLoading:i,resendCooldownSeconds:a,onVerify:o,onResend:c,onBack:d}){let[f,p]=(0,l.useState)(a),m=(0,l.useRef)(null),h=(0,l.useCallback)(e=>{m.current&&clearInterval(m.current),p(e),m.current=setInterval(()=>{p(e=>e<=1?(m.current&&clearInterval(m.current),0):e-1)},1e3)},[]);(0,l.useEffect)(()=>(h(a),()=>{m.current&&clearInterval(m.current)}),[]);let g=(0,l.useCallback)(()=>{h(a),c()},[c,a,h]);return(0,u.jsxs)(`div`,{className:`flex flex-col items-center gap-4`,children:[(0,u.jsxs)(s.InputOTP,{maxLength:8,pattern:`^[ABCDEFGHJKMNPQRSTUVWXYZ23456789abcdefghjkmnpqrstuvwxyz23456789]*$`,inputMode:`text`,value:t,onChange:e=>n(e.toUpperCase()),onComplete:r,disabled:i,containerClassName:`gap-1 sm:gap-2`,children:[(0,u.jsxs)(s.InputOTPGroup,{children:[(0,u.jsx)(s.InputOTPSlot,{index:0,className:`size-7 text-xs sm:size-9 sm:text-sm`}),(0,u.jsx)(s.InputOTPSlot,{index:1,className:`size-7 text-xs sm:size-9 sm:text-sm`}),(0,u.jsx)(s.InputOTPSlot,{index:2,className:`size-7 text-xs sm:size-9 sm:text-sm`}),(0,u.jsx)(s.InputOTPSlot,{index:3,className:`size-7 text-xs sm:size-9 sm:text-sm`})]}),(0,u.jsx)(s.InputOTPSeparator,{className:`max-sm:[&>svg]:size-3`}),(0,u.jsxs)(s.InputOTPGroup,{children:[(0,u.jsx)(s.InputOTPSlot,{index:4,className:`size-7 text-xs sm:size-9 sm:text-sm`}),(0,u.jsx)(s.InputOTPSlot,{index:5,className:`size-7 text-xs sm:size-9 sm:text-sm`}),(0,u.jsx)(s.InputOTPSlot,{index:6,className:`size-7 text-xs sm:size-9 sm:text-sm`}),(0,u.jsx)(s.InputOTPSlot,{index:7,className:`size-7 text-xs sm:size-9 sm:text-sm`})]})]}),(0,u.jsx)(e.Button,{type:`button`,isLoading:i,disabled:t.length<8,className:`w-full`,onClick:o,children:`Đăng nhập`}),(0,u.jsxs)(`div`,{className:`flex items-center gap-1 text-text-positive-weak text-sm`,children:[(0,u.jsx)(`span`,{children:`Chưa nhận được mã?`}),(0,u.jsx)(e.Button,{variant:`link`,size:`sm`,className:`h-auto p-0`,disabled:f>0||i,onClick:g,children:f>0?`Gửi lại (${f}s)`:`Gửi lại`})]}),(0,u.jsx)(e.Button,{type:`button`,variant:`ghost`,size:`sm`,className:`w-full`,disabled:i,onClick:d,children:`Quay lại`})]})}),g=({open:e,onOpenChange:r,onLogin:a,onRequestOtp:o,onVerifyOtp:s,onForgotPassword:c,onRegister:d,isLoading:g=!1,errorMessage:_,title:v=`Đăng nhập`,subtitle:y=`Nhập thông tin để tiếp tục`,resendCooldownSeconds:b=60})=>{let x=(0,l.useId)(),S=(0,l.useId)(),[C,w]=(0,l.useState)(`password`),[T,E]=(0,l.useState)(`form`),[D,O]=(0,l.useState)(``),[k,A]=(0,l.useState)(``),[j,M]=(0,l.useState)(``),[N,P]=(0,l.useState)(!1),[F,I]=(0,l.useState)({});(0,l.useEffect)(()=>{e||(E(`form`),M(``),I({}),w(`password`))},[e]);let L=(0,l.useCallback)(e=>{(e===`password`||e===`otp`)&&(w(e),I({}),A(``))},[]),R=(0,l.useCallback)(async()=>{let e=p.safeParse({email:D,password:k});if(!e.success){let t=e.error.flatten().fieldErrors;I({email:t.email?.[0],password:t.password?.[0]});return}I({}),await a(D,k)},[D,k,a]),z=(0,l.useCallback)(async()=>{let e=m.safeParse({email:D});if(!e.success){I({email:e.error.flatten().fieldErrors.email?.[0]});return}I({}),await o(D)&&E(`otp-verify`)},[D,o]),B=(0,l.useCallback)(async e=>{e.preventDefault(),C===`password`?await R():await z()},[C,R,z]),V=(0,l.useCallback)(async()=>{await o(D)},[D,o]),H=(0,l.useCallback)(async()=>{j.length<8||await s(D,j)},[D,j,s]),U=(0,l.useCallback)(()=>{M(``),E(`form`)},[]),W=(0,l.useCallback)(()=>P(e=>!e),[]),G=(0,l.useCallback)(()=>r(!1),[r]),K=(0,l.useMemo)(()=>T===`otp-verify`?(0,u.jsxs)(u.Fragment,{children:[`Nhập mã đăng nhập đã được gửi tới `,(0,u.jsx)(`span`,{className:`font-medium text-text-positive-weak`,children:D}),`. Mã có hiệu lực trong 10 phút.`]}):y,[T,D,y]);return(0,u.jsx)(n.Dialog,{open:e,onOpenChange:r,children:(0,u.jsxs)(n.DialogContent,{showCloseButton:!1,className:`max-sm:data-[state=open]:slide-in-from-bottom max-sm:data-[state=open]:zoom-in-100 max-sm:data-[state=closed]:slide-out-to-bottom max-sm:data-[state=closed]:zoom-out-100 max-sm:top-auto max-sm:right-0 max-sm:bottom-0 max-sm:left-0 max-sm:max-w-full max-sm:translate-x-0 max-sm:translate-y-0 max-sm:rounded-b-none sm:max-w-sm`,children:[(0,u.jsxs)(n.DialogHeader,{children:[(0,u.jsx)(t.LunasLogo,{variant:`horizontal`,size:`sm`,className:`mx-auto`}),(0,u.jsxs)(`div`,{className:`flex flex-col gap-0.5 items-center`,children:[(0,u.jsx)(n.DialogTitle,{children:v}),(0,u.jsx)(n.DialogDescription,{children:K})]})]}),_&&(0,u.jsx)(i.t,{variant:`destructive`,children:(0,u.jsx)(i.n,{children:_})}),T===`form`?(0,u.jsx)(f,{emailId:x,passwordId:S,method:C,onMethodChange:L,email:D,onEmailChange:O,password:k,onPasswordChange:A,showPassword:N,onToggleShowPassword:W,fieldErrors:F,isLoading:g,onForgotPassword:c,onRegister:d,onClose:G,onSubmit:B}):(0,u.jsx)(h,{otp:j,onOtpChange:M,onComplete:H,isLoading:g,resendCooldownSeconds:b,onVerify:H,onResend:V,onBack:U})]})})};Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return g}});
2
+ //# sourceMappingURL=LoginPage-DPUdRD0r.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoginPage-DPUdRD0r.cjs","names":["Label","Input","Button","EyeOff","Eye","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","z","InputOTP","InputOTPGroup","InputOTPSlot","InputOTPSeparator","Button","Dialog","DialogContent","DialogHeader","LunasLogo","DialogTitle","DialogDescription","Alert","AlertDescription"],"sources":["../packages/components/pages/LoginPage/components/credentials-form.tsx","../packages/components/pages/LoginPage/constants.ts","../packages/components/pages/LoginPage/components/otp-verify-step.tsx","../packages/components/pages/LoginPage/index.tsx"],"sourcesContent":["'use client';\n\nimport { memo } from 'react';\n\nimport { Eye, EyeOff } from 'lucide-react';\n\nimport { Button } from '../../../ui/button';\nimport { Input } from '../../../ui/input';\nimport { Label } from '../../../ui/label';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../../ui/select';\nimport type { LoginMethod } from '../types';\n\nexport interface CredentialsFormProps {\n emailId: string;\n passwordId: string;\n method: LoginMethod;\n onMethodChange: (value: string) => void;\n email: string;\n onEmailChange: (value: string) => void;\n password: string;\n onPasswordChange: (value: string) => void;\n showPassword: boolean;\n onToggleShowPassword: () => void;\n fieldErrors: { email?: string; password?: string };\n isLoading: boolean;\n onForgotPassword?: () => void;\n onRegister?: () => void;\n onClose: () => void;\n onSubmit: (e: React.FormEvent<HTMLFormElement>) => void;\n}\n\nexport const CredentialsForm = memo(function CredentialsForm({\n emailId,\n passwordId,\n method,\n onMethodChange,\n email,\n onEmailChange,\n password,\n onPasswordChange,\n showPassword,\n onToggleShowPassword,\n fieldErrors,\n isLoading,\n onForgotPassword,\n onRegister,\n onClose,\n onSubmit,\n}: CredentialsFormProps) {\n return (\n <>\n <form onSubmit={onSubmit} noValidate className=\"flex flex-col gap-4\">\n <div className=\"flex flex-col gap-1.5\">\n <Label htmlFor={emailId}>Email</Label>\n <Input\n id={emailId}\n type=\"email\"\n autoComplete=\"email\"\n placeholder=\"nguyenvana@example.com\"\n value={email}\n onChange={e => onEmailChange(e.target.value)}\n aria-invalid={!!fieldErrors.email}\n disabled={isLoading}\n />\n {fieldErrors.email && <p className=\"text-danger text-xs\">{fieldErrors.email}</p>}\n </div>\n\n {method === 'password' && (\n <div className=\"flex flex-col gap-1.5\">\n <div className=\"flex items-center justify-between\">\n <Label htmlFor={passwordId}>Mật khẩu</Label>\n {onForgotPassword && (\n <Button type=\"button\" variant=\"link\" size=\"sm\" className=\"h-auto p-0 text-xs ring-0! ring-offset-0!\" onClick={onForgotPassword}>\n Quên mật khẩu?\n </Button>\n )}\n </div>\n <div className=\"relative\">\n <Input\n id={passwordId}\n type={showPassword ? 'text' : 'password'}\n autoComplete=\"current-password\"\n placeholder=\"••••••••\"\n value={password}\n onChange={e => onPasswordChange(e.target.value)}\n aria-invalid={!!fieldErrors.password}\n disabled={isLoading}\n className=\"pr-10\"\n />\n <button\n type=\"button\"\n className=\"absolute inset-y-0 right-0 flex items-center px-3 text-muted-foreground hover:text-text-positive-strong\"\n onMouseDown={e => {\n e.preventDefault();\n onToggleShowPassword();\n }}\n aria-label={showPassword ? 'Ẩn mật khẩu' : 'Hiện mật khẩu'}\n >\n {showPassword ? <EyeOff size={16} /> : <Eye size={16} />}\n </button>\n </div>\n {fieldErrors.password && <p className=\"text-danger text-xs\">{fieldErrors.password}</p>}\n </div>\n )}\n\n <Button type=\"submit\" isLoading={isLoading} className=\"w-full\">\n {method === 'password' ? 'Đăng nhập' : 'Gửi mã đăng nhập'}\n </Button>\n <Button type=\"button\" variant=\"outline\" className=\"w-full\" disabled={isLoading} onClick={onClose}>\n Đóng hộp thoại\n </Button>\n\n <div className=\"flex flex-col gap-1.5\">\n <Label>Phương thức đăng nhập</Label>\n <Select value={method} onValueChange={onMethodChange} disabled={isLoading}>\n <SelectTrigger className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"otp\">Mã gửi qua email</SelectItem>\n <SelectItem value=\"password\">Mật khẩu</SelectItem>\n </SelectContent>\n </Select>\n </div>\n </form>\n\n {onRegister && (\n <div className=\"flex justify-center gap-1 text-muted-foreground text-sm\">\n <span>Chưa có tài khoản?</span>\n <Button variant=\"link\" size=\"sm\" className=\"h-auto p-0\" onClick={onRegister}>\n Đăng ký\n </Button>\n </div>\n )}\n </>\n );\n});\n","import { z } from 'zod/v4';\n\n// Same alphabet as the backend's generated code — visually confusing\n// characters (0/O, 1/I/L) are excluded.\nexport const OTP_ALPHABET = 'ABCDEFGHJKMNPQRSTUVWXYZ23456789';\n// Accepts both cases at the input level — input-otp validates each keystroke\n// against this pattern *before* our onChange runs, so lowercase must be\n// allowed here too or typing it (the common case, no shift/caps-lock) gets\n// silently rejected. onChange still upper-cases the accepted value.\nexport const OTP_PATTERN = `^[${OTP_ALPHABET}${OTP_ALPHABET.toLowerCase()}]*$`;\nexport const OTP_LENGTH = 8;\n\nexport const passwordLoginSchema = z.object({\n email: z.email('Email không hợp lệ').min(1, 'Vui lòng nhập email'),\n password: z.string().min(1, 'Vui lòng nhập mật khẩu'),\n});\n\nexport const otpRequestSchema = z.object({\n email: z.email('Email không hợp lệ').min(1, 'Vui lòng nhập email'),\n});\n","'use client';\n\nimport { memo, useCallback, useEffect, useRef, useState } from 'react';\n\nimport { Button } from '../../../ui/button';\nimport { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot } from '../../../ui/input-otp';\nimport { OTP_LENGTH, OTP_PATTERN } from '../constants';\n\nexport interface OtpVerifyStepProps {\n otp: string;\n onOtpChange: (value: string) => void;\n onComplete: () => void;\n isLoading: boolean;\n resendCooldownSeconds: number;\n onVerify: () => void;\n onResend: () => void;\n onBack: () => void;\n}\n\nexport const OtpVerifyStep = memo(function OtpVerifyStep({\n otp,\n onOtpChange,\n onComplete,\n isLoading,\n resendCooldownSeconds,\n onVerify,\n onResend,\n onBack,\n}: OtpVerifyStepProps) {\n // Đếm ngược sống hẳn trong component này — tick mỗi giây chỉ re-render\n // OtpVerifyStep, không kéo theo LoginPage cha re-render liên tục.\n const [countdown, setCountdown] = useState(resendCooldownSeconds);\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n const startCountdown = useCallback((seconds: number) => {\n if (intervalRef.current) clearInterval(intervalRef.current);\n setCountdown(seconds);\n intervalRef.current = setInterval(() => {\n setCountdown(prev => {\n if (prev <= 1) {\n if (intervalRef.current) clearInterval(intervalRef.current);\n return 0;\n }\n return prev - 1;\n });\n }, 1000);\n }, []);\n\n // Bắt đầu đếm ngược ngay khi bước này được mount, dừng khi unmount (quay lại/đóng dialog)\n // biome-ignore lint/correctness/useExhaustiveDependencies: chỉ chạy 1 lần lúc mount, không cần re-run khi resendCooldownSeconds/startCountdown đổi\n useEffect(() => {\n startCountdown(resendCooldownSeconds);\n return () => {\n if (intervalRef.current) clearInterval(intervalRef.current);\n };\n }, []);\n\n const handleResendClick = useCallback(() => {\n startCountdown(resendCooldownSeconds);\n onResend();\n }, [onResend, resendCooldownSeconds, startCountdown]);\n\n return (\n <div className=\"flex flex-col items-center gap-4\">\n <InputOTP\n maxLength={OTP_LENGTH}\n pattern={OTP_PATTERN}\n inputMode=\"text\"\n value={otp}\n onChange={value => onOtpChange(value.toUpperCase())}\n onComplete={onComplete}\n disabled={isLoading}\n containerClassName=\"gap-1 sm:gap-2\"\n >\n <InputOTPGroup>\n <InputOTPSlot index={0} className=\"size-7 text-xs sm:size-9 sm:text-sm\" />\n <InputOTPSlot index={1} className=\"size-7 text-xs sm:size-9 sm:text-sm\" />\n <InputOTPSlot index={2} className=\"size-7 text-xs sm:size-9 sm:text-sm\" />\n <InputOTPSlot index={3} className=\"size-7 text-xs sm:size-9 sm:text-sm\" />\n </InputOTPGroup>\n <InputOTPSeparator className=\"max-sm:[&>svg]:size-3\" />\n <InputOTPGroup>\n <InputOTPSlot index={4} className=\"size-7 text-xs sm:size-9 sm:text-sm\" />\n <InputOTPSlot index={5} className=\"size-7 text-xs sm:size-9 sm:text-sm\" />\n <InputOTPSlot index={6} className=\"size-7 text-xs sm:size-9 sm:text-sm\" />\n <InputOTPSlot index={7} className=\"size-7 text-xs sm:size-9 sm:text-sm\" />\n </InputOTPGroup>\n </InputOTP>\n\n <Button type=\"button\" isLoading={isLoading} disabled={otp.length < OTP_LENGTH} className=\"w-full\" onClick={onVerify}>\n Đăng nhập\n </Button>\n\n <div className=\"flex items-center gap-1 text-text-positive-weak text-sm\">\n <span>Chưa nhận được mã?</span>\n <Button variant=\"link\" size=\"sm\" className=\"h-auto p-0\" disabled={countdown > 0 || isLoading} onClick={handleResendClick}>\n {countdown > 0 ? `Gửi lại (${countdown}s)` : 'Gửi lại'}\n </Button>\n </div>\n\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" className=\"w-full\" disabled={isLoading} onClick={onBack}>\n Quay lại\n </Button>\n </div>\n );\n});\n","'use client';\n\nimport { useCallback, useEffect, useId, useMemo, useState } from 'react';\n\nimport { LunasLogo } from '../../features/logo';\nimport { Alert, AlertDescription } from '../../ui/alert';\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../../ui/dialog';\nimport { CredentialsForm } from './components/credentials-form';\nimport { OtpVerifyStep } from './components/otp-verify-step';\nimport { OTP_LENGTH, otpRequestSchema, passwordLoginSchema } from './constants';\nimport type { LoginMethod, LoginPageProps } from './types';\n\nexport type { LoginMethod, LoginPageProps } from './types';\n\n/**\n * Modal login dialog for the client authentication flow. Defaults to\n * email/password credentials; a select at the bottom of the form switches\n * to a passwordless login code sent by email instead. The code flow's\n * request and verify steps are both handled inside this single dialog.\n *\n * @example\n * ```tsx\n * import { LoginPage } from '@customafk/lunas-ui/pages/LoginPage';\n *\n * <LoginPage\n * open={open}\n * onOpenChange={setOpen}\n * onLogin={async (email, password) => {\n * await authService.login(email, password);\n * setOpen(false);\n * }}\n * onRequestOtp={async (email) => {\n * const res = await authService.requestLoginOtp(email);\n * return res.success;\n * }}\n * onVerifyOtp={async (email, otp) => {\n * await authService.verifyLoginOtp(email, otp);\n * setOpen(false);\n * }}\n * onRegister={() => { setOpen(false); setRegisterOpen(true); }}\n * />\n * ```\n */\nexport const LoginPage = ({\n open,\n onOpenChange,\n onLogin,\n onRequestOtp,\n onVerifyOtp,\n onForgotPassword,\n onRegister,\n isLoading = false,\n errorMessage,\n title = 'Đăng nhập',\n subtitle = 'Nhập thông tin để tiếp tục',\n resendCooldownSeconds = 60,\n}: LoginPageProps) => {\n const emailId = useId();\n const passwordId = useId();\n const [method, setMethod] = useState<LoginMethod>('password');\n const [step, setStep] = useState<'form' | 'otp-verify'>('form');\n const [email, setEmail] = useState<string>('');\n const [password, setPassword] = useState<string>('');\n const [otp, setOtp] = useState<string>('');\n const [showPassword, setShowPassword] = useState<boolean>(false);\n const [fieldErrors, setFieldErrors] = useState<{ email?: string; password?: string }>({});\n\n useEffect(() => {\n if (!open) {\n setStep('form');\n setOtp('');\n setFieldErrors({});\n setMethod('password');\n }\n }, [open]);\n\n // Chuyển đổi giữa phương thức \"password\" và \"otp\", xoá lỗi/mật khẩu cũ\n const handleMethodChange = useCallback((value: string) => {\n if (value !== 'password' && value !== 'otp') return;\n setMethod(value as LoginMethod);\n setFieldErrors({});\n setPassword('');\n }, []);\n\n // Validate rồi gọi onLogin khi đăng nhập bằng email/mật khẩu\n const handlePasswordSubmit = useCallback(async () => {\n const result = passwordLoginSchema.safeParse({ email, password });\n if (!result.success) {\n const errors = result.error.flatten().fieldErrors;\n setFieldErrors({ email: errors.email?.[0], password: errors.password?.[0] });\n return;\n }\n setFieldErrors({});\n await onLogin(email, password);\n }, [email, password, onLogin]);\n\n // Validate email rồi gửi yêu cầu OTP, chuyển sang bước nhập mã nếu thành công\n const handleOtpRequestSubmit = useCallback(async () => {\n const result = otpRequestSchema.safeParse({ email });\n if (!result.success) {\n setFieldErrors({ email: result.error.flatten().fieldErrors.email?.[0] });\n return;\n }\n setFieldErrors({});\n const sent = await onRequestOtp(email);\n if (sent) setStep('otp-verify');\n }, [email, onRequestOtp]);\n\n // Submit form ở bước \"form\" — rẽ nhánh theo method đang chọn\n const handleSubmit = useCallback(\n async (e: React.SubmitEvent<HTMLFormElement>) => {\n e.preventDefault();\n if (method === 'password') await handlePasswordSubmit();\n else await handleOtpRequestSubmit();\n },\n [method, handlePasswordSubmit, handleOtpRequestSubmit]\n );\n\n // Gửi lại mã OTP — đếm ngược tự quản lý bên trong OtpVerifyStep\n const handleResend = useCallback(async () => {\n await onRequestOtp(email);\n }, [email, onRequestOtp]);\n\n // Xác thực mã OTP khi đã nhập đủ độ dài\n const handleVerify = useCallback(async () => {\n if (otp.length < OTP_LENGTH) return;\n await onVerifyOtp(email, otp);\n }, [email, otp, onVerifyOtp]);\n\n // Quay lại bước \"form\" từ bước nhập OTP\n const handleBackToForm = useCallback(() => {\n setOtp('');\n setStep('form');\n }, []);\n\n // Đảo trạng thái hiện/ẩn mật khẩu\n const handleToggleShowPassword = useCallback(() => setShowPassword(v => !v), []);\n\n // Đóng dialog đăng nhập\n const handleClose = useCallback(() => onOpenChange(false), [onOpenChange]);\n\n // Nội dung mô tả dialog đổi theo bước hiện tại — chỉ tính lại khi step/email/subtitle đổi\n const dialogDescription = useMemo(\n () =>\n step === 'otp-verify' ? (\n <>\n Nhập mã đăng nhập đã được gửi tới <span className=\"font-medium text-text-positive-weak\">{email}</span>. Mã có hiệu lực trong 10 phút.\n </>\n ) : (\n subtitle\n ),\n [step, email, subtitle]\n );\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent showCloseButton={false} className=\"max-sm:data-[state=open]:slide-in-from-bottom max-sm:data-[state=open]:zoom-in-100 max-sm:data-[state=closed]:slide-out-to-bottom max-sm:data-[state=closed]:zoom-out-100 max-sm:top-auto max-sm:right-0 max-sm:bottom-0 max-sm:left-0 max-sm:max-w-full max-sm:translate-x-0 max-sm:translate-y-0 max-sm:rounded-b-none sm:max-w-sm\">\n <DialogHeader>\n <LunasLogo variant=\"horizontal\" size=\"sm\" className=\"mx-auto\" />\n <div className=\"flex flex-col gap-0.5 items-center\">\n <DialogTitle>{title}</DialogTitle>\n <DialogDescription>{dialogDescription}</DialogDescription>\n </div>\n </DialogHeader>\n\n {errorMessage && (\n <Alert variant=\"destructive\">\n <AlertDescription>{errorMessage}</AlertDescription>\n </Alert>\n )}\n\n {step === 'form' ? (\n <CredentialsForm\n emailId={emailId}\n passwordId={passwordId}\n method={method}\n onMethodChange={handleMethodChange}\n email={email}\n onEmailChange={setEmail}\n password={password}\n onPasswordChange={setPassword}\n showPassword={showPassword}\n onToggleShowPassword={handleToggleShowPassword}\n fieldErrors={fieldErrors}\n isLoading={isLoading}\n onForgotPassword={onForgotPassword}\n onRegister={onRegister}\n onClose={handleClose}\n onSubmit={handleSubmit}\n />\n ) : (\n <OtpVerifyStep\n otp={otp}\n onOtpChange={setOtp}\n onComplete={handleVerify}\n isLoading={isLoading}\n resendCooldownSeconds={resendCooldownSeconds}\n onVerify={handleVerify}\n onResend={handleResend}\n onBack={handleBackToForm}\n />\n )}\n </DialogContent>\n </Dialog>\n );\n};\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ const e=require("./ui/button.cjs"),t=require("./tanstack-form-DCB2addt.cjs");let n=require("react"),r=require("@customafk/react-toolkit/utils"),i=require("react/jsx-runtime");const a=({label:a,className:o})=>{let s=t.it(),c=(0,n.useCallback)(async()=>{await s.handleSubmit({submitAction:`submit`}),s.state.isSubmitSuccessful&&s.reset()},[s]);return(0,i.jsx)(s.Subscribe,{selector:e=>({disabled:e.isPristine||!e.isValid||e.isValidating||e.isSubmitting||!e.canSubmit||e.isDefaultValue,isSubmitting:e.isSubmitting}),children:({disabled:t,isSubmitting:n})=>(0,i.jsx)(e.Button,{type:`button`,size:`md`,disabled:t,isLoading:n,className:(0,r.cn)(`min-h-8 min-w-32`,o),onClick:c,children:a??`Xác nhận`})})};exports.TanStackActionSubmit=a;
2
+ //# sourceMappingURL=action-submit-B2qFdfi6.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"action-submit-B9vHpLoN.cjs","names":["useTanStackFormContext","Button"],"sources":["../packages/components/features/tanstack-form/components/forms/action-submit.tsx"],"sourcesContent":["import { useCallback } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\n\nimport { useTanStackFormContext } from '../form-context';\n\n/**\n * Renders a submit button wired to the current TanStack Form context, automatically handling loading and disabled states.\n *\n * @example\n * import { TanStackActionSubmit } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * // Inside a TanStack Form provider:\n * <TanStackActionSubmit label=\"Save Changes\" className=\"mt-4\" />\n */\nexport const TanStackActionSubmit: React.FC<{\n /** Button label text. Defaults to `'Submit'` when omitted. */\n label?: string;\n /** Additional CSS class names applied to the button element. */\n className?: string;\n}> = ({ label, className }) => {\n const form = useTanStackFormContext();\n\n const onSubmit = useCallback(async () => {\n await form.handleSubmit({ submitAction: 'submit' });\n if (!form.state.isSubmitSuccessful) return;\n form.reset();\n }, [form]);\n return (\n <form.Subscribe\n selector={state => ({\n disabled: state.isPristine || !state.isValid || state.isValidating || state.isSubmitting || !state.canSubmit || state.isDefaultValue,\n isSubmitting: state.isSubmitting,\n })}\n children={({ disabled, isSubmitting }) => {\n return (\n <Button type=\"button\" size=\"md\" disabled={disabled} isLoading={isSubmitting} className={cn('min-h-8 min-w-32', className)} onClick={onSubmit}>\n {label ?? 'Xác nhận'}\n </Button>\n );\n }}\n />\n );\n};\n"],"mappings":"+KAiBA,MAAa,GAKP,CAAE,QAAO,eAAgB,CAC7B,IAAM,EAAOA,EAAAA,EAAuB,EAE9B,GAAA,EAAA,EAAA,YAAA,CAAuB,SAAY,CACvC,MAAM,EAAK,aAAa,CAAE,aAAc,QAAS,CAAC,EAC7C,EAAK,MAAM,oBAChB,EAAK,MAAM,CACb,EAAG,CAAC,CAAI,CAAC,EACT,OACE,EAAA,EAAA,IAAA,CAAC,EAAK,UAAN,CACE,SAAU,IAAU,CAClB,SAAU,EAAM,YAAc,CAAC,EAAM,SAAW,EAAM,cAAgB,EAAM,cAAgB,CAAC,EAAM,WAAa,EAAM,eACtH,aAAc,EAAM,YACtB,GACA,UAAW,CAAE,WAAU,mBAEnB,EAAA,EAAA,IAAA,CAACC,EAAAA,OAAD,CAAQ,KAAK,SAAS,KAAK,KAAe,WAAU,UAAW,EAAc,WAAA,EAAA,EAAA,GAAA,CAAc,mBAAoB,CAAS,EAAG,QAAS,EACjI,SAAA,GAAS,UACJ,CAAA,CAGb,CAAA,CAEL"}
1
+ {"version":3,"file":"action-submit-B2qFdfi6.cjs","names":["useTanStackFormContext","Button"],"sources":["../packages/components/features/tanstack-form/components/forms/action-submit.tsx"],"sourcesContent":["import { useCallback } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\n\nimport { useTanStackFormContext } from '../form-context';\n\n/**\n * Renders a submit button wired to the current TanStack Form context, automatically handling loading and disabled states.\n *\n * @example\n * import { TanStackActionSubmit } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * // Inside a TanStack Form provider:\n * <TanStackActionSubmit label=\"Save Changes\" className=\"mt-4\" />\n */\nexport const TanStackActionSubmit: React.FC<{\n /** Button label text. Defaults to `'Submit'` when omitted. */\n label?: string;\n /** Additional CSS class names applied to the button element. */\n className?: string;\n}> = ({ label, className }) => {\n const form = useTanStackFormContext();\n\n const onSubmit = useCallback(async () => {\n await form.handleSubmit({ submitAction: 'submit' });\n if (!form.state.isSubmitSuccessful) return;\n form.reset();\n }, [form]);\n return (\n <form.Subscribe\n selector={state => ({\n disabled: state.isPristine || !state.isValid || state.isValidating || state.isSubmitting || !state.canSubmit || state.isDefaultValue,\n isSubmitting: state.isSubmitting,\n })}\n children={({ disabled, isSubmitting }) => {\n return (\n <Button type=\"button\" size=\"md\" disabled={disabled} isLoading={isSubmitting} className={cn('min-h-8 min-w-32', className)} onClick={onSubmit}>\n {label ?? 'Xác nhận'}\n </Button>\n );\n }}\n />\n );\n};\n"],"mappings":"+KAiBA,MAAa,GAKP,CAAE,QAAO,eAAgB,CAC7B,IAAM,EAAOA,EAAAA,GAAuB,EAE9B,GAAA,EAAA,EAAA,YAAA,CAAuB,SAAY,CACvC,MAAM,EAAK,aAAa,CAAE,aAAc,QAAS,CAAC,EAC7C,EAAK,MAAM,oBAChB,EAAK,MAAM,CACb,EAAG,CAAC,CAAI,CAAC,EACT,OACE,EAAA,EAAA,IAAA,CAAC,EAAK,UAAN,CACE,SAAU,IAAU,CAClB,SAAU,EAAM,YAAc,CAAC,EAAM,SAAW,EAAM,cAAgB,EAAM,cAAgB,CAAC,EAAM,WAAa,EAAM,eACtH,aAAc,EAAM,YACtB,GACA,UAAW,CAAE,WAAU,mBAEnB,EAAA,EAAA,IAAA,CAACC,EAAAA,OAAD,CAAQ,KAAK,SAAS,KAAK,KAAe,WAAU,UAAW,EAAc,WAAA,EAAA,EAAA,GAAA,CAAc,mBAAoB,CAAS,EAAG,QAAS,EACjI,SAAA,GAAS,UACJ,CAAA,CAGb,CAAA,CAEL"}
@@ -0,0 +1,2 @@
1
+ import{it as e}from"./tanstack-form-BhKAn9I0.mjs";import{Button as t}from"./ui/button.mjs";import{useCallback as n}from"react";import{cn as r}from"@customafk/react-toolkit/utils";import{jsx as i}from"react/jsx-runtime";const a=({label:a,className:o})=>{let s=e(),c=n(async()=>{await s.handleSubmit({submitAction:`submit`}),s.state.isSubmitSuccessful&&s.reset()},[s]);return i(s.Subscribe,{selector:e=>({disabled:e.isPristine||!e.isValid||e.isValidating||e.isSubmitting||!e.canSubmit||e.isDefaultValue,isSubmitting:e.isSubmitting}),children:({disabled:e,isSubmitting:n})=>i(t,{type:`button`,size:`md`,disabled:e,isLoading:n,className:r(`min-h-8 min-w-32`,o),onClick:c,children:a??`Xác nhận`})})};export{a as TanStackActionSubmit};
2
+ //# sourceMappingURL=action-submit-DyNvI-F2.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"action-submit-BQdkz4mS.mjs","names":[],"sources":["../packages/components/features/tanstack-form/components/forms/action-submit.tsx"],"sourcesContent":["import { useCallback } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\n\nimport { useTanStackFormContext } from '../form-context';\n\n/**\n * Renders a submit button wired to the current TanStack Form context, automatically handling loading and disabled states.\n *\n * @example\n * import { TanStackActionSubmit } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * // Inside a TanStack Form provider:\n * <TanStackActionSubmit label=\"Save Changes\" className=\"mt-4\" />\n */\nexport const TanStackActionSubmit: React.FC<{\n /** Button label text. Defaults to `'Submit'` when omitted. */\n label?: string;\n /** Additional CSS class names applied to the button element. */\n className?: string;\n}> = ({ label, className }) => {\n const form = useTanStackFormContext();\n\n const onSubmit = useCallback(async () => {\n await form.handleSubmit({ submitAction: 'submit' });\n if (!form.state.isSubmitSuccessful) return;\n form.reset();\n }, [form]);\n return (\n <form.Subscribe\n selector={state => ({\n disabled: state.isPristine || !state.isValid || state.isValidating || state.isSubmitting || !state.canSubmit || state.isDefaultValue,\n isSubmitting: state.isSubmitting,\n })}\n children={({ disabled, isSubmitting }) => {\n return (\n <Button type=\"button\" size=\"md\" disabled={disabled} isLoading={isSubmitting} className={cn('min-h-8 min-w-32', className)} onClick={onSubmit}>\n {label ?? 'Xác nhận'}\n </Button>\n );\n }}\n />\n );\n};\n"],"mappings":"0NAiBA,MAAa,GAKP,CAAE,QAAO,eAAgB,CAC7B,IAAM,EAAO,EAAuB,EAE9B,EAAW,EAAY,SAAY,CACvC,MAAM,EAAK,aAAa,CAAE,aAAc,QAAS,CAAC,EAC7C,EAAK,MAAM,oBAChB,EAAK,MAAM,CACb,EAAG,CAAC,CAAI,CAAC,EACT,OACE,EAAC,EAAK,UAAN,CACE,SAAU,IAAU,CAClB,SAAU,EAAM,YAAc,CAAC,EAAM,SAAW,EAAM,cAAgB,EAAM,cAAgB,CAAC,EAAM,WAAa,EAAM,eACtH,aAAc,EAAM,YACtB,GACA,UAAW,CAAE,WAAU,kBAEnB,EAAC,EAAD,CAAQ,KAAK,SAAS,KAAK,KAAe,WAAU,UAAW,EAAc,UAAW,EAAG,mBAAoB,CAAS,EAAG,QAAS,EACjI,SAAA,GAAS,UACJ,CAAA,CAGb,CAAA,CAEL"}
1
+ {"version":3,"file":"action-submit-DyNvI-F2.mjs","names":[],"sources":["../packages/components/features/tanstack-form/components/forms/action-submit.tsx"],"sourcesContent":["import { useCallback } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\n\nimport { useTanStackFormContext } from '../form-context';\n\n/**\n * Renders a submit button wired to the current TanStack Form context, automatically handling loading and disabled states.\n *\n * @example\n * import { TanStackActionSubmit } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * // Inside a TanStack Form provider:\n * <TanStackActionSubmit label=\"Save Changes\" className=\"mt-4\" />\n */\nexport const TanStackActionSubmit: React.FC<{\n /** Button label text. Defaults to `'Submit'` when omitted. */\n label?: string;\n /** Additional CSS class names applied to the button element. */\n className?: string;\n}> = ({ label, className }) => {\n const form = useTanStackFormContext();\n\n const onSubmit = useCallback(async () => {\n await form.handleSubmit({ submitAction: 'submit' });\n if (!form.state.isSubmitSuccessful) return;\n form.reset();\n }, [form]);\n return (\n <form.Subscribe\n selector={state => ({\n disabled: state.isPristine || !state.isValid || state.isValidating || state.isSubmitting || !state.canSubmit || state.isDefaultValue,\n isSubmitting: state.isSubmitting,\n })}\n children={({ disabled, isSubmitting }) => {\n return (\n <Button type=\"button\" size=\"md\" disabled={disabled} isLoading={isSubmitting} className={cn('min-h-8 min-w-32', className)} onClick={onSubmit}>\n {label ?? 'Xác nhận'}\n </Button>\n );\n }}\n />\n );\n};\n"],"mappings":"2NAiBA,MAAa,GAKP,CAAE,QAAO,eAAgB,CAC7B,IAAM,EAAO,EAAuB,EAE9B,EAAW,EAAY,SAAY,CACvC,MAAM,EAAK,aAAa,CAAE,aAAc,QAAS,CAAC,EAC7C,EAAK,MAAM,oBAChB,EAAK,MAAM,CACb,EAAG,CAAC,CAAI,CAAC,EACT,OACE,EAAC,EAAK,UAAN,CACE,SAAU,IAAU,CAClB,SAAU,EAAM,YAAc,CAAC,EAAM,SAAW,EAAM,cAAgB,EAAM,cAAgB,CAAC,EAAM,WAAa,EAAM,eACtH,aAAc,EAAM,YACtB,GACA,UAAW,CAAE,WAAU,kBAEnB,EAAC,EAAD,CAAQ,KAAK,SAAS,KAAK,KAAe,WAAU,UAAW,EAAc,UAAW,EAAG,mBAAoB,CAAS,EAAG,QAAS,EACjI,SAAA,GAAS,UACJ,CAAA,CAGb,CAAA,CAEL"}
@@ -0,0 +1,2 @@
1
+ import{it as e}from"./tanstack-form-BhKAn9I0.mjs";import{Button as t}from"./ui/button.mjs";import{ArrowDownToLine as n,PlusIcon as r}from"lucide-react";import{jsx as i,jsxs as a}from"react/jsx-runtime";const o=({type:o=`create`})=>{let s=e();return a(`div`,{className:`flex h-8 items-center justify-between`,children:[i(s.Subscribe,{selector:e=>({disabled:e.isPristine||e.isSubmitting}),children:({disabled:e})=>i(t,{color:`muted`,variant:`outline`,type:`button`,size:`md`,disabled:e,className:`h-full min-w-32`,onClick:()=>s.reset(),children:`Hủy bỏ`})}),o===`create`&&i(s.Subscribe,{selector:e=>({disabled:e.isPristine||!e.isValid||e.isValidating||e.isSubmitting||!e.canSubmit||e.isDefaultValue,isSubmitting:e.isSubmitting}),children:({disabled:e,isSubmitting:n})=>a(t,{type:`submit`,size:`md`,disabled:e,isLoading:n,className:`h-full min-w-32`,onClick:async()=>{await s.handleSubmit({submitAction:`create`}),s.state.isSubmitSuccessful&&s.reset()},children:[i(r,{}),`Thêm mới`]})}),o===`update`&&i(s.Subscribe,{selector:e=>({disabled:e.isPristine||!e.isValid||e.isValidating||e.isSubmitting||!e.canSubmit||e.isDefaultValue,isSubmitting:e.isSubmitting}),children:({disabled:e,isSubmitting:r})=>a(t,{type:`submit`,size:`md`,disabled:e,isLoading:r,className:`h-full min-w-32`,onClick:async()=>{await s.handleSubmit({submitAction:`update`}),s.state.isSubmitSuccessful&&s.reset()},children:[i(n,{}),`Cập nhật`]})})]})};export{o as TanStackActionsForm};
2
+ //# sourceMappingURL=actions-form-CB0lZlE6.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"actions-form-D4n1W3-X.mjs","names":[],"sources":["../packages/components/features/tanstack-form/components/forms/actions-form.tsx"],"sourcesContent":["import { ArrowDownToLine, PlusIcon } from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\n\nimport { useTanStackFormContext } from '../form-context';\n\n/**\n * Renders a form action bar with a Cancel button and a context-aware submit button (Add New or Update) driven by TanStack Form state.\n *\n * @example\n * import { TanStackActionsForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * // Inside a TanStack Form provider:\n * <TanStackActionsForm type=\"create\" />\n *\n * // For an update workflow:\n * <TanStackActionsForm type=\"update\" />\n */\nexport const TanStackActionsForm: React.FC<\n React.PropsWithChildren<{\n /**\n * Determines which submit button variant is rendered.\n * - `'create'` — shows an \"Add New\" button that resets the form on success.\n * - `'update'` — shows an \"Update\" button that resets the form on success.\n * Defaults to `'create'`.\n */\n type?: 'create' | 'update';\n }>\n> = ({ type = 'create' }) => {\n const form = useTanStackFormContext();\n return (\n <div className=\"flex h-8 items-center justify-between\">\n <form.Subscribe\n selector={state => ({\n disabled: state.isPristine || state.isSubmitting,\n })}\n children={({ disabled }) => {\n return (\n <Button color=\"muted\" variant=\"outline\" type=\"button\" size=\"md\" disabled={disabled} className=\"h-full min-w-32\" onClick={() => form.reset()}>\n Hủy bỏ\n </Button>\n );\n }}\n />\n {type === 'create' && (\n <form.Subscribe\n selector={state => ({\n disabled: state.isPristine || !state.isValid || state.isValidating || state.isSubmitting || !state.canSubmit || state.isDefaultValue,\n isSubmitting: state.isSubmitting,\n })}\n children={({ disabled, isSubmitting }) => {\n return (\n <Button\n type=\"submit\"\n size=\"md\"\n disabled={disabled}\n isLoading={isSubmitting}\n className=\"h-full min-w-32\"\n onClick={async () => {\n await form.handleSubmit({ submitAction: 'create' });\n if (!form.state.isSubmitSuccessful) return;\n form.reset();\n }}\n >\n <PlusIcon />\n Thêm mới\n </Button>\n );\n }}\n />\n )}\n {type === 'update' && (\n <form.Subscribe\n selector={state => ({\n disabled: state.isPristine || !state.isValid || state.isValidating || state.isSubmitting || !state.canSubmit || state.isDefaultValue,\n isSubmitting: state.isSubmitting,\n })}\n children={({ disabled, isSubmitting }) => {\n return (\n <Button\n type=\"submit\"\n size=\"md\"\n disabled={disabled}\n isLoading={isSubmitting}\n className=\"h-full min-w-32\"\n onClick={async () => {\n await form.handleSubmit({ submitAction: 'update' });\n if (!form.state.isSubmitSuccessful) return;\n form.reset();\n }}\n >\n <ArrowDownToLine />\n Cập nhật\n </Button>\n );\n }}\n />\n )}\n </div>\n );\n};\n"],"mappings":"yMAkBA,MAAa,GAUR,CAAE,OAAO,YAAe,CAC3B,IAAM,EAAO,EAAuB,EACpC,OACE,EAAC,MAAD,CAAK,UAAU,wCAAf,SAAA,CACE,EAAC,EAAK,UAAN,CACE,SAAU,IAAU,CAClB,SAAU,EAAM,YAAc,EAAM,YACtC,GACA,UAAW,CAAE,cAET,EAAC,EAAD,CAAQ,MAAM,QAAQ,QAAQ,UAAU,KAAK,SAAS,KAAK,KAAe,WAAU,UAAU,kBAAkB,YAAe,EAAK,MAAM,EAAG,SAAA,QAErI,CAAA,CAGb,CAAA,EACA,IAAS,UACR,EAAC,EAAK,UAAN,CACE,SAAU,IAAU,CAClB,SAAU,EAAM,YAAc,CAAC,EAAM,SAAW,EAAM,cAAgB,EAAM,cAAgB,CAAC,EAAM,WAAa,EAAM,eACtH,aAAc,EAAM,YACtB,GACA,UAAW,CAAE,WAAU,kBAEnB,EAAC,EAAD,CACE,KAAK,SACL,KAAK,KACK,WACV,UAAW,EACX,UAAU,kBACV,QAAS,SAAY,CACnB,MAAM,EAAK,aAAa,CAAE,aAAc,QAAS,CAAC,EAC7C,EAAK,MAAM,oBAChB,EAAK,MAAM,CACb,EAVF,SAAA,CAYE,EAAC,EAAD,CAAW,CAAA,EAAC,UAEN,GAGb,CAAA,EAEF,IAAS,UACR,EAAC,EAAK,UAAN,CACE,SAAU,IAAU,CAClB,SAAU,EAAM,YAAc,CAAC,EAAM,SAAW,EAAM,cAAgB,EAAM,cAAgB,CAAC,EAAM,WAAa,EAAM,eACtH,aAAc,EAAM,YACtB,GACA,UAAW,CAAE,WAAU,kBAEnB,EAAC,EAAD,CACE,KAAK,SACL,KAAK,KACK,WACV,UAAW,EACX,UAAU,kBACV,QAAS,SAAY,CACnB,MAAM,EAAK,aAAa,CAAE,aAAc,QAAS,CAAC,EAC7C,EAAK,MAAM,oBAChB,EAAK,MAAM,CACb,EAVF,SAAA,CAYE,EAAC,EAAD,CAAkB,CAAA,EAAC,UAEb,GAGb,CAAA,CAEA,GAET"}
1
+ {"version":3,"file":"actions-form-CB0lZlE6.mjs","names":[],"sources":["../packages/components/features/tanstack-form/components/forms/actions-form.tsx"],"sourcesContent":["import { ArrowDownToLine, PlusIcon } from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\n\nimport { useTanStackFormContext } from '../form-context';\n\n/**\n * Renders a form action bar with a Cancel button and a context-aware submit button (Add New or Update) driven by TanStack Form state.\n *\n * @example\n * import { TanStackActionsForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * // Inside a TanStack Form provider:\n * <TanStackActionsForm type=\"create\" />\n *\n * // For an update workflow:\n * <TanStackActionsForm type=\"update\" />\n */\nexport const TanStackActionsForm: React.FC<\n React.PropsWithChildren<{\n /**\n * Determines which submit button variant is rendered.\n * - `'create'` — shows an \"Add New\" button that resets the form on success.\n * - `'update'` — shows an \"Update\" button that resets the form on success.\n * Defaults to `'create'`.\n */\n type?: 'create' | 'update';\n }>\n> = ({ type = 'create' }) => {\n const form = useTanStackFormContext();\n return (\n <div className=\"flex h-8 items-center justify-between\">\n <form.Subscribe\n selector={state => ({\n disabled: state.isPristine || state.isSubmitting,\n })}\n children={({ disabled }) => {\n return (\n <Button color=\"muted\" variant=\"outline\" type=\"button\" size=\"md\" disabled={disabled} className=\"h-full min-w-32\" onClick={() => form.reset()}>\n Hủy bỏ\n </Button>\n );\n }}\n />\n {type === 'create' && (\n <form.Subscribe\n selector={state => ({\n disabled: state.isPristine || !state.isValid || state.isValidating || state.isSubmitting || !state.canSubmit || state.isDefaultValue,\n isSubmitting: state.isSubmitting,\n })}\n children={({ disabled, isSubmitting }) => {\n return (\n <Button\n type=\"submit\"\n size=\"md\"\n disabled={disabled}\n isLoading={isSubmitting}\n className=\"h-full min-w-32\"\n onClick={async () => {\n await form.handleSubmit({ submitAction: 'create' });\n if (!form.state.isSubmitSuccessful) return;\n form.reset();\n }}\n >\n <PlusIcon />\n Thêm mới\n </Button>\n );\n }}\n />\n )}\n {type === 'update' && (\n <form.Subscribe\n selector={state => ({\n disabled: state.isPristine || !state.isValid || state.isValidating || state.isSubmitting || !state.canSubmit || state.isDefaultValue,\n isSubmitting: state.isSubmitting,\n })}\n children={({ disabled, isSubmitting }) => {\n return (\n <Button\n type=\"submit\"\n size=\"md\"\n disabled={disabled}\n isLoading={isSubmitting}\n className=\"h-full min-w-32\"\n onClick={async () => {\n await form.handleSubmit({ submitAction: 'update' });\n if (!form.state.isSubmitSuccessful) return;\n form.reset();\n }}\n >\n <ArrowDownToLine />\n Cập nhật\n </Button>\n );\n }}\n />\n )}\n </div>\n );\n};\n"],"mappings":"0MAkBA,MAAa,GAUR,CAAE,OAAO,YAAe,CAC3B,IAAM,EAAO,EAAuB,EACpC,OACE,EAAC,MAAD,CAAK,UAAU,wCAAf,SAAA,CACE,EAAC,EAAK,UAAN,CACE,SAAU,IAAU,CAClB,SAAU,EAAM,YAAc,EAAM,YACtC,GACA,UAAW,CAAE,cAET,EAAC,EAAD,CAAQ,MAAM,QAAQ,QAAQ,UAAU,KAAK,SAAS,KAAK,KAAe,WAAU,UAAU,kBAAkB,YAAe,EAAK,MAAM,EAAG,SAAA,QAErI,CAAA,CAGb,CAAA,EACA,IAAS,UACR,EAAC,EAAK,UAAN,CACE,SAAU,IAAU,CAClB,SAAU,EAAM,YAAc,CAAC,EAAM,SAAW,EAAM,cAAgB,EAAM,cAAgB,CAAC,EAAM,WAAa,EAAM,eACtH,aAAc,EAAM,YACtB,GACA,UAAW,CAAE,WAAU,kBAEnB,EAAC,EAAD,CACE,KAAK,SACL,KAAK,KACK,WACV,UAAW,EACX,UAAU,kBACV,QAAS,SAAY,CACnB,MAAM,EAAK,aAAa,CAAE,aAAc,QAAS,CAAC,EAC7C,EAAK,MAAM,oBAChB,EAAK,MAAM,CACb,EAVF,SAAA,CAYE,EAAC,EAAD,CAAW,CAAA,EAAC,UAEN,GAGb,CAAA,EAEF,IAAS,UACR,EAAC,EAAK,UAAN,CACE,SAAU,IAAU,CAClB,SAAU,EAAM,YAAc,CAAC,EAAM,SAAW,EAAM,cAAgB,EAAM,cAAgB,CAAC,EAAM,WAAa,EAAM,eACtH,aAAc,EAAM,YACtB,GACA,UAAW,CAAE,WAAU,kBAEnB,EAAC,EAAD,CACE,KAAK,SACL,KAAK,KACK,WACV,UAAW,EACX,UAAU,kBACV,QAAS,SAAY,CACnB,MAAM,EAAK,aAAa,CAAE,aAAc,QAAS,CAAC,EAC7C,EAAK,MAAM,oBAChB,EAAK,MAAM,CACb,EAVF,SAAA,CAYE,EAAC,EAAD,CAAkB,CAAA,EAAC,UAEb,GAGb,CAAA,CAEA,GAET"}
@@ -0,0 +1,2 @@
1
+ const e=require("./ui/button.cjs"),t=require("./tanstack-form-DCB2addt.cjs");let n=require("lucide-react"),r=require("react/jsx-runtime");const i=({type:i=`create`})=>{let a=t.it();return(0,r.jsxs)(`div`,{className:`flex h-8 items-center justify-between`,children:[(0,r.jsx)(a.Subscribe,{selector:e=>({disabled:e.isPristine||e.isSubmitting}),children:({disabled:t})=>(0,r.jsx)(e.Button,{color:`muted`,variant:`outline`,type:`button`,size:`md`,disabled:t,className:`h-full min-w-32`,onClick:()=>a.reset(),children:`Hủy bỏ`})}),i===`create`&&(0,r.jsx)(a.Subscribe,{selector:e=>({disabled:e.isPristine||!e.isValid||e.isValidating||e.isSubmitting||!e.canSubmit||e.isDefaultValue,isSubmitting:e.isSubmitting}),children:({disabled:t,isSubmitting:i})=>(0,r.jsxs)(e.Button,{type:`submit`,size:`md`,disabled:t,isLoading:i,className:`h-full min-w-32`,onClick:async()=>{await a.handleSubmit({submitAction:`create`}),a.state.isSubmitSuccessful&&a.reset()},children:[(0,r.jsx)(n.PlusIcon,{}),`Thêm mới`]})}),i===`update`&&(0,r.jsx)(a.Subscribe,{selector:e=>({disabled:e.isPristine||!e.isValid||e.isValidating||e.isSubmitting||!e.canSubmit||e.isDefaultValue,isSubmitting:e.isSubmitting}),children:({disabled:t,isSubmitting:i})=>(0,r.jsxs)(e.Button,{type:`submit`,size:`md`,disabled:t,isLoading:i,className:`h-full min-w-32`,onClick:async()=>{await a.handleSubmit({submitAction:`update`}),a.state.isSubmitSuccessful&&a.reset()},children:[(0,r.jsx)(n.ArrowDownToLine,{}),`Cập nhật`]})})]})};exports.TanStackActionsForm=i;
2
+ //# sourceMappingURL=actions-form-DnlpVrgF.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"actions-form-DF2eYxGQ.cjs","names":["useTanStackFormContext","Button","PlusIcon","ArrowDownToLine"],"sources":["../packages/components/features/tanstack-form/components/forms/actions-form.tsx"],"sourcesContent":["import { ArrowDownToLine, PlusIcon } from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\n\nimport { useTanStackFormContext } from '../form-context';\n\n/**\n * Renders a form action bar with a Cancel button and a context-aware submit button (Add New or Update) driven by TanStack Form state.\n *\n * @example\n * import { TanStackActionsForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * // Inside a TanStack Form provider:\n * <TanStackActionsForm type=\"create\" />\n *\n * // For an update workflow:\n * <TanStackActionsForm type=\"update\" />\n */\nexport const TanStackActionsForm: React.FC<\n React.PropsWithChildren<{\n /**\n * Determines which submit button variant is rendered.\n * - `'create'` — shows an \"Add New\" button that resets the form on success.\n * - `'update'` — shows an \"Update\" button that resets the form on success.\n * Defaults to `'create'`.\n */\n type?: 'create' | 'update';\n }>\n> = ({ type = 'create' }) => {\n const form = useTanStackFormContext();\n return (\n <div className=\"flex h-8 items-center justify-between\">\n <form.Subscribe\n selector={state => ({\n disabled: state.isPristine || state.isSubmitting,\n })}\n children={({ disabled }) => {\n return (\n <Button color=\"muted\" variant=\"outline\" type=\"button\" size=\"md\" disabled={disabled} className=\"h-full min-w-32\" onClick={() => form.reset()}>\n Hủy bỏ\n </Button>\n );\n }}\n />\n {type === 'create' && (\n <form.Subscribe\n selector={state => ({\n disabled: state.isPristine || !state.isValid || state.isValidating || state.isSubmitting || !state.canSubmit || state.isDefaultValue,\n isSubmitting: state.isSubmitting,\n })}\n children={({ disabled, isSubmitting }) => {\n return (\n <Button\n type=\"submit\"\n size=\"md\"\n disabled={disabled}\n isLoading={isSubmitting}\n className=\"h-full min-w-32\"\n onClick={async () => {\n await form.handleSubmit({ submitAction: 'create' });\n if (!form.state.isSubmitSuccessful) return;\n form.reset();\n }}\n >\n <PlusIcon />\n Thêm mới\n </Button>\n );\n }}\n />\n )}\n {type === 'update' && (\n <form.Subscribe\n selector={state => ({\n disabled: state.isPristine || !state.isValid || state.isValidating || state.isSubmitting || !state.canSubmit || state.isDefaultValue,\n isSubmitting: state.isSubmitting,\n })}\n children={({ disabled, isSubmitting }) => {\n return (\n <Button\n type=\"submit\"\n size=\"md\"\n disabled={disabled}\n isLoading={isSubmitting}\n className=\"h-full min-w-32\"\n onClick={async () => {\n await form.handleSubmit({ submitAction: 'update' });\n if (!form.state.isSubmitSuccessful) return;\n form.reset();\n }}\n >\n <ArrowDownToLine />\n Cập nhật\n </Button>\n );\n }}\n />\n )}\n </div>\n );\n};\n"],"mappings":"0IAkBA,MAAa,GAUR,CAAE,OAAO,YAAe,CAC3B,IAAM,EAAOA,EAAAA,EAAuB,EACpC,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,wCAAf,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,EAAK,UAAN,CACE,SAAU,IAAU,CAClB,SAAU,EAAM,YAAc,EAAM,YACtC,GACA,UAAW,CAAE,eAET,EAAA,EAAA,IAAA,CAACC,EAAAA,OAAD,CAAQ,MAAM,QAAQ,QAAQ,UAAU,KAAK,SAAS,KAAK,KAAe,WAAU,UAAU,kBAAkB,YAAe,EAAK,MAAM,EAAG,SAAA,QAErI,CAAA,CAGb,CAAA,EACA,IAAS,WACR,EAAA,EAAA,IAAA,CAAC,EAAK,UAAN,CACE,SAAU,IAAU,CAClB,SAAU,EAAM,YAAc,CAAC,EAAM,SAAW,EAAM,cAAgB,EAAM,cAAgB,CAAC,EAAM,WAAa,EAAM,eACtH,aAAc,EAAM,YACtB,GACA,UAAW,CAAE,WAAU,mBAEnB,EAAA,EAAA,KAAA,CAACA,EAAAA,OAAD,CACE,KAAK,SACL,KAAK,KACK,WACV,UAAW,EACX,UAAU,kBACV,QAAS,SAAY,CACnB,MAAM,EAAK,aAAa,CAAE,aAAc,QAAS,CAAC,EAC7C,EAAK,MAAM,oBAChB,EAAK,MAAM,CACb,EAVF,SAAA,EAYE,EAAA,EAAA,IAAA,CAACC,EAAAA,SAAD,CAAW,CAAA,EAAC,UAEN,GAGb,CAAA,EAEF,IAAS,WACR,EAAA,EAAA,IAAA,CAAC,EAAK,UAAN,CACE,SAAU,IAAU,CAClB,SAAU,EAAM,YAAc,CAAC,EAAM,SAAW,EAAM,cAAgB,EAAM,cAAgB,CAAC,EAAM,WAAa,EAAM,eACtH,aAAc,EAAM,YACtB,GACA,UAAW,CAAE,WAAU,mBAEnB,EAAA,EAAA,KAAA,CAACD,EAAAA,OAAD,CACE,KAAK,SACL,KAAK,KACK,WACV,UAAW,EACX,UAAU,kBACV,QAAS,SAAY,CACnB,MAAM,EAAK,aAAa,CAAE,aAAc,QAAS,CAAC,EAC7C,EAAK,MAAM,oBAChB,EAAK,MAAM,CACb,EAVF,SAAA,EAYE,EAAA,EAAA,IAAA,CAACE,EAAAA,gBAAD,CAAkB,CAAA,EAAC,UAEb,GAGb,CAAA,CAEA,GAET"}
1
+ {"version":3,"file":"actions-form-DnlpVrgF.cjs","names":["useTanStackFormContext","Button","PlusIcon","ArrowDownToLine"],"sources":["../packages/components/features/tanstack-form/components/forms/actions-form.tsx"],"sourcesContent":["import { ArrowDownToLine, PlusIcon } from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\n\nimport { useTanStackFormContext } from '../form-context';\n\n/**\n * Renders a form action bar with a Cancel button and a context-aware submit button (Add New or Update) driven by TanStack Form state.\n *\n * @example\n * import { TanStackActionsForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * // Inside a TanStack Form provider:\n * <TanStackActionsForm type=\"create\" />\n *\n * // For an update workflow:\n * <TanStackActionsForm type=\"update\" />\n */\nexport const TanStackActionsForm: React.FC<\n React.PropsWithChildren<{\n /**\n * Determines which submit button variant is rendered.\n * - `'create'` — shows an \"Add New\" button that resets the form on success.\n * - `'update'` — shows an \"Update\" button that resets the form on success.\n * Defaults to `'create'`.\n */\n type?: 'create' | 'update';\n }>\n> = ({ type = 'create' }) => {\n const form = useTanStackFormContext();\n return (\n <div className=\"flex h-8 items-center justify-between\">\n <form.Subscribe\n selector={state => ({\n disabled: state.isPristine || state.isSubmitting,\n })}\n children={({ disabled }) => {\n return (\n <Button color=\"muted\" variant=\"outline\" type=\"button\" size=\"md\" disabled={disabled} className=\"h-full min-w-32\" onClick={() => form.reset()}>\n Hủy bỏ\n </Button>\n );\n }}\n />\n {type === 'create' && (\n <form.Subscribe\n selector={state => ({\n disabled: state.isPristine || !state.isValid || state.isValidating || state.isSubmitting || !state.canSubmit || state.isDefaultValue,\n isSubmitting: state.isSubmitting,\n })}\n children={({ disabled, isSubmitting }) => {\n return (\n <Button\n type=\"submit\"\n size=\"md\"\n disabled={disabled}\n isLoading={isSubmitting}\n className=\"h-full min-w-32\"\n onClick={async () => {\n await form.handleSubmit({ submitAction: 'create' });\n if (!form.state.isSubmitSuccessful) return;\n form.reset();\n }}\n >\n <PlusIcon />\n Thêm mới\n </Button>\n );\n }}\n />\n )}\n {type === 'update' && (\n <form.Subscribe\n selector={state => ({\n disabled: state.isPristine || !state.isValid || state.isValidating || state.isSubmitting || !state.canSubmit || state.isDefaultValue,\n isSubmitting: state.isSubmitting,\n })}\n children={({ disabled, isSubmitting }) => {\n return (\n <Button\n type=\"submit\"\n size=\"md\"\n disabled={disabled}\n isLoading={isSubmitting}\n className=\"h-full min-w-32\"\n onClick={async () => {\n await form.handleSubmit({ submitAction: 'update' });\n if (!form.state.isSubmitSuccessful) return;\n form.reset();\n }}\n >\n <ArrowDownToLine />\n Cập nhật\n </Button>\n );\n }}\n />\n )}\n </div>\n );\n};\n"],"mappings":"0IAkBA,MAAa,GAUR,CAAE,OAAO,YAAe,CAC3B,IAAM,EAAOA,EAAAA,GAAuB,EACpC,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,wCAAf,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,EAAK,UAAN,CACE,SAAU,IAAU,CAClB,SAAU,EAAM,YAAc,EAAM,YACtC,GACA,UAAW,CAAE,eAET,EAAA,EAAA,IAAA,CAACC,EAAAA,OAAD,CAAQ,MAAM,QAAQ,QAAQ,UAAU,KAAK,SAAS,KAAK,KAAe,WAAU,UAAU,kBAAkB,YAAe,EAAK,MAAM,EAAG,SAAA,QAErI,CAAA,CAGb,CAAA,EACA,IAAS,WACR,EAAA,EAAA,IAAA,CAAC,EAAK,UAAN,CACE,SAAU,IAAU,CAClB,SAAU,EAAM,YAAc,CAAC,EAAM,SAAW,EAAM,cAAgB,EAAM,cAAgB,CAAC,EAAM,WAAa,EAAM,eACtH,aAAc,EAAM,YACtB,GACA,UAAW,CAAE,WAAU,mBAEnB,EAAA,EAAA,KAAA,CAACA,EAAAA,OAAD,CACE,KAAK,SACL,KAAK,KACK,WACV,UAAW,EACX,UAAU,kBACV,QAAS,SAAY,CACnB,MAAM,EAAK,aAAa,CAAE,aAAc,QAAS,CAAC,EAC7C,EAAK,MAAM,oBAChB,EAAK,MAAM,CACb,EAVF,SAAA,EAYE,EAAA,EAAA,IAAA,CAACC,EAAAA,SAAD,CAAW,CAAA,EAAC,UAEN,GAGb,CAAA,EAEF,IAAS,WACR,EAAA,EAAA,IAAA,CAAC,EAAK,UAAN,CACE,SAAU,IAAU,CAClB,SAAU,EAAM,YAAc,CAAC,EAAM,SAAW,EAAM,cAAgB,EAAM,cAAgB,CAAC,EAAM,WAAa,EAAM,eACtH,aAAc,EAAM,YACtB,GACA,UAAW,CAAE,WAAU,mBAEnB,EAAA,EAAA,KAAA,CAACD,EAAAA,OAAD,CACE,KAAK,SACL,KAAK,KACK,WACV,UAAW,EACX,UAAU,kBACV,QAAS,SAAY,CACnB,MAAM,EAAK,aAAa,CAAE,aAAc,QAAS,CAAC,EAC7C,EAAK,MAAM,oBAChB,EAAK,MAAM,CACb,EAVF,SAAA,EAYE,EAAA,EAAA,IAAA,CAACE,EAAAA,gBAAD,CAAkB,CAAA,EAAC,UAEb,GAGb,CAAA,CAEA,GAET"}
@@ -0,0 +1,2 @@
1
+ const e=require("./ui/checkbox.cjs"),t=require("./tanstack-form-DCB2addt.cjs");let n=require("react/jsx-runtime"),r=require("@tanstack/react-form");const i=({label:i,description:a,options:o,tooltip:s,helperText:c,orientation:l})=>{let u=t.rt(),d=(0,r.useStore)(u.form.store,({isSubmitting:e})=>e);return(0,n.jsxs)(t.X,{className:`gap-y-4 px-4`,children:[(0,n.jsxs)(t.G,{orientation:l,children:[(0,n.jsxs)(t.K,{children:[(0,n.jsxs)(t.Z,{children:[i,s&&(0,n.jsx)(t.nt,{tooltip:s})]}),(0,n.jsx)(t.J,{children:a}),(0,n.jsx)(t.$,{isShow:!!c,children:c})]}),(0,n.jsx)(t.q,{children:(0,n.jsx)(t.X,{className:`flex flex-col gap-y-2`,children:o.map(r=>(0,n.jsxs)(t.G,{orientation:`horizontal`,children:[(0,n.jsx)(e.Checkbox,{id:`${u.name}-${r.value}`,name:u.name,checked:u.state.value?.includes(r.value)??!1,disabled:d,onCheckedChange:e=>{if(e&&u.state.value!==null)u.pushValue(r.value);else if(e&&u.state.value===null)u.setValue([r.value]);else if(!e&&u.state.value!==null){let e=u.state.value.indexOf(r.value);e>-1&&u.removeValue(e)}else u.setValue(null)}}),(0,n.jsx)(t.Z,{htmlFor:`${u.name}-${r.value}`,className:`text-text-positive`,children:r.label})]},r.value))})})]}),(0,n.jsx)(t.et,{})]})};exports.CheckboxField=i;
2
+ //# sourceMappingURL=checkbox-field-CFPHAcwN.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"checkbox-field-ldZRSCca.cjs","names":["useTanStackFieldContext","FieldGroup","Field","FieldContent","FieldLabel","FieldTooltip","FieldDescription","FieldNote","FieldContentMain","Checkbox","FieldSeparator"],"sources":["../packages/components/features/tanstack-form/components/fields/checkbox-field.tsx"],"sourcesContent":["'use client';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { useTanStackFieldContext } from '../form-context';\nimport { Field, FieldContent, FieldContentMain, FieldDescription, FieldGroup, FieldLabel, FieldNote, FieldSeparator, FieldTooltip } from '../ui/field';\nimport { Checkbox } from '@/components/ui/checkbox';\n\nimport type { CheckboxFieldProps as Props } from '../../types';\n\n/**\n * A TanStack Form-connected checkbox group field that manages an array of selected string values,\n * supporting multi-selection and submission-state disabling.\n *\n * @example\n * import { CheckboxField } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <form.Field name=\"roles\">\n * {() => (\n * <CheckboxField\n * label=\"Roles\"\n * options={[\n * { value: 'admin', label: 'Admin' },\n * { value: 'editor', label: 'Editor' },\n * ]}\n * helperText=\"Select one or more roles\"\n * />\n * )}\n * </form.Field>\n */\nexport const CheckboxField: React.FC<Props> = ({ label, description, options, tooltip, helperText, orientation }) => {\n const field = useTanStackFieldContext<string[] | null>();\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation={orientation}>\n <FieldContent>\n <FieldLabel>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </FieldContent>\n <FieldContentMain>\n <FieldGroup className=\"flex flex-col gap-y-2\">\n {options.map(option => {\n return (\n <Field key={option.value} orientation=\"horizontal\">\n <Checkbox\n id={`${field.name}-${option.value}`}\n name={field.name}\n checked={field.state.value?.includes(option.value) ?? false}\n disabled={isSubmitting}\n onCheckedChange={checked => {\n if (checked && field.state.value !== null) {\n field.pushValue(option.value);\n } else if (checked && field.state.value === null) {\n field.setValue([option.value]);\n } else if (!checked && field.state.value !== null) {\n const index = field.state.value.indexOf(option.value);\n if (index > -1) field.removeValue(index);\n } else {\n field.setValue(null);\n }\n }}\n />\n <FieldLabel htmlFor={`${field.name}-${option.value}`} className=\"text-text-positive\">\n {option.label}\n </FieldLabel>\n </Field>\n );\n })}\n </FieldGroup>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n};\n"],"mappings":"sLA8BA,MAAa,GAAkC,CAAE,QAAO,cAAa,UAAS,UAAS,aAAY,iBAAkB,CACnH,IAAM,EAAQA,EAAAA,EAAyC,EACjD,GAAA,EAAA,EAAA,SAAA,CAAwB,EAAM,KAAK,OAAQ,CAAE,kBAAmB,CAAY,EAElF,OACE,EAAA,EAAA,KAAA,CAACC,EAAAA,WAAD,CAAY,UAAU,eAAtB,SAAA,EACE,EAAA,EAAA,KAAA,CAACC,EAAAA,MAAD,CAAoB,cAApB,SAAA,EACE,EAAA,EAAA,KAAA,CAACC,EAAAA,aAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAA,CAACC,EAAAA,WAAD,CAAA,SAAA,CACG,EACA,IAAW,EAAA,EAAA,IAAA,CAACC,EAAAA,aAAD,CAAuB,SAAU,CAAA,CACnC,CAAA,CAAA,GACZ,EAAA,EAAA,IAAA,CAACC,EAAAA,iBAAD,CAAA,SAAmB,CAA8B,CAAA,GACjD,EAAA,EAAA,IAAA,CAACC,EAAAA,UAAD,CAAW,OAAQ,CAAC,CAAC,EAAa,SAAA,CAAsB,CAAA,CAC5C,CAAA,CAAA,GACd,EAAA,EAAA,IAAA,CAACC,EAAAA,iBAAD,CAAA,UACE,EAAA,EAAA,IAAA,CAACP,EAAAA,WAAD,CAAY,UAAU,wBACnB,SAAA,EAAQ,IAAI,IAET,EAAA,EAAA,KAAA,CAACC,EAAAA,MAAD,CAA0B,YAAY,aAAtC,SAAA,EACE,EAAA,EAAA,IAAA,CAACO,EAAAA,SAAD,CACE,GAAI,GAAG,EAAM,KAAK,GAAG,EAAO,QAC5B,KAAM,EAAM,KACZ,QAAS,EAAM,MAAM,OAAO,SAAS,EAAO,KAAK,GAAK,GACtD,SAAU,EACV,gBAAiB,GAAW,CAC1B,GAAI,GAAW,EAAM,MAAM,QAAU,KACnC,EAAM,UAAU,EAAO,KAAK,OACvB,GAAI,GAAW,EAAM,MAAM,QAAU,KAC1C,EAAM,SAAS,CAAC,EAAO,KAAK,CAAC,OACxB,GAAI,CAAC,GAAW,EAAM,MAAM,QAAU,KAAM,CACjD,IAAM,EAAQ,EAAM,MAAM,MAAM,QAAQ,EAAO,KAAK,EAChD,EAAQ,IAAI,EAAM,YAAY,CAAK,CACzC,MACE,EAAM,SAAS,IAAI,CAEvB,CACD,CAAA,GACD,EAAA,EAAA,IAAA,CAACL,EAAAA,WAAD,CAAY,QAAS,GAAG,EAAM,KAAK,GAAG,EAAO,QAAS,UAAU,qBAC7D,SAAA,EAAO,KACE,CAAA,CACP,CAtBK,EAAA,EAAO,KAsBZ,CAEV,CACS,CAAA,CACI,CAAA,CACb,CACP,CAAA,GAAA,EAAA,EAAA,IAAA,CAACM,EAAAA,eAAD,CAAiB,CAAA,CACP,GAEhB"}
1
+ {"version":3,"file":"checkbox-field-CFPHAcwN.cjs","names":["useTanStackFieldContext","FieldGroup","Field","FieldContent","FieldLabel","FieldTooltip","FieldDescription","FieldNote","FieldContentMain","Checkbox","FieldSeparator"],"sources":["../packages/components/features/tanstack-form/components/fields/checkbox-field.tsx"],"sourcesContent":["'use client';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { useTanStackFieldContext } from '../form-context';\nimport { Field, FieldContent, FieldContentMain, FieldDescription, FieldGroup, FieldLabel, FieldNote, FieldSeparator, FieldTooltip } from '../ui/field';\nimport { Checkbox } from '@/components/ui/checkbox';\n\nimport type { CheckboxFieldProps as Props } from '../../types';\n\n/**\n * A TanStack Form-connected checkbox group field that manages an array of selected string values,\n * supporting multi-selection and submission-state disabling.\n *\n * @example\n * import { CheckboxField } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <form.Field name=\"roles\">\n * {() => (\n * <CheckboxField\n * label=\"Roles\"\n * options={[\n * { value: 'admin', label: 'Admin' },\n * { value: 'editor', label: 'Editor' },\n * ]}\n * helperText=\"Select one or more roles\"\n * />\n * )}\n * </form.Field>\n */\nexport const CheckboxField: React.FC<Props> = ({ label, description, options, tooltip, helperText, orientation }) => {\n const field = useTanStackFieldContext<string[] | null>();\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation={orientation}>\n <FieldContent>\n <FieldLabel>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </FieldContent>\n <FieldContentMain>\n <FieldGroup className=\"flex flex-col gap-y-2\">\n {options.map(option => {\n return (\n <Field key={option.value} orientation=\"horizontal\">\n <Checkbox\n id={`${field.name}-${option.value}`}\n name={field.name}\n checked={field.state.value?.includes(option.value) ?? false}\n disabled={isSubmitting}\n onCheckedChange={checked => {\n if (checked && field.state.value !== null) {\n field.pushValue(option.value);\n } else if (checked && field.state.value === null) {\n field.setValue([option.value]);\n } else if (!checked && field.state.value !== null) {\n const index = field.state.value.indexOf(option.value);\n if (index > -1) field.removeValue(index);\n } else {\n field.setValue(null);\n }\n }}\n />\n <FieldLabel htmlFor={`${field.name}-${option.value}`} className=\"text-text-positive\">\n {option.label}\n </FieldLabel>\n </Field>\n );\n })}\n </FieldGroup>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n};\n"],"mappings":"oJA8BA,MAAa,GAAkC,CAAE,QAAO,cAAa,UAAS,UAAS,aAAY,iBAAkB,CACnH,IAAM,EAAQA,EAAAA,GAAyC,EACjD,GAAA,EAAA,EAAA,SAAA,CAAwB,EAAM,KAAK,OAAQ,CAAE,kBAAmB,CAAY,EAElF,OACE,EAAA,EAAA,KAAA,CAACC,EAAAA,EAAD,CAAY,UAAU,eAAtB,SAAA,EACE,EAAA,EAAA,KAAA,CAACC,EAAAA,EAAD,CAAoB,cAApB,SAAA,EACE,EAAA,EAAA,KAAA,CAACC,EAAAA,EAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAA,CAACC,EAAAA,EAAD,CAAA,SAAA,CACG,EACA,IAAW,EAAA,EAAA,IAAA,CAACC,EAAAA,GAAD,CAAuB,SAAU,CAAA,CACnC,CAAA,CAAA,GACZ,EAAA,EAAA,IAAA,CAACC,EAAAA,EAAD,CAAA,SAAmB,CAA8B,CAAA,GACjD,EAAA,EAAA,IAAA,CAACC,EAAAA,EAAD,CAAW,OAAQ,CAAC,CAAC,EAAa,SAAA,CAAsB,CAAA,CAC5C,CAAA,CAAA,GACd,EAAA,EAAA,IAAA,CAACC,EAAAA,EAAD,CAAA,UACE,EAAA,EAAA,IAAA,CAACP,EAAAA,EAAD,CAAY,UAAU,wBACnB,SAAA,EAAQ,IAAI,IAET,EAAA,EAAA,KAAA,CAACC,EAAAA,EAAD,CAA0B,YAAY,aAAtC,SAAA,EACE,EAAA,EAAA,IAAA,CAACO,EAAAA,SAAD,CACE,GAAI,GAAG,EAAM,KAAK,GAAG,EAAO,QAC5B,KAAM,EAAM,KACZ,QAAS,EAAM,MAAM,OAAO,SAAS,EAAO,KAAK,GAAK,GACtD,SAAU,EACV,gBAAiB,GAAW,CAC1B,GAAI,GAAW,EAAM,MAAM,QAAU,KACnC,EAAM,UAAU,EAAO,KAAK,OACvB,GAAI,GAAW,EAAM,MAAM,QAAU,KAC1C,EAAM,SAAS,CAAC,EAAO,KAAK,CAAC,OACxB,GAAI,CAAC,GAAW,EAAM,MAAM,QAAU,KAAM,CACjD,IAAM,EAAQ,EAAM,MAAM,MAAM,QAAQ,EAAO,KAAK,EAChD,EAAQ,IAAI,EAAM,YAAY,CAAK,CACzC,MACE,EAAM,SAAS,IAAI,CAEvB,CACD,CAAA,GACD,EAAA,EAAA,IAAA,CAACL,EAAAA,EAAD,CAAY,QAAS,GAAG,EAAM,KAAK,GAAG,EAAO,QAAS,UAAU,qBAC7D,SAAA,EAAO,KACE,CAAA,CACP,CAtBK,EAAA,EAAO,KAsBZ,CAEV,CACS,CAAA,CACI,CAAA,CACb,CACP,CAAA,GAAA,EAAA,EAAA,IAAA,CAACM,EAAAA,GAAD,CAAiB,CAAA,CACP,GAEhB"}
@@ -0,0 +1,2 @@
1
+ import{$ as e,G as t,J as n,K as r,X as i,Z as a,et as o,nt as s,q as c,rt as l}from"./tanstack-form-BhKAn9I0.mjs";import{Checkbox as u}from"./ui/checkbox.mjs";import{jsx as d,jsxs as f}from"react/jsx-runtime";import{useStore as p}from"@tanstack/react-form";const m=({label:m,description:h,options:g,tooltip:_,helperText:v,orientation:y})=>{let b=l(),x=p(b.form.store,({isSubmitting:e})=>e);return f(i,{className:`gap-y-4 px-4`,children:[f(t,{orientation:y,children:[f(r,{children:[f(a,{children:[m,_&&d(s,{tooltip:_})]}),d(n,{children:h}),d(e,{isShow:!!v,children:v})]}),d(c,{children:d(i,{className:`flex flex-col gap-y-2`,children:g.map(e=>f(t,{orientation:`horizontal`,children:[d(u,{id:`${b.name}-${e.value}`,name:b.name,checked:b.state.value?.includes(e.value)??!1,disabled:x,onCheckedChange:t=>{if(t&&b.state.value!==null)b.pushValue(e.value);else if(t&&b.state.value===null)b.setValue([e.value]);else if(!t&&b.state.value!==null){let t=b.state.value.indexOf(e.value);t>-1&&b.removeValue(t)}else b.setValue(null)}}),d(a,{htmlFor:`${b.name}-${e.value}`,className:`text-text-positive`,children:e.label})]},e.value))})})]}),d(o,{})]})};export{m as CheckboxField};
2
+ //# sourceMappingURL=checkbox-field-DodKeFS_.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"checkbox-field-BRGTLOjq.mjs","names":[],"sources":["../packages/components/features/tanstack-form/components/fields/checkbox-field.tsx"],"sourcesContent":["'use client';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { useTanStackFieldContext } from '../form-context';\nimport { Field, FieldContent, FieldContentMain, FieldDescription, FieldGroup, FieldLabel, FieldNote, FieldSeparator, FieldTooltip } from '../ui/field';\nimport { Checkbox } from '@/components/ui/checkbox';\n\nimport type { CheckboxFieldProps as Props } from '../../types';\n\n/**\n * A TanStack Form-connected checkbox group field that manages an array of selected string values,\n * supporting multi-selection and submission-state disabling.\n *\n * @example\n * import { CheckboxField } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <form.Field name=\"roles\">\n * {() => (\n * <CheckboxField\n * label=\"Roles\"\n * options={[\n * { value: 'admin', label: 'Admin' },\n * { value: 'editor', label: 'Editor' },\n * ]}\n * helperText=\"Select one or more roles\"\n * />\n * )}\n * </form.Field>\n */\nexport const CheckboxField: React.FC<Props> = ({ label, description, options, tooltip, helperText, orientation }) => {\n const field = useTanStackFieldContext<string[] | null>();\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation={orientation}>\n <FieldContent>\n <FieldLabel>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </FieldContent>\n <FieldContentMain>\n <FieldGroup className=\"flex flex-col gap-y-2\">\n {options.map(option => {\n return (\n <Field key={option.value} orientation=\"horizontal\">\n <Checkbox\n id={`${field.name}-${option.value}`}\n name={field.name}\n checked={field.state.value?.includes(option.value) ?? false}\n disabled={isSubmitting}\n onCheckedChange={checked => {\n if (checked && field.state.value !== null) {\n field.pushValue(option.value);\n } else if (checked && field.state.value === null) {\n field.setValue([option.value]);\n } else if (!checked && field.state.value !== null) {\n const index = field.state.value.indexOf(option.value);\n if (index > -1) field.removeValue(index);\n } else {\n field.setValue(null);\n }\n }}\n />\n <FieldLabel htmlFor={`${field.name}-${option.value}`} className=\"text-text-positive\">\n {option.label}\n </FieldLabel>\n </Field>\n );\n })}\n </FieldGroup>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n};\n"],"mappings":"gYA8BA,MAAa,GAAkC,CAAE,QAAO,cAAa,UAAS,UAAS,aAAY,iBAAkB,CACnH,IAAM,EAAQ,EAAyC,EACjD,EAAe,EAAS,EAAM,KAAK,OAAQ,CAAE,kBAAmB,CAAY,EAElF,OACE,EAAC,EAAD,CAAY,UAAU,eAAtB,SAAA,CACE,EAAC,EAAD,CAAoB,cAApB,SAAA,CACE,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CAAA,SAAA,CACG,EACA,GAAW,EAAC,EAAD,CAAuB,SAAU,CAAA,CACnC,CAAA,CAAA,EACZ,EAAC,EAAD,CAAA,SAAmB,CAA8B,CAAA,EACjD,EAAC,EAAD,CAAW,OAAQ,CAAC,CAAC,EAAa,SAAA,CAAsB,CAAA,CAC5C,CAAA,CAAA,EACd,EAAC,EAAD,CAAA,SACE,EAAC,EAAD,CAAY,UAAU,wBACnB,SAAA,EAAQ,IAAI,GAET,EAAC,EAAD,CAA0B,YAAY,aAAtC,SAAA,CACE,EAAC,EAAD,CACE,GAAI,GAAG,EAAM,KAAK,GAAG,EAAO,QAC5B,KAAM,EAAM,KACZ,QAAS,EAAM,MAAM,OAAO,SAAS,EAAO,KAAK,GAAK,GACtD,SAAU,EACV,gBAAiB,GAAW,CAC1B,GAAI,GAAW,EAAM,MAAM,QAAU,KACnC,EAAM,UAAU,EAAO,KAAK,OACvB,GAAI,GAAW,EAAM,MAAM,QAAU,KAC1C,EAAM,SAAS,CAAC,EAAO,KAAK,CAAC,OACxB,GAAI,CAAC,GAAW,EAAM,MAAM,QAAU,KAAM,CACjD,IAAM,EAAQ,EAAM,MAAM,MAAM,QAAQ,EAAO,KAAK,EAChD,EAAQ,IAAI,EAAM,YAAY,CAAK,CACzC,MACE,EAAM,SAAS,IAAI,CAEvB,CACD,CAAA,EACD,EAAC,EAAD,CAAY,QAAS,GAAG,EAAM,KAAK,GAAG,EAAO,QAAS,UAAU,qBAC7D,SAAA,EAAO,KACE,CAAA,CACP,CAtBK,EAAA,EAAO,KAsBZ,CAEV,CACS,CAAA,CACI,CAAA,CACb,CACP,CAAA,EAAA,EAAC,EAAD,CAAiB,CAAA,CACP,GAEhB"}
1
+ {"version":3,"file":"checkbox-field-DodKeFS_.mjs","names":[],"sources":["../packages/components/features/tanstack-form/components/fields/checkbox-field.tsx"],"sourcesContent":["'use client';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { useTanStackFieldContext } from '../form-context';\nimport { Field, FieldContent, FieldContentMain, FieldDescription, FieldGroup, FieldLabel, FieldNote, FieldSeparator, FieldTooltip } from '../ui/field';\nimport { Checkbox } from '@/components/ui/checkbox';\n\nimport type { CheckboxFieldProps as Props } from '../../types';\n\n/**\n * A TanStack Form-connected checkbox group field that manages an array of selected string values,\n * supporting multi-selection and submission-state disabling.\n *\n * @example\n * import { CheckboxField } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <form.Field name=\"roles\">\n * {() => (\n * <CheckboxField\n * label=\"Roles\"\n * options={[\n * { value: 'admin', label: 'Admin' },\n * { value: 'editor', label: 'Editor' },\n * ]}\n * helperText=\"Select one or more roles\"\n * />\n * )}\n * </form.Field>\n */\nexport const CheckboxField: React.FC<Props> = ({ label, description, options, tooltip, helperText, orientation }) => {\n const field = useTanStackFieldContext<string[] | null>();\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation={orientation}>\n <FieldContent>\n <FieldLabel>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </FieldContent>\n <FieldContentMain>\n <FieldGroup className=\"flex flex-col gap-y-2\">\n {options.map(option => {\n return (\n <Field key={option.value} orientation=\"horizontal\">\n <Checkbox\n id={`${field.name}-${option.value}`}\n name={field.name}\n checked={field.state.value?.includes(option.value) ?? false}\n disabled={isSubmitting}\n onCheckedChange={checked => {\n if (checked && field.state.value !== null) {\n field.pushValue(option.value);\n } else if (checked && field.state.value === null) {\n field.setValue([option.value]);\n } else if (!checked && field.state.value !== null) {\n const index = field.state.value.indexOf(option.value);\n if (index > -1) field.removeValue(index);\n } else {\n field.setValue(null);\n }\n }}\n />\n <FieldLabel htmlFor={`${field.name}-${option.value}`} className=\"text-text-positive\">\n {option.label}\n </FieldLabel>\n </Field>\n );\n })}\n </FieldGroup>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n};\n"],"mappings":"kQA8BA,MAAa,GAAkC,CAAE,QAAO,cAAa,UAAS,UAAS,aAAY,iBAAkB,CACnH,IAAM,EAAQ,EAAyC,EACjD,EAAe,EAAS,EAAM,KAAK,OAAQ,CAAE,kBAAmB,CAAY,EAElF,OACE,EAAC,EAAD,CAAY,UAAU,eAAtB,SAAA,CACE,EAAC,EAAD,CAAoB,cAApB,SAAA,CACE,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CAAA,SAAA,CACG,EACA,GAAW,EAAC,EAAD,CAAuB,SAAU,CAAA,CACnC,CAAA,CAAA,EACZ,EAAC,EAAD,CAAA,SAAmB,CAA8B,CAAA,EACjD,EAAC,EAAD,CAAW,OAAQ,CAAC,CAAC,EAAa,SAAA,CAAsB,CAAA,CAC5C,CAAA,CAAA,EACd,EAAC,EAAD,CAAA,SACE,EAAC,EAAD,CAAY,UAAU,wBACnB,SAAA,EAAQ,IAAI,GAET,EAAC,EAAD,CAA0B,YAAY,aAAtC,SAAA,CACE,EAAC,EAAD,CACE,GAAI,GAAG,EAAM,KAAK,GAAG,EAAO,QAC5B,KAAM,EAAM,KACZ,QAAS,EAAM,MAAM,OAAO,SAAS,EAAO,KAAK,GAAK,GACtD,SAAU,EACV,gBAAiB,GAAW,CAC1B,GAAI,GAAW,EAAM,MAAM,QAAU,KACnC,EAAM,UAAU,EAAO,KAAK,OACvB,GAAI,GAAW,EAAM,MAAM,QAAU,KAC1C,EAAM,SAAS,CAAC,EAAO,KAAK,CAAC,OACxB,GAAI,CAAC,GAAW,EAAM,MAAM,QAAU,KAAM,CACjD,IAAM,EAAQ,EAAM,MAAM,MAAM,QAAQ,EAAO,KAAK,EAChD,EAAQ,IAAI,EAAM,YAAY,CAAK,CACzC,MACE,EAAM,SAAS,IAAI,CAEvB,CACD,CAAA,EACD,EAAC,EAAD,CAAY,QAAS,GAAG,EAAM,KAAK,GAAG,EAAO,QAAS,UAAU,qBAC7D,SAAA,EAAO,KACE,CAAA,CACP,CAtBK,EAAA,EAAO,KAsBZ,CAEV,CACS,CAAA,CACI,CAAA,CACb,CACP,CAAA,EAAA,EAAC,EAAD,CAAiB,CAAA,CACP,GAEhB"}
@@ -1,2 +1,2 @@
1
- const e=require("./dist-DzA--RwW.cjs"),t=require("./ui/button.cjs");require("./ui/skeleton.cjs");const n=require("./ui/tooltip.cjs"),r=require("./ui/avatar.cjs"),i=require("./features/logo/index.cjs"),a=require("./ui/input.cjs"),o=require("./ui/dropdown-menu.cjs"),s=require("./ui/separator.cjs");let c=require("lucide-react"),l=require("react"),u=require("@customafk/react-toolkit/utils"),d=require("class-variance-authority"),f=require("react/jsx-runtime"),p=require("@customafk/react-toolkit/color-hash");const m=(0,l.createContext)(null);function h(){let e=(0,l.useContext)(m);if(!e)throw Error(`useSidebar must be used within a SidebarProvider.`);return e}function g({defaultOpen:e=!0,open:t,onOpenChange:r,className:i,style:a,children:o,...s}){let[c,d]=(0,l.useState)(e),p=t??c,h=(0,l.useCallback)(e=>{let t=typeof e==`function`?e(p):e;r?r(t):d(t),document.cookie=`sidebar_state=${t}; path=/; max-age=604800`},[r,p]),g=(0,l.useCallback)(()=>{h(e=>!e)},[h]);(0,l.useEffect)(()=>{let e=e=>{e.key===`b`&&(e.metaKey||e.ctrlKey)&&(e.preventDefault(),g())};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[g]);let _=p?`expanded`:`collapsed`,v=(0,l.useMemo)(()=>({state:_,open:p,setOpen:h,toggleSidebar:g}),[_,p,h,g]);return(0,f.jsx)(m.Provider,{value:v,children:(0,f.jsx)(n.TooltipProvider,{delayDuration:0,children:(0,f.jsx)(`div`,{"data-slot":`layout-scroll-container`,className:`h-dvh w-full overflow-auto bg-sidebar`,children:(0,f.jsx)(`section`,{"data-slot":`layout-wrapper`,style:{"--sidebar-width":`16rem`,"--sidebar-width-icon":`3rem`,...a},className:(0,u.cn)(`group/sidebar-wrapper relative grid`,`h-dvh min-h-160 w-full min-w-264 max-w-svw`,`grid-cols-[auto_1fr] grid-rows-[auto_1fr]`,i),...s,children:o})})})})}const _=(0,l.memo)(({side:e=`left`,className:t,children:n,...r})=>{let{state:i}=h();return(0,f.jsxs)(`div`,{className:`group peer relative col-start-1 row-start-2 block bg-card text-sidebar-foreground`,"data-state":i,"data-collapsible":i===`collapsed`?`icon`:``,"data-side":e,"data-slot":`sidebar`,children:[(0,f.jsx)(`div`,{"data-slot":`sidebar-gap`,className:(0,u.cn)(`relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear`,`group-data-[side=right]:rotate-180`,`group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]`)}),(0,f.jsx)(`div`,{"data-slot":`sidebar-container`,className:(0,u.cn)(`absolute inset-y-0 z-10 flex w-(--sidebar-width) p-2 shadow-nav`,`transition-[left,right,width] duration-200 ease-linear`,`group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]`,e===`left`?`left-0`:`right-0`,t),...r,children:(0,f.jsx)(`div`,{"data-sidebar":`sidebar`,"data-slot":`sidebar-inner`,className:`relative flex size-full flex-col`,children:n})})]})});_.displayName=`CMSLayoutSidebar`;const v=(0,l.memo)(({className:e,children:t,...n})=>(0,f.jsx)(`main`,{"data-slot":`sidebar-inset`,className:(0,u.cn)(`col-start-2 row-start-2 grid min-h-0 min-w-0 grid-rows-1`,e),...n,children:(0,f.jsx)(`div`,{className:`relative grid min-h-0 grid-cols-1 overflow-auto`,children:t})}));v.displayName=`CMSLayoutMain`;const y=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(a.Input,{"data-slot":`sidebar-input`,"data-sidebar":`input`,className:(0,u.cn)(`h-8 w-full bg-background shadow-none`,e),...t}));y.displayName=`SidebarInput`;const b=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(`div`,{"data-slot":`sidebar-header`,"data-sidebar":`header`,className:(0,u.cn)(`flex flex-col gap-2 p-2`,e),...t}));b.displayName=`SidebarHeader`;const x=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(`div`,{"data-slot":`sidebar-footer`,"data-sidebar":`footer`,className:(0,u.cn)(`flex flex-col gap-2`,e),...t}));x.displayName=`SidebarFooter`;const S=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(s.Separator,{"data-slot":`sidebar-separator`,"data-sidebar":`separator`,className:(0,u.cn)(`mx-2 w-auto bg-sidebar-border`,e),...t}));S.displayName=`SidebarSeparator`;const C=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(`div`,{"data-slot":`sidebar-content`,"data-sidebar":`content`,className:(0,u.cn)(`flex flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden`,e),...t}));C.displayName=`SidebarContent`;const w=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(`div`,{"data-slot":`sidebar-group`,"data-sidebar":`group`,className:(0,u.cn)(`relative flex w-full flex-col`,e),...t}));w.displayName=`SidebarGroup`;const T=(0,l.memo)(({className:t,asChild:n=!1,...r})=>(0,f.jsx)(n?e.t:`div`,{"data-slot":`sidebar-group-label`,"data-sidebar":`group-label`,className:(0,u.cn)(`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`,`group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0`,t),...r}));T.displayName=`SidebarGroupLabel`;const E=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(`div`,{"data-slot":`sidebar-group-content`,"data-sidebar":`group-content`,className:(0,u.cn)(`w-full text-sm`,e),...t}));E.displayName=`SidebarGroupContent`;const D=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(`ul`,{"data-slot":`sidebar-menu`,"data-sidebar":`menu`,className:(0,u.cn)(`flex w-full min-w-0 flex-col gap-1`,e),...t}));D.displayName=`SidebarMenu`;const O=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(`li`,{"data-slot":`sidebar-menu-item`,"data-sidebar":`menu-item`,className:(0,u.cn)(`group/menu-item relative`,e),...t}));O.displayName=`SidebarMenuItem`;const k=(0,d.cva)([`peer/menu-button`,`cursor-pointer`,`flex w-full items-center gap-2`,`overflow-hidden rounded-md p-2 outline-hidden`,`truncate text-left font-normal`,`transition-[color,background-color,width,height,padding]`,`active:bg-sidebar-accent active:text-sidebar-accent-foreground`,`disabled:pointer-events-none disabled:opacity-50`,`group-has-data-[sidebar=menu-action]/menu-item:pr-8`,`aria-disabled:pointer-events-none aria-disabled:opacity-50`,`data-[active=true]:bg-sidebar-primary-muted data-[active=true]:text-sidebar-primary`,`data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground`,`group-data-[collapsible=icon]:size-12! group-data-[collapsible=icon]:p-3! group-data-[collapsible=icon]:gap-3!`,`[&>svg]:size-6 [&>svg]:shrink-0`,`[&>span:last-child]:truncate`],{variants:{variant:{default:`hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground`,outline:`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))]`},size:{default:`h-10 text-sm`,sm:`h-7 text-xs`,lg:`h-12 text-sm group-data-[collapsible=icon]:p-0!`}},defaultVariants:{variant:`default`,size:`default`}}),A=(0,l.memo)(({asChild:t=!1,isActive:r=!1,variant:i=`default`,size:a=`default`,tooltip:o,className:s,...c})=>{let l=t?e.t:`button`,{state:d}=h(),p=(0,f.jsx)(l,{"data-slot":`sidebar-menu-button`,"data-sidebar":`menu-button`,"data-size":a,"data-active":r,className:(0,u.cn)(k({variant:i,size:a}),s),...c});return o?(typeof o==`string`&&(o={children:o}),(0,f.jsxs)(n.Tooltip,{children:[(0,f.jsx)(n.TooltipTrigger,{asChild:!0,children:p}),(0,f.jsx)(n.TooltipContent,{side:`right`,align:`center`,hidden:d!==`collapsed`,...o})]})):p});A.displayName=`SidebarMenuButton`;const j=({i18nText:e,onChangeToEnLocale:n,onChangeToViLocale:a,user:s,onLogout:d,logoutLabel:m=`Log out`,logo:g})=>{let{toggleSidebar:_}=h(),v=(0,l.useCallback)(e=>{e.preventDefault(),e.stopPropagation(),_()},[_]),y=(0,l.useCallback)(e=>{e.preventDefault(),e.stopPropagation(),n?.()},[n]),b=(0,l.useCallback)(e=>{e.preventDefault(),e.stopPropagation(),a?.()},[a]),x=s?p.colorHashLight.hex(s.name):void 0;return(0,f.jsxs)(`header`,{"data-slot":`cms-layout-header`,className:(0,u.cn)(`bg-card`,`h-(--header-height)`,`sm:h-(--header-height) sm:px-4 sm:pr-6`,`col-span-2 row-start-1 z-20 gap-2 px-2 pr-4.5`,`flex items-center shadow-nav`,`transition-[height] ease-linear`),children:[(0,f.jsxs)(t.Button,{"data-sidebar":`trigger`,"data-slot":`sidebar-trigger`,variant:`ghost`,color:`muted`,size:`icon`,className:`size-10 rounded-full transition-all hover:text-text-positive`,onClick:v,children:[(0,f.jsx)(c.MenuIcon,{className:`size-6!`}),(0,f.jsx)(`span`,{className:`sr-only`,children:`Toggle Sidebar`})]}),(0,f.jsx)(`div`,{className:`flex flex-1 items-center sm:ml-2.5`,children:g??(0,f.jsx)(i.LunasLogo,{variant:`horizontal`,size:`xs`})}),(0,f.jsxs)(`div`,{className:`flex items-center gap-1`,children:[s&&(0,f.jsxs)(o.DropdownMenu,{children:[(0,f.jsx)(o.DropdownMenuTrigger,{asChild:!0,children:(0,f.jsxs)(t.Button,{variant:`ghost`,color:`muted`,className:`h-9 gap-2.5 rounded-full px-2 transition-all`,children:[(0,f.jsxs)(r.Avatar,{className:`size-7 shrink-0`,children:[(0,f.jsx)(r.AvatarImage,{src:s.avatarUrl,alt:s.name}),(0,f.jsx)(r.AvatarFallback,{style:{backgroundColor:x},children:(0,f.jsx)(c.UserRoundIcon,{size:14,className:`text-white`})})]}),(0,f.jsxs)(`div`,{className:`hidden flex-col items-start sm:flex`,children:[(0,f.jsx)(`span`,{className:`max-w-36 truncate text-xs font-semibold leading-tight text-text-positive`,children:s.name}),s.email&&(0,f.jsx)(`span`,{className:`max-w-36 truncate text-xs leading-tight text-text-positive-weak`,children:s.email})]})]})}),(0,f.jsxs)(o.DropdownMenuContent,{align:`end`,className:`w-60`,children:[(0,f.jsxs)(`div`,{className:`flex flex-col items-center gap-2 px-4 py-4 text-center`,children:[(0,f.jsxs)(r.Avatar,{className:`size-12`,children:[(0,f.jsx)(r.AvatarImage,{src:s.avatarUrl,alt:s.name}),(0,f.jsx)(r.AvatarFallback,{style:{backgroundColor:x},children:(0,f.jsx)(c.UserRoundIcon,{size:22,className:`text-white`})})]}),(0,f.jsxs)(`div`,{className:`flex min-w-0 w-full flex-col items-center gap-0.5`,children:[(0,f.jsx)(`p`,{className:`truncate text-sm font-semibold text-text-positive`,children:s.name}),s.email&&(0,f.jsx)(`p`,{className:`truncate text-xs text-text-positive-weak`,children:s.email}),s.role&&(0,f.jsx)(`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`,children:s.role})]})]}),d&&(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)(o.DropdownMenuSeparator,{}),(0,f.jsx)(o.DropdownMenuGroup,{children:(0,f.jsxs)(o.DropdownMenuItem,{className:`text-danger focus:text-danger`,onClick:d,children:[(0,f.jsx)(c.LogOutIcon,{className:`size-4`}),m]})})]})]})]}),s&&(n||a)&&(0,f.jsx)(`div`,{className:`mx-1 h-5 w-px bg-border`}),(n||a)&&(0,f.jsxs)(o.DropdownMenu,{children:[(0,f.jsx)(o.DropdownMenuTrigger,{asChild:!0,children:(0,f.jsxs)(t.Button,{"data-slot":`locale-trigger`,variant:`ghost`,color:`muted`,className:`gap-x-1 rounded-full transition-all hover:text-text-positive`,children:[(0,f.jsx)(c.EarthIcon,{className:`size-6!`}),e]})}),(0,f.jsx)(o.DropdownMenuContent,{align:`end`,children:(0,f.jsxs)(o.DropdownMenuGroup,{children:[(0,f.jsx)(o.DropdownMenuItem,{onClick:y,children:`EN - English`}),(0,f.jsx)(o.DropdownMenuItem,{onClick:b,children:`VI - Vietnamese`})]})})]})]})]})},M=(0,l.memo)(({id:e,label:t,icon:n,activeNavItemId:r,onClick:i,renderAs:a})=>(0,f.jsx)(O,{children:a?(0,f.jsx)(A,{asChild:!0,isActive:e===r,children:a({icon:n,label:t})}):(0,f.jsxs)(A,{isActive:e===r,onClick:i,children:[n,t]})}));M.displayName=`SidebarContentGroupItem`;const N=(0,l.memo)(({id:e,label:t,children:n})=>(0,f.jsxs)(w,{children:[(0,f.jsx)(T,{children:t}),(0,f.jsx)(E,{children:(0,f.jsx)(D,{children:n})})]}));N.displayName=`SidebarContentGroup`;const P=({i18nText:e,activeNavItemId:t,sidebar:n,children:r,onChangeToEnLocale:i,onChangeToViLocale:a,onLogout:o,logoutLabel:s=`Log out`,copyright:l=`Copyright © ${new Date().getFullYear()}, Lunas.`,user:u})=>{let d=n?.groupcontent??[];return(0,f.jsxs)(g,{children:[(0,f.jsx)(j,{i18nText:e,onChangeToEnLocale:i,onChangeToViLocale:a,user:u,onLogout:o,logoutLabel:s}),(0,f.jsxs)(_,{children:[(0,f.jsx)(C,{children:d.map(e=>(0,f.jsx)(N,{id:e.id,label:e.label,children:e.items.map(e=>(0,f.jsx)(M,{id:e.id,activeNavItemId:t,label:e.label,icon:e.icon,renderAs:e.renderAs,onClick:e.onClick},e.id))},e.id))}),(0,f.jsx)(x,{children:(0,f.jsxs)(D,{children:[(0,f.jsx)(O,{children:(0,f.jsxs)(A,{className:`border border-border`,onClick:o,children:[(0,f.jsx)(c.LogOutIcon,{className:`text-text-positive-weak`}),s]})}),(0,f.jsx)(O,{className:`mt-2 border-t border-t-border`,children:(0,f.jsx)(`p`,{className:`pt-2 text-center text-xs text-text-positive-subtle`,children:l})})]})})]}),(0,f.jsx)(v,{children:r})]})};Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return P}});
2
- //# sourceMappingURL=cms-layout-BGsf1E4E.cjs.map
1
+ const e=require("./dist-CIdWHwhj.cjs"),t=require("./ui/button.cjs");require("./ui/skeleton.cjs");const n=require("./ui/tooltip.cjs"),r=require("./ui/avatar.cjs"),i=require("./features/logo/index.cjs"),a=require("./ui/input.cjs"),o=require("./ui/dropdown-menu.cjs"),s=require("./ui/separator.cjs");let c=require("lucide-react"),l=require("react"),u=require("@customafk/react-toolkit/utils"),d=require("class-variance-authority"),f=require("react/jsx-runtime"),p=require("@customafk/react-toolkit/color-hash");const m=(0,l.createContext)(null);function h(){let e=(0,l.useContext)(m);if(!e)throw Error(`useSidebar must be used within a SidebarProvider.`);return e}function g({defaultOpen:e=!0,open:t,onOpenChange:r,className:i,style:a,children:o,...s}){let[c,d]=(0,l.useState)(e),p=t??c,h=(0,l.useCallback)(e=>{let t=typeof e==`function`?e(p):e;r?r(t):d(t),document.cookie=`sidebar_state=${t}; path=/; max-age=604800`},[r,p]),g=(0,l.useCallback)(()=>{h(e=>!e)},[h]);(0,l.useEffect)(()=>{let e=e=>{e.key===`b`&&(e.metaKey||e.ctrlKey)&&(e.preventDefault(),g())};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[g]);let _=p?`expanded`:`collapsed`,v=(0,l.useMemo)(()=>({state:_,open:p,setOpen:h,toggleSidebar:g}),[_,p,h,g]);return(0,f.jsx)(m.Provider,{value:v,children:(0,f.jsx)(n.TooltipProvider,{delayDuration:0,children:(0,f.jsx)(`div`,{"data-slot":`layout-scroll-container`,className:`h-dvh w-full overflow-auto bg-sidebar`,children:(0,f.jsx)(`section`,{"data-slot":`layout-wrapper`,style:{"--sidebar-width":`16rem`,"--sidebar-width-icon":`3rem`,...a},className:(0,u.cn)(`group/sidebar-wrapper relative grid`,`h-dvh min-h-160 w-full min-w-264 max-w-svw`,`grid-cols-[auto_1fr] grid-rows-[auto_1fr]`,i),...s,children:o})})})})}const _=(0,l.memo)(({side:e=`left`,className:t,children:n,...r})=>{let{state:i}=h();return(0,f.jsxs)(`div`,{className:`group peer relative col-start-1 row-start-2 block bg-card text-sidebar-foreground`,"data-state":i,"data-collapsible":i===`collapsed`?`icon`:``,"data-side":e,"data-slot":`sidebar`,children:[(0,f.jsx)(`div`,{"data-slot":`sidebar-gap`,className:(0,u.cn)(`relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear`,`group-data-[side=right]:rotate-180`,`group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]`)}),(0,f.jsx)(`div`,{"data-slot":`sidebar-container`,className:(0,u.cn)(`absolute inset-y-0 z-10 flex w-(--sidebar-width) p-2 shadow-nav`,`transition-[left,right,width] duration-200 ease-linear`,`group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]`,e===`left`?`left-0`:`right-0`,t),...r,children:(0,f.jsx)(`div`,{"data-sidebar":`sidebar`,"data-slot":`sidebar-inner`,className:`relative flex size-full flex-col`,children:n})})]})});_.displayName=`CMSLayoutSidebar`;const v=(0,l.memo)(({className:e,children:t,...n})=>(0,f.jsx)(`main`,{"data-slot":`sidebar-inset`,className:(0,u.cn)(`col-start-2 row-start-2 grid min-h-0 min-w-0 grid-rows-1`,e),...n,children:(0,f.jsx)(`div`,{className:`relative grid min-h-0 grid-cols-1 overflow-auto`,children:t})}));v.displayName=`CMSLayoutMain`;const y=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(a.Input,{"data-slot":`sidebar-input`,"data-sidebar":`input`,className:(0,u.cn)(`h-8 w-full bg-background shadow-none`,e),...t}));y.displayName=`SidebarInput`;const b=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(`div`,{"data-slot":`sidebar-header`,"data-sidebar":`header`,className:(0,u.cn)(`flex flex-col gap-2 p-2`,e),...t}));b.displayName=`SidebarHeader`;const x=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(`div`,{"data-slot":`sidebar-footer`,"data-sidebar":`footer`,className:(0,u.cn)(`flex flex-col gap-2`,e),...t}));x.displayName=`SidebarFooter`;const S=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(s.Separator,{"data-slot":`sidebar-separator`,"data-sidebar":`separator`,className:(0,u.cn)(`mx-2 w-auto bg-sidebar-border`,e),...t}));S.displayName=`SidebarSeparator`;const C=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(`div`,{"data-slot":`sidebar-content`,"data-sidebar":`content`,className:(0,u.cn)(`flex flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden`,e),...t}));C.displayName=`SidebarContent`;const w=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(`div`,{"data-slot":`sidebar-group`,"data-sidebar":`group`,className:(0,u.cn)(`relative flex w-full flex-col`,e),...t}));w.displayName=`SidebarGroup`;const T=(0,l.memo)(({className:t,asChild:n=!1,...r})=>(0,f.jsx)(n?e.t:`div`,{"data-slot":`sidebar-group-label`,"data-sidebar":`group-label`,className:(0,u.cn)(`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`,`group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0`,t),...r}));T.displayName=`SidebarGroupLabel`;const E=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(`div`,{"data-slot":`sidebar-group-content`,"data-sidebar":`group-content`,className:(0,u.cn)(`w-full text-sm`,e),...t}));E.displayName=`SidebarGroupContent`;const D=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(`ul`,{"data-slot":`sidebar-menu`,"data-sidebar":`menu`,className:(0,u.cn)(`flex w-full min-w-0 flex-col gap-1`,e),...t}));D.displayName=`SidebarMenu`;const O=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(`li`,{"data-slot":`sidebar-menu-item`,"data-sidebar":`menu-item`,className:(0,u.cn)(`group/menu-item relative`,e),...t}));O.displayName=`SidebarMenuItem`;const k=(0,d.cva)([`peer/menu-button`,`cursor-pointer`,`flex w-full items-center gap-2`,`overflow-hidden rounded-md p-2 outline-hidden`,`truncate text-left font-normal`,`transition-[color,background-color,width,height,padding]`,`active:bg-sidebar-accent active:text-sidebar-accent-foreground`,`disabled:pointer-events-none disabled:opacity-50`,`group-has-data-[sidebar=menu-action]/menu-item:pr-8`,`aria-disabled:pointer-events-none aria-disabled:opacity-50`,`data-[active=true]:bg-sidebar-primary-muted data-[active=true]:text-sidebar-primary`,`data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground`,`group-data-[collapsible=icon]:size-12! group-data-[collapsible=icon]:p-3! group-data-[collapsible=icon]:gap-3!`,`[&>svg]:size-6 [&>svg]:shrink-0`,`[&>span:last-child]:truncate`],{variants:{variant:{default:`hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground`,outline:`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))]`},size:{default:`h-10 text-sm`,sm:`h-7 text-xs`,lg:`h-12 text-sm group-data-[collapsible=icon]:p-0!`}},defaultVariants:{variant:`default`,size:`default`}}),A=(0,l.memo)(({asChild:t=!1,isActive:r=!1,variant:i=`default`,size:a=`default`,tooltip:o,className:s,...c})=>{let l=t?e.t:`button`,{state:d}=h(),p=(0,f.jsx)(l,{"data-slot":`sidebar-menu-button`,"data-sidebar":`menu-button`,"data-size":a,"data-active":r,className:(0,u.cn)(k({variant:i,size:a}),s),...c});return o?(typeof o==`string`&&(o={children:o}),(0,f.jsxs)(n.Tooltip,{children:[(0,f.jsx)(n.TooltipTrigger,{asChild:!0,children:p}),(0,f.jsx)(n.TooltipContent,{side:`right`,align:`center`,hidden:d!==`collapsed`,...o})]})):p});A.displayName=`SidebarMenuButton`;const j=({i18nText:e,onChangeToEnLocale:n,onChangeToViLocale:a,user:s,onLogout:d,logoutLabel:m=`Log out`,logo:g})=>{let{toggleSidebar:_}=h(),v=(0,l.useCallback)(e=>{e.preventDefault(),e.stopPropagation(),_()},[_]),y=(0,l.useCallback)(e=>{e.preventDefault(),e.stopPropagation(),n?.()},[n]),b=(0,l.useCallback)(e=>{e.preventDefault(),e.stopPropagation(),a?.()},[a]),x=s?p.colorHashLight.hex(s.name):void 0;return(0,f.jsxs)(`header`,{"data-slot":`cms-layout-header`,className:(0,u.cn)(`bg-card`,`h-(--header-height)`,`sm:h-(--header-height) sm:px-4 sm:pr-6`,`col-span-2 row-start-1 z-20 gap-2 px-2 pr-4.5`,`flex items-center shadow-nav`,`transition-[height] ease-linear`),children:[(0,f.jsxs)(t.Button,{"data-sidebar":`trigger`,"data-slot":`sidebar-trigger`,variant:`ghost`,color:`muted`,size:`icon`,className:`size-10 rounded-full transition-all hover:text-text-positive`,onClick:v,children:[(0,f.jsx)(c.MenuIcon,{className:`size-6!`}),(0,f.jsx)(`span`,{className:`sr-only`,children:`Toggle Sidebar`})]}),(0,f.jsx)(`div`,{className:`flex flex-1 items-center sm:ml-2.5`,children:g??(0,f.jsx)(i.LunasLogo,{variant:`horizontal`,size:`xs`})}),(0,f.jsxs)(`div`,{className:`flex items-center gap-1`,children:[s&&(0,f.jsxs)(o.DropdownMenu,{children:[(0,f.jsx)(o.DropdownMenuTrigger,{asChild:!0,children:(0,f.jsxs)(t.Button,{variant:`ghost`,color:`muted`,className:`h-9 gap-2.5 rounded-full px-2 transition-all`,children:[(0,f.jsxs)(r.Avatar,{className:`size-7 shrink-0`,children:[(0,f.jsx)(r.AvatarImage,{src:s.avatarUrl,alt:s.name}),(0,f.jsx)(r.AvatarFallback,{style:{backgroundColor:x},children:(0,f.jsx)(c.UserRoundIcon,{size:14,className:`text-white`})})]}),(0,f.jsxs)(`div`,{className:`hidden flex-col items-start sm:flex`,children:[(0,f.jsx)(`span`,{className:`max-w-36 truncate text-xs font-semibold leading-tight text-text-positive`,children:s.name}),s.email&&(0,f.jsx)(`span`,{className:`max-w-36 truncate text-xs leading-tight text-text-positive-weak`,children:s.email})]})]})}),(0,f.jsxs)(o.DropdownMenuContent,{align:`end`,className:`w-60`,children:[(0,f.jsxs)(`div`,{className:`flex flex-col items-center gap-2 px-4 py-4 text-center`,children:[(0,f.jsxs)(r.Avatar,{className:`size-12`,children:[(0,f.jsx)(r.AvatarImage,{src:s.avatarUrl,alt:s.name}),(0,f.jsx)(r.AvatarFallback,{style:{backgroundColor:x},children:(0,f.jsx)(c.UserRoundIcon,{size:22,className:`text-white`})})]}),(0,f.jsxs)(`div`,{className:`flex min-w-0 w-full flex-col items-center gap-0.5`,children:[(0,f.jsx)(`p`,{className:`truncate text-sm font-semibold text-text-positive`,children:s.name}),s.email&&(0,f.jsx)(`p`,{className:`truncate text-xs text-text-positive-weak`,children:s.email}),s.role&&(0,f.jsx)(`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`,children:s.role})]})]}),d&&(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)(o.DropdownMenuSeparator,{}),(0,f.jsx)(o.DropdownMenuGroup,{children:(0,f.jsxs)(o.DropdownMenuItem,{className:`text-danger focus:text-danger`,onClick:d,children:[(0,f.jsx)(c.LogOutIcon,{className:`size-4`}),m]})})]})]})]}),s&&(n||a)&&(0,f.jsx)(`div`,{className:`mx-1 h-5 w-px bg-border`}),(n||a)&&(0,f.jsxs)(o.DropdownMenu,{children:[(0,f.jsx)(o.DropdownMenuTrigger,{asChild:!0,children:(0,f.jsxs)(t.Button,{"data-slot":`locale-trigger`,variant:`ghost`,color:`muted`,className:`gap-x-1 rounded-full transition-all hover:text-text-positive`,children:[(0,f.jsx)(c.EarthIcon,{className:`size-6!`}),e]})}),(0,f.jsx)(o.DropdownMenuContent,{align:`end`,children:(0,f.jsxs)(o.DropdownMenuGroup,{children:[(0,f.jsx)(o.DropdownMenuItem,{onClick:y,children:`EN - English`}),(0,f.jsx)(o.DropdownMenuItem,{onClick:b,children:`VI - Vietnamese`})]})})]})]})]})},M=(0,l.memo)(({id:e,label:t,icon:n,activeNavItemId:r,onClick:i,renderAs:a})=>(0,f.jsx)(O,{children:a?(0,f.jsx)(A,{asChild:!0,isActive:e===r,children:a({icon:n,label:t})}):(0,f.jsxs)(A,{isActive:e===r,onClick:i,children:[n,t]})}));M.displayName=`SidebarContentGroupItem`;const N=(0,l.memo)(({id:e,label:t,children:n})=>(0,f.jsxs)(w,{children:[(0,f.jsx)(T,{children:t}),(0,f.jsx)(E,{children:(0,f.jsx)(D,{children:n})})]}));N.displayName=`SidebarContentGroup`;const P=({i18nText:e,activeNavItemId:t,sidebar:n,children:r,onChangeToEnLocale:i,onChangeToViLocale:a,onLogout:o,logoutLabel:s=`Log out`,copyright:l=`Copyright © ${new Date().getFullYear()}, Lunas.`,user:u})=>{let d=n?.groupcontent??[];return(0,f.jsxs)(g,{children:[(0,f.jsx)(j,{i18nText:e,onChangeToEnLocale:i,onChangeToViLocale:a,user:u,onLogout:o,logoutLabel:s}),(0,f.jsxs)(_,{children:[(0,f.jsx)(C,{children:d.map(e=>(0,f.jsx)(N,{id:e.id,label:e.label,children:e.items.map(e=>(0,f.jsx)(M,{id:e.id,activeNavItemId:t,label:e.label,icon:e.icon,renderAs:e.renderAs,onClick:e.onClick},e.id))},e.id))}),(0,f.jsx)(x,{children:(0,f.jsxs)(D,{children:[(0,f.jsx)(O,{children:(0,f.jsxs)(A,{className:`border border-border`,onClick:o,children:[(0,f.jsx)(c.LogOutIcon,{className:`text-text-positive-weak`}),s]})}),(0,f.jsx)(O,{className:`mt-2 border-t border-t-border`,children:(0,f.jsx)(`p`,{className:`pt-2 text-center text-xs text-text-positive-subtle`,children:l})})]})})]}),(0,f.jsx)(v,{children:r})]})};Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return P}});
2
+ //# sourceMappingURL=cms-layout-DYEmSqzx.cjs.map