@tangle-network/sandbox-ui 0.2.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/README.md +68 -0
- package/dist/auth.d.ts +57 -0
- package/dist/auth.js +14 -0
- package/dist/branding-DCi5VEik.d.ts +13 -0
- package/dist/button-BidTtuRS.d.ts +15 -0
- package/dist/chat.d.ts +121 -0
- package/dist/chat.js +25 -0
- package/dist/chunk-2UHPE5T7.js +201 -0
- package/dist/chunk-4EIWPJMJ.js +545 -0
- package/dist/chunk-6MQIDUPA.js +502 -0
- package/dist/chunk-B26TQ7SA.js +47 -0
- package/dist/chunk-E6FS7R4X.js +109 -0
- package/dist/chunk-GRYHFH5O.js +110 -0
- package/dist/chunk-HMND7JPA.js +868 -0
- package/dist/chunk-HRMUF35V.js +19 -0
- package/dist/chunk-HYEAX3DC.js +822 -0
- package/dist/chunk-KMXV7DDX.js +174 -0
- package/dist/chunk-KYY2X6LY.js +318 -0
- package/dist/chunk-L6ZDH5F4.js +334 -0
- package/dist/chunk-LTFK464G.js +103 -0
- package/dist/chunk-M34OA6PQ.js +233 -0
- package/dist/chunk-M6VLC32S.js +219 -0
- package/dist/chunk-MCGKDCOR.js +173 -0
- package/dist/chunk-NI2EI43H.js +294 -0
- package/dist/chunk-OU4TRNQZ.js +173 -0
- package/dist/chunk-QD4QE5P5.js +40 -0
- package/dist/chunk-QSQBDR3N.js +180 -0
- package/dist/chunk-RQHJBTEU.js +10 -0
- package/dist/chunk-U62G5TS7.js +472 -0
- package/dist/chunk-ZOL2TR5M.js +475 -0
- package/dist/dashboard.d.ts +111 -0
- package/dist/dashboard.js +26 -0
- package/dist/editor.d.ts +196 -0
- package/dist/editor.js +713 -0
- package/dist/expanded-tool-detail-OkXGqTHe.d.ts +52 -0
- package/dist/files.d.ts +66 -0
- package/dist/files.js +11 -0
- package/dist/hooks.d.ts +22 -0
- package/dist/hooks.js +107 -0
- package/dist/index.d.ts +107 -0
- package/dist/index.js +551 -0
- package/dist/markdown.d.ts +55 -0
- package/dist/markdown.js +17 -0
- package/dist/pages.d.ts +89 -0
- package/dist/pages.js +1181 -0
- package/dist/parts-CyGkM6Fp.d.ts +50 -0
- package/dist/primitives.d.ts +189 -0
- package/dist/primitives.js +161 -0
- package/dist/run-CtFZ6s-D.d.ts +41 -0
- package/dist/run.d.ts +14 -0
- package/dist/run.js +29 -0
- package/dist/sidecar-CFU2W9j1.d.ts +8 -0
- package/dist/stores.d.ts +28 -0
- package/dist/stores.js +49 -0
- package/dist/terminal.d.ts +44 -0
- package/dist/terminal.js +160 -0
- package/dist/tool-call-feed-D5Ume-Pt.d.ts +66 -0
- package/dist/tool-display-BvsVW_Ur.d.ts +32 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.js +0 -0
- package/dist/usage-chart-DINgSVL5.d.ts +60 -0
- package/dist/use-sidecar-auth-Bb0-w3lX.d.ts +339 -0
- package/dist/utils.d.ts +28 -0
- package/dist/utils.js +28 -0
- package/dist/workspace.d.ts +113 -0
- package/dist/workspace.js +15 -0
- package/package.json +174 -0
- package/src/styles/globals.css +230 -0
- package/src/styles/tokens.css +73 -0
- package/tailwind.config.cjs +99 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SimpleMarkdown
|
|
3
|
+
} from "./chunk-M34OA6PQ.js";
|
|
4
|
+
import {
|
|
5
|
+
cn
|
|
6
|
+
} from "./chunk-RQHJBTEU.js";
|
|
7
|
+
|
|
8
|
+
// src/run/tool-call-step.tsx
|
|
9
|
+
import { useState } from "react";
|
|
10
|
+
import {
|
|
11
|
+
Terminal,
|
|
12
|
+
FileText,
|
|
13
|
+
FileCode,
|
|
14
|
+
Search,
|
|
15
|
+
CheckCircle,
|
|
16
|
+
ChevronRight,
|
|
17
|
+
Loader2,
|
|
18
|
+
FolderOpen,
|
|
19
|
+
Download,
|
|
20
|
+
Pencil,
|
|
21
|
+
Eye
|
|
22
|
+
} from "lucide-react";
|
|
23
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
24
|
+
var ICONS = {
|
|
25
|
+
bash: Terminal,
|
|
26
|
+
read: Eye,
|
|
27
|
+
write: FileText,
|
|
28
|
+
edit: Pencil,
|
|
29
|
+
glob: FolderOpen,
|
|
30
|
+
grep: Search,
|
|
31
|
+
list: FolderOpen,
|
|
32
|
+
download: Download,
|
|
33
|
+
inspect: Search,
|
|
34
|
+
audit: CheckCircle,
|
|
35
|
+
unknown: FileCode
|
|
36
|
+
};
|
|
37
|
+
var STATUS_COLORS = {
|
|
38
|
+
running: "text-[var(--brand-cool)]",
|
|
39
|
+
success: "text-[var(--code-success)]",
|
|
40
|
+
error: "text-[var(--code-error)]"
|
|
41
|
+
};
|
|
42
|
+
function ToolCallStep({
|
|
43
|
+
type,
|
|
44
|
+
label,
|
|
45
|
+
status,
|
|
46
|
+
detail,
|
|
47
|
+
output,
|
|
48
|
+
duration,
|
|
49
|
+
className
|
|
50
|
+
}) {
|
|
51
|
+
const [expanded, setExpanded] = useState(false);
|
|
52
|
+
const Icon = ICONS[type] || ICONS.unknown;
|
|
53
|
+
const hasExpandable = !!(detail || output);
|
|
54
|
+
return /* @__PURE__ */ jsxs(
|
|
55
|
+
"div",
|
|
56
|
+
{
|
|
57
|
+
className: cn(
|
|
58
|
+
"group border-l-2 pl-3 py-1.5 transition-colors",
|
|
59
|
+
status === "running" && "border-[var(--brand-cool)] bg-[var(--brand-cool)]/5",
|
|
60
|
+
status === "success" && "border-[var(--border-subtle)] hover:border-[var(--border-accent)]",
|
|
61
|
+
status === "error" && "border-[var(--code-error)]/40",
|
|
62
|
+
className
|
|
63
|
+
),
|
|
64
|
+
children: [
|
|
65
|
+
/* @__PURE__ */ jsxs(
|
|
66
|
+
"button",
|
|
67
|
+
{
|
|
68
|
+
onClick: () => hasExpandable && setExpanded(!expanded),
|
|
69
|
+
disabled: !hasExpandable,
|
|
70
|
+
className: cn(
|
|
71
|
+
"flex items-center gap-2 w-full text-left text-sm",
|
|
72
|
+
hasExpandable && "cursor-pointer"
|
|
73
|
+
),
|
|
74
|
+
children: [
|
|
75
|
+
status === "running" ? /* @__PURE__ */ jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin text-[var(--brand-cool)] shrink-0" }) : /* @__PURE__ */ jsx(Icon, { className: cn("h-3.5 w-3.5 shrink-0", STATUS_COLORS[status]) }),
|
|
76
|
+
/* @__PURE__ */ jsx("span", { className: "text-[var(--text-secondary)] truncate flex-1 font-[var(--font-sans)]", children: label }),
|
|
77
|
+
duration !== void 0 && status !== "running" && /* @__PURE__ */ jsx("span", { className: "text-[var(--text-muted)] text-xs tabular-nums shrink-0", children: duration < 1e3 ? `${duration}ms` : `${(duration / 1e3).toFixed(1)}s` }),
|
|
78
|
+
hasExpandable && /* @__PURE__ */ jsx(
|
|
79
|
+
ChevronRight,
|
|
80
|
+
{
|
|
81
|
+
className: cn(
|
|
82
|
+
"h-3 w-3 text-[var(--text-muted)] transition-transform shrink-0",
|
|
83
|
+
expanded && "rotate-90"
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
)
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
),
|
|
90
|
+
expanded && (detail || output) && /* @__PURE__ */ jsxs("div", { className: "mt-1.5 ml-5.5 space-y-1", children: [
|
|
91
|
+
detail && /* @__PURE__ */ jsx("div", { className: "text-xs text-[var(--text-muted)] font-[var(--font-mono)]", children: detail }),
|
|
92
|
+
output && /* @__PURE__ */ jsx("pre", { className: "text-xs text-[var(--text-secondary)] bg-[var(--bg-input)] border border-[var(--border-subtle)] rounded-[var(--radius-sm)] p-2 overflow-x-auto max-h-48 font-[var(--font-mono)]", children: output })
|
|
93
|
+
] })
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
function ToolCallGroup({ title, children, className }) {
|
|
99
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-0.5 my-2", className), children: [
|
|
100
|
+
title && /* @__PURE__ */ jsx("div", { className: "text-xs font-medium text-[var(--text-muted)] uppercase tracking-wider mb-1 px-1", children: title }),
|
|
101
|
+
children
|
|
102
|
+
] });
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// src/run/tool-call-feed.tsx
|
|
106
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
107
|
+
function ToolCallFeed({ segments, className }) {
|
|
108
|
+
if (segments.length === 0) return null;
|
|
109
|
+
return /* @__PURE__ */ jsx2("div", { className: cn("space-y-1", className), children: segments.map((segment, i) => {
|
|
110
|
+
if (segment.kind === "text") {
|
|
111
|
+
return segment.content.trim() ? /* @__PURE__ */ jsx2(SimpleMarkdown, { content: segment.content }, i) : null;
|
|
112
|
+
}
|
|
113
|
+
if (segment.kind === "tool_call") {
|
|
114
|
+
return /* @__PURE__ */ jsx2(
|
|
115
|
+
ToolCallStep,
|
|
116
|
+
{
|
|
117
|
+
type: segment.call.type,
|
|
118
|
+
label: segment.call.label,
|
|
119
|
+
status: segment.call.status,
|
|
120
|
+
detail: segment.call.detail,
|
|
121
|
+
output: segment.call.output,
|
|
122
|
+
duration: segment.call.duration
|
|
123
|
+
},
|
|
124
|
+
segment.call.id || i
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
if (segment.kind === "tool_group") {
|
|
128
|
+
return /* @__PURE__ */ jsx2(ToolCallGroup, { title: segment.title, children: segment.calls.map((call) => /* @__PURE__ */ jsx2(
|
|
129
|
+
ToolCallStep,
|
|
130
|
+
{
|
|
131
|
+
type: call.type,
|
|
132
|
+
label: call.label,
|
|
133
|
+
status: call.status,
|
|
134
|
+
detail: call.detail,
|
|
135
|
+
output: call.output,
|
|
136
|
+
duration: call.duration
|
|
137
|
+
},
|
|
138
|
+
call.id
|
|
139
|
+
)) }, i);
|
|
140
|
+
}
|
|
141
|
+
return null;
|
|
142
|
+
}) });
|
|
143
|
+
}
|
|
144
|
+
function parseToolEvent(event) {
|
|
145
|
+
const { type, data } = event;
|
|
146
|
+
if (type === "tool.invocation" || type === "tool_use") {
|
|
147
|
+
const toolName = data.name || data.tool || "unknown";
|
|
148
|
+
const input = data.input;
|
|
149
|
+
return {
|
|
150
|
+
id: data.id || data.toolUseId || crypto.randomUUID(),
|
|
151
|
+
type: mapToolName(toolName),
|
|
152
|
+
label: formatToolLabel(toolName, input),
|
|
153
|
+
status: "running",
|
|
154
|
+
detail: input ? formatToolInput(toolName, input) : void 0
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
if (type === "tool.result" || type === "tool_result") {
|
|
158
|
+
return {
|
|
159
|
+
id: data.id || data.toolUseId || "",
|
|
160
|
+
type: mapToolName(data.name || data.tool || "unknown"),
|
|
161
|
+
label: formatToolLabel(data.name || data.tool || "unknown"),
|
|
162
|
+
status: data.error ? "error" : "success",
|
|
163
|
+
output: truncate(data.output || data.result || "", 500),
|
|
164
|
+
duration: data.duration
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
function mapToolName(name) {
|
|
170
|
+
const lower = name.toLowerCase();
|
|
171
|
+
if (lower.includes("bash") || lower.includes("terminal") || lower.includes("exec")) return "bash";
|
|
172
|
+
if (lower.includes("read") || lower.includes("cat")) return "read";
|
|
173
|
+
if (lower.includes("write") || lower.includes("create")) return "write";
|
|
174
|
+
if (lower.includes("edit") || lower.includes("replace")) return "edit";
|
|
175
|
+
if (lower.includes("glob") || lower.includes("find")) return "glob";
|
|
176
|
+
if (lower.includes("grep") || lower.includes("search")) return "grep";
|
|
177
|
+
if (lower.includes("list") || lower.includes("ls")) return "list";
|
|
178
|
+
if (lower.includes("inspect")) return "inspect";
|
|
179
|
+
if (lower.includes("audit")) return "audit";
|
|
180
|
+
return "unknown";
|
|
181
|
+
}
|
|
182
|
+
function formatToolLabel(toolName, input) {
|
|
183
|
+
const lower = toolName.toLowerCase();
|
|
184
|
+
if (lower.includes("bash") && input?.command) {
|
|
185
|
+
const cmd = String(input.command);
|
|
186
|
+
return cmd.length > 80 ? `${cmd.slice(0, 77)}...` : cmd;
|
|
187
|
+
}
|
|
188
|
+
if ((lower.includes("read") || lower.includes("cat")) && input?.path) {
|
|
189
|
+
return `Read ${input.path}`;
|
|
190
|
+
}
|
|
191
|
+
if (lower.includes("write") && input?.path) {
|
|
192
|
+
return `Write ${input.path}`;
|
|
193
|
+
}
|
|
194
|
+
if (lower.includes("edit") && input?.path) {
|
|
195
|
+
return `Edit ${input.path}`;
|
|
196
|
+
}
|
|
197
|
+
if (lower.includes("glob") && input?.pattern) {
|
|
198
|
+
return `Find ${input.pattern}`;
|
|
199
|
+
}
|
|
200
|
+
if (lower.includes("grep") && input?.pattern) {
|
|
201
|
+
return `Search for ${input.pattern}`;
|
|
202
|
+
}
|
|
203
|
+
return toolName;
|
|
204
|
+
}
|
|
205
|
+
function formatToolInput(toolName, input) {
|
|
206
|
+
if (input.command) return String(input.command);
|
|
207
|
+
if (input.path) return String(input.path);
|
|
208
|
+
return JSON.stringify(input, null, 2).slice(0, 300);
|
|
209
|
+
}
|
|
210
|
+
function truncate(text, max) {
|
|
211
|
+
return text.length > max ? text.slice(0, max - 3) + "..." : text;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export {
|
|
215
|
+
ToolCallStep,
|
|
216
|
+
ToolCallGroup,
|
|
217
|
+
ToolCallFeed,
|
|
218
|
+
parseToolEvent
|
|
219
|
+
};
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cn
|
|
3
|
+
} from "./chunk-RQHJBTEU.js";
|
|
4
|
+
|
|
5
|
+
// src/primitives/dropdown-menu.tsx
|
|
6
|
+
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
7
|
+
import { Check, ChevronRight, Circle } from "lucide-react";
|
|
8
|
+
import * as React from "react";
|
|
9
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
var DropdownMenu = DropdownMenuPrimitive.Root;
|
|
11
|
+
var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
|
12
|
+
var DropdownMenuGroup = DropdownMenuPrimitive.Group;
|
|
13
|
+
var DropdownMenuPortal = DropdownMenuPrimitive.Portal;
|
|
14
|
+
var DropdownMenuSub = DropdownMenuPrimitive.Sub;
|
|
15
|
+
var DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
|
|
16
|
+
var DropdownMenuSubTrigger = React.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
17
|
+
DropdownMenuPrimitive.SubTrigger,
|
|
18
|
+
{
|
|
19
|
+
ref,
|
|
20
|
+
className: cn(
|
|
21
|
+
"flex cursor-default select-none items-center rounded-md px-2 py-1.5 text-sm outline-none",
|
|
22
|
+
"focus:bg-accent data-[state=open]:bg-accent",
|
|
23
|
+
inset && "pl-8",
|
|
24
|
+
className
|
|
25
|
+
),
|
|
26
|
+
...props,
|
|
27
|
+
children: [
|
|
28
|
+
children,
|
|
29
|
+
/* @__PURE__ */ jsx(ChevronRight, { className: "ml-auto h-4 w-4" })
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
));
|
|
33
|
+
DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
|
|
34
|
+
var DropdownMenuSubContent = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
35
|
+
DropdownMenuPrimitive.SubContent,
|
|
36
|
+
{
|
|
37
|
+
ref,
|
|
38
|
+
className: cn(
|
|
39
|
+
"z-50 min-w-[8rem] overflow-hidden rounded-xl border border-border bg-popover p-1 text-popover-foreground shadow-xl",
|
|
40
|
+
"data-[state=closed]:animate-out data-[state=open]:animate-in",
|
|
41
|
+
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
42
|
+
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
43
|
+
"data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
|
|
44
|
+
"data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
45
|
+
className
|
|
46
|
+
),
|
|
47
|
+
...props
|
|
48
|
+
}
|
|
49
|
+
));
|
|
50
|
+
DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
|
|
51
|
+
var DropdownMenuContent = React.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
52
|
+
DropdownMenuPrimitive.Content,
|
|
53
|
+
{
|
|
54
|
+
ref,
|
|
55
|
+
sideOffset,
|
|
56
|
+
className: cn(
|
|
57
|
+
"z-50 min-w-[8rem] overflow-hidden rounded-xl border border-border bg-popover p-1 text-popover-foreground shadow-xl",
|
|
58
|
+
"data-[state=closed]:animate-out data-[state=open]:animate-in",
|
|
59
|
+
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
60
|
+
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
61
|
+
"data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
|
|
62
|
+
"data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
63
|
+
className
|
|
64
|
+
),
|
|
65
|
+
...props
|
|
66
|
+
}
|
|
67
|
+
) }));
|
|
68
|
+
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
|
|
69
|
+
var DropdownMenuItem = React.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
70
|
+
DropdownMenuPrimitive.Item,
|
|
71
|
+
{
|
|
72
|
+
ref,
|
|
73
|
+
className: cn(
|
|
74
|
+
"relative flex cursor-pointer select-none items-center rounded-md px-2 py-1.5 text-sm outline-none transition-colors",
|
|
75
|
+
"focus:bg-accent focus:text-accent-foreground",
|
|
76
|
+
"data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
77
|
+
inset && "pl-8",
|
|
78
|
+
className
|
|
79
|
+
),
|
|
80
|
+
...props
|
|
81
|
+
}
|
|
82
|
+
));
|
|
83
|
+
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
|
|
84
|
+
var DropdownMenuCheckboxItem = React.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
85
|
+
DropdownMenuPrimitive.CheckboxItem,
|
|
86
|
+
{
|
|
87
|
+
ref,
|
|
88
|
+
className: cn(
|
|
89
|
+
"relative flex cursor-pointer select-none items-center rounded-md py-1.5 pr-2 pl-8 text-sm outline-none transition-colors",
|
|
90
|
+
"focus:bg-accent focus:text-accent-foreground",
|
|
91
|
+
"data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
92
|
+
className
|
|
93
|
+
),
|
|
94
|
+
checked,
|
|
95
|
+
...props,
|
|
96
|
+
children: [
|
|
97
|
+
/* @__PURE__ */ jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" }) }) }),
|
|
98
|
+
children
|
|
99
|
+
]
|
|
100
|
+
}
|
|
101
|
+
));
|
|
102
|
+
DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
|
|
103
|
+
var DropdownMenuRadioItem = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
104
|
+
DropdownMenuPrimitive.RadioItem,
|
|
105
|
+
{
|
|
106
|
+
ref,
|
|
107
|
+
className: cn(
|
|
108
|
+
"relative flex cursor-pointer select-none items-center rounded-md py-1.5 pr-2 pl-8 text-sm outline-none transition-colors",
|
|
109
|
+
"focus:bg-accent focus:text-accent-foreground",
|
|
110
|
+
"data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
111
|
+
className
|
|
112
|
+
),
|
|
113
|
+
...props,
|
|
114
|
+
children: [
|
|
115
|
+
/* @__PURE__ */ jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Circle, { className: "h-2 w-2 fill-current" }) }) }),
|
|
116
|
+
children
|
|
117
|
+
]
|
|
118
|
+
}
|
|
119
|
+
));
|
|
120
|
+
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
|
|
121
|
+
var DropdownMenuLabel = React.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
122
|
+
DropdownMenuPrimitive.Label,
|
|
123
|
+
{
|
|
124
|
+
ref,
|
|
125
|
+
className: cn(
|
|
126
|
+
"px-2 py-1.5 font-semibold text-sm",
|
|
127
|
+
inset && "pl-8",
|
|
128
|
+
className
|
|
129
|
+
),
|
|
130
|
+
...props
|
|
131
|
+
}
|
|
132
|
+
));
|
|
133
|
+
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
|
|
134
|
+
var DropdownMenuSeparator = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
135
|
+
DropdownMenuPrimitive.Separator,
|
|
136
|
+
{
|
|
137
|
+
ref,
|
|
138
|
+
className: cn("-mx-1 my-1 h-px bg-border", className),
|
|
139
|
+
...props
|
|
140
|
+
}
|
|
141
|
+
));
|
|
142
|
+
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
|
|
143
|
+
var DropdownMenuShortcut = ({
|
|
144
|
+
className,
|
|
145
|
+
...props
|
|
146
|
+
}) => {
|
|
147
|
+
return /* @__PURE__ */ jsx(
|
|
148
|
+
"span",
|
|
149
|
+
{
|
|
150
|
+
className: cn("ml-auto text-xs tracking-widest opacity-60", className),
|
|
151
|
+
...props
|
|
152
|
+
}
|
|
153
|
+
);
|
|
154
|
+
};
|
|
155
|
+
DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
|
|
156
|
+
|
|
157
|
+
export {
|
|
158
|
+
DropdownMenu,
|
|
159
|
+
DropdownMenuTrigger,
|
|
160
|
+
DropdownMenuGroup,
|
|
161
|
+
DropdownMenuPortal,
|
|
162
|
+
DropdownMenuSub,
|
|
163
|
+
DropdownMenuRadioGroup,
|
|
164
|
+
DropdownMenuSubTrigger,
|
|
165
|
+
DropdownMenuSubContent,
|
|
166
|
+
DropdownMenuContent,
|
|
167
|
+
DropdownMenuItem,
|
|
168
|
+
DropdownMenuCheckboxItem,
|
|
169
|
+
DropdownMenuRadioItem,
|
|
170
|
+
DropdownMenuLabel,
|
|
171
|
+
DropdownMenuSeparator,
|
|
172
|
+
DropdownMenuShortcut
|
|
173
|
+
};
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cn
|
|
3
|
+
} from "./chunk-RQHJBTEU.js";
|
|
4
|
+
|
|
5
|
+
// src/primitives/dialog.tsx
|
|
6
|
+
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
7
|
+
import { X } from "lucide-react";
|
|
8
|
+
import * as React from "react";
|
|
9
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
var Dialog = DialogPrimitive.Root;
|
|
11
|
+
var DialogTrigger = DialogPrimitive.Trigger;
|
|
12
|
+
var DialogPortal = DialogPrimitive.Portal;
|
|
13
|
+
var DialogClose = DialogPrimitive.Close;
|
|
14
|
+
var DialogOverlay = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
15
|
+
DialogPrimitive.Overlay,
|
|
16
|
+
{
|
|
17
|
+
ref,
|
|
18
|
+
className: cn(
|
|
19
|
+
"fixed inset-0 z-50 bg-black/80 backdrop-blur-sm",
|
|
20
|
+
"data-[state=closed]:animate-out data-[state=open]:animate-in",
|
|
21
|
+
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
22
|
+
className
|
|
23
|
+
),
|
|
24
|
+
...props
|
|
25
|
+
}
|
|
26
|
+
));
|
|
27
|
+
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
28
|
+
var DialogContent = React.forwardRef(({ className, children, variant = "default", ...props }, ref) => {
|
|
29
|
+
const variants = {
|
|
30
|
+
default: "border-border",
|
|
31
|
+
sandbox: "border-purple-500/20 shadow-lg shadow-purple-500/10"
|
|
32
|
+
};
|
|
33
|
+
return /* @__PURE__ */ jsxs(DialogPortal, { children: [
|
|
34
|
+
/* @__PURE__ */ jsx(DialogOverlay, {}),
|
|
35
|
+
/* @__PURE__ */ jsxs(
|
|
36
|
+
DialogPrimitive.Content,
|
|
37
|
+
{
|
|
38
|
+
ref,
|
|
39
|
+
className: cn(
|
|
40
|
+
"fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%]",
|
|
41
|
+
"gap-4 rounded-xl border bg-card p-6 shadow-xl duration-200",
|
|
42
|
+
"data-[state=closed]:animate-out data-[state=open]:animate-in",
|
|
43
|
+
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
44
|
+
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
45
|
+
"data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%]",
|
|
46
|
+
"data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]",
|
|
47
|
+
variants[variant],
|
|
48
|
+
className
|
|
49
|
+
),
|
|
50
|
+
...props,
|
|
51
|
+
children: [
|
|
52
|
+
children,
|
|
53
|
+
/* @__PURE__ */ jsxs(DialogPrimitive.Close, { className: "absolute top-4 right-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground", children: [
|
|
54
|
+
/* @__PURE__ */ jsx(X, { className: "h-4 w-4" }),
|
|
55
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
|
|
56
|
+
] })
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
)
|
|
60
|
+
] });
|
|
61
|
+
});
|
|
62
|
+
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
63
|
+
var DialogHeader = ({
|
|
64
|
+
className,
|
|
65
|
+
...props
|
|
66
|
+
}) => /* @__PURE__ */ jsx(
|
|
67
|
+
"div",
|
|
68
|
+
{
|
|
69
|
+
className: cn(
|
|
70
|
+
"flex flex-col space-y-1.5 text-center sm:text-left",
|
|
71
|
+
className
|
|
72
|
+
),
|
|
73
|
+
...props
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
DialogHeader.displayName = "DialogHeader";
|
|
77
|
+
var DialogFooter = ({
|
|
78
|
+
className,
|
|
79
|
+
...props
|
|
80
|
+
}) => /* @__PURE__ */ jsx(
|
|
81
|
+
"div",
|
|
82
|
+
{
|
|
83
|
+
className: cn(
|
|
84
|
+
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
|
|
85
|
+
className
|
|
86
|
+
),
|
|
87
|
+
...props
|
|
88
|
+
}
|
|
89
|
+
);
|
|
90
|
+
DialogFooter.displayName = "DialogFooter";
|
|
91
|
+
var DialogTitle = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
92
|
+
DialogPrimitive.Title,
|
|
93
|
+
{
|
|
94
|
+
ref,
|
|
95
|
+
className: cn(
|
|
96
|
+
"font-semibold text-lg leading-none tracking-tight",
|
|
97
|
+
className
|
|
98
|
+
),
|
|
99
|
+
...props
|
|
100
|
+
}
|
|
101
|
+
));
|
|
102
|
+
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
103
|
+
var DialogDescription = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
104
|
+
DialogPrimitive.Description,
|
|
105
|
+
{
|
|
106
|
+
ref,
|
|
107
|
+
className: cn("text-muted-foreground text-sm", className),
|
|
108
|
+
...props
|
|
109
|
+
}
|
|
110
|
+
));
|
|
111
|
+
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
112
|
+
|
|
113
|
+
// src/primitives/input.tsx
|
|
114
|
+
import * as React2 from "react";
|
|
115
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
116
|
+
var Input = React2.forwardRef(
|
|
117
|
+
({ className, type, variant = "default", label, error, hint, id, ...props }, ref) => {
|
|
118
|
+
const inputId = id ?? label?.toLowerCase().replace(/\s+/g, "-");
|
|
119
|
+
const variants = {
|
|
120
|
+
default: "border-input focus:ring-ring",
|
|
121
|
+
sandbox: "border-purple-500/20 focus:border-purple-500/50 focus:ring-purple-500/20"
|
|
122
|
+
};
|
|
123
|
+
const input = /* @__PURE__ */ jsx2(
|
|
124
|
+
"input",
|
|
125
|
+
{
|
|
126
|
+
type,
|
|
127
|
+
id: inputId,
|
|
128
|
+
className: cn(
|
|
129
|
+
"flex h-11 w-full rounded-lg border bg-card/50 px-4 py-2 text-sm transition-all duration-200",
|
|
130
|
+
"placeholder:text-muted-foreground",
|
|
131
|
+
"focus:outline-none focus:ring-2 focus:ring-offset-0",
|
|
132
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
133
|
+
"file:border-0 file:bg-transparent file:font-medium file:text-sm",
|
|
134
|
+
error ? "border-red-500/50 focus:ring-red-500/20" : variants[variant],
|
|
135
|
+
className
|
|
136
|
+
),
|
|
137
|
+
ref,
|
|
138
|
+
...props
|
|
139
|
+
}
|
|
140
|
+
);
|
|
141
|
+
if (!label && !error && !hint) return input;
|
|
142
|
+
return /* @__PURE__ */ jsxs2("div", { className: "w-full space-y-1.5", children: [
|
|
143
|
+
label && /* @__PURE__ */ jsx2(
|
|
144
|
+
"label",
|
|
145
|
+
{
|
|
146
|
+
htmlFor: inputId,
|
|
147
|
+
className: "block font-medium text-muted-foreground text-sm",
|
|
148
|
+
children: label
|
|
149
|
+
}
|
|
150
|
+
),
|
|
151
|
+
input,
|
|
152
|
+
error && /* @__PURE__ */ jsx2("p", { className: "text-red-400 text-sm", children: error }),
|
|
153
|
+
hint && !error && /* @__PURE__ */ jsx2("p", { className: "text-muted-foreground/70 text-sm", children: hint })
|
|
154
|
+
] });
|
|
155
|
+
}
|
|
156
|
+
);
|
|
157
|
+
Input.displayName = "Input";
|
|
158
|
+
var Textarea = React2.forwardRef(
|
|
159
|
+
({ className, variant = "default", label, error, hint, id, ...props }, ref) => {
|
|
160
|
+
const textareaId = id ?? label?.toLowerCase().replace(/\s+/g, "-");
|
|
161
|
+
const variants = {
|
|
162
|
+
default: "border-input focus:ring-ring",
|
|
163
|
+
sandbox: "border-purple-500/20 focus:border-purple-500/50 focus:ring-purple-500/20"
|
|
164
|
+
};
|
|
165
|
+
const textarea = /* @__PURE__ */ jsx2(
|
|
166
|
+
"textarea",
|
|
167
|
+
{
|
|
168
|
+
id: textareaId,
|
|
169
|
+
className: cn(
|
|
170
|
+
"flex min-h-[120px] w-full resize-y rounded-lg border bg-card/50 px-4 py-3 text-sm transition-all duration-200",
|
|
171
|
+
"placeholder:text-muted-foreground",
|
|
172
|
+
"focus:outline-none focus:ring-2 focus:ring-offset-0",
|
|
173
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
174
|
+
error ? "border-red-500/50 focus:ring-red-500/20" : variants[variant],
|
|
175
|
+
className
|
|
176
|
+
),
|
|
177
|
+
ref,
|
|
178
|
+
...props
|
|
179
|
+
}
|
|
180
|
+
);
|
|
181
|
+
if (!label && !error && !hint) return textarea;
|
|
182
|
+
return /* @__PURE__ */ jsxs2("div", { className: "w-full space-y-1.5", children: [
|
|
183
|
+
label && /* @__PURE__ */ jsx2(
|
|
184
|
+
"label",
|
|
185
|
+
{
|
|
186
|
+
htmlFor: textareaId,
|
|
187
|
+
className: "block font-medium text-muted-foreground text-sm",
|
|
188
|
+
children: label
|
|
189
|
+
}
|
|
190
|
+
),
|
|
191
|
+
textarea,
|
|
192
|
+
error && /* @__PURE__ */ jsx2("p", { className: "text-red-400 text-sm", children: error }),
|
|
193
|
+
hint && !error && /* @__PURE__ */ jsx2("p", { className: "text-muted-foreground/70 text-sm", children: hint })
|
|
194
|
+
] });
|
|
195
|
+
}
|
|
196
|
+
);
|
|
197
|
+
Textarea.displayName = "Textarea";
|
|
198
|
+
|
|
199
|
+
// src/primitives/tabs.tsx
|
|
200
|
+
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
|
201
|
+
import * as React3 from "react";
|
|
202
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
203
|
+
var Tabs = TabsPrimitive.Root;
|
|
204
|
+
var TabsList = React3.forwardRef(({ className, variant = "default", ...props }, ref) => {
|
|
205
|
+
const variants = {
|
|
206
|
+
default: "inline-flex h-10 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
|
|
207
|
+
pills: "inline-flex items-center gap-2",
|
|
208
|
+
underline: "inline-flex items-center gap-4 border-b border-border"
|
|
209
|
+
};
|
|
210
|
+
return /* @__PURE__ */ jsx3(
|
|
211
|
+
TabsPrimitive.List,
|
|
212
|
+
{
|
|
213
|
+
ref,
|
|
214
|
+
className: cn(variants[variant], className),
|
|
215
|
+
...props
|
|
216
|
+
}
|
|
217
|
+
);
|
|
218
|
+
});
|
|
219
|
+
TabsList.displayName = TabsPrimitive.List.displayName;
|
|
220
|
+
var TabsTrigger = React3.forwardRef(({ className, variant = "default", ...props }, ref) => {
|
|
221
|
+
const variants = {
|
|
222
|
+
default: "inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
|
|
223
|
+
pills: "inline-flex items-center justify-center whitespace-nowrap rounded-full px-4 py-2 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-primary data-[state=active]:text-primary-foreground data-[state=inactive]:text-muted-foreground data-[state=inactive]:hover:bg-muted",
|
|
224
|
+
underline: "inline-flex items-center justify-center whitespace-nowrap pb-3 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 border-b-2 border-transparent data-[state=active]:border-primary data-[state=active]:text-foreground data-[state=inactive]:text-muted-foreground"
|
|
225
|
+
};
|
|
226
|
+
return /* @__PURE__ */ jsx3(
|
|
227
|
+
TabsPrimitive.Trigger,
|
|
228
|
+
{
|
|
229
|
+
ref,
|
|
230
|
+
className: cn(variants[variant], className),
|
|
231
|
+
...props
|
|
232
|
+
}
|
|
233
|
+
);
|
|
234
|
+
});
|
|
235
|
+
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
|
236
|
+
var TabsContent = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx3(
|
|
237
|
+
TabsPrimitive.Content,
|
|
238
|
+
{
|
|
239
|
+
ref,
|
|
240
|
+
className: cn(
|
|
241
|
+
"mt-4 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
242
|
+
"data-[state=active]:fade-in-0 data-[state=active]:slide-in-from-bottom-2 data-[state=active]:animate-in",
|
|
243
|
+
className
|
|
244
|
+
),
|
|
245
|
+
...props
|
|
246
|
+
}
|
|
247
|
+
));
|
|
248
|
+
TabsContent.displayName = TabsPrimitive.Content.displayName;
|
|
249
|
+
|
|
250
|
+
// src/primitives/empty-state.tsx
|
|
251
|
+
import * as React4 from "react";
|
|
252
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
253
|
+
var EmptyState = React4.forwardRef(
|
|
254
|
+
({ className, icon, title, description, action, ...props }, ref) => {
|
|
255
|
+
return /* @__PURE__ */ jsxs3(
|
|
256
|
+
"div",
|
|
257
|
+
{
|
|
258
|
+
ref,
|
|
259
|
+
className: cn(
|
|
260
|
+
"flex flex-col items-center justify-center px-4 py-16 text-center",
|
|
261
|
+
className
|
|
262
|
+
),
|
|
263
|
+
...props,
|
|
264
|
+
children: [
|
|
265
|
+
icon && /* @__PURE__ */ jsx4("div", { className: "mb-4 rounded-full bg-muted p-4 text-muted-foreground", children: icon }),
|
|
266
|
+
/* @__PURE__ */ jsx4("h3", { className: "font-semibold text-lg", children: title }),
|
|
267
|
+
description && /* @__PURE__ */ jsx4("p", { className: "mt-2 max-w-sm text-muted-foreground text-sm", children: description }),
|
|
268
|
+
action && /* @__PURE__ */ jsx4("div", { className: "mt-6", children: action })
|
|
269
|
+
]
|
|
270
|
+
}
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
);
|
|
274
|
+
EmptyState.displayName = "EmptyState";
|
|
275
|
+
|
|
276
|
+
export {
|
|
277
|
+
Dialog,
|
|
278
|
+
DialogTrigger,
|
|
279
|
+
DialogPortal,
|
|
280
|
+
DialogClose,
|
|
281
|
+
DialogOverlay,
|
|
282
|
+
DialogContent,
|
|
283
|
+
DialogHeader,
|
|
284
|
+
DialogFooter,
|
|
285
|
+
DialogTitle,
|
|
286
|
+
DialogDescription,
|
|
287
|
+
Input,
|
|
288
|
+
Textarea,
|
|
289
|
+
Tabs,
|
|
290
|
+
TabsList,
|
|
291
|
+
TabsTrigger,
|
|
292
|
+
TabsContent,
|
|
293
|
+
EmptyState
|
|
294
|
+
};
|