@krizaka/ui 2.3.0 → 2.4.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 (280) hide show
  1. package/README.md +16 -1
  2. package/dist/audio-player.d.ts +113 -0
  3. package/dist/audio-player.js +207 -0
  4. package/dist/audio-player.js.map +1 -0
  5. package/dist/chunk-2USC2YT6.js +17 -0
  6. package/dist/chunk-2USC2YT6.js.map +1 -0
  7. package/dist/chunk-EUPTXKH7.js +95 -0
  8. package/dist/chunk-EUPTXKH7.js.map +1 -0
  9. package/dist/chunk-RUPRYJ45.js +82 -0
  10. package/dist/chunk-RUPRYJ45.js.map +1 -0
  11. package/dist/chunk-XUMJA5ZI.js +283 -0
  12. package/dist/chunk-XUMJA5ZI.js.map +1 -0
  13. package/dist/chunk-YH4LMWRU.js +92 -0
  14. package/dist/chunk-YH4LMWRU.js.map +1 -0
  15. package/dist/chunk-YX6CNVJA.js +94 -0
  16. package/dist/chunk-YX6CNVJA.js.map +1 -0
  17. package/dist/chunk-ZIXB33X7.js +95 -0
  18. package/dist/chunk-ZIXB33X7.js.map +1 -0
  19. package/dist/combobox.d.ts +188 -0
  20. package/dist/combobox.js +16 -0
  21. package/dist/combobox.js.map +1 -0
  22. package/dist/data-table.d.ts +246 -0
  23. package/dist/data-table.js +290 -0
  24. package/dist/data-table.js.map +1 -0
  25. package/dist/date-picker.d.ts +288 -0
  26. package/dist/date-picker.js +364 -0
  27. package/dist/date-picker.js.map +1 -0
  28. package/dist/file-upload.d.ts +238 -0
  29. package/dist/file-upload.js +437 -0
  30. package/dist/file-upload.js.map +1 -0
  31. package/dist/filter-bar.d.ts +139 -0
  32. package/dist/filter-bar.js +155 -0
  33. package/dist/filter-bar.js.map +1 -0
  34. package/dist/image-cropper.d.ts +115 -0
  35. package/dist/image-cropper.js +166 -0
  36. package/dist/image-cropper.js.map +1 -0
  37. package/dist/index.js.map +1 -1
  38. package/dist/media-capture.d.ts +155 -0
  39. package/dist/media-capture.js +242 -0
  40. package/dist/media-capture.js.map +1 -0
  41. package/dist/native/media-capture.d.ts +49 -0
  42. package/dist/native/media-capture.js +113 -0
  43. package/dist/native/media-capture.js.map +1 -0
  44. package/dist/native/video-player.d.ts +50 -0
  45. package/dist/native/video-player.js +69 -0
  46. package/dist/native/video-player.js.map +1 -0
  47. package/dist/native.d.ts +66 -2
  48. package/dist/native.js +166 -68
  49. package/dist/native.js.map +1 -1
  50. package/dist/pagination.d.ts +141 -0
  51. package/dist/pagination.js +165 -0
  52. package/dist/pagination.js.map +1 -0
  53. package/dist/search-field.d.ts +100 -0
  54. package/dist/search-field.js +167 -0
  55. package/dist/search-field.js.map +1 -0
  56. package/dist/tag-input.d.ts +44 -0
  57. package/dist/tag-input.js +67 -0
  58. package/dist/tag-input.js.map +1 -0
  59. package/dist/video-player.d.ts +204 -0
  60. package/dist/video-player.js +371 -0
  61. package/dist/video-player.js.map +1 -0
  62. package/dist/video-trimmer.d.ts +142 -0
  63. package/dist/video-trimmer.js +193 -0
  64. package/dist/video-trimmer.js.map +1 -0
  65. package/package.json +232 -4
  66. package/registry/alert.json +1 -1
  67. package/registry/audio-player.json +282 -0
  68. package/registry/avatar.json +1 -1
  69. package/registry/badge.json +1 -1
  70. package/registry/button.json +1 -1
  71. package/registry/card.json +1 -1
  72. package/registry/checkbox.json +1 -1
  73. package/registry/chip-link.json +1 -1
  74. package/registry/chip.json +1 -1
  75. package/registry/combobox.json +475 -0
  76. package/registry/command.json +1 -1
  77. package/registry/confirm-button.json +1 -1
  78. package/registry/countdown.json +1 -1
  79. package/registry/data-table.json +500 -0
  80. package/registry/date-picker.json +978 -0
  81. package/registry/dialog.json +1 -1
  82. package/registry/dropdown-menu.json +1 -1
  83. package/registry/empty-state.json +1 -1
  84. package/registry/examples/audio-player/podcast.d.ts +4 -0
  85. package/registry/examples/audio-player/podcast.js +22 -0
  86. package/registry/examples/audio-player/podcast.tsx +19 -0
  87. package/registry/examples/audio-player/voice-note.d.ts +4 -0
  88. package/registry/examples/audio-player/voice-note.js +12 -0
  89. package/registry/examples/audio-player/voice-note.tsx +12 -0
  90. package/registry/examples/combobox/async.d.ts +4 -0
  91. package/registry/examples/combobox/async.js +23 -0
  92. package/registry/examples/combobox/async.tsx +22 -0
  93. package/registry/examples/combobox/creatable.d.ts +4 -0
  94. package/registry/examples/combobox/creatable.js +32 -0
  95. package/registry/examples/combobox/creatable.tsx +28 -0
  96. package/registry/examples/combobox/invalid.d.ts +4 -0
  97. package/registry/examples/combobox/invalid.js +23 -0
  98. package/registry/examples/combobox/invalid.tsx +17 -0
  99. package/registry/examples/combobox/multiple.d.ts +4 -0
  100. package/registry/examples/combobox/multiple.js +29 -0
  101. package/registry/examples/combobox/multiple.tsx +26 -0
  102. package/registry/examples/data-table/cards.d.ts +4 -0
  103. package/registry/examples/data-table/cards.js +21 -0
  104. package/registry/examples/data-table/cards.tsx +20 -0
  105. package/registry/examples/data-table/empty.d.ts +4 -0
  106. package/registry/examples/data-table/empty.js +26 -0
  107. package/registry/examples/data-table/empty.tsx +21 -0
  108. package/registry/examples/data-table/error.d.ts +4 -0
  109. package/registry/examples/data-table/error.js +28 -0
  110. package/registry/examples/data-table/error.tsx +29 -0
  111. package/registry/examples/data-table/jobs.d.ts +4 -0
  112. package/registry/examples/data-table/jobs.js +37 -0
  113. package/registry/examples/data-table/jobs.tsx +36 -0
  114. package/registry/examples/data-table/loading.d.ts +4 -0
  115. package/registry/examples/data-table/loading.js +16 -0
  116. package/registry/examples/data-table/loading.tsx +12 -0
  117. package/registry/examples/data-table/virtualized.d.ts +4 -0
  118. package/registry/examples/data-table/virtualized.js +21 -0
  119. package/registry/examples/data-table/virtualized.tsx +20 -0
  120. package/registry/examples/date-picker/calendar.d.ts +4 -0
  121. package/registry/examples/date-picker/calendar.js +14 -0
  122. package/registry/examples/date-picker/calendar.tsx +16 -0
  123. package/registry/examples/date-picker/french.d.ts +4 -0
  124. package/registry/examples/date-picker/french.js +20 -0
  125. package/registry/examples/date-picker/french.tsx +14 -0
  126. package/registry/examples/date-picker/open.d.ts +4 -0
  127. package/registry/examples/date-picker/open.js +11 -0
  128. package/registry/examples/date-picker/open.tsx +8 -0
  129. package/registry/examples/date-picker/range.d.ts +4 -0
  130. package/registry/examples/date-picker/range.js +29 -0
  131. package/registry/examples/date-picker/range.tsx +25 -0
  132. package/registry/examples/date-picker/schedule.d.ts +4 -0
  133. package/registry/examples/date-picker/schedule.js +26 -0
  134. package/registry/examples/date-picker/schedule.tsx +22 -0
  135. package/registry/examples/file-upload/images.d.ts +4 -0
  136. package/registry/examples/file-upload/images.js +32 -0
  137. package/registry/examples/file-upload/images.tsx +25 -0
  138. package/registry/examples/file-upload/states.d.ts +4 -0
  139. package/registry/examples/file-upload/states.js +28 -0
  140. package/registry/examples/file-upload/states.tsx +23 -0
  141. package/registry/examples/file-upload/tus.d.ts +4 -0
  142. package/registry/examples/file-upload/tus.js +23 -0
  143. package/registry/examples/file-upload/tus.tsx +26 -0
  144. package/registry/examples/file-upload/video.d.ts +4 -0
  145. package/registry/examples/file-upload/video.js +39 -0
  146. package/registry/examples/file-upload/video.tsx +36 -0
  147. package/registry/examples/filter-bar/address.d.ts +4 -0
  148. package/registry/examples/filter-bar/address.js +29 -0
  149. package/registry/examples/filter-bar/address.tsx +27 -0
  150. package/registry/examples/filter-bar/jobs.d.ts +4 -0
  151. package/registry/examples/filter-bar/jobs.js +37 -0
  152. package/registry/examples/filter-bar/jobs.tsx +37 -0
  153. package/registry/examples/filter-bar/menu.d.ts +4 -0
  154. package/registry/examples/filter-bar/menu.js +27 -0
  155. package/registry/examples/filter-bar/menu.tsx +23 -0
  156. package/registry/examples/image-cropper/avatar.d.ts +4 -0
  157. package/registry/examples/image-cropper/avatar.js +13 -0
  158. package/registry/examples/image-cropper/avatar.tsx +14 -0
  159. package/registry/examples/image-cropper/banner.d.ts +4 -0
  160. package/registry/examples/image-cropper/banner.js +11 -0
  161. package/registry/examples/image-cropper/banner.tsx +10 -0
  162. package/registry/examples/image-cropper/vertical-video.d.ts +4 -0
  163. package/registry/examples/image-cropper/vertical-video.js +12 -0
  164. package/registry/examples/image-cropper/vertical-video.tsx +16 -0
  165. package/registry/examples/media-capture/clip.d.ts +4 -0
  166. package/registry/examples/media-capture/clip.js +20 -0
  167. package/registry/examples/media-capture/clip.tsx +18 -0
  168. package/registry/examples/media-capture/native/photo.d.ts +4 -0
  169. package/registry/examples/media-capture/native/photo.dark.png +0 -0
  170. package/registry/examples/media-capture/native/photo.js +27 -0
  171. package/registry/examples/media-capture/native/photo.light.png +0 -0
  172. package/registry/examples/media-capture/native/photo.tsx +20 -0
  173. package/registry/examples/media-capture/profile-photo.d.ts +4 -0
  174. package/registry/examples/media-capture/profile-photo.js +24 -0
  175. package/registry/examples/media-capture/profile-photo.tsx +20 -0
  176. package/registry/examples/pagination/cursor.d.ts +4 -0
  177. package/registry/examples/pagination/cursor.js +24 -0
  178. package/registry/examples/pagination/cursor.tsx +20 -0
  179. package/registry/examples/pagination/links.d.ts +4 -0
  180. package/registry/examples/pagination/links.js +11 -0
  181. package/registry/examples/pagination/links.tsx +6 -0
  182. package/registry/examples/pagination/native/cursor.d.ts +4 -0
  183. package/registry/examples/pagination/native/cursor.dark.png +0 -0
  184. package/registry/examples/pagination/native/cursor.js +19 -0
  185. package/registry/examples/pagination/native/cursor.light.png +0 -0
  186. package/registry/examples/pagination/native/cursor.tsx +13 -0
  187. package/registry/examples/pagination/native/pages.d.ts +4 -0
  188. package/registry/examples/pagination/native/pages.dark.png +0 -0
  189. package/registry/examples/pagination/native/pages.js +21 -0
  190. package/registry/examples/pagination/native/pages.light.png +0 -0
  191. package/registry/examples/pagination/native/pages.tsx +14 -0
  192. package/registry/examples/pagination/results.d.ts +4 -0
  193. package/registry/examples/pagination/results.js +23 -0
  194. package/registry/examples/pagination/results.tsx +19 -0
  195. package/registry/examples/pagination/table-footer.d.ts +4 -0
  196. package/registry/examples/pagination/table-footer.js +31 -0
  197. package/registry/examples/pagination/table-footer.tsx +27 -0
  198. package/registry/examples/search-field/global.d.ts +4 -0
  199. package/registry/examples/search-field/global.js +19 -0
  200. package/registry/examples/search-field/global.tsx +15 -0
  201. package/registry/examples/search-field/native/default.d.ts +4 -0
  202. package/registry/examples/search-field/native/default.dark.png +0 -0
  203. package/registry/examples/search-field/native/default.js +13 -0
  204. package/registry/examples/search-field/native/default.light.png +0 -0
  205. package/registry/examples/search-field/native/default.tsx +7 -0
  206. package/registry/examples/search-field/suggestions.d.ts +4 -0
  207. package/registry/examples/search-field/suggestions.js +30 -0
  208. package/registry/examples/search-field/suggestions.tsx +27 -0
  209. package/registry/examples/search-field/toolbar.d.ts +4 -0
  210. package/registry/examples/search-field/toolbar.js +17 -0
  211. package/registry/examples/search-field/toolbar.tsx +21 -0
  212. package/registry/examples/tag-input/recipients.d.ts +4 -0
  213. package/registry/examples/tag-input/recipients.js +23 -0
  214. package/registry/examples/tag-input/recipients.tsx +20 -0
  215. package/registry/examples/tag-input/video-tags.d.ts +4 -0
  216. package/registry/examples/tag-input/video-tags.js +26 -0
  217. package/registry/examples/tag-input/video-tags.tsx +22 -0
  218. package/registry/examples/video-player/default.d.ts +4 -0
  219. package/registry/examples/video-player/default.js +12 -0
  220. package/registry/examples/video-player/default.tsx +8 -0
  221. package/registry/examples/video-player/gated.d.ts +4 -0
  222. package/registry/examples/video-player/gated.js +26 -0
  223. package/registry/examples/video-player/gated.tsx +23 -0
  224. package/registry/examples/video-player/native/default.d.ts +4 -0
  225. package/registry/examples/video-player/native/default.dark.png +0 -0
  226. package/registry/examples/video-player/native/default.js +18 -0
  227. package/registry/examples/video-player/native/default.light.png +0 -0
  228. package/registry/examples/video-player/native/default.tsx +12 -0
  229. package/registry/examples/video-player/signed-source.d.ts +4 -0
  230. package/registry/examples/video-player/signed-source.js +16 -0
  231. package/registry/examples/video-player/signed-source.tsx +15 -0
  232. package/registry/examples/video-player/vertical.d.ts +4 -0
  233. package/registry/examples/video-player/vertical.js +12 -0
  234. package/registry/examples/video-player/vertical.tsx +12 -0
  235. package/registry/examples/video-trimmer/custom.d.ts +4 -0
  236. package/registry/examples/video-trimmer/custom.js +24 -0
  237. package/registry/examples/video-trimmer/custom.tsx +26 -0
  238. package/registry/examples/video-trimmer/filmstrip.d.ts +4 -0
  239. package/registry/examples/video-trimmer/filmstrip.js +15 -0
  240. package/registry/examples/video-trimmer/filmstrip.tsx +13 -0
  241. package/registry/examples/video-trimmer/playhead.d.ts +4 -0
  242. package/registry/examples/video-trimmer/playhead.js +15 -0
  243. package/registry/examples/video-trimmer/playhead.tsx +13 -0
  244. package/registry/field.json +1 -1
  245. package/registry/file-upload.json +471 -0
  246. package/registry/filter-bar.json +347 -0
  247. package/registry/glow-card.json +1 -1
  248. package/registry/image-cropper.json +313 -0
  249. package/registry/index.json +255 -1
  250. package/registry/iso.json +1 -1
  251. package/registry/kbd.json +1 -1
  252. package/registry/loader.json +1 -1
  253. package/registry/marquee.json +1 -1
  254. package/registry/mascots.json +1 -1
  255. package/registry/media-capture.json +347 -0
  256. package/registry/meter.json +3 -3
  257. package/registry/nav-bar.json +1 -1
  258. package/registry/number-ticker.json +1 -1
  259. package/registry/page-header.json +1 -1
  260. package/registry/pagination.json +475 -0
  261. package/registry/popover.json +1 -1
  262. package/registry/progress.json +5 -5
  263. package/registry/radio-group.json +1 -1
  264. package/registry/search-field.json +436 -0
  265. package/registry/section-backdrop.json +1 -1
  266. package/registry/separator.json +1 -1
  267. package/registry/skeleton.json +1 -1
  268. package/registry/slider.json +1 -1
  269. package/registry/slot.json +1 -1
  270. package/registry/spinner.json +1 -1
  271. package/registry/stat.json +1 -1
  272. package/registry/stepper.json +1 -1
  273. package/registry/switch.json +1 -1
  274. package/registry/tabs.json +1 -1
  275. package/registry/tag-input.json +363 -0
  276. package/registry/theme.json +1 -1
  277. package/registry/toast.json +1 -1
  278. package/registry/tooltip.json +1 -1
  279. package/registry/video-player.json +598 -0
  280. package/registry/video-trimmer.json +385 -0
@@ -0,0 +1,36 @@
1
+ "use client";
2
+
3
+ import { Dropzone, UploadList, useUploadQueue } from "@krizaka/ui/file-upload";
4
+
5
+ // A stand-in for your client (Tus, multipart…): it reports progress and stops when the signal aborts.
6
+ function fakeUpload(file: File, { signal, onProgress }: { signal: AbortSignal; onProgress: (sent: number) => void }) {
7
+ return new Promise<void>((resolve) => {
8
+ let sent = 0;
9
+ const timer = setInterval(() => {
10
+ sent = Math.min(file.size, sent + file.size / 40);
11
+ onProgress(sent);
12
+ if (sent < file.size) return;
13
+ clearInterval(timer);
14
+ resolve();
15
+ }, 150);
16
+ signal.addEventListener("abort", () => clearInterval(timer));
17
+ });
18
+ }
19
+
20
+ export default function FileUploadVideo() {
21
+ const queue = useUploadQueue({ upload: fakeUpload });
22
+ return (
23
+ <div className="flex w-full max-w-lg flex-col gap-3">
24
+ <Dropzone
25
+ title="Drop your video here"
26
+ browseLabel="Choose a video"
27
+ hint="MP4, MOV or WebM, up to 4 GB"
28
+ accept="video/*"
29
+ maxSize={4 * 1024 ** 3}
30
+ onFiles={queue.add}
31
+ refusalLabel={(r) => `${r.file.name}: ${r.reason === "size" ? "larger than 4 GB" : "not a video"}`}
32
+ />
33
+ {queue.items.length > 0 && <UploadList items={queue.items} onPause={queue.pause} onResume={queue.resume} onCancel={queue.cancel} onRemove={queue.remove} onRetry={queue.retry} />}
34
+ </div>
35
+ );
36
+ }
@@ -0,0 +1,4 @@
1
+ import type { ComponentType } from "react";
2
+ /** A named example of the @krizaka/ui registry; `defaultOpen` opens what it opens (a dialog, a menu, toasts) at load. */
3
+ declare const Example: ComponentType<{ defaultOpen?: boolean }>;
4
+ export default Example;
@@ -0,0 +1,29 @@
1
+ "use client";
2
+
3
+ // registry/examples/filter-bar/address.tsx
4
+ import { FilterBar, FilterMenu, readFilterParams, writeFilterParams } from "@krizaka/ui/filter-bar";
5
+ import * as React from "react";
6
+ import { jsx } from "react/jsx-runtime";
7
+ var ROLES = [
8
+ { value: "creator", label: "Creator" },
9
+ { value: "fan", label: "Fan" },
10
+ { value: "admin", label: "Admin" }
11
+ ];
12
+ function FilterBarAddress() {
13
+ const [params, setParams] = React.useState(() => new URLSearchParams("role=creator,admin&page=3"));
14
+ const { role } = readFilterParams(params, ["role"]);
15
+ const set = (next) => setParams(writeFilterParams(params, { role: next }));
16
+ return /* @__PURE__ */ jsx(
17
+ FilterBar,
18
+ {
19
+ label: "Filter users",
20
+ active: role.map((r) => ({ id: r, label: `Role: ${ROLES.find((o) => o.value === r)?.label}`, onRemove: () => set(role.filter((x) => x !== r)) })),
21
+ onClearAll: () => set([]),
22
+ results: `?${params.toString()}`,
23
+ children: /* @__PURE__ */ jsx(FilterMenu, { label: "Role", options: ROLES, value: role, onValueChange: set })
24
+ }
25
+ );
26
+ }
27
+ export {
28
+ FilterBarAddress as default
29
+ };
@@ -0,0 +1,27 @@
1
+ "use client";
2
+
3
+ import { FilterBar, FilterMenu, readFilterParams, writeFilterParams } from "@krizaka/ui/filter-bar";
4
+ import * as React from "react";
5
+
6
+ const ROLES = [
7
+ { value: "creator", label: "Creator" },
8
+ { value: "fan", label: "Fan" },
9
+ { value: "admin", label: "Admin" },
10
+ ];
11
+
12
+ // The address is the state: read it, write it back (the page goes back to 1). In Next.js: useSearchParams + router.replace.
13
+ export default function FilterBarAddress() {
14
+ const [params, setParams] = React.useState(() => new URLSearchParams("role=creator,admin&page=3"));
15
+ const { role } = readFilterParams(params, ["role"]);
16
+ const set = (next: string[]) => setParams(writeFilterParams(params, { role: next }));
17
+ return (
18
+ <FilterBar
19
+ label="Filter users"
20
+ active={role!.map((r) => ({ id: r, label: `Role: ${ROLES.find((o) => o.value === r)?.label}`, onRemove: () => set(role!.filter((x) => x !== r)) }))}
21
+ onClearAll={() => set([])}
22
+ results={`?${params.toString()}`}
23
+ >
24
+ <FilterMenu label="Role" options={ROLES} value={role!} onValueChange={set} />
25
+ </FilterBar>
26
+ );
27
+ }
@@ -0,0 +1,4 @@
1
+ import type { ComponentType } from "react";
2
+ /** A named example of the @krizaka/ui registry; `defaultOpen` opens what it opens (a dialog, a menu, toasts) at load. */
3
+ declare const Example: ComponentType<{ defaultOpen?: boolean }>;
4
+ export default Example;
@@ -0,0 +1,37 @@
1
+ "use client";
2
+
3
+ // registry/examples/filter-bar/jobs.tsx
4
+ import { FilterBar, FilterMenu } from "@krizaka/ui/filter-bar";
5
+ import { SearchField } from "@krizaka/ui/search-field";
6
+ import * as React from "react";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ var STATUS = [
9
+ { value: "running", label: "Running", count: 3 },
10
+ { value: "done", label: "Done", count: 128 },
11
+ { value: "failed", label: "Failed", count: 6 }
12
+ ];
13
+ var MODELS = [
14
+ { value: "", label: "All models" },
15
+ { value: "flux", label: "Flux 1.1" },
16
+ { value: "whisper", label: "Whisper large" }
17
+ ];
18
+ function FilterBarJobs() {
19
+ const [query, setQuery] = React.useState("");
20
+ const [status, setStatus] = React.useState(["failed"]);
21
+ const [model, setModel] = React.useState("flux");
22
+ const active = [
23
+ ...status.map((s) => ({ id: `status:${s}`, label: `Status: ${STATUS.find((o) => o.value === s)?.label}`, onRemove: () => setStatus(status.filter((x) => x !== s)) })),
24
+ ...model ? [{ id: "model", label: `Model: ${MODELS.find((m) => m.value === model)?.label}`, onRemove: () => setModel("") }] : []
25
+ ];
26
+ return /* @__PURE__ */ jsxs(FilterBar, { label: "Filter jobs", active, onClearAll: () => {
27
+ setStatus([]);
28
+ setModel("");
29
+ }, results: "6 jobs", children: [
30
+ /* @__PURE__ */ jsx(SearchField, { label: "Search jobs", placeholder: "Search jobs", value: query, onValueChange: setQuery, landmark: false, className: "sm:max-w-64" }),
31
+ /* @__PURE__ */ jsx(FilterMenu, { label: "Status", options: STATUS, value: status, onValueChange: setStatus }),
32
+ /* @__PURE__ */ jsx(FilterMenu, { label: "Model", multiple: false, options: MODELS, value: model, onValueChange: setModel })
33
+ ] });
34
+ }
35
+ export {
36
+ FilterBarJobs as default
37
+ };
@@ -0,0 +1,37 @@
1
+ "use client";
2
+
3
+ import { FilterBar, FilterMenu } from "@krizaka/ui/filter-bar";
4
+ import { SearchField } from "@krizaka/ui/search-field";
5
+ import * as React from "react";
6
+
7
+ const STATUS = [
8
+ { value: "running", label: "Running", count: 3 },
9
+ { value: "done", label: "Done", count: 128 },
10
+ { value: "failed", label: "Failed", count: 6 },
11
+ ];
12
+ const MODELS = [
13
+ { value: "", label: "All models" },
14
+ { value: "flux", label: "Flux 1.1" },
15
+ { value: "whisper", label: "Whisper large" },
16
+ ];
17
+
18
+ // Several criteria at once; each one in force is a chip that undoes it.
19
+ export default function FilterBarJobs() {
20
+ const [query, setQuery] = React.useState("");
21
+ const [status, setStatus] = React.useState(["failed"]);
22
+ const [model, setModel] = React.useState("flux");
23
+ const active = [
24
+ ...status.map((s) => ({ id: `status:${s}`, label: `Status: ${STATUS.find((o) => o.value === s)?.label}`, onRemove: () => setStatus(status.filter((x) => x !== s)) })),
25
+ ...(model ? [{ id: "model", label: `Model: ${MODELS.find((m) => m.value === model)?.label}`, onRemove: () => setModel("") }] : []),
26
+ ];
27
+ return (
28
+ <FilterBar label="Filter jobs" active={active} onClearAll={() => {
29
+ setStatus([]);
30
+ setModel("");
31
+ }} results="6 jobs">
32
+ <SearchField label="Search jobs" placeholder="Search jobs" value={query} onValueChange={setQuery} landmark={false} className="sm:max-w-64" />
33
+ <FilterMenu label="Status" options={STATUS} value={status} onValueChange={setStatus} />
34
+ <FilterMenu label="Model" multiple={false} options={MODELS} value={model} onValueChange={setModel} />
35
+ </FilterBar>
36
+ );
37
+ }
@@ -0,0 +1,4 @@
1
+ import type { ComponentType } from "react";
2
+ /** A named example of the @krizaka/ui registry; `defaultOpen` opens what it opens (a dialog, a menu, toasts) at load. */
3
+ declare const Example: ComponentType<{ defaultOpen?: boolean }>;
4
+ export default Example;
@@ -0,0 +1,27 @@
1
+ "use client";
2
+
3
+ // registry/examples/filter-bar/menu.tsx
4
+ import { FilterMenu } from "@krizaka/ui/filter-bar";
5
+ import * as React from "react";
6
+ import { jsx } from "react/jsx-runtime";
7
+ function FilterBarMenu({ defaultOpen }) {
8
+ const [formats, setFormats] = React.useState(["vertical"]);
9
+ return /* @__PURE__ */ jsx(
10
+ FilterMenu,
11
+ {
12
+ label: "Format",
13
+ defaultOpen,
14
+ options: [
15
+ { value: "vertical", label: "Vertical", count: 214 },
16
+ { value: "landscape", label: "Landscape", count: 96 },
17
+ { value: "square", label: "Square", count: 12 },
18
+ { value: "audio", label: "Audio only", count: 0, disabled: true }
19
+ ],
20
+ value: formats,
21
+ onValueChange: setFormats
22
+ }
23
+ );
24
+ }
25
+ export {
26
+ FilterBarMenu as default
27
+ };
@@ -0,0 +1,23 @@
1
+ "use client";
2
+
3
+ import { FilterMenu } from "@krizaka/ui/filter-bar";
4
+ import * as React from "react";
5
+
6
+ // A filter's menu: checkboxes, and what each value would give.
7
+ export default function FilterBarMenu({ defaultOpen }: { defaultOpen?: boolean }) {
8
+ const [formats, setFormats] = React.useState(["vertical"]);
9
+ return (
10
+ <FilterMenu
11
+ label="Format"
12
+ defaultOpen={defaultOpen}
13
+ options={[
14
+ { value: "vertical", label: "Vertical", count: 214 },
15
+ { value: "landscape", label: "Landscape", count: 96 },
16
+ { value: "square", label: "Square", count: 12 },
17
+ { value: "audio", label: "Audio only", count: 0, disabled: true },
18
+ ]}
19
+ value={formats}
20
+ onValueChange={setFormats}
21
+ />
22
+ );
23
+ }
@@ -0,0 +1,4 @@
1
+ import type { ComponentType } from "react";
2
+ /** A named example of the @krizaka/ui registry; `defaultOpen` opens what it opens (a dialog, a menu, toasts) at load. */
3
+ declare const Example: ComponentType<{ defaultOpen?: boolean }>;
4
+ export default Example;
@@ -0,0 +1,13 @@
1
+ "use client";
2
+
3
+ // registry/examples/image-cropper/avatar.tsx
4
+ import { ImageCropper } from "@krizaka/ui/image-cropper";
5
+ import * as React from "react";
6
+ import { jsx } from "react/jsx-runtime";
7
+ function ImageCropperAvatar() {
8
+ const [crop, setCrop] = React.useState({ x: 0.42, y: 0.5, zoom: 1.4 });
9
+ return /* @__PURE__ */ jsx("div", { className: "w-64", children: /* @__PURE__ */ jsx(ImageCropper, { src: "https://www.krizaka.com/assets/orochia/tour/elena-live.jpg", aspect: 1, round: true, value: crop, onValueChange: setCrop }) });
10
+ }
11
+ export {
12
+ ImageCropperAvatar as default
13
+ };
@@ -0,0 +1,14 @@
1
+ "use client";
2
+
3
+ import { type CropValue, ImageCropper } from "@krizaka/ui/image-cropper";
4
+ import * as React from "react";
5
+
6
+ // A round mask on a square frame: what others will see. Send the focus point and the zoom with the file.
7
+ export default function ImageCropperAvatar() {
8
+ const [crop, setCrop] = React.useState<CropValue>({ x: 0.42, y: 0.5, zoom: 1.4 });
9
+ return (
10
+ <div className="w-64">
11
+ <ImageCropper src="https://www.krizaka.com/assets/orochia/tour/elena-live.jpg" aspect={1} round value={crop} onValueChange={setCrop} />
12
+ </div>
13
+ );
14
+ }
@@ -0,0 +1,4 @@
1
+ import type { ComponentType } from "react";
2
+ /** A named example of the @krizaka/ui registry; `defaultOpen` opens what it opens (a dialog, a menu, toasts) at load. */
3
+ declare const Example: ComponentType<{ defaultOpen?: boolean }>;
4
+ export default Example;
@@ -0,0 +1,11 @@
1
+ "use client";
2
+
3
+ // registry/examples/image-cropper/banner.tsx
4
+ import { ImageCropper } from "@krizaka/ui/image-cropper";
5
+ import { jsx } from "react/jsx-runtime";
6
+ function ImageCropperBanner() {
7
+ return /* @__PURE__ */ jsx("div", { className: "w-full max-w-lg", children: /* @__PURE__ */ jsx(ImageCropper, { src: "https://www.krizaka.com/assets/orochia/tour/alex-discover.jpg", aspect: 3, defaultValue: { x: 0.5, y: 0.45, zoom: 1.2 }, labels: { frame: "Cover picture" } }) });
8
+ }
9
+ export {
10
+ ImageCropperBanner as default
11
+ };
@@ -0,0 +1,10 @@
1
+ import { ImageCropper } from "@krizaka/ui/image-cropper";
2
+
3
+ // A profile's cover: a 3:1 frame, zoomed in on the centre.
4
+ export default function ImageCropperBanner() {
5
+ return (
6
+ <div className="w-full max-w-lg">
7
+ <ImageCropper src="https://www.krizaka.com/assets/orochia/tour/alex-discover.jpg" aspect={3} defaultValue={{ x: 0.5, y: 0.45, zoom: 1.2 }} labels={{ frame: "Cover picture" }} />
8
+ </div>
9
+ );
10
+ }
@@ -0,0 +1,4 @@
1
+ import type { ComponentType } from "react";
2
+ /** A named example of the @krizaka/ui registry; `defaultOpen` opens what it opens (a dialog, a menu, toasts) at load. */
3
+ declare const Example: ComponentType<{ defaultOpen?: boolean }>;
4
+ export default Example;
@@ -0,0 +1,12 @@
1
+ "use client";
2
+
3
+ // registry/examples/image-cropper/vertical-video.tsx
4
+ import { ImageCropper } from "@krizaka/ui/image-cropper";
5
+ import { jsx } from "react/jsx-runtime";
6
+ var TOUR = "https://www.krizaka.com/assets/orochia/tour";
7
+ function ImageCropperVerticalVideo() {
8
+ return /* @__PURE__ */ jsx("div", { className: "w-48", children: /* @__PURE__ */ jsx(ImageCropper, { aspect: 9 / 16, naturalSize: { width: 1280, height: 800 }, defaultValue: { x: 0.35, y: 0.5, zoom: 1 }, showZoom: false, labels: { frame: "Vertical frame" }, children: /* @__PURE__ */ jsx("video", { src: `${TOUR}/elena-earnings.mp4`, poster: `${TOUR}/elena-earnings.jpg`, muted: true, playsInline: true, preload: "none", "aria-hidden": true }) }) });
9
+ }
10
+ export {
11
+ ImageCropperVerticalVideo as default
12
+ };
@@ -0,0 +1,16 @@
1
+ "use client";
2
+
3
+ import { ImageCropper } from "@krizaka/ui/image-cropper";
4
+
5
+ const TOUR = "https://www.krizaka.com/assets/orochia/tour";
6
+
7
+ // A landscape video, a 9:16 frame: choose what the vertical version keeps. The size is the video's own.
8
+ export default function ImageCropperVerticalVideo() {
9
+ return (
10
+ <div className="w-48">
11
+ <ImageCropper aspect={9 / 16} naturalSize={{ width: 1280, height: 800 }} defaultValue={{ x: 0.35, y: 0.5, zoom: 1 }} showZoom={false} labels={{ frame: "Vertical frame" }}>
12
+ <video src={`${TOUR}/elena-earnings.mp4`} poster={`${TOUR}/elena-earnings.jpg`} muted playsInline preload="none" aria-hidden />
13
+ </ImageCropper>
14
+ </div>
15
+ );
16
+ }
@@ -0,0 +1,4 @@
1
+ import type { ComponentType } from "react";
2
+ /** A named example of the @krizaka/ui registry; `defaultOpen` opens what it opens (a dialog, a menu, toasts) at load. */
3
+ declare const Example: ComponentType<{ defaultOpen?: boolean }>;
4
+ export default Example;
@@ -0,0 +1,20 @@
1
+ "use client";
2
+
3
+ // registry/examples/media-capture/clip.tsx
4
+ import { MediaCapture } from "@krizaka/ui/media-capture";
5
+ import { jsx } from "react/jsx-runtime";
6
+ function MediaCaptureClip() {
7
+ return /* @__PURE__ */ jsx("div", { className: "w-72", children: /* @__PURE__ */ jsx(
8
+ MediaCapture,
9
+ {
10
+ mode: "both",
11
+ maxDuration: 60,
12
+ aspectRatio: "9 / 16",
13
+ onCapture: (result) => console.info(result.kind, result.blob.size),
14
+ labels: { prompt: "Film a story of up to 60 seconds, or take a photo." }
15
+ }
16
+ ) });
17
+ }
18
+ export {
19
+ MediaCaptureClip as default
20
+ };
@@ -0,0 +1,18 @@
1
+ "use client";
2
+
3
+ import { MediaCapture } from "@krizaka/ui/media-capture";
4
+
5
+ // A photo or a clip of 60 seconds at most, for a story; the blob goes to the upload queue.
6
+ export default function MediaCaptureClip() {
7
+ return (
8
+ <div className="w-72">
9
+ <MediaCapture
10
+ mode="both"
11
+ maxDuration={60}
12
+ aspectRatio="9 / 16"
13
+ onCapture={(result) => console.info(result.kind, result.blob.size)}
14
+ labels={{ prompt: "Film a story of up to 60 seconds, or take a photo." }}
15
+ />
16
+ </div>
17
+ );
18
+ }
@@ -0,0 +1,4 @@
1
+ import type { ComponentType } from "react";
2
+ /** A named example of the @krizaka/ui registry; `defaultOpen` opens what it opens (a dialog, a menu, toasts) at load. */
3
+ declare const Example: ComponentType<{ defaultOpen?: boolean }>;
4
+ export default Example;
@@ -0,0 +1,27 @@
1
+ "use client";
2
+
3
+ // registry/examples/media-capture/native/photo.tsx
4
+ import { MediaCapture } from "@krizaka/ui/native/media-capture";
5
+ import { jsx } from "react/jsx-runtime";
6
+ function NativeMediaCapturePhoto() {
7
+ return /* @__PURE__ */ jsx(
8
+ MediaCapture,
9
+ {
10
+ mode: "photo",
11
+ onCapture: ({ uri }) => console.info(uri),
12
+ labels: {
13
+ prompt: "Take a profile picture with your camera.",
14
+ start: "Turn on the camera",
15
+ denied: "Camera access is off. Turn it on in Settings.",
16
+ settings: "Open Settings",
17
+ takePhoto: "Take photo",
18
+ startRecording: "Start recording",
19
+ stopRecording: "Stop recording",
20
+ switchCamera: "Switch camera"
21
+ }
22
+ }
23
+ );
24
+ }
25
+ export {
26
+ NativeMediaCapturePhoto as default
27
+ };
@@ -0,0 +1,20 @@
1
+ import { MediaCapture } from "@krizaka/ui/native/media-capture";
2
+
3
+ export default function NativeMediaCapturePhoto() {
4
+ return (
5
+ <MediaCapture
6
+ mode="photo"
7
+ onCapture={({ uri }) => console.info(uri)}
8
+ labels={{
9
+ prompt: "Take a profile picture with your camera.",
10
+ start: "Turn on the camera",
11
+ denied: "Camera access is off. Turn it on in Settings.",
12
+ settings: "Open Settings",
13
+ takePhoto: "Take photo",
14
+ startRecording: "Start recording",
15
+ stopRecording: "Stop recording",
16
+ switchCamera: "Switch camera",
17
+ }}
18
+ />
19
+ );
20
+ }
@@ -0,0 +1,4 @@
1
+ import type { ComponentType } from "react";
2
+ /** A named example of the @krizaka/ui registry; `defaultOpen` opens what it opens (a dialog, a menu, toasts) at load. */
3
+ declare const Example: ComponentType<{ defaultOpen?: boolean }>;
4
+ export default Example;
@@ -0,0 +1,24 @@
1
+ "use client";
2
+
3
+ // registry/examples/media-capture/profile-photo.tsx
4
+ import { MediaCapture } from "@krizaka/ui/media-capture";
5
+ import * as React from "react";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ function MediaCaptureProfilePhoto() {
8
+ const [photo, setPhoto] = React.useState(null);
9
+ return /* @__PURE__ */ jsxs("div", { className: "flex w-72 flex-col gap-3", children: [
10
+ /* @__PURE__ */ jsx(
11
+ MediaCapture,
12
+ {
13
+ mode: "photo",
14
+ facing: "user",
15
+ onCapture: (result) => setPhoto(result.url),
16
+ labels: { prompt: "Take a profile picture with your camera.", start: "Turn on the camera" }
17
+ }
18
+ ),
19
+ photo && /* @__PURE__ */ jsx("img", { src: photo, alt: "Your new profile picture", className: "h-20 w-20 rounded-full object-cover" })
20
+ ] });
21
+ }
22
+ export {
23
+ MediaCaptureProfilePhoto as default
24
+ };
@@ -0,0 +1,20 @@
1
+ "use client";
2
+
3
+ import { MediaCapture } from "@krizaka/ui/media-capture";
4
+ import * as React from "react";
5
+
6
+ // The front camera, a photo; the browser asks only when the button is pressed.
7
+ export default function MediaCaptureProfilePhoto() {
8
+ const [photo, setPhoto] = React.useState<string | null>(null);
9
+ return (
10
+ <div className="flex w-72 flex-col gap-3">
11
+ <MediaCapture
12
+ mode="photo"
13
+ facing="user"
14
+ onCapture={(result) => setPhoto(result.url)}
15
+ labels={{ prompt: "Take a profile picture with your camera.", start: "Turn on the camera" }}
16
+ />
17
+ {photo && <img src={photo} alt="Your new profile picture" className="h-20 w-20 rounded-full object-cover" />}
18
+ </div>
19
+ );
20
+ }
@@ -0,0 +1,4 @@
1
+ import type { ComponentType } from "react";
2
+ /** A named example of the @krizaka/ui registry; `defaultOpen` opens what it opens (a dialog, a menu, toasts) at load. */
3
+ declare const Example: ComponentType<{ defaultOpen?: boolean }>;
4
+ export default Example;
@@ -0,0 +1,24 @@
1
+ "use client";
2
+
3
+ // registry/examples/pagination/cursor.tsx
4
+ import { Pagination } from "@krizaka/ui/pagination";
5
+ import * as React from "react";
6
+ import { jsx } from "react/jsx-runtime";
7
+ function PaginationCursor() {
8
+ const [pages, setPages] = React.useState(["start"]);
9
+ const index = pages.length - 1;
10
+ return /* @__PURE__ */ jsx(
11
+ Pagination,
12
+ {
13
+ hasPrevious: index > 0,
14
+ hasNext: true,
15
+ onPrevious: () => setPages((p) => p.slice(0, -1)),
16
+ onNext: () => setPages((p) => [...p, `cursor-${p.length}`]),
17
+ status: `Jobs ${index * 25 + 1}\u2013${index * 25 + 25}`,
18
+ labels: { previous: "Newer jobs", next: "Older jobs" }
19
+ }
20
+ );
21
+ }
22
+ export {
23
+ PaginationCursor as default
24
+ };
@@ -0,0 +1,20 @@
1
+ "use client";
2
+
3
+ import { Pagination } from "@krizaka/ui/pagination";
4
+ import * as React from "react";
5
+
6
+ // An API that answers with a `nextCursor`: no total, previous and next only.
7
+ export default function PaginationCursor() {
8
+ const [pages, setPages] = React.useState(["start"]);
9
+ const index = pages.length - 1;
10
+ return (
11
+ <Pagination
12
+ hasPrevious={index > 0}
13
+ hasNext
14
+ onPrevious={() => setPages((p) => p.slice(0, -1))}
15
+ onNext={() => setPages((p) => [...p, `cursor-${p.length}`])}
16
+ status={`Jobs ${index * 25 + 1}–${index * 25 + 25}`}
17
+ labels={{ previous: "Newer jobs", next: "Older jobs" }}
18
+ />
19
+ );
20
+ }
@@ -0,0 +1,4 @@
1
+ import type { ComponentType } from "react";
2
+ /** A named example of the @krizaka/ui registry; `defaultOpen` opens what it opens (a dialog, a menu, toasts) at load. */
3
+ declare const Example: ComponentType<{ defaultOpen?: boolean }>;
4
+ export default Example;
@@ -0,0 +1,11 @@
1
+ "use client";
2
+
3
+ // registry/examples/pagination/links.tsx
4
+ import { Pagination } from "@krizaka/ui/pagination";
5
+ import { jsx } from "react/jsx-runtime";
6
+ function PaginationLinks() {
7
+ return /* @__PURE__ */ jsx(Pagination, { page: 7, pageCount: 42, getHref: (page) => `/explore?q=sunset&page=${page}`, siblings: 2 });
8
+ }
9
+ export {
10
+ PaginationLinks as default
11
+ };
@@ -0,0 +1,6 @@
1
+ import { Pagination } from "@krizaka/ui/pagination";
2
+
3
+ // Server-rendered: every page is a link, the page lives in the address (`?q=sunset&page=7`).
4
+ export default function PaginationLinks() {
5
+ return <Pagination page={7} pageCount={42} getHref={(page) => `/explore?q=sunset&page=${page}`} siblings={2} />;
6
+ }
@@ -0,0 +1,4 @@
1
+ import type { ComponentType } from "react";
2
+ /** A named example of the @krizaka/ui registry; `defaultOpen` opens what it opens (a dialog, a menu, toasts) at load. */
3
+ declare const Example: ComponentType<{ defaultOpen?: boolean }>;
4
+ export default Example;
@@ -0,0 +1,19 @@
1
+ "use client";
2
+
3
+ // registry/examples/pagination/native/cursor.tsx
4
+ import { Pagination } from "@krizaka/ui/native";
5
+ import { jsx } from "react/jsx-runtime";
6
+ function NativePaginationCursor() {
7
+ return /* @__PURE__ */ jsx(
8
+ Pagination,
9
+ {
10
+ hasPrevious: true,
11
+ hasNext: true,
12
+ status: "Payouts 21\u201340",
13
+ labels: { previous: "Newer payouts", next: "Older payouts", compact: (p, count) => `${p} / ${count}` }
14
+ }
15
+ );
16
+ }
17
+ export {
18
+ NativePaginationCursor as default
19
+ };
@@ -0,0 +1,13 @@
1
+ import { Pagination } from "@krizaka/ui/native";
2
+
3
+ // A cursor: the range in between, no total.
4
+ export default function NativePaginationCursor() {
5
+ return (
6
+ <Pagination
7
+ hasPrevious
8
+ hasNext
9
+ status="Payouts 21–40"
10
+ labels={{ previous: "Newer payouts", next: "Older payouts", compact: (p, count) => `${p} / ${count}` }}
11
+ />
12
+ );
13
+ }
@@ -0,0 +1,4 @@
1
+ import type { ComponentType } from "react";
2
+ /** A named example of the @krizaka/ui registry; `defaultOpen` opens what it opens (a dialog, a menu, toasts) at load. */
3
+ declare const Example: ComponentType<{ defaultOpen?: boolean }>;
4
+ export default Example;