@timbal-ai/timbal-react 0.6.1 → 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.
- package/CHANGELOG.md +37 -0
- package/README.md +24 -5
- package/dist/app.cjs +2282 -738
- package/dist/app.d.cts +4 -1
- package/dist/app.d.ts +4 -1
- package/dist/app.esm.js +58 -5
- package/dist/button-CIKzUrJI.d.cts +18 -0
- package/dist/button-CIKzUrJI.d.ts +18 -0
- package/dist/chart-artifact-BFDz8Tf9.d.ts +756 -0
- package/dist/chart-artifact-bWUa-iSG.d.cts +756 -0
- package/dist/chat.cjs +872 -562
- package/dist/chat.d.cts +2 -2
- package/dist/chat.d.ts +2 -2
- package/dist/chat.esm.js +3 -3
- package/dist/{chunk-4TCJQSIX.esm.js → chunk-2XZ3S4OP.esm.js} +14 -3
- package/dist/chunk-533MK5EA.esm.js +2294 -0
- package/dist/{chunk-OVHR7J3J.esm.js → chunk-7O5VY3TP.esm.js} +38 -11
- package/dist/{chunk-WLTW56MC.esm.js → chunk-N3PYVTY5.esm.js} +2 -2
- package/dist/{chunk-IYENDIRY.esm.js → chunk-TDIJHV4I.esm.js} +1 -1
- package/dist/{chunk-YJQLLFKP.esm.js → chunk-TLUF2RUL.esm.js} +813 -507
- package/dist/{chunk-OFHLFNJH.esm.js → chunk-Z27GBSOT.esm.js} +3 -1
- package/dist/index.cjs +2587 -1016
- package/dist/index.d.cts +6 -5
- package/dist/index.d.ts +6 -5
- package/dist/index.esm.js +57 -7
- package/dist/{layout-CQWngNQ7.d.ts → layout-BTJyU8wd.d.ts} +1 -1
- package/dist/{layout-B9VayJhZ.d.cts → layout-C2G-FcER.d.cts} +1 -1
- package/dist/studio.cjs +1127 -788
- package/dist/studio.d.cts +1 -1
- package/dist/studio.d.ts +1 -1
- package/dist/studio.esm.js +6 -6
- package/dist/{timbal-v2-button-F4-z7m33.d.ts → timbal-v2-button-CNfdwGq4.d.cts} +1 -1
- package/dist/{timbal-v2-button-F4-z7m33.d.cts → timbal-v2-button-CNfdwGq4.d.ts} +1 -1
- package/dist/ui.cjs +12 -3
- package/dist/ui.d.cts +5 -16
- package/dist/ui.d.ts +5 -16
- package/dist/ui.esm.js +2 -2
- package/dist/{welcome-BOizSp5h.d.ts → welcome-BBmB3tl7.d.ts} +4 -3
- package/dist/{welcome--80i_O0p.d.cts → welcome-C89Mgdaw.d.cts} +4 -3
- package/package.json +2 -1
- package/vite/local-dev.mjs +45 -3
- package/dist/chart-artifact-C71dk4xI.d.ts +0 -329
- package/dist/chart-artifact-CPEpOmtV.d.cts +0 -329
- package/dist/chunk-M4V6Q6XO.esm.js +0 -1082
package/dist/app.cjs
CHANGED
|
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/app.ts
|
|
31
31
|
var app_exports = {};
|
|
32
32
|
__export(app_exports, {
|
|
33
|
+
APP_KIT_AGENT_INSTRUCTIONS: () => APP_KIT_AGENT_INSTRUCTIONS,
|
|
33
34
|
AppChatPanel: () => AppChatPanel,
|
|
34
35
|
AppConfirmDialog: () => AppConfirmDialog,
|
|
35
36
|
AppCopilotProvider: () => AppCopilotProvider,
|
|
@@ -37,23 +38,47 @@ __export(app_exports, {
|
|
|
37
38
|
AppShellChatTrigger: () => AppShellChatTrigger,
|
|
38
39
|
AppShellTopbar: () => AppShellTopbar,
|
|
39
40
|
Breadcrumbs: () => Breadcrumbs,
|
|
41
|
+
Button: () => Button,
|
|
42
|
+
CHART_PALETTE: () => CHART_PALETTE,
|
|
40
43
|
ChartArtifactView: () => ChartArtifactView,
|
|
41
44
|
ChartPanel: () => ChartPanel,
|
|
45
|
+
ConnectionRow: () => ConnectionRow,
|
|
46
|
+
ConnectionRowList: () => ConnectionRowList,
|
|
47
|
+
DangerZone: () => DangerZone,
|
|
48
|
+
DangerZoneAction: () => DangerZoneAction,
|
|
42
49
|
DataTable: () => DataTable,
|
|
43
|
-
|
|
50
|
+
DescriptionList: () => DescriptionList,
|
|
51
|
+
EmptyState: () => EmptyState,
|
|
52
|
+
ExpandableSection: () => ExpandableSection,
|
|
44
53
|
Field: () => Field,
|
|
45
54
|
FieldInput: () => FieldInput,
|
|
55
|
+
FieldRow: () => FieldRow,
|
|
46
56
|
FieldSelect: () => FieldSelect,
|
|
47
57
|
FieldSwitch: () => FieldSwitch,
|
|
48
58
|
FieldTextarea: () => FieldTextarea,
|
|
49
59
|
FilterBar: () => FilterBar,
|
|
60
|
+
FloatingUnsavedChangesBar: () => FloatingUnsavedChangesBar,
|
|
50
61
|
FormSection: () => FormSection,
|
|
62
|
+
INTEGRATION_CATALOG_CARD_HEIGHT_CLASS: () => INTEGRATION_CATALOG_CARD_HEIGHT_CLASS,
|
|
63
|
+
InfoCard: () => InfoCard,
|
|
64
|
+
IntegrationCard: () => IntegrationCard,
|
|
65
|
+
IntegrationsEmptyState: () => IntegrationsEmptyState,
|
|
66
|
+
LineAreaChart: () => LineAreaChart,
|
|
67
|
+
MetricChartCard: () => MetricChartCard,
|
|
68
|
+
MetricRow: () => MetricRow,
|
|
69
|
+
MetricTile: () => MetricTile,
|
|
51
70
|
Page: () => Page,
|
|
52
71
|
PageHeader: () => PageHeader,
|
|
72
|
+
PlanBadge: () => PlanBadge,
|
|
73
|
+
ResourceCard: () => ResourceCard,
|
|
53
74
|
SearchInput: () => SearchInput,
|
|
54
75
|
Section: () => Section,
|
|
76
|
+
SettingsSection: () => SettingsSection,
|
|
77
|
+
SettingsSectionHeader: () => SettingsSectionHeader,
|
|
78
|
+
Sparkline: () => Sparkline,
|
|
55
79
|
StatTile: () => StatTile,
|
|
56
80
|
StatusBadge: () => StatusBadge,
|
|
81
|
+
StatusDot: () => StatusDot,
|
|
57
82
|
SubNav: () => SubNav,
|
|
58
83
|
SurfaceCard: () => SurfaceCard,
|
|
59
84
|
TimbalChat: () => TimbalChat,
|
|
@@ -64,11 +89,197 @@ __export(app_exports, {
|
|
|
64
89
|
appShellTopbarInsetClass: () => appShellTopbarInsetClass,
|
|
65
90
|
appStatTileClass: () => appStatTileClass,
|
|
66
91
|
appSurfaceCardClass: () => appSurfaceCardClass,
|
|
92
|
+
connectionRowListClass: () => connectionRowListClass,
|
|
67
93
|
useAppCopilotContext: () => useAppCopilotContext,
|
|
68
94
|
useAppShellChat: () => useAppShellChat
|
|
69
95
|
});
|
|
70
96
|
module.exports = __toCommonJS(app_exports);
|
|
71
97
|
|
|
98
|
+
// src/app/agent-instructions.ts
|
|
99
|
+
var APP_KIT_AGENT_INSTRUCTIONS = `
|
|
100
|
+
## App kit (@timbal-ai/timbal-react/app)
|
|
101
|
+
|
|
102
|
+
Build **dashboard and operations UIs** with React components. Import from \`@timbal-ai/timbal-react/app\` (or the main package entry if your app already uses it).
|
|
103
|
+
|
|
104
|
+
### Creative freedom (read this first)
|
|
105
|
+
|
|
106
|
+
You are **not** required to copy any example layout, page title, section order, or visual theme.
|
|
107
|
+
|
|
108
|
+
- **Do** invent layouts that fit the user's domain (CRM, inventory, billing, internal tools, etc.).
|
|
109
|
+
- **Do** pick only the components you need; skip shell, sidebar, or copilot when the task does not need them.
|
|
110
|
+
- **Do** vary density, grid columns, navigation patterns, and copy \u2014 as long as you follow the **design guidelines** below.
|
|
111
|
+
- **Do not** treat \`examples/app-kit/reference/\` as a template to clone (no default "Operations" dashboard with sidebar + three KPI tiles + SubNav + table unless the user asked for that).
|
|
112
|
+
- **Do** use \`examples/app-kit/recipes/\` as **short grammar examples** (one concern per file), not as a full app blueprint.
|
|
113
|
+
|
|
114
|
+
When in doubt: compose from the **component menu** + **guidelines**, then adapt creatively to the request.
|
|
115
|
+
|
|
116
|
+
### Module layout (source folders)
|
|
117
|
+
|
|
118
|
+
Presentational groups \u2014 import from the package root, not from these paths:
|
|
119
|
+
|
|
120
|
+
| Folder | Components |
|
|
121
|
+
|--------|------------|
|
|
122
|
+
| \`data/\` | \`MetricRow\`, \`MetricChartCard\`, \`MetricTile\`, \`DataTable\`, \`FilterBar\`, \`ChartPanel\` |
|
|
123
|
+
| \`integrations/\` | \`IntegrationCard\`, \`ConnectionRow\`, \`ConnectionRowList\`, \`IntegrationsEmptyState\`, \`PlanBadge\` |
|
|
124
|
+
| \`settings/\` | \`SettingsSection\`, \`FieldRow\`, \`DangerZone\`, \`FloatingUnsavedChangesBar\` |
|
|
125
|
+
| \`surfaces/\` | \`StatTile\`, \`InfoCard\`, \`ResourceCard\`, \`DescriptionList\`, \`ExpandableSection\`, \`StatusDot\`, \`StatusBadge\`, \`EmptyState\` |
|
|
126
|
+
| \`layout/\` | \`AppShell\`, \`Page\`, \`Section\` |
|
|
127
|
+
| \`charts\` (re-exported) | \`LineAreaChart\`, \`Sparkline\`, \`CHART_PALETTE\` |
|
|
128
|
+
|
|
129
|
+
Also re-exported: \`Button\`, \`TimbalChat\`, \`ChartArtifactView\`, \`APP_KIT_AGENT_INSTRUCTIONS\`.
|
|
130
|
+
|
|
131
|
+
### Design guidelines (required)
|
|
132
|
+
|
|
133
|
+
| Area | Rule |
|
|
134
|
+
|------|------|
|
|
135
|
+
| **Copilot** | Use \`AppCopilotProvider\` for page context (\`useAppCopilotContext\`). Copilot is a **floating overlay** via \`AppShell\` \`chat={<AppChatPanel />}\` \u2014 not a sidebar column that shrinks main content. |
|
|
136
|
+
| **Chat panel** | \`AppChatPanel\` only; \`Thread\` uses \`variant="panel"\` internally. Dismiss with **X**; trigger is a **text-only** pill (e.g. "Assistant") \u2014 **no** MessageSquare or chat icons on the shell trigger. |
|
|
137
|
+
| **Context** | Do not show raw JSON context in the panel header; keep context in \`AppCopilotProvider\` only. |
|
|
138
|
+
| **Theming** | Use semantic Tailwind tokens (\`bg-background\`, \`text-foreground\`, \`border-border\`, \`bg-elevated-from\`, etc.) from the host app's \`styles.css\`. Optional: \`import "@timbal-ai/timbal-react/styles.css"\`. |
|
|
139
|
+
| **Layout chrome** | \`Page\` \u2192 \`Section\` for main content hierarchy. \`AppShellTopbar\` for global actions (auth, theme). |
|
|
140
|
+
| **Data** | Prefer \`DataTable\` with typed \`columns\` / \`rows\` / \`getRowKey\`; use \`ChartPanel\` with \`ChartArtifact\` for charts. |
|
|
141
|
+
| **Modals** | Use \`AppConfirmDialog\` for destructive/export confirmations. |
|
|
142
|
+
| **Metrics** | Overview KPIs \u2192 \`MetricRow\` or \`MetricChartCard\` (not four separate heavy cards). Values use **normal** font weight, not bold. |
|
|
143
|
+
| **Integrations** | Catalog \u2192 \`IntegrationCard\` grid; connected list \u2192 \`ConnectionRow\` inside \`ConnectionRowList\`. Footer CTAs: \`Button variant="secondary"\`. |
|
|
144
|
+
| **Anti-slop** | No loud green/red trend pills on every tile; no \`bg-card\` flat grids when platform chrome exists; avoid recycling demo names ("Operations", mock workforce lists). |
|
|
145
|
+
|
|
146
|
+
### Accessibility (required)
|
|
147
|
+
|
|
148
|
+
| Area | Rule |
|
|
149
|
+
|------|------|
|
|
150
|
+
| **Headings** | Use \`Page\` / \`Section\` titles for hierarchy. Card titles inside premade components are already \`h3\`/\`h4\`. |
|
|
151
|
+
| **Selectable metrics** | \`MetricChartCard\` / \`MetricRow\` tiles are buttons with \`aria-pressed\`. Pass \`metricsAriaLabel\` when the default "Metrics" is too vague. |
|
|
152
|
+
| **Charts** | \`LineAreaChart\` exposes \`role="img"\` + \`aria-label\`; \`MetricChartCard\` updates the chart label when the active metric changes (\`aria-live\` on the plot region). |
|
|
153
|
+
| **Integration cards** | Whole-card click \u2192 \`onClick\` only (no nested footer button). With footer \`action\`, render a static \`article\` \u2014 do not wrap the CTA in a card button. Pass \`ariaLabel\` when \`name\` is not plain text. |
|
|
154
|
+
| **Lists** | Wrap \`ConnectionRow\` in \`ConnectionRowList\` (\`role="list"\`); rows expose \`role="listitem"\`. |
|
|
155
|
+
| **Status** | Pair \`StatusDot\` / \`StatusBadge\` with visible text \u2014 do not rely on color alone. |
|
|
156
|
+
| **Forms** | Use \`Field*\` components; errors use \`role="alert"\`. |
|
|
157
|
+
| **Custom labels** | \`ariaLabel\` props exist on \`MetricTile\`, \`IntegrationCard\`, \`ConnectionRow\`, \`ResourceCard\` when slots are icons or rich nodes. |
|
|
158
|
+
|
|
159
|
+
### Component menu
|
|
160
|
+
|
|
161
|
+
| Component | Use for |
|
|
162
|
+
|-----------|---------|
|
|
163
|
+
| \`AppShell\` | Shell: optional \`sidebar\`, \`topbar\`, main \`children\`, optional floating \`chat\`. Props: \`chatTriggerLabel\`, \`chatCollapsible\`, \`chatWidth\`, \`chatHeight\`, controlled \`chatOpen\`. |
|
|
164
|
+
| \`AppShellTopbar\` | Full-width top bar: \`start\`, \`actions\` slots. |
|
|
165
|
+
| \`AppCopilotProvider\` | React context for copilot-aware tools (page, filters, selection, etc.). |
|
|
166
|
+
| \`AppChatPanel\` | Floating thread: \`workforceId\`, \`welcome\`, \`debug\`. |
|
|
167
|
+
| \`useAppShellChat\` | Custom open/close trigger when \`hideChatTrigger\` on shell. |
|
|
168
|
+
| \`Page\` | Page title, description, \`breadcrumbs\`, \`actions\`, children. |
|
|
169
|
+
| \`Section\` | Titled block inside a page. |
|
|
170
|
+
| \`SubNav\` | In-page tabs: \`items\`, \`activeId\`, \`onChange\`. |
|
|
171
|
+
| \`Breadcrumbs\` | Trail: \`items: [{ label, href? }]\`. |
|
|
172
|
+
| \`Button\` | Actions \u2014 \`variant="secondary"\` for catalog/secondary CTAs; \`variant="default"\` for primary. |
|
|
173
|
+
| \`StatTile\` | Single KPI in its own card (grid of scattered stats). Prefer \`MetricRow\` for a unified overview strip. |
|
|
174
|
+
| \`StatusBadge\` | Status pill: \`tone\` (\`success\`, \`warn\`, \u2026), children. |
|
|
175
|
+
| \`FilterBar\` | Horizontal filter row (wraps \`SearchInput\`, buttons, etc.). |
|
|
176
|
+
| \`SearchInput\` | Filter field with consistent app styling. |
|
|
177
|
+
| \`DataTable\` | Sortable table: \`columns\`, \`rows\`, \`getRowKey\`, optional \`sort\` / \`onSortChange\`, \`emptyTitle\`, \`showRowCount\`, \`caption\` for screen readers. |
|
|
178
|
+
| \`ChartPanel\` | Same shell as \`MetricChartCard\`: title row (\`px-4 pt-4\`), flush plot (\`pt-2\` only). Pass \`title\` + \`artifact\` (omit \`artifact.title\` to avoid duplicates) or \`children\`. |
|
|
179
|
+
| \`FieldInput\`, \`FieldTextarea\`, \`FieldSelect\`, \`FieldSwitch\` | Settings-style forms with labels and hints. |
|
|
180
|
+
| \`FormSection\` | Grouped form block. |
|
|
181
|
+
| \`AppConfirmDialog\` | Confirm/cancel modal: \`open\`, \`onOpenChange\`, \`title\`, \`description\`, \`onConfirm\`. |
|
|
182
|
+
| \`SurfaceCard\`, \`EmptyState\` | Generic surfaces when needed. |
|
|
183
|
+
| \`TimbalChat\` | Re-export if you need chat outside \`AppChatPanel\`. |
|
|
184
|
+
|
|
185
|
+
#### Charts & metrics
|
|
186
|
+
|
|
187
|
+
| Component | Use for |
|
|
188
|
+
|-----------|---------|
|
|
189
|
+
| \`LineAreaChart\` | Chart engine. Props: \`data\`, \`xKey\`, \`series\`, \`variant\` (\`"area"\`), \`layout\` (\`"flush"\`), \`height\`, \`ariaLabel\`, \`formatX\`, \`formatValue\`. |
|
|
190
|
+
| \`Sparkline\` | Tiny inline trend (table cells): \`data\`, \`color\`, \`area\`. |
|
|
191
|
+
| \`MetricTile\` | Low-level KPI cell \u2014 prefer \`MetricRow\` / \`MetricChartCard\` instead of hand-wiring tiles. |
|
|
192
|
+
| \`MetricRow\` | KPI strip in one elevated card (no chart). Props: \`metrics: [{ id, label, value, unit?, trend? }]\`, optional \`onMetricChange\`, \`metricsAriaLabel\`. |
|
|
193
|
+
| \`MetricChartCard\` | KPI strip + flush chart; tile click swaps series. Same metrics shape + \`data\` per metric. Default chart height 300. |
|
|
194
|
+
|
|
195
|
+
#### Settings
|
|
196
|
+
|
|
197
|
+
| Component | Use for |
|
|
198
|
+
|-----------|---------|
|
|
199
|
+
| \`SettingsSection\` | Two-column settings block: \`title\` + \`description\` rail on the left, controls on the right. |
|
|
200
|
+
| \`FieldRow\` | Labeled control row: \`label\`, \`description\`, \`inline\` (right-aligned control for switches). |
|
|
201
|
+
| \`DangerZone\` + \`DangerZoneAction\` | Destructive-actions container with destructive border. |
|
|
202
|
+
| \`FloatingUnsavedChangesBar\` | Portaled discard/save pill: \`visible\`, \`onDiscard\`, \`onSave\`, \`isSaving\`. |
|
|
203
|
+
|
|
204
|
+
#### Integrations & resources
|
|
205
|
+
|
|
206
|
+
| Component | Use for |
|
|
207
|
+
|-----------|---------|
|
|
208
|
+
| \`IntegrationCard\` | Catalog tile: \`logo\`, \`name\`, \`description\`, \`badge\`, \`status\`, footer \`action\` **or** whole-card \`onClick\` (never both). |
|
|
209
|
+
| \`ConnectionRow\` | One connected provider row: \`logo\`, \`name\`, \`meta\`, \`badge\`, \`action\`. |
|
|
210
|
+
| \`ConnectionRowList\` | Wrapper for rows (\`role="list"\`) \u2014 use instead of raw class strings. |
|
|
211
|
+
| \`IntegrationsEmptyState\` | Empty catalog hero: \`icon\`, \`title\`, \`description\`, \`action\`. |
|
|
212
|
+
| \`PlanBadge\` | Neutral tier chip on catalog cards. |
|
|
213
|
+
| \`ResourceCard\` | Project/agent/dataset card on elevated surface + logo tile: \`media\`, \`title\`, \`subtitle\`, optional \`badge\`, \`footer\` (\`StatusDot\`), \`action\` (\`Sparkline\`). |
|
|
214
|
+
|
|
215
|
+
#### Surfaces & details
|
|
216
|
+
|
|
217
|
+
| Component | Use for |
|
|
218
|
+
|-----------|---------|
|
|
219
|
+
| \`InfoCard\` | Soft callout: \`icon\`, \`title\`, body, \`action\`, \`tone\` (\`info\`/\`success\`/\`warn\`/\`danger\`). |
|
|
220
|
+
| \`DescriptionList\` | Read-only key/value metadata: \`items: [{ label, value }]\`, optional \`stacked\`. |
|
|
221
|
+
| \`ExpandableSection\` | Collapsible block: \`title\`, \`icon\`, \`count\`, animated body (\`aria-expanded\` + \`aria-controls\`). |
|
|
222
|
+
| \`StatusDot\` | Status indicator dot: \`tone\`, \`label\`, \`pulse\`. |
|
|
223
|
+
|
|
224
|
+
Studio chrome (\`StudioSidebar\`, \`ModeToggle\`, \u2026) lives in \`@timbal-ai/timbal-react/studio\` \u2014 optional, not required for every dashboard.
|
|
225
|
+
|
|
226
|
+
### Recipe index (\`examples/app-kit/recipes/\`)
|
|
227
|
+
|
|
228
|
+
| Recipe file | Components to study |
|
|
229
|
+
|-------------|---------------------|
|
|
230
|
+
| \`metrics-row.tsx\` | \`Page\`, \`MetricRow\` |
|
|
231
|
+
| \`analytics-card.tsx\` | \`MetricChartCard\`, \`Button\` |
|
|
232
|
+
| \`integrations-grid.tsx\` | \`IntegrationCard\`, \`ConnectionRowList\`, \`PlanBadge\` |
|
|
233
|
+
| \`table-with-filters.tsx\` | \`FilterBar\`, \`DataTable\` |
|
|
234
|
+
| \`settings-page.tsx\` | \`SettingsSection\`, \`DangerZone\`, \`FloatingUnsavedChangesBar\` |
|
|
235
|
+
| \`resource-gallery.tsx\` | \`ResourceCard\`, \`StatusDot\`, \`Sparkline\` |
|
|
236
|
+
| \`charts-panel.tsx\` | \`ChartPanel\`, \`ChartArtifact\` |
|
|
237
|
+
| \`copilot-overlay.tsx\` | \`AppShell\`, \`AppChatPanel\` |
|
|
238
|
+
|
|
239
|
+
### Typical compositions
|
|
240
|
+
|
|
241
|
+
- **Metrics overview** \u2014 \`MetricRow\` or \`MetricChartCard\` (not four isolated stat cards with bold numbers).
|
|
242
|
+
- **Analytics** \u2014 \`MetricChartCard\`; header action: \`Button variant="secondary" size="sm"\`.
|
|
243
|
+
- **Table workspace** \u2014 \`Page\` + \`FilterBar\` + \`DataTable\` (+ \`StatusBadge\` / \`StatusDot\` in cells).
|
|
244
|
+
- **Settings** \u2014 \`Page\` + \`SettingsSection\`s + \`DangerZone\` + \`FloatingUnsavedChangesBar\`.
|
|
245
|
+
- **Integrations** \u2014 grid of \`IntegrationCard\`; \`ConnectionRowList\` for connected providers; \`IntegrationsEmptyState\` when empty.
|
|
246
|
+
- **Resource gallery** \u2014 grid of \`ResourceCard\`.
|
|
247
|
+
- **Copilot-assisted app** \u2014 \`AppCopilotProvider\` + \`AppShell\` with \`chat={<AppChatPanel workforceId="\u2026" />}\`.
|
|
248
|
+
|
|
249
|
+
### Example imports
|
|
250
|
+
|
|
251
|
+
\`\`\`tsx
|
|
252
|
+
import {
|
|
253
|
+
AppShell,
|
|
254
|
+
AppCopilotProvider,
|
|
255
|
+
AppChatPanel,
|
|
256
|
+
Page,
|
|
257
|
+
Section,
|
|
258
|
+
MetricRow,
|
|
259
|
+
MetricChartCard,
|
|
260
|
+
IntegrationCard,
|
|
261
|
+
ConnectionRow,
|
|
262
|
+
ConnectionRowList,
|
|
263
|
+
Button,
|
|
264
|
+
DataTable,
|
|
265
|
+
FilterBar,
|
|
266
|
+
} from "@timbal-ai/timbal-react/app";
|
|
267
|
+
\`\`\`
|
|
268
|
+
|
|
269
|
+
### Examples in this repo (for humans/tools)
|
|
270
|
+
|
|
271
|
+
| Path | Purpose |
|
|
272
|
+
|------|---------|
|
|
273
|
+
| \`examples/app-kit/recipes/*\` | **Recipes** \u2014 one pattern each (~20\u201380 lines). Use for capability, not layout. |
|
|
274
|
+
| \`examples/app-kit/reference/operations-dashboard.tsx\` | **Reference only** \u2014 full wired app; do not treat as the default generated layout. |
|
|
275
|
+
|
|
276
|
+
### Rules
|
|
277
|
+
|
|
278
|
+
- Prefer stable props documented above; avoid undocumented \`design/*\` class exports (\`connectionRowListClass\` is exported but \`ConnectionRowList\` is preferred).
|
|
279
|
+
- Match the user's domain language in titles and labels.
|
|
280
|
+
- For rich in-chat widgets, use **artifacts** (\`ARTIFACT_AGENT_INSTRUCTIONS\`) \u2014 app kit is for the **host application shell**.
|
|
281
|
+
`.trim();
|
|
282
|
+
|
|
72
283
|
// src/app/layout/AppShell.tsx
|
|
73
284
|
var import_react3 = require("motion/react");
|
|
74
285
|
var import_react4 = require("react");
|
|
@@ -174,6 +385,10 @@ var TIMBAL_V2_SWITCH_THUMB = cn(
|
|
|
174
385
|
TIMBAL_V2_ELEVATED_GRADIENT,
|
|
175
386
|
"border border-border/80 shadow-sm"
|
|
176
387
|
);
|
|
388
|
+
var TIMBAL_V2_ELEVATED_SURFACE = cn(
|
|
389
|
+
TIMBAL_V2_ELEVATED_GRADIENT,
|
|
390
|
+
"border border-border shadow-card"
|
|
391
|
+
);
|
|
177
392
|
var TIMBAL_V2_SECONDARY_CHROME = [
|
|
178
393
|
TIMBAL_V2_ELEVATED_GRADIENT,
|
|
179
394
|
"border border-border shadow-card",
|
|
@@ -181,6 +396,11 @@ var TIMBAL_V2_SECONDARY_CHROME = [
|
|
|
181
396
|
"hover:from-secondary-fill-hover-from hover:to-secondary-fill-hover-to",
|
|
182
397
|
"active:from-secondary-fill-active-from active:to-secondary-fill-active-to"
|
|
183
398
|
].join(" ");
|
|
399
|
+
var TIMBAL_V2_LOGO_TILE = cn(
|
|
400
|
+
"bg-gradient-to-b from-white to-neutral-100",
|
|
401
|
+
"border border-neutral-200",
|
|
402
|
+
"shadow-[0_1px_2px_-0.5px_rgba(0,0,0,0.08)]"
|
|
403
|
+
);
|
|
184
404
|
|
|
185
405
|
// src/design/classes.ts
|
|
186
406
|
var studioTopbarPillHeightClass = "h-[var(--studio-chrome-pill-height)] min-h-[var(--studio-chrome-pill-height)]";
|
|
@@ -312,10 +532,10 @@ var appSurfaceCardClass = cn(
|
|
|
312
532
|
);
|
|
313
533
|
var appStatTileClass = cn(
|
|
314
534
|
appSurfaceCardClass,
|
|
315
|
-
"flex flex-col gap-1"
|
|
535
|
+
"flex flex-col gap-1 px-4 py-3 shadow-none"
|
|
316
536
|
);
|
|
317
|
-
var appStatValueClass = "text-2xl font-
|
|
318
|
-
var appStatLabelClass = "text-
|
|
537
|
+
var appStatValueClass = "text-2xl font-normal tracking-tight text-foreground tabular-nums";
|
|
538
|
+
var appStatLabelClass = "text-xs font-normal text-muted-foreground";
|
|
319
539
|
var appFilterBarClass = cn(
|
|
320
540
|
"flex flex-wrap items-center gap-2",
|
|
321
541
|
studioTopbarPillHeightClass
|
|
@@ -339,7 +559,6 @@ var appEmptyStateClass = cn(
|
|
|
339
559
|
var appEmptyStateTitleClass = "text-base font-medium text-foreground";
|
|
340
560
|
var appEmptyStateDescriptionClass = "max-w-sm text-sm text-muted-foreground";
|
|
341
561
|
var appChartPanelClass = cn(appSurfaceCardClass, "flex flex-col gap-3");
|
|
342
|
-
var appChartPanelTitleClass = "text-sm font-medium text-foreground";
|
|
343
562
|
|
|
344
563
|
// src/design/sidebar-motion.ts
|
|
345
564
|
var STUDIO_SIDEBAR_EASE_ENTER = [0, 0, 0.2, 1];
|
|
@@ -636,7 +855,7 @@ var TimbalV2Button = React.forwardRef(function TimbalV2Button2({
|
|
|
636
855
|
isIconOnly = false,
|
|
637
856
|
isLoading = false,
|
|
638
857
|
fullWidth = false,
|
|
639
|
-
shape = "pill",
|
|
858
|
+
shape: _shape = "pill",
|
|
640
859
|
asChild = false,
|
|
641
860
|
className,
|
|
642
861
|
disabled,
|
|
@@ -646,7 +865,7 @@ var TimbalV2Button = React.forwardRef(function TimbalV2Button2({
|
|
|
646
865
|
}, ref) {
|
|
647
866
|
const isDisabled = disabled || isLoading;
|
|
648
867
|
const sizeClass = isIconOnly ? TIMBAL_V2_SIZE_ICON[size] : TIMBAL_V2_SIZE_HEIGHT[size];
|
|
649
|
-
const radiusClass =
|
|
868
|
+
const radiusClass = "rounded-full";
|
|
650
869
|
const sharedRootClass = cn(
|
|
651
870
|
"relative box-border inline-flex items-center justify-center gap-2 whitespace-nowrap border-0 text-sm font-normal shadow-none transition duration-200 ease-in-out",
|
|
652
871
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/60 focus-visible:ring-offset-1 focus-visible:ring-offset-background",
|
|
@@ -811,10 +1030,10 @@ function useAppCopilotContext() {
|
|
|
811
1030
|
var import_lucide_react9 = require("lucide-react");
|
|
812
1031
|
|
|
813
1032
|
// src/chat/thread.tsx
|
|
814
|
-
var
|
|
815
|
-
var
|
|
1033
|
+
var import_react34 = require("react");
|
|
1034
|
+
var import_react35 = require("@assistant-ui/react");
|
|
816
1035
|
var import_lucide_react8 = require("lucide-react");
|
|
817
|
-
var
|
|
1036
|
+
var import_react36 = require("motion/react");
|
|
818
1037
|
|
|
819
1038
|
// src/chat/attachment.tsx
|
|
820
1039
|
var import_react7 = require("react");
|
|
@@ -1187,292 +1406,476 @@ var import_react_markdown = require("@assistant-ui/react-markdown");
|
|
|
1187
1406
|
var import_remark_gfm = __toESM(require("remark-gfm"), 1);
|
|
1188
1407
|
var import_remark_math = __toESM(require("remark-math"), 1);
|
|
1189
1408
|
var import_rehype_katex = __toESM(require("rehype-katex"), 1);
|
|
1190
|
-
var
|
|
1409
|
+
var import_react21 = require("react");
|
|
1191
1410
|
var import_lucide_react4 = require("lucide-react");
|
|
1192
1411
|
|
|
1193
1412
|
// src/chat/syntax-highlighter.tsx
|
|
1194
|
-
var
|
|
1413
|
+
var import_react20 = require("react");
|
|
1195
1414
|
var import_core = require("shiki/core");
|
|
1196
1415
|
var import_javascript = require("shiki/engine/javascript");
|
|
1197
1416
|
|
|
1198
1417
|
// src/artifacts/registry.tsx
|
|
1199
|
-
var
|
|
1418
|
+
var import_react19 = require("react");
|
|
1200
1419
|
|
|
1201
1420
|
// src/artifacts/chart-artifact.tsx
|
|
1421
|
+
var import_react11 = require("react");
|
|
1422
|
+
|
|
1423
|
+
// src/charts/line-area-chart.tsx
|
|
1424
|
+
var import_react10 = require("react");
|
|
1425
|
+
|
|
1426
|
+
// src/charts/use-chart-width.ts
|
|
1202
1427
|
var import_react9 = require("react");
|
|
1428
|
+
function useChartWidth(initial = 640) {
|
|
1429
|
+
const ref = (0, import_react9.useRef)(null);
|
|
1430
|
+
const [width, setWidth] = (0, import_react9.useState)(initial);
|
|
1431
|
+
(0, import_react9.useEffect)(() => {
|
|
1432
|
+
const el = ref.current;
|
|
1433
|
+
if (!el || typeof ResizeObserver === "undefined") return;
|
|
1434
|
+
const ro = new ResizeObserver((entries) => {
|
|
1435
|
+
const w = entries[0]?.contentRect.width;
|
|
1436
|
+
if (w && w > 0) setWidth(w);
|
|
1437
|
+
});
|
|
1438
|
+
ro.observe(el);
|
|
1439
|
+
return () => ro.disconnect();
|
|
1440
|
+
}, []);
|
|
1441
|
+
return { ref, width };
|
|
1442
|
+
}
|
|
1203
1443
|
|
|
1204
|
-
// src/
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1444
|
+
// src/charts/geometry.ts
|
|
1445
|
+
function toNum(value) {
|
|
1446
|
+
const n = typeof value === "number" ? value : Number(value);
|
|
1447
|
+
return Number.isFinite(n) ? n : 0;
|
|
1448
|
+
}
|
|
1449
|
+
function monotoneLinePath(points) {
|
|
1450
|
+
const n = points.length;
|
|
1451
|
+
if (n === 0) return "";
|
|
1452
|
+
if (n === 1) return `M ${points[0].x},${points[0].y}`;
|
|
1453
|
+
if (n === 2) {
|
|
1454
|
+
return `M ${points[0].x},${points[0].y} L ${points[1].x},${points[1].y}`;
|
|
1455
|
+
}
|
|
1456
|
+
const tangents = monotoneTangents(points);
|
|
1457
|
+
let d = `M ${points[0].x},${points[0].y}`;
|
|
1458
|
+
for (let i = 0; i < n - 1; i++) {
|
|
1459
|
+
const p0 = points[i];
|
|
1460
|
+
const p1 = points[i + 1];
|
|
1461
|
+
const dx = (p1.x - p0.x) / 3;
|
|
1462
|
+
const c1x = p0.x + dx;
|
|
1463
|
+
const c1y = p0.y + dx * tangents[i];
|
|
1464
|
+
const c2x = p1.x - dx;
|
|
1465
|
+
const c2y = p1.y - dx * tangents[i + 1];
|
|
1466
|
+
d += ` C ${c1x},${c1y} ${c2x},${c2y} ${p1.x},${p1.y}`;
|
|
1467
|
+
}
|
|
1468
|
+
return d;
|
|
1469
|
+
}
|
|
1470
|
+
function monotoneAreaPath(points, baseY) {
|
|
1471
|
+
if (points.length === 0) return "";
|
|
1472
|
+
const line = monotoneLinePath(points);
|
|
1473
|
+
const last = points[points.length - 1];
|
|
1474
|
+
const first = points[0];
|
|
1475
|
+
return `${line} L ${last.x},${baseY} L ${first.x},${baseY} Z`;
|
|
1476
|
+
}
|
|
1477
|
+
function monotoneTangents(points) {
|
|
1478
|
+
const n = points.length;
|
|
1479
|
+
const slopes = new Array(n - 1);
|
|
1480
|
+
for (let i = 0; i < n - 1; i++) {
|
|
1481
|
+
const dx = points[i + 1].x - points[i].x || 1;
|
|
1482
|
+
slopes[i] = (points[i + 1].y - points[i].y) / dx;
|
|
1483
|
+
}
|
|
1484
|
+
const tangents = new Array(n);
|
|
1485
|
+
tangents[0] = slopes[0];
|
|
1486
|
+
tangents[n - 1] = slopes[n - 2];
|
|
1487
|
+
for (let i = 1; i < n - 1; i++) {
|
|
1488
|
+
const s0 = slopes[i - 1];
|
|
1489
|
+
const s1 = slopes[i];
|
|
1490
|
+
if (s0 * s1 <= 0) {
|
|
1491
|
+
tangents[i] = 0;
|
|
1492
|
+
} else {
|
|
1493
|
+
tangents[i] = (s0 + s1) / 2;
|
|
1224
1494
|
}
|
|
1225
|
-
|
|
1226
|
-
|
|
1495
|
+
}
|
|
1496
|
+
for (let i = 0; i < n - 1; i++) {
|
|
1497
|
+
const s = slopes[i];
|
|
1498
|
+
if (s === 0) {
|
|
1499
|
+
tangents[i] = 0;
|
|
1500
|
+
tangents[i + 1] = 0;
|
|
1501
|
+
continue;
|
|
1502
|
+
}
|
|
1503
|
+
const a = tangents[i] / s;
|
|
1504
|
+
const b = tangents[i + 1] / s;
|
|
1505
|
+
const h = Math.hypot(a, b);
|
|
1506
|
+
if (h > 3) {
|
|
1507
|
+
const t = 3 / h;
|
|
1508
|
+
tangents[i] = t * a * s;
|
|
1509
|
+
tangents[i + 1] = t * b * s;
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
return tangents;
|
|
1513
|
+
}
|
|
1514
|
+
function niceTicks(min, max, count = 4) {
|
|
1515
|
+
if (!Number.isFinite(min) || !Number.isFinite(max) || max === min) {
|
|
1516
|
+
return [min || 0];
|
|
1517
|
+
}
|
|
1518
|
+
const step = niceStep((max - min) / count);
|
|
1519
|
+
const start = Math.floor(min / step) * step;
|
|
1520
|
+
const out = [];
|
|
1521
|
+
for (let v = start; v <= max + step / 2; v += step) {
|
|
1522
|
+
out.push(round(v));
|
|
1523
|
+
}
|
|
1524
|
+
return out;
|
|
1525
|
+
}
|
|
1526
|
+
function niceStep(raw) {
|
|
1527
|
+
const exp = Math.floor(Math.log10(Math.abs(raw) || 1));
|
|
1528
|
+
const base = Math.pow(10, exp);
|
|
1529
|
+
const norm = raw / base;
|
|
1530
|
+
let nice = 1;
|
|
1531
|
+
if (norm >= 5) nice = 5;
|
|
1532
|
+
else if (norm >= 2) nice = 2;
|
|
1533
|
+
return nice * base;
|
|
1534
|
+
}
|
|
1535
|
+
function round(v) {
|
|
1536
|
+
return Math.round(v * 1e6) / 1e6;
|
|
1537
|
+
}
|
|
1538
|
+
function formatCompact(value, unit) {
|
|
1539
|
+
const abs = Math.abs(value);
|
|
1540
|
+
let s;
|
|
1541
|
+
if (abs >= 1e6) s = `${round(value / 1e6)}M`;
|
|
1542
|
+
else if (abs >= 1e3) s = `${round(value / 1e3)}k`;
|
|
1543
|
+
else s = String(round(value));
|
|
1544
|
+
return unit ? `${s}${unit}` : s;
|
|
1545
|
+
}
|
|
1227
1546
|
|
|
1228
|
-
// src/
|
|
1229
|
-
var
|
|
1230
|
-
var
|
|
1231
|
-
artifact
|
|
1232
|
-
}) => {
|
|
1233
|
-
const { type: _t, chartType = "bar", data = [] } = artifact;
|
|
1234
|
-
const xKey = artifact.xKey ?? inferXKey(data);
|
|
1235
|
-
const dataKeys = (0, import_react9.useMemo)(() => {
|
|
1236
|
-
if (Array.isArray(artifact.dataKey)) return artifact.dataKey;
|
|
1237
|
-
if (typeof artifact.dataKey === "string") return [artifact.dataKey];
|
|
1238
|
-
return inferDataKeys(data, xKey);
|
|
1239
|
-
}, [artifact.dataKey, data, xKey]);
|
|
1240
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ArtifactCard, { title: artifact.title, kind: "chart", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "aui-artifact-chart p-3", children: [
|
|
1241
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1242
|
-
ChartSvg,
|
|
1243
|
-
{
|
|
1244
|
-
chartType,
|
|
1245
|
-
data,
|
|
1246
|
-
xKey,
|
|
1247
|
-
dataKeys,
|
|
1248
|
-
unit: artifact.unit
|
|
1249
|
-
}
|
|
1250
|
-
),
|
|
1251
|
-
dataKeys.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Legend, { dataKeys })
|
|
1252
|
-
] }) });
|
|
1253
|
-
};
|
|
1254
|
-
var COLORS = [
|
|
1547
|
+
// src/charts/line-area-chart.tsx
|
|
1548
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1549
|
+
var CHART_PALETTE = [
|
|
1255
1550
|
"var(--primary, #6366f1)",
|
|
1256
|
-
"#
|
|
1551
|
+
"#10b981",
|
|
1257
1552
|
"#f59e0b",
|
|
1258
|
-
"#ef4444",
|
|
1259
1553
|
"#06b6d4",
|
|
1260
|
-
"#a855f7"
|
|
1554
|
+
"#a855f7",
|
|
1555
|
+
"#ef4444"
|
|
1261
1556
|
];
|
|
1262
|
-
var
|
|
1263
|
-
var
|
|
1264
|
-
var
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1557
|
+
var PAD_DEFAULT = { top: 12, right: 16, bottom: 26, left: 44 };
|
|
1558
|
+
var PAD_FLUSH = { top: 20, right: 0, bottom: 8, left: 0 };
|
|
1559
|
+
var LineAreaChart = ({
|
|
1560
|
+
data = [],
|
|
1561
|
+
xKey: xKeyProp,
|
|
1562
|
+
series: seriesProp,
|
|
1563
|
+
variant = "area",
|
|
1564
|
+
height = 240,
|
|
1565
|
+
unit,
|
|
1566
|
+
yMax,
|
|
1567
|
+
layout = "default",
|
|
1568
|
+
showGrid = true,
|
|
1569
|
+
showXAxis: showXAxisProp,
|
|
1570
|
+
showYAxis: showYAxisProp,
|
|
1571
|
+
showLegend: showLegendProp,
|
|
1572
|
+
showTooltip = true,
|
|
1573
|
+
formatValue,
|
|
1574
|
+
formatX,
|
|
1575
|
+
className,
|
|
1576
|
+
ariaLabel = "Chart"
|
|
1577
|
+
}) => {
|
|
1578
|
+
const uid = (0, import_react10.useId)();
|
|
1579
|
+
const { ref, width } = useChartWidth();
|
|
1580
|
+
const [active, setActive] = (0, import_react10.useState)(null);
|
|
1581
|
+
const [grown, setGrown] = (0, import_react10.useState)(false);
|
|
1582
|
+
const xKey = xKeyProp ?? inferXKey(data);
|
|
1583
|
+
const series = (0, import_react10.useMemo)(
|
|
1584
|
+
() => resolveSeries(seriesProp, data, xKey),
|
|
1585
|
+
[seriesProp, data, xKey]
|
|
1586
|
+
);
|
|
1587
|
+
const pad = layout === "flush" ? PAD_FLUSH : PAD_DEFAULT;
|
|
1588
|
+
const showXAxis = showXAxisProp ?? layout !== "flush";
|
|
1589
|
+
const showYAxis = showYAxisProp ?? layout !== "flush";
|
|
1590
|
+
const showLegend = showLegendProp ?? (layout !== "flush" && series.length > 1);
|
|
1591
|
+
(0, import_react10.useEffect)(() => {
|
|
1592
|
+
const t = requestAnimationFrame(() => setGrown(true));
|
|
1593
|
+
return () => cancelAnimationFrame(t);
|
|
1594
|
+
}, []);
|
|
1595
|
+
const innerW = Math.max(0, width - pad.left - pad.right);
|
|
1596
|
+
const innerH = Math.max(0, height - pad.top - pad.bottom);
|
|
1597
|
+
const { minV, maxV } = (0, import_react10.useMemo)(() => {
|
|
1598
|
+
let lo = 0;
|
|
1599
|
+
let hi = yMax ?? 0;
|
|
1600
|
+
for (const s of series) {
|
|
1601
|
+
for (const d of data) {
|
|
1602
|
+
const v = toNum(d[s.dataKey]);
|
|
1603
|
+
if (v > hi && yMax == null) hi = v;
|
|
1604
|
+
if (v < lo) lo = v;
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1607
|
+
if (hi === lo) hi = lo + 1;
|
|
1608
|
+
return { minV: lo, maxV: yMax != null ? yMax : hi * 1.08 };
|
|
1609
|
+
}, [series, data, yMax]);
|
|
1610
|
+
const ticks = (0, import_react10.useMemo)(() => niceTicks(minV, maxV, 4), [minV, maxV]);
|
|
1611
|
+
if (data.length === 0 || series.length === 0) {
|
|
1612
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ChartEmpty, { className, height });
|
|
1271
1613
|
}
|
|
1272
|
-
const
|
|
1273
|
-
const innerH = H - PAD.top - PAD.bottom;
|
|
1274
|
-
const all = dataKeys.flatMap((k) => data.map((d) => toNum(d[k])));
|
|
1275
|
-
const maxV = Math.max(0, ...all);
|
|
1276
|
-
const minV = Math.min(0, ...all);
|
|
1277
|
-
const range = maxV - minV || 1;
|
|
1278
|
-
const yScale = (v) => PAD.top + innerH - (v - minV) / range * innerH;
|
|
1614
|
+
const yScale = (v) => pad.top + innerH - (v - minV) / (maxV - minV || 1) * innerH;
|
|
1279
1615
|
const xCount = data.length;
|
|
1280
1616
|
const xStep = xCount > 1 ? innerW / (xCount - 1) : innerW;
|
|
1281
|
-
const xPos = (i) =>
|
|
1282
|
-
const
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1617
|
+
const xPos = (i) => variant === "bar" ? pad.left + innerW * (i + 0.5) / xCount : pad.left + i * xStep;
|
|
1618
|
+
const baseY = yScale(Math.max(0, minV));
|
|
1619
|
+
const fmtV = (v) => formatValue ? formatValue(v) : formatCompact(v, unit);
|
|
1620
|
+
const fmtX = (i) => formatX ? formatX(data[i]?.[xKey], i) : String(data[i]?.[xKey] ?? i);
|
|
1621
|
+
const onMove = (event) => {
|
|
1622
|
+
const rect = event.currentTarget.getBoundingClientRect();
|
|
1623
|
+
const px2 = event.clientX - rect.left - pad.left;
|
|
1624
|
+
const i = Math.round(px2 / (xStep || 1));
|
|
1625
|
+
setActive(Math.max(0, Math.min(xCount - 1, i)));
|
|
1626
|
+
};
|
|
1627
|
+
const labelIdx = pickXLabels(xCount, innerW);
|
|
1628
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { ref, className: cn("relative w-full", className), style: { height }, children: [
|
|
1629
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1630
|
+
"svg",
|
|
1631
|
+
{
|
|
1632
|
+
width,
|
|
1633
|
+
height,
|
|
1634
|
+
role: "img",
|
|
1635
|
+
"aria-label": ariaLabel,
|
|
1636
|
+
className: "block overflow-visible",
|
|
1637
|
+
children: [
|
|
1638
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("defs", { children: [
|
|
1639
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("clipPath", { id: `${uid}-grow`, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1640
|
+
"rect",
|
|
1641
|
+
{
|
|
1642
|
+
x: pad.left,
|
|
1643
|
+
y: 0,
|
|
1644
|
+
height,
|
|
1645
|
+
width: grown ? innerW : 0,
|
|
1646
|
+
style: { transition: "width 900ms cubic-bezier(0.22,1,0.36,1)" }
|
|
1647
|
+
}
|
|
1648
|
+
) }),
|
|
1649
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("linearGradient", { id: `${uid}-gridfade`, x1: "0%", x2: "100%", y1: "0", y2: "0", children: [
|
|
1650
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("stop", { offset: "0%", stopColor: "white", stopOpacity: 0 }),
|
|
1651
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("stop", { offset: "8%", stopColor: "white", stopOpacity: 1 }),
|
|
1652
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("stop", { offset: "92%", stopColor: "white", stopOpacity: 1 }),
|
|
1653
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("stop", { offset: "100%", stopColor: "white", stopOpacity: 0 })
|
|
1654
|
+
] }),
|
|
1655
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("mask", { id: `${uid}-gridmask`, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1656
|
+
"rect",
|
|
1657
|
+
{
|
|
1658
|
+
x: pad.left,
|
|
1659
|
+
y: pad.top,
|
|
1660
|
+
width: innerW,
|
|
1661
|
+
height: innerH,
|
|
1662
|
+
fill: `url(#${uid}-gridfade)`
|
|
1663
|
+
}
|
|
1664
|
+
) }),
|
|
1665
|
+
series.map((s, i) => {
|
|
1666
|
+
const color = s.color ?? CHART_PALETTE[i % CHART_PALETTE.length];
|
|
1667
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1668
|
+
"linearGradient",
|
|
1669
|
+
{
|
|
1670
|
+
id: `${uid}-fill-${i}`,
|
|
1671
|
+
x1: "0",
|
|
1672
|
+
x2: "0",
|
|
1673
|
+
y1: "0",
|
|
1674
|
+
y2: "1",
|
|
1675
|
+
children: [
|
|
1676
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("stop", { offset: "0%", style: { stopColor: color, stopOpacity: 0.28 } }),
|
|
1677
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("stop", { offset: "100%", style: { stopColor: color, stopOpacity: 0 } })
|
|
1678
|
+
]
|
|
1679
|
+
},
|
|
1680
|
+
s.dataKey
|
|
1681
|
+
);
|
|
1682
|
+
})
|
|
1683
|
+
] }),
|
|
1684
|
+
showGrid && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("g", { mask: `url(#${uid}-gridmask)`, children: ticks.map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1293
1685
|
"line",
|
|
1294
1686
|
{
|
|
1295
|
-
x1:
|
|
1296
|
-
x2:
|
|
1687
|
+
x1: pad.left,
|
|
1688
|
+
x2: width - pad.right,
|
|
1297
1689
|
y1: yScale(t),
|
|
1298
1690
|
y2: yScale(t),
|
|
1299
1691
|
stroke: "currentColor",
|
|
1300
|
-
strokeOpacity: 0.
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1692
|
+
strokeOpacity: 0.14,
|
|
1693
|
+
strokeDasharray: "4 4",
|
|
1694
|
+
className: "text-muted-foreground"
|
|
1695
|
+
},
|
|
1696
|
+
i
|
|
1697
|
+
)) }),
|
|
1698
|
+
showYAxis && ticks.map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1304
1699
|
"text",
|
|
1305
1700
|
{
|
|
1306
|
-
x:
|
|
1701
|
+
x: pad.left - 8,
|
|
1307
1702
|
y: yScale(t),
|
|
1308
1703
|
textAnchor: "end",
|
|
1309
1704
|
dominantBaseline: "middle",
|
|
1310
|
-
className: "fill-muted-foreground text-[10px]",
|
|
1311
|
-
children:
|
|
1705
|
+
className: "fill-muted-foreground text-[10px] tabular-nums",
|
|
1706
|
+
children: fmtV(t)
|
|
1707
|
+
},
|
|
1708
|
+
i
|
|
1709
|
+
)),
|
|
1710
|
+
showXAxis && labelIdx.map((i) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1711
|
+
"text",
|
|
1712
|
+
{
|
|
1713
|
+
x: xPos(i),
|
|
1714
|
+
y: height - pad.bottom + 16,
|
|
1715
|
+
textAnchor: i === 0 ? "start" : i === xCount - 1 ? "end" : "middle",
|
|
1716
|
+
className: "fill-muted-foreground text-[10px] tabular-nums",
|
|
1717
|
+
children: fmtX(i)
|
|
1718
|
+
},
|
|
1719
|
+
i
|
|
1720
|
+
)),
|
|
1721
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("g", { clipPath: `url(#${uid}-grow)`, children: variant === "bar" ? renderBars({ data, series, xCount, xPos, yScale, baseY, innerW, uid }) : series.map((s, si) => {
|
|
1722
|
+
const color = s.color ?? CHART_PALETTE[si % CHART_PALETTE.length];
|
|
1723
|
+
const pts = data.map((d, i) => ({
|
|
1724
|
+
x: xPos(i),
|
|
1725
|
+
y: yScale(toNum(d[s.dataKey]))
|
|
1726
|
+
}));
|
|
1727
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("g", { children: [
|
|
1728
|
+
variant === "area" && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: monotoneAreaPath(pts, baseY), fill: `url(#${uid}-fill-${si})` }),
|
|
1729
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1730
|
+
"path",
|
|
1731
|
+
{
|
|
1732
|
+
d: monotoneLinePath(pts),
|
|
1733
|
+
fill: "none",
|
|
1734
|
+
stroke: color,
|
|
1735
|
+
strokeWidth: 2,
|
|
1736
|
+
strokeLinecap: "round",
|
|
1737
|
+
strokeLinejoin: "round"
|
|
1738
|
+
}
|
|
1739
|
+
)
|
|
1740
|
+
] }, s.dataKey);
|
|
1741
|
+
}) }),
|
|
1742
|
+
showTooltip && active != null && variant !== "bar" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("g", { pointerEvents: "none", children: [
|
|
1743
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1744
|
+
"line",
|
|
1745
|
+
{
|
|
1746
|
+
x1: xPos(active),
|
|
1747
|
+
x2: xPos(active),
|
|
1748
|
+
y1: pad.top,
|
|
1749
|
+
y2: pad.top + innerH,
|
|
1750
|
+
stroke: "currentColor",
|
|
1751
|
+
strokeOpacity: 0.25,
|
|
1752
|
+
className: "text-foreground"
|
|
1753
|
+
}
|
|
1754
|
+
),
|
|
1755
|
+
series.map((s, si) => {
|
|
1756
|
+
const color = s.color ?? CHART_PALETTE[si % CHART_PALETTE.length];
|
|
1757
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1758
|
+
"circle",
|
|
1759
|
+
{
|
|
1760
|
+
cx: xPos(active),
|
|
1761
|
+
cy: yScale(toNum(data[active]?.[s.dataKey])),
|
|
1762
|
+
r: 4,
|
|
1763
|
+
fill: color,
|
|
1764
|
+
stroke: "var(--background, #fff)",
|
|
1765
|
+
strokeWidth: 2
|
|
1766
|
+
},
|
|
1767
|
+
s.dataKey
|
|
1768
|
+
);
|
|
1769
|
+
})
|
|
1770
|
+
] }),
|
|
1771
|
+
showTooltip && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1772
|
+
"rect",
|
|
1773
|
+
{
|
|
1774
|
+
x: pad.left,
|
|
1775
|
+
y: pad.top,
|
|
1776
|
+
width: innerW,
|
|
1777
|
+
height: innerH,
|
|
1778
|
+
fill: "transparent",
|
|
1779
|
+
style: { cursor: "crosshair" },
|
|
1780
|
+
onMouseMove: onMove,
|
|
1781
|
+
onMouseLeave: () => setActive(null)
|
|
1312
1782
|
}
|
|
1313
1783
|
)
|
|
1314
|
-
]
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
xPos,
|
|
1333
|
-
yScale,
|
|
1334
|
-
color: COLORS[ki % COLORS.length]
|
|
1335
|
-
},
|
|
1336
|
-
k
|
|
1337
|
-
)),
|
|
1338
|
-
chartType === "area" && dataKeys.map((k, ki) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1339
|
-
Area,
|
|
1340
|
-
{
|
|
1341
|
-
data,
|
|
1342
|
-
dataKey: k,
|
|
1343
|
-
xPos,
|
|
1344
|
-
yScale,
|
|
1345
|
-
baseY: yScale(Math.max(0, minV)),
|
|
1346
|
-
color: COLORS[ki % COLORS.length]
|
|
1347
|
-
},
|
|
1348
|
-
k
|
|
1349
|
-
))
|
|
1350
|
-
]
|
|
1351
|
-
}
|
|
1352
|
-
);
|
|
1784
|
+
]
|
|
1785
|
+
}
|
|
1786
|
+
),
|
|
1787
|
+
showTooltip && active != null && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1788
|
+
ChartTooltip,
|
|
1789
|
+
{
|
|
1790
|
+
x: xPos(active),
|
|
1791
|
+
width,
|
|
1792
|
+
title: fmtX(active),
|
|
1793
|
+
rows: series.map((s, si) => ({
|
|
1794
|
+
color: s.color ?? CHART_PALETTE[si % CHART_PALETTE.length],
|
|
1795
|
+
label: s.label ?? s.dataKey,
|
|
1796
|
+
value: fmtV(toNum(data[active]?.[s.dataKey]))
|
|
1797
|
+
}))
|
|
1798
|
+
}
|
|
1799
|
+
),
|
|
1800
|
+
showLegend ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ChartLegend, { series }) : null
|
|
1801
|
+
] });
|
|
1353
1802
|
};
|
|
1354
1803
|
function renderBars(args) {
|
|
1355
|
-
const { data,
|
|
1356
|
-
const groupWidth = innerW / xCount * 0.
|
|
1357
|
-
const barWidth = groupWidth /
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
const
|
|
1362
|
-
const
|
|
1363
|
-
const x = xPos(i) - groupWidth / 2 + ki * barWidth;
|
|
1804
|
+
const { data, series, xCount, xPos, yScale, baseY, innerW } = args;
|
|
1805
|
+
const groupWidth = innerW / xCount * 0.66;
|
|
1806
|
+
const barWidth = groupWidth / series.length;
|
|
1807
|
+
return series.flatMap(
|
|
1808
|
+
(s, si) => data.map((d, i) => {
|
|
1809
|
+
const color = s.color ?? CHART_PALETTE[si % CHART_PALETTE.length];
|
|
1810
|
+
const y = yScale(toNum(d[s.dataKey]));
|
|
1811
|
+
const x = xPos(i) - groupWidth / 2 + si * barWidth;
|
|
1364
1812
|
const top = Math.min(y, baseY);
|
|
1365
|
-
const
|
|
1366
|
-
return /* @__PURE__ */ (0,
|
|
1813
|
+
const h = Math.max(1, Math.abs(y - baseY));
|
|
1814
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1367
1815
|
"rect",
|
|
1368
1816
|
{
|
|
1369
1817
|
x,
|
|
1370
1818
|
y: top,
|
|
1371
1819
|
width: Math.max(1, barWidth - 2),
|
|
1372
|
-
height:
|
|
1373
|
-
rx:
|
|
1374
|
-
fill:
|
|
1820
|
+
height: h,
|
|
1821
|
+
rx: 3,
|
|
1822
|
+
fill: color
|
|
1375
1823
|
},
|
|
1376
|
-
`${
|
|
1824
|
+
`${s.dataKey}-${i}`
|
|
1377
1825
|
);
|
|
1378
1826
|
})
|
|
1379
1827
|
);
|
|
1380
1828
|
}
|
|
1381
|
-
var
|
|
1382
|
-
const
|
|
1383
|
-
return /* @__PURE__ */ (0,
|
|
1384
|
-
"
|
|
1385
|
-
{
|
|
1386
|
-
points,
|
|
1387
|
-
fill: "none",
|
|
1388
|
-
stroke: color,
|
|
1389
|
-
strokeWidth: 2,
|
|
1390
|
-
strokeLinejoin: "round",
|
|
1391
|
-
strokeLinecap: "round"
|
|
1392
|
-
}
|
|
1393
|
-
);
|
|
1394
|
-
};
|
|
1395
|
-
var Area = ({ data, dataKey, xPos, yScale, baseY, color }) => {
|
|
1396
|
-
if (data.length === 0) return null;
|
|
1397
|
-
const top = data.map((d, i) => `${xPos(i)},${yScale(toNum(d[dataKey]))}`).join(" ");
|
|
1398
|
-
const path = `M ${xPos(0)},${baseY} L ${top} L ${xPos(data.length - 1)},${baseY} Z`;
|
|
1399
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
1400
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: path, fill: color, fillOpacity: 0.18 }),
|
|
1401
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Polyline, { data, dataKey, xPos, yScale, color })
|
|
1402
|
-
] });
|
|
1403
|
-
};
|
|
1404
|
-
var PieChart = ({ data, xKey, dataKey }) => {
|
|
1405
|
-
const cx = W / 2;
|
|
1406
|
-
const cy = H / 2;
|
|
1407
|
-
const r = Math.min(W, H) / 2 - 16;
|
|
1408
|
-
const total = data.reduce((sum, d) => sum + toNum(d[dataKey]), 0) || 1;
|
|
1409
|
-
let acc = 0;
|
|
1410
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1411
|
-
"svg",
|
|
1829
|
+
var ChartTooltip = ({ x, width, title, rows }) => {
|
|
1830
|
+
const flip = x > width - 160;
|
|
1831
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1832
|
+
"div",
|
|
1412
1833
|
{
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
);
|
|
1435
|
-
})
|
|
1834
|
+
className: "pointer-events-none absolute top-2 z-10 min-w-[8rem] rounded-lg border border-border bg-popover/95 px-2.5 py-2 text-popover-foreground shadow-card-elevated backdrop-blur-sm",
|
|
1835
|
+
style: {
|
|
1836
|
+
left: flip ? void 0 : Math.min(x + 12, width - 8),
|
|
1837
|
+
right: flip ? Math.max(width - x + 12, 8) : void 0
|
|
1838
|
+
},
|
|
1839
|
+
children: [
|
|
1840
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "mb-1.5 text-[11px] text-muted-foreground", children: title }),
|
|
1841
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "flex flex-col gap-1", children: rows.map((r) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-between gap-4", children: [
|
|
1842
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "inline-flex items-center gap-1.5 text-xs text-muted-foreground", children: [
|
|
1843
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1844
|
+
"span",
|
|
1845
|
+
{
|
|
1846
|
+
className: "inline-block size-2 rounded-full",
|
|
1847
|
+
style: { background: r.color }
|
|
1848
|
+
}
|
|
1849
|
+
),
|
|
1850
|
+
r.label
|
|
1851
|
+
] }),
|
|
1852
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "text-xs font-medium tabular-nums text-foreground", children: r.value })
|
|
1853
|
+
] }, r.label)) })
|
|
1854
|
+
]
|
|
1436
1855
|
}
|
|
1437
1856
|
);
|
|
1438
1857
|
};
|
|
1439
|
-
var
|
|
1440
|
-
|
|
1441
|
-
const y1 = cy - Math.cos(start) * r;
|
|
1442
|
-
const x2 = cx + Math.sin(end) * r;
|
|
1443
|
-
const y2 = cy - Math.cos(end) * r;
|
|
1444
|
-
const large = end - start > Math.PI ? 1 : 0;
|
|
1445
|
-
const path = `M ${cx} ${cy} L ${x1} ${y1} A ${r} ${r} 0 ${large} 1 ${x2} ${y2} Z`;
|
|
1446
|
-
const mid = (start + end) / 2;
|
|
1447
|
-
const lx = cx + Math.sin(mid) * (r * 0.65);
|
|
1448
|
-
const ly = cy - Math.cos(mid) * (r * 0.65);
|
|
1449
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("g", { children: [
|
|
1450
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: path, fill: color, stroke: "var(--background, #fff)", strokeWidth: 1 }),
|
|
1451
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1452
|
-
"text",
|
|
1453
|
-
{
|
|
1454
|
-
x: lx,
|
|
1455
|
-
y: ly,
|
|
1456
|
-
textAnchor: "middle",
|
|
1457
|
-
dominantBaseline: "middle",
|
|
1458
|
-
className: "fill-white text-[10px] font-semibold",
|
|
1459
|
-
children: label
|
|
1460
|
-
}
|
|
1461
|
-
)
|
|
1462
|
-
] });
|
|
1463
|
-
};
|
|
1464
|
-
var Legend = ({ dataKeys }) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "aui-artifact-chart-legend mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground", children: dataKeys.map((k, i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
1465
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1858
|
+
var ChartLegend = ({ series }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 pl-10 text-xs text-muted-foreground", children: series.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
1859
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1466
1860
|
"span",
|
|
1467
1861
|
{
|
|
1468
1862
|
className: "inline-block size-2 rounded-sm",
|
|
1469
|
-
style: { background:
|
|
1470
|
-
"aria-hidden": true
|
|
1863
|
+
style: { background: s.color ?? CHART_PALETTE[i % CHART_PALETTE.length] }
|
|
1471
1864
|
}
|
|
1472
1865
|
),
|
|
1473
|
-
|
|
1474
|
-
] },
|
|
1475
|
-
var
|
|
1866
|
+
s.label ?? s.dataKey
|
|
1867
|
+
] }, s.dataKey)) });
|
|
1868
|
+
var ChartEmpty = ({ className, height }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1869
|
+
"div",
|
|
1870
|
+
{
|
|
1871
|
+
className: cn(
|
|
1872
|
+
"flex w-full items-center justify-center text-xs text-muted-foreground",
|
|
1873
|
+
className
|
|
1874
|
+
),
|
|
1875
|
+
style: { height },
|
|
1876
|
+
children: "No data yet"
|
|
1877
|
+
}
|
|
1878
|
+
);
|
|
1476
1879
|
function inferXKey(data) {
|
|
1477
1880
|
if (data.length === 0) return "x";
|
|
1478
1881
|
for (const k of Object.keys(data[0])) {
|
|
@@ -1480,73 +1883,190 @@ function inferXKey(data) {
|
|
|
1480
1883
|
}
|
|
1481
1884
|
return Object.keys(data[0])[0] ?? "x";
|
|
1482
1885
|
}
|
|
1483
|
-
function
|
|
1484
|
-
if (
|
|
1485
|
-
|
|
1486
|
-
(k) => k !== xKey && typeof data[0][k] === "number"
|
|
1487
|
-
);
|
|
1488
|
-
}
|
|
1489
|
-
function toNum(value) {
|
|
1490
|
-
const n = typeof value === "number" ? value : Number(value);
|
|
1491
|
-
return Number.isFinite(n) ? n : 0;
|
|
1492
|
-
}
|
|
1493
|
-
function niceTicks(min, max, count = 4) {
|
|
1494
|
-
if (max === min) return [min];
|
|
1495
|
-
const range = max - min;
|
|
1496
|
-
const step = niceStep(range / count);
|
|
1497
|
-
const start = Math.floor(min / step) * step;
|
|
1498
|
-
const out = [];
|
|
1499
|
-
for (let v = start; v <= max + step / 2; v += step) {
|
|
1500
|
-
out.push(round(v));
|
|
1886
|
+
function resolveSeries(seriesProp, data, xKey) {
|
|
1887
|
+
if (seriesProp && seriesProp.length > 0) {
|
|
1888
|
+
return seriesProp.map((s) => typeof s === "string" ? { dataKey: s } : s);
|
|
1501
1889
|
}
|
|
1502
|
-
return
|
|
1503
|
-
}
|
|
1504
|
-
function niceStep(raw) {
|
|
1505
|
-
const exp = Math.floor(Math.log10(Math.abs(raw))) || 0;
|
|
1506
|
-
const base = Math.pow(10, exp);
|
|
1507
|
-
const norm = raw / base;
|
|
1508
|
-
let nice = 1;
|
|
1509
|
-
if (norm >= 5) nice = 5;
|
|
1510
|
-
else if (norm >= 2) nice = 2;
|
|
1511
|
-
return nice * base;
|
|
1512
|
-
}
|
|
1513
|
-
function round(v) {
|
|
1514
|
-
return Math.round(v * 1e6) / 1e6;
|
|
1890
|
+
if (data.length === 0) return [];
|
|
1891
|
+
return Object.keys(data[0]).filter((k) => k !== xKey && typeof data[0][k] === "number").map((dataKey) => ({ dataKey }));
|
|
1515
1892
|
}
|
|
1516
|
-
function
|
|
1517
|
-
|
|
1518
|
-
|
|
1893
|
+
function pickXLabels(count, innerW) {
|
|
1894
|
+
if (count <= 1) return [0];
|
|
1895
|
+
const maxLabels = Math.max(2, Math.min(count, Math.floor(innerW / 64) + 1));
|
|
1896
|
+
if (maxLabels >= count) return Array.from({ length: count }, (_, i) => i);
|
|
1897
|
+
const out = /* @__PURE__ */ new Set([0, count - 1]);
|
|
1898
|
+
const step = (count - 1) / (maxLabels - 1);
|
|
1899
|
+
for (let i = 1; i < maxLabels - 1; i++) out.add(Math.round(i * step));
|
|
1900
|
+
return [...out].sort((a, b) => a - b);
|
|
1519
1901
|
}
|
|
1520
1902
|
|
|
1521
|
-
// src/artifacts/
|
|
1522
|
-
var
|
|
1523
|
-
var
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1903
|
+
// src/artifacts/artifact-card.tsx
|
|
1904
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
1905
|
+
var ArtifactCard = ({ title, kind, className, bodyClassName, toolbar, children }) => {
|
|
1906
|
+
const hasHeader = Boolean(title || toolbar);
|
|
1907
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
1908
|
+
"div",
|
|
1909
|
+
{
|
|
1910
|
+
className: cn(
|
|
1911
|
+
"aui-artifact-root my-3 overflow-hidden rounded-xl border border-border/60 bg-background shadow-sm",
|
|
1912
|
+
className
|
|
1913
|
+
),
|
|
1914
|
+
"data-artifact-kind": kind,
|
|
1915
|
+
children: [
|
|
1916
|
+
hasHeader && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "aui-artifact-header flex items-center gap-2 border-b border-border/40 bg-muted/30 px-3 py-1.5", children: [
|
|
1917
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "aui-artifact-title flex-1 truncate text-xs font-semibold text-foreground/80", children: title }),
|
|
1918
|
+
!title && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "flex-1" }),
|
|
1919
|
+
toolbar
|
|
1920
|
+
] }),
|
|
1921
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: cn("aui-artifact-body", bodyClassName), children })
|
|
1922
|
+
]
|
|
1923
|
+
}
|
|
1924
|
+
);
|
|
1925
|
+
};
|
|
1926
|
+
|
|
1927
|
+
// src/artifacts/chart-artifact.tsx
|
|
1928
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1929
|
+
var ChartArtifactView = ({
|
|
1930
|
+
artifact,
|
|
1931
|
+
embedded = false,
|
|
1932
|
+
height = 300
|
|
1933
|
+
}) => {
|
|
1934
|
+
const plot = /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ChartArtifactPlot, { artifact, height });
|
|
1935
|
+
if (embedded) {
|
|
1936
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "aui-artifact-chart w-full", children: plot });
|
|
1937
|
+
}
|
|
1938
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ArtifactCard, { title: artifact.title, kind: "chart", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "aui-artifact-chart pt-2", children: plot }) });
|
|
1939
|
+
};
|
|
1940
|
+
function ChartArtifactPlot({
|
|
1941
|
+
artifact,
|
|
1942
|
+
height
|
|
1943
|
+
}) {
|
|
1944
|
+
const { chartType = "bar", data = [] } = artifact;
|
|
1945
|
+
const xKey = artifact.xKey ?? inferXKey2(data);
|
|
1946
|
+
const series = (0, import_react11.useMemo)(() => {
|
|
1947
|
+
const keys = Array.isArray(artifact.dataKey) ? artifact.dataKey : typeof artifact.dataKey === "string" ? [artifact.dataKey] : inferDataKeys(data, xKey);
|
|
1948
|
+
return keys.map((dataKey) => ({ dataKey }));
|
|
1949
|
+
}, [artifact.dataKey, data, xKey]);
|
|
1950
|
+
if (chartType === "pie") {
|
|
1951
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "px-3 pb-3 pt-2", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(PieChart, { data, xKey, dataKey: series[0]?.dataKey ?? "value" }) });
|
|
1952
|
+
}
|
|
1953
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1954
|
+
LineAreaChart,
|
|
1955
|
+
{
|
|
1956
|
+
data,
|
|
1957
|
+
xKey,
|
|
1958
|
+
series,
|
|
1959
|
+
layout: "flush",
|
|
1960
|
+
height,
|
|
1961
|
+
variant: chartType === "line" ? "line" : chartType === "area" ? "area" : "bar",
|
|
1962
|
+
unit: artifact.unit,
|
|
1963
|
+
ariaLabel: typeof artifact.title === "string" ? artifact.title : "Chart"
|
|
1964
|
+
}
|
|
1965
|
+
);
|
|
1966
|
+
}
|
|
1967
|
+
var PIE_W = 320;
|
|
1968
|
+
var PIE_H = 220;
|
|
1969
|
+
var PieChart = ({ data, xKey, dataKey }) => {
|
|
1970
|
+
if (data.length === 0) {
|
|
1971
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "flex h-32 items-center justify-center text-xs text-muted-foreground", children: "No data" });
|
|
1972
|
+
}
|
|
1973
|
+
const cx = PIE_W / 2;
|
|
1974
|
+
const cy = PIE_H / 2;
|
|
1975
|
+
const r = Math.min(PIE_W, PIE_H) / 2 - 16;
|
|
1976
|
+
const total = data.reduce((sum, d) => sum + toNum(d[dataKey]), 0) || 1;
|
|
1977
|
+
let acc = 0;
|
|
1978
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col items-center gap-3", children: [
|
|
1979
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1980
|
+
"svg",
|
|
1981
|
+
{
|
|
1982
|
+
viewBox: `0 0 ${PIE_W} ${PIE_H}`,
|
|
1983
|
+
className: "w-full max-w-[20rem]",
|
|
1984
|
+
role: "img",
|
|
1985
|
+
"aria-label": "Pie chart",
|
|
1986
|
+
children: data.map((d, i) => {
|
|
1987
|
+
const value = toNum(d[dataKey]);
|
|
1988
|
+
const start = acc / total * Math.PI * 2;
|
|
1989
|
+
acc += value;
|
|
1990
|
+
const end = acc / total * Math.PI * 2;
|
|
1991
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1992
|
+
PieSlice,
|
|
1993
|
+
{
|
|
1994
|
+
cx,
|
|
1995
|
+
cy,
|
|
1996
|
+
r,
|
|
1997
|
+
start,
|
|
1998
|
+
end,
|
|
1999
|
+
color: CHART_PALETTE[i % CHART_PALETTE.length]
|
|
2000
|
+
},
|
|
2001
|
+
i
|
|
2002
|
+
);
|
|
2003
|
+
})
|
|
2004
|
+
}
|
|
2005
|
+
),
|
|
2006
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "flex flex-wrap items-center justify-center gap-x-3 gap-y-1 text-xs text-muted-foreground", children: data.map((d, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
2007
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2008
|
+
"span",
|
|
2009
|
+
{
|
|
2010
|
+
className: "inline-block size-2 rounded-sm",
|
|
2011
|
+
style: { background: CHART_PALETTE[i % CHART_PALETTE.length] }
|
|
2012
|
+
}
|
|
2013
|
+
),
|
|
2014
|
+
String(d[xKey] ?? i)
|
|
2015
|
+
] }, i)) })
|
|
2016
|
+
] });
|
|
2017
|
+
};
|
|
2018
|
+
var PieSlice = ({ cx, cy, r, start, end, color }) => {
|
|
2019
|
+
const x1 = cx + Math.sin(start) * r;
|
|
2020
|
+
const y1 = cy - Math.cos(start) * r;
|
|
2021
|
+
const x2 = cx + Math.sin(end) * r;
|
|
2022
|
+
const y2 = cy - Math.cos(end) * r;
|
|
2023
|
+
const large = end - start > Math.PI ? 1 : 0;
|
|
2024
|
+
const path = `M ${cx} ${cy} L ${x1} ${y1} A ${r} ${r} 0 ${large} 1 ${x2} ${y2} Z`;
|
|
2025
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: path, fill: color, stroke: "var(--background, #fff)", strokeWidth: 1.5 });
|
|
2026
|
+
};
|
|
2027
|
+
function inferXKey2(data) {
|
|
2028
|
+
if (data.length === 0) return "x";
|
|
2029
|
+
for (const k of Object.keys(data[0])) {
|
|
2030
|
+
if (typeof data[0][k] !== "number") return k;
|
|
2031
|
+
}
|
|
2032
|
+
return Object.keys(data[0])[0] ?? "x";
|
|
2033
|
+
}
|
|
2034
|
+
function inferDataKeys(data, xKey) {
|
|
2035
|
+
if (data.length === 0) return [];
|
|
2036
|
+
return Object.keys(data[0]).filter(
|
|
2037
|
+
(k) => k !== xKey && typeof data[0][k] === "number"
|
|
2038
|
+
);
|
|
2039
|
+
}
|
|
2040
|
+
|
|
2041
|
+
// src/artifacts/question-artifact.tsx
|
|
2042
|
+
var import_react12 = require("react");
|
|
2043
|
+
var import_react13 = require("@assistant-ui/react");
|
|
2044
|
+
var import_lucide_react3 = require("lucide-react");
|
|
2045
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
2046
|
+
function optionKey(option, index) {
|
|
2047
|
+
const id = option.id?.trim();
|
|
2048
|
+
return id ? id : `__option-${index}`;
|
|
2049
|
+
}
|
|
2050
|
+
var OptionRadio = ({ selected }) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2051
|
+
"span",
|
|
2052
|
+
{
|
|
1533
2053
|
className: cn(
|
|
1534
2054
|
"flex size-4 shrink-0 items-center justify-center rounded-full border-2 transition-colors",
|
|
1535
2055
|
selected ? "border-foreground bg-foreground text-background" : "border-border bg-background"
|
|
1536
2056
|
),
|
|
1537
2057
|
"aria-hidden": true,
|
|
1538
|
-
children: selected ? /* @__PURE__ */ (0,
|
|
2058
|
+
children: selected ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react3.CheckIcon, { className: "size-2.5 stroke-[3]" }) : null
|
|
1539
2059
|
}
|
|
1540
2060
|
);
|
|
1541
2061
|
var QuestionArtifactView = ({
|
|
1542
2062
|
artifact
|
|
1543
2063
|
}) => {
|
|
1544
|
-
const runtime = (0,
|
|
1545
|
-
const [selected, setSelected] = (0,
|
|
1546
|
-
const [submittedIds, setSubmittedIds] = (0,
|
|
2064
|
+
const runtime = (0, import_react13.useThreadRuntime)();
|
|
2065
|
+
const [selected, setSelected] = (0, import_react12.useState)([]);
|
|
2066
|
+
const [submittedIds, setSubmittedIds] = (0, import_react12.useState)(null);
|
|
1547
2067
|
const isMulti = artifact.multi === true;
|
|
1548
2068
|
const isDisabled = submittedIds !== null;
|
|
1549
|
-
const send = (0,
|
|
2069
|
+
const send = (0, import_react12.useCallback)(
|
|
1550
2070
|
(keys) => {
|
|
1551
2071
|
if (keys.length === 0) return;
|
|
1552
2072
|
const labels = artifact.options.map((option, index) => ({ option, key: optionKey(option, index) })).filter(({ key }) => keys.includes(key)).map(({ option }) => option.label);
|
|
@@ -1558,7 +2078,7 @@ var QuestionArtifactView = ({
|
|
|
1558
2078
|
},
|
|
1559
2079
|
[artifact.options, runtime]
|
|
1560
2080
|
);
|
|
1561
|
-
const onPick = (0,
|
|
2081
|
+
const onPick = (0, import_react12.useCallback)(
|
|
1562
2082
|
(key) => {
|
|
1563
2083
|
if (isDisabled) return;
|
|
1564
2084
|
if (!isMulti) {
|
|
@@ -1571,15 +2091,15 @@ var QuestionArtifactView = ({
|
|
|
1571
2091
|
},
|
|
1572
2092
|
[isDisabled, isMulti, send]
|
|
1573
2093
|
);
|
|
1574
|
-
const onConfirm = (0,
|
|
2094
|
+
const onConfirm = (0, import_react12.useCallback)(() => {
|
|
1575
2095
|
send(selected);
|
|
1576
2096
|
}, [selected, send]);
|
|
1577
|
-
return /* @__PURE__ */ (0,
|
|
1578
|
-
artifact.prompt ? /* @__PURE__ */ (0,
|
|
1579
|
-
/* @__PURE__ */ (0,
|
|
2097
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: studioArtifactShellClass, "data-artifact-kind": "question", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "px-2.5 py-2", children: [
|
|
2098
|
+
artifact.prompt ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "mb-2 text-sm font-normal leading-snug text-foreground", children: artifact.prompt }) : null,
|
|
2099
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex flex-col gap-0.5", role: "list", children: artifact.options.map((option, index) => {
|
|
1580
2100
|
const key = optionKey(option, index);
|
|
1581
2101
|
const isSelected = submittedIds ? submittedIds.includes(key) : isMulti && selected.includes(key);
|
|
1582
|
-
return /* @__PURE__ */ (0,
|
|
2102
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
1583
2103
|
"button",
|
|
1584
2104
|
{
|
|
1585
2105
|
type: "button",
|
|
@@ -1591,17 +2111,17 @@ var QuestionArtifactView = ({
|
|
|
1591
2111
|
isDisabled && (isSelected ? "cursor-default" : "cursor-not-allowed opacity-50")
|
|
1592
2112
|
),
|
|
1593
2113
|
children: [
|
|
1594
|
-
/* @__PURE__ */ (0,
|
|
1595
|
-
/* @__PURE__ */ (0,
|
|
1596
|
-
/* @__PURE__ */ (0,
|
|
1597
|
-
option.description ? /* @__PURE__ */ (0,
|
|
2114
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(OptionRadio, { selected: isSelected }),
|
|
2115
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "min-w-0 flex-1 text-left", children: [
|
|
2116
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "block font-normal text-foreground", children: option.label }),
|
|
2117
|
+
option.description ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "mt-0.5 block text-xs text-muted-foreground", children: option.description }) : null
|
|
1598
2118
|
] })
|
|
1599
2119
|
]
|
|
1600
2120
|
},
|
|
1601
2121
|
key
|
|
1602
2122
|
);
|
|
1603
2123
|
}) }),
|
|
1604
|
-
isMulti && !submittedIds ? /* @__PURE__ */ (0,
|
|
2124
|
+
isMulti && !submittedIds ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "mt-2 flex justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1605
2125
|
TimbalV2Button,
|
|
1606
2126
|
{
|
|
1607
2127
|
type: "button",
|
|
@@ -1616,12 +2136,12 @@ var QuestionArtifactView = ({
|
|
|
1616
2136
|
};
|
|
1617
2137
|
|
|
1618
2138
|
// src/artifacts/html-artifact.tsx
|
|
1619
|
-
var
|
|
2139
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
1620
2140
|
var HtmlArtifactView = ({ artifact }) => {
|
|
1621
2141
|
const sandboxed = artifact.sandboxed !== false;
|
|
1622
2142
|
const sandbox = sandboxed ? "allow-scripts allow-same-origin allow-forms allow-modals allow-popups allow-pointer-lock" : void 0;
|
|
1623
2143
|
const height = artifact.height ?? "320px";
|
|
1624
|
-
return /* @__PURE__ */ (0,
|
|
2144
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ArtifactCard, { title: artifact.title, kind: "html", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1625
2145
|
"iframe",
|
|
1626
2146
|
{
|
|
1627
2147
|
title: artifact.title ?? "HTML artifact",
|
|
@@ -1634,7 +2154,7 @@ var HtmlArtifactView = ({ artifact }) => {
|
|
|
1634
2154
|
};
|
|
1635
2155
|
|
|
1636
2156
|
// src/artifacts/json-artifact.tsx
|
|
1637
|
-
var
|
|
2157
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
1638
2158
|
var JsonArtifactView = ({
|
|
1639
2159
|
artifact
|
|
1640
2160
|
}) => {
|
|
@@ -1646,16 +2166,16 @@ var JsonArtifactView = ({
|
|
|
1646
2166
|
} catch {
|
|
1647
2167
|
body = String(data);
|
|
1648
2168
|
}
|
|
1649
|
-
return /* @__PURE__ */ (0,
|
|
2169
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ArtifactCard, { title, kind: "json", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("pre", { className: "aui-artifact-json m-0 max-h-[420px] overflow-auto p-3 font-mono text-[12px] leading-relaxed text-foreground/85", children: body }) });
|
|
1650
2170
|
};
|
|
1651
2171
|
|
|
1652
2172
|
// src/artifacts/table-artifact.tsx
|
|
1653
|
-
var
|
|
2173
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
1654
2174
|
var TableArtifactView = ({ artifact }) => {
|
|
1655
2175
|
const rows = artifact.rows ?? [];
|
|
1656
2176
|
const columns = artifact.columns ?? deriveColumns(rows);
|
|
1657
|
-
return /* @__PURE__ */ (0,
|
|
1658
|
-
/* @__PURE__ */ (0,
|
|
2177
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ArtifactCard, { title: artifact.title, kind: "table", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "aui-artifact-table-wrap overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("table", { className: "aui-artifact-table w-full border-collapse text-sm", children: [
|
|
2178
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("tr", { className: "border-b border-border/40 bg-muted/20", children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1659
2179
|
"th",
|
|
1660
2180
|
{
|
|
1661
2181
|
className: "px-3 py-2 text-left text-xs font-semibold uppercase tracking-wider text-muted-foreground",
|
|
@@ -1663,11 +2183,11 @@ var TableArtifactView = ({ artifact }) => {
|
|
|
1663
2183
|
},
|
|
1664
2184
|
col.key
|
|
1665
2185
|
)) }) }),
|
|
1666
|
-
/* @__PURE__ */ (0,
|
|
2186
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("tbody", { children: rows.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1667
2187
|
"tr",
|
|
1668
2188
|
{
|
|
1669
2189
|
className: "border-b border-border/30 transition-colors last:border-b-0 hover:bg-muted/20",
|
|
1670
|
-
children: columns.map((col) => /* @__PURE__ */ (0,
|
|
2190
|
+
children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1671
2191
|
"td",
|
|
1672
2192
|
{
|
|
1673
2193
|
className: "px-3 py-2 align-top text-foreground/85",
|
|
@@ -1700,7 +2220,7 @@ function formatCell(value) {
|
|
|
1700
2220
|
}
|
|
1701
2221
|
|
|
1702
2222
|
// src/artifacts/ui/ui-artifact.tsx
|
|
1703
|
-
var
|
|
2223
|
+
var import_react18 = require("react");
|
|
1704
2224
|
|
|
1705
2225
|
// src/artifacts/ui/types.ts
|
|
1706
2226
|
function isUiBinding(value) {
|
|
@@ -1753,38 +2273,38 @@ function resolveBindable(value, state) {
|
|
|
1753
2273
|
}
|
|
1754
2274
|
|
|
1755
2275
|
// src/artifacts/ui/registry.tsx
|
|
1756
|
-
var
|
|
1757
|
-
var
|
|
1758
|
-
var UiStateContext = (0,
|
|
1759
|
-
var UiDispatchContext = (0,
|
|
2276
|
+
var import_react14 = require("react");
|
|
2277
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
2278
|
+
var UiStateContext = (0, import_react14.createContext)({});
|
|
2279
|
+
var UiDispatchContext = (0, import_react14.createContext)(() => {
|
|
1760
2280
|
});
|
|
1761
|
-
var UiStateProvider = ({ state, dispatch, children }) => /* @__PURE__ */ (0,
|
|
2281
|
+
var UiStateProvider = ({ state, dispatch, children }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(UiStateContext.Provider, { value: state, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(UiDispatchContext.Provider, { value: dispatch, children }) });
|
|
1762
2282
|
function useUiState() {
|
|
1763
|
-
return (0,
|
|
2283
|
+
return (0, import_react14.useContext)(UiStateContext);
|
|
1764
2284
|
}
|
|
1765
2285
|
function useUiDispatch() {
|
|
1766
|
-
return (0,
|
|
2286
|
+
return (0, import_react14.useContext)(UiDispatchContext);
|
|
1767
2287
|
}
|
|
1768
|
-
var UiEventContext = (0,
|
|
2288
|
+
var UiEventContext = (0, import_react14.createContext)(
|
|
1769
2289
|
null
|
|
1770
2290
|
);
|
|
1771
|
-
var UiEventProvider = ({ onEvent, children }) => /* @__PURE__ */ (0,
|
|
2291
|
+
var UiEventProvider = ({ onEvent, children }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(UiEventContext.Provider, { value: onEvent, children });
|
|
1772
2292
|
function useUiEventEmitter() {
|
|
1773
|
-
return (0,
|
|
2293
|
+
return (0, import_react14.useContext)(UiEventContext);
|
|
1774
2294
|
}
|
|
1775
|
-
var UiCustomNodeRegistryContext = (0,
|
|
2295
|
+
var UiCustomNodeRegistryContext = (0, import_react14.createContext)({});
|
|
1776
2296
|
function useUiCustomNodeRegistry() {
|
|
1777
|
-
return (0,
|
|
2297
|
+
return (0, import_react14.useContext)(UiCustomNodeRegistryContext);
|
|
1778
2298
|
}
|
|
1779
2299
|
|
|
1780
2300
|
// src/artifacts/ui/nodes.tsx
|
|
1781
|
-
var
|
|
1782
|
-
var
|
|
1783
|
-
var
|
|
2301
|
+
var import_react15 = require("react");
|
|
2302
|
+
var import_react16 = require("motion/react");
|
|
2303
|
+
var import_react17 = require("@assistant-ui/react");
|
|
1784
2304
|
|
|
1785
2305
|
// src/ui/button.tsx
|
|
1786
2306
|
var import_class_variance_authority = require("class-variance-authority");
|
|
1787
|
-
var
|
|
2307
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
1788
2308
|
var LEGACY_SIZE_TO_V2 = {
|
|
1789
2309
|
default: "md",
|
|
1790
2310
|
xs: "xs",
|
|
@@ -1834,7 +2354,7 @@ function Button({
|
|
|
1834
2354
|
const v2Variant = TIMBAL_V2_FROM_LEGACY_BUTTON[variant ?? "default"];
|
|
1835
2355
|
const v2Size = LEGACY_SIZE_TO_V2[size ?? "default"];
|
|
1836
2356
|
const isIconOnly = typeof size === "string" && size.startsWith("icon");
|
|
1837
|
-
return /* @__PURE__ */ (0,
|
|
2357
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
1838
2358
|
TimbalV2Button,
|
|
1839
2359
|
{
|
|
1840
2360
|
"data-slot": "button",
|
|
@@ -1842,7 +2362,7 @@ function Button({
|
|
|
1842
2362
|
"data-size": size,
|
|
1843
2363
|
variant: v2Variant,
|
|
1844
2364
|
size: v2Size,
|
|
1845
|
-
shape: "
|
|
2365
|
+
shape: "pill",
|
|
1846
2366
|
isIconOnly,
|
|
1847
2367
|
asChild,
|
|
1848
2368
|
className: cn(buttonVariants({ variant, size, className })),
|
|
@@ -1852,29 +2372,29 @@ function Button({
|
|
|
1852
2372
|
}
|
|
1853
2373
|
|
|
1854
2374
|
// src/artifacts/ui/nodes.tsx
|
|
1855
|
-
var
|
|
2375
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
1856
2376
|
var UiNodeView = ({ node }) => {
|
|
1857
2377
|
switch (node.kind) {
|
|
1858
2378
|
case "box":
|
|
1859
|
-
return /* @__PURE__ */ (0,
|
|
2379
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(BoxNode, { node });
|
|
1860
2380
|
case "text":
|
|
1861
|
-
return /* @__PURE__ */ (0,
|
|
2381
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TextNode, { node });
|
|
1862
2382
|
case "heading":
|
|
1863
|
-
return /* @__PURE__ */ (0,
|
|
2383
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(HeadingNode, { node });
|
|
1864
2384
|
case "badge":
|
|
1865
|
-
return /* @__PURE__ */ (0,
|
|
2385
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(BadgeNode, { node });
|
|
1866
2386
|
case "button":
|
|
1867
|
-
return /* @__PURE__ */ (0,
|
|
2387
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ButtonNode, { node });
|
|
1868
2388
|
case "toggle":
|
|
1869
|
-
return /* @__PURE__ */ (0,
|
|
2389
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ToggleNode, { node });
|
|
1870
2390
|
case "slider":
|
|
1871
|
-
return /* @__PURE__ */ (0,
|
|
2391
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SliderNode, { node });
|
|
1872
2392
|
case "tooltip":
|
|
1873
|
-
return /* @__PURE__ */ (0,
|
|
2393
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipNode, { node });
|
|
1874
2394
|
case "draggable":
|
|
1875
|
-
return /* @__PURE__ */ (0,
|
|
2395
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(DraggableNode, { node });
|
|
1876
2396
|
case "custom":
|
|
1877
|
-
return /* @__PURE__ */ (0,
|
|
2397
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CustomNode, { node });
|
|
1878
2398
|
default:
|
|
1879
2399
|
return null;
|
|
1880
2400
|
}
|
|
@@ -1882,9 +2402,9 @@ var UiNodeView = ({ node }) => {
|
|
|
1882
2402
|
function useActionRunner() {
|
|
1883
2403
|
const state = useUiState();
|
|
1884
2404
|
const dispatch = useUiDispatch();
|
|
1885
|
-
const runtime = (0,
|
|
2405
|
+
const runtime = (0, import_react17.useThreadRuntime)();
|
|
1886
2406
|
const emit = useUiEventEmitter();
|
|
1887
|
-
return (0,
|
|
2407
|
+
return (0, import_react15.useCallback)(
|
|
1888
2408
|
(actions) => {
|
|
1889
2409
|
if (!actions) return;
|
|
1890
2410
|
const list = Array.isArray(actions) ? actions : [actions];
|
|
@@ -1934,7 +2454,7 @@ var JUSTIFY_CLS = {
|
|
|
1934
2454
|
};
|
|
1935
2455
|
var BoxNode = ({ node }) => {
|
|
1936
2456
|
const dir = node.direction ?? "col";
|
|
1937
|
-
return /* @__PURE__ */ (0,
|
|
2457
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
1938
2458
|
"div",
|
|
1939
2459
|
{
|
|
1940
2460
|
className: cn(
|
|
@@ -1949,7 +2469,7 @@ var BoxNode = ({ node }) => {
|
|
|
1949
2469
|
gap: node.gap !== void 0 ? `${node.gap * 0.25}rem` : void 0,
|
|
1950
2470
|
padding: node.padding !== void 0 ? `${node.padding * 0.25}rem` : void 0
|
|
1951
2471
|
},
|
|
1952
|
-
children: node.children?.map((child, i) => /* @__PURE__ */ (0,
|
|
2472
|
+
children: node.children?.map((child, i) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(UiNodeView, { node: child }, child.id ?? i))
|
|
1953
2473
|
}
|
|
1954
2474
|
);
|
|
1955
2475
|
};
|
|
@@ -1968,7 +2488,7 @@ var TEXT_WEIGHT = {
|
|
|
1968
2488
|
var TextNode = ({ node }) => {
|
|
1969
2489
|
const state = useUiState();
|
|
1970
2490
|
const value = resolveBindable(node.value, state);
|
|
1971
|
-
return /* @__PURE__ */ (0,
|
|
2491
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
1972
2492
|
"span",
|
|
1973
2493
|
{
|
|
1974
2494
|
className: cn(
|
|
@@ -1999,13 +2519,13 @@ var HeadingNode = ({ node }) => {
|
|
|
1999
2519
|
);
|
|
2000
2520
|
switch (level) {
|
|
2001
2521
|
case 1:
|
|
2002
|
-
return /* @__PURE__ */ (0,
|
|
2522
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h1", { className: cls, children: value });
|
|
2003
2523
|
case 2:
|
|
2004
|
-
return /* @__PURE__ */ (0,
|
|
2524
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h2", { className: cls, children: value });
|
|
2005
2525
|
case 3:
|
|
2006
|
-
return /* @__PURE__ */ (0,
|
|
2526
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { className: cls, children: value });
|
|
2007
2527
|
case 4:
|
|
2008
|
-
return /* @__PURE__ */ (0,
|
|
2528
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h4", { className: cls, children: value });
|
|
2009
2529
|
}
|
|
2010
2530
|
};
|
|
2011
2531
|
var BADGE_TONE = {
|
|
@@ -2018,7 +2538,7 @@ var BADGE_TONE = {
|
|
|
2018
2538
|
var BadgeNode = ({ node }) => {
|
|
2019
2539
|
const state = useUiState();
|
|
2020
2540
|
const value = String(resolveBindable(node.value, state) ?? "");
|
|
2021
|
-
return /* @__PURE__ */ (0,
|
|
2541
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2022
2542
|
"span",
|
|
2023
2543
|
{
|
|
2024
2544
|
className: cn(
|
|
@@ -2035,7 +2555,7 @@ var ButtonNode = ({ node }) => {
|
|
|
2035
2555
|
const run = useActionRunner();
|
|
2036
2556
|
const label = String(resolveBindable(node.label, state) ?? "");
|
|
2037
2557
|
const disabled = node.disabled !== void 0 ? Boolean(resolveBindable(node.disabled, state)) : false;
|
|
2038
|
-
return /* @__PURE__ */ (0,
|
|
2558
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2039
2559
|
Button,
|
|
2040
2560
|
{
|
|
2041
2561
|
variant: node.variant ?? "default",
|
|
@@ -2057,7 +2577,7 @@ var ToggleNode = ({ node }) => {
|
|
|
2057
2577
|
dispatch({ type: "toggle", path: node.binding });
|
|
2058
2578
|
run(node.onChange);
|
|
2059
2579
|
};
|
|
2060
|
-
return /* @__PURE__ */ (0,
|
|
2580
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
2061
2581
|
"label",
|
|
2062
2582
|
{
|
|
2063
2583
|
className: cn(
|
|
@@ -2065,7 +2585,7 @@ var ToggleNode = ({ node }) => {
|
|
|
2065
2585
|
node.className
|
|
2066
2586
|
),
|
|
2067
2587
|
children: [
|
|
2068
|
-
/* @__PURE__ */ (0,
|
|
2588
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2069
2589
|
"button",
|
|
2070
2590
|
{
|
|
2071
2591
|
type: "button",
|
|
@@ -2076,7 +2596,7 @@ var ToggleNode = ({ node }) => {
|
|
|
2076
2596
|
"relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-[background,box-shadow,border-color] duration-200",
|
|
2077
2597
|
value ? "border-foreground/15 bg-gradient-to-b from-primary-fill-from to-primary-fill-to shadow-card" : cn(TIMBAL_V2_SWITCH_TRACK_OFF, "hover:from-secondary-fill-hover-from hover:to-secondary-fill-hover-to")
|
|
2078
2598
|
),
|
|
2079
|
-
children: /* @__PURE__ */ (0,
|
|
2599
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2080
2600
|
"span",
|
|
2081
2601
|
{
|
|
2082
2602
|
className: cn(
|
|
@@ -2089,7 +2609,7 @@ var ToggleNode = ({ node }) => {
|
|
|
2089
2609
|
)
|
|
2090
2610
|
}
|
|
2091
2611
|
),
|
|
2092
|
-
label && /* @__PURE__ */ (0,
|
|
2612
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-foreground/85", children: label })
|
|
2093
2613
|
]
|
|
2094
2614
|
}
|
|
2095
2615
|
);
|
|
@@ -2109,12 +2629,12 @@ var SliderNode = ({ node }) => {
|
|
|
2109
2629
|
const next = Number(e.target.value);
|
|
2110
2630
|
dispatch({ type: "set", path: node.binding, value: next });
|
|
2111
2631
|
};
|
|
2112
|
-
return /* @__PURE__ */ (0,
|
|
2113
|
-
(label || showValue) && /* @__PURE__ */ (0,
|
|
2114
|
-
label && /* @__PURE__ */ (0,
|
|
2115
|
-
showValue && /* @__PURE__ */ (0,
|
|
2632
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: cn("aui-ui-slider flex flex-col gap-1", node.className), children: [
|
|
2633
|
+
(label || showValue) && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center justify-between text-xs text-muted-foreground", children: [
|
|
2634
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: label }),
|
|
2635
|
+
showValue && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "font-mono", children: value })
|
|
2116
2636
|
] }),
|
|
2117
|
-
/* @__PURE__ */ (0,
|
|
2637
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2118
2638
|
"input",
|
|
2119
2639
|
{
|
|
2120
2640
|
type: "range",
|
|
@@ -2136,9 +2656,9 @@ var SliderNode = ({ node }) => {
|
|
|
2136
2656
|
var TooltipNode = ({ node }) => {
|
|
2137
2657
|
const state = useUiState();
|
|
2138
2658
|
const content = String(resolveBindable(node.content, state) ?? "");
|
|
2139
|
-
return /* @__PURE__ */ (0,
|
|
2140
|
-
/* @__PURE__ */ (0,
|
|
2141
|
-
/* @__PURE__ */ (0,
|
|
2659
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Tooltip, { children: [
|
|
2660
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: cn("aui-ui-tooltip-trigger inline-flex", node.className), children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(UiNodeView, { node: node.child }) }) }),
|
|
2661
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipContent, { side: node.side ?? "top", children: content })
|
|
2142
2662
|
] }) });
|
|
2143
2663
|
};
|
|
2144
2664
|
var DraggableNode = ({ node }) => {
|
|
@@ -2146,8 +2666,8 @@ var DraggableNode = ({ node }) => {
|
|
|
2146
2666
|
const snapBack = node.snapBack ?? true;
|
|
2147
2667
|
const axis = node.axis ?? "both";
|
|
2148
2668
|
const dragProp = axis === "both" ? true : axis;
|
|
2149
|
-
return /* @__PURE__ */ (0,
|
|
2150
|
-
|
|
2669
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2670
|
+
import_react16.motion.div,
|
|
2151
2671
|
{
|
|
2152
2672
|
drag: dragProp,
|
|
2153
2673
|
dragMomentum: false,
|
|
@@ -2158,7 +2678,7 @@ var DraggableNode = ({ node }) => {
|
|
|
2158
2678
|
"aui-ui-draggable inline-block cursor-grab touch-none",
|
|
2159
2679
|
node.className
|
|
2160
2680
|
),
|
|
2161
|
-
children: /* @__PURE__ */ (0,
|
|
2681
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(UiNodeView, { node: node.child })
|
|
2162
2682
|
}
|
|
2163
2683
|
);
|
|
2164
2684
|
};
|
|
@@ -2168,8 +2688,8 @@ var CustomNode = ({ node }) => {
|
|
|
2168
2688
|
const Renderer = registry[node.name];
|
|
2169
2689
|
if (!Renderer) return null;
|
|
2170
2690
|
const resolvedProps = resolveProps(node.props ?? {}, state);
|
|
2171
|
-
const children = node.children?.map((child, i) => /* @__PURE__ */ (0,
|
|
2172
|
-
return /* @__PURE__ */ (0,
|
|
2691
|
+
const children = node.children?.map((child, i) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(UiNodeView, { node: child }, child.id ?? i));
|
|
2692
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Renderer, { props: resolvedProps, children });
|
|
2173
2693
|
};
|
|
2174
2694
|
function resolveProps(props, state) {
|
|
2175
2695
|
const out = {};
|
|
@@ -2180,17 +2700,17 @@ function resolveProps(props, state) {
|
|
|
2180
2700
|
}
|
|
2181
2701
|
|
|
2182
2702
|
// src/artifacts/ui/ui-artifact.tsx
|
|
2183
|
-
var
|
|
2703
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
2184
2704
|
var UiArtifactView = ({ artifact }) => {
|
|
2185
|
-
const [state, dispatch] = (0,
|
|
2705
|
+
const [state, dispatch] = (0, import_react18.useReducer)(
|
|
2186
2706
|
uiStateReducer,
|
|
2187
2707
|
artifact.initialState ?? {}
|
|
2188
2708
|
);
|
|
2189
|
-
return /* @__PURE__ */ (0,
|
|
2709
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ArtifactCard, { title: artifact.title, kind: "ui", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(UiStateProvider, { state, dispatch, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "aui-ui-root p-3", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(UiNodeView, { node: artifact.root }) }) }) });
|
|
2190
2710
|
};
|
|
2191
2711
|
|
|
2192
2712
|
// src/artifacts/registry.tsx
|
|
2193
|
-
var
|
|
2713
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
2194
2714
|
var defaultArtifactRenderers = {
|
|
2195
2715
|
chart: ChartArtifactView,
|
|
2196
2716
|
question: QuestionArtifactView,
|
|
@@ -2199,25 +2719,25 @@ var defaultArtifactRenderers = {
|
|
|
2199
2719
|
table: TableArtifactView,
|
|
2200
2720
|
ui: UiArtifactView
|
|
2201
2721
|
};
|
|
2202
|
-
var ArtifactRegistryContext = (0,
|
|
2722
|
+
var ArtifactRegistryContext = (0, import_react19.createContext)(
|
|
2203
2723
|
defaultArtifactRenderers
|
|
2204
2724
|
);
|
|
2205
2725
|
var ArtifactRegistryProvider = ({ renderers, override, children }) => {
|
|
2206
|
-
const merged = (0,
|
|
2726
|
+
const merged = (0, import_react19.useMemo)(() => {
|
|
2207
2727
|
if (!renderers) return defaultArtifactRenderers;
|
|
2208
2728
|
if (override) return renderers;
|
|
2209
2729
|
return { ...defaultArtifactRenderers, ...renderers };
|
|
2210
2730
|
}, [renderers, override]);
|
|
2211
|
-
return /* @__PURE__ */ (0,
|
|
2731
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ArtifactRegistryContext.Provider, { value: merged, children });
|
|
2212
2732
|
};
|
|
2213
2733
|
function useArtifactRegistry() {
|
|
2214
|
-
return (0,
|
|
2734
|
+
return (0, import_react19.useContext)(ArtifactRegistryContext);
|
|
2215
2735
|
}
|
|
2216
2736
|
var ArtifactView = ({ artifact }) => {
|
|
2217
2737
|
const registry = useArtifactRegistry();
|
|
2218
2738
|
const Renderer = registry[artifact.type] ?? registry.json;
|
|
2219
2739
|
if (!Renderer) return null;
|
|
2220
|
-
return /* @__PURE__ */ (0,
|
|
2740
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Renderer, { artifact });
|
|
2221
2741
|
};
|
|
2222
2742
|
|
|
2223
2743
|
// src/artifacts/types.ts
|
|
@@ -2298,7 +2818,7 @@ var import_c = __toESM(require("shiki/langs/c.mjs"), 1);
|
|
|
2298
2818
|
var import_cpp = __toESM(require("shiki/langs/cpp.mjs"), 1);
|
|
2299
2819
|
var import_vitesse_dark = __toESM(require("shiki/themes/vitesse-dark.mjs"), 1);
|
|
2300
2820
|
var import_vitesse_light = __toESM(require("shiki/themes/vitesse-light.mjs"), 1);
|
|
2301
|
-
var
|
|
2821
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
2302
2822
|
var SHIKI_THEME_DARK = "vitesse-dark";
|
|
2303
2823
|
var SHIKI_THEME_LIGHT = "vitesse-light";
|
|
2304
2824
|
var highlighterPromise = null;
|
|
@@ -2336,8 +2856,8 @@ var ShikiSyntaxHighlighter = ({
|
|
|
2336
2856
|
language,
|
|
2337
2857
|
code
|
|
2338
2858
|
}) => {
|
|
2339
|
-
const [html, setHtml] = (0,
|
|
2340
|
-
(0,
|
|
2859
|
+
const [html, setHtml] = (0, import_react20.useState)(null);
|
|
2860
|
+
(0, import_react20.useEffect)(() => {
|
|
2341
2861
|
let cancelled = false;
|
|
2342
2862
|
(async () => {
|
|
2343
2863
|
try {
|
|
@@ -2367,13 +2887,13 @@ var ShikiSyntaxHighlighter = ({
|
|
|
2367
2887
|
try {
|
|
2368
2888
|
const parsed = JSON.parse(code);
|
|
2369
2889
|
if (isArtifact(parsed)) {
|
|
2370
|
-
return /* @__PURE__ */ (0,
|
|
2890
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ArtifactView, { artifact: parsed });
|
|
2371
2891
|
}
|
|
2372
2892
|
} catch {
|
|
2373
2893
|
}
|
|
2374
2894
|
}
|
|
2375
2895
|
if (html) {
|
|
2376
|
-
return /* @__PURE__ */ (0,
|
|
2896
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
2377
2897
|
"div",
|
|
2378
2898
|
{
|
|
2379
2899
|
className: "shiki-wrapper [&>pre]:!m-0 [&>pre]:!rounded-t-none [&>pre]:!rounded-b-lg [&>pre]:!border [&>pre]:!border-t-0 [&>pre]:!border-border/50 [&>pre]:!p-3 [&>pre]:!text-xs [&>pre]:!leading-relaxed [&>pre]:overflow-x-auto",
|
|
@@ -2381,14 +2901,14 @@ var ShikiSyntaxHighlighter = ({
|
|
|
2381
2901
|
}
|
|
2382
2902
|
);
|
|
2383
2903
|
}
|
|
2384
|
-
return /* @__PURE__ */ (0,
|
|
2904
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Pre, { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Code2, { children: code }) });
|
|
2385
2905
|
};
|
|
2386
2906
|
var syntax_highlighter_default = ShikiSyntaxHighlighter;
|
|
2387
2907
|
|
|
2388
2908
|
// src/chat/markdown-text.tsx
|
|
2389
|
-
var
|
|
2909
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
2390
2910
|
var MarkdownTextImpl = () => {
|
|
2391
|
-
return /* @__PURE__ */ (0,
|
|
2911
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2392
2912
|
import_react_markdown.MarkdownTextPrimitive,
|
|
2393
2913
|
{
|
|
2394
2914
|
remarkPlugins: [import_remark_gfm.default, import_remark_math.default],
|
|
@@ -2401,7 +2921,7 @@ var MarkdownTextImpl = () => {
|
|
|
2401
2921
|
}
|
|
2402
2922
|
);
|
|
2403
2923
|
};
|
|
2404
|
-
var MarkdownText = (0,
|
|
2924
|
+
var MarkdownText = (0, import_react21.memo)(MarkdownTextImpl);
|
|
2405
2925
|
var CodeHeader = ({ language, code }) => {
|
|
2406
2926
|
const { isCopied, copyToClipboard } = useCopyToClipboard();
|
|
2407
2927
|
if (isArtifactFenceLanguage(language)) return null;
|
|
@@ -2409,20 +2929,20 @@ var CodeHeader = ({ language, code }) => {
|
|
|
2409
2929
|
if (!code || isCopied) return;
|
|
2410
2930
|
copyToClipboard(code);
|
|
2411
2931
|
};
|
|
2412
|
-
return /* @__PURE__ */ (0,
|
|
2413
|
-
/* @__PURE__ */ (0,
|
|
2414
|
-
/* @__PURE__ */ (0,
|
|
2932
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "aui-code-header flex items-center justify-between rounded-t-lg border border-b-0 border-border/50 bg-code-header-bg px-4 py-2", children: [
|
|
2933
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "flex items-center gap-2 text-xs font-semibold tracking-wide text-muted-foreground/80 uppercase", children: [
|
|
2934
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "inline-block h-2 w-2 rounded-full bg-primary/40" }),
|
|
2415
2935
|
language
|
|
2416
2936
|
] }),
|
|
2417
|
-
/* @__PURE__ */ (0,
|
|
2937
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
2418
2938
|
TooltipIconButton,
|
|
2419
2939
|
{
|
|
2420
2940
|
tooltip: isCopied ? "Copied!" : "Copy",
|
|
2421
2941
|
onClick: onCopy,
|
|
2422
2942
|
className: "transition-colors hover:text-foreground",
|
|
2423
2943
|
children: [
|
|
2424
|
-
!isCopied && /* @__PURE__ */ (0,
|
|
2425
|
-
isCopied && /* @__PURE__ */ (0,
|
|
2944
|
+
!isCopied && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react4.CopyIcon, { className: "h-3.5 w-3.5" }),
|
|
2945
|
+
isCopied && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react4.CheckIcon, { className: "h-3.5 w-3.5 text-emerald-500" })
|
|
2426
2946
|
]
|
|
2427
2947
|
}
|
|
2428
2948
|
)
|
|
@@ -2431,7 +2951,7 @@ var CodeHeader = ({ language, code }) => {
|
|
|
2431
2951
|
var useCopyToClipboard = ({
|
|
2432
2952
|
copiedDuration = 3e3
|
|
2433
2953
|
} = {}) => {
|
|
2434
|
-
const [isCopied, setIsCopied] = (0,
|
|
2954
|
+
const [isCopied, setIsCopied] = (0, import_react21.useState)(false);
|
|
2435
2955
|
const copyToClipboard = (value) => {
|
|
2436
2956
|
if (!value) return;
|
|
2437
2957
|
navigator.clipboard.writeText(value).then(() => {
|
|
@@ -2442,7 +2962,7 @@ var useCopyToClipboard = ({
|
|
|
2442
2962
|
return { isCopied, copyToClipboard };
|
|
2443
2963
|
};
|
|
2444
2964
|
var defaultComponents = (0, import_react_markdown.unstable_memoizeMarkdownComponents)({
|
|
2445
|
-
h1: ({ className, ...props }) => /* @__PURE__ */ (0,
|
|
2965
|
+
h1: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2446
2966
|
"h1",
|
|
2447
2967
|
{
|
|
2448
2968
|
className: cn(
|
|
@@ -2452,7 +2972,7 @@ var defaultComponents = (0, import_react_markdown.unstable_memoizeMarkdownCompon
|
|
|
2452
2972
|
...props
|
|
2453
2973
|
}
|
|
2454
2974
|
),
|
|
2455
|
-
h2: ({ className, ...props }) => /* @__PURE__ */ (0,
|
|
2975
|
+
h2: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2456
2976
|
"h2",
|
|
2457
2977
|
{
|
|
2458
2978
|
className: cn(
|
|
@@ -2462,7 +2982,7 @@ var defaultComponents = (0, import_react_markdown.unstable_memoizeMarkdownCompon
|
|
|
2462
2982
|
...props
|
|
2463
2983
|
}
|
|
2464
2984
|
),
|
|
2465
|
-
h3: ({ className, ...props }) => /* @__PURE__ */ (0,
|
|
2985
|
+
h3: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2466
2986
|
"h3",
|
|
2467
2987
|
{
|
|
2468
2988
|
className: cn(
|
|
@@ -2472,7 +2992,7 @@ var defaultComponents = (0, import_react_markdown.unstable_memoizeMarkdownCompon
|
|
|
2472
2992
|
...props
|
|
2473
2993
|
}
|
|
2474
2994
|
),
|
|
2475
|
-
h4: ({ className, ...props }) => /* @__PURE__ */ (0,
|
|
2995
|
+
h4: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2476
2996
|
"h4",
|
|
2477
2997
|
{
|
|
2478
2998
|
className: cn(
|
|
@@ -2482,7 +3002,7 @@ var defaultComponents = (0, import_react_markdown.unstable_memoizeMarkdownCompon
|
|
|
2482
3002
|
...props
|
|
2483
3003
|
}
|
|
2484
3004
|
),
|
|
2485
|
-
h5: ({ className, ...props }) => /* @__PURE__ */ (0,
|
|
3005
|
+
h5: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2486
3006
|
"h5",
|
|
2487
3007
|
{
|
|
2488
3008
|
className: cn(
|
|
@@ -2492,7 +3012,7 @@ var defaultComponents = (0, import_react_markdown.unstable_memoizeMarkdownCompon
|
|
|
2492
3012
|
...props
|
|
2493
3013
|
}
|
|
2494
3014
|
),
|
|
2495
|
-
h6: ({ className, ...props }) => /* @__PURE__ */ (0,
|
|
3015
|
+
h6: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2496
3016
|
"h6",
|
|
2497
3017
|
{
|
|
2498
3018
|
className: cn(
|
|
@@ -2502,7 +3022,7 @@ var defaultComponents = (0, import_react_markdown.unstable_memoizeMarkdownCompon
|
|
|
2502
3022
|
...props
|
|
2503
3023
|
}
|
|
2504
3024
|
),
|
|
2505
|
-
p: ({ className, ...props }) => /* @__PURE__ */ (0,
|
|
3025
|
+
p: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2506
3026
|
"p",
|
|
2507
3027
|
{
|
|
2508
3028
|
className: cn(
|
|
@@ -2512,7 +3032,7 @@ var defaultComponents = (0, import_react_markdown.unstable_memoizeMarkdownCompon
|
|
|
2512
3032
|
...props
|
|
2513
3033
|
}
|
|
2514
3034
|
),
|
|
2515
|
-
a: ({ className, ...props }) => /* @__PURE__ */ (0,
|
|
3035
|
+
a: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2516
3036
|
"a",
|
|
2517
3037
|
{
|
|
2518
3038
|
className: cn(
|
|
@@ -2524,7 +3044,7 @@ var defaultComponents = (0, import_react_markdown.unstable_memoizeMarkdownCompon
|
|
|
2524
3044
|
...props
|
|
2525
3045
|
}
|
|
2526
3046
|
),
|
|
2527
|
-
blockquote: ({ className, ...props }) => /* @__PURE__ */ (0,
|
|
3047
|
+
blockquote: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2528
3048
|
"blockquote",
|
|
2529
3049
|
{
|
|
2530
3050
|
className: cn(
|
|
@@ -2534,7 +3054,7 @@ var defaultComponents = (0, import_react_markdown.unstable_memoizeMarkdownCompon
|
|
|
2534
3054
|
...props
|
|
2535
3055
|
}
|
|
2536
3056
|
),
|
|
2537
|
-
ul: ({ className, ...props }) => /* @__PURE__ */ (0,
|
|
3057
|
+
ul: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2538
3058
|
"ul",
|
|
2539
3059
|
{
|
|
2540
3060
|
className: cn(
|
|
@@ -2544,7 +3064,7 @@ var defaultComponents = (0, import_react_markdown.unstable_memoizeMarkdownCompon
|
|
|
2544
3064
|
...props
|
|
2545
3065
|
}
|
|
2546
3066
|
),
|
|
2547
|
-
ol: ({ className, ...props }) => /* @__PURE__ */ (0,
|
|
3067
|
+
ol: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2548
3068
|
"ol",
|
|
2549
3069
|
{
|
|
2550
3070
|
className: cn(
|
|
@@ -2554,7 +3074,7 @@ var defaultComponents = (0, import_react_markdown.unstable_memoizeMarkdownCompon
|
|
|
2554
3074
|
...props
|
|
2555
3075
|
}
|
|
2556
3076
|
),
|
|
2557
|
-
hr: ({ className, ...props }) => /* @__PURE__ */ (0,
|
|
3077
|
+
hr: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2558
3078
|
"hr",
|
|
2559
3079
|
{
|
|
2560
3080
|
className: cn(
|
|
@@ -2564,14 +3084,14 @@ var defaultComponents = (0, import_react_markdown.unstable_memoizeMarkdownCompon
|
|
|
2564
3084
|
...props
|
|
2565
3085
|
}
|
|
2566
3086
|
),
|
|
2567
|
-
table: ({ className, ...props }) => /* @__PURE__ */ (0,
|
|
3087
|
+
table: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "my-4 w-full overflow-x-auto rounded-lg border border-border/50", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2568
3088
|
"table",
|
|
2569
3089
|
{
|
|
2570
3090
|
className: cn("aui-md-table w-full border-collapse text-sm", className),
|
|
2571
3091
|
...props
|
|
2572
3092
|
}
|
|
2573
3093
|
) }),
|
|
2574
|
-
th: ({ className, ...props }) => /* @__PURE__ */ (0,
|
|
3094
|
+
th: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2575
3095
|
"th",
|
|
2576
3096
|
{
|
|
2577
3097
|
className: cn(
|
|
@@ -2581,7 +3101,7 @@ var defaultComponents = (0, import_react_markdown.unstable_memoizeMarkdownCompon
|
|
|
2581
3101
|
...props
|
|
2582
3102
|
}
|
|
2583
3103
|
),
|
|
2584
|
-
td: ({ className, ...props }) => /* @__PURE__ */ (0,
|
|
3104
|
+
td: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2585
3105
|
"td",
|
|
2586
3106
|
{
|
|
2587
3107
|
className: cn(
|
|
@@ -2591,7 +3111,7 @@ var defaultComponents = (0, import_react_markdown.unstable_memoizeMarkdownCompon
|
|
|
2591
3111
|
...props
|
|
2592
3112
|
}
|
|
2593
3113
|
),
|
|
2594
|
-
tr: ({ className, ...props }) => /* @__PURE__ */ (0,
|
|
3114
|
+
tr: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2595
3115
|
"tr",
|
|
2596
3116
|
{
|
|
2597
3117
|
className: cn(
|
|
@@ -2601,8 +3121,8 @@ var defaultComponents = (0, import_react_markdown.unstable_memoizeMarkdownCompon
|
|
|
2601
3121
|
...props
|
|
2602
3122
|
}
|
|
2603
3123
|
),
|
|
2604
|
-
li: ({ className, ...props }) => /* @__PURE__ */ (0,
|
|
2605
|
-
sup: ({ className, ...props }) => /* @__PURE__ */ (0,
|
|
3124
|
+
li: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("li", { className: cn("aui-md-li leading-[1.7]", className), ...props }),
|
|
3125
|
+
sup: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2606
3126
|
"sup",
|
|
2607
3127
|
{
|
|
2608
3128
|
className: cn(
|
|
@@ -2612,7 +3132,7 @@ var defaultComponents = (0, import_react_markdown.unstable_memoizeMarkdownCompon
|
|
|
2612
3132
|
...props
|
|
2613
3133
|
}
|
|
2614
3134
|
),
|
|
2615
|
-
pre: ({ className, ...props }) => /* @__PURE__ */ (0,
|
|
3135
|
+
pre: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2616
3136
|
"pre",
|
|
2617
3137
|
{
|
|
2618
3138
|
className: cn(
|
|
@@ -2624,7 +3144,7 @@ var defaultComponents = (0, import_react_markdown.unstable_memoizeMarkdownCompon
|
|
|
2624
3144
|
),
|
|
2625
3145
|
code: function Code({ className, ...props }) {
|
|
2626
3146
|
const isCodeBlock = (0, import_react_markdown.useIsMarkdownCodeBlock)();
|
|
2627
|
-
return /* @__PURE__ */ (0,
|
|
3147
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2628
3148
|
"code",
|
|
2629
3149
|
{
|
|
2630
3150
|
className: cn(
|
|
@@ -2635,20 +3155,20 @@ var defaultComponents = (0, import_react_markdown.unstable_memoizeMarkdownCompon
|
|
|
2635
3155
|
}
|
|
2636
3156
|
);
|
|
2637
3157
|
},
|
|
2638
|
-
strong: ({ className, ...props }) => /* @__PURE__ */ (0,
|
|
2639
|
-
em: ({ className, ...props }) => /* @__PURE__ */ (0,
|
|
3158
|
+
strong: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("strong", { className: cn("font-semibold text-foreground", className), ...props }),
|
|
3159
|
+
em: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("em", { className: cn("italic", className), ...props }),
|
|
2640
3160
|
CodeHeader
|
|
2641
3161
|
});
|
|
2642
3162
|
|
|
2643
3163
|
// src/chat/tool-fallback.tsx
|
|
2644
|
-
var
|
|
3164
|
+
var import_react28 = require("react");
|
|
2645
3165
|
var import_lucide_react5 = require("lucide-react");
|
|
2646
|
-
var
|
|
3166
|
+
var import_react29 = require("@assistant-ui/react");
|
|
2647
3167
|
|
|
2648
3168
|
// src/ui/shimmer.tsx
|
|
2649
|
-
var
|
|
2650
|
-
var
|
|
2651
|
-
var
|
|
3169
|
+
var import_react22 = require("motion/react");
|
|
3170
|
+
var import_react23 = require("react");
|
|
3171
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
2652
3172
|
var ShimmerComponent = ({
|
|
2653
3173
|
children,
|
|
2654
3174
|
as: Component = "p",
|
|
@@ -2656,14 +3176,14 @@ var ShimmerComponent = ({
|
|
|
2656
3176
|
duration = 2,
|
|
2657
3177
|
spread = 2
|
|
2658
3178
|
}) => {
|
|
2659
|
-
const MotionComponent =
|
|
3179
|
+
const MotionComponent = import_react22.motion.create(
|
|
2660
3180
|
Component
|
|
2661
3181
|
);
|
|
2662
|
-
const dynamicSpread = (0,
|
|
3182
|
+
const dynamicSpread = (0, import_react23.useMemo)(
|
|
2663
3183
|
() => (children?.length ?? 0) * spread,
|
|
2664
3184
|
[children, spread]
|
|
2665
3185
|
);
|
|
2666
|
-
return /* @__PURE__ */ (0,
|
|
3186
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
2667
3187
|
MotionComponent,
|
|
2668
3188
|
{
|
|
2669
3189
|
animate: { backgroundPosition: "0% center" },
|
|
@@ -2686,11 +3206,11 @@ var ShimmerComponent = ({
|
|
|
2686
3206
|
}
|
|
2687
3207
|
);
|
|
2688
3208
|
};
|
|
2689
|
-
var Shimmer = (0,
|
|
3209
|
+
var Shimmer = (0, import_react23.memo)(ShimmerComponent);
|
|
2690
3210
|
|
|
2691
3211
|
// src/chat/motion.tsx
|
|
2692
|
-
var
|
|
2693
|
-
var
|
|
3212
|
+
var import_react24 = require("motion/react");
|
|
3213
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
2694
3214
|
var luxuryEase = [0.16, 1, 0.3, 1];
|
|
2695
3215
|
var TOOL_ENTER_MS = 0.78;
|
|
2696
3216
|
var TOOL_EXIT_MS = 0.28;
|
|
@@ -2716,10 +3236,10 @@ function toolMotionState(reduced, entering, variant) {
|
|
|
2716
3236
|
return entering ? { opacity: 0, y: 14, filter: "blur(10px)" } : { opacity: 1, y: 0, filter: "blur(0px)" };
|
|
2717
3237
|
}
|
|
2718
3238
|
function ToolMotion({ children, className, motionKey }) {
|
|
2719
|
-
const reduced = (0,
|
|
3239
|
+
const reduced = (0, import_react24.useReducedMotion)() ?? false;
|
|
2720
3240
|
const { enter, exit } = toolPresenceTransition(reduced);
|
|
2721
|
-
return /* @__PURE__ */ (0,
|
|
2722
|
-
|
|
3241
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
3242
|
+
import_react24.motion.div,
|
|
2723
3243
|
{
|
|
2724
3244
|
className: cn("aui-tool-motion w-full min-w-0", className),
|
|
2725
3245
|
initial: toolMotionState(reduced, true, "settled"),
|
|
@@ -2738,11 +3258,11 @@ function ToolPresence({
|
|
|
2738
3258
|
className,
|
|
2739
3259
|
variant = "settled"
|
|
2740
3260
|
}) {
|
|
2741
|
-
const reduced = (0,
|
|
3261
|
+
const reduced = (0, import_react24.useReducedMotion)() ?? false;
|
|
2742
3262
|
const { enter, exit } = toolPresenceTransition(reduced);
|
|
2743
3263
|
const enterTransition = variant === "executing" ? { duration: reduced ? 0.3 : 0.52, ease: luxuryEase } : enter;
|
|
2744
|
-
return /* @__PURE__ */ (0,
|
|
2745
|
-
|
|
3264
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react24.AnimatePresence, { mode: "wait", initial: true, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
3265
|
+
import_react24.motion.div,
|
|
2746
3266
|
{
|
|
2747
3267
|
className: cn("aui-tool-presence w-full min-w-0", className),
|
|
2748
3268
|
initial: toolMotionState(reduced, true, variant),
|
|
@@ -2762,8 +3282,8 @@ function ToolBodyPresence({
|
|
|
2762
3282
|
children,
|
|
2763
3283
|
className
|
|
2764
3284
|
}) {
|
|
2765
|
-
const reduced = (0,
|
|
2766
|
-
return /* @__PURE__ */ (0,
|
|
3285
|
+
const reduced = (0, import_react24.useReducedMotion)() ?? false;
|
|
3286
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
2767
3287
|
"div",
|
|
2768
3288
|
{
|
|
2769
3289
|
className: cn(
|
|
@@ -2771,7 +3291,7 @@ function ToolBodyPresence({
|
|
|
2771
3291
|
open ? reduced ? "duration-200 ease-out" : "duration-[340ms] ease-[cubic-bezier(0.16,1,0.3,1)]" : reduced ? "duration-150 ease-[cubic-bezier(0.4,0,0.2,1)]" : "duration-200 ease-[cubic-bezier(0.4,0,0.2,1)]"
|
|
2772
3292
|
),
|
|
2773
3293
|
style: { gridTemplateRows: open ? "1fr" : "0fr" },
|
|
2774
|
-
children: /* @__PURE__ */ (0,
|
|
3294
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "min-h-0 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
2775
3295
|
"div",
|
|
2776
3296
|
{
|
|
2777
3297
|
className: cn(
|
|
@@ -2787,8 +3307,8 @@ function ToolBodyPresence({
|
|
|
2787
3307
|
}
|
|
2788
3308
|
|
|
2789
3309
|
// src/runtime/provider.tsx
|
|
2790
|
-
var
|
|
2791
|
-
var
|
|
3310
|
+
var import_react26 = require("react");
|
|
3311
|
+
var import_react27 = require("@assistant-ui/react");
|
|
2792
3312
|
var import_timbal_sdk = require("@timbal-ai/timbal-sdk");
|
|
2793
3313
|
|
|
2794
3314
|
// src/auth/tokens.ts
|
|
@@ -3203,17 +3723,17 @@ function buildPromptBody({
|
|
|
3203
3723
|
}
|
|
3204
3724
|
|
|
3205
3725
|
// src/runtime/attachments-context.tsx
|
|
3206
|
-
var
|
|
3207
|
-
var
|
|
3208
|
-
var TimbalAttachmentsEnabledContext = (0,
|
|
3726
|
+
var import_react25 = require("react");
|
|
3727
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
3728
|
+
var TimbalAttachmentsEnabledContext = (0, import_react25.createContext)(false);
|
|
3209
3729
|
function TimbalAttachmentsEnabledProvider({
|
|
3210
3730
|
enabled,
|
|
3211
3731
|
children
|
|
3212
3732
|
}) {
|
|
3213
|
-
return /* @__PURE__ */ (0,
|
|
3733
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TimbalAttachmentsEnabledContext.Provider, { value: enabled, children });
|
|
3214
3734
|
}
|
|
3215
3735
|
function useTimbalAttachmentsEnabled() {
|
|
3216
|
-
return (0,
|
|
3736
|
+
return (0, import_react25.useContext)(TimbalAttachmentsEnabledContext);
|
|
3217
3737
|
}
|
|
3218
3738
|
|
|
3219
3739
|
// src/runtime/upload-adapter.ts
|
|
@@ -3322,7 +3842,7 @@ function resolveAttachmentAdapter(attachments, options = {}) {
|
|
|
3322
3842
|
}
|
|
3323
3843
|
|
|
3324
3844
|
// src/runtime/provider.tsx
|
|
3325
|
-
var
|
|
3845
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
3326
3846
|
function projectAttachment(attachment) {
|
|
3327
3847
|
const filename = attachment.name ?? "attachment";
|
|
3328
3848
|
const mimeType = attachment.contentType ?? "application/octet-stream";
|
|
@@ -3387,22 +3907,22 @@ function useTimbalStream({
|
|
|
3387
3907
|
fetch: fetchFn,
|
|
3388
3908
|
debug = false
|
|
3389
3909
|
}) {
|
|
3390
|
-
const [messages, setMessages] = (0,
|
|
3391
|
-
const [isRunning, setIsRunning] = (0,
|
|
3392
|
-
const abortRef = (0,
|
|
3393
|
-
const messagesRef = (0,
|
|
3394
|
-
const fetchFnRef = (0,
|
|
3395
|
-
(0,
|
|
3910
|
+
const [messages, setMessages] = (0, import_react26.useState)([]);
|
|
3911
|
+
const [isRunning, setIsRunning] = (0, import_react26.useState)(false);
|
|
3912
|
+
const abortRef = (0, import_react26.useRef)(null);
|
|
3913
|
+
const messagesRef = (0, import_react26.useRef)([]);
|
|
3914
|
+
const fetchFnRef = (0, import_react26.useRef)(fetchFn ?? authFetch);
|
|
3915
|
+
(0, import_react26.useEffect)(() => {
|
|
3396
3916
|
fetchFnRef.current = fetchFn ?? authFetch;
|
|
3397
3917
|
}, [fetchFn]);
|
|
3398
|
-
const debugRef = (0,
|
|
3399
|
-
(0,
|
|
3918
|
+
const debugRef = (0, import_react26.useRef)(debug);
|
|
3919
|
+
(0, import_react26.useEffect)(() => {
|
|
3400
3920
|
debugRef.current = debug;
|
|
3401
3921
|
}, [debug]);
|
|
3402
|
-
(0,
|
|
3922
|
+
(0, import_react26.useEffect)(() => {
|
|
3403
3923
|
messagesRef.current = messages;
|
|
3404
3924
|
}, [messages]);
|
|
3405
|
-
const streamAssistantResponse = (0,
|
|
3925
|
+
const streamAssistantResponse = (0, import_react26.useCallback)(
|
|
3406
3926
|
async (input, attachments, userId, assistantId, parentId, signal) => {
|
|
3407
3927
|
const state = createReducerState();
|
|
3408
3928
|
const flush = () => {
|
|
@@ -3481,7 +4001,7 @@ function useTimbalStream({
|
|
|
3481
4001
|
},
|
|
3482
4002
|
[workforceId, baseUrl]
|
|
3483
4003
|
);
|
|
3484
|
-
const send = (0,
|
|
4004
|
+
const send = (0, import_react26.useCallback)(
|
|
3485
4005
|
async (input, options) => {
|
|
3486
4006
|
const userId = crypto.randomUUID();
|
|
3487
4007
|
const assistantId = crypto.randomUUID();
|
|
@@ -3512,7 +4032,7 @@ function useTimbalStream({
|
|
|
3512
4032
|
},
|
|
3513
4033
|
[streamAssistantResponse]
|
|
3514
4034
|
);
|
|
3515
|
-
const reload = (0,
|
|
4035
|
+
const reload = (0, import_react26.useCallback)(
|
|
3516
4036
|
async (messageId) => {
|
|
3517
4037
|
const current = messagesRef.current;
|
|
3518
4038
|
const idx = messageId ? current.findIndex((m) => m.id === messageId) : current.length - 2;
|
|
@@ -3541,14 +4061,14 @@ function useTimbalStream({
|
|
|
3541
4061
|
},
|
|
3542
4062
|
[streamAssistantResponse]
|
|
3543
4063
|
);
|
|
3544
|
-
const cancel = (0,
|
|
4064
|
+
const cancel = (0, import_react26.useCallback)(() => {
|
|
3545
4065
|
abortRef.current?.abort();
|
|
3546
4066
|
}, []);
|
|
3547
|
-
const clear = (0,
|
|
4067
|
+
const clear = (0, import_react26.useCallback)(() => {
|
|
3548
4068
|
abortRef.current?.abort();
|
|
3549
4069
|
setMessages([]);
|
|
3550
4070
|
}, []);
|
|
3551
|
-
return (0,
|
|
4071
|
+
return (0, import_react26.useMemo)(
|
|
3552
4072
|
() => ({ messages, isRunning, send, reload, cancel, clear }),
|
|
3553
4073
|
[messages, isRunning, send, reload, cancel, clear]
|
|
3554
4074
|
);
|
|
@@ -3559,9 +4079,9 @@ function readTopLevelStartRunId(event) {
|
|
|
3559
4079
|
}
|
|
3560
4080
|
return null;
|
|
3561
4081
|
}
|
|
3562
|
-
var TimbalStreamContext = (0,
|
|
4082
|
+
var TimbalStreamContext = (0, import_react26.createContext)(null);
|
|
3563
4083
|
function useTimbalRuntime() {
|
|
3564
|
-
const ctx = (0,
|
|
4084
|
+
const ctx = (0, import_react26.useContext)(TimbalStreamContext);
|
|
3565
4085
|
if (!ctx) {
|
|
3566
4086
|
throw new Error(
|
|
3567
4087
|
"useTimbalRuntime must be used inside a <TimbalRuntimeProvider>."
|
|
@@ -3585,7 +4105,7 @@ function TimbalRuntimeProvider({
|
|
|
3585
4105
|
fetch: fetchFn,
|
|
3586
4106
|
debug
|
|
3587
4107
|
});
|
|
3588
|
-
const attachmentAdapter = (0,
|
|
4108
|
+
const attachmentAdapter = (0, import_react26.useMemo)(
|
|
3589
4109
|
() => resolveAttachmentAdapter(attachments, {
|
|
3590
4110
|
baseUrl,
|
|
3591
4111
|
fetch: fetchFn,
|
|
@@ -3594,7 +4114,7 @@ function TimbalRuntimeProvider({
|
|
|
3594
4114
|
}),
|
|
3595
4115
|
[attachments, attachmentsUploadUrl, attachmentsAccept, baseUrl, fetchFn]
|
|
3596
4116
|
);
|
|
3597
|
-
const onNew = (0,
|
|
4117
|
+
const onNew = (0, import_react26.useCallback)(
|
|
3598
4118
|
async (message) => {
|
|
3599
4119
|
const textPart = message.content.find((c) => c.type === "text");
|
|
3600
4120
|
const input = textPart && textPart.type === "text" ? textPart.text : "";
|
|
@@ -3609,16 +4129,16 @@ function TimbalRuntimeProvider({
|
|
|
3609
4129
|
},
|
|
3610
4130
|
[stream]
|
|
3611
4131
|
);
|
|
3612
|
-
const onReload = (0,
|
|
4132
|
+
const onReload = (0, import_react26.useCallback)(
|
|
3613
4133
|
async (messageId) => {
|
|
3614
4134
|
await stream.reload(messageId);
|
|
3615
4135
|
},
|
|
3616
4136
|
[stream]
|
|
3617
4137
|
);
|
|
3618
|
-
const onCancel = (0,
|
|
4138
|
+
const onCancel = (0, import_react26.useCallback)(async () => {
|
|
3619
4139
|
stream.cancel();
|
|
3620
4140
|
}, [stream]);
|
|
3621
|
-
const runtime = (0,
|
|
4141
|
+
const runtime = (0, import_react27.useExternalStoreRuntime)({
|
|
3622
4142
|
isRunning: stream.isRunning,
|
|
3623
4143
|
messages: stream.messages,
|
|
3624
4144
|
convertMessage,
|
|
@@ -3628,7 +4148,7 @@ function TimbalRuntimeProvider({
|
|
|
3628
4148
|
onCancel,
|
|
3629
4149
|
...attachmentAdapter ? { adapters: { attachments: attachmentAdapter } } : {}
|
|
3630
4150
|
});
|
|
3631
|
-
return /* @__PURE__ */ (0,
|
|
4151
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(TimbalStreamContext.Provider, { value: stream, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(TimbalAttachmentsEnabledProvider, { enabled: attachmentAdapter !== void 0, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_react27.AssistantRuntimeProvider, { runtime, children }) }) });
|
|
3632
4152
|
}
|
|
3633
4153
|
function findParentIdFromAuiParent(messages, auiParentId) {
|
|
3634
4154
|
const idx = messages.findIndex((m) => m.id === auiParentId);
|
|
@@ -3637,7 +4157,7 @@ function findParentIdFromAuiParent(messages, auiParentId) {
|
|
|
3637
4157
|
}
|
|
3638
4158
|
|
|
3639
4159
|
// src/chat/tool-fallback.tsx
|
|
3640
|
-
var
|
|
4160
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
3641
4161
|
function detectRunning({
|
|
3642
4162
|
status,
|
|
3643
4163
|
result,
|
|
@@ -3651,7 +4171,7 @@ function detectRunning({
|
|
|
3651
4171
|
}
|
|
3652
4172
|
function useToolRunning(props) {
|
|
3653
4173
|
const { isRunning: streamRunning } = useTimbalRuntime();
|
|
3654
|
-
const partStatus = (0,
|
|
4174
|
+
const partStatus = (0, import_react29.useAuiState)((s) => s.part.status);
|
|
3655
4175
|
return detectRunning({
|
|
3656
4176
|
status: partStatus ?? props.status,
|
|
3657
4177
|
result: props.result,
|
|
@@ -3669,8 +4189,8 @@ function formatToolResult(result) {
|
|
|
3669
4189
|
return String(result);
|
|
3670
4190
|
}
|
|
3671
4191
|
}
|
|
3672
|
-
var TimelineActionLabel = ({ action, detail, shimmer = false }) => /* @__PURE__ */ (0,
|
|
3673
|
-
action ? shimmer ? /* @__PURE__ */ (0,
|
|
4192
|
+
var TimelineActionLabel = ({ action, detail, shimmer = false }) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "inline-flex min-w-0 max-w-full items-baseline gap-1", children: [
|
|
4193
|
+
action ? shimmer ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
3674
4194
|
Shimmer,
|
|
3675
4195
|
{
|
|
3676
4196
|
as: "span",
|
|
@@ -3679,10 +4199,10 @@ var TimelineActionLabel = ({ action, detail, shimmer = false }) => /* @__PURE__
|
|
|
3679
4199
|
spread: 2.5,
|
|
3680
4200
|
children: action
|
|
3681
4201
|
}
|
|
3682
|
-
) : /* @__PURE__ */ (0,
|
|
3683
|
-
detail ? /* @__PURE__ */ (0,
|
|
4202
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: studioTimelineActionClass, children: action }) : null,
|
|
4203
|
+
detail ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: studioTimelineDetailClass, children: detail }) : null
|
|
3684
4204
|
] });
|
|
3685
|
-
var TimelineHoverChevron = ({ expanded }) => /* @__PURE__ */ (0,
|
|
4205
|
+
var TimelineHoverChevron = ({ expanded }) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
3686
4206
|
import_lucide_react5.ChevronRightIcon,
|
|
3687
4207
|
{
|
|
3688
4208
|
className: studioTimelineChevronClass(expanded),
|
|
@@ -3690,9 +4210,9 @@ var TimelineHoverChevron = ({ expanded }) => /* @__PURE__ */ (0, import_jsx_runt
|
|
|
3690
4210
|
}
|
|
3691
4211
|
);
|
|
3692
4212
|
var ToolPanel = ({ toolName, argsText, result, isError }) => {
|
|
3693
|
-
const [open, setOpen] = (0,
|
|
4213
|
+
const [open, setOpen] = (0, import_react28.useState)(false);
|
|
3694
4214
|
const detail = formatToolLabel(toolName);
|
|
3695
|
-
const formattedArgs = (0,
|
|
4215
|
+
const formattedArgs = (0, import_react28.useMemo)(() => {
|
|
3696
4216
|
if (!argsText || argsText === "{}") return null;
|
|
3697
4217
|
try {
|
|
3698
4218
|
return JSON.stringify(JSON.parse(argsText), null, 2);
|
|
@@ -3700,17 +4220,17 @@ var ToolPanel = ({ toolName, argsText, result, isError }) => {
|
|
|
3700
4220
|
return argsText;
|
|
3701
4221
|
}
|
|
3702
4222
|
}, [argsText]);
|
|
3703
|
-
const formattedResult = (0,
|
|
4223
|
+
const formattedResult = (0, import_react28.useMemo)(() => {
|
|
3704
4224
|
if (result === void 0 || result === null) return null;
|
|
3705
4225
|
return formatToolResult(result);
|
|
3706
4226
|
}, [result]);
|
|
3707
4227
|
const hasBody = Boolean(formattedArgs || formattedResult);
|
|
3708
4228
|
const action = isError ? "Failed" : "Used";
|
|
3709
4229
|
if (!hasBody) {
|
|
3710
|
-
return /* @__PURE__ */ (0,
|
|
4230
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "aui-tool-row w-full min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TimelineActionLabel, { action, detail }) });
|
|
3711
4231
|
}
|
|
3712
|
-
return /* @__PURE__ */ (0,
|
|
3713
|
-
/* @__PURE__ */ (0,
|
|
4232
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "aui-tool-row w-full min-w-0", children: [
|
|
4233
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
3714
4234
|
"button",
|
|
3715
4235
|
{
|
|
3716
4236
|
type: "button",
|
|
@@ -3718,7 +4238,7 @@ var ToolPanel = ({ toolName, argsText, result, isError }) => {
|
|
|
3718
4238
|
"aria-expanded": open,
|
|
3719
4239
|
"aria-label": `${action} ${detail}`,
|
|
3720
4240
|
className: studioTimelineRowButtonClass,
|
|
3721
|
-
children: /* @__PURE__ */ (0,
|
|
4241
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
3722
4242
|
"span",
|
|
3723
4243
|
{
|
|
3724
4244
|
className: cn(
|
|
@@ -3727,37 +4247,37 @@ var ToolPanel = ({ toolName, argsText, result, isError }) => {
|
|
|
3727
4247
|
"text-foreground"
|
|
3728
4248
|
),
|
|
3729
4249
|
children: [
|
|
3730
|
-
/* @__PURE__ */ (0,
|
|
3731
|
-
/* @__PURE__ */ (0,
|
|
4250
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TimelineActionLabel, { action, detail }),
|
|
4251
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TimelineHoverChevron, { expanded: open })
|
|
3732
4252
|
]
|
|
3733
4253
|
}
|
|
3734
4254
|
)
|
|
3735
4255
|
}
|
|
3736
4256
|
),
|
|
3737
|
-
/* @__PURE__ */ (0,
|
|
4257
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
3738
4258
|
ToolBodyPresence,
|
|
3739
4259
|
{
|
|
3740
4260
|
open,
|
|
3741
4261
|
className: cn(studioTimelineBodyPadClass, "gap-2"),
|
|
3742
4262
|
children: [
|
|
3743
|
-
formattedArgs ? /* @__PURE__ */ (0,
|
|
4263
|
+
formattedArgs ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
3744
4264
|
"div",
|
|
3745
4265
|
{
|
|
3746
4266
|
className: cn(
|
|
3747
4267
|
studioComposerIoWellClass,
|
|
3748
4268
|
"max-h-48 overflow-auto px-2.5 py-2"
|
|
3749
4269
|
),
|
|
3750
|
-
children: /* @__PURE__ */ (0,
|
|
4270
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("pre", { className: "whitespace-pre-wrap break-words font-mono text-[11px] font-normal leading-relaxed text-foreground", children: formattedArgs })
|
|
3751
4271
|
}
|
|
3752
4272
|
) : null,
|
|
3753
|
-
formattedResult ? /* @__PURE__ */ (0,
|
|
4273
|
+
formattedResult ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
3754
4274
|
"div",
|
|
3755
4275
|
{
|
|
3756
4276
|
className: cn(
|
|
3757
4277
|
studioComposerIoWellClass,
|
|
3758
4278
|
"max-h-48 overflow-auto px-2.5 py-2"
|
|
3759
4279
|
),
|
|
3760
|
-
children: /* @__PURE__ */ (0,
|
|
4280
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("pre", { className: "whitespace-pre-wrap break-words font-mono text-[11px] font-normal leading-relaxed text-foreground", children: formattedResult })
|
|
3761
4281
|
}
|
|
3762
4282
|
) : null
|
|
3763
4283
|
]
|
|
@@ -3774,20 +4294,20 @@ var ToolFallbackImpl = ({
|
|
|
3774
4294
|
const isRunning = useToolRunning({ status, result });
|
|
3775
4295
|
const isError = status?.type === "incomplete" && status.reason !== "cancelled";
|
|
3776
4296
|
const presenceKey = isRunning ? "running" : isError ? "error" : "complete";
|
|
3777
|
-
return /* @__PURE__ */ (0,
|
|
4297
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
3778
4298
|
ToolPresence,
|
|
3779
4299
|
{
|
|
3780
4300
|
presenceKey,
|
|
3781
4301
|
variant: isRunning ? "executing" : "settled",
|
|
3782
4302
|
className: "py-0.5",
|
|
3783
|
-
children: isRunning ? /* @__PURE__ */ (0,
|
|
4303
|
+
children: isRunning ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "aui-tool-running", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
3784
4304
|
TimelineActionLabel,
|
|
3785
4305
|
{
|
|
3786
4306
|
action: "Using",
|
|
3787
4307
|
detail: formatToolLabel(toolName),
|
|
3788
4308
|
shimmer: true
|
|
3789
4309
|
}
|
|
3790
|
-
) }) : /* @__PURE__ */ (0,
|
|
4310
|
+
) }) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
3791
4311
|
ToolPanel,
|
|
3792
4312
|
{
|
|
3793
4313
|
toolName,
|
|
@@ -3799,13 +4319,13 @@ var ToolFallbackImpl = ({
|
|
|
3799
4319
|
}
|
|
3800
4320
|
);
|
|
3801
4321
|
};
|
|
3802
|
-
var ToolFallback = (0,
|
|
4322
|
+
var ToolFallback = (0, import_react28.memo)(
|
|
3803
4323
|
ToolFallbackImpl
|
|
3804
4324
|
);
|
|
3805
4325
|
ToolFallback.displayName = "ToolFallback";
|
|
3806
4326
|
|
|
3807
4327
|
// src/artifacts/tool-artifact.tsx
|
|
3808
|
-
var
|
|
4328
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
3809
4329
|
var ToolArtifactFallback = (props) => {
|
|
3810
4330
|
const registry = useArtifactRegistry();
|
|
3811
4331
|
const isRunning = useToolRunning({
|
|
@@ -3817,24 +4337,24 @@ var ToolArtifactFallback = (props) => {
|
|
|
3817
4337
|
if (artifact) {
|
|
3818
4338
|
const Renderer = registry[artifact.type];
|
|
3819
4339
|
if (Renderer) {
|
|
3820
|
-
return /* @__PURE__ */ (0,
|
|
4340
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
3821
4341
|
ToolMotion,
|
|
3822
4342
|
{
|
|
3823
4343
|
motionKey: `artifact-${artifact.type}`,
|
|
3824
4344
|
className: "aui-tool-artifact",
|
|
3825
|
-
children: /* @__PURE__ */ (0,
|
|
4345
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Renderer, { artifact })
|
|
3826
4346
|
}
|
|
3827
4347
|
);
|
|
3828
4348
|
}
|
|
3829
4349
|
}
|
|
3830
4350
|
}
|
|
3831
|
-
return /* @__PURE__ */ (0,
|
|
4351
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ToolFallback, { ...props });
|
|
3832
4352
|
};
|
|
3833
4353
|
|
|
3834
4354
|
// src/chat/composer.tsx
|
|
3835
|
-
var
|
|
4355
|
+
var import_react30 = require("@assistant-ui/react");
|
|
3836
4356
|
var import_lucide_react6 = require("lucide-react");
|
|
3837
|
-
var
|
|
4357
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
3838
4358
|
var Composer = ({
|
|
3839
4359
|
placeholder = "Send a message...",
|
|
3840
4360
|
showAttachments,
|
|
@@ -3845,10 +4365,10 @@ var Composer = ({
|
|
|
3845
4365
|
}) => {
|
|
3846
4366
|
const attachmentsEnabled = useTimbalAttachmentsEnabled();
|
|
3847
4367
|
const attachUi = showAttachments !== false && attachmentsEnabled;
|
|
3848
|
-
const shell = /* @__PURE__ */ (0,
|
|
3849
|
-
attachUi && /* @__PURE__ */ (0,
|
|
3850
|
-
/* @__PURE__ */ (0,
|
|
3851
|
-
/* @__PURE__ */ (0,
|
|
4368
|
+
const shell = /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
|
|
4369
|
+
attachUi && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ComposerAttachments, {}),
|
|
4370
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ComposerInput, { placeholder, autoFocus: !noAutoFocus }),
|
|
4371
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
3852
4372
|
ComposerToolbar,
|
|
3853
4373
|
{
|
|
3854
4374
|
showAttachments: attachUi,
|
|
@@ -3857,15 +4377,15 @@ var Composer = ({
|
|
|
3857
4377
|
}
|
|
3858
4378
|
)
|
|
3859
4379
|
] });
|
|
3860
|
-
return /* @__PURE__ */ (0,
|
|
3861
|
-
|
|
4380
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
4381
|
+
import_react30.ComposerPrimitive.Root,
|
|
3862
4382
|
{
|
|
3863
4383
|
className: cn(
|
|
3864
4384
|
"aui-composer-root relative flex w-full flex-col",
|
|
3865
4385
|
className
|
|
3866
4386
|
),
|
|
3867
|
-
children: attachUi ? /* @__PURE__ */ (0,
|
|
3868
|
-
|
|
4387
|
+
children: attachUi ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
4388
|
+
import_react30.ComposerPrimitive.AttachmentDropzone,
|
|
3869
4389
|
{
|
|
3870
4390
|
className: cn(
|
|
3871
4391
|
studioComposeInputShellClass,
|
|
@@ -3873,7 +4393,7 @@ var Composer = ({
|
|
|
3873
4393
|
),
|
|
3874
4394
|
children: shell
|
|
3875
4395
|
}
|
|
3876
|
-
) : /* @__PURE__ */ (0,
|
|
4396
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: studioComposeInputShellClass, children: shell })
|
|
3877
4397
|
}
|
|
3878
4398
|
);
|
|
3879
4399
|
};
|
|
@@ -3881,7 +4401,7 @@ var ComposerInput = ({
|
|
|
3881
4401
|
placeholder,
|
|
3882
4402
|
autoFocus
|
|
3883
4403
|
}) => {
|
|
3884
|
-
const composer = (0,
|
|
4404
|
+
const composer = (0, import_react30.useComposerRuntime)();
|
|
3885
4405
|
const onKeyDown = (e) => {
|
|
3886
4406
|
if (e.key === "Enter" && !e.shiftKey && !e.nativeEvent.isComposing) {
|
|
3887
4407
|
e.preventDefault();
|
|
@@ -3893,8 +4413,8 @@ var ComposerInput = ({
|
|
|
3893
4413
|
el.style.height = "auto";
|
|
3894
4414
|
el.style.height = `${Math.min(el.scrollHeight, 240)}px`;
|
|
3895
4415
|
};
|
|
3896
|
-
return /* @__PURE__ */ (0,
|
|
3897
|
-
|
|
4416
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
4417
|
+
import_react30.ComposerPrimitive.Input,
|
|
3898
4418
|
{
|
|
3899
4419
|
placeholder,
|
|
3900
4420
|
className: "aui-composer-input max-h-60 min-h-14 w-full resize-none bg-composer-bg px-3 pt-3 pb-1 text-sm outline-none placeholder:text-muted-foreground/70 focus-visible:ring-0",
|
|
@@ -3907,17 +4427,17 @@ var ComposerInput = ({
|
|
|
3907
4427
|
);
|
|
3908
4428
|
};
|
|
3909
4429
|
var ComposerToolbar = ({ showAttachments, toolbar, sendTooltip }) => {
|
|
3910
|
-
return /* @__PURE__ */ (0,
|
|
3911
|
-
/* @__PURE__ */ (0,
|
|
3912
|
-
showAttachments && /* @__PURE__ */ (0,
|
|
4430
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "aui-composer-action-wrapper relative z-[1] flex items-center justify-between gap-1 bg-composer-bg px-2.5 pb-2.5", children: [
|
|
4431
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
4432
|
+
showAttachments && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ComposerAddAttachment, {}),
|
|
3913
4433
|
toolbar
|
|
3914
4434
|
] }),
|
|
3915
|
-
/* @__PURE__ */ (0,
|
|
4435
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ComposerSendOrCancel, { sendTooltip })
|
|
3916
4436
|
] });
|
|
3917
4437
|
};
|
|
3918
4438
|
var ComposerSendOrCancel = ({ sendTooltip }) => {
|
|
3919
|
-
return /* @__PURE__ */ (0,
|
|
3920
|
-
/* @__PURE__ */ (0,
|
|
4439
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
|
|
4440
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react30.AuiIf, { condition: (s) => !s.thread.isRunning, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react30.ComposerPrimitive.Send, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
3921
4441
|
TooltipIconButton,
|
|
3922
4442
|
{
|
|
3923
4443
|
tooltip: sendTooltip,
|
|
@@ -3925,34 +4445,34 @@ var ComposerSendOrCancel = ({ sendTooltip }) => {
|
|
|
3925
4445
|
type: "submit",
|
|
3926
4446
|
className: "aui-composer-send shrink-0 disabled:opacity-30",
|
|
3927
4447
|
"aria-label": "Send message",
|
|
3928
|
-
children: /* @__PURE__ */ (0,
|
|
4448
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react6.ArrowUpIcon, { className: "aui-composer-send-icon size-4" })
|
|
3929
4449
|
}
|
|
3930
4450
|
) }) }),
|
|
3931
|
-
/* @__PURE__ */ (0,
|
|
4451
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react30.AuiIf, { condition: (s) => s.thread.isRunning, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react30.ComposerPrimitive.Cancel, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
3932
4452
|
TooltipIconButton,
|
|
3933
4453
|
{
|
|
3934
4454
|
tooltip: "Stop generating",
|
|
3935
4455
|
variant: "primary",
|
|
3936
4456
|
className: "aui-composer-cancel shrink-0",
|
|
3937
4457
|
"aria-label": "Stop generating",
|
|
3938
|
-
children: /* @__PURE__ */ (0,
|
|
4458
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react6.SquareIcon, { className: "aui-composer-cancel-icon size-3 fill-current" })
|
|
3939
4459
|
}
|
|
3940
4460
|
) }) })
|
|
3941
4461
|
] });
|
|
3942
4462
|
};
|
|
3943
4463
|
|
|
3944
4464
|
// src/chat/suggestions.tsx
|
|
3945
|
-
var
|
|
3946
|
-
var
|
|
4465
|
+
var import_react31 = require("react");
|
|
4466
|
+
var import_react32 = require("@assistant-ui/react");
|
|
3947
4467
|
var import_lucide_react7 = require("lucide-react");
|
|
3948
|
-
var
|
|
4468
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
3949
4469
|
var Suggestions = ({
|
|
3950
4470
|
suggestions,
|
|
3951
4471
|
className
|
|
3952
4472
|
}) => {
|
|
3953
4473
|
const items = useResolvedSuggestions(suggestions);
|
|
3954
4474
|
if (!items || items.length === 0) return null;
|
|
3955
|
-
return /* @__PURE__ */ (0,
|
|
4475
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
3956
4476
|
"div",
|
|
3957
4477
|
{
|
|
3958
4478
|
className: cn(
|
|
@@ -3961,17 +4481,17 @@ var Suggestions = ({
|
|
|
3961
4481
|
),
|
|
3962
4482
|
role: "list",
|
|
3963
4483
|
"aria-label": "Suggested prompts",
|
|
3964
|
-
children: items.map((suggestion, i) => /* @__PURE__ */ (0,
|
|
4484
|
+
children: items.map((suggestion, i) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(SuggestionRow, { suggestion }, (suggestion.prompt ?? suggestion.title) + i))
|
|
3965
4485
|
}
|
|
3966
4486
|
);
|
|
3967
4487
|
};
|
|
3968
4488
|
var SuggestionRow = ({ suggestion }) => {
|
|
3969
|
-
const runtime = (0,
|
|
4489
|
+
const runtime = (0, import_react32.useThreadRuntime)();
|
|
3970
4490
|
const onClick = () => {
|
|
3971
4491
|
const text = suggestion.prompt ?? suggestion.title;
|
|
3972
4492
|
runtime.append({ role: "user", content: [{ type: "text", text }] });
|
|
3973
4493
|
};
|
|
3974
|
-
return /* @__PURE__ */ (0,
|
|
4494
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
3975
4495
|
"button",
|
|
3976
4496
|
{
|
|
3977
4497
|
type: "button",
|
|
@@ -3979,20 +4499,20 @@ var SuggestionRow = ({ suggestion }) => {
|
|
|
3979
4499
|
onClick,
|
|
3980
4500
|
className: cn("aui-thread-suggestion", studioListRowButtonClass),
|
|
3981
4501
|
children: [
|
|
3982
|
-
/* @__PURE__ */ (0,
|
|
3983
|
-
/* @__PURE__ */ (0,
|
|
3984
|
-
/* @__PURE__ */ (0,
|
|
3985
|
-
suggestion.description && /* @__PURE__ */ (0,
|
|
4502
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "aui-thread-suggestion-icon shrink-0 text-muted-foreground", children: suggestion.icon ?? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_lucide_react7.ArrowUpIcon, { className: "size-4", strokeWidth: 1.75, "aria-hidden": true }) }),
|
|
4503
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "aui-thread-suggestion-text min-w-0 flex-1 text-left", children: [
|
|
4504
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "aui-thread-suggestion-text-1 block truncate text-sm font-normal text-foreground", children: suggestion.title }),
|
|
4505
|
+
suggestion.description && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "aui-thread-suggestion-text-2 mt-0.5 block truncate text-xs text-muted-foreground", children: suggestion.description })
|
|
3986
4506
|
] })
|
|
3987
4507
|
]
|
|
3988
4508
|
}
|
|
3989
4509
|
);
|
|
3990
4510
|
};
|
|
3991
4511
|
function useResolvedSuggestions(source) {
|
|
3992
|
-
const [resolved, setResolved] = (0,
|
|
4512
|
+
const [resolved, setResolved] = (0, import_react31.useState)(
|
|
3993
4513
|
() => Array.isArray(source) ? source : void 0
|
|
3994
4514
|
);
|
|
3995
|
-
(0,
|
|
4515
|
+
(0, import_react31.useEffect)(() => {
|
|
3996
4516
|
if (!source) {
|
|
3997
4517
|
setResolved(void 0);
|
|
3998
4518
|
return;
|
|
@@ -4011,7 +4531,7 @@ function useResolvedSuggestions(source) {
|
|
|
4011
4531
|
cancelled = true;
|
|
4012
4532
|
};
|
|
4013
4533
|
}, [source]);
|
|
4014
|
-
return (0,
|
|
4534
|
+
return (0, import_react31.useMemo)(() => resolved, [resolved]);
|
|
4015
4535
|
}
|
|
4016
4536
|
|
|
4017
4537
|
// src/design/theme-sanity.ts
|
|
@@ -4084,15 +4604,15 @@ function scheduleThemeSanityCheck() {
|
|
|
4084
4604
|
}
|
|
4085
4605
|
|
|
4086
4606
|
// src/chat/thread-variant.tsx
|
|
4087
|
-
var
|
|
4088
|
-
var ThreadVariantContext = (0,
|
|
4607
|
+
var import_react33 = require("react");
|
|
4608
|
+
var ThreadVariantContext = (0, import_react33.createContext)("default");
|
|
4089
4609
|
var ThreadVariantProvider = ThreadVariantContext.Provider;
|
|
4090
4610
|
function useThreadVariant() {
|
|
4091
|
-
return (0,
|
|
4611
|
+
return (0, import_react33.useContext)(ThreadVariantContext);
|
|
4092
4612
|
}
|
|
4093
4613
|
|
|
4094
4614
|
// src/chat/thread.tsx
|
|
4095
|
-
var
|
|
4615
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
4096
4616
|
var Thread = ({
|
|
4097
4617
|
className,
|
|
4098
4618
|
variant = "default",
|
|
@@ -4114,17 +4634,17 @@ var Thread = ({
|
|
|
4114
4634
|
const EditComposerSlot = components?.EditComposer ?? EditComposer;
|
|
4115
4635
|
const ScrollToBottomSlot = components?.ScrollToBottom ?? ThreadScrollToBottom;
|
|
4116
4636
|
const SuggestionsSlot = components?.Suggestions ?? Suggestions;
|
|
4117
|
-
(0,
|
|
4637
|
+
(0, import_react34.useEffect)(() => {
|
|
4118
4638
|
scheduleThemeSanityCheck();
|
|
4119
4639
|
}, []);
|
|
4120
|
-
return /* @__PURE__ */ (0,
|
|
4640
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ThreadVariantProvider, { value: variant, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4121
4641
|
ArtifactRegistryProvider,
|
|
4122
4642
|
{
|
|
4123
4643
|
renderers: artifacts?.renderers,
|
|
4124
4644
|
override: artifacts?.override,
|
|
4125
|
-
children: /* @__PURE__ */ (0,
|
|
4126
|
-
}), children: /* @__PURE__ */ (0,
|
|
4127
|
-
|
|
4645
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(UiEventProvider, { onEvent: onArtifactEvent ?? (() => {
|
|
4646
|
+
}), children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4647
|
+
import_react35.ThreadPrimitive.Root,
|
|
4128
4648
|
{
|
|
4129
4649
|
className: cn(
|
|
4130
4650
|
"aui-root aui-thread-root @container flex h-full flex-col bg-transparent",
|
|
@@ -4133,8 +4653,8 @@ var Thread = ({
|
|
|
4133
4653
|
),
|
|
4134
4654
|
style: { ["--thread-max-width"]: maxWidth },
|
|
4135
4655
|
"data-thread-variant": variant,
|
|
4136
|
-
children: /* @__PURE__ */ (0,
|
|
4137
|
-
|
|
4656
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
4657
|
+
import_react35.ThreadPrimitive.Viewport,
|
|
4138
4658
|
{
|
|
4139
4659
|
turnAnchor: "bottom",
|
|
4140
4660
|
className: cn(
|
|
@@ -4142,7 +4662,7 @@ var Thread = ({
|
|
|
4142
4662
|
isPanel ? "px-2 pt-2" : "px-4 pt-4"
|
|
4143
4663
|
),
|
|
4144
4664
|
children: [
|
|
4145
|
-
/* @__PURE__ */ (0,
|
|
4665
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4146
4666
|
WelcomeSlot,
|
|
4147
4667
|
{
|
|
4148
4668
|
config: welcome,
|
|
@@ -4150,8 +4670,8 @@ var Thread = ({
|
|
|
4150
4670
|
Suggestions: SuggestionsSlot
|
|
4151
4671
|
}
|
|
4152
4672
|
),
|
|
4153
|
-
/* @__PURE__ */ (0,
|
|
4154
|
-
|
|
4673
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4674
|
+
import_react35.ThreadPrimitive.Messages,
|
|
4155
4675
|
{
|
|
4156
4676
|
components: {
|
|
4157
4677
|
UserMessage: UserMessageSlot,
|
|
@@ -4160,14 +4680,14 @@ var Thread = ({
|
|
|
4160
4680
|
}
|
|
4161
4681
|
}
|
|
4162
4682
|
),
|
|
4163
|
-
/* @__PURE__ */ (0,
|
|
4164
|
-
|
|
4683
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4684
|
+
import_react35.ThreadPrimitive.ViewportFooter,
|
|
4165
4685
|
{
|
|
4166
4686
|
className: cn(
|
|
4167
4687
|
"aui-thread-viewport-footer sticky bottom-0 z-10 mt-auto w-full isolate pt-2",
|
|
4168
4688
|
isPanel ? "bg-card pb-2" : "bg-background pb-4 md:pb-6"
|
|
4169
4689
|
),
|
|
4170
|
-
children: /* @__PURE__ */ (0,
|
|
4690
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
4171
4691
|
"div",
|
|
4172
4692
|
{
|
|
4173
4693
|
className: cn(
|
|
@@ -4175,8 +4695,8 @@ var Thread = ({
|
|
|
4175
4695
|
isPanel ? "gap-2" : "gap-4"
|
|
4176
4696
|
),
|
|
4177
4697
|
children: [
|
|
4178
|
-
/* @__PURE__ */ (0,
|
|
4179
|
-
/* @__PURE__ */ (0,
|
|
4698
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ScrollToBottomSlot, {}),
|
|
4699
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ComposerSlot, { placeholder })
|
|
4180
4700
|
]
|
|
4181
4701
|
}
|
|
4182
4702
|
)
|
|
@@ -4191,13 +4711,13 @@ var Thread = ({
|
|
|
4191
4711
|
) });
|
|
4192
4712
|
};
|
|
4193
4713
|
var ThreadScrollToBottom = () => {
|
|
4194
|
-
return /* @__PURE__ */ (0,
|
|
4714
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react35.ThreadPrimitive.ScrollToBottom, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4195
4715
|
TooltipIconButton,
|
|
4196
4716
|
{
|
|
4197
4717
|
tooltip: "Scroll to bottom",
|
|
4198
4718
|
variant: "secondary",
|
|
4199
4719
|
className: "aui-thread-scroll-to-bottom absolute -top-12 z-10 self-center disabled:invisible",
|
|
4200
|
-
children: /* @__PURE__ */ (0,
|
|
4720
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react8.ArrowDownIcon, { className: "size-4" })
|
|
4201
4721
|
}
|
|
4202
4722
|
) });
|
|
4203
4723
|
};
|
|
@@ -4229,14 +4749,14 @@ var ThreadWelcome = ({
|
|
|
4229
4749
|
suggestions,
|
|
4230
4750
|
Suggestions: SuggestionsSlot = Suggestions
|
|
4231
4751
|
}) => {
|
|
4232
|
-
const isEmpty = (0,
|
|
4752
|
+
const isEmpty = (0, import_react35.useThread)((s) => s.messages.length === 0);
|
|
4233
4753
|
const isPanel = useThreadVariant() === "panel";
|
|
4234
4754
|
if (!isEmpty) return null;
|
|
4235
4755
|
const defaultHeading = isPanel ? "Ask about this page" : "How can I help you today?";
|
|
4236
4756
|
const defaultSubheading = isPanel ? "The assistant can use dashboard context from your app." : "Send a message to start a conversation.";
|
|
4237
|
-
return /* @__PURE__ */ (0,
|
|
4238
|
-
/* @__PURE__ */ (0,
|
|
4239
|
-
|
|
4757
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "aui-thread-welcome-root mx-auto my-auto flex w-full max-w-(--thread-max-width) grow flex-col", children: [
|
|
4758
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "aui-thread-welcome-center flex w-full grow flex-col items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
4759
|
+
import_react36.motion.div,
|
|
4240
4760
|
{
|
|
4241
4761
|
className: cn(
|
|
4242
4762
|
"aui-thread-welcome-message flex flex-col items-center justify-center text-center",
|
|
@@ -4246,9 +4766,9 @@ var ThreadWelcome = ({
|
|
|
4246
4766
|
initial: "initial",
|
|
4247
4767
|
animate: "animate",
|
|
4248
4768
|
children: [
|
|
4249
|
-
config?.icon && /* @__PURE__ */ (0,
|
|
4250
|
-
/* @__PURE__ */ (0,
|
|
4251
|
-
|
|
4769
|
+
config?.icon && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react36.motion.div, { variants: welcomeIcon, className: isPanel ? "mb-3" : "mb-5", children: config.icon }),
|
|
4770
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4771
|
+
import_react36.motion.h1,
|
|
4252
4772
|
{
|
|
4253
4773
|
variants: welcomeItem,
|
|
4254
4774
|
className: cn(
|
|
@@ -4258,8 +4778,8 @@ var ThreadWelcome = ({
|
|
|
4258
4778
|
children: config?.heading ?? defaultHeading
|
|
4259
4779
|
}
|
|
4260
4780
|
),
|
|
4261
|
-
/* @__PURE__ */ (0,
|
|
4262
|
-
|
|
4781
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4782
|
+
import_react36.motion.p,
|
|
4263
4783
|
{
|
|
4264
4784
|
variants: welcomeItem,
|
|
4265
4785
|
className: "aui-thread-welcome-message-inner mt-1.5 text-muted-foreground text-sm",
|
|
@@ -4269,16 +4789,16 @@ var ThreadWelcome = ({
|
|
|
4269
4789
|
]
|
|
4270
4790
|
}
|
|
4271
4791
|
) }),
|
|
4272
|
-
suggestions && !isPanel ? /* @__PURE__ */ (0,
|
|
4792
|
+
suggestions && !isPanel ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "aui-thread-welcome-suggestions mx-auto w-full max-w-(--thread-max-width) px-2", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(SuggestionsSlot, { suggestions }) }) : null
|
|
4273
4793
|
] });
|
|
4274
4794
|
};
|
|
4275
4795
|
var MessageError = () => {
|
|
4276
|
-
return /* @__PURE__ */ (0,
|
|
4796
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react35.MessagePrimitive.Error, { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react35.ErrorPrimitive.Root, { className: "aui-message-error-root mt-2 rounded-md border border-destructive bg-destructive/10 p-3 text-destructive text-sm", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react35.ErrorPrimitive.Message, { className: "aui-message-error-message line-clamp-2" }) }) });
|
|
4277
4797
|
};
|
|
4278
4798
|
var AssistantMessage = () => {
|
|
4279
4799
|
const isPanel = useThreadVariant() === "panel";
|
|
4280
|
-
return /* @__PURE__ */ (0,
|
|
4281
|
-
|
|
4800
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
4801
|
+
import_react35.MessagePrimitive.Root,
|
|
4282
4802
|
{
|
|
4283
4803
|
className: cn(
|
|
4284
4804
|
"aui-assistant-message-root fade-in slide-in-from-bottom-1 relative mx-auto w-full max-w-(--thread-max-width) animate-in duration-150",
|
|
@@ -4286,7 +4806,7 @@ var AssistantMessage = () => {
|
|
|
4286
4806
|
),
|
|
4287
4807
|
"data-role": "assistant",
|
|
4288
4808
|
children: [
|
|
4289
|
-
/* @__PURE__ */ (0,
|
|
4809
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
4290
4810
|
"div",
|
|
4291
4811
|
{
|
|
4292
4812
|
className: cn(
|
|
@@ -4294,8 +4814,8 @@ var AssistantMessage = () => {
|
|
|
4294
4814
|
isPanel ? "px-1 text-sm" : "px-2"
|
|
4295
4815
|
),
|
|
4296
4816
|
children: [
|
|
4297
|
-
/* @__PURE__ */ (0,
|
|
4298
|
-
|
|
4817
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4818
|
+
import_react35.MessagePrimitive.Parts,
|
|
4299
4819
|
{
|
|
4300
4820
|
components: {
|
|
4301
4821
|
Text: MarkdownText,
|
|
@@ -4305,11 +4825,11 @@ var AssistantMessage = () => {
|
|
|
4305
4825
|
}
|
|
4306
4826
|
}
|
|
4307
4827
|
),
|
|
4308
|
-
/* @__PURE__ */ (0,
|
|
4828
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(MessageError, {})
|
|
4309
4829
|
]
|
|
4310
4830
|
}
|
|
4311
4831
|
),
|
|
4312
|
-
/* @__PURE__ */ (0,
|
|
4832
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "aui-assistant-message-footer mt-1 mb-3 ml-1 flex", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(AssistantActionBar, {}) })
|
|
4313
4833
|
]
|
|
4314
4834
|
}
|
|
4315
4835
|
);
|
|
@@ -4322,36 +4842,36 @@ var ASSISTANT_ACTION_ICON_CLASS = cn(
|
|
|
4322
4842
|
"[&>span:first-child]:group-hover/tbv2:bg-ghost-fill-hover"
|
|
4323
4843
|
);
|
|
4324
4844
|
var AssistantActionBar = () => {
|
|
4325
|
-
return /* @__PURE__ */ (0,
|
|
4326
|
-
|
|
4845
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
4846
|
+
import_react35.ActionBarPrimitive.Root,
|
|
4327
4847
|
{
|
|
4328
4848
|
hideWhenRunning: true,
|
|
4329
4849
|
autohide: "never",
|
|
4330
4850
|
className: "aui-assistant-action-bar-root flex items-center gap-0 bg-transparent px-0 py-0.5 text-muted-foreground/60",
|
|
4331
4851
|
children: [
|
|
4332
|
-
/* @__PURE__ */ (0,
|
|
4852
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react35.ActionBarPrimitive.Copy, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
4333
4853
|
TooltipIconButton,
|
|
4334
4854
|
{
|
|
4335
4855
|
tooltip: "Copy",
|
|
4336
4856
|
variant: "ghost",
|
|
4337
4857
|
className: ASSISTANT_ACTION_ICON_CLASS,
|
|
4338
4858
|
children: [
|
|
4339
|
-
/* @__PURE__ */ (0,
|
|
4340
|
-
/* @__PURE__ */ (0,
|
|
4859
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react35.AuiIf, { condition: (s) => s.message.isCopied, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react8.CheckIcon, { className: "size-3" }) }),
|
|
4860
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react35.AuiIf, { condition: (s) => !s.message.isCopied, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react8.CopyIcon, { className: "size-3" }) })
|
|
4341
4861
|
]
|
|
4342
4862
|
}
|
|
4343
4863
|
) }),
|
|
4344
|
-
/* @__PURE__ */ (0,
|
|
4864
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react35.ActionBarPrimitive.Reload, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4345
4865
|
TooltipIconButton,
|
|
4346
4866
|
{
|
|
4347
4867
|
tooltip: "Regenerate",
|
|
4348
4868
|
variant: "ghost",
|
|
4349
4869
|
className: ASSISTANT_ACTION_ICON_CLASS,
|
|
4350
|
-
children: /* @__PURE__ */ (0,
|
|
4870
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react8.RefreshCwIcon, { className: "size-3" })
|
|
4351
4871
|
}
|
|
4352
4872
|
) }),
|
|
4353
|
-
/* @__PURE__ */ (0,
|
|
4354
|
-
/* @__PURE__ */ (0,
|
|
4873
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_react35.ActionBarMorePrimitive.Root, { children: [
|
|
4874
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react35.ActionBarMorePrimitive.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4355
4875
|
TooltipIconButton,
|
|
4356
4876
|
{
|
|
4357
4877
|
tooltip: "More",
|
|
@@ -4360,17 +4880,17 @@ var AssistantActionBar = () => {
|
|
|
4360
4880
|
ASSISTANT_ACTION_ICON_CLASS,
|
|
4361
4881
|
"data-[state=open]:text-muted-foreground/80"
|
|
4362
4882
|
),
|
|
4363
|
-
children: /* @__PURE__ */ (0,
|
|
4883
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react8.MoreHorizontalIcon, { className: "size-3" })
|
|
4364
4884
|
}
|
|
4365
4885
|
) }),
|
|
4366
|
-
/* @__PURE__ */ (0,
|
|
4367
|
-
|
|
4886
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4887
|
+
import_react35.ActionBarMorePrimitive.Content,
|
|
4368
4888
|
{
|
|
4369
4889
|
side: "bottom",
|
|
4370
4890
|
align: "start",
|
|
4371
4891
|
className: "aui-action-bar-more-content z-50 min-w-36 overflow-hidden rounded-lg border border-border bg-popover p-1 text-popover-foreground shadow-card-elevated",
|
|
4372
|
-
children: /* @__PURE__ */ (0,
|
|
4373
|
-
/* @__PURE__ */ (0,
|
|
4892
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react35.ActionBarPrimitive.ExportMarkdown, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_react35.ActionBarMorePrimitive.Item, { className: "aui-action-bar-more-item flex cursor-pointer select-none items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-none hover:bg-muted focus:bg-muted", children: [
|
|
4893
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react8.DownloadIcon, { className: "size-4 shrink-0" }),
|
|
4374
4894
|
"Export as Markdown"
|
|
4375
4895
|
] }) })
|
|
4376
4896
|
}
|
|
@@ -4381,12 +4901,12 @@ var AssistantActionBar = () => {
|
|
|
4381
4901
|
);
|
|
4382
4902
|
};
|
|
4383
4903
|
var UserMessageText = () => {
|
|
4384
|
-
return /* @__PURE__ */ (0,
|
|
4904
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "whitespace-pre-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react35.MessagePartPrimitive.Text, { smooth: false }) });
|
|
4385
4905
|
};
|
|
4386
4906
|
var UserMessage = () => {
|
|
4387
4907
|
const isPanel = useThreadVariant() === "panel";
|
|
4388
|
-
return /* @__PURE__ */ (0,
|
|
4389
|
-
|
|
4908
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
4909
|
+
import_react35.MessagePrimitive.Root,
|
|
4390
4910
|
{
|
|
4391
4911
|
className: cn(
|
|
4392
4912
|
"aui-user-message-root mx-auto flex w-full max-w-(--thread-max-width) flex-col items-end gap-2",
|
|
@@ -4394,9 +4914,9 @@ var UserMessage = () => {
|
|
|
4394
4914
|
),
|
|
4395
4915
|
"data-role": "user",
|
|
4396
4916
|
children: [
|
|
4397
|
-
/* @__PURE__ */ (0,
|
|
4398
|
-
/* @__PURE__ */ (0,
|
|
4399
|
-
|
|
4917
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(UserMessageAttachments, {}),
|
|
4918
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
4919
|
+
import_react36.motion.div,
|
|
4400
4920
|
{
|
|
4401
4921
|
className: cn(
|
|
4402
4922
|
"aui-user-message-content relative inline-block max-w-[85%] rounded-2xl bg-bubble-user text-bubble-user-foreground",
|
|
@@ -4406,8 +4926,8 @@ var UserMessage = () => {
|
|
|
4406
4926
|
animate: { opacity: 1, y: 0, scale: 1 },
|
|
4407
4927
|
transition: { duration: 0.65, ease: luxuryEase },
|
|
4408
4928
|
children: [
|
|
4409
|
-
/* @__PURE__ */ (0,
|
|
4410
|
-
/* @__PURE__ */ (0,
|
|
4929
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react35.MessagePrimitive.Parts, { components: { Text: UserMessageText } }),
|
|
4930
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "aui-user-action-bar-wrapper absolute top-1/2 left-0 -translate-x-full -translate-y-1/2 pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(UserActionBar, {}) })
|
|
4411
4931
|
]
|
|
4412
4932
|
}
|
|
4413
4933
|
)
|
|
@@ -4416,42 +4936,42 @@ var UserMessage = () => {
|
|
|
4416
4936
|
);
|
|
4417
4937
|
};
|
|
4418
4938
|
var UserActionBar = () => {
|
|
4419
|
-
return /* @__PURE__ */ (0,
|
|
4420
|
-
|
|
4939
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4940
|
+
import_react35.ActionBarPrimitive.Root,
|
|
4421
4941
|
{
|
|
4422
4942
|
hideWhenRunning: true,
|
|
4423
4943
|
autohide: "always",
|
|
4424
4944
|
className: "aui-user-action-bar-root flex flex-col items-end",
|
|
4425
|
-
children: /* @__PURE__ */ (0,
|
|
4945
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react35.ActionBarPrimitive.Edit, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4426
4946
|
TooltipIconButton,
|
|
4427
4947
|
{
|
|
4428
4948
|
tooltip: "Edit",
|
|
4429
4949
|
variant: "ghost",
|
|
4430
4950
|
className: ASSISTANT_ACTION_ICON_CLASS,
|
|
4431
|
-
children: /* @__PURE__ */ (0,
|
|
4951
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react8.PencilIcon, { className: "size-3" })
|
|
4432
4952
|
}
|
|
4433
4953
|
) })
|
|
4434
4954
|
}
|
|
4435
4955
|
);
|
|
4436
4956
|
};
|
|
4437
4957
|
var EditComposer = () => {
|
|
4438
|
-
return /* @__PURE__ */ (0,
|
|
4439
|
-
/* @__PURE__ */ (0,
|
|
4440
|
-
|
|
4958
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react35.MessagePrimitive.Root, { className: "aui-edit-composer-wrapper mx-auto flex w-full max-w-(--thread-max-width) flex-col px-2 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_react35.ComposerPrimitive.Root, { className: "aui-edit-composer-root ml-auto flex w-full max-w-[85%] flex-col rounded-2xl bg-muted", children: [
|
|
4959
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4960
|
+
import_react35.ComposerPrimitive.Input,
|
|
4441
4961
|
{
|
|
4442
4962
|
className: "aui-edit-composer-input min-h-14 w-full resize-none bg-transparent p-4 text-foreground text-sm outline-none",
|
|
4443
4963
|
autoFocus: true
|
|
4444
4964
|
}
|
|
4445
4965
|
),
|
|
4446
|
-
/* @__PURE__ */ (0,
|
|
4447
|
-
/* @__PURE__ */ (0,
|
|
4448
|
-
/* @__PURE__ */ (0,
|
|
4966
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "aui-edit-composer-footer mx-3 mb-3 flex items-center gap-2 self-end", children: [
|
|
4967
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react35.ComposerPrimitive.Cancel, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(TimbalV2Button, { variant: "ghost", size: "sm", children: "Cancel" }) }),
|
|
4968
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react35.ComposerPrimitive.Send, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(TimbalV2Button, { variant: "primary", size: "sm", children: "Update" }) })
|
|
4449
4969
|
] })
|
|
4450
4970
|
] }) });
|
|
4451
4971
|
};
|
|
4452
4972
|
|
|
4453
4973
|
// src/app/chat/AppChatPanel.tsx
|
|
4454
|
-
var
|
|
4974
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
4455
4975
|
var shellClass = "aui-app-chat-panel flex h-full min-h-0 flex-col overflow-hidden";
|
|
4456
4976
|
var chromeClass = cn(
|
|
4457
4977
|
"aui-app-chat-panel-chrome relative z-20 flex min-h-12 shrink-0 items-center justify-end",
|
|
@@ -4495,18 +5015,18 @@ var AppChatPanel = ({
|
|
|
4495
5015
|
...rest
|
|
4496
5016
|
}) => {
|
|
4497
5017
|
const shellChat = useAppShellChat();
|
|
4498
|
-
return /* @__PURE__ */ (0,
|
|
4499
|
-
shellChat?.collapsible ? /* @__PURE__ */ (0,
|
|
5018
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: cn(shellClass, className), children: [
|
|
5019
|
+
shellChat?.collapsible ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: chromeClass, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
4500
5020
|
"button",
|
|
4501
5021
|
{
|
|
4502
5022
|
type: "button",
|
|
4503
5023
|
className: closeButtonClass,
|
|
4504
5024
|
onClick: () => shellChat.setOpen(false),
|
|
4505
5025
|
"aria-label": "Close assistant",
|
|
4506
|
-
children: /* @__PURE__ */ (0,
|
|
5026
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_lucide_react9.XIcon, { className: "size-4", "aria-hidden": true })
|
|
4507
5027
|
}
|
|
4508
5028
|
) }) : null,
|
|
4509
|
-
/* @__PURE__ */ (0,
|
|
5029
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: bodyClass, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
4510
5030
|
TimbalRuntimeProvider,
|
|
4511
5031
|
{
|
|
4512
5032
|
workforceId,
|
|
@@ -4516,7 +5036,7 @@ var AppChatPanel = ({
|
|
|
4516
5036
|
attachmentsUploadUrl,
|
|
4517
5037
|
attachmentsAccept,
|
|
4518
5038
|
debug,
|
|
4519
|
-
children: /* @__PURE__ */ (0,
|
|
5039
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
4520
5040
|
Thread,
|
|
4521
5041
|
{
|
|
4522
5042
|
variant: "panel",
|
|
@@ -4536,38 +5056,38 @@ var AppChatPanel = ({
|
|
|
4536
5056
|
};
|
|
4537
5057
|
|
|
4538
5058
|
// src/app/surfaces/SurfaceCard.tsx
|
|
4539
|
-
var
|
|
5059
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
4540
5060
|
var SurfaceCard = ({ children, className }) => {
|
|
4541
|
-
return /* @__PURE__ */ (0,
|
|
5061
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: cn("aui-app-surface-card", appSurfaceCardClass, className), children });
|
|
4542
5062
|
};
|
|
4543
5063
|
|
|
4544
5064
|
// src/app/surfaces/StatTile.tsx
|
|
4545
|
-
var
|
|
5065
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
4546
5066
|
var StatTile = ({ label, value, hint, className }) => {
|
|
4547
|
-
return /* @__PURE__ */ (0,
|
|
4548
|
-
/* @__PURE__ */ (0,
|
|
4549
|
-
/* @__PURE__ */ (0,
|
|
4550
|
-
hint ? /* @__PURE__ */ (0,
|
|
5067
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: cn("aui-app-stat-tile", appStatTileClass, className), children: [
|
|
5068
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: appStatLabelClass, children: label }),
|
|
5069
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: appStatValueClass, children: value }),
|
|
5070
|
+
hint ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "text-xs text-muted-foreground", children: hint }) : null
|
|
4551
5071
|
] });
|
|
4552
5072
|
};
|
|
4553
5073
|
|
|
4554
5074
|
// src/app/surfaces/EmptyState.tsx
|
|
4555
|
-
var
|
|
4556
|
-
var
|
|
5075
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
5076
|
+
var EmptyState = ({
|
|
4557
5077
|
title,
|
|
4558
5078
|
description,
|
|
4559
5079
|
action,
|
|
4560
5080
|
className
|
|
4561
5081
|
}) => {
|
|
4562
|
-
return /* @__PURE__ */ (0,
|
|
4563
|
-
/* @__PURE__ */ (0,
|
|
4564
|
-
description ? /* @__PURE__ */ (0,
|
|
5082
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: cn("aui-app-empty-state", appEmptyStateClass, className), children: [
|
|
5083
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("p", { className: appEmptyStateTitleClass, children: title }),
|
|
5084
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("p", { className: appEmptyStateDescriptionClass, children: description }) : null,
|
|
4565
5085
|
action
|
|
4566
5086
|
] });
|
|
4567
5087
|
};
|
|
4568
5088
|
|
|
4569
5089
|
// src/app/surfaces/StatusBadge.tsx
|
|
4570
|
-
var
|
|
5090
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
4571
5091
|
var statusBadgeToneClass = {
|
|
4572
5092
|
default: "bg-muted text-foreground",
|
|
4573
5093
|
primary: "bg-primary/10 text-primary",
|
|
@@ -4580,7 +5100,7 @@ var StatusBadge = ({
|
|
|
4580
5100
|
tone = "default",
|
|
4581
5101
|
className
|
|
4582
5102
|
}) => {
|
|
4583
|
-
return /* @__PURE__ */ (0,
|
|
5103
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
4584
5104
|
"span",
|
|
4585
5105
|
{
|
|
4586
5106
|
className: cn(
|
|
@@ -4594,7 +5114,7 @@ var StatusBadge = ({
|
|
|
4594
5114
|
};
|
|
4595
5115
|
|
|
4596
5116
|
// src/app/surfaces/AppConfirmDialog.tsx
|
|
4597
|
-
var
|
|
5117
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
4598
5118
|
var bodyClass2 = "flex flex-col gap-4 p-6";
|
|
4599
5119
|
var titleClass = "pr-8";
|
|
4600
5120
|
var actionsClass = "flex flex-wrap justify-end gap-2";
|
|
@@ -4609,15 +5129,15 @@ var AppConfirmDialog = ({
|
|
|
4609
5129
|
destructive = false,
|
|
4610
5130
|
className
|
|
4611
5131
|
}) => {
|
|
4612
|
-
return /* @__PURE__ */ (0,
|
|
5132
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Dialog, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
4613
5133
|
DialogContent,
|
|
4614
5134
|
{
|
|
4615
5135
|
className: cn("gap-0 p-0 sm:max-w-md", className),
|
|
4616
|
-
children: /* @__PURE__ */ (0,
|
|
4617
|
-
/* @__PURE__ */ (0,
|
|
4618
|
-
description ? /* @__PURE__ */ (0,
|
|
4619
|
-
/* @__PURE__ */ (0,
|
|
4620
|
-
/* @__PURE__ */ (0,
|
|
5136
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: bodyClass2, children: [
|
|
5137
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(DialogTitle, { className: titleClass, children: title }),
|
|
5138
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("p", { className: "text-sm text-muted-foreground", children: description }) : null,
|
|
5139
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: actionsClass, children: [
|
|
5140
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
4621
5141
|
TimbalV2Button,
|
|
4622
5142
|
{
|
|
4623
5143
|
type: "button",
|
|
@@ -4627,7 +5147,7 @@ var AppConfirmDialog = ({
|
|
|
4627
5147
|
children: cancelLabel
|
|
4628
5148
|
}
|
|
4629
5149
|
),
|
|
4630
|
-
/* @__PURE__ */ (0,
|
|
5150
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
4631
5151
|
TimbalV2Button,
|
|
4632
5152
|
{
|
|
4633
5153
|
type: "button",
|
|
@@ -4646,30 +5166,640 @@ var AppConfirmDialog = ({
|
|
|
4646
5166
|
) });
|
|
4647
5167
|
};
|
|
4648
5168
|
|
|
4649
|
-
// src/
|
|
4650
|
-
var
|
|
4651
|
-
var
|
|
5169
|
+
// src/app/surfaces/InfoCard.tsx
|
|
5170
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
5171
|
+
var toneClass = {
|
|
5172
|
+
neutral: "border-border bg-muted/40",
|
|
5173
|
+
info: "border-primary/25 bg-primary/5",
|
|
5174
|
+
success: "border-emerald-500/25 bg-emerald-500/5",
|
|
5175
|
+
warn: "border-amber-500/25 bg-amber-500/5",
|
|
5176
|
+
danger: "border-destructive/25 bg-destructive/5"
|
|
5177
|
+
};
|
|
5178
|
+
var InfoCard = ({
|
|
5179
|
+
title,
|
|
5180
|
+
children,
|
|
5181
|
+
icon,
|
|
5182
|
+
action,
|
|
5183
|
+
tone = "neutral",
|
|
5184
|
+
className
|
|
5185
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
5186
|
+
"div",
|
|
5187
|
+
{
|
|
5188
|
+
className: cn(
|
|
5189
|
+
"flex items-start gap-3 rounded-xl border p-4",
|
|
5190
|
+
toneClass[tone],
|
|
5191
|
+
className
|
|
5192
|
+
),
|
|
5193
|
+
children: [
|
|
5194
|
+
icon ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "mt-0.5 shrink-0 text-muted-foreground", children: icon }) : null,
|
|
5195
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
5196
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { className: "text-sm font-medium text-foreground", children: title }) : null,
|
|
5197
|
+
children ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: cn("text-sm text-muted-foreground", title && "mt-1"), children }) : null
|
|
5198
|
+
] }),
|
|
5199
|
+
action ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "shrink-0", children: action }) : null
|
|
5200
|
+
]
|
|
5201
|
+
}
|
|
5202
|
+
);
|
|
4652
5203
|
|
|
4653
|
-
// src/
|
|
4654
|
-
var
|
|
4655
|
-
var
|
|
4656
|
-
"bg-
|
|
4657
|
-
"
|
|
5204
|
+
// src/app/surfaces/StatusDot.tsx
|
|
5205
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
5206
|
+
var dotClass = {
|
|
5207
|
+
online: "bg-emerald-500",
|
|
5208
|
+
busy: "bg-amber-500",
|
|
5209
|
+
offline: "bg-muted-foreground/50",
|
|
5210
|
+
error: "bg-destructive",
|
|
5211
|
+
neutral: "bg-muted-foreground"
|
|
5212
|
+
};
|
|
5213
|
+
var StatusDot = ({
|
|
5214
|
+
tone = "neutral",
|
|
5215
|
+
label,
|
|
5216
|
+
pulse = false,
|
|
5217
|
+
className
|
|
5218
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: cn("inline-flex items-center gap-1.5", className), children: [
|
|
5219
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "relative flex size-2", children: [
|
|
5220
|
+
pulse ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
5221
|
+
"span",
|
|
5222
|
+
{
|
|
5223
|
+
className: cn(
|
|
5224
|
+
"absolute inline-flex size-full animate-ping rounded-full opacity-60",
|
|
5225
|
+
dotClass[tone]
|
|
5226
|
+
)
|
|
5227
|
+
}
|
|
5228
|
+
) : null,
|
|
5229
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: cn("relative inline-flex size-2 rounded-full", dotClass[tone]) })
|
|
5230
|
+
] }),
|
|
5231
|
+
label ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "text-xs text-muted-foreground", children: label }) : null
|
|
5232
|
+
] });
|
|
5233
|
+
|
|
5234
|
+
// src/app/surfaces/DescriptionList.tsx
|
|
5235
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
5236
|
+
var DescriptionList = ({
|
|
5237
|
+
items,
|
|
5238
|
+
stacked = false,
|
|
5239
|
+
className
|
|
5240
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
5241
|
+
"dl",
|
|
5242
|
+
{
|
|
5243
|
+
className: cn(
|
|
5244
|
+
"divide-y divide-border rounded-xl border border-border bg-card",
|
|
5245
|
+
className
|
|
5246
|
+
),
|
|
5247
|
+
children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
5248
|
+
"div",
|
|
5249
|
+
{
|
|
5250
|
+
className: cn(
|
|
5251
|
+
"px-4 py-3",
|
|
5252
|
+
stacked ? "flex flex-col gap-0.5" : "flex items-center justify-between gap-4"
|
|
5253
|
+
),
|
|
5254
|
+
children: [
|
|
5255
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("dt", { className: "text-sm text-muted-foreground", children: item.label }),
|
|
5256
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
5257
|
+
"dd",
|
|
5258
|
+
{
|
|
5259
|
+
className: cn(
|
|
5260
|
+
"text-sm text-foreground",
|
|
5261
|
+
!stacked && "text-right tabular-nums"
|
|
5262
|
+
),
|
|
5263
|
+
children: item.value
|
|
5264
|
+
}
|
|
5265
|
+
)
|
|
5266
|
+
]
|
|
5267
|
+
},
|
|
5268
|
+
i
|
|
5269
|
+
))
|
|
5270
|
+
}
|
|
4658
5271
|
);
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
5272
|
+
|
|
5273
|
+
// src/app/surfaces/ExpandableSection.tsx
|
|
5274
|
+
var import_react37 = require("react");
|
|
5275
|
+
var import_react38 = require("motion/react");
|
|
5276
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
5277
|
+
var Chevron = ({ open }) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
5278
|
+
"svg",
|
|
5279
|
+
{
|
|
5280
|
+
viewBox: "0 0 24 24",
|
|
5281
|
+
className: cn(
|
|
5282
|
+
"size-4 text-muted-foreground transition-transform duration-200",
|
|
5283
|
+
open && "rotate-180"
|
|
5284
|
+
),
|
|
5285
|
+
fill: "none",
|
|
5286
|
+
stroke: "currentColor",
|
|
5287
|
+
strokeWidth: 2,
|
|
5288
|
+
strokeLinecap: "round",
|
|
5289
|
+
strokeLinejoin: "round",
|
|
5290
|
+
"aria-hidden": true,
|
|
5291
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("path", { d: "m6 9 6 6 6-6" })
|
|
5292
|
+
}
|
|
4663
5293
|
);
|
|
4664
|
-
var
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
5294
|
+
var ExpandableSection = ({
|
|
5295
|
+
title,
|
|
5296
|
+
icon,
|
|
5297
|
+
count,
|
|
5298
|
+
children,
|
|
5299
|
+
open: openProp,
|
|
5300
|
+
defaultOpen = false,
|
|
5301
|
+
onOpenChange,
|
|
5302
|
+
className
|
|
5303
|
+
}) => {
|
|
5304
|
+
const reduceMotion = (0, import_react38.useReducedMotion)();
|
|
5305
|
+
const panelId = (0, import_react37.useId)();
|
|
5306
|
+
const [internalOpen, setInternalOpen] = (0, import_react37.useState)(defaultOpen);
|
|
5307
|
+
const open = openProp ?? internalOpen;
|
|
5308
|
+
const toggle = () => {
|
|
5309
|
+
if (openProp == null) setInternalOpen((o) => !o);
|
|
5310
|
+
onOpenChange?.(!open);
|
|
5311
|
+
};
|
|
5312
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: cn("border-b border-border last:border-0", className), children: [
|
|
5313
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
|
|
5314
|
+
"button",
|
|
5315
|
+
{
|
|
5316
|
+
type: "button",
|
|
5317
|
+
onClick: toggle,
|
|
5318
|
+
"aria-expanded": open,
|
|
5319
|
+
"aria-controls": panelId,
|
|
5320
|
+
className: "flex w-full items-center justify-between gap-3 bg-transparent px-4 py-3 text-left hover:bg-transparent active:bg-transparent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-foreground/10",
|
|
5321
|
+
children: [
|
|
5322
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("span", { className: "flex min-w-0 items-center gap-3", children: [
|
|
5323
|
+
icon ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "flex size-8 items-center justify-center rounded-lg border border-border bg-muted text-muted-foreground", children: icon }) : null,
|
|
5324
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "truncate text-sm font-medium text-foreground", children: title }),
|
|
5325
|
+
count != null ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "rounded-full border border-border bg-muted px-2 py-0.5 text-xs text-muted-foreground", children: count }) : null
|
|
5326
|
+
] }),
|
|
5327
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Chevron, { open })
|
|
5328
|
+
]
|
|
5329
|
+
}
|
|
5330
|
+
),
|
|
5331
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react38.AnimatePresence, { initial: false, children: open ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
5332
|
+
import_react38.motion.div,
|
|
5333
|
+
{
|
|
5334
|
+
id: panelId,
|
|
5335
|
+
initial: reduceMotion ? void 0 : { height: 0, opacity: 0 },
|
|
5336
|
+
animate: { height: "auto", opacity: 1 },
|
|
5337
|
+
exit: reduceMotion ? void 0 : { height: 0, opacity: 0 },
|
|
5338
|
+
transition: { duration: 0.2, ease: "easeOut" },
|
|
5339
|
+
className: "overflow-hidden",
|
|
5340
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "bg-muted/20", children })
|
|
5341
|
+
},
|
|
5342
|
+
"body"
|
|
5343
|
+
) : null })
|
|
5344
|
+
] });
|
|
5345
|
+
};
|
|
5346
|
+
|
|
5347
|
+
// src/app/surfaces/ResourceCard.tsx
|
|
5348
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
5349
|
+
var resourceCardShellClass = cn(
|
|
5350
|
+
"flex min-h-[8.5rem] flex-col rounded-2xl p-4 text-left font-normal",
|
|
5351
|
+
TIMBAL_V2_ELEVATED_SURFACE
|
|
4668
5352
|
);
|
|
4669
|
-
var
|
|
4670
|
-
"
|
|
5353
|
+
var mediaShellClass = cn(
|
|
5354
|
+
"flex size-10 shrink-0 items-center justify-center overflow-hidden rounded-xl text-sm font-normal text-foreground",
|
|
5355
|
+
TIMBAL_V2_LOGO_TILE
|
|
4671
5356
|
);
|
|
4672
|
-
var
|
|
5357
|
+
var resourceCardInteractiveClass = cn(
|
|
5358
|
+
resourceCardShellClass,
|
|
5359
|
+
"cursor-pointer bg-transparent hover:bg-transparent active:bg-transparent",
|
|
5360
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/15 focus-visible:ring-offset-2 focus-visible:ring-offset-background"
|
|
5361
|
+
);
|
|
5362
|
+
var ResourceCard = ({
|
|
5363
|
+
title,
|
|
5364
|
+
subtitle,
|
|
5365
|
+
media,
|
|
5366
|
+
badge,
|
|
5367
|
+
footer,
|
|
5368
|
+
action,
|
|
5369
|
+
onClick,
|
|
5370
|
+
ariaLabel,
|
|
5371
|
+
className
|
|
5372
|
+
}) => {
|
|
5373
|
+
const body = /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_jsx_runtime47.Fragment, { children: [
|
|
5374
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-start gap-3", children: [
|
|
5375
|
+
media ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: mediaShellClass, children: media }) : null,
|
|
5376
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "min-w-0 flex-1 pt-0.5", children: [
|
|
5377
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("p", { className: "truncate text-sm font-normal leading-snug text-foreground", children: title }),
|
|
5378
|
+
subtitle ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("p", { className: "mt-1 line-clamp-2 text-xs font-normal text-muted-foreground", children: subtitle }) : null
|
|
5379
|
+
] }),
|
|
5380
|
+
badge ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "shrink-0 pt-0.5", children: badge }) : null
|
|
5381
|
+
] }),
|
|
5382
|
+
footer || action ? /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "mt-auto flex items-center justify-between gap-3 border-t border-border/40 pt-3 text-xs font-normal text-muted-foreground", children: [
|
|
5383
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "min-w-0 truncate", children: footer }),
|
|
5384
|
+
action ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "shrink-0 opacity-80", children: action }) : null
|
|
5385
|
+
] }) : null
|
|
5386
|
+
] });
|
|
5387
|
+
if (onClick) {
|
|
5388
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", onClick, "aria-label": ariaLabel, className: cn(resourceCardInteractiveClass, className), children: body });
|
|
5389
|
+
}
|
|
5390
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("article", { className: cn(resourceCardShellClass, className), children: body });
|
|
5391
|
+
};
|
|
5392
|
+
|
|
5393
|
+
// src/app/settings/SettingsSection.tsx
|
|
5394
|
+
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
5395
|
+
var SettingsSectionHeader = ({
|
|
5396
|
+
title,
|
|
5397
|
+
description,
|
|
5398
|
+
className
|
|
5399
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: cn("flex flex-col", className), children: [
|
|
5400
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("h3", { className: "text-[17px] font-medium leading-tight text-foreground", children: title }),
|
|
5401
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null
|
|
5402
|
+
] });
|
|
5403
|
+
var SettingsSection = ({
|
|
5404
|
+
title,
|
|
5405
|
+
description,
|
|
5406
|
+
descriptionFooter,
|
|
5407
|
+
children,
|
|
5408
|
+
noBorderTop = false,
|
|
5409
|
+
className
|
|
5410
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
|
|
5411
|
+
"section",
|
|
5412
|
+
{
|
|
5413
|
+
className: cn(
|
|
5414
|
+
"grid grid-cols-1 gap-y-4 lg:grid-cols-[minmax(200px,280px)_minmax(0,1fr)] lg:gap-x-12 lg:gap-y-0",
|
|
5415
|
+
noBorderTop ? "pb-6" : "border-t border-border py-6",
|
|
5416
|
+
className
|
|
5417
|
+
),
|
|
5418
|
+
children: [
|
|
5419
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "min-w-0", children: [
|
|
5420
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("h2", { className: "text-sm font-medium text-foreground", children: title }),
|
|
5421
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null,
|
|
5422
|
+
descriptionFooter ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "mt-3 min-w-0", children: descriptionFooter }) : null
|
|
5423
|
+
] }),
|
|
5424
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "min-w-0 space-y-3", children })
|
|
5425
|
+
]
|
|
5426
|
+
}
|
|
5427
|
+
);
|
|
5428
|
+
|
|
5429
|
+
// src/app/settings/FieldRow.tsx
|
|
5430
|
+
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
5431
|
+
var FieldRow = ({
|
|
5432
|
+
label,
|
|
5433
|
+
children,
|
|
5434
|
+
description,
|
|
5435
|
+
inline = false,
|
|
5436
|
+
htmlFor,
|
|
5437
|
+
className
|
|
5438
|
+
}) => {
|
|
5439
|
+
if (inline) {
|
|
5440
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
|
|
5441
|
+
"div",
|
|
5442
|
+
{
|
|
5443
|
+
className: cn(
|
|
5444
|
+
"flex items-center justify-between gap-4 rounded-lg border border-border bg-card px-3.5 py-3",
|
|
5445
|
+
className
|
|
5446
|
+
),
|
|
5447
|
+
children: [
|
|
5448
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "min-w-0", children: [
|
|
5449
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
5450
|
+
"label",
|
|
5451
|
+
{
|
|
5452
|
+
htmlFor,
|
|
5453
|
+
className: "block text-sm font-medium text-foreground",
|
|
5454
|
+
children: label
|
|
5455
|
+
}
|
|
5456
|
+
),
|
|
5457
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("p", { className: "mt-0.5 text-xs text-muted-foreground", children: description }) : null
|
|
5458
|
+
] }),
|
|
5459
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "shrink-0", children })
|
|
5460
|
+
]
|
|
5461
|
+
}
|
|
5462
|
+
);
|
|
5463
|
+
}
|
|
5464
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: cn("flex flex-col gap-1.5", className), children: [
|
|
5465
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("label", { htmlFor, className: "text-sm font-medium text-foreground", children: label }),
|
|
5466
|
+
children,
|
|
5467
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("p", { className: "text-xs text-muted-foreground", children: description }) : null
|
|
5468
|
+
] });
|
|
5469
|
+
};
|
|
5470
|
+
|
|
5471
|
+
// src/app/settings/FloatingUnsavedChangesBar.tsx
|
|
5472
|
+
var import_react39 = require("react");
|
|
5473
|
+
var import_react_dom = require("react-dom");
|
|
5474
|
+
var import_react40 = require("motion/react");
|
|
5475
|
+
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
5476
|
+
var FloatingUnsavedChangesBar = ({
|
|
5477
|
+
visible,
|
|
5478
|
+
message = "Unsaved changes",
|
|
5479
|
+
discardLabel = "Discard",
|
|
5480
|
+
saveLabel = "Save changes",
|
|
5481
|
+
isSaving = false,
|
|
5482
|
+
saveDisabled = false,
|
|
5483
|
+
onDiscard,
|
|
5484
|
+
onSave,
|
|
5485
|
+
ariaLabel = "Unsaved changes",
|
|
5486
|
+
className
|
|
5487
|
+
}) => {
|
|
5488
|
+
const reduceMotion = (0, import_react40.useReducedMotion)();
|
|
5489
|
+
const [mounted, setMounted] = (0, import_react39.useState)(false);
|
|
5490
|
+
(0, import_react39.useEffect)(() => setMounted(true), []);
|
|
5491
|
+
if (!mounted || typeof document === "undefined") return null;
|
|
5492
|
+
return (0, import_react_dom.createPortal)(
|
|
5493
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_react40.AnimatePresence, { children: visible ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "pointer-events-none fixed inset-x-0 bottom-5 z-50 flex justify-center px-4", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
5494
|
+
import_react40.motion.div,
|
|
5495
|
+
{
|
|
5496
|
+
role: "region",
|
|
5497
|
+
"aria-label": ariaLabel,
|
|
5498
|
+
initial: reduceMotion ? { opacity: 0 } : { opacity: 0, y: 28, scale: 0.94 },
|
|
5499
|
+
animate: { opacity: 1, y: 0, scale: 1 },
|
|
5500
|
+
exit: reduceMotion ? { opacity: 0 } : { opacity: 0, y: 18, scale: 0.96 },
|
|
5501
|
+
transition: { type: "spring", stiffness: 420, damping: 32 },
|
|
5502
|
+
className: cn(
|
|
5503
|
+
"pointer-events-auto inline-flex max-w-[calc(100vw-2rem)] items-center gap-3 rounded-full border border-border bg-card py-1.5 pl-4 pr-1.5 shadow-card-elevated",
|
|
5504
|
+
className
|
|
5505
|
+
),
|
|
5506
|
+
children: [
|
|
5507
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "text-sm text-muted-foreground", children: message }),
|
|
5508
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("span", { className: "flex items-center gap-1.5", children: [
|
|
5509
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(Button, { variant: "ghost", size: "sm", onClick: onDiscard, disabled: isSaving, children: discardLabel }),
|
|
5510
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(Button, { size: "sm", onClick: onSave, disabled: saveDisabled || isSaving, children: isSaving ? "Saving\u2026" : saveLabel })
|
|
5511
|
+
] })
|
|
5512
|
+
]
|
|
5513
|
+
}
|
|
5514
|
+
) }) : null }),
|
|
5515
|
+
document.body
|
|
5516
|
+
);
|
|
5517
|
+
};
|
|
5518
|
+
|
|
5519
|
+
// src/app/settings/DangerZone.tsx
|
|
5520
|
+
var import_jsx_runtime51 = require("react/jsx-runtime");
|
|
5521
|
+
var DangerZoneAction = ({
|
|
5522
|
+
title,
|
|
5523
|
+
description,
|
|
5524
|
+
action,
|
|
5525
|
+
className
|
|
5526
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
5527
|
+
"div",
|
|
5528
|
+
{
|
|
5529
|
+
className: cn(
|
|
5530
|
+
"flex flex-col gap-3 px-4 py-3.5 sm:flex-row sm:items-center sm:justify-between",
|
|
5531
|
+
className
|
|
5532
|
+
),
|
|
5533
|
+
children: [
|
|
5534
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "min-w-0", children: [
|
|
5535
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("p", { className: "text-sm font-medium text-foreground", children: title }),
|
|
5536
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
|
|
5537
|
+
] }),
|
|
5538
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "shrink-0", children: action })
|
|
5539
|
+
]
|
|
5540
|
+
}
|
|
5541
|
+
);
|
|
5542
|
+
var DangerZone = ({
|
|
5543
|
+
title = "Danger zone",
|
|
5544
|
+
description,
|
|
5545
|
+
children,
|
|
5546
|
+
className
|
|
5547
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
5548
|
+
"section",
|
|
5549
|
+
{
|
|
5550
|
+
className: cn(
|
|
5551
|
+
"overflow-hidden rounded-xl border border-destructive/30",
|
|
5552
|
+
className
|
|
5553
|
+
),
|
|
5554
|
+
children: [
|
|
5555
|
+
(title || description) && /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("header", { className: "border-b border-destructive/20 bg-destructive/5 px-4 py-3", children: [
|
|
5556
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("h3", { className: "text-sm font-semibold text-destructive", children: title }) : null,
|
|
5557
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
|
|
5558
|
+
] }),
|
|
5559
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "divide-y divide-border bg-card", children })
|
|
5560
|
+
]
|
|
5561
|
+
}
|
|
5562
|
+
);
|
|
5563
|
+
|
|
5564
|
+
// src/app/integrations/IntegrationCard.tsx
|
|
5565
|
+
var import_react41 = require("react");
|
|
5566
|
+
var import_jsx_runtime52 = require("react/jsx-runtime");
|
|
5567
|
+
var INTEGRATION_CATALOG_CARD_HEIGHT_CLASS = "h-[12.25rem] min-h-[12.25rem] max-h-[12.25rem]";
|
|
5568
|
+
var statusLabel = {
|
|
5569
|
+
available: null,
|
|
5570
|
+
connected: "Connected",
|
|
5571
|
+
disabled: "Disabled",
|
|
5572
|
+
locked: "Locked"
|
|
5573
|
+
};
|
|
5574
|
+
var catalogCardShellClass = cn(
|
|
5575
|
+
"group relative box-border flex flex-col overflow-hidden rounded-2xl px-4 pb-4 pt-4 text-left font-normal",
|
|
5576
|
+
INTEGRATION_CATALOG_CARD_HEIGHT_CLASS,
|
|
5577
|
+
TIMBAL_V2_ELEVATED_SURFACE,
|
|
5578
|
+
"transition-opacity duration-200 ease-out"
|
|
5579
|
+
);
|
|
5580
|
+
var catalogCardInteractiveClass = cn(
|
|
5581
|
+
catalogCardShellClass,
|
|
5582
|
+
"cursor-pointer bg-transparent hover:bg-transparent active:bg-transparent",
|
|
5583
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/15 focus-visible:ring-offset-2 focus-visible:ring-offset-background"
|
|
5584
|
+
);
|
|
5585
|
+
var catalogCardMutedClass = cn(
|
|
5586
|
+
"border-border/60 saturate-[0.72]",
|
|
5587
|
+
"from-muted/80 to-muted/50 dark:border-white/[0.06] dark:from-white/[0.04] dark:to-white/[0.02]"
|
|
5588
|
+
);
|
|
5589
|
+
var logoShellClass = cn(
|
|
5590
|
+
"relative flex size-10 shrink-0 items-center justify-center overflow-hidden rounded-xl",
|
|
5591
|
+
TIMBAL_V2_LOGO_TILE
|
|
5592
|
+
);
|
|
5593
|
+
var IntegrationCard = ({
|
|
5594
|
+
name,
|
|
5595
|
+
description,
|
|
5596
|
+
logo,
|
|
5597
|
+
badge,
|
|
5598
|
+
status = "available",
|
|
5599
|
+
action,
|
|
5600
|
+
onClick,
|
|
5601
|
+
ariaLabel,
|
|
5602
|
+
className
|
|
5603
|
+
}) => {
|
|
5604
|
+
const titleId = (0, import_react41.useId)();
|
|
5605
|
+
const locked = status === "locked";
|
|
5606
|
+
const dimmed = status === "disabled" || locked;
|
|
5607
|
+
const body = /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "flex h-full min-h-0 flex-col", children: [
|
|
5608
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "flex shrink-0 items-start gap-3 pr-2", children: [
|
|
5609
|
+
logo ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: logoShellClass, "aria-hidden": Boolean(ariaLabel), children: logo }) : null,
|
|
5610
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "min-w-0 flex-1 pt-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "flex items-start justify-between gap-2", children: [
|
|
5611
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "min-w-0", children: [
|
|
5612
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
5613
|
+
"h4",
|
|
5614
|
+
{
|
|
5615
|
+
id: onClick && !action ? void 0 : titleId,
|
|
5616
|
+
className: "truncate text-sm font-normal leading-snug text-foreground",
|
|
5617
|
+
children: name
|
|
5618
|
+
}
|
|
5619
|
+
),
|
|
5620
|
+
statusLabel[status] ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("p", { className: "mt-0.5 text-xs text-muted-foreground", children: statusLabel[status] }) : null
|
|
5621
|
+
] }),
|
|
5622
|
+
badge ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "shrink-0", children: badge }) : null
|
|
5623
|
+
] }) })
|
|
5624
|
+
] }),
|
|
5625
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
5626
|
+
"p",
|
|
5627
|
+
{
|
|
5628
|
+
className: cn(
|
|
5629
|
+
"mt-3 line-clamp-3 shrink-0 text-sm leading-relaxed text-muted-foreground",
|
|
5630
|
+
dimmed && "text-muted-foreground/80"
|
|
5631
|
+
),
|
|
5632
|
+
children: description
|
|
5633
|
+
}
|
|
5634
|
+
) : null,
|
|
5635
|
+
action ? /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_jsx_runtime52.Fragment, { children: [
|
|
5636
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "min-h-0 flex-1", "aria-hidden": true }),
|
|
5637
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "relative mt-3 shrink-0", children: action })
|
|
5638
|
+
] }) : null
|
|
5639
|
+
] });
|
|
5640
|
+
const shellClass3 = cn(
|
|
5641
|
+
catalogCardShellClass,
|
|
5642
|
+
dimmed && catalogCardMutedClass,
|
|
5643
|
+
locked && "cursor-default opacity-75",
|
|
5644
|
+
className
|
|
5645
|
+
);
|
|
5646
|
+
if (onClick && !action) {
|
|
5647
|
+
return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
5648
|
+
"button",
|
|
5649
|
+
{
|
|
5650
|
+
type: "button",
|
|
5651
|
+
onClick,
|
|
5652
|
+
disabled: locked,
|
|
5653
|
+
"aria-label": ariaLabel,
|
|
5654
|
+
className: cn(
|
|
5655
|
+
catalogCardInteractiveClass,
|
|
5656
|
+
dimmed && catalogCardMutedClass,
|
|
5657
|
+
locked && "cursor-default opacity-75",
|
|
5658
|
+
className
|
|
5659
|
+
),
|
|
5660
|
+
children: body
|
|
5661
|
+
}
|
|
5662
|
+
);
|
|
5663
|
+
}
|
|
5664
|
+
return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("article", { className: shellClass3, "aria-labelledby": titleId, children: body });
|
|
5665
|
+
};
|
|
5666
|
+
|
|
5667
|
+
// src/app/integrations/IntegrationsEmptyState.tsx
|
|
5668
|
+
var import_react42 = require("react");
|
|
5669
|
+
var import_jsx_runtime53 = require("react/jsx-runtime");
|
|
5670
|
+
var IntegrationsEmptyState = ({
|
|
5671
|
+
title = "No integrations yet",
|
|
5672
|
+
description = "Connect a provider to start syncing data and powering your workforce.",
|
|
5673
|
+
icon,
|
|
5674
|
+
action,
|
|
5675
|
+
className
|
|
5676
|
+
}) => {
|
|
5677
|
+
const titleId = (0, import_react42.useId)();
|
|
5678
|
+
return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
|
|
5679
|
+
"section",
|
|
5680
|
+
{
|
|
5681
|
+
className: cn(
|
|
5682
|
+
"flex flex-col items-center justify-center gap-3 rounded-2xl px-6 py-14 text-center",
|
|
5683
|
+
TIMBAL_V2_ELEVATED_SURFACE,
|
|
5684
|
+
className
|
|
5685
|
+
),
|
|
5686
|
+
"aria-labelledby": titleId,
|
|
5687
|
+
children: [
|
|
5688
|
+
icon ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
5689
|
+
"span",
|
|
5690
|
+
{
|
|
5691
|
+
className: cn(
|
|
5692
|
+
"flex size-14 items-center justify-center overflow-hidden rounded-2xl",
|
|
5693
|
+
TIMBAL_V2_LOGO_TILE,
|
|
5694
|
+
"text-muted-foreground"
|
|
5695
|
+
),
|
|
5696
|
+
"aria-hidden": true,
|
|
5697
|
+
children: icon
|
|
5698
|
+
}
|
|
5699
|
+
) : null,
|
|
5700
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)("h3", { id: titleId, className: "text-base font-normal text-foreground", children: title }),
|
|
5701
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { className: "max-w-sm text-sm text-muted-foreground", children: description }) : null,
|
|
5702
|
+
action ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "mt-1", children: action }) : null
|
|
5703
|
+
]
|
|
5704
|
+
}
|
|
5705
|
+
);
|
|
5706
|
+
};
|
|
5707
|
+
|
|
5708
|
+
// src/app/integrations/PlanBadge.tsx
|
|
5709
|
+
var import_jsx_runtime54 = require("react/jsx-runtime");
|
|
5710
|
+
var planBadgeClass = "inline-flex h-5 max-w-full shrink-0 items-center rounded-md border border-border bg-muted/90 px-2 text-[11px] font-normal text-muted-foreground dark:border-white/10 dark:bg-white/5 dark:text-muted-foreground";
|
|
5711
|
+
var PlanBadge = ({ children, className }) => /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: cn(planBadgeClass, className), children });
|
|
5712
|
+
|
|
5713
|
+
// src/app/integrations/ConnectionRow.tsx
|
|
5714
|
+
var import_jsx_runtime55 = require("react/jsx-runtime");
|
|
5715
|
+
var logoShellClass2 = cn(
|
|
5716
|
+
"flex size-9 shrink-0 items-center justify-center overflow-hidden rounded-lg",
|
|
5717
|
+
TIMBAL_V2_LOGO_TILE
|
|
5718
|
+
);
|
|
5719
|
+
var ConnectionRow = ({
|
|
5720
|
+
name,
|
|
5721
|
+
logo,
|
|
5722
|
+
meta,
|
|
5723
|
+
badge,
|
|
5724
|
+
action,
|
|
5725
|
+
onClick,
|
|
5726
|
+
ariaLabel,
|
|
5727
|
+
className
|
|
5728
|
+
}) => {
|
|
5729
|
+
const inner = /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
|
|
5730
|
+
logo ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: logoShellClass2, children: logo }) : null,
|
|
5731
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
5732
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)("p", { className: "truncate text-sm font-normal text-foreground", children: name }),
|
|
5733
|
+
meta ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("p", { className: "truncate text-xs text-muted-foreground", children: meta }) : null
|
|
5734
|
+
] }),
|
|
5735
|
+
badge ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "shrink-0", children: badge }) : null,
|
|
5736
|
+
action ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "shrink-0", children: action }) : null
|
|
5737
|
+
] });
|
|
5738
|
+
const rowClass2 = cn(
|
|
5739
|
+
"flex w-full items-center gap-3 px-4 py-3 text-left",
|
|
5740
|
+
onClick && "cursor-pointer bg-transparent hover:bg-transparent active:bg-transparent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-foreground/10",
|
|
5741
|
+
className
|
|
5742
|
+
);
|
|
5743
|
+
if (onClick) {
|
|
5744
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
5745
|
+
"button",
|
|
5746
|
+
{
|
|
5747
|
+
type: "button",
|
|
5748
|
+
role: "listitem",
|
|
5749
|
+
onClick,
|
|
5750
|
+
"aria-label": ariaLabel,
|
|
5751
|
+
className: rowClass2,
|
|
5752
|
+
children: inner
|
|
5753
|
+
}
|
|
5754
|
+
);
|
|
5755
|
+
}
|
|
5756
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { role: "listitem", className: rowClass2, children: inner });
|
|
5757
|
+
};
|
|
5758
|
+
var connectionRowListClass = cn(
|
|
5759
|
+
"overflow-hidden rounded-2xl",
|
|
5760
|
+
TIMBAL_V2_ELEVATED_SURFACE
|
|
5761
|
+
);
|
|
5762
|
+
|
|
5763
|
+
// src/app/integrations/ConnectionRowList.tsx
|
|
5764
|
+
var import_jsx_runtime56 = require("react/jsx-runtime");
|
|
5765
|
+
var ConnectionRowList = ({
|
|
5766
|
+
children,
|
|
5767
|
+
"aria-label": ariaLabel = "Connected integrations",
|
|
5768
|
+
className
|
|
5769
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
5770
|
+
"div",
|
|
5771
|
+
{
|
|
5772
|
+
role: "list",
|
|
5773
|
+
"aria-label": ariaLabel,
|
|
5774
|
+
className: cn(connectionRowListClass, "divide-y divide-border", className),
|
|
5775
|
+
children
|
|
5776
|
+
}
|
|
5777
|
+
);
|
|
5778
|
+
|
|
5779
|
+
// src/ui/pill-segmented-tabs.tsx
|
|
5780
|
+
var import_react43 = require("react");
|
|
5781
|
+
var import_react44 = require("motion/react");
|
|
5782
|
+
|
|
5783
|
+
// src/design/pill-segmented-classes.ts
|
|
5784
|
+
var pillSegmentedTrackBase = "inline-flex w-fit max-w-max shrink-0 self-start items-center rounded-full";
|
|
5785
|
+
var pillSegmentedTrackSurface = cn(
|
|
5786
|
+
"bg-pill-segmented-track border border-[var(--pill-segmented-track-border)]",
|
|
5787
|
+
"shadow-[var(--pill-segmented-track-shadow)]"
|
|
5788
|
+
);
|
|
5789
|
+
var pillSegmentedTrackClass = cn(
|
|
5790
|
+
pillSegmentedTrackBase,
|
|
5791
|
+
pillSegmentedTrackSurface,
|
|
5792
|
+
"gap-1 p-1"
|
|
5793
|
+
);
|
|
5794
|
+
var pillSegmentedTrackFlushClass = cn(
|
|
5795
|
+
pillSegmentedTrackBase,
|
|
5796
|
+
pillSegmentedTrackSurface,
|
|
5797
|
+
"h-[var(--studio-chrome-pill-height)] items-center gap-0.5 overflow-visible p-0.5"
|
|
5798
|
+
);
|
|
5799
|
+
var pillSegmentedSegmentClass = cn(
|
|
5800
|
+
"relative flex items-center gap-1.5 rounded-full px-4 py-1.5 text-xs font-normal transition-colors"
|
|
5801
|
+
);
|
|
5802
|
+
var pillSegmentedFlushSegmentClass = cn(
|
|
4673
5803
|
"relative box-border inline-flex h-9 min-h-9 items-center justify-center gap-1.5 rounded-full px-3.5 py-0",
|
|
4674
5804
|
"text-sm font-normal leading-tight transition-colors"
|
|
4675
5805
|
);
|
|
@@ -4681,7 +5811,7 @@ var pillSegmentedActiveIndicatorClass = cn(
|
|
|
4681
5811
|
);
|
|
4682
5812
|
|
|
4683
5813
|
// src/ui/pill-segmented-tabs.tsx
|
|
4684
|
-
var
|
|
5814
|
+
var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
4685
5815
|
var PillTab = ({
|
|
4686
5816
|
tabKey,
|
|
4687
5817
|
label,
|
|
@@ -4692,10 +5822,10 @@ var PillTab = ({
|
|
|
4692
5822
|
segmentClassName,
|
|
4693
5823
|
animateIndicator
|
|
4694
5824
|
}) => {
|
|
4695
|
-
const handlePress = (0,
|
|
5825
|
+
const handlePress = (0, import_react43.useCallback)(() => {
|
|
4696
5826
|
if (!disabled) onSelect(tabKey);
|
|
4697
5827
|
}, [disabled, onSelect, tabKey]);
|
|
4698
|
-
return /* @__PURE__ */ (0,
|
|
5828
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
|
|
4699
5829
|
"button",
|
|
4700
5830
|
{
|
|
4701
5831
|
type: "button",
|
|
@@ -4708,15 +5838,15 @@ var PillTab = ({
|
|
|
4708
5838
|
!disabled && (isActive ? "text-foreground" : "text-muted-foreground hover:text-foreground")
|
|
4709
5839
|
),
|
|
4710
5840
|
children: [
|
|
4711
|
-
isActive && animateIndicator ? /* @__PURE__ */ (0,
|
|
4712
|
-
|
|
5841
|
+
isActive && animateIndicator ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
5842
|
+
import_react44.motion.div,
|
|
4713
5843
|
{
|
|
4714
5844
|
layoutId,
|
|
4715
5845
|
className: pillSegmentedActiveIndicatorClass,
|
|
4716
5846
|
transition: { type: "spring", duration: 0.3, bounce: 0.15 }
|
|
4717
5847
|
}
|
|
4718
|
-
) : isActive ? /* @__PURE__ */ (0,
|
|
4719
|
-
/* @__PURE__ */ (0,
|
|
5848
|
+
) : isActive ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: pillSegmentedActiveIndicatorClass, "aria-hidden": true }) : null,
|
|
5849
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "relative z-10 whitespace-nowrap", children: label })
|
|
4720
5850
|
]
|
|
4721
5851
|
}
|
|
4722
5852
|
);
|
|
@@ -4730,13 +5860,13 @@ var PillSegmentedTabs = ({
|
|
|
4730
5860
|
layoutId: layoutIdProp,
|
|
4731
5861
|
"aria-label": ariaLabel
|
|
4732
5862
|
}) => {
|
|
4733
|
-
const reactId = (0,
|
|
5863
|
+
const reactId = (0, import_react43.useId)();
|
|
4734
5864
|
const layoutId = layoutIdProp ?? `pill-segmented-${reactId.replace(/:/g, "")}`;
|
|
4735
|
-
const reducedMotion = (0,
|
|
5865
|
+
const reducedMotion = (0, import_react44.useReducedMotion)();
|
|
4736
5866
|
const isFlush = trackVariant === "flush";
|
|
4737
5867
|
const trackClass2 = isFlush ? pillSegmentedTrackFlushClass : pillSegmentedTrackClass;
|
|
4738
5868
|
const segmentClassName = isFlush ? pillSegmentedFlushSegmentClass : pillSegmentedSegmentClass;
|
|
4739
|
-
return /* @__PURE__ */ (0,
|
|
5869
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { role: "group", "aria-label": ariaLabel, className: cn(trackClass2, className), children: tabs.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
4740
5870
|
PillTab,
|
|
4741
5871
|
{
|
|
4742
5872
|
tabKey: tab.key,
|
|
@@ -4751,10 +5881,10 @@ var PillSegmentedTabs = ({
|
|
|
4751
5881
|
tab.key
|
|
4752
5882
|
)) });
|
|
4753
5883
|
};
|
|
4754
|
-
var MemoPillSegmentedTabs = (0,
|
|
5884
|
+
var MemoPillSegmentedTabs = (0, import_react43.memo)(PillSegmentedTabs);
|
|
4755
5885
|
|
|
4756
5886
|
// src/app/navigation/SubNav.tsx
|
|
4757
|
-
var
|
|
5887
|
+
var import_jsx_runtime58 = require("react/jsx-runtime");
|
|
4758
5888
|
var SubNav = ({
|
|
4759
5889
|
items,
|
|
4760
5890
|
activeId,
|
|
@@ -4763,7 +5893,7 @@ var SubNav = ({
|
|
|
4763
5893
|
"aria-label": ariaLabel = "Section navigation",
|
|
4764
5894
|
layoutId
|
|
4765
5895
|
}) => {
|
|
4766
|
-
return /* @__PURE__ */ (0,
|
|
5896
|
+
return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("nav", { className: cn("aui-app-sub-nav", className), "aria-label": ariaLabel, children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
4767
5897
|
PillSegmentedTabs,
|
|
4768
5898
|
{
|
|
4769
5899
|
value: activeId,
|
|
@@ -4777,13 +5907,13 @@ var SubNav = ({
|
|
|
4777
5907
|
};
|
|
4778
5908
|
|
|
4779
5909
|
// src/app/navigation/Breadcrumbs.tsx
|
|
4780
|
-
var
|
|
5910
|
+
var import_jsx_runtime59 = require("react/jsx-runtime");
|
|
4781
5911
|
var Breadcrumbs = ({ items, className }) => {
|
|
4782
|
-
return /* @__PURE__ */ (0,
|
|
5912
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("nav", { className: cn("aui-app-breadcrumbs", appBreadcrumbsClass, className), "aria-label": "Breadcrumb", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("ol", { className: "flex flex-wrap items-center gap-1.5", children: items.map((item, index) => {
|
|
4783
5913
|
const isLast = index === items.length - 1;
|
|
4784
|
-
return /* @__PURE__ */ (0,
|
|
4785
|
-
index > 0 ? /* @__PURE__ */ (0,
|
|
4786
|
-
isLast ? /* @__PURE__ */ (0,
|
|
5914
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("li", { className: "inline-flex items-center gap-1.5", children: [
|
|
5915
|
+
index > 0 ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "text-muted-foreground/50", "aria-hidden": true, children: "/" }) : null,
|
|
5916
|
+
isLast ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "text-foreground", "aria-current": "page", children: item.label }) : item.href ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("a", { href: item.href, className: appBreadcrumbLinkClass, children: item.label }) : /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
4787
5917
|
"button",
|
|
4788
5918
|
{
|
|
4789
5919
|
type: "button",
|
|
@@ -4797,7 +5927,7 @@ var Breadcrumbs = ({ items, className }) => {
|
|
|
4797
5927
|
};
|
|
4798
5928
|
|
|
4799
5929
|
// src/app/forms/Field.tsx
|
|
4800
|
-
var
|
|
5930
|
+
var import_jsx_runtime60 = require("react/jsx-runtime");
|
|
4801
5931
|
var Field = ({
|
|
4802
5932
|
label,
|
|
4803
5933
|
hint,
|
|
@@ -4806,11 +5936,11 @@ var Field = ({
|
|
|
4806
5936
|
className,
|
|
4807
5937
|
htmlFor
|
|
4808
5938
|
}) => {
|
|
4809
|
-
return /* @__PURE__ */ (0,
|
|
4810
|
-
/* @__PURE__ */ (0,
|
|
5939
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: cn("aui-app-field", appFieldClass, className), children: [
|
|
5940
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("label", { className: appFieldLabelClass, htmlFor, children: label }),
|
|
4811
5941
|
children,
|
|
4812
|
-
hint && !error ? /* @__PURE__ */ (0,
|
|
4813
|
-
error ? /* @__PURE__ */ (0,
|
|
5942
|
+
hint && !error ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("p", { className: appFieldHintClass, children: hint }) : null,
|
|
5943
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("p", { className: "text-xs text-destructive", role: "alert", children: error }) : null
|
|
4814
5944
|
] });
|
|
4815
5945
|
};
|
|
4816
5946
|
var FieldInput = ({
|
|
@@ -4823,7 +5953,7 @@ var FieldInput = ({
|
|
|
4823
5953
|
...inputProps
|
|
4824
5954
|
}) => {
|
|
4825
5955
|
const inputId = id ?? inputProps.name;
|
|
4826
|
-
return /* @__PURE__ */ (0,
|
|
5956
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
4827
5957
|
Field,
|
|
4828
5958
|
{
|
|
4829
5959
|
label,
|
|
@@ -4831,7 +5961,7 @@ var FieldInput = ({
|
|
|
4831
5961
|
error,
|
|
4832
5962
|
htmlFor: inputId,
|
|
4833
5963
|
className: fieldClassName,
|
|
4834
|
-
children: /* @__PURE__ */ (0,
|
|
5964
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
4835
5965
|
"input",
|
|
4836
5966
|
{
|
|
4837
5967
|
id: inputId,
|
|
@@ -4845,7 +5975,7 @@ var FieldInput = ({
|
|
|
4845
5975
|
};
|
|
4846
5976
|
|
|
4847
5977
|
// src/app/forms/FieldTextarea.tsx
|
|
4848
|
-
var
|
|
5978
|
+
var import_jsx_runtime61 = require("react/jsx-runtime");
|
|
4849
5979
|
var textareaClass = cn(
|
|
4850
5980
|
appInputClass,
|
|
4851
5981
|
"min-h-[5.5rem] resize-y py-2.5 leading-relaxed"
|
|
@@ -4860,7 +5990,7 @@ var FieldTextarea = ({
|
|
|
4860
5990
|
...props
|
|
4861
5991
|
}) => {
|
|
4862
5992
|
const textareaId = id ?? props.name;
|
|
4863
|
-
return /* @__PURE__ */ (0,
|
|
5993
|
+
return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
4864
5994
|
Field,
|
|
4865
5995
|
{
|
|
4866
5996
|
label,
|
|
@@ -4868,7 +5998,7 @@ var FieldTextarea = ({
|
|
|
4868
5998
|
error,
|
|
4869
5999
|
htmlFor: textareaId,
|
|
4870
6000
|
className: fieldClassName,
|
|
4871
|
-
children: /* @__PURE__ */ (0,
|
|
6001
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
4872
6002
|
"textarea",
|
|
4873
6003
|
{
|
|
4874
6004
|
id: textareaId,
|
|
@@ -4883,7 +6013,7 @@ var FieldTextarea = ({
|
|
|
4883
6013
|
|
|
4884
6014
|
// src/app/forms/FieldSelect.tsx
|
|
4885
6015
|
var import_lucide_react10 = require("lucide-react");
|
|
4886
|
-
var
|
|
6016
|
+
var import_jsx_runtime62 = require("react/jsx-runtime");
|
|
4887
6017
|
var selectWrapClass = "relative";
|
|
4888
6018
|
var selectClass = cn(
|
|
4889
6019
|
appInputClass,
|
|
@@ -4900,7 +6030,7 @@ var FieldSelect = ({
|
|
|
4900
6030
|
...props
|
|
4901
6031
|
}) => {
|
|
4902
6032
|
const selectId = id ?? props.name;
|
|
4903
|
-
return /* @__PURE__ */ (0,
|
|
6033
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
4904
6034
|
Field,
|
|
4905
6035
|
{
|
|
4906
6036
|
label,
|
|
@@ -4908,8 +6038,8 @@ var FieldSelect = ({
|
|
|
4908
6038
|
error,
|
|
4909
6039
|
htmlFor: selectId,
|
|
4910
6040
|
className: fieldClassName,
|
|
4911
|
-
children: /* @__PURE__ */ (0,
|
|
4912
|
-
/* @__PURE__ */ (0,
|
|
6041
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: selectWrapClass, children: [
|
|
6042
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
4913
6043
|
"select",
|
|
4914
6044
|
{
|
|
4915
6045
|
id: selectId,
|
|
@@ -4919,7 +6049,7 @@ var FieldSelect = ({
|
|
|
4919
6049
|
children
|
|
4920
6050
|
}
|
|
4921
6051
|
),
|
|
4922
|
-
/* @__PURE__ */ (0,
|
|
6052
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
4923
6053
|
import_lucide_react10.ChevronDownIcon,
|
|
4924
6054
|
{
|
|
4925
6055
|
className: "pointer-events-none absolute top-1/2 right-3 size-4 -translate-y-1/2 text-muted-foreground",
|
|
@@ -4932,7 +6062,7 @@ var FieldSelect = ({
|
|
|
4932
6062
|
};
|
|
4933
6063
|
|
|
4934
6064
|
// src/app/forms/FieldSwitch.tsx
|
|
4935
|
-
var
|
|
6065
|
+
var import_jsx_runtime63 = require("react/jsx-runtime");
|
|
4936
6066
|
var trackClass = cn(
|
|
4937
6067
|
"relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-[background,box-shadow,border-color] duration-200",
|
|
4938
6068
|
"peer-focus-visible:ring-2 peer-focus-visible:ring-foreground/10",
|
|
@@ -4953,7 +6083,7 @@ var FieldSwitch = ({
|
|
|
4953
6083
|
...props
|
|
4954
6084
|
}) => {
|
|
4955
6085
|
const inputId = id ?? props.name ?? "switch";
|
|
4956
|
-
return /* @__PURE__ */ (0,
|
|
6086
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(
|
|
4957
6087
|
"label",
|
|
4958
6088
|
{
|
|
4959
6089
|
className: cn(
|
|
@@ -4962,8 +6092,8 @@ var FieldSwitch = ({
|
|
|
4962
6092
|
),
|
|
4963
6093
|
htmlFor: inputId,
|
|
4964
6094
|
children: [
|
|
4965
|
-
/* @__PURE__ */ (0,
|
|
4966
|
-
/* @__PURE__ */ (0,
|
|
6095
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("span", { className: "relative mt-0.5", children: [
|
|
6096
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
4967
6097
|
"input",
|
|
4968
6098
|
{
|
|
4969
6099
|
id: inputId,
|
|
@@ -4973,11 +6103,11 @@ var FieldSwitch = ({
|
|
|
4973
6103
|
...props
|
|
4974
6104
|
}
|
|
4975
6105
|
),
|
|
4976
|
-
/* @__PURE__ */ (0,
|
|
6106
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: trackClass, "aria-hidden": true, children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: thumbClass }) })
|
|
4977
6107
|
] }),
|
|
4978
|
-
/* @__PURE__ */ (0,
|
|
4979
|
-
/* @__PURE__ */ (0,
|
|
4980
|
-
description ? /* @__PURE__ */ (0,
|
|
6108
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("span", { className: "flex min-w-0 flex-col gap-0.5", children: [
|
|
6109
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "text-sm font-medium text-foreground", children: label }),
|
|
6110
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "text-xs text-muted-foreground", children: description }) : null
|
|
4981
6111
|
] })
|
|
4982
6112
|
]
|
|
4983
6113
|
}
|
|
@@ -4986,13 +6116,13 @@ var FieldSwitch = ({
|
|
|
4986
6116
|
|
|
4987
6117
|
// src/app/forms/SearchInput.tsx
|
|
4988
6118
|
var import_lucide_react11 = require("lucide-react");
|
|
4989
|
-
var
|
|
6119
|
+
var import_jsx_runtime64 = require("react/jsx-runtime");
|
|
4990
6120
|
var SearchInput = ({
|
|
4991
6121
|
className,
|
|
4992
6122
|
placeholder = "Search\u2026",
|
|
4993
6123
|
...props
|
|
4994
6124
|
}) => {
|
|
4995
|
-
return /* @__PURE__ */ (0,
|
|
6125
|
+
return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(
|
|
4996
6126
|
"label",
|
|
4997
6127
|
{
|
|
4998
6128
|
className: cn(
|
|
@@ -5001,8 +6131,8 @@ var SearchInput = ({
|
|
|
5001
6131
|
className
|
|
5002
6132
|
),
|
|
5003
6133
|
children: [
|
|
5004
|
-
/* @__PURE__ */ (0,
|
|
5005
|
-
/* @__PURE__ */ (0,
|
|
6134
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_lucide_react11.SearchIcon, { className: "size-4 shrink-0 text-muted-foreground", "aria-hidden": true }),
|
|
6135
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
|
|
5006
6136
|
"input",
|
|
5007
6137
|
{
|
|
5008
6138
|
type: "search",
|
|
@@ -5017,18 +6147,18 @@ var SearchInput = ({
|
|
|
5017
6147
|
};
|
|
5018
6148
|
|
|
5019
6149
|
// src/app/forms/FormSection.tsx
|
|
5020
|
-
var
|
|
6150
|
+
var import_jsx_runtime65 = require("react/jsx-runtime");
|
|
5021
6151
|
var FormSection = ({ title, children, className }) => {
|
|
5022
|
-
return /* @__PURE__ */ (0,
|
|
5023
|
-
title ? /* @__PURE__ */ (0,
|
|
5024
|
-
/* @__PURE__ */ (0,
|
|
6152
|
+
return /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("fieldset", { className: cn("aui-app-form-section", appSectionClass, "border-0 p-0", className), children: [
|
|
6153
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("legend", { className: cn(appSectionTitleClass, "mb-3 px-0"), children: title }) : null,
|
|
6154
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("div", { className: "flex flex-col gap-4", children })
|
|
5025
6155
|
] });
|
|
5026
6156
|
};
|
|
5027
6157
|
|
|
5028
6158
|
// src/app/data/FilterBar.tsx
|
|
5029
|
-
var
|
|
6159
|
+
var import_jsx_runtime66 = require("react/jsx-runtime");
|
|
5030
6160
|
var FilterBar = ({ children, className }) => {
|
|
5031
|
-
return /* @__PURE__ */ (0,
|
|
6161
|
+
return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
|
|
5032
6162
|
"div",
|
|
5033
6163
|
{
|
|
5034
6164
|
className: cn("aui-app-filter-bar", appFilterBarClass, className),
|
|
@@ -5040,9 +6170,9 @@ var FilterBar = ({ children, className }) => {
|
|
|
5040
6170
|
};
|
|
5041
6171
|
|
|
5042
6172
|
// src/app/data/DataTable.tsx
|
|
5043
|
-
var
|
|
6173
|
+
var import_react45 = require("react");
|
|
5044
6174
|
var import_lucide_react12 = require("lucide-react");
|
|
5045
|
-
var
|
|
6175
|
+
var import_jsx_runtime67 = require("react/jsx-runtime");
|
|
5046
6176
|
var shellClass2 = "overflow-hidden rounded-xl border border-border bg-card shadow-card";
|
|
5047
6177
|
var tableClass = "w-full border-collapse bg-transparent text-sm";
|
|
5048
6178
|
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";
|
|
@@ -5082,12 +6212,12 @@ function SortIndicator({
|
|
|
5082
6212
|
}) {
|
|
5083
6213
|
const iconClass = "size-3.5 shrink-0 opacity-60 group-hover:opacity-100";
|
|
5084
6214
|
if (!active) {
|
|
5085
|
-
return /* @__PURE__ */ (0,
|
|
6215
|
+
return /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(import_lucide_react12.ArrowUpDownIcon, { className: iconClass, "aria-hidden": true });
|
|
5086
6216
|
}
|
|
5087
6217
|
if (direction === "desc") {
|
|
5088
|
-
return /* @__PURE__ */ (0,
|
|
6218
|
+
return /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(import_lucide_react12.ArrowDownIcon, { className: iconClass, "aria-hidden": true });
|
|
5089
6219
|
}
|
|
5090
|
-
return /* @__PURE__ */ (0,
|
|
6220
|
+
return /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(import_lucide_react12.ArrowUpIcon, { className: iconClass, "aria-hidden": true });
|
|
5091
6221
|
}
|
|
5092
6222
|
function DataTable({
|
|
5093
6223
|
columns,
|
|
@@ -5108,7 +6238,7 @@ function DataTable({
|
|
|
5108
6238
|
dense = false,
|
|
5109
6239
|
caption
|
|
5110
6240
|
}) {
|
|
5111
|
-
const [uncontrolledSort, setUncontrolledSort] = (0,
|
|
6241
|
+
const [uncontrolledSort, setUncontrolledSort] = (0, import_react45.useState)(
|
|
5112
6242
|
defaultSort
|
|
5113
6243
|
);
|
|
5114
6244
|
const isSortControlled = sortProp !== void 0;
|
|
@@ -5119,7 +6249,7 @@ function DataTable({
|
|
|
5119
6249
|
}
|
|
5120
6250
|
onSortChange?.(next);
|
|
5121
6251
|
};
|
|
5122
|
-
const sortedRows = (0,
|
|
6252
|
+
const sortedRows = (0, import_react45.useMemo)(() => {
|
|
5123
6253
|
if (!sort) return rows;
|
|
5124
6254
|
const column = columns.find((col) => col.id === sort.columnId);
|
|
5125
6255
|
if (!column?.sortable) return rows;
|
|
@@ -5138,28 +6268,28 @@ function DataTable({
|
|
|
5138
6268
|
const cellPad = dense ? "px-3 py-2" : void 0;
|
|
5139
6269
|
const headPad = dense ? "px-3 py-2" : void 0;
|
|
5140
6270
|
if (rows.length === 0 && emptyMode === "replace") {
|
|
5141
|
-
return /* @__PURE__ */ (0,
|
|
6271
|
+
return /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(EmptyState, { title: emptyTitle, description: emptyDescription, className });
|
|
5142
6272
|
}
|
|
5143
6273
|
const rowCountText = rowCountLabel?.(sortedRows.length) ?? `${sortedRows.length} row${sortedRows.length === 1 ? "" : "s"}`;
|
|
5144
6274
|
const hasFoot = Boolean((showRowCount || footer) && sortedRows.length > 0);
|
|
5145
|
-
return /* @__PURE__ */ (0,
|
|
5146
|
-
caption ? /* @__PURE__ */ (0,
|
|
5147
|
-
/* @__PURE__ */ (0,
|
|
6275
|
+
return /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("div", { className: cn("aui-app-data-table", shellClass2, className), children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("div", { className: "overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("table", { className: tableClass, children: [
|
|
6276
|
+
caption ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("caption", { className: "sr-only", children: caption }) : null,
|
|
6277
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("thead", { className: cn(stickyHeader && stickyHeadClass), children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("tr", { children: columns.map((col) => {
|
|
5148
6278
|
const isSorted = sort?.columnId === col.id;
|
|
5149
6279
|
const ariaSort = col.sortable ? isSorted ? sort.direction === "asc" ? "ascending" : "descending" : "none" : void 0;
|
|
5150
|
-
const headerContent = col.sortable ? /* @__PURE__ */ (0,
|
|
6280
|
+
const headerContent = col.sortable ? /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(
|
|
5151
6281
|
"button",
|
|
5152
6282
|
{
|
|
5153
6283
|
type: "button",
|
|
5154
6284
|
className: sortButtonClass,
|
|
5155
6285
|
onClick: () => setSort(nextSort(sort, col.id)),
|
|
5156
6286
|
children: [
|
|
5157
|
-
/* @__PURE__ */ (0,
|
|
5158
|
-
/* @__PURE__ */ (0,
|
|
6287
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { className: "truncate", children: col.header }),
|
|
6288
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)(SortIndicator, { active: Boolean(isSorted), direction: sort?.direction })
|
|
5159
6289
|
]
|
|
5160
6290
|
}
|
|
5161
6291
|
) : col.header;
|
|
5162
|
-
return /* @__PURE__ */ (0,
|
|
6292
|
+
return /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
5163
6293
|
"th",
|
|
5164
6294
|
{
|
|
5165
6295
|
scope: "col",
|
|
@@ -5175,10 +6305,10 @@ function DataTable({
|
|
|
5175
6305
|
col.id
|
|
5176
6306
|
);
|
|
5177
6307
|
}) }) }),
|
|
5178
|
-
/* @__PURE__ */ (0,
|
|
5179
|
-
/* @__PURE__ */ (0,
|
|
5180
|
-
emptyDescription ? /* @__PURE__ */ (0,
|
|
5181
|
-
] }) }) }) : sortedRows.map((row) => /* @__PURE__ */ (0,
|
|
6308
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("tbody", { className: cn(!hasFoot && "[&_tr:last-child_td]:border-b-0"), children: sortedRows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("td", { colSpan: columns.length, className: emptyCellClass, children: /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { className: "flex flex-col items-center gap-1", children: [
|
|
6309
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("p", { className: "font-medium text-foreground", children: emptyTitle }),
|
|
6310
|
+
emptyDescription ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("p", { className: "max-w-sm text-muted-foreground", children: emptyDescription }) : null
|
|
6311
|
+
] }) }) }) : sortedRows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
5182
6312
|
"tr",
|
|
5183
6313
|
{
|
|
5184
6314
|
className: rowClass,
|
|
@@ -5192,7 +6322,7 @@ function DataTable({
|
|
|
5192
6322
|
} : void 0,
|
|
5193
6323
|
tabIndex: onRowClick ? 0 : void 0,
|
|
5194
6324
|
role: onRowClick ? "button" : void 0,
|
|
5195
|
-
children: columns.map((col) => /* @__PURE__ */ (0,
|
|
6325
|
+
children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
5196
6326
|
"td",
|
|
5197
6327
|
{
|
|
5198
6328
|
className: cn(
|
|
@@ -5208,7 +6338,7 @@ function DataTable({
|
|
|
5208
6338
|
},
|
|
5209
6339
|
getRowKey(row)
|
|
5210
6340
|
)) }),
|
|
5211
|
-
hasFoot ? /* @__PURE__ */ (0,
|
|
6341
|
+
hasFoot ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("tfoot", { children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("td", { colSpan: columns.length, className: footCellClass, children: /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(
|
|
5212
6342
|
"div",
|
|
5213
6343
|
{
|
|
5214
6344
|
className: cn(
|
|
@@ -5216,7 +6346,7 @@ function DataTable({
|
|
|
5216
6346
|
showRowCount && footer ? "justify-between" : "justify-start"
|
|
5217
6347
|
),
|
|
5218
6348
|
children: [
|
|
5219
|
-
showRowCount ? /* @__PURE__ */ (0,
|
|
6349
|
+
showRowCount ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { children: rowCountText }) : null,
|
|
5220
6350
|
footer
|
|
5221
6351
|
]
|
|
5222
6352
|
}
|
|
@@ -5225,27 +6355,415 @@ function DataTable({
|
|
|
5225
6355
|
}
|
|
5226
6356
|
|
|
5227
6357
|
// src/app/data/ChartPanel.tsx
|
|
5228
|
-
var
|
|
5229
|
-
|
|
6358
|
+
var import_react46 = require("react");
|
|
6359
|
+
|
|
6360
|
+
// src/app/data/metrics-shared.tsx
|
|
6361
|
+
var import_jsx_runtime68 = require("react/jsx-runtime");
|
|
6362
|
+
var metricCardShellClass = cn(
|
|
6363
|
+
studioIntegrationCardClass,
|
|
6364
|
+
"aui-app-metric-card shadow-none",
|
|
6365
|
+
"flex flex-col overflow-hidden"
|
|
6366
|
+
);
|
|
6367
|
+
var metricCardHeaderClass = "flex items-start justify-between gap-3 px-4 pb-1 pt-3";
|
|
6368
|
+
var metricTilesRowClass = "grid w-full min-w-0";
|
|
6369
|
+
var metricChartRegionClass = "relative min-h-0 w-full border-t border-border/40 pt-2";
|
|
6370
|
+
var metricChartPlotRegionClass = "relative min-h-0 w-full border-t border-border/40 px-0 pt-5 pb-3";
|
|
6371
|
+
var metricCellDividerClass = "border-r border-border/40";
|
|
6372
|
+
var MetricCardHeader = ({
|
|
6373
|
+
title,
|
|
6374
|
+
titleId,
|
|
6375
|
+
description,
|
|
6376
|
+
actions
|
|
6377
|
+
}) => {
|
|
6378
|
+
if (!title && !description && !actions) return null;
|
|
6379
|
+
return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("header", { className: metricCardHeaderClass, children: [
|
|
6380
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "min-w-0", children: [
|
|
6381
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("h3", { id: titleId, className: "text-base font-normal text-foreground", children: title }) : null,
|
|
6382
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
|
|
6383
|
+
] }),
|
|
6384
|
+
actions ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "shrink-0", children: actions }) : null
|
|
6385
|
+
] });
|
|
6386
|
+
};
|
|
6387
|
+
function metricTilesGridColsClass(n) {
|
|
6388
|
+
switch (n) {
|
|
6389
|
+
case 1:
|
|
6390
|
+
return "grid-cols-1";
|
|
6391
|
+
case 2:
|
|
6392
|
+
return "grid-cols-2";
|
|
6393
|
+
case 3:
|
|
6394
|
+
return "grid-cols-3";
|
|
6395
|
+
case 5:
|
|
6396
|
+
return "grid-cols-2 sm:grid-cols-5";
|
|
6397
|
+
case 6:
|
|
6398
|
+
return "grid-cols-2 sm:grid-cols-3 lg:grid-cols-6";
|
|
6399
|
+
default:
|
|
6400
|
+
return "grid-cols-2 md:grid-cols-4";
|
|
6401
|
+
}
|
|
6402
|
+
}
|
|
6403
|
+
|
|
6404
|
+
// src/app/data/ChartPanel.tsx
|
|
6405
|
+
var import_jsx_runtime69 = require("react/jsx-runtime");
|
|
5230
6406
|
var ChartPanel = ({
|
|
5231
6407
|
title,
|
|
6408
|
+
description,
|
|
5232
6409
|
artifact,
|
|
5233
6410
|
children,
|
|
5234
6411
|
actions,
|
|
6412
|
+
height = 300,
|
|
5235
6413
|
className
|
|
5236
6414
|
}) => {
|
|
5237
|
-
const
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
|
|
6415
|
+
const titleId = (0, import_react46.useId)();
|
|
6416
|
+
const resolvedTitle = title ?? artifact?.title;
|
|
6417
|
+
const hasHeader = Boolean(resolvedTitle || description || actions);
|
|
6418
|
+
const body = children ?? (artifact ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ChartArtifactView, { artifact, embedded: true, height }) : null);
|
|
6419
|
+
return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
|
|
6420
|
+
"section",
|
|
6421
|
+
{
|
|
6422
|
+
className: cn(metricCardShellClass, "aui-app-chart-panel", className),
|
|
6423
|
+
"aria-labelledby": resolvedTitle ? titleId : void 0,
|
|
6424
|
+
children: [
|
|
6425
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
6426
|
+
MetricCardHeader,
|
|
6427
|
+
{
|
|
6428
|
+
title: resolvedTitle,
|
|
6429
|
+
titleId,
|
|
6430
|
+
description,
|
|
6431
|
+
actions
|
|
6432
|
+
}
|
|
6433
|
+
),
|
|
6434
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
6435
|
+
"div",
|
|
6436
|
+
{
|
|
6437
|
+
className: cn(
|
|
6438
|
+
"relative min-h-0 w-full",
|
|
6439
|
+
hasHeader ? metricChartPlotRegionClass : "pt-2 pb-3"
|
|
6440
|
+
),
|
|
6441
|
+
children: body ?? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
6442
|
+
"div",
|
|
6443
|
+
{
|
|
6444
|
+
className: "flex items-center justify-center text-sm font-normal text-muted-foreground",
|
|
6445
|
+
style: { minHeight: height },
|
|
6446
|
+
role: "status",
|
|
6447
|
+
children: "No chart"
|
|
6448
|
+
}
|
|
6449
|
+
)
|
|
6450
|
+
}
|
|
6451
|
+
)
|
|
6452
|
+
]
|
|
6453
|
+
}
|
|
6454
|
+
);
|
|
6455
|
+
};
|
|
6456
|
+
|
|
6457
|
+
// src/app/data/MetricTile.tsx
|
|
6458
|
+
var import_jsx_runtime70 = require("react/jsx-runtime");
|
|
6459
|
+
var trendToneClass = {
|
|
6460
|
+
up: "border-border/80 bg-muted/40 text-muted-foreground",
|
|
6461
|
+
down: "border-border/80 bg-muted/40 text-muted-foreground",
|
|
6462
|
+
neutral: "border-border/80 bg-muted/30 text-muted-foreground"
|
|
6463
|
+
};
|
|
6464
|
+
var metricTileBaseClass = "relative flex min-w-0 flex-1 flex-col gap-1 px-4 py-3 text-left font-normal";
|
|
6465
|
+
var metricTileInteractiveClass = cn(
|
|
6466
|
+
metricTileBaseClass,
|
|
6467
|
+
"bg-transparent hover:bg-transparent active:bg-transparent",
|
|
6468
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-foreground/10"
|
|
6469
|
+
);
|
|
6470
|
+
var MetricTile = ({
|
|
6471
|
+
label,
|
|
6472
|
+
value,
|
|
6473
|
+
unit,
|
|
6474
|
+
trend,
|
|
6475
|
+
trendTone = "neutral",
|
|
6476
|
+
active = false,
|
|
6477
|
+
showDivider = false,
|
|
6478
|
+
onSelect,
|
|
6479
|
+
ariaLabel,
|
|
6480
|
+
className
|
|
6481
|
+
}) => {
|
|
6482
|
+
const content = /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(import_jsx_runtime70.Fragment, { children: [
|
|
6483
|
+
active ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
6484
|
+
"span",
|
|
6485
|
+
{
|
|
6486
|
+
"aria-hidden": true,
|
|
6487
|
+
className: "absolute inset-x-0 bottom-0 h-0.5 bg-foreground dark:bg-white"
|
|
6488
|
+
}
|
|
6489
|
+
) : null,
|
|
6490
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)("span", { className: "text-xs font-normal text-muted-foreground", children: label }),
|
|
6491
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("span", { className: "flex items-center gap-2", children: [
|
|
6492
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("span", { className: "flex items-baseline gap-1", children: [
|
|
6493
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)("span", { className: "text-2xl font-normal tracking-tight text-foreground tabular-nums", children: value }),
|
|
6494
|
+
unit ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("span", { className: "text-xs font-normal text-muted-foreground", children: unit }) : null
|
|
6495
|
+
] }),
|
|
6496
|
+
trend ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
6497
|
+
"span",
|
|
6498
|
+
{
|
|
6499
|
+
className: cn(
|
|
6500
|
+
"rounded-full border px-1.5 py-0.5 text-xs font-normal",
|
|
6501
|
+
trendToneClass[trendTone]
|
|
6502
|
+
),
|
|
6503
|
+
children: trend
|
|
6504
|
+
}
|
|
6505
|
+
) : null
|
|
6506
|
+
] })
|
|
5244
6507
|
] });
|
|
6508
|
+
const divider = showDivider ? metricCellDividerClass : void 0;
|
|
6509
|
+
if (onSelect) {
|
|
6510
|
+
return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
6511
|
+
"button",
|
|
6512
|
+
{
|
|
6513
|
+
type: "button",
|
|
6514
|
+
onClick: onSelect,
|
|
6515
|
+
"aria-pressed": active,
|
|
6516
|
+
"aria-label": ariaLabel,
|
|
6517
|
+
className: cn(metricTileInteractiveClass, divider, className),
|
|
6518
|
+
children: content
|
|
6519
|
+
}
|
|
6520
|
+
);
|
|
6521
|
+
}
|
|
6522
|
+
return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { className: cn(metricTileBaseClass, divider, className), children: content });
|
|
6523
|
+
};
|
|
6524
|
+
|
|
6525
|
+
// src/app/data/MetricRow.tsx
|
|
6526
|
+
var import_react47 = require("react");
|
|
6527
|
+
var import_jsx_runtime71 = require("react/jsx-runtime");
|
|
6528
|
+
var MetricRow = ({
|
|
6529
|
+
title,
|
|
6530
|
+
description,
|
|
6531
|
+
actions,
|
|
6532
|
+
metrics,
|
|
6533
|
+
activeMetricId,
|
|
6534
|
+
defaultActiveMetricId,
|
|
6535
|
+
onMetricChange,
|
|
6536
|
+
metricsAriaLabel = "Metrics",
|
|
6537
|
+
className
|
|
6538
|
+
}) => {
|
|
6539
|
+
const titleId = (0, import_react47.useId)();
|
|
6540
|
+
const selectable = onMetricChange != null || activeMetricId != null;
|
|
6541
|
+
const [internalId, setInternalId] = (0, import_react47.useState)(
|
|
6542
|
+
defaultActiveMetricId ?? metrics[0]?.id
|
|
6543
|
+
);
|
|
6544
|
+
const activeId = activeMetricId ?? internalId;
|
|
6545
|
+
const select = (id) => {
|
|
6546
|
+
if (activeMetricId == null) setInternalId(id);
|
|
6547
|
+
onMetricChange?.(id);
|
|
6548
|
+
};
|
|
6549
|
+
return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(
|
|
6550
|
+
"section",
|
|
6551
|
+
{
|
|
6552
|
+
className: cn(metricCardShellClass, className),
|
|
6553
|
+
"aria-labelledby": title ? titleId : void 0,
|
|
6554
|
+
children: [
|
|
6555
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
6556
|
+
MetricCardHeader,
|
|
6557
|
+
{
|
|
6558
|
+
title,
|
|
6559
|
+
titleId,
|
|
6560
|
+
description,
|
|
6561
|
+
actions
|
|
6562
|
+
}
|
|
6563
|
+
),
|
|
6564
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
6565
|
+
"div",
|
|
6566
|
+
{
|
|
6567
|
+
role: selectable ? "group" : void 0,
|
|
6568
|
+
"aria-label": selectable ? metricsAriaLabel : void 0,
|
|
6569
|
+
className: cn(
|
|
6570
|
+
metricTilesRowClass,
|
|
6571
|
+
metricTilesGridColsClass(metrics.length),
|
|
6572
|
+
(title || description || actions) && "mt-3"
|
|
6573
|
+
),
|
|
6574
|
+
children: metrics.map((m, index) => /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
6575
|
+
MetricTile,
|
|
6576
|
+
{
|
|
6577
|
+
label: m.label,
|
|
6578
|
+
value: m.value,
|
|
6579
|
+
unit: m.unit,
|
|
6580
|
+
trend: m.trend,
|
|
6581
|
+
trendTone: m.trendTone,
|
|
6582
|
+
active: selectable && m.id === activeId,
|
|
6583
|
+
showDivider: index < metrics.length - 1,
|
|
6584
|
+
onSelect: selectable ? () => select(m.id) : void 0
|
|
6585
|
+
},
|
|
6586
|
+
m.id
|
|
6587
|
+
))
|
|
6588
|
+
}
|
|
6589
|
+
)
|
|
6590
|
+
]
|
|
6591
|
+
}
|
|
6592
|
+
);
|
|
6593
|
+
};
|
|
6594
|
+
|
|
6595
|
+
// src/app/data/MetricChartCard.tsx
|
|
6596
|
+
var import_react48 = require("react");
|
|
6597
|
+
var import_jsx_runtime72 = require("react/jsx-runtime");
|
|
6598
|
+
var MetricChartCard = ({
|
|
6599
|
+
title,
|
|
6600
|
+
description,
|
|
6601
|
+
actions,
|
|
6602
|
+
metrics,
|
|
6603
|
+
activeMetricId,
|
|
6604
|
+
defaultActiveMetricId,
|
|
6605
|
+
onMetricChange,
|
|
6606
|
+
xKey = "date",
|
|
6607
|
+
variant = "area",
|
|
6608
|
+
height = 300,
|
|
6609
|
+
formatX,
|
|
6610
|
+
formatValue,
|
|
6611
|
+
emptyLabel = "No data yet",
|
|
6612
|
+
metricsAriaLabel = "Metrics",
|
|
6613
|
+
className
|
|
6614
|
+
}) => {
|
|
6615
|
+
const titleId = (0, import_react48.useId)();
|
|
6616
|
+
const [internalId, setInternalId] = (0, import_react48.useState)(
|
|
6617
|
+
defaultActiveMetricId ?? metrics[0]?.id
|
|
6618
|
+
);
|
|
6619
|
+
const activeId = activeMetricId ?? internalId;
|
|
6620
|
+
const active = metrics.find((m) => m.id === activeId) ?? metrics[0];
|
|
6621
|
+
const select = (id) => {
|
|
6622
|
+
if (activeMetricId == null) setInternalId(id);
|
|
6623
|
+
onMetricChange?.(id);
|
|
6624
|
+
};
|
|
6625
|
+
const hasHeader = Boolean(title || description || actions);
|
|
6626
|
+
const chartAriaLabel = typeof active?.label === "string" ? `${active.label} over time` : "Metric chart";
|
|
6627
|
+
return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(
|
|
6628
|
+
"section",
|
|
6629
|
+
{
|
|
6630
|
+
className: cn(metricCardShellClass, className),
|
|
6631
|
+
"aria-labelledby": title ? titleId : void 0,
|
|
6632
|
+
children: [
|
|
6633
|
+
/* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
6634
|
+
MetricCardHeader,
|
|
6635
|
+
{
|
|
6636
|
+
title,
|
|
6637
|
+
titleId,
|
|
6638
|
+
description,
|
|
6639
|
+
actions
|
|
6640
|
+
}
|
|
6641
|
+
),
|
|
6642
|
+
/* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
6643
|
+
"div",
|
|
6644
|
+
{
|
|
6645
|
+
role: "group",
|
|
6646
|
+
"aria-label": metricsAriaLabel,
|
|
6647
|
+
className: cn(
|
|
6648
|
+
metricTilesRowClass,
|
|
6649
|
+
metricTilesGridColsClass(metrics.length),
|
|
6650
|
+
hasHeader && "mt-3"
|
|
6651
|
+
),
|
|
6652
|
+
children: metrics.map((m, index) => /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
6653
|
+
MetricTile,
|
|
6654
|
+
{
|
|
6655
|
+
label: m.label,
|
|
6656
|
+
value: m.value,
|
|
6657
|
+
unit: m.unit,
|
|
6658
|
+
trend: m.trend,
|
|
6659
|
+
trendTone: m.trendTone,
|
|
6660
|
+
active: m.id === active?.id,
|
|
6661
|
+
showDivider: index < metrics.length - 1,
|
|
6662
|
+
onSelect: () => select(m.id)
|
|
6663
|
+
},
|
|
6664
|
+
m.id
|
|
6665
|
+
))
|
|
6666
|
+
}
|
|
6667
|
+
),
|
|
6668
|
+
/* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: metricChartRegionClass, "aria-live": "polite", "aria-atomic": "true", children: active?.data && active.data.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
6669
|
+
LineAreaChart,
|
|
6670
|
+
{
|
|
6671
|
+
data: active.data,
|
|
6672
|
+
xKey,
|
|
6673
|
+
series: [
|
|
6674
|
+
{
|
|
6675
|
+
dataKey: active.dataKey ?? "value",
|
|
6676
|
+
label: typeof active.label === "string" ? active.label : active.id,
|
|
6677
|
+
color: active.color
|
|
6678
|
+
}
|
|
6679
|
+
],
|
|
6680
|
+
variant,
|
|
6681
|
+
layout: "flush",
|
|
6682
|
+
height,
|
|
6683
|
+
formatX,
|
|
6684
|
+
formatValue,
|
|
6685
|
+
ariaLabel: chartAriaLabel
|
|
6686
|
+
},
|
|
6687
|
+
active.id
|
|
6688
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
6689
|
+
"div",
|
|
6690
|
+
{
|
|
6691
|
+
className: "flex w-full items-center justify-center text-sm font-normal text-muted-foreground",
|
|
6692
|
+
style: { height },
|
|
6693
|
+
role: "status",
|
|
6694
|
+
children: emptyLabel
|
|
6695
|
+
}
|
|
6696
|
+
) })
|
|
6697
|
+
]
|
|
6698
|
+
}
|
|
6699
|
+
);
|
|
6700
|
+
};
|
|
6701
|
+
|
|
6702
|
+
// src/charts/sparkline.tsx
|
|
6703
|
+
var import_react49 = require("react");
|
|
6704
|
+
var import_jsx_runtime73 = require("react/jsx-runtime");
|
|
6705
|
+
var Sparkline = ({
|
|
6706
|
+
data,
|
|
6707
|
+
dataKey = "value",
|
|
6708
|
+
color = "var(--primary, #6366f1)",
|
|
6709
|
+
area = true,
|
|
6710
|
+
width = 96,
|
|
6711
|
+
height = 28,
|
|
6712
|
+
strokeWidth = 1.5,
|
|
6713
|
+
className,
|
|
6714
|
+
ariaLabel = "Trend"
|
|
6715
|
+
}) => {
|
|
6716
|
+
const uid = (0, import_react49.useId)();
|
|
6717
|
+
const values = data.map((d) => typeof d === "number" ? d : toNum(d[dataKey]));
|
|
6718
|
+
if (values.length === 0) {
|
|
6719
|
+
return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: cn("inline-block", className), style: { width, height } });
|
|
6720
|
+
}
|
|
6721
|
+
const pad = strokeWidth + 1;
|
|
6722
|
+
const min = Math.min(...values);
|
|
6723
|
+
const max = Math.max(...values);
|
|
6724
|
+
const range = max - min || 1;
|
|
6725
|
+
const innerW = width - pad * 2;
|
|
6726
|
+
const innerH = height - pad * 2;
|
|
6727
|
+
const points = values.map((v, i) => ({
|
|
6728
|
+
x: pad + (values.length > 1 ? i / (values.length - 1) * innerW : innerW / 2),
|
|
6729
|
+
y: pad + innerH - (v - min) / range * innerH
|
|
6730
|
+
}));
|
|
6731
|
+
return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
|
|
6732
|
+
"svg",
|
|
6733
|
+
{
|
|
6734
|
+
width,
|
|
6735
|
+
height,
|
|
6736
|
+
viewBox: `0 0 ${width} ${height}`,
|
|
6737
|
+
className: cn("block", className),
|
|
6738
|
+
role: "img",
|
|
6739
|
+
"aria-label": ariaLabel,
|
|
6740
|
+
preserveAspectRatio: "none",
|
|
6741
|
+
children: [
|
|
6742
|
+
area && /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(import_jsx_runtime73.Fragment, { children: [
|
|
6743
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("linearGradient", { id: `${uid}-spark`, x1: "0", x2: "0", y1: "0", y2: "1", children: [
|
|
6744
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)("stop", { offset: "0%", style: { stopColor: color, stopOpacity: 0.25 } }),
|
|
6745
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)("stop", { offset: "100%", style: { stopColor: color, stopOpacity: 0 } })
|
|
6746
|
+
] }) }),
|
|
6747
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)("path", { d: monotoneAreaPath(points, height - pad), fill: `url(#${uid}-spark)` })
|
|
6748
|
+
] }),
|
|
6749
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
6750
|
+
"path",
|
|
6751
|
+
{
|
|
6752
|
+
d: monotoneLinePath(points),
|
|
6753
|
+
fill: "none",
|
|
6754
|
+
stroke: color,
|
|
6755
|
+
strokeWidth,
|
|
6756
|
+
strokeLinecap: "round",
|
|
6757
|
+
strokeLinejoin: "round"
|
|
6758
|
+
}
|
|
6759
|
+
)
|
|
6760
|
+
]
|
|
6761
|
+
}
|
|
6762
|
+
);
|
|
5245
6763
|
};
|
|
5246
6764
|
|
|
5247
6765
|
// src/chat/chat.tsx
|
|
5248
|
-
var
|
|
6766
|
+
var import_jsx_runtime74 = require("react/jsx-runtime");
|
|
5249
6767
|
function TimbalChat({
|
|
5250
6768
|
workforceId,
|
|
5251
6769
|
baseUrl,
|
|
@@ -5256,7 +6774,7 @@ function TimbalChat({
|
|
|
5256
6774
|
debug,
|
|
5257
6775
|
...threadProps
|
|
5258
6776
|
}) {
|
|
5259
|
-
return /* @__PURE__ */ (0,
|
|
6777
|
+
return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
5260
6778
|
TimbalRuntimeProvider,
|
|
5261
6779
|
{
|
|
5262
6780
|
workforceId,
|
|
@@ -5266,12 +6784,13 @@ function TimbalChat({
|
|
|
5266
6784
|
attachmentsUploadUrl,
|
|
5267
6785
|
attachmentsAccept,
|
|
5268
6786
|
debug,
|
|
5269
|
-
children: /* @__PURE__ */ (0,
|
|
6787
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(Thread, { ...threadProps })
|
|
5270
6788
|
}
|
|
5271
6789
|
);
|
|
5272
6790
|
}
|
|
5273
6791
|
// Annotate the CommonJS export names for ESM import in node:
|
|
5274
6792
|
0 && (module.exports = {
|
|
6793
|
+
APP_KIT_AGENT_INSTRUCTIONS,
|
|
5275
6794
|
AppChatPanel,
|
|
5276
6795
|
AppConfirmDialog,
|
|
5277
6796
|
AppCopilotProvider,
|
|
@@ -5279,23 +6798,47 @@ function TimbalChat({
|
|
|
5279
6798
|
AppShellChatTrigger,
|
|
5280
6799
|
AppShellTopbar,
|
|
5281
6800
|
Breadcrumbs,
|
|
6801
|
+
Button,
|
|
6802
|
+
CHART_PALETTE,
|
|
5282
6803
|
ChartArtifactView,
|
|
5283
6804
|
ChartPanel,
|
|
6805
|
+
ConnectionRow,
|
|
6806
|
+
ConnectionRowList,
|
|
6807
|
+
DangerZone,
|
|
6808
|
+
DangerZoneAction,
|
|
5284
6809
|
DataTable,
|
|
6810
|
+
DescriptionList,
|
|
5285
6811
|
EmptyState,
|
|
6812
|
+
ExpandableSection,
|
|
5286
6813
|
Field,
|
|
5287
6814
|
FieldInput,
|
|
6815
|
+
FieldRow,
|
|
5288
6816
|
FieldSelect,
|
|
5289
6817
|
FieldSwitch,
|
|
5290
6818
|
FieldTextarea,
|
|
5291
6819
|
FilterBar,
|
|
6820
|
+
FloatingUnsavedChangesBar,
|
|
5292
6821
|
FormSection,
|
|
6822
|
+
INTEGRATION_CATALOG_CARD_HEIGHT_CLASS,
|
|
6823
|
+
InfoCard,
|
|
6824
|
+
IntegrationCard,
|
|
6825
|
+
IntegrationsEmptyState,
|
|
6826
|
+
LineAreaChart,
|
|
6827
|
+
MetricChartCard,
|
|
6828
|
+
MetricRow,
|
|
6829
|
+
MetricTile,
|
|
5293
6830
|
Page,
|
|
5294
6831
|
PageHeader,
|
|
6832
|
+
PlanBadge,
|
|
6833
|
+
ResourceCard,
|
|
5295
6834
|
SearchInput,
|
|
5296
6835
|
Section,
|
|
6836
|
+
SettingsSection,
|
|
6837
|
+
SettingsSectionHeader,
|
|
6838
|
+
Sparkline,
|
|
5297
6839
|
StatTile,
|
|
5298
6840
|
StatusBadge,
|
|
6841
|
+
StatusDot,
|
|
5299
6842
|
SubNav,
|
|
5300
6843
|
SurfaceCard,
|
|
5301
6844
|
TimbalChat,
|
|
@@ -5306,6 +6849,7 @@ function TimbalChat({
|
|
|
5306
6849
|
appShellTopbarInsetClass,
|
|
5307
6850
|
appStatTileClass,
|
|
5308
6851
|
appSurfaceCardClass,
|
|
6852
|
+
connectionRowListClass,
|
|
5309
6853
|
useAppCopilotContext,
|
|
5310
6854
|
useAppShellChat
|
|
5311
6855
|
});
|