@customafk/lunas-ui 0.2.44 → 0.2.47

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 (620) hide show
  1. package/dist/{alert-BbvPwf2x.mjs → alert-BzBDfGk2.js} +1 -1
  2. package/dist/alert-BzBDfGk2.js.map +1 -0
  3. package/dist/{alert-B02cVKWp.d.cts → alert-CNFuxKp7.d.cts} +6 -6
  4. package/dist/{alert-DHSm8bMn.d.mts → alert-EH6BsbAj.d.ts} +8 -8
  5. package/dist/{avatar-fltdRVsJ.mjs → avatar-Hpj8lmux.js} +1 -1
  6. package/dist/avatar-Hpj8lmux.js.map +1 -0
  7. package/dist/{badge-CDGBGq8X.mjs → badge-CRpRXSuO.js} +1 -1
  8. package/dist/badge-CRpRXSuO.js.map +1 -0
  9. package/dist/{badge-BxSbkHQL.d.mts → badge-Cca0AHjT.d.ts} +7 -7
  10. package/dist/{badge-zrAIDd-9.d.cts → badge-D0JnPurs.d.cts} +7 -7
  11. package/dist/{button-D3d7M90P.d.mts → button-Cr817M3U.d.cts} +6 -6
  12. package/dist/{button-D3QvCdr6.d.cts → button-DuZy_wDo.d.ts} +7 -7
  13. package/dist/button-LMMbL-uH.js +2 -0
  14. package/dist/button-LMMbL-uH.js.map +1 -0
  15. package/dist/{button.variants-DkMqWB8G.mjs → button.variants-CoSpd71B.js} +1 -1
  16. package/dist/button.variants-CoSpd71B.js.map +1 -0
  17. package/dist/calendar-DzPt7b6k.js +2 -0
  18. package/dist/calendar-DzPt7b6k.js.map +1 -0
  19. package/dist/cards/{grid-product-card.d.mts → grid-product-card.d.ts} +1 -1
  20. package/dist/cards/grid-product-card.js +2 -0
  21. package/dist/cards/grid-product-card.js.map +1 -0
  22. package/dist/cards/{product-card.d.mts → product-card.d.ts} +1 -1
  23. package/dist/cards/product-card.js +2 -0
  24. package/dist/cards/product-card.js.map +1 -0
  25. package/dist/cards/{simple-card.d.mts → simple-card.d.ts} +1 -1
  26. package/dist/cards/simple-card.js +2 -0
  27. package/dist/cards/simple-card.js.map +1 -0
  28. package/dist/{checkbox-Cat3i08X.mjs → checkbox-DLGDoU-1.js} +1 -1
  29. package/dist/checkbox-DLGDoU-1.js.map +1 -0
  30. package/dist/{close-_UHFeiLS.mjs → close-C0PdZGxr.js} +1 -1
  31. package/dist/close-C0PdZGxr.js.map +1 -0
  32. package/dist/cms-layout-tPwrgJZc.js +2 -0
  33. package/dist/cms-layout-tPwrgJZc.js.map +1 -0
  34. package/dist/command-2gUejA6g.js +2 -0
  35. package/dist/command-2gUejA6g.js.map +1 -0
  36. package/dist/data-display/{country.d.mts → country.d.ts} +2 -2
  37. package/dist/data-display/country.js +2 -0
  38. package/dist/data-display/country.js.map +1 -0
  39. package/dist/data-display/{data-list.d.mts → data-list.d.ts} +1 -1
  40. package/dist/data-display/{data-list.mjs → data-list.js} +1 -1
  41. package/dist/data-display/data-list.js.map +1 -0
  42. package/dist/data-display/{date-tooltip.d.mts → date-tooltip.d.ts} +1 -1
  43. package/dist/data-display/date-tooltip.js +2 -0
  44. package/dist/data-display/date-tooltip.js.map +1 -0
  45. package/dist/data-display/{date.d.mts → date.d.ts} +1 -1
  46. package/dist/data-display/date.js +1 -0
  47. package/dist/data-display/{empty.d.mts → empty.d.ts} +1 -1
  48. package/dist/data-display/{empty.mjs → empty.js} +1 -1
  49. package/dist/data-display/empty.js.map +1 -0
  50. package/dist/data-display/{name.d.mts → name.d.ts} +1 -1
  51. package/dist/data-display/name.js +2 -0
  52. package/dist/data-display/name.js.map +1 -0
  53. package/dist/data-display/{phone-number.d.mts → phone-number.d.ts} +1 -1
  54. package/dist/data-display/phone-number.js +2 -0
  55. package/dist/data-display/phone-number.js.map +1 -0
  56. package/dist/data-display/{role-badge.d.mts → role-badge.d.ts} +2 -2
  57. package/dist/data-display/role-badge.js +2 -0
  58. package/dist/data-display/role-badge.js.map +1 -0
  59. package/dist/data-display/statistic.d.cts +1 -1
  60. package/dist/data-display/{statistic.d.mts → statistic.d.ts} +7 -7
  61. package/dist/data-display/statistic.js +1 -0
  62. package/dist/data-display/{user.d.mts → user.d.ts} +1 -1
  63. package/dist/data-display/user.js +1 -0
  64. package/dist/{date-fY3sUcLp.mjs → date-BIqCFM1Z.js} +1 -1
  65. package/dist/date-BIqCFM1Z.js.map +1 -0
  66. package/dist/{dialog-Bd5cOZia.d.mts → dialog-C48T3MZN.d.cts} +12 -12
  67. package/dist/{dialog-DEmYNufN.d.cts → dialog-CQygxUtj.d.ts} +12 -12
  68. package/dist/dialog-CmutQ3rp.js +2 -0
  69. package/dist/dialog-CmutQ3rp.js.map +1 -0
  70. package/dist/dialogs/{confirm-dialog.d.mts → confirm-dialog.d.ts} +1 -1
  71. package/dist/dialogs/confirm-dialog.js +2 -0
  72. package/dist/dialogs/confirm-dialog.js.map +1 -0
  73. package/dist/dialogs/detail-dialog/components/sidebar.d.cts +27 -27
  74. package/dist/dialogs/detail-dialog/components/{sidebar.d.mts → sidebar.d.ts} +30 -30
  75. package/dist/dialogs/detail-dialog/components/sidebar.js +1 -0
  76. package/dist/dialogs/detail-dialog/{index.d.mts → index.d.ts} +1 -1
  77. package/dist/dialogs/detail-dialog/index.js +2 -0
  78. package/dist/dialogs/detail-dialog/index.js.map +1 -0
  79. package/dist/dialogs/{error-dialog.d.mts → error-dialog.d.ts} +1 -1
  80. package/dist/dialogs/error-dialog.js +2 -0
  81. package/dist/dialogs/error-dialog.js.map +1 -0
  82. package/dist/dialogs/{loading-dialog.d.mts → loading-dialog.d.ts} +1 -1
  83. package/dist/dialogs/loading-dialog.js +2 -0
  84. package/dist/dialogs/loading-dialog.js.map +1 -0
  85. package/dist/{dist-DVrfqn8H.mjs → dist-EPxjIRJp.js} +1 -1
  86. package/dist/dist-EPxjIRJp.js.map +1 -0
  87. package/dist/{drawer-CMD7JWH8.mjs → drawer-B3qXaN5p.js} +1 -1
  88. package/dist/drawer-B3qXaN5p.js.map +1 -0
  89. package/dist/{dropdown-menu-BWhiVsEf.mjs → dropdown-menu-DeHCVyby.js} +1 -1
  90. package/dist/dropdown-menu-DeHCVyby.js.map +1 -0
  91. package/dist/features/descriptions/index.d.cts +4 -4
  92. package/dist/features/descriptions/{index.d.mts → index.d.ts} +8 -8
  93. package/dist/features/descriptions/index.js +2 -0
  94. package/dist/features/descriptions/index.js.map +1 -0
  95. package/dist/features/search-modal/index.d.cts +2 -2
  96. package/dist/features/search-modal/{index.d.mts → index.d.ts} +3 -3
  97. package/dist/features/search-modal/index.js +1 -0
  98. package/dist/features/tables/index.d.cts +1 -1
  99. package/dist/features/tables/{index.d.mts → index.d.ts} +2 -2
  100. package/dist/features/tables/index.js +1 -0
  101. package/dist/features/tanstack-form/index.cjs +1 -1
  102. package/dist/features/tanstack-form/index.d.cts +2 -2
  103. package/dist/features/tanstack-form/index.d.ts +2 -0
  104. package/dist/features/tanstack-form/index.js +1 -0
  105. package/dist/features/text-editor/index.d.cts +1 -1
  106. package/dist/features/text-editor/{index.d.mts → index.d.ts} +1 -1
  107. package/dist/features/text-editor/index.js +1 -0
  108. package/dist/field-DpoKF1nY.js +2 -0
  109. package/dist/field-DpoKF1nY.js.map +1 -0
  110. package/dist/{flex-B6YSJzGe.mjs → flex-CinRrgEy.js} +1 -1
  111. package/dist/flex-CinRrgEy.js.map +1 -0
  112. package/dist/{heading-De4Pn3mZ.mjs → heading-Bz-hSatD.js} +1 -1
  113. package/dist/heading-Bz-hSatD.js.map +1 -0
  114. package/dist/image-BpTuF_1w.js +2 -0
  115. package/dist/image-BpTuF_1w.js.map +1 -0
  116. package/dist/{index-CiG1i12w.d.cts → index-Bc9X8pLk.d.cts} +7 -7
  117. package/dist/{index-Cm62M0Ft.d.mts → index-BlQGXGqt.d.ts} +1 -1
  118. package/dist/{index-DNozPoRR.d.mts → index-C1O2C-cg.d.ts} +7 -7
  119. package/dist/{index-BhiLHeUb.d.cts → index-CgH0tiiC.d.cts} +30 -30
  120. package/dist/{index-DSciiDhn.d.cts → index-D5u9CKyd.d.cts} +309 -950
  121. package/dist/{index-DriviV-i.d.mts → index-DFUF27Yy.d.ts} +31 -31
  122. package/dist/{index-Cl_7tlH_.d.mts → index-Ilj04YNO.d.ts} +309 -950
  123. package/dist/index.cjs +1 -1
  124. package/dist/index.d.cts +9 -9
  125. package/dist/index.d.ts +93 -0
  126. package/dist/index.js +1 -0
  127. package/dist/{input-BtuZm0BQ.d.mts → input-B_gst0eJ.d.cts} +7 -7
  128. package/dist/{input-CD4zf7t1.d.cts → input-BkHdaXGY.d.ts} +7 -7
  129. package/dist/{input-NJP2wQOm.mjs → input-DAfP6LZ7.js} +1 -1
  130. package/dist/input-DAfP6LZ7.js.map +1 -0
  131. package/dist/{label-CUCpwS5D.mjs → label-B8cAG2kc.js} +1 -1
  132. package/dist/label-B8cAG2kc.js.map +1 -0
  133. package/dist/layouts/cms-layout/index.d.ts +2 -0
  134. package/dist/layouts/cms-layout/index.js +1 -0
  135. package/dist/layouts/flex.d.cts +4 -4
  136. package/dist/layouts/{flex.d.mts → flex.d.ts} +5 -5
  137. package/dist/layouts/flex.js +1 -0
  138. package/dist/layouts/{grid.d.mts → grid.d.ts} +1 -1
  139. package/dist/layouts/{grid.mjs → grid.js} +1 -1
  140. package/dist/layouts/grid.js.map +1 -0
  141. package/dist/layouts/payment-layout/{index.d.mts → index.d.ts} +1 -1
  142. package/dist/layouts/payment-layout/index.js +1 -0
  143. package/dist/pages/FeatureDeveloping.d.cts +2 -2
  144. package/dist/pages/{FeatureDeveloping.d.mts → FeatureDeveloping.d.ts} +3 -3
  145. package/dist/pages/FeatureDeveloping.js +2 -0
  146. package/dist/pages/FeatureDeveloping.js.map +1 -0
  147. package/dist/pages/FeatureFixing.d.cts +2 -2
  148. package/dist/pages/{FeatureFixing.d.mts → FeatureFixing.d.ts} +3 -3
  149. package/dist/pages/FeatureFixing.js +2 -0
  150. package/dist/pages/FeatureFixing.js.map +1 -0
  151. package/dist/pages/LoginPage.d.cts +2 -2
  152. package/dist/pages/{LoginPage.d.mts → LoginPage.d.ts} +3 -3
  153. package/dist/pages/LoginPage.js +2 -0
  154. package/dist/pages/LoginPage.js.map +1 -0
  155. package/dist/pages/NotAuthorized.d.cts +2 -2
  156. package/dist/pages/{NotAuthorized.d.mts → NotAuthorized.d.ts} +3 -3
  157. package/dist/pages/NotAuthorized.js +2 -0
  158. package/dist/pages/NotAuthorized.js.map +1 -0
  159. package/dist/pages/NotFound.d.cts +2 -2
  160. package/dist/pages/{NotFound.d.mts → NotFound.d.ts} +3 -3
  161. package/dist/pages/NotFound.js +2 -0
  162. package/dist/pages/NotFound.js.map +1 -0
  163. package/dist/pages/RegisterPage.d.cts +2 -2
  164. package/dist/pages/{RegisterPage.d.mts → RegisterPage.d.ts} +3 -3
  165. package/dist/pages/RegisterPage.js +2 -0
  166. package/dist/pages/RegisterPage.js.map +1 -0
  167. package/dist/pages/VerifyEmailPage.d.cts +2 -2
  168. package/dist/pages/{VerifyEmailPage.d.mts → VerifyEmailPage.d.ts} +3 -3
  169. package/dist/pages/VerifyEmailPage.js +2 -0
  170. package/dist/pages/VerifyEmailPage.js.map +1 -0
  171. package/dist/{paragraph-DYLaQtTV.mjs → paragraph-Cc13ZI4d.js} +1 -1
  172. package/dist/paragraph-Cc13ZI4d.js.map +1 -0
  173. package/dist/payment-layout-giaGvs8T.js +2 -0
  174. package/dist/payment-layout-giaGvs8T.js.map +1 -0
  175. package/dist/popover-6233wU1s.js +2 -0
  176. package/dist/popover-6233wU1s.js.map +1 -0
  177. package/dist/{progress-CLeM0e7Z.mjs → progress-AYknlEgK.js} +1 -1
  178. package/dist/progress-AYknlEgK.js.map +1 -0
  179. package/dist/{radio-group-Y9bhdr55.mjs → radio-group-ImoBjpqZ.js} +1 -1
  180. package/dist/radio-group-ImoBjpqZ.js.map +1 -0
  181. package/dist/{resizable-CpCaSCFB.mjs → resizable-C-M-mu6b.js} +1 -1
  182. package/dist/resizable-C-M-mu6b.js.map +1 -0
  183. package/dist/search-modal-b2AE5WEW.js +2 -0
  184. package/dist/search-modal-b2AE5WEW.js.map +1 -0
  185. package/dist/{select-LlPCZFSF.mjs → select-CryLzZA0.js} +1 -1
  186. package/dist/select-CryLzZA0.js.map +1 -0
  187. package/dist/{separator-D3Gmkxzq.mjs → separator-BM8hA4DP.js} +1 -1
  188. package/dist/separator-BM8hA4DP.js.map +1 -0
  189. package/dist/{sheet-BFlIfNaA.mjs → sheet-DGXXYgWB.js} +1 -1
  190. package/dist/sheet-DGXXYgWB.js.map +1 -0
  191. package/dist/sidebar-BDrsbzo5.js +2 -0
  192. package/dist/sidebar-BDrsbzo5.js.map +1 -0
  193. package/dist/{skeleton-C51IdOfK.mjs → skeleton-DlRDNM97.js} +1 -1
  194. package/dist/skeleton-DlRDNM97.js.map +1 -0
  195. package/dist/{spinner-eClTgHjk.mjs → spinner-C1eamx3w.js} +1 -1
  196. package/dist/spinner-C1eamx3w.js.map +1 -0
  197. package/dist/{statistic-cwLwcukn.mjs → statistic-CYMqAYNc.js} +1 -1
  198. package/dist/statistic-CYMqAYNc.js.map +1 -0
  199. package/dist/{switch-BP7EPatj.mjs → switch-BLHmdRq2.js} +1 -1
  200. package/dist/switch-BLHmdRq2.js.map +1 -0
  201. package/dist/systems/{google.d.mts → google.d.ts} +1 -1
  202. package/dist/systems/{google.mjs → google.js} +1 -1
  203. package/dist/systems/google.js.map +1 -0
  204. package/dist/tables-DWQytYNm.js +4 -0
  205. package/dist/tables-DWQytYNm.js.map +1 -0
  206. package/dist/tanstack-form-CCDV-3Ml.js +12 -0
  207. package/dist/tanstack-form-CCDV-3Ml.js.map +1 -0
  208. package/dist/{tanstack-form-DatI41wz.cjs → tanstack-form-DoI86Ezs.cjs} +2 -2
  209. package/dist/{tanstack-form-DatI41wz.cjs.map → tanstack-form-DoI86Ezs.cjs.map} +1 -1
  210. package/dist/text-editor-WbS7pJJs.js +2 -0
  211. package/dist/text-editor-WbS7pJJs.js.map +1 -0
  212. package/dist/{textarea-7HDXcaK9.mjs → textarea-Bp6VvhiA.js} +1 -1
  213. package/dist/textarea-Bp6VvhiA.js.map +1 -0
  214. package/dist/{tooltip-Dxl5Wa8i.mjs → tooltip-CVIl6Hln.js} +1 -1
  215. package/dist/tooltip-CVIl6Hln.js.map +1 -0
  216. package/dist/{types-YLu40dXY.d.mts → types-BVSfF-1o.d.ts} +1 -1
  217. package/dist/{types-B5nyTWtO.mjs → types-BZqffRVJ.js} +1 -1
  218. package/dist/types-BZqffRVJ.js.map +1 -0
  219. package/dist/typography/paragraph.d.cts +5 -5
  220. package/dist/typography/{paragraph.d.mts → paragraph.d.ts} +6 -6
  221. package/dist/typography/paragraph.js +1 -0
  222. package/dist/typography/{title.d.mts → title.d.ts} +1 -1
  223. package/dist/typography/{title.mjs → title.js} +1 -1
  224. package/dist/typography/title.js.map +1 -0
  225. package/dist/ui/alert-dialog.d.cts +12 -12
  226. package/dist/ui/{alert-dialog.d.mts → alert-dialog.d.ts} +13 -13
  227. package/dist/ui/alert-dialog.js +2 -0
  228. package/dist/ui/alert-dialog.js.map +1 -0
  229. package/dist/ui/alert.d.cts +1 -1
  230. package/dist/ui/{alert.d.mts → alert.d.ts} +1 -1
  231. package/dist/ui/alert.js +1 -0
  232. package/dist/ui/aspect-ratio.d.cts +2 -2
  233. package/dist/ui/{aspect-ratio.d.mts → aspect-ratio.d.ts} +3 -3
  234. package/dist/ui/{aspect-ratio.mjs → aspect-ratio.js} +1 -1
  235. package/dist/ui/aspect-ratio.js.map +1 -0
  236. package/dist/ui/avatar.d.cts +4 -4
  237. package/dist/ui/{avatar.d.mts → avatar.d.ts} +5 -5
  238. package/dist/ui/avatar.js +1 -0
  239. package/dist/ui/badge.d.cts +1 -1
  240. package/dist/ui/badge.d.ts +2 -0
  241. package/dist/ui/badge.js +1 -0
  242. package/dist/ui/breadcrumb.d.cts +8 -8
  243. package/dist/ui/{breadcrumb.d.mts → breadcrumb.d.ts} +9 -9
  244. package/dist/ui/breadcrumb.js +2 -0
  245. package/dist/ui/breadcrumb.js.map +1 -0
  246. package/dist/ui/button-group.d.cts +6 -6
  247. package/dist/ui/{button-group.d.mts → button-group.d.ts} +8 -8
  248. package/dist/ui/button-group.js +2 -0
  249. package/dist/ui/button-group.js.map +1 -0
  250. package/dist/ui/button.d.cts +1 -1
  251. package/dist/ui/button.d.ts +2 -0
  252. package/dist/ui/button.js +1 -0
  253. package/dist/ui/buttons/{add-new.d.mts → add-new.d.ts} +1 -1
  254. package/dist/ui/buttons/add-new.js +2 -0
  255. package/dist/ui/buttons/add-new.js.map +1 -0
  256. package/dist/ui/buttons/{edit.d.mts → edit.d.ts} +1 -1
  257. package/dist/ui/buttons/edit.js +2 -0
  258. package/dist/ui/buttons/edit.js.map +1 -0
  259. package/dist/ui/buttons/{refresh.d.mts → refresh.d.ts} +1 -1
  260. package/dist/ui/buttons/refresh.js +2 -0
  261. package/dist/ui/buttons/refresh.js.map +1 -0
  262. package/dist/ui/buttons/{trash.d.mts → trash.d.ts} +1 -1
  263. package/dist/ui/buttons/trash.js +2 -0
  264. package/dist/ui/buttons/trash.js.map +1 -0
  265. package/dist/ui/buttons/{upload-image.d.mts → upload-image.d.ts} +1 -1
  266. package/dist/ui/buttons/upload-image.js +2 -0
  267. package/dist/ui/buttons/upload-image.js.map +1 -0
  268. package/dist/ui/calendar.d.cts +4 -4
  269. package/dist/ui/{calendar.d.mts → calendar.d.ts} +5 -5
  270. package/dist/ui/calendar.js +1 -0
  271. package/dist/ui/card.d.cts +8 -8
  272. package/dist/ui/{card.d.mts → card.d.ts} +9 -9
  273. package/dist/ui/card.js +2 -0
  274. package/dist/ui/card.js.map +1 -0
  275. package/dist/ui/carousel.d.cts +7 -7
  276. package/dist/ui/{carousel.d.mts → carousel.d.ts} +8 -8
  277. package/dist/ui/carousel.js +2 -0
  278. package/dist/ui/carousel.js.map +1 -0
  279. package/dist/ui/checkbox.d.cts +2 -2
  280. package/dist/ui/{checkbox.d.mts → checkbox.d.ts} +3 -3
  281. package/dist/ui/checkbox.js +1 -0
  282. package/dist/ui/collapsible.d.cts +4 -4
  283. package/dist/ui/{collapsible.d.mts → collapsible.d.ts} +5 -5
  284. package/dist/ui/{collapsible.mjs → collapsible.js} +1 -1
  285. package/dist/ui/collapsible.js.map +1 -0
  286. package/dist/ui/command.d.cts +11 -11
  287. package/dist/ui/{command.d.mts → command.d.ts} +12 -12
  288. package/dist/ui/command.js +1 -0
  289. package/dist/ui/context-menu.d.cts +16 -16
  290. package/dist/ui/{context-menu.d.mts → context-menu.d.ts} +17 -17
  291. package/dist/ui/{context-menu.mjs → context-menu.js} +1 -1
  292. package/dist/ui/context-menu.js.map +1 -0
  293. package/dist/ui/dialog.d.cts +1 -1
  294. package/dist/ui/{dialog.d.mts → dialog.d.ts} +1 -1
  295. package/dist/ui/dialog.js +1 -0
  296. package/dist/ui/drawer.d.cts +11 -11
  297. package/dist/ui/{drawer.d.mts → drawer.d.ts} +12 -12
  298. package/dist/ui/drawer.js +1 -0
  299. package/dist/ui/dropdown-menu.d.cts +16 -16
  300. package/dist/ui/{dropdown-menu.d.mts → dropdown-menu.d.ts} +17 -17
  301. package/dist/ui/dropdown-menu.js +1 -0
  302. package/dist/ui/empty.d.cts +9 -9
  303. package/dist/ui/{empty.d.mts → empty.d.ts} +10 -10
  304. package/dist/ui/{empty.mjs → empty.js} +1 -1
  305. package/dist/ui/empty.js.map +1 -0
  306. package/dist/ui/field.d.cts +23 -23
  307. package/dist/ui/field.d.ts +65 -0
  308. package/dist/ui/field.js +1 -0
  309. package/dist/ui/file-uploader.d.cts +2 -2
  310. package/dist/ui/{file-uploader.d.mts → file-uploader.d.ts} +3 -3
  311. package/dist/ui/file-uploader.js +3 -0
  312. package/dist/ui/file-uploader.js.map +1 -0
  313. package/dist/ui/form.d.cts +10 -10
  314. package/dist/ui/{form.d.mts → form.d.ts} +11 -11
  315. package/dist/ui/form.js +2 -0
  316. package/dist/ui/form.js.map +1 -0
  317. package/dist/ui/hover-card.d.cts +4 -4
  318. package/dist/ui/{hover-card.d.mts → hover-card.d.ts} +5 -5
  319. package/dist/ui/{hover-card.mjs → hover-card.js} +1 -1
  320. package/dist/ui/hover-card.js.map +1 -0
  321. package/dist/ui/{image.d.mts → image.d.ts} +1 -1
  322. package/dist/ui/image.js +1 -0
  323. package/dist/ui/input-otp.d.cts +5 -5
  324. package/dist/ui/{input-otp.d.mts → input-otp.d.ts} +6 -6
  325. package/dist/ui/{input-otp.mjs → input-otp.js} +1 -1
  326. package/dist/ui/input-otp.js.map +1 -0
  327. package/dist/ui/input.d.cts +1 -1
  328. package/dist/ui/input.d.ts +2 -0
  329. package/dist/ui/input.js +1 -0
  330. package/dist/ui/inputs/search-input.d.cts +3 -3
  331. package/dist/ui/inputs/{search-input.d.mts → search-input.d.ts} +4 -4
  332. package/dist/ui/inputs/search-input.js +2 -0
  333. package/dist/ui/inputs/search-input.js.map +1 -0
  334. package/dist/ui/item.d.cts +16 -16
  335. package/dist/ui/{item.d.mts → item.d.ts} +18 -18
  336. package/dist/ui/item.js +2 -0
  337. package/dist/ui/item.js.map +1 -0
  338. package/dist/ui/label.d.cts +2 -2
  339. package/dist/ui/{label.d.mts → label.d.ts} +3 -3
  340. package/dist/ui/label.js +1 -0
  341. package/dist/ui/menubar.d.cts +17 -17
  342. package/dist/ui/{menubar.d.mts → menubar.d.ts} +18 -18
  343. package/dist/ui/{menubar.mjs → menubar.js} +1 -1
  344. package/dist/ui/menubar.js.map +1 -0
  345. package/dist/ui/multi-select.d.cts +2 -2
  346. package/dist/ui/{multi-select.d.mts → multi-select.d.ts} +5 -5
  347. package/dist/ui/multi-select.js +2 -0
  348. package/dist/ui/multi-select.js.map +1 -0
  349. package/dist/ui/navigation-menu.d.cts +11 -11
  350. package/dist/ui/{navigation-menu.d.mts → navigation-menu.d.ts} +12 -12
  351. package/dist/ui/{navigation-menu.mjs → navigation-menu.js} +1 -1
  352. package/dist/ui/navigation-menu.js.map +1 -0
  353. package/dist/ui/pagination.d.cts +9 -9
  354. package/dist/ui/{pagination.d.mts → pagination.d.ts} +10 -10
  355. package/dist/ui/pagination.js +2 -0
  356. package/dist/ui/pagination.js.map +1 -0
  357. package/dist/ui/popover.d.cts +6 -6
  358. package/dist/ui/{popover.d.mts → popover.d.ts} +7 -7
  359. package/dist/ui/popover.js +1 -0
  360. package/dist/ui/progress.d.cts +2 -2
  361. package/dist/ui/{progress.d.mts → progress.d.ts} +3 -3
  362. package/dist/ui/progress.js +1 -0
  363. package/dist/ui/radio-group.d.cts +3 -3
  364. package/dist/ui/{radio-group.d.mts → radio-group.d.ts} +4 -4
  365. package/dist/ui/radio-group.js +1 -0
  366. package/dist/ui/resizable.d.cts +9 -9
  367. package/dist/ui/{resizable.d.mts → resizable.d.ts} +10 -10
  368. package/dist/ui/resizable.js +1 -0
  369. package/dist/ui/scroll-area.d.cts +5 -5
  370. package/dist/ui/{scroll-area.d.mts → scroll-area.d.ts} +6 -6
  371. package/dist/ui/{scroll-area.mjs → scroll-area.js} +1 -1
  372. package/dist/ui/scroll-area.js.map +1 -0
  373. package/dist/ui/select.d.cts +9 -9
  374. package/dist/ui/{select.d.mts → select.d.ts} +10 -10
  375. package/dist/ui/select.js +1 -0
  376. package/dist/ui/separator.d.cts +2 -2
  377. package/dist/ui/{separator.d.mts → separator.d.ts} +3 -3
  378. package/dist/ui/separator.js +1 -0
  379. package/dist/ui/sheet.d.cts +9 -9
  380. package/dist/ui/{sheet.d.mts → sheet.d.ts} +10 -10
  381. package/dist/ui/sheet.js +1 -0
  382. package/dist/ui/skeleton.d.cts +2 -2
  383. package/dist/ui/{skeleton.d.mts → skeleton.d.ts} +3 -3
  384. package/dist/ui/skeleton.js +1 -0
  385. package/dist/ui/slider.d.cts +2 -2
  386. package/dist/ui/{slider.d.mts → slider.d.ts} +3 -3
  387. package/dist/ui/{slider.mjs → slider.js} +1 -1
  388. package/dist/ui/slider.js.map +1 -0
  389. package/dist/ui/sonner.d.cts +2 -2
  390. package/dist/ui/{sonner.d.mts → sonner.d.ts} +3 -3
  391. package/dist/ui/{sonner.mjs → sonner.js} +1 -1
  392. package/dist/ui/sonner.js.map +1 -0
  393. package/dist/ui/spinner.d.cts +2 -2
  394. package/dist/ui/{spinner.d.mts → spinner.d.ts} +3 -3
  395. package/dist/ui/spinner.js +1 -0
  396. package/dist/ui/switch.d.cts +2 -2
  397. package/dist/ui/{switch.d.mts → switch.d.ts} +3 -3
  398. package/dist/ui/switch.js +1 -0
  399. package/dist/ui/table.d.cts +17 -17
  400. package/dist/ui/{table.d.mts → table.d.ts} +18 -18
  401. package/dist/ui/{table.mjs → table.js} +1 -1
  402. package/dist/ui/table.js.map +1 -0
  403. package/dist/ui/tabs.d.cts +5 -5
  404. package/dist/ui/{tabs.d.mts → tabs.d.ts} +6 -6
  405. package/dist/ui/{tabs.mjs → tabs.js} +1 -1
  406. package/dist/ui/tabs.js.map +1 -0
  407. package/dist/ui/textarea.d.cts +2 -2
  408. package/dist/ui/{textarea.d.mts → textarea.d.ts} +3 -3
  409. package/dist/ui/textarea.js +1 -0
  410. package/dist/ui/toggle-group.d.cts +3 -3
  411. package/dist/ui/{toggle-group.d.mts → toggle-group.d.ts} +5 -5
  412. package/dist/ui/toggle-group.js +2 -0
  413. package/dist/ui/toggle-group.js.map +1 -0
  414. package/dist/ui/toggle.d.cts +5 -5
  415. package/dist/ui/{toggle.d.mts → toggle.d.ts} +4 -4
  416. package/dist/ui/{toggle.mjs → toggle.js} +1 -1
  417. package/dist/ui/toggle.js.map +1 -0
  418. package/dist/ui/tooltip.d.cts +5 -5
  419. package/dist/ui/{tooltip.d.mts → tooltip.d.ts} +6 -6
  420. package/dist/ui/tooltip.js +1 -0
  421. package/dist/user-BSpgswEC.js +2 -0
  422. package/dist/user-BSpgswEC.js.map +1 -0
  423. package/package.json +97 -97
  424. package/dist/alert-BbvPwf2x.mjs.map +0 -1
  425. package/dist/avatar-fltdRVsJ.mjs.map +0 -1
  426. package/dist/badge-CDGBGq8X.mjs.map +0 -1
  427. package/dist/button-CCVJTHBI.mjs +0 -2
  428. package/dist/button-CCVJTHBI.mjs.map +0 -1
  429. package/dist/button.variants-DkMqWB8G.mjs.map +0 -1
  430. package/dist/calendar-R866yyd1.mjs +0 -2
  431. package/dist/calendar-R866yyd1.mjs.map +0 -1
  432. package/dist/cards/grid-product-card.mjs +0 -2
  433. package/dist/cards/grid-product-card.mjs.map +0 -1
  434. package/dist/cards/product-card.mjs +0 -2
  435. package/dist/cards/product-card.mjs.map +0 -1
  436. package/dist/cards/simple-card.mjs +0 -2
  437. package/dist/cards/simple-card.mjs.map +0 -1
  438. package/dist/checkbox-Cat3i08X.mjs.map +0 -1
  439. package/dist/close-_UHFeiLS.mjs.map +0 -1
  440. package/dist/cms-layout-DkCR1AfG.mjs +0 -2
  441. package/dist/cms-layout-DkCR1AfG.mjs.map +0 -1
  442. package/dist/command-D6_CSbwJ.mjs +0 -2
  443. package/dist/command-D6_CSbwJ.mjs.map +0 -1
  444. package/dist/data-display/country.mjs +0 -2
  445. package/dist/data-display/country.mjs.map +0 -1
  446. package/dist/data-display/data-list.mjs.map +0 -1
  447. package/dist/data-display/date-tooltip.mjs +0 -2
  448. package/dist/data-display/date-tooltip.mjs.map +0 -1
  449. package/dist/data-display/date.mjs +0 -1
  450. package/dist/data-display/empty.mjs.map +0 -1
  451. package/dist/data-display/name.mjs +0 -2
  452. package/dist/data-display/name.mjs.map +0 -1
  453. package/dist/data-display/phone-number.mjs +0 -2
  454. package/dist/data-display/phone-number.mjs.map +0 -1
  455. package/dist/data-display/role-badge.mjs +0 -2
  456. package/dist/data-display/role-badge.mjs.map +0 -1
  457. package/dist/data-display/statistic.mjs +0 -1
  458. package/dist/data-display/user.mjs +0 -1
  459. package/dist/date-fY3sUcLp.mjs.map +0 -1
  460. package/dist/dialog-CLDnvNH_.mjs +0 -2
  461. package/dist/dialog-CLDnvNH_.mjs.map +0 -1
  462. package/dist/dialogs/confirm-dialog.mjs +0 -2
  463. package/dist/dialogs/confirm-dialog.mjs.map +0 -1
  464. package/dist/dialogs/detail-dialog/components/sidebar.mjs +0 -1
  465. package/dist/dialogs/detail-dialog/index.mjs +0 -2
  466. package/dist/dialogs/detail-dialog/index.mjs.map +0 -1
  467. package/dist/dialogs/error-dialog.mjs +0 -2
  468. package/dist/dialogs/error-dialog.mjs.map +0 -1
  469. package/dist/dialogs/loading-dialog.mjs +0 -2
  470. package/dist/dialogs/loading-dialog.mjs.map +0 -1
  471. package/dist/dist-DVrfqn8H.mjs.map +0 -1
  472. package/dist/drawer-CMD7JWH8.mjs.map +0 -1
  473. package/dist/dropdown-menu-BWhiVsEf.mjs.map +0 -1
  474. package/dist/features/descriptions/index.mjs +0 -2
  475. package/dist/features/descriptions/index.mjs.map +0 -1
  476. package/dist/features/search-modal/index.mjs +0 -1
  477. package/dist/features/tables/index.mjs +0 -1
  478. package/dist/features/tanstack-form/index.d.mts +0 -2
  479. package/dist/features/tanstack-form/index.mjs +0 -1
  480. package/dist/features/text-editor/index.mjs +0 -1
  481. package/dist/field-dYemS0hQ.mjs +0 -2
  482. package/dist/field-dYemS0hQ.mjs.map +0 -1
  483. package/dist/flex-B6YSJzGe.mjs.map +0 -1
  484. package/dist/heading-De4Pn3mZ.mjs.map +0 -1
  485. package/dist/image-D7OZ13Ib.mjs +0 -2
  486. package/dist/image-D7OZ13Ib.mjs.map +0 -1
  487. package/dist/index.d.mts +0 -93
  488. package/dist/index.mjs +0 -1
  489. package/dist/input-NJP2wQOm.mjs.map +0 -1
  490. package/dist/label-CUCpwS5D.mjs.map +0 -1
  491. package/dist/layouts/cms-layout/index.d.mts +0 -2
  492. package/dist/layouts/cms-layout/index.mjs +0 -1
  493. package/dist/layouts/flex.mjs +0 -1
  494. package/dist/layouts/grid.mjs.map +0 -1
  495. package/dist/layouts/payment-layout/index.mjs +0 -1
  496. package/dist/pages/FeatureDeveloping.mjs +0 -2
  497. package/dist/pages/FeatureDeveloping.mjs.map +0 -1
  498. package/dist/pages/FeatureFixing.mjs +0 -2
  499. package/dist/pages/FeatureFixing.mjs.map +0 -1
  500. package/dist/pages/LoginPage.mjs +0 -2
  501. package/dist/pages/LoginPage.mjs.map +0 -1
  502. package/dist/pages/NotAuthorized.mjs +0 -2
  503. package/dist/pages/NotAuthorized.mjs.map +0 -1
  504. package/dist/pages/NotFound.mjs +0 -2
  505. package/dist/pages/NotFound.mjs.map +0 -1
  506. package/dist/pages/RegisterPage.mjs +0 -2
  507. package/dist/pages/RegisterPage.mjs.map +0 -1
  508. package/dist/pages/VerifyEmailPage.mjs +0 -2
  509. package/dist/pages/VerifyEmailPage.mjs.map +0 -1
  510. package/dist/paragraph-DYLaQtTV.mjs.map +0 -1
  511. package/dist/payment-layout-DrQ0kZPX.mjs +0 -2
  512. package/dist/payment-layout-DrQ0kZPX.mjs.map +0 -1
  513. package/dist/popover-C8rcemA3.mjs +0 -2
  514. package/dist/popover-C8rcemA3.mjs.map +0 -1
  515. package/dist/progress-CLeM0e7Z.mjs.map +0 -1
  516. package/dist/radio-group-Y9bhdr55.mjs.map +0 -1
  517. package/dist/resizable-CpCaSCFB.mjs.map +0 -1
  518. package/dist/search-modal-Bn-GOOCy.mjs +0 -2
  519. package/dist/search-modal-Bn-GOOCy.mjs.map +0 -1
  520. package/dist/select-LlPCZFSF.mjs.map +0 -1
  521. package/dist/separator-D3Gmkxzq.mjs.map +0 -1
  522. package/dist/sheet-BFlIfNaA.mjs.map +0 -1
  523. package/dist/sidebar-ChtCyu-n.mjs +0 -2
  524. package/dist/sidebar-ChtCyu-n.mjs.map +0 -1
  525. package/dist/skeleton-C51IdOfK.mjs.map +0 -1
  526. package/dist/spinner-eClTgHjk.mjs.map +0 -1
  527. package/dist/statistic-cwLwcukn.mjs.map +0 -1
  528. package/dist/switch-BP7EPatj.mjs.map +0 -1
  529. package/dist/systems/google.mjs.map +0 -1
  530. package/dist/tables-CFrsk2lM.mjs +0 -4
  531. package/dist/tables-CFrsk2lM.mjs.map +0 -1
  532. package/dist/tanstack-form-DT1TqIDl.mjs +0 -12
  533. package/dist/tanstack-form-DT1TqIDl.mjs.map +0 -1
  534. package/dist/text-editor-5mA7XyaI.mjs +0 -2
  535. package/dist/text-editor-5mA7XyaI.mjs.map +0 -1
  536. package/dist/textarea-7HDXcaK9.mjs.map +0 -1
  537. package/dist/tooltip-Dxl5Wa8i.mjs.map +0 -1
  538. package/dist/types-B5nyTWtO.mjs.map +0 -1
  539. package/dist/typography/paragraph.mjs +0 -1
  540. package/dist/typography/title.mjs.map +0 -1
  541. package/dist/ui/alert-dialog.mjs +0 -2
  542. package/dist/ui/alert-dialog.mjs.map +0 -1
  543. package/dist/ui/alert.mjs +0 -1
  544. package/dist/ui/aspect-ratio.mjs.map +0 -1
  545. package/dist/ui/avatar.mjs +0 -1
  546. package/dist/ui/badge.d.mts +0 -2
  547. package/dist/ui/badge.mjs +0 -1
  548. package/dist/ui/breadcrumb.mjs +0 -2
  549. package/dist/ui/breadcrumb.mjs.map +0 -1
  550. package/dist/ui/button-group.mjs +0 -2
  551. package/dist/ui/button-group.mjs.map +0 -1
  552. package/dist/ui/button.d.mts +0 -2
  553. package/dist/ui/button.mjs +0 -1
  554. package/dist/ui/buttons/add-new.mjs +0 -2
  555. package/dist/ui/buttons/add-new.mjs.map +0 -1
  556. package/dist/ui/buttons/edit.mjs +0 -2
  557. package/dist/ui/buttons/edit.mjs.map +0 -1
  558. package/dist/ui/buttons/refresh.mjs +0 -2
  559. package/dist/ui/buttons/refresh.mjs.map +0 -1
  560. package/dist/ui/buttons/trash.mjs +0 -2
  561. package/dist/ui/buttons/trash.mjs.map +0 -1
  562. package/dist/ui/buttons/upload-image.mjs +0 -2
  563. package/dist/ui/buttons/upload-image.mjs.map +0 -1
  564. package/dist/ui/calendar.mjs +0 -1
  565. package/dist/ui/card.mjs +0 -2
  566. package/dist/ui/card.mjs.map +0 -1
  567. package/dist/ui/carousel.mjs +0 -2
  568. package/dist/ui/carousel.mjs.map +0 -1
  569. package/dist/ui/checkbox.mjs +0 -1
  570. package/dist/ui/collapsible.mjs.map +0 -1
  571. package/dist/ui/command.mjs +0 -1
  572. package/dist/ui/context-menu.mjs.map +0 -1
  573. package/dist/ui/dialog.mjs +0 -1
  574. package/dist/ui/drawer.mjs +0 -1
  575. package/dist/ui/dropdown-menu.mjs +0 -1
  576. package/dist/ui/empty.mjs.map +0 -1
  577. package/dist/ui/field.d.mts +0 -65
  578. package/dist/ui/field.mjs +0 -1
  579. package/dist/ui/file-uploader.mjs +0 -3
  580. package/dist/ui/file-uploader.mjs.map +0 -1
  581. package/dist/ui/form.mjs +0 -2
  582. package/dist/ui/form.mjs.map +0 -1
  583. package/dist/ui/hover-card.mjs.map +0 -1
  584. package/dist/ui/image.mjs +0 -1
  585. package/dist/ui/input-otp.mjs.map +0 -1
  586. package/dist/ui/input.d.mts +0 -2
  587. package/dist/ui/input.mjs +0 -1
  588. package/dist/ui/inputs/search-input.mjs +0 -2
  589. package/dist/ui/inputs/search-input.mjs.map +0 -1
  590. package/dist/ui/item.mjs +0 -2
  591. package/dist/ui/item.mjs.map +0 -1
  592. package/dist/ui/label.mjs +0 -1
  593. package/dist/ui/menubar.mjs.map +0 -1
  594. package/dist/ui/multi-select.mjs +0 -2
  595. package/dist/ui/multi-select.mjs.map +0 -1
  596. package/dist/ui/navigation-menu.mjs.map +0 -1
  597. package/dist/ui/pagination.mjs +0 -2
  598. package/dist/ui/pagination.mjs.map +0 -1
  599. package/dist/ui/popover.mjs +0 -1
  600. package/dist/ui/progress.mjs +0 -1
  601. package/dist/ui/radio-group.mjs +0 -1
  602. package/dist/ui/resizable.mjs +0 -1
  603. package/dist/ui/scroll-area.mjs.map +0 -1
  604. package/dist/ui/select.mjs +0 -1
  605. package/dist/ui/separator.mjs +0 -1
  606. package/dist/ui/sheet.mjs +0 -1
  607. package/dist/ui/skeleton.mjs +0 -1
  608. package/dist/ui/slider.mjs.map +0 -1
  609. package/dist/ui/sonner.mjs.map +0 -1
  610. package/dist/ui/spinner.mjs +0 -1
  611. package/dist/ui/switch.mjs +0 -1
  612. package/dist/ui/table.mjs.map +0 -1
  613. package/dist/ui/tabs.mjs.map +0 -1
  614. package/dist/ui/textarea.mjs +0 -1
  615. package/dist/ui/toggle-group.mjs +0 -2
  616. package/dist/ui/toggle-group.mjs.map +0 -1
  617. package/dist/ui/toggle.mjs.map +0 -1
  618. package/dist/ui/tooltip.mjs +0 -1
  619. package/dist/user-DtZy4P9d.mjs +0 -2
  620. package/dist/user-DtZy4P9d.mjs.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"file-uploader.mjs","names":[],"sources":["../../packages/components/ui/file-uploader.tsx"],"sourcesContent":["'use client';\nimport { useCallback, useEffect } from 'react';\nimport Dropzone, { type DropzoneProps, type FileRejection } from 'react-dropzone';\nimport { useControllableState } from '@customafk/react-toolkit/hooks/useControllableState';\nimport { cn, formatBytes } from '@customafk/react-toolkit/utils';\n\nimport { FileText, Image, Trash2, Upload } from 'lucide-react';\nimport { toast } from 'sonner';\n\nimport { Button } from '@/components/ui/button';\nimport { Progress } from '@/components/ui/progress';\n\n/**\n * Props for the FileUploader component.\n *\n * @example\n * ```tsx\n * import { FileUploader } from '@customafk/lunas-ui/ui/file-uploader';\n *\n * <FileUploader\n * accept={{ 'image/*': [] }}\n * maxSize={1024 * 1024 * 5}\n * maxFileCount={3}\n * multiple\n * onUpload={async (files) => { await uploadFiles(files); }}\n * />\n * ```\n */\ninterface FileUploaderProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Value of the uploader.\n * @type File[]\n * @default undefined\n * @example value={files}\n */\n value?: File[];\n\n /**\n * Function to be called when the value changes.\n * @type (files: File[]) => void\n * @default undefined\n * @example onValueChange={(files) => setFiles(files)}\n */\n onValueChange?: (files: File[]) => void;\n\n /**\n * Function to be called when files are uploaded.\n * @type (files: File[]) => Promise<void>\n * @default undefined\n * @example onUpload={(files) => uploadFiles(files)}\n */\n onUpload?: (files: File[]) => Promise<void>;\n\n /**\n * Progress of the uploaded files.\n * @type Record<string, number> | undefined\n * @default undefined\n * @example progresses={{ \"file1.png\": 50 }}\n */\n progresses?: Record<string, number>;\n\n /**\n * Accepted file types for the uploader.\n * @type { [key: string]: string[]}\n * @default\n * ```ts\n * { \"image/*\": [] }\n * ```\n * @example accept={[\"image/png\", \"image/jpeg\"]}\n */\n accept?: DropzoneProps['accept'];\n\n /**\n * Maximum file size for the uploader.\n * @type number | undefined\n * @default 1024 * 1024 * 2 // 2MB\n * @example maxSize={1024 * 1024 * 2} // 2MB\n */\n maxSize?: DropzoneProps['maxSize'];\n\n /**\n * Maximum number of files for the uploader.\n * @type number | undefined\n * @default 1\n * @example maxFileCount={4}\n */\n maxFileCount?: DropzoneProps['maxFiles'];\n\n /**\n * Whether the uploader should accept multiple files.\n * @type boolean\n * @default false\n * @example multiple\n */\n multiple?: boolean;\n\n /**\n * Whether the uploader is disabled.\n * @type boolean\n * @default false\n * @example disabled\n */\n disabled?: boolean;\n\n /**\n * Whether to show the instructional drag-and-drop text inside the drop zone.\n * @default true\n */\n showText?: boolean;\n /** Size in pixels for the upload icon. */\n iconSize?: number;\n}\n\n/**\n * A drag-and-drop file upload zone that manages file selection, validation, preview generation, and optional async upload with progress tracking.\n */\nexport function FileUploader(props: FileUploaderProps) {\n const {\n value: valueProp,\n onValueChange,\n onUpload,\n progresses,\n accept = {\n 'image/*': [],\n },\n maxSize = 1024 * 1024 * 2,\n maxFileCount = 1,\n multiple = false,\n disabled = false,\n showText = true,\n iconSize,\n className,\n ...dropzoneProps\n } = props;\n\n const [files, setFiles] = useControllableState({\n prop: valueProp,\n onChange: onValueChange,\n });\n\n const onDrop = useCallback(\n (acceptedFiles: File[], rejectedFiles: FileRejection[]) => {\n if (!multiple && maxFileCount === 1 && acceptedFiles.length > 1) {\n toast.error('Cannot upload more than 1 file at a time');\n\n return;\n }\n\n if ((files?.length ?? 0) + acceptedFiles.length > maxFileCount) {\n toast.error(`Cannot upload more than ${maxFileCount} files`);\n return;\n }\n\n const newFiles = acceptedFiles.map(file =>\n Object.assign(file, {\n preview: URL.createObjectURL(file),\n })\n );\n\n const updatedFiles = files ? [...files, ...newFiles] : newFiles;\n\n setFiles(updatedFiles);\n\n if (rejectedFiles.length > 0) {\n rejectedFiles.forEach(({ file }) => {\n toast.error(`File ${file.name} was rejected`);\n });\n }\n\n if (onUpload && updatedFiles.length > 0 && updatedFiles.length <= maxFileCount) {\n const target = updatedFiles.length > 0 ? `${updatedFiles.length} files` : `file`;\n\n onUpload(updatedFiles).then(() => {\n setFiles([]);\n toast(`${target} uploaded`);\n });\n }\n },\n\n [files, maxFileCount, multiple, onUpload, setFiles]\n );\n\n function onRemove(index: number) {\n if (!files) return;\n\n if (isFileWithPreview(files[index])) {\n URL.revokeObjectURL(files[index].preview);\n }\n\n const newFiles = files.filter((_, i) => i !== index);\n setFiles(newFiles);\n onValueChange?.(newFiles);\n }\n\n // Revoke preview url when component unmounts\n useEffect(() => {\n return () => {\n if (!files) return;\n files.forEach(file => {\n if (isFileWithPreview(file)) {\n URL.revokeObjectURL(file.preview);\n }\n });\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const isDisabled = disabled || (files?.length ?? 0) >= maxFileCount;\n\n return (\n <div className=\"relative flex w-full flex-col gap-6\">\n <Dropzone onDrop={onDrop} accept={accept} maxSize={maxSize} maxFiles={maxFileCount} multiple={maxFileCount > 1 || multiple} disabled={isDisabled}>\n {({ getRootProps, getInputProps, isDragActive }) => (\n <div\n {...getRootProps()}\n className={cn(\n 'group',\n 'border-border-weak',\n 'hover:bg-border-weak/20',\n 'relative grid h-52 w-full cursor-pointer place-items-center rounded-lg border-2 border-dashed px-5 py-2.5 text-center transition',\n 'ring-offset-background',\n 'focus-visible:ring-primary-weak',\n 'focus-visible:ring-2',\n 'focus-visible:ring-offset-2',\n 'focus-visible:outline-hidden',\n isDragActive && 'border-border-primary-strong bg-border-weak/40',\n isDisabled && 'pointer-events-none opacity-60',\n className\n )}\n {...dropzoneProps}\n >\n <input {...getInputProps()} />\n {isDragActive ? (\n <div className=\"flex flex-col items-center justify-center gap-4 sm:px-5\">\n <div className=\"rounded-full border border-dashed p-3\">\n <Upload className=\"text-text-positive-muted size-7\" aria-hidden=\"true\" />\n </div>\n <p className=\"text-text-positive-muted font-medium\">Drop the files here</p>\n </div>\n ) : (\n <div className=\"flex flex-col items-center justify-center gap-4 sm:px-5\">\n <div className=\"rounded-full border border-dashed p-3\">\n <Upload size={iconSize || 24} className=\"text-muted-foreground\" aria-hidden=\"true\" />\n </div>\n {showText && (\n <div className=\"flex flex-col gap-px\">\n <p className=\"text-text-positive-weak text-xs font-medium\">Drag {`'n'`} drop files here, or click to select files</p>\n <p className=\"text-text-positive-muted text-xs\">\n You can upload\n {maxFileCount > 1\n ? ` ${maxFileCount === Infinity ? 'multiple' : maxFileCount}\n files (up to ${formatBytes(maxSize)} each)`\n : ` a file with ${formatBytes(maxSize)}`}\n </p>\n </div>\n )}\n </div>\n )}\n </div>\n )}\n </Dropzone>\n {files?.length ? (\n <div className=\"h-fit w-full overflow-y-auto\">\n <div className=\"flex items-center justify-between px-3 py-2.5\">\n <div className=\"text-text-positive-weak flex items-center gap-1\">\n <Image size={16} aria-hidden=\"true\" />\n <p className=\"text-sm\">Ảnh đã tải lên ({files.length})</p>\n </div>\n <button\n className=\"hover:text-text-positive text-text-positive-muted flex cursor-pointer items-center gap-1 transition-colors duration-200\"\n onClick={() => {\n if (!files) return;\n files.forEach(file => {\n if (!isFileWithPreview(file)) return;\n URL.revokeObjectURL(file.preview);\n });\n setFiles([]);\n onValueChange?.([]);\n }}\n >\n <Trash2 size={16} aria-hidden=\"true\" />\n <p className=\"text-sm\">Xóa tất cả</p>\n </button>\n </div>\n <div className=\"flex flex-col gap-2.5\">\n {files?.map((file, index) => (\n <FileCard key={index} file={file} onRemove={() => onRemove(index)} progress={progresses?.[file.name]} />\n ))}\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\ninterface FileCardProps {\n file: File;\n onRemove: () => void;\n progress?: number;\n}\n\nfunction FileCard({ file, progress, onRemove }: FileCardProps) {\n return (\n <div className=\"border-border-weak hover:border-border relative flex items-center gap-4 rounded-md border py-2 pr-3 pl-2 shadow-xs transition-colors\">\n <div className=\"flex flex-1 gap-2.5\">\n {isFileWithPreview(file) ? <FilePreview file={file} /> : null}\n <div className=\"flex w-full flex-col gap-2\">\n <div className=\"flex flex-col gap-y-0.5\">\n <p className=\"text-text-positive line-clamp-1 text-sm\">{file.name}</p>\n <p className=\"text-text-positive-muted text-xs\">{formatBytes(file.size)}</p>\n </div>\n {progress ? <Progress value={progress} /> : null}\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <Button type=\"button\" variant=\"ghost\" color=\"secondary\" size=\"icon\" className=\"size-7\" onClick={onRemove}>\n <Trash2 size={16} className=\"text-text-positive-muted\" aria-hidden=\"true\" />\n <span className=\"sr-only\">Remove file</span>\n </Button>\n </div>\n </div>\n );\n}\n\nfunction isFileWithPreview(file: File): file is File & { preview: string } {\n return 'preview' in file && typeof file.preview === 'string';\n}\n\ninterface FilePreviewProps {\n file: File & { preview: string };\n}\n\nfunction FilePreview({ file }: FilePreviewProps) {\n if (file.type.startsWith('image/')) {\n return <img src={file.preview} className=\"border-border aspect-square size-10 shrink-0 rounded border object-cover object-top shadow-sm\" />;\n }\n\n return <FileText className=\"text-text-positive-muted size-10 border\" aria-hidden=\"true\" />;\n}\n"],"mappings":"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"}
package/dist/ui/form.mjs DELETED
@@ -1,2 +0,0 @@
1
- "use client";import"../separator-D3Gmkxzq.mjs";import"../label-CUCpwS5D.mjs";import{o as e,r as t,t as n}from"../field-dYemS0hQ.mjs";import{createContext as r,memo as i,use as a,useId as o}from"react";import{cn as s}from"@customafk/react-toolkit/utils";import{jsx as c}from"react/jsx-runtime";import{Slot as l}from"radix-ui";import{Controller as u,FormProvider as d,useFormContext as f,useFormState as p}from"react-hook-form";const m=d,h=r({}),g=({...e})=>c(h.Provider,{value:{name:e.name},children:c(u,{...e})}),_=()=>{let e=a(h),t=a(v),{getFieldState:n,control:r,resetField:i}=f(),o=p({name:e.name}),s=n(e.name,o);if(!e)throw Error(`useFormField should be used within <FormField>`);let{id:c}=t;return{id:c,control:r,resetField:i,name:e.name,formItemId:`${c}-form-item`,formDescriptionId:`${c}-form-item-description`,formMessageId:`${c}-form-item-message`,...s}},v=r({}),y=i(({className:e,orientation:t=`responsive`,...r})=>{let i=o();return c(v.Provider,{value:{id:i},children:c(n,{orientation:t,...r,className:e})})});y.displayName=`FormItem`;const b=i(({...t})=>{let{formItemId:n}=_();return c(e,{htmlFor:n,...t})});b.displayName=`FormLabel`;const x=i(({...e})=>{let{error:t,formItemId:n,formDescriptionId:r,formMessageId:i}=_();return c(l.Slot,{"data-slot":`form-control`,id:n,"aria-describedby":t?`${r} ${i}`:`${r}`,"aria-invalid":!!t,...e})});x.displayName=`FormControl`;function S({className:e,...n}){let{formDescriptionId:r}=_();return c(t,{id:r,className:s(`text-text-positive-weak text-sm/6 leading-normal font-normal`,`group-has-data-[orientation=horizontal]/field:text-balance`,`last:mt-0 nth-last-2:-mt-1 [[data-variant=legend]+&]:-mt-1.5`,`[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4`,e),...n})}function C({className:e,children:t,...n}){let{error:r,formMessageId:i}=_();return c(`span`,{"data-slot":`form-message`,id:i,className:s(`text-danger text-xs`,e),...n,children:r?String(r?.message??``):t})}export{m as Form,x as FormControl,S as FormDescription,g as FormField,y as FormItem,b as FormLabel,C as FormMessage,_ as useFormField};
2
- //# sourceMappingURL=form.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"form.mjs","names":["SlotPrimitive"],"sources":["../../packages/components/ui/form.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@customafk/react-toolkit/utils';\nimport { type Label as LabelPrimitive, Slot as SlotPrimitive } from 'radix-ui';\nimport { createContext, memo, use, useId } from 'react';\nimport type { ControllerProps, FieldPath, FieldValues } from 'react-hook-form';\nimport { Controller, FormProvider, useFormContext, useFormState } from 'react-hook-form';\nimport { Field, FieldDescription, FieldLabel } from './field';\n\n/**\n * Re-export of react-hook-form's `FormProvider`; wrap your form with this to give all nested form components access to the form context.\n *\n * @example\n * ```tsx\n * import { Form, FormField, FormItem, FormLabel, FormControl, FormMessage } from '@customafk/lunas-ui/ui/form';\n * import { useForm } from 'react-hook-form';\n *\n * const form = useForm<{ username: string }>();\n *\n * <Form {...form}>\n * <form onSubmit={form.handleSubmit(onSubmit)}>\n * <FormField\n * control={form.control}\n * name=\"username\"\n * render={({ field }) => (\n * <FormItem>\n * <FormLabel>Username</FormLabel>\n * <FormControl><input {...field} /></FormControl>\n * <FormMessage />\n * </FormItem>\n * )}\n * />\n * </form>\n * </Form>\n * ```\n */\nconst Form = FormProvider;\n\ntype FormFieldContextValue<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>> = {\n name: TName;\n};\n\nconst FormFieldContext = createContext<FormFieldContextValue>({} as FormFieldContextValue);\n\n/**\n * Connects a single react-hook-form field to the form context; renders a `Controller` and passes `name` down to nested FormItem, FormLabel, FormControl, and FormMessage.\n */\nconst FormField = <TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({\n ...props\n}: ControllerProps<TFieldValues, TName>) => {\n return (\n <FormFieldContext.Provider value={{ name: props.name }}>\n <Controller {...props} />\n </FormFieldContext.Provider>\n );\n};\n\n/**\n * Hook that returns the field state and IDs for the enclosing FormField.\n * Must be called inside a component rendered within a `<FormField>`.\n */\nconst useFormField = () => {\n const fieldContext = use(FormFieldContext);\n const itemContext = use(FormItemContext);\n const { getFieldState, control, resetField } = useFormContext();\n const formState = useFormState({ name: fieldContext.name });\n const fieldState = getFieldState(fieldContext.name, formState);\n\n if (!fieldContext) {\n throw new Error('useFormField should be used within <FormField>');\n }\n\n const { id } = itemContext;\n\n return {\n id,\n control,\n resetField,\n name: fieldContext.name,\n formItemId: `${id}-form-item`,\n formDescriptionId: `${id}-form-item-description`,\n formMessageId: `${id}-form-item-message`,\n ...fieldState,\n };\n};\n\ntype FormItemContextValue = {\n id: string;\n};\n\nconst FormItemContext = createContext<FormItemContextValue>({} as FormItemContextValue);\n\n/**\n * Container for a single form field — generates a unique ID and provides it via context to FormLabel, FormControl, and FormMessage.\n *\n * @param orientation - Layout direction: `'vertical'`, `'horizontal'`, or `'responsive'` (default).\n */\nconst FormItem = memo(\n ({\n className,\n orientation = 'responsive',\n ...props\n }: React.ComponentProps<'div'> & {\n orientation?: 'vertical' | 'horizontal' | 'responsive';\n }) => {\n const id = useId();\n\n return (\n <FormItemContext.Provider value={{ id }}>\n <Field orientation={orientation} {...props} className={className} />\n </FormItemContext.Provider>\n );\n }\n);\nFormItem.displayName = 'FormItem';\n\n/** Styled label automatically associated with the FormItem's control via `htmlFor`. */\nconst FormLabel = memo(({ ...props }: React.ComponentProps<typeof LabelPrimitive.Root>) => {\n const { formItemId } = useFormField();\n return <FieldLabel htmlFor={formItemId} {...props} />;\n});\nFormLabel.displayName = 'FormLabel';\n\n/** Radix Slot wrapper that wires the correct `id`, `aria-describedby`, and `aria-invalid` attributes onto the underlying control element. */\nconst FormControl = memo(({ ...props }: React.ComponentProps<typeof SlotPrimitive.Slot>) => {\n const { error, formItemId, formDescriptionId, formMessageId } = useFormField();\n\n return (\n <SlotPrimitive.Slot\n data-slot=\"form-control\"\n id={formItemId}\n aria-describedby={!error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`}\n aria-invalid={!!error}\n {...props}\n />\n );\n});\nFormControl.displayName = 'FormControl';\n\n/** Helper text displayed below the control that provides additional context about the field. */\nfunction FormDescription({ className, ...props }: React.ComponentProps<'p'>) {\n const { formDescriptionId } = useFormField();\n\n return (\n <FieldDescription\n id={formDescriptionId}\n className={cn(\n 'text-text-positive-weak text-sm/6 leading-normal font-normal',\n 'group-has-data-[orientation=horizontal]/field:text-balance',\n 'last:mt-0 nth-last-2:-mt-1 [[data-variant=legend]+&]:-mt-1.5',\n '[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4',\n className\n )}\n {...props}\n />\n );\n}\n\n/** Displays the validation error message for the field, or falls back to `children` when there is no error. */\nfunction FormMessage({ className, children, ...props }: React.ComponentProps<'p'>) {\n const { error, formMessageId } = useFormField();\n\n return (\n <span data-slot=\"form-message\" id={formMessageId} className={cn('text-danger text-xs', className)} {...props}>\n {error ? String(error?.message ?? '') : children}\n </span>\n );\n}\n\n// eslint-disable-next-line react-refresh/only-export-components\nexport { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, useFormField };\n"],"mappings":"0aAoCA,MAAM,EAAO,EAMP,EAAmB,EAAqC,EAAE,CAA0B,CAKpF,GAA8H,CAClI,GAAG,KAGD,EAAC,EAAiB,SAAA,CAAS,MAAO,CAAE,KAAM,EAAM,KAAM,UACpD,EAAC,EAAA,CAAW,GAAI,EAAA,CAAS,EACC,CAQ1B,MAAqB,CACzB,IAAM,EAAe,EAAI,EAAiB,CACpC,EAAc,EAAI,EAAgB,CAClC,CAAE,gBAAe,UAAS,cAAe,GAAgB,CACzD,EAAY,EAAa,CAAE,KAAM,EAAa,KAAM,CAAC,CACrD,EAAa,EAAc,EAAa,KAAM,EAAU,CAE9D,GAAI,CAAC,EACH,MAAU,MAAM,iDAAiD,CAGnE,GAAM,CAAE,MAAO,EAEf,MAAO,CACL,KACA,UACA,aACA,KAAM,EAAa,KACnB,WAAY,GAAG,EAAG,YAClB,kBAAmB,GAAG,EAAG,wBACzB,cAAe,GAAG,EAAG,oBACrB,GAAG,EACJ,EAOG,EAAkB,EAAoC,EAAE,CAAyB,CAOjF,EAAW,GACd,CACC,YACA,cAAc,aACd,GAAG,KAGC,CACJ,IAAM,EAAK,GAAO,CAElB,OACE,EAAC,EAAgB,SAAA,CAAS,MAAO,CAAE,KAAI,UACrC,EAAC,EAAA,CAAmB,cAAa,GAAI,EAAkB,aAAa,EAC3C,EAGhC,CACD,EAAS,YAAc,WAGvB,MAAM,EAAY,GAAM,CAAE,GAAG,KAA8D,CACzF,GAAM,CAAE,cAAe,GAAc,CACrC,OAAO,EAAC,EAAA,CAAW,QAAS,EAAY,GAAI,GAAS,EACrD,CACF,EAAU,YAAc,YAGxB,MAAM,EAAc,GAAM,CAAE,GAAG,KAA6D,CAC1F,GAAM,CAAE,QAAO,aAAY,oBAAmB,iBAAkB,GAAc,CAE9E,OACE,EAACA,EAAc,KAAA,CACb,YAAU,eACV,GAAI,EACJ,mBAAmB,EAAiC,GAAG,EAAkB,GAAG,IAAjD,GAAG,IAC9B,eAAc,CAAC,CAAC,EAChB,GAAI,GACJ,EAEJ,CACF,EAAY,YAAc,cAG1B,SAAS,EAAgB,CAAE,YAAW,GAAG,GAAoC,CAC3E,GAAM,CAAE,qBAAsB,GAAc,CAE5C,OACE,EAAC,EAAA,CACC,GAAI,EACJ,UAAW,EACT,+DACA,6DACA,+DACA,oEACA,EACD,CACD,GAAI,GACJ,CAKN,SAAS,EAAY,CAAE,YAAW,WAAU,GAAG,GAAoC,CACjF,GAAM,CAAE,QAAO,iBAAkB,GAAc,CAE/C,OACE,EAAC,OAAA,CAAK,YAAU,eAAe,GAAI,EAAe,UAAW,EAAG,sBAAuB,EAAU,CAAE,GAAI,WACpG,EAAQ,OAAO,GAAO,SAAW,GAAG,CAAG,GACnC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"hover-card.mjs","names":["HoverCardPrimitive"],"sources":["../../packages/components/ui/hover-card.tsx"],"sourcesContent":["'use client';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { HoverCard as HoverCardPrimitive } from 'radix-ui';\n\n/**\n * Root provider for the HoverCard — shows a floating card when the trigger is hovered.\n *\n * @example\n * ```tsx\n * import { HoverCard, HoverCardTrigger, HoverCardContent } from '@customafk/lunas-ui/ui/hover-card';\n *\n * <HoverCard>\n * <HoverCardTrigger>@username</HoverCardTrigger>\n * <HoverCardContent>\n * <p>Profile details here</p>\n * </HoverCardContent>\n * </HoverCard>\n * ```\n */\nfunction HoverCard({ ...props }: React.ComponentProps<typeof HoverCardPrimitive.Root>) {\n return <HoverCardPrimitive.Root data-slot=\"hover-card\" {...props} />;\n}\n\n/** The element that triggers the HoverCard on pointer enter. */\nfunction HoverCardTrigger({ ...props }: React.ComponentProps<typeof HoverCardPrimitive.Trigger>) {\n return <HoverCardPrimitive.Trigger data-slot=\"hover-card-trigger\" {...props} />;\n}\n\n/** The floating card panel displayed when the trigger is hovered. */\nfunction HoverCardContent({ className, align = 'center', sideOffset = 4, ...props }: React.ComponentProps<typeof HoverCardPrimitive.Content>) {\n return (\n <HoverCardPrimitive.Portal data-slot=\"hover-card-portal\">\n <HoverCardPrimitive.Content\n data-slot=\"hover-card-content\"\n align={align}\n sideOffset={sideOffset}\n className={cn(\n 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden',\n className\n )}\n {...props}\n />\n </HoverCardPrimitive.Portal>\n );\n}\n\nexport { HoverCard, HoverCardContent, HoverCardTrigger };\n"],"mappings":"8IAoBA,SAAS,EAAU,CAAE,GAAG,GAA+D,CACrF,OAAO,EAACA,EAAmB,KAAA,CAAK,YAAU,aAAa,GAAI,GAAS,CAItE,SAAS,EAAiB,CAAE,GAAG,GAAkE,CAC/F,OAAO,EAACA,EAAmB,QAAA,CAAQ,YAAU,qBAAqB,GAAI,GAAS,CAIjF,SAAS,EAAiB,CAAE,YAAW,QAAQ,SAAU,aAAa,EAAG,GAAG,GAAkE,CAC5I,OACE,EAACA,EAAmB,OAAA,CAAO,YAAU,6BACnC,EAACA,EAAmB,QAAA,CAClB,YAAU,qBACH,QACK,aACZ,UAAW,EACT,oeACA,EACD,CACD,GAAI,GACJ,EACwB"}
package/dist/ui/image.mjs DELETED
@@ -1 +0,0 @@
1
- import"../skeleton-C51IdOfK.mjs";import{t as e}from"../image-D7OZ13Ib.mjs";export{e as Image};
@@ -1 +0,0 @@
1
- {"version":3,"file":"input-otp.mjs","names":[],"sources":["../../packages/components/ui/input-otp.tsx"],"sourcesContent":["'use client';\nimport { use } from 'react';\n\nimport { MinusIcon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { OTPInput, OTPInputContext } from 'input-otp';\n\n/**\n * One-time password (OTP) input composed of individual character slots.\n *\n * @example\n * ```tsx\n * import { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator } from '@customafk/lunas-ui/ui/input-otp';\n *\n * <InputOTP maxLength={6}>\n * <InputOTPGroup>\n * <InputOTPSlot index={0} />\n * <InputOTPSlot index={1} />\n * <InputOTPSlot index={2} />\n * </InputOTPGroup>\n * <InputOTPSeparator />\n * <InputOTPGroup>\n * <InputOTPSlot index={3} />\n * <InputOTPSlot index={4} />\n * <InputOTPSlot index={5} />\n * </InputOTPGroup>\n * </InputOTP>\n * ```\n */\nfunction InputOTP({\n className,\n containerClassName,\n ...props\n}: React.ComponentProps<typeof OTPInput> & {\n /** Class name applied to the outer container div. */\n containerClassName?: string;\n}) {\n return (\n <OTPInput\n data-slot=\"input-otp\"\n containerClassName={cn('flex items-center gap-2 has-disabled:opacity-50', containerClassName)}\n className={cn('disabled:cursor-not-allowed', className)}\n {...props}\n />\n );\n}\n\n/** Flex container that groups a sequence of InputOTPSlot elements. */\nfunction InputOTPGroup({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"input-otp-group\" className={cn('flex items-center', className)} {...props} />;\n}\n\n/**\n * A single character slot in an InputOTP — displays the typed character and a blinking caret when focused.\n *\n * @param index - Zero-based position of this slot within the OTP sequence.\n */\nfunction InputOTPSlot({\n index,\n className,\n ...props\n}: React.ComponentProps<'div'> & {\n index: number;\n}) {\n const inputOTPContext = use(OTPInputContext);\n const { char, hasFakeCaret, isActive } = inputOTPContext?.slots[index] ?? {};\n\n return (\n <div\n data-slot=\"input-otp-slot\"\n data-active={isActive}\n className={cn(\n 'data-[active=true]:border-ring data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:ring-destructive/20 dark:data-[active=true]:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive dark:bg-input/30 border-input relative flex h-9 w-9 items-center justify-center border-y border-r text-sm shadow-xs transition-all outline-none first:rounded-l-md first:border-l last:rounded-r-md data-[active=true]:z-10 data-[active=true]:ring-[3px]',\n className\n )}\n {...props}\n >\n {char}\n {hasFakeCaret && (\n <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center\">\n <div className=\"animate-caret-blink bg-foreground h-4 w-px duration-1000\" />\n </div>\n )}\n </div>\n );\n}\n\n/** Visual separator (dash) placed between InputOTPGroup elements. */\nfunction InputOTPSeparator({ ...props }: React.ComponentProps<'div'>) {\n return (\n <div data-slot=\"input-otp-separator\" role=\"separator\" {...props}>\n <MinusIcon />\n </div>\n );\n}\n\nexport { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot };\n"],"mappings":"kPA+BA,SAAS,EAAS,CAChB,YACA,qBACA,GAAG,GAIF,CACD,OACE,EAAC,EAAA,CACC,YAAU,YACV,mBAAoB,EAAG,kDAAmD,EAAmB,CAC7F,UAAW,EAAG,8BAA+B,EAAU,CACvD,GAAI,GACJ,CAKN,SAAS,EAAc,CAAE,YAAW,GAAG,GAAsC,CAC3E,OAAO,EAAC,MAAA,CAAI,YAAU,kBAAkB,UAAW,EAAG,oBAAqB,EAAU,CAAE,GAAI,GAAS,CAQtG,SAAS,EAAa,CACpB,QACA,YACA,GAAG,GAGF,CAED,GAAM,CAAE,OAAM,eAAc,YADJ,EAAI,EAAgB,EACc,MAAM,IAAU,EAAE,CAE5E,OACE,EAAC,MAAA,CACC,YAAU,iBACV,cAAa,EACb,UAAW,EACT,2fACA,EACD,CACD,GAAI,YAEH,EACA,GACC,EAAC,MAAA,CAAI,UAAU,iFACb,EAAC,MAAA,CAAI,UAAU,2DAAA,CAA6D,EACxE,CAAA,EAEJ,CAKV,SAAS,EAAkB,CAAE,GAAG,GAAsC,CACpE,OACE,EAAC,MAAA,CAAI,YAAU,sBAAsB,KAAK,YAAY,GAAI,WACxD,EAAC,EAAA,EAAA,CAAY,EACT"}
@@ -1,2 +0,0 @@
1
- import { n as InputVariantProps, r as inputVariants, t as Input } from "../input-BtuZm0BQ.mjs";
2
- export { Input, InputVariantProps, inputVariants };
package/dist/ui/input.mjs DELETED
@@ -1 +0,0 @@
1
- "use client";import{n as e,t}from"../input-NJP2wQOm.mjs";export{t as Input,e as inputVariants};
@@ -1,2 +0,0 @@
1
- import{t as e}from"../../input-NJP2wQOm.mjs";import{ArrowRightIcon as t,SearchIcon as n}from"lucide-react";import{cn as r}from"@customafk/react-toolkit/utils";import{jsx as i,jsxs as a}from"react/jsx-runtime";const o=({className:o,...s})=>a(`div`,{className:`relative`,children:[i(e,{...s,type:`search`,className:r(`ps-9 pe-9`,o)}),i(`div`,{className:`pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 text-text-positive-weak peer-disabled:opacity-50`,children:i(n,{size:16})}),i(`button`,{className:`absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md text-text-positive-weak outline-none transition-[color,box-shadow] hover:text-text-positive focus:z-10 focus-visible:border focus-visible:border-primary-strong focus-visible:ring-[3px] focus-visible:ring-primary-weak disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50`,"aria-label":`Submit search`,type:`submit`,children:i(t,{size:16,"aria-hidden":`true`})})]});export{o as SearchInput};
2
- //# sourceMappingURL=search-input.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"search-input.mjs","names":[],"sources":["../../../packages/components/ui/inputs/search-input.tsx"],"sourcesContent":["import { ArrowRightIcon, SearchIcon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Input } from '../input';\n\n/**\n * Props for {@link SearchInput}. Accepts all native props of the underlying\n * `Input` component (itself a thin wrapper around `<input>`), including\n * `value`, `defaultValue`, `onChange`, `placeholder`, `disabled`, etc.\n * The `type` prop is fixed to `\"search\"` and cannot be overridden.\n */\ntype Props = React.ComponentPropsWithoutRef<typeof Input>;\n\n/**\n * A search input field with a leading search icon and a trailing arrow submit button, intended for use inside an HTML `<form>` element.\n *\n * @example\n * import { SearchInput } from '@customafk/lunas-ui/ui/inputs/search-input';\n *\n * <form onSubmit={handleSearch}>\n * <SearchInput placeholder=\"Search…\" value={query} onChange={(e) => setQuery(e.target.value)} />\n * </form>\n */\nexport const SearchInput = ({ className, ...rest }: Props) => {\n return (\n <div className=\"relative\">\n <Input {...rest} type=\"search\" className={cn('ps-9 pe-9', className)} />\n <div className=\"pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 text-text-positive-weak peer-disabled:opacity-50\">\n <SearchIcon size={16} />\n </div>\n <button\n className=\"absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md text-text-positive-weak outline-none transition-[color,box-shadow] hover:text-text-positive focus:z-10 focus-visible:border focus-visible:border-primary-strong focus-visible:ring-[3px] focus-visible:ring-primary-weak disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"\n aria-label=\"Submit search\"\n type=\"submit\"\n >\n <ArrowRightIcon size={16} aria-hidden=\"true\" />\n </button>\n </div>\n );\n};\n"],"mappings":"iNAwBA,MAAa,GAAe,CAAE,YAAW,GAAG,KAExC,EAAC,MAAA,CAAI,UAAU,qBACb,EAAC,EAAA,CAAM,GAAI,EAAM,KAAK,SAAS,UAAW,EAAG,YAAa,EAAU,EAAI,CACxE,EAAC,MAAA,CAAI,UAAU,iJACb,EAAC,EAAA,CAAW,KAAM,GAAA,CAAM,EACpB,CACN,EAAC,SAAA,CACC,UAAU,0XACV,aAAW,gBACX,KAAK,kBAEL,EAAC,EAAA,CAAe,KAAM,GAAI,cAAY,QAAS,EACxC,GACL"}
package/dist/ui/item.mjs DELETED
@@ -1,2 +0,0 @@
1
- import{t as e}from"../dist-DVrfqn8H.mjs";import{t}from"../separator-D3Gmkxzq.mjs";import{cn as n}from"@customafk/react-toolkit/utils";import{cva as r}from"class-variance-authority";import{jsx as i}from"react/jsx-runtime";function a({className:e,...t}){return i(`div`,{role:`list`,"data-slot":`item-group`,className:n(`group/item-group flex flex-col`,e),...t})}function o({className:e,...r}){return i(t,{"data-slot":`item-separator`,orientation:`horizontal`,className:n(`my-0`,e),...r})}const s=r(`group/item flex items-center border border-transparent text-sm rounded-md transition-colors [a]:hover:bg-accent/50 [a]:transition-colors duration-100 flex-wrap outline-none focus-visible:border-primary-strong focus-visible:ring-primary-weak focus-visible:ring-[3px]`,{variants:{variant:{default:`bg-transparent`,outline:`border-border`,muted:`bg-muted-weak`},size:{default:`p-4 gap-4 `,sm:`py-3 px-4 gap-2.5`}},defaultVariants:{variant:`default`,size:`default`}});function c({className:t,variant:r=`default`,size:a=`default`,asChild:o=!1,...c}){return i(o?e:`div`,{"data-slot":`item`,"data-variant":r,"data-size":a,className:n(s({variant:r,size:a,className:t})),...c})}const l=r(`flex shrink-0 items-center justify-center gap-2 group-has-[[data-slot=item-description]]/item:self-start [&_svg]:pointer-events-none group-has-[[data-slot=item-description]]/item:translate-y-0.5`,{variants:{variant:{default:`bg-transparent`,icon:`size-8 border rounded-sm bg-muted [&_svg:not([class*='size-'])]:size-4`,image:`size-10 rounded-sm overflow-hidden [&_img]:size-full [&_img]:object-cover`}},defaultVariants:{variant:`default`}});function u({className:e,variant:t=`default`,...r}){return i(`div`,{"data-slot":`item-media`,"data-variant":t,className:n(l({variant:t,className:e})),...r})}function d({className:e,...t}){return i(`div`,{"data-slot":`item-content`,className:n(`flex flex-1 flex-col gap-1 [&+[data-slot=item-content]]:flex-none`,e),...t})}function f({className:e,...t}){return i(`div`,{"data-slot":`item-title`,className:n(`flex w-fit items-center gap-2 text-sm leading-snug font-medium`,e),...t})}function p({className:e,...t}){return i(`p`,{"data-slot":`item-description`,className:n(`text-muted-foreground line-clamp-2 text-sm leading-normal font-normal text-balance`,`[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4`,e),...t})}function m({className:e,...t}){return i(`div`,{"data-slot":`item-actions`,className:n(`flex items-center gap-2`,e),...t})}function h({className:e,...t}){return i(`div`,{"data-slot":`item-header`,className:n(`flex basis-full items-center justify-between gap-2`,e),...t})}function g({className:e,...t}){return i(`div`,{"data-slot":`item-footer`,className:n(`flex basis-full items-center justify-between gap-2`,e),...t})}export{c as Item,m as ItemActions,d as ItemContent,p as ItemDescription,g as ItemFooter,a as ItemGroup,h as ItemHeader,u as ItemMedia,o as ItemSeparator,f as ItemTitle};
2
- //# sourceMappingURL=item.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"item.mjs","names":[],"sources":["../../packages/components/ui/item.tsx"],"sourcesContent":["import { cn } from '@customafk/react-toolkit/utils';\n\nimport { Slot } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { Separator } from '@/components/ui/separator';\n\n/**\n * A list-row layout primitive for rendering structured content rows with optional media, title, description, and action areas.\n *\n * @example\n * ```tsx\n * import { Item, ItemMedia, ItemContent, ItemTitle, ItemDescription, ItemActions, ItemGroup } from '@customafk/lunas-ui/ui/item';\n * import { User } from 'lucide-react';\n *\n * <ItemGroup>\n * <Item variant=\"outline\">\n * <ItemMedia variant=\"icon\"><User /></ItemMedia>\n * <ItemContent>\n * <ItemTitle>Alice</ItemTitle>\n * <ItemDescription>alice@example.com</ItemDescription>\n * </ItemContent>\n * <ItemActions><button>Edit</button></ItemActions>\n * </Item>\n * </ItemGroup>\n * ```\n */\nfunction ItemGroup({ className, ...props }: React.ComponentProps<'div'>) {\n return <div role=\"list\" data-slot=\"item-group\" className={cn('group/item-group flex flex-col', className)} {...props} />;\n}\n\n/** Horizontal separator rendered between items in an ItemGroup. */\nfunction ItemSeparator({ className, ...props }: React.ComponentProps<typeof Separator>) {\n return <Separator data-slot=\"item-separator\" orientation=\"horizontal\" className={cn('my-0', className)} {...props} />;\n}\n\nconst itemVariants = cva(\n 'group/item flex items-center border border-transparent text-sm rounded-md transition-colors [a]:hover:bg-accent/50 [a]:transition-colors duration-100 flex-wrap outline-none focus-visible:border-primary-strong focus-visible:ring-primary-weak focus-visible:ring-[3px]',\n {\n variants: {\n variant: {\n default: 'bg-transparent',\n outline: 'border-border',\n muted: 'bg-muted-weak',\n },\n size: {\n default: 'p-4 gap-4 ',\n sm: 'py-3 px-4 gap-2.5',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n }\n);\n\n/**\n * The primary row container inside an ItemGroup.\n *\n * @param variant - Visual style: `'default'`, `'outline'`, or `'muted'`.\n * @param size - Spacing size: `'default'` or `'sm'`.\n * @param asChild - When true, renders as the child element via Radix Slot.\n */\nfunction Item({\n className,\n variant = 'default',\n size = 'default',\n asChild = false,\n ...props\n}: React.ComponentProps<'div'> & VariantProps<typeof itemVariants> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : 'div';\n return <Comp data-slot=\"item\" data-variant={variant} data-size={size} className={cn(itemVariants({ variant, size, className }))} {...props} />;\n}\n\nconst itemMediaVariants = cva(\n 'flex shrink-0 items-center justify-center gap-2 group-has-[[data-slot=item-description]]/item:self-start [&_svg]:pointer-events-none group-has-[[data-slot=item-description]]/item:translate-y-0.5',\n {\n variants: {\n variant: {\n default: 'bg-transparent',\n icon: \"size-8 border rounded-sm bg-muted [&_svg:not([class*='size-'])]:size-4\",\n image: 'size-10 rounded-sm overflow-hidden [&_img]:size-full [&_img]:object-cover',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n }\n);\n\n/**\n * Left-aligned slot for an avatar, icon, or image within an Item.\n *\n * @param variant - `'default'` for a transparent wrapper, `'icon'` for a small bordered square, or `'image'` for a rounded thumbnail.\n */\nfunction ItemMedia({ className, variant = 'default', ...props }: React.ComponentProps<'div'> & VariantProps<typeof itemMediaVariants>) {\n return <div data-slot=\"item-media\" data-variant={variant} className={cn(itemMediaVariants({ variant, className }))} {...props} />;\n}\n\n/** Flex-1 column that holds the ItemTitle and ItemDescription. */\nfunction ItemContent({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"item-content\" className={cn('flex flex-1 flex-col gap-1 [&+[data-slot=item-content]]:flex-none', className)} {...props} />;\n}\n\n/** Primary label text rendered in medium weight inside an ItemContent. */\nfunction ItemTitle({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"item-title\" className={cn('flex w-fit items-center gap-2 text-sm leading-snug font-medium', className)} {...props} />;\n}\n\n/** Secondary, muted body text clamped to two lines inside an ItemContent. */\nfunction ItemDescription({ className, ...props }: React.ComponentProps<'p'>) {\n return (\n <p\n data-slot=\"item-description\"\n className={cn(\n 'text-muted-foreground line-clamp-2 text-sm leading-normal font-normal text-balance',\n '[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4',\n className\n )}\n {...props}\n />\n );\n}\n\n/** Right-aligned slot for buttons or other interactive controls within an Item. */\nfunction ItemActions({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"item-actions\" className={cn('flex items-center gap-2', className)} {...props} />;\n}\n\n/** Full-width row at the top of an Item for header-level labels or metadata. */\nfunction ItemHeader({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"item-header\" className={cn('flex basis-full items-center justify-between gap-2', className)} {...props} />;\n}\n\n/** Full-width row at the bottom of an Item for footer-level content or secondary actions. */\nfunction ItemFooter({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"item-footer\" className={cn('flex basis-full items-center justify-between gap-2', className)} {...props} />;\n}\n\nexport { Item, ItemMedia, ItemContent, ItemActions, ItemGroup, ItemSeparator, ItemTitle, ItemDescription, ItemHeader, ItemFooter };\n"],"mappings":"6NA0BA,SAAS,EAAU,CAAE,YAAW,GAAG,GAAsC,CACvE,OAAO,EAAC,MAAA,CAAI,KAAK,OAAO,YAAU,aAAa,UAAW,EAAG,iCAAkC,EAAU,CAAE,GAAI,GAAS,CAI1H,SAAS,EAAc,CAAE,YAAW,GAAG,GAAiD,CACtF,OAAO,EAAC,EAAA,CAAU,YAAU,iBAAiB,YAAY,aAAa,UAAW,EAAG,OAAQ,EAAU,CAAE,GAAI,GAAS,CAGvH,MAAM,EAAe,EACnB,4QACA,CACE,SAAU,CACR,QAAS,CACP,QAAS,iBACT,QAAS,gBACT,MAAO,gBACR,CACD,KAAM,CACJ,QAAS,aACT,GAAI,oBACL,CACF,CACD,gBAAiB,CACf,QAAS,UACT,KAAM,UACP,CACF,CACF,CASD,SAAS,EAAK,CACZ,YACA,UAAU,UACV,OAAO,UACP,UAAU,GACV,GAAG,GACuF,CAE1F,OAAO,EADM,EAAU,EAAO,MAAA,CACjB,YAAU,OAAO,eAAc,EAAS,YAAW,EAAM,UAAW,EAAG,EAAa,CAAE,UAAS,OAAM,YAAW,CAAC,CAAC,CAAE,GAAI,GAAS,CAGhJ,MAAM,EAAoB,EACxB,qMACA,CACE,SAAU,CACR,QAAS,CACP,QAAS,iBACT,KAAM,yEACN,MAAO,4EACR,CACF,CACD,gBAAiB,CACf,QAAS,UACV,CACF,CACF,CAOD,SAAS,EAAU,CAAE,YAAW,UAAU,UAAW,GAAG,GAA+E,CACrI,OAAO,EAAC,MAAA,CAAI,YAAU,aAAa,eAAc,EAAS,UAAW,EAAG,EAAkB,CAAE,UAAS,YAAW,CAAC,CAAC,CAAE,GAAI,GAAS,CAInI,SAAS,EAAY,CAAE,YAAW,GAAG,GAAsC,CACzE,OAAO,EAAC,MAAA,CAAI,YAAU,eAAe,UAAW,EAAG,oEAAqE,EAAU,CAAE,GAAI,GAAS,CAInJ,SAAS,EAAU,CAAE,YAAW,GAAG,GAAsC,CACvE,OAAO,EAAC,MAAA,CAAI,YAAU,aAAa,UAAW,EAAG,iEAAkE,EAAU,CAAE,GAAI,GAAS,CAI9I,SAAS,EAAgB,CAAE,YAAW,GAAG,GAAoC,CAC3E,OACE,EAAC,IAAA,CACC,YAAU,mBACV,UAAW,EACT,qFACA,oEACA,EACD,CACD,GAAI,GACJ,CAKN,SAAS,EAAY,CAAE,YAAW,GAAG,GAAsC,CACzE,OAAO,EAAC,MAAA,CAAI,YAAU,eAAe,UAAW,EAAG,0BAA2B,EAAU,CAAE,GAAI,GAAS,CAIzG,SAAS,EAAW,CAAE,YAAW,GAAG,GAAsC,CACxE,OAAO,EAAC,MAAA,CAAI,YAAU,cAAc,UAAW,EAAG,qDAAsD,EAAU,CAAE,GAAI,GAAS,CAInI,SAAS,EAAW,CAAE,YAAW,GAAG,GAAsC,CACxE,OAAO,EAAC,MAAA,CAAI,YAAU,cAAc,UAAW,EAAG,qDAAsD,EAAU,CAAE,GAAI,GAAS"}
package/dist/ui/label.mjs DELETED
@@ -1 +0,0 @@
1
- "use client";import{t as e}from"../label-CUCpwS5D.mjs";export{e as Label};
@@ -1 +0,0 @@
1
- {"version":3,"file":"menubar.mjs","names":["MenubarPrimitive"],"sources":["../../packages/components/ui/menubar.tsx"],"sourcesContent":["'use client';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from 'lucide-react';\n\nimport { Menubar as MenubarPrimitive } from 'radix-ui';\n\n/**\n * A horizontal menu bar similar to a desktop application menu, composed of menus with dropdown content.\n *\n * @example\n * ```tsx\n * import {\n * Menubar, MenubarMenu, MenubarTrigger, MenubarContent,\n * MenubarItem, MenubarSeparator,\n * } from '@customafk/lunas-ui/ui/menubar';\n *\n * <Menubar>\n * <MenubarMenu>\n * <MenubarTrigger>File</MenubarTrigger>\n * <MenubarContent>\n * <MenubarItem>New Window</MenubarItem>\n * <MenubarSeparator />\n * <MenubarItem>Exit</MenubarItem>\n * </MenubarContent>\n * </MenubarMenu>\n * </Menubar>\n * ```\n */\nfunction Menubar({ className, ...props }: React.ComponentProps<typeof MenubarPrimitive.Root>) {\n return (\n <MenubarPrimitive.Root\n data-slot=\"menubar\"\n className={cn('bg-background flex h-9 items-center gap-1 rounded-md border p-1 shadow-xs', className)}\n {...props}\n />\n );\n}\n\n/** Root container for a single drop-down menu entry within a Menubar. */\nfunction MenubarMenu({ ...props }: React.ComponentProps<typeof MenubarPrimitive.Menu>) {\n return <MenubarPrimitive.Menu data-slot=\"menubar-menu\" {...props} />;\n}\n\n/** Groups related MenubarItems under a shared logical section. */\nfunction MenubarGroup({ ...props }: React.ComponentProps<typeof MenubarPrimitive.Group>) {\n return <MenubarPrimitive.Group data-slot=\"menubar-group\" {...props} />;\n}\n\n/** Portals Menubar content outside the current DOM hierarchy. */\nfunction MenubarPortal({ ...props }: React.ComponentProps<typeof MenubarPrimitive.Portal>) {\n return <MenubarPrimitive.Portal data-slot=\"menubar-portal\" {...props} />;\n}\n\n/** Groups MenubarRadioItems so only one can be selected at a time. */\nfunction MenubarRadioGroup({ ...props }: React.ComponentProps<typeof MenubarPrimitive.RadioGroup>) {\n return <MenubarPrimitive.RadioGroup data-slot=\"menubar-radio-group\" {...props} />;\n}\n\n/** Button in the Menubar that opens its associated MenubarContent dropdown. */\nfunction MenubarTrigger({ className, ...props }: React.ComponentProps<typeof MenubarPrimitive.Trigger>) {\n return (\n <MenubarPrimitive.Trigger\n data-slot=\"menubar-trigger\"\n className={cn(\n 'focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex items-center rounded-sm px-2 py-1 text-sm font-medium outline-hidden select-none',\n className\n )}\n {...props}\n />\n );\n}\n\n/** Animated floating panel that contains MenubarItems for a given MenubarMenu. */\nfunction MenubarContent({ className, align = 'start', alignOffset = -4, sideOffset = 8, ...props }: React.ComponentProps<typeof MenubarPrimitive.Content>) {\n return (\n <MenubarPortal>\n <MenubarPrimitive.Content\n data-slot=\"menubar-content\"\n align={align}\n alignOffset={alignOffset}\n sideOffset={sideOffset}\n className={cn(\n 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[12rem] origin-(--radix-menubar-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-md',\n className\n )}\n {...props}\n />\n </MenubarPortal>\n );\n}\n\n/**\n * A single clickable row inside a MenubarContent.\n *\n * @param inset - When true, adds left padding to align with items that have icons.\n * @param variant - Visual style: `'default'` or `'destructive'`.\n */\nfunction MenubarItem({\n className,\n inset,\n variant = 'default',\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Item> & {\n inset?: boolean;\n variant?: 'default' | 'destructive';\n}) {\n return (\n <MenubarPrimitive.Item\n data-slot=\"menubar-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n );\n}\n\n/** A checkable menubar item that displays a checkmark when selected. */\nfunction MenubarCheckboxItem({ className, children, checked, ...props }: React.ComponentProps<typeof MenubarPrimitive.CheckboxItem>) {\n return (\n <MenubarPrimitive.CheckboxItem\n data-slot=\"menubar-checkbox-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <MenubarPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </MenubarPrimitive.ItemIndicator>\n </span>\n {children}\n </MenubarPrimitive.CheckboxItem>\n );\n}\n\n/** A radio-button menubar item; shows a filled circle when selected. */\nfunction MenubarRadioItem({ className, children, ...props }: React.ComponentProps<typeof MenubarPrimitive.RadioItem>) {\n return (\n <MenubarPrimitive.RadioItem\n data-slot=\"menubar-radio-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <MenubarPrimitive.ItemIndicator>\n <CircleIcon className=\"size-2 fill-current\" />\n </MenubarPrimitive.ItemIndicator>\n </span>\n {children}\n </MenubarPrimitive.RadioItem>\n );\n}\n\n/**\n * Non-interactive label used to describe a group of menubar items.\n *\n * @param inset - When true, adds left padding to align with inset items.\n */\nfunction MenubarLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Label> & {\n inset?: boolean;\n}) {\n return (\n <MenubarPrimitive.Label\n data-slot=\"menubar-label\"\n data-inset={inset}\n className={cn('px-2 py-1.5 text-sm font-medium data-[inset]:pl-8', className)}\n {...props}\n />\n );\n}\n\n/** Horizontal dividing line between groups of menubar items. */\nfunction MenubarSeparator({ className, ...props }: React.ComponentProps<typeof MenubarPrimitive.Separator>) {\n return <MenubarPrimitive.Separator data-slot=\"menubar-separator\" className={cn('bg-border -mx-1 my-1 h-px', className)} {...props} />;\n}\n\n/** Displays a keyboard shortcut hint aligned to the right of a menubar item. */\nfunction MenubarShortcut({ className, ...props }: React.ComponentProps<'span'>) {\n return <span data-slot=\"menubar-shortcut\" className={cn('text-muted-foreground ml-auto text-xs tracking-widest', className)} {...props} />;\n}\n\n/** Root container for a nested sub-menu inside a Menubar dropdown. */\nfunction MenubarSub({ ...props }: React.ComponentProps<typeof MenubarPrimitive.Sub>) {\n return <MenubarPrimitive.Sub data-slot=\"menubar-sub\" {...props} />;\n}\n\n/**\n * Menu item that reveals a nested MenubarSubContent on hover or activation.\n *\n * @param inset - When true, adds left padding to align with inset items.\n */\nfunction MenubarSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.SubTrigger> & {\n inset?: boolean;\n}) {\n return (\n <MenubarPrimitive.SubTrigger\n data-slot=\"menubar-sub-trigger\"\n data-inset={inset}\n className={cn(\n 'focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-none select-none data-[inset]:pl-8',\n className\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto h-4 w-4\" />\n </MenubarPrimitive.SubTrigger>\n );\n}\n\n/** Floating panel that contains the items of a nested Menubar sub-menu. */\nfunction MenubarSubContent({ className, ...props }: React.ComponentProps<typeof MenubarPrimitive.SubContent>) {\n return (\n <MenubarPrimitive.SubContent\n data-slot=\"menubar-sub-content\"\n className={cn(\n 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-menubar-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg',\n className\n )}\n {...props}\n />\n );\n}\n\nexport {\n Menubar,\n MenubarCheckboxItem,\n MenubarContent,\n MenubarGroup,\n MenubarItem,\n MenubarLabel,\n MenubarMenu,\n MenubarPortal,\n MenubarRadioGroup,\n MenubarRadioItem,\n MenubarSeparator,\n MenubarShortcut,\n MenubarSub,\n MenubarSubContent,\n MenubarSubTrigger,\n MenubarTrigger,\n};\n"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- "use client";import"../button.variants-DkMqWB8G.mjs";import{t as e}from"../button-CCVJTHBI.mjs";import"../heading-De4Pn3mZ.mjs";import"../paragraph-DYLaQtTV.mjs";import"../close-_UHFeiLS.mjs";import"../dialog-CLDnvNH_.mjs";import{c as t,i as n,o as r,s as ee,t as te}from"../command-D6_CSbwJ.mjs";import{PlusIcon as ne,X as i}from"lucide-react";import{forwardRef as a,useCallback as o,useEffect as s,useImperativeHandle as c,useMemo as re,useRef as l,useState as u}from"react";import{cn as d}from"@customafk/react-toolkit/utils";import{Fragment as f,jsx as p,jsxs as m}from"react/jsx-runtime";import{Command as h,useCommandState as g}from"cmdk";function _(e,t){let[n,r]=u(e);return s(()=>{let n=setTimeout(()=>r(e),t||500);return()=>{clearTimeout(n)}},[e,t]),n}function v(e,t){if(e.length===0)return{};if(!t)return{"":e};let n={};return e.forEach(e=>{let r=e[t]||``;n[r]||(n[r]=[]),n[r].push(e)}),n}function ie(e,t){let n=JSON.parse(JSON.stringify(e));for(let[e,r]of Object.entries(n))n[e]=r.filter(e=>!t.find(t=>t.value===e.value));return n}function ae(e,t){for(let[,n]of Object.entries(e))if(n.some(e=>t.find(t=>t.value===e.value)))return!0;return!1}const y=a(({className:e,...t},n)=>g(e=>e.filtered.count===0)?p(`div`,{ref:n,className:d(`px-2 py-4 text-center text-sm`,e),"cmdk-empty":``,role:`presentation`,...t}):null);y.displayName=`CommandEmpty`;const b=a(({value:a,onChange:g,placeholder:b,defaultOptions:x=[],options:S,delay:oe,onSearch:C,onSearchSync:w,loadingIndicator:se,emptyIndicator:T,maxSelected:E=2**53-1,onMaxSelected:D,hidePlaceholderWhenSelected:O,disabled:k,groupBy:A,className:ce,badgeClassName:le,selectFirstItem:ue=!0,creatable:j=!1,triggerSearchOnFocus:M=!1,commandProps:N,inputProps:P,hideClearAllButton:F=!1,onAddNewItem:I},de)=>{let L=l(null),R=l(null),[z,B]=u(!1),[V,H]=u(!1),[U,W]=u(!1),[G,K]=u(a||[]),[q,J]=u(v(x,A)),[Y,X]=u(``),Z=_(Y,oe||500);c(de,()=>({selectedValue:[...G],input:L.current,focus:()=>L?.current?.focus(),reset:()=>K([])}),[G]);let Q=o(e=>{R.current&&!R.current.contains(e.target)&&L.current&&!L.current.contains(e.target)&&(B(!1),L.current.blur())},[]),$=o(e=>{let t=G.filter(t=>t.value!==e.value);K(t),g?.(t)},[g,G]),fe=o(e=>{let t=L.current;t&&((e.key===`Delete`||e.key===`Backspace`)&&t.value===``&&G.length>0&&(G[G.length-1].fixed||$(G[G.length-1])),e.key===`Escape`&&t.blur())},[$,G]);s(()=>(z?(document.addEventListener(`mousedown`,Q),document.addEventListener(`touchend`,Q)):(document.removeEventListener(`mousedown`,Q),document.removeEventListener(`touchend`,Q)),()=>{document.removeEventListener(`mousedown`,Q),document.removeEventListener(`touchend`,Q)}),[z]),s(()=>{a&&K(a)},[a]),s(()=>{if(!S||C)return;let e=v(S||[],A);JSON.stringify(e)!==JSON.stringify(q)&&J(e)},[x,S,A,C,q]),s(()=>{let e=()=>{let e=w?.(Z);J(v(e||[],A))};(async()=>{!w||!z||(M&&e(),Z&&e())})()},[Z,A,z,M]),s(()=>{let e=async()=>{W(!0),J(v(await C?.(Z)||[],A)),W(!1)};(async()=>{!C||!z||(M&&await e(),Z&&await e())})()},[Z,A,z,M]);let pe=()=>{if(!j||ae(q,[{value:Y,label:Y}])||G.find(e=>e.value===Y))return;let e=p(r,{value:Y,className:`cursor-pointer`,onMouseDown:e=>{e.preventDefault(),e.stopPropagation()},onSelect:e=>{if(G.length>=E){D?.(G.length);return}X(``);let t=[...G,{value:e,label:e}];K(t),g?.(t)},children:`Create "${Y}"`});if(!C&&Y.length>0||C&&Z.length>0&&!U)return e},me=o(()=>{if(T)return C&&!j&&Object.keys(q).length===0?p(r,{value:`-`,disabled:!0,children:T}):p(y,{children:T})},[j,T,C,q]),he=re(()=>ie(q,G),[q,G]),ge=o(()=>{if(N?.filter)return N.filter;if(j)return(e,t)=>e.toLowerCase().includes(t.toLowerCase())?1:-1},[j,N?.filter]);return m(te,{ref:R,...N,onKeyDown:e=>{fe(e),N?.onKeyDown?.(e)},className:d(`h-auto overflow-visible bg-transparent`,N?.className),shouldFilter:N?.shouldFilter===void 0?!C:N.shouldFilter,filter:ge(),children:[p(`div`,{className:d(`border-border-weak relative rounded-md border text-sm transition-shadow`,`focus-within:border-primary`,`focus-within:ring-primary-weak`,`focus-within:ring-4`,`focus-within:outline-hidden`,`has-disabled:bg-muted`,`has-disabled:text-muted-foreground`,G.length!==0&&`p-1`,!k&&G.length!==0&&`cursor-text`,!F&&`pe-9`,ce),onClick:()=>{k||L?.current?.focus()},children:m(`div`,{className:`flex flex-wrap gap-1`,children:[G.map(e=>m(`div`,{className:d(`animate-fadeIn`,`bg-background`,`hover:bg-background`,`border-border-weak border border-solid`,`text-text-positive-weak relative inline-flex h-7 cursor-default items-center rounded-md ps-2 pe-7 pl-2 text-xs font-medium transition-all`,`disabled:cursor-not-allowed`,`disabled:opacity-50`,`data-fixed:pe-2`,le),"data-fixed":e.fixed,"data-disabled":k||void 0,children:[e.label,p(`button`,{type:`button`,disabled:k||e.fixed,className:d(`text-text-positive-muted absolute -inset-y-px -end-px flex size-7 items-center justify-center rounded-e-lg border border-transparent p-0 outline-0 transition-colors`,`hover:text-foreground`,`focus-visible:outline`,`focus-visible:outline-2`,`focus-visible:outline-primary-weak`,`disabled:hover:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50`),onKeyDown:t=>{t.key===`Enter`&&$(e)},onMouseDown:e=>{e.preventDefault(),e.stopPropagation()},onClick:()=>$(e),"aria-label":`Remove`,children:p(i,{size:14,strokeWidth:2,"aria-hidden":`true`})})]},e.value)),p(h.Input,{...P,ref:L,value:Y,disabled:k,onValueChange:e=>{X(e),P?.onValueChange?.(e)},onBlur:e=>{V||B(!1),P?.onBlur?.(e)},onFocus:e=>{B(!0),M&&C?.(Z),P?.onFocus?.(e)},placeholder:O&&G.length!==0?``:b,className:d(`placeholder:text-text-positive-muted flex-1 bg-transparent outline-hidden`,`disabled:placeholder:text-transparent`,{"w-full":O,"px-3 py-2":G.length===0,"ml-1":G.length!==0},P?.className)}),p(`button`,{type:`button`,onClick:()=>{K(G.filter(e=>e.fixed)),g?.(G.filter(e=>e.fixed))},className:d(`text-muted-foreground/80`,`absolute end-0 top-0 flex size-9 items-center justify-center rounded-lg border border-transparent transition-colors`,`focus-visible:outline-2`,`hover:text-text-positive`,`focus-visible:outline-primary-weak`,(F||k||G.length<1||G.filter(({fixed:e})=>e).length===G.length)&&`hidden`),"aria-label":`Clear all`,children:p(i,{size:16,strokeWidth:2,"aria-hidden":`true`})})]})}),p(`div`,{className:`relative`,children:p(`div`,{className:d(`shadow-dropdown absolute top-2 z-10 w-full overflow-hidden rounded-lg`,`data-[state=open]:animate-in`,`data-[state=closed]:animate-out`,`data-[state=closed]:fade-out-0`,`data-[state=open]:fade-in-0`,`data-[state=closed]:zoom-out-95`,`data-[state=open]:zoom-in-95`,!z&&`hidden`),"data-state":z?`open`:`closed`,children:z&&m(ee,{className:`shadow-lg outline-hidden`,onMouseLeave:()=>{H(!1)},onMouseEnter:()=>{H(!0)},onMouseUp:()=>{L?.current?.focus()},children:[I&&m(f,{children:[p(t,{}),p(n,{children:m(e,{type:`button`,variant:`ghost`,className:`w-full font-normal [&_div]:justify-start`,onClick:I,children:[p(ne,{size:14,className:`opacity-60`,"aria-hidden":`true`}),`Thêm mới`]})})]}),U?se:m(f,{children:[me(),pe(),!ue&&p(r,{value:`-`,className:`hidden`}),Object.entries(he).map(([e,t])=>p(n,{heading:e,className:`h-full overflow-auto`,children:t.map(e=>p(r,{value:e.value,disabled:e.disable,onMouseDown:e=>{e.preventDefault(),e.stopPropagation()},onSelect:()=>{if(G.length>=E){D?.(G.length);return}let t=[...G,e];X(``),K(t),g?.(t)},className:d(`cursor-pointer`,e.disable&&`cursor-not-allowed opacity-50`),children:e.label},e.value))},e))]})]})})})]})});b.displayName=`MultipleSelector`;export{b as MultipleSelector,_ as useDebounce};
2
- //# sourceMappingURL=multi-select.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"multi-select.mjs","names":["groupOption: GroupOption","value","Command","CommandPrimitive"],"sources":["../../packages/components/ui/multi-select.tsx"],"sourcesContent":["'use client';\nimport { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { PlusIcon, X } from 'lucide-react';\n\nimport { Button } from '@/components/ui/button';\nimport { Command, CommandGroup, CommandItem, CommandList, CommandSeparator } from '@/components/ui/command';\n\nimport { Command as CommandPrimitive, useCommandState } from 'cmdk';\n\n/** Represents a single selectable option in the MultipleSelector. */\nexport interface Option {\n /** Unique value used for selection and comparison. */\n value: string;\n /** Human-readable label displayed in the dropdown and as a badge. */\n label: string;\n /** When true, the option is disabled and cannot be selected. */\n disable?: boolean;\n /** fixed option that can&lsquo;t be removed. */\n fixed?: boolean;\n /** Group the options by providing key. */\n [key: string]: string | boolean | undefined;\n}\ninterface GroupOption {\n [key: string]: Option[];\n}\n\n/** Props for the MultipleSelector component. */\ninterface MultipleSelectorProps {\n /** Controlled list of currently selected options. */\n value?: Option[];\n /** Initial options pre-loaded into the dropdown (uncontrolled). */\n defaultOptions?: Option[];\n /** manually controlled options */\n options?: Option[];\n placeholder?: string;\n /** Loading component. */\n loadingIndicator?: React.ReactNode;\n /** Empty component. */\n emptyIndicator?: React.ReactNode;\n /** Debounce time for async search. Only work with `onSearch`. */\n delay?: number;\n /**\n * Only work with `onSearch` prop. Trigger search when `onFocus`.\n * For example, when user click on the input, it will trigger the search to get initial options.\n **/\n triggerSearchOnFocus?: boolean;\n /** async search */\n onSearch?: (value: string) => Promise<Option[]>;\n /**\n * sync search. This search will not showing loadingIndicator.\n * The rest props are the same as async search.\n * i.e.: creatable, groupBy, delay.\n **/\n onSearchSync?: (value: string) => Option[];\n onChange?: (options: Option[]) => void;\n /** Limit the maximum number of selected options. */\n maxSelected?: number;\n /** When the number of selected options exceeds the limit, the onMaxSelected will be called. */\n onMaxSelected?: (maxLimit: number) => void;\n /** Hide the placeholder when there are options selected. */\n hidePlaceholderWhenSelected?: boolean;\n disabled?: boolean;\n /** Group the options base on provided key. */\n groupBy?: string;\n className?: string;\n badgeClassName?: string;\n /**\n * First item selected is a default behavior by cmdk. That is why the default is true.\n * This is a workaround solution by add a dummy item.\n *\n * @reference: https://github.com/pacocoursey/cmdk/issues/171\n */\n selectFirstItem?: boolean;\n /** Allow user to create option when there is no option matched. */\n creatable?: boolean;\n /** Props of `Command` */\n commandProps?: React.ComponentPropsWithoutRef<typeof Command>;\n /** Props of `CommandInput` */\n inputProps?: Omit<React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>, 'value' | 'placeholder' | 'disabled'>;\n /** hide the clear all button. */\n hideClearAllButton?: boolean;\n\n /** Add new item event for select with search */\n onAddNewItem?: () => void;\n}\n\n/** Imperative handle exposed by MultipleSelector via `ref`. */\nexport interface MultipleSelectorRef {\n /** The currently selected options. */\n selectedValue: Option[];\n /** The underlying `<input>` DOM element. */\n input: HTMLInputElement;\n /** Programmatically focus the search input. */\n focus: () => void;\n /** Clear all selected options. */\n reset: () => void;\n}\n\n/**\n * Returns a debounced copy of `value` that only updates after `delay` ms of inactivity.\n *\n * @param value - The value to debounce.\n * @param delay - Debounce delay in milliseconds (default 500).\n */\n// eslint-disable-next-line react-refresh/only-export-components\nexport function useDebounce<T>(value: T, delay?: number): T {\n const [debouncedValue, setDebouncedValue] = useState<T>(value);\n\n useEffect(() => {\n const timer = setTimeout(() => setDebouncedValue(value), delay || 500);\n\n return () => {\n clearTimeout(timer);\n };\n }, [value, delay]);\n\n return debouncedValue;\n}\n\nfunction transToGroupOption(options: Option[], groupBy?: string) {\n if (options.length === 0) {\n return {};\n }\n if (!groupBy) {\n return {\n '': options,\n };\n }\n\n const groupOption: GroupOption = {};\n options.forEach(option => {\n const key = (option[groupBy] as string) || '';\n if (!groupOption[key]) {\n groupOption[key] = [];\n }\n groupOption[key].push(option);\n });\n return groupOption;\n}\n\nfunction removePickedOption(groupOption: GroupOption, picked: Option[]) {\n const cloneOption = JSON.parse(JSON.stringify(groupOption)) as GroupOption;\n\n for (const [key, value] of Object.entries(cloneOption)) {\n cloneOption[key] = value.filter(val => !picked.find(p => p.value === val.value));\n }\n return cloneOption;\n}\n\nfunction isOptionsExist(groupOption: GroupOption, targetOption: Option[]) {\n for (const [, value] of Object.entries(groupOption)) {\n if (value.some(option => targetOption.find(p => p.value === option.value))) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * The `CommandEmpty` of shadcn/ui will cause the cmdk empty not rendering correctly.\n * So we create one and copy the `Empty` implementation from `cmdk`.\n *\n * @reference: https://github.com/hsuanyi-chou/shadcn-ui-expansions/issues/34#issuecomment-1949561607\n **/\nconst CommandEmpty = forwardRef<HTMLDivElement, React.ComponentProps<typeof CommandPrimitive.Empty>>(({ className, ...props }, forwardedRef) => {\n const render = useCommandState(state => state.filtered.count === 0);\n\n if (!render) return null;\n\n return <div ref={forwardedRef} className={cn('px-2 py-4 text-center text-sm', className)} cmdk-empty=\"\" role=\"presentation\" {...props} />;\n});\n\nCommandEmpty.displayName = 'CommandEmpty';\n\n/**\n * A combobox-style input that allows selecting multiple options displayed as removable badge chips, with optional async search and creatable mode.\n *\n * @example\n * ```tsx\n * import { MultipleSelector } from '@customafk/lunas-ui/ui/multi-select';\n *\n * const options = [\n * { value: 'react', label: 'React' },\n * { value: 'vue', label: 'Vue' },\n * ];\n *\n * <MultipleSelector\n * options={options}\n * placeholder=\"Select frameworks…\"\n * onChange={(selected) => console.log(selected)}\n * />\n * ```\n */\nexport const MultipleSelector = forwardRef<MultipleSelectorRef, MultipleSelectorProps>(\n (\n {\n value,\n onChange,\n placeholder,\n defaultOptions: arrayDefaultOptions = [],\n options: arrayOptions,\n delay,\n onSearch,\n onSearchSync,\n loadingIndicator: LoadingIndicator,\n emptyIndicator,\n maxSelected = Number.MAX_SAFE_INTEGER,\n onMaxSelected,\n hidePlaceholderWhenSelected,\n disabled,\n groupBy,\n className,\n badgeClassName,\n selectFirstItem = true,\n creatable = false,\n triggerSearchOnFocus = false,\n commandProps,\n inputProps,\n hideClearAllButton = false,\n onAddNewItem,\n }: MultipleSelectorProps,\n ref: React.Ref<MultipleSelectorRef>\n ) => {\n const inputRef = useRef<HTMLInputElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null); // Added this\n\n const [open, setOpen] = useState(false);\n const [onScrollbar, setOnScrollbar] = useState(false);\n const [isLoading, setIsLoading] = useState(false);\n\n const [selected, setSelected] = useState<Option[]>(value || []);\n const [options, setOptions] = useState<GroupOption>(transToGroupOption(arrayDefaultOptions, groupBy));\n const [inputValue, setInputValue] = useState('');\n\n const debouncedSearchTerm = useDebounce(inputValue, delay || 500);\n\n useImperativeHandle(\n ref,\n () => ({\n selectedValue: [...selected],\n input: inputRef.current as HTMLInputElement,\n focus: () => inputRef?.current?.focus(),\n reset: () => setSelected([]),\n }),\n [selected]\n );\n\n const handleClickOutside = useCallback((event: MouseEvent | TouchEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node) && inputRef.current && !inputRef.current.contains(event.target as Node)) {\n setOpen(false);\n inputRef.current.blur();\n }\n }, []);\n\n const handleUnselect = useCallback(\n (option: Option) => {\n const newOptions = selected.filter(s => s.value !== option.value);\n setSelected(newOptions);\n onChange?.(newOptions);\n },\n [onChange, selected]\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLDivElement>) => {\n const input = inputRef.current;\n if (!input) return;\n\n if (e.key === 'Delete' || e.key === 'Backspace') {\n if (input.value === '' && selected.length > 0) {\n const lastSelectOption = selected[selected.length - 1];\n // If last item is fixed, we should not remove it.\n if (!lastSelectOption.fixed) {\n handleUnselect(selected[selected.length - 1]);\n }\n }\n }\n\n // This is not a default behavior of the <input /> field\n if (e.key === 'Escape') {\n input.blur();\n }\n },\n [handleUnselect, selected]\n );\n\n useEffect(() => {\n if (open) {\n document.addEventListener('mousedown', handleClickOutside);\n document.addEventListener('touchend', handleClickOutside);\n } else {\n document.removeEventListener('mousedown', handleClickOutside);\n document.removeEventListener('touchend', handleClickOutside);\n }\n\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n document.removeEventListener('touchend', handleClickOutside);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open]);\n\n useEffect(() => {\n if (value) {\n setSelected(value);\n }\n }, [value]);\n\n useEffect(() => {\n /** If `onSearch` is provided, do not trigger options updated. */\n if (!arrayOptions || onSearch) {\n return;\n }\n const newOption = transToGroupOption(arrayOptions || [], groupBy);\n if (JSON.stringify(newOption) !== JSON.stringify(options)) {\n setOptions(newOption);\n }\n }, [arrayDefaultOptions, arrayOptions, groupBy, onSearch, options]);\n\n useEffect(() => {\n /** sync search */\n\n const doSearchSync = () => {\n const res = onSearchSync?.(debouncedSearchTerm);\n setOptions(transToGroupOption(res || [], groupBy));\n };\n\n const exec = async () => {\n if (!onSearchSync || !open) return;\n\n if (triggerSearchOnFocus) {\n doSearchSync();\n }\n\n if (debouncedSearchTerm) {\n doSearchSync();\n }\n };\n\n void exec();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [debouncedSearchTerm, groupBy, open, triggerSearchOnFocus]);\n\n useEffect(() => {\n /** async search */\n\n const doSearch = async () => {\n setIsLoading(true);\n const res = await onSearch?.(debouncedSearchTerm);\n setOptions(transToGroupOption(res || [], groupBy));\n setIsLoading(false);\n };\n\n const exec = async () => {\n if (!onSearch || !open) return;\n\n if (triggerSearchOnFocus) {\n await doSearch();\n }\n\n if (debouncedSearchTerm) {\n await doSearch();\n }\n };\n\n void exec();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [debouncedSearchTerm, groupBy, open, triggerSearchOnFocus]);\n\n const CreatableItem = () => {\n if (!creatable) return undefined;\n if (isOptionsExist(options, [{ value: inputValue, label: inputValue }]) || selected.find(s => s.value === inputValue)) {\n return undefined;\n }\n\n const Item = (\n <CommandItem\n value={inputValue}\n className=\"cursor-pointer\"\n onMouseDown={e => {\n e.preventDefault();\n e.stopPropagation();\n }}\n onSelect={(value: string) => {\n if (selected.length >= maxSelected) {\n onMaxSelected?.(selected.length);\n return;\n }\n setInputValue('');\n const newOptions = [...selected, { value, label: value }];\n setSelected(newOptions);\n onChange?.(newOptions);\n }}\n >\n {`Create \"${inputValue}\"`}\n </CommandItem>\n );\n\n // For normal creatable\n if (!onSearch && inputValue.length > 0) {\n return Item;\n }\n\n // For async search creatable. avoid showing creatable item before loading at first.\n if (onSearch && debouncedSearchTerm.length > 0 && !isLoading) {\n return Item;\n }\n\n return undefined;\n };\n\n const EmptyItem = useCallback(() => {\n if (!emptyIndicator) return undefined;\n\n // For async search that showing emptyIndicator\n if (onSearch && !creatable && Object.keys(options).length === 0) {\n return (\n <CommandItem value=\"-\" disabled>\n {emptyIndicator}\n </CommandItem>\n );\n }\n\n return <CommandEmpty>{emptyIndicator}</CommandEmpty>;\n }, [creatable, emptyIndicator, onSearch, options]);\n\n const selectables = useMemo<GroupOption>(() => removePickedOption(options, selected), [options, selected]);\n\n /** Avoid Creatable Selector freezing or lagging when paste a long string. */\n const commandFilter = useCallback(() => {\n if (commandProps?.filter) {\n return commandProps.filter;\n }\n\n if (creatable) {\n return (value: string, search: string) => {\n return value.toLowerCase().includes(search.toLowerCase()) ? 1 : -1;\n };\n }\n // Using default filter in `cmdk`. We don&lsquo;t have to provide it.\n return undefined;\n }, [creatable, commandProps?.filter]);\n\n return (\n <Command\n ref={dropdownRef}\n {...commandProps}\n onKeyDown={e => {\n handleKeyDown(e);\n commandProps?.onKeyDown?.(e);\n }}\n className={cn('h-auto overflow-visible bg-transparent', commandProps?.className)}\n shouldFilter={commandProps?.shouldFilter !== undefined ? commandProps.shouldFilter : !onSearch} // When onSearch is provided, we don&lsquo;t want to filter the options. You can still override it.\n filter={commandFilter()}\n >\n <div\n className={cn(\n 'border-border-weak relative rounded-md border text-sm transition-shadow',\n 'focus-within:border-primary',\n 'focus-within:ring-primary-weak',\n 'focus-within:ring-4',\n 'focus-within:outline-hidden',\n 'has-disabled:bg-muted',\n 'has-disabled:text-muted-foreground',\n selected.length !== 0 && 'p-1',\n !disabled && selected.length !== 0 && 'cursor-text',\n !hideClearAllButton && 'pe-9',\n className\n )}\n onClick={() => {\n if (disabled) return;\n inputRef?.current?.focus();\n }}\n >\n <div className=\"flex flex-wrap gap-1\">\n {selected.map(option => {\n return (\n <div\n key={option.value}\n className={cn(\n 'animate-fadeIn',\n 'bg-background',\n 'hover:bg-background',\n 'border-border-weak border border-solid',\n 'text-text-positive-weak relative inline-flex h-7 cursor-default items-center rounded-md ps-2 pe-7 pl-2 text-xs font-medium transition-all',\n 'disabled:cursor-not-allowed',\n 'disabled:opacity-50',\n 'data-fixed:pe-2',\n badgeClassName\n )}\n data-fixed={option.fixed}\n data-disabled={disabled || undefined}\n >\n {option.label}\n <button\n type=\"button\"\n disabled={disabled || option.fixed}\n className={cn(\n 'text-text-positive-muted absolute -inset-y-px -end-px flex size-7 items-center justify-center rounded-e-lg border border-transparent p-0 outline-0 transition-colors',\n 'hover:text-foreground',\n 'focus-visible:outline',\n 'focus-visible:outline-2',\n 'focus-visible:outline-primary-weak',\n 'disabled:hover:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50'\n )}\n onKeyDown={e => {\n if (e.key !== 'Enter') return;\n handleUnselect(option);\n }}\n onMouseDown={e => {\n e.preventDefault();\n e.stopPropagation();\n }}\n onClick={() => handleUnselect(option)}\n aria-label=\"Remove\"\n >\n <X size={14} strokeWidth={2} aria-hidden=\"true\" />\n </button>\n </div>\n );\n })}\n {/* Avoid having the \"Search\" Icon */}\n <CommandPrimitive.Input\n {...inputProps}\n ref={inputRef}\n value={inputValue}\n disabled={disabled}\n onValueChange={value => {\n setInputValue(value);\n inputProps?.onValueChange?.(value);\n }}\n onBlur={event => {\n if (!onScrollbar) {\n setOpen(false);\n }\n inputProps?.onBlur?.(event);\n }}\n onFocus={event => {\n setOpen(true);\n if (triggerSearchOnFocus) {\n onSearch?.(debouncedSearchTerm);\n }\n inputProps?.onFocus?.(event);\n }}\n placeholder={hidePlaceholderWhenSelected && selected.length !== 0 ? '' : placeholder}\n className={cn(\n 'placeholder:text-text-positive-muted flex-1 bg-transparent outline-hidden',\n 'disabled:placeholder:text-transparent',\n {\n 'w-full': hidePlaceholderWhenSelected,\n 'px-3 py-2': selected.length === 0,\n 'ml-1': selected.length !== 0,\n },\n inputProps?.className\n )}\n />\n <button\n type=\"button\"\n onClick={() => {\n setSelected(selected.filter(s => s.fixed));\n onChange?.(selected.filter(s => s.fixed));\n }}\n className={cn(\n 'text-muted-foreground/80',\n 'absolute end-0 top-0 flex size-9 items-center justify-center rounded-lg border border-transparent transition-colors',\n 'focus-visible:outline-2',\n 'hover:text-text-positive',\n 'focus-visible:outline-primary-weak',\n (hideClearAllButton || disabled || selected.length < 1 || selected.filter(({ fixed }) => fixed).length === selected.length) && 'hidden'\n )}\n aria-label=\"Clear all\"\n >\n <X size={16} strokeWidth={2} aria-hidden=\"true\" />\n </button>\n </div>\n </div>\n <div className=\"relative\">\n <div\n className={cn(\n 'shadow-dropdown absolute top-2 z-10 w-full overflow-hidden rounded-lg',\n 'data-[state=open]:animate-in',\n 'data-[state=closed]:animate-out',\n 'data-[state=closed]:fade-out-0',\n 'data-[state=open]:fade-in-0',\n 'data-[state=closed]:zoom-out-95',\n 'data-[state=open]:zoom-in-95',\n !open && 'hidden'\n )}\n data-state={open ? 'open' : 'closed'}\n >\n {open && (\n <CommandList\n className=\"shadow-lg outline-hidden\"\n onMouseLeave={() => {\n setOnScrollbar(false);\n }}\n onMouseEnter={() => {\n setOnScrollbar(true);\n }}\n onMouseUp={() => {\n inputRef?.current?.focus();\n }}\n >\n {onAddNewItem && (\n <>\n <CommandSeparator />\n <CommandGroup>\n <Button type=\"button\" variant=\"ghost\" className=\"w-full font-normal [&_div]:justify-start\" onClick={onAddNewItem}>\n <PlusIcon size={14} className=\"opacity-60\" aria-hidden=\"true\" />\n Thêm mới\n </Button>\n </CommandGroup>\n </>\n )}\n {isLoading ? (\n LoadingIndicator\n ) : (\n <>\n {EmptyItem()}\n {CreatableItem()}\n {!selectFirstItem && <CommandItem value=\"-\" className=\"hidden\" />}\n {Object.entries(selectables).map(([key, dropdowns]) => (\n <CommandGroup key={key} heading={key} className=\"h-full overflow-auto\">\n {dropdowns.map(option => {\n return (\n <CommandItem\n key={option.value}\n value={option.value}\n disabled={option.disable}\n onMouseDown={e => {\n e.preventDefault();\n e.stopPropagation();\n }}\n onSelect={() => {\n if (selected.length >= maxSelected) {\n onMaxSelected?.(selected.length);\n return;\n }\n const newOptions = [...selected, option];\n setInputValue('');\n setSelected(newOptions);\n onChange?.(newOptions);\n }}\n className={cn('cursor-pointer', option.disable && 'cursor-not-allowed opacity-50')}\n >\n {option.label}\n </CommandItem>\n );\n })}\n </CommandGroup>\n ))}\n </>\n )}\n </CommandList>\n )}\n </div>\n </div>\n </Command>\n );\n }\n);\n\nMultipleSelector.displayName = 'MultipleSelector';\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"navigation-menu.mjs","names":["NavigationMenuPrimitive"],"sources":["../../packages/components/ui/navigation-menu.tsx"],"sourcesContent":["'use client';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { ChevronDownIcon } from 'lucide-react';\n\nimport { cva } from 'class-variance-authority';\nimport { NavigationMenu as NavigationMenuPrimitive } from 'radix-ui';\n\n/**\n * Root provider for the NavigationMenu — a horizontal nav bar with dropdown content panels.\n *\n * @example\n * ```tsx\n * import {\n * NavigationMenu, NavigationMenuList, NavigationMenuItem,\n * NavigationMenuTrigger, NavigationMenuContent, NavigationMenuLink,\n * } from '@customafk/lunas-ui/ui/navigation-menu';\n *\n * <NavigationMenu>\n * <NavigationMenuList>\n * <NavigationMenuItem>\n * <NavigationMenuTrigger>Products</NavigationMenuTrigger>\n * <NavigationMenuContent>\n * <NavigationMenuLink href=\"/products\">All Products</NavigationMenuLink>\n * </NavigationMenuContent>\n * </NavigationMenuItem>\n * </NavigationMenuList>\n * </NavigationMenu>\n * ```\n */\nfunction NavigationMenu({\n className,\n children,\n viewport = true,\n ...props\n}: React.ComponentProps<typeof NavigationMenuPrimitive.Root> & {\n /** When false, the viewport animation panel is omitted (useful for inline menus). */\n viewport?: boolean;\n}) {\n return (\n <NavigationMenuPrimitive.Root\n data-slot=\"navigation-menu\"\n data-viewport={viewport}\n className={cn('group/navigation-menu relative flex max-w-max flex-1 items-center justify-center', className)}\n {...props}\n >\n {children}\n {viewport && <NavigationMenuViewport />}\n </NavigationMenuPrimitive.Root>\n );\n}\n\n/** Horizontal list that holds NavigationMenuItems. */\nfunction NavigationMenuList({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.List>) {\n return (\n <NavigationMenuPrimitive.List\n data-slot=\"navigation-menu-list\"\n className={cn('group flex flex-1 list-none items-center justify-center gap-1', className)}\n {...props}\n />\n );\n}\n\n/** A single navigation entry that may contain a trigger and a dropdown content panel. */\nfunction NavigationMenuItem({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Item>) {\n return <NavigationMenuPrimitive.Item data-slot=\"navigation-menu-item\" className={cn('relative', className)} {...props} />;\n}\n\nconst navigationMenuTriggerStyle = cva([\n 'group inline-flex h-9 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium',\n 'outline-none transition-[color,box-shadow]',\n 'hover:bg-muted-muted',\n 'hover:text-text-positive-strong',\n 'focus:bg-muted-muted',\n 'focus:text-text-positive-strong',\n 'disabled:pointer-events-none',\n 'disabled:opacity-50',\n 'data-[state=open]:hover:bg-muted-muted',\n 'data-[state=open]:text-text-positive-strong',\n 'data-[state=open]:focus:bg-muted-muted',\n 'data-[state=open]:bg-muted-weak',\n 'focus-visible:ring-primary-weak',\n 'focus-visible:ring-[3px]',\n 'focus-visible:outline-1',\n]);\n\n/** Button that opens the associated NavigationMenuContent panel on focus or hover. */\nfunction NavigationMenuTrigger({ className, children, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Trigger>) {\n return (\n <NavigationMenuPrimitive.Trigger data-slot=\"navigation-menu-trigger\" className={cn(navigationMenuTriggerStyle(), 'group', className)} {...props}>\n {children} <ChevronDownIcon className=\"relative top-[1px] ml-1 size-3 transition duration-300 group-data-[state=open]:rotate-180\" aria-hidden=\"true\" />\n </NavigationMenuPrimitive.Trigger>\n );\n}\n\n/** Dropdown content panel revealed when a NavigationMenuTrigger is activated. */\nfunction NavigationMenuContent({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Content>) {\n return (\n <NavigationMenuPrimitive.Content\n data-slot=\"navigation-menu-content\"\n className={cn(\n 'data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 top-0 left-0 w-full p-2 pr-2.5 md:absolute md:w-auto',\n 'group-data-[viewport=false]/navigation-menu:bg-popover group-data-[viewport=false]/navigation-menu:text-popover-foreground group-data-[viewport=false]/navigation-menu:data-[state=open]:animate-in group-data-[viewport=false]/navigation-menu:data-[state=closed]:animate-out group-data-[viewport=false]/navigation-menu:data-[state=closed]:zoom-out-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:zoom-in-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:fade-in-0 group-data-[viewport=false]/navigation-menu:data-[state=closed]:fade-out-0 group-data-[viewport=false]/navigation-menu:top-full group-data-[viewport=false]/navigation-menu:mt-1.5 group-data-[viewport=false]/navigation-menu:overflow-hidden group-data-[viewport=false]/navigation-menu:rounded-md group-data-[viewport=false]/navigation-menu:border group-data-[viewport=false]/navigation-menu:shadow group-data-[viewport=false]/navigation-menu:duration-200 **:data-[slot=navigation-menu-link]:focus:ring-0 **:data-[slot=navigation-menu-link]:focus:outline-none',\n className\n )}\n {...props}\n />\n );\n}\n\n/** Animated viewport container that hosts the active NavigationMenuContent. */\nfunction NavigationMenuViewport({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Viewport>) {\n return (\n <div className={cn('absolute top-full left-0 isolate z-50 flex justify-center')}>\n <NavigationMenuPrimitive.Viewport\n data-slot=\"navigation-menu-viewport\"\n className={cn(\n 'origin-top-center bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border shadow md:w-[var(--radix-navigation-menu-viewport-width)]',\n className\n )}\n {...props}\n />\n </div>\n );\n}\n\n/** A styled link used inside NavigationMenuContent that highlights when active. */\nfunction NavigationMenuLink({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Link>) {\n return (\n <NavigationMenuPrimitive.Link\n data-slot=\"navigation-menu-link\"\n className={cn(\n 'text-text-positive flex flex-col gap-1 rounded-sm p-2 text-sm transition-all outline-none',\n 'hover:bg-muted-muted',\n 'hover:text-text-positive-strong',\n 'focus:bg-muted-muted',\n 'focus:text-text-positive-strong',\n 'focus-visible:ring-primary-weak',\n 'focus-visible:outline-1',\n 'focus-visible:ring-[3px]',\n \"[&_svg:not([class*='text-'])]:text-text-positive-weak\",\n \"[&_svg:not([class*='size-'])]:size-4\",\n 'data-[active=true]:focus:bg-muted-muted',\n 'data-[active=true]:hover:bg-muted-muted',\n 'data-[active=true]:bg-muted-weak',\n 'data-[active=true]:text-text-positive-strong',\n className\n )}\n {...props}\n />\n );\n}\n\n/** Small arrow indicator that points from the active NavigationMenuTrigger to its content panel. */\nfunction NavigationMenuIndicator({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Indicator>) {\n return (\n <NavigationMenuPrimitive.Indicator\n data-slot=\"navigation-menu-indicator\"\n className={cn(\n 'top-full z-1 flex h-1.5 items-end justify-center overflow-hidden',\n 'data-[state=visible]:animate-in',\n 'data-[state=hidden]:animate-out',\n 'data-[state=hidden]:fade-out',\n 'data-[state=visible]:fade-in',\n className\n )}\n {...props}\n >\n <div className=\"bg-border relative top-3/5 h-2 w-2 rotate-45 rounded-tl-sm shadow-md\" />\n </NavigationMenuPrimitive.Indicator>\n );\n}\n\nexport {\n NavigationMenu,\n NavigationMenuContent,\n NavigationMenuIndicator,\n NavigationMenuItem,\n NavigationMenuLink,\n NavigationMenuList,\n NavigationMenuTrigger,\n // eslint-disable-next-line react-refresh/only-export-components\n navigationMenuTriggerStyle,\n NavigationMenuViewport,\n};\n"],"mappings":"2PA8BA,SAAS,EAAe,CACtB,YACA,WACA,WAAW,GACX,GAAG,GAIF,CACD,OACE,EAACA,EAAwB,KAAA,CACvB,YAAU,kBACV,gBAAe,EACf,UAAW,EAAG,mFAAoF,EAAU,CAC5G,GAAI,YAEH,EACA,GAAY,EAAC,EAAA,EAAA,CAAyB,CAAA,EACV,CAKnC,SAAS,EAAmB,CAAE,YAAW,GAAG,GAAoE,CAC9G,OACE,EAACA,EAAwB,KAAA,CACvB,YAAU,uBACV,UAAW,EAAG,gEAAiE,EAAU,CACzF,GAAI,GACJ,CAKN,SAAS,EAAmB,CAAE,YAAW,GAAG,GAAoE,CAC9G,OAAO,EAACA,EAAwB,KAAA,CAAK,YAAU,uBAAuB,UAAW,EAAG,WAAY,EAAU,CAAE,GAAI,GAAS,CAG3H,MAAM,EAA6B,EAAI,CACrC,iHACA,6CACA,uBACA,kCACA,uBACA,kCACA,+BACA,sBACA,yCACA,8CACA,yCACA,kCACA,kCACA,2BACA,0BACD,CAAC,CAGF,SAAS,EAAsB,CAAE,YAAW,WAAU,GAAG,GAAuE,CAC9H,OACE,EAACA,EAAwB,QAAA,CAAQ,YAAU,0BAA0B,UAAW,EAAG,GAA4B,CAAE,QAAS,EAAU,CAAE,GAAI,YACvI,EAAS,IAAC,EAAC,EAAA,CAAgB,UAAU,4FAA4F,cAAY,QAAS,GACvH,CAKtC,SAAS,EAAsB,CAAE,YAAW,GAAG,GAAuE,CACpH,OACE,EAACA,EAAwB,QAAA,CACvB,YAAU,0BACV,UAAW,EACT,mWACA,4hCACA,EACD,CACD,GAAI,GACJ,CAKN,SAAS,EAAuB,CAAE,YAAW,GAAG,GAAwE,CACtH,OACE,EAAC,MAAA,CAAI,UAAW,EAAG,4DAA4D,UAC7E,EAACA,EAAwB,SAAA,CACvB,YAAU,2BACV,UAAW,EACT,qVACA,EACD,CACD,GAAI,GACJ,EACE,CAKV,SAAS,EAAmB,CAAE,YAAW,GAAG,GAAoE,CAC9G,OACE,EAACA,EAAwB,KAAA,CACvB,YAAU,uBACV,UAAW,EACT,4FACA,uBACA,kCACA,uBACA,kCACA,kCACA,0BACA,2BACA,wDACA,uCACA,0CACA,0CACA,mCACA,+CACA,EACD,CACD,GAAI,GACJ,CAKN,SAAS,EAAwB,CAAE,YAAW,GAAG,GAAyE,CACxH,OACE,EAACA,EAAwB,UAAA,CACvB,YAAU,4BACV,UAAW,EACT,mEACA,kCACA,kCACA,+BACA,+BACA,EACD,CACD,GAAI,WAEJ,EAAC,MAAA,CAAI,UAAU,uEAAA,CAAyE,EACtD"}
@@ -1,2 +0,0 @@
1
- "use client";import{n as e}from"../button.variants-DkMqWB8G.mjs";import{ChevronLeftIcon as t,ChevronRightIcon as n,MoreHorizontalIcon as r}from"lucide-react";import{cn as i}from"@customafk/react-toolkit/utils";import{jsx as a,jsxs as o}from"react/jsx-runtime";function s({className:e,...t}){return a(`nav`,{role:`navigation`,"aria-label":`pagination`,"data-slot":`pagination`,className:i(`mx-auto flex w-full justify-center`,e),...t})}function c({className:e,...t}){return a(`ul`,{"data-slot":`pagination-content`,className:i(`flex flex-row items-center gap-1`,e),...t})}function l({...e}){return a(`li`,{"data-slot":`pagination-item`,...e})}function u({className:t,isActive:n,size:r=`icon`,...o}){return a(`a`,{"aria-current":n?`page`:void 0,"data-slot":`pagination-link`,"data-active":n,className:i(e({variant:n?`outline`:`ghost`,size:r}),t),...o})}function d({className:e,...n}){return o(u,{"aria-label":`Go to previous page`,size:`default`,className:i(`gap-1 px-2.5 sm:pl-2.5`,e),...n,children:[a(t,{}),a(`span`,{className:`hidden sm:block`,children:`Previous`})]})}function f({className:e,...t}){return o(u,{"aria-label":`Go to next page`,size:`default`,className:i(`gap-1 px-2.5 sm:pr-2.5`,e),...t,children:[a(`span`,{className:`hidden sm:block`,children:`Next`}),a(n,{})]})}function p({className:e,...t}){return o(`span`,{"aria-hidden":!0,"data-slot":`pagination-ellipsis`,className:i(`flex size-9 items-center justify-center`,e),...t,children:[a(r,{className:`size-4`}),a(`span`,{className:`sr-only`,children:`More pages`})]})}export{s as Pagination,c as PaginationContent,p as PaginationEllipsis,l as PaginationItem,u as PaginationLink,f as PaginationNext,d as PaginationPrevious};
2
- //# sourceMappingURL=pagination.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pagination.mjs","names":[],"sources":["../../packages/components/ui/pagination.tsx"],"sourcesContent":["'use client';\n\nimport { ChevronLeftIcon, ChevronRightIcon, MoreHorizontalIcon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport type { Button } from '@/components/ui/button';\nimport { buttonVariants } from './button.variants';\n\n/**\n * Root `<nav>` wrapper for a Pagination control with accessible ARIA attributes.\n *\n * @example\n * ```tsx\n * import {\n * Pagination, PaginationContent, PaginationItem,\n * PaginationLink, PaginationPrevious, PaginationNext, PaginationEllipsis,\n * } from '@customafk/lunas-ui/ui/pagination';\n *\n * <Pagination>\n * <PaginationContent>\n * <PaginationItem><PaginationPrevious href=\"?page=1\" /></PaginationItem>\n * <PaginationItem><PaginationLink href=\"?page=2\" isActive>2</PaginationLink></PaginationItem>\n * <PaginationItem><PaginationEllipsis /></PaginationItem>\n * <PaginationItem><PaginationNext href=\"?page=3\" /></PaginationItem>\n * </PaginationContent>\n * </Pagination>\n * ```\n */\nfunction Pagination({ className, ...props }: React.ComponentProps<'nav'>) {\n return <nav role=\"navigation\" aria-label=\"pagination\" data-slot=\"pagination\" className={cn('mx-auto flex w-full justify-center', className)} {...props} />;\n}\n\n/** Horizontal list that holds PaginationItem elements. */\nfunction PaginationContent({ className, ...props }: React.ComponentProps<'ul'>) {\n return <ul data-slot=\"pagination-content\" className={cn('flex flex-row items-center gap-1', className)} {...props} />;\n}\n\n/** Wrapper `<li>` for a single pagination button or link. */\nfunction PaginationItem({ ...props }: React.ComponentProps<'li'>) {\n return <li data-slot=\"pagination-item\" {...props} />;\n}\n\ntype PaginationLinkProps = {\n /** When true, the link is styled as the currently active page. */\n isActive?: boolean;\n} & Pick<React.ComponentProps<typeof Button>, 'size'> &\n React.ComponentProps<'a'>;\n\n/** An anchor-based page link styled as a button, highlighted when `isActive` is true. */\nfunction PaginationLink({ className, isActive, size = 'icon', ...props }: PaginationLinkProps) {\n return (\n <a\n aria-current={isActive ? 'page' : undefined}\n data-slot=\"pagination-link\"\n data-active={isActive}\n className={cn(\n buttonVariants({\n variant: isActive ? 'outline' : 'ghost',\n size,\n }),\n className\n )}\n {...props}\n />\n );\n}\n\n/** \"Previous page\" navigation link with a left chevron icon. */\nfunction PaginationPrevious({ className, ...props }: React.ComponentProps<typeof PaginationLink>) {\n return (\n <PaginationLink aria-label=\"Go to previous page\" size=\"default\" className={cn('gap-1 px-2.5 sm:pl-2.5', className)} {...props}>\n <ChevronLeftIcon />\n <span className=\"hidden sm:block\">Previous</span>\n </PaginationLink>\n );\n}\n\n/** \"Next page\" navigation link with a right chevron icon. */\nfunction PaginationNext({ className, ...props }: React.ComponentProps<typeof PaginationLink>) {\n return (\n <PaginationLink aria-label=\"Go to next page\" size=\"default\" className={cn('gap-1 px-2.5 sm:pr-2.5', className)} {...props}>\n <span className=\"hidden sm:block\">Next</span>\n <ChevronRightIcon />\n </PaginationLink>\n );\n}\n\n/** Ellipsis indicator rendered between non-adjacent page numbers. */\nfunction PaginationEllipsis({ className, ...props }: React.ComponentProps<'span'>) {\n return (\n <span aria-hidden data-slot=\"pagination-ellipsis\" className={cn('flex size-9 items-center justify-center', className)} {...props}>\n <MoreHorizontalIcon className=\"size-4\" />\n <span className=\"sr-only\">More pages</span>\n </span>\n );\n}\n\nexport { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious };\n"],"mappings":"oQA6BA,SAAS,EAAW,CAAE,YAAW,GAAG,GAAsC,CACxE,OAAO,EAAC,MAAA,CAAI,KAAK,aAAa,aAAW,aAAa,YAAU,aAAa,UAAW,EAAG,qCAAsC,EAAU,CAAE,GAAI,GAAS,CAI5J,SAAS,EAAkB,CAAE,YAAW,GAAG,GAAqC,CAC9E,OAAO,EAAC,KAAA,CAAG,YAAU,qBAAqB,UAAW,EAAG,mCAAoC,EAAU,CAAE,GAAI,GAAS,CAIvH,SAAS,EAAe,CAAE,GAAG,GAAqC,CAChE,OAAO,EAAC,KAAA,CAAG,YAAU,kBAAkB,GAAI,GAAS,CAUtD,SAAS,EAAe,CAAE,YAAW,WAAU,OAAO,OAAQ,GAAG,GAA8B,CAC7F,OACE,EAAC,IAAA,CACC,eAAc,EAAW,OAAS,IAAA,GAClC,YAAU,kBACV,cAAa,EACb,UAAW,EACT,EAAe,CACb,QAAS,EAAW,UAAY,QAChC,OACD,CAAC,CACF,EACD,CACD,GAAI,GACJ,CAKN,SAAS,EAAmB,CAAE,YAAW,GAAG,GAAsD,CAChG,OACE,EAAC,EAAA,CAAe,aAAW,sBAAsB,KAAK,UAAU,UAAW,EAAG,yBAA0B,EAAU,CAAE,GAAI,YACtH,EAAC,EAAA,EAAA,CAAkB,CACnB,EAAC,OAAA,CAAK,UAAU,2BAAkB,YAAe,CAAA,EAClC,CAKrB,SAAS,EAAe,CAAE,YAAW,GAAG,GAAsD,CAC5F,OACE,EAAC,EAAA,CAAe,aAAW,kBAAkB,KAAK,UAAU,UAAW,EAAG,yBAA0B,EAAU,CAAE,GAAI,YAClH,EAAC,OAAA,CAAK,UAAU,2BAAkB,QAAW,CAC7C,EAAC,EAAA,EAAA,CAAmB,CAAA,EACL,CAKrB,SAAS,EAAmB,CAAE,YAAW,GAAG,GAAuC,CACjF,OACE,EAAC,OAAA,CAAK,cAAA,GAAY,YAAU,sBAAsB,UAAW,EAAG,0CAA2C,EAAU,CAAE,GAAI,YACzH,EAAC,EAAA,CAAmB,UAAU,SAAA,CAAW,CACzC,EAAC,OAAA,CAAK,UAAU,mBAAU,cAAiB,CAAA,EACtC"}
@@ -1 +0,0 @@
1
- "use client";import"../close-_UHFeiLS.mjs";import{a as e,i as t,n,r,t as i}from"../popover-C8rcemA3.mjs";export{i as Popover,n as PopoverAnchor,r as PopoverClose,t as PopoverContent,e as PopoverTrigger};
@@ -1 +0,0 @@
1
- "use client";import{t as e}from"../progress-CLeM0e7Z.mjs";export{e as Progress};
@@ -1 +0,0 @@
1
- "use client";import{n as e,t}from"../radio-group-Y9bhdr55.mjs";export{t as RadioGroup,e as RadioGroupItem};
@@ -1 +0,0 @@
1
- "use client";import{n as e,r as t,t as n}from"../resizable-CpCaSCFB.mjs";export{n as ResizableHandle,e as ResizablePanel,t as ResizablePanelGroup};
@@ -1 +0,0 @@
1
- {"version":3,"file":"scroll-area.mjs","names":["ScrollAreaPrimitive"],"sources":["../../packages/components/ui/scroll-area.tsx"],"sourcesContent":["'use client';\nimport { memo } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { ScrollArea as ScrollAreaPrimitive } from 'radix-ui';\n\n/**\n * A scrollable container with a styled, custom scrollbar that overlays the content.\n *\n * @example\n * ```tsx\n * import { ScrollArea } from '@customafk/lunas-ui/ui/scroll-area';\n *\n * <ScrollArea className=\"h-64 w-full\">\n * <div className=\"p-4\">Long content goes here…</div>\n * </ScrollArea>\n * ```\n */\nconst ScrollArea = memo(({ className, children, ref, onScroll, ...props }: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) => {\n return (\n <ScrollAreaPrimitive.Root data-slot=\"scroll-area\" className={cn('relative overflow-hidden', className)} {...props}>\n <ScrollAreaPrimitive.Viewport ref={ref} className=\"size-full rounded-[inherit]\" onScroll={onScroll}>\n {children}\n </ScrollAreaPrimitive.Viewport>\n <ScrollBar />\n <ScrollAreaPrimitive.Corner />\n </ScrollAreaPrimitive.Root>\n );\n});\nScrollArea.displayName = 'ScrollArea';\n\n/**\n * The styled scrollbar track and thumb rendered inside a ScrollArea.\n *\n * @param orientation - Direction of the scrollbar: `'vertical'` (default) or `'horizontal'`.\n */\nconst ScrollBar = memo(({ className, orientation = 'vertical', ...props }: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) => {\n return (\n <ScrollAreaPrimitive.ScrollAreaScrollbar\n data-slot=\"scroll-area-scrollbar\"\n orientation={orientation}\n className={cn(\n 'flex touch-none select-none border-border-weak p-px transition-colors',\n orientation === 'vertical' && 'h-full w-2.5 border-l border-l-transparent',\n orientation === 'horizontal' && 'h-2.5 flex-col border-t border-t-transparent',\n className\n )}\n {...props}\n >\n <ScrollAreaPrimitive.ScrollAreaThumb className=\"relative flex-1 rounded-full bg-border-weak\" />\n </ScrollAreaPrimitive.ScrollAreaScrollbar>\n );\n});\nScrollBar.displayName = 'ScrollBar';\n\nexport { ScrollArea, ScrollBar };\n"],"mappings":"sLAmBA,MAAM,EAAa,GAAM,CAAE,YAAW,WAAU,MAAK,WAAU,GAAG,KAE9D,EAACA,EAAoB,KAAA,CAAK,YAAU,cAAc,UAAW,EAAG,2BAA4B,EAAU,CAAE,GAAI,YAC1G,EAACA,EAAoB,SAAA,CAAc,MAAK,UAAU,8BAAwC,WACvF,YAC4B,CAC/B,EAAC,EAAA,EAAA,CAAY,CACb,EAACA,EAAoB,OAAA,EAAA,CAAS,GACL,CAE7B,CACF,EAAW,YAAc,aAOzB,MAAM,EAAY,GAAM,CAAE,YAAW,cAAc,WAAY,GAAG,KAE9D,EAACA,EAAoB,oBAAA,CACnB,YAAU,wBACG,cACb,UAAW,EACT,wEACA,IAAgB,YAAc,6CAC9B,IAAgB,cAAgB,+CAChC,EACD,CACD,GAAI,WAEJ,EAACA,EAAoB,gBAAA,CAAgB,UAAU,8CAAA,CAAgD,EACvD,CAE5C,CACF,EAAU,YAAc"}
@@ -1 +0,0 @@
1
- "use client";import{a as e,c as t,i as n,n as r,o as i,r as a,s as o,t as s}from"../select-LlPCZFSF.mjs";export{s as Select,r as SelectContent,a as SelectGroup,n as SelectItem,e as SelectLabel,i as SelectSeparator,o as SelectTrigger,t as SelectValue};
@@ -1 +0,0 @@
1
- "use client";import{t as e}from"../separator-D3Gmkxzq.mjs";export{e as Separator};
package/dist/ui/sheet.mjs DELETED
@@ -1 +0,0 @@
1
- "use client";import{a as e,c as t,i as n,n as r,o as i,r as a,s as o,t as s}from"../sheet-BFlIfNaA.mjs";export{s as Sheet,r as SheetClose,a as SheetContent,n as SheetDescription,e as SheetFooter,i as SheetHeader,o as SheetTitle,t as SheetTrigger};
@@ -1 +0,0 @@
1
- "use client";import{t as e}from"../skeleton-C51IdOfK.mjs";export{e as Skeleton};
@@ -1 +0,0 @@
1
- {"version":3,"file":"slider.mjs","names":["SliderPrimitive"],"sources":["../../packages/components/ui/slider.tsx"],"sourcesContent":["'use client';\nimport { useMemo } from 'react';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Slider as SliderPrimitive } from 'radix-ui';\n\n/**\n * An accessible range slider supporting single-thumb, multi-thumb, and vertical orientations.\n *\n * @example\n * ```tsx\n * import { Slider } from '@customafk/lunas-ui/ui/slider';\n *\n * <Slider defaultValue={[40]} min={0} max={100} step={5} />\n * ```\n */\nfunction Slider({ className, defaultValue, value, min = 0, max = 100, ...props }: React.ComponentProps<typeof SliderPrimitive.Root>) {\n const _values = useMemo(() => (Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min, max]), [value, defaultValue, min, max]);\n\n return (\n <SliderPrimitive.Root\n data-slot=\"slider\"\n defaultValue={defaultValue}\n value={value}\n min={min}\n max={max}\n className={cn(\n 'relative flex w-full touch-none items-center select-none',\n 'data-[disabled]:opacity-50',\n 'data-[orientation=vertical]:h-full',\n 'data-[orientation=vertical]:min-h-44',\n 'data-[orientation=vertical]:w-auto',\n 'data-[orientation=vertical]:flex-col',\n className\n )}\n {...props}\n >\n <SliderPrimitive.Track\n data-slot=\"slider-track\"\n className={cn(\n 'bg-muted relative grow overflow-hidden rounded-full data-[orientation=horizontal]:h-1.5 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1.5'\n )}\n >\n <SliderPrimitive.Range\n data-slot=\"slider-range\"\n className={cn('bg-primary absolute data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full')}\n />\n </SliderPrimitive.Track>\n {Array.from({ length: _values.length }, (_, index) => (\n <SliderPrimitive.Thumb\n data-slot=\"slider-thumb\"\n key={index}\n className=\"border-primary bg-background ring-ring/50 block size-4 shrink-0 rounded-full border shadow-sm transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50\"\n />\n ))}\n </SliderPrimitive.Root>\n );\n}\n\nexport { Slider };\n"],"mappings":"qLAgBA,SAAS,EAAO,CAAE,YAAW,eAAc,QAAO,MAAM,EAAG,MAAM,IAAK,GAAG,GAA4D,CACnI,IAAM,EAAU,MAAe,MAAM,QAAQ,EAAM,CAAG,EAAQ,MAAM,QAAQ,EAAa,CAAG,EAAe,CAAC,EAAK,EAAI,CAAG,CAAC,EAAO,EAAc,EAAK,EAAI,CAAC,CAExJ,OACE,EAACA,EAAgB,KAAA,CACf,YAAU,SACI,eACP,QACF,MACA,MACL,UAAW,EACT,2DACA,6BACA,qCACA,uCACA,qCACA,uCACA,EACD,CACD,GAAI,YAEJ,EAACA,EAAgB,MAAA,CACf,YAAU,eACV,UAAW,EACT,oMACD,UAED,EAACA,EAAgB,MAAA,CACf,YAAU,eACV,UAAW,EAAG,8FAA8F,EAC5G,EACoB,CACvB,MAAM,KAAK,CAAE,OAAQ,EAAQ,OAAQ,EAAG,EAAG,IAC1C,EAACA,EAAgB,MAAA,CACf,YAAU,eAEV,UAAU,+OADL,EAEL,CACF,CAAA,EACmB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"sonner.mjs","names":["Sonner"],"sources":["../../packages/components/ui/sonner.tsx"],"sourcesContent":["'use client';\nimport { LoaderIcon } from 'lucide-react';\nimport { useTheme } from 'next-themes';\nimport { Toaster as Sonner, toast, type ToasterProps } from 'sonner';\n\n/**\n * Global toast notification container — mount once near the root of your app; use the exported `toast` helper to trigger toasts from anywhere.\n *\n * @example\n * ```tsx\n * import { Toaster, toast } from '@customafk/lunas-ui/ui/sonner';\n *\n * // In your app root:\n * <Toaster />\n *\n * // Anywhere in your code:\n * toast.success('Saved!');\n * toast.error('Something went wrong.');\n * ```\n */\nconst Toaster = () => {\n const { theme = 'system' } = useTheme();\n\n return (\n <Sonner\n theme={theme as ToasterProps['theme']}\n expand={false}\n visibleToasts={5}\n closeButton={true}\n position=\"bottom-right\"\n swipeDirections={['left', 'right']}\n icons={{\n loading: <LoaderIcon size={16} className=\"animate-spin\" />,\n }}\n style={\n {\n '--normal-bg': 'rgb(124 58 237)',\n '--normal-text': 'white',\n '--normal-border': 'transparent',\n } as React.CSSProperties\n }\n toastOptions={{\n classNames: {\n toast: '!text-white !border-none !rounded-xl cursor-grab active:cursor-grabbing select-none z-99999 !px-4 !py-3.5 !gap-3 !items-center',\n icon: '!size-8 !rounded-full !bg-white/20 !shrink-0 [&>svg]:!size-4 !flex !items-center !justify-center',\n title: '!text-sm !font-bold !leading-snug !text-white',\n description: '!text-xs !font-medium !text-white/75 !leading-snug',\n success: '!bg-success',\n info: '!bg-blue-700',\n loading: '!bg-slate-500',\n warning: '!bg-warning',\n error: '!bg-danger',\n closeButton: '!text-white/60 hover:!text-white !bg-white/10 hover:!bg-white/20 !border-none !top-1/2 !-translate-y-1/2 !right-3 !left-auto',\n },\n }}\n className=\"toaster group pointer-events-auto z-999999!\"\n />\n );\n};\n\nexport { Toaster, toast };\nexport default Toaster;\n"],"mappings":"kLAoBA,MAAM,MAAgB,CACpB,GAAM,CAAE,QAAQ,UAAa,GAAU,CAEvC,OACE,EAACA,EAAAA,CACQ,QACP,OAAQ,GACR,cAAe,EACf,YAAa,GACb,SAAS,eACT,gBAAiB,CAAC,OAAQ,QAAQ,CAClC,MAAO,CACL,QAAS,EAAC,EAAA,CAAW,KAAM,GAAI,UAAU,gBAAiB,CAC3D,CACD,MACE,CACE,cAAe,kBACf,gBAAiB,QACjB,kBAAmB,cACpB,CAEH,aAAc,CACZ,WAAY,CACV,MAAO,iIACP,KAAM,mGACN,MAAO,gDACP,YAAa,qDACb,QAAS,cACT,KAAM,eACN,QAAS,gBACT,QAAS,cACT,MAAO,aACP,YAAa,+HACd,CACF,CACD,UAAU,+CACV,EAKN,IAAA,EAAe"}
@@ -1 +0,0 @@
1
- import{t as e}from"../spinner-eClTgHjk.mjs";export{e as Spinner};
@@ -1 +0,0 @@
1
- "use client";import{t as e}from"../switch-BP7EPatj.mjs";export{e as Switch};
@@ -1 +0,0 @@
1
- {"version":3,"file":"table.mjs","names":[],"sources":["../../packages/components/ui/table.tsx"],"sourcesContent":["'use client';\n\nimport { memo } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\n/**\n * Full-width semantic table with caption-bottom layout, intended to be composed with TableHeader, TableBody, and related sub-components.\n *\n * @example\n * ```tsx\n * import {\n * Table, TableHeader, TableBody, TableRow,\n * TableHead, TableCell, TableCaption,\n * } from '@customafk/lunas-ui/ui/table';\n *\n * <Table>\n * <TableCaption>Invoice list</TableCaption>\n * <TableHeader>\n * <TableRow>\n * <TableHead>Name</TableHead>\n * <TableHead>Amount</TableHead>\n * </TableRow>\n * </TableHeader>\n * <TableBody>\n * <TableRow>\n * <TableCell>Acme Corp</TableCell>\n * <TableCell>$1,200</TableCell>\n * </TableRow>\n * </TableBody>\n * </Table>\n * ```\n */\nconst Table = memo(({ className, ...props }: React.ComponentProps<'table'>) => {\n return <table data-slot=\"table\" className={cn('w-full caption-bottom text-sm', className)} {...props} />;\n});\nTable.displayName = 'Table';\n\n/** The `<thead>` element containing one or more header rows. */\nconst TableHeader = memo(({ className, ...props }: React.ComponentProps<'thead'>) => {\n return <thead data-slot=\"table-header\" className={cn('[&_tr:not(:last-child)_td]:border-b', className)} {...props} />;\n});\nTableHeader.displayName = 'TableHeader';\n\n/** The `<tbody>` element containing data rows with hover and selection styling. */\nconst TableBody = memo(({ className, ...props }: React.ComponentProps<'tbody'>) => {\n return (\n <tbody\n data-slot=\"table-body\"\n className={cn(\n '[&_tr:last-child]:border-0',\n '[&_tr]:hover:bg-muted-muted/50',\n '[&_tr]:active:bg-muted-muted',\n '[&_tr]:data-[state=selected]:bg-muted',\n '[&_tr]:border-border-weak',\n '[&_tr]:border-b',\n '[&_tr]:transition-colors',\n className\n )}\n {...props}\n />\n );\n});\nTableBody.displayName = 'TableBody';\n\n/** The `<tfoot>` element for summary or aggregate rows at the bottom of the table. */\nconst TableFooter = memo(({ className, ...props }: React.ComponentProps<'tfoot'>) => {\n return <tfoot data-slot=\"table-footer\" className={cn('border-border-weak border-t font-medium [&>tr]:last:border-b-0', className)} {...props} />;\n});\nTableFooter.displayName = 'TableFooter';\n\n/** A single `<tr>` row used inside TableHeader, TableBody, or TableFooter. */\nconst TableRow = memo(({ className, ...props }: React.ComponentProps<'tr'>) => {\n return <tr data-slot=\"table-row\" className={className} {...props} />;\n});\nTableRow.displayName = 'TableRow';\n\n/** A `<th>` column header cell with medium-weight text and left alignment. */\nconst TableHead = memo(({ className, ...props }: React.ComponentProps<'th'>) => {\n return (\n <th\n data-slot=\"table-head\"\n className={cn(\n 'text-text-positive-weak',\n 'h-10 whitespace-nowrap px-2 text-left align-middle font-medium',\n '[&:has([role=checkbox])]:pr-0',\n '[&>[role=checkbox]]:translate-y-0.5',\n className\n )}\n {...props}\n />\n );\n});\nTableHead.displayName = 'TableHead';\n\n/** A standard `<td>` data cell used inside a TableRow. */\nconst TableCell = memo(({ className, ...props }: React.ComponentProps<'td'>) => {\n return <td data-slot=\"table-cell\" className={className} {...props} />;\n});\nTableCell.displayName = 'TableCell';\n\n/** An accessible `<caption>` element displayed below the table. */\nconst TableCaption = memo(({ className, ...props }: React.ComponentProps<'caption'>) => {\n return <caption data-slot=\"table-caption\" className={cn('text-text-positive-muted mt-4 text-sm', className)} {...props} />;\n});\nTableCaption.displayName = 'TableCaption';\n\nexport { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow };\n"],"mappings":"sIAiCA,MAAM,EAAQ,GAAM,CAAE,YAAW,GAAG,KAC3B,EAAC,QAAA,CAAM,YAAU,QAAQ,UAAW,EAAG,gCAAiC,EAAU,CAAE,GAAI,GAAS,CACxG,CACF,EAAM,YAAc,QAGpB,MAAM,EAAc,GAAM,CAAE,YAAW,GAAG,KACjC,EAAC,QAAA,CAAM,YAAU,eAAe,UAAW,EAAG,sCAAuC,EAAU,CAAE,GAAI,GAAS,CACrH,CACF,EAAY,YAAc,cAG1B,MAAM,EAAY,GAAM,CAAE,YAAW,GAAG,KAEpC,EAAC,QAAA,CACC,YAAU,aACV,UAAW,EACT,6BACA,iCACA,+BACA,wCACA,4BACA,kBACA,2BACA,EACD,CACD,GAAI,GACJ,CAEJ,CACF,EAAU,YAAc,YAGxB,MAAM,EAAc,GAAM,CAAE,YAAW,GAAG,KACjC,EAAC,QAAA,CAAM,YAAU,eAAe,UAAW,EAAG,iEAAkE,EAAU,CAAE,GAAI,GAAS,CAChJ,CACF,EAAY,YAAc,cAG1B,MAAM,EAAW,GAAM,CAAE,YAAW,GAAG,KAC9B,EAAC,KAAA,CAAG,YAAU,YAAuB,YAAW,GAAI,GAAS,CACpE,CACF,EAAS,YAAc,WAGvB,MAAM,EAAY,GAAM,CAAE,YAAW,GAAG,KAEpC,EAAC,KAAA,CACC,YAAU,aACV,UAAW,EACT,0BACA,iEACA,gCACA,sCACA,EACD,CACD,GAAI,GACJ,CAEJ,CACF,EAAU,YAAc,YAGxB,MAAM,EAAY,GAAM,CAAE,YAAW,GAAG,KAC/B,EAAC,KAAA,CAAG,YAAU,aAAwB,YAAW,GAAI,GAAS,CACrE,CACF,EAAU,YAAc,YAGxB,MAAM,EAAe,GAAM,CAAE,YAAW,GAAG,KAClC,EAAC,UAAA,CAAQ,YAAU,gBAAgB,UAAW,EAAG,wCAAyC,EAAU,CAAE,GAAI,GAAS,CAC1H,CACF,EAAa,YAAc"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"tabs.mjs","names":["TabsPrimitive"],"sources":["../../packages/components/ui/tabs.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Tabs as TabsPrimitive } from 'radix-ui';\n\n/**\n * Keyboard-accessible tabbed panel built on Radix UI's Tabs primitives, composed from `Tabs`, `TabsList`, `TabsTrigger`, and `TabsContent`.\n *\n * @example\n * ```tsx\n * import { Tabs, TabsList, TabsTrigger, TabsContent } from '@customafk/lunas-ui/ui/tabs';\n *\n * <Tabs defaultValue=\"overview\">\n * <TabsList>\n * <TabsTrigger value=\"overview\">Overview</TabsTrigger>\n * <TabsTrigger value=\"settings\">Settings</TabsTrigger>\n * </TabsList>\n * <TabsContent value=\"overview\">Overview content here.</TabsContent>\n * <TabsContent value=\"settings\">Settings content here.</TabsContent>\n * </Tabs>\n * ```\n */\nfunction Tabs({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Root>) {\n return <TabsPrimitive.Root data-slot=\"tabs\" className={cn('flex flex-col gap-2', className)} {...props} />;\n}\n\n/** Container that holds the row of `TabsTrigger` buttons with a muted background pill style. */\nfunction TabsList({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.List>) {\n return (\n <TabsPrimitive.List\n data-slot=\"tabs-list\"\n className={cn('inline-flex h-9 w-fit items-center justify-center gap-x-1 rounded-sm bg-muted-muted p-1', className)}\n {...props}\n />\n );\n}\n\n/** Individual tab button that activates its associated `TabsContent` panel when clicked. */\nfunction TabsTrigger({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Trigger>) {\n return (\n <TabsPrimitive.Trigger\n data-slot=\"tabs-trigger\"\n className={cn(\n 'text-text-positive-weak',\n 'inline-flex h-[calc(100%-1px)] min-w-32 flex-1 cursor-pointer items-center justify-center gap-1.5',\n 'rounded-sm',\n 'whitespace-nowrap border border-transparent px-2 py-1 font-medium text-sm transition',\n // 'hover:bg-muted-muted/60',\n 'data-[state=active]:shadow-card',\n 'data-[state=active]:bg-background',\n 'disabled:opacity-50',\n 'disabled:pointer-events-none',\n 'focus-visible:border-primary',\n 'focus-visible:ring-4',\n 'focus-visible:ring-primary-weak',\n 'focus-visible:outline-1',\n 'focus-visible:outline-primary',\n '[&_svg]:pointer-events-none',\n '[&_svg]:shrink-0',\n \"[&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n );\n}\n\n/** Panel whose visibility is controlled by the active `TabsTrigger`; each panel must have a matching `value`. */\nfunction TabsContent({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Content>) {\n return <TabsPrimitive.Content data-slot=\"tabs-content\" className={cn('flex-1 outline-none', className)} {...props} />;\n}\n\nexport { Tabs, TabsContent, TabsList, TabsTrigger };\n"],"mappings":"yIAuBA,SAAS,EAAK,CAAE,YAAW,GAAG,GAA0D,CACtF,OAAO,EAACA,EAAc,KAAA,CAAK,YAAU,OAAO,UAAW,EAAG,sBAAuB,EAAU,CAAE,GAAI,GAAS,CAI5G,SAAS,EAAS,CAAE,YAAW,GAAG,GAA0D,CAC1F,OACE,EAACA,EAAc,KAAA,CACb,YAAU,YACV,UAAW,EAAG,0FAA2F,EAAU,CACnH,GAAI,GACJ,CAKN,SAAS,EAAY,CAAE,YAAW,GAAG,GAA6D,CAChG,OACE,EAACA,EAAc,QAAA,CACb,YAAU,eACV,UAAW,EACT,0BACA,oGACA,aACA,uFAEA,kCACA,oCACA,sBACA,+BACA,+BACA,uBACA,kCACA,0BACA,gCACA,8BACA,mBACA,uCACA,EACD,CACD,GAAI,GACJ,CAKN,SAAS,EAAY,CAAE,YAAW,GAAG,GAA6D,CAChG,OAAO,EAACA,EAAc,QAAA,CAAQ,YAAU,eAAe,UAAW,EAAG,sBAAuB,EAAU,CAAE,GAAI,GAAS"}
@@ -1 +0,0 @@
1
- "use client";import{t as e}from"../textarea-7HDXcaK9.mjs";export{e as Textarea};
@@ -1,2 +0,0 @@
1
- "use client";import{toggleVariants as e}from"./toggle.mjs";import{createContext as t,use as n}from"react";import{cn as r}from"@customafk/react-toolkit/utils";import{jsx as i}from"react/jsx-runtime";import{ToggleGroup as a}from"radix-ui";const o=t({size:`default`,variant:`default`});function s({className:e,variant:t,size:n,children:s,...c}){return i(a.Root,{"data-slot":`toggle-group`,"data-variant":t,"data-size":n,className:r(`group/toggle-group flex w-fit items-center rounded-md data-[variant=outline]:shadow-xs`,e),...c,children:i(o.Provider,{value:{variant:t,size:n},children:s})})}function c({className:t,children:s,variant:c,size:l,...u}){let d=n(o);return i(a.Item,{"data-slot":`toggle-group-item`,"data-variant":d.variant||c,"data-size":d.size||l,className:r(e({variant:d.variant||c,size:d.size||l}),`min-w-0 flex-1 shrink-0 rounded-none shadow-none first:rounded-l-md last:rounded-r-md focus:z-10 focus-visible:z-10 data-[variant=outline]:border-l-0 data-[variant=outline]:first:border-l`,t),...u,children:s})}export{s as ToggleGroup,c as ToggleGroupItem};
2
- //# sourceMappingURL=toggle-group.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"toggle-group.mjs","names":["ToggleGroupPrimitive"],"sources":["../../packages/components/ui/toggle-group.tsx"],"sourcesContent":["'use client';\nimport { createContext, use } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport type { VariantProps } from 'class-variance-authority';\nimport { ToggleGroup as ToggleGroupPrimitive } from 'radix-ui';\nimport { toggleVariants } from '@/components/ui/toggle';\n\nconst ToggleGroupContext = createContext<VariantProps<typeof toggleVariants>>({\n size: 'default',\n variant: 'default',\n});\n\n/**\n * A group of connected Toggle buttons where one or multiple items can be active at a time.\n *\n * @example\n * ```tsx\n * import { ToggleGroup, ToggleGroupItem } from '@customafk/lunas-ui/ui/toggle-group';\n *\n * <ToggleGroup type=\"single\" variant=\"outline\">\n * <ToggleGroupItem value=\"left\">Left</ToggleGroupItem>\n * <ToggleGroupItem value=\"center\">Center</ToggleGroupItem>\n * <ToggleGroupItem value=\"right\">Right</ToggleGroupItem>\n * </ToggleGroup>\n * ```\n */\nfunction ToggleGroup({\n className,\n variant,\n size,\n children,\n ...props\n}: React.ComponentProps<typeof ToggleGroupPrimitive.Root> & VariantProps<typeof toggleVariants>) {\n return (\n <ToggleGroupPrimitive.Root\n data-slot=\"toggle-group\"\n data-variant={variant}\n data-size={size}\n className={cn('group/toggle-group flex w-fit items-center rounded-md data-[variant=outline]:shadow-xs', className)}\n {...props}\n >\n <ToggleGroupContext.Provider value={{ variant, size }}>{children}</ToggleGroupContext.Provider>\n </ToggleGroupPrimitive.Root>\n );\n}\n\n/** A single item/button within a ToggleGroup that inherits the group's variant and size. */\nfunction ToggleGroupItem({\n className,\n children,\n variant,\n size,\n ...props\n}: React.ComponentProps<typeof ToggleGroupPrimitive.Item> & VariantProps<typeof toggleVariants>) {\n const context = use(ToggleGroupContext);\n\n return (\n <ToggleGroupPrimitive.Item\n data-slot=\"toggle-group-item\"\n data-variant={context.variant || variant}\n data-size={context.size || size}\n className={cn(\n toggleVariants({\n variant: context.variant || variant,\n size: context.size || size,\n }),\n 'min-w-0 flex-1 shrink-0 rounded-none shadow-none first:rounded-l-md last:rounded-r-md focus:z-10 focus-visible:z-10 data-[variant=outline]:border-l-0 data-[variant=outline]:first:border-l',\n className\n )}\n {...props}\n >\n {children}\n </ToggleGroupPrimitive.Item>\n );\n}\n\nexport { ToggleGroup, ToggleGroupItem };\n"],"mappings":"6OASA,MAAM,EAAqB,EAAmD,CAC5E,KAAM,UACN,QAAS,UACV,CAAC,CAgBF,SAAS,EAAY,CACnB,YACA,UACA,OACA,WACA,GAAG,GAC4F,CAC/F,OACE,EAACA,EAAqB,KAAA,CACpB,YAAU,eACV,eAAc,EACd,YAAW,EACX,UAAW,EAAG,yFAA0F,EAAU,CAClH,GAAI,WAEJ,EAAC,EAAmB,SAAA,CAAS,MAAO,CAAE,UAAS,OAAM,CAAG,YAAuC,EACrE,CAKhC,SAAS,EAAgB,CACvB,YACA,WACA,UACA,OACA,GAAG,GAC4F,CAC/F,IAAM,EAAU,EAAI,EAAmB,CAEvC,OACE,EAACA,EAAqB,KAAA,CACpB,YAAU,oBACV,eAAc,EAAQ,SAAW,EACjC,YAAW,EAAQ,MAAQ,EAC3B,UAAW,EACT,EAAe,CACb,QAAS,EAAQ,SAAW,EAC5B,KAAM,EAAQ,MAAQ,EACvB,CAAC,CACF,8LACA,EACD,CACD,GAAI,EAEH,YACyB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"toggle.mjs","names":["TogglePrimitive"],"sources":["../../packages/components/ui/toggle.tsx"],"sourcesContent":["'use client';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { Toggle as TogglePrimitive } from 'radix-ui';\n\nconst toggleVariants = cva(\n \"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none transition-[color,box-shadow] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive whitespace-nowrap\",\n {\n variants: {\n variant: {\n default: 'bg-transparent',\n outline: 'border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground',\n },\n size: {\n default: 'h-9 px-2 min-w-9',\n sm: 'h-8 px-1.5 min-w-8',\n lg: 'h-10 px-2.5 min-w-10',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n }\n);\n\n/**\n * A two-state button that switches between pressed (`on`) and unpressed (`off`).\n *\n * @example\n * ```tsx\n * import { Toggle } from '@customafk/lunas-ui/ui/toggle';\n * import { Bold } from 'lucide-react';\n *\n * <Toggle aria-label=\"Toggle bold\" variant=\"outline\">\n * <Bold />\n * </Toggle>\n * ```\n */\nfunction Toggle({ className, variant, size, ...props }: React.ComponentProps<typeof TogglePrimitive.Root> & VariantProps<typeof toggleVariants>) {\n return <TogglePrimitive.Root data-slot=\"toggle\" className={cn(toggleVariants({ variant, size, className }))} {...props} />;\n}\n\n// eslint-disable-next-line react-refresh/only-export-components\nexport { Toggle, toggleVariants };\n"],"mappings":"0LAMA,MAAM,EAAiB,EACrB,gjBACA,CACE,SAAU,CACR,QAAS,CACP,QAAS,iBACT,QAAS,4FACV,CACD,KAAM,CACJ,QAAS,mBACT,GAAI,qBACJ,GAAI,uBACL,CACF,CACD,gBAAiB,CACf,QAAS,UACT,KAAM,UACP,CACF,CACF,CAeD,SAAS,EAAO,CAAE,YAAW,UAAS,OAAM,GAAG,GAAkG,CAC/I,OAAO,EAACA,EAAgB,KAAA,CAAK,YAAU,SAAS,UAAW,EAAG,EAAe,CAAE,UAAS,OAAM,YAAW,CAAC,CAAC,CAAE,GAAI,GAAS"}
@@ -1 +0,0 @@
1
- "use client";import{i as e,n as t,r as n,t as r}from"../tooltip-Dxl5Wa8i.mjs";export{r as Tooltip,t as TooltipContent,n as TooltipProvider,e as TooltipTrigger};
@@ -1,2 +0,0 @@
1
- import{t as e}from"./paragraph-DYLaQtTV.mjs";import{t}from"./flex-B6YSJzGe.mjs";import{n,t as r}from"./avatar-fltdRVsJ.mjs";import{UserRoundIcon as i}from"lucide-react";import{jsx as a,jsxs as o}from"react/jsx-runtime";import{colorHashLight as s}from"@customafk/react-toolkit/color-hash";const c=({uuid:c,username:l,email:u})=>o(t,{"data-slot":`user-display`,wrap:!1,gap:`sm`,padding:`none`,children:[a(r,{className:`size-10 shadow-card`,children:a(n,{style:{backgroundColor:s.hex(c)},children:a(i,{size:28,className:`text-white`})})}),o(t,{vertical:!0,padding:`none`,gap:`none`,align:`start`,children:[a(e,{className:`text-sm font-medium text-text-positive`,children:l}),a(e,{variant:`sm`,className:`mt-0! text-xs text-text-positive-weak`,children:u})]})]});export{c as t};
2
- //# sourceMappingURL=user-DtZy4P9d.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"user-DtZy4P9d.mjs","names":["UserDataDisplay: React.FC<UserDataDisplayProps>"],"sources":["../packages/components/data-display/user.tsx"],"sourcesContent":["'use client';\n\nimport { UserRoundIcon } from 'lucide-react';\n\nimport { colorHashLight } from '@customafk/react-toolkit/color-hash';\n\nimport { Flex } from '../layouts/flex';\nimport { Paragraph } from '../typography/paragraph';\nimport { Avatar, AvatarFallback } from '../ui/avatar';\n\ntype UserDataDisplayProps = {\n /** Unique identifier used to deterministically generate the avatar background colour. */\n uuid: string;\n /** Display name rendered as the primary line of the user card. */\n username: string;\n /** Email address rendered as the secondary, muted line below the username. */\n email: string;\n};\n\n/**\n * Displays a user identity card with a colour-hashed avatar, username, and email address.\n *\n * @example\n * ```tsx\n * import { UserDataDisplay } from '@customafk/lunas-ui/data-display/user';\n *\n * <UserDataDisplay uuid=\"abc-123\" username=\"Nguyễn Văn An\" email=\"an@example.com\" />\n * ```\n */\nexport const UserDataDisplay: React.FC<UserDataDisplayProps> = ({ uuid, username, email }) => {\n return (\n <Flex data-slot=\"user-display\" wrap={false} gap=\"sm\" padding=\"none\">\n <Avatar className=\"size-10 shadow-card\">\n <AvatarFallback style={{ backgroundColor: colorHashLight.hex(uuid) }}>\n <UserRoundIcon size={28} className=\"text-white\" />\n </AvatarFallback>\n </Avatar>\n <Flex vertical padding=\"none\" gap=\"none\" align=\"start\">\n <Paragraph className=\"text-sm font-medium text-text-positive\">{username}</Paragraph>\n <Paragraph variant=\"sm\" className=\"mt-0! text-xs text-text-positive-weak\">\n {email}\n </Paragraph>\n </Flex>\n </Flex>\n );\n};\n"],"mappings":"gSA6BA,MAAaA,GAAmD,CAAE,OAAM,WAAU,WAE9E,EAAC,EAAA,CAAK,YAAU,eAAe,KAAM,GAAO,IAAI,KAAK,QAAQ,iBAC3D,EAAC,EAAA,CAAO,UAAU,+BAChB,EAAC,EAAA,CAAe,MAAO,CAAE,gBAAiB,EAAe,IAAI,EAAK,CAAE,UAClE,EAAC,EAAA,CAAc,KAAM,GAAI,UAAU,cAAe,EACnC,EACV,CACT,EAAC,EAAA,CAAK,SAAA,GAAS,QAAQ,OAAO,IAAI,OAAO,MAAM,kBAC7C,EAAC,EAAA,CAAU,UAAU,kDAA0C,GAAqB,CACpF,EAAC,EAAA,CAAU,QAAQ,KAAK,UAAU,iDAC/B,GACS,CAAA,EACP,CAAA,EACF"}