@krizaka/ui 3.24.0 → 3.26.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 (236) hide show
  1. package/README.md +9 -1
  2. package/dist/account-menu.d.ts +163 -0
  3. package/dist/account-menu.js +211 -0
  4. package/dist/account-menu.js.map +1 -0
  5. package/dist/app-shell.js +4 -4
  6. package/dist/changelog-page.d.ts +13 -1
  7. package/dist/changelog-page.js +20 -0
  8. package/dist/changelog-page.js.map +1 -1
  9. package/dist/{chunk-CEJDH6SA.js → chunk-2PNLHZLT.js} +23 -3
  10. package/dist/chunk-2PNLHZLT.js.map +1 -0
  11. package/dist/chunk-3S4GHSPZ.js +109 -0
  12. package/dist/chunk-3S4GHSPZ.js.map +1 -0
  13. package/dist/{chunk-FTX66XZY.js → chunk-BCGJZ5PG.js} +3 -3
  14. package/dist/{chunk-FTX66XZY.js.map → chunk-BCGJZ5PG.js.map} +1 -1
  15. package/dist/chunk-C7LTF5CC.js +21 -0
  16. package/dist/chunk-C7LTF5CC.js.map +1 -0
  17. package/dist/{chunk-F7FVPPBB.js → chunk-LYOPPBMC.js} +2 -2
  18. package/dist/{chunk-AFY35UCB.js → chunk-P7GZR5CU.js} +3 -1
  19. package/dist/{chunk-AFY35UCB.js.map → chunk-P7GZR5CU.js.map} +1 -1
  20. package/dist/code-block.js +1 -1
  21. package/dist/cover-hero.d.ts +125 -0
  22. package/dist/cover-hero.js +82 -0
  23. package/dist/cover-hero.js.map +1 -0
  24. package/dist/data-table.js +2 -2
  25. package/dist/docs-nav.js +3 -16
  26. package/dist/docs-nav.js.map +1 -1
  27. package/dist/dropdown-menu.d.ts +12 -1
  28. package/dist/dropdown-menu.js +25 -2
  29. package/dist/dropdown-menu.js.map +1 -1
  30. package/dist/filter-bar.js +1 -1
  31. package/dist/genui.js +2 -2
  32. package/dist/language-switch.d.ts +120 -0
  33. package/dist/language-switch.js +32 -0
  34. package/dist/language-switch.js.map +1 -0
  35. package/dist/media-gallery.d.ts +73 -0
  36. package/dist/media-gallery.js +42 -0
  37. package/dist/media-gallery.js.map +1 -0
  38. package/dist/nav-bar.d.ts +40 -2
  39. package/dist/nav-bar.js +68 -12
  40. package/dist/nav-bar.js.map +1 -1
  41. package/dist/opening-hours.d.ts +124 -0
  42. package/dist/opening-hours.js +48 -0
  43. package/dist/opening-hours.js.map +1 -0
  44. package/dist/rail-nav.js +1 -1
  45. package/dist/service-card.d.ts +168 -0
  46. package/dist/service-card.js +112 -0
  47. package/dist/service-card.js.map +1 -0
  48. package/dist/site-footer.js +1 -1
  49. package/dist/sites.js +2 -2
  50. package/dist/sites.js.map +1 -1
  51. package/dist/slot-picker.d.ts +119 -0
  52. package/dist/slot-picker.js +46 -0
  53. package/dist/slot-picker.js.map +1 -0
  54. package/dist/sticky-action.d.ts +12 -0
  55. package/dist/sticky-action.js +14 -0
  56. package/dist/sticky-action.js.map +1 -0
  57. package/package.json +121 -7
  58. package/registry/account-menu.json +280 -0
  59. package/registry/achievement.json +1 -1
  60. package/registry/action-bar.json +1 -1
  61. package/registry/activity-feed.json +3 -3
  62. package/registry/alert.json +1 -1
  63. package/registry/app-header.json +1 -1
  64. package/registry/app-shell.json +1 -1
  65. package/registry/argument-card.json +1 -1
  66. package/registry/audio-player.json +1 -1
  67. package/registry/auth-layout.json +1 -1
  68. package/registry/avatar.json +1 -1
  69. package/registry/badge.json +1 -1
  70. package/registry/button.json +1 -1
  71. package/registry/captcha.json +1 -1
  72. package/registry/card-grid.json +1 -1
  73. package/registry/card.json +3 -3
  74. package/registry/catalogue-page.json +1 -1
  75. package/registry/changelog-page.json +3 -3
  76. package/registry/chat.json +1 -1
  77. package/registry/checkbox.json +1 -1
  78. package/registry/chip-link.json +1 -1
  79. package/registry/chip.json +1 -1
  80. package/registry/choice-grid.json +1 -1
  81. package/registry/code-block.json +1 -1
  82. package/registry/combobox.json +1 -1
  83. package/registry/command.json +1 -1
  84. package/registry/comparison-table.json +1 -1
  85. package/registry/component-page.json +1 -1
  86. package/registry/confirm-button.json +1 -1
  87. package/registry/contact-page.json +1 -1
  88. package/registry/continue-prompt.json +1 -1
  89. package/registry/countdown.json +1 -1
  90. package/registry/cover-hero.json +246 -0
  91. package/registry/cta-panel.json +1 -1
  92. package/registry/dashboard-layout.json +1 -1
  93. package/registry/data-table.json +1 -1
  94. package/registry/date-picker.json +1 -1
  95. package/registry/decision-list.json +1 -1
  96. package/registry/description-list.json +1 -1
  97. package/registry/detail-layout.json +1 -1
  98. package/registry/dialog.json +1 -1
  99. package/registry/docs-article-page.json +1 -1
  100. package/registry/docs-hub-page.json +1 -1
  101. package/registry/docs-layout.json +1 -1
  102. package/registry/docs-nav.json +1 -1
  103. package/registry/document-viewer.json +1 -1
  104. package/registry/dropdown-menu.json +33 -3
  105. package/registry/empty-state.json +1 -1
  106. package/registry/error-page.json +1 -1
  107. package/registry/examples/account-menu/default.d.ts +4 -0
  108. package/registry/examples/account-menu/default.js +28 -0
  109. package/registry/examples/account-menu/default.tsx +22 -0
  110. package/registry/examples/cover-hero/plain.d.ts +4 -0
  111. package/registry/examples/cover-hero/plain.js +12 -0
  112. package/registry/examples/cover-hero/plain.tsx +7 -0
  113. package/registry/examples/cover-hero/shop.d.ts +4 -0
  114. package/registry/examples/cover-hero/shop.js +27 -0
  115. package/registry/examples/cover-hero/shop.tsx +20 -0
  116. package/registry/examples/language-switch/inline.d.ts +4 -0
  117. package/registry/examples/language-switch/inline.js +11 -0
  118. package/registry/examples/language-switch/inline.tsx +6 -0
  119. package/registry/examples/language-switch/menu.d.ts +4 -0
  120. package/registry/examples/language-switch/menu.js +11 -0
  121. package/registry/examples/language-switch/menu.tsx +6 -0
  122. package/registry/examples/media-gallery/shop.d.ts +4 -0
  123. package/registry/examples/media-gallery/shop.js +22 -0
  124. package/registry/examples/media-gallery/shop.tsx +18 -0
  125. package/registry/examples/nav-bar/family-product.js +18 -10
  126. package/registry/examples/nav-bar/family-product.tsx +28 -27
  127. package/registry/examples/opening-hours/week.d.ts +4 -0
  128. package/registry/examples/opening-hours/week.js +28 -0
  129. package/registry/examples/opening-hours/week.tsx +22 -0
  130. package/registry/examples/service-card/services.d.ts +4 -0
  131. package/registry/examples/service-card/services.js +15 -0
  132. package/registry/examples/service-card/services.tsx +12 -0
  133. package/registry/examples/slot-picker/times.d.ts +4 -0
  134. package/registry/examples/slot-picker/times.js +27 -0
  135. package/registry/examples/slot-picker/times.tsx +23 -0
  136. package/registry/examples/sticky-action/phone.d.ts +4 -0
  137. package/registry/examples/sticky-action/phone.js +15 -0
  138. package/registry/examples/sticky-action/phone.tsx +14 -0
  139. package/registry/field.json +1 -1
  140. package/registry/file-upload.json +1 -1
  141. package/registry/filter-bar.json +1 -1
  142. package/registry/force-update-screen.json +1 -1
  143. package/registry/form.json +3 -3
  144. package/registry/gallery-page.json +1 -1
  145. package/registry/genui.json +1 -1
  146. package/registry/glow-card.json +1 -1
  147. package/registry/goal-gauge.json +1 -1
  148. package/registry/how-it-works-page.json +1 -1
  149. package/registry/image-cropper.json +1 -1
  150. package/registry/index.json +258 -5
  151. package/registry/iso.json +1 -1
  152. package/registry/kanban.json +1 -1
  153. package/registry/kbd.json +1 -1
  154. package/registry/landing-page.json +1 -1
  155. package/registry/landscape.json +1 -1
  156. package/registry/language-switch.json +246 -0
  157. package/registry/legal-page.json +1 -1
  158. package/registry/link-card.json +3 -3
  159. package/registry/list.json +1 -1
  160. package/registry/loader.json +1 -1
  161. package/registry/longform-page.json +1 -1
  162. package/registry/maintenance-screen.json +1 -1
  163. package/registry/map.json +2 -2
  164. package/registry/markdown.json +1 -1
  165. package/registry/marketing-layout.json +1 -1
  166. package/registry/marquee.json +1 -1
  167. package/registry/mascot-quote.json +1 -1
  168. package/registry/mascot-state.json +1 -1
  169. package/registry/mascots.json +1 -1
  170. package/registry/match-dialog.json +1 -1
  171. package/registry/media-capture.json +3 -3
  172. package/registry/media-gallery.json +144 -0
  173. package/registry/media-grid.json +3 -3
  174. package/registry/meta-row.json +1 -1
  175. package/registry/meter.json +1 -1
  176. package/registry/nav-bar.json +138 -8
  177. package/registry/number-ticker.json +1 -1
  178. package/registry/opening-hours.json +178 -0
  179. package/registry/page-header.json +1 -1
  180. package/registry/page-hero.json +3 -3
  181. package/registry/page.json +7 -7
  182. package/registry/pagination.json +1 -1
  183. package/registry/photo-grid.json +1 -1
  184. package/registry/pointer-light.json +1 -1
  185. package/registry/popover.json +1 -1
  186. package/registry/pricing-page.json +1 -1
  187. package/registry/product-page.json +1 -1
  188. package/registry/profile-card.json +1 -1
  189. package/registry/progress.json +1 -1
  190. package/registry/promise-card.json +1 -1
  191. package/registry/radio-group.json +1 -1
  192. package/registry/rail-nav.json +2 -2
  193. package/registry/recipes.json +1 -1
  194. package/registry/scroll-stage.json +1 -1
  195. package/registry/search-field.json +1 -1
  196. package/registry/section-backdrop.json +1 -1
  197. package/registry/separator.json +1 -1
  198. package/registry/service-card.json +358 -0
  199. package/registry/settings-layout.json +1 -1
  200. package/registry/showcase.json +1 -1
  201. package/registry/site-footer.json +2 -2
  202. package/registry/sites.json +2 -2
  203. package/registry/skeleton.json +3 -3
  204. package/registry/skip-link.json +1 -1
  205. package/registry/slider.json +1 -1
  206. package/registry/slot-picker.json +222 -0
  207. package/registry/slot.json +1 -1
  208. package/registry/spinner.json +1 -1
  209. package/registry/split-view.json +1 -1
  210. package/registry/stage-banner.json +1 -1
  211. package/registry/stat.json +1 -1
  212. package/registry/status-page.json +1 -1
  213. package/registry/step-progress.json +1 -1
  214. package/registry/step-showcase.json +1 -1
  215. package/registry/stepper.json +1 -1
  216. package/registry/sticky-action.json +108 -0
  217. package/registry/swipe-deck.json +1 -1
  218. package/registry/switch.json +1 -1
  219. package/registry/tabs.json +1 -1
  220. package/registry/tag-input.json +1 -1
  221. package/registry/tag-selector.json +1 -1
  222. package/registry/terminal-replay.json +1 -1
  223. package/registry/theme.json +1 -1
  224. package/registry/toast.json +1 -1
  225. package/registry/toc.json +1 -1
  226. package/registry/tooltip.json +1 -1
  227. package/registry/tree-view.json +1 -1
  228. package/registry/update-prompt.json +1 -1
  229. package/registry/verified-badge.json +1 -1
  230. package/registry/vertical-video.json +5 -5
  231. package/registry/video-player.json +3 -3
  232. package/registry/video-trimmer.json +1 -1
  233. package/registry/virtual.json +1 -1
  234. package/registry/waveform.json +1 -1
  235. package/dist/chunk-CEJDH6SA.js.map +0 -1
  236. /package/dist/{chunk-F7FVPPBB.js.map → chunk-LYOPPBMC.js.map} +0 -0
@@ -0,0 +1,73 @@
1
+ import * as tailwind_variants from 'tailwind-variants';
2
+ import * as React from 'react';
3
+
4
+ declare const mediaGallery: tailwind_variants.TVReturnType<{
5
+ [key: string]: {
6
+ [key: string]: tailwind_variants.ClassValue | {
7
+ root?: tailwind_variants.ClassValue;
8
+ media?: tailwind_variants.ClassValue;
9
+ caption?: tailwind_variants.ClassValue;
10
+ tile?: tailwind_variants.ClassValue;
11
+ };
12
+ };
13
+ } | {
14
+ [x: string]: {
15
+ [x: string]: tailwind_variants.ClassValue | {
16
+ root?: tailwind_variants.ClassValue;
17
+ media?: tailwind_variants.ClassValue;
18
+ caption?: tailwind_variants.ClassValue;
19
+ tile?: tailwind_variants.ClassValue;
20
+ };
21
+ };
22
+ } | {}, {
23
+ root: string;
24
+ tile: string;
25
+ media: string;
26
+ caption: string;
27
+ }, undefined, {
28
+ [key: string]: {
29
+ [key: string]: tailwind_variants.ClassValue | {
30
+ root?: tailwind_variants.ClassValue;
31
+ media?: tailwind_variants.ClassValue;
32
+ caption?: tailwind_variants.ClassValue;
33
+ tile?: tailwind_variants.ClassValue;
34
+ };
35
+ };
36
+ } | {}, {
37
+ root: string;
38
+ tile: string;
39
+ media: string;
40
+ caption: string;
41
+ }, tailwind_variants.TVReturnTypeLike<unknown, {
42
+ root: string;
43
+ tile: string;
44
+ media: string;
45
+ caption: string;
46
+ }>>;
47
+ type GalleryMedia = {
48
+ /** A stable id. */
49
+ id: string;
50
+ /** The still: a photo, or the poster of a loop. */
51
+ src: string;
52
+ /** What it shows, in words. */
53
+ alt: string;
54
+ /** A muted loop: WebM first, MP4 for Safari. */
55
+ video?: {
56
+ webm?: string;
57
+ mp4?: string;
58
+ };
59
+ /** One line over the foot of the tile. */
60
+ caption?: string;
61
+ /** `wide` for a landscape source (4:3 tile); the default tile is a 3:4 portrait. */
62
+ shape?: "portrait" | "wide";
63
+ };
64
+ type MediaGalleryProps = Omit<React.ComponentProps<"ul">, "children"> & {
65
+ /** The photos and loops, the featured one first. */
66
+ items: readonly GalleryMedia[];
67
+ /** The gallery's accessible name, passed translated. */
68
+ label: string;
69
+ };
70
+ /** Photos and loops in tiles, the first featured; loops play while seen. */
71
+ declare function MediaGallery({ items, label, className, ...props }: MediaGalleryProps): React.JSX.Element;
72
+
73
+ export { type GalleryMedia, MediaGallery, type MediaGalleryProps, mediaGallery };
@@ -0,0 +1,42 @@
1
+ "use client";
2
+
3
+ // src/media-gallery/media-gallery.tsx
4
+ import * as React from "react";
5
+ import { tv } from "tailwind-variants";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ var mediaGallery = tv({
8
+ slots: {
9
+ root: "m-0 grid list-none grid-cols-2 gap-2 p-0 sm:gap-3 md:grid-cols-4",
10
+ tile: "group relative isolate m-0 aspect-[3/4] overflow-hidden rounded-xl border border-border-default bg-media data-[shape=wide]:aspect-[4/3] data-[featured]:col-span-2 data-[featured]:aspect-[4/3] md:data-[featured]:aspect-auto",
11
+ media: "absolute inset-0 h-full w-full object-cover transition-transform duration-500 motion-safe:group-hover:scale-105",
12
+ caption: "pointer-events-none absolute inset-x-0 bottom-0 bg-linear-to-t from-scrim-strong to-transparent p-3 pt-8 text-xs font-semibold text-fg-on-media"
13
+ }
14
+ });
15
+ var s = mediaGallery();
16
+ function Tile({ item, featured }) {
17
+ const ref = React.useRef(null);
18
+ const [play, setPlay] = React.useState(false);
19
+ React.useEffect(() => {
20
+ const node = ref.current;
21
+ if (!item.video || !node || window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
22
+ const io = new IntersectionObserver(([entry]) => setPlay(Boolean(entry?.isIntersecting)), { rootMargin: "120px" });
23
+ io.observe(node);
24
+ return () => io.disconnect();
25
+ }, [item.video]);
26
+ return /* @__PURE__ */ jsx("li", { ref, className: s.tile(), "data-featured": featured ? "" : void 0, "data-shape": item.shape ?? "portrait", children: /* @__PURE__ */ jsxs("figure", { className: "m-0 h-full w-full", children: [
27
+ /* @__PURE__ */ jsx("img", { src: item.src, alt: item.alt, loading: "lazy", decoding: "async", className: s.media() }),
28
+ play && item.video && /* @__PURE__ */ jsxs("video", { className: s.media(), poster: item.src, autoPlay: true, muted: true, loop: true, playsInline: true, preload: "none", "aria-hidden": true, tabIndex: -1, children: [
29
+ item.video.webm && /* @__PURE__ */ jsx("source", { src: item.video.webm, type: "video/webm" }),
30
+ item.video.mp4 && /* @__PURE__ */ jsx("source", { src: item.video.mp4, type: "video/mp4" })
31
+ ] }),
32
+ item.caption && /* @__PURE__ */ jsx("figcaption", { className: s.caption(), children: item.caption })
33
+ ] }) });
34
+ }
35
+ function MediaGallery({ items, label, className, ...props }) {
36
+ return /* @__PURE__ */ jsx("ul", { "aria-label": label, className: s.root({ className }), ...props, children: items.map((item, i) => /* @__PURE__ */ jsx(Tile, { item, featured: i === 0 && items.length > 2 }, item.id)) });
37
+ }
38
+ export {
39
+ MediaGallery,
40
+ mediaGallery
41
+ };
42
+ //# sourceMappingURL=media-gallery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/media-gallery/media-gallery.tsx"],"sourcesContent":["// Client (the reader's motion preference). A shop's photos and loops in tiles: the first is the featured one, loops play\n// muted while their tile is on screen (a still under reduced motion), a caption rides the foot of a tile.\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nexport const mediaGallery = tv({\n slots: {\n root: \"m-0 grid list-none grid-cols-2 gap-2 p-0 sm:gap-3 md:grid-cols-4\",\n tile:\n \"group relative isolate m-0 aspect-[3/4] overflow-hidden rounded-xl border border-border-default bg-media data-[shape=wide]:aspect-[4/3] \" +\n // The featured tile takes two columns; from md up it has no ratio of its own and stretches to the height of the row its neighbours set.\n \"data-[featured]:col-span-2 data-[featured]:aspect-[4/3] md:data-[featured]:aspect-auto\",\n media: \"absolute inset-0 h-full w-full object-cover transition-transform duration-500 motion-safe:group-hover:scale-105\",\n caption: \"pointer-events-none absolute inset-x-0 bottom-0 bg-linear-to-t from-scrim-strong to-transparent p-3 pt-8 text-xs font-semibold text-fg-on-media\",\n },\n});\nconst s = mediaGallery();\n\nexport type GalleryMedia = {\n /** A stable id. */\n id: string;\n /** The still: a photo, or the poster of a loop. */\n src: string;\n /** What it shows, in words. */\n alt: string;\n /** A muted loop: WebM first, MP4 for Safari. */\n video?: { webm?: string; mp4?: string };\n /** One line over the foot of the tile. */\n caption?: string;\n /** `wide` for a landscape source (4:3 tile); the default tile is a 3:4 portrait. */\n shape?: \"portrait\" | \"wide\";\n};\n\nexport type MediaGalleryProps = Omit<React.ComponentProps<\"ul\">, \"children\"> & {\n /** The photos and loops, the featured one first. */\n items: readonly GalleryMedia[];\n /** The gallery's accessible name, passed translated. */\n label: string;\n};\n\nfunction Tile({ item, featured }: { item: GalleryMedia; featured: boolean }) {\n const ref = React.useRef<HTMLLIElement>(null);\n const [play, setPlay] = React.useState(false);\n React.useEffect(() => {\n const node = ref.current;\n if (!item.video || !node || window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches) return;\n const io = new IntersectionObserver(([entry]) => setPlay(Boolean(entry?.isIntersecting)), { rootMargin: \"120px\" });\n io.observe(node);\n return () => io.disconnect();\n }, [item.video]);\n return (\n <li ref={ref} className={s.tile()} data-featured={featured ? \"\" : undefined} data-shape={item.shape ?? \"portrait\"}>\n <figure className=\"m-0 h-full w-full\">\n <img src={item.src} alt={item.alt} loading=\"lazy\" decoding=\"async\" className={s.media()} />\n {play && item.video && (\n <video className={s.media()} poster={item.src} autoPlay muted loop playsInline preload=\"none\" aria-hidden tabIndex={-1}>\n {item.video.webm && <source src={item.video.webm} type=\"video/webm\" />}\n {item.video.mp4 && <source src={item.video.mp4} type=\"video/mp4\" />}\n </video>\n )}\n {item.caption && <figcaption className={s.caption()}>{item.caption}</figcaption>}\n </figure>\n </li>\n );\n}\n\n/** Photos and loops in tiles, the first featured; loops play while seen. */\nexport function MediaGallery({ items, label, className, ...props }: MediaGalleryProps) {\n return (\n <ul aria-label={label} className={s.root({ className })} {...props}>\n {items.map((item, i) => (\n <Tile key={item.id} item={item} featured={i === 0 && items.length > 2} />\n ))}\n </ul>\n );\n}\n"],"mappings":";;;AAEA,YAAY,WAAW;AACvB,SAAS,UAAU;AAkDX,cAEE,YAFF;AAhDD,IAAM,eAAe,GAAG;AAAA,EAC7B,OAAO;AAAA,IACL,MAAM;AAAA,IACN,MACE;AAAA,IAGF,OAAO;AAAA,IACP,SAAS;AAAA,EACX;AACF,CAAC;AACD,IAAM,IAAI,aAAa;AAwBvB,SAAS,KAAK,EAAE,MAAM,SAAS,GAA8C;AAC3E,QAAM,MAAY,aAAsB,IAAI;AAC5C,QAAM,CAAC,MAAM,OAAO,IAAU,eAAS,KAAK;AAC5C,EAAM,gBAAU,MAAM;AACpB,UAAM,OAAO,IAAI;AACjB,QAAI,CAAC,KAAK,SAAS,CAAC,QAAQ,OAAO,WAAW,kCAAkC,EAAE,QAAS;AAC3F,UAAM,KAAK,IAAI,qBAAqB,CAAC,CAAC,KAAK,MAAM,QAAQ,QAAQ,OAAO,cAAc,CAAC,GAAG,EAAE,YAAY,QAAQ,CAAC;AACjH,OAAG,QAAQ,IAAI;AACf,WAAO,MAAM,GAAG,WAAW;AAAA,EAC7B,GAAG,CAAC,KAAK,KAAK,CAAC;AACf,SACE,oBAAC,QAAG,KAAU,WAAW,EAAE,KAAK,GAAG,iBAAe,WAAW,KAAK,QAAW,cAAY,KAAK,SAAS,YACrG,+BAAC,YAAO,WAAU,qBAChB;AAAA,wBAAC,SAAI,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,SAAQ,QAAO,UAAS,SAAQ,WAAW,EAAE,MAAM,GAAG;AAAA,IACxF,QAAQ,KAAK,SACZ,qBAAC,WAAM,WAAW,EAAE,MAAM,GAAG,QAAQ,KAAK,KAAK,UAAQ,MAAC,OAAK,MAAC,MAAI,MAAC,aAAW,MAAC,SAAQ,QAAO,eAAW,MAAC,UAAU,IACjH;AAAA,WAAK,MAAM,QAAQ,oBAAC,YAAO,KAAK,KAAK,MAAM,MAAM,MAAK,cAAa;AAAA,MACnE,KAAK,MAAM,OAAO,oBAAC,YAAO,KAAK,KAAK,MAAM,KAAK,MAAK,aAAY;AAAA,OACnE;AAAA,IAED,KAAK,WAAW,oBAAC,gBAAW,WAAW,EAAE,QAAQ,GAAI,eAAK,SAAQ;AAAA,KACrE,GACF;AAEJ;AAGO,SAAS,aAAa,EAAE,OAAO,OAAO,WAAW,GAAG,MAAM,GAAsB;AACrF,SACE,oBAAC,QAAG,cAAY,OAAO,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC,GAAI,GAAG,OAC1D,gBAAM,IAAI,CAAC,MAAM,MAChB,oBAAC,QAAmB,MAAY,UAAU,MAAM,KAAK,MAAM,SAAS,KAAzD,KAAK,EAAuD,CACxE,GACH;AAEJ;","names":[]}
package/dist/nav-bar.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as tailwind_variants from 'tailwind-variants';
2
2
  import { NavigationMenu } from 'radix-ui';
3
3
  import * as React from 'react';
4
+ import { LanguageSwitchProps } from './language-switch.js';
4
5
  import { S as SiteId, F as FamilyLabels } from './sites-CHp_vELn.js';
5
6
 
6
7
  declare const navBar: tailwind_variants.TVReturnType<{
@@ -252,6 +253,18 @@ type NavBarBadgeProps = React.ComponentProps<"span"> & {
252
253
  };
253
254
  /** A small mono badge beside the brand: the environment and the version (`DEV · v1.2.3`). Hidden below `sm`. */
254
255
  declare function NavBarBadge({ env, version, className, children, ...props }: NavBarBadgeProps): React.JSX.Element;
256
+ type NavBarLanguageProps = Omit<LanguageSwitchProps, "variant">;
257
+ /**
258
+ * The language switch, the same on every site: in the bar a globe and the current code (FR) opening a short menu of
259
+ * the languages by their own names; inside `NavBar.Mobile` the same languages as a row in the preferences.
260
+ */
261
+ declare function NavBarLanguage(props: NavBarLanguageProps): React.JSX.Element;
262
+ type NavBarMobilePreferencesProps = Omit<React.ComponentProps<"div">, "title"> & {
263
+ /** The group's heading (“Preferences”) — passed translated. */
264
+ label: string;
265
+ };
266
+ /** The last group of the mobile panel: the preferences (theme, `NavBar.Language`), in a row under their heading. */
267
+ declare function NavBarMobilePreferences({ label, className, children, ...props }: NavBarMobilePreferencesProps): React.JSX.Element;
255
268
  type NavBarRepoProps = Omit<React.ComponentProps<"a">, "children"> & {
256
269
  /** The repository the site is built from. */
257
270
  href: string;
@@ -261,7 +274,7 @@ type NavBarRepoProps = Omit<React.ComponentProps<"a">, "children"> & {
261
274
  /** The site's repository on GitHub, an icon link of `NavBar.Actions`. */
262
275
  declare function NavBarRepo({ label, className, ...props }: NavBarRepoProps): React.JSX.Element;
263
276
  /**
264
- * `NavBar.Root/Brand/Family/Badge/Items/Link/Menu/MenuLink/Actions/Repo/Mobile/MobileGroup/MobileLink` — the Krizaka navigation bar,
277
+ * `NavBar.Root/Brand/Family/Badge/Items/Link/Menu/MenuLink/Actions/Repo/Language/Mobile/MobileGroup/MobilePreferences/MobileLink` — the Krizaka navigation bar,
265
278
  * the same on every site of the family: floating, tightening on scroll, the family switcher on the brand, one light
266
279
  * gliding between its items, accessible menus, a mobile panel.
267
280
  */
@@ -276,9 +289,34 @@ declare const NavBar: {
276
289
  MenuLink: typeof NavBarMenuLink;
277
290
  Actions: typeof NavBarActions;
278
291
  Repo: typeof NavBarRepo;
292
+ Language: typeof NavBarLanguage;
279
293
  Mobile: typeof NavBarMobile;
294
+ MobilePreferences: typeof NavBarMobilePreferences;
280
295
  MobileGroup: typeof NavBarMobileGroup;
281
296
  MobileLink: typeof NavBarMobileLink;
282
297
  };
283
298
 
284
- export { NavBar, NavBarActions, NavBarBadge, type NavBarBadgeProps, NavBarBrand, type NavBarBrandProps, NavBarFamily, type NavBarFamilyProps, NavBarItems, type NavBarItemsProps, NavBarLink, type NavBarLinkProps, NavBarMenu, NavBarMenuLink, type NavBarMenuLinkProps, type NavBarMenuProps, NavBarMobile, NavBarMobileGroup, type NavBarMobileGroupProps, NavBarMobileLink, type NavBarMobileLinkProps, type NavBarMobileProps, NavBarRepo, type NavBarRepoProps, NavBarRoot, type NavBarRootProps, navBar };
299
+ /**
300
+ * Where a menu panel of the bar sits: its left edge under its trigger's, pushed back inside the page when it would run
301
+ * past the right edge, never closer to the left edge than the gutter. All values are pixels of the page (a bounding
302
+ * rect's `left`, a width), the result is the panel's `left` relative to the bar's navigation (`root`). Pure, so a
303
+ * viewport of 360 px and one of 1280 px are tested without a browser.
304
+ */
305
+ interface PlacePanel {
306
+ /** The trigger's left edge. */
307
+ trigger: number;
308
+ /** The navigation's left edge (the panel is positioned inside it). */
309
+ root: number;
310
+ /** The panel's width. */
311
+ panel: number;
312
+ /** The window's width. */
313
+ window: number;
314
+ /**
315
+ * The space kept between the panel and the window's edges.
316
+ * @default 16
317
+ */
318
+ gutter?: number;
319
+ }
320
+ declare function placePanel({ trigger, root, panel, window, gutter }: PlacePanel): number;
321
+
322
+ export { NavBar, NavBarActions, NavBarBadge, type NavBarBadgeProps, NavBarBrand, type NavBarBrandProps, NavBarFamily, type NavBarFamilyProps, NavBarItems, type NavBarItemsProps, NavBarLanguage, type NavBarLanguageProps, NavBarLink, type NavBarLinkProps, NavBarMenu, NavBarMenuLink, type NavBarMenuLinkProps, type NavBarMenuProps, NavBarMobile, NavBarMobileGroup, type NavBarMobileGroupProps, NavBarMobileLink, type NavBarMobileLinkProps, NavBarMobilePreferences, type NavBarMobilePreferencesProps, type NavBarMobileProps, NavBarRepo, type NavBarRepoProps, NavBarRoot, type NavBarRootProps, type PlacePanel, navBar, placePanel };
package/dist/nav-bar.js CHANGED
@@ -4,7 +4,10 @@ import {
4
4
  GitHubGlyph,
5
5
  familyLabels,
6
6
  sitesByGroup
7
- } from "./chunk-FTX66XZY.js";
7
+ } from "./chunk-BCGJZ5PG.js";
8
+ import {
9
+ LanguageSwitch
10
+ } from "./chunk-3S4GHSPZ.js";
8
11
  import {
9
12
  useSlidingIndicator
10
13
  } from "./chunk-4QN5YJ3D.js";
@@ -17,6 +20,16 @@ import {
17
20
  import { NavigationMenu as Nav, Slot } from "radix-ui";
18
21
  import * as React from "react";
19
22
  import { tv } from "tailwind-variants";
23
+
24
+ // src/nav-bar/placement.ts
25
+ function placePanel({ trigger, root, panel, window: window2, gutter = 16 }) {
26
+ const wanted = trigger - root;
27
+ const farthest = window2 - gutter - panel - root;
28
+ const nearest = gutter - root;
29
+ return Math.round(Math.max(nearest, Math.min(wanted, farthest)));
30
+ }
31
+
32
+ // src/nav-bar/nav-bar.tsx
20
33
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
21
34
  var navBar = tv({
22
35
  slots: {
@@ -26,14 +39,19 @@ var navBar = tv({
26
39
  list: "group/list relative isolate flex items-center gap-0.5 before:absolute before:left-0 before:top-0 before:-z-10 before:h-(--kz-ind-h) before:w-(--kz-ind-w) before:translate-x-(--kz-ind-x) before:translate-y-(--kz-ind-y) before:rounded-full before:bg-surface-3 before:opacity-0 before:transition-[translate,width,opacity] before:duration-300 motion-reduce:before:transition-none data-[indicator=on]:before:opacity-100",
27
40
  item: "inline-flex h-9 select-none items-center gap-1 rounded-full px-3.5 text-sm font-medium text-fg-secondary no-underline transition-colors hover:text-fg data-active:text-fg data-[state=open]:text-fg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring group-not-data-[indicator=on]/list:data-active:bg-surface-3",
28
41
  chevron: "h-3.5 w-3.5 transition-transform duration-300 group-data-[state=open]/trigger:rotate-180 motion-reduce:transition-none",
29
- viewport: "kz-pop absolute left-0 top-full mt-2 h-(--radix-navigation-menu-viewport-height) w-(--radix-navigation-menu-viewport-width) origin-top-left overflow-hidden rounded-2xl border border-border-default bg-surface-1 shadow-lg transition-[width,height] duration-300 motion-reduce:transition-none",
30
- // Compact: icon · title · one line. A sensible width (20rem, 36rem in two columns) — never a sheet over the page.
31
- panel: "grid w-[min(92vw,20rem)] gap-0.5 p-1.5",
32
- panelWide: "w-[min(92vw,36rem)] md:grid-cols-2",
33
- menuLink: "group/link flex items-center gap-2.5 rounded-lg px-2.5 py-2 text-left no-underline outline-hidden transition-colors hover:bg-surface-2 focus-visible:bg-surface-2 focus-visible:ring-2 focus-visible:ring-ring data-active:bg-accent-soft",
42
+ viewport: (
43
+ // `left` is set by NavBarItems (--kz-menu-left): the panel's edge under its trigger, kept inside the page.
44
+ "kz-pop absolute left-[var(--kz-menu-left,0px)] top-full mt-2 h-(--radix-navigation-menu-viewport-height) w-(--radix-navigation-menu-viewport-width) origin-top-left overflow-hidden rounded-2xl border border-border-default bg-surface-1 shadow-lg transition-[left,width,height] duration-300 motion-reduce:transition-none"
45
+ ),
46
+ // Icon · title · a description of two lines at most. 28 rem (40 rem in two columns), never wider than the page
47
+ // between its gutters, and never taller than the screen.
48
+ panel: "grid w-[min(28rem,calc(100vw-2rem))] max-h-[calc(100dvh-6rem)] gap-0.5 overflow-y-auto p-1.5",
49
+ panelWide: "w-[min(40rem,calc(100vw-2rem))] md:grid-cols-2",
50
+ menuLink: "group/link flex items-start gap-3 rounded-lg px-2.5 py-2 text-left no-underline outline-hidden transition-colors hover:bg-surface-2 focus-visible:bg-surface-2 focus-visible:ring-2 focus-visible:ring-ring data-active:bg-accent-soft",
34
51
  menuIcon: "flex h-8 w-8 shrink-0 items-center justify-center rounded-md border border-border-default bg-surface-2 text-fg-accent transition-[transform,border-color] duration-300 group-hover/link:-translate-y-0.5 group-hover/link:border-accent [&>svg]:h-4 [&>svg]:w-4 motion-reduce:transform-none",
35
- menuTitle: "block truncate text-sm font-semibold leading-5 text-fg",
36
- menuText: "block truncate text-xs leading-4 text-fg-secondary",
52
+ menuTitle: "block line-clamp-2 wrap-break-word text-sm font-semibold leading-5 text-fg",
53
+ // Two lines at most, wrapped at word boundaries — a longer one ends in an ellipsis, never cut mid-sentence.
54
+ menuText: "mt-0.5 block line-clamp-2 wrap-break-word text-xs leading-4 text-fg-secondary",
37
55
  actions: "ml-auto flex items-center gap-2",
38
56
  toggle: "inline-flex h-9 w-9 items-center justify-center rounded-full border border-border-subtle bg-surface-2/60 text-fg md:hidden focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring",
39
57
  mobile: "kz-pop absolute inset-x-0 top-full mt-2 grid gap-1 rounded-2xl border border-border-default bg-surface-1 p-2 shadow-lg md:hidden",
@@ -110,9 +128,31 @@ function NavBarItems({ className, children, value: valueProp, defaultValue, onVa
110
128
  prefer: "[data-nav-item][data-state=open]",
111
129
  follow: true
112
130
  });
113
- return /* @__PURE__ */ jsx(ItemsContext.Provider, { value: items, children: /* @__PURE__ */ jsxs(Nav.Root, { "aria-label": label, className: s.items({ className }), value, onValueChange: setValue, delayDuration, ...props, children: [
131
+ const root = React.useRef(null);
132
+ const viewport = React.useRef(null);
133
+ React.useLayoutEffect(() => {
134
+ const panel = viewport.current;
135
+ const nav = root.current;
136
+ if (!panel || !nav || !value) return;
137
+ const place = () => {
138
+ const trigger = nav.querySelector("[data-nav-item][data-state=open]");
139
+ const width = Number.parseFloat(panel.style.getPropertyValue("--radix-navigation-menu-viewport-width"));
140
+ if (!trigger || !Number.isFinite(width)) return;
141
+ const left = `${placePanel({ trigger: trigger.getBoundingClientRect().left, root: nav.getBoundingClientRect().left, panel: width, window: document.documentElement.clientWidth })}px`;
142
+ if (panel.style.getPropertyValue("--kz-menu-left") !== left) panel.style.setProperty("--kz-menu-left", left);
143
+ };
144
+ place();
145
+ const watch = new MutationObserver(place);
146
+ watch.observe(panel, { attributes: true, attributeFilter: ["style"] });
147
+ window.addEventListener("resize", place);
148
+ return () => {
149
+ watch.disconnect();
150
+ window.removeEventListener("resize", place);
151
+ };
152
+ }, [value]);
153
+ return /* @__PURE__ */ jsx(ItemsContext.Provider, { value: items, children: /* @__PURE__ */ jsxs(Nav.Root, { ref: root, "aria-label": label, className: s.items({ className }), value, onValueChange: setValue, delayDuration, ...props, children: [
114
154
  /* @__PURE__ */ jsx(Nav.List, { ref, className: s.list(), ...handlers, children }),
115
- /* @__PURE__ */ jsx(Nav.Viewport, { className: s.viewport() })
155
+ /* @__PURE__ */ jsx(Nav.Viewport, { ref: viewport, className: s.viewport() })
116
156
  ] }) });
117
157
  }
118
158
  function NavBarLink({ active, className, onPointerEnter, ...props }) {
@@ -145,7 +185,7 @@ function NavBarMenu({ label, active, columns = 1, children, className, ...props
145
185
  function NavBarMenuLink({ title, description, icon, active, href, className, asChild, children, ...props }) {
146
186
  const body = /* @__PURE__ */ jsxs(Fragment, { children: [
147
187
  icon && /* @__PURE__ */ jsx("span", { className: s.menuIcon(), children: icon }),
148
- /* @__PURE__ */ jsxs("span", { className: "min-w-0", children: [
188
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
149
189
  /* @__PURE__ */ jsx("span", { className: s.menuTitle(), children: title }),
150
190
  description && /* @__PURE__ */ jsx("span", { className: s.menuText(), children: description })
151
191
  ] })
@@ -260,6 +300,17 @@ function NavBarBadge({ env, version, className, children, ...props }) {
260
300
  children
261
301
  ] });
262
302
  }
303
+ function NavBarLanguage(props) {
304
+ const inMobile = React.useContext(MobileContext);
305
+ return /* @__PURE__ */ jsx(LanguageSwitch, { variant: inMobile ? "inline" : "menu", ...props });
306
+ }
307
+ function NavBarMobilePreferences({ label, className, children, ...props }) {
308
+ const id = React.useId();
309
+ return /* @__PURE__ */ jsxs("div", { role: "group", "aria-labelledby": id, className: s.mobileGroup({ className }), ...props, children: [
310
+ /* @__PURE__ */ jsx("p", { id, className: s.mobileGroupTitle(), children: label }),
311
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-2 px-3 py-1", children })
312
+ ] });
313
+ }
263
314
  function NavBarRepo({ label, className, ...props }) {
264
315
  return /* @__PURE__ */ jsx("a", { "aria-label": label, className: s.repo({ className }), ...props, children: /* @__PURE__ */ jsx(GitHubGlyph, { size: 18 }) });
265
316
  }
@@ -274,7 +325,9 @@ var NavBar = {
274
325
  MenuLink: NavBarMenuLink,
275
326
  Actions: NavBarActions,
276
327
  Repo: NavBarRepo,
328
+ Language: NavBarLanguage,
277
329
  Mobile: NavBarMobile,
330
+ MobilePreferences: NavBarMobilePreferences,
278
331
  MobileGroup: NavBarMobileGroup,
279
332
  MobileLink: NavBarMobileLink
280
333
  };
@@ -285,14 +338,17 @@ export {
285
338
  NavBarBrand,
286
339
  NavBarFamily,
287
340
  NavBarItems,
341
+ NavBarLanguage,
288
342
  NavBarLink,
289
343
  NavBarMenu,
290
344
  NavBarMenuLink,
291
345
  NavBarMobile,
292
346
  NavBarMobileGroup,
293
347
  NavBarMobileLink,
348
+ NavBarMobilePreferences,
294
349
  NavBarRepo,
295
350
  NavBarRoot,
296
- navBar
351
+ navBar,
352
+ placePanel
297
353
  };
298
354
  //# sourceMappingURL=nav-bar.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/nav-bar/nav-bar.tsx"],"sourcesContent":["// Client (scroll, a sliding indicator, menus). Radix NavigationMenu does the menus' semantics and keyboard (Enter, Space\n// and ↓ open; ↑ ↓ Home End walk; Escape closes and returns the focus; Tab out closes); this file draws the Krizaka bar:\n// a floating pill that tightens once the page scrolls, one light that glides to the item under the pointer or the\n// focus and rests on the current page, and a mobile panel that is a plain disclosure (no focus trap, Escape closes).\nimport { NavigationMenu as Nav, Slot } from \"radix-ui\";\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { cn } from \"../cn\";\nimport { FamilyMark, GitHubGlyph } from \"../family-mark\";\nimport { type FamilyLabels, familyLabels, type Site, type SiteId, sitesByGroup } from \"../sites/sites\";\nimport { useSlidingIndicator } from \"../sliding-indicator\";\n\nexport const navBar = tv({\n slots: {\n root:\n \"group/nav relative z-40 mx-auto flex h-14 w-full items-center gap-2 border-border-subtle bg-surface-1/75 backdrop-blur-xl backdrop-saturate-150 \" +\n \"transition-[height,background-color,border-color,box-shadow] duration-300 motion-reduce:transition-none \" +\n \"data-compact:h-12 data-compact:border-border-default data-compact:bg-surface-1/90 data-compact:shadow-lg\",\n brand:\n \"mr-2 inline-flex shrink-0 items-center gap-2 font-display text-[15px] font-bold tracking-tight text-fg no-underline \" +\n \"rounded-md focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n items: \"relative hidden md:block\",\n list:\n \"group/list relative isolate flex items-center gap-0.5 \" +\n // The light: under the item that is pointed at or focused, resting on the current page.\n \"before:absolute before:left-0 before:top-0 before:-z-10 before:h-(--kz-ind-h) before:w-(--kz-ind-w) before:translate-x-(--kz-ind-x) before:translate-y-(--kz-ind-y) \" +\n \"before:rounded-full before:bg-surface-3 before:opacity-0 before:transition-[translate,width,opacity] before:duration-300 motion-reduce:before:transition-none \" +\n \"data-[indicator=on]:before:opacity-100\",\n item:\n \"inline-flex h-9 select-none items-center gap-1 rounded-full px-3.5 text-sm font-medium text-fg-secondary no-underline transition-colors \" +\n \"hover:text-fg data-active:text-fg data-[state=open]:text-fg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring \" +\n // Before the light is ready (server render), the current page carries its own tint.\n \"group-not-data-[indicator=on]/list:data-active:bg-surface-3\",\n chevron: \"h-3.5 w-3.5 transition-transform duration-300 group-data-[state=open]/trigger:rotate-180 motion-reduce:transition-none\",\n viewport:\n \"kz-pop absolute left-0 top-full mt-2 h-(--radix-navigation-menu-viewport-height) w-(--radix-navigation-menu-viewport-width) origin-top-left overflow-hidden \" +\n \"rounded-2xl border border-border-default bg-surface-1 shadow-lg transition-[width,height] duration-300 motion-reduce:transition-none\",\n // Compact: icon · title · one line. A sensible width (20rem, 36rem in two columns) — never a sheet over the page.\n panel: \"grid w-[min(92vw,20rem)] gap-0.5 p-1.5\",\n panelWide: \"w-[min(92vw,36rem)] md:grid-cols-2\",\n menuLink:\n \"group/link flex items-center gap-2.5 rounded-lg px-2.5 py-2 text-left no-underline outline-hidden transition-colors \" +\n \"hover:bg-surface-2 focus-visible:bg-surface-2 focus-visible:ring-2 focus-visible:ring-ring data-active:bg-accent-soft\",\n menuIcon:\n \"flex h-8 w-8 shrink-0 items-center justify-center rounded-md border border-border-default bg-surface-2 text-fg-accent \" +\n \"transition-[transform,border-color] duration-300 group-hover/link:-translate-y-0.5 group-hover/link:border-accent [&>svg]:h-4 [&>svg]:w-4 motion-reduce:transform-none\",\n menuTitle: \"block truncate text-sm font-semibold leading-5 text-fg\",\n menuText: \"block truncate text-xs leading-4 text-fg-secondary\",\n actions: \"ml-auto flex items-center gap-2\",\n toggle:\n \"inline-flex h-9 w-9 items-center justify-center rounded-full border border-border-subtle bg-surface-2/60 text-fg md:hidden \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n mobile: \"kz-pop absolute inset-x-0 top-full mt-2 grid gap-1 rounded-2xl border border-border-default bg-surface-1 p-2 shadow-lg md:hidden\",\n mobileGroup: \"grid gap-0.5 [&+&]:mt-1 [&+&]:border-t [&+&]:border-border-subtle [&+&]:pt-2\",\n mobileGroupTitle: \"px-3 pb-1 pt-1 text-[11px] font-semibold uppercase tracking-wider text-fg-secondary\",\n mobileLink:\n \"flex items-center justify-between rounded-xl px-3 py-3 text-[15px] font-medium text-fg no-underline hover:bg-surface-2 \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring aria-[current=page]:text-fg-accent\",\n // The family switcher: a chevron attached to the brand, its panel aligned on the bar's left edge.\n family: \"hidden md:block\",\n familyTrigger:\n \"group/trigger -ml-2 mr-1 inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-fg-secondary transition-colors \" +\n \"hover:bg-surface-3 hover:text-fg data-[state=open]:bg-surface-3 data-[state=open]:text-fg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n familyViewport:\n \"kz-pop absolute left-0 top-full mt-2 h-(--radix-navigation-menu-viewport-height) w-(--radix-navigation-menu-viewport-width) origin-top-left overflow-hidden \" +\n \"rounded-2xl border border-border-default bg-surface-1 shadow-lg transition-[width,height] duration-300 motion-reduce:transition-none\",\n familyPanel: \"grid w-[min(92vw,42rem)] gap-x-2 gap-y-3 p-3 sm:grid-cols-2\",\n familyGroupTitle: \"px-3 pb-1 pt-1 text-[11px] font-semibold uppercase tracking-wider text-fg-secondary\",\n familyLink:\n \"group/link flex items-start gap-3 rounded-xl px-3 py-2.5 text-left no-underline outline-hidden transition-colors \" +\n \"hover:bg-surface-2 focus-visible:bg-surface-2 focus-visible:ring-2 focus-visible:ring-ring data-current:bg-accent-soft\",\n familyMark: \"mt-0.5 flex h-7 w-7 shrink-0 items-center justify-center text-fg\",\n familyName: \"flex flex-wrap items-center gap-x-2 gap-y-0.5 text-sm font-semibold text-fg\",\n familyText: \"mt-0.5 block text-xs leading-relaxed text-fg-secondary\",\n familyTag: \"rounded-full px-1.5 py-px text-[10px] font-semibold uppercase tracking-wider\",\n mobileFamily: \"mt-1 grid gap-2 border-t border-border-subtle px-1 pb-1 pt-3\",\n mobileFamilyLink:\n \"flex min-h-11 items-center gap-3 rounded-xl px-2 py-2 text-[15px] font-medium text-fg no-underline hover:bg-surface-2 \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring data-current:bg-accent-soft\",\n badge:\n \"hidden h-6 shrink-0 items-center gap-1 rounded-full border border-border-subtle bg-surface-2 px-2 font-mono text-[11px] font-medium text-fg-secondary sm:inline-flex\",\n repo:\n \"inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-full text-fg-secondary transition-colors hover:bg-surface-3 hover:text-fg \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n },\n variants: {\n floating: {\n true: { root: \"max-w-5xl rounded-full border pl-5 pr-2 data-compact:max-w-4xl\" },\n false: { root: \"border-b px-4 md:px-6\" },\n },\n },\n defaultVariants: { floating: true },\n});\nconst s = navBar();\n\ninterface NavBarContext {\n label: string;\n open: boolean;\n setOpen: (open: boolean) => void;\n panelId: string;\n}\nconst Context = React.createContext<NavBarContext | null>(null);\n/** The open menu of `NavBar.Items` (`\"\"`: none), so a plain link can close it when the pointer moves on to it. */\nconst ItemsContext = React.createContext<{ close: () => void }>({ close: () => {} });\n/** True inside `NavBar.Mobile`: the family renders as the panel's last group instead of a switcher. */\nconst MobileContext = React.createContext(false);\nconst useNavBar = () => {\n const ctx = React.useContext(Context);\n if (!ctx) throw new Error(\"NavBar parts must be inside <NavBar.Root>.\");\n return ctx;\n};\n\nexport type NavBarRootProps = React.ComponentProps<\"header\"> & {\n /** The accessible name of the navigation (“Main”) — passed translated. */\n label: string;\n /**\n * Pixels of scroll after which the bar tightens (denser, lower, lifted). `false`: never.\n * @default 24\n */\n compactAfter?: number | false;\n /**\n * A floating pill (the Krizaka bar) or a full-width bar with a hairline under it.\n * @default true\n */\n floating?: boolean;\n};\n\n/** The bar. Place it in a `sticky top-3` (floating) or `sticky top-0` wrapper — or let it scroll. */\nexport function NavBarRoot({ label, compactAfter = 24, floating = true, className, children, ...props }: NavBarRootProps) {\n const [compact, setCompact] = React.useState(false);\n const [open, setOpen] = React.useState(false);\n const panelId = React.useId();\n React.useEffect(() => {\n if (compactAfter === false) return;\n const onScroll = () => setCompact(window.scrollY > compactAfter);\n onScroll();\n window.addEventListener(\"scroll\", onScroll, { passive: true });\n return () => window.removeEventListener(\"scroll\", onScroll);\n }, [compactAfter]);\n const ctx = React.useMemo(() => ({ label, open, setOpen, panelId }), [label, open, panelId]);\n return (\n <Context.Provider value={ctx}>\n <header data-compact={compact ? \"\" : undefined} data-floating={floating} className={navBar({ floating }).root({ className })} {...props}>\n {children}\n </header>\n </Context.Provider>\n );\n}\n\nexport type NavBarBrandProps = React.ComponentProps<\"a\"> & {\n /** Renders your link (a router `<Link>`) with the brand's look. */\n asChild?: boolean;\n};\n\n/** The brand: a mark and a name, linking home. */\nexport function NavBarBrand({ asChild, className, ...props }: NavBarBrandProps) {\n const Comp = asChild ? Slot.Root : \"a\";\n return <Comp className={s.brand({ className })} {...props} />;\n}\n\nexport type NavBarItemsProps = Omit<React.ComponentProps<typeof Nav.Root>, \"orientation\">;\n\n/**\n * The desktop navigation: links and menus, with the light that glides between them. Hidden below `md` (see\n * `NavBar.Mobile`). A menu opens on click, Enter, Space or ↓ — or when the pointer rests on its trigger (hover intent,\n * `delayDuration`, 200 ms): passing over the bar opens nothing. While a menu is open the light stays on its trigger;\n * moving on to a plain link closes the menu, so the bar never shows two current items. A click outside or Escape closes.\n */\nexport function NavBarItems({ className, children, value: valueProp, defaultValue, onValueChange, delayDuration = 200, ...props }: NavBarItemsProps) {\n const { label } = useNavBar();\n const [inner, setInner] = React.useState(defaultValue ?? \"\");\n const value = valueProp ?? inner;\n const setValue = React.useCallback(\n (next: string) => {\n setInner(next);\n onValueChange?.(next);\n },\n [onValueChange],\n );\n const items = React.useMemo(() => ({ close: () => setValue(\"\") }), [setValue]);\n const { ref, handlers } = useSlidingIndicator<HTMLUListElement>({\n item: \"[data-nav-item]\",\n active: \"[data-nav-item][data-active]\",\n prefer: \"[data-nav-item][data-state=open]\",\n follow: true,\n });\n return (\n <ItemsContext.Provider value={items}>\n <Nav.Root aria-label={label} className={s.items({ className })} value={value} onValueChange={setValue} delayDuration={delayDuration} {...props}>\n <Nav.List ref={ref} className={s.list()} {...handlers}>\n {children}\n </Nav.List>\n <Nav.Viewport className={s.viewport()} />\n </Nav.Root>\n </ItemsContext.Provider>\n );\n}\n\nexport type NavBarLinkProps = Omit<React.ComponentProps<typeof Nav.Link>, \"active\"> & {\n /** The current page: `aria-current=\"page\"`, and the light rests on it. */\n active?: boolean;\n};\n\n/** A link of the bar. `asChild` renders your router's `<Link>`. */\nexport function NavBarLink({ active, className, onPointerEnter, ...props }: NavBarLinkProps) {\n const { close } = React.useContext(ItemsContext);\n return (\n <Nav.Item>\n <Nav.Link\n data-nav-item=\"\"\n data-active={active ? \"\" : undefined}\n active={active}\n aria-current={active ? \"page\" : undefined}\n className={s.item({ className })}\n onPointerEnter={(e) => {\n onPointerEnter?.(e);\n close();\n }}\n {...props}\n />\n </Nav.Item>\n );\n}\n\nexport type NavBarMenuProps = Omit<React.ComponentProps<typeof Nav.Item>, \"children\"> & {\n /** The trigger's words (“Products”) — passed translated. */\n label: string;\n /** The current page is inside this menu: the light rests on its trigger. */\n active?: boolean;\n /** The menu's links (`NavBar.MenuLink`), laid out in a panel; `columns` sets the grid. */\n children: React.ReactNode;\n /**\n * Columns of the panel.\n * @default 1\n */\n columns?: 1 | 2;\n};\n\n/** A menu of the bar: its trigger, and its links in a panel that opens under the bar. */\nexport function NavBarMenu({ label, active, columns = 1, children, className, ...props }: NavBarMenuProps) {\n return (\n <Nav.Item className={className} {...props}>\n <Nav.Trigger data-nav-item=\"\" data-active={active ? \"\" : undefined} className={cn(s.item(), \"group/trigger\")}>\n {label}\n <svg viewBox=\"0 0 24 24\" className={s.chevron()} fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" aria-hidden>\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n </Nav.Trigger>\n <Nav.Content className={cn(s.panel(), columns === 2 && s.panelWide())}>{children}</Nav.Content>\n </Nav.Item>\n );\n}\n\nexport type NavBarMenuLinkProps = Omit<React.ComponentProps<typeof Nav.Link>, \"title\" | \"active\"> & {\n /** The link's name — passed translated. */\n title: string;\n /** One line under it — passed translated. */\n description?: string;\n /** An icon (a signature icon of `@krizaka/icons`: its node lights up on hover). */\n icon?: React.ReactNode;\n /** The current page. */\n active?: boolean;\n};\n\n/** A link inside a menu: an icon, a name and a line of text. */\nexport function NavBarMenuLink({ title, description, icon, active, href, className, asChild, children, ...props }: NavBarMenuLinkProps) {\n const body = (\n <>\n {icon && <span className={s.menuIcon()}>{icon}</span>}\n <span className=\"min-w-0\">\n <span className={s.menuTitle()}>{title}</span>\n {description && <span className={s.menuText()}>{description}</span>}\n </span>\n </>\n );\n return (\n <Nav.Link asChild={asChild} href={asChild ? undefined : href} active={active} aria-current={active ? \"page\" : undefined} data-active={active ? \"\" : undefined} className={s.menuLink({ className })} {...props}>\n {asChild && React.isValidElement<{ children?: React.ReactNode }>(children) ? React.cloneElement(children, undefined, body) : body}\n </Nav.Link>\n );\n}\n\n/** The right side: search, theme, language, the call to action. */\nexport function NavBarActions({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div className={s.actions({ className })} {...props} />;\n}\n\nexport type NavBarMobileProps = React.ComponentProps<\"nav\"> & {\n /** The toggle's name when closed (“Open the menu”) — passed translated. */\n openLabel: string;\n /** The toggle's name when open (“Close the menu”) — passed translated. */\n closeLabel: string;\n};\n\n/**\n * Below `md`: a toggle, and a panel under the bar with its links (`NavBar.MobileLink`), grouped like the bar's menus\n * (`NavBar.MobileGroup`). A disclosure: Escape, a click on a link or a press outside close it; Escape returns the focus\n * to the toggle.\n */\nexport function NavBarMobile({ openLabel, closeLabel, className, children, ...props }: NavBarMobileProps) {\n const { label, open, setOpen, panelId } = useNavBar();\n const toggle = React.useRef<HTMLButtonElement>(null);\n React.useEffect(() => {\n if (!open) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== \"Escape\") return;\n setOpen(false);\n toggle.current?.focus();\n };\n // A press outside the panel and its toggle closes it (the page under it stays usable).\n const onPress = (e: PointerEvent) => {\n const target = e.target as Node | null;\n if (!target || toggle.current?.contains(target) || document.getElementById(panelId)?.contains(target)) return;\n setOpen(false);\n };\n document.addEventListener(\"keydown\", onKey);\n document.addEventListener(\"pointerdown\", onPress);\n return () => {\n document.removeEventListener(\"keydown\", onKey);\n document.removeEventListener(\"pointerdown\", onPress);\n };\n }, [open, setOpen, panelId]);\n return (\n <>\n <button ref={toggle} type=\"button\" aria-expanded={open} aria-controls={panelId} aria-label={open ? closeLabel : openLabel} onClick={() => setOpen(!open)} className={s.toggle()}>\n <svg viewBox=\"0 0 24 24\" className=\"h-4.5 w-4.5\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" aria-hidden>\n {open ? <path d=\"M18 6 6 18M6 6l12 12\" /> : <path d=\"M4 7h16M4 12h16M4 17h10\" />}\n </svg>\n </button>\n {open && (\n <nav\n id={panelId}\n aria-label={label}\n className={s.mobile({ className })}\n onClick={(e) => {\n if ((e.target as Element).closest(\"a\")) setOpen(false);\n }}\n {...props}\n >\n <MobileContext.Provider value>{children}</MobileContext.Provider>\n </nav>\n )}\n </>\n );\n}\n\nexport type NavBarMobileGroupProps = Omit<React.ComponentProps<\"div\">, \"title\"> & {\n /** The group's heading — the same words as the bar's menu (“Product”) — passed translated. */\n label: string;\n};\n\n/** A group of the mobile panel: the links of one of the bar's menus under its name, in the same order. */\nexport function NavBarMobileGroup({ label, className, children, ...props }: NavBarMobileGroupProps) {\n const id = React.useId();\n return (\n <div role=\"group\" aria-labelledby={id} className={s.mobileGroup({ className })} {...props}>\n <p id={id} className={s.mobileGroupTitle()}>\n {label}\n </p>\n {children}\n </div>\n );\n}\n\nexport type NavBarMobileLinkProps = React.ComponentProps<\"a\"> & {\n /** The current page. */\n active?: boolean;\n /** Renders your router's `<Link>`. */\n asChild?: boolean;\n};\n\n/** A link of the mobile panel. */\nexport function NavBarMobileLink({ active, asChild, className, ...props }: NavBarMobileLinkProps) {\n const Comp = asChild ? Slot.Root : \"a\";\n return <Comp aria-current={active ? \"page\" : undefined} className={s.mobileLink({ className })} {...props} />;\n}\n\n\nconst tagTone = {\n upcoming: \"bg-accent-soft text-fg ring-1 ring-inset ring-accent/40\",\n construction: \"bg-warning/15 text-fg ring-1 ring-inset ring-warning/40\",\n development: \"bg-surface-3 text-fg ring-1 ring-inset ring-border-strong\",\n current: \"bg-surface-3 text-fg-secondary\",\n};\n\n/** A site's name and its tags: status when not released, “You are here” on the current one. */\nfunction FamilyName({ site, current, labels }: { site: Site; current: boolean; labels: FamilyLabels }) {\n return (\n <span className={s.familyName()}>\n {site.name}\n {site.status !== \"released\" && <span className={cn(s.familyTag(), tagTone[site.status])}>{labels.status[site.status]}</span>}\n {current && <span className={cn(s.familyTag(), tagTone.current)}>{labels.current}</span>}\n </span>\n );\n}\n\nexport type NavBarFamilyProps = {\n /** The site this bar belongs to (`@krizaka/ui/sites`): marked in the family, `aria-current=\"true\"`. */\n current: SiteId;\n /**\n * The family's words, passed translated: `familyLabels.fr` from `@krizaka/ui/sites`, or your own of the same shape.\n * @default familyLabels.en\n */\n labels?: FamilyLabels;\n /** Opens the panel at first render (a story, a screenshot). */\n defaultOpen?: boolean;\n /** Classes of the switcher (or, inside `NavBar.Mobile`, of the family's group). */\n className?: string;\n};\n\n/**\n * The family switcher, attached to the brand (place it right after `NavBar.Brand`): a chevron that opens every site of\n * Krizaka grouped — Krizaka · Products · Open source · GitHub — the current one marked. It opens on click, Enter, Space\n * or ↓ (never on hover); ↑ ↓ walk the sites, Escape closes and returns the focus. Hidden below `md`: place a second\n * `NavBar.Family` as the last child of `NavBar.Mobile`, where it renders as the panel's last group.\n */\nexport function NavBarFamily({ current, labels = familyLabels.en, defaultOpen, className }: NavBarFamilyProps) {\n const inMobile = React.useContext(MobileContext);\n const id = React.useId();\n const groups = sitesByGroup();\n if (inMobile) {\n return (\n <div role=\"group\" aria-labelledby={`${id}-family`} className={s.mobileFamily({ className })}>\n <p id={`${id}-family`} className={s.familyGroupTitle()}>\n {labels.family}\n </p>\n {groups.map(({ group, sites }) => (\n <div key={group}>\n {/* The company's own group is named like the family itself: its heading would repeat the panel's. */}\n {group !== \"krizaka\" && (\n <p id={`${id}-${group}`} className={s.familyGroupTitle()}>\n {labels.groups[group]}\n </p>\n )}\n <ul aria-labelledby={group !== \"krizaka\" ? `${id}-${group}` : `${id}-family`} className=\"grid gap-0.5\">\n {sites.map((site) => (\n <li key={site.id}>\n <a href={site.url} data-current={site.id === current ? \"\" : undefined} aria-current={site.id === current ? \"true\" : undefined} className={s.mobileFamilyLink()}>\n <span className={s.familyMark()}>\n <FamilyMark mark={site.mark} size={24} />\n </span>\n <FamilyName site={site} current={site.id === current} labels={labels} />\n </a>\n </li>\n ))}\n </ul>\n </div>\n ))}\n </div>\n );\n }\n // Click only: a pointer passing over the brand never opens the family (Radix opens its menus on hover by default).\n const noHover = (e: React.PointerEvent) => e.preventDefault();\n const columns = [groups.filter((g) => g.group === \"krizaka\" || g.group === \"products\"), groups.filter((g) => g.group === \"open-source\" || g.group === \"github\")];\n return (\n <Nav.Root aria-label={labels.family} defaultValue={defaultOpen ? \"family\" : undefined} className={s.family({ className })}>\n <Nav.List className=\"flex\">\n <Nav.Item value=\"family\">\n <Nav.Trigger aria-label={labels.family} onPointerMove={noHover} onPointerLeave={noHover} className={s.familyTrigger()}>\n <svg viewBox=\"0 0 24 24\" className={s.chevron()} fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" aria-hidden>\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n </Nav.Trigger>\n <Nav.Content onPointerLeave={noHover} className={s.familyPanel()}>\n {columns.map((column, i) => (\n <div key={i} className=\"grid content-start gap-3\">\n {column.map(({ group, sites }) => (\n <div key={group}>\n <p id={`${id}-${group}`} className={s.familyGroupTitle()}>\n {labels.groups[group]}\n </p>\n <ul aria-labelledby={`${id}-${group}`} className=\"grid gap-0.5\">\n {sites.map((site) => (\n <li key={site.id}>\n <Nav.Link href={site.url} data-current={site.id === current ? \"\" : undefined} aria-current={site.id === current ? \"true\" : undefined} className={s.familyLink()}>\n <span className={s.familyMark()}>\n <FamilyMark mark={site.mark} size={28} />\n </span>\n <span className=\"min-w-0\">\n <FamilyName site={site} current={site.id === current} labels={labels} />\n <span className={s.familyText()}>{labels.descriptions[site.id]}</span>\n </span>\n </Nav.Link>\n </li>\n ))}\n </ul>\n </div>\n ))}\n </div>\n ))}\n </Nav.Content>\n </Nav.Item>\n </Nav.List>\n <Nav.Viewport onPointerLeave={noHover} className={s.familyViewport()} />\n </Nav.Root>\n );\n}\n\nexport type NavBarBadgeProps = React.ComponentProps<\"span\"> & {\n /** The environment, when it is not production (`DEV`). */\n env?: string;\n /** The version the site runs (`1.2.3`, shown `v1.2.3`). */\n version?: string;\n};\n\n/** A small mono badge beside the brand: the environment and the version (`DEV · v1.2.3`). Hidden below `sm`. */\nexport function NavBarBadge({ env, version, className, children, ...props }: NavBarBadgeProps) {\n const parts = [env, version && `v${version.replace(/^v/, \"\")}`].filter(Boolean);\n return (\n <span className={s.badge({ className })} {...props}>\n {parts.join(\" · \")}\n {children}\n </span>\n );\n}\n\nexport type NavBarRepoProps = Omit<React.ComponentProps<\"a\">, \"children\"> & {\n /** The repository the site is built from. */\n href: string;\n /** The link's accessible name (“Source on GitHub”) — passed translated. */\n label: string;\n};\n\n/** The site's repository on GitHub, an icon link of `NavBar.Actions`. */\nexport function NavBarRepo({ label, className, ...props }: NavBarRepoProps) {\n return (\n <a aria-label={label} className={s.repo({ className })} {...props}>\n <GitHubGlyph size={18} />\n </a>\n );\n}\n\n/**\n * `NavBar.Root/Brand/Family/Badge/Items/Link/Menu/MenuLink/Actions/Repo/Mobile/MobileGroup/MobileLink` — the Krizaka navigation bar,\n * the same on every site of the family: floating, tightening on scroll, the family switcher on the brand, one light\n * gliding between its items, accessible menus, a mobile panel.\n */\nexport const NavBar = {\n Root: NavBarRoot,\n Brand: NavBarBrand,\n Family: NavBarFamily,\n Badge: NavBarBadge,\n Items: NavBarItems,\n Link: NavBarLink,\n Menu: NavBarMenu,\n MenuLink: NavBarMenuLink,\n Actions: NavBarActions,\n Repo: NavBarRepo,\n Mobile: NavBarMobile,\n MobileGroup: NavBarMobileGroup,\n MobileLink: NavBarMobileLink,\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/nav-bar/nav-bar.tsx","../src/nav-bar/placement.ts"],"sourcesContent":["// Client (scroll, a sliding indicator, menus). Radix NavigationMenu does the menus' semantics and keyboard (Enter, Space\n// and ↓ open; ↑ ↓ Home End walk; Escape closes and returns the focus; Tab out closes); this file draws the Krizaka bar:\n// a floating pill that tightens once the page scrolls, one light that glides to the item under the pointer or the\n// focus and rests on the current page, and a mobile panel that is a plain disclosure (no focus trap, Escape closes).\nimport { NavigationMenu as Nav, Slot } from \"radix-ui\";\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { cn } from \"../cn\";\nimport { FamilyMark, GitHubGlyph } from \"../family-mark\";\nimport { LanguageSwitch, type LanguageSwitchProps } from \"../language-switch/language-switch\";\nimport { type FamilyLabels, familyLabels, type Site, type SiteId, sitesByGroup } from \"../sites/sites\";\nimport { useSlidingIndicator } from \"../sliding-indicator\";\nimport { placePanel } from \"./placement\";\n\nexport const navBar = tv({\n slots: {\n root:\n \"group/nav relative z-40 mx-auto flex h-14 w-full items-center gap-2 border-border-subtle bg-surface-1/75 backdrop-blur-xl backdrop-saturate-150 \" +\n \"transition-[height,background-color,border-color,box-shadow] duration-300 motion-reduce:transition-none \" +\n \"data-compact:h-12 data-compact:border-border-default data-compact:bg-surface-1/90 data-compact:shadow-lg\",\n brand:\n \"mr-2 inline-flex shrink-0 items-center gap-2 font-display text-[15px] font-bold tracking-tight text-fg no-underline \" +\n \"rounded-md focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n items: \"relative hidden md:block\",\n list:\n \"group/list relative isolate flex items-center gap-0.5 \" +\n // The light: under the item that is pointed at or focused, resting on the current page.\n \"before:absolute before:left-0 before:top-0 before:-z-10 before:h-(--kz-ind-h) before:w-(--kz-ind-w) before:translate-x-(--kz-ind-x) before:translate-y-(--kz-ind-y) \" +\n \"before:rounded-full before:bg-surface-3 before:opacity-0 before:transition-[translate,width,opacity] before:duration-300 motion-reduce:before:transition-none \" +\n \"data-[indicator=on]:before:opacity-100\",\n item:\n \"inline-flex h-9 select-none items-center gap-1 rounded-full px-3.5 text-sm font-medium text-fg-secondary no-underline transition-colors \" +\n \"hover:text-fg data-active:text-fg data-[state=open]:text-fg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring \" +\n // Before the light is ready (server render), the current page carries its own tint.\n \"group-not-data-[indicator=on]/list:data-active:bg-surface-3\",\n chevron: \"h-3.5 w-3.5 transition-transform duration-300 group-data-[state=open]/trigger:rotate-180 motion-reduce:transition-none\",\n viewport:\n // `left` is set by NavBarItems (--kz-menu-left): the panel's edge under its trigger, kept inside the page.\n \"kz-pop absolute left-[var(--kz-menu-left,0px)] top-full mt-2 h-(--radix-navigation-menu-viewport-height) w-(--radix-navigation-menu-viewport-width) origin-top-left overflow-hidden \" +\n \"rounded-2xl border border-border-default bg-surface-1 shadow-lg transition-[left,width,height] duration-300 motion-reduce:transition-none\",\n // Icon · title · a description of two lines at most. 28 rem (40 rem in two columns), never wider than the page\n // between its gutters, and never taller than the screen.\n panel: \"grid w-[min(28rem,calc(100vw-2rem))] max-h-[calc(100dvh-6rem)] gap-0.5 overflow-y-auto p-1.5\",\n panelWide: \"w-[min(40rem,calc(100vw-2rem))] md:grid-cols-2\",\n menuLink:\n \"group/link flex items-start gap-3 rounded-lg px-2.5 py-2 text-left no-underline outline-hidden transition-colors \" +\n \"hover:bg-surface-2 focus-visible:bg-surface-2 focus-visible:ring-2 focus-visible:ring-ring data-active:bg-accent-soft\",\n menuIcon:\n \"flex h-8 w-8 shrink-0 items-center justify-center rounded-md border border-border-default bg-surface-2 text-fg-accent \" +\n \"transition-[transform,border-color] duration-300 group-hover/link:-translate-y-0.5 group-hover/link:border-accent [&>svg]:h-4 [&>svg]:w-4 motion-reduce:transform-none\",\n menuTitle: \"block line-clamp-2 wrap-break-word text-sm font-semibold leading-5 text-fg\",\n // Two lines at most, wrapped at word boundaries — a longer one ends in an ellipsis, never cut mid-sentence.\n menuText: \"mt-0.5 block line-clamp-2 wrap-break-word text-xs leading-4 text-fg-secondary\",\n actions: \"ml-auto flex items-center gap-2\",\n toggle:\n \"inline-flex h-9 w-9 items-center justify-center rounded-full border border-border-subtle bg-surface-2/60 text-fg md:hidden \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n mobile: \"kz-pop absolute inset-x-0 top-full mt-2 grid gap-1 rounded-2xl border border-border-default bg-surface-1 p-2 shadow-lg md:hidden\",\n mobileGroup: \"grid gap-0.5 [&+&]:mt-1 [&+&]:border-t [&+&]:border-border-subtle [&+&]:pt-2\",\n mobileGroupTitle: \"px-3 pb-1 pt-1 text-[11px] font-semibold uppercase tracking-wider text-fg-secondary\",\n mobileLink:\n \"flex items-center justify-between rounded-xl px-3 py-3 text-[15px] font-medium text-fg no-underline hover:bg-surface-2 \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring aria-[current=page]:text-fg-accent\",\n // The family switcher: a chevron attached to the brand, its panel aligned on the bar's left edge.\n family: \"hidden md:block\",\n familyTrigger:\n \"group/trigger -ml-2 mr-1 inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-fg-secondary transition-colors \" +\n \"hover:bg-surface-3 hover:text-fg data-[state=open]:bg-surface-3 data-[state=open]:text-fg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n familyViewport:\n \"kz-pop absolute left-0 top-full mt-2 h-(--radix-navigation-menu-viewport-height) w-(--radix-navigation-menu-viewport-width) origin-top-left overflow-hidden \" +\n \"rounded-2xl border border-border-default bg-surface-1 shadow-lg transition-[width,height] duration-300 motion-reduce:transition-none\",\n familyPanel: \"grid w-[min(92vw,42rem)] gap-x-2 gap-y-3 p-3 sm:grid-cols-2\",\n familyGroupTitle: \"px-3 pb-1 pt-1 text-[11px] font-semibold uppercase tracking-wider text-fg-secondary\",\n familyLink:\n \"group/link flex items-start gap-3 rounded-xl px-3 py-2.5 text-left no-underline outline-hidden transition-colors \" +\n \"hover:bg-surface-2 focus-visible:bg-surface-2 focus-visible:ring-2 focus-visible:ring-ring data-current:bg-accent-soft\",\n familyMark: \"mt-0.5 flex h-7 w-7 shrink-0 items-center justify-center text-fg\",\n familyName: \"flex flex-wrap items-center gap-x-2 gap-y-0.5 text-sm font-semibold text-fg\",\n familyText: \"mt-0.5 block text-xs leading-relaxed text-fg-secondary\",\n familyTag: \"rounded-full px-1.5 py-px text-[10px] font-semibold uppercase tracking-wider\",\n mobileFamily: \"mt-1 grid gap-2 border-t border-border-subtle px-1 pb-1 pt-3\",\n mobileFamilyLink:\n \"flex min-h-11 items-center gap-3 rounded-xl px-2 py-2 text-[15px] font-medium text-fg no-underline hover:bg-surface-2 \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring data-current:bg-accent-soft\",\n badge:\n \"hidden h-6 shrink-0 items-center gap-1 rounded-full border border-border-subtle bg-surface-2 px-2 font-mono text-[11px] font-medium text-fg-secondary sm:inline-flex\",\n repo:\n \"inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-full text-fg-secondary transition-colors hover:bg-surface-3 hover:text-fg \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n },\n variants: {\n floating: {\n true: { root: \"max-w-5xl rounded-full border pl-5 pr-2 data-compact:max-w-4xl\" },\n false: { root: \"border-b px-4 md:px-6\" },\n },\n },\n defaultVariants: { floating: true },\n});\nconst s = navBar();\n\ninterface NavBarContext {\n label: string;\n open: boolean;\n setOpen: (open: boolean) => void;\n panelId: string;\n}\nconst Context = React.createContext<NavBarContext | null>(null);\n/** The open menu of `NavBar.Items` (`\"\"`: none), so a plain link can close it when the pointer moves on to it. */\nconst ItemsContext = React.createContext<{ close: () => void }>({ close: () => {} });\n/** True inside `NavBar.Mobile`: the family renders as the panel's last group instead of a switcher. */\nconst MobileContext = React.createContext(false);\nconst useNavBar = () => {\n const ctx = React.useContext(Context);\n if (!ctx) throw new Error(\"NavBar parts must be inside <NavBar.Root>.\");\n return ctx;\n};\n\nexport type NavBarRootProps = React.ComponentProps<\"header\"> & {\n /** The accessible name of the navigation (“Main”) — passed translated. */\n label: string;\n /**\n * Pixels of scroll after which the bar tightens (denser, lower, lifted). `false`: never.\n * @default 24\n */\n compactAfter?: number | false;\n /**\n * A floating pill (the Krizaka bar) or a full-width bar with a hairline under it.\n * @default true\n */\n floating?: boolean;\n};\n\n/** The bar. Place it in a `sticky top-3` (floating) or `sticky top-0` wrapper — or let it scroll. */\nexport function NavBarRoot({ label, compactAfter = 24, floating = true, className, children, ...props }: NavBarRootProps) {\n const [compact, setCompact] = React.useState(false);\n const [open, setOpen] = React.useState(false);\n const panelId = React.useId();\n React.useEffect(() => {\n if (compactAfter === false) return;\n const onScroll = () => setCompact(window.scrollY > compactAfter);\n onScroll();\n window.addEventListener(\"scroll\", onScroll, { passive: true });\n return () => window.removeEventListener(\"scroll\", onScroll);\n }, [compactAfter]);\n const ctx = React.useMemo(() => ({ label, open, setOpen, panelId }), [label, open, panelId]);\n return (\n <Context.Provider value={ctx}>\n <header data-compact={compact ? \"\" : undefined} data-floating={floating} className={navBar({ floating }).root({ className })} {...props}>\n {children}\n </header>\n </Context.Provider>\n );\n}\n\nexport type NavBarBrandProps = React.ComponentProps<\"a\"> & {\n /** Renders your link (a router `<Link>`) with the brand's look. */\n asChild?: boolean;\n};\n\n/** The brand: a mark and a name, linking home. */\nexport function NavBarBrand({ asChild, className, ...props }: NavBarBrandProps) {\n const Comp = asChild ? Slot.Root : \"a\";\n return <Comp className={s.brand({ className })} {...props} />;\n}\n\nexport type NavBarItemsProps = Omit<React.ComponentProps<typeof Nav.Root>, \"orientation\">;\n\n/**\n * The desktop navigation: links and menus, with the light that glides between them. Hidden below `md` (see\n * `NavBar.Mobile`). A menu opens on click, Enter, Space or ↓ — or when the pointer rests on its trigger (hover intent,\n * `delayDuration`, 200 ms): passing over the bar opens nothing. While a menu is open the light stays on its trigger;\n * moving on to a plain link closes the menu, so the bar never shows two current items. A click outside or Escape closes.\n */\nexport function NavBarItems({ className, children, value: valueProp, defaultValue, onValueChange, delayDuration = 200, ...props }: NavBarItemsProps) {\n const { label } = useNavBar();\n const [inner, setInner] = React.useState(defaultValue ?? \"\");\n const value = valueProp ?? inner;\n const setValue = React.useCallback(\n (next: string) => {\n setInner(next);\n onValueChange?.(next);\n },\n [onValueChange],\n );\n const items = React.useMemo(() => ({ close: () => setValue(\"\") }), [setValue]);\n const { ref, handlers } = useSlidingIndicator<HTMLUListElement>({\n item: \"[data-nav-item]\",\n active: \"[data-nav-item][data-active]\",\n prefer: \"[data-nav-item][data-state=open]\",\n follow: true,\n });\n const root = React.useRef<HTMLElement>(null);\n const viewport = React.useRef<HTMLDivElement>(null);\n // The open panel sits under its trigger and stays inside the page (collision): measured when a menu opens, when\n // the panel changes size (another menu) and when the window does.\n React.useLayoutEffect(() => {\n const panel = viewport.current;\n const nav = root.current;\n if (!panel || !nav || !value) return;\n const place = () => {\n const trigger = nav.querySelector<HTMLElement>(\"[data-nav-item][data-state=open]\");\n const width = Number.parseFloat(panel.style.getPropertyValue(\"--radix-navigation-menu-viewport-width\"));\n if (!trigger || !Number.isFinite(width)) return;\n const left = `${placePanel({ trigger: trigger.getBoundingClientRect().left, root: nav.getBoundingClientRect().left, panel: width, window: document.documentElement.clientWidth })}px`;\n if (panel.style.getPropertyValue(\"--kz-menu-left\") !== left) panel.style.setProperty(\"--kz-menu-left\", left);\n };\n place();\n const watch = new MutationObserver(place);\n watch.observe(panel, { attributes: true, attributeFilter: [\"style\"] });\n window.addEventListener(\"resize\", place);\n return () => {\n watch.disconnect();\n window.removeEventListener(\"resize\", place);\n };\n }, [value]);\n return (\n <ItemsContext.Provider value={items}>\n <Nav.Root ref={root} aria-label={label} className={s.items({ className })} value={value} onValueChange={setValue} delayDuration={delayDuration} {...props}>\n <Nav.List ref={ref} className={s.list()} {...handlers}>\n {children}\n </Nav.List>\n <Nav.Viewport ref={viewport} className={s.viewport()} />\n </Nav.Root>\n </ItemsContext.Provider>\n );\n}\n\nexport type NavBarLinkProps = Omit<React.ComponentProps<typeof Nav.Link>, \"active\"> & {\n /** The current page: `aria-current=\"page\"`, and the light rests on it. */\n active?: boolean;\n};\n\n/** A link of the bar. `asChild` renders your router's `<Link>`. */\nexport function NavBarLink({ active, className, onPointerEnter, ...props }: NavBarLinkProps) {\n const { close } = React.useContext(ItemsContext);\n return (\n <Nav.Item>\n <Nav.Link\n data-nav-item=\"\"\n data-active={active ? \"\" : undefined}\n active={active}\n aria-current={active ? \"page\" : undefined}\n className={s.item({ className })}\n onPointerEnter={(e) => {\n onPointerEnter?.(e);\n close();\n }}\n {...props}\n />\n </Nav.Item>\n );\n}\n\nexport type NavBarMenuProps = Omit<React.ComponentProps<typeof Nav.Item>, \"children\"> & {\n /** The trigger's words (“Products”) — passed translated. */\n label: string;\n /** The current page is inside this menu: the light rests on its trigger. */\n active?: boolean;\n /** The menu's links (`NavBar.MenuLink`), laid out in a panel; `columns` sets the grid. */\n children: React.ReactNode;\n /**\n * Columns of the panel.\n * @default 1\n */\n columns?: 1 | 2;\n};\n\n/** A menu of the bar: its trigger, and its links in a panel that opens under the bar. */\nexport function NavBarMenu({ label, active, columns = 1, children, className, ...props }: NavBarMenuProps) {\n return (\n <Nav.Item className={className} {...props}>\n <Nav.Trigger data-nav-item=\"\" data-active={active ? \"\" : undefined} className={cn(s.item(), \"group/trigger\")}>\n {label}\n <svg viewBox=\"0 0 24 24\" className={s.chevron()} fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" aria-hidden>\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n </Nav.Trigger>\n <Nav.Content className={cn(s.panel(), columns === 2 && s.panelWide())}>{children}</Nav.Content>\n </Nav.Item>\n );\n}\n\nexport type NavBarMenuLinkProps = Omit<React.ComponentProps<typeof Nav.Link>, \"title\" | \"active\"> & {\n /** The link's name — passed translated. */\n title: string;\n /** One line under it — passed translated. */\n description?: string;\n /** An icon (a signature icon of `@krizaka/icons`: its node lights up on hover). */\n icon?: React.ReactNode;\n /** The current page. */\n active?: boolean;\n};\n\n/** A link inside a menu: an icon, a name and a line of text. */\nexport function NavBarMenuLink({ title, description, icon, active, href, className, asChild, children, ...props }: NavBarMenuLinkProps) {\n const body = (\n <>\n {icon && <span className={s.menuIcon()}>{icon}</span>}\n <span className=\"min-w-0 flex-1\">\n <span className={s.menuTitle()}>{title}</span>\n {description && <span className={s.menuText()}>{description}</span>}\n </span>\n </>\n );\n return (\n <Nav.Link asChild={asChild} href={asChild ? undefined : href} active={active} aria-current={active ? \"page\" : undefined} data-active={active ? \"\" : undefined} className={s.menuLink({ className })} {...props}>\n {asChild && React.isValidElement<{ children?: React.ReactNode }>(children) ? React.cloneElement(children, undefined, body) : body}\n </Nav.Link>\n );\n}\n\n/** The right side: search, theme, language, the call to action. */\nexport function NavBarActions({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div className={s.actions({ className })} {...props} />;\n}\n\nexport type NavBarMobileProps = React.ComponentProps<\"nav\"> & {\n /** The toggle's name when closed (“Open the menu”) — passed translated. */\n openLabel: string;\n /** The toggle's name when open (“Close the menu”) — passed translated. */\n closeLabel: string;\n};\n\n/**\n * Below `md`: a toggle, and a panel under the bar with its links (`NavBar.MobileLink`), grouped like the bar's menus\n * (`NavBar.MobileGroup`). A disclosure: Escape, a click on a link or a press outside close it; Escape returns the focus\n * to the toggle.\n */\nexport function NavBarMobile({ openLabel, closeLabel, className, children, ...props }: NavBarMobileProps) {\n const { label, open, setOpen, panelId } = useNavBar();\n const toggle = React.useRef<HTMLButtonElement>(null);\n React.useEffect(() => {\n if (!open) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== \"Escape\") return;\n setOpen(false);\n toggle.current?.focus();\n };\n // A press outside the panel and its toggle closes it (the page under it stays usable).\n const onPress = (e: PointerEvent) => {\n const target = e.target as Node | null;\n if (!target || toggle.current?.contains(target) || document.getElementById(panelId)?.contains(target)) return;\n setOpen(false);\n };\n document.addEventListener(\"keydown\", onKey);\n document.addEventListener(\"pointerdown\", onPress);\n return () => {\n document.removeEventListener(\"keydown\", onKey);\n document.removeEventListener(\"pointerdown\", onPress);\n };\n }, [open, setOpen, panelId]);\n return (\n <>\n <button ref={toggle} type=\"button\" aria-expanded={open} aria-controls={panelId} aria-label={open ? closeLabel : openLabel} onClick={() => setOpen(!open)} className={s.toggle()}>\n <svg viewBox=\"0 0 24 24\" className=\"h-4.5 w-4.5\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" aria-hidden>\n {open ? <path d=\"M18 6 6 18M6 6l12 12\" /> : <path d=\"M4 7h16M4 12h16M4 17h10\" />}\n </svg>\n </button>\n {open && (\n <nav\n id={panelId}\n aria-label={label}\n className={s.mobile({ className })}\n onClick={(e) => {\n if ((e.target as Element).closest(\"a\")) setOpen(false);\n }}\n {...props}\n >\n <MobileContext.Provider value>{children}</MobileContext.Provider>\n </nav>\n )}\n </>\n );\n}\n\nexport type NavBarMobileGroupProps = Omit<React.ComponentProps<\"div\">, \"title\"> & {\n /** The group's heading — the same words as the bar's menu (“Product”) — passed translated. */\n label: string;\n};\n\n/** A group of the mobile panel: the links of one of the bar's menus under its name, in the same order. */\nexport function NavBarMobileGroup({ label, className, children, ...props }: NavBarMobileGroupProps) {\n const id = React.useId();\n return (\n <div role=\"group\" aria-labelledby={id} className={s.mobileGroup({ className })} {...props}>\n <p id={id} className={s.mobileGroupTitle()}>\n {label}\n </p>\n {children}\n </div>\n );\n}\n\nexport type NavBarMobileLinkProps = React.ComponentProps<\"a\"> & {\n /** The current page. */\n active?: boolean;\n /** Renders your router's `<Link>`. */\n asChild?: boolean;\n};\n\n/** A link of the mobile panel. */\nexport function NavBarMobileLink({ active, asChild, className, ...props }: NavBarMobileLinkProps) {\n const Comp = asChild ? Slot.Root : \"a\";\n return <Comp aria-current={active ? \"page\" : undefined} className={s.mobileLink({ className })} {...props} />;\n}\n\n\nconst tagTone = {\n upcoming: \"bg-accent-soft text-fg ring-1 ring-inset ring-accent/40\",\n construction: \"bg-warning/15 text-fg ring-1 ring-inset ring-warning/40\",\n development: \"bg-surface-3 text-fg ring-1 ring-inset ring-border-strong\",\n current: \"bg-surface-3 text-fg-secondary\",\n};\n\n/** A site's name and its tags: status when not released, “You are here” on the current one. */\nfunction FamilyName({ site, current, labels }: { site: Site; current: boolean; labels: FamilyLabels }) {\n return (\n <span className={s.familyName()}>\n {site.name}\n {site.status !== \"released\" && <span className={cn(s.familyTag(), tagTone[site.status])}>{labels.status[site.status]}</span>}\n {current && <span className={cn(s.familyTag(), tagTone.current)}>{labels.current}</span>}\n </span>\n );\n}\n\nexport type NavBarFamilyProps = {\n /** The site this bar belongs to (`@krizaka/ui/sites`): marked in the family, `aria-current=\"true\"`. */\n current: SiteId;\n /**\n * The family's words, passed translated: `familyLabels.fr` from `@krizaka/ui/sites`, or your own of the same shape.\n * @default familyLabels.en\n */\n labels?: FamilyLabels;\n /** Opens the panel at first render (a story, a screenshot). */\n defaultOpen?: boolean;\n /** Classes of the switcher (or, inside `NavBar.Mobile`, of the family's group). */\n className?: string;\n};\n\n/**\n * The family switcher, attached to the brand (place it right after `NavBar.Brand`): a chevron that opens every site of\n * Krizaka grouped — Krizaka · Products · Open source · GitHub — the current one marked. It opens on click, Enter, Space\n * or ↓ (never on hover); ↑ ↓ walk the sites, Escape closes and returns the focus. Hidden below `md`: place a second\n * `NavBar.Family` as the last child of `NavBar.Mobile`, where it renders as the panel's last group.\n */\nexport function NavBarFamily({ current, labels = familyLabels.en, defaultOpen, className }: NavBarFamilyProps) {\n const inMobile = React.useContext(MobileContext);\n const id = React.useId();\n const groups = sitesByGroup();\n if (inMobile) {\n return (\n <div role=\"group\" aria-labelledby={`${id}-family`} className={s.mobileFamily({ className })}>\n <p id={`${id}-family`} className={s.familyGroupTitle()}>\n {labels.family}\n </p>\n {groups.map(({ group, sites }) => (\n <div key={group}>\n {/* The company's own group is named like the family itself: its heading would repeat the panel's. */}\n {group !== \"krizaka\" && (\n <p id={`${id}-${group}`} className={s.familyGroupTitle()}>\n {labels.groups[group]}\n </p>\n )}\n <ul aria-labelledby={group !== \"krizaka\" ? `${id}-${group}` : `${id}-family`} className=\"grid gap-0.5\">\n {sites.map((site) => (\n <li key={site.id}>\n <a href={site.url} data-current={site.id === current ? \"\" : undefined} aria-current={site.id === current ? \"true\" : undefined} className={s.mobileFamilyLink()}>\n <span className={s.familyMark()}>\n <FamilyMark mark={site.mark} size={24} />\n </span>\n <FamilyName site={site} current={site.id === current} labels={labels} />\n </a>\n </li>\n ))}\n </ul>\n </div>\n ))}\n </div>\n );\n }\n // Click only: a pointer passing over the brand never opens the family (Radix opens its menus on hover by default).\n const noHover = (e: React.PointerEvent) => e.preventDefault();\n const columns = [groups.filter((g) => g.group === \"krizaka\" || g.group === \"products\"), groups.filter((g) => g.group === \"open-source\" || g.group === \"github\")];\n return (\n <Nav.Root aria-label={labels.family} defaultValue={defaultOpen ? \"family\" : undefined} className={s.family({ className })}>\n <Nav.List className=\"flex\">\n <Nav.Item value=\"family\">\n <Nav.Trigger aria-label={labels.family} onPointerMove={noHover} onPointerLeave={noHover} className={s.familyTrigger()}>\n <svg viewBox=\"0 0 24 24\" className={s.chevron()} fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" aria-hidden>\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n </Nav.Trigger>\n <Nav.Content onPointerLeave={noHover} className={s.familyPanel()}>\n {columns.map((column, i) => (\n <div key={i} className=\"grid content-start gap-3\">\n {column.map(({ group, sites }) => (\n <div key={group}>\n <p id={`${id}-${group}`} className={s.familyGroupTitle()}>\n {labels.groups[group]}\n </p>\n <ul aria-labelledby={`${id}-${group}`} className=\"grid gap-0.5\">\n {sites.map((site) => (\n <li key={site.id}>\n <Nav.Link href={site.url} data-current={site.id === current ? \"\" : undefined} aria-current={site.id === current ? \"true\" : undefined} className={s.familyLink()}>\n <span className={s.familyMark()}>\n <FamilyMark mark={site.mark} size={28} />\n </span>\n <span className=\"min-w-0\">\n <FamilyName site={site} current={site.id === current} labels={labels} />\n <span className={s.familyText()}>{labels.descriptions[site.id]}</span>\n </span>\n </Nav.Link>\n </li>\n ))}\n </ul>\n </div>\n ))}\n </div>\n ))}\n </Nav.Content>\n </Nav.Item>\n </Nav.List>\n <Nav.Viewport onPointerLeave={noHover} className={s.familyViewport()} />\n </Nav.Root>\n );\n}\n\nexport type NavBarBadgeProps = React.ComponentProps<\"span\"> & {\n /** The environment, when it is not production (`DEV`). */\n env?: string;\n /** The version the site runs (`1.2.3`, shown `v1.2.3`). */\n version?: string;\n};\n\n/** A small mono badge beside the brand: the environment and the version (`DEV · v1.2.3`). Hidden below `sm`. */\nexport function NavBarBadge({ env, version, className, children, ...props }: NavBarBadgeProps) {\n const parts = [env, version && `v${version.replace(/^v/, \"\")}`].filter(Boolean);\n return (\n <span className={s.badge({ className })} {...props}>\n {parts.join(\" · \")}\n {children}\n </span>\n );\n}\n\nexport type NavBarLanguageProps = Omit<LanguageSwitchProps, \"variant\">;\n\n/**\n * The language switch, the same on every site: in the bar a globe and the current code (FR) opening a short menu of\n * the languages by their own names; inside `NavBar.Mobile` the same languages as a row in the preferences.\n */\nexport function NavBarLanguage(props: NavBarLanguageProps) {\n const inMobile = React.useContext(MobileContext);\n return <LanguageSwitch variant={inMobile ? \"inline\" : \"menu\"} {...props} />;\n}\n\nexport type NavBarMobilePreferencesProps = Omit<React.ComponentProps<\"div\">, \"title\"> & {\n /** The group's heading (“Preferences”) — passed translated. */\n label: string;\n};\n\n/** The last group of the mobile panel: the preferences (theme, `NavBar.Language`), in a row under their heading. */\nexport function NavBarMobilePreferences({ label, className, children, ...props }: NavBarMobilePreferencesProps) {\n const id = React.useId();\n return (\n <div role=\"group\" aria-labelledby={id} className={s.mobileGroup({ className })} {...props}>\n <p id={id} className={s.mobileGroupTitle()}>\n {label}\n </p>\n <div className=\"flex flex-wrap items-center gap-2 px-3 py-1\">{children}</div>\n </div>\n );\n}\n\nexport type NavBarRepoProps = Omit<React.ComponentProps<\"a\">, \"children\"> & {\n /** The repository the site is built from. */\n href: string;\n /** The link's accessible name (“Source on GitHub”) — passed translated. */\n label: string;\n};\n\n/** The site's repository on GitHub, an icon link of `NavBar.Actions`. */\nexport function NavBarRepo({ label, className, ...props }: NavBarRepoProps) {\n return (\n <a aria-label={label} className={s.repo({ className })} {...props}>\n <GitHubGlyph size={18} />\n </a>\n );\n}\n\n/**\n * `NavBar.Root/Brand/Family/Badge/Items/Link/Menu/MenuLink/Actions/Repo/Language/Mobile/MobileGroup/MobilePreferences/MobileLink` — the Krizaka navigation bar,\n * the same on every site of the family: floating, tightening on scroll, the family switcher on the brand, one light\n * gliding between its items, accessible menus, a mobile panel.\n */\nexport const NavBar = {\n Root: NavBarRoot,\n Brand: NavBarBrand,\n Family: NavBarFamily,\n Badge: NavBarBadge,\n Items: NavBarItems,\n Link: NavBarLink,\n Menu: NavBarMenu,\n MenuLink: NavBarMenuLink,\n Actions: NavBarActions,\n Repo: NavBarRepo,\n Language: NavBarLanguage,\n Mobile: NavBarMobile,\n MobilePreferences: NavBarMobilePreferences,\n MobileGroup: NavBarMobileGroup,\n MobileLink: NavBarMobileLink,\n};\n","/**\n * Where a menu panel of the bar sits: its left edge under its trigger's, pushed back inside the page when it would run\n * past the right edge, never closer to the left edge than the gutter. All values are pixels of the page (a bounding\n * rect's `left`, a width), the result is the panel's `left` relative to the bar's navigation (`root`). Pure, so a\n * viewport of 360 px and one of 1280 px are tested without a browser.\n */\nexport interface PlacePanel {\n /** The trigger's left edge. */\n trigger: number;\n /** The navigation's left edge (the panel is positioned inside it). */\n root: number;\n /** The panel's width. */\n panel: number;\n /** The window's width. */\n window: number;\n /**\n * The space kept between the panel and the window's edges.\n * @default 16\n */\n gutter?: number;\n}\n\nexport function placePanel({ trigger, root, panel, window, gutter = 16 }: PlacePanel): number {\n const wanted = trigger - root;\n const farthest = window - gutter - panel - root;\n const nearest = gutter - root;\n return Math.round(Math.max(nearest, Math.min(wanted, farthest)));\n}\n"],"mappings":"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","names":["window"]}