@krizaka/ui 2.0.0-beta.5 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (688) hide show
  1. package/README.md +44 -28
  2. package/dist/{button-D5aSsmxX.d.ts → button-Cgfkg_3y.d.ts} +5 -1
  3. package/dist/button.d.ts +5 -1
  4. package/dist/button.js +4 -2
  5. package/dist/button.js.map +1 -1
  6. package/dist/card.d.ts +7 -1
  7. package/dist/card.js +2 -2
  8. package/dist/card.js.map +1 -1
  9. package/dist/{chunk-IUGBKMJC.js → chunk-FHYZSO2S.js} +2 -2
  10. package/dist/{chunk-6DJ6SQY3.js → chunk-PESA2R4U.js} +5 -3
  11. package/dist/chunk-PESA2R4U.js.map +1 -0
  12. package/dist/command.d.ts +11 -2
  13. package/dist/command.js +17 -6
  14. package/dist/command.js.map +1 -1
  15. package/dist/confirm-button.d.ts +1 -1
  16. package/dist/confirm-button.js +1 -1
  17. package/dist/countdown.d.ts +7 -6
  18. package/dist/countdown.js +12 -8
  19. package/dist/countdown.js.map +1 -1
  20. package/dist/dialog.js +2 -2
  21. package/dist/dropdown-menu.js +3 -3
  22. package/dist/dropdown-menu.js.map +1 -1
  23. package/dist/field.js +2 -2
  24. package/dist/field.js.map +1 -1
  25. package/dist/native.d.ts +56 -6
  26. package/dist/native.js +129 -85
  27. package/dist/native.js.map +1 -1
  28. package/dist/theme.d.ts +1 -1
  29. package/dist/theme.js +1 -1
  30. package/package.json +11 -11
  31. package/registry/alert.json +141 -3
  32. package/registry/avatar.json +314 -3
  33. package/registry/badge.json +233 -3
  34. package/registry/button.json +522 -8
  35. package/registry/card.json +427 -4
  36. package/registry/checkbox.json +127 -3
  37. package/registry/chip.json +394 -3
  38. package/registry/cn.json +51 -3
  39. package/registry/command.json +246 -5
  40. package/registry/confirm-button.json +172 -5
  41. package/registry/countdown.json +318 -7
  42. package/registry/dialog.json +310 -3
  43. package/registry/dropdown-menu.json +117 -4
  44. package/registry/empty-state.json +170 -3
  45. package/registry/examples/alert/danger.d.ts +4 -0
  46. package/registry/examples/alert/danger.js +22 -0
  47. package/registry/examples/alert/danger.tsx +25 -0
  48. package/registry/examples/alert/info.d.ts +4 -0
  49. package/registry/{demos/alert.js → examples/alert/info.js} +3 -3
  50. package/registry/{demos/alert.tsx → examples/alert/info.tsx} +1 -1
  51. package/registry/examples/alert/success.d.ts +4 -0
  52. package/registry/examples/alert/success.js +12 -0
  53. package/registry/examples/alert/success.tsx +15 -0
  54. package/registry/examples/alert/title-only.d.ts +4 -0
  55. package/registry/examples/alert/title-only.js +11 -0
  56. package/registry/examples/alert/title-only.tsx +5 -0
  57. package/registry/examples/alert/warning.d.ts +4 -0
  58. package/registry/examples/alert/warning.js +13 -0
  59. package/registry/examples/alert/warning.tsx +17 -0
  60. package/registry/examples/avatar/fallback.d.ts +4 -0
  61. package/registry/examples/avatar/fallback.js +11 -0
  62. package/registry/examples/avatar/fallback.tsx +6 -0
  63. package/registry/examples/avatar/group.d.ts +4 -0
  64. package/registry/examples/avatar/group.js +20 -0
  65. package/registry/examples/avatar/group.tsx +21 -0
  66. package/registry/examples/avatar/native/group.d.ts +4 -0
  67. package/registry/examples/avatar/native/group.dark.png +0 -0
  68. package/registry/examples/avatar/native/group.js +17 -0
  69. package/registry/examples/avatar/native/group.light.png +0 -0
  70. package/registry/examples/avatar/native/group.tsx +13 -0
  71. package/registry/examples/avatar/native/sizes.d.ts +4 -0
  72. package/registry/examples/avatar/native/sizes.dark.png +0 -0
  73. package/registry/examples/avatar/native/sizes.js +18 -0
  74. package/registry/examples/avatar/native/sizes.light.png +0 -0
  75. package/registry/examples/avatar/native/sizes.tsx +15 -0
  76. package/registry/examples/avatar/sizes.d.ts +4 -0
  77. package/registry/examples/avatar/sizes.js +17 -0
  78. package/registry/examples/avatar/sizes.tsx +13 -0
  79. package/registry/examples/avatar/with-image.d.ts +4 -0
  80. package/registry/{demos/avatar.js → examples/avatar/with-image.js} +3 -3
  81. package/registry/{demos/avatar.tsx → examples/avatar/with-image.tsx} +1 -1
  82. package/registry/examples/badge/accent.d.ts +4 -0
  83. package/registry/examples/badge/accent.js +11 -0
  84. package/registry/examples/badge/accent.tsx +9 -0
  85. package/registry/examples/badge/danger.d.ts +4 -0
  86. package/registry/examples/badge/danger.js +11 -0
  87. package/registry/examples/badge/danger.tsx +9 -0
  88. package/registry/examples/badge/medium.d.ts +4 -0
  89. package/registry/examples/badge/medium.js +11 -0
  90. package/registry/examples/badge/medium.tsx +9 -0
  91. package/registry/examples/badge/native/dot.d.ts +4 -0
  92. package/registry/examples/badge/native/dot.dark.png +0 -0
  93. package/registry/examples/badge/native/dot.js +15 -0
  94. package/registry/examples/badge/native/dot.light.png +0 -0
  95. package/registry/examples/badge/native/dot.tsx +16 -0
  96. package/registry/examples/badge/native/scrim.d.ts +4 -0
  97. package/registry/examples/badge/native/scrim.dark.png +0 -0
  98. package/registry/examples/badge/native/scrim.js +13 -0
  99. package/registry/examples/badge/native/scrim.light.png +0 -0
  100. package/registry/examples/badge/native/scrim.tsx +14 -0
  101. package/registry/examples/badge/native/tones.d.ts +4 -0
  102. package/registry/examples/badge/native/tones.dark.png +0 -0
  103. package/registry/examples/badge/native/tones.js +18 -0
  104. package/registry/examples/badge/native/tones.light.png +0 -0
  105. package/registry/examples/badge/native/tones.tsx +14 -0
  106. package/registry/examples/badge/neutral.d.ts +4 -0
  107. package/registry/{demos/badge.js → examples/badge/neutral.js} +3 -3
  108. package/registry/{demos/badge.tsx → examples/badge/neutral.tsx} +1 -1
  109. package/registry/examples/badge/scrim.d.ts +4 -0
  110. package/registry/examples/badge/scrim.js +11 -0
  111. package/registry/examples/badge/scrim.tsx +10 -0
  112. package/registry/examples/badge/success.d.ts +4 -0
  113. package/registry/examples/badge/success.js +11 -0
  114. package/registry/examples/badge/success.tsx +9 -0
  115. package/registry/examples/badge/warning.d.ts +4 -0
  116. package/registry/examples/badge/warning.js +11 -0
  117. package/registry/examples/badge/warning.tsx +9 -0
  118. package/registry/examples/button/as-child-link.d.ts +4 -0
  119. package/registry/examples/button/as-child-link.js +11 -0
  120. package/registry/examples/button/as-child-link.tsx +10 -0
  121. package/registry/examples/button/danger.d.ts +4 -0
  122. package/registry/examples/button/danger.js +11 -0
  123. package/registry/examples/button/danger.tsx +5 -0
  124. package/registry/examples/button/disabled.d.ts +4 -0
  125. package/registry/examples/button/disabled.js +11 -0
  126. package/registry/examples/button/disabled.tsx +9 -0
  127. package/registry/examples/button/ghost.d.ts +4 -0
  128. package/registry/examples/button/ghost.js +11 -0
  129. package/registry/examples/button/ghost.tsx +5 -0
  130. package/registry/examples/button/gradient.d.ts +4 -0
  131. package/registry/examples/button/gradient.js +11 -0
  132. package/registry/examples/button/gradient.tsx +5 -0
  133. package/registry/examples/button/icon.d.ts +4 -0
  134. package/registry/examples/button/icon.js +14 -0
  135. package/registry/examples/button/icon.tsx +18 -0
  136. package/registry/examples/button/loading.d.ts +4 -0
  137. package/registry/examples/button/loading.js +11 -0
  138. package/registry/examples/button/loading.tsx +10 -0
  139. package/registry/examples/button/native/danger.d.ts +4 -0
  140. package/registry/examples/button/native/danger.dark.png +0 -0
  141. package/registry/examples/button/native/danger.js +12 -0
  142. package/registry/examples/button/native/danger.light.png +0 -0
  143. package/registry/examples/button/native/danger.tsx +5 -0
  144. package/registry/examples/button/native/disabled.d.ts +4 -0
  145. package/registry/examples/button/native/disabled.dark.png +0 -0
  146. package/registry/examples/button/native/disabled.js +11 -0
  147. package/registry/examples/button/native/disabled.light.png +0 -0
  148. package/registry/examples/button/native/disabled.tsx +5 -0
  149. package/registry/examples/button/native/ghost.d.ts +4 -0
  150. package/registry/examples/button/native/ghost.dark.png +0 -0
  151. package/registry/examples/button/native/ghost.js +12 -0
  152. package/registry/examples/button/native/ghost.light.png +0 -0
  153. package/registry/examples/button/native/ghost.tsx +5 -0
  154. package/registry/examples/button/native/gradient.d.ts +4 -0
  155. package/registry/examples/button/native/gradient.dark.png +0 -0
  156. package/registry/examples/button/native/gradient.js +12 -0
  157. package/registry/examples/button/native/gradient.light.png +0 -0
  158. package/registry/examples/button/native/gradient.tsx +5 -0
  159. package/registry/examples/button/native/icon-only.d.ts +4 -0
  160. package/registry/examples/button/native/icon-only.dark.png +0 -0
  161. package/registry/examples/button/native/icon-only.js +19 -0
  162. package/registry/examples/button/native/icon-only.light.png +0 -0
  163. package/registry/examples/button/native/icon-only.tsx +21 -0
  164. package/registry/examples/button/native/icon.d.ts +4 -0
  165. package/registry/examples/button/native/icon.dark.png +0 -0
  166. package/registry/examples/button/native/icon.js +16 -0
  167. package/registry/examples/button/native/icon.light.png +0 -0
  168. package/registry/examples/button/native/icon.tsx +15 -0
  169. package/registry/examples/button/native/loading.d.ts +4 -0
  170. package/registry/examples/button/native/loading.dark.png +0 -0
  171. package/registry/examples/button/native/loading.js +11 -0
  172. package/registry/examples/button/native/loading.light.png +0 -0
  173. package/registry/examples/button/native/loading.tsx +6 -0
  174. package/registry/examples/button/native/outline.d.ts +4 -0
  175. package/registry/examples/button/native/outline.dark.png +0 -0
  176. package/registry/examples/button/native/outline.js +12 -0
  177. package/registry/examples/button/native/outline.light.png +0 -0
  178. package/registry/examples/button/native/outline.tsx +5 -0
  179. package/registry/examples/button/native/primary.d.ts +4 -0
  180. package/registry/examples/button/native/primary.dark.png +0 -0
  181. package/registry/examples/button/native/primary.js +12 -0
  182. package/registry/examples/button/native/primary.light.png +0 -0
  183. package/registry/examples/button/native/primary.tsx +5 -0
  184. package/registry/examples/button/native/secondary.d.ts +4 -0
  185. package/registry/examples/button/native/secondary.dark.png +0 -0
  186. package/registry/examples/button/native/secondary.js +12 -0
  187. package/registry/examples/button/native/secondary.light.png +0 -0
  188. package/registry/examples/button/native/secondary.tsx +6 -0
  189. package/registry/examples/button/native/sizes.d.ts +4 -0
  190. package/registry/examples/button/native/sizes.dark.png +0 -0
  191. package/registry/examples/button/native/sizes.js +15 -0
  192. package/registry/examples/button/native/sizes.light.png +0 -0
  193. package/registry/examples/button/native/sizes.tsx +11 -0
  194. package/registry/examples/button/outline.d.ts +4 -0
  195. package/registry/examples/button/outline.js +11 -0
  196. package/registry/examples/button/outline.tsx +5 -0
  197. package/registry/examples/button/pill.d.ts +4 -0
  198. package/registry/examples/button/pill.js +11 -0
  199. package/registry/examples/button/pill.tsx +9 -0
  200. package/registry/examples/button/primary.d.ts +4 -0
  201. package/registry/{demos/button.js → examples/button/primary.js} +3 -3
  202. package/registry/{demos/button.tsx → examples/button/primary.tsx} +1 -1
  203. package/registry/examples/button/secondary.d.ts +4 -0
  204. package/registry/examples/button/secondary.js +11 -0
  205. package/registry/examples/button/secondary.tsx +6 -0
  206. package/registry/examples/button/sizes.d.ts +4 -0
  207. package/registry/examples/button/sizes.js +15 -0
  208. package/registry/examples/button/sizes.tsx +17 -0
  209. package/registry/examples/card/interactive-link.d.ts +4 -0
  210. package/registry/examples/card/interactive-link.js +15 -0
  211. package/registry/examples/card/interactive-link.tsx +16 -0
  212. package/registry/examples/card/media-card.d.ts +4 -0
  213. package/registry/{demos/card.js → examples/card/media-card.js} +3 -3
  214. package/registry/{demos/card.tsx → examples/card/media-card.tsx} +1 -1
  215. package/registry/examples/card/media-fallback.d.ts +4 -0
  216. package/registry/examples/card/media-fallback.js +18 -0
  217. package/registry/examples/card/media-fallback.tsx +22 -0
  218. package/registry/examples/card/native/body.d.ts +4 -0
  219. package/registry/examples/card/native/body.dark.png +0 -0
  220. package/registry/examples/card/native/body.js +15 -0
  221. package/registry/examples/card/native/body.light.png +0 -0
  222. package/registry/examples/card/native/body.tsx +13 -0
  223. package/registry/examples/card/native/default.d.ts +4 -0
  224. package/registry/examples/card/native/default.dark.png +0 -0
  225. package/registry/examples/card/native/default.js +24 -0
  226. package/registry/examples/card/native/default.light.png +0 -0
  227. package/registry/examples/card/native/default.tsx +28 -0
  228. package/registry/examples/card/native/elevated.d.ts +4 -0
  229. package/registry/examples/card/native/elevated.dark.png +0 -0
  230. package/registry/examples/card/native/elevated.js +24 -0
  231. package/registry/examples/card/native/elevated.light.png +0 -0
  232. package/registry/examples/card/native/elevated.tsx +28 -0
  233. package/registry/examples/card/native/pressable.d.ts +4 -0
  234. package/registry/examples/card/native/pressable.dark.png +0 -0
  235. package/registry/examples/card/native/pressable.js +15 -0
  236. package/registry/examples/card/native/pressable.light.png +0 -0
  237. package/registry/examples/card/native/pressable.tsx +13 -0
  238. package/registry/examples/card/reveal-grid.d.ts +4 -0
  239. package/registry/examples/card/reveal-grid.js +28 -0
  240. package/registry/examples/card/reveal-grid.tsx +31 -0
  241. package/registry/examples/card/stat-card.d.ts +4 -0
  242. package/registry/examples/card/stat-card.js +18 -0
  243. package/registry/examples/card/stat-card.tsx +17 -0
  244. package/registry/examples/checkbox/checked.d.ts +4 -0
  245. package/registry/examples/checkbox/checked.js +11 -0
  246. package/registry/examples/checkbox/checked.tsx +5 -0
  247. package/registry/examples/checkbox/disabled.d.ts +4 -0
  248. package/registry/examples/checkbox/disabled.js +14 -0
  249. package/registry/examples/checkbox/disabled.tsx +12 -0
  250. package/registry/examples/checkbox/indeterminate.d.ts +4 -0
  251. package/registry/examples/checkbox/indeterminate.js +11 -0
  252. package/registry/examples/checkbox/indeterminate.tsx +6 -0
  253. package/registry/examples/checkbox/invalid.d.ts +4 -0
  254. package/registry/examples/checkbox/invalid.js +15 -0
  255. package/registry/examples/checkbox/invalid.tsx +14 -0
  256. package/registry/examples/checkbox/unchecked.d.ts +4 -0
  257. package/registry/{demos/checkbox.js → examples/checkbox/unchecked.js} +3 -3
  258. package/registry/{demos/checkbox.tsx → examples/checkbox/unchecked.tsx} +2 -1
  259. package/registry/examples/chip/multiple.d.ts +4 -0
  260. package/registry/examples/chip/multiple.js +16 -0
  261. package/registry/examples/chip/multiple.tsx +12 -0
  262. package/registry/examples/chip/native/multiple.d.ts +4 -0
  263. package/registry/examples/chip/native/multiple.dark.png +0 -0
  264. package/registry/examples/chip/native/multiple.js +18 -0
  265. package/registry/examples/chip/native/multiple.light.png +0 -0
  266. package/registry/examples/chip/native/multiple.tsx +17 -0
  267. package/registry/examples/chip/native/removable.d.ts +4 -0
  268. package/registry/examples/chip/native/removable.dark.png +0 -0
  269. package/registry/examples/chip/native/removable.js +17 -0
  270. package/registry/examples/chip/native/removable.light.png +0 -0
  271. package/registry/examples/chip/native/removable.tsx +15 -0
  272. package/registry/examples/chip/native/single.d.ts +4 -0
  273. package/registry/examples/chip/native/single.dark.png +0 -0
  274. package/registry/examples/chip/native/single.js +15 -0
  275. package/registry/examples/chip/native/single.light.png +0 -0
  276. package/registry/examples/chip/native/single.tsx +11 -0
  277. package/registry/examples/chip/native/toggle.d.ts +4 -0
  278. package/registry/examples/chip/native/toggle.dark.png +0 -0
  279. package/registry/examples/chip/native/toggle.js +17 -0
  280. package/registry/examples/chip/native/toggle.light.png +0 -0
  281. package/registry/examples/chip/native/toggle.tsx +16 -0
  282. package/registry/examples/chip/removable.d.ts +4 -0
  283. package/registry/examples/chip/removable.js +16 -0
  284. package/registry/examples/chip/removable.tsx +15 -0
  285. package/registry/examples/chip/single.d.ts +4 -0
  286. package/registry/examples/chip/single.js +16 -0
  287. package/registry/examples/chip/single.tsx +13 -0
  288. package/registry/examples/chip/small.d.ts +4 -0
  289. package/registry/examples/chip/small.js +16 -0
  290. package/registry/examples/chip/small.tsx +12 -0
  291. package/registry/examples/chip/toggle.d.ts +4 -0
  292. package/registry/{demos/chip.js → examples/chip/toggle.js} +3 -3
  293. package/registry/{demos/chip.tsx → examples/chip/toggle.tsx} +2 -1
  294. package/registry/examples/cn/merge.d.ts +4 -0
  295. package/registry/{demos/cn.js → examples/cn/merge.js} +3 -3
  296. package/registry/{demos/cn.tsx → examples/cn/merge.tsx} +1 -1
  297. package/registry/examples/command/dialog.d.ts +4 -0
  298. package/registry/examples/command/dialog.js +39 -0
  299. package/registry/examples/command/dialog.tsx +35 -0
  300. package/registry/examples/command/inline.d.ts +4 -0
  301. package/registry/{demos/command.js → examples/command/inline.js} +4 -5
  302. package/registry/{demos/command.tsx → examples/command/inline.tsx} +2 -3
  303. package/registry/examples/command/no-results.d.ts +4 -0
  304. package/registry/examples/command/no-results.js +19 -0
  305. package/registry/examples/command/no-results.tsx +20 -0
  306. package/registry/examples/confirm-button/armed.d.ts +4 -0
  307. package/registry/examples/confirm-button/armed.js +12 -0
  308. package/registry/examples/confirm-button/armed.tsx +14 -0
  309. package/registry/examples/confirm-button/idle.d.ts +4 -0
  310. package/registry/{demos/confirm-button.js → examples/confirm-button/idle.js} +3 -3
  311. package/registry/{demos/confirm-button.tsx → examples/confirm-button/idle.tsx} +1 -1
  312. package/registry/examples/confirm-button/with-text.d.ts +4 -0
  313. package/registry/examples/confirm-button/with-text.js +12 -0
  314. package/registry/examples/confirm-button/with-text.tsx +12 -0
  315. package/registry/examples/countdown/days.d.ts +4 -0
  316. package/registry/examples/countdown/days.js +13 -0
  317. package/registry/examples/countdown/days.tsx +10 -0
  318. package/registry/examples/countdown/ended.d.ts +4 -0
  319. package/registry/examples/countdown/ended.js +13 -0
  320. package/registry/examples/countdown/ended.tsx +10 -0
  321. package/registry/examples/countdown/hours.d.ts +4 -0
  322. package/registry/{demos/countdown.js → examples/countdown/hours.js} +3 -3
  323. package/registry/{demos/countdown.tsx → examples/countdown/hours.tsx} +1 -1
  324. package/registry/examples/countdown/native/days.d.ts +4 -0
  325. package/registry/examples/countdown/native/days.dark.png +0 -0
  326. package/registry/examples/countdown/native/days.js +13 -0
  327. package/registry/examples/countdown/native/days.light.png +0 -0
  328. package/registry/examples/countdown/native/days.tsx +7 -0
  329. package/registry/examples/countdown/native/hours.d.ts +4 -0
  330. package/registry/examples/countdown/native/hours.dark.png +0 -0
  331. package/registry/examples/countdown/native/hours.js +13 -0
  332. package/registry/examples/countdown/native/hours.light.png +0 -0
  333. package/registry/examples/countdown/native/hours.tsx +7 -0
  334. package/registry/examples/countdown/native/sizes.d.ts +4 -0
  335. package/registry/examples/countdown/native/sizes.dark.png +0 -0
  336. package/registry/examples/countdown/native/sizes.js +18 -0
  337. package/registry/examples/countdown/native/sizes.light.png +0 -0
  338. package/registry/examples/countdown/native/sizes.tsx +15 -0
  339. package/registry/examples/countdown/native/urgent.d.ts +4 -0
  340. package/registry/examples/countdown/native/urgent.dark.png +0 -0
  341. package/registry/examples/countdown/native/urgent.js +13 -0
  342. package/registry/examples/countdown/native/urgent.light.png +0 -0
  343. package/registry/examples/countdown/native/urgent.tsx +7 -0
  344. package/registry/examples/countdown/native/with-label.d.ts +4 -0
  345. package/registry/examples/countdown/native/with-label.dark.png +0 -0
  346. package/registry/examples/countdown/native/with-label.js +13 -0
  347. package/registry/examples/countdown/native/with-label.light.png +0 -0
  348. package/registry/examples/countdown/native/with-label.tsx +7 -0
  349. package/registry/examples/countdown/sizes.d.ts +4 -0
  350. package/registry/examples/countdown/sizes.js +18 -0
  351. package/registry/examples/countdown/sizes.tsx +17 -0
  352. package/registry/examples/countdown/urgent.d.ts +4 -0
  353. package/registry/examples/countdown/urgent.js +13 -0
  354. package/registry/examples/countdown/urgent.tsx +10 -0
  355. package/registry/examples/countdown/with-label.d.ts +4 -0
  356. package/registry/examples/countdown/with-label.js +13 -0
  357. package/registry/examples/countdown/with-label.tsx +10 -0
  358. package/registry/examples/dialog/alert-destructive.d.ts +4 -0
  359. package/registry/examples/dialog/alert-destructive.js +24 -0
  360. package/registry/examples/dialog/alert-destructive.tsx +20 -0
  361. package/registry/examples/dialog/bottom.d.ts +4 -0
  362. package/registry/examples/dialog/bottom.js +29 -0
  363. package/registry/examples/dialog/bottom.tsx +32 -0
  364. package/registry/examples/dialog/center.d.ts +4 -0
  365. package/registry/{demos/dialog.js → examples/dialog/center.js} +3 -3
  366. package/registry/{demos/dialog.tsx → examples/dialog/center.tsx} +1 -1
  367. package/registry/examples/dialog/gate.d.ts +4 -0
  368. package/registry/examples/dialog/gate.js +24 -0
  369. package/registry/examples/dialog/gate.tsx +27 -0
  370. package/registry/examples/dialog/right.d.ts +4 -0
  371. package/registry/examples/dialog/right.js +29 -0
  372. package/registry/examples/dialog/right.tsx +32 -0
  373. package/registry/examples/dialog/sheet-form.d.ts +4 -0
  374. package/registry/examples/dialog/sheet-form.js +35 -0
  375. package/registry/examples/dialog/sheet-form.tsx +36 -0
  376. package/registry/examples/dropdown-menu/actions.d.ts +4 -0
  377. package/registry/{demos/dropdown-menu.js → examples/dropdown-menu/actions.js} +3 -3
  378. package/registry/{demos/dropdown-menu.tsx → examples/dropdown-menu/actions.tsx} +1 -1
  379. package/registry/examples/empty-state/default.d.ts +4 -0
  380. package/registry/{demos/empty-state.js → examples/empty-state/default.js} +3 -3
  381. package/registry/{demos/empty-state.tsx → examples/empty-state/default.tsx} +1 -1
  382. package/registry/examples/empty-state/native/default.d.ts +4 -0
  383. package/registry/examples/empty-state/native/default.dark.png +0 -0
  384. package/registry/examples/empty-state/native/default.js +25 -0
  385. package/registry/examples/empty-state/native/default.light.png +0 -0
  386. package/registry/examples/empty-state/native/default.tsx +25 -0
  387. package/registry/examples/empty-state/title-only.d.ts +4 -0
  388. package/registry/examples/empty-state/title-only.js +11 -0
  389. package/registry/examples/empty-state/title-only.tsx +5 -0
  390. package/registry/examples/empty-state/with-action.d.ts +4 -0
  391. package/registry/examples/empty-state/with-action.js +24 -0
  392. package/registry/examples/empty-state/with-action.tsx +25 -0
  393. package/registry/examples/field/default.d.ts +4 -0
  394. package/registry/{demos/field.js → examples/field/default.js} +3 -3
  395. package/registry/{demos/field.tsx → examples/field/default.tsx} +1 -1
  396. package/registry/examples/field/disabled.d.ts +4 -0
  397. package/registry/examples/field/disabled.js +14 -0
  398. package/registry/examples/field/disabled.tsx +10 -0
  399. package/registry/examples/field/invalid.d.ts +4 -0
  400. package/registry/examples/field/invalid.js +15 -0
  401. package/registry/examples/field/invalid.tsx +12 -0
  402. package/registry/examples/field/select.d.ts +4 -0
  403. package/registry/examples/field/select.js +18 -0
  404. package/registry/examples/field/select.tsx +15 -0
  405. package/registry/examples/field/textarea.d.ts +4 -0
  406. package/registry/examples/field/textarea.js +14 -0
  407. package/registry/examples/field/textarea.tsx +10 -0
  408. package/registry/examples/kbd/key.d.ts +4 -0
  409. package/registry/{demos/kbd.js → examples/kbd/key.js} +3 -3
  410. package/registry/{demos/kbd.tsx → examples/kbd/key.tsx} +1 -1
  411. package/registry/examples/kbd/shortcut.d.ts +4 -0
  412. package/registry/examples/kbd/shortcut.js +15 -0
  413. package/registry/examples/kbd/shortcut.tsx +11 -0
  414. package/registry/examples/kbd/small.d.ts +4 -0
  415. package/registry/examples/kbd/small.js +11 -0
  416. package/registry/examples/kbd/small.tsx +5 -0
  417. package/registry/examples/page-header/default.d.ts +4 -0
  418. package/registry/{demos/page-header.js → examples/page-header/default.js} +3 -3
  419. package/registry/{demos/page-header.tsx → examples/page-header/default.tsx} +1 -1
  420. package/registry/examples/page-header/with-actions.d.ts +4 -0
  421. package/registry/examples/page-header/with-actions.js +22 -0
  422. package/registry/examples/page-header/with-actions.tsx +17 -0
  423. package/registry/examples/page-header/with-breadcrumb.d.ts +4 -0
  424. package/registry/examples/page-header/with-breadcrumb.js +24 -0
  425. package/registry/examples/page-header/with-breadcrumb.tsx +26 -0
  426. package/registry/examples/popover/form.d.ts +4 -0
  427. package/registry/{demos/popover.js → examples/popover/form.js} +3 -3
  428. package/registry/{demos/popover.tsx → examples/popover/form.tsx} +1 -1
  429. package/registry/examples/progress/bar-indeterminate.d.ts +4 -0
  430. package/registry/examples/progress/bar-indeterminate.js +11 -0
  431. package/registry/examples/progress/bar-indeterminate.tsx +6 -0
  432. package/registry/examples/progress/bar-sizes.d.ts +4 -0
  433. package/registry/examples/progress/bar-sizes.js +15 -0
  434. package/registry/examples/progress/bar-sizes.tsx +11 -0
  435. package/registry/examples/progress/bar.d.ts +4 -0
  436. package/registry/{demos/progress.js → examples/progress/bar.js} +3 -3
  437. package/registry/{demos/progress.tsx → examples/progress/bar.tsx} +1 -1
  438. package/registry/examples/progress/native/bar.d.ts +4 -0
  439. package/registry/examples/progress/native/bar.dark.png +0 -0
  440. package/registry/examples/progress/native/bar.js +16 -0
  441. package/registry/examples/progress/native/bar.light.png +0 -0
  442. package/registry/examples/progress/native/bar.tsx +12 -0
  443. package/registry/examples/progress/native/indeterminate.d.ts +4 -0
  444. package/registry/examples/progress/native/indeterminate.dark.png +0 -0
  445. package/registry/examples/progress/native/indeterminate.js +15 -0
  446. package/registry/examples/progress/native/indeterminate.light.png +0 -0
  447. package/registry/examples/progress/native/indeterminate.tsx +12 -0
  448. package/registry/examples/progress/native/ring.d.ts +4 -0
  449. package/registry/examples/progress/native/ring.dark.png +0 -0
  450. package/registry/examples/progress/native/ring.js +19 -0
  451. package/registry/examples/progress/native/ring.light.png +0 -0
  452. package/registry/examples/progress/native/ring.tsx +19 -0
  453. package/registry/examples/progress/ring-indeterminate.d.ts +4 -0
  454. package/registry/examples/progress/ring-indeterminate.js +11 -0
  455. package/registry/examples/progress/ring-indeterminate.tsx +5 -0
  456. package/registry/examples/progress/ring.d.ts +4 -0
  457. package/registry/examples/progress/ring.js +18 -0
  458. package/registry/examples/progress/ring.tsx +17 -0
  459. package/registry/examples/radio-group/cards.d.ts +4 -0
  460. package/registry/examples/radio-group/cards.js +19 -0
  461. package/registry/examples/radio-group/cards.tsx +21 -0
  462. package/registry/examples/radio-group/horizontal.d.ts +4 -0
  463. package/registry/examples/radio-group/horizontal.js +15 -0
  464. package/registry/examples/radio-group/horizontal.tsx +12 -0
  465. package/registry/examples/radio-group/items.d.ts +4 -0
  466. package/registry/{demos/radio-group.js → examples/radio-group/items.js} +3 -3
  467. package/registry/{demos/radio-group.tsx → examples/radio-group/items.tsx} +1 -1
  468. package/registry/examples/section-backdrop/depth-of-field.d.ts +4 -0
  469. package/registry/examples/section-backdrop/depth-of-field.js +18 -0
  470. package/registry/examples/section-backdrop/depth-of-field.tsx +13 -0
  471. package/registry/examples/section-backdrop/hero.d.ts +4 -0
  472. package/registry/{demos/section-backdrop.js → examples/section-backdrop/hero.js} +3 -3
  473. package/registry/{demos/section-backdrop.tsx → examples/section-backdrop/hero.tsx} +1 -1
  474. package/registry/examples/section-backdrop/plain.d.ts +4 -0
  475. package/registry/examples/section-backdrop/plain.js +11 -0
  476. package/registry/examples/section-backdrop/plain.tsx +10 -0
  477. package/registry/examples/section-backdrop/sequence.d.ts +4 -0
  478. package/registry/examples/section-backdrop/sequence.js +14 -0
  479. package/registry/examples/section-backdrop/sequence.tsx +15 -0
  480. package/registry/examples/section-backdrop/up.d.ts +4 -0
  481. package/registry/examples/section-backdrop/up.js +11 -0
  482. package/registry/examples/section-backdrop/up.tsx +10 -0
  483. package/registry/examples/segmented/native/default.d.ts +4 -0
  484. package/registry/examples/segmented/native/default.dark.png +0 -0
  485. package/registry/examples/segmented/native/default.js +19 -0
  486. package/registry/examples/segmented/native/default.light.png +0 -0
  487. package/registry/examples/segmented/native/default.tsx +19 -0
  488. package/registry/examples/segmented/native/small.d.ts +4 -0
  489. package/registry/examples/segmented/native/small.dark.png +0 -0
  490. package/registry/examples/segmented/native/small.js +19 -0
  491. package/registry/examples/segmented/native/small.light.png +0 -0
  492. package/registry/examples/segmented/native/small.tsx +19 -0
  493. package/registry/examples/separator/horizontal.d.ts +4 -0
  494. package/registry/{demos/separator.js → examples/separator/horizontal.js} +3 -3
  495. package/registry/{demos/separator.tsx → examples/separator/horizontal.tsx} +1 -1
  496. package/registry/examples/separator/vertical.d.ts +4 -0
  497. package/registry/examples/separator/vertical.js +17 -0
  498. package/registry/examples/separator/vertical.tsx +14 -0
  499. package/registry/examples/skeleton/circle.d.ts +4 -0
  500. package/registry/examples/skeleton/circle.js +11 -0
  501. package/registry/examples/skeleton/circle.tsx +5 -0
  502. package/registry/examples/skeleton/composition.d.ts +4 -0
  503. package/registry/{demos/skeleton.js → examples/skeleton/composition.js} +3 -3
  504. package/registry/{demos/skeleton.tsx → examples/skeleton/composition.tsx} +1 -1
  505. package/registry/examples/skeleton/native/shapes.d.ts +4 -0
  506. package/registry/examples/skeleton/native/shapes.dark.png +0 -0
  507. package/registry/examples/skeleton/native/shapes.js +21 -0
  508. package/registry/examples/skeleton/native/shapes.light.png +0 -0
  509. package/registry/examples/skeleton/native/shapes.tsx +18 -0
  510. package/registry/examples/skeleton/rect.d.ts +4 -0
  511. package/registry/examples/skeleton/rect.js +11 -0
  512. package/registry/examples/skeleton/rect.tsx +5 -0
  513. package/registry/examples/skeleton/text.d.ts +4 -0
  514. package/registry/examples/skeleton/text.js +11 -0
  515. package/registry/examples/skeleton/text.tsx +5 -0
  516. package/registry/examples/slider/centred.d.ts +4 -0
  517. package/registry/examples/slider/centred.js +11 -0
  518. package/registry/examples/slider/centred.tsx +8 -0
  519. package/registry/examples/slider/default.d.ts +4 -0
  520. package/registry/{demos/slider.js → examples/slider/default.js} +3 -3
  521. package/registry/{demos/slider.tsx → examples/slider/default.tsx} +1 -1
  522. package/registry/examples/slider/disabled.d.ts +4 -0
  523. package/registry/examples/slider/disabled.js +11 -0
  524. package/registry/examples/slider/disabled.tsx +5 -0
  525. package/registry/examples/slider/range.d.ts +4 -0
  526. package/registry/examples/slider/range.js +22 -0
  527. package/registry/examples/slider/range.tsx +18 -0
  528. package/registry/examples/slider/with-label.d.ts +4 -0
  529. package/registry/examples/slider/with-label.js +11 -0
  530. package/registry/examples/slider/with-label.tsx +8 -0
  531. package/registry/examples/slot/as-child.d.ts +4 -0
  532. package/registry/{demos/slot.js → examples/slot/as-child.js} +3 -3
  533. package/registry/{demos/slot.tsx → examples/slot/as-child.tsx} +1 -1
  534. package/registry/examples/slot/visually-hidden.d.ts +4 -0
  535. package/registry/examples/slot/visually-hidden.js +14 -0
  536. package/registry/examples/slot/visually-hidden.tsx +13 -0
  537. package/registry/examples/spinner/default.d.ts +4 -0
  538. package/registry/{demos/spinner.js → examples/spinner/default.js} +3 -3
  539. package/registry/{demos/spinner.tsx → examples/spinner/default.tsx} +1 -1
  540. package/registry/examples/spinner/muted.d.ts +4 -0
  541. package/registry/examples/spinner/muted.js +11 -0
  542. package/registry/examples/spinner/muted.tsx +6 -0
  543. package/registry/examples/spinner/native/sizes.d.ts +4 -0
  544. package/registry/examples/spinner/native/sizes.dark.png +0 -0
  545. package/registry/examples/spinner/native/sizes.js +16 -0
  546. package/registry/examples/spinner/native/sizes.light.png +0 -0
  547. package/registry/examples/spinner/native/sizes.tsx +13 -0
  548. package/registry/examples/spinner/sizes.d.ts +4 -0
  549. package/registry/examples/spinner/sizes.js +15 -0
  550. package/registry/examples/spinner/sizes.tsx +11 -0
  551. package/registry/examples/stat/down.d.ts +4 -0
  552. package/registry/examples/stat/down.js +11 -0
  553. package/registry/examples/stat/down.tsx +5 -0
  554. package/registry/examples/stat/flat.d.ts +4 -0
  555. package/registry/examples/stat/flat.js +11 -0
  556. package/registry/examples/stat/flat.tsx +5 -0
  557. package/registry/examples/stat/plain.d.ts +4 -0
  558. package/registry/examples/stat/plain.js +11 -0
  559. package/registry/examples/stat/plain.tsx +5 -0
  560. package/registry/examples/stat/row.d.ts +4 -0
  561. package/registry/examples/stat/row.js +15 -0
  562. package/registry/examples/stat/row.tsx +12 -0
  563. package/registry/examples/stat/up.d.ts +4 -0
  564. package/registry/{demos/stat.js → examples/stat/up.js} +3 -3
  565. package/registry/{demos/stat.tsx → examples/stat/up.tsx} +1 -1
  566. package/registry/examples/switch/disabled.d.ts +4 -0
  567. package/registry/examples/switch/disabled.js +14 -0
  568. package/registry/examples/switch/disabled.tsx +10 -0
  569. package/registry/examples/switch/off.d.ts +4 -0
  570. package/registry/{demos/switch.js → examples/switch/off.js} +3 -3
  571. package/registry/{demos/switch.tsx → examples/switch/off.tsx} +1 -1
  572. package/registry/examples/switch/on.d.ts +4 -0
  573. package/registry/examples/switch/on.js +11 -0
  574. package/registry/examples/switch/on.tsx +5 -0
  575. package/registry/examples/switch/small.d.ts +4 -0
  576. package/registry/examples/switch/small.js +11 -0
  577. package/registry/examples/switch/small.tsx +5 -0
  578. package/registry/examples/switch/with-label.d.ts +4 -0
  579. package/registry/examples/switch/with-label.js +18 -0
  580. package/registry/examples/switch/with-label.tsx +17 -0
  581. package/registry/examples/tabs/pills.d.ts +4 -0
  582. package/registry/examples/tabs/pills.js +20 -0
  583. package/registry/examples/tabs/pills.tsx +23 -0
  584. package/registry/examples/tabs/segmented.d.ts +4 -0
  585. package/registry/examples/tabs/segmented.js +20 -0
  586. package/registry/examples/tabs/segmented.tsx +23 -0
  587. package/registry/examples/tabs/underline.d.ts +4 -0
  588. package/registry/{demos/tabs.js → examples/tabs/underline.js} +3 -3
  589. package/registry/{demos/tabs.tsx → examples/tabs/underline.tsx} +1 -1
  590. package/registry/examples/tabs/vertical.d.ts +4 -0
  591. package/registry/examples/tabs/vertical.js +20 -0
  592. package/registry/examples/tabs/vertical.tsx +23 -0
  593. package/registry/examples/theme/native/provider.d.ts +4 -0
  594. package/registry/examples/theme/native/provider.js +23 -0
  595. package/registry/examples/theme/native/provider.tsx +21 -0
  596. package/registry/examples/theme/secondary.d.ts +4 -0
  597. package/registry/examples/theme/secondary.js +11 -0
  598. package/registry/examples/theme/secondary.tsx +10 -0
  599. package/registry/examples/theme/toggle.d.ts +4 -0
  600. package/registry/{demos/theme.js → examples/theme/toggle.js} +3 -3
  601. package/registry/{demos/theme.tsx → examples/theme/toggle.tsx} +1 -1
  602. package/registry/examples/toast/custom.d.ts +4 -0
  603. package/registry/examples/toast/custom.js +30 -0
  604. package/registry/examples/toast/custom.tsx +35 -0
  605. package/registry/examples/toast/native/notification.d.ts +4 -0
  606. package/registry/examples/toast/native/notification.dark.png +0 -0
  607. package/registry/examples/toast/native/notification.js +29 -0
  608. package/registry/examples/toast/native/notification.light.png +0 -0
  609. package/registry/examples/toast/native/notification.tsx +30 -0
  610. package/registry/examples/toast/native/tones.d.ts +4 -0
  611. package/registry/examples/toast/native/tones.dark.png +0 -0
  612. package/registry/examples/toast/native/tones.js +28 -0
  613. package/registry/examples/toast/native/tones.light.png +0 -0
  614. package/registry/examples/toast/native/tones.tsx +25 -0
  615. package/registry/examples/toast/tones.d.ts +4 -0
  616. package/registry/{demos/toast.js → examples/toast/tones.js} +3 -3
  617. package/registry/{demos/toast.tsx → examples/toast/tones.tsx} +1 -1
  618. package/registry/examples/tooltip/right.d.ts +4 -0
  619. package/registry/examples/tooltip/right.js +15 -0
  620. package/registry/examples/tooltip/right.tsx +15 -0
  621. package/registry/examples/tooltip/top.d.ts +4 -0
  622. package/registry/{demos/tooltip.js → examples/tooltip/top.js} +3 -3
  623. package/registry/{demos/tooltip.tsx → examples/tooltip/top.tsx} +1 -1
  624. package/registry/examples/txt/native/tones.d.ts +4 -0
  625. package/registry/examples/txt/native/tones.dark.png +0 -0
  626. package/registry/examples/txt/native/tones.js +16 -0
  627. package/registry/examples/txt/native/tones.light.png +0 -0
  628. package/registry/examples/txt/native/tones.tsx +17 -0
  629. package/registry/examples/txt/native/variants.d.ts +4 -0
  630. package/registry/examples/txt/native/variants.dark.png +0 -0
  631. package/registry/examples/txt/native/variants.js +18 -0
  632. package/registry/examples/txt/native/variants.light.png +0 -0
  633. package/registry/examples/txt/native/variants.tsx +15 -0
  634. package/registry/field.json +142 -4
  635. package/registry/index.json +353 -33
  636. package/registry/kbd.json +90 -3
  637. package/registry/page-header.json +121 -3
  638. package/registry/popover.json +90 -3
  639. package/registry/progress.json +265 -3
  640. package/registry/radio-group.json +136 -3
  641. package/registry/section-backdrop.json +144 -3
  642. package/registry/segmented.json +125 -0
  643. package/registry/separator.json +67 -3
  644. package/registry/skeleton.json +166 -3
  645. package/registry/slider.json +177 -3
  646. package/registry/slot.json +79 -3
  647. package/registry/spinner.json +144 -3
  648. package/registry/stat.json +140 -3
  649. package/registry/switch.json +130 -3
  650. package/registry/tabs.json +117 -3
  651. package/registry/theme.json +190 -4
  652. package/registry/toast.json +190 -3
  653. package/registry/tooltip.json +143 -3
  654. package/registry/txt.json +97 -0
  655. package/dist/chunk-6DJ6SQY3.js.map +0 -1
  656. package/registry/demos/alert.d.ts +0 -5
  657. package/registry/demos/avatar.d.ts +0 -5
  658. package/registry/demos/badge.d.ts +0 -5
  659. package/registry/demos/button.d.ts +0 -5
  660. package/registry/demos/card.d.ts +0 -5
  661. package/registry/demos/checkbox.d.ts +0 -5
  662. package/registry/demos/chip.d.ts +0 -5
  663. package/registry/demos/cn.d.ts +0 -7
  664. package/registry/demos/command.d.ts +0 -5
  665. package/registry/demos/confirm-button.d.ts +0 -5
  666. package/registry/demos/countdown.d.ts +0 -5
  667. package/registry/demos/dialog.d.ts +0 -7
  668. package/registry/demos/dropdown-menu.d.ts +0 -7
  669. package/registry/demos/empty-state.d.ts +0 -5
  670. package/registry/demos/field.d.ts +0 -5
  671. package/registry/demos/kbd.d.ts +0 -5
  672. package/registry/demos/page-header.d.ts +0 -5
  673. package/registry/demos/popover.d.ts +0 -7
  674. package/registry/demos/progress.d.ts +0 -5
  675. package/registry/demos/radio-group.d.ts +0 -5
  676. package/registry/demos/section-backdrop.d.ts +0 -5
  677. package/registry/demos/separator.d.ts +0 -5
  678. package/registry/demos/skeleton.d.ts +0 -5
  679. package/registry/demos/slider.d.ts +0 -5
  680. package/registry/demos/slot.d.ts +0 -5
  681. package/registry/demos/spinner.d.ts +0 -5
  682. package/registry/demos/stat.d.ts +0 -5
  683. package/registry/demos/switch.d.ts +0 -5
  684. package/registry/demos/tabs.d.ts +0 -5
  685. package/registry/demos/theme.d.ts +0 -5
  686. package/registry/demos/toast.d.ts +0 -8
  687. package/registry/demos/tooltip.d.ts +0 -7
  688. /package/dist/{chunk-IUGBKMJC.js.map → chunk-FHYZSO2S.js.map} +0 -0
package/registry/cn.json CHANGED
@@ -1,7 +1,55 @@
1
1
  {
2
2
  "name": "cn",
3
3
  "type": "primitive",
4
- "description": "Merges Tailwind classes: the last one wins — a product's `className` overrides the primitive's. The merge engine is tailwind-merge as tailwind-variants ships it (the one `tv` uses), so the platform carries a single copy of it. tailwind-variants bundles that engine since 3.3 (it never imports the `tailwind-merge` package, an optional peer): hence `tailwind-variants ^3.3.1` and no `tailwind-merge` dependency — `scripts/consumer.mjs` checks it on a clean install of the packed package.",
4
+ "title": "cn",
5
+ "summary": "Joins class names and resolves Tailwind conflicts: the last class wins.",
6
+ "description": "Joins class names and resolves Tailwind conflicts: the last class wins.",
7
+ "status": "stable",
8
+ "category": "foundations",
9
+ "platforms": "web",
10
+ "whenToUse": [
11
+ "To build a `className` from conditions in a product component.",
12
+ "To let a caller's `className` override a component's classes."
13
+ ],
14
+ "whenNotToUse": [
15
+ {
16
+ "when": "To define the variants of a component: use `tv()` from tailwind-variants, like the primitives."
17
+ },
18
+ {
19
+ "when": "To pass props and classes to a child element.",
20
+ "use": "slot"
21
+ }
22
+ ],
23
+ "bestPractices": [
24
+ "Put the caller's `className` last: `cn(base, conditional, className)`.",
25
+ "One `cn` per app: it shares the merge engine of the primitives."
26
+ ],
27
+ "accessibility": {
28
+ "keyboard": [],
29
+ "notes": [
30
+ "No effect on accessibility: it only computes a class string."
31
+ ]
32
+ },
33
+ "related": [
34
+ "slot",
35
+ "theme"
36
+ ],
37
+ "web": {
38
+ "entry": "@krizaka/ui/cn",
39
+ "import": "import { cn } from \"@krizaka/ui/cn\";",
40
+ "props": [],
41
+ "examples": [
42
+ {
43
+ "name": "merge",
44
+ "title": "Merge",
45
+ "description": "The last class wins: `px-4` replaces `px-3`, the selected colours replace the idle ones.",
46
+ "path": "examples/cn/merge.tsx",
47
+ "module": "@krizaka/ui/registry/examples/cn/merge",
48
+ "code": "import { cn } from \"@krizaka/ui/cn\";\n\nexport default function CnMerge({ selected = true }: { selected?: boolean }) {\n return (\n <p className={cn(\"rounded-lg border border-border-default px-3 py-2 text-sm text-fg-secondary\", selected && \"border-accent text-fg\", \"px-4\")}>\n The last class wins: <code>px-4</code> replaces <code>px-3</code>, and the selected colours replace the idle ones.\n </p>\n );\n}\n"
49
+ }
50
+ ]
51
+ },
52
+ "native": null,
5
53
  "files": [
6
54
  {
7
55
  "path": "cn.ts",
@@ -14,8 +62,8 @@
14
62
  ],
15
63
  "registryDependencies": [],
16
64
  "demo": {
17
- "path": "demos/cn.tsx",
18
- "content": "import { cn } from \"@krizaka/ui/cn\";\n\nexport default function CnDemo({ selected = true }: { selected?: boolean }) {\n return (\n <p className={cn(\"rounded-lg border border-border-default px-3 py-2 text-sm text-fg-secondary\", selected && \"border-accent text-fg\", \"px-4\")}>\n The last class wins: <code>px-4</code> replaces <code>px-3</code>, and the selected colours replace the idle ones.\n </p>\n );\n}\n"
65
+ "path": "examples/cn/merge.tsx",
66
+ "content": "import { cn } from \"@krizaka/ui/cn\";\n\nexport default function CnMerge({ selected = true }: { selected?: boolean }) {\n return (\n <p className={cn(\"rounded-lg border border-border-default px-3 py-2 text-sm text-fg-secondary\", selected && \"border-accent text-fg\", \"px-4\")}>\n The last class wins: <code>px-4</code> replaces <code>px-3</code>, and the selected colours replace the idle ones.\n </p>\n );\n}\n"
19
67
  },
20
68
  "props": []
21
69
  }
@@ -1,15 +1,249 @@
1
1
  {
2
2
  "name": "command",
3
3
  "type": "primitive",
4
- "description": "`Command.*` (cmdk) and `CommandDialog`, `command` (the slots). Client (\"use client\").",
4
+ "title": "Command",
5
+ "summary": "A command palette on cmdk: a search input over a filtered list of commands, inline or in a dialog.",
6
+ "description": "A command palette on cmdk: a search input over a filtered list of commands, inline or in a dialog.",
7
+ "status": "beta",
8
+ "category": "navigation",
9
+ "platforms": "web",
10
+ "whenToUse": [
11
+ "To reach any page or action of an app from the keyboard (⌘K): `CommandDialog`.",
12
+ "For a searchable list of choices inside a panel: `Command.Root` inline.",
13
+ "When results come from the server: `shouldFilter={false}` and `Command.Loading`."
14
+ ],
15
+ "whenNotToUse": [
16
+ {
17
+ "when": "For a short list of actions on one item.",
18
+ "use": "dropdown-menu"
19
+ },
20
+ {
21
+ "when": "For a choice among a few options in a form: use a select or radios.",
22
+ "use": "radio-group"
23
+ },
24
+ {
25
+ "when": "As the only way to navigate: keep the visible navigation."
26
+ }
27
+ ],
28
+ "bestPractices": [
29
+ "Group the commands (`Command.Group heading`) and show their shortcuts with `Command.Shortcut`.",
30
+ "Add `keywords` so a command is found by the words people type, not only by its label.",
31
+ "Always say what an empty search means with `emptyLabel` on `Command.List` (said beside the listbox, never inside it)."
32
+ ],
33
+ "accessibility": {
34
+ "keyboard": [
35
+ {
36
+ "keys": "Arrow keys",
37
+ "action": "Move through the results."
38
+ },
39
+ {
40
+ "keys": "Enter",
41
+ "action": "Runs the highlighted command."
42
+ },
43
+ {
44
+ "keys": "Esc",
45
+ "action": "Closes the `CommandDialog` and returns the focus."
46
+ }
47
+ ],
48
+ "notes": [
49
+ "A combobox and a listbox: the input owns `aria-activedescendant`, the results are options.",
50
+ "`label` names the palette, `Command.List label` the results.",
51
+ "`CommandDialog` traps the focus in the platform's Dialog and puts it in the input when it opens."
52
+ ]
53
+ },
54
+ "related": [
55
+ "dialog",
56
+ "dropdown-menu",
57
+ "kbd"
58
+ ],
59
+ "web": {
60
+ "entry": "@krizaka/ui/command",
61
+ "import": "import { Command, CommandDialog } from \"@krizaka/ui/command\";",
62
+ "props": [
63
+ {
64
+ "component": "CommandRoot",
65
+ "description": "The palette: `value` / `onValueChange` (the active item), `shouldFilter`, `filter`, `loop`.",
66
+ "props": [
67
+ {
68
+ "name": "label",
69
+ "type": "string",
70
+ "default": null,
71
+ "description": "Accessible label for this command menu. Not shown visibly.\nThe accessible name of the palette — passed translated (\"Search\", \"Commands\").",
72
+ "required": false
73
+ }
74
+ ]
75
+ },
76
+ {
77
+ "component": "CommandInput",
78
+ "description": "The search field (`value` / `onValueChange` for the query), with a magnifier.",
79
+ "props": [
80
+ {
81
+ "name": "placeholder",
82
+ "type": "string",
83
+ "default": null,
84
+ "description": "What to type — passed translated. The input is named by the palette's `label`.",
85
+ "required": true
86
+ },
87
+ {
88
+ "name": "trailing",
89
+ "type": "ReactNode",
90
+ "default": null,
91
+ "description": "After the input, inside the bar: a spinner, a clear button.",
92
+ "required": false
93
+ }
94
+ ]
95
+ },
96
+ {
97
+ "component": "CommandList",
98
+ "description": "",
99
+ "props": [
100
+ {
101
+ "name": "emptyLabel",
102
+ "type": "ReactNode",
103
+ "default": null,
104
+ "description": "Shown when nothing matches — passed translated. Rendered after the listbox, never inside it: an empty listbox is\nvalid, a listbox holding text is not.",
105
+ "required": false
106
+ },
107
+ {
108
+ "name": "label",
109
+ "type": "string",
110
+ "default": null,
111
+ "description": "Accessible label for this List of suggestions. Not shown visibly.\nThe accessible name of the list of results — passed translated (\"Suggestions\", \"Results\").",
112
+ "required": false
113
+ }
114
+ ]
115
+ },
116
+ {
117
+ "component": "CommandEmpty",
118
+ "description": "Shown by cmdk only when no item matches. Place it beside `Command.List` (or pass `emptyLabel` to the list), never\ninside it: inside, it is rendered as before but warns in development — the listbox then holds text, which axe\nrefuses (`aria-required-children`).",
119
+ "props": [
120
+ {
121
+ "name": "emptyLabel",
122
+ "type": "ReactNode",
123
+ "default": null,
124
+ "description": "Shown when nothing matches — passed translated.",
125
+ "required": true
126
+ }
127
+ ]
128
+ },
129
+ {
130
+ "component": "CommandLoading",
131
+ "description": "While results load (`label` is announced).",
132
+ "props": []
133
+ },
134
+ {
135
+ "component": "CommandGroup",
136
+ "description": "A group of items under a `heading`.",
137
+ "props": []
138
+ },
139
+ {
140
+ "component": "CommandItem",
141
+ "description": "An option: `onSelect` on Enter or click, `value` and `keywords` for the filter, `disabled`.",
142
+ "props": []
143
+ },
144
+ {
145
+ "component": "CommandSeparator",
146
+ "description": "A line between groups. Decorative (`role=\"none\"`): cmdk's own separator is a role a listbox may not hold (axe).",
147
+ "props": []
148
+ },
149
+ {
150
+ "component": "CommandShortcut",
151
+ "description": "A keyboard hint at the end of an item.",
152
+ "props": []
153
+ },
154
+ {
155
+ "component": "CommandDialog",
156
+ "description": "The palette in a dialog (Radix: focus trap, Escape, focus return). The dialog is named by `label`; it has no close\nbutton — Escape and a click outside close it — and the input takes the focus when it opens.",
157
+ "props": [
158
+ {
159
+ "name": "contentProps",
160
+ "type": "Omit<DialogContentProps & RefAttributes<HTMLDivElement> & DialogVariants & { closeLabel?: string; hideClose: true; } & { ...; }, \"children\" | ... 1 more ... | \"hideClose\">",
161
+ "default": null,
162
+ "description": "Passed to `Dialog.Content`: `size`, `container`, `className` of the dialog.",
163
+ "required": false
164
+ },
165
+ {
166
+ "name": "defaultOpen",
167
+ "type": "boolean",
168
+ "default": null,
169
+ "description": "Open at first, uncontrolled.",
170
+ "required": false
171
+ },
172
+ {
173
+ "name": "footer",
174
+ "type": "ReactNode",
175
+ "default": null,
176
+ "description": "Under the palette, inside the dialog: shortcuts, a \"see all results\" link.",
177
+ "required": false
178
+ },
179
+ {
180
+ "name": "label",
181
+ "type": "string",
182
+ "default": null,
183
+ "description": "Accessible label for this command menu. Not shown visibly.\nThe accessible name of the palette — passed translated (\"Search\", \"Commands\").",
184
+ "required": false
185
+ },
186
+ {
187
+ "name": "onOpenChange",
188
+ "type": "((open: boolean) => void)",
189
+ "default": null,
190
+ "description": "Called when it opens or closes (Escape, a click outside, a shortcut of the product).",
191
+ "required": false
192
+ },
193
+ {
194
+ "name": "open",
195
+ "type": "boolean",
196
+ "default": null,
197
+ "description": "Open or closed (controlled), with `onOpenChange`.",
198
+ "required": false
199
+ }
200
+ ]
201
+ }
202
+ ],
203
+ "examples": [
204
+ {
205
+ "name": "inline",
206
+ "title": "Inline",
207
+ "description": "In a card: the input, groups, shortcuts, a disabled item.",
208
+ "path": "examples/command/inline.tsx",
209
+ "module": "@krizaka/ui/registry/examples/command/inline",
210
+ "code": "import { Command } from \"@krizaka/ui/command\";\n\nexport default function CommandInline() {\n return (\n <Command.Root label=\"Commands\" className=\"w-[28rem] max-w-full rounded-xl border border-border-default shadow-lg\">\n <Command.Input placeholder=\"Type a command or search\" />\n <Command.List label=\"Suggestions\" emptyLabel=\"Nothing matches.\">\n <Command.Group heading=\"Pages\">\n <Command.Item>\n Home\n <Command.Shortcut>G H</Command.Shortcut>\n </Command.Item>\n <Command.Item>\n Wallet\n <Command.Shortcut>G W</Command.Shortcut>\n </Command.Item>\n <Command.Item disabled>Studio</Command.Item>\n </Command.Group>\n <Command.Separator />\n <Command.Group heading=\"Actions\">\n <Command.Item keywords={[\"video\", \"new\"]}>Upload a video</Command.Item>\n <Command.Item>Switch the theme</Command.Item>\n </Command.Group>\n </Command.List>\n </Command.Root>\n );\n}\n"
211
+ },
212
+ {
213
+ "name": "no-results",
214
+ "title": "No results",
215
+ "description": "`emptyLabel` on `Command.List`: said beside the listbox when nothing matches.",
216
+ "path": "examples/command/no-results.tsx",
217
+ "module": "@krizaka/ui/registry/examples/command/no-results",
218
+ "code": "\"use client\";\n\nimport { Command } from \"@krizaka/ui/command\";\nimport { useState } from \"react\";\n\n// Nothing matches: `emptyLabel` is said beside the results, the listbox stays empty (valid for screen readers).\nexport default function CommandNoResults() {\n const [query, setQuery] = useState(\"zzz\");\n return (\n <Command.Root label=\"Commands\" className=\"w-[28rem] max-w-full rounded-xl border border-border-default shadow-lg\">\n <Command.Input placeholder=\"Type a command or search\" value={query} onValueChange={setQuery} />\n <Command.List label=\"Suggestions\" emptyLabel={`Nothing matches “${query}”.`}>\n <Command.Group heading=\"Pages\">\n <Command.Item>Home</Command.Item>\n <Command.Item>Wallet</Command.Item>\n </Command.Group>\n </Command.List>\n </Command.Root>\n );\n}\n"
219
+ },
220
+ {
221
+ "name": "dialog",
222
+ "title": "In a dialog",
223
+ "description": "`CommandDialog`: the palette of an app, opened from a button or a shortcut.",
224
+ "path": "examples/command/dialog.tsx",
225
+ "module": "@krizaka/ui/registry/examples/command/dialog",
226
+ "code": "\"use client\";\n\nimport { Button } from \"@krizaka/ui/button\";\nimport { Command, CommandDialog } from \"@krizaka/ui/command\";\nimport { Kbd } from \"@krizaka/ui/kbd\";\nimport { useState } from \"react\";\n\n// The palette of an app, in the platform's Dialog: open it from a button or your own ⌘K shortcut.\nexport default function CommandDialogExample({ defaultOpen = false }: { defaultOpen?: boolean }) {\n const [open, setOpen] = useState(defaultOpen);\n return (\n <>\n <Button variant=\"outline\" onClick={() => setOpen(true)}>\n Search <Kbd size=\"sm\">⌘K</Kbd>\n </Button>\n <CommandDialog\n open={open}\n onOpenChange={setOpen}\n label=\"Search\"\n footer={<p className=\"border-t border-border-subtle bg-surface-2 px-4 py-2.5 text-xs text-fg-secondary\">↑↓ to move, ↵ to open</p>}\n >\n <Command.Input placeholder=\"Search creators, videos, tags\" />\n <Command.List label=\"Results\" emptyLabel=\"Nothing matches.\">\n <Command.Group heading=\"Pages\">\n <Command.Item onSelect={() => setOpen(false)}>Home</Command.Item>\n <Command.Item onSelect={() => setOpen(false)}>Wallet</Command.Item>\n </Command.Group>\n <Command.Group heading=\"Actions\">\n <Command.Item keywords={[\"video\", \"new\"]}>Upload a video</Command.Item>\n </Command.Group>\n </Command.List>\n </CommandDialog>\n </>\n );\n}\n"
227
+ }
228
+ ]
229
+ },
230
+ "native": null,
5
231
  "files": [
6
232
  {
7
233
  "path": "command/command.tsx",
8
- "content": "// Client. A command palette on cmdk: the combobox / listbox roles, the active option (aria-activedescendant), the\n// arrows, Home / End, Enter, and the filtering (turn it off with `shouldFilter={false}` when the server searches).\n// `CommandDialog` puts it in the platform's Dialog. Words arrive as props.\nimport { Command as CommandPrimitive } from \"cmdk\";\nimport { Dialog as DialogPrimitive } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { cn } from \"../cn\";\nimport { DialogContent, type DialogContentProps } from \"../dialog/dialog\";\n\nexport const command = tv({\n slots: {\n root: \"flex h-full w-full flex-col overflow-hidden bg-surface-1 text-fg\",\n inputWrap: \"flex items-center gap-3 border-b border-border-default px-4\",\n icon: \"h-5 w-5 shrink-0 text-fg-secondary\",\n input:\n \"h-13 w-full min-w-0 flex-1 bg-transparent text-sm text-fg outline-hidden placeholder:text-fg-muted disabled:cursor-not-allowed disabled:opacity-50 sm:text-base\",\n list: \"max-h-[min(60dvh,26rem)] scroll-py-2 overflow-y-auto overscroll-contain p-2\",\n empty: \"px-3 py-8 text-center text-sm text-fg-secondary\",\n loading: \"px-3 py-6 text-center text-sm text-fg-secondary\",\n group:\n \"[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:pb-1.5 [&_[cmdk-group-heading]]:pt-3 [&_[cmdk-group-heading]]:text-xs \" +\n \"[&_[cmdk-group-heading]]:font-semibold [&_[cmdk-group-heading]]:uppercase [&_[cmdk-group-heading]]:tracking-wider [&_[cmdk-group-heading]]:text-fg-secondary\",\n item:\n \"relative flex cursor-pointer select-none items-center gap-3 rounded-lg px-3 py-2.5 text-sm text-fg outline-hidden transition-colors \" +\n \"before:absolute before:inset-y-2 before:left-0 before:w-0.5 before:rounded-full before:bg-transparent \" +\n \"data-[selected=true]:bg-surface-2 data-[selected=true]:before:bg-accent data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-40\",\n separator: \"-mx-2 my-1 h-px bg-border-subtle\",\n shortcut: \"ml-auto text-xs tracking-widest text-fg-secondary\",\n },\n});\nconst s = command();\n\nfunction SearchIcon({ className }: { className?: string }) {\n return (\n <svg viewBox=\"0 0 24 24\" className={className} fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"m20 20-3.5-3.5\" />\n </svg>\n );\n}\n\nexport type CommandRootProps = React.ComponentProps<typeof CommandPrimitive> & {\n /** The accessible name of the palette — passed translated (\"Search\", \"Commands\"). */\n label: string;\n};\n\n/** The palette: `value` / `onValueChange` (the active item), `shouldFilter`, `filter`, `loop`. */\nexport function CommandRoot({ className, ...props }: CommandRootProps) {\n return <CommandPrimitive className={s.root({ className })} {...props} />;\n}\n\nexport type CommandInputProps = Omit<React.ComponentProps<typeof CommandPrimitive.Input>, \"placeholder\"> & {\n /** What to type — passed translated. The input is named by the palette's `label`. */\n placeholder: string;\n /** After the input, inside the bar: a spinner, a clear button. */\n trailing?: React.ReactNode;\n};\n\n/** The search field (`value` / `onValueChange` for the query), with a magnifier. */\nexport function CommandInput({ className, placeholder, trailing, ...props }: CommandInputProps) {\n return (\n <div className={s.inputWrap()} cmdk-input-wrapper=\"\">\n <SearchIcon className={s.icon()} />\n <CommandPrimitive.Input placeholder={placeholder} className={s.input({ className })} {...props} />\n {trailing}\n </div>\n );\n}\n\nexport type CommandListProps = React.ComponentProps<typeof CommandPrimitive.List> & {\n /** The accessible name of the list of results — passed translated (\"Suggestions\", \"Results\"). */\n label: string;\n};\n\nexport function CommandList({ className, ...props }: CommandListProps) {\n return <CommandPrimitive.List className={s.list({ className })} {...props} />;\n}\n\nexport type CommandEmptyProps = Omit<React.ComponentProps<typeof CommandPrimitive.Empty>, \"children\"> & {\n /** Shown when nothing matches — passed translated. */\n emptyLabel: React.ReactNode;\n};\n\n/** Shown by cmdk only when no item matches. */\nexport function CommandEmpty({ className, emptyLabel, ...props }: CommandEmptyProps) {\n return (\n <CommandPrimitive.Empty className={s.empty({ className })} {...props}>\n {emptyLabel}\n </CommandPrimitive.Empty>\n );\n}\n\n/** While results load (`label` is announced). */\nexport function CommandLoading({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Loading>) {\n return <CommandPrimitive.Loading className={s.loading({ className })} {...props} />;\n}\n\n/** A group of items under a `heading`. */\nexport function CommandGroup({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Group>) {\n return <CommandPrimitive.Group className={s.group({ className })} {...props} />;\n}\n\n/** An option: `onSelect` on Enter or click, `value` and `keywords` for the filter, `disabled`. */\nexport function CommandItem({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Item>) {\n return <CommandPrimitive.Item className={s.item({ className })} {...props} />;\n}\n\n/** A line between groups. Decorative (`role=\"none\"`): cmdk's own separator is a role a listbox may not hold (axe). */\nexport function CommandSeparator({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div role=\"none\" className={s.separator({ className })} {...props} />;\n}\n\n/** A keyboard hint at the end of an item. */\nexport function CommandShortcut({ className, ...props }: React.ComponentProps<\"span\">) {\n return <span className={s.shortcut({ className })} {...props} />;\n}\n\n/** `Command.Root/Input/List/Empty/Loading/Group/Item/Separator/Shortcut`. */\nexport const Command = {\n Root: CommandRoot,\n Input: CommandInput,\n List: CommandList,\n Empty: CommandEmpty,\n Loading: CommandLoading,\n Group: CommandGroup,\n Item: CommandItem,\n Separator: CommandSeparator,\n Shortcut: CommandShortcut,\n};\n\nexport type CommandDialogProps = Omit<CommandRootProps, \"title\"> & {\n /** Open or closed (controlled), with `onOpenChange`. */\n open?: boolean;\n /** Open at first, uncontrolled. */\n defaultOpen?: boolean;\n /** Called when it opens or closes (Escape, a click outside, a shortcut of the product). */\n onOpenChange?: (open: boolean) => void;\n /** Under the palette, inside the dialog: shortcuts, a \"see all results\" link. */\n footer?: React.ReactNode;\n /** Passed to `Dialog.Content`: `size`, `container`, `className` of the dialog. */\n contentProps?: Omit<Extract<DialogContentProps, { hideClose: true }>, \"hideClose\" | \"children\" | \"placement\">;\n};\n\n/**\n * The palette in a dialog (Radix: focus trap, Escape, focus return). The dialog is named by `label`; it has no close\n * button — Escape and a click outside close it — and the input takes the focus when it opens.\n */\nexport function CommandDialog({ open, defaultOpen, onOpenChange, footer, contentProps, label, className, children, ...props }: CommandDialogProps) {\n const { className: contentClassName, ...content } = contentProps ?? {};\n return (\n <DialogPrimitive.Root open={open} defaultOpen={defaultOpen} onOpenChange={onOpenChange}>\n <DialogContent\n hideClose\n size=\"lg\"\n aria-describedby={undefined}\n className={cn(\"top-[12dvh] translate-y-0 sm:top-[14dvh]\", contentClassName)}\n {...content}\n >\n <DialogPrimitive.Title className=\"sr-only\">{label}</DialogPrimitive.Title>\n <CommandRoot label={label} className={className} {...props}>\n {children}\n </CommandRoot>\n {footer}\n </DialogContent>\n </DialogPrimitive.Root>\n );\n}\n"
234
+ "content": "// Client. A command palette on cmdk: the combobox / listbox roles, the active option (aria-activedescendant), the\n// arrows, Home / End, Enter, and the filtering (turn it off with `shouldFilter={false}` when the server searches).\n// `CommandDialog` puts it in the platform's Dialog. Words arrive as props.\nimport { Command as CommandPrimitive } from \"cmdk\";\nimport { Dialog as DialogPrimitive } from \"radix-ui\";\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { cn } from \"../cn\";\nimport { DialogContent, type DialogContentProps } from \"../dialog/dialog\";\n\nexport const command = tv({\n slots: {\n root: \"flex h-full w-full flex-col overflow-hidden bg-surface-1 text-fg\",\n inputWrap: \"flex items-center gap-3 border-b border-border-default px-4\",\n icon: \"h-5 w-5 shrink-0 text-fg-secondary\",\n input:\n \"h-13 w-full min-w-0 flex-1 bg-transparent text-sm text-fg outline-hidden placeholder:text-fg-muted disabled:cursor-not-allowed disabled:opacity-50 sm:text-base\",\n list: \"max-h-[min(60dvh,26rem)] scroll-py-2 overflow-y-auto overscroll-contain p-2 [&:not(:has([cmdk-item]))]:p-0\",\n empty: \"px-3 py-8 text-center text-sm text-fg-secondary\",\n loading: \"px-3 py-6 text-center text-sm text-fg-secondary\",\n group:\n \"[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:pb-1.5 [&_[cmdk-group-heading]]:pt-3 [&_[cmdk-group-heading]]:text-xs \" +\n \"[&_[cmdk-group-heading]]:font-semibold [&_[cmdk-group-heading]]:uppercase [&_[cmdk-group-heading]]:tracking-wider [&_[cmdk-group-heading]]:text-fg-secondary\",\n item:\n \"relative flex cursor-pointer select-none items-center gap-3 rounded-lg px-3 py-2.5 text-sm text-fg outline-hidden transition-colors \" +\n \"before:absolute before:inset-y-2 before:left-0 before:w-0.5 before:rounded-full before:bg-transparent \" +\n \"data-[selected=true]:bg-surface-2 data-[selected=true]:before:bg-accent data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-40\",\n separator: \"-mx-2 my-1 h-px bg-border-subtle\",\n shortcut: \"ml-auto text-xs tracking-widest text-fg-secondary\",\n },\n});\nconst s = command();\n\nfunction SearchIcon({ className }: { className?: string }) {\n return (\n <svg viewBox=\"0 0 24 24\" className={className} fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"m20 20-3.5-3.5\" />\n </svg>\n );\n}\n\nexport type CommandRootProps = React.ComponentProps<typeof CommandPrimitive> & {\n /** The accessible name of the palette — passed translated (\"Search\", \"Commands\"). */\n label: string;\n};\n\n/** The palette: `value` / `onValueChange` (the active item), `shouldFilter`, `filter`, `loop`. */\nexport function CommandRoot({ className, ...props }: CommandRootProps) {\n return <CommandPrimitive className={s.root({ className })} {...props} />;\n}\n\nexport type CommandInputProps = Omit<React.ComponentProps<typeof CommandPrimitive.Input>, \"placeholder\"> & {\n /** What to type — passed translated. The input is named by the palette's `label`. */\n placeholder: string;\n /** After the input, inside the bar: a spinner, a clear button. */\n trailing?: React.ReactNode;\n};\n\n/** The search field (`value` / `onValueChange` for the query), with a magnifier. */\nexport function CommandInput({ className, placeholder, trailing, ...props }: CommandInputProps) {\n return (\n <div className={s.inputWrap()} cmdk-input-wrapper=\"\">\n <SearchIcon className={s.icon()} />\n <CommandPrimitive.Input placeholder={placeholder} className={s.input({ className })} {...props} />\n {trailing}\n </div>\n );\n}\n\n// Set inside `Command.List`: a listbox may only hold options and groups (axe `aria-required-children`), so the empty\n// message must live beside it, not in it.\nconst InsideList = React.createContext(false);\n\nexport type CommandListProps = React.ComponentProps<typeof CommandPrimitive.List> & {\n /** The accessible name of the list of results — passed translated (\"Suggestions\", \"Results\"). */\n label: string;\n /**\n * Shown when nothing matches — passed translated. Rendered after the listbox, never inside it: an empty listbox is\n * valid, a listbox holding text is not.\n */\n emptyLabel?: React.ReactNode;\n};\n\nexport function CommandList({ className, emptyLabel, children, ...props }: CommandListProps) {\n return (\n <>\n <CommandPrimitive.List className={s.list({ className })} {...props}>\n <InsideList.Provider value>{children}</InsideList.Provider>\n </CommandPrimitive.List>\n {emptyLabel === undefined ? null : <CommandEmpty emptyLabel={emptyLabel} />}\n </>\n );\n}\n\nexport type CommandEmptyProps = Omit<React.ComponentProps<typeof CommandPrimitive.Empty>, \"children\"> & {\n /** Shown when nothing matches — passed translated. */\n emptyLabel: React.ReactNode;\n};\n\n/**\n * Shown by cmdk only when no item matches. Place it beside `Command.List` (or pass `emptyLabel` to the list), never\n * inside it: inside, it is rendered as before but warns in development — the listbox then holds text, which axe\n * refuses (`aria-required-children`).\n */\nexport function CommandEmpty({ className, emptyLabel, ...props }: CommandEmptyProps) {\n const inside = React.useContext(InsideList);\n React.useEffect(() => {\n if (inside && typeof process !== \"undefined\" && process.env.NODE_ENV !== \"production\") {\n console.warn(\"@krizaka/ui/command: <Command.Empty> inside <Command.List> breaks the listbox (axe aria-required-children). Pass `emptyLabel` to <Command.List> instead.\");\n }\n }, [inside]);\n return (\n <CommandPrimitive.Empty className={s.empty({ className })} {...props}>\n {emptyLabel}\n </CommandPrimitive.Empty>\n );\n}\n\n/** While results load (`label` is announced). */\nexport function CommandLoading({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Loading>) {\n return <CommandPrimitive.Loading className={s.loading({ className })} {...props} />;\n}\n\n/** A group of items under a `heading`. */\nexport function CommandGroup({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Group>) {\n return <CommandPrimitive.Group className={s.group({ className })} {...props} />;\n}\n\n/** An option: `onSelect` on Enter or click, `value` and `keywords` for the filter, `disabled`. */\nexport function CommandItem({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Item>) {\n return <CommandPrimitive.Item className={s.item({ className })} {...props} />;\n}\n\n/** A line between groups. Decorative (`role=\"none\"`): cmdk's own separator is a role a listbox may not hold (axe). */\nexport function CommandSeparator({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div role=\"none\" className={s.separator({ className })} {...props} />;\n}\n\n/** A keyboard hint at the end of an item. */\nexport function CommandShortcut({ className, ...props }: React.ComponentProps<\"span\">) {\n return <span className={s.shortcut({ className })} {...props} />;\n}\n\n/** `Command.Root/Input/List/Empty/Loading/Group/Item/Separator/Shortcut`. */\nexport const Command = {\n Root: CommandRoot,\n Input: CommandInput,\n List: CommandList,\n Empty: CommandEmpty,\n Loading: CommandLoading,\n Group: CommandGroup,\n Item: CommandItem,\n Separator: CommandSeparator,\n Shortcut: CommandShortcut,\n};\n\nexport type CommandDialogProps = Omit<CommandRootProps, \"title\"> & {\n /** Open or closed (controlled), with `onOpenChange`. */\n open?: boolean;\n /** Open at first, uncontrolled. */\n defaultOpen?: boolean;\n /** Called when it opens or closes (Escape, a click outside, a shortcut of the product). */\n onOpenChange?: (open: boolean) => void;\n /** Under the palette, inside the dialog: shortcuts, a \"see all results\" link. */\n footer?: React.ReactNode;\n /** Passed to `Dialog.Content`: `size`, `container`, `className` of the dialog. */\n contentProps?: Omit<Extract<DialogContentProps, { hideClose: true }>, \"hideClose\" | \"children\" | \"placement\">;\n};\n\n/**\n * The palette in a dialog (Radix: focus trap, Escape, focus return). The dialog is named by `label`; it has no close\n * button — Escape and a click outside close it — and the input takes the focus when it opens.\n */\nexport function CommandDialog({ open, defaultOpen, onOpenChange, footer, contentProps, label, className, children, ...props }: CommandDialogProps) {\n const { className: contentClassName, ...content } = contentProps ?? {};\n return (\n <DialogPrimitive.Root open={open} defaultOpen={defaultOpen} onOpenChange={onOpenChange}>\n <DialogContent\n hideClose\n size=\"lg\"\n aria-describedby={undefined}\n className={cn(\"top-[12dvh] translate-y-0 sm:top-[14dvh]\", contentClassName)}\n {...content}\n >\n <DialogPrimitive.Title className=\"sr-only\">{label}</DialogPrimitive.Title>\n <CommandRoot label={label} className={className} {...props}>\n {children}\n </CommandRoot>\n {footer}\n </DialogContent>\n </DialogPrimitive.Root>\n );\n}\n"
9
235
  },
10
236
  {
11
237
  "path": "command/index.ts",
12
238
  "content": "/** @krizaka/ui/command — `Command.*` (cmdk) and `CommandDialog`, `command` (the slots). Client (\"use client\"). */\nexport {\n Command,\n command,\n CommandDialog,\n type CommandDialogProps,\n CommandEmpty,\n type CommandEmptyProps,\n CommandGroup,\n CommandInput,\n type CommandInputProps,\n CommandItem,\n CommandList,\n type CommandListProps,\n CommandLoading,\n CommandRoot,\n type CommandRootProps,\n CommandSeparator,\n CommandShortcut,\n} from \"./command\";\n"
239
+ },
240
+ {
241
+ "path": "command/meta.ts",
242
+ "content": "import type { ComponentMeta } from \"../meta\";\n\nexport const meta = {\n title: \"Command\",\n summary: \"A command palette on cmdk: a search input over a filtered list of commands, inline or in a dialog.\",\n status: \"beta\",\n category: \"navigation\",\n platforms: \"web\",\n whenToUse: [\n \"To reach any page or action of an app from the keyboard (⌘K): `CommandDialog`.\",\n \"For a searchable list of choices inside a panel: `Command.Root` inline.\",\n \"When results come from the server: `shouldFilter={false}` and `Command.Loading`.\",\n ],\n whenNotToUse: [\n { when: \"For a short list of actions on one item.\", use: \"dropdown-menu\" },\n { when: \"For a choice among a few options in a form: use a select or radios.\", use: \"radio-group\" },\n { when: \"As the only way to navigate: keep the visible navigation.\" },\n ],\n bestPractices: [\n \"Group the commands (`Command.Group heading`) and show their shortcuts with `Command.Shortcut`.\",\n \"Add `keywords` so a command is found by the words people type, not only by its label.\",\n \"Always say what an empty search means with `emptyLabel` on `Command.List` (said beside the listbox, never inside it).\",\n ],\n accessibility: {\n keyboard: [\n { keys: \"Arrow keys\", action: \"Move through the results.\" },\n { keys: \"Enter\", action: \"Runs the highlighted command.\" },\n { keys: \"Esc\", action: \"Closes the `CommandDialog` and returns the focus.\" },\n ],\n notes: [\n \"A combobox and a listbox: the input owns `aria-activedescendant`, the results are options.\",\n \"`label` names the palette, `Command.List label` the results.\",\n \"`CommandDialog` traps the focus in the platform's Dialog and puts it in the input when it opens.\",\n ],\n },\n related: [\"dialog\", \"dropdown-menu\", \"kbd\"],\n web: {\n imports: [\"Command\", \"CommandDialog\"],\n examples: [\n { name: \"inline\", title: \"Inline\", description: \"In a card: the input, groups, shortcuts, a disabled item.\" },\n { name: \"no-results\", title: \"No results\", description: \"`emptyLabel` on `Command.List`: said beside the listbox when nothing matches.\" },\n { name: \"dialog\", title: \"In a dialog\", description: \"`CommandDialog`: the palette of an app, opened from a button or a shortcut.\" },\n ],\n },\n} satisfies ComponentMeta;\n"
243
+ },
244
+ {
245
+ "path": "meta.ts",
246
+ "content": "// The documentation of a component, carried by its code: each primitive has a `meta.ts` beside its source\n// (`src/<name>/meta.ts`; a component that exists only in React Native: `src/native/meta/<name>.ts`). Never built into\n// the package: `scripts/build-registry.mjs` reads them into `registry/<name>.json`, which krizaka.com renders as\n// /docs/ui/<name>, and `scripts/registry.test.mjs` fails when one is missing or incomplete.\n//\n// Why a typed module and not JSDoc tags: the fields are lists and links (`related`, `whenNotToUse[].use`, examples),\n// which a type checks and a comment does not; the file is plain data (erasable TypeScript), so Node reads it without a\n// compiler, and an editor completes it.\n\n/** Every documented component: the web primitives (one entry of the package each) and the native-only ones. */\nexport type ComponentName =\n | \"alert\"\n | \"avatar\"\n | \"badge\"\n | \"button\"\n | \"card\"\n | \"checkbox\"\n | \"chip\"\n | \"cn\"\n | \"command\"\n | \"confirm-button\"\n | \"countdown\"\n | \"dialog\"\n | \"dropdown-menu\"\n | \"empty-state\"\n | \"field\"\n | \"kbd\"\n | \"page-header\"\n | \"popover\"\n | \"progress\"\n | \"radio-group\"\n | \"section-backdrop\"\n | \"segmented\"\n | \"separator\"\n | \"skeleton\"\n | \"slider\"\n | \"slot\"\n | \"spinner\"\n | \"stat\"\n | \"switch\"\n | \"tabs\"\n | \"theme\"\n | \"toast\"\n | \"tooltip\"\n | \"txt\";\n\n/** Where a component exists: `@krizaka/ui/<name>` (web), `@krizaka/ui/native` (React Native), or both. */\nexport type Platform = \"web\" | \"native\" | \"both\";\n\n/** `stable`: its API only changes in a major. `beta`: it may still change in a minor. */\nexport type Status = \"stable\" | \"beta\";\n\n/** The group of the catalogue. */\nexport type Category = \"actions\" | \"forms\" | \"navigation\" | \"overlays\" | \"feedback\" | \"data-display\" | \"layout\" | \"foundations\";\n\n/**\n * A named example: the file `registry/examples/<component>/<name>.tsx` (web) or\n * `registry/examples/<component>/native/<name>.tsx` (React Native) — at most 40 lines, imported by the stories and\n * shown (live, with its code) by the documentation.\n */\nexport interface Example {\n /** The file name, kebab-case (`primary`, `icon-button`). */\n readonly name: string;\n /** A short title (`Primary`, `Icon button`). */\n readonly title: string;\n /** One or two sentences: when this variant is the right one. */\n readonly description: string;\n}\n\n/** One platform's side of a component. */\nexport interface PlatformDocs {\n /** The names to import (`[\"Button\", \"IconButton\"]`): from `@krizaka/ui/<name>` on the web, `@krizaka/ui/native` in React Native. */\n readonly imports: readonly string[];\n /** The examples, in reading order; the first one is the component's preview. */\n readonly examples: readonly Example[];\n}\n\n/** The React Native side: the same concept, and what differs from the web API. */\nexport interface NativeDocs extends PlatformDocs {\n /** What differs from the web API (`label` instead of children…); empty for a native-only component. */\n readonly differences: readonly string[];\n}\n\nexport interface KeyboardInteraction {\n /** The keys, as written on a keyboard: `Space`, `Enter`, `Arrow keys`, `Esc`, `Tab`. */\n readonly keys: string;\n /** What they do. */\n readonly action: string;\n}\n\nexport interface ComponentMeta {\n /** The display name: `Button`, `Dropdown menu`. */\n readonly title: string;\n /** One sentence: what it is. */\n readonly summary: string;\n readonly status: Status;\n readonly category: Category;\n /** Must match the sides below: `both` ⇔ `web` and `native`. */\n readonly platforms: Platform;\n /** When to reach for it: concrete situations, one per item. */\n readonly whenToUse: readonly string[];\n /** When not to — and what to use instead (`use`), when another component is the answer. */\n readonly whenNotToUse: readonly { readonly when: string; readonly use?: ComponentName }[];\n /** How to use it well: wording, placement, composition. */\n readonly bestPractices: readonly string[];\n readonly accessibility: {\n /** The keyboard, when it does more than Tab and Enter. */\n readonly keyboard: readonly KeyboardInteraction[];\n /** Roles, names and announcements: what the component does, what the app must provide. */\n readonly notes: readonly string[];\n };\n /** The components a reader of this page should know about. */\n readonly related: readonly ComponentName[];\n readonly web?: PlatformDocs;\n readonly native?: NativeDocs;\n}\n"
13
247
  }
14
248
  ],
15
249
  "dependencies": [
@@ -22,8 +256,8 @@
22
256
  "dialog"
23
257
  ],
24
258
  "demo": {
25
- "path": "demos/command.tsx",
26
- "content": "import { Command } from \"@krizaka/ui/command\";\n\nexport default function CommandDemo() {\n return (\n <Command.Root label=\"Commands\" className=\"w-[28rem] max-w-full rounded-xl border border-border-default shadow-lg\">\n <Command.Input placeholder=\"Type a command or search\" />\n <Command.List label=\"Suggestions\">\n <Command.Empty emptyLabel=\"Nothing matches.\" />\n <Command.Group heading=\"Pages\">\n <Command.Item>\n Home\n <Command.Shortcut>G H</Command.Shortcut>\n </Command.Item>\n <Command.Item>\n Wallet\n <Command.Shortcut>G W</Command.Shortcut>\n </Command.Item>\n <Command.Item disabled>Studio</Command.Item>\n </Command.Group>\n <Command.Separator />\n <Command.Group heading=\"Actions\">\n <Command.Item keywords={[\"video\", \"new\"]}>Upload a video</Command.Item>\n <Command.Item>Switch the theme</Command.Item>\n </Command.Group>\n </Command.List>\n </Command.Root>\n );\n}\n"
259
+ "path": "examples/command/inline.tsx",
260
+ "content": "import { Command } from \"@krizaka/ui/command\";\n\nexport default function CommandInline() {\n return (\n <Command.Root label=\"Commands\" className=\"w-[28rem] max-w-full rounded-xl border border-border-default shadow-lg\">\n <Command.Input placeholder=\"Type a command or search\" />\n <Command.List label=\"Suggestions\" emptyLabel=\"Nothing matches.\">\n <Command.Group heading=\"Pages\">\n <Command.Item>\n Home\n <Command.Shortcut>G H</Command.Shortcut>\n </Command.Item>\n <Command.Item>\n Wallet\n <Command.Shortcut>G W</Command.Shortcut>\n </Command.Item>\n <Command.Item disabled>Studio</Command.Item>\n </Command.Group>\n <Command.Separator />\n <Command.Group heading=\"Actions\">\n <Command.Item keywords={[\"video\", \"new\"]}>Upload a video</Command.Item>\n <Command.Item>Switch the theme</Command.Item>\n </Command.Group>\n </Command.List>\n </Command.Root>\n );\n}\n"
27
261
  },
28
262
  "props": [
29
263
  {
@@ -63,6 +297,13 @@
63
297
  "component": "CommandList",
64
298
  "description": "",
65
299
  "props": [
300
+ {
301
+ "name": "emptyLabel",
302
+ "type": "ReactNode",
303
+ "default": null,
304
+ "description": "Shown when nothing matches — passed translated. Rendered after the listbox, never inside it: an empty listbox is\nvalid, a listbox holding text is not.",
305
+ "required": false
306
+ },
66
307
  {
67
308
  "name": "label",
68
309
  "type": "string",
@@ -74,7 +315,7 @@
74
315
  },
75
316
  {
76
317
  "component": "CommandEmpty",
77
- "description": "Shown by cmdk only when no item matches.",
318
+ "description": "Shown by cmdk only when no item matches. Place it beside `Command.List` (or pass `emptyLabel` to the list), never\ninside it: inside, it is rendered as before but warns in development — the listbox then holds text, which axe\nrefuses (`aria-required-children`).",
78
319
  "props": [
79
320
  {
80
321
  "name": "emptyLabel",
@@ -1,7 +1,166 @@
1
1
  {
2
2
  "name": "confirm-button",
3
3
  "type": "primitive",
4
- "description": "`ConfirmButton` (two steps: arm, then confirm). Client (\"use client\").",
4
+ "title": "Confirm button",
5
+ "summary": "A destructive action in two presses: the first arms it and says what will happen, the second runs it.",
6
+ "description": "A destructive action in two presses: the first arms it and says what will happen, the second runs it.",
7
+ "status": "beta",
8
+ "category": "actions",
9
+ "platforms": "web",
10
+ "whenToUse": [
11
+ "For a destructive action on one item, in place: delete a comment, remove a member, leave a group.",
12
+ "When a dialog would be too heavy and an undo is not possible."
13
+ ],
14
+ "whenNotToUse": [
15
+ {
16
+ "when": "When the consequences need explaining, or several things are affected.",
17
+ "use": "dialog"
18
+ },
19
+ {
20
+ "when": "For an action that is not destructive.",
21
+ "use": "button"
22
+ },
23
+ {
24
+ "when": "When the action can be undone: run it at once and offer “Undo” in a toast.",
25
+ "use": "toast"
26
+ }
27
+ ],
28
+ "bestPractices": [
29
+ "`confirmLabel` says the consequence as a question: “Delete for good?”.",
30
+ "Keep `timeoutMs` short (4 s by default): an armed button left on screen is a trap.",
31
+ "Never use `window.confirm` for this."
32
+ ],
33
+ "accessibility": {
34
+ "keyboard": [
35
+ {
36
+ "keys": "Enter / Space",
37
+ "action": "Arms, then confirms."
38
+ },
39
+ {
40
+ "keys": "Esc",
41
+ "action": "Disarms; so does moving the focus away."
42
+ }
43
+ ],
44
+ "notes": [
45
+ "Once armed, `confirmLabel` names the button and is announced politely.",
46
+ "An icon-only confirm button needs `label` while idle.",
47
+ "The armed state is `data-armed`: style it with the danger tint, the words stay a text role."
48
+ ]
49
+ },
50
+ "related": [
51
+ "button",
52
+ "dialog",
53
+ "toast"
54
+ ],
55
+ "web": {
56
+ "entry": "@krizaka/ui/confirm-button",
57
+ "import": "import { ConfirmButton } from \"@krizaka/ui/confirm-button\";",
58
+ "props": [
59
+ {
60
+ "component": "ConfirmButton",
61
+ "description": "A two-step button: press to arm, press again within `timeoutMs` to confirm. State: `data-armed`.",
62
+ "props": [
63
+ {
64
+ "name": "confirmLabel",
65
+ "type": "string",
66
+ "default": null,
67
+ "description": "What the second press does, in words — shown and announced once armed (\"Delete for good?\"). Passed translated.",
68
+ "required": true
69
+ },
70
+ {
71
+ "name": "onConfirm",
72
+ "type": "() => void",
73
+ "default": null,
74
+ "description": "Runs on the second press.",
75
+ "required": true
76
+ },
77
+ {
78
+ "name": "armedContent",
79
+ "type": "ReactNode",
80
+ "default": null,
81
+ "description": "What it shows once armed (default: its children, then `confirmLabel`).",
82
+ "required": false
83
+ },
84
+ {
85
+ "name": "label",
86
+ "type": "string",
87
+ "default": null,
88
+ "description": "The accessible name while idle, for an icon-only button (the confirm label names it once armed).",
89
+ "required": false
90
+ },
91
+ {
92
+ "name": "loading",
93
+ "type": "boolean",
94
+ "default": null,
95
+ "description": "Disables and signals the wait (aria-busy, data-loading) — the product adds a spinner if it wants one.",
96
+ "required": false
97
+ },
98
+ {
99
+ "name": "onArmedChange",
100
+ "type": "((armed: boolean) => void)",
101
+ "default": null,
102
+ "description": "Notified when it arms and disarms.",
103
+ "required": false
104
+ },
105
+ {
106
+ "name": "shape",
107
+ "type": "\"rounded\" | \"pill\"",
108
+ "default": "rounded",
109
+ "description": "rounded · pill.",
110
+ "required": false
111
+ },
112
+ {
113
+ "name": "size",
114
+ "type": "\"icon\" | \"sm\" | \"md\" | \"lg\"",
115
+ "default": "md",
116
+ "description": "sm · md · lg, or `icon` (a square).",
117
+ "required": false
118
+ },
119
+ {
120
+ "name": "timeoutMs",
121
+ "type": "number",
122
+ "default": "4000",
123
+ "description": "Disarms after this many milliseconds (4000 by default).",
124
+ "required": false
125
+ },
126
+ {
127
+ "name": "variant",
128
+ "type": "\"danger\" | \"primary\" | \"gradient\" | \"secondary\" | \"outline\" | \"ghost\"",
129
+ "default": "ghost",
130
+ "description": "The look: `primary` (the accent), `gradient` (accent → accent-2), `secondary` (a raised surface), `outline`,\n`ghost`, `danger`.",
131
+ "required": false
132
+ }
133
+ ]
134
+ }
135
+ ],
136
+ "examples": [
137
+ {
138
+ "name": "idle",
139
+ "title": "Icon, idle",
140
+ "description": "An icon named by `label`.",
141
+ "path": "examples/confirm-button/idle.tsx",
142
+ "module": "@krizaka/ui/registry/examples/confirm-button/idle",
143
+ "code": "\"use client\";\n\nimport { ConfirmButton } from \"@krizaka/ui/confirm-button\";\n\nexport default function ConfirmButtonIdle() {\n return (\n <ConfirmButton label=\"Delete the comment\" confirmLabel=\"Delete?\" size=\"sm\" onConfirm={() => {}}>\n <svg viewBox=\"0 0 24 24\" className=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <path d=\"M3 6h18M8 6V4h8v2M19 6l-1 14H6L5 6\" />\n </svg>\n </ConfirmButton>\n );\n}\n"
144
+ },
145
+ {
146
+ "name": "armed",
147
+ "title": "Armed",
148
+ "description": "After the first press: the danger border and tint, the words legible.",
149
+ "path": "examples/confirm-button/armed.tsx",
150
+ "module": "@krizaka/ui/registry/examples/confirm-button/armed",
151
+ "code": "\"use client\";\n\nimport { ConfirmButton } from \"@krizaka/ui/confirm-button\";\n\n// Press once: it arms and says what will happen (`confirmLabel`); press again within `timeoutMs` to confirm.\nexport default function ConfirmButtonArmed() {\n return (\n <ConfirmButton label=\"Delete the comment\" confirmLabel=\"Delete?\" size=\"sm\" timeoutMs={600_000} onConfirm={() => {}}>\n <svg viewBox=\"0 0 24 24\" className=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <path d=\"M3 6h18M8 6V4h8v2M19 6l-1 14H6L5 6\" />\n </svg>\n </ConfirmButton>\n );\n}\n"
152
+ },
153
+ {
154
+ "name": "with-text",
155
+ "title": "With words",
156
+ "description": "Once armed, `armedContent` replaces the words.",
157
+ "path": "examples/confirm-button/with-text.tsx",
158
+ "module": "@krizaka/ui/registry/examples/confirm-button/with-text",
159
+ "code": "\"use client\";\n\nimport { ConfirmButton } from \"@krizaka/ui/confirm-button\";\n\n// With words: once armed, `armedContent` replaces them.\nexport default function ConfirmButtonWithText() {\n return (\n <ConfirmButton variant=\"outline\" confirmLabel=\"Leave for good?\" armedContent=\"Leave for good?\" onConfirm={() => {}}>\n Leave the group\n </ConfirmButton>\n );\n}\n"
160
+ }
161
+ ]
162
+ },
163
+ "native": null,
5
164
  "files": [
6
165
  {
7
166
  "path": "confirm-button/confirm-button.tsx",
@@ -10,6 +169,14 @@
10
169
  {
11
170
  "path": "confirm-button/index.ts",
12
171
  "content": "/** @krizaka/ui/confirm-button — `ConfirmButton` (two steps: arm, then confirm). Client (\"use client\"). */\nexport { confirmArmed, ConfirmButton, type ConfirmButtonProps } from \"./confirm-button\";\n"
172
+ },
173
+ {
174
+ "path": "confirm-button/meta.ts",
175
+ "content": "import type { ComponentMeta } from \"../meta\";\n\nexport const meta = {\n title: \"Confirm button\",\n summary: \"A destructive action in two presses: the first arms it and says what will happen, the second runs it.\",\n status: \"beta\",\n category: \"actions\",\n platforms: \"web\",\n whenToUse: [\n \"For a destructive action on one item, in place: delete a comment, remove a member, leave a group.\",\n \"When a dialog would be too heavy and an undo is not possible.\",\n ],\n whenNotToUse: [\n { when: \"When the consequences need explaining, or several things are affected.\", use: \"dialog\" },\n { when: \"For an action that is not destructive.\", use: \"button\" },\n { when: \"When the action can be undone: run it at once and offer “Undo” in a toast.\", use: \"toast\" },\n ],\n bestPractices: [\n \"`confirmLabel` says the consequence as a question: “Delete for good?”.\",\n \"Keep `timeoutMs` short (4 s by default): an armed button left on screen is a trap.\",\n \"Never use `window.confirm` for this.\",\n ],\n accessibility: {\n keyboard: [\n { keys: \"Enter / Space\", action: \"Arms, then confirms.\" },\n { keys: \"Esc\", action: \"Disarms; so does moving the focus away.\" },\n ],\n notes: [\n \"Once armed, `confirmLabel` names the button and is announced politely.\",\n \"An icon-only confirm button needs `label` while idle.\",\n \"The armed state is `data-armed`: style it with the danger tint, the words stay a text role.\",\n ],\n },\n related: [\"button\", \"dialog\", \"toast\"],\n web: {\n imports: [\"ConfirmButton\"],\n examples: [\n { name: \"idle\", title: \"Icon, idle\", description: \"An icon named by `label`.\" },\n { name: \"armed\", title: \"Armed\", description: \"After the first press: the danger border and tint, the words legible.\" },\n { name: \"with-text\", title: \"With words\", description: \"Once armed, `armedContent` replaces the words.\" },\n ],\n },\n} satisfies ComponentMeta;\n"
176
+ },
177
+ {
178
+ "path": "meta.ts",
179
+ "content": "// The documentation of a component, carried by its code: each primitive has a `meta.ts` beside its source\n// (`src/<name>/meta.ts`; a component that exists only in React Native: `src/native/meta/<name>.ts`). Never built into\n// the package: `scripts/build-registry.mjs` reads them into `registry/<name>.json`, which krizaka.com renders as\n// /docs/ui/<name>, and `scripts/registry.test.mjs` fails when one is missing or incomplete.\n//\n// Why a typed module and not JSDoc tags: the fields are lists and links (`related`, `whenNotToUse[].use`, examples),\n// which a type checks and a comment does not; the file is plain data (erasable TypeScript), so Node reads it without a\n// compiler, and an editor completes it.\n\n/** Every documented component: the web primitives (one entry of the package each) and the native-only ones. */\nexport type ComponentName =\n | \"alert\"\n | \"avatar\"\n | \"badge\"\n | \"button\"\n | \"card\"\n | \"checkbox\"\n | \"chip\"\n | \"cn\"\n | \"command\"\n | \"confirm-button\"\n | \"countdown\"\n | \"dialog\"\n | \"dropdown-menu\"\n | \"empty-state\"\n | \"field\"\n | \"kbd\"\n | \"page-header\"\n | \"popover\"\n | \"progress\"\n | \"radio-group\"\n | \"section-backdrop\"\n | \"segmented\"\n | \"separator\"\n | \"skeleton\"\n | \"slider\"\n | \"slot\"\n | \"spinner\"\n | \"stat\"\n | \"switch\"\n | \"tabs\"\n | \"theme\"\n | \"toast\"\n | \"tooltip\"\n | \"txt\";\n\n/** Where a component exists: `@krizaka/ui/<name>` (web), `@krizaka/ui/native` (React Native), or both. */\nexport type Platform = \"web\" | \"native\" | \"both\";\n\n/** `stable`: its API only changes in a major. `beta`: it may still change in a minor. */\nexport type Status = \"stable\" | \"beta\";\n\n/** The group of the catalogue. */\nexport type Category = \"actions\" | \"forms\" | \"navigation\" | \"overlays\" | \"feedback\" | \"data-display\" | \"layout\" | \"foundations\";\n\n/**\n * A named example: the file `registry/examples/<component>/<name>.tsx` (web) or\n * `registry/examples/<component>/native/<name>.tsx` (React Native) — at most 40 lines, imported by the stories and\n * shown (live, with its code) by the documentation.\n */\nexport interface Example {\n /** The file name, kebab-case (`primary`, `icon-button`). */\n readonly name: string;\n /** A short title (`Primary`, `Icon button`). */\n readonly title: string;\n /** One or two sentences: when this variant is the right one. */\n readonly description: string;\n}\n\n/** One platform's side of a component. */\nexport interface PlatformDocs {\n /** The names to import (`[\"Button\", \"IconButton\"]`): from `@krizaka/ui/<name>` on the web, `@krizaka/ui/native` in React Native. */\n readonly imports: readonly string[];\n /** The examples, in reading order; the first one is the component's preview. */\n readonly examples: readonly Example[];\n}\n\n/** The React Native side: the same concept, and what differs from the web API. */\nexport interface NativeDocs extends PlatformDocs {\n /** What differs from the web API (`label` instead of children…); empty for a native-only component. */\n readonly differences: readonly string[];\n}\n\nexport interface KeyboardInteraction {\n /** The keys, as written on a keyboard: `Space`, `Enter`, `Arrow keys`, `Esc`, `Tab`. */\n readonly keys: string;\n /** What they do. */\n readonly action: string;\n}\n\nexport interface ComponentMeta {\n /** The display name: `Button`, `Dropdown menu`. */\n readonly title: string;\n /** One sentence: what it is. */\n readonly summary: string;\n readonly status: Status;\n readonly category: Category;\n /** Must match the sides below: `both` ⇔ `web` and `native`. */\n readonly platforms: Platform;\n /** When to reach for it: concrete situations, one per item. */\n readonly whenToUse: readonly string[];\n /** When not to — and what to use instead (`use`), when another component is the answer. */\n readonly whenNotToUse: readonly { readonly when: string; readonly use?: ComponentName }[];\n /** How to use it well: wording, placement, composition. */\n readonly bestPractices: readonly string[];\n readonly accessibility: {\n /** The keyboard, when it does more than Tab and Enter. */\n readonly keyboard: readonly KeyboardInteraction[];\n /** Roles, names and announcements: what the component does, what the app must provide. */\n readonly notes: readonly string[];\n };\n /** The components a reader of this page should know about. */\n readonly related: readonly ComponentName[];\n readonly web?: PlatformDocs;\n readonly native?: NativeDocs;\n}\n"
13
180
  }
14
181
  ],
15
182
  "dependencies": [
@@ -20,8 +187,8 @@
20
187
  "cn"
21
188
  ],
22
189
  "demo": {
23
- "path": "demos/confirm-button.tsx",
24
- "content": "\"use client\";\n\nimport { ConfirmButton } from \"@krizaka/ui/confirm-button\";\n\nexport default function ConfirmButtonDemo() {\n return (\n <ConfirmButton label=\"Delete the comment\" confirmLabel=\"Delete?\" size=\"sm\" onConfirm={() => {}}>\n <svg viewBox=\"0 0 24 24\" className=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <path d=\"M3 6h18M8 6V4h8v2M19 6l-1 14H6L5 6\" />\n </svg>\n </ConfirmButton>\n );\n}\n"
190
+ "path": "examples/confirm-button/idle.tsx",
191
+ "content": "\"use client\";\n\nimport { ConfirmButton } from \"@krizaka/ui/confirm-button\";\n\nexport default function ConfirmButtonIdle() {\n return (\n <ConfirmButton label=\"Delete the comment\" confirmLabel=\"Delete?\" size=\"sm\" onConfirm={() => {}}>\n <svg viewBox=\"0 0 24 24\" className=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <path d=\"M3 6h18M8 6V4h8v2M19 6l-1 14H6L5 6\" />\n </svg>\n </ConfirmButton>\n );\n}\n"
25
192
  },
26
193
  "props": [
27
194
  {
@@ -93,9 +260,9 @@
93
260
  },
94
261
  {
95
262
  "name": "variant",
96
- "type": "\"danger\" | \"primary\" | \"secondary\" | \"outline\" | \"ghost\"",
263
+ "type": "\"danger\" | \"primary\" | \"gradient\" | \"secondary\" | \"outline\" | \"ghost\"",
97
264
  "default": "ghost",
98
- "description": "The look: `primary` (the accent), `secondary` (a raised surface), `outline`, `ghost`, `danger`.",
265
+ "description": "The look: `primary` (the accent), `gradient` (accent → accent-2), `secondary` (a raised surface), `outline`,\n`ghost`, `danger`.",
99
266
  "required": false
100
267
  }
101
268
  ]