@krizaka/ui 3.21.0 → 3.23.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 (494) hide show
  1. package/README.md +5 -0
  2. package/dist/achievement.js +1 -1
  3. package/dist/action-bar.js +4 -4
  4. package/dist/app-header.d.ts +79 -0
  5. package/dist/app-header.js +32 -0
  6. package/dist/app-header.js.map +1 -0
  7. package/dist/app-shell.d.ts +20 -2
  8. package/dist/app-shell.js +35 -20
  9. package/dist/app-shell.js.map +1 -1
  10. package/dist/argument-card.d.ts +4 -1
  11. package/dist/argument-card.js +8 -5
  12. package/dist/argument-card.js.map +1 -1
  13. package/dist/audio-player.d.ts +3 -2
  14. package/dist/audio-player.js +14 -10
  15. package/dist/audio-player.js.map +1 -1
  16. package/dist/blocks.css +28 -0
  17. package/dist/button.js +2 -1
  18. package/dist/captcha.d.ts +81 -0
  19. package/dist/captcha.js +162 -0
  20. package/dist/captcha.js.map +1 -0
  21. package/dist/card-grid.d.ts +10 -1
  22. package/dist/card-grid.js +3 -2
  23. package/dist/card-grid.js.map +1 -1
  24. package/dist/card.js +3 -3
  25. package/dist/changelog-page.d.ts +57 -3
  26. package/dist/changelog-page.js +117 -1
  27. package/dist/changelog-page.js.map +1 -1
  28. package/dist/choice-grid.js +1 -1
  29. package/dist/{chunk-5MH64NIL.js → chunk-2L67YTNV.js} +2 -2
  30. package/dist/{chunk-3IN6TOPM.js → chunk-6ZYRUOTA.js} +6 -3
  31. package/dist/chunk-6ZYRUOTA.js.map +1 -0
  32. package/dist/chunk-APNIVNIX.js +54 -0
  33. package/dist/chunk-APNIVNIX.js.map +1 -0
  34. package/dist/{chunk-FKBHWS4N.js → chunk-CEJDH6SA.js} +2 -2
  35. package/dist/{chunk-OWC2LZD2.js → chunk-CHOJUCVE.js} +6 -3
  36. package/dist/chunk-CHOJUCVE.js.map +1 -0
  37. package/dist/{chunk-3BC4XQ6C.js → chunk-DZU6RMYD.js} +6 -3
  38. package/dist/chunk-DZU6RMYD.js.map +1 -0
  39. package/dist/chunk-F7FVPPBB.js +1080 -0
  40. package/dist/chunk-F7FVPPBB.js.map +1 -0
  41. package/dist/{chunk-5Z7FWCV2.js → chunk-HBZPJ3EP.js} +2 -2
  42. package/dist/{chunk-C2BRIFJG.js → chunk-HJFRHYCI.js} +2 -2
  43. package/dist/{chunk-ZNMFG62E.js → chunk-KH3JOEPY.js} +3 -2
  44. package/dist/chunk-KH3JOEPY.js.map +1 -0
  45. package/dist/{chunk-BTMFZ66D.js → chunk-KM6VAKIE.js} +2 -2
  46. package/dist/{chunk-DGQMDJXK.js → chunk-LZNZLCOE.js} +2 -2
  47. package/dist/chunk-MQPC3P4T.js +126 -0
  48. package/dist/chunk-MQPC3P4T.js.map +1 -0
  49. package/dist/{chunk-2FRWNSRO.js → chunk-NSLXEDIS.js} +3 -2
  50. package/dist/chunk-NSLXEDIS.js.map +1 -0
  51. package/dist/{chunk-3GODX3D6.js → chunk-QDXV544C.js} +2 -2
  52. package/dist/chunk-QDXV544C.js.map +1 -0
  53. package/dist/{chunk-4LOMIQVX.js → chunk-W675RFOA.js} +3 -2
  54. package/dist/chunk-W675RFOA.js.map +1 -0
  55. package/dist/{chunk-G3ETON2A.js → chunk-WU4VLSEA.js} +3 -2
  56. package/dist/chunk-WU4VLSEA.js.map +1 -0
  57. package/dist/{chunk-IZ7MV6HM.js → chunk-XVFQZ3ZG.js} +3 -2
  58. package/dist/chunk-XVFQZ3ZG.js.map +1 -0
  59. package/dist/{chunk-LIPK4UCS.js → chunk-YCIBJ6OQ.js} +140 -209
  60. package/dist/chunk-YCIBJ6OQ.js.map +1 -0
  61. package/dist/cn.js +1 -1
  62. package/dist/code-block.js +2 -2
  63. package/dist/code-block.js.map +1 -1
  64. package/dist/command.js +3 -3
  65. package/dist/comparison-table.d.ts +44 -0
  66. package/dist/comparison-table.js +84 -0
  67. package/dist/comparison-table.js.map +1 -0
  68. package/dist/confirm-button.js +2 -2
  69. package/dist/continue-prompt.js +3 -3
  70. package/dist/continue-prompt.js.map +1 -1
  71. package/dist/cta-panel.js +1 -1
  72. package/dist/data-table.js +19 -1066
  73. package/dist/data-table.js.map +1 -1
  74. package/dist/date-picker.js +4 -4
  75. package/dist/decision-list.js +1 -1
  76. package/dist/dialog.js +3 -2
  77. package/dist/dialog.js.map +1 -1
  78. package/dist/docs-nav.d.ts +36 -0
  79. package/dist/docs-nav.js +44 -0
  80. package/dist/docs-nav.js.map +1 -0
  81. package/dist/dropdown-menu.js +1 -1
  82. package/dist/error-page.js +1 -1
  83. package/dist/field.js +1 -1
  84. package/dist/filter-bar.js +2 -2
  85. package/dist/force-update-screen.js +2 -1
  86. package/dist/force-update-screen.js.map +1 -1
  87. package/dist/gallery-page.js +1 -1
  88. package/dist/genui.d.ts +221 -0
  89. package/dist/genui.js +533 -0
  90. package/dist/genui.js.map +1 -0
  91. package/dist/glow-card.js +1 -1
  92. package/dist/goal-gauge.js +1 -1
  93. package/dist/how-it-works-page.js +1 -1
  94. package/dist/image-cropper.js +3 -3
  95. package/dist/index.d.ts +17 -24
  96. package/dist/index.js +4 -4
  97. package/dist/landscape.js +1 -1
  98. package/dist/link-card.d.ts +9 -2
  99. package/dist/link-card.js +5 -44
  100. package/dist/link-card.js.map +1 -1
  101. package/dist/longform-page.js +1 -1
  102. package/dist/maintenance-screen.js +2 -1
  103. package/dist/maintenance-screen.js.map +1 -1
  104. package/dist/map.js +3 -3
  105. package/dist/map.js.map +1 -1
  106. package/dist/markdown.js +2 -1
  107. package/dist/markdown.js.map +1 -1
  108. package/dist/marketing-layout.js +1 -1
  109. package/dist/marketing-layout.js.map +1 -1
  110. package/dist/marquee.js +1 -1
  111. package/dist/mascot-quote.js +1 -1
  112. package/dist/match-dialog.js +2 -1
  113. package/dist/match-dialog.js.map +1 -1
  114. package/dist/media-grid.d.ts +26 -4
  115. package/dist/media-grid.js +122 -163
  116. package/dist/media-grid.js.map +1 -1
  117. package/dist/meta-row.d.ts +54 -0
  118. package/dist/meta-row.js +35 -0
  119. package/dist/meta-row.js.map +1 -0
  120. package/dist/native/map.js +3 -3
  121. package/dist/native/map.js.map +1 -1
  122. package/dist/native.d.ts +42 -16
  123. package/dist/native.js +591 -537
  124. package/dist/native.js.map +1 -1
  125. package/dist/nav-bar.js +3 -3
  126. package/dist/page-hero.js +5 -5
  127. package/dist/page.js +2 -2
  128. package/dist/popover.js +1 -1
  129. package/dist/pricing-page.js +1 -1
  130. package/dist/product-page.js +1 -1
  131. package/dist/profile-card.js +1 -1
  132. package/dist/promise-card.js +1 -1
  133. package/dist/radio-group.js +2 -2
  134. package/dist/rail-nav.d.ts +149 -0
  135. package/dist/rail-nav.js +177 -0
  136. package/dist/rail-nav.js.map +1 -0
  137. package/dist/scroll-stage.js +1 -1
  138. package/dist/settings-layout.d.ts +75 -62
  139. package/dist/settings-layout.js +39 -6
  140. package/dist/settings-layout.js.map +1 -1
  141. package/dist/showcase.js +1 -1
  142. package/dist/site-footer.d.ts +48 -67
  143. package/dist/site-footer.js +36 -12
  144. package/dist/site-footer.js.map +1 -1
  145. package/dist/skip-link.js +1 -1
  146. package/dist/slider.js +2 -2
  147. package/dist/stage-banner.js +1 -1
  148. package/dist/step-showcase.d.ts +62 -0
  149. package/dist/step-showcase.js +227 -0
  150. package/dist/step-showcase.js.map +1 -0
  151. package/dist/tabs.js +1 -1
  152. package/dist/tabs.js.map +1 -1
  153. package/dist/terminal-replay.js +1 -1
  154. package/dist/theme.js +2 -1
  155. package/dist/theme.js.map +1 -1
  156. package/dist/toast.js +1 -1
  157. package/dist/toc.js +1 -1
  158. package/dist/tooltip.js +1 -1
  159. package/dist/update-prompt.js +2 -1
  160. package/dist/update-prompt.js.map +1 -1
  161. package/dist/vertical-video.js +2 -2
  162. package/dist/video-player.js +3 -3
  163. package/dist/waveform.d.ts +93 -0
  164. package/dist/waveform.js +95 -0
  165. package/dist/waveform.js.map +1 -0
  166. package/package.json +138 -10
  167. package/registry/achievement.json +1 -1
  168. package/registry/action-bar.json +1 -1
  169. package/registry/activity-feed.json +1 -1
  170. package/registry/alert.json +1 -1
  171. package/registry/app-header.json +202 -0
  172. package/registry/app-shell.json +33 -9
  173. package/registry/argument-card.json +37 -5
  174. package/registry/audio-player.json +5 -3
  175. package/registry/auth-layout.json +1 -1
  176. package/registry/avatar.json +1 -1
  177. package/registry/badge.json +1 -1
  178. package/registry/button.json +3 -2
  179. package/registry/captcha.json +300 -0
  180. package/registry/card-grid.json +27 -3
  181. package/registry/card.json +1 -1
  182. package/registry/catalogue-page.json +1 -1
  183. package/registry/changelog-page.json +11 -7
  184. package/registry/chat.json +1 -1
  185. package/registry/checkbox.json +1 -1
  186. package/registry/chip-link.json +1 -1
  187. package/registry/chip.json +1 -1
  188. package/registry/choice-grid.json +1 -1
  189. package/registry/cn.json +1 -1
  190. package/registry/code-block.json +1 -1
  191. package/registry/combobox.json +1 -1
  192. package/registry/command.json +1 -1
  193. package/registry/comparison-table.json +207 -0
  194. package/registry/component-page.json +1 -1
  195. package/registry/confirm-button.json +1 -1
  196. package/registry/contact-page.json +1 -1
  197. package/registry/continue-prompt.json +1 -1
  198. package/registry/countdown.json +1 -1
  199. package/registry/cta-panel.json +1 -1
  200. package/registry/dashboard-layout.json +1 -1
  201. package/registry/data-table.json +1 -1
  202. package/registry/date-picker.json +1 -1
  203. package/registry/decision-list.json +1 -1
  204. package/registry/description-list.json +1 -1
  205. package/registry/detail-layout.json +1 -1
  206. package/registry/dialog.json +1 -1
  207. package/registry/docs-article-page.json +1 -1
  208. package/registry/docs-hub-page.json +1 -1
  209. package/registry/docs-layout.json +1 -1
  210. package/registry/docs-nav.json +177 -0
  211. package/registry/document-viewer.json +1 -1
  212. package/registry/dropdown-menu.json +1 -1
  213. package/registry/empty-state.json +1 -1
  214. package/registry/error-page.json +1 -1
  215. package/registry/examples/activity-feed/native/notifications.light.png +0 -0
  216. package/registry/examples/app-header/basic.d.ts +4 -0
  217. package/registry/examples/app-header/basic.js +23 -0
  218. package/registry/examples/app-header/basic.tsx +17 -0
  219. package/registry/examples/app-shell/desktop.d.ts +4 -0
  220. package/registry/examples/app-shell/desktop.js +41 -0
  221. package/registry/examples/app-shell/desktop.tsx +37 -0
  222. package/registry/examples/argument-card/hover-light.d.ts +4 -0
  223. package/registry/examples/argument-card/hover-light.js +17 -0
  224. package/registry/examples/argument-card/hover-light.tsx +19 -0
  225. package/registry/examples/argument-card/hover-quiet.d.ts +4 -0
  226. package/registry/examples/argument-card/hover-quiet.js +17 -0
  227. package/registry/examples/argument-card/hover-quiet.tsx +19 -0
  228. package/registry/examples/avatar/native/group.light.png +0 -0
  229. package/registry/examples/avatar/native/presence.light.png +0 -0
  230. package/registry/examples/avatar/native/sizes.light.png +0 -0
  231. package/registry/examples/badge/native/tones.light.png +0 -0
  232. package/registry/examples/button/native/ghost.light.png +0 -0
  233. package/registry/examples/captcha/disclosure.d.ts +4 -0
  234. package/registry/examples/captcha/disclosure.js +14 -0
  235. package/registry/examples/captcha/disclosure.tsx +11 -0
  236. package/registry/examples/captcha/form.d.ts +4 -0
  237. package/registry/examples/captcha/form.js +18 -0
  238. package/registry/examples/captcha/form.tsx +17 -0
  239. package/registry/examples/card/native/body.light.png +0 -0
  240. package/registry/examples/card/native/default.light.png +0 -0
  241. package/registry/examples/card/native/elevated.light.png +0 -0
  242. package/registry/examples/card/native/pressable.light.png +0 -0
  243. package/registry/examples/card-grid/hover-quiet.d.ts +4 -0
  244. package/registry/examples/card-grid/hover-quiet.js +18 -0
  245. package/registry/examples/card-grid/hover-quiet.tsx +20 -0
  246. package/registry/examples/changelog-page/releases.js +1 -1
  247. package/registry/examples/changelog-page/releases.tsx +1 -1
  248. package/registry/examples/chat/native/conversation.light.png +0 -0
  249. package/registry/examples/chat/native/inbox.light.png +0 -0
  250. package/registry/examples/chip/native/multiple.light.png +0 -0
  251. package/registry/examples/chip/native/removable.light.png +0 -0
  252. package/registry/examples/chip/native/single.light.png +0 -0
  253. package/registry/examples/chip/native/toggle.light.png +0 -0
  254. package/registry/examples/combobox/native/multiple.light.png +0 -0
  255. package/registry/examples/combobox/native/search.light.png +0 -0
  256. package/registry/examples/comparison-table/versus.d.ts +4 -0
  257. package/registry/examples/comparison-table/versus.js +28 -0
  258. package/registry/examples/comparison-table/versus.tsx +20 -0
  259. package/registry/examples/countdown/native/days.light.png +0 -0
  260. package/registry/examples/countdown/native/hours.light.png +0 -0
  261. package/registry/examples/countdown/native/sizes.light.png +0 -0
  262. package/registry/examples/countdown/native/urgent.light.png +0 -0
  263. package/registry/examples/countdown/native/with-label.light.png +0 -0
  264. package/registry/examples/date-picker/native/birth-date-wheel.light.png +0 -0
  265. package/registry/examples/date-picker/native/birth-date.light.png +0 -0
  266. package/registry/examples/date-picker/native/calendar.dark.png +0 -0
  267. package/registry/examples/date-picker/native/calendar.light.png +0 -0
  268. package/registry/examples/date-picker/native/day-strip.dark.png +0 -0
  269. package/registry/examples/date-picker/native/day-strip.light.png +0 -0
  270. package/registry/examples/date-picker/native/time-slots.dark.png +0 -0
  271. package/registry/examples/date-picker/native/time-slots.light.png +0 -0
  272. package/registry/examples/date-picker/native/time-wheel.light.png +0 -0
  273. package/registry/examples/description-list/native/job-details.light.png +0 -0
  274. package/registry/examples/dialog/native/sheet.dark.png +0 -0
  275. package/registry/examples/dialog/native/sheet.light.png +0 -0
  276. package/registry/examples/docs-nav/groups.d.ts +4 -0
  277. package/registry/examples/docs-nav/groups.js +21 -0
  278. package/registry/examples/docs-nav/groups.tsx +15 -0
  279. package/registry/examples/empty-state/native/default.light.png +0 -0
  280. package/registry/examples/field/native/default.light.png +0 -0
  281. package/registry/examples/field/native/select.light.png +0 -0
  282. package/registry/examples/force-update-screen/native/default.light.png +0 -0
  283. package/registry/examples/form/native/amount.light.png +0 -0
  284. package/registry/examples/form/native/audience.light.png +0 -0
  285. package/registry/examples/form/native/profile.light.png +0 -0
  286. package/registry/examples/form/native/settings.light.png +0 -0
  287. package/registry/examples/form/native/sign-up.light.png +0 -0
  288. package/registry/examples/form/native/upload.dark.png +0 -0
  289. package/registry/examples/form/native/upload.light.png +0 -0
  290. package/registry/examples/genui/streaming.d.ts +4 -0
  291. package/registry/examples/genui/streaming.js +18 -0
  292. package/registry/examples/genui/streaming.tsx +14 -0
  293. package/registry/examples/genui/table.d.ts +4 -0
  294. package/registry/examples/genui/table.js +19 -0
  295. package/registry/examples/genui/table.tsx +14 -0
  296. package/registry/examples/goal-gauge/native/default.light.png +0 -0
  297. package/registry/examples/header/native/large-title.light.png +0 -0
  298. package/registry/examples/link-card/hover-light.d.ts +4 -0
  299. package/registry/examples/link-card/hover-light.js +18 -0
  300. package/registry/examples/link-card/hover-light.tsx +20 -0
  301. package/registry/examples/link-card/hover-quiet.d.ts +4 -0
  302. package/registry/examples/link-card/hover-quiet.js +18 -0
  303. package/registry/examples/link-card/hover-quiet.tsx +20 -0
  304. package/registry/examples/loader/native/job-wait.light.png +0 -0
  305. package/registry/examples/maintenance-screen/native/default.light.png +0 -0
  306. package/registry/examples/map/native/places.light.png +0 -0
  307. package/registry/examples/markdown/native/basic.light.png +0 -0
  308. package/registry/examples/mascot-state/native/default.light.png +0 -0
  309. package/registry/examples/media-picker/native/story.light.png +0 -0
  310. package/registry/examples/meta-row/native/video.d.ts +4 -0
  311. package/registry/examples/meta-row/native/video.dark.png +0 -0
  312. package/registry/examples/meta-row/native/video.js +11 -0
  313. package/registry/examples/meta-row/native/video.light.png +0 -0
  314. package/registry/examples/meta-row/native/video.tsx +5 -0
  315. package/registry/examples/meta-row/status.d.ts +4 -0
  316. package/registry/examples/meta-row/status.js +12 -0
  317. package/registry/examples/meta-row/status.tsx +7 -0
  318. package/registry/examples/meta-row/video.d.ts +4 -0
  319. package/registry/examples/meta-row/video.js +12 -0
  320. package/registry/examples/meta-row/video.tsx +7 -0
  321. package/registry/examples/meter/native/credits.light.png +0 -0
  322. package/registry/examples/meter/native/split-ring.light.png +0 -0
  323. package/registry/examples/number-ticker/native/balance.light.png +0 -0
  324. package/registry/examples/onboarding/native/first-launch.light.png +0 -0
  325. package/registry/examples/otp-input/native/verify.light.png +0 -0
  326. package/registry/examples/pagination/native/cursor.light.png +0 -0
  327. package/registry/examples/pagination/native/pages.light.png +0 -0
  328. package/registry/examples/permission-prompt/native/blocked.light.png +0 -0
  329. package/registry/examples/permission-prompt/native/camera.light.png +0 -0
  330. package/registry/examples/profile-card/native/default.light.png +0 -0
  331. package/registry/examples/radio-group/native/buttons.light.png +0 -0
  332. package/registry/examples/radio-group/native/cards.light.png +0 -0
  333. package/registry/examples/radio-group/native/list.light.png +0 -0
  334. package/registry/examples/radio-group/native/segmented.light.png +0 -0
  335. package/registry/examples/rail-nav/expandable.d.ts +4 -0
  336. package/registry/examples/rail-nav/expandable.js +34 -0
  337. package/registry/examples/rail-nav/expandable.tsx +28 -0
  338. package/registry/examples/rail-nav/studio.d.ts +4 -0
  339. package/registry/examples/rail-nav/studio.js +43 -0
  340. package/registry/examples/rail-nav/studio.tsx +38 -0
  341. package/registry/examples/screen/native/app-shell.light.png +0 -0
  342. package/registry/examples/screen/native/auth.light.png +0 -0
  343. package/registry/examples/screen/native/map.light.png +0 -0
  344. package/registry/examples/screen/native/notifications.light.png +0 -0
  345. package/registry/examples/screen/native/profile.light.png +0 -0
  346. package/registry/examples/segmented/native/default.light.png +0 -0
  347. package/registry/examples/segmented/native/small.light.png +0 -0
  348. package/registry/examples/settings-layout/flat.d.ts +4 -0
  349. package/registry/examples/settings-layout/flat.js +26 -0
  350. package/registry/examples/settings-layout/flat.tsx +30 -0
  351. package/registry/examples/showcase/native/slides.light.png +0 -0
  352. package/registry/examples/site-footer/app.d.ts +4 -0
  353. package/registry/examples/site-footer/app.js +25 -0
  354. package/registry/examples/site-footer/app.tsx +22 -0
  355. package/registry/examples/site-footer/docs.d.ts +4 -0
  356. package/registry/examples/site-footer/docs.js +31 -0
  357. package/registry/examples/site-footer/docs.tsx +24 -0
  358. package/registry/examples/slider/native/default.light.png +0 -0
  359. package/registry/examples/slider/native/stepped.light.png +0 -0
  360. package/registry/examples/step-progress/native/sign-up.light.png +0 -0
  361. package/registry/examples/step-showcase/desktop.d.ts +4 -0
  362. package/registry/examples/step-showcase/desktop.js +24 -0
  363. package/registry/examples/step-showcase/desktop.tsx +19 -0
  364. package/registry/examples/step-showcase/phone.d.ts +4 -0
  365. package/registry/examples/step-showcase/phone.js +24 -0
  366. package/registry/examples/step-showcase/phone.tsx +19 -0
  367. package/registry/examples/stepper/native/run.light.png +0 -0
  368. package/registry/examples/swipeable-row/native/conversation.light.png +0 -0
  369. package/registry/examples/switch/native/settings.light.png +0 -0
  370. package/registry/examples/tab-bar/native/main-sections.light.png +0 -0
  371. package/registry/examples/tabs/native/sections.light.png +0 -0
  372. package/registry/examples/tabs/native/segmented.light.png +0 -0
  373. package/registry/examples/tag-selector/native/interests.light.png +0 -0
  374. package/registry/examples/toast/native/tones.light.png +0 -0
  375. package/registry/examples/txt/native/tones.dark.png +0 -0
  376. package/registry/examples/txt/native/tones.light.png +0 -0
  377. package/registry/examples/update-prompt/native/default.light.png +0 -0
  378. package/registry/examples/waveform/card.d.ts +4 -0
  379. package/registry/examples/waveform/card.js +18 -0
  380. package/registry/examples/waveform/card.tsx +16 -0
  381. package/registry/examples/waveform/native/card.d.ts +4 -0
  382. package/registry/examples/waveform/native/card.dark.png +0 -0
  383. package/registry/examples/waveform/native/card.js +19 -0
  384. package/registry/examples/waveform/native/card.light.png +0 -0
  385. package/registry/examples/waveform/native/card.tsx +19 -0
  386. package/registry/examples/waveform/sizes.d.ts +4 -0
  387. package/registry/examples/waveform/sizes.js +16 -0
  388. package/registry/examples/waveform/sizes.tsx +14 -0
  389. package/registry/field.json +1 -1
  390. package/registry/file-upload.json +1 -1
  391. package/registry/filter-bar.json +1 -1
  392. package/registry/force-update-screen.json +1 -1
  393. package/registry/form.json +1 -1
  394. package/registry/gallery-page.json +1 -1
  395. package/registry/genui.json +409 -0
  396. package/registry/glow-card.json +1 -1
  397. package/registry/goal-gauge.json +1 -1
  398. package/registry/how-it-works-page.json +1 -1
  399. package/registry/image-cropper.json +1 -1
  400. package/registry/index.json +323 -14
  401. package/registry/iso.json +1 -1
  402. package/registry/kanban.json +1 -1
  403. package/registry/kbd.json +1 -1
  404. package/registry/landing-page.json +1 -1
  405. package/registry/landscape.json +1 -1
  406. package/registry/legal-page.json +1 -1
  407. package/registry/link-card.json +38 -6
  408. package/registry/list.json +1 -1
  409. package/registry/loader.json +1 -1
  410. package/registry/longform-page.json +1 -1
  411. package/registry/maintenance-screen.json +1 -1
  412. package/registry/map.json +2 -2
  413. package/registry/markdown.json +1 -1
  414. package/registry/marketing-layout.json +1 -1
  415. package/registry/marquee.json +1 -1
  416. package/registry/mascot-quote.json +1 -1
  417. package/registry/mascot-state.json +1 -1
  418. package/registry/mascots.json +1 -1
  419. package/registry/match-dialog.json +1 -1
  420. package/registry/media-capture.json +1 -1
  421. package/registry/media-grid.json +92 -6
  422. package/registry/meta-row.json +215 -0
  423. package/registry/meter.json +1 -1
  424. package/registry/nav-bar.json +13 -13
  425. package/registry/number-ticker.json +1 -1
  426. package/registry/page-header.json +1 -1
  427. package/registry/page-hero.json +1 -1
  428. package/registry/page.json +1 -1
  429. package/registry/pagination.json +1 -1
  430. package/registry/photo-grid.json +1 -1
  431. package/registry/pointer-light.json +1 -1
  432. package/registry/popover.json +1 -1
  433. package/registry/pricing-page.json +1 -1
  434. package/registry/product-page.json +1 -1
  435. package/registry/profile-card.json +1 -1
  436. package/registry/progress.json +1 -1
  437. package/registry/promise-card.json +1 -1
  438. package/registry/radio-group.json +1 -1
  439. package/registry/rail-nav.json +493 -0
  440. package/registry/recipes.json +1 -1
  441. package/registry/scroll-stage.json +1 -1
  442. package/registry/search-field.json +1 -1
  443. package/registry/section-backdrop.json +1 -1
  444. package/registry/separator.json +1 -1
  445. package/registry/settings-layout.json +104 -9
  446. package/registry/showcase.json +1 -1
  447. package/registry/site-footer.json +49 -17
  448. package/registry/sites.json +1 -1
  449. package/registry/skeleton.json +1 -1
  450. package/registry/skip-link.json +2 -2
  451. package/registry/slider.json +1 -1
  452. package/registry/slot.json +1 -1
  453. package/registry/spinner.json +1 -1
  454. package/registry/split-view.json +1 -1
  455. package/registry/stage-banner.json +1 -1
  456. package/registry/stat.json +1 -1
  457. package/registry/status-page.json +1 -1
  458. package/registry/step-progress.json +1 -1
  459. package/registry/step-showcase.json +296 -0
  460. package/registry/stepper.json +1 -1
  461. package/registry/swipe-deck.json +1 -1
  462. package/registry/switch.json +1 -1
  463. package/registry/tabs.json +2 -2
  464. package/registry/tag-input.json +1 -1
  465. package/registry/tag-selector.json +1 -1
  466. package/registry/terminal-replay.json +1 -1
  467. package/registry/theme.json +1 -1
  468. package/registry/toast.json +1 -1
  469. package/registry/toc.json +1 -1
  470. package/registry/tooltip.json +1 -1
  471. package/registry/tree-view.json +1 -1
  472. package/registry/update-prompt.json +1 -1
  473. package/registry/verified-badge.json +1 -1
  474. package/registry/vertical-video.json +1 -1
  475. package/registry/video-player.json +1 -1
  476. package/registry/video-trimmer.json +1 -1
  477. package/registry/virtual.json +1 -1
  478. package/registry/waveform.json +296 -0
  479. package/dist/chunk-2FRWNSRO.js.map +0 -1
  480. package/dist/chunk-3BC4XQ6C.js.map +0 -1
  481. package/dist/chunk-3GODX3D6.js.map +0 -1
  482. package/dist/chunk-3IN6TOPM.js.map +0 -1
  483. package/dist/chunk-4LOMIQVX.js.map +0 -1
  484. package/dist/chunk-G3ETON2A.js.map +0 -1
  485. package/dist/chunk-IZ7MV6HM.js.map +0 -1
  486. package/dist/chunk-LIPK4UCS.js.map +0 -1
  487. package/dist/chunk-OWC2LZD2.js.map +0 -1
  488. package/dist/chunk-ZNMFG62E.js.map +0 -1
  489. /package/dist/{chunk-5MH64NIL.js.map → chunk-2L67YTNV.js.map} +0 -0
  490. /package/dist/{chunk-FKBHWS4N.js.map → chunk-CEJDH6SA.js.map} +0 -0
  491. /package/dist/{chunk-5Z7FWCV2.js.map → chunk-HBZPJ3EP.js.map} +0 -0
  492. /package/dist/{chunk-C2BRIFJG.js.map → chunk-HJFRHYCI.js.map} +0 -0
  493. /package/dist/{chunk-BTMFZ66D.js.map → chunk-KM6VAKIE.js.map} +0 -0
  494. /package/dist/{chunk-DGQMDJXK.js.map → chunk-LZNZLCOE.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/markdown/markdown.tsx","../src/cn.ts","../src/markdown/parse.ts"],"sourcesContent":["// Server-safe (no hook, no context): a Markdown text rendered on the tokens, from TanStack Markdown's AST. Raw HTML is\n// never enabled (it is shown as text), executable URLs are dropped, links to another site carry `rel=\"noopener\n// noreferrer\"`, and every fenced block is a `CodeBlock` (the same grammars, the same colours). `streaming` is for a\n// text that arrives in pieces — an AI answer: the unfinished end is closed and a caret marks where it goes on.\nimport { CodeBlock } from \"@krizaka/ui/code-block\";\nimport * as React from \"react\";\n\nimport { cn } from \"../cn\";\nimport { type BlockNode, type InlineNode, parseSource, textOf } from \"./parse\";\n\nexport type MarkdownLinkProps = React.ComponentProps<\"a\">;\n\nexport type MarkdownProps = Omit<React.ComponentProps<\"div\">, \"children\"> & {\n /** The Markdown source. */\n children: string;\n /** The text is still arriving: the unfinished end is closed and a caret marks the end. */\n streaming?: boolean;\n /** Gives every heading an `id`, for `#section` links. */\n headingIds?: boolean;\n /** The words of the copy button of the code blocks, passed translated. Without them a code block has no copy button. */\n codeLabels?: { copy: string; copied: string };\n /** Your router's link (Next's `Link`) for the links that stay on the site (`/docs`, `#section`); the others are plain `a`. */\n linkAs?: React.ElementType<MarkdownLinkProps>;\n};\n\ntype Context = Pick<MarkdownProps, \"codeLabels\" | \"linkAs\">;\n\nconst external = (href: string) => /^[a-z][a-z0-9+.-]*:/i.test(href);\n\nfunction Inlines({ nodes, ctx }: { nodes: readonly InlineNode[]; ctx: Context }) {\n return nodes.map((node, i) => <Inline key={i} node={node} ctx={ctx} />);\n}\n\nfunction Inline({ node, ctx }: { node: InlineNode; ctx: Context }): React.ReactNode {\n switch (node.type) {\n case \"text\":\n return node.value;\n case \"inlineCode\":\n return <code>{node.value}</code>;\n case \"strong\":\n return (\n <strong>\n <Inlines nodes={node.children} ctx={ctx} />\n </strong>\n );\n case \"emphasis\":\n return (\n <em>\n <Inlines nodes={node.children} ctx={ctx} />\n </em>\n );\n case \"strike\":\n return (\n <del>\n <Inlines nodes={node.children} ctx={ctx} />\n </del>\n );\n case \"break\":\n return <br />;\n case \"link\": {\n const Link = external(node.href) ? \"a\" : (ctx.linkAs ?? \"a\");\n const props = external(node.href) && !node.href.startsWith(\"mailto:\") && !node.href.startsWith(\"tel:\") ? { rel: \"noopener noreferrer\" } : {};\n return (\n <Link href={node.href} title={node.title} {...props}>\n <Inlines nodes={node.children} ctx={ctx} />\n </Link>\n );\n }\n case \"image\":\n return <img src={node.src} alt={node.alt} title={node.title} loading=\"lazy\" />;\n case \"footnoteReference\":\n return (\n <sup>\n <a id={`kz-fnref-${node.id}`} href={`#kz-fn-${node.id}`} data-footnote-ref=\"\">\n {node.number}\n </a>\n </sup>\n );\n // Raw HTML is never enabled by the parser: it arrives as text. A node of this kind is shown as text too.\n case \"inlineHtml\":\n return node.value;\n default:\n return null;\n }\n}\n\nfunction Blocks({ nodes, ctx }: { nodes: readonly BlockNode[]; ctx: Context }) {\n return nodes.map((node, i) => <Block key={i} node={node} ctx={ctx} />);\n}\n\nfunction Block({ node, ctx }: { node: BlockNode; ctx: Context }): React.ReactNode {\n switch (node.type) {\n case \"heading\": {\n const Tag = `h${node.depth}` as const;\n return (\n <Tag id={node.id}>\n <Inlines nodes={node.children} ctx={ctx} />\n </Tag>\n );\n }\n case \"paragraph\":\n return (\n <p>\n <Inlines nodes={node.children} ctx={ctx} />\n </p>\n );\n case \"code\":\n return (\n <CodeBlock\n code={node.value}\n language={node.lang ?? \"text\"}\n file={node.title ?? node.file}\n copyLabel={ctx.codeLabels?.copy}\n copiedLabel={ctx.codeLabels?.copied}\n annotations={node.highlightLines?.map((line) => ({ lines: line, kind: \"highlight\" as const }))}\n />\n );\n case \"list\": {\n const Tag = node.ordered ? \"ol\" : \"ul\";\n const tasks = node.items.some((item) => item.checked !== undefined);\n return (\n <Tag start={node.ordered && node.start !== undefined && node.start !== 1 ? node.start : undefined} data-tasks={tasks ? \"\" : undefined}>\n {node.items.map((item, i) => (\n <li key={i}>\n {item.checked !== undefined ? (\n <label>\n <input type=\"checkbox\" checked={item.checked} disabled readOnly />{\" \"}\n <ListItem blocks={item.children} ctx={ctx} />\n </label>\n ) : (\n <ListItem blocks={item.children} ctx={ctx} />\n )}\n </li>\n ))}\n </Tag>\n );\n }\n case \"blockquote\":\n return (\n <blockquote>\n <Blocks nodes={node.children} ctx={ctx} />\n </blockquote>\n );\n case \"table\":\n return (\n <div className=\"kz-md-table\">\n <table>\n <thead>\n <tr>\n {node.header.map((cell, i) => (\n <th key={i} scope=\"col\" style={{ textAlign: node.align[i] ?? undefined }}>\n <Inlines nodes={cell.children} ctx={ctx} />\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {node.rows.map((row, r) => (\n <tr key={r}>\n {row.map((cell, i) => (\n <td key={i} style={{ textAlign: node.align[i] ?? undefined }}>\n <Inlines nodes={cell.children} ctx={ctx} />\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n case \"thematicBreak\":\n return <hr />;\n case \"footnotes\":\n return (\n <section data-footnotes=\"\">\n <ol>\n {node.items.map((item) => (\n <li key={item.id} id={`kz-fn-${item.id}`}>\n <Blocks nodes={item.children} ctx={ctx} />\n </li>\n ))}\n </ol>\n </section>\n );\n // Raw HTML (never enabled) arrives as a paragraph of text; extensions are not enabled either. Shown as text.\n case \"html\":\n return <p>{node.value}</p>;\n default:\n return null;\n }\n}\n\n/** A list item: a lone paragraph is inline (a tight list), anything else keeps its blocks. */\nfunction ListItem({ blocks, ctx }: { blocks: readonly BlockNode[]; ctx: Context }) {\n return blocks.map((block, i) => (block.type === \"paragraph\" && blocks.length === 1 ? <Inlines key={i} nodes={block.children} ctx={ctx} /> : <Block key={i} node={block} ctx={ctx} />));\n}\n\n/** A Markdown text on the tokens: headings, paragraphs, lists (and tasks), quotes, tables, code, links, images, footnotes. */\nexport function Markdown({ children, streaming, headingIds, codeLabels, linkAs, className, ...props }: MarkdownProps) {\n const blocks = parseSource(children, { streaming, headingIds });\n return (\n <div className={cn(\"kz-md\", className)} data-streaming={streaming ? \"\" : undefined} aria-busy={streaming || undefined} {...props}>\n <Blocks nodes={blocks} ctx={{ codeLabels, linkAs }} />\n </div>\n );\n}\n\nexport { textOf };\n","import { type ClassValue, clsx } from \"clsx\";\nimport { cnMerge, type TWMergeConfig } from \"tailwind-variants\";\n\nexport type { ClassValue };\n\n/**\n * The preset's own utilities, told to the merge engine: the material (BRAND.md §6: `bg-sheen`, `bg-fill-shade`,\n * `bg-halo` are background images; `shadow-raised` · `-floating` · `-overlay` · `-glow` are shadows; `inset-shadow-edge`\n * · `-edge-fill` · `-well` are inset shadows). Unknown, tailwind-merge would take `bg-sheen` for a colour and drop the\n * `bg-surface-2` it lies on.\n */\nexport const twMergeConfig: TWMergeConfig = {\n extend: {\n classGroups: {\n \"bg-image\": [\"bg-sheen\", \"bg-fill-shade\", \"bg-halo\"],\n shadow: [\"shadow-raised\", \"shadow-floating\", \"shadow-overlay\", \"shadow-glow\", \"shadow-glow-lg\"],\n \"inset-shadow\": [\"inset-shadow-edge\", \"inset-shadow-edge-fill\", \"inset-shadow-well\"],\n },\n },\n};\n\n/**\n * Merges Tailwind classes: the last one wins — a product's `className` overrides the primitive's. The merge engine is\n * tailwind-merge as tailwind-variants ships it (the one `tv` uses), so the platform carries a single copy of it.\n * tailwind-variants bundles that engine since 3.3 (it never imports the `tailwind-merge` package, an optional peer):\n * hence `tailwind-variants ^3.3.1` and no `tailwind-merge` dependency — `scripts/consumer.mjs` checks it on a clean\n * install of the packed package.\n */\nexport function cn(...inputs: ClassValue[]): string {\n return cnMerge(clsx(inputs))({ twMergeConfig }) ?? \"\";\n}\n","// The shared half of Markdown, web and React Native: the source becomes TanStack Markdown's serializable AST\n// (`@tanstack/markdown/parser`) — raw HTML is never enabled (it stays text), executable URLs are dropped (`javascript:`,\n// `data:`), and a text that is still arriving is healed so the half-written end reads like the finished one.\nimport type { BlockNode } from \"@tanstack/markdown\";\nimport { streamingMarkdownExtension } from \"@tanstack/markdown/extensions/streaming\";\nimport { parseMarkdown } from \"@tanstack/markdown/parser\";\n\nexport type { BlockNode, InlineNode, ListItemNode, TableNode } from \"@tanstack/markdown\";\n\nexport type ParseOptions = {\n /** The text is still arriving (an AI answer): the unfinished end is closed, so it never shows `**` or a half link. */\n streaming?: boolean;\n /** Gives every heading an `id` (`#section` links, a table of contents). */\n headingIds?: boolean;\n};\n\nconst FENCE = /^ {0,3}(```|~~~)/gm;\n\n/** A link or image cut at its end: `[label`, `[label]`, `[label](http…` become `label`, an image is dropped. Linear: one scan of the last `[`. */\nfunction healLink(text: string): string {\n const open = text.lastIndexOf(\"[\");\n if (open < 0) return text;\n const rest = text.slice(open + 1);\n if (rest.includes(\"\\n\")) return text;\n const image = open > 0 && text[open - 1] === \"!\";\n const close = rest.indexOf(\"]\");\n const after = close < 0 ? \"\" : rest.slice(close + 1);\n const cut = close < 0 || after === \"\" || (after.startsWith(\"(\") && !after.includes(\")\"));\n if (!cut) return text;\n const head = text.slice(0, image ? open - 1 : open);\n return image ? head : head + (close < 0 ? rest : rest.slice(0, close));\n}\n\n/**\n * Closes what a text cut in the middle leaves open: an emphasis (`**`, `~~`) or a code span, a link or image whose\n * address has not arrived. Inside an open code fence nothing is healed — it is shown as code as it comes.\n */\nexport function healStreaming(source: string): string {\n if (((source.match(FENCE) ?? []).length & 1) === 1) return source;\n let out = healLink(source);\n const cut = out.lastIndexOf(\"\\n\\n\");\n const block = cut < 0 ? out : out.slice(cut + 2);\n const open = (marker: string) => (block.split(marker).length - 1) % 2 === 1;\n // A marker just opened, with nothing after it yet, is dropped rather than shown as an empty emphasis.\n const close = (marker: string) => (out.endsWith(marker) ? out.slice(0, -marker.length) : `${out}${marker}`);\n if (open(\"`\")) return close(\"`\");\n for (const marker of [\"**\", \"~~\"]) if (open(marker)) out = close(marker);\n return out;\n}\n\n/** The blocks of a Markdown source. */\nexport function parseSource(source: string, { streaming = false, headingIds = false }: ParseOptions = {}): BlockNode[] {\n return parseMarkdown(streaming ? healStreaming(source) : source, { headingIds, ...(streaming && { extensions: [streamingMarkdownExtension()] }) }).children;\n}\n\n/** The text of inline nodes (a heading's label, an image's alt). */\nexport function textOf(nodes: readonly { type: string; value?: string; children?: readonly unknown[] }[]): string {\n return nodes\n .map((node) => (node.children ? textOf(node.children as typeof nodes) : (node.value ?? \"\")))\n .join(\"\");\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/markdown/markdown.tsx","../src/cn.ts","../src/markdown/parse.ts"],"sourcesContent":["// Server-safe (no hook, no context): a Markdown text rendered on the tokens, from TanStack Markdown's AST. Raw HTML is\n// never enabled (it is shown as text), executable URLs are dropped, links to another site carry `rel=\"noopener\n// noreferrer\"`, and every fenced block is a `CodeBlock` (the same grammars, the same colours). `streaming` is for a\n// text that arrives in pieces — an AI answer: the unfinished end is closed and a caret marks where it goes on.\nimport { CodeBlock } from \"@krizaka/ui/code-block\";\nimport * as React from \"react\";\n\nimport { cn } from \"../cn\";\nimport { type BlockNode, type InlineNode, parseSource, textOf } from \"./parse\";\n\nexport type MarkdownLinkProps = React.ComponentProps<\"a\">;\n\nexport type MarkdownProps = Omit<React.ComponentProps<\"div\">, \"children\"> & {\n /** The Markdown source. */\n children: string;\n /** The text is still arriving: the unfinished end is closed and a caret marks the end. */\n streaming?: boolean;\n /** Gives every heading an `id`, for `#section` links. */\n headingIds?: boolean;\n /** The words of the copy button of the code blocks, passed translated. Without them a code block has no copy button. */\n codeLabels?: { copy: string; copied: string };\n /** Your router's link (Next's `Link`) for the links that stay on the site (`/docs`, `#section`); the others are plain `a`. */\n linkAs?: React.ElementType<MarkdownLinkProps>;\n};\n\ntype Context = Pick<MarkdownProps, \"codeLabels\" | \"linkAs\">;\n\nconst external = (href: string) => /^[a-z][a-z0-9+.-]*:/i.test(href);\n\nfunction Inlines({ nodes, ctx }: { nodes: readonly InlineNode[]; ctx: Context }) {\n return nodes.map((node, i) => <Inline key={i} node={node} ctx={ctx} />);\n}\n\nfunction Inline({ node, ctx }: { node: InlineNode; ctx: Context }): React.ReactNode {\n switch (node.type) {\n case \"text\":\n return node.value;\n case \"inlineCode\":\n return <code>{node.value}</code>;\n case \"strong\":\n return (\n <strong>\n <Inlines nodes={node.children} ctx={ctx} />\n </strong>\n );\n case \"emphasis\":\n return (\n <em>\n <Inlines nodes={node.children} ctx={ctx} />\n </em>\n );\n case \"strike\":\n return (\n <del>\n <Inlines nodes={node.children} ctx={ctx} />\n </del>\n );\n case \"break\":\n return <br />;\n case \"link\": {\n const Link = external(node.href) ? \"a\" : (ctx.linkAs ?? \"a\");\n const props = external(node.href) && !node.href.startsWith(\"mailto:\") && !node.href.startsWith(\"tel:\") ? { rel: \"noopener noreferrer\" } : {};\n return (\n <Link href={node.href} title={node.title} {...props}>\n <Inlines nodes={node.children} ctx={ctx} />\n </Link>\n );\n }\n case \"image\":\n return <img src={node.src} alt={node.alt} title={node.title} loading=\"lazy\" />;\n case \"footnoteReference\":\n return (\n <sup>\n <a id={`kz-fnref-${node.id}`} href={`#kz-fn-${node.id}`} data-footnote-ref=\"\">\n {node.number}\n </a>\n </sup>\n );\n // Raw HTML is never enabled by the parser: it arrives as text. A node of this kind is shown as text too.\n case \"inlineHtml\":\n return node.value;\n default:\n return null;\n }\n}\n\nfunction Blocks({ nodes, ctx }: { nodes: readonly BlockNode[]; ctx: Context }) {\n return nodes.map((node, i) => <Block key={i} node={node} ctx={ctx} />);\n}\n\nfunction Block({ node, ctx }: { node: BlockNode; ctx: Context }): React.ReactNode {\n switch (node.type) {\n case \"heading\": {\n const Tag = `h${node.depth}` as const;\n return (\n <Tag id={node.id}>\n <Inlines nodes={node.children} ctx={ctx} />\n </Tag>\n );\n }\n case \"paragraph\":\n return (\n <p>\n <Inlines nodes={node.children} ctx={ctx} />\n </p>\n );\n case \"code\":\n return (\n <CodeBlock\n code={node.value}\n language={node.lang ?? \"text\"}\n file={node.title ?? node.file}\n copyLabel={ctx.codeLabels?.copy}\n copiedLabel={ctx.codeLabels?.copied}\n annotations={node.highlightLines?.map((line) => ({ lines: line, kind: \"highlight\" as const }))}\n />\n );\n case \"list\": {\n const Tag = node.ordered ? \"ol\" : \"ul\";\n const tasks = node.items.some((item) => item.checked !== undefined);\n return (\n <Tag start={node.ordered && node.start !== undefined && node.start !== 1 ? node.start : undefined} data-tasks={tasks ? \"\" : undefined}>\n {node.items.map((item, i) => (\n <li key={i}>\n {item.checked !== undefined ? (\n <label>\n <input type=\"checkbox\" checked={item.checked} disabled readOnly />{\" \"}\n <ListItem blocks={item.children} ctx={ctx} />\n </label>\n ) : (\n <ListItem blocks={item.children} ctx={ctx} />\n )}\n </li>\n ))}\n </Tag>\n );\n }\n case \"blockquote\":\n return (\n <blockquote>\n <Blocks nodes={node.children} ctx={ctx} />\n </blockquote>\n );\n case \"table\":\n return (\n <div className=\"kz-md-table\">\n <table>\n <thead>\n <tr>\n {node.header.map((cell, i) => (\n <th key={i} scope=\"col\" style={{ textAlign: node.align[i] ?? undefined }}>\n <Inlines nodes={cell.children} ctx={ctx} />\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {node.rows.map((row, r) => (\n <tr key={r}>\n {row.map((cell, i) => (\n <td key={i} style={{ textAlign: node.align[i] ?? undefined }}>\n <Inlines nodes={cell.children} ctx={ctx} />\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n case \"thematicBreak\":\n return <hr />;\n case \"footnotes\":\n return (\n <section data-footnotes=\"\">\n <ol>\n {node.items.map((item) => (\n <li key={item.id} id={`kz-fn-${item.id}`}>\n <Blocks nodes={item.children} ctx={ctx} />\n </li>\n ))}\n </ol>\n </section>\n );\n // Raw HTML (never enabled) arrives as a paragraph of text; extensions are not enabled either. Shown as text.\n case \"html\":\n return <p>{node.value}</p>;\n default:\n return null;\n }\n}\n\n/** A list item: a lone paragraph is inline (a tight list), anything else keeps its blocks. */\nfunction ListItem({ blocks, ctx }: { blocks: readonly BlockNode[]; ctx: Context }) {\n return blocks.map((block, i) => (block.type === \"paragraph\" && blocks.length === 1 ? <Inlines key={i} nodes={block.children} ctx={ctx} /> : <Block key={i} node={block} ctx={ctx} />));\n}\n\n/** A Markdown text on the tokens: headings, paragraphs, lists (and tasks), quotes, tables, code, links, images, footnotes. */\nexport function Markdown({ children, streaming, headingIds, codeLabels, linkAs, className, ...props }: MarkdownProps) {\n const blocks = parseSource(children, { streaming, headingIds });\n return (\n <div className={cn(\"kz-md\", className)} data-streaming={streaming ? \"\" : undefined} aria-busy={streaming || undefined} {...props}>\n <Blocks nodes={blocks} ctx={{ codeLabels, linkAs }} />\n </div>\n );\n}\n\nexport { textOf };\n","import { type ClassValue, clsx } from \"clsx\";\nimport { cnMerge, type TWMergeConfig } from \"tailwind-variants\";\n\nexport type { ClassValue };\n\n/**\n * The preset's own utilities, told to the merge engine: the material (BRAND.md §6: `bg-sheen`, `bg-fill-shade`,\n * `bg-halo` are background images; `shadow-raised` · `-floating` · `-overlay` · `-glow` are shadows; `inset-shadow-edge`\n * · `-edge-fill` · `-well` are inset shadows). Unknown, tailwind-merge would take `bg-sheen` for a colour and drop the\n * `bg-surface-2` it lies on.\n */\nexport const twMergeConfig: TWMergeConfig = {\n extend: {\n classGroups: {\n \"bg-image\": [\"bg-sheen\", \"bg-fill-shade\", \"bg-halo\"],\n shadow: [\"shadow-raised\", \"shadow-floating\", \"shadow-overlay\", \"shadow-glow\", \"shadow-glow-lg\"],\n \"inset-shadow\": [\"inset-shadow-edge\", \"inset-shadow-edge-fill\", \"inset-shadow-well\"],\n },\n },\n};\n\nconst mergeConfig = { twMergeConfig };\n\n/**\n * Merges Tailwind classes: the last one wins — a product's `className` overrides the primitive's. The merge engine is\n * tailwind-merge as tailwind-variants ships it (the one `tv` uses), so the platform carries a single copy of it.\n * tailwind-variants bundles that engine since 3.3 (it never imports the `tailwind-merge` package, an optional peer):\n * hence `tailwind-variants ^3.3.1` and no `tailwind-merge` dependency — `scripts/consumer.mjs` checks it on a clean\n * install of the packed package.\n */\nexport function cn(...inputs: ClassValue[]): string {\n return cnMerge(clsx(inputs))(mergeConfig) ?? \"\";\n}\n\n","// The shared half of Markdown, web and React Native: the source becomes TanStack Markdown's serializable AST\n// (`@tanstack/markdown/parser`) — raw HTML is never enabled (it stays text), executable URLs are dropped (`javascript:`,\n// `data:`), and a text that is still arriving is healed so the half-written end reads like the finished one.\nimport type { BlockNode } from \"@tanstack/markdown\";\nimport { streamingMarkdownExtension } from \"@tanstack/markdown/extensions/streaming\";\nimport { parseMarkdown } from \"@tanstack/markdown/parser\";\n\nexport type { BlockNode, InlineNode, ListItemNode, TableNode } from \"@tanstack/markdown\";\n\nexport type ParseOptions = {\n /** The text is still arriving (an AI answer): the unfinished end is closed, so it never shows `**` or a half link. */\n streaming?: boolean;\n /** Gives every heading an `id` (`#section` links, a table of contents). */\n headingIds?: boolean;\n};\n\nconst FENCE = /^ {0,3}(```|~~~)/gm;\n\n/** A link or image cut at its end: `[label`, `[label]`, `[label](http…` become `label`, an image is dropped. Linear: one scan of the last `[`. */\nfunction healLink(text: string): string {\n const open = text.lastIndexOf(\"[\");\n if (open < 0) return text;\n const rest = text.slice(open + 1);\n if (rest.includes(\"\\n\")) return text;\n const image = open > 0 && text[open - 1] === \"!\";\n const close = rest.indexOf(\"]\");\n const after = close < 0 ? \"\" : rest.slice(close + 1);\n const cut = close < 0 || after === \"\" || (after.startsWith(\"(\") && !after.includes(\")\"));\n if (!cut) return text;\n const head = text.slice(0, image ? open - 1 : open);\n return image ? head : head + (close < 0 ? rest : rest.slice(0, close));\n}\n\n/**\n * Closes what a text cut in the middle leaves open: an emphasis (`**`, `~~`) or a code span, a link or image whose\n * address has not arrived. Inside an open code fence nothing is healed — it is shown as code as it comes.\n */\nexport function healStreaming(source: string): string {\n if (((source.match(FENCE) ?? []).length & 1) === 1) return source;\n let out = healLink(source);\n const cut = out.lastIndexOf(\"\\n\\n\");\n const block = cut < 0 ? out : out.slice(cut + 2);\n const open = (marker: string) => (block.split(marker).length - 1) % 2 === 1;\n // A marker just opened, with nothing after it yet, is dropped rather than shown as an empty emphasis.\n const close = (marker: string) => (out.endsWith(marker) ? out.slice(0, -marker.length) : `${out}${marker}`);\n if (open(\"`\")) return close(\"`\");\n for (const marker of [\"**\", \"~~\"]) if (open(marker)) out = close(marker);\n return out;\n}\n\n/** The blocks of a Markdown source. */\nexport function parseSource(source: string, { streaming = false, headingIds = false }: ParseOptions = {}): BlockNode[] {\n return parseMarkdown(streaming ? healStreaming(source) : source, { headingIds, ...(streaming && { extensions: [streamingMarkdownExtension()] }) }).children;\n}\n\n/** The text of inline nodes (a heading's label, an image's alt). */\nexport function textOf(nodes: readonly { type: string; value?: string; children?: readonly unknown[] }[]): string {\n return nodes\n .map((node) => (node.children ? textOf(node.children as typeof nodes) : (node.value ?? \"\")))\n .join(\"\");\n}\n"],"mappings":"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","names":[]}
@@ -2,7 +2,7 @@
2
2
  import { tv } from "tailwind-variants";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  var skipLink = tv({
5
- base: "sr-only focus:not-sr-only focus:fixed focus:left-4 focus:top-4 focus:z-[100] focus:rounded-full focus:bg-surface-1 focus:px-4 focus:py-2 focus:text-sm focus:font-semibold focus:text-fg focus:no-underline focus:shadow-lg focus:outline-hidden focus:ring-2 focus:ring-ring"
5
+ base: "sr-only focus:not-sr-only focus:fixed focus:left-4 focus:top-4 focus:z-[100] focus:rounded-full focus:bg-surface-1 focus:px-4 focus:py-2 focus:text-sm focus:font-semibold focus:text-fg focus:no-underline focus:shadow-lg focus:outline-hidden focus-visible:ring-2 focus-visible:ring-ring"
6
6
  });
7
7
  function SkipLink({ href = "#content", className, onClick, children, ...props }) {
8
8
  const handleClick = (event) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/skip-link/skip-link.tsx","../src/marketing-layout/marketing-layout.tsx"],"sourcesContent":["// Client (it moves focus). WCAG 2.4.1 Bypass Blocks: the first tab stop of a page, a link that skips the navigation and\n// lands on the content. Visually hidden until focused, then a pill above everything in the brand ring. The label is\n// passed translated; the target needs an `id` (and is made focusable, so focus really moves, router or not).\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nexport const skipLink = tv({\n base:\n \"sr-only focus:not-sr-only focus:fixed focus:left-4 focus:top-4 focus:z-[100] focus:rounded-full focus:bg-surface-1 focus:px-4 focus:py-2 \" +\n \"focus:text-sm focus:font-semibold focus:text-fg focus:no-underline focus:shadow-lg focus:outline-hidden focus:ring-2 focus:ring-ring\",\n});\n\nexport type SkipLinkProps = Omit<React.ComponentProps<\"a\">, \"href\"> & {\n /**\n * The content to land on: `#` and its `id`. The element becomes focusable (`tabindex=\"-1\"`) when it is not.\n * @default \"#content\"\n */\n href?: `#${string}`;\n};\n\n/** A \"skip to content\" link: the first tab stop, hidden until focused; Enter moves focus to the target. */\nexport function SkipLink({ href = \"#content\", className, onClick, children, ...props }: SkipLinkProps) {\n const handleClick = (event: React.MouseEvent<HTMLAnchorElement>) => {\n onClick?.(event);\n if (event.defaultPrevented) return;\n const target = document.getElementById(decodeURIComponent(href.slice(1)));\n if (!target) return;\n if (!target.hasAttribute(\"tabindex\") && !target.matches(\"a[href], button, input, select, textarea, [contenteditable]\")) target.setAttribute(\"tabindex\", \"-1\");\n target.focus();\n };\n return (\n <a href={href} className={skipLink({ className })} onClick={handleClick} {...props}>\n {children}\n </a>\n );\n}\n","// Server-safe. The page of a site (krizaka.com, a product's public pages): a link to skip to the content, the site's\n// bar, the page — its PageHero and Sections (@krizaka/ui/page) — and the footer. The bar floats over the hero\n// (`--kz-hero-top` clears it); everything shares the page frame (`--kz-page-max`, `--kz-page-gutter`).\nimport { SkipLink } from \"@krizaka/ui/skip-link\";\nimport type * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nexport const marketingLayout = tv({\n slots: {\n root: \"flex min-h-dvh w-full flex-col bg-surface-0 text-fg\",\n header: \"fixed inset-x-0 top-3 z-50 px-(--kz-page-gutter,16px) pointer-events-none *:pointer-events-auto\",\n main: \"flex-1 outline-hidden\",\n },\n});\nconst s = marketingLayout();\n\nexport type MarketingLayoutProps = React.ComponentProps<\"div\"> & {\n /** The site's bar (a floating NavBar of @krizaka/ui/nav-bar). */\n header: React.ReactNode;\n /** The site's footer. */\n footer?: React.ReactNode;\n /** The words of the link that skips to the content (`Skip to content`). */\n skipLabel: string;\n /** The page: a PageHero, then Sections. */\n children: React.ReactNode;\n};\n\n/** A site's page: skip link, floating bar, the page, the footer. */\nexport function MarketingLayout({ header, footer, skipLabel, className, children, ...props }: MarketingLayoutProps) {\n return (\n <div className={s.root({ className })} {...props}>\n <SkipLink>{skipLabel}</SkipLink>\n <div className={s.header()}>{header}</div>\n <main id=\"content\" tabIndex={-1} className={s.main()}>\n {children}\n </main>\n {footer}\n </div>\n );\n}\n"],"mappings":";AAIA,SAAS,UAAU;AA2Bf;AAzBG,IAAM,WAAW,GAAG;AAAA,EACzB,MACE;AAEJ,CAAC;AAWM,SAAS,SAAS,EAAE,OAAO,YAAY,WAAW,SAAS,UAAU,GAAG,MAAM,GAAkB;AACrG,QAAM,cAAc,CAAC,UAA+C;AAClE,cAAU,KAAK;AACf,QAAI,MAAM,iBAAkB;AAC5B,UAAM,SAAS,SAAS,eAAe,mBAAmB,KAAK,MAAM,CAAC,CAAC,CAAC;AACxE,QAAI,CAAC,OAAQ;AACb,QAAI,CAAC,OAAO,aAAa,UAAU,KAAK,CAAC,OAAO,QAAQ,6DAA6D,EAAG,QAAO,aAAa,YAAY,IAAI;AAC5J,WAAO,MAAM;AAAA,EACf;AACA,SACE,oBAAC,OAAE,MAAY,WAAW,SAAS,EAAE,UAAU,CAAC,GAAG,SAAS,aAAc,GAAG,OAC1E,UACH;AAEJ;;;AC9BA,SAAS,MAAAA,WAAU;AAyBf,SACE,OAAAC,MADF;AAvBG,IAAM,kBAAkBD,IAAG;AAAA,EAChC,OAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AACF,CAAC;AACD,IAAM,IAAI,gBAAgB;AAcnB,SAAS,gBAAgB,EAAE,QAAQ,QAAQ,WAAW,WAAW,UAAU,GAAG,MAAM,GAAyB;AAClH,SACE,qBAAC,SAAI,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC,GAAI,GAAG,OACzC;AAAA,oBAAAC,KAAC,YAAU,qBAAU;AAAA,IACrB,gBAAAA,KAAC,SAAI,WAAW,EAAE,OAAO,GAAI,kBAAO;AAAA,IACpC,gBAAAA,KAAC,UAAK,IAAG,WAAU,UAAU,IAAI,WAAW,EAAE,KAAK,GAChD,UACH;AAAA,IACC;AAAA,KACH;AAEJ;","names":["tv","jsx"]}
1
+ {"version":3,"sources":["../src/skip-link/skip-link.tsx","../src/marketing-layout/marketing-layout.tsx"],"sourcesContent":["// Client (it moves focus). WCAG 2.4.1 Bypass Blocks: the first tab stop of a page, a link that skips the navigation and\n// lands on the content. Visually hidden until focused, then a pill above everything in the brand ring. The label is\n// passed translated; the target needs an `id` (and is made focusable, so focus really moves, router or not).\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nexport const skipLink = tv({\n base:\n \"sr-only focus:not-sr-only focus:fixed focus:left-4 focus:top-4 focus:z-[100] focus:rounded-full focus:bg-surface-1 focus:px-4 focus:py-2 \" +\n \"focus:text-sm focus:font-semibold focus:text-fg focus:no-underline focus:shadow-lg focus:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n});\n\nexport type SkipLinkProps = Omit<React.ComponentProps<\"a\">, \"href\"> & {\n /**\n * The content to land on: `#` and its `id`. The element becomes focusable (`tabindex=\"-1\"`) when it is not.\n * @default \"#content\"\n */\n href?: `#${string}`;\n};\n\n/** A \"skip to content\" link: the first tab stop, hidden until focused; Enter moves focus to the target. */\nexport function SkipLink({ href = \"#content\", className, onClick, children, ...props }: SkipLinkProps) {\n const handleClick = (event: React.MouseEvent<HTMLAnchorElement>) => {\n onClick?.(event);\n if (event.defaultPrevented) return;\n const target = document.getElementById(decodeURIComponent(href.slice(1)));\n if (!target) return;\n if (!target.hasAttribute(\"tabindex\") && !target.matches(\"a[href], button, input, select, textarea, [contenteditable]\")) target.setAttribute(\"tabindex\", \"-1\");\n target.focus();\n };\n return (\n <a href={href} className={skipLink({ className })} onClick={handleClick} {...props}>\n {children}\n </a>\n );\n}\n","// Server-safe. The page of a site (krizaka.com, a product's public pages): a link to skip to the content, the site's\n// bar, the page — its PageHero and Sections (@krizaka/ui/page) — and the footer. The bar floats over the hero\n// (`--kz-hero-top` clears it); everything shares the page frame (`--kz-page-max`, `--kz-page-gutter`).\nimport { SkipLink } from \"@krizaka/ui/skip-link\";\nimport type * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nexport const marketingLayout = tv({\n slots: {\n root: \"flex min-h-dvh w-full flex-col bg-surface-0 text-fg\",\n header: \"fixed inset-x-0 top-3 z-50 px-(--kz-page-gutter,16px) pointer-events-none *:pointer-events-auto\",\n main: \"flex-1 outline-hidden\",\n },\n});\nconst s = marketingLayout();\n\nexport type MarketingLayoutProps = React.ComponentProps<\"div\"> & {\n /** The site's bar (a floating NavBar of @krizaka/ui/nav-bar). */\n header: React.ReactNode;\n /** The site's footer. */\n footer?: React.ReactNode;\n /** The words of the link that skips to the content (`Skip to content`). */\n skipLabel: string;\n /** The page: a PageHero, then Sections. */\n children: React.ReactNode;\n};\n\n/** A site's page: skip link, floating bar, the page, the footer. */\nexport function MarketingLayout({ header, footer, skipLabel, className, children, ...props }: MarketingLayoutProps) {\n return (\n <div className={s.root({ className })} {...props}>\n <SkipLink>{skipLabel}</SkipLink>\n <div className={s.header()}>{header}</div>\n <main id=\"content\" tabIndex={-1} className={s.main()}>\n {children}\n </main>\n {footer}\n </div>\n );\n}\n"],"mappings":";AAIA,SAAS,UAAU;AA2Bf;AAzBG,IAAM,WAAW,GAAG;AAAA,EACzB,MACE;AAEJ,CAAC;AAWM,SAAS,SAAS,EAAE,OAAO,YAAY,WAAW,SAAS,UAAU,GAAG,MAAM,GAAkB;AACrG,QAAM,cAAc,CAAC,UAA+C;AAClE,cAAU,KAAK;AACf,QAAI,MAAM,iBAAkB;AAC5B,UAAM,SAAS,SAAS,eAAe,mBAAmB,KAAK,MAAM,CAAC,CAAC,CAAC;AACxE,QAAI,CAAC,OAAQ;AACb,QAAI,CAAC,OAAO,aAAa,UAAU,KAAK,CAAC,OAAO,QAAQ,6DAA6D,EAAG,QAAO,aAAa,YAAY,IAAI;AAC5J,WAAO,MAAM;AAAA,EACf;AACA,SACE,oBAAC,OAAE,MAAY,WAAW,SAAS,EAAE,UAAU,CAAC,GAAG,SAAS,aAAc,GAAG,OAC1E,UACH;AAEJ;;;AC9BA,SAAS,MAAAA,WAAU;AAyBf,SACE,OAAAC,MADF;AAvBG,IAAM,kBAAkBD,IAAG;AAAA,EAChC,OAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AACF,CAAC;AACD,IAAM,IAAI,gBAAgB;AAcnB,SAAS,gBAAgB,EAAE,QAAQ,QAAQ,WAAW,WAAW,UAAU,GAAG,MAAM,GAAyB;AAClH,SACE,qBAAC,SAAI,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC,GAAI,GAAG,OACzC;AAAA,oBAAAC,KAAC,YAAU,qBAAU;AAAA,IACrB,gBAAAA,KAAC,SAAI,WAAW,EAAE,OAAO,GAAI,kBAAO;AAAA,IACpC,gBAAAA,KAAC,UAAK,IAAG,WAAU,UAAU,IAAI,WAAW,EAAE,KAAK,GAChD,UACH;AAAA,IACC;AAAA,KACH;AAEJ;","names":["tv","jsx"]}
package/dist/marquee.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  cn
4
- } from "./chunk-2FRWNSRO.js";
4
+ } from "./chunk-NSLXEDIS.js";
5
5
 
6
6
  // src/marquee/marquee.tsx
7
7
  import * as React from "react";
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  cn
4
- } from "./chunk-G3ETON2A.js";
4
+ } from "./chunk-WU4VLSEA.js";
5
5
 
6
6
  // src/mascots/mascot.tsx
7
7
  import { useId } from "react";
@@ -7,8 +7,9 @@ import "./chunk-JXLDUDTD.js";
7
7
  import {
8
8
  Button,
9
9
  IconButton
10
- } from "./chunk-3BC4XQ6C.js";
10
+ } from "./chunk-DZU6RMYD.js";
11
11
  import "./chunk-D3T54RSL.js";
12
+ import "./chunk-NSLXEDIS.js";
12
13
 
13
14
  // src/dialog/dialog.tsx
14
15
  import { Dialog as DialogPrimitive } from "radix-ui";
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/dialog/dialog.tsx","../src/dialog/return-focus.ts","../src/match-dialog/match-dialog.tsx"],"sourcesContent":["// Client (a portal). Radix does the focus trap, the scroll lock, Escape, the outside click, aria-modal, the\n// aria-labelledby / aria-describedby wiring and the focus return: this file only holds the shape.\nimport { Dialog as DialogPrimitive } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { IconButton } from \"../button/button\";\nimport { useReturnFocus } from \"./return-focus\";\n\nexport const dialog = tv({\n slots: {\n overlay: \"kz-overlay fixed inset-0 z-50 bg-overlay backdrop-blur-xs\",\n content:\n \"kz-dialog fixed z-50 flex flex-col overflow-hidden border border-border-default bg-surface-1 text-fg shadow-lg focus:outline-hidden\",\n close: \"absolute right-3 top-3 h-9 w-9\",\n header: \"flex flex-col gap-1 px-5 pb-2 pr-14 pt-5\",\n title: \"text-base font-bold text-fg\",\n description: \"text-sm text-fg-secondary\",\n body: \"min-h-0 flex-1 overflow-y-auto px-5 pb-5\",\n footer:\n \"flex flex-wrap items-center justify-end gap-2 border-t border-border-subtle px-5 py-4 pb-[max(1rem,env(safe-area-inset-bottom))]\",\n },\n variants: {\n placement: {\n center: { content: \"left-1/2 top-1/2 max-h-[85dvh] w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 rounded-xl\" },\n /* A sheet: anchored at the bottom on a phone, centred from `sm` up. */\n bottom: {\n content:\n \"inset-x-0 bottom-0 max-h-[92dvh] rounded-t-[1.75rem] sm:bottom-auto sm:left-1/2 sm:top-1/2 sm:w-full \" +\n \"sm:-translate-x-1/2 sm:-translate-y-1/2 sm:rounded-[1.75rem]\",\n },\n right: { content: \"inset-y-0 right-0 h-full w-full max-w-md rounded-none border-y-0 border-r-0\" },\n /* A navigation drawer: full height, from the left, clear of the notch. */\n left: { content: \"inset-y-0 left-0 h-full w-full max-w-md rounded-none border-y-0 border-l-0 pl-[env(safe-area-inset-left)]\" },\n },\n size: { sm: { content: \"sm:max-w-sm\" }, md: { content: \"sm:max-w-md\" }, lg: { content: \"sm:max-w-2xl\" } },\n },\n defaultVariants: { placement: \"center\", size: \"md\" },\n});\nconst s = dialog();\n\nexport type DialogVariants = VariantProps<typeof dialog>;\n\nfunction CloseIcon() {\n return (\n <svg viewBox=\"0 0 24 24\" className=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" aria-hidden>\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </svg>\n );\n}\n\ntype CloseButtonProps =\n | {\n /** The accessible name of the close button — passed translated. */\n closeLabel: string;\n /** Leaves the close button out (the content brings its own way out, or none: see `dismissible`). */\n hideClose?: false;\n }\n | { closeLabel?: string; hideClose: true };\n\nexport type DialogContentProps = React.ComponentProps<typeof DialogPrimitive.Content> &\n DialogVariants &\n CloseButtonProps & {\n /**\n * center · bottom (a sheet on a phone, centred from `sm` up) · right (a side panel, full height) · left (a\n * navigation drawer, full height).\n * @default \"center\"\n */\n placement?: DialogVariants[\"placement\"];\n /**\n * sm · md · lg: the width of the dialog.\n * @default \"md\"\n */\n size?: DialogVariants[\"size\"];\n /**\n * `false`: Escape and a click outside do not close it (a gate the user must answer: age, terms). It still closes\n * through `open` / `onOpenChange` and any `Dialog.Close` inside. Default `true`.\n */\n dismissible?: boolean;\n /** The element the portal renders into (default: document.body). */\n container?: HTMLElement | null;\n };\n\nconst prevent = (event: Event) => event.preventDefault();\n\n/** Radix's content, mounted only while open: it remembers the opener then and gives focus back on close (WCAG 2.4.3). */\nfunction ReturnFocusContent({ onCloseAutoFocus, ...props }: React.ComponentProps<typeof DialogPrimitive.Content>) {\n return <DialogPrimitive.Content onCloseAutoFocus={useReturnFocus(onCloseAutoFocus)} {...props} />;\n}\n\n/** The dialog itself, portalled over a dimmed overlay, with a close button. Give it a `Dialog.Title`. */\nexport function DialogContent({\n placement,\n size,\n closeLabel,\n hideClose,\n dismissible = true,\n container,\n className,\n children,\n onEscapeKeyDown,\n onPointerDownOutside,\n onInteractOutside,\n ...props\n}: DialogContentProps) {\n const v = dialog({ placement, size });\n return (\n <DialogPrimitive.Portal container={container}>\n <DialogPrimitive.Overlay className={v.overlay()} />\n <ReturnFocusContent\n data-placement={placement ?? \"center\"}\n data-dismissible={dismissible ? undefined : \"false\"}\n className={v.content({ className })}\n onEscapeKeyDown={dismissible ? onEscapeKeyDown : chain(onEscapeKeyDown, prevent)}\n onPointerDownOutside={dismissible ? onPointerDownOutside : chain(onPointerDownOutside, prevent)}\n onInteractOutside={dismissible ? onInteractOutside : chain(onInteractOutside, prevent)}\n {...props}\n >\n {children}\n {!hideClose && (\n <DialogPrimitive.Close asChild>\n <IconButton label={closeLabel as string} variant=\"ghost\" shape=\"pill\" className={v.close()}>\n <CloseIcon />\n </IconButton>\n </DialogPrimitive.Close>\n )}\n </ReturnFocusContent>\n </DialogPrimitive.Portal>\n );\n}\n\nfunction chain<E extends Event>(handler: ((event: E) => void) | undefined, then: (event: E) => void) {\n return (event: E) => {\n handler?.(event);\n then(event);\n };\n}\n\nexport function DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div className={s.header({ className })} {...props} />;\n}\n\nexport function DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>) {\n return <DialogPrimitive.Title className={s.title({ className })} {...props} />;\n}\n\nexport function DialogDescription({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Description>) {\n return <DialogPrimitive.Description className={s.description({ className })} {...props} />;\n}\n\nexport function DialogBody({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div className={s.body({ className })} {...props} />;\n}\n\nexport function DialogFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div className={s.footer({ className })} {...props} />;\n}\n\n/** `Dialog.Root/Trigger/Content/Header/Title/Description/Body/Footer/Close`. `open`/`defaultOpen` + `onOpenChange`. */\nexport const Dialog = {\n Root: DialogPrimitive.Root,\n Trigger: DialogPrimitive.Trigger,\n Close: DialogPrimitive.Close,\n Content: DialogContent,\n Header: DialogHeader,\n Title: DialogTitle,\n Description: DialogDescription,\n Body: DialogBody,\n Footer: DialogFooter,\n};\n\n/** `Omit` that keeps the close-button union (`closeLabel` required unless `hideClose`). */\ntype DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;\n\nexport type SheetProps = DistributiveOmit<DialogContentProps, \"placement\">;\n\n/** A sheet is a dialog anchored at the bottom (centred from `sm` up): `Dialog.Content placement=\"bottom\"`. */\nexport function Sheet(props: SheetProps) {\n return <DialogContent placement=\"bottom\" {...props} />;\n}\n","// Client. WCAG 2.4.3: when a dialog closes, focus goes back to what opened it. Radix only does it for `Dialog.Trigger`;\n// most app dialogs are controlled (`open` / `onOpenChange`) and opened by a plain button, so on Escape focus fell to\n// <body>. The content remembers the focused element when it mounts (it is still the opener: Radix moves focus in an\n// effect) and gives it back on close, unless the consumer's `onCloseAutoFocus` prevented the default.\nimport * as React from \"react\";\n\n/** The handler for `onCloseAutoFocus`: yours first, then focus back on the opener if it is still on the page. */\nexport function useReturnFocus(onCloseAutoFocus?: (event: Event) => void) {\n const [opener] = React.useState<Element | null>(() => (typeof document === \"undefined\" ? null : document.activeElement));\n return React.useCallback(\n (event: Event) => {\n onCloseAutoFocus?.(event);\n if (event.defaultPrevented) return;\n if (opener instanceof HTMLElement && opener !== document.body && opener.isConnected) {\n event.preventDefault();\n opener.focus();\n }\n },\n [opener, onCloseAutoFocus],\n );\n}\n","// Client (a portal). The moment two people choose each other — a match, a pair, a deal: a dialog in the brand\n// gradient, the two avatars meeting at a heart, the next step. The entrance plays once; still under reduced motion.\nimport * as React from \"react\";\n\nimport { Avatar } from \"../avatar\";\nimport { Button } from \"../button\";\nimport { Dialog } from \"../dialog\";\n\nexport type MatchDialogProps = {\n /** Shown (controlled). */\n open: boolean;\n /** Called when it closes. */\n onOpenChange: (open: boolean) => void;\n /** The headline (“It's a match!”) — passed translated; the dialog's name. */\n title: string;\n /** A line under it. */\n description?: string;\n /** The two people: avatar URLs and names. */\n people: readonly [{ src?: string | null; name: string }, { src?: string | null; name: string }];\n /** The main action (“Send a message”). */\n primaryLabel: string;\n /** What it does. */\n onPrimary: () => void;\n /** The way back (“Keep swiping”). */\n secondaryLabel: string;\n /** Where it is drawn (the page's body by default): give an element inside a brand scope (`.brand-…`) so the dialog wears the brand too. */\n container?: HTMLElement | null;\n};\n\n/** Two people choose each other: the avatars meet at a heart in the brand gradient, the next step under them. */\nexport function MatchDialog({ open, onOpenChange, title, description, people, primaryLabel, onPrimary, secondaryLabel, container }: MatchDialogProps) {\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Content hideClose size=\"sm\" container={container} className=\"overflow-hidden border-0 bg-gradient-to-br from-accent to-accent-2 text-center text-on-accent\">\n <style href=\"krizaka-match\" precedence=\"default\">\n {\"@media (prefers-reduced-motion:no-preference){[data-kz-match] [data-side=a]{animation:kz-match-a .55s cubic-bezier(.3,1.6,.5,1) both}[data-kz-match] [data-side=b]{animation:kz-match-b .55s cubic-bezier(.3,1.6,.5,1) both}[data-kz-match] [data-heart]{animation:kz-match-heart .45s .25s cubic-bezier(.3,1.6,.5,1) both}}@keyframes kz-match-a{from{transform:translateX(-60px) rotate(-8deg);opacity:0}}@keyframes kz-match-b{from{transform:translateX(60px) rotate(8deg);opacity:0}}@keyframes kz-match-heart{from{transform:scale(0)}}\"}\n </style>\n <div data-kz-match=\"\" className=\"flex flex-col items-center gap-3 px-2 pb-2 pt-6\">\n <Dialog.Title className=\"font-display text-4xl font-black text-on-accent\">{title}</Dialog.Title>\n {description ? <Dialog.Description className=\"max-w-xs text-sm text-on-accent\">{description}</Dialog.Description> : null}\n <div className=\"relative my-6 flex h-36 w-64 items-center justify-center\" aria-hidden>\n <span data-side=\"a\" className=\"absolute left-6 -rotate-6 rounded-full ring-4 ring-on-accent\">\n <Avatar src={people[0].src ?? null} alt=\"\" fallback={people[0].name.charAt(0)} className=\"h-28 w-28 text-3xl\" />\n </span>\n <span data-side=\"b\" className=\"absolute right-6 rotate-6 rounded-full ring-4 ring-on-accent\">\n <Avatar src={people[1].src ?? null} alt=\"\" fallback={people[1].name.charAt(0)} className=\"h-28 w-28 text-3xl\" />\n </span>\n <span data-heart=\"\" className=\"absolute -bottom-1 flex h-12 w-12 items-center justify-center rounded-full bg-on-accent text-accent shadow-lg\">\n <svg viewBox=\"0 0 24 24\" className=\"h-6 w-6\" fill=\"currentColor\">\n <path d=\"M12 20s-7-4.4-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.6-7 10-7 10z\" />\n </svg>\n </span>\n </div>\n <div className=\"flex w-full flex-col gap-2\">\n <Button\n size=\"lg\"\n onClick={() => {\n onOpenChange(false);\n onPrimary();\n }}\n >\n {primaryLabel}\n </Button>\n <Dialog.Close asChild>\n <Button size=\"lg\" variant=\"ghost\" className=\"text-on-accent hover:bg-on-accent/15\">\n {secondaryLabel}\n </Button>\n </Dialog.Close>\n </div>\n </div>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n"],"mappings":"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","names":["jsx","jsxs"]}
1
+ {"version":3,"sources":["../src/dialog/dialog.tsx","../src/dialog/return-focus.ts","../src/match-dialog/match-dialog.tsx"],"sourcesContent":["// Client (a portal). Radix does the focus trap, the scroll lock, Escape, the outside click, aria-modal, the\n// aria-labelledby / aria-describedby wiring and the focus return: this file only holds the shape.\nimport { Dialog as DialogPrimitive } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { IconButton } from \"../button/button\";\nimport { useReturnFocus } from \"./return-focus\";\n\nexport const dialog = tv({\n slots: {\n overlay: \"kz-overlay fixed inset-0 z-50 bg-overlay backdrop-blur-xs\",\n content:\n \"kz-dialog fixed z-50 flex flex-col overflow-hidden border border-border-default bg-surface-1 text-fg shadow-lg focus:outline-hidden\",\n close: \"absolute right-3 top-3 h-9 w-9\",\n header: \"flex flex-col gap-1 px-5 pb-2 pr-14 pt-5\",\n title: \"text-base font-bold text-fg\",\n description: \"text-sm text-fg-secondary\",\n body: \"min-h-0 flex-1 overflow-y-auto px-5 pb-5\",\n footer:\n \"flex flex-wrap items-center justify-end gap-2 border-t border-border-subtle px-5 py-4 pb-[max(1rem,env(safe-area-inset-bottom))]\",\n },\n variants: {\n placement: {\n center: { content: \"left-1/2 top-1/2 max-h-[85dvh] w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 rounded-xl\" },\n /* A sheet: anchored at the bottom on a phone, centred from `sm` up. */\n bottom: {\n content:\n \"inset-x-0 bottom-0 max-h-[92dvh] rounded-t-[1.75rem] sm:bottom-auto sm:left-1/2 sm:top-1/2 sm:w-full \" +\n \"sm:-translate-x-1/2 sm:-translate-y-1/2 sm:rounded-[1.75rem]\",\n },\n right: { content: \"inset-y-0 right-0 h-full w-full max-w-md rounded-none border-y-0 border-r-0\" },\n /* A navigation drawer: full height, from the left, clear of the notch. */\n left: { content: \"inset-y-0 left-0 h-full w-full max-w-md rounded-none border-y-0 border-l-0 pl-[env(safe-area-inset-left)]\" },\n },\n size: { sm: { content: \"sm:max-w-sm\" }, md: { content: \"sm:max-w-md\" }, lg: { content: \"sm:max-w-2xl\" } },\n },\n defaultVariants: { placement: \"center\", size: \"md\" },\n});\nconst s = dialog();\n\nexport type DialogVariants = VariantProps<typeof dialog>;\n\nfunction CloseIcon() {\n return (\n <svg viewBox=\"0 0 24 24\" className=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" aria-hidden>\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </svg>\n );\n}\n\ntype CloseButtonProps =\n | {\n /** The accessible name of the close button — passed translated. */\n closeLabel: string;\n /** Leaves the close button out (the content brings its own way out, or none: see `dismissible`). */\n hideClose?: false;\n }\n | { closeLabel?: string; hideClose: true };\n\nexport type DialogContentProps = React.ComponentProps<typeof DialogPrimitive.Content> &\n DialogVariants &\n CloseButtonProps & {\n /**\n * center · bottom (a sheet on a phone, centred from `sm` up) · right (a side panel, full height) · left (a\n * navigation drawer, full height).\n * @default \"center\"\n */\n placement?: DialogVariants[\"placement\"];\n /**\n * sm · md · lg: the width of the dialog.\n * @default \"md\"\n */\n size?: DialogVariants[\"size\"];\n /**\n * `false`: Escape and a click outside do not close it (a gate the user must answer: age, terms). It still closes\n * through `open` / `onOpenChange` and any `Dialog.Close` inside. Default `true`.\n */\n dismissible?: boolean;\n /** The element the portal renders into (default: document.body). */\n container?: HTMLElement | null;\n };\n\nconst prevent = (event: Event) => event.preventDefault();\n\n/** Radix's content, mounted only while open: it remembers the opener then and gives focus back on close (WCAG 2.4.3). */\nfunction ReturnFocusContent({ onCloseAutoFocus, ...props }: React.ComponentProps<typeof DialogPrimitive.Content>) {\n return <DialogPrimitive.Content onCloseAutoFocus={useReturnFocus(onCloseAutoFocus)} {...props} />;\n}\n\n/** The dialog itself, portalled over a dimmed overlay, with a close button. Give it a `Dialog.Title`. */\nexport function DialogContent({\n placement,\n size,\n closeLabel,\n hideClose,\n dismissible = true,\n container,\n className,\n children,\n onEscapeKeyDown,\n onPointerDownOutside,\n onInteractOutside,\n ...props\n}: DialogContentProps) {\n const v = dialog({ placement, size });\n return (\n <DialogPrimitive.Portal container={container}>\n <DialogPrimitive.Overlay className={v.overlay()} />\n <ReturnFocusContent\n data-placement={placement ?? \"center\"}\n data-dismissible={dismissible ? undefined : \"false\"}\n className={v.content({ className })}\n onEscapeKeyDown={dismissible ? onEscapeKeyDown : chain(onEscapeKeyDown, prevent)}\n onPointerDownOutside={dismissible ? onPointerDownOutside : chain(onPointerDownOutside, prevent)}\n onInteractOutside={dismissible ? onInteractOutside : chain(onInteractOutside, prevent)}\n {...props}\n >\n {children}\n {!hideClose && (\n <DialogPrimitive.Close asChild>\n <IconButton label={closeLabel as string} variant=\"ghost\" shape=\"pill\" className={v.close()}>\n <CloseIcon />\n </IconButton>\n </DialogPrimitive.Close>\n )}\n </ReturnFocusContent>\n </DialogPrimitive.Portal>\n );\n}\n\nfunction chain<E extends Event>(handler: ((event: E) => void) | undefined, then: (event: E) => void) {\n return (event: E) => {\n handler?.(event);\n then(event);\n };\n}\n\nexport function DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div className={s.header({ className })} {...props} />;\n}\n\nexport function DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>) {\n return <DialogPrimitive.Title className={s.title({ className })} {...props} />;\n}\n\nexport function DialogDescription({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Description>) {\n return <DialogPrimitive.Description className={s.description({ className })} {...props} />;\n}\n\nexport function DialogBody({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div className={s.body({ className })} {...props} />;\n}\n\nexport function DialogFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div className={s.footer({ className })} {...props} />;\n}\n\n/** `Dialog.Root/Trigger/Content/Header/Title/Description/Body/Footer/Close`. `open`/`defaultOpen` + `onOpenChange`. */\nexport const Dialog = {\n Root: DialogPrimitive.Root,\n Trigger: DialogPrimitive.Trigger,\n Close: DialogPrimitive.Close,\n Content: DialogContent,\n Header: DialogHeader,\n Title: DialogTitle,\n Description: DialogDescription,\n Body: DialogBody,\n Footer: DialogFooter,\n};\n\n/** `Omit` that keeps the close-button union (`closeLabel` required unless `hideClose`). */\ntype DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;\n\nexport type SheetProps = DistributiveOmit<DialogContentProps, \"placement\">;\n\n/** A sheet is a dialog anchored at the bottom (centred from `sm` up): `Dialog.Content placement=\"bottom\"`. */\nexport function Sheet(props: SheetProps) {\n return <DialogContent placement=\"bottom\" {...props} />;\n}\n","// Client. WCAG 2.4.3: when a dialog closes, focus goes back to what opened it. Radix only does it for `Dialog.Trigger`;\n// most app dialogs are controlled (`open` / `onOpenChange`) and opened by a plain button, so on Escape focus fell to\n// <body>. The content remembers the focused element when it mounts (it is still the opener: Radix moves focus in an\n// effect) and gives it back on close, unless the consumer's `onCloseAutoFocus` prevented the default.\nimport * as React from \"react\";\n\n/** The handler for `onCloseAutoFocus`: yours first, then focus back on the opener if it is still on the page. */\nexport function useReturnFocus(onCloseAutoFocus?: (event: Event) => void) {\n const [opener] = React.useState<Element | null>(() => (typeof document === \"undefined\" ? null : document.activeElement));\n return React.useCallback(\n (event: Event) => {\n onCloseAutoFocus?.(event);\n if (event.defaultPrevented) return;\n if (opener instanceof HTMLElement && opener !== document.body && opener.isConnected) {\n event.preventDefault();\n opener.focus();\n }\n },\n [opener, onCloseAutoFocus],\n );\n}\n","// Client (a portal). The moment two people choose each other — a match, a pair, a deal: a dialog in the brand\n// gradient, the two avatars meeting at a heart, the next step. The entrance plays once; still under reduced motion.\nimport * as React from \"react\";\n\nimport { Avatar } from \"../avatar\";\nimport { Button } from \"../button\";\nimport { Dialog } from \"../dialog\";\n\nexport type MatchDialogProps = {\n /** Shown (controlled). */\n open: boolean;\n /** Called when it closes. */\n onOpenChange: (open: boolean) => void;\n /** The headline (“It's a match!”) — passed translated; the dialog's name. */\n title: string;\n /** A line under it. */\n description?: string;\n /** The two people: avatar URLs and names. */\n people: readonly [{ src?: string | null; name: string }, { src?: string | null; name: string }];\n /** The main action (“Send a message”). */\n primaryLabel: string;\n /** What it does. */\n onPrimary: () => void;\n /** The way back (“Keep swiping”). */\n secondaryLabel: string;\n /** Where it is drawn (the page's body by default): give an element inside a brand scope (`.brand-…`) so the dialog wears the brand too. */\n container?: HTMLElement | null;\n};\n\n/** Two people choose each other: the avatars meet at a heart in the brand gradient, the next step under them. */\nexport function MatchDialog({ open, onOpenChange, title, description, people, primaryLabel, onPrimary, secondaryLabel, container }: MatchDialogProps) {\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Content hideClose size=\"sm\" container={container} className=\"overflow-hidden border-0 bg-gradient-to-br from-accent to-accent-2 text-center text-on-accent\">\n <style href=\"krizaka-match\" precedence=\"default\">\n {\"@media (prefers-reduced-motion:no-preference){[data-kz-match] [data-side=a]{animation:kz-match-a .55s cubic-bezier(.3,1.6,.5,1) both}[data-kz-match] [data-side=b]{animation:kz-match-b .55s cubic-bezier(.3,1.6,.5,1) both}[data-kz-match] [data-heart]{animation:kz-match-heart .45s .25s cubic-bezier(.3,1.6,.5,1) both}}@keyframes kz-match-a{from{transform:translateX(-60px) rotate(-8deg);opacity:0}}@keyframes kz-match-b{from{transform:translateX(60px) rotate(8deg);opacity:0}}@keyframes kz-match-heart{from{transform:scale(0)}}\"}\n </style>\n <div data-kz-match=\"\" className=\"flex flex-col items-center gap-3 px-2 pb-2 pt-6\">\n <Dialog.Title className=\"font-display text-4xl font-black text-on-accent\">{title}</Dialog.Title>\n {description ? <Dialog.Description className=\"max-w-xs text-sm text-on-accent\">{description}</Dialog.Description> : null}\n <div className=\"relative my-6 flex h-36 w-64 items-center justify-center\" aria-hidden>\n <span data-side=\"a\" className=\"absolute left-6 -rotate-6 rounded-full ring-4 ring-on-accent\">\n <Avatar src={people[0].src ?? null} alt=\"\" fallback={people[0].name.charAt(0)} className=\"h-28 w-28 text-3xl\" />\n </span>\n <span data-side=\"b\" className=\"absolute right-6 rotate-6 rounded-full ring-4 ring-on-accent\">\n <Avatar src={people[1].src ?? null} alt=\"\" fallback={people[1].name.charAt(0)} className=\"h-28 w-28 text-3xl\" />\n </span>\n <span data-heart=\"\" className=\"absolute -bottom-1 flex h-12 w-12 items-center justify-center rounded-full bg-on-accent text-accent shadow-lg\">\n <svg viewBox=\"0 0 24 24\" className=\"h-6 w-6\" fill=\"currentColor\">\n <path d=\"M12 20s-7-4.4-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.6-7 10-7 10z\" />\n </svg>\n </span>\n </div>\n <div className=\"flex w-full flex-col gap-2\">\n <Button\n size=\"lg\"\n onClick={() => {\n onOpenChange(false);\n onPrimary();\n }}\n >\n {primaryLabel}\n </Button>\n <Dialog.Close asChild>\n <Button size=\"lg\" variant=\"ghost\" className=\"text-on-accent hover:bg-on-accent/15\">\n {secondaryLabel}\n </Button>\n </Dialog.Close>\n </div>\n </div>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AAEA,SAAS,UAAU,uBAAuB;AAE1C,SAAS,UAA6B;;;ACAtC,YAAY,WAAW;AAGhB,SAAS,eAAe,kBAA2C;AACxE,QAAM,CAAC,MAAM,IAAU,eAAyB,MAAO,OAAO,aAAa,cAAc,OAAO,SAAS,aAAc;AACvH,SAAa;AAAA,IACX,CAAC,UAAiB;AAChB,yBAAmB,KAAK;AACxB,UAAI,MAAM,iBAAkB;AAC5B,UAAI,kBAAkB,eAAe,WAAW,SAAS,QAAQ,OAAO,aAAa;AACnF,cAAM,eAAe;AACrB,eAAO,MAAM;AAAA,MACf;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,gBAAgB;AAAA,EAC3B;AACF;;;AD0BM,cA+DA,YA/DA;AArCC,IAAM,SAAS,GAAG;AAAA,EACvB,OAAO;AAAA,IACL,SAAS;AAAA,IACT,SACE;AAAA,IACF,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,QACE;AAAA,EACJ;AAAA,EACA,UAAU;AAAA,IACR,WAAW;AAAA,MACT,QAAQ,EAAE,SAAS,kGAAkG;AAAA;AAAA,MAErH,QAAQ;AAAA,QACN,SACE;AAAA,MAEJ;AAAA,MACA,OAAO,EAAE,SAAS,8EAA8E;AAAA;AAAA,MAEhG,MAAM,EAAE,SAAS,4GAA4G;AAAA,IAC/H;AAAA,IACA,MAAM,EAAE,IAAI,EAAE,SAAS,cAAc,GAAG,IAAI,EAAE,SAAS,cAAc,GAAG,IAAI,EAAE,SAAS,eAAe,EAAE;AAAA,EAC1G;AAAA,EACA,iBAAiB,EAAE,WAAW,UAAU,MAAM,KAAK;AACrD,CAAC;AACD,IAAM,IAAI,OAAO;AAIjB,SAAS,YAAY;AACnB,SACE,oBAAC,SAAI,SAAQ,aAAY,WAAU,WAAU,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,eAAW,MAC9H,8BAAC,UAAK,GAAE,wBAAuB,GACjC;AAEJ;AAkCA,IAAM,UAAU,CAAC,UAAiB,MAAM,eAAe;AAGvD,SAAS,mBAAmB,EAAE,kBAAkB,GAAG,MAAM,GAAyD;AAChH,SAAO,oBAAC,gBAAgB,SAAhB,EAAwB,kBAAkB,eAAe,gBAAgB,GAAI,GAAG,OAAO;AACjG;AAGO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAuB;AACrB,QAAM,IAAI,OAAO,EAAE,WAAW,KAAK,CAAC;AACpC,SACE,qBAAC,gBAAgB,QAAhB,EAAuB,WACtB;AAAA,wBAAC,gBAAgB,SAAhB,EAAwB,WAAW,EAAE,QAAQ,GAAG;AAAA,IACjD;AAAA,MAAC;AAAA;AAAA,QACC,kBAAgB,aAAa;AAAA,QAC7B,oBAAkB,cAAc,SAAY;AAAA,QAC5C,WAAW,EAAE,QAAQ,EAAE,UAAU,CAAC;AAAA,QAClC,iBAAiB,cAAc,kBAAkB,MAAM,iBAAiB,OAAO;AAAA,QAC/E,sBAAsB,cAAc,uBAAuB,MAAM,sBAAsB,OAAO;AAAA,QAC9F,mBAAmB,cAAc,oBAAoB,MAAM,mBAAmB,OAAO;AAAA,QACpF,GAAG;AAAA,QAEH;AAAA;AAAA,UACA,CAAC,aACA,oBAAC,gBAAgB,OAAhB,EAAsB,SAAO,MAC5B,8BAAC,cAAW,OAAO,YAAsB,SAAQ,SAAQ,OAAM,QAAO,WAAW,EAAE,MAAM,GACvF,8BAAC,aAAU,GACb,GACF;AAAA;AAAA;AAAA,IAEJ;AAAA,KACF;AAEJ;AAEA,SAAS,MAAuB,SAA2C,MAA0B;AACnG,SAAO,CAAC,UAAa;AACnB,cAAU,KAAK;AACf,SAAK,KAAK;AAAA,EACZ;AACF;AAEO,SAAS,aAAa,EAAE,WAAW,GAAG,MAAM,GAAgC;AACjF,SAAO,oBAAC,SAAI,WAAW,EAAE,OAAO,EAAE,UAAU,CAAC,GAAI,GAAG,OAAO;AAC7D;AAEO,SAAS,YAAY,EAAE,WAAW,GAAG,MAAM,GAAuD;AACvG,SAAO,oBAAC,gBAAgB,OAAhB,EAAsB,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,GAAI,GAAG,OAAO;AAC9E;AAEO,SAAS,kBAAkB,EAAE,WAAW,GAAG,MAAM,GAA6D;AACnH,SAAO,oBAAC,gBAAgB,aAAhB,EAA4B,WAAW,EAAE,YAAY,EAAE,UAAU,CAAC,GAAI,GAAG,OAAO;AAC1F;AAEO,SAAS,WAAW,EAAE,WAAW,GAAG,MAAM,GAAgC;AAC/E,SAAO,oBAAC,SAAI,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC,GAAI,GAAG,OAAO;AAC3D;AAEO,SAAS,aAAa,EAAE,WAAW,GAAG,MAAM,GAAgC;AACjF,SAAO,oBAAC,SAAI,WAAW,EAAE,OAAO,EAAE,UAAU,CAAC,GAAI,GAAG,OAAO;AAC7D;AAGO,IAAM,SAAS;AAAA,EACpB,MAAM,gBAAgB;AAAA,EACtB,SAAS,gBAAgB;AAAA,EACzB,OAAO,gBAAgB;AAAA,EACvB,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,aAAa;AAAA,EACb,MAAM;AAAA,EACN,QAAQ;AACV;;;AEvIQ,gBAAAA,MAME,QAAAC,aANF;AAJD,SAAS,YAAY,EAAE,MAAM,cAAc,OAAO,aAAa,QAAQ,cAAc,WAAW,gBAAgB,UAAU,GAAqB;AACpJ,SACE,gBAAAD,KAAC,OAAO,MAAP,EAAY,MAAY,cACvB,0BAAAC,MAAC,OAAO,SAAP,EAAe,WAAS,MAAC,MAAK,MAAK,WAAsB,WAAU,iGAClE;AAAA,oBAAAD,KAAC,WAAM,MAAK,iBAAgB,YAAW,WACpC,2hBACH;AAAA,IACA,gBAAAC,MAAC,SAAI,iBAAc,IAAG,WAAU,mDAC9B;AAAA,sBAAAD,KAAC,OAAO,OAAP,EAAa,WAAU,mDAAmD,iBAAM;AAAA,MAChF,cAAc,gBAAAA,KAAC,OAAO,aAAP,EAAmB,WAAU,mCAAmC,uBAAY,IAAwB;AAAA,MACpH,gBAAAC,MAAC,SAAI,WAAU,4DAA2D,eAAW,MACnF;AAAA,wBAAAD,KAAC,UAAK,aAAU,KAAI,WAAU,gEAC5B,0BAAAA,KAAC,UAAO,KAAK,OAAO,CAAC,EAAE,OAAO,MAAM,KAAI,IAAG,UAAU,OAAO,CAAC,EAAE,KAAK,OAAO,CAAC,GAAG,WAAU,sBAAqB,GAChH;AAAA,QACA,gBAAAA,KAAC,UAAK,aAAU,KAAI,WAAU,gEAC5B,0BAAAA,KAAC,UAAO,KAAK,OAAO,CAAC,EAAE,OAAO,MAAM,KAAI,IAAG,UAAU,OAAO,CAAC,EAAE,KAAK,OAAO,CAAC,GAAG,WAAU,sBAAqB,GAChH;AAAA,QACA,gBAAAA,KAAC,UAAK,cAAW,IAAG,WAAU,iHAC5B,0BAAAA,KAAC,SAAI,SAAQ,aAAY,WAAU,WAAU,MAAK,gBAChD,0BAAAA,KAAC,UAAK,GAAE,uEAAsE,GAChF,GACF;AAAA,SACF;AAAA,MACA,gBAAAC,MAAC,SAAI,WAAU,8BACb;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS,MAAM;AACb,2BAAa,KAAK;AAClB,wBAAU;AAAA,YACZ;AAAA,YAEC;AAAA;AAAA,QACH;AAAA,QACA,gBAAAA,KAAC,OAAO,OAAP,EAAa,SAAO,MACnB,0BAAAA,KAAC,UAAO,MAAK,MAAK,SAAQ,SAAQ,WAAU,wCACzC,0BACH,GACF;AAAA,SACF;AAAA,OACF;AAAA,KACF,GACF;AAEJ;","names":["jsx","jsxs"]}
@@ -35,11 +35,28 @@ type LinkComponent = React.ElementType<{
35
35
  "aria-describedby"?: string;
36
36
  }>;
37
37
 
38
+ interface SectionHintProps {
39
+ /** The button's accessible name, passed translated (“What are Shorts?”). */
40
+ label: string;
41
+ /** The definition, in one line. */
42
+ text: string;
43
+ /** A link to the full definition (the glossary). */
44
+ link?: {
45
+ href: string;
46
+ label: string;
47
+ linkAs?: LinkComponent;
48
+ };
49
+ }
50
+ /** The definition of a section, one tap away from its heading. */
51
+ declare function SectionHint({ label, text, link }: SectionHintProps): React.JSX.Element;
52
+
38
53
  interface ShortsShelfProps<T> extends Omit<React.ComponentProps<"section">, "children" | "title"> {
39
54
  /** The shelf's accessible name ("Shorts"), passed translated; shown as its heading unless `title` is set. */
40
55
  label: string;
41
56
  /** A heading different from the name. */
42
57
  title?: React.ReactNode;
58
+ /** A small “i” beside the heading: the one-line definition of the section and a link to the glossary. */
59
+ hint?: SectionHintProps;
43
60
  /** The clips, in order. */
44
61
  items: readonly T[];
45
62
  /** A stable key for an item. */
@@ -58,7 +75,7 @@ interface ShortsShelfProps<T> extends Omit<React.ComponentProps<"section">, "chi
58
75
  nextLabel: string;
59
76
  }
60
77
  /** A Shorts shelf: equal-height 9:16 cards in a snap-scrolling row. */
61
- declare function ShortsShelf<T>({ label, title, items, getId, renderItem, seeAll, previousLabel, nextLabel, className, ...props }: ShortsShelfProps<T>): React.JSX.Element | null;
78
+ declare function ShortsShelf<T>({ label, title, hint, items, getId, renderItem, seeAll, previousLabel, nextLabel, className, ...props }: ShortsShelfProps<T>): React.JSX.Element | null;
62
79
 
63
80
  type DefaultAvatarBrand = "krizaka" | "orazaka" | "orochia" | "yasakia" | "yororis" | "yomizaka" | "kachizaka" | "akinaza";
64
81
  /** `person`: a neutral silhouette. `plain`: the brand's gradient alone, ready for initials. */
@@ -178,10 +195,15 @@ interface MediaGridProps<T> extends Omit<React.ComponentProps<"div">, "children"
178
195
  /** `grid` or `list` (one row per video). @default "grid" */
179
196
  layout?: "grid" | "list";
180
197
  /** The shelf of `split`: its name, "See all" and arrows, passed translated. */
181
- shelf: Pick<ShortsShelfProps<unknown>, "label" | "title" | "seeAll" | "previousLabel" | "nextLabel">;
198
+ shelf: Pick<ShortsShelfProps<unknown>, "label" | "title" | "hint" | "seeAll" | "previousLabel" | "nextLabel">;
199
+ /** A heading for the grid of the others (“Videos”), in the style of the shelf's, with an optional definition. */
200
+ grid?: {
201
+ label: string;
202
+ hint?: SectionHintProps;
203
+ };
182
204
  }
183
205
  /** A media grid that never mixes heights badly: a shelf for the 9:16, a uniform grid for the rest. */
184
- declare function MediaGrid<T>({ items, getId, orientationOf, renderItem, mode, frame, layout, shelf, className, ...props }: MediaGridProps<T>): React.JSX.Element;
206
+ declare function MediaGrid<T>({ items, getId, orientationOf, renderItem, mode, frame, layout, shelf, grid, className, ...props }: MediaGridProps<T>): React.JSX.Element;
185
207
 
186
208
  interface VideoCardSkeletonProps extends React.ComponentProps<"div"> {
187
209
  /** `landscape` (16:9) or `portrait` (9:16), as the card it stands for. @default "landscape" */
@@ -206,4 +228,4 @@ interface MediaGridSkeletonProps extends Omit<React.ComponentProps<"div">, "chil
206
228
  /** The placeholder of a `MediaGrid`: the same shelf and grid, skeleton cards, one polite announcement. */
207
229
  declare function MediaGridSkeleton({ label, count, shelfCount, layout, frame, className, ...props }: MediaGridSkeletonProps): React.JSX.Element;
208
230
 
209
- export { LoadMore, type LoadMoreProps, MediaGrid, type MediaGridProps, MediaGridSkeleton, type MediaGridSkeletonProps, type MediaGridState, ShortsShelf, type ShortsShelfProps, VideoCard, type VideoCardAspect, type VideoCardCreator, type VideoCardProps, VideoCardSkeleton, type VideoCardSkeletonProps };
231
+ export { LoadMore, type LoadMoreProps, MediaGrid, type MediaGridProps, MediaGridSkeleton, type MediaGridSkeletonProps, type MediaGridState, SectionHint, type SectionHintProps, ShortsShelf, type ShortsShelfProps, VideoCard, type VideoCardAspect, type VideoCardCreator, type VideoCardProps, VideoCardSkeleton, type VideoCardSkeletonProps };