@zentauri-ui/zentauri-components 2.2.1 → 2.2.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 (97) hide show
  1. package/README.md +8 -7
  2. package/cli/props.json +297 -0
  3. package/cli/registry.json +6 -0
  4. package/dist/{chunk-NW5BSLR2.js → chunk-5I4GAURE.js} +6 -6
  5. package/dist/{chunk-NW5BSLR2.js.map → chunk-5I4GAURE.js.map} +1 -1
  6. package/dist/chunk-ATE5SCTR.mjs +39 -0
  7. package/dist/chunk-ATE5SCTR.mjs.map +1 -0
  8. package/dist/chunk-DIAA5VH4.mjs +64 -0
  9. package/dist/chunk-DIAA5VH4.mjs.map +1 -0
  10. package/dist/{chunk-5HLEHSPM.mjs → chunk-GFE6ZX5Y.mjs} +13 -3
  11. package/dist/chunk-GFE6ZX5Y.mjs.map +1 -0
  12. package/dist/chunk-H3BJOK22.js +74 -0
  13. package/dist/chunk-H3BJOK22.js.map +1 -0
  14. package/dist/chunk-ILPPXWR3.js +19 -0
  15. package/dist/{chunk-YBKNXDZU.js.map → chunk-ILPPXWR3.js.map} +1 -1
  16. package/dist/{chunk-DUH2YLH2.js → chunk-IY72Z65Z.js} +12 -12
  17. package/dist/{chunk-DUH2YLH2.js.map → chunk-IY72Z65Z.js.map} +1 -1
  18. package/dist/{chunk-YSQW56JX.mjs → chunk-N2G7IWHS.mjs} +4 -4
  19. package/dist/{chunk-YSQW56JX.mjs.map → chunk-N2G7IWHS.mjs.map} +1 -1
  20. package/dist/{chunk-Z4Y5IPR3.mjs → chunk-NUV2I337.mjs} +3 -3
  21. package/dist/{chunk-Z4Y5IPR3.mjs.map → chunk-NUV2I337.mjs.map} +1 -1
  22. package/dist/chunk-PQ2XTY3M.js +44 -0
  23. package/dist/chunk-PQ2XTY3M.js.map +1 -0
  24. package/dist/{chunk-UJZ7JQBQ.js → chunk-UZ6Y5CSV.js} +13 -3
  25. package/dist/chunk-UZ6Y5CSV.js.map +1 -0
  26. package/dist/{chunk-45ZHGDT2.mjs → chunk-W5MTZJPE.mjs} +3 -3
  27. package/dist/{chunk-45ZHGDT2.mjs.map → chunk-W5MTZJPE.mjs.map} +1 -1
  28. package/dist/design-system/facade.js +4 -3
  29. package/dist/design-system/facade.js.map +1 -1
  30. package/dist/design-system/facade.mjs +3 -2
  31. package/dist/design-system/facade.mjs.map +1 -1
  32. package/dist/design-system/index.d.ts +1 -0
  33. package/dist/design-system/index.d.ts.map +1 -1
  34. package/dist/design-system/secret-reveal.d.ts +57 -0
  35. package/dist/design-system/secret-reveal.d.ts.map +1 -0
  36. package/dist/ui/buttons/animated.js +6 -5
  37. package/dist/ui/buttons/animated.js.map +1 -1
  38. package/dist/ui/buttons/animated.mjs +4 -3
  39. package/dist/ui/buttons/animated.mjs.map +1 -1
  40. package/dist/ui/buttons.js +7 -6
  41. package/dist/ui/buttons.mjs +5 -4
  42. package/dist/ui/data-table.js +16 -15
  43. package/dist/ui/data-table.js.map +1 -1
  44. package/dist/ui/data-table.mjs +6 -5
  45. package/dist/ui/data-table.mjs.map +1 -1
  46. package/dist/ui/dynamic-stepper.js +16 -15
  47. package/dist/ui/dynamic-stepper.js.map +1 -1
  48. package/dist/ui/dynamic-stepper.mjs +5 -4
  49. package/dist/ui/dynamic-stepper.mjs.map +1 -1
  50. package/dist/ui/pagination.js +8 -7
  51. package/dist/ui/pagination.mjs +5 -4
  52. package/dist/ui/secret-reveal/animated/animations.d.ts +8 -0
  53. package/dist/ui/secret-reveal/animated/animations.d.ts.map +1 -0
  54. package/dist/ui/secret-reveal/animated/index.d.ts +4 -0
  55. package/dist/ui/secret-reveal/animated/index.d.ts.map +1 -0
  56. package/dist/ui/secret-reveal/animated/secret-reveal-animated.d.ts +6 -0
  57. package/dist/ui/secret-reveal/animated/secret-reveal-animated.d.ts.map +1 -0
  58. package/dist/ui/secret-reveal/animated/types.d.ts +9 -0
  59. package/dist/ui/secret-reveal/animated/types.d.ts.map +1 -0
  60. package/dist/ui/secret-reveal/animated.js +194 -0
  61. package/dist/ui/secret-reveal/animated.js.map +1 -0
  62. package/dist/ui/secret-reveal/animated.mjs +191 -0
  63. package/dist/ui/secret-reveal/animated.mjs.map +1 -0
  64. package/dist/ui/secret-reveal/index.d.ts +4 -0
  65. package/dist/ui/secret-reveal/index.d.ts.map +1 -0
  66. package/dist/ui/secret-reveal/secret-reveal-base.d.ts +6 -0
  67. package/dist/ui/secret-reveal/secret-reveal-base.d.ts.map +1 -0
  68. package/dist/ui/secret-reveal/secret-reveal.d.ts +2 -0
  69. package/dist/ui/secret-reveal/secret-reveal.d.ts.map +1 -0
  70. package/dist/ui/secret-reveal/types.d.ts +15 -0
  71. package/dist/ui/secret-reveal/types.d.ts.map +1 -0
  72. package/dist/ui/secret-reveal/variants.d.ts +15 -0
  73. package/dist/ui/secret-reveal/variants.d.ts.map +1 -0
  74. package/dist/ui/secret-reveal.js +136 -0
  75. package/dist/ui/secret-reveal.js.map +1 -0
  76. package/dist/ui/secret-reveal.mjs +119 -0
  77. package/dist/ui/secret-reveal.mjs.map +1 -0
  78. package/dist/ui/split-button.js +18 -17
  79. package/dist/ui/split-button.js.map +1 -1
  80. package/dist/ui/split-button.mjs +5 -4
  81. package/dist/ui/split-button.mjs.map +1 -1
  82. package/package.json +1 -1
  83. package/src/design-system/index.ts +1 -0
  84. package/src/design-system/secret-reveal.ts +75 -0
  85. package/src/ui/secret-reveal/animated/animations.ts +74 -0
  86. package/src/ui/secret-reveal/animated/index.ts +5 -0
  87. package/src/ui/secret-reveal/animated/secret-reveal-animated.tsx +132 -0
  88. package/src/ui/secret-reveal/animated/types.ts +11 -0
  89. package/src/ui/secret-reveal/index.ts +14 -0
  90. package/src/ui/secret-reveal/secret-reveal-base.tsx +116 -0
  91. package/src/ui/secret-reveal/secret-reveal.test.tsx +75 -0
  92. package/src/ui/secret-reveal/secret-reveal.tsx +2 -0
  93. package/src/ui/secret-reveal/types.ts +21 -0
  94. package/src/ui/secret-reveal/variants.ts +49 -0
  95. package/dist/chunk-5HLEHSPM.mjs.map +0 -1
  96. package/dist/chunk-UJZ7JQBQ.js.map +0 -1
  97. package/dist/chunk-YBKNXDZU.js +0 -19
@@ -0,0 +1,132 @@
1
+ "use client";
2
+
3
+ import { AnimatePresence, motion } from "framer-motion";
4
+ import { useCallback, useState } from "react";
5
+
6
+ import { cn } from "../../../lib/utils";
7
+
8
+ import { secretRevealAnimationPresets } from "./animations";
9
+ import type { SecretRevealAnimatedProps } from "./types";
10
+ import {
11
+ secretRevealLabelVariants,
12
+ secretRevealToggleVariants,
13
+ secretRevealValueVariants,
14
+ secretRevealVariants,
15
+ } from "../variants";
16
+
17
+ export function SecretRevealAnimated({
18
+ appearance,
19
+ size,
20
+ value,
21
+ children,
22
+ label,
23
+ labelPosition = "top",
24
+ initiallyRevealed = false,
25
+ onVisibilityChange,
26
+ animation = "fade",
27
+ muteChar = "•",
28
+ className,
29
+ ref,
30
+ ...rest
31
+ }: SecretRevealAnimatedProps) {
32
+ const [revealed, setRevealed] = useState(initiallyRevealed);
33
+
34
+ const toggle = useCallback(() => {
35
+ const next = !revealed;
36
+ setRevealed(next);
37
+ onVisibilityChange?.(next);
38
+ }, [onVisibilityChange, revealed]);
39
+
40
+ const preset = secretRevealAnimationPresets[animation];
41
+ const displayText = value ?? (typeof children === "string" ? children : "");
42
+
43
+ return (
44
+ <div
45
+ ref={ref}
46
+ data-slot="secret-reveal"
47
+ className={cn(secretRevealVariants({ appearance, size }), className)}
48
+ {...rest}
49
+ >
50
+ {label && labelPosition === "top" && (
51
+ <span
52
+ data-slot="secret-reveal-label"
53
+ className={secretRevealLabelVariants({ size })}
54
+ >
55
+ {label}
56
+ </span>
57
+ )}
58
+ <span className="flex items-center gap-2 flex-1 min-w-0">
59
+ {label && labelPosition === "side" && (
60
+ <span
61
+ data-slot="secret-reveal-label"
62
+ className={secretRevealLabelVariants({ size })}
63
+ >
64
+ {label}
65
+ </span>
66
+ )}
67
+ <span
68
+ data-slot="secret-reveal-value"
69
+ className={cn(secretRevealValueVariants({ size }), "flex-1 truncate")}
70
+ >
71
+ <AnimatePresence mode="wait">
72
+ <motion.span
73
+ key={revealed ? "revealed" : "hidden"}
74
+ initial="initial"
75
+ animate="animate"
76
+ exit="exit"
77
+ variants={preset.variants}
78
+ transition={preset.transition}
79
+ className="inline-block"
80
+ >
81
+ {revealed
82
+ ? (value ?? children)
83
+ : muteChar.repeat(displayText.length || 8)}
84
+ </motion.span>
85
+ </AnimatePresence>
86
+ </span>
87
+ <button
88
+ type="button"
89
+ data-slot="secret-reveal-toggle"
90
+ className={secretRevealToggleVariants({ size, appearance })}
91
+ onClick={toggle}
92
+ aria-label={revealed ? "Hide secret" : "Reveal secret"}
93
+ >
94
+ {revealed ? (
95
+ <svg
96
+ xmlns="http://www.w3.org/2000/svg"
97
+ width="16"
98
+ height="16"
99
+ viewBox="0 0 24 24"
100
+ fill="none"
101
+ stroke="currentColor"
102
+ strokeWidth="2"
103
+ strokeLinecap="round"
104
+ strokeLinejoin="round"
105
+ >
106
+ <path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94" />
107
+ <path d="M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19" />
108
+ <line x1="1" y1="1" x2="23" y2="23" />
109
+ </svg>
110
+ ) : (
111
+ <svg
112
+ xmlns="http://www.w3.org/2000/svg"
113
+ width="16"
114
+ height="16"
115
+ viewBox="0 0 24 24"
116
+ fill="none"
117
+ stroke="currentColor"
118
+ strokeWidth="2"
119
+ strokeLinecap="round"
120
+ strokeLinejoin="round"
121
+ >
122
+ <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" />
123
+ <circle cx="12" cy="12" r="3" />
124
+ </svg>
125
+ )}
126
+ </button>
127
+ </span>
128
+ </div>
129
+ );
130
+ }
131
+
132
+ SecretRevealAnimated.displayName = "SecretRevealAnimated";
@@ -0,0 +1,11 @@
1
+ import type { Ref } from "react";
2
+
3
+ import type { SecretRevealBaseProps } from "../types";
4
+ import type { SecretRevealAnimation } from "./animations";
5
+
6
+ export type { SecretRevealAnimation };
7
+
8
+ export type SecretRevealAnimatedProps = SecretRevealBaseProps & {
9
+ animation?: SecretRevealAnimation;
10
+ ref?: Ref<HTMLDivElement>;
11
+ };
@@ -0,0 +1,14 @@
1
+ "use client";
2
+
3
+ export { SecretReveal } from "./secret-reveal";
4
+ export type {
5
+ SecretRevealBaseProps,
6
+ SecretRevealProps,
7
+ SecretRevealVariantProps,
8
+ } from "./types";
9
+ export {
10
+ secretRevealLabelVariants,
11
+ secretRevealToggleVariants,
12
+ secretRevealValueVariants,
13
+ secretRevealVariants,
14
+ } from "./variants";
@@ -0,0 +1,116 @@
1
+ "use client";
2
+
3
+ import { useCallback, useState } from "react";
4
+
5
+ import { cn } from "../../lib/utils";
6
+
7
+ import type { SecretRevealBaseProps } from "./types";
8
+ import {
9
+ secretRevealLabelVariants,
10
+ secretRevealToggleVariants,
11
+ secretRevealValueVariants,
12
+ secretRevealVariants,
13
+ } from "./variants";
14
+
15
+ export function SecretRevealBase({
16
+ appearance,
17
+ size,
18
+ value,
19
+ children,
20
+ label,
21
+ labelPosition = "top",
22
+ initiallyRevealed = false,
23
+ onVisibilityChange,
24
+ muteChar = "•",
25
+ className,
26
+ ref,
27
+ ...rest
28
+ }: SecretRevealBaseProps) {
29
+ const [revealed, setRevealed] = useState(initiallyRevealed);
30
+
31
+ const toggle = useCallback(() => {
32
+ const next = !revealed;
33
+ setRevealed(next);
34
+ onVisibilityChange?.(next);
35
+ }, [onVisibilityChange, revealed]);
36
+
37
+ const displayText = value ?? (typeof children === "string" ? children : "");
38
+
39
+ return (
40
+ <div
41
+ ref={ref}
42
+ data-slot="secret-reveal"
43
+ className={cn(secretRevealVariants({ appearance, size }), className)}
44
+ {...rest}
45
+ >
46
+ {label && labelPosition === "top" && (
47
+ <span
48
+ data-slot="secret-reveal-label"
49
+ className={secretRevealLabelVariants({ size })}
50
+ >
51
+ {label}
52
+ </span>
53
+ )}
54
+ <span className="flex items-center gap-2 flex-1 min-w-0">
55
+ {label && labelPosition === "side" && (
56
+ <span
57
+ data-slot="secret-reveal-label"
58
+ className={secretRevealLabelVariants({ size })}
59
+ >
60
+ {label}
61
+ </span>
62
+ )}
63
+ <span
64
+ data-slot="secret-reveal-value"
65
+ className={cn(secretRevealValueVariants({ size }), "flex-1 truncate")}
66
+ >
67
+ {revealed
68
+ ? (value ?? children)
69
+ : muteChar.repeat(displayText.length || 8)}
70
+ </span>
71
+ <button
72
+ type="button"
73
+ data-slot="secret-reveal-toggle"
74
+ className={secretRevealToggleVariants({ size, appearance })}
75
+ onClick={toggle}
76
+ aria-label={revealed ? "Hide secret" : "Reveal secret"}
77
+ >
78
+ {revealed ? (
79
+ <svg
80
+ xmlns="http://www.w3.org/2000/svg"
81
+ width="16"
82
+ height="16"
83
+ viewBox="0 0 24 24"
84
+ fill="none"
85
+ stroke="currentColor"
86
+ strokeWidth="2"
87
+ strokeLinecap="round"
88
+ strokeLinejoin="round"
89
+ >
90
+ <path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94" />
91
+ <path d="M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19" />
92
+ <line x1="1" y1="1" x2="23" y2="23" />
93
+ </svg>
94
+ ) : (
95
+ <svg
96
+ xmlns="http://www.w3.org/2000/svg"
97
+ width="16"
98
+ height="16"
99
+ viewBox="0 0 24 24"
100
+ fill="none"
101
+ stroke="currentColor"
102
+ strokeWidth="2"
103
+ strokeLinecap="round"
104
+ strokeLinejoin="round"
105
+ >
106
+ <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" />
107
+ <circle cx="12" cy="12" r="3" />
108
+ </svg>
109
+ )}
110
+ </button>
111
+ </span>
112
+ </div>
113
+ );
114
+ }
115
+
116
+ SecretRevealBase.displayName = "SecretReveal";
@@ -0,0 +1,75 @@
1
+ import { createRef } from "react";
2
+ import { render } from "@testing-library/react";
3
+ import { describe, expect, it } from "vitest";
4
+
5
+ import { SecretReveal } from "./secret-reveal";
6
+
7
+ describe("SecretReveal", () => {
8
+ it("should set displayName", () => {
9
+ expect(SecretReveal.displayName).toBe("SecretReveal");
10
+ });
11
+
12
+ it("should stamp data-slot on the root container", () => {
13
+ const { container } = render(<SecretReveal value="sk-test" />);
14
+ const root = container.querySelector('[data-slot="secret-reveal"]');
15
+ expect(root).toBeTruthy();
16
+ });
17
+
18
+ it("should render masked value by default", () => {
19
+ const { container } = render(<SecretReveal value="sk-test" />);
20
+ const valueEl = container.querySelector(
21
+ '[data-slot="secret-reveal-value"]',
22
+ );
23
+ expect(valueEl?.textContent).toBe("•••••••");
24
+ });
25
+
26
+ it("should render a label", () => {
27
+ const { container } = render(
28
+ <SecretReveal value="sk-test" label="API Key" />,
29
+ );
30
+ const label = container.querySelector('[data-slot="secret-reveal-label"]');
31
+ expect(label).toBeTruthy();
32
+ expect(label?.textContent).toBe("API Key");
33
+ });
34
+
35
+ it("should render a toggle button", () => {
36
+ const { container } = render(<SecretReveal value="sk-test" />);
37
+ const toggle = container.querySelector(
38
+ '[data-slot="secret-reveal-toggle"]',
39
+ );
40
+ expect(toggle).toBeTruthy();
41
+ });
42
+
43
+ it("should render initial revealed state", () => {
44
+ const { container } = render(
45
+ <SecretReveal value="sk-test" initiallyRevealed />,
46
+ );
47
+ const valueEl = container.querySelector(
48
+ '[data-slot="secret-reveal-value"]',
49
+ );
50
+ expect(valueEl?.textContent).toBe("sk-test");
51
+ });
52
+
53
+ it("should render with children instead of value", () => {
54
+ const { container } = render(<SecretReveal>my-secret-key</SecretReveal>);
55
+ const valueEl = container.querySelector(
56
+ '[data-slot="secret-reveal-value"]',
57
+ );
58
+ expect(valueEl?.textContent).toBe("•••••••••••••");
59
+ });
60
+
61
+ it("should forward refs to the root element", () => {
62
+ const ref = createRef<HTMLDivElement>();
63
+ render(<SecretReveal value="test" ref={ref} />);
64
+ expect(ref.current).toBeInstanceOf(HTMLElement);
65
+ expect(ref.current?.getAttribute("data-slot")).toBe("secret-reveal");
66
+ });
67
+
68
+ it("should apply custom className", () => {
69
+ const { container } = render(
70
+ <SecretReveal value="test" className="custom-class" />,
71
+ );
72
+ const root = container.querySelector('[data-slot="secret-reveal"]');
73
+ expect(root?.className).toMatch(/custom-class/);
74
+ });
75
+ });
@@ -0,0 +1,2 @@
1
+ // secret-reveal.tsx — default static entry (no framer-motion)
2
+ export { SecretRevealBase as SecretReveal } from "./secret-reveal-base";
@@ -0,0 +1,21 @@
1
+ import type { VariantProps } from "class-variance-authority";
2
+ import type { ComponentPropsWithRef, ReactNode } from "react";
3
+
4
+ import type { secretRevealVariants } from "./variants";
5
+
6
+ export type SecretRevealVariantProps = VariantProps<
7
+ typeof secretRevealVariants
8
+ >;
9
+
10
+ export type SecretRevealBaseProps = SecretRevealVariantProps &
11
+ ComponentPropsWithRef<"div"> & {
12
+ value?: string;
13
+ children?: ReactNode;
14
+ label?: ReactNode;
15
+ labelPosition?: "top" | "side";
16
+ initiallyRevealed?: boolean;
17
+ onVisibilityChange?: (revealed: boolean) => void;
18
+ muteChar?: string;
19
+ };
20
+
21
+ export type SecretRevealProps = SecretRevealBaseProps;
@@ -0,0 +1,49 @@
1
+ import { cva } from "class-variance-authority";
2
+
3
+ import {
4
+ zuiSecretRevealAppearances,
5
+ zuiSecretRevealContainerBase,
6
+ zuiSecretRevealLabelBase,
7
+ zuiSecretRevealLabelSizes,
8
+ zuiSecretRevealSizes,
9
+ zuiSecretRevealToggleBase,
10
+ zuiSecretRevealToggleSizes,
11
+ zuiSecretRevealValueBase,
12
+ zuiSecretRevealValueSizes,
13
+ } from "../../design-system/secret-reveal";
14
+
15
+ export const secretRevealVariants = cva(zuiSecretRevealContainerBase, {
16
+ variants: {
17
+ appearance: zuiSecretRevealAppearances,
18
+ size: zuiSecretRevealSizes,
19
+ },
20
+ defaultVariants: {
21
+ appearance: "default",
22
+ size: "md",
23
+ },
24
+ });
25
+
26
+ export const secretRevealLabelVariants = cva(zuiSecretRevealLabelBase, {
27
+ variants: {
28
+ size: zuiSecretRevealLabelSizes,
29
+ },
30
+ defaultVariants: { size: "md" },
31
+ });
32
+
33
+ export const secretRevealValueVariants = cva(zuiSecretRevealValueBase, {
34
+ variants: {
35
+ size: zuiSecretRevealValueSizes,
36
+ },
37
+ defaultVariants: { size: "md" },
38
+ });
39
+
40
+ export const secretRevealToggleVariants = cva(zuiSecretRevealToggleBase, {
41
+ variants: {
42
+ size: zuiSecretRevealToggleSizes,
43
+ appearance: zuiSecretRevealAppearances,
44
+ },
45
+ defaultVariants: {
46
+ size: "md",
47
+ appearance: "default",
48
+ },
49
+ });