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

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 (42) hide show
  1. package/README.md +52 -0
  2. package/dist/components/ai/StreamingResponse/AnimatedText.js +3 -3
  3. package/dist/components/ai/StreamingResponse/MarkdownRenderer.js +22 -22
  4. package/dist/components/ai/StreamingResponse/StreamingCursor.js +1 -1
  5. package/dist/components/ai/StreamingResponse/StreamingResponse.animations.js +10 -10
  6. package/dist/components/ai/StreamingResponse/StreamingResponse.js +3 -3
  7. package/dist/components/ai/StreamingResponse/WordAnimationContext.d.ts +1 -1
  8. package/dist/components/ai/StreamingResponse/WordAnimationContext.js +11 -11
  9. package/dist/components/ai/index.d.ts +0 -2
  10. package/dist/components/ai/index.js +0 -2
  11. package/dist/components/core/Progress/Progress.theme.js +2 -2
  12. package/dist/components/effects/GlassSurface/GlassSurface.js +7 -7
  13. package/dist/components/effects/GlassSurface/GlassSurface.types.d.ts +6 -0
  14. package/dist/components/effects/Neumorphic/InsetCircleButton.d.ts +2 -1
  15. package/dist/components/effects/Neumorphic/InsetCircleButton.js +2 -2
  16. package/dist/components/effects/Neumorphic/InsetPill.d.ts +2 -1
  17. package/dist/components/effects/Neumorphic/InsetPill.js +2 -2
  18. package/dist/components/forms/Slider/Slider.js +10 -3
  19. package/dist/components/forms/Slider/Slider.theme.js +3 -3
  20. package/dist/components/forms/Switch/Switch.js +10 -2
  21. package/dist/components/forms/Switch/Switch.theme.js +2 -2
  22. package/dist/components/forms/index.d.ts +0 -3
  23. package/dist/components/forms/index.js +0 -2
  24. package/dist/index.js +0 -2
  25. package/dist/styles.css +1 -1
  26. package/package.json +1 -1
  27. package/dist/components/ai/ThinkingIndicator/ThinkingIndicator.animations.d.ts +0 -10
  28. package/dist/components/ai/ThinkingIndicator/ThinkingIndicator.animations.js +0 -47
  29. package/dist/components/ai/ThinkingIndicator/ThinkingIndicator.d.ts +0 -20
  30. package/dist/components/ai/ThinkingIndicator/ThinkingIndicator.js +0 -44
  31. package/dist/components/ai/ThinkingIndicator/ThinkingIndicator.theme.d.ts +0 -2
  32. package/dist/components/ai/ThinkingIndicator/ThinkingIndicator.theme.js +0 -20
  33. package/dist/components/ai/ThinkingIndicator/ThinkingIndicator.types.d.ts +0 -67
  34. package/dist/components/ai/ThinkingIndicator/index.d.ts +0 -3
  35. package/dist/components/forms/TransferList/TransferList.animations.d.ts +0 -10
  36. package/dist/components/forms/TransferList/TransferList.animations.js +0 -32
  37. package/dist/components/forms/TransferList/TransferList.d.ts +0 -28
  38. package/dist/components/forms/TransferList/TransferList.js +0 -199
  39. package/dist/components/forms/TransferList/TransferList.theme.d.ts +0 -6
  40. package/dist/components/forms/TransferList/TransferList.theme.js +0 -60
  41. package/dist/components/forms/TransferList/TransferList.types.d.ts +0 -101
  42. 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
+ ```
@@ -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';
@@ -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 };
@@ -23,7 +23,7 @@ const useDarkMode = () => {
23
23
  * Creates a realistic chromatic aberration glass effect using SVG filters.
24
24
  * Works as a wrapper for any content.
25
25
  */
26
- const GlassSurface = React__default.forwardRef(({ children, width, height, borderRadius = 20, borderWidth = 0.07, brightness: brightnessProp, opacity: opacityProp, blur: blurProp, displace: displaceProp, backgroundOpacity: backgroundOpacityProp, backgroundColor, saturation: saturationProp, distortionScale: distortionScaleProp, redOffset = 0, greenOffset = 10, blueOffset = 20, xChannel = "R", yChannel = "G", mixBlendMode: mixBlendModeProp, colorScheme = "auto", frosted = false, className = "", style = {}, }, forwardedRef) => {
26
+ const GlassSurface = React__default.forwardRef(({ children, width, height, borderRadius = 20, borderWidth = 0.07, brightness: brightnessProp, opacity: opacityProp, blur: blurProp, displace: displaceProp, backgroundOpacity: backgroundOpacityProp, backgroundColor, saturation: saturationProp, distortionScale: distortionScaleProp, redOffset = 0, greenOffset = 10, blueOffset = 20, xChannel = "R", yChannel = "G", mixBlendMode: mixBlendModeProp, colorScheme = "auto", backdropBrightness = 1, frosted = false, className = "", style = {}, }, forwardedRef) => {
27
27
  const uniqueId = useId().replace(/:/g, "-");
28
28
  const filterId = `glass-filter-${uniqueId}`;
29
29
  const redGradId = `red-grad-${uniqueId}`;
@@ -66,11 +66,11 @@ const GlassSurface = React__default.forwardRef(({ children, width, height, borde
66
66
  <svg viewBox="0 0 ${actualWidth} ${actualHeight}" xmlns="http://www.w3.org/2000/svg">
67
67
  <defs>
68
68
  <linearGradient id="${redGradId}" x1="100%" y1="0%" x2="0%" y2="0%">
69
- <stop offset="0%" stop-color="#0000"/>
69
+ <stop offset="0%" stop-color="#000"/>
70
70
  <stop offset="100%" stop-color="red"/>
71
71
  </linearGradient>
72
72
  <linearGradient id="${blueGradId}" x1="0%" y1="0%" x2="0%" y2="100%">
73
- <stop offset="0%" stop-color="#0000"/>
73
+ <stop offset="0%" stop-color="#000"/>
74
74
  <stop offset="100%" stop-color="blue"/>
75
75
  </linearGradient>
76
76
  </defs>
@@ -186,8 +186,8 @@ const GlassSurface = React__default.forwardRef(({ children, width, height, borde
186
186
  return {
187
187
  ...baseStyles,
188
188
  background: getBackgroundWithOpacity(),
189
- backdropFilter: `url(#${filterId}) ${frostedBlur} saturate(${saturation})`,
190
- WebkitBackdropFilter: `url(#${filterId}) ${frostedBlur} saturate(${saturation})`,
189
+ backdropFilter: `url(#${filterId}) ${frostedBlur} brightness(${backdropBrightness}) saturate(${saturation})`,
190
+ WebkitBackdropFilter: `url(#${filterId}) ${frostedBlur} brightness(${backdropBrightness}) saturate(${saturation})`,
191
191
  ...(!resolvedDark && { border: "1px solid rgba(0, 0, 0, 0.06)" }),
192
192
  ...(hasCustomShadow
193
193
  ? {}
@@ -246,7 +246,7 @@ const GlassSurface = React__default.forwardRef(({ children, width, height, borde
246
246
  };
247
247
  }
248
248
  }
249
- }, [style, width, height, borderRadius, frosted, svgSupported, backgroundColor, resolvedDark, backgroundOpacity, filterId, saturation, hasCustomShadow, supportsBackdrop]);
249
+ }, [style, width, height, borderRadius, frosted, svgSupported, backgroundColor, resolvedDark, backgroundOpacity, filterId, backdropBrightness, saturation, hasCustomShadow, supportsBackdrop]);
250
250
  const focusVisibleClasses = resolvedDark
251
251
  ? "focus-visible:outline-2 focus-visible:outline-[#0A84FF] focus-visible:outline-offset-2"
252
252
  : "focus-visible:outline-2 focus-visible:outline-[#007AFF] focus-visible:outline-offset-2";
@@ -257,7 +257,7 @@ const GlassSurface = React__default.forwardRef(({ children, width, height, borde
257
257
  else if (forwardedRef)
258
258
  forwardedRef.current = node;
259
259
  }, [forwardedRef]);
260
- return (jsxs("div", { ref: mergedRef, className: cn("relative transition-opacity duration-[260ms] ease-out", focusVisibleClasses, className), style: containerStyles, children: [jsx("svg", { className: "w-full h-full pointer-events-none absolute inset-0 opacity-0 -z-10", xmlns: "http://www.w3.org/2000/svg", children: jsxs("defs", { children: [jsxs("filter", { id: filterId, colorInterpolationFilters: "sRGB", x: "0%", y: "0%", width: "100%", height: "100%", children: [jsx("feImage", { ref: feImageRef, x: "0", y: "0", width: "100%", height: "100%", preserveAspectRatio: "none", result: "map" }), jsx("feDisplacementMap", { ref: redChannelRef, in: "SourceGraphic", in2: "map", id: "redchannel", result: "dispRed" }), jsx("feColorMatrix", { in: "dispRed", type: "matrix", values: "1 0 0 0 0\n 0 0 0 0 0\n 0 0 0 0 0\n 0 0 0 1 0", result: "red" }), jsx("feDisplacementMap", { ref: greenChannelRef, in: "SourceGraphic", in2: "map", id: "greenchannel", result: "dispGreen" }), jsx("feColorMatrix", { in: "dispGreen", type: "matrix", values: "0 0 0 0 0\n 0 1 0 0 0\n 0 0 0 0 0\n 0 0 0 1 0", result: "green" }), jsx("feDisplacementMap", { ref: blueChannelRef, in: "SourceGraphic", in2: "map", id: "bluechannel", result: "dispBlue" }), jsx("feColorMatrix", { in: "dispBlue", type: "matrix", values: "0 0 0 0 0\n 0 0 0 0 0\n 0 0 1 0 0\n 0 0 0 1 0", result: "blue" }), jsx("feBlend", { in: "red", in2: "green", mode: "screen", result: "rg" }), jsx("feBlend", { in: "rg", in2: "blue", mode: "screen", result: "output" }), jsx("feGaussianBlur", { ref: gaussianBlurRef, in: "output", stdDeviation: "0.7" })] }), jsx("filter", { id: noiseFilterId, x: "0%", y: "0%", width: "100%", height: "100%", children: jsx("feTurbulence", { type: "fractalNoise", baseFrequency: "0.65", numOctaves: "3", stitchTiles: "stitch" }) })] }) }), jsx("div", { className: "relative z-10 h-full rounded-[inherit]", children: children }), jsx("div", { className: "absolute inset-0 pointer-events-none rounded-[inherit] overflow-hidden z-20", children: frosted && (jsx("div", { className: "absolute inset-0 opacity-10 mix-blend-overlay", style: { filter: `url(#${noiseFilterId})` } })) })] }));
260
+ return (jsxs("div", { ref: mergedRef, className: cn("relative transition-opacity duration-[260ms] ease-out", focusVisibleClasses, className), style: containerStyles, children: [jsx("svg", { className: "w-full h-full pointer-events-none absolute inset-0 opacity-0 -z-10", xmlns: "http://www.w3.org/2000/svg", children: jsxs("defs", { children: [jsxs("filter", { id: filterId, colorInterpolationFilters: "sRGB", x: "0%", y: "0%", width: "100%", height: "100%", children: [jsx("feImage", { ref: feImageRef, x: "0", y: "0", width: "100%", height: "100%", preserveAspectRatio: "none", result: "map" }), jsx("feDisplacementMap", { ref: redChannelRef, in: "SourceGraphic", in2: "map", result: "dispRed" }), jsx("feColorMatrix", { in: "dispRed", type: "matrix", values: "1 0 0 0 0\n 0 0 0 0 0\n 0 0 0 0 0\n 0 0 0 1 0", result: "red" }), jsx("feDisplacementMap", { ref: greenChannelRef, in: "SourceGraphic", in2: "map", result: "dispGreen" }), jsx("feColorMatrix", { in: "dispGreen", type: "matrix", values: "0 0 0 0 0\n 0 1 0 0 0\n 0 0 0 0 0\n 0 0 0 1 0", result: "green" }), jsx("feDisplacementMap", { ref: blueChannelRef, in: "SourceGraphic", in2: "map", result: "dispBlue" }), jsx("feColorMatrix", { in: "dispBlue", type: "matrix", values: "0 0 0 0 0\n 0 0 0 0 0\n 0 0 1 0 0\n 0 0 0 1 0", result: "blue" }), jsx("feBlend", { in: "red", in2: "green", mode: "screen", result: "rg" }), jsx("feBlend", { in: "rg", in2: "blue", mode: "screen", result: "output" }), jsx("feGaussianBlur", { ref: gaussianBlurRef, in: "output", stdDeviation: "0.7" })] }), jsx("filter", { id: noiseFilterId, x: "0%", y: "0%", width: "100%", height: "100%", children: jsx("feTurbulence", { type: "fractalNoise", baseFrequency: "0.65", numOctaves: "3", stitchTiles: "stitch" }) })] }) }), jsx("div", { className: "relative z-10 h-full rounded-[inherit]", children: children }), jsx("div", { className: "absolute inset-0 pointer-events-none rounded-[inherit] overflow-hidden z-20", children: frosted && (jsx("div", { className: "absolute inset-0 opacity-10 mix-blend-overlay", style: { filter: `url(#${noiseFilterId})` } })) })] }));
261
261
  });
262
262
  GlassSurface.displayName = "GlassSurface";
263
263
 
@@ -48,6 +48,12 @@ export interface GlassSurfaceProps {
48
48
  * @default 'auto'
49
49
  */
50
50
  colorScheme?: "auto" | "dark" | "light";
51
+ /**
52
+ * Brightness multiplier for the backdrop-filter chain.
53
+ * Values > 1 brighten, < 1 darken. Only applies when SVG filters are supported.
54
+ * @default 1
55
+ */
56
+ backdropBrightness?: number;
51
57
  /**
52
58
  * Enable frosted glass effect with noise texture
53
59
  * @default false
@@ -5,5 +5,6 @@ export interface InsetCircleButtonProps {
5
5
  className?: string;
6
6
  classNameDisc?: string;
7
7
  classNameHover?: string;
8
+ onClick?: () => void;
8
9
  }
9
- export declare function InsetCircleButton({ children, size, className, classNameDisc, classNameHover, }: InsetCircleButtonProps): import("react/jsx-runtime").JSX.Element;
10
+ export declare function InsetCircleButton({ children, size, className, classNameDisc, classNameHover, onClick, }: InsetCircleButtonProps): import("react/jsx-runtime").JSX.Element;
@@ -3,8 +3,8 @@ import { motion } from 'motion/react';
3
3
  import { cn } from '../../../utils/cn.js';
4
4
  import 'react';
5
5
 
6
- function InsetCircleButton({ children, size = 44, className, classNameDisc, classNameHover, }) {
7
- return (jsx("div", { className: cn("neu-circle-groove group shrink-0 cursor-pointer bg-neutral-200/80 dark:bg-neutral-900", className), style: { width: size, height: size }, children: jsxs(motion.div, { className: cn("neu-circle-disc bg-linear-to-br from-neutral-100 to-neutral-300 dark:from-neutral-700 dark:to-neutral-900", classNameDisc), whileHover: { scale: 1 }, whileTap: { scale: 0.975 }, transition: { type: "spring", stiffness: 200, damping: 20 }, children: [jsx("div", { className: cn("absolute inset-0 rounded-full bg-linear-to-br from-neutral-300 to-neutral-200 dark:from-neutral-900 dark:to-neutral-700 opacity-0 group-hover:opacity-100 transition-opacity duration-300", classNameHover) }), jsx("div", { className: "relative z-2", children: children })] }) }));
6
+ function InsetCircleButton({ children, size = 44, className, classNameDisc, classNameHover, onClick, }) {
7
+ return (jsx("div", { className: cn("neu-circle-groove group shrink-0 cursor-pointer bg-neutral-200/80 dark:bg-neutral-900", className), style: { width: size, height: size }, onClick: onClick, children: jsxs(motion.div, { className: cn("neu-circle-disc bg-linear-to-br from-neutral-100 to-neutral-300 dark:from-neutral-700 dark:to-neutral-900", classNameDisc), whileHover: { scale: 1 }, whileTap: { scale: 0.975 }, transition: { type: "spring", stiffness: 200, damping: 20 }, children: [jsx("div", { className: cn("absolute inset-0 rounded-full bg-linear-to-br from-neutral-300 to-neutral-200 dark:from-neutral-900 dark:to-neutral-700 opacity-0 group-hover:opacity-100 transition-opacity duration-300", classNameHover) }), jsx("div", { className: "relative z-2", children: children })] }) }));
8
8
  }
9
9
 
10
10
  export { InsetCircleButton };
@@ -3,5 +3,6 @@ export interface InsetPillProps {
3
3
  children: React.ReactNode;
4
4
  className?: string;
5
5
  padding?: string;
6
+ onClick?: () => void;
6
7
  }
7
- export declare function InsetPill({ children, className, padding, }: InsetPillProps): import("react/jsx-runtime").JSX.Element;
8
+ export declare function InsetPill({ children, className, padding, onClick, }: InsetPillProps): import("react/jsx-runtime").JSX.Element;
@@ -1,7 +1,7 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
 
3
- function InsetPill({ children, className, padding = "10px 18px", }) {
4
- return (jsx("div", { className: `neu-inset inline-flex items-center gap-2 cursor-pointer rounded-full bg-neutral-200/60 dark:bg-neutral-800/80 ${className !== null && className !== void 0 ? className : ""}`, style: { padding }, children: jsx("div", { className: "relative z-2 flex items-center gap-2", children: children }) }));
3
+ function InsetPill({ children, className, padding = "10px 18px", onClick, }) {
4
+ return (jsx("div", { className: `neu-inset inline-flex items-center gap-2 cursor-pointer rounded-full bg-neutral-200/60 dark:bg-neutral-800/80 ${className !== null && className !== void 0 ? className : ""}`, style: { padding }, onClick: onClick, children: jsx("div", { className: "relative z-2 flex items-center gap-2", children: children }) }));
5
5
  }
6
6
 
7
7
  export { InsetPill };
@@ -216,18 +216,25 @@ const Slider = React__default.forwardRef(({ state = "default", className = "", l
216
216
  }
217
217
  return `${currentValue}${unit}`;
218
218
  };
219
- return (jsxs("div", { className: cn(mergedTheme.wrapperStyle, wrapperClassName), ref: ref, ...props, children: [label && (jsx(FormLabel, { htmlFor: sliderId, required: required, className: cn(mergedTheme.labelStyle, labelClassName), children: label })), jsxs("div", { className: "flex items-center gap-4", children: [iconStart && (jsx("div", { className: "flex-shrink-0 text-[var(--color-text-muted)]", children: iconStart })), showMinMax && (jsx("span", { className: cn(mergedTheme.minMaxLabelStyle), children: min })), jsxs("div", { className: cn(mergedTheme.rootStyle, className), "data-disabled": isDisabled || undefined, "data-invalid": isInvalid || undefined, "data-orientation": "horizontal", children: [jsxs("div", { ref: trackRef, className: mergedTheme.trackStyle, onPointerDown: handleTrackClick, role: "presentation", children: [jsx("div", { className: mergedTheme.rangeStyle, style: getFilledTrackStyle() }), showTicks &&
219
+ const filterId = `slider-liquid-lens-${sliderId}`;
220
+ return (jsxs("div", { className: cn(mergedTheme.wrapperStyle, wrapperClassName), ref: ref, ...props, children: [jsx("svg", { width: "0", height: "0", className: "absolute", "aria-hidden": "true", children: jsx("defs", { children: jsxs("filter", { id: filterId, children: [jsx("feGaussianBlur", { in: "SourceGraphic", stdDeviation: "1", result: "blur" }), jsx("feColorMatrix", { in: "blur", type: "matrix", values: "1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -7", result: "goo" }), jsx("feComposite", { in: "SourceGraphic", in2: "goo", operator: "atop" })] }) }) }), label && (jsx(FormLabel, { htmlFor: sliderId, required: required, className: cn(mergedTheme.labelStyle, labelClassName), children: label })), jsxs("div", { className: "flex items-center gap-4", children: [iconStart && (jsx("div", { className: "flex-shrink-0 text-[var(--color-text-muted)]", children: iconStart })), showMinMax && (jsx("span", { className: cn(mergedTheme.minMaxLabelStyle), children: min })), jsxs("div", { className: cn(mergedTheme.rootStyle, className), "data-disabled": isDisabled || undefined, "data-invalid": isInvalid || undefined, "data-orientation": "horizontal", children: [jsxs("div", { ref: trackRef, className: mergedTheme.trackStyle, onPointerDown: handleTrackClick, role: "presentation", children: [jsx("div", { className: mergedTheme.rangeStyle, style: getFilledTrackStyle() }), showTicks &&
220
221
  ticks.map((tick) => {
221
222
  const percentage = getPercentage(tick);
222
223
  return (jsx("div", { className: mergedTheme.tickStyle, style: { left: `${percentage}%` } }, tick));
223
224
  })] }), values.map((val, index) => {
224
225
  const percentage = getPercentage(val);
225
- return (jsx("div", { className: cn(mergedTheme.thumbStyle, "outline-[1px] outline-white/50 ring-0 shadow-none p-0 overflow-visible"), style: {
226
+ return (jsxs("div", { className: cn(mergedTheme.thumbStyle, "outline-[2px] outline-[var(--color-border)]/80 ring-0 shadow-lg p-0"), style: {
226
227
  left: `${percentage}%`,
227
228
  transform: "translate(-50%, -50%)",
228
229
  position: "absolute",
229
230
  top: "50%",
230
- }, onPointerDown: (e) => handlePointerDown(e, index), onKeyDown: (e) => handleKeyDown(e, index), role: "slider", "aria-valuemin": min, "aria-valuemax": max, "aria-valuenow": val, "aria-orientation": "horizontal", "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : (range ? `Slider thumb ${index + 1}` : "Slider"), "aria-labelledby": ariaLabelledby, "aria-describedby": ariaDescribedby !== null && ariaDescribedby !== void 0 ? ariaDescribedby : helperTextId, tabIndex: isDisabled ? -1 : 0, "data-disabled": isDisabled || undefined, "data-invalid": isInvalid || undefined }, index));
231
+ }, onPointerDown: (e) => handlePointerDown(e, index), onKeyDown: (e) => handleKeyDown(e, index), role: "slider", "aria-valuemin": min, "aria-valuemax": max, "aria-valuenow": val, "aria-orientation": "horizontal", "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : (range ? `Slider thumb ${index + 1}` : "Slider"), "aria-labelledby": ariaLabelledby, "aria-describedby": ariaDescribedby !== null && ariaDescribedby !== void 0 ? ariaDescribedby : helperTextId, tabIndex: isDisabled ? -1 : 0, "data-disabled": isDisabled || undefined, "data-invalid": isInvalid || undefined, children: [jsx("div", { className: "absolute inset-0 z-0 rounded-full", style: {
232
+ backdropFilter: "blur(0.6px)",
233
+ WebkitBackdropFilter: "blur(0.6px)",
234
+ filter: `url(#${filterId})`,
235
+ }, "aria-hidden": "true" }), jsx("div", { className: "absolute inset-0 z-[1] rounded-full bg-[var(--color-surface)]/90", "aria-hidden": "true" }), jsx("div", { className: "absolute inset-0 z-[2] rounded-full", style: {
236
+ boxShadow: "inset 1px 1px 0 rgba(255,255,255,0.35), inset 1px 3px 0 rgba(0,0,0,0.03), inset 0 0 14px rgba(255,255,255,0.25), inset -1px -1px 0 rgba(0,0,0,0.06)",
237
+ }, "aria-hidden": "true" })] }, index));
231
238
  }), name && (jsx("input", { type: "hidden", name: name, value: Array.isArray(currentValue)
232
239
  ? currentValue.join(",")
233
240
  : currentValue }))] }), showMinMax && (jsx("span", { className: cn(mergedTheme.minMaxLabelStyle), children: max })), showValue && (jsx("div", { className: cn(mergedTheme.valueDisplayStyle), children: formatValueDisplay() })), iconEnd && (jsx("div", { className: "flex-shrink-0 text-[var(--color-text-muted)]", children: iconEnd }))] }), helperText && (jsx("div", { id: helperTextId, className: cn(mergedTheme.helperTextStyle, helperTextClassName), children: helperText }))] }));
@@ -10,17 +10,17 @@ const sliderTheme = {
10
10
  // Root container with layout
11
11
  rootStyle: "relative flex items-center w-full touch-none select-none data-[orientation=vertical]:flex-col data-[orientation=vertical]:h-full",
12
12
  // Track (background)
13
- trackStyle: "relative w-full h-2 grow rounded-full bg-[var(--color-background-tertiary)] overflow-hidden data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 data-[orientation=vertical]:w-2 data-[orientation=vertical]:h-full",
13
+ trackStyle: "relative w-full h-2 grow rounded-full bg-[var(--color-background-tertiary)] overflow-hidden data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 data-[orientation=vertical]:w-2 data-[orientation=vertical]:h-full shadow-inner",
14
14
  // Range (filled portion) - rounded to match track clipping
15
15
  rangeStyle: "absolute h-full bg-gradient-to-r from-[var(--color-primary-500)] to-[var(--color-primary-700)] transition-all rounded-full data-[disabled]:bg-[var(--color-background-disabled)] data-[invalid]:bg-[var(--color-danger)]",
16
16
  // Thumb (draggable handle)
17
- thumbStyle: "block h-5 w-8 rounded-full border-2 border-[var(--color-primary)] ring-2 ring-white shadow-sm cursor-grab active:cursor-grabbing focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-border)] focus-visible:ring-offset-2 transition-all hover:scale-110 disabled:cursor-not-allowed disabled:bg-[var(--color-background-disabled)] disabled:hover:scale-100 data-[disabled]:cursor-not-allowed data-[disabled]:bg-[var(--color-background-disabled)] data-[disabled]:border-[var(--color-border)] data-[disabled]:hover:scale-100 data-[invalid]:border-[var(--color-danger)] data-[invalid]:focus-visible:ring-[var(--color-danger)] glass-effect-5",
17
+ thumbStyle: "block h-5 w-7 rounded-full bg-transparent overflow-hidden cursor-grab active:cursor-grabbing active:scale-x-110 active:scale-y-[0.98] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-border)] focus-visible:ring-offset-2 transition-all hover:scale-110 data-[disabled]:cursor-not-allowed data-[disabled]:hover:scale-100 data-[invalid]:focus-visible:ring-[var(--color-danger)]",
18
18
  // Value display
19
19
  valueDisplayStyle: "text-base font-medium text-[var(--color-text-secondary)] w-fit min-w-12",
20
20
  // Min/max labels
21
21
  minMaxLabelStyle: "text-base font-medium text-[var(--color-text-muted)]",
22
22
  // Tick marks
23
- tickStyle: "absolute w-0.5 h-2 bg-white/60 -translate-x-0.5 pointer-events-none",
23
+ tickStyle: "absolute w-0.5 h-2 bg-[var(--color-border)] -translate-x-0.5 pointer-events-none",
24
24
  };
25
25
 
26
26
  export { sliderTheme };