@krizaka/ui 2.0.0-beta.1 → 2.0.0-beta.3

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 (210) hide show
  1. package/README.md +44 -3
  2. package/dist/alert.d.ts +2 -0
  3. package/dist/alert.js.map +1 -1
  4. package/dist/avatar.d.ts +5 -0
  5. package/dist/avatar.js.map +1 -1
  6. package/dist/badge.d.ts +12 -0
  7. package/dist/badge.js.map +1 -1
  8. package/dist/button-8La7l0V4.d.ts +83 -0
  9. package/dist/button.d.ts +19 -0
  10. package/dist/button.js.map +1 -1
  11. package/dist/card.d.ts +24 -1
  12. package/dist/card.js +1 -1
  13. package/dist/card.js.map +1 -1
  14. package/dist/checkbox.d.ts +52 -0
  15. package/dist/checkbox.js +42 -0
  16. package/dist/checkbox.js.map +1 -0
  17. package/dist/chip.d.ts +120 -0
  18. package/dist/chip.js +93 -0
  19. package/dist/chip.js.map +1 -0
  20. package/dist/chunk-3X5MVH54.js +121 -0
  21. package/dist/chunk-3X5MVH54.js.map +1 -0
  22. package/dist/{chunk-RLOXWF2G.js → chunk-5AXLA4LK.js} +1 -1
  23. package/dist/chunk-5AXLA4LK.js.map +1 -0
  24. package/dist/{chunk-CPMZS4XA.js → chunk-FJDSLNXK.js} +1 -1
  25. package/dist/chunk-FJDSLNXK.js.map +1 -0
  26. package/dist/{chunk-QRG5RYEI.js → chunk-ZUD4U22H.js} +1 -1
  27. package/dist/chunk-ZUD4U22H.js.map +1 -0
  28. package/dist/cn.d.ts +3 -0
  29. package/dist/cn.js +1 -1
  30. package/dist/command.d.ts +159 -0
  31. package/dist/command.js +111 -0
  32. package/dist/command.js.map +1 -0
  33. package/dist/confirm-button.d.ts +23 -0
  34. package/dist/confirm-button.js +85 -0
  35. package/dist/confirm-button.js.map +1 -0
  36. package/dist/countdown.d.ts +3 -0
  37. package/dist/countdown.js.map +1 -1
  38. package/dist/dialog-GQ4Nvuyf.d.ts +157 -0
  39. package/dist/dialog.d.ts +12 -131
  40. package/dist/dialog.js +27 -91
  41. package/dist/dialog.js.map +1 -1
  42. package/dist/dropdown-menu.d.ts +1 -0
  43. package/dist/dropdown-menu.js +1 -1
  44. package/dist/dropdown-menu.js.map +1 -1
  45. package/dist/empty-state.d.ts +2 -0
  46. package/dist/empty-state.js.map +1 -1
  47. package/dist/field.js +1 -1
  48. package/dist/kbd.d.ts +7 -1
  49. package/dist/kbd.js.map +1 -1
  50. package/dist/motion.css +7 -1
  51. package/dist/page-header.d.ts +2 -0
  52. package/dist/page-header.js.map +1 -1
  53. package/dist/popover.js +1 -1
  54. package/dist/progress.d.ts +92 -0
  55. package/dist/progress.js +85 -0
  56. package/dist/progress.js.map +1 -0
  57. package/dist/radio-group.d.ts +77 -0
  58. package/dist/radio-group.js +48 -0
  59. package/dist/radio-group.js.map +1 -0
  60. package/dist/skeleton.d.ts +7 -1
  61. package/dist/skeleton.js.map +1 -1
  62. package/dist/slider.d.ts +90 -0
  63. package/dist/slider.js +82 -0
  64. package/dist/slider.js.map +1 -0
  65. package/dist/spinner.d.ts +5 -0
  66. package/dist/spinner.js.map +1 -1
  67. package/dist/stat.d.ts +2 -0
  68. package/dist/stat.js.map +1 -1
  69. package/dist/switch.d.ts +76 -0
  70. package/dist/switch.js +38 -0
  71. package/dist/switch.js.map +1 -0
  72. package/dist/tabs.d.ts +86 -0
  73. package/dist/tabs.js +60 -0
  74. package/dist/tabs.js.map +1 -0
  75. package/dist/theme.d.ts +11 -60
  76. package/dist/theme.js +4 -2
  77. package/dist/theme.js.map +1 -1
  78. package/dist/toast.js +1 -1
  79. package/dist/tooltip.d.ts +3 -0
  80. package/dist/tooltip.js +1 -1
  81. package/dist/tooltip.js.map +1 -1
  82. package/package.json +146 -6
  83. package/registry/alert.json +59 -0
  84. package/registry/avatar.json +114 -0
  85. package/registry/badge.json +59 -0
  86. package/registry/button.json +115 -0
  87. package/registry/card.json +154 -0
  88. package/registry/checkbox.json +46 -0
  89. package/registry/chip.json +164 -0
  90. package/registry/cn.json +21 -0
  91. package/registry/command.json +162 -0
  92. package/registry/confirm-button.json +104 -0
  93. package/registry/countdown.json +84 -0
  94. package/registry/demos/alert.d.ts +5 -0
  95. package/registry/demos/alert.js +12 -0
  96. package/registry/demos/alert.tsx +15 -0
  97. package/registry/demos/avatar.d.ts +5 -0
  98. package/registry/demos/avatar.js +14 -0
  99. package/registry/demos/avatar.tsx +13 -0
  100. package/registry/demos/badge.d.ts +5 -0
  101. package/registry/demos/badge.js +11 -0
  102. package/registry/demos/badge.tsx +5 -0
  103. package/registry/demos/button.d.ts +5 -0
  104. package/registry/demos/button.js +11 -0
  105. package/registry/demos/button.tsx +5 -0
  106. package/registry/demos/card.d.ts +5 -0
  107. package/registry/demos/card.js +30 -0
  108. package/registry/demos/card.tsx +37 -0
  109. package/registry/demos/checkbox.d.ts +5 -0
  110. package/registry/demos/checkbox.js +11 -0
  111. package/registry/demos/checkbox.tsx +5 -0
  112. package/registry/demos/chip.d.ts +5 -0
  113. package/registry/demos/chip.js +15 -0
  114. package/registry/demos/chip.tsx +11 -0
  115. package/registry/demos/cn.d.ts +7 -0
  116. package/registry/demos/cn.js +17 -0
  117. package/registry/demos/cn.tsx +9 -0
  118. package/registry/demos/command.d.ts +5 -0
  119. package/registry/demos/command.js +32 -0
  120. package/registry/demos/command.tsx +28 -0
  121. package/registry/demos/confirm-button.d.ts +5 -0
  122. package/registry/demos/confirm-button.js +12 -0
  123. package/registry/demos/confirm-button.tsx +13 -0
  124. package/registry/demos/countdown.d.ts +5 -0
  125. package/registry/demos/countdown.js +13 -0
  126. package/registry/demos/countdown.tsx +10 -0
  127. package/registry/demos/dialog.d.ts +7 -0
  128. package/registry/demos/dialog.js +29 -0
  129. package/registry/demos/dialog.tsx +31 -0
  130. package/registry/demos/dropdown-menu.d.ts +7 -0
  131. package/registry/demos/dropdown-menu.js +36 -0
  132. package/registry/demos/dropdown-menu.tsx +27 -0
  133. package/registry/demos/empty-state.d.ts +5 -0
  134. package/registry/demos/empty-state.js +15 -0
  135. package/registry/demos/empty-state.tsx +12 -0
  136. package/registry/demos/field.d.ts +5 -0
  137. package/registry/demos/field.js +15 -0
  138. package/registry/demos/field.tsx +11 -0
  139. package/registry/demos/kbd.d.ts +5 -0
  140. package/registry/demos/kbd.js +11 -0
  141. package/registry/demos/kbd.tsx +5 -0
  142. package/registry/demos/page-header.d.ts +5 -0
  143. package/registry/demos/page-header.js +11 -0
  144. package/registry/demos/page-header.tsx +5 -0
  145. package/registry/demos/popover.d.ts +7 -0
  146. package/registry/demos/popover.js +25 -0
  147. package/registry/demos/popover.tsx +31 -0
  148. package/registry/demos/progress.d.ts +5 -0
  149. package/registry/demos/progress.js +11 -0
  150. package/registry/demos/progress.tsx +5 -0
  151. package/registry/demos/radio-group.d.ts +5 -0
  152. package/registry/demos/radio-group.js +16 -0
  153. package/registry/demos/radio-group.tsx +14 -0
  154. package/registry/demos/separator.d.ts +5 -0
  155. package/registry/demos/separator.js +15 -0
  156. package/registry/demos/separator.tsx +11 -0
  157. package/registry/demos/skeleton.d.ts +5 -0
  158. package/registry/demos/skeleton.js +20 -0
  159. package/registry/demos/skeleton.tsx +16 -0
  160. package/registry/demos/slider.d.ts +5 -0
  161. package/registry/demos/slider.js +11 -0
  162. package/registry/demos/slider.tsx +5 -0
  163. package/registry/demos/slot.d.ts +5 -0
  164. package/registry/demos/slot.js +14 -0
  165. package/registry/demos/slot.tsx +13 -0
  166. package/registry/demos/spinner.d.ts +5 -0
  167. package/registry/demos/spinner.js +11 -0
  168. package/registry/demos/spinner.tsx +5 -0
  169. package/registry/demos/stat.d.ts +5 -0
  170. package/registry/demos/stat.js +11 -0
  171. package/registry/demos/stat.tsx +5 -0
  172. package/registry/demos/switch.d.ts +5 -0
  173. package/registry/demos/switch.js +11 -0
  174. package/registry/demos/switch.tsx +5 -0
  175. package/registry/demos/tabs.d.ts +5 -0
  176. package/registry/demos/tabs.js +22 -0
  177. package/registry/demos/tabs.tsx +28 -0
  178. package/registry/demos/theme.d.ts +5 -0
  179. package/registry/demos/theme.js +11 -0
  180. package/registry/demos/theme.tsx +9 -0
  181. package/registry/demos/toast.d.ts +8 -0
  182. package/registry/demos/toast.js +29 -0
  183. package/registry/demos/toast.tsx +31 -0
  184. package/registry/demos/tooltip.d.ts +7 -0
  185. package/registry/demos/tooltip.js +15 -0
  186. package/registry/demos/tooltip.tsx +15 -0
  187. package/registry/dialog.json +218 -0
  188. package/registry/dropdown-menu.json +63 -0
  189. package/registry/empty-state.json +59 -0
  190. package/registry/field.json +66 -0
  191. package/registry/index.json +320 -0
  192. package/registry/kbd.json +38 -0
  193. package/registry/page-header.json +66 -0
  194. package/registry/popover.json +44 -0
  195. package/registry/progress.json +80 -0
  196. package/registry/radio-group.json +64 -0
  197. package/registry/separator.json +25 -0
  198. package/registry/skeleton.json +38 -0
  199. package/registry/slider.json +95 -0
  200. package/registry/slot.json +31 -0
  201. package/registry/spinner.json +45 -0
  202. package/registry/stat.json +66 -0
  203. package/registry/switch.json +53 -0
  204. package/registry/tabs.json +44 -0
  205. package/registry/theme.json +78 -0
  206. package/registry/toast.json +54 -0
  207. package/registry/tooltip.json +91 -0
  208. package/dist/chunk-CPMZS4XA.js.map +0 -1
  209. package/dist/chunk-QRG5RYEI.js.map +0 -1
  210. package/dist/chunk-RLOXWF2G.js.map +0 -1
@@ -0,0 +1,20 @@
1
+ "use client";
2
+
3
+ // registry/demos/skeleton.tsx
4
+ import { Skeleton } from "@krizaka/ui/skeleton";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ function SkeletonDemo() {
7
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 rounded-xl border border-border-default bg-surface-1 p-4", children: [
8
+ /* @__PURE__ */ jsx(Skeleton, { shape: "rect", className: "h-32" }),
9
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
10
+ /* @__PURE__ */ jsx(Skeleton, { shape: "circle", className: "h-8" }),
11
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-2", children: [
12
+ /* @__PURE__ */ jsx(Skeleton, {}),
13
+ /* @__PURE__ */ jsx(Skeleton, { className: "w-2/3" })
14
+ ] })
15
+ ] })
16
+ ] });
17
+ }
18
+ export {
19
+ SkeletonDemo as default
20
+ };
@@ -0,0 +1,16 @@
1
+ import { Skeleton } from "@krizaka/ui/skeleton";
2
+
3
+ export default function SkeletonDemo() {
4
+ return (
5
+ <div className="flex flex-col gap-3 rounded-xl border border-border-default bg-surface-1 p-4">
6
+ <Skeleton shape="rect" className="h-32" />
7
+ <div className="flex items-center gap-3">
8
+ <Skeleton shape="circle" className="h-8" />
9
+ <div className="flex flex-1 flex-col gap-2">
10
+ <Skeleton />
11
+ <Skeleton className="w-2/3" />
12
+ </div>
13
+ </div>
14
+ </div>
15
+ );
16
+ }
@@ -0,0 +1,5 @@
1
+ import * as react from 'react';
2
+
3
+ declare function SliderDemo(): react.JSX.Element;
4
+
5
+ export { SliderDemo as default };
@@ -0,0 +1,11 @@
1
+ "use client";
2
+
3
+ // registry/demos/slider.tsx
4
+ import { Slider } from "@krizaka/ui/slider";
5
+ import { jsx } from "react/jsx-runtime";
6
+ function SliderDemo() {
7
+ return /* @__PURE__ */ jsx(Slider, { label: "Volume", defaultValue: 60 });
8
+ }
9
+ export {
10
+ SliderDemo as default
11
+ };
@@ -0,0 +1,5 @@
1
+ import { Slider } from "@krizaka/ui/slider";
2
+
3
+ export default function SliderDemo() {
4
+ return <Slider label="Volume" defaultValue={60} />;
5
+ }
@@ -0,0 +1,5 @@
1
+ import * as react from 'react';
2
+
3
+ declare function SlotDemo(): react.JSX.Element;
4
+
5
+ export { SlotDemo as default };
@@ -0,0 +1,14 @@
1
+ "use client";
2
+
3
+ // registry/demos/slot.tsx
4
+ import { Slot, VisuallyHidden } from "@krizaka/ui/slot";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ function SlotDemo() {
7
+ return /* @__PURE__ */ jsx(Slot, { className: "text-sm font-semibold text-fg underline underline-offset-4", children: /* @__PURE__ */ jsxs("a", { href: "#docs", children: [
8
+ "Read the docs",
9
+ /* @__PURE__ */ jsx(VisuallyHidden, { children: " about Slot" })
10
+ ] }) });
11
+ }
12
+ export {
13
+ SlotDemo as default
14
+ };
@@ -0,0 +1,13 @@
1
+ import { Slot, VisuallyHidden } from "@krizaka/ui/slot";
2
+
3
+ export default function SlotDemo() {
4
+ // Slot merges its props and classes into its only child: the link is rendered, styled by the Slot.
5
+ return (
6
+ <Slot className="text-sm font-semibold text-fg underline underline-offset-4">
7
+ <a href="#docs">
8
+ Read the docs
9
+ <VisuallyHidden> about Slot</VisuallyHidden>
10
+ </a>
11
+ </Slot>
12
+ );
13
+ }
@@ -0,0 +1,5 @@
1
+ import * as react from 'react';
2
+
3
+ declare function SpinnerDemo(): react.JSX.Element;
4
+
5
+ export { SpinnerDemo as default };
@@ -0,0 +1,11 @@
1
+ "use client";
2
+
3
+ // registry/demos/spinner.tsx
4
+ import { Spinner } from "@krizaka/ui/spinner";
5
+ import { jsx } from "react/jsx-runtime";
6
+ function SpinnerDemo() {
7
+ return /* @__PURE__ */ jsx(Spinner, { label: "Loading" });
8
+ }
9
+ export {
10
+ SpinnerDemo as default
11
+ };
@@ -0,0 +1,5 @@
1
+ import { Spinner } from "@krizaka/ui/spinner";
2
+
3
+ export default function SpinnerDemo() {
4
+ return <Spinner label="Loading" />;
5
+ }
@@ -0,0 +1,5 @@
1
+ import * as react from 'react';
2
+
3
+ declare function StatDemo(): react.JSX.Element;
4
+
5
+ export { StatDemo as default };
@@ -0,0 +1,11 @@
1
+ "use client";
2
+
3
+ // registry/demos/stat.tsx
4
+ import { Stat } from "@krizaka/ui/stat";
5
+ import { jsx } from "react/jsx-runtime";
6
+ function StatDemo() {
7
+ return /* @__PURE__ */ jsx(Stat, { label: "Revenue", value: "\u20AC4,812", hint: "vs last month", trend: "up", trendLabel: "+12 %" });
8
+ }
9
+ export {
10
+ StatDemo as default
11
+ };
@@ -0,0 +1,5 @@
1
+ import { Stat } from "@krizaka/ui/stat";
2
+
3
+ export default function StatDemo() {
4
+ return <Stat label="Revenue" value="€4,812" hint="vs last month" trend="up" trendLabel="+12 %" />;
5
+ }
@@ -0,0 +1,5 @@
1
+ import * as react from 'react';
2
+
3
+ declare function SwitchDemo(): react.JSX.Element;
4
+
5
+ export { SwitchDemo as default };
@@ -0,0 +1,11 @@
1
+ "use client";
2
+
3
+ // registry/demos/switch.tsx
4
+ import { Switch } from "@krizaka/ui/switch";
5
+ import { jsx } from "react/jsx-runtime";
6
+ function SwitchDemo() {
7
+ return /* @__PURE__ */ jsx(Switch, { label: "Autoplay" });
8
+ }
9
+ export {
10
+ SwitchDemo as default
11
+ };
@@ -0,0 +1,5 @@
1
+ import { Switch } from "@krizaka/ui/switch";
2
+
3
+ export default function SwitchDemo() {
4
+ return <Switch label="Autoplay" />;
5
+ }
@@ -0,0 +1,5 @@
1
+ import * as react from 'react';
2
+
3
+ declare function TabsDemo(): react.JSX.Element;
4
+
5
+ export { TabsDemo as default };
@@ -0,0 +1,22 @@
1
+ "use client";
2
+
3
+ // registry/demos/tabs.tsx
4
+ import { Tabs } from "@krizaka/ui/tabs";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ function TabsDemo() {
7
+ return /* @__PURE__ */ jsxs(Tabs.Root, { defaultValue: "videos", children: [
8
+ /* @__PURE__ */ jsxs(Tabs.List, { "aria-label": "Profile", children: [
9
+ /* @__PURE__ */ jsx(Tabs.Trigger, { value: "videos", children: "Videos" }),
10
+ /* @__PURE__ */ jsx(Tabs.Trigger, { value: "stories", children: "Stories" }),
11
+ /* @__PURE__ */ jsx(Tabs.Trigger, { value: "collections", children: "Collections" }),
12
+ /* @__PURE__ */ jsx(Tabs.Trigger, { value: "about", disabled: true, children: "About" })
13
+ ] }),
14
+ /* @__PURE__ */ jsx(Tabs.Content, { value: "videos", className: "text-sm text-fg-secondary", children: "Twelve videos, newest first." }),
15
+ /* @__PURE__ */ jsx(Tabs.Content, { value: "stories", className: "text-sm text-fg-secondary", children: "Stories of the last 24 hours." }),
16
+ /* @__PURE__ */ jsx(Tabs.Content, { value: "collections", className: "text-sm text-fg-secondary", children: "Three public collections." }),
17
+ /* @__PURE__ */ jsx(Tabs.Content, { value: "about", className: "text-sm text-fg-secondary", children: "About this channel." })
18
+ ] });
19
+ }
20
+ export {
21
+ TabsDemo as default
22
+ };
@@ -0,0 +1,28 @@
1
+ import { Tabs } from "@krizaka/ui/tabs";
2
+
3
+ export default function TabsDemo() {
4
+ return (
5
+ <Tabs.Root defaultValue="videos">
6
+ <Tabs.List aria-label="Profile">
7
+ <Tabs.Trigger value="videos">Videos</Tabs.Trigger>
8
+ <Tabs.Trigger value="stories">Stories</Tabs.Trigger>
9
+ <Tabs.Trigger value="collections">Collections</Tabs.Trigger>
10
+ <Tabs.Trigger value="about" disabled>
11
+ About
12
+ </Tabs.Trigger>
13
+ </Tabs.List>
14
+ <Tabs.Content value="videos" className="text-sm text-fg-secondary">
15
+ Twelve videos, newest first.
16
+ </Tabs.Content>
17
+ <Tabs.Content value="stories" className="text-sm text-fg-secondary">
18
+ Stories of the last 24 hours.
19
+ </Tabs.Content>
20
+ <Tabs.Content value="collections" className="text-sm text-fg-secondary">
21
+ Three public collections.
22
+ </Tabs.Content>
23
+ <Tabs.Content value="about" className="text-sm text-fg-secondary">
24
+ About this channel.
25
+ </Tabs.Content>
26
+ </Tabs.Root>
27
+ );
28
+ }
@@ -0,0 +1,5 @@
1
+ import * as react from 'react';
2
+
3
+ declare function ThemeDemo(): react.JSX.Element;
4
+
5
+ export { ThemeDemo as default };
@@ -0,0 +1,11 @@
1
+ "use client";
2
+
3
+ // registry/demos/theme.tsx
4
+ import { ThemeProvider, ThemeToggle } from "@krizaka/ui/theme";
5
+ import { jsx } from "react/jsx-runtime";
6
+ function ThemeDemo() {
7
+ return /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(ThemeToggle, { label: "Change the theme" }) });
8
+ }
9
+ export {
10
+ ThemeDemo as default
11
+ };
@@ -0,0 +1,9 @@
1
+ import { ThemeProvider, ThemeToggle } from "@krizaka/ui/theme";
2
+
3
+ export default function ThemeDemo() {
4
+ return (
5
+ <ThemeProvider>
6
+ <ThemeToggle label="Change the theme" />
7
+ </ThemeProvider>
8
+ );
9
+ }
@@ -0,0 +1,8 @@
1
+ import * as react from 'react';
2
+
3
+ /** `defaultOpen`: the toasts show at once and stay (the screenshot); otherwise the button shows them. */
4
+ declare function ToastDemo({ defaultOpen }: {
5
+ defaultOpen?: boolean;
6
+ }): react.JSX.Element;
7
+
8
+ export { ToastDemo as default };
@@ -0,0 +1,29 @@
1
+ "use client";
2
+
3
+ // registry/demos/toast.tsx
4
+ import { Button } from "@krizaka/ui/button";
5
+ import { toast, Toaster } from "@krizaka/ui/toast";
6
+ import { useEffect } from "react";
7
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
+ var toasterId = "tones";
9
+ var show = () => {
10
+ toast("Draft saved", { toasterId, description: "Autosaved a moment ago." });
11
+ toast.success("Payment received", { toasterId, description: "\u20AC12.00 from @maya." });
12
+ toast.warning("Your balance is low", { toasterId, description: "Two tips left before a top-up." });
13
+ toast.error("Upload failed", { toasterId, description: "The connection dropped at 64 %.", action: { label: "Retry", onClick: () => {
14
+ } } });
15
+ };
16
+ function ToastDemo({ defaultOpen = false }) {
17
+ useEffect(() => {
18
+ if (!defaultOpen) return;
19
+ toast.dismiss();
20
+ show();
21
+ }, [defaultOpen]);
22
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
23
+ /* @__PURE__ */ jsx(Toaster, { id: toasterId, label: "Notifications", closeLabel: "Dismiss", position: "bottom-right", expand: true, visibleToasts: 4, duration: defaultOpen ? Number.POSITIVE_INFINITY : void 0 }),
24
+ /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: show, children: "Show again" })
25
+ ] });
26
+ }
27
+ export {
28
+ ToastDemo as default
29
+ };
@@ -0,0 +1,31 @@
1
+ "use client";
2
+
3
+ import { Button } from "@krizaka/ui/button";
4
+ import { toast, Toaster } from "@krizaka/ui/toast";
5
+ import { useEffect } from "react";
6
+
7
+ // Each toaster has its own `id`: the toasts of this demo stay in this demo's toaster.
8
+ const toasterId = "tones";
9
+ const show = () => {
10
+ toast("Draft saved", { toasterId, description: "Autosaved a moment ago." });
11
+ toast.success("Payment received", { toasterId, description: "€12.00 from @maya." });
12
+ toast.warning("Your balance is low", { toasterId, description: "Two tips left before a top-up." });
13
+ toast.error("Upload failed", { toasterId, description: "The connection dropped at 64 %.", action: { label: "Retry", onClick: () => {} } });
14
+ };
15
+
16
+ /** `defaultOpen`: the toasts show at once and stay (the screenshot); otherwise the button shows them. */
17
+ export default function ToastDemo({ defaultOpen = false }: { defaultOpen?: boolean }) {
18
+ useEffect(() => {
19
+ if (!defaultOpen) return;
20
+ toast.dismiss();
21
+ show();
22
+ }, [defaultOpen]);
23
+ return (
24
+ <>
25
+ <Toaster id={toasterId} label="Notifications" closeLabel="Dismiss" position="bottom-right" expand visibleToasts={4} duration={defaultOpen ? Number.POSITIVE_INFINITY : undefined} />
26
+ <Button variant="outline" onClick={show}>
27
+ Show again
28
+ </Button>
29
+ </>
30
+ );
31
+ }
@@ -0,0 +1,7 @@
1
+ import * as react from 'react';
2
+
3
+ declare function TooltipDemo({ defaultOpen }: {
4
+ defaultOpen?: boolean;
5
+ }): react.JSX.Element;
6
+
7
+ export { TooltipDemo as default };
@@ -0,0 +1,15 @@
1
+ "use client";
2
+
3
+ // registry/demos/tooltip.tsx
4
+ import { IconButton } from "@krizaka/ui/button";
5
+ import { Tooltip } from "@krizaka/ui/tooltip";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ function TooltipDemo({ defaultOpen = false }) {
8
+ return /* @__PURE__ */ jsx(Tooltip, { content: "Copy the link", defaultOpen, children: /* @__PURE__ */ jsx(IconButton, { label: "Copy", variant: "outline", children: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", className: "h-4 w-4", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: [
9
+ /* @__PURE__ */ jsx("rect", { x: "9", y: "9", width: "12", height: "12", rx: "2" }),
10
+ /* @__PURE__ */ jsx("path", { d: "M5 15V5a2 2 0 0 1 2-2h10" })
11
+ ] }) }) });
12
+ }
13
+ export {
14
+ TooltipDemo as default
15
+ };
@@ -0,0 +1,15 @@
1
+ import { IconButton } from "@krizaka/ui/button";
2
+ import { Tooltip } from "@krizaka/ui/tooltip";
3
+
4
+ export default function TooltipDemo({ defaultOpen = false }: { defaultOpen?: boolean }) {
5
+ return (
6
+ <Tooltip content="Copy the link" defaultOpen={defaultOpen}>
7
+ <IconButton label="Copy" variant="outline">
8
+ <svg viewBox="0 0 24 24" className="h-4 w-4" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" aria-hidden>
9
+ <rect x="9" y="9" width="12" height="12" rx="2" />
10
+ <path d="M5 15V5a2 2 0 0 1 2-2h10" />
11
+ </svg>
12
+ </IconButton>
13
+ </Tooltip>
14
+ );
15
+ }
@@ -0,0 +1,218 @@
1
+ {
2
+ "name": "dialog",
3
+ "type": "primitive",
4
+ "description": "`Dialog.*`, `Sheet`, `AlertDialog`, `dialog` (the slots). Client (\"use client\").",
5
+ "files": [
6
+ {
7
+ "path": "dialog/alert-dialog.tsx",
8
+ "content": "// Client. A confirmation that interrupts: Radix AlertDialog (role=\"alertdialog\", no outside click, focus on Cancel).\n// `onConfirm` may be async: the dialog stays open with the confirm button loading until it settles, closes when it\n// resolves, and stays open when it rejects (the product shows the error).\nimport { AlertDialog as AlertDialogPrimitive } from \"radix-ui\";\nimport * as React from \"react\";\n\nimport { Button } from \"../button/button\";\nimport { dialog } from \"./dialog\";\n\nconst s = dialog({ placement: \"center\", size: \"sm\" });\n\nexport type AlertDialogProps = {\n /** Open or closed (controlled), with `onOpenChange`. */\n open?: boolean;\n /** Open at first, uncontrolled. */\n defaultOpen?: boolean;\n /** Called when it opens or closes (never while `onConfirm` is pending). */\n onOpenChange?: (open: boolean) => void;\n /** The element that opens the dialog (rendered as is, `asChild`): a Button, an IconButton. */\n trigger?: React.ReactNode;\n /** The question asked (\"Delete this video?\"): the dialog's accessible name. */\n title: React.ReactNode;\n /** What the action does and what it costs: the dialog's description. */\n description?: React.ReactNode;\n /** More content between the description and the actions. */\n children?: React.ReactNode;\n /** The words of the confirm button — passed translated. */\n confirmLabel: string;\n /** The words of the cancel button (it takes the focus at open) — passed translated. */\n cancelLabel: string;\n /** `danger` for a destructive action (delete, leave, cancel a payment). */\n tone?: \"danger\" | \"primary\";\n /** Runs on confirm. A promise keeps the dialog open and the button loading until it settles. */\n onConfirm: () => void | Promise<unknown>;\n /** The element the portal renders into (default: document.body). */\n container?: HTMLElement | null;\n /** Classes of the dialog's content, merged last. */\n className?: string;\n};\n\nexport function AlertDialog({\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n trigger,\n title,\n description,\n children,\n confirmLabel,\n cancelLabel,\n tone = \"primary\",\n onConfirm,\n container,\n className,\n}: AlertDialogProps) {\n const [openState, setOpenState] = React.useState(defaultOpen);\n const [pending, setPending] = React.useState(false);\n const open = openProp ?? openState;\n\n const setOpen = (next: boolean) => {\n if (openProp === undefined) setOpenState(next);\n onOpenChange?.(next);\n };\n\n const confirm = async () => {\n setPending(true);\n try {\n await onConfirm();\n setOpen(false);\n } catch {\n // Stays open: the product reports the failure (a toast, an inline error) and the person may retry.\n } finally {\n setPending(false);\n }\n };\n\n return (\n <AlertDialogPrimitive.Root open={open} onOpenChange={(next) => (pending ? undefined : setOpen(next))}>\n {trigger && <AlertDialogPrimitive.Trigger asChild>{trigger}</AlertDialogPrimitive.Trigger>}\n <AlertDialogPrimitive.Portal container={container}>\n <AlertDialogPrimitive.Overlay className={s.overlay()} />\n <AlertDialogPrimitive.Content\n data-tone={tone}\n aria-busy={pending || undefined}\n className={s.content({ className })}\n onEscapeKeyDown={(event) => pending && event.preventDefault()}\n >\n <div className={s.header({ className: \"pr-5\" })}>\n <AlertDialogPrimitive.Title className={s.title()}>{title}</AlertDialogPrimitive.Title>\n {description && <AlertDialogPrimitive.Description className={s.description()}>{description}</AlertDialogPrimitive.Description>}\n </div>\n {children && <div className={s.body()}>{children}</div>}\n <div className={s.footer()}>\n <AlertDialogPrimitive.Cancel asChild>\n <Button variant=\"ghost\" disabled={pending}>\n {cancelLabel}\n </Button>\n </AlertDialogPrimitive.Cancel>\n <Button variant={tone === \"danger\" ? \"danger\" : \"primary\"} loading={pending} onClick={confirm}>\n {confirmLabel}\n </Button>\n </div>\n </AlertDialogPrimitive.Content>\n </AlertDialogPrimitive.Portal>\n </AlertDialogPrimitive.Root>\n );\n}\n"
9
+ },
10
+ {
11
+ "path": "dialog/dialog.tsx",
12
+ "content": "// Client (a portal). Radix does the focus trap, the scroll lock, Escape, the outside click, aria-modal, the\n// aria-labelledby / aria-describedby wiring and the focus return: this file only holds the shape.\nimport { Dialog as DialogPrimitive } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { IconButton } from \"../button/button\";\n\nexport const dialog = tv({\n slots: {\n overlay: \"kz-overlay fixed inset-0 z-50 bg-overlay backdrop-blur-xs\",\n content:\n \"kz-dialog fixed z-50 flex flex-col overflow-hidden border border-border-default bg-surface-1 text-fg shadow-lg focus:outline-hidden\",\n close: \"absolute right-3 top-3 h-9 w-9\",\n header: \"flex flex-col gap-1 px-5 pb-2 pr-14 pt-5\",\n title: \"text-base font-bold text-fg\",\n description: \"text-sm text-fg-secondary\",\n body: \"min-h-0 flex-1 overflow-y-auto px-5 pb-5\",\n footer:\n \"flex flex-wrap items-center justify-end gap-2 border-t border-border-subtle px-5 py-4 pb-[max(1rem,env(safe-area-inset-bottom))]\",\n },\n variants: {\n placement: {\n center: { content: \"left-1/2 top-1/2 max-h-[85dvh] w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 rounded-xl\" },\n /* A sheet: anchored at the bottom on a phone, centred from `sm` up. */\n bottom: {\n content:\n \"inset-x-0 bottom-0 max-h-[92dvh] rounded-t-[1.75rem] sm:bottom-auto sm:left-1/2 sm:top-1/2 sm:w-full \" +\n \"sm:-translate-x-1/2 sm:-translate-y-1/2 sm:rounded-[1.75rem]\",\n },\n right: { content: \"inset-y-0 right-0 h-full w-full max-w-md rounded-none border-y-0 border-r-0\" },\n },\n size: { sm: { content: \"sm:max-w-sm\" }, md: { content: \"sm:max-w-md\" }, lg: { content: \"sm:max-w-2xl\" } },\n },\n defaultVariants: { placement: \"center\", size: \"md\" },\n});\nconst s = dialog();\n\nexport type DialogVariants = VariantProps<typeof dialog>;\n\nfunction CloseIcon() {\n return (\n <svg viewBox=\"0 0 24 24\" className=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" aria-hidden>\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </svg>\n );\n}\n\ntype CloseButtonProps =\n | {\n /** The accessible name of the close button — passed translated. */\n closeLabel: string;\n /** Leaves the close button out (the content brings its own way out, or none: see `dismissible`). */\n hideClose?: false;\n }\n | { closeLabel?: string; hideClose: true };\n\nexport type DialogContentProps = React.ComponentProps<typeof DialogPrimitive.Content> &\n DialogVariants &\n CloseButtonProps & {\n /**\n * center · bottom (a sheet on a phone, centred from `sm` up) · right (a side panel, full height).\n * @default \"center\"\n */\n placement?: DialogVariants[\"placement\"];\n /**\n * sm · md · lg: the width of the dialog.\n * @default \"md\"\n */\n size?: DialogVariants[\"size\"];\n /**\n * `false`: Escape and a click outside do not close it (a gate the user must answer: age, terms). It still closes\n * through `open` / `onOpenChange` and any `Dialog.Close` inside. Default `true`.\n */\n dismissible?: boolean;\n /** The element the portal renders into (default: document.body). */\n container?: HTMLElement | null;\n };\n\nconst prevent = (event: Event) => event.preventDefault();\n\n/** The dialog itself, portalled over a dimmed overlay, with a close button. Give it a `Dialog.Title`. */\nexport function DialogContent({\n placement,\n size,\n closeLabel,\n hideClose,\n dismissible = true,\n container,\n className,\n children,\n onEscapeKeyDown,\n onPointerDownOutside,\n onInteractOutside,\n ...props\n}: DialogContentProps) {\n const v = dialog({ placement, size });\n return (\n <DialogPrimitive.Portal container={container}>\n <DialogPrimitive.Overlay className={v.overlay()} />\n <DialogPrimitive.Content\n data-placement={placement ?? \"center\"}\n data-dismissible={dismissible ? undefined : \"false\"}\n className={v.content({ className })}\n onEscapeKeyDown={dismissible ? onEscapeKeyDown : chain(onEscapeKeyDown, prevent)}\n onPointerDownOutside={dismissible ? onPointerDownOutside : chain(onPointerDownOutside, prevent)}\n onInteractOutside={dismissible ? onInteractOutside : chain(onInteractOutside, prevent)}\n {...props}\n >\n {children}\n {!hideClose && (\n <DialogPrimitive.Close asChild>\n <IconButton label={closeLabel as string} variant=\"ghost\" shape=\"pill\" className={v.close()}>\n <CloseIcon />\n </IconButton>\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Content>\n </DialogPrimitive.Portal>\n );\n}\n\nfunction chain<E extends Event>(handler: ((event: E) => void) | undefined, then: (event: E) => void) {\n return (event: E) => {\n handler?.(event);\n then(event);\n };\n}\n\nexport function DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div className={s.header({ className })} {...props} />;\n}\n\nexport function DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>) {\n return <DialogPrimitive.Title className={s.title({ className })} {...props} />;\n}\n\nexport function DialogDescription({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Description>) {\n return <DialogPrimitive.Description className={s.description({ className })} {...props} />;\n}\n\nexport function DialogBody({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div className={s.body({ className })} {...props} />;\n}\n\nexport function DialogFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div className={s.footer({ className })} {...props} />;\n}\n\n/** `Dialog.Root/Trigger/Content/Header/Title/Description/Body/Footer/Close`. `open`/`defaultOpen` + `onOpenChange`. */\nexport const Dialog = {\n Root: DialogPrimitive.Root,\n Trigger: DialogPrimitive.Trigger,\n Close: DialogPrimitive.Close,\n Content: DialogContent,\n Header: DialogHeader,\n Title: DialogTitle,\n Description: DialogDescription,\n Body: DialogBody,\n Footer: DialogFooter,\n};\n\n/** `Omit` that keeps the close-button union (`closeLabel` required unless `hideClose`). */\ntype DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;\n\nexport type SheetProps = DistributiveOmit<DialogContentProps, \"placement\">;\n\n/** A sheet is a dialog anchored at the bottom (centred from `sm` up): `Dialog.Content placement=\"bottom\"`. */\nexport function Sheet(props: SheetProps) {\n return <DialogContent placement=\"bottom\" {...props} />;\n}\n"
13
+ },
14
+ {
15
+ "path": "dialog/index.ts",
16
+ "content": "/** @krizaka/ui/dialog — `Dialog.*`, `Sheet`, `AlertDialog`, `dialog` (the slots). Client (\"use client\"). */\nexport { AlertDialog, type AlertDialogProps } from \"./alert-dialog\";\nexport {\n Dialog,\n dialog,\n DialogBody,\n DialogContent,\n type DialogContentProps,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n type DialogVariants,\n Sheet,\n type SheetProps,\n} from \"./dialog\";\n"
17
+ }
18
+ ],
19
+ "dependencies": [
20
+ "radix-ui@^1.7.0",
21
+ "tailwind-variants@^3.3.1"
22
+ ],
23
+ "registryDependencies": [
24
+ "button"
25
+ ],
26
+ "demo": {
27
+ "path": "demos/dialog.tsx",
28
+ "content": "import { Button } from \"@krizaka/ui/button\";\nimport { Dialog } from \"@krizaka/ui/dialog\";\nimport { Field, Input } from \"@krizaka/ui/field\";\n\nexport default function DialogDemo({ defaultOpen = false }: { defaultOpen?: boolean }) {\n return (\n <Dialog.Root defaultOpen={defaultOpen}>\n <Dialog.Trigger asChild>\n <Button>Open</Button>\n </Dialog.Trigger>\n <Dialog.Content closeLabel=\"Close\">\n <Dialog.Header>\n <Dialog.Title>Invite a collaborator</Dialog.Title>\n <Dialog.Description>They get access to the drafts of this channel.</Dialog.Description>\n </Dialog.Header>\n <Dialog.Body>\n <Field.Root>\n <Field.Label htmlFor=\"invite-email\">Email</Field.Label>\n <Input id=\"invite-email\" type=\"email\" placeholder=\"name@example.com\" />\n </Field.Root>\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button variant=\"ghost\">Cancel</Button>\n </Dialog.Close>\n <Button variant=\"primary\">Send the invitation</Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n"
29
+ },
30
+ "props": [
31
+ {
32
+ "component": "AlertDialog",
33
+ "description": "",
34
+ "props": [
35
+ {
36
+ "name": "cancelLabel",
37
+ "type": "string",
38
+ "default": null,
39
+ "description": "The words of the cancel button (it takes the focus at open) — passed translated.",
40
+ "required": true
41
+ },
42
+ {
43
+ "name": "confirmLabel",
44
+ "type": "string",
45
+ "default": null,
46
+ "description": "The words of the confirm button — passed translated.",
47
+ "required": true
48
+ },
49
+ {
50
+ "name": "onConfirm",
51
+ "type": "() => void | Promise<unknown>",
52
+ "default": null,
53
+ "description": "Runs on confirm. A promise keeps the dialog open and the button loading until it settles.",
54
+ "required": true
55
+ },
56
+ {
57
+ "name": "title",
58
+ "type": "ReactNode",
59
+ "default": null,
60
+ "description": "The question asked (\"Delete this video?\"): the dialog's accessible name.",
61
+ "required": true
62
+ },
63
+ {
64
+ "name": "children",
65
+ "type": "ReactNode",
66
+ "default": null,
67
+ "description": "More content between the description and the actions.",
68
+ "required": false
69
+ },
70
+ {
71
+ "name": "className",
72
+ "type": "string",
73
+ "default": null,
74
+ "description": "Classes of the dialog's content, merged last.",
75
+ "required": false
76
+ },
77
+ {
78
+ "name": "container",
79
+ "type": "HTMLElement | null",
80
+ "default": null,
81
+ "description": "The element the portal renders into (default: document.body).",
82
+ "required": false
83
+ },
84
+ {
85
+ "name": "defaultOpen",
86
+ "type": "boolean",
87
+ "default": "false",
88
+ "description": "Open at first, uncontrolled.",
89
+ "required": false
90
+ },
91
+ {
92
+ "name": "description",
93
+ "type": "ReactNode",
94
+ "default": null,
95
+ "description": "What the action does and what it costs: the dialog's description.",
96
+ "required": false
97
+ },
98
+ {
99
+ "name": "onOpenChange",
100
+ "type": "((open: boolean) => void)",
101
+ "default": null,
102
+ "description": "Called when it opens or closes (never while `onConfirm` is pending).",
103
+ "required": false
104
+ },
105
+ {
106
+ "name": "open",
107
+ "type": "boolean",
108
+ "default": null,
109
+ "description": "Open or closed (controlled), with `onOpenChange`.",
110
+ "required": false
111
+ },
112
+ {
113
+ "name": "tone",
114
+ "type": "\"danger\" | \"primary\"",
115
+ "default": "primary",
116
+ "description": "`danger` for a destructive action (delete, leave, cancel a payment).",
117
+ "required": false
118
+ },
119
+ {
120
+ "name": "trigger",
121
+ "type": "ReactNode",
122
+ "default": null,
123
+ "description": "The element that opens the dialog (rendered as is, `asChild`): a Button, an IconButton.",
124
+ "required": false
125
+ }
126
+ ]
127
+ },
128
+ {
129
+ "component": "DialogContent",
130
+ "description": "The dialog itself, portalled over a dimmed overlay, with a close button. Give it a `Dialog.Title`.",
131
+ "props": [
132
+ {
133
+ "name": "closeLabel",
134
+ "type": "string",
135
+ "default": null,
136
+ "description": "The accessible name of the close button — passed translated.",
137
+ "required": false
138
+ },
139
+ {
140
+ "name": "container",
141
+ "type": "HTMLElement | null",
142
+ "default": null,
143
+ "description": "The element the portal renders into (default: document.body).",
144
+ "required": false
145
+ },
146
+ {
147
+ "name": "dismissible",
148
+ "type": "boolean",
149
+ "default": "true",
150
+ "description": "`false`: Escape and a click outside do not close it (a gate the user must answer: age, terms). It still closes\nthrough `open` / `onOpenChange` and any `Dialog.Close` inside. Default `true`.",
151
+ "required": false
152
+ },
153
+ {
154
+ "name": "hideClose",
155
+ "type": "boolean",
156
+ "default": null,
157
+ "description": "Leaves the close button out (the content brings its own way out, or none: see `dismissible`).",
158
+ "required": false
159
+ },
160
+ {
161
+ "name": "placement",
162
+ "type": "\"center\" | \"bottom\" | \"right\"",
163
+ "default": "center",
164
+ "description": "center · bottom (a sheet on a phone, centred from `sm` up) · right (a side panel, full height).",
165
+ "required": false
166
+ },
167
+ {
168
+ "name": "size",
169
+ "type": "\"sm\" | \"md\" | \"lg\"",
170
+ "default": "md",
171
+ "description": "sm · md · lg: the width of the dialog.",
172
+ "required": false
173
+ }
174
+ ]
175
+ },
176
+ {
177
+ "component": "Sheet",
178
+ "description": "A sheet is a dialog anchored at the bottom (centred from `sm` up): `Dialog.Content placement=\"bottom\"`.",
179
+ "props": [
180
+ {
181
+ "name": "closeLabel",
182
+ "type": "string",
183
+ "default": null,
184
+ "description": "The accessible name of the close button — passed translated.",
185
+ "required": false
186
+ },
187
+ {
188
+ "name": "container",
189
+ "type": "HTMLElement | null",
190
+ "default": null,
191
+ "description": "The element the portal renders into (default: document.body).",
192
+ "required": false
193
+ },
194
+ {
195
+ "name": "dismissible",
196
+ "type": "boolean",
197
+ "default": null,
198
+ "description": "`false`: Escape and a click outside do not close it (a gate the user must answer: age, terms). It still closes\nthrough `open` / `onOpenChange` and any `Dialog.Close` inside. Default `true`.",
199
+ "required": false
200
+ },
201
+ {
202
+ "name": "hideClose",
203
+ "type": "boolean",
204
+ "default": null,
205
+ "description": "Leaves the close button out (the content brings its own way out, or none: see `dismissible`).",
206
+ "required": false
207
+ },
208
+ {
209
+ "name": "size",
210
+ "type": "\"sm\" | \"md\" | \"lg\"",
211
+ "default": "md",
212
+ "description": "sm · md · lg: the width of the dialog.",
213
+ "required": false
214
+ }
215
+ ]
216
+ }
217
+ ]
218
+ }