@nebutra/ui 0.2.3 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/animate-in-BlvjVh2S.d.ts +250 -0
- package/dist/{canonical-Drca5UMj.d.ts → canonical-DEhT4VfS.d.ts} +83 -369
- package/dist/card-DunB1gKE.d.ts +105 -0
- package/dist/chat/index.d.ts +1 -0
- package/dist/chat/index.js +3 -0
- package/dist/chat/index.js.map +1 -0
- package/dist/components/index.d.ts +90 -126
- package/dist/components/index.js +433 -182
- package/dist/components/index.js.map +1 -1
- package/dist/editorial/index.d.ts +404 -0
- package/dist/editorial/index.js +942 -0
- package/dist/editorial/index.js.map +1 -0
- package/dist/empty-state-bmfHCOuN.d.ts +86 -0
- package/dist/hooks/index.d.ts +18 -1
- package/dist/hooks/index.js +120 -5
- package/dist/hooks/index.js.map +1 -1
- package/dist/icons/index.d.ts +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/layout/index.d.ts +17 -58
- package/dist/layout/index.js +368 -127
- package/dist/layout/index.js.map +1 -1
- package/dist/layouts/index.d.ts +1 -1
- package/dist/layouts/index.js +93 -28
- package/dist/layouts/index.js.map +1 -1
- package/dist/patterns/index.d.ts +39 -46
- package/dist/patterns/index.js +534 -323
- package/dist/patterns/index.js.map +1 -1
- package/dist/primitives/canonical.d.ts +5 -2
- package/dist/primitives/canonical.js +598 -288
- package/dist/primitives/canonical.js.map +1 -1
- package/dist/primitives/index.d.ts +165 -63
- package/dist/primitives/index.js +1251 -983
- package/dist/primitives/index.js.map +1 -1
- package/dist/tailwind.preset.d.ts +32 -32
- package/dist/tailwind.preset.js +24 -20
- package/dist/tailwind.preset.js.map +1 -1
- package/dist/theme/index.d.ts +1 -110
- package/dist/typography/fonts.css +8 -16
- package/dist/typography/index.d.ts +29 -45
- package/dist/typography/index.js +26 -14
- package/dist/typography/index.js.map +1 -1
- package/dist/utils/auth-surfaces.d.ts +33 -0
- package/dist/utils/auth-surfaces.js +9 -0
- package/dist/utils/auth-surfaces.js.map +1 -0
- package/dist/utils/index.d.ts +20 -16
- package/dist/utils/index.js +99 -20
- package/dist/utils/index.js.map +1 -1
- package/package.json +25 -11
- package/src/typography/fonts.css +8 -16
- package/dist/styles/brand-override.css +0 -61
- package/src/styles/brand-override.css +0 -61
package/dist/patterns/index.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { clsx } from 'clsx';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
3
|
+
import { extendTailwindMerge } from 'tailwind-merge';
|
|
4
|
+
import { jsxs, jsx, Fragment as Fragment$1 } from 'react/jsx-runtime';
|
|
5
|
+
import { cva } from 'class-variance-authority';
|
|
6
|
+
import * as React10 from 'react';
|
|
6
7
|
import { useState, useRef, useCallback, useMemo, Fragment, isValidElement } from 'react';
|
|
7
8
|
import { Check, Copy, Pencil, FileText, TextBold, TextItalic, Code, Hash, ListUnordered, Link, Image, ChevronUp, ChevronDown, Calendar, Eye, Bookmark, StarFill, Share, Flag, ChevronUpDown, Pin, ChevronRight, MoreHorizontal } from '@nebutra/icons';
|
|
8
|
-
import { cva } from 'class-variance-authority';
|
|
9
9
|
import { Menu } from '@base-ui/react/menu';
|
|
10
10
|
import { colors } from '@nebutra/brand';
|
|
11
|
+
import { tokenColor, fontStack } from '@nebutra/tokens/values';
|
|
11
12
|
import { Tabs as Tabs$1 } from '@base-ui/react/tabs';
|
|
12
13
|
import { Tooltip as Tooltip$1 } from '@base-ui/react/tooltip';
|
|
13
14
|
import ReactMarkdown from 'react-markdown';
|
|
@@ -17,6 +18,80 @@ import { Avatar as Avatar$1 } from '@base-ui/react/avatar';
|
|
|
17
18
|
import { useReducedMotion, AnimatePresence, motion } from 'framer-motion';
|
|
18
19
|
|
|
19
20
|
// src/utils/cn.ts
|
|
21
|
+
|
|
22
|
+
// src/utils/tw-merge-theme.generated.ts
|
|
23
|
+
var TW_MERGE_THEME = {
|
|
24
|
+
breakpoint: ["3xl", "shell", "tight", "xs"],
|
|
25
|
+
container: ["content", "text", "wide"],
|
|
26
|
+
ease: ["brand", "in", "in-out", "out", "spring"],
|
|
27
|
+
font: ["cn", "display", "heading", "mono", "sans"],
|
|
28
|
+
leading: ["display", "heading"],
|
|
29
|
+
radius: ["2xl", "3xl", "button", "card", "full", "lg", "md", "none", "panel", "sm", "xl", "xs"],
|
|
30
|
+
shadow: [
|
|
31
|
+
"2xl",
|
|
32
|
+
"ambient-glow",
|
|
33
|
+
"ambient-lg",
|
|
34
|
+
"ambient-md",
|
|
35
|
+
"ambient-sm",
|
|
36
|
+
"brand",
|
|
37
|
+
"brand-lg",
|
|
38
|
+
"glass-lg",
|
|
39
|
+
"glass-md",
|
|
40
|
+
"glass-sm",
|
|
41
|
+
"glow-accent",
|
|
42
|
+
"glow-accent-lg",
|
|
43
|
+
"glow-accent-sm",
|
|
44
|
+
"glow-primary",
|
|
45
|
+
"lg",
|
|
46
|
+
"md",
|
|
47
|
+
"sheen",
|
|
48
|
+
"sm",
|
|
49
|
+
"xl",
|
|
50
|
+
"xs"
|
|
51
|
+
],
|
|
52
|
+
text: [
|
|
53
|
+
"2xl",
|
|
54
|
+
"2xs",
|
|
55
|
+
"3xl",
|
|
56
|
+
"4xl",
|
|
57
|
+
"5xl",
|
|
58
|
+
"6xl",
|
|
59
|
+
"7xl",
|
|
60
|
+
"8xl",
|
|
61
|
+
"9xl",
|
|
62
|
+
"base",
|
|
63
|
+
"body",
|
|
64
|
+
"display",
|
|
65
|
+
"label",
|
|
66
|
+
"lg",
|
|
67
|
+
"meta",
|
|
68
|
+
"sm",
|
|
69
|
+
"ui",
|
|
70
|
+
"xl",
|
|
71
|
+
"xs"
|
|
72
|
+
],
|
|
73
|
+
tracking: ["display", "heading", "label", "tight"]
|
|
74
|
+
};
|
|
75
|
+
var TW_MERGE_CLASS_GROUPS = {
|
|
76
|
+
duration: [{ duration: ["cinematic", "flow", "micro", "reveal"] }]
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// src/utils/cn.ts
|
|
80
|
+
var twMerge = extendTailwindMerge({
|
|
81
|
+
extend: {
|
|
82
|
+
theme: Object.fromEntries(
|
|
83
|
+
Object.entries(TW_MERGE_THEME).map(([key, values]) => [key, [...values]])
|
|
84
|
+
),
|
|
85
|
+
classGroups: Object.fromEntries(
|
|
86
|
+
Object.entries(TW_MERGE_CLASS_GROUPS).map(([key, groups]) => [
|
|
87
|
+
key,
|
|
88
|
+
groups.map(
|
|
89
|
+
(group) => Object.fromEntries(Object.entries(group).map(([k, v]) => [k, [...v]]))
|
|
90
|
+
)
|
|
91
|
+
])
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
});
|
|
20
95
|
function cn(...inputs) {
|
|
21
96
|
return twMerge(clsx(inputs));
|
|
22
97
|
}
|
|
@@ -129,108 +204,120 @@ function ArtifactShiftCardFooter({ className, ...props }) {
|
|
|
129
204
|
}
|
|
130
205
|
);
|
|
131
206
|
}
|
|
132
|
-
var
|
|
133
|
-
var
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
ref,
|
|
152
|
-
className: cn(
|
|
153
|
-
"rounded-[var(--radius-xl)] transition-[background-color,border-color,box-shadow,color] duration-micro",
|
|
154
|
-
variantStyles[variant],
|
|
155
|
-
paddingMap[padding],
|
|
156
|
-
className
|
|
157
|
-
),
|
|
158
|
-
...props,
|
|
159
|
-
children
|
|
207
|
+
var cardVariants = cva(
|
|
208
|
+
"rounded-[var(--radius-card,var(--radius-lg))] text-card-foreground transition-[box-shadow,background-color] duration-micro",
|
|
209
|
+
{
|
|
210
|
+
variants: {
|
|
211
|
+
variant: {
|
|
212
|
+
default: "bg-card shadow-[var(--elevation-card)] ring-1 ring-[var(--edge-soft)]",
|
|
213
|
+
elevated: "bg-card shadow-ambient-md ring-1 ring-[var(--edge-soft)]",
|
|
214
|
+
outline: "bg-transparent ring-1 ring-border",
|
|
215
|
+
ghost: "bg-transparent"
|
|
216
|
+
},
|
|
217
|
+
padding: {
|
|
218
|
+
none: "",
|
|
219
|
+
sm: "p-4",
|
|
220
|
+
md: "p-6",
|
|
221
|
+
lg: "p-8"
|
|
222
|
+
},
|
|
223
|
+
interactive: {
|
|
224
|
+
true: "cursor-pointer hover:shadow-ambient-md",
|
|
225
|
+
false: ""
|
|
160
226
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
);
|
|
164
|
-
CardRoot.displayName = "Card";
|
|
165
|
-
var CardHeader = React.forwardRef(
|
|
166
|
-
({ className, spacing: gap = "md", children, ...props }, ref) => {
|
|
167
|
-
const gapMap = { sm: "gap-2", md: "gap-3", lg: "gap-4" };
|
|
168
|
-
return /* @__PURE__ */ jsx("div", { ref, className: cn("flex items-start", gapMap[gap], className), ...props, children });
|
|
169
|
-
}
|
|
170
|
-
);
|
|
171
|
-
CardHeader.displayName = "Card.Header";
|
|
172
|
-
var CardBody = React.forwardRef(
|
|
173
|
-
({ className, children, ...props }, ref) => {
|
|
174
|
-
return /* @__PURE__ */ jsx("div", { ref, className: cn("mt-4", className), ...props, children });
|
|
175
|
-
}
|
|
176
|
-
);
|
|
177
|
-
CardBody.displayName = "Card.Body";
|
|
178
|
-
var CardFooter = React.forwardRef(
|
|
179
|
-
({ className, children, ...props }, ref) => {
|
|
180
|
-
return /* @__PURE__ */ jsx("div", { ref, className: cn("mt-6 pt-4 border-t border-border/50", className), ...props, children });
|
|
227
|
+
},
|
|
228
|
+
defaultVariants: { variant: "default", padding: "none", interactive: false }
|
|
181
229
|
}
|
|
182
230
|
);
|
|
183
|
-
|
|
184
|
-
var
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
sizeMap[size],
|
|
198
|
-
className
|
|
199
|
-
),
|
|
200
|
-
...props,
|
|
201
|
-
children
|
|
202
|
-
}
|
|
203
|
-
);
|
|
231
|
+
var CardPaddedContext = React10.createContext(false);
|
|
232
|
+
var CardRoot = ({
|
|
233
|
+
className,
|
|
234
|
+
variant,
|
|
235
|
+
padding = "none",
|
|
236
|
+
interactive,
|
|
237
|
+
ref,
|
|
238
|
+
...props
|
|
239
|
+
}) => /* @__PURE__ */ jsx(CardPaddedContext.Provider, { value: padding !== "none", children: /* @__PURE__ */ jsx(
|
|
240
|
+
"div",
|
|
241
|
+
{
|
|
242
|
+
ref,
|
|
243
|
+
className: cn(cardVariants({ variant, padding, interactive }), className),
|
|
244
|
+
...props
|
|
204
245
|
}
|
|
205
|
-
);
|
|
206
|
-
|
|
207
|
-
var
|
|
208
|
-
|
|
209
|
-
|
|
246
|
+
) });
|
|
247
|
+
CardRoot.displayName = "Card";
|
|
248
|
+
var CardHeader = ({ className, ref, ...props }) => {
|
|
249
|
+
const padded = React10.use(CardPaddedContext);
|
|
250
|
+
return /* @__PURE__ */ jsx(
|
|
251
|
+
"div",
|
|
252
|
+
{
|
|
253
|
+
ref,
|
|
254
|
+
className: cn("flex flex-col gap-1.5", !padded && "p-6", className),
|
|
255
|
+
...props
|
|
256
|
+
}
|
|
257
|
+
);
|
|
258
|
+
};
|
|
259
|
+
CardHeader.displayName = "CardHeader";
|
|
260
|
+
var CardTitle = ({ className, as: Tag = "h3", ref, ...props }) => /* @__PURE__ */ jsx(
|
|
261
|
+
Tag,
|
|
262
|
+
{
|
|
263
|
+
ref,
|
|
264
|
+
className: cn("text-lg font-semibold leading-tight tracking-tight text-foreground", className),
|
|
265
|
+
...props
|
|
210
266
|
}
|
|
211
267
|
);
|
|
212
|
-
CardTitle.displayName = "
|
|
213
|
-
var CardDescription =
|
|
214
|
-
|
|
215
|
-
|
|
268
|
+
CardTitle.displayName = "CardTitle";
|
|
269
|
+
var CardDescription = ({ className, as: Tag = "p", ref, ...props }) => React10.createElement(Tag, {
|
|
270
|
+
ref,
|
|
271
|
+
className: cn("text-sm leading-relaxed text-muted-foreground", className),
|
|
272
|
+
...props
|
|
273
|
+
});
|
|
274
|
+
CardDescription.displayName = "CardDescription";
|
|
275
|
+
var CardContent = ({ className, ref, ...props }) => {
|
|
276
|
+
const padded = React10.use(CardPaddedContext);
|
|
277
|
+
return /* @__PURE__ */ jsx("div", { ref, className: cn(padded ? "mt-4 first:mt-0" : "p-6 pt-0", className), ...props });
|
|
278
|
+
};
|
|
279
|
+
CardContent.displayName = "CardContent";
|
|
280
|
+
var CardFooter = ({ className, ref, ...props }) => {
|
|
281
|
+
const padded = React10.use(CardPaddedContext);
|
|
282
|
+
return /* @__PURE__ */ jsx(
|
|
283
|
+
"div",
|
|
216
284
|
{
|
|
217
285
|
ref,
|
|
218
|
-
className: cn(
|
|
286
|
+
className: cn(
|
|
287
|
+
"flex items-center",
|
|
288
|
+
padded ? "mt-6 border-t border-border/50 pt-4 first:mt-0" : "p-6 pt-0",
|
|
289
|
+
className
|
|
290
|
+
),
|
|
219
291
|
...props
|
|
220
|
-
}
|
|
221
|
-
children
|
|
292
|
+
}
|
|
222
293
|
);
|
|
223
|
-
}
|
|
224
|
-
|
|
294
|
+
};
|
|
295
|
+
CardFooter.displayName = "CardFooter";
|
|
296
|
+
var iconSize = { sm: "size-8", md: "size-10", lg: "size-12" };
|
|
297
|
+
var CardIcon = ({ className, size = "md", ref, ...props }) => /* @__PURE__ */ jsx(
|
|
298
|
+
"div",
|
|
299
|
+
{
|
|
300
|
+
ref,
|
|
301
|
+
className: cn(
|
|
302
|
+
"flex shrink-0 items-center justify-center rounded-[var(--radius-lg)] bg-muted/50",
|
|
303
|
+
iconSize[size],
|
|
304
|
+
className
|
|
305
|
+
),
|
|
306
|
+
...props
|
|
307
|
+
}
|
|
308
|
+
);
|
|
309
|
+
CardIcon.displayName = "CardIcon";
|
|
225
310
|
var Card = Object.assign(CardRoot, {
|
|
226
311
|
Header: CardHeader,
|
|
227
|
-
Body: CardBody,
|
|
228
|
-
Footer: CardFooter,
|
|
229
|
-
Icon: CardIcon,
|
|
230
312
|
Title: CardTitle,
|
|
231
|
-
Description: CardDescription
|
|
313
|
+
Description: CardDescription,
|
|
314
|
+
Content: CardContent,
|
|
315
|
+
Body: CardContent,
|
|
316
|
+
Footer: CardFooter,
|
|
317
|
+
Icon: CardIcon
|
|
232
318
|
});
|
|
233
|
-
var
|
|
319
|
+
var CardBody = CardContent;
|
|
320
|
+
var CommandBox = React10.forwardRef(
|
|
234
321
|
({
|
|
235
322
|
className,
|
|
236
323
|
command,
|
|
@@ -240,8 +327,8 @@ var CommandBox = React.forwardRef(
|
|
|
240
327
|
onCopy,
|
|
241
328
|
...props
|
|
242
329
|
}, ref) => {
|
|
243
|
-
const [copied, setCopied] =
|
|
244
|
-
const handleCopy =
|
|
330
|
+
const [copied, setCopied] = React10.useState(false);
|
|
331
|
+
const handleCopy = React10.useCallback(async () => {
|
|
245
332
|
try {
|
|
246
333
|
await navigator.clipboard.writeText(command);
|
|
247
334
|
setCopied(true);
|
|
@@ -253,7 +340,7 @@ var CommandBox = React.forwardRef(
|
|
|
253
340
|
}
|
|
254
341
|
}
|
|
255
342
|
}, [command, onCopy]);
|
|
256
|
-
const
|
|
343
|
+
const variantStyles2 = {
|
|
257
344
|
default: "bg-muted border border-border rounded-[var(--radius-lg)]",
|
|
258
345
|
minimal: "bg-background border border-border rounded-[var(--radius-md)]",
|
|
259
346
|
pill: "bg-muted border border-border rounded-full"
|
|
@@ -266,7 +353,7 @@ var CommandBox = React.forwardRef(
|
|
|
266
353
|
ref,
|
|
267
354
|
className: cn(
|
|
268
355
|
"group relative flex items-center gap-3 px-4 py-2.5 font-mono text-sm cursor-pointer transition-colors hover:bg-muted",
|
|
269
|
-
|
|
356
|
+
variantStyles2[variant],
|
|
270
357
|
className
|
|
271
358
|
),
|
|
272
359
|
onClick: handleCopy,
|
|
@@ -281,14 +368,14 @@ var CommandBox = React.forwardRef(
|
|
|
281
368
|
"aria-label": `Copy command: ${command}`,
|
|
282
369
|
...props,
|
|
283
370
|
children: [
|
|
284
|
-
/* @__PURE__ */ jsx("span", { className: "text-
|
|
371
|
+
/* @__PURE__ */ jsx("span", { className: "text-success-strong shrink-0 select-none", children: prefix }),
|
|
285
372
|
/* @__PURE__ */ jsx("span", { className: "flex-1 text-muted-foreground truncate", children: command }),
|
|
286
373
|
showCopyButton && /* @__PURE__ */ jsx(
|
|
287
374
|
"span",
|
|
288
375
|
{
|
|
289
376
|
className: cn(
|
|
290
377
|
"shrink-0 text-xs transition-colors",
|
|
291
|
-
copied ? "text-
|
|
378
|
+
copied ? "text-success-strong" : "text-muted-foreground group-hover:text-muted-foreground"
|
|
292
379
|
),
|
|
293
380
|
children: copied ? /* @__PURE__ */ jsx(CopiedIcon, { className: "w-4 h-4" }) : /* @__PURE__ */ jsx(CopyIcon, { className: "w-4 h-4" })
|
|
294
381
|
}
|
|
@@ -297,7 +384,7 @@ var CommandBox = React.forwardRef(
|
|
|
297
384
|
"span",
|
|
298
385
|
{
|
|
299
386
|
className: cn(
|
|
300
|
-
"absolute -top-8 left-1/2 -translate-x-1/2 px-2 py-1 text-xs rounded bg-
|
|
387
|
+
"absolute -top-8 left-1/2 -translate-x-1/2 px-2 py-1 text-xs rounded bg-popover text-popover-foreground opacity-0 transition-opacity pointer-events-none",
|
|
301
388
|
"group-hover:opacity-100",
|
|
302
389
|
copied && "opacity-100"
|
|
303
390
|
),
|
|
@@ -351,8 +438,8 @@ function CopiedIcon({ className }) {
|
|
|
351
438
|
var metricToneClasses = {
|
|
352
439
|
neutral: "bg-muted/70 text-muted-foreground ring-border",
|
|
353
440
|
blue: "bg-info/10 text-info ring-info/20",
|
|
354
|
-
green: "bg-success/10 text-success ring-success/20",
|
|
355
|
-
amber: "bg-warning/10 text-warning ring-warning/20"
|
|
441
|
+
green: "bg-success/10 text-success-strong ring-success/20",
|
|
442
|
+
amber: "bg-warning/10 text-warning-strong ring-warning/20"
|
|
356
443
|
};
|
|
357
444
|
function DashboardCommandSurface({
|
|
358
445
|
status,
|
|
@@ -367,25 +454,27 @@ function DashboardCommandSurface({
|
|
|
367
454
|
{
|
|
368
455
|
"data-pattern": "nebutra-dashboard-command",
|
|
369
456
|
className: cn(
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
457
|
+
// Same surface rails as Card: --radius-card, --edge-soft hairline and
|
|
458
|
+
// --elevation-card, so a Brand Package retargets a command header and a
|
|
459
|
+
// card together. The gradient hairline + radial wash that used to sit
|
|
460
|
+
// here were decoration no language could retarget.
|
|
461
|
+
"rounded-[var(--radius-card)] bg-card p-4 text-card-foreground shadow-[0_0_0_1px_var(--edge-soft),var(--elevation-card)]",
|
|
373
462
|
"sm:p-5",
|
|
374
463
|
className
|
|
375
464
|
),
|
|
376
465
|
children: [
|
|
377
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
466
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between", children: [
|
|
378
467
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
379
468
|
status ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
380
|
-
/* @__PURE__ */ jsx("span", { className: "size-1.5 rounded-full bg-success
|
|
381
|
-
/* @__PURE__ */ jsx("p", { className: "text-
|
|
469
|
+
/* @__PURE__ */ jsx("span", { className: "size-1.5 rounded-full bg-success" }),
|
|
470
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium uppercase tracking-label text-muted-foreground", children: status })
|
|
382
471
|
] }) : null,
|
|
383
|
-
/* @__PURE__ */ jsx("h1", { className: "mt-2 text-2xl font-semibold tracking-
|
|
384
|
-
description ? /* @__PURE__ */ jsx("p", { className: "mt-2 max-w-2xl text-
|
|
472
|
+
/* @__PURE__ */ jsx("h1", { className: "mt-2 text-2xl font-semibold tracking-heading text-card-foreground sm:text-3xl", children: title }),
|
|
473
|
+
description ? /* @__PURE__ */ jsx("p", { className: "mt-2 max-w-2xl text-sm leading-5 text-muted-foreground", children: description }) : null
|
|
385
474
|
] }),
|
|
386
475
|
actions ? /* @__PURE__ */ jsx("div", { className: "flex shrink-0 flex-wrap items-center gap-1.5", children: actions }) : null
|
|
387
476
|
] }),
|
|
388
|
-
children ? /* @__PURE__ */ jsx("div", { className: "
|
|
477
|
+
children ? /* @__PURE__ */ jsx("div", { className: "mt-4", children }) : null
|
|
389
478
|
]
|
|
390
479
|
}
|
|
391
480
|
);
|
|
@@ -404,7 +493,7 @@ function DashboardPanel({
|
|
|
404
493
|
{
|
|
405
494
|
"data-pattern": "nebutra-dashboard-panel",
|
|
406
495
|
className: cn(
|
|
407
|
-
"rounded-[var(--radius-
|
|
496
|
+
"rounded-[var(--radius-card)] bg-card p-3.5 text-card-foreground shadow-[0_0_0_1px_var(--edge-soft),var(--elevation-card)] sm:p-4",
|
|
408
497
|
className
|
|
409
498
|
),
|
|
410
499
|
children: [
|
|
@@ -417,7 +506,7 @@ function DashboardPanel({
|
|
|
417
506
|
),
|
|
418
507
|
children: [
|
|
419
508
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
420
|
-
/* @__PURE__ */ jsx("h2", { className: "text-sm font-semibold
|
|
509
|
+
/* @__PURE__ */ jsx("h2", { className: "text-sm font-semibold text-card-foreground", children: title }),
|
|
421
510
|
description ? /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-xs leading-5 text-muted-foreground", children: description }) : null
|
|
422
511
|
] }),
|
|
423
512
|
(meta || action) && /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-2 lg:justify-end", children: [
|
|
@@ -446,8 +535,8 @@ function DashboardMetricTile({
|
|
|
446
535
|
{
|
|
447
536
|
"data-pattern": "nebutra-dashboard-metric",
|
|
448
537
|
className: cn(
|
|
449
|
-
"group h-full rounded-[var(--radius-
|
|
450
|
-
"hover:
|
|
538
|
+
"group h-full rounded-[var(--radius-card)] bg-muted/40 p-3 shadow-[0_0_0_1px_var(--edge-soft)] transition-[background-color,box-shadow] duration-micro",
|
|
539
|
+
"hover:bg-muted/65 hover:shadow-[0_0_0_1px_var(--edge-medium)]",
|
|
451
540
|
className
|
|
452
541
|
),
|
|
453
542
|
children: [
|
|
@@ -464,10 +553,10 @@ function DashboardMetricTile({
|
|
|
464
553
|
}
|
|
465
554
|
) : null
|
|
466
555
|
] }),
|
|
467
|
-
/* @__PURE__ */ jsx("p", { className: "mt-2 text-2xl font-semibold tabular-nums
|
|
556
|
+
/* @__PURE__ */ jsx("p", { className: "mt-2 text-2xl font-semibold tabular-nums text-card-foreground", children: value }),
|
|
468
557
|
(detail || source) && /* @__PURE__ */ jsxs("div", { className: "mt-1.5 space-y-0.5 text-xs leading-5 text-muted-foreground", children: [
|
|
469
558
|
detail ? /* @__PURE__ */ jsx("span", { className: "block", children: detail }) : null,
|
|
470
|
-
source ? /* @__PURE__ */ jsx("span", { className: "block text-
|
|
559
|
+
source ? /* @__PURE__ */ jsx("span", { className: "block text-xs text-muted-foreground/70", children: source }) : null
|
|
471
560
|
] })
|
|
472
561
|
]
|
|
473
562
|
}
|
|
@@ -518,8 +607,14 @@ var badgeVariants = cva(
|
|
|
518
607
|
"teal-subtle": "bg-info/10 text-info fill-current border-transparent",
|
|
519
608
|
inverted: "bg-foreground text-background fill-current",
|
|
520
609
|
// Special visual treatments (intentional product design, not brand hex)
|
|
521
|
-
trial:
|
|
522
|
-
|
|
610
|
+
trial: (
|
|
611
|
+
// allow-palette: the trial gradient is fixed and vivid in both themes, so its ink is fixed white
|
|
612
|
+
"bg-gradient-to-br from-trial-start to-trial-end text-white fill-current"
|
|
613
|
+
),
|
|
614
|
+
turbo: (
|
|
615
|
+
// allow-palette: the turbo gradient is fixed and vivid in both themes, so its ink is fixed white
|
|
616
|
+
"bg-gradient-to-br from-turbo-start to-turbo-end text-white fill-current"
|
|
617
|
+
),
|
|
523
618
|
pill: "bg-background text-foreground fill-foreground border-border hover:bg-muted/50 focus-visible:bg-muted/50",
|
|
524
619
|
beta: "border-transparent bg-muted text-muted-foreground",
|
|
525
620
|
new: "border-transparent bg-primary/10 text-primary",
|
|
@@ -584,11 +679,11 @@ function Badge({
|
|
|
584
679
|
label
|
|
585
680
|
] });
|
|
586
681
|
if (asChild) {
|
|
587
|
-
const childArray =
|
|
682
|
+
const childArray = React10.Children.toArray(children);
|
|
588
683
|
const child = childArray.length === 1 ? childArray[0] : null;
|
|
589
|
-
if (
|
|
684
|
+
if (React10.isValidElement(child)) {
|
|
590
685
|
const childProps = child.props;
|
|
591
|
-
return
|
|
686
|
+
return React10.cloneElement(child, {
|
|
592
687
|
...props,
|
|
593
688
|
...childProps,
|
|
594
689
|
"data-slot": "badge",
|
|
@@ -601,7 +696,7 @@ function Badge({
|
|
|
601
696
|
return /* @__PURE__ */ jsx("span", { "data-slot": "badge", className: badgeClassName, ...props, children: renderContent(children) });
|
|
602
697
|
}
|
|
603
698
|
({
|
|
604
|
-
// Nebutra Blue (云毓蓝) — technology & trust
|
|
699
|
+
// Nebutra Blue (云毓蓝) — technology & trust
|
|
605
700
|
blue50: colors.primary[50],
|
|
606
701
|
blue100: colors.primary[100],
|
|
607
702
|
blue200: colors.primary[200],
|
|
@@ -614,7 +709,7 @@ function Badge({
|
|
|
614
709
|
blue800: colors.primary[800],
|
|
615
710
|
blue900: colors.primary[900],
|
|
616
711
|
blue950: colors.primary[950],
|
|
617
|
-
// Nebutra Cyan (云毓青) — data flow & intelligence
|
|
712
|
+
// Nebutra Cyan (云毓青) — data flow & intelligence
|
|
618
713
|
cyan50: colors.accent[50],
|
|
619
714
|
cyan100: colors.accent[100],
|
|
620
715
|
cyan200: colors.accent[200],
|
|
@@ -639,6 +734,13 @@ function Badge({
|
|
|
639
734
|
neutral800: colors.neutral[800],
|
|
640
735
|
neutral900: colors.neutral[900],
|
|
641
736
|
neutral950: colors.neutral[950],
|
|
737
|
+
// deepest — used as dark background
|
|
738
|
+
// Semantic raw colors — VI §Color Specifications. The 500s are the status
|
|
739
|
+
// tokens; the 600 hover steps have no token of their own.
|
|
740
|
+
// NOTE: info = brand blue, not sky/teal
|
|
741
|
+
red500: tokenColor("--status-danger"),
|
|
742
|
+
green500: tokenColor("--status-success"),
|
|
743
|
+
amber500: tokenColor("--status-warning"),
|
|
642
744
|
white: colors.white,
|
|
643
745
|
black: colors.black
|
|
644
746
|
});
|
|
@@ -677,6 +779,18 @@ var primitiveFontSize = {
|
|
|
677
779
|
sm: 14,
|
|
678
780
|
base: 16,
|
|
679
781
|
lg: 18};
|
|
782
|
+
({
|
|
783
|
+
/** Default body/UI stack — Geist with CJK falling through to MiSans */
|
|
784
|
+
sans: fontStack("--font-sans"),
|
|
785
|
+
/** CJK-locale stack (same order as sans, minus Latin-only system faces) */
|
|
786
|
+
cnSans: fontStack("--font-cn"),
|
|
787
|
+
/** Display / hero headlines */
|
|
788
|
+
display: fontStack("--font-display"),
|
|
789
|
+
/** Headings */
|
|
790
|
+
heading: fontStack("--font-heading"),
|
|
791
|
+
/** Code / monospace */
|
|
792
|
+
mono: fontStack("--font-mono")
|
|
793
|
+
});
|
|
680
794
|
var primitiveTransition = {
|
|
681
795
|
duration: {
|
|
682
796
|
// hover, focus, small state changes
|
|
@@ -702,17 +816,18 @@ var overlayZIndex = {
|
|
|
702
816
|
};
|
|
703
817
|
var overlayClassNames = {
|
|
704
818
|
menuSurface: [
|
|
705
|
-
"min-w-32 overflow-hidden rounded-[var(--radius-lg)] border border-border/70 bg-popover/95 p-1 text-popover-foreground backdrop-blur-md",
|
|
819
|
+
"min-w-32 origin-[var(--transform-origin)] overflow-hidden rounded-[var(--radius-lg)] border border-border/70 bg-popover/95 p-1 text-popover-foreground backdrop-blur-md",
|
|
706
820
|
shadowClasses.xl,
|
|
707
|
-
"outline-none transition-[opacity,transform
|
|
708
|
-
"data-[starting-style]:scale-
|
|
821
|
+
"outline-none transition-[opacity,transform] duration-[var(--motion-duration-flow)] ease-[var(--ease-brand)]",
|
|
822
|
+
"data-[starting-style]:scale-[0.97] data-[starting-style]:opacity-0 data-ending-style:scale-[0.97] data-ending-style:opacity-0 data-ending-style:duration-[var(--motion-duration-micro)]",
|
|
709
823
|
"motion-reduce:transition-none motion-reduce:data-[starting-style]:transform-none motion-reduce:data-[ending-style]:transform-none"
|
|
710
824
|
].join(" "),
|
|
711
825
|
tooltipSurface: [
|
|
712
|
-
"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",
|
|
826
|
+
"origin-[var(--transform-origin)] 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",
|
|
713
827
|
shadowClasses.md,
|
|
714
|
-
"transition-[opacity,transform
|
|
715
|
-
"data-starting-style:scale-
|
|
828
|
+
"transition-[opacity,transform] duration-[var(--motion-duration-flow)] ease-[var(--ease-brand)]",
|
|
829
|
+
"data-starting-style:scale-[0.97] data-starting-style:opacity-0 data-ending-style:scale-[0.97] data-ending-style:opacity-0 data-ending-style:duration-[var(--motion-duration-micro)]",
|
|
830
|
+
"data-[instant]:duration-0",
|
|
716
831
|
"motion-reduce:transition-none motion-reduce:data-starting-style:transform-none motion-reduce:data-ending-style:transform-none"
|
|
717
832
|
].join(" ")};
|
|
718
833
|
|
|
@@ -726,7 +841,7 @@ var menuHighlightedClassName = "data-[highlighted]:bg-accent data-[highlighted]:
|
|
|
726
841
|
var overlayPrimitiveClassNames = {
|
|
727
842
|
menuSurface: "rounded-[var(--radius-md)] border-border/70 bg-popover/95 shadow-md",
|
|
728
843
|
menuItem: [menuItemBaseClassName, menuHighlightedClassName].join(" ")};
|
|
729
|
-
var DropdownMenuContext =
|
|
844
|
+
var DropdownMenuContext = React10.createContext(null);
|
|
730
845
|
function DropdownMenu({
|
|
731
846
|
open: controlledOpen,
|
|
732
847
|
defaultOpen = false,
|
|
@@ -734,7 +849,7 @@ function DropdownMenu({
|
|
|
734
849
|
children,
|
|
735
850
|
...props
|
|
736
851
|
}) {
|
|
737
|
-
const [uncontrolledOpen, setUncontrolledOpen] =
|
|
852
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React10.useState(defaultOpen);
|
|
738
853
|
const open = controlledOpen ?? uncontrolledOpen;
|
|
739
854
|
function setOpen(nextOpen, eventDetails) {
|
|
740
855
|
if (controlledOpen === void 0) {
|
|
@@ -753,11 +868,11 @@ var DropdownMenuTrigger = ({
|
|
|
753
868
|
ref,
|
|
754
869
|
...props
|
|
755
870
|
}) => {
|
|
756
|
-
const context =
|
|
871
|
+
const context = React10.use(DropdownMenuContext);
|
|
757
872
|
function openFromTrigger() {
|
|
758
873
|
context?.setOpen(true);
|
|
759
874
|
}
|
|
760
|
-
const childRenderElement = asChild &&
|
|
875
|
+
const childRenderElement = asChild && React10.isValidElement(children) ? React10.cloneElement(children, {
|
|
761
876
|
onMouseDown: (event) => {
|
|
762
877
|
children.props.onMouseDown?.(event);
|
|
763
878
|
if (!event.defaultPrevented) {
|
|
@@ -802,6 +917,7 @@ var DropdownMenuContent = ({
|
|
|
802
917
|
align,
|
|
803
918
|
alignOffset,
|
|
804
919
|
side,
|
|
920
|
+
style: { zIndex: overlayZIndex.popover },
|
|
805
921
|
children: /* @__PURE__ */ jsx(
|
|
806
922
|
Menu.Popup,
|
|
807
923
|
{
|
|
@@ -849,11 +965,13 @@ var DropdownMenuSeparator = ({
|
|
|
849
965
|
DropdownMenuSeparator.displayName = "DropdownMenuSeparator";
|
|
850
966
|
var iconToneStyles = {
|
|
851
967
|
neutral: "bg-muted text-muted-foreground",
|
|
852
|
-
blue: "bg-blue-
|
|
853
|
-
cyan: "bg-cyan-
|
|
968
|
+
blue: "bg-blue-3 text-blue-11",
|
|
969
|
+
cyan: "bg-cyan-3 text-cyan-11",
|
|
970
|
+
// allow-palette: categorical hue with no token equivalent (purple/violet has no semantic slot)
|
|
854
971
|
purple: "bg-purple-50 text-purple-700 dark:bg-purple-950/40 dark:text-purple-300",
|
|
855
|
-
amber: "bg-
|
|
856
|
-
green: "bg-
|
|
972
|
+
amber: "bg-warning/15 text-warning-strong",
|
|
973
|
+
green: "bg-success/15 text-success-strong",
|
|
974
|
+
// allow-palette: categorical hue with no token equivalent (pink has no semantic slot)
|
|
857
975
|
pink: "bg-pink-50 text-pink-700 dark:bg-pink-950/40 dark:text-pink-300"
|
|
858
976
|
};
|
|
859
977
|
var badgeToneToVariant = {
|
|
@@ -901,7 +1019,7 @@ function GalleryCardActionsMenu({ actions, title }) {
|
|
|
901
1019
|
action.onSelect();
|
|
902
1020
|
},
|
|
903
1021
|
className: cn(
|
|
904
|
-
action.destructive && "text-destructive data-[highlighted]:bg-destructive/10 data-[highlighted]:text-destructive"
|
|
1022
|
+
action.destructive && "text-destructive-strong data-[highlighted]:bg-destructive/10 data-[highlighted]:text-destructive-strong"
|
|
905
1023
|
),
|
|
906
1024
|
children: action.label
|
|
907
1025
|
},
|
|
@@ -916,6 +1034,7 @@ function GalleryCardBody({
|
|
|
916
1034
|
iconTone,
|
|
917
1035
|
badge,
|
|
918
1036
|
pinned,
|
|
1037
|
+
pinnedLabel = "Pinned",
|
|
919
1038
|
metadata,
|
|
920
1039
|
actions
|
|
921
1040
|
}) {
|
|
@@ -935,7 +1054,13 @@ function GalleryCardBody({
|
|
|
935
1054
|
}
|
|
936
1055
|
) : /* @__PURE__ */ jsx("span", { className: "h-10 w-10 shrink-0", "aria-hidden": "true" }),
|
|
937
1056
|
(pinned || hasActions) && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
938
|
-
pinned && /* @__PURE__ */ jsx(
|
|
1057
|
+
pinned && /* @__PURE__ */ jsx(
|
|
1058
|
+
Pin,
|
|
1059
|
+
{
|
|
1060
|
+
className: "h-3.5 w-3.5 fill-warning-strong text-warning-strong",
|
|
1061
|
+
"aria-label": pinnedLabel
|
|
1062
|
+
}
|
|
1063
|
+
),
|
|
939
1064
|
hasActions && actions ? /* @__PURE__ */ jsx(GalleryCardActionsMenu, { actions, title }) : null
|
|
940
1065
|
] })
|
|
941
1066
|
] }),
|
|
@@ -961,6 +1086,7 @@ function GalleryCard(props) {
|
|
|
961
1086
|
iconTone = "neutral",
|
|
962
1087
|
badge,
|
|
963
1088
|
pinned,
|
|
1089
|
+
pinnedLabel,
|
|
964
1090
|
metadata,
|
|
965
1091
|
actions,
|
|
966
1092
|
onClick,
|
|
@@ -977,6 +1103,7 @@ function GalleryCard(props) {
|
|
|
977
1103
|
iconTone,
|
|
978
1104
|
badge,
|
|
979
1105
|
pinned,
|
|
1106
|
+
...pinnedLabel !== void 0 ? { pinnedLabel } : {},
|
|
980
1107
|
metadata,
|
|
981
1108
|
actions
|
|
982
1109
|
}
|
|
@@ -1008,7 +1135,7 @@ function lineTone(line) {
|
|
|
1008
1135
|
return "text-primary font-medium";
|
|
1009
1136
|
}
|
|
1010
1137
|
if (trimmed.includes(":")) {
|
|
1011
|
-
return "text-
|
|
1138
|
+
return "text-success-strong";
|
|
1012
1139
|
}
|
|
1013
1140
|
return "text-foreground/78";
|
|
1014
1141
|
}
|
|
@@ -1034,7 +1161,6 @@ function renderIcon(icon) {
|
|
|
1034
1161
|
}
|
|
1035
1162
|
function KineticFeatureCard({
|
|
1036
1163
|
icon,
|
|
1037
|
-
eyebrow,
|
|
1038
1164
|
title,
|
|
1039
1165
|
description,
|
|
1040
1166
|
children,
|
|
@@ -1056,20 +1182,12 @@ function KineticFeatureCard({
|
|
|
1056
1182
|
"div",
|
|
1057
1183
|
{
|
|
1058
1184
|
"aria-hidden": "true",
|
|
1059
|
-
className: "pointer-events-none absolute inset-0 bg-[radial-gradient(
|
|
1060
|
-
}
|
|
1061
|
-
),
|
|
1062
|
-
/* @__PURE__ */ jsx(
|
|
1063
|
-
"div",
|
|
1064
|
-
{
|
|
1065
|
-
"aria-hidden": "true",
|
|
1066
|
-
className: "pointer-events-none absolute inset-x-0 top-0 h-40 bg-gradient-to-b from-primary/12 via-primary/5 to-transparent",
|
|
1185
|
+
className: "pointer-events-none absolute inset-x-0 top-0 h-40 bg-[radial-gradient(ellipse_at_top,hsl(var(--primary)/0.12),transparent_70%)]",
|
|
1067
1186
|
style: { maskImage: "linear-gradient(to bottom, black 45%, transparent 100%)" }
|
|
1068
1187
|
}
|
|
1069
1188
|
),
|
|
1070
|
-
/* @__PURE__ */ jsx("div", { className: "absolute right-0 top-0 z-10 rounded-bl-[2rem] border-b border-l border-border/60 bg-muted/55 px-4 py-2 backdrop-blur-xl", children: /* @__PURE__ */ jsx("span", { className: "font-mono text-[10px] font-semibold uppercase tracking-[0.18em] text-muted-foreground", children: eyebrow }) }),
|
|
1071
1189
|
/* @__PURE__ */ jsxs("div", { className: "relative z-10 flex h-full flex-col", children: [
|
|
1072
|
-
/* @__PURE__ */ jsx("div", { className: "mb-8 flex items-start justify-between gap-4
|
|
1190
|
+
/* @__PURE__ */ jsx("div", { className: "mb-8 flex items-start justify-between gap-4", children: renderedIcon && /* @__PURE__ */ jsx("div", { className: "grid size-14 place-items-center rounded-[var(--radius-xl)] border border-border/65 bg-background/75 shadow-glass-sm transition-transform duration-500 group-hover/kinetic:-translate-y-1", children: renderedIcon }) }),
|
|
1073
1191
|
/* @__PURE__ */ jsx(
|
|
1074
1192
|
"h3",
|
|
1075
1193
|
{
|
|
@@ -1142,9 +1260,9 @@ function KineticConsoleFrame({
|
|
|
1142
1260
|
children: [
|
|
1143
1261
|
/* @__PURE__ */ jsxs("div", { className: "flex h-14 flex-none items-center gap-4 border-b border-border/60 bg-background/70 px-5 backdrop-blur-xl", children: [
|
|
1144
1262
|
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", "aria-hidden": true, children: [
|
|
1145
|
-
/* @__PURE__ */ jsx("span", { className: "size-3 rounded-full border border-border/80 bg-muted shadow-sm transition-colors group-hover/kinetic:bg-
|
|
1146
|
-
/* @__PURE__ */ jsx("span", { className: "size-3 rounded-full border border-border/80 bg-muted shadow-sm transition-colors group-hover/kinetic:bg-
|
|
1147
|
-
/* @__PURE__ */ jsx("span", { className: "size-3 rounded-full border border-border/80 bg-muted shadow-sm transition-colors group-hover/kinetic:bg-
|
|
1263
|
+
/* @__PURE__ */ jsx("span", { className: "size-3 rounded-full border border-border/80 bg-muted shadow-sm transition-colors group-hover/kinetic:bg-destructive/80" }),
|
|
1264
|
+
/* @__PURE__ */ jsx("span", { className: "size-3 rounded-full border border-border/80 bg-muted shadow-sm transition-colors group-hover/kinetic:bg-warning/80" }),
|
|
1265
|
+
/* @__PURE__ */ jsx("span", { className: "size-3 rounded-full border border-border/80 bg-muted shadow-sm transition-colors group-hover/kinetic:bg-success/80" })
|
|
1148
1266
|
] }),
|
|
1149
1267
|
/* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1 text-center", children: /* @__PURE__ */ jsx("span", { className: "inline-flex max-w-full items-center rounded-[var(--radius-md)] border border-border/50 bg-muted/35 px-4 py-1 font-mono text-[10px] font-semibold uppercase tracking-[0.16em] text-muted-foreground", children: /* @__PURE__ */ jsx("span", { className: "truncate", translate: "no", children: title }) }) }),
|
|
1150
1268
|
/* @__PURE__ */ jsx("div", { className: "hidden min-w-20 justify-end sm:flex", children: status && /* @__PURE__ */ jsx("span", { className: "rounded-full border border-border/55 bg-background/65 px-2 py-0.5 font-mono text-[10px] uppercase text-muted-foreground", children: status }) })
|
|
@@ -1187,13 +1305,6 @@ function KineticMorphSurface({
|
|
|
1187
1305
|
"data-taste": "nebutra-morph-surface",
|
|
1188
1306
|
...props,
|
|
1189
1307
|
children: [
|
|
1190
|
-
/* @__PURE__ */ jsx(
|
|
1191
|
-
"div",
|
|
1192
|
-
{
|
|
1193
|
-
"aria-hidden": "true",
|
|
1194
|
-
className: "pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_1px_1px,var(--neutral-8)_1px,transparent_0)] bg-[length:20px_20px] opacity-[0.10]"
|
|
1195
|
-
}
|
|
1196
|
-
),
|
|
1197
1308
|
/* @__PURE__ */ jsx(
|
|
1198
1309
|
"div",
|
|
1199
1310
|
{
|
|
@@ -1273,13 +1384,6 @@ function KineticCommandBox({
|
|
|
1273
1384
|
"data-taste": "nebutra-texture-command",
|
|
1274
1385
|
...props,
|
|
1275
1386
|
children: [
|
|
1276
|
-
/* @__PURE__ */ jsx(
|
|
1277
|
-
"div",
|
|
1278
|
-
{
|
|
1279
|
-
"aria-hidden": "true",
|
|
1280
|
-
className: "pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_1px_1px,var(--neutral-8)_1px,transparent_0)] bg-[length:16px_16px] opacity-[0.10]"
|
|
1281
|
-
}
|
|
1282
|
-
),
|
|
1283
1387
|
/* @__PURE__ */ jsxs("code", { className: "relative z-10 flex-1 overflow-x-auto whitespace-nowrap px-4 py-3.5 font-mono text-xs text-foreground sm:px-5 sm:text-sm md:text-base", children: [
|
|
1284
1388
|
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "$" }),
|
|
1285
1389
|
" ",
|
|
@@ -1381,11 +1485,11 @@ function KineticStep({
|
|
|
1381
1485
|
}
|
|
1382
1486
|
);
|
|
1383
1487
|
}
|
|
1384
|
-
var Slot =
|
|
1488
|
+
var Slot = React10.forwardRef(
|
|
1385
1489
|
({ children, className, style, ...props }, ref) => {
|
|
1386
|
-
const childArray =
|
|
1490
|
+
const childArray = React10.Children.toArray(children);
|
|
1387
1491
|
const child = childArray.length === 1 ? childArray[0] : null;
|
|
1388
|
-
if (child == null || !
|
|
1492
|
+
if (child == null || !React10.isValidElement(child)) {
|
|
1389
1493
|
return /* @__PURE__ */ jsx("span", { ref, className, style, ...props, children });
|
|
1390
1494
|
}
|
|
1391
1495
|
const childProps = child.props;
|
|
@@ -1406,7 +1510,7 @@ var Slot = React.forwardRef(
|
|
|
1406
1510
|
className: mergedClass,
|
|
1407
1511
|
style: { ...childProps.style, ...style }
|
|
1408
1512
|
};
|
|
1409
|
-
return
|
|
1513
|
+
return React10.cloneElement(
|
|
1410
1514
|
child,
|
|
1411
1515
|
merged
|
|
1412
1516
|
);
|
|
@@ -1418,7 +1522,12 @@ var buttonVariants = cva(
|
|
|
1418
1522
|
"inline-flex items-center justify-center gap-2 whitespace-nowrap",
|
|
1419
1523
|
"rounded-[var(--btn-default-radius,var(--radius-md))]",
|
|
1420
1524
|
"text-[length:var(--control-font-size-md,0.875rem)] font-[number:var(--font-weight-medium,500)]",
|
|
1421
|
-
|
|
1525
|
+
// `transform` is in the property list on purpose: without it the
|
|
1526
|
+
// active:scale-[0.97] press snapped instantly and the button felt dead
|
|
1527
|
+
// under the finger. Duration/ease stay on the flow rail — motion
|
|
1528
|
+
// governance pins them (primitives/__tests__/motion-governance.test.ts).
|
|
1529
|
+
"transition-[color,background-color,border-color,box-shadow,transform] duration-flow ease-[var(--ease-brand)]",
|
|
1530
|
+
"active:scale-[0.97] motion-reduce:active:scale-100 motion-reduce:transition-none",
|
|
1422
1531
|
"disabled:pointer-events-none disabled:opacity-50",
|
|
1423
1532
|
"aria-busy:cursor-wait"
|
|
1424
1533
|
].join(" "),
|
|
@@ -1427,7 +1536,7 @@ var buttonVariants = cva(
|
|
|
1427
1536
|
variant: {
|
|
1428
1537
|
// Recipe-driven via packages/design/tokens/recipe.css (.btn-brand-default)
|
|
1429
1538
|
default: "btn-brand-default",
|
|
1430
|
-
ink: "bg-
|
|
1539
|
+
ink: "bg-neutral-12 text-neutral-1 ring-1 ring-inset ring-neutral-1/5 hover:bg-neutral-11 hover:-translate-y-px active:translate-y-0 transition-[transform,background-color] duration-micro",
|
|
1431
1540
|
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
1432
1541
|
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
|
1433
1542
|
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
@@ -1550,10 +1659,10 @@ function Spinner({ className }) {
|
|
|
1550
1659
|
}
|
|
1551
1660
|
);
|
|
1552
1661
|
}
|
|
1553
|
-
function getIconSizeClass(size,
|
|
1554
|
-
if (
|
|
1555
|
-
if (
|
|
1556
|
-
if (
|
|
1662
|
+
function getIconSizeClass(size, iconSize2) {
|
|
1663
|
+
if (iconSize2 === "sm") return "[&>svg]:size-3.5";
|
|
1664
|
+
if (iconSize2 === "md") return "[&>svg]:size-3.5";
|
|
1665
|
+
if (iconSize2 === "lg") return "[&>svg]:size-4";
|
|
1557
1666
|
switch (size) {
|
|
1558
1667
|
case "tiny":
|
|
1559
1668
|
return "[&>svg]:size-3";
|
|
@@ -1568,10 +1677,10 @@ function getIconSizeClass(size, iconSize) {
|
|
|
1568
1677
|
return "[&>svg]:size-4";
|
|
1569
1678
|
}
|
|
1570
1679
|
}
|
|
1571
|
-
function getSpinnerSizeClass(size,
|
|
1572
|
-
if (
|
|
1573
|
-
if (
|
|
1574
|
-
if (
|
|
1680
|
+
function getSpinnerSizeClass(size, iconSize2) {
|
|
1681
|
+
if (iconSize2 === "sm") return "size-3.5";
|
|
1682
|
+
if (iconSize2 === "md") return "size-3.5";
|
|
1683
|
+
if (iconSize2 === "lg") return "size-4";
|
|
1575
1684
|
switch (size) {
|
|
1576
1685
|
case "tiny":
|
|
1577
1686
|
return "size-3";
|
|
@@ -1596,10 +1705,10 @@ function resolveShadowClass(shadow) {
|
|
|
1596
1705
|
const level = shadow === true ? "md" : shadow;
|
|
1597
1706
|
return SHADOW_CLASSES[level];
|
|
1598
1707
|
}
|
|
1599
|
-
function ButtonContent({ loading, prefix, suffix, size, iconSize, children }) {
|
|
1600
|
-
const iconSizeClass = getIconSizeClass(size,
|
|
1708
|
+
function ButtonContent({ loading, prefix, suffix, size, iconSize: iconSize2, children }) {
|
|
1709
|
+
const iconSizeClass = getIconSizeClass(size, iconSize2);
|
|
1601
1710
|
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
1602
|
-
loading && /* @__PURE__ */ jsx(Spinner, { className: getSpinnerSizeClass(size,
|
|
1711
|
+
loading && /* @__PURE__ */ jsx(Spinner, { className: getSpinnerSizeClass(size, iconSize2) }),
|
|
1603
1712
|
prefix != null && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn("shrink-0", iconSizeClass), children: prefix }),
|
|
1604
1713
|
children,
|
|
1605
1714
|
suffix != null && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn("shrink-0", iconSizeClass), children: suffix })
|
|
@@ -1610,7 +1719,7 @@ var Button = ({
|
|
|
1610
1719
|
variant,
|
|
1611
1720
|
size,
|
|
1612
1721
|
shape,
|
|
1613
|
-
iconSize,
|
|
1722
|
+
iconSize: iconSize2,
|
|
1614
1723
|
asChild = false,
|
|
1615
1724
|
loading = false,
|
|
1616
1725
|
disabled,
|
|
@@ -1628,7 +1737,7 @@ var Button = ({
|
|
|
1628
1737
|
Comp,
|
|
1629
1738
|
{
|
|
1630
1739
|
ref,
|
|
1631
|
-
className: cn(buttonVariants({ variant, size, shape, iconSize }), shadowClass, className),
|
|
1740
|
+
className: cn(buttonVariants({ variant, size, shape, iconSize: iconSize2 }), shadowClass, className),
|
|
1632
1741
|
disabled: isDisabled,
|
|
1633
1742
|
"aria-busy": loading || void 0,
|
|
1634
1743
|
...props,
|
|
@@ -1639,7 +1748,7 @@ var Button = ({
|
|
|
1639
1748
|
prefix,
|
|
1640
1749
|
suffix,
|
|
1641
1750
|
size,
|
|
1642
|
-
iconSize,
|
|
1751
|
+
iconSize: iconSize2,
|
|
1643
1752
|
children
|
|
1644
1753
|
}
|
|
1645
1754
|
)
|
|
@@ -1716,20 +1825,65 @@ function asPlainStyle(style) {
|
|
|
1716
1825
|
function withHtmlProps(Component) {
|
|
1717
1826
|
return Component;
|
|
1718
1827
|
}
|
|
1719
|
-
|
|
1828
|
+
|
|
1829
|
+
// src/tokens/components/interaction.ts
|
|
1830
|
+
var interaction = {
|
|
1831
|
+
/**
|
|
1832
|
+
* Tooltips. The first one waits so a sweeping pointer does not strobe;
|
|
1833
|
+
* once one is open, its neighbours open instantly if the pointer arrives
|
|
1834
|
+
* within the skip window. Radix Tooltip defaults: delayDuration 700,
|
|
1835
|
+
* skipDelayDuration 300. Vercel/Kowalski: "delay the first tooltip only".
|
|
1836
|
+
*/
|
|
1837
|
+
tooltip: { delayMs: 700, skipWindowMs: 300 }};
|
|
1838
|
+
var DEFAULT_TOOLTIP_DELAY_MS = interaction.tooltip.delayMs;
|
|
1839
|
+
var SKIP_DELAY_WINDOW_MS = interaction.tooltip.skipWindowMs;
|
|
1840
|
+
var lastTooltipOpenAt = 0;
|
|
1841
|
+
var skipDelayListeners = /* @__PURE__ */ new Set();
|
|
1842
|
+
function markTooltipOpened() {
|
|
1843
|
+
lastTooltipOpenAt = Date.now();
|
|
1844
|
+
for (const listener of skipDelayListeners) listener();
|
|
1845
|
+
}
|
|
1846
|
+
function shouldSkipDelay() {
|
|
1847
|
+
return Date.now() - lastTooltipOpenAt < SKIP_DELAY_WINDOW_MS;
|
|
1848
|
+
}
|
|
1849
|
+
function useSkipDelay() {
|
|
1850
|
+
const [, tick] = React10.useReducer((count) => count + 1, 0);
|
|
1851
|
+
React10.useEffect(() => {
|
|
1852
|
+
skipDelayListeners.add(tick);
|
|
1853
|
+
return () => {
|
|
1854
|
+
skipDelayListeners.delete(tick);
|
|
1855
|
+
};
|
|
1856
|
+
}, []);
|
|
1857
|
+
return shouldSkipDelay();
|
|
1858
|
+
}
|
|
1859
|
+
var TooltipInstantContext = React10.createContext(false);
|
|
1720
1860
|
var TooltipProvider = ({
|
|
1721
1861
|
children,
|
|
1722
1862
|
delayDuration = DEFAULT_TOOLTIP_DELAY_MS
|
|
1723
1863
|
}) => {
|
|
1724
|
-
|
|
1864
|
+
const skipDelay = useSkipDelay();
|
|
1865
|
+
return /* @__PURE__ */ jsx(Tooltip$1.Provider, { delay: skipDelay ? 0 : delayDuration, children });
|
|
1725
1866
|
};
|
|
1726
1867
|
var Tooltip = ({
|
|
1727
1868
|
delayDuration,
|
|
1728
1869
|
children,
|
|
1870
|
+
onOpenChange,
|
|
1729
1871
|
...props
|
|
1730
1872
|
}) => {
|
|
1731
|
-
const
|
|
1732
|
-
|
|
1873
|
+
const skipDelay = useSkipDelay();
|
|
1874
|
+
const instant = delayDuration == null && skipDelay;
|
|
1875
|
+
const delay = delayDuration ?? (instant ? 0 : DEFAULT_TOOLTIP_DELAY_MS);
|
|
1876
|
+
return /* @__PURE__ */ jsx(TooltipInstantContext.Provider, { value: instant, children: /* @__PURE__ */ jsx(Tooltip$1.Provider, { delay, children: /* @__PURE__ */ jsx(
|
|
1877
|
+
Tooltip$1.Root,
|
|
1878
|
+
{
|
|
1879
|
+
...props,
|
|
1880
|
+
onOpenChange: (open, eventDetails) => {
|
|
1881
|
+
if (open) markTooltipOpened();
|
|
1882
|
+
onOpenChange?.(open, eventDetails);
|
|
1883
|
+
},
|
|
1884
|
+
children
|
|
1885
|
+
}
|
|
1886
|
+
) }) });
|
|
1733
1887
|
};
|
|
1734
1888
|
var TooltipTrigger = ({
|
|
1735
1889
|
asChild,
|
|
@@ -1737,7 +1891,7 @@ var TooltipTrigger = ({
|
|
|
1737
1891
|
ref,
|
|
1738
1892
|
...props
|
|
1739
1893
|
}) => {
|
|
1740
|
-
if (asChild &&
|
|
1894
|
+
if (asChild && React10.isValidElement(children)) {
|
|
1741
1895
|
return /* @__PURE__ */ jsx(
|
|
1742
1896
|
Tooltip$1.Trigger,
|
|
1743
1897
|
{
|
|
@@ -1759,25 +1913,29 @@ var TooltipContent = ({
|
|
|
1759
1913
|
alignOffset = 0,
|
|
1760
1914
|
ref,
|
|
1761
1915
|
...props
|
|
1762
|
-
}) =>
|
|
1763
|
-
|
|
1764
|
-
{
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1916
|
+
}) => {
|
|
1917
|
+
const instant = React10.use(TooltipInstantContext);
|
|
1918
|
+
return /* @__PURE__ */ jsx(Tooltip$1.Portal, { children: /* @__PURE__ */ jsx(
|
|
1919
|
+
Tooltip$1.Positioner,
|
|
1920
|
+
{
|
|
1921
|
+
side,
|
|
1922
|
+
align,
|
|
1923
|
+
sideOffset,
|
|
1924
|
+
alignOffset,
|
|
1925
|
+
style: { zIndex: overlayZIndex.tooltip },
|
|
1926
|
+
children: /* @__PURE__ */ jsx(
|
|
1927
|
+
Tooltip$1.Popup,
|
|
1928
|
+
{
|
|
1929
|
+
ref,
|
|
1930
|
+
className: cn(overlayClassNames.tooltipSurface, className),
|
|
1931
|
+
"data-instant": instant || void 0,
|
|
1932
|
+
style: { zIndex: overlayZIndex.tooltip, ...style },
|
|
1933
|
+
...props
|
|
1934
|
+
}
|
|
1935
|
+
)
|
|
1936
|
+
}
|
|
1937
|
+
) });
|
|
1938
|
+
};
|
|
1781
1939
|
TooltipContent.displayName = "TooltipContent";
|
|
1782
1940
|
var BaseRoot = withHtmlProps(Tabs$1.Root);
|
|
1783
1941
|
var BaseList = withHtmlProps(Tabs$1.List);
|
|
@@ -1872,7 +2030,7 @@ var tabsContentVariants = cva(
|
|
|
1872
2030
|
}
|
|
1873
2031
|
}
|
|
1874
2032
|
);
|
|
1875
|
-
var TabsContext =
|
|
2033
|
+
var TabsContext = React10.createContext({
|
|
1876
2034
|
activationMode: "manual",
|
|
1877
2035
|
disabled: false,
|
|
1878
2036
|
shape: "default",
|
|
@@ -1930,7 +2088,7 @@ function Tabs({
|
|
|
1930
2088
|
}) {
|
|
1931
2089
|
const rootValue = selected ?? value;
|
|
1932
2090
|
const rootDefaultValue = defaultValue ?? getFirstEnabledValue(tabs);
|
|
1933
|
-
const context =
|
|
2091
|
+
const context = React10.useMemo(
|
|
1934
2092
|
() => ({ activationMode, disabled, shape, size, variant }),
|
|
1935
2093
|
[activationMode, disabled, shape, size, variant]
|
|
1936
2094
|
);
|
|
@@ -2016,11 +2174,11 @@ function TabsList({
|
|
|
2016
2174
|
children,
|
|
2017
2175
|
...props
|
|
2018
2176
|
}) {
|
|
2019
|
-
const context =
|
|
2177
|
+
const context = React10.use(TabsContext);
|
|
2020
2178
|
const resolvedVariant = variant ?? context.variant;
|
|
2021
2179
|
const resolvedShape = shape ?? context.shape;
|
|
2022
2180
|
const resolvedActivateOnFocus = activateOnFocus ?? context.activationMode === "automatic";
|
|
2023
|
-
const listContext =
|
|
2181
|
+
const listContext = React10.useMemo(
|
|
2024
2182
|
() => ({ ...context, shape: resolvedShape, variant: resolvedVariant }),
|
|
2025
2183
|
[context, resolvedShape, resolvedVariant]
|
|
2026
2184
|
);
|
|
@@ -2057,7 +2215,7 @@ function TabsList({
|
|
|
2057
2215
|
) });
|
|
2058
2216
|
}
|
|
2059
2217
|
function TabsTrigger({ badge, children, className, disabled, icon, ...props }) {
|
|
2060
|
-
const context =
|
|
2218
|
+
const context = React10.use(TabsContext);
|
|
2061
2219
|
const isDisabled = disabled ?? context.disabled;
|
|
2062
2220
|
return /* @__PURE__ */ jsxs(
|
|
2063
2221
|
BaseTrigger,
|
|
@@ -2121,7 +2279,7 @@ var formControlFocusClassNames = {
|
|
|
2121
2279
|
var formControlInvalidClassNames = {
|
|
2122
2280
|
textarea: "aria-invalid:border-destructive/60 aria-invalid:focus:border-destructive aria-invalid:focus:ring-destructive/20"};
|
|
2123
2281
|
var fieldMessageClassName = "text-xs text-muted-foreground";
|
|
2124
|
-
var fieldErrorClassName = "text-xs font-medium text-destructive";
|
|
2282
|
+
var fieldErrorClassName = "text-xs font-medium text-destructive-strong";
|
|
2125
2283
|
function getTextareaStyle(size, style) {
|
|
2126
2284
|
const token = textareaTokens.sizes[size];
|
|
2127
2285
|
return {
|
|
@@ -2156,6 +2314,7 @@ var Textarea = ({
|
|
|
2156
2314
|
description,
|
|
2157
2315
|
error,
|
|
2158
2316
|
fieldClassName,
|
|
2317
|
+
tone = "bordered",
|
|
2159
2318
|
id,
|
|
2160
2319
|
onChange,
|
|
2161
2320
|
onValueChange,
|
|
@@ -2164,13 +2323,13 @@ var Textarea = ({
|
|
|
2164
2323
|
ref,
|
|
2165
2324
|
...props
|
|
2166
2325
|
}) => {
|
|
2167
|
-
const baseId =
|
|
2326
|
+
const baseId = React10.useId();
|
|
2168
2327
|
const textareaId = id ?? (label || description || typeof error === "string" ? baseId : void 0);
|
|
2169
2328
|
const resolvedInvalid = isInvalid(error, ariaInvalid);
|
|
2170
2329
|
const descriptionId = description && textareaId ? `${textareaId}-description` : void 0;
|
|
2171
2330
|
const errorId = typeof error === "string" && textareaId ? `${textareaId}-error` : void 0;
|
|
2172
2331
|
const describedBy = joinDescriptionIds(ariaDescribedBy, descriptionId, errorId);
|
|
2173
|
-
const handleChange =
|
|
2332
|
+
const handleChange = React10.useCallback(
|
|
2174
2333
|
(event) => {
|
|
2175
2334
|
onValueChange?.(event.currentTarget.value);
|
|
2176
2335
|
onChange?.(event);
|
|
@@ -2181,10 +2340,10 @@ var Textarea = ({
|
|
|
2181
2340
|
"textarea",
|
|
2182
2341
|
{
|
|
2183
2342
|
className: cn(
|
|
2184
|
-
"flex min-h-[var(--textarea-min-height)] w-full resize-y rounded-[var(--textarea-radius)]
|
|
2185
|
-
"px-[var(--textarea-padding-x)] py-[var(--textarea-padding-y)] text-[length:var(--textarea-font-size)] text-foreground
|
|
2343
|
+
"flex min-h-[var(--textarea-min-height)] w-full resize-y rounded-[var(--textarea-radius)]",
|
|
2344
|
+
"px-[var(--textarea-padding-x)] py-[var(--textarea-padding-y)] text-[length:var(--textarea-font-size)] text-foreground",
|
|
2186
2345
|
"transition-[background-color,border-color,box-shadow,color] duration-micro ease-out placeholder:text-muted-foreground",
|
|
2187
|
-
formControlFocusClassNames.textarea,
|
|
2346
|
+
tone === "bordered" ? `border border-input bg-background ${formControlFocusClassNames.textarea}` : "border-0 bg-transparent shadow-none",
|
|
2188
2347
|
"disabled:cursor-not-allowed disabled:opacity-50 read-only:cursor-default read-only:bg-muted/70",
|
|
2189
2348
|
formControlInvalidClassNames.textarea,
|
|
2190
2349
|
className
|
|
@@ -2290,6 +2449,17 @@ function MarkdownRenderer({ content, className }) {
|
|
|
2290
2449
|
}
|
|
2291
2450
|
) });
|
|
2292
2451
|
}
|
|
2452
|
+
var DEFAULT_MARKDOWN_EDITOR_LABELS = {
|
|
2453
|
+
bold: "Bold (Ctrl+B)",
|
|
2454
|
+
italic: "Italic (Ctrl+I)",
|
|
2455
|
+
inlineCode: "Inline code",
|
|
2456
|
+
heading: "Heading",
|
|
2457
|
+
blockQuote: "Block quote",
|
|
2458
|
+
bulletList: "Bullet list",
|
|
2459
|
+
link: "Link",
|
|
2460
|
+
image: "Image",
|
|
2461
|
+
fencedCodeBlock: "Fenced code block"
|
|
2462
|
+
};
|
|
2293
2463
|
function QuoteGlyph(props) {
|
|
2294
2464
|
return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 16 16", fill: "currentColor", "aria-hidden": "true", className: props.className, children: [
|
|
2295
2465
|
/* @__PURE__ */ jsx("title", { children: "Block quote" }),
|
|
@@ -2298,11 +2468,15 @@ function QuoteGlyph(props) {
|
|
|
2298
2468
|
}
|
|
2299
2469
|
function MarkdownEditor({
|
|
2300
2470
|
value,
|
|
2301
|
-
|
|
2471
|
+
onValueChange,
|
|
2472
|
+
onChange: legacyOnChange,
|
|
2302
2473
|
placeholder = "Write your answer here\u2026",
|
|
2303
2474
|
minHeight = 250,
|
|
2304
|
-
className
|
|
2475
|
+
className,
|
|
2476
|
+
labels
|
|
2305
2477
|
}) {
|
|
2478
|
+
const onChange = onValueChange ?? legacyOnChange;
|
|
2479
|
+
const mergedLabels = { ...DEFAULT_MARKDOWN_EDITOR_LABELS, ...labels };
|
|
2306
2480
|
const [tab, setTab] = useState("write");
|
|
2307
2481
|
const textareaRef = useRef(null);
|
|
2308
2482
|
const insertMarkdown = useCallback(
|
|
@@ -2342,14 +2516,42 @@ function MarkdownEditor({
|
|
|
2342
2516
|
] })
|
|
2343
2517
|
] }),
|
|
2344
2518
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
2345
|
-
/* @__PURE__ */ jsx(ToolbarButton, { "aria-label": "Bold (Ctrl+B)", onClick: () => insertMarkdown("**", "**"), children: /* @__PURE__ */ jsx(TextBold, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) }),
|
|
2346
|
-
/* @__PURE__ */ jsx(ToolbarButton, { "aria-label": "Italic (Ctrl+I)", onClick: () => insertMarkdown("*", "*"), children: /* @__PURE__ */ jsx(TextItalic, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) }),
|
|
2347
|
-
/* @__PURE__ */ jsx(ToolbarButton, { "aria-label": "Inline code", onClick: () => insertMarkdown("`", "`"), children: /* @__PURE__ */ jsx(Code, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) }),
|
|
2348
|
-
/* @__PURE__ */ jsx(ToolbarButton, { "aria-label": "Heading", onClick: () => insertMarkdown("\n## ", "", true), children: /* @__PURE__ */ jsx(Hash, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) }),
|
|
2349
2519
|
/* @__PURE__ */ jsx(
|
|
2350
2520
|
ToolbarButton,
|
|
2351
2521
|
{
|
|
2352
|
-
"aria-label":
|
|
2522
|
+
"aria-label": mergedLabels.bold,
|
|
2523
|
+
onClick: () => insertMarkdown("**", "**"),
|
|
2524
|
+
children: /* @__PURE__ */ jsx(TextBold, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
|
|
2525
|
+
}
|
|
2526
|
+
),
|
|
2527
|
+
/* @__PURE__ */ jsx(
|
|
2528
|
+
ToolbarButton,
|
|
2529
|
+
{
|
|
2530
|
+
"aria-label": mergedLabels.italic,
|
|
2531
|
+
onClick: () => insertMarkdown("*", "*"),
|
|
2532
|
+
children: /* @__PURE__ */ jsx(TextItalic, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
|
|
2533
|
+
}
|
|
2534
|
+
),
|
|
2535
|
+
/* @__PURE__ */ jsx(
|
|
2536
|
+
ToolbarButton,
|
|
2537
|
+
{
|
|
2538
|
+
"aria-label": mergedLabels.inlineCode,
|
|
2539
|
+
onClick: () => insertMarkdown("`", "`"),
|
|
2540
|
+
children: /* @__PURE__ */ jsx(Code, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
|
|
2541
|
+
}
|
|
2542
|
+
),
|
|
2543
|
+
/* @__PURE__ */ jsx(
|
|
2544
|
+
ToolbarButton,
|
|
2545
|
+
{
|
|
2546
|
+
"aria-label": mergedLabels.heading,
|
|
2547
|
+
onClick: () => insertMarkdown("\n## ", "", true),
|
|
2548
|
+
children: /* @__PURE__ */ jsx(Hash, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
|
|
2549
|
+
}
|
|
2550
|
+
),
|
|
2551
|
+
/* @__PURE__ */ jsx(
|
|
2552
|
+
ToolbarButton,
|
|
2553
|
+
{
|
|
2554
|
+
"aria-label": mergedLabels.blockQuote,
|
|
2353
2555
|
onClick: () => insertMarkdown("\n> ", "", true),
|
|
2354
2556
|
children: /* @__PURE__ */ jsx(QuoteGlyph, { className: "h-3.5 w-3.5" })
|
|
2355
2557
|
}
|
|
@@ -2357,17 +2559,31 @@ function MarkdownEditor({
|
|
|
2357
2559
|
/* @__PURE__ */ jsx(
|
|
2358
2560
|
ToolbarButton,
|
|
2359
2561
|
{
|
|
2360
|
-
"aria-label":
|
|
2562
|
+
"aria-label": mergedLabels.bulletList,
|
|
2361
2563
|
onClick: () => insertMarkdown("\n- ", "", true),
|
|
2362
2564
|
children: /* @__PURE__ */ jsx(ListUnordered, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
|
|
2363
2565
|
}
|
|
2364
2566
|
),
|
|
2365
|
-
/* @__PURE__ */ jsx(ToolbarButton, { "aria-label": "Link", onClick: () => insertMarkdown("[", "](url)"), children: /* @__PURE__ */ jsx(Link, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) }),
|
|
2366
|
-
/* @__PURE__ */ jsx(ToolbarButton, { "aria-label": "Image", onClick: () => insertMarkdown(""), children: /* @__PURE__ */ jsx(Image, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) }),
|
|
2367
2567
|
/* @__PURE__ */ jsx(
|
|
2368
2568
|
ToolbarButton,
|
|
2369
2569
|
{
|
|
2370
|
-
"aria-label":
|
|
2570
|
+
"aria-label": mergedLabels.link,
|
|
2571
|
+
onClick: () => insertMarkdown("[", "](url)"),
|
|
2572
|
+
children: /* @__PURE__ */ jsx(Link, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
|
|
2573
|
+
}
|
|
2574
|
+
),
|
|
2575
|
+
/* @__PURE__ */ jsx(
|
|
2576
|
+
ToolbarButton,
|
|
2577
|
+
{
|
|
2578
|
+
"aria-label": mergedLabels.image,
|
|
2579
|
+
onClick: () => insertMarkdown(""),
|
|
2580
|
+
children: /* @__PURE__ */ jsx(Image, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
|
|
2581
|
+
}
|
|
2582
|
+
),
|
|
2583
|
+
/* @__PURE__ */ jsx(
|
|
2584
|
+
ToolbarButton,
|
|
2585
|
+
{
|
|
2586
|
+
"aria-label": mergedLabels.fencedCodeBlock,
|
|
2371
2587
|
onClick: () => insertMarkdown("\n```javascript\n", "\n```\n", true),
|
|
2372
2588
|
children: /* @__PURE__ */ jsx(FileText, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
|
|
2373
2589
|
}
|
|
@@ -2381,7 +2597,8 @@ function MarkdownEditor({
|
|
|
2381
2597
|
value,
|
|
2382
2598
|
onChange: (e) => onChange(e.target.value),
|
|
2383
2599
|
placeholder,
|
|
2384
|
-
|
|
2600
|
+
tone: "bare",
|
|
2601
|
+
className: "resize-none rounded-none font-mono text-sm",
|
|
2385
2602
|
style: { minHeight }
|
|
2386
2603
|
}
|
|
2387
2604
|
) }),
|
|
@@ -2416,34 +2633,6 @@ function ToolbarButton({
|
|
|
2416
2633
|
}
|
|
2417
2634
|
);
|
|
2418
2635
|
}
|
|
2419
|
-
var Card2 = ({
|
|
2420
|
-
className,
|
|
2421
|
-
ref,
|
|
2422
|
-
...props
|
|
2423
|
-
}) => /* @__PURE__ */ jsx(
|
|
2424
|
-
"div",
|
|
2425
|
-
{
|
|
2426
|
-
ref,
|
|
2427
|
-
className: cn(
|
|
2428
|
-
"rounded-[var(--radius-lg)] border border-border bg-card text-card-foreground shadow-sm",
|
|
2429
|
-
className
|
|
2430
|
-
),
|
|
2431
|
-
...props
|
|
2432
|
-
}
|
|
2433
|
-
);
|
|
2434
|
-
Card2.displayName = "Card";
|
|
2435
|
-
var CardHeader2 = ({
|
|
2436
|
-
className,
|
|
2437
|
-
ref,
|
|
2438
|
-
...props
|
|
2439
|
-
}) => /* @__PURE__ */ jsx("div", { ref, className: cn("flex flex-col space-y-1.5 p-6", className), ...props });
|
|
2440
|
-
CardHeader2.displayName = "CardHeader";
|
|
2441
|
-
var CardContent = ({
|
|
2442
|
-
className,
|
|
2443
|
-
ref,
|
|
2444
|
-
...props
|
|
2445
|
-
}) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props });
|
|
2446
|
-
CardContent.displayName = "CardContent";
|
|
2447
2636
|
var Separator = ({
|
|
2448
2637
|
className,
|
|
2449
2638
|
orientation = "horizontal",
|
|
@@ -2472,7 +2661,7 @@ var sizeClasses = {
|
|
|
2472
2661
|
xl: { root: "h-20 w-20", fallback: "text-2xl" }
|
|
2473
2662
|
};
|
|
2474
2663
|
var numericAvatarClass = "h-[var(--avatar-size)] w-[var(--avatar-size)]";
|
|
2475
|
-
var AvatarContext =
|
|
2664
|
+
var AvatarContext = React10.createContext(null);
|
|
2476
2665
|
function isPresetSize(size) {
|
|
2477
2666
|
return typeof size === "string";
|
|
2478
2667
|
}
|
|
@@ -2574,7 +2763,7 @@ var AvatarFallback = ({
|
|
|
2574
2763
|
ref,
|
|
2575
2764
|
...props
|
|
2576
2765
|
}) => {
|
|
2577
|
-
const context =
|
|
2766
|
+
const context = React10.use(AvatarContext);
|
|
2578
2767
|
const resolvedSize = size ?? context?.size ?? "md";
|
|
2579
2768
|
const fallbackLabel = ariaLabel ?? (typeof children === "string" && children.trim().length > 0 ? `Avatar with initials: ${children}` : context?.title);
|
|
2580
2769
|
return /* @__PURE__ */ jsx(
|
|
@@ -2616,9 +2805,10 @@ function UserInfo({ author, timestamp, verb = "asked", className }) {
|
|
|
2616
2805
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
2617
2806
|
/* @__PURE__ */ jsx("span", { className: "font-medium text-foreground text-sm", children: author.name }),
|
|
2618
2807
|
/* @__PURE__ */ jsx("span", { className: "font-bold text-muted-foreground text-xs tabular-nums", children: author.reputation.toLocaleString() }),
|
|
2619
|
-
author.badges.gold > 0 && /* @__PURE__ */ jsx(Badge2, { color: "bg-
|
|
2620
|
-
author.badges.silver > 0 && /* @__PURE__ */ jsx(Badge2, { color: "bg-
|
|
2621
|
-
author.badges.bronze > 0 &&
|
|
2808
|
+
author.badges.gold > 0 && /* @__PURE__ */ jsx(Badge2, { color: "bg-warning", count: author.badges.gold, label: "gold" }),
|
|
2809
|
+
author.badges.silver > 0 && /* @__PURE__ */ jsx(Badge2, { color: "bg-neutral-9", count: author.badges.silver, label: "silver" }),
|
|
2810
|
+
author.badges.bronze > 0 && // allow-palette: bronze medal tier has no design-system equivalent; amber-600 is the closest fixed hue and is distinct from the gold (warning) dot above
|
|
2811
|
+
/* @__PURE__ */ jsx(Badge2, { color: "bg-amber-600", count: author.badges.bronze, label: "bronze" })
|
|
2622
2812
|
] })
|
|
2623
2813
|
] })
|
|
2624
2814
|
]
|
|
@@ -2649,7 +2839,7 @@ function VoteButtons({
|
|
|
2649
2839
|
size = "default",
|
|
2650
2840
|
label = "post"
|
|
2651
2841
|
}) {
|
|
2652
|
-
const
|
|
2842
|
+
const iconSize2 = size === "large" ? "h-5 w-5" : "h-4 w-4";
|
|
2653
2843
|
const scoreSize = size === "large" ? "text-lg" : "text-base";
|
|
2654
2844
|
const score = votes + voteDelta(userVote);
|
|
2655
2845
|
return /* @__PURE__ */ jsxs("fieldset", { className: "flex flex-col items-center gap-2", children: [
|
|
@@ -2667,7 +2857,7 @@ function VoteButtons({
|
|
|
2667
2857
|
"aria-pressed": userVote === "up",
|
|
2668
2858
|
onClick: () => onVote("up"),
|
|
2669
2859
|
className: cn("p-2", userVote === "up" && "bg-primary/10 text-primary hover:bg-primary/15"),
|
|
2670
|
-
children: /* @__PURE__ */ jsx(ChevronUp, { className:
|
|
2860
|
+
children: /* @__PURE__ */ jsx(ChevronUp, { className: iconSize2, "aria-hidden": "true" })
|
|
2671
2861
|
}
|
|
2672
2862
|
),
|
|
2673
2863
|
/* @__PURE__ */ jsx(
|
|
@@ -2697,7 +2887,7 @@ function VoteButtons({
|
|
|
2697
2887
|
"p-2",
|
|
2698
2888
|
userVote === "down" && "bg-muted text-muted-foreground hover:bg-muted"
|
|
2699
2889
|
),
|
|
2700
|
-
children: /* @__PURE__ */ jsx(ChevronDown, { className:
|
|
2890
|
+
children: /* @__PURE__ */ jsx(ChevronDown, { className: iconSize2, "aria-hidden": "true" })
|
|
2701
2891
|
}
|
|
2702
2892
|
)
|
|
2703
2893
|
] });
|
|
@@ -2770,7 +2960,7 @@ function QAPage({
|
|
|
2770
2960
|
return bScore - aScore;
|
|
2771
2961
|
});
|
|
2772
2962
|
}, [answers]);
|
|
2773
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("mx-auto w-full max-w-
|
|
2963
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("mx-auto w-full max-w-content p-4 md:p-6", className), children: [
|
|
2774
2964
|
/* @__PURE__ */ jsxs("header", { className: "mb-6", children: [
|
|
2775
2965
|
/* @__PURE__ */ jsx("h1", { className: "mb-4 font-bold text-2xl leading-tight text-foreground", children: question.title }),
|
|
2776
2966
|
/* @__PURE__ */ jsxs("div", { className: "mb-4 flex items-center gap-4 text-muted-foreground text-sm", children: [
|
|
@@ -2788,7 +2978,7 @@ function QAPage({
|
|
|
2788
2978
|
] }),
|
|
2789
2979
|
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: question.tags.map((tag) => /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-xs", children: tag }, tag)) })
|
|
2790
2980
|
] }),
|
|
2791
|
-
/* @__PURE__ */ jsx(
|
|
2981
|
+
/* @__PURE__ */ jsx(Card, { className: "mb-8", children: /* @__PURE__ */ jsxs(CardContent, { className: "flex gap-6 p-6", children: [
|
|
2792
2982
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-4", children: [
|
|
2793
2983
|
/* @__PURE__ */ jsx(
|
|
2794
2984
|
VoteButtons,
|
|
@@ -2809,7 +2999,7 @@ function QAPage({
|
|
|
2809
2999
|
"aria-label": question.bookmarked ? "Remove bookmark" : "Bookmark question",
|
|
2810
3000
|
"aria-pressed": question.bookmarked,
|
|
2811
3001
|
onClick: handleBookmarkToggle,
|
|
2812
|
-
className: cn("p-2", question.bookmarked && "bg-warning/10 text-warning"),
|
|
3002
|
+
className: cn("p-2", question.bookmarked && "bg-warning/10 text-warning-strong"),
|
|
2813
3003
|
children: /* @__PURE__ */ jsx(Bookmark, { className: "h-4 w-4", "aria-hidden": "true" })
|
|
2814
3004
|
}
|
|
2815
3005
|
)
|
|
@@ -2836,7 +3026,7 @@ function QAPage({
|
|
|
2836
3026
|
answers.length === 1 ? "Answer" : "Answers"
|
|
2837
3027
|
] }) }),
|
|
2838
3028
|
/* @__PURE__ */ jsx("div", { className: "mb-8", children: sortedAnswers.map((answer, index) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2839
|
-
/* @__PURE__ */ jsx(
|
|
3029
|
+
/* @__PURE__ */ jsx(Card, { className: cn("mb-6", answer.isAccepted && "ring-2 ring-success/40"), children: /* @__PURE__ */ jsxs(CardContent, { className: "flex gap-6 p-6", children: [
|
|
2840
3030
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-4", children: [
|
|
2841
3031
|
/* @__PURE__ */ jsx(
|
|
2842
3032
|
VoteButtons,
|
|
@@ -2857,13 +3047,19 @@ function QAPage({
|
|
|
2857
3047
|
"aria-label": answer.isAccepted ? "Unaccept this answer" : "Accept this answer",
|
|
2858
3048
|
"aria-pressed": answer.isAccepted,
|
|
2859
3049
|
onClick: () => handleAccept(answer.id),
|
|
2860
|
-
className: cn("p-2", answer.isAccepted && "bg-success/10 text-success"),
|
|
3050
|
+
className: cn("p-2", answer.isAccepted && "bg-success/10 text-success-strong"),
|
|
2861
3051
|
children: /* @__PURE__ */ jsx(Check, { className: "h-5 w-5", "aria-hidden": "true" })
|
|
2862
3052
|
}
|
|
2863
3053
|
),
|
|
2864
3054
|
answer.isAccepted && /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
2865
|
-
/* @__PURE__ */ jsx(
|
|
2866
|
-
|
|
3055
|
+
/* @__PURE__ */ jsx(
|
|
3056
|
+
StarFill,
|
|
3057
|
+
{
|
|
3058
|
+
"aria-hidden": "true",
|
|
3059
|
+
className: "mx-auto mb-1 h-4 w-4 text-success-strong"
|
|
3060
|
+
}
|
|
3061
|
+
),
|
|
3062
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-success-strong text-xs", children: "Accepted" })
|
|
2867
3063
|
] })
|
|
2868
3064
|
] }),
|
|
2869
3065
|
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [
|
|
@@ -2884,10 +3080,17 @@ function QAPage({
|
|
|
2884
3080
|
] }) }),
|
|
2885
3081
|
index < sortedAnswers.length - 1 && /* @__PURE__ */ jsx(Separator, { className: "mb-6" })
|
|
2886
3082
|
] }, answer.id)) }),
|
|
2887
|
-
/* @__PURE__ */ jsxs(
|
|
2888
|
-
/* @__PURE__ */ jsx(
|
|
3083
|
+
/* @__PURE__ */ jsxs(Card, { children: [
|
|
3084
|
+
/* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsx("h3", { className: "font-semibold text-foreground text-lg", children: "Your Answer" }) }),
|
|
2889
3085
|
/* @__PURE__ */ jsxs(CardContent, { className: "space-y-4", children: [
|
|
2890
|
-
/* @__PURE__ */ jsx(
|
|
3086
|
+
/* @__PURE__ */ jsx(
|
|
3087
|
+
MarkdownEditor,
|
|
3088
|
+
{
|
|
3089
|
+
value: draft,
|
|
3090
|
+
onValueChange: setDraft,
|
|
3091
|
+
placeholder: "Write your answer here\u2026"
|
|
3092
|
+
}
|
|
3093
|
+
),
|
|
2891
3094
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
2892
3095
|
/* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-xs", children: "Thanks for contributing an answer!" }),
|
|
2893
3096
|
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
@@ -2935,7 +3138,7 @@ function PostActions({
|
|
|
2935
3138
|
/* @__PURE__ */ jsx(UserInfo, { author, timestamp, verb })
|
|
2936
3139
|
] });
|
|
2937
3140
|
}
|
|
2938
|
-
var CollapsibleContext =
|
|
3141
|
+
var CollapsibleContext = React10.createContext({});
|
|
2939
3142
|
var Collapsible = ({
|
|
2940
3143
|
className,
|
|
2941
3144
|
open: openProp,
|
|
@@ -2946,10 +3149,10 @@ var Collapsible = ({
|
|
|
2946
3149
|
ref,
|
|
2947
3150
|
...props
|
|
2948
3151
|
}) => {
|
|
2949
|
-
const [uncontrolledOpen, setUncontrolledOpen] =
|
|
3152
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React10.useState(defaultOpen || false);
|
|
2950
3153
|
const isControlled = openProp !== void 0;
|
|
2951
3154
|
const open = isControlled ? openProp : uncontrolledOpen;
|
|
2952
|
-
const handleOpenChange =
|
|
3155
|
+
const handleOpenChange = React10.useCallback(
|
|
2953
3156
|
(nextOpen) => {
|
|
2954
3157
|
if (!isControlled) {
|
|
2955
3158
|
setUncontrolledOpen(nextOpen);
|
|
@@ -2978,8 +3181,8 @@ var CollapsibleTrigger = ({
|
|
|
2978
3181
|
ref,
|
|
2979
3182
|
...props
|
|
2980
3183
|
}) => {
|
|
2981
|
-
const { open, onOpenChange, disabled } =
|
|
2982
|
-
const handleClick =
|
|
3184
|
+
const { open, onOpenChange, disabled } = React10.use(CollapsibleContext);
|
|
3185
|
+
const handleClick = React10.useCallback(
|
|
2983
3186
|
(e) => {
|
|
2984
3187
|
if (disabled) return;
|
|
2985
3188
|
onOpenChange?.(!open);
|
|
@@ -2987,8 +3190,8 @@ var CollapsibleTrigger = ({
|
|
|
2987
3190
|
},
|
|
2988
3191
|
[disabled, open, onOpenChange, props.onClick]
|
|
2989
3192
|
);
|
|
2990
|
-
if (asChild &&
|
|
2991
|
-
return
|
|
3193
|
+
if (asChild && React10.isValidElement(children)) {
|
|
3194
|
+
return React10.cloneElement(children, {
|
|
2992
3195
|
ref,
|
|
2993
3196
|
onClick: handleClick,
|
|
2994
3197
|
"data-state": open ? "open" : "closed",
|
|
@@ -3022,7 +3225,7 @@ var CollapsibleContent = ({
|
|
|
3022
3225
|
ref,
|
|
3023
3226
|
...props
|
|
3024
3227
|
}) => {
|
|
3025
|
-
const { open } =
|
|
3228
|
+
const { open } = React10.use(CollapsibleContext);
|
|
3026
3229
|
const shouldReduceMotion = useReducedMotion();
|
|
3027
3230
|
return /* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: open && /* @__PURE__ */ jsx(
|
|
3028
3231
|
motion.div,
|
|
@@ -3042,9 +3245,9 @@ var CollapsibleContent = ({
|
|
|
3042
3245
|
) });
|
|
3043
3246
|
};
|
|
3044
3247
|
CollapsibleContent.displayName = "CollapsibleContent";
|
|
3045
|
-
var ITEM_BASE_CLASSES = "group flex min-h-8 items-center gap-2 rounded-[var(--radius-md)] px-2.5 py-1.5 text-[13px] leading-5 transition-[background-color,color,box-shadow,transform]";
|
|
3046
|
-
var ITEM_DEFAULT_CLASSES = "text-sidebar-foreground/72 hover:bg-sidebar-accent hover:text-sidebar-
|
|
3047
|
-
var ITEM_ACTIVE_CLASSES = "bg-sidebar-
|
|
3248
|
+
var ITEM_BASE_CLASSES = "group flex min-h-8 items-center gap-2 rounded-[var(--radius-md)] px-2.5 py-1.5 text-[13px] leading-5 transition-[background-color,color,box-shadow,transform] duration-micro ease-brand";
|
|
3249
|
+
var ITEM_DEFAULT_CLASSES = "text-sidebar-foreground/72 hover:bg-sidebar-accent/55 hover:text-sidebar-foreground";
|
|
3250
|
+
var ITEM_ACTIVE_CLASSES = "bg-sidebar-accent text-sidebar-foreground font-medium shadow-[inset_0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent";
|
|
3048
3251
|
var ITEM_DISABLED_CLASSES = "opacity-50 pointer-events-none";
|
|
3049
3252
|
var ITEM_COLLAPSED_CLASSES = "justify-center px-0 size-8 mx-auto";
|
|
3050
3253
|
var ICON_CLASSES = "size-4 shrink-0";
|
|
@@ -3077,19 +3280,19 @@ function ItemContent({
|
|
|
3077
3280
|
const Icon = item.icon;
|
|
3078
3281
|
if (collapsed) {
|
|
3079
3282
|
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
3080
|
-
Icon ? /* @__PURE__ */ jsx(Icon, { className: ICON_CLASSES }) : null,
|
|
3283
|
+
Icon ? /* @__PURE__ */ jsx(Icon, { className: cn(ICON_CLASSES, item.isActive && "text-sidebar-primary") }) : null,
|
|
3081
3284
|
/* @__PURE__ */ jsx("span", { className: "sr-only", children: item.label })
|
|
3082
3285
|
] });
|
|
3083
3286
|
}
|
|
3084
3287
|
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
3085
|
-
Icon ? /* @__PURE__ */ jsx(Icon, { className: ICON_CLASSES }) : null,
|
|
3288
|
+
Icon ? /* @__PURE__ */ jsx(Icon, { className: cn(ICON_CLASSES, item.isActive && "text-sidebar-primary") }) : null,
|
|
3086
3289
|
/* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: item.label }),
|
|
3087
3290
|
item.badge ? /* @__PURE__ */ jsx(Badge, { variant: item.badge.tone, size: "sm", children: item.badge.label }) : null,
|
|
3088
3291
|
showChevron ? /* @__PURE__ */ jsx(
|
|
3089
3292
|
ChevronRight,
|
|
3090
3293
|
{
|
|
3091
3294
|
className: cn(
|
|
3092
|
-
"size-3.5 shrink-0 text-
|
|
3295
|
+
"size-3.5 shrink-0 text-sidebar-foreground/50 transition-transform duration-micro ease-brand",
|
|
3093
3296
|
chevronOpen && "rotate-90"
|
|
3094
3297
|
),
|
|
3095
3298
|
"aria-hidden": "true"
|
|
@@ -3173,12 +3376,12 @@ function ParentItem({
|
|
|
3173
3376
|
renderLink
|
|
3174
3377
|
}) {
|
|
3175
3378
|
const hasActiveChild = item.children?.some((c) => c.isActive === true) ?? false;
|
|
3176
|
-
const [uncontrolledOpen, setUncontrolledOpen] =
|
|
3379
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React10.useState(
|
|
3177
3380
|
item.isActive === true || hasActiveChild
|
|
3178
3381
|
);
|
|
3179
3382
|
const isControlled = item.expanded !== void 0 && item.onExpandedChange !== void 0;
|
|
3180
3383
|
const open = isControlled ? item.expanded : uncontrolledOpen;
|
|
3181
|
-
const setOpen =
|
|
3384
|
+
const setOpen = React10.useCallback(
|
|
3182
3385
|
(next) => {
|
|
3183
3386
|
if (isControlled) {
|
|
3184
3387
|
item.onExpandedChange?.(next);
|
|
@@ -3237,12 +3440,13 @@ function SidebarNav({
|
|
|
3237
3440
|
itemClassName,
|
|
3238
3441
|
header,
|
|
3239
3442
|
footer,
|
|
3240
|
-
renderLink = defaultRenderLink
|
|
3443
|
+
renderLink = defaultRenderLink,
|
|
3444
|
+
navLabel = "Sidebar"
|
|
3241
3445
|
}) {
|
|
3242
3446
|
return /* @__PURE__ */ jsx(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs(
|
|
3243
3447
|
"nav",
|
|
3244
3448
|
{
|
|
3245
|
-
"aria-label":
|
|
3449
|
+
"aria-label": navLabel,
|
|
3246
3450
|
"data-ui": "nebutra-sidebar-nav",
|
|
3247
3451
|
className: cn(
|
|
3248
3452
|
"flex h-full flex-col",
|
|
@@ -3299,13 +3503,13 @@ function SidebarNav({
|
|
|
3299
3503
|
}
|
|
3300
3504
|
) });
|
|
3301
3505
|
}
|
|
3302
|
-
var TerminalContext =
|
|
3303
|
-
var
|
|
3506
|
+
var TerminalContext = React10.createContext(null);
|
|
3507
|
+
var variantStyles = {
|
|
3304
3508
|
default: "bg-muted border border-border",
|
|
3305
3509
|
minimal: "bg-background border border-border",
|
|
3306
3510
|
glass: "bg-muted backdrop-blur-md border border-border"
|
|
3307
3511
|
};
|
|
3308
|
-
var TerminalRoot =
|
|
3512
|
+
var TerminalRoot = React10.forwardRef(
|
|
3309
3513
|
({ className, variant = "default", children, ...props }, ref) => {
|
|
3310
3514
|
return /* @__PURE__ */ jsx(TerminalContext.Provider, { value: { variant }, children: /* @__PURE__ */ jsx(
|
|
3311
3515
|
"div",
|
|
@@ -3313,7 +3517,7 @@ var TerminalRoot = React.forwardRef(
|
|
|
3313
3517
|
ref,
|
|
3314
3518
|
className: cn(
|
|
3315
3519
|
"rounded-[var(--radius-xl)] overflow-hidden font-mono text-sm",
|
|
3316
|
-
|
|
3520
|
+
variantStyles[variant],
|
|
3317
3521
|
className
|
|
3318
3522
|
),
|
|
3319
3523
|
...props,
|
|
@@ -3323,7 +3527,7 @@ var TerminalRoot = React.forwardRef(
|
|
|
3323
3527
|
}
|
|
3324
3528
|
);
|
|
3325
3529
|
TerminalRoot.displayName = "Terminal";
|
|
3326
|
-
var TerminalHeader =
|
|
3530
|
+
var TerminalHeader = React10.forwardRef(
|
|
3327
3531
|
({ className, title, showControls = true, children, ...props }, ref) => {
|
|
3328
3532
|
return /* @__PURE__ */ jsxs(
|
|
3329
3533
|
"div",
|
|
@@ -3348,13 +3552,13 @@ var TerminalHeader = React.forwardRef(
|
|
|
3348
3552
|
}
|
|
3349
3553
|
);
|
|
3350
3554
|
TerminalHeader.displayName = "Terminal.Header";
|
|
3351
|
-
var TerminalBody =
|
|
3555
|
+
var TerminalBody = React10.forwardRef(
|
|
3352
3556
|
({ className, children, ...props }, ref) => {
|
|
3353
3557
|
return /* @__PURE__ */ jsx("div", { ref, className: cn("p-4 space-y-1", className), ...props, children });
|
|
3354
3558
|
}
|
|
3355
3559
|
);
|
|
3356
3560
|
TerminalBody.displayName = "Terminal.Body";
|
|
3357
|
-
var TerminalLine =
|
|
3561
|
+
var TerminalLine = React10.forwardRef(
|
|
3358
3562
|
({ className, prompt = "$", output = false, highlight = false, children, ...props }, ref) => {
|
|
3359
3563
|
return /* @__PURE__ */ jsxs(
|
|
3360
3564
|
"div",
|
|
@@ -3367,7 +3571,7 @@ var TerminalLine = React.forwardRef(
|
|
|
3367
3571
|
),
|
|
3368
3572
|
...props,
|
|
3369
3573
|
children: [
|
|
3370
|
-
!output && /* @__PURE__ */ jsx("span", { className: "text-
|
|
3574
|
+
!output && /* @__PURE__ */ jsx("span", { className: "text-success-strong shrink-0 select-none", children: prompt }),
|
|
3371
3575
|
/* @__PURE__ */ jsx("span", { className: cn("flex-1", output ? "text-muted-foreground" : "text-muted-foreground"), children })
|
|
3372
3576
|
]
|
|
3373
3577
|
}
|
|
@@ -3409,7 +3613,7 @@ function subscribePlatform() {
|
|
|
3409
3613
|
return () => void 0;
|
|
3410
3614
|
}
|
|
3411
3615
|
function usePlatform() {
|
|
3412
|
-
return
|
|
3616
|
+
return React10.useSyncExternalStore(subscribePlatform, getClientPlatform, () => "apple");
|
|
3413
3617
|
}
|
|
3414
3618
|
function normalizeKey(children) {
|
|
3415
3619
|
if (typeof children !== "string") {
|
|
@@ -3483,13 +3687,16 @@ function computeInitials(user) {
|
|
|
3483
3687
|
}
|
|
3484
3688
|
return source.slice(0, 2).toUpperCase();
|
|
3485
3689
|
}
|
|
3486
|
-
function DefaultTrigger({
|
|
3690
|
+
function DefaultTrigger({
|
|
3691
|
+
user,
|
|
3692
|
+
triggerLabel = "Open user menu"
|
|
3693
|
+
}) {
|
|
3487
3694
|
const initials2 = computeInitials(user);
|
|
3488
3695
|
return /* @__PURE__ */ jsx(
|
|
3489
3696
|
"button",
|
|
3490
3697
|
{
|
|
3491
3698
|
type: "button",
|
|
3492
|
-
"aria-label":
|
|
3699
|
+
"aria-label": triggerLabel,
|
|
3493
3700
|
className: cn(
|
|
3494
3701
|
"inline-flex h-8 w-8 shrink-0 items-center justify-center overflow-hidden rounded-full",
|
|
3495
3702
|
"outline-none transition-[box-shadow,opacity] hover:opacity-90",
|
|
@@ -3498,7 +3705,7 @@ function DefaultTrigger({ user }) {
|
|
|
3498
3705
|
),
|
|
3499
3706
|
children: /* @__PURE__ */ jsxs(Avatar, { size: "sm", children: [
|
|
3500
3707
|
user.avatarUrl ? /* @__PURE__ */ jsx(AvatarImage, { src: user.avatarUrl, alt: user.name }) : null,
|
|
3501
|
-
/* @__PURE__ */ jsx(AvatarFallback, { size: "sm", className: "bg-primary text-
|
|
3708
|
+
/* @__PURE__ */ jsx(AvatarFallback, { size: "sm", className: "bg-primary text-primary-foreground", children: initials2 })
|
|
3502
3709
|
] })
|
|
3503
3710
|
}
|
|
3504
3711
|
);
|
|
@@ -3519,16 +3726,17 @@ function UserMenu(props) {
|
|
|
3519
3726
|
renderTrigger,
|
|
3520
3727
|
renderLink,
|
|
3521
3728
|
className,
|
|
3522
|
-
align = "end"
|
|
3729
|
+
align = "end",
|
|
3730
|
+
triggerLabel
|
|
3523
3731
|
} = props;
|
|
3524
3732
|
const initials2 = computeInitials(user);
|
|
3525
3733
|
return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
3526
|
-
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: renderTrigger ? renderTrigger(user) : /* @__PURE__ */ jsx(DefaultTrigger, { user }) }),
|
|
3734
|
+
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: renderTrigger ? renderTrigger(user) : /* @__PURE__ */ jsx(DefaultTrigger, { user, ...triggerLabel !== void 0 ? { triggerLabel } : {} }) }),
|
|
3527
3735
|
/* @__PURE__ */ jsxs(DropdownMenuContent, { align, sideOffset: 8, className: cn("w-[280px] p-1", className), children: [
|
|
3528
3736
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 p-3", children: [
|
|
3529
3737
|
/* @__PURE__ */ jsxs(Avatar, { size: "md", children: [
|
|
3530
3738
|
user.avatarUrl ? /* @__PURE__ */ jsx(AvatarImage, { src: user.avatarUrl, alt: user.name }) : null,
|
|
3531
|
-
/* @__PURE__ */ jsx(AvatarFallback, { size: "md", className: "bg-primary text-
|
|
3739
|
+
/* @__PURE__ */ jsx(AvatarFallback, { size: "md", className: "bg-primary text-primary-foreground", children: initials2 })
|
|
3532
3740
|
] }),
|
|
3533
3741
|
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [
|
|
3534
3742
|
/* @__PURE__ */ jsx("span", { className: "truncate text-sm font-medium text-foreground", children: user.name }),
|
|
@@ -3542,12 +3750,12 @@ function UserMenu(props) {
|
|
|
3542
3750
|
] }) : null,
|
|
3543
3751
|
groups.map((group, groupIndex) => {
|
|
3544
3752
|
const isLastGroup = groupIndex === groups.length - 1;
|
|
3545
|
-
return /* @__PURE__ */ jsxs(
|
|
3753
|
+
return /* @__PURE__ */ jsxs(React10.Fragment, { children: [
|
|
3546
3754
|
group.label ? /* @__PURE__ */ jsx("div", { className: "px-2 py-1 text-xs font-medium uppercase tracking-wider text-muted-foreground", children: group.label }) : null,
|
|
3547
3755
|
group.items.map((item) => {
|
|
3548
3756
|
const itemClassName = cn(
|
|
3549
3757
|
"flex w-full cursor-pointer items-center",
|
|
3550
|
-
item.destructive && "text-destructive focus:bg-destructive focus:text-destructive-foreground data-[highlighted]:bg-destructive data-[highlighted]:text-destructive-foreground"
|
|
3758
|
+
item.destructive && "text-destructive-strong focus:bg-destructive focus:text-destructive-foreground data-[highlighted]:bg-destructive data-[highlighted]:text-destructive-foreground"
|
|
3551
3759
|
);
|
|
3552
3760
|
if (item.href && !item.disabled) {
|
|
3553
3761
|
const linkContent = /* @__PURE__ */ jsx(UserMenuItemContent, { item });
|
|
@@ -3619,7 +3827,7 @@ function WorkspaceAvatar({ workspace, size = "sm", className }) {
|
|
|
3619
3827
|
AvatarFallback,
|
|
3620
3828
|
{
|
|
3621
3829
|
size,
|
|
3622
|
-
className: "rounded-[var(--radius-md)] bg-primary text-
|
|
3830
|
+
className: "rounded-[var(--radius-md)] bg-primary text-primary-foreground font-semibold",
|
|
3623
3831
|
children: initials2
|
|
3624
3832
|
}
|
|
3625
3833
|
)
|
|
@@ -3631,6 +3839,7 @@ function TriggerButton({
|
|
|
3631
3839
|
showRoleBadge,
|
|
3632
3840
|
disabled,
|
|
3633
3841
|
className,
|
|
3842
|
+
switchLabel = "Switch workspace",
|
|
3634
3843
|
ref
|
|
3635
3844
|
}) {
|
|
3636
3845
|
const isOwner = activeWorkspace.role === "owner";
|
|
@@ -3640,7 +3849,7 @@ function TriggerButton({
|
|
|
3640
3849
|
{
|
|
3641
3850
|
ref,
|
|
3642
3851
|
type: "button",
|
|
3643
|
-
"aria-label":
|
|
3852
|
+
"aria-label": switchLabel,
|
|
3644
3853
|
disabled,
|
|
3645
3854
|
className: cn(
|
|
3646
3855
|
"inline-flex items-center gap-1 rounded-[var(--radius-md)] p-1 outline-none transition-colors",
|
|
@@ -3661,7 +3870,7 @@ function TriggerButton({
|
|
|
3661
3870
|
{
|
|
3662
3871
|
ref,
|
|
3663
3872
|
type: "button",
|
|
3664
|
-
"aria-label":
|
|
3873
|
+
"aria-label": switchLabel,
|
|
3665
3874
|
disabled,
|
|
3666
3875
|
className: cn(
|
|
3667
3876
|
"inline-flex w-full items-center gap-2 rounded-[var(--radius-md)] border border-border bg-background px-2 py-1 text-left outline-none transition-colors",
|
|
@@ -3696,8 +3905,8 @@ function WorkspaceItem({ workspace, isActive, onSelect }) {
|
|
|
3696
3905
|
"span",
|
|
3697
3906
|
{
|
|
3698
3907
|
className: cn(
|
|
3699
|
-
"truncate
|
|
3700
|
-
isActive ? "
|
|
3908
|
+
"truncate font-medium text-sm",
|
|
3909
|
+
isActive ? "text-foreground" : "text-foreground/80"
|
|
3701
3910
|
),
|
|
3702
3911
|
children: workspace.name
|
|
3703
3912
|
}
|
|
@@ -3722,7 +3931,8 @@ function WorkspaceSwitcher({
|
|
|
3722
3931
|
headerSlot,
|
|
3723
3932
|
className,
|
|
3724
3933
|
showRoleBadge = true,
|
|
3725
|
-
disabled = false
|
|
3934
|
+
disabled = false,
|
|
3935
|
+
switchLabel
|
|
3726
3936
|
}) {
|
|
3727
3937
|
const activeWorkspace = workspaces.find((ws) => ws.id === activeWorkspaceId) ?? workspaces[0];
|
|
3728
3938
|
const handleSelect = (id) => {
|
|
@@ -3753,7 +3963,8 @@ function WorkspaceSwitcher({
|
|
|
3753
3963
|
variant,
|
|
3754
3964
|
showRoleBadge,
|
|
3755
3965
|
disabled,
|
|
3756
|
-
className
|
|
3966
|
+
className,
|
|
3967
|
+
...switchLabel !== void 0 ? { switchLabel } : {}
|
|
3757
3968
|
}
|
|
3758
3969
|
) }),
|
|
3759
3970
|
/* @__PURE__ */ jsxs(
|