sevatech-library 1.0.1 → 1.0.3

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 (356) hide show
  1. package/README.md +2 -2
  2. package/dist/cjs/index.js +1644 -36
  3. package/dist/cjs/index.js.map +1 -1
  4. package/dist/cjs/types/components/avatar/avatar-group.component.d.ts +1 -1
  5. package/dist/cjs/types/components/avatar/avatar-group.component.d.ts.map +1 -1
  6. package/dist/cjs/types/components/avatar/avatar-label-group.component.d.ts +1 -1
  7. package/dist/cjs/types/components/avatar/avatar-label-group.component.d.ts.map +1 -1
  8. package/dist/cjs/types/components/avatar/avatar-profile.component.d.ts +1 -1
  9. package/dist/cjs/types/components/avatar/avatar-profile.component.d.ts.map +1 -1
  10. package/dist/cjs/types/components/avatar/avatar-user.component.d.ts +1 -1
  11. package/dist/cjs/types/components/avatar/avatar-user.component.d.ts.map +1 -1
  12. package/dist/cjs/types/components/avatar/index.d.ts +4 -4
  13. package/dist/cjs/types/components/avatar/index.d.ts.map +1 -1
  14. package/dist/cjs/types/components/bread-crumbs/bread-crumbs.component.d.ts +1 -1
  15. package/dist/cjs/types/components/bread-crumbs/bread-crumbs.component.d.ts.map +1 -1
  16. package/dist/cjs/types/components/bread-crumbs/index.d.ts +3 -0
  17. package/dist/cjs/types/components/bread-crumbs/index.d.ts.map +1 -0
  18. package/dist/cjs/types/components/button/index.d.ts +3 -0
  19. package/dist/cjs/types/components/button/index.d.ts.map +1 -0
  20. package/dist/cjs/types/components/button-bar/button-bar.component.d.ts +1 -1
  21. package/dist/cjs/types/components/button-bar/button-bar.component.d.ts.map +1 -1
  22. package/dist/cjs/types/components/button-bar/index.d.ts +2 -0
  23. package/dist/cjs/types/components/button-bar/index.d.ts.map +1 -0
  24. package/dist/cjs/types/components/checkbox/checkbox-content.component.d.ts.map +1 -1
  25. package/dist/cjs/types/components/checkbox/checkbox.component.d.ts +1 -1
  26. package/dist/cjs/types/components/checkbox/checkbox.component.d.ts.map +1 -1
  27. package/dist/cjs/types/components/checkbox/index.d.ts +4 -0
  28. package/dist/cjs/types/components/checkbox/index.d.ts.map +1 -0
  29. package/dist/cjs/types/components/chip/chip.component.d.ts +1 -1
  30. package/dist/cjs/types/components/chip/chip.component.d.ts.map +1 -1
  31. package/dist/cjs/types/components/chip/index.d.ts +3 -0
  32. package/dist/cjs/types/components/chip/index.d.ts.map +1 -0
  33. package/dist/cjs/types/components/date-field/date-field.component.d.ts +1 -1
  34. package/dist/cjs/types/components/date-field/date-field.component.d.ts.map +1 -1
  35. package/dist/cjs/types/components/date-field/index.d.ts +2 -0
  36. package/dist/cjs/types/components/date-field/index.d.ts.map +1 -0
  37. package/dist/cjs/types/components/date-range-picker/date-range-picker.component.d.ts +1 -1
  38. package/dist/cjs/types/components/date-range-picker/date-range-picker.component.d.ts.map +1 -1
  39. package/dist/cjs/types/components/date-range-picker/index.d.ts +2 -0
  40. package/dist/cjs/types/components/date-range-picker/index.d.ts.map +1 -0
  41. package/dist/cjs/types/components/dropdown-field/dropdown-field.component.d.ts +1 -1
  42. package/dist/cjs/types/components/dropdown-field/dropdown-field.component.d.ts.map +1 -1
  43. package/dist/cjs/types/components/dropdown-field/index.d.ts +2 -0
  44. package/dist/cjs/types/components/dropdown-field/index.d.ts.map +1 -0
  45. package/dist/cjs/types/components/grid/grid.component.d.ts +1 -1
  46. package/dist/cjs/types/components/grid/grid.component.d.ts.map +1 -1
  47. package/dist/cjs/types/components/grid/index.d.ts +2 -0
  48. package/dist/cjs/types/components/grid/index.d.ts.map +1 -0
  49. package/dist/cjs/types/components/index.d.ts +22 -23
  50. package/dist/cjs/types/components/index.d.ts.map +1 -1
  51. package/dist/cjs/types/components/input-stepper/index.d.ts +4 -0
  52. package/dist/cjs/types/components/input-stepper/index.d.ts.map +1 -0
  53. package/dist/cjs/types/components/input-stepper/input-stepper-skeleton.d.ts +1 -1
  54. package/dist/cjs/types/components/input-stepper/input-stepper-skeleton.d.ts.map +1 -1
  55. package/dist/cjs/types/components/input-stepper/input-stepper.component.d.ts +1 -1
  56. package/dist/cjs/types/components/input-stepper/input-stepper.component.d.ts.map +1 -1
  57. package/dist/cjs/types/components/link-field/index.d.ts +2 -0
  58. package/dist/cjs/types/components/link-field/index.d.ts.map +1 -0
  59. package/dist/cjs/types/components/link-field/link-field.component.d.ts +1 -1
  60. package/dist/cjs/types/components/link-field/link-field.component.d.ts.map +1 -1
  61. package/dist/cjs/types/components/modal/index.d.ts +2 -2
  62. package/dist/cjs/types/components/modal/index.d.ts.map +1 -1
  63. package/dist/cjs/types/components/modal/modal-card.component.d.ts +1 -1
  64. package/dist/cjs/types/components/modal/modal-card.component.d.ts.map +1 -1
  65. package/dist/cjs/types/components/modal/modal.component.d.ts +1 -1
  66. package/dist/cjs/types/components/modal/modal.component.d.ts.map +1 -1
  67. package/dist/cjs/types/components/money-field/index.d.ts +2 -0
  68. package/dist/cjs/types/components/money-field/index.d.ts.map +1 -0
  69. package/dist/cjs/types/components/money-field/money-field.component.d.ts +1 -1
  70. package/dist/cjs/types/components/money-field/money-field.component.d.ts.map +1 -1
  71. package/dist/cjs/types/components/phone-number-field/index.d.ts +2 -0
  72. package/dist/cjs/types/components/phone-number-field/index.d.ts.map +1 -0
  73. package/dist/cjs/types/components/phone-number-field/phone-number-field.component.d.ts +1 -1
  74. package/dist/cjs/types/components/phone-number-field/phone-number-field.component.d.ts.map +1 -1
  75. package/dist/cjs/types/components/pin/index.d.ts +3 -0
  76. package/dist/cjs/types/components/pin/index.d.ts.map +1 -0
  77. package/dist/cjs/types/components/pin/pin.component.d.ts +1 -1
  78. package/dist/cjs/types/components/pin/pin.component.d.ts.map +1 -1
  79. package/dist/cjs/types/components/search-dropdown/index.d.ts +2 -0
  80. package/dist/cjs/types/components/search-dropdown/index.d.ts.map +1 -0
  81. package/dist/cjs/types/components/search-dropdown/search-dropdown.component.d.ts +1 -1
  82. package/dist/cjs/types/components/search-dropdown/search-dropdown.component.d.ts.map +1 -1
  83. package/dist/cjs/types/components/search-field/index.d.ts +2 -0
  84. package/dist/cjs/types/components/search-field/index.d.ts.map +1 -0
  85. package/dist/cjs/types/components/search-field/search-field.component.d.ts +1 -1
  86. package/dist/cjs/types/components/search-field/search-field.component.d.ts.map +1 -1
  87. package/dist/cjs/types/components/switch/index.d.ts +3 -0
  88. package/dist/cjs/types/components/switch/index.d.ts.map +1 -0
  89. package/dist/cjs/types/components/switch/switch-content.component.d.ts +1 -1
  90. package/dist/cjs/types/components/switch/switch-content.component.d.ts.map +1 -1
  91. package/dist/cjs/types/components/switch/switch.component.d.ts +1 -1
  92. package/dist/cjs/types/components/switch/switch.component.d.ts.map +1 -1
  93. package/dist/cjs/types/components/tab/index.d.ts +3 -0
  94. package/dist/cjs/types/components/tab/index.d.ts.map +1 -0
  95. package/dist/cjs/types/components/tab/tab.component.d.ts +1 -1
  96. package/dist/cjs/types/components/tab/tab.component.d.ts.map +1 -1
  97. package/dist/cjs/types/components/text-area/index.d.ts +2 -0
  98. package/dist/cjs/types/components/text-area/index.d.ts.map +1 -0
  99. package/dist/cjs/types/components/text-area/text-area.component.d.ts +1 -1
  100. package/dist/cjs/types/components/text-area/text-area.component.d.ts.map +1 -1
  101. package/dist/cjs/types/components/text-field/index.d.ts +2 -0
  102. package/dist/cjs/types/components/text-field/index.d.ts.map +1 -0
  103. package/dist/cjs/types/components/text-field/text-field.component.d.ts +1 -1
  104. package/dist/cjs/types/components/text-field/text-field.component.d.ts.map +1 -1
  105. package/dist/cjs/types/components/typography/typography-limit-one-line.component.d.ts +1 -1
  106. package/dist/cjs/types/components/typography/typography-limit-one-line.component.d.ts.map +1 -1
  107. package/dist/cjs/types/components/uploader/index.d.ts +3 -0
  108. package/dist/cjs/types/components/uploader/index.d.ts.map +1 -0
  109. package/dist/cjs/types/components/uploader/uploader-item.component.d.ts +1 -1
  110. package/dist/cjs/types/components/uploader/uploader-item.component.d.ts.map +1 -1
  111. package/dist/cjs/types/components/uploader/uploader.component.d.ts +1 -1
  112. package/dist/cjs/types/components/uploader/uploader.component.d.ts.map +1 -1
  113. package/dist/esm/index.js +1591 -29
  114. package/dist/esm/index.js.map +1 -1
  115. package/dist/esm/types/components/avatar/avatar-group.component.d.ts +1 -1
  116. package/dist/esm/types/components/avatar/avatar-group.component.d.ts.map +1 -1
  117. package/dist/esm/types/components/avatar/avatar-label-group.component.d.ts +1 -1
  118. package/dist/esm/types/components/avatar/avatar-label-group.component.d.ts.map +1 -1
  119. package/dist/esm/types/components/avatar/avatar-profile.component.d.ts +1 -1
  120. package/dist/esm/types/components/avatar/avatar-profile.component.d.ts.map +1 -1
  121. package/dist/esm/types/components/avatar/avatar-user.component.d.ts +1 -1
  122. package/dist/esm/types/components/avatar/avatar-user.component.d.ts.map +1 -1
  123. package/dist/esm/types/components/avatar/index.d.ts +4 -4
  124. package/dist/esm/types/components/avatar/index.d.ts.map +1 -1
  125. package/dist/esm/types/components/bread-crumbs/bread-crumbs.component.d.ts +1 -1
  126. package/dist/esm/types/components/bread-crumbs/bread-crumbs.component.d.ts.map +1 -1
  127. package/dist/esm/types/components/bread-crumbs/index.d.ts +3 -0
  128. package/dist/esm/types/components/bread-crumbs/index.d.ts.map +1 -0
  129. package/dist/esm/types/components/button/index.d.ts +3 -0
  130. package/dist/esm/types/components/button/index.d.ts.map +1 -0
  131. package/dist/esm/types/components/button-bar/button-bar.component.d.ts +1 -1
  132. package/dist/esm/types/components/button-bar/button-bar.component.d.ts.map +1 -1
  133. package/dist/esm/types/components/button-bar/index.d.ts +2 -0
  134. package/dist/esm/types/components/button-bar/index.d.ts.map +1 -0
  135. package/dist/esm/types/components/checkbox/checkbox-content.component.d.ts.map +1 -1
  136. package/dist/esm/types/components/checkbox/checkbox.component.d.ts +1 -1
  137. package/dist/esm/types/components/checkbox/checkbox.component.d.ts.map +1 -1
  138. package/dist/esm/types/components/checkbox/index.d.ts +4 -0
  139. package/dist/esm/types/components/checkbox/index.d.ts.map +1 -0
  140. package/dist/esm/types/components/chip/chip.component.d.ts +1 -1
  141. package/dist/esm/types/components/chip/chip.component.d.ts.map +1 -1
  142. package/dist/esm/types/components/chip/index.d.ts +3 -0
  143. package/dist/esm/types/components/chip/index.d.ts.map +1 -0
  144. package/dist/esm/types/components/date-field/date-field.component.d.ts +1 -1
  145. package/dist/esm/types/components/date-field/date-field.component.d.ts.map +1 -1
  146. package/dist/esm/types/components/date-field/index.d.ts +2 -0
  147. package/dist/esm/types/components/date-field/index.d.ts.map +1 -0
  148. package/dist/esm/types/components/date-range-picker/date-range-picker.component.d.ts +1 -1
  149. package/dist/esm/types/components/date-range-picker/date-range-picker.component.d.ts.map +1 -1
  150. package/dist/esm/types/components/date-range-picker/index.d.ts +2 -0
  151. package/dist/esm/types/components/date-range-picker/index.d.ts.map +1 -0
  152. package/dist/esm/types/components/dropdown-field/dropdown-field.component.d.ts +1 -1
  153. package/dist/esm/types/components/dropdown-field/dropdown-field.component.d.ts.map +1 -1
  154. package/dist/esm/types/components/dropdown-field/index.d.ts +2 -0
  155. package/dist/esm/types/components/dropdown-field/index.d.ts.map +1 -0
  156. package/dist/esm/types/components/grid/grid.component.d.ts +1 -1
  157. package/dist/esm/types/components/grid/grid.component.d.ts.map +1 -1
  158. package/dist/esm/types/components/grid/index.d.ts +2 -0
  159. package/dist/esm/types/components/grid/index.d.ts.map +1 -0
  160. package/dist/esm/types/components/index.d.ts +22 -23
  161. package/dist/esm/types/components/index.d.ts.map +1 -1
  162. package/dist/esm/types/components/input-stepper/index.d.ts +4 -0
  163. package/dist/esm/types/components/input-stepper/index.d.ts.map +1 -0
  164. package/dist/esm/types/components/input-stepper/input-stepper-skeleton.d.ts +1 -1
  165. package/dist/esm/types/components/input-stepper/input-stepper-skeleton.d.ts.map +1 -1
  166. package/dist/esm/types/components/input-stepper/input-stepper.component.d.ts +1 -1
  167. package/dist/esm/types/components/input-stepper/input-stepper.component.d.ts.map +1 -1
  168. package/dist/esm/types/components/link-field/index.d.ts +2 -0
  169. package/dist/esm/types/components/link-field/index.d.ts.map +1 -0
  170. package/dist/esm/types/components/link-field/link-field.component.d.ts +1 -1
  171. package/dist/esm/types/components/link-field/link-field.component.d.ts.map +1 -1
  172. package/dist/esm/types/components/modal/index.d.ts +2 -2
  173. package/dist/esm/types/components/modal/index.d.ts.map +1 -1
  174. package/dist/esm/types/components/modal/modal-card.component.d.ts +1 -1
  175. package/dist/esm/types/components/modal/modal-card.component.d.ts.map +1 -1
  176. package/dist/esm/types/components/modal/modal.component.d.ts +1 -1
  177. package/dist/esm/types/components/modal/modal.component.d.ts.map +1 -1
  178. package/dist/esm/types/components/money-field/index.d.ts +2 -0
  179. package/dist/esm/types/components/money-field/index.d.ts.map +1 -0
  180. package/dist/esm/types/components/money-field/money-field.component.d.ts +1 -1
  181. package/dist/esm/types/components/money-field/money-field.component.d.ts.map +1 -1
  182. package/dist/esm/types/components/phone-number-field/index.d.ts +2 -0
  183. package/dist/esm/types/components/phone-number-field/index.d.ts.map +1 -0
  184. package/dist/esm/types/components/phone-number-field/phone-number-field.component.d.ts +1 -1
  185. package/dist/esm/types/components/phone-number-field/phone-number-field.component.d.ts.map +1 -1
  186. package/dist/esm/types/components/pin/index.d.ts +3 -0
  187. package/dist/esm/types/components/pin/index.d.ts.map +1 -0
  188. package/dist/esm/types/components/pin/pin.component.d.ts +1 -1
  189. package/dist/esm/types/components/pin/pin.component.d.ts.map +1 -1
  190. package/dist/esm/types/components/search-dropdown/index.d.ts +2 -0
  191. package/dist/esm/types/components/search-dropdown/index.d.ts.map +1 -0
  192. package/dist/esm/types/components/search-dropdown/search-dropdown.component.d.ts +1 -1
  193. package/dist/esm/types/components/search-dropdown/search-dropdown.component.d.ts.map +1 -1
  194. package/dist/esm/types/components/search-field/index.d.ts +2 -0
  195. package/dist/esm/types/components/search-field/index.d.ts.map +1 -0
  196. package/dist/esm/types/components/search-field/search-field.component.d.ts +1 -1
  197. package/dist/esm/types/components/search-field/search-field.component.d.ts.map +1 -1
  198. package/dist/esm/types/components/switch/index.d.ts +3 -0
  199. package/dist/esm/types/components/switch/index.d.ts.map +1 -0
  200. package/dist/esm/types/components/switch/switch-content.component.d.ts +1 -1
  201. package/dist/esm/types/components/switch/switch-content.component.d.ts.map +1 -1
  202. package/dist/esm/types/components/switch/switch.component.d.ts +1 -1
  203. package/dist/esm/types/components/switch/switch.component.d.ts.map +1 -1
  204. package/dist/esm/types/components/tab/index.d.ts +3 -0
  205. package/dist/esm/types/components/tab/index.d.ts.map +1 -0
  206. package/dist/esm/types/components/tab/tab.component.d.ts +1 -1
  207. package/dist/esm/types/components/tab/tab.component.d.ts.map +1 -1
  208. package/dist/esm/types/components/text-area/index.d.ts +2 -0
  209. package/dist/esm/types/components/text-area/index.d.ts.map +1 -0
  210. package/dist/esm/types/components/text-area/text-area.component.d.ts +1 -1
  211. package/dist/esm/types/components/text-area/text-area.component.d.ts.map +1 -1
  212. package/dist/esm/types/components/text-field/index.d.ts +2 -0
  213. package/dist/esm/types/components/text-field/index.d.ts.map +1 -0
  214. package/dist/esm/types/components/text-field/text-field.component.d.ts +1 -1
  215. package/dist/esm/types/components/text-field/text-field.component.d.ts.map +1 -1
  216. package/dist/esm/types/components/typography/typography-limit-one-line.component.d.ts +1 -1
  217. package/dist/esm/types/components/typography/typography-limit-one-line.component.d.ts.map +1 -1
  218. package/dist/esm/types/components/uploader/index.d.ts +3 -0
  219. package/dist/esm/types/components/uploader/index.d.ts.map +1 -0
  220. package/dist/esm/types/components/uploader/uploader-item.component.d.ts +1 -1
  221. package/dist/esm/types/components/uploader/uploader-item.component.d.ts.map +1 -1
  222. package/dist/esm/types/components/uploader/uploader.component.d.ts +1 -1
  223. package/dist/esm/types/components/uploader/uploader.component.d.ts.map +1 -1
  224. package/package.json +1 -1
  225. package/dist/cjs/types/components/bread-cumbs/bread-crumbs.component.d.ts +0 -21
  226. package/dist/cjs/types/components/bread-cumbs/bread-crumbs.component.d.ts.map +0 -1
  227. package/dist/esm/types/components/bread-cumbs/bread-crumbs.component.d.ts +0 -21
  228. package/dist/esm/types/components/bread-cumbs/bread-crumbs.component.d.ts.map +0 -1
  229. package/dist/types/components/avatar/avatar-group.component.d.ts +0 -20
  230. package/dist/types/components/avatar/avatar-group.component.d.ts.map +0 -1
  231. package/dist/types/components/avatar/avatar-label-group.component.d.ts +0 -11
  232. package/dist/types/components/avatar/avatar-label-group.component.d.ts.map +0 -1
  233. package/dist/types/components/avatar/avatar-profile.component.d.ts +0 -4
  234. package/dist/types/components/avatar/avatar-profile.component.d.ts.map +0 -1
  235. package/dist/types/components/avatar/avatar-user.component.d.ts +0 -14
  236. package/dist/types/components/avatar/avatar-user.component.d.ts.map +0 -1
  237. package/dist/types/components/avatar/avatar.component.d.ts +0 -20
  238. package/dist/types/components/avatar/avatar.component.d.ts.map +0 -1
  239. package/dist/types/components/avatar/avatar.constant.d.ts +0 -35
  240. package/dist/types/components/avatar/avatar.constant.d.ts.map +0 -1
  241. package/dist/types/components/avatar/avatar.interface.d.ts +0 -28
  242. package/dist/types/components/avatar/avatar.interface.d.ts.map +0 -1
  243. package/dist/types/components/bread-cumbs/bread-crumbs.component.d.ts +0 -21
  244. package/dist/types/components/bread-cumbs/bread-crumbs.component.d.ts.map +0 -1
  245. package/dist/types/components/button/button.component.d.ts +0 -38
  246. package/dist/types/components/button/button.component.d.ts.map +0 -1
  247. package/dist/types/components/button/button.constants.d.ts +0 -33
  248. package/dist/types/components/button/button.constants.d.ts.map +0 -1
  249. package/dist/types/components/button-bar/button-bar.component.d.ts +0 -15
  250. package/dist/types/components/button-bar/button-bar.component.d.ts.map +0 -1
  251. package/dist/types/components/checkbox/checkbox-content.component.d.ts +0 -19
  252. package/dist/types/components/checkbox/checkbox-content.component.d.ts.map +0 -1
  253. package/dist/types/components/checkbox/checkbox.component.d.ts +0 -22
  254. package/dist/types/components/checkbox/checkbox.component.d.ts.map +0 -1
  255. package/dist/types/components/checkbox/checkbox.constant.d.ts +0 -26
  256. package/dist/types/components/checkbox/checkbox.constant.d.ts.map +0 -1
  257. package/dist/types/components/chip/chip.component.d.ts +0 -15
  258. package/dist/types/components/chip/chip.component.d.ts.map +0 -1
  259. package/dist/types/components/chip/chip.constant.d.ts +0 -16
  260. package/dist/types/components/chip/chip.constant.d.ts.map +0 -1
  261. package/dist/types/components/date-field/date-field.component.d.ts +0 -23
  262. package/dist/types/components/date-field/date-field.component.d.ts.map +0 -1
  263. package/dist/types/components/date-range-picker/date-range-picker.component.d.ts +0 -25
  264. package/dist/types/components/date-range-picker/date-range-picker.component.d.ts.map +0 -1
  265. package/dist/types/components/dropdown-field/dropdown-field.component.d.ts +0 -28
  266. package/dist/types/components/dropdown-field/dropdown-field.component.d.ts.map +0 -1
  267. package/dist/types/components/grid/grid.component.d.ts +0 -11
  268. package/dist/types/components/grid/grid.component.d.ts.map +0 -1
  269. package/dist/types/components/icon/icon.element.d.ts +0 -12
  270. package/dist/types/components/icon/icon.element.d.ts.map +0 -1
  271. package/dist/types/components/icon/index.d.ts +0 -2
  272. package/dist/types/components/icon/index.d.ts.map +0 -1
  273. package/dist/types/components/image/image.element.d.ts +0 -13
  274. package/dist/types/components/image/image.element.d.ts.map +0 -1
  275. package/dist/types/components/image/image.enum.d.ts +0 -6
  276. package/dist/types/components/image/image.enum.d.ts.map +0 -1
  277. package/dist/types/components/image/index.d.ts +0 -3
  278. package/dist/types/components/image/index.d.ts.map +0 -1
  279. package/dist/types/components/index.d.ts +0 -28
  280. package/dist/types/components/index.d.ts.map +0 -1
  281. package/dist/types/components/input-stepper/input-stepper-skeleton.d.ts +0 -9
  282. package/dist/types/components/input-stepper/input-stepper-skeleton.d.ts.map +0 -1
  283. package/dist/types/components/input-stepper/input-stepper.component.d.ts +0 -37
  284. package/dist/types/components/input-stepper/input-stepper.component.d.ts.map +0 -1
  285. package/dist/types/components/input-stepper/input-stepper.constant.d.ts +0 -32
  286. package/dist/types/components/input-stepper/input-stepper.constant.d.ts.map +0 -1
  287. package/dist/types/components/link/index.d.ts +0 -3
  288. package/dist/types/components/link/index.d.ts.map +0 -1
  289. package/dist/types/components/link/link-internal.element.d.ts +0 -9
  290. package/dist/types/components/link/link-internal.element.d.ts.map +0 -1
  291. package/dist/types/components/link/link.element.d.ts +0 -8
  292. package/dist/types/components/link/link.element.d.ts.map +0 -1
  293. package/dist/types/components/link-field/link-field.component.d.ts +0 -23
  294. package/dist/types/components/link-field/link-field.component.d.ts.map +0 -1
  295. package/dist/types/components/modal/modal-card.component.d.ts +0 -15
  296. package/dist/types/components/modal/modal-card.component.d.ts.map +0 -1
  297. package/dist/types/components/modal/modal-content.component.d.ts +0 -16
  298. package/dist/types/components/modal/modal-content.component.d.ts.map +0 -1
  299. package/dist/types/components/modal/modal.component.d.ts +0 -11
  300. package/dist/types/components/modal/modal.component.d.ts.map +0 -1
  301. package/dist/types/components/modal/modal.interface.d.ts +0 -20
  302. package/dist/types/components/modal/modal.interface.d.ts.map +0 -1
  303. package/dist/types/components/money-field/money-field.component.d.ts +0 -24
  304. package/dist/types/components/money-field/money-field.component.d.ts.map +0 -1
  305. package/dist/types/components/phone-number-field/phone-number-field.component.d.ts +0 -28
  306. package/dist/types/components/phone-number-field/phone-number-field.component.d.ts.map +0 -1
  307. package/dist/types/components/pin/pin.component.d.ts +0 -23
  308. package/dist/types/components/pin/pin.component.d.ts.map +0 -1
  309. package/dist/types/components/pin/pin.constant.d.ts +0 -25
  310. package/dist/types/components/pin/pin.constant.d.ts.map +0 -1
  311. package/dist/types/components/search-dropdown/search-dropdown.component.d.ts +0 -30
  312. package/dist/types/components/search-dropdown/search-dropdown.component.d.ts.map +0 -1
  313. package/dist/types/components/search-field/search-field.component.d.ts +0 -14
  314. package/dist/types/components/search-field/search-field.component.d.ts.map +0 -1
  315. package/dist/types/components/switch/switch-content.component.d.ts +0 -13
  316. package/dist/types/components/switch/switch-content.component.d.ts.map +0 -1
  317. package/dist/types/components/switch/switch.component.d.ts +0 -12
  318. package/dist/types/components/switch/switch.component.d.ts.map +0 -1
  319. package/dist/types/components/tab/tab.component.d.ts +0 -22
  320. package/dist/types/components/tab/tab.component.d.ts.map +0 -1
  321. package/dist/types/components/tab/tab.constant.d.ts +0 -15
  322. package/dist/types/components/tab/tab.constant.d.ts.map +0 -1
  323. package/dist/types/components/text-area/text-area.component.d.ts +0 -22
  324. package/dist/types/components/text-area/text-area.component.d.ts.map +0 -1
  325. package/dist/types/components/text-field/text-field.component.d.ts +0 -21
  326. package/dist/types/components/text-field/text-field.component.d.ts.map +0 -1
  327. package/dist/types/components/typography/index.d.ts +0 -2
  328. package/dist/types/components/typography/index.d.ts.map +0 -1
  329. package/dist/types/components/typography/typography-limit-one-line.component.d.ts +0 -9
  330. package/dist/types/components/typography/typography-limit-one-line.component.d.ts.map +0 -1
  331. package/dist/types/components/uploader/uploader-item.component.d.ts +0 -17
  332. package/dist/types/components/uploader/uploader-item.component.d.ts.map +0 -1
  333. package/dist/types/components/uploader/uploader-item.styles.d.ts +0 -53
  334. package/dist/types/components/uploader/uploader-item.styles.d.ts.map +0 -1
  335. package/dist/types/components/uploader/uploader.component.d.ts +0 -48
  336. package/dist/types/components/uploader/uploader.component.d.ts.map +0 -1
  337. package/dist/types/constants/apps.data.d.ts +0 -7
  338. package/dist/types/constants/apps.data.d.ts.map +0 -1
  339. package/dist/types/constants/color.constant.d.ts +0 -105
  340. package/dist/types/constants/color.constant.d.ts.map +0 -1
  341. package/dist/types/constants/index.d.ts +0 -5
  342. package/dist/types/constants/index.d.ts.map +0 -1
  343. package/dist/types/constants/style.constant.d.ts +0 -58
  344. package/dist/types/constants/style.constant.d.ts.map +0 -1
  345. package/dist/types/constants/typography.constant.d.ts +0 -710
  346. package/dist/types/constants/typography.constant.d.ts.map +0 -1
  347. package/dist/types/index.d.ts +0 -5
  348. package/dist/types/index.d.ts.map +0 -1
  349. package/dist/types/styles/index.d.ts +0 -2
  350. package/dist/types/styles/index.d.ts.map +0 -1
  351. package/dist/types/styles/stack.style.d.ts +0 -54
  352. package/dist/types/styles/stack.style.d.ts.map +0 -1
  353. package/dist/types/types/index.d.ts +0 -1
  354. package/dist/types/types/index.d.ts.map +0 -1
  355. package/dist/types/utils/index.d.ts +0 -2
  356. package/dist/types/utils/index.d.ts.map +0 -1
package/dist/esm/index.js CHANGED
@@ -1,26 +1,26 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
- import { Stack, TableCell, tableCellClasses, LinearProgress, linearProgressClasses, useTheme, Skeleton, Box, Icon, Typography, Link, CircularProgress, Button, Dialog, DialogContent, DialogActions, styled as styled$1, Autocomplete, Switch } from '@mui/material';
3
- import React, { useState } from 'react';
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
4
  import { styled } from '@mui/material/styles';
5
5
  import LinkIcon from '@mui/icons-material/Link';
6
6
  import CheckIcon from '@mui/icons-material/Check';
7
7
  import RemoveIcon from '@mui/icons-material/Remove';
8
8
  import FiberManualRecordIcon from '@mui/icons-material/FiberManualRecord';
9
- import '@mui/x-date-pickers/DatePicker';
10
- import '@mui/x-date-pickers/LocalizationProvider';
11
- import '@mui/x-date-pickers/AdapterDayjs';
12
- import 'dayjs';
13
- import '@mui/icons-material/Add';
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
14
  import MuiTextField from '@mui/material/TextField';
15
15
  import { Form } from 'formik';
16
16
  import Slider from 'react-slick';
17
17
  import 'slick-carousel/slick/slick.css';
18
18
  import 'slick-carousel/slick/slick-theme.css';
19
- import '@mui/icons-material/AttachMoney';
20
- import '@mui/icons-material/Search';
21
- import 'framer-motion';
22
- import '@mui/icons-material/CheckCircle';
23
- import '@mui/icons-material/Refresh';
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
24
 
25
25
  const AVATAR_SIZES = {
26
26
  xs: 24,
@@ -225,13 +225,13 @@ const TEXT_FIELD = {
225
225
  FONT_SIZE_TITLE: 18,
226
226
  FONT_SIZE_CAPTION: 10,
227
227
  };
228
- const FONT_SIZE_ICON = {
228
+ const FONT_SIZE_ICON$1 = {
229
229
  large: '22px',
230
230
  xl: '20px',
231
231
  medium: '19px',
232
232
  small: '12px',
233
233
  };
234
- const FONT_SIZE_LOADING = {
234
+ const FONT_SIZE_LOADING$1 = {
235
235
  large: 40,
236
236
  medium: 22.5,
237
237
  small: 16,
@@ -271,8 +271,8 @@ var style_constant = /*#__PURE__*/Object.freeze({
271
271
  BORDER_RADIUS_ELEMENT_SMALL: BORDER_RADIUS_ELEMENT_SMALL,
272
272
  BORDER_RADIUS_ELEMENT_TAG: BORDER_RADIUS_ELEMENT_TAG,
273
273
  BORDER_RADIUS_ELEMENT_WRAPPER: BORDER_RADIUS_ELEMENT_WRAPPER,
274
- FONT_SIZE_ICON: FONT_SIZE_ICON,
275
- FONT_SIZE_LOADING: FONT_SIZE_LOADING,
274
+ FONT_SIZE_ICON: FONT_SIZE_ICON$1,
275
+ FONT_SIZE_LOADING: FONT_SIZE_LOADING$1,
276
276
  GAP_ICON_CONTENT_BY_SIZE: GAP_ICON_CONTENT_BY_SIZE,
277
277
  HEIGHT_DEFAULT_TEXT_FIELD_BUTTON: HEIGHT_DEFAULT_TEXT_FIELD_BUTTON,
278
278
  HEIGHT_ELEMENT_OTHER: HEIGHT_ELEMENT_OTHER,
@@ -908,7 +908,7 @@ styled(Stack)(() => ({
908
908
  alignItems: 'center',
909
909
  justifyContent: 'center',
910
910
  }));
911
- styled(Stack)(() => ({
911
+ const StackRowAlignCenterJustEnd = styled(Stack)(() => ({
912
912
  flexDirection: 'row',
913
913
  alignItems: 'center',
914
914
  justifyContent: 'flex-end',
@@ -921,7 +921,7 @@ styled(Stack)(() => ({
921
921
  flexDirection: 'row',
922
922
  justifyContent: 'space-between',
923
923
  }));
924
- styled(Stack)(() => ({
924
+ const StackRowAlignCenterJustBetween = styled(Stack)(() => ({
925
925
  flexDirection: 'row',
926
926
  alignItems: 'center',
927
927
  justifyContent: 'space-between',
@@ -1120,7 +1120,7 @@ const IconElement = ({ icon, size = 'medium', color, disabled, onClick, sx, fill
1120
1120
  };
1121
1121
  return (jsx(Icon, { onClick: onClick, color: color, sx: {
1122
1122
  cursor: 'inherit',
1123
- fontSize: FONT_SIZE_ICON[size],
1123
+ fontSize: FONT_SIZE_ICON$1[size],
1124
1124
  fontVariationSettings: `'FILL' ${fill}, 'wght' 100, 'GRAD' 200, 'opsz' 24`,
1125
1125
  ...sx,
1126
1126
  }, component: 'span', className: "material-symbols-rounded", children: icon }));
@@ -1200,6 +1200,60 @@ const AvatarUserComponent = ({ title, description, descriptionHref, onDescriptio
1200
1200
  }, children: [jsx(LinkIcon, { sx: { fontSize: 16, color: descriptionColor } }), description] }))] })] }));
1201
1201
  };
1202
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
+
1203
1257
  /** Shade values mapping */
1204
1258
  const SHADE_VALUES = {
1205
1259
  light: 100,
@@ -1340,6 +1394,17 @@ const ButtonComponent = ({ variant = 'solid', color = 'brand', shade = 'dark', s
1340
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] })) }));
1341
1395
  };
1342
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
+
1343
1408
  const CHECKBOX_COLORS = {
1344
1409
  default: {
1345
1410
  border: '#D0D5DD',
@@ -1503,6 +1568,363 @@ const CheckboxContentComponent = ({ checked = false, disabled = false, title, co
1503
1568
  }, children: content }))] })] }));
1504
1569
  };
1505
1570
 
1571
+ const CHIP_ICON_SIZE = {
1572
+ small: '16px',
1573
+ medium: '18px',
1574
+ large: '22px',
1575
+ };
1576
+ const CHIP_LABEL_PADDING = {
1577
+ WITH_ICON_LEFT: '4px 8px 4px 4px',
1578
+ WITH_ICON_RIGHT: '4px 4px 4px 8px',
1579
+ NO_ICON: '4px 8px',
1580
+ };
1581
+ const CHIP_SIZE_CONFIG = {
1582
+ small: {
1583
+ height: 24,
1584
+ fontSize: '12px',
1585
+ borderRadius: '12px',
1586
+ iconSize: '16px',
1587
+ },
1588
+ medium: {
1589
+ height: 32,
1590
+ fontSize: '14px',
1591
+ borderRadius: '16px',
1592
+ iconSize: '18px',
1593
+ },
1594
+ large: {
1595
+ height: 40,
1596
+ fontSize: '16px',
1597
+ borderRadius: '20px',
1598
+ iconSize: '22px',
1599
+ },
1600
+ };
1601
+
1602
+ const getLabelPadding = (hasIcon, position) => {
1603
+ if (!hasIcon)
1604
+ return CHIP_LABEL_PADDING.NO_ICON;
1605
+ return position === 'left' ? CHIP_LABEL_PADDING.WITH_ICON_LEFT : CHIP_LABEL_PADDING.WITH_ICON_RIGHT;
1606
+ };
1607
+ const ChipIcon = ({ icon, size, sxIcon }) => (jsx(Box, { sx: {
1608
+ display: 'inline-flex',
1609
+ alignItems: 'center',
1610
+ justifyContent: 'center',
1611
+ borderRadius: '50%',
1612
+ padding: '2px',
1613
+ '& svg': {
1614
+ width: size,
1615
+ height: size,
1616
+ display: 'block',
1617
+ },
1618
+ ...sxIcon,
1619
+ }, children: icon }));
1620
+ const ChipComponent = ({ label, onAction, icon, disabled = false, clickable = true, sx, sxIcon, iconPosition = 'right', size = 'medium', }) => {
1621
+ const sizeConfig = CHIP_SIZE_CONFIG[size];
1622
+ const hasIcon = Boolean(icon);
1623
+ 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: {
1624
+ height: sizeConfig.height,
1625
+ fontSize: sizeConfig.fontSize,
1626
+ borderRadius: sizeConfig.borderRadius,
1627
+ cursor: clickable ? 'pointer' : 'default',
1628
+ backgroundColor: 'transparent',
1629
+ border: '1px solid #D1D5DB',
1630
+ '& .MuiChip-label': {
1631
+ padding: getLabelPadding(hasIcon, iconPosition),
1632
+ display: 'flex',
1633
+ alignItems: 'center',
1634
+ },
1635
+ '& .MuiChip-label svg': {
1636
+ flexShrink: 0,
1637
+ color: '#4B5563',
1638
+ },
1639
+ '&.Mui-disabled': {
1640
+ opacity: 0.5,
1641
+ color: '#9E9E9E',
1642
+ },
1643
+ ...sx,
1644
+ } }));
1645
+ };
1646
+
1647
+ 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 }) => {
1648
+ // Convert string to Dayjs if needed
1649
+ const dayjsValue = value && typeof value === 'string' ? dayjs(value, format) : value instanceof dayjs ? value : null;
1650
+ const handleDateChange = (date) => {
1651
+ onChange?.(date);
1652
+ };
1653
+ // Disable past dates function
1654
+ const shouldDisableDate = (date) => {
1655
+ if (!disablePastDates)
1656
+ return false;
1657
+ return date.isBefore(dayjs(), 'day');
1658
+ };
1659
+ return (jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Typography, { sx: {
1660
+ display: 'block',
1661
+ ...TYPOGRAPHY.textFieldLabel,
1662
+ color: COLOR_GRAY[800],
1663
+ marginBottom: '4px',
1664
+ }, children: label })), jsx(LocalizationProvider, { dateAdapter: AdapterDayjs, adapterLocale: locale, children: jsx(DatePicker, { value: dayjsValue, onChange: handleDateChange, disabled: disabled, format: format, shouldDisableDate: shouldDisableDate, slotProps: {
1665
+ textField: {
1666
+ placeholder,
1667
+ error: error || false,
1668
+ helperText: error ? errorMessage : helperText,
1669
+ size: 'small',
1670
+ fullWidth: true,
1671
+ disabled: disabled,
1672
+ },
1673
+ openPickerButton: {
1674
+ size: 'small',
1675
+ },
1676
+ }, slots: {
1677
+ openPickerIcon: (props) => jsx(IconElement, { icon: "calendar_today", ...props }),
1678
+ }, sx: {
1679
+ width: '100%',
1680
+ '& .MuiPickersInputBase-root': {
1681
+ borderRadius: borderRadius === 'max' ? '100px' : `${borderRadius}px`,
1682
+ '& fieldset': { borderColor: COLOR_NEUTRAL[300] },
1683
+ '&:hover fieldset': { borderColor: COLOR_NEUTRAL[400] },
1684
+ '&.Mui-focused fieldset': { borderColor: COLOR_NEUTRAL[300], borderWidth: '2px' },
1685
+ '&.Mui-focused': {
1686
+ boxShadow: '0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px #FEE4E2',
1687
+ },
1688
+ '&.Mui-disabled': {
1689
+ backgroundColor: COLOR_NEUTRAL[100],
1690
+ '& fieldset': { borderColor: COLOR_NEUTRAL[200] },
1691
+ '& input': { color: COLOR_NEUTRAL[400], WebkitTextFillColor: COLOR_NEUTRAL[400] },
1692
+ },
1693
+ '&.Mui-error fieldset': { borderColor: COLOR_ERROR[500] },
1694
+ '&.Mui-error.Mui-focused fieldset': { borderColor: COLOR_ERROR[500], borderWidth: '2px' },
1695
+ '&.Mui-error.Mui-focused': {
1696
+ boxShadow: `0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px rgba(255, 66, 79, 0.15)`,
1697
+ },
1698
+ ...(success && {
1699
+ '&.Mui-focused': {
1700
+ boxShadow: `0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px ${COLOR_SUCCESS[100]}`,
1701
+ },
1702
+ }),
1703
+ },
1704
+ '& .MuiInputBase-input': {
1705
+ ...TYPOGRAPHY.text14Regular,
1706
+ padding: '12px 8px',
1707
+ color: COLOR_GRAY[900],
1708
+ '&::placeholder': { color: COLOR_NEUTRAL[400], opacity: 0.7 },
1709
+ },
1710
+ }, ...props }) }), success && !error && successMessage && (jsx(Typography, { sx: {
1711
+ ...TYPOGRAPHY.textFieldHelper,
1712
+ color: COLOR_SUCCESS[500],
1713
+ marginTop: '4px',
1714
+ }, children: successMessage }))] }));
1715
+ };
1716
+
1717
+ 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 }) => {
1718
+ // Convert string to Dayjs if needed
1719
+ const dayjsFromDate = fromDate && typeof fromDate === 'string' ? dayjs(fromDate, format) : fromDate instanceof dayjs ? fromDate : null;
1720
+ const dayjsToDate = toDate && typeof toDate === 'string' ? dayjs(toDate, format) : toDate instanceof dayjs ? toDate : null;
1721
+ // State for picker
1722
+ const [pickerOpen, setPickerOpen] = useState(false);
1723
+ const [selectingPhase, setSelectingPhase] = useState('from');
1724
+ const inputRef = useRef(null);
1725
+ // Disable past dates function
1726
+ const shouldDisableDate = (date) => {
1727
+ if (!disablePastDates)
1728
+ return false;
1729
+ return date.isBefore(dayjs(), 'day');
1730
+ };
1731
+ const handleInputClick = () => {
1732
+ setPickerOpen(true);
1733
+ // Only reset to 'from' if both dates are empty (fresh start)
1734
+ if (!dayjsFromDate && !dayjsToDate) {
1735
+ setSelectingPhase('from');
1736
+ }
1737
+ };
1738
+ const handleDateChange = (date) => {
1739
+ if (selectingPhase === 'from') {
1740
+ onChange?.([date, dayjsToDate]);
1741
+ if (date) {
1742
+ // Auto switch to toDate selection
1743
+ setSelectingPhase('to');
1744
+ }
1745
+ }
1746
+ else {
1747
+ onChange?.([dayjsFromDate, date]);
1748
+ // Keep picker open for user to potentially change toDate
1749
+ }
1750
+ };
1751
+ return (jsx(LocalizationProvider, { dateAdapter: AdapterDayjs, adapterLocale: locale, children: jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Typography, { sx: {
1752
+ display: 'block',
1753
+ ...TYPOGRAPHY.textFieldLabel,
1754
+ color: COLOR_GRAY[800],
1755
+ marginBottom: '4px',
1756
+ }, children: label })), jsxs(Box, { ref: inputRef, onClick: !disabled ? handleInputClick : undefined, sx: {
1757
+ display: 'flex',
1758
+ alignItems: 'center',
1759
+ gap: '12px',
1760
+ padding: '12px 8px',
1761
+ borderRadius: borderRadius === 'max' ? '100px' : `${borderRadius}px`,
1762
+ border: `1px solid ${error ? COLOR_ERROR[500] : COLOR_NEUTRAL[300]}`,
1763
+ backgroundColor: disabled ? COLOR_NEUTRAL[100] : 'white',
1764
+ cursor: disabled ? 'default' : 'pointer',
1765
+ transition: 'all 0.2s ease',
1766
+ ...(disabled
1767
+ ? {}
1768
+ : {
1769
+ '&:hover': {
1770
+ borderColor: error ? COLOR_ERROR[500] : COLOR_NEUTRAL[400],
1771
+ },
1772
+ }),
1773
+ }, children: [jsxs(Typography, { sx: {
1774
+ flex: 1,
1775
+ ...TYPOGRAPHY.text14Regular,
1776
+ color: dayjsFromDate || dayjsToDate ? COLOR_GRAY[900] : COLOR_NEUTRAL[400],
1777
+ }, children: [dayjsFromDate ? dayjsFromDate.format(format) : format, " \u2192", ' ', dayjsToDate ? dayjsToDate.format(format) : format] }), jsx(Box, { sx: {
1778
+ display: 'flex',
1779
+ alignItems: 'center',
1780
+ justifyContent: 'center',
1781
+ width: '24px',
1782
+ height: '24px',
1783
+ color: COLOR_NEUTRAL[400],
1784
+ }, 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: {
1785
+ textField: {
1786
+ hidden: true,
1787
+ size: 'small',
1788
+ sx: {
1789
+ display: 'none',
1790
+ },
1791
+ },
1792
+ popper: {
1793
+ anchorEl: inputRef.current,
1794
+ placement: 'bottom-start',
1795
+ },
1796
+ } }), helperText && !error && !success && (jsx(Typography, { sx: {
1797
+ ...TYPOGRAPHY.textFieldHelper,
1798
+ color: COLOR_NEUTRAL[400],
1799
+ marginTop: '4px',
1800
+ }, children: helperText })), error && errorMessage && (jsx(Typography, { sx: {
1801
+ ...TYPOGRAPHY.textFieldHelper,
1802
+ color: COLOR_ERROR[500],
1803
+ marginTop: '4px',
1804
+ }, children: errorMessage })), success && !error && successMessage && (jsx(Typography, { sx: {
1805
+ ...TYPOGRAPHY.textFieldHelper,
1806
+ color: COLOR_SUCCESS[500],
1807
+ marginTop: '4px',
1808
+ }, children: successMessage }))] }) }));
1809
+ };
1810
+
1811
+ 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, }) => {
1812
+ const borderRadiusValue = borderRadius === 'max' ? '100px' : `${borderRadius}px`;
1813
+ const selectedOption = useMemo(() => options.find((opt) => opt.value === value), [options, value]);
1814
+ const getHelperText = useCallback(() => {
1815
+ if (error && errorMessage)
1816
+ return errorMessage;
1817
+ if (success && successMessage)
1818
+ return successMessage;
1819
+ if (helperText)
1820
+ return helperText;
1821
+ return '';
1822
+ }, [error, errorMessage, success, successMessage, helperText]);
1823
+ const getHelperTextColor = useCallback(() => {
1824
+ if (error)
1825
+ return COLOR_ERROR[500];
1826
+ if (success)
1827
+ return COLOR_SUCCESS[500];
1828
+ return COLOR_NEUTRAL[400];
1829
+ }, [error, success]);
1830
+ const getBorderColor = useCallback(() => {
1831
+ if (error)
1832
+ return COLOR_ERROR[500];
1833
+ if (success)
1834
+ return COLOR_SUCCESS[500];
1835
+ return COLOR_NEUTRAL[300];
1836
+ }, [error, success]);
1837
+ const selectSx = useMemo(() => ({
1838
+ '& .MuiOutlinedInput-root': {
1839
+ borderRadius: borderRadiusValue,
1840
+ backgroundColor: disabled ? COLOR_NEUTRAL[100] : 'white',
1841
+ transition: 'all 0.2s ease',
1842
+ '& fieldset': {
1843
+ borderColor: getBorderColor(),
1844
+ },
1845
+ '&:hover fieldset': {
1846
+ borderColor: disabled ? getBorderColor() : error ? COLOR_ERROR[500] : COLOR_NEUTRAL[400],
1847
+ },
1848
+ '&.Mui-focused fieldset': {
1849
+ borderColor: error ? COLOR_ERROR[500] : COLOR_NEUTRAL[400],
1850
+ borderWidth: '1.5px',
1851
+ },
1852
+ },
1853
+ '& .MuiOutlinedInput-input': {
1854
+ padding: '12px 14px',
1855
+ color: COLOR_GRAY[900],
1856
+ '&::placeholder': {
1857
+ color: COLOR_NEUTRAL[400],
1858
+ opacity: 1,
1859
+ },
1860
+ },
1861
+ }), [borderRadiusValue, disabled, error, getBorderColor]);
1862
+ return (jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Typography, { sx: {
1863
+ display: 'block',
1864
+ ...TYPOGRAPHY.textFieldLabel,
1865
+ color: COLOR_GRAY[800],
1866
+ marginBottom: '4px',
1867
+ }, children: label })), jsx(Select, { fullWidth: true, value: value || '', onChange: (e) => {
1868
+ const selectedValue = e.target.value;
1869
+ const matchedOption = options.find((opt) => String(opt.value) === String(selectedValue));
1870
+ if (matchedOption) {
1871
+ onChange?.(matchedOption.value);
1872
+ }
1873
+ }, disabled: disabled, displayEmpty: true, MenuProps: {
1874
+ disableScrollLock: true,
1875
+ }, renderValue: () => {
1876
+ if (!value) {
1877
+ return (jsx(Box, { sx: { color: COLOR_NEUTRAL[400], display: 'flex', alignItems: 'center', gap: '8px' }, children: placeholder }));
1878
+ }
1879
+ return (jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: '8px' }, children: [selectedOption?.statusIndicator && (jsx(Box, { sx: {
1880
+ width: '8px',
1881
+ height: '8px',
1882
+ borderRadius: '50%',
1883
+ backgroundColor: '#4CAF50',
1884
+ } })), selectedOption?.avatar && (jsx(Avatar, { src: selectedOption.avatar, sx: {
1885
+ width: '24px',
1886
+ height: '24px',
1887
+ fontSize: '12px',
1888
+ } })), selectedOption?.icon && jsx(IconElement, { icon: selectedOption.icon }), jsx(Typography, { sx: { color: COLOR_GRAY[900], ...TYPOGRAPHY.text14Regular }, children: selectedOption?.label })] }));
1889
+ }, 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: {
1890
+ width: '8px',
1891
+ height: '8px',
1892
+ borderRadius: '50%',
1893
+ backgroundColor: '#4CAF50',
1894
+ } })), option.avatar && (jsx(Avatar, { src: option.avatar, sx: {
1895
+ width: '24px',
1896
+ height: '24px',
1897
+ fontSize: '12px',
1898
+ } })), 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: {
1899
+ color: getHelperTextColor(),
1900
+ marginTop: '4px',
1901
+ ...TYPOGRAPHY.textFieldHelper,
1902
+ }, children: getHelperText() }))] }));
1903
+ };
1904
+
1905
+ const BACKGROUND_COLOR_GRID = '#FFFFFF';
1906
+ const COLOR_CONTENT_GRID = '#27272A';
1907
+ const BORDER_RADIUS_GRID_CONTAINER = 8;
1908
+ const BORDER_RADIUS_GRID = 4;
1909
+ const GridComponent = ({ sx = {}, sxContainer = {}, content = 'Grids', children, }) => {
1910
+ return (jsxs(Stack, { sx: {
1911
+ bgcolor: BACKGROUND_COLOR_GRID,
1912
+ p: BORDER_RADIUS_GRID_CONTAINER,
1913
+ borderRadius: BORDER_RADIUS_GRID_CONTAINER,
1914
+ gap: BORDER_RADIUS_GRID,
1915
+ ...sx,
1916
+ }, children: [content && (jsx(Typography, { sx: {
1917
+ color: COLOR_CONTENT_GRID,
1918
+ ...TYPOGRAPHY_STYLES.lg.bold,
1919
+ }, children: content })), jsx(Container, { maxWidth: false, sx: {
1920
+ bgcolor: BACKGROUND_COLOR_GRID,
1921
+ borderRadius: BORDER_RADIUS_GRID,
1922
+ minHeight: 400,
1923
+ boxShadow: '0 0 8px -4px rgba(16, 24, 40, 0.3)',
1924
+ ...sxContainer,
1925
+ }, children: children })] }));
1926
+ };
1927
+
1506
1928
  var BorderRadius;
1507
1929
  (function (BorderRadius) {
1508
1930
  BorderRadius["SQUARE"] = "4px";
@@ -1523,6 +1945,163 @@ var ButtonSize;
1523
1945
  ButtonSize[ButtonSize["SMALL"] = 32] = "SMALL";
1524
1946
  ButtonSize[ButtonSize["MEDIUM"] = 40] = "MEDIUM";
1525
1947
  })(ButtonSize || (ButtonSize = {}));
1948
+ const Colors = {
1949
+ BORDER_COLOR_BUTTON: '#07554B',
1950
+ BORDER_COLOR_DISABLE: '#0000000D',
1951
+ HOVER_BG_COLOR: 'rgba(7, 85, 75, 0.04)',
1952
+ BACKGROUND_COLOR: '#FFFFFF',
1953
+ TEXT_COLOR_READONLY: '#27272A',
1954
+ };
1955
+ const FONT_SIZE_LOADING = {
1956
+ large: 40,
1957
+ };
1958
+ const BORDER_TEXT_FIELD_LOADING = 20;
1959
+ const FONT_SIZE_ICON = {
1960
+ small: 12,
1961
+ xl: 20,
1962
+ };
1963
+
1964
+ const InputStepperSkeleton = ({ orientation, buttonShape }) => {
1965
+ 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: {
1966
+ borderRadius: buttonShape === ShapeType.CIRCLE ? BorderRadius.CIRCLE : BorderRadius.SQUARE,
1967
+ maxHeight: FONT_SIZE_LOADING.large,
1968
+ } }), jsx(Skeleton, { width: FONT_SIZE_LOADING.large, sx: {
1969
+ borderRadius: `${BORDER_TEXT_FIELD_LOADING}px`,
1970
+ } }), jsx(Skeleton, { variant: buttonShape === ShapeType.CIRCLE ? 'circular' : 'rectangular', width: FONT_SIZE_LOADING.large, height: FONT_SIZE_LOADING.large, sx: {
1971
+ borderRadius: buttonShape === ShapeType.CIRCLE ? BorderRadius.CIRCLE : BorderRadius.SQUARE,
1972
+ maxHeight: FONT_SIZE_LOADING.large,
1973
+ } })] }));
1974
+ };
1975
+
1976
+ 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
1977
+ sxButton = {}, // style cho 2 button
1978
+ buttonShape = ShapeType.SQUARE, buttonColor, textFieldShape = ShapeType.SQUARE, decrementIcon = jsx(RemoveIcon, {}), incrementIcon = jsx(AddIcon, {}), }) => {
1979
+ const [internalValue, setInternalValue] = useState(controlledValue ?? min ?? 0);
1980
+ const value = controlledValue !== undefined ? controlledValue : internalValue;
1981
+ const updateValue = (newValue) => {
1982
+ let finalValue = newValue;
1983
+ if (min !== undefined && newValue < min)
1984
+ finalValue = min;
1985
+ if (max !== undefined && newValue > max)
1986
+ finalValue = max;
1987
+ if (controlledValue === undefined) {
1988
+ setInternalValue(finalValue);
1989
+ }
1990
+ onChange?.(finalValue);
1991
+ };
1992
+ const handleIncrement = () => {
1993
+ updateValue(Number(value) + step);
1994
+ };
1995
+ const handleDecrement = () => {
1996
+ updateValue(Number(value) - step);
1997
+ };
1998
+ const handleInputChange = (event) => {
1999
+ if (!readOnly) {
2000
+ const newValue = event.target.value === '' ? min || 0 : Number(event.target.value);
2001
+ if (!isNaN(newValue)) {
2002
+ updateValue(newValue);
2003
+ }
2004
+ }
2005
+ };
2006
+ const isDecrementDisabled = disabled || (min !== undefined && Number(value) <= min);
2007
+ const isIncrementDisabled = disabled || (max !== undefined && Number(value) >= max);
2008
+ const buttonSize = ButtonSize.MEDIUM;
2009
+ if (loading) {
2010
+ return jsx(InputStepperSkeleton, { orientation: orientation, buttonShape: buttonShape });
2011
+ }
2012
+ return (jsxs(Box, { display: "inline-flex", flexDirection: orientation === 'horizontal' ? 'row' : 'column', alignItems: "center", gap: PADDING_GAP_ITEM, sx: {
2013
+ opacity: disabled ? 0.5 : 1,
2014
+ pointerEvents: disabled ? 'none' : 'auto',
2015
+ ...sx,
2016
+ }, children: [jsx(IconButton, { onClick: handleDecrement, disabled: isDecrementDisabled, sx: {
2017
+ borderRadius: buttonShape === 'circle' ? BorderRadius.CIRCLE : BorderRadius.SQUARE,
2018
+ width: buttonSize,
2019
+ height: buttonSize,
2020
+ padding: PADDING_GAP_ITEM,
2021
+ border: isDecrementDisabled
2022
+ ? `1px solid ${Colors.BORDER_COLOR_DISABLE}`
2023
+ : `1px solid ${Colors.BORDER_COLOR_BUTTON}`,
2024
+ backgroundColor: Colors.BACKGROUND_COLOR,
2025
+ color: buttonColor || Colors.BORDER_COLOR_BUTTON,
2026
+ '&:hover': {
2027
+ backgroundColor: Colors.HOVER_BG_COLOR,
2028
+ },
2029
+ ...(isDecrementDisabled ? {} : sxButton),
2030
+ }, children: decrementIcon }), jsx(TextField, { value: value, onChange: handleInputChange, disabled: disabled, inputProps: {
2031
+ min,
2032
+ max,
2033
+ step,
2034
+ readOnly,
2035
+ }, type: "number", sx: {
2036
+ minWidth: buttonSize,
2037
+ width: sxTextField?.width || buttonSize,
2038
+ minHeight: buttonSize,
2039
+ height: sxTextField?.height || buttonSize,
2040
+ overflow: 'hidden',
2041
+ borderRadius: textFieldShape === 'circle' ? BorderRadius.CIRCLE : BorderRadius.SQUARE,
2042
+ color: readOnly ? Colors.TEXT_COLOR_READONLY : '',
2043
+ backgroundColor: readOnly ? 'transparent !important' : sxTextField?.backgroundColor,
2044
+ '& .MuiOutlinedInput-root': {
2045
+ width: '100%',
2046
+ height: '100%',
2047
+ borderRadius: 'inherit',
2048
+ '& fieldset': {
2049
+ borderColor: readOnly || disabled ? 'transparent' : sxTextField?.borderColor || Colors.BORDER_COLOR_BUTTON,
2050
+ borderWidth: readOnly || disabled ? 0 : 1,
2051
+ borderRadius: textFieldShape === 'circle' ? BorderRadius.CIRCLE : BorderRadius.SQUARE,
2052
+ },
2053
+ '&:hover fieldset': readOnly || disabled
2054
+ ? {}
2055
+ : {
2056
+ borderColor: sxTextField?.borderColorHover || Colors.BORDER_COLOR_BUTTON,
2057
+ },
2058
+ '&.Mui-focused fieldset': readOnly
2059
+ ? {
2060
+ borderColor: 'transparent',
2061
+ borderWidth: 0,
2062
+ }
2063
+ : {
2064
+ borderColor: sxTextField?.borderColorFocused || Colors.BORDER_COLOR_BUTTON,
2065
+ borderWidth: 1,
2066
+ },
2067
+ '&.Mui-disabled fieldset': {
2068
+ borderColor: Colors.BORDER_COLOR_DISABLE,
2069
+ backgroundColor: readOnly ? 'transparent' : Colors.BORDER_COLOR_DISABLE,
2070
+ },
2071
+ },
2072
+ '& input[type=number]::-webkit-outer-spin-button, & input[type=number]::-webkit-inner-spin-button': {
2073
+ WebkitAppearance: 'none',
2074
+ margin: 0,
2075
+ },
2076
+ '& input[type=number]': {
2077
+ MozAppearance: 'textfield',
2078
+ },
2079
+ '& .MuiInputBase-input': {
2080
+ textAlign: sxTextField?.textAlign || 'center',
2081
+ padding: sxTextField?.padding || '4px 8px',
2082
+ fontSize: readOnly ? '16px' : sxTextField?.fontSize || '1rem',
2083
+ cursor: readOnly ? 'not-allowed' : 'text',
2084
+ borderRadius: 'inherit',
2085
+ backgroundColor: readOnly ? 'transparent' : sxTextField?.backgroundColor || 'transparent',
2086
+ color: readOnly ? Colors.TEXT_COLOR_READONLY : sxTextField?.color || 'inherit',
2087
+ fontWeight: sxTextField?.fontWeight || (readOnly ? 700 : 'normal'),
2088
+ },
2089
+ } }), jsx(IconButton, { onClick: handleIncrement, disabled: isIncrementDisabled, sx: {
2090
+ borderRadius: buttonShape === 'circle' ? BorderRadius.CIRCLE : BorderRadius.SQUARE,
2091
+ width: buttonSize,
2092
+ height: buttonSize,
2093
+ padding: PADDING_GAP_ITEM,
2094
+ border: isIncrementDisabled
2095
+ ? `1px solid ${Colors.BORDER_COLOR_DISABLE}`
2096
+ : `1px solid ${Colors.BORDER_COLOR_BUTTON}`,
2097
+ backgroundColor: Colors.BACKGROUND_COLOR,
2098
+ color: buttonColor || Colors.BORDER_COLOR_BUTTON,
2099
+ '&:hover': {
2100
+ backgroundColor: Colors.HOVER_BG_COLOR,
2101
+ },
2102
+ ...(isIncrementDisabled ? {} : sxButton),
2103
+ }, children: incrementIcon })] }));
2104
+ };
1526
2105
 
1527
2106
  const LinkInternalElement = ({ content, onClick, sx = {} }) => {
1528
2107
  return (jsx(Typography, { onClick: onClick, sx: {
@@ -1545,7 +2124,7 @@ const LinkElement = ({ onClick, sx = {}, target = '_self', ...rest }) => {
1545
2124
  }, ...rest }));
1546
2125
  };
1547
2126
 
1548
- styled(MuiTextField)(({ theme }) => {
2127
+ const StyledTextField$3 = styled(MuiTextField)(({ theme }) => {
1549
2128
  return {
1550
2129
  '& .MuiOutlinedInput-root': {
1551
2130
  '& fieldset': { borderColor: COLOR_NEUTRAL[300] },
@@ -1587,6 +2166,57 @@ styled(MuiTextField)(({ theme }) => {
1587
2166
  },
1588
2167
  };
1589
2168
  });
2169
+ 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 }) => {
2170
+ const [validationError, setValidationError] = useState(false);
2171
+ const isValidLink = (url) => {
2172
+ if (!url)
2173
+ return true; // Empty is valid (optional field)
2174
+ try {
2175
+ const urlToTest = url.includes('://') ? url : `${protocol}${url}`;
2176
+ new URL(urlToTest);
2177
+ // Kiểm tra domain phải có dấu chấm (ít nhất là có TLD)
2178
+ const hostname = new URL(urlToTest).hostname;
2179
+ if (!hostname || !hostname.includes('.')) {
2180
+ return false;
2181
+ }
2182
+ return true;
2183
+ }
2184
+ catch {
2185
+ return false;
2186
+ }
2187
+ };
2188
+ const handleBlur = (event) => {
2189
+ const inputValue = event.target.value;
2190
+ if (inputValue && !isValidLink(inputValue)) {
2191
+ setValidationError(true);
2192
+ }
2193
+ else {
2194
+ setValidationError(false);
2195
+ }
2196
+ };
2197
+ return (jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Typography, { sx: {
2198
+ display: 'block',
2199
+ ...TYPOGRAPHY.textFieldLabel,
2200
+ color: COLOR_GRAY[800],
2201
+ marginBottom: '4px',
2202
+ }, 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: {
2203
+ startAdornment: (jsx(InputAdornment, { position: "start", children: jsx(Typography, { sx: { color: COLOR_NEUTRAL[300], ...TYPOGRAPHY.text14Regular }, children: protocol }) })),
2204
+ 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] } })) })),
2205
+ }, sx: {
2206
+ '& .MuiOutlinedInput-root': {
2207
+ borderRadius: borderRadius === 'max' ? '100px' : `${borderRadius}px`,
2208
+ ...(success && {
2209
+ '&.Mui-focused': {
2210
+ boxShadow: `0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px ${COLOR_SUCCESS[100]}`,
2211
+ },
2212
+ }),
2213
+ },
2214
+ } }), success && !error && successMessage && (jsx(Typography, { sx: {
2215
+ ...TYPOGRAPHY.textFieldHelper,
2216
+ color: COLOR_SUCCESS[500],
2217
+ marginTop: '4px',
2218
+ }, children: successMessage }))] }));
2219
+ };
1590
2220
 
1591
2221
  const MODAL_ICON_COLORS = {
1592
2222
  check_circle: '#10B981',
@@ -1696,7 +2326,15 @@ const ModalCardComponent = ({ open, isForm = false, onClose, items, nodeContent,
1696
2326
  }, 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 }) }))] }))] }) }))] }) }));
1697
2327
  };
1698
2328
 
1699
- styled(MuiTextField)(({ theme }) => {
2329
+ const CURRENCIES = ['USD', 'EUR', 'GBP', 'JPY', 'AUD', 'CAD', 'CHF', 'CNY', 'VND', 'INR'];
2330
+ // Format number with thousand separators
2331
+ const formatMoneyDisplay = (value) => {
2332
+ if (!value)
2333
+ return '';
2334
+ const numericOnly = value.replace(/\D/g, '');
2335
+ return numericOnly.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
2336
+ };
2337
+ const StyledTextField$2 = styled(MuiTextField)(({ theme }) => {
1700
2338
  return {
1701
2339
  '& .MuiOutlinedInput-root': {
1702
2340
  '& fieldset': { borderColor: COLOR_NEUTRAL[300] },
@@ -1738,8 +2376,64 @@ styled(MuiTextField)(({ theme }) => {
1738
2376
  },
1739
2377
  };
1740
2378
  });
2379
+ 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 }) => {
2380
+ const [selectedCurrency, setSelectedCurrency] = useState(currency);
2381
+ const handleCurrencyChange = (e) => {
2382
+ const newCurrency = e.target.value;
2383
+ setSelectedCurrency(newCurrency);
2384
+ onCurrencyChange?.(newCurrency);
2385
+ };
2386
+ const handleMoneyChange = (e) => {
2387
+ const rawValue = e.target.value.replace(/,/g, '');
2388
+ onChange?.({ ...e, target: { ...e.target, value: rawValue } });
2389
+ };
2390
+ return (jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Typography, { sx: {
2391
+ display: 'block',
2392
+ ...TYPOGRAPHY.textFieldLabel,
2393
+ color: COLOR_GRAY[800],
2394
+ marginBottom: '4px',
2395
+ }, 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: {
2396
+ startAdornment: (jsx(InputAdornment, { position: "start", children: iconBefore ? iconBefore : jsx(AttachMoneyIcon, { sx: { fontSize: '18px', color: COLOR_GRAY[400], mr: 0.5 } }) })),
2397
+ 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: {
2398
+ border: 'none',
2399
+ outline: 'none',
2400
+ '& .MuiSelect-standard': { border: 'none' },
2401
+ '&.MuiInput-underline:before': { borderBottom: 'none' },
2402
+ '&.MuiInput-underline:hover:before': { borderBottom: 'none' },
2403
+ '&.MuiInput-underline:after': { borderBottom: 'none' },
2404
+ minWidth: '70px',
2405
+ fontSize: '14px',
2406
+ color: COLOR_GRAY[500],
2407
+ }, children: optionCurrencies.map((curr) => (jsx(MenuItem, { value: curr, children: curr }, curr))) })] }) })),
2408
+ }, sx: {
2409
+ '& .MuiOutlinedInput-root': {
2410
+ borderRadius: borderRadius === 'max' ? '100px' : `${borderRadius}px`,
2411
+ ...(success && {
2412
+ '&.Mui-focused': {
2413
+ boxShadow: `0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px ${COLOR_SUCCESS[100]}`,
2414
+ },
2415
+ }),
2416
+ },
2417
+ } }), success && !error && successMessage && (jsx(Typography, { sx: {
2418
+ ...TYPOGRAPHY.textFieldHelper,
2419
+ color: COLOR_SUCCESS[600],
2420
+ marginTop: '4px',
2421
+ }, children: successMessage }))] }));
2422
+ };
1741
2423
 
1742
- styled(MuiTextField)(({ theme }) => {
2424
+ const COUNTRY_CODES = [
2425
+ { code: 'US', name: 'United States', flag: '🇺🇸', value: '+1' },
2426
+ { code: 'GB', name: 'United Kingdom', flag: '🇬🇧', value: '+44' },
2427
+ { code: 'CA', name: 'Canada', flag: '🇨🇦', value: '+1' },
2428
+ { code: 'AU', name: 'Australia', flag: '🇦🇺', value: '+61' },
2429
+ { code: 'VN', name: 'Vietnam', flag: '🇻🇳', value: '+84' },
2430
+ { code: 'JP', name: 'Japan', flag: '🇯🇵', value: '+81' },
2431
+ { code: 'CN', name: 'China', flag: '🇨🇳', value: '+86' },
2432
+ { code: 'IN', name: 'India', flag: '🇮🇳', value: '+91' },
2433
+ { code: 'DE', name: 'Germany', flag: '🇩🇪', value: '+49' },
2434
+ { code: 'FR', name: 'France', flag: '🇫🇷', value: '+33' },
2435
+ ];
2436
+ const StyledTextField$1 = styled(MuiTextField)(({ theme }) => {
1743
2437
  return {
1744
2438
  '& .MuiOutlinedInput-root': {
1745
2439
  '& fieldset': { borderColor: COLOR_NEUTRAL[300] },
@@ -1781,8 +2475,250 @@ styled(MuiTextField)(({ theme }) => {
1781
2475
  },
1782
2476
  };
1783
2477
  });
2478
+ 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 }) => {
2479
+ const handleCountryChange = (e) => {
2480
+ const newCode = e.target.value;
2481
+ onCountryCodeChange?.(newCode);
2482
+ };
2483
+ return (jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Typography, { sx: {
2484
+ display: 'block',
2485
+ ...TYPOGRAPHY.textFieldLabel,
2486
+ color: COLOR_GRAY[800],
2487
+ marginBottom: '4px',
2488
+ }, children: label })), jsx(StyledTextField$1, { placeholder: placeholder, value: value, disabled: disabled, error: error, helperText: error ? errorMessage : helperText, size: "small", fullWidth: true, onChange: onChange, InputProps: {
2489
+ startAdornment: (jsx(InputAdornment, { position: "start", sx: { mr: 0 }, children: jsx(Select, { value: countryCode, onChange: handleCountryChange, disabled: disabled, variant: "standard", sx: {
2490
+ border: 'none',
2491
+ outline: 'none',
2492
+ '& .MuiSelect-standard': { border: 'none' },
2493
+ '&.MuiInput-underline:before': { borderBottom: 'none' },
2494
+ '&.MuiInput-underline:hover:before': { borderBottom: 'none' },
2495
+ '&.MuiInput-underline:after': { borderBottom: 'none' },
2496
+ minWidth: '50px',
2497
+ fontSize: '14px',
2498
+ color: COLOR_GRAY[500],
2499
+ display: 'flex',
2500
+ alignItems: 'center',
2501
+ gap: 0.5,
2502
+ }, children: countries.map((c) => (jsx(MenuItem, { value: c.code, children: c.code }, c.code))) }) })),
2503
+ endAdornment: (success || error) && (jsx(InputAdornment, { position: "end", children: jsx(IconElement, { icon: error ? 'info' : 'check_circle', sx: { color: error ? COLOR_ERROR[500] : COLOR_SUCCESS[500] } }) })),
2504
+ }, sx: {
2505
+ '& .MuiOutlinedInput-root': {
2506
+ borderRadius: borderRadius === 'max' ? '100px' : `${borderRadius}px`,
2507
+ ...(success && {
2508
+ '&.Mui-focused': {
2509
+ boxShadow: `0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px ${COLOR_SUCCESS[100]}`,
2510
+ },
2511
+ }),
2512
+ },
2513
+ } }), success && !error && successMessage && (jsx(Typography, { sx: {
2514
+ ...TYPOGRAPHY.textFieldHelper,
2515
+ color: COLOR_SUCCESS[600],
2516
+ marginTop: '4px',
2517
+ }, children: successMessage }))] }));
2518
+ };
2519
+
2520
+ const PIN_SIZES = {
2521
+ sm: { width: 40, height: 40, fontSize: 18 },
2522
+ md: { width: 48, height: 48, fontSize: 20 },
2523
+ lg: { width: 56, height: 56, fontSize: 24 },
2524
+ };
2525
+ const PIN_SPACING = {
2526
+ sm: 8,
2527
+ md: 12,
2528
+ lg: 16,
2529
+ };
1784
2530
 
1785
- styled$1(Autocomplete)(({ theme }) => ({
2531
+ 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, }) => {
2532
+ const { palette } = useTheme();
2533
+ const inputRefs = useRef([]);
2534
+ useEffect(() => {
2535
+ if (autoFocus && inputRefs.current[0]) {
2536
+ inputRefs.current[0].focus();
2537
+ }
2538
+ }, [autoFocus]);
2539
+ const handleChange = (index, val) => {
2540
+ if (!/^\d*$/.test(val))
2541
+ return;
2542
+ const newValue = value.split('');
2543
+ newValue[index] = val;
2544
+ const updatedValue = newValue.join('').slice(0, length);
2545
+ onChange(updatedValue);
2546
+ if (val && index < length - 1) {
2547
+ inputRefs.current[index + 1]?.focus();
2548
+ }
2549
+ if (updatedValue.length === length) {
2550
+ onComplete?.(updatedValue);
2551
+ }
2552
+ };
2553
+ const handleKeyDown = (index, e) => {
2554
+ if (e.key === 'Backspace' && !value[index] && index > 0) {
2555
+ inputRefs.current[index - 1]?.focus();
2556
+ }
2557
+ };
2558
+ const renderPINDisplay = (index) => {
2559
+ const inputValue = value[index] || '';
2560
+ const isFilled = !!inputValue;
2561
+ const sizeStyle = PIN_SIZES[size];
2562
+ const borderColor = error ? palette.error.main : COLOR_GRAY[200];
2563
+ const borderFocusColorValue = borderFocusColor || (error ? palette.error.main : COLOR_GRAY[900]);
2564
+ if (type === 'bullet') {
2565
+ return (jsxs(Box, { sx: { position: 'relative', width: sizeStyle.width, height: sizeStyle.height }, children: [jsx(TextField, { ref: (el) => {
2566
+ const input = el?.querySelector('input');
2567
+ if (input) {
2568
+ inputRefs.current[index] = input;
2569
+ }
2570
+ }, type: "text", inputMode: "numeric", value: inputValue, onChange: (e) => handleChange(index, e.target.value), onKeyDown: (e) => handleKeyDown(index, e), disabled: disabled, error: error, sx: {
2571
+ width: '100%',
2572
+ height: '100%',
2573
+ '& .MuiOutlinedInput-root': {
2574
+ height: '100%',
2575
+ padding: 0,
2576
+ '& input': {
2577
+ textAlign: 'center',
2578
+ fontSize: sizeStyle.fontSize,
2579
+ fontWeight: 600,
2580
+ padding: 0,
2581
+ color: masked && isFilled ? 'transparent' : 'inherit',
2582
+ WebkitTextFillColor: masked && isFilled ? 'transparent' : 'unset',
2583
+ caretColor: palette.primary.main,
2584
+ '&::placeholder': {
2585
+ color: palette.action.disabled,
2586
+ opacity: 1,
2587
+ },
2588
+ },
2589
+ '& fieldset': {
2590
+ borderColor: borderColor,
2591
+ borderRadius: '8px',
2592
+ },
2593
+ '&:hover fieldset': {
2594
+ borderColor: error ? palette.error.main : borderFocusColorValue,
2595
+ },
2596
+ '&.Mui-focused fieldset': {
2597
+ borderColor: borderFocusColorValue,
2598
+ borderWidth: 1,
2599
+ },
2600
+ },
2601
+ '& input': {
2602
+ maxLength: 1,
2603
+ },
2604
+ }, placeholder: "-" }), masked && isFilled && (jsx(Box, { sx: {
2605
+ position: 'absolute',
2606
+ top: '50%',
2607
+ left: '50%',
2608
+ transform: 'translate(-50%, -50%)',
2609
+ fontSize: sizeStyle.fontSize,
2610
+ fontWeight: 600,
2611
+ color: error ? palette.error.main : palette.text.primary,
2612
+ pointerEvents: 'none',
2613
+ }, children: "\u25CF" }))] }));
2614
+ }
2615
+ if (type === 'circle') {
2616
+ return (jsxs(Box, { sx: { position: 'relative', width: sizeStyle.width, height: sizeStyle.height }, children: [jsx(TextField, { ref: (el) => {
2617
+ const input = el?.querySelector('input');
2618
+ if (input) {
2619
+ inputRefs.current[index] = input;
2620
+ }
2621
+ }, type: "text", inputMode: "numeric", value: inputValue, onChange: (e) => handleChange(index, e.target.value), onKeyDown: (e) => handleKeyDown(index, e), disabled: disabled, error: error, sx: {
2622
+ width: '100%',
2623
+ height: '100%',
2624
+ '& .MuiOutlinedInput-root': {
2625
+ height: '100%',
2626
+ padding: 0,
2627
+ borderRadius: '50%',
2628
+ '& input': {
2629
+ textAlign: 'center',
2630
+ fontSize: sizeStyle.fontSize,
2631
+ fontWeight: 600,
2632
+ padding: 0,
2633
+ color: masked && isFilled ? 'transparent' : 'inherit',
2634
+ WebkitTextFillColor: masked && isFilled ? 'transparent' : 'unset',
2635
+ caretColor: palette.primary.main,
2636
+ '&::placeholder': {
2637
+ color: palette.action.disabled,
2638
+ opacity: 1,
2639
+ },
2640
+ },
2641
+ '& fieldset': {
2642
+ borderColor: borderColor,
2643
+ borderRadius: '50%',
2644
+ },
2645
+ '&:hover fieldset': {
2646
+ borderColor: error ? palette.error.main : borderFocusColorValue,
2647
+ },
2648
+ '&.Mui-focused fieldset': {
2649
+ borderColor: borderFocusColorValue,
2650
+ borderWidth: 1,
2651
+ },
2652
+ },
2653
+ '& input': {
2654
+ maxLength: 1,
2655
+ },
2656
+ }, placeholder: "-" }), masked && isFilled && (jsx(Box, { sx: {
2657
+ position: 'absolute',
2658
+ top: '50%',
2659
+ left: '50%',
2660
+ transform: 'translate(-50%, -50%)',
2661
+ fontSize: sizeStyle.fontSize,
2662
+ fontWeight: 600,
2663
+ color: error ? palette.error.main : palette.text.primary,
2664
+ pointerEvents: 'none',
2665
+ }, children: "\u25CF" }))] }));
2666
+ }
2667
+ // Default text type
2668
+ return (jsx(TextField, { ref: (el) => {
2669
+ const input = el?.querySelector('input');
2670
+ if (input) {
2671
+ inputRefs.current[index] = input;
2672
+ }
2673
+ }, type: "text", inputMode: "numeric", value: inputValue, onChange: (e) => handleChange(index, e.target.value), onKeyDown: (e) => handleKeyDown(index, e), disabled: disabled, error: error, sx: {
2674
+ width: sizeStyle.width,
2675
+ '& .MuiOutlinedInput-root': {
2676
+ height: sizeStyle.height,
2677
+ padding: 0,
2678
+ '& input': {
2679
+ textAlign: 'center',
2680
+ fontSize: sizeStyle.fontSize,
2681
+ fontWeight: 600,
2682
+ padding: 0,
2683
+ '&::placeholder': {
2684
+ color: palette.action.disabled,
2685
+ opacity: 1,
2686
+ },
2687
+ },
2688
+ '& fieldset': {
2689
+ borderColor: borderColor,
2690
+ },
2691
+ '&:hover fieldset': {
2692
+ borderColor: error ? palette.error.main : borderFocusColorValue,
2693
+ },
2694
+ '&.Mui-focused fieldset': {
2695
+ borderColor: borderFocusColorValue,
2696
+ borderWidth: 1,
2697
+ },
2698
+ },
2699
+ '& input': {
2700
+ maxLength: 1,
2701
+ },
2702
+ }, placeholder: "-" }));
2703
+ };
2704
+ return (jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Box, { sx: {
2705
+ mb: 1,
2706
+ fontSize: 14,
2707
+ fontWeight: 500,
2708
+ color: palette.text.primary,
2709
+ }, children: label })), jsx(Box, { sx: {
2710
+ display: 'flex',
2711
+ gap: `${PIN_SPACING[spacing]}px`,
2712
+ justifyContent: align === 'center' ? 'center' : align === 'right' ? 'flex-end' : 'flex-start',
2713
+ }, children: Array.from({ length }).map((_, index) => (jsx(Box, { children: renderPINDisplay(index) }, index))) }), error && errorMessage && (jsx(Box, { sx: {
2714
+ mt: 1,
2715
+ fontSize: 12,
2716
+ color: palette.error.main,
2717
+ textAlign: align,
2718
+ }, children: errorMessage }))] }));
2719
+ };
2720
+
2721
+ const StyledAutocomplete$1 = styled$1(Autocomplete)(({ theme }) => ({
1786
2722
  '& .MuiOutlinedInput-root': {
1787
2723
  padding: '8px !important',
1788
2724
  display: 'flex',
@@ -1843,8 +2779,138 @@ styled$1(Autocomplete)(({ theme }) => ({
1843
2779
  },
1844
2780
  },
1845
2781
  }));
2782
+ 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, }) => {
2783
+ const DEBOUNCE_DELAY = 500;
2784
+ const [inputValue, setInputValue] = useState('');
2785
+ const [filteredOptions, setFilteredOptions] = useState(options);
2786
+ const [isLoading, setIsLoading] = useState(false);
2787
+ const debounceTimerRef = useRef(null);
2788
+ const onSearchRef = useRef(onSearch);
2789
+ const onInputChangeRef = useRef(onInputChange);
2790
+ const optionsRef = useRef(options);
2791
+ // Update refs when props change
2792
+ useEffect(() => {
2793
+ onSearchRef.current = onSearch;
2794
+ onInputChangeRef.current = onInputChange;
2795
+ optionsRef.current = options;
2796
+ }, [onSearch, onInputChange, options]);
2797
+ // Normalize value to array for internal state
2798
+ const selectedValues = useMemo(() => {
2799
+ if (!value)
2800
+ return [];
2801
+ const values = Array.isArray(value) ? value : [value];
2802
+ return values.map((v) => (typeof v === 'object' ? v : { label: String(v), value: v }));
2803
+ }, [value]);
2804
+ // Search logic with debounce
2805
+ useEffect(() => {
2806
+ if (debounceTimerRef.current) {
2807
+ clearTimeout(debounceTimerRef.current);
2808
+ }
2809
+ // Reset to original options when input is empty
2810
+ if (!inputValue.trim()) {
2811
+ setFilteredOptions(optionsRef.current);
2812
+ return;
2813
+ }
2814
+ debounceTimerRef.current = setTimeout(async () => {
2815
+ const searchFn = onSearchRef.current;
2816
+ if (searchFn) {
2817
+ // Async search
2818
+ setIsLoading(true);
2819
+ try {
2820
+ const results = await searchFn(inputValue);
2821
+ setFilteredOptions(results);
2822
+ }
2823
+ catch (error) {
2824
+ console.error('Search error:', error);
2825
+ setFilteredOptions([]);
2826
+ }
2827
+ finally {
2828
+ setIsLoading(false);
2829
+ }
2830
+ }
2831
+ else {
2832
+ // Local filtering
2833
+ const filtered = optionsRef.current.filter((opt) => opt.label.toLowerCase().includes(inputValue.toLowerCase()));
2834
+ setFilteredOptions(filtered);
2835
+ }
2836
+ onInputChangeRef.current?.(inputValue);
2837
+ }, DEBOUNCE_DELAY);
2838
+ return () => {
2839
+ if (debounceTimerRef.current) {
2840
+ clearTimeout(debounceTimerRef.current);
2841
+ }
2842
+ };
2843
+ }, [inputValue]);
2844
+ const handleInputChange = (event, newInputValue) => {
2845
+ setInputValue(newInputValue);
2846
+ };
2847
+ const handleChange = (event, newValue) => {
2848
+ if (multiple) {
2849
+ const result = Array.isArray(newValue) ? newValue : newValue ? [newValue] : [];
2850
+ onChange?.(result.length > 0 ? result : null);
2851
+ }
2852
+ else {
2853
+ onChange?.(newValue || null);
2854
+ }
2855
+ };
2856
+ const handleClear = () => {
2857
+ setInputValue('');
2858
+ setFilteredOptions(optionsRef.current);
2859
+ onClear?.();
2860
+ };
2861
+ return (jsxs(Box, { sx: { width: '100%', ...sx }, children: [label && (jsx(Typography, { variant: "subtitle2", sx: {
2862
+ fontWeight: 500,
2863
+ color: COLOR_GRAY[900],
2864
+ marginBottom: '6px',
2865
+ display: 'block',
2866
+ }, children: label })), jsx(StyledAutocomplete$1, { multiple: multiple, freeSolo: true, options: filteredOptions, getOptionLabel: (option) => {
2867
+ if (!option)
2868
+ return '';
2869
+ if (typeof option === 'object' && 'label' in option)
2870
+ return option.label;
2871
+ return String(option);
2872
+ }, isOptionEqualToValue: (option, val) => {
2873
+ if (!option || !val)
2874
+ return false;
2875
+ if (typeof option === 'object' && typeof val === 'object' && 'value' in option && 'value' in val) {
2876
+ return option.value === val.value;
2877
+ }
2878
+ return false;
2879
+ }, 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: {
2880
+ '& .MuiOutlinedInput-root': {
2881
+ borderRadius: borderRadius === 'max' ? '100px' : `${borderRadius}px`,
2882
+ borderColor: error ? COLOR_ERROR[500] : success ? COLOR_SUCCESS[500] : undefined,
2883
+ },
2884
+ }, renderInput: (params) => (jsx(TextField, { ...params, placeholder: placeholder, variant: "outlined", size: "small", error: error, InputProps: {
2885
+ ...params.InputProps,
2886
+ startAdornment: (jsxs(Fragment, { children: [jsx(InputAdornment, { position: "start", sx: { marginLeft: '4px', marginRight: '0px' }, children: jsx(SearchIcon, { sx: { color: '#999', fontSize: '18px' } }) }), params.InputProps?.startAdornment] })),
2887
+ } })), renderTags: (value, getTagProps) => value.map((option, index) => {
2888
+ const label = typeof option === 'object' && option && 'label' in option ? option.label : String(option);
2889
+ return jsx(Chip, { ...getTagProps({ index }), label: label, size: "small" });
2890
+ }), renderOption: (props, option) => {
2891
+ const { key, ...otherProps } = props;
2892
+ const label = option?.label || '';
2893
+ return (jsx(Box, { ...otherProps, component: "li", children: label }, key));
2894
+ }, componentsProps: {
2895
+ clearIndicator: {
2896
+ onClick: handleClear,
2897
+ },
2898
+ } }), error && errorMessage && (jsx(Box, { sx: {
2899
+ fontSize: '12px',
2900
+ color: COLOR_ERROR[500],
2901
+ marginTop: '4px',
2902
+ }, children: errorMessage })), success && successMessage && (jsx(Box, { sx: {
2903
+ fontSize: '12px',
2904
+ color: COLOR_SUCCESS[500],
2905
+ marginTop: '4px',
2906
+ }, children: successMessage })), helperText && !error && !success && (jsx(Box, { sx: {
2907
+ fontSize: '12px',
2908
+ color: COLOR_NEUTRAL[500],
2909
+ marginTop: '4px',
2910
+ }, children: helperText }))] }));
2911
+ };
1846
2912
 
1847
- styled$1(Autocomplete)(({ theme }) => ({
2913
+ const StyledAutocomplete = styled$1(Autocomplete)(({ theme }) => ({
1848
2914
  '& .MuiOutlinedInput-root': {
1849
2915
  padding: '0 !important',
1850
2916
  display: 'flex',
@@ -1883,6 +2949,45 @@ styled$1(Autocomplete)(({ theme }) => ({
1883
2949
  paddingRight: '8px',
1884
2950
  },
1885
2951
  }));
2952
+ const SearchFieldComponent = ({ value, onChange, onClear, onInputChange, borderRadius = 6, disabled = false, placeholder = 'Placeholder', sx, }) => {
2953
+ const DEBOUNCE_DELAY = 1000;
2954
+ const [inputValue, setInputValue] = useState('');
2955
+ const debounceTimer = useRef(null);
2956
+ useEffect(() => {
2957
+ if (debounceTimer.current) {
2958
+ clearTimeout(debounceTimer.current);
2959
+ }
2960
+ debounceTimer.current = setTimeout(() => {
2961
+ onInputChange?.(new Event('debounce'), inputValue, 'debounce');
2962
+ }, DEBOUNCE_DELAY);
2963
+ return () => {
2964
+ if (debounceTimer.current) {
2965
+ clearTimeout(debounceTimer.current);
2966
+ }
2967
+ };
2968
+ }, [inputValue, onInputChange]);
2969
+ const handleInputChange = useCallback((event, value) => {
2970
+ setInputValue(value);
2971
+ }, []);
2972
+ const handleClear = useCallback(() => {
2973
+ setInputValue('');
2974
+ onClear?.();
2975
+ onInputChange?.(new Event('clear'), '', 'clear');
2976
+ }, [onClear, onInputChange]);
2977
+ return (jsx(StyledAutocomplete, { freeSolo: true, options: [], inputValue: inputValue, onInputChange: handleInputChange, disabled: disabled, onChange: onChange, noOptionsText: null, sx: {
2978
+ '& .MuiOutlinedInput-root': {
2979
+ borderRadius: borderRadius === 'max' ? '100px' : `${borderRadius}px`,
2980
+ },
2981
+ ...sx,
2982
+ }, renderInput: (params) => (jsx(TextField, { ...params, placeholder: placeholder, variant: "outlined", size: "small", InputProps: {
2983
+ ...params.InputProps,
2984
+ startAdornment: (jsx(InputAdornment, { position: "start", sx: { marginLeft: '8px' }, children: jsx(SearchIcon, { sx: { color: '#999', fontSize: '20px' } }) })),
2985
+ } })), componentsProps: {
2986
+ clearIndicator: {
2987
+ onClick: handleClear,
2988
+ },
2989
+ } }));
2990
+ };
1886
2991
 
1887
2992
  const SWITCH_SIZE = {
1888
2993
  small: { width: '36px', height: '20px', thumbSize: '16px' },
@@ -1902,7 +3007,7 @@ const SWITCH_COLORS = {
1902
3007
  thumbFocusColor: '#F4EBFF',
1903
3008
  },
1904
3009
  };
1905
- styled$1(Switch, {
3010
+ const StyledSwitch = styled$1(Switch, {
1906
3011
  shouldForwardProp: (prop) => prop !== 'size',
1907
3012
  })(({ theme, size = 'medium' }) => {
1908
3013
  const mode = theme.palette.mode;
@@ -1955,7 +3060,89 @@ styled$1(Switch, {
1955
3060
  },
1956
3061
  };
1957
3062
  });
3063
+ const SwitchComponent = ({ title, sx, ...switchProps }) => {
3064
+ if (!title) {
3065
+ return jsx(StyledSwitch, { disableRipple: true, ...switchProps });
3066
+ }
3067
+ return (jsxs(StackRowAlignCenterJustEnd, { sx: {
3068
+ display: 'inline-flex',
3069
+ alignItems: 'center',
3070
+ gap: '12px',
3071
+ ...sx,
3072
+ }, children: [jsx(StyledSwitch, { disableRipple: true, ...switchProps }), title] }));
3073
+ };
3074
+
3075
+ const SwitchContentComponent = ({ title, content, checked, disabled, size = 'medium', onChange, sx, }) => {
3076
+ return (jsxs(StackRow, { sx: {
3077
+ width: 'fit-content',
3078
+ gap: '12px',
3079
+ maxWidth: '345px',
3080
+ ...sx,
3081
+ }, children: [jsx(SwitchComponent, { checked: checked, disabled: disabled, size: size, onChange: onChange }), jsxs(Box, { children: [jsx(Typography, { sx: {
3082
+ fontSize: 16,
3083
+ lineHeight: '24px',
3084
+ fontWeight: 500,
3085
+ color: '#344054',
3086
+ }, children: title }), content && (jsx(Typography, { sx: {
3087
+ mt: 0.5,
3088
+ fontSize: 16,
3089
+ lineHeight: '24px',
3090
+ fontWeight: 400,
3091
+ color: '#667085',
3092
+ }, children: content }))] })] }));
3093
+ };
1958
3094
 
3095
+ const TAB_STYLES = {
3096
+ position: 'relative',
3097
+ padding: '18px 16px',
3098
+ cursor: 'pointer',
3099
+ minHeight: 44,
3100
+ '&:hover': {
3101
+ bgcolor: '#F3F4F6',
3102
+ },
3103
+ };
3104
+ const TAB_BACKGROUND_STYLES = {
3105
+ position: 'absolute',
3106
+ top: 0,
3107
+ left: 0,
3108
+ right: 0,
3109
+ bottom: 0,
3110
+ borderRadius: 1,
3111
+ };
3112
+ const TAB_UNDERLINE_STYLES = {
3113
+ width: '1px',
3114
+ alignSelf: 'stretch',
3115
+ bgcolor: '#E5E7EB',
3116
+ };
3117
+ const TABS_CONTAINER_HORIZONTAL = {
3118
+ display: 'flex',
3119
+ alignItems: 'center',
3120
+ borderBottom: '2px solid #E5E7EB',
3121
+ };
3122
+ const TAB_ACTIVE_BACKGROUND_HORIZONTAL = {
3123
+ position: 'absolute',
3124
+ bottom: -2,
3125
+ left: 0,
3126
+ right: 0,
3127
+ height: '2px',
3128
+ bgcolor: '#0F766E',
3129
+ };
3130
+ const TABS_CONTAINER_VERTICAL = {
3131
+ position: 'relative',
3132
+ padding: '10px',
3133
+ cursor: 'pointer',
3134
+ minHeight: 40,
3135
+ '&:hover': {
3136
+ bgcolor: '#F3F4F6',
3137
+ },
3138
+ width: '100%',
3139
+ };
3140
+ const TAB_ACTIVE_BACKGROUND_VERTICAL = {
3141
+ position: 'absolute',
3142
+ inset: 0,
3143
+ bgcolor: '#E6EEED',
3144
+ borderRadius: 1,
3145
+ };
1959
3146
  var TabColors;
1960
3147
  (function (TabColors) {
1961
3148
  TabColors["ACTIVE_TEXT"] = "#0F766E";
@@ -1964,7 +3151,171 @@ var TabColors;
1964
3151
  TabColors["MENU_ACTIVE_BACKGROUND"] = "#E0F2FE";
1965
3152
  })(TabColors || (TabColors = {}));
1966
3153
 
1967
- styled(MuiTextField)(({ theme }) => {
3154
+ const TabsComponent = ({ idSelect, tabs, size, direction = 'row', maxDisplay, onChange, sx, sxTabs, sxWrapper, }) => {
3155
+ // state
3156
+ const [selected, setSelected] = useState(idSelect);
3157
+ const [anchorEl, setAnchorEl] = useState(null);
3158
+ const layoutGroupId = useId();
3159
+ useEffect(() => {
3160
+ setSelected(idSelect);
3161
+ }, [idSelect]);
3162
+ const isVertical = direction === 'column';
3163
+ const showOverflow = !isVertical && maxDisplay && tabs.length > maxDisplay;
3164
+ const visibleTabs = showOverflow ? tabs.slice(0, maxDisplay) : tabs;
3165
+ const overflowTabs = showOverflow ? tabs.slice(maxDisplay) : [];
3166
+ // function
3167
+ const handleOpenDropdown = (event) => {
3168
+ setAnchorEl(event.currentTarget);
3169
+ };
3170
+ const handleTabClick = (tab) => {
3171
+ setSelected(tab.id);
3172
+ onChange?.(tab.id);
3173
+ if (tab.onClick) {
3174
+ tab.onClick();
3175
+ }
3176
+ };
3177
+ const handleOverflowItemClick = (tab) => {
3178
+ handleTabClick(tab);
3179
+ setAnchorEl(null);
3180
+ };
3181
+ 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) => {
3182
+ const isActive = tab.id === selected;
3183
+ 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: {
3184
+ ...TABS_CONTAINER_VERTICAL,
3185
+ color: isActive ? TabColors.ACTIVE_TEXT : TabColors.INACTIVE_TEXT,
3186
+ }, onTap: () => handleTabClick(tab), children: jsxs(Box, { sx: {
3187
+ ...TYPOGRAPHY_STYLES.textMd.medium,
3188
+ display: 'flex',
3189
+ alignItems: 'center',
3190
+ gap: tab.icon ? 0.5 : 0,
3191
+ position: 'relative',
3192
+ zIndex: 1,
3193
+ ...sx,
3194
+ }, 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));
3195
+ }) }) })) : (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) => {
3196
+ const isActive = tab.id === selected;
3197
+ return (jsx(LinkElement, { href: tab.href, onClick: tab.onClick, id: tab.id, children: jsxs(Stack, { component: motion.div, sx: {
3198
+ color: isActive ? TabColors.ACTIVE_TEXT : TabColors.INACTIVE_TEXT,
3199
+ position: 'relative',
3200
+ padding: '18px 16px',
3201
+ cursor: 'pointer',
3202
+ minHeight: 40,
3203
+ '&:hover': {
3204
+ bgcolor: TabColors.HOVER_BACKGROUND,
3205
+ },
3206
+ ...sxTabs,
3207
+ }, onTap: () => handleTabClick(tab), children: [jsxs(Box, { sx: {
3208
+ ...TYPOGRAPHY_STYLES.textMd.medium,
3209
+ display: 'flex',
3210
+ alignItems: 'center',
3211
+ gap: tab.icon ? 0.5 : 0,
3212
+ ...sx,
3213
+ }, 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));
3214
+ }), showOverflow && (jsxs(React.Fragment, { children: [jsx(Box, { sx: { ...TAB_UNDERLINE_STYLES } }), jsx(Stack, { sx: {
3215
+ ...TAB_STYLES,
3216
+ }, onClick: handleOpenDropdown, children: jsx(IconElement, { icon: "more_horiz", size: size }) })] }))] }), jsx(Menu, { disableScrollLock: true, anchorEl: anchorEl, open: Boolean(anchorEl), onClose: () => setAnchorEl(null), anchorOrigin: {
3217
+ vertical: 'bottom',
3218
+ horizontal: 'left',
3219
+ }, transformOrigin: {
3220
+ vertical: 'top',
3221
+ horizontal: 'left',
3222
+ }, children: overflowTabs.map((tab) => {
3223
+ const isActive = tab.id === selected;
3224
+ return (jsx(MenuItem, { onClick: () => handleOverflowItemClick(tab), sx: {
3225
+ color: isActive ? TabColors.ACTIVE_TEXT : TabColors.INACTIVE_TEXT,
3226
+ bgcolor: isActive ? TabColors.MENU_ACTIVE_BACKGROUND : 'transparent',
3227
+ '&:hover': {
3228
+ bgcolor: isActive ? TabColors.MENU_ACTIVE_BACKGROUND : TabColors.HOVER_BACKGROUND,
3229
+ },
3230
+ }, children: jsxs(Box, { sx: {
3231
+ display: 'flex',
3232
+ alignItems: 'center',
3233
+ gap: tab.icon ? 0.5 : 0,
3234
+ }, children: [tab.icon && jsx(IconElement, { size: size, icon: tab.icon }), tab.name] }) }, tab.id));
3235
+ }) })] }) })) }));
3236
+ };
3237
+
3238
+ const TextAreaComponent = ({ label = '', placeholder = '', value = '', disabled = false, error = false, success = false, errorMessage, successMessage, borderRadius = 6, onChange, onBlur, helperText = '', rows = 4, maxLength, sx, }) => {
3239
+ const borderRadiusValue = borderRadius === 'max' ? '100px' : `${borderRadius}px`;
3240
+ const getHelperText = () => {
3241
+ if (error && errorMessage)
3242
+ return errorMessage;
3243
+ if (success && successMessage)
3244
+ return successMessage;
3245
+ if (helperText)
3246
+ return helperText;
3247
+ return '';
3248
+ };
3249
+ const getHelperTextColor = () => {
3250
+ if (error)
3251
+ return COLOR_ERROR[500];
3252
+ if (success)
3253
+ return COLOR_SUCCESS[500];
3254
+ return COLOR_NEUTRAL[400];
3255
+ };
3256
+ const getBorderColor = () => {
3257
+ if (error)
3258
+ return COLOR_ERROR[500];
3259
+ if (success)
3260
+ return COLOR_SUCCESS[500];
3261
+ return COLOR_NEUTRAL[300];
3262
+ };
3263
+ return (jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Typography, { sx: {
3264
+ display: 'block',
3265
+ ...TYPOGRAPHY.textFieldLabel,
3266
+ color: COLOR_GRAY[800],
3267
+ marginBottom: '4px',
3268
+ }, 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: {
3269
+ maxLength: maxLength,
3270
+ style: {
3271
+ ...TYPOGRAPHY.text14Regular,
3272
+ paddingBottom: maxLength ? '24px' : '0px',
3273
+ },
3274
+ }, sx: {
3275
+ '& .MuiOutlinedInput-root': {
3276
+ borderRadius: borderRadiusValue,
3277
+ backgroundColor: disabled ? COLOR_NEUTRAL[100] : 'white',
3278
+ transition: 'all 0.2s ease',
3279
+ '& fieldset': {
3280
+ borderColor: getBorderColor(),
3281
+ },
3282
+ '&:hover fieldset': {
3283
+ borderColor: disabled ? getBorderColor() : error ? COLOR_ERROR[500] : COLOR_NEUTRAL[400],
3284
+ },
3285
+ '&.Mui-focused fieldset': {
3286
+ borderColor: error ? COLOR_ERROR[500] : COLOR_NEUTRAL[400],
3287
+ borderWidth: '1.5px',
3288
+ },
3289
+ },
3290
+ '& .MuiOutlinedInput-input': {
3291
+ color: value ? COLOR_GRAY[900] : COLOR_NEUTRAL[400],
3292
+ '&::placeholder': {
3293
+ color: COLOR_NEUTRAL[400],
3294
+ opacity: 1,
3295
+ },
3296
+ '&:disabled': {
3297
+ color: COLOR_NEUTRAL[400],
3298
+ WebkitTextFillColor: COLOR_NEUTRAL[400],
3299
+ },
3300
+ },
3301
+ '& .MuiOutlinedInput-notchedOutline': {
3302
+ borderColor: getBorderColor(),
3303
+ },
3304
+ } }), maxLength && (jsxs(Box, { sx: {
3305
+ position: 'absolute',
3306
+ bottom: '8px',
3307
+ right: '12px',
3308
+ fontSize: '12px',
3309
+ color: COLOR_NEUTRAL[400],
3310
+ pointerEvents: 'none',
3311
+ }, children: ["(", value?.length, "/", maxLength, ")"] }))] }), getHelperText() && (jsx(Box, { sx: {
3312
+ color: getHelperTextColor(),
3313
+ marginTop: '4px',
3314
+ ...TYPOGRAPHY.textFieldHelper,
3315
+ }, children: getHelperText() }))] }));
3316
+ };
3317
+
3318
+ const StyledTextField = styled(MuiTextField)(({ theme }) => {
1968
3319
  return {
1969
3320
  '& .MuiOutlinedInput-root': {
1970
3321
  '& fieldset': { borderColor: COLOR_NEUTRAL[300] },
@@ -2006,10 +3357,221 @@ styled(MuiTextField)(({ theme }) => {
2006
3357
  },
2007
3358
  };
2008
3359
  });
3360
+ const TextFieldComponent = ({ label, placeholder = 'Placeholder', value, disabled = false, error = false, success = false, errorMessage, successMessage, borderRadius = 6, helperText, onChange, iconBefore, iconAfter, sx, ...props }) => {
3361
+ return (jsxs(Box, { sx: { ...sx }, children: [label && (jsx(Typography, { sx: {
3362
+ display: 'block',
3363
+ ...TYPOGRAPHY.textFieldLabel,
3364
+ color: COLOR_GRAY[800],
3365
+ marginBottom: '4px',
3366
+ }, children: label })), jsx(StyledTextField, { placeholder: placeholder, value: value, disabled: disabled, error: error, helperText: error ? errorMessage : helperText, size: "small", fullWidth: true, onChange: onChange, InputProps: {
3367
+ startAdornment: iconBefore ? jsx(InputAdornment, { position: "start", children: iconBefore }) : undefined,
3368
+ endAdornment: iconAfter ? jsx(InputAdornment, { position: "end", children: iconAfter }) : undefined,
3369
+ }, sx: {
3370
+ '& .MuiOutlinedInput-root': {
3371
+ borderRadius: borderRadius === 'max' ? '100px' : `${borderRadius}px`,
3372
+ ...(success && {
3373
+ '&.Mui-focused': {
3374
+ boxShadow: `0 1px 2px 0 rgba(10, 13, 18, 0.05), 0 0 0 4px ${COLOR_SUCCESS[100]}`,
3375
+ },
3376
+ }),
3377
+ },
3378
+ }, ...props }), success && !error && successMessage && (jsx(Typography, { sx: {
3379
+ ...TYPOGRAPHY.textFieldHelper,
3380
+ color: COLOR_SUCCESS[500],
3381
+ marginTop: '4px',
3382
+ }, children: successMessage }))] }));
3383
+ };
2009
3384
 
2010
- ({
3385
+ const SX_STYLES = {
2011
3386
  progressBar: {
2012
- backgroundColor: COLOR_GRAY[200]}});
3387
+ position: 'absolute',
3388
+ top: 0,
3389
+ left: 0,
3390
+ height: '100%',
3391
+ backgroundColor: COLOR_GRAY[200],
3392
+ opacity: 0.8,
3393
+ transition: 'width 0.3s ease, opacity 0.3s ease',
3394
+ animation: 'wave 1.5s linear infinite',
3395
+ '@keyframes wave': {
3396
+ '0%': { backgroundPosition: '0% 0%' },
3397
+ '50%': { backgroundPosition: '100% 0%' },
3398
+ '100%': { backgroundPosition: '0% 0%' },
3399
+ },
3400
+ },
3401
+ imageIcon: {
3402
+ width: '40px',
3403
+ height: '40px',
3404
+ flexShrink: 0,
3405
+ position: 'relative',
3406
+ zIndex: 1,
3407
+ },
3408
+ contentBox: {
3409
+ flexGrow: 1,
3410
+ minWidth: 0,
3411
+ position: 'relative',
3412
+ zIndex: 1,
3413
+ },
3414
+ textBox: {
3415
+ minWidth: 0,
3416
+ flexGrow: 1,
3417
+ mr: 2,
3418
+ },
3419
+ actionBox: {
3420
+ flexShrink: 0,
3421
+ display: 'flex',
3422
+ alignItems: 'center',
3423
+ position: 'relative',
3424
+ zIndex: 1,
3425
+ },
3426
+ linearProgress: {
3427
+ mt: 1,
3428
+ width: '100%',
3429
+ },
3430
+ };
3431
+
3432
+ const VIDEO_EXTENSIONS = ['mp4', 'mov', 'avi', 'wmv', 'flv', 'mkv', 'webm'];
3433
+ const ICON_PATH = {
3434
+ VIDEO: '/images/icon/film.svg',
3435
+ FILE: '/images/icon/file.svg',
3436
+ };
3437
+ // ============================================================================
3438
+ // Helper Functions
3439
+ // ============================================================================
3440
+ const formatFileSize = (bytes) => {
3441
+ if (bytes === 0)
3442
+ return '0 Bytes';
3443
+ const k = 1024;
3444
+ const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
3445
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
3446
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
3447
+ };
3448
+ const getFileIcon = (fileName) => {
3449
+ const ext = fileName.split('.').pop()?.toLowerCase();
3450
+ return ext && VIDEO_EXTENSIONS.includes(ext) ? ICON_PATH.VIDEO : ICON_PATH.FILE;
3451
+ };
3452
+ // ============================================================================
3453
+ // Component
3454
+ // ============================================================================
3455
+ const UploaderItemComponent = ({ file, progress = 0, status = 'pending', onDelete, onRetry, isProcess = true, borderSuccess, borderError = COLOR_ERROR[600], sx, }) => {
3456
+ // Memoize
3457
+ const iconSrc = useMemo(() => getFileIcon(file.name), [file.name]);
3458
+ // Status flags
3459
+ const isCompleted = status === 'success';
3460
+ const isFailed = status === 'failed';
3461
+ const isUploading = status === 'uploading';
3462
+ // Determine colors based on status
3463
+ const borderColor = isFailed
3464
+ ? String(borderError)
3465
+ : isCompleted && borderSuccess
3466
+ ? String(borderSuccess)
3467
+ : '#e0e0e0';
3468
+ const textColor = isFailed ? String(borderError) : '#737373';
3469
+ const subtitleColor = isFailed ? String(borderError) : '#a3a3a3';
3470
+ // Render progress info
3471
+ const renderProgressInfo = () => {
3472
+ if (isUploading && !isCompleted)
3473
+ return ` • ${Math.round(progress)}% uploaded`;
3474
+ if (isFailed)
3475
+ return ' • Upload failed';
3476
+ return '';
3477
+ };
3478
+ return (jsxs(Box, { sx: {
3479
+ display: 'flex',
3480
+ alignItems: 'flex-start',
3481
+ padding: '16px',
3482
+ border: '1px solid',
3483
+ borderColor: borderColor,
3484
+ borderRadius: '8px',
3485
+ gap: '16px',
3486
+ position: 'relative',
3487
+ overflow: 'hidden',
3488
+ transition: 'background-color 0.3s ease',
3489
+ backgroundColor: 'background.paper',
3490
+ ...sx,
3491
+ }, 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 } }) }))] })] }));
3492
+ };
3493
+
3494
+ const UploaderComponent = ({ onFilesSelected, accept = '*', multiple = true, children, sx, labelSx, uploadLabel = 'Click to upload', appearance, files: externalFiles, onDeleteFile, onRetryFile, borderError, }) => {
3495
+ const fileInputRef = useRef(null);
3496
+ const [isDragging, setIsDragging] = useState(false);
3497
+ // Sử dụng external files nếu có, nếu không hiển thị rỗng
3498
+ const displayFiles = externalFiles || [];
3499
+ const handleClick = () => {
3500
+ fileInputRef.current?.click();
3501
+ };
3502
+ const handleFileChange = (event) => {
3503
+ const selectedFiles = event.target.files;
3504
+ if (selectedFiles) {
3505
+ const fileArray = Array.from(selectedFiles);
3506
+ onFilesSelected(fileArray);
3507
+ }
3508
+ event.target.value = '';
3509
+ };
3510
+ const handleDeleteFile = (file) => {
3511
+ if (onDeleteFile) {
3512
+ onDeleteFile(file);
3513
+ }
3514
+ };
3515
+ const handleDragOver = (e) => {
3516
+ e.preventDefault();
3517
+ e.stopPropagation();
3518
+ setIsDragging(true);
3519
+ };
3520
+ const handleDragLeave = (e) => {
3521
+ e.preventDefault();
3522
+ e.stopPropagation();
3523
+ setIsDragging(false);
3524
+ };
3525
+ const handleDrop = (e) => {
3526
+ e.preventDefault();
3527
+ e.stopPropagation();
3528
+ setIsDragging(false);
3529
+ const files = e.dataTransfer.files;
3530
+ if (files) {
3531
+ onFilesSelected(Array.from(files));
3532
+ }
3533
+ };
3534
+ return (jsxs(Box, { sx: {
3535
+ border: '2px solid',
3536
+ borderColor: appearance?.borderColor || 'action.selected',
3537
+ borderRadius: '8px',
3538
+ padding: '32px 24px',
3539
+ textAlign: 'center',
3540
+ cursor: 'pointer',
3541
+ transition: 'all 0.3s ease',
3542
+ backgroundColor: isDragging ? 'action.selected' : appearance?.background || 'background.paper',
3543
+ '&:hover': {
3544
+ borderColor: appearance?.borderColorHover || appearance?.borderColor || 'primary.main',
3545
+ filter: 'brightness(0.92)',
3546
+ },
3547
+ ...sx,
3548
+ }, 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: {
3549
+ color: 'primary.main',
3550
+ textDecoration: 'underline',
3551
+ fontWeight: 500,
3552
+ fontSize: '14px',
3553
+ marginTop: '12px',
3554
+ margin: '12px 0 0 0',
3555
+ ...labelSx,
3556
+ }, children: [uploadLabel, " or drag and drop"] })] })) : (jsxs(Box, { children: [jsx(Box, { component: "img", src: "/images/icon/uploader.svg", alt: "Upload icon", sx: {
3557
+ width: '46px',
3558
+ height: '46px',
3559
+ marginBottom: '12px',
3560
+ } }), jsxs(Box, { component: "p", sx: {
3561
+ color: 'primary.main',
3562
+ textDecoration: 'underline',
3563
+ fontWeight: 500,
3564
+ fontSize: '14px',
3565
+ margin: 0,
3566
+ ...labelSx,
3567
+ }, children: [uploadLabel, " or drag and drop"] })] })) })), displayFiles && displayFiles.length > 0 && (jsx(Box, { sx: {
3568
+ marginTop: '24px',
3569
+ display: 'flex',
3570
+ flexDirection: 'column',
3571
+ gap: '12px',
3572
+ textAlign: 'left',
3573
+ }, 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))) }))] }));
3574
+ };
2013
3575
 
2014
- export { AVATAR_SIZES, AvatarColor, AvatarComponent, AvatarGroupComponent, AvatarLabelGroupComponent, AvatarProfileComponent, AvatarUserComponent, BADGE_FONT_SIZES, BADGE_SIZES, BadgeImage, BadgeLive, BadgeNumber, BadgeOnline, ButtonComponent, COLOR_ACCENT, COLOR_BRAND, COLOR_ERROR, COLOR_GRAY, COLOR_INFO, COLOR_NEUTRAL, COLOR_SUCCESS, COLOR_WARNING, CheckboxContentComponent, DialogWrapper, FONT_FAMILY, FONT_SIZE, FONT_STYLE, FONT_WEIGHT, IconElement, ImageElement, ImageSizeType, LINE_HEIGHT, LinkElement, LinkInternalElement, MAP_SIZE, ModalComponent as Modal, ModalCardComponent as ModalCard, ModalDescription, ModalIcon, ModalTitle, SIZE_EXTRA_LARGE, style_constant as STYLE, TYPOGRAPHY, TYPOGRAPHY_STYLES, TypographyOneLine, createTypography, getBadgePosition };
3576
+ export { ACCESSIBILITY, AVATAR_SIZES, AvatarColor, AvatarComponent, AvatarGroupComponent, AvatarLabelGroupComponent, AvatarProfileComponent, AvatarUserComponent, BADGE_FONT_SIZES, BADGE_SIZES, BORDER_TEXT_FIELD_LOADING, BUTTON_CONSTANTS, BadgeImage, BadgeLive, BadgeNumber, BadgeOnline, BorderRadius, BreadcrumbsComponent, ButtonBarComponent, ButtonComponent, ButtonSize, CHECKBOX_COLORS, CHECKBOX_SIZE, CHIP_ICON_SIZE, CHIP_LABEL_PADDING, CHIP_SIZE_CONFIG, COLORS, COLOR_ACCENT, COLOR_BRAND, COLOR_ERROR, COLOR_GRAY, COLOR_INFO, COLOR_NEUTRAL, COLOR_SUCCESS, COLOR_WARNING, CheckboxComponent, CheckboxContentComponent, ChipComponent, Colors, DateFieldComponent, DateRangePickerComponent, DialogWrapper, DropdownFieldComponent, FONT_FAMILY, FONT_SIZE, FONT_SIZE_ICON, FONT_SIZE_LOADING, FONT_STYLE, FONT_WEIGHT, GridComponent, IconElement, ImageElement, ImageSizeType, InputStepperComponent, InputStepperSkeleton, LINE_HEIGHT, LinkElement, LinkFieldComponent, LinkInternalElement, MAP_SIZE, ModalComponent as Modal, ModalCardComponent as ModalCard, ModalDescription, ModalIcon, ModalTitle, MoneyFieldComponent, Orientation, PINComponent, PIN_SIZES, PIN_SPACING, PhoneNumberFieldComponent, SHADE_VALUES, SIZES, SIZE_EXTRA_LARGE, style_constant as STYLE, SearchDropdownComponent, SearchFieldComponent, ShapeType, SwitchComponent, SwitchContentComponent, TABS_CONTAINER_HORIZONTAL, TABS_CONTAINER_VERTICAL, TAB_ACTIVE_BACKGROUND_HORIZONTAL, TAB_ACTIVE_BACKGROUND_VERTICAL, TAB_BACKGROUND_STYLES, TAB_STYLES, TAB_UNDERLINE_STYLES, TYPOGRAPHY, TYPOGRAPHY_STYLES, TabColors, TabsComponent, TextAreaComponent, TextFieldComponent, TypographyOneLine, UploaderComponent, UploaderItemComponent, createTypography, getBadgePosition };
2015
3577
  //# sourceMappingURL=index.js.map