@zentauri-ui/zentauri-components 1.7.0 → 1.7.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 (136) hide show
  1. package/README.md +11 -5
  2. package/cli/index.mjs +1 -0
  3. package/cli/registry.json +3 -0
  4. package/dist/chunk-6QQUQLPB.js +107 -0
  5. package/dist/chunk-6QQUQLPB.js.map +1 -0
  6. package/dist/chunk-BC6M42HQ.mjs +251 -0
  7. package/dist/chunk-BC6M42HQ.mjs.map +1 -0
  8. package/dist/chunk-K6IZANTI.mjs +80 -0
  9. package/dist/chunk-K6IZANTI.mjs.map +1 -0
  10. package/dist/chunk-MTTXLC2V.mjs +100 -0
  11. package/dist/chunk-MTTXLC2V.mjs.map +1 -0
  12. package/dist/chunk-PHEUJ4EF.js +84 -0
  13. package/dist/chunk-PHEUJ4EF.js.map +1 -0
  14. package/dist/chunk-QSPXPU72.js +259 -0
  15. package/dist/chunk-QSPXPU72.js.map +1 -0
  16. package/dist/design-system/checkbox.d.ts +32 -0
  17. package/dist/design-system/checkbox.d.ts.map +1 -0
  18. package/dist/design-system/index.d.ts +3 -0
  19. package/dist/design-system/index.d.ts.map +1 -1
  20. package/dist/design-system/popover.d.ts +40 -0
  21. package/dist/design-system/popover.d.ts.map +1 -0
  22. package/dist/design-system/radio-group.d.ts +37 -0
  23. package/dist/design-system/radio-group.d.ts.map +1 -0
  24. package/dist/ui/checkbox/animated/animations.d.ts +32 -0
  25. package/dist/ui/checkbox/animated/animations.d.ts.map +1 -0
  26. package/dist/ui/checkbox/animated/checkbox-animated.d.ts +6 -0
  27. package/dist/ui/checkbox/animated/checkbox-animated.d.ts.map +1 -0
  28. package/dist/ui/checkbox/animated/index.d.ts +4 -0
  29. package/dist/ui/checkbox/animated/index.d.ts.map +1 -0
  30. package/dist/ui/checkbox/animated/types.d.ts +8 -0
  31. package/dist/ui/checkbox/animated/types.d.ts.map +1 -0
  32. package/dist/ui/checkbox/animated.js +153 -0
  33. package/dist/ui/checkbox/animated.js.map +1 -0
  34. package/dist/ui/checkbox/animated.mjs +150 -0
  35. package/dist/ui/checkbox/animated.mjs.map +1 -0
  36. package/dist/ui/checkbox/checkbox-base.d.ts +6 -0
  37. package/dist/ui/checkbox/checkbox-base.d.ts.map +1 -0
  38. package/dist/ui/checkbox/checkbox.d.ts +6 -0
  39. package/dist/ui/checkbox/checkbox.d.ts.map +1 -0
  40. package/dist/ui/checkbox/index.d.ts +4 -0
  41. package/dist/ui/checkbox/index.d.ts.map +1 -0
  42. package/dist/ui/checkbox/types.d.ts +19 -0
  43. package/dist/ui/checkbox/types.d.ts.map +1 -0
  44. package/dist/ui/checkbox/variants.d.ts +11 -0
  45. package/dist/ui/checkbox/variants.d.ts.map +1 -0
  46. package/dist/ui/checkbox.js +150 -0
  47. package/dist/ui/checkbox.js.map +1 -0
  48. package/dist/ui/checkbox.mjs +137 -0
  49. package/dist/ui/checkbox.mjs.map +1 -0
  50. package/dist/ui/popover/animated/animations.d.ts +3 -0
  51. package/dist/ui/popover/animated/animations.d.ts.map +1 -0
  52. package/dist/ui/popover/animated/index.d.ts +4 -0
  53. package/dist/ui/popover/animated/index.d.ts.map +1 -0
  54. package/dist/ui/popover/animated/popover-content-animated.d.ts +3 -0
  55. package/dist/ui/popover/animated/popover-content-animated.d.ts.map +1 -0
  56. package/dist/ui/popover/animated/types.d.ts +9 -0
  57. package/dist/ui/popover/animated/types.d.ts.map +1 -0
  58. package/dist/ui/popover/animated.js +67 -0
  59. package/dist/ui/popover/animated.js.map +1 -0
  60. package/dist/ui/popover/animated.mjs +64 -0
  61. package/dist/ui/popover/animated.mjs.map +1 -0
  62. package/dist/ui/popover/index.d.ts +4 -0
  63. package/dist/ui/popover/index.d.ts.map +1 -0
  64. package/dist/ui/popover/popover-base.d.ts +8 -0
  65. package/dist/ui/popover/popover-base.d.ts.map +1 -0
  66. package/dist/ui/popover/popover.d.ts +2 -0
  67. package/dist/ui/popover/popover.d.ts.map +1 -0
  68. package/dist/ui/popover/types.d.ts +34 -0
  69. package/dist/ui/popover/types.d.ts.map +1 -0
  70. package/dist/ui/popover/variants.d.ts +6 -0
  71. package/dist/ui/popover/variants.d.ts.map +1 -0
  72. package/dist/ui/popover.js +34 -0
  73. package/dist/ui/popover.js.map +1 -0
  74. package/dist/ui/popover.mjs +5 -0
  75. package/dist/ui/popover.mjs.map +1 -0
  76. package/dist/ui/radio-group/animated/animations.d.ts +32 -0
  77. package/dist/ui/radio-group/animated/animations.d.ts.map +1 -0
  78. package/dist/ui/radio-group/animated/index.d.ts +4 -0
  79. package/dist/ui/radio-group/animated/index.d.ts.map +1 -0
  80. package/dist/ui/radio-group/animated/radio-group-animated.d.ts +10 -0
  81. package/dist/ui/radio-group/animated/radio-group-animated.d.ts.map +1 -0
  82. package/dist/ui/radio-group/animated/types.d.ts +11 -0
  83. package/dist/ui/radio-group/animated/types.d.ts.map +1 -0
  84. package/dist/ui/radio-group/animated.js +177 -0
  85. package/dist/ui/radio-group/animated.js.map +1 -0
  86. package/dist/ui/radio-group/animated.mjs +173 -0
  87. package/dist/ui/radio-group/animated.mjs.map +1 -0
  88. package/dist/ui/radio-group/index.d.ts +4 -0
  89. package/dist/ui/radio-group/index.d.ts.map +1 -0
  90. package/dist/ui/radio-group/radio-group-context.d.ts +13 -0
  91. package/dist/ui/radio-group/radio-group-context.d.ts.map +1 -0
  92. package/dist/ui/radio-group/radio-group.d.ts +10 -0
  93. package/dist/ui/radio-group/radio-group.d.ts.map +1 -0
  94. package/dist/ui/radio-group/types.d.ts +26 -0
  95. package/dist/ui/radio-group/types.d.ts.map +1 -0
  96. package/dist/ui/radio-group/variants.d.ts +14 -0
  97. package/dist/ui/radio-group/variants.d.ts.map +1 -0
  98. package/dist/ui/radio-group.js +171 -0
  99. package/dist/ui/radio-group.js.map +1 -0
  100. package/dist/ui/radio-group.mjs +153 -0
  101. package/dist/ui/radio-group.mjs.map +1 -0
  102. package/package.json +1 -1
  103. package/src/design-system/checkbox.ts +47 -0
  104. package/src/design-system/index.ts +3 -0
  105. package/src/design-system/popover.ts +66 -0
  106. package/src/design-system/radio-group.ts +54 -0
  107. package/src/ui/checkbox/animated/animations.ts +12 -0
  108. package/src/ui/checkbox/animated/checkbox-animated.tsx +145 -0
  109. package/src/ui/checkbox/animated/index.ts +9 -0
  110. package/src/ui/checkbox/animated/types.ts +9 -0
  111. package/src/ui/checkbox/checkbox-base.tsx +134 -0
  112. package/src/ui/checkbox/checkbox.test.tsx +53 -0
  113. package/src/ui/checkbox/checkbox.tsx +8 -0
  114. package/src/ui/checkbox/index.ts +15 -0
  115. package/src/ui/checkbox/types.ts +40 -0
  116. package/src/ui/checkbox/variants.ts +50 -0
  117. package/src/ui/popover/animated/animations.ts +15 -0
  118. package/src/ui/popover/animated/index.ts +10 -0
  119. package/src/ui/popover/animated/popover-content-animated.tsx +54 -0
  120. package/src/ui/popover/animated/types.ts +18 -0
  121. package/src/ui/popover/index.ts +18 -0
  122. package/src/ui/popover/popover-base.tsx +261 -0
  123. package/src/ui/popover/popover.test.tsx +84 -0
  124. package/src/ui/popover/popover.tsx +8 -0
  125. package/src/ui/popover/types.ts +38 -0
  126. package/src/ui/popover/variants.ts +21 -0
  127. package/src/ui/radio-group/animated/animations.ts +12 -0
  128. package/src/ui/radio-group/animated/index.ts +10 -0
  129. package/src/ui/radio-group/animated/radio-group-animated.tsx +173 -0
  130. package/src/ui/radio-group/animated/types.ts +13 -0
  131. package/src/ui/radio-group/index.ts +19 -0
  132. package/src/ui/radio-group/radio-group-context.ts +23 -0
  133. package/src/ui/radio-group/radio-group.test.tsx +61 -0
  134. package/src/ui/radio-group/radio-group.tsx +159 -0
  135. package/src/ui/radio-group/types.ts +62 -0
  136. package/src/ui/radio-group/variants.ts +61 -0
@@ -0,0 +1,61 @@
1
+ import { createRef } from "react";
2
+ import { render, screen } from "@testing-library/react";
3
+ import userEvent from "@testing-library/user-event";
4
+ import { describe, expect, it, vi } from "vitest";
5
+
6
+ import { RadioGroup, RadioGroupItem } from "./radio-group";
7
+
8
+ describe("RadioGroup", () => {
9
+ it("should expose displayName", () => {
10
+ expect(RadioGroup.displayName).toBe("RadioGroup");
11
+ expect(RadioGroupItem.displayName).toBe("RadioGroupItem");
12
+ });
13
+
14
+ it("should stamp data-slot", () => {
15
+ render(
16
+ <RadioGroup defaultValue="a" aria-label="Plans">
17
+ <RadioGroupItem value="a">A</RadioGroupItem>
18
+ </RadioGroup>,
19
+ );
20
+ expect(document.querySelector('[data-slot="radio-group"]')).toBeTruthy();
21
+ expect(document.querySelector('[data-slot="radio-group-item"]')).toBeTruthy();
22
+ });
23
+
24
+ it("should select one value at a time", async () => {
25
+ const user = userEvent.setup();
26
+ const onValueChange = vi.fn();
27
+ render(
28
+ <RadioGroup defaultValue="starter" onValueChange={onValueChange}>
29
+ <RadioGroupItem value="starter">Starter</RadioGroupItem>
30
+ <RadioGroupItem value="pro">Pro</RadioGroupItem>
31
+ </RadioGroup>,
32
+ );
33
+
34
+ await user.click(screen.getByRole("radio", { name: "Pro" }));
35
+
36
+ expect(onValueChange).toHaveBeenLastCalledWith("pro");
37
+ expect(screen.getByRole("radio", { name: "Starter" })).not.toBeChecked();
38
+ expect(screen.getByRole("radio", { name: "Pro" })).toBeChecked();
39
+ });
40
+
41
+ it("should support controlled value", () => {
42
+ render(
43
+ <RadioGroup value="pro">
44
+ <RadioGroupItem value="starter">Starter</RadioGroupItem>
45
+ <RadioGroupItem value="pro">Pro</RadioGroupItem>
46
+ </RadioGroup>,
47
+ );
48
+
49
+ expect(screen.getByRole("radio", { name: "Pro" })).toBeChecked();
50
+ });
51
+
52
+ it("should forward ref to the root", () => {
53
+ const ref = createRef<HTMLDivElement>();
54
+ render(
55
+ <RadioGroup ref={ref} defaultValue="a">
56
+ <RadioGroupItem value="a">A</RadioGroupItem>
57
+ </RadioGroup>,
58
+ );
59
+ expect(ref.current?.getAttribute("data-slot")).toBe("radio-group");
60
+ });
61
+ });
@@ -0,0 +1,159 @@
1
+ "use client";
2
+
3
+ import { useCallback, useId, useState } from "react";
4
+
5
+ import { cn } from "../../lib/utils";
6
+
7
+ import {
8
+ RadioGroupContext,
9
+ useRadioGroupContext,
10
+ } from "./radio-group-context";
11
+ import type { RadioGroupItemProps, RadioGroupProps } from "./types";
12
+ import {
13
+ radioGroupControlVariants,
14
+ radioGroupIndicatorVariants,
15
+ radioGroupItemVariants,
16
+ radioGroupRootVariants,
17
+ } from "./variants";
18
+
19
+ export function RadioGroup(props: RadioGroupProps) {
20
+ const {
21
+ className,
22
+ value,
23
+ defaultValue,
24
+ name,
25
+ disabled,
26
+ required,
27
+ onValueChange,
28
+ orientation,
29
+ appearance,
30
+ size,
31
+ children,
32
+ ref,
33
+ ...rest
34
+ } = props;
35
+ const generatedName = useId();
36
+ const isControlled = value !== undefined;
37
+ const [uncontrolled, setUncontrolled] = useState(defaultValue);
38
+ const resolvedValue = isControlled ? value : uncontrolled;
39
+
40
+ const setValue = useCallback(
41
+ (next: string) => {
42
+ if (!isControlled) {
43
+ setUncontrolled(next);
44
+ }
45
+ onValueChange?.(next);
46
+ },
47
+ [isControlled, onValueChange],
48
+ );
49
+
50
+ return (
51
+ <RadioGroupContext.Provider
52
+ value={{
53
+ value: resolvedValue,
54
+ name: name ?? generatedName,
55
+ disabled,
56
+ required,
57
+ appearance: appearance ?? undefined,
58
+ size: size ?? undefined,
59
+ onValueChange: setValue,
60
+ }}
61
+ >
62
+ <div
63
+ ref={ref}
64
+ role="radiogroup"
65
+ data-slot="radio-group"
66
+ data-orientation={orientation ?? "vertical"}
67
+ className={cn(radioGroupRootVariants({ orientation }), className)}
68
+ {...rest}
69
+ >
70
+ {children}
71
+ </div>
72
+ </RadioGroupContext.Provider>
73
+ );
74
+ }
75
+
76
+ RadioGroup.displayName = "RadioGroup";
77
+
78
+ export function RadioGroupItem(props: RadioGroupItemProps) {
79
+ const {
80
+ className,
81
+ rootClassName,
82
+ controlClassName,
83
+ indicatorClassName,
84
+ value,
85
+ appearance: appearanceProp,
86
+ size: sizeProp,
87
+ disabled: disabledProp,
88
+ required: requiredProp,
89
+ children,
90
+ label,
91
+ id,
92
+ ref,
93
+ "aria-label": ariaLabel,
94
+ ...rest
95
+ } = props;
96
+ const generatedId = useId();
97
+ const context = useRadioGroupContext();
98
+ const controlId = id ?? generatedId;
99
+ const checked = context?.value === value;
100
+ const disabled = disabledProp ?? context?.disabled;
101
+ const required = requiredProp ?? context?.required;
102
+ const appearance = appearanceProp ?? context?.appearance;
103
+ const size = sizeProp ?? context?.size;
104
+ const labelContent = label ?? children;
105
+ const hasVisibleLabel =
106
+ labelContent !== undefined && labelContent !== null && labelContent !== false;
107
+
108
+ return (
109
+ <label
110
+ className={cn(radioGroupItemVariants({ size }), rootClassName, className)}
111
+ data-disabled={disabled ? "true" : undefined}
112
+ data-state={checked ? "checked" : "unchecked"}
113
+ htmlFor={controlId}
114
+ >
115
+ <input
116
+ ref={ref}
117
+ id={controlId}
118
+ type="radio"
119
+ data-slot="radio-group-item"
120
+ className="peer sr-only"
121
+ name={context?.name}
122
+ value={value}
123
+ checked={checked}
124
+ disabled={disabled}
125
+ required={required}
126
+ aria-label={ariaLabel ?? (hasVisibleLabel ? undefined : value)}
127
+ onChange={(event) => {
128
+ if (event.currentTarget.checked) {
129
+ context?.onValueChange(value);
130
+ }
131
+ }}
132
+ {...rest}
133
+ />
134
+ <span
135
+ aria-hidden="true"
136
+ className={cn(
137
+ radioGroupControlVariants({ appearance, size }),
138
+ controlClassName,
139
+ )}
140
+ data-slot="radio-group-control"
141
+ >
142
+ <span
143
+ className={cn(
144
+ radioGroupIndicatorVariants({ size }),
145
+ indicatorClassName,
146
+ )}
147
+ data-slot="radio-group-indicator"
148
+ />
149
+ </span>
150
+ {hasVisibleLabel && (
151
+ <span className="min-w-0 leading-6" data-slot="radio-group-label">
152
+ {labelContent}
153
+ </span>
154
+ )}
155
+ </label>
156
+ );
157
+ }
158
+
159
+ RadioGroupItem.displayName = "RadioGroupItem";
@@ -0,0 +1,62 @@
1
+ import type { VariantProps } from "class-variance-authority";
2
+ import type { ComponentPropsWithRef, ReactNode } from "react";
3
+
4
+ import type {
5
+ radioGroupControlVariants,
6
+ radioGroupIndicatorVariants,
7
+ radioGroupItemVariants,
8
+ radioGroupRootVariants,
9
+ } from "./variants";
10
+
11
+ export type RadioGroupRootVariantProps = VariantProps<
12
+ typeof radioGroupRootVariants
13
+ >;
14
+ export type RadioGroupItemVariantProps = VariantProps<
15
+ typeof radioGroupItemVariants
16
+ >;
17
+ export type RadioGroupControlVariantProps = VariantProps<
18
+ typeof radioGroupControlVariants
19
+ >;
20
+ export type RadioGroupIndicatorVariantProps = VariantProps<
21
+ typeof radioGroupIndicatorVariants
22
+ >;
23
+
24
+ export type RadioGroupAppearance = NonNullable<
25
+ RadioGroupControlVariantProps["appearance"]
26
+ >;
27
+ export type RadioGroupSize = NonNullable<RadioGroupItemVariantProps["size"]>;
28
+
29
+ export type RadioGroupProps = RadioGroupRootVariantProps &
30
+ Pick<RadioGroupControlVariantProps, "appearance"> &
31
+ RadioGroupItemVariantProps &
32
+ Omit<
33
+ ComponentPropsWithRef<"div">,
34
+ "defaultValue" | "dir" | "onChange" | "role"
35
+ > & {
36
+ value?: string;
37
+ defaultValue?: string;
38
+ name?: string;
39
+ disabled?: boolean;
40
+ required?: boolean;
41
+ onValueChange?: (value: string) => void;
42
+ };
43
+
44
+ export type RadioGroupItemProps = RadioGroupItemVariantProps &
45
+ RadioGroupControlVariantProps &
46
+ Omit<
47
+ ComponentPropsWithRef<"input">,
48
+ | "type"
49
+ | "size"
50
+ | "name"
51
+ | "checked"
52
+ | "defaultChecked"
53
+ | "onChange"
54
+ | "children"
55
+ > & {
56
+ value: string;
57
+ label?: ReactNode;
58
+ children?: ReactNode;
59
+ rootClassName?: string;
60
+ controlClassName?: string;
61
+ indicatorClassName?: string;
62
+ };
@@ -0,0 +1,61 @@
1
+ import { cva } from "class-variance-authority";
2
+
3
+ import {
4
+ zuiRadioGroupAppearances,
5
+ zuiRadioGroupControlBase,
6
+ zuiRadioGroupIndicatorBase,
7
+ zuiRadioGroupItemBase,
8
+ zuiRadioGroupOrientations,
9
+ zuiRadioGroupRootBase,
10
+ zuiRadioGroupSizes,
11
+ } from "../../design-system/radio-group";
12
+
13
+ export const radioGroupRootVariants = cva(zuiRadioGroupRootBase, {
14
+ variants: {
15
+ orientation: zuiRadioGroupOrientations,
16
+ },
17
+ defaultVariants: {
18
+ orientation: "vertical",
19
+ },
20
+ });
21
+
22
+ export const radioGroupItemVariants = cva(zuiRadioGroupItemBase, {
23
+ variants: {
24
+ size: {
25
+ sm: zuiRadioGroupSizes.sm.item,
26
+ md: zuiRadioGroupSizes.md.item,
27
+ lg: zuiRadioGroupSizes.lg.item,
28
+ },
29
+ },
30
+ defaultVariants: {
31
+ size: "md",
32
+ },
33
+ });
34
+
35
+ export const radioGroupControlVariants = cva(zuiRadioGroupControlBase, {
36
+ variants: {
37
+ appearance: zuiRadioGroupAppearances,
38
+ size: {
39
+ sm: zuiRadioGroupSizes.sm.control,
40
+ md: zuiRadioGroupSizes.md.control,
41
+ lg: zuiRadioGroupSizes.lg.control,
42
+ },
43
+ },
44
+ defaultVariants: {
45
+ appearance: "default",
46
+ size: "md",
47
+ },
48
+ });
49
+
50
+ export const radioGroupIndicatorVariants = cva(zuiRadioGroupIndicatorBase, {
51
+ variants: {
52
+ size: {
53
+ sm: zuiRadioGroupSizes.sm.indicator,
54
+ md: zuiRadioGroupSizes.md.indicator,
55
+ lg: zuiRadioGroupSizes.lg.indicator,
56
+ },
57
+ },
58
+ defaultVariants: {
59
+ size: "md",
60
+ },
61
+ });