@timbal-ai/timbal-react 0.6.0 → 0.7.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 (44) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +24 -5
  3. package/dist/app.cjs +2282 -738
  4. package/dist/app.d.cts +4 -1
  5. package/dist/app.d.ts +4 -1
  6. package/dist/app.esm.js +58 -5
  7. package/dist/button-CIKzUrJI.d.cts +18 -0
  8. package/dist/button-CIKzUrJI.d.ts +18 -0
  9. package/dist/chart-artifact-BFDz8Tf9.d.ts +756 -0
  10. package/dist/chart-artifact-bWUa-iSG.d.cts +756 -0
  11. package/dist/chat.cjs +872 -562
  12. package/dist/chat.d.cts +2 -2
  13. package/dist/chat.d.ts +2 -2
  14. package/dist/chat.esm.js +3 -3
  15. package/dist/{chunk-4TCJQSIX.esm.js → chunk-2XZ3S4OP.esm.js} +14 -3
  16. package/dist/chunk-533MK5EA.esm.js +2294 -0
  17. package/dist/{chunk-OVHR7J3J.esm.js → chunk-7O5VY3TP.esm.js} +38 -11
  18. package/dist/{chunk-WLTW56MC.esm.js → chunk-N3PYVTY5.esm.js} +2 -2
  19. package/dist/{chunk-IYENDIRY.esm.js → chunk-TDIJHV4I.esm.js} +1 -1
  20. package/dist/{chunk-YJQLLFKP.esm.js → chunk-TLUF2RUL.esm.js} +813 -507
  21. package/dist/{chunk-OFHLFNJH.esm.js → chunk-Z27GBSOT.esm.js} +3 -1
  22. package/dist/index.cjs +2587 -1016
  23. package/dist/index.d.cts +6 -5
  24. package/dist/index.d.ts +6 -5
  25. package/dist/index.esm.js +57 -7
  26. package/dist/{layout-CQWngNQ7.d.ts → layout-BTJyU8wd.d.ts} +1 -1
  27. package/dist/{layout-B9VayJhZ.d.cts → layout-C2G-FcER.d.cts} +1 -1
  28. package/dist/studio.cjs +1127 -788
  29. package/dist/studio.d.cts +1 -1
  30. package/dist/studio.d.ts +1 -1
  31. package/dist/studio.esm.js +6 -6
  32. package/dist/{timbal-v2-button-F4-z7m33.d.ts → timbal-v2-button-CNfdwGq4.d.cts} +1 -1
  33. package/dist/{timbal-v2-button-F4-z7m33.d.cts → timbal-v2-button-CNfdwGq4.d.ts} +1 -1
  34. package/dist/ui.cjs +12 -3
  35. package/dist/ui.d.cts +5 -16
  36. package/dist/ui.d.ts +5 -16
  37. package/dist/ui.esm.js +2 -2
  38. package/dist/{welcome-BOizSp5h.d.ts → welcome-BBmB3tl7.d.ts} +4 -3
  39. package/dist/{welcome--80i_O0p.d.cts → welcome-C89Mgdaw.d.cts} +4 -3
  40. package/package.json +2 -1
  41. package/vite/local-dev.mjs +91 -5
  42. package/dist/chart-artifact-C71dk4xI.d.ts +0 -329
  43. package/dist/chart-artifact-CPEpOmtV.d.cts +0 -329
  44. package/dist/chunk-M4V6Q6XO.esm.js +0 -1082
@@ -1,1082 +0,0 @@
1
- import {
2
- SIDEBAR_INSET_PX_EXPANDED,
3
- ShellInsetProvider,
4
- studioChromeShellStyle,
5
- studioSidebarWidthTransition
6
- } from "./chunk-OFHLFNJH.esm.js";
7
- import {
8
- ChartArtifactView,
9
- Thread,
10
- TimbalRuntimeProvider,
11
- studioIntegrationCardClass,
12
- studioSearchChromeClass,
13
- studioSecondaryChromeClass,
14
- studioTopbarPillHeightClass
15
- } from "./chunk-YJQLLFKP.esm.js";
16
- import {
17
- PillSegmentedTabs
18
- } from "./chunk-IYENDIRY.esm.js";
19
- import {
20
- Dialog,
21
- DialogContent,
22
- DialogTitle,
23
- TIMBAL_V2_SWITCH_THUMB,
24
- TIMBAL_V2_SWITCH_TRACK_OFF,
25
- TimbalV2Button,
26
- cn
27
- } from "./chunk-4TCJQSIX.esm.js";
28
-
29
- // src/design/app-classes.ts
30
- var appPageColumnClass = "mx-auto w-full max-w-6xl px-4 md:px-6";
31
- var appShellTopbarInsetClass = "w-full px-4 md:px-6";
32
- var appShellInsetTopClass = "pt-4 md:pt-6";
33
- var appShellTopbarRowClass = cn(
34
- studioTopbarPillHeightClass,
35
- "flex w-full items-center justify-between gap-2"
36
- );
37
- var appShellTopbarStickyClass = cn(
38
- "sticky top-0 z-20 shrink-0 bg-background pb-2",
39
- appShellInsetTopClass
40
- );
41
- var appPageHeaderClass = cn(
42
- "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",
43
- "pb-4 pt-2"
44
- );
45
- var appSectionClass = "flex flex-col gap-4 py-4";
46
- var appSectionTitleClass = "text-lg font-semibold text-foreground";
47
- var appSectionDescriptionClass = "text-sm text-muted-foreground";
48
- var appSurfaceCardClass = cn(
49
- studioIntegrationCardClass,
50
- "p-4 md:p-5"
51
- );
52
- var appStatTileClass = cn(
53
- appSurfaceCardClass,
54
- "flex flex-col gap-1"
55
- );
56
- var appStatValueClass = "text-2xl font-semibold tracking-tight text-foreground";
57
- var appStatLabelClass = "text-sm text-muted-foreground";
58
- var appFilterBarClass = cn(
59
- "flex flex-wrap items-center gap-2",
60
- studioTopbarPillHeightClass
61
- );
62
- var appSearchInputClass = cn(studioSearchChromeClass, "text-sm");
63
- var appBreadcrumbsClass = "flex flex-wrap items-center gap-1.5 text-sm text-muted-foreground";
64
- var appBreadcrumbLinkClass = "transition-colors hover:text-foreground";
65
- var appFieldClass = "flex flex-col gap-1.5";
66
- var appFieldLabelClass = "text-sm font-medium text-foreground";
67
- var appFieldHintClass = "text-xs text-muted-foreground";
68
- var appInputClass = cn(
69
- studioSecondaryChromeClass,
70
- "h-10 w-full rounded-lg px-3 text-sm text-foreground outline-none",
71
- "placeholder:text-muted-foreground/70",
72
- "focus-visible:ring-2 focus-visible:ring-foreground/10"
73
- );
74
- var appEmptyStateClass = cn(
75
- appSurfaceCardClass,
76
- "flex flex-col items-center justify-center gap-2 py-12 text-center"
77
- );
78
- var appEmptyStateTitleClass = "text-base font-medium text-foreground";
79
- var appEmptyStateDescriptionClass = "max-w-sm text-sm text-muted-foreground";
80
- var appChartPanelClass = cn(appSurfaceCardClass, "flex flex-col gap-3");
81
- var appChartPanelTitleClass = "text-sm font-medium text-foreground";
82
-
83
- // src/app/layout/app-shell-chat-context.tsx
84
- import { createContext, useContext } from "react";
85
- var AppShellChatContext = createContext(null);
86
- var AppShellChatProvider = AppShellChatContext.Provider;
87
- function useAppShellChat() {
88
- return useContext(AppShellChatContext);
89
- }
90
-
91
- // src/app/layout/AppShell.tsx
92
- import { motion, useReducedMotion } from "motion/react";
93
- import { useCallback, useState } from "react";
94
- import { jsx, jsxs } from "react/jsx-runtime";
95
- var floatingTriggerClass = cn(
96
- "aui-app-shell-chat-trigger-fixed fixed z-50 rounded-full px-5 py-2.5 text-sm font-medium shadow-card-elevated",
97
- "bg-primary text-primary-foreground transition-colors hover:bg-primary/90",
98
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
99
- "bottom-6 right-6 max-sm:bottom-4 max-sm:right-4"
100
- );
101
- var floatingPanelClass = cn(
102
- "aui-app-shell-chat-float fixed z-50 flex flex-col overflow-hidden rounded-2xl border border-border/60 shadow-card-elevated",
103
- "bg-card/85 backdrop-blur-xl supports-backdrop-filter:bg-card/75",
104
- // Mobile: stretch between insets (no fixed width — avoids a wide empty strip on the right)
105
- "max-sm:inset-x-3 max-sm:top-3 max-sm:bottom-3 max-sm:w-auto",
106
- "sm:top-6 sm:right-6 sm:bottom-6 sm:w-[var(--app-shell-chat-width)] sm:max-w-[calc(100vw-3rem)]"
107
- );
108
- var AppShellBody = ({
109
- sidebar,
110
- topbarContent,
111
- mainClassName,
112
- insetPaddingPx,
113
- insetExpanded,
114
- children
115
- }) => {
116
- const reducedMotion = useReducedMotion();
117
- const layoutDirection = insetExpanded ? "expand" : "collapse";
118
- const layoutTransition = studioSidebarWidthTransition(
119
- !!reducedMotion,
120
- layoutDirection
121
- );
122
- const insetPadding = sidebar ? insetPaddingPx : 0;
123
- return /* @__PURE__ */ jsx(
124
- motion.div,
125
- {
126
- className: "aui-app-shell-body relative z-10 flex min-h-0 min-w-0 flex-1 flex-col",
127
- initial: false,
128
- animate: { paddingLeft: insetPadding },
129
- transition: layoutTransition,
130
- children: /* @__PURE__ */ jsxs(
131
- "div",
132
- {
133
- className: cn(
134
- "aui-app-shell-scroll flex min-h-0 flex-1 flex-col overflow-y-auto",
135
- !topbarContent && appShellInsetTopClass
136
- ),
137
- children: [
138
- topbarContent ? /* @__PURE__ */ jsx("header", { className: cn("aui-app-shell-topbar-region", appShellTopbarStickyClass), children: /* @__PURE__ */ jsx("div", { className: appShellTopbarInsetClass, children: topbarContent }) }) : null,
139
- /* @__PURE__ */ jsx("main", { className: cn("aui-app-shell-main min-w-0 flex-1", mainClassName), children })
140
- ]
141
- }
142
- )
143
- }
144
- );
145
- };
146
- var AppShell = ({
147
- sidebar,
148
- topbar,
149
- header,
150
- children,
151
- chat,
152
- chatWidth = "24rem",
153
- chatHeight,
154
- chatOpen: chatOpenProp,
155
- defaultChatOpen = false,
156
- onChatOpenChange,
157
- chatCollapsible = true,
158
- chatTriggerLabel = "Assistant",
159
- hideChatTrigger = false,
160
- className,
161
- mainClassName
162
- }) => {
163
- const topbarContent = topbar ?? header;
164
- const hasChat = Boolean(chat);
165
- const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultChatOpen);
166
- const isChatControlled = chatOpenProp !== void 0;
167
- const chatOpen = isChatControlled ? chatOpenProp : uncontrolledOpen;
168
- const setChatOpen = useCallback(
169
- (open) => {
170
- if (!isChatControlled) {
171
- setUncontrolledOpen(open);
172
- }
173
- onChatOpenChange?.(open);
174
- },
175
- [isChatControlled, onChatOpenChange]
176
- );
177
- const toggleChat = useCallback(() => {
178
- setChatOpen(!chatOpen);
179
- }, [chatOpen, setChatOpen]);
180
- const [insetPaddingPx, setInsetPaddingPx] = useState(
181
- sidebar ? SIDEBAR_INSET_PX_EXPANDED : 0
182
- );
183
- const reportShellInset = useCallback((insetPx) => {
184
- setInsetPaddingPx(insetPx);
185
- }, []);
186
- const insetExpanded = insetPaddingPx >= SIDEBAR_INSET_PX_EXPANDED;
187
- const shellBody = /* @__PURE__ */ jsx(
188
- AppShellBody,
189
- {
190
- sidebar,
191
- topbarContent,
192
- mainClassName,
193
- insetPaddingPx,
194
- insetExpanded,
195
- children
196
- }
197
- );
198
- const tree = /* @__PURE__ */ jsx(ShellInsetProvider, { value: sidebar ? reportShellInset : null, children: /* @__PURE__ */ jsxs(
199
- "div",
200
- {
201
- className: cn(
202
- "aui-app-shell relative flex h-dvh overflow-hidden bg-background",
203
- className
204
- ),
205
- style: studioChromeShellStyle,
206
- children: [
207
- sidebar,
208
- shellBody,
209
- hasChat && chatOpen ? /* @__PURE__ */ jsx(
210
- "div",
211
- {
212
- className: floatingPanelClass,
213
- style: {
214
- ["--app-shell-chat-width"]: chatWidth,
215
- ...chatHeight ? { height: chatHeight } : void 0
216
- },
217
- role: "dialog",
218
- "aria-label": typeof chatTriggerLabel === "string" ? chatTriggerLabel : "Assistant",
219
- children: chat
220
- }
221
- ) : null,
222
- hasChat && chatCollapsible && !chatOpen && !hideChatTrigger ? /* @__PURE__ */ jsx(
223
- "button",
224
- {
225
- type: "button",
226
- className: floatingTriggerClass,
227
- onClick: () => setChatOpen(true),
228
- "aria-expanded": false,
229
- children: chatTriggerLabel
230
- }
231
- ) : null
232
- ]
233
- }
234
- ) });
235
- if (!hasChat) {
236
- return tree;
237
- }
238
- return /* @__PURE__ */ jsx(
239
- AppShellChatProvider,
240
- {
241
- value: {
242
- open: chatOpen,
243
- setOpen: setChatOpen,
244
- toggle: toggleChat,
245
- collapsible: chatCollapsible
246
- },
247
- children: tree
248
- }
249
- );
250
- };
251
-
252
- // src/app/layout/AppShellTopbar.tsx
253
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
254
- var AppShellTopbar = ({
255
- start,
256
- actions,
257
- children,
258
- className
259
- }) => {
260
- return /* @__PURE__ */ jsxs2("div", { className: cn("aui-app-shell-topbar", appShellTopbarRowClass, className), children: [
261
- /* @__PURE__ */ jsxs2("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
262
- start,
263
- children
264
- ] }),
265
- actions ? /* @__PURE__ */ jsx2("div", { className: "aui-app-shell-topbar-actions flex shrink-0 items-center gap-2", children: actions }) : null
266
- ] });
267
- };
268
-
269
- // src/app/layout/AppShellChatTrigger.tsx
270
- import { jsx as jsx3 } from "react/jsx-runtime";
271
- var floatingPositionClass = "fixed bottom-6 right-6 z-50 max-sm:bottom-4 max-sm:right-4";
272
- var AppShellChatTrigger = ({
273
- className,
274
- label = "Assistant",
275
- placement = "inline"
276
- }) => {
277
- const shellChat = useAppShellChat();
278
- if (!shellChat || shellChat.open) return null;
279
- return /* @__PURE__ */ jsx3(
280
- TimbalV2Button,
281
- {
282
- type: "button",
283
- variant: placement === "floating" ? "primary" : "secondary",
284
- size: "sm",
285
- className: cn(
286
- "aui-app-shell-chat-trigger",
287
- placement === "floating" && floatingPositionClass,
288
- placement === "floating" && "shadow-card-elevated",
289
- className
290
- ),
291
- onClick: () => shellChat.setOpen(true),
292
- "aria-expanded": false,
293
- children: label
294
- }
295
- );
296
- };
297
-
298
- // src/app/layout/PageHeader.tsx
299
- import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
300
- var PageHeader = ({
301
- title,
302
- description,
303
- actions,
304
- className
305
- }) => {
306
- return /* @__PURE__ */ jsxs3("header", { className: cn("aui-app-page-header", appPageHeaderClass, className), children: [
307
- /* @__PURE__ */ jsxs3("div", { className: "min-w-0", children: [
308
- /* @__PURE__ */ jsx4("h1", { className: "text-2xl font-semibold tracking-tight text-foreground", children: title }),
309
- description ? /* @__PURE__ */ jsx4("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null
310
- ] }),
311
- actions ? /* @__PURE__ */ jsx4("div", { className: "aui-app-page-header-actions flex shrink-0 flex-wrap items-center gap-2", children: actions }) : null
312
- ] });
313
- };
314
-
315
- // src/app/layout/Page.tsx
316
- import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
317
- var Page = ({
318
- children,
319
- breadcrumbs,
320
- className,
321
- ...headerProps
322
- }) => {
323
- return /* @__PURE__ */ jsxs4("div", { className: cn("aui-app-page", appPageColumnClass, className), children: [
324
- breadcrumbs,
325
- /* @__PURE__ */ jsx5(PageHeader, { ...headerProps }),
326
- children
327
- ] });
328
- };
329
-
330
- // src/app/layout/Section.tsx
331
- import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
332
- var Section = ({
333
- title,
334
- description,
335
- children,
336
- className
337
- }) => {
338
- return /* @__PURE__ */ jsxs5("section", { className: cn("aui-app-section", appSectionClass, className), children: [
339
- title ? /* @__PURE__ */ jsx6("h2", { className: appSectionTitleClass, children: title }) : null,
340
- description ? /* @__PURE__ */ jsx6("p", { className: appSectionDescriptionClass, children: description }) : null,
341
- children
342
- ] });
343
- };
344
-
345
- // src/app/copilot/app-copilot-context.tsx
346
- import { createContext as createContext2, useContext as useContext2 } from "react";
347
- import { jsx as jsx7 } from "react/jsx-runtime";
348
- var AppCopilotContext = createContext2(null);
349
- var AppCopilotProvider = ({
350
- value,
351
- children
352
- }) => {
353
- return /* @__PURE__ */ jsx7(AppCopilotContext.Provider, { value, children });
354
- };
355
- function useAppCopilotContext() {
356
- return useContext2(AppCopilotContext) ?? {};
357
- }
358
-
359
- // src/app/chat/AppChatPanel.tsx
360
- import { XIcon } from "lucide-react";
361
- import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
362
- var shellClass = "aui-app-chat-panel flex h-full min-h-0 flex-col overflow-hidden";
363
- var chromeClass = cn(
364
- "aui-app-chat-panel-chrome relative z-20 flex min-h-12 shrink-0 items-center justify-end",
365
- "bg-card/90 px-2 pt-3 pb-3 backdrop-blur-sm"
366
- );
367
- var closeButtonClass = cn(
368
- "aui-app-chat-panel-close flex size-8 shrink-0 items-center justify-center rounded-md",
369
- "text-muted-foreground transition-colors hover:bg-foreground/5 hover:text-foreground",
370
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-transparent"
371
- );
372
- var bodyClass = cn(
373
- "aui-app-chat-panel-body relative min-h-0 flex-1 overflow-hidden",
374
- "[&_.aui-thread-root]:h-full",
375
- "[&_.aui-thread-viewport]:scrollbar-thin",
376
- "[&_.aui-thread-viewport]:[scrollbar-color:var(--border)_transparent]",
377
- // Reserve the scrollbar gutter on BOTH edges so the composer + messages
378
- // stay symmetric (otherwise the right-side scrollbar adds a phantom inset).
379
- "[&_.aui-thread-viewport]:[scrollbar-gutter:stable_both-edges]",
380
- // Tighter symmetric horizontal inset for panel + composer
381
- "[&_.aui-thread-viewport]:!px-2",
382
- "[&_.aui-thread-viewport]:!pt-2",
383
- "[&_.aui-user-message-root]:!px-0",
384
- "[&_.aui-composer-input]:!px-2",
385
- "[&_.aui-composer-action-wrapper]:!px-2"
386
- );
387
- var AppChatPanel = ({
388
- className,
389
- workforceId,
390
- baseUrl,
391
- fetch,
392
- attachments,
393
- attachmentsUploadUrl,
394
- attachmentsAccept,
395
- debug,
396
- welcome,
397
- suggestions,
398
- composerPlaceholder,
399
- components,
400
- artifacts,
401
- onArtifactEvent,
402
- ...rest
403
- }) => {
404
- const shellChat = useAppShellChat();
405
- return /* @__PURE__ */ jsxs6("div", { className: cn(shellClass, className), children: [
406
- shellChat?.collapsible ? /* @__PURE__ */ jsx8("div", { className: chromeClass, children: /* @__PURE__ */ jsx8(
407
- "button",
408
- {
409
- type: "button",
410
- className: closeButtonClass,
411
- onClick: () => shellChat.setOpen(false),
412
- "aria-label": "Close assistant",
413
- children: /* @__PURE__ */ jsx8(XIcon, { className: "size-4", "aria-hidden": true })
414
- }
415
- ) }) : null,
416
- /* @__PURE__ */ jsx8("div", { className: bodyClass, children: /* @__PURE__ */ jsx8(
417
- TimbalRuntimeProvider,
418
- {
419
- workforceId,
420
- baseUrl,
421
- fetch,
422
- attachments,
423
- attachmentsUploadUrl,
424
- attachmentsAccept,
425
- debug,
426
- children: /* @__PURE__ */ jsx8(
427
- Thread,
428
- {
429
- variant: "panel",
430
- className: "aui-app-chat-panel-thread",
431
- welcome,
432
- suggestions,
433
- composerPlaceholder,
434
- components,
435
- artifacts,
436
- onArtifactEvent,
437
- ...rest
438
- }
439
- )
440
- }
441
- ) })
442
- ] });
443
- };
444
-
445
- // src/app/surfaces/SurfaceCard.tsx
446
- import { jsx as jsx9 } from "react/jsx-runtime";
447
- var SurfaceCard = ({ children, className }) => {
448
- return /* @__PURE__ */ jsx9("div", { className: cn("aui-app-surface-card", appSurfaceCardClass, className), children });
449
- };
450
-
451
- // src/app/surfaces/StatTile.tsx
452
- import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
453
- var StatTile = ({ label, value, hint, className }) => {
454
- return /* @__PURE__ */ jsxs7("div", { className: cn("aui-app-stat-tile", appStatTileClass, className), children: [
455
- /* @__PURE__ */ jsx10("span", { className: appStatLabelClass, children: label }),
456
- /* @__PURE__ */ jsx10("span", { className: appStatValueClass, children: value }),
457
- hint ? /* @__PURE__ */ jsx10("span", { className: "text-xs text-muted-foreground", children: hint }) : null
458
- ] });
459
- };
460
-
461
- // src/app/surfaces/EmptyState.tsx
462
- import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
463
- var EmptyState = ({
464
- title,
465
- description,
466
- action,
467
- className
468
- }) => {
469
- return /* @__PURE__ */ jsxs8("div", { className: cn("aui-app-empty-state", appEmptyStateClass, className), children: [
470
- /* @__PURE__ */ jsx11("p", { className: appEmptyStateTitleClass, children: title }),
471
- description ? /* @__PURE__ */ jsx11("p", { className: appEmptyStateDescriptionClass, children: description }) : null,
472
- action
473
- ] });
474
- };
475
-
476
- // src/app/surfaces/StatusBadge.tsx
477
- import { jsx as jsx12 } from "react/jsx-runtime";
478
- var statusBadgeToneClass = {
479
- default: "bg-muted text-foreground",
480
- primary: "bg-primary/10 text-primary",
481
- success: "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400",
482
- warn: "bg-amber-500/10 text-amber-600 dark:text-amber-400",
483
- muted: "bg-muted/80 text-muted-foreground"
484
- };
485
- var StatusBadge = ({
486
- children,
487
- tone = "default",
488
- className
489
- }) => {
490
- return /* @__PURE__ */ jsx12(
491
- "span",
492
- {
493
- className: cn(
494
- "aui-app-status-badge inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium",
495
- statusBadgeToneClass[tone],
496
- className
497
- ),
498
- children
499
- }
500
- );
501
- };
502
-
503
- // src/app/surfaces/AppConfirmDialog.tsx
504
- import { jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
505
- var bodyClass2 = "flex flex-col gap-4 p-6";
506
- var titleClass = "pr-8";
507
- var actionsClass = "flex flex-wrap justify-end gap-2";
508
- var AppConfirmDialog = ({
509
- open,
510
- onOpenChange,
511
- title,
512
- description,
513
- confirmLabel = "Confirm",
514
- cancelLabel = "Cancel",
515
- onConfirm,
516
- destructive = false,
517
- className
518
- }) => {
519
- return /* @__PURE__ */ jsx13(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsx13(
520
- DialogContent,
521
- {
522
- className: cn("gap-0 p-0 sm:max-w-md", className),
523
- children: /* @__PURE__ */ jsxs9("div", { className: bodyClass2, children: [
524
- /* @__PURE__ */ jsx13(DialogTitle, { className: titleClass, children: title }),
525
- description ? /* @__PURE__ */ jsx13("p", { className: "text-sm text-muted-foreground", children: description }) : null,
526
- /* @__PURE__ */ jsxs9("div", { className: actionsClass, children: [
527
- /* @__PURE__ */ jsx13(
528
- TimbalV2Button,
529
- {
530
- type: "button",
531
- variant: "secondary",
532
- size: "sm",
533
- onClick: () => onOpenChange(false),
534
- children: cancelLabel
535
- }
536
- ),
537
- /* @__PURE__ */ jsx13(
538
- TimbalV2Button,
539
- {
540
- type: "button",
541
- variant: destructive ? "destructive" : "primary",
542
- size: "sm",
543
- onClick: () => {
544
- onConfirm();
545
- onOpenChange(false);
546
- },
547
- children: confirmLabel
548
- }
549
- )
550
- ] })
551
- ] })
552
- }
553
- ) });
554
- };
555
-
556
- // src/app/navigation/SubNav.tsx
557
- import { jsx as jsx14 } from "react/jsx-runtime";
558
- var SubNav = ({
559
- items,
560
- activeId,
561
- onChange,
562
- className,
563
- "aria-label": ariaLabel = "Section navigation",
564
- layoutId
565
- }) => {
566
- return /* @__PURE__ */ jsx14("nav", { className: cn("aui-app-sub-nav", className), "aria-label": ariaLabel, children: /* @__PURE__ */ jsx14(
567
- PillSegmentedTabs,
568
- {
569
- value: activeId,
570
- onChange,
571
- tabs: items.map((item) => ({ key: item.id, label: item.label })),
572
- trackVariant: "flush",
573
- layoutId: layoutId ?? "app-sub-nav-segmented",
574
- "aria-label": ariaLabel
575
- }
576
- ) });
577
- };
578
-
579
- // src/app/navigation/Breadcrumbs.tsx
580
- import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
581
- var Breadcrumbs = ({ items, className }) => {
582
- return /* @__PURE__ */ jsx15("nav", { className: cn("aui-app-breadcrumbs", appBreadcrumbsClass, className), "aria-label": "Breadcrumb", children: /* @__PURE__ */ jsx15("ol", { className: "flex flex-wrap items-center gap-1.5", children: items.map((item, index) => {
583
- const isLast = index === items.length - 1;
584
- return /* @__PURE__ */ jsxs10("li", { className: "inline-flex items-center gap-1.5", children: [
585
- index > 0 ? /* @__PURE__ */ jsx15("span", { className: "text-muted-foreground/50", "aria-hidden": true, children: "/" }) : null,
586
- isLast ? /* @__PURE__ */ jsx15("span", { className: "text-foreground", "aria-current": "page", children: item.label }) : item.href ? /* @__PURE__ */ jsx15("a", { href: item.href, className: appBreadcrumbLinkClass, children: item.label }) : /* @__PURE__ */ jsx15(
587
- "button",
588
- {
589
- type: "button",
590
- className: appBreadcrumbLinkClass,
591
- onClick: item.onClick,
592
- children: item.label
593
- }
594
- )
595
- ] }, index);
596
- }) }) });
597
- };
598
-
599
- // src/app/forms/Field.tsx
600
- import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
601
- var Field = ({
602
- label,
603
- hint,
604
- error,
605
- children,
606
- className,
607
- htmlFor
608
- }) => {
609
- return /* @__PURE__ */ jsxs11("div", { className: cn("aui-app-field", appFieldClass, className), children: [
610
- /* @__PURE__ */ jsx16("label", { className: appFieldLabelClass, htmlFor, children: label }),
611
- children,
612
- hint && !error ? /* @__PURE__ */ jsx16("p", { className: appFieldHintClass, children: hint }) : null,
613
- error ? /* @__PURE__ */ jsx16("p", { className: "text-xs text-destructive", role: "alert", children: error }) : null
614
- ] });
615
- };
616
- var FieldInput = ({
617
- label,
618
- hint,
619
- error,
620
- fieldClassName,
621
- className,
622
- id,
623
- ...inputProps
624
- }) => {
625
- const inputId = id ?? inputProps.name;
626
- return /* @__PURE__ */ jsx16(
627
- Field,
628
- {
629
- label,
630
- hint,
631
- error,
632
- htmlFor: inputId,
633
- className: fieldClassName,
634
- children: /* @__PURE__ */ jsx16(
635
- "input",
636
- {
637
- id: inputId,
638
- className: cn(appInputClass, className),
639
- "aria-invalid": error ? true : void 0,
640
- ...inputProps
641
- }
642
- )
643
- }
644
- );
645
- };
646
-
647
- // src/app/forms/FieldTextarea.tsx
648
- import { jsx as jsx17 } from "react/jsx-runtime";
649
- var textareaClass = cn(
650
- appInputClass,
651
- "min-h-[5.5rem] resize-y py-2.5 leading-relaxed"
652
- );
653
- var FieldTextarea = ({
654
- label,
655
- hint,
656
- error,
657
- fieldClassName,
658
- className,
659
- id,
660
- ...props
661
- }) => {
662
- const textareaId = id ?? props.name;
663
- return /* @__PURE__ */ jsx17(
664
- Field,
665
- {
666
- label,
667
- hint,
668
- error,
669
- htmlFor: textareaId,
670
- className: fieldClassName,
671
- children: /* @__PURE__ */ jsx17(
672
- "textarea",
673
- {
674
- id: textareaId,
675
- className: cn(textareaClass, className),
676
- "aria-invalid": error ? true : void 0,
677
- ...props
678
- }
679
- )
680
- }
681
- );
682
- };
683
-
684
- // src/app/forms/FieldSelect.tsx
685
- import { ChevronDownIcon } from "lucide-react";
686
- import { jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
687
- var selectWrapClass = "relative";
688
- var selectClass = cn(
689
- appInputClass,
690
- "appearance-none pr-9"
691
- );
692
- var FieldSelect = ({
693
- label,
694
- hint,
695
- error,
696
- fieldClassName,
697
- className,
698
- children,
699
- id,
700
- ...props
701
- }) => {
702
- const selectId = id ?? props.name;
703
- return /* @__PURE__ */ jsx18(
704
- Field,
705
- {
706
- label,
707
- hint,
708
- error,
709
- htmlFor: selectId,
710
- className: fieldClassName,
711
- children: /* @__PURE__ */ jsxs12("div", { className: selectWrapClass, children: [
712
- /* @__PURE__ */ jsx18(
713
- "select",
714
- {
715
- id: selectId,
716
- className: cn(selectClass, className),
717
- "aria-invalid": error ? true : void 0,
718
- ...props,
719
- children
720
- }
721
- ),
722
- /* @__PURE__ */ jsx18(
723
- ChevronDownIcon,
724
- {
725
- className: "pointer-events-none absolute top-1/2 right-3 size-4 -translate-y-1/2 text-muted-foreground",
726
- "aria-hidden": true
727
- }
728
- )
729
- ] })
730
- }
731
- );
732
- };
733
-
734
- // src/app/forms/FieldSwitch.tsx
735
- import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
736
- var trackClass = cn(
737
- "relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-[background,box-shadow,border-color] duration-200",
738
- "peer-focus-visible:ring-2 peer-focus-visible:ring-foreground/10",
739
- "peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
740
- TIMBAL_V2_SWITCH_TRACK_OFF,
741
- "peer-checked:border-foreground/15 peer-checked:from-primary-fill-from peer-checked:to-primary-fill-to peer-checked:shadow-card",
742
- "peer-checked:[&>span]:translate-x-4"
743
- );
744
- var thumbClass = cn(
745
- "pointer-events-none inline-block size-4 shrink-0 translate-x-0.5 rounded-full transition-transform",
746
- TIMBAL_V2_SWITCH_THUMB
747
- );
748
- var FieldSwitch = ({
749
- label,
750
- description,
751
- className,
752
- id,
753
- ...props
754
- }) => {
755
- const inputId = id ?? props.name ?? "switch";
756
- return /* @__PURE__ */ jsxs13(
757
- "label",
758
- {
759
- className: cn(
760
- "aui-app-field-switch flex cursor-pointer items-start gap-3",
761
- className
762
- ),
763
- htmlFor: inputId,
764
- children: [
765
- /* @__PURE__ */ jsxs13("span", { className: "relative mt-0.5", children: [
766
- /* @__PURE__ */ jsx19(
767
- "input",
768
- {
769
- id: inputId,
770
- type: "checkbox",
771
- role: "switch",
772
- className: "peer sr-only",
773
- ...props
774
- }
775
- ),
776
- /* @__PURE__ */ jsx19("span", { className: trackClass, "aria-hidden": true, children: /* @__PURE__ */ jsx19("span", { className: thumbClass }) })
777
- ] }),
778
- /* @__PURE__ */ jsxs13("span", { className: "flex min-w-0 flex-col gap-0.5", children: [
779
- /* @__PURE__ */ jsx19("span", { className: "text-sm font-medium text-foreground", children: label }),
780
- description ? /* @__PURE__ */ jsx19("span", { className: "text-xs text-muted-foreground", children: description }) : null
781
- ] })
782
- ]
783
- }
784
- );
785
- };
786
-
787
- // src/app/forms/SearchInput.tsx
788
- import { SearchIcon } from "lucide-react";
789
- import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
790
- var SearchInput = ({
791
- className,
792
- placeholder = "Search\u2026",
793
- ...props
794
- }) => {
795
- return /* @__PURE__ */ jsxs14(
796
- "label",
797
- {
798
- className: cn(
799
- "aui-app-search-input inline-flex min-w-[12rem] items-center gap-2",
800
- appSearchInputClass,
801
- className
802
- ),
803
- children: [
804
- /* @__PURE__ */ jsx20(SearchIcon, { className: "size-4 shrink-0 text-muted-foreground", "aria-hidden": true }),
805
- /* @__PURE__ */ jsx20(
806
- "input",
807
- {
808
- type: "search",
809
- placeholder,
810
- className: "min-w-0 flex-1 border-0 bg-transparent text-sm outline-none placeholder:text-muted-foreground/70",
811
- ...props
812
- }
813
- )
814
- ]
815
- }
816
- );
817
- };
818
-
819
- // src/app/forms/FormSection.tsx
820
- import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
821
- var FormSection = ({ title, children, className }) => {
822
- return /* @__PURE__ */ jsxs15("fieldset", { className: cn("aui-app-form-section", appSectionClass, "border-0 p-0", className), children: [
823
- title ? /* @__PURE__ */ jsx21("legend", { className: cn(appSectionTitleClass, "mb-3 px-0"), children: title }) : null,
824
- /* @__PURE__ */ jsx21("div", { className: "flex flex-col gap-4", children })
825
- ] });
826
- };
827
-
828
- // src/app/data/FilterBar.tsx
829
- import { jsx as jsx22 } from "react/jsx-runtime";
830
- var FilterBar = ({ children, className }) => {
831
- return /* @__PURE__ */ jsx22(
832
- "div",
833
- {
834
- className: cn("aui-app-filter-bar", appFilterBarClass, className),
835
- role: "toolbar",
836
- "aria-label": "Filters",
837
- children
838
- }
839
- );
840
- };
841
-
842
- // src/app/data/DataTable.tsx
843
- import { useMemo, useState as useState2 } from "react";
844
- import { ArrowDownIcon, ArrowUpDownIcon, ArrowUpIcon } from "lucide-react";
845
- import { jsx as jsx23, jsxs as jsxs16 } from "react/jsx-runtime";
846
- var shellClass2 = "overflow-hidden rounded-xl border border-border bg-card shadow-card";
847
- var tableClass = "w-full border-collapse bg-transparent text-sm";
848
- var headCellClass = "border-b border-border/60 bg-transparent px-4 py-2.5 text-left text-xs font-medium uppercase tracking-wide text-muted-foreground";
849
- var bodyCellClass = "border-b border-border/40 bg-transparent px-4 py-2.5 text-foreground";
850
- var rowClass = "bg-transparent transition-colors hover:bg-foreground/[0.03] data-[clickable=true]:cursor-pointer";
851
- var footCellClass = "border-t border-border/60 bg-transparent px-4 py-2.5 text-xs text-muted-foreground";
852
- var footInnerClass = "flex flex-wrap items-center gap-2";
853
- var emptyCellClass = "bg-transparent px-4 py-10 text-center text-sm text-muted-foreground";
854
- var sortButtonClass = "group inline-flex min-w-0 items-center gap-1.5 rounded-md -mx-1 px-1 py-0.5 text-left font-medium text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/10";
855
- var stickyHeadClass = "sticky top-0 z-[1] bg-card/95 shadow-[0_1px_0_0_hsl(var(--border)/0.5)] backdrop-blur-sm [&_th]:bg-card/95";
856
- var alignClass = {
857
- left: "text-left",
858
- center: "text-center",
859
- right: "text-right"
860
- };
861
- function compareSortValues(a, b) {
862
- if (a == null && b == null) return 0;
863
- if (a == null) return 1;
864
- if (b == null) return -1;
865
- if (a instanceof Date && b instanceof Date) return a.getTime() - b.getTime();
866
- if (typeof a === "number" && typeof b === "number") return a - b;
867
- if (typeof a === "boolean" && typeof b === "boolean") return Number(a) - Number(b);
868
- return String(a).localeCompare(String(b), void 0, { sensitivity: "base" });
869
- }
870
- function nextSort(current, columnId) {
871
- if (current?.columnId !== columnId) {
872
- return { columnId, direction: "asc" };
873
- }
874
- if (current.direction === "asc") {
875
- return { columnId, direction: "desc" };
876
- }
877
- return null;
878
- }
879
- function SortIndicator({
880
- active,
881
- direction
882
- }) {
883
- const iconClass = "size-3.5 shrink-0 opacity-60 group-hover:opacity-100";
884
- if (!active) {
885
- return /* @__PURE__ */ jsx23(ArrowUpDownIcon, { className: iconClass, "aria-hidden": true });
886
- }
887
- if (direction === "desc") {
888
- return /* @__PURE__ */ jsx23(ArrowDownIcon, { className: iconClass, "aria-hidden": true });
889
- }
890
- return /* @__PURE__ */ jsx23(ArrowUpIcon, { className: iconClass, "aria-hidden": true });
891
- }
892
- function DataTable({
893
- columns,
894
- rows,
895
- getRowKey,
896
- emptyTitle = "No data",
897
- emptyDescription,
898
- emptyMode = "replace",
899
- className,
900
- sort: sortProp,
901
- defaultSort = null,
902
- onSortChange,
903
- showRowCount = false,
904
- rowCountLabel,
905
- footer,
906
- onRowClick,
907
- stickyHeader = false,
908
- dense = false,
909
- caption
910
- }) {
911
- const [uncontrolledSort, setUncontrolledSort] = useState2(
912
- defaultSort
913
- );
914
- const isSortControlled = sortProp !== void 0;
915
- const sort = isSortControlled ? sortProp : uncontrolledSort;
916
- const setSort = (next) => {
917
- if (!isSortControlled) {
918
- setUncontrolledSort(next);
919
- }
920
- onSortChange?.(next);
921
- };
922
- const sortedRows = useMemo(() => {
923
- if (!sort) return rows;
924
- const column = columns.find((col) => col.id === sort.columnId);
925
- if (!column?.sortable) return rows;
926
- const getValue = column.sortValue ?? ((row) => {
927
- const rendered = column.cell(row);
928
- if (rendered === null || rendered === void 0 || typeof rendered === "string" || typeof rendered === "number" || typeof rendered === "boolean") {
929
- return rendered;
930
- }
931
- return String(rendered);
932
- });
933
- return [...rows].sort((a, b) => {
934
- const cmp = compareSortValues(getValue(a), getValue(b));
935
- return sort.direction === "asc" ? cmp : -cmp;
936
- });
937
- }, [columns, rows, sort]);
938
- const cellPad = dense ? "px-3 py-2" : void 0;
939
- const headPad = dense ? "px-3 py-2" : void 0;
940
- if (rows.length === 0 && emptyMode === "replace") {
941
- return /* @__PURE__ */ jsx23(EmptyState, { title: emptyTitle, description: emptyDescription, className });
942
- }
943
- const rowCountText = rowCountLabel?.(sortedRows.length) ?? `${sortedRows.length} row${sortedRows.length === 1 ? "" : "s"}`;
944
- const hasFoot = Boolean((showRowCount || footer) && sortedRows.length > 0);
945
- return /* @__PURE__ */ jsx23("div", { className: cn("aui-app-data-table", shellClass2, className), children: /* @__PURE__ */ jsx23("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs16("table", { className: tableClass, children: [
946
- caption ? /* @__PURE__ */ jsx23("caption", { className: "sr-only", children: caption }) : null,
947
- /* @__PURE__ */ jsx23("thead", { className: cn(stickyHeader && stickyHeadClass), children: /* @__PURE__ */ jsx23("tr", { children: columns.map((col) => {
948
- const isSorted = sort?.columnId === col.id;
949
- const ariaSort = col.sortable ? isSorted ? sort.direction === "asc" ? "ascending" : "descending" : "none" : void 0;
950
- const headerContent = col.sortable ? /* @__PURE__ */ jsxs16(
951
- "button",
952
- {
953
- type: "button",
954
- className: sortButtonClass,
955
- onClick: () => setSort(nextSort(sort, col.id)),
956
- children: [
957
- /* @__PURE__ */ jsx23("span", { className: "truncate", children: col.header }),
958
- /* @__PURE__ */ jsx23(SortIndicator, { active: Boolean(isSorted), direction: sort?.direction })
959
- ]
960
- }
961
- ) : col.header;
962
- return /* @__PURE__ */ jsx23(
963
- "th",
964
- {
965
- scope: "col",
966
- "aria-sort": ariaSort,
967
- className: cn(
968
- headCellClass,
969
- headPad,
970
- col.align && alignClass[col.align],
971
- col.headerClassName
972
- ),
973
- children: headerContent
974
- },
975
- col.id
976
- );
977
- }) }) }),
978
- /* @__PURE__ */ jsx23("tbody", { className: cn(!hasFoot && "[&_tr:last-child_td]:border-b-0"), children: sortedRows.length === 0 ? /* @__PURE__ */ jsx23("tr", { children: /* @__PURE__ */ jsx23("td", { colSpan: columns.length, className: emptyCellClass, children: /* @__PURE__ */ jsxs16("div", { className: "flex flex-col items-center gap-1", children: [
979
- /* @__PURE__ */ jsx23("p", { className: "font-medium text-foreground", children: emptyTitle }),
980
- emptyDescription ? /* @__PURE__ */ jsx23("p", { className: "max-w-sm text-muted-foreground", children: emptyDescription }) : null
981
- ] }) }) }) : sortedRows.map((row) => /* @__PURE__ */ jsx23(
982
- "tr",
983
- {
984
- className: rowClass,
985
- "data-clickable": onRowClick ? "true" : void 0,
986
- onClick: onRowClick ? () => onRowClick(row) : void 0,
987
- onKeyDown: onRowClick ? (event) => {
988
- if (event.key === "Enter" || event.key === " ") {
989
- event.preventDefault();
990
- onRowClick(row);
991
- }
992
- } : void 0,
993
- tabIndex: onRowClick ? 0 : void 0,
994
- role: onRowClick ? "button" : void 0,
995
- children: columns.map((col) => /* @__PURE__ */ jsx23(
996
- "td",
997
- {
998
- className: cn(
999
- bodyCellClass,
1000
- cellPad,
1001
- col.align && alignClass[col.align],
1002
- col.className
1003
- ),
1004
- children: col.cell(row)
1005
- },
1006
- col.id
1007
- ))
1008
- },
1009
- getRowKey(row)
1010
- )) }),
1011
- hasFoot ? /* @__PURE__ */ jsx23("tfoot", { children: /* @__PURE__ */ jsx23("tr", { children: /* @__PURE__ */ jsx23("td", { colSpan: columns.length, className: footCellClass, children: /* @__PURE__ */ jsxs16(
1012
- "div",
1013
- {
1014
- className: cn(
1015
- footInnerClass,
1016
- showRowCount && footer ? "justify-between" : "justify-start"
1017
- ),
1018
- children: [
1019
- showRowCount ? /* @__PURE__ */ jsx23("span", { children: rowCountText }) : null,
1020
- footer
1021
- ]
1022
- }
1023
- ) }) }) }) : null
1024
- ] }) }) });
1025
- }
1026
-
1027
- // src/app/data/ChartPanel.tsx
1028
- import { jsx as jsx24, jsxs as jsxs17 } from "react/jsx-runtime";
1029
- var chartEmbedClass = "[&_.aui-artifact-root]:my-0 [&_.aui-artifact-root]:rounded-none [&_.aui-artifact-root]:border-0 [&_.aui-artifact-root]:bg-transparent [&_.aui-artifact-root]:shadow-none";
1030
- var ChartPanel = ({
1031
- title,
1032
- artifact,
1033
- children,
1034
- actions,
1035
- className
1036
- }) => {
1037
- const body = children ?? (artifact ? /* @__PURE__ */ jsx24("div", { className: chartEmbedClass, children: /* @__PURE__ */ jsx24(ChartArtifactView, { artifact }) }) : null);
1038
- return /* @__PURE__ */ jsxs17("div", { className: cn("aui-app-chart-panel", appChartPanelClass, className), children: [
1039
- title || actions ? /* @__PURE__ */ jsxs17("div", { className: "flex items-center justify-between gap-2", children: [
1040
- title ? /* @__PURE__ */ jsx24("h3", { className: appChartPanelTitleClass, children: title }) : /* @__PURE__ */ jsx24("span", {}),
1041
- actions
1042
- ] }) : null,
1043
- /* @__PURE__ */ jsx24("div", { className: "min-h-[12rem] w-full", children: body })
1044
- ] });
1045
- };
1046
-
1047
- export {
1048
- appPageColumnClass,
1049
- appShellTopbarInsetClass,
1050
- appShellInsetTopClass,
1051
- appSurfaceCardClass,
1052
- appStatTileClass,
1053
- appFilterBarClass,
1054
- appSearchInputClass,
1055
- useAppShellChat,
1056
- AppShell,
1057
- AppShellTopbar,
1058
- AppShellChatTrigger,
1059
- PageHeader,
1060
- Page,
1061
- Section,
1062
- AppCopilotProvider,
1063
- useAppCopilotContext,
1064
- AppChatPanel,
1065
- SurfaceCard,
1066
- StatTile,
1067
- EmptyState,
1068
- StatusBadge,
1069
- AppConfirmDialog,
1070
- SubNav,
1071
- Breadcrumbs,
1072
- Field,
1073
- FieldInput,
1074
- FieldTextarea,
1075
- FieldSelect,
1076
- FieldSwitch,
1077
- SearchInput,
1078
- FormSection,
1079
- FilterBar,
1080
- DataTable,
1081
- ChartPanel
1082
- };