@nebutra/ui 0.2.1 → 0.2.3
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-Drca5UMj.d.ts +4309 -0
- package/dist/components/index.d.ts +51 -56
- package/dist/components/index.js +1696 -1203
- 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 +7 -3
- package/dist/layout/index.js +525 -542
- package/dist/layout/index.js.map +1 -1
- package/dist/layouts/index.d.ts +80 -2
- package/dist/layouts/index.js +32 -19
- package/dist/layouts/index.js.map +1 -1
- package/dist/patterns/index.d.ts +131 -5
- package/dist/patterns/index.js +1594 -806
- package/dist/patterns/index.js.map +1 -1
- package/dist/primitives/canonical.d.ts +25 -0
- package/dist/primitives/canonical.js +12269 -0
- package/dist/primitives/canonical.js.map +1 -0
- package/dist/primitives/index.d.ts +694 -3544
- package/dist/primitives/index.js +8994 -6583
- 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 +51 -37
- 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 +66 -14
- package/dist/utils/index.js +53 -10
- package/dist/utils/index.js.map +1 -1
- package/package.json +56 -14
- package/src/styles/brand-override.css +61 -0
- package/src/styles/preset.css +29 -0
- package/src/styles/sources.css +37 -0
- package/src/typography/fonts.css +124 -0
package/dist/components/index.js
CHANGED
|
@@ -1,43 +1,540 @@
|
|
|
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 { Popover as Popover$1 } from '@base-ui/react/popover';
|
|
21
|
+
import { ReactFlowProvider, ReactFlow, Background, Controls, Panel, Handle, Position } from '@xyflow/react';
|
|
21
22
|
import '@xyflow/react/dist/style.css';
|
|
22
23
|
import { wouldCreateCycle } from '@nebutra/graph-model';
|
|
23
24
|
import { Input as Input$1 } from '@base-ui/react/input';
|
|
24
25
|
|
|
25
26
|
// src/components/index.ts
|
|
27
|
+
|
|
28
|
+
// src/shared/animation/motion/tokens.ts
|
|
29
|
+
var animationDurations = {
|
|
30
|
+
instant: 0,
|
|
31
|
+
micro: 0.1,
|
|
32
|
+
fast: 0.16,
|
|
33
|
+
standard: 0.2,
|
|
34
|
+
reveal: 0.3,
|
|
35
|
+
page: 0.44
|
|
36
|
+
};
|
|
37
|
+
var animationEasings = {
|
|
38
|
+
linear: "linear",
|
|
39
|
+
enter: [0, 0, 0.2, 1],
|
|
40
|
+
exit: [0.4, 0, 1, 1],
|
|
41
|
+
standard: [0.4, 0, 0.2, 1],
|
|
42
|
+
emphasized: [0.16, 1, 0.3, 1]
|
|
43
|
+
};
|
|
44
|
+
var animationSprings = {
|
|
45
|
+
interactive: { type: "spring", stiffness: 380, damping: 34, mass: 0.8 },
|
|
46
|
+
layout: { type: "spring", stiffness: 480, damping: 42, mass: 1 },
|
|
47
|
+
panel: { type: "spring", stiffness: 320, damping: 36, mass: 1 }
|
|
48
|
+
};
|
|
49
|
+
var animationDistances = {
|
|
50
|
+
xs: 4,
|
|
51
|
+
sm: 8,
|
|
52
|
+
md: 16,
|
|
53
|
+
lg: 24,
|
|
54
|
+
panel: 32
|
|
55
|
+
};
|
|
56
|
+
var animationTransitions = {
|
|
57
|
+
instant: { duration: animationDurations.instant },
|
|
58
|
+
micro: { duration: animationDurations.micro, ease: animationEasings.enter },
|
|
59
|
+
standard: { duration: animationDurations.standard, ease: animationEasings.enter },
|
|
60
|
+
reveal: { duration: animationDurations.reveal, ease: animationEasings.emphasized },
|
|
61
|
+
page: { duration: animationDurations.page, ease: animationEasings.emphasized },
|
|
62
|
+
layout: animationSprings.layout,
|
|
63
|
+
panel: animationSprings.panel
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// src/shared/animation/motion/variants.ts
|
|
67
|
+
var fadeIn = {
|
|
68
|
+
initial: { opacity: 0 },
|
|
69
|
+
animate: { opacity: 1, transition: animationTransitions.standard },
|
|
70
|
+
exit: { opacity: 0, transition: animationTransitions.micro }
|
|
71
|
+
};
|
|
72
|
+
var scaleIn = {
|
|
73
|
+
initial: { opacity: 0, scale: 0.96 },
|
|
74
|
+
animate: { opacity: 1, scale: 1, transition: animationTransitions.reveal },
|
|
75
|
+
exit: { opacity: 0, scale: 0.98, transition: animationTransitions.micro }
|
|
76
|
+
};
|
|
77
|
+
var slideIn = {
|
|
78
|
+
up: {
|
|
79
|
+
initial: { opacity: 0, y: animationDistances.md },
|
|
80
|
+
animate: { opacity: 1, y: 0, transition: animationTransitions.reveal },
|
|
81
|
+
exit: { opacity: 0, y: animationDistances.sm, transition: animationTransitions.micro }
|
|
82
|
+
},
|
|
83
|
+
down: {
|
|
84
|
+
initial: { opacity: 0, y: -animationDistances.md },
|
|
85
|
+
animate: { opacity: 1, y: 0, transition: animationTransitions.reveal },
|
|
86
|
+
exit: { opacity: 0, y: -animationDistances.sm, transition: animationTransitions.micro }
|
|
87
|
+
},
|
|
88
|
+
left: {
|
|
89
|
+
initial: { opacity: 0, x: animationDistances.md },
|
|
90
|
+
animate: { opacity: 1, x: 0, transition: animationTransitions.reveal },
|
|
91
|
+
exit: { opacity: 0, x: animationDistances.sm, transition: animationTransitions.micro }
|
|
92
|
+
},
|
|
93
|
+
right: {
|
|
94
|
+
initial: { opacity: 0, x: -animationDistances.md },
|
|
95
|
+
animate: { opacity: 1, x: 0, transition: animationTransitions.reveal },
|
|
96
|
+
exit: { opacity: 0, x: -animationDistances.sm, transition: animationTransitions.micro }
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
var animatedList = {
|
|
100
|
+
initial: {},
|
|
101
|
+
animate: { transition: { staggerChildren: 0.06, delayChildren: 0.02 } },
|
|
102
|
+
exit: { transition: { staggerChildren: 0.03, staggerDirection: -1 } }
|
|
103
|
+
};
|
|
104
|
+
var animatedListItem = {
|
|
105
|
+
initial: { opacity: 0, y: animationDistances.sm },
|
|
106
|
+
animate: { opacity: 1, y: 0, transition: animationTransitions.standard },
|
|
107
|
+
exit: { opacity: 0, y: animationDistances.xs, transition: animationTransitions.micro }
|
|
108
|
+
};
|
|
109
|
+
var modalSurface = {
|
|
110
|
+
initial: { opacity: 0, scale: 0.98, y: animationDistances.sm },
|
|
111
|
+
animate: { opacity: 1, scale: 1, y: 0, transition: animationTransitions.panel },
|
|
112
|
+
exit: {
|
|
113
|
+
opacity: 0,
|
|
114
|
+
scale: 0.98,
|
|
115
|
+
y: animationDistances.xs,
|
|
116
|
+
transition: animationTransitions.micro
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
var drawerSurface = {
|
|
120
|
+
left: {
|
|
121
|
+
initial: { opacity: 0, x: "-100%" },
|
|
122
|
+
animate: { opacity: 1, x: 0, transition: animationTransitions.panel },
|
|
123
|
+
exit: { opacity: 0, x: "-100%", transition: animationTransitions.micro }
|
|
124
|
+
},
|
|
125
|
+
right: {
|
|
126
|
+
initial: { opacity: 0, x: "100%" },
|
|
127
|
+
animate: { opacity: 1, x: 0, transition: animationTransitions.panel },
|
|
128
|
+
exit: { opacity: 0, x: "100%", transition: animationTransitions.micro }
|
|
129
|
+
},
|
|
130
|
+
top: {
|
|
131
|
+
initial: { opacity: 0, y: "-100%" },
|
|
132
|
+
animate: { opacity: 1, y: 0, transition: animationTransitions.panel },
|
|
133
|
+
exit: { opacity: 0, y: "-100%", transition: animationTransitions.micro }
|
|
134
|
+
},
|
|
135
|
+
bottom: {
|
|
136
|
+
initial: { opacity: 0, y: "100%" },
|
|
137
|
+
animate: { opacity: 1, y: 0, transition: animationTransitions.panel },
|
|
138
|
+
exit: { opacity: 0, y: "100%", transition: animationTransitions.micro }
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
var popoverSurface = {
|
|
142
|
+
initial: { opacity: 0, scale: 0.98, y: animationDistances.xs },
|
|
143
|
+
animate: { opacity: 1, scale: 1, y: 0, transition: animationTransitions.standard },
|
|
144
|
+
exit: {
|
|
145
|
+
opacity: 0,
|
|
146
|
+
scale: 0.98,
|
|
147
|
+
y: animationDistances.xs,
|
|
148
|
+
transition: animationTransitions.micro
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
var pageTransition = {
|
|
152
|
+
initial: { opacity: 0, y: animationDistances.sm },
|
|
153
|
+
animate: { opacity: 1, y: 0, transition: animationTransitions.page },
|
|
154
|
+
exit: { opacity: 0, y: -animationDistances.xs, transition: animationTransitions.standard }
|
|
155
|
+
};
|
|
156
|
+
var reducedMotionVariants = {
|
|
157
|
+
initial: { opacity: 0 },
|
|
158
|
+
animate: { opacity: 1, transition: animationTransitions.instant },
|
|
159
|
+
exit: { opacity: 0, transition: animationTransitions.instant }
|
|
160
|
+
};
|
|
161
|
+
function useAccessibleVariants(variants, allowTransform = false) {
|
|
162
|
+
const shouldReduceMotion = useReducedMotion();
|
|
163
|
+
return shouldReduceMotion && !allowTransform ? reducedMotionVariants : variants;
|
|
164
|
+
}
|
|
165
|
+
function FadeIn({ children, ...props }) {
|
|
166
|
+
const variants = useAccessibleVariants(fadeIn);
|
|
167
|
+
return /* @__PURE__ */ jsx(motion.div, { initial: "initial", animate: "animate", exit: "exit", variants, ...props, children });
|
|
168
|
+
}
|
|
169
|
+
function SlideIn({
|
|
170
|
+
children,
|
|
171
|
+
direction = "up",
|
|
172
|
+
...props
|
|
173
|
+
}) {
|
|
174
|
+
const variants = useAccessibleVariants(slideIn[direction]);
|
|
175
|
+
return /* @__PURE__ */ jsx(motion.div, { initial: "initial", animate: "animate", exit: "exit", variants, ...props, children });
|
|
176
|
+
}
|
|
177
|
+
function ScaleIn({ children, ...props }) {
|
|
178
|
+
const variants = useAccessibleVariants(scaleIn);
|
|
179
|
+
return /* @__PURE__ */ jsx(motion.div, { initial: "initial", animate: "animate", exit: "exit", variants, ...props, children });
|
|
180
|
+
}
|
|
181
|
+
function AnimatedCard({ children, ...props }) {
|
|
182
|
+
return /* @__PURE__ */ jsx(ScaleIn, { whileHover: { y: -2 }, whileTap: { scale: 0.99 }, ...props, children });
|
|
183
|
+
}
|
|
184
|
+
function AnimatedList({ children, ...props }) {
|
|
185
|
+
const containerVariants2 = useAccessibleVariants(animatedList);
|
|
186
|
+
const itemVariants2 = useAccessibleVariants(animatedListItem);
|
|
187
|
+
return /* @__PURE__ */ jsx(
|
|
188
|
+
motion.div,
|
|
189
|
+
{
|
|
190
|
+
initial: "initial",
|
|
191
|
+
animate: "animate",
|
|
192
|
+
exit: "exit",
|
|
193
|
+
variants: containerVariants2,
|
|
194
|
+
...props,
|
|
195
|
+
children: Array.isArray(children) ? children.map((child, index) => /* @__PURE__ */ jsx(motion.div, { variants: itemVariants2, children: child }, index)) : children
|
|
196
|
+
}
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
function AnimatedModal({ children, open, ...props }) {
|
|
200
|
+
const variants = useAccessibleVariants(modalSurface);
|
|
201
|
+
return /* @__PURE__ */ jsx(AnimatePresence, { children: open ? /* @__PURE__ */ jsx(motion.div, { initial: "initial", animate: "animate", exit: "exit", variants, ...props, children }) : null });
|
|
202
|
+
}
|
|
203
|
+
function AnimatedDrawer({
|
|
204
|
+
children,
|
|
205
|
+
open,
|
|
206
|
+
side = "right",
|
|
207
|
+
...props
|
|
208
|
+
}) {
|
|
209
|
+
const variants = useAccessibleVariants(drawerSurface[side]);
|
|
210
|
+
return /* @__PURE__ */ jsx(AnimatePresence, { children: open ? /* @__PURE__ */ jsx(motion.div, { initial: "initial", animate: "animate", exit: "exit", variants, ...props, children }) : null });
|
|
211
|
+
}
|
|
212
|
+
function AnimatedPopover({
|
|
213
|
+
children,
|
|
214
|
+
open,
|
|
215
|
+
...props
|
|
216
|
+
}) {
|
|
217
|
+
const variants = useAccessibleVariants(popoverSurface);
|
|
218
|
+
return /* @__PURE__ */ jsx(AnimatePresence, { children: open ? /* @__PURE__ */ jsx(motion.div, { initial: "initial", animate: "animate", exit: "exit", variants, ...props, children }) : null });
|
|
219
|
+
}
|
|
220
|
+
function PageTransition({ children, ...props }) {
|
|
221
|
+
const variants = useAccessibleVariants(pageTransition);
|
|
222
|
+
return /* @__PURE__ */ jsx(motion.div, { initial: "initial", animate: "animate", exit: "exit", variants, ...props, children });
|
|
223
|
+
}
|
|
224
|
+
({
|
|
225
|
+
// Nebutra Blue (云毓蓝) — technology & trust — VI: #0033FE
|
|
226
|
+
blue50: colors.primary[50],
|
|
227
|
+
blue100: colors.primary[100],
|
|
228
|
+
blue200: colors.primary[200],
|
|
229
|
+
blue300: colors.primary[300],
|
|
230
|
+
blue400: colors.primary[400],
|
|
231
|
+
blue500: colors.primary[500],
|
|
232
|
+
// brand primary
|
|
233
|
+
blue600: colors.primary[600],
|
|
234
|
+
blue700: colors.primary[700],
|
|
235
|
+
blue800: colors.primary[800],
|
|
236
|
+
blue900: colors.primary[900],
|
|
237
|
+
blue950: colors.primary[950],
|
|
238
|
+
// Nebutra Cyan (云毓青) — data flow & intelligence — VI: #0BF1C3
|
|
239
|
+
cyan50: colors.accent[50],
|
|
240
|
+
cyan100: colors.accent[100],
|
|
241
|
+
cyan200: colors.accent[200],
|
|
242
|
+
cyan300: colors.accent[300],
|
|
243
|
+
cyan400: colors.accent[400],
|
|
244
|
+
cyan500: colors.accent[500],
|
|
245
|
+
// brand secondary
|
|
246
|
+
cyan600: colors.accent[600],
|
|
247
|
+
cyan700: colors.accent[700],
|
|
248
|
+
cyan800: colors.accent[800],
|
|
249
|
+
cyan900: colors.accent[900],
|
|
250
|
+
cyan950: colors.accent[950],
|
|
251
|
+
// Neutral (blue-undertone gray scale)
|
|
252
|
+
neutral50: colors.neutral[50],
|
|
253
|
+
neutral100: colors.neutral[100],
|
|
254
|
+
neutral200: colors.neutral[200],
|
|
255
|
+
neutral300: colors.neutral[300],
|
|
256
|
+
neutral400: colors.neutral[400],
|
|
257
|
+
neutral500: colors.neutral[500],
|
|
258
|
+
neutral600: colors.neutral[600],
|
|
259
|
+
neutral700: colors.neutral[700],
|
|
260
|
+
neutral800: colors.neutral[800],
|
|
261
|
+
neutral900: colors.neutral[900],
|
|
262
|
+
neutral950: colors.neutral[950],
|
|
263
|
+
white: colors.white,
|
|
264
|
+
black: colors.black
|
|
265
|
+
});
|
|
266
|
+
({
|
|
267
|
+
/** Hero sections, primary CTA buttons, logo fills — VI signature gradient */
|
|
268
|
+
primary: colors.gradient.primary,
|
|
269
|
+
/** Hover states, secondary gradient elements */
|
|
270
|
+
reverse: colors.gradient.primaryReverse,
|
|
271
|
+
/** Vertical layout dividers, page section separators */
|
|
272
|
+
vertical: colors.gradient.primaryVertical,
|
|
273
|
+
/** Background halos, focus glow effects, radial emphasis */
|
|
274
|
+
radial: colors.gradient.primaryRadial});
|
|
275
|
+
var primitiveSpacing = {
|
|
276
|
+
1: 4,
|
|
277
|
+
2: 8,
|
|
278
|
+
3: 12,
|
|
279
|
+
4: 16,
|
|
280
|
+
20: 80,
|
|
281
|
+
24: 96
|
|
282
|
+
};
|
|
283
|
+
var primitiveSizing = {
|
|
284
|
+
xs: 20,
|
|
285
|
+
/** Geist button-specific size (24px). Larger than xs by design. */
|
|
286
|
+
tiny: 24,
|
|
287
|
+
sm: 32,
|
|
288
|
+
md: 40,
|
|
289
|
+
lg: 48};
|
|
290
|
+
var primitiveRadius = {
|
|
291
|
+
md: 6,
|
|
292
|
+
// Geist default — slightly more rounded than 4px
|
|
293
|
+
lg: 8};
|
|
294
|
+
var primitiveFontSize = {
|
|
295
|
+
xs: 12,
|
|
296
|
+
sm: 14,
|
|
297
|
+
base: 16};
|
|
298
|
+
|
|
299
|
+
// src/tokens/shadows.ts
|
|
300
|
+
var shadowClasses = {
|
|
301
|
+
md: "shadow-md",
|
|
302
|
+
xl: "shadow-xl",
|
|
303
|
+
"2xl": "shadow-2xl"};
|
|
304
|
+
|
|
305
|
+
// src/tokens/components/overlay.ts
|
|
306
|
+
var overlayFocusRingClassName = "outline-none";
|
|
307
|
+
var overlayZIndex = {
|
|
308
|
+
backdrop: 1040,
|
|
309
|
+
modal: 1050,
|
|
310
|
+
popover: 1060,
|
|
311
|
+
tooltip: 1070
|
|
312
|
+
};
|
|
313
|
+
var overlayClassNames = {
|
|
314
|
+
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",
|
|
315
|
+
modalSurface: [
|
|
316
|
+
"fixed left-1/2 top-1/2 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4",
|
|
317
|
+
"border border-border/60 bg-background/95 p-6 text-foreground backdrop-blur-xl",
|
|
318
|
+
"rounded-[var(--radius-xl)]",
|
|
319
|
+
shadowClasses["2xl"],
|
|
320
|
+
"outline-none",
|
|
321
|
+
"transition-[opacity,transform,display] duration-[var(--motion-duration-flow)] ease-[var(--ease-out)]",
|
|
322
|
+
"data-starting-style:scale-95 data-starting-style:opacity-0 data-ending-style:scale-95 data-ending-style:opacity-0",
|
|
323
|
+
"motion-reduce:transition-none motion-reduce:data-starting-style:transform-none motion-reduce:data-ending-style:transform-none"
|
|
324
|
+
].join(" "),
|
|
325
|
+
popoverSurface: [
|
|
326
|
+
"w-72 rounded-[var(--radius-lg)] border border-border/70 bg-popover/95 p-4 text-popover-foreground backdrop-blur-md",
|
|
327
|
+
shadowClasses.xl,
|
|
328
|
+
"outline-none transition-[opacity,transform,display] duration-[var(--motion-duration-flow)] ease-[var(--ease-out)]",
|
|
329
|
+
"data-[open]:opacity-100 data-[closed]:opacity-0 data-[closed]:scale-95 data-[open]:scale-100",
|
|
330
|
+
"motion-reduce:transition-none motion-reduce:data-[closed]:transform-none motion-reduce:data-[open]:transform-none"
|
|
331
|
+
].join(" "),
|
|
332
|
+
tooltipSurface: [
|
|
333
|
+
"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",
|
|
334
|
+
shadowClasses.md,
|
|
335
|
+
"transition-[opacity,transform,display] duration-[var(--motion-duration-flow)] ease-[var(--ease-out)]",
|
|
336
|
+
"data-starting-style:scale-95 data-starting-style:opacity-0 data-ending-style:scale-95 data-ending-style:opacity-0",
|
|
337
|
+
"motion-reduce:transition-none motion-reduce:data-starting-style:transform-none motion-reduce:data-ending-style:transform-none"
|
|
338
|
+
].join(" "),
|
|
339
|
+
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`
|
|
340
|
+
};
|
|
26
341
|
function cn(...inputs) {
|
|
27
342
|
return twMerge(clsx(inputs));
|
|
28
343
|
}
|
|
29
|
-
var
|
|
344
|
+
var overlayPrimitiveClassNames = {
|
|
345
|
+
modalSurface: "rounded-[var(--radius-md)] border-border/70 bg-popover/95 text-popover-foreground shadow-xl",
|
|
346
|
+
popoverSurface: "rounded-[var(--radius-md)] border-border/70 bg-popover/95 shadow-md"};
|
|
347
|
+
var Dialog = Dialog$1.Root;
|
|
348
|
+
var DialogPortal = Dialog$1.Portal;
|
|
349
|
+
var DialogTrigger = ({
|
|
350
|
+
asChild,
|
|
351
|
+
children,
|
|
352
|
+
ref,
|
|
353
|
+
...props
|
|
354
|
+
}) => {
|
|
355
|
+
if (asChild && React5.isValidElement(children)) {
|
|
356
|
+
return /* @__PURE__ */ jsx(
|
|
357
|
+
Dialog$1.Trigger,
|
|
358
|
+
{
|
|
359
|
+
ref,
|
|
360
|
+
...props,
|
|
361
|
+
render: children
|
|
362
|
+
}
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
return /* @__PURE__ */ jsx(Dialog$1.Trigger, { ref, ...props, children });
|
|
366
|
+
};
|
|
367
|
+
DialogTrigger.displayName = "DialogTrigger";
|
|
368
|
+
var DialogClose = ({
|
|
369
|
+
asChild,
|
|
370
|
+
children,
|
|
371
|
+
ref,
|
|
372
|
+
...props
|
|
373
|
+
}) => {
|
|
374
|
+
if (asChild && React5.isValidElement(children)) {
|
|
375
|
+
return /* @__PURE__ */ jsx(
|
|
376
|
+
Dialog$1.Close,
|
|
377
|
+
{
|
|
378
|
+
ref,
|
|
379
|
+
...props,
|
|
380
|
+
render: children
|
|
381
|
+
}
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
return /* @__PURE__ */ jsx(Dialog$1.Close, { ref, ...props, children });
|
|
385
|
+
};
|
|
386
|
+
DialogClose.displayName = "DialogClose";
|
|
387
|
+
var DialogOverlay = ({
|
|
388
|
+
className,
|
|
389
|
+
style,
|
|
390
|
+
ref,
|
|
391
|
+
...props
|
|
392
|
+
}) => /* @__PURE__ */ jsx(
|
|
393
|
+
Dialog$1.Backdrop,
|
|
394
|
+
{
|
|
395
|
+
ref,
|
|
396
|
+
className: cn(overlayClassNames.backdrop, className),
|
|
397
|
+
style: { zIndex: overlayZIndex.backdrop, ...style },
|
|
398
|
+
...props
|
|
399
|
+
}
|
|
400
|
+
);
|
|
401
|
+
DialogOverlay.displayName = "DialogOverlay";
|
|
402
|
+
var DialogContent = ({
|
|
403
|
+
className,
|
|
404
|
+
children,
|
|
405
|
+
style,
|
|
406
|
+
ref,
|
|
407
|
+
...props
|
|
408
|
+
}) => /* @__PURE__ */ jsxs(DialogPortal, { children: [
|
|
409
|
+
/* @__PURE__ */ jsx(DialogOverlay, {}),
|
|
410
|
+
/* @__PURE__ */ jsxs(
|
|
411
|
+
Dialog$1.Popup,
|
|
412
|
+
{
|
|
413
|
+
ref,
|
|
414
|
+
className: cn(
|
|
415
|
+
overlayClassNames.modalSurface,
|
|
416
|
+
overlayPrimitiveClassNames.modalSurface,
|
|
417
|
+
className
|
|
418
|
+
),
|
|
419
|
+
style: { zIndex: overlayZIndex.modal, ...style },
|
|
420
|
+
...props,
|
|
421
|
+
children: [
|
|
422
|
+
children,
|
|
423
|
+
/* @__PURE__ */ jsxs(DialogClose, { className: overlayClassNames.closeButton, children: [
|
|
424
|
+
/* @__PURE__ */ jsx(Cross, { className: "h-4 w-4" }),
|
|
425
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
|
|
426
|
+
] })
|
|
427
|
+
]
|
|
428
|
+
}
|
|
429
|
+
)
|
|
430
|
+
] });
|
|
431
|
+
DialogContent.displayName = "DialogContent";
|
|
432
|
+
var DialogTitle = ({
|
|
433
|
+
className,
|
|
434
|
+
ref,
|
|
435
|
+
...props
|
|
436
|
+
}) => /* @__PURE__ */ jsx(
|
|
437
|
+
Dialog$1.Title,
|
|
438
|
+
{
|
|
439
|
+
ref,
|
|
440
|
+
className: cn("text-lg font-semibold leading-none tracking-tight", className),
|
|
441
|
+
...props
|
|
442
|
+
}
|
|
443
|
+
);
|
|
444
|
+
DialogTitle.displayName = "DialogTitle";
|
|
445
|
+
var isImageFile = (file) => file.type.startsWith("image/");
|
|
446
|
+
var getFilePreviewKey = (file) => `${file.name}-${file.size}-${file.lastModified}`;
|
|
447
|
+
var preventDragDefaults = (e) => {
|
|
448
|
+
e.preventDefault();
|
|
449
|
+
e.stopPropagation();
|
|
450
|
+
};
|
|
451
|
+
var ImageViewDialog = ({ imageUrl, onClose }) => {
|
|
452
|
+
const shouldReduceMotion = useReducedMotion();
|
|
453
|
+
if (!imageUrl) return null;
|
|
454
|
+
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: [
|
|
455
|
+
/* @__PURE__ */ jsx(DialogTitle, { className: "sr-only", children: "Image Preview" }),
|
|
456
|
+
/* @__PURE__ */ jsx(
|
|
457
|
+
m.div,
|
|
458
|
+
{
|
|
459
|
+
initial: shouldReduceMotion ? { opacity: 1 } : { opacity: 0, scale: 0.95 },
|
|
460
|
+
animate: { opacity: 1, ...shouldReduceMotion ? {} : { scale: 1 } },
|
|
461
|
+
exit: shouldReduceMotion ? { opacity: 0 } : { opacity: 0, scale: 0.95 },
|
|
462
|
+
transition: shouldReduceMotion ? { duration: 0 } : { duration: 0.2, ease: "easeOut" },
|
|
463
|
+
className: "relative bg-background rounded-[var(--radius-2xl)] overflow-hidden shadow-2xl",
|
|
464
|
+
children: /* @__PURE__ */ jsx(
|
|
465
|
+
Image,
|
|
466
|
+
{
|
|
467
|
+
src: imageUrl,
|
|
468
|
+
alt: "Full preview",
|
|
469
|
+
className: "w-full max-h-[80vh] object-contain rounded-[var(--radius-2xl)]",
|
|
470
|
+
fill: true,
|
|
471
|
+
sizes: "(max-width: 768px) 90vw, 800px"
|
|
472
|
+
}
|
|
473
|
+
)
|
|
474
|
+
}
|
|
475
|
+
)
|
|
476
|
+
] }) });
|
|
477
|
+
};
|
|
478
|
+
ImageViewDialog.displayName = "ImageViewDialog";
|
|
479
|
+
function PromptAttachmentPreviews({
|
|
480
|
+
files,
|
|
481
|
+
filePreviews,
|
|
482
|
+
isRecording,
|
|
483
|
+
onPreview,
|
|
484
|
+
onRemove
|
|
485
|
+
}) {
|
|
486
|
+
if (files.length === 0 || isRecording) return null;
|
|
487
|
+
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) => {
|
|
488
|
+
const previewKey = getFilePreviewKey(file);
|
|
489
|
+
const preview = filePreviews[previewKey];
|
|
490
|
+
return /* @__PURE__ */ jsx("div", { className: "relative group h-16 w-16", children: isImageFile(file) && preview && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
491
|
+
/* @__PURE__ */ jsx(
|
|
492
|
+
"button",
|
|
493
|
+
{
|
|
494
|
+
type: "button",
|
|
495
|
+
"aria-label": `Preview ${file.name}`,
|
|
496
|
+
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",
|
|
497
|
+
onClick: () => onPreview(preview),
|
|
498
|
+
children: /* @__PURE__ */ jsx(
|
|
499
|
+
Image,
|
|
500
|
+
{
|
|
501
|
+
src: preview,
|
|
502
|
+
alt: file.name,
|
|
503
|
+
className: "h-full w-full object-cover",
|
|
504
|
+
fill: true,
|
|
505
|
+
sizes: "64px"
|
|
506
|
+
}
|
|
507
|
+
)
|
|
508
|
+
}
|
|
509
|
+
),
|
|
510
|
+
/* @__PURE__ */ jsx(
|
|
511
|
+
"button",
|
|
512
|
+
{
|
|
513
|
+
type: "button",
|
|
514
|
+
"aria-label": `Remove ${file.name}`,
|
|
515
|
+
onClick: (event) => {
|
|
516
|
+
event.stopPropagation();
|
|
517
|
+
onRemove(file);
|
|
518
|
+
},
|
|
519
|
+
className: "absolute top-1 right-1 rounded-full bg-black/70 p-0.5 opacity-100 transition-opacity motion-reduce:transition-none",
|
|
520
|
+
children: /* @__PURE__ */ jsx(Cross, { className: "h-3 w-3 text-white" })
|
|
521
|
+
}
|
|
522
|
+
)
|
|
523
|
+
] }) }, previewKey);
|
|
524
|
+
}) });
|
|
525
|
+
}
|
|
526
|
+
var Slot = React5.forwardRef(
|
|
30
527
|
({ children, className, style, ...props }, ref) => {
|
|
31
|
-
const childArray =
|
|
528
|
+
const childArray = React5.Children.toArray(children);
|
|
32
529
|
const child = childArray.length === 1 ? childArray[0] : null;
|
|
33
|
-
if (child == null || !
|
|
530
|
+
if (child == null || !React5.isValidElement(child)) {
|
|
34
531
|
return /* @__PURE__ */ jsx("span", { ref, className, style, ...props, children });
|
|
35
532
|
}
|
|
36
533
|
const childProps = child.props;
|
|
37
534
|
const mergedRef = (node) => {
|
|
38
535
|
if (typeof ref === "function") ref(node);
|
|
39
536
|
else if (ref) ref.current = node;
|
|
40
|
-
const childRef =
|
|
537
|
+
const childRef = childProps.ref;
|
|
41
538
|
if (typeof childRef === "function") childRef(node);
|
|
42
539
|
else if (childRef && "current" in childRef) {
|
|
43
540
|
childRef.current = node;
|
|
@@ -51,7 +548,7 @@ var Slot = React6.forwardRef(
|
|
|
51
548
|
className: mergedClass,
|
|
52
549
|
style: { ...childProps.style, ...style }
|
|
53
550
|
};
|
|
54
|
-
return
|
|
551
|
+
return React5.cloneElement(
|
|
55
552
|
child,
|
|
56
553
|
merged
|
|
57
554
|
);
|
|
@@ -61,17 +558,18 @@ Slot.displayName = "Slot";
|
|
|
61
558
|
var buttonVariants = cva(
|
|
62
559
|
[
|
|
63
560
|
"inline-flex items-center justify-center gap-2 whitespace-nowrap",
|
|
64
|
-
"rounded-[var(--radius-md)]
|
|
65
|
-
"
|
|
66
|
-
"
|
|
561
|
+
"rounded-[var(--btn-default-radius,var(--radius-md))]",
|
|
562
|
+
"text-[length:var(--control-font-size-md,0.875rem)] font-[number:var(--font-weight-medium,500)]",
|
|
563
|
+
"transition-colors duration-micro ease-out",
|
|
67
564
|
"disabled:pointer-events-none disabled:opacity-50",
|
|
68
565
|
"aria-busy:cursor-wait"
|
|
69
566
|
].join(" "),
|
|
70
567
|
{
|
|
71
568
|
variants: {
|
|
72
569
|
variant: {
|
|
73
|
-
|
|
74
|
-
|
|
570
|
+
// Recipe-driven via packages/design/tokens/recipe.css (.btn-brand-default)
|
|
571
|
+
default: "btn-brand-default",
|
|
572
|
+
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
573
|
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
76
574
|
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
|
77
575
|
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
@@ -81,34 +579,99 @@ var buttonVariants = cva(
|
|
|
81
579
|
warning: "bg-warning text-warning-foreground hover:bg-warning/90"
|
|
82
580
|
},
|
|
83
581
|
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)
|
|
582
|
+
tiny: "h-[var(--control-height-tiny,1.5rem)] rounded-[var(--radius-sm)] px-2 text-[length:var(--control-font-size-tiny,0.6875rem)]",
|
|
583
|
+
sm: "h-[var(--control-height-sm,2rem)] rounded-[var(--radius-sm)] px-3 text-[length:var(--control-font-size-sm,0.75rem)]",
|
|
584
|
+
default: "h-[var(--control-height-md,2.5rem)] px-[var(--btn-default-padding-x,1rem)] py-[var(--btn-default-padding-y,0.5rem)]",
|
|
585
|
+
lg: "h-[var(--control-height-lg,3rem)] rounded-[var(--radius-lg)] px-5 text-[length:var(--control-font-size-lg,1rem)]",
|
|
586
|
+
icon: "h-[var(--control-height-md,2.5rem)] w-[var(--control-height-md,2.5rem)]"
|
|
94
587
|
},
|
|
95
588
|
shape: {
|
|
96
589
|
default: "",
|
|
97
|
-
|
|
98
|
-
|
|
590
|
+
// Radius from --btn-default-radius / --radius-md — brand-switchable.
|
|
591
|
+
// Do not hardcode rounded-md here; a language must be able to retarget
|
|
592
|
+
// the corner treatment of every icon trigger at once.
|
|
593
|
+
square: "rounded-[var(--btn-default-radius,var(--radius-md))]",
|
|
594
|
+
// Pill radius token, not Tailwind rounded-full — same 9999px default,
|
|
595
|
+
// but a brand that ships a softer "circle" can override --radius-pill.
|
|
596
|
+
circle: "rounded-[var(--radius-pill,9999px)]",
|
|
597
|
+
pill: "rounded-[var(--radius-pill,9999px)]"
|
|
598
|
+
},
|
|
599
|
+
// Icon-only box size — orthogonal to `size` (which tunes text-button
|
|
600
|
+
// height/padding/font together) and to `shape` (which picks the
|
|
601
|
+
// corner treatment). Only takes effect combined with shape="square"
|
|
602
|
+
// or shape="circle" (see compoundVariants below); every other
|
|
603
|
+
// combination ignores it. 28/32/36 cover the icon-trigger sizes that
|
|
604
|
+
// actually occur in the app — 24/40/48 are already reachable via
|
|
605
|
+
// shape + size (tiny/default/lg). Heights read --control-height-icon-*
|
|
606
|
+
// so density-aware Brand Packages can scale them with the ladder.
|
|
607
|
+
iconSize: {
|
|
608
|
+
sm: "",
|
|
609
|
+
// 28px default
|
|
610
|
+
md: "",
|
|
611
|
+
// 32px default
|
|
612
|
+
lg: ""
|
|
613
|
+
// 36px default
|
|
99
614
|
}
|
|
100
615
|
},
|
|
101
616
|
compoundVariants: [
|
|
102
|
-
|
|
103
|
-
{ shape: "square", size: "
|
|
104
|
-
{ shape: "square", size: "
|
|
105
|
-
{ shape: "square", size: "
|
|
106
|
-
{
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
{
|
|
617
|
+
{ shape: "square", size: "tiny", className: "w-[var(--control-height-tiny,1.5rem)] px-0" },
|
|
618
|
+
{ shape: "square", size: "sm", className: "w-[var(--control-height-sm,2rem)] px-0" },
|
|
619
|
+
{ shape: "square", size: "default", className: "w-[var(--control-height-md,2.5rem)] px-0" },
|
|
620
|
+
{ shape: "square", size: "lg", className: "w-[var(--control-height-lg,3rem)] px-0" },
|
|
621
|
+
{
|
|
622
|
+
shape: "circle",
|
|
623
|
+
size: "tiny",
|
|
624
|
+
className: "w-[var(--control-height-tiny,1.5rem)] px-0"
|
|
625
|
+
},
|
|
626
|
+
{
|
|
627
|
+
shape: "circle",
|
|
628
|
+
size: "sm",
|
|
629
|
+
className: "w-[var(--control-height-sm,2rem)] px-0"
|
|
630
|
+
},
|
|
631
|
+
{
|
|
632
|
+
shape: "circle",
|
|
633
|
+
size: "default",
|
|
634
|
+
className: "w-[var(--control-height-md,2.5rem)] px-0"
|
|
635
|
+
},
|
|
636
|
+
{
|
|
637
|
+
shape: "circle",
|
|
638
|
+
size: "lg",
|
|
639
|
+
className: "w-[var(--control-height-lg,3rem)] px-0"
|
|
640
|
+
},
|
|
641
|
+
// iconSize wins over the size-driven box above — matched on shape +
|
|
642
|
+
// iconSize only, so it applies regardless of whatever `size` was
|
|
643
|
+
// passed (or left at its "default" fallback). Corner treatment stays
|
|
644
|
+
// on the shape variant (token-backed); only the box is set here.
|
|
645
|
+
{
|
|
646
|
+
shape: "square",
|
|
647
|
+
iconSize: "sm",
|
|
648
|
+
className: "h-[var(--control-height-icon-sm,1.75rem)] w-[var(--control-height-icon-sm,1.75rem)] px-0"
|
|
649
|
+
},
|
|
650
|
+
{
|
|
651
|
+
shape: "square",
|
|
652
|
+
iconSize: "md",
|
|
653
|
+
className: "h-[var(--control-height-icon-md,2rem)] w-[var(--control-height-icon-md,2rem)] px-0"
|
|
654
|
+
},
|
|
655
|
+
{
|
|
656
|
+
shape: "square",
|
|
657
|
+
iconSize: "lg",
|
|
658
|
+
className: "h-[var(--control-height-icon-lg,2.25rem)] w-[var(--control-height-icon-lg,2.25rem)] px-0"
|
|
659
|
+
},
|
|
660
|
+
{
|
|
661
|
+
shape: "circle",
|
|
662
|
+
iconSize: "sm",
|
|
663
|
+
className: "h-[var(--control-height-icon-sm,1.75rem)] w-[var(--control-height-icon-sm,1.75rem)] px-0"
|
|
664
|
+
},
|
|
665
|
+
{
|
|
666
|
+
shape: "circle",
|
|
667
|
+
iconSize: "md",
|
|
668
|
+
className: "h-[var(--control-height-icon-md,2rem)] w-[var(--control-height-icon-md,2rem)] px-0"
|
|
669
|
+
},
|
|
670
|
+
{
|
|
671
|
+
shape: "circle",
|
|
672
|
+
iconSize: "lg",
|
|
673
|
+
className: "h-[var(--control-height-icon-lg,2.25rem)] w-[var(--control-height-icon-lg,2.25rem)] px-0"
|
|
674
|
+
}
|
|
112
675
|
],
|
|
113
676
|
defaultVariants: {
|
|
114
677
|
variant: "default",
|
|
@@ -129,7 +692,10 @@ function Spinner({ className }) {
|
|
|
129
692
|
}
|
|
130
693
|
);
|
|
131
694
|
}
|
|
132
|
-
function getIconSizeClass(size) {
|
|
695
|
+
function getIconSizeClass(size, iconSize) {
|
|
696
|
+
if (iconSize === "sm") return "[&>svg]:size-3.5";
|
|
697
|
+
if (iconSize === "md") return "[&>svg]:size-3.5";
|
|
698
|
+
if (iconSize === "lg") return "[&>svg]:size-4";
|
|
133
699
|
switch (size) {
|
|
134
700
|
case "tiny":
|
|
135
701
|
return "[&>svg]:size-3";
|
|
@@ -144,7 +710,10 @@ function getIconSizeClass(size) {
|
|
|
144
710
|
return "[&>svg]:size-4";
|
|
145
711
|
}
|
|
146
712
|
}
|
|
147
|
-
function getSpinnerSizeClass(size) {
|
|
713
|
+
function getSpinnerSizeClass(size, iconSize) {
|
|
714
|
+
if (iconSize === "sm") return "size-3.5";
|
|
715
|
+
if (iconSize === "md") return "size-3.5";
|
|
716
|
+
if (iconSize === "lg") return "size-4";
|
|
148
717
|
switch (size) {
|
|
149
718
|
case "tiny":
|
|
150
719
|
return "size-3";
|
|
@@ -162,269 +731,64 @@ function getSpinnerSizeClass(size) {
|
|
|
162
731
|
var SHADOW_CLASSES = {
|
|
163
732
|
sm: "shadow-sm",
|
|
164
733
|
md: "shadow-md",
|
|
165
|
-
lg: "shadow-
|
|
734
|
+
lg: "shadow-md"
|
|
166
735
|
};
|
|
167
736
|
function resolveShadowClass(shadow) {
|
|
168
737
|
if (!shadow) return void 0;
|
|
169
738
|
const level = shadow === true ? "md" : shadow;
|
|
170
739
|
return SHADOW_CLASSES[level];
|
|
171
740
|
}
|
|
172
|
-
function ButtonContent({ loading, prefix, suffix, size, children }) {
|
|
173
|
-
const iconSizeClass = getIconSizeClass(size);
|
|
741
|
+
function ButtonContent({ loading, prefix, suffix, size, iconSize, children }) {
|
|
742
|
+
const iconSizeClass = getIconSizeClass(size, iconSize);
|
|
174
743
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
175
|
-
loading && /* @__PURE__ */ jsx(Spinner, { className: getSpinnerSizeClass(size) }),
|
|
744
|
+
loading && /* @__PURE__ */ jsx(Spinner, { className: getSpinnerSizeClass(size, iconSize) }),
|
|
176
745
|
prefix != null && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn("shrink-0", iconSizeClass), children: prefix }),
|
|
177
746
|
children,
|
|
178
747
|
suffix != null && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn("shrink-0", iconSizeClass), children: suffix })
|
|
179
748
|
] });
|
|
180
749
|
}
|
|
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,
|
|
750
|
+
var Button = ({
|
|
751
|
+
className,
|
|
752
|
+
variant,
|
|
753
|
+
size,
|
|
754
|
+
shape,
|
|
755
|
+
iconSize,
|
|
756
|
+
asChild = false,
|
|
757
|
+
loading = false,
|
|
758
|
+
disabled,
|
|
759
|
+
prefix,
|
|
760
|
+
suffix,
|
|
761
|
+
shadow,
|
|
762
|
+
children,
|
|
763
|
+
ref,
|
|
764
|
+
...props
|
|
765
|
+
}) => {
|
|
766
|
+
const Comp = asChild ? Slot : "button";
|
|
767
|
+
const isDisabled = Boolean(disabled || loading);
|
|
768
|
+
const shadowClass = resolveShadowClass(shadow);
|
|
769
|
+
return /* @__PURE__ */ jsx(
|
|
770
|
+
Comp,
|
|
296
771
|
{
|
|
297
772
|
ref,
|
|
298
|
-
className: cn(
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
),
|
|
773
|
+
className: cn(buttonVariants({ variant, size, shape, iconSize }), shadowClass, className),
|
|
774
|
+
disabled: isDisabled,
|
|
775
|
+
"aria-busy": loading || void 0,
|
|
302
776
|
...props,
|
|
303
|
-
children:
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
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
|
|
321
|
-
}
|
|
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
|
|
777
|
+
children: asChild ? children : /* @__PURE__ */ jsx(
|
|
778
|
+
ButtonContent,
|
|
779
|
+
{
|
|
780
|
+
loading,
|
|
781
|
+
prefix,
|
|
782
|
+
suffix,
|
|
783
|
+
size,
|
|
784
|
+
iconSize,
|
|
785
|
+
children
|
|
786
|
+
}
|
|
787
|
+
)
|
|
332
788
|
}
|
|
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
|
|
789
|
+
);
|
|
412
790
|
};
|
|
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};
|
|
791
|
+
Button.displayName = "Button";
|
|
428
792
|
|
|
429
793
|
// src/tokens/components/textarea.ts
|
|
430
794
|
var textareaTokens = {
|
|
@@ -454,6 +818,20 @@ var textareaTokens = {
|
|
|
454
818
|
labelSize: primitiveFontSize.sm,
|
|
455
819
|
focusRingWidth: 3,
|
|
456
820
|
fieldGap: primitiveSpacing[2] - primitiveSpacing[1] / 2};
|
|
821
|
+
|
|
822
|
+
// src/utils/primitive-props.ts
|
|
823
|
+
function asPlainStyle(style) {
|
|
824
|
+
if (style == null || typeof style === "function") return {};
|
|
825
|
+
return style;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
// src/primitives/form-control.ts
|
|
829
|
+
var formControlFocusClassNames = {
|
|
830
|
+
input: "outline-none focus:border-ring focus:ring-[length:var(--input-focus-ring-width)] focus:ring-ring/30",
|
|
831
|
+
textarea: "outline-none focus:border-ring focus:ring-[length:var(--textarea-focus-ring-width)] focus:ring-ring/30"};
|
|
832
|
+
var formControlInvalidClassNames = {
|
|
833
|
+
input: "aria-invalid:border-destructive/60 aria-invalid:focus:border-destructive aria-invalid:focus:ring-destructive/20",
|
|
834
|
+
textarea: "aria-invalid:border-destructive/60 aria-invalid:focus:border-destructive aria-invalid:focus:ring-destructive/20"};
|
|
457
835
|
var fieldMessageClassName = "text-xs text-muted-foreground";
|
|
458
836
|
var fieldErrorClassName = "text-xs font-medium text-destructive";
|
|
459
837
|
function getTextareaStyle(size, style) {
|
|
@@ -464,100 +842,99 @@ function getTextareaStyle(size, style) {
|
|
|
464
842
|
"--textarea-padding-y": `${token.paddingY}px`,
|
|
465
843
|
"--textarea-font-size": `${token.fontSize}px`,
|
|
466
844
|
"--textarea-radius": `${token.radius}px`,
|
|
467
|
-
"--textarea-focus-ring-width": `${textareaTokens.focusRingWidth}px`,
|
|
468
|
-
borderRadius: "var(--textarea-radius)",
|
|
469
|
-
outline: "none",
|
|
470
|
-
...style
|
|
471
|
-
};
|
|
472
|
-
}
|
|
473
|
-
function getTextareaFieldStyle() {
|
|
474
|
-
return {
|
|
475
|
-
"--textarea-field-gap": `${textareaTokens.fieldGap}px`,
|
|
476
|
-
"--textarea-label-size": `${textareaTokens.labelSize}px`
|
|
477
|
-
};
|
|
478
|
-
}
|
|
479
|
-
function joinDescriptionIds(...ids) {
|
|
480
|
-
return ids.filter(Boolean).join(" ") || void 0;
|
|
481
|
-
}
|
|
482
|
-
function isInvalid(error, ariaInvalid) {
|
|
483
|
-
return error === true || typeof error === "string" || ariaInvalid === true || ariaInvalid === "true";
|
|
484
|
-
}
|
|
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;
|
|
845
|
+
"--textarea-focus-ring-width": `${textareaTokens.focusRingWidth}px`,
|
|
846
|
+
borderRadius: "var(--textarea-radius)",
|
|
847
|
+
outline: "none",
|
|
848
|
+
...asPlainStyle(style)
|
|
849
|
+
};
|
|
850
|
+
}
|
|
851
|
+
function getTextareaFieldStyle() {
|
|
852
|
+
return {
|
|
853
|
+
"--textarea-field-gap": `${textareaTokens.fieldGap}px`,
|
|
854
|
+
"--textarea-label-size": `${textareaTokens.labelSize}px`
|
|
855
|
+
};
|
|
856
|
+
}
|
|
857
|
+
function joinDescriptionIds(...ids) {
|
|
858
|
+
return ids.filter(Boolean).join(" ") || void 0;
|
|
859
|
+
}
|
|
860
|
+
function isInvalid(error, ariaInvalid) {
|
|
861
|
+
return error === true || typeof error === "string" || ariaInvalid === true || ariaInvalid === "true";
|
|
862
|
+
}
|
|
863
|
+
var Textarea = ({
|
|
864
|
+
className,
|
|
865
|
+
style,
|
|
866
|
+
size = "md",
|
|
867
|
+
label,
|
|
868
|
+
description,
|
|
869
|
+
error,
|
|
870
|
+
fieldClassName,
|
|
871
|
+
id,
|
|
872
|
+
onChange,
|
|
873
|
+
onValueChange,
|
|
874
|
+
"aria-describedby": ariaDescribedBy,
|
|
875
|
+
"aria-invalid": ariaInvalid,
|
|
876
|
+
ref,
|
|
877
|
+
...props
|
|
878
|
+
}) => {
|
|
879
|
+
const baseId = React5.useId();
|
|
880
|
+
const textareaId = id ?? (label || description || typeof error === "string" ? baseId : void 0);
|
|
881
|
+
const resolvedInvalid = isInvalid(error, ariaInvalid);
|
|
882
|
+
const descriptionId = description && textareaId ? `${textareaId}-description` : void 0;
|
|
883
|
+
const errorId = typeof error === "string" && textareaId ? `${textareaId}-error` : void 0;
|
|
884
|
+
const describedBy = joinDescriptionIds(ariaDescribedBy, descriptionId, errorId);
|
|
885
|
+
const handleChange = React5.useCallback(
|
|
886
|
+
(event) => {
|
|
887
|
+
onValueChange?.(event.currentTarget.value);
|
|
888
|
+
onChange?.(event);
|
|
889
|
+
},
|
|
890
|
+
[onChange, onValueChange]
|
|
891
|
+
);
|
|
892
|
+
const control = /* @__PURE__ */ jsx(
|
|
893
|
+
"textarea",
|
|
894
|
+
{
|
|
895
|
+
className: cn(
|
|
896
|
+
"flex min-h-[var(--textarea-min-height)] w-full resize-y rounded-[var(--textarea-radius)] border border-input bg-background",
|
|
897
|
+
"px-[var(--textarea-padding-x)] py-[var(--textarea-padding-y)] text-[length:var(--textarea-font-size)] text-foreground shadow-xs",
|
|
898
|
+
"transition-[background-color,border-color,box-shadow,color] duration-micro ease-out placeholder:text-muted-foreground",
|
|
899
|
+
formControlFocusClassNames.textarea,
|
|
900
|
+
"disabled:cursor-not-allowed disabled:opacity-50 read-only:cursor-default read-only:bg-muted/70",
|
|
901
|
+
formControlInvalidClassNames.textarea,
|
|
902
|
+
className
|
|
903
|
+
),
|
|
904
|
+
ref,
|
|
905
|
+
id: textareaId,
|
|
906
|
+
"aria-invalid": resolvedInvalid || void 0,
|
|
907
|
+
"aria-describedby": describedBy,
|
|
908
|
+
style: getTextareaStyle(size, style),
|
|
909
|
+
onChange: handleChange,
|
|
910
|
+
...props
|
|
537
911
|
}
|
|
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
|
-
);
|
|
912
|
+
);
|
|
913
|
+
if (!label && !description && typeof error !== "string" && !fieldClassName) {
|
|
914
|
+
return control;
|
|
559
915
|
}
|
|
560
|
-
|
|
916
|
+
return /* @__PURE__ */ jsxs(
|
|
917
|
+
"div",
|
|
918
|
+
{
|
|
919
|
+
"data-slot": "textarea-field",
|
|
920
|
+
className: cn("grid gap-[var(--textarea-field-gap)]", fieldClassName),
|
|
921
|
+
style: getTextareaFieldStyle(),
|
|
922
|
+
children: [
|
|
923
|
+
label && /* @__PURE__ */ jsx(
|
|
924
|
+
"label",
|
|
925
|
+
{
|
|
926
|
+
htmlFor: textareaId,
|
|
927
|
+
className: "text-[length:var(--textarea-label-size)] font-medium text-foreground",
|
|
928
|
+
children: label
|
|
929
|
+
}
|
|
930
|
+
),
|
|
931
|
+
control,
|
|
932
|
+
description && !error && /* @__PURE__ */ jsx("p", { id: descriptionId, className: fieldMessageClassName, children: description }),
|
|
933
|
+
typeof error === "string" && /* @__PURE__ */ jsx("p", { id: errorId, role: "alert", className: fieldErrorClassName, children: error })
|
|
934
|
+
]
|
|
935
|
+
}
|
|
936
|
+
);
|
|
937
|
+
};
|
|
561
938
|
Textarea.displayName = "Textarea";
|
|
562
939
|
var DEFAULT_TOOLTIP_DELAY_MS = 150;
|
|
563
940
|
var TooltipProvider = ({
|
|
@@ -574,8 +951,13 @@ var Tooltip = ({
|
|
|
574
951
|
const delay = delayDuration ?? DEFAULT_TOOLTIP_DELAY_MS;
|
|
575
952
|
return /* @__PURE__ */ jsx(Tooltip$1.Provider, { delay, children: /* @__PURE__ */ jsx(Tooltip$1.Root, { ...props, children }) });
|
|
576
953
|
};
|
|
577
|
-
var TooltipTrigger =
|
|
578
|
-
|
|
954
|
+
var TooltipTrigger = ({
|
|
955
|
+
asChild,
|
|
956
|
+
children,
|
|
957
|
+
ref,
|
|
958
|
+
...props
|
|
959
|
+
}) => {
|
|
960
|
+
if (asChild && React5.isValidElement(children)) {
|
|
579
961
|
return /* @__PURE__ */ jsx(
|
|
580
962
|
Tooltip$1.Trigger,
|
|
581
963
|
{
|
|
@@ -586,183 +968,147 @@ var TooltipTrigger = React6.forwardRef(({ asChild, children, ...props }, ref) =>
|
|
|
586
968
|
);
|
|
587
969
|
}
|
|
588
970
|
return /* @__PURE__ */ jsx(Tooltip$1.Trigger, { ref, ...props, children });
|
|
589
|
-
}
|
|
971
|
+
};
|
|
590
972
|
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
|
-
|
|
973
|
+
var TooltipContent = ({
|
|
974
|
+
className,
|
|
975
|
+
style,
|
|
976
|
+
side = "top",
|
|
977
|
+
align = "center",
|
|
978
|
+
sideOffset = 4,
|
|
979
|
+
alignOffset = 0,
|
|
980
|
+
ref,
|
|
981
|
+
...props
|
|
982
|
+
}) => /* @__PURE__ */ jsx(Tooltip$1.Portal, { children: /* @__PURE__ */ jsx(
|
|
983
|
+
Tooltip$1.Positioner,
|
|
984
|
+
{
|
|
985
|
+
side,
|
|
986
|
+
align,
|
|
987
|
+
sideOffset,
|
|
988
|
+
alignOffset,
|
|
989
|
+
style: { zIndex: overlayZIndex.tooltip },
|
|
990
|
+
children: /* @__PURE__ */ jsx(
|
|
991
|
+
Tooltip$1.Popup,
|
|
992
|
+
{
|
|
993
|
+
ref,
|
|
994
|
+
className: cn(overlayClassNames.tooltipSurface, className),
|
|
995
|
+
style: { zIndex: overlayZIndex.tooltip, ...style },
|
|
996
|
+
...props
|
|
997
|
+
}
|
|
998
|
+
)
|
|
999
|
+
}
|
|
1000
|
+
) });
|
|
614
1001
|
TooltipContent.displayName = "TooltipContent";
|
|
615
|
-
var
|
|
1002
|
+
var MAX_VISUALIZER_BARS = 64;
|
|
1003
|
+
var VISUALIZER_BAR_STYLES = Array.from({ length: MAX_VISUALIZER_BARS }, (_, index) => ({
|
|
1004
|
+
id: `voice-bar-${index}`,
|
|
1005
|
+
height: `${15 + index * 37 % 86}%`,
|
|
1006
|
+
animationDelay: `${index * 0.05}s`,
|
|
1007
|
+
animationDuration: `${0.5 + index * 17 % 6 / 10}s`
|
|
1008
|
+
}));
|
|
1009
|
+
var formatRecordingTime = (seconds) => {
|
|
1010
|
+
const mins = Math.floor(seconds / 60);
|
|
1011
|
+
const secs = seconds % 60;
|
|
1012
|
+
return `${mins.toString().padStart(2, "0")}:${secs.toString().padStart(2, "0")}`;
|
|
1013
|
+
};
|
|
616
1014
|
var VoiceRecorder = ({
|
|
617
1015
|
isRecording,
|
|
618
|
-
|
|
619
|
-
onStopRecording,
|
|
1016
|
+
time,
|
|
620
1017
|
visualizerBars = 32
|
|
621
1018
|
}) => {
|
|
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
|
-
};
|
|
1019
|
+
const barStyles = VISUALIZER_BAR_STYLES.slice(
|
|
1020
|
+
0,
|
|
1021
|
+
Math.min(visualizerBars, VISUALIZER_BAR_STYLES.length)
|
|
1022
|
+
);
|
|
645
1023
|
return /* @__PURE__ */ jsxs(
|
|
646
1024
|
"div",
|
|
647
1025
|
{
|
|
648
|
-
className:
|
|
649
|
-
"flex flex-col items-center justify-center w-full transition-
|
|
1026
|
+
className: cn(
|
|
1027
|
+
"flex flex-col items-center justify-center w-full transition-[background-color,border-color,box-shadow,color,opacity,transform] duration-300 py-3",
|
|
650
1028
|
isRecording ? "opacity-100" : "opacity-0 h-0"
|
|
651
1029
|
),
|
|
652
1030
|
children: [
|
|
653
1031
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-3", children: [
|
|
654
1032
|
/* @__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:
|
|
1033
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono text-sm text-white/80", children: formatRecordingTime(time) })
|
|
656
1034
|
] }),
|
|
657
|
-
/* @__PURE__ */ jsx("div", { className: "w-full h-10 flex items-center justify-center gap-0.5 px-4", children:
|
|
1035
|
+
/* @__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
1036
|
"div",
|
|
659
1037
|
{
|
|
660
1038
|
className: "w-0.5 rounded-full bg-white/50 animate-pulse",
|
|
661
1039
|
style: {
|
|
662
|
-
height:
|
|
663
|
-
animationDelay:
|
|
664
|
-
animationDuration:
|
|
1040
|
+
height: bar.height,
|
|
1041
|
+
animationDelay: bar.animationDelay,
|
|
1042
|
+
animationDuration: bar.animationDuration
|
|
665
1043
|
}
|
|
666
1044
|
},
|
|
667
|
-
|
|
1045
|
+
bar.id
|
|
668
1046
|
)) })
|
|
669
1047
|
]
|
|
670
1048
|
}
|
|
671
1049
|
);
|
|
672
1050
|
};
|
|
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
|
-
] }) });
|
|
1051
|
+
VoiceRecorder.displayName = "VoiceRecorder";
|
|
1052
|
+
var noopSetPromptValue = (_value) => {
|
|
697
1053
|
};
|
|
698
|
-
var
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
onSubmit: void 0,
|
|
705
|
-
disabled: false
|
|
706
|
-
});
|
|
1054
|
+
var PromptInputIsLoadingContext = React5__default.createContext(false);
|
|
1055
|
+
var PromptInputValueContext = React5__default.createContext("");
|
|
1056
|
+
var PromptInputSetValueContext = React5__default.createContext(noopSetPromptValue);
|
|
1057
|
+
var PromptInputMaxHeightContext = React5__default.createContext(240);
|
|
1058
|
+
var PromptInputSubmitContext = React5__default.createContext(void 0);
|
|
1059
|
+
var PromptInputDisabledContext = React5__default.createContext(false);
|
|
707
1060
|
function usePromptInput() {
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
1061
|
+
return {
|
|
1062
|
+
isLoading: React5__default.use(PromptInputIsLoadingContext),
|
|
1063
|
+
value: React5__default.use(PromptInputValueContext),
|
|
1064
|
+
setValue: React5__default.use(PromptInputSetValueContext),
|
|
1065
|
+
maxHeight: React5__default.use(PromptInputMaxHeightContext),
|
|
1066
|
+
onSubmit: React5__default.use(PromptInputSubmitContext),
|
|
1067
|
+
disabled: React5__default.use(PromptInputDisabledContext)
|
|
1068
|
+
};
|
|
711
1069
|
}
|
|
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
|
-
);
|
|
1070
|
+
var PromptInput = ({
|
|
1071
|
+
className,
|
|
1072
|
+
isLoading = false,
|
|
1073
|
+
maxHeight = 240,
|
|
1074
|
+
value,
|
|
1075
|
+
onValueChange,
|
|
1076
|
+
onSubmit,
|
|
1077
|
+
children,
|
|
1078
|
+
disabled = false,
|
|
1079
|
+
onDragOver,
|
|
1080
|
+
onDragLeave,
|
|
1081
|
+
onDrop,
|
|
1082
|
+
ref
|
|
1083
|
+
}) => {
|
|
1084
|
+
const [internalValue, setInternalValue] = React5__default.useState(value || "");
|
|
1085
|
+
const handleChange = (newValue) => {
|
|
1086
|
+
setInternalValue(newValue);
|
|
1087
|
+
onValueChange?.(newValue);
|
|
1088
|
+
};
|
|
1089
|
+
const promptValue = value ?? internalValue;
|
|
1090
|
+
const setPromptValue = onValueChange ?? handleChange;
|
|
1091
|
+
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(
|
|
1092
|
+
"div",
|
|
1093
|
+
{
|
|
1094
|
+
ref,
|
|
1095
|
+
className: cn(
|
|
1096
|
+
"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",
|
|
1097
|
+
isLoading && "border-destructive/70",
|
|
1098
|
+
className
|
|
1099
|
+
),
|
|
1100
|
+
onDragOver,
|
|
1101
|
+
onDragLeave,
|
|
1102
|
+
onDrop,
|
|
1103
|
+
children
|
|
1104
|
+
}
|
|
1105
|
+
) }) }) }) }) }) }) });
|
|
1106
|
+
};
|
|
761
1107
|
PromptInput.displayName = "PromptInput";
|
|
762
1108
|
var PromptInputTextarea = ({ className, onKeyDown, disableAutosize = false, placeholder, style, ...props }) => {
|
|
763
1109
|
const { value, setValue, maxHeight, onSubmit, disabled } = usePromptInput();
|
|
764
|
-
const textareaRef =
|
|
765
|
-
|
|
1110
|
+
const textareaRef = React5__default.useRef(null);
|
|
1111
|
+
React5__default.useEffect(() => {
|
|
766
1112
|
if (disableAutosize || !textareaRef.current) return;
|
|
767
1113
|
textareaRef.current.style.height = "auto";
|
|
768
1114
|
textareaRef.current.style.height = typeof maxHeight === "number" ? `${Math.min(textareaRef.current.scrollHeight, maxHeight)}px` : `min(${textareaRef.current.scrollHeight}px, ${maxHeight})`;
|
|
@@ -783,7 +1129,7 @@ var PromptInputTextarea = ({ className, onKeyDown, disableAutosize = false, plac
|
|
|
783
1129
|
onKeyDown: handleKeyDown,
|
|
784
1130
|
rows: 1,
|
|
785
1131
|
style: { "--textarea-min-height": "2rem", ...style },
|
|
786
|
-
className:
|
|
1132
|
+
className: cn("resize-none border-0 shadow-none", className),
|
|
787
1133
|
disabled,
|
|
788
1134
|
placeholder,
|
|
789
1135
|
...props
|
|
@@ -794,7 +1140,7 @@ var PromptInputActions = ({
|
|
|
794
1140
|
children,
|
|
795
1141
|
className,
|
|
796
1142
|
...props
|
|
797
|
-
}) => /* @__PURE__ */ jsx("div", { className:
|
|
1143
|
+
}) => /* @__PURE__ */ jsx("div", { className: cn("flex items-center gap-2", className), ...props, children });
|
|
798
1144
|
var PromptInputAction = ({
|
|
799
1145
|
tooltip,
|
|
800
1146
|
children,
|
|
@@ -817,416 +1163,445 @@ var CustomDivider = () => /* @__PURE__ */ jsx("div", { className: "relative h-6
|
|
|
817
1163
|
}
|
|
818
1164
|
}
|
|
819
1165
|
) });
|
|
820
|
-
var
|
|
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
|
-
|
|
1166
|
+
var promptModeToneClassName = {
|
|
1167
|
+
search: {
|
|
1168
|
+
active: "bg-info/15 border-info text-info",
|
|
1169
|
+
icon: "text-info",
|
|
1170
|
+
label: "text-info"
|
|
1171
|
+
},
|
|
1172
|
+
think: {
|
|
1173
|
+
active: "bg-indigo-500/15 border-indigo-500 text-indigo-500",
|
|
1174
|
+
icon: "text-indigo-500",
|
|
1175
|
+
label: "text-indigo-500"
|
|
1176
|
+
},
|
|
1177
|
+
canvas: {
|
|
1178
|
+
active: "bg-warning/15 border-warning text-warning",
|
|
1179
|
+
icon: "text-warning",
|
|
1180
|
+
label: "text-warning"
|
|
1181
|
+
}
|
|
1182
|
+
};
|
|
1183
|
+
function PromptModeIcon({ tone, active }) {
|
|
1184
|
+
const className = cn("w-4 h-4", active ? promptModeToneClassName[tone].icon : "text-inherit");
|
|
1185
|
+
if (tone === "search") return /* @__PURE__ */ jsx(Globe, { className });
|
|
1186
|
+
if (tone === "think") return /* @__PURE__ */ jsx(Brain, { className });
|
|
1187
|
+
return /* @__PURE__ */ jsx(FolderClosed, { className });
|
|
1188
|
+
}
|
|
1189
|
+
function PromptModeButton({
|
|
1190
|
+
active,
|
|
1191
|
+
label,
|
|
1192
|
+
tone,
|
|
1193
|
+
onClick
|
|
1194
|
+
}) {
|
|
1195
|
+
const toneClassName = promptModeToneClassName[tone];
|
|
1196
|
+
const shouldReduceMotion = useReducedMotion();
|
|
1197
|
+
return /* @__PURE__ */ jsxs(
|
|
1198
|
+
"button",
|
|
1199
|
+
{
|
|
1200
|
+
type: "button",
|
|
1201
|
+
onClick,
|
|
1202
|
+
className: cn(
|
|
1203
|
+
"rounded-full transition-[background-color,border-color,box-shadow,color,opacity,transform] flex items-center gap-1 px-2 py-1 border h-8",
|
|
1204
|
+
active ? toneClassName.active : "bg-transparent border-transparent text-muted-foreground hover:text-foreground"
|
|
1205
|
+
),
|
|
1206
|
+
children: [
|
|
1207
|
+
/* @__PURE__ */ jsx("div", { className: "w-5 h-5 flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsx(
|
|
1208
|
+
m.div,
|
|
1209
|
+
{
|
|
1210
|
+
animate: shouldReduceMotion ? { opacity: active ? 1 : 0.82 } : { rotate: active ? 360 : 0, scale: active ? 1.1 : 1 },
|
|
1211
|
+
whileHover: shouldReduceMotion ? { opacity: 1 } : {
|
|
1212
|
+
rotate: active ? 360 : 15,
|
|
1213
|
+
scale: 1.1,
|
|
1214
|
+
transition: { type: "spring", stiffness: 300, damping: 10 }
|
|
1215
|
+
},
|
|
1216
|
+
transition: shouldReduceMotion ? { duration: 0 } : { type: "spring", stiffness: 260, damping: 25 },
|
|
1217
|
+
children: /* @__PURE__ */ jsx(PromptModeIcon, { tone, active })
|
|
1218
|
+
}
|
|
1219
|
+
) }),
|
|
1220
|
+
/* @__PURE__ */ jsx(AnimatePresence, { children: active && /* @__PURE__ */ jsx(
|
|
1221
|
+
m.span,
|
|
1222
|
+
{
|
|
1223
|
+
initial: shouldReduceMotion ? { opacity: 1 } : { width: 0, opacity: 0 },
|
|
1224
|
+
animate: { width: "auto", opacity: 1 },
|
|
1225
|
+
exit: shouldReduceMotion ? { opacity: 0 } : { width: 0, opacity: 0 },
|
|
1226
|
+
transition: shouldReduceMotion ? { duration: 0 } : { duration: 0.2 },
|
|
1227
|
+
className: cn(
|
|
1228
|
+
"text-xs overflow-hidden whitespace-nowrap flex-shrink-0",
|
|
1229
|
+
toneClassName.label
|
|
1230
|
+
),
|
|
1231
|
+
children: label
|
|
1232
|
+
}
|
|
1233
|
+
) })
|
|
1234
|
+
]
|
|
1235
|
+
}
|
|
1236
|
+
);
|
|
1237
|
+
}
|
|
1238
|
+
function PromptModeActions({
|
|
1239
|
+
uploadInputRef,
|
|
1240
|
+
isRecording,
|
|
1241
|
+
modes,
|
|
1242
|
+
onToggleMode,
|
|
1243
|
+
onToggleCanvas,
|
|
1244
|
+
onProcessFile
|
|
1245
|
+
}) {
|
|
1246
|
+
return /* @__PURE__ */ jsxs(
|
|
1247
|
+
"div",
|
|
1248
|
+
{
|
|
1249
|
+
className: cn(
|
|
1250
|
+
"flex items-center gap-1 transition-opacity duration-300",
|
|
1251
|
+
isRecording ? "opacity-0 invisible h-0" : "opacity-100 visible"
|
|
1252
|
+
),
|
|
1253
|
+
children: [
|
|
1254
|
+
/* @__PURE__ */ jsx(PromptInputAction, { tooltip: "Upload image", children: /* @__PURE__ */ jsx(
|
|
1255
|
+
"button",
|
|
1256
|
+
{
|
|
1257
|
+
type: "button",
|
|
1258
|
+
"aria-label": "Upload image",
|
|
1259
|
+
onClick: () => uploadInputRef.current?.click(),
|
|
1260
|
+
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",
|
|
1261
|
+
disabled: isRecording,
|
|
1262
|
+
children: /* @__PURE__ */ jsx(Paperclip, { className: "h-5 w-5 transition-colors" })
|
|
1263
|
+
}
|
|
1264
|
+
) }),
|
|
1265
|
+
/* @__PURE__ */ jsx(
|
|
1266
|
+
"input",
|
|
1267
|
+
{
|
|
1268
|
+
ref: uploadInputRef,
|
|
1269
|
+
type: "file",
|
|
1270
|
+
className: "hidden",
|
|
1271
|
+
onChange: (event) => {
|
|
1272
|
+
const file = event.target.files?.[0];
|
|
1273
|
+
if (file) onProcessFile(file);
|
|
1274
|
+
if (event.target) event.target.value = "";
|
|
1275
|
+
},
|
|
1276
|
+
accept: "image/*",
|
|
1277
|
+
"aria-label": "Upload image"
|
|
1278
|
+
}
|
|
1279
|
+
),
|
|
1280
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
1281
|
+
/* @__PURE__ */ jsx(
|
|
1282
|
+
PromptModeButton,
|
|
1283
|
+
{
|
|
1284
|
+
active: modes.search,
|
|
1285
|
+
label: "Search",
|
|
1286
|
+
tone: "search",
|
|
1287
|
+
onClick: () => onToggleMode("search")
|
|
1288
|
+
}
|
|
1289
|
+
),
|
|
1290
|
+
/* @__PURE__ */ jsx(CustomDivider, {}),
|
|
1291
|
+
/* @__PURE__ */ jsx(
|
|
1292
|
+
PromptModeButton,
|
|
1293
|
+
{
|
|
1294
|
+
active: modes.think,
|
|
1295
|
+
label: "Think",
|
|
1296
|
+
tone: "think",
|
|
1297
|
+
onClick: () => onToggleMode("think")
|
|
1298
|
+
}
|
|
1299
|
+
),
|
|
1300
|
+
/* @__PURE__ */ jsx(CustomDivider, {}),
|
|
1301
|
+
/* @__PURE__ */ jsx(
|
|
1302
|
+
PromptModeButton,
|
|
1303
|
+
{
|
|
1304
|
+
active: modes.canvas,
|
|
1305
|
+
label: "Canvas",
|
|
1306
|
+
tone: "canvas",
|
|
1307
|
+
onClick: onToggleCanvas
|
|
1308
|
+
}
|
|
1309
|
+
)
|
|
1310
|
+
] })
|
|
1311
|
+
]
|
|
1312
|
+
}
|
|
1313
|
+
);
|
|
1314
|
+
}
|
|
1315
|
+
function PromptSubmitAction({
|
|
1316
|
+
isLoading,
|
|
1317
|
+
isRecording,
|
|
1318
|
+
hasContent,
|
|
1319
|
+
onActivate
|
|
1320
|
+
}) {
|
|
1321
|
+
const shouldReduceMotion = useReducedMotion();
|
|
1322
|
+
return /* @__PURE__ */ jsx(
|
|
1323
|
+
PromptInputAction,
|
|
1324
|
+
{
|
|
1325
|
+
tooltip: isLoading ? "Stop generation" : isRecording ? "Stop recording" : hasContent ? "Send message" : "Voice message",
|
|
1326
|
+
children: /* @__PURE__ */ jsx(
|
|
1327
|
+
Button,
|
|
1328
|
+
{
|
|
1329
|
+
variant: "default",
|
|
1330
|
+
size: "icon",
|
|
1331
|
+
className: cn(
|
|
1332
|
+
"h-8 w-8 rounded-full transition-[background-color,border-color,box-shadow,color,opacity,transform] duration-micro",
|
|
1333
|
+
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"
|
|
1334
|
+
),
|
|
1335
|
+
onClick: onActivate,
|
|
1336
|
+
disabled: isLoading && !hasContent,
|
|
1337
|
+
children: isLoading ? /* @__PURE__ */ jsx(
|
|
1338
|
+
StopFill,
|
|
1339
|
+
{
|
|
1340
|
+
className: cn(
|
|
1341
|
+
"h-4 w-4 fill-primary-foreground",
|
|
1342
|
+
shouldReduceMotion ? "opacity-100" : "animate-pulse"
|
|
1343
|
+
)
|
|
1344
|
+
}
|
|
1345
|
+
) : 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" })
|
|
1346
|
+
}
|
|
1347
|
+
)
|
|
1348
|
+
}
|
|
1349
|
+
);
|
|
1350
|
+
}
|
|
1351
|
+
var promptInputBoxInitialState = {
|
|
1352
|
+
input: "",
|
|
1353
|
+
files: [],
|
|
1354
|
+
filePreviews: {},
|
|
1355
|
+
selectedImage: null,
|
|
1356
|
+
isRecording: false,
|
|
1357
|
+
recordingTime: 0,
|
|
1358
|
+
showSearch: false,
|
|
1359
|
+
showThink: false,
|
|
1360
|
+
showCanvas: false
|
|
1361
|
+
};
|
|
1362
|
+
function promptInputBoxReducer(state, action) {
|
|
1363
|
+
switch (action.type) {
|
|
1364
|
+
case "set-input":
|
|
1365
|
+
return { ...state, input: action.value };
|
|
1366
|
+
case "set-active-file":
|
|
1367
|
+
return { ...state, files: [action.file], filePreviews: {} };
|
|
1368
|
+
case "set-file-preview":
|
|
1369
|
+
return { ...state, filePreviews: { [action.previewKey]: action.preview } };
|
|
1370
|
+
case "remove-file": {
|
|
1371
|
+
const nextPreviews = { ...state.filePreviews };
|
|
1372
|
+
delete nextPreviews[action.previewKey];
|
|
1373
|
+
return {
|
|
1374
|
+
...state,
|
|
1375
|
+
filePreviews: nextPreviews,
|
|
1376
|
+
files: state.files.filter((file) => getFilePreviewKey(file) !== action.previewKey)
|
|
1377
|
+
};
|
|
1378
|
+
}
|
|
1379
|
+
case "set-selected-image":
|
|
1380
|
+
return { ...state, selectedImage: action.imageUrl };
|
|
1381
|
+
case "toggle-mode":
|
|
1382
|
+
if (action.mode === "search") {
|
|
1383
|
+
return { ...state, showSearch: !state.showSearch, showThink: false };
|
|
1384
|
+
}
|
|
1385
|
+
if (action.mode === "think") {
|
|
1386
|
+
return { ...state, showSearch: false, showThink: !state.showThink };
|
|
1387
|
+
}
|
|
1388
|
+
return { ...state, showCanvas: !state.showCanvas };
|
|
1389
|
+
case "start-recording":
|
|
1390
|
+
return { ...state, recordingTime: 0, isRecording: true };
|
|
1391
|
+
case "tick-recording":
|
|
1392
|
+
return { ...state, recordingTime: state.recordingTime + 1 };
|
|
1393
|
+
case "stop-recording":
|
|
1394
|
+
return { ...state, isRecording: false, recordingTime: 0 };
|
|
1395
|
+
case "reset-composer":
|
|
1396
|
+
return { ...state, input: "", files: [], filePreviews: {} };
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
var PromptInputBox = (props) => {
|
|
1400
|
+
const {
|
|
1401
|
+
onSend = () => {
|
|
1402
|
+
},
|
|
1403
|
+
isLoading = false,
|
|
1404
|
+
placeholder = "Type your message here...",
|
|
1405
|
+
className,
|
|
1406
|
+
ref
|
|
1407
|
+
} = props;
|
|
1408
|
+
const [state, dispatch] = React5__default.useReducer(promptInputBoxReducer, promptInputBoxInitialState);
|
|
1409
|
+
const {
|
|
1410
|
+
input,
|
|
1411
|
+
files,
|
|
1412
|
+
filePreviews,
|
|
1413
|
+
selectedImage,
|
|
1414
|
+
isRecording,
|
|
1415
|
+
recordingTime,
|
|
1416
|
+
showSearch,
|
|
1417
|
+
showThink,
|
|
1418
|
+
showCanvas
|
|
1419
|
+
} = state;
|
|
1420
|
+
const uploadInputRef = React5__default.useRef(null);
|
|
1421
|
+
const promptBoxRef = React5__default.useRef(null);
|
|
1422
|
+
const handleToggleChange = (mode) => dispatch({ type: "toggle-mode", mode });
|
|
1423
|
+
const handleCanvasToggle = () => dispatch({ type: "toggle-mode", mode: "canvas" });
|
|
1424
|
+
const processFile = (file) => {
|
|
1425
|
+
if (!isImageFile(file)) {
|
|
1426
|
+
return;
|
|
1427
|
+
}
|
|
1428
|
+
if (file.size > 10 * 1024 * 1024) {
|
|
1429
|
+
return;
|
|
1430
|
+
}
|
|
1431
|
+
const previewKey = getFilePreviewKey(file);
|
|
1432
|
+
dispatch({ type: "set-active-file", file });
|
|
1433
|
+
const reader = new FileReader();
|
|
1434
|
+
reader.onload = (e) => {
|
|
1435
|
+
const preview = e.target?.result;
|
|
1436
|
+
if (typeof preview === "string") {
|
|
1437
|
+
dispatch({ type: "set-file-preview", previewKey, preview });
|
|
846
1438
|
}
|
|
847
1439
|
};
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
1440
|
+
reader.readAsDataURL(file);
|
|
1441
|
+
};
|
|
1442
|
+
const handleDrop = (e) => {
|
|
1443
|
+
preventDragDefaults(e);
|
|
1444
|
+
const droppedFiles = Array.from(e.dataTransfer.files);
|
|
1445
|
+
const firstFile = droppedFiles.find((file) => isImageFile(file));
|
|
1446
|
+
if (firstFile) processFile(firstFile);
|
|
1447
|
+
};
|
|
1448
|
+
const handleRemoveFile = (fileToRemove) => {
|
|
1449
|
+
const previewKey = getFilePreviewKey(fileToRemove);
|
|
1450
|
+
dispatch({ type: "remove-file", previewKey });
|
|
1451
|
+
};
|
|
1452
|
+
const openImageModal = (imageUrl) => dispatch({ type: "set-selected-image", imageUrl });
|
|
1453
|
+
const handlePasteEvent = useEffectEvent((e) => {
|
|
1454
|
+
const items = e.clipboardData?.items;
|
|
1455
|
+
if (!items) return;
|
|
1456
|
+
for (const item of Array.from(items)) {
|
|
1457
|
+
if (item.type.includes("image")) {
|
|
1458
|
+
const file = item.getAsFile();
|
|
1459
|
+
if (file) {
|
|
1460
|
+
e.preventDefault();
|
|
1461
|
+
processFile(file);
|
|
1462
|
+
break;
|
|
857
1463
|
}
|
|
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
1464
|
}
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
const handlePaste =
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
1465
|
+
}
|
|
1466
|
+
});
|
|
1467
|
+
React5__default.useEffect(() => {
|
|
1468
|
+
const handlePaste = (e) => handlePasteEvent(e);
|
|
1469
|
+
document.addEventListener("paste", handlePaste);
|
|
1470
|
+
return () => document.removeEventListener("paste", handlePaste);
|
|
1471
|
+
}, []);
|
|
1472
|
+
React5__default.useEffect(() => {
|
|
1473
|
+
if (!isRecording) return;
|
|
1474
|
+
const timer = window.setInterval(() => dispatch({ type: "tick-recording" }), 1e3);
|
|
1475
|
+
return () => window.clearInterval(timer);
|
|
1476
|
+
}, [isRecording]);
|
|
1477
|
+
const handleSubmit = () => {
|
|
1478
|
+
if (input.trim() || files.length > 0) {
|
|
1479
|
+
let messagePrefix = "";
|
|
1480
|
+
if (showSearch) messagePrefix = "[Search: ";
|
|
1481
|
+
else if (showThink) messagePrefix = "[Think: ";
|
|
1482
|
+
else if (showCanvas) messagePrefix = "[Canvas: ";
|
|
1483
|
+
const formattedInput = messagePrefix ? `${messagePrefix}${input}]` : input;
|
|
1484
|
+
onSend(formattedInput, files);
|
|
1485
|
+
dispatch({ type: "reset-composer" });
|
|
1486
|
+
}
|
|
1487
|
+
};
|
|
1488
|
+
const startRecording = () => dispatch({ type: "start-recording" });
|
|
1489
|
+
const stopRecording = () => {
|
|
1490
|
+
onSend(`[Voice message - ${recordingTime} seconds]`, []);
|
|
1491
|
+
dispatch({ type: "stop-recording" });
|
|
1492
|
+
};
|
|
1493
|
+
const hasContent = input.trim() !== "" || files.length > 0;
|
|
1494
|
+
return /* @__PURE__ */ jsxs(LazyMotion, { features: domAnimation, children: [
|
|
1495
|
+
/* @__PURE__ */ jsxs(
|
|
1496
|
+
PromptInput,
|
|
1497
|
+
{
|
|
1498
|
+
value: input,
|
|
1499
|
+
onValueChange: (value) => dispatch({ type: "set-input", value }),
|
|
1500
|
+
isLoading,
|
|
1501
|
+
onSubmit: handleSubmit,
|
|
1502
|
+
className: cn(
|
|
1503
|
+
"w-full bg-background border-input shadow-lg transition-[background-color,border-color,box-shadow,color,opacity,transform] duration-300 ease-in-out",
|
|
1504
|
+
isRecording && "border-destructive/70",
|
|
1505
|
+
className
|
|
1506
|
+
),
|
|
1507
|
+
disabled: isLoading || isRecording,
|
|
1508
|
+
ref: ref || promptBoxRef,
|
|
1509
|
+
onDragOver: preventDragDefaults,
|
|
1510
|
+
onDragLeave: preventDragDefaults,
|
|
1511
|
+
onDrop: handleDrop,
|
|
1512
|
+
children: [
|
|
1513
|
+
/* @__PURE__ */ jsx(
|
|
1514
|
+
PromptAttachmentPreviews,
|
|
1515
|
+
{
|
|
1516
|
+
files,
|
|
1517
|
+
filePreviews,
|
|
1518
|
+
isRecording,
|
|
1519
|
+
onPreview: openImageModal,
|
|
1520
|
+
onRemove: handleRemoveFile
|
|
1521
|
+
}
|
|
1522
|
+
),
|
|
1523
|
+
/* @__PURE__ */ jsx(
|
|
1524
|
+
"div",
|
|
1525
|
+
{
|
|
1526
|
+
className: cn(
|
|
1527
|
+
"transition-[background-color,border-color,box-shadow,color,opacity,transform] duration-300",
|
|
1528
|
+
isRecording ? "h-0 overflow-hidden opacity-0" : "opacity-100"
|
|
1529
|
+
),
|
|
1530
|
+
children: /* @__PURE__ */ jsx(
|
|
1531
|
+
PromptInputTextarea,
|
|
1532
|
+
{
|
|
1533
|
+
placeholder: showSearch ? "Search the web..." : showThink ? "Think deeply..." : showCanvas ? "Create on canvas..." : placeholder,
|
|
1534
|
+
className: "text-base"
|
|
1535
|
+
}
|
|
1536
|
+
)
|
|
906
1537
|
}
|
|
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
1538
|
),
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
onDragOver: handleDragOver,
|
|
952
|
-
onDragLeave: handleDragLeave,
|
|
953
|
-
onDrop: handleDrop,
|
|
954
|
-
children: [
|
|
955
|
-
files.length > 0 && !isRecording && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2 p-0 pb-1 transition-all duration-300", children: files.map((file, index) => /* @__PURE__ */ jsx("div", { className: "relative group", children: file.type.startsWith("image/") && filePreviews[file.name] && // biome-ignore lint/a11y/useSemanticElements: ARIA pattern
|
|
956
|
-
/* @__PURE__ */ jsxs(
|
|
957
|
-
"div",
|
|
958
|
-
{
|
|
959
|
-
role: "button",
|
|
960
|
-
tabIndex: 0,
|
|
961
|
-
onKeyDown: (e) => {
|
|
962
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
963
|
-
e.preventDefault();
|
|
964
|
-
const preview = filePreviews[file.name];
|
|
965
|
-
if (preview) openImageModal(preview);
|
|
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)) }),
|
|
1539
|
+
isRecording && /* @__PURE__ */ jsx(VoiceRecorder, { isRecording, time: recordingTime }),
|
|
1540
|
+
/* @__PURE__ */ jsxs(PromptInputActions, { className: "flex items-center justify-between gap-2 p-0 pt-2", children: [
|
|
998
1541
|
/* @__PURE__ */ jsx(
|
|
999
|
-
|
|
1542
|
+
PromptModeActions,
|
|
1000
1543
|
{
|
|
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
|
-
)
|
|
1544
|
+
uploadInputRef,
|
|
1545
|
+
isRecording,
|
|
1546
|
+
modes: { search: showSearch, think: showThink, canvas: showCanvas },
|
|
1547
|
+
onToggleMode: handleToggleChange,
|
|
1548
|
+
onToggleCanvas: handleCanvasToggle,
|
|
1549
|
+
onProcessFile: processFile
|
|
1012
1550
|
}
|
|
1013
1551
|
),
|
|
1014
|
-
|
|
1015
|
-
|
|
1552
|
+
/* @__PURE__ */ jsx(
|
|
1553
|
+
PromptSubmitAction,
|
|
1016
1554
|
{
|
|
1555
|
+
isLoading,
|
|
1017
1556
|
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
|
-
)
|
|
1557
|
+
hasContent,
|
|
1558
|
+
onActivate: () => {
|
|
1559
|
+
if (isRecording) stopRecording();
|
|
1560
|
+
else if (hasContent) handleSubmit();
|
|
1561
|
+
else startRecording();
|
|
1207
1562
|
}
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
]
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1563
|
+
}
|
|
1564
|
+
)
|
|
1565
|
+
] })
|
|
1566
|
+
]
|
|
1567
|
+
}
|
|
1568
|
+
),
|
|
1569
|
+
/* @__PURE__ */ jsx(
|
|
1570
|
+
ImageViewDialog,
|
|
1571
|
+
{
|
|
1572
|
+
imageUrl: selectedImage,
|
|
1573
|
+
onClose: () => dispatch({ type: "set-selected-image", imageUrl: null })
|
|
1574
|
+
}
|
|
1575
|
+
)
|
|
1576
|
+
] });
|
|
1577
|
+
};
|
|
1217
1578
|
PromptInputBox.displayName = "PromptInputBox";
|
|
1579
|
+
var emergeTransition = {
|
|
1580
|
+
duration: emerge.transition.duration,
|
|
1581
|
+
ease: [0.16, 1, 0.3, 1]
|
|
1582
|
+
};
|
|
1583
|
+
var flowTransition = {
|
|
1584
|
+
duration: flow.transition.duration,
|
|
1585
|
+
ease: [0, 0, 0.2, 1]
|
|
1586
|
+
};
|
|
1587
|
+
var defaultSpringTransition = {
|
|
1588
|
+
type: "spring",
|
|
1589
|
+
stiffness: brandSpring.default.stiffness,
|
|
1590
|
+
damping: brandSpring.default.damping,
|
|
1591
|
+
mass: brandSpring.default.mass
|
|
1592
|
+
};
|
|
1218
1593
|
var PRESETS = {
|
|
1219
1594
|
emerge: {
|
|
1220
1595
|
initial: emerge.initial,
|
|
1221
1596
|
animate: emerge.animate,
|
|
1222
1597
|
exit: emerge.exit,
|
|
1223
|
-
transition:
|
|
1598
|
+
transition: emergeTransition
|
|
1224
1599
|
},
|
|
1225
1600
|
flow: {
|
|
1226
1601
|
initial: flow.initial,
|
|
1227
1602
|
animate: flow.animate,
|
|
1228
1603
|
exit: flow.exit,
|
|
1229
|
-
transition:
|
|
1604
|
+
transition: flowTransition
|
|
1230
1605
|
},
|
|
1231
1606
|
fade: {
|
|
1232
1607
|
initial: { opacity: 0 },
|
|
@@ -1238,13 +1613,13 @@ var PRESETS = {
|
|
|
1238
1613
|
initial: { opacity: 0, y: 16 },
|
|
1239
1614
|
animate: { opacity: 1, y: 0 },
|
|
1240
1615
|
exit: { opacity: 0, y: 16 },
|
|
1241
|
-
transition:
|
|
1616
|
+
transition: defaultSpringTransition
|
|
1242
1617
|
},
|
|
1243
1618
|
scale: {
|
|
1244
1619
|
initial: { opacity: 0, scale: 0.95 },
|
|
1245
1620
|
animate: { opacity: 1, scale: 1 },
|
|
1246
1621
|
exit: { opacity: 0, scale: 0.95 },
|
|
1247
|
-
transition:
|
|
1622
|
+
transition: defaultSpringTransition
|
|
1248
1623
|
}
|
|
1249
1624
|
};
|
|
1250
1625
|
var STAGGER = { fast: 0.05, normal: 0.1, slow: 0.2 };
|
|
@@ -1254,7 +1629,7 @@ function MotionDiv(props) {
|
|
|
1254
1629
|
function AnimateIn(props) {
|
|
1255
1630
|
const { children, preset = "emerge", delay = 0, duration, inView = false, className } = props;
|
|
1256
1631
|
const shouldReduce = useReducedMotion();
|
|
1257
|
-
const { initial, animate, exit, transition } = PRESETS[preset];
|
|
1632
|
+
const { initial, animate: animate2, exit, transition } = PRESETS[preset];
|
|
1258
1633
|
const t = {
|
|
1259
1634
|
...transition,
|
|
1260
1635
|
...delay ? { delay } : {},
|
|
@@ -1267,7 +1642,7 @@ function AnimateIn(props) {
|
|
|
1267
1642
|
{
|
|
1268
1643
|
className,
|
|
1269
1644
|
initial,
|
|
1270
|
-
whileInView:
|
|
1645
|
+
whileInView: animate2,
|
|
1271
1646
|
exit,
|
|
1272
1647
|
viewport: { once: true, margin: "-10%" },
|
|
1273
1648
|
transition: t,
|
|
@@ -1275,7 +1650,7 @@ function AnimateIn(props) {
|
|
|
1275
1650
|
}
|
|
1276
1651
|
);
|
|
1277
1652
|
}
|
|
1278
|
-
return /* @__PURE__ */ jsx(MotionDiv, { className, initial, animate, exit, transition: t, children });
|
|
1653
|
+
return /* @__PURE__ */ jsx(MotionDiv, { className, initial, animate: animate2, exit, transition: t, children });
|
|
1279
1654
|
}
|
|
1280
1655
|
function AnimateInGroup(props) {
|
|
1281
1656
|
const { children, stagger = "normal", inView = false, className } = props;
|
|
@@ -1313,115 +1688,192 @@ function AsciiText({ text, className = "", font = slant }) {
|
|
|
1313
1688
|
}
|
|
1314
1689
|
);
|
|
1315
1690
|
}
|
|
1691
|
+
function Popover({ ...props }) {
|
|
1692
|
+
return /* @__PURE__ */ jsx(Popover$1.Root, { "data-slot": "popover", ...props });
|
|
1693
|
+
}
|
|
1694
|
+
function PopoverTrigger({ asChild, children, render, ...props }) {
|
|
1695
|
+
const renderElement = asChild && React5.isValidElement(children) ? children : render;
|
|
1696
|
+
return /* @__PURE__ */ jsx(
|
|
1697
|
+
Popover$1.Trigger,
|
|
1698
|
+
{
|
|
1699
|
+
"data-slot": "popover-trigger",
|
|
1700
|
+
render: renderElement,
|
|
1701
|
+
...renderElement ? props : { ...props, children }
|
|
1702
|
+
}
|
|
1703
|
+
);
|
|
1704
|
+
}
|
|
1705
|
+
function PopoverContent({
|
|
1706
|
+
className,
|
|
1707
|
+
align = "center",
|
|
1708
|
+
sideOffset = 8,
|
|
1709
|
+
alignOffset = 0,
|
|
1710
|
+
side = "bottom",
|
|
1711
|
+
children,
|
|
1712
|
+
showArrow = false,
|
|
1713
|
+
style,
|
|
1714
|
+
...props
|
|
1715
|
+
}) {
|
|
1716
|
+
return /* @__PURE__ */ jsx(Popover$1.Portal, { children: /* @__PURE__ */ jsx(
|
|
1717
|
+
Popover$1.Positioner,
|
|
1718
|
+
{
|
|
1719
|
+
"data-slot": "popover-positioner",
|
|
1720
|
+
sideOffset,
|
|
1721
|
+
align,
|
|
1722
|
+
alignOffset,
|
|
1723
|
+
side,
|
|
1724
|
+
children: /* @__PURE__ */ jsxs(
|
|
1725
|
+
Popover$1.Popup,
|
|
1726
|
+
{
|
|
1727
|
+
"data-slot": "popover-content",
|
|
1728
|
+
className: cn(
|
|
1729
|
+
overlayClassNames.popoverSurface,
|
|
1730
|
+
overlayPrimitiveClassNames.popoverSurface,
|
|
1731
|
+
className
|
|
1732
|
+
),
|
|
1733
|
+
style: { zIndex: overlayZIndex.popover, ...style },
|
|
1734
|
+
...props,
|
|
1735
|
+
children: [
|
|
1736
|
+
children,
|
|
1737
|
+
showArrow && /* @__PURE__ */ jsx(PopoverArrow, {})
|
|
1738
|
+
]
|
|
1739
|
+
}
|
|
1740
|
+
)
|
|
1741
|
+
}
|
|
1742
|
+
) });
|
|
1743
|
+
}
|
|
1744
|
+
function PopoverArrow({
|
|
1745
|
+
className,
|
|
1746
|
+
style,
|
|
1747
|
+
...props
|
|
1748
|
+
}) {
|
|
1749
|
+
return /* @__PURE__ */ jsx(
|
|
1750
|
+
Popover$1.Arrow,
|
|
1751
|
+
{
|
|
1752
|
+
"data-slot": "popover-arrow",
|
|
1753
|
+
className: cn(
|
|
1754
|
+
"data-[side=bottom]:top-[-8px] data-[side=left]:right-[-13px] data-[side=left]:rotate-90 data-[side=right]:left-[-13px] data-[side=right]:-rotate-90 data-[side=top]:bottom-[-8px] data-[side=top]:rotate-180",
|
|
1755
|
+
className
|
|
1756
|
+
),
|
|
1757
|
+
style: { zIndex: overlayZIndex.popover, ...style },
|
|
1758
|
+
...props,
|
|
1759
|
+
children: /* @__PURE__ */ jsxs("svg", { "aria-hidden": "true", width: "20", height: "10", viewBox: "0 0 20 10", fill: "none", children: [
|
|
1760
|
+
/* @__PURE__ */ jsx(
|
|
1761
|
+
"path",
|
|
1762
|
+
{
|
|
1763
|
+
d: "M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V9H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z",
|
|
1764
|
+
className: "fill-popover"
|
|
1765
|
+
}
|
|
1766
|
+
),
|
|
1767
|
+
/* @__PURE__ */ jsx(
|
|
1768
|
+
"path",
|
|
1769
|
+
{
|
|
1770
|
+
d: "M10.3333 3.34539L5.47654 7.71648C4.55842 8.54279 3.36693 9 2.13172 9H0V8H2.13172C3.11989 8 4.07308 7.63423 4.80758 6.97318L9.66437 2.60207C10.0447 2.25979 10.622 2.2598 11.0023 2.60207L15.8591 6.97318C16.5936 7.63423 17.5468 8 18.5349 8H20V9H18.5349C17.2998 9 16.1083 8.54278 15.1901 7.71648L10.3333 3.34539Z",
|
|
1771
|
+
className: "fill-border"
|
|
1772
|
+
}
|
|
1773
|
+
)
|
|
1774
|
+
] })
|
|
1775
|
+
}
|
|
1776
|
+
);
|
|
1777
|
+
}
|
|
1316
1778
|
var TAG_COLOR_MAP = {
|
|
1317
|
-
feature: "bg-[var(--
|
|
1779
|
+
feature: "bg-[hsl(var(--primary))] text-white",
|
|
1318
1780
|
fix: "bg-[var(--status-success)] text-white",
|
|
1319
1781
|
breaking: "bg-[var(--status-danger)] text-white",
|
|
1320
1782
|
improvement: "bg-[var(--status-warning)] text-white",
|
|
1321
1783
|
security: "bg-[var(--status-danger)] text-white",
|
|
1322
|
-
experimental: "bg-[var(--neutral-8)] text-
|
|
1784
|
+
experimental: "bg-[var(--neutral-8)] text-foreground"
|
|
1785
|
+
};
|
|
1786
|
+
var getTagColor = (tag) => {
|
|
1787
|
+
if (!tag) return "bg-[var(--neutral-7)] text-foreground";
|
|
1788
|
+
return TAG_COLOR_MAP[tag.toLowerCase()] || TAG_COLOR_MAP.feature;
|
|
1789
|
+
};
|
|
1790
|
+
var getUnreadCount = (entries, lastSeenVersion) => {
|
|
1791
|
+
if (!lastSeenVersion) return entries.length;
|
|
1792
|
+
const lastSeenIndex = entries.findIndex((entry) => entry.version === lastSeenVersion);
|
|
1793
|
+
return lastSeenIndex === -1 ? entries.length : lastSeenIndex;
|
|
1323
1794
|
};
|
|
1324
1795
|
function ChangelogWidget({
|
|
1325
1796
|
entries,
|
|
1326
1797
|
changelogUrl = "/changelog",
|
|
1327
1798
|
className
|
|
1328
1799
|
}) {
|
|
1329
|
-
const [isOpen, setIsOpen] =
|
|
1330
|
-
const [lastSeenVersion, setLastSeenVersion] =
|
|
1331
|
-
const
|
|
1332
|
-
const unreadCount = React6.useMemo(() => {
|
|
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]);
|
|
1800
|
+
const [isOpen, setIsOpen] = React5.useState(false);
|
|
1801
|
+
const [lastSeenVersion, setLastSeenVersion] = React5.useState(null);
|
|
1802
|
+
const unreadCount = getUnreadCount(entries, lastSeenVersion);
|
|
1337
1803
|
const recentEntries = entries.slice(0, 5);
|
|
1338
|
-
const
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
}
|
|
1343
|
-
}, [recentEntries]);
|
|
1344
|
-
React6.useEffect(() => {
|
|
1345
|
-
const handleEscape = (e) => {
|
|
1346
|
-
if (e.key === "Escape") handleClose();
|
|
1347
|
-
};
|
|
1348
|
-
const handleClickOutside = (e) => {
|
|
1349
|
-
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
|
1350
|
-
handleClose();
|
|
1351
|
-
}
|
|
1352
|
-
};
|
|
1353
|
-
if (isOpen) {
|
|
1354
|
-
document.addEventListener("keydown", handleEscape);
|
|
1355
|
-
document.addEventListener("mousedown", handleClickOutside);
|
|
1356
|
-
}
|
|
1357
|
-
return () => {
|
|
1358
|
-
document.removeEventListener("keydown", handleEscape);
|
|
1359
|
-
document.removeEventListener("mousedown", handleClickOutside);
|
|
1360
|
-
};
|
|
1361
|
-
}, [isOpen, handleClose]);
|
|
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;
|
|
1804
|
+
const latestVersion = recentEntries[0]?.version ?? null;
|
|
1805
|
+
const handleOpenChange = (open) => {
|
|
1806
|
+
setIsOpen(open);
|
|
1807
|
+
if (!open && latestVersion) setLastSeenVersion(latestVersion);
|
|
1365
1808
|
};
|
|
1366
|
-
return /* @__PURE__ */ jsxs(
|
|
1809
|
+
return /* @__PURE__ */ jsxs(Popover, { open: isOpen, onOpenChange: handleOpenChange, children: [
|
|
1367
1810
|
/* @__PURE__ */ jsxs(
|
|
1368
|
-
|
|
1811
|
+
PopoverTrigger,
|
|
1369
1812
|
{
|
|
1370
|
-
type: "button",
|
|
1371
1813
|
"aria-label": "View changelog",
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1814
|
+
className: cn(
|
|
1815
|
+
"relative inline-flex items-center justify-center rounded-[var(--radius-lg)] p-2 transition-colors hover:bg-muted",
|
|
1816
|
+
className
|
|
1817
|
+
),
|
|
1375
1818
|
children: [
|
|
1376
|
-
/* @__PURE__ */ jsx(Bell, { className: "h-5 w-5 text-
|
|
1819
|
+
/* @__PURE__ */ jsx(Bell, { className: "h-5 w-5 text-muted-foreground" }),
|
|
1377
1820
|
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
1821
|
]
|
|
1379
1822
|
}
|
|
1380
1823
|
),
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
"
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
{
|
|
1397
|
-
className:
|
|
1398
|
-
"
|
|
1399
|
-
|
|
1400
|
-
),
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1824
|
+
/* @__PURE__ */ jsxs(
|
|
1825
|
+
PopoverContent,
|
|
1826
|
+
{
|
|
1827
|
+
align: "end",
|
|
1828
|
+
side: "bottom",
|
|
1829
|
+
sideOffset: 8,
|
|
1830
|
+
className: "w-80 overflow-hidden rounded-[var(--radius-lg)] border-border bg-white p-0 shadow-lg",
|
|
1831
|
+
children: [
|
|
1832
|
+
/* @__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" }) }),
|
|
1833
|
+
/* @__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(
|
|
1834
|
+
"a",
|
|
1835
|
+
{
|
|
1836
|
+
href: entry.url,
|
|
1837
|
+
className: "block border-b border-border px-4 py-3 transition-colors hover:bg-muted",
|
|
1838
|
+
children: [
|
|
1839
|
+
/* @__PURE__ */ jsx("div", { className: "mb-2 flex items-center justify-between gap-2", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1840
|
+
/* @__PURE__ */ jsxs("span", { className: "font-mono text-xs font-bold text-primary", children: [
|
|
1841
|
+
"v",
|
|
1842
|
+
entry.version
|
|
1843
|
+
] }),
|
|
1844
|
+
entry.tag && /* @__PURE__ */ jsx(
|
|
1845
|
+
"span",
|
|
1846
|
+
{
|
|
1847
|
+
className: cn(
|
|
1848
|
+
"rounded px-2 py-0.5 text-xs font-medium",
|
|
1849
|
+
getTagColor(entry.tag)
|
|
1850
|
+
),
|
|
1851
|
+
children: entry.tag
|
|
1852
|
+
}
|
|
1853
|
+
)
|
|
1854
|
+
] }) }),
|
|
1855
|
+
/* @__PURE__ */ jsx("p", { className: "mb-1 text-sm font-medium text-foreground", children: entry.title }),
|
|
1856
|
+
/* @__PURE__ */ jsx("p", { className: "mb-2 line-clamp-2 text-xs text-muted-foreground", children: entry.excerpt }),
|
|
1857
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: entry.date })
|
|
1858
|
+
]
|
|
1859
|
+
},
|
|
1860
|
+
entry.version
|
|
1861
|
+
)) }),
|
|
1862
|
+
/* @__PURE__ */ jsxs(
|
|
1863
|
+
"a",
|
|
1864
|
+
{
|
|
1865
|
+
href: changelogUrl,
|
|
1866
|
+
onClick: () => handleOpenChange(false),
|
|
1867
|
+
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",
|
|
1868
|
+
children: [
|
|
1869
|
+
/* @__PURE__ */ jsx("span", { children: "View all updates" }),
|
|
1870
|
+
/* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
|
|
1871
|
+
]
|
|
1872
|
+
}
|
|
1873
|
+
)
|
|
1874
|
+
]
|
|
1875
|
+
}
|
|
1876
|
+
)
|
|
1425
1877
|
] });
|
|
1426
1878
|
}
|
|
1427
1879
|
var GRAPH_NODE_FLOW_TYPE = "graph-node";
|
|
@@ -1496,12 +1948,28 @@ var XYFLOW_TOKEN_THEME = {
|
|
|
1496
1948
|
["--xy-controls-button-color"]: "var(--neutral-11)"
|
|
1497
1949
|
};
|
|
1498
1950
|
var nodeCardVariants = cva(
|
|
1499
|
-
"min-w-[160px] rounded-lg border bg-neutral-2 px-3 py-2 text-neutral-12 shadow-sm transition-colors",
|
|
1951
|
+
"min-w-[160px] rounded-[var(--radius-lg)] border bg-neutral-2 px-3 py-2 text-neutral-12 shadow-sm transition-colors",
|
|
1500
1952
|
{
|
|
1501
1953
|
variants: { ready: { true: "border-success", false: "border-neutral-7" } },
|
|
1502
1954
|
defaultVariants: { ready: false }
|
|
1503
1955
|
}
|
|
1504
1956
|
);
|
|
1957
|
+
function GraphNodeCard({ data }) {
|
|
1958
|
+
const view = data.view;
|
|
1959
|
+
return /* @__PURE__ */ jsxs("div", { className: nodeCardVariants({ ready: view.ready ?? false }), children: [
|
|
1960
|
+
/* @__PURE__ */ jsx(Handle, { type: "target", position: Position.Left }),
|
|
1961
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-xs font-medium text-neutral-11 uppercase tracking-wide", children: [
|
|
1962
|
+
view.icon,
|
|
1963
|
+
view.label
|
|
1964
|
+
] }),
|
|
1965
|
+
view.subtitle ? /* @__PURE__ */ jsx("div", { className: "mt-0.5 text-sm text-neutral-12", children: view.subtitle }) : null,
|
|
1966
|
+
/* @__PURE__ */ jsx(Handle, { type: "source", position: Position.Right })
|
|
1967
|
+
] });
|
|
1968
|
+
}
|
|
1969
|
+
var NODE_TYPES = {
|
|
1970
|
+
[GRAPH_NODE_FLOW_TYPE]: GraphNodeCard
|
|
1971
|
+
};
|
|
1972
|
+
var REACT_FLOW_PRO_OPTIONS = { hideAttribution: true };
|
|
1505
1973
|
function NodeGraphCanvas({
|
|
1506
1974
|
graph,
|
|
1507
1975
|
onChange,
|
|
@@ -1513,82 +1981,63 @@ function NodeGraphCanvas({
|
|
|
1513
1981
|
}) {
|
|
1514
1982
|
const statusId = useId();
|
|
1515
1983
|
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;
|
|
1984
|
+
const { nodes: graphNodes, edges } = graphToFlow(graph, edgeIdentity);
|
|
1985
|
+
const nodes = graphNodes.map((node) => ({
|
|
1986
|
+
...node,
|
|
1987
|
+
data: {
|
|
1988
|
+
...node.data,
|
|
1989
|
+
view: renderNode(node.data.node)
|
|
1990
|
+
}
|
|
1991
|
+
}));
|
|
1992
|
+
const onNodesChange = (changes) => {
|
|
1993
|
+
if (readOnly) return;
|
|
1994
|
+
const removed = changes.filter(
|
|
1995
|
+
(c) => c.type === "remove"
|
|
1996
|
+
);
|
|
1997
|
+
if (removed.length > 0) {
|
|
1567
1998
|
let next = graph;
|
|
1568
|
-
for (const r of removed) next =
|
|
1999
|
+
for (const r of removed) next = removeNode(next, r.id);
|
|
1569
2000
|
onChange(next);
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
}
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
2001
|
+
return;
|
|
2002
|
+
}
|
|
2003
|
+
const positional = changes.some((c) => c.type === "position" && c.dragging === false);
|
|
2004
|
+
if (positional) {
|
|
2005
|
+
const moved = nodes.map((n) => {
|
|
2006
|
+
const change = changes.find((c) => c.type === "position" && c.id === n.id);
|
|
2007
|
+
if (change && change.type === "position" && change.position) {
|
|
2008
|
+
return { ...n, position: change.position };
|
|
2009
|
+
}
|
|
2010
|
+
return n;
|
|
2011
|
+
});
|
|
2012
|
+
onChange(applyNodePositions(graph, moved));
|
|
2013
|
+
}
|
|
2014
|
+
};
|
|
2015
|
+
const onEdgesChange = (changes) => {
|
|
2016
|
+
if (readOnly) return;
|
|
2017
|
+
const removed = changes.filter(
|
|
2018
|
+
(c) => c.type === "remove"
|
|
2019
|
+
);
|
|
2020
|
+
if (removed.length === 0) return;
|
|
2021
|
+
let next = graph;
|
|
2022
|
+
for (const r of removed) next = removeFlowEdge(next, r.id, edgeIdentity);
|
|
2023
|
+
onChange(next);
|
|
2024
|
+
};
|
|
2025
|
+
const onConnect = (connection) => {
|
|
2026
|
+
if (readOnly) return;
|
|
2027
|
+
const result = tryAddEdge(graph, connection, { makeEdge, edgeIdentity });
|
|
2028
|
+
if (result.ok) {
|
|
2029
|
+
setRejection(null);
|
|
2030
|
+
onChange(result.graph);
|
|
2031
|
+
} else {
|
|
2032
|
+
setRejection(result.reason);
|
|
2033
|
+
}
|
|
2034
|
+
};
|
|
1586
2035
|
return /* @__PURE__ */ jsx(AnimateIn, { preset: "emerge", children: /* @__PURE__ */ jsx(
|
|
1587
2036
|
"div",
|
|
1588
2037
|
{
|
|
1589
2038
|
style: XYFLOW_TOKEN_THEME,
|
|
1590
2039
|
className: cn(
|
|
1591
|
-
"relative h-[480px] w-full overflow-hidden rounded-xl border border-neutral-7 bg-neutral-1",
|
|
2040
|
+
"relative h-[480px] w-full overflow-hidden rounded-[var(--radius-xl)] border border-neutral-7 bg-neutral-1",
|
|
1592
2041
|
className
|
|
1593
2042
|
),
|
|
1594
2043
|
children: /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsxs(
|
|
@@ -1596,7 +2045,7 @@ function NodeGraphCanvas({
|
|
|
1596
2045
|
{
|
|
1597
2046
|
nodes,
|
|
1598
2047
|
edges,
|
|
1599
|
-
nodeTypes,
|
|
2048
|
+
nodeTypes: NODE_TYPES,
|
|
1600
2049
|
onNodesChange,
|
|
1601
2050
|
onEdgesChange,
|
|
1602
2051
|
onConnect,
|
|
@@ -1604,7 +2053,7 @@ function NodeGraphCanvas({
|
|
|
1604
2053
|
nodesConnectable: !readOnly,
|
|
1605
2054
|
elementsSelectable: !readOnly,
|
|
1606
2055
|
fitView: true,
|
|
1607
|
-
proOptions:
|
|
2056
|
+
proOptions: REACT_FLOW_PRO_OPTIONS,
|
|
1608
2057
|
children: [
|
|
1609
2058
|
/* @__PURE__ */ jsx(Background, { color: "var(--neutral-6)" }),
|
|
1610
2059
|
/* @__PURE__ */ jsx(Controls, { showInteractive: !readOnly }),
|
|
@@ -1614,7 +2063,7 @@ function NodeGraphCanvas({
|
|
|
1614
2063
|
id: statusId,
|
|
1615
2064
|
role: "alert",
|
|
1616
2065
|
"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",
|
|
2066
|
+
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
2067
|
children: [
|
|
1619
2068
|
/* @__PURE__ */ jsx("span", { children: rejection }),
|
|
1620
2069
|
/* @__PURE__ */ jsx(
|
|
@@ -1661,6 +2110,20 @@ var itemVariants = {
|
|
|
1661
2110
|
}
|
|
1662
2111
|
}
|
|
1663
2112
|
};
|
|
2113
|
+
var reducedContainerVariants = {
|
|
2114
|
+
hidden: { opacity: 1 },
|
|
2115
|
+
visible: {
|
|
2116
|
+
opacity: 1,
|
|
2117
|
+
transition: { duration: 0 }
|
|
2118
|
+
}
|
|
2119
|
+
};
|
|
2120
|
+
var reducedItemVariants = {
|
|
2121
|
+
hidden: { opacity: 1 },
|
|
2122
|
+
visible: {
|
|
2123
|
+
opacity: 1,
|
|
2124
|
+
transition: { duration: 0 }
|
|
2125
|
+
}
|
|
2126
|
+
};
|
|
1664
2127
|
function OnboardingChecklist({
|
|
1665
2128
|
title,
|
|
1666
2129
|
description,
|
|
@@ -1669,12 +2132,15 @@ function OnboardingChecklist({
|
|
|
1669
2132
|
videoUrl,
|
|
1670
2133
|
className
|
|
1671
2134
|
}) {
|
|
2135
|
+
const shouldReduceMotion = useReducedMotion();
|
|
2136
|
+
const activeContainerVariants = shouldReduceMotion ? reducedContainerVariants : containerVariants;
|
|
2137
|
+
const activeItemVariants = shouldReduceMotion ? reducedItemVariants : itemVariants;
|
|
1672
2138
|
return /* @__PURE__ */ jsx(
|
|
1673
2139
|
motion.div,
|
|
1674
2140
|
{
|
|
1675
2141
|
initial: "hidden",
|
|
1676
2142
|
animate: "visible",
|
|
1677
|
-
variants:
|
|
2143
|
+
variants: activeContainerVariants,
|
|
1678
2144
|
className: cn(
|
|
1679
2145
|
"w-full max-w-4xl mx-auto bg-card text-card-foreground border rounded-[var(--radius-2xl)] shadow-sm p-8 overflow-hidden",
|
|
1680
2146
|
className
|
|
@@ -1683,7 +2149,7 @@ function OnboardingChecklist({
|
|
|
1683
2149
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
1684
2150
|
/* @__PURE__ */ jsx("h2", { className: "text-2xl font-bold tracking-tight", children: title }),
|
|
1685
2151
|
/* @__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:
|
|
2152
|
+
/* @__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
2153
|
/* @__PURE__ */ jsxs("div", { className: "flex items-start", children: [
|
|
1688
2154
|
/* @__PURE__ */ jsx(CheckCircle, { className: "h-5 w-5 text-green-500 mt-0.5 flex-shrink-0" }),
|
|
1689
2155
|
/* @__PURE__ */ jsx("span", { className: "ml-3 text-sm font-medium", children: item.text })
|
|
@@ -1695,7 +2161,7 @@ function OnboardingChecklist({
|
|
|
1695
2161
|
"a",
|
|
1696
2162
|
{
|
|
1697
2163
|
href: item.helperLink.href,
|
|
1698
|
-
className: "text-primary underline-offset-4 hover:underline
|
|
2164
|
+
className: "text-primary underline-offset-4 hover:underline rounded-[var(--radius-sm)]",
|
|
1699
2165
|
children: item.helperLink.text
|
|
1700
2166
|
}
|
|
1701
2167
|
)
|
|
@@ -1705,25 +2171,26 @@ function OnboardingChecklist({
|
|
|
1705
2171
|
/* @__PURE__ */ jsx(
|
|
1706
2172
|
motion.div,
|
|
1707
2173
|
{
|
|
1708
|
-
variants:
|
|
2174
|
+
variants: activeItemVariants,
|
|
1709
2175
|
className: "relative group rounded-[var(--radius-lg)] overflow-hidden cursor-pointer w-full aspect-video",
|
|
1710
2176
|
children: /* @__PURE__ */ jsxs(Dialog, { children: [
|
|
1711
2177
|
/* @__PURE__ */ jsx(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
1712
2178
|
"button",
|
|
1713
2179
|
{
|
|
1714
2180
|
type: "button",
|
|
1715
|
-
|
|
2181
|
+
"aria-label": "Play the video guide",
|
|
2182
|
+
className: "w-full h-full rounded-[var(--radius-lg)]",
|
|
1716
2183
|
children: [
|
|
1717
2184
|
/* @__PURE__ */ jsx(
|
|
1718
2185
|
Image,
|
|
1719
2186
|
{
|
|
1720
2187
|
src: videoThumbnailUrl,
|
|
1721
2188
|
alt: "Video guide thumbnail",
|
|
1722
|
-
className: "w-full h-full object-cover transition-transform duration-300 group-hover:scale-105",
|
|
2189
|
+
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
2190
|
fill: true
|
|
1724
2191
|
}
|
|
1725
2192
|
),
|
|
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-
|
|
2193
|
+
/* @__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
2194
|
]
|
|
1728
2195
|
}
|
|
1729
2196
|
) }),
|
|
@@ -1817,7 +2284,7 @@ function subscribePlatform() {
|
|
|
1817
2284
|
return () => void 0;
|
|
1818
2285
|
}
|
|
1819
2286
|
function usePlatform() {
|
|
1820
|
-
return
|
|
2287
|
+
return React5.useSyncExternalStore(subscribePlatform, getClientPlatform, () => "apple");
|
|
1821
2288
|
}
|
|
1822
2289
|
function normalizeKey(children) {
|
|
1823
2290
|
if (typeof children !== "string") {
|
|
@@ -1832,54 +2299,63 @@ function normalizeKey(children) {
|
|
|
1832
2299
|
function getModifierSymbols(platform) {
|
|
1833
2300
|
return platform === "apple" ? appleModifierSymbols : otherModifierSymbols;
|
|
1834
2301
|
}
|
|
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
|
-
|
|
2302
|
+
var Kbd = ({
|
|
2303
|
+
meta,
|
|
2304
|
+
shift,
|
|
2305
|
+
alt,
|
|
2306
|
+
ctrl,
|
|
2307
|
+
small,
|
|
2308
|
+
children,
|
|
2309
|
+
className,
|
|
2310
|
+
"aria-label": ariaLabel,
|
|
2311
|
+
ref,
|
|
2312
|
+
...props
|
|
2313
|
+
}) => {
|
|
2314
|
+
const platform = usePlatform();
|
|
2315
|
+
const symbols = getModifierSymbols(platform);
|
|
2316
|
+
const activeModifiers = modifierOrder.filter((modifier) => {
|
|
2317
|
+
if (modifier === "meta") return meta;
|
|
2318
|
+
if (modifier === "shift") return shift;
|
|
2319
|
+
if (modifier === "alt") return alt;
|
|
2320
|
+
return ctrl;
|
|
2321
|
+
});
|
|
2322
|
+
const normalizedKey = normalizeKey(children);
|
|
2323
|
+
const visualParts = [
|
|
2324
|
+
...activeModifiers.map((modifier) => symbols[modifier]),
|
|
2325
|
+
normalizedKey
|
|
2326
|
+
].filter(Boolean);
|
|
2327
|
+
const accessibleName = ariaLabel ?? [
|
|
2328
|
+
...activeModifiers.map((modifier) => modifierLabels[modifier]),
|
|
2329
|
+
typeof normalizedKey === "string" ? normalizedKey : void 0
|
|
2330
|
+
].filter(Boolean).join(" ");
|
|
2331
|
+
return /* @__PURE__ */ jsx(
|
|
2332
|
+
"kbd",
|
|
2333
|
+
{
|
|
2334
|
+
ref,
|
|
2335
|
+
"aria-label": accessibleName || void 0,
|
|
2336
|
+
className: cn(
|
|
2337
|
+
"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",
|
|
2338
|
+
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",
|
|
2339
|
+
className
|
|
2340
|
+
),
|
|
2341
|
+
...props,
|
|
2342
|
+
children: visualParts.join("")
|
|
2343
|
+
}
|
|
2344
|
+
);
|
|
2345
|
+
};
|
|
1870
2346
|
Kbd.displayName = "Kbd";
|
|
1871
2347
|
var inputVariants = cva(
|
|
1872
2348
|
[
|
|
1873
|
-
"flex h-[var(--input-height)] w-full rounded-[var(--input-radius)]
|
|
1874
|
-
"px-[var(--input-padding-x)] text-[length:var(--input-font-size)] text-foreground
|
|
2349
|
+
"flex h-[var(--input-height)] w-full rounded-[var(--input-radius)]",
|
|
2350
|
+
"px-[var(--input-padding-x)] text-[length:var(--input-font-size)] text-foreground",
|
|
1875
2351
|
"transition-[background-color,border-color,box-shadow,color] duration-micro ease-out",
|
|
1876
2352
|
"placeholder:text-muted-foreground",
|
|
1877
|
-
"outline-none
|
|
2353
|
+
"outline-none",
|
|
1878
2354
|
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
1879
2355
|
"read-only:bg-muted/70 read-only:cursor-default",
|
|
1880
2356
|
"file:h-full file:border-0 file:border-e file:border-solid file:border-input file:bg-transparent",
|
|
1881
2357
|
"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
|
-
|
|
2358
|
+
formControlInvalidClassNames.input,
|
|
1883
2359
|
"[&[type=search]::-webkit-search-cancel-button]:appearance-none",
|
|
1884
2360
|
"[&[type=search]::-webkit-search-decoration]:appearance-none",
|
|
1885
2361
|
"[&[type=search]::-webkit-search-results-button]:appearance-none",
|
|
@@ -1897,11 +2373,31 @@ var inputVariants = cva(
|
|
|
1897
2373
|
prefix: "pl-[var(--input-padding-left)]",
|
|
1898
2374
|
suffix: "pr-[var(--input-padding-right)]",
|
|
1899
2375
|
both: "pl-[var(--input-padding-left)] pr-[var(--input-padding-right)]"
|
|
2376
|
+
},
|
|
2377
|
+
/**
|
|
2378
|
+
* `bare` drops the field's own stroke, fill and lift so it can sit inside
|
|
2379
|
+
* a container that already provides them — a footer subscribe group, a
|
|
2380
|
+
* search well, a segmented composer. Those surfaces were each being built
|
|
2381
|
+
* by hand with a raw <input>, because overriding the bordered look from
|
|
2382
|
+
* outside is not reliable: `border-transparent` passed via className and
|
|
2383
|
+
* `border-input` from the base are both border-color utilities, so which
|
|
2384
|
+
* one wins depends on their order in the generated stylesheet rather than
|
|
2385
|
+
* on the order they were written. That is why the stroke, fill and shadow
|
|
2386
|
+
* live in this variant instead of the base — the two tones now never emit
|
|
2387
|
+
* a competing declaration.
|
|
2388
|
+
*
|
|
2389
|
+
* A bare field draws no focus ring of its own. The container owns it, so
|
|
2390
|
+
* the ring surrounds the whole group rather than a box inside it.
|
|
2391
|
+
*/
|
|
2392
|
+
tone: {
|
|
2393
|
+
bordered: `border border-input bg-background shadow-xs ${formControlFocusClassNames.input}`,
|
|
2394
|
+
bare: "border-0 bg-transparent shadow-none"
|
|
1900
2395
|
}
|
|
1901
2396
|
},
|
|
1902
2397
|
defaultVariants: {
|
|
1903
2398
|
size: "md",
|
|
1904
|
-
affix: "none"
|
|
2399
|
+
affix: "none",
|
|
2400
|
+
tone: "bordered"
|
|
1905
2401
|
}
|
|
1906
2402
|
}
|
|
1907
2403
|
);
|
|
@@ -1924,7 +2420,7 @@ var inputControlButtonVariants = cva(
|
|
|
1924
2420
|
"absolute right-[var(--input-control-inset)] top-1/2 flex size-[var(--input-control-size)] -translate-y-1/2 items-center justify-center",
|
|
1925
2421
|
"rounded-[var(--radius-sm)] text-muted-foreground transition-colors duration-micro ease-out",
|
|
1926
2422
|
"hover:bg-accent hover:text-foreground",
|
|
1927
|
-
"focus-visible:outline-none
|
|
2423
|
+
"focus-visible:outline-none",
|
|
1928
2424
|
"disabled:pointer-events-none disabled:opacity-50",
|
|
1929
2425
|
"[&_svg]:size-[var(--input-control-icon-size)]"
|
|
1930
2426
|
].join(" ")
|
|
@@ -1963,7 +2459,7 @@ function getInputStyle(size, style) {
|
|
|
1963
2459
|
"--input-focus-ring-width": `${inputTokens.focusRingWidth}px`,
|
|
1964
2460
|
borderRadius: "var(--input-radius)",
|
|
1965
2461
|
outline: "none",
|
|
1966
|
-
...style
|
|
2462
|
+
...asPlainStyle(style)
|
|
1967
2463
|
};
|
|
1968
2464
|
}
|
|
1969
2465
|
function getAffixMode(prefix, hasRightAdornment) {
|
|
@@ -1981,11 +2477,15 @@ function isTextAffix(value) {
|
|
|
1981
2477
|
function joinDescriptionIds2(...ids) {
|
|
1982
2478
|
return ids.filter(Boolean).join(" ") || void 0;
|
|
1983
2479
|
}
|
|
1984
|
-
var Input =
|
|
2480
|
+
var Input = ({
|
|
2481
|
+
ref: forwardedRef,
|
|
2482
|
+
...props
|
|
2483
|
+
}) => {
|
|
1985
2484
|
const {
|
|
1986
2485
|
className,
|
|
1987
2486
|
type = "text",
|
|
1988
2487
|
size = "md",
|
|
2488
|
+
tone = "bordered",
|
|
1989
2489
|
prefix,
|
|
1990
2490
|
suffix,
|
|
1991
2491
|
clearable,
|
|
@@ -2014,16 +2514,16 @@ var Input = React6.forwardRef((props, forwardedRef) => {
|
|
|
2014
2514
|
...rest
|
|
2015
2515
|
} = props;
|
|
2016
2516
|
const isControlled = value !== void 0;
|
|
2017
|
-
const baseId =
|
|
2018
|
-
const inputRef =
|
|
2517
|
+
const baseId = React5.useId();
|
|
2518
|
+
const inputRef = React5.useRef(null);
|
|
2019
2519
|
const descriptionId = description && id ? `${id}-description` : void 0;
|
|
2020
2520
|
const errorId = typeof error === "string" && id ? `${id}-error` : void 0;
|
|
2021
2521
|
const prefixDescriptionId = isTextAffix(prefix) ? `${id ?? baseId}-prefix` : void 0;
|
|
2022
2522
|
const suffixDescriptionId = isTextAffix(suffix) ? `${id ?? baseId}-suffix` : void 0;
|
|
2023
|
-
const [internalValue, setInternalValue] =
|
|
2523
|
+
const [internalValue, setInternalValue] = React5.useState(
|
|
2024
2524
|
typeof defaultValue === "string" || typeof defaultValue === "number" ? String(defaultValue) : ""
|
|
2025
2525
|
);
|
|
2026
|
-
const [passwordVisible, setPasswordVisible] =
|
|
2526
|
+
const [passwordVisible, setPasswordVisible] = React5.useState(false);
|
|
2027
2527
|
const currentValue = isControlled ? String(value ?? "") : internalValue;
|
|
2028
2528
|
const clearOnEscapeEnabled = clearOnEscape ?? type === "search";
|
|
2029
2529
|
const canRevealPassword = Boolean(revealable && type === "password");
|
|
@@ -2043,7 +2543,7 @@ var Input = React6.forwardRef((props, forwardedRef) => {
|
|
|
2043
2543
|
errorId
|
|
2044
2544
|
);
|
|
2045
2545
|
const valueProps = isControlled ? { value } : clearable || shortcut || clearOnEscapeEnabled ? { value: currentValue } : { defaultValue };
|
|
2046
|
-
const setInputRef =
|
|
2546
|
+
const setInputRef = React5.useCallback(
|
|
2047
2547
|
(node) => {
|
|
2048
2548
|
const input = node instanceof HTMLInputElement ? node : null;
|
|
2049
2549
|
inputRef.current = input;
|
|
@@ -2051,7 +2551,7 @@ var Input = React6.forwardRef((props, forwardedRef) => {
|
|
|
2051
2551
|
},
|
|
2052
2552
|
[forwardedRef]
|
|
2053
2553
|
);
|
|
2054
|
-
const emitNativeInput =
|
|
2554
|
+
const emitNativeInput = React5.useCallback(
|
|
2055
2555
|
(nextValue) => {
|
|
2056
2556
|
const input = inputRef.current;
|
|
2057
2557
|
if (!input) {
|
|
@@ -2068,7 +2568,7 @@ var Input = React6.forwardRef((props, forwardedRef) => {
|
|
|
2068
2568
|
},
|
|
2069
2569
|
[isControlled, onValueChange]
|
|
2070
2570
|
);
|
|
2071
|
-
const syncInputValue =
|
|
2571
|
+
const syncInputValue = React5.useCallback(
|
|
2072
2572
|
(event) => {
|
|
2073
2573
|
if (!isControlled) setInternalValue(event.currentTarget.value);
|
|
2074
2574
|
onValueChange?.(event.currentTarget.value);
|
|
@@ -2076,12 +2576,12 @@ var Input = React6.forwardRef((props, forwardedRef) => {
|
|
|
2076
2576
|
},
|
|
2077
2577
|
[isControlled, onChange, onValueChange]
|
|
2078
2578
|
);
|
|
2079
|
-
const handleClear =
|
|
2579
|
+
const handleClear = React5.useCallback(() => {
|
|
2080
2580
|
emitNativeInput("");
|
|
2081
2581
|
onClear?.();
|
|
2082
2582
|
inputRef.current?.focus();
|
|
2083
2583
|
}, [emitNativeInput, onClear]);
|
|
2084
|
-
const handleKeyDown =
|
|
2584
|
+
const handleKeyDown = React5.useCallback(
|
|
2085
2585
|
(event) => {
|
|
2086
2586
|
onKeyDown?.(event);
|
|
2087
2587
|
if (event.defaultPrevented || event.key !== "Escape" || !clearOnEscapeEnabled || currentValue.length === 0 || disabled) {
|
|
@@ -2105,7 +2605,7 @@ var Input = React6.forwardRef((props, forwardedRef) => {
|
|
|
2105
2605
|
"aria-describedby": describedBy,
|
|
2106
2606
|
"aria-busy": loading || void 0,
|
|
2107
2607
|
className: cn(
|
|
2108
|
-
inputVariants({ size, affix }),
|
|
2608
|
+
inputVariants({ size, affix, tone }),
|
|
2109
2609
|
type === "file" && "p-0 pr-[var(--input-padding-x)] text-muted-foreground",
|
|
2110
2610
|
className
|
|
2111
2611
|
),
|
|
@@ -2210,7 +2710,7 @@ var Input = React6.forwardRef((props, forwardedRef) => {
|
|
|
2210
2710
|
]
|
|
2211
2711
|
}
|
|
2212
2712
|
);
|
|
2213
|
-
}
|
|
2713
|
+
};
|
|
2214
2714
|
Input.displayName = "Input";
|
|
2215
2715
|
function Avatar({ src, alt, isOnline, size = "md" }) {
|
|
2216
2716
|
const sizeClasses = size === "sm" ? "w-10 h-10" : "w-10 h-10";
|
|
@@ -2271,16 +2771,16 @@ function TeamChat({
|
|
|
2271
2771
|
"div",
|
|
2272
2772
|
{
|
|
2273
2773
|
className: cn(
|
|
2274
|
-
"w-full max-w-
|
|
2774
|
+
"w-full max-w-[var(--container-content)] mx-auto p-6 bg-white dark:bg-black rounded-[var(--radius-3xl)] shadow-lg flex flex-col h-[550px] border border-border",
|
|
2275
2775
|
className
|
|
2276
2776
|
),
|
|
2277
2777
|
children: [
|
|
2278
|
-
/* @__PURE__ */ jsxs("header", { className: "flex justify-between items-center border-b border-
|
|
2778
|
+
/* @__PURE__ */ jsxs("header", { className: "flex justify-between items-center border-b border-border pb-3 mb-6", children: [
|
|
2279
2779
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
2280
|
-
/* @__PURE__ */ jsx(Users, { className: "w-8 h-8 text-black
|
|
2780
|
+
/* @__PURE__ */ jsx(Users, { className: "w-8 h-8 text-black" }),
|
|
2281
2781
|
/* @__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-
|
|
2782
|
+
/* @__PURE__ */ jsx("h2", { className: "text-2xl font-semibold text-black", children: chatName }),
|
|
2783
|
+
tagline && /* @__PURE__ */ jsx("p", { className: "italic text-sm text-muted-foreground", children: tagline })
|
|
2284
2784
|
] })
|
|
2285
2785
|
] }),
|
|
2286
2786
|
/* @__PURE__ */ jsx(
|
|
@@ -2289,13 +2789,13 @@ function TeamChat({
|
|
|
2289
2789
|
type: "button",
|
|
2290
2790
|
"aria-label": "More options",
|
|
2291
2791
|
onClick: onMoreOptions,
|
|
2292
|
-
className: "p-2 rounded-[var(--radius-lg)] hover:bg-
|
|
2293
|
-
children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "w-6 h-6 text-
|
|
2792
|
+
className: "p-2 rounded-[var(--radius-lg)] hover:bg-muted transition",
|
|
2793
|
+
children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "w-6 h-6 text-muted-foreground" })
|
|
2294
2794
|
}
|
|
2295
2795
|
)
|
|
2296
2796
|
] }),
|
|
2297
|
-
/* @__PURE__ */ jsxs("main", { className: "flex flex-1 overflow-hidden rounded-[var(--radius-xl)] border border-
|
|
2298
|
-
/* @__PURE__ */ jsx("aside", { className: "w-56 bg-
|
|
2797
|
+
/* @__PURE__ */ jsxs("main", { className: "flex flex-1 overflow-hidden rounded-[var(--radius-xl)] border border-border", children: [
|
|
2798
|
+
/* @__PURE__ */ jsx("aside", { className: "w-56 bg-muted border-r border-border p-4 overflow-y-auto", children: uniqueSenders.map((sender) => {
|
|
2299
2799
|
const isSelected = selectedSender === sender.name;
|
|
2300
2800
|
return /* @__PURE__ */ jsxs(
|
|
2301
2801
|
"button",
|
|
@@ -2304,7 +2804,7 @@ function TeamChat({
|
|
|
2304
2804
|
onClick: () => setSelectedSender(isSelected ? null : sender.name),
|
|
2305
2805
|
className: cn(
|
|
2306
2806
|
"flex items-center gap-3 w-full p-3 mb-3 rounded-[var(--radius-lg)] transition-colors",
|
|
2307
|
-
isSelected ? "bg-black
|
|
2807
|
+
isSelected ? "bg-black text-white dark:text-black" : "hover:bg-muted text-foreground"
|
|
2308
2808
|
),
|
|
2309
2809
|
children: [
|
|
2310
2810
|
/* @__PURE__ */ jsx(Avatar, { src: sender.avatar, alt: sender.name, isOnline: sender.isOnline }),
|
|
@@ -2314,57 +2814,50 @@ function TeamChat({
|
|
|
2314
2814
|
sender.name
|
|
2315
2815
|
);
|
|
2316
2816
|
}) }),
|
|
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
|
-
)) })
|
|
2817
|
+
/* @__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: [
|
|
2818
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 mb-2", children: [
|
|
2819
|
+
/* @__PURE__ */ jsx(Avatar, { src: message.sender.avatar, alt: message.sender.name }),
|
|
2820
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2821
|
+
/* @__PURE__ */ jsx("p", { className: "font-semibold text-black", children: message.sender.name }),
|
|
2822
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: message.timestamp })
|
|
2823
|
+
] })
|
|
2824
|
+
] }),
|
|
2825
|
+
/* @__PURE__ */ jsx("p", { className: "text-foreground text-lg mb-1", children: message.content }),
|
|
2826
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm text-muted-foreground", children: [
|
|
2827
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
2828
|
+
message.status === "read" && /* @__PURE__ */ jsx(DoubleCheck, { className: "w-5 h-5 text-green-500" }),
|
|
2829
|
+
message.status === "delivered" && /* @__PURE__ */ jsx(Check, { className: "w-5 h-5" }),
|
|
2830
|
+
/* @__PURE__ */ jsx("span", { children: message.timestamp })
|
|
2831
|
+
] }),
|
|
2832
|
+
/* @__PURE__ */ jsx("div", { className: "flex gap-2", children: message.reactions?.map((reaction) => /* @__PURE__ */ jsxs(
|
|
2833
|
+
"button",
|
|
2834
|
+
{
|
|
2835
|
+
type: "button",
|
|
2836
|
+
onClick: () => onReactionClick?.(message.id, reaction.emoji),
|
|
2837
|
+
className: cn(
|
|
2838
|
+
"px-2 py-1 rounded-[var(--radius-md)] text-sm transition-colors",
|
|
2839
|
+
reaction.reacted ? "bg-[var(--neutral-5)] text-black" : "bg-muted text-muted-foreground",
|
|
2840
|
+
"hover:bg-muted"
|
|
2841
|
+
),
|
|
2842
|
+
children: [
|
|
2843
|
+
reaction.emoji,
|
|
2844
|
+
" ",
|
|
2845
|
+
reaction.count
|
|
2846
|
+
]
|
|
2847
|
+
},
|
|
2848
|
+
reaction.emoji
|
|
2849
|
+
)) })
|
|
2850
|
+
] })
|
|
2851
|
+
] }, message.id)) })
|
|
2359
2852
|
] }),
|
|
2360
|
-
/* @__PURE__ */ jsxs("footer", { className: "mt-6 flex items-center gap-4 border-t border-
|
|
2853
|
+
/* @__PURE__ */ jsxs("footer", { className: "mt-6 flex items-center gap-4 border-t border-border pt-4", children: [
|
|
2361
2854
|
/* @__PURE__ */ jsx(
|
|
2362
2855
|
"button",
|
|
2363
2856
|
{
|
|
2364
2857
|
type: "button",
|
|
2365
2858
|
"aria-label": "Add emoji",
|
|
2366
|
-
className: "p-3 rounded-full bg-
|
|
2367
|
-
children: /* @__PURE__ */ jsx(FacePlus, { className: "w-6 h-6 text-
|
|
2859
|
+
className: "p-3 rounded-full bg-muted hover:bg-muted transition",
|
|
2860
|
+
children: /* @__PURE__ */ jsx(FacePlus, { className: "w-6 h-6 text-muted-foreground" })
|
|
2368
2861
|
}
|
|
2369
2862
|
),
|
|
2370
2863
|
/* @__PURE__ */ jsx(
|
|
@@ -2383,7 +2876,7 @@ function TeamChat({
|
|
|
2383
2876
|
type: "button",
|
|
2384
2877
|
"aria-label": "Send message",
|
|
2385
2878
|
onClick: handleSend,
|
|
2386
|
-
className: "p-3 rounded-full bg-black
|
|
2879
|
+
className: "p-3 rounded-full bg-black text-white dark:text-black hover:brightness-90 transition",
|
|
2387
2880
|
children: /* @__PURE__ */ jsx(PaperAirplane, { className: "w-6 h-6" })
|
|
2388
2881
|
}
|
|
2389
2882
|
)
|
|
@@ -2393,6 +2886,6 @@ function TeamChat({
|
|
|
2393
2886
|
);
|
|
2394
2887
|
}
|
|
2395
2888
|
|
|
2396
|
-
export { AnimateIn, AnimateInGroup, AsciiText, ChangelogWidget, NodeGraphCanvas, OnboardingChecklist, PromptInputBox, TeamChat };
|
|
2889
|
+
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
2890
|
//# sourceMappingURL=index.js.map
|
|
2398
2891
|
//# sourceMappingURL=index.js.map
|