@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,145 @@
1
+ "use client";
2
+
3
+ import { motion } from "framer-motion";
4
+ import { useCallback, useId, useState } from "react";
5
+
6
+ import { cn } from "../../../lib/utils";
7
+
8
+ import { checkboxAnimationPresets } from "./animations";
9
+ import type { CheckboxAnimatedProps } from "./types";
10
+ import type { CheckboxState } from "../types";
11
+ import {
12
+ checkboxControlVariants,
13
+ checkboxIndicatorVariants,
14
+ checkboxRootVariants,
15
+ } from "../variants";
16
+
17
+ function resolveCheckboxState(
18
+ checked: boolean,
19
+ indeterminate: boolean | undefined,
20
+ ): CheckboxState {
21
+ if (indeterminate) {
22
+ return "indeterminate";
23
+ }
24
+ return checked ? "checked" : "unchecked";
25
+ }
26
+
27
+ export function CheckboxAnimated(props: CheckboxAnimatedProps) {
28
+ const {
29
+ className,
30
+ rootClassName,
31
+ controlClassName,
32
+ indicatorClassName,
33
+ appearance,
34
+ size,
35
+ checked,
36
+ defaultChecked = false,
37
+ indeterminate,
38
+ onCheckedChange,
39
+ disabled,
40
+ children,
41
+ label,
42
+ id,
43
+ ref,
44
+ "aria-label": ariaLabel,
45
+ animation = "draw",
46
+ ...rest
47
+ } = props;
48
+ const generatedId = useId();
49
+ const controlId = id ?? generatedId;
50
+ const isControlled = checked !== undefined;
51
+ const [uncontrolled, setUncontrolled] = useState(defaultChecked);
52
+ const resolvedChecked = isControlled ? Boolean(checked) : uncontrolled;
53
+ const state = resolveCheckboxState(resolvedChecked, indeterminate);
54
+ const labelContent = label ?? children;
55
+ const hasVisibleLabel =
56
+ labelContent !== undefined && labelContent !== null && labelContent !== false;
57
+ const motionPreset = checkboxAnimationPresets[animation];
58
+ const svgMotionProps = animation === "spring" ? motionPreset : undefined;
59
+ const pathMotionProps = animation === "draw" ? motionPreset : undefined;
60
+
61
+ const setChecked = useCallback(
62
+ (next: boolean) => {
63
+ if (!isControlled) {
64
+ setUncontrolled(next);
65
+ }
66
+ onCheckedChange?.(next);
67
+ },
68
+ [isControlled, onCheckedChange],
69
+ );
70
+
71
+ return (
72
+ <label
73
+ className={cn(checkboxRootVariants({ size }), rootClassName, className)}
74
+ data-disabled={disabled ? "true" : undefined}
75
+ data-state={state}
76
+ htmlFor={controlId}
77
+ >
78
+ <input
79
+ ref={ref}
80
+ id={controlId}
81
+ type="checkbox"
82
+ data-slot="checkbox"
83
+ className="peer sr-only"
84
+ checked={resolvedChecked}
85
+ disabled={disabled}
86
+ aria-checked={indeterminate ? "mixed" : resolvedChecked}
87
+ aria-label={ariaLabel ?? (hasVisibleLabel ? undefined : "Checkbox")}
88
+ onChange={(event) => setChecked(event.currentTarget.checked)}
89
+ {...rest}
90
+ />
91
+ <span
92
+ aria-hidden="true"
93
+ className={cn(
94
+ checkboxControlVariants({ appearance, size }),
95
+ controlClassName,
96
+ )}
97
+ data-slot="checkbox-control"
98
+ >
99
+ {state !== "unchecked" && (
100
+ <motion.svg
101
+ key={state}
102
+ viewBox="0 0 16 16"
103
+ fill="none"
104
+ className={cn(
105
+ checkboxIndicatorVariants({ size }),
106
+ "opacity-100",
107
+ indicatorClassName,
108
+ )}
109
+ initial={svgMotionProps?.initial}
110
+ animate={svgMotionProps?.animate}
111
+ transition={svgMotionProps?.transition}
112
+ >
113
+ {state === "indeterminate" ? (
114
+ <motion.path
115
+ d="M3.5 8H12.5"
116
+ strokeWidth="2.4"
117
+ strokeLinecap="round"
118
+ initial={pathMotionProps?.initial}
119
+ animate={pathMotionProps?.animate}
120
+ transition={pathMotionProps?.transition}
121
+ />
122
+ ) : (
123
+ <motion.path
124
+ d="M3.2 8.4L6.5 11.5L12.8 4.5"
125
+ strokeWidth="2.2"
126
+ strokeLinecap="round"
127
+ strokeLinejoin="round"
128
+ initial={pathMotionProps?.initial}
129
+ animate={pathMotionProps?.animate}
130
+ transition={pathMotionProps?.transition}
131
+ />
132
+ )}
133
+ </motion.svg>
134
+ )}
135
+ </span>
136
+ {hasVisibleLabel && (
137
+ <span className="min-w-0 leading-6" data-slot="checkbox-label">
138
+ {labelContent}
139
+ </span>
140
+ )}
141
+ </label>
142
+ );
143
+ }
144
+
145
+ CheckboxAnimated.displayName = "Checkbox";
@@ -0,0 +1,9 @@
1
+ "use client";
2
+
3
+ export { CheckboxAnimated } from "./checkbox-animated";
4
+ export type {
5
+ CheckboxAnimatedProps,
6
+ CheckboxAnimation,
7
+ CheckboxAnimationPresets,
8
+ } from "./types";
9
+ export { checkboxAnimationPresets } from "./animations";
@@ -0,0 +1,9 @@
1
+ import type { CheckboxProps } from "../types";
2
+ import type { checkboxAnimationPresets } from "./animations";
3
+
4
+ export type CheckboxAnimation = keyof typeof checkboxAnimationPresets;
5
+ export type CheckboxAnimationPresets = typeof checkboxAnimationPresets;
6
+
7
+ export type CheckboxAnimatedProps = CheckboxProps & {
8
+ animation?: CheckboxAnimation;
9
+ };
@@ -0,0 +1,134 @@
1
+ "use client";
2
+
3
+ import { useCallback, useId, useState } from "react";
4
+
5
+ import { cn } from "../../lib/utils";
6
+
7
+ import type { CheckboxProps, CheckboxState } from "./types";
8
+ import {
9
+ checkboxControlVariants,
10
+ checkboxIndicatorVariants,
11
+ checkboxRootVariants,
12
+ } from "./variants";
13
+
14
+ function resolveCheckboxState(
15
+ checked: boolean,
16
+ indeterminate: boolean | undefined,
17
+ ): CheckboxState {
18
+ if (indeterminate) {
19
+ return "indeterminate";
20
+ }
21
+ return checked ? "checked" : "unchecked";
22
+ }
23
+
24
+ export function CheckboxBase(props: CheckboxProps) {
25
+ const {
26
+ className,
27
+ rootClassName,
28
+ controlClassName,
29
+ indicatorClassName,
30
+ appearance,
31
+ size,
32
+ checked,
33
+ defaultChecked = false,
34
+ indeterminate,
35
+ onCheckedChange,
36
+ disabled,
37
+ children,
38
+ label,
39
+ id,
40
+ ref,
41
+ "aria-label": ariaLabel,
42
+ ...rest
43
+ } = props;
44
+ const generatedId = useId();
45
+ const controlId = id ?? generatedId;
46
+ const isControlled = checked !== undefined;
47
+ const [uncontrolled, setUncontrolled] = useState(defaultChecked);
48
+ const resolvedChecked = isControlled ? Boolean(checked) : uncontrolled;
49
+ const state = resolveCheckboxState(resolvedChecked, indeterminate);
50
+ const labelContent = label ?? children;
51
+ const hasVisibleLabel =
52
+ labelContent !== undefined && labelContent !== null && labelContent !== false;
53
+
54
+ const setChecked = useCallback(
55
+ (next: boolean) => {
56
+ if (!isControlled) {
57
+ setUncontrolled(next);
58
+ }
59
+ onCheckedChange?.(next);
60
+ },
61
+ [isControlled, onCheckedChange],
62
+ );
63
+
64
+ return (
65
+ <label
66
+ className={cn(checkboxRootVariants({ size }), rootClassName, className)}
67
+ data-disabled={disabled ? "true" : undefined}
68
+ data-state={state}
69
+ htmlFor={controlId}
70
+ >
71
+ <input
72
+ ref={ref}
73
+ id={controlId}
74
+ type="checkbox"
75
+ data-slot="checkbox"
76
+ className="peer sr-only"
77
+ checked={resolvedChecked}
78
+ disabled={disabled}
79
+ aria-checked={indeterminate ? "mixed" : resolvedChecked}
80
+ aria-label={ariaLabel ?? (hasVisibleLabel ? undefined : "Checkbox")}
81
+ onChange={(event) => setChecked(event.currentTarget.checked)}
82
+ {...rest}
83
+ />
84
+ <span
85
+ aria-hidden="true"
86
+ className={cn(
87
+ checkboxControlVariants({ appearance, size }),
88
+ controlClassName,
89
+ )}
90
+ data-slot="checkbox-control"
91
+ >
92
+ {state === "indeterminate" ? (
93
+ <svg
94
+ viewBox="0 0 16 16"
95
+ fill="none"
96
+ className={cn(
97
+ checkboxIndicatorVariants({ size }),
98
+ indicatorClassName,
99
+ )}
100
+ >
101
+ <path
102
+ d="M3.5 8H12.5"
103
+ strokeWidth="2.4"
104
+ strokeLinecap="round"
105
+ />
106
+ </svg>
107
+ ) : (
108
+ <svg
109
+ viewBox="0 0 16 16"
110
+ fill="none"
111
+ className={cn(
112
+ checkboxIndicatorVariants({ size }),
113
+ indicatorClassName,
114
+ )}
115
+ >
116
+ <path
117
+ d="M3.2 8.4L6.5 11.5L12.8 4.5"
118
+ strokeWidth="2.2"
119
+ strokeLinecap="round"
120
+ strokeLinejoin="round"
121
+ />
122
+ </svg>
123
+ )}
124
+ </span>
125
+ {hasVisibleLabel && (
126
+ <span className="min-w-0 leading-6" data-slot="checkbox-label">
127
+ {labelContent}
128
+ </span>
129
+ )}
130
+ </label>
131
+ );
132
+ }
133
+
134
+ CheckboxBase.displayName = "Checkbox";
@@ -0,0 +1,53 @@
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 { Checkbox } from "./checkbox";
7
+
8
+ describe("Checkbox", () => {
9
+ it("should expose displayName", () => {
10
+ expect(Checkbox.displayName).toBe("Checkbox");
11
+ });
12
+
13
+ it("should stamp data-slot", () => {
14
+ render(<Checkbox aria-label="Accept" />);
15
+ expect(document.querySelector('[data-slot="checkbox"]')).toBeTruthy();
16
+ });
17
+
18
+ it("should use accessible label content", () => {
19
+ render(<Checkbox>Accept terms</Checkbox>);
20
+ expect(
21
+ screen.getByRole("checkbox", { name: "Accept terms" }),
22
+ ).toBeInTheDocument();
23
+ });
24
+
25
+ it("should call onCheckedChange when toggled", async () => {
26
+ const user = userEvent.setup();
27
+ const onCheckedChange = vi.fn();
28
+ render(
29
+ <Checkbox defaultChecked={false} onCheckedChange={onCheckedChange}>
30
+ Marketing emails
31
+ </Checkbox>,
32
+ );
33
+
34
+ await user.click(screen.getByRole("checkbox", { name: "Marketing emails" }));
35
+ expect(onCheckedChange).toHaveBeenLastCalledWith(true);
36
+ });
37
+
38
+ it("should expose mixed state when indeterminate", () => {
39
+ render(
40
+ <Checkbox indeterminate aria-label="Select partial group" />,
41
+ );
42
+ expect(screen.getByRole("checkbox")).toHaveAttribute(
43
+ "aria-checked",
44
+ "mixed",
45
+ );
46
+ });
47
+
48
+ it("should forward ref to the input", () => {
49
+ const ref = createRef<HTMLInputElement>();
50
+ render(<Checkbox ref={ref} aria-label="Remember me" />);
51
+ expect(ref.current?.getAttribute("data-slot")).toBe("checkbox");
52
+ });
53
+ });
@@ -0,0 +1,8 @@
1
+ import { CheckboxBase } from "./checkbox-base";
2
+ import type { CheckboxProps } from "./types";
3
+
4
+ export function Checkbox(props: CheckboxProps) {
5
+ return <CheckboxBase {...props} />;
6
+ }
7
+
8
+ Checkbox.displayName = "Checkbox";
@@ -0,0 +1,15 @@
1
+ "use client";
2
+
3
+ export { Checkbox } from "./checkbox";
4
+ export type {
5
+ CheckboxControlVariantProps,
6
+ CheckboxIndicatorVariantProps,
7
+ CheckboxProps,
8
+ CheckboxRootVariantProps,
9
+ CheckboxState,
10
+ } from "./types";
11
+ export {
12
+ checkboxControlVariants,
13
+ checkboxIndicatorVariants,
14
+ checkboxRootVariants,
15
+ } from "./variants";
@@ -0,0 +1,40 @@
1
+ import type { VariantProps } from "class-variance-authority";
2
+ import type { ComponentPropsWithRef, ReactNode } from "react";
3
+
4
+ import type {
5
+ checkboxControlVariants,
6
+ checkboxIndicatorVariants,
7
+ checkboxRootVariants,
8
+ } from "./variants";
9
+
10
+ export type CheckboxState = "checked" | "unchecked" | "indeterminate";
11
+
12
+ export type CheckboxRootVariantProps = VariantProps<typeof checkboxRootVariants>;
13
+ export type CheckboxControlVariantProps = VariantProps<
14
+ typeof checkboxControlVariants
15
+ >;
16
+ export type CheckboxIndicatorVariantProps = VariantProps<
17
+ typeof checkboxIndicatorVariants
18
+ >;
19
+
20
+ export type CheckboxProps = CheckboxRootVariantProps &
21
+ CheckboxControlVariantProps &
22
+ Omit<
23
+ ComponentPropsWithRef<"input">,
24
+ | "type"
25
+ | "size"
26
+ | "checked"
27
+ | "defaultChecked"
28
+ | "onChange"
29
+ | "children"
30
+ > & {
31
+ checked?: boolean;
32
+ defaultChecked?: boolean;
33
+ indeterminate?: boolean;
34
+ onCheckedChange?: (checked: boolean) => void;
35
+ children?: ReactNode;
36
+ label?: ReactNode;
37
+ rootClassName?: string;
38
+ controlClassName?: string;
39
+ indicatorClassName?: string;
40
+ };
@@ -0,0 +1,50 @@
1
+ import { cva } from "class-variance-authority";
2
+
3
+ import {
4
+ zuiCheckboxAppearances,
5
+ zuiCheckboxControlBase,
6
+ zuiCheckboxIndicatorBase,
7
+ zuiCheckboxRootBase,
8
+ zuiCheckboxSizes,
9
+ } from "../../design-system/checkbox";
10
+
11
+ export const checkboxRootVariants = cva(zuiCheckboxRootBase, {
12
+ variants: {
13
+ size: {
14
+ sm: zuiCheckboxSizes.sm.root,
15
+ md: zuiCheckboxSizes.md.root,
16
+ lg: zuiCheckboxSizes.lg.root,
17
+ },
18
+ },
19
+ defaultVariants: {
20
+ size: "md",
21
+ },
22
+ });
23
+
24
+ export const checkboxControlVariants = cva(zuiCheckboxControlBase, {
25
+ variants: {
26
+ appearance: zuiCheckboxAppearances,
27
+ size: {
28
+ sm: zuiCheckboxSizes.sm.control,
29
+ md: zuiCheckboxSizes.md.control,
30
+ lg: zuiCheckboxSizes.lg.control,
31
+ },
32
+ },
33
+ defaultVariants: {
34
+ appearance: "default",
35
+ size: "md",
36
+ },
37
+ });
38
+
39
+ export const checkboxIndicatorVariants = cva(zuiCheckboxIndicatorBase, {
40
+ variants: {
41
+ size: {
42
+ sm: zuiCheckboxSizes.sm.indicator,
43
+ md: zuiCheckboxSizes.md.indicator,
44
+ lg: zuiCheckboxSizes.lg.indicator,
45
+ },
46
+ },
47
+ defaultVariants: {
48
+ size: "md",
49
+ },
50
+ });
@@ -0,0 +1,15 @@
1
+ import type { PopoverAnimationPresets } from "./types";
2
+
3
+ export const popoverAnimationPresets: PopoverAnimationPresets = {
4
+ none: {},
5
+ fade: {
6
+ initial: { opacity: 0, y: -4 },
7
+ animate: { opacity: 1, y: 0 },
8
+ transition: { duration: 0.16, ease: "easeOut" },
9
+ },
10
+ scale: {
11
+ initial: { opacity: 0, scale: 0.96 },
12
+ animate: { opacity: 1, scale: 1 },
13
+ transition: { duration: 0.16, ease: "easeOut" },
14
+ },
15
+ };
@@ -0,0 +1,10 @@
1
+ "use client";
2
+
3
+ export { PopoverContentAnimated } from "./popover-content-animated";
4
+ export { popoverAnimationPresets } from "./animations";
5
+ export type {
6
+ PopoverAnimation,
7
+ PopoverAnimationPresets,
8
+ PopoverContentAnimatedProps,
9
+ PopoverPresetMotionProps,
10
+ } from "./types";
@@ -0,0 +1,54 @@
1
+ "use client";
2
+
3
+ import { motion } from "framer-motion";
4
+
5
+ import { cn } from "../../../lib/utils";
6
+
7
+ import { popoverAnimationPresets } from "./animations";
8
+ import type { PopoverContentAnimatedProps } from "./types";
9
+ import { sideAlignClass, usePopover } from "../popover-base";
10
+ import { popoverContentVariants } from "../variants";
11
+
12
+ export const PopoverContentAnimated = ({
13
+ children,
14
+ className,
15
+ variant,
16
+ size,
17
+ width,
18
+ side = "bottom",
19
+ align = "center",
20
+ role = "dialog",
21
+ animation = "none",
22
+ onDrag: _onDrag,
23
+ onDragStart: _onDragStart,
24
+ onDragEnd: _onDragEnd,
25
+ onAnimationStart: _onAnimationStart,
26
+ ...props
27
+ }: PopoverContentAnimatedProps) => {
28
+ const { open, contentId, contentRef } = usePopover();
29
+
30
+ if (!open) {
31
+ return null;
32
+ }
33
+
34
+ const motionProps = popoverAnimationPresets[animation];
35
+
36
+ return (
37
+ <motion.div
38
+ ref={contentRef}
39
+ id={contentId}
40
+ data-open={open}
41
+ role={role}
42
+ tabIndex={-1}
43
+ {...motionProps}
44
+ className={cn(
45
+ popoverContentVariants({ variant, size, width }),
46
+ sideAlignClass(side, align),
47
+ className,
48
+ )}
49
+ {...props}
50
+ >
51
+ {children}
52
+ </motion.div>
53
+ );
54
+ };
@@ -0,0 +1,18 @@
1
+ import type { HTMLMotionProps } from "framer-motion";
2
+ import type { PopoverContentProps } from "../types";
3
+
4
+ export type PopoverAnimation = "none" | "fade" | "scale";
5
+
6
+ export type PopoverPresetMotionProps = Pick<
7
+ HTMLMotionProps<"div">,
8
+ "initial" | "animate" | "style" | "transition"
9
+ >;
10
+
11
+ export type PopoverAnimationPresets = Record<
12
+ PopoverAnimation,
13
+ PopoverPresetMotionProps
14
+ >;
15
+
16
+ export type PopoverContentAnimatedProps = PopoverContentProps & {
17
+ animation?: PopoverAnimation;
18
+ };
@@ -0,0 +1,18 @@
1
+ "use client";
2
+
3
+ export {
4
+ Popover,
5
+ PopoverTrigger,
6
+ PopoverContent,
7
+ PopoverContext,
8
+ usePopover,
9
+ } from "./popover";
10
+ export { popoverContentVariants } from "./variants";
11
+ export type {
12
+ PopoverAlign,
13
+ PopoverContentProps,
14
+ PopoverContextType,
15
+ PopoverProps,
16
+ PopoverSide,
17
+ PopoverTriggerProps,
18
+ } from "./types";