@krizaka/ui 2.0.0-beta.0 → 2.0.0-beta.2

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 (82) hide show
  1. package/README.md +52 -3
  2. package/dist/alert.d.ts +95 -0
  3. package/dist/alert.js +38 -0
  4. package/dist/alert.js.map +1 -0
  5. package/dist/button-G5qY4qSY.d.ts +68 -0
  6. package/dist/card.d.ts +227 -0
  7. package/dist/card.js +108 -0
  8. package/dist/card.js.map +1 -0
  9. package/dist/checkbox.d.ts +52 -0
  10. package/dist/checkbox.js +42 -0
  11. package/dist/checkbox.js.map +1 -0
  12. package/dist/chip.d.ts +97 -0
  13. package/dist/chip.js +93 -0
  14. package/dist/chip.js.map +1 -0
  15. package/dist/chunk-5AXLA4LK.js +13 -0
  16. package/dist/chunk-5AXLA4LK.js.map +1 -0
  17. package/dist/chunk-5FRYKFTO.js +121 -0
  18. package/dist/chunk-5FRYKFTO.js.map +1 -0
  19. package/dist/{chunk-CPMZS4XA.js → chunk-FJDSLNXK.js} +1 -1
  20. package/dist/chunk-FJDSLNXK.js.map +1 -0
  21. package/dist/chunk-J3NC6ER4.js +9 -0
  22. package/dist/chunk-J3NC6ER4.js.map +1 -0
  23. package/dist/chunk-QRG5RYEI.js +49 -0
  24. package/dist/chunk-QRG5RYEI.js.map +1 -0
  25. package/dist/cn.d.ts +3 -0
  26. package/dist/cn.js +1 -1
  27. package/dist/command.d.ts +156 -0
  28. package/dist/command.js +111 -0
  29. package/dist/command.js.map +1 -0
  30. package/dist/confirm-button.d.ts +23 -0
  31. package/dist/confirm-button.js +85 -0
  32. package/dist/confirm-button.js.map +1 -0
  33. package/dist/dialog-DGBY2grk.d.ts +147 -0
  34. package/dist/dialog.d.ts +28 -0
  35. package/dist/dialog.js +93 -0
  36. package/dist/dialog.js.map +1 -0
  37. package/dist/dropdown-menu.d.ts +71 -0
  38. package/dist/dropdown-menu.js +66 -0
  39. package/dist/dropdown-menu.js.map +1 -0
  40. package/dist/field.js +1 -1
  41. package/dist/kbd.d.ts +24 -0
  42. package/dist/kbd.js +16 -0
  43. package/dist/kbd.js.map +1 -0
  44. package/dist/motion.css +7 -1
  45. package/dist/page-header.d.ts +77 -0
  46. package/dist/page-header.js +32 -0
  47. package/dist/page-header.js.map +1 -0
  48. package/dist/popover.d.ts +18 -0
  49. package/dist/popover.js +34 -0
  50. package/dist/popover.js.map +1 -0
  51. package/dist/progress.d.ts +87 -0
  52. package/dist/progress.js +85 -0
  53. package/dist/progress.js.map +1 -0
  54. package/dist/radio-group.d.ts +77 -0
  55. package/dist/radio-group.js +48 -0
  56. package/dist/radio-group.js.map +1 -0
  57. package/dist/separator.d.ts +24 -0
  58. package/dist/separator.js +17 -0
  59. package/dist/separator.js.map +1 -0
  60. package/dist/slider.d.ts +88 -0
  61. package/dist/slider.js +82 -0
  62. package/dist/slider.js.map +1 -0
  63. package/dist/stat.d.ts +75 -0
  64. package/dist/stat.js +42 -0
  65. package/dist/stat.js.map +1 -0
  66. package/dist/switch.d.ts +72 -0
  67. package/dist/switch.js +38 -0
  68. package/dist/switch.js.map +1 -0
  69. package/dist/tabs.d.ts +83 -0
  70. package/dist/tabs.js +60 -0
  71. package/dist/tabs.js.map +1 -0
  72. package/dist/theme.d.ts +2 -59
  73. package/dist/theme.js +13 -34
  74. package/dist/theme.js.map +1 -1
  75. package/dist/toast.d.ts +32 -0
  76. package/dist/toast.js +49 -0
  77. package/dist/toast.js.map +1 -0
  78. package/dist/tooltip.d.ts +21 -0
  79. package/dist/tooltip.js +44 -0
  80. package/dist/tooltip.js.map +1 -0
  81. package/package.json +291 -5
  82. package/dist/chunk-CPMZS4XA.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/card/card.tsx"],"sourcesContent":["// Server-safe: no hook, no context. One `tv` definition with slots: each part takes its slot, and a product overrides\n// any part through `className` (merged last by tailwind-merge).\nimport { Slot } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { cn } from \"../cn\";\n\nexport const card = tv({\n slots: {\n root:\n \"group relative flex flex-col overflow-hidden border border-border-default bg-surface-1 text-fg transition-colors \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n media: \"relative overflow-hidden bg-media\",\n image: \"h-full w-full object-cover transition-transform duration-500 motion-safe:group-hover:scale-105\",\n fallback: \"flex h-full w-full items-center justify-center bg-linear-to-br from-accent/15 via-media to-accent-2/15 text-accent/60\",\n overlay: \"absolute z-10 flex items-center gap-1.5\",\n body: \"relative flex flex-1 flex-col gap-3\",\n title: \"line-clamp-1 text-sm font-semibold text-fg transition-colors group-hover:text-accent\",\n description: \"line-clamp-2 text-xs text-fg-secondary\",\n stat: \"min-w-0\",\n statLabel: \"text-[10px] font-semibold uppercase tracking-wider text-fg-secondary\",\n statValue: \"font-display text-xl font-black tabular-nums text-fg\",\n footer: \"relative mt-auto flex items-center gap-2 border-t border-border-subtle pt-3 text-xs text-fg-secondary\",\n },\n variants: {\n radius: { md: { root: \"rounded-md\" }, lg: { root: \"rounded-lg\" }, xl: { root: \"rounded-xl\" } },\n tone: { default: {}, elevated: { root: \"bg-surface-2 shadow-md\" }, glass: { root: \"bg-surface-1/70 backdrop-blur-md\" } },\n interactive: { true: { root: \"kz-spotlight kz-lift hover:border-accent/50\" } },\n padding: { none: { body: \"p-0\" }, sm: { body: \"p-3\" }, md: { body: \"p-4\" }, lg: { body: \"p-6\" } },\n },\n defaultVariants: { radius: \"xl\", tone: \"default\", padding: \"md\" },\n});\n\ntype CardVariants = VariantProps<typeof card>;\n/** The parts without a variant read the default slots: no context, so server-safe. */\nconst slots = card();\n\nexport type CardRootProps = React.ComponentProps<\"div\"> &\n Pick<CardVariants, \"radius\" | \"tone\" | \"interactive\"> & {\n /** Renders the child (a link, an article) instead of the <div>, with props, classes and ref merged. */\n asChild?: boolean;\n /** Enters on scroll (MotionObserver): the index in the grid becomes the delay (50 ms a step, 8 steps at most). */\n reveal?: number;\n };\n\nexport function CardRoot({ asChild, reveal, radius, tone, interactive, className, style, ...props }: CardRootProps) {\n const Comp = asChild ? Slot.Root : \"div\";\n const revealStyle =\n reveal === undefined ? style : ({ ...style, \"--kz-delay\": `${Math.min(Math.max(reveal, 0), 8) * 50}ms` } as React.CSSProperties);\n return (\n <Comp\n data-reveal={reveal === undefined ? undefined : \"\"}\n data-interactive={interactive ? \"\" : undefined}\n style={revealStyle}\n className={card({ radius, tone, interactive }).root({ className })}\n {...props}\n />\n );\n}\n\nconst ASPECT = { video: \"aspect-video\", square: \"aspect-square\", portrait: \"aspect-[3/4]\", auto: \"\" } as const;\nexport type CardMediaProps = React.ComponentProps<\"div\"> & { aspect?: keyof typeof ASPECT };\n\nexport function CardMedia({ aspect = \"video\", className, ...props }: CardMediaProps) {\n return <div data-aspect={aspect} className={slots.media({ className: cn(ASPECT[aspect], className) })} {...props} />;\n}\n\nexport type CardImageProps = Omit<React.ComponentProps<\"img\">, \"src\"> & {\n src?: string | null;\n /** Shown when there is no image: an icon, an illustration (decorative). */\n fallback?: React.ReactNode;\n};\n\n/** The image of a media, or its `fallback` when there is none. `alt` is empty by default: the title names the card. */\nexport function CardImage({ src, alt = \"\", fallback, className, ...props }: CardImageProps) {\n if (!src) {\n return (\n <div data-fallback=\"\" aria-hidden className={slots.fallback({ className })}>\n {fallback}\n </div>\n );\n }\n return <img src={src} alt={alt} loading=\"lazy\" decoding=\"async\" className={slots.image({ className })} {...props} />;\n}\n\nconst CORNER = {\n \"top-left\": \"left-2.5 top-2.5\",\n \"top-right\": \"right-2.5 top-2.5\",\n \"bottom-left\": \"bottom-2.5 left-2.5\",\n \"bottom-right\": \"bottom-2.5 right-2.5\",\n} as const;\nexport type CardOverlayProps = React.ComponentProps<\"div\"> & { corner?: keyof typeof CORNER };\n\n/** What sits on the media (badges, a caption). `scrim` and `fg-on-media` are invariant: nothing to do for light. */\nexport function CardOverlay({ corner = \"top-left\", className, ...props }: CardOverlayProps) {\n return <div data-corner={corner} className={slots.overlay({ className: cn(CORNER[corner], className) })} {...props} />;\n}\n\nexport type CardBodyProps = React.ComponentProps<\"div\"> & Pick<CardVariants, \"padding\">;\n\nexport function CardBody({ padding, className, ...props }: CardBodyProps) {\n return <div className={card({ padding }).body({ className })} {...props} />;\n}\n\nexport type CardTitleProps = React.ComponentProps<\"h3\"> & { as?: \"h2\" | \"h3\" | \"h4\" };\n\nexport function CardTitle({ as: Tag = \"h3\", className, ...props }: CardTitleProps) {\n return <Tag className={slots.title({ className })} {...props} />;\n}\n\nexport function CardDescription({ className, ...props }: React.ComponentProps<\"p\">) {\n return <p className={slots.description({ className })} {...props} />;\n}\n\nexport type CardStatProps = React.ComponentProps<\"div\"> & { label: React.ReactNode };\n\n/** A figure put forward: the label in capitals, the value in tabular digits. */\nexport function CardStat({ label, className, children, ...props }: CardStatProps) {\n return (\n <div className={slots.stat({ className })} {...props}>\n <p className={slots.statLabel()}>{label}</p>\n <p className={slots.statValue()}>{children}</p>\n </div>\n );\n}\n\nexport function CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div className={slots.footer({ className })} {...props} />;\n}\n\n/** `Card.Root/Media/Image/Overlay/Body/Title/Description/Stat/Footer`. */\nexport const Card = {\n Root: CardRoot,\n Media: CardMedia,\n Image: CardImage,\n Overlay: CardOverlay,\n Body: CardBody,\n Title: CardTitle,\n Description: CardDescription,\n Stat: CardStat,\n Footer: CardFooter,\n};\n"],"mappings":"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","names":[]}
@@ -0,0 +1,52 @@
1
+ import * as tailwind_variants from 'tailwind-variants';
2
+ import { Checkbox as Checkbox$1 } from 'radix-ui';
3
+ import * as React from 'react';
4
+
5
+ declare const checkbox: tailwind_variants.TVReturnType<{
6
+ [key: string]: {
7
+ [key: string]: tailwind_variants.ClassValue | {
8
+ indicator?: tailwind_variants.ClassValue;
9
+ label?: tailwind_variants.ClassValue;
10
+ root?: tailwind_variants.ClassValue;
11
+ };
12
+ };
13
+ } | {
14
+ [x: string]: {
15
+ [x: string]: tailwind_variants.ClassValue | {
16
+ indicator?: tailwind_variants.ClassValue;
17
+ label?: tailwind_variants.ClassValue;
18
+ root?: tailwind_variants.ClassValue;
19
+ };
20
+ };
21
+ } | {}, {
22
+ root: string;
23
+ indicator: string;
24
+ label: string;
25
+ }, undefined, {
26
+ [key: string]: {
27
+ [key: string]: tailwind_variants.ClassValue | {
28
+ indicator?: tailwind_variants.ClassValue;
29
+ label?: tailwind_variants.ClassValue;
30
+ root?: tailwind_variants.ClassValue;
31
+ };
32
+ };
33
+ } | {}, {
34
+ root: string;
35
+ indicator: string;
36
+ label: string;
37
+ }, tailwind_variants.TVReturnTypeLike<unknown, {
38
+ root: string;
39
+ indicator: string;
40
+ label: string;
41
+ }>>;
42
+ type CheckboxProps = Omit<React.ComponentProps<typeof Checkbox$1.Root>, "children"> & {
43
+ /** Marks it invalid: aria-invalid and data-invalid (pair it with a `Field.Error` in aria-describedby). */
44
+ invalid?: boolean;
45
+ /** The text next to the box, clickable: the box and its words in one `<label>`. Otherwise name it with
46
+ * `Field.Label htmlFor` or `aria-label`. */
47
+ children?: React.ReactNode;
48
+ };
49
+ /** A checkbox: `checked`/`defaultChecked` (`true` · `false` · `"indeterminate"`) + `onCheckedChange`. */
50
+ declare function Checkbox({ invalid, className, children, ...props }: CheckboxProps): React.JSX.Element;
51
+
52
+ export { Checkbox, type CheckboxProps, checkbox };
@@ -0,0 +1,42 @@
1
+ "use client";
2
+
3
+ // src/checkbox/checkbox.tsx
4
+ import { Checkbox as CheckboxPrimitive } from "radix-ui";
5
+ import { tv } from "tailwind-variants";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ var checkbox = tv({
8
+ slots: {
9
+ root: "peer inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-md border border-border-strong bg-surface-1 text-on-accent transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0 hover:border-accent disabled:cursor-not-allowed disabled:opacity-40 data-[state=checked]:border-accent data-[state=checked]:bg-accent data-[state=indeterminate]:border-accent data-[state=indeterminate]:bg-accent aria-invalid:border-danger aria-invalid:ring-danger/30",
10
+ indicator: "flex items-center justify-center",
11
+ label: "flex cursor-pointer items-start gap-3 text-sm text-fg has-disabled:cursor-not-allowed has-disabled:opacity-60"
12
+ }
13
+ });
14
+ function Check() {
15
+ return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", className: "h-3.5 w-3.5", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M20 6 9 17l-5-5" }) });
16
+ }
17
+ function Dash() {
18
+ return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", className: "h-3.5 w-3.5", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M5 12h14" }) });
19
+ }
20
+ function Checkbox({ invalid, className, children, ...props }) {
21
+ const s = checkbox();
22
+ const box = /* @__PURE__ */ jsx(
23
+ CheckboxPrimitive.Root,
24
+ {
25
+ "aria-invalid": invalid || void 0,
26
+ "data-invalid": invalid ? "" : void 0,
27
+ className: s.root({ className: children ? "mt-0.5" : className }),
28
+ ...props,
29
+ children: /* @__PURE__ */ jsx(CheckboxPrimitive.Indicator, { className: s.indicator(), children: props.checked === "indeterminate" ? /* @__PURE__ */ jsx(Dash, {}) : /* @__PURE__ */ jsx(Check, {}) })
30
+ }
31
+ );
32
+ if (!children) return box;
33
+ return /* @__PURE__ */ jsxs("label", { className: s.label({ className }), children: [
34
+ box,
35
+ /* @__PURE__ */ jsx("span", { className: "min-w-0", children })
36
+ ] });
37
+ }
38
+ export {
39
+ Checkbox,
40
+ checkbox
41
+ };
42
+ //# sourceMappingURL=checkbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/checkbox/checkbox.tsx"],"sourcesContent":["// Client. Radix Checkbox: role=\"checkbox\", aria-checked (true · false · mixed), Space toggles, a hidden input inside a\n// form. It sits in a `Field` like the other controls: `<Field.Label htmlFor={id}>`, `invalid`, aria-describedby.\nimport { Checkbox as CheckboxPrimitive } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nexport const checkbox = tv({\n slots: {\n root:\n \"peer inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-md border border-border-strong bg-surface-1 text-on-accent transition-colors \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0 \" +\n \"hover:border-accent disabled:cursor-not-allowed disabled:opacity-40 \" +\n \"data-[state=checked]:border-accent data-[state=checked]:bg-accent data-[state=indeterminate]:border-accent data-[state=indeterminate]:bg-accent \" +\n \"aria-invalid:border-danger aria-invalid:ring-danger/30\",\n indicator: \"flex items-center justify-center\",\n label: \"flex cursor-pointer items-start gap-3 text-sm text-fg has-disabled:cursor-not-allowed has-disabled:opacity-60\",\n },\n});\n\nfunction Check() {\n return (\n <svg viewBox=\"0 0 24 24\" className=\"h-3.5 w-3.5\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"3\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n );\n}\n\nfunction Dash() {\n return (\n <svg viewBox=\"0 0 24 24\" className=\"h-3.5 w-3.5\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"3\" strokeLinecap=\"round\" aria-hidden>\n <path d=\"M5 12h14\" />\n </svg>\n );\n}\n\nexport type CheckboxProps = Omit<React.ComponentProps<typeof CheckboxPrimitive.Root>, \"children\"> & {\n /** Marks it invalid: aria-invalid and data-invalid (pair it with a `Field.Error` in aria-describedby). */\n invalid?: boolean;\n /** The text next to the box, clickable: the box and its words in one `<label>`. Otherwise name it with\n * `Field.Label htmlFor` or `aria-label`. */\n children?: React.ReactNode;\n};\n\n/** A checkbox: `checked`/`defaultChecked` (`true` · `false` · `\"indeterminate\"`) + `onCheckedChange`. */\nexport function Checkbox({ invalid, className, children, ...props }: CheckboxProps) {\n const s = checkbox();\n const box = (\n <CheckboxPrimitive.Root\n aria-invalid={invalid || undefined}\n data-invalid={invalid ? \"\" : undefined}\n className={s.root({ className: children ? \"mt-0.5\" : className })}\n {...props}\n >\n <CheckboxPrimitive.Indicator className={s.indicator()}>\n {props.checked === \"indeterminate\" ? <Dash /> : <Check />}\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n );\n if (!children) return box;\n return (\n <label className={s.label({ className })}>\n {box}\n <span className=\"min-w-0\">{children}</span>\n </label>\n );\n}\n"],"mappings":";;;AAEA,SAAS,YAAY,yBAAyB;AAE9C,SAAS,UAAU;AAkBb,cAsCF,YAtCE;AAhBC,IAAM,WAAW,GAAG;AAAA,EACzB,OAAO;AAAA,IACL,MACE;AAAA,IAKF,WAAW;AAAA,IACX,OAAO;AAAA,EACT;AACF,CAAC;AAED,SAAS,QAAQ;AACf,SACE,oBAAC,SAAI,SAAQ,aAAY,WAAU,eAAc,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SAAQ,eAAW,MACzJ,8BAAC,UAAK,GAAE,mBAAkB,GAC5B;AAEJ;AAEA,SAAS,OAAO;AACd,SACE,oBAAC,SAAI,SAAQ,aAAY,WAAU,eAAc,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,eAAW,MAClI,8BAAC,UAAK,GAAE,YAAW,GACrB;AAEJ;AAWO,SAAS,SAAS,EAAE,SAAS,WAAW,UAAU,GAAG,MAAM,GAAkB;AAClF,QAAM,IAAI,SAAS;AACnB,QAAM,MACJ;AAAA,IAAC,kBAAkB;AAAA,IAAlB;AAAA,MACC,gBAAc,WAAW;AAAA,MACzB,gBAAc,UAAU,KAAK;AAAA,MAC7B,WAAW,EAAE,KAAK,EAAE,WAAW,WAAW,WAAW,UAAU,CAAC;AAAA,MAC/D,GAAG;AAAA,MAEJ,8BAAC,kBAAkB,WAAlB,EAA4B,WAAW,EAAE,UAAU,GACjD,gBAAM,YAAY,kBAAkB,oBAAC,QAAK,IAAK,oBAAC,SAAM,GACzD;AAAA;AAAA,EACF;AAEF,MAAI,CAAC,SAAU,QAAO;AACtB,SACE,qBAAC,WAAM,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,GACpC;AAAA;AAAA,IACD,oBAAC,UAAK,WAAU,WAAW,UAAS;AAAA,KACtC;AAEJ;","names":[]}
package/dist/chip.d.ts ADDED
@@ -0,0 +1,97 @@
1
+ import * as tailwind_variants from 'tailwind-variants';
2
+ import { VariantProps } from 'tailwind-variants';
3
+ import * as React from 'react';
4
+
5
+ declare const chip: tailwind_variants.TVReturnType<{
6
+ size: {
7
+ sm: {
8
+ base: string;
9
+ };
10
+ md: {
11
+ base: string;
12
+ };
13
+ };
14
+ }, {
15
+ group: string;
16
+ base: string;
17
+ remove: string;
18
+ }, undefined, {
19
+ size: {
20
+ sm: {
21
+ base: string;
22
+ };
23
+ md: {
24
+ base: string;
25
+ };
26
+ };
27
+ }, {
28
+ group: string;
29
+ base: string;
30
+ remove: string;
31
+ }, tailwind_variants.TVReturnTypeLike<{
32
+ size: {
33
+ sm: {
34
+ base: string;
35
+ };
36
+ md: {
37
+ base: string;
38
+ };
39
+ };
40
+ }, {
41
+ group: string;
42
+ base: string;
43
+ remove: string;
44
+ }>>;
45
+ type ChipVariants = VariantProps<typeof chip>;
46
+ type ToggleChipProps = Omit<React.ComponentProps<"button">, "value" | "defaultValue"> & ChipVariants & {
47
+ /** Inside `Chip.Group`: the value this chip stands for (required there, ignored alone). */
48
+ value?: string;
49
+ /** Alone: pressed or not (`defaultSelected` uncontrolled), `onSelectedChange` on every press. */
50
+ selected?: boolean;
51
+ defaultSelected?: boolean;
52
+ onSelectedChange?: (selected: boolean) => void;
53
+ removable?: false;
54
+ };
55
+ type RemovableChipProps = Omit<React.ComponentProps<"span">, "onSelect"> & ChipVariants & {
56
+ /** A static chip (a chosen tag, an applied filter) with a remove button. */
57
+ removable: true;
58
+ /** The accessible name of the remove button — passed translated, e.g. "Remove #night". */
59
+ removeLabel: string;
60
+ onRemove: () => void;
61
+ disabled?: boolean;
62
+ };
63
+ type ChipProps = ToggleChipProps | RemovableChipProps;
64
+ /** A selectable pill (`selected` / `onSelectedChange`), an item of `Chip.Group` (`value`), or `removable`. */
65
+ declare function ChipBase(props: ChipProps): React.JSX.Element;
66
+ type GroupBase = Omit<React.ComponentProps<"div">, "defaultValue" | "dir"> & ChipVariants & {
67
+ /** The group's accessible name — passed translated ("Filter by format"). */
68
+ label?: string;
69
+ orientation?: "horizontal" | "vertical";
70
+ /** Arrow keys wrap from the last chip to the first (default `true`). */
71
+ loop?: boolean;
72
+ disabled?: boolean;
73
+ };
74
+ type ChipGroupProps = (GroupBase & {
75
+ /** One choice: the chips behave as radios. */
76
+ type: "single";
77
+ value?: string;
78
+ defaultValue?: string;
79
+ onValueChange?: (value: string) => void;
80
+ /** Keeps one chip selected: pressing the selected chip does not clear it (default `false`). */
81
+ required?: boolean;
82
+ }) | (GroupBase & {
83
+ /** Any number of choices: the chips are pressed buttons. */
84
+ type: "multiple";
85
+ value?: string[];
86
+ defaultValue?: string[];
87
+ onValueChange?: (value: string[]) => void;
88
+ required?: never;
89
+ });
90
+ /** Chips that choose together: `type` single · multiple, `value`/`defaultValue` + `onValueChange`. */
91
+ declare function ChipGroup({ label, size, className, children, ...props }: ChipGroupProps): React.JSX.Element;
92
+ /** `Chip` (selectable, removable) and `Chip.Group` (single · multiple). */
93
+ declare const Chip: typeof ChipBase & {
94
+ Group: typeof ChipGroup;
95
+ };
96
+
97
+ export { Chip, ChipGroup, type ChipGroupProps, type ChipProps, type ChipVariants, chip };
package/dist/chip.js ADDED
@@ -0,0 +1,93 @@
1
+ "use client";
2
+
3
+ // src/chip/chip.tsx
4
+ import { Toggle as TogglePrimitive, ToggleGroup as ToggleGroupPrimitive } from "radix-ui";
5
+ import * as React from "react";
6
+ import { tv } from "tailwind-variants";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ var chip = tv({
9
+ slots: {
10
+ group: "flex flex-wrap items-center gap-2 data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch",
11
+ base: "inline-flex shrink-0 select-none items-center justify-center gap-1.5 whitespace-nowrap rounded-full border font-semibold transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-40 border-border-default bg-surface-1 text-fg-secondary hover:border-border-strong hover:text-fg data-[state=on]:border-accent data-[state=on]:bg-accent-soft data-[state=on]:text-fg",
12
+ remove: "-mr-1.5 inline-flex h-6 w-6 items-center justify-center rounded-full text-fg-secondary transition-colors hover:bg-surface-3 hover:text-fg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring"
13
+ },
14
+ variants: {
15
+ size: { sm: { base: "h-7 px-3 text-xs" }, md: { base: "h-9 px-3.5 text-xs" } }
16
+ },
17
+ defaultVariants: { size: "md" }
18
+ });
19
+ var ChipGroupContext = React.createContext(null);
20
+ function RemoveIcon() {
21
+ return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", className: "h-3.5 w-3.5", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M18 6 6 18M6 6l12 12" }) });
22
+ }
23
+ function ChipBase(props) {
24
+ const group = React.useContext(ChipGroupContext);
25
+ if (props.removable) {
26
+ const { removable: _removable2, removeLabel, onRemove, disabled, size: size2, className: className2, children, ...rest2 } = props;
27
+ const s2 = chip({ size: size2 ?? group?.size });
28
+ return /* @__PURE__ */ jsxs("span", { "data-removable": "", className: s2.base({ className: className2 }), ...rest2, children: [
29
+ children,
30
+ /* @__PURE__ */ jsx("button", { type: "button", "aria-label": removeLabel, title: removeLabel, disabled, onClick: onRemove, className: s2.remove(), children: /* @__PURE__ */ jsx(RemoveIcon, {}) })
31
+ ] });
32
+ }
33
+ const { removable: _removable, value, selected, defaultSelected, onSelectedChange, size, className, ...rest } = props;
34
+ const s = chip({ size: size ?? group?.size });
35
+ if (group) {
36
+ if (value === void 0) throw new Error("Chip: a chip inside Chip.Group needs a `value`.");
37
+ return /* @__PURE__ */ jsx(ToggleGroupPrimitive.Item, { value, className: s.base({ className }), ...rest });
38
+ }
39
+ return /* @__PURE__ */ jsx(
40
+ TogglePrimitive.Root,
41
+ {
42
+ pressed: selected,
43
+ defaultPressed: defaultSelected,
44
+ onPressedChange: onSelectedChange,
45
+ className: s.base({ className }),
46
+ ...rest
47
+ }
48
+ );
49
+ }
50
+ function ChipGroup({ label, size, className, children, ...props }) {
51
+ const s = chip({ size });
52
+ const context = React.useMemo(() => ({ size }), [size]);
53
+ const common = { "aria-label": label, className: s.group({ className }) };
54
+ let group;
55
+ if (props.type === "single") {
56
+ const { type: _type, value, defaultValue, onValueChange, required, ...rest } = props;
57
+ group = /* @__PURE__ */ jsx(SingleGroup, { ...rest, ...common, value, defaultValue, onValueChange, required, children });
58
+ } else {
59
+ const { type: _type, required: _required, ...rest } = props;
60
+ group = /* @__PURE__ */ jsx(ToggleGroupPrimitive.Root, { type: "multiple", ...rest, ...common, children });
61
+ }
62
+ return /* @__PURE__ */ jsx(ChipGroupContext.Provider, { value: context, children: group });
63
+ }
64
+ function SingleGroup({
65
+ value,
66
+ defaultValue,
67
+ onValueChange,
68
+ required,
69
+ ...props
70
+ }) {
71
+ const [inner, setInner] = React.useState(defaultValue ?? "");
72
+ const current = value ?? inner;
73
+ return /* @__PURE__ */ jsx(
74
+ ToggleGroupPrimitive.Root,
75
+ {
76
+ type: "single",
77
+ value: current,
78
+ onValueChange: (next) => {
79
+ if (required && !next) return;
80
+ if (value === void 0) setInner(next);
81
+ onValueChange?.(next);
82
+ },
83
+ ...props
84
+ }
85
+ );
86
+ }
87
+ var Chip = Object.assign(ChipBase, { Group: ChipGroup });
88
+ export {
89
+ Chip,
90
+ ChipGroup,
91
+ chip
92
+ };
93
+ //# sourceMappingURL=chip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/chip/chip.tsx"],"sourcesContent":["// Client (a context). A chip is a pressable pill: alone it is a Radix Toggle (aria-pressed), inside `Chip.Group` an\n// item of a Radix Toggle Group (roving focus with the arrows; `single` = radio semantics, `multiple` = pressed\n// buttons). A `removable` chip is a static label with its own remove button (two buttons cannot nest).\nimport { Toggle as TogglePrimitive, ToggleGroup as ToggleGroupPrimitive } from \"radix-ui\";\nimport * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nexport const chip = tv({\n slots: {\n group: \"flex flex-wrap items-center gap-2 data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch\",\n base:\n \"inline-flex shrink-0 select-none items-center justify-center gap-1.5 whitespace-nowrap rounded-full border font-semibold transition-colors \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-40 \" +\n \"border-border-default bg-surface-1 text-fg-secondary hover:border-border-strong hover:text-fg \" +\n \"data-[state=on]:border-accent data-[state=on]:bg-accent-soft data-[state=on]:text-fg\",\n remove:\n \"-mr-1.5 inline-flex h-6 w-6 items-center justify-center rounded-full text-fg-secondary transition-colors hover:bg-surface-3 hover:text-fg \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n },\n variants: {\n size: { sm: { base: \"h-7 px-3 text-xs\" }, md: { base: \"h-9 px-3.5 text-xs\" } },\n },\n defaultVariants: { size: \"md\" },\n});\n\nexport type ChipVariants = VariantProps<typeof chip>;\n\ntype GroupContext = { size: ChipVariants[\"size\"] };\nconst ChipGroupContext = React.createContext<GroupContext | null>(null);\n\nfunction RemoveIcon() {\n return (\n <svg viewBox=\"0 0 24 24\" className=\"h-3.5 w-3.5\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" aria-hidden>\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </svg>\n );\n}\n\ntype ToggleChipProps = Omit<React.ComponentProps<\"button\">, \"value\" | \"defaultValue\"> &\n ChipVariants & {\n /** Inside `Chip.Group`: the value this chip stands for (required there, ignored alone). */\n value?: string;\n /** Alone: pressed or not (`defaultSelected` uncontrolled), `onSelectedChange` on every press. */\n selected?: boolean;\n defaultSelected?: boolean;\n onSelectedChange?: (selected: boolean) => void;\n removable?: false;\n };\n\ntype RemovableChipProps = Omit<React.ComponentProps<\"span\">, \"onSelect\"> &\n ChipVariants & {\n /** A static chip (a chosen tag, an applied filter) with a remove button. */\n removable: true;\n /** The accessible name of the remove button — passed translated, e.g. \"Remove #night\". */\n removeLabel: string;\n onRemove: () => void;\n disabled?: boolean;\n };\n\nexport type ChipProps = ToggleChipProps | RemovableChipProps;\n\n/** A selectable pill (`selected` / `onSelectedChange`), an item of `Chip.Group` (`value`), or `removable`. */\nfunction ChipBase(props: ChipProps) {\n const group = React.useContext(ChipGroupContext);\n if (props.removable) {\n const { removable: _removable, removeLabel, onRemove, disabled, size, className, children, ...rest } = props;\n const s = chip({ size: size ?? group?.size });\n return (\n <span data-removable=\"\" className={s.base({ className })} {...rest}>\n {children}\n <button type=\"button\" aria-label={removeLabel} title={removeLabel} disabled={disabled} onClick={onRemove} className={s.remove()}>\n <RemoveIcon />\n </button>\n </span>\n );\n }\n const { removable: _removable, value, selected, defaultSelected, onSelectedChange, size, className, ...rest } = props;\n const s = chip({ size: size ?? group?.size });\n if (group) {\n if (value === undefined) throw new Error(\"Chip: a chip inside Chip.Group needs a `value`.\");\n return <ToggleGroupPrimitive.Item value={value} className={s.base({ className })} {...rest} />;\n }\n return (\n <TogglePrimitive.Root\n pressed={selected}\n defaultPressed={defaultSelected}\n onPressedChange={onSelectedChange}\n className={s.base({ className })}\n {...rest}\n />\n );\n}\n\ntype GroupBase = Omit<React.ComponentProps<\"div\">, \"defaultValue\" | \"dir\"> &\n ChipVariants & {\n /** The group's accessible name — passed translated (\"Filter by format\"). */\n label?: string;\n orientation?: \"horizontal\" | \"vertical\";\n /** Arrow keys wrap from the last chip to the first (default `true`). */\n loop?: boolean;\n disabled?: boolean;\n };\n\nexport type ChipGroupProps =\n | (GroupBase & {\n /** One choice: the chips behave as radios. */\n type: \"single\";\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n /** Keeps one chip selected: pressing the selected chip does not clear it (default `false`). */\n required?: boolean;\n })\n | (GroupBase & {\n /** Any number of choices: the chips are pressed buttons. */\n type: \"multiple\";\n value?: string[];\n defaultValue?: string[];\n onValueChange?: (value: string[]) => void;\n required?: never;\n });\n\n/** Chips that choose together: `type` single · multiple, `value`/`defaultValue` + `onValueChange`. */\nexport function ChipGroup({ label, size, className, children, ...props }: ChipGroupProps) {\n const s = chip({ size });\n const context = React.useMemo(() => ({ size }), [size]);\n const common = { \"aria-label\": label, className: s.group({ className }) };\n let group: React.ReactNode;\n if (props.type === \"single\") {\n const { type: _type, value, defaultValue, onValueChange, required, ...rest } = props;\n group = <SingleGroup {...rest} {...common} value={value} defaultValue={defaultValue} onValueChange={onValueChange} required={required}>{children}</SingleGroup>;\n } else {\n const { type: _type, required: _required, ...rest } = props;\n group = (\n <ToggleGroupPrimitive.Root type=\"multiple\" {...rest} {...common}>\n {children}\n </ToggleGroupPrimitive.Root>\n );\n }\n return <ChipGroupContext.Provider value={context}>{group}</ChipGroupContext.Provider>;\n}\n\n/** Radix's single group, plus `required`: the value is held here so that an empty change can be refused. */\nfunction SingleGroup({\n value,\n defaultValue,\n onValueChange,\n required,\n ...props\n}: Omit<GroupBase, \"size\" | \"label\"> & {\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n required?: boolean;\n}) {\n const [inner, setInner] = React.useState(defaultValue ?? \"\");\n const current = value ?? inner;\n return (\n <ToggleGroupPrimitive.Root\n type=\"single\"\n value={current}\n onValueChange={(next) => {\n if (required && !next) return;\n if (value === undefined) setInner(next);\n onValueChange?.(next);\n }}\n {...props}\n />\n );\n}\n\n/** `Chip` (selectable, removable) and `Chip.Group` (single · multiple). */\nexport const Chip = Object.assign(ChipBase, { Group: ChipGroup });\n"],"mappings":"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","names":["_removable","size","className","rest","s"]}
@@ -0,0 +1,13 @@
1
+ "use client";
2
+
3
+ // src/cn.ts
4
+ import { clsx } from "clsx";
5
+ import { cn as merge } from "tailwind-variants";
6
+ function cn(...inputs) {
7
+ return merge(clsx(inputs)) ?? "";
8
+ }
9
+
10
+ export {
11
+ cn
12
+ };
13
+ //# sourceMappingURL=chunk-5AXLA4LK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cn.ts"],"sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { cn as merge } from \"tailwind-variants\";\n\nexport type { ClassValue };\n\n/**\n * Merges Tailwind classes: the last one wins — a product's `className` overrides the primitive's. The merge engine is\n * tailwind-merge as tailwind-variants ships it (the one `tv` uses), so the platform carries a single copy of it.\n * tailwind-variants bundles that engine since 3.3 (it never imports the `tailwind-merge` package, an optional peer):\n * hence `tailwind-variants ^3.3.1` and no `tailwind-merge` dependency — `scripts/consumer.mjs` checks it on a clean\n * install of the packed package.\n */\nexport function cn(...inputs: ClassValue[]): string {\n return merge(clsx(inputs)) ?? \"\";\n}\n"],"mappings":";;;AAAA,SAA0B,YAAY;AACtC,SAAS,MAAM,aAAa;AAWrB,SAAS,MAAM,QAA8B;AAClD,SAAO,MAAM,KAAK,MAAM,CAAC,KAAK;AAChC;","names":[]}
@@ -0,0 +1,121 @@
1
+ "use client";
2
+ import {
3
+ IconButton
4
+ } from "./chunk-QRG5RYEI.js";
5
+
6
+ // src/dialog/dialog.tsx
7
+ import { Dialog as DialogPrimitive } from "radix-ui";
8
+ import { tv } from "tailwind-variants";
9
+ import { jsx, jsxs } from "react/jsx-runtime";
10
+ var dialog = tv({
11
+ slots: {
12
+ overlay: "kz-overlay fixed inset-0 z-50 bg-overlay backdrop-blur-xs",
13
+ content: "kz-dialog fixed z-50 flex flex-col overflow-hidden border border-border-default bg-surface-1 text-fg shadow-lg focus:outline-hidden",
14
+ close: "absolute right-3 top-3 h-9 w-9",
15
+ header: "flex flex-col gap-1 px-5 pb-2 pr-14 pt-5",
16
+ title: "text-base font-bold text-fg",
17
+ description: "text-sm text-fg-secondary",
18
+ body: "min-h-0 flex-1 overflow-y-auto px-5 pb-5",
19
+ footer: "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))]"
20
+ },
21
+ variants: {
22
+ placement: {
23
+ 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" },
24
+ /* A sheet: anchored at the bottom on a phone, centred from `sm` up. */
25
+ bottom: {
26
+ content: "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 sm:-translate-x-1/2 sm:-translate-y-1/2 sm:rounded-[1.75rem]"
27
+ },
28
+ right: { content: "inset-y-0 right-0 h-full w-full max-w-md rounded-none border-y-0 border-r-0" }
29
+ },
30
+ size: { sm: { content: "sm:max-w-sm" }, md: { content: "sm:max-w-md" }, lg: { content: "sm:max-w-2xl" } }
31
+ },
32
+ defaultVariants: { placement: "center", size: "md" }
33
+ });
34
+ var s = dialog();
35
+ function CloseIcon() {
36
+ return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", className: "h-4 w-4", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M18 6 6 18M6 6l12 12" }) });
37
+ }
38
+ var prevent = (event) => event.preventDefault();
39
+ function DialogContent({
40
+ placement,
41
+ size,
42
+ closeLabel,
43
+ hideClose,
44
+ dismissible = true,
45
+ container,
46
+ className,
47
+ children,
48
+ onEscapeKeyDown,
49
+ onPointerDownOutside,
50
+ onInteractOutside,
51
+ ...props
52
+ }) {
53
+ const v = dialog({ placement, size });
54
+ return /* @__PURE__ */ jsxs(DialogPrimitive.Portal, { container, children: [
55
+ /* @__PURE__ */ jsx(DialogPrimitive.Overlay, { className: v.overlay() }),
56
+ /* @__PURE__ */ jsxs(
57
+ DialogPrimitive.Content,
58
+ {
59
+ "data-placement": placement ?? "center",
60
+ "data-dismissible": dismissible ? void 0 : "false",
61
+ className: v.content({ className }),
62
+ onEscapeKeyDown: dismissible ? onEscapeKeyDown : chain(onEscapeKeyDown, prevent),
63
+ onPointerDownOutside: dismissible ? onPointerDownOutside : chain(onPointerDownOutside, prevent),
64
+ onInteractOutside: dismissible ? onInteractOutside : chain(onInteractOutside, prevent),
65
+ ...props,
66
+ children: [
67
+ children,
68
+ !hideClose && /* @__PURE__ */ jsx(DialogPrimitive.Close, { asChild: true, children: /* @__PURE__ */ jsx(IconButton, { label: closeLabel, variant: "ghost", shape: "pill", className: v.close(), children: /* @__PURE__ */ jsx(CloseIcon, {}) }) })
69
+ ]
70
+ }
71
+ )
72
+ ] });
73
+ }
74
+ function chain(handler, then) {
75
+ return (event) => {
76
+ handler?.(event);
77
+ then(event);
78
+ };
79
+ }
80
+ function DialogHeader({ className, ...props }) {
81
+ return /* @__PURE__ */ jsx("div", { className: s.header({ className }), ...props });
82
+ }
83
+ function DialogTitle({ className, ...props }) {
84
+ return /* @__PURE__ */ jsx(DialogPrimitive.Title, { className: s.title({ className }), ...props });
85
+ }
86
+ function DialogDescription({ className, ...props }) {
87
+ return /* @__PURE__ */ jsx(DialogPrimitive.Description, { className: s.description({ className }), ...props });
88
+ }
89
+ function DialogBody({ className, ...props }) {
90
+ return /* @__PURE__ */ jsx("div", { className: s.body({ className }), ...props });
91
+ }
92
+ function DialogFooter({ className, ...props }) {
93
+ return /* @__PURE__ */ jsx("div", { className: s.footer({ className }), ...props });
94
+ }
95
+ var Dialog = {
96
+ Root: DialogPrimitive.Root,
97
+ Trigger: DialogPrimitive.Trigger,
98
+ Close: DialogPrimitive.Close,
99
+ Content: DialogContent,
100
+ Header: DialogHeader,
101
+ Title: DialogTitle,
102
+ Description: DialogDescription,
103
+ Body: DialogBody,
104
+ Footer: DialogFooter
105
+ };
106
+ function Sheet(props) {
107
+ return /* @__PURE__ */ jsx(DialogContent, { placement: "bottom", ...props });
108
+ }
109
+
110
+ export {
111
+ dialog,
112
+ DialogContent,
113
+ DialogHeader,
114
+ DialogTitle,
115
+ DialogDescription,
116
+ DialogBody,
117
+ DialogFooter,
118
+ Dialog,
119
+ Sheet
120
+ };
121
+ //# sourceMappingURL=chunk-5FRYKFTO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/dialog/dialog.tsx"],"sourcesContent":["// 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 * `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"],"mappings":"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","names":[]}
@@ -8,4 +8,4 @@ function cn(...inputs) {
8
8
  export {
9
9
  cn
10
10
  };
11
- //# sourceMappingURL=chunk-CPMZS4XA.js.map
11
+ //# sourceMappingURL=chunk-FJDSLNXK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cn.ts"],"sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { cn as merge } from \"tailwind-variants\";\n\nexport type { ClassValue };\n\n/**\n * Merges Tailwind classes: the last one wins — a product's `className` overrides the primitive's. The merge engine is\n * tailwind-merge as tailwind-variants ships it (the one `tv` uses), so the platform carries a single copy of it.\n * tailwind-variants bundles that engine since 3.3 (it never imports the `tailwind-merge` package, an optional peer):\n * hence `tailwind-variants ^3.3.1` and no `tailwind-merge` dependency — `scripts/consumer.mjs` checks it on a clean\n * install of the packed package.\n */\nexport function cn(...inputs: ClassValue[]): string {\n return merge(clsx(inputs)) ?? \"\";\n}\n"],"mappings":";AAAA,SAA0B,YAAY;AACtC,SAAS,MAAM,aAAa;AAWrB,SAAS,MAAM,QAA8B;AAClD,SAAO,MAAM,KAAK,MAAM,CAAC,KAAK;AAChC;","names":[]}
@@ -0,0 +1,9 @@
1
+ "use client";
2
+
3
+ // src/floating.ts
4
+ var floating = "kz-pop z-50 rounded-lg border border-border-default bg-surface-2 text-fg shadow-lg outline-hidden";
5
+
6
+ export {
7
+ floating
8
+ };
9
+ //# sourceMappingURL=chunk-J3NC6ER4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/floating.ts"],"sourcesContent":["// The one surface of everything that floats next to its trigger (popover, menu, tooltip): a raised surface, a border,\n// the large shadow and the `kz-pop` entrance from the side Radix measured (`--radix-*-transform-origin`).\nexport const floating =\n \"kz-pop z-50 rounded-lg border border-border-default bg-surface-2 text-fg shadow-lg outline-hidden\";\n"],"mappings":";;;AAEO,IAAM,WACX;","names":[]}
@@ -0,0 +1,49 @@
1
+ "use client";
2
+
3
+ // src/button/button.tsx
4
+ import { Slot } from "radix-ui";
5
+ import { tv } from "tailwind-variants";
6
+ import { jsx } from "react/jsx-runtime";
7
+ var buttonVariants = tv({
8
+ base: "inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap font-semibold transition-all focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0 disabled:pointer-events-none disabled:opacity-40 data-loading:cursor-progress active:scale-[0.98]",
9
+ variants: {
10
+ variant: {
11
+ primary: "bg-accent text-on-accent shadow-sm hover:bg-accent-hover",
12
+ secondary: "border border-border-default bg-surface-2 text-fg hover:border-border-strong hover:bg-surface-3",
13
+ outline: "border border-border-default bg-transparent text-fg hover:border-accent hover:text-accent",
14
+ ghost: "text-fg-secondary hover:bg-surface-2 hover:text-fg",
15
+ // The danger token is invariant and too light for small text on a light surface (3.6:1): the label stays a
16
+ // text role, the border and the tint carry the danger.
17
+ danger: "border border-danger/50 bg-danger/10 text-fg hover:border-danger hover:bg-danger/20"
18
+ },
19
+ size: { sm: "h-8 px-3 text-xs", md: "h-10 px-4 text-sm", lg: "h-12 px-6 text-sm", icon: "h-10 w-10" },
20
+ shape: { rounded: "rounded-lg", pill: "rounded-full" }
21
+ },
22
+ defaultVariants: { variant: "secondary", size: "md", shape: "rounded" }
23
+ });
24
+ function Button({ asChild, loading, variant, size, shape, className, disabled, ...props }) {
25
+ const Comp = asChild ? Slot.Root : "button";
26
+ return /* @__PURE__ */ jsx(
27
+ Comp,
28
+ {
29
+ type: asChild ? void 0 : "button",
30
+ "aria-busy": loading || void 0,
31
+ "data-loading": loading ? "" : void 0,
32
+ "data-variant": variant ?? "secondary",
33
+ disabled: asChild ? void 0 : disabled || loading,
34
+ "aria-disabled": asChild && (disabled || loading) ? true : void 0,
35
+ className: buttonVariants({ variant, size, shape, className }),
36
+ ...props
37
+ }
38
+ );
39
+ }
40
+ function IconButton({ label, size = "icon", ...props }) {
41
+ return /* @__PURE__ */ jsx(Button, { "aria-label": label, title: label, size, ...props });
42
+ }
43
+
44
+ export {
45
+ buttonVariants,
46
+ Button,
47
+ IconButton
48
+ };
49
+ //# sourceMappingURL=chunk-QRG5RYEI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/button/button.tsx"],"sourcesContent":["// Server-safe: no hook, no context. `buttonVariants` styles a <Link> or a Server Component without the component.\nimport { Slot } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nexport const buttonVariants = tv({\n base:\n \"inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap font-semibold transition-all \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0 \" +\n \"disabled:pointer-events-none disabled:opacity-40 data-loading:cursor-progress active:scale-[0.98]\",\n variants: {\n variant: {\n primary: \"bg-accent text-on-accent shadow-sm hover:bg-accent-hover\",\n secondary: \"border border-border-default bg-surface-2 text-fg hover:border-border-strong hover:bg-surface-3\",\n outline: \"border border-border-default bg-transparent text-fg hover:border-accent hover:text-accent\",\n ghost: \"text-fg-secondary hover:bg-surface-2 hover:text-fg\",\n // The danger token is invariant and too light for small text on a light surface (3.6:1): the label stays a\n // text role, the border and the tint carry the danger.\n danger: \"border border-danger/50 bg-danger/10 text-fg hover:border-danger hover:bg-danger/20\",\n },\n size: { sm: \"h-8 px-3 text-xs\", md: \"h-10 px-4 text-sm\", lg: \"h-12 px-6 text-sm\", icon: \"h-10 w-10\" },\n shape: { rounded: \"rounded-lg\", pill: \"rounded-full\" },\n },\n defaultVariants: { variant: \"secondary\", size: \"md\", shape: \"rounded\" },\n});\n\nexport type ButtonVariants = VariantProps<typeof buttonVariants>;\n\nexport type ButtonProps = React.ComponentProps<\"button\"> &\n ButtonVariants & {\n /** Renders the child (e.g. a <Link>) instead of the <button>, with props, classes and ref merged. */\n asChild?: boolean;\n /** Disables and signals the wait (aria-busy, data-loading) — the product adds a spinner if it wants one. */\n loading?: boolean;\n };\n\nexport function Button({ asChild, loading, variant, size, shape, className, disabled, ...props }: ButtonProps) {\n const Comp = asChild ? Slot.Root : \"button\";\n return (\n <Comp\n type={asChild ? undefined : \"button\"}\n aria-busy={loading || undefined}\n data-loading={loading ? \"\" : undefined}\n data-variant={variant ?? \"secondary\"}\n disabled={asChild ? undefined : disabled || loading}\n aria-disabled={asChild && (disabled || loading) ? true : undefined}\n className={buttonVariants({ variant, size, shape, className })}\n {...props}\n />\n );\n}\n\nexport type IconButtonProps = Omit<ButtonProps, \"size\"> & {\n /** The accessible name (and tooltip) of the button — required, passed translated. */\n label: string;\n size?: ButtonProps[\"size\"];\n};\n\n/** An icon-only button: `label` is required, it is its accessible name. */\nexport function IconButton({ label, size = \"icon\", ...props }: IconButtonProps) {\n return <Button aria-label={label} title={label} size={size} {...props} />;\n}\n"],"mappings":";;;AACA,SAAS,YAAY;AAErB,SAAS,UAA6B;AAoClC;AAlCG,IAAM,iBAAiB,GAAG;AAAA,EAC/B,MACE;AAAA,EAGF,UAAU;AAAA,IACR,SAAS;AAAA,MACP,SAAS;AAAA,MACT,WAAW;AAAA,MACX,SAAS;AAAA,MACT,OAAO;AAAA;AAAA;AAAA,MAGP,QAAQ;AAAA,IACV;AAAA,IACA,MAAM,EAAE,IAAI,oBAAoB,IAAI,qBAAqB,IAAI,qBAAqB,MAAM,YAAY;AAAA,IACpG,OAAO,EAAE,SAAS,cAAc,MAAM,eAAe;AAAA,EACvD;AAAA,EACA,iBAAiB,EAAE,SAAS,aAAa,MAAM,MAAM,OAAO,UAAU;AACxE,CAAC;AAYM,SAAS,OAAO,EAAE,SAAS,SAAS,SAAS,MAAM,OAAO,WAAW,UAAU,GAAG,MAAM,GAAgB;AAC7G,QAAM,OAAO,UAAU,KAAK,OAAO;AACnC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAM,UAAU,SAAY;AAAA,MAC5B,aAAW,WAAW;AAAA,MACtB,gBAAc,UAAU,KAAK;AAAA,MAC7B,gBAAc,WAAW;AAAA,MACzB,UAAU,UAAU,SAAY,YAAY;AAAA,MAC5C,iBAAe,YAAY,YAAY,WAAW,OAAO;AAAA,MACzD,WAAW,eAAe,EAAE,SAAS,MAAM,OAAO,UAAU,CAAC;AAAA,MAC5D,GAAG;AAAA;AAAA,EACN;AAEJ;AASO,SAAS,WAAW,EAAE,OAAO,OAAO,QAAQ,GAAG,MAAM,GAAoB;AAC9E,SAAO,oBAAC,UAAO,cAAY,OAAO,OAAO,OAAO,MAAa,GAAG,OAAO;AACzE;","names":[]}
package/dist/cn.d.ts CHANGED
@@ -4,6 +4,9 @@ export { ClassValue } from 'clsx';
4
4
  /**
5
5
  * Merges Tailwind classes: the last one wins — a product's `className` overrides the primitive's. The merge engine is
6
6
  * tailwind-merge as tailwind-variants ships it (the one `tv` uses), so the platform carries a single copy of it.
7
+ * tailwind-variants bundles that engine since 3.3 (it never imports the `tailwind-merge` package, an optional peer):
8
+ * hence `tailwind-variants ^3.3.1` and no `tailwind-merge` dependency — `scripts/consumer.mjs` checks it on a clean
9
+ * install of the packed package.
7
10
  */
8
11
  declare function cn(...inputs: ClassValue[]): string;
9
12
 
package/dist/cn.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  cn
3
- } from "./chunk-CPMZS4XA.js";
3
+ } from "./chunk-FJDSLNXK.js";
4
4
  export {
5
5
  cn
6
6
  };