@zentauri-ui/zentauri-components 2.1.9 → 2.2.0

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 +6 -5
  2. package/cli/props.json +220 -0
  3. package/cli/registry.json +7 -1
  4. package/dist/{chunk-VN7FE5RR.mjs → chunk-37KMH77M.mjs} +3 -3
  5. package/dist/{chunk-VN7FE5RR.mjs.map → chunk-37KMH77M.mjs.map} +1 -1
  6. package/dist/chunk-4KOQS4DT.mjs +96 -0
  7. package/dist/chunk-4KOQS4DT.mjs.map +1 -0
  8. package/dist/{chunk-3HBC34NF.mjs → chunk-5XSW5JYA.mjs} +4 -4
  9. package/dist/{chunk-3HBC34NF.mjs.map → chunk-5XSW5JYA.mjs.map} +1 -1
  10. package/dist/{chunk-3RC5IG6O.mjs → chunk-AMNJ35TT.mjs} +13 -3
  11. package/dist/chunk-AMNJ35TT.mjs.map +1 -0
  12. package/dist/chunk-DXNIAFBG.js +103 -0
  13. package/dist/chunk-DXNIAFBG.js.map +1 -0
  14. package/dist/chunk-EMZC6ICD.mjs +55 -0
  15. package/dist/chunk-EMZC6ICD.mjs.map +1 -0
  16. package/dist/{chunk-7DGPRPWM.js → chunk-EPJYLBXV.js} +6 -6
  17. package/dist/{chunk-7DGPRPWM.js.map → chunk-EPJYLBXV.js.map} +1 -1
  18. package/dist/{chunk-4TPE5DEG.js → chunk-F3G3RL2N.js} +13 -3
  19. package/dist/chunk-F3G3RL2N.js.map +1 -0
  20. package/dist/chunk-HNPGWFVY.js +65 -0
  21. package/dist/chunk-HNPGWFVY.js.map +1 -0
  22. package/dist/{chunk-OLT7P7JO.mjs → chunk-TACF7MJE.mjs} +3 -3
  23. package/dist/{chunk-OLT7P7JO.mjs.map → chunk-TACF7MJE.mjs.map} +1 -1
  24. package/dist/chunk-VQJXOJ7G.js +19 -0
  25. package/dist/{chunk-MWG7LHAK.js.map → chunk-VQJXOJ7G.js.map} +1 -1
  26. package/dist/{chunk-7CZDJTPD.js → chunk-YTCVWOBC.js} +12 -12
  27. package/dist/{chunk-7CZDJTPD.js.map → chunk-YTCVWOBC.js.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/typing-indicator.d.ts +47 -0
  35. package/dist/design-system/typing-indicator.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/split-button.js +18 -17
  53. package/dist/ui/split-button.js.map +1 -1
  54. package/dist/ui/split-button.mjs +5 -4
  55. package/dist/ui/split-button.mjs.map +1 -1
  56. package/dist/ui/typing-indicator/animated/animations.d.ts +8 -0
  57. package/dist/ui/typing-indicator/animated/animations.d.ts.map +1 -0
  58. package/dist/ui/typing-indicator/animated/index.d.ts +4 -0
  59. package/dist/ui/typing-indicator/animated/index.d.ts.map +1 -0
  60. package/dist/ui/typing-indicator/animated/types.d.ts +9 -0
  61. package/dist/ui/typing-indicator/animated/types.d.ts.map +1 -0
  62. package/dist/ui/typing-indicator/animated/typing-indicator-animated.d.ts +6 -0
  63. package/dist/ui/typing-indicator/animated/typing-indicator-animated.d.ts.map +1 -0
  64. package/dist/ui/typing-indicator/animated.js +119 -0
  65. package/dist/ui/typing-indicator/animated.js.map +1 -0
  66. package/dist/ui/typing-indicator/animated.mjs +116 -0
  67. package/dist/ui/typing-indicator/animated.mjs.map +1 -0
  68. package/dist/ui/typing-indicator/index.d.ts +4 -0
  69. package/dist/ui/typing-indicator/index.d.ts.map +1 -0
  70. package/dist/ui/typing-indicator/types.d.ts +13 -0
  71. package/dist/ui/typing-indicator/types.d.ts.map +1 -0
  72. package/dist/ui/typing-indicator/typing-indicator-base.d.ts +13 -0
  73. package/dist/ui/typing-indicator/typing-indicator-base.d.ts.map +1 -0
  74. package/dist/ui/typing-indicator/typing-indicator.d.ts +2 -0
  75. package/dist/ui/typing-indicator/typing-indicator.d.ts.map +1 -0
  76. package/dist/ui/typing-indicator/variants.d.ts +16 -0
  77. package/dist/ui/typing-indicator/variants.d.ts.map +1 -0
  78. package/dist/ui/typing-indicator.js +32 -0
  79. package/dist/ui/typing-indicator.js.map +1 -0
  80. package/dist/ui/typing-indicator.mjs +7 -0
  81. package/dist/ui/typing-indicator.mjs.map +1 -0
  82. package/package.json +1 -1
  83. package/src/design-system/index.ts +1 -0
  84. package/src/design-system/typing-indicator.ts +74 -0
  85. package/src/ui/typing-indicator/animated/animations.ts +58 -0
  86. package/src/ui/typing-indicator/animated/index.ts +8 -0
  87. package/src/ui/typing-indicator/animated/types.ts +11 -0
  88. package/src/ui/typing-indicator/animated/typing-indicator-animated.tsx +79 -0
  89. package/src/ui/typing-indicator/index.ts +15 -0
  90. package/src/ui/typing-indicator/types.ts +20 -0
  91. package/src/ui/typing-indicator/typing-indicator-base.tsx +75 -0
  92. package/src/ui/typing-indicator/typing-indicator.test.tsx +76 -0
  93. package/src/ui/typing-indicator/typing-indicator.tsx +2 -0
  94. package/src/ui/typing-indicator/variants.ts +49 -0
  95. package/dist/chunk-3RC5IG6O.mjs.map +0 -1
  96. package/dist/chunk-4TPE5DEG.js.map +0 -1
  97. package/dist/chunk-MWG7LHAK.js +0 -19
@@ -0,0 +1,116 @@
1
+ "use client";
2
+ import { TypingIndicatorLabel, typingIndicatorDotVariants, typingIndicatorDotsVariants, typingIndicatorVariants } from '../../chunk-4KOQS4DT.mjs';
3
+ import '../../chunk-EMZC6ICD.mjs';
4
+ import { cn } from '../../chunk-4D54YOL6.mjs';
5
+ import '../../chunk-J5LGTIGS.mjs';
6
+ import { motion } from 'framer-motion';
7
+ import { useMemo } from 'react';
8
+ import { jsxs, jsx } from 'react/jsx-runtime';
9
+
10
+ // src/ui/typing-indicator/animated/animations.ts
11
+ var typingIndicatorAnimationPresets = {
12
+ none: {
13
+ transition: { duration: 0 },
14
+ variants: {
15
+ initial: { y: 0 },
16
+ animate: { y: 0 }
17
+ }
18
+ },
19
+ bounce: {
20
+ transition: {
21
+ type: "spring",
22
+ stiffness: 500,
23
+ damping: 10,
24
+ mass: 0.5
25
+ },
26
+ variants: {
27
+ initial: { y: 0 },
28
+ animate: { y: -6 }
29
+ }
30
+ },
31
+ pulse: {
32
+ transition: {
33
+ duration: 0.8,
34
+ repeat: Infinity,
35
+ repeatType: "reverse",
36
+ ease: "easeInOut"
37
+ },
38
+ variants: {
39
+ initial: { scale: 1, opacity: 0.4 },
40
+ animate: { scale: 1.3, opacity: 1 }
41
+ }
42
+ },
43
+ wave: {
44
+ transition: {
45
+ type: "spring",
46
+ stiffness: 400,
47
+ damping: 8,
48
+ mass: 0.4
49
+ },
50
+ variants: {
51
+ initial: { y: 0, scale: 1 },
52
+ animate: { y: -8, scale: 0.9 }
53
+ }
54
+ }
55
+ };
56
+ function TypingIndicatorAnimated({
57
+ appearance,
58
+ size,
59
+ dots = 3,
60
+ label,
61
+ labelPosition = "before",
62
+ animation = "bounce",
63
+ className,
64
+ ref,
65
+ ...rest
66
+ }) {
67
+ const preset = typingIndicatorAnimationPresets[animation];
68
+ const dotTransitionOverrides = useMemo(
69
+ () => Array.from({ length: dots }).map((_, i) => ({
70
+ delay: i * 0.12,
71
+ ...animation !== "none" ? { repeat: Infinity, repeatType: "reverse" } : {},
72
+ ...preset.transition
73
+ })),
74
+ [dots, animation, preset.transition]
75
+ );
76
+ return /* @__PURE__ */ jsxs(
77
+ "span",
78
+ {
79
+ ref,
80
+ "data-slot": "typing-indicator",
81
+ className: cn(typingIndicatorVariants({ size }), className),
82
+ ...rest,
83
+ children: [
84
+ label && labelPosition === "before" && /* @__PURE__ */ jsx(TypingIndicatorLabel, { size, children: label }),
85
+ /* @__PURE__ */ jsx(
86
+ "span",
87
+ {
88
+ "data-slot": "typing-indicator-dots",
89
+ className: typingIndicatorDotsVariants({ size }),
90
+ children: Array.from({ length: dots }).map((_, i) => /* @__PURE__ */ jsx(
91
+ motion.span,
92
+ {
93
+ "data-slot": "typing-indicator-dot",
94
+ className: cn(
95
+ typingIndicatorDotVariants({ appearance, size }),
96
+ "animate-none"
97
+ ),
98
+ initial: "initial",
99
+ animate: "animate",
100
+ variants: preset.variants,
101
+ transition: dotTransitionOverrides[i]
102
+ },
103
+ i
104
+ ))
105
+ }
106
+ ),
107
+ label && labelPosition === "after" && /* @__PURE__ */ jsx(TypingIndicatorLabel, { size, children: label })
108
+ ]
109
+ }
110
+ );
111
+ }
112
+ TypingIndicatorAnimated.displayName = "TypingIndicatorAnimated";
113
+
114
+ export { TypingIndicatorAnimated, typingIndicatorAnimationPresets };
115
+ //# sourceMappingURL=animated.mjs.map
116
+ //# sourceMappingURL=animated.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/ui/typing-indicator/animated/animations.ts","../../../src/ui/typing-indicator/animated/typing-indicator-animated.tsx"],"names":[],"mappings":"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","file":"animated.mjs","sourcesContent":["import type { Transition, Variants } from \"framer-motion\";\n\nexport type TypingIndicatorAnimation = \"none\" | \"bounce\" | \"pulse\" | \"wave\";\n\nexport type TypingIndicatorAnimationPresets = Record<\n TypingIndicatorAnimation,\n {\n transition: Transition;\n variants: Variants;\n }\n>;\n\nexport const typingIndicatorAnimationPresets: TypingIndicatorAnimationPresets =\n {\n none: {\n transition: { duration: 0 },\n variants: {\n initial: { y: 0 },\n animate: { y: 0 },\n },\n },\n bounce: {\n transition: {\n type: \"spring\",\n stiffness: 500,\n damping: 10,\n mass: 0.5,\n },\n variants: {\n initial: { y: 0 },\n animate: { y: -6 },\n },\n },\n pulse: {\n transition: {\n duration: 0.8,\n repeat: Infinity,\n repeatType: \"reverse\",\n ease: \"easeInOut\",\n },\n variants: {\n initial: { scale: 1, opacity: 0.4 },\n animate: { scale: 1.3, opacity: 1 },\n },\n },\n wave: {\n transition: {\n type: \"spring\",\n stiffness: 400,\n damping: 8,\n mass: 0.4,\n },\n variants: {\n initial: { y: 0, scale: 1 },\n animate: { y: -8, scale: 0.9 },\n },\n },\n };\n","\"use client\";\n\nimport { motion } from \"framer-motion\";\nimport { useMemo } from \"react\";\n\nimport { cn } from \"../../../lib/utils\";\n\nimport {\n typingIndicatorDotVariants,\n typingIndicatorDotsVariants,\n typingIndicatorVariants,\n} from \"../variants\";\n\nimport { typingIndicatorAnimationPresets } from \"./animations\";\nimport type { TypingIndicatorAnimatedProps } from \"./types\";\nimport { TypingIndicatorLabel } from \"../typing-indicator-base\";\n\nexport function TypingIndicatorAnimated({\n appearance,\n size,\n dots = 3,\n label,\n labelPosition = \"before\",\n animation = \"bounce\",\n className,\n ref,\n ...rest\n}: TypingIndicatorAnimatedProps) {\n const preset = typingIndicatorAnimationPresets[animation];\n\n const dotTransitionOverrides = useMemo(\n () =>\n Array.from({ length: dots }).map((_, i) => ({\n delay: i * 0.12,\n ...(animation !== \"none\"\n ? { repeat: Infinity, repeatType: \"reverse\" as const }\n : {}),\n ...preset.transition,\n })),\n [dots, animation, preset.transition],\n );\n\n return (\n <span\n ref={ref}\n data-slot=\"typing-indicator\"\n className={cn(typingIndicatorVariants({ size }), className)}\n {...rest}\n >\n {label && labelPosition === \"before\" && (\n <TypingIndicatorLabel size={size}>{label}</TypingIndicatorLabel>\n )}\n <span\n data-slot=\"typing-indicator-dots\"\n className={typingIndicatorDotsVariants({ size })}\n >\n {Array.from({ length: dots }).map((_, i) => (\n <motion.span\n key={i}\n data-slot=\"typing-indicator-dot\"\n className={cn(\n typingIndicatorDotVariants({ appearance, size }),\n \"animate-none\",\n )}\n initial=\"initial\"\n animate=\"animate\"\n variants={preset.variants}\n transition={dotTransitionOverrides[i]}\n />\n ))}\n </span>\n {label && labelPosition === \"after\" && (\n <TypingIndicatorLabel size={size}>{label}</TypingIndicatorLabel>\n )}\n </span>\n );\n}\n\nTypingIndicatorAnimated.displayName = \"TypingIndicatorAnimated\";\n"]}
@@ -0,0 +1,4 @@
1
+ export { TypingIndicator } from "./typing-indicator";
2
+ export type { TypingIndicatorBaseProps, TypingIndicatorDots, TypingIndicatorProps, TypingIndicatorVariantProps, } from "./types";
3
+ export { typingIndicatorDotVariants, typingIndicatorDotsVariants, typingIndicatorLabelVariants, typingIndicatorVariants, } from "./variants";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/typing-indicator/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,YAAY,EACV,wBAAwB,EACxB,mBAAmB,EACnB,oBAAoB,EACpB,2BAA2B,GAC5B,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,4BAA4B,EAC5B,uBAAuB,GACxB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { VariantProps } from "class-variance-authority";
2
+ import type { ComponentPropsWithRef, ReactNode } from "react";
3
+ import type { typingIndicatorDotVariants } from "./variants";
4
+ export type TypingIndicatorVariantProps = VariantProps<typeof typingIndicatorDotVariants>;
5
+ export type TypingIndicatorDots = 3 | 4 | 5;
6
+ export type TypingIndicatorBaseProps = TypingIndicatorVariantProps & ComponentPropsWithRef<"span"> & {
7
+ dots?: TypingIndicatorDots;
8
+ label?: ReactNode;
9
+ labelPosition?: "before" | "after";
10
+ children?: ReactNode;
11
+ };
12
+ export type TypingIndicatorProps = TypingIndicatorBaseProps;
13
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/ui/typing-indicator/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9D,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAE7D,MAAM,MAAM,2BAA2B,GAAG,YAAY,CACpD,OAAO,0BAA0B,CAClC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAE5C,MAAM,MAAM,wBAAwB,GAAG,2BAA2B,GAChE,qBAAqB,CAAC,MAAM,CAAC,GAAG;IAC9B,IAAI,CAAC,EAAE,mBAAmB,CAAC;IAC3B,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,aAAa,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IACnC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,CAAC;AAEJ,MAAM,MAAM,oBAAoB,GAAG,wBAAwB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { TypingIndicatorBaseProps } from "./types";
2
+ export declare function TypingIndicatorBase({ appearance, size, dots, label, labelPosition, className, ref, ...rest }: TypingIndicatorBaseProps): import("react/jsx-runtime").JSX.Element;
3
+ export declare namespace TypingIndicatorBase {
4
+ var displayName: string;
5
+ }
6
+ export declare function TypingIndicatorLabel({ size, children, }: {
7
+ size?: TypingIndicatorBaseProps["size"];
8
+ children: React.ReactNode;
9
+ }): import("react/jsx-runtime").JSX.Element;
10
+ export declare namespace TypingIndicatorLabel {
11
+ var displayName: string;
12
+ }
13
+ //# sourceMappingURL=typing-indicator-base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typing-indicator-base.d.ts","sourceRoot":"","sources":["../../../src/ui/typing-indicator/typing-indicator-base.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AASxD,wBAAgB,mBAAmB,CAAC,EAClC,UAAU,EACV,IAAI,EACJ,IAAQ,EACR,KAAK,EACL,aAAwB,EACxB,SAAS,EACT,GAAG,EACH,GAAG,IAAI,EACR,EAAE,wBAAwB,2CA+B1B;yBAxCe,mBAAmB;;;AA4CnC,wBAAgB,oBAAoB,CAAC,EACnC,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,CAAC,EAAE,wBAAwB,CAAC,MAAM,CAAC,CAAC;IACxC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,2CASA;yBAfe,oBAAoB"}
@@ -0,0 +1,2 @@
1
+ export { TypingIndicatorBase as TypingIndicator } from "./typing-indicator-base";
2
+ //# sourceMappingURL=typing-indicator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typing-indicator.d.ts","sourceRoot":"","sources":["../../../src/ui/typing-indicator/typing-indicator.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,IAAI,eAAe,EAAE,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { zuiTypingIndicatorDotDelays } from "../../design-system/typing-indicator";
2
+ export { zuiTypingIndicatorDotDelays as typingIndicatorDotDelays };
3
+ export declare const typingIndicatorVariants: (props?: ({
4
+ size?: "md" | "sm" | "lg" | null | undefined;
5
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
6
+ export declare const typingIndicatorDotsVariants: (props?: ({
7
+ size?: "md" | "sm" | "lg" | null | undefined;
8
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
9
+ export declare const typingIndicatorDotVariants: (props?: ({
10
+ appearance?: "default" | "muted" | "sky" | "emerald" | "rose" | "slate" | "gray" | "indigo" | "cyan" | "blue" | "green" | "lime" | "orange" | "pink" | "purple" | "red" | "teal" | "yellow" | "gradient-blue" | "gradient-green" | "gradient-purple" | "zinc" | "subtle" | "primary" | null | undefined;
11
+ size?: "md" | "sm" | "lg" | null | undefined;
12
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
13
+ export declare const typingIndicatorLabelVariants: (props?: ({
14
+ size?: "md" | "sm" | "lg" | null | undefined;
15
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
16
+ //# sourceMappingURL=variants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"variants.d.ts","sourceRoot":"","sources":["../../../src/ui/typing-indicator/variants.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,2BAA2B,EAM5B,MAAM,sCAAsC,CAAC;AAE9C,OAAO,EAAE,2BAA2B,IAAI,wBAAwB,EAAE,CAAC;AAEnE,eAAO,MAAM,uBAAuB;;8EAOlC,CAAC;AAEH,eAAO,MAAM,2BAA2B;;8EAKtC,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;8EASrC,CAAC;AAEH,eAAO,MAAM,4BAA4B;;8EAKvC,CAAC"}
@@ -0,0 +1,32 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var chunkDXNIAFBG_js = require('../chunk-DXNIAFBG.js');
5
+ require('../chunk-HNPGWFVY.js');
6
+ require('../chunk-ZS5756ZC.js');
7
+ require('../chunk-PZ5AY32C.js');
8
+
9
+
10
+
11
+ Object.defineProperty(exports, "TypingIndicator", {
12
+ enumerable: true,
13
+ get: function () { return chunkDXNIAFBG_js.TypingIndicatorBase; }
14
+ });
15
+ Object.defineProperty(exports, "typingIndicatorDotVariants", {
16
+ enumerable: true,
17
+ get: function () { return chunkDXNIAFBG_js.typingIndicatorDotVariants; }
18
+ });
19
+ Object.defineProperty(exports, "typingIndicatorDotsVariants", {
20
+ enumerable: true,
21
+ get: function () { return chunkDXNIAFBG_js.typingIndicatorDotsVariants; }
22
+ });
23
+ Object.defineProperty(exports, "typingIndicatorLabelVariants", {
24
+ enumerable: true,
25
+ get: function () { return chunkDXNIAFBG_js.typingIndicatorLabelVariants; }
26
+ });
27
+ Object.defineProperty(exports, "typingIndicatorVariants", {
28
+ enumerable: true,
29
+ get: function () { return chunkDXNIAFBG_js.typingIndicatorVariants; }
30
+ });
31
+ //# sourceMappingURL=typing-indicator.js.map
32
+ //# sourceMappingURL=typing-indicator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"typing-indicator.js"}
@@ -0,0 +1,7 @@
1
+ "use client";
2
+ export { TypingIndicatorBase as TypingIndicator, typingIndicatorDotVariants, typingIndicatorDotsVariants, typingIndicatorLabelVariants, typingIndicatorVariants } from '../chunk-4KOQS4DT.mjs';
3
+ import '../chunk-EMZC6ICD.mjs';
4
+ import '../chunk-4D54YOL6.mjs';
5
+ import '../chunk-J5LGTIGS.mjs';
6
+ //# sourceMappingURL=typing-indicator.mjs.map
7
+ //# sourceMappingURL=typing-indicator.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"typing-indicator.mjs"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zentauri-ui/zentauri-components",
3
- "version": "2.1.9",
3
+ "version": "2.2.0",
4
4
  "description": "React + Tailwind UI kit with charts, ESM/CJS builds, per-entry exports, and a zentauri-components / zentauri-ui CLI to vendor UI or hook source into your app",
5
5
  "keywords": [
6
6
  "react",
@@ -42,6 +42,7 @@ export * from "./timeline";
42
42
  export * from "./toast";
43
43
  export * from "./tokens";
44
44
  export * from "./toggle";
45
+ export * from "./typing-indicator";
45
46
  export * from "./tooltip";
46
47
  export * from "./tree-view";
47
48
  export * from "./typography";
@@ -0,0 +1,74 @@
1
+ export const zuiTypingIndicatorAppearances = {
2
+ default:
3
+ "bg-[var(--zui-typing-indicator-default-dot-bg,var(--zui-brand,oklch(20.8%_0.042_265.755)))] dark:bg-[var(--zui-typing-indicator-default-dot-bg-dark,var(--zui-brand-dark,oklch(98.4%_0.003_247.858)))]",
4
+ subtle:
5
+ "bg-[var(--zui-typing-indicator-subtle-dot-bg,var(--zui-surface-muted,oklch(92.9%_0.013_255.508)))] dark:bg-[var(--zui-typing-indicator-subtle-dot-bg-dark,var(--zui-surface-muted-dark,oklch(27.9%_0.041_260.031)))]",
6
+ muted:
7
+ "bg-[var(--zui-typing-indicator-muted-dot-bg,var(--zui-fg-muted,oklch(44.6%_0.043_257.281)))] dark:bg-[var(--zui-typing-indicator-muted-dot-bg-dark,var(--zui-fg-muted-dark,oklch(86.9%_0.022_252.894)))]",
8
+ primary:
9
+ "bg-[var(--zui-typing-indicator-primary-dot-bg,var(--zui-fg,oklch(20.8%_0.042_265.755)))] dark:bg-[var(--zui-typing-indicator-primary-dot-bg-dark,var(--zui-fg-dark,oklch(98.4%_0.003_247.858)))]",
10
+ blue: "bg-[var(--zui-typing-indicator-blue-dot-bg,var(--zui-color-blue,#2563eb))] dark:bg-[var(--zui-typing-indicator-blue-dot-bg-dark,var(--zui-color-blue-dark,#3b82f6))]",
11
+ cyan: "bg-[var(--zui-typing-indicator-cyan-dot-bg,var(--zui-color-cyan,#0891b2))] dark:bg-[var(--zui-typing-indicator-cyan-dot-bg-dark,var(--zui-color-cyan-dark,#22d3ee))]",
12
+ green:
13
+ "bg-[var(--zui-typing-indicator-green-dot-bg,var(--zui-color-green,#16a34a))] dark:bg-[var(--zui-typing-indicator-green-dot-bg-dark,var(--zui-color-green-dark,#22c55e))]",
14
+ lime: "bg-[var(--zui-typing-indicator-lime-dot-bg,var(--zui-color-lime,#65a30d))] dark:bg-[var(--zui-typing-indicator-lime-dot-bg-dark,var(--zui-color-lime-dark,#a3e635))]",
15
+ emerald:
16
+ "bg-[var(--zui-typing-indicator-emerald-dot-bg,var(--zui-color-emerald,oklch(69.6%_0.17_162.48)))] dark:bg-[var(--zui-typing-indicator-emerald-dot-bg-dark,var(--zui-color-emerald-dark,oklch(43.2%_0.095_166.913)))]",
17
+ indigo:
18
+ "bg-[var(--zui-typing-indicator-indigo-dot-bg,var(--zui-color-indigo,oklch(39.8%_0.195_277.366)))] dark:bg-[var(--zui-typing-indicator-indigo-dot-bg-dark,var(--zui-color-indigo-dark,oklch(51.1%_0.262_276.966)))]",
19
+ purple:
20
+ "bg-[var(--zui-typing-indicator-purple-dot-bg,var(--zui-color-purple,oklch(43.8%_0.218_303.724)))] dark:bg-[var(--zui-typing-indicator-purple-dot-bg-dark,var(--zui-color-purple-dark,oklch(55.8%_0.288_302.321)))]",
21
+ pink: "bg-[var(--zui-typing-indicator-pink-dot-bg,var(--zui-color-pink,oklch(45.9%_0.187_3.815)))] dark:bg-[var(--zui-typing-indicator-pink-dot-bg-dark,var(--zui-color-pink-dark,oklch(59.2%_0.249_0.584)))]",
22
+ rose: "bg-[var(--zui-typing-indicator-rose-dot-bg,var(--zui-color-rose,oklch(64.5%_0.246_16.439)))] dark:bg-[var(--zui-typing-indicator-rose-dot-bg-dark,var(--zui-color-rose-dark,oklch(51.4%_0.222_16.935)))]",
23
+ sky: "bg-[var(--zui-typing-indicator-sky-dot-bg,var(--zui-color-sky,oklch(68.5%_0.169_237.323)))] dark:bg-[var(--zui-typing-indicator-sky-dot-bg-dark,var(--zui-color-sky-dark,oklch(50%_0.134_242.749)))]",
24
+ teal: "bg-[var(--zui-typing-indicator-teal-dot-bg,var(--zui-color-teal,oklch(70.4%_0.14_182.503)))] dark:bg-[var(--zui-typing-indicator-teal-dot-bg-dark,var(--zui-color-teal-dark,oklch(51.1%_0.096_186.391)))]",
25
+ yellow:
26
+ "bg-[var(--zui-typing-indicator-yellow-dot-bg,var(--zui-color-yellow,oklch(79.5%_0.184_86.047)))] dark:bg-[var(--zui-typing-indicator-yellow-dot-bg-dark,var(--zui-color-yellow-dark,oklch(47.6%_0.114_61.907)))]",
27
+ orange:
28
+ "bg-[var(--zui-typing-indicator-orange-dot-bg,var(--zui-color-orange,oklch(70.5%_0.213_47.604)))] dark:bg-[var(--zui-typing-indicator-orange-dot-bg-dark,var(--zui-color-orange-dark,oklch(47%_0.157_37.304)))]",
29
+ red: "bg-[var(--zui-typing-indicator-red-dot-bg,var(--zui-color-red,#dc2626))] dark:bg-[var(--zui-typing-indicator-red-dot-bg-dark,var(--zui-color-red-dark,#ef4444))]",
30
+ slate:
31
+ "bg-[var(--zui-typing-indicator-slate-dot-bg,var(--zui-color-slate,#475569))] dark:bg-[var(--zui-typing-indicator-slate-dot-bg-dark,var(--zui-color-slate-dark,#64748b))]",
32
+ gray: "bg-[var(--zui-typing-indicator-gray-dot-bg,var(--zui-color-gray,oklch(55.1%_0.027_264.364)))] dark:bg-[var(--zui-typing-indicator-gray-dot-bg-dark,var(--zui-color-gray-dark,oklch(55.1%_0.027_264.364)))]",
33
+ zinc: "bg-[var(--zui-typing-indicator-zinc-dot-bg,var(--zui-color-zinc,#52525b))] dark:bg-[var(--zui-typing-indicator-zinc-dot-bg-dark,var(--zui-color-zinc-dark,#71717a))]",
34
+ "gradient-blue":
35
+ "bg-linear-to-r from-[var(--zui-typing-indicator-gradient-blue-from,var(--zui-color-blue,oklch(42.4%_0.199_265.638)))] dark:from-[var(--zui-typing-indicator-gradient-blue-from-dark,var(--zui-color-blue-dark,oklch(54.6%_0.245_262.881)))] to-[var(--zui-typing-indicator-gradient-blue-to,var(--zui-color-purple,oklch(43.8%_0.218_303.724)))] dark:to-[var(--zui-typing-indicator-gradient-blue-to-dark,var(--zui-color-purple-dark,oklch(55.8%_0.288_302.321)))]",
36
+ "gradient-green":
37
+ "bg-linear-to-r from-[var(--zui-typing-indicator-gradient-green-from,var(--zui-color-green,oklch(44.8%_0.119_151.328)))] dark:from-[var(--zui-typing-indicator-gradient-green-from-dark,var(--zui-color-green-dark,oklch(62.7%_0.194_149.214)))] to-[var(--zui-typing-indicator-gradient-green-to,var(--zui-color-lime,oklch(45.3%_0.124_130.933)))] dark:to-[var(--zui-typing-indicator-gradient-green-to-dark,var(--zui-color-lime-dark,oklch(64.8%_0.2_131.684)))]",
38
+ "gradient-purple":
39
+ "bg-linear-to-r from-[var(--zui-typing-indicator-gradient-purple-from,var(--zui-color-purple,oklch(43.8%_0.218_303.724)))] dark:from-[var(--zui-typing-indicator-gradient-purple-from-dark,var(--zui-color-purple-dark,oklch(55.8%_0.288_302.321)))] to-[var(--zui-typing-indicator-gradient-purple-to,var(--zui-color-pink,oklch(45.9%_0.187_3.815)))] dark:to-[var(--zui-typing-indicator-gradient-purple-to-dark,var(--zui-color-pink-dark,oklch(59.2%_0.249_0.584)))]",
40
+ } as const;
41
+
42
+ export const zuiTypingIndicatorDotsBase = "inline-flex items-center";
43
+
44
+ export const zuiTypingIndicatorDotBase =
45
+ "rounded-full animate-bounce [animation-duration:1.4s]";
46
+
47
+ export const zuiTypingIndicatorDotDelays = [
48
+ "[animation-delay:0s]",
49
+ "[animation-delay:0.16s]",
50
+ "[animation-delay:0.32s]",
51
+ ] as const;
52
+
53
+ export const zuiTypingIndicatorSizes = {
54
+ sm: "gap-1",
55
+ md: "gap-1.5",
56
+ lg: "gap-2",
57
+ } as const;
58
+
59
+ export const zuiTypingIndicatorDotSizes = {
60
+ sm: "size-1.5",
61
+ md: "size-2",
62
+ lg: "size-2.5",
63
+ } as const;
64
+
65
+ export const zuiTypingIndicatorLabelBase =
66
+ "text-[color:var(--zui-typing-indicator-label-fg,var(--zui-fg-muted,oklch(44.6%_0.043_257.287)))] dark:text-[color:var(--zui-typing-indicator-label-fg-dark,var(--zui-fg-muted-dark,oklch(86.9%_0.022_252.894)))]";
67
+
68
+ export const zuiTypingIndicatorLabelSizes = {
69
+ sm: "text-xs",
70
+ md: "text-sm",
71
+ lg: "text-base",
72
+ } as const;
73
+
74
+ export const zuiTypingIndicatorContainerBase = "inline-flex items-center gap-2";
@@ -0,0 +1,58 @@
1
+ import type { Transition, Variants } from "framer-motion";
2
+
3
+ export type TypingIndicatorAnimation = "none" | "bounce" | "pulse" | "wave";
4
+
5
+ export type TypingIndicatorAnimationPresets = Record<
6
+ TypingIndicatorAnimation,
7
+ {
8
+ transition: Transition;
9
+ variants: Variants;
10
+ }
11
+ >;
12
+
13
+ export const typingIndicatorAnimationPresets: TypingIndicatorAnimationPresets =
14
+ {
15
+ none: {
16
+ transition: { duration: 0 },
17
+ variants: {
18
+ initial: { y: 0 },
19
+ animate: { y: 0 },
20
+ },
21
+ },
22
+ bounce: {
23
+ transition: {
24
+ type: "spring",
25
+ stiffness: 500,
26
+ damping: 10,
27
+ mass: 0.5,
28
+ },
29
+ variants: {
30
+ initial: { y: 0 },
31
+ animate: { y: -6 },
32
+ },
33
+ },
34
+ pulse: {
35
+ transition: {
36
+ duration: 0.8,
37
+ repeat: Infinity,
38
+ repeatType: "reverse",
39
+ ease: "easeInOut",
40
+ },
41
+ variants: {
42
+ initial: { scale: 1, opacity: 0.4 },
43
+ animate: { scale: 1.3, opacity: 1 },
44
+ },
45
+ },
46
+ wave: {
47
+ transition: {
48
+ type: "spring",
49
+ stiffness: 400,
50
+ damping: 8,
51
+ mass: 0.4,
52
+ },
53
+ variants: {
54
+ initial: { y: 0, scale: 1 },
55
+ animate: { y: -8, scale: 0.9 },
56
+ },
57
+ },
58
+ };
@@ -0,0 +1,8 @@
1
+ "use client";
2
+
3
+ export { TypingIndicatorAnimated } from "./typing-indicator-animated";
4
+ export type {
5
+ TypingIndicatorAnimation,
6
+ TypingIndicatorAnimatedProps,
7
+ } from "./types";
8
+ export { typingIndicatorAnimationPresets } from "./animations";
@@ -0,0 +1,11 @@
1
+ import type { Ref } from "react";
2
+
3
+ import type { TypingIndicatorBaseProps } from "../types";
4
+ import type { TypingIndicatorAnimation } from "./animations";
5
+
6
+ export type { TypingIndicatorAnimation };
7
+
8
+ export type TypingIndicatorAnimatedProps = TypingIndicatorBaseProps & {
9
+ animation?: TypingIndicatorAnimation;
10
+ ref?: Ref<HTMLSpanElement>;
11
+ };
@@ -0,0 +1,79 @@
1
+ "use client";
2
+
3
+ import { motion } from "framer-motion";
4
+ import { useMemo } from "react";
5
+
6
+ import { cn } from "../../../lib/utils";
7
+
8
+ import {
9
+ typingIndicatorDotVariants,
10
+ typingIndicatorDotsVariants,
11
+ typingIndicatorVariants,
12
+ } from "../variants";
13
+
14
+ import { typingIndicatorAnimationPresets } from "./animations";
15
+ import type { TypingIndicatorAnimatedProps } from "./types";
16
+ import { TypingIndicatorLabel } from "../typing-indicator-base";
17
+
18
+ export function TypingIndicatorAnimated({
19
+ appearance,
20
+ size,
21
+ dots = 3,
22
+ label,
23
+ labelPosition = "before",
24
+ animation = "bounce",
25
+ className,
26
+ ref,
27
+ ...rest
28
+ }: TypingIndicatorAnimatedProps) {
29
+ const preset = typingIndicatorAnimationPresets[animation];
30
+
31
+ const dotTransitionOverrides = useMemo(
32
+ () =>
33
+ Array.from({ length: dots }).map((_, i) => ({
34
+ delay: i * 0.12,
35
+ ...(animation !== "none"
36
+ ? { repeat: Infinity, repeatType: "reverse" as const }
37
+ : {}),
38
+ ...preset.transition,
39
+ })),
40
+ [dots, animation, preset.transition],
41
+ );
42
+
43
+ return (
44
+ <span
45
+ ref={ref}
46
+ data-slot="typing-indicator"
47
+ className={cn(typingIndicatorVariants({ size }), className)}
48
+ {...rest}
49
+ >
50
+ {label && labelPosition === "before" && (
51
+ <TypingIndicatorLabel size={size}>{label}</TypingIndicatorLabel>
52
+ )}
53
+ <span
54
+ data-slot="typing-indicator-dots"
55
+ className={typingIndicatorDotsVariants({ size })}
56
+ >
57
+ {Array.from({ length: dots }).map((_, i) => (
58
+ <motion.span
59
+ key={i}
60
+ data-slot="typing-indicator-dot"
61
+ className={cn(
62
+ typingIndicatorDotVariants({ appearance, size }),
63
+ "animate-none",
64
+ )}
65
+ initial="initial"
66
+ animate="animate"
67
+ variants={preset.variants}
68
+ transition={dotTransitionOverrides[i]}
69
+ />
70
+ ))}
71
+ </span>
72
+ {label && labelPosition === "after" && (
73
+ <TypingIndicatorLabel size={size}>{label}</TypingIndicatorLabel>
74
+ )}
75
+ </span>
76
+ );
77
+ }
78
+
79
+ TypingIndicatorAnimated.displayName = "TypingIndicatorAnimated";
@@ -0,0 +1,15 @@
1
+ "use client";
2
+
3
+ export { TypingIndicator } from "./typing-indicator";
4
+ export type {
5
+ TypingIndicatorBaseProps,
6
+ TypingIndicatorDots,
7
+ TypingIndicatorProps,
8
+ TypingIndicatorVariantProps,
9
+ } from "./types";
10
+ export {
11
+ typingIndicatorDotVariants,
12
+ typingIndicatorDotsVariants,
13
+ typingIndicatorLabelVariants,
14
+ typingIndicatorVariants,
15
+ } from "./variants";
@@ -0,0 +1,20 @@
1
+ import type { VariantProps } from "class-variance-authority";
2
+ import type { ComponentPropsWithRef, ReactNode } from "react";
3
+
4
+ import type { typingIndicatorDotVariants } from "./variants";
5
+
6
+ export type TypingIndicatorVariantProps = VariantProps<
7
+ typeof typingIndicatorDotVariants
8
+ >;
9
+
10
+ export type TypingIndicatorDots = 3 | 4 | 5;
11
+
12
+ export type TypingIndicatorBaseProps = TypingIndicatorVariantProps &
13
+ ComponentPropsWithRef<"span"> & {
14
+ dots?: TypingIndicatorDots;
15
+ label?: ReactNode;
16
+ labelPosition?: "before" | "after";
17
+ children?: ReactNode;
18
+ };
19
+
20
+ export type TypingIndicatorProps = TypingIndicatorBaseProps;
@@ -0,0 +1,75 @@
1
+ "use client";
2
+
3
+ import { cn } from "../../lib/utils";
4
+
5
+ import type { TypingIndicatorBaseProps } from "./types";
6
+ import {
7
+ typingIndicatorDotDelays,
8
+ typingIndicatorDotVariants,
9
+ typingIndicatorDotsVariants,
10
+ typingIndicatorLabelVariants,
11
+ typingIndicatorVariants,
12
+ } from "./variants";
13
+
14
+ export function TypingIndicatorBase({
15
+ appearance,
16
+ size,
17
+ dots = 3,
18
+ label,
19
+ labelPosition = "before",
20
+ className,
21
+ ref,
22
+ ...rest
23
+ }: TypingIndicatorBaseProps) {
24
+ return (
25
+ <span
26
+ ref={ref}
27
+ data-slot="typing-indicator"
28
+ className={cn(typingIndicatorVariants({ size }), className)}
29
+ {...rest}
30
+ >
31
+ {label && labelPosition === "before" && (
32
+ <TypingIndicatorLabel size={size}>{label}</TypingIndicatorLabel>
33
+ )}
34
+ <span
35
+ data-slot="typing-indicator-dots"
36
+ className={typingIndicatorDotsVariants({ size })}
37
+ >
38
+ {Array.from({ length: dots }).map((_, i) => (
39
+ <span
40
+ key={i}
41
+ data-slot="typing-indicator-dot"
42
+ className={cn(
43
+ typingIndicatorDotVariants({ appearance, size }),
44
+ typingIndicatorDotDelays[i % typingIndicatorDotDelays.length],
45
+ )}
46
+ />
47
+ ))}
48
+ </span>
49
+ {label && labelPosition === "after" && (
50
+ <TypingIndicatorLabel size={size}>{label}</TypingIndicatorLabel>
51
+ )}
52
+ </span>
53
+ );
54
+ }
55
+
56
+ TypingIndicatorBase.displayName = "TypingIndicator";
57
+
58
+ export function TypingIndicatorLabel({
59
+ size,
60
+ children,
61
+ }: {
62
+ size?: TypingIndicatorBaseProps["size"];
63
+ children: React.ReactNode;
64
+ }) {
65
+ return (
66
+ <span
67
+ data-slot="typing-indicator-label"
68
+ className={typingIndicatorLabelVariants({ size })}
69
+ >
70
+ {children}
71
+ </span>
72
+ );
73
+ }
74
+
75
+ TypingIndicatorLabel.displayName = "TypingIndicatorLabel";