@krizaka/ui 2.6.0 → 2.9.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 (331) hide show
  1. package/README.md +37 -4
  2. package/dist/achievement.d.ts +54 -0
  3. package/dist/achievement.js +73 -0
  4. package/dist/achievement.js.map +1 -0
  5. package/dist/app-shell.d.ts +203 -0
  6. package/dist/app-shell.js +137 -0
  7. package/dist/app-shell.js.map +1 -0
  8. package/dist/auth-layout.d.ts +136 -0
  9. package/dist/auth-layout.js +75 -0
  10. package/dist/auth-layout.js.map +1 -0
  11. package/dist/choice-grid.d.ts +84 -0
  12. package/dist/choice-grid.js +141 -0
  13. package/dist/choice-grid.js.map +1 -0
  14. package/dist/chunk-555LWYIN.js +11 -0
  15. package/dist/chunk-555LWYIN.js.map +1 -0
  16. package/dist/chunk-AZPKXP3O.js +36 -0
  17. package/dist/chunk-AZPKXP3O.js.map +1 -0
  18. package/dist/chunk-NOVUREEC.js +274 -0
  19. package/dist/chunk-NOVUREEC.js.map +1 -0
  20. package/dist/chunk-VCAAHCHL.js +17 -0
  21. package/dist/chunk-VCAAHCHL.js.map +1 -0
  22. package/dist/code-block.js +23 -44
  23. package/dist/code-block.js.map +1 -1
  24. package/dist/continue-prompt.d.ts +48 -0
  25. package/dist/continue-prompt.js +200 -0
  26. package/dist/continue-prompt.js.map +1 -0
  27. package/dist/dashboard-layout.d.ts +139 -0
  28. package/dist/dashboard-layout.js +68 -0
  29. package/dist/dashboard-layout.js.map +1 -0
  30. package/dist/detail-layout.d.ts +126 -0
  31. package/dist/detail-layout.js +48 -0
  32. package/dist/detail-layout.js.map +1 -0
  33. package/dist/docs-layout.d.ts +78 -0
  34. package/dist/docs-layout.js +60 -0
  35. package/dist/docs-layout.js.map +1 -0
  36. package/dist/geometry-CXrAW34x.d.ts +19 -0
  37. package/dist/goal-gauge.d.ts +38 -0
  38. package/dist/goal-gauge.js +53 -0
  39. package/dist/goal-gauge.js.map +1 -0
  40. package/dist/index.d.ts +11 -2
  41. package/dist/index.js +89 -4
  42. package/dist/index.js.map +1 -1
  43. package/dist/landscape.d.ts +41 -0
  44. package/dist/landscape.js +836 -0
  45. package/dist/landscape.js.map +1 -0
  46. package/dist/marketing-layout.d.ts +60 -0
  47. package/dist/marketing-layout.js +25 -0
  48. package/dist/marketing-layout.js.map +1 -0
  49. package/dist/mascot-quote.d.ts +4 -3
  50. package/dist/mascot-quote.js +21 -1
  51. package/dist/mascot-quote.js.map +1 -1
  52. package/dist/mascot-state.d.ts +128 -0
  53. package/dist/mascot-state.js +95 -0
  54. package/dist/mascot-state.js.map +1 -0
  55. package/dist/mascots.d.ts +18 -20
  56. package/dist/mascots.js +65 -221
  57. package/dist/mascots.js.map +1 -1
  58. package/dist/native.d.ts +124 -7
  59. package/dist/native.js +641 -239
  60. package/dist/native.js.map +1 -1
  61. package/dist/profile-card.d.ts +85 -0
  62. package/dist/profile-card.js +87 -0
  63. package/dist/profile-card.js.map +1 -0
  64. package/dist/promise-card.d.ts +28 -0
  65. package/dist/promise-card.js +29 -0
  66. package/dist/promise-card.js.map +1 -0
  67. package/dist/scroll-stage.d.ts +603 -0
  68. package/dist/scroll-stage.js +59 -0
  69. package/dist/scroll-stage.js.map +1 -0
  70. package/dist/settings-layout.d.ts +154 -0
  71. package/dist/settings-layout.js +57 -0
  72. package/dist/settings-layout.js.map +1 -0
  73. package/dist/split-view.d.ts +106 -0
  74. package/dist/split-view.js +41 -0
  75. package/dist/split-view.js.map +1 -0
  76. package/dist/stage-banner.d.ts +34 -0
  77. package/dist/stage-banner.js +26 -0
  78. package/dist/stage-banner.js.map +1 -0
  79. package/dist/story-variant-CLn4H5Nt.d.ts +4 -0
  80. package/dist/story.css +432 -0
  81. package/package.json +267 -10
  82. package/registry/achievement.json +322 -0
  83. package/registry/action-bar.json +1 -1
  84. package/registry/alert.json +1 -1
  85. package/registry/app-shell.json +451 -0
  86. package/registry/argument-card.json +1 -1
  87. package/registry/audio-player.json +1 -1
  88. package/registry/auth-layout.json +230 -0
  89. package/registry/avatar.json +1 -1
  90. package/registry/badge.json +1 -1
  91. package/registry/button.json +5 -5
  92. package/registry/card-grid.json +5 -5
  93. package/registry/card.json +3 -3
  94. package/registry/checkbox.json +1 -1
  95. package/registry/chip-link.json +1 -1
  96. package/registry/chip.json +1 -1
  97. package/registry/choice-grid.json +318 -0
  98. package/registry/code-block.json +1 -1
  99. package/registry/combobox.json +1 -1
  100. package/registry/command.json +1 -1
  101. package/registry/confirm-button.json +3 -3
  102. package/registry/continue-prompt.json +312 -0
  103. package/registry/countdown.json +1 -1
  104. package/registry/cta-panel.json +1 -1
  105. package/registry/dashboard-layout.json +273 -0
  106. package/registry/data-table.json +1 -1
  107. package/registry/date-picker.json +1 -1
  108. package/registry/decision-list.json +1 -1
  109. package/registry/detail-layout.json +233 -0
  110. package/registry/dialog.json +1 -1
  111. package/registry/docs-layout.json +148 -0
  112. package/registry/dropdown-menu.json +3 -3
  113. package/registry/empty-state.json +1 -1
  114. package/registry/examples/achievement/arcade.d.ts +4 -0
  115. package/registry/examples/achievement/arcade.js +15 -0
  116. package/registry/examples/achievement/arcade.tsx +12 -0
  117. package/registry/examples/achievement/milestones.d.ts +4 -0
  118. package/registry/examples/achievement/milestones.js +15 -0
  119. package/registry/examples/achievement/milestones.tsx +12 -0
  120. package/registry/examples/app-shell/admin-console.d.ts +4 -0
  121. package/registry/examples/app-shell/admin-console.js +52 -0
  122. package/registry/examples/app-shell/admin-console.tsx +64 -0
  123. package/registry/examples/app-shell/basic.d.ts +4 -0
  124. package/registry/examples/app-shell/basic.js +37 -0
  125. package/registry/examples/app-shell/basic.tsx +31 -0
  126. package/registry/examples/app-shell/orochia-studio.d.ts +4 -0
  127. package/registry/examples/app-shell/orochia-studio.js +89 -0
  128. package/registry/examples/app-shell/orochia-studio.tsx +101 -0
  129. package/registry/examples/auth-layout/onboarding.d.ts +4 -0
  130. package/registry/examples/auth-layout/onboarding.js +56 -0
  131. package/registry/examples/auth-layout/onboarding.tsx +47 -0
  132. package/registry/examples/auth-layout/sign-in.d.ts +4 -0
  133. package/registry/examples/auth-layout/sign-in.js +55 -0
  134. package/registry/examples/auth-layout/sign-in.tsx +47 -0
  135. package/registry/examples/auth-layout/verify.d.ts +4 -0
  136. package/registry/examples/auth-layout/verify.js +23 -0
  137. package/registry/examples/auth-layout/verify.tsx +19 -0
  138. package/registry/examples/choice-grid/line-up.d.ts +4 -0
  139. package/registry/examples/choice-grid/line-up.js +37 -0
  140. package/registry/examples/choice-grid/line-up.tsx +32 -0
  141. package/registry/examples/choice-grid/plans.d.ts +4 -0
  142. package/registry/examples/choice-grid/plans.js +28 -0
  143. package/registry/examples/choice-grid/plans.tsx +24 -0
  144. package/registry/examples/continue-prompt/arcade.d.ts +4 -0
  145. package/registry/examples/continue-prompt/arcade.js +28 -0
  146. package/registry/examples/continue-prompt/arcade.tsx +25 -0
  147. package/registry/examples/continue-prompt/offer.d.ts +4 -0
  148. package/registry/examples/continue-prompt/offer.js +24 -0
  149. package/registry/examples/continue-prompt/offer.tsx +19 -0
  150. package/registry/examples/dashboard-layout/orazaka-eric.d.ts +4 -0
  151. package/registry/examples/dashboard-layout/orazaka-eric.js +58 -0
  152. package/registry/examples/dashboard-layout/orazaka-eric.tsx +80 -0
  153. package/registry/examples/dashboard-layout/widgets.d.ts +4 -0
  154. package/registry/examples/dashboard-layout/widgets.js +17 -0
  155. package/registry/examples/dashboard-layout/widgets.tsx +22 -0
  156. package/registry/examples/detail-layout/job.d.ts +4 -0
  157. package/registry/examples/detail-layout/job.js +25 -0
  158. package/registry/examples/detail-layout/job.tsx +20 -0
  159. package/registry/examples/detail-layout/video.d.ts +4 -0
  160. package/registry/examples/detail-layout/video.js +44 -0
  161. package/registry/examples/detail-layout/video.tsx +53 -0
  162. package/registry/examples/docs-layout/page.d.ts +4 -0
  163. package/registry/examples/docs-layout/page.js +26 -0
  164. package/registry/examples/docs-layout/page.tsx +30 -0
  165. package/registry/examples/goal-gauge/arcade.d.ts +4 -0
  166. package/registry/examples/goal-gauge/arcade.js +11 -0
  167. package/registry/examples/goal-gauge/arcade.tsx +10 -0
  168. package/registry/examples/goal-gauge/challenge.d.ts +4 -0
  169. package/registry/examples/goal-gauge/challenge.js +11 -0
  170. package/registry/examples/goal-gauge/challenge.tsx +10 -0
  171. package/registry/examples/goal-gauge/drain.d.ts +4 -0
  172. package/registry/examples/goal-gauge/drain.js +11 -0
  173. package/registry/examples/goal-gauge/drain.tsx +10 -0
  174. package/registry/examples/goal-gauge/native/default.d.ts +4 -0
  175. package/registry/examples/goal-gauge/native/default.dark.png +0 -0
  176. package/registry/examples/goal-gauge/native/default.js +15 -0
  177. package/registry/examples/goal-gauge/native/default.light.png +0 -0
  178. package/registry/examples/goal-gauge/native/default.tsx +12 -0
  179. package/registry/examples/landscape/backdrop.d.ts +4 -0
  180. package/registry/examples/landscape/backdrop.js +14 -0
  181. package/registry/examples/landscape/backdrop.tsx +11 -0
  182. package/registry/examples/landscape/brand.d.ts +4 -0
  183. package/registry/examples/landscape/brand.js +11 -0
  184. package/registry/examples/landscape/brand.tsx +10 -0
  185. package/registry/examples/marketing-layout/basic.d.ts +4 -0
  186. package/registry/examples/marketing-layout/basic.js +31 -0
  187. package/registry/examples/marketing-layout/basic.tsx +28 -0
  188. package/registry/examples/marketing-layout/docs-hub.d.ts +4 -0
  189. package/registry/examples/marketing-layout/docs-hub.js +37 -0
  190. package/registry/examples/marketing-layout/docs-hub.tsx +44 -0
  191. package/registry/examples/marketing-layout/pricing.d.ts +4 -0
  192. package/registry/examples/marketing-layout/pricing.js +45 -0
  193. package/registry/examples/marketing-layout/pricing.tsx +55 -0
  194. package/registry/examples/marketing-layout/product-page.d.ts +4 -0
  195. package/registry/examples/marketing-layout/product-page.js +79 -0
  196. package/registry/examples/marketing-layout/product-page.tsx +83 -0
  197. package/registry/examples/mascot-state/empty.d.ts +4 -0
  198. package/registry/examples/mascot-state/empty.js +22 -0
  199. package/registry/examples/mascot-state/empty.tsx +20 -0
  200. package/registry/examples/mascot-state/error.d.ts +4 -0
  201. package/registry/examples/mascot-state/error.js +23 -0
  202. package/registry/examples/mascot-state/error.tsx +21 -0
  203. package/registry/examples/mascot-state/loading.d.ts +4 -0
  204. package/registry/examples/mascot-state/loading.js +22 -0
  205. package/registry/examples/mascot-state/loading.tsx +16 -0
  206. package/registry/examples/mascot-state/native/default.d.ts +4 -0
  207. package/registry/examples/mascot-state/native/default.dark.png +0 -0
  208. package/registry/examples/mascot-state/native/default.js +25 -0
  209. package/registry/examples/mascot-state/native/default.light.png +0 -0
  210. package/registry/examples/mascot-state/native/default.tsx +19 -0
  211. package/registry/examples/mascot-state/success.d.ts +4 -0
  212. package/registry/examples/mascot-state/success.js +21 -0
  213. package/registry/examples/mascot-state/success.tsx +19 -0
  214. package/registry/examples/mascot-state/welcome.d.ts +4 -0
  215. package/registry/examples/mascot-state/welcome.js +21 -0
  216. package/registry/examples/mascot-state/welcome.tsx +19 -0
  217. package/registry/examples/mascots/flock.tsx +1 -1
  218. package/registry/examples/mascots/lovebird.d.ts +4 -0
  219. package/registry/examples/mascots/lovebird.js +19 -0
  220. package/registry/examples/mascots/lovebird.tsx +18 -0
  221. package/registry/examples/mascots/native/lovebird.d.ts +4 -0
  222. package/registry/examples/mascots/native/lovebird.dark.png +0 -0
  223. package/registry/examples/mascots/native/lovebird.js +21 -0
  224. package/registry/examples/mascots/native/lovebird.light.png +0 -0
  225. package/registry/examples/mascots/native/lovebird.tsx +18 -0
  226. package/registry/examples/mascots/native/phoenix.d.ts +4 -0
  227. package/registry/examples/mascots/native/phoenix.dark.png +0 -0
  228. package/registry/examples/mascots/native/phoenix.js +21 -0
  229. package/registry/examples/mascots/native/phoenix.light.png +0 -0
  230. package/registry/examples/mascots/native/phoenix.tsx +18 -0
  231. package/registry/examples/mascots/phoenix.d.ts +4 -0
  232. package/registry/examples/mascots/phoenix.js +14 -0
  233. package/registry/examples/mascots/phoenix.tsx +11 -0
  234. package/registry/examples/profile-card/arcade.d.ts +4 -0
  235. package/registry/examples/profile-card/arcade.js +25 -0
  236. package/registry/examples/profile-card/arcade.tsx +19 -0
  237. package/registry/examples/profile-card/creator.d.ts +4 -0
  238. package/registry/examples/profile-card/creator.js +31 -0
  239. package/registry/examples/profile-card/creator.tsx +26 -0
  240. package/registry/examples/profile-card/match.d.ts +4 -0
  241. package/registry/examples/profile-card/match.js +25 -0
  242. package/registry/examples/profile-card/match.tsx +19 -0
  243. package/registry/examples/profile-card/native/default.d.ts +4 -0
  244. package/registry/examples/profile-card/native/default.dark.png +0 -0
  245. package/registry/examples/profile-card/native/default.js +27 -0
  246. package/registry/examples/profile-card/native/default.light.png +0 -0
  247. package/registry/examples/profile-card/native/default.tsx +22 -0
  248. package/registry/examples/promise-card/arcade.d.ts +4 -0
  249. package/registry/examples/promise-card/arcade.js +25 -0
  250. package/registry/examples/promise-card/arcade.tsx +19 -0
  251. package/registry/examples/promise-card/guarantee.d.ts +4 -0
  252. package/registry/examples/promise-card/guarantee.js +23 -0
  253. package/registry/examples/promise-card/guarantee.tsx +17 -0
  254. package/registry/examples/scroll-stage/arcade.d.ts +4 -0
  255. package/registry/examples/scroll-stage/arcade.js +16 -0
  256. package/registry/examples/scroll-stage/arcade.tsx +15 -0
  257. package/registry/examples/scroll-stage/chapters.d.ts +4 -0
  258. package/registry/examples/scroll-stage/chapters.js +25 -0
  259. package/registry/examples/scroll-stage/chapters.tsx +22 -0
  260. package/registry/examples/settings-layout/account.d.ts +4 -0
  261. package/registry/examples/settings-layout/account.js +51 -0
  262. package/registry/examples/settings-layout/account.tsx +50 -0
  263. package/registry/examples/settings-layout/sections.d.ts +4 -0
  264. package/registry/examples/settings-layout/sections.js +27 -0
  265. package/registry/examples/settings-layout/sections.tsx +24 -0
  266. package/registry/examples/split-view/empty.d.ts +4 -0
  267. package/registry/examples/split-view/empty.js +19 -0
  268. package/registry/examples/split-view/empty.tsx +13 -0
  269. package/registry/examples/split-view/messages.d.ts +4 -0
  270. package/registry/examples/split-view/messages.js +49 -0
  271. package/registry/examples/split-view/messages.tsx +52 -0
  272. package/registry/examples/stage-banner/round.d.ts +4 -0
  273. package/registry/examples/stage-banner/round.js +14 -0
  274. package/registry/examples/stage-banner/round.tsx +11 -0
  275. package/registry/examples/stage-banner/steps.d.ts +4 -0
  276. package/registry/examples/stage-banner/steps.js +14 -0
  277. package/registry/examples/stage-banner/steps.tsx +11 -0
  278. package/registry/field.json +1 -1
  279. package/registry/file-upload.json +1 -1
  280. package/registry/filter-bar.json +1 -1
  281. package/registry/glow-card.json +1 -1
  282. package/registry/goal-gauge.json +322 -0
  283. package/registry/image-cropper.json +1 -1
  284. package/registry/index.json +337 -5
  285. package/registry/iso.json +1 -1
  286. package/registry/kbd.json +1 -1
  287. package/registry/landscape.json +189 -0
  288. package/registry/link-card.json +1 -1
  289. package/registry/loader.json +1 -1
  290. package/registry/marketing-layout.json +172 -0
  291. package/registry/marquee.json +1 -1
  292. package/registry/mascot-quote.json +6 -6
  293. package/registry/mascot-state.json +1249 -0
  294. package/registry/mascots.json +140 -23
  295. package/registry/media-capture.json +1 -1
  296. package/registry/meter.json +1 -1
  297. package/registry/nav-bar.json +1 -1
  298. package/registry/number-ticker.json +1 -1
  299. package/registry/page-header.json +1 -1
  300. package/registry/page-hero.json +3 -3
  301. package/registry/page.json +5 -5
  302. package/registry/pagination.json +1 -1
  303. package/registry/pointer-light.json +1 -1
  304. package/registry/popover.json +1 -1
  305. package/registry/profile-card.json +501 -0
  306. package/registry/progress.json +1 -1
  307. package/registry/promise-card.json +228 -0
  308. package/registry/radio-group.json +1 -1
  309. package/registry/scroll-stage.json +197 -0
  310. package/registry/search-field.json +1 -1
  311. package/registry/section-backdrop.json +1 -1
  312. package/registry/separator.json +1 -1
  313. package/registry/settings-layout.json +231 -0
  314. package/registry/skeleton.json +1 -1
  315. package/registry/slider.json +1 -1
  316. package/registry/slot.json +1 -1
  317. package/registry/spinner.json +1 -1
  318. package/registry/split-view.json +233 -0
  319. package/registry/stage-banner.json +221 -0
  320. package/registry/stat.json +1 -1
  321. package/registry/stepper.json +1 -1
  322. package/registry/switch.json +1 -1
  323. package/registry/tabs.json +1 -1
  324. package/registry/tag-input.json +1 -1
  325. package/registry/terminal-replay.json +1 -1
  326. package/registry/theme.json +1 -1
  327. package/registry/toast.json +1 -1
  328. package/registry/toc.json +1 -1
  329. package/registry/tooltip.json +1 -1
  330. package/registry/video-player.json +1 -1
  331. package/registry/video-trimmer.json +1 -1
package/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
 
10
10
  **The Krizaka front-end platform's components, shared by every product.**
11
11
  The primitives (button, badge, avatar, field, theme, countdown…) on the semantic `--kz-*` tokens, the animated marks
12
- of Krizaka, Orazaka and Orochia, and the Krizaka motion signature — one easing, one way to enter, reveal, roll, shine
12
+ of Krizaka, Orazaka, Orochia and Yazakia, and the Krizaka motion signature — one easing, one way to enter, reveal, roll, shine
13
13
  and open.
14
14
 
15
15
  [![npm](https://img.shields.io/npm/v/@krizaka/ui?color=196df5&label=npm)](https://www.npmjs.com/package/@krizaka/ui)
@@ -160,10 +160,19 @@ light or a product's — is a set of tokens.
160
160
  | `@krizaka/ui/stepper` | `Stepper` (`steps`: `title`, `description`, `status`, `value`, `content`; `current`, `labels` of the states, `orientation`) | server |
161
161
  | `@krizaka/ui/number-ticker` | `NumberTicker` (`value`, `locale`, `format`, `trigger` view·change, `duration`, `announce`, `align`) | client |
162
162
  | `@krizaka/ui/terminal-replay` | `TerminalReplay` (`steps` command + output lines with a tone, `label`, `title`, `prompt`, `playLabel`/`pauseLabel`/`replayLabel`, `copyLabel`/`copiedLabel`, `typingSpeed`, `lineDelay`, `stepDelay`, `rows`, `autoPlay`) | client |
163
+ | `@krizaka/ui/scroll-stage` | `ScrollStage` (`variant`, `threshold`, `as`) and `Scene` (`brand`, `as`): chapters played once as they scroll in, one loop each while on screen — the storytelling kit, styles in `@krizaka/ui/story.css` | client |
164
+ | `@krizaka/ui/choice-grid` | `ChoiceGrid` (`items` with `badge`/`eyebrow`/`extra`/`meta`/`href`, `label`, `tag`, `caption`, `prompt`, `value`/`defaultValue`/`onValueChange`, `linkAs`, `columns`, `variant`, `brand`): choices as tiles — a radio group when selectable, links with `href` | client |
165
+ | `@krizaka/ui/profile-card` | `ProfileCard` (`visual`, `name`, `statLabel`/`value`/`figure`, `stats`, `caption`, `variant`, `brand`): a profile at a glance; `StatGauge` (`label`, `value`, `max`, `valueText`, `figure`): one measured strength; native too | server |
166
+ | `@krizaka/ui/stage-banner` | `StageBanner` (`stage`, `name`, `size="lg"` with `title`/`subtitle`, `variant`) | server |
167
+ | `@krizaka/ui/goal-gauge` | `GoalGauge` (`label`, `segments`, `value`, `mode` fill · drain, `variant`): a goal in steps, a meter; native too | server |
168
+ | `@krizaka/ui/promise-card` | `PromiseCard` (`label`, `promise`, `keys`, `bearer`, `bearerLabel`, `bearerName`, `variant`): a promise, the keys that call it, who carries it | server |
169
+ | `@krizaka/ui/continue-prompt` | `ContinuePrompt` (`title`, `count`/`countdown`, children, `actionLabel`, `onAction`/`href`, `actionKey`, `highlight`, `hint`, `status`, `variant`) | server |
170
+ | `@krizaka/ui/achievement` | `Achievement` (`title`, `eyebrow`, `badge`, `replaced`, `locked`), `AchievementList`, `Emblem` (`sword` · `mirror` · `jewel`) | server |
171
+ | `@krizaka/ui/landscape` | `Landscape` (`tone` own · brand, `flock`, `phoenix`, `animated`, `position`, `fade`): the Krizaka valley at dusk, decorative | client |
163
172
  | `@krizaka/ui/glow-card` | `GlowCard` (`glow` border·spotlight·both, `alive`, `asChild`) | client |
164
173
  | `@krizaka/ui/marquee` | `Marquee` (`label`, `pauseLabel`, `playLabel`, `speed` px/s, `direction`, `fade`, `defaultPaused`) | client |
165
174
  | `@krizaka/ui/section-backdrop` | `SectionBackdrop` (`as`, `direction` down·up, `dome`, `grid`, `media` blurred for depth of field, `animated`): a page section on the brand's section gradient — see `@krizaka/tokens` BRAND.md, "Visual language" | server |
166
- | `@krizaka/ui/mascots` | `Mascot` (`bird` falcon·owl·duck·flamingo·pigeon, `mood` welcome·thinking·success·empty·error, `tone` brand·own, `size`, `animated`, `title`), `MASCOT_BIRDS`, `MASCOT_MOODS`: the Krizaka flock, in the host brand's accent — one bird at a moment that matters (onboarding, a long wait, a success, an empty list, an error); native `Mascot` in `/native` | client |
175
+ | `@krizaka/ui/mascots` | `Mascot` (`bird` falcon·owl·duck·flamingo·pigeon·lovebird, `mood` welcome·thinking·success·empty·error, `tone` brand·own, `size`, `animated`, `title`), `MASCOT_BIRDS`, `MASCOT_MOODS`: the Krizaka flock, in the host brand's accent — one bird at a moment that matters (onboarding, a long wait, a success, an empty list, an error); native `Mascot` in `/native` | client |
167
176
  | `@krizaka/ui/iso` | the isometric kit: `IsoHub` (a hero driven by data: `layers`, `dome`, `satellites`, `highlight`), `IsoScene`, `IsoPrism`, `IsoStack`, `IsoDome`, `IsoTile`, `IsoLink`, `IsoNode`, `IsoLabel`, the projection helpers — static SVG animated by motion.css | server |
168
177
  | `@krizaka/ui/motion` | `MotionObserver` (reveal, off-screen pause, settle, spotlight, magnetism) and `RotatingWord` (no layout shift) | client |
169
178
  | `@krizaka/ui/pagination` | `Pagination` (pages: `page`, `pageCount`, `onPageChange` or `getHref` for links; cursor: `hasPrevious`/`hasNext`, `onPrevious`/`onNext`; `status`, `pageSize` + `pageSizeOptions`, `siblings`, `boundaries`, `labels`; folds into "Page 3 of 12" in a narrow container), `pageRange` | server |
@@ -191,6 +200,14 @@ light or a product's — is a set of tokens.
191
200
  | `@krizaka/ui/action-bar` | `ActionBar` (`actions`: `href`, `label`, `icon`; `variant` buttons·icons — the words in a CSS tooltip —, `primaryFirst`, `size`, `label`, `linkAs`) | server |
192
201
  | `@krizaka/ui/cta-panel` | `CtaPanel` (`id`, `title`, `body`, the actions as children, `level`, `reveal`) | server |
193
202
  | `@krizaka/ui/toc` | `Toc` (`label`, `items`; the section being read marked), `TocLayout` (`toc`, the sections as children) | client |
203
+ | `@krizaka/ui/app-shell` | `AppShell.Root` (`defaultCollapsed`, `collapsed` + `onCollapsedChange`) `/Sidebar` (`label`, `brand`, `footer`, `collapseLabels`, `closeLabel`; a drawer on a phone) `/Group/Item` (`icon`, `label`, `current`, `badge`, `asChild`) `/Body/Header` (`title`, `menuLabel`, `actions`) `/Main` — see [Layouts and templates](#layouts-and-templates) | client |
204
+ | `@krizaka/ui/dashboard-layout` | `DashboardLayout` (`title`, `eyebrow`, `description`, `actions`, `toolbar`, `headingAs`), `Widget` (`title`, `description`, `action`, `span` 1·2·3·full, `level`) | server |
205
+ | `@krizaka/ui/settings-layout` | `SettingsLayout` (`title`, `description`, `nav`, `navLabel`, `linkAs`), `SettingsSection` (`title`, `description`, `footer`) | server |
206
+ | `@krizaka/ui/auth-layout` | `AuthLayout` (`brand`, `title`, `description`, `footer`, `legal`, `promise`, `aside`, `asideFooter`) | server |
207
+ | `@krizaka/ui/detail-layout` | `DetailLayout` (`back`, `media`, `eyebrow`, `title`, `status`, `meta`, `actions`, `tabs`, `aside`) | server |
208
+ | `@krizaka/ui/split-view` | `SplitView` (`listTitle`, `listActions`, `list`, `detailHead`, `detail`, `empty`, `showDetail`, `back`) | server |
209
+ | `@krizaka/ui/marketing-layout` | `MarketingLayout` (`header`, `footer`, `skipLabel`) | server |
210
+ | `@krizaka/ui/docs-layout` | `DocsLayout` (`sidebar`, `sidebarLabel`, `toc`) | server |
194
211
  | `@krizaka/ui/native/video-player` | React Native `VideoPlayer` on expo-video (optional peer) | native |
195
212
  | `@krizaka/ui/native/media-capture` | React Native `MediaCapture` on expo-camera (optional peer) | native |
196
213
  | `@krizaka/ui` | the marks, `MotionObserver`, `RotatingWord`, `cx` (unchanged) | client |
@@ -243,6 +260,21 @@ import { LinkCard } from "@krizaka/ui/link-card";
243
260
  - **Motion.** `reveal` uses `[data-reveal]` (MotionObserver): never on the first screen. The pointer's light, the lifts
244
261
  and the hops stop under `prefers-reduced-motion`; nothing loops.
245
262
 
263
+ ## Layouts and templates
264
+
265
+ > Category **layouts** of krizaka.com/docs/ui, and **templates**: whole screens composed from the platform.
266
+
267
+ The shells of the products' screens, read from their real screens (Orochia web, admin and mobile; Orazaka web-client,
268
+ web-admin and mobile; krizaka.com): `AppShell` (sidebar that collapses, header, drawer on a phone), `DashboardLayout`
269
+ (a grid of widgets), `SettingsLayout`, `AuthLayout`, `DetailLayout`, `SplitView`, and for a site `MarketingLayout` and
270
+ `DocsLayout`. Every layout is responsive by construction — one column, a drawer, chips or a disclosure on a phone.
271
+
272
+ A **template** is an example flagged `template: true` in its layout's `meta.ts` (≤ 160 lines): a complete screen with
273
+ real words — Orochia's creator studio, Orazaka's console for Eric, an administration console, sign-in, onboarding,
274
+ settings, a video's page, messages, a product page, pricing and credits, a documentation hub. Each has a phone story
275
+ (`parameters.phone`: captured at 390 × 844). Copy one into the product, keep its structure, change the words. The
276
+ React Native shells are `@krizaka/ui/native`'s (DS4): same names where the concept is the same.
277
+
246
278
  ## Registry — the code drives the documentation
247
279
 
248
280
  Every component is also published as data: **[krizaka.com/docs/ui](https://www.krizaka.com/docs/ui)** is generated
@@ -335,7 +367,7 @@ const { theme, scheme, mode, setMode, radius } = useTheme(); // theme.surface1,
335
367
  | `Segmented` | `options` (`value`, `label`, `disabled`), `value`, `onValueChange`, `size` | The web `Tabs variant="segmented"` (a tab list). To filter, `Chip.Group`. |
336
368
  | `Progress` | `variant` bar·ring, `size`, `value`/`max`, `label`, `valueText`, a ring's centre as children | The fill is the `accent` → `accent2` gradient (react-native-svg); it animates to each new value. |
337
369
  | `Toaster`, `toast` | `toast(title, { description, tone, icon, action, onPress, id, duration, onDismiss })`, `toast.success/warning/error/info`, `toast.dismiss(id?)`; `Toaster closeLabel position offset duration max` | No sonner: a light queue of its own. `offset` takes the safe-area inset (no safe-area dependency). |
338
- | `KrizakaMark`, `OrazakaMark`, `OrochiaMark`, `ProductMark` (`id`) | `size`, `animated`, `title`, `neutral` (default `theme.textMuted`) | The brand marks, drawn with react-native-svg from the web marks' geometry. |
370
+ | `KrizakaMark`, `OrazakaMark`, `OrochiaMark`, `YazakiaMark`, `ProductMark` (`id`) | `size`, `animated`, `title`, `neutral` (default `theme.textMuted`) | The brand marks, drawn with react-native-svg from the web marks' geometry. |
339
371
 
340
372
  Every animation (skeleton, badge dot, urgent countdown, progress, toast entrance, the marks) stops when the system
341
373
  asks to reduce motion (`useReducedMotion()`). Accessibility goes through `role` and `aria-*` (RN ≥ 0.71): headings,
@@ -365,11 +397,12 @@ Testing Library (`src/native/*.test.tsx`); `scripts/native-dist.mjs` checks that
365
397
  ## The marks
366
398
 
367
399
  ```tsx
368
- import { KrizakaLogo, OrazakaLogo, OrochiaLogo, ProductLogo } from "@krizaka/ui";
400
+ import { KrizakaLogo, OrazakaLogo, OrochiaLogo, ProductLogo, YazakiaLogo } from "@krizaka/ui";
369
401
 
370
402
  <OrochiaLogo size={36} /> // decorative (aria-hidden)
371
403
  <KrizakaLogo size={48} title="Krizaka" /> // an image with an accessible name
372
404
  <ProductLogo id="orazaka" animated={false} /> // by id, still
405
+ <YazakiaLogo size={32} /> // Yazakia: emerald → turquoise, two voices that meet
373
406
  ```
374
407
 
375
408
  Neutral strokes follow the host's `--kz-*` tokens when they exist (`--kz-border-strong`, `--kz-text-muted`…) and the
@@ -0,0 +1,54 @@
1
+ import * as React from 'react';
2
+ import { S as StoryVariant } from './story-variant-CLn4H5Nt.js';
3
+
4
+ type AchievementProps = Omit<React.HTMLAttributes<HTMLDivElement>, "title"> & {
5
+ /** What was achieved: the outcome, in a few words. */
6
+ title: React.ReactNode;
7
+ /** A small line above: its number, its kind (“Milestone 03”). */
8
+ eyebrow?: React.ReactNode;
9
+ /** A glyph before the eyebrow (an `Emblem`, an icon). Decorative. */
10
+ icon?: React.ReactNode;
11
+ /** The badge in the corner (“Done”, “Unlocked”, arcade “Sealed”). */
12
+ badge?: React.ReactNode;
13
+ /** What it replaced or overcame, struck through above the title (“Paying 30 % to a platform”). */
14
+ replaced?: React.ReactNode;
15
+ /** Not reached yet: muted, its badge neutral. Say it in the badge too (“Locked”). */
16
+ locked?: boolean;
17
+ /**
18
+ * `default`: a calm badge. `arcade`: a mono stamp that slams onto the card.
19
+ * @default "default"
20
+ */
21
+ variant?: StoryVariant;
22
+ /** A brand scope (`orochia` → `.brand-orochia`). */
23
+ brand?: string;
24
+ };
25
+ /** Something done: an eyebrow, a badge, what it replaced (struck through) and the outcome. */
26
+ declare function Achievement({ title, eyebrow, icon, badge, replaced, locked, variant, brand, className, ...props }: AchievementProps): React.JSX.Element;
27
+ type AchievementListProps = React.OlHTMLAttributes<HTMLOListElement> & {
28
+ /** The `Achievement`s, in order: each one becomes an item of the list (its badge arrives after the previous one's). */
29
+ children: React.ReactNode;
30
+ /**
31
+ * The narrowest a card gets before the grid drops a column.
32
+ * @default "220px"
33
+ */
34
+ minWidth?: string;
35
+ /** The look of every card: `default` or `arcade`. */
36
+ variant?: StoryVariant;
37
+ /** A brand scope (`orochia` → `.brand-orochia`). */
38
+ brand?: string;
39
+ };
40
+ /** An ordered list of `Achievement`s on one grid of hairlines. */
41
+ declare function AchievementList({ children, minWidth, variant, brand, className, style, ...props }: AchievementListProps): React.JSX.Element;
42
+ type EmblemProps = Omit<React.SVGProps<SVGSVGElement>, "children"> & {
43
+ /** The emblem: `sword` (courage, the first step), `mirror` (clarity, honesty), `jewel` (care, what is kept). */
44
+ kind: "sword" | "mirror" | "jewel";
45
+ /**
46
+ * Width and height in pixels.
47
+ * @default 20
48
+ */
49
+ size?: number;
50
+ };
51
+ /** Three line emblems for achievements and choices (`currentColor`, decorative). */
52
+ declare function Emblem({ kind, size, ...props }: EmblemProps): React.JSX.Element;
53
+
54
+ export { Achievement, AchievementList, type AchievementListProps, type AchievementProps, Emblem, type EmblemProps };
@@ -0,0 +1,73 @@
1
+ import {
2
+ brandClass,
3
+ cn,
4
+ storyVariantClass
5
+ } from "./chunk-VCAAHCHL.js";
6
+
7
+ // src/achievement/achievement.tsx
8
+ import * as React from "react";
9
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
+ function Achievement({ title, eyebrow, icon, badge, replaced, locked, variant, brand, className, ...props }) {
11
+ return /* @__PURE__ */ jsxs("div", { "data-locked": locked ? "" : void 0, className: cn("kzs-achievement", storyVariantClass(variant), brandClass(brand), className), ...props, children: [
12
+ (eyebrow || badge || icon) && /* @__PURE__ */ jsxs("div", { className: "kzs-achievement-head", children: [
13
+ /* @__PURE__ */ jsxs("span", { className: "kzs-achievement-eyebrow", children: [
14
+ icon && /* @__PURE__ */ jsx("span", { "aria-hidden": true, children: icon }),
15
+ eyebrow
16
+ ] }),
17
+ badge && /* @__PURE__ */ jsx("span", { className: "kzs-achievement-badge", children: badge })
18
+ ] }),
19
+ replaced && /* @__PURE__ */ jsx("del", { className: "kzs-achievement-replaced", style: { textDecorationLine: "line-through" }, children: replaced }),
20
+ /* @__PURE__ */ jsx("p", { className: "kzs-achievement-title", children: title })
21
+ ] });
22
+ }
23
+ function AchievementList({ children, minWidth, variant, brand, className, style, ...props }) {
24
+ const items = React.Children.toArray(children);
25
+ return /* @__PURE__ */ jsx(
26
+ "ol",
27
+ {
28
+ className: cn("kzs-achievements", storyVariantClass(variant), brandClass(brand), className),
29
+ style: minWidth ? { "--kzs-min": minWidth, ...style } : style,
30
+ ...props,
31
+ children: items.map((child, i) => /* @__PURE__ */ jsx("li", { style: { "--i": i }, children: child }, React.isValidElement(child) && child.key != null ? child.key : i))
32
+ }
33
+ );
34
+ }
35
+ function Emblem({ kind, size = 20, ...props }) {
36
+ return /* @__PURE__ */ jsxs(
37
+ "svg",
38
+ {
39
+ viewBox: "0 0 48 48",
40
+ width: size,
41
+ height: size,
42
+ fill: "none",
43
+ stroke: "currentColor",
44
+ strokeWidth: 2.4,
45
+ strokeLinecap: "round",
46
+ strokeLinejoin: "round",
47
+ "aria-hidden": true,
48
+ focusable: "false",
49
+ ...props,
50
+ children: [
51
+ kind === "sword" && /* @__PURE__ */ jsxs(Fragment, { children: [
52
+ /* @__PURE__ */ jsx("path", { d: "M24 3 L27 28 L24 36 L21 28 Z" }),
53
+ /* @__PURE__ */ jsx("path", { d: "M15 30 H33 M24 36 V45" })
54
+ ] }),
55
+ kind === "mirror" && /* @__PURE__ */ jsxs(Fragment, { children: [
56
+ /* @__PURE__ */ jsx("circle", { cx: "24", cy: "24", r: "17" }),
57
+ /* @__PURE__ */ jsx("circle", { cx: "24", cy: "24", r: "9" }),
58
+ /* @__PURE__ */ jsx("path", { d: "M24 2 V6 M24 42 V46 M2 24 H6 M42 24 H46" })
59
+ ] }),
60
+ kind === "jewel" && /* @__PURE__ */ jsxs(Fragment, { children: [
61
+ /* @__PURE__ */ jsx("path", { d: "M31 10 a13 13 0 1 1 -15 19 a8 8 0 0 0 8 -9 a8 8 0 0 1 7 -10 Z" }),
62
+ /* @__PURE__ */ jsx("circle", { cx: "29", cy: "17", r: "2.6", fill: "currentColor", stroke: "none" })
63
+ ] })
64
+ ]
65
+ }
66
+ );
67
+ }
68
+ export {
69
+ Achievement,
70
+ AchievementList,
71
+ Emblem
72
+ };
73
+ //# sourceMappingURL=achievement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/achievement/achievement.tsx"],"sourcesContent":["// Server-safe. Something done, and what it replaced (story.css): a milestone reached, a dare completed, a problem out of\n// the way. A list of them shares one grid of hairlines; in a `Scene` of a `ScrollStage` their badges arrive one by one.\nimport * as React from \"react\";\n\nimport { cn } from \"../cn\";\nimport { brandClass, type StoryVariant, storyVariantClass } from \"../story-variant\";\n\nexport type AchievementProps = Omit<React.HTMLAttributes<HTMLDivElement>, \"title\"> & {\n /** What was achieved: the outcome, in a few words. */\n title: React.ReactNode;\n /** A small line above: its number, its kind (“Milestone 03”). */\n eyebrow?: React.ReactNode;\n /** A glyph before the eyebrow (an `Emblem`, an icon). Decorative. */\n icon?: React.ReactNode;\n /** The badge in the corner (“Done”, “Unlocked”, arcade “Sealed”). */\n badge?: React.ReactNode;\n /** What it replaced or overcame, struck through above the title (“Paying 30 % to a platform”). */\n replaced?: React.ReactNode;\n /** Not reached yet: muted, its badge neutral. Say it in the badge too (“Locked”). */\n locked?: boolean;\n /**\n * `default`: a calm badge. `arcade`: a mono stamp that slams onto the card.\n * @default \"default\"\n */\n variant?: StoryVariant;\n /** A brand scope (`orochia` → `.brand-orochia`). */\n brand?: string;\n};\n\n/** Something done: an eyebrow, a badge, what it replaced (struck through) and the outcome. */\nexport function Achievement({ title, eyebrow, icon, badge, replaced, locked, variant, brand, className, ...props }: AchievementProps) {\n return (\n <div data-locked={locked ? \"\" : undefined} className={cn(\"kzs-achievement\", storyVariantClass(variant), brandClass(brand), className)} {...props}>\n {(eyebrow || badge || icon) && (\n <div className=\"kzs-achievement-head\">\n <span className=\"kzs-achievement-eyebrow\">\n {icon && <span aria-hidden>{icon}</span>}\n {eyebrow}\n </span>\n {badge && <span className=\"kzs-achievement-badge\">{badge}</span>}\n </div>\n )}\n {replaced && (\n <del className=\"kzs-achievement-replaced\" style={{ textDecorationLine: \"line-through\" }}>\n {replaced}\n </del>\n )}\n <p className=\"kzs-achievement-title\">{title}</p>\n </div>\n );\n}\n\nexport type AchievementListProps = React.OlHTMLAttributes<HTMLOListElement> & {\n /** The `Achievement`s, in order: each one becomes an item of the list (its badge arrives after the previous one's). */\n children: React.ReactNode;\n /**\n * The narrowest a card gets before the grid drops a column.\n * @default \"220px\"\n */\n minWidth?: string;\n /** The look of every card: `default` or `arcade`. */\n variant?: StoryVariant;\n /** A brand scope (`orochia` → `.brand-orochia`). */\n brand?: string;\n};\n\n/** An ordered list of `Achievement`s on one grid of hairlines. */\nexport function AchievementList({ children, minWidth, variant, brand, className, style, ...props }: AchievementListProps) {\n const items = React.Children.toArray(children);\n return (\n <ol\n className={cn(\"kzs-achievements\", storyVariantClass(variant), brandClass(brand), className)}\n style={minWidth ? ({ \"--kzs-min\": minWidth, ...style } as React.CSSProperties) : style}\n {...props}\n >\n {items.map((child, i) => (\n <li key={React.isValidElement(child) && child.key != null ? child.key : i} style={{ \"--i\": i } as React.CSSProperties}>\n {child}\n </li>\n ))}\n </ol>\n );\n}\n\nexport type EmblemProps = Omit<React.SVGProps<SVGSVGElement>, \"children\"> & {\n /** The emblem: `sword` (courage, the first step), `mirror` (clarity, honesty), `jewel` (care, what is kept). */\n kind: \"sword\" | \"mirror\" | \"jewel\";\n /**\n * Width and height in pixels.\n * @default 20\n */\n size?: number;\n};\n\n/** Three line emblems for achievements and choices (`currentColor`, decorative). */\nexport function Emblem({ kind, size = 20, ...props }: EmblemProps) {\n return (\n <svg\n viewBox=\"0 0 48 48\"\n width={size}\n height={size}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2.4}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden\n focusable=\"false\"\n {...props}\n >\n {kind === \"sword\" && (\n <>\n <path d=\"M24 3 L27 28 L24 36 L21 28 Z\" />\n <path d=\"M15 30 H33 M24 36 V45\" />\n </>\n )}\n {kind === \"mirror\" && (\n <>\n <circle cx=\"24\" cy=\"24\" r=\"17\" />\n <circle cx=\"24\" cy=\"24\" r=\"9\" />\n <path d=\"M24 2 V6 M24 42 V46 M2 24 H6 M42 24 H46\" />\n </>\n )}\n {kind === \"jewel\" && (\n <>\n <path d=\"M31 10 a13 13 0 1 1 -15 19 a8 8 0 0 0 8 -9 a8 8 0 0 1 7 -10 Z\" />\n <circle cx=\"29\" cy=\"17\" r=\"2.6\" fill=\"currentColor\" stroke=\"none\" />\n </>\n )}\n </svg>\n );\n}\n"],"mappings":";;;;;;;AAEA,YAAY,WAAW;AAiCb,SA4EF,UA3Ea,KADX;AALH,SAAS,YAAY,EAAE,OAAO,SAAS,MAAM,OAAO,UAAU,QAAQ,SAAS,OAAO,WAAW,GAAG,MAAM,GAAqB;AACpI,SACE,qBAAC,SAAI,eAAa,SAAS,KAAK,QAAW,WAAW,GAAG,mBAAmB,kBAAkB,OAAO,GAAG,WAAW,KAAK,GAAG,SAAS,GAAI,GAAG,OACvI;AAAA,gBAAW,SAAS,SACpB,qBAAC,SAAI,WAAU,wBACb;AAAA,2BAAC,UAAK,WAAU,2BACb;AAAA,gBAAQ,oBAAC,UAAK,eAAW,MAAE,gBAAK;AAAA,QAChC;AAAA,SACH;AAAA,MACC,SAAS,oBAAC,UAAK,WAAU,yBAAyB,iBAAM;AAAA,OAC3D;AAAA,IAED,YACC,oBAAC,SAAI,WAAU,4BAA2B,OAAO,EAAE,oBAAoB,eAAe,GACnF,oBACH;AAAA,IAEF,oBAAC,OAAE,WAAU,yBAAyB,iBAAM;AAAA,KAC9C;AAEJ;AAiBO,SAAS,gBAAgB,EAAE,UAAU,UAAU,SAAS,OAAO,WAAW,OAAO,GAAG,MAAM,GAAyB;AACxH,QAAM,QAAc,eAAS,QAAQ,QAAQ;AAC7C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,oBAAoB,kBAAkB,OAAO,GAAG,WAAW,KAAK,GAAG,SAAS;AAAA,MAC1F,OAAO,WAAY,EAAE,aAAa,UAAU,GAAG,MAAM,IAA4B;AAAA,MAChF,GAAG;AAAA,MAEH,gBAAM,IAAI,CAAC,OAAO,MACjB,oBAAC,QAA0E,OAAO,EAAE,OAAO,EAAE,GAC1F,mBADY,qBAAe,KAAK,KAAK,MAAM,OAAO,OAAO,MAAM,MAAM,CAExE,CACD;AAAA;AAAA,EACH;AAEJ;AAaO,SAAS,OAAO,EAAE,MAAM,OAAO,IAAI,GAAG,MAAM,GAAgB;AACjE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAQ;AAAA,MACR,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,MAAK;AAAA,MACL,QAAO;AAAA,MACP,aAAa;AAAA,MACb,eAAc;AAAA,MACd,gBAAe;AAAA,MACf,eAAW;AAAA,MACX,WAAU;AAAA,MACT,GAAG;AAAA,MAEH;AAAA,iBAAS,WACR,iCACE;AAAA,8BAAC,UAAK,GAAE,gCAA+B;AAAA,UACvC,oBAAC,UAAK,GAAE,yBAAwB;AAAA,WAClC;AAAA,QAED,SAAS,YACR,iCACE;AAAA,8BAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,MAAK;AAAA,UAC/B,oBAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,KAAI;AAAA,UAC9B,oBAAC,UAAK,GAAE,2CAA0C;AAAA,WACpD;AAAA,QAED,SAAS,WACR,iCACE;AAAA,8BAAC,UAAK,GAAE,iEAAgE;AAAA,UACxE,oBAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,OAAM,MAAK,gBAAe,QAAO,QAAO;AAAA,WACpE;AAAA;AAAA;AAAA,EAEJ;AAEJ;","names":[]}
@@ -0,0 +1,203 @@
1
+ import * as tailwind_variants from 'tailwind-variants';
2
+ import * as React from 'react';
3
+
4
+ declare const appShell: tailwind_variants.TVReturnType<{
5
+ [key: string]: {
6
+ [key: string]: tailwind_variants.ClassValue | {
7
+ root?: tailwind_variants.ClassValue;
8
+ drawer?: tailwind_variants.ClassValue;
9
+ overlay?: tailwind_variants.ClassValue;
10
+ brand?: tailwind_variants.ClassValue;
11
+ nav?: tailwind_variants.ClassValue;
12
+ group?: tailwind_variants.ClassValue;
13
+ itemLabel?: tailwind_variants.ClassValue;
14
+ footer?: tailwind_variants.ClassValue;
15
+ body?: tailwind_variants.ClassValue;
16
+ header?: tailwind_variants.ClassValue;
17
+ title?: tailwind_variants.ClassValue;
18
+ actions?: tailwind_variants.ClassValue;
19
+ main?: tailwind_variants.ClassValue;
20
+ sidebar?: tailwind_variants.ClassValue;
21
+ item?: tailwind_variants.ClassValue;
22
+ itemBadge?: tailwind_variants.ClassValue;
23
+ collapse?: tailwind_variants.ClassValue;
24
+ menuButton?: tailwind_variants.ClassValue;
25
+ };
26
+ };
27
+ } | {
28
+ [x: string]: {
29
+ [x: string]: tailwind_variants.ClassValue | {
30
+ root?: tailwind_variants.ClassValue;
31
+ drawer?: tailwind_variants.ClassValue;
32
+ overlay?: tailwind_variants.ClassValue;
33
+ brand?: tailwind_variants.ClassValue;
34
+ nav?: tailwind_variants.ClassValue;
35
+ group?: tailwind_variants.ClassValue;
36
+ itemLabel?: tailwind_variants.ClassValue;
37
+ footer?: tailwind_variants.ClassValue;
38
+ body?: tailwind_variants.ClassValue;
39
+ header?: tailwind_variants.ClassValue;
40
+ title?: tailwind_variants.ClassValue;
41
+ actions?: tailwind_variants.ClassValue;
42
+ main?: tailwind_variants.ClassValue;
43
+ sidebar?: tailwind_variants.ClassValue;
44
+ item?: tailwind_variants.ClassValue;
45
+ itemBadge?: tailwind_variants.ClassValue;
46
+ collapse?: tailwind_variants.ClassValue;
47
+ menuButton?: tailwind_variants.ClassValue;
48
+ };
49
+ };
50
+ } | {}, {
51
+ root: string;
52
+ sidebar: string;
53
+ drawer: string;
54
+ overlay: string;
55
+ brand: string;
56
+ nav: string;
57
+ group: string;
58
+ item: string;
59
+ itemLabel: string;
60
+ itemBadge: string;
61
+ footer: string;
62
+ collapse: string;
63
+ body: string;
64
+ header: string;
65
+ menuButton: string;
66
+ title: string;
67
+ actions: string;
68
+ main: string;
69
+ }, undefined, {
70
+ [key: string]: {
71
+ [key: string]: tailwind_variants.ClassValue | {
72
+ root?: tailwind_variants.ClassValue;
73
+ drawer?: tailwind_variants.ClassValue;
74
+ overlay?: tailwind_variants.ClassValue;
75
+ brand?: tailwind_variants.ClassValue;
76
+ nav?: tailwind_variants.ClassValue;
77
+ group?: tailwind_variants.ClassValue;
78
+ itemLabel?: tailwind_variants.ClassValue;
79
+ footer?: tailwind_variants.ClassValue;
80
+ body?: tailwind_variants.ClassValue;
81
+ header?: tailwind_variants.ClassValue;
82
+ title?: tailwind_variants.ClassValue;
83
+ actions?: tailwind_variants.ClassValue;
84
+ main?: tailwind_variants.ClassValue;
85
+ sidebar?: tailwind_variants.ClassValue;
86
+ item?: tailwind_variants.ClassValue;
87
+ itemBadge?: tailwind_variants.ClassValue;
88
+ collapse?: tailwind_variants.ClassValue;
89
+ menuButton?: tailwind_variants.ClassValue;
90
+ };
91
+ };
92
+ } | {}, {
93
+ root: string;
94
+ sidebar: string;
95
+ drawer: string;
96
+ overlay: string;
97
+ brand: string;
98
+ nav: string;
99
+ group: string;
100
+ item: string;
101
+ itemLabel: string;
102
+ itemBadge: string;
103
+ footer: string;
104
+ collapse: string;
105
+ body: string;
106
+ header: string;
107
+ menuButton: string;
108
+ title: string;
109
+ actions: string;
110
+ main: string;
111
+ }, tailwind_variants.TVReturnTypeLike<unknown, {
112
+ root: string;
113
+ sidebar: string;
114
+ drawer: string;
115
+ overlay: string;
116
+ brand: string;
117
+ nav: string;
118
+ group: string;
119
+ item: string;
120
+ itemLabel: string;
121
+ itemBadge: string;
122
+ footer: string;
123
+ collapse: string;
124
+ body: string;
125
+ header: string;
126
+ menuButton: string;
127
+ title: string;
128
+ actions: string;
129
+ main: string;
130
+ }>>;
131
+ type AppShellRootProps = React.ComponentProps<"div"> & {
132
+ /** The sidebar starts collapsed to its icons (desktop). */
133
+ defaultCollapsed?: boolean;
134
+ /** Controlled collapse (desktop): pair with `onCollapsedChange` to persist the choice. */
135
+ collapsed?: boolean;
136
+ /** Called when the sidebar collapses or expands. */
137
+ onCollapsedChange?: (collapsed: boolean) => void;
138
+ };
139
+ /** The shell: holds the collapse (desktop) and the drawer (phone) state. Children: Sidebar, then Body. */
140
+ declare function AppShellRoot({ defaultCollapsed, collapsed: controlled, onCollapsedChange, className, ...props }: AppShellRootProps): React.JSX.Element;
141
+ type AppShellSidebarProps = Omit<React.ComponentProps<"nav">, "children"> & {
142
+ /** The navigation's accessible name (`Studio`, `Administration`). */
143
+ label: string;
144
+ /** The brand at the top: the product's mark and name (a link home through `asChild` of your router, or plain). */
145
+ brand?: React.ReactNode;
146
+ /** The sections: `AppShell.Group` and `AppShell.Item`. */
147
+ children: React.ReactNode;
148
+ /** At the bottom, above the collapse button: the account, a plan, the version. */
149
+ footer?: React.ReactNode;
150
+ /** The collapse button's words, `[collapse, expand]` (desktop only). Without it the sidebar cannot collapse. */
151
+ collapseLabels?: readonly [string, string];
152
+ /** The drawer's close button words (phone). */
153
+ closeLabel: string;
154
+ };
155
+ /** The sidebar: on a desktop a column that collapses to its icons; on a phone the same content in a drawer. */
156
+ declare function AppShellSidebar({ label, brand, children, footer, collapseLabels, closeLabel, className, ...props }: AppShellSidebarProps): React.JSX.Element;
157
+ type AppShellGroupProps = React.ComponentProps<"p"> & {
158
+ /** The group's name, above its items (hidden when the sidebar is collapsed). */
159
+ children: React.ReactNode;
160
+ };
161
+ /** A heading between groups of items. */
162
+ declare function AppShellGroup({ className, ...props }: AppShellGroupProps): React.JSX.Element;
163
+ type AppShellItemProps = Omit<React.ComponentProps<"a">, "children"> & {
164
+ /** The item's icon (a signature icon): it stays when the sidebar collapses. */
165
+ icon?: React.ReactNode;
166
+ /** Its words: the accessible name, hidden visually when collapsed (the icon carries a tooltip through `title`). */
167
+ label: string;
168
+ /** The screen it opens is the current one: `aria-current="page"`. */
169
+ current?: boolean;
170
+ /** A count beside it (unread, pending): a number or a few characters. */
171
+ badge?: React.ReactNode;
172
+ /** Renders your link (Next's `Link`) with the item's look: pass it as the only child. */
173
+ asChild?: boolean;
174
+ /** Your link element when `asChild`. */
175
+ children?: React.ReactElement;
176
+ };
177
+ /** A destination of the sidebar: icon, words, a count. */
178
+ declare function AppShellItem({ icon, label, current, badge, asChild, children, className, ...props }: AppShellItemProps): React.JSX.Element;
179
+ /** The column right of the sidebar: Header, then Main. */
180
+ declare function AppShellBody({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
181
+ type AppShellHeaderProps = Omit<React.ComponentProps<"header">, "title"> & {
182
+ /** The screen's title (an `h1`). */
183
+ title?: React.ReactNode;
184
+ /** The button that opens the drawer on a phone: its words. */
185
+ menuLabel: string;
186
+ /** The screen's actions, on the right. */
187
+ actions?: React.ReactNode;
188
+ };
189
+ /** The top of the screen: the drawer's button (phone), the title, the actions. Sticky. */
190
+ declare function AppShellHeader({ title, menuLabel, actions, className, children, ...props }: AppShellHeaderProps): React.JSX.Element;
191
+ /** The screen's content. */
192
+ declare function AppShellMain({ className, ...props }: React.ComponentProps<"main">): React.JSX.Element;
193
+ declare const AppShell: {
194
+ Root: typeof AppShellRoot;
195
+ Sidebar: typeof AppShellSidebar;
196
+ Group: typeof AppShellGroup;
197
+ Item: typeof AppShellItem;
198
+ Body: typeof AppShellBody;
199
+ Header: typeof AppShellHeader;
200
+ Main: typeof AppShellMain;
201
+ };
202
+
203
+ export { AppShell, AppShellBody, AppShellGroup, type AppShellGroupProps, AppShellHeader, type AppShellHeaderProps, AppShellItem, type AppShellItemProps, AppShellMain, AppShellRoot, type AppShellRootProps, AppShellSidebar, type AppShellSidebarProps, appShell };
@@ -0,0 +1,137 @@
1
+ "use client";
2
+ import {
3
+ ChevronGlyph,
4
+ CloseGlyph
5
+ } from "./chunk-AZPKXP3O.js";
6
+ import {
7
+ cn
8
+ } from "./chunk-5AXLA4LK.js";
9
+
10
+ // src/app-shell/app-shell.tsx
11
+ import { Dialog as DialogPrimitive, Slot } from "radix-ui";
12
+ import * as React from "react";
13
+ import { tv } from "tailwind-variants";
14
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
15
+ var appShell = tv({
16
+ slots: {
17
+ root: "flex min-h-dvh w-full bg-surface-0 text-fg",
18
+ sidebar: "sticky top-0 hidden h-dvh shrink-0 flex-col border-r border-border-subtle bg-surface-1 transition-[width] duration-300 motion-reduce:transition-none md:flex w-64 data-collapsed:w-[4.25rem]",
19
+ drawer: "kz-dialog fixed inset-y-0 left-0 z-50 flex w-[min(20rem,88vw)] flex-col border-r border-border-default bg-surface-1 pl-[env(safe-area-inset-left)] shadow-lg focus:outline-hidden",
20
+ overlay: "kz-overlay fixed inset-0 z-50 bg-overlay backdrop-blur-xs",
21
+ brand: "flex h-14 shrink-0 items-center gap-2.5 px-4 font-display text-[15px] font-bold tracking-tight [[data-collapsed]_&]:justify-center [[data-collapsed]_&]:px-0",
22
+ nav: "flex min-h-0 flex-1 flex-col gap-0.5 overflow-y-auto px-2 py-2",
23
+ group: "mt-3 mb-1 px-3 font-mono text-[10.5px] font-semibold uppercase tracking-[0.14em] text-fg-secondary [[data-collapsed]_&]:sr-only",
24
+ item: "group/item relative flex h-10 items-center gap-3 rounded-lg px-3 text-sm font-medium text-fg-secondary no-underline transition-colors hover:bg-surface-2 hover:text-fg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring aria-[current=page]:bg-accent-soft aria-[current=page]:text-fg aria-[current=page]:before:absolute aria-[current=page]:before:inset-y-2 aria-[current=page]:before:-left-2 aria-[current=page]:before:w-1 aria-[current=page]:before:rounded-full aria-[current=page]:before:bg-accent [[data-collapsed]_&]:justify-center [[data-collapsed]_&]:px-0 [&>svg]:h-[18px] [&>svg]:w-[18px] [&>svg]:shrink-0",
25
+ itemLabel: "min-w-0 flex-1 truncate [[data-collapsed]_&]:sr-only",
26
+ itemBadge: "ml-auto inline-flex min-w-5 items-center justify-center rounded-full bg-accent px-1.5 text-[11px] font-bold text-on-accent [[data-collapsed]_&]:absolute [[data-collapsed]_&]:right-1.5 [[data-collapsed]_&]:top-1 [[data-collapsed]_&]:min-w-4 [[data-collapsed]_&]:px-1 [[data-collapsed]_&]:text-[10px]",
27
+ footer: "shrink-0 border-t border-border-subtle p-2",
28
+ collapse: "hidden h-9 w-full items-center gap-2 rounded-lg px-3 text-xs font-medium text-fg-secondary hover:bg-surface-2 hover:text-fg md:flex focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring [[data-collapsed]_&]:justify-center [[data-collapsed]_&]:px-0",
29
+ body: "flex min-w-0 flex-1 flex-col",
30
+ header: "sticky top-0 z-30 flex h-14 shrink-0 items-center gap-3 border-b border-border-subtle bg-surface-0/85 px-4 backdrop-blur-xl md:px-6",
31
+ menuButton: "inline-flex h-9 w-9 items-center justify-center rounded-lg border border-border-subtle bg-surface-1 text-fg md:hidden focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring",
32
+ title: "min-w-0 flex-1 truncate font-display text-base font-bold tracking-tight",
33
+ actions: "ml-auto flex shrink-0 items-center gap-2",
34
+ main: "min-w-0 flex-1 px-4 py-6 md:px-6 md:py-8"
35
+ }
36
+ });
37
+ var s = appShell();
38
+ var ShellContext = React.createContext(null);
39
+ var useShell = () => {
40
+ const ctx = React.useContext(ShellContext);
41
+ if (!ctx) throw new Error("AppShell parts must be inside <AppShell.Root>");
42
+ return ctx;
43
+ };
44
+ function AppShellRoot({ defaultCollapsed = false, collapsed: controlled, onCollapsedChange, className, ...props }) {
45
+ const [own, setOwn] = React.useState(defaultCollapsed);
46
+ const [open, setOpen] = React.useState(false);
47
+ const collapsed = controlled ?? own;
48
+ const setCollapsed = React.useCallback(
49
+ (value2) => {
50
+ if (controlled === void 0) setOwn(value2);
51
+ onCollapsedChange?.(value2);
52
+ },
53
+ [controlled, onCollapsedChange]
54
+ );
55
+ const value = React.useMemo(() => ({ collapsed, setCollapsed, open, setOpen, inDrawer: false }), [collapsed, setCollapsed, open]);
56
+ return /* @__PURE__ */ jsx(ShellContext.Provider, { value, children: /* @__PURE__ */ jsx("div", { className: s.root({ className }), ...props }) });
57
+ }
58
+ function SidebarContent({ brand, children, footer, collapseLabels, closeLabel }) {
59
+ const { collapsed, setCollapsed, inDrawer } = useShell();
60
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
61
+ /* @__PURE__ */ jsxs("div", { className: s.brand(), children: [
62
+ brand,
63
+ inDrawer && /* @__PURE__ */ jsx(DialogPrimitive.Close, { className: cn(s.menuButton(), "ml-auto flex"), "aria-label": closeLabel, children: /* @__PURE__ */ jsx(CloseGlyph, { className: "h-4 w-4" }) })
64
+ ] }),
65
+ /* @__PURE__ */ jsx("div", { className: s.nav(), children }),
66
+ (footer || collapseLabels && !inDrawer) && /* @__PURE__ */ jsxs("div", { className: s.footer(), children: [
67
+ footer,
68
+ collapseLabels && !inDrawer && /* @__PURE__ */ jsxs("button", { type: "button", className: s.collapse(), "aria-expanded": !collapsed, onClick: () => setCollapsed(!collapsed), children: [
69
+ /* @__PURE__ */ jsx(ChevronGlyph, { direction: collapsed ? "right" : "left", className: "h-4 w-4" }),
70
+ /* @__PURE__ */ jsx("span", { className: collapsed ? "sr-only" : void 0, children: collapsed ? collapseLabels[1] : collapseLabels[0] })
71
+ ] })
72
+ ] })
73
+ ] });
74
+ }
75
+ function AppShellSidebar({ label, brand, children, footer, collapseLabels, closeLabel, className, ...props }) {
76
+ const shell = useShell();
77
+ const content = { brand, children, footer, collapseLabels, closeLabel };
78
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
79
+ /* @__PURE__ */ jsx("nav", { "aria-label": label, "data-collapsed": shell.collapsed ? "" : void 0, className: s.sidebar({ className }), ...props, children: /* @__PURE__ */ jsx(SidebarContent, { ...content }) }),
80
+ /* @__PURE__ */ jsx(DialogPrimitive.Root, { open: shell.open, onOpenChange: shell.setOpen, children: /* @__PURE__ */ jsxs(DialogPrimitive.Portal, { children: [
81
+ /* @__PURE__ */ jsx(DialogPrimitive.Overlay, { className: s.overlay() }),
82
+ /* @__PURE__ */ jsxs(DialogPrimitive.Content, { className: s.drawer(), "aria-describedby": void 0, children: [
83
+ /* @__PURE__ */ jsx(DialogPrimitive.Title, { className: "sr-only", children: label }),
84
+ /* @__PURE__ */ jsx(ShellContext.Provider, { value: { ...shell, collapsed: false, inDrawer: true }, children: /* @__PURE__ */ jsx("nav", { "aria-label": label, className: "flex min-h-0 flex-1 flex-col", onClick: (e) => e.target.closest("a") && shell.setOpen(false), children: /* @__PURE__ */ jsx(SidebarContent, { ...content }) }) })
85
+ ] })
86
+ ] }) })
87
+ ] });
88
+ }
89
+ function AppShellGroup({ className, ...props }) {
90
+ return /* @__PURE__ */ jsx("p", { className: s.group({ className }), ...props });
91
+ }
92
+ function AppShellItem({ icon, label, current, badge, asChild, children, className, ...props }) {
93
+ const { collapsed } = useShell();
94
+ const Comp = asChild ? Slot.Root : "a";
95
+ const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
96
+ icon,
97
+ /* @__PURE__ */ jsx("span", { className: s.itemLabel(), children: label }),
98
+ badge != null && /* @__PURE__ */ jsx("span", { className: s.itemBadge(), children: badge })
99
+ ] });
100
+ return /* @__PURE__ */ jsx(Comp, { "aria-current": current ? "page" : void 0, title: collapsed ? label : void 0, className: s.item({ className }), ...props, children: asChild && children ? React.cloneElement(children, void 0, inner) : inner });
101
+ }
102
+ function AppShellBody({ className, ...props }) {
103
+ return /* @__PURE__ */ jsx("div", { className: s.body({ className }), ...props });
104
+ }
105
+ function AppShellHeader({ title, menuLabel, actions, className, children, ...props }) {
106
+ const { open, setOpen } = useShell();
107
+ return /* @__PURE__ */ jsxs("header", { className: s.header({ className }), ...props, children: [
108
+ /* @__PURE__ */ jsx("button", { type: "button", className: s.menuButton(), "aria-label": menuLabel, "aria-expanded": open, "aria-haspopup": "dialog", onClick: () => setOpen(true), children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", className: "h-4 w-4", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M4 7h16M4 12h16M4 17h10" }) }) }),
109
+ title && /* @__PURE__ */ jsx("h1", { className: s.title(), children: title }),
110
+ children,
111
+ actions && /* @__PURE__ */ jsx("div", { className: s.actions(), children: actions })
112
+ ] });
113
+ }
114
+ function AppShellMain({ className, ...props }) {
115
+ return /* @__PURE__ */ jsx("main", { className: s.main({ className }), ...props });
116
+ }
117
+ var AppShell = {
118
+ Root: AppShellRoot,
119
+ Sidebar: AppShellSidebar,
120
+ Group: AppShellGroup,
121
+ Item: AppShellItem,
122
+ Body: AppShellBody,
123
+ Header: AppShellHeader,
124
+ Main: AppShellMain
125
+ };
126
+ export {
127
+ AppShell,
128
+ AppShellBody,
129
+ AppShellGroup,
130
+ AppShellHeader,
131
+ AppShellItem,
132
+ AppShellMain,
133
+ AppShellRoot,
134
+ AppShellSidebar,
135
+ appShell
136
+ };
137
+ //# sourceMappingURL=app-shell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/app-shell/app-shell.tsx"],"sourcesContent":["// Client (the collapse, the drawer). The shell of an application screen, read from the products' consoles (Orochia\n// admin and studio, Orazaka web-admin and web-client): a sidebar of sections that collapses to its icons on a desktop,\n// a header with the screen's title and actions, the content — and below `md` the sidebar becomes a drawer opened from\n// the header (Radix Dialog: focus trap, Escape, focus return). Words arrive as props; links through `asChild`.\nimport { Dialog as DialogPrimitive, Slot } from \"radix-ui\";\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { cn } from \"../cn\";\nimport { ChevronGlyph, CloseGlyph } from \"../glyphs\";\n\nexport const appShell = tv({\n slots: {\n root: \"flex min-h-dvh w-full bg-surface-0 text-fg\",\n sidebar:\n \"sticky top-0 hidden h-dvh shrink-0 flex-col border-r border-border-subtle bg-surface-1 transition-[width] duration-300 motion-reduce:transition-none md:flex \" +\n \"w-64 data-collapsed:w-[4.25rem]\",\n drawer:\n \"kz-dialog fixed inset-y-0 left-0 z-50 flex w-[min(20rem,88vw)] flex-col border-r border-border-default bg-surface-1 pl-[env(safe-area-inset-left)] shadow-lg focus:outline-hidden\",\n overlay: \"kz-overlay fixed inset-0 z-50 bg-overlay backdrop-blur-xs\",\n brand: \"flex h-14 shrink-0 items-center gap-2.5 px-4 font-display text-[15px] font-bold tracking-tight [[data-collapsed]_&]:justify-center [[data-collapsed]_&]:px-0\",\n nav: \"flex min-h-0 flex-1 flex-col gap-0.5 overflow-y-auto px-2 py-2\",\n group: \"mt-3 mb-1 px-3 font-mono text-[10.5px] font-semibold uppercase tracking-[0.14em] text-fg-secondary [[data-collapsed]_&]:sr-only\",\n item:\n \"group/item relative flex h-10 items-center gap-3 rounded-lg px-3 text-sm font-medium text-fg-secondary no-underline transition-colors \" +\n \"hover:bg-surface-2 hover:text-fg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring \" +\n \"aria-[current=page]:bg-accent-soft aria-[current=page]:text-fg \" +\n \"aria-[current=page]:before:absolute aria-[current=page]:before:inset-y-2 aria-[current=page]:before:-left-2 aria-[current=page]:before:w-1 aria-[current=page]:before:rounded-full aria-[current=page]:before:bg-accent \" +\n \"[[data-collapsed]_&]:justify-center [[data-collapsed]_&]:px-0 [&>svg]:h-[18px] [&>svg]:w-[18px] [&>svg]:shrink-0\",\n itemLabel: \"min-w-0 flex-1 truncate [[data-collapsed]_&]:sr-only\",\n itemBadge:\n \"ml-auto inline-flex min-w-5 items-center justify-center rounded-full bg-accent px-1.5 text-[11px] font-bold text-on-accent \" +\n \"[[data-collapsed]_&]:absolute [[data-collapsed]_&]:right-1.5 [[data-collapsed]_&]:top-1 [[data-collapsed]_&]:min-w-4 [[data-collapsed]_&]:px-1 [[data-collapsed]_&]:text-[10px]\",\n footer: \"shrink-0 border-t border-border-subtle p-2\",\n collapse:\n \"hidden h-9 w-full items-center gap-2 rounded-lg px-3 text-xs font-medium text-fg-secondary hover:bg-surface-2 hover:text-fg md:flex \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring [[data-collapsed]_&]:justify-center [[data-collapsed]_&]:px-0\",\n body: \"flex min-w-0 flex-1 flex-col\",\n header:\n \"sticky top-0 z-30 flex h-14 shrink-0 items-center gap-3 border-b border-border-subtle bg-surface-0/85 px-4 backdrop-blur-xl md:px-6\",\n menuButton:\n \"inline-flex h-9 w-9 items-center justify-center rounded-lg border border-border-subtle bg-surface-1 text-fg md:hidden \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n title: \"min-w-0 flex-1 truncate font-display text-base font-bold tracking-tight\",\n actions: \"ml-auto flex shrink-0 items-center gap-2\",\n main: \"min-w-0 flex-1 px-4 py-6 md:px-6 md:py-8\",\n },\n});\nconst s = appShell();\n\ninterface ShellState {\n collapsed: boolean;\n setCollapsed: (value: boolean) => void;\n open: boolean;\n setOpen: (value: boolean) => void;\n inDrawer: boolean;\n}\nconst ShellContext = React.createContext<ShellState | null>(null);\nconst useShell = () => {\n const ctx = React.useContext(ShellContext);\n if (!ctx) throw new Error(\"AppShell parts must be inside <AppShell.Root>\");\n return ctx;\n};\n\nexport type AppShellRootProps = React.ComponentProps<\"div\"> & {\n /** The sidebar starts collapsed to its icons (desktop). */\n defaultCollapsed?: boolean;\n /** Controlled collapse (desktop): pair with `onCollapsedChange` to persist the choice. */\n collapsed?: boolean;\n /** Called when the sidebar collapses or expands. */\n onCollapsedChange?: (collapsed: boolean) => void;\n};\n\n/** The shell: holds the collapse (desktop) and the drawer (phone) state. Children: Sidebar, then Body. */\nexport function AppShellRoot({ defaultCollapsed = false, collapsed: controlled, onCollapsedChange, className, ...props }: AppShellRootProps) {\n const [own, setOwn] = React.useState(defaultCollapsed);\n const [open, setOpen] = React.useState(false);\n const collapsed = controlled ?? own;\n const setCollapsed = React.useCallback(\n (value: boolean) => {\n if (controlled === undefined) setOwn(value);\n onCollapsedChange?.(value);\n },\n [controlled, onCollapsedChange],\n );\n const value = React.useMemo(() => ({ collapsed, setCollapsed, open, setOpen, inDrawer: false }), [collapsed, setCollapsed, open]);\n return (\n <ShellContext.Provider value={value}>\n <div className={s.root({ className })} {...props} />\n </ShellContext.Provider>\n );\n}\n\nexport type AppShellSidebarProps = Omit<React.ComponentProps<\"nav\">, \"children\"> & {\n /** The navigation's accessible name (`Studio`, `Administration`). */\n label: string;\n /** The brand at the top: the product's mark and name (a link home through `asChild` of your router, or plain). */\n brand?: React.ReactNode;\n /** The sections: `AppShell.Group` and `AppShell.Item`. */\n children: React.ReactNode;\n /** At the bottom, above the collapse button: the account, a plan, the version. */\n footer?: React.ReactNode;\n /** The collapse button's words, `[collapse, expand]` (desktop only). Without it the sidebar cannot collapse. */\n collapseLabels?: readonly [string, string];\n /** The drawer's close button words (phone). */\n closeLabel: string;\n};\n\nfunction SidebarContent({ brand, children, footer, collapseLabels, closeLabel }: Pick<AppShellSidebarProps, \"brand\" | \"children\" | \"footer\" | \"collapseLabels\" | \"closeLabel\">) {\n const { collapsed, setCollapsed, inDrawer } = useShell();\n return (\n <>\n <div className={s.brand()}>\n {brand}\n {inDrawer && (\n <DialogPrimitive.Close className={cn(s.menuButton(), \"ml-auto flex\")} aria-label={closeLabel}>\n <CloseGlyph className=\"h-4 w-4\" />\n </DialogPrimitive.Close>\n )}\n </div>\n <div className={s.nav()}>{children}</div>\n {(footer || (collapseLabels && !inDrawer)) && (\n <div className={s.footer()}>\n {footer}\n {collapseLabels && !inDrawer && (\n <button type=\"button\" className={s.collapse()} aria-expanded={!collapsed} onClick={() => setCollapsed(!collapsed)}>\n <ChevronGlyph direction={collapsed ? \"right\" : \"left\"} className=\"h-4 w-4\" />\n <span className={collapsed ? \"sr-only\" : undefined}>{collapsed ? collapseLabels[1] : collapseLabels[0]}</span>\n </button>\n )}\n </div>\n )}\n </>\n );\n}\n\n/** The sidebar: on a desktop a column that collapses to its icons; on a phone the same content in a drawer. */\nexport function AppShellSidebar({ label, brand, children, footer, collapseLabels, closeLabel, className, ...props }: AppShellSidebarProps) {\n const shell = useShell();\n const content = { brand, children, footer, collapseLabels, closeLabel };\n return (\n <>\n <nav aria-label={label} data-collapsed={shell.collapsed ? \"\" : undefined} className={s.sidebar({ className })} {...props}>\n <SidebarContent {...content} />\n </nav>\n <DialogPrimitive.Root open={shell.open} onOpenChange={shell.setOpen}>\n <DialogPrimitive.Portal>\n <DialogPrimitive.Overlay className={s.overlay()} />\n <DialogPrimitive.Content className={s.drawer()} aria-describedby={undefined}>\n <DialogPrimitive.Title className=\"sr-only\">{label}</DialogPrimitive.Title>\n <ShellContext.Provider value={{ ...shell, collapsed: false, inDrawer: true }}>\n <nav aria-label={label} className=\"flex min-h-0 flex-1 flex-col\" onClick={(e) => (e.target as Element).closest(\"a\") && shell.setOpen(false)}>\n <SidebarContent {...content} />\n </nav>\n </ShellContext.Provider>\n </DialogPrimitive.Content>\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n </>\n );\n}\n\nexport type AppShellGroupProps = React.ComponentProps<\"p\"> & {\n /** The group's name, above its items (hidden when the sidebar is collapsed). */\n children: React.ReactNode;\n};\n\n/** A heading between groups of items. */\nexport function AppShellGroup({ className, ...props }: AppShellGroupProps) {\n return <p className={s.group({ className })} {...props} />;\n}\n\nexport type AppShellItemProps = Omit<React.ComponentProps<\"a\">, \"children\"> & {\n /** The item's icon (a signature icon): it stays when the sidebar collapses. */\n icon?: React.ReactNode;\n /** Its words: the accessible name, hidden visually when collapsed (the icon carries a tooltip through `title`). */\n label: string;\n /** The screen it opens is the current one: `aria-current=\"page\"`. */\n current?: boolean;\n /** A count beside it (unread, pending): a number or a few characters. */\n badge?: React.ReactNode;\n /** Renders your link (Next's `Link`) with the item's look: pass it as the only child. */\n asChild?: boolean;\n /** Your link element when `asChild`. */\n children?: React.ReactElement;\n};\n\n/** A destination of the sidebar: icon, words, a count. */\nexport function AppShellItem({ icon, label, current, badge, asChild, children, className, ...props }: AppShellItemProps) {\n const { collapsed } = useShell();\n const Comp = asChild ? Slot.Root : \"a\";\n const inner = (\n <>\n {icon}\n <span className={s.itemLabel()}>{label}</span>\n {badge != null && <span className={s.itemBadge()}>{badge}</span>}\n </>\n );\n return (\n <Comp aria-current={current ? \"page\" : undefined} title={collapsed ? label : undefined} className={s.item({ className })} {...props}>\n {asChild && children ? React.cloneElement(children, undefined, inner) : inner}\n </Comp>\n );\n}\n\n/** The column right of the sidebar: Header, then Main. */\nexport function AppShellBody({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div className={s.body({ className })} {...props} />;\n}\n\nexport type AppShellHeaderProps = Omit<React.ComponentProps<\"header\">, \"title\"> & {\n /** The screen's title (an `h1`). */\n title?: React.ReactNode;\n /** The button that opens the drawer on a phone: its words. */\n menuLabel: string;\n /** The screen's actions, on the right. */\n actions?: React.ReactNode;\n};\n\n/** The top of the screen: the drawer's button (phone), the title, the actions. Sticky. */\nexport function AppShellHeader({ title, menuLabel, actions, className, children, ...props }: AppShellHeaderProps) {\n const { open, setOpen } = useShell();\n return (\n <header className={s.header({ className })} {...props}>\n <button type=\"button\" className={s.menuButton()} aria-label={menuLabel} aria-expanded={open} aria-haspopup=\"dialog\" onClick={() => setOpen(true)}>\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=\"M4 7h16M4 12h16M4 17h10\" />\n </svg>\n </button>\n {title && <h1 className={s.title()}>{title}</h1>}\n {children}\n {actions && <div className={s.actions()}>{actions}</div>}\n </header>\n );\n}\n\n/** The screen's content. */\nexport function AppShellMain({ className, ...props }: React.ComponentProps<\"main\">) {\n return <main className={s.main({ className })} {...props} />;\n}\n\nexport const AppShell = {\n Root: AppShellRoot,\n Sidebar: AppShellSidebar,\n Group: AppShellGroup,\n Item: AppShellItem,\n Body: AppShellBody,\n Header: AppShellHeader,\n Main: AppShellMain,\n};\n"],"mappings":"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","names":["value"]}