@dowel-ui/react 0.1.1 → 0.3.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 (142) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +193 -0
  3. package/dist/components/ai-action-ledger/ai-action-ledger.d.ts +77 -0
  4. package/dist/components/ai-action-ledger/ai-action-ledger.d.ts.map +1 -0
  5. package/dist/components/ai-action-ledger/ai-action-ledger.js +224 -0
  6. package/dist/components/ai-action-ledger/ai-action-ledger.js.map +1 -0
  7. package/dist/components/ai-action-ledger/index.d.ts +2 -0
  8. package/dist/components/ai-action-ledger/index.js +2 -0
  9. package/dist/components/ai-action-ledger/meta.js +17 -0
  10. package/dist/components/ai-action-ledger/meta.js.map +1 -0
  11. package/dist/components/ai-agent-plan/ai-agent-plan.d.ts +50 -0
  12. package/dist/components/ai-agent-plan/ai-agent-plan.d.ts.map +1 -0
  13. package/dist/components/ai-agent-plan/ai-agent-plan.js +156 -0
  14. package/dist/components/ai-agent-plan/ai-agent-plan.js.map +1 -0
  15. package/dist/components/ai-agent-plan/index.d.ts +2 -0
  16. package/dist/components/ai-agent-plan/index.js +2 -0
  17. package/dist/components/ai-agent-plan/meta.js +17 -0
  18. package/dist/components/ai-agent-plan/meta.js.map +1 -0
  19. package/dist/components/ai-agent-status/ai-agent-status.d.ts +1 -1
  20. package/dist/components/ai-approval-request/ai-approval-request.d.ts +67 -0
  21. package/dist/components/ai-approval-request/ai-approval-request.d.ts.map +1 -0
  22. package/dist/components/ai-approval-request/ai-approval-request.js +218 -0
  23. package/dist/components/ai-approval-request/ai-approval-request.js.map +1 -0
  24. package/dist/components/ai-approval-request/index.d.ts +2 -0
  25. package/dist/components/ai-approval-request/index.js +2 -0
  26. package/dist/components/ai-approval-request/meta.js +17 -0
  27. package/dist/components/ai-approval-request/meta.js.map +1 -0
  28. package/dist/components/ai-inline-completion/ai-inline-completion.d.ts +45 -0
  29. package/dist/components/ai-inline-completion/ai-inline-completion.d.ts.map +1 -0
  30. package/dist/components/ai-inline-completion/ai-inline-completion.js +110 -0
  31. package/dist/components/ai-inline-completion/ai-inline-completion.js.map +1 -0
  32. package/dist/components/ai-inline-completion/index.d.ts +2 -0
  33. package/dist/components/ai-inline-completion/index.js +2 -0
  34. package/dist/components/ai-inline-completion/meta.js +17 -0
  35. package/dist/components/ai-inline-completion/meta.js.map +1 -0
  36. package/dist/components/ai-response/ai-response.d.ts.map +1 -1
  37. package/dist/components/ai-response/ai-response.js +1 -0
  38. package/dist/components/ai-response/ai-response.js.map +1 -1
  39. package/dist/components/ai-structured-output/ai-structured-output.d.ts +75 -0
  40. package/dist/components/ai-structured-output/ai-structured-output.d.ts.map +1 -0
  41. package/dist/components/ai-structured-output/ai-structured-output.js +137 -0
  42. package/dist/components/ai-structured-output/ai-structured-output.js.map +1 -0
  43. package/dist/components/ai-structured-output/index.d.ts +2 -0
  44. package/dist/components/ai-structured-output/index.js +2 -0
  45. package/dist/components/ai-structured-output/meta.js +17 -0
  46. package/dist/components/ai-structured-output/meta.js.map +1 -0
  47. package/dist/components/ai-tool/ai-tool.d.ts +1 -1
  48. package/dist/components/alert/alert.d.ts +1 -1
  49. package/dist/components/badge/badge.d.ts +1 -1
  50. package/dist/components/button/button.d.ts +1 -1
  51. package/dist/components/file-upload/file-upload.d.ts +46 -0
  52. package/dist/components/file-upload/file-upload.d.ts.map +1 -0
  53. package/dist/components/file-upload/file-upload.js +204 -0
  54. package/dist/components/file-upload/file-upload.js.map +1 -0
  55. package/dist/components/file-upload/index.d.ts +3 -0
  56. package/dist/components/file-upload/index.js +3 -0
  57. package/dist/components/file-upload/meta.js +17 -0
  58. package/dist/components/file-upload/meta.js.map +1 -0
  59. package/dist/components/file-upload/upload-queue.d.ts +87 -0
  60. package/dist/components/file-upload/upload-queue.d.ts.map +1 -0
  61. package/dist/components/file-upload/upload-queue.js +249 -0
  62. package/dist/components/file-upload/upload-queue.js.map +1 -0
  63. package/dist/components/meter/index.d.ts +2 -0
  64. package/dist/components/meter/index.js +2 -0
  65. package/dist/components/meter/meta.js +17 -0
  66. package/dist/components/meter/meta.js.map +1 -0
  67. package/dist/components/meter/meter.d.ts +69 -0
  68. package/dist/components/meter/meter.d.ts.map +1 -0
  69. package/dist/components/meter/meter.js +144 -0
  70. package/dist/components/meter/meter.js.map +1 -0
  71. package/dist/components/metric-delta/index.d.ts +2 -0
  72. package/dist/components/metric-delta/index.js +2 -0
  73. package/dist/components/metric-delta/meta.js +17 -0
  74. package/dist/components/metric-delta/meta.js.map +1 -0
  75. package/dist/components/metric-delta/metric-delta.d.ts +59 -0
  76. package/dist/components/metric-delta/metric-delta.d.ts.map +1 -0
  77. package/dist/components/metric-delta/metric-delta.js +82 -0
  78. package/dist/components/metric-delta/metric-delta.js.map +1 -0
  79. package/dist/components/progress/progress.d.ts +1 -1
  80. package/dist/components/progress/progress.js +1 -0
  81. package/dist/components/progress/progress.js.map +1 -1
  82. package/dist/components/record-diff/index.d.ts +2 -0
  83. package/dist/components/record-diff/index.js +2 -0
  84. package/dist/components/record-diff/meta.js +17 -0
  85. package/dist/components/record-diff/meta.js.map +1 -0
  86. package/dist/components/record-diff/record-diff.d.ts +56 -0
  87. package/dist/components/record-diff/record-diff.d.ts.map +1 -0
  88. package/dist/components/record-diff/record-diff.js +199 -0
  89. package/dist/components/record-diff/record-diff.js.map +1 -0
  90. package/dist/components/spinner/spinner.js +1 -0
  91. package/dist/components/spinner/spinner.js.map +1 -1
  92. package/dist/components/tags-input/index.d.ts +2 -0
  93. package/dist/components/tags-input/index.js +2 -0
  94. package/dist/components/tags-input/meta.js +17 -0
  95. package/dist/components/tags-input/meta.js.map +1 -0
  96. package/dist/components/tags-input/tags-input.d.ts +47 -0
  97. package/dist/components/tags-input/tags-input.d.ts.map +1 -0
  98. package/dist/components/tags-input/tags-input.js +182 -0
  99. package/dist/components/tags-input/tags-input.js.map +1 -0
  100. package/dist/components/toast/toast.d.ts +1 -1
  101. package/dist/index.d.ts +22 -1
  102. package/dist/index.js +12 -1
  103. package/dist/registry/components.d.ts.map +1 -1
  104. package/dist/registry/components.js +65 -45
  105. package/dist/registry/components.js.map +1 -1
  106. package/package.json +36 -4
  107. package/src/components/ai-action-ledger/ai-action-ledger.tsx +381 -0
  108. package/src/components/ai-action-ledger/index.ts +14 -0
  109. package/src/components/ai-action-ledger/meta.ts +19 -0
  110. package/src/components/ai-agent-plan/ai-agent-plan.tsx +0 -0
  111. package/src/components/ai-agent-plan/index.ts +10 -0
  112. package/src/components/ai-agent-plan/meta.ts +19 -0
  113. package/src/components/ai-approval-request/ai-approval-request.tsx +368 -0
  114. package/src/components/ai-approval-request/index.ts +7 -0
  115. package/src/components/ai-approval-request/meta.ts +21 -0
  116. package/src/components/ai-inline-completion/ai-inline-completion.tsx +214 -0
  117. package/src/components/ai-inline-completion/index.ts +1 -0
  118. package/src/components/ai-inline-completion/meta.ts +20 -0
  119. package/src/components/ai-response/ai-response.tsx +1 -0
  120. package/src/components/ai-structured-output/ai-structured-output.tsx +268 -0
  121. package/src/components/ai-structured-output/index.ts +10 -0
  122. package/src/components/ai-structured-output/meta.ts +18 -0
  123. package/src/components/file-upload/file-upload.tsx +322 -0
  124. package/src/components/file-upload/index.ts +20 -0
  125. package/src/components/file-upload/meta.ts +21 -0
  126. package/src/components/file-upload/upload-queue.ts +337 -0
  127. package/src/components/meter/index.ts +8 -0
  128. package/src/components/meter/meta.ts +20 -0
  129. package/src/components/meter/meter.tsx +219 -0
  130. package/src/components/metric-delta/index.ts +6 -0
  131. package/src/components/metric-delta/meta.ts +18 -0
  132. package/src/components/metric-delta/metric-delta.tsx +180 -0
  133. package/src/components/progress/progress.tsx +3 -0
  134. package/src/components/record-diff/index.ts +10 -0
  135. package/src/components/record-diff/meta.ts +19 -0
  136. package/src/components/record-diff/record-diff.tsx +341 -0
  137. package/src/components/spinner/spinner.tsx +5 -0
  138. package/src/components/tags-input/index.ts +1 -0
  139. package/src/components/tags-input/meta.ts +23 -0
  140. package/src/components/tags-input/tags-input.tsx +300 -0
  141. package/src/index.ts +10 -0
  142. package/src/registry/components.ts +20 -0
@@ -0,0 +1,300 @@
1
+ "use client";
2
+
3
+ import {
4
+ useId,
5
+ useRef,
6
+ useState,
7
+ type ClipboardEvent,
8
+ type ComponentPropsWithRef,
9
+ type KeyboardEvent,
10
+ } from "react";
11
+
12
+ import { disabledStyles, focusRing } from "@/lib/styles";
13
+ import { cn } from "@/lib/utils";
14
+
15
+ /**
16
+ * A field whose value is a list of short strings: invited emails, allowed
17
+ * domains, labels, stop sequences.
18
+ *
19
+ * The behaviour that makes this worth shipping is what happens to input that
20
+ * fails validation. Every implementation surveyed either refuses to create the
21
+ * token, or creates it and silently throws it away — and both leave the reader
22
+ * staring at a field that did not do what they asked, with nothing to correct.
23
+ * Here an invalid entry becomes a token like any other, marked invalid and
24
+ * carrying its reason, so it can be seen, read out, and fixed by removing it.
25
+ * `value` holds every token including the invalid ones; the consumer runs the
26
+ * same `validate` to decide whether the field is submittable.
27
+ *
28
+ * Deliberately no suggestion list. A token field with an anchored listbox is a
29
+ * multi-select combobox, and this library already has 544 lines of hand-rolled
30
+ * combobox ARIA. A second copy of that would be the expensive kind of
31
+ * duplication — the kind that drifts. When multi-select is wanted, it belongs in
32
+ * Combobox.
33
+ */
34
+
35
+ /** Returns `true` for a valid tag, or a reason it is not. */
36
+ export type TagValidator = (tag: string, existing: string[]) => true | string;
37
+
38
+ export interface TagsInputProps extends Omit<
39
+ ComponentPropsWithRef<"div">,
40
+ "onChange" | "children"
41
+ > {
42
+ value: string[];
43
+ onValueChange: (tags: string[]) => void;
44
+ /** Names the field. Required — an unlabelled list of tokens is unreadable. */
45
+ label: string;
46
+ /** Characters that commit the token being typed, besides Enter. */
47
+ delimiters?: string[];
48
+ /**
49
+ * Decides whether a tag is acceptable. An invalid tag is still added, marked,
50
+ * and given its reason, rather than being refused or dropped.
51
+ */
52
+ validate?: TagValidator;
53
+ /** Rejects a tag already present. Rejections are announced, never silent. */
54
+ allowDuplicates?: boolean;
55
+ /** Refuses further tags once reached, and says so. */
56
+ max?: number;
57
+ placeholder?: string;
58
+ disabled?: boolean;
59
+ inputProps?: Omit<ComponentPropsWithRef<"input">, "value" | "onChange" | "disabled">;
60
+ }
61
+
62
+ /** Splits pasted or typed text on any delimiter, dropping empty fragments. */
63
+ function splitOn(text: string, delimiters: string[]): string[] {
64
+ if (delimiters.length === 0) return [text];
65
+ const pattern = new RegExp(`[${delimiters.map((d) => `\\${d}`).join("")}]`);
66
+ return text
67
+ .split(pattern)
68
+ .map((part) => part.trim())
69
+ .filter((part) => part.length > 0);
70
+ }
71
+
72
+ export function TagsInput({
73
+ className,
74
+ value,
75
+ onValueChange,
76
+ label,
77
+ delimiters = [",", ";"],
78
+ validate,
79
+ allowDuplicates = false,
80
+ max,
81
+ placeholder,
82
+ disabled = false,
83
+ inputProps,
84
+ ...props
85
+ }: TagsInputProps) {
86
+ const [draft, setDraft] = useState("");
87
+ const [announcement, setAnnouncement] = useState("");
88
+ const inputRef = useRef<HTMLInputElement | null>(null);
89
+ const labelId = useId();
90
+ const inputId = useId();
91
+ const hintId = useId();
92
+
93
+ const atLimit = max !== undefined && value.length >= max;
94
+
95
+ function reasonFor(tag: string): string | null {
96
+ if (!validate) return null;
97
+ const result = validate(tag, value);
98
+ return result === true ? null : result;
99
+ }
100
+
101
+ /** Adds tags, reporting anything refused rather than dropping it in silence. */
102
+ function commit(candidates: string[]) {
103
+ const accepted: string[] = [];
104
+ const refused: string[] = [];
105
+
106
+ // Split defensively rather than trusting the caller. A draft can arrive
107
+ // holding a delimiter from autofill, an IME commit, or a programmatic set,
108
+ // and a token with a comma inside it is never what was meant.
109
+ for (const candidate of candidates.flatMap((part) => splitOn(part, delimiters))) {
110
+ const tag = candidate.trim();
111
+ if (tag.length === 0) continue;
112
+
113
+ if (!allowDuplicates && [...value, ...accepted].includes(tag)) {
114
+ refused.push(`${tag} is already added`);
115
+ continue;
116
+ }
117
+ if (max !== undefined && value.length + accepted.length >= max) {
118
+ refused.push(`${tag} not added, limit of ${String(max)} reached`);
119
+ continue;
120
+ }
121
+ // An invalid tag is still added. It is the reader's text and they need to
122
+ // see it to fix it; refusing silently is how these fields lose input.
123
+ accepted.push(tag);
124
+ }
125
+
126
+ if (accepted.length > 0) onValueChange([...value, ...accepted]);
127
+
128
+ const parts: string[] = [];
129
+ if (accepted.length > 0) {
130
+ const invalid = accepted.filter((tag) => reasonFor(tag) !== null);
131
+ parts.push(`Added ${accepted.join(", ")}`);
132
+ if (invalid.length > 0) parts.push(`${String(invalid.length)} need attention`);
133
+ }
134
+ parts.push(...refused);
135
+ setAnnouncement(parts.join(". "));
136
+ }
137
+
138
+ function removeAt(index: number) {
139
+ const removed = value[index];
140
+ onValueChange(value.filter((_, position) => position !== index));
141
+ setAnnouncement(removed === undefined ? "" : `Removed ${removed}`);
142
+ inputRef.current?.focus();
143
+ }
144
+
145
+ function handleKeyDown(event: KeyboardEvent<HTMLInputElement>) {
146
+ if (event.key === "Enter") {
147
+ // Never let a token commit submit the form as well.
148
+ event.preventDefault();
149
+ if (draft.trim().length > 0) {
150
+ commit([draft]);
151
+ setDraft("");
152
+ }
153
+ return;
154
+ }
155
+
156
+ if (delimiters.includes(event.key)) {
157
+ event.preventDefault();
158
+ if (draft.trim().length > 0) {
159
+ commit([draft]);
160
+ setDraft("");
161
+ }
162
+ return;
163
+ }
164
+
165
+ // Backspace on an empty field removes the last token — the expected
166
+ // shortcut, and the only way to correct without reaching for the mouse.
167
+ if (event.key === "Backspace" && draft.length === 0 && value.length > 0) {
168
+ event.preventDefault();
169
+ removeAt(value.length - 1);
170
+ }
171
+ }
172
+
173
+ function handlePaste(event: ClipboardEvent<HTMLInputElement>) {
174
+ const text = event.clipboardData.getData("text");
175
+ const parts = splitOn(text, delimiters);
176
+ // Only intercept a paste that actually contains several tags; a single
177
+ // value should behave like an ordinary paste and stay editable.
178
+ if (parts.length <= 1) return;
179
+
180
+ event.preventDefault();
181
+ commit(parts);
182
+ setDraft("");
183
+ }
184
+
185
+ return (
186
+ <div data-slot="tags-input" className={cn("flex flex-col gap-1.5", className)} {...props}>
187
+ <label id={labelId} htmlFor={inputId} className="w-fit text-sm font-medium">
188
+ {label}
189
+ </label>
190
+
191
+ {/* A group rather than a listbox: these are committed values, not options
192
+ being chosen from, and calling it a listbox would promise navigation
193
+ semantics that do not exist here. */}
194
+ <div
195
+ role="group"
196
+ aria-labelledby={labelId}
197
+ data-disabled={disabled || undefined}
198
+ className={cn(
199
+ "flex min-h-10 w-full flex-wrap items-center gap-1.5 rounded-md border border-input bg-background px-2 py-1.5",
200
+ "focus-within:ring-2 focus-within:ring-ring/55",
201
+ disabled && "pointer-events-none opacity-55",
202
+ )}
203
+ >
204
+ {value.length > 0 ? (
205
+ <ul className="contents">
206
+ {value.map((tag, index) => {
207
+ const reason = reasonFor(tag);
208
+ return (
209
+ <li
210
+ key={`${tag}-${String(index)}`}
211
+ data-slot="tags-input-tag"
212
+ data-invalid={reason !== null || undefined}
213
+ className={cn(
214
+ "inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-xs font-medium",
215
+ reason === null
216
+ ? "border-transparent bg-secondary text-secondary-foreground"
217
+ : "border-destructive/40 bg-destructive/10 text-destructive",
218
+ )}
219
+ >
220
+ {tag}
221
+ {/* The reason travels with the token, so it is announced when
222
+ the token is, rather than as a detached error elsewhere. */}
223
+ {reason === null ? null : (
224
+ <span className="sr-only">, invalid: {reason}</span>
225
+ )}
226
+ <button
227
+ type="button"
228
+ data-slot="tags-input-remove"
229
+ disabled={disabled}
230
+ aria-label={`Remove ${tag}`}
231
+ onClick={() => {
232
+ removeAt(index);
233
+ }}
234
+ className={cn(
235
+ "-mr-0.5 grid size-4 place-items-center rounded-full",
236
+ "transition-colors hover:bg-foreground/10",
237
+ focusRing,
238
+ disabledStyles,
239
+ )}
240
+ >
241
+ <svg viewBox="0 0 24 24" aria-hidden="true" className="size-2.5">
242
+ <path
243
+ d="M6 6l12 12M18 6L6 18"
244
+ stroke="currentColor"
245
+ strokeWidth="3"
246
+ strokeLinecap="round"
247
+ />
248
+ </svg>
249
+ </button>
250
+ </li>
251
+ );
252
+ })}
253
+ </ul>
254
+ ) : null}
255
+
256
+ <input
257
+ ref={inputRef}
258
+ type="text"
259
+ id={inputId}
260
+ data-slot="tags-input-field"
261
+ value={draft}
262
+ disabled={disabled}
263
+ placeholder={value.length === 0 ? placeholder : undefined}
264
+ aria-describedby={hintId}
265
+ onChange={(event) => {
266
+ setDraft(event.target.value);
267
+ }}
268
+ onKeyDown={handleKeyDown}
269
+ onPaste={handlePaste}
270
+ onBlur={() => {
271
+ // Committing on blur stops a typed-but-uncommitted value being lost
272
+ // when the reader tabs away thinking they are done.
273
+ if (draft.trim().length > 0) {
274
+ commit([draft]);
275
+ setDraft("");
276
+ }
277
+ }}
278
+ className={cn(
279
+ "min-w-24 flex-1 self-stretch bg-transparent text-sm outline-none",
280
+ "placeholder:text-muted-foreground",
281
+ )}
282
+ {...inputProps}
283
+ />
284
+ </div>
285
+
286
+ <span id={hintId} className="text-xs text-muted-foreground">
287
+ {atLimit
288
+ ? `Limit of ${String(max ?? 0)} reached`
289
+ : `Press Enter${delimiters.length > 0 ? ` or ${delimiters.join(" ")}` : ""} to add`}
290
+ </span>
291
+
292
+ {/* Additions, removals and refusals all land here. A refusal that is only
293
+ visible as "nothing happened" is the failure this component exists to
294
+ avoid. */}
295
+ <span aria-live="polite" className="sr-only">
296
+ {announcement}
297
+ </span>
298
+ </div>
299
+ );
300
+ }
package/src/index.ts CHANGED
@@ -1,6 +1,11 @@
1
1
  export * from "./components/accordion";
2
2
  export * from "./components/activity-feed";
3
+ export * from "./components/ai-action-ledger";
4
+ export * from "./components/ai-inline-completion";
5
+ export * from "./components/ai-structured-output";
6
+ export * from "./components/ai-agent-plan";
3
7
  export * from "./components/ai-agent-status";
8
+ export * from "./components/ai-approval-request";
4
9
  export * from "./components/ai-conversation";
5
10
  export * from "./components/ai-message";
6
11
  export * from "./components/ai-model-selector";
@@ -26,9 +31,13 @@ export * from "./components/dialog";
26
31
  export * from "./components/drawer";
27
32
  export * from "./components/dropdown-menu";
28
33
  export * from "./components/empty-state";
34
+ export * from "./components/file-upload";
29
35
  export * from "./components/form";
30
36
  export * from "./components/input";
31
37
  export * from "./components/label";
38
+ export * from "./components/meter";
39
+ export * from "./components/metric-delta";
40
+ export * from "./components/record-diff";
32
41
  export * from "./components/pagination";
33
42
  export * from "./components/popover";
34
43
  export * from "./components/progress";
@@ -42,6 +51,7 @@ export * from "./components/spinner";
42
51
  export * from "./components/switch";
43
52
  export * from "./components/table";
44
53
  export * from "./components/tabs";
54
+ export * from "./components/tags-input";
45
55
  export * from "./components/toast";
46
56
  export * from "./components/tooltip";
47
57
 
@@ -2,14 +2,19 @@ import type { ComponentMeta } from "./schema";
2
2
 
3
3
  import { meta as accordionMeta } from "@/components/accordion/meta";
4
4
  import { meta as activityFeedMeta } from "@/components/activity-feed/meta";
5
+ import { meta as aiActionLedgerMeta } from "@/components/ai-action-ledger/meta";
6
+ import { meta as aiAgentPlanMeta } from "@/components/ai-agent-plan/meta";
5
7
  import { meta as aiAgentStatusMeta } from "@/components/ai-agent-status/meta";
8
+ import { meta as aiApprovalRequestMeta } from "@/components/ai-approval-request/meta";
6
9
  import { meta as aiConversationMeta } from "@/components/ai-conversation/meta";
10
+ import { meta as aiInlineCompletionMeta } from "@/components/ai-inline-completion/meta";
7
11
  import { meta as aiMessageMeta } from "@/components/ai-message/meta";
8
12
  import { meta as aiModelSelectorMeta } from "@/components/ai-model-selector/meta";
9
13
  import { meta as aiPromptInputMeta } from "@/components/ai-prompt-input/meta";
10
14
  import { meta as aiReasoningMeta } from "@/components/ai-reasoning/meta";
11
15
  import { meta as aiResponseMeta } from "@/components/ai-response/meta";
12
16
  import { meta as aiSourcesMeta } from "@/components/ai-sources/meta";
17
+ import { meta as aiStructuredOutputMeta } from "@/components/ai-structured-output/meta";
13
18
  import { meta as aiTokenUsageMeta } from "@/components/ai-token-usage/meta";
14
19
  import { meta as aiToolMeta } from "@/components/ai-tool/meta";
15
20
  import { meta as alertMeta } from "@/components/alert/meta";
@@ -28,13 +33,17 @@ import { meta as dialogMeta } from "@/components/dialog/meta";
28
33
  import { meta as drawerMeta } from "@/components/drawer/meta";
29
34
  import { meta as dropdownMenuMeta } from "@/components/dropdown-menu/meta";
30
35
  import { meta as emptyStateMeta } from "@/components/empty-state/meta";
36
+ import { meta as fileUploadMeta } from "@/components/file-upload/meta";
31
37
  import { meta as formMeta } from "@/components/form/meta";
32
38
  import { meta as inputMeta } from "@/components/input/meta";
33
39
  import { meta as labelMeta } from "@/components/label/meta";
40
+ import { meta as meterMeta } from "@/components/meter/meta";
41
+ import { meta as metricDeltaMeta } from "@/components/metric-delta/meta";
34
42
  import { meta as paginationMeta } from "@/components/pagination/meta";
35
43
  import { meta as popoverMeta } from "@/components/popover/meta";
36
44
  import { meta as progressMeta } from "@/components/progress/meta";
37
45
  import { meta as radioGroupMeta } from "@/components/radio-group/meta";
46
+ import { meta as recordDiffMeta } from "@/components/record-diff/meta";
38
47
  import { meta as selectMeta } from "@/components/select/meta";
39
48
  import { meta as separatorMeta } from "@/components/separator/meta";
40
49
  import { meta as sheetMeta } from "@/components/sheet/meta";
@@ -44,6 +53,7 @@ import { meta as spinnerMeta } from "@/components/spinner/meta";
44
53
  import { meta as switchMeta } from "@/components/switch/meta";
45
54
  import { meta as tableMeta } from "@/components/table/meta";
46
55
  import { meta as tabsMeta } from "@/components/tabs/meta";
56
+ import { meta as tagsInputMeta } from "@/components/tags-input/meta";
47
57
  import { meta as toastMeta } from "@/components/toast/meta";
48
58
  import { meta as tooltipMeta } from "@/components/tooltip/meta";
49
59
 
@@ -61,14 +71,19 @@ import { meta as tooltipMeta } from "@/components/tooltip/meta";
61
71
  export const componentMetas: ComponentMeta[] = [
62
72
  accordionMeta,
63
73
  activityFeedMeta,
74
+ aiActionLedgerMeta,
75
+ aiAgentPlanMeta,
64
76
  aiAgentStatusMeta,
77
+ aiApprovalRequestMeta,
65
78
  aiConversationMeta,
79
+ aiInlineCompletionMeta,
66
80
  aiMessageMeta,
67
81
  aiModelSelectorMeta,
68
82
  aiPromptInputMeta,
69
83
  aiReasoningMeta,
70
84
  aiResponseMeta,
71
85
  aiSourcesMeta,
86
+ aiStructuredOutputMeta,
72
87
  aiTokenUsageMeta,
73
88
  aiToolMeta,
74
89
  alertMeta,
@@ -87,13 +102,17 @@ export const componentMetas: ComponentMeta[] = [
87
102
  drawerMeta,
88
103
  dropdownMenuMeta,
89
104
  emptyStateMeta,
105
+ fileUploadMeta,
90
106
  formMeta,
91
107
  inputMeta,
92
108
  labelMeta,
109
+ meterMeta,
110
+ metricDeltaMeta,
93
111
  paginationMeta,
94
112
  popoverMeta,
95
113
  progressMeta,
96
114
  radioGroupMeta,
115
+ recordDiffMeta,
97
116
  selectMeta,
98
117
  separatorMeta,
99
118
  sheetMeta,
@@ -103,6 +122,7 @@ export const componentMetas: ComponentMeta[] = [
103
122
  switchMeta,
104
123
  tableMeta,
105
124
  tabsMeta,
125
+ tagsInputMeta,
106
126
  toastMeta,
107
127
  tooltipMeta,
108
128
  ];