@tangle-network/ui 11.51.16 → 11.51.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/chat/thinking-indicator.js +9 -15
- package/dist/editor/tiptap-editor.js +4 -4
- package/dist/files/file-preview.js +1 -1
- package/dist/hooks/use-phone.d.ts +4 -0
- package/dist/hooks/use-phone.js +14 -0
- package/dist/hooks.d.ts +2 -1
- package/dist/hooks.js +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/openui/openui-artifact-renderer.js +7 -7
- package/dist/presentation.d.ts +1 -1
- package/dist/presentation.js +1 -1
- package/dist/primitives/artifact-pane.js +1 -1
- package/dist/primitives/heading.js +1 -1
- package/dist/primitives/progress.js +1 -1
- package/dist/primitives/sidebar-drop-zone.js +1 -1
- package/dist/primitives/stat-card.js +1 -1
- package/dist/primitives/toast.js +1 -1
- package/dist/primitives/upload-progress.js +2 -2
- package/dist/primitives/wizard.js +2 -2
- package/dist/run/expandable-content.js +1 -1
- package/dist/run/expanded-tool-detail.js +3 -3
- package/dist/run/run-group.js +11 -14
- package/dist/run/run-item-primitives.js +1 -1
- package/dist/tool-previews/command-preview.js +3 -3
- package/dist/tool-previews/diff-preview.js +2 -2
- package/dist/tool-previews/question-preview.js +1 -1
- package/package.json +1 -1
- package/src/chat/thinking-indicator.tsx +2 -4
- package/src/editor/document-editor-pane.stories.tsx +1 -1
- package/src/editor/tiptap-editor.tsx +4 -4
- package/src/files/file-preview.tsx +1 -1
- package/src/hooks/index.ts +1 -0
- package/src/hooks/use-phone.ts +18 -0
- package/src/markdown/markdown.stories.tsx +1 -1
- package/src/openui/openui-artifact-renderer.tsx +7 -7
- package/src/presentation.ts +1 -1
- package/src/primitives/artifact-pane.tsx +1 -1
- package/src/primitives/avatar.stories.tsx +3 -3
- package/src/primitives/badge.stories.tsx +3 -3
- package/src/primitives/card.stories.tsx +1 -1
- package/src/primitives/compliance-badge.stories.tsx +3 -3
- package/src/primitives/dropdown-menu.stories.tsx +1 -1
- package/src/primitives/heading.tsx +1 -1
- package/src/primitives/input.stories.tsx +2 -2
- package/src/primitives/label.stories.tsx +3 -3
- package/src/primitives/progress.stories.tsx +5 -5
- package/src/primitives/progress.tsx +1 -1
- package/src/primitives/select.stories.tsx +3 -3
- package/src/primitives/sidebar-drop-zone.stories.tsx +1 -1
- package/src/primitives/sidebar-drop-zone.tsx +1 -1
- package/src/primitives/skeleton.stories.tsx +4 -4
- package/src/primitives/stat-card.stories.tsx +22 -33
- package/src/primitives/stat-card.tsx +1 -1
- package/src/primitives/switch.stories.tsx +2 -2
- package/src/primitives/tabs.stories.tsx +3 -3
- package/src/primitives/toast.tsx +1 -1
- package/src/primitives/upload-progress.tsx +2 -2
- package/src/primitives/wizard.tsx +1 -1
- package/src/run/expandable-content.tsx +1 -1
- package/src/run/expanded-tool-detail.tsx +3 -3
- package/src/run/inline-thinking-item.stories.tsx +3 -3
- package/src/run/inline-tool-item.stories.tsx +3 -3
- package/src/run/run-group.tsx +9 -9
- package/src/run/run-item-primitives.tsx +1 -1
- package/src/styles/presentation.css +1 -1
- package/src/tool-previews/command-preview.tsx +3 -3
- package/src/tool-previews/diff-preview.tsx +2 -2
- package/src/tool-previews/question-preview.tsx +1 -1
|
@@ -299,19 +299,19 @@ function ConnectionIndicator({
|
|
|
299
299
|
}) {
|
|
300
300
|
const config = {
|
|
301
301
|
disconnected: {
|
|
302
|
-
color: "bg-
|
|
302
|
+
color: "bg-[var(--surface-danger-text)]",
|
|
303
303
|
label: "Disconnected",
|
|
304
304
|
},
|
|
305
305
|
connecting: {
|
|
306
|
-
color: "bg-
|
|
306
|
+
color: "bg-[var(--surface-warning-text)] animate-pulse motion-reduce:animate-none",
|
|
307
307
|
label: "Connecting...",
|
|
308
308
|
},
|
|
309
309
|
connected: {
|
|
310
|
-
color: "bg-
|
|
310
|
+
color: "bg-[var(--surface-info-text)]",
|
|
311
311
|
label: "Connected",
|
|
312
312
|
},
|
|
313
313
|
synced: {
|
|
314
|
-
color: "bg-
|
|
314
|
+
color: "bg-[var(--surface-success-text)]",
|
|
315
315
|
label: "Synced",
|
|
316
316
|
},
|
|
317
317
|
}[state];
|
|
@@ -379,7 +379,7 @@ export function FilePreview({
|
|
|
379
379
|
<div className="flex items-center gap-2 px-3 py-2 border-b border-border shrink-0">
|
|
380
380
|
<div className="min-w-0 flex-1">
|
|
381
381
|
<div className="truncate text-sm font-medium text-foreground">{filename}</div>
|
|
382
|
-
<div className="mt-0.5 text-
|
|
382
|
+
<div className="mt-0.5 text-xs text-muted-foreground">
|
|
383
383
|
{previewLabel}
|
|
384
384
|
</div>
|
|
385
385
|
</div>
|
package/src/hooks/index.ts
CHANGED
|
@@ -11,3 +11,4 @@ export * from "./use-sse-stream";
|
|
|
11
11
|
|
|
12
12
|
export { useEventStream, type EventStreamHandlers, type EventStreamSource, type EventStreamOpener } from "./use-event-stream";
|
|
13
13
|
export { useFollowTail } from "./use-follow-tail";
|
|
14
|
+
export { usePhone, PHONE_MEDIA } from "./use-phone";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useSyncExternalStore } from "react";
|
|
3
|
+
|
|
4
|
+
/** Below the tablet breakpoint a workspace shows one region at a time and an agent opens as a full-screen sheet. */
|
|
5
|
+
export const PHONE_MEDIA = "(max-width: 767px)";
|
|
6
|
+
|
|
7
|
+
/** Whether the page is phone-width. The server renders the desktop shape; the client corrects it on hydration. */
|
|
8
|
+
export function usePhone(media: string = PHONE_MEDIA): boolean {
|
|
9
|
+
return useSyncExternalStore(
|
|
10
|
+
(notify) => {
|
|
11
|
+
const query = window.matchMedia(media);
|
|
12
|
+
query.addEventListener("change", notify);
|
|
13
|
+
return () => query.removeEventListener("change", notify);
|
|
14
|
+
},
|
|
15
|
+
() => window.matchMedia(media).matches,
|
|
16
|
+
() => false,
|
|
17
|
+
);
|
|
18
|
+
}
|
|
@@ -30,7 +30,7 @@ Source: \`github.com/tangle-network/gtm-agent\` Live at: [gtm.tangle.tools](http
|
|
|
30
30
|
|
|
31
31
|
## What It Is
|
|
32
32
|
|
|
33
|
-
GTM Agent is
|
|
33
|
+
GTM Agent is a go-to-market workspace where founders get a sandboxed environment and an agent that works alongside them.
|
|
34
34
|
|
|
35
35
|
## Architecture
|
|
36
36
|
|
|
@@ -232,7 +232,7 @@ function renderNode(
|
|
|
232
232
|
return (
|
|
233
233
|
<div className="space-y-1">
|
|
234
234
|
{node.kicker && (
|
|
235
|
-
<div className="text-
|
|
235
|
+
<div className="text-xs font-medium text-muted-foreground">
|
|
236
236
|
{node.kicker}
|
|
237
237
|
</div>
|
|
238
238
|
)}
|
|
@@ -275,7 +275,7 @@ function renderNode(
|
|
|
275
275
|
return (
|
|
276
276
|
<Card variant="glass" className="border-border shadow-[var(--shadow-card)]">
|
|
277
277
|
<CardContent className="space-y-2 p-4">
|
|
278
|
-
<div className="text-xs
|
|
278
|
+
<div className="text-xs text-muted-foreground">
|
|
279
279
|
{node.label}
|
|
280
280
|
</div>
|
|
281
281
|
<div className="text-2xl font-semibold tracking-tight text-foreground">
|
|
@@ -310,7 +310,7 @@ function renderNode(
|
|
|
310
310
|
key={item.id ?? `${item.label}-${index}`}
|
|
311
311
|
className="rounded-[var(--radius-lg)] border border-border bg-card px-4 py-3"
|
|
312
312
|
>
|
|
313
|
-
<dt className="text-
|
|
313
|
+
<dt className="text-xs text-muted-foreground">
|
|
314
314
|
{item.label}
|
|
315
315
|
</dt>
|
|
316
316
|
<dd
|
|
@@ -330,7 +330,7 @@ function renderNode(
|
|
|
330
330
|
return (
|
|
331
331
|
<div className="space-y-2">
|
|
332
332
|
{node.title && (
|
|
333
|
-
<div className="text-xs
|
|
333
|
+
<div className="text-xs text-muted-foreground">
|
|
334
334
|
{node.title}
|
|
335
335
|
</div>
|
|
336
336
|
)}
|
|
@@ -365,7 +365,7 @@ function renderNode(
|
|
|
365
365
|
<TableHead
|
|
366
366
|
key={column.key}
|
|
367
367
|
className={cn(
|
|
368
|
-
"h-10 text-
|
|
368
|
+
"h-10 text-xs text-muted-foreground",
|
|
369
369
|
column.align === "right" && "text-right",
|
|
370
370
|
)}
|
|
371
371
|
>
|
|
@@ -408,7 +408,7 @@ function renderNode(
|
|
|
408
408
|
<div className="flex items-center gap-3">
|
|
409
409
|
<div className="h-px flex-1 bg-border" />
|
|
410
410
|
{node.label && (
|
|
411
|
-
<span className="text-
|
|
411
|
+
<span className="text-xs text-muted-foreground">
|
|
412
412
|
{node.label}
|
|
413
413
|
</span>
|
|
414
414
|
)}
|
|
@@ -460,7 +460,7 @@ function renderNode(
|
|
|
460
460
|
<div className="flex items-start justify-between gap-3">
|
|
461
461
|
<div className="min-w-0 flex-1 space-y-1">
|
|
462
462
|
{node.eyebrow && (
|
|
463
|
-
<div className="text-
|
|
463
|
+
<div className="text-xs font-medium text-muted-foreground">
|
|
464
464
|
{node.eyebrow}
|
|
465
465
|
</div>
|
|
466
466
|
)}
|
package/src/presentation.ts
CHANGED
|
@@ -264,7 +264,7 @@ export const cardPresentation = {
|
|
|
264
264
|
variants: {
|
|
265
265
|
default: "bg-card border-border shadow-[var(--edge-highlight),var(--shadow-card)]",
|
|
266
266
|
elevated: "bg-muted/50 border-border shadow-[var(--shadow-card)]",
|
|
267
|
-
glass: "bg-card
|
|
267
|
+
glass: "bg-card border-border shadow-[var(--shadow-card)]",
|
|
268
268
|
sandbox: "bg-muted/50 border-primary/20 shadow-[var(--shadow-accent)]",
|
|
269
269
|
},
|
|
270
270
|
} as const;
|
|
@@ -69,7 +69,7 @@ export function ArtifactPane({
|
|
|
69
69
|
{!hideTitleBlock && (
|
|
70
70
|
<>
|
|
71
71
|
{eyebrow && (
|
|
72
|
-
<div className="mb-1 inline-flex max-w-full items-center px-1 py-0.5 text-
|
|
72
|
+
<div className="mb-1 inline-flex max-w-full items-center px-1 py-0.5 text-xs font-medium text-muted-foreground">
|
|
73
73
|
{eyebrow}
|
|
74
74
|
</div>
|
|
75
75
|
)}
|
|
@@ -48,7 +48,7 @@ export const Overview: Story = {
|
|
|
48
48
|
name: 'Overview',
|
|
49
49
|
render: () => (
|
|
50
50
|
<div className="flex flex-col gap-6 p-6">
|
|
51
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
51
|
+
<div className="text-muted-foreground text-xs font-mono">Sizes</div>
|
|
52
52
|
<div className="flex items-center gap-4">
|
|
53
53
|
<Avatar className="h-6 w-6">
|
|
54
54
|
<AvatarFallback className="text-xs">XS</AvatarFallback>
|
|
@@ -66,7 +66,7 @@ export const Overview: Story = {
|
|
|
66
66
|
<AvatarFallback className="text-xl">XL</AvatarFallback>
|
|
67
67
|
</Avatar>
|
|
68
68
|
</div>
|
|
69
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
69
|
+
<div className="text-muted-foreground text-xs font-mono mt-2">Team</div>
|
|
70
70
|
<div className="flex items-center gap-3">
|
|
71
71
|
{[
|
|
72
72
|
{ initials: 'AK', label: 'Alex Kim' },
|
|
@@ -82,7 +82,7 @@ export const Overview: Story = {
|
|
|
82
82
|
</div>
|
|
83
83
|
))}
|
|
84
84
|
</div>
|
|
85
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
85
|
+
<div className="text-muted-foreground text-xs font-mono mt-2">Stacked</div>
|
|
86
86
|
<div className="flex -space-x-2">
|
|
87
87
|
{['AK', 'JD', 'MR', 'SP', '+4'].map((label) => (
|
|
88
88
|
<Avatar key={label} className="border-2 border-background">
|
|
@@ -29,10 +29,10 @@ export const Cold: Story = { args: { variant: 'cold', dot: true, children: 'Cold
|
|
|
29
29
|
export const Deleted: Story = { args: { variant: 'deleted', dot: true, children: 'Deleted' } }
|
|
30
30
|
|
|
31
31
|
export const AllVariants: Story = {
|
|
32
|
-
name: 'All
|
|
32
|
+
name: 'All variants',
|
|
33
33
|
render: () => (
|
|
34
34
|
<div className="flex flex-col gap-4 p-6">
|
|
35
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
35
|
+
<div className="text-muted-foreground text-xs font-mono">Semantic</div>
|
|
36
36
|
<div className="flex flex-wrap gap-2">
|
|
37
37
|
<Badge variant="default">Default</Badge>
|
|
38
38
|
<Badge variant="secondary">Secondary</Badge>
|
|
@@ -43,7 +43,7 @@ export const AllVariants: Story = {
|
|
|
43
43
|
<Badge variant="error">Error</Badge>
|
|
44
44
|
<Badge variant="info">Info</Badge>
|
|
45
45
|
</div>
|
|
46
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
46
|
+
<div className="text-muted-foreground text-xs font-mono mt-2">Operational status</div>
|
|
47
47
|
<div className="flex flex-wrap gap-2">
|
|
48
48
|
<Badge variant="running" dot>Running</Badge>
|
|
49
49
|
<Badge variant="creating" dot>Creating</Badge>
|
|
@@ -15,7 +15,7 @@ const SampleCard = ({ variant, hover }: { variant?: 'default' | 'glass' | 'sandb
|
|
|
15
15
|
<Card variant={variant} hover={hover} className="w-72">
|
|
16
16
|
<CardHeader>
|
|
17
17
|
<div className="flex items-center justify-between">
|
|
18
|
-
<CardTitle>Agent
|
|
18
|
+
<CardTitle>Agent session</CardTitle>
|
|
19
19
|
<Badge variant="running" dot>Running</Badge>
|
|
20
20
|
</div>
|
|
21
21
|
<CardDescription>GPT-4o · Tangle Cloud</CardDescription>
|
|
@@ -52,21 +52,21 @@ export const AllStates: Story = {
|
|
|
52
52
|
name: 'All States',
|
|
53
53
|
render: () => (
|
|
54
54
|
<div className="flex flex-col gap-4 p-6">
|
|
55
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
55
|
+
<div className="text-muted-foreground text-xs font-mono">HIPAA</div>
|
|
56
56
|
<div className="flex flex-wrap items-center gap-2">
|
|
57
57
|
<ComplianceBadge status="ready" />
|
|
58
58
|
<ComplianceBadge status="compliant" />
|
|
59
59
|
<ComplianceBadge status="ready" size="md" />
|
|
60
60
|
<ComplianceBadge status="compliant" size="md" />
|
|
61
61
|
</div>
|
|
62
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
62
|
+
<div className="text-muted-foreground text-xs font-mono mt-2">SOC 2</div>
|
|
63
63
|
<div className="flex flex-wrap items-center gap-2">
|
|
64
64
|
<ComplianceBadge product="soc2" status="ready" />
|
|
65
65
|
<ComplianceBadge product="soc2" status="compliant" />
|
|
66
66
|
<ComplianceBadge product="soc2" status="ready" size="md" />
|
|
67
67
|
<ComplianceBadge product="soc2" status="compliant" size="md" />
|
|
68
68
|
</div>
|
|
69
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
69
|
+
<div className="text-muted-foreground text-xs font-mono mt-2">Linked</div>
|
|
70
70
|
<div className="flex flex-wrap items-center gap-2">
|
|
71
71
|
<ComplianceBadge status="ready" href="/trust" />
|
|
72
72
|
<ComplianceBadge product="soc2" status="compliant" href="/trust" />
|
|
@@ -90,7 +90,7 @@ export const RegionSelector: Story = {
|
|
|
90
90
|
</button>
|
|
91
91
|
</DropdownMenuTrigger>
|
|
92
92
|
<DropdownMenuContent className="w-52">
|
|
93
|
-
<DropdownMenuLabel className="text-xs text-muted-foreground font-normal
|
|
93
|
+
<DropdownMenuLabel className="text-xs text-muted-foreground font-normal">
|
|
94
94
|
Regions
|
|
95
95
|
</DropdownMenuLabel>
|
|
96
96
|
<DropdownMenuSeparator />
|
|
@@ -22,7 +22,7 @@ const VARIANT_CLASS: Record<HeadingVariant, string> = {
|
|
|
22
22
|
subsection:
|
|
23
23
|
"font-semibold text-foreground text-[length:var(--font-size-base,1rem)] leading-[1.4]",
|
|
24
24
|
eyebrow:
|
|
25
|
-
"font-
|
|
25
|
+
"font-medium text-muted-foreground text-[length:var(--font-size-xs,0.75rem)] leading-4",
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
const DEFAULT_TAG: Record<HeadingVariant, React.ElementType> = {
|
|
@@ -90,7 +90,7 @@ export const Overview: Story = {
|
|
|
90
90
|
name: 'Overview',
|
|
91
91
|
render: () => (
|
|
92
92
|
<div className="flex flex-col gap-6 p-6 w-96">
|
|
93
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
93
|
+
<div className="text-muted-foreground text-xs font-mono">Input variants</div>
|
|
94
94
|
<Input label="Sandbox name" placeholder="my-sandbox-01" />
|
|
95
95
|
<Input
|
|
96
96
|
variant="sandbox"
|
|
@@ -104,7 +104,7 @@ export const Overview: Story = {
|
|
|
104
104
|
error="Must be a number between 1 and 32."
|
|
105
105
|
/>
|
|
106
106
|
<Input label="Region" defaultValue="us-east-1" disabled />
|
|
107
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
107
|
+
<div className="text-muted-foreground text-xs font-mono mt-2">Textarea</div>
|
|
108
108
|
<Textarea
|
|
109
109
|
label="Environment variables"
|
|
110
110
|
placeholder="NODE_ENV=production PORT=3000"
|
|
@@ -49,10 +49,10 @@ export const Overview: Story = {
|
|
|
49
49
|
name: 'Overview',
|
|
50
50
|
render: () => (
|
|
51
51
|
<div className="flex flex-col gap-6 p-6 w-80">
|
|
52
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
52
|
+
<div className="text-muted-foreground text-xs font-mono">Standalone</div>
|
|
53
53
|
<Label>Standalone label</Label>
|
|
54
54
|
|
|
55
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
55
|
+
<div className="text-muted-foreground text-xs font-mono">Paired with input</div>
|
|
56
56
|
<div className="flex flex-col gap-1.5">
|
|
57
57
|
<Label htmlFor="overview-name">Sandbox name</Label>
|
|
58
58
|
<Input id="overview-name" placeholder="my-sandbox-01" />
|
|
@@ -62,7 +62,7 @@ export const Overview: Story = {
|
|
|
62
62
|
<Input id="overview-image" placeholder="ubuntu:22.04" />
|
|
63
63
|
</div>
|
|
64
64
|
|
|
65
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
65
|
+
<div className="text-muted-foreground text-xs font-mono">Paired with switch</div>
|
|
66
66
|
<div className="flex flex-col gap-3">
|
|
67
67
|
<div className="flex items-center gap-2">
|
|
68
68
|
<Switch id="overview-sleep" defaultChecked />
|
|
@@ -60,27 +60,27 @@ export const Overview: Story = {
|
|
|
60
60
|
name: 'Overview',
|
|
61
61
|
render: () => (
|
|
62
62
|
<div className="flex flex-col gap-8 p-6 w-96">
|
|
63
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
63
|
+
<div className="text-muted-foreground text-xs font-mono">Default variant</div>
|
|
64
64
|
<div className="flex flex-col gap-4">
|
|
65
65
|
{[0, 25, 50, 75, 100].map((v) => (
|
|
66
66
|
<div key={v} className="flex items-center gap-3">
|
|
67
67
|
<span className="text-muted-foreground text-xs w-8 text-right">{v}%</span>
|
|
68
|
-
<
|
|
68
|
+
<div className="flex-1"><Progress value={v} /></div>
|
|
69
69
|
</div>
|
|
70
70
|
))}
|
|
71
71
|
</div>
|
|
72
72
|
|
|
73
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
73
|
+
<div className="text-muted-foreground text-xs font-mono">Sandbox variant</div>
|
|
74
74
|
<div className="flex flex-col gap-4">
|
|
75
75
|
{[0, 25, 50, 75, 100].map((v) => (
|
|
76
76
|
<div key={v} className="flex items-center gap-3">
|
|
77
77
|
<span className="text-muted-foreground text-xs w-8 text-right">{v}%</span>
|
|
78
|
-
<Progress value={v} variant="sandbox"
|
|
78
|
+
<div className="flex-1"><Progress value={v} variant="sandbox" /></div>
|
|
79
79
|
</div>
|
|
80
80
|
))}
|
|
81
81
|
</div>
|
|
82
82
|
|
|
83
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
83
|
+
<div className="text-muted-foreground text-xs font-mono">Sandbox task list</div>
|
|
84
84
|
<div className="rounded-xl border border-border bg-card p-4 flex flex-col gap-4">
|
|
85
85
|
{[
|
|
86
86
|
{ label: 'Pulling image', value: 100 },
|
|
@@ -42,7 +42,7 @@ const Progress = React.forwardRef<
|
|
|
42
42
|
>
|
|
43
43
|
<ProgressPrimitive.Indicator
|
|
44
44
|
className={cn(
|
|
45
|
-
"h-full w-full flex-1 transition-
|
|
45
|
+
"h-full w-full flex-1 transition-transform duration-300 ease-out",
|
|
46
46
|
tone ? TONE_FILL[tone] : indicatorVariants[variant],
|
|
47
47
|
)}
|
|
48
48
|
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
|
|
@@ -117,7 +117,7 @@ export const Overview: Story = {
|
|
|
117
117
|
name: 'Overview',
|
|
118
118
|
render: () => (
|
|
119
119
|
<div className="flex flex-col gap-6 p-6 w-72">
|
|
120
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
120
|
+
<div className="text-muted-foreground text-xs font-mono">Region</div>
|
|
121
121
|
<Select defaultValue="us-east-1">
|
|
122
122
|
<SelectTrigger>
|
|
123
123
|
<SelectValue />
|
|
@@ -130,7 +130,7 @@ export const Overview: Story = {
|
|
|
130
130
|
</SelectContent>
|
|
131
131
|
</Select>
|
|
132
132
|
|
|
133
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
133
|
+
<div className="text-muted-foreground text-xs font-mono">Runtime</div>
|
|
134
134
|
<Select>
|
|
135
135
|
<SelectTrigger>
|
|
136
136
|
<SelectValue placeholder="Select runtime..." />
|
|
@@ -150,7 +150,7 @@ export const Overview: Story = {
|
|
|
150
150
|
</SelectContent>
|
|
151
151
|
</Select>
|
|
152
152
|
|
|
153
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
153
|
+
<div className="text-muted-foreground text-xs font-mono">Disabled</div>
|
|
154
154
|
<Select disabled>
|
|
155
155
|
<SelectTrigger>
|
|
156
156
|
<SelectValue placeholder="Locked to current plan" />
|
|
@@ -12,7 +12,7 @@ const meta: Meta<typeof SidebarDropZone> = {
|
|
|
12
12
|
decorators: [
|
|
13
13
|
(Story) => (
|
|
14
14
|
<div className="w-64 p-4 rounded-xl border border-border bg-background space-y-3">
|
|
15
|
-
<div className="text-xs text-muted-foreground font-mono
|
|
15
|
+
<div className="text-xs text-muted-foreground font-mono">Workspace files</div>
|
|
16
16
|
<div className="space-y-1 text-sm text-foreground">
|
|
17
17
|
<div className="px-2 py-1 rounded hover:bg-accent">index.ts</div>
|
|
18
18
|
<div className="px-2 py-1 rounded hover:bg-accent">utils.ts</div>
|
|
@@ -108,7 +108,7 @@ export function SidebarDropZone({
|
|
|
108
108
|
onDragOver={handleDragOver}
|
|
109
109
|
onDrop={handleDrop}
|
|
110
110
|
className={cn(
|
|
111
|
-
"rounded-lg border-2 border-dashed transition-
|
|
111
|
+
"rounded-lg border-2 border-dashed transition-colors duration-150",
|
|
112
112
|
isVisible ? "p-4" : "p-0 border-transparent",
|
|
113
113
|
dragOver
|
|
114
114
|
? "border-[var(--brand-cool,hsl(var(--ring)))] bg-[var(--accent-surface-soft)]"
|
|
@@ -42,7 +42,7 @@ export const Overview: Story = {
|
|
|
42
42
|
name: 'Overview',
|
|
43
43
|
render: () => (
|
|
44
44
|
<div className="flex flex-col gap-8 p-6 w-[560px]">
|
|
45
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
45
|
+
<div className="text-muted-foreground text-xs font-mono">Inline elements</div>
|
|
46
46
|
<div className="flex flex-col gap-2">
|
|
47
47
|
<Skeleton className="h-5 w-3/4" />
|
|
48
48
|
<Skeleton className="h-4 w-full" />
|
|
@@ -50,7 +50,7 @@ export const Overview: Story = {
|
|
|
50
50
|
<Skeleton className="h-4 w-2/3" />
|
|
51
51
|
</div>
|
|
52
52
|
|
|
53
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
53
|
+
<div className="text-muted-foreground text-xs font-mono">Team list</div>
|
|
54
54
|
<div className="flex flex-col gap-3">
|
|
55
55
|
{[1, 2, 3].map((i) => (
|
|
56
56
|
<div key={i} className="flex items-center gap-3">
|
|
@@ -64,13 +64,13 @@ export const Overview: Story = {
|
|
|
64
64
|
))}
|
|
65
65
|
</div>
|
|
66
66
|
|
|
67
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
67
|
+
<div className="text-muted-foreground text-xs font-mono">Cards</div>
|
|
68
68
|
<div className="flex gap-4">
|
|
69
69
|
<SkeletonCard className="flex-1" />
|
|
70
70
|
<SkeletonCard className="flex-1" />
|
|
71
71
|
</div>
|
|
72
72
|
|
|
73
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
73
|
+
<div className="text-muted-foreground text-xs font-mono">Table</div>
|
|
74
74
|
<div className="rounded-xl border border-border bg-card p-4">
|
|
75
75
|
<SkeletonTable rows={3} />
|
|
76
76
|
</div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
-
import {
|
|
2
|
+
import { Terminal } from 'lucide-react'
|
|
3
3
|
import { StatCard } from './stat-card'
|
|
4
4
|
|
|
5
5
|
const meta: Meta<typeof StatCard> = {
|
|
@@ -13,7 +13,7 @@ type Story = StoryObj<typeof StatCard>
|
|
|
13
13
|
|
|
14
14
|
export const Default: Story = {
|
|
15
15
|
args: {
|
|
16
|
-
title: 'Active
|
|
16
|
+
title: 'Active sessions',
|
|
17
17
|
value: 24,
|
|
18
18
|
subtitle: 'across 3 regions',
|
|
19
19
|
icon: <Terminal className="h-5 w-5" />,
|
|
@@ -21,10 +21,10 @@ export const Default: Story = {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
export const SandboxVariant: Story = {
|
|
24
|
-
name: 'Sandbox
|
|
24
|
+
name: 'Sandbox variant',
|
|
25
25
|
args: {
|
|
26
26
|
variant: 'sandbox',
|
|
27
|
-
title: 'Active
|
|
27
|
+
title: 'Active sessions',
|
|
28
28
|
value: 24,
|
|
29
29
|
subtitle: 'across 3 regions',
|
|
30
30
|
icon: <Terminal className="h-5 w-5" />,
|
|
@@ -33,103 +33,92 @@ export const SandboxVariant: Story = {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export const CpuUsage: Story = {
|
|
36
|
-
name: 'CPU
|
|
36
|
+
name: 'CPU usage',
|
|
37
37
|
args: {
|
|
38
|
-
title: 'Avg CPU
|
|
38
|
+
title: 'Avg CPU usage',
|
|
39
39
|
value: '68%',
|
|
40
40
|
subtitle: 'p95: 94%',
|
|
41
|
-
icon: <Cpu className="h-5 w-5" />,
|
|
42
41
|
trend: { value: -4, label: 'vs yesterday' },
|
|
43
42
|
},
|
|
44
43
|
}
|
|
45
44
|
|
|
46
45
|
export const MemoryUsage: Story = {
|
|
47
|
-
name: 'Memory
|
|
46
|
+
name: 'Memory usage',
|
|
48
47
|
args: {
|
|
49
|
-
title: 'Memory
|
|
48
|
+
title: 'Memory allocated',
|
|
50
49
|
value: '12.4 GB',
|
|
51
50
|
subtitle: 'of 32 GB pool',
|
|
52
|
-
icon: <HardDrive className="h-5 w-5" />,
|
|
53
51
|
trend: { value: 8, label: 'vs last hour' },
|
|
54
52
|
},
|
|
55
53
|
}
|
|
56
54
|
|
|
57
55
|
export const MonthlyCost: Story = {
|
|
58
|
-
name: 'Monthly
|
|
56
|
+
name: 'Monthly cost',
|
|
59
57
|
args: {
|
|
60
|
-
title: 'Estimated
|
|
58
|
+
title: 'Estimated cost',
|
|
61
59
|
value: '$142.80',
|
|
62
60
|
subtitle: 'current billing cycle',
|
|
63
|
-
icon: <DollarSign className="h-5 w-5" />,
|
|
64
61
|
trend: { value: 0, label: 'vs last month' },
|
|
65
62
|
},
|
|
66
63
|
}
|
|
67
64
|
|
|
68
65
|
export const TrendPositive: Story = {
|
|
69
|
-
name: 'Trend
|
|
66
|
+
name: 'Trend up',
|
|
70
67
|
args: {
|
|
71
|
-
title: 'Sessions
|
|
68
|
+
title: 'Sessions today',
|
|
72
69
|
value: 1284,
|
|
73
|
-
icon: <Activity className="h-5 w-5" />,
|
|
74
70
|
trend: { value: 23, label: 'vs yesterday' },
|
|
75
71
|
},
|
|
76
72
|
}
|
|
77
73
|
|
|
78
74
|
export const TrendNegative: Story = {
|
|
79
|
-
name: 'Trend
|
|
75
|
+
name: 'Trend down',
|
|
80
76
|
args: {
|
|
81
|
-
title: 'Error
|
|
77
|
+
title: 'Error rate',
|
|
82
78
|
value: '1.2%',
|
|
83
|
-
icon: <Zap className="h-5 w-5" />,
|
|
84
79
|
trend: { value: -18, label: 'vs last week' },
|
|
85
80
|
},
|
|
86
81
|
}
|
|
87
82
|
|
|
88
83
|
export const InfraGrid: Story = {
|
|
89
|
-
name: 'Infrastructure
|
|
84
|
+
name: 'Infrastructure grid',
|
|
90
85
|
render: () => (
|
|
91
86
|
<div className="grid grid-cols-2 gap-4 w-[640px]">
|
|
92
87
|
<StatCard
|
|
93
|
-
title="Active
|
|
88
|
+
title="Active sessions"
|
|
94
89
|
value={24}
|
|
95
90
|
subtitle="across 3 regions"
|
|
96
|
-
icon={<Terminal className="h-5 w-5" />}
|
|
97
91
|
trend={{ value: 12, label: 'vs last hour' }}
|
|
98
92
|
/>
|
|
99
93
|
<StatCard
|
|
100
|
-
title="CPU
|
|
94
|
+
title="CPU usage"
|
|
101
95
|
value="68%"
|
|
102
96
|
subtitle="p95: 94%"
|
|
103
|
-
icon={<Cpu className="h-5 w-5" />}
|
|
104
97
|
trend={{ value: -4, label: 'vs yesterday' }}
|
|
105
98
|
/>
|
|
106
99
|
<StatCard
|
|
107
|
-
title="Memory
|
|
100
|
+
title="Memory allocated"
|
|
108
101
|
value="12.4 GB"
|
|
109
102
|
subtitle="of 32 GB pool"
|
|
110
|
-
icon={<HardDrive className="h-5 w-5" />}
|
|
111
103
|
trend={{ value: 8, label: 'vs last hour' }}
|
|
112
104
|
/>
|
|
113
105
|
<StatCard
|
|
114
106
|
variant="sandbox"
|
|
115
|
-
title="Estimated
|
|
107
|
+
title="Estimated cost"
|
|
116
108
|
value="$142.80"
|
|
117
109
|
subtitle="current billing cycle"
|
|
118
|
-
icon={<DollarSign className="h-5 w-5" />}
|
|
119
110
|
trend={{ value: 3, label: 'vs last month' }}
|
|
120
111
|
/>
|
|
121
112
|
<StatCard
|
|
122
|
-
title="Unique
|
|
113
|
+
title="Unique users"
|
|
123
114
|
value={312}
|
|
124
115
|
subtitle="last 30 days"
|
|
125
|
-
|
|
126
|
-
trend={{ value: 19, label: 'MoM' }}
|
|
116
|
+
trend={{ value: 19, label: 'vs last month' }}
|
|
127
117
|
/>
|
|
128
118
|
<StatCard
|
|
129
|
-
title="Avg
|
|
119
|
+
title="Avg startup time"
|
|
130
120
|
value="840ms"
|
|
131
121
|
subtitle="p99: 1.4s"
|
|
132
|
-
icon={<Zap className="h-5 w-5" />}
|
|
133
122
|
trend={{ value: -11, label: 'vs last week' }}
|
|
134
123
|
/>
|
|
135
124
|
</div>
|
|
@@ -57,7 +57,7 @@ const StatCard = React.forwardRef<HTMLDivElement, StatCardProps>(
|
|
|
57
57
|
<div className="flex items-start justify-between">
|
|
58
58
|
<div className="space-y-1">
|
|
59
59
|
<p className="text-muted-foreground text-sm">{title}</p>
|
|
60
|
-
<p className="font-
|
|
60
|
+
<p className="font-medium text-3xl tabular-nums tracking-tight">{value}</p>
|
|
61
61
|
{/* A token, never `opacity-70` over the muted tone: a translucent
|
|
62
62
|
foreground renders as the token COMPOSITED over whatever plane sits
|
|
63
63
|
behind it, so the same class lands a different colour — and a
|
|
@@ -41,7 +41,7 @@ export const Overview: Story = {
|
|
|
41
41
|
name: 'Overview',
|
|
42
42
|
render: () => (
|
|
43
43
|
<div className="flex flex-col gap-6 p-6 w-80">
|
|
44
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
44
|
+
<div className="text-muted-foreground text-xs font-mono">States</div>
|
|
45
45
|
<div className="flex flex-col gap-4">
|
|
46
46
|
<div className="flex items-center justify-between">
|
|
47
47
|
<span className="text-sm text-muted-foreground">Off</span>
|
|
@@ -61,7 +61,7 @@ export const Overview: Story = {
|
|
|
61
61
|
</div>
|
|
62
62
|
</div>
|
|
63
63
|
|
|
64
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
64
|
+
<div className="text-muted-foreground text-xs font-mono mt-2">Settings panel</div>
|
|
65
65
|
<div className="rounded-xl border border-border bg-card p-4 flex flex-col gap-4">
|
|
66
66
|
{[
|
|
67
67
|
{ id: 'auto-sleep', label: 'Auto-sleep after idle', checked: true },
|
|
@@ -104,7 +104,7 @@ export const Overview: Story = {
|
|
|
104
104
|
render: () => (
|
|
105
105
|
<div className="flex flex-col gap-10 p-6 w-[480px]">
|
|
106
106
|
<div>
|
|
107
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
107
|
+
<div className="text-muted-foreground text-xs font-mono mb-4">Default (segmented)</div>
|
|
108
108
|
<Tabs defaultValue="overview">
|
|
109
109
|
<TabsList>
|
|
110
110
|
<TabsTrigger value="overview">Overview</TabsTrigger>
|
|
@@ -137,7 +137,7 @@ export const Overview: Story = {
|
|
|
137
137
|
</div>
|
|
138
138
|
|
|
139
139
|
<div>
|
|
140
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
140
|
+
<div className="text-muted-foreground text-xs font-mono mb-4">Pills</div>
|
|
141
141
|
<Tabs defaultValue="all">
|
|
142
142
|
<TabsList variant="pills">
|
|
143
143
|
<TabsTrigger value="all" variant="pills">All</TabsTrigger>
|
|
@@ -157,7 +157,7 @@ export const Overview: Story = {
|
|
|
157
157
|
</div>
|
|
158
158
|
|
|
159
159
|
<div>
|
|
160
|
-
<div className="text-muted-foreground text-xs font-mono
|
|
160
|
+
<div className="text-muted-foreground text-xs font-mono mb-4">Underline</div>
|
|
161
161
|
<Tabs defaultValue="settings">
|
|
162
162
|
<TabsList variant="underline">
|
|
163
163
|
<TabsTrigger value="settings" variant="underline">Settings</TabsTrigger>
|