@jameskabz/nextcraft-ui 0.6.5 → 0.6.6

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 (357) hide show
  1. package/dist/index.cjs +3448 -103
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +746 -54
  4. package/dist/index.d.ts +746 -54
  5. package/dist/index.js +3388 -50
  6. package/dist/index.js.map +1 -1
  7. package/package.json +1 -26
  8. package/dist/components/craft-alert.cjs +0 -69
  9. package/dist/components/craft-alert.cjs.map +0 -1
  10. package/dist/components/craft-alert.d.cts +0 -16
  11. package/dist/components/craft-alert.d.ts +0 -16
  12. package/dist/components/craft-alert.js +0 -45
  13. package/dist/components/craft-alert.js.map +0 -1
  14. package/dist/components/craft-badge.cjs +0 -54
  15. package/dist/components/craft-badge.cjs.map +0 -1
  16. package/dist/components/craft-badge.d.cts +0 -12
  17. package/dist/components/craft-badge.d.ts +0 -12
  18. package/dist/components/craft-badge.js +0 -30
  19. package/dist/components/craft-badge.js.map +0 -1
  20. package/dist/components/craft-button.cjs +0 -66
  21. package/dist/components/craft-button.cjs.map +0 -1
  22. package/dist/components/craft-button.d.cts +0 -15
  23. package/dist/components/craft-button.d.ts +0 -15
  24. package/dist/components/craft-button.js +0 -42
  25. package/dist/components/craft-button.js.map +0 -1
  26. package/dist/components/craft-card.cjs +0 -63
  27. package/dist/components/craft-card.cjs.map +0 -1
  28. package/dist/components/craft-card.d.cts +0 -13
  29. package/dist/components/craft-card.d.ts +0 -13
  30. package/dist/components/craft-card.js +0 -39
  31. package/dist/components/craft-card.js.map +0 -1
  32. package/dist/components/craft-checkbox.cjs +0 -103
  33. package/dist/components/craft-checkbox.cjs.map +0 -1
  34. package/dist/components/craft-checkbox.d.cts +0 -16
  35. package/dist/components/craft-checkbox.d.ts +0 -16
  36. package/dist/components/craft-checkbox.js +0 -69
  37. package/dist/components/craft-checkbox.js.map +0 -1
  38. package/dist/components/craft-command-palette.cjs +0 -134
  39. package/dist/components/craft-command-palette.cjs.map +0 -1
  40. package/dist/components/craft-command-palette.d.cts +0 -28
  41. package/dist/components/craft-command-palette.d.ts +0 -28
  42. package/dist/components/craft-command-palette.js +0 -100
  43. package/dist/components/craft-command-palette.js.map +0 -1
  44. package/dist/components/craft-confirm-dialog.cjs +0 -114
  45. package/dist/components/craft-confirm-dialog.cjs.map +0 -1
  46. package/dist/components/craft-confirm-dialog.d.cts +0 -21
  47. package/dist/components/craft-confirm-dialog.d.ts +0 -21
  48. package/dist/components/craft-confirm-dialog.js +0 -80
  49. package/dist/components/craft-confirm-dialog.js.map +0 -1
  50. package/dist/components/craft-create-edit-drawer.cjs +0 -112
  51. package/dist/components/craft-create-edit-drawer.cjs.map +0 -1
  52. package/dist/components/craft-create-edit-drawer.d.cts +0 -28
  53. package/dist/components/craft-create-edit-drawer.d.ts +0 -28
  54. package/dist/components/craft-create-edit-drawer.js +0 -78
  55. package/dist/components/craft-create-edit-drawer.js.map +0 -1
  56. package/dist/components/craft-currency-input.cjs +0 -68
  57. package/dist/components/craft-currency-input.cjs.map +0 -1
  58. package/dist/components/craft-currency-input.d.cts +0 -14
  59. package/dist/components/craft-currency-input.d.ts +0 -14
  60. package/dist/components/craft-currency-input.js +0 -34
  61. package/dist/components/craft-currency-input.js.map +0 -1
  62. package/dist/components/craft-data-table.cjs +0 -407
  63. package/dist/components/craft-data-table.cjs.map +0 -1
  64. package/dist/components/craft-data-table.d.cts +0 -58
  65. package/dist/components/craft-data-table.d.ts +0 -58
  66. package/dist/components/craft-data-table.js +0 -373
  67. package/dist/components/craft-data-table.js.map +0 -1
  68. package/dist/components/craft-date-picker.cjs +0 -226
  69. package/dist/components/craft-date-picker.cjs.map +0 -1
  70. package/dist/components/craft-date-picker.d.cts +0 -17
  71. package/dist/components/craft-date-picker.d.ts +0 -17
  72. package/dist/components/craft-date-picker.js +0 -192
  73. package/dist/components/craft-date-picker.js.map +0 -1
  74. package/dist/components/craft-drawer.cjs +0 -126
  75. package/dist/components/craft-drawer.cjs.map +0 -1
  76. package/dist/components/craft-drawer.d.cts +0 -19
  77. package/dist/components/craft-drawer.d.ts +0 -19
  78. package/dist/components/craft-drawer.js +0 -92
  79. package/dist/components/craft-drawer.js.map +0 -1
  80. package/dist/components/craft-dropdown-menu.cjs +0 -127
  81. package/dist/components/craft-dropdown-menu.cjs.map +0 -1
  82. package/dist/components/craft-dropdown-menu.d.cts +0 -28
  83. package/dist/components/craft-dropdown-menu.d.ts +0 -28
  84. package/dist/components/craft-dropdown-menu.js +0 -93
  85. package/dist/components/craft-dropdown-menu.js.map +0 -1
  86. package/dist/components/craft-empty-state.cjs +0 -58
  87. package/dist/components/craft-empty-state.cjs.map +0 -1
  88. package/dist/components/craft-empty-state.d.cts +0 -14
  89. package/dist/components/craft-empty-state.d.ts +0 -14
  90. package/dist/components/craft-empty-state.js +0 -34
  91. package/dist/components/craft-empty-state.js.map +0 -1
  92. package/dist/components/craft-error-state.cjs +0 -60
  93. package/dist/components/craft-error-state.cjs.map +0 -1
  94. package/dist/components/craft-error-state.d.cts +0 -15
  95. package/dist/components/craft-error-state.d.ts +0 -15
  96. package/dist/components/craft-error-state.js +0 -36
  97. package/dist/components/craft-error-state.js.map +0 -1
  98. package/dist/components/craft-filter-bar.cjs +0 -76
  99. package/dist/components/craft-filter-bar.cjs.map +0 -1
  100. package/dist/components/craft-filter-bar.d.cts +0 -18
  101. package/dist/components/craft-filter-bar.d.ts +0 -18
  102. package/dist/components/craft-filter-bar.js +0 -52
  103. package/dist/components/craft-filter-bar.js.map +0 -1
  104. package/dist/components/craft-form-builder.cjs +0 -330
  105. package/dist/components/craft-form-builder.cjs.map +0 -1
  106. package/dist/components/craft-form-builder.d.cts +0 -57
  107. package/dist/components/craft-form-builder.d.ts +0 -57
  108. package/dist/components/craft-form-builder.js +0 -301
  109. package/dist/components/craft-form-builder.js.map +0 -1
  110. package/dist/components/craft-form-field.cjs +0 -301
  111. package/dist/components/craft-form-field.cjs.map +0 -1
  112. package/dist/components/craft-form-field.d.cts +0 -30
  113. package/dist/components/craft-form-field.d.ts +0 -30
  114. package/dist/components/craft-form-field.js +0 -280
  115. package/dist/components/craft-form-field.js.map +0 -1
  116. package/dist/components/craft-form.cjs +0 -114
  117. package/dist/components/craft-form.cjs.map +0 -1
  118. package/dist/components/craft-form.d.cts +0 -27
  119. package/dist/components/craft-form.d.ts +0 -27
  120. package/dist/components/craft-form.js +0 -80
  121. package/dist/components/craft-form.js.map +0 -1
  122. package/dist/components/craft-icon.cjs +0 -102
  123. package/dist/components/craft-icon.cjs.map +0 -1
  124. package/dist/components/craft-icon.d.cts +0 -19
  125. package/dist/components/craft-icon.d.ts +0 -19
  126. package/dist/components/craft-icon.js +0 -67
  127. package/dist/components/craft-icon.js.map +0 -1
  128. package/dist/components/craft-input.cjs +0 -78
  129. package/dist/components/craft-input.cjs.map +0 -1
  130. package/dist/components/craft-input.d.cts +0 -19
  131. package/dist/components/craft-input.d.ts +0 -19
  132. package/dist/components/craft-input.js +0 -44
  133. package/dist/components/craft-input.js.map +0 -1
  134. package/dist/components/craft-link.cjs +0 -70
  135. package/dist/components/craft-link.cjs.map +0 -1
  136. package/dist/components/craft-link.d.cts +0 -14
  137. package/dist/components/craft-link.d.ts +0 -14
  138. package/dist/components/craft-link.js +0 -36
  139. package/dist/components/craft-link.js.map +0 -1
  140. package/dist/components/craft-loading-state.cjs +0 -64
  141. package/dist/components/craft-loading-state.cjs.map +0 -1
  142. package/dist/components/craft-loading-state.d.cts +0 -13
  143. package/dist/components/craft-loading-state.d.ts +0 -13
  144. package/dist/components/craft-loading-state.js +0 -40
  145. package/dist/components/craft-loading-state.js.map +0 -1
  146. package/dist/components/craft-modal.cjs +0 -174
  147. package/dist/components/craft-modal.cjs.map +0 -1
  148. package/dist/components/craft-modal.d.cts +0 -19
  149. package/dist/components/craft-modal.d.ts +0 -19
  150. package/dist/components/craft-modal.js +0 -140
  151. package/dist/components/craft-modal.js.map +0 -1
  152. package/dist/components/craft-number-input.cjs +0 -63
  153. package/dist/components/craft-number-input.cjs.map +0 -1
  154. package/dist/components/craft-number-input.d.cts +0 -12
  155. package/dist/components/craft-number-input.d.ts +0 -12
  156. package/dist/components/craft-number-input.js +0 -29
  157. package/dist/components/craft-number-input.js.map +0 -1
  158. package/dist/components/craft-pagination.cjs +0 -130
  159. package/dist/components/craft-pagination.cjs.map +0 -1
  160. package/dist/components/craft-pagination.d.cts +0 -19
  161. package/dist/components/craft-pagination.d.ts +0 -19
  162. package/dist/components/craft-pagination.js +0 -106
  163. package/dist/components/craft-pagination.js.map +0 -1
  164. package/dist/components/craft-popover.cjs +0 -123
  165. package/dist/components/craft-popover.cjs.map +0 -1
  166. package/dist/components/craft-popover.d.cts +0 -20
  167. package/dist/components/craft-popover.d.ts +0 -20
  168. package/dist/components/craft-popover.js +0 -89
  169. package/dist/components/craft-popover.js.map +0 -1
  170. package/dist/components/craft-select.cjs +0 -84
  171. package/dist/components/craft-select.cjs.map +0 -1
  172. package/dist/components/craft-select.d.cts +0 -12
  173. package/dist/components/craft-select.d.ts +0 -12
  174. package/dist/components/craft-select.js +0 -50
  175. package/dist/components/craft-select.js.map +0 -1
  176. package/dist/components/craft-skeleton.cjs +0 -45
  177. package/dist/components/craft-skeleton.cjs.map +0 -1
  178. package/dist/components/craft-skeleton.d.cts +0 -10
  179. package/dist/components/craft-skeleton.d.ts +0 -10
  180. package/dist/components/craft-skeleton.js +0 -21
  181. package/dist/components/craft-skeleton.js.map +0 -1
  182. package/dist/components/craft-stat-card.cjs +0 -67
  183. package/dist/components/craft-stat-card.cjs.map +0 -1
  184. package/dist/components/craft-stat-card.d.cts +0 -17
  185. package/dist/components/craft-stat-card.d.ts +0 -17
  186. package/dist/components/craft-stat-card.js +0 -43
  187. package/dist/components/craft-stat-card.js.map +0 -1
  188. package/dist/components/craft-submit-button.cjs +0 -71
  189. package/dist/components/craft-submit-button.cjs.map +0 -1
  190. package/dist/components/craft-submit-button.d.cts +0 -13
  191. package/dist/components/craft-submit-button.d.ts +0 -13
  192. package/dist/components/craft-submit-button.js +0 -47
  193. package/dist/components/craft-submit-button.js.map +0 -1
  194. package/dist/components/craft-switch.cjs +0 -82
  195. package/dist/components/craft-switch.cjs.map +0 -1
  196. package/dist/components/craft-switch.d.cts +0 -14
  197. package/dist/components/craft-switch.d.ts +0 -14
  198. package/dist/components/craft-switch.js +0 -48
  199. package/dist/components/craft-switch.js.map +0 -1
  200. package/dist/components/craft-table-toolbar.cjs +0 -79
  201. package/dist/components/craft-table-toolbar.cjs.map +0 -1
  202. package/dist/components/craft-table-toolbar.d.cts +0 -19
  203. package/dist/components/craft-table-toolbar.d.ts +0 -19
  204. package/dist/components/craft-table-toolbar.js +0 -55
  205. package/dist/components/craft-table-toolbar.js.map +0 -1
  206. package/dist/components/craft-tabs.cjs +0 -105
  207. package/dist/components/craft-tabs.cjs.map +0 -1
  208. package/dist/components/craft-tabs.d.cts +0 -19
  209. package/dist/components/craft-tabs.d.ts +0 -19
  210. package/dist/components/craft-tabs.js +0 -71
  211. package/dist/components/craft-tabs.js.map +0 -1
  212. package/dist/components/craft-textarea.cjs +0 -69
  213. package/dist/components/craft-textarea.cjs.map +0 -1
  214. package/dist/components/craft-textarea.d.cts +0 -12
  215. package/dist/components/craft-textarea.d.ts +0 -12
  216. package/dist/components/craft-textarea.js +0 -35
  217. package/dist/components/craft-textarea.js.map +0 -1
  218. package/dist/components/craft-toast.cjs +0 -98
  219. package/dist/components/craft-toast.cjs.map +0 -1
  220. package/dist/components/craft-toast.d.cts +0 -24
  221. package/dist/components/craft-toast.d.ts +0 -24
  222. package/dist/components/craft-toast.js +0 -63
  223. package/dist/components/craft-toast.js.map +0 -1
  224. package/dist/components/craft-tooltip.cjs +0 -75
  225. package/dist/components/craft-tooltip.cjs.map +0 -1
  226. package/dist/components/craft-tooltip.d.cts +0 -13
  227. package/dist/components/craft-tooltip.d.ts +0 -13
  228. package/dist/components/craft-tooltip.js +0 -41
  229. package/dist/components/craft-tooltip.js.map +0 -1
  230. package/dist/components/forms/types.cjs +0 -17
  231. package/dist/components/forms/types.cjs.map +0 -1
  232. package/dist/components/forms/types.d.cts +0 -7
  233. package/dist/components/forms/types.d.ts +0 -7
  234. package/dist/components/forms/types.js +0 -1
  235. package/dist/components/forms/types.js.map +0 -1
  236. package/dist/components/glass-card.cjs +0 -64
  237. package/dist/components/glass-card.cjs.map +0 -1
  238. package/dist/components/glass-card.d.cts +0 -12
  239. package/dist/components/glass-card.d.ts +0 -12
  240. package/dist/components/glass-card.js +0 -40
  241. package/dist/components/glass-card.js.map +0 -1
  242. package/dist/components/layout/app-shell.cjs +0 -49
  243. package/dist/components/layout/app-shell.cjs.map +0 -1
  244. package/dist/components/layout/app-shell.d.cts +0 -10
  245. package/dist/components/layout/app-shell.d.ts +0 -10
  246. package/dist/components/layout/app-shell.js +0 -25
  247. package/dist/components/layout/app-shell.js.map +0 -1
  248. package/dist/components/layout/app-template.cjs +0 -104
  249. package/dist/components/layout/app-template.cjs.map +0 -1
  250. package/dist/components/layout/app-template.d.cts +0 -19
  251. package/dist/components/layout/app-template.d.ts +0 -19
  252. package/dist/components/layout/app-template.js +0 -70
  253. package/dist/components/layout/app-template.js.map +0 -1
  254. package/dist/components/layout/auth-layout.cjs +0 -65
  255. package/dist/components/layout/auth-layout.cjs.map +0 -1
  256. package/dist/components/layout/auth-layout.d.cts +0 -12
  257. package/dist/components/layout/auth-layout.d.ts +0 -12
  258. package/dist/components/layout/auth-layout.js +0 -41
  259. package/dist/components/layout/auth-layout.js.map +0 -1
  260. package/dist/components/layout/breadcrumbs.cjs +0 -39
  261. package/dist/components/layout/breadcrumbs.cjs.map +0 -1
  262. package/dist/components/layout/breadcrumbs.d.cts +0 -13
  263. package/dist/components/layout/breadcrumbs.d.ts +0 -13
  264. package/dist/components/layout/breadcrumbs.js +0 -15
  265. package/dist/components/layout/breadcrumbs.js.map +0 -1
  266. package/dist/components/layout/container.cjs +0 -45
  267. package/dist/components/layout/container.cjs.map +0 -1
  268. package/dist/components/layout/container.d.cts +0 -9
  269. package/dist/components/layout/container.d.ts +0 -9
  270. package/dist/components/layout/container.js +0 -21
  271. package/dist/components/layout/container.js.map +0 -1
  272. package/dist/components/layout/grid.cjs +0 -47
  273. package/dist/components/layout/grid.cjs.map +0 -1
  274. package/dist/components/layout/grid.d.cts +0 -10
  275. package/dist/components/layout/grid.d.ts +0 -10
  276. package/dist/components/layout/grid.js +0 -23
  277. package/dist/components/layout/grid.js.map +0 -1
  278. package/dist/components/layout/layout-config.cjs +0 -78
  279. package/dist/components/layout/layout-config.cjs.map +0 -1
  280. package/dist/components/layout/layout-config.d.cts +0 -92
  281. package/dist/components/layout/layout-config.d.ts +0 -92
  282. package/dist/components/layout/layout-config.js +0 -54
  283. package/dist/components/layout/layout-config.js.map +0 -1
  284. package/dist/components/layout/page-header.cjs +0 -52
  285. package/dist/components/layout/page-header.cjs.map +0 -1
  286. package/dist/components/layout/page-header.d.cts +0 -11
  287. package/dist/components/layout/page-header.d.ts +0 -11
  288. package/dist/components/layout/page-header.js +0 -28
  289. package/dist/components/layout/page-header.js.map +0 -1
  290. package/dist/components/layout/sidebar.cjs +0 -64
  291. package/dist/components/layout/sidebar.cjs.map +0 -1
  292. package/dist/components/layout/sidebar.d.cts +0 -17
  293. package/dist/components/layout/sidebar.d.ts +0 -17
  294. package/dist/components/layout/sidebar.js +0 -40
  295. package/dist/components/layout/sidebar.js.map +0 -1
  296. package/dist/components/layout/top-nav.cjs +0 -49
  297. package/dist/components/layout/top-nav.cjs.map +0 -1
  298. package/dist/components/layout/top-nav.d.cts +0 -11
  299. package/dist/components/layout/top-nav.d.ts +0 -11
  300. package/dist/components/layout/top-nav.js +0 -25
  301. package/dist/components/layout/top-nav.js.map +0 -1
  302. package/dist/components/layout/types.cjs +0 -29
  303. package/dist/components/layout/types.cjs.map +0 -1
  304. package/dist/components/layout/types.d.cts +0 -12
  305. package/dist/components/layout/types.d.ts +0 -12
  306. package/dist/components/layout/types.js +0 -5
  307. package/dist/components/layout/types.js.map +0 -1
  308. package/dist/components/table/types.cjs +0 -17
  309. package/dist/components/table/types.cjs.map +0 -1
  310. package/dist/components/table/types.d.cts +0 -7
  311. package/dist/components/table/types.d.ts +0 -7
  312. package/dist/components/table/types.js +0 -1
  313. package/dist/components/table/types.js.map +0 -1
  314. package/dist/components/theme-switcher.cjs +0 -72
  315. package/dist/components/theme-switcher.cjs.map +0 -1
  316. package/dist/components/theme-switcher.d.cts +0 -9
  317. package/dist/components/theme-switcher.d.ts +0 -9
  318. package/dist/components/theme-switcher.js +0 -48
  319. package/dist/components/theme-switcher.js.map +0 -1
  320. package/dist/craft/components.cjs +0 -123
  321. package/dist/craft/components.cjs.map +0 -1
  322. package/dist/craft/components.d.cts +0 -36
  323. package/dist/craft/components.d.ts +0 -36
  324. package/dist/craft/components.js +0 -67
  325. package/dist/craft/components.js.map +0 -1
  326. package/dist/craft/forms.cjs +0 -35
  327. package/dist/craft/forms.cjs.map +0 -1
  328. package/dist/craft/forms.d.cts +0 -7
  329. package/dist/craft/forms.d.ts +0 -7
  330. package/dist/craft/forms.js +0 -9
  331. package/dist/craft/forms.js.map +0 -1
  332. package/dist/craft/layout.cjs +0 -56
  333. package/dist/craft/layout.cjs.map +0 -1
  334. package/dist/craft/layout.d.cts +0 -12
  335. package/dist/craft/layout.d.ts +0 -12
  336. package/dist/craft/layout.js +0 -23
  337. package/dist/craft/layout.js.map +0 -1
  338. package/dist/craft/table.cjs +0 -38
  339. package/dist/craft/table.cjs.map +0 -1
  340. package/dist/craft/table.d.cts +0 -7
  341. package/dist/craft/table.d.ts +0 -7
  342. package/dist/craft/table.js +0 -11
  343. package/dist/craft/table.js.map +0 -1
  344. package/dist/craft/theme.cjs +0 -34
  345. package/dist/craft/theme.cjs.map +0 -1
  346. package/dist/craft/theme.d.cts +0 -4
  347. package/dist/craft/theme.d.ts +0 -4
  348. package/dist/craft/theme.js +0 -8
  349. package/dist/craft/theme.js.map +0 -1
  350. package/dist/theme-context-EVI9PfKv.d.cts +0 -22
  351. package/dist/theme-context-EVI9PfKv.d.ts +0 -22
  352. package/dist/utils/cn.cjs +0 -31
  353. package/dist/utils/cn.cjs.map +0 -1
  354. package/dist/utils/cn.d.cts +0 -3
  355. package/dist/utils/cn.d.ts +0 -3
  356. package/dist/utils/cn.js +0 -7
  357. package/dist/utils/cn.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,114 +17,3457 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
19
31
  var index_exports = {};
20
32
  __export(index_exports, {
21
- AppShell: () => import_app_shell.AppShell,
22
- AppTemplate: () => import_app_template.AppTemplate,
23
- AuthLayout: () => import_auth_layout.AuthLayout,
24
- Breadcrumbs: () => import_breadcrumbs.Breadcrumbs,
25
- Container: () => import_container.Container,
26
- CraftAlert: () => import_craft_alert.CraftAlert,
27
- CraftBadge: () => import_craft_badge.CraftBadge,
28
- CraftButton: () => import_craft_button.CraftButton,
29
- CraftCard: () => import_craft_card.CraftCard,
30
- CraftCheckbox: () => import_craft_checkbox.CraftCheckbox,
31
- CraftCommandPalette: () => import_craft_command_palette.CraftCommandPalette,
32
- CraftConfirmDialog: () => import_craft_confirm_dialog.CraftConfirmDialog,
33
- CraftCreateEditDrawer: () => import_craft_create_edit_drawer.CraftCreateEditDrawer,
34
- CraftCurrencyInput: () => import_craft_currency_input.CraftCurrencyInput,
35
- CraftDataTable: () => import_craft_data_table.CraftDataTable,
36
- CraftDatePicker: () => import_craft_date_picker.CraftDatePicker,
37
- CraftDrawer: () => import_craft_drawer.CraftDrawer,
38
- CraftDropdownMenu: () => import_craft_dropdown_menu.CraftDropdownMenu,
39
- CraftEmptyState: () => import_craft_empty_state.CraftEmptyState,
40
- CraftErrorState: () => import_craft_error_state.CraftErrorState,
41
- CraftFilterBar: () => import_craft_filter_bar.CraftFilterBar,
42
- CraftForm: () => import_craft_form.CraftForm,
43
- CraftFormBuilder: () => import_craft_form_builder.CraftFormBuilder,
44
- CraftFormField: () => import_craft_form_field.CraftFormField,
45
- CraftIcon: () => import_craft_icon.CraftIcon,
46
- CraftIconProvider: () => import_craft_icon.CraftIconProvider,
47
- CraftInput: () => import_craft_input.CraftInput,
48
- CraftLink: () => import_craft_link.CraftLink,
49
- CraftLoadingState: () => import_craft_loading_state.CraftLoadingState,
50
- CraftModal: () => import_craft_modal.CraftModal,
51
- CraftNumberInput: () => import_craft_number_input.CraftNumberInput,
52
- CraftPagination: () => import_craft_pagination.CraftPagination,
53
- CraftPopover: () => import_craft_popover.CraftPopover,
54
- CraftSelect: () => import_craft_select.CraftSelect,
55
- CraftSkeleton: () => import_craft_skeleton.CraftSkeleton,
56
- CraftStatCard: () => import_craft_stat_card.CraftStatCard,
57
- CraftSubmitButton: () => import_craft_submit_button.CraftSubmitButton,
58
- CraftSwitch: () => import_craft_switch.CraftSwitch,
59
- CraftTableToolbar: () => import_craft_table_toolbar.CraftTableToolbar,
60
- CraftTabs: () => import_craft_tabs.CraftTabs,
61
- CraftTextarea: () => import_craft_textarea.CraftTextarea,
62
- CraftToastHost: () => import_craft_toast.CraftToastHost,
63
- CraftTooltip: () => import_craft_tooltip.CraftTooltip,
64
- GlassCard: () => import_glass_card.GlassCard,
65
- Grid: () => import_grid.Grid,
66
- PageHeader: () => import_page_header.PageHeader,
67
- Sidebar: () => import_sidebar.Sidebar,
68
- ThemeProvider: () => import_theme_context.ThemeProvider,
69
- ThemeSwitcher: () => import_theme_switcher.ThemeSwitcher,
70
- TopNav: () => import_top_nav.TopNav,
71
- layoutConfigSchema: () => import_layout_config.layoutConfigSchema,
72
- useCraftToast: () => import_craft_toast.useCraftToast,
73
- useTheme: () => import_theme_context.useTheme
33
+ AppShell: () => AppShell,
34
+ AppTemplate: () => AppTemplate,
35
+ AuthLayout: () => AuthLayout,
36
+ Breadcrumbs: () => Breadcrumbs,
37
+ Container: () => Container,
38
+ CraftAlert: () => CraftAlert,
39
+ CraftBadge: () => CraftBadge,
40
+ CraftButton: () => CraftButton,
41
+ CraftCard: () => CraftCard,
42
+ CraftCheckbox: () => CraftCheckbox,
43
+ CraftCommandPalette: () => CraftCommandPalette,
44
+ CraftConfirmDialog: () => CraftConfirmDialog,
45
+ CraftCreateEditDrawer: () => CraftCreateEditDrawer,
46
+ CraftCurrencyInput: () => CraftCurrencyInput,
47
+ CraftDataTable: () => CraftDataTable,
48
+ CraftDatePicker: () => CraftDatePicker,
49
+ CraftDrawer: () => CraftDrawer,
50
+ CraftDropdownMenu: () => CraftDropdownMenu,
51
+ CraftEmptyState: () => CraftEmptyState,
52
+ CraftErrorState: () => CraftErrorState,
53
+ CraftFilterBar: () => CraftFilterBar,
54
+ CraftForm: () => CraftForm,
55
+ CraftFormBuilder: () => CraftFormBuilder,
56
+ CraftFormField: () => CraftFormField,
57
+ CraftIcon: () => CraftIcon,
58
+ CraftIconProvider: () => CraftIconProvider,
59
+ CraftInput: () => CraftInput,
60
+ CraftLink: () => CraftLink,
61
+ CraftLoadingState: () => CraftLoadingState,
62
+ CraftModal: () => CraftModal,
63
+ CraftNumberInput: () => CraftNumberInput,
64
+ CraftPagination: () => CraftPagination,
65
+ CraftPopover: () => CraftPopover,
66
+ CraftSelect: () => CraftSelect,
67
+ CraftSkeleton: () => CraftSkeleton,
68
+ CraftStatCard: () => CraftStatCard,
69
+ CraftSubmitButton: () => CraftSubmitButton,
70
+ CraftSwitch: () => CraftSwitch,
71
+ CraftTableToolbar: () => CraftTableToolbar,
72
+ CraftTabs: () => CraftTabs,
73
+ CraftTextarea: () => CraftTextarea,
74
+ CraftToastHost: () => CraftToastHost,
75
+ CraftTooltip: () => CraftTooltip,
76
+ GlassCard: () => GlassCard,
77
+ Grid: () => Grid,
78
+ PageHeader: () => PageHeader,
79
+ Sidebar: () => Sidebar,
80
+ ThemeProvider: () => ThemeProvider,
81
+ ThemeSwitcher: () => ThemeSwitcher,
82
+ TopNav: () => TopNav,
83
+ layoutConfigSchema: () => layoutConfigSchema,
84
+ useCraftToast: () => useCraftToast,
85
+ useTheme: () => useTheme
74
86
  });
75
87
  module.exports = __toCommonJS(index_exports);
76
- var import_craft_button = require("./components/craft-button");
77
- var import_glass_card = require("./components/glass-card");
78
- var import_craft_input = require("./components/craft-input");
79
- var import_craft_textarea = require("./components/craft-textarea");
80
- var import_craft_select = require("./components/craft-select");
81
- var import_craft_checkbox = require("./components/craft-checkbox");
82
- var import_craft_switch = require("./components/craft-switch");
83
- var import_craft_badge = require("./components/craft-badge");
84
- var import_craft_alert = require("./components/craft-alert");
85
- var import_craft_error_state = require("./components/craft-error-state");
86
- var import_craft_loading_state = require("./components/craft-loading-state");
87
- var import_craft_card = require("./components/craft-card");
88
- var import_craft_modal = require("./components/craft-modal");
89
- var import_craft_drawer = require("./components/craft-drawer");
90
- var import_craft_tabs = require("./components/craft-tabs");
91
- var import_craft_tooltip = require("./components/craft-tooltip");
92
- var import_craft_toast = require("./components/craft-toast");
93
- var import_craft_skeleton = require("./components/craft-skeleton");
94
- var import_craft_empty_state = require("./components/craft-empty-state");
95
- var import_craft_popover = require("./components/craft-popover");
96
- var import_craft_dropdown_menu = require("./components/craft-dropdown-menu");
97
- var import_craft_command_palette = require("./components/craft-command-palette");
98
- var import_craft_link = require("./components/craft-link");
99
- var import_craft_stat_card = require("./components/craft-stat-card");
100
- var import_craft_date_picker = require("./components/craft-date-picker");
101
- var import_craft_icon = require("./components/craft-icon");
102
- var import_craft_number_input = require("./components/craft-number-input");
103
- var import_craft_currency_input = require("./components/craft-currency-input");
104
- var import_craft_form = require("./components/craft-form");
105
- var import_craft_form_builder = require("./components/craft-form-builder");
106
- var import_craft_form_field = require("./components/craft-form-field");
107
- var import_craft_submit_button = require("./components/craft-submit-button");
108
- var import_craft_confirm_dialog = require("./components/craft-confirm-dialog");
109
- var import_craft_create_edit_drawer = require("./components/craft-create-edit-drawer");
110
- var import_craft_filter_bar = require("./components/craft-filter-bar");
111
- var import_craft_table_toolbar = require("./components/craft-table-toolbar");
112
- var import_craft_data_table = require("./components/craft-data-table");
113
- var import_craft_pagination = require("./components/craft-pagination");
114
- var import_app_shell = require("./components/layout/app-shell");
115
- var import_app_template = require("./components/layout/app-template");
116
- var import_layout_config = require("./components/layout/layout-config");
117
- var import_sidebar = require("./components/layout/sidebar");
118
- var import_top_nav = require("./components/layout/top-nav");
119
- var import_page_header = require("./components/layout/page-header");
120
- var import_breadcrumbs = require("./components/layout/breadcrumbs");
121
- var import_auth_layout = require("./components/layout/auth-layout");
122
- var import_container = require("./components/layout/container");
123
- var import_grid = require("./components/layout/grid");
124
- var import_theme_switcher = require("./components/theme-switcher");
125
- var import_theme_context = require("./theme/theme-context");
88
+
89
+ // src/utils/cn.ts
90
+ function cn(...values) {
91
+ return values.filter(Boolean).join(" ");
92
+ }
93
+
94
+ // src/components/craft-button.tsx
95
+ var import_jsx_runtime = require("react/jsx-runtime");
96
+ var sizeClasses = {
97
+ sm: "h-9 px-4 text-xs",
98
+ md: "h-11 px-6 text-sm",
99
+ lg: "h-13 px-8 text-base"
100
+ };
101
+ var variantClasses = {
102
+ solid: "bg-gradient-to-br from-[rgb(var(--nc-accent-1))] via-[rgb(var(--nc-accent-2))] to-[rgb(var(--nc-accent-3))] text-white shadow-[0_12px_30px_rgb(var(--nc-accent-1)/0.45)] hover:shadow-[0_16px_36px_rgb(var(--nc-accent-1)/0.6)] hover:scale-[1.02] active:scale-[0.98]",
103
+ ghost: "bg-[color:rgb(var(--nc-surface)/0.12)] text-[rgb(var(--nc-fg))] hover:bg-[color:rgb(var(--nc-surface)/0.18)] backdrop-blur-sm border border-[rgb(var(--nc-border)/0.35)] hover:border-[color:rgb(var(--nc-border)/0.5)]",
104
+ outline: "bg-transparent text-[color:rgb(var(--nc-accent-1))] border-2 border-[color:rgb(var(--nc-accent-1)/0.5)] hover:border-[color:rgb(var(--nc-accent-1))] hover:bg-[color:rgb(var(--nc-accent-1)/0.1)]",
105
+ gradient: "bg-gradient-to-r from-[rgb(var(--nc-accent-1))] via-[rgb(var(--nc-accent-2))] to-[rgb(var(--nc-accent-3))] text-white shadow-[0_12px_30px_rgb(var(--nc-accent-2)/0.45)] hover:shadow-[0_16px_36px_rgb(var(--nc-accent-2)/0.6)] hover:scale-[1.02] active:scale-[0.98]"
106
+ };
107
+ function CraftButton({
108
+ className,
109
+ variant = "solid",
110
+ size = "md",
111
+ glow = true,
112
+ tone,
113
+ disabled,
114
+ ...props
115
+ }) {
116
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
117
+ "button",
118
+ {
119
+ className: cn(
120
+ "relative inline-flex items-center justify-center gap-2 rounded-xl font-semibold tracking-wide transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[rgb(var(--nc-accent-1)/0.6)] focus-visible:ring-offset-2 focus-visible:ring-offset-slate-900 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:scale-100",
121
+ sizeClasses[size],
122
+ variantClasses[variant],
123
+ glow && (variant === "solid" || variant === "gradient") ? "before:absolute before:-inset-1 before:rounded-xl before:bg-linear-to-r before:from-[rgb(var(--nc-accent-1)/0.2)] before:via-[rgb(var(--nc-accent-2)/0.2)] before:to-[rgb(var(--nc-accent-3)/0.2)] before:blur-xl before:-z-10 before:opacity-0 hover:before:opacity-100 before:transition-opacity" : "",
124
+ className
125
+ ),
126
+ "data-nc-theme": tone,
127
+ disabled,
128
+ ...props
129
+ }
130
+ );
131
+ }
132
+
133
+ // src/components/glass-card.tsx
134
+ var import_jsx_runtime2 = require("react/jsx-runtime");
135
+ var intensityClasses = {
136
+ subtle: "backdrop-blur-md bg-opacity-50",
137
+ medium: "backdrop-blur-xl bg-opacity-70",
138
+ strong: "backdrop-blur-2xl bg-opacity-90"
139
+ };
140
+ function GlassCard({
141
+ className,
142
+ tone,
143
+ intensity = "medium",
144
+ bordered = true,
145
+ children,
146
+ ...props
147
+ }) {
148
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
149
+ "div",
150
+ {
151
+ className: cn(
152
+ "relative overflow-hidden rounded-3xl p-6 text-[rgb(var(--nc-fg))]",
153
+ "shadow-[0_8px_32px_rgba(0,0,0,0.3)]",
154
+ "transition-all duration-300",
155
+ "hover:shadow-[0_8px_40px_rgba(0,0,0,0.4)]",
156
+ intensityClasses[intensity],
157
+ "bg-linear-to-br from-[rgb(var(--nc-accent-1)/0.15)] via-[rgb(var(--nc-accent-2)/0.10)] to-[rgb(var(--nc-accent-3)/0.15)]",
158
+ "border-[rgb(var(--nc-accent-1)/0.3)]",
159
+ bordered ? "border-2" : "border-0",
160
+ "before:absolute before:inset-0 before:bg-linear-to-br before:from-white/10 before:to-transparent before:opacity-0 hover:before:opacity-100 before:transition-opacity before:duration-300",
161
+ className
162
+ ),
163
+ "data-nc-theme": tone,
164
+ ...props,
165
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "relative z-10", children })
166
+ }
167
+ );
168
+ }
169
+
170
+ // src/components/craft-input.tsx
171
+ var React = __toESM(require("react"), 1);
172
+ var import_jsx_runtime3 = require("react/jsx-runtime");
173
+ var inputSizeClasses = {
174
+ sm: "h-10 px-4 text-sm",
175
+ md: "h-12 px-5 text-base",
176
+ lg: "h-14 px-6 text-lg"
177
+ };
178
+ var CraftInput = React.forwardRef(
179
+ ({ className, tone, inputSize = "md", glow = true, icon, ...props }, ref) => {
180
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "relative w-full", "data-nc-theme": tone, children: [
181
+ icon && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "absolute left-4 top-1/2 -translate-y-1/2 text-[rgb(var(--nc-fg-soft))]", children: icon }),
182
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
183
+ "input",
184
+ {
185
+ ref,
186
+ className: cn(
187
+ "w-full rounded-2xl border-2 bg-[rgb(var(--nc-surface)/0.08)] text-[rgb(var(--nc-fg))] backdrop-blur-xl",
188
+ "shadow-[inset_0_2px_8px_rgba(0,0,0,0.3)]",
189
+ "focus:outline-none focus:ring-4",
190
+ "transition-all duration-300",
191
+ "disabled:opacity-50 disabled:cursor-not-allowed",
192
+ inputSizeClasses[inputSize],
193
+ "border-[rgb(var(--nc-border)/0.35)]",
194
+ "focus:border-[rgb(var(--nc-accent-1)/0.8)] focus:ring-[rgb(var(--nc-accent-1)/0.3)]",
195
+ "placeholder:text-[rgb(var(--nc-fg-soft))]",
196
+ glow ? "focus:shadow-[0_0_30px_-5px_var(--glow-color)]" : "",
197
+ icon ? "pl-12" : "",
198
+ className
199
+ ),
200
+ style: {
201
+ "--glow-color": "rgb(var(--nc-accent-1) / 0.5)"
202
+ },
203
+ ...props
204
+ }
205
+ )
206
+ ] });
207
+ }
208
+ );
209
+ CraftInput.displayName = "CraftInput";
210
+
211
+ // src/components/craft-textarea.tsx
212
+ var React2 = __toESM(require("react"), 1);
213
+ var import_jsx_runtime4 = require("react/jsx-runtime");
214
+ var CraftTextarea = React2.forwardRef(
215
+ ({ className, tone, rows = 4, ...props }, ref) => {
216
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "relative w-full", "data-nc-theme": tone, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
217
+ "textarea",
218
+ {
219
+ ref,
220
+ rows,
221
+ className: cn(
222
+ "w-full rounded-2xl border-2 bg-[rgb(var(--nc-surface)/0.08)] text-[rgb(var(--nc-fg))] backdrop-blur-xl",
223
+ "shadow-[inset_0_2px_8px_rgba(0,0,0,0.3)]",
224
+ "focus:outline-none focus:ring-4",
225
+ "transition-all duration-300",
226
+ "disabled:opacity-50 disabled:cursor-not-allowed",
227
+ "border-[rgb(var(--nc-border)/0.35)]",
228
+ "focus:border-[rgb(var(--nc-accent-1)/0.8)] focus:ring-[rgb(var(--nc-accent-1)/0.3)]",
229
+ "placeholder:text-[rgb(var(--nc-fg-soft))]",
230
+ "px-5 py-3 text-base",
231
+ className
232
+ ),
233
+ style: {
234
+ "--glow-color": "rgb(var(--nc-accent-1) / 0.5)"
235
+ },
236
+ ...props
237
+ }
238
+ ) });
239
+ }
240
+ );
241
+ CraftTextarea.displayName = "CraftTextarea";
242
+
243
+ // src/components/craft-select.tsx
244
+ var React3 = __toESM(require("react"), 1);
245
+ var import_jsx_runtime5 = require("react/jsx-runtime");
246
+ var CraftSelect = React3.forwardRef(
247
+ ({ className, tone, children, ...props }, ref) => {
248
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "relative w-full", "data-nc-theme": tone, children: [
249
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
250
+ "select",
251
+ {
252
+ ref,
253
+ className: cn(
254
+ "w-full appearance-none rounded-2xl border-2 bg-[rgb(var(--nc-surface)/0.08)] text-[rgb(var(--nc-fg))] backdrop-blur-xl",
255
+ "shadow-[inset_0_2px_8px_rgba(0,0,0,0.3)]",
256
+ "focus:outline-none focus:ring-4",
257
+ "transition-all duration-300",
258
+ "disabled:opacity-50 disabled:cursor-not-allowed",
259
+ "border-[rgb(var(--nc-border)/0.35)]",
260
+ "focus:border-[rgb(var(--nc-accent-1)/0.8)] focus:ring-[rgb(var(--nc-accent-1)/0.3)]",
261
+ "px-5 py-3 pr-10 text-base",
262
+ className
263
+ ),
264
+ ...props,
265
+ children
266
+ }
267
+ ),
268
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
269
+ "svg",
270
+ {
271
+ className: "pointer-events-none absolute right-4 top-1/2 h-4 w-4 -translate-y-1/2 text-[rgb(var(--nc-fg-soft))]",
272
+ viewBox: "0 0 20 20",
273
+ fill: "currentColor",
274
+ "aria-hidden": "true",
275
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
276
+ "path",
277
+ {
278
+ fillRule: "evenodd",
279
+ d: "M5.23 7.21a.75.75 0 011.06.02L10 10.94l3.71-3.7a.75.75 0 111.06 1.06l-4.24 4.24a.75.75 0 01-1.06 0L5.21 8.29a.75.75 0 01.02-1.08z",
280
+ clipRule: "evenodd"
281
+ }
282
+ )
283
+ }
284
+ )
285
+ ] });
286
+ }
287
+ );
288
+ CraftSelect.displayName = "CraftSelect";
289
+
290
+ // src/components/craft-checkbox.tsx
291
+ var React4 = __toESM(require("react"), 1);
292
+ var import_jsx_runtime6 = require("react/jsx-runtime");
293
+ var CraftCheckbox = React4.forwardRef(
294
+ ({ className, tone, label, description, ...props }, ref) => {
295
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
296
+ "label",
297
+ {
298
+ className: cn(
299
+ "flex items-start gap-3 text-sm text-[rgb(var(--nc-fg))]",
300
+ props.disabled ? "opacity-60" : "cursor-pointer",
301
+ className
302
+ ),
303
+ "data-nc-theme": tone,
304
+ children: [
305
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "relative mt-0.5", children: [
306
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
307
+ "input",
308
+ {
309
+ ref,
310
+ type: "checkbox",
311
+ className: "peer sr-only",
312
+ ...props
313
+ }
314
+ ),
315
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
316
+ "span",
317
+ {
318
+ className: cn(
319
+ "flex h-5 w-5 items-center justify-center rounded-md border-2",
320
+ "border-[rgb(var(--nc-border)/0.45)] bg-[rgb(var(--nc-surface)/0.08)]",
321
+ "transition-all duration-200",
322
+ "peer-checked:border-[rgb(var(--nc-accent-1))] peer-checked:bg-[rgb(var(--nc-accent-1)/0.25)]",
323
+ "peer-focus-visible:ring-2 peer-focus-visible:ring-[rgb(var(--nc-accent-1)/0.5)]"
324
+ ),
325
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
326
+ "svg",
327
+ {
328
+ className: "h-3 w-3 text-[rgb(var(--nc-fg))] opacity-0 transition-opacity peer-checked:opacity-100",
329
+ viewBox: "0 0 20 20",
330
+ fill: "currentColor",
331
+ "aria-hidden": "true",
332
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
333
+ "path",
334
+ {
335
+ fillRule: "evenodd",
336
+ d: "M16.704 5.29a1 1 0 010 1.415l-7.2 7.2a1 1 0 01-1.415 0l-3.2-3.2a1 1 0 111.415-1.415l2.492 2.493 6.493-6.493a1 1 0 011.415 0z",
337
+ clipRule: "evenodd"
338
+ }
339
+ )
340
+ }
341
+ )
342
+ }
343
+ )
344
+ ] }),
345
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "space-y-1", children: [
346
+ label && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "block font-medium text-[rgb(var(--nc-fg))]", children: label }),
347
+ description && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "block text-xs text-[rgb(var(--nc-fg-muted))]", children: description })
348
+ ] })
349
+ ]
350
+ }
351
+ );
352
+ }
353
+ );
354
+ CraftCheckbox.displayName = "CraftCheckbox";
355
+
356
+ // src/components/craft-switch.tsx
357
+ var React5 = __toESM(require("react"), 1);
358
+ var import_jsx_runtime7 = require("react/jsx-runtime");
359
+ var CraftSwitch = React5.forwardRef(
360
+ ({ className, tone, label, ...props }, ref) => {
361
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
362
+ "label",
363
+ {
364
+ className: cn(
365
+ "inline-flex items-center gap-3 text-sm text-[rgb(var(--nc-fg))]",
366
+ props.disabled ? "opacity-60" : "cursor-pointer",
367
+ className
368
+ ),
369
+ "data-nc-theme": tone,
370
+ children: [
371
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("input", { ref, type: "checkbox", className: "peer sr-only", ...props }),
372
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
373
+ "span",
374
+ {
375
+ className: cn(
376
+ "relative h-6 w-11 rounded-full border-2 border-[rgb(var(--nc-border)/0.35)] bg-[rgb(var(--nc-surface)/0.08)]",
377
+ "transition-all duration-200",
378
+ "peer-focus-visible:ring-2 peer-focus-visible:ring-[rgb(var(--nc-accent-1)/0.5)]",
379
+ "peer-checked:border-[rgb(var(--nc-accent-1)/0.6)] peer-checked:bg-[rgb(var(--nc-accent-1)/0.25)]"
380
+ ),
381
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
382
+ "span",
383
+ {
384
+ className: cn(
385
+ "absolute left-0.5 top-0.5 h-4 w-4 rounded-full bg-[rgb(var(--nc-surface-muted)/0.9)]",
386
+ "transition-all duration-200",
387
+ "peer-checked:translate-x-5 peer-checked:bg-[rgb(var(--nc-surface-muted))]"
388
+ )
389
+ }
390
+ )
391
+ }
392
+ ),
393
+ label && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: label })
394
+ ]
395
+ }
396
+ );
397
+ }
398
+ );
399
+ CraftSwitch.displayName = "CraftSwitch";
400
+
401
+ // src/components/craft-badge.tsx
402
+ var import_jsx_runtime8 = require("react/jsx-runtime");
403
+ var variantClasses2 = {
404
+ solid: "bg-[color:rgb(var(--nc-accent-1))] text-white shadow-[0_10px_20px_rgb(var(--nc-accent-1)/0.35)]",
405
+ soft: "bg-[color:rgb(var(--nc-accent-1)/0.2)] text-[rgb(var(--nc-fg))]",
406
+ outline: "border border-[color:rgb(var(--nc-accent-1)/0.6)] text-[rgb(var(--nc-fg))]"
407
+ };
408
+ function CraftBadge({
409
+ className,
410
+ variant = "soft",
411
+ tone,
412
+ ...props
413
+ }) {
414
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
415
+ "span",
416
+ {
417
+ className: cn(
418
+ "inline-flex items-center rounded-full px-3 py-1 text-xs font-semibold uppercase tracking-wide",
419
+ variantClasses2[variant],
420
+ className
421
+ ),
422
+ "data-nc-theme": tone,
423
+ ...props
424
+ }
425
+ );
426
+ }
427
+
428
+ // src/components/craft-alert.tsx
429
+ var import_jsx_runtime9 = require("react/jsx-runtime");
430
+ var variantClasses3 = {
431
+ info: "border-[rgb(var(--nc-accent-1)/0.45)] bg-[rgb(var(--nc-accent-1)/0.12)]",
432
+ success: "border-[rgb(var(--nc-accent-2)/0.45)] bg-[rgb(var(--nc-accent-2)/0.12)]",
433
+ warning: "border-[rgb(var(--nc-accent-3)/0.45)] bg-[rgb(var(--nc-accent-3)/0.12)]",
434
+ error: "border-[rgb(var(--nc-accent-3)/0.65)] bg-[rgb(var(--nc-accent-3)/0.18)]"
435
+ };
436
+ function CraftAlert({
437
+ title,
438
+ description,
439
+ variant = "info",
440
+ icon,
441
+ actions,
442
+ tone,
443
+ className,
444
+ ...props
445
+ }) {
446
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
447
+ "div",
448
+ {
449
+ className: cn(
450
+ "rounded-2xl border p-4 text-[rgb(var(--nc-fg))] backdrop-blur-xl",
451
+ variantClasses3[variant],
452
+ className
453
+ ),
454
+ "data-nc-theme": tone,
455
+ ...props,
456
+ children: [
457
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-start gap-3", children: [
458
+ icon && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "mt-1 text-[rgb(var(--nc-fg))]", children: icon }),
459
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "space-y-1", children: [
460
+ title && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-sm font-semibold", children: title }),
461
+ description && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-sm text-[rgb(var(--nc-fg-muted))]", children: description })
462
+ ] })
463
+ ] }),
464
+ actions && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "mt-3 flex flex-wrap gap-2", children: actions })
465
+ ]
466
+ }
467
+ );
468
+ }
469
+
470
+ // src/components/craft-error-state.tsx
471
+ var import_jsx_runtime10 = require("react/jsx-runtime");
472
+ function CraftErrorState({
473
+ title = "Something went wrong",
474
+ description = "Try again or check your connection.",
475
+ actionLabel = "Retry",
476
+ onAction,
477
+ action,
478
+ tone,
479
+ className,
480
+ ...props
481
+ }) {
482
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
483
+ "div",
484
+ {
485
+ className: cn(
486
+ "rounded-3xl border border-[rgb(var(--nc-border)/0.35)] bg-[rgb(var(--nc-surface)/0.12)] p-6 text-[rgb(var(--nc-fg))] shadow-[0_12px_30px_rgba(0,0,0,0.25)] backdrop-blur-xl",
487
+ className
488
+ ),
489
+ "data-nc-theme": tone,
490
+ ...props,
491
+ children: [
492
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "space-y-2", children: [
493
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { className: "text-lg font-semibold", children: title }),
494
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-sm text-[rgb(var(--nc-fg-muted))]", children: description })
495
+ ] }),
496
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "mt-4", children: action != null ? action : onAction && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(CraftButton, { size: "sm", onClick: onAction, children: actionLabel }) })
497
+ ]
498
+ }
499
+ );
500
+ }
501
+
502
+ // src/components/craft-loading-state.tsx
503
+ var import_jsx_runtime11 = require("react/jsx-runtime");
504
+ var sizeClasses2 = {
505
+ sm: "h-4 w-4 border-2",
506
+ md: "h-6 w-6 border-2",
507
+ lg: "h-8 w-8 border-[3px]"
508
+ };
509
+ function CraftLoadingState({
510
+ label = "Loading...",
511
+ size = "md",
512
+ tone,
513
+ className,
514
+ ...props
515
+ }) {
516
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
517
+ "div",
518
+ {
519
+ className: cn("flex items-center gap-3 text-[rgb(var(--nc-fg))]", className),
520
+ "data-nc-theme": tone,
521
+ ...props,
522
+ children: [
523
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
524
+ "span",
525
+ {
526
+ className: cn(
527
+ "inline-block animate-spin rounded-full border-[rgb(var(--nc-accent-1)/0.25)] border-t-[rgb(var(--nc-accent-1))]",
528
+ sizeClasses2[size]
529
+ ),
530
+ "aria-hidden": "true"
531
+ }
532
+ ),
533
+ label && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-sm text-[rgb(var(--nc-fg-muted))]", children: label })
534
+ ]
535
+ }
536
+ );
537
+ }
538
+
539
+ // src/components/craft-card.tsx
540
+ var import_jsx_runtime12 = require("react/jsx-runtime");
541
+ var intensityClasses2 = {
542
+ subtle: "backdrop-blur-md bg-opacity-50",
543
+ medium: "backdrop-blur-xl bg-opacity-70",
544
+ strong: "backdrop-blur-2xl bg-opacity-90"
545
+ };
546
+ function CraftCard({
547
+ className,
548
+ tone,
549
+ elevated = true,
550
+ intensity = "medium",
551
+ bordered = true,
552
+ children,
553
+ ...props
554
+ }) {
555
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
556
+ "div",
557
+ {
558
+ className: cn(
559
+ "relative overflow-hidden rounded-3xl p-6 text-[rgb(var(--nc-fg))]",
560
+ intensityClasses2[intensity],
561
+ "bg-linear-to-br from-[rgb(var(--nc-accent-1)/0.15)] via-[rgb(var(--nc-accent-2)/0.10)] to-[rgb(var(--nc-accent-3)/0.15)]",
562
+ bordered ? "border-2 border-[rgb(var(--nc-accent-1)/0.3)]" : "border-0",
563
+ elevated ? "shadow-[0_8px_32px_rgba(0,0,0,0.3)] hover:shadow-[0_8px_40px_rgba(0,0,0,0.4)]" : "shadow-none",
564
+ "before:absolute before:inset-0 before:bg-linear-to-br before:from-white/10 before:to-transparent before:opacity-0 hover:before:opacity-100 before:transition-opacity before:duration-300",
565
+ "transition-all duration-300",
566
+ className
567
+ ),
568
+ "data-nc-theme": tone,
569
+ ...props,
570
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "relative z-10", children })
571
+ }
572
+ );
573
+ }
574
+
575
+ // src/components/craft-modal.tsx
576
+ var React6 = __toESM(require("react"), 1);
577
+ var import_react_dom = require("react-dom");
578
+ var import_jsx_runtime13 = require("react/jsx-runtime");
579
+ var FOCUSABLE_SELECTORS = [
580
+ "a[href]",
581
+ "button:not([disabled])",
582
+ "textarea:not([disabled])",
583
+ "input:not([disabled])",
584
+ "select:not([disabled])",
585
+ "[tabindex]:not([tabindex='-1'])"
586
+ ].join(",");
587
+ function useFocusTrap(active) {
588
+ const ref = React6.useRef(null);
589
+ React6.useEffect(() => {
590
+ if (!active || !ref.current) return;
591
+ const root = ref.current;
592
+ const getFocusable = () => Array.from(root.querySelectorAll(FOCUSABLE_SELECTORS));
593
+ const focusables = getFocusable();
594
+ if (focusables.length) {
595
+ focusables[0].focus();
596
+ } else {
597
+ root.focus();
598
+ }
599
+ const handleKeyDown = (event) => {
600
+ if (event.key !== "Tab") return;
601
+ const items = getFocusable();
602
+ if (!items.length) return;
603
+ const first = items[0];
604
+ const last = items[items.length - 1];
605
+ const activeEl = document.activeElement;
606
+ if (event.shiftKey && activeEl === first) {
607
+ event.preventDefault();
608
+ last.focus();
609
+ } else if (!event.shiftKey && activeEl === last) {
610
+ event.preventDefault();
611
+ first.focus();
612
+ }
613
+ };
614
+ root.addEventListener("keydown", handleKeyDown);
615
+ return () => root.removeEventListener("keydown", handleKeyDown);
616
+ }, [active]);
617
+ return ref;
618
+ }
619
+ function CraftModal({
620
+ open,
621
+ defaultOpen = false,
622
+ onOpenChange,
623
+ tone,
624
+ title,
625
+ description,
626
+ children,
627
+ trigger,
628
+ footer,
629
+ className
630
+ }) {
631
+ const [uncontrolledOpen, setUncontrolledOpen] = React6.useState(defaultOpen);
632
+ const isControlled = typeof open === "boolean";
633
+ const isOpen = isControlled ? open : uncontrolledOpen;
634
+ const setOpen = React6.useCallback(
635
+ (next) => {
636
+ if (!isControlled) {
637
+ setUncontrolledOpen(next);
638
+ }
639
+ onOpenChange == null ? void 0 : onOpenChange(next);
640
+ },
641
+ [isControlled, onOpenChange]
642
+ );
643
+ React6.useEffect(() => {
644
+ if (!isOpen) return;
645
+ const handleKey = (event) => {
646
+ if (event.key === "Escape") setOpen(false);
647
+ };
648
+ document.addEventListener("keydown", handleKey);
649
+ return () => document.removeEventListener("keydown", handleKey);
650
+ }, [isOpen, setOpen]);
651
+ const ref = useFocusTrap(isOpen);
652
+ const content = isOpen ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "fixed inset-0 z-50 flex items-center justify-center px-4 py-8", children: [
653
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
654
+ "div",
655
+ {
656
+ className: "absolute inset-0 backdrop-blur-sm",
657
+ onClick: () => setOpen(false)
658
+ }
659
+ ),
660
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
661
+ "div",
662
+ {
663
+ ref,
664
+ tabIndex: -1,
665
+ className: cn(
666
+ "relative z-10 w-full max-w-7xl rounded-3xl border border-[rgb(var(--nc-border)/0.45)] p-6 text-[rgb(var(--nc-fg))] shadow-[0_20px_60px_rgba(0,0,0,0.45)] backdrop-blur-2xl",
667
+ "max-h-[calc(100vh-1rem)] overflow-y-auto",
668
+ className
669
+ ),
670
+ "data-nc-theme": tone,
671
+ children: [
672
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-start justify-between gap-4", children: [
673
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "space-y-1", children: [
674
+ title && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h3", { className: "text-2xl font-semibold", children: title }),
675
+ description && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-[rgb(var(--nc-fg-muted))]", children: description })
676
+ ] }),
677
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
678
+ "button",
679
+ {
680
+ className: "rounded-full border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] p-2 text-[rgb(var(--nc-fg-soft))] transition hover:text-[rgb(var(--nc-fg))]",
681
+ onClick: () => setOpen(false),
682
+ "aria-label": "Close",
683
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("svg", { viewBox: "0 0 20 20", className: "h-4 w-4", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" }) })
684
+ }
685
+ )
686
+ ] }),
687
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "mt-5 space-y-4", children }),
688
+ footer && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "mt-6", children: footer })
689
+ ]
690
+ }
691
+ )
692
+ ] }) : null;
693
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
694
+ trigger && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
695
+ "span",
696
+ {
697
+ onClick: () => setOpen(true),
698
+ onKeyDown: (event) => {
699
+ if (event.key === "Enter" || event.key === " ") setOpen(true);
700
+ },
701
+ role: "button",
702
+ tabIndex: 0,
703
+ className: "inline-flex",
704
+ children: trigger
705
+ }
706
+ ),
707
+ typeof document !== "undefined" && content ? (0, import_react_dom.createPortal)(content, document.body) : content
708
+ ] });
709
+ }
710
+
711
+ // src/components/craft-drawer.tsx
712
+ var React7 = __toESM(require("react"), 1);
713
+ var import_react_dom2 = require("react-dom");
714
+ var import_jsx_runtime14 = require("react/jsx-runtime");
715
+ function CraftDrawer({
716
+ open,
717
+ defaultOpen = false,
718
+ onOpenChange,
719
+ tone,
720
+ side = "left",
721
+ title,
722
+ children,
723
+ trigger,
724
+ footer,
725
+ className
726
+ }) {
727
+ const [uncontrolledOpen, setUncontrolledOpen] = React7.useState(defaultOpen);
728
+ const isControlled = typeof open === "boolean";
729
+ const isOpen = isControlled ? open : uncontrolledOpen;
730
+ const setOpen = React7.useCallback(
731
+ (next) => {
732
+ if (!isControlled) setUncontrolledOpen(next);
733
+ onOpenChange == null ? void 0 : onOpenChange(next);
734
+ },
735
+ [isControlled, onOpenChange]
736
+ );
737
+ React7.useEffect(() => {
738
+ if (!isOpen) return;
739
+ const handleKey = (event) => {
740
+ if (event.key === "Escape") setOpen(false);
741
+ };
742
+ document.addEventListener("keydown", handleKey);
743
+ return () => document.removeEventListener("keydown", handleKey);
744
+ }, [isOpen, setOpen]);
745
+ const content = isOpen ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "fixed inset-0 z-50 overflow-hidden", children: [
746
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
747
+ "div",
748
+ {
749
+ className: "absolute inset-0 backdrop-blur-sm",
750
+ onClick: () => setOpen(false)
751
+ }
752
+ ),
753
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
754
+ "div",
755
+ {
756
+ className: cn(
757
+ "absolute top-0 h-full w-full max-w-md border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] text-[rgb(var(--nc-fg))] shadow-[0_20px_60px_rgba(0,0,0,0.45)] backdrop-blur-2xl",
758
+ side === "right" ? "right-0" : "left-0",
759
+ className
760
+ ),
761
+ "data-nc-theme": tone,
762
+ children: [
763
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-between border-b border-[rgb(var(--nc-border)/0.3)] p-6", children: [
764
+ title && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h3", { className: "text-xl font-semibold", children: title }),
765
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
766
+ "button",
767
+ {
768
+ className: "rounded-full border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] p-2 text-[rgb(var(--nc-fg-soft))] transition hover:text-[rgb(var(--nc-fg))]",
769
+ onClick: () => setOpen(false),
770
+ "aria-label": "Close",
771
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { viewBox: "0 0 20 20", className: "h-4 w-4", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" }) })
772
+ }
773
+ )
774
+ ] }),
775
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "p-6 space-y-4 overflow-y-auto h-[calc(100%-5.5rem)]", children }),
776
+ footer && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "border-t border-[rgb(var(--nc-border)/0.3)] p-6", children: footer })
777
+ ]
778
+ }
779
+ )
780
+ ] }) : null;
781
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
782
+ trigger && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
783
+ "span",
784
+ {
785
+ onClick: () => setOpen(true),
786
+ onKeyDown: (event) => {
787
+ if (event.key === "Enter" || event.key === " ") setOpen(true);
788
+ },
789
+ role: "button",
790
+ tabIndex: 0,
791
+ className: "inline-flex",
792
+ children: trigger
793
+ }
794
+ ),
795
+ typeof document !== "undefined" && content ? (0, import_react_dom2.createPortal)(content, document.body) : content
796
+ ] });
797
+ }
798
+
799
+ // src/components/craft-tabs.tsx
800
+ var React8 = __toESM(require("react"), 1);
801
+ var import_jsx_runtime15 = require("react/jsx-runtime");
802
+ function CraftTabs({
803
+ value,
804
+ defaultValue,
805
+ onValueChange,
806
+ tone,
807
+ tabs,
808
+ panels,
809
+ className
810
+ }) {
811
+ var _a, _b;
812
+ const fallback = (_b = (_a = tabs[0]) == null ? void 0 : _a.value) != null ? _b : "";
813
+ const [uncontrolledValue, setUncontrolledValue] = React8.useState(
814
+ defaultValue != null ? defaultValue : fallback
815
+ );
816
+ const isControlled = value !== void 0;
817
+ const activeValue = isControlled ? value : uncontrolledValue;
818
+ const setValue = React8.useCallback(
819
+ (next) => {
820
+ if (!isControlled) setUncontrolledValue(next);
821
+ onValueChange == null ? void 0 : onValueChange(next);
822
+ },
823
+ [isControlled, onValueChange]
824
+ );
825
+ const onKeyDown = (event) => {
826
+ if (!tabs.length) return;
827
+ const currentIndex = tabs.findIndex((tab) => tab.value === activeValue);
828
+ if (event.key === "ArrowRight") {
829
+ event.preventDefault();
830
+ const next = tabs[(currentIndex + 1) % tabs.length];
831
+ setValue(next.value);
832
+ }
833
+ if (event.key === "ArrowLeft") {
834
+ event.preventDefault();
835
+ const next = tabs[(currentIndex - 1 + tabs.length) % tabs.length];
836
+ setValue(next.value);
837
+ }
838
+ };
839
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: cn("space-y-4", className), "data-nc-theme": tone, children: [
840
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
841
+ "div",
842
+ {
843
+ className: "inline-flex flex-wrap items-center gap-2 rounded-full border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.08)] p-2",
844
+ role: "tablist",
845
+ onKeyDown,
846
+ children: tabs.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
847
+ "button",
848
+ {
849
+ role: "tab",
850
+ "aria-selected": activeValue === tab.value,
851
+ onClick: () => setValue(tab.value),
852
+ className: cn(
853
+ "rounded-full px-4 py-2 text-sm font-semibold transition-all",
854
+ activeValue === tab.value ? "bg-[rgb(var(--nc-accent-1)/0.65)] text-white shadow-[0_7px_5px_rgb(var(--nc-accent-1)/0.35)]" : "text-[rgb(var(--nc-fg-muted))] hover:text-[rgb(var(--nc-fg))]"
855
+ ),
856
+ children: tab.label
857
+ },
858
+ tab.value
859
+ ))
860
+ }
861
+ ),
862
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "rounded-2xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.08)] p-4 text-[rgb(var(--nc-fg))]", children: panels[activeValue] })
863
+ ] });
864
+ }
865
+
866
+ // src/components/craft-tooltip.tsx
867
+ var React9 = __toESM(require("react"), 1);
868
+ var import_jsx_runtime16 = require("react/jsx-runtime");
869
+ function CraftTooltip({ content, tone, children, side = "top" }) {
870
+ const [open, setOpen] = React9.useState(false);
871
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
872
+ "span",
873
+ {
874
+ className: "relative inline-flex",
875
+ onMouseEnter: () => setOpen(true),
876
+ onMouseLeave: () => setOpen(false),
877
+ onFocus: () => setOpen(true),
878
+ onBlur: () => setOpen(false),
879
+ children: [
880
+ children,
881
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
882
+ "span",
883
+ {
884
+ className: cn(
885
+ "pointer-events-none absolute z-20 whitespace-nowrap rounded-lg border border-white/10 bg-black/80 px-3 py-2 text-xs text-white shadow-lg transition-all",
886
+ "backdrop-blur-xl",
887
+ open ? "opacity-100 translate-y-0" : "opacity-0 translate-y-1",
888
+ side === "top" && "bottom-full left-1/2 -translate-x-1/2 -translate-y-2",
889
+ side === "bottom" && "top-full left-1/2 -translate-x-1/2 translate-y-2",
890
+ side === "left" && "right-full top-1/2 -translate-y-1/2 -translate-x-2",
891
+ side === "right" && "left-full top-1/2 -translate-y-1/2 translate-x-2"
892
+ ),
893
+ "data-nc-theme": tone,
894
+ role: "tooltip",
895
+ children: content
896
+ }
897
+ )
898
+ ]
899
+ }
900
+ );
901
+ }
902
+
903
+ // src/components/craft-toast.tsx
904
+ var React10 = __toESM(require("react"), 1);
905
+ var import_jsx_runtime17 = require("react/jsx-runtime");
906
+ var variantClasses4 = {
907
+ info: "border-[color:rgb(var(--nc-accent-1)/0.4)]",
908
+ success: "border-emerald-400/40",
909
+ warning: "border-amber-400/40",
910
+ error: "border-rose-400/40"
911
+ };
912
+ function useCraftToast() {
913
+ const [toasts, setToasts] = React10.useState([]);
914
+ const push = React10.useCallback((toast) => {
915
+ const id = `${Date.now()}-${Math.random().toString(16).slice(2)}`;
916
+ setToasts((prev) => [...prev, { ...toast, id }]);
917
+ return id;
918
+ }, []);
919
+ const remove = React10.useCallback((id) => {
920
+ setToasts((prev) => prev.filter((toast) => toast.id !== id));
921
+ }, []);
922
+ return { toasts, push, remove };
923
+ }
924
+ function CraftToastHost({ toasts, onDismiss, tone }) {
925
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
926
+ "div",
927
+ {
928
+ className: "fixed right-6 top-6 z-50 flex w-full max-w-sm flex-col gap-3",
929
+ "data-nc-theme": tone,
930
+ children: toasts.map((toast) => {
931
+ var _a;
932
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
933
+ "div",
934
+ {
935
+ className: cn(
936
+ "rounded-2xl border bg-[rgb(var(--nc-surface)/0.12)] p-4 text-[rgb(var(--nc-fg))] shadow-[0_15px_35px_rgba(0,0,0,0.35)] backdrop-blur-xl",
937
+ variantClasses4[(_a = toast.variant) != null ? _a : "info"]
938
+ ),
939
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-start justify-between gap-4", children: [
940
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
941
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-sm font-semibold", children: toast.title }),
942
+ toast.description && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-xs text-[rgb(var(--nc-fg-muted))]", children: toast.description })
943
+ ] }),
944
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
945
+ "button",
946
+ {
947
+ className: "text-[rgb(var(--nc-fg-soft))] hover:text-[rgb(var(--nc-fg))]",
948
+ onClick: () => onDismiss(toast.id),
949
+ children: "\u2715"
950
+ }
951
+ )
952
+ ] })
953
+ },
954
+ toast.id
955
+ );
956
+ })
957
+ }
958
+ );
959
+ }
960
+
961
+ // src/components/craft-skeleton.tsx
962
+ var import_jsx_runtime18 = require("react/jsx-runtime");
963
+ function CraftSkeleton({ className, tone, ...props }) {
964
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
965
+ "div",
966
+ {
967
+ className: cn(
968
+ "relative overflow-hidden rounded-2xl bg-[rgb(var(--nc-surface)/0.12)]",
969
+ "after:absolute after:inset-0 after:-translate-x-full after:bg-linear-to-r after:from-transparent after:via-white/20 after:to-transparent",
970
+ "after:animate-[shimmer_1.6s_infinite]",
971
+ className
972
+ ),
973
+ "data-nc-theme": tone,
974
+ ...props
975
+ }
976
+ );
977
+ }
978
+
979
+ // src/components/craft-empty-state.tsx
980
+ var import_jsx_runtime19 = require("react/jsx-runtime");
981
+ function CraftEmptyState({
982
+ className,
983
+ tone,
984
+ title,
985
+ description,
986
+ icon,
987
+ action,
988
+ ...props
989
+ }) {
990
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
991
+ "div",
992
+ {
993
+ className: cn(
994
+ "rounded-3xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.08)] p-8 text-center text-[rgb(var(--nc-fg))] backdrop-blur-xl",
995
+ "shadow-[0_18px_40px_rgba(0,0,0,0.25)]",
996
+ className
997
+ ),
998
+ "data-nc-theme": tone,
999
+ ...props,
1000
+ children: [
1001
+ icon && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-2xl bg-[rgb(var(--nc-accent-1)/0.2)] text-[rgb(var(--nc-accent-1))]", children: icon }),
1002
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h3", { className: "text-xl font-semibold", children: title }),
1003
+ description && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "mt-2 text-sm text-[rgb(var(--nc-fg-muted))]", children: description }),
1004
+ action && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "mt-6 flex justify-center", children: action })
1005
+ ]
1006
+ }
1007
+ );
1008
+ }
1009
+
1010
+ // src/components/craft-popover.tsx
1011
+ var React11 = __toESM(require("react"), 1);
1012
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1013
+ var alignClasses = {
1014
+ start: "left-0",
1015
+ center: "left-1/2 -translate-x-1/2",
1016
+ end: "right-0"
1017
+ };
1018
+ function CraftPopover({
1019
+ open,
1020
+ defaultOpen = false,
1021
+ onOpenChange,
1022
+ trigger,
1023
+ content,
1024
+ align = "start",
1025
+ sideOffset = 10,
1026
+ tone,
1027
+ className,
1028
+ contentClassName
1029
+ }) {
1030
+ const [uncontrolledOpen, setUncontrolledOpen] = React11.useState(defaultOpen);
1031
+ const isControlled = typeof open === "boolean";
1032
+ const isOpen = isControlled ? open : uncontrolledOpen;
1033
+ const rootRef = React11.useRef(null);
1034
+ const setOpen = React11.useCallback(
1035
+ (next) => {
1036
+ if (!isControlled) setUncontrolledOpen(next);
1037
+ onOpenChange == null ? void 0 : onOpenChange(next);
1038
+ },
1039
+ [isControlled, onOpenChange]
1040
+ );
1041
+ React11.useEffect(() => {
1042
+ if (!isOpen) return;
1043
+ const handleClick = (event) => {
1044
+ if (!rootRef.current) return;
1045
+ if (!rootRef.current.contains(event.target)) setOpen(false);
1046
+ };
1047
+ const handleKey = (event) => {
1048
+ if (event.key === "Escape") setOpen(false);
1049
+ };
1050
+ document.addEventListener("mousedown", handleClick);
1051
+ document.addEventListener("keydown", handleKey);
1052
+ return () => {
1053
+ document.removeEventListener("mousedown", handleClick);
1054
+ document.removeEventListener("keydown", handleKey);
1055
+ };
1056
+ }, [isOpen, setOpen]);
1057
+ const triggerNode = React11.isValidElement(trigger) ? React11.cloneElement(trigger, {
1058
+ onClick: (event) => {
1059
+ const handler = trigger.props.onClick;
1060
+ handler == null ? void 0 : handler(event);
1061
+ if (!event.defaultPrevented) setOpen(!isOpen);
1062
+ },
1063
+ "aria-expanded": isOpen,
1064
+ "aria-haspopup": "dialog"
1065
+ }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1066
+ "button",
1067
+ {
1068
+ type: "button",
1069
+ onClick: () => setOpen(!isOpen),
1070
+ className: "inline-flex",
1071
+ "aria-expanded": isOpen,
1072
+ "aria-haspopup": "dialog",
1073
+ children: trigger
1074
+ }
1075
+ );
1076
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: cn("relative inline-flex", className), ref: rootRef, children: [
1077
+ triggerNode,
1078
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1079
+ "div",
1080
+ {
1081
+ className: cn(
1082
+ "absolute z-40 w-max min-w-48 rounded-2xl border border-[rgb(var(--nc-border)/0.35)] bg-[rgb(var(--nc-surface)/0.08)] p-3 text-[rgb(var(--nc-fg))] shadow-[0_18px_40px_rgba(0,0,0,0.35)] backdrop-blur-2xl",
1083
+ alignClasses[align],
1084
+ contentClassName
1085
+ ),
1086
+ style: { marginTop: sideOffset },
1087
+ role: "dialog",
1088
+ "data-nc-theme": tone,
1089
+ children: content
1090
+ }
1091
+ )
1092
+ ] });
1093
+ }
1094
+
1095
+ // src/components/craft-dropdown-menu.tsx
1096
+ var React12 = __toESM(require("react"), 1);
1097
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1098
+ function CraftDropdownMenu({
1099
+ trigger,
1100
+ items = [],
1101
+ content,
1102
+ open,
1103
+ defaultOpen = false,
1104
+ onOpenChange,
1105
+ align = "end",
1106
+ tone,
1107
+ className,
1108
+ menuClassName
1109
+ }) {
1110
+ const [uncontrolledOpen, setUncontrolledOpen] = React12.useState(defaultOpen);
1111
+ const isControlled = typeof open === "boolean";
1112
+ const isOpen = isControlled ? open : uncontrolledOpen;
1113
+ const setOpen = React12.useCallback(
1114
+ (next) => {
1115
+ if (!isControlled) setUncontrolledOpen(next);
1116
+ onOpenChange == null ? void 0 : onOpenChange(next);
1117
+ },
1118
+ [isControlled, onOpenChange]
1119
+ );
1120
+ const menuContent = content != null ? content : items.length ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: cn("space-y-1", menuClassName), role: "menu", children: items.map((item, index) => {
1121
+ var _a;
1122
+ const key = (_a = item.id) != null ? _a : `${index}-${String(item.label)}`;
1123
+ const itemClasses = cn(
1124
+ "flex w-full items-start gap-3 rounded-xl px-3 py-2 text-left text-sm transition",
1125
+ item.disabled ? "cursor-not-allowed text-[rgb(var(--nc-fg-soft))] opacity-60" : "text-[rgb(var(--nc-fg))] hover:bg-[rgb(var(--nc-surface)/0.12)]"
1126
+ );
1127
+ const contentNode = /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
1128
+ item.icon && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "mt-0.5", children: item.icon }),
1129
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "flex-1", children: [
1130
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "block font-medium", children: item.label }),
1131
+ item.description && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "block text-xs text-[rgb(var(--nc-fg-muted))]", children: item.description })
1132
+ ] })
1133
+ ] });
1134
+ if (item.href) {
1135
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1136
+ "a",
1137
+ {
1138
+ href: item.href,
1139
+ className: itemClasses,
1140
+ role: "menuitem",
1141
+ onClick: () => {
1142
+ var _a2;
1143
+ if (item.disabled) return;
1144
+ (_a2 = item.onSelect) == null ? void 0 : _a2.call(item);
1145
+ setOpen(false);
1146
+ },
1147
+ children: contentNode
1148
+ },
1149
+ key
1150
+ );
1151
+ }
1152
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1153
+ "button",
1154
+ {
1155
+ type: "button",
1156
+ className: itemClasses,
1157
+ role: "menuitem",
1158
+ onClick: () => {
1159
+ var _a2;
1160
+ if (item.disabled) return;
1161
+ (_a2 = item.onSelect) == null ? void 0 : _a2.call(item);
1162
+ setOpen(false);
1163
+ },
1164
+ children: contentNode
1165
+ },
1166
+ key
1167
+ );
1168
+ }) }) : null;
1169
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1170
+ CraftPopover,
1171
+ {
1172
+ trigger,
1173
+ content: menuContent,
1174
+ open: isOpen,
1175
+ onOpenChange: setOpen,
1176
+ align,
1177
+ tone,
1178
+ className
1179
+ }
1180
+ );
1181
+ }
1182
+
1183
+ // src/components/craft-command-palette.tsx
1184
+ var React13 = __toESM(require("react"), 1);
1185
+ var import_jsx_runtime22 = require("react/jsx-runtime");
1186
+ function CraftCommandPalette({
1187
+ items,
1188
+ open,
1189
+ defaultOpen = false,
1190
+ onOpenChange,
1191
+ trigger,
1192
+ title = "Command Palette",
1193
+ placeholder = "Search commands...",
1194
+ emptyText = "No results found.",
1195
+ tone,
1196
+ className
1197
+ }) {
1198
+ const [uncontrolledOpen, setUncontrolledOpen] = React13.useState(defaultOpen);
1199
+ const isControlled = typeof open === "boolean";
1200
+ const isOpen = isControlled ? open : uncontrolledOpen;
1201
+ const [query, setQuery] = React13.useState("");
1202
+ const setOpen = React13.useCallback(
1203
+ (next) => {
1204
+ if (!isControlled) setUncontrolledOpen(next);
1205
+ onOpenChange == null ? void 0 : onOpenChange(next);
1206
+ },
1207
+ [isControlled, onOpenChange]
1208
+ );
1209
+ const filtered = React13.useMemo(() => {
1210
+ const q = query.trim().toLowerCase();
1211
+ if (!q) return items;
1212
+ return items.filter((item) => {
1213
+ var _a, _b;
1214
+ const haystack = [
1215
+ item.label,
1216
+ (_a = item.description) != null ? _a : "",
1217
+ ...(_b = item.keywords) != null ? _b : []
1218
+ ].join(" ").toLowerCase();
1219
+ return haystack.includes(q);
1220
+ });
1221
+ }, [items, query]);
1222
+ React13.useEffect(() => {
1223
+ if (!isOpen) setQuery("");
1224
+ }, [isOpen]);
1225
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1226
+ CraftModal,
1227
+ {
1228
+ open: isOpen,
1229
+ onOpenChange: setOpen,
1230
+ trigger,
1231
+ title,
1232
+ tone,
1233
+ className: cn("max-w-xl", className),
1234
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-4", children: [
1235
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1236
+ CraftInput,
1237
+ {
1238
+ type: "search",
1239
+ placeholder,
1240
+ value: query,
1241
+ onChange: (event) => setQuery(event.target.value)
1242
+ }
1243
+ ),
1244
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-2", children: [
1245
+ filtered.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "rounded-2xl border border-[rgb(var(--nc-border)/0.35)] bg-[rgb(var(--nc-surface)/0.12)] p-4 text-sm text-[rgb(var(--nc-fg-muted))]", children: emptyText }),
1246
+ filtered.map((item) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
1247
+ "button",
1248
+ {
1249
+ type: "button",
1250
+ disabled: item.disabled,
1251
+ onClick: () => {
1252
+ var _a;
1253
+ if (item.disabled) return;
1254
+ (_a = item.onSelect) == null ? void 0 : _a.call(item);
1255
+ setOpen(false);
1256
+ },
1257
+ className: cn(
1258
+ "flex w-full items-start gap-3 rounded-2xl border border-[rgb(var(--nc-border)/0.35)] bg-[rgb(var(--nc-surface)/0.08)] px-4 py-3 text-left transition",
1259
+ item.disabled ? "cursor-not-allowed opacity-60" : "hover:bg-[rgb(var(--nc-surface)/0.16)]"
1260
+ ),
1261
+ children: [
1262
+ item.icon && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "mt-1", children: item.icon }),
1263
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { children: [
1264
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "block text-sm font-semibold", children: item.label }),
1265
+ item.description && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "block text-xs text-[rgb(var(--nc-fg-muted))]", children: item.description })
1266
+ ] })
1267
+ ]
1268
+ },
1269
+ item.id
1270
+ ))
1271
+ ] })
1272
+ ] })
1273
+ }
1274
+ );
1275
+ }
1276
+
1277
+ // src/components/craft-link.tsx
1278
+ var import_link = __toESM(require("next/link"), 1);
1279
+ var import_jsx_runtime23 = require("react/jsx-runtime");
1280
+ var variantClasses5 = {
1281
+ default: "text-[rgb(var(--nc-accent-1))] hover:text-[rgb(var(--nc-accent-1))]",
1282
+ muted: "text-[rgb(var(--nc-fg-muted))] hover:text-[rgb(var(--nc-fg))]",
1283
+ button: "inline-flex items-center rounded-xl border border-[rgb(var(--nc-border)/0.35)] bg-[rgb(var(--nc-surface)/0.12)] px-4 py-2 text-sm font-semibold text-[rgb(var(--nc-fg))] transition hover:bg-[rgb(var(--nc-surface)/0.2)]",
1284
+ ghost: "inline-flex items-center rounded-xl px-4 py-2 text-sm font-semibold text-[rgb(var(--nc-fg))] transition hover:bg-[rgb(var(--nc-surface)/0.18)]"
1285
+ };
1286
+ function CraftLink({
1287
+ variant = "default",
1288
+ underline = false,
1289
+ tone,
1290
+ className,
1291
+ children,
1292
+ ...props
1293
+ }) {
1294
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1295
+ import_link.default,
1296
+ {
1297
+ className: cn(
1298
+ "transition-colors",
1299
+ variantClasses5[variant],
1300
+ underline && "underline underline-offset-4",
1301
+ className
1302
+ ),
1303
+ "data-nc-theme": tone,
1304
+ ...props,
1305
+ children
1306
+ }
1307
+ );
1308
+ }
1309
+
1310
+ // src/components/craft-stat-card.tsx
1311
+ var import_jsx_runtime24 = require("react/jsx-runtime");
1312
+ var trendClasses = {
1313
+ up: "text-emerald-300",
1314
+ down: "text-rose-300",
1315
+ neutral: "text-[rgb(var(--nc-fg-muted))]"
1316
+ };
1317
+ function CraftStatCard({
1318
+ label,
1319
+ value,
1320
+ delta,
1321
+ trend = "neutral",
1322
+ icon,
1323
+ footer,
1324
+ tone,
1325
+ className,
1326
+ ...props
1327
+ }) {
1328
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
1329
+ CraftCard,
1330
+ {
1331
+ className: cn("space-y-3", className),
1332
+ tone,
1333
+ ...props,
1334
+ children: [
1335
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center justify-between", children: [
1336
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-sm text-[rgb(var(--nc-fg-muted))]", children: label }),
1337
+ icon && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "text-[rgb(var(--nc-fg-soft))]", children: icon })
1338
+ ] }),
1339
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-3xl font-semibold", children: value }),
1340
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center justify-between text-xs", children: [
1341
+ delta && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: trendClasses[trend], children: delta }),
1342
+ footer && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-[rgb(var(--nc-fg-muted))]", children: footer })
1343
+ ] })
1344
+ ]
1345
+ }
1346
+ );
1347
+ }
1348
+
1349
+ // src/components/craft-date-picker.tsx
1350
+ var React14 = __toESM(require("react"), 1);
1351
+ var import_jsx_runtime25 = require("react/jsx-runtime");
1352
+ var WEEK_DAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
1353
+ function formatDate(date) {
1354
+ const year = date.getFullYear();
1355
+ const month = `${date.getMonth() + 1}`.padStart(2, "0");
1356
+ const day = `${date.getDate()}`.padStart(2, "0");
1357
+ return `${year}-${month}-${day}`;
1358
+ }
1359
+ function parseDate(value) {
1360
+ if (!value) return null;
1361
+ const [year, month, day] = value.split("-").map(Number);
1362
+ if (!year || !month || !day) return null;
1363
+ return new Date(year, month - 1, day);
1364
+ }
1365
+ function isSameDay(a, b) {
1366
+ return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
1367
+ }
1368
+ function isOutsideRange(date, min, max) {
1369
+ const minDate = parseDate(min);
1370
+ const maxDate = parseDate(max);
1371
+ if (minDate && date < minDate) return true;
1372
+ if (maxDate && date > maxDate) return true;
1373
+ return false;
1374
+ }
1375
+ function CraftDatePicker({
1376
+ value,
1377
+ defaultValue,
1378
+ onChange,
1379
+ tone,
1380
+ min,
1381
+ max,
1382
+ placeholder = "Select date",
1383
+ className
1384
+ }) {
1385
+ const [open, setOpen] = React14.useState(false);
1386
+ const [uncontrolledValue, setUncontrolledValue] = React14.useState(defaultValue != null ? defaultValue : "");
1387
+ const isControlled = value !== void 0;
1388
+ const selectedValue = isControlled ? value != null ? value : "" : uncontrolledValue;
1389
+ const selectedDate = parseDate(selectedValue);
1390
+ const initialMonth = selectedDate != null ? selectedDate : /* @__PURE__ */ new Date();
1391
+ const [viewDate, setViewDate] = React14.useState(initialMonth);
1392
+ React14.useEffect(() => {
1393
+ if (selectedDate) setViewDate(selectedDate);
1394
+ }, [selectedDate]);
1395
+ const wrapperRef = React14.useRef(null);
1396
+ React14.useEffect(() => {
1397
+ if (!open) return;
1398
+ const handleClick = (event) => {
1399
+ var _a;
1400
+ if (!((_a = wrapperRef.current) == null ? void 0 : _a.contains(event.target))) {
1401
+ setOpen(false);
1402
+ }
1403
+ };
1404
+ const handleKey = (event) => {
1405
+ if (event.key === "Escape") setOpen(false);
1406
+ };
1407
+ document.addEventListener("mousedown", handleClick);
1408
+ document.addEventListener("keydown", handleKey);
1409
+ return () => {
1410
+ document.removeEventListener("mousedown", handleClick);
1411
+ document.removeEventListener("keydown", handleKey);
1412
+ };
1413
+ }, [open]);
1414
+ const setValue = React14.useCallback(
1415
+ (next) => {
1416
+ if (!isControlled) setUncontrolledValue(next);
1417
+ onChange == null ? void 0 : onChange(next);
1418
+ },
1419
+ [isControlled, onChange]
1420
+ );
1421
+ const monthStart = new Date(viewDate.getFullYear(), viewDate.getMonth(), 1);
1422
+ const monthEnd = new Date(viewDate.getFullYear(), viewDate.getMonth() + 1, 0);
1423
+ const startDay = monthStart.getDay();
1424
+ const daysInMonth = monthEnd.getDate();
1425
+ const cells = Array.from({ length: startDay + daysInMonth }, (_, i) => {
1426
+ const dayNumber = i - startDay + 1;
1427
+ if (dayNumber < 1) return null;
1428
+ return new Date(viewDate.getFullYear(), viewDate.getMonth(), dayNumber);
1429
+ });
1430
+ const handleDaySelect = (date) => {
1431
+ if (isOutsideRange(date, min, max)) return;
1432
+ const next = formatDate(date);
1433
+ setValue(next);
1434
+ setOpen(false);
1435
+ };
1436
+ const handleKeyDown = (event) => {
1437
+ if (!open) return;
1438
+ if (!selectedDate) return;
1439
+ const next = new Date(selectedDate);
1440
+ if (event.key === "ArrowRight") next.setDate(next.getDate() + 1);
1441
+ if (event.key === "ArrowLeft") next.setDate(next.getDate() - 1);
1442
+ if (event.key === "ArrowDown") next.setDate(next.getDate() + 7);
1443
+ if (event.key === "ArrowUp") next.setDate(next.getDate() - 7);
1444
+ if (event.key === "Enter") {
1445
+ event.preventDefault();
1446
+ handleDaySelect(selectedDate);
1447
+ return;
1448
+ }
1449
+ if (next.getTime() !== selectedDate.getTime()) {
1450
+ event.preventDefault();
1451
+ if (!isOutsideRange(next, min, max)) {
1452
+ setValue(formatDate(next));
1453
+ setViewDate(next);
1454
+ }
1455
+ }
1456
+ };
1457
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "relative w-full", "data-nc-theme": tone, ref: wrapperRef, children: [
1458
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
1459
+ "button",
1460
+ {
1461
+ type: "button",
1462
+ onClick: () => setOpen((prev) => !prev),
1463
+ className: cn(
1464
+ "flex w-full items-center justify-between rounded-2xl border-2 bg-[rgb(var(--nc-surface)/0.08)] px-5 py-3 text-left text-base text-[rgb(var(--nc-fg))] backdrop-blur-xl",
1465
+ "shadow-[inset_0_2px_8px_rgba(0,0,0,0.3)]",
1466
+ "transition-all duration-300",
1467
+ "border-[rgb(var(--nc-border)/0.35)]",
1468
+ "focus:outline-none focus:ring-4 focus:ring-[rgb(var(--nc-accent-1)/0.3)]",
1469
+ className
1470
+ ),
1471
+ children: [
1472
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: selectedValue ? "text-[rgb(var(--nc-fg))]" : "text-[rgb(var(--nc-fg-soft))]", children: selectedValue || placeholder }),
1473
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("svg", { className: "h-4 w-4 text-[rgb(var(--nc-fg-soft))]", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("path", { d: "M6 2a1 1 0 011 1v1h6V3a1 1 0 112 0v1h1a2 2 0 012 2v10a2 2 0 01-2 2H4a2 2 0 01-2-2V6a2 2 0 012-2h1V3a1 1 0 011-1zm10 6H4v8h12V8z" }) })
1474
+ ]
1475
+ }
1476
+ ),
1477
+ open && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
1478
+ "div",
1479
+ {
1480
+ className: cn(
1481
+ "absolute left-0 top-full z-20 mt-3 w-full rounded-3xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/1.52)] p-4 text-[rgb(var(--nc-fg))] shadow-[0_20px_60px_rgba(0,0,0,0.55)] backdrop-blur-10xl"
1482
+ ),
1483
+ onKeyDown: handleKeyDown,
1484
+ tabIndex: -1,
1485
+ children: [
1486
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center justify-between", children: [
1487
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1488
+ "button",
1489
+ {
1490
+ type: "button",
1491
+ className: "rounded-xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] px-3 py-1 text-sm text-[rgb(var(--nc-fg))]",
1492
+ onClick: () => setViewDate(
1493
+ new Date(viewDate.getFullYear(), viewDate.getMonth() - 1, 1)
1494
+ ),
1495
+ children: "Prev"
1496
+ }
1497
+ ),
1498
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "text-sm font-semibold", children: viewDate.toLocaleString(void 0, { month: "long", year: "numeric" }) }),
1499
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1500
+ "button",
1501
+ {
1502
+ type: "button",
1503
+ className: "rounded-xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] px-3 py-1 text-sm text-[rgb(var(--nc-fg))]",
1504
+ onClick: () => setViewDate(
1505
+ new Date(viewDate.getFullYear(), viewDate.getMonth() + 1, 1)
1506
+ ),
1507
+ children: "Next"
1508
+ }
1509
+ )
1510
+ ] }),
1511
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "mt-4 grid grid-cols-7 gap-2 text-xs text-[rgb(var(--nc-fg-muted))]", children: WEEK_DAYS.map((day) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "text-center", children: day }, day)) }),
1512
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "mt-2 grid grid-cols-7 gap-2", children: cells.map((date, index) => {
1513
+ if (!date) return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", {}, `empty-${index}`);
1514
+ const disabled = isOutsideRange(date, min, max);
1515
+ const selected = selectedDate && isSameDay(date, selectedDate);
1516
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1517
+ "button",
1518
+ {
1519
+ type: "button",
1520
+ onClick: () => handleDaySelect(date),
1521
+ disabled,
1522
+ className: cn(
1523
+ "rounded-lg py-2 text-sm transition-all",
1524
+ selected ? "bg-[rgb(var(--nc-accent-1)/0.3)] text-[rgb(var(--nc-fg))]" : "text-[rgb(var(--nc-fg-muted))] hover:bg-[rgb(var(--nc-surface)/0.12)]",
1525
+ disabled && "opacity-40 hover:bg-transparent"
1526
+ ),
1527
+ children: date.getDate()
1528
+ },
1529
+ date.toISOString()
1530
+ );
1531
+ }) })
1532
+ ]
1533
+ }
1534
+ )
1535
+ ] });
1536
+ }
1537
+
1538
+ // src/components/craft-icon.tsx
1539
+ var React15 = __toESM(require("react"), 1);
1540
+ var import_jsx_runtime26 = require("react/jsx-runtime");
1541
+ var CraftIconContext = React15.createContext(null);
1542
+ function CraftIconProvider({ icons, children }) {
1543
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(CraftIconContext.Provider, { value: icons, children });
1544
+ }
1545
+ function CraftIcon({
1546
+ name,
1547
+ className,
1548
+ "aria-label": ariaLabel,
1549
+ icons,
1550
+ useLucide = true
1551
+ }) {
1552
+ const contextRegistry = React15.useContext(CraftIconContext);
1553
+ const registry = icons != null ? icons : contextRegistry;
1554
+ const icon = registry == null ? void 0 : registry[name];
1555
+ const [LucideIcon, setLucideIcon] = React15.useState(
1556
+ null
1557
+ );
1558
+ React15.useEffect(() => {
1559
+ if (!useLucide || icon || LucideIcon) return;
1560
+ let mounted = true;
1561
+ (async () => {
1562
+ try {
1563
+ const mod = await Function(
1564
+ "return import('lucide-react/dynamic')"
1565
+ )();
1566
+ if (mounted) {
1567
+ setLucideIcon(() => mod.DynamicIcon);
1568
+ }
1569
+ } catch {
1570
+ if (mounted) setLucideIcon(null);
1571
+ }
1572
+ })();
1573
+ return () => {
1574
+ mounted = false;
1575
+ };
1576
+ }, [LucideIcon, icon, useLucide]);
1577
+ if (!icon) {
1578
+ if (!useLucide) return null;
1579
+ if (!LucideIcon) return null;
1580
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1581
+ LucideIcon,
1582
+ {
1583
+ name,
1584
+ className,
1585
+ "aria-hidden": ariaLabel ? void 0 : true,
1586
+ "aria-label": ariaLabel
1587
+ }
1588
+ );
1589
+ }
1590
+ if (React15.isValidElement(icon)) {
1591
+ return React15.cloneElement(icon, {
1592
+ className: cn(icon.props.className, className),
1593
+ "aria-hidden": ariaLabel ? void 0 : true,
1594
+ "aria-label": ariaLabel
1595
+ });
1596
+ }
1597
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className, "aria-label": ariaLabel, children: icon });
1598
+ }
1599
+
1600
+ // src/components/craft-number-input.tsx
1601
+ var React16 = __toESM(require("react"), 1);
1602
+ var import_jsx_runtime27 = require("react/jsx-runtime");
1603
+ var CraftNumberInput = React16.forwardRef(({ className, tone, ...props }, ref) => {
1604
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "relative w-full", "data-nc-theme": tone, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
1605
+ "input",
1606
+ {
1607
+ ref,
1608
+ type: "number",
1609
+ className: cn(
1610
+ "w-full rounded-2xl border-2 bg-[rgb(var(--nc-surface)/0.08)] text-[rgb(var(--nc-fg))] backdrop-blur-xl",
1611
+ "shadow-[inset_0_2px_8px_rgba(0,0,0,0.3)]",
1612
+ "focus:outline-none focus:ring-4",
1613
+ "transition-all duration-300",
1614
+ "disabled:opacity-50 disabled:cursor-not-allowed",
1615
+ "border-[rgb(var(--nc-border)/0.35)]",
1616
+ "focus:border-[rgb(var(--nc-accent-1)/0.8)] focus:ring-[rgb(var(--nc-accent-1)/0.3)]",
1617
+ "px-5 py-3 text-base",
1618
+ className
1619
+ ),
1620
+ ...props
1621
+ }
1622
+ ) });
1623
+ });
1624
+ CraftNumberInput.displayName = "CraftNumberInput";
1625
+
1626
+ // src/components/craft-currency-input.tsx
1627
+ var React17 = __toESM(require("react"), 1);
1628
+ var import_jsx_runtime28 = require("react/jsx-runtime");
1629
+ var CraftCurrencyInput = React17.forwardRef(({ className, tone, currencySymbol = "$", ...props }, ref) => {
1630
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "relative w-full", "data-nc-theme": tone, children: [
1631
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "pointer-events-none absolute left-4 top-1/2 -translate-y-1/2 text-[rgb(var(--nc-fg-soft))]", children: currencySymbol }),
1632
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
1633
+ "input",
1634
+ {
1635
+ ref,
1636
+ type: "text",
1637
+ inputMode: "decimal",
1638
+ className: cn(
1639
+ "w-full rounded-2xl border-2 bg-[rgb(var(--nc-surface)/0.08)] text-[rgb(var(--nc-fg))] backdrop-blur-xl",
1640
+ "shadow-[inset_0_2px_8px_rgba(0,0,0,0.3)]",
1641
+ "focus:outline-none focus:ring-4",
1642
+ "transition-all duration-300",
1643
+ "disabled:opacity-50 disabled:cursor-not-allowed",
1644
+ "border-[rgb(var(--nc-border)/0.35)]",
1645
+ "focus:border-[rgb(var(--nc-accent-1)/0.8)] focus:ring-[rgb(var(--nc-accent-1)/0.3)]",
1646
+ "placeholder:text-[rgb(var(--nc-fg-soft))]",
1647
+ "px-5 py-3 pl-9 text-base",
1648
+ className
1649
+ ),
1650
+ ...props
1651
+ }
1652
+ )
1653
+ ] });
1654
+ });
1655
+ CraftCurrencyInput.displayName = "CraftCurrencyInput";
1656
+
1657
+ // src/components/craft-form.tsx
1658
+ var React18 = __toESM(require("react"), 1);
1659
+ var import_react_hook_form2 = require("react-hook-form");
1660
+
1661
+ // src/components/craft-submit-button.tsx
1662
+ var import_react_hook_form = require("react-hook-form");
1663
+ var import_jsx_runtime29 = require("react/jsx-runtime");
1664
+ function CraftSubmitButton({
1665
+ className,
1666
+ tone,
1667
+ loading,
1668
+ loadingLabel = "Submitting...",
1669
+ disableWhenInvalid = true,
1670
+ disabled,
1671
+ children,
1672
+ ...props
1673
+ }) {
1674
+ var _a, _b, _c, _d;
1675
+ const form = (0, import_react_hook_form.useFormContext)();
1676
+ const isSubmitting = (_b = loading != null ? loading : (_a = form == null ? void 0 : form.formState) == null ? void 0 : _a.isSubmitting) != null ? _b : false;
1677
+ const isValid = (_d = (_c = form == null ? void 0 : form.formState) == null ? void 0 : _c.isValid) != null ? _d : true;
1678
+ const isDisabled = disabled || isSubmitting || disableWhenInvalid && !isValid;
1679
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
1680
+ "button",
1681
+ {
1682
+ type: "submit",
1683
+ className: cn(
1684
+ "relative inline-flex items-center justify-center gap-2 rounded-xl px-6 py-2 text-sm font-semibold",
1685
+ "bg-linear-to-br from-[rgb(var(--nc-accent-1))] via-[rgb(var(--nc-accent-2))] to-[rgb(var(--nc-accent-3))]",
1686
+ "text-white shadow-[0_12px_30px_rgb(var(--nc-accent-1)/0.35)]",
1687
+ "transition-all duration-200",
1688
+ "hover:shadow-[0_16px_36px_rgb(var(--nc-accent-1)/0.5)] hover:scale-[1.02] active:scale-[0.98]",
1689
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[rgb(var(--nc-accent-1)/0.6)]",
1690
+ "disabled:opacity-60 disabled:cursor-not-allowed disabled:hover:scale-100",
1691
+ className
1692
+ ),
1693
+ "data-nc-theme": tone,
1694
+ disabled: isDisabled,
1695
+ ...props,
1696
+ children: [
1697
+ isSubmitting && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "inline-flex h-4 w-4 animate-spin rounded-full border-2 border-white/60 border-t-white" }),
1698
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: isSubmitting ? loadingLabel : children })
1699
+ ]
1700
+ }
1701
+ );
1702
+ }
1703
+
1704
+ // src/components/craft-form.tsx
1705
+ var import_jsx_runtime30 = require("react/jsx-runtime");
1706
+ function CraftForm({
1707
+ form,
1708
+ onSubmit,
1709
+ open,
1710
+ defaultOpen = false,
1711
+ onOpenChange,
1712
+ trigger,
1713
+ title,
1714
+ description,
1715
+ submitLabel = "Save",
1716
+ cancelLabel = "Cancel",
1717
+ tone,
1718
+ className,
1719
+ children,
1720
+ footer,
1721
+ disableSubmitWhenInvalid = true,
1722
+ closeOnSubmit = true,
1723
+ formClassName
1724
+ }) {
1725
+ const [uncontrolledOpen, setUncontrolledOpen] = React18.useState(defaultOpen);
1726
+ const isControlled = typeof open === "boolean";
1727
+ const isOpen = isControlled ? open : uncontrolledOpen;
1728
+ const setOpen = React18.useCallback(
1729
+ (next) => {
1730
+ if (!isControlled) setUncontrolledOpen(next);
1731
+ onOpenChange == null ? void 0 : onOpenChange(next);
1732
+ },
1733
+ [isControlled, onOpenChange]
1734
+ );
1735
+ const formId = React18.useId();
1736
+ const handleSubmit = form.handleSubmit(async (values) => {
1737
+ await onSubmit(values);
1738
+ if (closeOnSubmit) setOpen(false);
1739
+ });
1740
+ const footerContent = footer != null ? footer : /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-wrap items-center justify-end gap-3", children: [
1741
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(CraftButton, { type: "button", variant: "ghost", onClick: () => setOpen(false), children: cancelLabel }),
1742
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1743
+ CraftSubmitButton,
1744
+ {
1745
+ form: formId,
1746
+ disableWhenInvalid: disableSubmitWhenInvalid,
1747
+ children: submitLabel
1748
+ }
1749
+ )
1750
+ ] });
1751
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react_hook_form2.FormProvider, { ...form, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1752
+ CraftModal,
1753
+ {
1754
+ open: isOpen,
1755
+ onOpenChange: setOpen,
1756
+ trigger,
1757
+ title,
1758
+ description,
1759
+ tone,
1760
+ className,
1761
+ footer: footerContent,
1762
+ children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1763
+ "form",
1764
+ {
1765
+ id: formId,
1766
+ onSubmit: handleSubmit,
1767
+ className: cn("space-y-5", formClassName),
1768
+ children
1769
+ }
1770
+ )
1771
+ }
1772
+ ) });
1773
+ }
1774
+
1775
+ // src/components/craft-form-builder.tsx
1776
+ var React19 = __toESM(require("react"), 1);
1777
+ var import_react_hook_form4 = require("react-hook-form");
1778
+
1779
+ // src/components/craft-form-field.tsx
1780
+ var import_react_hook_form3 = require("react-hook-form");
1781
+ var import_jsx_runtime31 = require("react/jsx-runtime");
1782
+ function getFieldError(errors, name) {
1783
+ if (!errors || typeof errors !== "object") return void 0;
1784
+ const segments = name.split(".");
1785
+ let current = errors;
1786
+ for (const segment of segments) {
1787
+ if (!current || typeof current !== "object") return void 0;
1788
+ current = current[segment];
1789
+ }
1790
+ return current;
1791
+ }
1792
+ var baseInputClass = "w-full rounded-2xl border-2 bg-[rgb(var(--nc-surface)/0.08)] text-[rgb(var(--nc-fg))] backdrop-blur-xl shadow-[inset_0_2px_8px_rgba(0,0,0,0.3)] focus:outline-none focus:ring-4 transition-all duration-300 disabled:opacity-50 disabled:cursor-not-allowed border-[rgb(var(--nc-border)/0.35)] focus:border-[rgb(var(--nc-accent-1)/0.8)] focus:ring-[rgb(var(--nc-accent-1)/0.3)] px-5 py-3 text-base placeholder:text-[rgb(var(--nc-fg-soft))]";
1793
+ function CraftFormField({
1794
+ name,
1795
+ label,
1796
+ description,
1797
+ type = "text",
1798
+ options = [],
1799
+ placeholder,
1800
+ tone,
1801
+ className,
1802
+ inputClassName,
1803
+ labelClassName,
1804
+ descriptionClassName,
1805
+ rules,
1806
+ disabled,
1807
+ fieldProps
1808
+ }) {
1809
+ const { register, control, formState } = (0, import_react_hook_form3.useFormContext)();
1810
+ const error = getFieldError(formState.errors, name);
1811
+ const errorMessage = typeof (error == null ? void 0 : error.message) === "string" ? error.message : void 0;
1812
+ if (type === "hidden") {
1813
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("input", { type: "hidden", ...register(name, rules) });
1814
+ }
1815
+ const labelNode = label ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1816
+ "label",
1817
+ {
1818
+ htmlFor: name,
1819
+ className: cn(
1820
+ "text-sm font-semibold text-[rgb(var(--nc-fg))]",
1821
+ labelClassName
1822
+ ),
1823
+ children: label
1824
+ }
1825
+ ) : null;
1826
+ const descriptionNode = description ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1827
+ "p",
1828
+ {
1829
+ className: cn(
1830
+ "text-xs text-[rgb(var(--nc-fg-muted))]",
1831
+ descriptionClassName
1832
+ ),
1833
+ children: description
1834
+ }
1835
+ ) : null;
1836
+ const errorNode = errorMessage ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { className: "text-xs text-[rgb(var(--nc-accent-3))]", children: errorMessage }) : null;
1837
+ const renderInput = () => {
1838
+ if (type === "textarea") {
1839
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1840
+ CraftTextarea,
1841
+ {
1842
+ id: name,
1843
+ placeholder,
1844
+ tone,
1845
+ className: inputClassName,
1846
+ disabled,
1847
+ ...fieldProps,
1848
+ ...register(name, rules)
1849
+ }
1850
+ );
1851
+ }
1852
+ if (type === "select" || type === "multiselect") {
1853
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
1854
+ CraftSelect,
1855
+ {
1856
+ id: name,
1857
+ tone,
1858
+ className: inputClassName,
1859
+ multiple: type === "multiselect",
1860
+ disabled,
1861
+ ...fieldProps,
1862
+ ...register(name, rules),
1863
+ children: [
1864
+ placeholder && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("option", { value: "", disabled: true, children: placeholder }),
1865
+ options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1866
+ "option",
1867
+ {
1868
+ value: option.value,
1869
+ disabled: option.disabled,
1870
+ children: option.label
1871
+ },
1872
+ option.value
1873
+ ))
1874
+ ]
1875
+ }
1876
+ );
1877
+ }
1878
+ if (type === "checkbox") {
1879
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1880
+ CraftCheckbox,
1881
+ {
1882
+ tone,
1883
+ label,
1884
+ description,
1885
+ disabled,
1886
+ ...fieldProps,
1887
+ ...register(name, rules)
1888
+ }
1889
+ );
1890
+ }
1891
+ if (type === "switch") {
1892
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1893
+ CraftSwitch,
1894
+ {
1895
+ tone,
1896
+ label,
1897
+ disabled,
1898
+ ...fieldProps,
1899
+ ...register(name, rules)
1900
+ }
1901
+ );
1902
+ }
1903
+ if (type === "date") {
1904
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1905
+ import_react_hook_form3.Controller,
1906
+ {
1907
+ control,
1908
+ name,
1909
+ rules,
1910
+ render: ({ field }) => {
1911
+ var _a;
1912
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1913
+ CraftDatePicker,
1914
+ {
1915
+ value: (_a = field.value) != null ? _a : "",
1916
+ onChange: field.onChange,
1917
+ tone,
1918
+ placeholder,
1919
+ ...fieldProps
1920
+ }
1921
+ );
1922
+ }
1923
+ }
1924
+ );
1925
+ }
1926
+ if (type === "number") {
1927
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1928
+ CraftNumberInput,
1929
+ {
1930
+ id: name,
1931
+ tone,
1932
+ placeholder,
1933
+ className: inputClassName,
1934
+ disabled,
1935
+ ...fieldProps,
1936
+ ...register(name, rules)
1937
+ }
1938
+ );
1939
+ }
1940
+ if (type === "currency") {
1941
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1942
+ CraftCurrencyInput,
1943
+ {
1944
+ id: name,
1945
+ tone,
1946
+ placeholder,
1947
+ className: inputClassName,
1948
+ disabled,
1949
+ ...fieldProps,
1950
+ ...register(name, rules)
1951
+ }
1952
+ );
1953
+ }
1954
+ if (type === "radio") {
1955
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "grid gap-3", children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
1956
+ "label",
1957
+ {
1958
+ className: cn(
1959
+ "flex items-center gap-3 rounded-2xl border border-[rgb(var(--nc-border)/0.35)] bg-[rgb(var(--nc-surface)/0.08)] px-4 py-3 text-sm text-[rgb(var(--nc-fg))]",
1960
+ "transition-all duration-200",
1961
+ "focus-within:ring-2 focus-within:ring-[rgb(var(--nc-accent-1)/0.5)]",
1962
+ option.disabled ? "opacity-60" : "cursor-pointer"
1963
+ ),
1964
+ "data-nc-theme": tone,
1965
+ children: [
1966
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1967
+ "input",
1968
+ {
1969
+ type: "radio",
1970
+ value: option.value,
1971
+ disabled: option.disabled || disabled,
1972
+ className: "h-4 w-4 accent-[rgb(var(--nc-accent-1))]",
1973
+ ...fieldProps,
1974
+ ...register(name, rules)
1975
+ }
1976
+ ),
1977
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { children: option.label })
1978
+ ]
1979
+ },
1980
+ option.value
1981
+ )) });
1982
+ }
1983
+ if (type === "range" || type === "slider") {
1984
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1985
+ "input",
1986
+ {
1987
+ id: name,
1988
+ type: "range",
1989
+ className: cn(
1990
+ "w-full accent-[rgb(var(--nc-accent-1))]",
1991
+ inputClassName
1992
+ ),
1993
+ disabled,
1994
+ ...fieldProps,
1995
+ ...register(name, rules)
1996
+ }
1997
+ );
1998
+ }
1999
+ if (type === "file" || type === "multifile") {
2000
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2001
+ "input",
2002
+ {
2003
+ id: name,
2004
+ type: "file",
2005
+ multiple: type === "multifile",
2006
+ className: cn(
2007
+ baseInputClass,
2008
+ "file:mr-4 file:rounded-xl file:border-0 file:bg-[rgb(var(--nc-surface)/0.35)] file:px-4 file:py-2 file:text-sm file:font-semibold file:text-[rgb(var(--nc-fg))]",
2009
+ inputClassName
2010
+ ),
2011
+ disabled,
2012
+ ...fieldProps,
2013
+ ...register(name, rules)
2014
+ }
2015
+ );
2016
+ }
2017
+ const inputType = type === "search" || type === "password" || type === "email" || type === "tel" || type === "url" || type === "time" || type === "datetime-local" || type === "month" || type === "week" || type === "color" ? type : "text";
2018
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2019
+ CraftInput,
2020
+ {
2021
+ id: name,
2022
+ type: inputType,
2023
+ placeholder,
2024
+ tone,
2025
+ className: inputClassName,
2026
+ disabled,
2027
+ ...fieldProps,
2028
+ ...register(name, rules)
2029
+ }
2030
+ );
2031
+ };
2032
+ const showLabel = type !== "checkbox" && type !== "switch";
2033
+ const showDescriptionAbove = type !== "checkbox" && type !== "switch";
2034
+ const showDescriptionBelow = type === "switch";
2035
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: cn("space-y-2", className), "data-nc-theme": tone, children: [
2036
+ showLabel ? labelNode : null,
2037
+ showDescriptionAbove ? descriptionNode : null,
2038
+ renderInput(),
2039
+ showDescriptionBelow ? descriptionNode : null,
2040
+ errorNode
2041
+ ] });
2042
+ }
2043
+
2044
+ // src/components/craft-form-builder.tsx
2045
+ var import_jsx_runtime32 = require("react/jsx-runtime");
2046
+ function defaultValueForField(field) {
2047
+ var _a, _b, _c, _d;
2048
+ if (field.defaultValue !== void 0) return field.defaultValue;
2049
+ switch (field.type) {
2050
+ case "checkbox":
2051
+ case "switch":
2052
+ return false;
2053
+ case "number":
2054
+ case "slider":
2055
+ case "range":
2056
+ return (_a = field.min) != null ? _a : 0;
2057
+ case "multifile":
2058
+ return [];
2059
+ case "file":
2060
+ return null;
2061
+ case "multiselect":
2062
+ return [];
2063
+ case "radio":
2064
+ return (_d = (_c = (_b = field.options) == null ? void 0 : _b[0]) == null ? void 0 : _c.value) != null ? _d : "";
2065
+ default:
2066
+ return "";
2067
+ }
2068
+ }
2069
+ function buildDefaultValues(fields, initialData) {
2070
+ const values = {};
2071
+ fields.forEach((field) => {
2072
+ const initialValue = initialData == null ? void 0 : initialData[field.name];
2073
+ if (initialValue !== void 0 && initialValue !== null) {
2074
+ values[field.name] = initialValue;
2075
+ } else {
2076
+ values[field.name] = defaultValueForField(field);
2077
+ }
2078
+ });
2079
+ return values;
2080
+ }
2081
+ function buildRules(field, getValues) {
2082
+ var _a;
2083
+ const rules = { ...field.rules };
2084
+ const mergeValidate = (current, next) => {
2085
+ if (!current) return next;
2086
+ if (typeof current === "function") {
2087
+ return (value) => {
2088
+ const result = current(
2089
+ value,
2090
+ getValues()
2091
+ );
2092
+ if (result !== true) return result;
2093
+ return next(value);
2094
+ };
2095
+ }
2096
+ if (typeof current === "object") {
2097
+ return (value) => {
2098
+ const entries = Object.entries(current);
2099
+ for (const [, validator] of entries) {
2100
+ const result = validator(
2101
+ value,
2102
+ getValues()
2103
+ );
2104
+ if (result !== true) return result;
2105
+ }
2106
+ return next(value);
2107
+ };
2108
+ }
2109
+ return next;
2110
+ };
2111
+ if (field.required && field.type !== "hidden") {
2112
+ if (field.type === "checkbox" || field.type === "switch") {
2113
+ rules.validate = mergeValidate(
2114
+ rules.validate,
2115
+ (value) => {
2116
+ var _a2;
2117
+ return value ? true : `${String((_a2 = field.label) != null ? _a2 : field.name)} is required`;
2118
+ }
2119
+ );
2120
+ } else if (field.type === "multiselect") {
2121
+ rules.validate = mergeValidate(
2122
+ rules.validate,
2123
+ (value) => {
2124
+ var _a2;
2125
+ return Array.isArray(value) && value.length > 0 ? true : `${String((_a2 = field.label) != null ? _a2 : field.name)} is required`;
2126
+ }
2127
+ );
2128
+ } else if (field.type === "file") {
2129
+ rules.validate = mergeValidate(
2130
+ rules.validate,
2131
+ (value) => {
2132
+ var _a2;
2133
+ return value instanceof FileList && value.length > 0 ? true : `${String((_a2 = field.label) != null ? _a2 : field.name)} is required`;
2134
+ }
2135
+ );
2136
+ } else if (field.type === "multifile") {
2137
+ rules.validate = mergeValidate(
2138
+ rules.validate,
2139
+ (value) => {
2140
+ var _a2;
2141
+ return Array.isArray(value) && value.length > 0 ? true : `${String((_a2 = field.label) != null ? _a2 : field.name)} is required`;
2142
+ }
2143
+ );
2144
+ } else {
2145
+ rules.required = `${String((_a = field.label) != null ? _a : field.name)} is required`;
2146
+ }
2147
+ }
2148
+ if (field.min !== void 0) {
2149
+ rules.min = { value: field.min, message: `Min ${field.min}` };
2150
+ }
2151
+ if (field.max !== void 0) {
2152
+ rules.max = { value: field.max, message: `Max ${field.max}` };
2153
+ }
2154
+ if (field.type === "email") {
2155
+ rules.pattern = {
2156
+ value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
2157
+ message: "Please enter a valid email address"
2158
+ };
2159
+ }
2160
+ if (field.type === "url") {
2161
+ rules.pattern = {
2162
+ value: /^https?:\/\/.+/,
2163
+ message: "Please enter a valid URL"
2164
+ };
2165
+ }
2166
+ if (field.validate) {
2167
+ rules.validate = mergeValidate(
2168
+ rules.validate,
2169
+ (value) => {
2170
+ var _a2;
2171
+ return (_a2 = field.validate) == null ? void 0 : _a2.call(field, value, getValues());
2172
+ }
2173
+ );
2174
+ }
2175
+ return rules;
2176
+ }
2177
+ function CraftFormBuilder({
2178
+ title = "Form",
2179
+ description,
2180
+ fields,
2181
+ initialData = null,
2182
+ open,
2183
+ defaultOpen = false,
2184
+ onOpenChange,
2185
+ trigger,
2186
+ submitLabel = "Submit",
2187
+ cancelLabel = "Cancel",
2188
+ resetLabel = "Reset",
2189
+ showReset = true,
2190
+ showCancel = true,
2191
+ tone,
2192
+ className,
2193
+ formClassName,
2194
+ loading = false,
2195
+ disableSubmitWhenInvalid = true,
2196
+ closeOnSubmit = true,
2197
+ closeOnCancel = true,
2198
+ onSubmit,
2199
+ onReset,
2200
+ onCancel,
2201
+ customValidation
2202
+ }) {
2203
+ const [uncontrolledOpen, setUncontrolledOpen] = React19.useState(defaultOpen);
2204
+ const isControlled = typeof open === "boolean";
2205
+ const isOpen = isControlled ? open : uncontrolledOpen;
2206
+ const setOpen = React19.useCallback(
2207
+ (next) => {
2208
+ if (!isControlled) setUncontrolledOpen(next);
2209
+ onOpenChange == null ? void 0 : onOpenChange(next);
2210
+ },
2211
+ [isControlled, onOpenChange]
2212
+ );
2213
+ const defaultValues = React19.useMemo(
2214
+ () => buildDefaultValues(fields, initialData),
2215
+ [fields, initialData]
2216
+ );
2217
+ const form = (0, import_react_hook_form4.useForm)({
2218
+ mode: "onChange",
2219
+ defaultValues
2220
+ });
2221
+ const formId = React19.useId();
2222
+ React19.useEffect(() => {
2223
+ form.reset(defaultValues);
2224
+ }, [defaultValues, form]);
2225
+ const handleSubmit = form.handleSubmit(async (values) => {
2226
+ if (customValidation) {
2227
+ const customErrors = customValidation(values);
2228
+ if (customErrors && Object.keys(customErrors).length > 0) {
2229
+ Object.entries(customErrors).forEach(([key, message]) => {
2230
+ if (message) {
2231
+ form.setError(key, {
2232
+ type: "custom",
2233
+ message: String(message)
2234
+ });
2235
+ }
2236
+ });
2237
+ return;
2238
+ }
2239
+ }
2240
+ await onSubmit(values);
2241
+ if (closeOnSubmit) setOpen(false);
2242
+ });
2243
+ const handleReset = () => {
2244
+ form.reset(defaultValues);
2245
+ onReset == null ? void 0 : onReset();
2246
+ };
2247
+ const handleCancel = () => {
2248
+ onCancel == null ? void 0 : onCancel();
2249
+ if (closeOnCancel) setOpen(false);
2250
+ };
2251
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_react_hook_form4.FormProvider, { ...form, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2252
+ CraftModal,
2253
+ {
2254
+ open: isOpen,
2255
+ onOpenChange: setOpen,
2256
+ trigger,
2257
+ title,
2258
+ description,
2259
+ tone,
2260
+ className,
2261
+ footer: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-wrap items-center justify-end gap-3", children: [
2262
+ showReset && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2263
+ CraftButton,
2264
+ {
2265
+ type: "button",
2266
+ variant: "outline",
2267
+ onClick: handleReset,
2268
+ disabled: loading,
2269
+ children: resetLabel
2270
+ }
2271
+ ),
2272
+ showCancel && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2273
+ CraftButton,
2274
+ {
2275
+ type: "button",
2276
+ variant: "ghost",
2277
+ onClick: handleCancel,
2278
+ disabled: loading,
2279
+ children: cancelLabel
2280
+ }
2281
+ ),
2282
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2283
+ CraftSubmitButton,
2284
+ {
2285
+ loading,
2286
+ disableWhenInvalid: disableSubmitWhenInvalid,
2287
+ form: formId,
2288
+ children: submitLabel
2289
+ }
2290
+ )
2291
+ ] }),
2292
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2293
+ "form",
2294
+ {
2295
+ id: formId,
2296
+ onSubmit: handleSubmit,
2297
+ className: cn("space-y-5", formClassName),
2298
+ children: fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "space-y-2", children: [
2299
+ field.helpText && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { className: "text-xs text-[rgb(var(--nc-fg-muted))]", children: field.helpText }),
2300
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2301
+ CraftFormField,
2302
+ {
2303
+ name: field.name,
2304
+ label: field.label,
2305
+ description: field.description,
2306
+ type: field.type,
2307
+ placeholder: field.placeholder,
2308
+ options: field.options,
2309
+ tone,
2310
+ disabled: field.disabled || loading,
2311
+ rules: buildRules(field, form.getValues),
2312
+ fieldProps: {
2313
+ min: field.min,
2314
+ max: field.max,
2315
+ step: field.step,
2316
+ rows: field.rows,
2317
+ accept: field.accept,
2318
+ multiple: field.type === "multifile",
2319
+ ...field.fieldProps
2320
+ }
2321
+ }
2322
+ )
2323
+ ] }, field.name))
2324
+ }
2325
+ )
2326
+ }
2327
+ ) });
2328
+ }
2329
+
2330
+ // src/components/craft-confirm-dialog.tsx
2331
+ var React20 = __toESM(require("react"), 1);
2332
+ var import_jsx_runtime33 = require("react/jsx-runtime");
2333
+ function CraftConfirmDialog({
2334
+ open,
2335
+ defaultOpen = false,
2336
+ onOpenChange,
2337
+ tone,
2338
+ title = "Confirm action",
2339
+ description,
2340
+ confirmLabel = "Confirm",
2341
+ cancelLabel = "Cancel",
2342
+ onConfirm,
2343
+ trigger,
2344
+ className,
2345
+ confirmVariant = "solid"
2346
+ }) {
2347
+ const [uncontrolledOpen, setUncontrolledOpen] = React20.useState(defaultOpen);
2348
+ const isControlled = typeof open === "boolean";
2349
+ const isOpen = isControlled ? open : uncontrolledOpen;
2350
+ const setOpen = React20.useCallback(
2351
+ (next) => {
2352
+ if (!isControlled) setUncontrolledOpen(next);
2353
+ onOpenChange == null ? void 0 : onOpenChange(next);
2354
+ },
2355
+ [isControlled, onOpenChange]
2356
+ );
2357
+ const [isLoading, setIsLoading] = React20.useState(false);
2358
+ const handleConfirm = async () => {
2359
+ if (!onConfirm) {
2360
+ setOpen(false);
2361
+ return;
2362
+ }
2363
+ setIsLoading(true);
2364
+ await onConfirm();
2365
+ setIsLoading(false);
2366
+ setOpen(false);
2367
+ };
2368
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
2369
+ CraftModal,
2370
+ {
2371
+ open: isOpen,
2372
+ onOpenChange: setOpen,
2373
+ trigger,
2374
+ title,
2375
+ description,
2376
+ tone,
2377
+ className: cn("max-w-md", className),
2378
+ footer: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex flex-wrap items-center justify-end gap-3", children: [
2379
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
2380
+ CraftButton,
2381
+ {
2382
+ type: "button",
2383
+ variant: "ghost",
2384
+ onClick: () => setOpen(false),
2385
+ children: cancelLabel
2386
+ }
2387
+ ),
2388
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
2389
+ CraftButton,
2390
+ {
2391
+ type: "button",
2392
+ variant: confirmVariant,
2393
+ disabled: isLoading,
2394
+ onClick: handleConfirm,
2395
+ children: isLoading ? "Working..." : confirmLabel
2396
+ }
2397
+ )
2398
+ ] }),
2399
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "text-sm text-[rgb(var(--nc-fg-muted))]", children: description })
2400
+ }
2401
+ );
2402
+ }
2403
+
2404
+ // src/components/craft-create-edit-drawer.tsx
2405
+ var React21 = __toESM(require("react"), 1);
2406
+ var import_react_hook_form5 = require("react-hook-form");
2407
+ var import_jsx_runtime34 = require("react/jsx-runtime");
2408
+ function CraftCreateEditDrawer({
2409
+ mode = "create",
2410
+ form,
2411
+ onSubmit,
2412
+ open,
2413
+ defaultOpen = false,
2414
+ onOpenChange,
2415
+ trigger,
2416
+ title,
2417
+ description,
2418
+ submitLabel,
2419
+ cancelLabel = "Cancel",
2420
+ tone,
2421
+ className,
2422
+ children,
2423
+ footer,
2424
+ disableSubmitWhenInvalid = true,
2425
+ closeOnSubmit = true,
2426
+ side = "right"
2427
+ }) {
2428
+ const [uncontrolledOpen, setUncontrolledOpen] = React21.useState(defaultOpen);
2429
+ const isControlled = typeof open === "boolean";
2430
+ const isOpen = isControlled ? open : uncontrolledOpen;
2431
+ const setOpen = React21.useCallback(
2432
+ (next) => {
2433
+ if (!isControlled) setUncontrolledOpen(next);
2434
+ onOpenChange == null ? void 0 : onOpenChange(next);
2435
+ },
2436
+ [isControlled, onOpenChange]
2437
+ );
2438
+ const formId = React21.useId();
2439
+ const handleSubmit = form.handleSubmit(async (values) => {
2440
+ await onSubmit(values);
2441
+ if (closeOnSubmit) setOpen(false);
2442
+ });
2443
+ const resolvedTitle = title != null ? title : mode === "create" ? "Create item" : "Edit item";
2444
+ const resolvedSubmitLabel = submitLabel != null ? submitLabel : mode === "create" ? "Create" : "Save changes";
2445
+ const footerContent = footer != null ? footer : /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex flex-wrap items-center justify-end gap-3", children: [
2446
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(CraftButton, { type: "button", variant: "ghost", onClick: () => setOpen(false), children: cancelLabel }),
2447
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
2448
+ CraftSubmitButton,
2449
+ {
2450
+ form: formId,
2451
+ disableWhenInvalid: disableSubmitWhenInvalid,
2452
+ children: resolvedSubmitLabel
2453
+ }
2454
+ )
2455
+ ] });
2456
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react_hook_form5.FormProvider, { ...form, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
2457
+ CraftDrawer,
2458
+ {
2459
+ open: isOpen,
2460
+ onOpenChange: setOpen,
2461
+ trigger,
2462
+ title: resolvedTitle,
2463
+ tone,
2464
+ side,
2465
+ className: cn("flex flex-col", className),
2466
+ footer: footerContent,
2467
+ children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("form", { id: formId, onSubmit: handleSubmit, className: "space-y-5", children: [
2468
+ description && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: "text-sm text-[rgb(var(--nc-fg-muted))]", children: description }),
2469
+ children
2470
+ ] })
2471
+ }
2472
+ ) });
2473
+ }
2474
+
2475
+ // src/components/craft-filter-bar.tsx
2476
+ var import_jsx_runtime35 = require("react/jsx-runtime");
2477
+ function CraftFilterBar({
2478
+ title,
2479
+ description,
2480
+ searchValue,
2481
+ onSearchChange,
2482
+ searchPlaceholder = "Search...",
2483
+ actions,
2484
+ filters,
2485
+ tone,
2486
+ className
2487
+ }) {
2488
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
2489
+ "div",
2490
+ {
2491
+ className: cn(
2492
+ "rounded-3xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] p-4 text-[rgb(var(--nc-fg))] shadow-[0_12px_36px_rgba(0,0,0,0.2)] backdrop-blur-2xl",
2493
+ className
2494
+ ),
2495
+ "data-nc-theme": tone,
2496
+ children: [
2497
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-4", children: [
2498
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { children: [
2499
+ title && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("h3", { className: "text-lg font-semibold", children: title }),
2500
+ description && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: "text-sm text-[rgb(var(--nc-fg-muted))]", children: description })
2501
+ ] }),
2502
+ actions && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "flex items-center gap-3", children: actions })
2503
+ ] }),
2504
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "mt-4 grid gap-4 md:grid-cols-[minmax(0,1fr)_auto]", children: [
2505
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
2506
+ CraftInput,
2507
+ {
2508
+ type: "search",
2509
+ placeholder: searchPlaceholder,
2510
+ value: searchValue != null ? searchValue : "",
2511
+ onChange: (event) => onSearchChange == null ? void 0 : onSearchChange(event.target.value),
2512
+ tone
2513
+ }
2514
+ ),
2515
+ filters && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "flex flex-wrap items-center gap-3", children: filters })
2516
+ ] })
2517
+ ]
2518
+ }
2519
+ );
2520
+ }
2521
+
2522
+ // src/components/craft-table-toolbar.tsx
2523
+ var import_jsx_runtime36 = require("react/jsx-runtime");
2524
+ function CraftTableToolbar({
2525
+ title,
2526
+ description,
2527
+ searchValue,
2528
+ onSearchChange,
2529
+ searchPlaceholder = "Search table...",
2530
+ actions,
2531
+ filters,
2532
+ bulkActions,
2533
+ tone,
2534
+ className
2535
+ }) {
2536
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
2537
+ "div",
2538
+ {
2539
+ className: cn(
2540
+ "rounded-3xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] p-4 text-[rgb(var(--nc-fg))] shadow-[0_12px_36px_rgba(0,0,0,0.2)] backdrop-blur-2xl",
2541
+ className
2542
+ ),
2543
+ "data-nc-theme": tone,
2544
+ children: [
2545
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-4", children: [
2546
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { children: [
2547
+ title && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("h3", { className: "text-lg font-semibold", children: title }),
2548
+ description && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: "text-sm text-[rgb(var(--nc-fg-muted))]", children: description })
2549
+ ] }),
2550
+ actions && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "flex items-center gap-3", children: actions })
2551
+ ] }),
2552
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "mt-4 grid gap-4 lg:grid-cols-[minmax(0,1fr)_auto]", children: [
2553
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
2554
+ CraftInput,
2555
+ {
2556
+ type: "search",
2557
+ placeholder: searchPlaceholder,
2558
+ value: searchValue != null ? searchValue : "",
2559
+ onChange: (event) => onSearchChange == null ? void 0 : onSearchChange(event.target.value),
2560
+ tone
2561
+ }
2562
+ ),
2563
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
2564
+ filters,
2565
+ bulkActions
2566
+ ] })
2567
+ ] })
2568
+ ]
2569
+ }
2570
+ );
2571
+ }
2572
+
2573
+ // src/components/craft-data-table.tsx
2574
+ var React22 = __toESM(require("react"), 1);
2575
+
2576
+ // src/components/craft-pagination.tsx
2577
+ var import_jsx_runtime37 = require("react/jsx-runtime");
2578
+ function getPageNumbers(pageIndex, pageCount, maxButtons = 5) {
2579
+ if (pageCount <= maxButtons) {
2580
+ return Array.from({ length: pageCount }, (_, i) => i);
2581
+ }
2582
+ const pages = [];
2583
+ const start = Math.max(0, pageIndex - 1);
2584
+ const end = Math.min(pageCount - 1, pageIndex + 1);
2585
+ pages.push(0);
2586
+ if (start > 1) pages.push("ellipsis");
2587
+ for (let i = start; i <= end; i += 1) {
2588
+ if (i !== 0 && i !== pageCount - 1) pages.push(i);
2589
+ }
2590
+ if (end < pageCount - 2) pages.push("ellipsis");
2591
+ pages.push(pageCount - 1);
2592
+ return pages;
2593
+ }
2594
+ function CraftPagination({
2595
+ pageIndex,
2596
+ pageCount,
2597
+ onPageChange,
2598
+ canPrevious = pageIndex > 0,
2599
+ canNext = pageIndex < pageCount - 1,
2600
+ pageSize,
2601
+ pageSizeOptions = [10, 20, 50],
2602
+ onPageSizeChange,
2603
+ tone,
2604
+ className
2605
+ }) {
2606
+ const pages = getPageNumbers(pageIndex, pageCount);
2607
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
2608
+ "div",
2609
+ {
2610
+ className: cn(
2611
+ "flex flex-wrap items-center justify-between gap-4",
2612
+ className
2613
+ ),
2614
+ "data-nc-theme": tone,
2615
+ children: [
2616
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex items-center gap-2", children: [
2617
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2618
+ "button",
2619
+ {
2620
+ type: "button",
2621
+ className: cn(
2622
+ "rounded-xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] px-3 py-2 text-xs text-[rgb(var(--nc-fg))] transition",
2623
+ "hover:bg-[rgb(var(--nc-surface)/0.2)]",
2624
+ !canPrevious && "opacity-50 cursor-not-allowed"
2625
+ ),
2626
+ onClick: () => onPageChange(Math.max(pageIndex - 1, 0)),
2627
+ disabled: !canPrevious,
2628
+ children: "Prev"
2629
+ }
2630
+ ),
2631
+ pages.map(
2632
+ (page, index) => page === "ellipsis" ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "px-2 text-[rgb(var(--nc-fg-muted))]", children: "..." }, `ellipsis-${index}`) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2633
+ "button",
2634
+ {
2635
+ type: "button",
2636
+ className: cn(
2637
+ "rounded-xl border px-3 py-2 text-xs transition",
2638
+ page === pageIndex ? "border-[rgb(var(--nc-accent-1)/0.6)] bg-[rgb(var(--nc-accent-1)/0.2)] text-[rgb(var(--nc-fg))]" : "border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] text-[rgb(var(--nc-fg-muted))] hover:text-[rgb(var(--nc-fg))] hover:bg-[rgb(var(--nc-surface)/0.2)]"
2639
+ ),
2640
+ onClick: () => onPageChange(page),
2641
+ children: page + 1
2642
+ },
2643
+ page
2644
+ )
2645
+ ),
2646
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2647
+ "button",
2648
+ {
2649
+ type: "button",
2650
+ className: cn(
2651
+ "rounded-xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] px-3 py-2 text-xs text-[rgb(var(--nc-fg))] transition",
2652
+ "hover:bg-[rgb(var(--nc-surface)/0.2)]",
2653
+ !canNext && "opacity-50 cursor-not-allowed"
2654
+ ),
2655
+ onClick: () => onPageChange(Math.min(pageIndex + 1, pageCount - 1)),
2656
+ disabled: !canNext,
2657
+ children: "Next"
2658
+ }
2659
+ )
2660
+ ] }),
2661
+ onPageSizeChange && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex items-center gap-2 text-xs text-[rgb(var(--nc-fg-muted))]", children: [
2662
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { children: "Rows" }),
2663
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2664
+ "select",
2665
+ {
2666
+ className: "rounded-xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] px-2 py-1 text-xs text-[rgb(var(--nc-fg))]",
2667
+ value: pageSize,
2668
+ onChange: (event) => onPageSizeChange(Number(event.target.value)),
2669
+ children: pageSizeOptions.map((size) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("option", { value: size, children: size }, size))
2670
+ }
2671
+ )
2672
+ ] })
2673
+ ]
2674
+ }
2675
+ );
2676
+ }
2677
+
2678
+ // src/components/craft-data-table.tsx
2679
+ var import_jsx_runtime38 = require("react/jsx-runtime");
2680
+ function getColumnValue(column, row) {
2681
+ if (typeof column.accessor === "function") return column.accessor(row);
2682
+ const record = row;
2683
+ if (typeof column.accessor === "string") return record[column.accessor];
2684
+ return record[column.id];
2685
+ }
2686
+ function normalizeValue(value) {
2687
+ if (value === null || value === void 0) return "";
2688
+ if (typeof value === "number") return value;
2689
+ if (typeof value === "string") return value.toLowerCase();
2690
+ if (value instanceof Date) return value.getTime();
2691
+ return String(value).toLowerCase();
2692
+ }
2693
+ function CraftDataTable({
2694
+ data,
2695
+ columns,
2696
+ tone,
2697
+ className,
2698
+ loading = false,
2699
+ emptyState,
2700
+ toolbar,
2701
+ enableSorting = true,
2702
+ enableFiltering = true,
2703
+ enableColumnVisibility = true,
2704
+ enableRowSelection = true,
2705
+ enablePagination = true,
2706
+ showGlobalFilter,
2707
+ manualSorting = false,
2708
+ manualFiltering = false,
2709
+ manualPagination = false,
2710
+ sortBy,
2711
+ onSortChange,
2712
+ filters,
2713
+ onFiltersChange,
2714
+ globalFilter,
2715
+ onGlobalFilterChange,
2716
+ columnVisibility,
2717
+ onColumnVisibilityChange,
2718
+ selectedRowIds,
2719
+ onRowSelectionChange,
2720
+ getRowId,
2721
+ pageIndex,
2722
+ pageSize = 10,
2723
+ pageCount,
2724
+ onPageChange,
2725
+ onPageSizeChange
2726
+ }) {
2727
+ const [internalSort, setInternalSort] = React22.useState(null);
2728
+ const [internalFilters, setInternalFilters] = React22.useState({});
2729
+ const [internalGlobalFilter, setInternalGlobalFilter] = React22.useState("");
2730
+ const [internalVisibility, setInternalVisibility] = React22.useState(
2731
+ () => columns.reduce((acc, column) => {
2732
+ acc[column.id] = !column.hidden;
2733
+ return acc;
2734
+ }, {})
2735
+ );
2736
+ const [internalSelection, setInternalSelection] = React22.useState({});
2737
+ const [internalPageIndex, setInternalPageIndex] = React22.useState(0);
2738
+ const [showColumns, setShowColumns] = React22.useState(false);
2739
+ const resolvedSort = sortBy != null ? sortBy : internalSort;
2740
+ const resolvedFilters = filters != null ? filters : internalFilters;
2741
+ const resolvedGlobalFilter = globalFilter != null ? globalFilter : internalGlobalFilter;
2742
+ const resolvedVisibility = columnVisibility != null ? columnVisibility : internalVisibility;
2743
+ const resolvedSelection = selectedRowIds != null ? selectedRowIds : internalSelection;
2744
+ const resolvedPageIndex = pageIndex != null ? pageIndex : internalPageIndex;
2745
+ const setSort = (next) => {
2746
+ if (sortBy === void 0) setInternalSort(next);
2747
+ onSortChange == null ? void 0 : onSortChange(next);
2748
+ };
2749
+ const setFilters = (next) => {
2750
+ if (filters === void 0) setInternalFilters(next);
2751
+ onFiltersChange == null ? void 0 : onFiltersChange(next);
2752
+ };
2753
+ const setVisibility = (next) => {
2754
+ if (columnVisibility === void 0) setInternalVisibility(next);
2755
+ onColumnVisibilityChange == null ? void 0 : onColumnVisibilityChange(next);
2756
+ };
2757
+ const setSelection = (next) => {
2758
+ if (selectedRowIds === void 0) setInternalSelection(next);
2759
+ onRowSelectionChange == null ? void 0 : onRowSelectionChange(next);
2760
+ };
2761
+ const setPageIndex = React22.useCallback(
2762
+ (next) => {
2763
+ if (pageIndex === void 0) setInternalPageIndex(next);
2764
+ onPageChange == null ? void 0 : onPageChange(next);
2765
+ },
2766
+ [pageIndex, onPageChange]
2767
+ );
2768
+ const visibleColumns = columns.filter(
2769
+ (column) => resolvedVisibility[column.id] !== false
2770
+ );
2771
+ const filteredData = React22.useMemo(() => {
2772
+ if (manualFiltering) return data;
2773
+ const globalValue = resolvedGlobalFilter.trim();
2774
+ return data.filter((row) => {
2775
+ if (globalValue) {
2776
+ const matchesGlobal = columns.some((column) => {
2777
+ const value = normalizeValue(getColumnValue(column, row));
2778
+ return String(value).includes(globalValue.toLowerCase());
2779
+ });
2780
+ if (!matchesGlobal) return false;
2781
+ }
2782
+ return Object.entries(resolvedFilters).every(([columnId, value]) => {
2783
+ if (!value) return true;
2784
+ const column = columns.find((col) => col.id === columnId);
2785
+ if (!column) return true;
2786
+ const cellValue = normalizeValue(getColumnValue(column, row));
2787
+ return String(cellValue).includes(value.toLowerCase());
2788
+ });
2789
+ });
2790
+ }, [columns, data, manualFiltering, resolvedFilters, resolvedGlobalFilter]);
2791
+ const sortedData = React22.useMemo(() => {
2792
+ if (manualSorting || !resolvedSort) return filteredData;
2793
+ const column = columns.find((col) => col.id === resolvedSort.id);
2794
+ if (!column) return filteredData;
2795
+ const sorted = [...filteredData].sort((a, b) => {
2796
+ const valueA = normalizeValue(getColumnValue(column, a));
2797
+ const valueB = normalizeValue(getColumnValue(column, b));
2798
+ if (typeof valueA === "number" && typeof valueB === "number") {
2799
+ return valueA - valueB;
2800
+ }
2801
+ return String(valueA).localeCompare(String(valueB));
2802
+ });
2803
+ return resolvedSort.desc ? sorted.reverse() : sorted;
2804
+ }, [columns, filteredData, manualSorting, resolvedSort]);
2805
+ const resolvedPageCount = manualPagination ? Math.max(pageCount != null ? pageCount : 1, 1) : Math.max(Math.ceil(sortedData.length / pageSize), 1);
2806
+ React22.useEffect(() => {
2807
+ if (resolvedPageIndex > resolvedPageCount - 1) {
2808
+ setPageIndex(Math.max(resolvedPageCount - 1, 0));
2809
+ }
2810
+ }, [resolvedPageCount, resolvedPageIndex, setPageIndex]);
2811
+ const pagedData = React22.useMemo(() => {
2812
+ if (!enablePagination || manualPagination) return sortedData;
2813
+ const start = resolvedPageIndex * pageSize;
2814
+ return sortedData.slice(start, start + pageSize);
2815
+ }, [enablePagination, manualPagination, pageSize, resolvedPageIndex, sortedData]);
2816
+ const rowIdFor = React22.useCallback(
2817
+ (row, index) => {
2818
+ var _a;
2819
+ return (_a = getRowId == null ? void 0 : getRowId(row, index)) != null ? _a : String(index);
2820
+ },
2821
+ [getRowId]
2822
+ );
2823
+ const pageStartIndex = enablePagination && !manualPagination ? resolvedPageIndex * pageSize : 0;
2824
+ const pageRowIds = pagedData.map(
2825
+ (row, index) => rowIdFor(row, pageStartIndex + index)
2826
+ );
2827
+ const allSelected = pageRowIds.length > 0 && pageRowIds.every((id) => resolvedSelection[id]);
2828
+ const someSelected = pageRowIds.some((id) => resolvedSelection[id]);
2829
+ const headerCheckboxRef = React22.useRef(null);
2830
+ React22.useEffect(() => {
2831
+ if (headerCheckboxRef.current) {
2832
+ headerCheckboxRef.current.indeterminate = someSelected && !allSelected;
2833
+ }
2834
+ }, [someSelected, allSelected]);
2835
+ const toggleSort = (column) => {
2836
+ if (!enableSorting || column.sortable === false) return;
2837
+ const current = resolvedSort;
2838
+ if (!current || current.id !== column.id) {
2839
+ setSort({ id: column.id, desc: false });
2840
+ return;
2841
+ }
2842
+ if (!current.desc) {
2843
+ setSort({ id: column.id, desc: true });
2844
+ return;
2845
+ }
2846
+ setSort(null);
2847
+ };
2848
+ const emptyContent = emptyState != null ? emptyState : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "text-center text-sm text-[rgb(var(--nc-fg-muted))]", children: "No results found." });
2849
+ const resolvedShowGlobalFilter = showGlobalFilter != null ? showGlobalFilter : enableFiltering && !toolbar;
2850
+ const setGlobalFilter = (next) => {
2851
+ if (globalFilter === void 0) setInternalGlobalFilter(next);
2852
+ onGlobalFilterChange == null ? void 0 : onGlobalFilterChange(next);
2853
+ };
2854
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: cn("space-y-4", className), "data-nc-theme": tone, children: [
2855
+ toolbar,
2856
+ resolvedShowGlobalFilter && /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-center justify-between gap-3 rounded-2xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] px-3 py-2 text-sm text-[rgb(var(--nc-fg))]", children: [
2857
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "text-xs text-[rgb(var(--nc-fg-muted))]", children: "Global filter" }),
2858
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2859
+ "input",
2860
+ {
2861
+ type: "search",
2862
+ value: resolvedGlobalFilter,
2863
+ onChange: (event) => setGlobalFilter(event.target.value),
2864
+ placeholder: "Search all columns...",
2865
+ className: "w-full max-w-xs rounded-xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.18)] px-3 py-2 text-xs text-[rgb(var(--nc-fg))]"
2866
+ }
2867
+ )
2868
+ ] }),
2869
+ enableColumnVisibility && /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "relative flex justify-end", children: [
2870
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2871
+ "button",
2872
+ {
2873
+ type: "button",
2874
+ className: "rounded-xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] px-3 py-2 text-xs text-[rgb(var(--nc-fg))] transition hover:bg-[rgb(var(--nc-surface)/0.2)]",
2875
+ onClick: () => setShowColumns((prev) => !prev),
2876
+ children: "Columns"
2877
+ }
2878
+ ),
2879
+ showColumns && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "absolute right-0 top-10 z-20 w-48 rounded-2xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.2)] p-3 shadow-[0_12px_30px_rgba(0,0,0,0.35)] backdrop-blur-2xl", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "grid gap-2", children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
2880
+ "label",
2881
+ {
2882
+ className: "flex items-center gap-2 text-xs text-[rgb(var(--nc-fg))]",
2883
+ children: [
2884
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2885
+ "input",
2886
+ {
2887
+ type: "checkbox",
2888
+ className: "h-4 w-4 accent-[rgb(var(--nc-accent-1))]",
2889
+ checked: resolvedVisibility[column.id] !== false,
2890
+ onChange: (event) => setVisibility({
2891
+ ...resolvedVisibility,
2892
+ [column.id]: event.target.checked
2893
+ })
2894
+ }
2895
+ ),
2896
+ column.header
2897
+ ]
2898
+ },
2899
+ column.id
2900
+ )) }) })
2901
+ ] }),
2902
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "overflow-hidden rounded-3xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.08)] shadow-[0_18px_50px_rgba(0,0,0,0.35)] backdrop-blur-2xl", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("table", { className: "w-full border-collapse text-left text-sm", children: [
2903
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("thead", { className: "bg-[rgb(var(--nc-surface)/0.12)] text-[rgb(var(--nc-fg-muted))]", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("tr", { children: [
2904
+ enableRowSelection && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("th", { className: "w-12 px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2905
+ "input",
2906
+ {
2907
+ ref: headerCheckboxRef,
2908
+ type: "checkbox",
2909
+ className: "h-4 w-4 accent-[rgb(var(--nc-accent-1))]",
2910
+ checked: allSelected,
2911
+ onChange: (event) => {
2912
+ const next = { ...resolvedSelection };
2913
+ pageRowIds.forEach((id) => {
2914
+ next[id] = event.target.checked;
2915
+ });
2916
+ setSelection(next);
2917
+ }
2918
+ }
2919
+ ) }),
2920
+ visibleColumns.map((column) => {
2921
+ var _a;
2922
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
2923
+ "th",
2924
+ {
2925
+ className: cn(
2926
+ "px-4 py-3 text-xs font-semibold uppercase tracking-[0.2em]",
2927
+ column.headerClassName
2928
+ ),
2929
+ style: { width: column.width },
2930
+ children: [
2931
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
2932
+ "button",
2933
+ {
2934
+ type: "button",
2935
+ className: cn(
2936
+ "flex items-center gap-2",
2937
+ enableSorting && column.sortable !== false ? "cursor-pointer" : "cursor-default"
2938
+ ),
2939
+ onClick: () => toggleSort(column),
2940
+ children: [
2941
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { children: column.header }),
2942
+ (resolvedSort == null ? void 0 : resolvedSort.id) === column.id && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "text-[rgb(var(--nc-accent-1))]", children: resolvedSort.desc ? "\u2193" : "\u2191" })
2943
+ ]
2944
+ }
2945
+ ),
2946
+ enableFiltering && column.filterable !== false && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2947
+ "input",
2948
+ {
2949
+ type: "text",
2950
+ value: (_a = resolvedFilters[column.id]) != null ? _a : "",
2951
+ onChange: (event) => setFilters({
2952
+ ...resolvedFilters,
2953
+ [column.id]: event.target.value
2954
+ }),
2955
+ placeholder: "Filter",
2956
+ className: "mt-2 w-full rounded-xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.18)] px-2 py-1 text-xs text-[rgb(var(--nc-fg))]"
2957
+ }
2958
+ )
2959
+ ]
2960
+ },
2961
+ column.id
2962
+ );
2963
+ })
2964
+ ] }) }),
2965
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("tbody", { className: "text-[rgb(var(--nc-fg))]", children: [
2966
+ loading && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2967
+ "td",
2968
+ {
2969
+ colSpan: visibleColumns.length + (enableRowSelection ? 1 : 0),
2970
+ className: "px-4 py-10 text-center text-sm text-[rgb(var(--nc-fg-muted))]",
2971
+ children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("span", { className: "inline-flex items-center gap-2", children: [
2972
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "h-4 w-4 animate-spin rounded-full border-2 border-[rgb(var(--nc-fg-muted))] border-t-transparent" }),
2973
+ "Loading data..."
2974
+ ] })
2975
+ }
2976
+ ) }),
2977
+ !loading && pagedData.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2978
+ "td",
2979
+ {
2980
+ colSpan: visibleColumns.length + (enableRowSelection ? 1 : 0),
2981
+ className: "px-4 py-10",
2982
+ children: emptyContent
2983
+ }
2984
+ ) }),
2985
+ !loading && pagedData.map((row, rowIndex) => {
2986
+ const rowId = rowIdFor(row, pageStartIndex + rowIndex);
2987
+ const isSelected = resolvedSelection[rowId];
2988
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
2989
+ "tr",
2990
+ {
2991
+ className: cn(
2992
+ "border-t border-[rgb(var(--nc-border)/0.15)]",
2993
+ isSelected && "bg-[rgb(var(--nc-accent-1)/0.08)]"
2994
+ ),
2995
+ children: [
2996
+ enableRowSelection && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("td", { className: "px-4 py-4", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2997
+ "input",
2998
+ {
2999
+ type: "checkbox",
3000
+ className: "h-4 w-4 accent-[rgb(var(--nc-accent-1))]",
3001
+ checked: isSelected,
3002
+ onChange: (event) => setSelection({
3003
+ ...resolvedSelection,
3004
+ [rowId]: event.target.checked
3005
+ })
3006
+ }
3007
+ ) }),
3008
+ visibleColumns.map((column) => {
3009
+ var _a;
3010
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
3011
+ "td",
3012
+ {
3013
+ className: cn(
3014
+ "px-4 py-4",
3015
+ column.align === "center" && "text-center",
3016
+ column.align === "right" && "text-right",
3017
+ column.cellClassName
3018
+ ),
3019
+ children: column.cell ? column.cell(row) : String((_a = getColumnValue(column, row)) != null ? _a : "")
3020
+ },
3021
+ column.id
3022
+ );
3023
+ })
3024
+ ]
3025
+ },
3026
+ rowId
3027
+ );
3028
+ })
3029
+ ] })
3030
+ ] }) }),
3031
+ enablePagination && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
3032
+ CraftPagination,
3033
+ {
3034
+ pageIndex: resolvedPageIndex,
3035
+ pageCount: resolvedPageCount,
3036
+ onPageChange: setPageIndex,
3037
+ pageSize,
3038
+ onPageSizeChange,
3039
+ tone
3040
+ }
3041
+ )
3042
+ ] });
3043
+ }
3044
+
3045
+ // src/components/layout/app-shell.tsx
3046
+ var import_jsx_runtime39 = require("react/jsx-runtime");
3047
+ function AppShell({ className, sidebar, topNav, children, ...props }) {
3048
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
3049
+ "div",
3050
+ {
3051
+ className: cn(
3052
+ "grid min-h-screen grid-cols-1 gap-6 bg-background p-6 lg:grid-cols-[260px_1fr]",
3053
+ className
3054
+ ),
3055
+ ...props,
3056
+ children: [
3057
+ sidebar && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "h-full lg:sticky lg:top-6 lg:self-start lg:max-h-[calc(100vh-3rem)] lg:overflow-y-auto", children: sidebar }),
3058
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex flex-col gap-6", children: [
3059
+ topNav && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "lg:sticky lg:top-6 lg:z-20", children: topNav }),
3060
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("main", { className: "flex-1", children })
3061
+ ] })
3062
+ ]
3063
+ }
3064
+ );
3065
+ }
3066
+
3067
+ // src/components/layout/app-template.tsx
3068
+ var React23 = __toESM(require("react"), 1);
3069
+
3070
+ // src/components/layout/breadcrumbs.tsx
3071
+ var import_jsx_runtime40 = require("react/jsx-runtime");
3072
+ function Breadcrumbs({ className, items, ...props }) {
3073
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("nav", { className: cn("flex items-center text-sm text-[rgb(var(--nc-fg-muted))]", className), ...props, children: items.map((item, index) => {
3074
+ const content = item.href ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("a", { href: item.href, className: "transition hover:text-[rgb(var(--nc-fg))]", children: item.label }) : /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "text-[rgb(var(--nc-fg))]", children: item.label });
3075
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("span", { className: "flex items-center", children: [
3076
+ content,
3077
+ index < items.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "mx-2 text-[rgb(var(--nc-fg-soft))]", children: "/" })
3078
+ ] }, `${item.label}-${index}`);
3079
+ }) });
3080
+ }
3081
+
3082
+ // src/components/layout/sidebar.tsx
3083
+ var import_jsx_runtime41 = require("react/jsx-runtime");
3084
+ function Sidebar({ className, title, items, footer, ...props }) {
3085
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
3086
+ "aside",
3087
+ {
3088
+ className: cn(
3089
+ "flex h-full w-full flex-col gap-6 rounded-3xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.08)] p-6 text-[rgb(var(--nc-fg))] backdrop-blur-xl",
3090
+ className
3091
+ ),
3092
+ ...props,
3093
+ children: [
3094
+ title && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "text-lg font-semibold", children: title }),
3095
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("nav", { className: "flex flex-col gap-2", children: items.map((item, index) => {
3096
+ var _a;
3097
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
3098
+ "a",
3099
+ {
3100
+ href: (_a = item.href) != null ? _a : "#",
3101
+ className: cn(
3102
+ "flex items-center gap-3 rounded-2xl px-3 py-2 text-sm transition",
3103
+ item.active ? "bg-[rgb(var(--nc-accent-1)/0.25)] text-[rgb(var(--nc-fg))]" : "text-[rgb(var(--nc-fg-muted))] hover:bg-[rgb(var(--nc-surface)/0.12)] hover:text-[rgb(var(--nc-fg))]"
3104
+ ),
3105
+ children: [
3106
+ item.icon,
3107
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { children: item.label })
3108
+ ]
3109
+ },
3110
+ `${item.label}-${index}`
3111
+ );
3112
+ }) }),
3113
+ footer && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "mt-auto pt-4", children: footer })
3114
+ ]
3115
+ }
3116
+ );
3117
+ }
3118
+
3119
+ // src/components/layout/top-nav.tsx
3120
+ var import_jsx_runtime42 = require("react/jsx-runtime");
3121
+ function TopNav({ className, title, actions, breadcrumb, ...props }) {
3122
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
3123
+ "header",
3124
+ {
3125
+ className: cn(
3126
+ "flex flex-wrap items-center justify-between gap-4 rounded-3xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.08)] px-6 py-4 text-[rgb(var(--nc-fg))] backdrop-blur-xl",
3127
+ className
3128
+ ),
3129
+ ...props,
3130
+ children: [
3131
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "space-y-1", children: [
3132
+ breadcrumb,
3133
+ title && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "text-xl font-semibold", children: title })
3134
+ ] }),
3135
+ actions && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "flex flex-wrap gap-3", children: actions })
3136
+ ]
3137
+ }
3138
+ );
3139
+ }
3140
+
3141
+ // src/components/layout/app-template.tsx
3142
+ var import_jsx_runtime43 = require("react/jsx-runtime");
3143
+ function AppTemplate({
3144
+ config,
3145
+ headerActions,
3146
+ headerBreadcrumb,
3147
+ sidebarFooter,
3148
+ resolveIcon,
3149
+ icons,
3150
+ activePath,
3151
+ getActivePath,
3152
+ lucideFallback = true,
3153
+ children
3154
+ }) {
3155
+ const sidebarConfig = config.sidebar;
3156
+ const headerConfig = config.header;
3157
+ const resolvedActivePath = activePath != null ? activePath : getActivePath == null ? void 0 : getActivePath();
3158
+ const buildIcon = React23.useCallback(
3159
+ (name) => {
3160
+ if (!name) return void 0;
3161
+ if (resolveIcon) return resolveIcon(name);
3162
+ if (icons == null ? void 0 : icons[name]) return icons[name];
3163
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(CraftIcon, { name, useLucide: lucideFallback });
3164
+ },
3165
+ [icons, lucideFallback, resolveIcon]
3166
+ );
3167
+ const sidebarItems = sidebarConfig ? sidebarConfig.items.map((item) => {
3168
+ var _a;
3169
+ return {
3170
+ label: item.label,
3171
+ href: item.href,
3172
+ active: (_a = item.active) != null ? _a : resolvedActivePath && item.href ? item.href === resolvedActivePath : false,
3173
+ icon: buildIcon(item.icon)
3174
+ };
3175
+ }) : null;
3176
+ const breadcrumbNode = headerBreadcrumb != null ? headerBreadcrumb : (headerConfig == null ? void 0 : headerConfig.breadcrumb) ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Breadcrumbs, { items: headerConfig.breadcrumb }) : null;
3177
+ const sidebarFooterNode = sidebarFooter != null ? sidebarFooter : (sidebarConfig == null ? void 0 : sidebarConfig.footerText) ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "text-xs text-[rgb(var(--nc-fg-muted))]", children: sidebarConfig.footerText }) : null;
3178
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3179
+ AppShell,
3180
+ {
3181
+ sidebar: sidebarConfig && sidebarItems ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3182
+ Sidebar,
3183
+ {
3184
+ title: sidebarConfig.title,
3185
+ items: sidebarItems,
3186
+ footer: sidebarFooterNode
3187
+ }
3188
+ ) : void 0,
3189
+ topNav: headerConfig ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3190
+ TopNav,
3191
+ {
3192
+ title: headerConfig.title,
3193
+ breadcrumb: breadcrumbNode,
3194
+ actions: headerActions
3195
+ }
3196
+ ) : void 0,
3197
+ children
3198
+ }
3199
+ );
3200
+ }
3201
+
3202
+ // src/components/layout/layout-config.ts
3203
+ var layoutConfigSchema = {
3204
+ $schema: "https://json-schema.org/draft/2020-12/schema",
3205
+ title: "Nextcraft UI Layout Config",
3206
+ type: "object",
3207
+ additionalProperties: false,
3208
+ properties: {
3209
+ sidebar: {
3210
+ type: "object",
3211
+ additionalProperties: false,
3212
+ properties: {
3213
+ title: { type: "string" },
3214
+ footerText: { type: "string" },
3215
+ items: {
3216
+ type: "array",
3217
+ items: {
3218
+ type: "object",
3219
+ additionalProperties: false,
3220
+ properties: {
3221
+ label: { type: "string" },
3222
+ href: { type: "string" },
3223
+ icon: { type: "string" },
3224
+ active: { type: "boolean" }
3225
+ },
3226
+ required: ["label"]
3227
+ }
3228
+ }
3229
+ },
3230
+ required: ["items"]
3231
+ },
3232
+ header: {
3233
+ type: "object",
3234
+ additionalProperties: false,
3235
+ properties: {
3236
+ title: { type: "string" },
3237
+ breadcrumb: {
3238
+ type: "array",
3239
+ items: {
3240
+ type: "object",
3241
+ additionalProperties: false,
3242
+ properties: {
3243
+ label: { type: "string" },
3244
+ href: { type: "string" }
3245
+ },
3246
+ required: ["label"]
3247
+ }
3248
+ }
3249
+ }
3250
+ }
3251
+ }
3252
+ };
3253
+
3254
+ // src/components/layout/page-header.tsx
3255
+ var import_jsx_runtime44 = require("react/jsx-runtime");
3256
+ function PageHeader({
3257
+ className,
3258
+ title,
3259
+ description,
3260
+ actions,
3261
+ ...props
3262
+ }) {
3263
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
3264
+ "div",
3265
+ {
3266
+ className: cn("flex flex-wrap items-start justify-between gap-6", className),
3267
+ ...props,
3268
+ children: [
3269
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "space-y-2", children: [
3270
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("h1", { className: "text-3xl font-bold text-[rgb(var(--nc-fg))]", children: title }),
3271
+ description && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("p", { className: "text-[rgb(var(--nc-fg-muted))]", children: description })
3272
+ ] }),
3273
+ actions && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "flex flex-wrap gap-3", children: actions })
3274
+ ]
3275
+ }
3276
+ );
3277
+ }
3278
+
3279
+ // src/components/layout/auth-layout.tsx
3280
+ var import_jsx_runtime45 = require("react/jsx-runtime");
3281
+ function AuthLayout({
3282
+ className,
3283
+ title,
3284
+ description,
3285
+ footer,
3286
+ graphic,
3287
+ children,
3288
+ ...props
3289
+ }) {
3290
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
3291
+ "div",
3292
+ {
3293
+ className: cn(
3294
+ "grid min-h-screen grid-cols-1 bg-background",
3295
+ "lg:grid-cols-[1.1fr_0.9fr]",
3296
+ className
3297
+ ),
3298
+ ...props,
3299
+ children: [
3300
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "flex flex-col justify-center px-6 py-16 sm:px-12", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "mx-auto w-full max-w-md space-y-6", children: [
3301
+ (title || description) && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "space-y-2", children: [
3302
+ title && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h1", { className: "text-3xl font-bold text-[rgb(var(--nc-fg))]", children: title }),
3303
+ description && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-[rgb(var(--nc-fg-muted))]", children: description })
3304
+ ] }),
3305
+ children,
3306
+ footer && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "text-sm text-[rgb(var(--nc-fg-muted))]", children: footer })
3307
+ ] }) }),
3308
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "hidden items-center justify-center border-l border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.08)] p-12 text-[rgb(var(--nc-fg))] lg:flex", children: graphic != null ? graphic : /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "max-w-sm space-y-4 text-center", children: [
3309
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h2", { className: "text-2xl font-semibold", children: "Crafted experiences" }),
3310
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-[rgb(var(--nc-fg-muted))]", children: "Build authentication flows that feel premium and cohesive." })
3311
+ ] }) })
3312
+ ]
3313
+ }
3314
+ );
3315
+ }
3316
+
3317
+ // src/components/layout/container.tsx
3318
+ var import_jsx_runtime46 = require("react/jsx-runtime");
3319
+ var sizeClasses3 = {
3320
+ sm: "max-w-3xl",
3321
+ md: "max-w-5xl",
3322
+ lg: "max-w-6xl",
3323
+ xl: "max-w-7xl"
3324
+ };
3325
+ function Container({ className, size = "lg", ...props }) {
3326
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3327
+ "div",
3328
+ {
3329
+ className: cn("mx-auto w-full px-4 sm:px-6 lg:px-8", sizeClasses3[size], className),
3330
+ ...props
3331
+ }
3332
+ );
3333
+ }
3334
+
3335
+ // src/components/layout/grid.tsx
3336
+ var import_jsx_runtime47 = require("react/jsx-runtime");
3337
+ var colClasses = {
3338
+ 1: "grid-cols-1",
3339
+ 2: "grid-cols-1 md:grid-cols-2",
3340
+ 3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3",
3341
+ 4: "grid-cols-1 md:grid-cols-2 lg:grid-cols-4",
3342
+ 5: "grid-cols-1 md:grid-cols-2 lg:grid-cols-5",
3343
+ 6: "grid-cols-1 md:grid-cols-3 lg:grid-cols-6"
3344
+ };
3345
+ var gapClasses = {
3346
+ sm: "gap-4",
3347
+ md: "gap-6",
3348
+ lg: "gap-8",
3349
+ xl: "gap-10"
3350
+ };
3351
+ function Grid({ className, columns = 3, gap = "md", ...props }) {
3352
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: cn("grid", colClasses[columns], gapClasses[gap], className), ...props });
3353
+ }
3354
+
3355
+ // src/theme/theme-context.tsx
3356
+ var React24 = __toESM(require("react"), 1);
3357
+ var import_jsx_runtime48 = require("react/jsx-runtime");
3358
+ var THEME_NAMES = [
3359
+ "aurora",
3360
+ "ember",
3361
+ "ocean",
3362
+ "midnight",
3363
+ "cosmic"
3364
+ ];
3365
+ var ThemeContext = React24.createContext(null);
3366
+ var DEFAULT_THEME_KEY = "nextcraft-theme";
3367
+ var DEFAULT_MODE_KEY = "nextcraft-mode";
3368
+ function ThemeProvider({
3369
+ children,
3370
+ defaultTheme = "ocean",
3371
+ defaultMode = "system",
3372
+ storageKeyTheme = DEFAULT_THEME_KEY,
3373
+ storageKeyMode = DEFAULT_MODE_KEY
3374
+ }) {
3375
+ const [theme, setTheme] = React24.useState(defaultTheme);
3376
+ const [mode, setMode] = React24.useState(defaultMode);
3377
+ React24.useEffect(() => {
3378
+ if (typeof window === "undefined") return;
3379
+ try {
3380
+ const storedTheme = window.localStorage.getItem(storageKeyTheme);
3381
+ const storedMode = window.localStorage.getItem(storageKeyMode);
3382
+ if (storedTheme) setTheme(storedTheme);
3383
+ if (storedMode) setMode(storedMode);
3384
+ } catch {
3385
+ }
3386
+ }, [storageKeyTheme, storageKeyMode]);
3387
+ React24.useEffect(() => {
3388
+ if (typeof window === "undefined") return;
3389
+ try {
3390
+ window.localStorage.setItem(storageKeyTheme, theme);
3391
+ window.localStorage.setItem(storageKeyMode, mode);
3392
+ } catch {
3393
+ }
3394
+ }, [theme, mode, storageKeyTheme, storageKeyMode]);
3395
+ React24.useEffect(() => {
3396
+ if (typeof document === "undefined") return;
3397
+ const root = document.documentElement;
3398
+ root.dataset.ncTheme = theme;
3399
+ if (mode !== "system") {
3400
+ root.dataset.ncMode = mode;
3401
+ return;
3402
+ }
3403
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
3404
+ const applySystem = () => {
3405
+ root.dataset.ncMode = mediaQuery.matches ? "dark" : "light";
3406
+ };
3407
+ applySystem();
3408
+ if (typeof mediaQuery.addEventListener === "function") {
3409
+ mediaQuery.addEventListener("change", applySystem);
3410
+ return () => mediaQuery.removeEventListener("change", applySystem);
3411
+ }
3412
+ mediaQuery.addListener(applySystem);
3413
+ return () => mediaQuery.removeListener(applySystem);
3414
+ }, [theme, mode]);
3415
+ const value = React24.useMemo(
3416
+ () => ({ theme, mode, setTheme, setMode }),
3417
+ [theme, mode]
3418
+ );
3419
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ThemeContext.Provider, { value, children });
3420
+ }
3421
+ function useTheme() {
3422
+ const context = React24.useContext(ThemeContext);
3423
+ if (!context) {
3424
+ throw new Error("useTheme must be used within ThemeProvider");
3425
+ }
3426
+ return context;
3427
+ }
3428
+
3429
+ // src/components/theme-switcher.tsx
3430
+ var import_jsx_runtime49 = require("react/jsx-runtime");
3431
+ var MODE_OPTIONS = ["system", "light", "dark"];
3432
+ function ThemeSwitcher({ className, showLabels = true, ...props }) {
3433
+ const { theme, mode, setTheme, setMode } = useTheme();
3434
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
3435
+ "div",
3436
+ {
3437
+ className: cn(
3438
+ "flex flex-wrap items-center gap-3 rounded-2xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.08)] px-4 py-3 text-sm text-[rgb(var(--nc-fg))] shadow-[inset_0_1px_0_rgba(255,255,255,0.06)]",
3439
+ className
3440
+ ),
3441
+ ...props,
3442
+ children: [
3443
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("label", { className: "flex items-center gap-2", children: [
3444
+ showLabels && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-[rgb(var(--nc-fg-muted))]", children: "Theme" }),
3445
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
3446
+ "select",
3447
+ {
3448
+ className: "rounded-lg border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] px-3 py-1 text-[rgb(var(--nc-fg))] outline-none focus:ring-2 focus:ring-[rgb(var(--nc-accent-1)/0.5)]",
3449
+ value: theme,
3450
+ onChange: (event) => setTheme(event.target.value),
3451
+ children: THEME_NAMES.map((name) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("option", { value: name, className: "text-slate-900", children: name }, name))
3452
+ }
3453
+ )
3454
+ ] }),
3455
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("label", { className: "flex items-center gap-2", children: [
3456
+ showLabels && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-[rgb(var(--nc-fg-muted))]", children: "Mode" }),
3457
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
3458
+ "select",
3459
+ {
3460
+ className: "rounded-lg border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] px-3 py-1 text-[rgb(var(--nc-fg))] outline-none focus:ring-2 focus:ring-[rgb(var(--nc-accent-1)/0.5)]",
3461
+ value: mode,
3462
+ onChange: (event) => setMode(event.target.value),
3463
+ children: MODE_OPTIONS.map((value) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("option", { value, className: "text-slate-900", children: value }, value))
3464
+ }
3465
+ )
3466
+ ] })
3467
+ ]
3468
+ }
3469
+ );
3470
+ }
126
3471
  // Annotate the CommonJS export names for ESM import in node:
127
3472
  0 && (module.exports = {
128
3473
  AppShell,