@tangle-network/ui 11.12.0 → 11.13.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/CHANGELOG.md +17 -0
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/auth/auth.d.ts +53 -0
- package/dist/{auth-DOETfnd9.js → auth/auth.js} +7 -37
- package/dist/auth/login-layout.d.ts +20 -0
- package/dist/auth/login-layout.js +36 -0
- package/dist/auth.d.ts +2 -1
- package/dist/auth.js +2 -1
- package/dist/chat/agent-timeline.d.ts +83 -0
- package/dist/chat/agent-timeline.js +236 -0
- package/dist/chat/chat-container.d.ts +51 -0
- package/dist/chat/chat-container.js +309 -0
- package/dist/chat/chat-message.d.ts +22 -0
- package/dist/chat/chat-message.js +38 -0
- package/dist/chat/message-list.d.ts +32 -0
- package/dist/chat/message-list.js +37 -0
- package/dist/chat/thinking-indicator.d.ts +6 -0
- package/dist/chat/thinking-indicator.js +38 -0
- package/dist/chat/user-message.d.ts +21 -0
- package/dist/chat/user-message.js +42 -0
- package/dist/chat.d.ts +6 -1
- package/dist/chat.js +6 -1
- package/dist/editor/document-editor-pane.d.ts +37 -0
- package/dist/editor/document-editor-pane.js +199 -0
- package/dist/editor/editor-lazy.js +37 -0
- package/dist/editor/editor-loading.js +21 -0
- package/dist/editor/editor-peers.d.ts +6 -0
- package/dist/editor/editor-peers.js +155 -0
- package/dist/editor/editor-provider.d.ts +97 -0
- package/dist/editor/editor-provider.js +253 -0
- package/dist/editor/editor-toolbar.d.ts +11 -0
- package/dist/editor/editor-toolbar.js +106 -0
- package/dist/editor/markdown-conversion.js +23 -0
- package/dist/editor/markdown-document-editor.js +103 -0
- package/dist/editor/tiptap-editor.d.ts +45 -0
- package/dist/editor/tiptap-editor.js +271 -0
- package/dist/editor/use-editor.d.ts +67 -0
- package/dist/editor/use-editor.js +158 -0
- package/dist/editor.d.ts +6 -119
- package/dist/editor.js +5 -1
- package/dist/files/file-artifact-pane.d.ts +47 -0
- package/dist/files/file-artifact-pane.js +114 -0
- package/dist/files/file-format.d.ts +51 -0
- package/dist/{file-format-BgXbr-Ib.js → files/file-format.js} +1 -1
- package/dist/files/file-preview.d.ts +27 -0
- package/dist/files/file-preview.js +359 -0
- package/dist/files/file-tabs.d.ts +19 -0
- package/dist/files/file-tabs.js +48 -0
- package/dist/files/file-tree.d.ts +31 -0
- package/dist/files/file-tree.js +135 -0
- package/dist/files/rich-file-tree.d.ts +62 -0
- package/dist/files/rich-file-tree.js +122 -0
- package/dist/files.d.ts +6 -1
- package/dist/files.js +6 -2
- package/dist/hooks/use-auth.d.ts +40 -0
- package/dist/hooks/use-auth.js +91 -0
- package/dist/hooks/use-auto-scroll.d.ts +11 -0
- package/dist/hooks/use-auto-scroll.js +48 -0
- package/dist/hooks/use-dropdown-menu.d.ts +12 -0
- package/dist/hooks/use-dropdown-menu.js +31 -0
- package/dist/hooks/use-live-time.d.ts +7 -0
- package/dist/hooks/use-live-time.js +22 -0
- package/dist/hooks/use-realtime-session.d.ts +32 -0
- package/dist/hooks/use-realtime-session.js +235 -0
- package/dist/hooks/use-run-collapse-state.d.ts +13 -0
- package/dist/hooks/use-run-collapse-state.js +24 -0
- package/dist/hooks/use-run-groups.d.ts +11 -0
- package/dist/hooks/use-run-groups.js +85 -0
- package/dist/hooks/use-sdk-session.d.ts +59 -0
- package/dist/hooks/use-sdk-session.js +322 -0
- package/dist/hooks/use-sse-stream.d.ts +124 -0
- package/dist/hooks/use-sse-stream.js +229 -0
- package/dist/hooks/use-tool-call-stream.d.ts +23 -0
- package/dist/hooks/use-tool-call-stream.js +75 -0
- package/dist/hooks.d.ts +11 -49
- package/dist/hooks.js +10 -110
- package/dist/index.d.ts +99 -25
- package/dist/index.js +86 -36
- package/dist/lib/focus.d.ts +55 -0
- package/dist/{focus-BcE_SHqz.js → lib/focus.js} +1 -1
- package/dist/lib/utils.d.ts +4 -0
- package/dist/{utils-C_uf36nf.js → lib/utils.js} +1 -1
- package/dist/{code-block-B9miUPht.d.ts → markdown/code-block.d.ts} +5 -6
- package/dist/{code-block-B36KVUSN.js → markdown/code-block.js} +22 -47
- package/dist/{markdown-C0atSabr.d.ts → markdown/markdown.d.ts} +4 -5
- package/dist/{markdown-Db08KAYF.js → markdown/markdown.js} +3 -3
- package/dist/markdown.d.ts +2 -2
- package/dist/markdown.js +2 -2
- package/dist/{openui-artifact-renderer-fkBQaoLO.d.ts → openui/openui-artifact-renderer.d.ts} +20 -21
- package/dist/{openui-artifact-renderer-DG_i2lOR.js → openui/openui-artifact-renderer.js} +9 -7
- package/dist/{schema-BpW9rSSG.js → openui/schema-compiled.js} +2 -354
- package/dist/{schema-DAstk-J4.d.ts → openui/schema-data.d.ts} +3 -24
- package/dist/openui/schema-data.js +206 -0
- package/dist/openui-schema.d.ts +22 -3
- package/dist/openui-schema.js +138 -1
- package/dist/openui.d.ts +3 -2
- package/dist/openui.js +3 -2
- package/dist/{artifact-pane-BL_DFWNl.d.ts → primitives/artifact-pane.d.ts} +3 -4
- package/dist/{artifact-pane-DMXT9a8U.js → primitives/artifact-pane.js} +2 -2
- package/dist/primitives/avatar.d.ts +8 -0
- package/dist/primitives/avatar.js +25 -0
- package/dist/primitives/badge.d.ts +22 -0
- package/dist/primitives/badge.js +47 -0
- package/dist/{button-yoIv77e2.d.ts → primitives/button.d.ts} +2 -2
- package/dist/primitives/button.js +113 -0
- package/dist/primitives/card.d.ts +18 -0
- package/dist/primitives/card.js +52 -0
- package/dist/primitives/code-block.d.ts +6 -0
- package/dist/primitives/code-block.js +13 -0
- package/dist/primitives/dialog.d.ts +23 -0
- package/dist/primitives/dialog.js +59 -0
- package/dist/primitives/drop-zone.d.ts +23 -0
- package/dist/primitives/drop-zone.js +104 -0
- package/dist/primitives/dropdown-menu.d.ts +29 -0
- package/dist/{dropdown-menu-BpcLa5vF.js → primitives/dropdown-menu.js} +2 -23
- package/dist/primitives/empty-state.d.ts +11 -0
- package/dist/primitives/empty-state.js +32 -0
- package/dist/primitives/heading.d.ts +23 -0
- package/dist/primitives/heading.js +38 -0
- package/dist/primitives/input.d.ts +23 -0
- package/dist/primitives/input.js +110 -0
- package/dist/primitives/label.d.ts +6 -0
- package/dist/primitives/label.js +16 -0
- package/dist/primitives/metric-strip.d.ts +48 -0
- package/dist/primitives/metric-strip.js +52 -0
- package/dist/primitives/page-header.d.ts +25 -0
- package/dist/primitives/page-header.js +47 -0
- package/dist/primitives/page-shell.d.ts +14 -0
- package/dist/primitives/page-shell.js +17 -0
- package/dist/primitives/progress.d.ts +9 -0
- package/dist/primitives/progress.js +29 -0
- package/dist/primitives/segmented-control.d.ts +40 -0
- package/dist/primitives/segmented-control.js +57 -0
- package/dist/primitives/select.d.ts +15 -0
- package/dist/primitives/select.js +74 -0
- package/dist/primitives/sidebar-drop-zone.d.ts +21 -0
- package/dist/primitives/sidebar-drop-zone.js +88 -0
- package/dist/primitives/skeleton.d.ts +10 -0
- package/dist/primitives/skeleton.js +50 -0
- package/dist/primitives/stat-card.d.ts +16 -0
- package/dist/primitives/stat-card.js +60 -0
- package/dist/primitives/status-pill.d.ts +44 -0
- package/dist/primitives/status-pill.js +119 -0
- package/dist/primitives/switch.d.ts +6 -0
- package/dist/primitives/switch.js +16 -0
- package/dist/primitives/table.d.ts +22 -0
- package/dist/primitives/table.js +63 -0
- package/dist/primitives/tabs.d.ts +13 -0
- package/dist/{tabs-BVHR6NkO.js → primitives/tabs.js} +3 -3
- package/dist/primitives/terminal-display.d.ts +25 -0
- package/dist/primitives/terminal-display.js +109 -0
- package/dist/primitives/text-shimmer.d.ts +16 -0
- package/dist/{text-shimmer-BUUo6I-g.js → primitives/text-shimmer.js} +2 -2
- package/dist/primitives/theme-toggle.d.ts +11 -0
- package/dist/primitives/theme-toggle.js +154 -0
- package/dist/primitives/toast.d.ts +29 -0
- package/dist/primitives/toast.js +142 -0
- package/dist/primitives/toolbar.d.ts +55 -0
- package/dist/primitives/toolbar.js +37 -0
- package/dist/primitives/upload-progress.d.ts +23 -0
- package/dist/primitives/upload-progress.js +72 -0
- package/dist/primitives.d.ts +35 -5
- package/dist/primitives.js +35 -9
- package/dist/{index-COgqsFAQ.d.ts → redaction/redacted-document.d.ts} +6 -7
- package/dist/{redaction-CGGB2ENG.js → redaction/redacted-document.js} +2 -2
- package/dist/redaction.d.ts +1 -1
- package/dist/redaction.js +1 -1
- package/dist/run/expandable-content.js +41 -0
- package/dist/run/expanded-tool-detail.d.ts +12 -0
- package/dist/run/expanded-tool-detail.js +163 -0
- package/dist/run/inline-thinking-item.d.ts +11 -0
- package/dist/run/inline-thinking-item.js +60 -0
- package/dist/run/inline-tool-item.d.ts +25 -0
- package/dist/run/inline-tool-item.js +63 -0
- package/dist/run/run-group.d.ts +26 -0
- package/dist/{run-group-BWGeesgs.js → run/run-group.js} +9 -60
- package/dist/run/run-item-primitives.d.ts +5 -0
- package/dist/{run-ZsIKPA6J.js → run/run-item-primitives.js} +2 -2
- package/dist/run/run-row-shell.d.ts +53 -0
- package/dist/run/run-row-shell.js +114 -0
- package/dist/{tool-call-feed-BeB1_4pX.d.ts → run/tool-call-feed.d.ts} +7 -12
- package/dist/{tool-call-feed-BpmMLpPX.js → run/tool-call-feed.js} +4 -4
- package/dist/run/tool-call-step.d.ts +5 -0
- package/dist/run/tool-call-step.js +82 -0
- package/dist/run.d.ts +8 -2
- package/dist/run.js +7 -4
- package/dist/sdk-hooks.d.ts +8 -1
- package/dist/sdk-hooks.js +8 -2
- package/dist/stores/active-sessions-store.d.ts +83 -0
- package/dist/{active-sessions-store-Gt1R0rFG.js → stores/active-sessions-store.js} +1 -1
- package/dist/stores/chat-store.d.ts +14 -0
- package/dist/stores/chat-store.js +33 -0
- package/dist/stores.d.ts +3 -16
- package/dist/stores.js +2 -33
- package/dist/tool-previews/command-preview.d.ts +11 -0
- package/dist/tool-previews/command-preview.js +91 -0
- package/dist/tool-previews/diff-preview.d.ts +7 -0
- package/dist/tool-previews/diff-preview.js +76 -0
- package/dist/tool-previews/glob-results-preview.d.ts +7 -0
- package/dist/tool-previews/glob-results-preview.js +53 -0
- package/dist/tool-previews/grep-results-preview.d.ts +7 -0
- package/dist/tool-previews/grep-results-preview.js +99 -0
- package/dist/tool-previews/preview-primitives.js +58 -0
- package/dist/tool-previews/question-preview.d.ts +7 -0
- package/dist/tool-previews/question-preview.js +63 -0
- package/dist/tool-previews/web-search-preview.d.ts +7 -0
- package/dist/tool-previews/web-search-preview.js +78 -0
- package/dist/tool-previews/write-file-preview.d.ts +11 -0
- package/dist/tool-previews/write-file-preview.js +52 -0
- package/dist/tool-previews.d.ts +7 -1
- package/dist/tool-previews.js +7 -1
- package/dist/{branding-26d5ARIr.d.ts → types/branding.d.ts} +2 -3
- package/dist/{message-vhUI0c5G.d.ts → types/message.d.ts} +2 -3
- package/dist/{parts-5mhy9yJ3.d.ts → types/parts.d.ts} +8 -9
- package/dist/{run-OyWmIDqu.d.ts → types/run.d.ts} +9 -10
- package/dist/{tool-display-DgmL5rIU.d.ts → types/tool-display.d.ts} +5 -6
- package/dist/types.d.ts +5 -5
- package/dist/utils/copy-text.d.ts +7 -0
- package/dist/{utils-Bl_CZ0Qp.js → utils/copy-text.js} +1 -11
- package/dist/utils/format.d.ts +22 -0
- package/dist/{format-DfcLWqMa.js → utils/format.js} +1 -1
- package/dist/utils/time-ago.d.ts +3 -0
- package/dist/utils/time-ago.js +11 -0
- package/dist/utils/tool-display.d.ts +16 -0
- package/dist/{tool-display-BAuAVa43.js → utils/tool-display.js} +1 -1
- package/dist/utils.d.ts +6 -1
- package/dist/utils.js +6 -5
- package/package.json +2 -2
- package/src/files/rich-file-tree.stories.tsx +1 -1
- package/src/files/rich-file-tree.tsx +12 -9
- package/src/markdown/code-block.test.tsx +46 -2
- package/src/markdown/code-block.tsx +23 -60
- package/src/primitives/button.stories.tsx +37 -1
- package/src/primitives/button.test.tsx +230 -0
- package/src/primitives/button.tsx +62 -14
- package/src/primitives/card-anatomy.stories.tsx +51 -0
- package/src/primitives/card.test.tsx +71 -0
- package/src/primitives/card.tsx +25 -13
- package/src/primitives/heading.stories.tsx +35 -0
- package/src/primitives/heading.test.tsx +56 -0
- package/src/primitives/heading.tsx +76 -0
- package/src/primitives/index.ts +8 -0
- package/src/primitives/input.stories.tsx +28 -0
- package/src/primitives/input.test.tsx +161 -0
- package/src/primitives/input.tsx +34 -28
- package/src/primitives/page-header.stories.tsx +51 -0
- package/src/primitives/page-header.test.tsx +48 -0
- package/src/primitives/page-header.tsx +35 -35
- package/src/primitives/page-shell.stories.tsx +89 -0
- package/src/primitives/page-shell.test.tsx +24 -0
- package/src/primitives/page-shell.tsx +26 -0
- package/src/primitives/table-wrapper.stories.tsx +54 -0
- package/src/primitives/table.test.tsx +72 -0
- package/src/primitives/table.tsx +33 -12
- package/src/primitives/theme-toggle.test.tsx +167 -0
- package/src/primitives/theme-toggle.tsx +111 -39
- package/dist/active-sessions-store-nl70ZnMC.d.ts +0 -84
- package/dist/button-C87nEe2R.js +0 -78
- package/dist/chat-DDvF2oGQ.js +0 -672
- package/dist/diff-preview-BcK3nRXb.js +0 -533
- package/dist/document-editor-pane-BilJfiCo.d.ts +0 -136
- package/dist/document-editor-pane-POsq5Q0o.js +0 -1279
- package/dist/files-hywocVZz.js +0 -753
- package/dist/index-2UntyjBb.d.ts +0 -52
- package/dist/index-BgUHilZm.d.ts +0 -108
- package/dist/index-CJ8wRfiC.d.ts +0 -236
- package/dist/index-CPDET_s1.d.ts +0 -549
- package/dist/index-Cg6gYAqh.d.ts +0 -73
- package/dist/index-Cs7j8V7l.d.ts +0 -203
- package/dist/index-DjKxO357.d.ts +0 -128
- package/dist/primitives-Bx59fT-U.js +0 -1239
- package/dist/table-Bss73DhB.js +0 -146
- package/dist/tool-call-step-DNebqhmX.js +0 -434
- package/dist/use-auto-scroll-C5Pjeqon.js +0 -153
- package/dist/use-sse-stream-DjqRuDft.js +0 -884
- package/dist/use-sse-stream-Dm6R5YWz.d.ts +0 -282
|
@@ -1,1239 +0,0 @@
|
|
|
1
|
-
import { a as focusRingInset, i as focusRing, n as focusFieldInvalid, r as focusFieldWithin, t as focusField } from "./focus-BcE_SHqz.js";
|
|
2
|
-
import { t as cn } from "./utils-C_uf36nf.js";
|
|
3
|
-
import { d as Card } from "./table-Bss73DhB.js";
|
|
4
|
-
import { cva } from "class-variance-authority";
|
|
5
|
-
import * as React from "react";
|
|
6
|
-
import { useCallback, useEffect, useRef, useState } from "react";
|
|
7
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
-
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
9
|
-
import { AlertCircle, AlertTriangle, Check, CheckCircle2, ChevronDown, ChevronUp, FileText, Info, Loader2, RefreshCw, Upload, X } from "lucide-react";
|
|
10
|
-
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
11
|
-
import * as ProgressPrimitive from "@radix-ui/react-progress";
|
|
12
|
-
import * as SwitchPrimitives from "@radix-ui/react-switch";
|
|
13
|
-
import * as LabelPrimitive from "@radix-ui/react-label";
|
|
14
|
-
import { Logo, TangleKnot } from "@tangle-network/brand";
|
|
15
|
-
//#region src/primitives/dialog.tsx
|
|
16
|
-
const Dialog = DialogPrimitive.Root;
|
|
17
|
-
const DialogTrigger = DialogPrimitive.Trigger;
|
|
18
|
-
const DialogPortal = DialogPrimitive.Portal;
|
|
19
|
-
const DialogClose = DialogPrimitive.Close;
|
|
20
|
-
const DialogOverlay = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Overlay, {
|
|
21
|
-
ref,
|
|
22
|
-
className: cn("fixed inset-0 z-50 bg-black/40", "data-[state=closed]:animate-out data-[state=open]:animate-in", "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", className),
|
|
23
|
-
...props
|
|
24
|
-
}));
|
|
25
|
-
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
26
|
-
const DialogContent = React.forwardRef(({ className, children, variant = "default", ...props }, ref) => {
|
|
27
|
-
return /* @__PURE__ */ jsxs(DialogPortal, { children: [/* @__PURE__ */ jsx(DialogOverlay, {}), /* @__PURE__ */ jsxs(DialogPrimitive.Content, {
|
|
28
|
-
ref,
|
|
29
|
-
className: cn("fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%]", "gap-4 rounded-lg border bg-card p-6 shadow-lg duration-200", "data-[state=closed]:animate-out data-[state=open]:animate-in", "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-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%]", "data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]", {
|
|
30
|
-
default: "border-border",
|
|
31
|
-
sandbox: "border-[var(--border-accent)] shadow-[var(--shadow-accent)]"
|
|
32
|
-
}[variant], className),
|
|
33
|
-
...props,
|
|
34
|
-
children: [children, /* @__PURE__ */ jsxs(DialogPrimitive.Close, {
|
|
35
|
-
className: cn("absolute top-4 right-4 rounded-sm opacity-70 transition-[opacity,box-shadow] hover:opacity-100 focus-visible:opacity-100 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground", focusRing),
|
|
36
|
-
children: [/* @__PURE__ */ jsx(X, { className: "h-4 w-4" }), /* @__PURE__ */ jsx("span", {
|
|
37
|
-
className: "sr-only",
|
|
38
|
-
children: "Close"
|
|
39
|
-
})]
|
|
40
|
-
})]
|
|
41
|
-
})] });
|
|
42
|
-
});
|
|
43
|
-
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
44
|
-
const DialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
|
|
45
|
-
className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className),
|
|
46
|
-
...props
|
|
47
|
-
});
|
|
48
|
-
DialogHeader.displayName = "DialogHeader";
|
|
49
|
-
const DialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
|
|
50
|
-
className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className),
|
|
51
|
-
...props
|
|
52
|
-
});
|
|
53
|
-
DialogFooter.displayName = "DialogFooter";
|
|
54
|
-
const DialogTitle = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Title, {
|
|
55
|
-
ref,
|
|
56
|
-
className: cn("font-semibold text-lg leading-none tracking-tight", className),
|
|
57
|
-
...props
|
|
58
|
-
}));
|
|
59
|
-
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
60
|
-
const DialogDescription = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Description, {
|
|
61
|
-
ref,
|
|
62
|
-
className: cn("text-muted-foreground text-sm", className),
|
|
63
|
-
...props
|
|
64
|
-
}));
|
|
65
|
-
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
66
|
-
//#endregion
|
|
67
|
-
//#region src/primitives/input.tsx
|
|
68
|
-
const inputVariants = cva(cn("flex w-full rounded-lg border bg-card px-4 py-2 text-sm placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50 file:border-0 file:bg-transparent file:font-medium file:text-sm", focusField), {
|
|
69
|
-
variants: {
|
|
70
|
-
variant: {
|
|
71
|
-
default: "",
|
|
72
|
-
sandbox: "",
|
|
73
|
-
error: focusFieldInvalid
|
|
74
|
-
},
|
|
75
|
-
size: {
|
|
76
|
-
default: "h-11",
|
|
77
|
-
sm: "h-9 px-3",
|
|
78
|
-
lg: "h-12 px-5"
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
defaultVariants: {
|
|
82
|
-
variant: "default",
|
|
83
|
-
size: "default"
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
const Input = React.forwardRef(({ className, type, variant, size, label, error, hint, id, ...props }, ref) => {
|
|
87
|
-
const inputId = id ?? label?.toLowerCase().replace(/\s+/g, "-");
|
|
88
|
-
const input = /* @__PURE__ */ jsx("input", {
|
|
89
|
-
type,
|
|
90
|
-
id: inputId,
|
|
91
|
-
className: cn(inputVariants({
|
|
92
|
-
variant: error ? "error" : variant,
|
|
93
|
-
size,
|
|
94
|
-
className
|
|
95
|
-
})),
|
|
96
|
-
ref,
|
|
97
|
-
...props
|
|
98
|
-
});
|
|
99
|
-
if (!label && !error && !hint) return input;
|
|
100
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
101
|
-
className: "w-full space-y-1.5",
|
|
102
|
-
children: [
|
|
103
|
-
label && /* @__PURE__ */ jsx("label", {
|
|
104
|
-
htmlFor: inputId,
|
|
105
|
-
className: "block font-medium text-foreground text-sm",
|
|
106
|
-
children: label
|
|
107
|
-
}),
|
|
108
|
-
input,
|
|
109
|
-
error && /* @__PURE__ */ jsx("p", {
|
|
110
|
-
className: "text-[var(--surface-danger-text)] text-sm font-medium",
|
|
111
|
-
children: error
|
|
112
|
-
}),
|
|
113
|
-
hint && !error && /* @__PURE__ */ jsx("p", {
|
|
114
|
-
className: "text-[var(--text-dim)] text-sm",
|
|
115
|
-
children: hint
|
|
116
|
-
})
|
|
117
|
-
]
|
|
118
|
-
});
|
|
119
|
-
});
|
|
120
|
-
Input.displayName = "Input";
|
|
121
|
-
const Textarea = React.forwardRef(({ className, variant: _variant, label, error, hint, id, ...props }, ref) => {
|
|
122
|
-
const textareaId = id ?? label?.toLowerCase().replace(/\s+/g, "-");
|
|
123
|
-
const textarea = /* @__PURE__ */ jsx("textarea", {
|
|
124
|
-
id: textareaId,
|
|
125
|
-
className: cn("flex min-h-[120px] w-full resize-y rounded-lg border bg-card px-4 py-3 text-sm", "placeholder:text-muted-foreground", "disabled:cursor-not-allowed disabled:opacity-50", focusField, error && "border-[var(--surface-danger-border)] hover:border-[var(--surface-danger-border)] focus:border-[var(--focus-border-danger)] focus:ring-[var(--focus-halo-danger)]", className),
|
|
126
|
-
ref,
|
|
127
|
-
...props
|
|
128
|
-
});
|
|
129
|
-
if (!label && !error && !hint) return textarea;
|
|
130
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
131
|
-
className: "w-full space-y-1.5",
|
|
132
|
-
children: [
|
|
133
|
-
label && /* @__PURE__ */ jsx("label", {
|
|
134
|
-
htmlFor: textareaId,
|
|
135
|
-
className: "block font-medium text-muted-foreground text-sm",
|
|
136
|
-
children: label
|
|
137
|
-
}),
|
|
138
|
-
textarea,
|
|
139
|
-
error && /* @__PURE__ */ jsx("p", {
|
|
140
|
-
className: "text-[var(--surface-danger-text)] text-sm",
|
|
141
|
-
children: error
|
|
142
|
-
}),
|
|
143
|
-
hint && !error && /* @__PURE__ */ jsx("p", {
|
|
144
|
-
className: "text-[var(--text-dim)] text-sm",
|
|
145
|
-
children: hint
|
|
146
|
-
})
|
|
147
|
-
]
|
|
148
|
-
});
|
|
149
|
-
});
|
|
150
|
-
Textarea.displayName = "Textarea";
|
|
151
|
-
//#endregion
|
|
152
|
-
//#region src/primitives/select.tsx
|
|
153
|
-
const Select = SelectPrimitive.Root;
|
|
154
|
-
const SelectGroup = SelectPrimitive.Group;
|
|
155
|
-
const SelectValue = SelectPrimitive.Value;
|
|
156
|
-
const SelectTrigger = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(SelectPrimitive.Trigger, {
|
|
157
|
-
ref,
|
|
158
|
-
className: cn("flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border bg-card px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1", focusField, className),
|
|
159
|
-
...props,
|
|
160
|
-
children: [children, /* @__PURE__ */ jsx(SelectPrimitive.Icon, {
|
|
161
|
-
asChild: true,
|
|
162
|
-
children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 opacity-50" })
|
|
163
|
-
})]
|
|
164
|
-
}));
|
|
165
|
-
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
166
|
-
const SelectScrollUpButton = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.ScrollUpButton, {
|
|
167
|
-
ref,
|
|
168
|
-
className: cn("flex cursor-default items-center justify-center py-1", className),
|
|
169
|
-
...props,
|
|
170
|
-
children: /* @__PURE__ */ jsx(ChevronUp, { className: "h-4 w-4" })
|
|
171
|
-
}));
|
|
172
|
-
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
|
173
|
-
const SelectScrollDownButton = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.ScrollDownButton, {
|
|
174
|
-
ref,
|
|
175
|
-
className: cn("flex cursor-default items-center justify-center py-1", className),
|
|
176
|
-
...props,
|
|
177
|
-
children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4" })
|
|
178
|
-
}));
|
|
179
|
-
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
|
|
180
|
-
const SelectContent = React.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(SelectPrimitive.Content, {
|
|
181
|
-
ref,
|
|
182
|
-
className: cn("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", 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", className),
|
|
183
|
-
position,
|
|
184
|
-
...props,
|
|
185
|
-
children: [
|
|
186
|
-
/* @__PURE__ */ jsx(SelectScrollUpButton, {}),
|
|
187
|
-
/* @__PURE__ */ jsx(SelectPrimitive.Viewport, {
|
|
188
|
-
className: cn("p-1", position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"),
|
|
189
|
-
children
|
|
190
|
-
}),
|
|
191
|
-
/* @__PURE__ */ jsx(SelectScrollDownButton, {})
|
|
192
|
-
]
|
|
193
|
-
}) }));
|
|
194
|
-
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
195
|
-
const SelectLabel = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Label, {
|
|
196
|
-
ref,
|
|
197
|
-
className: cn("px-2 py-1.5 font-semibold text-sm", className),
|
|
198
|
-
...props
|
|
199
|
-
}));
|
|
200
|
-
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
201
|
-
const SelectItem = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(SelectPrimitive.Item, {
|
|
202
|
-
ref,
|
|
203
|
-
className: cn("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", className),
|
|
204
|
-
...props,
|
|
205
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
206
|
-
className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center",
|
|
207
|
-
children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" }) })
|
|
208
|
-
}), /* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children })]
|
|
209
|
-
}));
|
|
210
|
-
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
211
|
-
const SelectSeparator = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Separator, {
|
|
212
|
-
ref,
|
|
213
|
-
className: cn("-mx-1 my-1 h-px bg-border", className),
|
|
214
|
-
...props
|
|
215
|
-
}));
|
|
216
|
-
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
|
|
217
|
-
//#endregion
|
|
218
|
-
//#region src/primitives/segmented-control.tsx
|
|
219
|
-
function SegmentedControl({ value, onValueChange, options, variant = "row", className, ...rest }) {
|
|
220
|
-
if (typeof process !== "undefined" && process?.env?.NODE_ENV !== "production" && !rest["aria-label"] && !rest["aria-labelledby"]) console.warn("[SegmentedControl] role=\"radiogroup\" requires either aria-label or aria-labelledby for accessibility.");
|
|
221
|
-
const optionRefs = React.useRef(/* @__PURE__ */ new Map());
|
|
222
|
-
const hasMatch = options.some((o) => o.value === value);
|
|
223
|
-
const handleKeyDown = (e) => {
|
|
224
|
-
if (options.length === 0) return;
|
|
225
|
-
let idx = options.findIndex((o) => o.value === value);
|
|
226
|
-
if (idx === -1) idx = 0;
|
|
227
|
-
let next;
|
|
228
|
-
if (e.key === "ArrowRight" || e.key === "ArrowDown") next = (idx + 1) % options.length;
|
|
229
|
-
else if (e.key === "ArrowLeft" || e.key === "ArrowUp") next = (idx - 1 + options.length) % options.length;
|
|
230
|
-
else if (e.key === "Home") next = 0;
|
|
231
|
-
else if (e.key === "End") next = options.length - 1;
|
|
232
|
-
if (next !== void 0) {
|
|
233
|
-
e.preventDefault();
|
|
234
|
-
if (options[next].value !== value) onValueChange(options[next].value);
|
|
235
|
-
optionRefs.current.get(options[next].value)?.focus();
|
|
236
|
-
}
|
|
237
|
-
};
|
|
238
|
-
return /* @__PURE__ */ jsx("div", {
|
|
239
|
-
role: "radiogroup",
|
|
240
|
-
id: rest.id,
|
|
241
|
-
"aria-label": rest["aria-label"],
|
|
242
|
-
"aria-labelledby": rest["aria-labelledby"],
|
|
243
|
-
onKeyDown: handleKeyDown,
|
|
244
|
-
className: cn("flex gap-1", variant === "row" && "flex-wrap items-center rounded-lg border border-border bg-card p-1", variant === "tabs" && "flex-nowrap items-end border-b border-border pb-0 overflow-x-auto", className),
|
|
245
|
-
children: options.map((option, i) => {
|
|
246
|
-
const active = option.value === value;
|
|
247
|
-
return /* @__PURE__ */ jsxs("button", {
|
|
248
|
-
ref: (el) => {
|
|
249
|
-
if (el) optionRefs.current.set(option.value, el);
|
|
250
|
-
else optionRefs.current.delete(option.value);
|
|
251
|
-
},
|
|
252
|
-
type: "button",
|
|
253
|
-
role: "radio",
|
|
254
|
-
"aria-checked": active,
|
|
255
|
-
tabIndex: active || !hasMatch && i === 0 ? 0 : -1,
|
|
256
|
-
onClick: () => {
|
|
257
|
-
if (!active) onValueChange(option.value);
|
|
258
|
-
},
|
|
259
|
-
className: cn("relative inline-flex items-center gap-2 whitespace-nowrap text-sm transition-[color,background-color,border-color,box-shadow]", variant === "row" && ["rounded-md px-3 py-1.5", focusRing], variant === "tabs" && ["rounded-none border-b-2 -mb-px px-4 py-2", focusRingInset], 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"),
|
|
260
|
-
children: [/* @__PURE__ */ jsx("span", { children: option.label }), option.adornment && /* @__PURE__ */ jsx("span", {
|
|
261
|
-
className: cn("text-xs", active ? "text-[var(--accent-text)]/80" : "text-muted-foreground"),
|
|
262
|
-
children: option.adornment
|
|
263
|
-
})]
|
|
264
|
-
}, option.value);
|
|
265
|
-
})
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
//#endregion
|
|
269
|
-
//#region src/primitives/progress.tsx
|
|
270
|
-
const Progress = React.forwardRef(({ className, value, variant = "default", showValue = false, ...props }, ref) => {
|
|
271
|
-
const indicatorVariants = {
|
|
272
|
-
default: "bg-primary",
|
|
273
|
-
sandbox: "bg-[image:var(--accent-gradient-strong)]"
|
|
274
|
-
};
|
|
275
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
276
|
-
className: "relative",
|
|
277
|
-
children: [/* @__PURE__ */ jsx(ProgressPrimitive.Root, {
|
|
278
|
-
ref,
|
|
279
|
-
className: cn("relative h-2 w-full overflow-hidden rounded-full bg-muted", className),
|
|
280
|
-
...props,
|
|
281
|
-
children: /* @__PURE__ */ jsx(ProgressPrimitive.Indicator, {
|
|
282
|
-
className: cn("h-full w-full flex-1 transition-all duration-300 ease-out", indicatorVariants[variant]),
|
|
283
|
-
style: { transform: `translateX(-${100 - (value || 0)}%)` }
|
|
284
|
-
})
|
|
285
|
-
}), showValue && /* @__PURE__ */ jsxs("span", {
|
|
286
|
-
className: "absolute -top-6 right-0 text-muted-foreground text-xs",
|
|
287
|
-
children: [value, "%"]
|
|
288
|
-
})]
|
|
289
|
-
});
|
|
290
|
-
});
|
|
291
|
-
Progress.displayName = ProgressPrimitive.Root.displayName;
|
|
292
|
-
//#endregion
|
|
293
|
-
//#region src/primitives/switch.tsx
|
|
294
|
-
const Switch = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(SwitchPrimitives.Root, {
|
|
295
|
-
className: cn("peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-[background-color,box-shadow] disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input", focusRing, className),
|
|
296
|
-
...props,
|
|
297
|
-
ref,
|
|
298
|
-
children: /* @__PURE__ */ jsx(SwitchPrimitives.Thumb, { className: cn("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") })
|
|
299
|
-
}));
|
|
300
|
-
Switch.displayName = SwitchPrimitives.Root.displayName;
|
|
301
|
-
//#endregion
|
|
302
|
-
//#region src/primitives/skeleton.tsx
|
|
303
|
-
function Skeleton({ className, ...props }) {
|
|
304
|
-
return /* @__PURE__ */ jsx("div", {
|
|
305
|
-
className: cn("animate-pulse rounded-lg bg-muted/50", className),
|
|
306
|
-
...props
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
function SkeletonCard({ className }) {
|
|
310
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
311
|
-
className: cn("space-y-4 rounded-xl border border-border bg-card p-6", className),
|
|
312
|
-
children: [
|
|
313
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-3/4" }),
|
|
314
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/2" }),
|
|
315
|
-
/* @__PURE__ */ jsxs("div", {
|
|
316
|
-
className: "space-y-2 pt-4",
|
|
317
|
-
children: [
|
|
318
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-full" }),
|
|
319
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-5/6" }),
|
|
320
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-4/6" })
|
|
321
|
-
]
|
|
322
|
-
})
|
|
323
|
-
]
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
function SkeletonTable({ rows = 5 }) {
|
|
327
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
328
|
-
className: "space-y-3",
|
|
329
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
330
|
-
className: "flex gap-4 border-border border-b pb-2",
|
|
331
|
-
children: [
|
|
332
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/4" }),
|
|
333
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/4" }),
|
|
334
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/4" }),
|
|
335
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/4" })
|
|
336
|
-
]
|
|
337
|
-
}), Array.from({ length: rows }).map((_, i) => /* @__PURE__ */ jsxs("div", {
|
|
338
|
-
className: "flex gap-4",
|
|
339
|
-
children: [
|
|
340
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/4" }),
|
|
341
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/4" }),
|
|
342
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/4" }),
|
|
343
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/4" })
|
|
344
|
-
]
|
|
345
|
-
}, i))]
|
|
346
|
-
});
|
|
347
|
-
}
|
|
348
|
-
//#endregion
|
|
349
|
-
//#region src/primitives/toast.tsx
|
|
350
|
-
const toastVariants = cva("pointer-events-auto relative flex w-full items-center justify-between gap-3 overflow-hidden rounded-lg border p-4 shadow-lg transition-all", {
|
|
351
|
-
variants: { variant: {
|
|
352
|
-
default: "border-border bg-background text-foreground",
|
|
353
|
-
success: "border-[var(--surface-success-border)] bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]",
|
|
354
|
-
error: "border-[var(--surface-danger-border)] bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)]",
|
|
355
|
-
warning: "border-[var(--surface-warning-border)] bg-[var(--surface-warning-bg)] text-[var(--surface-warning-text)]",
|
|
356
|
-
info: "border-[var(--surface-info-border)] bg-[var(--surface-info-bg)] text-[var(--surface-info-text)]"
|
|
357
|
-
} },
|
|
358
|
-
defaultVariants: { variant: "default" }
|
|
359
|
-
});
|
|
360
|
-
const icons = {
|
|
361
|
-
success: CheckCircle2,
|
|
362
|
-
error: AlertCircle,
|
|
363
|
-
warning: AlertTriangle,
|
|
364
|
-
info: Info,
|
|
365
|
-
default: Info
|
|
366
|
-
};
|
|
367
|
-
function ToastComponent({ id, title, description, variant = "default", onDismiss }) {
|
|
368
|
-
const Icon = icons[variant];
|
|
369
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
370
|
-
className: cn(toastVariants({ variant })),
|
|
371
|
-
role: "alert",
|
|
372
|
-
"aria-live": "polite",
|
|
373
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
374
|
-
className: "flex items-start gap-3",
|
|
375
|
-
children: [/* @__PURE__ */ jsx(Icon, {
|
|
376
|
-
className: "h-5 w-5 shrink-0",
|
|
377
|
-
"aria-hidden": "true"
|
|
378
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
379
|
-
className: "flex-1",
|
|
380
|
-
children: [/* @__PURE__ */ jsx("p", {
|
|
381
|
-
className: "font-medium text-sm",
|
|
382
|
-
children: title
|
|
383
|
-
}), description && /* @__PURE__ */ jsx("p", {
|
|
384
|
-
className: "mt-1 text-sm opacity-80",
|
|
385
|
-
children: description
|
|
386
|
-
})]
|
|
387
|
-
})]
|
|
388
|
-
}), /* @__PURE__ */ jsx("button", {
|
|
389
|
-
type: "button",
|
|
390
|
-
onClick: () => onDismiss(id),
|
|
391
|
-
className: cn("shrink-0 rounded-md p-1 opacity-70 transition-[opacity,box-shadow] hover:opacity-100 focus-visible:opacity-100", focusRing),
|
|
392
|
-
"aria-label": "Dismiss notification",
|
|
393
|
-
children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
|
|
394
|
-
})]
|
|
395
|
-
});
|
|
396
|
-
}
|
|
397
|
-
function ToastContainer({ toasts, onDismiss }) {
|
|
398
|
-
return /* @__PURE__ */ jsx("div", {
|
|
399
|
-
role: "region",
|
|
400
|
-
className: "fixed right-4 bottom-4 z-50 flex max-w-md flex-col gap-2",
|
|
401
|
-
"aria-label": "Notifications",
|
|
402
|
-
children: toasts.map((toast) => /* @__PURE__ */ jsx(ToastComponent, {
|
|
403
|
-
...toast,
|
|
404
|
-
onDismiss
|
|
405
|
-
}, toast.id))
|
|
406
|
-
});
|
|
407
|
-
}
|
|
408
|
-
const ToastContext = React.createContext(null);
|
|
409
|
-
function ToastProvider({ children }) {
|
|
410
|
-
const [toasts, setToasts] = React.useState([]);
|
|
411
|
-
const dismiss = React.useCallback((id) => {
|
|
412
|
-
setToasts((prev) => prev.filter((t) => t.id !== id));
|
|
413
|
-
}, []);
|
|
414
|
-
const toast = React.useCallback((input) => {
|
|
415
|
-
const id = Math.random().toString(36).slice(2);
|
|
416
|
-
const newToast = {
|
|
417
|
-
id,
|
|
418
|
-
...input
|
|
419
|
-
};
|
|
420
|
-
setToasts((prev) => [...prev, newToast]);
|
|
421
|
-
const duration = input.duration ?? 5e3;
|
|
422
|
-
if (duration > 0) setTimeout(() => dismiss(id), duration);
|
|
423
|
-
}, [dismiss]);
|
|
424
|
-
const success = React.useCallback((title, description) => {
|
|
425
|
-
toast({
|
|
426
|
-
title,
|
|
427
|
-
description,
|
|
428
|
-
variant: "success"
|
|
429
|
-
});
|
|
430
|
-
}, [toast]);
|
|
431
|
-
const error = React.useCallback((title, description) => {
|
|
432
|
-
toast({
|
|
433
|
-
title,
|
|
434
|
-
description,
|
|
435
|
-
variant: "error"
|
|
436
|
-
});
|
|
437
|
-
}, [toast]);
|
|
438
|
-
const warning = React.useCallback((title, description) => {
|
|
439
|
-
toast({
|
|
440
|
-
title,
|
|
441
|
-
description,
|
|
442
|
-
variant: "warning"
|
|
443
|
-
});
|
|
444
|
-
}, [toast]);
|
|
445
|
-
const info = React.useCallback((title, description) => {
|
|
446
|
-
toast({
|
|
447
|
-
title,
|
|
448
|
-
description,
|
|
449
|
-
variant: "info"
|
|
450
|
-
});
|
|
451
|
-
}, [toast]);
|
|
452
|
-
const value = React.useMemo(() => ({
|
|
453
|
-
toasts,
|
|
454
|
-
toast,
|
|
455
|
-
success,
|
|
456
|
-
error,
|
|
457
|
-
warning,
|
|
458
|
-
info,
|
|
459
|
-
dismiss
|
|
460
|
-
}), [
|
|
461
|
-
toasts,
|
|
462
|
-
toast,
|
|
463
|
-
success,
|
|
464
|
-
error,
|
|
465
|
-
warning,
|
|
466
|
-
info,
|
|
467
|
-
dismiss
|
|
468
|
-
]);
|
|
469
|
-
return /* @__PURE__ */ jsxs(ToastContext.Provider, {
|
|
470
|
-
value,
|
|
471
|
-
children: [children, /* @__PURE__ */ jsx(ToastContainer, {
|
|
472
|
-
toasts,
|
|
473
|
-
onDismiss: dismiss
|
|
474
|
-
})]
|
|
475
|
-
});
|
|
476
|
-
}
|
|
477
|
-
function useToast() {
|
|
478
|
-
const context = React.useContext(ToastContext);
|
|
479
|
-
if (!context) throw new Error("useToast must be used within a ToastProvider");
|
|
480
|
-
return context;
|
|
481
|
-
}
|
|
482
|
-
//#endregion
|
|
483
|
-
//#region src/primitives/label.tsx
|
|
484
|
-
const labelVariants = cva("font-medium text-sm leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70");
|
|
485
|
-
const Label = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(LabelPrimitive.Root, {
|
|
486
|
-
ref,
|
|
487
|
-
className: cn(labelVariants(), className),
|
|
488
|
-
...props
|
|
489
|
-
}));
|
|
490
|
-
Label.displayName = LabelPrimitive.Root.displayName;
|
|
491
|
-
//#endregion
|
|
492
|
-
//#region src/primitives/empty-state.tsx
|
|
493
|
-
const EmptyState = React.forwardRef(({ className, icon, title, description, action, ...props }, ref) => {
|
|
494
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
495
|
-
ref,
|
|
496
|
-
className: cn("flex flex-col items-center justify-center px-4 py-16 text-center", className),
|
|
497
|
-
...props,
|
|
498
|
-
children: [
|
|
499
|
-
icon && /* @__PURE__ */ jsx("div", {
|
|
500
|
-
className: "mb-4 rounded-full bg-muted p-4 text-muted-foreground",
|
|
501
|
-
children: icon
|
|
502
|
-
}),
|
|
503
|
-
/* @__PURE__ */ jsx("h3", {
|
|
504
|
-
className: "font-semibold text-lg",
|
|
505
|
-
children: title
|
|
506
|
-
}),
|
|
507
|
-
description && /* @__PURE__ */ jsx("p", {
|
|
508
|
-
className: "mt-2 max-w-sm text-muted-foreground text-sm",
|
|
509
|
-
children: description
|
|
510
|
-
}),
|
|
511
|
-
action && /* @__PURE__ */ jsx("div", {
|
|
512
|
-
className: "mt-6",
|
|
513
|
-
children: action
|
|
514
|
-
})
|
|
515
|
-
]
|
|
516
|
-
});
|
|
517
|
-
});
|
|
518
|
-
EmptyState.displayName = "EmptyState";
|
|
519
|
-
//#endregion
|
|
520
|
-
//#region src/primitives/stat-card.tsx
|
|
521
|
-
const StatCard = React.forwardRef(({ className, variant = "default", title, value, subtitle, icon, trend, ...props }, ref) => {
|
|
522
|
-
const iconColors = {
|
|
523
|
-
default: "text-muted-foreground",
|
|
524
|
-
sandbox: "text-[var(--accent-text)]"
|
|
525
|
-
};
|
|
526
|
-
const trendColors = {
|
|
527
|
-
positive: "text-[var(--surface-success-text)]",
|
|
528
|
-
negative: "text-[var(--surface-danger-text)]",
|
|
529
|
-
neutral: "text-muted-foreground"
|
|
530
|
-
};
|
|
531
|
-
const trendStatus = trend ? trend.value > 0 ? "positive" : trend.value < 0 ? "negative" : "neutral" : null;
|
|
532
|
-
return /* @__PURE__ */ jsx(Card, {
|
|
533
|
-
ref,
|
|
534
|
-
variant,
|
|
535
|
-
className: cn("p-6", className),
|
|
536
|
-
...props,
|
|
537
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
538
|
-
className: "flex items-start justify-between",
|
|
539
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
540
|
-
className: "space-y-1",
|
|
541
|
-
children: [
|
|
542
|
-
/* @__PURE__ */ jsx("p", {
|
|
543
|
-
className: "text-muted-foreground text-sm",
|
|
544
|
-
children: title
|
|
545
|
-
}),
|
|
546
|
-
/* @__PURE__ */ jsx("p", {
|
|
547
|
-
className: "font-bold text-3xl tracking-tight",
|
|
548
|
-
children: value
|
|
549
|
-
}),
|
|
550
|
-
subtitle && /* @__PURE__ */ jsx("p", {
|
|
551
|
-
className: "text-[var(--text-dim)] text-xs",
|
|
552
|
-
children: subtitle
|
|
553
|
-
}),
|
|
554
|
-
trend && trendStatus && /* @__PURE__ */ jsxs("div", {
|
|
555
|
-
className: cn("flex items-center gap-1 text-sm", trendColors[trendStatus]),
|
|
556
|
-
children: [
|
|
557
|
-
trend.value > 0 ? "↑" : trend.value < 0 ? "↓" : "→",
|
|
558
|
-
/* @__PURE__ */ jsxs("span", { children: [Math.abs(trend.value), "%"] }),
|
|
559
|
-
trend.label && /* @__PURE__ */ jsx("span", {
|
|
560
|
-
className: "text-muted-foreground",
|
|
561
|
-
children: trend.label
|
|
562
|
-
})
|
|
563
|
-
]
|
|
564
|
-
})
|
|
565
|
-
]
|
|
566
|
-
}), icon && /* @__PURE__ */ jsx("div", {
|
|
567
|
-
className: cn("rounded-lg bg-muted/50 p-2", variant === "sandbox" && "bg-[var(--accent-surface-soft)]", iconColors[variant]),
|
|
568
|
-
children: icon
|
|
569
|
-
})]
|
|
570
|
-
})
|
|
571
|
-
});
|
|
572
|
-
});
|
|
573
|
-
StatCard.displayName = "StatCard";
|
|
574
|
-
//#endregion
|
|
575
|
-
//#region src/primitives/terminal-display.tsx
|
|
576
|
-
const TerminalDisplay = React.forwardRef(({ className, variant = "default", title = "Terminal", showHeader = true, autoScroll = true, maxHeight = "400px", children, ...props }, ref) => {
|
|
577
|
-
const containerRef = useRef(null);
|
|
578
|
-
useEffect(() => {
|
|
579
|
-
if (autoScroll && containerRef.current) containerRef.current.scrollTop = containerRef.current.scrollHeight;
|
|
580
|
-
}, [autoScroll]);
|
|
581
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
582
|
-
ref,
|
|
583
|
-
className: cn("overflow-hidden rounded-xl border bg-background font-mono text-sm", {
|
|
584
|
-
default: "border-border",
|
|
585
|
-
sandbox: "border-border shadow-[var(--shadow-accent)]"
|
|
586
|
-
}[variant], className),
|
|
587
|
-
...props,
|
|
588
|
-
children: [showHeader && /* @__PURE__ */ jsx("div", {
|
|
589
|
-
className: "flex items-center border-b border-border bg-card px-4 py-3",
|
|
590
|
-
children: /* @__PURE__ */ jsx("span", {
|
|
591
|
-
className: "text-muted-foreground text-xs",
|
|
592
|
-
children: title
|
|
593
|
-
})
|
|
594
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
595
|
-
ref: containerRef,
|
|
596
|
-
className: "overflow-auto p-4",
|
|
597
|
-
style: { maxHeight },
|
|
598
|
-
children
|
|
599
|
-
})]
|
|
600
|
-
});
|
|
601
|
-
});
|
|
602
|
-
TerminalDisplay.displayName = "TerminalDisplay";
|
|
603
|
-
const TerminalLine = React.forwardRef(({ className, type = "output", prompt = "$", timestamp, children, ...props }, ref) => {
|
|
604
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
605
|
-
ref,
|
|
606
|
-
className: cn("flex items-start gap-2 py-0.5 leading-relaxed", {
|
|
607
|
-
input: "text-foreground",
|
|
608
|
-
output: "text-foreground",
|
|
609
|
-
error: "text-[var(--surface-danger-text)]",
|
|
610
|
-
success: "text-[var(--surface-success-text)]",
|
|
611
|
-
info: "text-[var(--surface-info-text)]",
|
|
612
|
-
thinking: "text-[var(--surface-warning-text)] animate-pulse",
|
|
613
|
-
command: "text-foreground",
|
|
614
|
-
warning: "text-[var(--surface-warning-text)]"
|
|
615
|
-
}[type], className),
|
|
616
|
-
...props,
|
|
617
|
-
children: [
|
|
618
|
-
(type === "input" || type === "command") && /* @__PURE__ */ jsx("span", {
|
|
619
|
-
className: "shrink-0 select-none text-[var(--surface-success-text)]",
|
|
620
|
-
children: prompt
|
|
621
|
-
}),
|
|
622
|
-
type === "thinking" && /* @__PURE__ */ jsx("span", {
|
|
623
|
-
className: "shrink-0 select-none",
|
|
624
|
-
children: "..."
|
|
625
|
-
}),
|
|
626
|
-
timestamp && /* @__PURE__ */ jsxs("span", {
|
|
627
|
-
className: "shrink-0 select-none text-[var(--text-dim)]",
|
|
628
|
-
children: [
|
|
629
|
-
"[",
|
|
630
|
-
timestamp,
|
|
631
|
-
"]"
|
|
632
|
-
]
|
|
633
|
-
}),
|
|
634
|
-
/* @__PURE__ */ jsx("span", {
|
|
635
|
-
className: "whitespace-pre-wrap break-all",
|
|
636
|
-
children
|
|
637
|
-
})
|
|
638
|
-
]
|
|
639
|
-
});
|
|
640
|
-
});
|
|
641
|
-
TerminalLine.displayName = "TerminalLine";
|
|
642
|
-
const TerminalCursor = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("span", {
|
|
643
|
-
ref,
|
|
644
|
-
className: cn("ml-0.5 inline-block h-4 w-2 animate-pulse bg-foreground", className),
|
|
645
|
-
...props
|
|
646
|
-
}));
|
|
647
|
-
TerminalCursor.displayName = "TerminalCursor";
|
|
648
|
-
const TerminalInput = React.forwardRef(({ className, onSubmit, variant: _variant, ...props }, ref) => {
|
|
649
|
-
const [value, setValue] = React.useState("");
|
|
650
|
-
const handleKeyDown = (e) => {
|
|
651
|
-
if (e.key === "Enter" && value.trim() && onSubmit) {
|
|
652
|
-
onSubmit(value.trim());
|
|
653
|
-
setValue("");
|
|
654
|
-
}
|
|
655
|
-
};
|
|
656
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
657
|
-
className: cn("flex items-center rounded-lg border bg-background px-4 py-2.5 font-mono text-sm", focusFieldWithin, className),
|
|
658
|
-
children: [
|
|
659
|
-
/* @__PURE__ */ jsx("span", {
|
|
660
|
-
className: "mr-2 select-none text-[var(--surface-success-text)]",
|
|
661
|
-
children: "$"
|
|
662
|
-
}),
|
|
663
|
-
/* @__PURE__ */ jsx("input", {
|
|
664
|
-
ref,
|
|
665
|
-
type: "text",
|
|
666
|
-
value,
|
|
667
|
-
onChange: (e) => setValue(e.target.value),
|
|
668
|
-
onKeyDown: handleKeyDown,
|
|
669
|
-
className: "flex-1 bg-transparent text-foreground outline-none placeholder:text-muted-foreground",
|
|
670
|
-
...props
|
|
671
|
-
}),
|
|
672
|
-
/* @__PURE__ */ jsx(TerminalCursor, {})
|
|
673
|
-
]
|
|
674
|
-
});
|
|
675
|
-
});
|
|
676
|
-
TerminalInput.displayName = "TerminalInput";
|
|
677
|
-
//#endregion
|
|
678
|
-
//#region src/primitives/drop-zone.tsx
|
|
679
|
-
/**
|
|
680
|
-
* DropZone — full-window drag-and-drop file upload overlay.
|
|
681
|
-
*
|
|
682
|
-
* Detects when files are dragged over the browser window and shows a
|
|
683
|
-
* customizable overlay. Products provide the onDrop handler and optional
|
|
684
|
-
* custom overlay content.
|
|
685
|
-
*
|
|
686
|
-
* Usage:
|
|
687
|
-
* <DropZone onDrop={files => uploadToR2(files)} accept=".pdf,.csv">
|
|
688
|
-
* <YourApp />
|
|
689
|
-
* </DropZone>
|
|
690
|
-
*/
|
|
691
|
-
function DropZone({ onDrop, accept, disabled, overlay, title = "Drop files to upload", description = "Your files will be securely stored in the workspace.", icon = "cloud_upload", children, className }) {
|
|
692
|
-
const [dragOver, setDragOver] = useState(false);
|
|
693
|
-
const counter = useRef(0);
|
|
694
|
-
const isAccepted = useCallback((file) => {
|
|
695
|
-
if (!accept) return true;
|
|
696
|
-
const extensions = accept.split(",").map((ext) => ext.trim().toLowerCase());
|
|
697
|
-
const fileName = file.name.toLowerCase();
|
|
698
|
-
return extensions.some((ext) => fileName.endsWith(ext));
|
|
699
|
-
}, [accept]);
|
|
700
|
-
const handleDragEnter = useCallback((e) => {
|
|
701
|
-
e.preventDefault();
|
|
702
|
-
if (disabled) return;
|
|
703
|
-
counter.current++;
|
|
704
|
-
if (e.dataTransfer?.types.includes("Files")) setDragOver(true);
|
|
705
|
-
}, [disabled]);
|
|
706
|
-
const handleDragLeave = useCallback((e) => {
|
|
707
|
-
e.preventDefault();
|
|
708
|
-
counter.current--;
|
|
709
|
-
if (counter.current === 0) setDragOver(false);
|
|
710
|
-
}, []);
|
|
711
|
-
const handleDragOver = useCallback((e) => {
|
|
712
|
-
e.preventDefault();
|
|
713
|
-
if (!disabled) e.dataTransfer.dropEffect = "copy";
|
|
714
|
-
}, [disabled]);
|
|
715
|
-
const handleDrop = useCallback((e) => {
|
|
716
|
-
e.preventDefault();
|
|
717
|
-
counter.current = 0;
|
|
718
|
-
setDragOver(false);
|
|
719
|
-
if (disabled) return;
|
|
720
|
-
const allFiles = Array.from(e.dataTransfer?.files || []);
|
|
721
|
-
const accepted = accept ? allFiles.filter(isAccepted) : allFiles;
|
|
722
|
-
if (accepted.length > 0) onDrop(accepted);
|
|
723
|
-
}, [
|
|
724
|
-
disabled,
|
|
725
|
-
accept,
|
|
726
|
-
isAccepted,
|
|
727
|
-
onDrop
|
|
728
|
-
]);
|
|
729
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
730
|
-
onDragEnter: handleDragEnter,
|
|
731
|
-
onDragLeave: handleDragLeave,
|
|
732
|
-
onDragOver: handleDragOver,
|
|
733
|
-
onDrop: handleDrop,
|
|
734
|
-
className: cn("relative", className),
|
|
735
|
-
children: [dragOver && (overlay || /* @__PURE__ */ jsx("div", {
|
|
736
|
-
className: "fixed inset-0 z-[100] flex items-center justify-center pointer-events-none bg-background",
|
|
737
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
738
|
-
className: "rounded-2xl border-2 border-dashed border-border bg-card p-16 text-center shadow-[var(--shadow-dropdown)] max-w-lg mx-auto",
|
|
739
|
-
children: [
|
|
740
|
-
/* @__PURE__ */ jsx("div", {
|
|
741
|
-
className: "mx-auto mb-6 flex h-20 w-20 items-center justify-center rounded-2xl border border-border bg-[var(--accent-surface-soft)]",
|
|
742
|
-
children: typeof icon === "string" ? /* @__PURE__ */ jsxs("svg", {
|
|
743
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
744
|
-
viewBox: "0 0 24 24",
|
|
745
|
-
fill: "none",
|
|
746
|
-
stroke: "currentColor",
|
|
747
|
-
strokeWidth: "1.5",
|
|
748
|
-
strokeLinecap: "round",
|
|
749
|
-
strokeLinejoin: "round",
|
|
750
|
-
className: "h-10 w-10 text-[var(--accent-text)]",
|
|
751
|
-
children: [
|
|
752
|
-
/* @__PURE__ */ jsx("title", { children: "Upload" }),
|
|
753
|
-
/* @__PURE__ */ jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
754
|
-
/* @__PURE__ */ jsx("polyline", { points: "17 8 12 3 7 8" }),
|
|
755
|
-
/* @__PURE__ */ jsx("line", {
|
|
756
|
-
x1: "12",
|
|
757
|
-
x2: "12",
|
|
758
|
-
y1: "3",
|
|
759
|
-
y2: "15"
|
|
760
|
-
})
|
|
761
|
-
]
|
|
762
|
-
}) : icon
|
|
763
|
-
}),
|
|
764
|
-
/* @__PURE__ */ jsx("h2", {
|
|
765
|
-
className: "text-2xl font-bold text-foreground",
|
|
766
|
-
children: title
|
|
767
|
-
}),
|
|
768
|
-
/* @__PURE__ */ jsx("p", {
|
|
769
|
-
className: "mt-2 text-sm text-muted-foreground",
|
|
770
|
-
children: description
|
|
771
|
-
})
|
|
772
|
-
]
|
|
773
|
-
})
|
|
774
|
-
})), children]
|
|
775
|
-
});
|
|
776
|
-
}
|
|
777
|
-
//#endregion
|
|
778
|
-
//#region src/primitives/upload-progress.tsx
|
|
779
|
-
/**
|
|
780
|
-
* UploadProgress — file upload status indicators.
|
|
781
|
-
*
|
|
782
|
-
* Shows a list of files being uploaded with progress bars,
|
|
783
|
-
* completion checkmarks, and error states.
|
|
784
|
-
*/
|
|
785
|
-
function formatSize(bytes) {
|
|
786
|
-
if (bytes < 1024) return `${bytes}B`;
|
|
787
|
-
if (bytes < 1048576) return `${(bytes / 1024).toFixed(0)}KB`;
|
|
788
|
-
return `${(bytes / 1048576).toFixed(1)}MB`;
|
|
789
|
-
}
|
|
790
|
-
function UploadProgress({ files, onRemove, onRetry, className }) {
|
|
791
|
-
if (files.length === 0) return null;
|
|
792
|
-
return /* @__PURE__ */ jsx("div", {
|
|
793
|
-
className: cn("space-y-2", className),
|
|
794
|
-
children: files.map((file) => /* @__PURE__ */ jsxs("div", {
|
|
795
|
-
className: cn("flex items-center gap-3 rounded-lg border px-3 py-2 text-sm", 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"),
|
|
796
|
-
children: [
|
|
797
|
-
file.status === "complete" && /* @__PURE__ */ jsx(CheckCircle2, { className: "h-4 w-4 shrink-0 text-[var(--surface-success-text)]" }),
|
|
798
|
-
file.status === "error" && /* @__PURE__ */ jsx(AlertCircle, { className: "h-4 w-4 shrink-0 text-[var(--surface-danger-text)]" }),
|
|
799
|
-
file.status === "uploading" && /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 shrink-0 animate-spin text-primary" }),
|
|
800
|
-
file.status === "pending" && /* @__PURE__ */ jsx(FileText, { className: "h-4 w-4 shrink-0 text-muted-foreground" }),
|
|
801
|
-
/* @__PURE__ */ jsxs("div", {
|
|
802
|
-
className: "min-w-0 flex-1",
|
|
803
|
-
children: [
|
|
804
|
-
/* @__PURE__ */ jsxs("div", {
|
|
805
|
-
className: "flex items-center gap-2",
|
|
806
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
807
|
-
className: "truncate font-medium text-foreground",
|
|
808
|
-
children: file.name
|
|
809
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
810
|
-
className: "shrink-0 text-xs text-muted-foreground",
|
|
811
|
-
children: formatSize(file.size)
|
|
812
|
-
})]
|
|
813
|
-
}),
|
|
814
|
-
file.status === "uploading" && file.progress !== void 0 && /* @__PURE__ */ jsx("div", {
|
|
815
|
-
className: "mt-1 h-1 w-full overflow-hidden rounded-full bg-muted/50",
|
|
816
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
817
|
-
className: "h-full rounded-full bg-primary transition-all",
|
|
818
|
-
style: { width: `${file.progress}%` }
|
|
819
|
-
})
|
|
820
|
-
}),
|
|
821
|
-
file.status === "error" && file.error && /* @__PURE__ */ jsx("p", {
|
|
822
|
-
className: "mt-0.5 text-xs text-[var(--surface-danger-text)]",
|
|
823
|
-
children: file.error
|
|
824
|
-
})
|
|
825
|
-
]
|
|
826
|
-
}),
|
|
827
|
-
/* @__PURE__ */ jsxs("div", {
|
|
828
|
-
className: "flex shrink-0 items-center gap-1",
|
|
829
|
-
children: [file.status === "error" && onRetry && /* @__PURE__ */ jsx("button", {
|
|
830
|
-
type: "button",
|
|
831
|
-
onClick: () => onRetry(file.id),
|
|
832
|
-
className: "rounded p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
|
|
833
|
-
children: /* @__PURE__ */ jsx(RefreshCw, { className: "h-3.5 w-3.5" })
|
|
834
|
-
}), onRemove && /* @__PURE__ */ jsx("button", {
|
|
835
|
-
type: "button",
|
|
836
|
-
onClick: () => onRemove(file.id),
|
|
837
|
-
className: "rounded p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
|
|
838
|
-
children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5" })
|
|
839
|
-
})]
|
|
840
|
-
})
|
|
841
|
-
]
|
|
842
|
-
}, file.id))
|
|
843
|
-
});
|
|
844
|
-
}
|
|
845
|
-
//#endregion
|
|
846
|
-
//#region src/primitives/sidebar-drop-zone.tsx
|
|
847
|
-
/**
|
|
848
|
-
* SidebarDropZone — compact scoped drop zone for sidebar panels and narrow containers.
|
|
849
|
-
*
|
|
850
|
-
* Unlike the full-window DropZone, this renders as an inline element
|
|
851
|
-
* that can be placed inside sidebar panels, file trees, or any container.
|
|
852
|
-
* Shows a subtle drop target when files are dragged over it.
|
|
853
|
-
*
|
|
854
|
-
* Usage:
|
|
855
|
-
* <SidebarPanelContent>
|
|
856
|
-
* <FileTree ... />
|
|
857
|
-
* <SidebarDropZone onDrop={uploadToWorkspace} title="Upload to workspace" />
|
|
858
|
-
* </SidebarPanelContent>
|
|
859
|
-
*/
|
|
860
|
-
function SidebarDropZone({ onDrop, accept, disabled, title = "Drop files here", description, icon, persistent = false, className }) {
|
|
861
|
-
const [dragOver, setDragOver] = useState(false);
|
|
862
|
-
const counter = useRef(0);
|
|
863
|
-
const isAccepted = useCallback((file) => {
|
|
864
|
-
if (!accept) return true;
|
|
865
|
-
const extensions = accept.split(",").map((ext) => ext.trim().toLowerCase());
|
|
866
|
-
const fileName = file.name.toLowerCase();
|
|
867
|
-
return extensions.some((ext) => fileName.endsWith(ext));
|
|
868
|
-
}, [accept]);
|
|
869
|
-
const handleDragEnter = useCallback((e) => {
|
|
870
|
-
e.preventDefault();
|
|
871
|
-
e.stopPropagation();
|
|
872
|
-
if (disabled) return;
|
|
873
|
-
counter.current++;
|
|
874
|
-
if (e.dataTransfer?.types.includes("Files")) setDragOver(true);
|
|
875
|
-
}, [disabled]);
|
|
876
|
-
const handleDragLeave = useCallback((e) => {
|
|
877
|
-
e.preventDefault();
|
|
878
|
-
e.stopPropagation();
|
|
879
|
-
counter.current--;
|
|
880
|
-
if (counter.current === 0) setDragOver(false);
|
|
881
|
-
}, []);
|
|
882
|
-
const handleDragOver = useCallback((e) => {
|
|
883
|
-
e.preventDefault();
|
|
884
|
-
e.stopPropagation();
|
|
885
|
-
if (!disabled) e.dataTransfer.dropEffect = "copy";
|
|
886
|
-
}, [disabled]);
|
|
887
|
-
const handleDrop = useCallback((e) => {
|
|
888
|
-
e.preventDefault();
|
|
889
|
-
e.stopPropagation();
|
|
890
|
-
counter.current = 0;
|
|
891
|
-
setDragOver(false);
|
|
892
|
-
if (disabled) return;
|
|
893
|
-
const allFiles = Array.from(e.dataTransfer?.files || []);
|
|
894
|
-
const accepted = accept ? allFiles.filter(isAccepted) : allFiles;
|
|
895
|
-
if (accepted.length > 0) onDrop(accepted);
|
|
896
|
-
}, [
|
|
897
|
-
disabled,
|
|
898
|
-
accept,
|
|
899
|
-
isAccepted,
|
|
900
|
-
onDrop
|
|
901
|
-
]);
|
|
902
|
-
const isVisible = persistent || dragOver;
|
|
903
|
-
return /* @__PURE__ */ jsx("div", {
|
|
904
|
-
onDragEnter: handleDragEnter,
|
|
905
|
-
onDragLeave: handleDragLeave,
|
|
906
|
-
onDragOver: handleDragOver,
|
|
907
|
-
onDrop: handleDrop,
|
|
908
|
-
className: cn("rounded-lg border-2 border-dashed transition-all duration-150", isVisible ? "p-4" : "p-0 border-transparent", 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)))]" : "", disabled && "opacity-50 pointer-events-none", className),
|
|
909
|
-
children: isVisible && /* @__PURE__ */ jsxs("div", {
|
|
910
|
-
className: "flex flex-col items-center gap-2 text-center",
|
|
911
|
-
children: [
|
|
912
|
-
/* @__PURE__ */ jsx("div", {
|
|
913
|
-
className: cn("flex h-8 w-8 items-center justify-center rounded-lg transition-colors", dragOver ? "bg-[var(--brand-cool,hsl(var(--primary)))]/15 text-[var(--brand-cool,hsl(var(--primary)))]" : "text-[var(--text-muted,hsl(var(--muted-foreground)))]"),
|
|
914
|
-
children: icon ?? /* @__PURE__ */ jsx(Upload, { className: "h-4 w-4" })
|
|
915
|
-
}),
|
|
916
|
-
/* @__PURE__ */ jsx("p", {
|
|
917
|
-
className: cn("text-xs font-medium", dragOver ? "text-[var(--text-primary,hsl(var(--foreground)))]" : "text-[var(--text-muted,hsl(var(--muted-foreground)))]"),
|
|
918
|
-
children: title
|
|
919
|
-
}),
|
|
920
|
-
description && /* @__PURE__ */ jsx("p", {
|
|
921
|
-
className: "text-[10px] text-[var(--text-muted,hsl(var(--muted-foreground)))]",
|
|
922
|
-
children: description
|
|
923
|
-
})
|
|
924
|
-
]
|
|
925
|
-
})
|
|
926
|
-
});
|
|
927
|
-
}
|
|
928
|
-
//#endregion
|
|
929
|
-
//#region src/primitives/code-block.tsx
|
|
930
|
-
function InlineCode({ className, children, ...props }) {
|
|
931
|
-
return /* @__PURE__ */ jsx("code", {
|
|
932
|
-
className: cn("rounded border border-border bg-muted px-1.5 py-0.5 font-mono text-[0.85em] text-foreground", className),
|
|
933
|
-
...props,
|
|
934
|
-
children
|
|
935
|
-
});
|
|
936
|
-
}
|
|
937
|
-
//#endregion
|
|
938
|
-
//#region src/primitives/theme-toggle.tsx
|
|
939
|
-
function getSystemTheme() {
|
|
940
|
-
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
941
|
-
}
|
|
942
|
-
function applyTheme(theme) {
|
|
943
|
-
const resolved = theme === "system" ? getSystemTheme() : theme;
|
|
944
|
-
document.documentElement.classList.toggle("dark", resolved === "dark");
|
|
945
|
-
}
|
|
946
|
-
function useTheme() {
|
|
947
|
-
const [theme, setThemeState] = useState(() => {
|
|
948
|
-
if (typeof window === "undefined") return "system";
|
|
949
|
-
return localStorage.getItem("theme") ?? "system";
|
|
950
|
-
});
|
|
951
|
-
const setTheme = useCallback((next) => {
|
|
952
|
-
setThemeState(next);
|
|
953
|
-
if (next === "system") localStorage.removeItem("theme");
|
|
954
|
-
else localStorage.setItem("theme", next);
|
|
955
|
-
applyTheme(next);
|
|
956
|
-
}, []);
|
|
957
|
-
useEffect(() => {
|
|
958
|
-
applyTheme(theme);
|
|
959
|
-
if (theme !== "system") return;
|
|
960
|
-
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
961
|
-
const handler = () => applyTheme("system");
|
|
962
|
-
mq.addEventListener("change", handler);
|
|
963
|
-
return () => mq.removeEventListener("change", handler);
|
|
964
|
-
}, [theme]);
|
|
965
|
-
return {
|
|
966
|
-
theme,
|
|
967
|
-
setTheme
|
|
968
|
-
};
|
|
969
|
-
}
|
|
970
|
-
const iconClass = "h-4 w-4";
|
|
971
|
-
function SunIcon() {
|
|
972
|
-
return /* @__PURE__ */ jsxs("svg", {
|
|
973
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
974
|
-
viewBox: "0 0 24 24",
|
|
975
|
-
fill: "none",
|
|
976
|
-
stroke: "currentColor",
|
|
977
|
-
strokeWidth: 2,
|
|
978
|
-
strokeLinecap: "round",
|
|
979
|
-
strokeLinejoin: "round",
|
|
980
|
-
className: iconClass,
|
|
981
|
-
children: [/* @__PURE__ */ jsx("circle", {
|
|
982
|
-
cx: 12,
|
|
983
|
-
cy: 12,
|
|
984
|
-
r: 5
|
|
985
|
-
}), /* @__PURE__ */ jsx("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" })]
|
|
986
|
-
});
|
|
987
|
-
}
|
|
988
|
-
function MoonIcon() {
|
|
989
|
-
return /* @__PURE__ */ jsx("svg", {
|
|
990
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
991
|
-
viewBox: "0 0 24 24",
|
|
992
|
-
fill: "none",
|
|
993
|
-
stroke: "currentColor",
|
|
994
|
-
strokeWidth: 2,
|
|
995
|
-
strokeLinecap: "round",
|
|
996
|
-
strokeLinejoin: "round",
|
|
997
|
-
className: iconClass,
|
|
998
|
-
children: /* @__PURE__ */ jsx("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" })
|
|
999
|
-
});
|
|
1000
|
-
}
|
|
1001
|
-
function ThemeToggle() {
|
|
1002
|
-
const { theme, setTheme } = useTheme();
|
|
1003
|
-
const resolved = theme === "system" ? getSystemTheme() : theme;
|
|
1004
|
-
return /* @__PURE__ */ jsx("button", {
|
|
1005
|
-
type: "button",
|
|
1006
|
-
onClick: () => setTheme(resolved === "dark" ? "light" : "dark"),
|
|
1007
|
-
className: "inline-flex items-center justify-center rounded-md p-2 text-muted-foreground hover:bg-accent hover:text-accent-foreground transition-colors",
|
|
1008
|
-
"aria-label": `Switch to ${resolved === "dark" ? "light" : "dark"} mode`,
|
|
1009
|
-
children: resolved === "dark" ? /* @__PURE__ */ jsx(SunIcon, {}) : /* @__PURE__ */ jsx(MoonIcon, {})
|
|
1010
|
-
});
|
|
1011
|
-
}
|
|
1012
|
-
//#endregion
|
|
1013
|
-
//#region src/primitives/page-header.tsx
|
|
1014
|
-
const PageHeader = React.forwardRef(({ className, title, description, actions, meta, titleId, level = 1, ...props }, ref) => {
|
|
1015
|
-
const Heading = level === 1 ? "h1" : "h2";
|
|
1016
|
-
return /* @__PURE__ */ jsxs("header", {
|
|
1017
|
-
ref,
|
|
1018
|
-
className: cn("mb-6", className),
|
|
1019
|
-
...props,
|
|
1020
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
1021
|
-
className: "flex flex-wrap items-start justify-between gap-x-6 gap-y-3",
|
|
1022
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
1023
|
-
className: "min-w-0",
|
|
1024
|
-
children: [/* @__PURE__ */ jsx(Heading, {
|
|
1025
|
-
id: titleId,
|
|
1026
|
-
className: cn("text-balance font-semibold tracking-tight", level === 1 ? "text-2xl" : "text-lg"),
|
|
1027
|
-
children: title
|
|
1028
|
-
}), description && /* @__PURE__ */ jsx("p", {
|
|
1029
|
-
className: "mt-1 max-w-prose text-muted-foreground text-sm",
|
|
1030
|
-
children: description
|
|
1031
|
-
})]
|
|
1032
|
-
}), actions && /* @__PURE__ */ jsx("div", {
|
|
1033
|
-
className: "flex flex-wrap items-center gap-2",
|
|
1034
|
-
children: actions
|
|
1035
|
-
})]
|
|
1036
|
-
}), meta && /* @__PURE__ */ jsx("div", {
|
|
1037
|
-
className: "mt-3 flex flex-wrap items-center gap-x-4 gap-y-2 text-[var(--text-dim)] text-xs",
|
|
1038
|
-
children: meta
|
|
1039
|
-
})]
|
|
1040
|
-
});
|
|
1041
|
-
});
|
|
1042
|
-
PageHeader.displayName = "PageHeader";
|
|
1043
|
-
//#endregion
|
|
1044
|
-
//#region src/primitives/status-pill.tsx
|
|
1045
|
-
const TONE_SURFACE = {
|
|
1046
|
-
success: "bg-[var(--surface-success-bg)] text-[var(--surface-success-text)] border-[var(--surface-success-border)]",
|
|
1047
|
-
warning: "bg-[var(--surface-warning-bg)] text-[var(--surface-warning-text)] border-[var(--surface-warning-border)]",
|
|
1048
|
-
danger: "bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)] border-[var(--surface-danger-border)]",
|
|
1049
|
-
info: "bg-[var(--surface-info-bg)] text-[var(--surface-info-text)] border-[var(--surface-info-border)]",
|
|
1050
|
-
running: "bg-[var(--surface-info-bg)] text-[var(--surface-info-text)] border-[var(--surface-info-border)]",
|
|
1051
|
-
neutral: "bg-[var(--surface-neutral-bg)] text-[var(--surface-neutral-text)] border-[var(--surface-neutral-border)]"
|
|
1052
|
-
};
|
|
1053
|
-
/**
|
|
1054
|
-
* The text tier alone, for `bare`. Declared rather than recovered from
|
|
1055
|
-
* `TONE_SURFACE` by string search: picking the `text-` class out of that string
|
|
1056
|
-
* silently yields `undefined` the moment the triple gains a second `text-`
|
|
1057
|
-
* utility, and an undefined class removes the tone from the one channel `bare`
|
|
1058
|
-
* has left — the glyph — with nothing to signal that it happened.
|
|
1059
|
-
*/
|
|
1060
|
-
const TONE_TEXT = {
|
|
1061
|
-
success: "text-[var(--surface-success-text)]",
|
|
1062
|
-
warning: "text-[var(--surface-warning-text)]",
|
|
1063
|
-
danger: "text-[var(--surface-danger-text)]",
|
|
1064
|
-
info: "text-[var(--surface-info-text)]",
|
|
1065
|
-
running: "text-[var(--surface-info-text)]",
|
|
1066
|
-
neutral: "text-[var(--surface-neutral-text)]"
|
|
1067
|
-
};
|
|
1068
|
-
/**
|
|
1069
|
-
* One glyph per silhouette. `currentColor` throughout so the mark inherits the
|
|
1070
|
-
* tone's text colour and can never drift from the label beside it.
|
|
1071
|
-
*/
|
|
1072
|
-
function ToneGlyph({ tone }) {
|
|
1073
|
-
const common = {
|
|
1074
|
-
viewBox: "0 0 8 8",
|
|
1075
|
-
className: "size-2 shrink-0"
|
|
1076
|
-
};
|
|
1077
|
-
switch (tone) {
|
|
1078
|
-
case "success": return /* @__PURE__ */ jsx("svg", {
|
|
1079
|
-
...common,
|
|
1080
|
-
"aria-hidden": "true",
|
|
1081
|
-
fill: "currentColor",
|
|
1082
|
-
children: /* @__PURE__ */ jsx("circle", {
|
|
1083
|
-
cx: "4",
|
|
1084
|
-
cy: "4",
|
|
1085
|
-
r: "3.25"
|
|
1086
|
-
})
|
|
1087
|
-
});
|
|
1088
|
-
case "danger": return /* @__PURE__ */ jsxs("svg", {
|
|
1089
|
-
...common,
|
|
1090
|
-
"aria-hidden": "true",
|
|
1091
|
-
fill: "none",
|
|
1092
|
-
stroke: "currentColor",
|
|
1093
|
-
strokeWidth: "1.5",
|
|
1094
|
-
children: [/* @__PURE__ */ jsx("circle", {
|
|
1095
|
-
cx: "4",
|
|
1096
|
-
cy: "4",
|
|
1097
|
-
r: "3.1",
|
|
1098
|
-
fill: "currentColor",
|
|
1099
|
-
opacity: "0.35"
|
|
1100
|
-
}), /* @__PURE__ */ jsx("path", {
|
|
1101
|
-
d: "M1.9 6.1 6.1 1.9",
|
|
1102
|
-
strokeLinecap: "round"
|
|
1103
|
-
})]
|
|
1104
|
-
});
|
|
1105
|
-
case "warning": return /* @__PURE__ */ jsx("svg", {
|
|
1106
|
-
...common,
|
|
1107
|
-
"aria-hidden": "true",
|
|
1108
|
-
fill: "currentColor",
|
|
1109
|
-
children: /* @__PURE__ */ jsx("path", { d: "M4 0.6 7.7 7.1H0.3z" })
|
|
1110
|
-
});
|
|
1111
|
-
case "running": return /* @__PURE__ */ jsx("svg", {
|
|
1112
|
-
...common,
|
|
1113
|
-
"aria-hidden": "true",
|
|
1114
|
-
fill: "none",
|
|
1115
|
-
stroke: "currentColor",
|
|
1116
|
-
strokeWidth: "1.75",
|
|
1117
|
-
children: /* @__PURE__ */ jsx("circle", {
|
|
1118
|
-
cx: "4",
|
|
1119
|
-
cy: "4",
|
|
1120
|
-
r: "2.9"
|
|
1121
|
-
})
|
|
1122
|
-
});
|
|
1123
|
-
case "info": return /* @__PURE__ */ jsx("svg", {
|
|
1124
|
-
...common,
|
|
1125
|
-
"aria-hidden": "true",
|
|
1126
|
-
fill: "currentColor",
|
|
1127
|
-
children: /* @__PURE__ */ jsx("rect", {
|
|
1128
|
-
x: "0.9",
|
|
1129
|
-
y: "0.9",
|
|
1130
|
-
width: "6.2",
|
|
1131
|
-
height: "6.2",
|
|
1132
|
-
rx: "1.2"
|
|
1133
|
-
})
|
|
1134
|
-
});
|
|
1135
|
-
default: return /* @__PURE__ */ jsx("svg", {
|
|
1136
|
-
...common,
|
|
1137
|
-
"aria-hidden": "true",
|
|
1138
|
-
fill: "none",
|
|
1139
|
-
stroke: "currentColor",
|
|
1140
|
-
strokeWidth: "1.75",
|
|
1141
|
-
children: /* @__PURE__ */ jsx("path", {
|
|
1142
|
-
d: "M1 4h6",
|
|
1143
|
-
strokeLinecap: "round"
|
|
1144
|
-
})
|
|
1145
|
-
});
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
1148
|
-
const StatusPill = React.forwardRef(({ className, tone, children, bare = false, size = "sm", ...props }, ref) => /* @__PURE__ */ jsxs("span", {
|
|
1149
|
-
ref,
|
|
1150
|
-
className: cn("inline-flex items-center gap-1.5 whitespace-nowrap rounded-full font-medium", size === "sm" ? "px-2 py-0.5 text-xs" : "px-2.5 py-1 text-sm", bare ? "border border-transparent bg-transparent px-0" : cn("border", TONE_SURFACE[tone]), className),
|
|
1151
|
-
...props,
|
|
1152
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
1153
|
-
className: cn("inline-flex", bare && TONE_TEXT[tone]),
|
|
1154
|
-
children: /* @__PURE__ */ jsx(ToneGlyph, { tone })
|
|
1155
|
-
}), children]
|
|
1156
|
-
}));
|
|
1157
|
-
StatusPill.displayName = "StatusPill";
|
|
1158
|
-
//#endregion
|
|
1159
|
-
//#region src/primitives/metric-strip.tsx
|
|
1160
|
-
const MetricStrip = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx("dl", {
|
|
1161
|
-
ref,
|
|
1162
|
-
className: cn("grid grid-cols-2 rounded-[var(--radius-lg)] border border-border bg-card shadow-[var(--shadow-card)] sm:grid-cols-4", className),
|
|
1163
|
-
...props,
|
|
1164
|
-
children
|
|
1165
|
-
}));
|
|
1166
|
-
MetricStrip.displayName = "MetricStrip";
|
|
1167
|
-
/**
|
|
1168
|
-
* One reading inside a `MetricStrip`.
|
|
1169
|
-
*
|
|
1170
|
-
* `<dt>` carries the label and `<dd>` the value, so the pair is announced as a
|
|
1171
|
-
* described term rather than as two loose strings — the semantic that makes a
|
|
1172
|
-
* figure legible without the visual grouping.
|
|
1173
|
-
*
|
|
1174
|
-
* The value is `tabular-nums`: these sit in a row and change on a timer, and
|
|
1175
|
-
* proportional digits make the column jitter every time a 1 becomes an 8.
|
|
1176
|
-
*/
|
|
1177
|
-
const Metric = React.forwardRef(({ className, label, value, hint, attention, ...props }, ref) => /* @__PURE__ */ jsxs("div", {
|
|
1178
|
-
ref,
|
|
1179
|
-
className: cn("border-border p-4 sm:p-5", "max-sm:[&:not(:nth-child(2n+1))]:border-l", "sm:[&:not(:nth-child(4n+1))]:border-l", className),
|
|
1180
|
-
...props,
|
|
1181
|
-
children: [
|
|
1182
|
-
/* @__PURE__ */ jsxs("dt", {
|
|
1183
|
-
className: "flex items-center gap-2 text-muted-foreground text-sm",
|
|
1184
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
1185
|
-
className: "truncate",
|
|
1186
|
-
children: label
|
|
1187
|
-
}), attention && /* @__PURE__ */ jsx(StatusPill, {
|
|
1188
|
-
tone: attention.tone,
|
|
1189
|
-
children: attention.label
|
|
1190
|
-
})]
|
|
1191
|
-
}),
|
|
1192
|
-
/* @__PURE__ */ jsx("dd", {
|
|
1193
|
-
className: cn("mt-1 truncate font-semibold text-xl tabular-nums tracking-tight lg:text-2xl", attention?.tone === "danger" && "text-[var(--surface-danger-text)]"),
|
|
1194
|
-
title: typeof value === "string" ? value : void 0,
|
|
1195
|
-
children: value
|
|
1196
|
-
}),
|
|
1197
|
-
hint && /* @__PURE__ */ jsx("dd", {
|
|
1198
|
-
className: "mt-0.5 truncate text-[var(--text-dim)] text-xs",
|
|
1199
|
-
title: typeof hint === "string" ? hint : void 0,
|
|
1200
|
-
children: hint
|
|
1201
|
-
})
|
|
1202
|
-
]
|
|
1203
|
-
}));
|
|
1204
|
-
Metric.displayName = "Metric";
|
|
1205
|
-
//#endregion
|
|
1206
|
-
//#region src/primitives/toolbar.tsx
|
|
1207
|
-
const Toolbar = React.forwardRef(({ className, search, filters, actions, ...props }, ref) => /* @__PURE__ */ jsxs("div", {
|
|
1208
|
-
ref,
|
|
1209
|
-
className: cn("mb-4 flex flex-col gap-3 lg:flex-row lg:items-center", className),
|
|
1210
|
-
...props,
|
|
1211
|
-
children: [
|
|
1212
|
-
search && /* @__PURE__ */ jsx("div", {
|
|
1213
|
-
className: "min-w-0 lg:max-w-sm lg:flex-1",
|
|
1214
|
-
children: search
|
|
1215
|
-
}),
|
|
1216
|
-
filters && /* @__PURE__ */ jsx("div", {
|
|
1217
|
-
className: "flex min-w-0 items-center gap-2 overflow-x-auto py-1 lg:flex-1",
|
|
1218
|
-
children: filters
|
|
1219
|
-
}),
|
|
1220
|
-
actions && /* @__PURE__ */ jsx("div", {
|
|
1221
|
-
className: "flex shrink-0 items-center gap-2 lg:ml-auto",
|
|
1222
|
-
children: actions
|
|
1223
|
-
})
|
|
1224
|
-
]
|
|
1225
|
-
}));
|
|
1226
|
-
Toolbar.displayName = "Toolbar";
|
|
1227
|
-
const FilterField = React.forwardRef(({ className, label, htmlFor, children, ...props }, ref) => /* @__PURE__ */ jsxs("div", {
|
|
1228
|
-
ref,
|
|
1229
|
-
className: cn("flex shrink-0 items-center gap-2", className),
|
|
1230
|
-
...props,
|
|
1231
|
-
children: [/* @__PURE__ */ jsx("label", {
|
|
1232
|
-
htmlFor,
|
|
1233
|
-
className: "whitespace-nowrap text-muted-foreground text-xs",
|
|
1234
|
-
children: label
|
|
1235
|
-
}), children]
|
|
1236
|
-
}));
|
|
1237
|
-
FilterField.displayName = "FilterField";
|
|
1238
|
-
//#endregion
|
|
1239
|
-
export { SegmentedControl as A, SelectValue as B, ToastProvider as C, SkeletonTable as D, SkeletonCard as E, SelectLabel as F, DialogContent as G, Textarea as H, SelectScrollDownButton as I, DialogHeader as J, DialogDescription as K, SelectScrollUpButton as L, SelectContent as M, SelectGroup as N, Switch as O, SelectItem as P, DialogTrigger as Q, SelectSeparator as R, ToastContainer as S, Skeleton as T, Dialog as U, Input as V, DialogClose as W, DialogPortal as X, DialogOverlay as Y, DialogTitle as Z, TerminalInput as _, Metric as a, EmptyState as b, PageHeader as c, InlineCode as d, SidebarDropZone as f, TerminalDisplay as g, TerminalCursor as h, Toolbar as i, Select as j, Progress as k, ThemeToggle as l, DropZone as m, TangleKnot as n, MetricStrip as o, UploadProgress as p, DialogFooter as q, FilterField as r, StatusPill as s, Logo as t, useTheme as u, TerminalLine as v, useToast as w, Label as x, StatCard as y, SelectTrigger as z };
|