@customafk/lunas-ui 0.2.36 → 0.2.38

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 (523) hide show
  1. package/dist/{alert-DubR6Szk.cjs → alert-B2PaDJp6.cjs} +2 -2
  2. package/dist/{alert-DubR6Szk.cjs.map → alert-B2PaDJp6.cjs.map} +1 -1
  3. package/dist/{alert-ArM88PNb.d.cts → alert-C-bk-pne.d.mts} +7 -7
  4. package/dist/{alert-oiaUJxqr.d.mts → alert-DDxGzOzi.d.cts} +7 -7
  5. package/dist/{avatar-CqRl9dge.cjs → avatar-TyOphzGo.cjs} +2 -2
  6. package/dist/{avatar-CqRl9dge.cjs.map → avatar-TyOphzGo.cjs.map} +1 -1
  7. package/dist/{avatar-m1LjDIil.mjs → avatar-fltdRVsJ.mjs} +1 -1
  8. package/dist/{avatar-m1LjDIil.mjs.map → avatar-fltdRVsJ.mjs.map} +1 -1
  9. package/dist/{badge-Bhbhmsic.mjs → badge-CDGBGq8X.mjs} +1 -1
  10. package/dist/{badge-Bhbhmsic.mjs.map → badge-CDGBGq8X.mjs.map} +1 -1
  11. package/dist/{badge-D5Wq3XJq.d.cts → badge-IUtmECjN.d.cts} +5 -5
  12. package/dist/{badge-DMnKV_uW.cjs → badge-KW7xu5Ca.cjs} +2 -2
  13. package/dist/{badge-DMnKV_uW.cjs.map → badge-KW7xu5Ca.cjs.map} +1 -1
  14. package/dist/{badge-C9JgOJ5_.d.mts → badge-lvr8nB_0.d.mts} +5 -5
  15. package/dist/{button-CdROwJlN.d.cts → button-Brw-tmr9.d.cts} +6 -6
  16. package/dist/{button-Bu4ejNOW.cjs → button-C--DAN1D.cjs} +2 -2
  17. package/dist/button-C--DAN1D.cjs.map +1 -0
  18. package/dist/button-CCVJTHBI.mjs +2 -0
  19. package/dist/button-CCVJTHBI.mjs.map +1 -0
  20. package/dist/{button-CoySHVye.d.mts → button-DhDRMeFA.d.mts} +6 -6
  21. package/dist/{button.variants-tnhb123u.cjs → button.variants-4kw6plrv.cjs} +2 -2
  22. package/dist/{button.variants-tnhb123u.cjs.map → button.variants-4kw6plrv.cjs.map} +1 -1
  23. package/dist/{button.variants-B8aRZ52K.mjs → button.variants-DkMqWB8G.mjs} +1 -1
  24. package/dist/{button.variants-B8aRZ52K.mjs.map → button.variants-DkMqWB8G.mjs.map} +1 -1
  25. package/dist/{calendar-CMd11yg9.cjs → calendar-4weBDnXz.cjs} +2 -2
  26. package/dist/{calendar-CMd11yg9.cjs.map → calendar-4weBDnXz.cjs.map} +1 -1
  27. package/dist/{calendar-BDhIfwPP.mjs → calendar-R866yyd1.mjs} +2 -2
  28. package/dist/{calendar-BDhIfwPP.mjs.map → calendar-R866yyd1.mjs.map} +1 -1
  29. package/dist/cards/grid-product-card.cjs +1 -1
  30. package/dist/cards/grid-product-card.mjs +1 -1
  31. package/dist/cards/product-card.cjs +1 -1
  32. package/dist/cards/product-card.mjs +1 -1
  33. package/dist/cards/simple-card.cjs +1 -1
  34. package/dist/cards/simple-card.d.mts +2 -2
  35. package/dist/cards/simple-card.mjs +1 -1
  36. package/dist/{checkbox-CgHaRkuU.mjs → checkbox-Cat3i08X.mjs} +1 -1
  37. package/dist/{checkbox-CgHaRkuU.mjs.map → checkbox-Cat3i08X.mjs.map} +1 -1
  38. package/dist/{checkbox-BwDvS4De.cjs → checkbox-Dsq-MSbH.cjs} +2 -2
  39. package/dist/{checkbox-BwDvS4De.cjs.map → checkbox-Dsq-MSbH.cjs.map} +1 -1
  40. package/dist/chunk-350yNsax.cjs +1 -0
  41. package/dist/{close-DrCUWZt0.cjs → close-Dlo1bI8x.cjs} +2 -2
  42. package/dist/{close-DrCUWZt0.cjs.map → close-Dlo1bI8x.cjs.map} +1 -1
  43. package/dist/{close-B7OOMSZl.mjs → close-_UHFeiLS.mjs} +1 -1
  44. package/dist/{close-B7OOMSZl.mjs.map → close-_UHFeiLS.mjs.map} +1 -1
  45. package/dist/cms-layout-BCH4NroR.cjs +2 -0
  46. package/dist/cms-layout-BCH4NroR.cjs.map +1 -0
  47. package/dist/cms-layout-DkCR1AfG.mjs +2 -0
  48. package/dist/cms-layout-DkCR1AfG.mjs.map +1 -0
  49. package/dist/{command-DiXzSGc8.cjs → command-CsP8a1Un.cjs} +2 -2
  50. package/dist/{command-DiXzSGc8.cjs.map → command-CsP8a1Un.cjs.map} +1 -1
  51. package/dist/{command-FnbrPZ7_.mjs → command-D6_CSbwJ.mjs} +2 -2
  52. package/dist/{command-FnbrPZ7_.mjs.map → command-D6_CSbwJ.mjs.map} +1 -1
  53. package/dist/data-display/country.cjs +1 -1
  54. package/dist/data-display/country.mjs +1 -1
  55. package/dist/data-display/data-list.cjs +1 -1
  56. package/dist/data-display/date-tooltip.cjs +1 -1
  57. package/dist/data-display/date-tooltip.mjs +1 -1
  58. package/dist/data-display/date.cjs +1 -1
  59. package/dist/data-display/date.mjs +1 -1
  60. package/dist/data-display/empty.cjs +1 -1
  61. package/dist/data-display/name.cjs +1 -1
  62. package/dist/data-display/name.mjs +1 -1
  63. package/dist/data-display/phone-number.cjs +1 -1
  64. package/dist/data-display/phone-number.mjs +1 -1
  65. package/dist/data-display/role-badge.cjs +1 -1
  66. package/dist/data-display/role-badge.mjs +1 -1
  67. package/dist/data-display/statistic.cjs +1 -1
  68. package/dist/data-display/statistic.d.cts +3 -3
  69. package/dist/data-display/statistic.d.mts +3 -3
  70. package/dist/data-display/statistic.mjs +1 -1
  71. package/dist/data-display/user.cjs +1 -1
  72. package/dist/data-display/user.mjs +1 -1
  73. package/dist/{date-DtajzNoy.cjs → date-D4NVl6C9.cjs} +2 -2
  74. package/dist/{date-DtajzNoy.cjs.map → date-D4NVl6C9.cjs.map} +1 -1
  75. package/dist/{date-CFgc7pK3.mjs → date-fY3sUcLp.mjs} +1 -1
  76. package/dist/{date-CFgc7pK3.mjs.map → date-fY3sUcLp.mjs.map} +1 -1
  77. package/dist/{dialog-D1sWnn6n.cjs → dialog-BigPrWIj.cjs} +2 -2
  78. package/dist/{dialog-D1sWnn6n.cjs.map → dialog-BigPrWIj.cjs.map} +1 -1
  79. package/dist/{dialog-EGFZeITu.mjs → dialog-CLDnvNH_.mjs} +2 -2
  80. package/dist/{dialog-EGFZeITu.mjs.map → dialog-CLDnvNH_.mjs.map} +1 -1
  81. package/dist/{dialog-BYzcewOe.d.cts → dialog-CsltUGHB.d.mts} +12 -12
  82. package/dist/{dialog-DYhbRnya.d.mts → dialog-D0zfwr8i.d.cts} +12 -12
  83. package/dist/dialogs/confirm-dialog.cjs +1 -1
  84. package/dist/dialogs/confirm-dialog.cjs.map +1 -1
  85. package/dist/dialogs/confirm-dialog.mjs +1 -1
  86. package/dist/dialogs/confirm-dialog.mjs.map +1 -1
  87. package/dist/dialogs/detail-dialog/components/sidebar.cjs +1 -1
  88. package/dist/dialogs/detail-dialog/components/sidebar.d.cts +25 -25
  89. package/dist/dialogs/detail-dialog/components/sidebar.d.mts +27 -27
  90. package/dist/dialogs/detail-dialog/components/sidebar.mjs +1 -1
  91. package/dist/dialogs/detail-dialog/index.cjs +1 -1
  92. package/dist/dialogs/detail-dialog/index.mjs +1 -1
  93. package/dist/dialogs/error-dialog.cjs +1 -1
  94. package/dist/dialogs/error-dialog.mjs +1 -1
  95. package/dist/dialogs/loading-dialog.cjs +1 -1
  96. package/dist/dialogs/loading-dialog.mjs +1 -1
  97. package/dist/dist-Cx5ufCdr.cjs +2 -0
  98. package/dist/{dist-CAeolvAH.cjs.map → dist-Cx5ufCdr.cjs.map} +1 -1
  99. package/dist/dist-DVrfqn8H.mjs +2 -0
  100. package/dist/{dist-BQGL-YKY.mjs.map → dist-DVrfqn8H.mjs.map} +1 -1
  101. package/dist/{drawer-B6C8-Ndu.cjs → drawer-BB8BZzDG.cjs} +2 -2
  102. package/dist/{drawer-B6C8-Ndu.cjs.map → drawer-BB8BZzDG.cjs.map} +1 -1
  103. package/dist/{dropdown-menu-C6tRSumY.mjs → dropdown-menu-BWhiVsEf.mjs} +1 -1
  104. package/dist/{dropdown-menu-C6tRSumY.mjs.map → dropdown-menu-BWhiVsEf.mjs.map} +1 -1
  105. package/dist/{dropdown-menu-Bz7oMQ36.cjs → dropdown-menu-CVh520yG.cjs} +2 -2
  106. package/dist/{dropdown-menu-Bz7oMQ36.cjs.map → dropdown-menu-CVh520yG.cjs.map} +1 -1
  107. package/dist/features/descriptions/index.cjs +1 -1
  108. package/dist/features/descriptions/index.cjs.map +1 -1
  109. package/dist/features/descriptions/index.d.cts +3 -3
  110. package/dist/features/descriptions/index.d.mts +6 -6
  111. package/dist/features/descriptions/index.mjs +1 -1
  112. package/dist/features/descriptions/index.mjs.map +1 -1
  113. package/dist/features/search-modal/index.cjs +1 -1
  114. package/dist/features/search-modal/index.d.cts +2 -2
  115. package/dist/features/search-modal/index.d.mts +2 -2
  116. package/dist/features/search-modal/index.mjs +1 -1
  117. package/dist/features/tables/index.cjs +1 -1
  118. package/dist/features/tables/index.d.cts +2 -2
  119. package/dist/features/tables/index.d.mts +3 -3
  120. package/dist/features/tables/index.mjs +1 -1
  121. package/dist/features/tanstack-form/index.cjs +1 -1
  122. package/dist/features/tanstack-form/index.d.cts +2 -2
  123. package/dist/features/tanstack-form/index.d.mts +2 -2
  124. package/dist/features/tanstack-form/index.mjs +1 -1
  125. package/dist/features/text-editor/index.cjs +1 -1
  126. package/dist/features/text-editor/index.d.cts +1 -1
  127. package/dist/features/text-editor/index.d.mts +1 -1
  128. package/dist/features/text-editor/index.mjs +1 -1
  129. package/dist/{field-pfL7RWcN.cjs → field-BrlETeXX.cjs} +2 -2
  130. package/dist/{field-pfL7RWcN.cjs.map → field-BrlETeXX.cjs.map} +1 -1
  131. package/dist/{field-DhgAIueI.mjs → field-dYemS0hQ.mjs} +2 -2
  132. package/dist/{field-DhgAIueI.mjs.map → field-dYemS0hQ.mjs.map} +1 -1
  133. package/dist/{flex-BAcvp4lB.mjs → flex-B6YSJzGe.mjs} +1 -1
  134. package/dist/{flex-BAcvp4lB.mjs.map → flex-B6YSJzGe.mjs.map} +1 -1
  135. package/dist/{flex-DYh2t8ft.cjs → flex-DmWmOBn5.cjs} +2 -2
  136. package/dist/{flex-DYh2t8ft.cjs.map → flex-DmWmOBn5.cjs.map} +1 -1
  137. package/dist/{heading-woRh-IC7.mjs → heading-De4Pn3mZ.mjs} +1 -1
  138. package/dist/{heading-woRh-IC7.mjs.map → heading-De4Pn3mZ.mjs.map} +1 -1
  139. package/dist/{heading-wUXEbicM.cjs → heading-tGTqk3pA.cjs} +2 -2
  140. package/dist/{heading-wUXEbicM.cjs.map → heading-tGTqk3pA.cjs.map} +1 -1
  141. package/dist/image-D7OZ13Ib.mjs +2 -0
  142. package/dist/{image-D2U1SBw5.mjs.map → image-D7OZ13Ib.mjs.map} +1 -1
  143. package/dist/image-W_Yb0xTB.cjs +2 -0
  144. package/dist/{image-Y7gCz7uE.cjs.map → image-W_Yb0xTB.cjs.map} +1 -1
  145. package/dist/{index-DuRmheOp.d.cts → index-9eog5ilY.d.cts} +64 -32
  146. package/dist/{index-CEUx5VIo.d.mts → index-BuNzvvj3.d.mts} +64 -32
  147. package/dist/{index-DMSKIqbL.d.cts → index-CG8iS6qj.d.cts} +15 -15
  148. package/dist/index-Cm62M0Ft.d.mts +90 -0
  149. package/dist/{index-ByhKmerO.d.mts → index-DI8qmezw.d.mts} +15 -15
  150. package/dist/index-DsD83ZN8.d.cts +2348 -0
  151. package/dist/index-KO98y6L0.d.cts +90 -0
  152. package/dist/index-SMYnpHIM.d.mts +2348 -0
  153. package/dist/index.cjs +1 -1
  154. package/dist/index.d.cts +10 -10
  155. package/dist/index.d.mts +10 -10
  156. package/dist/index.mjs +1 -1
  157. package/dist/{input-DHt0MAKf.d.cts → input-BFtFMzRG.d.mts} +6 -6
  158. package/dist/{input-DLqmDeEo.d.mts → input-DvkEND5a.d.cts} +6 -6
  159. package/dist/{input-5gk-Jv1y.mjs → input-NJP2wQOm.mjs} +1 -1
  160. package/dist/{input-5gk-Jv1y.mjs.map → input-NJP2wQOm.mjs.map} +1 -1
  161. package/dist/{input-BvzsfAUc.cjs → input-WJ0DLHTR.cjs} +2 -2
  162. package/dist/{input-BvzsfAUc.cjs.map → input-WJ0DLHTR.cjs.map} +1 -1
  163. package/dist/{label-eIyGIRyw.cjs → label-CC6fXVbC.cjs} +2 -2
  164. package/dist/{label-eIyGIRyw.cjs.map → label-CC6fXVbC.cjs.map} +1 -1
  165. package/dist/{label-D9uNQ9b_.mjs → label-CUCpwS5D.mjs} +1 -1
  166. package/dist/{label-D9uNQ9b_.mjs.map → label-CUCpwS5D.mjs.map} +1 -1
  167. package/dist/layouts/cms-layout/index.cjs +1 -1
  168. package/dist/layouts/cms-layout/index.d.cts +2 -76
  169. package/dist/layouts/cms-layout/index.d.mts +2 -76
  170. package/dist/layouts/cms-layout/index.mjs +1 -1
  171. package/dist/layouts/flex.cjs +1 -1
  172. package/dist/layouts/flex.d.cts +8 -8
  173. package/dist/layouts/flex.d.mts +8 -8
  174. package/dist/layouts/flex.mjs +1 -1
  175. package/dist/layouts/grid.cjs +1 -1
  176. package/dist/layouts/payment-layout/index.cjs +1 -1
  177. package/dist/layouts/payment-layout/index.mjs +1 -1
  178. package/dist/pages/FeatureDeveloping.cjs +1 -1
  179. package/dist/pages/FeatureDeveloping.d.cts +2 -2
  180. package/dist/pages/FeatureDeveloping.d.mts +2 -2
  181. package/dist/pages/FeatureDeveloping.mjs +1 -1
  182. package/dist/pages/FeatureFixing.cjs +1 -1
  183. package/dist/pages/FeatureFixing.d.cts +2 -2
  184. package/dist/pages/FeatureFixing.mjs +1 -1
  185. package/dist/pages/LoginPage.cjs +1 -1
  186. package/dist/pages/LoginPage.cjs.map +1 -1
  187. package/dist/pages/LoginPage.d.cts +2 -2
  188. package/dist/pages/LoginPage.d.mts +2 -2
  189. package/dist/pages/LoginPage.mjs +1 -1
  190. package/dist/pages/LoginPage.mjs.map +1 -1
  191. package/dist/pages/NotAuthorized.cjs +1 -1
  192. package/dist/pages/NotAuthorized.d.cts +2 -2
  193. package/dist/pages/NotAuthorized.d.mts +2 -2
  194. package/dist/pages/NotAuthorized.mjs +1 -1
  195. package/dist/pages/NotFound.cjs +1 -1
  196. package/dist/pages/NotFound.d.cts +2 -2
  197. package/dist/pages/NotFound.d.mts +2 -2
  198. package/dist/pages/NotFound.mjs +1 -1
  199. package/dist/pages/RegisterPage.cjs +1 -1
  200. package/dist/pages/RegisterPage.cjs.map +1 -1
  201. package/dist/pages/RegisterPage.d.cts +2 -2
  202. package/dist/pages/RegisterPage.d.mts +2 -2
  203. package/dist/pages/RegisterPage.mjs +1 -1
  204. package/dist/pages/RegisterPage.mjs.map +1 -1
  205. package/dist/pages/VerifyEmailPage.cjs +1 -1
  206. package/dist/pages/VerifyEmailPage.d.cts +2 -2
  207. package/dist/pages/VerifyEmailPage.d.mts +2 -2
  208. package/dist/pages/VerifyEmailPage.mjs +1 -1
  209. package/dist/{paragraph-CjstaJFj.mjs → paragraph-DYLaQtTV.mjs} +1 -1
  210. package/dist/{paragraph-CjstaJFj.mjs.map → paragraph-DYLaQtTV.mjs.map} +1 -1
  211. package/dist/{paragraph-D-JHj7EP.cjs → paragraph-DvTZvbzw.cjs} +2 -2
  212. package/dist/{paragraph-D-JHj7EP.cjs.map → paragraph-DvTZvbzw.cjs.map} +1 -1
  213. package/dist/{payment-layout-_ZM4uBy_.mjs → payment-layout-DrQ0kZPX.mjs} +2 -2
  214. package/dist/{payment-layout-_ZM4uBy_.mjs.map → payment-layout-DrQ0kZPX.mjs.map} +1 -1
  215. package/dist/{payment-layout-fsYTkw3r.cjs → payment-layout-DyILfyVG.cjs} +2 -2
  216. package/dist/{payment-layout-fsYTkw3r.cjs.map → payment-layout-DyILfyVG.cjs.map} +1 -1
  217. package/dist/{popover-DwgdOX8a.mjs → popover-C8rcemA3.mjs} +2 -2
  218. package/dist/{popover-DwgdOX8a.mjs.map → popover-C8rcemA3.mjs.map} +1 -1
  219. package/dist/{popover-fsTCOb6a.cjs → popover-DBsC8Ltp.cjs} +2 -2
  220. package/dist/{popover-fsTCOb6a.cjs.map → popover-DBsC8Ltp.cjs.map} +1 -1
  221. package/dist/{progress-DCBKnTx0.mjs → progress-CLeM0e7Z.mjs} +1 -1
  222. package/dist/{progress-DCBKnTx0.mjs.map → progress-CLeM0e7Z.mjs.map} +1 -1
  223. package/dist/{progress-CDYA2V-W.cjs → progress-gvBqNiHp.cjs} +2 -2
  224. package/dist/{progress-CDYA2V-W.cjs.map → progress-gvBqNiHp.cjs.map} +1 -1
  225. package/dist/{radio-group-B-M599Ys.cjs → radio-group-_TdMkv8w.cjs} +2 -2
  226. package/dist/{radio-group-B-M599Ys.cjs.map → radio-group-_TdMkv8w.cjs.map} +1 -1
  227. package/dist/{resizable-DP1BQAF_.mjs → resizable-CpCaSCFB.mjs} +1 -1
  228. package/dist/{resizable-DP1BQAF_.mjs.map → resizable-CpCaSCFB.mjs.map} +1 -1
  229. package/dist/{resizable-DATSh0Du.cjs → resizable-sgpaHAb8.cjs} +2 -2
  230. package/dist/{resizable-DATSh0Du.cjs.map → resizable-sgpaHAb8.cjs.map} +1 -1
  231. package/dist/{search-modal-CYRJEDE-.cjs → search-modal-B-pzGcfP.cjs} +2 -2
  232. package/dist/{search-modal-CYRJEDE-.cjs.map → search-modal-B-pzGcfP.cjs.map} +1 -1
  233. package/dist/{search-modal-DWu08xkE.mjs → search-modal-Bn-GOOCy.mjs} +2 -2
  234. package/dist/{search-modal-DWu08xkE.mjs.map → search-modal-Bn-GOOCy.mjs.map} +1 -1
  235. package/dist/select-CWLQHh8x.cjs +2 -0
  236. package/dist/select-CWLQHh8x.cjs.map +1 -0
  237. package/dist/{select-BAlA65tZ.mjs → select-LlPCZFSF.mjs} +2 -2
  238. package/dist/select-LlPCZFSF.mjs.map +1 -0
  239. package/dist/{separator-C6s-YvlT.mjs → separator-D3Gmkxzq.mjs} +1 -1
  240. package/dist/{separator-C6s-YvlT.mjs.map → separator-D3Gmkxzq.mjs.map} +1 -1
  241. package/dist/{separator-CBup_ah1.cjs → separator-KuymG9g0.cjs} +2 -2
  242. package/dist/{separator-CBup_ah1.cjs.map → separator-KuymG9g0.cjs.map} +1 -1
  243. package/dist/{sheet-Cj8hoftE.mjs → sheet-BFlIfNaA.mjs} +1 -1
  244. package/dist/{sheet-Cj8hoftE.mjs.map → sheet-BFlIfNaA.mjs.map} +1 -1
  245. package/dist/{sheet-DAjZ-Q6Q.cjs → sheet-CvKSi0UC.cjs} +2 -2
  246. package/dist/{sheet-DAjZ-Q6Q.cjs.map → sheet-CvKSi0UC.cjs.map} +1 -1
  247. package/dist/{sidebar-RcmDh50_.mjs → sidebar-ChtCyu-n.mjs} +2 -2
  248. package/dist/{sidebar-RcmDh50_.mjs.map → sidebar-ChtCyu-n.mjs.map} +1 -1
  249. package/dist/{sidebar-Drasn0Bx.cjs → sidebar-D5J2gcTw.cjs} +2 -2
  250. package/dist/{sidebar-Drasn0Bx.cjs.map → sidebar-D5J2gcTw.cjs.map} +1 -1
  251. package/dist/{skeleton-DupQ91XW.mjs → skeleton-C51IdOfK.mjs} +1 -1
  252. package/dist/{skeleton-DupQ91XW.mjs.map → skeleton-C51IdOfK.mjs.map} +1 -1
  253. package/dist/{skeleton-CHympz8k.cjs → skeleton-CX1USu1w.cjs} +2 -2
  254. package/dist/{skeleton-CHympz8k.cjs.map → skeleton-CX1USu1w.cjs.map} +1 -1
  255. package/dist/{spinner-Bdta7BMp.cjs → spinner-CFxorYEt.cjs} +2 -2
  256. package/dist/{spinner-Bdta7BMp.cjs.map → spinner-CFxorYEt.cjs.map} +1 -1
  257. package/dist/{spinner-BCnPYF1H.mjs → spinner-eClTgHjk.mjs} +1 -1
  258. package/dist/{spinner-BCnPYF1H.mjs.map → spinner-eClTgHjk.mjs.map} +1 -1
  259. package/dist/{statistic-DDDm5Om1.cjs → statistic-DDXilD7q.cjs} +2 -2
  260. package/dist/{statistic-DDDm5Om1.cjs.map → statistic-DDXilD7q.cjs.map} +1 -1
  261. package/dist/{statistic-Cm4nbkjQ.mjs → statistic-cwLwcukn.mjs} +1 -1
  262. package/dist/{statistic-Cm4nbkjQ.mjs.map → statistic-cwLwcukn.mjs.map} +1 -1
  263. package/dist/{switch-Dbc77c_D.cjs → switch-DVfOV7wP.cjs} +2 -2
  264. package/dist/{switch-Dbc77c_D.cjs.map → switch-DVfOV7wP.cjs.map} +1 -1
  265. package/dist/systems/google.cjs +1 -1
  266. package/dist/tables-CFrsk2lM.mjs +4 -0
  267. package/dist/tables-CFrsk2lM.mjs.map +1 -0
  268. package/dist/tables-CPKHe3k-.cjs +4 -0
  269. package/dist/tables-CPKHe3k-.cjs.map +1 -0
  270. package/dist/tanstack-form-DT1TqIDl.mjs +12 -0
  271. package/dist/tanstack-form-DT1TqIDl.mjs.map +1 -0
  272. package/dist/tanstack-form-DatI41wz.cjs +12 -0
  273. package/dist/tanstack-form-DatI41wz.cjs.map +1 -0
  274. package/dist/text-editor-5mA7XyaI.mjs +2 -0
  275. package/dist/text-editor-5mA7XyaI.mjs.map +1 -0
  276. package/dist/text-editor-CvJN3nSL.cjs +2 -0
  277. package/dist/text-editor-CvJN3nSL.cjs.map +1 -0
  278. package/dist/{textarea-Byo8E8oi.cjs → textarea-Cc9CF8wD.cjs} +2 -2
  279. package/dist/{textarea-Byo8E8oi.cjs.map → textarea-Cc9CF8wD.cjs.map} +1 -1
  280. package/dist/{tooltip-DC6i1A25.cjs → tooltip-CBdoIzoM.cjs} +2 -2
  281. package/dist/{tooltip-DC6i1A25.cjs.map → tooltip-CBdoIzoM.cjs.map} +1 -1
  282. package/dist/{tooltip-BfBJRYpc.mjs → tooltip-Dxl5Wa8i.mjs} +1 -1
  283. package/dist/{tooltip-BfBJRYpc.mjs.map → tooltip-Dxl5Wa8i.mjs.map} +1 -1
  284. package/dist/{types-CFXgrpTm.mjs → types-B5nyTWtO.mjs} +1 -1
  285. package/dist/{types-CFXgrpTm.mjs.map → types-B5nyTWtO.mjs.map} +1 -1
  286. package/dist/typography/paragraph.cjs +1 -1
  287. package/dist/typography/paragraph.d.cts +4 -4
  288. package/dist/typography/paragraph.d.mts +4 -4
  289. package/dist/typography/paragraph.mjs +1 -1
  290. package/dist/typography/title.cjs +1 -1
  291. package/dist/ui/alert-dialog.cjs +1 -1
  292. package/dist/ui/alert-dialog.d.cts +12 -12
  293. package/dist/ui/alert-dialog.d.mts +12 -12
  294. package/dist/ui/alert-dialog.mjs +1 -1
  295. package/dist/ui/alert.cjs +1 -1
  296. package/dist/ui/alert.d.cts +1 -1
  297. package/dist/ui/alert.d.mts +1 -1
  298. package/dist/ui/aspect-ratio.cjs +1 -1
  299. package/dist/ui/aspect-ratio.d.cts +2 -2
  300. package/dist/ui/aspect-ratio.d.mts +2 -2
  301. package/dist/ui/avatar.cjs +1 -1
  302. package/dist/ui/avatar.d.cts +4 -4
  303. package/dist/ui/avatar.d.mts +4 -4
  304. package/dist/ui/avatar.mjs +1 -1
  305. package/dist/ui/badge.cjs +1 -1
  306. package/dist/ui/badge.d.cts +1 -1
  307. package/dist/ui/badge.d.mts +1 -1
  308. package/dist/ui/badge.mjs +1 -1
  309. package/dist/ui/breadcrumb.cjs +1 -1
  310. package/dist/ui/breadcrumb.d.cts +8 -8
  311. package/dist/ui/breadcrumb.d.mts +8 -8
  312. package/dist/ui/breadcrumb.mjs +1 -1
  313. package/dist/ui/button-group.cjs +1 -1
  314. package/dist/ui/button-group.d.cts +7 -7
  315. package/dist/ui/button-group.d.mts +7 -7
  316. package/dist/ui/button-group.mjs +1 -1
  317. package/dist/ui/button.cjs +1 -1
  318. package/dist/ui/button.d.cts +1 -1
  319. package/dist/ui/button.d.mts +1 -1
  320. package/dist/ui/button.mjs +1 -1
  321. package/dist/ui/buttons/add-new.cjs +1 -1
  322. package/dist/ui/buttons/add-new.mjs +1 -1
  323. package/dist/ui/buttons/edit.cjs +1 -1
  324. package/dist/ui/buttons/edit.mjs +1 -1
  325. package/dist/ui/buttons/refresh.cjs +1 -1
  326. package/dist/ui/buttons/refresh.mjs +1 -1
  327. package/dist/ui/buttons/trash.cjs +1 -1
  328. package/dist/ui/buttons/trash.mjs +1 -1
  329. package/dist/ui/buttons/upload-image.cjs +1 -1
  330. package/dist/ui/buttons/upload-image.mjs +1 -1
  331. package/dist/ui/calendar.cjs +1 -1
  332. package/dist/ui/calendar.d.cts +4 -4
  333. package/dist/ui/calendar.d.mts +4 -4
  334. package/dist/ui/calendar.mjs +1 -1
  335. package/dist/ui/card.cjs +1 -1
  336. package/dist/ui/card.d.cts +8 -8
  337. package/dist/ui/card.d.mts +8 -8
  338. package/dist/ui/card.mjs +1 -1
  339. package/dist/ui/carousel.cjs +1 -1
  340. package/dist/ui/carousel.d.cts +7 -7
  341. package/dist/ui/carousel.d.mts +7 -7
  342. package/dist/ui/carousel.mjs +1 -1
  343. package/dist/ui/checkbox.cjs +1 -1
  344. package/dist/ui/checkbox.d.cts +2 -2
  345. package/dist/ui/checkbox.d.mts +2 -2
  346. package/dist/ui/checkbox.mjs +1 -1
  347. package/dist/ui/collapsible.cjs +1 -1
  348. package/dist/ui/collapsible.d.cts +4 -4
  349. package/dist/ui/collapsible.d.mts +4 -4
  350. package/dist/ui/command.cjs +1 -1
  351. package/dist/ui/command.d.cts +11 -11
  352. package/dist/ui/command.d.mts +11 -11
  353. package/dist/ui/command.mjs +1 -1
  354. package/dist/ui/context-menu.cjs +1 -1
  355. package/dist/ui/context-menu.d.cts +16 -16
  356. package/dist/ui/context-menu.d.mts +16 -16
  357. package/dist/ui/dialog.cjs +1 -1
  358. package/dist/ui/dialog.d.cts +1 -1
  359. package/dist/ui/dialog.d.mts +1 -1
  360. package/dist/ui/dialog.mjs +1 -1
  361. package/dist/ui/drawer.cjs +1 -1
  362. package/dist/ui/drawer.d.cts +11 -11
  363. package/dist/ui/drawer.d.mts +11 -11
  364. package/dist/ui/dropdown-menu.cjs +1 -1
  365. package/dist/ui/dropdown-menu.d.cts +16 -16
  366. package/dist/ui/dropdown-menu.d.mts +16 -16
  367. package/dist/ui/dropdown-menu.mjs +1 -1
  368. package/dist/ui/empty.cjs +1 -1
  369. package/dist/ui/empty.d.cts +9 -9
  370. package/dist/ui/empty.d.mts +9 -9
  371. package/dist/ui/field.cjs +1 -1
  372. package/dist/ui/field.d.cts +24 -24
  373. package/dist/ui/field.d.mts +24 -24
  374. package/dist/ui/field.mjs +1 -1
  375. package/dist/ui/file-uploader.cjs +1 -1
  376. package/dist/ui/file-uploader.d.cts +2 -2
  377. package/dist/ui/file-uploader.mjs +1 -1
  378. package/dist/ui/form.cjs +1 -1
  379. package/dist/ui/form.d.cts +10 -10
  380. package/dist/ui/form.d.mts +10 -10
  381. package/dist/ui/form.mjs +1 -1
  382. package/dist/ui/hover-card.cjs +1 -1
  383. package/dist/ui/hover-card.d.cts +4 -4
  384. package/dist/ui/hover-card.d.mts +4 -4
  385. package/dist/ui/image.cjs +1 -1
  386. package/dist/ui/image.mjs +1 -1
  387. package/dist/ui/input-otp.cjs +1 -1
  388. package/dist/ui/input-otp.d.cts +5 -5
  389. package/dist/ui/input-otp.d.mts +5 -5
  390. package/dist/ui/input.cjs +1 -1
  391. package/dist/ui/input.d.cts +1 -1
  392. package/dist/ui/input.d.mts +1 -1
  393. package/dist/ui/input.mjs +1 -1
  394. package/dist/ui/inputs/search-input.cjs +1 -1
  395. package/dist/ui/inputs/search-input.d.cts +3 -3
  396. package/dist/ui/inputs/search-input.d.mts +3 -3
  397. package/dist/ui/inputs/search-input.mjs +1 -1
  398. package/dist/ui/item.cjs +1 -1
  399. package/dist/ui/item.d.cts +16 -16
  400. package/dist/ui/item.d.mts +16 -16
  401. package/dist/ui/item.mjs +1 -1
  402. package/dist/ui/label.cjs +1 -1
  403. package/dist/ui/label.d.cts +2 -2
  404. package/dist/ui/label.d.mts +2 -2
  405. package/dist/ui/label.mjs +1 -1
  406. package/dist/ui/menubar.cjs +1 -1
  407. package/dist/ui/menubar.d.cts +17 -17
  408. package/dist/ui/menubar.d.mts +17 -17
  409. package/dist/ui/multi-select.cjs +1 -1
  410. package/dist/ui/multi-select.d.cts +2 -2
  411. package/dist/ui/multi-select.d.mts +3 -3
  412. package/dist/ui/multi-select.mjs +1 -1
  413. package/dist/ui/navigation-menu.cjs +1 -1
  414. package/dist/ui/navigation-menu.d.cts +11 -11
  415. package/dist/ui/navigation-menu.d.mts +11 -11
  416. package/dist/ui/pagination.cjs +1 -1
  417. package/dist/ui/pagination.d.cts +9 -9
  418. package/dist/ui/pagination.d.mts +9 -9
  419. package/dist/ui/pagination.mjs +1 -1
  420. package/dist/ui/popover.cjs +1 -1
  421. package/dist/ui/popover.d.cts +6 -6
  422. package/dist/ui/popover.d.mts +6 -6
  423. package/dist/ui/popover.mjs +1 -1
  424. package/dist/ui/progress.cjs +1 -1
  425. package/dist/ui/progress.d.cts +2 -2
  426. package/dist/ui/progress.d.mts +2 -2
  427. package/dist/ui/progress.mjs +1 -1
  428. package/dist/ui/radio-group.cjs +1 -1
  429. package/dist/ui/radio-group.d.cts +3 -3
  430. package/dist/ui/radio-group.d.mts +3 -3
  431. package/dist/ui/resizable.cjs +1 -1
  432. package/dist/ui/resizable.d.cts +9 -9
  433. package/dist/ui/resizable.d.mts +9 -9
  434. package/dist/ui/resizable.mjs +1 -1
  435. package/dist/ui/scroll-area.cjs +1 -1
  436. package/dist/ui/scroll-area.d.cts +5 -5
  437. package/dist/ui/scroll-area.d.mts +5 -5
  438. package/dist/ui/select.cjs +1 -1
  439. package/dist/ui/select.d.cts +9 -9
  440. package/dist/ui/select.d.mts +9 -9
  441. package/dist/ui/select.mjs +1 -1
  442. package/dist/ui/separator.cjs +1 -1
  443. package/dist/ui/separator.d.cts +2 -2
  444. package/dist/ui/separator.d.mts +2 -2
  445. package/dist/ui/separator.mjs +1 -1
  446. package/dist/ui/sheet.cjs +1 -1
  447. package/dist/ui/sheet.d.cts +9 -9
  448. package/dist/ui/sheet.d.mts +9 -9
  449. package/dist/ui/sheet.mjs +1 -1
  450. package/dist/ui/skeleton.cjs +1 -1
  451. package/dist/ui/skeleton.d.cts +2 -2
  452. package/dist/ui/skeleton.d.mts +2 -2
  453. package/dist/ui/skeleton.mjs +1 -1
  454. package/dist/ui/slider.cjs +1 -1
  455. package/dist/ui/slider.d.cts +2 -2
  456. package/dist/ui/slider.d.mts +2 -2
  457. package/dist/ui/sonner.cjs +1 -1
  458. package/dist/ui/sonner.cjs.map +1 -1
  459. package/dist/ui/sonner.d.cts +2 -2
  460. package/dist/ui/sonner.d.mts +2 -2
  461. package/dist/ui/sonner.mjs +1 -1
  462. package/dist/ui/sonner.mjs.map +1 -1
  463. package/dist/ui/spinner.cjs +1 -1
  464. package/dist/ui/spinner.d.cts +2 -2
  465. package/dist/ui/spinner.d.mts +2 -2
  466. package/dist/ui/spinner.mjs +1 -1
  467. package/dist/ui/switch.cjs +1 -1
  468. package/dist/ui/switch.d.cts +2 -2
  469. package/dist/ui/switch.d.mts +2 -2
  470. package/dist/ui/table.cjs +1 -1
  471. package/dist/ui/table.d.cts +17 -17
  472. package/dist/ui/table.d.mts +17 -17
  473. package/dist/ui/tabs.cjs +1 -1
  474. package/dist/ui/tabs.d.cts +5 -5
  475. package/dist/ui/tabs.d.mts +5 -5
  476. package/dist/ui/textarea.cjs +1 -1
  477. package/dist/ui/textarea.d.cts +2 -2
  478. package/dist/ui/textarea.d.mts +2 -2
  479. package/dist/ui/toggle-group.cjs +1 -1
  480. package/dist/ui/toggle-group.d.cts +3 -3
  481. package/dist/ui/toggle-group.d.mts +3 -3
  482. package/dist/ui/toggle.cjs +1 -1
  483. package/dist/ui/toggle.d.cts +5 -5
  484. package/dist/ui/toggle.d.mts +5 -5
  485. package/dist/ui/tooltip.cjs +1 -1
  486. package/dist/ui/tooltip.d.cts +5 -5
  487. package/dist/ui/tooltip.d.mts +5 -5
  488. package/dist/ui/tooltip.mjs +1 -1
  489. package/dist/{user-D8Skw8dI.mjs → user-DtZy4P9d.mjs} +2 -2
  490. package/dist/{user-D8Skw8dI.mjs.map → user-DtZy4P9d.mjs.map} +1 -1
  491. package/dist/{user-Dns1BKaT.cjs → user-ii4FBhO1.cjs} +2 -2
  492. package/dist/{user-Dns1BKaT.cjs.map → user-ii4FBhO1.cjs.map} +1 -1
  493. package/package.json +20 -5
  494. package/styles/spacing.css +186 -0
  495. package/dist/button-Bu4ejNOW.cjs.map +0 -1
  496. package/dist/button-CfPTDyoq.mjs +0 -2
  497. package/dist/button-CfPTDyoq.mjs.map +0 -1
  498. package/dist/chunk-Bmb41Sf3.cjs +0 -1
  499. package/dist/cms-layout-BrubV8D8.cjs +0 -2
  500. package/dist/cms-layout-BrubV8D8.cjs.map +0 -1
  501. package/dist/cms-layout-C2-yysO2.mjs +0 -2
  502. package/dist/cms-layout-C2-yysO2.mjs.map +0 -1
  503. package/dist/dist-BQGL-YKY.mjs +0 -2
  504. package/dist/dist-CAeolvAH.cjs +0 -2
  505. package/dist/image-D2U1SBw5.mjs +0 -2
  506. package/dist/image-Y7gCz7uE.cjs +0 -2
  507. package/dist/index-CL3z9hOc.d.cts +0 -2749
  508. package/dist/index-CuvfEKgg.d.mts +0 -2749
  509. package/dist/select-BAlA65tZ.mjs.map +0 -1
  510. package/dist/select-Cib2aiw5.cjs +0 -2
  511. package/dist/select-Cib2aiw5.cjs.map +0 -1
  512. package/dist/tables-B3Ald6An.cjs +0 -4
  513. package/dist/tables-B3Ald6An.cjs.map +0 -1
  514. package/dist/tables-C3asiSD4.mjs +0 -4
  515. package/dist/tables-C3asiSD4.mjs.map +0 -1
  516. package/dist/tanstack-form-CYcb_gLQ.cjs +0 -2
  517. package/dist/tanstack-form-CYcb_gLQ.cjs.map +0 -1
  518. package/dist/tanstack-form-DQFyDxOg.mjs +0 -2
  519. package/dist/tanstack-form-DQFyDxOg.mjs.map +0 -1
  520. package/dist/text-editor-DqyiYNen.cjs +0 -2
  521. package/dist/text-editor-DqyiYNen.cjs.map +0 -1
  522. package/dist/text-editor-HGUUElOS.mjs +0 -2
  523. package/dist/text-editor-HGUUElOS.mjs.map +0 -1
@@ -1,2 +1,2 @@
1
- const e=require(`./chunk-Bmb41Sf3.cjs`),t=require(`./paragraph-D-JHj7EP.cjs`),n=require(`./flex-DYh2t8ft.cjs`),r=require(`./avatar-CqRl9dge.cjs`);let i=require(`lucide-react`),a=require(`react/jsx-runtime`),o=require(`@customafk/react-toolkit/color-hash`);const s=({uuid:e,username:s,email:c})=>(0,a.jsxs)(n.t,{"data-slot":`user-display`,wrap:!1,gap:`sm`,padding:`none`,children:[(0,a.jsx)(r.t,{className:`size-10 shadow-card`,children:(0,a.jsx)(r.n,{style:{backgroundColor:o.colorHashLight.hex(e)},children:(0,a.jsx)(i.UserRoundIcon,{size:28,className:`text-white`})})}),(0,a.jsxs)(n.t,{vertical:!0,padding:`none`,gap:`none`,align:`start`,children:[(0,a.jsx)(t.t,{className:`text-sm font-medium text-text-positive`,children:s}),(0,a.jsx)(t.t,{variant:`sm`,className:`mt-0! text-xs text-text-positive-weak`,children:c})]})]});Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return s}});
2
- //# sourceMappingURL=user-Dns1BKaT.cjs.map
1
+ const e=require(`./chunk-350yNsax.cjs`),t=require(`./paragraph-DvTZvbzw.cjs`),n=require(`./flex-DmWmOBn5.cjs`),r=require(`./avatar-TyOphzGo.cjs`);let i=require(`lucide-react`),a=require(`react/jsx-runtime`),o=require(`@customafk/react-toolkit/color-hash`);const s=({uuid:e,username:s,email:c})=>(0,a.jsxs)(n.t,{"data-slot":`user-display`,wrap:!1,gap:`sm`,padding:`none`,children:[(0,a.jsx)(r.t,{className:`size-10 shadow-card`,children:(0,a.jsx)(r.n,{style:{backgroundColor:o.colorHashLight.hex(e)},children:(0,a.jsx)(i.UserRoundIcon,{size:28,className:`text-white`})})}),(0,a.jsxs)(n.t,{vertical:!0,padding:`none`,gap:`none`,align:`start`,children:[(0,a.jsx)(t.t,{className:`text-sm font-medium text-text-positive`,children:s}),(0,a.jsx)(t.t,{variant:`sm`,className:`mt-0! text-xs text-text-positive-weak`,children:c})]})]});Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return s}});
2
+ //# sourceMappingURL=user-ii4FBhO1.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"user-Dns1BKaT.cjs","names":["UserDataDisplay: React.FC<UserDataDisplayProps>","Flex","Avatar","AvatarFallback","colorHashLight","UserRoundIcon","Paragraph"],"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":"gQA6BA,MAAaA,GAAmD,CAAE,OAAM,WAAU,YAE9E,EAAA,EAAA,MAACC,EAAAA,EAAAA,CAAK,YAAU,eAAe,KAAM,GAAO,IAAI,KAAK,QAAQ,kBAC3D,EAAA,EAAA,KAACC,EAAAA,EAAAA,CAAO,UAAU,gCAChB,EAAA,EAAA,KAACC,EAAAA,EAAAA,CAAe,MAAO,CAAE,gBAAiBC,EAAAA,eAAe,IAAI,EAAK,CAAE,WAClE,EAAA,EAAA,KAACC,EAAAA,cAAAA,CAAc,KAAM,GAAI,UAAU,cAAe,EACnC,EACV,EACT,EAAA,EAAA,MAACJ,EAAAA,EAAAA,CAAK,SAAA,GAAS,QAAQ,OAAO,IAAI,OAAO,MAAM,mBAC7C,EAAA,EAAA,KAACK,EAAAA,EAAAA,CAAU,UAAU,kDAA0C,GAAqB,EACpF,EAAA,EAAA,KAACA,EAAAA,EAAAA,CAAU,QAAQ,KAAK,UAAU,iDAC/B,GACS,CAAA,EACP,CAAA,EACF"}
1
+ {"version":3,"file":"user-ii4FBhO1.cjs","names":["UserDataDisplay: React.FC<UserDataDisplayProps>","Flex","Avatar","AvatarFallback","colorHashLight","UserRoundIcon","Paragraph"],"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":"gQA6BA,MAAaA,GAAmD,CAAE,OAAM,WAAU,YAE9E,EAAA,EAAA,MAACC,EAAAA,EAAAA,CAAK,YAAU,eAAe,KAAM,GAAO,IAAI,KAAK,QAAQ,kBAC3D,EAAA,EAAA,KAACC,EAAAA,EAAAA,CAAO,UAAU,gCAChB,EAAA,EAAA,KAACC,EAAAA,EAAAA,CAAe,MAAO,CAAE,gBAAiBC,EAAAA,eAAe,IAAI,EAAK,CAAE,WAClE,EAAA,EAAA,KAACC,EAAAA,cAAAA,CAAc,KAAM,GAAI,UAAU,cAAe,EACnC,EACV,EACT,EAAA,EAAA,MAACJ,EAAAA,EAAAA,CAAK,SAAA,GAAS,QAAQ,OAAO,IAAI,OAAO,MAAM,mBAC7C,EAAA,EAAA,KAACK,EAAAA,EAAAA,CAAU,UAAU,kDAA0C,GAAqB,EACpF,EAAA,EAAA,KAACA,EAAAA,EAAAA,CAAU,QAAQ,KAAK,UAAU,iDAC/B,GACS,CAAA,EACP,CAAA,EACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@customafk/lunas-ui",
3
- "version": "0.2.36",
3
+ "version": "0.2.38",
4
4
  "description": "UI library for Lunas Enterprise",
5
5
  "type": "module",
6
6
  "author": {
@@ -423,7 +423,11 @@
423
423
  "format": "npx @biomejs/biome format",
424
424
  "format:fix": "npx @biomejs/biome format --write",
425
425
  "storybook": "storybook dev -p 6006",
426
- "build-storybook": "storybook build"
426
+ "build-storybook": "storybook build",
427
+ "test": "vitest run",
428
+ "test:watch": "vitest",
429
+ "test:coverage": "vitest run --coverage",
430
+ "test:storybook": "vitest --config vitest.storybook.config.ts"
427
431
  },
428
432
  "peerDependencies": {
429
433
  "@customafk/react-toolkit": "0.0.19",
@@ -459,7 +463,7 @@
459
463
  "lucide-react": "^0.545.0",
460
464
  "nanoid": "^5.1.6",
461
465
  "next-themes": "^0.4.6",
462
- "radix-ui": "^1.4.0",
466
+ "radix-ui": "^1.6.0",
463
467
  "react": "^19.2.0",
464
468
  "react-country-flag": "^3.1.0",
465
469
  "react-day-picker": "^9.9.0",
@@ -481,15 +485,26 @@
481
485
  "@storybook/addon-mcp": "^0.6.0",
482
486
  "@storybook/addon-onboarding": "^10.1.0",
483
487
  "@storybook/addon-themes": "^10.1.0",
488
+ "@storybook/addon-vitest": "^10.4.6",
484
489
  "@storybook/react-vite": "^10.1.0",
490
+ "@testing-library/dom": "^10.4.1",
491
+ "@testing-library/jest-dom": "^6.9.1",
492
+ "@testing-library/react": "^16.3.2",
493
+ "@testing-library/user-event": "^14.6.1",
494
+ "@types/node": "^26.0.0",
485
495
  "@types/react": "*",
486
496
  "@types/react-dom": "*",
487
- "@vitejs/plugin-react": "^4.4.1",
497
+ "@vitejs/plugin-react": "^6.0.2",
498
+ "@vitest/browser": "^4.1.9",
499
+ "@vitest/browser-playwright": "^4.1.9",
500
+ "@vitest/coverage-v8": "^4.1.9",
501
+ "jsdom": "^26.1.0",
502
+ "playwright": "^1.61.0",
488
503
  "tsdown": "^0.18.0",
489
504
  "typescript": "^5.8.3",
490
505
  "typescript-eslint": "^8.30.1",
491
506
  "unplugin-lightningcss": "^0.4.2",
492
- "vite": "^6.3.5",
507
+ "vite": "^8.0.16",
493
508
  "vitest": "^4.1.8"
494
509
  },
495
510
  "main": "./dist/index.cjs",
@@ -0,0 +1,186 @@
1
+ /**
2
+ * spacing.css — Three-scale responsive spacing system
3
+ *
4
+ * ─────────────────────────────────────────────────────────────
5
+ * THE THREE SCALES
6
+ * ─────────────────────────────────────────────────────────────
7
+ *
8
+ * Pick the scale based on what sits on either side of the gap:
9
+ *
10
+ * layout — gaps between large page regions (sections, page gutters,
11
+ * hero-to-content, sidebar-to-main). The things on either
12
+ * side are full-width zones.
13
+ *
14
+ * section — gaps inside a section (header-to-body, card stacks,
15
+ * grouped rows, list items). The things on either side are
16
+ * content blocks within a zone.
17
+ *
18
+ * component — internal padding and gaps of a single UI component
19
+ * (button, chip, input, badge, tag). The things on either
20
+ * side are parts of one atomic element.
21
+ *
22
+ * Rule of thumb: the bigger the things on either side, the higher the
23
+ * scale. A gap between two full sections is `layout`. A gap between two
24
+ * lines of text inside a card is `component`.
25
+ *
26
+ * ─────────────────────────────────────────────────────────────
27
+ * BREAKPOINTS (mobile-first)
28
+ * ─────────────────────────────────────────────────────────────
29
+ *
30
+ * mobile — default (no media query), < 768px
31
+ * tablet — @media (min-width: 768px) → Tailwind `md:`
32
+ * desktop — @media (min-width: 1024px) → Tailwind `lg:`
33
+ *
34
+ * ─────────────────────────────────────────────────────────────
35
+ * NAMING CONVENTION
36
+ * ─────────────────────────────────────────────────────────────
37
+ *
38
+ * --spacing-{scale}-{size}
39
+ *
40
+ * Scales : layout | section | component
41
+ * Sizes : xl | lg | md | sm | xs | none
42
+ *
43
+ * ─────────────────────────────────────────────────────────────
44
+ * HOW TO USE
45
+ * ─────────────────────────────────────────────────────────────
46
+ *
47
+ * In CSS / inline styles:
48
+ *
49
+ * gap: var(--spacing-layout-md);
50
+ * padding: var(--spacing-section-lg);
51
+ * padding-inline: var(--spacing-component-sm);
52
+ *
53
+ * In Tailwind (via arbitrary value):
54
+ *
55
+ * class="gap-[var(--spacing-layout-md)]"
56
+ * class="p-[var(--spacing-section-lg)]"
57
+ *
58
+ * The CSS variable automatically resolves to the correct pixel value
59
+ * for the current viewport, so no responsive prefix is needed.
60
+ *
61
+ * ─────────────────────────────────────────────────────────────
62
+ * IMPORT ORDER (for consumers)
63
+ * ─────────────────────────────────────────────────────────────
64
+ *
65
+ * @import 'styles/base.css';
66
+ * @import 'styles/theme.css';
67
+ * @import 'styles/spacing.css'; ← here
68
+ * @import 'styles/typography.css'; (optional)
69
+ */
70
+
71
+ /* ─────────────────────────────────────────────────────────────
72
+ BASE VALUES — mobile (< 768px)
73
+ ───────────────────────────────────────────────────────────── */
74
+ :root {
75
+ /* ── Layout scale ──────────────────────────────────────────
76
+ * Page-level spacing: gaps between sections, page gutters.
77
+ * Use when spacing two full-width page regions apart.
78
+ *
79
+ * Token Mobile Tablet Desktop
80
+ * --spacing-layout-xl 48px 64px 128px
81
+ * --spacing-layout-lg 32px 48px 96px
82
+ * --spacing-layout-md 16px 32px 64px
83
+ * --spacing-layout-sm 12px 24px 48px
84
+ * --spacing-layout-xs 8px 16px 32px
85
+ * --spacing-layout-none 0 0 0
86
+ */
87
+ --spacing-layout-xl: 48px;
88
+ --spacing-layout-lg: 32px;
89
+ --spacing-layout-md: 16px;
90
+ --spacing-layout-sm: 12px;
91
+ --spacing-layout-xs: 8px;
92
+ --spacing-layout-none: 0;
93
+
94
+ /* ── Section scale ─────────────────────────────────────────
95
+ * Section-level spacing: header-to-body, card stacks,
96
+ * grouped rows, list items within a section.
97
+ *
98
+ * Token Mobile Tablet Desktop
99
+ * --spacing-section-xl 20px 32px 48px
100
+ * --spacing-section-lg 16px 20px 32px
101
+ * --spacing-section-md 12px 16px 24px
102
+ * --spacing-section-sm 12px 16px 16px
103
+ * --spacing-section-xs 8px 12px 12px
104
+ * --spacing-section-none 0 0 0
105
+ */
106
+ --spacing-section-xl: 20px;
107
+ --spacing-section-lg: 16px;
108
+ --spacing-section-md: 12px;
109
+ --spacing-section-sm: 12px;
110
+ --spacing-section-xs: 8px;
111
+ --spacing-section-none: 0;
112
+
113
+ /* ── Component scale ───────────────────────────────────────
114
+ * Component-internal spacing: padding and gaps inside a
115
+ * single UI element (button, chip, input, badge).
116
+ *
117
+ * Token Mobile Tablet Desktop
118
+ * --spacing-component-xl 12px 16px 24px
119
+ * --spacing-component-lg 12px 16px 16px
120
+ * --spacing-component-md 8px 12px 12px
121
+ * --spacing-component-sm 8px FLAT FLAT ← same at all sizes
122
+ * --spacing-component-xs 4px FLAT FLAT ← same at all sizes
123
+ * --spacing-component-none 0 0 0
124
+ *
125
+ * Note: component-sm and component-xs are intentionally flat.
126
+ * Tight internal spacing reads the same across all viewports.
127
+ */
128
+ --spacing-component-xl: 12px;
129
+ --spacing-component-lg: 12px;
130
+ --spacing-component-md: 8px;
131
+ --spacing-component-sm: 8px;
132
+ --spacing-component-xs: 4px;
133
+ --spacing-component-none: 0;
134
+ }
135
+
136
+ /* ─────────────────────────────────────────────────────────────
137
+ TABLET — 768px+ (Tailwind `md:`)
138
+ ───────────────────────────────────────────────────────────── */
139
+ @media (min-width: 768px) {
140
+ :root {
141
+ /* Layout */
142
+ --spacing-layout-xl: 64px;
143
+ --spacing-layout-lg: 48px;
144
+ --spacing-layout-md: 32px;
145
+ --spacing-layout-sm: 24px;
146
+ --spacing-layout-xs: 16px;
147
+
148
+ /* Section */
149
+ --spacing-section-xl: 32px;
150
+ --spacing-section-lg: 20px;
151
+ --spacing-section-md: 16px;
152
+ --spacing-section-sm: 16px;
153
+ --spacing-section-xs: 12px;
154
+
155
+ /* Component (xl / lg / md scale up; sm and xs stay flat) */
156
+ --spacing-component-xl: 16px;
157
+ --spacing-component-lg: 16px;
158
+ --spacing-component-md: 12px;
159
+ }
160
+ }
161
+
162
+ /* ─────────────────────────────────────────────────────────────
163
+ DESKTOP — 1024px+ (Tailwind `lg:`)
164
+ ───────────────────────────────────────────────────────────── */
165
+ @media (min-width: 1024px) {
166
+ :root {
167
+ /* Layout */
168
+ --spacing-layout-xl: 128px;
169
+ --spacing-layout-lg: 96px;
170
+ --spacing-layout-md: 64px;
171
+ --spacing-layout-sm: 48px;
172
+ --spacing-layout-xs: 32px;
173
+
174
+ /* Section */
175
+ --spacing-section-xl: 48px;
176
+ --spacing-section-lg: 32px;
177
+ --spacing-section-md: 24px;
178
+ --spacing-section-sm: 16px;
179
+ --spacing-section-xs: 12px;
180
+
181
+ /* Component (xl / lg / md scale up; sm and xs stay flat) */
182
+ --spacing-component-xl: 24px;
183
+ --spacing-component-lg: 16px;
184
+ --spacing-component-md: 12px;
185
+ }
186
+ }
@@ -1 +0,0 @@
1
- {"version":3,"file":"button-Bu4ejNOW.cjs","names":["Slot","buttonVariants","buttonLoadingVariant","Loader2Icon"],"sources":["../packages/components/ui/button.tsx"],"sourcesContent":["'use client';\n\nimport { Loader2Icon } from 'lucide-react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { cn } from '@customafk/react-toolkit/utils';\nimport { type ButtonVariantProps, buttonLoadingVariant, buttonVariants } from './button.variants';\n\n/**\n * Props for the {@link Button} component.\n *\n * Extends all native `<button>` attributes except `color`, which is\n * re-declared as a semantic design-token via {@link ButtonVariantProps}.\n *\n * @see {@link https://www.radix-ui.com/primitives/docs/utilities/slot} Radix Slot (asChild pattern)\n */\nexport interface ButtonProps extends Omit<React.ComponentProps<'button'>, 'color'> {\n /**\n * When `true`, renders children through Radix's `<Slot>` primitive,\n * merging all button props directly onto the child element.\n *\n * Use this to swap the rendered HTML element while keeping button styling\n * (e.g. render a Next.js `<Link>` that looks like a button).\n *\n * @default false\n * @example\n * ```tsx\n * <Button asChild variant=\"ghost\">\n * <Link href=\"/dashboard\">Go to Dashboard</Link>\n * </Button>\n * ```\n */\n asChild?: boolean;\n\n /**\n * When `true`, shows an animated `Loader2` spinner overlay and sets\n * `aria-busy=\"true\"`. The button is implicitly disabled while loading —\n * no separate `disabled` prop is needed for loading states.\n *\n * @default false\n */\n isLoading?: boolean;\n\n /**\n * Visual style variant of the button.\n *\n * | Value | Description |\n * |---|---|\n * | `\"default\"` | Filled surface — primary call-to-action (default) |\n * | `\"outline\"` | Transparent background with a visible border |\n * | `\"ghost\"` | No background or border — minimal footprint |\n * | `\"link\"` | Styled as an underlined hyperlink |\n * | `\"icon\"` | Square, padding-free — icon-only buttons |\n * | `\"destructive\"` | Red-toned filled surface for danger actions |\n *\n * @default \"default\"\n */\n variant?: ButtonVariantProps['variant'];\n\n /**\n * Semantic color token applied to the button's surface and text.\n *\n * | Value | Usage |\n * |---|---|\n * | `\"primary\"` | Brand primary (default) |\n * | `\"success\"` | Confirmation / save actions |\n * | `\"danger\"` | Destructive / delete actions |\n * | `\"warning\"` | Cautionary / irreversible actions |\n * | `\"muted\"` | Secondary / low-emphasis actions |\n *\n * @default \"primary\"\n */\n color?: ButtonVariantProps['color'];\n\n /**\n * Controls height, horizontal padding, and font size.\n *\n * | Value | Height |\n * |---|---|\n * | `\"sm\"` | 32 px |\n * | `\"default\"` | 36 px |\n * | `\"lg\"` | 40 px |\n * | `\"icon\"` | 36 × 36 px (square) |\n *\n * @default \"default\"\n */\n size?: ButtonVariantProps['size'];\n\n /**\n * Additional class names applied to the inner `<div>` that wraps `children`.\n * Use this to style the children's flex container without overriding the\n * button's outer layout or focus-ring classes.\n */\n innerClassName?: string;\n}\n\n/**\n * Primary interactive button component for `@customafk/lunas-ui`.\n *\n * Built on Radix UI's `<Slot>` primitive. Supports multiple visual variants,\n * semantic color tokens, a built-in loading state with full accessibility\n * attributes, and polymorphic rendering via `asChild`. All native `<button>`\n * attributes are forwarded to the underlying element.\n *\n * **Import:** `import { Button } from '@customafk/lunas-ui/ui/button'`\n *\n * @example Basic usage\n * ```tsx\n * import { Button } from '@customafk/lunas-ui/ui/button';\n *\n * export function SaveAction() {\n * return <Button color=\"primary\">Save changes</Button>;\n * }\n * ```\n *\n * @example Async loading state\n * ```tsx\n * import { Button } from '@customafk/lunas-ui/ui/button';\n *\n * export function SubmitButton({ isPending }: { isPending: boolean }) {\n * return (\n * <Button type=\"submit\" isLoading={isPending}>\n * Submit\n * </Button>\n * );\n * }\n * ```\n *\n * @example Destructive outline button\n * ```tsx\n * import { Button } from '@customafk/lunas-ui/ui/button';\n *\n * export function DeleteButton({ onDelete }: { onDelete: () => void }) {\n * return (\n * <Button variant=\"outline\" color=\"danger\" onClick={onDelete}>\n * Delete account\n * </Button>\n * );\n * }\n * ```\n *\n * @example Polymorphic — render as Next.js Link\n * ```tsx\n * import { Button } from '@customafk/lunas-ui/ui/button';\n * import Link from 'next/link';\n *\n * export function NavLink() {\n * return (\n * <Button asChild variant=\"ghost\" size=\"sm\">\n * <Link href=\"/settings\">Settings</Link>\n * </Button>\n * );\n * }\n * ```\n */\nfunction Button({\n className,\n variant,\n size = 'default',\n color,\n asChild = false,\n isLoading = false,\n children,\n disabled,\n type = 'button',\n innerClassName,\n ...props\n}: ButtonProps) {\n const Comp = asChild ? Slot : 'button';\n const isDisabled = disabled || isLoading;\n\n return (\n <Comp\n {...(!asChild ? { type, disabled: isDisabled } : undefined)}\n data-slot=\"button\"\n data-state={isLoading ? 'loading' : undefined}\n aria-disabled={isDisabled ? true : undefined}\n aria-busy={isLoading ? true : undefined}\n className={cn(\n buttonVariants({\n variant,\n size,\n color,\n className,\n })\n )}\n {...props}\n >\n {isLoading && (\n <div className={buttonLoadingVariant({ variant, color })}>\n <Loader2Icon size={16} className=\"animate-spin\" />\n <span className=\"sr-only\">Loading</span>\n </div>\n )}\n <div className={cn('inline-flex items-center justify-center gap-x-1', isLoading && 'invisible pointer-events-none', innerClassName)}>{children}</div>\n </Comp>\n );\n}\n\nexport { Button };\n"],"mappings":"8NA0JA,SAAS,EAAO,CACd,YACA,UACA,OAAO,UACP,QACA,UAAU,GACV,YAAY,GACZ,WACA,WACA,OAAO,SACP,iBACA,GAAG,GACW,CACd,IAAM,EAAO,EAAUA,EAAAA,EAAO,SACxB,EAAa,GAAY,EAE/B,OACE,EAAA,EAAA,MAAC,EAAA,CACC,GAAM,EAA2C,IAAA,GAAjC,CAAE,OAAM,SAAU,EAAY,CAC9C,YAAU,SACV,aAAY,EAAY,UAAY,IAAA,GACpC,gBAAe,EAAa,GAAO,IAAA,GACnC,YAAW,EAAY,GAAO,IAAA,GAC9B,WAAA,EAAA,EAAA,IACEC,EAAAA,EAAe,CACb,UACA,OACA,QACA,YACD,CAAC,CACH,CACD,GAAI,YAEH,IACC,EAAA,EAAA,MAAC,MAAA,CAAI,UAAWC,EAAAA,EAAqB,CAAE,UAAS,QAAO,CAAC,YACtD,EAAA,EAAA,KAACC,EAAAA,YAAAA,CAAY,KAAM,GAAI,UAAU,gBAAiB,EAClD,EAAA,EAAA,KAAC,OAAA,CAAK,UAAU,mBAAU,WAAc,CAAA,EACpC,EAER,EAAA,EAAA,KAAC,MAAA,CAAI,WAAA,EAAA,EAAA,IAAc,kDAAmD,GAAa,gCAAiC,EAAe,CAAG,YAAe,CAAA,EAChJ"}
@@ -1,2 +0,0 @@
1
- import{t as e}from"./dist-BQGL-YKY.mjs";import{n as t,t as n}from"./button.variants-B8aRZ52K.mjs";import{Loader2Icon 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:s,variant:c,size:l=`default`,color:u,asChild:d=!1,isLoading:f=!1,children:p,disabled:m,type:h=`button`,innerClassName:g,..._}){let v=d?e:`button`,y=m||f;return o(v,{...d?void 0:{type:h,disabled:y},"data-slot":`button`,"data-state":f?`loading`:void 0,"aria-disabled":y?!0:void 0,"aria-busy":f?!0:void 0,className:i(t({variant:c,size:l,color:u,className:s})),..._,children:[f&&o(`div`,{className:n({variant:c,color:u}),children:[a(r,{size:16,className:`animate-spin`}),a(`span`,{className:`sr-only`,children:`Loading`})]}),a(`div`,{className:i(`inline-flex items-center justify-center gap-x-1`,f&&`invisible pointer-events-none`,g),children:p})]})}export{s as t};
2
- //# sourceMappingURL=button-CfPTDyoq.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"button-CfPTDyoq.mjs","names":[],"sources":["../packages/components/ui/button.tsx"],"sourcesContent":["'use client';\n\nimport { Loader2Icon } from 'lucide-react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { cn } from '@customafk/react-toolkit/utils';\nimport { type ButtonVariantProps, buttonLoadingVariant, buttonVariants } from './button.variants';\n\n/**\n * Props for the {@link Button} component.\n *\n * Extends all native `<button>` attributes except `color`, which is\n * re-declared as a semantic design-token via {@link ButtonVariantProps}.\n *\n * @see {@link https://www.radix-ui.com/primitives/docs/utilities/slot} Radix Slot (asChild pattern)\n */\nexport interface ButtonProps extends Omit<React.ComponentProps<'button'>, 'color'> {\n /**\n * When `true`, renders children through Radix's `<Slot>` primitive,\n * merging all button props directly onto the child element.\n *\n * Use this to swap the rendered HTML element while keeping button styling\n * (e.g. render a Next.js `<Link>` that looks like a button).\n *\n * @default false\n * @example\n * ```tsx\n * <Button asChild variant=\"ghost\">\n * <Link href=\"/dashboard\">Go to Dashboard</Link>\n * </Button>\n * ```\n */\n asChild?: boolean;\n\n /**\n * When `true`, shows an animated `Loader2` spinner overlay and sets\n * `aria-busy=\"true\"`. The button is implicitly disabled while loading —\n * no separate `disabled` prop is needed for loading states.\n *\n * @default false\n */\n isLoading?: boolean;\n\n /**\n * Visual style variant of the button.\n *\n * | Value | Description |\n * |---|---|\n * | `\"default\"` | Filled surface — primary call-to-action (default) |\n * | `\"outline\"` | Transparent background with a visible border |\n * | `\"ghost\"` | No background or border — minimal footprint |\n * | `\"link\"` | Styled as an underlined hyperlink |\n * | `\"icon\"` | Square, padding-free — icon-only buttons |\n * | `\"destructive\"` | Red-toned filled surface for danger actions |\n *\n * @default \"default\"\n */\n variant?: ButtonVariantProps['variant'];\n\n /**\n * Semantic color token applied to the button's surface and text.\n *\n * | Value | Usage |\n * |---|---|\n * | `\"primary\"` | Brand primary (default) |\n * | `\"success\"` | Confirmation / save actions |\n * | `\"danger\"` | Destructive / delete actions |\n * | `\"warning\"` | Cautionary / irreversible actions |\n * | `\"muted\"` | Secondary / low-emphasis actions |\n *\n * @default \"primary\"\n */\n color?: ButtonVariantProps['color'];\n\n /**\n * Controls height, horizontal padding, and font size.\n *\n * | Value | Height |\n * |---|---|\n * | `\"sm\"` | 32 px |\n * | `\"default\"` | 36 px |\n * | `\"lg\"` | 40 px |\n * | `\"icon\"` | 36 × 36 px (square) |\n *\n * @default \"default\"\n */\n size?: ButtonVariantProps['size'];\n\n /**\n * Additional class names applied to the inner `<div>` that wraps `children`.\n * Use this to style the children's flex container without overriding the\n * button's outer layout or focus-ring classes.\n */\n innerClassName?: string;\n}\n\n/**\n * Primary interactive button component for `@customafk/lunas-ui`.\n *\n * Built on Radix UI's `<Slot>` primitive. Supports multiple visual variants,\n * semantic color tokens, a built-in loading state with full accessibility\n * attributes, and polymorphic rendering via `asChild`. All native `<button>`\n * attributes are forwarded to the underlying element.\n *\n * **Import:** `import { Button } from '@customafk/lunas-ui/ui/button'`\n *\n * @example Basic usage\n * ```tsx\n * import { Button } from '@customafk/lunas-ui/ui/button';\n *\n * export function SaveAction() {\n * return <Button color=\"primary\">Save changes</Button>;\n * }\n * ```\n *\n * @example Async loading state\n * ```tsx\n * import { Button } from '@customafk/lunas-ui/ui/button';\n *\n * export function SubmitButton({ isPending }: { isPending: boolean }) {\n * return (\n * <Button type=\"submit\" isLoading={isPending}>\n * Submit\n * </Button>\n * );\n * }\n * ```\n *\n * @example Destructive outline button\n * ```tsx\n * import { Button } from '@customafk/lunas-ui/ui/button';\n *\n * export function DeleteButton({ onDelete }: { onDelete: () => void }) {\n * return (\n * <Button variant=\"outline\" color=\"danger\" onClick={onDelete}>\n * Delete account\n * </Button>\n * );\n * }\n * ```\n *\n * @example Polymorphic — render as Next.js Link\n * ```tsx\n * import { Button } from '@customafk/lunas-ui/ui/button';\n * import Link from 'next/link';\n *\n * export function NavLink() {\n * return (\n * <Button asChild variant=\"ghost\" size=\"sm\">\n * <Link href=\"/settings\">Settings</Link>\n * </Button>\n * );\n * }\n * ```\n */\nfunction Button({\n className,\n variant,\n size = 'default',\n color,\n asChild = false,\n isLoading = false,\n children,\n disabled,\n type = 'button',\n innerClassName,\n ...props\n}: ButtonProps) {\n const Comp = asChild ? Slot : 'button';\n const isDisabled = disabled || isLoading;\n\n return (\n <Comp\n {...(!asChild ? { type, disabled: isDisabled } : undefined)}\n data-slot=\"button\"\n data-state={isLoading ? 'loading' : undefined}\n aria-disabled={isDisabled ? true : undefined}\n aria-busy={isLoading ? true : undefined}\n className={cn(\n buttonVariants({\n variant,\n size,\n color,\n className,\n })\n )}\n {...props}\n >\n {isLoading && (\n <div className={buttonLoadingVariant({ variant, color })}>\n <Loader2Icon size={16} className=\"animate-spin\" />\n <span className=\"sr-only\">Loading</span>\n </div>\n )}\n <div className={cn('inline-flex items-center justify-center gap-x-1', isLoading && 'invisible pointer-events-none', innerClassName)}>{children}</div>\n </Comp>\n );\n}\n\nexport { Button };\n"],"mappings":"mPA0JA,SAAS,EAAO,CACd,YACA,UACA,OAAO,UACP,QACA,UAAU,GACV,YAAY,GACZ,WACA,WACA,OAAO,SACP,iBACA,GAAG,GACW,CACd,IAAM,EAAO,EAAU,EAAO,SACxB,EAAa,GAAY,EAE/B,OACE,EAAC,EAAA,CACC,GAAM,EAA2C,IAAA,GAAjC,CAAE,OAAM,SAAU,EAAY,CAC9C,YAAU,SACV,aAAY,EAAY,UAAY,IAAA,GACpC,gBAAe,EAAa,GAAO,IAAA,GACnC,YAAW,EAAY,GAAO,IAAA,GAC9B,UAAW,EACT,EAAe,CACb,UACA,OACA,QACA,YACD,CAAC,CACH,CACD,GAAI,YAEH,GACC,EAAC,MAAA,CAAI,UAAW,EAAqB,CAAE,UAAS,QAAO,CAAC,WACtD,EAAC,EAAA,CAAY,KAAM,GAAI,UAAU,gBAAiB,CAClD,EAAC,OAAA,CAAK,UAAU,mBAAU,WAAc,CAAA,EACpC,CAER,EAAC,MAAA,CAAI,UAAW,EAAG,kDAAmD,GAAa,gCAAiC,EAAe,CAAG,YAAe,CAAA,EAChJ"}
@@ -1 +0,0 @@
1
- var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return s}});
@@ -1,2 +0,0 @@
1
- const e=require(`./chunk-Bmb41Sf3.cjs`),t=require(`./dist-CAeolvAH.cjs`),n=require(`./button-Bu4ejNOW.cjs`),r=require(`./tooltip-DC6i1A25.cjs`),i=require(`./separator-CBup_ah1.cjs`),a=require(`./sheet-DAjZ-Q6Q.cjs`),o=require(`./dropdown-menu-Bz7oMQ36.cjs`),s=require(`./input-BvzsfAUc.cjs`);let c=require(`lucide-react`),l=require(`react`),u=require(`@customafk/react-toolkit/utils`),d=require(`class-variance-authority`),f=require(`react/jsx-runtime`),p=require(`@customafk/react-toolkit/hooks/useMobile`);const m=`sidebar_state`,h=3600*24*7,g=`16rem`,_=`18rem`,v=`3rem`,y=`b`,b=(0,l.createContext)(null);function x(){let e=(0,l.useContext)(b);if(!e)throw Error(`useSidebar must be used within a SidebarProvider.`);return e}function S({defaultOpen:e=!0,open:t,onOpenChange:n,className:i,style:a,children:o,...s}){let c=(0,p.useIsMobile)(),[d,m]=(0,l.useState)(!1),[h,g]=(0,l.useState)(e),_=t??h,v=(0,l.useCallback)(e=>{let t=typeof e==`function`?e(_):e;n?n(t):g(t),document.cookie=`sidebar_state=${t}; path=/; max-age=604800`},[n,_]),y=(0,l.useCallback)(()=>c?m(e=>!e):v(e=>!e),[c,v]);(0,l.useEffect)(()=>{let e=e=>{e.key===`b`&&(e.metaKey||e.ctrlKey)&&(e.preventDefault(),y())};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[y]);let x=_?`expanded`:`collapsed`,S=(0,l.useMemo)(()=>({state:x,open:_,setOpen:v,isMobile:c,openMobile:d,setOpenMobile:m,toggleSidebar:y}),[x,_,v,c,d,y]);return(0,f.jsx)(b.Provider,{value:S,children:(0,f.jsx)(r.r,{delayDuration:0,children:(0,f.jsx)(`section`,{"data-slot":`layout-wrapper`,style:{"--sidebar-width":`16rem`,"--sidebar-width-icon":`3rem`,...a},className:(0,u.cn)(`relative group/sidebar-wrapper flex h-dvh bg-sidebar`,i),...s,children:o})})})}const C=(0,l.memo)(({side:e=`left`,variant:t=`sidebar`,collapsible:r=`offcanvas`,className:i,children:o,...s})=>{let{isMobile:d,state:p,openMobile:m,setOpenMobile:h,toggleSidebar:g}=x(),_=(0,l.useCallback)(e=>{g(),e.preventDefault(),e.stopPropagation()},[g]);return r===`none`?(0,f.jsx)(`aside`,{"data-slot":`sidebar`,className:(0,u.cn)(`flex w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground`,i),...s,children:o}):d?(0,f.jsx)(a.t,{open:m,onOpenChange:h,...s,children:(0,f.jsxs)(a.r,{"data-sidebar":`sidebar`,"data-slot":`sidebar`,"data-mobile":`true`,style:{"--sidebar-width":`18rem`},side:e,className:`w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground sm:max-w-3xs [&>button]:hidden`,children:[(0,f.jsxs)(a.o,{className:`sr-only`,children:[(0,f.jsx)(a.s,{children:`Sidebar`}),(0,f.jsx)(a.i,{children:`Displays the mobile sidebar.`})]}),(0,f.jsxs)(`div`,{className:`flex size-full flex-col`,children:[(0,f.jsxs)(`div`,{className:`flex flex-0 items-center gap-x-2 border-b border-border-weak p-2 pr-4`,children:[(0,f.jsxs)(n.t,{"data-sidebar":`trigger`,"data-slot":`sidebar-trigger`,variant:`ghost`,color:`muted`,size:`icon`,className:(0,u.cn)(`size-10 rounded-full`,i),onClick:_,children:[(0,f.jsx)(c.MenuIcon,{className:`size-6!`}),(0,f.jsx)(`span`,{className:`sr-only`,children:`Toggle Sidebar`})]}),(0,f.jsx)(`div`,{className:`ml-2 flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground`,children:(0,f.jsx)(c.ShoppingCartIcon,{size:20})}),(0,f.jsxs)(`div`,{className:`grid flex-1 text-left text-sm leading-tight`,children:[(0,f.jsx)(`span`,{className:`truncate font-medium`,children:`Lunas Store`}),(0,f.jsx)(`span`,{className:`truncate text-xs`,children:`Established 2023`})]})]}),(0,f.jsx)(`div`,{className:`flex flex-1 flex-col p-2`,children:o})]})]})}):(0,f.jsxs)(`aside`,{className:`group peer hidden bg-card text-sidebar-foreground md:block`,"data-state":p,"data-collapsible":p===`collapsed`?r:``,"data-variant":t,"data-side":e,"data-slot":`sidebar`,children:[(0,f.jsx)(`div`,{"data-slot":`sidebar-gap`,className:(0,u.cn)(`bg-transparent`,`transition-[width] duration-200 ease-linear`,`h-(--header-height) sm:h-[calc(var(--header-height)+0.5rem)]`,`w-(--sidebar-width)`,`group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]`)}),(0,f.jsx)(`div`,{"data-slot":`sidebar-container`,className:(0,u.cn)(`hidden md:flex shadow-nav`,`fixed left-0 inset-y-0 p-2`,`top-[calc(var(--header-height)+0.5rem)] z-10`,`w-(--sidebar-width)`,`transition-all duration-200 ease-linear`,`group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]`,i),...s,children:(0,f.jsx)(`div`,{"data-sidebar":`sidebar`,"data-slot":`sidebar-inner`,className:`relative flex size-full flex-col`,children:o})})]})});C.displayName=`CMSLayoutSidebar`;const w=(0,l.memo)(({className:e,children:t,...n})=>(0,f.jsxs)(`main`,{"data-slot":`sidebar-inset`,className:(0,u.cn)(`relative flex w-full flex-1 flex-col`,e),...n,children:[(0,f.jsx)(`div`,{className:`h-(--header-height) sm:h-[calc(var(--header-height)+0.5rem)]`}),(0,f.jsx)(`div`,{className:`relative flex-1 size-full overflow-auto`,children:t})]}));w.displayName=`CMSLayoutMain`;const T=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(s.t,{"data-slot":`sidebar-input`,"data-sidebar":`input`,className:(0,u.cn)(`h-8 w-full bg-background shadow-none`,e),...t}));T.displayName=`SidebarInput`;const E=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(`div`,{"data-slot":`sidebar-header`,"data-sidebar":`header`,className:(0,u.cn)(`flex flex-col gap-2 p-2`,e),...t}));E.displayName=`SidebarHeader`;const D=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(`div`,{"data-slot":`sidebar-footer`,"data-sidebar":`footer`,className:(0,u.cn)(`flex flex-col gap-2`,e),...t}));D.displayName=`SidebarFooter`;const O=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(i.t,{"data-slot":`sidebar-separator`,"data-sidebar":`separator`,className:(0,u.cn)(`mx-2 w-auto bg-sidebar-border`,e),...t}));O.displayName=`SidebarSeparator`;const k=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(`div`,{"data-slot":`sidebar-content`,"data-sidebar":`content`,className:(0,u.cn)(`flex flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden`,e),...t}));k.displayName=`SidebarContent`;const A=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(`div`,{"data-slot":`sidebar-group`,"data-sidebar":`group`,className:(0,u.cn)(`relative flex w-full flex-col`,e),...t}));A.displayName=`SidebarGroup`;const j=(0,l.memo)(({className:e,asChild:n=!1,...r})=>(0,f.jsx)(n?t.t:`div`,{"data-slot":`sidebar-group-label`,"data-sidebar":`group-label`,className:(0,u.cn)(`flex h-8 shrink-0 items-center rounded-md px-2 font-medium text-sidebar-foreground/70 text-xs outline-hidden ring-sidebar-ring transition-[margin,opacity,color] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0`,`group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0`,e),...r}));j.displayName=`SidebarGroupLabel`;const M=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(`div`,{"data-slot":`sidebar-group-content`,"data-sidebar":`group-content`,className:(0,u.cn)(`w-full text-sm`,e),...t}));M.displayName=`SidebarGroupContent`;const N=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(`ul`,{"data-slot":`sidebar-menu`,"data-sidebar":`menu`,className:(0,u.cn)(`flex w-full min-w-0 flex-col gap-1`,e),...t}));N.displayName=`SidebarMenu`;const P=(0,l.memo)(({className:e,...t})=>(0,f.jsx)(`li`,{"data-slot":`sidebar-menu-item`,"data-sidebar":`menu-item`,className:(0,u.cn)(`group/menu-item relative`,e),...t}));P.displayName=`SidebarMenuItem`;const F=(0,d.cva)([`peer/menu-button`,`cursor-pointer`,`flex w-full items-center gap-2`,`overflow-hidden rounded-md p-2 outline-hidden`,`truncate text-left font-normal`,`transition-[color,background-color,width,height,padding]`,`active:bg-sidebar-accent active:text-sidebar-accent-foreground`,`disabled:pointer-events-none disabled:opacity-50`,`group-has-data-[sidebar=menu-action]/menu-item:pr-8`,`aria-disabled:pointer-events-none aria-disabled:opacity-50`,`data-[active=true]:bg-sidebar-primary-muted data-[active=true]:text-sidebar-primary`,`data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground`,`group-data-[collapsible=icon]:size-12! group-data-[collapsible=icon]:p-3! group-data-[collapsible=icon]:gap-3!`,`[&>svg]:size-6 [&>svg]:shrink-0`,`[&>span:last-child]:truncate`],{variants:{variant:{default:`hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground`,outline:`bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]`},size:{default:`h-10 text-sm`,sm:`h-7 text-xs`,lg:`h-12 text-sm group-data-[collapsible=icon]:p-0!`}},defaultVariants:{variant:`default`,size:`default`}}),I=(0,l.memo)(({asChild:e=!1,isActive:n=!1,variant:i=`default`,size:a=`default`,tooltip:o,className:s,...c})=>{let d=e?t.t:`button`,{isMobile:p,state:m}=x(),h=(0,l.useCallback)(e=>{c.onClick?.(),e.preventDefault(),e.stopPropagation()},[c.onClick]),g=(0,f.jsx)(d,{"data-slot":`sidebar-menu-button`,"data-sidebar":`menu-button`,"data-size":a,"data-active":n,className:(0,u.cn)(F({variant:i,size:a}),s),onClick:h,...c});return o?(typeof o==`string`&&(o={children:o}),(0,f.jsxs)(r.t,{children:[(0,f.jsx)(r.i,{asChild:!0,children:g}),(0,f.jsx)(r.n,{side:`right`,align:`center`,hidden:m!==`collapsed`||p,...o})]})):g});I.displayName=`SidebarMenuButton`;const L=({i18nText:e,onChangeToEnLocale:t,onChangeToViLocale:r})=>{let{toggleSidebar:i}=x(),a=(0,l.useCallback)(e=>{e.preventDefault(),e.stopPropagation(),i()},[i]),s=(0,l.useCallback)(e=>{e.preventDefault(),e.stopPropagation(),t?.()},[t]),d=(0,l.useCallback)(e=>{e.preventDefault(),e.stopPropagation(),r?.()},[r]);return(0,f.jsxs)(`header`,{"data-slot":`cms-layout-header`,className:(0,u.cn)(`bg-card`,`h-(--header-height)`,`sm:h-[calc(var(--header-height)+0.5rem)] sm:px-4 sm:pr-6`,`absolute inset-x-0 top-0 z-20 gap-2 px-2 pr-4.5`,`flex items-center shadow-nav`,`transition-[height] ease-linear`),children:[(0,f.jsxs)(n.t,{"data-sidebar":`trigger`,"data-slot":`sidebar-trigger`,variant:`ghost`,color:`muted`,size:`icon`,className:`size-10 rounded-full transition-all hover:text-text-positive`,onClick:a,children:[(0,f.jsx)(c.MenuIcon,{className:`size-6!`}),(0,f.jsx)(`span`,{className:`sr-only`,children:`Toggle Sidebar`})]}),(0,f.jsxs)(`div`,{className:`flex flex-1 gap-x-2 sm:ml-2.5`,children:[(0,f.jsx)(`div`,{className:`flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground`,children:(0,f.jsx)(c.ShoppingCartIcon,{size:20})}),(0,f.jsxs)(`div`,{className:`grid flex-1 text-left text-sm leading-tight`,children:[(0,f.jsx)(`span`,{className:`truncate font-medium`,children:`Lunas Enterprise`}),(0,f.jsx)(`span`,{className:`truncate text-xs`,children:`Established 2025`})]})]}),(0,f.jsxs)(o.t,{children:[(0,f.jsx)(o.h,{asChild:!0,children:(0,f.jsxs)(n.t,{"data-slot":`locale-trigger`,variant:`ghost`,color:`muted`,className:`gap-x-1 rounded-full transition-all hover:text-text-positive`,children:[(0,f.jsx)(c.EarthIcon,{className:`size-6!`}),e]})}),(0,f.jsx)(o.r,{align:`end`,children:(0,f.jsxs)(o.i,{children:[(0,f.jsx)(o.a,{onClick:s,children:`EN - English`}),(0,f.jsx)(o.a,{onClick:d,children:`VI - Vietnamese`})]})})]})]})},R=(0,l.memo)(({id:e,label:t,icon:n,activeNavItemId:r,onClick:i})=>(0,f.jsx)(P,{children:(0,f.jsxs)(I,{isActive:e===r,onClick:i,children:[n,t]})}));R.displayName=`SidebarContentGroupItem`;const z=(0,l.memo)(({id:e,label:t,children:n})=>(0,f.jsxs)(A,{children:[(0,f.jsx)(j,{children:t}),(0,f.jsx)(M,{children:(0,f.jsx)(N,{children:n})})]}));z.displayName=`SidebarContentGroup`;const B=({i18nText:e,activeNavItemId:t,sidebar:n,children:r,onChangeToEnLocale:i,onChangeToViLocale:a,onLogout:o,logoutLabel:s=`Log out`,copyright:l=`Copyright © ${new Date().getFullYear()}, Lunas.`})=>{let u=n?.groupcontent??[];return(0,f.jsxs)(S,{children:[(0,f.jsx)(L,{i18nText:e,onChangeToEnLocale:i,onChangeToViLocale:a}),(0,f.jsxs)(C,{variant:`inset`,collapsible:`icon`,children:[(0,f.jsx)(k,{children:u.map(e=>(0,f.jsx)(z,{id:e.id,label:e.label,children:e.items.map(e=>(0,f.jsx)(R,{id:e.id,activeNavItemId:t,label:e.label,icon:e.icon,onClick:e.onClick},e.id))},e.id))}),(0,f.jsx)(D,{children:(0,f.jsxs)(N,{children:[(0,f.jsx)(P,{children:(0,f.jsxs)(I,{className:`border border-border`,onClick:o,children:[(0,f.jsx)(c.LogOutIcon,{className:`text-text-positive-weak`}),s]})}),(0,f.jsx)(P,{className:`mt-2 border-t border-t-border`,children:(0,f.jsx)(`p`,{className:`pt-2 text-center text-xs text-text-positive-subtle`,children:l})})]})})]}),(0,f.jsx)(w,{children:r})]})};Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return B}});
2
- //# sourceMappingURL=cms-layout-BrubV8D8.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cms-layout-BrubV8D8.cjs","names":["open","TooltipProvider","Sheet","SheetContent","SheetHeader","SheetTitle","SheetDescription","Button","MenuIcon","ShoppingCartIcon","Input","Separator","Slot","Tooltip","TooltipTrigger","TooltipContent","CMSLayoutHeader: React.FC<{\n i18nText?: string;\n onChangeToEnLocale?: () => void;\n onChangeToViLocale?: () => void;\n}>","Button","MenuIcon","ShoppingCartIcon","DropdownMenu","DropdownMenuTrigger","EarthIcon","DropdownMenuContent","DropdownMenuGroup","DropdownMenuItem","CMSLayout: React.FC<React.PropsWithChildren<CMSLayoutProps>>","LogOutIcon"],"sources":["../packages/components/layouts/cms-layout/components/sidebar.tsx","../packages/components/layouts/cms-layout/components/header.tsx","../packages/components/layouts/cms-layout/index.tsx"],"sourcesContent":["'use client';\n\nimport { createContext, memo, useCallback, useContext, useEffect, useMemo, useState } from 'react';\n\nimport { MenuIcon, PanelLeftIcon, ShoppingCartIcon } from 'lucide-react';\n\nimport { useIsMobile } from '@customafk/react-toolkit/hooks/useMobile';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Input } from '@/components/ui/input';\nimport { Separator } from '@/components/ui/separator';\nimport { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from '@/components/ui/sheet';\nimport { Skeleton } from '@/components/ui/skeleton';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';\n\nimport { Slot } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nconst SIDEBAR_COOKIE_NAME = 'sidebar_state';\nconst SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;\nconst SIDEBAR_WIDTH = '16rem';\nconst SIDEBAR_WIDTH_MOBILE = '18rem';\nconst SIDEBAR_WIDTH_ICON = '3rem';\nconst SIDEBAR_KEYBOARD_SHORTCUT = 'b';\n\ntype SidebarContextProps = {\n state: 'expanded' | 'collapsed';\n open: boolean;\n setOpen: (open: boolean) => void;\n openMobile: boolean;\n setOpenMobile: (open: boolean) => void;\n isMobile: boolean;\n toggleSidebar: () => void;\n};\n\nconst SidebarContext = createContext<SidebarContextProps | null>(null);\n\nfunction useSidebar() {\n const context = useContext(SidebarContext);\n if (!context) {\n throw new Error('useSidebar must be used within a SidebarProvider.');\n }\n return context;\n}\n\nfunction CMSLayoutProvider({\n defaultOpen = true,\n open: openProp,\n onOpenChange: setOpenProp,\n className,\n style,\n children,\n ...props\n}: React.ComponentProps<'div'> & {\n defaultOpen?: boolean;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n}) {\n const isMobile = useIsMobile();\n const [openMobile, setOpenMobile] = useState(false);\n\n const [_open, _setOpen] = useState(defaultOpen);\n const open = openProp ?? _open;\n const setOpen = useCallback(\n (value: boolean | ((value: boolean) => boolean)) => {\n const openState = typeof value === 'function' ? value(open) : value;\n if (setOpenProp) {\n setOpenProp(openState);\n } else {\n _setOpen(openState);\n }\n // biome-ignore lint/suspicious/noDocumentCookie: persists sidebar state across page loads\n document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;\n },\n [setOpenProp, open]\n );\n\n const toggleSidebar = useCallback(() => {\n return isMobile ? setOpenMobile(open => !open) : setOpen(open => !open);\n }, [isMobile, setOpen]);\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {\n event.preventDefault();\n toggleSidebar();\n }\n };\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [toggleSidebar]);\n\n const state = open ? 'expanded' : 'collapsed';\n\n const contextValue = useMemo<SidebarContextProps>(\n () => ({ state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar }),\n [state, open, setOpen, isMobile, openMobile, toggleSidebar]\n );\n\n return (\n <SidebarContext.Provider value={contextValue}>\n <TooltipProvider delayDuration={0}>\n <section\n data-slot=\"layout-wrapper\"\n style={{ '--sidebar-width': SIDEBAR_WIDTH, '--sidebar-width-icon': SIDEBAR_WIDTH_ICON, ...style } as React.CSSProperties}\n className={cn('relative group/sidebar-wrapper flex h-dvh bg-sidebar', className)}\n {...props}\n >\n {children}\n </section>\n </TooltipProvider>\n </SidebarContext.Provider>\n );\n}\n\nconst CMSLayoutSidebar = memo(\n ({\n side = 'left',\n variant = 'sidebar',\n collapsible = 'offcanvas',\n className,\n children,\n ...props\n }: React.ComponentProps<'div'> & {\n side?: 'left' | 'right';\n variant?: 'sidebar' | 'floating' | 'inset';\n collapsible?: 'offcanvas' | 'icon' | 'none';\n }) => {\n const { isMobile, state, openMobile, setOpenMobile, toggleSidebar } = useSidebar();\n\n const handleToggleSidebar = useCallback<React.MouseEventHandler<HTMLButtonElement>>(\n event => {\n toggleSidebar();\n event.preventDefault();\n event.stopPropagation();\n },\n [toggleSidebar]\n );\n\n if (collapsible === 'none') {\n return (\n <aside data-slot=\"sidebar\" className={cn('flex w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground', className)} {...props}>\n {children}\n </aside>\n );\n }\n\n if (isMobile) {\n return (\n <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>\n <SheetContent\n data-sidebar=\"sidebar\"\n data-slot=\"sidebar\"\n data-mobile=\"true\"\n style={{ '--sidebar-width': SIDEBAR_WIDTH_MOBILE } as React.CSSProperties}\n side={side}\n className=\"w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground sm:max-w-3xs [&>button]:hidden\"\n >\n <SheetHeader className=\"sr-only\">\n <SheetTitle>Sidebar</SheetTitle>\n <SheetDescription>Displays the mobile sidebar.</SheetDescription>\n </SheetHeader>\n <div className=\"flex size-full flex-col\">\n <div className=\"flex flex-0 items-center gap-x-2 border-b border-border-weak p-2 pr-4\">\n <Button\n data-sidebar=\"trigger\"\n data-slot=\"sidebar-trigger\"\n variant=\"ghost\"\n color=\"muted\"\n size=\"icon\"\n className={cn('size-10 rounded-full', className)}\n onClick={handleToggleSidebar}\n >\n <MenuIcon className=\"size-6!\" />\n <span className=\"sr-only\">Toggle Sidebar</span>\n </Button>\n <div className=\"ml-2 flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground\">\n <ShoppingCartIcon size={20} />\n </div>\n <div className=\"grid flex-1 text-left text-sm leading-tight\">\n <span className=\"truncate font-medium\">Lunas Store</span>\n <span className=\"truncate text-xs\">Established 2023</span>\n </div>\n </div>\n <div className=\"flex flex-1 flex-col p-2\">{children}</div>\n </div>\n </SheetContent>\n </Sheet>\n );\n }\n\n return (\n <aside\n className=\"group peer hidden bg-card text-sidebar-foreground md:block\"\n data-state={state}\n data-collapsible={state === 'collapsed' ? collapsible : ''}\n data-variant={variant}\n data-side={side}\n data-slot=\"sidebar\"\n >\n <div\n data-slot=\"sidebar-gap\"\n className={cn(\n 'bg-transparent',\n 'transition-[width] duration-200 ease-linear',\n 'h-(--header-height) sm:h-[calc(var(--header-height)+0.5rem)]',\n 'w-(--sidebar-width)',\n 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]'\n )}\n />\n <div\n data-slot=\"sidebar-container\"\n className={cn(\n 'hidden md:flex shadow-nav',\n 'fixed left-0 inset-y-0 p-2',\n 'top-[calc(var(--header-height)+0.5rem)] z-10',\n 'w-(--sidebar-width)',\n 'transition-all duration-200 ease-linear',\n 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]',\n className\n )}\n {...props}\n >\n <div data-sidebar=\"sidebar\" data-slot=\"sidebar-inner\" className=\"relative flex size-full flex-col\">\n {children}\n </div>\n </div>\n </aside>\n );\n }\n);\nCMSLayoutSidebar.displayName = 'CMSLayoutSidebar';\n\nfunction SidebarTrigger({ className, onClick, ...props }: React.ComponentProps<typeof Button>) {\n const { toggleSidebar } = useSidebar();\n\n return (\n <Button\n data-sidebar=\"trigger\"\n data-slot=\"sidebar-trigger\"\n variant=\"ghost\"\n size=\"icon\"\n className={cn('size-7', className)}\n onClick={event => {\n onClick?.(event);\n toggleSidebar();\n }}\n {...props}\n >\n <PanelLeftIcon />\n <span className=\"sr-only\">Toggle Sidebar</span>\n </Button>\n );\n}\n\nfunction SidebarRail({ className, ...props }: React.ComponentProps<'button'>) {\n const { toggleSidebar } = useSidebar();\n\n return (\n <button\n data-sidebar=\"rail\"\n data-slot=\"sidebar-rail\"\n aria-label=\"Toggle Sidebar\"\n tabIndex={-1}\n onClick={toggleSidebar}\n title=\"Toggle Sidebar\"\n className={cn(\n 'absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-0.5 hover:after:bg-sidebar-border group-data-[side=left]:-right-4 group-data-[side=right]:left-0 sm:flex',\n 'in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize',\n '[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize',\n 'group-data-[collapsible=offcanvas]:translate-x-0 hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:after:left-full',\n '[[data-side=left][data-collapsible=offcanvas]_&]:-right-2',\n '[[data-side=right][data-collapsible=offcanvas]_&]:-left-2',\n className\n )}\n {...props}\n />\n );\n}\n\nconst CMSLayoutMain = memo(({ className, children, ...props }: React.ComponentProps<'main'>) => {\n return (\n <main data-slot=\"sidebar-inset\" className={cn('relative flex w-full flex-1 flex-col', className)} {...props}>\n <div className=\"h-(--header-height) sm:h-[calc(var(--header-height)+0.5rem)]\" />\n <div className=\"relative flex-1 size-full overflow-auto\">{children}</div>\n </main>\n );\n});\nCMSLayoutMain.displayName = 'CMSLayoutMain';\n\nconst SidebarInput = memo(({ className, ...props }: React.ComponentProps<typeof Input>) => {\n return <Input data-slot=\"sidebar-input\" data-sidebar=\"input\" className={cn('h-8 w-full bg-background shadow-none', className)} {...props} />;\n});\nSidebarInput.displayName = 'SidebarInput';\n\nconst SidebarHeader = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"sidebar-header\" data-sidebar=\"header\" className={cn('flex flex-col gap-2 p-2', className)} {...props} />;\n});\nSidebarHeader.displayName = 'SidebarHeader';\n\nconst SidebarFooter = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"sidebar-footer\" data-sidebar=\"footer\" className={cn('flex flex-col gap-2', className)} {...props} />;\n});\nSidebarFooter.displayName = 'SidebarFooter';\n\nconst SidebarSeparator = memo(({ className, ...props }: React.ComponentProps<typeof Separator>) => {\n return <Separator data-slot=\"sidebar-separator\" data-sidebar=\"separator\" className={cn('mx-2 w-auto bg-sidebar-border', className)} {...props} />;\n});\nSidebarSeparator.displayName = 'SidebarSeparator';\n\nconst SidebarContent = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return (\n <div\n data-slot=\"sidebar-content\"\n data-sidebar=\"content\"\n className={cn('flex flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden', className)}\n {...props}\n />\n );\n});\nSidebarContent.displayName = 'SidebarContent';\n\nconst SidebarGroup = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"sidebar-group\" data-sidebar=\"group\" className={cn('relative flex w-full flex-col', className)} {...props} />;\n});\nSidebarGroup.displayName = 'SidebarGroup';\n\nconst SidebarGroupLabel = memo(({ className, asChild = false, ...props }: React.ComponentProps<'div'> & { asChild?: boolean }) => {\n const Comp = asChild ? Slot : 'div';\n\n return (\n <Comp\n data-slot=\"sidebar-group-label\"\n data-sidebar=\"group-label\"\n className={cn(\n 'flex h-8 shrink-0 items-center rounded-md px-2 font-medium text-sidebar-foreground/70 text-xs outline-hidden ring-sidebar-ring transition-[margin,opacity,color] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',\n 'group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0',\n className\n )}\n {...props}\n />\n );\n});\nSidebarGroupLabel.displayName = 'SidebarGroupLabel';\n\nfunction SidebarGroupAction({ className, asChild = false, ...props }: React.ComponentProps<'button'> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n data-slot=\"sidebar-group-action\"\n data-sidebar=\"group-action\"\n className={cn(\n 'absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-hidden ring-sidebar-ring transition-[background-color,color,transform] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2',\n '[&>svg]:size-4 [&>svg]:shrink-0',\n // Increases the hit area of the button on mobile.\n 'after:absolute after:-inset-2 md:after:hidden',\n 'group-data-[collapsible=icon]:hidden',\n className\n )}\n {...props}\n />\n );\n}\n\nconst SidebarGroupContent = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"sidebar-group-content\" data-sidebar=\"group-content\" className={cn('w-full text-sm', className)} {...props} />;\n});\nSidebarGroupContent.displayName = 'SidebarGroupContent';\n\nconst SidebarMenu = memo(({ className, ...props }: React.ComponentProps<'ul'>) => {\n return <ul data-slot=\"sidebar-menu\" data-sidebar=\"menu\" className={cn('flex w-full min-w-0 flex-col gap-1', className)} {...props} />;\n});\nSidebarMenu.displayName = 'SidebarMenu';\n\nconst SidebarMenuItem = memo(({ className, ...props }: React.ComponentProps<'li'>) => {\n return <li data-slot=\"sidebar-menu-item\" data-sidebar=\"menu-item\" className={cn('group/menu-item relative', className)} {...props} />;\n});\nSidebarMenuItem.displayName = 'SidebarMenuItem';\n\nconst sidebarMenuButtonVariants = cva(\n [\n 'peer/menu-button',\n 'cursor-pointer',\n 'flex w-full items-center gap-2',\n 'overflow-hidden rounded-md p-2 outline-hidden',\n 'truncate text-left font-normal',\n 'transition-[color,background-color,width,height,padding]',\n 'active:bg-sidebar-accent active:text-sidebar-accent-foreground',\n 'disabled:pointer-events-none disabled:opacity-50',\n 'group-has-data-[sidebar=menu-action]/menu-item:pr-8',\n 'aria-disabled:pointer-events-none aria-disabled:opacity-50',\n 'data-[active=true]:bg-sidebar-primary-muted data-[active=true]:text-sidebar-primary',\n 'data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground',\n 'group-data-[collapsible=icon]:size-12! group-data-[collapsible=icon]:p-3! group-data-[collapsible=icon]:gap-3!',\n '[&>svg]:size-6 [&>svg]:shrink-0',\n '[&>span:last-child]:truncate',\n ],\n {\n variants: {\n variant: {\n default: 'hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground',\n outline:\n 'bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]',\n },\n size: {\n default: 'h-10 text-sm',\n sm: 'h-7 text-xs',\n lg: 'h-12 text-sm group-data-[collapsible=icon]:p-0!',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n }\n);\n\nconst SidebarMenuButton = memo(\n ({\n asChild = false,\n isActive = false,\n variant = 'default',\n size = 'default',\n tooltip,\n className,\n ...props\n }: React.ComponentProps<'button'> & {\n asChild?: boolean;\n isActive?: boolean;\n tooltip?: string | React.ComponentProps<typeof TooltipContent>;\n onClick?: () => void;\n } & VariantProps<typeof sidebarMenuButtonVariants>) => {\n const Comp = asChild ? Slot : 'button';\n const { isMobile, state } = useSidebar();\n\n const handleClick = useCallback<React.MouseEventHandler<HTMLButtonElement>>(\n event => {\n props.onClick?.();\n event.preventDefault();\n event.stopPropagation();\n },\n [props.onClick]\n );\n\n const button = (\n <Comp\n data-slot=\"sidebar-menu-button\"\n data-sidebar=\"menu-button\"\n data-size={size}\n data-active={isActive}\n className={cn(sidebarMenuButtonVariants({ variant, size }), className)}\n onClick={handleClick}\n {...props}\n />\n );\n\n if (!tooltip) return button;\n\n if (typeof tooltip === 'string') {\n tooltip = { children: tooltip };\n }\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>{button}</TooltipTrigger>\n <TooltipContent side=\"right\" align=\"center\" hidden={state !== 'collapsed' || isMobile} {...tooltip} />\n </Tooltip>\n );\n }\n);\nSidebarMenuButton.displayName = 'SidebarMenuButton';\n\nfunction SidebarMenuAction({\n className,\n asChild = false,\n showOnHover = false,\n ...props\n}: React.ComponentProps<'button'> & {\n asChild?: boolean;\n showOnHover?: boolean;\n}) {\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n data-slot=\"sidebar-menu-action\"\n data-sidebar=\"menu-action\"\n className={cn(\n 'absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-hidden ring-sidebar-ring transition-[background-color,color,opacity] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-sidebar-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0',\n // Increases the hit area of the button on mobile.\n 'after:absolute after:-inset-2 md:after:hidden',\n 'peer-data-[size=sm]/menu-button:top-1',\n 'peer-data-[size=default]/menu-button:top-1.5',\n 'peer-data-[size=lg]/menu-button:top-2.5',\n 'group-data-[collapsible=icon]:hidden',\n showOnHover &&\n 'group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground md:opacity-0',\n className\n )}\n {...props}\n />\n );\n}\n\nfunction SidebarMenuBadge({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"sidebar-menu-badge\"\n data-sidebar=\"menu-badge\"\n className={cn(\n 'pointer-events-none absolute right-1 flex h-5 min-w-5 select-none items-center justify-center rounded-md px-1 font-medium text-sidebar-foreground text-xs tabular-nums transition-colors',\n 'peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground',\n 'peer-data-[size=sm]/menu-button:top-1',\n 'peer-data-[size=default]/menu-button:top-1.5',\n 'peer-data-[size=lg]/menu-button:top-2.5',\n 'group-data-[collapsible=icon]:hidden',\n className\n )}\n {...props}\n />\n );\n}\n\nfunction SidebarMenuSkeleton({\n className,\n showIcon = false,\n ...props\n}: React.ComponentProps<'div'> & {\n showIcon?: boolean;\n}) {\n const width = useMemo(() => `${Math.floor(Math.random() * 40) + 50}%`, []);\n\n return (\n <div data-slot=\"sidebar-menu-skeleton\" data-sidebar=\"menu-skeleton\" className={cn('flex h-8 items-center gap-2 rounded-md px-2', className)} {...props}>\n {showIcon && <Skeleton className=\"size-4 rounded-md\" data-sidebar=\"menu-skeleton-icon\" />}\n <Skeleton\n className=\"h-4 max-w-(--skeleton-width) flex-1\"\n data-sidebar=\"menu-skeleton-text\"\n style={{ '--skeleton-width': width } as React.CSSProperties}\n />\n </div>\n );\n}\n\nfunction SidebarMenuSub({ className, ...props }: React.ComponentProps<'ul'>) {\n return (\n <ul\n data-slot=\"sidebar-menu-sub\"\n data-sidebar=\"menu-sub\"\n className={cn(\n 'mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5',\n 'group-data-[collapsible=icon]:hidden',\n className\n )}\n {...props}\n />\n );\n}\n\nfunction SidebarMenuSubItem({ className, ...props }: React.ComponentProps<'li'>) {\n return <li data-slot=\"sidebar-menu-sub-item\" data-sidebar=\"menu-sub-item\" className={cn('group/menu-sub-item relative', className)} {...props} />;\n}\n\nfunction SidebarMenuSubButton({\n asChild = false,\n size = 'md',\n isActive = false,\n className,\n ...props\n}: React.ComponentProps<'a'> & {\n asChild?: boolean;\n size?: 'sm' | 'md';\n isActive?: boolean;\n}) {\n const Comp = asChild ? Slot : 'a';\n\n return (\n <Comp\n data-slot=\"sidebar-menu-sub-button\"\n data-sidebar=\"menu-sub-button\"\n data-size={size}\n data-active={isActive}\n className={cn(\n 'flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground outline-hidden ring-sidebar-ring transition-[background-color,color] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground',\n 'data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground',\n size === 'sm' && 'text-xs',\n size === 'md' && 'text-sm',\n 'group-data-[collapsible=icon]:hidden',\n className\n )}\n {...props}\n />\n );\n}\n\nexport {\n CMSLayoutSidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarInput,\n CMSLayoutMain,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSkeleton,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n CMSLayoutProvider,\n SidebarRail,\n SidebarSeparator,\n SidebarTrigger,\n // biome-ignore lint/style/useComponentExportOnlyModules: true\n useSidebar,\n};\n","'use client';\n\nimport { useCallback } from 'react';\n\nimport { EarthIcon, MenuIcon, ShoppingCartIcon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu';\n\nimport { useSidebar } from './sidebar';\n\nexport const CMSLayoutHeader: React.FC<{\n i18nText?: string;\n onChangeToEnLocale?: () => void;\n onChangeToViLocale?: () => void;\n}> = ({ i18nText, onChangeToEnLocale, onChangeToViLocale }) => {\n const { toggleSidebar } = useSidebar();\n\n const handleToggleSidebar = useCallback(\n (event: React.MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n toggleSidebar();\n },\n [toggleSidebar]\n );\n\n const handleEnLocale = useCallback(\n (event: React.MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n onChangeToEnLocale?.();\n },\n [onChangeToEnLocale]\n );\n\n const handleViLocale = useCallback(\n (event: React.MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n onChangeToViLocale?.();\n },\n [onChangeToViLocale]\n );\n\n return (\n <header\n data-slot=\"cms-layout-header\"\n className={cn(\n 'bg-card',\n 'h-(--header-height)',\n 'sm:h-[calc(var(--header-height)+0.5rem)] sm:px-4 sm:pr-6',\n 'absolute inset-x-0 top-0 z-20 gap-2 px-2 pr-4.5',\n 'flex items-center shadow-nav',\n 'transition-[height] ease-linear'\n )}\n >\n <Button\n data-sidebar=\"trigger\"\n data-slot=\"sidebar-trigger\"\n variant=\"ghost\"\n color=\"muted\"\n size=\"icon\"\n className=\"size-10 rounded-full transition-all hover:text-text-positive\"\n onClick={handleToggleSidebar}\n >\n <MenuIcon className=\"size-6!\" />\n <span className=\"sr-only\">Toggle Sidebar</span>\n </Button>\n\n <div className=\"flex flex-1 gap-x-2 sm:ml-2.5\">\n <div className=\"flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground\">\n <ShoppingCartIcon size={20} />\n </div>\n <div className=\"grid flex-1 text-left text-sm leading-tight\">\n <span className=\"truncate font-medium\">Lunas Enterprise</span>\n <span className=\"truncate text-xs\">Established 2025</span>\n </div>\n </div>\n\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button data-slot=\"locale-trigger\" variant=\"ghost\" color=\"muted\" className=\"gap-x-1 rounded-full transition-all hover:text-text-positive\">\n <EarthIcon className=\"size-6!\" />\n {i18nText}\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuGroup>\n <DropdownMenuItem onClick={handleEnLocale}>EN - English</DropdownMenuItem>\n <DropdownMenuItem onClick={handleViLocale}>VI - Vietnamese</DropdownMenuItem>\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n </header>\n );\n};\n","'use client';\n\nimport { memo } from 'react';\n\nimport { LogOutIcon } from 'lucide-react';\n\nimport { CMSLayoutHeader } from './components/header';\nimport {\n CMSLayoutSidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n CMSLayoutMain,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n CMSLayoutProvider,\n} from './components/sidebar';\n\ntype NavItem = {\n /** Unique identifier for the nav item, used as React key and for active-state comparison. */\n id: string;\n /** Human-readable label rendered inside the sidebar button. */\n label: string;\n /** Optional icon element rendered to the left of the label. */\n icon?: React.ReactNode;\n /** Callback fired when the sidebar button is clicked. */\n onClick?: () => void;\n};\n\ntype NavGroup = {\n /** Unique identifier for the group, used as React key. */\n id: string;\n /** Optional section heading rendered above the group's items. */\n label?: string;\n /** Navigation items that belong to this group. */\n items: NavItem[];\n};\n\nexport type CMSLayoutProps = {\n /** Text label used by the header for language-toggle or i18n display. */\n i18nText?: string;\n /** ID of the currently active navigation item; matched against `NavItem.id` to highlight the active button. */\n activeNavItemId?: string;\n /** Sidebar navigation definition; omitting this prop renders an empty sidebar. */\n sidebar?: { groupcontent: NavGroup[] };\n /** Callback fired when the logout button is clicked. */\n onLogout?: () => void;\n /** Callback fired when the user switches the UI locale to English. */\n onChangeToEnLocale?: () => void;\n /** Callback fired when the user switches the UI locale to Vietnamese. */\n onChangeToViLocale?: () => void;\n /**\n * Label displayed on the logout button.\n * @default 'Log out'\n */\n logoutLabel?: string;\n /**\n * Copyright string shown at the bottom of the sidebar.\n * @default `Copyright © <current year>, Lunas.`\n */\n copyright?: string;\n};\n\nconst SidebarContentGroupItem = memo<NavItem & { activeNavItemId?: string }>(({ id, label, icon, activeNavItemId, onClick }) => (\n <SidebarMenuItem>\n <SidebarMenuButton isActive={id === activeNavItemId} onClick={onClick}>\n {icon}\n {label}\n </SidebarMenuButton>\n </SidebarMenuItem>\n));\nSidebarContentGroupItem.displayName = 'SidebarContentGroupItem';\n\nconst SidebarContentGroup = memo<React.PropsWithChildren<Omit<NavGroup, 'items'>>>(({ id, label, children }) => (\n <SidebarGroup>\n <SidebarGroupLabel>{label}</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>{children}</SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n));\nSidebarContentGroup.displayName = 'SidebarContentGroup';\n\n/**\n * Full-page CMS application shell with a collapsible inset sidebar, header, and main content area.\n *\n * @example\n * ```tsx\n * import { CMSLayout } from '@customafk/lunas-ui/layouts/cms-layout';\n * import { LayoutDashboardIcon } from 'lucide-react';\n *\n * <CMSLayout\n * activeNavItemId=\"dashboard\"\n * sidebar={{\n * groupcontent: [\n * {\n * id: 'main',\n * label: 'Main',\n * items: [\n * { id: 'dashboard', label: 'Dashboard', icon: <LayoutDashboardIcon />, onClick: () => router.push('/') },\n * ],\n * },\n * ],\n * }}\n * onLogout={() => signOut()}\n * >\n * <DashboardPage />\n * </CMSLayout>\n * ```\n */\nexport const CMSLayout: React.FC<React.PropsWithChildren<CMSLayoutProps>> = ({\n i18nText,\n activeNavItemId,\n sidebar,\n children,\n onChangeToEnLocale,\n onChangeToViLocale,\n onLogout,\n logoutLabel = 'Log out',\n copyright = `Copyright © ${new Date().getFullYear()}, Lunas.`,\n}) => {\n const groups = sidebar?.groupcontent ?? [];\n\n return (\n <CMSLayoutProvider>\n <CMSLayoutHeader i18nText={i18nText} onChangeToEnLocale={onChangeToEnLocale} onChangeToViLocale={onChangeToViLocale} />\n <CMSLayoutSidebar variant=\"inset\" collapsible=\"icon\">\n <SidebarContent>\n {groups.map(group => (\n <SidebarContentGroup key={group.id} id={group.id} label={group.label}>\n {group.items.map(item => (\n <SidebarContentGroupItem\n key={item.id}\n id={item.id}\n activeNavItemId={activeNavItemId}\n label={item.label}\n icon={item.icon}\n onClick={item.onClick}\n />\n ))}\n </SidebarContentGroup>\n ))}\n </SidebarContent>\n <SidebarFooter>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton className=\"border border-border\" onClick={onLogout}>\n <LogOutIcon className=\"text-text-positive-weak\" />\n {logoutLabel}\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem className=\"mt-2 border-t border-t-border\">\n <p className=\"pt-2 text-center text-xs text-text-positive-subtle\">{copyright}</p>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarFooter>\n </CMSLayoutSidebar>\n <CMSLayoutMain>{children}</CMSLayoutMain>\n </CMSLayoutProvider>\n );\n};\n"],"mappings":"4fAmBA,MAAM,EAAsB,gBACtB,EAAyB,KAAU,GAAK,EACxC,EAAgB,QAChB,EAAuB,QACvB,EAAqB,OACrB,EAA4B,IAY5B,GAAA,EAAA,EAAA,eAA2D,KAAK,CAEtE,SAAS,GAAa,CACpB,IAAM,GAAA,EAAA,EAAA,YAAqB,EAAe,CAC1C,GAAI,CAAC,EACH,MAAU,MAAM,oDAAoD,CAEtE,OAAO,EAGT,SAAS,EAAkB,CACzB,cAAc,GACd,KAAM,EACN,aAAc,EACd,YACA,QACA,WACA,GAAG,GAKF,CACD,IAAM,GAAA,EAAA,EAAA,cAAwB,CACxB,CAAC,EAAY,IAAA,EAAA,EAAA,UAA0B,GAAM,CAE7C,CAAC,EAAO,IAAA,EAAA,EAAA,UAAqB,EAAY,CACzC,EAAO,GAAY,EACnB,GAAA,EAAA,EAAA,aACH,GAAmD,CAClD,IAAM,EAAY,OAAO,GAAU,WAAa,EAAM,EAAK,CAAG,EAC1D,EACF,EAAY,EAAU,CAEtB,EAAS,EAAU,CAGrB,SAAS,OAAS,iBAA0B,EAAU,2BAExD,CAAC,EAAa,EAAK,CACpB,CAEK,GAAA,EAAA,EAAA,iBACG,EAAW,EAAc,GAAQ,CAACA,EAAK,CAAG,EAAQ,GAAQ,CAACA,EAAK,CACtE,CAAC,EAAU,EAAQ,CAAC,EAEvB,EAAA,EAAA,eAAgB,CACd,IAAM,EAAiB,GAAyB,CAC1C,EAAM,MAAQ,MAA8B,EAAM,SAAW,EAAM,WACrE,EAAM,gBAAgB,CACtB,GAAe,GAInB,OADA,OAAO,iBAAiB,UAAW,EAAc,KACpC,OAAO,oBAAoB,UAAW,EAAc,EAChE,CAAC,EAAc,CAAC,CAEnB,IAAM,EAAQ,EAAO,WAAa,YAE5B,GAAA,EAAA,EAAA,cACG,CAAE,QAAO,OAAM,UAAS,WAAU,aAAY,gBAAe,gBAAe,EACnF,CAAC,EAAO,EAAM,EAAS,EAAU,EAAY,EAAc,CAC5D,CAED,OACE,EAAA,EAAA,KAAC,EAAe,SAAA,CAAS,MAAO,YAC9B,EAAA,EAAA,KAACC,EAAAA,EAAAA,CAAgB,cAAe,YAC9B,EAAA,EAAA,KAAC,UAAA,CACC,YAAU,iBACV,MAAO,CAAE,kBAAmB,QAAe,uBAAwB,OAAoB,GAAG,EAAO,CACjG,WAAA,EAAA,EAAA,IAAc,uDAAwD,EAAU,CAChF,GAAI,EAEH,YACO,EACM,EACM,CAI9B,MAAM,GAAA,EAAA,EAAA,OACH,CACC,OAAO,OACP,UAAU,UACV,cAAc,YACd,YACA,WACA,GAAG,KAKC,CACJ,GAAM,CAAE,WAAU,QAAO,aAAY,gBAAe,iBAAkB,GAAY,CAE5E,GAAA,EAAA,EAAA,aACJ,GAAS,CACP,GAAe,CACf,EAAM,gBAAgB,CACtB,EAAM,iBAAiB,EAEzB,CAAC,EAAc,CAChB,CAsDD,OApDI,IAAgB,QAEhB,EAAA,EAAA,KAAC,QAAA,CAAM,YAAU,UAAU,WAAA,EAAA,EAAA,IAAc,uEAAwE,EAAU,CAAE,GAAI,EAC9H,YACK,CAIR,GAEA,EAAA,EAAA,KAACC,EAAAA,EAAAA,CAAM,KAAM,EAAY,aAAc,EAAe,GAAI,YACxD,EAAA,EAAA,MAACC,EAAAA,EAAAA,CACC,eAAa,UACb,YAAU,UACV,cAAY,OACZ,MAAO,CAAE,kBAAmB,QAAsB,CAC5C,OACN,UAAU,uGAEV,EAAA,EAAA,MAACC,EAAAA,EAAAA,CAAY,UAAU,qBACrB,EAAA,EAAA,KAACC,EAAAA,EAAAA,CAAAA,SAAW,UAAA,CAAoB,EAChC,EAAA,EAAA,KAACC,EAAAA,EAAAA,CAAAA,SAAiB,+BAAA,CAA+C,CAAA,EACrD,EACd,EAAA,EAAA,MAAC,MAAA,CAAI,UAAU,qCACb,EAAA,EAAA,MAAC,MAAA,CAAI,UAAU,mFACb,EAAA,EAAA,MAACC,EAAAA,EAAAA,CACC,eAAa,UACb,YAAU,kBACV,QAAQ,QACR,MAAM,QACN,KAAK,OACL,WAAA,EAAA,EAAA,IAAc,uBAAwB,EAAU,CAChD,QAAS,aAET,EAAA,EAAA,KAACC,EAAAA,SAAAA,CAAS,UAAU,UAAA,CAAY,EAChC,EAAA,EAAA,KAAC,OAAA,CAAK,UAAU,mBAAU,kBAAqB,CAAA,EACxC,EACT,EAAA,EAAA,KAAC,MAAA,CAAI,UAAU,qIACb,EAAA,EAAA,KAACC,EAAAA,iBAAAA,CAAiB,KAAM,GAAA,CAAM,EAC1B,EACN,EAAA,EAAA,MAAC,MAAA,CAAI,UAAU,yDACb,EAAA,EAAA,KAAC,OAAA,CAAK,UAAU,gCAAuB,eAAkB,EACzD,EAAA,EAAA,KAAC,OAAA,CAAK,UAAU,4BAAmB,oBAAuB,CAAA,EACtD,GACF,EACN,EAAA,EAAA,KAAC,MAAA,CAAI,UAAU,2BAA4B,YAAe,CAAA,EACtD,CAAA,EACO,EACT,EAKV,EAAA,EAAA,MAAC,QAAA,CACC,UAAU,6DACV,aAAY,EACZ,mBAAkB,IAAU,YAAc,EAAc,GACxD,eAAc,EACd,YAAW,EACX,YAAU,qBAEV,EAAA,EAAA,KAAC,MAAA,CACC,YAAU,cACV,WAAA,EAAA,EAAA,IACE,iBACA,8CACA,+DACA,sBACA,mFACD,EACD,EACF,EAAA,EAAA,KAAC,MAAA,CACC,YAAU,oBACV,WAAA,EAAA,EAAA,IACE,4BACA,6BACA,+CACA,sBACA,0CACA,mFACA,EACD,CACD,GAAI,YAEJ,EAAA,EAAA,KAAC,MAAA,CAAI,eAAa,UAAU,YAAU,gBAAgB,UAAU,mCAC7D,YACG,EACF,CAAA,EACA,EAGb,CACD,EAAiB,YAAc,mBAiD/B,MAAM,GAAA,EAAA,EAAA,OAAsB,CAAE,YAAW,WAAU,GAAG,MAElD,EAAA,EAAA,MAAC,OAAA,CAAK,YAAU,gBAAgB,WAAA,EAAA,EAAA,IAAc,uCAAwC,EAAU,CAAE,GAAI,aACpG,EAAA,EAAA,KAAC,MAAA,CAAI,UAAU,+DAAA,CAAiE,EAChF,EAAA,EAAA,KAAC,MAAA,CAAI,UAAU,0CAA2C,YAAe,CAAA,EACpE,CAET,CACF,EAAc,YAAc,gBAE5B,MAAM,GAAA,EAAA,EAAA,OAAqB,CAAE,YAAW,GAAG,MAClC,EAAA,EAAA,KAACC,EAAAA,EAAAA,CAAM,YAAU,gBAAgB,eAAa,QAAQ,WAAA,EAAA,EAAA,IAAc,uCAAwC,EAAU,CAAE,GAAI,GAAS,CAC5I,CACF,EAAa,YAAc,eAE3B,MAAM,GAAA,EAAA,EAAA,OAAsB,CAAE,YAAW,GAAG,MACnC,EAAA,EAAA,KAAC,MAAA,CAAI,YAAU,iBAAiB,eAAa,SAAS,WAAA,EAAA,EAAA,IAAc,0BAA2B,EAAU,CAAE,GAAI,GAAS,CAC/H,CACF,EAAc,YAAc,gBAE5B,MAAM,GAAA,EAAA,EAAA,OAAsB,CAAE,YAAW,GAAG,MACnC,EAAA,EAAA,KAAC,MAAA,CAAI,YAAU,iBAAiB,eAAa,SAAS,WAAA,EAAA,EAAA,IAAc,sBAAuB,EAAU,CAAE,GAAI,GAAS,CAC3H,CACF,EAAc,YAAc,gBAE5B,MAAM,GAAA,EAAA,EAAA,OAAyB,CAAE,YAAW,GAAG,MACtC,EAAA,EAAA,KAACC,EAAAA,EAAAA,CAAU,YAAU,oBAAoB,eAAa,YAAY,WAAA,EAAA,EAAA,IAAc,gCAAiC,EAAU,CAAE,GAAI,GAAS,CACjJ,CACF,EAAiB,YAAc,mBAE/B,MAAM,GAAA,EAAA,EAAA,OAAuB,CAAE,YAAW,GAAG,MAEzC,EAAA,EAAA,KAAC,MAAA,CACC,YAAU,kBACV,eAAa,UACb,WAAA,EAAA,EAAA,IAAc,yFAA0F,EAAU,CAClH,GAAI,GACJ,CAEJ,CACF,EAAe,YAAc,iBAE7B,MAAM,GAAA,EAAA,EAAA,OAAqB,CAAE,YAAW,GAAG,MAClC,EAAA,EAAA,KAAC,MAAA,CAAI,YAAU,gBAAgB,eAAa,QAAQ,WAAA,EAAA,EAAA,IAAc,gCAAiC,EAAU,CAAE,GAAI,GAAS,CACnI,CACF,EAAa,YAAc,eAE3B,MAAM,GAAA,EAAA,EAAA,OAA0B,CAAE,YAAW,UAAU,GAAO,GAAG,MAI7D,EAAA,EAAA,KAHW,EAAUC,EAAAA,EAAO,MAAA,CAI1B,YAAU,sBACV,eAAa,cACb,WAAA,EAAA,EAAA,IACE,iPACA,8EACA,EACD,CACD,GAAI,GACJ,CAEJ,CACF,EAAkB,YAAc,oBAsBhC,MAAM,GAAA,EAAA,EAAA,OAA4B,CAAE,YAAW,GAAG,MACzC,EAAA,EAAA,KAAC,MAAA,CAAI,YAAU,wBAAwB,eAAa,gBAAgB,WAAA,EAAA,EAAA,IAAc,iBAAkB,EAAU,CAAE,GAAI,GAAS,CACpI,CACF,EAAoB,YAAc,sBAElC,MAAM,GAAA,EAAA,EAAA,OAAoB,CAAE,YAAW,GAAG,MACjC,EAAA,EAAA,KAAC,KAAA,CAAG,YAAU,eAAe,eAAa,OAAO,WAAA,EAAA,EAAA,IAAc,qCAAsC,EAAU,CAAE,GAAI,GAAS,CACrI,CACF,EAAY,YAAc,cAE1B,MAAM,GAAA,EAAA,EAAA,OAAwB,CAAE,YAAW,GAAG,MACrC,EAAA,EAAA,KAAC,KAAA,CAAG,YAAU,oBAAoB,eAAa,YAAY,WAAA,EAAA,EAAA,IAAc,2BAA4B,EAAU,CAAE,GAAI,GAAS,CACrI,CACF,EAAgB,YAAc,kBAE9B,MAAM,GAAA,EAAA,EAAA,KACJ,CACE,mBACA,iBACA,iCACA,gDACA,iCACA,2DACA,iEACA,mDACA,sDACA,6DACA,sFACA,mGACA,iHACA,kCACA,+BACD,CACD,CACE,SAAU,CACR,QAAS,CACP,QAAS,kEACT,QACE,+KACH,CACD,KAAM,CACJ,QAAS,eACT,GAAI,cACJ,GAAI,kDACL,CACF,CACD,gBAAiB,CACf,QAAS,UACT,KAAM,UACP,CACF,CACF,CAEK,GAAA,EAAA,EAAA,OACH,CACC,UAAU,GACV,WAAW,GACX,UAAU,UACV,OAAO,UACP,UACA,YACA,GAAG,KAMkD,CACrD,IAAM,EAAO,EAAUA,EAAAA,EAAO,SACxB,CAAE,WAAU,SAAU,GAAY,CAElC,GAAA,EAAA,EAAA,aACJ,GAAS,CACP,EAAM,WAAW,CACjB,EAAM,gBAAgB,CACtB,EAAM,iBAAiB,EAEzB,CAAC,EAAM,QAAQ,CAChB,CAEK,GACJ,EAAA,EAAA,KAAC,EAAA,CACC,YAAU,sBACV,eAAa,cACb,YAAW,EACX,cAAa,EACb,WAAA,EAAA,EAAA,IAAc,EAA0B,CAAE,UAAS,OAAM,CAAC,CAAE,EAAU,CACtE,QAAS,EACT,GAAI,GACJ,CASJ,OANK,GAED,OAAO,GAAY,WACrB,EAAU,CAAE,SAAU,EAAS,GAI/B,EAAA,EAAA,MAACC,EAAAA,EAAAA,CAAAA,SAAAA,EACC,EAAA,EAAA,KAACC,EAAAA,EAAAA,CAAe,QAAA,YAAS,GAAwB,EACjD,EAAA,EAAA,KAACC,EAAAA,EAAAA,CAAe,KAAK,QAAQ,MAAM,SAAS,OAAQ,IAAU,aAAe,EAAU,GAAI,GAAW,CAAA,CAAA,CAC9F,EAVS,GAaxB,CACD,EAAkB,YAAc,oBC3chC,MAAaC,GAIP,CAAE,WAAU,qBAAoB,wBAAyB,CAC7D,GAAM,CAAE,iBAAkB,GAAY,CAEhC,GAAA,EAAA,EAAA,aACH,GAA4B,CAC3B,EAAM,gBAAgB,CACtB,EAAM,iBAAiB,CACvB,GAAe,EAEjB,CAAC,EAAc,CAChB,CAEK,GAAA,EAAA,EAAA,aACH,GAA4B,CAC3B,EAAM,gBAAgB,CACtB,EAAM,iBAAiB,CACvB,KAAsB,EAExB,CAAC,EAAmB,CACrB,CAEK,GAAA,EAAA,EAAA,aACH,GAA4B,CAC3B,EAAM,gBAAgB,CACtB,EAAM,iBAAiB,CACvB,KAAsB,EAExB,CAAC,EAAmB,CACrB,CAED,OACE,EAAA,EAAA,MAAC,SAAA,CACC,YAAU,oBACV,WAAA,EAAA,EAAA,IACE,UACA,sBACA,2DACA,kDACA,+BACA,kCACD,YAED,EAAA,EAAA,MAACC,EAAAA,EAAAA,CACC,eAAa,UACb,YAAU,kBACV,QAAQ,QACR,MAAM,QACN,KAAK,OACL,UAAU,+DACV,QAAS,aAET,EAAA,EAAA,KAACC,EAAAA,SAAAA,CAAS,UAAU,UAAA,CAAY,EAChC,EAAA,EAAA,KAAC,OAAA,CAAK,UAAU,mBAAU,kBAAqB,CAAA,EACxC,EAET,EAAA,EAAA,MAAC,MAAA,CAAI,UAAU,2CACb,EAAA,EAAA,KAAC,MAAA,CAAI,UAAU,gIACb,EAAA,EAAA,KAACC,EAAAA,iBAAAA,CAAiB,KAAM,GAAA,CAAM,EAC1B,EACN,EAAA,EAAA,MAAC,MAAA,CAAI,UAAU,yDACb,EAAA,EAAA,KAAC,OAAA,CAAK,UAAU,gCAAuB,oBAAuB,EAC9D,EAAA,EAAA,KAAC,OAAA,CAAK,UAAU,4BAAmB,oBAAuB,CAAA,EACtD,CAAA,EACF,EAEN,EAAA,EAAA,MAACC,EAAAA,EAAAA,CAAAA,SAAAA,EACC,EAAA,EAAA,KAACC,EAAAA,EAAAA,CAAoB,QAAA,aACnB,EAAA,EAAA,MAACJ,EAAAA,EAAAA,CAAO,YAAU,iBAAiB,QAAQ,QAAQ,MAAM,QAAQ,UAAU,0EACzE,EAAA,EAAA,KAACK,EAAAA,UAAAA,CAAU,UAAU,UAAA,CAAY,CAChC,EAAA,EACM,EACW,EACtB,EAAA,EAAA,KAACC,EAAAA,EAAAA,CAAoB,MAAM,gBACzB,EAAA,EAAA,MAACC,EAAAA,EAAAA,CAAAA,SAAAA,EACC,EAAA,EAAA,KAACC,EAAAA,EAAAA,CAAiB,QAAS,WAAgB,gBAA+B,EAC1E,EAAA,EAAA,KAACA,EAAAA,EAAAA,CAAiB,QAAS,WAAgB,mBAAkC,CAAA,CAAA,CAC3D,EACA,CAAA,CAAA,CACT,GACR,EC9BP,GAAA,EAAA,EAAA,OAAwE,CAAE,KAAI,QAAO,OAAM,kBAAiB,cAChH,EAAA,EAAA,KAAC,EAAA,CAAA,UACC,EAAA,EAAA,MAAC,EAAA,CAAkB,SAAU,IAAO,EAA0B,oBAC3D,EACA,EAAA,EACiB,CAAA,CACJ,CAClB,CACF,EAAwB,YAAc,0BAEtC,MAAM,GAAA,EAAA,EAAA,OAA8E,CAAE,KAAI,QAAO,eAC/F,EAAA,EAAA,MAAC,EAAA,CAAA,SAAA,EACC,EAAA,EAAA,KAAC,EAAA,CAAA,SAAmB,EAAA,CAA0B,EAC9C,EAAA,EAAA,KAAC,EAAA,CAAA,UACC,EAAA,EAAA,KAAC,EAAA,CAAa,WAAA,CAAuB,CAAA,CACjB,CAAA,CAAA,CACT,CACf,CACF,EAAoB,YAAc,sBA6BlC,MAAaC,GAAgE,CAC3E,WACA,kBACA,UACA,WACA,qBACA,qBACA,WACA,cAAc,UACd,YAAY,eAAe,IAAI,MAAM,CAAC,aAAa,CAAC,aAChD,CACJ,IAAM,EAAS,GAAS,cAAgB,EAAE,CAE1C,OACE,EAAA,EAAA,MAAC,EAAA,CAAA,SAAA,EACC,EAAA,EAAA,KAAC,EAAA,CAA0B,WAA8B,qBAAwC,sBAAsB,EACvH,EAAA,EAAA,MAAC,EAAA,CAAiB,QAAQ,QAAQ,YAAY,kBAC5C,EAAA,EAAA,KAAC,EAAA,CAAA,SACE,EAAO,IAAI,IACV,EAAA,EAAA,KAAC,EAAA,CAAmC,GAAI,EAAM,GAAI,MAAO,EAAM,eAC5D,EAAM,MAAM,IAAI,IACf,EAAA,EAAA,KAAC,EAAA,CAEC,GAAI,EAAK,GACQ,kBACjB,MAAO,EAAK,MACZ,KAAM,EAAK,KACX,QAAS,EAAK,SALT,EAAK,GAMV,CACF,EAVsB,EAAM,GAWV,CACtB,CAAA,CACa,EACjB,EAAA,EAAA,KAAC,EAAA,CAAA,UACC,EAAA,EAAA,MAAC,EAAA,CAAA,SAAA,EACC,EAAA,EAAA,KAAC,EAAA,CAAA,UACC,EAAA,EAAA,MAAC,EAAA,CAAkB,UAAU,uBAAuB,QAAS,aAC3D,EAAA,EAAA,KAACC,EAAAA,WAAAA,CAAW,UAAU,0BAAA,CAA4B,CACjD,EAAA,EACiB,CAAA,CACJ,EAClB,EAAA,EAAA,KAAC,EAAA,CAAgB,UAAU,0CACzB,EAAA,EAAA,KAAC,IAAA,CAAE,UAAU,8DAAsD,GAAc,EACjE,CAAA,CAAA,CACN,CAAA,CACA,CAAA,EACC,EACnB,EAAA,EAAA,KAAC,EAAA,CAAe,WAAA,CAAyB,GACvB"}
@@ -1,2 +0,0 @@
1
- import{t as e}from"./dist-BQGL-YKY.mjs";import{t}from"./button-CfPTDyoq.mjs";import{i as n,n as r,r as i,t as a}from"./tooltip-BfBJRYpc.mjs";import{t as o}from"./separator-C6s-YvlT.mjs";import{i as s,o as c,r as l,s as u,t as d}from"./sheet-Cj8hoftE.mjs";import{a as f,h as p,i as m,r as h,t as g}from"./dropdown-menu-C6tRSumY.mjs";import{t as _}from"./input-5gk-Jv1y.mjs";import{EarthIcon as v,LogOutIcon as y,MenuIcon as b,ShoppingCartIcon as x}from"lucide-react";import{createContext as S,memo as C,useCallback as w,useContext as T,useEffect as E,useMemo as D,useState as O}from"react";import{cn as k}from"@customafk/react-toolkit/utils";import{cva as A}from"class-variance-authority";import{jsx as j,jsxs as M}from"react/jsx-runtime";import{useIsMobile as N}from"@customafk/react-toolkit/hooks/useMobile";const P=S(null);function F(){let e=T(P);if(!e)throw Error(`useSidebar must be used within a SidebarProvider.`);return e}function I({defaultOpen:e=!0,open:t,onOpenChange:n,className:r,style:a,children:o,...s}){let c=N(),[l,u]=O(!1),[d,f]=O(e),p=t??d,m=w(e=>{let t=typeof e==`function`?e(p):e;n?n(t):f(t),document.cookie=`sidebar_state=${t}; path=/; max-age=604800`},[n,p]),h=w(()=>c?u(e=>!e):m(e=>!e),[c,m]);E(()=>{let e=e=>{e.key===`b`&&(e.metaKey||e.ctrlKey)&&(e.preventDefault(),h())};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[h]);let g=p?`expanded`:`collapsed`,_=D(()=>({state:g,open:p,setOpen:m,isMobile:c,openMobile:l,setOpenMobile:u,toggleSidebar:h}),[g,p,m,c,l,h]);return j(P.Provider,{value:_,children:j(i,{delayDuration:0,children:j(`section`,{"data-slot":`layout-wrapper`,style:{"--sidebar-width":`16rem`,"--sidebar-width-icon":`3rem`,...a},className:k(`relative group/sidebar-wrapper flex h-dvh bg-sidebar`,r),...s,children:o})})})}const L=C(({side:e=`left`,variant:n=`sidebar`,collapsible:r=`offcanvas`,className:i,children:a,...o})=>{let{isMobile:f,state:p,openMobile:m,setOpenMobile:h,toggleSidebar:g}=F(),_=w(e=>{g(),e.preventDefault(),e.stopPropagation()},[g]);return r===`none`?j(`aside`,{"data-slot":`sidebar`,className:k(`flex w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground`,i),...o,children:a}):f?j(d,{open:m,onOpenChange:h,...o,children:M(l,{"data-sidebar":`sidebar`,"data-slot":`sidebar`,"data-mobile":`true`,style:{"--sidebar-width":`18rem`},side:e,className:`w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground sm:max-w-3xs [&>button]:hidden`,children:[M(c,{className:`sr-only`,children:[j(u,{children:`Sidebar`}),j(s,{children:`Displays the mobile sidebar.`})]}),M(`div`,{className:`flex size-full flex-col`,children:[M(`div`,{className:`flex flex-0 items-center gap-x-2 border-b border-border-weak p-2 pr-4`,children:[M(t,{"data-sidebar":`trigger`,"data-slot":`sidebar-trigger`,variant:`ghost`,color:`muted`,size:`icon`,className:k(`size-10 rounded-full`,i),onClick:_,children:[j(b,{className:`size-6!`}),j(`span`,{className:`sr-only`,children:`Toggle Sidebar`})]}),j(`div`,{className:`ml-2 flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground`,children:j(x,{size:20})}),M(`div`,{className:`grid flex-1 text-left text-sm leading-tight`,children:[j(`span`,{className:`truncate font-medium`,children:`Lunas Store`}),j(`span`,{className:`truncate text-xs`,children:`Established 2023`})]})]}),j(`div`,{className:`flex flex-1 flex-col p-2`,children:a})]})]})}):M(`aside`,{className:`group peer hidden bg-card text-sidebar-foreground md:block`,"data-state":p,"data-collapsible":p===`collapsed`?r:``,"data-variant":n,"data-side":e,"data-slot":`sidebar`,children:[j(`div`,{"data-slot":`sidebar-gap`,className:k(`bg-transparent`,`transition-[width] duration-200 ease-linear`,`h-(--header-height) sm:h-[calc(var(--header-height)+0.5rem)]`,`w-(--sidebar-width)`,`group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]`)}),j(`div`,{"data-slot":`sidebar-container`,className:k(`hidden md:flex shadow-nav`,`fixed left-0 inset-y-0 p-2`,`top-[calc(var(--header-height)+0.5rem)] z-10`,`w-(--sidebar-width)`,`transition-all duration-200 ease-linear`,`group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]`,i),...o,children:j(`div`,{"data-sidebar":`sidebar`,"data-slot":`sidebar-inner`,className:`relative flex size-full flex-col`,children:a})})]})});L.displayName=`CMSLayoutSidebar`;const R=C(({className:e,children:t,...n})=>M(`main`,{"data-slot":`sidebar-inset`,className:k(`relative flex w-full flex-1 flex-col`,e),...n,children:[j(`div`,{className:`h-(--header-height) sm:h-[calc(var(--header-height)+0.5rem)]`}),j(`div`,{className:`relative flex-1 size-full overflow-auto`,children:t})]}));R.displayName=`CMSLayoutMain`;const z=C(({className:e,...t})=>j(_,{"data-slot":`sidebar-input`,"data-sidebar":`input`,className:k(`h-8 w-full bg-background shadow-none`,e),...t}));z.displayName=`SidebarInput`;const B=C(({className:e,...t})=>j(`div`,{"data-slot":`sidebar-header`,"data-sidebar":`header`,className:k(`flex flex-col gap-2 p-2`,e),...t}));B.displayName=`SidebarHeader`;const V=C(({className:e,...t})=>j(`div`,{"data-slot":`sidebar-footer`,"data-sidebar":`footer`,className:k(`flex flex-col gap-2`,e),...t}));V.displayName=`SidebarFooter`;const H=C(({className:e,...t})=>j(o,{"data-slot":`sidebar-separator`,"data-sidebar":`separator`,className:k(`mx-2 w-auto bg-sidebar-border`,e),...t}));H.displayName=`SidebarSeparator`;const U=C(({className:e,...t})=>j(`div`,{"data-slot":`sidebar-content`,"data-sidebar":`content`,className:k(`flex flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden`,e),...t}));U.displayName=`SidebarContent`;const W=C(({className:e,...t})=>j(`div`,{"data-slot":`sidebar-group`,"data-sidebar":`group`,className:k(`relative flex w-full flex-col`,e),...t}));W.displayName=`SidebarGroup`;const G=C(({className:t,asChild:n=!1,...r})=>j(n?e:`div`,{"data-slot":`sidebar-group-label`,"data-sidebar":`group-label`,className:k(`flex h-8 shrink-0 items-center rounded-md px-2 font-medium text-sidebar-foreground/70 text-xs outline-hidden ring-sidebar-ring transition-[margin,opacity,color] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0`,`group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0`,t),...r}));G.displayName=`SidebarGroupLabel`;const K=C(({className:e,...t})=>j(`div`,{"data-slot":`sidebar-group-content`,"data-sidebar":`group-content`,className:k(`w-full text-sm`,e),...t}));K.displayName=`SidebarGroupContent`;const q=C(({className:e,...t})=>j(`ul`,{"data-slot":`sidebar-menu`,"data-sidebar":`menu`,className:k(`flex w-full min-w-0 flex-col gap-1`,e),...t}));q.displayName=`SidebarMenu`;const J=C(({className:e,...t})=>j(`li`,{"data-slot":`sidebar-menu-item`,"data-sidebar":`menu-item`,className:k(`group/menu-item relative`,e),...t}));J.displayName=`SidebarMenuItem`;const Y=A([`peer/menu-button`,`cursor-pointer`,`flex w-full items-center gap-2`,`overflow-hidden rounded-md p-2 outline-hidden`,`truncate text-left font-normal`,`transition-[color,background-color,width,height,padding]`,`active:bg-sidebar-accent active:text-sidebar-accent-foreground`,`disabled:pointer-events-none disabled:opacity-50`,`group-has-data-[sidebar=menu-action]/menu-item:pr-8`,`aria-disabled:pointer-events-none aria-disabled:opacity-50`,`data-[active=true]:bg-sidebar-primary-muted data-[active=true]:text-sidebar-primary`,`data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground`,`group-data-[collapsible=icon]:size-12! group-data-[collapsible=icon]:p-3! group-data-[collapsible=icon]:gap-3!`,`[&>svg]:size-6 [&>svg]:shrink-0`,`[&>span:last-child]:truncate`],{variants:{variant:{default:`hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground`,outline:`bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]`},size:{default:`h-10 text-sm`,sm:`h-7 text-xs`,lg:`h-12 text-sm group-data-[collapsible=icon]:p-0!`}},defaultVariants:{variant:`default`,size:`default`}}),X=C(({asChild:t=!1,isActive:i=!1,variant:o=`default`,size:s=`default`,tooltip:c,className:l,...u})=>{let d=t?e:`button`,{isMobile:f,state:p}=F(),m=w(e=>{u.onClick?.(),e.preventDefault(),e.stopPropagation()},[u.onClick]),h=j(d,{"data-slot":`sidebar-menu-button`,"data-sidebar":`menu-button`,"data-size":s,"data-active":i,className:k(Y({variant:o,size:s}),l),onClick:m,...u});return c?(typeof c==`string`&&(c={children:c}),M(a,{children:[j(n,{asChild:!0,children:h}),j(r,{side:`right`,align:`center`,hidden:p!==`collapsed`||f,...c})]})):h});X.displayName=`SidebarMenuButton`;const Z=({i18nText:e,onChangeToEnLocale:n,onChangeToViLocale:r})=>{let{toggleSidebar:i}=F(),a=w(e=>{e.preventDefault(),e.stopPropagation(),i()},[i]),o=w(e=>{e.preventDefault(),e.stopPropagation(),n?.()},[n]),s=w(e=>{e.preventDefault(),e.stopPropagation(),r?.()},[r]);return M(`header`,{"data-slot":`cms-layout-header`,className:k(`bg-card`,`h-(--header-height)`,`sm:h-[calc(var(--header-height)+0.5rem)] sm:px-4 sm:pr-6`,`absolute inset-x-0 top-0 z-20 gap-2 px-2 pr-4.5`,`flex items-center shadow-nav`,`transition-[height] ease-linear`),children:[M(t,{"data-sidebar":`trigger`,"data-slot":`sidebar-trigger`,variant:`ghost`,color:`muted`,size:`icon`,className:`size-10 rounded-full transition-all hover:text-text-positive`,onClick:a,children:[j(b,{className:`size-6!`}),j(`span`,{className:`sr-only`,children:`Toggle Sidebar`})]}),M(`div`,{className:`flex flex-1 gap-x-2 sm:ml-2.5`,children:[j(`div`,{className:`flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground`,children:j(x,{size:20})}),M(`div`,{className:`grid flex-1 text-left text-sm leading-tight`,children:[j(`span`,{className:`truncate font-medium`,children:`Lunas Enterprise`}),j(`span`,{className:`truncate text-xs`,children:`Established 2025`})]})]}),M(g,{children:[j(p,{asChild:!0,children:M(t,{"data-slot":`locale-trigger`,variant:`ghost`,color:`muted`,className:`gap-x-1 rounded-full transition-all hover:text-text-positive`,children:[j(v,{className:`size-6!`}),e]})}),j(h,{align:`end`,children:M(m,{children:[j(f,{onClick:o,children:`EN - English`}),j(f,{onClick:s,children:`VI - Vietnamese`})]})})]})]})},Q=C(({id:e,label:t,icon:n,activeNavItemId:r,onClick:i})=>j(J,{children:M(X,{isActive:e===r,onClick:i,children:[n,t]})}));Q.displayName=`SidebarContentGroupItem`;const $=C(({id:e,label:t,children:n})=>M(W,{children:[j(G,{children:t}),j(K,{children:j(q,{children:n})})]}));$.displayName=`SidebarContentGroup`;const ee=({i18nText:e,activeNavItemId:t,sidebar:n,children:r,onChangeToEnLocale:i,onChangeToViLocale:a,onLogout:o,logoutLabel:s=`Log out`,copyright:c=`Copyright © ${new Date().getFullYear()}, Lunas.`})=>{let l=n?.groupcontent??[];return M(I,{children:[j(Z,{i18nText:e,onChangeToEnLocale:i,onChangeToViLocale:a}),M(L,{variant:`inset`,collapsible:`icon`,children:[j(U,{children:l.map(e=>j($,{id:e.id,label:e.label,children:e.items.map(e=>j(Q,{id:e.id,activeNavItemId:t,label:e.label,icon:e.icon,onClick:e.onClick},e.id))},e.id))}),j(V,{children:M(q,{children:[j(J,{children:M(X,{className:`border border-border`,onClick:o,children:[j(y,{className:`text-text-positive-weak`}),s]})}),j(J,{className:`mt-2 border-t border-t-border`,children:j(`p`,{className:`pt-2 text-center text-xs text-text-positive-subtle`,children:c})})]})})]}),j(R,{children:r})]})};export{ee as t};
2
- //# sourceMappingURL=cms-layout-C2-yysO2.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cms-layout-C2-yysO2.mjs","names":["open","CMSLayoutHeader: React.FC<{\n i18nText?: string;\n onChangeToEnLocale?: () => void;\n onChangeToViLocale?: () => void;\n}>","CMSLayout: React.FC<React.PropsWithChildren<CMSLayoutProps>>"],"sources":["../packages/components/layouts/cms-layout/components/sidebar.tsx","../packages/components/layouts/cms-layout/components/header.tsx","../packages/components/layouts/cms-layout/index.tsx"],"sourcesContent":["'use client';\n\nimport { createContext, memo, useCallback, useContext, useEffect, useMemo, useState } from 'react';\n\nimport { MenuIcon, PanelLeftIcon, ShoppingCartIcon } from 'lucide-react';\n\nimport { useIsMobile } from '@customafk/react-toolkit/hooks/useMobile';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Input } from '@/components/ui/input';\nimport { Separator } from '@/components/ui/separator';\nimport { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from '@/components/ui/sheet';\nimport { Skeleton } from '@/components/ui/skeleton';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';\n\nimport { Slot } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nconst SIDEBAR_COOKIE_NAME = 'sidebar_state';\nconst SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;\nconst SIDEBAR_WIDTH = '16rem';\nconst SIDEBAR_WIDTH_MOBILE = '18rem';\nconst SIDEBAR_WIDTH_ICON = '3rem';\nconst SIDEBAR_KEYBOARD_SHORTCUT = 'b';\n\ntype SidebarContextProps = {\n state: 'expanded' | 'collapsed';\n open: boolean;\n setOpen: (open: boolean) => void;\n openMobile: boolean;\n setOpenMobile: (open: boolean) => void;\n isMobile: boolean;\n toggleSidebar: () => void;\n};\n\nconst SidebarContext = createContext<SidebarContextProps | null>(null);\n\nfunction useSidebar() {\n const context = useContext(SidebarContext);\n if (!context) {\n throw new Error('useSidebar must be used within a SidebarProvider.');\n }\n return context;\n}\n\nfunction CMSLayoutProvider({\n defaultOpen = true,\n open: openProp,\n onOpenChange: setOpenProp,\n className,\n style,\n children,\n ...props\n}: React.ComponentProps<'div'> & {\n defaultOpen?: boolean;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n}) {\n const isMobile = useIsMobile();\n const [openMobile, setOpenMobile] = useState(false);\n\n const [_open, _setOpen] = useState(defaultOpen);\n const open = openProp ?? _open;\n const setOpen = useCallback(\n (value: boolean | ((value: boolean) => boolean)) => {\n const openState = typeof value === 'function' ? value(open) : value;\n if (setOpenProp) {\n setOpenProp(openState);\n } else {\n _setOpen(openState);\n }\n // biome-ignore lint/suspicious/noDocumentCookie: persists sidebar state across page loads\n document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;\n },\n [setOpenProp, open]\n );\n\n const toggleSidebar = useCallback(() => {\n return isMobile ? setOpenMobile(open => !open) : setOpen(open => !open);\n }, [isMobile, setOpen]);\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {\n event.preventDefault();\n toggleSidebar();\n }\n };\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [toggleSidebar]);\n\n const state = open ? 'expanded' : 'collapsed';\n\n const contextValue = useMemo<SidebarContextProps>(\n () => ({ state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar }),\n [state, open, setOpen, isMobile, openMobile, toggleSidebar]\n );\n\n return (\n <SidebarContext.Provider value={contextValue}>\n <TooltipProvider delayDuration={0}>\n <section\n data-slot=\"layout-wrapper\"\n style={{ '--sidebar-width': SIDEBAR_WIDTH, '--sidebar-width-icon': SIDEBAR_WIDTH_ICON, ...style } as React.CSSProperties}\n className={cn('relative group/sidebar-wrapper flex h-dvh bg-sidebar', className)}\n {...props}\n >\n {children}\n </section>\n </TooltipProvider>\n </SidebarContext.Provider>\n );\n}\n\nconst CMSLayoutSidebar = memo(\n ({\n side = 'left',\n variant = 'sidebar',\n collapsible = 'offcanvas',\n className,\n children,\n ...props\n }: React.ComponentProps<'div'> & {\n side?: 'left' | 'right';\n variant?: 'sidebar' | 'floating' | 'inset';\n collapsible?: 'offcanvas' | 'icon' | 'none';\n }) => {\n const { isMobile, state, openMobile, setOpenMobile, toggleSidebar } = useSidebar();\n\n const handleToggleSidebar = useCallback<React.MouseEventHandler<HTMLButtonElement>>(\n event => {\n toggleSidebar();\n event.preventDefault();\n event.stopPropagation();\n },\n [toggleSidebar]\n );\n\n if (collapsible === 'none') {\n return (\n <aside data-slot=\"sidebar\" className={cn('flex w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground', className)} {...props}>\n {children}\n </aside>\n );\n }\n\n if (isMobile) {\n return (\n <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>\n <SheetContent\n data-sidebar=\"sidebar\"\n data-slot=\"sidebar\"\n data-mobile=\"true\"\n style={{ '--sidebar-width': SIDEBAR_WIDTH_MOBILE } as React.CSSProperties}\n side={side}\n className=\"w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground sm:max-w-3xs [&>button]:hidden\"\n >\n <SheetHeader className=\"sr-only\">\n <SheetTitle>Sidebar</SheetTitle>\n <SheetDescription>Displays the mobile sidebar.</SheetDescription>\n </SheetHeader>\n <div className=\"flex size-full flex-col\">\n <div className=\"flex flex-0 items-center gap-x-2 border-b border-border-weak p-2 pr-4\">\n <Button\n data-sidebar=\"trigger\"\n data-slot=\"sidebar-trigger\"\n variant=\"ghost\"\n color=\"muted\"\n size=\"icon\"\n className={cn('size-10 rounded-full', className)}\n onClick={handleToggleSidebar}\n >\n <MenuIcon className=\"size-6!\" />\n <span className=\"sr-only\">Toggle Sidebar</span>\n </Button>\n <div className=\"ml-2 flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground\">\n <ShoppingCartIcon size={20} />\n </div>\n <div className=\"grid flex-1 text-left text-sm leading-tight\">\n <span className=\"truncate font-medium\">Lunas Store</span>\n <span className=\"truncate text-xs\">Established 2023</span>\n </div>\n </div>\n <div className=\"flex flex-1 flex-col p-2\">{children}</div>\n </div>\n </SheetContent>\n </Sheet>\n );\n }\n\n return (\n <aside\n className=\"group peer hidden bg-card text-sidebar-foreground md:block\"\n data-state={state}\n data-collapsible={state === 'collapsed' ? collapsible : ''}\n data-variant={variant}\n data-side={side}\n data-slot=\"sidebar\"\n >\n <div\n data-slot=\"sidebar-gap\"\n className={cn(\n 'bg-transparent',\n 'transition-[width] duration-200 ease-linear',\n 'h-(--header-height) sm:h-[calc(var(--header-height)+0.5rem)]',\n 'w-(--sidebar-width)',\n 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]'\n )}\n />\n <div\n data-slot=\"sidebar-container\"\n className={cn(\n 'hidden md:flex shadow-nav',\n 'fixed left-0 inset-y-0 p-2',\n 'top-[calc(var(--header-height)+0.5rem)] z-10',\n 'w-(--sidebar-width)',\n 'transition-all duration-200 ease-linear',\n 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]',\n className\n )}\n {...props}\n >\n <div data-sidebar=\"sidebar\" data-slot=\"sidebar-inner\" className=\"relative flex size-full flex-col\">\n {children}\n </div>\n </div>\n </aside>\n );\n }\n);\nCMSLayoutSidebar.displayName = 'CMSLayoutSidebar';\n\nfunction SidebarTrigger({ className, onClick, ...props }: React.ComponentProps<typeof Button>) {\n const { toggleSidebar } = useSidebar();\n\n return (\n <Button\n data-sidebar=\"trigger\"\n data-slot=\"sidebar-trigger\"\n variant=\"ghost\"\n size=\"icon\"\n className={cn('size-7', className)}\n onClick={event => {\n onClick?.(event);\n toggleSidebar();\n }}\n {...props}\n >\n <PanelLeftIcon />\n <span className=\"sr-only\">Toggle Sidebar</span>\n </Button>\n );\n}\n\nfunction SidebarRail({ className, ...props }: React.ComponentProps<'button'>) {\n const { toggleSidebar } = useSidebar();\n\n return (\n <button\n data-sidebar=\"rail\"\n data-slot=\"sidebar-rail\"\n aria-label=\"Toggle Sidebar\"\n tabIndex={-1}\n onClick={toggleSidebar}\n title=\"Toggle Sidebar\"\n className={cn(\n 'absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-0.5 hover:after:bg-sidebar-border group-data-[side=left]:-right-4 group-data-[side=right]:left-0 sm:flex',\n 'in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize',\n '[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize',\n 'group-data-[collapsible=offcanvas]:translate-x-0 hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:after:left-full',\n '[[data-side=left][data-collapsible=offcanvas]_&]:-right-2',\n '[[data-side=right][data-collapsible=offcanvas]_&]:-left-2',\n className\n )}\n {...props}\n />\n );\n}\n\nconst CMSLayoutMain = memo(({ className, children, ...props }: React.ComponentProps<'main'>) => {\n return (\n <main data-slot=\"sidebar-inset\" className={cn('relative flex w-full flex-1 flex-col', className)} {...props}>\n <div className=\"h-(--header-height) sm:h-[calc(var(--header-height)+0.5rem)]\" />\n <div className=\"relative flex-1 size-full overflow-auto\">{children}</div>\n </main>\n );\n});\nCMSLayoutMain.displayName = 'CMSLayoutMain';\n\nconst SidebarInput = memo(({ className, ...props }: React.ComponentProps<typeof Input>) => {\n return <Input data-slot=\"sidebar-input\" data-sidebar=\"input\" className={cn('h-8 w-full bg-background shadow-none', className)} {...props} />;\n});\nSidebarInput.displayName = 'SidebarInput';\n\nconst SidebarHeader = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"sidebar-header\" data-sidebar=\"header\" className={cn('flex flex-col gap-2 p-2', className)} {...props} />;\n});\nSidebarHeader.displayName = 'SidebarHeader';\n\nconst SidebarFooter = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"sidebar-footer\" data-sidebar=\"footer\" className={cn('flex flex-col gap-2', className)} {...props} />;\n});\nSidebarFooter.displayName = 'SidebarFooter';\n\nconst SidebarSeparator = memo(({ className, ...props }: React.ComponentProps<typeof Separator>) => {\n return <Separator data-slot=\"sidebar-separator\" data-sidebar=\"separator\" className={cn('mx-2 w-auto bg-sidebar-border', className)} {...props} />;\n});\nSidebarSeparator.displayName = 'SidebarSeparator';\n\nconst SidebarContent = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return (\n <div\n data-slot=\"sidebar-content\"\n data-sidebar=\"content\"\n className={cn('flex flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden', className)}\n {...props}\n />\n );\n});\nSidebarContent.displayName = 'SidebarContent';\n\nconst SidebarGroup = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"sidebar-group\" data-sidebar=\"group\" className={cn('relative flex w-full flex-col', className)} {...props} />;\n});\nSidebarGroup.displayName = 'SidebarGroup';\n\nconst SidebarGroupLabel = memo(({ className, asChild = false, ...props }: React.ComponentProps<'div'> & { asChild?: boolean }) => {\n const Comp = asChild ? Slot : 'div';\n\n return (\n <Comp\n data-slot=\"sidebar-group-label\"\n data-sidebar=\"group-label\"\n className={cn(\n 'flex h-8 shrink-0 items-center rounded-md px-2 font-medium text-sidebar-foreground/70 text-xs outline-hidden ring-sidebar-ring transition-[margin,opacity,color] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',\n 'group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0',\n className\n )}\n {...props}\n />\n );\n});\nSidebarGroupLabel.displayName = 'SidebarGroupLabel';\n\nfunction SidebarGroupAction({ className, asChild = false, ...props }: React.ComponentProps<'button'> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n data-slot=\"sidebar-group-action\"\n data-sidebar=\"group-action\"\n className={cn(\n 'absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-hidden ring-sidebar-ring transition-[background-color,color,transform] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2',\n '[&>svg]:size-4 [&>svg]:shrink-0',\n // Increases the hit area of the button on mobile.\n 'after:absolute after:-inset-2 md:after:hidden',\n 'group-data-[collapsible=icon]:hidden',\n className\n )}\n {...props}\n />\n );\n}\n\nconst SidebarGroupContent = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"sidebar-group-content\" data-sidebar=\"group-content\" className={cn('w-full text-sm', className)} {...props} />;\n});\nSidebarGroupContent.displayName = 'SidebarGroupContent';\n\nconst SidebarMenu = memo(({ className, ...props }: React.ComponentProps<'ul'>) => {\n return <ul data-slot=\"sidebar-menu\" data-sidebar=\"menu\" className={cn('flex w-full min-w-0 flex-col gap-1', className)} {...props} />;\n});\nSidebarMenu.displayName = 'SidebarMenu';\n\nconst SidebarMenuItem = memo(({ className, ...props }: React.ComponentProps<'li'>) => {\n return <li data-slot=\"sidebar-menu-item\" data-sidebar=\"menu-item\" className={cn('group/menu-item relative', className)} {...props} />;\n});\nSidebarMenuItem.displayName = 'SidebarMenuItem';\n\nconst sidebarMenuButtonVariants = cva(\n [\n 'peer/menu-button',\n 'cursor-pointer',\n 'flex w-full items-center gap-2',\n 'overflow-hidden rounded-md p-2 outline-hidden',\n 'truncate text-left font-normal',\n 'transition-[color,background-color,width,height,padding]',\n 'active:bg-sidebar-accent active:text-sidebar-accent-foreground',\n 'disabled:pointer-events-none disabled:opacity-50',\n 'group-has-data-[sidebar=menu-action]/menu-item:pr-8',\n 'aria-disabled:pointer-events-none aria-disabled:opacity-50',\n 'data-[active=true]:bg-sidebar-primary-muted data-[active=true]:text-sidebar-primary',\n 'data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground',\n 'group-data-[collapsible=icon]:size-12! group-data-[collapsible=icon]:p-3! group-data-[collapsible=icon]:gap-3!',\n '[&>svg]:size-6 [&>svg]:shrink-0',\n '[&>span:last-child]:truncate',\n ],\n {\n variants: {\n variant: {\n default: 'hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground',\n outline:\n 'bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]',\n },\n size: {\n default: 'h-10 text-sm',\n sm: 'h-7 text-xs',\n lg: 'h-12 text-sm group-data-[collapsible=icon]:p-0!',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n }\n);\n\nconst SidebarMenuButton = memo(\n ({\n asChild = false,\n isActive = false,\n variant = 'default',\n size = 'default',\n tooltip,\n className,\n ...props\n }: React.ComponentProps<'button'> & {\n asChild?: boolean;\n isActive?: boolean;\n tooltip?: string | React.ComponentProps<typeof TooltipContent>;\n onClick?: () => void;\n } & VariantProps<typeof sidebarMenuButtonVariants>) => {\n const Comp = asChild ? Slot : 'button';\n const { isMobile, state } = useSidebar();\n\n const handleClick = useCallback<React.MouseEventHandler<HTMLButtonElement>>(\n event => {\n props.onClick?.();\n event.preventDefault();\n event.stopPropagation();\n },\n [props.onClick]\n );\n\n const button = (\n <Comp\n data-slot=\"sidebar-menu-button\"\n data-sidebar=\"menu-button\"\n data-size={size}\n data-active={isActive}\n className={cn(sidebarMenuButtonVariants({ variant, size }), className)}\n onClick={handleClick}\n {...props}\n />\n );\n\n if (!tooltip) return button;\n\n if (typeof tooltip === 'string') {\n tooltip = { children: tooltip };\n }\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>{button}</TooltipTrigger>\n <TooltipContent side=\"right\" align=\"center\" hidden={state !== 'collapsed' || isMobile} {...tooltip} />\n </Tooltip>\n );\n }\n);\nSidebarMenuButton.displayName = 'SidebarMenuButton';\n\nfunction SidebarMenuAction({\n className,\n asChild = false,\n showOnHover = false,\n ...props\n}: React.ComponentProps<'button'> & {\n asChild?: boolean;\n showOnHover?: boolean;\n}) {\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n data-slot=\"sidebar-menu-action\"\n data-sidebar=\"menu-action\"\n className={cn(\n 'absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-hidden ring-sidebar-ring transition-[background-color,color,opacity] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-sidebar-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0',\n // Increases the hit area of the button on mobile.\n 'after:absolute after:-inset-2 md:after:hidden',\n 'peer-data-[size=sm]/menu-button:top-1',\n 'peer-data-[size=default]/menu-button:top-1.5',\n 'peer-data-[size=lg]/menu-button:top-2.5',\n 'group-data-[collapsible=icon]:hidden',\n showOnHover &&\n 'group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground md:opacity-0',\n className\n )}\n {...props}\n />\n );\n}\n\nfunction SidebarMenuBadge({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"sidebar-menu-badge\"\n data-sidebar=\"menu-badge\"\n className={cn(\n 'pointer-events-none absolute right-1 flex h-5 min-w-5 select-none items-center justify-center rounded-md px-1 font-medium text-sidebar-foreground text-xs tabular-nums transition-colors',\n 'peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground',\n 'peer-data-[size=sm]/menu-button:top-1',\n 'peer-data-[size=default]/menu-button:top-1.5',\n 'peer-data-[size=lg]/menu-button:top-2.5',\n 'group-data-[collapsible=icon]:hidden',\n className\n )}\n {...props}\n />\n );\n}\n\nfunction SidebarMenuSkeleton({\n className,\n showIcon = false,\n ...props\n}: React.ComponentProps<'div'> & {\n showIcon?: boolean;\n}) {\n const width = useMemo(() => `${Math.floor(Math.random() * 40) + 50}%`, []);\n\n return (\n <div data-slot=\"sidebar-menu-skeleton\" data-sidebar=\"menu-skeleton\" className={cn('flex h-8 items-center gap-2 rounded-md px-2', className)} {...props}>\n {showIcon && <Skeleton className=\"size-4 rounded-md\" data-sidebar=\"menu-skeleton-icon\" />}\n <Skeleton\n className=\"h-4 max-w-(--skeleton-width) flex-1\"\n data-sidebar=\"menu-skeleton-text\"\n style={{ '--skeleton-width': width } as React.CSSProperties}\n />\n </div>\n );\n}\n\nfunction SidebarMenuSub({ className, ...props }: React.ComponentProps<'ul'>) {\n return (\n <ul\n data-slot=\"sidebar-menu-sub\"\n data-sidebar=\"menu-sub\"\n className={cn(\n 'mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5',\n 'group-data-[collapsible=icon]:hidden',\n className\n )}\n {...props}\n />\n );\n}\n\nfunction SidebarMenuSubItem({ className, ...props }: React.ComponentProps<'li'>) {\n return <li data-slot=\"sidebar-menu-sub-item\" data-sidebar=\"menu-sub-item\" className={cn('group/menu-sub-item relative', className)} {...props} />;\n}\n\nfunction SidebarMenuSubButton({\n asChild = false,\n size = 'md',\n isActive = false,\n className,\n ...props\n}: React.ComponentProps<'a'> & {\n asChild?: boolean;\n size?: 'sm' | 'md';\n isActive?: boolean;\n}) {\n const Comp = asChild ? Slot : 'a';\n\n return (\n <Comp\n data-slot=\"sidebar-menu-sub-button\"\n data-sidebar=\"menu-sub-button\"\n data-size={size}\n data-active={isActive}\n className={cn(\n 'flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground outline-hidden ring-sidebar-ring transition-[background-color,color] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground',\n 'data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground',\n size === 'sm' && 'text-xs',\n size === 'md' && 'text-sm',\n 'group-data-[collapsible=icon]:hidden',\n className\n )}\n {...props}\n />\n );\n}\n\nexport {\n CMSLayoutSidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarInput,\n CMSLayoutMain,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSkeleton,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n CMSLayoutProvider,\n SidebarRail,\n SidebarSeparator,\n SidebarTrigger,\n // biome-ignore lint/style/useComponentExportOnlyModules: true\n useSidebar,\n};\n","'use client';\n\nimport { useCallback } from 'react';\n\nimport { EarthIcon, MenuIcon, ShoppingCartIcon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu';\n\nimport { useSidebar } from './sidebar';\n\nexport const CMSLayoutHeader: React.FC<{\n i18nText?: string;\n onChangeToEnLocale?: () => void;\n onChangeToViLocale?: () => void;\n}> = ({ i18nText, onChangeToEnLocale, onChangeToViLocale }) => {\n const { toggleSidebar } = useSidebar();\n\n const handleToggleSidebar = useCallback(\n (event: React.MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n toggleSidebar();\n },\n [toggleSidebar]\n );\n\n const handleEnLocale = useCallback(\n (event: React.MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n onChangeToEnLocale?.();\n },\n [onChangeToEnLocale]\n );\n\n const handleViLocale = useCallback(\n (event: React.MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n onChangeToViLocale?.();\n },\n [onChangeToViLocale]\n );\n\n return (\n <header\n data-slot=\"cms-layout-header\"\n className={cn(\n 'bg-card',\n 'h-(--header-height)',\n 'sm:h-[calc(var(--header-height)+0.5rem)] sm:px-4 sm:pr-6',\n 'absolute inset-x-0 top-0 z-20 gap-2 px-2 pr-4.5',\n 'flex items-center shadow-nav',\n 'transition-[height] ease-linear'\n )}\n >\n <Button\n data-sidebar=\"trigger\"\n data-slot=\"sidebar-trigger\"\n variant=\"ghost\"\n color=\"muted\"\n size=\"icon\"\n className=\"size-10 rounded-full transition-all hover:text-text-positive\"\n onClick={handleToggleSidebar}\n >\n <MenuIcon className=\"size-6!\" />\n <span className=\"sr-only\">Toggle Sidebar</span>\n </Button>\n\n <div className=\"flex flex-1 gap-x-2 sm:ml-2.5\">\n <div className=\"flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground\">\n <ShoppingCartIcon size={20} />\n </div>\n <div className=\"grid flex-1 text-left text-sm leading-tight\">\n <span className=\"truncate font-medium\">Lunas Enterprise</span>\n <span className=\"truncate text-xs\">Established 2025</span>\n </div>\n </div>\n\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button data-slot=\"locale-trigger\" variant=\"ghost\" color=\"muted\" className=\"gap-x-1 rounded-full transition-all hover:text-text-positive\">\n <EarthIcon className=\"size-6!\" />\n {i18nText}\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuGroup>\n <DropdownMenuItem onClick={handleEnLocale}>EN - English</DropdownMenuItem>\n <DropdownMenuItem onClick={handleViLocale}>VI - Vietnamese</DropdownMenuItem>\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n </header>\n );\n};\n","'use client';\n\nimport { memo } from 'react';\n\nimport { LogOutIcon } from 'lucide-react';\n\nimport { CMSLayoutHeader } from './components/header';\nimport {\n CMSLayoutSidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n CMSLayoutMain,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n CMSLayoutProvider,\n} from './components/sidebar';\n\ntype NavItem = {\n /** Unique identifier for the nav item, used as React key and for active-state comparison. */\n id: string;\n /** Human-readable label rendered inside the sidebar button. */\n label: string;\n /** Optional icon element rendered to the left of the label. */\n icon?: React.ReactNode;\n /** Callback fired when the sidebar button is clicked. */\n onClick?: () => void;\n};\n\ntype NavGroup = {\n /** Unique identifier for the group, used as React key. */\n id: string;\n /** Optional section heading rendered above the group's items. */\n label?: string;\n /** Navigation items that belong to this group. */\n items: NavItem[];\n};\n\nexport type CMSLayoutProps = {\n /** Text label used by the header for language-toggle or i18n display. */\n i18nText?: string;\n /** ID of the currently active navigation item; matched against `NavItem.id` to highlight the active button. */\n activeNavItemId?: string;\n /** Sidebar navigation definition; omitting this prop renders an empty sidebar. */\n sidebar?: { groupcontent: NavGroup[] };\n /** Callback fired when the logout button is clicked. */\n onLogout?: () => void;\n /** Callback fired when the user switches the UI locale to English. */\n onChangeToEnLocale?: () => void;\n /** Callback fired when the user switches the UI locale to Vietnamese. */\n onChangeToViLocale?: () => void;\n /**\n * Label displayed on the logout button.\n * @default 'Log out'\n */\n logoutLabel?: string;\n /**\n * Copyright string shown at the bottom of the sidebar.\n * @default `Copyright © <current year>, Lunas.`\n */\n copyright?: string;\n};\n\nconst SidebarContentGroupItem = memo<NavItem & { activeNavItemId?: string }>(({ id, label, icon, activeNavItemId, onClick }) => (\n <SidebarMenuItem>\n <SidebarMenuButton isActive={id === activeNavItemId} onClick={onClick}>\n {icon}\n {label}\n </SidebarMenuButton>\n </SidebarMenuItem>\n));\nSidebarContentGroupItem.displayName = 'SidebarContentGroupItem';\n\nconst SidebarContentGroup = memo<React.PropsWithChildren<Omit<NavGroup, 'items'>>>(({ id, label, children }) => (\n <SidebarGroup>\n <SidebarGroupLabel>{label}</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>{children}</SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n));\nSidebarContentGroup.displayName = 'SidebarContentGroup';\n\n/**\n * Full-page CMS application shell with a collapsible inset sidebar, header, and main content area.\n *\n * @example\n * ```tsx\n * import { CMSLayout } from '@customafk/lunas-ui/layouts/cms-layout';\n * import { LayoutDashboardIcon } from 'lucide-react';\n *\n * <CMSLayout\n * activeNavItemId=\"dashboard\"\n * sidebar={{\n * groupcontent: [\n * {\n * id: 'main',\n * label: 'Main',\n * items: [\n * { id: 'dashboard', label: 'Dashboard', icon: <LayoutDashboardIcon />, onClick: () => router.push('/') },\n * ],\n * },\n * ],\n * }}\n * onLogout={() => signOut()}\n * >\n * <DashboardPage />\n * </CMSLayout>\n * ```\n */\nexport const CMSLayout: React.FC<React.PropsWithChildren<CMSLayoutProps>> = ({\n i18nText,\n activeNavItemId,\n sidebar,\n children,\n onChangeToEnLocale,\n onChangeToViLocale,\n onLogout,\n logoutLabel = 'Log out',\n copyright = `Copyright © ${new Date().getFullYear()}, Lunas.`,\n}) => {\n const groups = sidebar?.groupcontent ?? [];\n\n return (\n <CMSLayoutProvider>\n <CMSLayoutHeader i18nText={i18nText} onChangeToEnLocale={onChangeToEnLocale} onChangeToViLocale={onChangeToViLocale} />\n <CMSLayoutSidebar variant=\"inset\" collapsible=\"icon\">\n <SidebarContent>\n {groups.map(group => (\n <SidebarContentGroup key={group.id} id={group.id} label={group.label}>\n {group.items.map(item => (\n <SidebarContentGroupItem\n key={item.id}\n id={item.id}\n activeNavItemId={activeNavItemId}\n label={item.label}\n icon={item.icon}\n onClick={item.onClick}\n />\n ))}\n </SidebarContentGroup>\n ))}\n </SidebarContent>\n <SidebarFooter>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton className=\"border border-border\" onClick={onLogout}>\n <LogOutIcon className=\"text-text-positive-weak\" />\n {logoutLabel}\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem className=\"mt-2 border-t border-t-border\">\n <p className=\"pt-2 text-center text-xs text-text-positive-subtle\">{copyright}</p>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarFooter>\n </CMSLayoutSidebar>\n <CMSLayoutMain>{children}</CMSLayoutMain>\n </CMSLayoutProvider>\n );\n};\n"],"mappings":"yyBAmBA,MAiBM,EAAiB,EAA0C,KAAK,CAEtE,SAAS,GAAa,CACpB,IAAM,EAAU,EAAW,EAAe,CAC1C,GAAI,CAAC,EACH,MAAU,MAAM,oDAAoD,CAEtE,OAAO,EAGT,SAAS,EAAkB,CACzB,cAAc,GACd,KAAM,EACN,aAAc,EACd,YACA,QACA,WACA,GAAG,GAKF,CACD,IAAM,EAAW,GAAa,CACxB,CAAC,EAAY,GAAiB,EAAS,GAAM,CAE7C,CAAC,EAAO,GAAY,EAAS,EAAY,CACzC,EAAO,GAAY,EACnB,EAAU,EACb,GAAmD,CAClD,IAAM,EAAY,OAAO,GAAU,WAAa,EAAM,EAAK,CAAG,EAC1D,EACF,EAAY,EAAU,CAEtB,EAAS,EAAU,CAGrB,SAAS,OAAS,iBAA0B,EAAU,2BAExD,CAAC,EAAa,EAAK,CACpB,CAEK,EAAgB,MACb,EAAW,EAAc,GAAQ,CAACA,EAAK,CAAG,EAAQ,GAAQ,CAACA,EAAK,CACtE,CAAC,EAAU,EAAQ,CAAC,CAEvB,MAAgB,CACd,IAAM,EAAiB,GAAyB,CAC1C,EAAM,MAAQ,MAA8B,EAAM,SAAW,EAAM,WACrE,EAAM,gBAAgB,CACtB,GAAe,GAInB,OADA,OAAO,iBAAiB,UAAW,EAAc,KACpC,OAAO,oBAAoB,UAAW,EAAc,EAChE,CAAC,EAAc,CAAC,CAEnB,IAAM,EAAQ,EAAO,WAAa,YAE5B,EAAe,OACZ,CAAE,QAAO,OAAM,UAAS,WAAU,aAAY,gBAAe,gBAAe,EACnF,CAAC,EAAO,EAAM,EAAS,EAAU,EAAY,EAAc,CAC5D,CAED,OACE,EAAC,EAAe,SAAA,CAAS,MAAO,WAC9B,EAAC,EAAA,CAAgB,cAAe,WAC9B,EAAC,UAAA,CACC,YAAU,iBACV,MAAO,CAAE,kBAAmB,QAAe,uBAAwB,OAAoB,GAAG,EAAO,CACjG,UAAW,EAAG,uDAAwD,EAAU,CAChF,GAAI,EAEH,YACO,EACM,EACM,CAI9B,MAAM,EAAmB,GACtB,CACC,OAAO,OACP,UAAU,UACV,cAAc,YACd,YACA,WACA,GAAG,KAKC,CACJ,GAAM,CAAE,WAAU,QAAO,aAAY,gBAAe,iBAAkB,GAAY,CAE5E,EAAsB,EAC1B,GAAS,CACP,GAAe,CACf,EAAM,gBAAgB,CACtB,EAAM,iBAAiB,EAEzB,CAAC,EAAc,CAChB,CAsDD,OApDI,IAAgB,OAEhB,EAAC,QAAA,CAAM,YAAU,UAAU,UAAW,EAAG,uEAAwE,EAAU,CAAE,GAAI,EAC9H,YACK,CAIR,EAEA,EAAC,EAAA,CAAM,KAAM,EAAY,aAAc,EAAe,GAAI,WACxD,EAAC,EAAA,CACC,eAAa,UACb,YAAU,UACV,cAAY,OACZ,MAAO,CAAE,kBAAmB,QAAsB,CAC5C,OACN,UAAU,sGAEV,EAAC,EAAA,CAAY,UAAU,oBACrB,EAAC,EAAA,CAAA,SAAW,UAAA,CAAoB,CAChC,EAAC,EAAA,CAAA,SAAiB,+BAAA,CAA+C,CAAA,EACrD,CACd,EAAC,MAAA,CAAI,UAAU,oCACb,EAAC,MAAA,CAAI,UAAU,kFACb,EAAC,EAAA,CACC,eAAa,UACb,YAAU,kBACV,QAAQ,QACR,MAAM,QACN,KAAK,OACL,UAAW,EAAG,uBAAwB,EAAU,CAChD,QAAS,YAET,EAAC,EAAA,CAAS,UAAU,UAAA,CAAY,CAChC,EAAC,OAAA,CAAK,UAAU,mBAAU,kBAAqB,CAAA,EACxC,CACT,EAAC,MAAA,CAAI,UAAU,oIACb,EAAC,EAAA,CAAiB,KAAM,GAAA,CAAM,EAC1B,CACN,EAAC,MAAA,CAAI,UAAU,wDACb,EAAC,OAAA,CAAK,UAAU,gCAAuB,eAAkB,CACzD,EAAC,OAAA,CAAK,UAAU,4BAAmB,oBAAuB,CAAA,EACtD,GACF,CACN,EAAC,MAAA,CAAI,UAAU,2BAA4B,YAAe,CAAA,EACtD,CAAA,EACO,EACT,CAKV,EAAC,QAAA,CACC,UAAU,6DACV,aAAY,EACZ,mBAAkB,IAAU,YAAc,EAAc,GACxD,eAAc,EACd,YAAW,EACX,YAAU,oBAEV,EAAC,MAAA,CACC,YAAU,cACV,UAAW,EACT,iBACA,8CACA,+DACA,sBACA,mFACD,EACD,CACF,EAAC,MAAA,CACC,YAAU,oBACV,UAAW,EACT,4BACA,6BACA,+CACA,sBACA,0CACA,mFACA,EACD,CACD,GAAI,WAEJ,EAAC,MAAA,CAAI,eAAa,UAAU,YAAU,gBAAgB,UAAU,mCAC7D,YACG,EACF,CAAA,EACA,EAGb,CACD,EAAiB,YAAc,mBAiD/B,MAAM,EAAgB,GAAM,CAAE,YAAW,WAAU,GAAG,KAElD,EAAC,OAAA,CAAK,YAAU,gBAAgB,UAAW,EAAG,uCAAwC,EAAU,CAAE,GAAI,YACpG,EAAC,MAAA,CAAI,UAAU,+DAAA,CAAiE,CAChF,EAAC,MAAA,CAAI,UAAU,0CAA2C,YAAe,CAAA,EACpE,CAET,CACF,EAAc,YAAc,gBAE5B,MAAM,EAAe,GAAM,CAAE,YAAW,GAAG,KAClC,EAAC,EAAA,CAAM,YAAU,gBAAgB,eAAa,QAAQ,UAAW,EAAG,uCAAwC,EAAU,CAAE,GAAI,GAAS,CAC5I,CACF,EAAa,YAAc,eAE3B,MAAM,EAAgB,GAAM,CAAE,YAAW,GAAG,KACnC,EAAC,MAAA,CAAI,YAAU,iBAAiB,eAAa,SAAS,UAAW,EAAG,0BAA2B,EAAU,CAAE,GAAI,GAAS,CAC/H,CACF,EAAc,YAAc,gBAE5B,MAAM,EAAgB,GAAM,CAAE,YAAW,GAAG,KACnC,EAAC,MAAA,CAAI,YAAU,iBAAiB,eAAa,SAAS,UAAW,EAAG,sBAAuB,EAAU,CAAE,GAAI,GAAS,CAC3H,CACF,EAAc,YAAc,gBAE5B,MAAM,EAAmB,GAAM,CAAE,YAAW,GAAG,KACtC,EAAC,EAAA,CAAU,YAAU,oBAAoB,eAAa,YAAY,UAAW,EAAG,gCAAiC,EAAU,CAAE,GAAI,GAAS,CACjJ,CACF,EAAiB,YAAc,mBAE/B,MAAM,EAAiB,GAAM,CAAE,YAAW,GAAG,KAEzC,EAAC,MAAA,CACC,YAAU,kBACV,eAAa,UACb,UAAW,EAAG,yFAA0F,EAAU,CAClH,GAAI,GACJ,CAEJ,CACF,EAAe,YAAc,iBAE7B,MAAM,EAAe,GAAM,CAAE,YAAW,GAAG,KAClC,EAAC,MAAA,CAAI,YAAU,gBAAgB,eAAa,QAAQ,UAAW,EAAG,gCAAiC,EAAU,CAAE,GAAI,GAAS,CACnI,CACF,EAAa,YAAc,eAE3B,MAAM,EAAoB,GAAM,CAAE,YAAW,UAAU,GAAO,GAAG,KAI7D,EAHW,EAAU,EAAO,MAAA,CAI1B,YAAU,sBACV,eAAa,cACb,UAAW,EACT,iPACA,8EACA,EACD,CACD,GAAI,GACJ,CAEJ,CACF,EAAkB,YAAc,oBAsBhC,MAAM,EAAsB,GAAM,CAAE,YAAW,GAAG,KACzC,EAAC,MAAA,CAAI,YAAU,wBAAwB,eAAa,gBAAgB,UAAW,EAAG,iBAAkB,EAAU,CAAE,GAAI,GAAS,CACpI,CACF,EAAoB,YAAc,sBAElC,MAAM,EAAc,GAAM,CAAE,YAAW,GAAG,KACjC,EAAC,KAAA,CAAG,YAAU,eAAe,eAAa,OAAO,UAAW,EAAG,qCAAsC,EAAU,CAAE,GAAI,GAAS,CACrI,CACF,EAAY,YAAc,cAE1B,MAAM,EAAkB,GAAM,CAAE,YAAW,GAAG,KACrC,EAAC,KAAA,CAAG,YAAU,oBAAoB,eAAa,YAAY,UAAW,EAAG,2BAA4B,EAAU,CAAE,GAAI,GAAS,CACrI,CACF,EAAgB,YAAc,kBAE9B,MAAM,EAA4B,EAChC,CACE,mBACA,iBACA,iCACA,gDACA,iCACA,2DACA,iEACA,mDACA,sDACA,6DACA,sFACA,mGACA,iHACA,kCACA,+BACD,CACD,CACE,SAAU,CACR,QAAS,CACP,QAAS,kEACT,QACE,+KACH,CACD,KAAM,CACJ,QAAS,eACT,GAAI,cACJ,GAAI,kDACL,CACF,CACD,gBAAiB,CACf,QAAS,UACT,KAAM,UACP,CACF,CACF,CAEK,EAAoB,GACvB,CACC,UAAU,GACV,WAAW,GACX,UAAU,UACV,OAAO,UACP,UACA,YACA,GAAG,KAMkD,CACrD,IAAM,EAAO,EAAU,EAAO,SACxB,CAAE,WAAU,SAAU,GAAY,CAElC,EAAc,EAClB,GAAS,CACP,EAAM,WAAW,CACjB,EAAM,gBAAgB,CACtB,EAAM,iBAAiB,EAEzB,CAAC,EAAM,QAAQ,CAChB,CAEK,EACJ,EAAC,EAAA,CACC,YAAU,sBACV,eAAa,cACb,YAAW,EACX,cAAa,EACb,UAAW,EAAG,EAA0B,CAAE,UAAS,OAAM,CAAC,CAAE,EAAU,CACtE,QAAS,EACT,GAAI,GACJ,CASJ,OANK,GAED,OAAO,GAAY,WACrB,EAAU,CAAE,SAAU,EAAS,EAI/B,EAAC,EAAA,CAAA,SAAA,CACC,EAAC,EAAA,CAAe,QAAA,YAAS,GAAwB,CACjD,EAAC,EAAA,CAAe,KAAK,QAAQ,MAAM,SAAS,OAAQ,IAAU,aAAe,EAAU,GAAI,GAAW,CAAA,CAAA,CAC9F,EAVS,GAaxB,CACD,EAAkB,YAAc,oBC3chC,MAAaC,GAIP,CAAE,WAAU,qBAAoB,wBAAyB,CAC7D,GAAM,CAAE,iBAAkB,GAAY,CAEhC,EAAsB,EACzB,GAA4B,CAC3B,EAAM,gBAAgB,CACtB,EAAM,iBAAiB,CACvB,GAAe,EAEjB,CAAC,EAAc,CAChB,CAEK,EAAiB,EACpB,GAA4B,CAC3B,EAAM,gBAAgB,CACtB,EAAM,iBAAiB,CACvB,KAAsB,EAExB,CAAC,EAAmB,CACrB,CAEK,EAAiB,EACpB,GAA4B,CAC3B,EAAM,gBAAgB,CACtB,EAAM,iBAAiB,CACvB,KAAsB,EAExB,CAAC,EAAmB,CACrB,CAED,OACE,EAAC,SAAA,CACC,YAAU,oBACV,UAAW,EACT,UACA,sBACA,2DACA,kDACA,+BACA,kCACD,WAED,EAAC,EAAA,CACC,eAAa,UACb,YAAU,kBACV,QAAQ,QACR,MAAM,QACN,KAAK,OACL,UAAU,+DACV,QAAS,YAET,EAAC,EAAA,CAAS,UAAU,UAAA,CAAY,CAChC,EAAC,OAAA,CAAK,UAAU,mBAAU,kBAAqB,CAAA,EACxC,CAET,EAAC,MAAA,CAAI,UAAU,0CACb,EAAC,MAAA,CAAI,UAAU,+HACb,EAAC,EAAA,CAAiB,KAAM,GAAA,CAAM,EAC1B,CACN,EAAC,MAAA,CAAI,UAAU,wDACb,EAAC,OAAA,CAAK,UAAU,gCAAuB,oBAAuB,CAC9D,EAAC,OAAA,CAAK,UAAU,4BAAmB,oBAAuB,CAAA,EACtD,CAAA,EACF,CAEN,EAAC,EAAA,CAAA,SAAA,CACC,EAAC,EAAA,CAAoB,QAAA,YACnB,EAAC,EAAA,CAAO,YAAU,iBAAiB,QAAQ,QAAQ,MAAM,QAAQ,UAAU,yEACzE,EAAC,EAAA,CAAU,UAAU,UAAA,CAAY,CAChC,EAAA,EACM,EACW,CACtB,EAAC,EAAA,CAAoB,MAAM,eACzB,EAAC,EAAA,CAAA,SAAA,CACC,EAAC,EAAA,CAAiB,QAAS,WAAgB,gBAA+B,CAC1E,EAAC,EAAA,CAAiB,QAAS,WAAgB,mBAAkC,CAAA,CAAA,CAC3D,EACA,CAAA,CAAA,CACT,GACR,EC9BP,EAA0B,GAA8C,CAAE,KAAI,QAAO,OAAM,kBAAiB,aAChH,EAAC,EAAA,CAAA,SACC,EAAC,EAAA,CAAkB,SAAU,IAAO,EAA0B,oBAC3D,EACA,EAAA,EACiB,CAAA,CACJ,CAClB,CACF,EAAwB,YAAc,0BAEtC,MAAM,EAAsB,GAAwD,CAAE,KAAI,QAAO,cAC/F,EAAC,EAAA,CAAA,SAAA,CACC,EAAC,EAAA,CAAA,SAAmB,EAAA,CAA0B,CAC9C,EAAC,EAAA,CAAA,SACC,EAAC,EAAA,CAAa,WAAA,CAAuB,CAAA,CACjB,CAAA,CAAA,CACT,CACf,CACF,EAAoB,YAAc,sBA6BlC,MAAaC,IAAgE,CAC3E,WACA,kBACA,UACA,WACA,qBACA,qBACA,WACA,cAAc,UACd,YAAY,eAAe,IAAI,MAAM,CAAC,aAAa,CAAC,aAChD,CACJ,IAAM,EAAS,GAAS,cAAgB,EAAE,CAE1C,OACE,EAAC,EAAA,CAAA,SAAA,CACC,EAAC,EAAA,CAA0B,WAA8B,qBAAwC,sBAAsB,CACvH,EAAC,EAAA,CAAiB,QAAQ,QAAQ,YAAY,iBAC5C,EAAC,EAAA,CAAA,SACE,EAAO,IAAI,GACV,EAAC,EAAA,CAAmC,GAAI,EAAM,GAAI,MAAO,EAAM,eAC5D,EAAM,MAAM,IAAI,GACf,EAAC,EAAA,CAEC,GAAI,EAAK,GACQ,kBACjB,MAAO,EAAK,MACZ,KAAM,EAAK,KACX,QAAS,EAAK,SALT,EAAK,GAMV,CACF,EAVsB,EAAM,GAWV,CACtB,CAAA,CACa,CACjB,EAAC,EAAA,CAAA,SACC,EAAC,EAAA,CAAA,SAAA,CACC,EAAC,EAAA,CAAA,SACC,EAAC,EAAA,CAAkB,UAAU,uBAAuB,QAAS,YAC3D,EAAC,EAAA,CAAW,UAAU,0BAAA,CAA4B,CACjD,EAAA,EACiB,CAAA,CACJ,CAClB,EAAC,EAAA,CAAgB,UAAU,yCACzB,EAAC,IAAA,CAAE,UAAU,8DAAsD,GAAc,EACjE,CAAA,CAAA,CACN,CAAA,CACA,CAAA,EACC,CACnB,EAAC,EAAA,CAAe,WAAA,CAAyB,GACvB"}
@@ -1,2 +0,0 @@
1
- import*as e from"react";function t(e,t){if(typeof e==`function`)return e(t);e!=null&&(e.current=t)}function n(...e){return n=>{let r=!1,i=e.map(e=>{let i=t(e,n);return!r&&typeof i==`function`&&(r=!0),i});if(r)return()=>{for(let n=0;n<i.length;n++){let r=i[n];typeof r==`function`?r():t(e[n],null)}}}}function r(...t){return e.useCallback(n(...t),t)}function i(t){let n=e.forwardRef((n,i)=>{let{children:a,...o}=n,d=null,p=!1,_=[];f(a)&&typeof g==`function`&&(a=g(a._payload)),e.Children.forEach(a,e=>{if(u(e)){p=!0;let t=e,n=`child`in t.props?t.props.child:t.props.children;f(n)&&typeof g==`function`&&(n=g(n._payload)),d=s(t,n),_.push(d?.props?.children)}else _.push(e)}),d?d=e.cloneElement(d,void 0,_):!p&&e.Children.count(a)===1&&e.isValidElement(a)&&(d=a);let v=d?l(d):void 0,y=r(i,v);if(!d){if(a||a===0)throw Error(p?h(t):m(t));return a}let b=c(o,d.props??{});return d.type!==e.Fragment&&(b.ref=i?y:v),e.cloneElement(d,b)});return n.displayName=`${t}.Slot`,n}var a=i(`Slot`),o=Symbol.for(`radix.slottable`),s=(t,n)=>{if(`child`in t.props){let n=t.props.child;return e.isValidElement(n)?e.cloneElement(n,void 0,t.props.children(n.props.children)):null}return e.isValidElement(n)?n:null};function c(e,t){let n={...t};for(let r in t){let i=e[r],a=t[r];/^on[A-Z]/.test(r)?i&&a?n[r]=(...e)=>{let t=a(...e);return i(...e),t}:i&&(n[r]=i):r===`style`?n[r]={...i,...a}:r===`className`&&(n[r]=[i,a].filter(Boolean).join(` `))}return{...e,...n}}function l(e){let t=Object.getOwnPropertyDescriptor(e.props,`ref`)?.get,n=t&&`isReactWarning`in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,`ref`)?.get,n=t&&`isReactWarning`in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}function u(t){return e.isValidElement(t)&&typeof t.type==`function`&&`__radixId`in t.type&&t.type.__radixId===o}var d=Symbol.for(`react.lazy`);function f(e){return typeof e==`object`&&!!e&&`$$typeof`in e&&e.$$typeof===d&&`_payload`in e&&p(e._payload)}function p(e){return typeof e==`object`&&!!e&&`then`in e}var m=e=>`${e} failed to slot onto its children. Expected a single React element child or \`Slottable\`.`,h=e=>`${e} failed to slot onto its \`Slottable\`. Expected \`Slottable\` to receive a single React element child.`,g=e.use;export{a as t};
2
- //# sourceMappingURL=dist-BQGL-YKY.mjs.map