@flikk/ui 1.0.0-beta.15 → 1.0.0-beta.17

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 (92) hide show
  1. package/README.md +52 -0
  2. package/dist/bg/1.jpg +0 -0
  3. package/dist/bg/10.jpg +0 -0
  4. package/dist/bg/11.jpg +0 -0
  5. package/dist/bg/14.jpg +0 -0
  6. package/dist/bg/15.jpg +0 -0
  7. package/dist/bg/16.jpg +0 -0
  8. package/dist/bg/17.jpg +0 -0
  9. package/dist/bg/18.jpg +0 -0
  10. package/dist/bg/19.jpg +0 -0
  11. package/dist/bg/2.jpg +0 -0
  12. package/dist/bg/20.jpg +0 -0
  13. package/dist/bg/21.jpg +0 -0
  14. package/dist/bg/22.jpg +0 -0
  15. package/dist/bg/23.jpg +0 -0
  16. package/dist/bg/24.jpg +0 -0
  17. package/dist/bg/3.jpg +0 -0
  18. package/dist/bg/4.jpg +0 -0
  19. package/dist/bg/5.jpg +0 -0
  20. package/dist/bg/6.jpg +0 -0
  21. package/dist/bg/7.jpg +0 -0
  22. package/dist/bg/8.jpg +0 -0
  23. package/dist/bg/9.jpg +0 -0
  24. package/dist/bg/bg/1.jpg +0 -0
  25. package/dist/bg/bg/10.jpg +0 -0
  26. package/dist/bg/bg/11.jpg +0 -0
  27. package/dist/bg/bg/14.jpg +0 -0
  28. package/dist/bg/bg/15.jpg +0 -0
  29. package/dist/bg/bg/16.jpg +0 -0
  30. package/dist/bg/bg/17.jpg +0 -0
  31. package/dist/bg/bg/18.jpg +0 -0
  32. package/dist/bg/bg/19.jpg +0 -0
  33. package/dist/bg/bg/2.jpg +0 -0
  34. package/dist/bg/bg/20.jpg +0 -0
  35. package/dist/bg/bg/21.jpg +0 -0
  36. package/dist/bg/bg/22.jpg +0 -0
  37. package/dist/bg/bg/23.jpg +0 -0
  38. package/dist/bg/bg/24.jpg +0 -0
  39. package/dist/bg/bg/3.jpg +0 -0
  40. package/dist/bg/bg/4.jpg +0 -0
  41. package/dist/bg/bg/5.jpg +0 -0
  42. package/dist/bg/bg/6.jpg +0 -0
  43. package/dist/bg/bg/7.jpg +0 -0
  44. package/dist/bg/bg/8.jpg +0 -0
  45. package/dist/bg/bg/9.jpg +0 -0
  46. package/dist/components/ai/StreamingResponse/AnimatedText.js +3 -3
  47. package/dist/components/ai/StreamingResponse/MarkdownRenderer.js +22 -22
  48. package/dist/components/ai/StreamingResponse/StreamingCursor.js +1 -1
  49. package/dist/components/ai/StreamingResponse/StreamingResponse.animations.js +10 -10
  50. package/dist/components/ai/StreamingResponse/StreamingResponse.js +3 -3
  51. package/dist/components/ai/StreamingResponse/WordAnimationContext.d.ts +1 -1
  52. package/dist/components/ai/StreamingResponse/WordAnimationContext.js +11 -11
  53. package/dist/components/ai/index.d.ts +0 -2
  54. package/dist/components/ai/index.js +0 -2
  55. package/dist/components/core/Button/Button.js +1 -1
  56. package/dist/components/core/Calendar/Calendar.js +2 -2
  57. package/dist/components/core/Calendar/Calendar.types.d.ts +1 -1
  58. package/dist/components/core/Card/Card.theme.js +2 -2
  59. package/dist/components/core/Progress/Progress.theme.js +2 -2
  60. package/dist/components/effects/GlassSurface/GlassSurface.js +7 -7
  61. package/dist/components/effects/GlassSurface/GlassSurface.types.d.ts +6 -0
  62. package/dist/components/effects/Neumorphic/InsetCircleButton.d.ts +2 -1
  63. package/dist/components/effects/Neumorphic/InsetCircleButton.js +2 -2
  64. package/dist/components/effects/Neumorphic/InsetPill.d.ts +2 -1
  65. package/dist/components/effects/Neumorphic/InsetPill.js +2 -2
  66. package/dist/components/effects/index.d.ts +2 -2
  67. package/dist/components/effects/index.js +1 -1
  68. package/dist/components/forms/Slider/Slider.js +10 -3
  69. package/dist/components/forms/Slider/Slider.theme.js +3 -3
  70. package/dist/components/forms/Switch/Switch.js +10 -2
  71. package/dist/components/forms/Switch/Switch.theme.js +2 -2
  72. package/dist/components/forms/index.d.ts +0 -3
  73. package/dist/components/forms/index.js +0 -2
  74. package/dist/index.js +1 -3
  75. package/dist/styles.css +1 -1
  76. package/package.json +5 -3
  77. package/dist/components/ai/ThinkingIndicator/ThinkingIndicator.animations.d.ts +0 -10
  78. package/dist/components/ai/ThinkingIndicator/ThinkingIndicator.animations.js +0 -47
  79. package/dist/components/ai/ThinkingIndicator/ThinkingIndicator.d.ts +0 -20
  80. package/dist/components/ai/ThinkingIndicator/ThinkingIndicator.js +0 -44
  81. package/dist/components/ai/ThinkingIndicator/ThinkingIndicator.theme.d.ts +0 -2
  82. package/dist/components/ai/ThinkingIndicator/ThinkingIndicator.theme.js +0 -20
  83. package/dist/components/ai/ThinkingIndicator/ThinkingIndicator.types.d.ts +0 -67
  84. package/dist/components/ai/ThinkingIndicator/index.d.ts +0 -3
  85. package/dist/components/forms/TransferList/TransferList.animations.d.ts +0 -10
  86. package/dist/components/forms/TransferList/TransferList.animations.js +0 -32
  87. package/dist/components/forms/TransferList/TransferList.d.ts +0 -28
  88. package/dist/components/forms/TransferList/TransferList.js +0 -199
  89. package/dist/components/forms/TransferList/TransferList.theme.d.ts +0 -6
  90. package/dist/components/forms/TransferList/TransferList.theme.js +0 -60
  91. package/dist/components/forms/TransferList/TransferList.types.d.ts +0 -101
  92. package/dist/components/forms/TransferList/index.d.ts +0 -3
package/README.md CHANGED
@@ -1 +1,53 @@
1
1
  # Flikkui
2
+
3
+ A modern React component library built with TypeScript, Tailwind CSS v4, and Framer Motion. 150+ components following the shadcn philosophy with complete `className` override support.
4
+
5
+ ## MCP Server
6
+
7
+ Flikkui ships with an MCP (Model Context Protocol) server that gives AI coding tools full knowledge of the component library — component APIs, props, theme tokens, and code generation.
8
+
9
+ ### What It Does
10
+
11
+ | Tool | Description |
12
+ |------|-------------|
13
+ | `get_component` | Look up any component's full API — props, types, sub-components, theme tokens, and code examples |
14
+ | `search_components` | Find components by name, category (`core`, `forms`, `charts`, etc.), or pattern type (`compound`, `simple`, etc.) |
15
+ | `get_theme_tokens` | Get all CSS variables with correct Tailwind syntax (`bg-[var(--color-primary)]`) |
16
+ | `generate_code` | Generate production-ready Flikkui code from a description |
17
+
18
+ ### Setup for Claude Code
19
+
20
+ Add the following to your project's `.mcp.json`:
21
+
22
+ ```json
23
+ {
24
+ "mcpServers": {
25
+ "flikkui": {
26
+ "command": "npx",
27
+ "args": ["@flikk/mcp"]
28
+ }
29
+ }
30
+ }
31
+ ```
32
+
33
+ Or if you're working from a local clone of this repo:
34
+
35
+ ```json
36
+ {
37
+ "mcpServers": {
38
+ "flikkui": {
39
+ "command": "node",
40
+ "args": ["./packages/mcp/dist/index.js"]
41
+ }
42
+ }
43
+ }
44
+ ```
45
+
46
+ ### Building from Source
47
+
48
+ ```bash
49
+ cd packages/mcp
50
+ npm install
51
+ npm run extract # Parse component source files into registry.json
52
+ npm run build # Compile TypeScript
53
+ ```
package/dist/bg/1.jpg ADDED
Binary file
package/dist/bg/10.jpg ADDED
Binary file
package/dist/bg/11.jpg ADDED
Binary file
package/dist/bg/14.jpg ADDED
Binary file
package/dist/bg/15.jpg ADDED
Binary file
package/dist/bg/16.jpg ADDED
Binary file
package/dist/bg/17.jpg ADDED
Binary file
package/dist/bg/18.jpg ADDED
Binary file
package/dist/bg/19.jpg ADDED
Binary file
package/dist/bg/2.jpg ADDED
Binary file
package/dist/bg/20.jpg ADDED
Binary file
package/dist/bg/21.jpg ADDED
Binary file
package/dist/bg/22.jpg ADDED
Binary file
package/dist/bg/23.jpg ADDED
Binary file
package/dist/bg/24.jpg ADDED
Binary file
package/dist/bg/3.jpg ADDED
Binary file
package/dist/bg/4.jpg ADDED
Binary file
package/dist/bg/5.jpg ADDED
Binary file
package/dist/bg/6.jpg ADDED
Binary file
package/dist/bg/7.jpg ADDED
Binary file
package/dist/bg/8.jpg ADDED
Binary file
package/dist/bg/9.jpg ADDED
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -17,7 +17,7 @@ const tokenize = (text) => {
17
17
  * For performance, only the last N tokens are animated with motion.span,
18
18
  * while older tokens are rendered as static text.
19
19
  */
20
- const AnimatedText = ({ text, isStreaming, animateLastN = 6, enabled = true, className, }) => {
20
+ const AnimatedText = ({ text, isStreaming, animateLastN = 12, enabled = true, className, }) => {
21
21
  const shouldReduceMotion = useReducedMotion();
22
22
  const animate = enabled && !shouldReduceMotion;
23
23
  // Track which tokens have already been seen/animated
@@ -37,9 +37,9 @@ const AnimatedText = ({ text, isStreaming, animateLastN = 6, enabled = true, cla
37
37
  const animatedTokens = tokens.slice(settledCount);
38
38
  if (!animate || !isStreaming) {
39
39
  // No animation: render plain text
40
- return (jsx("p", { className: className || 'whitespace-pre-wrap break-words', children: text }));
40
+ return (jsx("p", { className: className || 'whitespace-pre-wrap wrap-break-word', children: text }));
41
41
  }
42
- return (jsxs("p", { className: className || 'whitespace-pre-wrap break-words', children: [settledText, animatedTokens.map((token, i) => (jsx(motion.span, { variants: tokenFadeIn, initial: "hidden", animate: "visible", transition: tokenTransition, style: { display: 'inline' }, children: token }, `${settledCount + i}-${token}`)))] }));
42
+ return (jsxs("p", { className: className || 'whitespace-pre-wrap wrap-break-word', children: [settledText, animatedTokens.map((token, i) => (jsx(motion.span, { variants: tokenFadeIn, initial: "hidden", animate: "visible", transition: tokenTransition, style: { display: 'inline' }, children: token }, `${settledCount + i}-${token}`)))] }));
43
43
  };
44
44
  AnimatedText.displayName = 'AnimatedText';
45
45
 
@@ -51,13 +51,13 @@ const SkipWords = ({ children }) => {
51
51
  * Supports GitHub Flavored Markdown (tables, task lists, strikethrough, etc.)
52
52
  * Animates individual words during streaming with a fade-in + blur effect
53
53
  */
54
- const MarkdownRenderer = ({ content, options = {}, isStreaming = false, animated = true, showCursor = true, animateLastN = 6, }) => {
54
+ const MarkdownRenderer = ({ content, options = {}, isStreaming = false, animated = true, showCursor = true, animateLastN = 12, }) => {
55
55
  const { allowHtml = false, syntaxTheme = 'light', renderCodeBlock } = options;
56
56
  const shouldReduceMotion = useReducedMotion();
57
57
  const shouldAnimate = animated && isStreaming && !shouldReduceMotion;
58
58
  // Append cursor character to content so it renders inline within the last element
59
59
  const displayContent = isStreaming && showCursor
60
- ? content + ' '
60
+ ? content + ' '
61
61
  : content;
62
62
  const markdownComponents = useMemo(() => ({
63
63
  // Code blocks with syntax highlighting
@@ -73,75 +73,75 @@ const MarkdownRenderer = ({ content, options = {}, isStreaming = false, animated
73
73
  return (jsxs(AnimatedBlock, { animate: shouldAnimate, children: [jsx(SkipWords, { children: children }), jsx(Prism, { style: syntaxTheme === 'dark' ? oneDark : oneLight, language: language, PreTag: "div", className: "rounded-lg my-3", ...props, children: String(children).replace(/\n$/, '') })] }));
74
74
  }
75
75
  // Inline code — skip word animation for code tokens
76
- return (jsxs(Fragment, { children: [jsx(SkipWords, { children: children }), jsx("code", { className: "bg-[var(--color-background-tertiary)] text-[var(--color-primary)] px-1.5 py-0.5 rounded text-base font-mono", ...props, children: children })] }));
76
+ return (jsxs(Fragment, { children: [jsx(SkipWords, { children: children }), jsx("code", { className: "bg-(--color-background-tertiary) text-(--color-primary) px-1.5 py-0.5 rounded text-base font-mono", ...props, children: children })] }));
77
77
  },
78
78
  // Paragraphs — word-level animation
79
79
  p({ children }) {
80
- return (jsx(AnimatedProse, { as: "p", className: "mb-3 last:mb-0 text-[var(--color-text-primary)] leading-relaxed", children: children }));
80
+ return (jsx(AnimatedProse, { as: "p", className: "mb-3 last:mb-0 text-(--color-text-primary) leading-relaxed", children: children }));
81
81
  },
82
82
  // Headings — word-level animation
83
83
  h1({ children }) {
84
- return (jsx(AnimatedProse, { as: "h1", className: "text-2xl font-bold mb-4 text-[var(--color-text-primary)] border-b border-[var(--color-border)] pb-2", children: children }));
84
+ return (jsx(AnimatedProse, { as: "h1", className: "text-2xl font-bold mb-4 text-(--color-text-primary) border-b border-(--color-border) pb-2", children: children }));
85
85
  },
86
86
  h2({ children }) {
87
- return (jsx(AnimatedProse, { as: "h2", className: "text-2xl font-bold mb-3 text-[var(--color-text-primary)] border-b border-[var(--color-border)] pb-2", children: children }));
87
+ return (jsx(AnimatedProse, { as: "h2", className: "text-2xl font-bold mb-3 text-(--color-text-primary) border-b border-(--color-border) pb-2", children: children }));
88
88
  },
89
89
  h3({ children }) {
90
- return (jsx(AnimatedProse, { as: "h3", className: "text-xl font-semibold mb-2 text-[var(--color-text-primary)]", children: children }));
90
+ return (jsx(AnimatedProse, { as: "h3", className: "text-xl font-semibold mb-2 text-(--color-text-primary)", children: children }));
91
91
  },
92
92
  h4({ children }) {
93
- return (jsx(AnimatedProse, { as: "h4", className: "text-lg font-semibold mb-2 text-[var(--color-text-primary)]", children: children }));
93
+ return (jsx(AnimatedProse, { as: "h4", className: "text-lg font-semibold mb-2 text-(--color-text-primary)", children: children }));
94
94
  },
95
95
  h5({ children }) {
96
- return (jsx(AnimatedProse, { as: "h5", className: "text-base font-semibold mb-2 text-[var(--color-text-primary)]", children: children }));
96
+ return (jsx(AnimatedProse, { as: "h5", className: "text-base font-semibold mb-2 text-(--color-text-primary)", children: children }));
97
97
  },
98
98
  h6({ children }) {
99
- return (jsx(AnimatedProse, { as: "h6", className: "text-base font-semibold mb-2 text-[var(--color-text-secondary)]", children: children }));
99
+ return (jsx(AnimatedProse, { as: "h6", className: "text-base font-semibold mb-2 text-(--color-text-secondary)", children: children }));
100
100
  },
101
101
  // Lists — word-level animation on li
102
102
  ul({ children }) {
103
- return (jsx("ul", { className: "list-disc list-inside mb-3 space-y-1 text-[var(--color-text-primary)]", children: children }));
103
+ return (jsx("ul", { className: "list-disc list-inside mb-3 space-y-1 text-(--color-text-primary)", children: children }));
104
104
  },
105
105
  ol({ children }) {
106
- return (jsx("ol", { className: "list-decimal list-inside mb-3 space-y-1 text-[var(--color-text-primary)]", children: children }));
106
+ return (jsx("ol", { className: "list-decimal list-inside mb-3 space-y-1 text-(--color-text-primary)", children: children }));
107
107
  },
108
108
  li({ children }) {
109
109
  return (jsx(AnimatedProse, { as: "li", className: "ml-4", children: children }));
110
110
  },
111
111
  // Blockquotes — word-level animation
112
112
  blockquote({ children }) {
113
- return (jsx("blockquote", { className: "border-l-4 border-[var(--color-primary)] pl-4 py-2 my-3 bg-[var(--color-background-secondary)] italic text-[var(--color-text-secondary)]", children: children }));
113
+ return (jsx("blockquote", { className: "border-l-4 border-(--color-primary) pl-4 py-2 my-3 bg-(--color-background-secondary) italic text-(--color-text-secondary)", children: children }));
114
114
  },
115
115
  // Links
116
116
  a({ href, children }) {
117
- return (jsx("a", { href: href, className: "text-[var(--color-primary)] hover:text-[var(--color-primary-700)] underline transition-colors", target: "_blank", rel: "noopener noreferrer", children: children }));
117
+ return (jsx("a", { href: href, className: "text-(--color-primary) hover:text-(--color-primary-700) underline transition-colors", target: "_blank", rel: "noopener noreferrer", children: children }));
118
118
  },
119
119
  // Tables — block-level slide-in, skip word animation
120
120
  table({ children }) {
121
- return (jsxs(AnimatedBlock, { animate: shouldAnimate, children: [jsx(SkipWords, { children: children }), jsx("div", { className: "overflow-x-auto my-3", children: jsx("table", { className: "min-w-full border-collapse border border-[var(--color-border)]", children: children }) })] }));
121
+ return (jsxs(AnimatedBlock, { animate: shouldAnimate, children: [jsx(SkipWords, { children: children }), jsx("div", { className: "overflow-x-auto my-3", children: jsx("table", { className: "min-w-full border-collapse border border-(--color-border)", children: children }) })] }));
122
122
  },
123
123
  thead({ children }) {
124
- return jsx("thead", { className: "bg-[var(--color-background-secondary)]", children: children });
124
+ return jsx("thead", { className: "bg-(--color-background-secondary)", children: children });
125
125
  },
126
126
  tbody({ children }) {
127
127
  return jsx("tbody", { children: children });
128
128
  },
129
129
  tr({ children }) {
130
- return jsx("tr", { className: "border-b border-[var(--color-border)]", children: children });
130
+ return jsx("tr", { className: "border-b border-(--color-border)", children: children });
131
131
  },
132
132
  th({ children }) {
133
- return (jsx("th", { className: "px-4 py-2 text-left font-semibold text-[var(--color-text-primary)] border border-[var(--color-border)]", children: children }));
133
+ return (jsx("th", { className: "px-4 py-2 text-left font-semibold text-(--color-text-primary) border border-(--color-border)", children: children }));
134
134
  },
135
135
  td({ children }) {
136
- return (jsx("td", { className: "px-4 py-2 text-[var(--color-text-primary)] border border-[var(--color-border)]", children: children }));
136
+ return (jsx("td", { className: "px-4 py-2 text-(--color-text-primary) border border-(--color-border)", children: children }));
137
137
  },
138
138
  // Horizontal rule
139
139
  hr() {
140
- return jsx("hr", { className: "my-4 border-t border-[var(--color-border)]" });
140
+ return jsx("hr", { className: "my-4 border-t border-(--color-border)" });
141
141
  },
142
142
  // Strong/Bold — pass through (word animation handles inline elements)
143
143
  strong({ children }) {
144
- return jsx("strong", { className: "font-semibold text-[var(--color-text-primary)]", children: children });
144
+ return jsx("strong", { className: "font-semibold text-(--color-text-primary)", children: children });
145
145
  },
146
146
  // Emphasis/Italic
147
147
  em({ children }) {
@@ -149,7 +149,7 @@ const MarkdownRenderer = ({ content, options = {}, isStreaming = false, animated
149
149
  },
150
150
  // Strikethrough (from remarkGfm)
151
151
  del({ children }) {
152
- return jsx("del", { className: "line-through text-[var(--color-text-secondary)]", children: children });
152
+ return jsx("del", { className: "line-through text-(--color-text-secondary)", children: children });
153
153
  },
154
154
  }), [shouldAnimate, syntaxTheme, renderCodeBlock]);
155
155
  return (jsx(WordAnimationProvider, { content: displayContent, enabled: shouldAnimate, animateLastN: animateLastN, hasCursor: isStreaming && showCursor, children: jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], skipHtml: !allowHtml, components: markdownComponents, children: displayContent }) }));
@@ -4,7 +4,7 @@ import { jsx } from 'react/jsx-runtime';
4
4
  * StreamingCursor renders a blinking caret that indicates active streaming.
5
5
  * Uses a simple CSS pulse animation — no framer motion, no layout shifts.
6
6
  */
7
- const StreamingCursor = ({ visible, enabled = true, cursor = "", className, }) => {
7
+ const StreamingCursor = ({ visible, enabled = true, cursor = "", className, }) => {
8
8
  if (!visible)
9
9
  return null;
10
10
  return (jsx("span", { className: className || `font-extralight ml-0.5 ${enabled ? "animate-pulse" : ""}`, "aria-hidden": "true", children: cursor }));
@@ -9,8 +9,8 @@
9
9
  const tokenFadeIn = {
10
10
  hidden: {
11
11
  opacity: 0,
12
- y: 6,
13
- filter: 'blur(4px)',
12
+ y: 4,
13
+ filter: 'blur(1.5px)',
14
14
  },
15
15
  visible: {
16
16
  opacity: 1,
@@ -19,8 +19,8 @@ const tokenFadeIn = {
19
19
  },
20
20
  };
21
21
  const tokenTransition = {
22
- duration: 0.35,
23
- ease: [0.25, 0.4, 0.55, 1],
22
+ duration: 0.25,
23
+ ease: [0.2, 0.8, 0.2, 1], // snappy easing
24
24
  };
25
25
  /**
26
26
  * Block slide-in animation
@@ -29,7 +29,7 @@ const tokenTransition = {
29
29
  const blockSlideIn = {
30
30
  hidden: {
31
31
  opacity: 0,
32
- y: 8,
32
+ y: 6,
33
33
  },
34
34
  visible: {
35
35
  opacity: 1,
@@ -37,8 +37,8 @@ const blockSlideIn = {
37
37
  },
38
38
  };
39
39
  const blockTransition = {
40
- duration: 0.4,
41
- ease: [0.25, 0.4, 0.55, 1],
40
+ duration: 0.35,
41
+ ease: [0.2, 0.8, 0.2, 1],
42
42
  };
43
43
  /**
44
44
  * Streaming cursor (caret) animation
@@ -62,7 +62,7 @@ const cursorPulse = {
62
62
  const inlineTokenFadeIn = {
63
63
  hidden: {
64
64
  opacity: 0,
65
- filter: 'blur(3px)',
65
+ filter: 'blur(1.5px)',
66
66
  },
67
67
  visible: {
68
68
  opacity: 1,
@@ -70,8 +70,8 @@ const inlineTokenFadeIn = {
70
70
  },
71
71
  };
72
72
  const inlineTokenTransition = {
73
- duration: 0.3,
74
- ease: [0.25, 0.4, 0.55, 1],
73
+ duration: 0.25,
74
+ ease: [0.2, 0.8, 0.2, 1],
75
75
  };
76
76
  /**
77
77
  * Container animation for staggered children
@@ -39,7 +39,7 @@ onToken, onComplete, onError, onStart, onAbort,
39
39
  // Display options
40
40
  typingSpeed = 100, enableTypewriter = true, enableMarkdown = true, markdownOptions,
41
41
  // Animation
42
- animated = true, showCursor = true, animateLastN = 6,
42
+ animated = true, showCursor = true, animateLastN = 12,
43
43
  // Message component props
44
44
  role = 'assistant', avatar, showTimestamp = true, showActions = true, onCopy, onRegenerate,
45
45
  // Error handling
@@ -80,11 +80,11 @@ className, }) => {
80
80
  }
81
81
  else if (enableTypewriter && isComplete && accumulatedText) {
82
82
  // Use typewriter animation after streaming completes
83
- messageContent = (jsx(TypeWriter, { text: accumulatedText, speed: typingSpeed, enabled: true, className: "whitespace-pre-wrap break-words" }));
83
+ messageContent = (jsx(TypeWriter, { text: accumulatedText, speed: typingSpeed, enabled: true, className: "whitespace-pre-wrap wrap-break-word" }));
84
84
  }
85
85
  else {
86
86
  // Show raw text (streaming complete, typewriter disabled)
87
- messageContent = (jsx("p", { className: "whitespace-pre-wrap break-words", children: accumulatedText }));
87
+ messageContent = (jsx("p", { className: "whitespace-pre-wrap wrap-break-word", children: accumulatedText }));
88
88
  }
89
89
  // Render with Message component
90
90
  return (jsx(Message, { role: role, content: messageContent, avatar: avatar, timestamp: startTimeRef.current, showTimestamp: showTimestamp, isStreaming: isStreaming, showActions: showActions && !error, onCopy: onCopy, onRegenerate: onRegenerate, className: className }));
@@ -4,7 +4,7 @@
4
4
  * inside markdown-rendered content. Works like AnimatedText but across
5
5
  * all markdown elements (paragraphs, headings, lists, blockquotes, etc.).
6
6
  */
7
- import React from 'react';
7
+ import React from "react";
8
8
  interface WordAnimationContextValue {
9
9
  /** Process children of a prose element, animating recent words */
10
10
  processChildren: (children: React.ReactNode) => React.ReactNode;
@@ -18,7 +18,7 @@ const tokenize = (text) => {
18
18
  const countWordsInChildren = (children) => {
19
19
  let count = 0;
20
20
  React__default.Children.forEach(children, (child) => {
21
- if (typeof child === 'string') {
21
+ if (typeof child === "string") {
22
22
  count += tokenize(child).length;
23
23
  }
24
24
  else if (React__default.isValidElement(child)) {
@@ -30,12 +30,12 @@ const countWordsInChildren = (children) => {
30
30
  });
31
31
  return count;
32
32
  };
33
- const WordAnimationProvider = ({ children, content, enabled, animateLastN = 6, hasCursor = false, }) => {
33
+ const WordAnimationProvider = ({ children, content, enabled, animateLastN = 12, hasCursor = false, }) => {
34
34
  const settledCountRef = useRef(0);
35
35
  // Count total prose words in the raw content
36
36
  const totalWords = useMemo(() => {
37
37
  // Strip the cursor character before counting
38
- const cleanContent = hasCursor ? content.replace(/\s*▍\s*$/, '') : content;
38
+ const cleanContent = hasCursor ? content.replace(/\s*▏\s*$/, "") : content;
39
39
  return tokenize(cleanContent).length;
40
40
  }, [content, hasCursor]);
41
41
  // Update settled count — words that have aged out of the animation window
@@ -59,7 +59,7 @@ const WordAnimationProvider = ({ children, content, enabled, animateLastN = 6, h
59
59
  */
60
60
  const processChildren = (children) => {
61
61
  return React__default.Children.map(children, (child) => {
62
- if (typeof child === 'string') {
62
+ if (typeof child === "string") {
63
63
  return processTextNode(child);
64
64
  }
65
65
  if (React__default.isValidElement(child)) {
@@ -82,18 +82,18 @@ const WordAnimationProvider = ({ children, content, enabled, animateLastN = 6, h
82
82
  if (tokens.length === 0)
83
83
  return text;
84
84
  const result = [];
85
- let staticBuffer = '';
85
+ let staticBuffer = "";
86
86
  for (const token of tokens) {
87
87
  const currentIndex = wordIndexRef.current;
88
88
  wordIndexRef.current++;
89
89
  // Check if this is the cursor character
90
- if (token.trim() === '▍') {
90
+ if (token.trim() === "▏") {
91
91
  // Flush static buffer
92
92
  if (staticBuffer) {
93
93
  result.push(staticBuffer);
94
- staticBuffer = '';
94
+ staticBuffer = "";
95
95
  }
96
- result.push(jsx("span", { className: "animate-pulse font-light", "aria-hidden": "true", children: "\u258D" }, "streaming-cursor"));
96
+ result.push(jsx("span", { className: "animate-pulse font-light", "aria-hidden": "true", children: "\u258F" }, "streaming-cursor"));
97
97
  continue;
98
98
  }
99
99
  if (currentIndex < settledCount) {
@@ -104,10 +104,10 @@ const WordAnimationProvider = ({ children, content, enabled, animateLastN = 6, h
104
104
  // Flush static buffer before animated tokens
105
105
  if (staticBuffer) {
106
106
  result.push(staticBuffer);
107
- staticBuffer = '';
107
+ staticBuffer = "";
108
108
  }
109
109
  // Animated word
110
- result.push(jsx(motion.span, { variants: inlineTokenFadeIn, initial: "hidden", animate: "visible", transition: inlineTokenTransition, style: { display: 'inline' }, children: token }, `word-${currentIndex}-${token.trim()}`));
110
+ result.push(jsx(motion.span, { variants: inlineTokenFadeIn, initial: "hidden", animate: "visible", transition: inlineTokenTransition, style: { display: "inline" }, children: token }, `word-${currentIndex}-${token.trim()}`));
111
111
  }
112
112
  }
113
113
  // Flush any remaining static buffer
@@ -129,6 +129,6 @@ const WordAnimationProvider = ({ children, content, enabled, animateLastN = 6, h
129
129
  }, [enabled, settledCount, totalWords]);
130
130
  return (jsx(WordAnimationContext.Provider, { value: contextValue, children: children }));
131
131
  };
132
- WordAnimationProvider.displayName = 'WordAnimationProvider';
132
+ WordAnimationProvider.displayName = "WordAnimationProvider";
133
133
 
134
134
  export { WordAnimationProvider, useWordAnimation };
@@ -2,8 +2,6 @@ export { Message, messageTheme } from "../core/Message";
2
2
  export type { MessageProps, MessageRole, MessageVariant, MessageAvatarProps, MessageTheme, MessageThemeOverrides, } from "../core/Message";
3
3
  export { PromptInput, promptInputTheme } from "./PromptInput";
4
4
  export type { PromptInputProps, PromptInputState, ModelOption, PromptInputTheme, PromptInputThemeOverrides, } from "./PromptInput";
5
- export { ThinkingIndicator, thinkingIndicatorTheme } from "./ThinkingIndicator";
6
- export type { ThinkingIndicatorProps, ThinkingIndicatorSize, ThinkingIndicatorTheme, ThinkingIndicatorThemeOverrides, } from "./ThinkingIndicator";
7
5
  export { TokenCounter, tokenCounterTheme, estimateTokens, calculateCost, formatCost, formatTokenCount, MODEL_CONFIGS, } from "./TokenCounter";
8
6
  export type { TokenCounterProps, TokenCounterModel, TokenCounterSize, TokenCounterTheme, TokenCounterThemeOverrides, ModelConfig, } from "./TokenCounter";
9
7
  export { PromptSuggestion, promptSuggestionTheme } from "./PromptSuggestions";
@@ -12,8 +12,6 @@ import '@heroicons/react/24/outline';
12
12
  import '@heroicons/react/24/solid';
13
13
  export { PromptInput } from './PromptInput/PromptInput.js';
14
14
  export { promptInputTheme } from './PromptInput/PromptInput.theme.js';
15
- export { ThinkingIndicator } from './ThinkingIndicator/ThinkingIndicator.js';
16
- export { thinkingIndicatorTheme } from './ThinkingIndicator/ThinkingIndicator.theme.js';
17
15
  export { TokenCounter } from './TokenCounter/TokenCounter.js';
18
16
  export { tokenCounterTheme } from './TokenCounter/TokenCounter.theme.js';
19
17
  export { MODEL_CONFIGS, calculateCost, estimateTokens, formatCost, formatTokenCount } from './TokenCounter/tokenUtils.js';
@@ -104,7 +104,7 @@ const Button = React__default.forwardRef(({ children, className = "", iconOnly =
104
104
  node;
105
105
  }
106
106
  }, [buttonRef]);
107
- return (jsxs(motion.button, { ...restProps, ...animationProps, ref: mergedRef, type: "button", className: cn(buttonTheme.baseStyle, colorClasses, variantClasses, sizeClasses, blockStyle, stateClasses, darkMode && "dark", className), disabled: isDisabled, "data-state": state, "data-color": resolvedColor, "data-variant": resolvedVariant, "data-size": size, "data-icon-only": iconOnly ? "true" : "false", "data-block": block ? "true" : "false", "aria-disabled": isDisabled || undefined, "aria-invalid": isError || undefined, "aria-label": ariaLabel, onClick: handleClick, children: [showReflection &&
107
+ return (jsxs(motion.button, { type: "button", ...restProps, ...animationProps, ref: mergedRef, className: cn(buttonTheme.baseStyle, colorClasses, variantClasses, sizeClasses, blockStyle, stateClasses, darkMode && "dark", className), disabled: isDisabled, "data-state": state, "data-color": resolvedColor, "data-variant": resolvedVariant, "data-size": size, "data-icon-only": iconOnly ? "true" : "false", "data-block": block ? "true" : "false", "aria-disabled": isDisabled || undefined, "aria-invalid": isError || undefined, "aria-label": ariaLabel, onClick: handleClick, children: [showReflection &&
108
108
  resolvedVariant !== "link" &&
109
109
  resolvedVariant !== "outline" && (jsx("div", { className: "absolute top-0.25 right-0.25 left-0.25 h-3 border-t-[0.5px] border-white/40 rounded-t-[calc(var(--button-radius)-1.25px)] opacity-60" })), isLoading && (jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: jsx(Spinner, { size: "sm", color: color, className: spinnerClassName }) })), jsx("span", { className: cn("inline-flex items-center gap-2 whitespace-nowrap", isLoading && "opacity-0"), children: children }), enableRipple &&
110
110
  ripples.map((ripple) => {
@@ -225,7 +225,7 @@ const Calendar = React__default.forwardRef(({ mode = 'single', value, defaultVal
225
225
  const currentDate = new Date();
226
226
  const defaultYearRange = {
227
227
  start: currentDate.getFullYear() - 100,
228
- end: currentDate.getFullYear(),
228
+ end: currentDate.getFullYear() + 10,
229
229
  };
230
230
  const actualYearRange = yearRange || defaultYearRange;
231
231
  const yearOptions = useMemo(() => {
@@ -236,7 +236,7 @@ const Calendar = React__default.forwardRef(({ mode = 'single', value, defaultVal
236
236
  startYear = Math.max(startYear, minDate.getFullYear());
237
237
  }
238
238
  if (maxDate) {
239
- endYear = Math.min(endYear, maxDate.getFullYear());
239
+ endYear = Math.max(endYear, maxDate.getFullYear());
240
240
  }
241
241
  const options = [];
242
242
  for (let year = endYear; year >= startYear; year--) {
@@ -70,7 +70,7 @@ export interface CalendarProps extends Omit<React.HTMLAttributes<HTMLDivElement>
70
70
  enableMonthDropdown?: boolean;
71
71
  /** Whether to enable year dropdown instead of navigation arrows (default: true) */
72
72
  enableYearDropdown?: boolean;
73
- /** Year range for dropdown selection (default: ±50 years from current) */
73
+ /** Year range for dropdown selection (default: 100 years past to 10 years future from current year) */
74
74
  yearRange?: {
75
75
  start: number;
76
76
  end: number;
@@ -3,8 +3,8 @@ const cardTheme = {
3
3
  headerStyle: "flex flex-col p-6",
4
4
  titleStyle: "text-lg font-semibold leading-none text-[var(--color-text-primary)]",
5
5
  subtitleStyle: "text-base text-[var(--color-text-muted)] mt-1.5",
6
- bodyStyle: "p-6 pt-0",
7
- footerStyle: "flex items-center p-6 pt-0",
6
+ bodyStyle: "p-6 pt-0 first:pt-6",
7
+ footerStyle: "flex items-center p-6 pt-0 first:pt-6",
8
8
  };
9
9
 
10
10
  export { cardTheme };
@@ -18,8 +18,8 @@ const progressTheme = {
18
18
  md: "h-2.5",
19
19
  lg: "h-4",
20
20
  },
21
- // Indeterminate animation styles (striped pattern by default)
22
- indeterminateStyle: "animate-[progress-indeterminate_1.8s_linear_infinite] bg-[repeating-linear-gradient(45deg,var(--color-primary),var(--color-primary)_10px,var(--color-primary-700)_10px,var(--color-primary-700)_20px)]",
21
+ // Indeterminate animation styles
22
+ indeterminateStyle: "animate-[progress-indeterminate_1.8s_linear_infinite]",
23
23
  };
24
24
 
25
25
  export { progressTheme };