@customafk/lunas-ui 0.2.64 → 0.2.65

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 (181) hide show
  1. package/dist/action-submit-3kZ7JOop.cjs +2 -0
  2. package/dist/action-submit-3kZ7JOop.cjs.map +1 -0
  3. package/dist/action-submit-Dg5GvYz5.mjs +2 -0
  4. package/dist/action-submit-Dg5GvYz5.mjs.map +1 -0
  5. package/dist/actions-form-BL_B81Vg.mjs +2 -0
  6. package/dist/actions-form-BL_B81Vg.mjs.map +1 -0
  7. package/dist/actions-form-CE_enCgE.cjs +2 -0
  8. package/dist/actions-form-CE_enCgE.cjs.map +1 -0
  9. package/dist/card-form-BR5kDTzB.cjs +2 -0
  10. package/dist/card-form-BR5kDTzB.cjs.map +1 -0
  11. package/dist/card-form-D9fNO-6F.mjs +2 -0
  12. package/dist/card-form-D9fNO-6F.mjs.map +1 -0
  13. package/dist/checkbox-field-CRcfuDu1.mjs +2 -0
  14. package/dist/checkbox-field-CRcfuDu1.mjs.map +1 -0
  15. package/dist/checkbox-field-DdeohRmi.cjs +2 -0
  16. package/dist/checkbox-field-DdeohRmi.cjs.map +1 -0
  17. package/dist/combobox-field-BGChwajc.mjs +2 -0
  18. package/dist/combobox-field-BGChwajc.mjs.map +1 -0
  19. package/dist/combobox-field-D9NdSih1.cjs +2 -0
  20. package/dist/combobox-field-D9NdSih1.cjs.map +1 -0
  21. package/dist/container-form-BdsEX0NH.mjs +2 -0
  22. package/dist/container-form-BdsEX0NH.mjs.map +1 -0
  23. package/dist/container-form-CxxUYctk.cjs +2 -0
  24. package/dist/container-form-CxxUYctk.cjs.map +1 -0
  25. package/dist/date-field-BqAX4M_h.cjs +2 -0
  26. package/dist/date-field-BqAX4M_h.cjs.map +1 -0
  27. package/dist/date-field-Dm4ki1HS.mjs +2 -0
  28. package/dist/date-field-Dm4ki1HS.mjs.map +1 -0
  29. package/dist/dialog-form-ClWBZbUN.mjs +2 -0
  30. package/dist/dialog-form-ClWBZbUN.mjs.map +1 -0
  31. package/dist/dialog-form-DN-NlQFO.cjs +2 -0
  32. package/dist/dialog-form-DN-NlQFO.cjs.map +1 -0
  33. package/dist/dialogs/confirm-dialog.cjs +1 -1
  34. package/dist/dialogs/confirm-dialog.cjs.map +1 -1
  35. package/dist/dialogs/confirm-dialog.mjs +1 -1
  36. package/dist/dialogs/confirm-dialog.mjs.map +1 -1
  37. package/dist/email-field-DZNR_JbT.mjs +2 -0
  38. package/dist/email-field-DZNR_JbT.mjs.map +1 -0
  39. package/dist/email-field-lDd9ouFN.cjs +2 -0
  40. package/dist/email-field-lDd9ouFN.cjs.map +1 -0
  41. package/dist/features/tables/index.d.cts +1 -1
  42. package/dist/features/tables/index.d.mts +1 -1
  43. package/dist/features/tanstack-form/index.cjs +1 -1
  44. package/dist/features/tanstack-form/index.d.cts +1 -1
  45. package/dist/features/tanstack-form/index.d.mts +1 -1
  46. package/dist/features/tanstack-form/index.mjs +1 -1
  47. package/dist/field-BKyUqvzh.mjs +2 -0
  48. package/dist/field-BKyUqvzh.mjs.map +1 -0
  49. package/dist/field-BV5twmKA.cjs +2 -0
  50. package/dist/field-BV5twmKA.cjs.map +1 -0
  51. package/dist/group-field-0kStiX8n.cjs +2 -0
  52. package/dist/group-field-0kStiX8n.cjs.map +1 -0
  53. package/dist/group-field-bviEXmo4.mjs +2 -0
  54. package/dist/group-field-bviEXmo4.mjs.map +1 -0
  55. package/dist/{index-CGpGIM1H.d.cts → index-C4isgHWG.d.cts} +2 -2
  56. package/dist/{index-DueBB0rP.d.mts → index-C8W56XKm.d.mts} +2 -2
  57. package/dist/{index-C2KjuFXQ.d.cts → index-DDROD2y9.d.cts} +596 -1117
  58. package/dist/{index-C2KjuFXQ.d.mts → index-DDROD2y9.d.mts} +596 -1117
  59. package/dist/index.cjs +1 -1
  60. package/dist/index.d.cts +3 -3
  61. package/dist/index.d.mts +3 -3
  62. package/dist/index.mjs +1 -1
  63. package/dist/{input-BJMvABEL.d.cts → input-go3H4EQz.d.cts} +2 -2
  64. package/dist/{input-BJMvABEL.d.mts → input-go3H4EQz.d.mts} +2 -2
  65. package/dist/number-field-Baj9Yhiv.mjs +2 -0
  66. package/dist/number-field-Baj9Yhiv.mjs.map +1 -0
  67. package/dist/number-field-BqeSbMvE.cjs +2 -0
  68. package/dist/number-field-BqeSbMvE.cjs.map +1 -0
  69. package/dist/number-input-CqkegUWs.mjs +2 -0
  70. package/dist/number-input-CqkegUWs.mjs.map +1 -0
  71. package/dist/number-input-kTh9zzr7.cjs +2 -0
  72. package/dist/number-input-kTh9zzr7.cjs.map +1 -0
  73. package/dist/password-field-Cq0S949S.cjs +2 -0
  74. package/dist/password-field-Cq0S949S.cjs.map +1 -0
  75. package/dist/password-field-fzpU42sV.mjs +2 -0
  76. package/dist/password-field-fzpU42sV.mjs.map +1 -0
  77. package/dist/popover-form-DNbBGWVF.mjs +2 -0
  78. package/dist/popover-form-DNbBGWVF.mjs.map +1 -0
  79. package/dist/popover-form-KLmew1Vd.cjs +2 -0
  80. package/dist/popover-form-KLmew1Vd.cjs.map +1 -0
  81. package/dist/radio-group-field-DjzD3i-f.cjs +2 -0
  82. package/dist/radio-group-field-DjzD3i-f.cjs.map +1 -0
  83. package/dist/radio-group-field-Ps8yHpnH.mjs +2 -0
  84. package/dist/radio-group-field-Ps8yHpnH.mjs.map +1 -0
  85. package/dist/section-form-B9iTs2we.cjs +2 -0
  86. package/dist/section-form-B9iTs2we.cjs.map +1 -0
  87. package/dist/section-form-B_AZr7jZ.mjs +2 -0
  88. package/dist/section-form-B_AZr7jZ.mjs.map +1 -0
  89. package/dist/select-field-B4eU65OI.cjs +2 -0
  90. package/dist/select-field-B4eU65OI.cjs.map +1 -0
  91. package/dist/select-field-D6Dw-Jwg.mjs +2 -0
  92. package/dist/select-field-D6Dw-Jwg.mjs.map +1 -0
  93. package/dist/separator-BlNAFSJv.mjs +2 -0
  94. package/dist/separator-BlNAFSJv.mjs.map +1 -0
  95. package/dist/separator-sBz__BXC.cjs +2 -0
  96. package/dist/separator-sBz__BXC.cjs.map +1 -0
  97. package/dist/simple-array-field-9oZ-Smzp.mjs +2 -0
  98. package/dist/simple-array-field-9oZ-Smzp.mjs.map +1 -0
  99. package/dist/simple-array-field-Bcs2pHdp.cjs +2 -0
  100. package/dist/simple-array-field-Bcs2pHdp.cjs.map +1 -0
  101. package/dist/simple-boolean-field-C-qq6Vlt.cjs +2 -0
  102. package/dist/simple-boolean-field-C-qq6Vlt.cjs.map +1 -0
  103. package/dist/simple-boolean-field-CkJUMxNU.mjs +2 -0
  104. package/dist/simple-boolean-field-CkJUMxNU.mjs.map +1 -0
  105. package/dist/simple-combobox-field-5dfMd49B.mjs +2 -0
  106. package/dist/simple-combobox-field-5dfMd49B.mjs.map +1 -0
  107. package/dist/simple-combobox-field-BtmQGEo5.cjs +2 -0
  108. package/dist/simple-combobox-field-BtmQGEo5.cjs.map +1 -0
  109. package/dist/simple-date-field-BXoLb496.mjs +2 -0
  110. package/dist/simple-date-field-BXoLb496.mjs.map +1 -0
  111. package/dist/simple-date-field-LVfNhVJi.cjs +2 -0
  112. package/dist/simple-date-field-LVfNhVJi.cjs.map +1 -0
  113. package/dist/simple-email-field-QVUrm8f7.cjs +2 -0
  114. package/dist/simple-email-field-QVUrm8f7.cjs.map +1 -0
  115. package/dist/simple-email-field-rZZIXu7S.mjs +2 -0
  116. package/dist/simple-email-field-rZZIXu7S.mjs.map +1 -0
  117. package/dist/simple-number-field-P9PTwcs4.cjs +2 -0
  118. package/dist/simple-number-field-P9PTwcs4.cjs.map +1 -0
  119. package/dist/simple-number-field-PJAyAOMO.mjs +2 -0
  120. package/dist/simple-number-field-PJAyAOMO.mjs.map +1 -0
  121. package/dist/simple-password-field-BEuFXAsk.mjs +2 -0
  122. package/dist/simple-password-field-BEuFXAsk.mjs.map +1 -0
  123. package/dist/simple-password-field-BW6YkfSP.cjs +2 -0
  124. package/dist/simple-password-field-BW6YkfSP.cjs.map +1 -0
  125. package/dist/simple-radio-group-field-BtQHJpOz.cjs +2 -0
  126. package/dist/simple-radio-group-field-BtQHJpOz.cjs.map +1 -0
  127. package/dist/simple-radio-group-field-DiYQfgts.mjs +2 -0
  128. package/dist/simple-radio-group-field-DiYQfgts.mjs.map +1 -0
  129. package/dist/simple-select-field--zJMLBUY.cjs +2 -0
  130. package/dist/simple-select-field--zJMLBUY.cjs.map +1 -0
  131. package/dist/simple-select-field-Df4DLsbi.mjs +2 -0
  132. package/dist/simple-select-field-Df4DLsbi.mjs.map +1 -0
  133. package/dist/simple-text-field-DVkuHrhF.cjs +2 -0
  134. package/dist/simple-text-field-DVkuHrhF.cjs.map +1 -0
  135. package/dist/simple-text-field-zAfkmlhc.mjs +2 -0
  136. package/dist/simple-text-field-zAfkmlhc.mjs.map +1 -0
  137. package/dist/simple-textarea-field-BaMK0feA.cjs +2 -0
  138. package/dist/simple-textarea-field-BaMK0feA.cjs.map +1 -0
  139. package/dist/simple-textarea-field-q9DeFByl.mjs +2 -0
  140. package/dist/simple-textarea-field-q9DeFByl.mjs.map +1 -0
  141. package/dist/submit-button-CGBaPzE9.mjs +2 -0
  142. package/dist/submit-button-CGBaPzE9.mjs.map +1 -0
  143. package/dist/submit-button-CvINfld5.cjs +2 -0
  144. package/dist/submit-button-CvINfld5.cjs.map +1 -0
  145. package/dist/switch-field-B8HVvc2f.mjs +2 -0
  146. package/dist/switch-field-B8HVvc2f.mjs.map +1 -0
  147. package/dist/switch-field-C1uNuuku.cjs +2 -0
  148. package/dist/switch-field-C1uNuuku.cjs.map +1 -0
  149. package/dist/tanstack-form-CM_Hb3JT.mjs +2 -0
  150. package/dist/tanstack-form-CM_Hb3JT.mjs.map +1 -0
  151. package/dist/tanstack-form-DS_ZvRl8.cjs +2 -0
  152. package/dist/tanstack-form-DS_ZvRl8.cjs.map +1 -0
  153. package/dist/text-editor-field-BBDgCPuc.cjs +2 -0
  154. package/dist/text-editor-field-BBDgCPuc.cjs.map +1 -0
  155. package/dist/text-editor-field-CcsR48Jw.mjs +2 -0
  156. package/dist/text-editor-field-CcsR48Jw.mjs.map +1 -0
  157. package/dist/text-field-BhC_ik5w.cjs +2 -0
  158. package/dist/text-field-BhC_ik5w.cjs.map +1 -0
  159. package/dist/text-field-qhiYvQKt.mjs +2 -0
  160. package/dist/text-field-qhiYvQKt.mjs.map +1 -0
  161. package/dist/textarea-field-C-7ZoUMz.cjs +2 -0
  162. package/dist/textarea-field-C-7ZoUMz.cjs.map +1 -0
  163. package/dist/textarea-field-DqDciVSB.mjs +2 -0
  164. package/dist/textarea-field-DqDciVSB.mjs.map +1 -0
  165. package/dist/title-field-84EnHPvl.mjs +2 -0
  166. package/dist/title-field-84EnHPvl.mjs.map +1 -0
  167. package/dist/title-field-CKxwzMOM.cjs +2 -0
  168. package/dist/title-field-CKxwzMOM.cjs.map +1 -0
  169. package/dist/ui/badge.cjs +1 -1
  170. package/dist/ui/badge.cjs.map +1 -1
  171. package/dist/ui/badge.mjs +1 -1
  172. package/dist/ui/badge.mjs.map +1 -1
  173. package/dist/ui/input.d.cts +1 -1
  174. package/dist/ui/input.d.mts +1 -1
  175. package/dist/ui/inputs/search-input.d.cts +1 -1
  176. package/dist/ui/inputs/search-input.d.mts +1 -1
  177. package/package.json +1 -5
  178. package/dist/tanstack-form-BMVn8ai_.cjs +0 -2
  179. package/dist/tanstack-form-BMVn8ai_.cjs.map +0 -1
  180. package/dist/tanstack-form-DTCgWGCA.mjs +0 -2
  181. package/dist/tanstack-form-DTCgWGCA.mjs.map +0 -1
@@ -0,0 +1,2 @@
1
+ const e=require("./ui/button.cjs"),t=require("./tanstack-form-DS_ZvRl8.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.K(),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-3kZ7JOop.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-submit-3kZ7JOop.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,WACjI,GAAS,UACJ,CAAA,CAGb,CAAA,CAEL"}
@@ -0,0 +1,2 @@
1
+ import{Button as e}from"./ui/button.mjs";import{K as t}from"./tanstack-form-CM_Hb3JT.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=t(),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:t,isSubmitting:n})=>i(e,{type:`button`,size:`md`,disabled:t,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-Dg5GvYz5.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-submit-Dg5GvYz5.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,WACjI,GAAS,UACJ,CAAA,CAGb,CAAA,CAEL"}
@@ -0,0 +1,2 @@
1
+ import{Button as e}from"./ui/button.mjs";import{K as t}from"./tanstack-form-CM_Hb3JT.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=t();return a(`div`,{className:`flex h-8 items-center justify-between`,children:[i(s.Subscribe,{selector:e=>({disabled:e.isPristine||e.isSubmitting}),children:({disabled:t})=>i(e,{color:`muted`,variant:`outline`,type:`button`,size:`md`,disabled:t,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:t,isSubmitting:n})=>a(e,{type:`submit`,size:`md`,disabled:t,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:t,isSubmitting:r})=>a(e,{type:`submit`,size:`md`,disabled:t,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-BL_B81Vg.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actions-form-BL_B81Vg.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,iDAAf,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,WAAG,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,WAVF,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,WAVF,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-DS_ZvRl8.cjs");let n=require("lucide-react"),r=require("react/jsx-runtime");const i=({type:i=`create`})=>{let a=t.K();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-CE_enCgE.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actions-form-CE_enCgE.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,iDAAf,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,WAAG,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,WAVF,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,WAVF,EAYE,EAAA,EAAA,IAAA,CAACE,EAAAA,gBAAD,CAAkB,CAAA,EAAC,UAEb,GAGb,CAAA,CAEA,GAET"}
@@ -0,0 +1,2 @@
1
+ const e=require("./ui/button.cjs"),t=require("./separator-sBz__BXC.cjs");let n=require("lucide-react"),r=require("react/jsx-runtime");const i=({title:i,description:a,onDelete:o,children:s})=>(0,r.jsxs)(`section`,{"data-slot":`card-form`,className:`relative flex flex-col rounded-md bg-card pb-4 shadow-card ring-1 ring-border`,children:[(0,r.jsxs)(`div`,{"data-slot":`card-form-header`,className:`flex flex-col space-y-0.5 px-4 py-3`,children:[(0,r.jsx)(`p`,{className:`font-semibold text-base tracking-tight`,children:i}),!!a&&(0,r.jsx)(`p`,{className:`text-text-positive-weak text-sm`,children:a})]}),(0,r.jsx)(t.t,{}),(0,r.jsx)(`div`,{"data-slot":`card-form-main`,className:`flex flex-col py-4`,children:s}),!!o&&(0,r.jsxs)(e.Button,{color:`danger`,variant:`ghost`,size:`sm`,className:`absolute top-2.5 right-3`,onClick:e=>{o?.(),e.preventDefault(),e.stopPropagation()},children:[(0,r.jsx)(n.Trash2Icon,{}),`Remove`]})]});exports.TanStackCardForm=i;
2
+ //# sourceMappingURL=card-form-BR5kDTzB.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card-form-BR5kDTzB.cjs","names":["Separator","Button","Trash2Icon"],"sources":["../packages/components/features/tanstack-form/components/forms/card-form.tsx"],"sourcesContent":["'use client';\n\nimport { Trash2Icon } from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\n\nimport { Separator } from '../ui/separator';\n\n/**\n * Renders a card-style form section with a header, optional description, a delete button, and a content area for fields.\n *\n * @example\n * import { TanStackCardForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <TanStackCardForm\n * title=\"Shipping Address\"\n * description=\"Where should we deliver your order?\"\n * onDelete={() => removeAddress(id)}\n * >\n * <TextField name=\"street\" />\n * </TanStackCardForm>\n */\nexport const TanStackCardForm: React.FC<\n React.PropsWithChildren<{\n /** Bold heading text shown at the top of the card. */\n title: string;\n /** Optional secondary text rendered beneath the title. */\n description?: string;\n /** When provided, renders a danger \"Remove\" button in the card's top-right corner. */\n onDelete?: () => void | Promise<void>;\n }>\n> = ({ title, description, onDelete, children }) => {\n return (\n <section data-slot=\"card-form\" className=\"relative flex flex-col rounded-md bg-card pb-4 shadow-card ring-1 ring-border\">\n <div data-slot=\"card-form-header\" className=\"flex flex-col space-y-0.5 px-4 py-3\">\n <p className=\"font-semibold text-base tracking-tight\">{title}</p>\n {!!description && <p className=\"text-text-positive-weak text-sm\">{description}</p>}\n </div>\n <Separator />\n <div data-slot=\"card-form-main\" className=\"flex flex-col py-4\">\n {children}\n </div>\n {!!onDelete && (\n <Button\n color=\"danger\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"absolute top-2.5 right-3\"\n onClick={e => {\n onDelete?.();\n e.preventDefault();\n e.stopPropagation();\n }}\n >\n <Trash2Icon />\n Remove\n </Button>\n )}\n </section>\n );\n};\n"],"mappings":"sIAsBA,MAAa,GASR,CAAE,QAAO,cAAa,WAAU,eAEjC,EAAA,EAAA,KAAA,CAAC,UAAD,CAAS,YAAU,YAAY,UAAU,yFAAzC,EACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,YAAU,mBAAmB,UAAU,+CAA5C,EACE,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAU,kDAA0C,CAAS,CAAA,EAC/D,CAAC,CAAC,IAAe,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAU,2CAAmC,CAAe,CAAA,CAC9E,KACL,EAAA,EAAA,IAAA,CAACA,EAAAA,EAAD,CAAY,CAAA,GACZ,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,YAAU,iBAAiB,UAAU,qBACvC,UACE,CAAA,EACJ,CAAC,CAAC,IACD,EAAA,EAAA,KAAA,CAACC,EAAAA,OAAD,CACE,MAAM,SACN,QAAQ,QACR,KAAK,KACL,UAAU,2BACV,QAAS,GAAK,CACZ,IAAW,EACX,EAAE,eAAe,EACjB,EAAE,gBAAgB,CACpB,WATF,EAWE,EAAA,EAAA,IAAA,CAACC,EAAAA,WAAD,CAAa,CAAA,EAAC,QAER,GAEH"}
@@ -0,0 +1,2 @@
1
+ import{Button as e}from"./ui/button.mjs";import{t}from"./separator-BlNAFSJv.mjs";import{Trash2Icon as n}from"lucide-react";import{jsx as r,jsxs as i}from"react/jsx-runtime";const a=({title:a,description:o,onDelete:s,children:c})=>i(`section`,{"data-slot":`card-form`,className:`relative flex flex-col rounded-md bg-card pb-4 shadow-card ring-1 ring-border`,children:[i(`div`,{"data-slot":`card-form-header`,className:`flex flex-col space-y-0.5 px-4 py-3`,children:[r(`p`,{className:`font-semibold text-base tracking-tight`,children:a}),!!o&&r(`p`,{className:`text-text-positive-weak text-sm`,children:o})]}),r(t,{}),r(`div`,{"data-slot":`card-form-main`,className:`flex flex-col py-4`,children:c}),!!s&&i(e,{color:`danger`,variant:`ghost`,size:`sm`,className:`absolute top-2.5 right-3`,onClick:e=>{s?.(),e.preventDefault(),e.stopPropagation()},children:[r(n,{}),`Remove`]})]});export{a as TanStackCardForm};
2
+ //# sourceMappingURL=card-form-D9fNO-6F.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card-form-D9fNO-6F.mjs","names":[],"sources":["../packages/components/features/tanstack-form/components/forms/card-form.tsx"],"sourcesContent":["'use client';\n\nimport { Trash2Icon } from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\n\nimport { Separator } from '../ui/separator';\n\n/**\n * Renders a card-style form section with a header, optional description, a delete button, and a content area for fields.\n *\n * @example\n * import { TanStackCardForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <TanStackCardForm\n * title=\"Shipping Address\"\n * description=\"Where should we deliver your order?\"\n * onDelete={() => removeAddress(id)}\n * >\n * <TextField name=\"street\" />\n * </TanStackCardForm>\n */\nexport const TanStackCardForm: React.FC<\n React.PropsWithChildren<{\n /** Bold heading text shown at the top of the card. */\n title: string;\n /** Optional secondary text rendered beneath the title. */\n description?: string;\n /** When provided, renders a danger \"Remove\" button in the card's top-right corner. */\n onDelete?: () => void | Promise<void>;\n }>\n> = ({ title, description, onDelete, children }) => {\n return (\n <section data-slot=\"card-form\" className=\"relative flex flex-col rounded-md bg-card pb-4 shadow-card ring-1 ring-border\">\n <div data-slot=\"card-form-header\" className=\"flex flex-col space-y-0.5 px-4 py-3\">\n <p className=\"font-semibold text-base tracking-tight\">{title}</p>\n {!!description && <p className=\"text-text-positive-weak text-sm\">{description}</p>}\n </div>\n <Separator />\n <div data-slot=\"card-form-main\" className=\"flex flex-col py-4\">\n {children}\n </div>\n {!!onDelete && (\n <Button\n color=\"danger\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"absolute top-2.5 right-3\"\n onClick={e => {\n onDelete?.();\n e.preventDefault();\n e.stopPropagation();\n }}\n >\n <Trash2Icon />\n Remove\n </Button>\n )}\n </section>\n );\n};\n"],"mappings":"6KAsBA,MAAa,GASR,CAAE,QAAO,cAAa,WAAU,cAEjC,EAAC,UAAD,CAAS,YAAU,YAAY,UAAU,yFAAzC,CACE,EAAC,MAAD,CAAK,YAAU,mBAAmB,UAAU,+CAA5C,CACE,EAAC,IAAD,CAAG,UAAU,kDAA0C,CAAS,CAAA,EAC/D,CAAC,CAAC,GAAe,EAAC,IAAD,CAAG,UAAU,2CAAmC,CAAe,CAAA,CAC9E,IACL,EAAC,EAAD,CAAY,CAAA,EACZ,EAAC,MAAD,CAAK,YAAU,iBAAiB,UAAU,qBACvC,UACE,CAAA,EACJ,CAAC,CAAC,GACD,EAAC,EAAD,CACE,MAAM,SACN,QAAQ,QACR,KAAK,KACL,UAAU,2BACV,QAAS,GAAK,CACZ,IAAW,EACX,EAAE,eAAe,EACjB,EAAE,gBAAgB,CACpB,WATF,CAWE,EAAC,EAAD,CAAa,CAAA,EAAC,QAER,GAEH"}
@@ -0,0 +1,2 @@
1
+ import{Checkbox as e}from"./ui/checkbox.mjs";import{G as t}from"./tanstack-form-CM_Hb3JT.mjs";import{Field as n,FieldContent as r,FieldContentMain as i,FieldDescription as a,FieldGroup as o,FieldLabel as s,FieldNote as c,FieldSeparator as l,FieldTooltip as u}from"./field-BKyUqvzh.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=t(),x=p(b.form.store,({isSubmitting:e})=>e);return f(o,{className:`gap-y-4 px-4`,children:[f(n,{orientation:y,children:[f(r,{children:[f(s,{children:[m,_&&d(u,{tooltip:_})]}),d(a,{children:h}),d(c,{isShow:!!v,children:v})]}),d(i,{children:d(o,{className:`flex flex-col gap-y-2`,children:g.map(t=>f(n,{orientation:`horizontal`,children:[d(e,{id:`${b.name}-${t.value}`,name:b.name,checked:b.state.value?.includes(t.value)??!1,disabled:x,onCheckedChange:e=>{if(e&&b.state.value!==null)b.pushValue(t.value);else if(e&&b.state.value===null)b.setValue([t.value]);else if(!e&&b.state.value!==null){let e=b.state.value.indexOf(t.value);e>-1&&b.removeValue(e)}else b.setValue(null)}}),d(s,{htmlFor:`${b.name}-${t.value}`,className:`text-text-positive`,children:t.label})]},t.value))})})]}),d(l,{})]})};export{m as CheckboxField};
2
+ //# sourceMappingURL=checkbox-field-CRcfuDu1.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkbox-field-CRcfuDu1.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,wBAAtB,CACE,EAAC,EAAD,CAAoB,uBAApB,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,WAAa,CAAsB,CAAA,CAC5C,CAAA,CAAA,EACd,EAAC,EAAD,CAAA,SACE,EAAC,EAAD,CAAY,UAAU,iCACnB,EAAQ,IAAI,GAET,EAAC,EAAD,CAA0B,YAAY,sBAAtC,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,8BAC7D,EAAO,KACE,CAAA,CACP,GAtBK,EAAO,KAsBZ,CAEV,CACS,CAAA,CACI,CAAA,CACb,IACP,EAAC,EAAD,CAAiB,CAAA,CACP,GAEhB"}
@@ -0,0 +1,2 @@
1
+ const e=require("./ui/checkbox.cjs"),t=require("./tanstack-form-DS_ZvRl8.cjs"),n=require("./field-BV5twmKA.cjs");let r=require("react/jsx-runtime"),i=require("@tanstack/react-form");const a=({label:a,description:o,options:s,tooltip:c,helperText:l,orientation:u})=>{let d=t.G(),f=(0,i.useStore)(d.form.store,({isSubmitting:e})=>e);return(0,r.jsxs)(n.FieldGroup,{className:`gap-y-4 px-4`,children:[(0,r.jsxs)(n.Field,{orientation:u,children:[(0,r.jsxs)(n.FieldContent,{children:[(0,r.jsxs)(n.FieldLabel,{children:[a,c&&(0,r.jsx)(n.FieldTooltip,{tooltip:c})]}),(0,r.jsx)(n.FieldDescription,{children:o}),(0,r.jsx)(n.FieldNote,{isShow:!!l,children:l})]}),(0,r.jsx)(n.FieldContentMain,{children:(0,r.jsx)(n.FieldGroup,{className:`flex flex-col gap-y-2`,children:s.map(t=>(0,r.jsxs)(n.Field,{orientation:`horizontal`,children:[(0,r.jsx)(e.Checkbox,{id:`${d.name}-${t.value}`,name:d.name,checked:d.state.value?.includes(t.value)??!1,disabled:f,onCheckedChange:e=>{if(e&&d.state.value!==null)d.pushValue(t.value);else if(e&&d.state.value===null)d.setValue([t.value]);else if(!e&&d.state.value!==null){let e=d.state.value.indexOf(t.value);e>-1&&d.removeValue(e)}else d.setValue(null)}}),(0,r.jsx)(n.FieldLabel,{htmlFor:`${d.name}-${t.value}`,className:`text-text-positive`,children:t.label})]},t.value))})})]}),(0,r.jsx)(n.FieldSeparator,{})]})};exports.CheckboxField=a;
2
+ //# sourceMappingURL=checkbox-field-DdeohRmi.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkbox-field-DdeohRmi.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,wBAAtB,EACE,EAAA,EAAA,KAAA,CAACC,EAAAA,MAAD,CAAoB,uBAApB,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,WAAa,CAAsB,CAAA,CAC5C,CAAA,CAAA,GACd,EAAA,EAAA,IAAA,CAACC,EAAAA,iBAAD,CAAA,UACE,EAAA,EAAA,IAAA,CAACP,EAAAA,WAAD,CAAY,UAAU,iCACnB,EAAQ,IAAI,IAET,EAAA,EAAA,KAAA,CAACC,EAAAA,MAAD,CAA0B,YAAY,sBAAtC,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,8BAC7D,EAAO,KACE,CAAA,CACP,GAtBK,EAAO,KAsBZ,CAEV,CACS,CAAA,CACI,CAAA,CACb,KACP,EAAA,EAAA,IAAA,CAACM,EAAAA,eAAD,CAAiB,CAAA,CACP,GAEhB"}
@@ -0,0 +1,2 @@
1
+ import{Button as e}from"./ui/button.mjs";import{Dialog as t,DialogClose as n,DialogOverlay as ee,DialogPortal as te}from"./ui/dialog.mjs";import{Command as r,CommandEmpty as i,CommandGroup as a,CommandInput as o,CommandItem as s,CommandList as c}from"./ui/command.mjs";import{Popover as ne,PopoverContent as re,PopoverTrigger as l}from"./ui/popover.mjs";import{G as u}from"./tanstack-form-CM_Hb3JT.mjs";import{Field as d,FieldContent as f,FieldContentMain as p,FieldDescription as m,FieldError as h,FieldGroup as g,FieldLabel as _,FieldNote as ie,FieldSeparator as ae,FieldTooltip as oe}from"./field-BKyUqvzh.mjs";import{XIcon as v}from"lucide-react";import{memo as y,useId as b,useState as x}from"react";import{cn as S}from"@customafk/react-toolkit/utils";import{Fragment as C,jsx as w,jsxs as T}from"react/jsx-runtime";import{Dialog as E}from"radix-ui";import{useIsMobile as D}from"@customafk/react-toolkit/hooks/useMobile";import{useStore as O}from"@tanstack/react-form";const k=y(({label:y,description:k,placeholder:A,tooltip:j,helperText:M,orientation:N=`responsive`,options:P,required:F=!1,disabled:se=!1,clearable:I=!1,showErrorMessage:L=!0})=>{let R=b(),z=u(),B=D(),[V,H]=x(!1),[U,W]=x(!1),G=O(z.form.store,({isSubmitting:e})=>e),K=se||G,q=z.state.meta.isDirty||z.state.meta.isTouched,J=q&&!z.state.meta.isValid,ce=F&&z.state.value===null,Y=I&&!!z.state.value&&!K,X=P.find(({value:e})=>e===z.state.value)?.label,Z=()=>{z.handleChange(null),z.handleBlur()},Q=t=>w(e,{variant:`outline`,color:`muted`,size:`lg`,disabled:K,"aria-invalid":J?!0:void 0,"aria-describedby":R,className:S(`flex w-full items-center justify-start rounded outline-border`,`hover:bg-transparent`,`focus-visible:outline-1 focus-visible:outline-primary-strong focus-visible:ring-4 focus-visible:ring-primary-weak`,`data-[state=open]:text-text-positive-muted data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak`,Y&&`pr-8`,!z.state.value&&`text-text-positive-muted`,J&&`outline-danger bg-danger-bg-subtle ring-4 ring-danger-weak`),onClick:t,children:X?w(`p`,{className:`flex min-w-0 flex-1 items-center gap-2 truncate text-start`,children:X}):w(`p`,{className:`flex-1 text-start text-text-positive-muted`,children:A})}),$=e=>T(r,{className:`border-none`,children:[w(o,{placeholder:A??`Tìm kiếm…`}),T(c,{children:[w(i,{className:`flex min-h-30 items-center justify-center text-sm text-text-positive-weak`,children:`Không tìm thấy kết quả nào phù hợp.`}),w(a,{className:`max-h-60 overflow-y-auto`,children:P.map(({value:t,label:n})=>w(s,{value:n,onSelect:()=>e(t),children:n},t))})]})]});return T(g,{className:`gap-y-4 px-4`,children:[T(d,{orientation:N,"data-invalid":J,children:[T(f,{children:[T(_,{"aria-required":ce,htmlFor:z.name,children:[y,j&&w(oe,{tooltip:j})]}),w(m,{children:k})]}),w(p,{className:`flex justify-end`,children:T(`div`,{className:`flex w-full flex-col`,children:[T(`div`,{className:`relative`,children:[B?T(C,{children:[Q(()=>H(!0)),w(t,{open:V,onOpenChange:e=>{H(e),e||z.handleBlur()},children:T(te,{children:[w(ee,{}),T(E.Content,{onOpenAutoFocus:e=>e.preventDefault(),className:S(`fixed inset-x-0 bottom-0 z-50`,`flex flex-col bg-background rounded-t-2xl outline-none`,`max-h-[80dvh] shadow-[0_-4px_24px_rgba(0,0,0,0.08)]`,`data-[state=open]:animate-in data-[state=open]:slide-in-from-bottom data-[state=open]:fade-in-0`,`data-[state=closed]:animate-out data-[state=closed]:slide-out-to-bottom data-[state=closed]:fade-out-0`,`duration-300`),children:[T(`div`,{className:`flex items-center justify-between px-4 py-3 border-b border-border shrink-0`,children:[w(`span`,{className:`font-semibold text-sm text-text-positive`,children:y}),w(n,{asChild:!0,children:w(`button`,{type:`button`,"aria-label":`Đóng`,className:`flex size-7 items-center justify-center rounded-md text-text-positive-weak transition-colors hover:bg-muted-muted hover:text-text-positive`,children:w(v,{size:16})})})]}),T(`div`,{className:`flex flex-col overflow-y-auto`,children:[Y&&w(n,{asChild:!0,children:T(`button`,{type:`button`,className:`flex w-full items-center gap-x-2 px-4 py-3 text-left text-sm text-danger-strong transition-colors hover:bg-danger-bg-subtle`,onClick:Z,children:[w(v,{size:14}),`Xóa lựa chọn`]})}),$(e=>{z.handleChange(e),H(!1),z.handleBlur()})]}),w(`div`,{className:`shrink-0 h-safe-bottom`})]})]})})]}):T(ne,{open:U,onOpenChange:e=>{W(e),e||z.handleBlur()},children:[w(l,{asChild:!0,children:Q()}),w(re,{align:`end`,side:`bottom`,className:`flex w-fit rounded p-0`,children:$(e=>{z.handleChange(e),W(!1),z.handleBlur()})})]}),Y&&w(`button`,{type:`button`,"aria-label":`Xóa lựa chọn`,className:`absolute right-2 top-1/2 -translate-y-1/2 flex size-4 cursor-pointer items-center justify-center rounded-md text-text-positive-weak outline-none transition-[color,transform] hover:text-text-positive focus-visible:text-primary-strong focus-visible:[&>svg]:scale-125 [&>svg]:size-3.5 [&>svg]:transition-transform`,onClick:Z,children:w(v,{"aria-hidden":`true`})})]}),q&&L&&w(h,{id:R,className:`mt-1`,errors:z.state.meta.errors}),w(ie,{isShow:!!M,children:M})]})})]}),w(ae,{})]})});k.displayName=`ComboboxField`;export{k as ComboboxField};
2
+ //# sourceMappingURL=combobox-field-BGChwajc.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"combobox-field-BGChwajc.mjs","names":["Dialog","RadixDialog","Popover"],"sources":["../packages/components/features/tanstack-form/components/fields/combobox-field.tsx"],"sourcesContent":["'use client';\n\nimport { memo, useId, useState } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { XIcon } from 'lucide-react';\n\nimport { Dialog as RadixDialog } from 'radix-ui';\n\nimport { useIsMobile } from '@customafk/react-toolkit/hooks/useMobile';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command';\nimport { Dialog, DialogClose, DialogOverlay, DialogPortal } from '@/components/ui/dialog';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\n\nimport { useTanStackFieldContext } from '../form-context';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\n\nimport type { ComboboxFieldProps } from '../../types';\n\nexport const ComboboxField = memo<ComboboxFieldProps>(\n ({\n label,\n description,\n placeholder,\n tooltip,\n helperText,\n orientation = 'responsive',\n options,\n required = false,\n disabled = false,\n clearable = false,\n showErrorMessage = true,\n }) => {\n const errorId = useId();\n const field = useTanStackFieldContext<string | null>();\n const isMobile = useIsMobile();\n const [dialogOpen, setDialogOpen] = useState(false);\n const [popoverOpen, setPopoverOpen] = useState(false);\n\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n const isDisabled = disabled || isSubmitting;\n\n const _touched = field.state.meta.isDirty || field.state.meta.isTouched;\n const _invalid = _touched && !field.state.meta.isValid;\n const _isEmpty = required && field.state.value === null;\n const _showClear = clearable && !!field.state.value && !isDisabled;\n\n const selectedLabel = options.find(({ value }) => value === field.state.value)?.label;\n\n const onClear = () => {\n field.handleChange(null);\n field.handleBlur();\n };\n\n const triggerButton = (onClick?: () => void) => (\n <Button\n variant=\"outline\"\n color=\"muted\"\n size=\"lg\"\n disabled={isDisabled}\n aria-invalid={_invalid ? true : undefined}\n aria-describedby={errorId}\n className={cn(\n 'flex w-full items-center justify-start rounded outline-border',\n 'hover:bg-transparent',\n 'focus-visible:outline-1 focus-visible:outline-primary-strong focus-visible:ring-4 focus-visible:ring-primary-weak',\n 'data-[state=open]:text-text-positive-muted data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak',\n _showClear && 'pr-8',\n !field.state.value && 'text-text-positive-muted',\n _invalid && 'outline-danger bg-danger-bg-subtle ring-4 ring-danger-weak'\n )}\n onClick={onClick}\n >\n {selectedLabel ? (\n <p className=\"flex min-w-0 flex-1 items-center gap-2 truncate text-start\">{selectedLabel}</p>\n ) : (\n <p className=\"flex-1 text-start text-text-positive-muted\">{placeholder}</p>\n )}\n </Button>\n );\n\n const renderCommandList = (onSelect: (value: string) => void) => (\n <Command className=\"border-none\">\n <CommandInput placeholder={placeholder ?? 'Tìm kiếm…'} />\n <CommandList>\n <CommandEmpty className=\"flex min-h-30 items-center justify-center text-sm text-text-positive-weak\">Không tìm thấy kết quả nào phù hợp.</CommandEmpty>\n <CommandGroup className=\"max-h-60 overflow-y-auto\">\n {options.map(({ value, label: optLabel }) => (\n <CommandItem key={value} value={optLabel} onSelect={() => onSelect(value)}>\n {optLabel}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n );\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation={orientation} data-invalid={_invalid}>\n <FieldContent>\n <FieldLabel aria-required={_isEmpty} htmlFor={field.name}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n\n <FieldContentMain className=\"flex justify-end\">\n <div className=\"flex w-full flex-col\">\n <div className=\"relative\">\n {isMobile ? (\n <>\n {triggerButton(() => setDialogOpen(true))}\n <Dialog\n open={dialogOpen}\n onOpenChange={open => {\n setDialogOpen(open);\n if (!open) field.handleBlur();\n }}\n >\n <DialogPortal>\n <DialogOverlay />\n <RadixDialog.Content\n onOpenAutoFocus={e => e.preventDefault()}\n className={cn(\n 'fixed inset-x-0 bottom-0 z-50',\n 'flex flex-col bg-background rounded-t-2xl outline-none',\n 'max-h-[80dvh] shadow-[0_-4px_24px_rgba(0,0,0,0.08)]',\n 'data-[state=open]:animate-in data-[state=open]:slide-in-from-bottom data-[state=open]:fade-in-0',\n 'data-[state=closed]:animate-out data-[state=closed]:slide-out-to-bottom data-[state=closed]:fade-out-0',\n 'duration-300'\n )}\n >\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border shrink-0\">\n <span className=\"font-semibold text-sm text-text-positive\">{label}</span>\n <DialogClose asChild>\n <button\n type=\"button\"\n aria-label=\"Đóng\"\n className=\"flex size-7 items-center justify-center rounded-md text-text-positive-weak transition-colors hover:bg-muted-muted hover:text-text-positive\"\n >\n <XIcon size={16} />\n </button>\n </DialogClose>\n </div>\n\n <div className=\"flex flex-col overflow-y-auto\">\n {_showClear && (\n <DialogClose asChild>\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-x-2 px-4 py-3 text-left text-sm text-danger-strong transition-colors hover:bg-danger-bg-subtle\"\n onClick={onClear}\n >\n <XIcon size={14} />\n Xóa lựa chọn\n </button>\n </DialogClose>\n )}\n {renderCommandList(value => {\n field.handleChange(value);\n setDialogOpen(false);\n field.handleBlur();\n })}\n </div>\n\n <div className=\"shrink-0 h-safe-bottom\" />\n </RadixDialog.Content>\n </DialogPortal>\n </Dialog>\n </>\n ) : (\n <Popover\n open={popoverOpen}\n onOpenChange={open => {\n setPopoverOpen(open);\n if (!open) field.handleBlur();\n }}\n >\n <PopoverTrigger asChild>{triggerButton()}</PopoverTrigger>\n <PopoverContent align=\"end\" side=\"bottom\" className=\"flex w-fit rounded p-0\">\n {renderCommandList(value => {\n field.handleChange(value);\n setPopoverOpen(false);\n field.handleBlur();\n })}\n </PopoverContent>\n </Popover>\n )}\n\n {_showClear && (\n <button\n type=\"button\"\n aria-label=\"Xóa lựa chọn\"\n className=\"absolute right-2 top-1/2 -translate-y-1/2 flex size-4 cursor-pointer items-center justify-center rounded-md text-text-positive-weak outline-none transition-[color,transform] hover:text-text-positive focus-visible:text-primary-strong focus-visible:[&>svg]:scale-125 [&>svg]:size-3.5 [&>svg]:transition-transform\"\n onClick={onClear}\n >\n <XIcon aria-hidden=\"true\" />\n </button>\n )}\n </div>\n\n {_touched && showErrorMessage && <FieldError id={errorId} className=\"mt-1\" errors={field.state.meta.errors} />}\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </div>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n }\n);\n\nComboboxField.displayName = 'ComboboxField';\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ const e=require("./ui/button.cjs"),t=require("./ui/dialog.cjs"),n=require("./ui/command.cjs"),r=require("./ui/popover.cjs"),i=require("./tanstack-form-DS_ZvRl8.cjs"),a=require("./field-BV5twmKA.cjs");let o=require("lucide-react"),s=require("react"),c=require("@customafk/react-toolkit/utils"),l=require("react/jsx-runtime"),u=require("radix-ui"),d=require("@customafk/react-toolkit/hooks/useMobile"),f=require("@tanstack/react-form");const p=(0,s.memo)(({label:p,description:m,placeholder:h,tooltip:g,helperText:_,orientation:v=`responsive`,options:y,required:b=!1,disabled:x=!1,clearable:S=!1,showErrorMessage:C=!0})=>{let w=(0,s.useId)(),T=i.G(),E=(0,d.useIsMobile)(),[D,O]=(0,s.useState)(!1),[k,A]=(0,s.useState)(!1),j=(0,f.useStore)(T.form.store,({isSubmitting:e})=>e),M=x||j,N=T.state.meta.isDirty||T.state.meta.isTouched,P=N&&!T.state.meta.isValid,F=b&&T.state.value===null,I=S&&!!T.state.value&&!M,L=y.find(({value:e})=>e===T.state.value)?.label,R=()=>{T.handleChange(null),T.handleBlur()},z=t=>(0,l.jsx)(e.Button,{variant:`outline`,color:`muted`,size:`lg`,disabled:M,"aria-invalid":P?!0:void 0,"aria-describedby":w,className:(0,c.cn)(`flex w-full items-center justify-start rounded outline-border`,`hover:bg-transparent`,`focus-visible:outline-1 focus-visible:outline-primary-strong focus-visible:ring-4 focus-visible:ring-primary-weak`,`data-[state=open]:text-text-positive-muted data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak`,I&&`pr-8`,!T.state.value&&`text-text-positive-muted`,P&&`outline-danger bg-danger-bg-subtle ring-4 ring-danger-weak`),onClick:t,children:L?(0,l.jsx)(`p`,{className:`flex min-w-0 flex-1 items-center gap-2 truncate text-start`,children:L}):(0,l.jsx)(`p`,{className:`flex-1 text-start text-text-positive-muted`,children:h})}),B=e=>(0,l.jsxs)(n.Command,{className:`border-none`,children:[(0,l.jsx)(n.CommandInput,{placeholder:h??`Tìm kiếm…`}),(0,l.jsxs)(n.CommandList,{children:[(0,l.jsx)(n.CommandEmpty,{className:`flex min-h-30 items-center justify-center text-sm text-text-positive-weak`,children:`Không tìm thấy kết quả nào phù hợp.`}),(0,l.jsx)(n.CommandGroup,{className:`max-h-60 overflow-y-auto`,children:y.map(({value:t,label:r})=>(0,l.jsx)(n.CommandItem,{value:r,onSelect:()=>e(t),children:r},t))})]})]});return(0,l.jsxs)(a.FieldGroup,{className:`gap-y-4 px-4`,children:[(0,l.jsxs)(a.Field,{orientation:v,"data-invalid":P,children:[(0,l.jsxs)(a.FieldContent,{children:[(0,l.jsxs)(a.FieldLabel,{"aria-required":F,htmlFor:T.name,children:[p,g&&(0,l.jsx)(a.FieldTooltip,{tooltip:g})]}),(0,l.jsx)(a.FieldDescription,{children:m})]}),(0,l.jsx)(a.FieldContentMain,{className:`flex justify-end`,children:(0,l.jsxs)(`div`,{className:`flex w-full flex-col`,children:[(0,l.jsxs)(`div`,{className:`relative`,children:[E?(0,l.jsxs)(l.Fragment,{children:[z(()=>O(!0)),(0,l.jsx)(t.Dialog,{open:D,onOpenChange:e=>{O(e),e||T.handleBlur()},children:(0,l.jsxs)(t.DialogPortal,{children:[(0,l.jsx)(t.DialogOverlay,{}),(0,l.jsxs)(u.Dialog.Content,{onOpenAutoFocus:e=>e.preventDefault(),className:(0,c.cn)(`fixed inset-x-0 bottom-0 z-50`,`flex flex-col bg-background rounded-t-2xl outline-none`,`max-h-[80dvh] shadow-[0_-4px_24px_rgba(0,0,0,0.08)]`,`data-[state=open]:animate-in data-[state=open]:slide-in-from-bottom data-[state=open]:fade-in-0`,`data-[state=closed]:animate-out data-[state=closed]:slide-out-to-bottom data-[state=closed]:fade-out-0`,`duration-300`),children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between px-4 py-3 border-b border-border shrink-0`,children:[(0,l.jsx)(`span`,{className:`font-semibold text-sm text-text-positive`,children:p}),(0,l.jsx)(t.DialogClose,{asChild:!0,children:(0,l.jsx)(`button`,{type:`button`,"aria-label":`Đóng`,className:`flex size-7 items-center justify-center rounded-md text-text-positive-weak transition-colors hover:bg-muted-muted hover:text-text-positive`,children:(0,l.jsx)(o.XIcon,{size:16})})})]}),(0,l.jsxs)(`div`,{className:`flex flex-col overflow-y-auto`,children:[I&&(0,l.jsx)(t.DialogClose,{asChild:!0,children:(0,l.jsxs)(`button`,{type:`button`,className:`flex w-full items-center gap-x-2 px-4 py-3 text-left text-sm text-danger-strong transition-colors hover:bg-danger-bg-subtle`,onClick:R,children:[(0,l.jsx)(o.XIcon,{size:14}),`Xóa lựa chọn`]})}),B(e=>{T.handleChange(e),O(!1),T.handleBlur()})]}),(0,l.jsx)(`div`,{className:`shrink-0 h-safe-bottom`})]})]})})]}):(0,l.jsxs)(r.Popover,{open:k,onOpenChange:e=>{A(e),e||T.handleBlur()},children:[(0,l.jsx)(r.PopoverTrigger,{asChild:!0,children:z()}),(0,l.jsx)(r.PopoverContent,{align:`end`,side:`bottom`,className:`flex w-fit rounded p-0`,children:B(e=>{T.handleChange(e),A(!1),T.handleBlur()})})]}),I&&(0,l.jsx)(`button`,{type:`button`,"aria-label":`Xóa lựa chọn`,className:`absolute right-2 top-1/2 -translate-y-1/2 flex size-4 cursor-pointer items-center justify-center rounded-md text-text-positive-weak outline-none transition-[color,transform] hover:text-text-positive focus-visible:text-primary-strong focus-visible:[&>svg]:scale-125 [&>svg]:size-3.5 [&>svg]:transition-transform`,onClick:R,children:(0,l.jsx)(o.XIcon,{"aria-hidden":`true`})})]}),N&&C&&(0,l.jsx)(a.FieldError,{id:w,className:`mt-1`,errors:T.state.meta.errors}),(0,l.jsx)(a.FieldNote,{isShow:!!_,children:_})]})})]}),(0,l.jsx)(a.FieldSeparator,{})]})});p.displayName=`ComboboxField`,exports.ComboboxField=p;
2
+ //# sourceMappingURL=combobox-field-D9NdSih1.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"combobox-field-D9NdSih1.cjs","names":["useTanStackFieldContext","Button","Command","CommandInput","CommandList","CommandEmpty","CommandGroup","CommandItem","FieldGroup","Field","FieldContent","FieldLabel","FieldTooltip","FieldDescription","FieldContentMain","Dialog","DialogPortal","DialogOverlay","RadixDialog","DialogClose","XIcon","Popover","PopoverTrigger","PopoverContent","FieldError","FieldNote","FieldSeparator"],"sources":["../packages/components/features/tanstack-form/components/fields/combobox-field.tsx"],"sourcesContent":["'use client';\n\nimport { memo, useId, useState } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { XIcon } from 'lucide-react';\n\nimport { Dialog as RadixDialog } from 'radix-ui';\n\nimport { useIsMobile } from '@customafk/react-toolkit/hooks/useMobile';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command';\nimport { Dialog, DialogClose, DialogOverlay, DialogPortal } from '@/components/ui/dialog';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\n\nimport { useTanStackFieldContext } from '../form-context';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\n\nimport type { ComboboxFieldProps } from '../../types';\n\nexport const ComboboxField = memo<ComboboxFieldProps>(\n ({\n label,\n description,\n placeholder,\n tooltip,\n helperText,\n orientation = 'responsive',\n options,\n required = false,\n disabled = false,\n clearable = false,\n showErrorMessage = true,\n }) => {\n const errorId = useId();\n const field = useTanStackFieldContext<string | null>();\n const isMobile = useIsMobile();\n const [dialogOpen, setDialogOpen] = useState(false);\n const [popoverOpen, setPopoverOpen] = useState(false);\n\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n const isDisabled = disabled || isSubmitting;\n\n const _touched = field.state.meta.isDirty || field.state.meta.isTouched;\n const _invalid = _touched && !field.state.meta.isValid;\n const _isEmpty = required && field.state.value === null;\n const _showClear = clearable && !!field.state.value && !isDisabled;\n\n const selectedLabel = options.find(({ value }) => value === field.state.value)?.label;\n\n const onClear = () => {\n field.handleChange(null);\n field.handleBlur();\n };\n\n const triggerButton = (onClick?: () => void) => (\n <Button\n variant=\"outline\"\n color=\"muted\"\n size=\"lg\"\n disabled={isDisabled}\n aria-invalid={_invalid ? true : undefined}\n aria-describedby={errorId}\n className={cn(\n 'flex w-full items-center justify-start rounded outline-border',\n 'hover:bg-transparent',\n 'focus-visible:outline-1 focus-visible:outline-primary-strong focus-visible:ring-4 focus-visible:ring-primary-weak',\n 'data-[state=open]:text-text-positive-muted data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak',\n _showClear && 'pr-8',\n !field.state.value && 'text-text-positive-muted',\n _invalid && 'outline-danger bg-danger-bg-subtle ring-4 ring-danger-weak'\n )}\n onClick={onClick}\n >\n {selectedLabel ? (\n <p className=\"flex min-w-0 flex-1 items-center gap-2 truncate text-start\">{selectedLabel}</p>\n ) : (\n <p className=\"flex-1 text-start text-text-positive-muted\">{placeholder}</p>\n )}\n </Button>\n );\n\n const renderCommandList = (onSelect: (value: string) => void) => (\n <Command className=\"border-none\">\n <CommandInput placeholder={placeholder ?? 'Tìm kiếm…'} />\n <CommandList>\n <CommandEmpty className=\"flex min-h-30 items-center justify-center text-sm text-text-positive-weak\">Không tìm thấy kết quả nào phù hợp.</CommandEmpty>\n <CommandGroup className=\"max-h-60 overflow-y-auto\">\n {options.map(({ value, label: optLabel }) => (\n <CommandItem key={value} value={optLabel} onSelect={() => onSelect(value)}>\n {optLabel}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n );\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field orientation={orientation} data-invalid={_invalid}>\n <FieldContent>\n <FieldLabel aria-required={_isEmpty} htmlFor={field.name}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n\n <FieldContentMain className=\"flex justify-end\">\n <div className=\"flex w-full flex-col\">\n <div className=\"relative\">\n {isMobile ? (\n <>\n {triggerButton(() => setDialogOpen(true))}\n <Dialog\n open={dialogOpen}\n onOpenChange={open => {\n setDialogOpen(open);\n if (!open) field.handleBlur();\n }}\n >\n <DialogPortal>\n <DialogOverlay />\n <RadixDialog.Content\n onOpenAutoFocus={e => e.preventDefault()}\n className={cn(\n 'fixed inset-x-0 bottom-0 z-50',\n 'flex flex-col bg-background rounded-t-2xl outline-none',\n 'max-h-[80dvh] shadow-[0_-4px_24px_rgba(0,0,0,0.08)]',\n 'data-[state=open]:animate-in data-[state=open]:slide-in-from-bottom data-[state=open]:fade-in-0',\n 'data-[state=closed]:animate-out data-[state=closed]:slide-out-to-bottom data-[state=closed]:fade-out-0',\n 'duration-300'\n )}\n >\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border shrink-0\">\n <span className=\"font-semibold text-sm text-text-positive\">{label}</span>\n <DialogClose asChild>\n <button\n type=\"button\"\n aria-label=\"Đóng\"\n className=\"flex size-7 items-center justify-center rounded-md text-text-positive-weak transition-colors hover:bg-muted-muted hover:text-text-positive\"\n >\n <XIcon size={16} />\n </button>\n </DialogClose>\n </div>\n\n <div className=\"flex flex-col overflow-y-auto\">\n {_showClear && (\n <DialogClose asChild>\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-x-2 px-4 py-3 text-left text-sm text-danger-strong transition-colors hover:bg-danger-bg-subtle\"\n onClick={onClear}\n >\n <XIcon size={14} />\n Xóa lựa chọn\n </button>\n </DialogClose>\n )}\n {renderCommandList(value => {\n field.handleChange(value);\n setDialogOpen(false);\n field.handleBlur();\n })}\n </div>\n\n <div className=\"shrink-0 h-safe-bottom\" />\n </RadixDialog.Content>\n </DialogPortal>\n </Dialog>\n </>\n ) : (\n <Popover\n open={popoverOpen}\n onOpenChange={open => {\n setPopoverOpen(open);\n if (!open) field.handleBlur();\n }}\n >\n <PopoverTrigger asChild>{triggerButton()}</PopoverTrigger>\n <PopoverContent align=\"end\" side=\"bottom\" className=\"flex w-fit rounded p-0\">\n {renderCommandList(value => {\n field.handleChange(value);\n setPopoverOpen(false);\n field.handleBlur();\n })}\n </PopoverContent>\n </Popover>\n )}\n\n {_showClear && (\n <button\n type=\"button\"\n aria-label=\"Xóa lựa chọn\"\n className=\"absolute right-2 top-1/2 -translate-y-1/2 flex size-4 cursor-pointer items-center justify-center rounded-md text-text-positive-weak outline-none transition-[color,transform] hover:text-text-positive focus-visible:text-primary-strong focus-visible:[&>svg]:scale-125 [&>svg]:size-3.5 [&>svg]:transition-transform\"\n onClick={onClear}\n >\n <XIcon aria-hidden=\"true\" />\n </button>\n )}\n </div>\n\n {_touched && showErrorMessage && <FieldError id={errorId} className=\"mt-1\" errors={field.state.meta.errors} />}\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </div>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n }\n);\n\nComboboxField.displayName = 'ComboboxField';\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{jsx as e}from"react/jsx-runtime";const t=({children:t})=>e(`div`,{"data-slot":`section-form`,className:`flex flex-col space-y-4`,children:t});export{t as TanStackContainerForm};
2
+ //# sourceMappingURL=container-form-BdsEX0NH.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"container-form-BdsEX0NH.mjs","names":[],"sources":["../packages/components/features/tanstack-form/components/forms/container-form.tsx"],"sourcesContent":["/**\n * Wraps a set of TanStack form sections in a vertically-stacked flex container.\n *\n * @example\n * import { TanStackContainerForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <TanStackContainerForm>\n * <TanStackSectionForm title=\"Personal Info\">\n * {/* fields *\\/}\n * </TanStackSectionForm>\n * </TanStackContainerForm>\n */\nexport const TanStackContainerForm: React.FC<React.PropsWithChildren> = ({ children }) => {\n return (\n <div data-slot=\"section-form\" className=\"flex flex-col space-y-4\">\n {children}\n </div>\n );\n};\n"],"mappings":"wCAYA,MAAa,GAA4D,CAAE,cAEvE,EAAC,MAAD,CAAK,YAAU,eAAe,UAAU,0BACrC,UACE,CAAA"}
@@ -0,0 +1,2 @@
1
+ let e=require("react/jsx-runtime");const t=({children:t})=>(0,e.jsx)(`div`,{"data-slot":`section-form`,className:`flex flex-col space-y-4`,children:t});exports.TanStackContainerForm=t;
2
+ //# sourceMappingURL=container-form-CxxUYctk.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"container-form-CxxUYctk.cjs","names":[],"sources":["../packages/components/features/tanstack-form/components/forms/container-form.tsx"],"sourcesContent":["/**\n * Wraps a set of TanStack form sections in a vertically-stacked flex container.\n *\n * @example\n * import { TanStackContainerForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <TanStackContainerForm>\n * <TanStackSectionForm title=\"Personal Info\">\n * {/* fields *\\/}\n * </TanStackSectionForm>\n * </TanStackContainerForm>\n */\nexport const TanStackContainerForm: React.FC<React.PropsWithChildren> = ({ children }) => {\n return (\n <div data-slot=\"section-form\" className=\"flex flex-col space-y-4\">\n {children}\n </div>\n );\n};\n"],"mappings":"mCAYA,MAAa,GAA4D,CAAE,eAEvE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,YAAU,eAAe,UAAU,0BACrC,UACE,CAAA"}
@@ -0,0 +1,2 @@
1
+ const e=require("./ui/button.cjs"),t=require("./ui/popover.cjs"),n=require("./tanstack-form-DS_ZvRl8.cjs"),r=require("./ui/calendar.cjs"),i=require("./field-BV5twmKA.cjs");let a=require("lucide-react"),o=require("react"),s=require("@customafk/react-toolkit/utils"),c=require("react/jsx-runtime"),l=require("@customafk/react-toolkit/date-fns"),u=require("@tanstack/react-form");const d=(0,o.memo)(({label:d,description:f,placeholder:p,orientation:m=`responsive`,tooltip:h,helperText:g,showErrorMessage:_=!0,required:v=!1,disabled:y=!1,minDate:b,maxDate:x})=>{let S=(0,o.useId)(),C=n.G(),[w,T]=(0,o.useState)(!1),E=(0,u.useStore)(C.form.store,({isSubmitting:e})=>e),D=y||E,O=C.state.meta.isDirty||C.state.meta.isTouched,k=O&&!C.state.meta.isValid,A=v&&C.state.value===null,j=e=>{C.handleChange(e),T(!1)};return(0,c.jsxs)(i.FieldGroup,{className:`px-4`,children:[(0,c.jsxs)(i.Field,{orientation:m,"data-invalid":k,children:[(0,c.jsxs)(i.FieldContent,{children:[(0,c.jsxs)(i.FieldLabel,{htmlFor:C.name,"aria-required":A,children:[d,h&&(0,c.jsx)(i.FieldTooltip,{tooltip:h})]}),(0,c.jsx)(i.FieldDescription,{children:f})]}),(0,c.jsx)(i.FieldContentMain,{className:`flex flex-col space-y-1`,children:(0,c.jsxs)(`div`,{className:`flex w-full flex-col`,children:[(0,c.jsxs)(t.Popover,{open:w,onOpenChange:e=>{T(e),e||C.handleBlur()},children:[(0,c.jsx)(t.PopoverTrigger,{asChild:!0,children:(0,c.jsxs)(e.Button,{variant:`outline`,color:`muted`,size:`lg`,disabled:D,"aria-invalid":k?!0:void 0,"aria-describedby":S,className:(0,s.cn)(`flex items-center justify-between rounded font-normal outline-border`,`hover:bg-transparent`,`focus:outline-1 focus:outline-primary-strong focus:ring-4 focus:ring-primary-weak`,`data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak`,C.state.value===null&&`text-text-positive-muted`,k&&`outline-danger bg-danger-bg-subtle ring-4 ring-danger-weak`),children:[(0,c.jsx)(`p`,{children:C.state.value===null?p??`Select date`:(0,l.format)(C.state.value,`PPPP`)}),(0,c.jsx)(a.CalendarDaysIcon,{strokeWidth:1})]})}),(0,c.jsxs)(t.PopoverContent,{align:`start`,side:`bottom`,className:`flex w-fit min-w-0 overflow-y-auto rounded p-0`,children:[(0,c.jsxs)(`div`,{className:`flex h-full flex-col space-y-2 border-r border-r-border p-2 [&>button]:justify-start [&>button]:text-sm`,children:[(0,c.jsx)(e.Button,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>j((0,l.endOfToday)()),children:`Hôm nay`}),(0,c.jsx)(e.Button,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>j((0,l.endOfTomorrow)()),children:`Ngày mai`}),(0,c.jsx)(e.Button,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>j((0,l.endOfYesterday)()),children:`Hôm qua`}),(0,c.jsx)(e.Button,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>j((0,l.subDays)((0,l.endOfToday)(),3)),children:`3 ngày qua`}),(0,c.jsx)(e.Button,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>j((0,l.subDays)((0,l.endOfToday)(),7)),children:`7 ngày qua`}),(0,c.jsx)(e.Button,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>j((0,l.subDays)((0,l.endOfToday)(),30)),children:`30 ngày qua`}),(0,c.jsx)(e.Button,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>j((0,l.startOfMonth)((0,l.endOfToday)())),children:`Tháng này`}),(0,c.jsx)(e.Button,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>j((0,l.lastDayOfMonth)((0,l.endOfToday)())),children:`Tháng trước`})]}),(0,c.jsx)(`div`,{className:`flex flex-1 flex-col`,children:(0,c.jsx)(`div`,{className:`min-w-73 border-b border-b-border p-2`,children:(0,c.jsx)(r.Calendar,{mode:`single`,selected:C.state.value??void 0,hidden:{before:b??new Date(1900,0,1),after:x??new Date(2100,11,31)},onSelect:e=>{e&&j(e)}})})})]})]}),O&&_&&(0,c.jsx)(i.FieldError,{id:S,className:`mt-1`,errors:C.state.meta.errors}),(0,c.jsx)(i.FieldNote,{isShow:!!g,children:g})]})})]}),(0,c.jsx)(i.FieldSeparator,{})]})});d.displayName=`DateField`,exports.DateField=d;
2
+ //# sourceMappingURL=date-field-BqAX4M_h.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-field-BqAX4M_h.cjs","names":["useTanStackFieldContext","FieldGroup","Field","FieldContent","FieldLabel","FieldTooltip","FieldDescription","FieldContentMain","Popover","PopoverTrigger","Button","CalendarDaysIcon","PopoverContent","Calendar","FieldError","FieldNote","FieldSeparator"],"sources":["../packages/components/features/tanstack-form/components/fields/date-field.tsx"],"sourcesContent":["'use client';\n\nimport { memo, useId, useState } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { CalendarDaysIcon } from 'lucide-react';\n\nimport { endOfToday, endOfTomorrow, endOfYesterday, format, lastDayOfMonth, startOfMonth, subDays } from '@customafk/react-toolkit/date-fns';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Calendar } from '@/components/ui/calendar';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\n\nimport { useTanStackFieldContext } from '../form-context';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\n\nimport type { DateFieldProps as Props } from '../../types';\n\nexport const DateField = memo<Props>(\n ({\n label,\n description,\n placeholder,\n orientation = 'responsive',\n tooltip,\n helperText,\n showErrorMessage = true,\n required = false,\n disabled = false,\n minDate,\n maxDate,\n }) => {\n const errorId = useId();\n const field = useTanStackFieldContext<Date | null>();\n const [popoverOpen, setPopoverOpen] = useState(false);\n\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n const isDisabled = disabled || isSubmitting;\n\n const _touched = field.state.meta.isDirty || field.state.meta.isTouched;\n const _isInvalid = _touched && !field.state.meta.isValid;\n const _isEmpty = required && field.state.value === null;\n\n const handleSelect = (date: Date) => {\n field.handleChange(date);\n setPopoverOpen(false);\n };\n\n return (\n <FieldGroup className=\"px-4\">\n <Field orientation={orientation} data-invalid={_isInvalid}>\n <FieldContent>\n <FieldLabel htmlFor={field.name} aria-required={_isEmpty}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n\n <FieldContentMain className=\"flex flex-col space-y-1\">\n <div className=\"flex w-full flex-col\">\n <Popover\n open={popoverOpen}\n onOpenChange={open => {\n setPopoverOpen(open);\n if (!open) field.handleBlur();\n }}\n >\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n color=\"muted\"\n size=\"lg\"\n disabled={isDisabled}\n aria-invalid={_isInvalid ? true : undefined}\n aria-describedby={errorId}\n className={cn(\n 'flex items-center justify-between rounded font-normal outline-border',\n 'hover:bg-transparent',\n 'focus:outline-1 focus:outline-primary-strong focus:ring-4 focus:ring-primary-weak',\n 'data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak',\n field.state.value === null && 'text-text-positive-muted',\n _isInvalid && 'outline-danger bg-danger-bg-subtle ring-4 ring-danger-weak'\n )}\n >\n <p>{field.state.value === null ? (placeholder ?? 'Select date') : format(field.state.value, 'PPPP')}</p>\n <CalendarDaysIcon strokeWidth={1} />\n </Button>\n </PopoverTrigger>\n\n <PopoverContent align=\"start\" side=\"bottom\" className=\"flex w-fit min-w-0 overflow-y-auto rounded p-0\">\n <div className=\"flex h-full flex-col space-y-2 border-r border-r-border p-2 [&>button]:justify-start [&>button]:text-sm\">\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(endOfToday())}>\n Hôm nay\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(endOfTomorrow())}>\n Ngày mai\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(endOfYesterday())}>\n Hôm qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(subDays(endOfToday(), 3))}>\n 3 ngày qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(subDays(endOfToday(), 7))}>\n 7 ngày qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(subDays(endOfToday(), 30))}>\n 30 ngày qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(startOfMonth(endOfToday()))}>\n Tháng này\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(lastDayOfMonth(endOfToday()))}>\n Tháng trước\n </Button>\n </div>\n <div className=\"flex flex-1 flex-col\">\n <div className=\"min-w-73 border-b border-b-border p-2\">\n <Calendar\n mode=\"single\"\n selected={field.state.value ?? undefined}\n hidden={{\n before: minDate ?? new Date(1900, 0, 1),\n after: maxDate ?? new Date(2100, 11, 31),\n }}\n onSelect={date => {\n if (!date) return;\n handleSelect(date);\n }}\n />\n </div>\n </div>\n </PopoverContent>\n </Popover>\n\n {_touched && showErrorMessage && <FieldError id={errorId} className=\"mt-1\" errors={field.state.meta.errors} />}\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </div>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n }\n);\n\nDateField.displayName = 'DateField';\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{Button as e}from"./ui/button.mjs";import{Popover as t,PopoverContent as n,PopoverTrigger as r}from"./ui/popover.mjs";import{G as i}from"./tanstack-form-CM_Hb3JT.mjs";import{Calendar as a}from"./ui/calendar.mjs";import{Field as o,FieldContent as s,FieldContentMain as c,FieldDescription as l,FieldError as u,FieldGroup as d,FieldLabel as f,FieldNote as p,FieldSeparator as m,FieldTooltip as h}from"./field-BKyUqvzh.mjs";import{CalendarDaysIcon as g}from"lucide-react";import{memo as _,useId as v,useState as y}from"react";import{cn as b}from"@customafk/react-toolkit/utils";import{jsx as x,jsxs as S}from"react/jsx-runtime";import{endOfToday as C,endOfTomorrow as w,endOfYesterday as T,format as E,lastDayOfMonth as D,startOfMonth as O,subDays as k}from"@customafk/react-toolkit/date-fns";import{useStore as A}from"@tanstack/react-form";const j=_(({label:_,description:j,placeholder:M,orientation:N=`responsive`,tooltip:P,helperText:F,showErrorMessage:I=!0,required:L=!1,disabled:R=!1,minDate:z,maxDate:B})=>{let V=v(),H=i(),[U,W]=y(!1),G=A(H.form.store,({isSubmitting:e})=>e),K=R||G,q=H.state.meta.isDirty||H.state.meta.isTouched,J=q&&!H.state.meta.isValid,Y=L&&H.state.value===null,X=e=>{H.handleChange(e),W(!1)};return S(d,{className:`px-4`,children:[S(o,{orientation:N,"data-invalid":J,children:[S(s,{children:[S(f,{htmlFor:H.name,"aria-required":Y,children:[_,P&&x(h,{tooltip:P})]}),x(l,{children:j})]}),x(c,{className:`flex flex-col space-y-1`,children:S(`div`,{className:`flex w-full flex-col`,children:[S(t,{open:U,onOpenChange:e=>{W(e),e||H.handleBlur()},children:[x(r,{asChild:!0,children:S(e,{variant:`outline`,color:`muted`,size:`lg`,disabled:K,"aria-invalid":J?!0:void 0,"aria-describedby":V,className:b(`flex items-center justify-between rounded font-normal outline-border`,`hover:bg-transparent`,`focus:outline-1 focus:outline-primary-strong focus:ring-4 focus:ring-primary-weak`,`data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak`,H.state.value===null&&`text-text-positive-muted`,J&&`outline-danger bg-danger-bg-subtle ring-4 ring-danger-weak`),children:[x(`p`,{children:H.state.value===null?M??`Select date`:E(H.state.value,`PPPP`)}),x(g,{strokeWidth:1})]})}),S(n,{align:`start`,side:`bottom`,className:`flex w-fit min-w-0 overflow-y-auto rounded p-0`,children:[S(`div`,{className:`flex h-full flex-col space-y-2 border-r border-r-border p-2 [&>button]:justify-start [&>button]:text-sm`,children:[x(e,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>X(C()),children:`Hôm nay`}),x(e,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>X(w()),children:`Ngày mai`}),x(e,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>X(T()),children:`Hôm qua`}),x(e,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>X(k(C(),3)),children:`3 ngày qua`}),x(e,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>X(k(C(),7)),children:`7 ngày qua`}),x(e,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>X(k(C(),30)),children:`30 ngày qua`}),x(e,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>X(O(C())),children:`Tháng này`}),x(e,{variant:`ghost`,color:`muted`,className:`w-32`,onClick:()=>X(D(C())),children:`Tháng trước`})]}),x(`div`,{className:`flex flex-1 flex-col`,children:x(`div`,{className:`min-w-73 border-b border-b-border p-2`,children:x(a,{mode:`single`,selected:H.state.value??void 0,hidden:{before:z??new Date(1900,0,1),after:B??new Date(2100,11,31)},onSelect:e=>{e&&X(e)}})})})]})]}),q&&I&&x(u,{id:V,className:`mt-1`,errors:H.state.meta.errors}),x(p,{isShow:!!F,children:F})]})})]}),x(m,{})]})});j.displayName=`DateField`;export{j as DateField};
2
+ //# sourceMappingURL=date-field-Dm4ki1HS.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-field-Dm4ki1HS.mjs","names":[],"sources":["../packages/components/features/tanstack-form/components/fields/date-field.tsx"],"sourcesContent":["'use client';\n\nimport { memo, useId, useState } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { CalendarDaysIcon } from 'lucide-react';\n\nimport { endOfToday, endOfTomorrow, endOfYesterday, format, lastDayOfMonth, startOfMonth, subDays } from '@customafk/react-toolkit/date-fns';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Calendar } from '@/components/ui/calendar';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\n\nimport { useTanStackFieldContext } from '../form-context';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\n\nimport type { DateFieldProps as Props } from '../../types';\n\nexport const DateField = memo<Props>(\n ({\n label,\n description,\n placeholder,\n orientation = 'responsive',\n tooltip,\n helperText,\n showErrorMessage = true,\n required = false,\n disabled = false,\n minDate,\n maxDate,\n }) => {\n const errorId = useId();\n const field = useTanStackFieldContext<Date | null>();\n const [popoverOpen, setPopoverOpen] = useState(false);\n\n const isSubmitting = useStore(field.form.store, ({ isSubmitting }) => isSubmitting);\n const isDisabled = disabled || isSubmitting;\n\n const _touched = field.state.meta.isDirty || field.state.meta.isTouched;\n const _isInvalid = _touched && !field.state.meta.isValid;\n const _isEmpty = required && field.state.value === null;\n\n const handleSelect = (date: Date) => {\n field.handleChange(date);\n setPopoverOpen(false);\n };\n\n return (\n <FieldGroup className=\"px-4\">\n <Field orientation={orientation} data-invalid={_isInvalid}>\n <FieldContent>\n <FieldLabel htmlFor={field.name} aria-required={_isEmpty}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n\n <FieldContentMain className=\"flex flex-col space-y-1\">\n <div className=\"flex w-full flex-col\">\n <Popover\n open={popoverOpen}\n onOpenChange={open => {\n setPopoverOpen(open);\n if (!open) field.handleBlur();\n }}\n >\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n color=\"muted\"\n size=\"lg\"\n disabled={isDisabled}\n aria-invalid={_isInvalid ? true : undefined}\n aria-describedby={errorId}\n className={cn(\n 'flex items-center justify-between rounded font-normal outline-border',\n 'hover:bg-transparent',\n 'focus:outline-1 focus:outline-primary-strong focus:ring-4 focus:ring-primary-weak',\n 'data-[state=open]:outline-1 data-[state=open]:outline-primary-strong data-[state=open]:ring-4 data-[state=open]:ring-primary-weak',\n field.state.value === null && 'text-text-positive-muted',\n _isInvalid && 'outline-danger bg-danger-bg-subtle ring-4 ring-danger-weak'\n )}\n >\n <p>{field.state.value === null ? (placeholder ?? 'Select date') : format(field.state.value, 'PPPP')}</p>\n <CalendarDaysIcon strokeWidth={1} />\n </Button>\n </PopoverTrigger>\n\n <PopoverContent align=\"start\" side=\"bottom\" className=\"flex w-fit min-w-0 overflow-y-auto rounded p-0\">\n <div className=\"flex h-full flex-col space-y-2 border-r border-r-border p-2 [&>button]:justify-start [&>button]:text-sm\">\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(endOfToday())}>\n Hôm nay\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(endOfTomorrow())}>\n Ngày mai\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(endOfYesterday())}>\n Hôm qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(subDays(endOfToday(), 3))}>\n 3 ngày qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(subDays(endOfToday(), 7))}>\n 7 ngày qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(subDays(endOfToday(), 30))}>\n 30 ngày qua\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(startOfMonth(endOfToday()))}>\n Tháng này\n </Button>\n <Button variant=\"ghost\" color=\"muted\" className=\"w-32\" onClick={() => handleSelect(lastDayOfMonth(endOfToday()))}>\n Tháng trước\n </Button>\n </div>\n <div className=\"flex flex-1 flex-col\">\n <div className=\"min-w-73 border-b border-b-border p-2\">\n <Calendar\n mode=\"single\"\n selected={field.state.value ?? undefined}\n hidden={{\n before: minDate ?? new Date(1900, 0, 1),\n after: maxDate ?? new Date(2100, 11, 31),\n }}\n onSelect={date => {\n if (!date) return;\n handleSelect(date);\n }}\n />\n </div>\n </div>\n </PopoverContent>\n </Popover>\n\n {_touched && showErrorMessage && <FieldError id={errorId} className=\"mt-1\" errors={field.state.meta.errors} />}\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </div>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n }\n);\n\nDateField.displayName = 'DateField';\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{Separator as e}from"./ui/separator.mjs";import{Dialog as t,DialogContent as n,DialogOverlay as r,DialogPortal as i,DialogTitle as a}from"./ui/dialog.mjs";import{K as o}from"./tanstack-form-CM_Hb3JT.mjs";import{n as s,t as c}from"./submit-button-CGBaPzE9.mjs";import{useCallback as l}from"react";import{cn as u}from"@customafk/react-toolkit/utils";import{jsx as d,jsxs as f}from"react/jsx-runtime";const p=({title:p,submitText:m,width:h,maxWidth:g,className:_,open:v,onOpenChange:y,children:b})=>{let x=o(),S=l(e=>{e||x.reset(),y?.(e)},[x.reset,y]);return d(t,{open:v,onOpenChange:S,children:f(i,{"data-slot":`dialog-portal`,children:[d(r,{}),f(n,{style:{"--width":h,"--max-width":g},className:u(`flex size-full max-h-dvh max-w-dvw flex-col gap-0 overflow-y-auto rounded-none p-0 shadow-dialog sm:h-auto sm:max-h-[85dvh] sm:max-w-5xl sm:rounded-md`,h&&`sm:w-(--width)`,g&&`sm:max-w-(--max-width)`,_),onOpenAutoFocus:e=>{e.preventDefault()},onInteractOutside:e=>{e.preventDefault()},children:[d(`div`,{"data-slot":`dialog-header`,className:`flex items-center justify-center gap-2 px-6 py-5 text-center sm:text-left`,children:d(a,{"data-slot":`dialog-title`,className:`font-semibold text-lg tracking-tight`,children:p})}),d(e,{}),d(`div`,{"data-slot":`dialog-content`,className:`relative flex flex-col overflow-y-auto p-0 pt-4 max-sm:flex-1 sm:p-4`,children:b}),d(e,{}),f(`div`,{"data-slot":`dialog-footer`,className:`flex flex-col-reverse items-center justify-end gap-2 px-6 py-4 sm:flex-row max-sm:[&>button]:w-full`,children:[d(x.Subscribe,{selector:e=>({disabled:e.isSubmitting}),children:({disabled:e})=>d(s,{disabled:e,onClick:()=>{x.reset(),S(!1)}})}),d(x.Subscribe,{selector:e=>({isSubmitting:e.isSubmitting,disabled:e.isPristine||!e.isValid||e.isValidating||e.isSubmitting||!e.canSubmit}),children:({isSubmitting:e,disabled:t})=>d(c,{isSubmitting:e,disabled:t,submitText:m,onClick:()=>x.handleSubmit()})})]})]})]})})};export{p as TanStackDialogForm};
2
+ //# sourceMappingURL=dialog-form-ClWBZbUN.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog-form-ClWBZbUN.mjs","names":[],"sources":["../packages/components/features/tanstack-form/components/forms/dialog-form.tsx"],"sourcesContent":["'use client';\n\nimport { useCallback } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Dialog, DialogContent, DialogOverlay, DialogPortal, DialogTitle } from '@/components/ui/dialog';\nimport { Separator } from '@/components/ui/separator';\n\nimport { useTanStackFormContext } from '../form-context';\nimport { CancelButton } from '../ui/cancel-button';\nimport { SubmitButton } from '../ui/submit-button';\n\n/**\n * Renders a modal dialog that wraps a TanStack Form with a title, scrollable content area, and built-in submit/cancel actions.\n *\n * @example\n * import { TanStackDialogForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <TanStackDialogForm\n * title=\"Create User\"\n * submitText=\"Create\"\n * className=\"max-w-lg\"\n * open={isOpen}\n * onOpenChange={setIsOpen}\n * >\n * <NameField />\n * <EmailField />\n * </TanStackDialogForm>\n */\nexport const TanStackDialogForm: React.FC<\n React.PropsWithChildren<{\n /** Heading text displayed in the dialog title bar. */\n title: string;\n /** Custom label for the submit button. Defaults to the `SubmitButton` component's built-in label when omitted. */\n submitText?: string;\n /** Optional fixed width for the dialog content area, as a pixel number (e.g. `600`) or any CSS string (e.g. `'50%'`, `'40rem'`). Omit to let the dialog size itself based on content. */\n width?: number | string;\n /** Optional fixed max-width for the dialog content area, as a pixel number (e.g. `600`) or any CSS string (e.g. `'50%'`, `'40rem'`). Omit to let the dialog size itself based on content and viewport. */\n maxWidth?: number | string;\n /** Optional additional class name(s) to apply to the dialog content container. */\n className?: string;\n /** Controlled open state of the dialog. */\n open?: boolean;\n /** Callback fired when the dialog open state changes; the form is reset on close. */\n onOpenChange?: (open: boolean) => void;\n }>\n> = ({ title, submitText, width, maxWidth, className, open, onOpenChange, children }) => {\n const form = useTanStackFormContext();\n\n const handleOpenChange = useCallback(\n (open: boolean) => {\n if (!open) form.reset();\n onOpenChange?.(open);\n },\n [form.reset, onOpenChange]\n );\n\n return (\n <Dialog open={open} onOpenChange={handleOpenChange}>\n <DialogPortal data-slot=\"dialog-portal\">\n <DialogOverlay />\n <DialogContent\n style={\n {\n '--width': width,\n '--max-width': maxWidth,\n } as React.CSSProperties\n }\n className={cn(\n 'flex size-full max-h-dvh max-w-dvw flex-col gap-0 overflow-y-auto rounded-none p-0 shadow-dialog sm:h-auto sm:max-h-[85dvh] sm:max-w-5xl sm:rounded-md',\n width && `sm:w-(--width)`,\n maxWidth && `sm:max-w-(--max-width)`,\n className\n )}\n onOpenAutoFocus={event => {\n // Prevents focus from shifting to the content when the dialog opens, which can cause layout shift if the content includes autofocusable elements.\n event.preventDefault();\n }}\n onInteractOutside={event => {\n // Prevents the dialog from closing when clicking outside, since the form may have unsaved changes.\n event.preventDefault();\n }}\n >\n <div data-slot=\"dialog-header\" className=\"flex items-center justify-center gap-2 px-6 py-5 text-center sm:text-left\">\n <DialogTitle data-slot=\"dialog-title\" className=\"font-semibold text-lg tracking-tight\">\n {title}\n </DialogTitle>\n </div>\n <Separator />\n <div data-slot=\"dialog-content\" className=\"relative flex flex-col overflow-y-auto p-0 pt-4 max-sm:flex-1 sm:p-4\">\n {children}\n </div>\n <Separator />\n <div data-slot=\"dialog-footer\" className=\"flex flex-col-reverse items-center justify-end gap-2 px-6 py-4 sm:flex-row max-sm:[&>button]:w-full\">\n <form.Subscribe\n selector={state => ({ disabled: state.isSubmitting })}\n children={({ disabled }) => (\n <CancelButton\n disabled={disabled}\n onClick={() => {\n form.reset();\n handleOpenChange(false);\n }}\n />\n )}\n />\n <form.Subscribe\n selector={state => ({\n isSubmitting: state.isSubmitting,\n disabled: state.isPristine || !state.isValid || state.isValidating || state.isSubmitting || !state.canSubmit,\n })}\n children={({ isSubmitting, disabled }) => (\n <SubmitButton isSubmitting={isSubmitting} disabled={disabled} submitText={submitText} onClick={() => form.handleSubmit()} />\n )}\n />\n </div>\n </DialogContent>\n </DialogPortal>\n </Dialog>\n );\n};\n"],"mappings":"oZA8BA,MAAa,GAiBR,CAAE,QAAO,aAAY,QAAO,WAAU,YAAW,OAAM,eAAc,cAAe,CACvF,IAAM,EAAO,EAAuB,EAE9B,EAAmB,EACtB,GAAkB,CACZ,GAAM,EAAK,MAAM,EACtB,IAAe,CAAI,CACrB,EACA,CAAC,EAAK,MAAO,CAAY,CAC3B,EAEA,OACE,EAAC,EAAD,CAAc,OAAM,aAAc,WAChC,EAAC,EAAD,CAAc,YAAU,yBAAxB,CACE,EAAC,EAAD,CAAgB,CAAA,EAChB,EAAC,EAAD,CACE,MACE,CACE,UAAW,EACX,cAAe,CACjB,EAEF,UAAW,EACT,yJACA,GAAS,iBACT,GAAY,yBACZ,CACF,EACA,gBAAiB,GAAS,CAExB,EAAM,eAAe,CACvB,EACA,kBAAmB,GAAS,CAE1B,EAAM,eAAe,CACvB,WApBF,CAsBE,EAAC,MAAD,CAAK,YAAU,gBAAgB,UAAU,qFACvC,EAAC,EAAD,CAAa,YAAU,eAAe,UAAU,gDAC7C,CACU,CAAA,CACV,CAAA,EACL,EAAC,EAAD,CAAY,CAAA,EACZ,EAAC,MAAD,CAAK,YAAU,iBAAiB,UAAU,uEACvC,UACE,CAAA,EACL,EAAC,EAAD,CAAY,CAAA,EACZ,EAAC,MAAD,CAAK,YAAU,gBAAgB,UAAU,+GAAzC,CACE,EAAC,EAAK,UAAN,CACE,SAAU,IAAU,CAAE,SAAU,EAAM,YAAa,GACnD,UAAW,CAAE,cACX,EAAC,EAAD,CACY,WACV,YAAe,CACb,EAAK,MAAM,EACX,EAAiB,EAAK,CACxB,CACD,CAAA,CAEJ,CAAA,EACD,EAAC,EAAK,UAAN,CACE,SAAU,IAAU,CAClB,aAAc,EAAM,aACpB,SAAU,EAAM,YAAc,CAAC,EAAM,SAAW,EAAM,cAAgB,EAAM,cAAgB,CAAC,EAAM,SACrG,GACA,UAAW,CAAE,eAAc,cACzB,EAAC,EAAD,CAA4B,eAAwB,WAAsB,aAAY,YAAe,EAAK,aAAa,CAAI,CAAA,CAE9H,CAAA,CACE,GACQ,GACH,GACR,CAAA,CAEZ"}
@@ -0,0 +1,2 @@
1
+ const e=require("./ui/separator.cjs"),t=require("./ui/dialog.cjs"),n=require("./tanstack-form-DS_ZvRl8.cjs"),r=require("./submit-button-CvINfld5.cjs");let i=require("react"),a=require("@customafk/react-toolkit/utils"),o=require("react/jsx-runtime");const s=({title:s,submitText:c,width:l,maxWidth:u,className:d,open:f,onOpenChange:p,children:m})=>{let h=n.K(),g=(0,i.useCallback)(e=>{e||h.reset(),p?.(e)},[h.reset,p]);return(0,o.jsx)(t.Dialog,{open:f,onOpenChange:g,children:(0,o.jsxs)(t.DialogPortal,{"data-slot":`dialog-portal`,children:[(0,o.jsx)(t.DialogOverlay,{}),(0,o.jsxs)(t.DialogContent,{style:{"--width":l,"--max-width":u},className:(0,a.cn)(`flex size-full max-h-dvh max-w-dvw flex-col gap-0 overflow-y-auto rounded-none p-0 shadow-dialog sm:h-auto sm:max-h-[85dvh] sm:max-w-5xl sm:rounded-md`,l&&`sm:w-(--width)`,u&&`sm:max-w-(--max-width)`,d),onOpenAutoFocus:e=>{e.preventDefault()},onInteractOutside:e=>{e.preventDefault()},children:[(0,o.jsx)(`div`,{"data-slot":`dialog-header`,className:`flex items-center justify-center gap-2 px-6 py-5 text-center sm:text-left`,children:(0,o.jsx)(t.DialogTitle,{"data-slot":`dialog-title`,className:`font-semibold text-lg tracking-tight`,children:s})}),(0,o.jsx)(e.Separator,{}),(0,o.jsx)(`div`,{"data-slot":`dialog-content`,className:`relative flex flex-col overflow-y-auto p-0 pt-4 max-sm:flex-1 sm:p-4`,children:m}),(0,o.jsx)(e.Separator,{}),(0,o.jsxs)(`div`,{"data-slot":`dialog-footer`,className:`flex flex-col-reverse items-center justify-end gap-2 px-6 py-4 sm:flex-row max-sm:[&>button]:w-full`,children:[(0,o.jsx)(h.Subscribe,{selector:e=>({disabled:e.isSubmitting}),children:({disabled:e})=>(0,o.jsx)(r.n,{disabled:e,onClick:()=>{h.reset(),g(!1)}})}),(0,o.jsx)(h.Subscribe,{selector:e=>({isSubmitting:e.isSubmitting,disabled:e.isPristine||!e.isValid||e.isValidating||e.isSubmitting||!e.canSubmit}),children:({isSubmitting:e,disabled:t})=>(0,o.jsx)(r.t,{isSubmitting:e,disabled:t,submitText:c,onClick:()=>h.handleSubmit()})})]})]})]})})};exports.TanStackDialogForm=s;
2
+ //# sourceMappingURL=dialog-form-DN-NlQFO.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog-form-DN-NlQFO.cjs","names":["useTanStackFormContext","Dialog","DialogPortal","DialogOverlay","DialogContent","DialogTitle","Separator","CancelButton","SubmitButton"],"sources":["../packages/components/features/tanstack-form/components/forms/dialog-form.tsx"],"sourcesContent":["'use client';\n\nimport { useCallback } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Dialog, DialogContent, DialogOverlay, DialogPortal, DialogTitle } from '@/components/ui/dialog';\nimport { Separator } from '@/components/ui/separator';\n\nimport { useTanStackFormContext } from '../form-context';\nimport { CancelButton } from '../ui/cancel-button';\nimport { SubmitButton } from '../ui/submit-button';\n\n/**\n * Renders a modal dialog that wraps a TanStack Form with a title, scrollable content area, and built-in submit/cancel actions.\n *\n * @example\n * import { TanStackDialogForm } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <TanStackDialogForm\n * title=\"Create User\"\n * submitText=\"Create\"\n * className=\"max-w-lg\"\n * open={isOpen}\n * onOpenChange={setIsOpen}\n * >\n * <NameField />\n * <EmailField />\n * </TanStackDialogForm>\n */\nexport const TanStackDialogForm: React.FC<\n React.PropsWithChildren<{\n /** Heading text displayed in the dialog title bar. */\n title: string;\n /** Custom label for the submit button. Defaults to the `SubmitButton` component's built-in label when omitted. */\n submitText?: string;\n /** Optional fixed width for the dialog content area, as a pixel number (e.g. `600`) or any CSS string (e.g. `'50%'`, `'40rem'`). Omit to let the dialog size itself based on content. */\n width?: number | string;\n /** Optional fixed max-width for the dialog content area, as a pixel number (e.g. `600`) or any CSS string (e.g. `'50%'`, `'40rem'`). Omit to let the dialog size itself based on content and viewport. */\n maxWidth?: number | string;\n /** Optional additional class name(s) to apply to the dialog content container. */\n className?: string;\n /** Controlled open state of the dialog. */\n open?: boolean;\n /** Callback fired when the dialog open state changes; the form is reset on close. */\n onOpenChange?: (open: boolean) => void;\n }>\n> = ({ title, submitText, width, maxWidth, className, open, onOpenChange, children }) => {\n const form = useTanStackFormContext();\n\n const handleOpenChange = useCallback(\n (open: boolean) => {\n if (!open) form.reset();\n onOpenChange?.(open);\n },\n [form.reset, onOpenChange]\n );\n\n return (\n <Dialog open={open} onOpenChange={handleOpenChange}>\n <DialogPortal data-slot=\"dialog-portal\">\n <DialogOverlay />\n <DialogContent\n style={\n {\n '--width': width,\n '--max-width': maxWidth,\n } as React.CSSProperties\n }\n className={cn(\n 'flex size-full max-h-dvh max-w-dvw flex-col gap-0 overflow-y-auto rounded-none p-0 shadow-dialog sm:h-auto sm:max-h-[85dvh] sm:max-w-5xl sm:rounded-md',\n width && `sm:w-(--width)`,\n maxWidth && `sm:max-w-(--max-width)`,\n className\n )}\n onOpenAutoFocus={event => {\n // Prevents focus from shifting to the content when the dialog opens, which can cause layout shift if the content includes autofocusable elements.\n event.preventDefault();\n }}\n onInteractOutside={event => {\n // Prevents the dialog from closing when clicking outside, since the form may have unsaved changes.\n event.preventDefault();\n }}\n >\n <div data-slot=\"dialog-header\" className=\"flex items-center justify-center gap-2 px-6 py-5 text-center sm:text-left\">\n <DialogTitle data-slot=\"dialog-title\" className=\"font-semibold text-lg tracking-tight\">\n {title}\n </DialogTitle>\n </div>\n <Separator />\n <div data-slot=\"dialog-content\" className=\"relative flex flex-col overflow-y-auto p-0 pt-4 max-sm:flex-1 sm:p-4\">\n {children}\n </div>\n <Separator />\n <div data-slot=\"dialog-footer\" className=\"flex flex-col-reverse items-center justify-end gap-2 px-6 py-4 sm:flex-row max-sm:[&>button]:w-full\">\n <form.Subscribe\n selector={state => ({ disabled: state.isSubmitting })}\n children={({ disabled }) => (\n <CancelButton\n disabled={disabled}\n onClick={() => {\n form.reset();\n handleOpenChange(false);\n }}\n />\n )}\n />\n <form.Subscribe\n selector={state => ({\n isSubmitting: state.isSubmitting,\n disabled: state.isPristine || !state.isValid || state.isValidating || state.isSubmitting || !state.canSubmit,\n })}\n children={({ isSubmitting, disabled }) => (\n <SubmitButton isSubmitting={isSubmitting} disabled={disabled} submitText={submitText} onClick={() => form.handleSubmit()} />\n )}\n />\n </div>\n </DialogContent>\n </DialogPortal>\n </Dialog>\n );\n};\n"],"mappings":"yPA8BA,MAAa,GAiBR,CAAE,QAAO,aAAY,QAAO,WAAU,YAAW,OAAM,eAAc,cAAe,CACvF,IAAM,EAAOA,EAAAA,EAAuB,EAE9B,GAAA,EAAA,EAAA,YAAA,CACH,GAAkB,CACZ,GAAM,EAAK,MAAM,EACtB,IAAe,CAAI,CACrB,EACA,CAAC,EAAK,MAAO,CAAY,CAC3B,EAEA,OACE,EAAA,EAAA,IAAA,CAACC,EAAAA,OAAD,CAAc,OAAM,aAAc,YAChC,EAAA,EAAA,KAAA,CAACC,EAAAA,aAAD,CAAc,YAAU,yBAAxB,EACE,EAAA,EAAA,IAAA,CAACC,EAAAA,cAAD,CAAgB,CAAA,GAChB,EAAA,EAAA,KAAA,CAACC,EAAAA,cAAD,CACE,MACE,CACE,UAAW,EACX,cAAe,CACjB,EAEF,WAAA,EAAA,EAAA,GAAA,CACE,yJACA,GAAS,iBACT,GAAY,yBACZ,CACF,EACA,gBAAiB,GAAS,CAExB,EAAM,eAAe,CACvB,EACA,kBAAmB,GAAS,CAE1B,EAAM,eAAe,CACvB,WApBF,EAsBE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,YAAU,gBAAgB,UAAU,sFACvC,EAAA,EAAA,IAAA,CAACC,EAAAA,YAAD,CAAa,YAAU,eAAe,UAAU,gDAC7C,CACU,CAAA,CACV,CAAA,GACL,EAAA,EAAA,IAAA,CAACC,EAAAA,UAAD,CAAY,CAAA,GACZ,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,YAAU,iBAAiB,UAAU,uEACvC,UACE,CAAA,GACL,EAAA,EAAA,IAAA,CAACA,EAAAA,UAAD,CAAY,CAAA,GACZ,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,YAAU,gBAAgB,UAAU,+GAAzC,EACE,EAAA,EAAA,IAAA,CAAC,EAAK,UAAN,CACE,SAAU,IAAU,CAAE,SAAU,EAAM,YAAa,GACnD,UAAW,CAAE,eACX,EAAA,EAAA,IAAA,CAACC,EAAAA,EAAD,CACY,WACV,YAAe,CACb,EAAK,MAAM,EACX,EAAiB,EAAK,CACxB,CACD,CAAA,CAEJ,CAAA,GACD,EAAA,EAAA,IAAA,CAAC,EAAK,UAAN,CACE,SAAU,IAAU,CAClB,aAAc,EAAM,aACpB,SAAU,EAAM,YAAc,CAAC,EAAM,SAAW,EAAM,cAAgB,EAAM,cAAgB,CAAC,EAAM,SACrG,GACA,UAAW,CAAE,eAAc,eACzB,EAAA,EAAA,IAAA,CAACC,EAAAA,EAAD,CAA4B,eAAwB,WAAsB,aAAY,YAAe,EAAK,aAAa,CAAI,CAAA,CAE9H,CAAA,CACE,GACQ,GACH,GACR,CAAA,CAEZ"}
@@ -1,2 +1,2 @@
1
- "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../ui/alert-dialog.cjs");let t=require("lucide-react"),n=require("react"),r=require("react/jsx-runtime");const i=({open:i,isLoading:a=!1,title:o,description:s,cancelText:c=`Cancel`,submitText:l=`Confirm`,descriptionClassName:u,onOpenChange:d,onConfirm:f})=>{let p=(0,n.useCallback)(e=>{e.preventDefault(),e.stopPropagation(),f?.()},[f]);return(0,r.jsx)(e.AlertDialog,{open:i,onOpenChange:d,children:(0,r.jsxs)(e.AlertDialogContent,{className:`p-4 pb-5`,children:[(0,r.jsxs)(e.AlertDialogHeader,{className:`gap-2`,children:[(0,r.jsxs)(e.AlertDialogTitle,{className:`inline-flex items-center gap-x-1`,children:[(0,r.jsx)(t.TriangleAlert,{size:20}),(0,r.jsx)(`p`,{children:o})]}),(0,r.jsx)(e.AlertDialogDescription,{className:u,children:s})]}),(0,r.jsxs)(e.AlertDialogFooter,{children:[(0,r.jsx)(e.AlertDialogCancel,{children:c}),(0,r.jsx)(e.AlertDialogAction,{type:`button`,className:`min-h-9 w-full md:w-24`,onClick:p,children:a?(0,r.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center`,children:(0,r.jsx)(`div`,{className:`loader-spinner text-text-positive-weak`})}):l})]})]})})};exports.ConfirmDialog=i;
1
+ "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../ui/alert-dialog.cjs");let t=require("lucide-react"),n=require("react"),r=require("react/jsx-runtime");const i=({open:i,isLoading:a=!1,title:o,description:s,cancelText:c=`Hủy`,submitText:l=`Xác nhận`,descriptionClassName:u,onOpenChange:d,onConfirm:f})=>{let p=(0,n.useCallback)(e=>{e.preventDefault(),e.stopPropagation(),f?.()},[f]);return(0,r.jsx)(e.AlertDialog,{open:i,onOpenChange:d,children:(0,r.jsxs)(e.AlertDialogContent,{className:`p-4 pb-5`,children:[(0,r.jsxs)(e.AlertDialogHeader,{className:`gap-2`,children:[(0,r.jsxs)(e.AlertDialogTitle,{className:`inline-flex items-center gap-x-1`,children:[(0,r.jsx)(t.TriangleAlert,{size:20}),(0,r.jsx)(`p`,{children:o})]}),(0,r.jsx)(e.AlertDialogDescription,{className:u,children:s})]}),(0,r.jsxs)(e.AlertDialogFooter,{children:[(0,r.jsx)(e.AlertDialogCancel,{children:c}),(0,r.jsx)(e.AlertDialogAction,{type:`button`,className:`min-h-9 w-full md:w-24`,onClick:p,children:a?(0,r.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center`,children:(0,r.jsx)(`div`,{className:`loader-spinner text-text-positive-weak`})}):l})]})]})})};exports.ConfirmDialog=i;
2
2
  //# sourceMappingURL=confirm-dialog.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"confirm-dialog.cjs","names":["AlertDialog","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","TriangleAlert","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction"],"sources":["../../packages/components/dialogs/confirm-dialog.tsx"],"sourcesContent":["'use client';\n\nimport { useCallback } from 'react';\n\nimport { TriangleAlert } from 'lucide-react';\n\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from '../ui/alert-dialog';\n\n/**\n * Props for the {@link ConfirmDialog} component.\n */\nexport type ConfirmDialogProps = {\n /**\n * Controls whether the dialog is currently open.\n * This is a **controlled** prop — pair it with `onOpenChange` to manage state.\n */\n open?: boolean;\n\n /**\n * When `true`, shows an animated spinner inside the confirm button and\n * prevents double-submission. Typically bound to a mutation's pending state.\n *\n * @default false\n */\n isLoading?: boolean;\n\n /**\n * The dialog heading text. Keep it short and action-oriented,\n * e.g. `\"Delete user?\"` or `\"Unsaved changes\"`.\n */\n title: string;\n\n /**\n * Body copy explaining what will happen if the user confirms.\n * For irreversible actions, state explicitly that the action cannot be undone.\n */\n description: string;\n\n /**\n * Label for the cancel / dismiss button.\n *\n * @default \"Cancel\"\n */\n cancelText?: string;\n\n /**\n * Label for the confirm / submit button.\n *\n * @default \"Confirm\"\n */\n submitText?: string;\n\n /**\n * Additional class names applied to the `AlertDialogDescription` element.\n * Useful for overriding text color or font size for specific contexts.\n */\n descriptionClassName?: string;\n\n /**\n * Callback fired when the dialog open state changes.\n * Required to implement controlled open / close behavior.\n *\n * @param open - `true` when opening, `false` when closing.\n */\n onOpenChange?: (open: boolean) => void;\n\n /**\n * Async-safe callback fired when the user clicks the confirm button.\n * Supports both synchronous and `Promise`-returning functions.\n *\n * The dialog does **not** auto-close after `onConfirm` resolves — the caller\n * is responsible for setting `open` to `false` once the operation completes.\n *\n * @example\n * ```tsx\n * onConfirm={async () => {\n * await deleteUser(userId);\n * setOpen(false);\n * }}\n * ```\n */\n onConfirm?: () => Promise<void> | void;\n};\n\n/**\n * A controlled confirmation dialog for destructive or irreversible actions.\n *\n * Built on Radix UI's `AlertDialog` primitive. Renders a warning icon, title,\n * description, and Cancel / Confirm buttons. The confirm button supports an\n * async loading state to prevent double-submission.\n *\n * **Import:** `import { ConfirmDialog } from '@customafk/lunas-ui/dialogs/confirm-dialog'`\n *\n * @example Delete confirmation with React state\n * ```tsx\n * import { useState } from 'react';\n * import { Button } from '@customafk/lunas-ui/ui/button';\n * import { ConfirmDialog } from '@customafk/lunas-ui/dialogs/confirm-dialog';\n *\n * export function DeleteUserButton({ userId }: { userId: string }) {\n * const [open, setOpen] = useState(false);\n * const [isPending, setIsPending] = useState(false);\n *\n * const handleDelete = async () => {\n * setIsPending(true);\n * try {\n * await deleteUser(userId);\n * setOpen(false);\n * } finally {\n * setIsPending(false);\n * }\n * };\n *\n * return (\n * <>\n * <Button variant=\"outline\" color=\"danger\" onClick={() => setOpen(true)}>\n * Delete user\n * </Button>\n * <ConfirmDialog\n * open={open}\n * title=\"Delete user?\"\n * description=\"This action is permanent and cannot be undone.\"\n * submitText=\"Yes, delete\"\n * isLoading={isPending}\n * onOpenChange={setOpen}\n * onConfirm={handleDelete}\n * />\n * </>\n * );\n * }\n * ```\n *\n * @example With TanStack Query mutation\n * ```tsx\n * import { ConfirmDialog } from '@customafk/lunas-ui/dialogs/confirm-dialog';\n * import { useMutation } from '@tanstack/react-query';\n *\n * export function ArchiveDialog({ open, onOpenChange, id }: Props) {\n * const { mutateAsync, isPending } = useMutation({ mutationFn: archiveItem });\n *\n * return (\n * <ConfirmDialog\n * open={open}\n * title=\"Archive item?\"\n * description=\"The item will be hidden but can be restored later.\"\n * submitText=\"Archive\"\n * isLoading={isPending}\n * onOpenChange={onOpenChange}\n * onConfirm={() => mutateAsync(id).then(() => onOpenChange(false))}\n * />\n * );\n * }\n * ```\n */\nexport const ConfirmDialog: React.FC<ConfirmDialogProps> = ({\n open,\n isLoading = false,\n title,\n description,\n cancelText = 'Cancel',\n submitText = 'Confirm',\n descriptionClassName,\n onOpenChange,\n onConfirm,\n}) => {\n const handleConfirm = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n onConfirm?.();\n },\n [onConfirm]\n );\n\n return (\n <AlertDialog open={open} onOpenChange={onOpenChange}>\n <AlertDialogContent className=\"p-4 pb-5\">\n <AlertDialogHeader className=\"gap-2\">\n <AlertDialogTitle className=\"inline-flex items-center gap-x-1\">\n <TriangleAlert size={20} />\n <p>{title}</p>\n </AlertDialogTitle>\n <AlertDialogDescription className={descriptionClassName}>{description}</AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>{cancelText}</AlertDialogCancel>\n <AlertDialogAction type=\"button\" className=\"min-h-9 w-full md:w-24\" onClick={handleConfirm}>\n {isLoading ? (\n <div className=\"absolute inset-0 flex items-center justify-center\">\n <div className=\"loader-spinner text-text-positive-weak\" />\n </div>\n ) : (\n submitText\n )}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n );\n};\n"],"mappings":"0MAmKA,MAAa,GAA+C,CAC1D,OACA,YAAY,GACZ,QACA,cACA,aAAa,SACb,aAAa,UACb,uBACA,eACA,eACI,CACJ,IAAM,GAAA,EAAA,EAAA,YAAA,CACH,GAAwB,CACvB,EAAE,eAAe,EACjB,EAAE,gBAAgB,EAClB,IAAY,CACd,EACA,CAAC,CAAS,CACZ,EAEA,OACE,EAAA,EAAA,IAAA,CAACA,EAAAA,YAAD,CAAmB,OAAoB,yBACrC,EAAA,EAAA,KAAA,CAACC,EAAAA,mBAAD,CAAoB,UAAU,oBAA9B,EACE,EAAA,EAAA,KAAA,CAACC,EAAAA,kBAAD,CAAmB,UAAU,iBAA7B,EACE,EAAA,EAAA,KAAA,CAACC,EAAAA,iBAAD,CAAkB,UAAU,4CAA5B,EACE,EAAA,EAAA,IAAA,CAACC,EAAAA,cAAD,CAAe,KAAM,EAAK,CAAA,GAC1B,EAAA,EAAA,IAAA,CAAC,IAAD,CAAA,SAAI,CAAS,CAAA,CACG,KAClB,EAAA,EAAA,IAAA,CAACC,EAAAA,uBAAD,CAAwB,UAAW,WAAuB,CAAoC,CAAA,CAC7E,KACnB,EAAA,EAAA,KAAA,CAACC,EAAAA,kBAAD,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAACC,EAAAA,kBAAD,CAAA,SAAoB,CAA8B,CAAA,GAClD,EAAA,EAAA,IAAA,CAACC,EAAAA,kBAAD,CAAmB,KAAK,SAAS,UAAU,yBAAyB,QAAS,WAC1E,GACC,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,8DACb,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,wCAA0C,CAAA,CACtD,CAAA,EAEL,CAEe,CAAA,CACF,CAAA,CAAA,CACD,GACT,CAAA,CAEjB"}
1
+ {"version":3,"file":"confirm-dialog.cjs","names":["AlertDialog","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","TriangleAlert","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction"],"sources":["../../packages/components/dialogs/confirm-dialog.tsx"],"sourcesContent":["'use client';\n\nimport { useCallback } from 'react';\n\nimport { TriangleAlert } from 'lucide-react';\n\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from '../ui/alert-dialog';\n\n/**\n * Props for the {@link ConfirmDialog} component.\n */\nexport type ConfirmDialogProps = {\n /**\n * Controls whether the dialog is currently open.\n * This is a **controlled** prop — pair it with `onOpenChange` to manage state.\n */\n open?: boolean;\n\n /**\n * When `true`, shows an animated spinner inside the confirm button and\n * prevents double-submission. Typically bound to a mutation's pending state.\n *\n * @default false\n */\n isLoading?: boolean;\n\n /**\n * The dialog heading text. Keep it short and action-oriented,\n * e.g. `\"Delete user?\"` or `\"Unsaved changes\"`.\n */\n title: string;\n\n /**\n * Body copy explaining what will happen if the user confirms.\n * For irreversible actions, state explicitly that the action cannot be undone.\n */\n description: string;\n\n /**\n * Label for the cancel / dismiss button.\n *\n * @default \"Cancel\"\n */\n cancelText?: string;\n\n /**\n * Label for the confirm / submit button.\n *\n * @default \"Confirm\"\n */\n submitText?: string;\n\n /**\n * Additional class names applied to the `AlertDialogDescription` element.\n * Useful for overriding text color or font size for specific contexts.\n */\n descriptionClassName?: string;\n\n /**\n * Callback fired when the dialog open state changes.\n * Required to implement controlled open / close behavior.\n *\n * @param open - `true` when opening, `false` when closing.\n */\n onOpenChange?: (open: boolean) => void;\n\n /**\n * Async-safe callback fired when the user clicks the confirm button.\n * Supports both synchronous and `Promise`-returning functions.\n *\n * The dialog does **not** auto-close after `onConfirm` resolves — the caller\n * is responsible for setting `open` to `false` once the operation completes.\n *\n * @example\n * ```tsx\n * onConfirm={async () => {\n * await deleteUser(userId);\n * setOpen(false);\n * }}\n * ```\n */\n onConfirm?: () => Promise<void> | void;\n};\n\n/**\n * A controlled confirmation dialog for destructive or irreversible actions.\n *\n * Built on Radix UI's `AlertDialog` primitive. Renders a warning icon, title,\n * description, and Cancel / Confirm buttons. The confirm button supports an\n * async loading state to prevent double-submission.\n *\n * **Import:** `import { ConfirmDialog } from '@customafk/lunas-ui/dialogs/confirm-dialog'`\n *\n * @example Delete confirmation with React state\n * ```tsx\n * import { useState } from 'react';\n * import { Button } from '@customafk/lunas-ui/ui/button';\n * import { ConfirmDialog } from '@customafk/lunas-ui/dialogs/confirm-dialog';\n *\n * export function DeleteUserButton({ userId }: { userId: string }) {\n * const [open, setOpen] = useState(false);\n * const [isPending, setIsPending] = useState(false);\n *\n * const handleDelete = async () => {\n * setIsPending(true);\n * try {\n * await deleteUser(userId);\n * setOpen(false);\n * } finally {\n * setIsPending(false);\n * }\n * };\n *\n * return (\n * <>\n * <Button variant=\"outline\" color=\"danger\" onClick={() => setOpen(true)}>\n * Delete user\n * </Button>\n * <ConfirmDialog\n * open={open}\n * title=\"Delete user?\"\n * description=\"This action is permanent and cannot be undone.\"\n * submitText=\"Yes, delete\"\n * isLoading={isPending}\n * onOpenChange={setOpen}\n * onConfirm={handleDelete}\n * />\n * </>\n * );\n * }\n * ```\n *\n * @example With TanStack Query mutation\n * ```tsx\n * import { ConfirmDialog } from '@customafk/lunas-ui/dialogs/confirm-dialog';\n * import { useMutation } from '@tanstack/react-query';\n *\n * export function ArchiveDialog({ open, onOpenChange, id }: Props) {\n * const { mutateAsync, isPending } = useMutation({ mutationFn: archiveItem });\n *\n * return (\n * <ConfirmDialog\n * open={open}\n * title=\"Archive item?\"\n * description=\"The item will be hidden but can be restored later.\"\n * submitText=\"Archive\"\n * isLoading={isPending}\n * onOpenChange={onOpenChange}\n * onConfirm={() => mutateAsync(id).then(() => onOpenChange(false))}\n * />\n * );\n * }\n * ```\n */\nexport const ConfirmDialog: React.FC<ConfirmDialogProps> = ({\n open,\n isLoading = false,\n title,\n description,\n cancelText = 'Hủy',\n submitText = 'Xác nhận',\n descriptionClassName,\n onOpenChange,\n onConfirm,\n}) => {\n const handleConfirm = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n onConfirm?.();\n },\n [onConfirm]\n );\n\n return (\n <AlertDialog open={open} onOpenChange={onOpenChange}>\n <AlertDialogContent className=\"p-4 pb-5\">\n <AlertDialogHeader className=\"gap-2\">\n <AlertDialogTitle className=\"inline-flex items-center gap-x-1\">\n <TriangleAlert size={20} />\n <p>{title}</p>\n </AlertDialogTitle>\n <AlertDialogDescription className={descriptionClassName}>{description}</AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>{cancelText}</AlertDialogCancel>\n <AlertDialogAction type=\"button\" className=\"min-h-9 w-full md:w-24\" onClick={handleConfirm}>\n {isLoading ? (\n <div className=\"absolute inset-0 flex items-center justify-center\">\n <div className=\"loader-spinner text-text-positive-weak\" />\n </div>\n ) : (\n submitText\n )}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n );\n};\n"],"mappings":"0MAmKA,MAAa,GAA+C,CAC1D,OACA,YAAY,GACZ,QACA,cACA,aAAa,MACb,aAAa,WACb,uBACA,eACA,eACI,CACJ,IAAM,GAAA,EAAA,EAAA,YAAA,CACH,GAAwB,CACvB,EAAE,eAAe,EACjB,EAAE,gBAAgB,EAClB,IAAY,CACd,EACA,CAAC,CAAS,CACZ,EAEA,OACE,EAAA,EAAA,IAAA,CAACA,EAAAA,YAAD,CAAmB,OAAoB,yBACrC,EAAA,EAAA,KAAA,CAACC,EAAAA,mBAAD,CAAoB,UAAU,oBAA9B,EACE,EAAA,EAAA,KAAA,CAACC,EAAAA,kBAAD,CAAmB,UAAU,iBAA7B,EACE,EAAA,EAAA,KAAA,CAACC,EAAAA,iBAAD,CAAkB,UAAU,4CAA5B,EACE,EAAA,EAAA,IAAA,CAACC,EAAAA,cAAD,CAAe,KAAM,EAAK,CAAA,GAC1B,EAAA,EAAA,IAAA,CAAC,IAAD,CAAA,SAAI,CAAS,CAAA,CACG,KAClB,EAAA,EAAA,IAAA,CAACC,EAAAA,uBAAD,CAAwB,UAAW,WAAuB,CAAoC,CAAA,CAC7E,KACnB,EAAA,EAAA,KAAA,CAACC,EAAAA,kBAAD,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAACC,EAAAA,kBAAD,CAAA,SAAoB,CAA8B,CAAA,GAClD,EAAA,EAAA,IAAA,CAACC,EAAAA,kBAAD,CAAmB,KAAK,SAAS,UAAU,yBAAyB,QAAS,WAC1E,GACC,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,8DACb,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,wCAA0C,CAAA,CACtD,CAAA,EAEL,CAEe,CAAA,CACF,CAAA,CAAA,CACD,GACT,CAAA,CAEjB"}
@@ -1,2 +1,2 @@
1
- "use client";import{AlertDialog as e,AlertDialogAction as t,AlertDialogCancel as n,AlertDialogContent as r,AlertDialogDescription as i,AlertDialogFooter as a,AlertDialogHeader as o,AlertDialogTitle as s}from"../ui/alert-dialog.mjs";import{TriangleAlert as c}from"lucide-react";import{useCallback as l}from"react";import{jsx as u,jsxs as d}from"react/jsx-runtime";const f=({open:f,isLoading:p=!1,title:m,description:h,cancelText:g=`Cancel`,submitText:_=`Confirm`,descriptionClassName:v,onOpenChange:y,onConfirm:b})=>{let x=l(e=>{e.preventDefault(),e.stopPropagation(),b?.()},[b]);return u(e,{open:f,onOpenChange:y,children:d(r,{className:`p-4 pb-5`,children:[d(o,{className:`gap-2`,children:[d(s,{className:`inline-flex items-center gap-x-1`,children:[u(c,{size:20}),u(`p`,{children:m})]}),u(i,{className:v,children:h})]}),d(a,{children:[u(n,{children:g}),u(t,{type:`button`,className:`min-h-9 w-full md:w-24`,onClick:x,children:p?u(`div`,{className:`absolute inset-0 flex items-center justify-center`,children:u(`div`,{className:`loader-spinner text-text-positive-weak`})}):_})]})]})})};export{f as ConfirmDialog};
1
+ "use client";import{AlertDialog as e,AlertDialogAction as t,AlertDialogCancel as n,AlertDialogContent as r,AlertDialogDescription as i,AlertDialogFooter as a,AlertDialogHeader as o,AlertDialogTitle as s}from"../ui/alert-dialog.mjs";import{TriangleAlert as c}from"lucide-react";import{useCallback as l}from"react";import{jsx as u,jsxs as d}from"react/jsx-runtime";const f=({open:f,isLoading:p=!1,title:m,description:h,cancelText:g=`Hủy`,submitText:_=`Xác nhận`,descriptionClassName:v,onOpenChange:y,onConfirm:b})=>{let x=l(e=>{e.preventDefault(),e.stopPropagation(),b?.()},[b]);return u(e,{open:f,onOpenChange:y,children:d(r,{className:`p-4 pb-5`,children:[d(o,{className:`gap-2`,children:[d(s,{className:`inline-flex items-center gap-x-1`,children:[u(c,{size:20}),u(`p`,{children:m})]}),u(i,{className:v,children:h})]}),d(a,{children:[u(n,{children:g}),u(t,{type:`button`,className:`min-h-9 w-full md:w-24`,onClick:x,children:p?u(`div`,{className:`absolute inset-0 flex items-center justify-center`,children:u(`div`,{className:`loader-spinner text-text-positive-weak`})}):_})]})]})})};export{f as ConfirmDialog};
2
2
  //# sourceMappingURL=confirm-dialog.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"confirm-dialog.mjs","names":[],"sources":["../../packages/components/dialogs/confirm-dialog.tsx"],"sourcesContent":["'use client';\n\nimport { useCallback } from 'react';\n\nimport { TriangleAlert } from 'lucide-react';\n\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from '../ui/alert-dialog';\n\n/**\n * Props for the {@link ConfirmDialog} component.\n */\nexport type ConfirmDialogProps = {\n /**\n * Controls whether the dialog is currently open.\n * This is a **controlled** prop — pair it with `onOpenChange` to manage state.\n */\n open?: boolean;\n\n /**\n * When `true`, shows an animated spinner inside the confirm button and\n * prevents double-submission. Typically bound to a mutation's pending state.\n *\n * @default false\n */\n isLoading?: boolean;\n\n /**\n * The dialog heading text. Keep it short and action-oriented,\n * e.g. `\"Delete user?\"` or `\"Unsaved changes\"`.\n */\n title: string;\n\n /**\n * Body copy explaining what will happen if the user confirms.\n * For irreversible actions, state explicitly that the action cannot be undone.\n */\n description: string;\n\n /**\n * Label for the cancel / dismiss button.\n *\n * @default \"Cancel\"\n */\n cancelText?: string;\n\n /**\n * Label for the confirm / submit button.\n *\n * @default \"Confirm\"\n */\n submitText?: string;\n\n /**\n * Additional class names applied to the `AlertDialogDescription` element.\n * Useful for overriding text color or font size for specific contexts.\n */\n descriptionClassName?: string;\n\n /**\n * Callback fired when the dialog open state changes.\n * Required to implement controlled open / close behavior.\n *\n * @param open - `true` when opening, `false` when closing.\n */\n onOpenChange?: (open: boolean) => void;\n\n /**\n * Async-safe callback fired when the user clicks the confirm button.\n * Supports both synchronous and `Promise`-returning functions.\n *\n * The dialog does **not** auto-close after `onConfirm` resolves — the caller\n * is responsible for setting `open` to `false` once the operation completes.\n *\n * @example\n * ```tsx\n * onConfirm={async () => {\n * await deleteUser(userId);\n * setOpen(false);\n * }}\n * ```\n */\n onConfirm?: () => Promise<void> | void;\n};\n\n/**\n * A controlled confirmation dialog for destructive or irreversible actions.\n *\n * Built on Radix UI's `AlertDialog` primitive. Renders a warning icon, title,\n * description, and Cancel / Confirm buttons. The confirm button supports an\n * async loading state to prevent double-submission.\n *\n * **Import:** `import { ConfirmDialog } from '@customafk/lunas-ui/dialogs/confirm-dialog'`\n *\n * @example Delete confirmation with React state\n * ```tsx\n * import { useState } from 'react';\n * import { Button } from '@customafk/lunas-ui/ui/button';\n * import { ConfirmDialog } from '@customafk/lunas-ui/dialogs/confirm-dialog';\n *\n * export function DeleteUserButton({ userId }: { userId: string }) {\n * const [open, setOpen] = useState(false);\n * const [isPending, setIsPending] = useState(false);\n *\n * const handleDelete = async () => {\n * setIsPending(true);\n * try {\n * await deleteUser(userId);\n * setOpen(false);\n * } finally {\n * setIsPending(false);\n * }\n * };\n *\n * return (\n * <>\n * <Button variant=\"outline\" color=\"danger\" onClick={() => setOpen(true)}>\n * Delete user\n * </Button>\n * <ConfirmDialog\n * open={open}\n * title=\"Delete user?\"\n * description=\"This action is permanent and cannot be undone.\"\n * submitText=\"Yes, delete\"\n * isLoading={isPending}\n * onOpenChange={setOpen}\n * onConfirm={handleDelete}\n * />\n * </>\n * );\n * }\n * ```\n *\n * @example With TanStack Query mutation\n * ```tsx\n * import { ConfirmDialog } from '@customafk/lunas-ui/dialogs/confirm-dialog';\n * import { useMutation } from '@tanstack/react-query';\n *\n * export function ArchiveDialog({ open, onOpenChange, id }: Props) {\n * const { mutateAsync, isPending } = useMutation({ mutationFn: archiveItem });\n *\n * return (\n * <ConfirmDialog\n * open={open}\n * title=\"Archive item?\"\n * description=\"The item will be hidden but can be restored later.\"\n * submitText=\"Archive\"\n * isLoading={isPending}\n * onOpenChange={onOpenChange}\n * onConfirm={() => mutateAsync(id).then(() => onOpenChange(false))}\n * />\n * );\n * }\n * ```\n */\nexport const ConfirmDialog: React.FC<ConfirmDialogProps> = ({\n open,\n isLoading = false,\n title,\n description,\n cancelText = 'Cancel',\n submitText = 'Confirm',\n descriptionClassName,\n onOpenChange,\n onConfirm,\n}) => {\n const handleConfirm = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n onConfirm?.();\n },\n [onConfirm]\n );\n\n return (\n <AlertDialog open={open} onOpenChange={onOpenChange}>\n <AlertDialogContent className=\"p-4 pb-5\">\n <AlertDialogHeader className=\"gap-2\">\n <AlertDialogTitle className=\"inline-flex items-center gap-x-1\">\n <TriangleAlert size={20} />\n <p>{title}</p>\n </AlertDialogTitle>\n <AlertDialogDescription className={descriptionClassName}>{description}</AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>{cancelText}</AlertDialogCancel>\n <AlertDialogAction type=\"button\" className=\"min-h-9 w-full md:w-24\" onClick={handleConfirm}>\n {isLoading ? (\n <div className=\"absolute inset-0 flex items-center justify-center\">\n <div className=\"loader-spinner text-text-positive-weak\" />\n </div>\n ) : (\n submitText\n )}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n );\n};\n"],"mappings":"2WAmKA,MAAa,GAA+C,CAC1D,OACA,YAAY,GACZ,QACA,cACA,aAAa,SACb,aAAa,UACb,uBACA,eACA,eACI,CACJ,IAAM,EAAgB,EACnB,GAAwB,CACvB,EAAE,eAAe,EACjB,EAAE,gBAAgB,EAClB,IAAY,CACd,EACA,CAAC,CAAS,CACZ,EAEA,OACE,EAAC,EAAD,CAAmB,OAAoB,wBACrC,EAAC,EAAD,CAAoB,UAAU,oBAA9B,CACE,EAAC,EAAD,CAAmB,UAAU,iBAA7B,CACE,EAAC,EAAD,CAAkB,UAAU,4CAA5B,CACE,EAAC,EAAD,CAAe,KAAM,EAAK,CAAA,EAC1B,EAAC,IAAD,CAAA,SAAI,CAAS,CAAA,CACG,IAClB,EAAC,EAAD,CAAwB,UAAW,WAAuB,CAAoC,CAAA,CAC7E,IACnB,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CAAA,SAAoB,CAA8B,CAAA,EAClD,EAAC,EAAD,CAAmB,KAAK,SAAS,UAAU,yBAAyB,QAAS,WAC1E,EACC,EAAC,MAAD,CAAK,UAAU,6DACb,EAAC,MAAD,CAAK,UAAU,wCAA0C,CAAA,CACtD,CAAA,EAEL,CAEe,CAAA,CACF,CAAA,CAAA,CACD,GACT,CAAA,CAEjB"}
1
+ {"version":3,"file":"confirm-dialog.mjs","names":[],"sources":["../../packages/components/dialogs/confirm-dialog.tsx"],"sourcesContent":["'use client';\n\nimport { useCallback } from 'react';\n\nimport { TriangleAlert } from 'lucide-react';\n\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from '../ui/alert-dialog';\n\n/**\n * Props for the {@link ConfirmDialog} component.\n */\nexport type ConfirmDialogProps = {\n /**\n * Controls whether the dialog is currently open.\n * This is a **controlled** prop — pair it with `onOpenChange` to manage state.\n */\n open?: boolean;\n\n /**\n * When `true`, shows an animated spinner inside the confirm button and\n * prevents double-submission. Typically bound to a mutation's pending state.\n *\n * @default false\n */\n isLoading?: boolean;\n\n /**\n * The dialog heading text. Keep it short and action-oriented,\n * e.g. `\"Delete user?\"` or `\"Unsaved changes\"`.\n */\n title: string;\n\n /**\n * Body copy explaining what will happen if the user confirms.\n * For irreversible actions, state explicitly that the action cannot be undone.\n */\n description: string;\n\n /**\n * Label for the cancel / dismiss button.\n *\n * @default \"Cancel\"\n */\n cancelText?: string;\n\n /**\n * Label for the confirm / submit button.\n *\n * @default \"Confirm\"\n */\n submitText?: string;\n\n /**\n * Additional class names applied to the `AlertDialogDescription` element.\n * Useful for overriding text color or font size for specific contexts.\n */\n descriptionClassName?: string;\n\n /**\n * Callback fired when the dialog open state changes.\n * Required to implement controlled open / close behavior.\n *\n * @param open - `true` when opening, `false` when closing.\n */\n onOpenChange?: (open: boolean) => void;\n\n /**\n * Async-safe callback fired when the user clicks the confirm button.\n * Supports both synchronous and `Promise`-returning functions.\n *\n * The dialog does **not** auto-close after `onConfirm` resolves — the caller\n * is responsible for setting `open` to `false` once the operation completes.\n *\n * @example\n * ```tsx\n * onConfirm={async () => {\n * await deleteUser(userId);\n * setOpen(false);\n * }}\n * ```\n */\n onConfirm?: () => Promise<void> | void;\n};\n\n/**\n * A controlled confirmation dialog for destructive or irreversible actions.\n *\n * Built on Radix UI's `AlertDialog` primitive. Renders a warning icon, title,\n * description, and Cancel / Confirm buttons. The confirm button supports an\n * async loading state to prevent double-submission.\n *\n * **Import:** `import { ConfirmDialog } from '@customafk/lunas-ui/dialogs/confirm-dialog'`\n *\n * @example Delete confirmation with React state\n * ```tsx\n * import { useState } from 'react';\n * import { Button } from '@customafk/lunas-ui/ui/button';\n * import { ConfirmDialog } from '@customafk/lunas-ui/dialogs/confirm-dialog';\n *\n * export function DeleteUserButton({ userId }: { userId: string }) {\n * const [open, setOpen] = useState(false);\n * const [isPending, setIsPending] = useState(false);\n *\n * const handleDelete = async () => {\n * setIsPending(true);\n * try {\n * await deleteUser(userId);\n * setOpen(false);\n * } finally {\n * setIsPending(false);\n * }\n * };\n *\n * return (\n * <>\n * <Button variant=\"outline\" color=\"danger\" onClick={() => setOpen(true)}>\n * Delete user\n * </Button>\n * <ConfirmDialog\n * open={open}\n * title=\"Delete user?\"\n * description=\"This action is permanent and cannot be undone.\"\n * submitText=\"Yes, delete\"\n * isLoading={isPending}\n * onOpenChange={setOpen}\n * onConfirm={handleDelete}\n * />\n * </>\n * );\n * }\n * ```\n *\n * @example With TanStack Query mutation\n * ```tsx\n * import { ConfirmDialog } from '@customafk/lunas-ui/dialogs/confirm-dialog';\n * import { useMutation } from '@tanstack/react-query';\n *\n * export function ArchiveDialog({ open, onOpenChange, id }: Props) {\n * const { mutateAsync, isPending } = useMutation({ mutationFn: archiveItem });\n *\n * return (\n * <ConfirmDialog\n * open={open}\n * title=\"Archive item?\"\n * description=\"The item will be hidden but can be restored later.\"\n * submitText=\"Archive\"\n * isLoading={isPending}\n * onOpenChange={onOpenChange}\n * onConfirm={() => mutateAsync(id).then(() => onOpenChange(false))}\n * />\n * );\n * }\n * ```\n */\nexport const ConfirmDialog: React.FC<ConfirmDialogProps> = ({\n open,\n isLoading = false,\n title,\n description,\n cancelText = 'Hủy',\n submitText = 'Xác nhận',\n descriptionClassName,\n onOpenChange,\n onConfirm,\n}) => {\n const handleConfirm = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n onConfirm?.();\n },\n [onConfirm]\n );\n\n return (\n <AlertDialog open={open} onOpenChange={onOpenChange}>\n <AlertDialogContent className=\"p-4 pb-5\">\n <AlertDialogHeader className=\"gap-2\">\n <AlertDialogTitle className=\"inline-flex items-center gap-x-1\">\n <TriangleAlert size={20} />\n <p>{title}</p>\n </AlertDialogTitle>\n <AlertDialogDescription className={descriptionClassName}>{description}</AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>{cancelText}</AlertDialogCancel>\n <AlertDialogAction type=\"button\" className=\"min-h-9 w-full md:w-24\" onClick={handleConfirm}>\n {isLoading ? (\n <div className=\"absolute inset-0 flex items-center justify-center\">\n <div className=\"loader-spinner text-text-positive-weak\" />\n </div>\n ) : (\n submitText\n )}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n );\n};\n"],"mappings":"2WAmKA,MAAa,GAA+C,CAC1D,OACA,YAAY,GACZ,QACA,cACA,aAAa,MACb,aAAa,WACb,uBACA,eACA,eACI,CACJ,IAAM,EAAgB,EACnB,GAAwB,CACvB,EAAE,eAAe,EACjB,EAAE,gBAAgB,EAClB,IAAY,CACd,EACA,CAAC,CAAS,CACZ,EAEA,OACE,EAAC,EAAD,CAAmB,OAAoB,wBACrC,EAAC,EAAD,CAAoB,UAAU,oBAA9B,CACE,EAAC,EAAD,CAAmB,UAAU,iBAA7B,CACE,EAAC,EAAD,CAAkB,UAAU,4CAA5B,CACE,EAAC,EAAD,CAAe,KAAM,EAAK,CAAA,EAC1B,EAAC,IAAD,CAAA,SAAI,CAAS,CAAA,CACG,IAClB,EAAC,EAAD,CAAwB,UAAW,WAAuB,CAAoC,CAAA,CAC7E,IACnB,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CAAA,SAAoB,CAA8B,CAAA,EAClD,EAAC,EAAD,CAAmB,KAAK,SAAS,UAAU,yBAAyB,QAAS,WAC1E,EACC,EAAC,MAAD,CAAK,UAAU,6DACb,EAAC,MAAD,CAAK,UAAU,wCAA0C,CAAA,CACtD,CAAA,EAEL,CAEe,CAAA,CACF,CAAA,CAAA,CACD,GACT,CAAA,CAEjB"}
@@ -0,0 +1,2 @@
1
+ import{Input as e}from"./ui/input.mjs";import{G as t}from"./tanstack-form-CM_Hb3JT.mjs";import{Field as n,FieldContent as r,FieldContentMain as i,FieldDescription as a,FieldError as o,FieldGroup as s,FieldLabel as c,FieldNote as l,FieldSeparator as u,FieldTooltip as d}from"./field-BKyUqvzh.mjs";import{AtSignIcon as f,XIcon as p}from"lucide-react";import{useCallback as m}from"react";import{cn as h}from"@customafk/react-toolkit/utils";import{jsx as g,jsxs as _}from"react/jsx-runtime";import{useStore as v}from"@tanstack/react-form";const y=({label:y,description:b,placeholder:x,tooltip:S,helperText:C,orientation:w=`responsive`,showErrorMessage:T=!0,required:E=!1,maxLength:D})=>{let{form:O,name:k,state:A,handleBlur:j,handleChange:M}=t(),N=v(O.store,({isSubmitting:e})=>e),P=A.meta.isDirty&&A.meta.isTouched&&!A.meta.isValid,F=E&&A.value===null,I=!N&&!!A.value,L=m(({target:{value:e}})=>{N||D&&e.length>D||M(e||null)},[N,D,M]),R=m(()=>{N||M(null)},[N,M]);return _(s,{className:`gap-y-4 px-4`,children:[_(n,{"data-invalid":P,orientation:w,children:[_(r,{children:[_(c,{htmlFor:k,"aria-required":F,children:[y,S&&g(d,{tooltip:S})]}),g(a,{children:b})]}),_(i,{children:[g(e,{id:k,name:k,value:A.value===null?``:A.value,"aria-invalid":P,autoComplete:`email`,placeholder:x,className:h(`pl-9`,I&&`pr-9`,N&&`pointer-events-none bg-muted-muted opacity-60`),onBlur:j,onChange:L}),g(`div`,{className:`absolute top-0 left-0 flex size-9 items-center justify-center text-muted`,children:g(f,{size:14})}),I&&g(`button`,{type:`button`,"aria-label":`Xóa`,className:`absolute inset-e-0 inset-y-0 top-3 flex h-fit w-8 cursor-pointer items-center justify-center rounded-e-md text-text-positive-weak outline-none transition-[color,box-shadow] hover:text-text-positive focus:text-text-positive-strong`,onClick:R,children:g(p,{size:14,"aria-hidden":`true`})}),g(`div`,{className:`mt-1 flex w-full items-start justify-start`,children:T&&A.meta.isDirty&&g(o,{errors:A.meta.errors})}),g(l,{isShow:!!C,children:C})]})]}),g(u,{})]})};export{y as EmailField};
2
+ //# sourceMappingURL=email-field-DZNR_JbT.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-field-DZNR_JbT.mjs","names":[],"sources":["../packages/components/features/tanstack-form/components/fields/email-field.tsx"],"sourcesContent":["'use client';\n\nimport { useCallback } from 'react';\n\nimport { useStore } from '@tanstack/react-form';\n\nimport { AtSignIcon, XIcon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Input } from '@/components/ui/input';\nimport {\n Field,\n FieldContent,\n FieldContentMain,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldNote,\n FieldSeparator,\n FieldTooltip,\n} from '../ui/field';\nimport { useTanStackFieldContext } from '../form-context';\n\nimport type { EmailFieldProps as Props } from '../../types';\n\n/**\n * A TanStack Form-connected email input field with an at-sign prefix icon,\n * optional clear button, and inline validation error display.\n *\n * @example\n * import { EmailField } from '@customafk/lunas-ui/features/tanstack-form';\n *\n * <form.Field name=\"email\">\n * {() => (\n * <EmailField\n * label=\"Email address\"\n * placeholder=\"you@example.com\"\n * required\n * />\n * )}\n * </form.Field>\n */\nexport const EmailField: React.FC<Props> = ({\n label,\n description,\n placeholder,\n tooltip,\n helperText,\n orientation = 'responsive',\n showErrorMessage = true,\n required = false,\n maxLength,\n}) => {\n const { form, name, state, handleBlur, handleChange } = useTanStackFieldContext<string | null>();\n\n const isSubmitting = useStore(form.store, ({ isSubmitting }) => isSubmitting);\n\n const _invalid = state.meta.isDirty && state.meta.isTouched && !state.meta.isValid;\n const _isEmpty = required && state.value === null;\n const _showClear = !isSubmitting && !!state.value;\n\n const onChange = useCallback<React.ChangeEventHandler<HTMLInputElement>>(\n ({ target: { value } }) => {\n if (isSubmitting) return;\n if (maxLength && value.length > maxLength) return;\n handleChange(value || null);\n },\n [isSubmitting, maxLength, handleChange]\n );\n\n const onClear = useCallback(() => {\n if (isSubmitting) return;\n handleChange(null);\n }, [isSubmitting, handleChange]);\n\n return (\n <FieldGroup className=\"gap-y-4 px-4\">\n <Field data-invalid={_invalid} orientation={orientation}>\n <FieldContent>\n <FieldLabel htmlFor={name} aria-required={_isEmpty}>\n {label}\n {tooltip && <FieldTooltip tooltip={tooltip} />}\n </FieldLabel>\n <FieldDescription>{description}</FieldDescription>\n </FieldContent>\n <FieldContentMain>\n <Input\n id={name}\n name={name}\n value={state.value === null ? '' : state.value}\n aria-invalid={_invalid}\n autoComplete=\"email\"\n placeholder={placeholder}\n className={cn('pl-9', _showClear && 'pr-9', isSubmitting && 'pointer-events-none bg-muted-muted opacity-60')}\n onBlur={handleBlur}\n onChange={onChange}\n />\n <div className=\"absolute top-0 left-0 flex size-9 items-center justify-center text-muted\">\n <AtSignIcon size={14} />\n </div>\n\n {_showClear && (\n <button\n type=\"button\"\n aria-label=\"Xóa\"\n className=\"absolute inset-e-0 inset-y-0 top-3 flex h-fit w-8 cursor-pointer items-center justify-center rounded-e-md text-text-positive-weak outline-none transition-[color,box-shadow] hover:text-text-positive focus:text-text-positive-strong\"\n onClick={onClear}\n >\n <XIcon size={14} aria-hidden=\"true\" />\n </button>\n )}\n\n <div className=\"mt-1 flex w-full items-start justify-start\">\n {showErrorMessage && state.meta.isDirty && <FieldError errors={state.meta.errors} />}\n </div>\n <FieldNote isShow={!!helperText}>{helperText}</FieldNote>\n </FieldContentMain>\n </Field>\n <FieldSeparator />\n </FieldGroup>\n );\n};\n"],"mappings":"uhBA4CA,MAAa,GAA+B,CAC1C,QACA,cACA,cACA,UACA,aACA,cAAc,aACd,mBAAmB,GACnB,WAAW,GACX,eACI,CACJ,GAAM,CAAE,OAAM,OAAM,QAAO,aAAY,gBAAiB,EAAuC,EAEzF,EAAe,EAAS,EAAK,OAAQ,CAAE,kBAAmB,CAAY,EAEtE,EAAW,EAAM,KAAK,SAAW,EAAM,KAAK,WAAa,CAAC,EAAM,KAAK,QACrE,EAAW,GAAY,EAAM,QAAU,KACvC,EAAa,CAAC,GAAgB,CAAC,CAAC,EAAM,MAEtC,EAAW,GACd,CAAE,OAAQ,CAAE,YAAc,CACrB,GACA,GAAa,EAAM,OAAS,GAChC,EAAa,GAAS,IAAI,CAC5B,EACA,CAAC,EAAc,EAAW,CAAY,CACxC,EAEM,EAAU,MAAkB,CAC5B,GACJ,EAAa,IAAI,CACnB,EAAG,CAAC,EAAc,CAAY,CAAC,EAE/B,OACE,EAAC,EAAD,CAAY,UAAU,wBAAtB,CACE,EAAC,EAAD,CAAO,eAAc,EAAuB,uBAA5C,CACE,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CAAY,QAAS,EAAM,gBAAe,WAA1C,CACG,EACA,GAAW,EAAC,EAAD,CAAuB,SAAU,CAAA,CACnC,IACZ,EAAC,EAAD,CAAA,SAAmB,CAA8B,CAAA,CACrC,CAAA,CAAA,EACd,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CACE,GAAI,EACE,OACN,MAAO,EAAM,QAAU,KAAO,GAAK,EAAM,MACzC,eAAc,EACd,aAAa,QACA,cACb,UAAW,EAAG,OAAQ,GAAc,OAAQ,GAAgB,+CAA+C,EAC3G,OAAQ,EACE,UACX,CAAA,EACD,EAAC,MAAD,CAAK,UAAU,oFACb,EAAC,EAAD,CAAY,KAAM,EAAK,CAAA,CACpB,CAAA,EAEJ,GACC,EAAC,SAAD,CACE,KAAK,SACL,aAAW,MACX,UAAU,wOACV,QAAS,WAET,EAAC,EAAD,CAAO,KAAM,GAAI,cAAY,MAAQ,CAAA,CAC/B,CAAA,EAGV,EAAC,MAAD,CAAK,UAAU,sDACZ,GAAoB,EAAM,KAAK,SAAW,EAAC,EAAD,CAAY,OAAQ,EAAM,KAAK,MAAS,CAAA,CAChF,CAAA,EACL,EAAC,EAAD,CAAW,OAAQ,CAAC,CAAC,WAAa,CAAsB,CAAA,CACxC,CAAA,CAAA,CACb,IACP,EAAC,EAAD,CAAiB,CAAA,CACP,GAEhB"}
@@ -0,0 +1,2 @@
1
+ const e=require("./ui/input.cjs"),t=require("./tanstack-form-DS_ZvRl8.cjs"),n=require("./field-BV5twmKA.cjs");let r=require("lucide-react"),i=require("react"),a=require("@customafk/react-toolkit/utils"),o=require("react/jsx-runtime"),s=require("@tanstack/react-form");const c=({label:c,description:l,placeholder:u,tooltip:d,helperText:f,orientation:p=`responsive`,showErrorMessage:m=!0,required:h=!1,maxLength:g})=>{let{form:_,name:v,state:y,handleBlur:b,handleChange:x}=t.G(),S=(0,s.useStore)(_.store,({isSubmitting:e})=>e),C=y.meta.isDirty&&y.meta.isTouched&&!y.meta.isValid,w=h&&y.value===null,T=!S&&!!y.value,E=(0,i.useCallback)(({target:{value:e}})=>{S||g&&e.length>g||x(e||null)},[S,g,x]),D=(0,i.useCallback)(()=>{S||x(null)},[S,x]);return(0,o.jsxs)(n.FieldGroup,{className:`gap-y-4 px-4`,children:[(0,o.jsxs)(n.Field,{"data-invalid":C,orientation:p,children:[(0,o.jsxs)(n.FieldContent,{children:[(0,o.jsxs)(n.FieldLabel,{htmlFor:v,"aria-required":w,children:[c,d&&(0,o.jsx)(n.FieldTooltip,{tooltip:d})]}),(0,o.jsx)(n.FieldDescription,{children:l})]}),(0,o.jsxs)(n.FieldContentMain,{children:[(0,o.jsx)(e.Input,{id:v,name:v,value:y.value===null?``:y.value,"aria-invalid":C,autoComplete:`email`,placeholder:u,className:(0,a.cn)(`pl-9`,T&&`pr-9`,S&&`pointer-events-none bg-muted-muted opacity-60`),onBlur:b,onChange:E}),(0,o.jsx)(`div`,{className:`absolute top-0 left-0 flex size-9 items-center justify-center text-muted`,children:(0,o.jsx)(r.AtSignIcon,{size:14})}),T&&(0,o.jsx)(`button`,{type:`button`,"aria-label":`Xóa`,className:`absolute inset-e-0 inset-y-0 top-3 flex h-fit w-8 cursor-pointer items-center justify-center rounded-e-md text-text-positive-weak outline-none transition-[color,box-shadow] hover:text-text-positive focus:text-text-positive-strong`,onClick:D,children:(0,o.jsx)(r.XIcon,{size:14,"aria-hidden":`true`})}),(0,o.jsx)(`div`,{className:`mt-1 flex w-full items-start justify-start`,children:m&&y.meta.isDirty&&(0,o.jsx)(n.FieldError,{errors:y.meta.errors})}),(0,o.jsx)(n.FieldNote,{isShow:!!f,children:f})]})]}),(0,o.jsx)(n.FieldSeparator,{})]})};exports.EmailField=c;
2
+ //# sourceMappingURL=email-field-lDd9ouFN.cjs.map