sevatech-library 1.0.0

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 (398) hide show
  1. package/README.md +655 -0
  2. package/dist/cjs/index.js +3565 -0
  3. package/dist/cjs/index.js.map +1 -0
  4. package/dist/cjs/types/components/avatar/avatar-group.component.d.ts +20 -0
  5. package/dist/cjs/types/components/avatar/avatar-group.component.d.ts.map +1 -0
  6. package/dist/cjs/types/components/avatar/avatar-label-group.component.d.ts +11 -0
  7. package/dist/cjs/types/components/avatar/avatar-label-group.component.d.ts.map +1 -0
  8. package/dist/cjs/types/components/avatar/avatar-profile.component.d.ts +5 -0
  9. package/dist/cjs/types/components/avatar/avatar-profile.component.d.ts.map +1 -0
  10. package/dist/cjs/types/components/avatar/avatar-user.component.d.ts +14 -0
  11. package/dist/cjs/types/components/avatar/avatar-user.component.d.ts.map +1 -0
  12. package/dist/cjs/types/components/avatar/avatar.component.d.ts +20 -0
  13. package/dist/cjs/types/components/avatar/avatar.component.d.ts.map +1 -0
  14. package/dist/cjs/types/components/avatar/avatar.constant.d.ts +35 -0
  15. package/dist/cjs/types/components/avatar/avatar.constant.d.ts.map +1 -0
  16. package/dist/cjs/types/components/avatar/avatar.interface.d.ts +28 -0
  17. package/dist/cjs/types/components/avatar/avatar.interface.d.ts.map +1 -0
  18. package/dist/cjs/types/components/avatar/index.d.ts +8 -0
  19. package/dist/cjs/types/components/avatar/index.d.ts.map +1 -0
  20. package/dist/cjs/types/components/bread-cumbs/bread-crumbs.component.d.ts +21 -0
  21. package/dist/cjs/types/components/bread-cumbs/bread-crumbs.component.d.ts.map +1 -0
  22. package/dist/cjs/types/components/button/button.component.d.ts +37 -0
  23. package/dist/cjs/types/components/button/button.component.d.ts.map +1 -0
  24. package/dist/cjs/types/components/button/button.constants.d.ts +33 -0
  25. package/dist/cjs/types/components/button/button.constants.d.ts.map +1 -0
  26. package/dist/cjs/types/components/button-bar/button-bar.component.d.ts +15 -0
  27. package/dist/cjs/types/components/button-bar/button-bar.component.d.ts.map +1 -0
  28. package/dist/cjs/types/components/checkbox/checkbox-content.component.d.ts +19 -0
  29. package/dist/cjs/types/components/checkbox/checkbox-content.component.d.ts.map +1 -0
  30. package/dist/cjs/types/components/checkbox/checkbox.component.d.ts +23 -0
  31. package/dist/cjs/types/components/checkbox/checkbox.component.d.ts.map +1 -0
  32. package/dist/cjs/types/components/checkbox/checkbox.constant.d.ts +26 -0
  33. package/dist/cjs/types/components/checkbox/checkbox.constant.d.ts.map +1 -0
  34. package/dist/cjs/types/components/chip/chip.component.d.ts +16 -0
  35. package/dist/cjs/types/components/chip/chip.component.d.ts.map +1 -0
  36. package/dist/cjs/types/components/chip/chip.constant.d.ts +16 -0
  37. package/dist/cjs/types/components/chip/chip.constant.d.ts.map +1 -0
  38. package/dist/cjs/types/components/date-field/date-field.component.d.ts +23 -0
  39. package/dist/cjs/types/components/date-field/date-field.component.d.ts.map +1 -0
  40. package/dist/cjs/types/components/date-range-picker/date-range-picker.component.d.ts +25 -0
  41. package/dist/cjs/types/components/date-range-picker/date-range-picker.component.d.ts.map +1 -0
  42. package/dist/cjs/types/components/dropdown-field/dropdown-field.component.d.ts +28 -0
  43. package/dist/cjs/types/components/dropdown-field/dropdown-field.component.d.ts.map +1 -0
  44. package/dist/cjs/types/components/grid/grid.component.d.ts +11 -0
  45. package/dist/cjs/types/components/grid/grid.component.d.ts.map +1 -0
  46. package/dist/cjs/types/components/icon/icon.element.d.ts +12 -0
  47. package/dist/cjs/types/components/icon/icon.element.d.ts.map +1 -0
  48. package/dist/cjs/types/components/icon/index.d.ts +2 -0
  49. package/dist/cjs/types/components/icon/index.d.ts.map +1 -0
  50. package/dist/cjs/types/components/image/image.element.d.ts +13 -0
  51. package/dist/cjs/types/components/image/image.element.d.ts.map +1 -0
  52. package/dist/cjs/types/components/image/image.enum.d.ts +6 -0
  53. package/dist/cjs/types/components/image/image.enum.d.ts.map +1 -0
  54. package/dist/cjs/types/components/image/index.d.ts +3 -0
  55. package/dist/cjs/types/components/image/index.d.ts.map +1 -0
  56. package/dist/cjs/types/components/index.d.ts +48 -0
  57. package/dist/cjs/types/components/index.d.ts.map +1 -0
  58. package/dist/cjs/types/components/input-stepper/input-stepper-skeleton.d.ts +9 -0
  59. package/dist/cjs/types/components/input-stepper/input-stepper-skeleton.d.ts.map +1 -0
  60. package/dist/cjs/types/components/input-stepper/input-stepper.component.d.ts +38 -0
  61. package/dist/cjs/types/components/input-stepper/input-stepper.component.d.ts.map +1 -0
  62. package/dist/cjs/types/components/input-stepper/input-stepper.constant.d.ts +32 -0
  63. package/dist/cjs/types/components/input-stepper/input-stepper.constant.d.ts.map +1 -0
  64. package/dist/cjs/types/components/link/index.d.ts +3 -0
  65. package/dist/cjs/types/components/link/index.d.ts.map +1 -0
  66. package/dist/cjs/types/components/link/link-internal.element.d.ts +9 -0
  67. package/dist/cjs/types/components/link/link-internal.element.d.ts.map +1 -0
  68. package/dist/cjs/types/components/link/link.element.d.ts +8 -0
  69. package/dist/cjs/types/components/link/link.element.d.ts.map +1 -0
  70. package/dist/cjs/types/components/link-field/link-field.component.d.ts +23 -0
  71. package/dist/cjs/types/components/link-field/link-field.component.d.ts.map +1 -0
  72. package/dist/cjs/types/components/modal/index.d.ts +5 -0
  73. package/dist/cjs/types/components/modal/index.d.ts.map +1 -0
  74. package/dist/cjs/types/components/modal/modal-card.component.d.ts +15 -0
  75. package/dist/cjs/types/components/modal/modal-card.component.d.ts.map +1 -0
  76. package/dist/cjs/types/components/modal/modal-content.component.d.ts +16 -0
  77. package/dist/cjs/types/components/modal/modal-content.component.d.ts.map +1 -0
  78. package/dist/cjs/types/components/modal/modal.component.d.ts +11 -0
  79. package/dist/cjs/types/components/modal/modal.component.d.ts.map +1 -0
  80. package/dist/cjs/types/components/modal/modal.interface.d.ts +20 -0
  81. package/dist/cjs/types/components/modal/modal.interface.d.ts.map +1 -0
  82. package/dist/cjs/types/components/money-field/money-field.component.d.ts +24 -0
  83. package/dist/cjs/types/components/money-field/money-field.component.d.ts.map +1 -0
  84. package/dist/cjs/types/components/phone-number-field/phone-number-field.component.d.ts +28 -0
  85. package/dist/cjs/types/components/phone-number-field/phone-number-field.component.d.ts.map +1 -0
  86. package/dist/cjs/types/components/pin/pin.component.d.ts +23 -0
  87. package/dist/cjs/types/components/pin/pin.component.d.ts.map +1 -0
  88. package/dist/cjs/types/components/pin/pin.constant.d.ts +25 -0
  89. package/dist/cjs/types/components/pin/pin.constant.d.ts.map +1 -0
  90. package/dist/cjs/types/components/search-dropdown/search-dropdown.component.d.ts +30 -0
  91. package/dist/cjs/types/components/search-dropdown/search-dropdown.component.d.ts.map +1 -0
  92. package/dist/cjs/types/components/search-field/search-field.component.d.ts +14 -0
  93. package/dist/cjs/types/components/search-field/search-field.component.d.ts.map +1 -0
  94. package/dist/cjs/types/components/switch/switch-content.component.d.ts +14 -0
  95. package/dist/cjs/types/components/switch/switch-content.component.d.ts.map +1 -0
  96. package/dist/cjs/types/components/switch/switch.component.d.ts +12 -0
  97. package/dist/cjs/types/components/switch/switch.component.d.ts.map +1 -0
  98. package/dist/cjs/types/components/tab/tab.component.d.ts +23 -0
  99. package/dist/cjs/types/components/tab/tab.component.d.ts.map +1 -0
  100. package/dist/cjs/types/components/tab/tab.constant.d.ts +15 -0
  101. package/dist/cjs/types/components/tab/tab.constant.d.ts.map +1 -0
  102. package/dist/cjs/types/components/text-area/text-area.component.d.ts +22 -0
  103. package/dist/cjs/types/components/text-area/text-area.component.d.ts.map +1 -0
  104. package/dist/cjs/types/components/text-field/text-field.component.d.ts +21 -0
  105. package/dist/cjs/types/components/text-field/text-field.component.d.ts.map +1 -0
  106. package/dist/cjs/types/components/typography/index.d.ts +2 -0
  107. package/dist/cjs/types/components/typography/index.d.ts.map +1 -0
  108. package/dist/cjs/types/components/typography/typography-limit-one-line.component.d.ts +9 -0
  109. package/dist/cjs/types/components/typography/typography-limit-one-line.component.d.ts.map +1 -0
  110. package/dist/cjs/types/components/uploader/uploader-item.component.d.ts +18 -0
  111. package/dist/cjs/types/components/uploader/uploader-item.component.d.ts.map +1 -0
  112. package/dist/cjs/types/components/uploader/uploader-item.styles.d.ts +53 -0
  113. package/dist/cjs/types/components/uploader/uploader-item.styles.d.ts.map +1 -0
  114. package/dist/cjs/types/components/uploader/uploader.component.d.ts +48 -0
  115. package/dist/cjs/types/components/uploader/uploader.component.d.ts.map +1 -0
  116. package/dist/cjs/types/constants/apps.data.d.ts +7 -0
  117. package/dist/cjs/types/constants/apps.data.d.ts.map +1 -0
  118. package/dist/cjs/types/constants/color.constant.d.ts +105 -0
  119. package/dist/cjs/types/constants/color.constant.d.ts.map +1 -0
  120. package/dist/cjs/types/constants/index.d.ts +5 -0
  121. package/dist/cjs/types/constants/index.d.ts.map +1 -0
  122. package/dist/cjs/types/constants/style.constant.d.ts +58 -0
  123. package/dist/cjs/types/constants/style.constant.d.ts.map +1 -0
  124. package/dist/cjs/types/constants/typography.constant.d.ts +710 -0
  125. package/dist/cjs/types/constants/typography.constant.d.ts.map +1 -0
  126. package/dist/cjs/types/index.d.ts +5 -0
  127. package/dist/cjs/types/index.d.ts.map +1 -0
  128. package/dist/cjs/types/styles/index.d.ts +2 -0
  129. package/dist/cjs/types/styles/index.d.ts.map +1 -0
  130. package/dist/cjs/types/styles/stack.style.d.ts +54 -0
  131. package/dist/cjs/types/styles/stack.style.d.ts.map +1 -0
  132. package/dist/cjs/types/types/index.d.ts +1 -0
  133. package/dist/cjs/types/types/index.d.ts.map +1 -0
  134. package/dist/cjs/types/utils/index.d.ts +2 -0
  135. package/dist/cjs/types/utils/index.d.ts.map +1 -0
  136. package/dist/esm/index.js +3500 -0
  137. package/dist/esm/index.js.map +1 -0
  138. package/dist/esm/types/components/avatar/avatar-group.component.d.ts +20 -0
  139. package/dist/esm/types/components/avatar/avatar-group.component.d.ts.map +1 -0
  140. package/dist/esm/types/components/avatar/avatar-label-group.component.d.ts +11 -0
  141. package/dist/esm/types/components/avatar/avatar-label-group.component.d.ts.map +1 -0
  142. package/dist/esm/types/components/avatar/avatar-profile.component.d.ts +5 -0
  143. package/dist/esm/types/components/avatar/avatar-profile.component.d.ts.map +1 -0
  144. package/dist/esm/types/components/avatar/avatar-user.component.d.ts +14 -0
  145. package/dist/esm/types/components/avatar/avatar-user.component.d.ts.map +1 -0
  146. package/dist/esm/types/components/avatar/avatar.component.d.ts +20 -0
  147. package/dist/esm/types/components/avatar/avatar.component.d.ts.map +1 -0
  148. package/dist/esm/types/components/avatar/avatar.constant.d.ts +35 -0
  149. package/dist/esm/types/components/avatar/avatar.constant.d.ts.map +1 -0
  150. package/dist/esm/types/components/avatar/avatar.interface.d.ts +28 -0
  151. package/dist/esm/types/components/avatar/avatar.interface.d.ts.map +1 -0
  152. package/dist/esm/types/components/avatar/index.d.ts +8 -0
  153. package/dist/esm/types/components/avatar/index.d.ts.map +1 -0
  154. package/dist/esm/types/components/bread-cumbs/bread-crumbs.component.d.ts +21 -0
  155. package/dist/esm/types/components/bread-cumbs/bread-crumbs.component.d.ts.map +1 -0
  156. package/dist/esm/types/components/button/button.component.d.ts +37 -0
  157. package/dist/esm/types/components/button/button.component.d.ts.map +1 -0
  158. package/dist/esm/types/components/button/button.constants.d.ts +33 -0
  159. package/dist/esm/types/components/button/button.constants.d.ts.map +1 -0
  160. package/dist/esm/types/components/button-bar/button-bar.component.d.ts +15 -0
  161. package/dist/esm/types/components/button-bar/button-bar.component.d.ts.map +1 -0
  162. package/dist/esm/types/components/checkbox/checkbox-content.component.d.ts +19 -0
  163. package/dist/esm/types/components/checkbox/checkbox-content.component.d.ts.map +1 -0
  164. package/dist/esm/types/components/checkbox/checkbox.component.d.ts +23 -0
  165. package/dist/esm/types/components/checkbox/checkbox.component.d.ts.map +1 -0
  166. package/dist/esm/types/components/checkbox/checkbox.constant.d.ts +26 -0
  167. package/dist/esm/types/components/checkbox/checkbox.constant.d.ts.map +1 -0
  168. package/dist/esm/types/components/chip/chip.component.d.ts +16 -0
  169. package/dist/esm/types/components/chip/chip.component.d.ts.map +1 -0
  170. package/dist/esm/types/components/chip/chip.constant.d.ts +16 -0
  171. package/dist/esm/types/components/chip/chip.constant.d.ts.map +1 -0
  172. package/dist/esm/types/components/date-field/date-field.component.d.ts +23 -0
  173. package/dist/esm/types/components/date-field/date-field.component.d.ts.map +1 -0
  174. package/dist/esm/types/components/date-range-picker/date-range-picker.component.d.ts +25 -0
  175. package/dist/esm/types/components/date-range-picker/date-range-picker.component.d.ts.map +1 -0
  176. package/dist/esm/types/components/dropdown-field/dropdown-field.component.d.ts +28 -0
  177. package/dist/esm/types/components/dropdown-field/dropdown-field.component.d.ts.map +1 -0
  178. package/dist/esm/types/components/grid/grid.component.d.ts +11 -0
  179. package/dist/esm/types/components/grid/grid.component.d.ts.map +1 -0
  180. package/dist/esm/types/components/icon/icon.element.d.ts +12 -0
  181. package/dist/esm/types/components/icon/icon.element.d.ts.map +1 -0
  182. package/dist/esm/types/components/icon/index.d.ts +2 -0
  183. package/dist/esm/types/components/icon/index.d.ts.map +1 -0
  184. package/dist/esm/types/components/image/image.element.d.ts +13 -0
  185. package/dist/esm/types/components/image/image.element.d.ts.map +1 -0
  186. package/dist/esm/types/components/image/image.enum.d.ts +6 -0
  187. package/dist/esm/types/components/image/image.enum.d.ts.map +1 -0
  188. package/dist/esm/types/components/image/index.d.ts +3 -0
  189. package/dist/esm/types/components/image/index.d.ts.map +1 -0
  190. package/dist/esm/types/components/index.d.ts +48 -0
  191. package/dist/esm/types/components/index.d.ts.map +1 -0
  192. package/dist/esm/types/components/input-stepper/input-stepper-skeleton.d.ts +9 -0
  193. package/dist/esm/types/components/input-stepper/input-stepper-skeleton.d.ts.map +1 -0
  194. package/dist/esm/types/components/input-stepper/input-stepper.component.d.ts +38 -0
  195. package/dist/esm/types/components/input-stepper/input-stepper.component.d.ts.map +1 -0
  196. package/dist/esm/types/components/input-stepper/input-stepper.constant.d.ts +32 -0
  197. package/dist/esm/types/components/input-stepper/input-stepper.constant.d.ts.map +1 -0
  198. package/dist/esm/types/components/link/index.d.ts +3 -0
  199. package/dist/esm/types/components/link/index.d.ts.map +1 -0
  200. package/dist/esm/types/components/link/link-internal.element.d.ts +9 -0
  201. package/dist/esm/types/components/link/link-internal.element.d.ts.map +1 -0
  202. package/dist/esm/types/components/link/link.element.d.ts +8 -0
  203. package/dist/esm/types/components/link/link.element.d.ts.map +1 -0
  204. package/dist/esm/types/components/link-field/link-field.component.d.ts +23 -0
  205. package/dist/esm/types/components/link-field/link-field.component.d.ts.map +1 -0
  206. package/dist/esm/types/components/modal/index.d.ts +5 -0
  207. package/dist/esm/types/components/modal/index.d.ts.map +1 -0
  208. package/dist/esm/types/components/modal/modal-card.component.d.ts +15 -0
  209. package/dist/esm/types/components/modal/modal-card.component.d.ts.map +1 -0
  210. package/dist/esm/types/components/modal/modal-content.component.d.ts +16 -0
  211. package/dist/esm/types/components/modal/modal-content.component.d.ts.map +1 -0
  212. package/dist/esm/types/components/modal/modal.component.d.ts +11 -0
  213. package/dist/esm/types/components/modal/modal.component.d.ts.map +1 -0
  214. package/dist/esm/types/components/modal/modal.interface.d.ts +20 -0
  215. package/dist/esm/types/components/modal/modal.interface.d.ts.map +1 -0
  216. package/dist/esm/types/components/money-field/money-field.component.d.ts +24 -0
  217. package/dist/esm/types/components/money-field/money-field.component.d.ts.map +1 -0
  218. package/dist/esm/types/components/phone-number-field/phone-number-field.component.d.ts +28 -0
  219. package/dist/esm/types/components/phone-number-field/phone-number-field.component.d.ts.map +1 -0
  220. package/dist/esm/types/components/pin/pin.component.d.ts +23 -0
  221. package/dist/esm/types/components/pin/pin.component.d.ts.map +1 -0
  222. package/dist/esm/types/components/pin/pin.constant.d.ts +25 -0
  223. package/dist/esm/types/components/pin/pin.constant.d.ts.map +1 -0
  224. package/dist/esm/types/components/search-dropdown/search-dropdown.component.d.ts +30 -0
  225. package/dist/esm/types/components/search-dropdown/search-dropdown.component.d.ts.map +1 -0
  226. package/dist/esm/types/components/search-field/search-field.component.d.ts +14 -0
  227. package/dist/esm/types/components/search-field/search-field.component.d.ts.map +1 -0
  228. package/dist/esm/types/components/switch/switch-content.component.d.ts +14 -0
  229. package/dist/esm/types/components/switch/switch-content.component.d.ts.map +1 -0
  230. package/dist/esm/types/components/switch/switch.component.d.ts +12 -0
  231. package/dist/esm/types/components/switch/switch.component.d.ts.map +1 -0
  232. package/dist/esm/types/components/tab/tab.component.d.ts +23 -0
  233. package/dist/esm/types/components/tab/tab.component.d.ts.map +1 -0
  234. package/dist/esm/types/components/tab/tab.constant.d.ts +15 -0
  235. package/dist/esm/types/components/tab/tab.constant.d.ts.map +1 -0
  236. package/dist/esm/types/components/text-area/text-area.component.d.ts +22 -0
  237. package/dist/esm/types/components/text-area/text-area.component.d.ts.map +1 -0
  238. package/dist/esm/types/components/text-field/text-field.component.d.ts +21 -0
  239. package/dist/esm/types/components/text-field/text-field.component.d.ts.map +1 -0
  240. package/dist/esm/types/components/typography/index.d.ts +2 -0
  241. package/dist/esm/types/components/typography/index.d.ts.map +1 -0
  242. package/dist/esm/types/components/typography/typography-limit-one-line.component.d.ts +9 -0
  243. package/dist/esm/types/components/typography/typography-limit-one-line.component.d.ts.map +1 -0
  244. package/dist/esm/types/components/uploader/uploader-item.component.d.ts +18 -0
  245. package/dist/esm/types/components/uploader/uploader-item.component.d.ts.map +1 -0
  246. package/dist/esm/types/components/uploader/uploader-item.styles.d.ts +53 -0
  247. package/dist/esm/types/components/uploader/uploader-item.styles.d.ts.map +1 -0
  248. package/dist/esm/types/components/uploader/uploader.component.d.ts +48 -0
  249. package/dist/esm/types/components/uploader/uploader.component.d.ts.map +1 -0
  250. package/dist/esm/types/constants/apps.data.d.ts +7 -0
  251. package/dist/esm/types/constants/apps.data.d.ts.map +1 -0
  252. package/dist/esm/types/constants/color.constant.d.ts +105 -0
  253. package/dist/esm/types/constants/color.constant.d.ts.map +1 -0
  254. package/dist/esm/types/constants/index.d.ts +5 -0
  255. package/dist/esm/types/constants/index.d.ts.map +1 -0
  256. package/dist/esm/types/constants/style.constant.d.ts +58 -0
  257. package/dist/esm/types/constants/style.constant.d.ts.map +1 -0
  258. package/dist/esm/types/constants/typography.constant.d.ts +710 -0
  259. package/dist/esm/types/constants/typography.constant.d.ts.map +1 -0
  260. package/dist/esm/types/index.d.ts +5 -0
  261. package/dist/esm/types/index.d.ts.map +1 -0
  262. package/dist/esm/types/styles/index.d.ts +2 -0
  263. package/dist/esm/types/styles/index.d.ts.map +1 -0
  264. package/dist/esm/types/styles/stack.style.d.ts +54 -0
  265. package/dist/esm/types/styles/stack.style.d.ts.map +1 -0
  266. package/dist/esm/types/types/index.d.ts +1 -0
  267. package/dist/esm/types/types/index.d.ts.map +1 -0
  268. package/dist/esm/types/utils/index.d.ts +2 -0
  269. package/dist/esm/types/utils/index.d.ts.map +1 -0
  270. package/dist/types/components/avatar/avatar-group.component.d.ts +20 -0
  271. package/dist/types/components/avatar/avatar-group.component.d.ts.map +1 -0
  272. package/dist/types/components/avatar/avatar-label-group.component.d.ts +11 -0
  273. package/dist/types/components/avatar/avatar-label-group.component.d.ts.map +1 -0
  274. package/dist/types/components/avatar/avatar-profile.component.d.ts +4 -0
  275. package/dist/types/components/avatar/avatar-profile.component.d.ts.map +1 -0
  276. package/dist/types/components/avatar/avatar-user.component.d.ts +14 -0
  277. package/dist/types/components/avatar/avatar-user.component.d.ts.map +1 -0
  278. package/dist/types/components/avatar/avatar.component.d.ts +20 -0
  279. package/dist/types/components/avatar/avatar.component.d.ts.map +1 -0
  280. package/dist/types/components/avatar/avatar.constant.d.ts +35 -0
  281. package/dist/types/components/avatar/avatar.constant.d.ts.map +1 -0
  282. package/dist/types/components/avatar/avatar.interface.d.ts +28 -0
  283. package/dist/types/components/avatar/avatar.interface.d.ts.map +1 -0
  284. package/dist/types/components/bread-cumbs/bread-crumbs.component.d.ts +21 -0
  285. package/dist/types/components/bread-cumbs/bread-crumbs.component.d.ts.map +1 -0
  286. package/dist/types/components/button/button.component.d.ts +38 -0
  287. package/dist/types/components/button/button.component.d.ts.map +1 -0
  288. package/dist/types/components/button/button.constants.d.ts +33 -0
  289. package/dist/types/components/button/button.constants.d.ts.map +1 -0
  290. package/dist/types/components/button-bar/button-bar.component.d.ts +15 -0
  291. package/dist/types/components/button-bar/button-bar.component.d.ts.map +1 -0
  292. package/dist/types/components/checkbox/checkbox-content.component.d.ts +19 -0
  293. package/dist/types/components/checkbox/checkbox-content.component.d.ts.map +1 -0
  294. package/dist/types/components/checkbox/checkbox.component.d.ts +22 -0
  295. package/dist/types/components/checkbox/checkbox.component.d.ts.map +1 -0
  296. package/dist/types/components/checkbox/checkbox.constant.d.ts +26 -0
  297. package/dist/types/components/checkbox/checkbox.constant.d.ts.map +1 -0
  298. package/dist/types/components/chip/chip.component.d.ts +15 -0
  299. package/dist/types/components/chip/chip.component.d.ts.map +1 -0
  300. package/dist/types/components/chip/chip.constant.d.ts +16 -0
  301. package/dist/types/components/chip/chip.constant.d.ts.map +1 -0
  302. package/dist/types/components/date-field/date-field.component.d.ts +23 -0
  303. package/dist/types/components/date-field/date-field.component.d.ts.map +1 -0
  304. package/dist/types/components/date-range-picker/date-range-picker.component.d.ts +25 -0
  305. package/dist/types/components/date-range-picker/date-range-picker.component.d.ts.map +1 -0
  306. package/dist/types/components/dropdown-field/dropdown-field.component.d.ts +28 -0
  307. package/dist/types/components/dropdown-field/dropdown-field.component.d.ts.map +1 -0
  308. package/dist/types/components/grid/grid.component.d.ts +11 -0
  309. package/dist/types/components/grid/grid.component.d.ts.map +1 -0
  310. package/dist/types/components/icon/icon.element.d.ts +12 -0
  311. package/dist/types/components/icon/icon.element.d.ts.map +1 -0
  312. package/dist/types/components/icon/index.d.ts +2 -0
  313. package/dist/types/components/icon/index.d.ts.map +1 -0
  314. package/dist/types/components/image/image.element.d.ts +13 -0
  315. package/dist/types/components/image/image.element.d.ts.map +1 -0
  316. package/dist/types/components/image/image.enum.d.ts +6 -0
  317. package/dist/types/components/image/image.enum.d.ts.map +1 -0
  318. package/dist/types/components/image/index.d.ts +3 -0
  319. package/dist/types/components/image/index.d.ts.map +1 -0
  320. package/dist/types/components/index.d.ts +28 -0
  321. package/dist/types/components/index.d.ts.map +1 -0
  322. package/dist/types/components/input-stepper/input-stepper-skeleton.d.ts +9 -0
  323. package/dist/types/components/input-stepper/input-stepper-skeleton.d.ts.map +1 -0
  324. package/dist/types/components/input-stepper/input-stepper.component.d.ts +37 -0
  325. package/dist/types/components/input-stepper/input-stepper.component.d.ts.map +1 -0
  326. package/dist/types/components/input-stepper/input-stepper.constant.d.ts +32 -0
  327. package/dist/types/components/input-stepper/input-stepper.constant.d.ts.map +1 -0
  328. package/dist/types/components/link/index.d.ts +3 -0
  329. package/dist/types/components/link/index.d.ts.map +1 -0
  330. package/dist/types/components/link/link-internal.element.d.ts +9 -0
  331. package/dist/types/components/link/link-internal.element.d.ts.map +1 -0
  332. package/dist/types/components/link/link.element.d.ts +8 -0
  333. package/dist/types/components/link/link.element.d.ts.map +1 -0
  334. package/dist/types/components/link-field/link-field.component.d.ts +23 -0
  335. package/dist/types/components/link-field/link-field.component.d.ts.map +1 -0
  336. package/dist/types/components/modal/modal-card.component.d.ts +15 -0
  337. package/dist/types/components/modal/modal-card.component.d.ts.map +1 -0
  338. package/dist/types/components/modal/modal-content.component.d.ts +16 -0
  339. package/dist/types/components/modal/modal-content.component.d.ts.map +1 -0
  340. package/dist/types/components/modal/modal.component.d.ts +11 -0
  341. package/dist/types/components/modal/modal.component.d.ts.map +1 -0
  342. package/dist/types/components/modal/modal.interface.d.ts +20 -0
  343. package/dist/types/components/modal/modal.interface.d.ts.map +1 -0
  344. package/dist/types/components/money-field/money-field.component.d.ts +24 -0
  345. package/dist/types/components/money-field/money-field.component.d.ts.map +1 -0
  346. package/dist/types/components/phone-number-field/phone-number-field.component.d.ts +28 -0
  347. package/dist/types/components/phone-number-field/phone-number-field.component.d.ts.map +1 -0
  348. package/dist/types/components/pin/pin.component.d.ts +23 -0
  349. package/dist/types/components/pin/pin.component.d.ts.map +1 -0
  350. package/dist/types/components/pin/pin.constant.d.ts +25 -0
  351. package/dist/types/components/pin/pin.constant.d.ts.map +1 -0
  352. package/dist/types/components/search-dropdown/search-dropdown.component.d.ts +30 -0
  353. package/dist/types/components/search-dropdown/search-dropdown.component.d.ts.map +1 -0
  354. package/dist/types/components/search-field/search-field.component.d.ts +14 -0
  355. package/dist/types/components/search-field/search-field.component.d.ts.map +1 -0
  356. package/dist/types/components/switch/switch-content.component.d.ts +13 -0
  357. package/dist/types/components/switch/switch-content.component.d.ts.map +1 -0
  358. package/dist/types/components/switch/switch.component.d.ts +12 -0
  359. package/dist/types/components/switch/switch.component.d.ts.map +1 -0
  360. package/dist/types/components/tab/tab.component.d.ts +22 -0
  361. package/dist/types/components/tab/tab.component.d.ts.map +1 -0
  362. package/dist/types/components/tab/tab.constant.d.ts +15 -0
  363. package/dist/types/components/tab/tab.constant.d.ts.map +1 -0
  364. package/dist/types/components/text-area/text-area.component.d.ts +22 -0
  365. package/dist/types/components/text-area/text-area.component.d.ts.map +1 -0
  366. package/dist/types/components/text-field/text-field.component.d.ts +21 -0
  367. package/dist/types/components/text-field/text-field.component.d.ts.map +1 -0
  368. package/dist/types/components/typography/index.d.ts +2 -0
  369. package/dist/types/components/typography/index.d.ts.map +1 -0
  370. package/dist/types/components/typography/typography-limit-one-line.component.d.ts +9 -0
  371. package/dist/types/components/typography/typography-limit-one-line.component.d.ts.map +1 -0
  372. package/dist/types/components/uploader/uploader-item.component.d.ts +17 -0
  373. package/dist/types/components/uploader/uploader-item.component.d.ts.map +1 -0
  374. package/dist/types/components/uploader/uploader-item.styles.d.ts +53 -0
  375. package/dist/types/components/uploader/uploader-item.styles.d.ts.map +1 -0
  376. package/dist/types/components/uploader/uploader.component.d.ts +48 -0
  377. package/dist/types/components/uploader/uploader.component.d.ts.map +1 -0
  378. package/dist/types/constants/apps.data.d.ts +7 -0
  379. package/dist/types/constants/apps.data.d.ts.map +1 -0
  380. package/dist/types/constants/color.constant.d.ts +105 -0
  381. package/dist/types/constants/color.constant.d.ts.map +1 -0
  382. package/dist/types/constants/index.d.ts +5 -0
  383. package/dist/types/constants/index.d.ts.map +1 -0
  384. package/dist/types/constants/style.constant.d.ts +58 -0
  385. package/dist/types/constants/style.constant.d.ts.map +1 -0
  386. package/dist/types/constants/typography.constant.d.ts +710 -0
  387. package/dist/types/constants/typography.constant.d.ts.map +1 -0
  388. package/dist/types/index.d.ts +5 -0
  389. package/dist/types/index.d.ts.map +1 -0
  390. package/dist/types/styles/index.d.ts +2 -0
  391. package/dist/types/styles/index.d.ts.map +1 -0
  392. package/dist/types/styles/stack.style.d.ts +54 -0
  393. package/dist/types/styles/stack.style.d.ts.map +1 -0
  394. package/dist/types/types/index.d.ts +1 -0
  395. package/dist/types/types/index.d.ts.map +1 -0
  396. package/dist/types/utils/index.d.ts +2 -0
  397. package/dist/types/utils/index.d.ts.map +1 -0
  398. package/package.json +54 -0
@@ -0,0 +1,3500 @@
1
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
+ import { Stack, TableCell, tableCellClasses, LinearProgress, linearProgressClasses, useTheme, Skeleton, Box, Icon, Typography, Link, Breadcrumbs, IconButton, Menu, MenuItem, CircularProgress, Button, Chip, Select, Avatar, Container, TextField, InputAdornment, Dialog, DialogContent, DialogActions, styled as styled$1, Autocomplete, Switch } from '@mui/material';
3
+ import React, { useState, useRef, useMemo, useCallback, useEffect, useId } from 'react';
4
+ import { styled } from '@mui/material/styles';
5
+ import LinkIcon from '@mui/icons-material/Link';
6
+ import CheckIcon from '@mui/icons-material/Check';
7
+ import RemoveIcon from '@mui/icons-material/Remove';
8
+ import FiberManualRecordIcon from '@mui/icons-material/FiberManualRecord';
9
+ import { DatePicker } from '@mui/x-date-pickers/DatePicker';
10
+ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
11
+ import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
12
+ import dayjs from 'dayjs';
13
+ import AddIcon from '@mui/icons-material/Add';
14
+ import MuiTextField from '@mui/material/TextField';
15
+ import { Form } from 'formik';
16
+ import Slider from 'react-slick';
17
+ import 'slick-carousel/slick/slick.css';
18
+ import 'slick-carousel/slick/slick-theme.css';
19
+ import AttachMoneyIcon from '@mui/icons-material/AttachMoney';
20
+ import SearchIcon from '@mui/icons-material/Search';
21
+ import { LayoutGroup, motion } from 'framer-motion';
22
+ import CheckCircleIcon from '@mui/icons-material/CheckCircle';
23
+ import RefreshIcon from '@mui/icons-material/Refresh';
24
+
25
+ const AVATAR_SIZES = {
26
+ xs: 24,
27
+ sm: 32,
28
+ md: 40,
29
+ lg: 48,
30
+ xl: 56,
31
+ '2xl': 64,
32
+ };
33
+ const BADGE_SIZES = {
34
+ xs: 8,
35
+ sm: 10,
36
+ md: 12,
37
+ lg: 14,
38
+ xl: 16,
39
+ '2xl': 18,
40
+ };
41
+ const BADGE_FONT_SIZES = {
42
+ xs: 4,
43
+ sm: 5,
44
+ md: 6,
45
+ lg: 7,
46
+ xl: 8,
47
+ '2xl': 9,
48
+ };
49
+ const getBadgePosition = (position) => {
50
+ const positions = {
51
+ 'top-left': { top: 0, left: 0 },
52
+ 'top-right': { top: 0, right: 0 },
53
+ 'top-center': { top: 0, left: '50%', transform: 'translateX(-50%)' },
54
+ 'bottom-left': { bottom: 0, left: 0 },
55
+ 'bottom-right': { bottom: 0, right: 0 },
56
+ 'bottom-center': { bottom: 0, left: '50%', transform: 'translateX(-50%)' },
57
+ };
58
+ return positions[position];
59
+ };
60
+ var AvatarColor;
61
+ (function (AvatarColor) {
62
+ AvatarColor["BACKGROUND_COLOR_BADGE"] = "#000000";
63
+ AvatarColor["COLOR_BADGE"] = "#FFFFFF";
64
+ AvatarColor["COLOR_TITLE"] = "#414651";
65
+ AvatarColor["COLOR_DESCRIPTION"] = "#535862";
66
+ })(AvatarColor || (AvatarColor = {}));
67
+
68
+ const SIZE_LARGE = 32;
69
+ const SIZE_MEDIUM = 26;
70
+ const SIZE_SMALL = 18;
71
+ const SIZE_EXTRA_SMALL = 20;
72
+ const SIZE_AVATAR_GROUP = 80;
73
+ const SIZE_EXTRA_LARGE = 36;
74
+ const MAP_SIZE = {
75
+ large: { width: SIZE_LARGE, height: SIZE_LARGE },
76
+ medium: { width: SIZE_MEDIUM, height: SIZE_MEDIUM },
77
+ small: { width: SIZE_SMALL, height: SIZE_SMALL },
78
+ extra_small: { width: SIZE_EXTRA_SMALL, height: SIZE_EXTRA_SMALL },
79
+ extra_large: { width: SIZE_EXTRA_LARGE, height: SIZE_EXTRA_LARGE },
80
+ avatar_group: { width: SIZE_AVATAR_GROUP, height: SIZE_AVATAR_GROUP },
81
+ };
82
+
83
+ // Brand Colors
84
+ const COLOR_BRAND = {
85
+ 50: '#EDFFFA',
86
+ 100: '#C3FFF2',
87
+ 200: '#87FFEB',
88
+ 300: '#42FFDC',
89
+ 400: '#0CF5CA',
90
+ 500: '#00D8B2',
91
+ 600: '#00AF93',
92
+ 700: '#008A77',
93
+ 800: '#026D60',
94
+ 900: '#07554B',
95
+ 950: '#003733',
96
+ };
97
+ // Neutral Colors
98
+ const COLOR_NEUTRAL = {
99
+ 50: '#FAFAFA',
100
+ 100: '#F5F5F5',
101
+ 200: '#E5E5E5',
102
+ 300: '#D4D4D4',
103
+ 400: '#A3A3A3',
104
+ 500: '#737373',
105
+ 600: '#525252',
106
+ 700: '#404040',
107
+ 800: '#202626',
108
+ 900: '#171717',
109
+ 950: '#0A0A0A',
110
+ };
111
+ // Gray Colors
112
+ const COLOR_GRAY = {
113
+ 50: '#F9AFAB',
114
+ 100: '#F3F4F6',
115
+ 200: '#E5E7EB',
116
+ 300: '#DDD5DB',
117
+ 400: '#9CA3AF',
118
+ 500: '#6B7280',
119
+ 600: '#4B5563',
120
+ 700: '#374151',
121
+ 800: '#1F2937',
122
+ 900: '#111827',
123
+ 950: '#030712',
124
+ };
125
+ // Error Colors
126
+ const COLOR_ERROR = {
127
+ 50: '#FEF2F2',
128
+ 100: '#FEE2E2',
129
+ 200: '#FECACA',
130
+ 300: '#FCASA5',
131
+ 400: '#F87171',
132
+ 500: '#EF4444',
133
+ 600: '#DC2626',
134
+ 700: '#B91C1C',
135
+ 800: '#991B1B',
136
+ 900: '#7F1D1D',
137
+ 950: '#450A0A',
138
+ };
139
+ // Warning Colors
140
+ const COLOR_WARNING = {
141
+ 50: '#FFEEB8',
142
+ 100: '#FFDD93',
143
+ 200: '#FFD08A',
144
+ 300: '#FDE047',
145
+ 400: '#FACC15',
146
+ 500: '#EAB308',
147
+ 600: '#CA8A04',
148
+ 700: '#A16207',
149
+ 800: '#854D0E',
150
+ 900: '#713F12',
151
+ 950: '#422006',
152
+ };
153
+ // Success Colors
154
+ const COLOR_SUCCESS = {
155
+ 50: '#F0FDF4',
156
+ 100: '#DCFCE7',
157
+ 200: '#BBF7D0',
158
+ 300: '#A6E96C',
159
+ 400: '#4ADE80',
160
+ 500: '#22C55E',
161
+ 600: '#16A34A',
162
+ 700: '#15803D',
163
+ 800: '#166534',
164
+ 900: '#14532D',
165
+ 950: '#052E16',
166
+ };
167
+ // Info Colors
168
+ const COLOR_INFO = {
169
+ 50: '#EFF8FF',
170
+ 100: '#0B8AFF',
171
+ 200: '#BFD8FE',
172
+ 300: '#93C5FD',
173
+ 400: '#60A5FA',
174
+ 500: '#3B82F6',
175
+ 600: '#2563EB',
176
+ 700: '#1D4ED8',
177
+ 800: '#1E40AF',
178
+ 900: '#1E3A8A',
179
+ 950: '#172554',
180
+ };
181
+ // Accent Colors
182
+ const COLOR_ACCENT = {
183
+ 50: '#F3F3FF',
184
+ 100: '#F9F9FF',
185
+ 200: '#DDD6FE',
186
+ 300: '#C4B5FD',
187
+ 400: '#A78BFA',
188
+ 500: '#8B5CF6',
189
+ 600: '#7C3AED',
190
+ 700: '#6D28D9',
191
+ 800: '#5B21B6',
192
+ 900: '#4C1D95',
193
+ 950: '#2E1065',
194
+ };
195
+
196
+ // CÁC THÔNG SỐ CÙNG GROUP CÓ TỶ LỆ VỚI NHAU
197
+ //
198
+ const ANIMATION_TIME = 300;
199
+ const SCALE_VALUE = 'scale(1.05)';
200
+ const TRANSITION_TIME = '0.2s';
201
+ //
202
+ const WIDTH_LAYOUT_DESKTOP = `1200px`;
203
+ const HEIGHT_LOGO_DEFAULT = '40px';
204
+ const HEIGHT_IMAGE_DEFAULT = '40px';
205
+ //
206
+ const PADDING_GAP_TAB = '24px';
207
+ const PADDING_GAP_LAYOUT = '16px';
208
+ const PADDING_GAP_BUTTON = '12px';
209
+ const PADDING_LAYOUT_HEADER = '8px 12px';
210
+ const PADDING_GAP_ITEM = '8px';
211
+ const PADDING_GAP_ITEM_SMALL = '6px';
212
+ //
213
+ const HEIGHT_ELEMENT_OTHER = '36px';
214
+ //
215
+ const BORDER_RADIUS_ELEMENT_ACTION = '24px';
216
+ const BORDER_RADIUS_ELEMENT_WRAPPER = '12px';
217
+ const BORDER_RADIUS_ELEMENT = '10px';
218
+ const BORDER_RADIUS_ELEMENT_SMALL = '6px';
219
+ const BORDER_RADIUS_ELEMENT_MIDDLE = '8px';
220
+ const BORDER_RADIUS_ELEMENT_TAG = '3px';
221
+ const HEIGHT_DEFAULT_TEXT_FIELD_BUTTON = '37.13px';
222
+ //
223
+ const TEXT_FIELD = {
224
+ FONT_SIZE_LABEL: 15,
225
+ FONT_SIZE_TITLE: 18,
226
+ FONT_SIZE_CAPTION: 10,
227
+ };
228
+ const FONT_SIZE_ICON = {
229
+ large: '22px',
230
+ xl: '20px',
231
+ medium: '19px',
232
+ small: '12px',
233
+ };
234
+ const FONT_SIZE_LOADING$1 = {
235
+ large: 40,
236
+ medium: 22.5,
237
+ small: 16,
238
+ };
239
+ const VARIANT_BY_SIZE = {
240
+ large: 'h6',
241
+ medium: 'subtitle1',
242
+ small: 'caption',
243
+ };
244
+ const GAP_ICON_CONTENT_BY_SIZE = {
245
+ large: '12px',
246
+ medium: '8px',
247
+ small: '4px',
248
+ };
249
+ const BORDER_COLOR_CARD = 'rgba(0, 0, 0, 0.12)';
250
+ const BORDER_COLOR_LAYOUT = '#E4E6E6';
251
+ const HEIGHT_HEADER = 57;
252
+ const WIDTH_COLLAPSE = 55;
253
+ const WIDTH_SIDEBAR = 224;
254
+ const WIDTH_SIDEBAR_EXPAND = 200;
255
+ const BACKGROUND_SYSTEM = '#F2F2F2';
256
+ const WIDTH_TEXT_FIELD = {
257
+ large: 300,
258
+ medium: 200,
259
+ small: 100,
260
+ };
261
+
262
+ var style_constant = /*#__PURE__*/Object.freeze({
263
+ __proto__: null,
264
+ ANIMATION_TIME: ANIMATION_TIME,
265
+ BACKGROUND_SYSTEM: BACKGROUND_SYSTEM,
266
+ BORDER_COLOR_CARD: BORDER_COLOR_CARD,
267
+ BORDER_COLOR_LAYOUT: BORDER_COLOR_LAYOUT,
268
+ BORDER_RADIUS_ELEMENT: BORDER_RADIUS_ELEMENT,
269
+ BORDER_RADIUS_ELEMENT_ACTION: BORDER_RADIUS_ELEMENT_ACTION,
270
+ BORDER_RADIUS_ELEMENT_MIDDLE: BORDER_RADIUS_ELEMENT_MIDDLE,
271
+ BORDER_RADIUS_ELEMENT_SMALL: BORDER_RADIUS_ELEMENT_SMALL,
272
+ BORDER_RADIUS_ELEMENT_TAG: BORDER_RADIUS_ELEMENT_TAG,
273
+ BORDER_RADIUS_ELEMENT_WRAPPER: BORDER_RADIUS_ELEMENT_WRAPPER,
274
+ FONT_SIZE_ICON: FONT_SIZE_ICON,
275
+ FONT_SIZE_LOADING: FONT_SIZE_LOADING$1,
276
+ GAP_ICON_CONTENT_BY_SIZE: GAP_ICON_CONTENT_BY_SIZE,
277
+ HEIGHT_DEFAULT_TEXT_FIELD_BUTTON: HEIGHT_DEFAULT_TEXT_FIELD_BUTTON,
278
+ HEIGHT_ELEMENT_OTHER: HEIGHT_ELEMENT_OTHER,
279
+ HEIGHT_HEADER: HEIGHT_HEADER,
280
+ HEIGHT_IMAGE_DEFAULT: HEIGHT_IMAGE_DEFAULT,
281
+ HEIGHT_LOGO_DEFAULT: HEIGHT_LOGO_DEFAULT,
282
+ PADDING_GAP_BUTTON: PADDING_GAP_BUTTON,
283
+ PADDING_GAP_ITEM: PADDING_GAP_ITEM,
284
+ PADDING_GAP_ITEM_SMALL: PADDING_GAP_ITEM_SMALL,
285
+ PADDING_GAP_LAYOUT: PADDING_GAP_LAYOUT,
286
+ PADDING_GAP_TAB: PADDING_GAP_TAB,
287
+ PADDING_LAYOUT_HEADER: PADDING_LAYOUT_HEADER,
288
+ SCALE_VALUE: SCALE_VALUE,
289
+ TEXT_FIELD: TEXT_FIELD,
290
+ TRANSITION_TIME: TRANSITION_TIME,
291
+ VARIANT_BY_SIZE: VARIANT_BY_SIZE,
292
+ WIDTH_COLLAPSE: WIDTH_COLLAPSE,
293
+ WIDTH_LAYOUT_DESKTOP: WIDTH_LAYOUT_DESKTOP,
294
+ WIDTH_SIDEBAR: WIDTH_SIDEBAR,
295
+ WIDTH_SIDEBAR_EXPAND: WIDTH_SIDEBAR_EXPAND,
296
+ WIDTH_TEXT_FIELD: WIDTH_TEXT_FIELD
297
+ });
298
+
299
+ const FONT_FAMILY = {
300
+ primary: 'Inter, sans-serif',
301
+ };
302
+ const FONT_SIZE = {
303
+ '5xl': '48px',
304
+ '4xl': '32px',
305
+ '3xl': '28px',
306
+ '2xl': '24px',
307
+ xl: '20px',
308
+ lg: '18px',
309
+ md: '16px',
310
+ base: '14px',
311
+ sm: '12px',
312
+ xs: '10px',
313
+ };
314
+ const FONT_WEIGHT = {
315
+ bold: 700,
316
+ semiBold: 600,
317
+ medium: 500,
318
+ regular: 400,
319
+ };
320
+ const LINE_HEIGHT = {
321
+ tight: 1.2,
322
+ normal: 1.5,
323
+ relaxed: 1.75,
324
+ loose: 2,
325
+ };
326
+ const FONT_STYLE = {
327
+ normal: 'normal',
328
+ underline: 'underline',
329
+ strikethrough: 'line-through',
330
+ };
331
+ // Helper function to combine typography styles
332
+ const createTypography = (fontSize, fontWeight, lineHeight, fontStyle) => ({
333
+ fontFamily: FONT_FAMILY.primary,
334
+ fontSize: typeof fontSize === 'number' ? `${fontSize}px` : fontSize,
335
+ fontWeight: fontWeight ?? FONT_WEIGHT.regular,
336
+ lineHeight: lineHeight ?? LINE_HEIGHT.normal,
337
+ fontStyle: fontStyle ?? FONT_STYLE.normal,
338
+ });
339
+ // Preset typography styles
340
+ const TYPOGRAPHY = {
341
+ h1: createTypography(FONT_SIZE['5xl'], FONT_WEIGHT.bold),
342
+ h2: createTypography(FONT_SIZE['4xl'], FONT_WEIGHT.bold),
343
+ h3: createTypography(FONT_SIZE['3xl'], FONT_WEIGHT.bold),
344
+ h4: createTypography(FONT_SIZE['2xl'], FONT_WEIGHT.bold),
345
+ h5: createTypography(FONT_SIZE['xl'], FONT_WEIGHT.bold),
346
+ h6: createTypography(FONT_SIZE['lg'], FONT_WEIGHT.bold),
347
+ body: createTypography(FONT_SIZE['md'], FONT_WEIGHT.regular),
348
+ caption: createTypography(FONT_SIZE['sm'], FONT_WEIGHT.regular),
349
+ // 14px combinations
350
+ text14Medium: createTypography(FONT_SIZE.base, FONT_WEIGHT.medium),
351
+ text14Regular: createTypography(FONT_SIZE.base, FONT_WEIGHT.regular),
352
+ text14SemiBold: createTypography(FONT_SIZE.base, FONT_WEIGHT.semiBold),
353
+ text14Bold: createTypography(FONT_SIZE.base, FONT_WEIGHT.bold),
354
+ // 12px combinations
355
+ text12Medium: createTypography(FONT_SIZE.sm, FONT_WEIGHT.medium),
356
+ text12Regular: createTypography(FONT_SIZE.sm, FONT_WEIGHT.regular),
357
+ text12SemiBold: createTypography(FONT_SIZE.sm, FONT_WEIGHT.semiBold),
358
+ text12Bold: createTypography(FONT_SIZE.sm, FONT_WEIGHT.bold),
359
+ // 10px combinations
360
+ text10Medium: createTypography(FONT_SIZE.xs, FONT_WEIGHT.medium),
361
+ text10Regular: createTypography(FONT_SIZE.xs, FONT_WEIGHT.regular),
362
+ text10SemiBold: createTypography(FONT_SIZE.xs, FONT_WEIGHT.semiBold),
363
+ text10Bold: createTypography(FONT_SIZE.xs, FONT_WEIGHT.bold),
364
+ // Custom TextField variants
365
+ textFieldLabel: createTypography(FONT_SIZE.base, FONT_WEIGHT.medium, LINE_HEIGHT.relaxed),
366
+ textFieldHelper: createTypography(FONT_SIZE.sm, FONT_WEIGHT.regular, LINE_HEIGHT.relaxed),
367
+ };
368
+ /**
369
+ * ============================================
370
+ * CÁCH SỬ DỤNG TYPOGRAPHY
371
+ * ============================================
372
+ *
373
+ * 1. Sử dụng TYPOGRAPHY presets trực tiếp:
374
+ * ----
375
+ * import { TYPOGRAPHY } from '@/common/constant/typography.constant';
376
+ *
377
+ * <Text style={TYPOGRAPHY.h1}>Heading 1</Text>
378
+ * <Text style={TYPOGRAPHY.text14Medium}>14px Medium</Text>
379
+ * <Text style={TYPOGRAPHY.text12Bold}>12px Bold</Text>
380
+ *
381
+ * 2. Kết hợp với các styles khác (CSS-in-JS):
382
+ * ----
383
+ * const styles = {
384
+ * title: {
385
+ * ...TYPOGRAPHY.h2,
386
+ * color: '#07554B',
387
+ * marginBottom: '16px',
388
+ * }
389
+ * };
390
+ *
391
+ * 3. Sử dụng hàm createTypography để tạo custom style:
392
+ * ----
393
+ * import { createTypography, FONT_SIZE, FONT_WEIGHT, LINE_HEIGHT } from '@/common/constant/typography.constant';
394
+ *
395
+ * const customStyle = createTypography(
396
+ * FONT_SIZE.lg, // 18px
397
+ * FONT_WEIGHT.semiBold, // 600
398
+ * LINE_HEIGHT.relaxed, // 1.75
399
+ * 'underline' // style
400
+ * );
401
+ * <Text style={customStyle}>Custom Text</Text>
402
+ *
403
+ * 4. Sử dụng từng hằng số riêng lẻ:
404
+ * ----
405
+ * import { FONT_SIZE, FONT_WEIGHT, LINE_HEIGHT } from '@/common/constant/typography.constant';
406
+ *
407
+ * <Text style={{
408
+ * fontSize: FONT_SIZE.md,
409
+ * fontWeight: FONT_WEIGHT.bold,
410
+ * lineHeight: LINE_HEIGHT.loose,
411
+ * }}>
412
+ * Custom Combination
413
+ * </Text>
414
+ *
415
+ * 5. Dùng trong Styled Components / Emotion:
416
+ * ----
417
+ * import styled from 'styled-components';
418
+ * import { TYPOGRAPHY } from '@/common/constant/typography.constant';
419
+ *
420
+ * const Title = styled.h1`
421
+ * ${TYPOGRAPHY.h1}
422
+ * color: #07554B;
423
+ * `;
424
+ */
425
+ const TYPOGRAPHY_STYLES = {
426
+ '2xl': {
427
+ regular: {
428
+ fontFamily: '"Inter",sans-serif',
429
+ fontWeight: 400,
430
+ fontStyle: 'normal',
431
+ fontSize: '72px',
432
+ lineHeight: '80px',
433
+ letterSpacing: '0%',
434
+ verticalAlign: 'middle',
435
+ },
436
+ medium: {
437
+ fontFamily: '"Inter",sans-serif',
438
+ fontWeight: 500,
439
+ fontStyle: 'normal',
440
+ fontSize: '72px',
441
+ lineHeight: '80px',
442
+ letterSpacing: '0%',
443
+ verticalAlign: 'middle',
444
+ },
445
+ semiBold: {
446
+ fontFamily: '"Inter",sans-serif',
447
+ fontWeight: 600,
448
+ fontStyle: 'normal',
449
+ fontSize: '72px',
450
+ lineHeight: '80px',
451
+ letterSpacing: '0%',
452
+ verticalAlign: 'middle',
453
+ },
454
+ bold: {
455
+ fontFamily: '"Inter",sans-serif',
456
+ fontWeight: 700,
457
+ fontStyle: 'normal',
458
+ fontSize: '72px',
459
+ lineHeight: '80px',
460
+ letterSpacing: '0%',
461
+ verticalAlign: 'middle',
462
+ },
463
+ },
464
+ xl: {
465
+ regular: {
466
+ fontFamily: '"Inter",sans-serif',
467
+ fontWeight: 400,
468
+ fontStyle: 'normal',
469
+ fontSize: '60px',
470
+ lineHeight: '68px',
471
+ letterSpacing: '0%',
472
+ verticalAlign: 'middle',
473
+ },
474
+ medium: {
475
+ fontFamily: '"Inter",sans-serif',
476
+ fontWeight: 500,
477
+ fontStyle: 'normal',
478
+ fontSize: '60px',
479
+ lineHeight: '68px',
480
+ letterSpacing: '0%',
481
+ verticalAlign: 'middle',
482
+ },
483
+ semiBold: {
484
+ fontFamily: '"Inter",sans-serif',
485
+ fontWeight: 600,
486
+ fontStyle: 'normal',
487
+ fontSize: '60px',
488
+ lineHeight: '68px',
489
+ letterSpacing: '0%',
490
+ verticalAlign: 'middle',
491
+ },
492
+ bold: {
493
+ fontFamily: '"Inter",sans-serif',
494
+ fontWeight: 700,
495
+ fontStyle: 'normal',
496
+ fontSize: '60px',
497
+ lineHeight: '68px',
498
+ letterSpacing: '0%',
499
+ verticalAlign: 'middle',
500
+ },
501
+ },
502
+ lg: {
503
+ regular: {
504
+ fontFamily: '"Inter",sans-serif',
505
+ fontWeight: 400,
506
+ fontStyle: 'normal',
507
+ fontSize: '48px',
508
+ lineHeight: '56px',
509
+ letterSpacing: '0%',
510
+ verticalAlign: 'middle',
511
+ },
512
+ medium: {
513
+ fontFamily: '"Inter",sans-serif',
514
+ fontWeight: 500,
515
+ fontStyle: 'normal',
516
+ fontSize: '48px',
517
+ lineHeight: '56px',
518
+ letterSpacing: '0%',
519
+ verticalAlign: 'middle',
520
+ },
521
+ semiBold: {
522
+ fontFamily: '"Inter",sans-serif',
523
+ fontWeight: 600,
524
+ fontStyle: 'normal',
525
+ fontSize: '48px',
526
+ lineHeight: '56px',
527
+ letterSpacing: '0%',
528
+ verticalAlign: 'middle',
529
+ },
530
+ bold: {
531
+ fontFamily: '"Inter",sans-serif',
532
+ fontWeight: 700,
533
+ fontStyle: 'normal',
534
+ fontSize: '48px',
535
+ lineHeight: '56px',
536
+ letterSpacing: '0%',
537
+ verticalAlign: 'middle',
538
+ },
539
+ },
540
+ md: {
541
+ regular: {
542
+ fontFamily: '"Inter",sans-serif',
543
+ fontWeight: 400,
544
+ fontStyle: 'normal',
545
+ fontSize: '36px',
546
+ lineHeight: '44px',
547
+ letterSpacing: '0%',
548
+ verticalAlign: 'middle',
549
+ },
550
+ medium: {
551
+ fontFamily: '"Inter",sans-serif',
552
+ fontWeight: 500,
553
+ fontStyle: 'normal',
554
+ fontSize: '36px',
555
+ lineHeight: '44px',
556
+ letterSpacing: '0%',
557
+ verticalAlign: 'middle',
558
+ },
559
+ semiBold: {
560
+ fontFamily: '"Inter",sans-serif',
561
+ fontWeight: 600,
562
+ fontStyle: 'normal',
563
+ fontSize: '36px',
564
+ lineHeight: '44px',
565
+ letterSpacing: '0%',
566
+ verticalAlign: 'middle',
567
+ },
568
+ bold: {
569
+ fontFamily: '"Inter",sans-serif',
570
+ fontWeight: 700,
571
+ fontStyle: 'normal',
572
+ fontSize: '36px',
573
+ lineHeight: '44px',
574
+ letterSpacing: '0%',
575
+ verticalAlign: 'middle',
576
+ },
577
+ },
578
+ sm: {
579
+ regular: {
580
+ fontFamily: '"Inter",sans-serif',
581
+ fontWeight: 400,
582
+ fontStyle: 'normal',
583
+ fontSize: '30px',
584
+ lineHeight: '38px',
585
+ letterSpacing: '0%',
586
+ verticalAlign: 'middle',
587
+ },
588
+ medium: {
589
+ fontFamily: '"Inter",sans-serif',
590
+ fontWeight: 500,
591
+ fontStyle: 'normal',
592
+ fontSize: '30px',
593
+ lineHeight: '38px',
594
+ letterSpacing: '0%',
595
+ verticalAlign: 'middle',
596
+ },
597
+ semiBold: {
598
+ fontFamily: '"Inter",sans-serif',
599
+ fontWeight: 600,
600
+ fontStyle: 'normal',
601
+ fontSize: '30px',
602
+ lineHeight: '38px',
603
+ letterSpacing: '0%',
604
+ verticalAlign: 'middle',
605
+ },
606
+ bold: {
607
+ fontFamily: '"Inter",sans-serif',
608
+ fontWeight: 700,
609
+ fontStyle: 'normal',
610
+ fontSize: '30px',
611
+ lineHeight: '38px',
612
+ letterSpacing: '0%',
613
+ verticalAlign: 'middle',
614
+ },
615
+ },
616
+ xs: {
617
+ regular: {
618
+ fontFamily: '"Inter",sans-serif',
619
+ fontWeight: 400,
620
+ fontStyle: 'normal',
621
+ fontSize: '24px',
622
+ lineHeight: '32px',
623
+ letterSpacing: '0%',
624
+ verticalAlign: 'middle',
625
+ },
626
+ medium: {
627
+ fontFamily: '"Inter",sans-serif',
628
+ fontWeight: 500,
629
+ fontStyle: 'normal',
630
+ fontSize: '24px',
631
+ lineHeight: '32px',
632
+ letterSpacing: '0%',
633
+ verticalAlign: 'middle',
634
+ },
635
+ semiBold: {
636
+ fontFamily: '"Inter",sans-serif',
637
+ fontWeight: 600,
638
+ fontStyle: 'normal',
639
+ fontSize: '24px',
640
+ lineHeight: '32px',
641
+ letterSpacing: '0%',
642
+ verticalAlign: 'middle',
643
+ },
644
+ bold: {
645
+ fontFamily: '"Inter",sans-serif',
646
+ fontWeight: 700,
647
+ fontStyle: 'normal',
648
+ fontSize: '24px',
649
+ lineHeight: '32px',
650
+ letterSpacing: '0%',
651
+ verticalAlign: 'middle',
652
+ },
653
+ },
654
+ textXl: {
655
+ regular: {
656
+ fontFamily: '"Inter",sans-serif',
657
+ fontWeight: 400,
658
+ fontStyle: 'normal',
659
+ fontSize: '20px',
660
+ lineHeight: '28px',
661
+ letterSpacing: '0%',
662
+ verticalAlign: 'middle',
663
+ },
664
+ medium: {
665
+ fontFamily: '"Inter",sans-serif',
666
+ fontWeight: 500,
667
+ fontStyle: 'normal',
668
+ fontSize: '20px',
669
+ lineHeight: '28px',
670
+ letterSpacing: '0%',
671
+ verticalAlign: 'middle',
672
+ },
673
+ semiBold: {
674
+ fontFamily: '"Inter",sans-serif',
675
+ fontWeight: 600,
676
+ fontStyle: 'normal',
677
+ fontSize: '20px',
678
+ lineHeight: '28px',
679
+ letterSpacing: '0%',
680
+ verticalAlign: 'middle',
681
+ },
682
+ bold: {
683
+ fontFamily: '"Inter",sans-serif',
684
+ fontWeight: 700,
685
+ fontStyle: 'normal',
686
+ fontSize: '20px',
687
+ lineHeight: '28px',
688
+ letterSpacing: '0%',
689
+ verticalAlign: 'middle',
690
+ },
691
+ },
692
+ textLg: {
693
+ regular: {
694
+ fontFamily: '"Inter",sans-serif',
695
+ fontWeight: 400,
696
+ fontStyle: 'normal',
697
+ fontSize: '18px',
698
+ lineHeight: '26px',
699
+ letterSpacing: '0%',
700
+ verticalAlign: 'middle',
701
+ },
702
+ medium: {
703
+ fontFamily: '"Inter",sans-serif',
704
+ fontWeight: 500,
705
+ fontStyle: 'normal',
706
+ fontSize: '18px',
707
+ lineHeight: '26px',
708
+ letterSpacing: '0%',
709
+ verticalAlign: 'middle',
710
+ },
711
+ semiBold: {
712
+ fontFamily: '"Inter",sans-serif',
713
+ fontWeight: 600,
714
+ fontStyle: 'normal',
715
+ fontSize: '18px',
716
+ lineHeight: '26px',
717
+ letterSpacing: '0%',
718
+ verticalAlign: 'middle',
719
+ },
720
+ bold: {
721
+ fontFamily: '"Inter",sans-serif',
722
+ fontWeight: 700,
723
+ fontStyle: 'normal',
724
+ fontSize: '18px',
725
+ lineHeight: '26px',
726
+ letterSpacing: '0%',
727
+ verticalAlign: 'middle',
728
+ },
729
+ },
730
+ textMd: {
731
+ regular: {
732
+ fontFamily: '"Inter",sans-serif',
733
+ fontWeight: 400,
734
+ fontStyle: 'normal',
735
+ fontSize: '16px',
736
+ lineHeight: '24px',
737
+ letterSpacing: '0%',
738
+ verticalAlign: 'middle',
739
+ },
740
+ medium: {
741
+ fontFamily: '"Inter",sans-serif',
742
+ fontWeight: 500,
743
+ fontStyle: 'normal',
744
+ fontSize: '16px',
745
+ lineHeight: '24px',
746
+ letterSpacing: '0%',
747
+ verticalAlign: 'middle',
748
+ },
749
+ semiBold: {
750
+ fontFamily: '"Inter",sans-serif',
751
+ fontWeight: 600,
752
+ fontStyle: 'normal',
753
+ fontSize: '16px',
754
+ lineHeight: '24px',
755
+ verticalAlign: 'middle',
756
+ },
757
+ bold: {
758
+ fontFamily: '"Inter",sans-serif',
759
+ fontWeight: 700,
760
+ fontStyle: 'normal',
761
+ fontSize: '16px',
762
+ lineHeight: '24px',
763
+ letterSpacing: '0%',
764
+ verticalAlign: 'middle',
765
+ },
766
+ },
767
+ textSm: {
768
+ regular: {
769
+ fontFamily: '"Inter",sans-serif',
770
+ fontWeight: 400,
771
+ fontStyle: 'normal',
772
+ fontSize: '14px',
773
+ lineHeight: '22px',
774
+ letterSpacing: '0%',
775
+ verticalAlign: 'middle',
776
+ },
777
+ medium: {
778
+ fontFamily: '"Inter",sans-serif',
779
+ fontWeight: 500,
780
+ fontStyle: 'normal',
781
+ fontSize: '14px',
782
+ lineHeight: '22px',
783
+ letterSpacing: '0%',
784
+ verticalAlign: 'middle',
785
+ },
786
+ semiBold: {
787
+ fontFamily: '"Inter",sans-serif',
788
+ fontWeight: 600,
789
+ fontStyle: 'normal',
790
+ fontSize: '14px',
791
+ lineHeight: '22px',
792
+ letterSpacing: '0%',
793
+ verticalAlign: 'middle',
794
+ },
795
+ bold: {
796
+ fontFamily: '"Inter",sans-serif',
797
+ fontWeight: 700,
798
+ fontStyle: 'normal',
799
+ fontSize: '14px',
800
+ lineHeight: '22px',
801
+ letterSpacing: '0%',
802
+ verticalAlign: 'middle',
803
+ },
804
+ },
805
+ textXs: {
806
+ regular: {
807
+ fontFamily: '"Inter",sans-serif',
808
+ fontWeight: 400,
809
+ fontStyle: 'normal',
810
+ fontSize: '12px',
811
+ lineHeight: '20px',
812
+ letterSpacing: '0%',
813
+ verticalAlign: 'middle',
814
+ },
815
+ medium: {
816
+ fontFamily: '"Inter",sans-serif',
817
+ fontWeight: 500,
818
+ fontStyle: 'normal',
819
+ fontSize: '12px',
820
+ lineHeight: '20px',
821
+ letterSpacing: '0%',
822
+ verticalAlign: 'middle',
823
+ },
824
+ semiBold: {
825
+ fontFamily: '"Inter",sans-serif',
826
+ fontWeight: 600,
827
+ fontStyle: 'normal',
828
+ fontSize: '12px',
829
+ lineHeight: '20px',
830
+ letterSpacing: '0%',
831
+ verticalAlign: 'middle',
832
+ },
833
+ bold: {
834
+ fontFamily: '"Inter",sans-serif',
835
+ fontWeight: 700,
836
+ fontStyle: 'normal',
837
+ fontSize: '12px',
838
+ lineHeight: '20px',
839
+ letterSpacing: '0%',
840
+ verticalAlign: 'middle',
841
+ },
842
+ },
843
+ textSmall: {
844
+ regular: {
845
+ fontFamily: '"Inter",sans-serif',
846
+ fontWeight: 400,
847
+ fontStyle: 'normal',
848
+ fontSize: '10px',
849
+ lineHeight: '12px',
850
+ letterSpacing: 0.1,
851
+ verticalAlign: 'middle',
852
+ },
853
+ medium: {
854
+ fontFamily: '"Inter",sans-serif',
855
+ fontWeight: 500,
856
+ fontStyle: 'normal',
857
+ fontSize: '10px',
858
+ lineHeight: '12px',
859
+ letterSpacing: '0%',
860
+ verticalAlign: 'middle',
861
+ },
862
+ semiBold: {
863
+ fontFamily: '"Inter",sans-serif',
864
+ fontWeight: 600,
865
+ fontStyle: 'normal',
866
+ fontSize: '10px',
867
+ lineHeight: '12px',
868
+ letterSpacing: 0.1,
869
+ verticalAlign: 'middle',
870
+ },
871
+ bold: {
872
+ fontFamily: '"Inter",sans-serif',
873
+ fontWeight: 700,
874
+ fontStyle: 'normal',
875
+ fontSize: '10px',
876
+ lineHeight: '12px',
877
+ letterSpacing: 0.1,
878
+ verticalAlign: 'middle',
879
+ },
880
+ },
881
+ };
882
+
883
+ const StackRow = styled(Stack)(() => ({
884
+ flexDirection: 'row',
885
+ }));
886
+ styled(Stack)(() => ({
887
+ flexDirection: 'row',
888
+ flexWrap: 'wrap',
889
+ }));
890
+ const StackRowAlignCenter = styled(Stack)(() => ({
891
+ flexDirection: 'row',
892
+ alignItems: 'center',
893
+ }));
894
+ styled(Stack)(() => ({
895
+ flexDirection: 'row',
896
+ alignItems: 'flex-end',
897
+ }));
898
+ styled(Stack)(() => ({
899
+ flexDirection: 'row',
900
+ justifyContent: 'center',
901
+ }));
902
+ styled(Stack)(() => ({
903
+ flexDirection: 'row',
904
+ justifyContent: 'space-around',
905
+ }));
906
+ styled(Stack)(() => ({
907
+ flexDirection: 'row',
908
+ alignItems: 'center',
909
+ justifyContent: 'center',
910
+ }));
911
+ const StackRowAlignCenterJustEnd = styled(Stack)(() => ({
912
+ flexDirection: 'row',
913
+ alignItems: 'center',
914
+ justifyContent: 'flex-end',
915
+ }));
916
+ styled(Stack)(() => ({
917
+ flexDirection: 'row',
918
+ justifyContent: 'flex-end',
919
+ }));
920
+ styled(Stack)(() => ({
921
+ flexDirection: 'row',
922
+ justifyContent: 'space-between',
923
+ }));
924
+ const StackRowAlignCenterJustBetween = styled(Stack)(() => ({
925
+ flexDirection: 'row',
926
+ alignItems: 'center',
927
+ justifyContent: 'space-between',
928
+ }));
929
+ styled(Stack)(() => ({
930
+ flexDirection: 'row',
931
+ alignItems: 'flex-start',
932
+ justifyContent: 'space-between',
933
+ }));
934
+ styled(Stack)(({ theme }) => ({
935
+ backgroundColor: theme.palette.background.default,
936
+ padding: PADDING_GAP_LAYOUT,
937
+ borderRadius: BORDER_RADIUS_ELEMENT,
938
+ }));
939
+ styled(Stack)(({ theme }) => ({
940
+ backgroundColor: theme.palette.background.paper,
941
+ padding: PADDING_GAP_LAYOUT,
942
+ borderRadius: BORDER_RADIUS_ELEMENT,
943
+ }));
944
+ styled(Stack)(() => ({
945
+ flexDirection: 'row',
946
+ alignItems: 'center',
947
+ marginRight: PADDING_GAP_ITEM_SMALL,
948
+ gap: PADDING_GAP_ITEM_SMALL,
949
+ }));
950
+ styled(Stack)(({ theme }) => ({
951
+ border: `1px solid ${theme.palette.common.white}`,
952
+ borderRadius: '50%',
953
+ display: 'flex',
954
+ justifyContent: 'center',
955
+ alignItems: 'center',
956
+ background: theme.palette.background.paper,
957
+ width: 16,
958
+ height: 16,
959
+ }));
960
+ styled(Stack)(({ theme }) => ({
961
+ borderRadius: BORDER_RADIUS_ELEMENT_TAG,
962
+ // padding: '6px',
963
+ backgroundColor: theme.palette.background.paper,
964
+ boxShadow: theme.shadows[1],
965
+ width: 'fit-content',
966
+ gap: 'unset',
967
+ }));
968
+ styled(TableCell)(({ theme }) => ({
969
+ [`&.${tableCellClasses.head}`]: {
970
+ backgroundColor: '#008A77',
971
+ color: theme.palette.common.white,
972
+ fontWeight: 600,
973
+ },
974
+ [`&.${tableCellClasses.body}`]: {
975
+ fontSize: 14,
976
+ },
977
+ '&:first-of-type': {
978
+ borderBottomLeftRadius: '0 !important',
979
+ },
980
+ '&:last-child': {
981
+ borderBottomRightRadius: '0 !important',
982
+ },
983
+ }));
984
+ styled(LinearProgress)(({ theme }) => ({
985
+ height: 10,
986
+ borderRadius: 5,
987
+ [`&.${linearProgressClasses.colorPrimary}`]: {
988
+ backgroundColor: theme.palette.grey[200],
989
+ ...theme.applyStyles('dark', {
990
+ backgroundColor: theme.palette.grey[800],
991
+ }),
992
+ },
993
+ [`& .${linearProgressClasses.bar}`]: {
994
+ borderRadius: 5,
995
+ backgroundColor: theme.palette.primary,
996
+ },
997
+ }));
998
+
999
+ var ImageSizeType;
1000
+ (function (ImageSizeType) {
1001
+ ImageSizeType["CIRCLE"] = "CIRCLE";
1002
+ ImageSizeType["SQUARE"] = "SQUARE";
1003
+ ImageSizeType["FULL_WIDTH"] = "FULL_WIDTH";
1004
+ })(ImageSizeType || (ImageSizeType = {}));
1005
+
1006
+ const ImageWrapper = ({ isWrap = false, children }) => {
1007
+ return isWrap ? (jsx(StackRow, { alignItems: "center", className: "jsdsdj", children: children })) : (jsx(Fragment, { children: children }));
1008
+ };
1009
+ const ImageElement = ({ url, onClick, sx = {}, isBorder = false, isWrap = false, sizeType = ImageSizeType.CIRCLE, size = 'medium', ...rest }) => {
1010
+ const { palette } = useTheme();
1011
+ const [loaded, setLoaded] = useState(false);
1012
+ if (onClick)
1013
+ sx = { ...sx, cursor: 'pointer' };
1014
+ const borderRadius = sizeType === ImageSizeType.CIRCLE
1015
+ ? '50%'
1016
+ : sizeType === ImageSizeType.SQUARE
1017
+ ? BORDER_RADIUS_ELEMENT_SMALL
1018
+ : 0;
1019
+ return (jsxs(ImageWrapper, { isWrap: isWrap, children: [!loaded && (jsx(Skeleton, { variant: "rectangular", sx: {
1020
+ ...MAP_SIZE[size],
1021
+ borderRadius,
1022
+ } })), jsx(Box, { ...rest, component: "img", src: url, onClick: onClick, onLoad: () => setLoaded(true), onError: (e) => {
1023
+ e.currentTarget.src = '/images/diamond.png';
1024
+ }, sx: {
1025
+ display: loaded ? 'block' : 'none',
1026
+ ...MAP_SIZE[size],
1027
+ objectFit: 'cover',
1028
+ borderRadius,
1029
+ border: isBorder ? `1px solid ${palette.divider}` : 'none',
1030
+ ...sx,
1031
+ } })] }));
1032
+ };
1033
+
1034
+ const AvatarProfileComponent = ({ url, size = 'md', border = false, borderColor = '#C3FFF2', borderWidth = 4, onClick, sx = {}, children, ...rest }) => {
1035
+ return (jsx(Box, { sx: {
1036
+ width: AVATAR_SIZES[size],
1037
+ height: AVATAR_SIZES[size],
1038
+ borderRadius: '50%',
1039
+ ...(border && {
1040
+ border: `${borderWidth}px solid ${borderColor}`,
1041
+ }),
1042
+ ...sx,
1043
+ }, children: jsx(ImageElement, { ...rest, url: url || '/images/avatarDefault.png', onClick: onClick, sx: {
1044
+ width: '100%',
1045
+ height: '100%',
1046
+ ...(onClick && { cursor: 'pointer' }),
1047
+ }, children: children }) }));
1048
+ };
1049
+
1050
+ const BadgeLive = ({ text = 'LIVE', size = 'md' }) => {
1051
+ const { typography } = useTheme();
1052
+ return (jsx(Box, { sx: {
1053
+ bgcolor: AvatarColor.BACKGROUND_COLOR_BADGE,
1054
+ color: AvatarColor.COLOR_BADGE,
1055
+ borderRadius: '12px',
1056
+ padding: '3px 6px',
1057
+ fontSize: BADGE_FONT_SIZES[size],
1058
+ fontWeight: typography.body2.fontWeight,
1059
+ }, children: text }));
1060
+ };
1061
+ const BadgeNumber = ({ number, size = 'md' }) => {
1062
+ const { typography } = useTheme();
1063
+ return (jsx(Box, { sx: {
1064
+ bgcolor: AvatarColor.BACKGROUND_COLOR_BADGE,
1065
+ color: AvatarColor.COLOR_BADGE,
1066
+ borderRadius: '50%',
1067
+ width: BADGE_SIZES[size],
1068
+ height: BADGE_SIZES[size],
1069
+ display: 'flex',
1070
+ alignItems: 'center',
1071
+ justifyContent: 'center',
1072
+ fontSize: BADGE_FONT_SIZES[size],
1073
+ fontWeight: typography.h2.fontWeight,
1074
+ }, children: number }));
1075
+ };
1076
+ const BadgeOnline = ({ size = 'md' }) => (jsx(Box, { sx: {
1077
+ width: BADGE_SIZES[size],
1078
+ height: BADGE_SIZES[size],
1079
+ borderRadius: '50%',
1080
+ bgcolor: '#4CAF50',
1081
+ border: '2px solid white',
1082
+ } }));
1083
+ const BadgeImage = ({ url, size = 'md' }) => (jsx(Box, { component: "img", src: url, alt: "badge", sx: {
1084
+ width: BADGE_SIZES[size],
1085
+ height: BADGE_SIZES[size],
1086
+ borderRadius: '50%',
1087
+ objectFit: 'cover',
1088
+ display: 'flex',
1089
+ alignItems: 'center',
1090
+ justifyContent: 'center',
1091
+ } }));
1092
+ const AvatarComponent = ({ url, size = 'md', border = false, borderColor = '#C3FFF2', borderWidth = 4, badge, badgePosition = 'bottom-right', onClick, sx = {}, sxProfile = {}, children, ...rest }) => {
1093
+ // Tự động inject size vào badge
1094
+ const badgeWithSize = badge && React.isValidElement(badge) ? React.cloneElement(badge, { size }) : badge;
1095
+ return (jsxs(Box, { sx: {
1096
+ position: 'relative',
1097
+ display: 'inline-flex',
1098
+ width: AVATAR_SIZES[size],
1099
+ height: AVATAR_SIZES[size],
1100
+ ...sx,
1101
+ }, children: [jsx(AvatarProfileComponent, { url: url, size: size, border: border, borderWidth: borderWidth, borderColor: borderColor, onClick: onClick, sx: sxProfile, ...rest, children: children }), badgeWithSize && (jsx(Box, { sx: {
1102
+ position: 'absolute',
1103
+ ...getBadgePosition(badgePosition),
1104
+ }, children: badgeWithSize }))] }));
1105
+ };
1106
+
1107
+ const IconElement = ({ icon, size = 'medium', color, disabled, onClick, sx, fill = 0, }) => {
1108
+ const { palette } = useTheme();
1109
+ if (disabled) {
1110
+ onClick = undefined;
1111
+ color = 'disabled';
1112
+ }
1113
+ if (onClick)
1114
+ sx = {
1115
+ cursor: 'pointer',
1116
+ '&:hover': {
1117
+ color: color ? 'none' : palette.primary.main,
1118
+ },
1119
+ ...sx,
1120
+ };
1121
+ return (jsx(Icon, { onClick: onClick, color: color, sx: {
1122
+ cursor: 'inherit',
1123
+ fontSize: FONT_SIZE_ICON[size],
1124
+ fontVariationSettings: `'FILL' ${fill}, 'wght' 100, 'GRAD' 200, 'opsz' 24`,
1125
+ ...sx,
1126
+ }, component: 'span', className: "material-symbols-rounded", children: icon }));
1127
+ };
1128
+
1129
+ const AvatarGroupComponent = ({ avatars = [], maxDisplay = 10, size = 'md', border = true, borderColor = '#FFFFFF', borderWidth = 2, onAddClick, overlap = 8, icon, sxAvatar, sx, }) => {
1130
+ const displayAvatars = avatars.slice(0, maxDisplay);
1131
+ const remainingCount = avatars.length - maxDisplay;
1132
+ return (jsxs(StackRowAlignCenter, { sx: { gap: 1, ...sx }, children: [jsxs(Box, { sx: { display: 'flex', alignItems: 'center' }, children: [displayAvatars.map((avatar, index) => (jsx(Box, { sx: {
1133
+ marginLeft: index > 0 ? `-${overlap}px` : 0,
1134
+ position: 'relative',
1135
+ }, children: jsx(AvatarComponent, { url: avatar.url, size: size, border: border, borderColor: borderColor, borderWidth: borderWidth, sx: sxAvatar }) }, avatar.id || index))), remainingCount > 0 && (jsxs(Box, { sx: {
1136
+ marginLeft: `-${overlap}px`,
1137
+ position: 'relative',
1138
+ color: '#07554B',
1139
+ backgroundColor: '#EDFFFA',
1140
+ width: AVATAR_SIZES[size],
1141
+ height: AVATAR_SIZES[size],
1142
+ display: 'flex',
1143
+ alignItems: 'center',
1144
+ justifyContent: 'center',
1145
+ border: '2px solid #ffffff',
1146
+ borderRadius: '50%',
1147
+ ...TYPOGRAPHY_STYLES.textMd.medium,
1148
+ }, children: ["+", remainingCount] }))] }), icon && (jsx(Box, { sx: {
1149
+ width: AVATAR_SIZES[size],
1150
+ height: AVATAR_SIZES[size],
1151
+ borderRadius: '50%',
1152
+ border: `2px dashed #D1D5DB`,
1153
+ display: 'flex',
1154
+ alignItems: 'center',
1155
+ justifyContent: 'center',
1156
+ cursor: 'pointer',
1157
+ transition: 'all 0.2s',
1158
+ '&:hover': {
1159
+ borderColor: 'primary.main',
1160
+ },
1161
+ }, onClick: onAddClick, children: jsx(IconElement, { icon: icon, sx: {
1162
+ color: 'primary.main',
1163
+ } }) }))] }));
1164
+ };
1165
+
1166
+ const AvatarLabelGroupComponent = ({ title, description, url, size = 'md', border, borderColor, borderWidth, badge, badgePosition, onClick, sx, sxAvatar, children, ...rest }) => {
1167
+ return (jsxs(Stack, { direction: "row", alignItems: "center", sx: { gap: BORDER_RADIUS_ELEMENT, ...sx }, children: [jsx(AvatarComponent, { url: url, size: size, border: border, borderColor: borderColor, borderWidth: borderWidth, badge: badge, badgePosition: badgePosition, onClick: onClick, sx: sxAvatar, ...rest, children: children }), jsxs(Stack, { sx: { gap: 0 }, children: [jsx(Typography, { noWrap: true, sx: { ...TYPOGRAPHY_STYLES.textSm.semiBold, color: AvatarColor.COLOR_TITLE }, children: title }), jsx(Typography, { noWrap: true, sx: { ...TYPOGRAPHY_STYLES.textXs.regular, color: AvatarColor.COLOR_DESCRIPTION }, children: description })] })] }));
1168
+ };
1169
+
1170
+ const getLimitLineCss = (line) => ({
1171
+ display: '-webkit-box',
1172
+ overflow: 'hidden',
1173
+ WebkitBoxOrient: 'vertical',
1174
+ WebkitLineClamp: line,
1175
+ // textOverflow: 'ellipsis',
1176
+ });
1177
+ const TypographyOneLine = ({ content, sx = {}, ...rest }) => {
1178
+ return (jsx(Typography, { sx: {
1179
+ ...getLimitLineCss(1),
1180
+ ...sx,
1181
+ }, ...rest, children: content }));
1182
+ };
1183
+
1184
+ const AvatarUserComponent = ({ title, description, descriptionHref, onDescriptionClick, titleColor = '#414651', descriptionColor = '#535862', url, onClick, sx, }) => {
1185
+ return (jsxs(Stack, { sx: { gap: 1, ...sx }, children: [jsx(ImageElement, { sx: {
1186
+ width: 160,
1187
+ height: 160,
1188
+ ...(onClick && { cursor: 'pointer' }),
1189
+ }, url: url || '/images/avatarDefault.png', sizeType: ImageSizeType.SQUARE }), jsxs(Stack, { sx: { gap: 0 }, children: [jsx(TypographyOneLine, { sx: { ...TYPOGRAPHY_STYLES.textLg.semiBold, color: titleColor }, content: title }), description && (jsxs(Link, { href: descriptionHref, onClick: onDescriptionClick, sx: {
1190
+ display: 'flex',
1191
+ alignItems: 'center',
1192
+ gap: 0.5,
1193
+ textDecoration: 'underline',
1194
+ color: descriptionColor,
1195
+ ...TYPOGRAPHY_STYLES.textSm.regular,
1196
+ cursor: 'pointer',
1197
+ '&:hover': {
1198
+ opacity: 0.8,
1199
+ },
1200
+ }, children: [jsx(LinkIcon, { sx: { fontSize: 16, color: descriptionColor } }), description] }))] })] }));
1201
+ };
1202
+
1203
+ const SEPARATOR_URLS = {
1204
+ '>': '/images/icon/chevron-right.svg',
1205
+ '/': '/images/icon/slash-separator.svg',
1206
+ };
1207
+ const BreadcrumbsComponent = ({ items, separator = '>', maxItems = 5, idSelect, sx, sxItem, onChange, }) => {
1208
+ // state
1209
+ const [anchorEl, setAnchorEl] = useState(null);
1210
+ const showCollapsed = items.length > maxItems;
1211
+ const visibleItems = showCollapsed ? [items[0], ...items.slice(-2)] : items;
1212
+ const collapsedItems = showCollapsed ? items.slice(1, -2) : [];
1213
+ // function
1214
+ const handleMenuOpen = (event) => {
1215
+ setAnchorEl(event.currentTarget);
1216
+ };
1217
+ const handleMenuClose = () => {
1218
+ setAnchorEl(null);
1219
+ };
1220
+ const renderItem = (item) => {
1221
+ const isActive = item.id === idSelect;
1222
+ return (jsxs(Link, { href: item.href, onClick: (e) => {
1223
+ if (item.onClick) {
1224
+ e.preventDefault();
1225
+ item.onClick();
1226
+ }
1227
+ if (onChange) {
1228
+ onChange(item.id);
1229
+ }
1230
+ }, sx: {
1231
+ display: 'flex',
1232
+ alignItems: 'center',
1233
+ gap: GAP_ICON_CONTENT_BY_SIZE.medium,
1234
+ ...TYPOGRAPHY_STYLES.textSm.semiBold,
1235
+ color: isActive ? '#000000' : '#676E76',
1236
+ cursor: 'pointer',
1237
+ textDecoration: 'none',
1238
+ ...sxItem,
1239
+ }, children: [item.icon && jsx(IconElement, { icon: item.icon }), item.label] }, item.id));
1240
+ };
1241
+ const renderSeparator = () => jsx(ImageElement, { sx: { width: 14, height: 14 }, url: SEPARATOR_URLS[separator] });
1242
+ return (jsxs(React.Fragment, { children: [jsx(Breadcrumbs, { "aria-label": "breadcrumb", sx: { ...sx }, children: showCollapsed ? (jsxs(StackRowAlignCenter, { sx: { gap: GAP_ICON_CONTENT_BY_SIZE.small }, children: [renderItem(items[0]), renderSeparator(), jsx(IconButton, { size: "small", onClick: handleMenuOpen, sx: { p: 0, mt: 'auto' }, children: jsx(IconElement, { icon: "more_horiz" }) }), renderSeparator(), visibleItems.slice(1).map((item, idx) => (jsxs(React.Fragment, { children: [idx > 0 && renderSeparator(), renderItem(item)] }, item.id)))] })) : (items.map((item) => renderItem(item))) }), jsx(Menu, { anchorEl: anchorEl, open: Boolean(anchorEl), onClose: handleMenuClose, disableScrollLock: true, children: collapsedItems.map((item) => {
1243
+ const isActive = item.id === idSelect;
1244
+ return (jsxs(MenuItem, { onClick: () => {
1245
+ if (item.onClick) {
1246
+ item.onClick();
1247
+ }
1248
+ handleMenuClose();
1249
+ }, sx: {
1250
+ gap: GAP_ICON_CONTENT_BY_SIZE.medium,
1251
+ color: isActive ? '#0F766E' : '#111827',
1252
+ bgcolor: isActive ? '#E0F2FE' : 'transparent',
1253
+ }, children: [item.icon && jsx(IconElement, { icon: item.icon }), item.label] }, item.id));
1254
+ }) })] }));
1255
+ };
1256
+
1257
+ /** Shade values mapping */
1258
+ const SHADE_VALUES = {
1259
+ light: 100,
1260
+ main: 500,
1261
+ dark: 700,
1262
+ };
1263
+ /** Button size configuration */
1264
+ const SIZES = {
1265
+ xs: { padding: '6px 12px', fontSize: '10px', height: '28px' },
1266
+ sm: { padding: '8px 16px', fontSize: '12px', height: '32px' },
1267
+ md: { padding: '16px 28px', fontSize: '14px', height: '60px', width: '192px' },
1268
+ lg: { padding: '12px 24px', fontSize: '16px', height: '44px' },
1269
+ xl: { padding: '14px 32px', fontSize: '18px', height: '48px' },
1270
+ };
1271
+ /** Color palette mapping */
1272
+ const COLORS = {
1273
+ brand: COLOR_BRAND,
1274
+ neutral: COLOR_NEUTRAL,
1275
+ error: COLOR_ERROR,
1276
+ warning: COLOR_WARNING,
1277
+ success: COLOR_SUCCESS,
1278
+ accent: COLOR_ACCENT,
1279
+ info: COLOR_INFO,
1280
+ };
1281
+ /** Button UI constants */
1282
+ const BUTTON_CONSTANTS = {
1283
+ ACTIVE_DOT_SIZE: 8,
1284
+ ACTIVE_DOT_MARGIN_RIGHT: 8,
1285
+ SPINNER_SIZE: 16,
1286
+ GAP: 12,
1287
+ BORDER_RADIUS: 8,
1288
+ TRANSITION_DURATION: '0.3s',
1289
+ };
1290
+ /** Accessibility constants */
1291
+ const ACCESSIBILITY = {
1292
+ HOVER_TRANSLATE_Y: '-2px',
1293
+ ACTIVE_TRANSLATE_Y: '0',
1294
+ BOX_SHADOW: '0 4px 12px rgba(0, 0, 0, 0.15)',
1295
+ FOCUS_OFFSET: '2px',
1296
+ };
1297
+
1298
+ const getButtonSx = (variant, color, shade, size, fullWidth) => {
1299
+ const colors = COLORS[color];
1300
+ const sizeConf = SIZES[size] || SIZES.md;
1301
+ // Xác định màu sắc theo shade
1302
+ let colorValue;
1303
+ if (typeof shade === 'number') {
1304
+ colorValue = colors[shade] || colors[700];
1305
+ }
1306
+ else {
1307
+ const shadeNum = SHADE_VALUES[shade] || 700;
1308
+ colorValue = colors[shadeNum];
1309
+ }
1310
+ const lightColor = colors[100];
1311
+ const base = {
1312
+ padding: sizeConf.padding,
1313
+ height: sizeConf.height,
1314
+ fontSize: sizeConf.fontSize,
1315
+ width: fullWidth ? '100%' : sizeConf.width || 'auto',
1316
+ fontFamily: TYPOGRAPHY.body.fontFamily,
1317
+ fontWeight: TYPOGRAPHY.body.fontWeight,
1318
+ borderRadius: `${BUTTON_CONSTANTS.BORDER_RADIUS}px`,
1319
+ gap: `${BUTTON_CONSTANTS.GAP}px`,
1320
+ textTransform: 'none',
1321
+ transition: `all ${BUTTON_CONSTANTS.TRANSITION_DURATION} ease`,
1322
+ '&:hover': {
1323
+ transform: `translateY(${ACCESSIBILITY.HOVER_TRANSLATE_Y})`,
1324
+ boxShadow: ACCESSIBILITY.BOX_SHADOW,
1325
+ },
1326
+ '&:active': {
1327
+ transform: `translateY(${ACCESSIBILITY.ACTIVE_TRANSLATE_Y})`,
1328
+ },
1329
+ '&:focus-visible': {
1330
+ outline: `2px solid ${colorValue}`,
1331
+ outlineOffset: ACCESSIBILITY.FOCUS_OFFSET,
1332
+ },
1333
+ };
1334
+ const variants = {
1335
+ solid: {
1336
+ backgroundColor: colorValue,
1337
+ color: '#ffffff',
1338
+ '&:hover': { ...base['&:hover'], backgroundColor: colorValue },
1339
+ '&:focus-visible': { ...base['&:focus-visible'], outline: '2px solid #ffffff' },
1340
+ },
1341
+ outline: {
1342
+ backgroundColor: 'transparent',
1343
+ color: colorValue,
1344
+ border: `2px solid ${colorValue}`,
1345
+ '&:hover': { ...base['&:hover'], backgroundColor: 'transparent', border: `2px solid ${colorValue}` },
1346
+ },
1347
+ ghost: {
1348
+ backgroundColor: lightColor,
1349
+ color: colorValue,
1350
+ '&:hover': { ...base['&:hover'], backgroundColor: lightColor },
1351
+ },
1352
+ text: {
1353
+ backgroundColor: 'transparent',
1354
+ color: colorValue,
1355
+ border: 'none',
1356
+ '&:hover': { ...base['&:hover'], backgroundColor: 'transparent' },
1357
+ },
1358
+ };
1359
+ return { ...base, ...variants[variant] };
1360
+ };
1361
+ const ButtonComponent = ({ variant = 'solid', color = 'brand', shade = 'dark', size = 'md', prefix, suffix, prefixIcon, suffixIcon, iconStyle, loading = false, children, fullWidth = false, disabled = false, active = false, activeDotColor = '#10b981', sx, ...props }) => {
1362
+ // Memoize style calculation
1363
+ const buttonSx = getButtonSx(variant, color, shade, size, fullWidth);
1364
+ // Render prefix element
1365
+ const renderPrefix = () => {
1366
+ if (prefixIcon)
1367
+ return jsx(IconElement, { icon: prefixIcon, sx: iconStyle });
1368
+ if (prefix)
1369
+ return prefix;
1370
+ return null;
1371
+ };
1372
+ // Render suffix element
1373
+ const renderSuffix = () => {
1374
+ if (suffixIcon)
1375
+ return jsx(IconElement, { icon: suffixIcon, sx: iconStyle });
1376
+ if (suffix)
1377
+ return suffix;
1378
+ return null;
1379
+ };
1380
+ const prefixContent = loading ? (jsx(CircularProgress, { size: BUTTON_CONSTANTS.SPINNER_SIZE, sx: { color: COLOR_NEUTRAL[50] } })) : (renderPrefix());
1381
+ const suffixContent = renderSuffix();
1382
+ // Nếu chỉ có icon mà không có children, render icon giữa button
1383
+ const isIconOnly = !children && !active && (prefixContent || suffixContent);
1384
+ // Active dot element
1385
+ const activeDot = active ? (jsx("span", { style: {
1386
+ width: `${BUTTON_CONSTANTS.ACTIVE_DOT_SIZE}px`,
1387
+ height: `${BUTTON_CONSTANTS.ACTIVE_DOT_SIZE}px`,
1388
+ borderRadius: '50%',
1389
+ backgroundColor: activeDotColor,
1390
+ display: 'inline-block',
1391
+ flexShrink: 0,
1392
+ marginRight: `${BUTTON_CONSTANTS.ACTIVE_DOT_MARGIN_RIGHT}px`,
1393
+ } })) : null;
1394
+ return (jsx(Button, { sx: { ...buttonSx, ...sx }, disabled: disabled || loading, fullWidth: fullWidth, startIcon: !isIconOnly ? prefixContent : undefined, endIcon: !isIconOnly ? suffixContent : undefined, ...props, children: isIconOnly ? (jsxs(Fragment, { children: [prefixContent, suffixContent] })) : (jsxs(Fragment, { children: [activeDot, children] })) }));
1395
+ };
1396
+
1397
+ const ButtonBarComponent = ({ layout, children, gap = 12, style }) => {
1398
+ const containerStyle = {
1399
+ display: 'flex',
1400
+ flexDirection: layout === 'horizontal' ? 'row' : 'column',
1401
+ gap: `${gap}px`,
1402
+ alignItems: layout === 'horizontal' ? 'center' : 'stretch',
1403
+ ...style,
1404
+ };
1405
+ return jsx("div", { style: containerStyle, children: children });
1406
+ };
1407
+
1408
+ const CHECKBOX_COLORS = {
1409
+ default: {
1410
+ border: '#D0D5DD',
1411
+ background: '#FFFFFF',
1412
+ hoverBg: '#F0FDF9',
1413
+ },
1414
+ checked: {
1415
+ border: '#07554B',
1416
+ filledBg: '#07554B',
1417
+ outlinedBg: '#FFFFFF',
1418
+ icon: '#FFFFFF',
1419
+ },
1420
+ disabled: {
1421
+ border: '#E4E7EC',
1422
+ background: '#F2F4F7',
1423
+ icon: '#98A2B3',
1424
+ },
1425
+ };
1426
+ const CHECKBOX_SIZE = {
1427
+ small: {
1428
+ boxSize: 16,
1429
+ iconSize: 14,
1430
+ titleFontSize: 14,
1431
+ titleFontWeight: 500,
1432
+ },
1433
+ medium: {
1434
+ boxSize: 20,
1435
+ iconSize: 16,
1436
+ titleFontSize: 16,
1437
+ titleFontWeight: 600,
1438
+ },
1439
+ };
1440
+
1441
+ const CheckboxComponent = ({ checked = false, disabled = false, shape = 'square', size = 'medium', variant = 'filled', iconType = 'check', title, children, onChange, sxCheckbox, sxLabel, sx, }) => {
1442
+ const checkboxStyle = CHECKBOX_SIZE[size];
1443
+ const isFilled = variant === 'filled';
1444
+ const handleToggle = () => {
1445
+ if (!disabled) {
1446
+ onChange?.(!checked);
1447
+ }
1448
+ };
1449
+ const backgroundColor = disabled
1450
+ ? CHECKBOX_COLORS.disabled.background
1451
+ : checked
1452
+ ? isFilled
1453
+ ? sxCheckbox?.backgroundColor || CHECKBOX_COLORS.checked.filledBg
1454
+ : CHECKBOX_COLORS.checked.outlinedBg
1455
+ : CHECKBOX_COLORS.default.background;
1456
+ const borderColor = disabled
1457
+ ? CHECKBOX_COLORS.disabled.border
1458
+ : checked
1459
+ ? sxCheckbox?.borderColor || CHECKBOX_COLORS.checked.border
1460
+ : CHECKBOX_COLORS.default.border;
1461
+ const iconColor = disabled
1462
+ ? CHECKBOX_COLORS.disabled.icon
1463
+ : isFilled
1464
+ ? CHECKBOX_COLORS.checked.icon
1465
+ : CHECKBOX_COLORS.checked.border;
1466
+ const renderIcon = () => {
1467
+ if (!checked)
1468
+ return null;
1469
+ const iconSx = {
1470
+ width: checkboxStyle.iconSize,
1471
+ height: checkboxStyle.iconSize,
1472
+ color: iconColor,
1473
+ };
1474
+ switch (iconType) {
1475
+ case 'check':
1476
+ return jsx(CheckIcon, { sx: iconSx });
1477
+ case 'minus':
1478
+ return jsx(RemoveIcon, { sx: iconSx });
1479
+ case 'dot':
1480
+ return (jsx(FiberManualRecordIcon, { sx: { ...iconSx, width: checkboxStyle.iconSize - 3, height: checkboxStyle.iconSize - 3 } }));
1481
+ case 'custom':
1482
+ return children;
1483
+ default:
1484
+ return null;
1485
+ }
1486
+ };
1487
+ const checkbox = (jsx(Box, { role: "checkbox", tabIndex: disabled ? -1 : 0, "aria-checked": checked, onClick: handleToggle, onKeyDown: (e) => {
1488
+ if (!disabled && (e.key === 'Enter' || e.key === ' ')) {
1489
+ e.preventDefault();
1490
+ handleToggle();
1491
+ }
1492
+ }, sx: {
1493
+ width: checkboxStyle.boxSize,
1494
+ height: checkboxStyle.boxSize,
1495
+ display: 'flex',
1496
+ alignItems: 'center',
1497
+ justifyContent: 'center',
1498
+ cursor: disabled ? 'not-allowed' : 'pointer',
1499
+ userSelect: 'none',
1500
+ borderRadius: shape === 'circle' ? '50%' : '4px',
1501
+ border: `1px solid ${borderColor}`,
1502
+ backgroundColor,
1503
+ transition: 'all 0.2s ease',
1504
+ ...(!disabled &&
1505
+ (!checked || !isFilled) && {
1506
+ '&:hover': {
1507
+ borderColor: sxCheckbox?.backgroundColor || CHECKBOX_COLORS.checked.border,
1508
+ backgroundColor: CHECKBOX_COLORS.default.hoverBg,
1509
+ },
1510
+ }),
1511
+ '&:focus-visible': {
1512
+ outline: 'none',
1513
+ boxShadow: '0 0 0 3px rgba(14, 147, 132, 0.25)',
1514
+ },
1515
+ ...(disabled && { opacity: 0.4 }),
1516
+ }, children: renderIcon() }));
1517
+ if (!title)
1518
+ return checkbox;
1519
+ return (jsxs(Box, { onClick: handleToggle, sx: {
1520
+ display: 'inline-flex',
1521
+ alignItems: 'center',
1522
+ gap: '8px',
1523
+ cursor: disabled ? 'not-allowed' : 'pointer',
1524
+ ...sx,
1525
+ }, children: [checkbox, jsx(Typography, { fontSize: checkboxStyle.titleFontSize, fontWeight: checkboxStyle.titleFontWeight, color: disabled ? '#D0D5DD' : '#344054', sx: {
1526
+ userSelect: 'none',
1527
+ ...sxLabel,
1528
+ }, children: title })] }));
1529
+ };
1530
+
1531
+ const CHIP_LABEL_PADDING = {
1532
+ WITH_ICON_LEFT: '4px 8px 4px 4px',
1533
+ WITH_ICON_RIGHT: '4px 4px 4px 8px',
1534
+ NO_ICON: '4px 8px',
1535
+ };
1536
+ const CHIP_SIZE_CONFIG = {
1537
+ small: {
1538
+ height: 24,
1539
+ fontSize: '12px',
1540
+ borderRadius: '12px',
1541
+ iconSize: '16px',
1542
+ },
1543
+ medium: {
1544
+ height: 32,
1545
+ fontSize: '14px',
1546
+ borderRadius: '16px',
1547
+ iconSize: '18px',
1548
+ },
1549
+ large: {
1550
+ height: 40,
1551
+ fontSize: '16px',
1552
+ borderRadius: '20px',
1553
+ iconSize: '22px',
1554
+ },
1555
+ };
1556
+
1557
+ const getLabelPadding = (hasIcon, position) => {
1558
+ if (!hasIcon)
1559
+ return CHIP_LABEL_PADDING.NO_ICON;
1560
+ return position === 'left' ? CHIP_LABEL_PADDING.WITH_ICON_LEFT : CHIP_LABEL_PADDING.WITH_ICON_RIGHT;
1561
+ };
1562
+ const ChipIcon = ({ icon, size, sxIcon }) => (jsx(Box, { sx: {
1563
+ display: 'inline-flex',
1564
+ alignItems: 'center',
1565
+ justifyContent: 'center',
1566
+ borderRadius: '50%',
1567
+ padding: '2px',
1568
+ '& svg': {
1569
+ width: size,
1570
+ height: size,
1571
+ display: 'block',
1572
+ },
1573
+ ...sxIcon,
1574
+ }, children: icon }));
1575
+ const ChipComponent = ({ label, onAction, icon, disabled = false, clickable = true, sx, sxIcon, iconPosition = 'right', size = 'medium', }) => {
1576
+ const sizeConfig = CHIP_SIZE_CONFIG[size];
1577
+ const hasIcon = Boolean(icon);
1578
+ return (jsx(Chip, { disabled: disabled, clickable: clickable, onClick: onAction, label: jsxs(StackRowAlignCenter, { sx: { gap: '8px' }, children: [hasIcon && iconPosition === 'left' && jsx(ChipIcon, { icon: icon, size: sizeConfig.iconSize, sxIcon: sxIcon }), jsx(Box, { component: "span", children: label }), hasIcon && iconPosition === 'right' && jsx(ChipIcon, { icon: icon, size: sizeConfig.iconSize, sxIcon: sxIcon })] }), sx: {
1579
+ height: sizeConfig.height,
1580
+ fontSize: sizeConfig.fontSize,
1581
+ borderRadius: sizeConfig.borderRadius,
1582
+ cursor: clickable ? 'pointer' : 'default',
1583
+ backgroundColor: 'transparent',
1584
+ border: '1px solid #D1D5DB',
1585
+ '& .MuiChip-label': {
1586
+ padding: getLabelPadding(hasIcon, iconPosition),
1587
+ display: 'flex',
1588
+ alignItems: 'center',
1589
+ },
1590
+ '& .MuiChip-label svg': {
1591
+ flexShrink: 0,
1592
+ color: '#4B5563',
1593
+ },
1594
+ '&.Mui-disabled': {
1595
+ opacity: 0.5,
1596
+ color: '#9E9E9E',
1597
+ },
1598
+ ...sx,
1599
+ } }));
1600
+ };
1601
+
1602
+ const DateFieldComponent = ({ label = 'Label', placeholder = 'DD/MM/YYYY', value, disabled = false, error = false, success = false, errorMessage, successMessage, borderRadius = 6, helperText = '', onChange, locale = 'vi', format = 'DD/MM/YYYY', sx, disablePastDates = false, ...props }) => {
1603
+ // Convert string to Dayjs if needed
1604
+ const dayjsValue = value && typeof value === 'string' ? dayjs(value, format) : value instanceof dayjs ? value : null;
1605
+ const handleDateChange = (date) => {
1606
+ onChange?.(date);
1607
+ };
1608
+ // Disable past dates function
1609
+ const shouldDisableDate = (date) => {
1610
+ if (!disablePastDates)
1611
+ return false;
1612
+ return date.isBefore(dayjs(), 'day');
1613
+ };
1614
+ return (jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Typography, { sx: {
1615
+ display: 'block',
1616
+ ...TYPOGRAPHY.textFieldLabel,
1617
+ color: COLOR_GRAY[800],
1618
+ marginBottom: '4px',
1619
+ }, children: label })), jsx(LocalizationProvider, { dateAdapter: AdapterDayjs, adapterLocale: locale, children: jsx(DatePicker, { value: dayjsValue, onChange: handleDateChange, disabled: disabled, format: format, shouldDisableDate: shouldDisableDate, slotProps: {
1620
+ textField: {
1621
+ placeholder,
1622
+ error: error || false,
1623
+ helperText: error ? errorMessage : helperText,
1624
+ size: 'small',
1625
+ fullWidth: true,
1626
+ disabled: disabled,
1627
+ },
1628
+ openPickerButton: {
1629
+ size: 'small',
1630
+ },
1631
+ }, slots: {
1632
+ openPickerIcon: (props) => jsx(IconElement, { icon: "calendar_today", ...props }),
1633
+ }, sx: {
1634
+ width: '100%',
1635
+ '& .MuiPickersInputBase-root': {
1636
+ borderRadius: borderRadius === 'max' ? '100px' : `${borderRadius}px`,
1637
+ '& fieldset': { borderColor: COLOR_NEUTRAL[300] },
1638
+ '&:hover fieldset': { borderColor: COLOR_NEUTRAL[400] },
1639
+ '&.Mui-focused fieldset': { borderColor: COLOR_NEUTRAL[300], borderWidth: '2px' },
1640
+ '&.Mui-focused': {
1641
+ boxShadow: '0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px #FEE4E2',
1642
+ },
1643
+ '&.Mui-disabled': {
1644
+ backgroundColor: COLOR_NEUTRAL[100],
1645
+ '& fieldset': { borderColor: COLOR_NEUTRAL[200] },
1646
+ '& input': { color: COLOR_NEUTRAL[400], WebkitTextFillColor: COLOR_NEUTRAL[400] },
1647
+ },
1648
+ '&.Mui-error fieldset': { borderColor: COLOR_ERROR[500] },
1649
+ '&.Mui-error.Mui-focused fieldset': { borderColor: COLOR_ERROR[500], borderWidth: '2px' },
1650
+ '&.Mui-error.Mui-focused': {
1651
+ boxShadow: `0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px rgba(255, 66, 79, 0.15)`,
1652
+ },
1653
+ ...(success && {
1654
+ '&.Mui-focused': {
1655
+ boxShadow: `0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px ${COLOR_SUCCESS[100]}`,
1656
+ },
1657
+ }),
1658
+ },
1659
+ '& .MuiInputBase-input': {
1660
+ ...TYPOGRAPHY.text14Regular,
1661
+ padding: '12px 8px',
1662
+ color: COLOR_GRAY[900],
1663
+ '&::placeholder': { color: COLOR_NEUTRAL[400], opacity: 0.7 },
1664
+ },
1665
+ }, ...props }) }), success && !error && successMessage && (jsx(Typography, { sx: {
1666
+ ...TYPOGRAPHY.textFieldHelper,
1667
+ color: COLOR_SUCCESS[500],
1668
+ marginTop: '4px',
1669
+ }, children: successMessage }))] }));
1670
+ };
1671
+
1672
+ const DateRangePickerComponent = ({ label = 'Date Range', fromDate, toDate, disabled = false, error = false, success = false, errorMessage, successMessage, borderRadius = 6, helperText = '', onChange, locale = 'vi', format = 'DD/MM/YYYY', minDate, maxDate, sx, disablePastDates = false, ...props }) => {
1673
+ // Convert string to Dayjs if needed
1674
+ const dayjsFromDate = fromDate && typeof fromDate === 'string' ? dayjs(fromDate, format) : fromDate instanceof dayjs ? fromDate : null;
1675
+ const dayjsToDate = toDate && typeof toDate === 'string' ? dayjs(toDate, format) : toDate instanceof dayjs ? toDate : null;
1676
+ // State for picker
1677
+ const [pickerOpen, setPickerOpen] = useState(false);
1678
+ const [selectingPhase, setSelectingPhase] = useState('from');
1679
+ const inputRef = useRef(null);
1680
+ // Disable past dates function
1681
+ const shouldDisableDate = (date) => {
1682
+ if (!disablePastDates)
1683
+ return false;
1684
+ return date.isBefore(dayjs(), 'day');
1685
+ };
1686
+ const handleInputClick = () => {
1687
+ setPickerOpen(true);
1688
+ // Only reset to 'from' if both dates are empty (fresh start)
1689
+ if (!dayjsFromDate && !dayjsToDate) {
1690
+ setSelectingPhase('from');
1691
+ }
1692
+ };
1693
+ const handleDateChange = (date) => {
1694
+ if (selectingPhase === 'from') {
1695
+ onChange?.([date, dayjsToDate]);
1696
+ if (date) {
1697
+ // Auto switch to toDate selection
1698
+ setSelectingPhase('to');
1699
+ }
1700
+ }
1701
+ else {
1702
+ onChange?.([dayjsFromDate, date]);
1703
+ // Keep picker open for user to potentially change toDate
1704
+ }
1705
+ };
1706
+ return (jsx(LocalizationProvider, { dateAdapter: AdapterDayjs, adapterLocale: locale, children: jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Typography, { sx: {
1707
+ display: 'block',
1708
+ ...TYPOGRAPHY.textFieldLabel,
1709
+ color: COLOR_GRAY[800],
1710
+ marginBottom: '4px',
1711
+ }, children: label })), jsxs(Box, { ref: inputRef, onClick: !disabled ? handleInputClick : undefined, sx: {
1712
+ display: 'flex',
1713
+ alignItems: 'center',
1714
+ gap: '12px',
1715
+ padding: '12px 8px',
1716
+ borderRadius: borderRadius === 'max' ? '100px' : `${borderRadius}px`,
1717
+ border: `1px solid ${error ? COLOR_ERROR[500] : COLOR_NEUTRAL[300]}`,
1718
+ backgroundColor: disabled ? COLOR_NEUTRAL[100] : 'white',
1719
+ cursor: disabled ? 'default' : 'pointer',
1720
+ transition: 'all 0.2s ease',
1721
+ ...(disabled
1722
+ ? {}
1723
+ : {
1724
+ '&:hover': {
1725
+ borderColor: error ? COLOR_ERROR[500] : COLOR_NEUTRAL[400],
1726
+ },
1727
+ }),
1728
+ }, children: [jsxs(Typography, { sx: {
1729
+ flex: 1,
1730
+ ...TYPOGRAPHY.text14Regular,
1731
+ color: dayjsFromDate || dayjsToDate ? COLOR_GRAY[900] : COLOR_NEUTRAL[400],
1732
+ }, children: [dayjsFromDate ? dayjsFromDate.format(format) : format, " \u2192", ' ', dayjsToDate ? dayjsToDate.format(format) : format] }), jsx(Box, { sx: {
1733
+ display: 'flex',
1734
+ alignItems: 'center',
1735
+ justifyContent: 'center',
1736
+ width: '24px',
1737
+ height: '24px',
1738
+ color: COLOR_NEUTRAL[400],
1739
+ }, children: jsx(IconElement, { icon: "calendar_today" }) })] }), jsx(DatePicker, { open: pickerOpen, onOpen: () => setPickerOpen(true), onClose: () => setPickerOpen(false), value: selectingPhase === 'from' ? dayjsFromDate : dayjsToDate, onChange: handleDateChange, disabled: disabled, format: format, minDate: selectingPhase === 'from' ? minDate : dayjsFromDate || minDate, maxDate: selectingPhase === 'to' ? maxDate : dayjsToDate || maxDate, shouldDisableDate: shouldDisableDate, slotProps: {
1740
+ textField: {
1741
+ hidden: true,
1742
+ size: 'small',
1743
+ sx: {
1744
+ display: 'none',
1745
+ },
1746
+ },
1747
+ popper: {
1748
+ anchorEl: inputRef.current,
1749
+ placement: 'bottom-start',
1750
+ },
1751
+ } }), helperText && !error && !success && (jsx(Typography, { sx: {
1752
+ ...TYPOGRAPHY.textFieldHelper,
1753
+ color: COLOR_NEUTRAL[400],
1754
+ marginTop: '4px',
1755
+ }, children: helperText })), error && errorMessage && (jsx(Typography, { sx: {
1756
+ ...TYPOGRAPHY.textFieldHelper,
1757
+ color: COLOR_ERROR[500],
1758
+ marginTop: '4px',
1759
+ }, children: errorMessage })), success && !error && successMessage && (jsx(Typography, { sx: {
1760
+ ...TYPOGRAPHY.textFieldHelper,
1761
+ color: COLOR_SUCCESS[500],
1762
+ marginTop: '4px',
1763
+ }, children: successMessage }))] }) }));
1764
+ };
1765
+
1766
+ const DropdownFieldComponent = ({ label = '', placeholder = 'Select option', value = null, disabled = false, error = false, success = false, errorMessage, successMessage, borderRadius = 6, onChange, helperText = '', options = [], checkIconColor = COLOR_ACCENT[900], sx, }) => {
1767
+ const borderRadiusValue = borderRadius === 'max' ? '100px' : `${borderRadius}px`;
1768
+ const selectedOption = useMemo(() => options.find((opt) => opt.value === value), [options, value]);
1769
+ const getHelperText = useCallback(() => {
1770
+ if (error && errorMessage)
1771
+ return errorMessage;
1772
+ if (success && successMessage)
1773
+ return successMessage;
1774
+ if (helperText)
1775
+ return helperText;
1776
+ return '';
1777
+ }, [error, errorMessage, success, successMessage, helperText]);
1778
+ const getHelperTextColor = useCallback(() => {
1779
+ if (error)
1780
+ return COLOR_ERROR[500];
1781
+ if (success)
1782
+ return COLOR_SUCCESS[500];
1783
+ return COLOR_NEUTRAL[400];
1784
+ }, [error, success]);
1785
+ const getBorderColor = useCallback(() => {
1786
+ if (error)
1787
+ return COLOR_ERROR[500];
1788
+ if (success)
1789
+ return COLOR_SUCCESS[500];
1790
+ return COLOR_NEUTRAL[300];
1791
+ }, [error, success]);
1792
+ const selectSx = useMemo(() => ({
1793
+ '& .MuiOutlinedInput-root': {
1794
+ borderRadius: borderRadiusValue,
1795
+ backgroundColor: disabled ? COLOR_NEUTRAL[100] : 'white',
1796
+ transition: 'all 0.2s ease',
1797
+ '& fieldset': {
1798
+ borderColor: getBorderColor(),
1799
+ },
1800
+ '&:hover fieldset': {
1801
+ borderColor: disabled ? getBorderColor() : error ? COLOR_ERROR[500] : COLOR_NEUTRAL[400],
1802
+ },
1803
+ '&.Mui-focused fieldset': {
1804
+ borderColor: error ? COLOR_ERROR[500] : COLOR_NEUTRAL[400],
1805
+ borderWidth: '1.5px',
1806
+ },
1807
+ },
1808
+ '& .MuiOutlinedInput-input': {
1809
+ padding: '12px 14px',
1810
+ color: COLOR_GRAY[900],
1811
+ '&::placeholder': {
1812
+ color: COLOR_NEUTRAL[400],
1813
+ opacity: 1,
1814
+ },
1815
+ },
1816
+ }), [borderRadiusValue, disabled, error, getBorderColor]);
1817
+ return (jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Typography, { sx: {
1818
+ display: 'block',
1819
+ ...TYPOGRAPHY.textFieldLabel,
1820
+ color: COLOR_GRAY[800],
1821
+ marginBottom: '4px',
1822
+ }, children: label })), jsx(Select, { fullWidth: true, value: value || '', onChange: (e) => {
1823
+ const selectedValue = e.target.value;
1824
+ const matchedOption = options.find((opt) => String(opt.value) === String(selectedValue));
1825
+ if (matchedOption) {
1826
+ onChange?.(matchedOption.value);
1827
+ }
1828
+ }, disabled: disabled, displayEmpty: true, MenuProps: {
1829
+ disableScrollLock: true,
1830
+ }, renderValue: () => {
1831
+ if (!value) {
1832
+ return (jsx(Box, { sx: { color: COLOR_NEUTRAL[400], display: 'flex', alignItems: 'center', gap: '8px' }, children: placeholder }));
1833
+ }
1834
+ return (jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: '8px' }, children: [selectedOption?.statusIndicator && (jsx(Box, { sx: {
1835
+ width: '8px',
1836
+ height: '8px',
1837
+ borderRadius: '50%',
1838
+ backgroundColor: '#4CAF50',
1839
+ } })), selectedOption?.avatar && (jsx(Avatar, { src: selectedOption.avatar, sx: {
1840
+ width: '24px',
1841
+ height: '24px',
1842
+ fontSize: '12px',
1843
+ } })), selectedOption?.icon && jsx(IconElement, { icon: selectedOption.icon }), jsx(Typography, { sx: { color: COLOR_GRAY[900], ...TYPOGRAPHY.text14Regular }, children: selectedOption?.label })] }));
1844
+ }, sx: selectSx, children: options.map((option) => (jsx(MenuItem, { value: option.value, children: jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: '8px', width: '100%' }, children: [option.statusIndicator && (jsx(Box, { sx: {
1845
+ width: '8px',
1846
+ height: '8px',
1847
+ borderRadius: '50%',
1848
+ backgroundColor: '#4CAF50',
1849
+ } })), option.avatar && (jsx(Avatar, { src: option.avatar, sx: {
1850
+ width: '24px',
1851
+ height: '24px',
1852
+ fontSize: '12px',
1853
+ } })), option.icon && jsx(IconElement, { icon: option.icon }), jsx(Typography, { sx: { color: COLOR_GRAY[900], ...TYPOGRAPHY.text14Regular }, children: option.label }), value === option.value && (jsx(Box, { sx: { marginLeft: 'auto', display: 'flex', alignItems: 'center' }, children: jsx(IconElement, { icon: "check", sx: { color: checkIconColor } }) }))] }) }, option.value))) }), getHelperText() && (jsx(Box, { sx: {
1854
+ color: getHelperTextColor(),
1855
+ marginTop: '4px',
1856
+ ...TYPOGRAPHY.textFieldHelper,
1857
+ }, children: getHelperText() }))] }));
1858
+ };
1859
+
1860
+ const BACKGROUND_COLOR_GRID = '#FFFFFF';
1861
+ const COLOR_CONTENT_GRID = '#27272A';
1862
+ const BORDER_RADIUS_GRID_CONTAINER = 8;
1863
+ const BORDER_RADIUS_GRID = 4;
1864
+ const GridComponent = ({ sx = {}, sxContainer = {}, content = 'Grids', children, }) => {
1865
+ return (jsxs(Stack, { sx: {
1866
+ bgcolor: BACKGROUND_COLOR_GRID,
1867
+ p: BORDER_RADIUS_GRID_CONTAINER,
1868
+ borderRadius: BORDER_RADIUS_GRID_CONTAINER,
1869
+ gap: BORDER_RADIUS_GRID,
1870
+ ...sx,
1871
+ }, children: [content && (jsx(Typography, { sx: {
1872
+ color: COLOR_CONTENT_GRID,
1873
+ ...TYPOGRAPHY_STYLES.lg.bold,
1874
+ }, children: content })), jsx(Container, { maxWidth: false, sx: {
1875
+ bgcolor: BACKGROUND_COLOR_GRID,
1876
+ borderRadius: BORDER_RADIUS_GRID,
1877
+ minHeight: 400,
1878
+ boxShadow: '0 0 8px -4px rgba(16, 24, 40, 0.3)',
1879
+ ...sxContainer,
1880
+ }, children: children })] }));
1881
+ };
1882
+
1883
+ var BorderRadius;
1884
+ (function (BorderRadius) {
1885
+ BorderRadius["SQUARE"] = "4px";
1886
+ BorderRadius["CIRCLE"] = "20px";
1887
+ })(BorderRadius || (BorderRadius = {}));
1888
+ var ShapeType;
1889
+ (function (ShapeType) {
1890
+ ShapeType["SQUARE"] = "square";
1891
+ ShapeType["CIRCLE"] = "circle";
1892
+ })(ShapeType || (ShapeType = {}));
1893
+ var Orientation;
1894
+ (function (Orientation) {
1895
+ Orientation["HORIZONTAL"] = "horizontal";
1896
+ Orientation["VERTICAL"] = "vertical";
1897
+ })(Orientation || (Orientation = {}));
1898
+ var ButtonSize;
1899
+ (function (ButtonSize) {
1900
+ ButtonSize[ButtonSize["SMALL"] = 32] = "SMALL";
1901
+ ButtonSize[ButtonSize["MEDIUM"] = 40] = "MEDIUM";
1902
+ })(ButtonSize || (ButtonSize = {}));
1903
+ const Colors = {
1904
+ BORDER_COLOR_BUTTON: '#07554B',
1905
+ BORDER_COLOR_DISABLE: '#0000000D',
1906
+ HOVER_BG_COLOR: 'rgba(7, 85, 75, 0.04)',
1907
+ BACKGROUND_COLOR: '#FFFFFF',
1908
+ TEXT_COLOR_READONLY: '#27272A',
1909
+ };
1910
+ const FONT_SIZE_LOADING = {
1911
+ large: 40,
1912
+ };
1913
+ const BORDER_TEXT_FIELD_LOADING = 20;
1914
+
1915
+ const InputStepperSkeleton = ({ orientation, buttonShape }) => {
1916
+ return (jsxs(Box, { display: "inline-flex", flexDirection: orientation === Orientation.HORIZONTAL ? 'row' : 'column', alignItems: "center", gap: 1, children: [jsx(Skeleton, { variant: buttonShape === ShapeType.CIRCLE ? 'circular' : 'rectangular', width: FONT_SIZE_LOADING.large, height: FONT_SIZE_LOADING.large, sx: {
1917
+ borderRadius: buttonShape === ShapeType.CIRCLE ? BorderRadius.CIRCLE : BorderRadius.SQUARE,
1918
+ maxHeight: FONT_SIZE_LOADING.large,
1919
+ } }), jsx(Skeleton, { width: FONT_SIZE_LOADING.large, sx: {
1920
+ borderRadius: `${BORDER_TEXT_FIELD_LOADING}px`,
1921
+ } }), jsx(Skeleton, { variant: buttonShape === ShapeType.CIRCLE ? 'circular' : 'rectangular', width: FONT_SIZE_LOADING.large, height: FONT_SIZE_LOADING.large, sx: {
1922
+ borderRadius: buttonShape === ShapeType.CIRCLE ? BorderRadius.CIRCLE : BorderRadius.SQUARE,
1923
+ maxHeight: FONT_SIZE_LOADING.large,
1924
+ } })] }));
1925
+ };
1926
+
1927
+ const InputStepperComponent = ({ value: controlledValue, onChange, min, max, step = 1, disabled = false, readOnly = false, orientation = Orientation.HORIZONTAL, loading = false, sx = {}, sxTextField = {}, // style cho input chứa value
1928
+ sxButton = {}, // style cho 2 button
1929
+ buttonShape = ShapeType.SQUARE, buttonColor, textFieldShape = ShapeType.SQUARE, decrementIcon = jsx(RemoveIcon, {}), incrementIcon = jsx(AddIcon, {}), }) => {
1930
+ const [internalValue, setInternalValue] = useState(controlledValue ?? min ?? 0);
1931
+ const value = controlledValue !== undefined ? controlledValue : internalValue;
1932
+ const updateValue = (newValue) => {
1933
+ let finalValue = newValue;
1934
+ if (min !== undefined && newValue < min)
1935
+ finalValue = min;
1936
+ if (max !== undefined && newValue > max)
1937
+ finalValue = max;
1938
+ if (controlledValue === undefined) {
1939
+ setInternalValue(finalValue);
1940
+ }
1941
+ onChange?.(finalValue);
1942
+ };
1943
+ const handleIncrement = () => {
1944
+ updateValue(Number(value) + step);
1945
+ };
1946
+ const handleDecrement = () => {
1947
+ updateValue(Number(value) - step);
1948
+ };
1949
+ const handleInputChange = (event) => {
1950
+ if (!readOnly) {
1951
+ const newValue = event.target.value === '' ? min || 0 : Number(event.target.value);
1952
+ if (!isNaN(newValue)) {
1953
+ updateValue(newValue);
1954
+ }
1955
+ }
1956
+ };
1957
+ const isDecrementDisabled = disabled || (min !== undefined && Number(value) <= min);
1958
+ const isIncrementDisabled = disabled || (max !== undefined && Number(value) >= max);
1959
+ const buttonSize = ButtonSize.MEDIUM;
1960
+ if (loading) {
1961
+ return jsx(InputStepperSkeleton, { orientation: orientation, buttonShape: buttonShape });
1962
+ }
1963
+ return (jsxs(Box, { display: "inline-flex", flexDirection: orientation === 'horizontal' ? 'row' : 'column', alignItems: "center", gap: PADDING_GAP_ITEM, sx: {
1964
+ opacity: disabled ? 0.5 : 1,
1965
+ pointerEvents: disabled ? 'none' : 'auto',
1966
+ ...sx,
1967
+ }, children: [jsx(IconButton, { onClick: handleDecrement, disabled: isDecrementDisabled, sx: {
1968
+ borderRadius: buttonShape === 'circle' ? BorderRadius.CIRCLE : BorderRadius.SQUARE,
1969
+ width: buttonSize,
1970
+ height: buttonSize,
1971
+ padding: PADDING_GAP_ITEM,
1972
+ border: isDecrementDisabled
1973
+ ? `1px solid ${Colors.BORDER_COLOR_DISABLE}`
1974
+ : `1px solid ${Colors.BORDER_COLOR_BUTTON}`,
1975
+ backgroundColor: Colors.BACKGROUND_COLOR,
1976
+ color: buttonColor || Colors.BORDER_COLOR_BUTTON,
1977
+ '&:hover': {
1978
+ backgroundColor: Colors.HOVER_BG_COLOR,
1979
+ },
1980
+ ...(isDecrementDisabled ? {} : sxButton),
1981
+ }, children: decrementIcon }), jsx(TextField, { value: value, onChange: handleInputChange, disabled: disabled, inputProps: {
1982
+ min,
1983
+ max,
1984
+ step,
1985
+ readOnly,
1986
+ }, type: "number", sx: {
1987
+ minWidth: buttonSize,
1988
+ width: sxTextField?.width || buttonSize,
1989
+ minHeight: buttonSize,
1990
+ height: sxTextField?.height || buttonSize,
1991
+ overflow: 'hidden',
1992
+ borderRadius: textFieldShape === 'circle' ? BorderRadius.CIRCLE : BorderRadius.SQUARE,
1993
+ color: readOnly ? Colors.TEXT_COLOR_READONLY : '',
1994
+ backgroundColor: readOnly ? 'transparent !important' : sxTextField?.backgroundColor,
1995
+ '& .MuiOutlinedInput-root': {
1996
+ width: '100%',
1997
+ height: '100%',
1998
+ borderRadius: 'inherit',
1999
+ '& fieldset': {
2000
+ borderColor: readOnly || disabled ? 'transparent' : sxTextField?.borderColor || Colors.BORDER_COLOR_BUTTON,
2001
+ borderWidth: readOnly || disabled ? 0 : 1,
2002
+ borderRadius: textFieldShape === 'circle' ? BorderRadius.CIRCLE : BorderRadius.SQUARE,
2003
+ },
2004
+ '&:hover fieldset': readOnly || disabled
2005
+ ? {}
2006
+ : {
2007
+ borderColor: sxTextField?.borderColorHover || Colors.BORDER_COLOR_BUTTON,
2008
+ },
2009
+ '&.Mui-focused fieldset': readOnly
2010
+ ? {
2011
+ borderColor: 'transparent',
2012
+ borderWidth: 0,
2013
+ }
2014
+ : {
2015
+ borderColor: sxTextField?.borderColorFocused || Colors.BORDER_COLOR_BUTTON,
2016
+ borderWidth: 1,
2017
+ },
2018
+ '&.Mui-disabled fieldset': {
2019
+ borderColor: Colors.BORDER_COLOR_DISABLE,
2020
+ backgroundColor: readOnly ? 'transparent' : Colors.BORDER_COLOR_DISABLE,
2021
+ },
2022
+ },
2023
+ '& input[type=number]::-webkit-outer-spin-button, & input[type=number]::-webkit-inner-spin-button': {
2024
+ WebkitAppearance: 'none',
2025
+ margin: 0,
2026
+ },
2027
+ '& input[type=number]': {
2028
+ MozAppearance: 'textfield',
2029
+ },
2030
+ '& .MuiInputBase-input': {
2031
+ textAlign: sxTextField?.textAlign || 'center',
2032
+ padding: sxTextField?.padding || '4px 8px',
2033
+ fontSize: readOnly ? '16px' : sxTextField?.fontSize || '1rem',
2034
+ cursor: readOnly ? 'not-allowed' : 'text',
2035
+ borderRadius: 'inherit',
2036
+ backgroundColor: readOnly ? 'transparent' : sxTextField?.backgroundColor || 'transparent',
2037
+ color: readOnly ? Colors.TEXT_COLOR_READONLY : sxTextField?.color || 'inherit',
2038
+ fontWeight: sxTextField?.fontWeight || (readOnly ? 700 : 'normal'),
2039
+ },
2040
+ } }), jsx(IconButton, { onClick: handleIncrement, disabled: isIncrementDisabled, sx: {
2041
+ borderRadius: buttonShape === 'circle' ? BorderRadius.CIRCLE : BorderRadius.SQUARE,
2042
+ width: buttonSize,
2043
+ height: buttonSize,
2044
+ padding: PADDING_GAP_ITEM,
2045
+ border: isIncrementDisabled
2046
+ ? `1px solid ${Colors.BORDER_COLOR_DISABLE}`
2047
+ : `1px solid ${Colors.BORDER_COLOR_BUTTON}`,
2048
+ backgroundColor: Colors.BACKGROUND_COLOR,
2049
+ color: buttonColor || Colors.BORDER_COLOR_BUTTON,
2050
+ '&:hover': {
2051
+ backgroundColor: Colors.HOVER_BG_COLOR,
2052
+ },
2053
+ ...(isIncrementDisabled ? {} : sxButton),
2054
+ }, children: incrementIcon })] }));
2055
+ };
2056
+
2057
+ const LinkInternalElement = ({ content, onClick, sx = {} }) => {
2058
+ return (jsx(Typography, { onClick: onClick, sx: {
2059
+ color: 'inherit',
2060
+ textDecorationColor: 'inherit',
2061
+ cursor: 'pointer',
2062
+ '&:hover': {
2063
+ textDecoration: 'underline',
2064
+ },
2065
+ ...sx,
2066
+ }, children: content }));
2067
+ };
2068
+
2069
+ const LinkElement = ({ onClick, sx = {}, target = '_self', ...rest }) => {
2070
+ return (jsx(Link, { target: target, rel: "noopener", sx: { textDecoration: 'none', color: 'unset', ...sx }, onClick: (event) => {
2071
+ if (onClick) {
2072
+ event.preventDefault();
2073
+ onClick();
2074
+ }
2075
+ }, ...rest }));
2076
+ };
2077
+
2078
+ const StyledTextField$3 = styled(MuiTextField)(({ theme }) => {
2079
+ return {
2080
+ '& .MuiOutlinedInput-root': {
2081
+ '& fieldset': { borderColor: COLOR_NEUTRAL[300] },
2082
+ '&:hover fieldset': { borderColor: COLOR_NEUTRAL[400] },
2083
+ '&.Mui-focused fieldset': { borderColor: COLOR_NEUTRAL[300], borderWidth: '2px' },
2084
+ '&.Mui-focused': {
2085
+ boxShadow: '0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px #FEE4E2',
2086
+ },
2087
+ '&.Mui-disabled': {
2088
+ backgroundColor: COLOR_NEUTRAL[100],
2089
+ '& fieldset': { borderColor: COLOR_NEUTRAL[200] },
2090
+ '& input': { color: COLOR_NEUTRAL[400], WebkitTextFillColor: COLOR_NEUTRAL[400] },
2091
+ },
2092
+ '&.Mui-error fieldset': { borderColor: COLOR_ERROR[600], borderWidth: '1px' },
2093
+ '&.Mui-error:hover fieldset': { borderColor: COLOR_ERROR[600] },
2094
+ '&.Mui-error.Mui-focused fieldset': { borderColor: COLOR_ERROR[600], borderWidth: '2px' },
2095
+ '&.Mui-error.Mui-focused': {
2096
+ boxShadow: '0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px rgba(255, 66, 79, 0.15)',
2097
+ },
2098
+ },
2099
+ '& .MuiInputBase-input': {
2100
+ ...TYPOGRAPHY.text14Regular,
2101
+ padding: '12px 8px',
2102
+ color: COLOR_GRAY[900],
2103
+ '&::placeholder': { color: COLOR_NEUTRAL[400], opacity: 0.7 },
2104
+ '&:focus': { outline: 'none' },
2105
+ },
2106
+ '& .MuiInputLabel-root': {
2107
+ ...TYPOGRAPHY.textFieldLabel,
2108
+ color: COLOR_GRAY[800],
2109
+ transform: 'translate(14px, -9px) scale(0.75)',
2110
+ '&.Mui-focused': { color: COLOR_NEUTRAL[500] },
2111
+ '&.Mui-error': { color: COLOR_ERROR[600] },
2112
+ },
2113
+ '& .MuiFormHelperText-root': {
2114
+ ...TYPOGRAPHY.textFieldHelper,
2115
+ margin: '4px 0 0 0',
2116
+ '&.Mui-error': { color: COLOR_ERROR[600] },
2117
+ },
2118
+ };
2119
+ });
2120
+ const LinkFieldComponent = ({ label = 'Website', placeholder = 'www.untitledui.com', value, disabled = false, error = false, success = false, errorMessage, successMessage, borderRadius = 6, helperText = 'This is a hint text to help user.', onChange, protocol = 'http://', iconAfter, sx, ...props }) => {
2121
+ const [validationError, setValidationError] = useState(false);
2122
+ const isValidLink = (url) => {
2123
+ if (!url)
2124
+ return true; // Empty is valid (optional field)
2125
+ try {
2126
+ const urlToTest = url.includes('://') ? url : `${protocol}${url}`;
2127
+ new URL(urlToTest);
2128
+ // Kiểm tra domain phải có dấu chấm (ít nhất là có TLD)
2129
+ const hostname = new URL(urlToTest).hostname;
2130
+ if (!hostname || !hostname.includes('.')) {
2131
+ return false;
2132
+ }
2133
+ return true;
2134
+ }
2135
+ catch {
2136
+ return false;
2137
+ }
2138
+ };
2139
+ const handleBlur = (event) => {
2140
+ const inputValue = event.target.value;
2141
+ if (inputValue && !isValidLink(inputValue)) {
2142
+ setValidationError(true);
2143
+ }
2144
+ else {
2145
+ setValidationError(false);
2146
+ }
2147
+ };
2148
+ return (jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Typography, { sx: {
2149
+ display: 'block',
2150
+ ...TYPOGRAPHY.textFieldLabel,
2151
+ color: COLOR_GRAY[800],
2152
+ marginBottom: '4px',
2153
+ }, children: label })), jsx(StyledTextField$3, { placeholder: placeholder, value: value, disabled: disabled, error: error || validationError, helperText: error || validationError ? (error ? errorMessage : 'đây không phải link') : '', size: "small", fullWidth: true, onChange: onChange, onBlur: handleBlur, InputProps: {
2154
+ startAdornment: (jsx(InputAdornment, { position: "start", children: jsx(Typography, { sx: { color: COLOR_NEUTRAL[300], ...TYPOGRAPHY.text14Regular }, children: protocol }) })),
2155
+ endAdornment: (success || error || validationError) && (jsx(InputAdornment, { position: "end", children: iconAfter ? (iconAfter) : (jsx(IconElement, { icon: error || validationError ? 'info' : 'check_circle', sx: { color: error || validationError ? COLOR_ERROR[500] : COLOR_SUCCESS[500] } })) })),
2156
+ }, sx: {
2157
+ '& .MuiOutlinedInput-root': {
2158
+ borderRadius: borderRadius === 'max' ? '100px' : `${borderRadius}px`,
2159
+ ...(success && {
2160
+ '&.Mui-focused': {
2161
+ boxShadow: `0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px ${COLOR_SUCCESS[100]}`,
2162
+ },
2163
+ }),
2164
+ },
2165
+ } }), success && !error && successMessage && (jsx(Typography, { sx: {
2166
+ ...TYPOGRAPHY.textFieldHelper,
2167
+ color: COLOR_SUCCESS[500],
2168
+ marginTop: '4px',
2169
+ }, children: successMessage }))] }));
2170
+ };
2171
+
2172
+ const MODAL_ICON_COLORS = {
2173
+ check_circle: '#10B981',
2174
+ warning: '#F59E0B',
2175
+ error: '#EF4444',
2176
+ info: '#3B82F6',
2177
+ };
2178
+ const ModalTitle = ({ content }) => {
2179
+ return jsx(Typography, { sx: { ...TYPOGRAPHY_STYLES.textLg.semiBold, color: '#101828' }, children: content });
2180
+ };
2181
+ const ModalDescription = ({ content }) => {
2182
+ return (jsx(Typography, { sx: {
2183
+ ...TYPOGRAPHY_STYLES.textSm.regular,
2184
+ color: '#667085',
2185
+ }, children: content }));
2186
+ };
2187
+ const ModalIcon = ({ type, size = 48, }) => {
2188
+ return (jsx(Box, { sx: {
2189
+ width: size,
2190
+ height: size,
2191
+ borderRadius: '28px',
2192
+ bgcolor: `${MODAL_ICON_COLORS[type]}20`,
2193
+ display: 'flex',
2194
+ alignItems: 'center',
2195
+ justifyContent: 'center',
2196
+ }, children: jsx(IconElement, { icon: type, sx: {
2197
+ fontSize: size * 0.6,
2198
+ color: MODAL_ICON_COLORS[type],
2199
+ flex: 1,
2200
+ } }) }));
2201
+ };
2202
+ const DialogWrapper = ({ isForm = false, children }) => {
2203
+ return isForm ? jsx(Form, { noValidate: true, children: children }) : jsx(React.Fragment, { children: children });
2204
+ };
2205
+
2206
+ const ModalComponent = ({ open, isForm = false, onClose, icon, avatars, title, nodeDescription, nodeContent, buttonLeft, buttonCenter, buttonRight, nodeBottomLeft, align = 'flex-start', direction = 'column', sx, sxContent, sxBottom, }) => {
2207
+ const hasActions = buttonLeft || buttonCenter || buttonRight || nodeBottomLeft;
2208
+ return (jsx(Dialog, { open: open, disableScrollLock: true, onClose: onClose, maxWidth: false, PaperProps: {
2209
+ sx: {
2210
+ borderRadius: BORDER_RADIUS_ELEMENT_WRAPPER,
2211
+ p: `calc(${PADDING_GAP_LAYOUT} + 8px)`,
2212
+ minWidth: 350,
2213
+ width: 'auto',
2214
+ ...sx,
2215
+ },
2216
+ }, children: jsx(DialogWrapper, { isForm: isForm, children: jsx(DialogContent, { sx: { p: 0, ...sxContent }, children: jsxs(Stack, { sx: { gap: 0, alignItems: 'center' }, children: [jsxs(Stack, { direction: direction, sx: {
2217
+ justifyContent: direction === 'row' ? 'flex-start' : align,
2218
+ gap: PADDING_GAP_LAYOUT,
2219
+ alignItems: direction === 'row' ? (nodeDescription ? 'flex-start' : 'center') : align,
2220
+ width: '100%',
2221
+ }, children: [icon && jsx(ModalIcon, { type: icon }), avatars && jsx(AvatarGroupComponent, { avatars: avatars }), (title || nodeDescription) && (jsxs(Stack, { sx: {
2222
+ gap: GAP_ICON_CONTENT_BY_SIZE.medium,
2223
+ alignItems: direction === 'row' ? 'flex-start' : align,
2224
+ width: '100%',
2225
+ }, children: [title && jsx(ModalTitle, { content: title }), nodeDescription] }))] }), nodeContent && jsx(Box, { sx: { width: '100%' }, children: nodeContent }), hasActions && (jsx(DialogActions, { sx: {
2226
+ width: '100%',
2227
+ mt: `calc(${PADDING_GAP_LAYOUT} + 8px)`,
2228
+ gap: GAP_ICON_CONTENT_BY_SIZE.large,
2229
+ ...sxBottom,
2230
+ }, children: jsxs(StackRowAlignCenter, { sx: { width: '100%' }, children: [nodeBottomLeft && jsx(Box, { sx: { width: '100%' }, children: nodeBottomLeft }), (buttonLeft || buttonCenter || buttonRight) && (jsxs(StackRow, { sx: { width: '100%', gap: PADDING_GAP_LAYOUT }, children: [buttonLeft && (jsx(Box, { sx: { flex: 1 }, children: jsx(ButtonComponent, { ...buttonLeft, fullWidth: true }) })), buttonCenter && (jsx(Box, { sx: { flex: 1 }, children: jsx(ButtonComponent, { ...buttonCenter, fullWidth: true }) })), buttonRight && (jsx(Box, { sx: { flex: 1 }, children: jsx(ButtonComponent, { ...buttonRight, fullWidth: true }) }))] }))] }) }))] }) }) }) }));
2231
+ };
2232
+
2233
+ const ModalCardComponent = ({ open, isForm = false, onClose, items, nodeContent, buttonLeft, buttonCenter, buttonRight, nodeBottomLeft, sx, sxContent, sxBottom, }) => {
2234
+ const itemsArray = Array.isArray(items) ? items : [items];
2235
+ const showSlider = itemsArray.length > 1;
2236
+ const hasActions = buttonLeft || buttonCenter || buttonRight || nodeBottomLeft;
2237
+ const sliderSettings = {
2238
+ dots: true,
2239
+ infinite: true,
2240
+ speed: 500,
2241
+ slidesToShow: 1,
2242
+ slidesToScroll: 1,
2243
+ arrows: false,
2244
+ };
2245
+ const renderCard = (item) => (jsxs(Stack, { sx: { gap: '20px', alignItems: 'center', textAlign: 'center' }, children: [jsx(ImageElement, { url: item?.image, sx: {
2246
+ borderRadius: BORDER_RADIUS_ELEMENT_MIDDLE,
2247
+ width: '100%',
2248
+ aspectRatio: 352 / 200,
2249
+ objectFit: 'cover',
2250
+ height: 'auto',
2251
+ } }), jsxs(Stack, { sx: { gap: 1 }, children: [jsx(ModalTitle, { content: item?.title }), jsx(ModalDescription, { content: item?.description })] })] }));
2252
+ return (jsx(Dialog, { open: open, onClose: onClose, PaperProps: {
2253
+ sx: {
2254
+ borderRadius: BORDER_RADIUS_ELEMENT_WRAPPER,
2255
+ p: `calc(${PADDING_GAP_LAYOUT} + 8px)`,
2256
+ minWidth: 350,
2257
+ width: 'auto',
2258
+ ...sx,
2259
+ },
2260
+ }, children: jsxs(DialogWrapper, { isForm: isForm, children: [jsx(DialogContent, { sx: { p: 0, ...sxContent }, children: jsxs(Stack, { sx: { gap: `calc(${PADDING_GAP_LAYOUT} + 8px)` }, children: [showSlider ? (jsx(Box, { sx: {
2261
+ '& .slick-slider': {
2262
+ position: 'relative',
2263
+ paddingBottom: '40px',
2264
+ },
2265
+ '& .slick-dots': {
2266
+ bottom: '0px',
2267
+ position: 'absolute',
2268
+ },
2269
+ '& .slick-list': {
2270
+ overflow: 'hidden',
2271
+ },
2272
+ }, children: jsx(Slider, { ...sliderSettings, children: itemsArray.map((item, index) => (jsx("div", { children: renderCard(item) }, index))) }) })) : (renderCard(itemsArray[0])), nodeContent && jsx(Box, { sx: { width: '100%' }, children: nodeContent })] }) }), hasActions && (jsx(DialogActions, { sx: {
2273
+ width: '100%',
2274
+ mt: `calc(${PADDING_GAP_LAYOUT} + 8px)`,
2275
+ gap: GAP_ICON_CONTENT_BY_SIZE.large,
2276
+ ...sxBottom,
2277
+ }, children: jsxs(StackRowAlignCenter, { sx: { width: '100%' }, children: [nodeBottomLeft && jsx(Box, { sx: { width: '100%' }, children: nodeBottomLeft }), (buttonLeft || buttonCenter || buttonRight) && (jsxs(StackRow, { sx: { width: '100%', gap: PADDING_GAP_LAYOUT }, children: [buttonLeft && (jsx(Box, { sx: { flex: 1 }, children: jsx(ButtonComponent, { ...buttonLeft, fullWidth: true }) })), buttonCenter && (jsx(Box, { sx: { flex: 1 }, children: jsx(ButtonComponent, { ...buttonCenter, fullWidth: true }) })), buttonRight && (jsx(Box, { sx: { flex: 1 }, children: jsx(ButtonComponent, { ...buttonRight, fullWidth: true }) }))] }))] }) }))] }) }));
2278
+ };
2279
+
2280
+ const CURRENCIES = ['USD', 'EUR', 'GBP', 'JPY', 'AUD', 'CAD', 'CHF', 'CNY', 'VND', 'INR'];
2281
+ // Format number with thousand separators
2282
+ const formatMoneyDisplay = (value) => {
2283
+ if (!value)
2284
+ return '';
2285
+ const numericOnly = value.replace(/\D/g, '');
2286
+ return numericOnly.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
2287
+ };
2288
+ const StyledTextField$2 = styled(MuiTextField)(({ theme }) => {
2289
+ return {
2290
+ '& .MuiOutlinedInput-root': {
2291
+ '& fieldset': { borderColor: COLOR_NEUTRAL[300] },
2292
+ '&:hover fieldset': { borderColor: COLOR_NEUTRAL[400] },
2293
+ '&.Mui-focused fieldset': { borderColor: COLOR_NEUTRAL[300], borderWidth: '2px' },
2294
+ '&.Mui-focused': {
2295
+ boxShadow: '0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px #FEE4E2',
2296
+ },
2297
+ '&.Mui-disabled': {
2298
+ backgroundColor: COLOR_NEUTRAL[100],
2299
+ '& fieldset': { borderColor: COLOR_NEUTRAL[200] },
2300
+ '& input': { color: COLOR_NEUTRAL[400], WebkitTextFillColor: COLOR_NEUTRAL[400] },
2301
+ },
2302
+ '&.Mui-error fieldset': { borderColor: COLOR_ERROR[600], borderWidth: '1px' },
2303
+ '&.Mui-error:hover fieldset': { borderColor: COLOR_ERROR[600] },
2304
+ '&.Mui-error.Mui-focused fieldset': { borderColor: COLOR_ERROR[600], borderWidth: '2px' },
2305
+ '&.Mui-error.Mui-focused': {
2306
+ boxShadow: '0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px rgba(255, 66, 79, 0.15)',
2307
+ },
2308
+ },
2309
+ '& .MuiInputBase-input': {
2310
+ ...TYPOGRAPHY.text14Regular,
2311
+ padding: '12px 8px',
2312
+ color: COLOR_GRAY[900],
2313
+ '&::placeholder': { color: COLOR_NEUTRAL[400], opacity: 0.7 },
2314
+ '&:focus': { outline: 'none' },
2315
+ },
2316
+ '& .MuiInputLabel-root': {
2317
+ ...TYPOGRAPHY.textFieldLabel,
2318
+ color: COLOR_GRAY[800],
2319
+ transform: 'translate(14px, -9px) scale(0.75)',
2320
+ '&.Mui-focused': { color: COLOR_NEUTRAL[500] },
2321
+ '&.Mui-error': { color: COLOR_ERROR[600] },
2322
+ },
2323
+ '& .MuiFormHelperText-root': {
2324
+ ...TYPOGRAPHY.textFieldHelper,
2325
+ margin: '4px 0 0 0',
2326
+ '&.Mui-error': { color: COLOR_ERROR[600] },
2327
+ },
2328
+ };
2329
+ });
2330
+ const MoneyFieldComponent = ({ label = 'Sale amount', placeholder = '1,000.00', value, disabled = false, error = false, success = false, errorMessage, successMessage, borderRadius = 6, helperText = 'This is a hint text to help user.', onChange, currency = 'USD', onCurrencyChange, iconBefore, optionCurrencies = CURRENCIES, sx, ...props }) => {
2331
+ const [selectedCurrency, setSelectedCurrency] = useState(currency);
2332
+ const handleCurrencyChange = (e) => {
2333
+ const newCurrency = e.target.value;
2334
+ setSelectedCurrency(newCurrency);
2335
+ onCurrencyChange?.(newCurrency);
2336
+ };
2337
+ const handleMoneyChange = (e) => {
2338
+ const rawValue = e.target.value.replace(/,/g, '');
2339
+ onChange?.({ ...e, target: { ...e.target, value: rawValue } });
2340
+ };
2341
+ return (jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Typography, { sx: {
2342
+ display: 'block',
2343
+ ...TYPOGRAPHY.textFieldLabel,
2344
+ color: COLOR_GRAY[800],
2345
+ marginBottom: '4px',
2346
+ }, children: label })), jsx(StyledTextField$2, { placeholder: placeholder, value: formatMoneyDisplay(value), disabled: disabled, error: error, helperText: error ? errorMessage : helperText, size: "small", fullWidth: true, onChange: handleMoneyChange, InputProps: {
2347
+ startAdornment: (jsx(InputAdornment, { position: "start", children: iconBefore ? iconBefore : jsx(AttachMoneyIcon, { sx: { fontSize: '18px', color: COLOR_GRAY[400], mr: 0.5 } }) })),
2348
+ endAdornment: (jsx(InputAdornment, { position: "end", children: jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1 }, children: [(success || error) && (jsx(IconElement, { icon: error ? 'info' : 'check_circle', sx: { color: error ? COLOR_ERROR[500] : COLOR_SUCCESS[500] } })), jsx(Select, { value: selectedCurrency, onChange: handleCurrencyChange, disabled: disabled, variant: "standard", sx: {
2349
+ border: 'none',
2350
+ outline: 'none',
2351
+ '& .MuiSelect-standard': { border: 'none' },
2352
+ '&.MuiInput-underline:before': { borderBottom: 'none' },
2353
+ '&.MuiInput-underline:hover:before': { borderBottom: 'none' },
2354
+ '&.MuiInput-underline:after': { borderBottom: 'none' },
2355
+ minWidth: '70px',
2356
+ fontSize: '14px',
2357
+ color: COLOR_GRAY[500],
2358
+ }, children: optionCurrencies.map((curr) => (jsx(MenuItem, { value: curr, children: curr }, curr))) })] }) })),
2359
+ }, sx: {
2360
+ '& .MuiOutlinedInput-root': {
2361
+ borderRadius: borderRadius === 'max' ? '100px' : `${borderRadius}px`,
2362
+ ...(success && {
2363
+ '&.Mui-focused': {
2364
+ boxShadow: `0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px ${COLOR_SUCCESS[100]}`,
2365
+ },
2366
+ }),
2367
+ },
2368
+ } }), success && !error && successMessage && (jsx(Typography, { sx: {
2369
+ ...TYPOGRAPHY.textFieldHelper,
2370
+ color: COLOR_SUCCESS[600],
2371
+ marginTop: '4px',
2372
+ }, children: successMessage }))] }));
2373
+ };
2374
+
2375
+ const COUNTRY_CODES = [
2376
+ { code: 'US', name: 'United States', flag: '🇺🇸', value: '+1' },
2377
+ { code: 'GB', name: 'United Kingdom', flag: '🇬🇧', value: '+44' },
2378
+ { code: 'CA', name: 'Canada', flag: '🇨🇦', value: '+1' },
2379
+ { code: 'AU', name: 'Australia', flag: '🇦🇺', value: '+61' },
2380
+ { code: 'VN', name: 'Vietnam', flag: '🇻🇳', value: '+84' },
2381
+ { code: 'JP', name: 'Japan', flag: '🇯🇵', value: '+81' },
2382
+ { code: 'CN', name: 'China', flag: '🇨🇳', value: '+86' },
2383
+ { code: 'IN', name: 'India', flag: '🇮🇳', value: '+91' },
2384
+ { code: 'DE', name: 'Germany', flag: '🇩🇪', value: '+49' },
2385
+ { code: 'FR', name: 'France', flag: '🇫🇷', value: '+33' },
2386
+ ];
2387
+ const StyledTextField$1 = styled(MuiTextField)(({ theme }) => {
2388
+ return {
2389
+ '& .MuiOutlinedInput-root': {
2390
+ '& fieldset': { borderColor: COLOR_NEUTRAL[300] },
2391
+ '&:hover fieldset': { borderColor: COLOR_NEUTRAL[400] },
2392
+ '&.Mui-focused fieldset': { borderColor: COLOR_NEUTRAL[300], borderWidth: '2px' },
2393
+ '&.Mui-focused': {
2394
+ boxShadow: '0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px #FEE4E2',
2395
+ },
2396
+ '&.Mui-disabled': {
2397
+ backgroundColor: COLOR_NEUTRAL[100],
2398
+ '& fieldset': { borderColor: COLOR_NEUTRAL[200] },
2399
+ '& input': { color: COLOR_NEUTRAL[400], WebkitTextFillColor: COLOR_NEUTRAL[400] },
2400
+ },
2401
+ '&.Mui-error fieldset': { borderColor: COLOR_ERROR[600], borderWidth: '1px' },
2402
+ '&.Mui-error:hover fieldset': { borderColor: COLOR_ERROR[600] },
2403
+ '&.Mui-error.Mui-focused fieldset': { borderColor: COLOR_ERROR[600], borderWidth: '2px' },
2404
+ '&.Mui-error.Mui-focused': {
2405
+ boxShadow: '0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px rgba(255, 66, 79, 0.15)',
2406
+ },
2407
+ },
2408
+ '& .MuiInputBase-input': {
2409
+ ...TYPOGRAPHY.text14Regular,
2410
+ padding: '12px 8px',
2411
+ color: COLOR_GRAY[900],
2412
+ '&::placeholder': { color: COLOR_NEUTRAL[400], opacity: 0.7 },
2413
+ '&:focus': { outline: 'none' },
2414
+ },
2415
+ '& .MuiInputLabel-root': {
2416
+ ...TYPOGRAPHY.textFieldLabel,
2417
+ color: COLOR_GRAY[800],
2418
+ transform: 'translate(14px, -9px) scale(0.75)',
2419
+ '&.Mui-focused': { color: COLOR_NEUTRAL[500] },
2420
+ '&.Mui-error': { color: COLOR_ERROR[600] },
2421
+ },
2422
+ '& .MuiFormHelperText-root': {
2423
+ ...TYPOGRAPHY.textFieldHelper,
2424
+ margin: '4px 0 0 0',
2425
+ '&.Mui-error': { color: COLOR_ERROR[600] },
2426
+ },
2427
+ };
2428
+ });
2429
+ const PhoneNumberFieldComponent = ({ label = 'Số điện thoại', placeholder = '0123 456 789', value, disabled = false, error = false, success = false, errorMessage, successMessage, borderRadius = 6, helperText, onChange, countryCode = 'US', onCountryCodeChange, countries = COUNTRY_CODES, sx, ...props }) => {
2430
+ const handleCountryChange = (e) => {
2431
+ const newCode = e.target.value;
2432
+ onCountryCodeChange?.(newCode);
2433
+ };
2434
+ return (jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Typography, { sx: {
2435
+ display: 'block',
2436
+ ...TYPOGRAPHY.textFieldLabel,
2437
+ color: COLOR_GRAY[800],
2438
+ marginBottom: '4px',
2439
+ }, children: label })), jsx(StyledTextField$1, { placeholder: placeholder, value: value, disabled: disabled, error: error, helperText: error ? errorMessage : helperText, size: "small", fullWidth: true, onChange: onChange, InputProps: {
2440
+ startAdornment: (jsx(InputAdornment, { position: "start", sx: { mr: 0 }, children: jsx(Select, { value: countryCode, onChange: handleCountryChange, disabled: disabled, variant: "standard", sx: {
2441
+ border: 'none',
2442
+ outline: 'none',
2443
+ '& .MuiSelect-standard': { border: 'none' },
2444
+ '&.MuiInput-underline:before': { borderBottom: 'none' },
2445
+ '&.MuiInput-underline:hover:before': { borderBottom: 'none' },
2446
+ '&.MuiInput-underline:after': { borderBottom: 'none' },
2447
+ minWidth: '50px',
2448
+ fontSize: '14px',
2449
+ color: COLOR_GRAY[500],
2450
+ display: 'flex',
2451
+ alignItems: 'center',
2452
+ gap: 0.5,
2453
+ }, children: countries.map((c) => (jsx(MenuItem, { value: c.code, children: c.code }, c.code))) }) })),
2454
+ endAdornment: (success || error) && (jsx(InputAdornment, { position: "end", children: jsx(IconElement, { icon: error ? 'info' : 'check_circle', sx: { color: error ? COLOR_ERROR[500] : COLOR_SUCCESS[500] } }) })),
2455
+ }, sx: {
2456
+ '& .MuiOutlinedInput-root': {
2457
+ borderRadius: borderRadius === 'max' ? '100px' : `${borderRadius}px`,
2458
+ ...(success && {
2459
+ '&.Mui-focused': {
2460
+ boxShadow: `0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px ${COLOR_SUCCESS[100]}`,
2461
+ },
2462
+ }),
2463
+ },
2464
+ } }), success && !error && successMessage && (jsx(Typography, { sx: {
2465
+ ...TYPOGRAPHY.textFieldHelper,
2466
+ color: COLOR_SUCCESS[600],
2467
+ marginTop: '4px',
2468
+ }, children: successMessage }))] }));
2469
+ };
2470
+
2471
+ const PIN_SIZES = {
2472
+ sm: { width: 40, height: 40, fontSize: 18 },
2473
+ md: { width: 48, height: 48, fontSize: 20 },
2474
+ lg: { width: 56, height: 56, fontSize: 24 },
2475
+ };
2476
+ const PIN_SPACING = {
2477
+ sm: 8,
2478
+ md: 12,
2479
+ lg: 16,
2480
+ };
2481
+
2482
+ const PINComponent = ({ length = 6, value, onChange, label, error = false, errorMessage, type = 'text', disabled = false, autoFocus = false, onComplete, align = 'left', spacing = 'md', size = 'md', masked = false, borderFocusColor, sx, }) => {
2483
+ const { palette } = useTheme();
2484
+ const inputRefs = useRef([]);
2485
+ useEffect(() => {
2486
+ if (autoFocus && inputRefs.current[0]) {
2487
+ inputRefs.current[0].focus();
2488
+ }
2489
+ }, [autoFocus]);
2490
+ const handleChange = (index, val) => {
2491
+ if (!/^\d*$/.test(val))
2492
+ return;
2493
+ const newValue = value.split('');
2494
+ newValue[index] = val;
2495
+ const updatedValue = newValue.join('').slice(0, length);
2496
+ onChange(updatedValue);
2497
+ if (val && index < length - 1) {
2498
+ inputRefs.current[index + 1]?.focus();
2499
+ }
2500
+ if (updatedValue.length === length) {
2501
+ onComplete?.(updatedValue);
2502
+ }
2503
+ };
2504
+ const handleKeyDown = (index, e) => {
2505
+ if (e.key === 'Backspace' && !value[index] && index > 0) {
2506
+ inputRefs.current[index - 1]?.focus();
2507
+ }
2508
+ };
2509
+ const renderPINDisplay = (index) => {
2510
+ const inputValue = value[index] || '';
2511
+ const isFilled = !!inputValue;
2512
+ const sizeStyle = PIN_SIZES[size];
2513
+ const borderColor = error ? palette.error.main : COLOR_GRAY[200];
2514
+ const borderFocusColorValue = borderFocusColor || (error ? palette.error.main : COLOR_GRAY[900]);
2515
+ if (type === 'bullet') {
2516
+ return (jsxs(Box, { sx: { position: 'relative', width: sizeStyle.width, height: sizeStyle.height }, children: [jsx(TextField, { ref: (el) => {
2517
+ const input = el?.querySelector('input');
2518
+ if (input) {
2519
+ inputRefs.current[index] = input;
2520
+ }
2521
+ }, type: "text", inputMode: "numeric", value: inputValue, onChange: (e) => handleChange(index, e.target.value), onKeyDown: (e) => handleKeyDown(index, e), disabled: disabled, error: error, sx: {
2522
+ width: '100%',
2523
+ height: '100%',
2524
+ '& .MuiOutlinedInput-root': {
2525
+ height: '100%',
2526
+ padding: 0,
2527
+ '& input': {
2528
+ textAlign: 'center',
2529
+ fontSize: sizeStyle.fontSize,
2530
+ fontWeight: 600,
2531
+ padding: 0,
2532
+ color: masked && isFilled ? 'transparent' : 'inherit',
2533
+ WebkitTextFillColor: masked && isFilled ? 'transparent' : 'unset',
2534
+ caretColor: palette.primary.main,
2535
+ '&::placeholder': {
2536
+ color: palette.action.disabled,
2537
+ opacity: 1,
2538
+ },
2539
+ },
2540
+ '& fieldset': {
2541
+ borderColor: borderColor,
2542
+ borderRadius: '8px',
2543
+ },
2544
+ '&:hover fieldset': {
2545
+ borderColor: error ? palette.error.main : borderFocusColorValue,
2546
+ },
2547
+ '&.Mui-focused fieldset': {
2548
+ borderColor: borderFocusColorValue,
2549
+ borderWidth: 1,
2550
+ },
2551
+ },
2552
+ '& input': {
2553
+ maxLength: 1,
2554
+ },
2555
+ }, placeholder: "-" }), masked && isFilled && (jsx(Box, { sx: {
2556
+ position: 'absolute',
2557
+ top: '50%',
2558
+ left: '50%',
2559
+ transform: 'translate(-50%, -50%)',
2560
+ fontSize: sizeStyle.fontSize,
2561
+ fontWeight: 600,
2562
+ color: error ? palette.error.main : palette.text.primary,
2563
+ pointerEvents: 'none',
2564
+ }, children: "\u25CF" }))] }));
2565
+ }
2566
+ if (type === 'circle') {
2567
+ return (jsxs(Box, { sx: { position: 'relative', width: sizeStyle.width, height: sizeStyle.height }, children: [jsx(TextField, { ref: (el) => {
2568
+ const input = el?.querySelector('input');
2569
+ if (input) {
2570
+ inputRefs.current[index] = input;
2571
+ }
2572
+ }, type: "text", inputMode: "numeric", value: inputValue, onChange: (e) => handleChange(index, e.target.value), onKeyDown: (e) => handleKeyDown(index, e), disabled: disabled, error: error, sx: {
2573
+ width: '100%',
2574
+ height: '100%',
2575
+ '& .MuiOutlinedInput-root': {
2576
+ height: '100%',
2577
+ padding: 0,
2578
+ borderRadius: '50%',
2579
+ '& input': {
2580
+ textAlign: 'center',
2581
+ fontSize: sizeStyle.fontSize,
2582
+ fontWeight: 600,
2583
+ padding: 0,
2584
+ color: masked && isFilled ? 'transparent' : 'inherit',
2585
+ WebkitTextFillColor: masked && isFilled ? 'transparent' : 'unset',
2586
+ caretColor: palette.primary.main,
2587
+ '&::placeholder': {
2588
+ color: palette.action.disabled,
2589
+ opacity: 1,
2590
+ },
2591
+ },
2592
+ '& fieldset': {
2593
+ borderColor: borderColor,
2594
+ borderRadius: '50%',
2595
+ },
2596
+ '&:hover fieldset': {
2597
+ borderColor: error ? palette.error.main : borderFocusColorValue,
2598
+ },
2599
+ '&.Mui-focused fieldset': {
2600
+ borderColor: borderFocusColorValue,
2601
+ borderWidth: 1,
2602
+ },
2603
+ },
2604
+ '& input': {
2605
+ maxLength: 1,
2606
+ },
2607
+ }, placeholder: "-" }), masked && isFilled && (jsx(Box, { sx: {
2608
+ position: 'absolute',
2609
+ top: '50%',
2610
+ left: '50%',
2611
+ transform: 'translate(-50%, -50%)',
2612
+ fontSize: sizeStyle.fontSize,
2613
+ fontWeight: 600,
2614
+ color: error ? palette.error.main : palette.text.primary,
2615
+ pointerEvents: 'none',
2616
+ }, children: "\u25CF" }))] }));
2617
+ }
2618
+ // Default text type
2619
+ return (jsx(TextField, { ref: (el) => {
2620
+ const input = el?.querySelector('input');
2621
+ if (input) {
2622
+ inputRefs.current[index] = input;
2623
+ }
2624
+ }, type: "text", inputMode: "numeric", value: inputValue, onChange: (e) => handleChange(index, e.target.value), onKeyDown: (e) => handleKeyDown(index, e), disabled: disabled, error: error, sx: {
2625
+ width: sizeStyle.width,
2626
+ '& .MuiOutlinedInput-root': {
2627
+ height: sizeStyle.height,
2628
+ padding: 0,
2629
+ '& input': {
2630
+ textAlign: 'center',
2631
+ fontSize: sizeStyle.fontSize,
2632
+ fontWeight: 600,
2633
+ padding: 0,
2634
+ '&::placeholder': {
2635
+ color: palette.action.disabled,
2636
+ opacity: 1,
2637
+ },
2638
+ },
2639
+ '& fieldset': {
2640
+ borderColor: borderColor,
2641
+ },
2642
+ '&:hover fieldset': {
2643
+ borderColor: error ? palette.error.main : borderFocusColorValue,
2644
+ },
2645
+ '&.Mui-focused fieldset': {
2646
+ borderColor: borderFocusColorValue,
2647
+ borderWidth: 1,
2648
+ },
2649
+ },
2650
+ '& input': {
2651
+ maxLength: 1,
2652
+ },
2653
+ }, placeholder: "-" }));
2654
+ };
2655
+ return (jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Box, { sx: {
2656
+ mb: 1,
2657
+ fontSize: 14,
2658
+ fontWeight: 500,
2659
+ color: palette.text.primary,
2660
+ }, children: label })), jsx(Box, { sx: {
2661
+ display: 'flex',
2662
+ gap: `${PIN_SPACING[spacing]}px`,
2663
+ justifyContent: align === 'center' ? 'center' : align === 'right' ? 'flex-end' : 'flex-start',
2664
+ }, children: Array.from({ length }).map((_, index) => (jsx(Box, { children: renderPINDisplay(index) }, index))) }), error && errorMessage && (jsx(Box, { sx: {
2665
+ mt: 1,
2666
+ fontSize: 12,
2667
+ color: palette.error.main,
2668
+ textAlign: align,
2669
+ }, children: errorMessage }))] }));
2670
+ };
2671
+
2672
+ const StyledAutocomplete$1 = styled$1(Autocomplete)(({ theme }) => ({
2673
+ '& .MuiOutlinedInput-root': {
2674
+ padding: '8px !important',
2675
+ display: 'flex',
2676
+ alignItems: 'flex-start',
2677
+ gap: '4px',
2678
+ minHeight: '44px',
2679
+ '& fieldset': {
2680
+ borderColor: COLOR_NEUTRAL[300],
2681
+ },
2682
+ '&:hover fieldset': {
2683
+ borderColor: COLOR_NEUTRAL[400],
2684
+ },
2685
+ '&.Mui-focused fieldset': {
2686
+ borderColor: COLOR_NEUTRAL[300] + ' !important',
2687
+ borderWidth: '1.5px',
2688
+ },
2689
+ '&.Mui-disabled': {
2690
+ backgroundColor: COLOR_NEUTRAL[100],
2691
+ '& fieldset': {
2692
+ borderColor: COLOR_NEUTRAL[200],
2693
+ },
2694
+ },
2695
+ '&.Mui-error fieldset': {
2696
+ borderColor: COLOR_ERROR[500],
2697
+ },
2698
+ '&.Mui-success fieldset': {
2699
+ borderColor: COLOR_SUCCESS[500],
2700
+ },
2701
+ },
2702
+ '& .MuiInputBase-input': {
2703
+ padding: '4px 4px !important',
2704
+ fontSize: '14px',
2705
+ flex: 1,
2706
+ minWidth: '60px',
2707
+ '&::placeholder': {
2708
+ color: COLOR_NEUTRAL[400],
2709
+ opacity: 1,
2710
+ },
2711
+ '&.Mui-disabled': {
2712
+ color: COLOR_NEUTRAL[400],
2713
+ WebkitTextFillColor: COLOR_NEUTRAL[400],
2714
+ },
2715
+ },
2716
+ '& .MuiAutocomplete-endAdornment': {
2717
+ paddingRight: '4px',
2718
+ },
2719
+ '& .MuiAutocomplete-tag': {
2720
+ backgroundColor: COLOR_ACCENT[50],
2721
+ border: `1px solid ${COLOR_ACCENT[200]}`,
2722
+ color: COLOR_ACCENT[900],
2723
+ fontSize: '12px',
2724
+ margin: '2px',
2725
+ '& .MuiChip-deleteIcon': {
2726
+ color: COLOR_ACCENT[400],
2727
+ '&:hover': {
2728
+ color: COLOR_ACCENT[600],
2729
+ },
2730
+ },
2731
+ },
2732
+ }));
2733
+ const SearchDropdownComponent = ({ value, onChange, onClear, onInputChange, onSearch, borderRadius = 6, disabled = false, multiple = false, label = '', placeholder = 'Search...', error = false, errorMessage, success = false, successMessage, helperText = '', options = [], loading = false, sx, }) => {
2734
+ const DEBOUNCE_DELAY = 500;
2735
+ const [inputValue, setInputValue] = useState('');
2736
+ const [filteredOptions, setFilteredOptions] = useState(options);
2737
+ const [isLoading, setIsLoading] = useState(false);
2738
+ const debounceTimerRef = useRef(null);
2739
+ const onSearchRef = useRef(onSearch);
2740
+ const onInputChangeRef = useRef(onInputChange);
2741
+ const optionsRef = useRef(options);
2742
+ // Update refs when props change
2743
+ useEffect(() => {
2744
+ onSearchRef.current = onSearch;
2745
+ onInputChangeRef.current = onInputChange;
2746
+ optionsRef.current = options;
2747
+ }, [onSearch, onInputChange, options]);
2748
+ // Normalize value to array for internal state
2749
+ const selectedValues = useMemo(() => {
2750
+ if (!value)
2751
+ return [];
2752
+ const values = Array.isArray(value) ? value : [value];
2753
+ return values.map((v) => (typeof v === 'object' ? v : { label: String(v), value: v }));
2754
+ }, [value]);
2755
+ // Search logic with debounce
2756
+ useEffect(() => {
2757
+ if (debounceTimerRef.current) {
2758
+ clearTimeout(debounceTimerRef.current);
2759
+ }
2760
+ // Reset to original options when input is empty
2761
+ if (!inputValue.trim()) {
2762
+ setFilteredOptions(optionsRef.current);
2763
+ return;
2764
+ }
2765
+ debounceTimerRef.current = setTimeout(async () => {
2766
+ const searchFn = onSearchRef.current;
2767
+ if (searchFn) {
2768
+ // Async search
2769
+ setIsLoading(true);
2770
+ try {
2771
+ const results = await searchFn(inputValue);
2772
+ setFilteredOptions(results);
2773
+ }
2774
+ catch (error) {
2775
+ console.error('Search error:', error);
2776
+ setFilteredOptions([]);
2777
+ }
2778
+ finally {
2779
+ setIsLoading(false);
2780
+ }
2781
+ }
2782
+ else {
2783
+ // Local filtering
2784
+ const filtered = optionsRef.current.filter((opt) => opt.label.toLowerCase().includes(inputValue.toLowerCase()));
2785
+ setFilteredOptions(filtered);
2786
+ }
2787
+ onInputChangeRef.current?.(inputValue);
2788
+ }, DEBOUNCE_DELAY);
2789
+ return () => {
2790
+ if (debounceTimerRef.current) {
2791
+ clearTimeout(debounceTimerRef.current);
2792
+ }
2793
+ };
2794
+ }, [inputValue]);
2795
+ const handleInputChange = (event, newInputValue) => {
2796
+ setInputValue(newInputValue);
2797
+ };
2798
+ const handleChange = (event, newValue) => {
2799
+ if (multiple) {
2800
+ const result = Array.isArray(newValue) ? newValue : newValue ? [newValue] : [];
2801
+ onChange?.(result.length > 0 ? result : null);
2802
+ }
2803
+ else {
2804
+ onChange?.(newValue || null);
2805
+ }
2806
+ };
2807
+ const handleClear = () => {
2808
+ setInputValue('');
2809
+ setFilteredOptions(optionsRef.current);
2810
+ onClear?.();
2811
+ };
2812
+ return (jsxs(Box, { sx: { width: '100%', ...sx }, children: [label && (jsx(Typography, { variant: "subtitle2", sx: {
2813
+ fontWeight: 500,
2814
+ color: COLOR_GRAY[900],
2815
+ marginBottom: '6px',
2816
+ display: 'block',
2817
+ }, children: label })), jsx(StyledAutocomplete$1, { multiple: multiple, freeSolo: true, options: filteredOptions, getOptionLabel: (option) => {
2818
+ if (!option)
2819
+ return '';
2820
+ if (typeof option === 'object' && 'label' in option)
2821
+ return option.label;
2822
+ return String(option);
2823
+ }, isOptionEqualToValue: (option, val) => {
2824
+ if (!option || !val)
2825
+ return false;
2826
+ if (typeof option === 'object' && typeof val === 'object' && 'value' in option && 'value' in val) {
2827
+ return option.value === val.value;
2828
+ }
2829
+ return false;
2830
+ }, value: multiple ? selectedValues : selectedValues[0] || null, inputValue: inputValue, onInputChange: handleInputChange, onChange: handleChange, disabled: disabled || loading, loading: isLoading || loading, noOptionsText: inputValue ? 'No results found' : 'Type to search', sx: {
2831
+ '& .MuiOutlinedInput-root': {
2832
+ borderRadius: borderRadius === 'max' ? '100px' : `${borderRadius}px`,
2833
+ borderColor: error ? COLOR_ERROR[500] : success ? COLOR_SUCCESS[500] : undefined,
2834
+ },
2835
+ }, renderInput: (params) => (jsx(TextField, { ...params, placeholder: placeholder, variant: "outlined", size: "small", error: error, InputProps: {
2836
+ ...params.InputProps,
2837
+ startAdornment: (jsxs(Fragment, { children: [jsx(InputAdornment, { position: "start", sx: { marginLeft: '4px', marginRight: '0px' }, children: jsx(SearchIcon, { sx: { color: '#999', fontSize: '18px' } }) }), params.InputProps?.startAdornment] })),
2838
+ } })), renderTags: (value, getTagProps) => value.map((option, index) => {
2839
+ const label = typeof option === 'object' && option && 'label' in option ? option.label : String(option);
2840
+ return jsx(Chip, { ...getTagProps({ index }), label: label, size: "small" });
2841
+ }), renderOption: (props, option) => {
2842
+ const { key, ...otherProps } = props;
2843
+ const label = option?.label || '';
2844
+ return (jsx(Box, { ...otherProps, component: "li", children: label }, key));
2845
+ }, componentsProps: {
2846
+ clearIndicator: {
2847
+ onClick: handleClear,
2848
+ },
2849
+ } }), error && errorMessage && (jsx(Box, { sx: {
2850
+ fontSize: '12px',
2851
+ color: COLOR_ERROR[500],
2852
+ marginTop: '4px',
2853
+ }, children: errorMessage })), success && successMessage && (jsx(Box, { sx: {
2854
+ fontSize: '12px',
2855
+ color: COLOR_SUCCESS[500],
2856
+ marginTop: '4px',
2857
+ }, children: successMessage })), helperText && !error && !success && (jsx(Box, { sx: {
2858
+ fontSize: '12px',
2859
+ color: COLOR_NEUTRAL[500],
2860
+ marginTop: '4px',
2861
+ }, children: helperText }))] }));
2862
+ };
2863
+
2864
+ const StyledAutocomplete = styled$1(Autocomplete)(({ theme }) => ({
2865
+ '& .MuiOutlinedInput-root': {
2866
+ padding: '0 !important',
2867
+ display: 'flex',
2868
+ alignItems: 'center',
2869
+ gap: '8px',
2870
+ '& fieldset': {
2871
+ borderColor: COLOR_NEUTRAL[300],
2872
+ },
2873
+ '&:hover fieldset': {
2874
+ borderColor: COLOR_NEUTRAL[400],
2875
+ },
2876
+ '&.Mui-focused fieldset': {
2877
+ borderColor: COLOR_NEUTRAL[300] + ' !important',
2878
+ },
2879
+ '&.Mui-disabled': {
2880
+ backgroundColor: COLOR_NEUTRAL[100],
2881
+ '& fieldset': {
2882
+ borderColor: COLOR_NEUTRAL[200],
2883
+ },
2884
+ },
2885
+ },
2886
+ '& .MuiInputBase-input': {
2887
+ padding: '8px 8px 8px 0 !important',
2888
+ fontSize: '14px',
2889
+ flex: 1,
2890
+ '&::placeholder': {
2891
+ color: COLOR_NEUTRAL[400],
2892
+ opacity: 1,
2893
+ },
2894
+ '&.Mui-disabled': {
2895
+ color: COLOR_NEUTRAL[400],
2896
+ WebkitTextFillColor: COLOR_NEUTRAL[400],
2897
+ },
2898
+ },
2899
+ '& .MuiAutocomplete-endAdornment': {
2900
+ paddingRight: '8px',
2901
+ },
2902
+ }));
2903
+ const SearchFieldComponent = ({ value, onChange, onClear, onInputChange, borderRadius = 6, disabled = false, placeholder = 'Placeholder', sx, }) => {
2904
+ const DEBOUNCE_DELAY = 1000;
2905
+ const [inputValue, setInputValue] = useState('');
2906
+ const debounceTimer = useRef(null);
2907
+ useEffect(() => {
2908
+ if (debounceTimer.current) {
2909
+ clearTimeout(debounceTimer.current);
2910
+ }
2911
+ debounceTimer.current = setTimeout(() => {
2912
+ onInputChange?.(new Event('debounce'), inputValue, 'debounce');
2913
+ }, DEBOUNCE_DELAY);
2914
+ return () => {
2915
+ if (debounceTimer.current) {
2916
+ clearTimeout(debounceTimer.current);
2917
+ }
2918
+ };
2919
+ }, [inputValue, onInputChange]);
2920
+ const handleInputChange = useCallback((event, value) => {
2921
+ setInputValue(value);
2922
+ }, []);
2923
+ const handleClear = useCallback(() => {
2924
+ setInputValue('');
2925
+ onClear?.();
2926
+ onInputChange?.(new Event('clear'), '', 'clear');
2927
+ }, [onClear, onInputChange]);
2928
+ return (jsx(StyledAutocomplete, { freeSolo: true, options: [], inputValue: inputValue, onInputChange: handleInputChange, disabled: disabled, onChange: onChange, noOptionsText: null, sx: {
2929
+ '& .MuiOutlinedInput-root': {
2930
+ borderRadius: borderRadius === 'max' ? '100px' : `${borderRadius}px`,
2931
+ },
2932
+ ...sx,
2933
+ }, renderInput: (params) => (jsx(TextField, { ...params, placeholder: placeholder, variant: "outlined", size: "small", InputProps: {
2934
+ ...params.InputProps,
2935
+ startAdornment: (jsx(InputAdornment, { position: "start", sx: { marginLeft: '8px' }, children: jsx(SearchIcon, { sx: { color: '#999', fontSize: '20px' } }) })),
2936
+ } })), componentsProps: {
2937
+ clearIndicator: {
2938
+ onClick: handleClear,
2939
+ },
2940
+ } }));
2941
+ };
2942
+
2943
+ const SWITCH_SIZE = {
2944
+ small: { width: '36px', height: '20px', thumbSize: '16px' },
2945
+ medium: { width: '44px', height: '24px', thumbSize: '20px' },
2946
+ };
2947
+ const SWITCH_COLORS = {
2948
+ dark: {
2949
+ trackBackgroundColor: '#F2F4F7',
2950
+ trackHoverColor: '#EAECF0',
2951
+ trackCheckedColor: '#07554B',
2952
+ thumbFocusColor: '#F4EBFF',
2953
+ },
2954
+ light: {
2955
+ trackBackgroundColor: '#F9F5FF',
2956
+ trackHoverColor: '#F4EBFF',
2957
+ trackCheckedColor: '#E9D7FE',
2958
+ thumbFocusColor: '#F4EBFF',
2959
+ },
2960
+ };
2961
+ const StyledSwitch = styled$1(Switch, {
2962
+ shouldForwardProp: (prop) => prop !== 'size',
2963
+ })(({ theme, size = 'medium' }) => {
2964
+ const mode = theme.palette.mode;
2965
+ const { width, height, thumbSize } = SWITCH_SIZE[size];
2966
+ const { trackBackgroundColor, trackHoverColor, trackCheckedColor, thumbFocusColor } = SWITCH_COLORS[mode] || SWITCH_COLORS.light;
2967
+ return {
2968
+ width,
2969
+ height,
2970
+ padding: 0,
2971
+ '& .MuiSwitch-switchBase': {
2972
+ padding: 0,
2973
+ margin: 2,
2974
+ transitionDuration: '300ms',
2975
+ '&.Mui-checked': {
2976
+ transform: `translateX(${size === 'small' ? '16px' : '20px'})`,
2977
+ color: '#FFFFFF',
2978
+ '& + .MuiSwitch-track': {
2979
+ backgroundColor: trackCheckedColor,
2980
+ opacity: 1,
2981
+ border: 0,
2982
+ },
2983
+ },
2984
+ '&.Mui-focusVisible .MuiSwitch-thumb': {
2985
+ color: thumbFocusColor,
2986
+ border: '6px solid #fff',
2987
+ boxShadow: '0 0 0 4px #F4EBFF',
2988
+ },
2989
+ '&.Mui-disabled .MuiSwitch-thumb': {
2990
+ color: '#FFFFFF',
2991
+ },
2992
+ '&.Mui-disabled + .MuiSwitch-track': {
2993
+ backgroundColor: trackBackgroundColor,
2994
+ },
2995
+ },
2996
+ '& .MuiSwitch-thumb': {
2997
+ boxSizing: 'border-box',
2998
+ width: thumbSize,
2999
+ height: thumbSize,
3000
+ },
3001
+ '& .MuiSwitch-track': {
3002
+ borderRadius: 26 / 2,
3003
+ backgroundColor: trackBackgroundColor,
3004
+ opacity: 1,
3005
+ transition: theme.transitions.create(['background-color'], {
3006
+ duration: 500,
3007
+ }),
3008
+ '&:hover': {
3009
+ backgroundColor: trackHoverColor,
3010
+ },
3011
+ },
3012
+ };
3013
+ });
3014
+ const SwitchComponent = ({ title, sx, ...switchProps }) => {
3015
+ if (!title) {
3016
+ return jsx(StyledSwitch, { disableRipple: true, ...switchProps });
3017
+ }
3018
+ return (jsxs(StackRowAlignCenterJustEnd, { sx: {
3019
+ display: 'inline-flex',
3020
+ alignItems: 'center',
3021
+ gap: '12px',
3022
+ ...sx,
3023
+ }, children: [jsx(StyledSwitch, { disableRipple: true, ...switchProps }), title] }));
3024
+ };
3025
+
3026
+ const TAB_STYLES = {
3027
+ position: 'relative',
3028
+ padding: '18px 16px',
3029
+ cursor: 'pointer',
3030
+ minHeight: 44,
3031
+ '&:hover': {
3032
+ bgcolor: '#F3F4F6',
3033
+ },
3034
+ };
3035
+ const TAB_UNDERLINE_STYLES = {
3036
+ width: '1px',
3037
+ alignSelf: 'stretch',
3038
+ bgcolor: '#E5E7EB',
3039
+ };
3040
+ const TABS_CONTAINER_HORIZONTAL = {
3041
+ display: 'flex',
3042
+ alignItems: 'center',
3043
+ borderBottom: '2px solid #E5E7EB',
3044
+ };
3045
+ const TAB_ACTIVE_BACKGROUND_HORIZONTAL = {
3046
+ position: 'absolute',
3047
+ bottom: -2,
3048
+ left: 0,
3049
+ right: 0,
3050
+ height: '2px',
3051
+ bgcolor: '#0F766E',
3052
+ };
3053
+ const TABS_CONTAINER_VERTICAL = {
3054
+ position: 'relative',
3055
+ padding: '10px',
3056
+ cursor: 'pointer',
3057
+ minHeight: 40,
3058
+ '&:hover': {
3059
+ bgcolor: '#F3F4F6',
3060
+ },
3061
+ width: '100%',
3062
+ };
3063
+ const TAB_ACTIVE_BACKGROUND_VERTICAL = {
3064
+ position: 'absolute',
3065
+ inset: 0,
3066
+ bgcolor: '#E6EEED',
3067
+ borderRadius: 1,
3068
+ };
3069
+ var TabColors;
3070
+ (function (TabColors) {
3071
+ TabColors["ACTIVE_TEXT"] = "#0F766E";
3072
+ TabColors["INACTIVE_TEXT"] = "#6B7280";
3073
+ TabColors["HOVER_BACKGROUND"] = "#F3F4F6";
3074
+ TabColors["MENU_ACTIVE_BACKGROUND"] = "#E0F2FE";
3075
+ })(TabColors || (TabColors = {}));
3076
+
3077
+ const TabsComponent = ({ idSelect, tabs, size, direction = 'row', maxDisplay, onChange, sx, sxTabs, sxWrapper, }) => {
3078
+ // state
3079
+ const [selected, setSelected] = useState(idSelect);
3080
+ const [anchorEl, setAnchorEl] = useState(null);
3081
+ const layoutGroupId = useId();
3082
+ useEffect(() => {
3083
+ setSelected(idSelect);
3084
+ }, [idSelect]);
3085
+ const isVertical = direction === 'column';
3086
+ const showOverflow = !isVertical && maxDisplay && tabs.length > maxDisplay;
3087
+ const visibleTabs = showOverflow ? tabs.slice(0, maxDisplay) : tabs;
3088
+ const overflowTabs = showOverflow ? tabs.slice(maxDisplay) : [];
3089
+ // function
3090
+ const handleOpenDropdown = (event) => {
3091
+ setAnchorEl(event.currentTarget);
3092
+ };
3093
+ const handleTabClick = (tab) => {
3094
+ setSelected(tab.id);
3095
+ onChange?.(tab.id);
3096
+ if (tab.onClick) {
3097
+ tab.onClick();
3098
+ }
3099
+ };
3100
+ const handleOverflowItemClick = (tab) => {
3101
+ handleTabClick(tab);
3102
+ setAnchorEl(null);
3103
+ };
3104
+ return (jsx(React.Fragment, { children: isVertical ? (jsx(LayoutGroup, { id: layoutGroupId, children: jsx(Stack, { direction: "column", sx: { width: 'fit-content', gap: PADDING_GAP_ITEM_SMALL, ...sxWrapper }, children: tabs.map((tab) => {
3105
+ const isActive = tab.id === selected;
3106
+ return (jsx(LinkElement, { href: tab.href, onClick: tab.onClick, id: tab.id, children: jsxs(Box, { sx: { position: 'relative' }, children: [jsx(Stack, { component: motion.div, sx: {
3107
+ ...TABS_CONTAINER_VERTICAL,
3108
+ color: isActive ? TabColors.ACTIVE_TEXT : TabColors.INACTIVE_TEXT,
3109
+ }, onTap: () => handleTabClick(tab), children: jsxs(Box, { sx: {
3110
+ ...TYPOGRAPHY_STYLES.textMd.medium,
3111
+ display: 'flex',
3112
+ alignItems: 'center',
3113
+ gap: tab.icon ? 0.5 : 0,
3114
+ position: 'relative',
3115
+ zIndex: 1,
3116
+ ...sx,
3117
+ }, children: [tab.icon && jsx(IconElement, { size: size, icon: tab.icon }), tab.name] }) }), isActive && (jsx(Box, { component: motion.div, sx: { ...TAB_ACTIVE_BACKGROUND_VERTICAL }, layoutId: `${layoutGroupId}-background` }))] }) }, tab.id));
3118
+ }) }) })) : (jsx(LayoutGroup, { id: layoutGroupId, children: jsxs(Box, { sx: { position: 'relative', display: 'flex', alignItems: 'center' }, children: [jsxs(Box, { sx: { ...TABS_CONTAINER_HORIZONTAL }, children: [visibleTabs.map((tab) => {
3119
+ const isActive = tab.id === selected;
3120
+ return (jsx(LinkElement, { href: tab.href, onClick: tab.onClick, id: tab.id, children: jsxs(Stack, { component: motion.div, sx: {
3121
+ color: isActive ? TabColors.ACTIVE_TEXT : TabColors.INACTIVE_TEXT,
3122
+ position: 'relative',
3123
+ padding: '18px 16px',
3124
+ cursor: 'pointer',
3125
+ minHeight: 40,
3126
+ '&:hover': {
3127
+ bgcolor: TabColors.HOVER_BACKGROUND,
3128
+ },
3129
+ ...sxTabs,
3130
+ }, onTap: () => handleTabClick(tab), children: [jsxs(Box, { sx: {
3131
+ ...TYPOGRAPHY_STYLES.textMd.medium,
3132
+ display: 'flex',
3133
+ alignItems: 'center',
3134
+ gap: tab.icon ? 0.5 : 0,
3135
+ ...sx,
3136
+ }, children: [tab.icon && jsx(IconElement, { size: size, icon: tab.icon }), tab.name] }), isActive && (jsx(Box, { component: motion.div, sx: { ...TAB_ACTIVE_BACKGROUND_HORIZONTAL }, layoutId: `${layoutGroupId}-underline` }))] }) }, tab.id));
3137
+ }), showOverflow && (jsxs(React.Fragment, { children: [jsx(Box, { sx: { ...TAB_UNDERLINE_STYLES } }), jsx(Stack, { sx: {
3138
+ ...TAB_STYLES,
3139
+ }, onClick: handleOpenDropdown, children: jsx(IconElement, { icon: "more_horiz", size: size }) })] }))] }), jsx(Menu, { disableScrollLock: true, anchorEl: anchorEl, open: Boolean(anchorEl), onClose: () => setAnchorEl(null), anchorOrigin: {
3140
+ vertical: 'bottom',
3141
+ horizontal: 'left',
3142
+ }, transformOrigin: {
3143
+ vertical: 'top',
3144
+ horizontal: 'left',
3145
+ }, children: overflowTabs.map((tab) => {
3146
+ const isActive = tab.id === selected;
3147
+ return (jsx(MenuItem, { onClick: () => handleOverflowItemClick(tab), sx: {
3148
+ color: isActive ? TabColors.ACTIVE_TEXT : TabColors.INACTIVE_TEXT,
3149
+ bgcolor: isActive ? TabColors.MENU_ACTIVE_BACKGROUND : 'transparent',
3150
+ '&:hover': {
3151
+ bgcolor: isActive ? TabColors.MENU_ACTIVE_BACKGROUND : TabColors.HOVER_BACKGROUND,
3152
+ },
3153
+ }, children: jsxs(Box, { sx: {
3154
+ display: 'flex',
3155
+ alignItems: 'center',
3156
+ gap: tab.icon ? 0.5 : 0,
3157
+ }, children: [tab.icon && jsx(IconElement, { size: size, icon: tab.icon }), tab.name] }) }, tab.id));
3158
+ }) })] }) })) }));
3159
+ };
3160
+
3161
+ const TextAreaComponent = ({ label = '', placeholder = '', value = '', disabled = false, error = false, success = false, errorMessage, successMessage, borderRadius = 6, onChange, onBlur, helperText = '', rows = 4, maxLength, sx, }) => {
3162
+ const borderRadiusValue = borderRadius === 'max' ? '100px' : `${borderRadius}px`;
3163
+ const getHelperText = () => {
3164
+ if (error && errorMessage)
3165
+ return errorMessage;
3166
+ if (success && successMessage)
3167
+ return successMessage;
3168
+ if (helperText)
3169
+ return helperText;
3170
+ return '';
3171
+ };
3172
+ const getHelperTextColor = () => {
3173
+ if (error)
3174
+ return COLOR_ERROR[500];
3175
+ if (success)
3176
+ return COLOR_SUCCESS[500];
3177
+ return COLOR_NEUTRAL[400];
3178
+ };
3179
+ const getBorderColor = () => {
3180
+ if (error)
3181
+ return COLOR_ERROR[500];
3182
+ if (success)
3183
+ return COLOR_SUCCESS[500];
3184
+ return COLOR_NEUTRAL[300];
3185
+ };
3186
+ return (jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Typography, { sx: {
3187
+ display: 'block',
3188
+ ...TYPOGRAPHY.textFieldLabel,
3189
+ color: COLOR_GRAY[800],
3190
+ marginBottom: '4px',
3191
+ }, children: label })), jsxs(Box, { sx: { position: 'relative' }, children: [jsx(TextField, { fullWidth: true, multiline: true, rows: rows, placeholder: placeholder, value: value, disabled: disabled, onChange: (e) => onChange?.(e.target.value), onBlur: (e) => onBlur?.(e.target.value), inputProps: {
3192
+ maxLength: maxLength,
3193
+ style: {
3194
+ ...TYPOGRAPHY.text14Regular,
3195
+ paddingBottom: maxLength ? '24px' : '0px',
3196
+ },
3197
+ }, sx: {
3198
+ '& .MuiOutlinedInput-root': {
3199
+ borderRadius: borderRadiusValue,
3200
+ backgroundColor: disabled ? COLOR_NEUTRAL[100] : 'white',
3201
+ transition: 'all 0.2s ease',
3202
+ '& fieldset': {
3203
+ borderColor: getBorderColor(),
3204
+ },
3205
+ '&:hover fieldset': {
3206
+ borderColor: disabled ? getBorderColor() : error ? COLOR_ERROR[500] : COLOR_NEUTRAL[400],
3207
+ },
3208
+ '&.Mui-focused fieldset': {
3209
+ borderColor: error ? COLOR_ERROR[500] : COLOR_NEUTRAL[400],
3210
+ borderWidth: '1.5px',
3211
+ },
3212
+ },
3213
+ '& .MuiOutlinedInput-input': {
3214
+ color: value ? COLOR_GRAY[900] : COLOR_NEUTRAL[400],
3215
+ '&::placeholder': {
3216
+ color: COLOR_NEUTRAL[400],
3217
+ opacity: 1,
3218
+ },
3219
+ '&:disabled': {
3220
+ color: COLOR_NEUTRAL[400],
3221
+ WebkitTextFillColor: COLOR_NEUTRAL[400],
3222
+ },
3223
+ },
3224
+ '& .MuiOutlinedInput-notchedOutline': {
3225
+ borderColor: getBorderColor(),
3226
+ },
3227
+ } }), maxLength && (jsxs(Box, { sx: {
3228
+ position: 'absolute',
3229
+ bottom: '8px',
3230
+ right: '12px',
3231
+ fontSize: '12px',
3232
+ color: COLOR_NEUTRAL[400],
3233
+ pointerEvents: 'none',
3234
+ }, children: ["(", value?.length, "/", maxLength, ")"] }))] }), getHelperText() && (jsx(Box, { sx: {
3235
+ color: getHelperTextColor(),
3236
+ marginTop: '4px',
3237
+ ...TYPOGRAPHY.textFieldHelper,
3238
+ }, children: getHelperText() }))] }));
3239
+ };
3240
+
3241
+ const StyledTextField = styled(MuiTextField)(({ theme }) => {
3242
+ return {
3243
+ '& .MuiOutlinedInput-root': {
3244
+ '& fieldset': { borderColor: COLOR_NEUTRAL[300] },
3245
+ '&:hover fieldset': { borderColor: COLOR_NEUTRAL[400] },
3246
+ '&.Mui-focused fieldset': { borderColor: COLOR_NEUTRAL[300], borderWidth: '2px' },
3247
+ '&.Mui-focused': {
3248
+ boxShadow: '0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px #FEE4E2',
3249
+ },
3250
+ '&.Mui-disabled': {
3251
+ backgroundColor: COLOR_NEUTRAL[100],
3252
+ '& fieldset': { borderColor: COLOR_NEUTRAL[200] },
3253
+ '& input': { color: COLOR_NEUTRAL[400], WebkitTextFillColor: COLOR_NEUTRAL[400] },
3254
+ },
3255
+ '&.Mui-error fieldset': { borderColor: COLOR_ERROR[500], borderWidth: '1px' },
3256
+ '&.Mui-error:hover fieldset': { borderColor: COLOR_ERROR[500] },
3257
+ '&.Mui-error.Mui-focused fieldset': { borderColor: COLOR_ERROR[500], borderWidth: '2px' },
3258
+ '&.Mui-error.Mui-focused': {
3259
+ boxShadow: '0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px rgba(255, 66, 79, 0.15)',
3260
+ },
3261
+ },
3262
+ '& .MuiInputBase-input': {
3263
+ ...TYPOGRAPHY.text14Regular,
3264
+ padding: '12px 16px',
3265
+ color: COLOR_GRAY[900],
3266
+ '&::placeholder': { color: COLOR_NEUTRAL[400], opacity: 0.7 },
3267
+ '&:focus': { outline: 'none' },
3268
+ },
3269
+ '& .MuiInputLabel-root': {
3270
+ ...TYPOGRAPHY.textFieldLabel,
3271
+ color: COLOR_GRAY[800],
3272
+ transform: 'translate(14px, -9px) scale(0.75)',
3273
+ '&.Mui-focused': { color: COLOR_NEUTRAL[500] },
3274
+ '&.Mui-error': { color: COLOR_ERROR[600] },
3275
+ },
3276
+ '& .MuiFormHelperText-root': {
3277
+ ...TYPOGRAPHY.textFieldHelper,
3278
+ margin: '4px 0 0 0',
3279
+ '&.Mui-error': { color: COLOR_ERROR[600] },
3280
+ },
3281
+ };
3282
+ });
3283
+ const TextFieldComponent = ({ label, placeholder = 'Placeholder', value, disabled = false, error = false, success = false, errorMessage, successMessage, borderRadius = 6, helperText, onChange, iconBefore, iconAfter, sx, ...props }) => {
3284
+ return (jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Typography, { sx: {
3285
+ display: 'block',
3286
+ ...TYPOGRAPHY.textFieldLabel,
3287
+ color: COLOR_GRAY[800],
3288
+ marginBottom: '4px',
3289
+ }, children: label })), jsx(StyledTextField, { placeholder: placeholder, value: value, disabled: disabled, error: error, helperText: error ? errorMessage : helperText, size: "small", fullWidth: true, onChange: onChange, InputProps: {
3290
+ startAdornment: iconBefore ? jsx(InputAdornment, { position: "start", children: iconBefore }) : undefined,
3291
+ endAdornment: iconAfter ? jsx(InputAdornment, { position: "end", children: iconAfter }) : undefined,
3292
+ }, sx: {
3293
+ '& .MuiOutlinedInput-root': {
3294
+ borderRadius: borderRadius === 'max' ? '100px' : `${borderRadius}px`,
3295
+ ...(success && {
3296
+ '&.Mui-focused': {
3297
+ boxShadow: `0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px ${COLOR_SUCCESS[100]}`,
3298
+ },
3299
+ }),
3300
+ },
3301
+ }, ...props }), success && !error && successMessage && (jsx(Typography, { sx: {
3302
+ ...TYPOGRAPHY.textFieldHelper,
3303
+ color: COLOR_SUCCESS[500],
3304
+ marginTop: '4px',
3305
+ }, children: successMessage }))] }));
3306
+ };
3307
+
3308
+ const SX_STYLES = {
3309
+ progressBar: {
3310
+ position: 'absolute',
3311
+ top: 0,
3312
+ left: 0,
3313
+ height: '100%',
3314
+ backgroundColor: COLOR_GRAY[200],
3315
+ opacity: 0.8,
3316
+ transition: 'width 0.3s ease, opacity 0.3s ease',
3317
+ animation: 'wave 1.5s linear infinite',
3318
+ '@keyframes wave': {
3319
+ '0%': { backgroundPosition: '0% 0%' },
3320
+ '50%': { backgroundPosition: '100% 0%' },
3321
+ '100%': { backgroundPosition: '0% 0%' },
3322
+ },
3323
+ },
3324
+ imageIcon: {
3325
+ width: '40px',
3326
+ height: '40px',
3327
+ flexShrink: 0,
3328
+ position: 'relative',
3329
+ zIndex: 1,
3330
+ },
3331
+ contentBox: {
3332
+ flexGrow: 1,
3333
+ minWidth: 0,
3334
+ position: 'relative',
3335
+ zIndex: 1,
3336
+ },
3337
+ textBox: {
3338
+ minWidth: 0,
3339
+ flexGrow: 1,
3340
+ mr: 2,
3341
+ },
3342
+ actionBox: {
3343
+ flexShrink: 0,
3344
+ display: 'flex',
3345
+ alignItems: 'center',
3346
+ position: 'relative',
3347
+ zIndex: 1,
3348
+ },
3349
+ linearProgress: {
3350
+ mt: 1,
3351
+ width: '100%',
3352
+ },
3353
+ };
3354
+
3355
+ const VIDEO_EXTENSIONS = ['mp4', 'mov', 'avi', 'wmv', 'flv', 'mkv', 'webm'];
3356
+ const ICON_PATH = {
3357
+ VIDEO: '/images/icon/film.svg',
3358
+ FILE: '/images/icon/file.svg',
3359
+ };
3360
+ // ============================================================================
3361
+ // Helper Functions
3362
+ // ============================================================================
3363
+ const formatFileSize = (bytes) => {
3364
+ if (bytes === 0)
3365
+ return '0 Bytes';
3366
+ const k = 1024;
3367
+ const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
3368
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
3369
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
3370
+ };
3371
+ const getFileIcon = (fileName) => {
3372
+ const ext = fileName.split('.').pop()?.toLowerCase();
3373
+ return ext && VIDEO_EXTENSIONS.includes(ext) ? ICON_PATH.VIDEO : ICON_PATH.FILE;
3374
+ };
3375
+ // ============================================================================
3376
+ // Component
3377
+ // ============================================================================
3378
+ const UploaderItemComponent = ({ file, progress = 0, status = 'pending', onDelete, onRetry, isProcess = true, borderSuccess, borderError = COLOR_ERROR[600], sx, }) => {
3379
+ // Memoize
3380
+ const iconSrc = useMemo(() => getFileIcon(file.name), [file.name]);
3381
+ // Status flags
3382
+ const isCompleted = status === 'success';
3383
+ const isFailed = status === 'failed';
3384
+ const isUploading = status === 'uploading';
3385
+ // Determine colors based on status
3386
+ const borderColor = isFailed
3387
+ ? String(borderError)
3388
+ : isCompleted && borderSuccess
3389
+ ? String(borderSuccess)
3390
+ : '#e0e0e0';
3391
+ const textColor = isFailed ? String(borderError) : '#737373';
3392
+ const subtitleColor = isFailed ? String(borderError) : '#a3a3a3';
3393
+ // Render progress info
3394
+ const renderProgressInfo = () => {
3395
+ if (isUploading && !isCompleted)
3396
+ return ` • ${Math.round(progress)}% uploaded`;
3397
+ if (isFailed)
3398
+ return ' • Upload failed';
3399
+ return '';
3400
+ };
3401
+ return (jsxs(Box, { sx: {
3402
+ display: 'flex',
3403
+ alignItems: 'flex-start',
3404
+ padding: '16px',
3405
+ border: '1px solid',
3406
+ borderColor: borderColor,
3407
+ borderRadius: '8px',
3408
+ gap: '16px',
3409
+ position: 'relative',
3410
+ overflow: 'hidden',
3411
+ transition: 'background-color 0.3s ease',
3412
+ backgroundColor: 'background.paper',
3413
+ ...sx,
3414
+ }, children: [!isProcess && isUploading && !isCompleted && !isFailed && (jsx(Box, { sx: { ...SX_STYLES.progressBar, width: `${progress}%` } })), jsx(Box, { component: "img", src: iconSrc, alt: "file icon", sx: SX_STYLES.imageIcon }), jsxs(Box, { sx: SX_STYLES.contentBox, children: [jsxs(StackRowAlignCenterJustBetween, { children: [jsxs(Box, { sx: SX_STYLES.textBox, children: [jsx(Typography, { noWrap: true, title: file.name, sx: { ...TYPOGRAPHY.text14Medium, color: textColor }, children: file.name }), jsxs(Typography, { sx: { ...TYPOGRAPHY.text14Regular, color: subtitleColor }, children: [formatFileSize(file.size), renderProgressInfo()] })] }), jsxs(Box, { sx: SX_STYLES.actionBox, children: [!isProcess && isUploading && !isCompleted && (jsx(Box, { sx: { position: 'relative', display: 'inline-flex', mr: 1 }, children: jsx(CircularProgress, { variant: "determinate", value: progress, color: "success", size: 24 }) })), isCompleted && jsx(CheckCircleIcon, { color: "success", sx: { mr: 1 } }), isFailed && onRetry && (jsx(IconButton, { size: "small", onClick: onRetry, title: "Retry upload", children: jsx(RefreshIcon, { fontSize: "small", sx: { color: borderError } }) })), !isFailed && onDelete && (jsx(IconButton, { size: "small", onClick: onDelete, children: jsx(IconElement, { icon: "delete" }) }))] })] }), isProcess && isUploading && (jsx(Box, { sx: SX_STYLES.linearProgress, children: jsx(LinearProgress, { variant: "determinate", value: progress, color: "success", sx: { height: 8, borderRadius: 4 } }) }))] })] }));
3415
+ };
3416
+
3417
+ const UploaderComponent = ({ onFilesSelected, accept = '*', multiple = true, children, sx, labelSx, uploadLabel = 'Click to upload', appearance, files: externalFiles, onDeleteFile, onRetryFile, borderError, }) => {
3418
+ const fileInputRef = useRef(null);
3419
+ const [isDragging, setIsDragging] = useState(false);
3420
+ // Sử dụng external files nếu có, nếu không hiển thị rỗng
3421
+ const displayFiles = externalFiles || [];
3422
+ const handleClick = () => {
3423
+ fileInputRef.current?.click();
3424
+ };
3425
+ const handleFileChange = (event) => {
3426
+ const selectedFiles = event.target.files;
3427
+ if (selectedFiles) {
3428
+ const fileArray = Array.from(selectedFiles);
3429
+ onFilesSelected(fileArray);
3430
+ }
3431
+ event.target.value = '';
3432
+ };
3433
+ const handleDeleteFile = (file) => {
3434
+ if (onDeleteFile) {
3435
+ onDeleteFile(file);
3436
+ }
3437
+ };
3438
+ const handleDragOver = (e) => {
3439
+ e.preventDefault();
3440
+ e.stopPropagation();
3441
+ setIsDragging(true);
3442
+ };
3443
+ const handleDragLeave = (e) => {
3444
+ e.preventDefault();
3445
+ e.stopPropagation();
3446
+ setIsDragging(false);
3447
+ };
3448
+ const handleDrop = (e) => {
3449
+ e.preventDefault();
3450
+ e.stopPropagation();
3451
+ setIsDragging(false);
3452
+ const files = e.dataTransfer.files;
3453
+ if (files) {
3454
+ onFilesSelected(Array.from(files));
3455
+ }
3456
+ };
3457
+ return (jsxs(Box, { sx: {
3458
+ border: '2px solid',
3459
+ borderColor: appearance?.borderColor || 'action.selected',
3460
+ borderRadius: '8px',
3461
+ padding: '32px 24px',
3462
+ textAlign: 'center',
3463
+ cursor: 'pointer',
3464
+ transition: 'all 0.3s ease',
3465
+ backgroundColor: isDragging ? 'action.selected' : appearance?.background || 'background.paper',
3466
+ '&:hover': {
3467
+ borderColor: appearance?.borderColorHover || appearance?.borderColor || 'primary.main',
3468
+ filter: 'brightness(0.92)',
3469
+ },
3470
+ ...sx,
3471
+ }, onClick: handleClick, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, children: [jsx("input", { ref: fileInputRef, type: "file", accept: accept, multiple: multiple, onChange: handleFileChange, style: { display: 'none' } }), displayFiles.length === 0 && (jsx(Fragment, { children: children ? (jsxs(Box, { children: [children, jsxs(Box, { component: "p", sx: {
3472
+ color: 'primary.main',
3473
+ textDecoration: 'underline',
3474
+ fontWeight: 500,
3475
+ fontSize: '14px',
3476
+ marginTop: '12px',
3477
+ margin: '12px 0 0 0',
3478
+ ...labelSx,
3479
+ }, children: [uploadLabel, " or drag and drop"] })] })) : (jsxs(Box, { children: [jsx(Box, { component: "img", src: "/images/icon/uploader.svg", alt: "Upload icon", sx: {
3480
+ width: '46px',
3481
+ height: '46px',
3482
+ marginBottom: '12px',
3483
+ } }), jsxs(Box, { component: "p", sx: {
3484
+ color: 'primary.main',
3485
+ textDecoration: 'underline',
3486
+ fontWeight: 500,
3487
+ fontSize: '14px',
3488
+ margin: 0,
3489
+ ...labelSx,
3490
+ }, children: [uploadLabel, " or drag and drop"] })] })) })), displayFiles && displayFiles.length > 0 && (jsx(Box, { sx: {
3491
+ marginTop: '24px',
3492
+ display: 'flex',
3493
+ flexDirection: 'column',
3494
+ gap: '12px',
3495
+ textAlign: 'left',
3496
+ }, onClick: (e) => e.stopPropagation(), children: displayFiles.map((item, index) => (jsx(UploaderItemComponent, { file: item.file, progress: item.progress, status: item.status, isProcess: item.isProcess ?? true, onDelete: () => handleDeleteFile(item.file), onRetry: () => onRetryFile?.(item.id), borderSuccess: appearance?.borderSuccess, borderError: borderError }, item.id || index))) }))] }));
3497
+ };
3498
+
3499
+ export { AVATAR_SIZES, AvatarColor, AvatarComponent, AvatarGroupComponent as AvatarGroup, AvatarLabelGroupComponent as AvatarLabelGroup, AvatarProfileComponent as AvatarProfile, AvatarUserComponent as AvatarUser, BADGE_FONT_SIZES, BADGE_SIZES, BadgeImage, BadgeLive, BadgeNumber, BadgeOnline, BreadcrumbsComponent as Breadcrumbs, ButtonBarComponent as ButtonBar, ButtonComponent, COLOR_ACCENT, COLOR_BRAND, COLOR_ERROR, COLOR_GRAY, COLOR_INFO, COLOR_NEUTRAL, COLOR_SUCCESS, COLOR_WARNING, CheckboxComponent as Checkbox, ChipComponent as Chip, DateFieldComponent as DateField, DateRangePickerComponent as DateRangePicker, DialogWrapper, DropdownFieldComponent as DropdownField, FONT_FAMILY, FONT_SIZE, FONT_STYLE, FONT_WEIGHT, GridComponent as Grid, IconElement, ImageElement, ImageSizeType, InputStepperComponent as InputStepper, LINE_HEIGHT, LinkElement, LinkFieldComponent as LinkField, LinkInternalElement, MAP_SIZE, ModalComponent as Modal, ModalCardComponent as ModalCard, ModalDescription, ModalIcon, ModalTitle, MoneyFieldComponent as MoneyField, PINComponent as PIN, PhoneNumberFieldComponent as PhoneField, SIZE_EXTRA_LARGE, style_constant as STYLE, SearchDropdownComponent as SearchDropdown, SearchFieldComponent as SearchField, SwitchComponent as Switch, TYPOGRAPHY, TYPOGRAPHY_STYLES, TabsComponent as Tabs, TextAreaComponent as TextArea, TextFieldComponent as TextField, TypographyOneLine, UploaderComponent as Uploader, createTypography, getBadgePosition };
3500
+ //# sourceMappingURL=index.js.map