@tangle-network/ui 11.9.0 → 11.11.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.
Files changed (155) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +14 -0
  3. package/dist/active-sessions-store-Gt1R0rFG.js +262 -0
  4. package/dist/{active-sessions-store-CeOmXgv5.d.ts → active-sessions-store-nl70ZnMC.d.ts} +40 -41
  5. package/dist/artifact-pane-BL_DFWNl.d.ts +32 -0
  6. package/dist/artifact-pane-DMXT9a8U.js +70 -0
  7. package/dist/auth-DixfCMCk.js +154 -0
  8. package/dist/auth.d.ts +2 -74
  9. package/dist/auth.js +2 -15
  10. package/dist/branding-26d5ARIr.d.ts +14 -0
  11. package/dist/button-uhNnwdsD.js +78 -0
  12. package/dist/button-yoIv77e2.d.ts +16 -0
  13. package/dist/chat-CPLL0Fd9.js +667 -0
  14. package/dist/chat.d.ts +2 -201
  15. package/dist/chat.js +2 -30
  16. package/dist/code-block-B9miUPht.d.ts +23 -0
  17. package/dist/code-block-CngSn37j.js +165 -0
  18. package/dist/diff-preview-cySuqowW.js +533 -0
  19. package/dist/document-editor-pane-BcoABlhn.d.ts +131 -0
  20. package/dist/document-editor-pane-Cz6oEF1o.js +1287 -0
  21. package/dist/dropdown-menu-BpcLa5vF.js +101 -0
  22. package/dist/editor.d.ts +76 -78
  23. package/dist/editor.js +2 -33
  24. package/dist/file-format-BgXbr-Ib.js +160 -0
  25. package/dist/files-CYlOo0mE.js +743 -0
  26. package/dist/files.d.ts +2 -243
  27. package/dist/files.js +3 -40
  28. package/dist/focus-Cw02pNSr.js +56 -0
  29. package/dist/format-DfcLWqMa.js +54 -0
  30. package/dist/hooks.d.ts +30 -37
  31. package/dist/hooks.js +111 -45
  32. package/dist/index-2UntyjBb.d.ts +52 -0
  33. package/dist/index-COgqsFAQ.d.ts +42 -0
  34. package/dist/index-CPDET_s1.d.ts +549 -0
  35. package/dist/index-CUhfHT_V.d.ts +204 -0
  36. package/dist/index-Cg6gYAqh.d.ts +73 -0
  37. package/dist/index-Cq-EJzqW.d.ts +16 -0
  38. package/dist/index-DhYmSaLF.d.ts +245 -0
  39. package/dist/index-DjKxO357.d.ts +128 -0
  40. package/dist/index-b56ew9aF.d.ts +107 -0
  41. package/dist/index.d.ts +26 -43
  42. package/dist/index.js +35 -460
  43. package/dist/markdown-BprL96Gl.js +45 -0
  44. package/dist/markdown.d.ts +3 -18
  45. package/dist/markdown.js +3 -14
  46. package/dist/message-vhUI0c5G.d.ts +16 -0
  47. package/dist/nav.d.ts +6 -8
  48. package/dist/nav.js +29 -11
  49. package/dist/openui-artifact-renderer-D3E5bIAI.d.ts +114 -0
  50. package/dist/openui-artifact-renderer-DT4xbvWt.js +266 -0
  51. package/dist/openui.d.ts +2 -115
  52. package/dist/openui.js +2 -12
  53. package/dist/parts-5mhy9yJ3.d.ts +37 -0
  54. package/dist/primitives-DE-blUz-.js +1239 -0
  55. package/dist/primitives.d.ts +5 -523
  56. package/dist/primitives.js +9 -211
  57. package/dist/redaction-CGGB2ENG.js +74 -0
  58. package/dist/redaction.d.ts +2 -42
  59. package/dist/redaction.js +2 -7
  60. package/dist/run-OyWmIDqu.d.ts +41 -0
  61. package/dist/run-ZsIKPA6J.js +17 -0
  62. package/dist/run-group-D1InSdQu.js +410 -0
  63. package/dist/run.d.ts +3 -126
  64. package/dist/run.js +5 -39
  65. package/dist/sdk-hooks.d.ts +2 -285
  66. package/dist/sdk-hooks.js +3 -35
  67. package/dist/stores.d.ts +13 -14
  68. package/dist/stores.js +34 -76
  69. package/dist/table-DHyqDPbU.js +146 -0
  70. package/dist/tabs-ujuqAdtb.js +40 -0
  71. package/dist/text-shimmer-BUUo6I-g.js +64 -0
  72. package/dist/tool-call-feed-BeB1_4pX.d.ts +47 -0
  73. package/dist/tool-call-feed-C1W1N54c.js +109 -0
  74. package/dist/tool-call-step-Bi3_YJRV.js +434 -0
  75. package/dist/tool-display-BAuAVa43.js +158 -0
  76. package/dist/{tool-display-z4JcDmMQ.d.ts → tool-display-DgmL5rIU.d.ts} +16 -16
  77. package/dist/tool-previews.d.ts +2 -48
  78. package/dist/tool-previews.js +2 -22
  79. package/dist/types.d.ts +6 -19
  80. package/dist/types.js +0 -1
  81. package/dist/use-auto-scroll-C5Pjeqon.js +153 -0
  82. package/dist/use-sse-stream-BjVBDbxK.js +884 -0
  83. package/dist/use-sse-stream-Dm6R5YWz.d.ts +282 -0
  84. package/dist/utils-Bl_CZ0Qp.js +37 -0
  85. package/dist/{chunk-RQHJBTEU.js → utils-C_uf36nf.js} +4 -6
  86. package/dist/utils.d.ts +2 -51
  87. package/dist/utils.js +6 -32
  88. package/package.json +39 -41
  89. package/src/auth/auth.tsx +5 -1
  90. package/src/chat/agent-timeline.tsx +6 -1
  91. package/src/chat/chat-container.tsx +2 -1
  92. package/src/editor/document-editor-pane.test.tsx +3 -1
  93. package/src/editor/document-editor-pane.tsx +5 -1
  94. package/src/editor/markdown-document-editor.test.tsx +9 -4
  95. package/src/files/file-artifact-pane.tsx +3 -2
  96. package/src/files/file-preview.tsx +3 -1
  97. package/src/files/file-tabs.tsx +9 -2
  98. package/src/lib/focus.ts +63 -0
  99. package/src/markdown/code-block.tsx +5 -1
  100. package/src/primitives/badge.tsx +2 -1
  101. package/src/primitives/button.tsx +2 -1
  102. package/src/primitives/card.tsx +1 -2
  103. package/src/primitives/dialog.tsx +7 -1
  104. package/src/primitives/input.tsx +15 -14
  105. package/src/primitives/segmented-control.tsx +5 -3
  106. package/src/primitives/select.tsx +3 -1
  107. package/src/primitives/switch.tsx +3 -1
  108. package/src/primitives/tabs.tsx +6 -4
  109. package/src/primitives/terminal-display.tsx +6 -8
  110. package/src/primitives/toast.tsx +5 -1
  111. package/src/tool-previews/command-preview.tsx +5 -1
  112. package/src/tool-previews/web-search-preview.tsx +2 -1
  113. package/src/utils/index.ts +7 -0
  114. package/dist/artifact-pane-DpuWcAiF.d.ts +0 -33
  115. package/dist/button-CMQuQEW_.d.ts +0 -17
  116. package/dist/chunk-34A66VBG.js +0 -214
  117. package/dist/chunk-3OI2QKFD.js +0 -0
  118. package/dist/chunk-3TI5DEHV.js +0 -299
  119. package/dist/chunk-4CLN43XT.js +0 -45
  120. package/dist/chunk-565EATZZ.js +0 -156
  121. package/dist/chunk-5Z5ZYMOJ.js +0 -0
  122. package/dist/chunk-6BGQA4BQ.js +0 -0
  123. package/dist/chunk-7YOCS6IF.js +0 -728
  124. package/dist/chunk-EOAX2ENE.js +0 -60
  125. package/dist/chunk-GYPQXTJU.js +0 -230
  126. package/dist/chunk-HFL6R6IF.js +0 -37
  127. package/dist/chunk-HGML45QH.js +0 -104
  128. package/dist/chunk-KNYSKNZX.js +0 -550
  129. package/dist/chunk-L57WRIND.js +0 -59
  130. package/dist/chunk-LDLOJKPC.js +0 -1585
  131. package/dist/chunk-LTEKI7YJ.js +0 -59
  132. package/dist/chunk-MKTSMWVD.js +0 -109
  133. package/dist/chunk-ND3ZFXQK.js +0 -179
  134. package/dist/chunk-NKDZ7GZE.js +0 -192
  135. package/dist/chunk-NWECTSOH.js +0 -589
  136. package/dist/chunk-OEX7NZE3.js +0 -321
  137. package/dist/chunk-Q56BYXQF.js +0 -61
  138. package/dist/chunk-REJESC5U.js +0 -117
  139. package/dist/chunk-RQGKSCEZ.js +0 -0
  140. package/dist/chunk-TN4FUEWY.js +0 -437
  141. package/dist/chunk-VPWY4I5O.js +0 -1048
  142. package/dist/chunk-WUQDUBJG.js +0 -168
  143. package/dist/chunk-XGKULLYE.js +0 -40
  144. package/dist/chunk-XU3HB5QL.js +0 -127
  145. package/dist/chunk-XYAIX4SU.js +0 -133
  146. package/dist/chunk-YJ6RE5WV.js +0 -875
  147. package/dist/chunk-YTO5V6QS.js +0 -19
  148. package/dist/chunk-ZKCEAIIZ.js +0 -1395
  149. package/dist/code-block-0kSpWMnf.d.ts +0 -25
  150. package/dist/document-editor-pane-EX25CEYW.js +0 -12
  151. package/dist/document-editor-pane-IAEQn_Dl.d.ts +0 -128
  152. package/dist/message-BHWbxBtT.d.ts +0 -15
  153. package/dist/parts-dj7AcUg0.d.ts +0 -36
  154. package/dist/run-PfLmDAox.d.ts +0 -41
  155. package/dist/tool-call-feed-D9iofJgW.d.ts +0 -46
@@ -1,1585 +0,0 @@
1
- import {
2
- Card
3
- } from "./chunk-GYPQXTJU.js";
4
- import {
5
- cn
6
- } from "./chunk-RQHJBTEU.js";
7
-
8
- // src/primitives/dialog.tsx
9
- import * as DialogPrimitive from "@radix-ui/react-dialog";
10
- import { X } from "lucide-react";
11
- import * as React from "react";
12
- import { jsx, jsxs } from "react/jsx-runtime";
13
- var Dialog = DialogPrimitive.Root;
14
- var DialogTrigger = DialogPrimitive.Trigger;
15
- var DialogPortal = DialogPrimitive.Portal;
16
- var DialogClose = DialogPrimitive.Close;
17
- var DialogOverlay = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
18
- DialogPrimitive.Overlay,
19
- {
20
- ref,
21
- className: cn(
22
- "fixed inset-0 z-50 bg-black/40",
23
- "data-[state=closed]:animate-out data-[state=open]:animate-in",
24
- "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
25
- className
26
- ),
27
- ...props
28
- }
29
- ));
30
- DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
31
- var DialogContent = React.forwardRef(({ className, children, variant = "default", ...props }, ref) => {
32
- const variants = {
33
- default: "border-border",
34
- sandbox: "border-[var(--border-accent)] shadow-[var(--shadow-accent)]"
35
- };
36
- return /* @__PURE__ */ jsxs(DialogPortal, { children: [
37
- /* @__PURE__ */ jsx(DialogOverlay, {}),
38
- /* @__PURE__ */ jsxs(
39
- DialogPrimitive.Content,
40
- {
41
- ref,
42
- className: cn(
43
- "fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%]",
44
- "gap-4 rounded-lg border bg-card p-6 shadow-lg duration-200",
45
- "data-[state=closed]:animate-out data-[state=open]:animate-in",
46
- "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
47
- "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
48
- "data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%]",
49
- "data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]",
50
- variants[variant],
51
- className
52
- ),
53
- ...props,
54
- children: [
55
- children,
56
- /* @__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: [
57
- /* @__PURE__ */ jsx(X, { className: "h-4 w-4" }),
58
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
59
- ] })
60
- ]
61
- }
62
- )
63
- ] });
64
- });
65
- DialogContent.displayName = DialogPrimitive.Content.displayName;
66
- var DialogHeader = ({
67
- className,
68
- ...props
69
- }) => /* @__PURE__ */ jsx(
70
- "div",
71
- {
72
- className: cn(
73
- "flex flex-col space-y-1.5 text-center sm:text-left",
74
- className
75
- ),
76
- ...props
77
- }
78
- );
79
- DialogHeader.displayName = "DialogHeader";
80
- var DialogFooter = ({
81
- className,
82
- ...props
83
- }) => /* @__PURE__ */ jsx(
84
- "div",
85
- {
86
- className: cn(
87
- "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
88
- className
89
- ),
90
- ...props
91
- }
92
- );
93
- DialogFooter.displayName = "DialogFooter";
94
- var DialogTitle = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
95
- DialogPrimitive.Title,
96
- {
97
- ref,
98
- className: cn(
99
- "font-semibold text-lg leading-none tracking-tight",
100
- className
101
- ),
102
- ...props
103
- }
104
- ));
105
- DialogTitle.displayName = DialogPrimitive.Title.displayName;
106
- var DialogDescription = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
107
- DialogPrimitive.Description,
108
- {
109
- ref,
110
- className: cn("text-muted-foreground text-sm", className),
111
- ...props
112
- }
113
- ));
114
- DialogDescription.displayName = DialogPrimitive.Description.displayName;
115
-
116
- // src/primitives/input.tsx
117
- import * as React2 from "react";
118
- import { cva } from "class-variance-authority";
119
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
120
- var inputVariants = cva(
121
- "flex w-full rounded-lg border bg-card px-4 py-2 text-sm transition-all duration-200 placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-offset-0 disabled:cursor-not-allowed disabled:opacity-50 file:border-0 file:bg-transparent file:font-medium file:text-sm",
122
- {
123
- variants: {
124
- variant: {
125
- default: "border-input focus:ring-ring",
126
- sandbox: "border-border focus:border-[var(--border-accent-hover)] focus:ring-[var(--border-accent)]",
127
- error: "border-[var(--surface-danger-border)] focus:ring-[var(--surface-danger-border)]"
128
- },
129
- size: {
130
- default: "h-11",
131
- sm: "h-9 px-3",
132
- lg: "h-12 px-5"
133
- }
134
- },
135
- defaultVariants: {
136
- variant: "default",
137
- size: "default"
138
- }
139
- }
140
- );
141
- var Input = React2.forwardRef(
142
- ({ className, type, variant, size, label, error, hint, id, ...props }, ref) => {
143
- const inputId = id ?? label?.toLowerCase().replace(/\s+/g, "-");
144
- const input = /* @__PURE__ */ jsx2(
145
- "input",
146
- {
147
- type,
148
- id: inputId,
149
- className: cn(inputVariants({ variant: error ? "error" : variant, size, className })),
150
- ref,
151
- ...props
152
- }
153
- );
154
- if (!label && !error && !hint) return input;
155
- return /* @__PURE__ */ jsxs2("div", { className: "w-full space-y-1.5", children: [
156
- label && /* @__PURE__ */ jsx2(
157
- "label",
158
- {
159
- htmlFor: inputId,
160
- className: "block font-medium text-foreground text-sm",
161
- children: label
162
- }
163
- ),
164
- input,
165
- error && /* @__PURE__ */ jsx2("p", { className: "text-[var(--surface-danger-text)] text-sm font-medium", children: error }),
166
- hint && !error && /* @__PURE__ */ jsx2("p", { className: "text-[var(--text-dim)] text-sm", children: hint })
167
- ] });
168
- }
169
- );
170
- Input.displayName = "Input";
171
- var Textarea = React2.forwardRef(
172
- ({ className, variant = "default", label, error, hint, id, ...props }, ref) => {
173
- const textareaId = id ?? label?.toLowerCase().replace(/\s+/g, "-");
174
- const variants = {
175
- default: "border-input focus:ring-ring",
176
- sandbox: "border-border focus:border-[var(--border-accent-hover)] focus:ring-[var(--border-accent)]"
177
- };
178
- const textarea = /* @__PURE__ */ jsx2(
179
- "textarea",
180
- {
181
- id: textareaId,
182
- className: cn(
183
- "flex min-h-[120px] w-full resize-y rounded-lg border bg-card px-4 py-3 text-sm transition-all duration-200",
184
- "placeholder:text-muted-foreground",
185
- "focus:outline-none focus:ring-2 focus:ring-offset-0",
186
- "disabled:cursor-not-allowed disabled:opacity-50",
187
- error ? "border-[var(--surface-danger-border)] focus:ring-[var(--surface-danger-border)]" : variants[variant],
188
- className
189
- ),
190
- ref,
191
- ...props
192
- }
193
- );
194
- if (!label && !error && !hint) return textarea;
195
- return /* @__PURE__ */ jsxs2("div", { className: "w-full space-y-1.5", children: [
196
- label && /* @__PURE__ */ jsx2(
197
- "label",
198
- {
199
- htmlFor: textareaId,
200
- className: "block font-medium text-muted-foreground text-sm",
201
- children: label
202
- }
203
- ),
204
- textarea,
205
- error && /* @__PURE__ */ jsx2("p", { className: "text-[var(--surface-danger-text)] text-sm", children: error }),
206
- hint && !error && /* @__PURE__ */ jsx2("p", { className: "text-[var(--text-dim)] text-sm", children: hint })
207
- ] });
208
- }
209
- );
210
- Textarea.displayName = "Textarea";
211
-
212
- // src/primitives/select.tsx
213
- import * as SelectPrimitive from "@radix-ui/react-select";
214
- import { Check, ChevronDown, ChevronUp } from "lucide-react";
215
- import * as React3 from "react";
216
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
217
- var Select = SelectPrimitive.Root;
218
- var SelectGroup = SelectPrimitive.Group;
219
- var SelectValue = SelectPrimitive.Value;
220
- var SelectTrigger = React3.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs3(
221
- SelectPrimitive.Trigger,
222
- {
223
- ref,
224
- className: cn(
225
- "flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-border bg-card px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-primary disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
226
- className
227
- ),
228
- ...props,
229
- children: [
230
- children,
231
- /* @__PURE__ */ jsx3(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx3(ChevronDown, { className: "h-4 w-4 opacity-50" }) })
232
- ]
233
- }
234
- ));
235
- SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
236
- var SelectScrollUpButton = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx3(
237
- SelectPrimitive.ScrollUpButton,
238
- {
239
- ref,
240
- className: cn(
241
- "flex cursor-default items-center justify-center py-1",
242
- className
243
- ),
244
- ...props,
245
- children: /* @__PURE__ */ jsx3(ChevronUp, { className: "h-4 w-4" })
246
- }
247
- ));
248
- SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
249
- var SelectScrollDownButton = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx3(
250
- SelectPrimitive.ScrollDownButton,
251
- {
252
- ref,
253
- className: cn(
254
- "flex cursor-default items-center justify-center py-1",
255
- className
256
- ),
257
- ...props,
258
- children: /* @__PURE__ */ jsx3(ChevronDown, { className: "h-4 w-4" })
259
- }
260
- ));
261
- SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
262
- var SelectContent = React3.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx3(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs3(
263
- SelectPrimitive.Content,
264
- {
265
- ref,
266
- className: cn(
267
- "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border border-border bg-card text-foreground shadow-[var(--shadow-card)] data-[state=closed]:animate-out data-[state=open]:animate-in",
268
- position === "popper" && "data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=bottom]:translate-y-1 data-[side=top]:-translate-y-1",
269
- className
270
- ),
271
- position,
272
- ...props,
273
- children: [
274
- /* @__PURE__ */ jsx3(SelectScrollUpButton, {}),
275
- /* @__PURE__ */ jsx3(
276
- SelectPrimitive.Viewport,
277
- {
278
- className: cn(
279
- "p-1",
280
- position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
281
- ),
282
- children
283
- }
284
- ),
285
- /* @__PURE__ */ jsx3(SelectScrollDownButton, {})
286
- ]
287
- }
288
- ) }));
289
- SelectContent.displayName = SelectPrimitive.Content.displayName;
290
- var SelectLabel = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx3(
291
- SelectPrimitive.Label,
292
- {
293
- ref,
294
- className: cn("px-2 py-1.5 font-semibold text-sm", className),
295
- ...props
296
- }
297
- ));
298
- SelectLabel.displayName = SelectPrimitive.Label.displayName;
299
- var SelectItem = React3.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs3(
300
- SelectPrimitive.Item,
301
- {
302
- ref,
303
- className: cn(
304
- "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pr-8 pl-2 text-sm outline-none focus:bg-muted/50 focus:text-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
305
- className
306
- ),
307
- ...props,
308
- children: [
309
- /* @__PURE__ */ jsx3("span", { className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx3(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx3(Check, { className: "h-4 w-4" }) }) }),
310
- /* @__PURE__ */ jsx3(SelectPrimitive.ItemText, { children })
311
- ]
312
- }
313
- ));
314
- SelectItem.displayName = SelectPrimitive.Item.displayName;
315
- var SelectSeparator = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx3(
316
- SelectPrimitive.Separator,
317
- {
318
- ref,
319
- className: cn("-mx-1 my-1 h-px bg-border", className),
320
- ...props
321
- }
322
- ));
323
- SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
324
-
325
- // src/primitives/segmented-control.tsx
326
- import * as React4 from "react";
327
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
328
- function SegmentedControl({
329
- value,
330
- onValueChange,
331
- options,
332
- variant = "row",
333
- className,
334
- ...rest
335
- }) {
336
- if (typeof process !== "undefined" && process?.env?.NODE_ENV !== "production" && !rest["aria-label"] && !rest["aria-labelledby"]) {
337
- console.warn(
338
- '[SegmentedControl] role="radiogroup" requires either aria-label or aria-labelledby for accessibility.'
339
- );
340
- }
341
- const optionRefs = React4.useRef(/* @__PURE__ */ new Map());
342
- const hasMatch = options.some((o) => o.value === value);
343
- const handleKeyDown = (e) => {
344
- if (options.length === 0) return;
345
- let idx = options.findIndex((o) => o.value === value);
346
- if (idx === -1) idx = 0;
347
- let next;
348
- if (e.key === "ArrowRight" || e.key === "ArrowDown") next = (idx + 1) % options.length;
349
- else if (e.key === "ArrowLeft" || e.key === "ArrowUp") next = (idx - 1 + options.length) % options.length;
350
- else if (e.key === "Home") next = 0;
351
- else if (e.key === "End") next = options.length - 1;
352
- if (next !== void 0) {
353
- e.preventDefault();
354
- if (options[next].value !== value) {
355
- onValueChange(options[next].value);
356
- }
357
- optionRefs.current.get(options[next].value)?.focus();
358
- }
359
- };
360
- return /* @__PURE__ */ jsx4(
361
- "div",
362
- {
363
- role: "radiogroup",
364
- id: rest.id,
365
- "aria-label": rest["aria-label"],
366
- "aria-labelledby": rest["aria-labelledby"],
367
- onKeyDown: handleKeyDown,
368
- className: cn(
369
- "flex gap-1",
370
- variant === "row" && "flex-wrap items-center rounded-lg border border-border bg-card p-1",
371
- variant === "tabs" && "flex-nowrap items-end border-b border-border pb-0 overflow-x-auto",
372
- className
373
- ),
374
- children: options.map((option, i) => {
375
- const active = option.value === value;
376
- const focusable = active || !hasMatch && i === 0;
377
- return /* @__PURE__ */ jsxs4(
378
- "button",
379
- {
380
- ref: (el) => {
381
- if (el) optionRefs.current.set(option.value, el);
382
- else optionRefs.current.delete(option.value);
383
- },
384
- type: "button",
385
- role: "radio",
386
- "aria-checked": active,
387
- tabIndex: focusable ? 0 : -1,
388
- onClick: () => {
389
- if (!active) onValueChange(option.value);
390
- },
391
- className: cn(
392
- "relative inline-flex items-center gap-2 whitespace-nowrap text-sm transition-colors",
393
- variant === "row" && "rounded-md px-3 py-1.5",
394
- variant === "tabs" && "rounded-none border-b-2 -mb-px px-4 py-2",
395
- // Active styling is the ONLY styled state — unselected
396
- // segments stay transparent on purpose so they don't
397
- // compete visually with the selection.
398
- active ? variant === "row" ? "border border-transparent bg-[var(--accent-surface)] text-[var(--accent-text)] font-semibold" : "border-[var(--accent-text)] text-[var(--accent-text)] font-semibold" : variant === "row" ? "border border-transparent text-muted-foreground hover:text-foreground" : "border-transparent text-muted-foreground hover:text-foreground"
399
- ),
400
- children: [
401
- /* @__PURE__ */ jsx4("span", { children: option.label }),
402
- option.adornment && /* @__PURE__ */ jsx4(
403
- "span",
404
- {
405
- className: cn(
406
- "text-xs",
407
- active ? "text-[var(--accent-text)]/80" : "text-muted-foreground"
408
- ),
409
- children: option.adornment
410
- }
411
- )
412
- ]
413
- },
414
- option.value
415
- );
416
- })
417
- }
418
- );
419
- }
420
-
421
- // src/primitives/progress.tsx
422
- import * as ProgressPrimitive from "@radix-ui/react-progress";
423
- import * as React5 from "react";
424
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
425
- var Progress = React5.forwardRef(
426
- ({ className, value, variant = "default", showValue = false, ...props }, ref) => {
427
- const indicatorVariants = {
428
- default: "bg-primary",
429
- sandbox: "bg-[image:var(--accent-gradient-strong)]"
430
- };
431
- return /* @__PURE__ */ jsxs5("div", { className: "relative", children: [
432
- /* @__PURE__ */ jsx5(
433
- ProgressPrimitive.Root,
434
- {
435
- ref,
436
- className: cn(
437
- "relative h-2 w-full overflow-hidden rounded-full bg-muted",
438
- className
439
- ),
440
- ...props,
441
- children: /* @__PURE__ */ jsx5(
442
- ProgressPrimitive.Indicator,
443
- {
444
- className: cn(
445
- "h-full w-full flex-1 transition-all duration-300 ease-out",
446
- indicatorVariants[variant]
447
- ),
448
- style: { transform: `translateX(-${100 - (value || 0)}%)` }
449
- }
450
- )
451
- }
452
- ),
453
- showValue && /* @__PURE__ */ jsxs5("span", { className: "absolute -top-6 right-0 text-muted-foreground text-xs", children: [
454
- value,
455
- "%"
456
- ] })
457
- ] });
458
- }
459
- );
460
- Progress.displayName = ProgressPrimitive.Root.displayName;
461
-
462
- // src/primitives/switch.tsx
463
- import * as SwitchPrimitives from "@radix-ui/react-switch";
464
- import * as React6 from "react";
465
- import { jsx as jsx6 } from "react/jsx-runtime";
466
- var Switch = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx6(
467
- SwitchPrimitives.Root,
468
- {
469
- className: cn(
470
- "peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
471
- className
472
- ),
473
- ...props,
474
- ref,
475
- children: /* @__PURE__ */ jsx6(
476
- SwitchPrimitives.Thumb,
477
- {
478
- className: cn(
479
- "pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0"
480
- )
481
- }
482
- )
483
- }
484
- ));
485
- Switch.displayName = SwitchPrimitives.Root.displayName;
486
-
487
- // src/primitives/skeleton.tsx
488
- import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
489
- function Skeleton({
490
- className,
491
- ...props
492
- }) {
493
- return /* @__PURE__ */ jsx7(
494
- "div",
495
- {
496
- className: cn("animate-pulse rounded-lg bg-muted/50", className),
497
- ...props
498
- }
499
- );
500
- }
501
- function SkeletonCard({ className }) {
502
- return /* @__PURE__ */ jsxs6(
503
- "div",
504
- {
505
- className: cn(
506
- "space-y-4 rounded-xl border border-border bg-card p-6",
507
- className
508
- ),
509
- children: [
510
- /* @__PURE__ */ jsx7(Skeleton, { className: "h-4 w-3/4" }),
511
- /* @__PURE__ */ jsx7(Skeleton, { className: "h-4 w-1/2" }),
512
- /* @__PURE__ */ jsxs6("div", { className: "space-y-2 pt-4", children: [
513
- /* @__PURE__ */ jsx7(Skeleton, { className: "h-3 w-full" }),
514
- /* @__PURE__ */ jsx7(Skeleton, { className: "h-3 w-5/6" }),
515
- /* @__PURE__ */ jsx7(Skeleton, { className: "h-3 w-4/6" })
516
- ] })
517
- ]
518
- }
519
- );
520
- }
521
- function SkeletonTable({ rows = 5 }) {
522
- return /* @__PURE__ */ jsxs6("div", { className: "space-y-3", children: [
523
- /* @__PURE__ */ jsxs6("div", { className: "flex gap-4 border-border border-b pb-2", children: [
524
- /* @__PURE__ */ jsx7(Skeleton, { className: "h-4 w-1/4" }),
525
- /* @__PURE__ */ jsx7(Skeleton, { className: "h-4 w-1/4" }),
526
- /* @__PURE__ */ jsx7(Skeleton, { className: "h-4 w-1/4" }),
527
- /* @__PURE__ */ jsx7(Skeleton, { className: "h-4 w-1/4" })
528
- ] }),
529
- Array.from({ length: rows }).map((_, i) => /* @__PURE__ */ jsxs6("div", { className: "flex gap-4", children: [
530
- /* @__PURE__ */ jsx7(Skeleton, { className: "h-4 w-1/4" }),
531
- /* @__PURE__ */ jsx7(Skeleton, { className: "h-4 w-1/4" }),
532
- /* @__PURE__ */ jsx7(Skeleton, { className: "h-4 w-1/4" }),
533
- /* @__PURE__ */ jsx7(Skeleton, { className: "h-4 w-1/4" })
534
- ] }, i))
535
- ] });
536
- }
537
-
538
- // src/primitives/toast.tsx
539
- import { cva as cva2 } from "class-variance-authority";
540
- import {
541
- AlertCircle,
542
- AlertTriangle,
543
- CheckCircle2,
544
- Info,
545
- X as X2
546
- } from "lucide-react";
547
- import * as React7 from "react";
548
- import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
549
- var toastVariants = cva2(
550
- "pointer-events-auto relative flex w-full items-center justify-between gap-3 overflow-hidden rounded-lg border p-4 shadow-lg transition-all",
551
- {
552
- variants: {
553
- variant: {
554
- default: "border-border bg-background text-foreground",
555
- success: "border-[var(--surface-success-border)] bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]",
556
- error: "border-[var(--surface-danger-border)] bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)]",
557
- warning: "border-[var(--surface-warning-border)] bg-[var(--surface-warning-bg)] text-[var(--surface-warning-text)]",
558
- info: "border-[var(--surface-info-border)] bg-[var(--surface-info-bg)] text-[var(--surface-info-text)]"
559
- }
560
- },
561
- defaultVariants: {
562
- variant: "default"
563
- }
564
- }
565
- );
566
- var icons = {
567
- success: CheckCircle2,
568
- error: AlertCircle,
569
- warning: AlertTriangle,
570
- info: Info,
571
- default: Info
572
- };
573
- function ToastComponent({
574
- id,
575
- title,
576
- description,
577
- variant = "default",
578
- onDismiss
579
- }) {
580
- const Icon2 = icons[variant];
581
- return /* @__PURE__ */ jsxs7(
582
- "div",
583
- {
584
- className: cn(toastVariants({ variant })),
585
- role: "alert",
586
- "aria-live": "polite",
587
- children: [
588
- /* @__PURE__ */ jsxs7("div", { className: "flex items-start gap-3", children: [
589
- /* @__PURE__ */ jsx8(Icon2, { className: "h-5 w-5 shrink-0", "aria-hidden": "true" }),
590
- /* @__PURE__ */ jsxs7("div", { className: "flex-1", children: [
591
- /* @__PURE__ */ jsx8("p", { className: "font-medium text-sm", children: title }),
592
- description && /* @__PURE__ */ jsx8("p", { className: "mt-1 text-sm opacity-80", children: description })
593
- ] })
594
- ] }),
595
- /* @__PURE__ */ jsx8(
596
- "button",
597
- {
598
- type: "button",
599
- onClick: () => onDismiss(id),
600
- className: "shrink-0 rounded-md p-1 opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-offset-2",
601
- "aria-label": "Dismiss notification",
602
- children: /* @__PURE__ */ jsx8(X2, { className: "h-4 w-4" })
603
- }
604
- )
605
- ]
606
- }
607
- );
608
- }
609
- function ToastContainer({ toasts, onDismiss }) {
610
- return /* @__PURE__ */ jsx8(
611
- "div",
612
- {
613
- role: "region",
614
- className: "fixed right-4 bottom-4 z-50 flex max-w-md flex-col gap-2",
615
- "aria-label": "Notifications",
616
- children: toasts.map((toast) => /* @__PURE__ */ jsx8(ToastComponent, { ...toast, onDismiss }, toast.id))
617
- }
618
- );
619
- }
620
- var ToastContext = React7.createContext(null);
621
- function ToastProvider({ children }) {
622
- const [toasts, setToasts] = React7.useState([]);
623
- const dismiss = React7.useCallback((id) => {
624
- setToasts((prev) => prev.filter((t) => t.id !== id));
625
- }, []);
626
- const toast = React7.useCallback(
627
- (input) => {
628
- const id = Math.random().toString(36).slice(2);
629
- const newToast = { id, ...input };
630
- setToasts((prev) => [...prev, newToast]);
631
- const duration = input.duration ?? 5e3;
632
- if (duration > 0) {
633
- setTimeout(() => dismiss(id), duration);
634
- }
635
- },
636
- [dismiss]
637
- );
638
- const success = React7.useCallback(
639
- (title, description) => {
640
- toast({ title, description, variant: "success" });
641
- },
642
- [toast]
643
- );
644
- const error = React7.useCallback(
645
- (title, description) => {
646
- toast({ title, description, variant: "error" });
647
- },
648
- [toast]
649
- );
650
- const warning = React7.useCallback(
651
- (title, description) => {
652
- toast({ title, description, variant: "warning" });
653
- },
654
- [toast]
655
- );
656
- const info = React7.useCallback(
657
- (title, description) => {
658
- toast({ title, description, variant: "info" });
659
- },
660
- [toast]
661
- );
662
- const value = React7.useMemo(
663
- () => ({ toasts, toast, success, error, warning, info, dismiss }),
664
- [toasts, toast, success, error, warning, info, dismiss]
665
- );
666
- return /* @__PURE__ */ jsxs7(ToastContext.Provider, { value, children: [
667
- children,
668
- /* @__PURE__ */ jsx8(ToastContainer, { toasts, onDismiss: dismiss })
669
- ] });
670
- }
671
- function useToast() {
672
- const context = React7.useContext(ToastContext);
673
- if (!context) {
674
- throw new Error("useToast must be used within a ToastProvider");
675
- }
676
- return context;
677
- }
678
-
679
- // src/primitives/label.tsx
680
- import * as LabelPrimitive from "@radix-ui/react-label";
681
- import { cva as cva3 } from "class-variance-authority";
682
- import * as React8 from "react";
683
- import { jsx as jsx9 } from "react/jsx-runtime";
684
- var labelVariants = cva3(
685
- "font-medium text-sm leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
686
- );
687
- var Label2 = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx9(
688
- LabelPrimitive.Root,
689
- {
690
- ref,
691
- className: cn(labelVariants(), className),
692
- ...props
693
- }
694
- ));
695
- Label2.displayName = LabelPrimitive.Root.displayName;
696
-
697
- // src/primitives/empty-state.tsx
698
- import * as React9 from "react";
699
- import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
700
- var EmptyState = React9.forwardRef(
701
- ({ className, icon, title, description, action, ...props }, ref) => {
702
- return /* @__PURE__ */ jsxs8(
703
- "div",
704
- {
705
- ref,
706
- className: cn(
707
- "flex flex-col items-center justify-center px-4 py-16 text-center",
708
- className
709
- ),
710
- ...props,
711
- children: [
712
- icon && /* @__PURE__ */ jsx10("div", { className: "mb-4 rounded-full bg-muted p-4 text-muted-foreground", children: icon }),
713
- /* @__PURE__ */ jsx10("h3", { className: "font-semibold text-lg", children: title }),
714
- description && /* @__PURE__ */ jsx10("p", { className: "mt-2 max-w-sm text-muted-foreground text-sm", children: description }),
715
- action && /* @__PURE__ */ jsx10("div", { className: "mt-6", children: action })
716
- ]
717
- }
718
- );
719
- }
720
- );
721
- EmptyState.displayName = "EmptyState";
722
-
723
- // src/primitives/stat-card.tsx
724
- import * as React10 from "react";
725
- import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
726
- var StatCard = React10.forwardRef(
727
- ({
728
- className,
729
- variant = "default",
730
- title,
731
- value,
732
- subtitle,
733
- icon,
734
- trend,
735
- ...props
736
- }, ref) => {
737
- const iconColors = {
738
- default: "text-muted-foreground",
739
- sandbox: "text-[var(--accent-text)]"
740
- };
741
- const trendColors = {
742
- positive: "text-[var(--surface-success-text)]",
743
- negative: "text-[var(--surface-danger-text)]",
744
- neutral: "text-muted-foreground"
745
- };
746
- const trendStatus = trend ? trend.value > 0 ? "positive" : trend.value < 0 ? "negative" : "neutral" : null;
747
- return /* @__PURE__ */ jsx11(
748
- Card,
749
- {
750
- ref,
751
- variant,
752
- className: cn("p-6", className),
753
- ...props,
754
- children: /* @__PURE__ */ jsxs9("div", { className: "flex items-start justify-between", children: [
755
- /* @__PURE__ */ jsxs9("div", { className: "space-y-1", children: [
756
- /* @__PURE__ */ jsx11("p", { className: "text-muted-foreground text-sm", children: title }),
757
- /* @__PURE__ */ jsx11("p", { className: "font-bold text-3xl tracking-tight", children: value }),
758
- subtitle && /* @__PURE__ */ jsx11("p", { className: "text-[var(--text-dim)] text-xs", children: subtitle }),
759
- trend && trendStatus && /* @__PURE__ */ jsxs9(
760
- "div",
761
- {
762
- className: cn(
763
- "flex items-center gap-1 text-sm",
764
- trendColors[trendStatus]
765
- ),
766
- children: [
767
- trend.value > 0 ? "\u2191" : trend.value < 0 ? "\u2193" : "\u2192",
768
- /* @__PURE__ */ jsxs9("span", { children: [
769
- Math.abs(trend.value),
770
- "%"
771
- ] }),
772
- trend.label && /* @__PURE__ */ jsx11("span", { className: "text-muted-foreground", children: trend.label })
773
- ]
774
- }
775
- )
776
- ] }),
777
- icon && /* @__PURE__ */ jsx11(
778
- "div",
779
- {
780
- className: cn(
781
- "rounded-lg bg-muted/50 p-2",
782
- variant === "sandbox" && "bg-[var(--accent-surface-soft)]",
783
- iconColors[variant]
784
- ),
785
- children: icon
786
- }
787
- )
788
- ] })
789
- }
790
- );
791
- }
792
- );
793
- StatCard.displayName = "StatCard";
794
-
795
- // src/primitives/index.ts
796
- import { Logo, TangleKnot } from "@tangle-network/brand";
797
-
798
- // src/primitives/terminal-display.tsx
799
- import * as React11 from "react";
800
- import { useEffect, useRef as useRef2 } from "react";
801
- import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
802
- var TerminalDisplay = React11.forwardRef(
803
- ({
804
- className,
805
- variant = "default",
806
- title = "Terminal",
807
- showHeader = true,
808
- autoScroll = true,
809
- maxHeight = "400px",
810
- children,
811
- ...props
812
- }, ref) => {
813
- const containerRef = useRef2(null);
814
- useEffect(() => {
815
- if (autoScroll && containerRef.current) {
816
- containerRef.current.scrollTop = containerRef.current.scrollHeight;
817
- }
818
- }, [autoScroll]);
819
- const variants = {
820
- default: "border-border",
821
- sandbox: "border-border shadow-[var(--shadow-accent)]"
822
- };
823
- return /* @__PURE__ */ jsxs10(
824
- "div",
825
- {
826
- ref,
827
- className: cn(
828
- "overflow-hidden rounded-xl border bg-background font-mono text-sm",
829
- variants[variant],
830
- className
831
- ),
832
- ...props,
833
- children: [
834
- showHeader && /* @__PURE__ */ jsx12("div", { className: "flex items-center border-b border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx12("span", { className: "text-muted-foreground text-xs", children: title }) }),
835
- /* @__PURE__ */ jsx12(
836
- "div",
837
- {
838
- ref: containerRef,
839
- className: "overflow-auto p-4",
840
- style: { maxHeight },
841
- children
842
- }
843
- )
844
- ]
845
- }
846
- );
847
- }
848
- );
849
- TerminalDisplay.displayName = "TerminalDisplay";
850
- var TerminalLine = React11.forwardRef(
851
- ({ className, type = "output", prompt = "$", timestamp, children, ...props }, ref) => {
852
- const typeStyles = {
853
- input: "text-foreground",
854
- output: "text-foreground",
855
- error: "text-[var(--surface-danger-text)]",
856
- success: "text-[var(--surface-success-text)]",
857
- info: "text-[var(--surface-info-text)]",
858
- thinking: "text-[var(--surface-warning-text)] animate-pulse",
859
- command: "text-foreground",
860
- warning: "text-[var(--surface-warning-text)]"
861
- };
862
- return /* @__PURE__ */ jsxs10(
863
- "div",
864
- {
865
- ref,
866
- className: cn(
867
- "flex items-start gap-2 py-0.5 leading-relaxed",
868
- typeStyles[type],
869
- className
870
- ),
871
- ...props,
872
- children: [
873
- (type === "input" || type === "command") && /* @__PURE__ */ jsx12("span", { className: "shrink-0 select-none text-[var(--surface-success-text)]", children: prompt }),
874
- type === "thinking" && /* @__PURE__ */ jsx12("span", { className: "shrink-0 select-none", children: "..." }),
875
- timestamp && /* @__PURE__ */ jsxs10("span", { className: "shrink-0 select-none text-[var(--text-dim)]", children: [
876
- "[",
877
- timestamp,
878
- "]"
879
- ] }),
880
- /* @__PURE__ */ jsx12("span", { className: "whitespace-pre-wrap break-all", children })
881
- ]
882
- }
883
- );
884
- }
885
- );
886
- TerminalLine.displayName = "TerminalLine";
887
- var TerminalCursor = React11.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx12(
888
- "span",
889
- {
890
- ref,
891
- className: cn(
892
- "ml-0.5 inline-block h-4 w-2 animate-pulse bg-foreground",
893
- className
894
- ),
895
- ...props
896
- }
897
- ));
898
- TerminalCursor.displayName = "TerminalCursor";
899
- var TerminalInput = React11.forwardRef(
900
- ({ className, onSubmit, variant = "default", ...props }, ref) => {
901
- const [value, setValue] = React11.useState("");
902
- const handleKeyDown = (e) => {
903
- if (e.key === "Enter" && value.trim() && onSubmit) {
904
- onSubmit(value.trim());
905
- setValue("");
906
- }
907
- };
908
- const variants = {
909
- default: "border-border focus-within:border-border",
910
- sandbox: "border-border focus-within:border-[var(--border-accent-hover)]"
911
- };
912
- return /* @__PURE__ */ jsxs10(
913
- "div",
914
- {
915
- className: cn(
916
- "flex items-center rounded-lg border bg-background px-4 py-2.5 font-mono text-sm transition-colors",
917
- variants[variant],
918
- className
919
- ),
920
- children: [
921
- /* @__PURE__ */ jsx12("span", { className: "mr-2 select-none text-[var(--surface-success-text)]", children: "$" }),
922
- /* @__PURE__ */ jsx12(
923
- "input",
924
- {
925
- ref,
926
- type: "text",
927
- value,
928
- onChange: (e) => setValue(e.target.value),
929
- onKeyDown: handleKeyDown,
930
- className: "flex-1 bg-transparent text-foreground outline-none placeholder:text-muted-foreground",
931
- ...props
932
- }
933
- ),
934
- /* @__PURE__ */ jsx12(TerminalCursor, {})
935
- ]
936
- }
937
- );
938
- }
939
- );
940
- TerminalInput.displayName = "TerminalInput";
941
-
942
- // src/primitives/drop-zone.tsx
943
- import { useCallback as useCallback2, useRef as useRef3, useState as useState3 } from "react";
944
- import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
945
- function DropZone({
946
- onDrop,
947
- accept,
948
- disabled,
949
- overlay,
950
- title = "Drop files to upload",
951
- description = "Your files will be securely stored in the workspace.",
952
- icon = "cloud_upload",
953
- children,
954
- className
955
- }) {
956
- const [dragOver, setDragOver] = useState3(false);
957
- const counter = useRef3(0);
958
- const isAccepted = useCallback2(
959
- (file) => {
960
- if (!accept) return true;
961
- const extensions = accept.split(",").map((ext) => ext.trim().toLowerCase());
962
- const fileName = file.name.toLowerCase();
963
- return extensions.some((ext) => fileName.endsWith(ext));
964
- },
965
- [accept]
966
- );
967
- const handleDragEnter = useCallback2(
968
- (e) => {
969
- e.preventDefault();
970
- if (disabled) return;
971
- counter.current++;
972
- if (e.dataTransfer?.types.includes("Files")) setDragOver(true);
973
- },
974
- [disabled]
975
- );
976
- const handleDragLeave = useCallback2((e) => {
977
- e.preventDefault();
978
- counter.current--;
979
- if (counter.current === 0) setDragOver(false);
980
- }, []);
981
- const handleDragOver = useCallback2(
982
- (e) => {
983
- e.preventDefault();
984
- if (!disabled) e.dataTransfer.dropEffect = "copy";
985
- },
986
- [disabled]
987
- );
988
- const handleDrop = useCallback2(
989
- (e) => {
990
- e.preventDefault();
991
- counter.current = 0;
992
- setDragOver(false);
993
- if (disabled) return;
994
- const allFiles = Array.from(e.dataTransfer?.files || []);
995
- const accepted = accept ? allFiles.filter(isAccepted) : allFiles;
996
- if (accepted.length > 0) onDrop(accepted);
997
- },
998
- [disabled, accept, isAccepted, onDrop]
999
- );
1000
- return /* @__PURE__ */ jsxs11(
1001
- "div",
1002
- {
1003
- onDragEnter: handleDragEnter,
1004
- onDragLeave: handleDragLeave,
1005
- onDragOver: handleDragOver,
1006
- onDrop: handleDrop,
1007
- className: cn("relative", className),
1008
- children: [
1009
- dragOver && (overlay || /* @__PURE__ */ jsx13("div", { className: "fixed inset-0 z-[100] flex items-center justify-center pointer-events-none bg-background", children: /* @__PURE__ */ jsxs11("div", { className: "rounded-2xl border-2 border-dashed border-border bg-card p-16 text-center shadow-[var(--shadow-dropdown)] max-w-lg mx-auto", children: [
1010
- /* @__PURE__ */ jsx13("div", { className: "mx-auto mb-6 flex h-20 w-20 items-center justify-center rounded-2xl border border-border bg-[var(--accent-surface-soft)]", children: typeof icon === "string" ? /* @__PURE__ */ jsxs11("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", className: "h-10 w-10 text-[var(--accent-text)]", children: [
1011
- /* @__PURE__ */ jsx13("title", { children: "Upload" }),
1012
- /* @__PURE__ */ jsx13("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
1013
- /* @__PURE__ */ jsx13("polyline", { points: "17 8 12 3 7 8" }),
1014
- /* @__PURE__ */ jsx13("line", { x1: "12", x2: "12", y1: "3", y2: "15" })
1015
- ] }) : icon }),
1016
- /* @__PURE__ */ jsx13("h2", { className: "text-2xl font-bold text-foreground", children: title }),
1017
- /* @__PURE__ */ jsx13("p", { className: "mt-2 text-sm text-muted-foreground", children: description })
1018
- ] }) })),
1019
- children
1020
- ]
1021
- }
1022
- );
1023
- }
1024
-
1025
- // src/primitives/upload-progress.tsx
1026
- import { AlertCircle as AlertCircle2, CheckCircle2 as CheckCircle22, FileText, Loader2, RefreshCw, X as X3 } from "lucide-react";
1027
- import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
1028
- function formatSize(bytes) {
1029
- if (bytes < 1024) return `${bytes}B`;
1030
- if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)}KB`;
1031
- return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
1032
- }
1033
- function UploadProgress({ files, onRemove, onRetry, className }) {
1034
- if (files.length === 0) return null;
1035
- return /* @__PURE__ */ jsx14("div", { className: cn("space-y-2", className), children: files.map((file) => /* @__PURE__ */ jsxs12(
1036
- "div",
1037
- {
1038
- className: cn(
1039
- "flex items-center gap-3 rounded-lg border px-3 py-2 text-sm",
1040
- file.status === "error" ? "border-[var(--surface-danger-border)] bg-[var(--surface-danger-bg)]" : file.status === "complete" ? "border-[var(--surface-success-border)] bg-[var(--surface-success-bg)]" : "border-border bg-card"
1041
- ),
1042
- children: [
1043
- file.status === "complete" && /* @__PURE__ */ jsx14(CheckCircle22, { className: "h-4 w-4 shrink-0 text-[var(--surface-success-text)]" }),
1044
- file.status === "error" && /* @__PURE__ */ jsx14(AlertCircle2, { className: "h-4 w-4 shrink-0 text-[var(--surface-danger-text)]" }),
1045
- file.status === "uploading" && /* @__PURE__ */ jsx14(Loader2, { className: "h-4 w-4 shrink-0 animate-spin text-primary" }),
1046
- file.status === "pending" && /* @__PURE__ */ jsx14(FileText, { className: "h-4 w-4 shrink-0 text-muted-foreground" }),
1047
- /* @__PURE__ */ jsxs12("div", { className: "min-w-0 flex-1", children: [
1048
- /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2", children: [
1049
- /* @__PURE__ */ jsx14("span", { className: "truncate font-medium text-foreground", children: file.name }),
1050
- /* @__PURE__ */ jsx14("span", { className: "shrink-0 text-xs text-muted-foreground", children: formatSize(file.size) })
1051
- ] }),
1052
- file.status === "uploading" && file.progress !== void 0 && /* @__PURE__ */ jsx14("div", { className: "mt-1 h-1 w-full overflow-hidden rounded-full bg-muted/50", children: /* @__PURE__ */ jsx14(
1053
- "div",
1054
- {
1055
- className: "h-full rounded-full bg-primary transition-all",
1056
- style: { width: `${file.progress}%` }
1057
- }
1058
- ) }),
1059
- file.status === "error" && file.error && /* @__PURE__ */ jsx14("p", { className: "mt-0.5 text-xs text-[var(--surface-danger-text)]", children: file.error })
1060
- ] }),
1061
- /* @__PURE__ */ jsxs12("div", { className: "flex shrink-0 items-center gap-1", children: [
1062
- file.status === "error" && onRetry && /* @__PURE__ */ jsx14(
1063
- "button",
1064
- {
1065
- type: "button",
1066
- onClick: () => onRetry(file.id),
1067
- className: "rounded p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
1068
- children: /* @__PURE__ */ jsx14(RefreshCw, { className: "h-3.5 w-3.5" })
1069
- }
1070
- ),
1071
- onRemove && /* @__PURE__ */ jsx14(
1072
- "button",
1073
- {
1074
- type: "button",
1075
- onClick: () => onRemove(file.id),
1076
- className: "rounded p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
1077
- children: /* @__PURE__ */ jsx14(X3, { className: "h-3.5 w-3.5" })
1078
- }
1079
- )
1080
- ] })
1081
- ]
1082
- },
1083
- file.id
1084
- )) });
1085
- }
1086
-
1087
- // src/primitives/sidebar-drop-zone.tsx
1088
- import { useCallback as useCallback3, useRef as useRef4, useState as useState4 } from "react";
1089
- import { Upload } from "lucide-react";
1090
- import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
1091
- function SidebarDropZone({
1092
- onDrop,
1093
- accept,
1094
- disabled,
1095
- title = "Drop files here",
1096
- description,
1097
- icon,
1098
- persistent = false,
1099
- className
1100
- }) {
1101
- const [dragOver, setDragOver] = useState4(false);
1102
- const counter = useRef4(0);
1103
- const isAccepted = useCallback3(
1104
- (file) => {
1105
- if (!accept) return true;
1106
- const extensions = accept.split(",").map((ext) => ext.trim().toLowerCase());
1107
- const fileName = file.name.toLowerCase();
1108
- return extensions.some((ext) => fileName.endsWith(ext));
1109
- },
1110
- [accept]
1111
- );
1112
- const handleDragEnter = useCallback3(
1113
- (e) => {
1114
- e.preventDefault();
1115
- e.stopPropagation();
1116
- if (disabled) return;
1117
- counter.current++;
1118
- if (e.dataTransfer?.types.includes("Files")) setDragOver(true);
1119
- },
1120
- [disabled]
1121
- );
1122
- const handleDragLeave = useCallback3((e) => {
1123
- e.preventDefault();
1124
- e.stopPropagation();
1125
- counter.current--;
1126
- if (counter.current === 0) setDragOver(false);
1127
- }, []);
1128
- const handleDragOver = useCallback3(
1129
- (e) => {
1130
- e.preventDefault();
1131
- e.stopPropagation();
1132
- if (!disabled) e.dataTransfer.dropEffect = "copy";
1133
- },
1134
- [disabled]
1135
- );
1136
- const handleDrop = useCallback3(
1137
- (e) => {
1138
- e.preventDefault();
1139
- e.stopPropagation();
1140
- counter.current = 0;
1141
- setDragOver(false);
1142
- if (disabled) return;
1143
- const allFiles = Array.from(e.dataTransfer?.files || []);
1144
- const accepted = accept ? allFiles.filter(isAccepted) : allFiles;
1145
- if (accepted.length > 0) onDrop(accepted);
1146
- },
1147
- [disabled, accept, isAccepted, onDrop]
1148
- );
1149
- const isVisible = persistent || dragOver;
1150
- return /* @__PURE__ */ jsx15(
1151
- "div",
1152
- {
1153
- onDragEnter: handleDragEnter,
1154
- onDragLeave: handleDragLeave,
1155
- onDragOver: handleDragOver,
1156
- onDrop: handleDrop,
1157
- className: cn(
1158
- "rounded-lg border-2 border-dashed transition-all duration-150",
1159
- isVisible ? "p-4" : "p-0 border-transparent",
1160
- dragOver ? "border-[var(--brand-cool,hsl(var(--ring)))] bg-[var(--accent-surface-soft)]" : persistent ? "border-[var(--border-subtle,hsl(var(--border)))] bg-transparent hover:border-[var(--border-default,hsl(var(--border)))] hover:bg-[var(--bg-hover,hsl(var(--accent)))]" : "",
1161
- disabled && "opacity-50 pointer-events-none",
1162
- className
1163
- ),
1164
- children: isVisible && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col items-center gap-2 text-center", children: [
1165
- /* @__PURE__ */ jsx15("div", { className: cn(
1166
- "flex h-8 w-8 items-center justify-center rounded-lg transition-colors",
1167
- dragOver ? "bg-[var(--brand-cool,hsl(var(--primary)))]/15 text-[var(--brand-cool,hsl(var(--primary)))]" : "text-[var(--text-muted,hsl(var(--muted-foreground)))]"
1168
- ), children: icon ?? /* @__PURE__ */ jsx15(Upload, { className: "h-4 w-4" }) }),
1169
- /* @__PURE__ */ jsx15("p", { className: cn(
1170
- "text-xs font-medium",
1171
- dragOver ? "text-[var(--text-primary,hsl(var(--foreground)))]" : "text-[var(--text-muted,hsl(var(--muted-foreground)))]"
1172
- ), children: title }),
1173
- description && /* @__PURE__ */ jsx15("p", { className: "text-[10px] text-[var(--text-muted,hsl(var(--muted-foreground)))]", children: description })
1174
- ] })
1175
- }
1176
- );
1177
- }
1178
-
1179
- // src/primitives/theme-toggle.tsx
1180
- import { useCallback as useCallback4, useEffect as useEffect2, useState as useState5 } from "react";
1181
- import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
1182
- function getSystemTheme() {
1183
- return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
1184
- }
1185
- function applyTheme(theme) {
1186
- const resolved = theme === "system" ? getSystemTheme() : theme;
1187
- document.documentElement.classList.toggle("dark", resolved === "dark");
1188
- }
1189
- function useTheme() {
1190
- const [theme, setThemeState] = useState5(() => {
1191
- if (typeof window === "undefined") return "system";
1192
- return localStorage.getItem("theme") ?? "system";
1193
- });
1194
- const setTheme = useCallback4((next) => {
1195
- setThemeState(next);
1196
- if (next === "system") {
1197
- localStorage.removeItem("theme");
1198
- } else {
1199
- localStorage.setItem("theme", next);
1200
- }
1201
- applyTheme(next);
1202
- }, []);
1203
- useEffect2(() => {
1204
- applyTheme(theme);
1205
- if (theme !== "system") return;
1206
- const mq = window.matchMedia("(prefers-color-scheme: dark)");
1207
- const handler = () => applyTheme("system");
1208
- mq.addEventListener("change", handler);
1209
- return () => mq.removeEventListener("change", handler);
1210
- }, [theme]);
1211
- return { theme, setTheme };
1212
- }
1213
- var iconClass = "h-4 w-4";
1214
- function SunIcon() {
1215
- return /* @__PURE__ */ jsxs14(
1216
- "svg",
1217
- {
1218
- xmlns: "http://www.w3.org/2000/svg",
1219
- viewBox: "0 0 24 24",
1220
- fill: "none",
1221
- stroke: "currentColor",
1222
- strokeWidth: 2,
1223
- strokeLinecap: "round",
1224
- strokeLinejoin: "round",
1225
- className: iconClass,
1226
- children: [
1227
- /* @__PURE__ */ jsx16("circle", { cx: 12, cy: 12, r: 5 }),
1228
- /* @__PURE__ */ jsx16("path", { d: "M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42" })
1229
- ]
1230
- }
1231
- );
1232
- }
1233
- function MoonIcon() {
1234
- return /* @__PURE__ */ jsx16(
1235
- "svg",
1236
- {
1237
- xmlns: "http://www.w3.org/2000/svg",
1238
- viewBox: "0 0 24 24",
1239
- fill: "none",
1240
- stroke: "currentColor",
1241
- strokeWidth: 2,
1242
- strokeLinecap: "round",
1243
- strokeLinejoin: "round",
1244
- className: iconClass,
1245
- children: /* @__PURE__ */ jsx16("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" })
1246
- }
1247
- );
1248
- }
1249
- function ThemeToggle() {
1250
- const { theme, setTheme } = useTheme();
1251
- const resolved = theme === "system" ? getSystemTheme() : theme;
1252
- return /* @__PURE__ */ jsx16(
1253
- "button",
1254
- {
1255
- type: "button",
1256
- onClick: () => setTheme(resolved === "dark" ? "light" : "dark"),
1257
- className: "inline-flex items-center justify-center rounded-md p-2 text-muted-foreground hover:bg-accent hover:text-accent-foreground transition-colors",
1258
- "aria-label": `Switch to ${resolved === "dark" ? "light" : "dark"} mode`,
1259
- children: resolved === "dark" ? /* @__PURE__ */ jsx16(SunIcon, {}) : /* @__PURE__ */ jsx16(MoonIcon, {})
1260
- }
1261
- );
1262
- }
1263
-
1264
- // src/primitives/page-header.tsx
1265
- import * as React12 from "react";
1266
- import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
1267
- var PageHeader = React12.forwardRef(
1268
- ({
1269
- className,
1270
- title,
1271
- description,
1272
- actions,
1273
- meta,
1274
- titleId,
1275
- level = 1,
1276
- ...props
1277
- }, ref) => {
1278
- const Heading = level === 1 ? "h1" : "h2";
1279
- return /* @__PURE__ */ jsxs15("header", { ref, className: cn("mb-6", className), ...props, children: [
1280
- /* @__PURE__ */ jsxs15("div", { className: "flex flex-wrap items-start justify-between gap-x-6 gap-y-3", children: [
1281
- /* @__PURE__ */ jsxs15("div", { className: "min-w-0", children: [
1282
- /* @__PURE__ */ jsx17(
1283
- Heading,
1284
- {
1285
- id: titleId,
1286
- className: cn(
1287
- "text-balance font-semibold tracking-tight",
1288
- level === 1 ? "text-2xl" : "text-lg"
1289
- ),
1290
- children: title
1291
- }
1292
- ),
1293
- description && /* @__PURE__ */ jsx17("p", { className: "mt-1 max-w-prose text-muted-foreground text-sm", children: description })
1294
- ] }),
1295
- actions && /* @__PURE__ */ jsx17("div", { className: "flex flex-wrap items-center gap-2", children: actions })
1296
- ] }),
1297
- meta && /* @__PURE__ */ jsx17("div", { className: "mt-3 flex flex-wrap items-center gap-x-4 gap-y-2 text-[var(--text-dim)] text-xs", children: meta })
1298
- ] });
1299
- }
1300
- );
1301
- PageHeader.displayName = "PageHeader";
1302
-
1303
- // src/primitives/status-pill.tsx
1304
- import * as React13 from "react";
1305
- import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
1306
- var TONE_SURFACE = {
1307
- success: "bg-[var(--surface-success-bg)] text-[var(--surface-success-text)] border-[var(--surface-success-border)]",
1308
- warning: "bg-[var(--surface-warning-bg)] text-[var(--surface-warning-text)] border-[var(--surface-warning-border)]",
1309
- danger: "bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)] border-[var(--surface-danger-border)]",
1310
- info: "bg-[var(--surface-info-bg)] text-[var(--surface-info-text)] border-[var(--surface-info-border)]",
1311
- // `running` shares the info triple on purpose. `--status-running` exists but
1312
- // is the green dot on a sandbox — a machine's power state, not a run's
1313
- // outcome — and it ships as one colour with no paired background or text
1314
- // tier, which is the pairing this component is built to guarantee. Green also
1315
- // already means SUCCEEDED here, so a green "running" pill would say a run had
1316
- // finished well while it was still going.
1317
- running: "bg-[var(--surface-info-bg)] text-[var(--surface-info-text)] border-[var(--surface-info-border)]",
1318
- neutral: "bg-[var(--surface-neutral-bg)] text-[var(--surface-neutral-text)] border-[var(--surface-neutral-border)]"
1319
- };
1320
- var TONE_TEXT = {
1321
- success: "text-[var(--surface-success-text)]",
1322
- warning: "text-[var(--surface-warning-text)]",
1323
- danger: "text-[var(--surface-danger-text)]",
1324
- info: "text-[var(--surface-info-text)]",
1325
- running: "text-[var(--surface-info-text)]",
1326
- neutral: "text-[var(--surface-neutral-text)]"
1327
- };
1328
- function ToneGlyph({ tone }) {
1329
- const common = {
1330
- viewBox: "0 0 8 8",
1331
- className: "size-2 shrink-0"
1332
- };
1333
- switch (tone) {
1334
- // Settled and good: a solid disc.
1335
- case "success":
1336
- return /* @__PURE__ */ jsx18("svg", { ...common, "aria-hidden": "true", fill: "currentColor", children: /* @__PURE__ */ jsx18("circle", { cx: "4", cy: "4", r: "3.25" }) });
1337
- // Settled and bad: a disc with a bar through it, so it differs from
1338
- // success in OUTLINE and not only in hue.
1339
- case "danger":
1340
- return /* @__PURE__ */ jsxs16(
1341
- "svg",
1342
- {
1343
- ...common,
1344
- "aria-hidden": "true",
1345
- fill: "none",
1346
- stroke: "currentColor",
1347
- strokeWidth: "1.5",
1348
- children: [
1349
- /* @__PURE__ */ jsx18("circle", { cx: "4", cy: "4", r: "3.1", fill: "currentColor", opacity: "0.35" }),
1350
- /* @__PURE__ */ jsx18("path", { d: "M1.9 6.1 6.1 1.9", strokeLinecap: "round" })
1351
- ]
1352
- }
1353
- );
1354
- // Needs a person: a triangle.
1355
- case "warning":
1356
- return /* @__PURE__ */ jsx18("svg", { ...common, "aria-hidden": "true", fill: "currentColor", children: /* @__PURE__ */ jsx18("path", { d: "M4 0.6 7.7 7.1H0.3z" }) });
1357
- // Still moving: an open ring, visibly hollow at 8px.
1358
- case "running":
1359
- return /* @__PURE__ */ jsx18(
1360
- "svg",
1361
- {
1362
- ...common,
1363
- "aria-hidden": "true",
1364
- fill: "none",
1365
- stroke: "currentColor",
1366
- strokeWidth: "1.75",
1367
- children: /* @__PURE__ */ jsx18("circle", { cx: "4", cy: "4", r: "2.9" })
1368
- }
1369
- );
1370
- // Informational: a square, the only right-angled mark in the set.
1371
- case "info":
1372
- return /* @__PURE__ */ jsx18("svg", { ...common, "aria-hidden": "true", fill: "currentColor", children: /* @__PURE__ */ jsx18("rect", { x: "0.9", y: "0.9", width: "6.2", height: "6.2", rx: "1.2" }) });
1373
- // Nothing has happened: a dash. No enclosed area at all.
1374
- default:
1375
- return /* @__PURE__ */ jsx18(
1376
- "svg",
1377
- {
1378
- ...common,
1379
- "aria-hidden": "true",
1380
- fill: "none",
1381
- stroke: "currentColor",
1382
- strokeWidth: "1.75",
1383
- children: /* @__PURE__ */ jsx18("path", { d: "M1 4h6", strokeLinecap: "round" })
1384
- }
1385
- );
1386
- }
1387
- }
1388
- var StatusPill = React13.forwardRef(
1389
- ({ className, tone, children, bare = false, size = "sm", ...props }, ref) => /* @__PURE__ */ jsxs16(
1390
- "span",
1391
- {
1392
- ref,
1393
- className: cn(
1394
- "inline-flex items-center gap-1.5 whitespace-nowrap rounded-full font-medium",
1395
- size === "sm" ? "px-2 py-0.5 text-xs" : "px-2.5 py-1 text-sm",
1396
- bare ? "border border-transparent bg-transparent px-0" : cn("border", TONE_SURFACE[tone]),
1397
- className
1398
- ),
1399
- ...props,
1400
- children: [
1401
- /* @__PURE__ */ jsx18("span", { className: cn("inline-flex", bare && TONE_TEXT[tone]), children: /* @__PURE__ */ jsx18(ToneGlyph, { tone }) }),
1402
- children
1403
- ]
1404
- }
1405
- )
1406
- );
1407
- StatusPill.displayName = "StatusPill";
1408
-
1409
- // src/primitives/metric-strip.tsx
1410
- import * as React14 from "react";
1411
- import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
1412
- var MetricStrip = React14.forwardRef(
1413
- ({ className, children, ...props }, ref) => /* @__PURE__ */ jsx19(
1414
- "dl",
1415
- {
1416
- ref,
1417
- className: cn(
1418
- "grid grid-cols-2 rounded-[var(--radius-lg)] border border-border bg-card shadow-[var(--shadow-card)] sm:grid-cols-4",
1419
- className
1420
- ),
1421
- ...props,
1422
- children
1423
- }
1424
- )
1425
- );
1426
- MetricStrip.displayName = "MetricStrip";
1427
- var Metric = React14.forwardRef(
1428
- ({ className, label, value, hint, attention, ...props }, ref) => /* @__PURE__ */ jsxs17(
1429
- "div",
1430
- {
1431
- ref,
1432
- className: cn(
1433
- // Leading hairline, DRAWN only where a divider belongs — never drawn
1434
- // and then suppressed. Stating it as `border-l` plus `border-l-0`
1435
- // variants puts both in one conflict group, where the winner is decided
1436
- // by emitted-rule order rather than by intent; that resolved the wrong
1437
- // way at every breakpoint and left a rule down the start of each row.
1438
- // `:not(:nth-child(Nn+1))` is the row-start test for the column count
1439
- // at that breakpoint, so no rule ever contradicts another.
1440
- //
1441
- // N is COUPLED to the grid template on `MetricStrip`: 2 columns below
1442
- // `sm`, 4 from `sm`. A new breakpoint there — `md:grid-cols-3`, say —
1443
- // needs its `md:[&:not(:nth-child(3n+1))]:border-l` here in the same
1444
- // change, or the dividers land mid-row at that width.
1445
- "border-border p-4 sm:p-5",
1446
- "max-sm:[&:not(:nth-child(2n+1))]:border-l",
1447
- "sm:[&:not(:nth-child(4n+1))]:border-l",
1448
- className
1449
- ),
1450
- ...props,
1451
- children: [
1452
- /* @__PURE__ */ jsxs17("dt", { className: "flex items-center gap-2 text-muted-foreground text-sm", children: [
1453
- /* @__PURE__ */ jsx19("span", { className: "truncate", children: label }),
1454
- attention && /* @__PURE__ */ jsx19(StatusPill, { tone: attention.tone, children: attention.label })
1455
- ] }),
1456
- /* @__PURE__ */ jsx19(
1457
- "dd",
1458
- {
1459
- className: cn(
1460
- "mt-1 truncate font-semibold text-xl tabular-nums tracking-tight lg:text-2xl",
1461
- attention?.tone === "danger" && "text-[var(--surface-danger-text)]"
1462
- ),
1463
- title: typeof value === "string" ? value : void 0,
1464
- children: value
1465
- }
1466
- ),
1467
- hint && // Titled for the same reason the value is: the line truncates, and a
1468
- // hint is where the qualifying detail lives — which wallet, which
1469
- // window — so a clipped one is the case most worth recovering.
1470
- /* @__PURE__ */ jsx19(
1471
- "dd",
1472
- {
1473
- className: "mt-0.5 truncate text-[var(--text-dim)] text-xs",
1474
- title: typeof hint === "string" ? hint : void 0,
1475
- children: hint
1476
- }
1477
- )
1478
- ]
1479
- }
1480
- )
1481
- );
1482
- Metric.displayName = "Metric";
1483
-
1484
- // src/primitives/toolbar.tsx
1485
- import * as React15 from "react";
1486
- import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
1487
- var Toolbar = React15.forwardRef(
1488
- ({ className, search, filters, actions, ...props }, ref) => /* @__PURE__ */ jsxs18(
1489
- "div",
1490
- {
1491
- ref,
1492
- className: cn(
1493
- "mb-4 flex flex-col gap-3 lg:flex-row lg:items-center",
1494
- className
1495
- ),
1496
- ...props,
1497
- children: [
1498
- search && /* @__PURE__ */ jsx20("div", { className: "min-w-0 lg:max-w-sm lg:flex-1", children: search }),
1499
- filters && // `py-1` leaves room for a focus ring above and below; horizontally the
1500
- // scroll container clips it, which is the trade a single-line filter row
1501
- // makes. No negative margin — pulling the row wider than its parent is
1502
- // what made every page report 4px of horizontal overflow.
1503
- /* @__PURE__ */ jsx20("div", { className: "flex min-w-0 items-center gap-2 overflow-x-auto py-1 lg:flex-1", children: filters }),
1504
- actions && /* @__PURE__ */ jsx20("div", { className: "flex shrink-0 items-center gap-2 lg:ml-auto", children: actions })
1505
- ]
1506
- }
1507
- )
1508
- );
1509
- Toolbar.displayName = "Toolbar";
1510
- var FilterField = React15.forwardRef(
1511
- ({ className, label, htmlFor, children, ...props }, ref) => /* @__PURE__ */ jsxs18(
1512
- "div",
1513
- {
1514
- ref,
1515
- className: cn("flex shrink-0 items-center gap-2", className),
1516
- ...props,
1517
- children: [
1518
- /* @__PURE__ */ jsx20(
1519
- "label",
1520
- {
1521
- htmlFor,
1522
- className: "whitespace-nowrap text-muted-foreground text-xs",
1523
- children: label
1524
- }
1525
- ),
1526
- children
1527
- ]
1528
- }
1529
- )
1530
- );
1531
- FilterField.displayName = "FilterField";
1532
-
1533
- export {
1534
- Dialog,
1535
- DialogTrigger,
1536
- DialogPortal,
1537
- DialogClose,
1538
- DialogOverlay,
1539
- DialogContent,
1540
- DialogHeader,
1541
- DialogFooter,
1542
- DialogTitle,
1543
- DialogDescription,
1544
- Input,
1545
- Textarea,
1546
- Select,
1547
- SelectGroup,
1548
- SelectValue,
1549
- SelectTrigger,
1550
- SelectScrollUpButton,
1551
- SelectScrollDownButton,
1552
- SelectContent,
1553
- SelectLabel,
1554
- SelectItem,
1555
- SelectSeparator,
1556
- SegmentedControl,
1557
- Progress,
1558
- Switch,
1559
- Skeleton,
1560
- SkeletonCard,
1561
- SkeletonTable,
1562
- ToastContainer,
1563
- ToastProvider,
1564
- useToast,
1565
- Label2 as Label,
1566
- EmptyState,
1567
- StatCard,
1568
- TerminalDisplay,
1569
- TerminalLine,
1570
- TerminalCursor,
1571
- TerminalInput,
1572
- DropZone,
1573
- UploadProgress,
1574
- SidebarDropZone,
1575
- useTheme,
1576
- ThemeToggle,
1577
- PageHeader,
1578
- StatusPill,
1579
- MetricStrip,
1580
- Metric,
1581
- Toolbar,
1582
- FilterField,
1583
- Logo,
1584
- TangleKnot
1585
- };