@nebutra/ui 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -676
- package/README.md +81 -86
- package/dist/agent/index.d.ts +119 -0
- package/dist/agent/index.js +135 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/canonical-CrO71UPO.d.ts +4058 -0
- package/dist/components/index.d.ts +51 -56
- package/dist/components/index.js +1467 -1160
- package/dist/components/index.js.map +1 -1
- package/dist/hooks/index.d.ts +62 -15
- package/dist/hooks/index.js +56 -34
- package/dist/hooks/index.js.map +1 -1
- package/dist/index-CKLIGfiU.d.ts +19 -0
- package/dist/index-Dg4jRJV2.d.ts +57 -0
- package/dist/layout/index.d.ts +5 -1
- package/dist/layout/index.js +427 -533
- package/dist/layout/index.js.map +1 -1
- package/dist/layouts/index.js +11 -9
- package/dist/layouts/index.js.map +1 -1
- package/dist/patterns/index.d.ts +128 -2
- package/dist/patterns/index.js +1478 -786
- package/dist/patterns/index.js.map +1 -1
- package/dist/primitives/canonical.d.ts +25 -0
- package/dist/primitives/canonical.js +11903 -0
- package/dist/primitives/canonical.js.map +1 -0
- package/dist/primitives/index.d.ts +577 -3545
- package/dist/primitives/index.js +8002 -6159
- package/dist/primitives/index.js.map +1 -1
- package/dist/shared/animation/css/index.d.ts +1 -0
- package/dist/shared/animation/css/index.js +14 -0
- package/dist/shared/animation/css/index.js.map +1 -0
- package/dist/shared/animation/index.d.ts +6 -0
- package/dist/shared/animation/index.js +272 -0
- package/dist/shared/animation/index.js.map +1 -0
- package/dist/shared/animation/motion/index.d.ts +4 -0
- package/dist/shared/animation/motion/index.js +205 -0
- package/dist/shared/animation/motion/index.js.map +1 -0
- package/dist/styles/brand-override.css +11 -11
- package/dist/tailwind.preset.d.ts +10 -10
- package/dist/tailwind.preset.js +7 -4
- package/dist/tailwind.preset.js.map +1 -1
- package/dist/theme/index.d.ts +2 -2
- package/dist/tokens-EAC6uPem.d.ts +302 -0
- package/dist/typography/fonts.css +31 -12
- package/dist/typography/index.d.ts +27 -27
- package/dist/typography/index.js +24 -4
- package/dist/typography/index.js.map +1 -1
- package/dist/utils/index.d.ts +36 -14
- package/dist/utils/index.js +44 -10
- package/dist/utils/index.js.map +1 -1
- package/package.json +38 -12
- package/src/styles/brand-override.css +61 -0
- package/src/styles/preset.css +29 -0
- package/src/styles/sources.css +27 -0
- package/src/typography/fonts.css +129 -0
package/dist/components/index.js
CHANGED
|
@@ -1,43 +1,529 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Button as Button$1 } from '@lobehub/ui';
|
|
3
3
|
export { ActionIcon, ActionIconGroup, Alert, Avatar, Button, Checkbox, DraggablePanel, DraggablePanelBody, DraggablePanelContainer, DraggablePanelFooter, DraggablePanelHeader, Flexbox, Form, FormGroup, FormItem, Highlighter, Image, Input, List, Markdown, Menu, Modal, SearchBar, Segmented, Select, SideNav, Tag, TextArea, Tooltip } from '@lobehub/ui';
|
|
4
|
-
export { Spotlight } from '@lobehub/ui/awesome';
|
|
5
4
|
export { ChatInputArea, ChatItem, ChatList, MessageInput, MessageModal } from '@lobehub/ui/chat';
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
|
|
5
|
+
export { default as Spotlight } from '@lobehub/ui/es/awesome/Spotlight/Spotlight';
|
|
6
|
+
import { motion, AnimatePresence, useReducedMotion, m, LazyMotion, domAnimation } from 'framer-motion';
|
|
7
|
+
export { AnimatePresence, LayoutGroup, LazyMotion, MotionConfig, animate, domAnimation, m, motion, useAnimationFrame, useInView, useMotionTemplate, useMotionValue, useReducedMotion, useScroll, useSpring, useTransform, useVelocity } from 'framer-motion';
|
|
8
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
9
|
+
import { Cross, Bell, ChevronRight, CrossSmall, CheckCircle, PlayCircle, Users, MoreHorizontal, DoubleCheck, Check, FacePlus, PaperAirplane, Paperclip, StopFill, StopCircle, ArrowUp, Microphone, LoaderCircle, EyeOff, Eye, Globe, Brain, FolderClosed } from '@nebutra/icons';
|
|
9
10
|
import Image from 'next/image';
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import {
|
|
11
|
+
import { Dialog as Dialog$1 } from '@base-ui/react/dialog';
|
|
12
|
+
import * as React5 from 'react';
|
|
13
|
+
import React5__default, { useEffectEvent, useId, useState } from 'react';
|
|
14
|
+
import { colors, emerge, flow, brandSpring } from '@nebutra/brand';
|
|
13
15
|
import { clsx } from 'clsx';
|
|
14
16
|
import { twMerge } from 'tailwind-merge';
|
|
15
|
-
import {
|
|
16
|
-
import { Dialog as Dialog$1 } from '@base-ui/react/dialog';
|
|
17
|
-
import { colors, flow, emerge, brandSpring } from '@nebutra/brand';
|
|
17
|
+
import { cva } from 'class-variance-authority';
|
|
18
18
|
import { Tooltip as Tooltip$1 } from '@base-ui/react/tooltip';
|
|
19
19
|
import { useAsciiText, slant } from 'react-ascii-text';
|
|
20
|
-
import {
|
|
20
|
+
import { ReactFlowProvider, ReactFlow, Background, Controls, Panel, Handle, Position } from '@xyflow/react';
|
|
21
21
|
import '@xyflow/react/dist/style.css';
|
|
22
22
|
import { wouldCreateCycle } from '@nebutra/graph-model';
|
|
23
23
|
import { Input as Input$1 } from '@base-ui/react/input';
|
|
24
24
|
|
|
25
25
|
// src/components/index.ts
|
|
26
|
+
|
|
27
|
+
// src/shared/animation/motion/tokens.ts
|
|
28
|
+
var animationDurations = {
|
|
29
|
+
instant: 0,
|
|
30
|
+
micro: 0.1,
|
|
31
|
+
fast: 0.16,
|
|
32
|
+
standard: 0.2,
|
|
33
|
+
reveal: 0.3,
|
|
34
|
+
page: 0.44
|
|
35
|
+
};
|
|
36
|
+
var animationEasings = {
|
|
37
|
+
linear: "linear",
|
|
38
|
+
enter: [0, 0, 0.2, 1],
|
|
39
|
+
exit: [0.4, 0, 1, 1],
|
|
40
|
+
standard: [0.4, 0, 0.2, 1],
|
|
41
|
+
emphasized: [0.16, 1, 0.3, 1]
|
|
42
|
+
};
|
|
43
|
+
var animationSprings = {
|
|
44
|
+
interactive: { type: "spring", stiffness: 380, damping: 34, mass: 0.8 },
|
|
45
|
+
layout: { type: "spring", stiffness: 480, damping: 42, mass: 1 },
|
|
46
|
+
panel: { type: "spring", stiffness: 320, damping: 36, mass: 1 }
|
|
47
|
+
};
|
|
48
|
+
var animationDistances = {
|
|
49
|
+
xs: 4,
|
|
50
|
+
sm: 8,
|
|
51
|
+
md: 16,
|
|
52
|
+
lg: 24,
|
|
53
|
+
panel: 32
|
|
54
|
+
};
|
|
55
|
+
var animationTransitions = {
|
|
56
|
+
instant: { duration: animationDurations.instant },
|
|
57
|
+
micro: { duration: animationDurations.micro, ease: animationEasings.enter },
|
|
58
|
+
standard: { duration: animationDurations.standard, ease: animationEasings.enter },
|
|
59
|
+
reveal: { duration: animationDurations.reveal, ease: animationEasings.emphasized },
|
|
60
|
+
page: { duration: animationDurations.page, ease: animationEasings.emphasized },
|
|
61
|
+
layout: animationSprings.layout,
|
|
62
|
+
panel: animationSprings.panel
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// src/shared/animation/motion/variants.ts
|
|
66
|
+
var fadeIn = {
|
|
67
|
+
initial: { opacity: 0 },
|
|
68
|
+
animate: { opacity: 1, transition: animationTransitions.standard },
|
|
69
|
+
exit: { opacity: 0, transition: animationTransitions.micro }
|
|
70
|
+
};
|
|
71
|
+
var scaleIn = {
|
|
72
|
+
initial: { opacity: 0, scale: 0.96 },
|
|
73
|
+
animate: { opacity: 1, scale: 1, transition: animationTransitions.reveal },
|
|
74
|
+
exit: { opacity: 0, scale: 0.98, transition: animationTransitions.micro }
|
|
75
|
+
};
|
|
76
|
+
var slideIn = {
|
|
77
|
+
up: {
|
|
78
|
+
initial: { opacity: 0, y: animationDistances.md },
|
|
79
|
+
animate: { opacity: 1, y: 0, transition: animationTransitions.reveal },
|
|
80
|
+
exit: { opacity: 0, y: animationDistances.sm, transition: animationTransitions.micro }
|
|
81
|
+
},
|
|
82
|
+
down: {
|
|
83
|
+
initial: { opacity: 0, y: -animationDistances.md },
|
|
84
|
+
animate: { opacity: 1, y: 0, transition: animationTransitions.reveal },
|
|
85
|
+
exit: { opacity: 0, y: -animationDistances.sm, transition: animationTransitions.micro }
|
|
86
|
+
},
|
|
87
|
+
left: {
|
|
88
|
+
initial: { opacity: 0, x: animationDistances.md },
|
|
89
|
+
animate: { opacity: 1, x: 0, transition: animationTransitions.reveal },
|
|
90
|
+
exit: { opacity: 0, x: animationDistances.sm, transition: animationTransitions.micro }
|
|
91
|
+
},
|
|
92
|
+
right: {
|
|
93
|
+
initial: { opacity: 0, x: -animationDistances.md },
|
|
94
|
+
animate: { opacity: 1, x: 0, transition: animationTransitions.reveal },
|
|
95
|
+
exit: { opacity: 0, x: -animationDistances.sm, transition: animationTransitions.micro }
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
var animatedList = {
|
|
99
|
+
initial: {},
|
|
100
|
+
animate: { transition: { staggerChildren: 0.06, delayChildren: 0.02 } },
|
|
101
|
+
exit: { transition: { staggerChildren: 0.03, staggerDirection: -1 } }
|
|
102
|
+
};
|
|
103
|
+
var animatedListItem = {
|
|
104
|
+
initial: { opacity: 0, y: animationDistances.sm },
|
|
105
|
+
animate: { opacity: 1, y: 0, transition: animationTransitions.standard },
|
|
106
|
+
exit: { opacity: 0, y: animationDistances.xs, transition: animationTransitions.micro }
|
|
107
|
+
};
|
|
108
|
+
var modalSurface = {
|
|
109
|
+
initial: { opacity: 0, scale: 0.98, y: animationDistances.sm },
|
|
110
|
+
animate: { opacity: 1, scale: 1, y: 0, transition: animationTransitions.panel },
|
|
111
|
+
exit: {
|
|
112
|
+
opacity: 0,
|
|
113
|
+
scale: 0.98,
|
|
114
|
+
y: animationDistances.xs,
|
|
115
|
+
transition: animationTransitions.micro
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
var drawerSurface = {
|
|
119
|
+
left: {
|
|
120
|
+
initial: { opacity: 0, x: "-100%" },
|
|
121
|
+
animate: { opacity: 1, x: 0, transition: animationTransitions.panel },
|
|
122
|
+
exit: { opacity: 0, x: "-100%", transition: animationTransitions.micro }
|
|
123
|
+
},
|
|
124
|
+
right: {
|
|
125
|
+
initial: { opacity: 0, x: "100%" },
|
|
126
|
+
animate: { opacity: 1, x: 0, transition: animationTransitions.panel },
|
|
127
|
+
exit: { opacity: 0, x: "100%", transition: animationTransitions.micro }
|
|
128
|
+
},
|
|
129
|
+
top: {
|
|
130
|
+
initial: { opacity: 0, y: "-100%" },
|
|
131
|
+
animate: { opacity: 1, y: 0, transition: animationTransitions.panel },
|
|
132
|
+
exit: { opacity: 0, y: "-100%", transition: animationTransitions.micro }
|
|
133
|
+
},
|
|
134
|
+
bottom: {
|
|
135
|
+
initial: { opacity: 0, y: "100%" },
|
|
136
|
+
animate: { opacity: 1, y: 0, transition: animationTransitions.panel },
|
|
137
|
+
exit: { opacity: 0, y: "100%", transition: animationTransitions.micro }
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
var popoverSurface = {
|
|
141
|
+
initial: { opacity: 0, scale: 0.98, y: animationDistances.xs },
|
|
142
|
+
animate: { opacity: 1, scale: 1, y: 0, transition: animationTransitions.standard },
|
|
143
|
+
exit: {
|
|
144
|
+
opacity: 0,
|
|
145
|
+
scale: 0.98,
|
|
146
|
+
y: animationDistances.xs,
|
|
147
|
+
transition: animationTransitions.micro
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
var pageTransition = {
|
|
151
|
+
initial: { opacity: 0, y: animationDistances.sm },
|
|
152
|
+
animate: { opacity: 1, y: 0, transition: animationTransitions.page },
|
|
153
|
+
exit: { opacity: 0, y: -animationDistances.xs, transition: animationTransitions.standard }
|
|
154
|
+
};
|
|
155
|
+
var reducedMotionVariants = {
|
|
156
|
+
initial: { opacity: 0 },
|
|
157
|
+
animate: { opacity: 1, transition: animationTransitions.instant },
|
|
158
|
+
exit: { opacity: 0, transition: animationTransitions.instant }
|
|
159
|
+
};
|
|
160
|
+
function useAccessibleVariants(variants, allowTransform = false) {
|
|
161
|
+
const shouldReduceMotion = useReducedMotion();
|
|
162
|
+
return shouldReduceMotion && !allowTransform ? reducedMotionVariants : variants;
|
|
163
|
+
}
|
|
164
|
+
function FadeIn({ children, ...props }) {
|
|
165
|
+
const variants = useAccessibleVariants(fadeIn);
|
|
166
|
+
return /* @__PURE__ */ jsx(motion.div, { initial: "initial", animate: "animate", exit: "exit", variants, ...props, children });
|
|
167
|
+
}
|
|
168
|
+
function SlideIn({
|
|
169
|
+
children,
|
|
170
|
+
direction = "up",
|
|
171
|
+
...props
|
|
172
|
+
}) {
|
|
173
|
+
const variants = useAccessibleVariants(slideIn[direction]);
|
|
174
|
+
return /* @__PURE__ */ jsx(motion.div, { initial: "initial", animate: "animate", exit: "exit", variants, ...props, children });
|
|
175
|
+
}
|
|
176
|
+
function ScaleIn({ children, ...props }) {
|
|
177
|
+
const variants = useAccessibleVariants(scaleIn);
|
|
178
|
+
return /* @__PURE__ */ jsx(motion.div, { initial: "initial", animate: "animate", exit: "exit", variants, ...props, children });
|
|
179
|
+
}
|
|
180
|
+
function AnimatedCard({ children, ...props }) {
|
|
181
|
+
return /* @__PURE__ */ jsx(ScaleIn, { whileHover: { y: -2 }, whileTap: { scale: 0.99 }, ...props, children });
|
|
182
|
+
}
|
|
183
|
+
function AnimatedList({ children, ...props }) {
|
|
184
|
+
const containerVariants2 = useAccessibleVariants(animatedList);
|
|
185
|
+
const itemVariants2 = useAccessibleVariants(animatedListItem);
|
|
186
|
+
return /* @__PURE__ */ jsx(
|
|
187
|
+
motion.div,
|
|
188
|
+
{
|
|
189
|
+
initial: "initial",
|
|
190
|
+
animate: "animate",
|
|
191
|
+
exit: "exit",
|
|
192
|
+
variants: containerVariants2,
|
|
193
|
+
...props,
|
|
194
|
+
children: Array.isArray(children) ? children.map((child, index) => /* @__PURE__ */ jsx(motion.div, { variants: itemVariants2, children: child }, index)) : children
|
|
195
|
+
}
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
function AnimatedModal({ children, open, ...props }) {
|
|
199
|
+
const variants = useAccessibleVariants(modalSurface);
|
|
200
|
+
return /* @__PURE__ */ jsx(AnimatePresence, { children: open ? /* @__PURE__ */ jsx(motion.div, { initial: "initial", animate: "animate", exit: "exit", variants, ...props, children }) : null });
|
|
201
|
+
}
|
|
202
|
+
function AnimatedDrawer({
|
|
203
|
+
children,
|
|
204
|
+
open,
|
|
205
|
+
side = "right",
|
|
206
|
+
...props
|
|
207
|
+
}) {
|
|
208
|
+
const variants = useAccessibleVariants(drawerSurface[side]);
|
|
209
|
+
return /* @__PURE__ */ jsx(AnimatePresence, { children: open ? /* @__PURE__ */ jsx(motion.div, { initial: "initial", animate: "animate", exit: "exit", variants, ...props, children }) : null });
|
|
210
|
+
}
|
|
211
|
+
function AnimatedPopover({
|
|
212
|
+
children,
|
|
213
|
+
open,
|
|
214
|
+
...props
|
|
215
|
+
}) {
|
|
216
|
+
const variants = useAccessibleVariants(popoverSurface);
|
|
217
|
+
return /* @__PURE__ */ jsx(AnimatePresence, { children: open ? /* @__PURE__ */ jsx(motion.div, { initial: "initial", animate: "animate", exit: "exit", variants, ...props, children }) : null });
|
|
218
|
+
}
|
|
219
|
+
function PageTransition({ children, ...props }) {
|
|
220
|
+
const variants = useAccessibleVariants(pageTransition);
|
|
221
|
+
return /* @__PURE__ */ jsx(motion.div, { initial: "initial", animate: "animate", exit: "exit", variants, ...props, children });
|
|
222
|
+
}
|
|
223
|
+
({
|
|
224
|
+
// Nebutra Blue (云毓蓝) — technology & trust — VI: #0033FE
|
|
225
|
+
blue50: colors.primary[50],
|
|
226
|
+
blue100: colors.primary[100],
|
|
227
|
+
blue200: colors.primary[200],
|
|
228
|
+
blue300: colors.primary[300],
|
|
229
|
+
blue400: colors.primary[400],
|
|
230
|
+
blue500: colors.primary[500],
|
|
231
|
+
// brand primary
|
|
232
|
+
blue600: colors.primary[600],
|
|
233
|
+
blue700: colors.primary[700],
|
|
234
|
+
blue800: colors.primary[800],
|
|
235
|
+
blue900: colors.primary[900],
|
|
236
|
+
blue950: colors.primary[950],
|
|
237
|
+
// Nebutra Cyan (云毓青) — data flow & intelligence — VI: #0BF1C3
|
|
238
|
+
cyan50: colors.accent[50],
|
|
239
|
+
cyan100: colors.accent[100],
|
|
240
|
+
cyan200: colors.accent[200],
|
|
241
|
+
cyan300: colors.accent[300],
|
|
242
|
+
cyan400: colors.accent[400],
|
|
243
|
+
cyan500: colors.accent[500],
|
|
244
|
+
// brand secondary
|
|
245
|
+
cyan600: colors.accent[600],
|
|
246
|
+
cyan700: colors.accent[700],
|
|
247
|
+
cyan800: colors.accent[800],
|
|
248
|
+
cyan900: colors.accent[900],
|
|
249
|
+
cyan950: colors.accent[950],
|
|
250
|
+
// Neutral (blue-undertone gray scale)
|
|
251
|
+
neutral50: colors.neutral[50],
|
|
252
|
+
neutral100: colors.neutral[100],
|
|
253
|
+
neutral200: colors.neutral[200],
|
|
254
|
+
neutral300: colors.neutral[300],
|
|
255
|
+
neutral400: colors.neutral[400],
|
|
256
|
+
neutral500: colors.neutral[500],
|
|
257
|
+
neutral600: colors.neutral[600],
|
|
258
|
+
neutral700: colors.neutral[700],
|
|
259
|
+
neutral800: colors.neutral[800],
|
|
260
|
+
neutral900: colors.neutral[900],
|
|
261
|
+
neutral950: colors.neutral[950],
|
|
262
|
+
white: colors.white,
|
|
263
|
+
black: colors.black
|
|
264
|
+
});
|
|
265
|
+
({
|
|
266
|
+
/** Hero sections, primary CTA buttons, logo fills — VI signature gradient */
|
|
267
|
+
primary: colors.gradient.primary,
|
|
268
|
+
/** Hover states, secondary gradient elements */
|
|
269
|
+
reverse: colors.gradient.primaryReverse,
|
|
270
|
+
/** Vertical layout dividers, page section separators */
|
|
271
|
+
vertical: colors.gradient.primaryVertical,
|
|
272
|
+
/** Background halos, focus glow effects, radial emphasis */
|
|
273
|
+
radial: colors.gradient.primaryRadial});
|
|
274
|
+
var primitiveSpacing = {
|
|
275
|
+
1: 4,
|
|
276
|
+
2: 8,
|
|
277
|
+
3: 12,
|
|
278
|
+
4: 16,
|
|
279
|
+
20: 80,
|
|
280
|
+
24: 96
|
|
281
|
+
};
|
|
282
|
+
var primitiveSizing = {
|
|
283
|
+
xs: 20,
|
|
284
|
+
/** Geist button-specific size (24px). Larger than xs by design. */
|
|
285
|
+
tiny: 24,
|
|
286
|
+
sm: 32,
|
|
287
|
+
md: 40,
|
|
288
|
+
lg: 48};
|
|
289
|
+
var primitiveRadius = {
|
|
290
|
+
md: 6,
|
|
291
|
+
// Geist default — slightly more rounded than 4px
|
|
292
|
+
lg: 8};
|
|
293
|
+
var primitiveFontSize = {
|
|
294
|
+
xs: 12,
|
|
295
|
+
sm: 14,
|
|
296
|
+
base: 16};
|
|
297
|
+
|
|
298
|
+
// src/tokens/shadows.ts
|
|
299
|
+
var shadowClasses = {
|
|
300
|
+
md: "shadow-md",
|
|
301
|
+
"2xl": "shadow-2xl"};
|
|
302
|
+
|
|
303
|
+
// src/tokens/components/overlay.ts
|
|
304
|
+
var overlayFocusRingClassName = "outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2";
|
|
305
|
+
var overlayZIndex = {
|
|
306
|
+
backdrop: 1040,
|
|
307
|
+
modal: 1050,
|
|
308
|
+
tooltip: 1070
|
|
309
|
+
};
|
|
310
|
+
var overlayClassNames = {
|
|
311
|
+
backdrop: "fixed inset-0 bg-black/40 backdrop-blur-sm transition-[opacity,display] duration-[var(--motion-duration-flow)] ease-[var(--ease-out)] data-ending-style:opacity-0 data-starting-style:opacity-0 motion-reduce:transition-none",
|
|
312
|
+
modalSurface: [
|
|
313
|
+
"fixed left-1/2 top-1/2 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4",
|
|
314
|
+
"border border-border/60 bg-background/95 p-6 text-foreground backdrop-blur-xl",
|
|
315
|
+
"rounded-[var(--radius-xl)]",
|
|
316
|
+
shadowClasses["2xl"],
|
|
317
|
+
"outline-none",
|
|
318
|
+
"transition-[opacity,transform,display] duration-[var(--motion-duration-flow)] ease-[var(--ease-out)]",
|
|
319
|
+
"data-starting-style:scale-95 data-starting-style:opacity-0 data-ending-style:scale-95 data-ending-style:opacity-0",
|
|
320
|
+
"motion-reduce:transition-none motion-reduce:data-starting-style:transform-none motion-reduce:data-ending-style:transform-none"
|
|
321
|
+
].join(" "),
|
|
322
|
+
tooltipSurface: [
|
|
323
|
+
"overflow-hidden rounded-[var(--radius-md)] border border-border/70 bg-popover/95 px-3 py-1.5 text-sm text-popover-foreground backdrop-blur-md",
|
|
324
|
+
shadowClasses.md,
|
|
325
|
+
"transition-[opacity,transform,display] duration-[var(--motion-duration-flow)] ease-[var(--ease-out)]",
|
|
326
|
+
"data-starting-style:scale-95 data-starting-style:opacity-0 data-ending-style:scale-95 data-ending-style:opacity-0",
|
|
327
|
+
"motion-reduce:transition-none motion-reduce:data-starting-style:transform-none motion-reduce:data-ending-style:transform-none"
|
|
328
|
+
].join(" "),
|
|
329
|
+
closeButton: `absolute right-4 top-4 rounded-[var(--radius-sm)] opacity-70 ring-offset-background ${overlayFocusRingClassName} transition-opacity duration-[var(--motion-duration-micro)] ease-[var(--ease-out)] hover:opacity-100 disabled:pointer-events-none data-[open]:bg-accent data-[open]:text-muted-foreground motion-reduce:transition-none`
|
|
330
|
+
};
|
|
26
331
|
function cn(...inputs) {
|
|
27
332
|
return twMerge(clsx(inputs));
|
|
28
333
|
}
|
|
29
|
-
var
|
|
334
|
+
var overlayPrimitiveClassNames = {
|
|
335
|
+
modalSurface: "rounded-[var(--radius-md)] border-border/70 bg-popover/95 text-popover-foreground shadow-xl"};
|
|
336
|
+
var Dialog = Dialog$1.Root;
|
|
337
|
+
var DialogPortal = Dialog$1.Portal;
|
|
338
|
+
var DialogTrigger = ({
|
|
339
|
+
asChild,
|
|
340
|
+
children,
|
|
341
|
+
ref,
|
|
342
|
+
...props
|
|
343
|
+
}) => {
|
|
344
|
+
if (asChild && React5.isValidElement(children)) {
|
|
345
|
+
return /* @__PURE__ */ jsx(
|
|
346
|
+
Dialog$1.Trigger,
|
|
347
|
+
{
|
|
348
|
+
ref,
|
|
349
|
+
...props,
|
|
350
|
+
render: children
|
|
351
|
+
}
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
return /* @__PURE__ */ jsx(Dialog$1.Trigger, { ref, ...props, children });
|
|
355
|
+
};
|
|
356
|
+
DialogTrigger.displayName = "DialogTrigger";
|
|
357
|
+
var DialogClose = ({
|
|
358
|
+
asChild,
|
|
359
|
+
children,
|
|
360
|
+
ref,
|
|
361
|
+
...props
|
|
362
|
+
}) => {
|
|
363
|
+
if (asChild && React5.isValidElement(children)) {
|
|
364
|
+
return /* @__PURE__ */ jsx(
|
|
365
|
+
Dialog$1.Close,
|
|
366
|
+
{
|
|
367
|
+
ref,
|
|
368
|
+
...props,
|
|
369
|
+
render: children
|
|
370
|
+
}
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
return /* @__PURE__ */ jsx(Dialog$1.Close, { ref, ...props, children });
|
|
374
|
+
};
|
|
375
|
+
DialogClose.displayName = "DialogClose";
|
|
376
|
+
var DialogOverlay = ({
|
|
377
|
+
className,
|
|
378
|
+
style,
|
|
379
|
+
ref,
|
|
380
|
+
...props
|
|
381
|
+
}) => /* @__PURE__ */ jsx(
|
|
382
|
+
Dialog$1.Backdrop,
|
|
383
|
+
{
|
|
384
|
+
ref,
|
|
385
|
+
className: cn(overlayClassNames.backdrop, className),
|
|
386
|
+
style: { zIndex: overlayZIndex.backdrop, ...style },
|
|
387
|
+
...props
|
|
388
|
+
}
|
|
389
|
+
);
|
|
390
|
+
DialogOverlay.displayName = "DialogOverlay";
|
|
391
|
+
var DialogContent = ({
|
|
392
|
+
className,
|
|
393
|
+
children,
|
|
394
|
+
style,
|
|
395
|
+
ref,
|
|
396
|
+
...props
|
|
397
|
+
}) => /* @__PURE__ */ jsxs(DialogPortal, { children: [
|
|
398
|
+
/* @__PURE__ */ jsx(DialogOverlay, {}),
|
|
399
|
+
/* @__PURE__ */ jsxs(
|
|
400
|
+
Dialog$1.Popup,
|
|
401
|
+
{
|
|
402
|
+
ref,
|
|
403
|
+
className: cn(
|
|
404
|
+
overlayClassNames.modalSurface,
|
|
405
|
+
overlayPrimitiveClassNames.modalSurface,
|
|
406
|
+
className
|
|
407
|
+
),
|
|
408
|
+
style: { zIndex: overlayZIndex.modal, ...style },
|
|
409
|
+
...props,
|
|
410
|
+
children: [
|
|
411
|
+
children,
|
|
412
|
+
/* @__PURE__ */ jsxs(DialogClose, { className: overlayClassNames.closeButton, children: [
|
|
413
|
+
/* @__PURE__ */ jsx(Cross, { className: "h-4 w-4" }),
|
|
414
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
|
|
415
|
+
] })
|
|
416
|
+
]
|
|
417
|
+
}
|
|
418
|
+
)
|
|
419
|
+
] });
|
|
420
|
+
DialogContent.displayName = "DialogContent";
|
|
421
|
+
var DialogTitle = ({
|
|
422
|
+
className,
|
|
423
|
+
ref,
|
|
424
|
+
...props
|
|
425
|
+
}) => /* @__PURE__ */ jsx(
|
|
426
|
+
Dialog$1.Title,
|
|
427
|
+
{
|
|
428
|
+
ref,
|
|
429
|
+
className: cn("text-lg font-semibold leading-none tracking-tight", className),
|
|
430
|
+
...props
|
|
431
|
+
}
|
|
432
|
+
);
|
|
433
|
+
DialogTitle.displayName = "DialogTitle";
|
|
434
|
+
var isImageFile = (file) => file.type.startsWith("image/");
|
|
435
|
+
var getFilePreviewKey = (file) => `${file.name}-${file.size}-${file.lastModified}`;
|
|
436
|
+
var preventDragDefaults = (e) => {
|
|
437
|
+
e.preventDefault();
|
|
438
|
+
e.stopPropagation();
|
|
439
|
+
};
|
|
440
|
+
var ImageViewDialog = ({ imageUrl, onClose }) => {
|
|
441
|
+
const shouldReduceMotion = useReducedMotion();
|
|
442
|
+
if (!imageUrl) return null;
|
|
443
|
+
return /* @__PURE__ */ jsx(Dialog, { open: !!imageUrl, onOpenChange: onClose, children: /* @__PURE__ */ jsxs(DialogContent, { className: "p-0 border-none bg-transparent shadow-none max-w-[90vw] md:max-w-[800px]", children: [
|
|
444
|
+
/* @__PURE__ */ jsx(DialogTitle, { className: "sr-only", children: "Image Preview" }),
|
|
445
|
+
/* @__PURE__ */ jsx(
|
|
446
|
+
m.div,
|
|
447
|
+
{
|
|
448
|
+
initial: shouldReduceMotion ? { opacity: 1 } : { opacity: 0, scale: 0.95 },
|
|
449
|
+
animate: { opacity: 1, ...shouldReduceMotion ? {} : { scale: 1 } },
|
|
450
|
+
exit: shouldReduceMotion ? { opacity: 0 } : { opacity: 0, scale: 0.95 },
|
|
451
|
+
transition: shouldReduceMotion ? { duration: 0 } : { duration: 0.2, ease: "easeOut" },
|
|
452
|
+
className: "relative bg-background rounded-[var(--radius-2xl)] overflow-hidden shadow-2xl",
|
|
453
|
+
children: /* @__PURE__ */ jsx(
|
|
454
|
+
Image,
|
|
455
|
+
{
|
|
456
|
+
src: imageUrl,
|
|
457
|
+
alt: "Full preview",
|
|
458
|
+
className: "w-full max-h-[80vh] object-contain rounded-[var(--radius-2xl)]",
|
|
459
|
+
fill: true,
|
|
460
|
+
sizes: "(max-width: 768px) 90vw, 800px"
|
|
461
|
+
}
|
|
462
|
+
)
|
|
463
|
+
}
|
|
464
|
+
)
|
|
465
|
+
] }) });
|
|
466
|
+
};
|
|
467
|
+
ImageViewDialog.displayName = "ImageViewDialog";
|
|
468
|
+
function PromptAttachmentPreviews({
|
|
469
|
+
files,
|
|
470
|
+
filePreviews,
|
|
471
|
+
isRecording,
|
|
472
|
+
onPreview,
|
|
473
|
+
onRemove
|
|
474
|
+
}) {
|
|
475
|
+
if (files.length === 0 || isRecording) return null;
|
|
476
|
+
return /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2 p-0 pb-1 transition-[background-color,border-color,box-shadow,color,opacity,transform] duration-300 motion-reduce:transition-none", children: files.map((file) => {
|
|
477
|
+
const previewKey = getFilePreviewKey(file);
|
|
478
|
+
const preview = filePreviews[previewKey];
|
|
479
|
+
return /* @__PURE__ */ jsx("div", { className: "relative group h-16 w-16", children: isImageFile(file) && preview && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
480
|
+
/* @__PURE__ */ jsx(
|
|
481
|
+
"button",
|
|
482
|
+
{
|
|
483
|
+
type: "button",
|
|
484
|
+
"aria-label": `Preview ${file.name}`,
|
|
485
|
+
className: "relative h-16 w-16 rounded-[var(--radius-xl)] overflow-hidden cursor-pointer transition-[background-color,border-color,box-shadow,color,opacity,transform] duration-300 motion-reduce:transition-none",
|
|
486
|
+
onClick: () => onPreview(preview),
|
|
487
|
+
children: /* @__PURE__ */ jsx(
|
|
488
|
+
Image,
|
|
489
|
+
{
|
|
490
|
+
src: preview,
|
|
491
|
+
alt: file.name,
|
|
492
|
+
className: "h-full w-full object-cover",
|
|
493
|
+
fill: true,
|
|
494
|
+
sizes: "64px"
|
|
495
|
+
}
|
|
496
|
+
)
|
|
497
|
+
}
|
|
498
|
+
),
|
|
499
|
+
/* @__PURE__ */ jsx(
|
|
500
|
+
"button",
|
|
501
|
+
{
|
|
502
|
+
type: "button",
|
|
503
|
+
"aria-label": `Remove ${file.name}`,
|
|
504
|
+
onClick: (event) => {
|
|
505
|
+
event.stopPropagation();
|
|
506
|
+
onRemove(file);
|
|
507
|
+
},
|
|
508
|
+
className: "absolute top-1 right-1 rounded-full bg-black/70 p-0.5 opacity-100 transition-opacity motion-reduce:transition-none",
|
|
509
|
+
children: /* @__PURE__ */ jsx(Cross, { className: "h-3 w-3 text-white" })
|
|
510
|
+
}
|
|
511
|
+
)
|
|
512
|
+
] }) }, previewKey);
|
|
513
|
+
}) });
|
|
514
|
+
}
|
|
515
|
+
var Slot = React5.forwardRef(
|
|
30
516
|
({ children, className, style, ...props }, ref) => {
|
|
31
|
-
const childArray =
|
|
517
|
+
const childArray = React5.Children.toArray(children);
|
|
32
518
|
const child = childArray.length === 1 ? childArray[0] : null;
|
|
33
|
-
if (child == null || !
|
|
519
|
+
if (child == null || !React5.isValidElement(child)) {
|
|
34
520
|
return /* @__PURE__ */ jsx("span", { ref, className, style, ...props, children });
|
|
35
521
|
}
|
|
36
522
|
const childProps = child.props;
|
|
37
523
|
const mergedRef = (node) => {
|
|
38
524
|
if (typeof ref === "function") ref(node);
|
|
39
525
|
else if (ref) ref.current = node;
|
|
40
|
-
const childRef =
|
|
526
|
+
const childRef = childProps.ref;
|
|
41
527
|
if (typeof childRef === "function") childRef(node);
|
|
42
528
|
else if (childRef && "current" in childRef) {
|
|
43
529
|
childRef.current = node;
|
|
@@ -51,7 +537,7 @@ var Slot = React6.forwardRef(
|
|
|
51
537
|
className: mergedClass,
|
|
52
538
|
style: { ...childProps.style, ...style }
|
|
53
539
|
};
|
|
54
|
-
return
|
|
540
|
+
return React5.cloneElement(
|
|
55
541
|
child,
|
|
56
542
|
merged
|
|
57
543
|
);
|
|
@@ -61,8 +547,9 @@ Slot.displayName = "Slot";
|
|
|
61
547
|
var buttonVariants = cva(
|
|
62
548
|
[
|
|
63
549
|
"inline-flex items-center justify-center gap-2 whitespace-nowrap",
|
|
64
|
-
"rounded-[var(--radius-md)]
|
|
65
|
-
"
|
|
550
|
+
"rounded-[var(--btn-default-radius,var(--radius-md))]",
|
|
551
|
+
"text-[length:var(--control-font-size-md,0.875rem)] font-[number:var(--font-weight-medium,500)]",
|
|
552
|
+
"transition-colors duration-micro ease-out",
|
|
66
553
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
67
554
|
"disabled:pointer-events-none disabled:opacity-50",
|
|
68
555
|
"aria-busy:cursor-wait"
|
|
@@ -70,8 +557,9 @@ var buttonVariants = cva(
|
|
|
70
557
|
{
|
|
71
558
|
variants: {
|
|
72
559
|
variant: {
|
|
73
|
-
|
|
74
|
-
|
|
560
|
+
// Recipe-driven via packages/design/tokens/recipe.css (.btn-brand-default)
|
|
561
|
+
default: "btn-brand-default",
|
|
562
|
+
ink: "bg-[var(--neutral-12)] text-[var(--neutral-1)] ring-1 ring-inset ring-[color:var(--neutral-1)]/5 hover:bg-[var(--neutral-11)] hover:-translate-y-px active:translate-y-0 transition-[transform,background-color] duration-micro",
|
|
75
563
|
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
76
564
|
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
|
77
565
|
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
@@ -81,16 +569,11 @@ var buttonVariants = cva(
|
|
|
81
569
|
warning: "bg-warning text-warning-foreground hover:bg-warning/90"
|
|
82
570
|
},
|
|
83
571
|
size: {
|
|
84
|
-
tiny: "h-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
// 40px
|
|
90
|
-
lg: "h-12 rounded-[var(--radius-lg)] px-5 text-base",
|
|
91
|
-
// 48px
|
|
92
|
-
icon: "h-10 w-10"
|
|
93
|
-
// 40×40px (kept for backward compat)
|
|
572
|
+
tiny: "h-[var(--control-height-tiny,1.5rem)] rounded-[var(--radius-sm)] px-2 text-[length:var(--control-font-size-tiny,0.6875rem)]",
|
|
573
|
+
sm: "h-[var(--control-height-sm,2rem)] rounded-[var(--radius-sm)] px-3 text-[length:var(--control-font-size-sm,0.75rem)]",
|
|
574
|
+
default: "h-[var(--control-height-md,2.5rem)] px-[var(--btn-default-padding-x,1rem)] py-[var(--btn-default-padding-y,0.5rem)]",
|
|
575
|
+
lg: "h-[var(--control-height-lg,3rem)] rounded-[var(--radius-lg)] px-5 text-[length:var(--control-font-size-lg,1rem)]",
|
|
576
|
+
icon: "h-[var(--control-height-md,2.5rem)] w-[var(--control-height-md,2.5rem)]"
|
|
94
577
|
},
|
|
95
578
|
shape: {
|
|
96
579
|
default: "",
|
|
@@ -99,16 +582,30 @@ var buttonVariants = cva(
|
|
|
99
582
|
}
|
|
100
583
|
},
|
|
101
584
|
compoundVariants: [
|
|
102
|
-
|
|
103
|
-
{ shape: "square", size: "
|
|
104
|
-
{ shape: "square", size: "
|
|
105
|
-
{ shape: "square", size: "
|
|
106
|
-
{
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
{
|
|
585
|
+
{ shape: "square", size: "tiny", className: "w-[var(--control-height-tiny,1.5rem)] px-0" },
|
|
586
|
+
{ shape: "square", size: "sm", className: "w-[var(--control-height-sm,2rem)] px-0" },
|
|
587
|
+
{ shape: "square", size: "default", className: "w-[var(--control-height-md,2.5rem)] px-0" },
|
|
588
|
+
{ shape: "square", size: "lg", className: "w-[var(--control-height-lg,3rem)] px-0" },
|
|
589
|
+
{
|
|
590
|
+
shape: "circle",
|
|
591
|
+
size: "tiny",
|
|
592
|
+
className: "w-[var(--control-height-tiny,1.5rem)] px-0 rounded-full"
|
|
593
|
+
},
|
|
594
|
+
{
|
|
595
|
+
shape: "circle",
|
|
596
|
+
size: "sm",
|
|
597
|
+
className: "w-[var(--control-height-sm,2rem)] px-0 rounded-full"
|
|
598
|
+
},
|
|
599
|
+
{
|
|
600
|
+
shape: "circle",
|
|
601
|
+
size: "default",
|
|
602
|
+
className: "w-[var(--control-height-md,2.5rem)] px-0 rounded-full"
|
|
603
|
+
},
|
|
604
|
+
{
|
|
605
|
+
shape: "circle",
|
|
606
|
+
size: "lg",
|
|
607
|
+
className: "w-[var(--control-height-lg,3rem)] px-0 rounded-full"
|
|
608
|
+
}
|
|
112
609
|
],
|
|
113
610
|
defaultVariants: {
|
|
114
611
|
variant: "default",
|
|
@@ -162,7 +659,7 @@ function getSpinnerSizeClass(size) {
|
|
|
162
659
|
var SHADOW_CLASSES = {
|
|
163
660
|
sm: "shadow-sm",
|
|
164
661
|
md: "shadow-md",
|
|
165
|
-
lg: "shadow-
|
|
662
|
+
lg: "shadow-md"
|
|
166
663
|
};
|
|
167
664
|
function resolveShadowClass(shadow) {
|
|
168
665
|
if (!shadow) return void 0;
|
|
@@ -178,253 +675,37 @@ function ButtonContent({ loading, prefix, suffix, size, children }) {
|
|
|
178
675
|
suffix != null && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn("shrink-0", iconSizeClass), children: suffix })
|
|
179
676
|
] });
|
|
180
677
|
}
|
|
181
|
-
var Button =
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
{
|
|
202
|
-
ref,
|
|
203
|
-
className: cn(buttonVariants({ variant, size, shape }), shadowClass, className),
|
|
204
|
-
disabled: isDisabled,
|
|
205
|
-
"aria-busy": loading || void 0,
|
|
206
|
-
...props,
|
|
207
|
-
children: asChild ? children : /* @__PURE__ */ jsx(ButtonContent, { loading, prefix, suffix, size, children })
|
|
208
|
-
}
|
|
209
|
-
);
|
|
210
|
-
}
|
|
211
|
-
);
|
|
212
|
-
Button.displayName = "Button";
|
|
213
|
-
var ButtonLink = React6.forwardRef(
|
|
214
|
-
({
|
|
215
|
-
className,
|
|
216
|
-
variant,
|
|
217
|
-
size,
|
|
218
|
-
shape,
|
|
219
|
-
prefix,
|
|
220
|
-
suffix,
|
|
221
|
-
shadow,
|
|
222
|
-
loading = false,
|
|
223
|
-
children,
|
|
224
|
-
...props
|
|
225
|
-
}, ref) => {
|
|
226
|
-
const shadowClass = resolveShadowClass(shadow);
|
|
227
|
-
const loadingProps = loading ? {
|
|
228
|
-
"aria-busy": "true",
|
|
229
|
-
"aria-disabled": "true",
|
|
230
|
-
tabIndex: -1
|
|
231
|
-
} : {};
|
|
232
|
-
return /* @__PURE__ */ jsx(
|
|
233
|
-
"a",
|
|
234
|
-
{
|
|
235
|
-
ref,
|
|
236
|
-
className: cn(
|
|
237
|
-
buttonVariants({ variant, size, shape }),
|
|
238
|
-
shadowClass,
|
|
239
|
-
loading && "pointer-events-none opacity-50",
|
|
240
|
-
className
|
|
241
|
-
),
|
|
242
|
-
...loadingProps,
|
|
243
|
-
...props,
|
|
244
|
-
children: /* @__PURE__ */ jsx(ButtonContent, { loading, prefix, suffix, size, children })
|
|
245
|
-
}
|
|
246
|
-
);
|
|
247
|
-
}
|
|
248
|
-
);
|
|
249
|
-
ButtonLink.displayName = "ButtonLink";
|
|
250
|
-
var Dialog = Dialog$1.Root;
|
|
251
|
-
var DialogPortal = Dialog$1.Portal;
|
|
252
|
-
var DialogTrigger = React6.forwardRef(({ asChild, children, ...props }, ref) => {
|
|
253
|
-
if (asChild && React6.isValidElement(children)) {
|
|
254
|
-
return /* @__PURE__ */ jsx(
|
|
255
|
-
Dialog$1.Trigger,
|
|
256
|
-
{
|
|
257
|
-
ref,
|
|
258
|
-
...props,
|
|
259
|
-
render: children
|
|
260
|
-
}
|
|
261
|
-
);
|
|
262
|
-
}
|
|
263
|
-
return /* @__PURE__ */ jsx(Dialog$1.Trigger, { ref, ...props, children });
|
|
264
|
-
});
|
|
265
|
-
DialogTrigger.displayName = "DialogTrigger";
|
|
266
|
-
var DialogClose = React6.forwardRef(({ asChild, children, ...props }, ref) => {
|
|
267
|
-
if (asChild && React6.isValidElement(children)) {
|
|
268
|
-
return /* @__PURE__ */ jsx(
|
|
269
|
-
Dialog$1.Close,
|
|
270
|
-
{
|
|
271
|
-
ref,
|
|
272
|
-
...props,
|
|
273
|
-
render: children
|
|
274
|
-
}
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
|
-
return /* @__PURE__ */ jsx(Dialog$1.Close, { ref, ...props, children });
|
|
278
|
-
});
|
|
279
|
-
DialogClose.displayName = "DialogClose";
|
|
280
|
-
var DialogOverlay = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
281
|
-
Dialog$1.Backdrop,
|
|
282
|
-
{
|
|
283
|
-
ref,
|
|
284
|
-
className: cn(
|
|
285
|
-
"fixed inset-0 z-50 bg-black/40 backdrop-blur-sm data-ending-style:animate-out data-starting-style:animate-in data-ending-style:fade-out-0 data-starting-style:fade-in-0 duration-300 transition-[opacity,display]",
|
|
286
|
-
className
|
|
287
|
-
),
|
|
288
|
-
...props
|
|
289
|
-
}
|
|
290
|
-
));
|
|
291
|
-
DialogOverlay.displayName = "DialogOverlay";
|
|
292
|
-
var DialogContent = React6.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(DialogPortal, { children: [
|
|
293
|
-
/* @__PURE__ */ jsx(DialogOverlay, {}),
|
|
294
|
-
/* @__PURE__ */ jsxs(
|
|
295
|
-
Dialog$1.Popup,
|
|
678
|
+
var Button = ({
|
|
679
|
+
className,
|
|
680
|
+
variant,
|
|
681
|
+
size,
|
|
682
|
+
shape,
|
|
683
|
+
asChild = false,
|
|
684
|
+
loading = false,
|
|
685
|
+
disabled,
|
|
686
|
+
prefix,
|
|
687
|
+
suffix,
|
|
688
|
+
shadow,
|
|
689
|
+
children,
|
|
690
|
+
ref,
|
|
691
|
+
...props
|
|
692
|
+
}) => {
|
|
693
|
+
const Comp = asChild ? Slot : "button";
|
|
694
|
+
const isDisabled = Boolean(disabled || loading);
|
|
695
|
+
const shadowClass = resolveShadowClass(shadow);
|
|
696
|
+
return /* @__PURE__ */ jsx(
|
|
697
|
+
Comp,
|
|
296
698
|
{
|
|
297
699
|
ref,
|
|
298
|
-
className: cn(
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
),
|
|
700
|
+
className: cn(buttonVariants({ variant, size, shape }), shadowClass, className),
|
|
701
|
+
disabled: isDisabled,
|
|
702
|
+
"aria-busy": loading || void 0,
|
|
302
703
|
...props,
|
|
303
|
-
children:
|
|
304
|
-
children,
|
|
305
|
-
/* @__PURE__ */ jsxs(DialogClose, { className: "absolute right-4 top-4 rounded-[var(--radius-sm)] opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[open]:bg-accent data-[open]:text-muted-foreground", children: [
|
|
306
|
-
/* @__PURE__ */ jsx(Cross, { className: "h-4 w-4" }),
|
|
307
|
-
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
|
|
308
|
-
] })
|
|
309
|
-
]
|
|
310
|
-
}
|
|
311
|
-
)
|
|
312
|
-
] }));
|
|
313
|
-
DialogContent.displayName = "DialogContent";
|
|
314
|
-
var DialogHeader = React6.forwardRef(
|
|
315
|
-
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
316
|
-
"div",
|
|
317
|
-
{
|
|
318
|
-
ref,
|
|
319
|
-
className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className),
|
|
320
|
-
...props
|
|
704
|
+
children: asChild ? children : /* @__PURE__ */ jsx(ButtonContent, { loading, prefix, suffix, size, children })
|
|
321
705
|
}
|
|
322
|
-
)
|
|
323
|
-
);
|
|
324
|
-
DialogHeader.displayName = "DialogHeader";
|
|
325
|
-
var DialogFooter = React6.forwardRef(
|
|
326
|
-
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
327
|
-
"div",
|
|
328
|
-
{
|
|
329
|
-
ref,
|
|
330
|
-
className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className),
|
|
331
|
-
...props
|
|
332
|
-
}
|
|
333
|
-
)
|
|
334
|
-
);
|
|
335
|
-
DialogFooter.displayName = "DialogFooter";
|
|
336
|
-
var DialogTitle = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
337
|
-
Dialog$1.Title,
|
|
338
|
-
{
|
|
339
|
-
ref,
|
|
340
|
-
className: cn("text-lg font-semibold leading-none tracking-tight", className),
|
|
341
|
-
...props
|
|
342
|
-
}
|
|
343
|
-
));
|
|
344
|
-
DialogTitle.displayName = "DialogTitle";
|
|
345
|
-
var DialogDescription = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
346
|
-
Dialog$1.Description,
|
|
347
|
-
{
|
|
348
|
-
ref,
|
|
349
|
-
className: cn("text-sm text-muted-foreground", className),
|
|
350
|
-
...props
|
|
351
|
-
}
|
|
352
|
-
));
|
|
353
|
-
DialogDescription.displayName = "DialogDescription";
|
|
354
|
-
({
|
|
355
|
-
// Nebutra Blue (云毓蓝) — technology & trust — VI: #0033FE
|
|
356
|
-
blue50: colors.primary[50],
|
|
357
|
-
blue100: colors.primary[100],
|
|
358
|
-
blue200: colors.primary[200],
|
|
359
|
-
blue300: colors.primary[300],
|
|
360
|
-
blue400: colors.primary[400],
|
|
361
|
-
blue500: colors.primary[500],
|
|
362
|
-
// brand primary
|
|
363
|
-
blue600: colors.primary[600],
|
|
364
|
-
blue700: colors.primary[700],
|
|
365
|
-
blue800: colors.primary[800],
|
|
366
|
-
blue900: colors.primary[900],
|
|
367
|
-
blue950: colors.primary[950],
|
|
368
|
-
// Nebutra Cyan (云毓青) — data flow & intelligence — VI: #0BF1C3
|
|
369
|
-
cyan50: colors.accent[50],
|
|
370
|
-
cyan100: colors.accent[100],
|
|
371
|
-
cyan200: colors.accent[200],
|
|
372
|
-
cyan300: colors.accent[300],
|
|
373
|
-
cyan400: colors.accent[400],
|
|
374
|
-
cyan500: colors.accent[500],
|
|
375
|
-
// brand secondary
|
|
376
|
-
cyan600: colors.accent[600],
|
|
377
|
-
cyan700: colors.accent[700],
|
|
378
|
-
cyan800: colors.accent[800],
|
|
379
|
-
cyan900: colors.accent[900],
|
|
380
|
-
cyan950: colors.accent[950],
|
|
381
|
-
// Neutral (blue-undertone gray scale)
|
|
382
|
-
neutral50: colors.neutral[50],
|
|
383
|
-
neutral100: colors.neutral[100],
|
|
384
|
-
neutral200: colors.neutral[200],
|
|
385
|
-
neutral300: colors.neutral[300],
|
|
386
|
-
neutral400: colors.neutral[400],
|
|
387
|
-
neutral500: colors.neutral[500],
|
|
388
|
-
neutral600: colors.neutral[600],
|
|
389
|
-
neutral700: colors.neutral[700],
|
|
390
|
-
neutral800: colors.neutral[800],
|
|
391
|
-
neutral900: colors.neutral[900],
|
|
392
|
-
neutral950: colors.neutral[950],
|
|
393
|
-
white: colors.white,
|
|
394
|
-
black: colors.black
|
|
395
|
-
});
|
|
396
|
-
({
|
|
397
|
-
/** Hero sections, primary CTA buttons, logo fills — VI signature gradient */
|
|
398
|
-
primary: colors.gradient.primary,
|
|
399
|
-
/** Hover states, secondary gradient elements */
|
|
400
|
-
reverse: colors.gradient.primaryReverse,
|
|
401
|
-
/** Vertical layout dividers, page section separators */
|
|
402
|
-
vertical: colors.gradient.primaryVertical,
|
|
403
|
-
/** Background halos, focus glow effects, radial emphasis */
|
|
404
|
-
radial: colors.gradient.primaryRadial});
|
|
405
|
-
var primitiveSpacing = {
|
|
406
|
-
1: 4,
|
|
407
|
-
2: 8,
|
|
408
|
-
3: 12,
|
|
409
|
-
4: 16,
|
|
410
|
-
20: 80,
|
|
411
|
-
24: 96
|
|
706
|
+
);
|
|
412
707
|
};
|
|
413
|
-
|
|
414
|
-
xs: 20,
|
|
415
|
-
/** Geist button-specific size (24px). Larger than xs by design. */
|
|
416
|
-
tiny: 24,
|
|
417
|
-
sm: 32,
|
|
418
|
-
md: 40,
|
|
419
|
-
lg: 48};
|
|
420
|
-
var primitiveRadius = {
|
|
421
|
-
md: 6,
|
|
422
|
-
// Geist default — slightly more rounded than 4px
|
|
423
|
-
lg: 8};
|
|
424
|
-
var primitiveFontSize = {
|
|
425
|
-
xs: 12,
|
|
426
|
-
sm: 14,
|
|
427
|
-
base: 16};
|
|
708
|
+
Button.displayName = "Button";
|
|
428
709
|
|
|
429
710
|
// src/tokens/components/textarea.ts
|
|
430
711
|
var textareaTokens = {
|
|
@@ -454,6 +735,14 @@ var textareaTokens = {
|
|
|
454
735
|
labelSize: primitiveFontSize.sm,
|
|
455
736
|
focusRingWidth: 3,
|
|
456
737
|
fieldGap: primitiveSpacing[2] - primitiveSpacing[1] / 2};
|
|
738
|
+
|
|
739
|
+
// src/primitives/form-control.ts
|
|
740
|
+
var formControlFocusClassNames = {
|
|
741
|
+
input: "outline-none focus:border-ring focus:ring-[length:var(--input-focus-ring-width)] focus:ring-ring/30",
|
|
742
|
+
textarea: "outline-none focus:border-ring focus:ring-[length:var(--textarea-focus-ring-width)] focus:ring-ring/30"};
|
|
743
|
+
var formControlInvalidClassNames = {
|
|
744
|
+
input: "aria-invalid:border-destructive/60 aria-invalid:focus:border-destructive aria-invalid:focus:ring-destructive/20",
|
|
745
|
+
textarea: "aria-invalid:border-destructive/60 aria-invalid:focus:border-destructive aria-invalid:focus:ring-destructive/20"};
|
|
457
746
|
var fieldMessageClassName = "text-xs text-muted-foreground";
|
|
458
747
|
var fieldErrorClassName = "text-xs font-medium text-destructive";
|
|
459
748
|
function getTextareaStyle(size, style) {
|
|
@@ -482,82 +771,81 @@ function joinDescriptionIds(...ids) {
|
|
|
482
771
|
function isInvalid(error, ariaInvalid) {
|
|
483
772
|
return error === true || typeof error === "string" || ariaInvalid === true || ariaInvalid === "true";
|
|
484
773
|
}
|
|
485
|
-
var Textarea =
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
}
|
|
534
|
-
);
|
|
535
|
-
if (!label && !description && typeof error !== "string" && !fieldClassName) {
|
|
536
|
-
return control;
|
|
774
|
+
var Textarea = ({
|
|
775
|
+
className,
|
|
776
|
+
style,
|
|
777
|
+
size = "md",
|
|
778
|
+
label,
|
|
779
|
+
description,
|
|
780
|
+
error,
|
|
781
|
+
fieldClassName,
|
|
782
|
+
id,
|
|
783
|
+
onChange,
|
|
784
|
+
onValueChange,
|
|
785
|
+
"aria-describedby": ariaDescribedBy,
|
|
786
|
+
"aria-invalid": ariaInvalid,
|
|
787
|
+
ref,
|
|
788
|
+
...props
|
|
789
|
+
}) => {
|
|
790
|
+
const baseId = React5.useId();
|
|
791
|
+
const textareaId = id ?? (label || description || typeof error === "string" ? baseId : void 0);
|
|
792
|
+
const resolvedInvalid = isInvalid(error, ariaInvalid);
|
|
793
|
+
const descriptionId = description && textareaId ? `${textareaId}-description` : void 0;
|
|
794
|
+
const errorId = typeof error === "string" && textareaId ? `${textareaId}-error` : void 0;
|
|
795
|
+
const describedBy = joinDescriptionIds(ariaDescribedBy, descriptionId, errorId);
|
|
796
|
+
const handleChange = React5.useCallback(
|
|
797
|
+
(event) => {
|
|
798
|
+
onValueChange?.(event.currentTarget.value);
|
|
799
|
+
onChange?.(event);
|
|
800
|
+
},
|
|
801
|
+
[onChange, onValueChange]
|
|
802
|
+
);
|
|
803
|
+
const control = /* @__PURE__ */ jsx(
|
|
804
|
+
"textarea",
|
|
805
|
+
{
|
|
806
|
+
className: cn(
|
|
807
|
+
"flex min-h-[var(--textarea-min-height)] w-full resize-y rounded-[var(--textarea-radius)] border border-input bg-background",
|
|
808
|
+
"px-[var(--textarea-padding-x)] py-[var(--textarea-padding-y)] text-[length:var(--textarea-font-size)] text-foreground shadow-xs",
|
|
809
|
+
"transition-[background-color,border-color,box-shadow,color] duration-micro ease-out placeholder:text-muted-foreground",
|
|
810
|
+
formControlFocusClassNames.textarea,
|
|
811
|
+
"disabled:cursor-not-allowed disabled:opacity-50 read-only:cursor-default read-only:bg-muted/70",
|
|
812
|
+
formControlInvalidClassNames.textarea,
|
|
813
|
+
className
|
|
814
|
+
),
|
|
815
|
+
ref,
|
|
816
|
+
id: textareaId,
|
|
817
|
+
"aria-invalid": resolvedInvalid || void 0,
|
|
818
|
+
"aria-describedby": describedBy,
|
|
819
|
+
style: getTextareaStyle(size, style),
|
|
820
|
+
onChange: handleChange,
|
|
821
|
+
...props
|
|
537
822
|
}
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
"data-slot": "textarea-field",
|
|
542
|
-
className: cn("grid gap-[var(--textarea-field-gap)]", fieldClassName),
|
|
543
|
-
style: getTextareaFieldStyle(),
|
|
544
|
-
children: [
|
|
545
|
-
label && /* @__PURE__ */ jsx(
|
|
546
|
-
"label",
|
|
547
|
-
{
|
|
548
|
-
htmlFor: textareaId,
|
|
549
|
-
className: "text-[length:var(--textarea-label-size)] font-medium text-foreground",
|
|
550
|
-
children: label
|
|
551
|
-
}
|
|
552
|
-
),
|
|
553
|
-
control,
|
|
554
|
-
description && !error && /* @__PURE__ */ jsx("p", { id: descriptionId, className: fieldMessageClassName, children: description }),
|
|
555
|
-
typeof error === "string" && /* @__PURE__ */ jsx("p", { id: errorId, role: "alert", className: fieldErrorClassName, children: error })
|
|
556
|
-
]
|
|
557
|
-
}
|
|
558
|
-
);
|
|
823
|
+
);
|
|
824
|
+
if (!label && !description && typeof error !== "string" && !fieldClassName) {
|
|
825
|
+
return control;
|
|
559
826
|
}
|
|
560
|
-
|
|
827
|
+
return /* @__PURE__ */ jsxs(
|
|
828
|
+
"div",
|
|
829
|
+
{
|
|
830
|
+
"data-slot": "textarea-field",
|
|
831
|
+
className: cn("grid gap-[var(--textarea-field-gap)]", fieldClassName),
|
|
832
|
+
style: getTextareaFieldStyle(),
|
|
833
|
+
children: [
|
|
834
|
+
label && /* @__PURE__ */ jsx(
|
|
835
|
+
"label",
|
|
836
|
+
{
|
|
837
|
+
htmlFor: textareaId,
|
|
838
|
+
className: "text-[length:var(--textarea-label-size)] font-medium text-foreground",
|
|
839
|
+
children: label
|
|
840
|
+
}
|
|
841
|
+
),
|
|
842
|
+
control,
|
|
843
|
+
description && !error && /* @__PURE__ */ jsx("p", { id: descriptionId, className: fieldMessageClassName, children: description }),
|
|
844
|
+
typeof error === "string" && /* @__PURE__ */ jsx("p", { id: errorId, role: "alert", className: fieldErrorClassName, children: error })
|
|
845
|
+
]
|
|
846
|
+
}
|
|
847
|
+
);
|
|
848
|
+
};
|
|
561
849
|
Textarea.displayName = "Textarea";
|
|
562
850
|
var DEFAULT_TOOLTIP_DELAY_MS = 150;
|
|
563
851
|
var TooltipProvider = ({
|
|
@@ -574,8 +862,13 @@ var Tooltip = ({
|
|
|
574
862
|
const delay = delayDuration ?? DEFAULT_TOOLTIP_DELAY_MS;
|
|
575
863
|
return /* @__PURE__ */ jsx(Tooltip$1.Provider, { delay, children: /* @__PURE__ */ jsx(Tooltip$1.Root, { ...props, children }) });
|
|
576
864
|
};
|
|
577
|
-
var TooltipTrigger =
|
|
578
|
-
|
|
865
|
+
var TooltipTrigger = ({
|
|
866
|
+
asChild,
|
|
867
|
+
children,
|
|
868
|
+
ref,
|
|
869
|
+
...props
|
|
870
|
+
}) => {
|
|
871
|
+
if (asChild && React5.isValidElement(children)) {
|
|
579
872
|
return /* @__PURE__ */ jsx(
|
|
580
873
|
Tooltip$1.Trigger,
|
|
581
874
|
{
|
|
@@ -586,183 +879,147 @@ var TooltipTrigger = React6.forwardRef(({ asChild, children, ...props }, ref) =>
|
|
|
586
879
|
);
|
|
587
880
|
}
|
|
588
881
|
return /* @__PURE__ */ jsx(Tooltip$1.Trigger, { ref, ...props, children });
|
|
589
|
-
}
|
|
882
|
+
};
|
|
590
883
|
TooltipTrigger.displayName = "TooltipTrigger";
|
|
591
|
-
var TooltipContent =
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
884
|
+
var TooltipContent = ({
|
|
885
|
+
className,
|
|
886
|
+
style,
|
|
887
|
+
side = "top",
|
|
888
|
+
align = "center",
|
|
889
|
+
sideOffset = 4,
|
|
890
|
+
alignOffset = 0,
|
|
891
|
+
ref,
|
|
892
|
+
...props
|
|
893
|
+
}) => /* @__PURE__ */ jsx(Tooltip$1.Portal, { children: /* @__PURE__ */ jsx(
|
|
894
|
+
Tooltip$1.Positioner,
|
|
895
|
+
{
|
|
896
|
+
side,
|
|
897
|
+
align,
|
|
898
|
+
sideOffset,
|
|
899
|
+
alignOffset,
|
|
900
|
+
style: { zIndex: overlayZIndex.tooltip },
|
|
901
|
+
children: /* @__PURE__ */ jsx(
|
|
902
|
+
Tooltip$1.Popup,
|
|
903
|
+
{
|
|
904
|
+
ref,
|
|
905
|
+
className: cn(overlayClassNames.tooltipSurface, className),
|
|
906
|
+
style: { zIndex: overlayZIndex.tooltip, ...style },
|
|
907
|
+
...props
|
|
908
|
+
}
|
|
909
|
+
)
|
|
910
|
+
}
|
|
911
|
+
) });
|
|
614
912
|
TooltipContent.displayName = "TooltipContent";
|
|
615
|
-
var
|
|
913
|
+
var MAX_VISUALIZER_BARS = 64;
|
|
914
|
+
var VISUALIZER_BAR_STYLES = Array.from({ length: MAX_VISUALIZER_BARS }, (_, index) => ({
|
|
915
|
+
id: `voice-bar-${index}`,
|
|
916
|
+
height: `${15 + index * 37 % 86}%`,
|
|
917
|
+
animationDelay: `${index * 0.05}s`,
|
|
918
|
+
animationDuration: `${0.5 + index * 17 % 6 / 10}s`
|
|
919
|
+
}));
|
|
920
|
+
var formatRecordingTime = (seconds) => {
|
|
921
|
+
const mins = Math.floor(seconds / 60);
|
|
922
|
+
const secs = seconds % 60;
|
|
923
|
+
return `${mins.toString().padStart(2, "0")}:${secs.toString().padStart(2, "0")}`;
|
|
924
|
+
};
|
|
616
925
|
var VoiceRecorder = ({
|
|
617
926
|
isRecording,
|
|
618
|
-
|
|
619
|
-
onStopRecording,
|
|
927
|
+
time,
|
|
620
928
|
visualizerBars = 32
|
|
621
929
|
}) => {
|
|
622
|
-
const
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
onStartRecording();
|
|
627
|
-
timerRef.current = setInterval(() => setTime((t) => t + 1), 1e3);
|
|
628
|
-
} else {
|
|
629
|
-
if (timerRef.current) {
|
|
630
|
-
clearInterval(timerRef.current);
|
|
631
|
-
timerRef.current = null;
|
|
632
|
-
}
|
|
633
|
-
onStopRecording(time);
|
|
634
|
-
setTime(0);
|
|
635
|
-
}
|
|
636
|
-
return () => {
|
|
637
|
-
if (timerRef.current) clearInterval(timerRef.current);
|
|
638
|
-
};
|
|
639
|
-
}, [isRecording, time, onStartRecording, onStopRecording]);
|
|
640
|
-
const formatTime = (seconds) => {
|
|
641
|
-
const mins = Math.floor(seconds / 60);
|
|
642
|
-
const secs = seconds % 60;
|
|
643
|
-
return `${mins.toString().padStart(2, "0")}:${secs.toString().padStart(2, "0")}`;
|
|
644
|
-
};
|
|
930
|
+
const barStyles = VISUALIZER_BAR_STYLES.slice(
|
|
931
|
+
0,
|
|
932
|
+
Math.min(visualizerBars, VISUALIZER_BAR_STYLES.length)
|
|
933
|
+
);
|
|
645
934
|
return /* @__PURE__ */ jsxs(
|
|
646
935
|
"div",
|
|
647
936
|
{
|
|
648
|
-
className:
|
|
649
|
-
"flex flex-col items-center justify-center w-full transition-
|
|
937
|
+
className: cn(
|
|
938
|
+
"flex flex-col items-center justify-center w-full transition-[background-color,border-color,box-shadow,color,opacity,transform] duration-300 py-3",
|
|
650
939
|
isRecording ? "opacity-100" : "opacity-0 h-0"
|
|
651
940
|
),
|
|
652
941
|
children: [
|
|
653
942
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-3", children: [
|
|
654
943
|
/* @__PURE__ */ jsx("div", { className: "h-2 w-2 rounded-full bg-red-500 animate-pulse" }),
|
|
655
|
-
/* @__PURE__ */ jsx("span", { className: "font-mono text-sm text-white/80", children:
|
|
944
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono text-sm text-white/80", children: formatRecordingTime(time) })
|
|
656
945
|
] }),
|
|
657
|
-
/* @__PURE__ */ jsx("div", { className: "w-full h-10 flex items-center justify-center gap-0.5 px-4", children:
|
|
946
|
+
/* @__PURE__ */ jsx("div", { className: "w-full h-10 flex items-center justify-center gap-0.5 px-4", children: barStyles.map((bar) => /* @__PURE__ */ jsx(
|
|
658
947
|
"div",
|
|
659
948
|
{
|
|
660
949
|
className: "w-0.5 rounded-full bg-white/50 animate-pulse",
|
|
661
950
|
style: {
|
|
662
|
-
height:
|
|
663
|
-
animationDelay:
|
|
664
|
-
animationDuration:
|
|
951
|
+
height: bar.height,
|
|
952
|
+
animationDelay: bar.animationDelay,
|
|
953
|
+
animationDuration: bar.animationDuration
|
|
665
954
|
}
|
|
666
955
|
},
|
|
667
|
-
|
|
956
|
+
bar.id
|
|
668
957
|
)) })
|
|
669
958
|
]
|
|
670
959
|
}
|
|
671
960
|
);
|
|
672
961
|
};
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
return /* @__PURE__ */ jsx(Dialog, { open: !!imageUrl, onOpenChange: onClose, children: /* @__PURE__ */ jsxs(DialogContent, { className: "p-0 border-none bg-transparent shadow-none max-w-[90vw] md:max-w-[800px]", children: [
|
|
676
|
-
/* @__PURE__ */ jsx(DialogTitle, { className: "sr-only", children: "Image Preview" }),
|
|
677
|
-
/* @__PURE__ */ jsx(
|
|
678
|
-
motion.div,
|
|
679
|
-
{
|
|
680
|
-
initial: { opacity: 0, scale: 0.95 },
|
|
681
|
-
animate: { opacity: 1, scale: 1 },
|
|
682
|
-
exit: { opacity: 0, scale: 0.95 },
|
|
683
|
-
transition: { duration: 0.2, ease: "easeOut" },
|
|
684
|
-
className: "relative bg-background rounded-2xl overflow-hidden shadow-2xl",
|
|
685
|
-
children: /* @__PURE__ */ jsx(
|
|
686
|
-
Image,
|
|
687
|
-
{
|
|
688
|
-
src: imageUrl,
|
|
689
|
-
alt: "Full preview",
|
|
690
|
-
className: "w-full max-h-[80vh] object-contain rounded-2xl",
|
|
691
|
-
fill: true
|
|
692
|
-
}
|
|
693
|
-
)
|
|
694
|
-
}
|
|
695
|
-
)
|
|
696
|
-
] }) });
|
|
962
|
+
VoiceRecorder.displayName = "VoiceRecorder";
|
|
963
|
+
var noopSetPromptValue = (_value) => {
|
|
697
964
|
};
|
|
698
|
-
var
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
onSubmit: void 0,
|
|
705
|
-
disabled: false
|
|
706
|
-
});
|
|
965
|
+
var PromptInputIsLoadingContext = React5__default.createContext(false);
|
|
966
|
+
var PromptInputValueContext = React5__default.createContext("");
|
|
967
|
+
var PromptInputSetValueContext = React5__default.createContext(noopSetPromptValue);
|
|
968
|
+
var PromptInputMaxHeightContext = React5__default.createContext(240);
|
|
969
|
+
var PromptInputSubmitContext = React5__default.createContext(void 0);
|
|
970
|
+
var PromptInputDisabledContext = React5__default.createContext(false);
|
|
707
971
|
function usePromptInput() {
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
972
|
+
return {
|
|
973
|
+
isLoading: React5__default.use(PromptInputIsLoadingContext),
|
|
974
|
+
value: React5__default.use(PromptInputValueContext),
|
|
975
|
+
setValue: React5__default.use(PromptInputSetValueContext),
|
|
976
|
+
maxHeight: React5__default.use(PromptInputMaxHeightContext),
|
|
977
|
+
onSubmit: React5__default.use(PromptInputSubmitContext),
|
|
978
|
+
disabled: React5__default.use(PromptInputDisabledContext)
|
|
979
|
+
};
|
|
711
980
|
}
|
|
712
|
-
var PromptInput =
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
className
|
|
750
|
-
),
|
|
751
|
-
onDragOver,
|
|
752
|
-
onDragLeave,
|
|
753
|
-
onDrop,
|
|
754
|
-
children
|
|
755
|
-
}
|
|
756
|
-
)
|
|
757
|
-
}
|
|
758
|
-
) });
|
|
759
|
-
}
|
|
760
|
-
);
|
|
981
|
+
var PromptInput = ({
|
|
982
|
+
className,
|
|
983
|
+
isLoading = false,
|
|
984
|
+
maxHeight = 240,
|
|
985
|
+
value,
|
|
986
|
+
onValueChange,
|
|
987
|
+
onSubmit,
|
|
988
|
+
children,
|
|
989
|
+
disabled = false,
|
|
990
|
+
onDragOver,
|
|
991
|
+
onDragLeave,
|
|
992
|
+
onDrop,
|
|
993
|
+
ref
|
|
994
|
+
}) => {
|
|
995
|
+
const [internalValue, setInternalValue] = React5__default.useState(value || "");
|
|
996
|
+
const handleChange = (newValue) => {
|
|
997
|
+
setInternalValue(newValue);
|
|
998
|
+
onValueChange?.(newValue);
|
|
999
|
+
};
|
|
1000
|
+
const promptValue = value ?? internalValue;
|
|
1001
|
+
const setPromptValue = onValueChange ?? handleChange;
|
|
1002
|
+
return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsx(PromptInputIsLoadingContext.Provider, { value: isLoading, children: /* @__PURE__ */ jsx(PromptInputValueContext.Provider, { value: promptValue, children: /* @__PURE__ */ jsx(PromptInputSetValueContext.Provider, { value: setPromptValue, children: /* @__PURE__ */ jsx(PromptInputMaxHeightContext.Provider, { value: maxHeight, children: /* @__PURE__ */ jsx(PromptInputSubmitContext.Provider, { value: onSubmit, children: /* @__PURE__ */ jsx(PromptInputDisabledContext.Provider, { value: disabled, children: /* @__PURE__ */ jsx(
|
|
1003
|
+
"div",
|
|
1004
|
+
{
|
|
1005
|
+
ref,
|
|
1006
|
+
className: cn(
|
|
1007
|
+
"rounded-[var(--radius-3xl)] border border-input bg-background p-2 shadow-lg transition-[background-color,border-color,box-shadow,color,opacity,transform] duration-300",
|
|
1008
|
+
isLoading && "border-destructive/70",
|
|
1009
|
+
className
|
|
1010
|
+
),
|
|
1011
|
+
onDragOver,
|
|
1012
|
+
onDragLeave,
|
|
1013
|
+
onDrop,
|
|
1014
|
+
children
|
|
1015
|
+
}
|
|
1016
|
+
) }) }) }) }) }) }) });
|
|
1017
|
+
};
|
|
761
1018
|
PromptInput.displayName = "PromptInput";
|
|
762
1019
|
var PromptInputTextarea = ({ className, onKeyDown, disableAutosize = false, placeholder, style, ...props }) => {
|
|
763
1020
|
const { value, setValue, maxHeight, onSubmit, disabled } = usePromptInput();
|
|
764
|
-
const textareaRef =
|
|
765
|
-
|
|
1021
|
+
const textareaRef = React5__default.useRef(null);
|
|
1022
|
+
React5__default.useEffect(() => {
|
|
766
1023
|
if (disableAutosize || !textareaRef.current) return;
|
|
767
1024
|
textareaRef.current.style.height = "auto";
|
|
768
1025
|
textareaRef.current.style.height = typeof maxHeight === "number" ? `${Math.min(textareaRef.current.scrollHeight, maxHeight)}px` : `min(${textareaRef.current.scrollHeight}px, ${maxHeight})`;
|
|
@@ -772,461 +1029,490 @@ var PromptInputTextarea = ({ className, onKeyDown, disableAutosize = false, plac
|
|
|
772
1029
|
e.preventDefault();
|
|
773
1030
|
onSubmit?.();
|
|
774
1031
|
}
|
|
775
|
-
onKeyDown?.(e);
|
|
776
|
-
};
|
|
1032
|
+
onKeyDown?.(e);
|
|
1033
|
+
};
|
|
1034
|
+
return /* @__PURE__ */ jsx(
|
|
1035
|
+
Textarea,
|
|
1036
|
+
{
|
|
1037
|
+
ref: textareaRef,
|
|
1038
|
+
value,
|
|
1039
|
+
onChange: (e) => setValue(e.target.value),
|
|
1040
|
+
onKeyDown: handleKeyDown,
|
|
1041
|
+
rows: 1,
|
|
1042
|
+
style: { "--textarea-min-height": "2rem", ...style },
|
|
1043
|
+
className: cn("resize-none border-0 shadow-none focus-visible:ring-0", className),
|
|
1044
|
+
disabled,
|
|
1045
|
+
placeholder,
|
|
1046
|
+
...props
|
|
1047
|
+
}
|
|
1048
|
+
);
|
|
1049
|
+
};
|
|
1050
|
+
var PromptInputActions = ({
|
|
1051
|
+
children,
|
|
1052
|
+
className,
|
|
1053
|
+
...props
|
|
1054
|
+
}) => /* @__PURE__ */ jsx("div", { className: cn("flex items-center gap-2", className), ...props, children });
|
|
1055
|
+
var PromptInputAction = ({
|
|
1056
|
+
tooltip,
|
|
1057
|
+
children,
|
|
1058
|
+
className,
|
|
1059
|
+
side = "top",
|
|
1060
|
+
...props
|
|
1061
|
+
}) => {
|
|
1062
|
+
const { disabled } = usePromptInput();
|
|
1063
|
+
return /* @__PURE__ */ jsxs(Tooltip, { ...props, children: [
|
|
1064
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, disabled, children }),
|
|
1065
|
+
/* @__PURE__ */ jsx(TooltipContent, { side, className: className || "", children: tooltip })
|
|
1066
|
+
] });
|
|
1067
|
+
};
|
|
1068
|
+
var CustomDivider = () => /* @__PURE__ */ jsx("div", { className: "relative h-6 w-[1.5px] mx-1", children: /* @__PURE__ */ jsx(
|
|
1069
|
+
"div",
|
|
1070
|
+
{
|
|
1071
|
+
className: "absolute inset-0 bg-gradient-to-t from-transparent via-cyan/40 to-transparent rounded-full",
|
|
1072
|
+
style: {
|
|
1073
|
+
clipPath: "polygon(0% 0%, 100% 0%, 100% 40%, 140% 50%, 100% 60%, 100% 100%, 0% 100%, 0% 60%, -40% 50%, 0% 40%)"
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
) });
|
|
1077
|
+
var promptModeToneClassName = {
|
|
1078
|
+
search: {
|
|
1079
|
+
active: "bg-info/15 border-info text-info",
|
|
1080
|
+
icon: "text-info",
|
|
1081
|
+
label: "text-info"
|
|
1082
|
+
},
|
|
1083
|
+
think: {
|
|
1084
|
+
active: "bg-indigo-500/15 border-indigo-500 text-indigo-500",
|
|
1085
|
+
icon: "text-indigo-500",
|
|
1086
|
+
label: "text-indigo-500"
|
|
1087
|
+
},
|
|
1088
|
+
canvas: {
|
|
1089
|
+
active: "bg-warning/15 border-warning text-warning",
|
|
1090
|
+
icon: "text-warning",
|
|
1091
|
+
label: "text-warning"
|
|
1092
|
+
}
|
|
1093
|
+
};
|
|
1094
|
+
function PromptModeIcon({ tone, active }) {
|
|
1095
|
+
const className = cn("w-4 h-4", active ? promptModeToneClassName[tone].icon : "text-inherit");
|
|
1096
|
+
if (tone === "search") return /* @__PURE__ */ jsx(Globe, { className });
|
|
1097
|
+
if (tone === "think") return /* @__PURE__ */ jsx(Brain, { className });
|
|
1098
|
+
return /* @__PURE__ */ jsx(FolderClosed, { className });
|
|
1099
|
+
}
|
|
1100
|
+
function PromptModeButton({
|
|
1101
|
+
active,
|
|
1102
|
+
label,
|
|
1103
|
+
tone,
|
|
1104
|
+
onClick
|
|
1105
|
+
}) {
|
|
1106
|
+
const toneClassName = promptModeToneClassName[tone];
|
|
1107
|
+
const shouldReduceMotion = useReducedMotion();
|
|
1108
|
+
return /* @__PURE__ */ jsxs(
|
|
1109
|
+
"button",
|
|
1110
|
+
{
|
|
1111
|
+
type: "button",
|
|
1112
|
+
onClick,
|
|
1113
|
+
className: cn(
|
|
1114
|
+
"rounded-full transition-[background-color,border-color,box-shadow,color,opacity,transform] flex items-center gap-1 px-2 py-1 border h-8",
|
|
1115
|
+
active ? toneClassName.active : "bg-transparent border-transparent text-muted-foreground hover:text-foreground"
|
|
1116
|
+
),
|
|
1117
|
+
children: [
|
|
1118
|
+
/* @__PURE__ */ jsx("div", { className: "w-5 h-5 flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsx(
|
|
1119
|
+
m.div,
|
|
1120
|
+
{
|
|
1121
|
+
animate: shouldReduceMotion ? { opacity: active ? 1 : 0.82 } : { rotate: active ? 360 : 0, scale: active ? 1.1 : 1 },
|
|
1122
|
+
whileHover: shouldReduceMotion ? { opacity: 1 } : {
|
|
1123
|
+
rotate: active ? 360 : 15,
|
|
1124
|
+
scale: 1.1,
|
|
1125
|
+
transition: { type: "spring", stiffness: 300, damping: 10 }
|
|
1126
|
+
},
|
|
1127
|
+
transition: shouldReduceMotion ? { duration: 0 } : { type: "spring", stiffness: 260, damping: 25 },
|
|
1128
|
+
children: /* @__PURE__ */ jsx(PromptModeIcon, { tone, active })
|
|
1129
|
+
}
|
|
1130
|
+
) }),
|
|
1131
|
+
/* @__PURE__ */ jsx(AnimatePresence, { children: active && /* @__PURE__ */ jsx(
|
|
1132
|
+
m.span,
|
|
1133
|
+
{
|
|
1134
|
+
initial: shouldReduceMotion ? { opacity: 1 } : { width: 0, opacity: 0 },
|
|
1135
|
+
animate: { width: "auto", opacity: 1 },
|
|
1136
|
+
exit: shouldReduceMotion ? { opacity: 0 } : { width: 0, opacity: 0 },
|
|
1137
|
+
transition: shouldReduceMotion ? { duration: 0 } : { duration: 0.2 },
|
|
1138
|
+
className: cn(
|
|
1139
|
+
"text-xs overflow-hidden whitespace-nowrap flex-shrink-0",
|
|
1140
|
+
toneClassName.label
|
|
1141
|
+
),
|
|
1142
|
+
children: label
|
|
1143
|
+
}
|
|
1144
|
+
) })
|
|
1145
|
+
]
|
|
1146
|
+
}
|
|
1147
|
+
);
|
|
1148
|
+
}
|
|
1149
|
+
function PromptModeActions({
|
|
1150
|
+
uploadInputRef,
|
|
1151
|
+
isRecording,
|
|
1152
|
+
modes,
|
|
1153
|
+
onToggleMode,
|
|
1154
|
+
onToggleCanvas,
|
|
1155
|
+
onProcessFile
|
|
1156
|
+
}) {
|
|
1157
|
+
return /* @__PURE__ */ jsxs(
|
|
1158
|
+
"div",
|
|
1159
|
+
{
|
|
1160
|
+
className: cn(
|
|
1161
|
+
"flex items-center gap-1 transition-opacity duration-300",
|
|
1162
|
+
isRecording ? "opacity-0 invisible h-0" : "opacity-100 visible"
|
|
1163
|
+
),
|
|
1164
|
+
children: [
|
|
1165
|
+
/* @__PURE__ */ jsx(PromptInputAction, { tooltip: "Upload image", children: /* @__PURE__ */ jsx(
|
|
1166
|
+
"button",
|
|
1167
|
+
{
|
|
1168
|
+
type: "button",
|
|
1169
|
+
"aria-label": "Upload image",
|
|
1170
|
+
onClick: () => uploadInputRef.current?.click(),
|
|
1171
|
+
className: "flex h-8 w-8 text-muted-foreground cursor-pointer items-center justify-center rounded-full transition-colors hover:bg-accent hover:text-foreground",
|
|
1172
|
+
disabled: isRecording,
|
|
1173
|
+
children: /* @__PURE__ */ jsx(Paperclip, { className: "h-5 w-5 transition-colors" })
|
|
1174
|
+
}
|
|
1175
|
+
) }),
|
|
1176
|
+
/* @__PURE__ */ jsx(
|
|
1177
|
+
"input",
|
|
1178
|
+
{
|
|
1179
|
+
ref: uploadInputRef,
|
|
1180
|
+
type: "file",
|
|
1181
|
+
className: "hidden",
|
|
1182
|
+
onChange: (event) => {
|
|
1183
|
+
const file = event.target.files?.[0];
|
|
1184
|
+
if (file) onProcessFile(file);
|
|
1185
|
+
if (event.target) event.target.value = "";
|
|
1186
|
+
},
|
|
1187
|
+
accept: "image/*",
|
|
1188
|
+
"aria-label": "Upload image"
|
|
1189
|
+
}
|
|
1190
|
+
),
|
|
1191
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
1192
|
+
/* @__PURE__ */ jsx(
|
|
1193
|
+
PromptModeButton,
|
|
1194
|
+
{
|
|
1195
|
+
active: modes.search,
|
|
1196
|
+
label: "Search",
|
|
1197
|
+
tone: "search",
|
|
1198
|
+
onClick: () => onToggleMode("search")
|
|
1199
|
+
}
|
|
1200
|
+
),
|
|
1201
|
+
/* @__PURE__ */ jsx(CustomDivider, {}),
|
|
1202
|
+
/* @__PURE__ */ jsx(
|
|
1203
|
+
PromptModeButton,
|
|
1204
|
+
{
|
|
1205
|
+
active: modes.think,
|
|
1206
|
+
label: "Think",
|
|
1207
|
+
tone: "think",
|
|
1208
|
+
onClick: () => onToggleMode("think")
|
|
1209
|
+
}
|
|
1210
|
+
),
|
|
1211
|
+
/* @__PURE__ */ jsx(CustomDivider, {}),
|
|
1212
|
+
/* @__PURE__ */ jsx(
|
|
1213
|
+
PromptModeButton,
|
|
1214
|
+
{
|
|
1215
|
+
active: modes.canvas,
|
|
1216
|
+
label: "Canvas",
|
|
1217
|
+
tone: "canvas",
|
|
1218
|
+
onClick: onToggleCanvas
|
|
1219
|
+
}
|
|
1220
|
+
)
|
|
1221
|
+
] })
|
|
1222
|
+
]
|
|
1223
|
+
}
|
|
1224
|
+
);
|
|
1225
|
+
}
|
|
1226
|
+
function PromptSubmitAction({
|
|
1227
|
+
isLoading,
|
|
1228
|
+
isRecording,
|
|
1229
|
+
hasContent,
|
|
1230
|
+
onActivate
|
|
1231
|
+
}) {
|
|
1232
|
+
const shouldReduceMotion = useReducedMotion();
|
|
777
1233
|
return /* @__PURE__ */ jsx(
|
|
778
|
-
|
|
1234
|
+
PromptInputAction,
|
|
779
1235
|
{
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
1236
|
+
tooltip: isLoading ? "Stop generation" : isRecording ? "Stop recording" : hasContent ? "Send message" : "Voice message",
|
|
1237
|
+
children: /* @__PURE__ */ jsx(
|
|
1238
|
+
Button,
|
|
1239
|
+
{
|
|
1240
|
+
variant: "default",
|
|
1241
|
+
size: "icon",
|
|
1242
|
+
className: cn(
|
|
1243
|
+
"h-8 w-8 rounded-full transition-[background-color,border-color,box-shadow,color,opacity,transform] duration-200",
|
|
1244
|
+
isRecording ? "bg-transparent hover:bg-accent text-destructive hover:text-destructive/80" : hasContent ? "bg-primary hover:bg-primary/90 text-primary-foreground" : "bg-transparent hover:bg-accent text-muted-foreground hover:text-foreground"
|
|
1245
|
+
),
|
|
1246
|
+
onClick: onActivate,
|
|
1247
|
+
disabled: isLoading && !hasContent,
|
|
1248
|
+
children: isLoading ? /* @__PURE__ */ jsx(
|
|
1249
|
+
StopFill,
|
|
1250
|
+
{
|
|
1251
|
+
className: cn(
|
|
1252
|
+
"h-4 w-4 fill-primary-foreground",
|
|
1253
|
+
shouldReduceMotion ? "opacity-100" : "animate-pulse"
|
|
1254
|
+
)
|
|
1255
|
+
}
|
|
1256
|
+
) : isRecording ? /* @__PURE__ */ jsx(StopCircle, { className: "h-5 w-5 text-destructive" }) : hasContent ? /* @__PURE__ */ jsx(ArrowUp, { className: "h-4 w-4 text-primary-foreground" }) : /* @__PURE__ */ jsx(Microphone, { className: "h-5 w-5 text-primary-foreground transition-colors" })
|
|
1257
|
+
}
|
|
1258
|
+
)
|
|
790
1259
|
}
|
|
791
1260
|
);
|
|
1261
|
+
}
|
|
1262
|
+
var promptInputBoxInitialState = {
|
|
1263
|
+
input: "",
|
|
1264
|
+
files: [],
|
|
1265
|
+
filePreviews: {},
|
|
1266
|
+
selectedImage: null,
|
|
1267
|
+
isRecording: false,
|
|
1268
|
+
recordingTime: 0,
|
|
1269
|
+
showSearch: false,
|
|
1270
|
+
showThink: false,
|
|
1271
|
+
showCanvas: false
|
|
792
1272
|
};
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
] });
|
|
810
|
-
};
|
|
811
|
-
var CustomDivider = () => /* @__PURE__ */ jsx("div", { className: "relative h-6 w-[1.5px] mx-1", children: /* @__PURE__ */ jsx(
|
|
812
|
-
"div",
|
|
813
|
-
{
|
|
814
|
-
className: "absolute inset-0 bg-gradient-to-t from-transparent via-cyan/40 to-transparent rounded-full",
|
|
815
|
-
style: {
|
|
816
|
-
clipPath: "polygon(0% 0%, 100% 0%, 100% 40%, 140% 50%, 100% 60%, 100% 100%, 0% 100%, 0% 60%, -40% 50%, 0% 40%)"
|
|
1273
|
+
function promptInputBoxReducer(state, action) {
|
|
1274
|
+
switch (action.type) {
|
|
1275
|
+
case "set-input":
|
|
1276
|
+
return { ...state, input: action.value };
|
|
1277
|
+
case "set-active-file":
|
|
1278
|
+
return { ...state, files: [action.file], filePreviews: {} };
|
|
1279
|
+
case "set-file-preview":
|
|
1280
|
+
return { ...state, filePreviews: { [action.previewKey]: action.preview } };
|
|
1281
|
+
case "remove-file": {
|
|
1282
|
+
const nextPreviews = { ...state.filePreviews };
|
|
1283
|
+
delete nextPreviews[action.previewKey];
|
|
1284
|
+
return {
|
|
1285
|
+
...state,
|
|
1286
|
+
filePreviews: nextPreviews,
|
|
1287
|
+
files: state.files.filter((file) => getFilePreviewKey(file) !== action.previewKey)
|
|
1288
|
+
};
|
|
817
1289
|
}
|
|
1290
|
+
case "set-selected-image":
|
|
1291
|
+
return { ...state, selectedImage: action.imageUrl };
|
|
1292
|
+
case "toggle-mode":
|
|
1293
|
+
if (action.mode === "search") {
|
|
1294
|
+
return { ...state, showSearch: !state.showSearch, showThink: false };
|
|
1295
|
+
}
|
|
1296
|
+
if (action.mode === "think") {
|
|
1297
|
+
return { ...state, showSearch: false, showThink: !state.showThink };
|
|
1298
|
+
}
|
|
1299
|
+
return { ...state, showCanvas: !state.showCanvas };
|
|
1300
|
+
case "start-recording":
|
|
1301
|
+
return { ...state, recordingTime: 0, isRecording: true };
|
|
1302
|
+
case "tick-recording":
|
|
1303
|
+
return { ...state, recordingTime: state.recordingTime + 1 };
|
|
1304
|
+
case "stop-recording":
|
|
1305
|
+
return { ...state, isRecording: false, recordingTime: 0 };
|
|
1306
|
+
case "reset-composer":
|
|
1307
|
+
return { ...state, input: "", files: [], filePreviews: {} };
|
|
818
1308
|
}
|
|
819
|
-
|
|
820
|
-
var PromptInputBox =
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
1309
|
+
}
|
|
1310
|
+
var PromptInputBox = (props) => {
|
|
1311
|
+
const {
|
|
1312
|
+
onSend = () => {
|
|
1313
|
+
},
|
|
1314
|
+
isLoading = false,
|
|
1315
|
+
placeholder = "Type your message here...",
|
|
1316
|
+
className,
|
|
1317
|
+
ref
|
|
1318
|
+
} = props;
|
|
1319
|
+
const [state, dispatch] = React5__default.useReducer(promptInputBoxReducer, promptInputBoxInitialState);
|
|
1320
|
+
const {
|
|
1321
|
+
input,
|
|
1322
|
+
files,
|
|
1323
|
+
filePreviews,
|
|
1324
|
+
selectedImage,
|
|
1325
|
+
isRecording,
|
|
1326
|
+
recordingTime,
|
|
1327
|
+
showSearch,
|
|
1328
|
+
showThink,
|
|
1329
|
+
showCanvas
|
|
1330
|
+
} = state;
|
|
1331
|
+
const uploadInputRef = React5__default.useRef(null);
|
|
1332
|
+
const promptBoxRef = React5__default.useRef(null);
|
|
1333
|
+
const handleToggleChange = (mode) => dispatch({ type: "toggle-mode", mode });
|
|
1334
|
+
const handleCanvasToggle = () => dispatch({ type: "toggle-mode", mode: "canvas" });
|
|
1335
|
+
const processFile = (file) => {
|
|
1336
|
+
if (!isImageFile(file)) {
|
|
1337
|
+
return;
|
|
1338
|
+
}
|
|
1339
|
+
if (file.size > 10 * 1024 * 1024) {
|
|
1340
|
+
return;
|
|
1341
|
+
}
|
|
1342
|
+
const previewKey = getFilePreviewKey(file);
|
|
1343
|
+
dispatch({ type: "set-active-file", file });
|
|
1344
|
+
const reader = new FileReader();
|
|
1345
|
+
reader.onload = (e) => {
|
|
1346
|
+
const preview = e.target?.result;
|
|
1347
|
+
if (typeof preview === "string") {
|
|
1348
|
+
dispatch({ type: "set-file-preview", previewKey, preview });
|
|
846
1349
|
}
|
|
847
1350
|
};
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
1351
|
+
reader.readAsDataURL(file);
|
|
1352
|
+
};
|
|
1353
|
+
const handleDrop = (e) => {
|
|
1354
|
+
preventDragDefaults(e);
|
|
1355
|
+
const droppedFiles = Array.from(e.dataTransfer.files);
|
|
1356
|
+
const firstFile = droppedFiles.find((file) => isImageFile(file));
|
|
1357
|
+
if (firstFile) processFile(firstFile);
|
|
1358
|
+
};
|
|
1359
|
+
const handleRemoveFile = (fileToRemove) => {
|
|
1360
|
+
const previewKey = getFilePreviewKey(fileToRemove);
|
|
1361
|
+
dispatch({ type: "remove-file", previewKey });
|
|
1362
|
+
};
|
|
1363
|
+
const openImageModal = (imageUrl) => dispatch({ type: "set-selected-image", imageUrl });
|
|
1364
|
+
const handlePasteEvent = useEffectEvent((e) => {
|
|
1365
|
+
const items = e.clipboardData?.items;
|
|
1366
|
+
if (!items) return;
|
|
1367
|
+
for (const item of Array.from(items)) {
|
|
1368
|
+
if (item.type.includes("image")) {
|
|
1369
|
+
const file = item.getAsFile();
|
|
1370
|
+
if (file) {
|
|
1371
|
+
e.preventDefault();
|
|
1372
|
+
processFile(file);
|
|
1373
|
+
break;
|
|
857
1374
|
}
|
|
858
|
-
setFiles([file]);
|
|
859
|
-
const reader = new FileReader();
|
|
860
|
-
reader.onload = (e) => setFilePreviews({ [file.name]: e.target?.result });
|
|
861
|
-
reader.readAsDataURL(file);
|
|
862
|
-
},
|
|
863
|
-
[isImageFile]
|
|
864
|
-
);
|
|
865
|
-
const handleDragOver = React6__default.useCallback((e) => {
|
|
866
|
-
e.preventDefault();
|
|
867
|
-
e.stopPropagation();
|
|
868
|
-
}, []);
|
|
869
|
-
const handleDragLeave = React6__default.useCallback((e) => {
|
|
870
|
-
e.preventDefault();
|
|
871
|
-
e.stopPropagation();
|
|
872
|
-
}, []);
|
|
873
|
-
const handleDrop = React6__default.useCallback(
|
|
874
|
-
(e) => {
|
|
875
|
-
e.preventDefault();
|
|
876
|
-
e.stopPropagation();
|
|
877
|
-
const files2 = Array.from(e.dataTransfer.files);
|
|
878
|
-
const imageFiles = files2.filter((file) => isImageFile(file));
|
|
879
|
-
const firstFile = imageFiles[0];
|
|
880
|
-
if (firstFile) processFile(firstFile);
|
|
881
|
-
},
|
|
882
|
-
[isImageFile, processFile]
|
|
883
|
-
);
|
|
884
|
-
const handleRemoveFile = (index) => {
|
|
885
|
-
const fileToRemove = files[index];
|
|
886
|
-
if (fileToRemove && filePreviews[fileToRemove.name]) {
|
|
887
|
-
const newPreviews = { ...filePreviews };
|
|
888
|
-
delete newPreviews[fileToRemove.name];
|
|
889
|
-
setFilePreviews(newPreviews);
|
|
890
1375
|
}
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
const handlePaste =
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
1376
|
+
}
|
|
1377
|
+
});
|
|
1378
|
+
React5__default.useEffect(() => {
|
|
1379
|
+
const handlePaste = (e) => handlePasteEvent(e);
|
|
1380
|
+
document.addEventListener("paste", handlePaste);
|
|
1381
|
+
return () => document.removeEventListener("paste", handlePaste);
|
|
1382
|
+
}, []);
|
|
1383
|
+
React5__default.useEffect(() => {
|
|
1384
|
+
if (!isRecording) return;
|
|
1385
|
+
const timer = window.setInterval(() => dispatch({ type: "tick-recording" }), 1e3);
|
|
1386
|
+
return () => window.clearInterval(timer);
|
|
1387
|
+
}, [isRecording]);
|
|
1388
|
+
const handleSubmit = () => {
|
|
1389
|
+
if (input.trim() || files.length > 0) {
|
|
1390
|
+
let messagePrefix = "";
|
|
1391
|
+
if (showSearch) messagePrefix = "[Search: ";
|
|
1392
|
+
else if (showThink) messagePrefix = "[Think: ";
|
|
1393
|
+
else if (showCanvas) messagePrefix = "[Canvas: ";
|
|
1394
|
+
const formattedInput = messagePrefix ? `${messagePrefix}${input}]` : input;
|
|
1395
|
+
onSend(formattedInput, files);
|
|
1396
|
+
dispatch({ type: "reset-composer" });
|
|
1397
|
+
}
|
|
1398
|
+
};
|
|
1399
|
+
const startRecording = () => dispatch({ type: "start-recording" });
|
|
1400
|
+
const stopRecording = () => {
|
|
1401
|
+
onSend(`[Voice message - ${recordingTime} seconds]`, []);
|
|
1402
|
+
dispatch({ type: "stop-recording" });
|
|
1403
|
+
};
|
|
1404
|
+
const hasContent = input.trim() !== "" || files.length > 0;
|
|
1405
|
+
return /* @__PURE__ */ jsxs(LazyMotion, { features: domAnimation, children: [
|
|
1406
|
+
/* @__PURE__ */ jsxs(
|
|
1407
|
+
PromptInput,
|
|
1408
|
+
{
|
|
1409
|
+
value: input,
|
|
1410
|
+
onValueChange: (value) => dispatch({ type: "set-input", value }),
|
|
1411
|
+
isLoading,
|
|
1412
|
+
onSubmit: handleSubmit,
|
|
1413
|
+
className: cn(
|
|
1414
|
+
"w-full bg-background border-input shadow-lg transition-[background-color,border-color,box-shadow,color,opacity,transform] duration-300 ease-in-out",
|
|
1415
|
+
isRecording && "border-destructive/70",
|
|
1416
|
+
className
|
|
1417
|
+
),
|
|
1418
|
+
disabled: isLoading || isRecording,
|
|
1419
|
+
ref: ref || promptBoxRef,
|
|
1420
|
+
onDragOver: preventDragDefaults,
|
|
1421
|
+
onDragLeave: preventDragDefaults,
|
|
1422
|
+
onDrop: handleDrop,
|
|
1423
|
+
children: [
|
|
1424
|
+
/* @__PURE__ */ jsx(
|
|
1425
|
+
PromptAttachmentPreviews,
|
|
1426
|
+
{
|
|
1427
|
+
files,
|
|
1428
|
+
filePreviews,
|
|
1429
|
+
isRecording,
|
|
1430
|
+
onPreview: openImageModal,
|
|
1431
|
+
onRemove: handleRemoveFile
|
|
906
1432
|
}
|
|
907
|
-
}
|
|
908
|
-
}
|
|
909
|
-
},
|
|
910
|
-
[processFile]
|
|
911
|
-
);
|
|
912
|
-
React6__default.useEffect(() => {
|
|
913
|
-
document.addEventListener("paste", handlePaste);
|
|
914
|
-
return () => document.removeEventListener("paste", handlePaste);
|
|
915
|
-
}, [handlePaste]);
|
|
916
|
-
const handleSubmit = () => {
|
|
917
|
-
if (input.trim() || files.length > 0) {
|
|
918
|
-
let messagePrefix = "";
|
|
919
|
-
if (showSearch) messagePrefix = "[Search: ";
|
|
920
|
-
else if (showThink) messagePrefix = "[Think: ";
|
|
921
|
-
else if (showCanvas) messagePrefix = "[Canvas: ";
|
|
922
|
-
const formattedInput = messagePrefix ? `${messagePrefix}${input}]` : input;
|
|
923
|
-
onSend(formattedInput, files);
|
|
924
|
-
setInput("");
|
|
925
|
-
setFiles([]);
|
|
926
|
-
setFilePreviews({});
|
|
927
|
-
}
|
|
928
|
-
};
|
|
929
|
-
const handleStartRecording = () => {
|
|
930
|
-
};
|
|
931
|
-
const handleStopRecording = (duration) => {
|
|
932
|
-
setIsRecording(false);
|
|
933
|
-
onSend(`[Voice message - ${duration} seconds]`, []);
|
|
934
|
-
};
|
|
935
|
-
const hasContent = input.trim() !== "" || files.length > 0;
|
|
936
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
937
|
-
/* @__PURE__ */ jsxs(
|
|
938
|
-
PromptInput,
|
|
939
|
-
{
|
|
940
|
-
value: input,
|
|
941
|
-
onValueChange: setInput,
|
|
942
|
-
isLoading,
|
|
943
|
-
onSubmit: handleSubmit,
|
|
944
|
-
className: cn2(
|
|
945
|
-
"w-full bg-background border-input shadow-lg transition-all duration-300 ease-in-out",
|
|
946
|
-
isRecording && "border-destructive/70",
|
|
947
|
-
className
|
|
948
1433
|
),
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
},
|
|
968
|
-
className: "w-16 h-16 rounded-xl overflow-hidden cursor-pointer transition-all duration-300",
|
|
969
|
-
onClick: () => {
|
|
970
|
-
const preview = filePreviews[file.name];
|
|
971
|
-
if (preview) openImageModal(preview);
|
|
972
|
-
},
|
|
973
|
-
children: [
|
|
974
|
-
/* @__PURE__ */ jsx(
|
|
975
|
-
Image,
|
|
976
|
-
{
|
|
977
|
-
src: filePreviews[file.name] ?? "",
|
|
978
|
-
alt: file.name,
|
|
979
|
-
className: "h-full w-full object-cover",
|
|
980
|
-
fill: true
|
|
981
|
-
}
|
|
982
|
-
),
|
|
983
|
-
/* @__PURE__ */ jsx(
|
|
984
|
-
"button",
|
|
985
|
-
{
|
|
986
|
-
type: "button",
|
|
987
|
-
onClick: (e) => {
|
|
988
|
-
e.stopPropagation();
|
|
989
|
-
handleRemoveFile(index);
|
|
990
|
-
},
|
|
991
|
-
className: "absolute top-1 right-1 rounded-full bg-black/70 p-0.5 opacity-100 transition-opacity",
|
|
992
|
-
children: /* @__PURE__ */ jsx(Cross, { className: "h-3 w-3 text-white" })
|
|
993
|
-
}
|
|
994
|
-
)
|
|
995
|
-
]
|
|
996
|
-
}
|
|
997
|
-
) }, index)) }),
|
|
1434
|
+
/* @__PURE__ */ jsx(
|
|
1435
|
+
"div",
|
|
1436
|
+
{
|
|
1437
|
+
className: cn(
|
|
1438
|
+
"transition-[background-color,border-color,box-shadow,color,opacity,transform] duration-300",
|
|
1439
|
+
isRecording ? "h-0 overflow-hidden opacity-0" : "opacity-100"
|
|
1440
|
+
),
|
|
1441
|
+
children: /* @__PURE__ */ jsx(
|
|
1442
|
+
PromptInputTextarea,
|
|
1443
|
+
{
|
|
1444
|
+
placeholder: showSearch ? "Search the web..." : showThink ? "Think deeply..." : showCanvas ? "Create on canvas..." : placeholder,
|
|
1445
|
+
className: "text-base"
|
|
1446
|
+
}
|
|
1447
|
+
)
|
|
1448
|
+
}
|
|
1449
|
+
),
|
|
1450
|
+
isRecording && /* @__PURE__ */ jsx(VoiceRecorder, { isRecording, time: recordingTime }),
|
|
1451
|
+
/* @__PURE__ */ jsxs(PromptInputActions, { className: "flex items-center justify-between gap-2 p-0 pt-2", children: [
|
|
998
1452
|
/* @__PURE__ */ jsx(
|
|
999
|
-
|
|
1453
|
+
PromptModeActions,
|
|
1000
1454
|
{
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
{
|
|
1008
|
-
placeholder: showSearch ? "Search the web..." : showThink ? "Think deeply..." : showCanvas ? "Create on canvas..." : placeholder,
|
|
1009
|
-
className: "text-base"
|
|
1010
|
-
}
|
|
1011
|
-
)
|
|
1455
|
+
uploadInputRef,
|
|
1456
|
+
isRecording,
|
|
1457
|
+
modes: { search: showSearch, think: showThink, canvas: showCanvas },
|
|
1458
|
+
onToggleMode: handleToggleChange,
|
|
1459
|
+
onToggleCanvas: handleCanvasToggle,
|
|
1460
|
+
onProcessFile: processFile
|
|
1012
1461
|
}
|
|
1013
1462
|
),
|
|
1014
|
-
|
|
1015
|
-
|
|
1463
|
+
/* @__PURE__ */ jsx(
|
|
1464
|
+
PromptSubmitAction,
|
|
1016
1465
|
{
|
|
1466
|
+
isLoading,
|
|
1017
1467
|
isRecording,
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
/* @__PURE__ */ jsxs(
|
|
1024
|
-
"div",
|
|
1025
|
-
{
|
|
1026
|
-
className: cn2(
|
|
1027
|
-
"flex items-center gap-1 transition-opacity duration-300",
|
|
1028
|
-
isRecording ? "opacity-0 invisible h-0" : "opacity-100 visible"
|
|
1029
|
-
),
|
|
1030
|
-
children: [
|
|
1031
|
-
/* @__PURE__ */ jsx(PromptInputAction, { tooltip: "Upload image", children: /* @__PURE__ */ jsxs(
|
|
1032
|
-
"button",
|
|
1033
|
-
{
|
|
1034
|
-
type: "button",
|
|
1035
|
-
onClick: () => uploadInputRef.current?.click(),
|
|
1036
|
-
className: "flex h-8 w-8 text-muted-foreground cursor-pointer items-center justify-center rounded-full transition-colors hover:bg-accent hover:text-foreground",
|
|
1037
|
-
disabled: isRecording,
|
|
1038
|
-
children: [
|
|
1039
|
-
/* @__PURE__ */ jsx(Paperclip, { className: "h-5 w-5 transition-colors" }),
|
|
1040
|
-
/* @__PURE__ */ jsx(
|
|
1041
|
-
"input",
|
|
1042
|
-
{
|
|
1043
|
-
ref: uploadInputRef,
|
|
1044
|
-
type: "file",
|
|
1045
|
-
className: "hidden",
|
|
1046
|
-
onChange: (e) => {
|
|
1047
|
-
const file = e.target.files?.[0];
|
|
1048
|
-
if (file) processFile(file);
|
|
1049
|
-
if (e.target) e.target.value = "";
|
|
1050
|
-
},
|
|
1051
|
-
accept: "image/*"
|
|
1052
|
-
}
|
|
1053
|
-
)
|
|
1054
|
-
]
|
|
1055
|
-
}
|
|
1056
|
-
) }),
|
|
1057
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
1058
|
-
/* @__PURE__ */ jsxs(
|
|
1059
|
-
"button",
|
|
1060
|
-
{
|
|
1061
|
-
type: "button",
|
|
1062
|
-
onClick: () => handleToggleChange("search"),
|
|
1063
|
-
className: cn2(
|
|
1064
|
-
"rounded-full transition-all flex items-center gap-1 px-2 py-1 border h-8",
|
|
1065
|
-
showSearch ? "bg-info/15 border-info text-info" : "bg-transparent border-transparent text-muted-foreground hover:text-foreground"
|
|
1066
|
-
),
|
|
1067
|
-
children: [
|
|
1068
|
-
/* @__PURE__ */ jsx("div", { className: "w-5 h-5 flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsx(
|
|
1069
|
-
motion.div,
|
|
1070
|
-
{
|
|
1071
|
-
animate: { rotate: showSearch ? 360 : 0, scale: showSearch ? 1.1 : 1 },
|
|
1072
|
-
whileHover: {
|
|
1073
|
-
rotate: showSearch ? 360 : 15,
|
|
1074
|
-
scale: 1.1,
|
|
1075
|
-
transition: { type: "spring", stiffness: 300, damping: 10 }
|
|
1076
|
-
},
|
|
1077
|
-
transition: { type: "spring", stiffness: 260, damping: 25 },
|
|
1078
|
-
children: /* @__PURE__ */ jsx(Globe, { className: cn2("w-4 h-4", showSearch ? "text-info" : "text-inherit") })
|
|
1079
|
-
}
|
|
1080
|
-
) }),
|
|
1081
|
-
/* @__PURE__ */ jsx(AnimatePresence, { children: showSearch && /* @__PURE__ */ jsx(
|
|
1082
|
-
motion.span,
|
|
1083
|
-
{
|
|
1084
|
-
initial: { width: 0, opacity: 0 },
|
|
1085
|
-
animate: { width: "auto", opacity: 1 },
|
|
1086
|
-
exit: { width: 0, opacity: 0 },
|
|
1087
|
-
transition: { duration: 0.2 },
|
|
1088
|
-
className: "text-xs overflow-hidden whitespace-nowrap text-info flex-shrink-0",
|
|
1089
|
-
children: "Search"
|
|
1090
|
-
}
|
|
1091
|
-
) })
|
|
1092
|
-
]
|
|
1093
|
-
}
|
|
1094
|
-
),
|
|
1095
|
-
/* @__PURE__ */ jsx(CustomDivider, {}),
|
|
1096
|
-
/* @__PURE__ */ jsxs(
|
|
1097
|
-
"button",
|
|
1098
|
-
{
|
|
1099
|
-
type: "button",
|
|
1100
|
-
onClick: () => handleToggleChange("think"),
|
|
1101
|
-
className: cn2(
|
|
1102
|
-
"rounded-full transition-all flex items-center gap-1 px-2 py-1 border h-8",
|
|
1103
|
-
showThink ? "bg-indigo-500/15 border-indigo-500 text-indigo-500" : "bg-transparent border-transparent text-muted-foreground hover:text-foreground"
|
|
1104
|
-
),
|
|
1105
|
-
children: [
|
|
1106
|
-
/* @__PURE__ */ jsx("div", { className: "w-5 h-5 flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsx(
|
|
1107
|
-
motion.div,
|
|
1108
|
-
{
|
|
1109
|
-
animate: { rotate: showThink ? 360 : 0, scale: showThink ? 1.1 : 1 },
|
|
1110
|
-
whileHover: {
|
|
1111
|
-
rotate: showThink ? 360 : 15,
|
|
1112
|
-
scale: 1.1,
|
|
1113
|
-
transition: { type: "spring", stiffness: 300, damping: 10 }
|
|
1114
|
-
},
|
|
1115
|
-
transition: { type: "spring", stiffness: 260, damping: 25 },
|
|
1116
|
-
children: /* @__PURE__ */ jsx(
|
|
1117
|
-
Brain,
|
|
1118
|
-
{
|
|
1119
|
-
className: cn2("w-4 h-4", showThink ? "text-indigo-500" : "text-inherit")
|
|
1120
|
-
}
|
|
1121
|
-
)
|
|
1122
|
-
}
|
|
1123
|
-
) }),
|
|
1124
|
-
/* @__PURE__ */ jsx(AnimatePresence, { children: showThink && /* @__PURE__ */ jsx(
|
|
1125
|
-
motion.span,
|
|
1126
|
-
{
|
|
1127
|
-
initial: { width: 0, opacity: 0 },
|
|
1128
|
-
animate: { width: "auto", opacity: 1 },
|
|
1129
|
-
exit: { width: 0, opacity: 0 },
|
|
1130
|
-
transition: { duration: 0.2 },
|
|
1131
|
-
className: "text-xs overflow-hidden whitespace-nowrap text-indigo-500 flex-shrink-0",
|
|
1132
|
-
children: "Think"
|
|
1133
|
-
}
|
|
1134
|
-
) })
|
|
1135
|
-
]
|
|
1136
|
-
}
|
|
1137
|
-
),
|
|
1138
|
-
/* @__PURE__ */ jsx(CustomDivider, {}),
|
|
1139
|
-
/* @__PURE__ */ jsxs(
|
|
1140
|
-
"button",
|
|
1141
|
-
{
|
|
1142
|
-
type: "button",
|
|
1143
|
-
onClick: handleCanvasToggle,
|
|
1144
|
-
className: cn2(
|
|
1145
|
-
"rounded-full transition-all flex items-center gap-1 px-2 py-1 border h-8",
|
|
1146
|
-
showCanvas ? "bg-warning/15 border-warning text-warning" : "bg-transparent border-transparent text-muted-foreground hover:text-foreground"
|
|
1147
|
-
),
|
|
1148
|
-
children: [
|
|
1149
|
-
/* @__PURE__ */ jsx("div", { className: "w-5 h-5 flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsx(
|
|
1150
|
-
motion.div,
|
|
1151
|
-
{
|
|
1152
|
-
animate: { rotate: showCanvas ? 360 : 0, scale: showCanvas ? 1.1 : 1 },
|
|
1153
|
-
whileHover: {
|
|
1154
|
-
rotate: showCanvas ? 360 : 15,
|
|
1155
|
-
scale: 1.1,
|
|
1156
|
-
transition: { type: "spring", stiffness: 300, damping: 10 }
|
|
1157
|
-
},
|
|
1158
|
-
transition: { type: "spring", stiffness: 260, damping: 25 },
|
|
1159
|
-
children: /* @__PURE__ */ jsx(
|
|
1160
|
-
FolderClosed,
|
|
1161
|
-
{
|
|
1162
|
-
className: cn2("w-4 h-4", showCanvas ? "text-warning" : "text-inherit")
|
|
1163
|
-
}
|
|
1164
|
-
)
|
|
1165
|
-
}
|
|
1166
|
-
) }),
|
|
1167
|
-
/* @__PURE__ */ jsx(AnimatePresence, { children: showCanvas && /* @__PURE__ */ jsx(
|
|
1168
|
-
motion.span,
|
|
1169
|
-
{
|
|
1170
|
-
initial: { width: 0, opacity: 0 },
|
|
1171
|
-
animate: { width: "auto", opacity: 1 },
|
|
1172
|
-
exit: { width: 0, opacity: 0 },
|
|
1173
|
-
transition: { duration: 0.2 },
|
|
1174
|
-
className: "text-xs overflow-hidden whitespace-nowrap text-warning flex-shrink-0",
|
|
1175
|
-
children: "Canvas"
|
|
1176
|
-
}
|
|
1177
|
-
) })
|
|
1178
|
-
]
|
|
1179
|
-
}
|
|
1180
|
-
)
|
|
1181
|
-
] })
|
|
1182
|
-
]
|
|
1183
|
-
}
|
|
1184
|
-
),
|
|
1185
|
-
/* @__PURE__ */ jsx(
|
|
1186
|
-
PromptInputAction,
|
|
1187
|
-
{
|
|
1188
|
-
tooltip: isLoading ? "Stop generation" : isRecording ? "Stop recording" : hasContent ? "Send message" : "Voice message",
|
|
1189
|
-
children: /* @__PURE__ */ jsx(
|
|
1190
|
-
Button,
|
|
1191
|
-
{
|
|
1192
|
-
variant: "default",
|
|
1193
|
-
size: "icon",
|
|
1194
|
-
className: cn2(
|
|
1195
|
-
"h-8 w-8 rounded-full transition-all duration-200",
|
|
1196
|
-
isRecording ? "bg-transparent hover:bg-accent text-destructive hover:text-destructive/80" : hasContent ? "bg-primary hover:bg-primary/90 text-primary-foreground" : "bg-transparent hover:bg-accent text-muted-foreground hover:text-foreground"
|
|
1197
|
-
),
|
|
1198
|
-
onClick: () => {
|
|
1199
|
-
if (isRecording) setIsRecording(false);
|
|
1200
|
-
else if (hasContent) handleSubmit();
|
|
1201
|
-
else setIsRecording(true);
|
|
1202
|
-
},
|
|
1203
|
-
disabled: isLoading && !hasContent,
|
|
1204
|
-
children: isLoading ? /* @__PURE__ */ jsx(Square, { className: "h-4 w-4 fill-primary-foreground animate-pulse" }) : isRecording ? /* @__PURE__ */ jsx(StopCircle, { className: "h-5 w-5 text-destructive" }) : hasContent ? /* @__PURE__ */ jsx(ArrowUp, { className: "h-4 w-4 text-primary-foreground" }) : /* @__PURE__ */ jsx(Microphone, { className: "h-5 w-5 text-primary-foreground transition-colors" })
|
|
1205
|
-
}
|
|
1206
|
-
)
|
|
1468
|
+
hasContent,
|
|
1469
|
+
onActivate: () => {
|
|
1470
|
+
if (isRecording) stopRecording();
|
|
1471
|
+
else if (hasContent) handleSubmit();
|
|
1472
|
+
else startRecording();
|
|
1207
1473
|
}
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
]
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1474
|
+
}
|
|
1475
|
+
)
|
|
1476
|
+
] })
|
|
1477
|
+
]
|
|
1478
|
+
}
|
|
1479
|
+
),
|
|
1480
|
+
/* @__PURE__ */ jsx(
|
|
1481
|
+
ImageViewDialog,
|
|
1482
|
+
{
|
|
1483
|
+
imageUrl: selectedImage,
|
|
1484
|
+
onClose: () => dispatch({ type: "set-selected-image", imageUrl: null })
|
|
1485
|
+
}
|
|
1486
|
+
)
|
|
1487
|
+
] });
|
|
1488
|
+
};
|
|
1217
1489
|
PromptInputBox.displayName = "PromptInputBox";
|
|
1490
|
+
var emergeTransition = {
|
|
1491
|
+
duration: emerge.transition.duration,
|
|
1492
|
+
ease: [0.16, 1, 0.3, 1]
|
|
1493
|
+
};
|
|
1494
|
+
var flowTransition = {
|
|
1495
|
+
duration: flow.transition.duration,
|
|
1496
|
+
ease: [0, 0, 0.2, 1]
|
|
1497
|
+
};
|
|
1498
|
+
var defaultSpringTransition = {
|
|
1499
|
+
type: "spring",
|
|
1500
|
+
stiffness: brandSpring.default.stiffness,
|
|
1501
|
+
damping: brandSpring.default.damping,
|
|
1502
|
+
mass: brandSpring.default.mass
|
|
1503
|
+
};
|
|
1218
1504
|
var PRESETS = {
|
|
1219
1505
|
emerge: {
|
|
1220
1506
|
initial: emerge.initial,
|
|
1221
1507
|
animate: emerge.animate,
|
|
1222
1508
|
exit: emerge.exit,
|
|
1223
|
-
transition:
|
|
1509
|
+
transition: emergeTransition
|
|
1224
1510
|
},
|
|
1225
1511
|
flow: {
|
|
1226
1512
|
initial: flow.initial,
|
|
1227
1513
|
animate: flow.animate,
|
|
1228
1514
|
exit: flow.exit,
|
|
1229
|
-
transition:
|
|
1515
|
+
transition: flowTransition
|
|
1230
1516
|
},
|
|
1231
1517
|
fade: {
|
|
1232
1518
|
initial: { opacity: 0 },
|
|
@@ -1238,13 +1524,13 @@ var PRESETS = {
|
|
|
1238
1524
|
initial: { opacity: 0, y: 16 },
|
|
1239
1525
|
animate: { opacity: 1, y: 0 },
|
|
1240
1526
|
exit: { opacity: 0, y: 16 },
|
|
1241
|
-
transition:
|
|
1527
|
+
transition: defaultSpringTransition
|
|
1242
1528
|
},
|
|
1243
1529
|
scale: {
|
|
1244
1530
|
initial: { opacity: 0, scale: 0.95 },
|
|
1245
1531
|
animate: { opacity: 1, scale: 1 },
|
|
1246
1532
|
exit: { opacity: 0, scale: 0.95 },
|
|
1247
|
-
transition:
|
|
1533
|
+
transition: defaultSpringTransition
|
|
1248
1534
|
}
|
|
1249
1535
|
};
|
|
1250
1536
|
var STAGGER = { fast: 0.05, normal: 0.1, slow: 0.2 };
|
|
@@ -1254,7 +1540,7 @@ function MotionDiv(props) {
|
|
|
1254
1540
|
function AnimateIn(props) {
|
|
1255
1541
|
const { children, preset = "emerge", delay = 0, duration, inView = false, className } = props;
|
|
1256
1542
|
const shouldReduce = useReducedMotion();
|
|
1257
|
-
const { initial, animate, exit, transition } = PRESETS[preset];
|
|
1543
|
+
const { initial, animate: animate2, exit, transition } = PRESETS[preset];
|
|
1258
1544
|
const t = {
|
|
1259
1545
|
...transition,
|
|
1260
1546
|
...delay ? { delay } : {},
|
|
@@ -1267,7 +1553,7 @@ function AnimateIn(props) {
|
|
|
1267
1553
|
{
|
|
1268
1554
|
className,
|
|
1269
1555
|
initial,
|
|
1270
|
-
whileInView:
|
|
1556
|
+
whileInView: animate2,
|
|
1271
1557
|
exit,
|
|
1272
1558
|
viewport: { once: true, margin: "-10%" },
|
|
1273
1559
|
transition: t,
|
|
@@ -1275,7 +1561,7 @@ function AnimateIn(props) {
|
|
|
1275
1561
|
}
|
|
1276
1562
|
);
|
|
1277
1563
|
}
|
|
1278
|
-
return /* @__PURE__ */ jsx(MotionDiv, { className, initial, animate, exit, transition: t, children });
|
|
1564
|
+
return /* @__PURE__ */ jsx(MotionDiv, { className, initial, animate: animate2, exit, transition: t, children });
|
|
1279
1565
|
}
|
|
1280
1566
|
function AnimateInGroup(props) {
|
|
1281
1567
|
const { children, stagger = "normal", inView = false, className } = props;
|
|
@@ -1314,55 +1600,57 @@ function AsciiText({ text, className = "", font = slant }) {
|
|
|
1314
1600
|
);
|
|
1315
1601
|
}
|
|
1316
1602
|
var TAG_COLOR_MAP = {
|
|
1317
|
-
feature: "bg-[var(--
|
|
1603
|
+
feature: "bg-[hsl(var(--primary))] text-white",
|
|
1318
1604
|
fix: "bg-[var(--status-success)] text-white",
|
|
1319
1605
|
breaking: "bg-[var(--status-danger)] text-white",
|
|
1320
1606
|
improvement: "bg-[var(--status-warning)] text-white",
|
|
1321
1607
|
security: "bg-[var(--status-danger)] text-white",
|
|
1322
|
-
experimental: "bg-[var(--neutral-8)] text-
|
|
1608
|
+
experimental: "bg-[var(--neutral-8)] text-foreground"
|
|
1609
|
+
};
|
|
1610
|
+
var getTagColor = (tag) => {
|
|
1611
|
+
if (!tag) return "bg-[var(--neutral-7)] text-foreground";
|
|
1612
|
+
return TAG_COLOR_MAP[tag.toLowerCase()] || TAG_COLOR_MAP.feature;
|
|
1613
|
+
};
|
|
1614
|
+
var getUnreadCount = (entries, lastSeenVersion) => {
|
|
1615
|
+
if (!lastSeenVersion) return entries.length;
|
|
1616
|
+
const lastSeenIndex = entries.findIndex((entry) => entry.version === lastSeenVersion);
|
|
1617
|
+
return lastSeenIndex === -1 ? entries.length : lastSeenIndex;
|
|
1323
1618
|
};
|
|
1324
1619
|
function ChangelogWidget({
|
|
1325
1620
|
entries,
|
|
1326
1621
|
changelogUrl = "/changelog",
|
|
1327
1622
|
className
|
|
1328
1623
|
}) {
|
|
1329
|
-
const [isOpen, setIsOpen] =
|
|
1330
|
-
const [lastSeenVersion, setLastSeenVersion] =
|
|
1331
|
-
const dropdownRef =
|
|
1332
|
-
const unreadCount =
|
|
1333
|
-
if (!lastSeenVersion) return entries.length;
|
|
1334
|
-
const lastSeenIndex = entries.findIndex((e) => e.version === lastSeenVersion);
|
|
1335
|
-
return lastSeenIndex === -1 ? entries.length : lastSeenIndex;
|
|
1336
|
-
}, [entries, lastSeenVersion]);
|
|
1624
|
+
const [isOpen, setIsOpen] = React5.useState(false);
|
|
1625
|
+
const [lastSeenVersion, setLastSeenVersion] = React5.useState(null);
|
|
1626
|
+
const dropdownRef = React5.useRef(null);
|
|
1627
|
+
const unreadCount = getUnreadCount(entries, lastSeenVersion);
|
|
1337
1628
|
const recentEntries = entries.slice(0, 5);
|
|
1338
|
-
const
|
|
1629
|
+
const latestVersion = recentEntries[0]?.version ?? null;
|
|
1630
|
+
const closeAndMarkSeen = () => {
|
|
1339
1631
|
setIsOpen(false);
|
|
1340
|
-
if (
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1632
|
+
if (latestVersion) setLastSeenVersion(latestVersion);
|
|
1633
|
+
};
|
|
1634
|
+
const closeFromDocumentEvent = useEffectEvent(() => {
|
|
1635
|
+
closeAndMarkSeen();
|
|
1636
|
+
});
|
|
1637
|
+
React5.useEffect(() => {
|
|
1638
|
+
if (!isOpen) return;
|
|
1345
1639
|
const handleEscape = (e) => {
|
|
1346
|
-
if (e.key === "Escape")
|
|
1640
|
+
if (e.key === "Escape") closeFromDocumentEvent();
|
|
1347
1641
|
};
|
|
1348
1642
|
const handleClickOutside = (e) => {
|
|
1349
1643
|
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
|
1350
|
-
|
|
1644
|
+
closeFromDocumentEvent();
|
|
1351
1645
|
}
|
|
1352
1646
|
};
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
document.addEventListener("mousedown", handleClickOutside);
|
|
1356
|
-
}
|
|
1647
|
+
document.addEventListener("keydown", handleEscape);
|
|
1648
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
1357
1649
|
return () => {
|
|
1358
1650
|
document.removeEventListener("keydown", handleEscape);
|
|
1359
1651
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
1360
1652
|
};
|
|
1361
|
-
}, [isOpen
|
|
1362
|
-
const getTagColor = (tag) => {
|
|
1363
|
-
if (!tag) return "bg-[var(--neutral-7)] text-[var(--neutral-12)]";
|
|
1364
|
-
return TAG_COLOR_MAP[tag.toLowerCase()] || TAG_COLOR_MAP.feature;
|
|
1365
|
-
};
|
|
1653
|
+
}, [isOpen]);
|
|
1366
1654
|
return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), ref: dropdownRef, children: [
|
|
1367
1655
|
/* @__PURE__ */ jsxs(
|
|
1368
1656
|
"button",
|
|
@@ -1370,24 +1658,24 @@ function ChangelogWidget({
|
|
|
1370
1658
|
type: "button",
|
|
1371
1659
|
"aria-label": "View changelog",
|
|
1372
1660
|
"aria-expanded": isOpen,
|
|
1373
|
-
onClick: () => setIsOpen(!
|
|
1374
|
-
className: "relative inline-flex items-center justify-center rounded-lg p-2 transition-colors hover:bg-
|
|
1661
|
+
onClick: () => setIsOpen((open) => !open),
|
|
1662
|
+
className: "relative inline-flex items-center justify-center rounded-[var(--radius-lg)] p-2 transition-colors hover:bg-muted",
|
|
1375
1663
|
children: [
|
|
1376
|
-
/* @__PURE__ */ jsx(Bell, { className: "h-5 w-5 text-
|
|
1664
|
+
/* @__PURE__ */ jsx(Bell, { className: "h-5 w-5 text-muted-foreground" }),
|
|
1377
1665
|
unreadCount > 0 && /* @__PURE__ */ jsx("span", { className: "absolute right-0 top-0 flex h-5 w-5 items-center justify-center rounded-full bg-[var(--status-danger)] text-xs font-bold text-white", children: unreadCount > 9 ? "9+" : unreadCount })
|
|
1378
1666
|
]
|
|
1379
1667
|
}
|
|
1380
1668
|
),
|
|
1381
|
-
isOpen && /* @__PURE__ */ jsxs("div", { className: "absolute right-0 top-full z-50 mt-2 w-80 overflow-hidden rounded-
|
|
1382
|
-
/* @__PURE__ */ jsx("div", { className: "bg-gradient-to-r from-[var(--blue-3)] to-[var(--cyan-3)] px-4 py-3", children: /* @__PURE__ */ jsx("h3", { className: "font-semibold text-
|
|
1383
|
-
/* @__PURE__ */ jsx("div", { className: "max-h-96 overflow-y-auto", children: recentEntries.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-4 py-6 text-center text-sm text-
|
|
1669
|
+
isOpen && /* @__PURE__ */ jsxs("div", { className: "absolute right-0 top-full z-50 mt-2 w-80 overflow-hidden rounded-[var(--radius-lg)] border border-border bg-white shadow-lg transition-[background-color,border-color,box-shadow,color,opacity,transform] duration-200", children: [
|
|
1670
|
+
/* @__PURE__ */ jsx("div", { className: "bg-gradient-to-r from-[var(--blue-3)] to-[var(--cyan-3)] px-4 py-3", children: /* @__PURE__ */ jsx("h3", { className: "font-semibold text-foreground", children: "What's New" }) }),
|
|
1671
|
+
/* @__PURE__ */ jsx("div", { className: "max-h-96 overflow-y-auto", children: recentEntries.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-4 py-6 text-center text-sm text-muted-foreground", children: "No updates available" }) : recentEntries.map((entry) => /* @__PURE__ */ jsxs(
|
|
1384
1672
|
"a",
|
|
1385
1673
|
{
|
|
1386
1674
|
href: entry.url,
|
|
1387
|
-
className: "block border-b border-
|
|
1675
|
+
className: "block border-b border-border px-4 py-3 transition-colors hover:bg-muted",
|
|
1388
1676
|
children: [
|
|
1389
1677
|
/* @__PURE__ */ jsx("div", { className: "mb-2 flex items-center justify-between gap-2", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1390
|
-
/* @__PURE__ */ jsxs("span", { className: "font-mono text-xs font-bold text-
|
|
1678
|
+
/* @__PURE__ */ jsxs("span", { className: "font-mono text-xs font-bold text-primary", children: [
|
|
1391
1679
|
"v",
|
|
1392
1680
|
entry.version
|
|
1393
1681
|
] }),
|
|
@@ -1402,9 +1690,9 @@ function ChangelogWidget({
|
|
|
1402
1690
|
}
|
|
1403
1691
|
)
|
|
1404
1692
|
] }) }),
|
|
1405
|
-
/* @__PURE__ */ jsx("p", { className: "mb-1 text-sm font-medium text-
|
|
1406
|
-
/* @__PURE__ */ jsx("p", { className: "mb-2 line-clamp-2 text-xs text-
|
|
1407
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-
|
|
1693
|
+
/* @__PURE__ */ jsx("p", { className: "mb-1 text-sm font-medium text-foreground", children: entry.title }),
|
|
1694
|
+
/* @__PURE__ */ jsx("p", { className: "mb-2 line-clamp-2 text-xs text-muted-foreground", children: entry.excerpt }),
|
|
1695
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: entry.date })
|
|
1408
1696
|
]
|
|
1409
1697
|
},
|
|
1410
1698
|
entry.version
|
|
@@ -1413,8 +1701,8 @@ function ChangelogWidget({
|
|
|
1413
1701
|
"a",
|
|
1414
1702
|
{
|
|
1415
1703
|
href: changelogUrl,
|
|
1416
|
-
onClick:
|
|
1417
|
-
className: "flex items-center justify-between border-t border-
|
|
1704
|
+
onClick: closeAndMarkSeen,
|
|
1705
|
+
className: "flex items-center justify-between border-t border-border bg-background px-4 py-3 text-sm font-medium text-primary transition-colors hover:bg-muted",
|
|
1418
1706
|
children: [
|
|
1419
1707
|
/* @__PURE__ */ jsx("span", { children: "View all updates" }),
|
|
1420
1708
|
/* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
|
|
@@ -1496,12 +1784,28 @@ var XYFLOW_TOKEN_THEME = {
|
|
|
1496
1784
|
["--xy-controls-button-color"]: "var(--neutral-11)"
|
|
1497
1785
|
};
|
|
1498
1786
|
var nodeCardVariants = cva(
|
|
1499
|
-
"min-w-[160px] rounded-lg border bg-neutral-2 px-3 py-2 text-neutral-12 shadow-sm transition-colors",
|
|
1787
|
+
"min-w-[160px] rounded-[var(--radius-lg)] border bg-neutral-2 px-3 py-2 text-neutral-12 shadow-sm transition-colors",
|
|
1500
1788
|
{
|
|
1501
1789
|
variants: { ready: { true: "border-success", false: "border-neutral-7" } },
|
|
1502
1790
|
defaultVariants: { ready: false }
|
|
1503
1791
|
}
|
|
1504
1792
|
);
|
|
1793
|
+
function GraphNodeCard({ data }) {
|
|
1794
|
+
const view = data.view;
|
|
1795
|
+
return /* @__PURE__ */ jsxs("div", { className: nodeCardVariants({ ready: view.ready ?? false }), children: [
|
|
1796
|
+
/* @__PURE__ */ jsx(Handle, { type: "target", position: Position.Left }),
|
|
1797
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-xs font-medium text-neutral-11 uppercase tracking-wide", children: [
|
|
1798
|
+
view.icon,
|
|
1799
|
+
view.label
|
|
1800
|
+
] }),
|
|
1801
|
+
view.subtitle ? /* @__PURE__ */ jsx("div", { className: "mt-0.5 text-sm text-neutral-12", children: view.subtitle }) : null,
|
|
1802
|
+
/* @__PURE__ */ jsx(Handle, { type: "source", position: Position.Right })
|
|
1803
|
+
] });
|
|
1804
|
+
}
|
|
1805
|
+
var NODE_TYPES = {
|
|
1806
|
+
[GRAPH_NODE_FLOW_TYPE]: GraphNodeCard
|
|
1807
|
+
};
|
|
1808
|
+
var REACT_FLOW_PRO_OPTIONS = { hideAttribution: true };
|
|
1505
1809
|
function NodeGraphCanvas({
|
|
1506
1810
|
graph,
|
|
1507
1811
|
onChange,
|
|
@@ -1513,82 +1817,63 @@ function NodeGraphCanvas({
|
|
|
1513
1817
|
}) {
|
|
1514
1818
|
const statusId = useId();
|
|
1515
1819
|
const [rejection, setRejection] = useState(null);
|
|
1516
|
-
const { nodes, edges } =
|
|
1517
|
-
const
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
}
|
|
1531
|
-
}),
|
|
1532
|
-
[renderNode]
|
|
1533
|
-
);
|
|
1534
|
-
const onNodesChange = useCallback(
|
|
1535
|
-
(changes) => {
|
|
1536
|
-
if (readOnly) return;
|
|
1537
|
-
const removed = changes.filter(
|
|
1538
|
-
(c) => c.type === "remove"
|
|
1539
|
-
);
|
|
1540
|
-
if (removed.length > 0) {
|
|
1541
|
-
let next = graph;
|
|
1542
|
-
for (const r of removed) next = removeNode(next, r.id);
|
|
1543
|
-
onChange(next);
|
|
1544
|
-
return;
|
|
1545
|
-
}
|
|
1546
|
-
const positional = changes.some((c) => c.type === "position" && c.dragging === false);
|
|
1547
|
-
if (positional) {
|
|
1548
|
-
const moved = nodes.map((n) => {
|
|
1549
|
-
const change = changes.find((c) => c.type === "position" && c.id === n.id);
|
|
1550
|
-
if (change && change.type === "position" && change.position) {
|
|
1551
|
-
return { ...n, position: change.position };
|
|
1552
|
-
}
|
|
1553
|
-
return n;
|
|
1554
|
-
});
|
|
1555
|
-
onChange(applyNodePositions(graph, moved));
|
|
1556
|
-
}
|
|
1557
|
-
},
|
|
1558
|
-
[graph, nodes, onChange, readOnly]
|
|
1559
|
-
);
|
|
1560
|
-
const onEdgesChange = useCallback(
|
|
1561
|
-
(changes) => {
|
|
1562
|
-
if (readOnly) return;
|
|
1563
|
-
const removed = changes.filter(
|
|
1564
|
-
(c) => c.type === "remove"
|
|
1565
|
-
);
|
|
1566
|
-
if (removed.length === 0) return;
|
|
1820
|
+
const { nodes: graphNodes, edges } = graphToFlow(graph, edgeIdentity);
|
|
1821
|
+
const nodes = graphNodes.map((node) => ({
|
|
1822
|
+
...node,
|
|
1823
|
+
data: {
|
|
1824
|
+
...node.data,
|
|
1825
|
+
view: renderNode(node.data.node)
|
|
1826
|
+
}
|
|
1827
|
+
}));
|
|
1828
|
+
const onNodesChange = (changes) => {
|
|
1829
|
+
if (readOnly) return;
|
|
1830
|
+
const removed = changes.filter(
|
|
1831
|
+
(c) => c.type === "remove"
|
|
1832
|
+
);
|
|
1833
|
+
if (removed.length > 0) {
|
|
1567
1834
|
let next = graph;
|
|
1568
|
-
for (const r of removed) next =
|
|
1835
|
+
for (const r of removed) next = removeNode(next, r.id);
|
|
1569
1836
|
onChange(next);
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
}
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1837
|
+
return;
|
|
1838
|
+
}
|
|
1839
|
+
const positional = changes.some((c) => c.type === "position" && c.dragging === false);
|
|
1840
|
+
if (positional) {
|
|
1841
|
+
const moved = nodes.map((n) => {
|
|
1842
|
+
const change = changes.find((c) => c.type === "position" && c.id === n.id);
|
|
1843
|
+
if (change && change.type === "position" && change.position) {
|
|
1844
|
+
return { ...n, position: change.position };
|
|
1845
|
+
}
|
|
1846
|
+
return n;
|
|
1847
|
+
});
|
|
1848
|
+
onChange(applyNodePositions(graph, moved));
|
|
1849
|
+
}
|
|
1850
|
+
};
|
|
1851
|
+
const onEdgesChange = (changes) => {
|
|
1852
|
+
if (readOnly) return;
|
|
1853
|
+
const removed = changes.filter(
|
|
1854
|
+
(c) => c.type === "remove"
|
|
1855
|
+
);
|
|
1856
|
+
if (removed.length === 0) return;
|
|
1857
|
+
let next = graph;
|
|
1858
|
+
for (const r of removed) next = removeFlowEdge(next, r.id, edgeIdentity);
|
|
1859
|
+
onChange(next);
|
|
1860
|
+
};
|
|
1861
|
+
const onConnect = (connection) => {
|
|
1862
|
+
if (readOnly) return;
|
|
1863
|
+
const result = tryAddEdge(graph, connection, { makeEdge, edgeIdentity });
|
|
1864
|
+
if (result.ok) {
|
|
1865
|
+
setRejection(null);
|
|
1866
|
+
onChange(result.graph);
|
|
1867
|
+
} else {
|
|
1868
|
+
setRejection(result.reason);
|
|
1869
|
+
}
|
|
1870
|
+
};
|
|
1586
1871
|
return /* @__PURE__ */ jsx(AnimateIn, { preset: "emerge", children: /* @__PURE__ */ jsx(
|
|
1587
1872
|
"div",
|
|
1588
1873
|
{
|
|
1589
1874
|
style: XYFLOW_TOKEN_THEME,
|
|
1590
1875
|
className: cn(
|
|
1591
|
-
"relative h-[480px] w-full overflow-hidden rounded-xl border border-neutral-7 bg-neutral-1",
|
|
1876
|
+
"relative h-[480px] w-full overflow-hidden rounded-[var(--radius-xl)] border border-neutral-7 bg-neutral-1",
|
|
1592
1877
|
className
|
|
1593
1878
|
),
|
|
1594
1879
|
children: /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsxs(
|
|
@@ -1596,7 +1881,7 @@ function NodeGraphCanvas({
|
|
|
1596
1881
|
{
|
|
1597
1882
|
nodes,
|
|
1598
1883
|
edges,
|
|
1599
|
-
nodeTypes,
|
|
1884
|
+
nodeTypes: NODE_TYPES,
|
|
1600
1885
|
onNodesChange,
|
|
1601
1886
|
onEdgesChange,
|
|
1602
1887
|
onConnect,
|
|
@@ -1604,7 +1889,7 @@ function NodeGraphCanvas({
|
|
|
1604
1889
|
nodesConnectable: !readOnly,
|
|
1605
1890
|
elementsSelectable: !readOnly,
|
|
1606
1891
|
fitView: true,
|
|
1607
|
-
proOptions:
|
|
1892
|
+
proOptions: REACT_FLOW_PRO_OPTIONS,
|
|
1608
1893
|
children: [
|
|
1609
1894
|
/* @__PURE__ */ jsx(Background, { color: "var(--neutral-6)" }),
|
|
1610
1895
|
/* @__PURE__ */ jsx(Controls, { showInteractive: !readOnly }),
|
|
@@ -1614,7 +1899,7 @@ function NodeGraphCanvas({
|
|
|
1614
1899
|
id: statusId,
|
|
1615
1900
|
role: "alert",
|
|
1616
1901
|
"aria-live": "assertive",
|
|
1617
|
-
className: "flex items-center gap-2 rounded-md border border-destructive bg-destructive/10 px-3 py-2 text-sm text-destructive",
|
|
1902
|
+
className: "flex items-center gap-2 rounded-[var(--radius-md)] border border-destructive bg-destructive/10 px-3 py-2 text-sm text-destructive",
|
|
1618
1903
|
children: [
|
|
1619
1904
|
/* @__PURE__ */ jsx("span", { children: rejection }),
|
|
1620
1905
|
/* @__PURE__ */ jsx(
|
|
@@ -1661,6 +1946,20 @@ var itemVariants = {
|
|
|
1661
1946
|
}
|
|
1662
1947
|
}
|
|
1663
1948
|
};
|
|
1949
|
+
var reducedContainerVariants = {
|
|
1950
|
+
hidden: { opacity: 1 },
|
|
1951
|
+
visible: {
|
|
1952
|
+
opacity: 1,
|
|
1953
|
+
transition: { duration: 0 }
|
|
1954
|
+
}
|
|
1955
|
+
};
|
|
1956
|
+
var reducedItemVariants = {
|
|
1957
|
+
hidden: { opacity: 1 },
|
|
1958
|
+
visible: {
|
|
1959
|
+
opacity: 1,
|
|
1960
|
+
transition: { duration: 0 }
|
|
1961
|
+
}
|
|
1962
|
+
};
|
|
1664
1963
|
function OnboardingChecklist({
|
|
1665
1964
|
title,
|
|
1666
1965
|
description,
|
|
@@ -1669,12 +1968,15 @@ function OnboardingChecklist({
|
|
|
1669
1968
|
videoUrl,
|
|
1670
1969
|
className
|
|
1671
1970
|
}) {
|
|
1971
|
+
const shouldReduceMotion = useReducedMotion();
|
|
1972
|
+
const activeContainerVariants = shouldReduceMotion ? reducedContainerVariants : containerVariants;
|
|
1973
|
+
const activeItemVariants = shouldReduceMotion ? reducedItemVariants : itemVariants;
|
|
1672
1974
|
return /* @__PURE__ */ jsx(
|
|
1673
1975
|
motion.div,
|
|
1674
1976
|
{
|
|
1675
1977
|
initial: "hidden",
|
|
1676
1978
|
animate: "visible",
|
|
1677
|
-
variants:
|
|
1979
|
+
variants: activeContainerVariants,
|
|
1678
1980
|
className: cn(
|
|
1679
1981
|
"w-full max-w-4xl mx-auto bg-card text-card-foreground border rounded-[var(--radius-2xl)] shadow-sm p-8 overflow-hidden",
|
|
1680
1982
|
className
|
|
@@ -1683,7 +1985,7 @@ function OnboardingChecklist({
|
|
|
1683
1985
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
1684
1986
|
/* @__PURE__ */ jsx("h2", { className: "text-2xl font-bold tracking-tight", children: title }),
|
|
1685
1987
|
/* @__PURE__ */ jsx("p", { className: "mt-2 text-muted-foreground", children: description }),
|
|
1686
|
-
/* @__PURE__ */ jsx("ul", { className: "mt-6 grid grid-cols-1 sm:grid-cols-2 gap-x-8 gap-y-4", children: items.map((item) => /* @__PURE__ */ jsxs(motion.li, { variants:
|
|
1988
|
+
/* @__PURE__ */ jsx("ul", { className: "mt-6 grid grid-cols-1 sm:grid-cols-2 gap-x-8 gap-y-4", children: items.map((item) => /* @__PURE__ */ jsxs(motion.li, { variants: activeItemVariants, className: "flex flex-col", children: [
|
|
1687
1989
|
/* @__PURE__ */ jsxs("div", { className: "flex items-start", children: [
|
|
1688
1990
|
/* @__PURE__ */ jsx(CheckCircle, { className: "h-5 w-5 text-green-500 mt-0.5 flex-shrink-0" }),
|
|
1689
1991
|
/* @__PURE__ */ jsx("span", { className: "ml-3 text-sm font-medium", children: item.text })
|
|
@@ -1695,7 +1997,7 @@ function OnboardingChecklist({
|
|
|
1695
1997
|
"a",
|
|
1696
1998
|
{
|
|
1697
1999
|
href: item.helperLink.href,
|
|
1698
|
-
className: "text-primary underline-offset-4 hover:underline focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 rounded-[var(--radius-sm)]",
|
|
2000
|
+
className: "text-primary underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 rounded-[var(--radius-sm)]",
|
|
1699
2001
|
children: item.helperLink.text
|
|
1700
2002
|
}
|
|
1701
2003
|
)
|
|
@@ -1705,25 +2007,25 @@ function OnboardingChecklist({
|
|
|
1705
2007
|
/* @__PURE__ */ jsx(
|
|
1706
2008
|
motion.div,
|
|
1707
2009
|
{
|
|
1708
|
-
variants:
|
|
2010
|
+
variants: activeItemVariants,
|
|
1709
2011
|
className: "relative group rounded-[var(--radius-lg)] overflow-hidden cursor-pointer w-full aspect-video",
|
|
1710
2012
|
children: /* @__PURE__ */ jsxs(Dialog, { children: [
|
|
1711
2013
|
/* @__PURE__ */ jsx(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
1712
2014
|
"button",
|
|
1713
2015
|
{
|
|
1714
2016
|
type: "button",
|
|
1715
|
-
className: "w-full h-full focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 rounded-[var(--radius-lg)]",
|
|
2017
|
+
className: "w-full h-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 rounded-[var(--radius-lg)]",
|
|
1716
2018
|
children: [
|
|
1717
2019
|
/* @__PURE__ */ jsx(
|
|
1718
2020
|
Image,
|
|
1719
2021
|
{
|
|
1720
2022
|
src: videoThumbnailUrl,
|
|
1721
2023
|
alt: "Video guide thumbnail",
|
|
1722
|
-
className: "w-full h-full object-cover transition-transform duration-300 group-hover:scale-105",
|
|
2024
|
+
className: "w-full h-full object-cover transition-transform duration-300 group-hover:scale-105 motion-reduce:transition-none motion-reduce:group-hover:scale-100",
|
|
1723
2025
|
fill: true
|
|
1724
2026
|
}
|
|
1725
2027
|
),
|
|
1726
|
-
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-black/30 flex items-center justify-center", children: /* @__PURE__ */ jsx(PlayCircle, { className: "h-16 w-16 text-white/80 transform transition-
|
|
2028
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-black/30 flex items-center justify-center", children: /* @__PURE__ */ jsx(PlayCircle, { className: "h-16 w-16 text-white/80 transform transition-[background-color,border-color,box-shadow,color,opacity,transform] duration-300 group-hover:scale-110 group-hover:text-white motion-reduce:transition-none motion-reduce:group-hover:scale-100" }) })
|
|
1727
2029
|
]
|
|
1728
2030
|
}
|
|
1729
2031
|
) }),
|
|
@@ -1817,7 +2119,7 @@ function subscribePlatform() {
|
|
|
1817
2119
|
return () => void 0;
|
|
1818
2120
|
}
|
|
1819
2121
|
function usePlatform() {
|
|
1820
|
-
return
|
|
2122
|
+
return React5.useSyncExternalStore(subscribePlatform, getClientPlatform, () => "apple");
|
|
1821
2123
|
}
|
|
1822
2124
|
function normalizeKey(children) {
|
|
1823
2125
|
if (typeof children !== "string") {
|
|
@@ -1832,54 +2134,63 @@ function normalizeKey(children) {
|
|
|
1832
2134
|
function getModifierSymbols(platform) {
|
|
1833
2135
|
return platform === "apple" ? appleModifierSymbols : otherModifierSymbols;
|
|
1834
2136
|
}
|
|
1835
|
-
var Kbd =
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
2137
|
+
var Kbd = ({
|
|
2138
|
+
meta,
|
|
2139
|
+
shift,
|
|
2140
|
+
alt,
|
|
2141
|
+
ctrl,
|
|
2142
|
+
small,
|
|
2143
|
+
children,
|
|
2144
|
+
className,
|
|
2145
|
+
"aria-label": ariaLabel,
|
|
2146
|
+
ref,
|
|
2147
|
+
...props
|
|
2148
|
+
}) => {
|
|
2149
|
+
const platform = usePlatform();
|
|
2150
|
+
const symbols = getModifierSymbols(platform);
|
|
2151
|
+
const activeModifiers = modifierOrder.filter((modifier) => {
|
|
2152
|
+
if (modifier === "meta") return meta;
|
|
2153
|
+
if (modifier === "shift") return shift;
|
|
2154
|
+
if (modifier === "alt") return alt;
|
|
2155
|
+
return ctrl;
|
|
2156
|
+
});
|
|
2157
|
+
const normalizedKey = normalizeKey(children);
|
|
2158
|
+
const visualParts = [
|
|
2159
|
+
...activeModifiers.map((modifier) => symbols[modifier]),
|
|
2160
|
+
normalizedKey
|
|
2161
|
+
].filter(Boolean);
|
|
2162
|
+
const accessibleName = ariaLabel ?? [
|
|
2163
|
+
...activeModifiers.map((modifier) => modifierLabels[modifier]),
|
|
2164
|
+
typeof normalizedKey === "string" ? normalizedKey : void 0
|
|
2165
|
+
].filter(Boolean).join(" ");
|
|
2166
|
+
return /* @__PURE__ */ jsx(
|
|
2167
|
+
"kbd",
|
|
2168
|
+
{
|
|
2169
|
+
ref,
|
|
2170
|
+
"aria-label": accessibleName || void 0,
|
|
2171
|
+
className: cn(
|
|
2172
|
+
"inline-flex select-none items-center justify-center gap-0.5 rounded-[var(--radius-sm)] border border-border bg-muted font-mono font-medium leading-none text-muted-foreground tabular-nums",
|
|
2173
|
+
small ? "min-h-4 min-w-4 px-1 py-0 text-xs" : "min-h-5 min-w-5 px-1.5 py-0.5 text-xs",
|
|
2174
|
+
className
|
|
2175
|
+
),
|
|
2176
|
+
...props,
|
|
2177
|
+
children: visualParts.join("")
|
|
2178
|
+
}
|
|
2179
|
+
);
|
|
2180
|
+
};
|
|
1870
2181
|
Kbd.displayName = "Kbd";
|
|
1871
2182
|
var inputVariants = cva(
|
|
1872
2183
|
[
|
|
1873
2184
|
"flex h-[var(--input-height)] w-full rounded-[var(--input-radius)] border border-input bg-background",
|
|
1874
|
-
"px-[var(--input-padding-x)] text-[length:var(--input-font-size)] text-foreground shadow-
|
|
2185
|
+
"px-[var(--input-padding-x)] text-[length:var(--input-font-size)] text-foreground shadow-xs",
|
|
1875
2186
|
"transition-[background-color,border-color,box-shadow,color] duration-micro ease-out",
|
|
1876
2187
|
"placeholder:text-muted-foreground",
|
|
1877
|
-
|
|
2188
|
+
formControlFocusClassNames.input,
|
|
1878
2189
|
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
1879
2190
|
"read-only:bg-muted/70 read-only:cursor-default",
|
|
1880
2191
|
"file:h-full file:border-0 file:border-e file:border-solid file:border-input file:bg-transparent",
|
|
1881
2192
|
"file:me-[var(--input-padding-x)] file:pe-[var(--input-padding-x)] file:text-[length:var(--input-font-size)] file:font-medium file:text-foreground",
|
|
1882
|
-
|
|
2193
|
+
formControlInvalidClassNames.input,
|
|
1883
2194
|
"[&[type=search]::-webkit-search-cancel-button]:appearance-none",
|
|
1884
2195
|
"[&[type=search]::-webkit-search-decoration]:appearance-none",
|
|
1885
2196
|
"[&[type=search]::-webkit-search-results-button]:appearance-none",
|
|
@@ -1981,7 +2292,10 @@ function isTextAffix(value) {
|
|
|
1981
2292
|
function joinDescriptionIds2(...ids) {
|
|
1982
2293
|
return ids.filter(Boolean).join(" ") || void 0;
|
|
1983
2294
|
}
|
|
1984
|
-
var Input =
|
|
2295
|
+
var Input = ({
|
|
2296
|
+
ref: forwardedRef,
|
|
2297
|
+
...props
|
|
2298
|
+
}) => {
|
|
1985
2299
|
const {
|
|
1986
2300
|
className,
|
|
1987
2301
|
type = "text",
|
|
@@ -2014,16 +2328,16 @@ var Input = React6.forwardRef((props, forwardedRef) => {
|
|
|
2014
2328
|
...rest
|
|
2015
2329
|
} = props;
|
|
2016
2330
|
const isControlled = value !== void 0;
|
|
2017
|
-
const baseId =
|
|
2018
|
-
const inputRef =
|
|
2331
|
+
const baseId = React5.useId();
|
|
2332
|
+
const inputRef = React5.useRef(null);
|
|
2019
2333
|
const descriptionId = description && id ? `${id}-description` : void 0;
|
|
2020
2334
|
const errorId = typeof error === "string" && id ? `${id}-error` : void 0;
|
|
2021
2335
|
const prefixDescriptionId = isTextAffix(prefix) ? `${id ?? baseId}-prefix` : void 0;
|
|
2022
2336
|
const suffixDescriptionId = isTextAffix(suffix) ? `${id ?? baseId}-suffix` : void 0;
|
|
2023
|
-
const [internalValue, setInternalValue] =
|
|
2337
|
+
const [internalValue, setInternalValue] = React5.useState(
|
|
2024
2338
|
typeof defaultValue === "string" || typeof defaultValue === "number" ? String(defaultValue) : ""
|
|
2025
2339
|
);
|
|
2026
|
-
const [passwordVisible, setPasswordVisible] =
|
|
2340
|
+
const [passwordVisible, setPasswordVisible] = React5.useState(false);
|
|
2027
2341
|
const currentValue = isControlled ? String(value ?? "") : internalValue;
|
|
2028
2342
|
const clearOnEscapeEnabled = clearOnEscape ?? type === "search";
|
|
2029
2343
|
const canRevealPassword = Boolean(revealable && type === "password");
|
|
@@ -2043,7 +2357,7 @@ var Input = React6.forwardRef((props, forwardedRef) => {
|
|
|
2043
2357
|
errorId
|
|
2044
2358
|
);
|
|
2045
2359
|
const valueProps = isControlled ? { value } : clearable || shortcut || clearOnEscapeEnabled ? { value: currentValue } : { defaultValue };
|
|
2046
|
-
const setInputRef =
|
|
2360
|
+
const setInputRef = React5.useCallback(
|
|
2047
2361
|
(node) => {
|
|
2048
2362
|
const input = node instanceof HTMLInputElement ? node : null;
|
|
2049
2363
|
inputRef.current = input;
|
|
@@ -2051,7 +2365,7 @@ var Input = React6.forwardRef((props, forwardedRef) => {
|
|
|
2051
2365
|
},
|
|
2052
2366
|
[forwardedRef]
|
|
2053
2367
|
);
|
|
2054
|
-
const emitNativeInput =
|
|
2368
|
+
const emitNativeInput = React5.useCallback(
|
|
2055
2369
|
(nextValue) => {
|
|
2056
2370
|
const input = inputRef.current;
|
|
2057
2371
|
if (!input) {
|
|
@@ -2068,7 +2382,7 @@ var Input = React6.forwardRef((props, forwardedRef) => {
|
|
|
2068
2382
|
},
|
|
2069
2383
|
[isControlled, onValueChange]
|
|
2070
2384
|
);
|
|
2071
|
-
const syncInputValue =
|
|
2385
|
+
const syncInputValue = React5.useCallback(
|
|
2072
2386
|
(event) => {
|
|
2073
2387
|
if (!isControlled) setInternalValue(event.currentTarget.value);
|
|
2074
2388
|
onValueChange?.(event.currentTarget.value);
|
|
@@ -2076,12 +2390,12 @@ var Input = React6.forwardRef((props, forwardedRef) => {
|
|
|
2076
2390
|
},
|
|
2077
2391
|
[isControlled, onChange, onValueChange]
|
|
2078
2392
|
);
|
|
2079
|
-
const handleClear =
|
|
2393
|
+
const handleClear = React5.useCallback(() => {
|
|
2080
2394
|
emitNativeInput("");
|
|
2081
2395
|
onClear?.();
|
|
2082
2396
|
inputRef.current?.focus();
|
|
2083
2397
|
}, [emitNativeInput, onClear]);
|
|
2084
|
-
const handleKeyDown =
|
|
2398
|
+
const handleKeyDown = React5.useCallback(
|
|
2085
2399
|
(event) => {
|
|
2086
2400
|
onKeyDown?.(event);
|
|
2087
2401
|
if (event.defaultPrevented || event.key !== "Escape" || !clearOnEscapeEnabled || currentValue.length === 0 || disabled) {
|
|
@@ -2210,7 +2524,7 @@ var Input = React6.forwardRef((props, forwardedRef) => {
|
|
|
2210
2524
|
]
|
|
2211
2525
|
}
|
|
2212
2526
|
);
|
|
2213
|
-
}
|
|
2527
|
+
};
|
|
2214
2528
|
Input.displayName = "Input";
|
|
2215
2529
|
function Avatar({ src, alt, isOnline, size = "md" }) {
|
|
2216
2530
|
const sizeClasses = size === "sm" ? "w-10 h-10" : "w-10 h-10";
|
|
@@ -2271,16 +2585,16 @@ function TeamChat({
|
|
|
2271
2585
|
"div",
|
|
2272
2586
|
{
|
|
2273
2587
|
className: cn(
|
|
2274
|
-
"w-full max-w-5xl mx-auto p-6 bg-white dark:bg-black rounded-[var(--radius-3xl)] shadow-lg flex flex-col h-[550px] border border-
|
|
2588
|
+
"w-full max-w-5xl mx-auto p-6 bg-white dark:bg-black rounded-[var(--radius-3xl)] shadow-lg flex flex-col h-[550px] border border-border",
|
|
2275
2589
|
className
|
|
2276
2590
|
),
|
|
2277
2591
|
children: [
|
|
2278
|
-
/* @__PURE__ */ jsxs("header", { className: "flex justify-between items-center border-b border-
|
|
2592
|
+
/* @__PURE__ */ jsxs("header", { className: "flex justify-between items-center border-b border-border pb-3 mb-6", children: [
|
|
2279
2593
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
2280
|
-
/* @__PURE__ */ jsx(Users, { className: "w-8 h-8 text-black
|
|
2594
|
+
/* @__PURE__ */ jsx(Users, { className: "w-8 h-8 text-black" }),
|
|
2281
2595
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
2282
|
-
/* @__PURE__ */ jsx("h2", { className: "text-2xl font-semibold text-black
|
|
2283
|
-
tagline && /* @__PURE__ */ jsx("p", { className: "italic text-sm text-
|
|
2596
|
+
/* @__PURE__ */ jsx("h2", { className: "text-2xl font-semibold text-black", children: chatName }),
|
|
2597
|
+
tagline && /* @__PURE__ */ jsx("p", { className: "italic text-sm text-muted-foreground", children: tagline })
|
|
2284
2598
|
] })
|
|
2285
2599
|
] }),
|
|
2286
2600
|
/* @__PURE__ */ jsx(
|
|
@@ -2289,13 +2603,13 @@ function TeamChat({
|
|
|
2289
2603
|
type: "button",
|
|
2290
2604
|
"aria-label": "More options",
|
|
2291
2605
|
onClick: onMoreOptions,
|
|
2292
|
-
className: "p-2 rounded-[var(--radius-lg)] hover:bg-
|
|
2293
|
-
children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "w-6 h-6 text-
|
|
2606
|
+
className: "p-2 rounded-[var(--radius-lg)] hover:bg-muted transition",
|
|
2607
|
+
children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "w-6 h-6 text-muted-foreground" })
|
|
2294
2608
|
}
|
|
2295
2609
|
)
|
|
2296
2610
|
] }),
|
|
2297
|
-
/* @__PURE__ */ jsxs("main", { className: "flex flex-1 overflow-hidden rounded-[var(--radius-xl)] border border-
|
|
2298
|
-
/* @__PURE__ */ jsx("aside", { className: "w-56 bg-
|
|
2611
|
+
/* @__PURE__ */ jsxs("main", { className: "flex flex-1 overflow-hidden rounded-[var(--radius-xl)] border border-border", children: [
|
|
2612
|
+
/* @__PURE__ */ jsx("aside", { className: "w-56 bg-muted border-r border-border p-4 overflow-y-auto", children: uniqueSenders.map((sender) => {
|
|
2299
2613
|
const isSelected = selectedSender === sender.name;
|
|
2300
2614
|
return /* @__PURE__ */ jsxs(
|
|
2301
2615
|
"button",
|
|
@@ -2304,7 +2618,7 @@ function TeamChat({
|
|
|
2304
2618
|
onClick: () => setSelectedSender(isSelected ? null : sender.name),
|
|
2305
2619
|
className: cn(
|
|
2306
2620
|
"flex items-center gap-3 w-full p-3 mb-3 rounded-[var(--radius-lg)] transition-colors",
|
|
2307
|
-
isSelected ? "bg-black
|
|
2621
|
+
isSelected ? "bg-black text-white dark:text-black" : "hover:bg-muted text-foreground"
|
|
2308
2622
|
),
|
|
2309
2623
|
children: [
|
|
2310
2624
|
/* @__PURE__ */ jsx(Avatar, { src: sender.avatar, alt: sender.name, isOnline: sender.isOnline }),
|
|
@@ -2314,57 +2628,50 @@ function TeamChat({
|
|
|
2314
2628
|
sender.name
|
|
2315
2629
|
);
|
|
2316
2630
|
}) }),
|
|
2317
|
-
/* @__PURE__ */ jsx("section", { className: "flex-1 p-6 overflow-y-auto bg-white dark:bg-black", children: filteredMessages.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-center text-
|
|
2318
|
-
"div",
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
/* @__PURE__ */
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
/* @__PURE__ */ jsx(
|
|
2330
|
-
/* @__PURE__ */
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
reaction.emoji
|
|
2353
|
-
)) })
|
|
2354
|
-
] })
|
|
2355
|
-
]
|
|
2356
|
-
},
|
|
2357
|
-
message.id
|
|
2358
|
-
)) })
|
|
2631
|
+
/* @__PURE__ */ jsx("section", { className: "flex-1 p-6 overflow-y-auto bg-white dark:bg-black", children: filteredMessages.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-center text-muted-foreground", children: "No messages to display." }) : filteredMessages.map((message) => /* @__PURE__ */ jsxs("div", { className: "mb-6 last:mb-0 group border-b border-border pb-4", children: [
|
|
2632
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 mb-2", children: [
|
|
2633
|
+
/* @__PURE__ */ jsx(Avatar, { src: message.sender.avatar, alt: message.sender.name }),
|
|
2634
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2635
|
+
/* @__PURE__ */ jsx("p", { className: "font-semibold text-black", children: message.sender.name }),
|
|
2636
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: message.timestamp })
|
|
2637
|
+
] })
|
|
2638
|
+
] }),
|
|
2639
|
+
/* @__PURE__ */ jsx("p", { className: "text-foreground text-lg mb-1", children: message.content }),
|
|
2640
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm text-muted-foreground", children: [
|
|
2641
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
2642
|
+
message.status === "read" && /* @__PURE__ */ jsx(DoubleCheck, { className: "w-5 h-5 text-green-500" }),
|
|
2643
|
+
message.status === "delivered" && /* @__PURE__ */ jsx(Check, { className: "w-5 h-5" }),
|
|
2644
|
+
/* @__PURE__ */ jsx("span", { children: message.timestamp })
|
|
2645
|
+
] }),
|
|
2646
|
+
/* @__PURE__ */ jsx("div", { className: "flex gap-2", children: message.reactions?.map((reaction) => /* @__PURE__ */ jsxs(
|
|
2647
|
+
"button",
|
|
2648
|
+
{
|
|
2649
|
+
type: "button",
|
|
2650
|
+
onClick: () => onReactionClick?.(message.id, reaction.emoji),
|
|
2651
|
+
className: cn(
|
|
2652
|
+
"px-2 py-1 rounded-[var(--radius-md)] text-sm transition-colors",
|
|
2653
|
+
reaction.reacted ? "bg-[var(--neutral-5)] text-black" : "bg-muted text-muted-foreground",
|
|
2654
|
+
"hover:bg-muted"
|
|
2655
|
+
),
|
|
2656
|
+
children: [
|
|
2657
|
+
reaction.emoji,
|
|
2658
|
+
" ",
|
|
2659
|
+
reaction.count
|
|
2660
|
+
]
|
|
2661
|
+
},
|
|
2662
|
+
reaction.emoji
|
|
2663
|
+
)) })
|
|
2664
|
+
] })
|
|
2665
|
+
] }, message.id)) })
|
|
2359
2666
|
] }),
|
|
2360
|
-
/* @__PURE__ */ jsxs("footer", { className: "mt-6 flex items-center gap-4 border-t border-
|
|
2667
|
+
/* @__PURE__ */ jsxs("footer", { className: "mt-6 flex items-center gap-4 border-t border-border pt-4", children: [
|
|
2361
2668
|
/* @__PURE__ */ jsx(
|
|
2362
2669
|
"button",
|
|
2363
2670
|
{
|
|
2364
2671
|
type: "button",
|
|
2365
2672
|
"aria-label": "Add emoji",
|
|
2366
|
-
className: "p-3 rounded-full bg-
|
|
2367
|
-
children: /* @__PURE__ */ jsx(FacePlus, { className: "w-6 h-6 text-
|
|
2673
|
+
className: "p-3 rounded-full bg-muted hover:bg-muted transition",
|
|
2674
|
+
children: /* @__PURE__ */ jsx(FacePlus, { className: "w-6 h-6 text-muted-foreground" })
|
|
2368
2675
|
}
|
|
2369
2676
|
),
|
|
2370
2677
|
/* @__PURE__ */ jsx(
|
|
@@ -2383,7 +2690,7 @@ function TeamChat({
|
|
|
2383
2690
|
type: "button",
|
|
2384
2691
|
"aria-label": "Send message",
|
|
2385
2692
|
onClick: handleSend,
|
|
2386
|
-
className: "p-3 rounded-full bg-black
|
|
2693
|
+
className: "p-3 rounded-full bg-black text-white dark:text-black hover:brightness-90 transition",
|
|
2387
2694
|
children: /* @__PURE__ */ jsx(PaperAirplane, { className: "w-6 h-6" })
|
|
2388
2695
|
}
|
|
2389
2696
|
)
|
|
@@ -2393,6 +2700,6 @@ function TeamChat({
|
|
|
2393
2700
|
);
|
|
2394
2701
|
}
|
|
2395
2702
|
|
|
2396
|
-
export { AnimateIn, AnimateInGroup, AsciiText, ChangelogWidget, NodeGraphCanvas, OnboardingChecklist, PromptInputBox, TeamChat };
|
|
2703
|
+
export { AnimateIn, AnimateInGroup, AnimatedCard, AnimatedDrawer, AnimatedList, AnimatedModal, AnimatedPopover, AsciiText, ChangelogWidget, FadeIn, ImageViewDialog, MAX_VISUALIZER_BARS, NodeGraphCanvas, OnboardingChecklist, PageTransition, PromptAttachmentPreviews, PromptInputBox, ScaleIn, SlideIn, TeamChat, VISUALIZER_BAR_STYLES, VoiceRecorder, animatedList, animatedListItem, animationDistances, animationDurations, animationEasings, animationSprings, animationTransitions, drawerSurface, fadeIn, formatRecordingTime, getFilePreviewKey, isImageFile, modalSurface, pageTransition, popoverSurface, preventDragDefaults, reducedMotionVariants, scaleIn, slideIn };
|
|
2397
2704
|
//# sourceMappingURL=index.js.map
|
|
2398
2705
|
//# sourceMappingURL=index.js.map
|