@iloveagents/foundry-web-ui 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -5
- package/dist/components/ag-ui-runtime-provider.d.ts +64 -0
- package/dist/components/ag-ui-runtime-provider.js +71 -0
- package/dist/components/app-brand.d.ts +6 -0
- package/dist/components/app-brand.js +13 -0
- package/dist/components/assistant-chat.d.ts +26 -0
- package/dist/components/assistant-chat.js +93 -0
- package/dist/components/chat-attachments.d.ts +25 -0
- package/dist/components/chat-attachments.js +20 -0
- package/dist/components/chat-bubble.d.ts +1 -0
- package/dist/components/chat-bubble.js +103 -0
- package/dist/components/chat-header.d.ts +2 -0
- package/dist/components/chat-header.js +16 -0
- package/dist/components/client-tool-executor.d.ts +12 -0
- package/dist/components/client-tool-executor.js +108 -0
- package/dist/components/collection-empty-state.d.ts +9 -0
- package/dist/components/collection-empty-state.js +6 -0
- package/dist/components/collection-filter-bar.d.ts +19 -0
- package/dist/components/collection-filter-bar.js +28 -0
- package/dist/components/collection-search-input.d.ts +6 -0
- package/dist/components/collection-search-input.js +8 -0
- package/dist/components/collection-skeleton.d.ts +6 -0
- package/dist/components/collection-skeleton.js +10 -0
- package/dist/components/collection-sort-menu.d.ts +10 -0
- package/dist/components/collection-sort-menu.js +9 -0
- package/dist/components/collection-surface.d.ts +8 -0
- package/dist/components/collection-surface.js +5 -0
- package/dist/components/collection-toolbar.d.ts +9 -0
- package/dist/components/collection-toolbar.js +5 -0
- package/dist/components/collection-view-toggle.d.ts +7 -0
- package/dist/components/collection-view-toggle.js +17 -0
- package/dist/components/composer-submit-bridge.d.ts +1 -0
- package/dist/components/composer-submit-bridge.js +15 -0
- package/dist/components/confirm-dialog.d.ts +11 -0
- package/dist/components/confirm-dialog.js +6 -0
- package/dist/components/confirmation-card.d.ts +14 -0
- package/dist/components/confirmation-card.js +12 -0
- package/dist/components/context-badges.d.ts +16 -0
- package/dist/components/context-badges.js +56 -0
- package/dist/components/context-bar.d.ts +41 -0
- package/dist/components/context-bar.js +123 -0
- package/dist/components/form-dialog.d.ts +12 -0
- package/dist/components/form-dialog.js +13 -0
- package/dist/components/global-selection-popover.d.ts +7 -0
- package/dist/components/global-selection-popover.js +167 -0
- package/dist/components/infinite-scroll-sentinel.d.ts +6 -0
- package/dist/components/infinite-scroll-sentinel.js +25 -0
- package/dist/components/json-viewer.d.ts +10 -0
- package/dist/components/json-viewer.js +80 -0
- package/dist/components/loading-indicator.d.ts +4 -0
- package/dist/components/loading-indicator.js +22 -0
- package/dist/components/markdown-text.d.ts +13 -0
- package/dist/components/markdown-text.js +221 -0
- package/dist/components/name-dialog.d.ts +16 -0
- package/dist/components/name-dialog.js +23 -0
- package/dist/components/selection-popover.d.ts +12 -0
- package/dist/components/selection-popover.js +111 -0
- package/dist/components/show-document-tool-ui.d.ts +1 -0
- package/dist/components/show-document-tool-ui.js +53 -0
- package/dist/components/sidebar.d.ts +4 -0
- package/dist/components/sidebar.js +904 -0
- package/dist/components/surface-card.d.ts +9 -0
- package/dist/components/surface-card.js +33 -0
- package/dist/components/theme-runtime-provider.d.ts +15 -0
- package/dist/components/theme-runtime-provider.js +48 -0
- package/dist/components/theme-toggle.d.ts +2 -0
- package/dist/components/theme-toggle.js +19 -0
- package/dist/components/tool-call-card.d.ts +27 -0
- package/dist/components/tool-call-card.js +13 -0
- package/dist/components/tool-fallback.d.ts +26 -0
- package/dist/components/tool-fallback.js +129 -0
- package/dist/components/tool-panel-layout.d.ts +10 -0
- package/dist/components/tool-panel-layout.js +12 -0
- package/dist/components/tool-panel.d.ts +1 -0
- package/dist/components/tool-panel.js +89 -0
- package/dist/components/tooltip-icon-button.d.ts +7 -0
- package/dist/components/tooltip-icon-button.js +9 -0
- package/dist/components/user-menu.d.ts +2 -0
- package/dist/components/user-menu.js +14 -0
- package/dist/index.d.ts +68 -0
- package/dist/index.js +83 -0
- package/dist/lib/ag-ui-adapter.d.ts +29 -0
- package/dist/lib/ag-ui-adapter.js +373 -0
- package/dist/lib/app-store.d.ts +115 -0
- package/dist/lib/app-store.js +199 -0
- package/dist/lib/attachment-adapter.d.ts +20 -0
- package/dist/lib/attachment-adapter.js +99 -0
- package/dist/lib/auth-provider.d.ts +16 -0
- package/dist/lib/auth-provider.js +88 -0
- package/dist/lib/chat-bubble-store.d.ts +30 -0
- package/dist/lib/chat-bubble-store.js +23 -0
- package/dist/lib/chat-lifecycle-store.d.ts +10 -0
- package/{src/lib/chat-lifecycle-store.ts → dist/lib/chat-lifecycle-store.js} +3 -13
- package/dist/lib/client-tools.d.ts +11 -0
- package/dist/lib/client-tools.js +274 -0
- package/dist/lib/composer-submit-store.d.ts +12 -0
- package/dist/lib/composer-submit-store.js +17 -0
- package/dist/lib/dev-store.d.ts +38 -0
- package/dist/lib/dev-store.js +32 -0
- package/dist/lib/nav-config.d.ts +159 -0
- package/dist/lib/nav-config.js +162 -0
- package/dist/lib/nav-dnd.d.ts +8 -0
- package/dist/lib/nav-dnd.js +9 -0
- package/dist/lib/nav-store.d.ts +45 -0
- package/dist/lib/nav-store.js +49 -0
- package/dist/lib/selection-context.d.ts +21 -0
- package/dist/lib/selection-context.js +34 -0
- package/dist/lib/sidebar-store.d.ts +23 -0
- package/dist/lib/sidebar-store.js +98 -0
- package/dist/lib/theme-runtime.d.ts +130 -0
- package/dist/lib/theme-runtime.js +479 -0
- package/dist/lib/theme-store.d.ts +15 -0
- package/dist/lib/theme-store.js +53 -0
- package/dist/lib/tool-panel-store.d.ts +48 -0
- package/dist/lib/tool-panel-store.js +69 -0
- package/dist/lib/use-new-conversation.d.ts +8 -0
- package/dist/lib/use-new-conversation.js +62 -0
- package/dist/lib/use-page-tools.d.ts +27 -0
- package/{src/lib/use-page-tools.ts → dist/lib/use-page-tools.js} +11 -13
- package/dist/styles.css +142 -0
- package/dist/ui/collapsible.d.ts +5 -0
- package/{src/ui/collapsible.tsx → dist/ui/collapsible.js} +0 -2
- package/dist/ui/dialog.d.ts +15 -0
- package/dist/ui/dialog.js +25 -0
- package/dist/ui/dropdown-menu.d.ts +7 -0
- package/dist/ui/dropdown-menu.js +19 -0
- package/dist/ui/popover.d.ts +7 -0
- package/dist/ui/popover.js +10 -0
- package/dist/ui/select.d.ts +4 -0
- package/dist/ui/select.js +9 -0
- package/dist/ui/tooltip.d.ts +7 -0
- package/dist/ui/tooltip.js +10 -0
- package/package.json +31 -12
- package/AGENTS.md +0 -59
- package/CHANGELOG.md +0 -203
- package/CLAUDE.md +0 -1
- package/src/__tests__/no-spaces-imports.test.ts +0 -59
- package/src/__tests__/open-core-guards.test.ts +0 -307
- package/src/__tests__/theme-runtime.test.ts +0 -81
- package/src/__tests__/tool-fallback.test.tsx +0 -109
- package/src/components/__tests__/context-bar.test.ts +0 -112
- package/src/components/ag-ui-runtime-provider.tsx +0 -170
- package/src/components/app-brand.tsx +0 -38
- package/src/components/assistant-chat.tsx +0 -461
- package/src/components/chat-attachments.tsx +0 -68
- package/src/components/chat-bubble.tsx +0 -373
- package/src/components/chat-header.tsx +0 -44
- package/src/components/client-tool-executor.tsx +0 -230
- package/src/components/collection-empty-state.tsx +0 -37
- package/src/components/collection-filter-bar.tsx +0 -168
- package/src/components/collection-search-input.tsx +0 -41
- package/src/components/collection-skeleton.tsx +0 -55
- package/src/components/collection-sort-menu.tsx +0 -62
- package/src/components/collection-surface.tsx +0 -46
- package/src/components/collection-toolbar.tsx +0 -33
- package/src/components/collection-view-toggle.tsx +0 -61
- package/src/components/composer-submit-bridge.tsx +0 -19
- package/src/components/confirm-dialog.tsx +0 -49
- package/src/components/confirmation-card.tsx +0 -32
- package/src/components/context-badges.tsx +0 -136
- package/src/components/context-bar.tsx +0 -238
- package/src/components/form-dialog.tsx +0 -56
- package/src/components/global-selection-popover.tsx +0 -266
- package/src/components/infinite-scroll-sentinel.tsx +0 -48
- package/src/components/json-viewer.tsx +0 -232
- package/src/components/loading-indicator.tsx +0 -40
- package/src/components/markdown-text-citations.test.tsx +0 -108
- package/src/components/markdown-text.tsx +0 -508
- package/src/components/name-dialog.tsx +0 -87
- package/src/components/selection-popover.tsx +0 -156
- package/src/components/show-document-tool-ui.tsx +0 -90
- package/src/components/sidebar.test.tsx +0 -611
- package/src/components/sidebar.tsx +0 -1689
- package/src/components/surface-card.tsx +0 -45
- package/src/components/theme-runtime-provider.tsx +0 -93
- package/src/components/theme-toggle.tsx +0 -27
- package/src/components/tool-call-card.tsx +0 -126
- package/src/components/tool-fallback.tsx +0 -169
- package/src/components/tool-panel-layout.tsx +0 -36
- package/src/components/tool-panel.tsx +0 -233
- package/src/components/tooltip-icon-button.tsx +0 -28
- package/src/components/user-menu.tsx +0 -60
- package/src/index.ts +0 -185
- package/src/lib/__tests__/ag-ui-adapter.test.ts +0 -273
- package/src/lib/__tests__/app-store.test.ts +0 -405
- package/src/lib/__tests__/attachment-adapter.test.ts +0 -48
- package/src/lib/__tests__/chat-bubble-store.test.ts +0 -67
- package/src/lib/__tests__/client-tools.test.ts +0 -124
- package/src/lib/__tests__/dev-store.test.ts +0 -78
- package/src/lib/__tests__/nav-config.test.ts +0 -135
- package/src/lib/__tests__/nav-dnd.test.ts +0 -24
- package/src/lib/__tests__/nav-store.test.ts +0 -59
- package/src/lib/__tests__/selection-context.test.ts +0 -114
- package/src/lib/__tests__/sidebar-store.test.ts +0 -144
- package/src/lib/__tests__/theme-store.test.ts +0 -83
- package/src/lib/__tests__/tool-panel-store.test.ts +0 -61
- package/src/lib/__tests__/use-page-context.test.ts +0 -58
- package/src/lib/ag-ui-adapter.ts +0 -412
- package/src/lib/app-store.ts +0 -361
- package/src/lib/attachment-adapter.ts +0 -92
- package/src/lib/auth-provider.tsx +0 -144
- package/src/lib/chat-bubble-store.ts +0 -46
- package/src/lib/client-tools.ts +0 -293
- package/src/lib/composer-submit-store.ts +0 -32
- package/src/lib/dev-store.ts +0 -69
- package/src/lib/nav-config.ts +0 -329
- package/src/lib/nav-dnd.ts +0 -14
- package/src/lib/nav-store.ts +0 -89
- package/src/lib/selection-context.ts +0 -65
- package/src/lib/sidebar-store.ts +0 -113
- package/src/lib/theme-runtime.ts +0 -660
- package/src/lib/theme-store.ts +0 -67
- package/src/lib/tool-panel-store.ts +0 -121
- package/src/lib/use-new-conversation.test.tsx +0 -168
- package/src/lib/use-new-conversation.ts +0 -64
- package/src/ui/dialog.tsx +0 -109
- package/src/ui/dropdown-menu.tsx +0 -75
- package/src/ui/popover.tsx +0 -34
- package/src/ui/select.tsx +0 -15
- package/src/ui/tooltip.tsx +0 -30
- package/src/vite-env.d.ts +0 -1
- package/tsconfig.json +0 -16
- package/vitest.config.ts +0 -8
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
import { Check, Filter, X } from "lucide-react";
|
|
2
|
-
|
|
3
|
-
import { Button } from "@iloveagents/foundry-web-primitives";
|
|
4
|
-
import { Checkbox } from "@iloveagents/foundry-web-primitives";
|
|
5
|
-
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover.tsx";
|
|
6
|
-
import { cn } from "@iloveagents/foundry-web-primitives";
|
|
7
|
-
|
|
8
|
-
export type CollectionFilterValue = string | string[] | boolean | undefined;
|
|
9
|
-
|
|
10
|
-
export interface CollectionFilterOption {
|
|
11
|
-
value: string;
|
|
12
|
-
label: string;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface CollectionFilterDefinition {
|
|
16
|
-
key: string;
|
|
17
|
-
label: string;
|
|
18
|
-
type: "single" | "multi" | "boolean";
|
|
19
|
-
options?: CollectionFilterOption[];
|
|
20
|
-
trueLabel?: string;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function activeCount(value: CollectionFilterValue, type: CollectionFilterDefinition["type"]) {
|
|
24
|
-
if (type === "boolean") return value ? 1 : 0;
|
|
25
|
-
if (Array.isArray(value)) return value.length;
|
|
26
|
-
return value ? 1 : 0;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function CollectionFilterBar({
|
|
30
|
-
filters,
|
|
31
|
-
values,
|
|
32
|
-
onValueChange,
|
|
33
|
-
onClearAll,
|
|
34
|
-
className,
|
|
35
|
-
}: {
|
|
36
|
-
filters: CollectionFilterDefinition[];
|
|
37
|
-
values: Record<string, CollectionFilterValue>;
|
|
38
|
-
onValueChange: (key: string, value: CollectionFilterValue) => void;
|
|
39
|
-
onClearAll?: () => void;
|
|
40
|
-
className?: string;
|
|
41
|
-
}) {
|
|
42
|
-
const hasActiveFilters = filters.some((filter) => activeCount(values[filter.key], filter.type) > 0);
|
|
43
|
-
|
|
44
|
-
return (
|
|
45
|
-
<div className={cn("flex flex-wrap items-center gap-2", className)}>
|
|
46
|
-
{filters.map((filter) => {
|
|
47
|
-
const count = activeCount(values[filter.key], filter.type);
|
|
48
|
-
return (
|
|
49
|
-
<Popover key={filter.key}>
|
|
50
|
-
<PopoverTrigger asChild>
|
|
51
|
-
<Button
|
|
52
|
-
type="button"
|
|
53
|
-
variant="outline"
|
|
54
|
-
size="sm"
|
|
55
|
-
className={cn(
|
|
56
|
-
"rounded-xl border-border/45 bg-background/65 shadow-none hover:bg-muted/26",
|
|
57
|
-
count > 0 && "border-primary/18 bg-primary/7 text-foreground hover:bg-primary/10",
|
|
58
|
-
)}
|
|
59
|
-
>
|
|
60
|
-
<Filter className="size-4" />
|
|
61
|
-
<span>{filter.label}</span>
|
|
62
|
-
{count > 0 ? (
|
|
63
|
-
<span className="rounded-full bg-primary/10 px-1.5 py-0.5 text-[11px] font-semibold text-primary">
|
|
64
|
-
{count}
|
|
65
|
-
</span>
|
|
66
|
-
) : null}
|
|
67
|
-
</Button>
|
|
68
|
-
</PopoverTrigger>
|
|
69
|
-
<PopoverContent align="start" className="w-64 rounded-2xl border-border/45 bg-popover/95 p-2 shadow-lg">
|
|
70
|
-
<div className="px-2 pb-2 pt-1 text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground">
|
|
71
|
-
{filter.label}
|
|
72
|
-
</div>
|
|
73
|
-
{filter.type === "boolean" ? (
|
|
74
|
-
<button
|
|
75
|
-
type="button"
|
|
76
|
-
onClick={() => onValueChange(filter.key, values[filter.key] ? undefined : true)}
|
|
77
|
-
className={cn(
|
|
78
|
-
"flex w-full items-center gap-3 rounded-xl px-3 py-2 text-left text-sm transition-colors",
|
|
79
|
-
values[filter.key] ? "bg-primary/8 text-foreground" : "hover:bg-accent",
|
|
80
|
-
)}
|
|
81
|
-
>
|
|
82
|
-
<Checkbox checked={Boolean(values[filter.key])} />
|
|
83
|
-
<span>{filter.trueLabel ?? `Only ${filter.label.toLowerCase()}`}</span>
|
|
84
|
-
</button>
|
|
85
|
-
) : null}
|
|
86
|
-
{filter.type === "single" ? (
|
|
87
|
-
<div className="space-y-1">
|
|
88
|
-
<button
|
|
89
|
-
type="button"
|
|
90
|
-
onClick={() => onValueChange(filter.key, undefined)}
|
|
91
|
-
className="flex w-full items-center justify-between rounded-xl px-3 py-2 text-left text-sm transition-colors hover:bg-accent"
|
|
92
|
-
>
|
|
93
|
-
<span>Any</span>
|
|
94
|
-
<Check
|
|
95
|
-
className={cn(
|
|
96
|
-
"size-4 text-primary",
|
|
97
|
-
values[filter.key] == null ? "opacity-100" : "opacity-0",
|
|
98
|
-
)}
|
|
99
|
-
/>
|
|
100
|
-
</button>
|
|
101
|
-
{filter.options?.map((option) => (
|
|
102
|
-
<button
|
|
103
|
-
key={option.value}
|
|
104
|
-
type="button"
|
|
105
|
-
onClick={() => onValueChange(filter.key, option.value)}
|
|
106
|
-
className="flex w-full items-center justify-between rounded-xl px-3 py-2 text-left text-sm transition-colors hover:bg-accent"
|
|
107
|
-
>
|
|
108
|
-
<span>{option.label}</span>
|
|
109
|
-
<Check
|
|
110
|
-
className={cn(
|
|
111
|
-
"size-4 text-primary",
|
|
112
|
-
values[filter.key] === option.value ? "opacity-100" : "opacity-0",
|
|
113
|
-
)}
|
|
114
|
-
/>
|
|
115
|
-
</button>
|
|
116
|
-
))}
|
|
117
|
-
</div>
|
|
118
|
-
) : null}
|
|
119
|
-
{filter.type === "multi" ? (
|
|
120
|
-
<div className="space-y-1">
|
|
121
|
-
{filter.options?.map((option) => {
|
|
122
|
-
const current = Array.isArray(values[filter.key])
|
|
123
|
-
? (values[filter.key] as string[])
|
|
124
|
-
: [];
|
|
125
|
-
const checked = current.includes(option.value);
|
|
126
|
-
return (
|
|
127
|
-
<button
|
|
128
|
-
key={option.value}
|
|
129
|
-
type="button"
|
|
130
|
-
onClick={() =>
|
|
131
|
-
onValueChange(
|
|
132
|
-
filter.key,
|
|
133
|
-
checked
|
|
134
|
-
? current.filter((item: string) => item !== option.value)
|
|
135
|
-
: [...current, option.value],
|
|
136
|
-
)
|
|
137
|
-
}
|
|
138
|
-
className={cn(
|
|
139
|
-
"flex w-full items-center gap-3 rounded-xl px-3 py-2 text-left text-sm transition-colors",
|
|
140
|
-
checked ? "bg-primary/8 text-foreground" : "hover:bg-accent",
|
|
141
|
-
)}
|
|
142
|
-
>
|
|
143
|
-
<Checkbox checked={checked} />
|
|
144
|
-
<span>{option.label}</span>
|
|
145
|
-
</button>
|
|
146
|
-
);
|
|
147
|
-
})}
|
|
148
|
-
</div>
|
|
149
|
-
) : null}
|
|
150
|
-
</PopoverContent>
|
|
151
|
-
</Popover>
|
|
152
|
-
);
|
|
153
|
-
})}
|
|
154
|
-
{hasActiveFilters && onClearAll ? (
|
|
155
|
-
<Button
|
|
156
|
-
type="button"
|
|
157
|
-
variant="ghost"
|
|
158
|
-
size="sm"
|
|
159
|
-
onClick={onClearAll}
|
|
160
|
-
className="rounded-xl text-muted-foreground hover:bg-muted/26"
|
|
161
|
-
>
|
|
162
|
-
<X className="size-4" />
|
|
163
|
-
<span>Clear</span>
|
|
164
|
-
</Button>
|
|
165
|
-
) : null}
|
|
166
|
-
</div>
|
|
167
|
-
);
|
|
168
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { Search, X } from "lucide-react";
|
|
2
|
-
|
|
3
|
-
import { Button } from "@iloveagents/foundry-web-primitives";
|
|
4
|
-
import { Input } from "@iloveagents/foundry-web-primitives";
|
|
5
|
-
import { cn } from "@iloveagents/foundry-web-primitives";
|
|
6
|
-
|
|
7
|
-
export function CollectionSearchInput({
|
|
8
|
-
value,
|
|
9
|
-
onValueChange,
|
|
10
|
-
placeholder = "Search...",
|
|
11
|
-
className,
|
|
12
|
-
}: {
|
|
13
|
-
value: string;
|
|
14
|
-
onValueChange: (value: string) => void;
|
|
15
|
-
placeholder?: string;
|
|
16
|
-
className?: string;
|
|
17
|
-
}) {
|
|
18
|
-
return (
|
|
19
|
-
<div className={cn("relative min-w-[16rem] flex-1", className)}>
|
|
20
|
-
<Search className="pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
|
|
21
|
-
<Input
|
|
22
|
-
value={value}
|
|
23
|
-
onChange={(event) => onValueChange(event.target.value)}
|
|
24
|
-
placeholder={placeholder}
|
|
25
|
-
className="h-10 rounded-xl border-border/45 bg-background/72 pl-9 pr-10 shadow-none hover:bg-background/82 focus:border-primary/20 focus:ring-primary/10"
|
|
26
|
-
/>
|
|
27
|
-
{value ? (
|
|
28
|
-
<Button
|
|
29
|
-
type="button"
|
|
30
|
-
variant="ghost"
|
|
31
|
-
size="icon"
|
|
32
|
-
onClick={() => onValueChange("")}
|
|
33
|
-
className="absolute right-1 top-1/2 size-8 -translate-y-1/2 rounded-lg text-muted-foreground"
|
|
34
|
-
>
|
|
35
|
-
<X className="size-4" />
|
|
36
|
-
<span className="sr-only">Clear search</span>
|
|
37
|
-
</Button>
|
|
38
|
-
) : null}
|
|
39
|
-
</div>
|
|
40
|
-
);
|
|
41
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { cn } from "@iloveagents/foundry-web-primitives";
|
|
2
|
-
|
|
3
|
-
import type { CollectionViewMode } from "./collection-view-toggle.tsx";
|
|
4
|
-
|
|
5
|
-
export function CollectionSkeleton({
|
|
6
|
-
view,
|
|
7
|
-
rows = 8,
|
|
8
|
-
className,
|
|
9
|
-
}: {
|
|
10
|
-
view: CollectionViewMode;
|
|
11
|
-
rows?: number;
|
|
12
|
-
className?: string;
|
|
13
|
-
}) {
|
|
14
|
-
if (view === "table") {
|
|
15
|
-
return (
|
|
16
|
-
<div className={cn("overflow-hidden rounded-[1.5rem] bg-background/65 ring-1 ring-border/35", className)}>
|
|
17
|
-
<div className="grid grid-cols-4 gap-4 border-b border-border/40 bg-muted/28 px-5 py-4">
|
|
18
|
-
{Array.from({ length: 4 }).map((_, index) => (
|
|
19
|
-
<div key={index} className="h-3.5 animate-pulse rounded bg-muted" />
|
|
20
|
-
))}
|
|
21
|
-
</div>
|
|
22
|
-
<div className="divide-y divide-border/35">
|
|
23
|
-
{Array.from({ length: rows }).map((_, index) => (
|
|
24
|
-
<div key={index} className="grid grid-cols-4 gap-4 px-5 py-4">
|
|
25
|
-
{Array.from({ length: 4 }).map((_, cellIndex) => (
|
|
26
|
-
<div key={cellIndex} className="h-4 animate-pulse rounded bg-muted/80" />
|
|
27
|
-
))}
|
|
28
|
-
</div>
|
|
29
|
-
))}
|
|
30
|
-
</div>
|
|
31
|
-
</div>
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return (
|
|
36
|
-
<div
|
|
37
|
-
className={cn(
|
|
38
|
-
view === "tiles"
|
|
39
|
-
? "grid gap-3 [grid-template-columns:repeat(auto-fit,minmax(min(100%,16rem),1fr))]"
|
|
40
|
-
: "grid gap-4 [grid-template-columns:repeat(auto-fit,minmax(min(100%,18rem),1fr))]",
|
|
41
|
-
className,
|
|
42
|
-
)}
|
|
43
|
-
>
|
|
44
|
-
{Array.from({ length: rows }).map((_, index) => (
|
|
45
|
-
<div
|
|
46
|
-
key={index}
|
|
47
|
-
className={cn(
|
|
48
|
-
"animate-pulse rounded-[1.5rem] bg-card/80 ring-1 ring-border/35",
|
|
49
|
-
view === "tiles" ? "h-28" : "h-40",
|
|
50
|
-
)}
|
|
51
|
-
/>
|
|
52
|
-
))}
|
|
53
|
-
</div>
|
|
54
|
-
);
|
|
55
|
-
}
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { ArrowUpDown, Check } from "lucide-react";
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
DropdownMenu,
|
|
5
|
-
DropdownMenuContent,
|
|
6
|
-
DropdownMenuItem,
|
|
7
|
-
DropdownMenuTrigger,
|
|
8
|
-
} from "../ui/dropdown-menu.tsx";
|
|
9
|
-
import { Button } from "@iloveagents/foundry-web-primitives";
|
|
10
|
-
import { cn } from "@iloveagents/foundry-web-primitives";
|
|
11
|
-
|
|
12
|
-
export interface CollectionSortOption {
|
|
13
|
-
value: string;
|
|
14
|
-
label: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function CollectionSortMenu({
|
|
18
|
-
options,
|
|
19
|
-
value,
|
|
20
|
-
onValueChange,
|
|
21
|
-
className,
|
|
22
|
-
}: {
|
|
23
|
-
options: CollectionSortOption[];
|
|
24
|
-
value: string;
|
|
25
|
-
onValueChange: (value: string) => void;
|
|
26
|
-
className?: string;
|
|
27
|
-
}) {
|
|
28
|
-
const active = options.find((option) => option.value === value) ?? options[0];
|
|
29
|
-
|
|
30
|
-
return (
|
|
31
|
-
<DropdownMenu>
|
|
32
|
-
<DropdownMenuTrigger asChild>
|
|
33
|
-
<Button
|
|
34
|
-
type="button"
|
|
35
|
-
variant="outline"
|
|
36
|
-
size="sm"
|
|
37
|
-
className={cn(
|
|
38
|
-
"rounded-xl border-border/45 bg-background/65 shadow-none hover:bg-muted/26",
|
|
39
|
-
className,
|
|
40
|
-
)}
|
|
41
|
-
>
|
|
42
|
-
<ArrowUpDown className="size-4" />
|
|
43
|
-
<span>{active?.label ?? "Sort"}</span>
|
|
44
|
-
</Button>
|
|
45
|
-
</DropdownMenuTrigger>
|
|
46
|
-
<DropdownMenuContent align="end" className="w-56 rounded-xl border-border/45 bg-popover/95 shadow-lg">
|
|
47
|
-
{options.map((option) => (
|
|
48
|
-
<DropdownMenuItem
|
|
49
|
-
key={option.value}
|
|
50
|
-
onClick={() => onValueChange(option.value)}
|
|
51
|
-
className="flex items-center justify-between gap-3"
|
|
52
|
-
>
|
|
53
|
-
<span>{option.label}</span>
|
|
54
|
-
<Check
|
|
55
|
-
className={cn("size-4 text-primary", value === option.value ? "opacity-100" : "opacity-0")}
|
|
56
|
-
/>
|
|
57
|
-
</DropdownMenuItem>
|
|
58
|
-
))}
|
|
59
|
-
</DropdownMenuContent>
|
|
60
|
-
</DropdownMenu>
|
|
61
|
-
);
|
|
62
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import type { ComponentPropsWithoutRef, ReactNode } from "react";
|
|
2
|
-
|
|
3
|
-
import { cn } from "@iloveagents/foundry-web-primitives";
|
|
4
|
-
|
|
5
|
-
export function CollectionSurface({
|
|
6
|
-
toolbar,
|
|
7
|
-
bordered = false,
|
|
8
|
-
backgrounded = true,
|
|
9
|
-
className,
|
|
10
|
-
toolbarClassName,
|
|
11
|
-
contentClassName,
|
|
12
|
-
children,
|
|
13
|
-
...props
|
|
14
|
-
}: ComponentPropsWithoutRef<"section"> & {
|
|
15
|
-
toolbar?: ReactNode;
|
|
16
|
-
bordered?: boolean;
|
|
17
|
-
backgrounded?: boolean;
|
|
18
|
-
toolbarClassName?: string;
|
|
19
|
-
contentClassName?: string;
|
|
20
|
-
}) {
|
|
21
|
-
return (
|
|
22
|
-
<section
|
|
23
|
-
className={cn(
|
|
24
|
-
"w-full min-w-0 overflow-hidden rounded-[1.75rem]",
|
|
25
|
-
backgrounded && "bg-card/60 shadow-[0_12px_36px_-24px_rgb(15_23_42/0.18)] backdrop-blur-sm",
|
|
26
|
-
bordered && "ring-1 ring-border/45",
|
|
27
|
-
className,
|
|
28
|
-
)}
|
|
29
|
-
{...props}
|
|
30
|
-
>
|
|
31
|
-
{toolbar ? (
|
|
32
|
-
<div
|
|
33
|
-
className={cn(
|
|
34
|
-
"sticky top-0 z-10 px-4 py-4 sm:px-5",
|
|
35
|
-
backgrounded && "bg-muted/18 backdrop-blur",
|
|
36
|
-
bordered && "border-b border-border/45",
|
|
37
|
-
toolbarClassName,
|
|
38
|
-
)}
|
|
39
|
-
>
|
|
40
|
-
{toolbar}
|
|
41
|
-
</div>
|
|
42
|
-
) : null}
|
|
43
|
-
<div className={cn("p-4 sm:p-5", contentClassName)}>{children}</div>
|
|
44
|
-
</section>
|
|
45
|
-
);
|
|
46
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import type { ReactNode } from "react";
|
|
2
|
-
|
|
3
|
-
import { cn } from "@iloveagents/foundry-web-primitives";
|
|
4
|
-
|
|
5
|
-
export function CollectionToolbar({
|
|
6
|
-
search,
|
|
7
|
-
filters,
|
|
8
|
-
sort,
|
|
9
|
-
viewToggle,
|
|
10
|
-
actions,
|
|
11
|
-
className,
|
|
12
|
-
}: {
|
|
13
|
-
search?: ReactNode;
|
|
14
|
-
filters?: ReactNode;
|
|
15
|
-
sort?: ReactNode;
|
|
16
|
-
viewToggle?: ReactNode;
|
|
17
|
-
actions?: ReactNode;
|
|
18
|
-
className?: string;
|
|
19
|
-
}) {
|
|
20
|
-
return (
|
|
21
|
-
<div className={cn("flex flex-col gap-2.5", className)}>
|
|
22
|
-
<div className="flex flex-col gap-2.5 lg:flex-row lg:items-center">
|
|
23
|
-
<div className="flex min-w-0 flex-1 items-center gap-3">{search}</div>
|
|
24
|
-
<div className="flex flex-wrap items-center gap-2">
|
|
25
|
-
{sort}
|
|
26
|
-
{viewToggle}
|
|
27
|
-
{actions}
|
|
28
|
-
</div>
|
|
29
|
-
</div>
|
|
30
|
-
{filters ? <div className="flex flex-wrap items-center gap-2">{filters}</div> : null}
|
|
31
|
-
</div>
|
|
32
|
-
);
|
|
33
|
-
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { LayoutGrid, Rows3, TableProperties } from "lucide-react";
|
|
2
|
-
|
|
3
|
-
import { Button } from "@iloveagents/foundry-web-primitives";
|
|
4
|
-
import { cn } from "@iloveagents/foundry-web-primitives";
|
|
5
|
-
|
|
6
|
-
export type CollectionViewMode = "table" | "grid" | "tiles";
|
|
7
|
-
|
|
8
|
-
const VIEW_OPTIONS: Array<{
|
|
9
|
-
value: CollectionViewMode;
|
|
10
|
-
label: string;
|
|
11
|
-
icon: typeof TableProperties;
|
|
12
|
-
}> = [
|
|
13
|
-
{ value: "table", label: "Table", icon: TableProperties },
|
|
14
|
-
{ value: "grid", label: "Grid", icon: LayoutGrid },
|
|
15
|
-
{ value: "tiles", label: "Tiles", icon: Rows3 },
|
|
16
|
-
];
|
|
17
|
-
|
|
18
|
-
export function CollectionViewToggle({
|
|
19
|
-
value,
|
|
20
|
-
onValueChange,
|
|
21
|
-
views = ["table", "grid"],
|
|
22
|
-
className,
|
|
23
|
-
}: {
|
|
24
|
-
value: CollectionViewMode;
|
|
25
|
-
onValueChange: (value: CollectionViewMode) => void;
|
|
26
|
-
views?: CollectionViewMode[];
|
|
27
|
-
className?: string;
|
|
28
|
-
}) {
|
|
29
|
-
return (
|
|
30
|
-
<div
|
|
31
|
-
className={cn(
|
|
32
|
-
"inline-flex items-center rounded-xl bg-muted/26 p-1 ring-1 ring-border/40",
|
|
33
|
-
className,
|
|
34
|
-
)}
|
|
35
|
-
>
|
|
36
|
-
{VIEW_OPTIONS.filter((option) => views.includes(option.value)).map((option) => {
|
|
37
|
-
const Icon = option.icon;
|
|
38
|
-
const active = value === option.value;
|
|
39
|
-
return (
|
|
40
|
-
<Button
|
|
41
|
-
key={option.value}
|
|
42
|
-
type="button"
|
|
43
|
-
aria-label={option.label}
|
|
44
|
-
variant={active ? "secondary" : "ghost"}
|
|
45
|
-
size="sm"
|
|
46
|
-
onClick={() => onValueChange(option.value)}
|
|
47
|
-
className={cn(
|
|
48
|
-
"rounded-lg px-2.5 text-muted-foreground hover:bg-background/70 hover:text-foreground",
|
|
49
|
-
active &&
|
|
50
|
-
"bg-background text-foreground ring-1 ring-primary/35 shadow-[0_1px_2px_rgb(15_23_42/0.08)] hover:bg-background",
|
|
51
|
-
)}
|
|
52
|
-
>
|
|
53
|
-
<Icon className="size-4" />
|
|
54
|
-
<span className="hidden sm:inline">{option.label}</span>
|
|
55
|
-
<span className="sr-only sm:hidden">{option.label}</span>
|
|
56
|
-
</Button>
|
|
57
|
-
);
|
|
58
|
-
})}
|
|
59
|
-
</div>
|
|
60
|
-
);
|
|
61
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { useEffect } from "react";
|
|
2
|
-
import { useComposerRuntime } from "@assistant-ui/react";
|
|
3
|
-
import { useComposerSubmitStore } from "../lib/composer-submit-store.ts";
|
|
4
|
-
|
|
5
|
-
export function ComposerSubmitBridge() {
|
|
6
|
-
const composerRuntime = useComposerRuntime();
|
|
7
|
-
const pending = useComposerSubmitStore((s) => s.pending);
|
|
8
|
-
|
|
9
|
-
useEffect(() => {
|
|
10
|
-
if (!pending) return;
|
|
11
|
-
|
|
12
|
-
composerRuntime.setText(pending.text);
|
|
13
|
-
composerRuntime.send({ startRun: true });
|
|
14
|
-
useComposerSubmitStore.getState().consume(pending.id);
|
|
15
|
-
}, [composerRuntime, pending]);
|
|
16
|
-
|
|
17
|
-
return null;
|
|
18
|
-
}
|
|
19
|
-
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { Button } from "@iloveagents/foundry-web-primitives";
|
|
2
|
-
import { FormDialog } from "./form-dialog.tsx";
|
|
3
|
-
|
|
4
|
-
export function ConfirmDialog({
|
|
5
|
-
open,
|
|
6
|
-
onOpenChange,
|
|
7
|
-
title,
|
|
8
|
-
description,
|
|
9
|
-
confirmLabel = "Confirm",
|
|
10
|
-
cancelLabel = "Cancel",
|
|
11
|
-
destructive = false,
|
|
12
|
-
onConfirm,
|
|
13
|
-
confirming = false,
|
|
14
|
-
}: {
|
|
15
|
-
open: boolean;
|
|
16
|
-
onOpenChange: (open: boolean) => void;
|
|
17
|
-
title: string;
|
|
18
|
-
description?: string;
|
|
19
|
-
confirmLabel?: string;
|
|
20
|
-
cancelLabel?: string;
|
|
21
|
-
destructive?: boolean;
|
|
22
|
-
onConfirm: () => void;
|
|
23
|
-
confirming?: boolean;
|
|
24
|
-
}) {
|
|
25
|
-
return (
|
|
26
|
-
<FormDialog
|
|
27
|
-
open={open}
|
|
28
|
-
onOpenChange={onOpenChange}
|
|
29
|
-
title={title}
|
|
30
|
-
description={description}
|
|
31
|
-
size="sm"
|
|
32
|
-
footer={
|
|
33
|
-
<>
|
|
34
|
-
<Button type="button" variant="ghost" onClick={() => onOpenChange(false)}>
|
|
35
|
-
{cancelLabel}
|
|
36
|
-
</Button>
|
|
37
|
-
<Button
|
|
38
|
-
type="button"
|
|
39
|
-
variant={destructive ? "destructive" : "default"}
|
|
40
|
-
onClick={onConfirm}
|
|
41
|
-
disabled={confirming}
|
|
42
|
-
>
|
|
43
|
-
{confirmLabel}
|
|
44
|
-
</Button>
|
|
45
|
-
</>
|
|
46
|
-
}
|
|
47
|
-
/>
|
|
48
|
-
);
|
|
49
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Confirmation Card — informational UI for the ui_confirm tool.
|
|
3
|
-
*
|
|
4
|
-
* Renders a card with action description and optional details.
|
|
5
|
-
* The user responds by typing their confirmation in the chat.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { ShieldCheck } from "lucide-react";
|
|
9
|
-
import { ToolCallCard, type ToolCallStatus } from "./tool-call-card.tsx";
|
|
10
|
-
|
|
11
|
-
interface ConfirmationCardProps {
|
|
12
|
-
action: string;
|
|
13
|
-
details?: string;
|
|
14
|
-
status: ToolCallStatus;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function ConfirmationCard({ action, details, status }: ConfirmationCardProps) {
|
|
18
|
-
return (
|
|
19
|
-
<ToolCallCard
|
|
20
|
-
icon={<ShieldCheck className="size-3.5" />}
|
|
21
|
-
title="Confirmation Required"
|
|
22
|
-
description={action}
|
|
23
|
-
status={status}
|
|
24
|
-
className="w-full"
|
|
25
|
-
>
|
|
26
|
-
{details && <p className="text-xs text-muted-foreground mt-1">{details}</p>}
|
|
27
|
-
<p className="text-xs text-muted-foreground mt-2 italic">
|
|
28
|
-
Reply to confirm or reject this action.
|
|
29
|
-
</p>
|
|
30
|
-
</ToolCallCard>
|
|
31
|
-
);
|
|
32
|
-
}
|