@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.
Files changed (223) hide show
  1. package/README.md +14 -5
  2. package/dist/components/ag-ui-runtime-provider.d.ts +64 -0
  3. package/dist/components/ag-ui-runtime-provider.js +71 -0
  4. package/dist/components/app-brand.d.ts +6 -0
  5. package/dist/components/app-brand.js +13 -0
  6. package/dist/components/assistant-chat.d.ts +26 -0
  7. package/dist/components/assistant-chat.js +93 -0
  8. package/dist/components/chat-attachments.d.ts +25 -0
  9. package/dist/components/chat-attachments.js +20 -0
  10. package/dist/components/chat-bubble.d.ts +1 -0
  11. package/dist/components/chat-bubble.js +103 -0
  12. package/dist/components/chat-header.d.ts +2 -0
  13. package/dist/components/chat-header.js +16 -0
  14. package/dist/components/client-tool-executor.d.ts +12 -0
  15. package/dist/components/client-tool-executor.js +108 -0
  16. package/dist/components/collection-empty-state.d.ts +9 -0
  17. package/dist/components/collection-empty-state.js +6 -0
  18. package/dist/components/collection-filter-bar.d.ts +19 -0
  19. package/dist/components/collection-filter-bar.js +28 -0
  20. package/dist/components/collection-search-input.d.ts +6 -0
  21. package/dist/components/collection-search-input.js +8 -0
  22. package/dist/components/collection-skeleton.d.ts +6 -0
  23. package/dist/components/collection-skeleton.js +10 -0
  24. package/dist/components/collection-sort-menu.d.ts +10 -0
  25. package/dist/components/collection-sort-menu.js +9 -0
  26. package/dist/components/collection-surface.d.ts +8 -0
  27. package/dist/components/collection-surface.js +5 -0
  28. package/dist/components/collection-toolbar.d.ts +9 -0
  29. package/dist/components/collection-toolbar.js +5 -0
  30. package/dist/components/collection-view-toggle.d.ts +7 -0
  31. package/dist/components/collection-view-toggle.js +17 -0
  32. package/dist/components/composer-submit-bridge.d.ts +1 -0
  33. package/dist/components/composer-submit-bridge.js +15 -0
  34. package/dist/components/confirm-dialog.d.ts +11 -0
  35. package/dist/components/confirm-dialog.js +6 -0
  36. package/dist/components/confirmation-card.d.ts +14 -0
  37. package/dist/components/confirmation-card.js +12 -0
  38. package/dist/components/context-badges.d.ts +16 -0
  39. package/dist/components/context-badges.js +56 -0
  40. package/dist/components/context-bar.d.ts +41 -0
  41. package/dist/components/context-bar.js +123 -0
  42. package/dist/components/form-dialog.d.ts +12 -0
  43. package/dist/components/form-dialog.js +13 -0
  44. package/dist/components/global-selection-popover.d.ts +7 -0
  45. package/dist/components/global-selection-popover.js +167 -0
  46. package/dist/components/infinite-scroll-sentinel.d.ts +6 -0
  47. package/dist/components/infinite-scroll-sentinel.js +25 -0
  48. package/dist/components/json-viewer.d.ts +10 -0
  49. package/dist/components/json-viewer.js +80 -0
  50. package/dist/components/loading-indicator.d.ts +4 -0
  51. package/dist/components/loading-indicator.js +22 -0
  52. package/dist/components/markdown-text.d.ts +13 -0
  53. package/dist/components/markdown-text.js +221 -0
  54. package/dist/components/name-dialog.d.ts +16 -0
  55. package/dist/components/name-dialog.js +23 -0
  56. package/dist/components/selection-popover.d.ts +12 -0
  57. package/dist/components/selection-popover.js +111 -0
  58. package/dist/components/show-document-tool-ui.d.ts +1 -0
  59. package/dist/components/show-document-tool-ui.js +53 -0
  60. package/dist/components/sidebar.d.ts +4 -0
  61. package/dist/components/sidebar.js +904 -0
  62. package/dist/components/surface-card.d.ts +9 -0
  63. package/dist/components/surface-card.js +33 -0
  64. package/dist/components/theme-runtime-provider.d.ts +15 -0
  65. package/dist/components/theme-runtime-provider.js +48 -0
  66. package/dist/components/theme-toggle.d.ts +2 -0
  67. package/dist/components/theme-toggle.js +19 -0
  68. package/dist/components/tool-call-card.d.ts +27 -0
  69. package/dist/components/tool-call-card.js +13 -0
  70. package/dist/components/tool-fallback.d.ts +26 -0
  71. package/dist/components/tool-fallback.js +129 -0
  72. package/dist/components/tool-panel-layout.d.ts +10 -0
  73. package/dist/components/tool-panel-layout.js +12 -0
  74. package/dist/components/tool-panel.d.ts +1 -0
  75. package/dist/components/tool-panel.js +89 -0
  76. package/dist/components/tooltip-icon-button.d.ts +7 -0
  77. package/dist/components/tooltip-icon-button.js +9 -0
  78. package/dist/components/user-menu.d.ts +2 -0
  79. package/dist/components/user-menu.js +14 -0
  80. package/dist/index.d.ts +68 -0
  81. package/dist/index.js +83 -0
  82. package/dist/lib/ag-ui-adapter.d.ts +29 -0
  83. package/dist/lib/ag-ui-adapter.js +373 -0
  84. package/dist/lib/app-store.d.ts +115 -0
  85. package/dist/lib/app-store.js +199 -0
  86. package/dist/lib/attachment-adapter.d.ts +20 -0
  87. package/dist/lib/attachment-adapter.js +99 -0
  88. package/dist/lib/auth-provider.d.ts +16 -0
  89. package/dist/lib/auth-provider.js +88 -0
  90. package/dist/lib/chat-bubble-store.d.ts +30 -0
  91. package/dist/lib/chat-bubble-store.js +23 -0
  92. package/dist/lib/chat-lifecycle-store.d.ts +10 -0
  93. package/{src/lib/chat-lifecycle-store.ts → dist/lib/chat-lifecycle-store.js} +3 -13
  94. package/dist/lib/client-tools.d.ts +11 -0
  95. package/dist/lib/client-tools.js +274 -0
  96. package/dist/lib/composer-submit-store.d.ts +12 -0
  97. package/dist/lib/composer-submit-store.js +17 -0
  98. package/dist/lib/dev-store.d.ts +38 -0
  99. package/dist/lib/dev-store.js +32 -0
  100. package/dist/lib/nav-config.d.ts +159 -0
  101. package/dist/lib/nav-config.js +162 -0
  102. package/dist/lib/nav-dnd.d.ts +8 -0
  103. package/dist/lib/nav-dnd.js +9 -0
  104. package/dist/lib/nav-store.d.ts +45 -0
  105. package/dist/lib/nav-store.js +49 -0
  106. package/dist/lib/selection-context.d.ts +21 -0
  107. package/dist/lib/selection-context.js +34 -0
  108. package/dist/lib/sidebar-store.d.ts +23 -0
  109. package/dist/lib/sidebar-store.js +98 -0
  110. package/dist/lib/theme-runtime.d.ts +130 -0
  111. package/dist/lib/theme-runtime.js +479 -0
  112. package/dist/lib/theme-store.d.ts +15 -0
  113. package/dist/lib/theme-store.js +53 -0
  114. package/dist/lib/tool-panel-store.d.ts +48 -0
  115. package/dist/lib/tool-panel-store.js +69 -0
  116. package/dist/lib/use-new-conversation.d.ts +8 -0
  117. package/dist/lib/use-new-conversation.js +62 -0
  118. package/dist/lib/use-page-tools.d.ts +27 -0
  119. package/{src/lib/use-page-tools.ts → dist/lib/use-page-tools.js} +11 -13
  120. package/dist/styles.css +142 -0
  121. package/dist/ui/collapsible.d.ts +5 -0
  122. package/{src/ui/collapsible.tsx → dist/ui/collapsible.js} +0 -2
  123. package/dist/ui/dialog.d.ts +15 -0
  124. package/dist/ui/dialog.js +25 -0
  125. package/dist/ui/dropdown-menu.d.ts +7 -0
  126. package/dist/ui/dropdown-menu.js +19 -0
  127. package/dist/ui/popover.d.ts +7 -0
  128. package/dist/ui/popover.js +10 -0
  129. package/dist/ui/select.d.ts +4 -0
  130. package/dist/ui/select.js +9 -0
  131. package/dist/ui/tooltip.d.ts +7 -0
  132. package/dist/ui/tooltip.js +10 -0
  133. package/package.json +31 -12
  134. package/AGENTS.md +0 -59
  135. package/CHANGELOG.md +0 -203
  136. package/CLAUDE.md +0 -1
  137. package/src/__tests__/no-spaces-imports.test.ts +0 -59
  138. package/src/__tests__/open-core-guards.test.ts +0 -307
  139. package/src/__tests__/theme-runtime.test.ts +0 -81
  140. package/src/__tests__/tool-fallback.test.tsx +0 -109
  141. package/src/components/__tests__/context-bar.test.ts +0 -112
  142. package/src/components/ag-ui-runtime-provider.tsx +0 -170
  143. package/src/components/app-brand.tsx +0 -38
  144. package/src/components/assistant-chat.tsx +0 -461
  145. package/src/components/chat-attachments.tsx +0 -68
  146. package/src/components/chat-bubble.tsx +0 -373
  147. package/src/components/chat-header.tsx +0 -44
  148. package/src/components/client-tool-executor.tsx +0 -230
  149. package/src/components/collection-empty-state.tsx +0 -37
  150. package/src/components/collection-filter-bar.tsx +0 -168
  151. package/src/components/collection-search-input.tsx +0 -41
  152. package/src/components/collection-skeleton.tsx +0 -55
  153. package/src/components/collection-sort-menu.tsx +0 -62
  154. package/src/components/collection-surface.tsx +0 -46
  155. package/src/components/collection-toolbar.tsx +0 -33
  156. package/src/components/collection-view-toggle.tsx +0 -61
  157. package/src/components/composer-submit-bridge.tsx +0 -19
  158. package/src/components/confirm-dialog.tsx +0 -49
  159. package/src/components/confirmation-card.tsx +0 -32
  160. package/src/components/context-badges.tsx +0 -136
  161. package/src/components/context-bar.tsx +0 -238
  162. package/src/components/form-dialog.tsx +0 -56
  163. package/src/components/global-selection-popover.tsx +0 -266
  164. package/src/components/infinite-scroll-sentinel.tsx +0 -48
  165. package/src/components/json-viewer.tsx +0 -232
  166. package/src/components/loading-indicator.tsx +0 -40
  167. package/src/components/markdown-text-citations.test.tsx +0 -108
  168. package/src/components/markdown-text.tsx +0 -508
  169. package/src/components/name-dialog.tsx +0 -87
  170. package/src/components/selection-popover.tsx +0 -156
  171. package/src/components/show-document-tool-ui.tsx +0 -90
  172. package/src/components/sidebar.test.tsx +0 -611
  173. package/src/components/sidebar.tsx +0 -1689
  174. package/src/components/surface-card.tsx +0 -45
  175. package/src/components/theme-runtime-provider.tsx +0 -93
  176. package/src/components/theme-toggle.tsx +0 -27
  177. package/src/components/tool-call-card.tsx +0 -126
  178. package/src/components/tool-fallback.tsx +0 -169
  179. package/src/components/tool-panel-layout.tsx +0 -36
  180. package/src/components/tool-panel.tsx +0 -233
  181. package/src/components/tooltip-icon-button.tsx +0 -28
  182. package/src/components/user-menu.tsx +0 -60
  183. package/src/index.ts +0 -185
  184. package/src/lib/__tests__/ag-ui-adapter.test.ts +0 -273
  185. package/src/lib/__tests__/app-store.test.ts +0 -405
  186. package/src/lib/__tests__/attachment-adapter.test.ts +0 -48
  187. package/src/lib/__tests__/chat-bubble-store.test.ts +0 -67
  188. package/src/lib/__tests__/client-tools.test.ts +0 -124
  189. package/src/lib/__tests__/dev-store.test.ts +0 -78
  190. package/src/lib/__tests__/nav-config.test.ts +0 -135
  191. package/src/lib/__tests__/nav-dnd.test.ts +0 -24
  192. package/src/lib/__tests__/nav-store.test.ts +0 -59
  193. package/src/lib/__tests__/selection-context.test.ts +0 -114
  194. package/src/lib/__tests__/sidebar-store.test.ts +0 -144
  195. package/src/lib/__tests__/theme-store.test.ts +0 -83
  196. package/src/lib/__tests__/tool-panel-store.test.ts +0 -61
  197. package/src/lib/__tests__/use-page-context.test.ts +0 -58
  198. package/src/lib/ag-ui-adapter.ts +0 -412
  199. package/src/lib/app-store.ts +0 -361
  200. package/src/lib/attachment-adapter.ts +0 -92
  201. package/src/lib/auth-provider.tsx +0 -144
  202. package/src/lib/chat-bubble-store.ts +0 -46
  203. package/src/lib/client-tools.ts +0 -293
  204. package/src/lib/composer-submit-store.ts +0 -32
  205. package/src/lib/dev-store.ts +0 -69
  206. package/src/lib/nav-config.ts +0 -329
  207. package/src/lib/nav-dnd.ts +0 -14
  208. package/src/lib/nav-store.ts +0 -89
  209. package/src/lib/selection-context.ts +0 -65
  210. package/src/lib/sidebar-store.ts +0 -113
  211. package/src/lib/theme-runtime.ts +0 -660
  212. package/src/lib/theme-store.ts +0 -67
  213. package/src/lib/tool-panel-store.ts +0 -121
  214. package/src/lib/use-new-conversation.test.tsx +0 -168
  215. package/src/lib/use-new-conversation.ts +0 -64
  216. package/src/ui/dialog.tsx +0 -109
  217. package/src/ui/dropdown-menu.tsx +0 -75
  218. package/src/ui/popover.tsx +0 -34
  219. package/src/ui/select.tsx +0 -15
  220. package/src/ui/tooltip.tsx +0 -30
  221. package/src/vite-env.d.ts +0 -1
  222. package/tsconfig.json +0 -16
  223. 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
- }