@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,119 @@
1
+ import * as tailwind_variants from 'tailwind-variants';
2
+ import * as React from 'react';
3
+ import { L as LinkComponent } from './block-link-BAg4eoZk.js';
4
+
5
+ declare const slotPicker: tailwind_variants.TVReturnType<{
6
+ [key: string]: {
7
+ [key: string]: tailwind_variants.ClassValue | {
8
+ time?: tailwind_variants.ClassValue;
9
+ note?: tailwind_variants.ClassValue;
10
+ root?: tailwind_variants.ClassValue;
11
+ days?: tailwind_variants.ClassValue;
12
+ dayName?: tailwind_variants.ClassValue;
13
+ daySub?: tailwind_variants.ClassValue;
14
+ times?: tailwind_variants.ClassValue;
15
+ empty?: tailwind_variants.ClassValue;
16
+ day?: tailwind_variants.ClassValue;
17
+ };
18
+ };
19
+ } | {
20
+ [x: string]: {
21
+ [x: string]: tailwind_variants.ClassValue | {
22
+ time?: tailwind_variants.ClassValue;
23
+ note?: tailwind_variants.ClassValue;
24
+ root?: tailwind_variants.ClassValue;
25
+ days?: tailwind_variants.ClassValue;
26
+ dayName?: tailwind_variants.ClassValue;
27
+ daySub?: tailwind_variants.ClassValue;
28
+ times?: tailwind_variants.ClassValue;
29
+ empty?: tailwind_variants.ClassValue;
30
+ day?: tailwind_variants.ClassValue;
31
+ };
32
+ };
33
+ } | {}, {
34
+ root: string;
35
+ days: string;
36
+ day: string;
37
+ dayName: string;
38
+ daySub: string;
39
+ times: string;
40
+ time: string;
41
+ note: string;
42
+ empty: string;
43
+ }, undefined, {
44
+ [key: string]: {
45
+ [key: string]: tailwind_variants.ClassValue | {
46
+ time?: tailwind_variants.ClassValue;
47
+ note?: tailwind_variants.ClassValue;
48
+ root?: tailwind_variants.ClassValue;
49
+ days?: tailwind_variants.ClassValue;
50
+ dayName?: tailwind_variants.ClassValue;
51
+ daySub?: tailwind_variants.ClassValue;
52
+ times?: tailwind_variants.ClassValue;
53
+ empty?: tailwind_variants.ClassValue;
54
+ day?: tailwind_variants.ClassValue;
55
+ };
56
+ };
57
+ } | {}, {
58
+ root: string;
59
+ days: string;
60
+ day: string;
61
+ dayName: string;
62
+ daySub: string;
63
+ times: string;
64
+ time: string;
65
+ note: string;
66
+ empty: string;
67
+ }, tailwind_variants.TVReturnTypeLike<unknown, {
68
+ root: string;
69
+ days: string;
70
+ day: string;
71
+ dayName: string;
72
+ daySub: string;
73
+ times: string;
74
+ time: string;
75
+ note: string;
76
+ empty: string;
77
+ }>>;
78
+ type PickerSlot = {
79
+ /** A stable id (the slot's start as an ISO string). */
80
+ id: string;
81
+ /** The time in words, formatted by the app (`9 h 30`). */
82
+ label: string;
83
+ /** What to know about it (`2 places left`), shown beside the time and read with it. */
84
+ note?: string;
85
+ /** Not offered any more: shown, disabled. */
86
+ disabled?: boolean;
87
+ /** Makes the time a link to this address (the booking page with the slot chosen). */
88
+ href?: string;
89
+ };
90
+ type PickerDay = {
91
+ /** A stable id (`2026-10-19`). */
92
+ id: string;
93
+ /** The day's name, translated (`Today`, `Mon`). */
94
+ label: string;
95
+ /** Under it (`19 Oct`). */
96
+ sub?: string;
97
+ /** Its free times, in order. */
98
+ slots: readonly PickerSlot[];
99
+ };
100
+ type SlotPickerProps = Omit<React.ComponentProps<"div">, "onChange" | "defaultValue"> & {
101
+ /** The days that have free times, in order. */
102
+ days: readonly PickerDay[];
103
+ /** The name of the group (`Available times`), passed translated. */
104
+ label: string;
105
+ /** Said when no day has a free time. */
106
+ emptyLabel: string;
107
+ /** The chosen slot's id (controlled). */
108
+ value?: string | null;
109
+ /** Called with the chosen slot's id. */
110
+ onValueChange?: (id: string) => void;
111
+ /** The first day shown. Default: the first of `days`. */
112
+ defaultDay?: string;
113
+ /** The app's link component for the times that have an `href`. */
114
+ linkAs?: LinkComponent;
115
+ };
116
+ /** Tappable free times by day: the day strip, then the day's chips — links or toggles. */
117
+ declare function SlotPicker({ days, label, emptyLabel, value, onValueChange, defaultDay, linkAs, className, ...props }: SlotPickerProps): React.JSX.Element;
118
+
119
+ export { type PickerDay, type PickerSlot, SlotPicker, type SlotPickerProps, slotPicker };
@@ -0,0 +1,46 @@
1
+ "use client";
2
+ import {
3
+ BlockLink
4
+ } from "./chunk-C7LTF5CC.js";
5
+
6
+ // src/slot-picker/slot-picker.tsx
7
+ import * as React from "react";
8
+ import { tv } from "tailwind-variants";
9
+ import { jsx, jsxs } from "react/jsx-runtime";
10
+ var slotPicker = tv({
11
+ slots: {
12
+ root: "flex min-w-0 flex-col gap-3",
13
+ days: "flex gap-2 overflow-x-auto p-1 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
14
+ day: "flex min-h-12 min-w-[4.5rem] shrink-0 cursor-pointer flex-col items-center justify-center rounded-xl border border-border-default bg-surface-1 px-3 py-1.5 text-center leading-tight text-fg-secondary transition-colors hover:border-border-strong hover:text-fg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring aria-pressed:border-accent aria-pressed:bg-accent-soft aria-pressed:text-fg",
15
+ dayName: "text-xs font-bold",
16
+ daySub: "text-[11px] tabular-nums text-fg-muted",
17
+ times: "m-0 flex list-none flex-wrap gap-2 p-0",
18
+ time: "inline-flex min-h-11 min-w-[4.75rem] items-center justify-center gap-1.5 rounded-full border border-border-default bg-surface-1 px-4 text-sm font-semibold tabular-nums text-fg no-underline transition-colors hover:border-accent/60 hover:bg-accent-soft focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring aria-pressed:border-accent aria-pressed:bg-accent aria-pressed:text-on-accent disabled:cursor-not-allowed disabled:opacity-50",
19
+ note: "text-[11px] font-medium text-fg-secondary group-aria-pressed:text-on-accent",
20
+ empty: "m-0 rounded-xl border border-dashed border-border-default px-4 py-6 text-center text-sm text-fg-secondary"
21
+ }
22
+ });
23
+ var s = slotPicker();
24
+ function SlotPicker({ days, label, emptyLabel, value, onValueChange, defaultDay, linkAs, className, ...props }) {
25
+ const [dayId, setDayId] = React.useState(defaultDay ?? days[0]?.id);
26
+ const active = days.find((d) => d.id === dayId) ?? days[0];
27
+ if (!active) return /* @__PURE__ */ jsx("p", { className: s.empty({ className }), children: emptyLabel });
28
+ return /* @__PURE__ */ jsxs("div", { className: s.root({ className }), ...props, children: [
29
+ /* @__PURE__ */ jsx("div", { className: s.days(), role: "group", "aria-label": label, children: days.map((day) => /* @__PURE__ */ jsxs("button", { type: "button", "aria-pressed": day.id === active.id, onClick: () => setDayId(day.id), className: s.day(), children: [
30
+ /* @__PURE__ */ jsx("span", { className: s.dayName(), children: day.label }),
31
+ day.sub && /* @__PURE__ */ jsx("span", { className: s.daySub(), children: day.sub })
32
+ ] }, day.id)) }),
33
+ /* @__PURE__ */ jsx("ul", { className: s.times(), "aria-label": `${active.label}${active.sub ? ` ${active.sub}` : ""}`, children: active.slots.map((slot) => /* @__PURE__ */ jsx("li", { children: slot.href ? /* @__PURE__ */ jsxs(BlockLink, { href: slot.href, linkAs, className: s.time(), children: [
34
+ slot.label,
35
+ slot.note && /* @__PURE__ */ jsx("span", { className: s.note(), children: slot.note })
36
+ ] }) : /* @__PURE__ */ jsxs("button", { type: "button", "aria-pressed": value === slot.id, disabled: slot.disabled, onClick: () => onValueChange?.(slot.id), className: s.time({ className: "group" }), children: [
37
+ slot.label,
38
+ slot.note && /* @__PURE__ */ jsx("span", { className: s.note(), children: slot.note })
39
+ ] }) }, slot.id)) })
40
+ ] });
41
+ }
42
+ export {
43
+ SlotPicker,
44
+ slotPicker
45
+ };
46
+ //# sourceMappingURL=slot-picker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/slot-picker/slot-picker.tsx"],"sourcesContent":["// Client (the chosen day). The next free times of a service as tappable chips: a strip of days, then the day's times.\n// A time is a link (`href`: the booking page with the time chosen) or a toggle the reader presses (`value`,\n// `onValueChange`). The app computes the slots (its availability is the truth) and formats the labels.\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { BlockLink, type LinkComponent } from \"../block-link\";\n\nexport const slotPicker = tv({\n slots: {\n root: \"flex min-w-0 flex-col gap-3\",\n days: \"flex gap-2 overflow-x-auto p-1 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden\",\n day:\n \"flex min-h-12 min-w-[4.5rem] shrink-0 cursor-pointer flex-col items-center justify-center rounded-xl border border-border-default bg-surface-1 px-3 py-1.5 text-center leading-tight text-fg-secondary \" +\n \"transition-colors hover:border-border-strong hover:text-fg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring \" +\n \"aria-pressed:border-accent aria-pressed:bg-accent-soft aria-pressed:text-fg\",\n dayName: \"text-xs font-bold\",\n daySub: \"text-[11px] tabular-nums text-fg-muted\",\n times: \"m-0 flex list-none flex-wrap gap-2 p-0\",\n time:\n \"inline-flex min-h-11 min-w-[4.75rem] items-center justify-center gap-1.5 rounded-full border border-border-default bg-surface-1 px-4 text-sm font-semibold tabular-nums text-fg no-underline \" +\n \"transition-colors hover:border-accent/60 hover:bg-accent-soft focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring \" +\n \"aria-pressed:border-accent aria-pressed:bg-accent aria-pressed:text-on-accent disabled:cursor-not-allowed disabled:opacity-50\",\n note: \"text-[11px] font-medium text-fg-secondary group-aria-pressed:text-on-accent\",\n empty: \"m-0 rounded-xl border border-dashed border-border-default px-4 py-6 text-center text-sm text-fg-secondary\",\n },\n});\nconst s = slotPicker();\n\nexport type PickerSlot = {\n /** A stable id (the slot's start as an ISO string). */\n id: string;\n /** The time in words, formatted by the app (`9 h 30`). */\n label: string;\n /** What to know about it (`2 places left`), shown beside the time and read with it. */\n note?: string;\n /** Not offered any more: shown, disabled. */\n disabled?: boolean;\n /** Makes the time a link to this address (the booking page with the slot chosen). */\n href?: string;\n};\n\nexport type PickerDay = {\n /** A stable id (`2026-10-19`). */\n id: string;\n /** The day's name, translated (`Today`, `Mon`). */\n label: string;\n /** Under it (`19 Oct`). */\n sub?: string;\n /** Its free times, in order. */\n slots: readonly PickerSlot[];\n};\n\nexport type SlotPickerProps = Omit<React.ComponentProps<\"div\">, \"onChange\" | \"defaultValue\"> & {\n /** The days that have free times, in order. */\n days: readonly PickerDay[];\n /** The name of the group (`Available times`), passed translated. */\n label: string;\n /** Said when no day has a free time. */\n emptyLabel: string;\n /** The chosen slot's id (controlled). */\n value?: string | null;\n /** Called with the chosen slot's id. */\n onValueChange?: (id: string) => void;\n /** The first day shown. Default: the first of `days`. */\n defaultDay?: string;\n /** The app's link component for the times that have an `href`. */\n linkAs?: LinkComponent;\n};\n\n/** Tappable free times by day: the day strip, then the day's chips — links or toggles. */\nexport function SlotPicker({ days, label, emptyLabel, value, onValueChange, defaultDay, linkAs, className, ...props }: SlotPickerProps) {\n const [dayId, setDayId] = React.useState(defaultDay ?? days[0]?.id);\n const active = days.find((d) => d.id === dayId) ?? days[0];\n if (!active) return <p className={s.empty({ className })}>{emptyLabel}</p>;\n return (\n <div className={s.root({ className })} {...props}>\n <div className={s.days()} role=\"group\" aria-label={label}>\n {days.map((day) => (\n <button key={day.id} type=\"button\" aria-pressed={day.id === active.id} onClick={() => setDayId(day.id)} className={s.day()}>\n <span className={s.dayName()}>{day.label}</span>\n {day.sub && <span className={s.daySub()}>{day.sub}</span>}\n </button>\n ))}\n </div>\n <ul className={s.times()} aria-label={`${active.label}${active.sub ? ` ${active.sub}` : \"\"}`}>\n {active.slots.map((slot) => (\n <li key={slot.id}>\n {slot.href ? (\n <BlockLink href={slot.href} linkAs={linkAs} className={s.time()}>\n {slot.label}\n {slot.note && <span className={s.note()}>{slot.note}</span>}\n </BlockLink>\n ) : (\n <button type=\"button\" aria-pressed={value === slot.id} disabled={slot.disabled} onClick={() => onValueChange?.(slot.id)} className={s.time({ className: \"group\" })}>\n {slot.label}\n {slot.note && <span className={s.note()}>{slot.note}</span>}\n </button>\n )}\n </li>\n ))}\n </ul>\n </div>\n );\n}\n"],"mappings":";;;;;;AAGA,YAAY,WAAW;AACvB,SAAS,UAAU;AAsEG,cAKZ,YALY;AAlEf,IAAM,aAAa,GAAG;AAAA,EAC3B,OAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN,KACE;AAAA,IAGF,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MACE;AAAA,IAGF,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AACF,CAAC;AACD,IAAM,IAAI,WAAW;AA4Cd,SAAS,WAAW,EAAE,MAAM,OAAO,YAAY,OAAO,eAAe,YAAY,QAAQ,WAAW,GAAG,MAAM,GAAoB;AACtI,QAAM,CAAC,OAAO,QAAQ,IAAU,eAAS,cAAc,KAAK,CAAC,GAAG,EAAE;AAClE,QAAM,SAAS,KAAK,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK,KAAK,KAAK,CAAC;AACzD,MAAI,CAAC,OAAQ,QAAO,oBAAC,OAAE,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,GAAI,sBAAW;AACtE,SACE,qBAAC,SAAI,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC,GAAI,GAAG,OACzC;AAAA,wBAAC,SAAI,WAAW,EAAE,KAAK,GAAG,MAAK,SAAQ,cAAY,OAChD,eAAK,IAAI,CAAC,QACT,qBAAC,YAAoB,MAAK,UAAS,gBAAc,IAAI,OAAO,OAAO,IAAI,SAAS,MAAM,SAAS,IAAI,EAAE,GAAG,WAAW,EAAE,IAAI,GACvH;AAAA,0BAAC,UAAK,WAAW,EAAE,QAAQ,GAAI,cAAI,OAAM;AAAA,MACxC,IAAI,OAAO,oBAAC,UAAK,WAAW,EAAE,OAAO,GAAI,cAAI,KAAI;AAAA,SAFvC,IAAI,EAGjB,CACD,GACH;AAAA,IACA,oBAAC,QAAG,WAAW,EAAE,MAAM,GAAG,cAAY,GAAG,OAAO,KAAK,GAAG,OAAO,MAAM,IAAI,OAAO,GAAG,KAAK,EAAE,IACvF,iBAAO,MAAM,IAAI,CAAC,SACjB,oBAAC,QACE,eAAK,OACJ,qBAAC,aAAU,MAAM,KAAK,MAAM,QAAgB,WAAW,EAAE,KAAK,GAC3D;AAAA,WAAK;AAAA,MACL,KAAK,QAAQ,oBAAC,UAAK,WAAW,EAAE,KAAK,GAAI,eAAK,MAAK;AAAA,OACtD,IAEA,qBAAC,YAAO,MAAK,UAAS,gBAAc,UAAU,KAAK,IAAI,UAAU,KAAK,UAAU,SAAS,MAAM,gBAAgB,KAAK,EAAE,GAAG,WAAW,EAAE,KAAK,EAAE,WAAW,QAAQ,CAAC,GAC9J;AAAA,WAAK;AAAA,MACL,KAAK,QAAQ,oBAAC,UAAK,WAAW,EAAE,KAAK,GAAI,eAAK,MAAK;AAAA,OACtD,KAVK,KAAK,EAYd,CACD,GACH;AAAA,KACF;AAEJ;","names":[]}
@@ -0,0 +1,12 @@
1
+ import * as tailwind_variants from 'tailwind-variants';
2
+ import * as React from 'react';
3
+
4
+ declare const stickyAction: tailwind_variants.TVReturnType<{} | {} | {}, undefined, "sticky bottom-0 z-30 border-t border-border-subtle bg-surface-1/90 px-4 pb-[max(0.75rem,env(safe-area-inset-bottom))] pt-3 backdrop-blur-xl md:hidden", {} | {}, undefined, tailwind_variants.TVReturnTypeLike<unknown, undefined>>;
5
+ type StickyActionProps = React.ComponentProps<"div"> & {
6
+ /** The action: one `ButtonLink` (full width is added). */
7
+ children: React.ReactNode;
8
+ };
9
+ /** The one action of a page, held at the bottom edge of a phone. */
10
+ declare function StickyAction({ className, children, ...props }: StickyActionProps): React.JSX.Element;
11
+
12
+ export { StickyAction, type StickyActionProps, stickyAction };
@@ -0,0 +1,14 @@
1
+ // src/sticky-action/sticky-action.tsx
2
+ import { tv } from "tailwind-variants";
3
+ import { jsx } from "react/jsx-runtime";
4
+ var stickyAction = tv({
5
+ base: "sticky bottom-0 z-30 border-t border-border-subtle bg-surface-1/90 px-4 pb-[max(0.75rem,env(safe-area-inset-bottom))] pt-3 backdrop-blur-xl md:hidden"
6
+ });
7
+ function StickyAction({ className, children, ...props }) {
8
+ return /* @__PURE__ */ jsx("div", { className: stickyAction({ className }), ...props, children: /* @__PURE__ */ jsx("div", { className: "mx-auto flex max-w-md flex-col [&>*]:w-full", children }) });
9
+ }
10
+ export {
11
+ StickyAction,
12
+ stickyAction
13
+ };
14
+ //# sourceMappingURL=sticky-action.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/sticky-action/sticky-action.tsx"],"sourcesContent":["// Server-safe: pure CSS. The main action of a page, stuck to the bottom of a phone's screen while the page scrolls: put it\n// as the last child of the page's `main` (a sticky element holds the viewport's edge inside its container). From `md` up it\n// is not drawn — the page's own buttons are within reach.\nimport type * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nexport const stickyAction = tv({\n base: \"sticky bottom-0 z-30 border-t border-border-subtle bg-surface-1/90 px-4 pb-[max(0.75rem,env(safe-area-inset-bottom))] pt-3 backdrop-blur-xl md:hidden\",\n});\n\nexport type StickyActionProps = React.ComponentProps<\"div\"> & {\n /** The action: one `ButtonLink` (full width is added). */\n children: React.ReactNode;\n};\n\n/** The one action of a page, held at the bottom edge of a phone. */\nexport function StickyAction({ className, children, ...props }: StickyActionProps) {\n return (\n <div className={stickyAction({ className })} {...props}>\n <div className=\"mx-auto flex max-w-md flex-col [&>*]:w-full\">{children}</div>\n </div>\n );\n}\n"],"mappings":";AAIA,SAAS,UAAU;AAeb;AAbC,IAAM,eAAe,GAAG;AAAA,EAC7B,MAAM;AACR,CAAC;AAQM,SAAS,aAAa,EAAE,WAAW,UAAU,GAAG,MAAM,GAAsB;AACjF,SACE,oBAAC,SAAI,WAAW,aAAa,EAAE,UAAU,CAAC,GAAI,GAAG,OAC/C,8BAAC,SAAI,WAAU,+CAA+C,UAAS,GACzE;AAEJ;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@krizaka/ui",
3
- "version": "3.24.0",
3
+ "version": "3.26.0",
4
4
  "description": "The Krizaka front-end platform's components: the primitives (button, card, dialog, toast, menu, field, tabs, chip, switch, slider, command palette, theme, countdown…) on the semantic --kz-* tokens, the animated marks (Krizaka, Orazaka, Orochia, Yasakia, Yororis) and the motion signature — web and /native.",
5
5
  "keywords": [
6
6
  "krizaka",
@@ -225,6 +225,10 @@
225
225
  "types": "./dist/nav-bar.d.ts",
226
226
  "import": "./dist/nav-bar.js"
227
227
  },
228
+ "./language-switch": {
229
+ "types": "./dist/language-switch.d.ts",
230
+ "import": "./dist/language-switch.js"
231
+ },
228
232
  "./site-footer": {
229
233
  "types": "./dist/site-footer.d.ts",
230
234
  "import": "./dist/site-footer.js"
@@ -373,6 +377,30 @@
373
377
  "types": "./dist/app-header.d.ts",
374
378
  "import": "./dist/app-header.js"
375
379
  },
380
+ "./opening-hours": {
381
+ "types": "./dist/opening-hours.d.ts",
382
+ "import": "./dist/opening-hours.js"
383
+ },
384
+ "./service-card": {
385
+ "types": "./dist/service-card.d.ts",
386
+ "import": "./dist/service-card.js"
387
+ },
388
+ "./slot-picker": {
389
+ "types": "./dist/slot-picker.d.ts",
390
+ "import": "./dist/slot-picker.js"
391
+ },
392
+ "./cover-hero": {
393
+ "types": "./dist/cover-hero.d.ts",
394
+ "import": "./dist/cover-hero.js"
395
+ },
396
+ "./media-gallery": {
397
+ "types": "./dist/media-gallery.d.ts",
398
+ "import": "./dist/media-gallery.js"
399
+ },
400
+ "./sticky-action": {
401
+ "types": "./dist/sticky-action.d.ts",
402
+ "import": "./dist/sticky-action.js"
403
+ },
376
404
  "./rail-nav": {
377
405
  "types": "./dist/rail-nav.d.ts",
378
406
  "import": "./dist/rail-nav.js"
@@ -445,6 +473,10 @@
445
473
  "types": "./dist/dashboard-layout.d.ts",
446
474
  "import": "./dist/dashboard-layout.js"
447
475
  },
476
+ "./account-menu": {
477
+ "types": "./dist/account-menu.d.ts",
478
+ "import": "./dist/account-menu.js"
479
+ },
448
480
  "./settings-layout": {
449
481
  "types": "./dist/settings-layout.d.ts",
450
482
  "import": "./dist/settings-layout.js"
@@ -677,7 +709,7 @@
677
709
  ],
678
710
  "peerDependencies": {
679
711
  "@krizaka/query": ">=0.2.1",
680
- "@krizaka/tailwind": ">=3.24.0",
712
+ "@krizaka/tailwind": ">=3.26.0",
681
713
  "@maplibre/maplibre-react-native": ">=11",
682
714
  "@shopify/flash-list": ">=2",
683
715
  "expo-camera": ">=16",
@@ -1198,7 +1230,17 @@
1198
1230
  {
1199
1231
  "name": "./nav-bar (Radix NavigationMenu, Slot, the family's marks)",
1200
1232
  "path": "dist/nav-bar.js",
1201
- "limit": "23.8 kB",
1233
+ "limit": "24.6 kB",
1234
+ "gzip": true,
1235
+ "ignore": [
1236
+ "tailwind-variants",
1237
+ "clsx"
1238
+ ]
1239
+ },
1240
+ {
1241
+ "name": "./language-switch (a disclosure)",
1242
+ "path": "dist/language-switch.js",
1243
+ "limit": "2.4 kB",
1202
1244
  "gzip": true,
1203
1245
  "ignore": [
1204
1246
  "tailwind-variants",
@@ -1346,7 +1388,7 @@
1346
1388
  "name": "./data-table: the toolbar (FilterBar on Radix DropdownMenu, SearchField, the columns menu, the export)",
1347
1389
  "path": "dist/data-table.js",
1348
1390
  "import": "{ DataTableFilters, DataTableColumnsMenu, DataTableExport }",
1349
- "limit": "41 kB",
1391
+ "limit": "42 kB",
1350
1392
  "gzip": true,
1351
1393
  "ignore": [
1352
1394
  "tailwind-variants",
@@ -1553,6 +1595,66 @@
1553
1595
  "clsx"
1554
1596
  ]
1555
1597
  },
1598
+ {
1599
+ "name": "./opening-hours",
1600
+ "path": "dist/opening-hours.js",
1601
+ "limit": "2 kB",
1602
+ "gzip": true,
1603
+ "ignore": [
1604
+ "tailwind-variants",
1605
+ "clsx"
1606
+ ]
1607
+ },
1608
+ {
1609
+ "name": "./service-card",
1610
+ "path": "dist/service-card.js",
1611
+ "limit": "2 kB",
1612
+ "gzip": true,
1613
+ "ignore": [
1614
+ "tailwind-variants",
1615
+ "clsx"
1616
+ ]
1617
+ },
1618
+ {
1619
+ "name": "./slot-picker",
1620
+ "path": "dist/slot-picker.js",
1621
+ "limit": "2 kB",
1622
+ "gzip": true,
1623
+ "ignore": [
1624
+ "tailwind-variants",
1625
+ "clsx"
1626
+ ]
1627
+ },
1628
+ {
1629
+ "name": "./cover-hero",
1630
+ "path": "dist/cover-hero.js",
1631
+ "limit": "2 kB",
1632
+ "gzip": true,
1633
+ "ignore": [
1634
+ "tailwind-variants",
1635
+ "clsx"
1636
+ ]
1637
+ },
1638
+ {
1639
+ "name": "./media-gallery",
1640
+ "path": "dist/media-gallery.js",
1641
+ "limit": "2 kB",
1642
+ "gzip": true,
1643
+ "ignore": [
1644
+ "tailwind-variants",
1645
+ "clsx"
1646
+ ]
1647
+ },
1648
+ {
1649
+ "name": "./sticky-action",
1650
+ "path": "dist/sticky-action.js",
1651
+ "limit": "1 kB",
1652
+ "gzip": true,
1653
+ "ignore": [
1654
+ "tailwind-variants",
1655
+ "clsx"
1656
+ ]
1657
+ },
1556
1658
  {
1557
1659
  "name": "./rail-nav",
1558
1660
  "path": "dist/rail-nav.js",
@@ -1809,6 +1911,18 @@
1809
1911
  "clsx"
1810
1912
  ]
1811
1913
  },
1914
+ {
1915
+ "name": "./account-menu",
1916
+ "path": "dist/account-menu.js",
1917
+ "limit": "3 kB",
1918
+ "gzip": true,
1919
+ "ignore": [
1920
+ "tailwind-variants",
1921
+ "clsx",
1922
+ "radix-ui",
1923
+ "react"
1924
+ ]
1925
+ },
1812
1926
  {
1813
1927
  "name": "./settings-layout",
1814
1928
  "path": "dist/settings-layout.js",
@@ -2071,7 +2185,7 @@
2071
2185
  {
2072
2186
  "name": "./changelog-page",
2073
2187
  "path": "dist/changelog-page.js",
2074
- "limit": "2.4 kB",
2188
+ "limit": "2.7 kB",
2075
2189
  "gzip": true,
2076
2190
  "ignore": [
2077
2191
  "tailwind-variants",
@@ -2312,9 +2426,9 @@
2312
2426
  "radix-ui": "^1.7.0",
2313
2427
  "sonner": "^2.0.8",
2314
2428
  "tailwind-variants": "^3.3.1",
2315
- "@krizaka/intl": "^0.2.1",
2429
+ "@krizaka/tokens": "^3.26.0",
2316
2430
  "@krizaka/pacer": "^0.1.0",
2317
- "@krizaka/tokens": "^3.24.0"
2431
+ "@krizaka/intl": "^0.2.1"
2318
2432
  },
2319
2433
  "scripts": {
2320
2434
  "build": "node -e \"const fs=require('node:fs');fs.rmSync('dist',{recursive:true,force:true});for(const f of fs.readdirSync('registry/examples',{recursive:true}))if(/\\.(js|d\\.ts)$/.test(f))fs.rmSync('registry/examples/'+f)\" && tsup && node -e \"require('node:fs').copyFileSync('src/motion.css','dist/motion.css');require('node:fs').copyFileSync('src/blocks.css','dist/blocks.css');require('node:fs').copyFileSync('src/story.css','dist/story.css')\" && node scripts/build-registry.mjs",