@timbal-ai/timbal-react 0.6.1 → 0.7.1
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 +55 -0
- package/README.md +35 -5
- package/dist/app.cjs +2291 -741
- package/dist/app.d.cts +5 -2
- package/dist/app.d.ts +5 -2
- 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-C2m891nx.d.cts +756 -0
- package/dist/chart-artifact-CqqhdSR9.d.ts +756 -0
- package/dist/{chat-CWtQWDtJ.d.cts → chat-Bed4FQSl.d.cts} +10 -0
- package/dist/{chat-CWtQWDtJ.d.ts → chat-Bed4FQSl.d.ts} +10 -0
- package/dist/chat.cjs +876 -562
- package/dist/chat.d.cts +3 -3
- package/dist/chat.d.ts +3 -3
- package/dist/chat.esm.js +3 -3
- package/dist/{chunk-4TCJQSIX.esm.js → chunk-2XZ3S4OP.esm.js} +14 -3
- package/dist/{chunk-WLTW56MC.esm.js → chunk-3WCG6ZRL.esm.js} +2 -2
- package/dist/chunk-7U2N6XZA.esm.js +2296 -0
- package/dist/{chunk-OVHR7J3J.esm.js → chunk-EQC5JEDZ.esm.js} +38 -11
- package/dist/{chunk-YJQLLFKP.esm.js → chunk-RY3LB3JN.esm.js} +817 -507
- package/dist/{chunk-IYENDIRY.esm.js → chunk-TDIJHV4I.esm.js} +1 -1
- package/dist/{chunk-OFHLFNJH.esm.js → chunk-Z27GBSOT.esm.js} +3 -1
- package/dist/index.cjs +2596 -1019
- package/dist/index.d.cts +8 -7
- package/dist/index.d.ts +8 -7
- 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 +1131 -788
- package/dist/studio.d.cts +2 -2
- package/dist/studio.d.ts +2 -2
- package/dist/studio.esm.js +6 -6
- package/dist/styles.css +8 -4
- 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--80i_O0p.d.cts → welcome-COOb05a5.d.cts} +5 -4
- package/dist/{welcome-BOizSp5h.d.ts → welcome-DE08m9ca.d.ts} +5 -4
- 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,21 +4604,22 @@ 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",
|
|
4099
4619
|
maxWidth: maxWidthProp,
|
|
4100
4620
|
welcome,
|
|
4101
4621
|
suggestions,
|
|
4622
|
+
showWelcomeSuggestions,
|
|
4102
4623
|
composerPlaceholder,
|
|
4103
4624
|
components,
|
|
4104
4625
|
artifacts,
|
|
@@ -4114,17 +4635,17 @@ var Thread = ({
|
|
|
4114
4635
|
const EditComposerSlot = components?.EditComposer ?? EditComposer;
|
|
4115
4636
|
const ScrollToBottomSlot = components?.ScrollToBottom ?? ThreadScrollToBottom;
|
|
4116
4637
|
const SuggestionsSlot = components?.Suggestions ?? Suggestions;
|
|
4117
|
-
(0,
|
|
4638
|
+
(0, import_react34.useEffect)(() => {
|
|
4118
4639
|
scheduleThemeSanityCheck();
|
|
4119
4640
|
}, []);
|
|
4120
|
-
return /* @__PURE__ */ (0,
|
|
4641
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ThreadVariantProvider, { value: variant, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4121
4642
|
ArtifactRegistryProvider,
|
|
4122
4643
|
{
|
|
4123
4644
|
renderers: artifacts?.renderers,
|
|
4124
4645
|
override: artifacts?.override,
|
|
4125
|
-
children: /* @__PURE__ */ (0,
|
|
4126
|
-
}), children: /* @__PURE__ */ (0,
|
|
4127
|
-
|
|
4646
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(UiEventProvider, { onEvent: onArtifactEvent ?? (() => {
|
|
4647
|
+
}), children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4648
|
+
import_react35.ThreadPrimitive.Root,
|
|
4128
4649
|
{
|
|
4129
4650
|
className: cn(
|
|
4130
4651
|
"aui-root aui-thread-root @container flex h-full flex-col bg-transparent",
|
|
@@ -4133,8 +4654,8 @@ var Thread = ({
|
|
|
4133
4654
|
),
|
|
4134
4655
|
style: { ["--thread-max-width"]: maxWidth },
|
|
4135
4656
|
"data-thread-variant": variant,
|
|
4136
|
-
children: /* @__PURE__ */ (0,
|
|
4137
|
-
|
|
4657
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
4658
|
+
import_react35.ThreadPrimitive.Viewport,
|
|
4138
4659
|
{
|
|
4139
4660
|
turnAnchor: "bottom",
|
|
4140
4661
|
className: cn(
|
|
@@ -4142,16 +4663,17 @@ var Thread = ({
|
|
|
4142
4663
|
isPanel ? "px-2 pt-2" : "px-4 pt-4"
|
|
4143
4664
|
),
|
|
4144
4665
|
children: [
|
|
4145
|
-
/* @__PURE__ */ (0,
|
|
4666
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4146
4667
|
WelcomeSlot,
|
|
4147
4668
|
{
|
|
4148
4669
|
config: welcome,
|
|
4149
4670
|
suggestions,
|
|
4671
|
+
showWelcomeSuggestions,
|
|
4150
4672
|
Suggestions: SuggestionsSlot
|
|
4151
4673
|
}
|
|
4152
4674
|
),
|
|
4153
|
-
/* @__PURE__ */ (0,
|
|
4154
|
-
|
|
4675
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4676
|
+
import_react35.ThreadPrimitive.Messages,
|
|
4155
4677
|
{
|
|
4156
4678
|
components: {
|
|
4157
4679
|
UserMessage: UserMessageSlot,
|
|
@@ -4160,14 +4682,14 @@ var Thread = ({
|
|
|
4160
4682
|
}
|
|
4161
4683
|
}
|
|
4162
4684
|
),
|
|
4163
|
-
/* @__PURE__ */ (0,
|
|
4164
|
-
|
|
4685
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4686
|
+
import_react35.ThreadPrimitive.ViewportFooter,
|
|
4165
4687
|
{
|
|
4166
4688
|
className: cn(
|
|
4167
4689
|
"aui-thread-viewport-footer sticky bottom-0 z-10 mt-auto w-full isolate pt-2",
|
|
4168
4690
|
isPanel ? "bg-card pb-2" : "bg-background pb-4 md:pb-6"
|
|
4169
4691
|
),
|
|
4170
|
-
children: /* @__PURE__ */ (0,
|
|
4692
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
4171
4693
|
"div",
|
|
4172
4694
|
{
|
|
4173
4695
|
className: cn(
|
|
@@ -4175,8 +4697,8 @@ var Thread = ({
|
|
|
4175
4697
|
isPanel ? "gap-2" : "gap-4"
|
|
4176
4698
|
),
|
|
4177
4699
|
children: [
|
|
4178
|
-
/* @__PURE__ */ (0,
|
|
4179
|
-
/* @__PURE__ */ (0,
|
|
4700
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ScrollToBottomSlot, {}),
|
|
4701
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ComposerSlot, { placeholder })
|
|
4180
4702
|
]
|
|
4181
4703
|
}
|
|
4182
4704
|
)
|
|
@@ -4191,13 +4713,13 @@ var Thread = ({
|
|
|
4191
4713
|
) });
|
|
4192
4714
|
};
|
|
4193
4715
|
var ThreadScrollToBottom = () => {
|
|
4194
|
-
return /* @__PURE__ */ (0,
|
|
4716
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react35.ThreadPrimitive.ScrollToBottom, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4195
4717
|
TooltipIconButton,
|
|
4196
4718
|
{
|
|
4197
4719
|
tooltip: "Scroll to bottom",
|
|
4198
4720
|
variant: "secondary",
|
|
4199
4721
|
className: "aui-thread-scroll-to-bottom absolute -top-12 z-10 self-center disabled:invisible",
|
|
4200
|
-
children: /* @__PURE__ */ (0,
|
|
4722
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react8.ArrowDownIcon, { className: "size-4" })
|
|
4201
4723
|
}
|
|
4202
4724
|
) });
|
|
4203
4725
|
};
|
|
@@ -4227,16 +4749,18 @@ var welcomeIcon = {
|
|
|
4227
4749
|
var ThreadWelcome = ({
|
|
4228
4750
|
config,
|
|
4229
4751
|
suggestions,
|
|
4752
|
+
showWelcomeSuggestions: showWelcomeSuggestionsProp,
|
|
4230
4753
|
Suggestions: SuggestionsSlot = Suggestions
|
|
4231
4754
|
}) => {
|
|
4232
|
-
const isEmpty = (0,
|
|
4755
|
+
const isEmpty = (0, import_react35.useThread)((s) => s.messages.length === 0);
|
|
4233
4756
|
const isPanel = useThreadVariant() === "panel";
|
|
4757
|
+
const showWelcomeSuggestions = showWelcomeSuggestionsProp ?? !isPanel;
|
|
4234
4758
|
if (!isEmpty) return null;
|
|
4235
4759
|
const defaultHeading = isPanel ? "Ask about this page" : "How can I help you today?";
|
|
4236
4760
|
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
|
-
|
|
4761
|
+
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: [
|
|
4762
|
+
/* @__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)(
|
|
4763
|
+
import_react36.motion.div,
|
|
4240
4764
|
{
|
|
4241
4765
|
className: cn(
|
|
4242
4766
|
"aui-thread-welcome-message flex flex-col items-center justify-center text-center",
|
|
@@ -4246,9 +4770,9 @@ var ThreadWelcome = ({
|
|
|
4246
4770
|
initial: "initial",
|
|
4247
4771
|
animate: "animate",
|
|
4248
4772
|
children: [
|
|
4249
|
-
config?.icon && /* @__PURE__ */ (0,
|
|
4250
|
-
/* @__PURE__ */ (0,
|
|
4251
|
-
|
|
4773
|
+
config?.icon && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react36.motion.div, { variants: welcomeIcon, className: isPanel ? "mb-3" : "mb-5", children: config.icon }),
|
|
4774
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4775
|
+
import_react36.motion.h1,
|
|
4252
4776
|
{
|
|
4253
4777
|
variants: welcomeItem,
|
|
4254
4778
|
className: cn(
|
|
@@ -4258,8 +4782,8 @@ var ThreadWelcome = ({
|
|
|
4258
4782
|
children: config?.heading ?? defaultHeading
|
|
4259
4783
|
}
|
|
4260
4784
|
),
|
|
4261
|
-
/* @__PURE__ */ (0,
|
|
4262
|
-
|
|
4785
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4786
|
+
import_react36.motion.p,
|
|
4263
4787
|
{
|
|
4264
4788
|
variants: welcomeItem,
|
|
4265
4789
|
className: "aui-thread-welcome-message-inner mt-1.5 text-muted-foreground text-sm",
|
|
@@ -4269,16 +4793,16 @@ var ThreadWelcome = ({
|
|
|
4269
4793
|
]
|
|
4270
4794
|
}
|
|
4271
4795
|
) }),
|
|
4272
|
-
|
|
4796
|
+
showWelcomeSuggestions && suggestions ? /* @__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
4797
|
] });
|
|
4274
4798
|
};
|
|
4275
4799
|
var MessageError = () => {
|
|
4276
|
-
return /* @__PURE__ */ (0,
|
|
4800
|
+
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
4801
|
};
|
|
4278
4802
|
var AssistantMessage = () => {
|
|
4279
4803
|
const isPanel = useThreadVariant() === "panel";
|
|
4280
|
-
return /* @__PURE__ */ (0,
|
|
4281
|
-
|
|
4804
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
4805
|
+
import_react35.MessagePrimitive.Root,
|
|
4282
4806
|
{
|
|
4283
4807
|
className: cn(
|
|
4284
4808
|
"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 +4810,7 @@ var AssistantMessage = () => {
|
|
|
4286
4810
|
),
|
|
4287
4811
|
"data-role": "assistant",
|
|
4288
4812
|
children: [
|
|
4289
|
-
/* @__PURE__ */ (0,
|
|
4813
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
4290
4814
|
"div",
|
|
4291
4815
|
{
|
|
4292
4816
|
className: cn(
|
|
@@ -4294,8 +4818,8 @@ var AssistantMessage = () => {
|
|
|
4294
4818
|
isPanel ? "px-1 text-sm" : "px-2"
|
|
4295
4819
|
),
|
|
4296
4820
|
children: [
|
|
4297
|
-
/* @__PURE__ */ (0,
|
|
4298
|
-
|
|
4821
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4822
|
+
import_react35.MessagePrimitive.Parts,
|
|
4299
4823
|
{
|
|
4300
4824
|
components: {
|
|
4301
4825
|
Text: MarkdownText,
|
|
@@ -4305,11 +4829,11 @@ var AssistantMessage = () => {
|
|
|
4305
4829
|
}
|
|
4306
4830
|
}
|
|
4307
4831
|
),
|
|
4308
|
-
/* @__PURE__ */ (0,
|
|
4832
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(MessageError, {})
|
|
4309
4833
|
]
|
|
4310
4834
|
}
|
|
4311
4835
|
),
|
|
4312
|
-
/* @__PURE__ */ (0,
|
|
4836
|
+
/* @__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
4837
|
]
|
|
4314
4838
|
}
|
|
4315
4839
|
);
|
|
@@ -4322,36 +4846,36 @@ var ASSISTANT_ACTION_ICON_CLASS = cn(
|
|
|
4322
4846
|
"[&>span:first-child]:group-hover/tbv2:bg-ghost-fill-hover"
|
|
4323
4847
|
);
|
|
4324
4848
|
var AssistantActionBar = () => {
|
|
4325
|
-
return /* @__PURE__ */ (0,
|
|
4326
|
-
|
|
4849
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
4850
|
+
import_react35.ActionBarPrimitive.Root,
|
|
4327
4851
|
{
|
|
4328
4852
|
hideWhenRunning: true,
|
|
4329
4853
|
autohide: "never",
|
|
4330
4854
|
className: "aui-assistant-action-bar-root flex items-center gap-0 bg-transparent px-0 py-0.5 text-muted-foreground/60",
|
|
4331
4855
|
children: [
|
|
4332
|
-
/* @__PURE__ */ (0,
|
|
4856
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react35.ActionBarPrimitive.Copy, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
4333
4857
|
TooltipIconButton,
|
|
4334
4858
|
{
|
|
4335
4859
|
tooltip: "Copy",
|
|
4336
4860
|
variant: "ghost",
|
|
4337
4861
|
className: ASSISTANT_ACTION_ICON_CLASS,
|
|
4338
4862
|
children: [
|
|
4339
|
-
/* @__PURE__ */ (0,
|
|
4340
|
-
/* @__PURE__ */ (0,
|
|
4863
|
+
/* @__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" }) }),
|
|
4864
|
+
/* @__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
4865
|
]
|
|
4342
4866
|
}
|
|
4343
4867
|
) }),
|
|
4344
|
-
/* @__PURE__ */ (0,
|
|
4868
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react35.ActionBarPrimitive.Reload, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4345
4869
|
TooltipIconButton,
|
|
4346
4870
|
{
|
|
4347
4871
|
tooltip: "Regenerate",
|
|
4348
4872
|
variant: "ghost",
|
|
4349
4873
|
className: ASSISTANT_ACTION_ICON_CLASS,
|
|
4350
|
-
children: /* @__PURE__ */ (0,
|
|
4874
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react8.RefreshCwIcon, { className: "size-3" })
|
|
4351
4875
|
}
|
|
4352
4876
|
) }),
|
|
4353
|
-
/* @__PURE__ */ (0,
|
|
4354
|
-
/* @__PURE__ */ (0,
|
|
4877
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_react35.ActionBarMorePrimitive.Root, { children: [
|
|
4878
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react35.ActionBarMorePrimitive.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4355
4879
|
TooltipIconButton,
|
|
4356
4880
|
{
|
|
4357
4881
|
tooltip: "More",
|
|
@@ -4360,17 +4884,17 @@ var AssistantActionBar = () => {
|
|
|
4360
4884
|
ASSISTANT_ACTION_ICON_CLASS,
|
|
4361
4885
|
"data-[state=open]:text-muted-foreground/80"
|
|
4362
4886
|
),
|
|
4363
|
-
children: /* @__PURE__ */ (0,
|
|
4887
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react8.MoreHorizontalIcon, { className: "size-3" })
|
|
4364
4888
|
}
|
|
4365
4889
|
) }),
|
|
4366
|
-
/* @__PURE__ */ (0,
|
|
4367
|
-
|
|
4890
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4891
|
+
import_react35.ActionBarMorePrimitive.Content,
|
|
4368
4892
|
{
|
|
4369
4893
|
side: "bottom",
|
|
4370
4894
|
align: "start",
|
|
4371
4895
|
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,
|
|
4896
|
+
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: [
|
|
4897
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react8.DownloadIcon, { className: "size-4 shrink-0" }),
|
|
4374
4898
|
"Export as Markdown"
|
|
4375
4899
|
] }) })
|
|
4376
4900
|
}
|
|
@@ -4381,12 +4905,12 @@ var AssistantActionBar = () => {
|
|
|
4381
4905
|
);
|
|
4382
4906
|
};
|
|
4383
4907
|
var UserMessageText = () => {
|
|
4384
|
-
return /* @__PURE__ */ (0,
|
|
4908
|
+
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
4909
|
};
|
|
4386
4910
|
var UserMessage = () => {
|
|
4387
4911
|
const isPanel = useThreadVariant() === "panel";
|
|
4388
|
-
return /* @__PURE__ */ (0,
|
|
4389
|
-
|
|
4912
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
4913
|
+
import_react35.MessagePrimitive.Root,
|
|
4390
4914
|
{
|
|
4391
4915
|
className: cn(
|
|
4392
4916
|
"aui-user-message-root mx-auto flex w-full max-w-(--thread-max-width) flex-col items-end gap-2",
|
|
@@ -4394,9 +4918,9 @@ var UserMessage = () => {
|
|
|
4394
4918
|
),
|
|
4395
4919
|
"data-role": "user",
|
|
4396
4920
|
children: [
|
|
4397
|
-
/* @__PURE__ */ (0,
|
|
4398
|
-
/* @__PURE__ */ (0,
|
|
4399
|
-
|
|
4921
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(UserMessageAttachments, {}),
|
|
4922
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
4923
|
+
import_react36.motion.div,
|
|
4400
4924
|
{
|
|
4401
4925
|
className: cn(
|
|
4402
4926
|
"aui-user-message-content relative inline-block max-w-[85%] rounded-2xl bg-bubble-user text-bubble-user-foreground",
|
|
@@ -4406,8 +4930,8 @@ var UserMessage = () => {
|
|
|
4406
4930
|
animate: { opacity: 1, y: 0, scale: 1 },
|
|
4407
4931
|
transition: { duration: 0.65, ease: luxuryEase },
|
|
4408
4932
|
children: [
|
|
4409
|
-
/* @__PURE__ */ (0,
|
|
4410
|
-
/* @__PURE__ */ (0,
|
|
4933
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react35.MessagePrimitive.Parts, { components: { Text: UserMessageText } }),
|
|
4934
|
+
/* @__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
4935
|
]
|
|
4412
4936
|
}
|
|
4413
4937
|
)
|
|
@@ -4416,46 +4940,45 @@ var UserMessage = () => {
|
|
|
4416
4940
|
);
|
|
4417
4941
|
};
|
|
4418
4942
|
var UserActionBar = () => {
|
|
4419
|
-
return /* @__PURE__ */ (0,
|
|
4420
|
-
|
|
4943
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4944
|
+
import_react35.ActionBarPrimitive.Root,
|
|
4421
4945
|
{
|
|
4422
4946
|
hideWhenRunning: true,
|
|
4423
4947
|
autohide: "always",
|
|
4424
4948
|
className: "aui-user-action-bar-root flex flex-col items-end",
|
|
4425
|
-
children: /* @__PURE__ */ (0,
|
|
4949
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react35.ActionBarPrimitive.Edit, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4426
4950
|
TooltipIconButton,
|
|
4427
4951
|
{
|
|
4428
4952
|
tooltip: "Edit",
|
|
4429
4953
|
variant: "ghost",
|
|
4430
4954
|
className: ASSISTANT_ACTION_ICON_CLASS,
|
|
4431
|
-
children: /* @__PURE__ */ (0,
|
|
4955
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react8.PencilIcon, { className: "size-3" })
|
|
4432
4956
|
}
|
|
4433
4957
|
) })
|
|
4434
4958
|
}
|
|
4435
4959
|
);
|
|
4436
4960
|
};
|
|
4437
4961
|
var EditComposer = () => {
|
|
4438
|
-
return /* @__PURE__ */ (0,
|
|
4439
|
-
/* @__PURE__ */ (0,
|
|
4440
|
-
|
|
4962
|
+
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: [
|
|
4963
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4964
|
+
import_react35.ComposerPrimitive.Input,
|
|
4441
4965
|
{
|
|
4442
4966
|
className: "aui-edit-composer-input min-h-14 w-full resize-none bg-transparent p-4 text-foreground text-sm outline-none",
|
|
4443
4967
|
autoFocus: true
|
|
4444
4968
|
}
|
|
4445
4969
|
),
|
|
4446
|
-
/* @__PURE__ */ (0,
|
|
4447
|
-
/* @__PURE__ */ (0,
|
|
4448
|
-
/* @__PURE__ */ (0,
|
|
4970
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "aui-edit-composer-footer mx-3 mb-3 flex items-center gap-2 self-end", children: [
|
|
4971
|
+
/* @__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" }) }),
|
|
4972
|
+
/* @__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
4973
|
] })
|
|
4450
4974
|
] }) });
|
|
4451
4975
|
};
|
|
4452
4976
|
|
|
4453
4977
|
// src/app/chat/AppChatPanel.tsx
|
|
4454
|
-
var
|
|
4978
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
4455
4979
|
var shellClass = "aui-app-chat-panel flex h-full min-h-0 flex-col overflow-hidden";
|
|
4456
4980
|
var chromeClass = cn(
|
|
4457
|
-
"aui-app-chat-panel-chrome relative z-20 flex min-h-
|
|
4458
|
-
"bg-card/90 px-2 pt-3 pb-3 backdrop-blur-sm"
|
|
4981
|
+
"aui-app-chat-panel-chrome relative z-20 flex min-h-10 shrink-0 items-center justify-end px-2 pt-2"
|
|
4459
4982
|
);
|
|
4460
4983
|
var closeButtonClass = cn(
|
|
4461
4984
|
"aui-app-chat-panel-close flex size-8 shrink-0 items-center justify-center rounded-md",
|
|
@@ -4472,8 +4995,9 @@ var bodyClass = cn(
|
|
|
4472
4995
|
"[&_.aui-thread-viewport]:[scrollbar-gutter:stable_both-edges]",
|
|
4473
4996
|
// Tighter symmetric horizontal inset for panel + composer
|
|
4474
4997
|
"[&_.aui-thread-viewport]:!px-2",
|
|
4475
|
-
"[&_.aui-thread-viewport]:!pt-
|
|
4998
|
+
"[&_.aui-thread-viewport]:!pt-1",
|
|
4476
4999
|
"[&_.aui-user-message-root]:!px-0",
|
|
5000
|
+
"[&_.aui-user-message-root]:!pe-1",
|
|
4477
5001
|
"[&_.aui-composer-input]:!px-2",
|
|
4478
5002
|
"[&_.aui-composer-action-wrapper]:!px-2"
|
|
4479
5003
|
);
|
|
@@ -4488,6 +5012,7 @@ var AppChatPanel = ({
|
|
|
4488
5012
|
debug,
|
|
4489
5013
|
welcome,
|
|
4490
5014
|
suggestions,
|
|
5015
|
+
showWelcomeSuggestions,
|
|
4491
5016
|
composerPlaceholder,
|
|
4492
5017
|
components,
|
|
4493
5018
|
artifacts,
|
|
@@ -4495,18 +5020,18 @@ var AppChatPanel = ({
|
|
|
4495
5020
|
...rest
|
|
4496
5021
|
}) => {
|
|
4497
5022
|
const shellChat = useAppShellChat();
|
|
4498
|
-
return /* @__PURE__ */ (0,
|
|
4499
|
-
shellChat?.collapsible ? /* @__PURE__ */ (0,
|
|
5023
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: cn(shellClass, className), children: [
|
|
5024
|
+
shellChat?.collapsible ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: chromeClass, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
4500
5025
|
"button",
|
|
4501
5026
|
{
|
|
4502
5027
|
type: "button",
|
|
4503
5028
|
className: closeButtonClass,
|
|
4504
5029
|
onClick: () => shellChat.setOpen(false),
|
|
4505
5030
|
"aria-label": "Close assistant",
|
|
4506
|
-
children: /* @__PURE__ */ (0,
|
|
5031
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_lucide_react9.XIcon, { className: "size-4", "aria-hidden": true })
|
|
4507
5032
|
}
|
|
4508
5033
|
) }) : null,
|
|
4509
|
-
/* @__PURE__ */ (0,
|
|
5034
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: bodyClass, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
4510
5035
|
TimbalRuntimeProvider,
|
|
4511
5036
|
{
|
|
4512
5037
|
workforceId,
|
|
@@ -4516,13 +5041,14 @@ var AppChatPanel = ({
|
|
|
4516
5041
|
attachmentsUploadUrl,
|
|
4517
5042
|
attachmentsAccept,
|
|
4518
5043
|
debug,
|
|
4519
|
-
children: /* @__PURE__ */ (0,
|
|
5044
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
4520
5045
|
Thread,
|
|
4521
5046
|
{
|
|
4522
5047
|
variant: "panel",
|
|
4523
5048
|
className: "aui-app-chat-panel-thread",
|
|
4524
5049
|
welcome,
|
|
4525
5050
|
suggestions,
|
|
5051
|
+
showWelcomeSuggestions,
|
|
4526
5052
|
composerPlaceholder,
|
|
4527
5053
|
components,
|
|
4528
5054
|
artifacts,
|
|
@@ -4536,38 +5062,38 @@ var AppChatPanel = ({
|
|
|
4536
5062
|
};
|
|
4537
5063
|
|
|
4538
5064
|
// src/app/surfaces/SurfaceCard.tsx
|
|
4539
|
-
var
|
|
5065
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
4540
5066
|
var SurfaceCard = ({ children, className }) => {
|
|
4541
|
-
return /* @__PURE__ */ (0,
|
|
5067
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: cn("aui-app-surface-card", appSurfaceCardClass, className), children });
|
|
4542
5068
|
};
|
|
4543
5069
|
|
|
4544
5070
|
// src/app/surfaces/StatTile.tsx
|
|
4545
|
-
var
|
|
5071
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
4546
5072
|
var StatTile = ({ label, value, hint, className }) => {
|
|
4547
|
-
return /* @__PURE__ */ (0,
|
|
4548
|
-
/* @__PURE__ */ (0,
|
|
4549
|
-
/* @__PURE__ */ (0,
|
|
4550
|
-
hint ? /* @__PURE__ */ (0,
|
|
5073
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: cn("aui-app-stat-tile", appStatTileClass, className), children: [
|
|
5074
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: appStatLabelClass, children: label }),
|
|
5075
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: appStatValueClass, children: value }),
|
|
5076
|
+
hint ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "text-xs text-muted-foreground", children: hint }) : null
|
|
4551
5077
|
] });
|
|
4552
5078
|
};
|
|
4553
5079
|
|
|
4554
5080
|
// src/app/surfaces/EmptyState.tsx
|
|
4555
|
-
var
|
|
4556
|
-
var
|
|
5081
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
5082
|
+
var EmptyState = ({
|
|
4557
5083
|
title,
|
|
4558
5084
|
description,
|
|
4559
5085
|
action,
|
|
4560
5086
|
className
|
|
4561
5087
|
}) => {
|
|
4562
|
-
return /* @__PURE__ */ (0,
|
|
4563
|
-
/* @__PURE__ */ (0,
|
|
4564
|
-
description ? /* @__PURE__ */ (0,
|
|
5088
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: cn("aui-app-empty-state", appEmptyStateClass, className), children: [
|
|
5089
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("p", { className: appEmptyStateTitleClass, children: title }),
|
|
5090
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("p", { className: appEmptyStateDescriptionClass, children: description }) : null,
|
|
4565
5091
|
action
|
|
4566
5092
|
] });
|
|
4567
5093
|
};
|
|
4568
5094
|
|
|
4569
5095
|
// src/app/surfaces/StatusBadge.tsx
|
|
4570
|
-
var
|
|
5096
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
4571
5097
|
var statusBadgeToneClass = {
|
|
4572
5098
|
default: "bg-muted text-foreground",
|
|
4573
5099
|
primary: "bg-primary/10 text-primary",
|
|
@@ -4580,7 +5106,7 @@ var StatusBadge = ({
|
|
|
4580
5106
|
tone = "default",
|
|
4581
5107
|
className
|
|
4582
5108
|
}) => {
|
|
4583
|
-
return /* @__PURE__ */ (0,
|
|
5109
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
4584
5110
|
"span",
|
|
4585
5111
|
{
|
|
4586
5112
|
className: cn(
|
|
@@ -4594,7 +5120,7 @@ var StatusBadge = ({
|
|
|
4594
5120
|
};
|
|
4595
5121
|
|
|
4596
5122
|
// src/app/surfaces/AppConfirmDialog.tsx
|
|
4597
|
-
var
|
|
5123
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
4598
5124
|
var bodyClass2 = "flex flex-col gap-4 p-6";
|
|
4599
5125
|
var titleClass = "pr-8";
|
|
4600
5126
|
var actionsClass = "flex flex-wrap justify-end gap-2";
|
|
@@ -4609,15 +5135,15 @@ var AppConfirmDialog = ({
|
|
|
4609
5135
|
destructive = false,
|
|
4610
5136
|
className
|
|
4611
5137
|
}) => {
|
|
4612
|
-
return /* @__PURE__ */ (0,
|
|
5138
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Dialog, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
4613
5139
|
DialogContent,
|
|
4614
5140
|
{
|
|
4615
5141
|
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,
|
|
5142
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: bodyClass2, children: [
|
|
5143
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(DialogTitle, { className: titleClass, children: title }),
|
|
5144
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("p", { className: "text-sm text-muted-foreground", children: description }) : null,
|
|
5145
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: actionsClass, children: [
|
|
5146
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
4621
5147
|
TimbalV2Button,
|
|
4622
5148
|
{
|
|
4623
5149
|
type: "button",
|
|
@@ -4627,7 +5153,7 @@ var AppConfirmDialog = ({
|
|
|
4627
5153
|
children: cancelLabel
|
|
4628
5154
|
}
|
|
4629
5155
|
),
|
|
4630
|
-
/* @__PURE__ */ (0,
|
|
5156
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
4631
5157
|
TimbalV2Button,
|
|
4632
5158
|
{
|
|
4633
5159
|
type: "button",
|
|
@@ -4646,30 +5172,640 @@ var AppConfirmDialog = ({
|
|
|
4646
5172
|
) });
|
|
4647
5173
|
};
|
|
4648
5174
|
|
|
4649
|
-
// src/
|
|
4650
|
-
var
|
|
4651
|
-
var
|
|
5175
|
+
// src/app/surfaces/InfoCard.tsx
|
|
5176
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
5177
|
+
var toneClass = {
|
|
5178
|
+
neutral: "border-border bg-muted/40",
|
|
5179
|
+
info: "border-primary/25 bg-primary/5",
|
|
5180
|
+
success: "border-emerald-500/25 bg-emerald-500/5",
|
|
5181
|
+
warn: "border-amber-500/25 bg-amber-500/5",
|
|
5182
|
+
danger: "border-destructive/25 bg-destructive/5"
|
|
5183
|
+
};
|
|
5184
|
+
var InfoCard = ({
|
|
5185
|
+
title,
|
|
5186
|
+
children,
|
|
5187
|
+
icon,
|
|
5188
|
+
action,
|
|
5189
|
+
tone = "neutral",
|
|
5190
|
+
className
|
|
5191
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
5192
|
+
"div",
|
|
5193
|
+
{
|
|
5194
|
+
className: cn(
|
|
5195
|
+
"flex items-start gap-3 rounded-xl border p-4",
|
|
5196
|
+
toneClass[tone],
|
|
5197
|
+
className
|
|
5198
|
+
),
|
|
5199
|
+
children: [
|
|
5200
|
+
icon ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "mt-0.5 shrink-0 text-muted-foreground", children: icon }) : null,
|
|
5201
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
5202
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { className: "text-sm font-medium text-foreground", children: title }) : null,
|
|
5203
|
+
children ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: cn("text-sm text-muted-foreground", title && "mt-1"), children }) : null
|
|
5204
|
+
] }),
|
|
5205
|
+
action ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "shrink-0", children: action }) : null
|
|
5206
|
+
]
|
|
5207
|
+
}
|
|
5208
|
+
);
|
|
4652
5209
|
|
|
4653
|
-
// src/
|
|
4654
|
-
var
|
|
4655
|
-
var
|
|
4656
|
-
"bg-
|
|
4657
|
-
"
|
|
5210
|
+
// src/app/surfaces/StatusDot.tsx
|
|
5211
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
5212
|
+
var dotClass = {
|
|
5213
|
+
online: "bg-emerald-500",
|
|
5214
|
+
busy: "bg-amber-500",
|
|
5215
|
+
offline: "bg-muted-foreground/50",
|
|
5216
|
+
error: "bg-destructive",
|
|
5217
|
+
neutral: "bg-muted-foreground"
|
|
5218
|
+
};
|
|
5219
|
+
var StatusDot = ({
|
|
5220
|
+
tone = "neutral",
|
|
5221
|
+
label,
|
|
5222
|
+
pulse = false,
|
|
5223
|
+
className
|
|
5224
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: cn("inline-flex items-center gap-1.5", className), children: [
|
|
5225
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "relative flex size-2", children: [
|
|
5226
|
+
pulse ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
5227
|
+
"span",
|
|
5228
|
+
{
|
|
5229
|
+
className: cn(
|
|
5230
|
+
"absolute inline-flex size-full animate-ping rounded-full opacity-60",
|
|
5231
|
+
dotClass[tone]
|
|
5232
|
+
)
|
|
5233
|
+
}
|
|
5234
|
+
) : null,
|
|
5235
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: cn("relative inline-flex size-2 rounded-full", dotClass[tone]) })
|
|
5236
|
+
] }),
|
|
5237
|
+
label ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "text-xs text-muted-foreground", children: label }) : null
|
|
5238
|
+
] });
|
|
5239
|
+
|
|
5240
|
+
// src/app/surfaces/DescriptionList.tsx
|
|
5241
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
5242
|
+
var DescriptionList = ({
|
|
5243
|
+
items,
|
|
5244
|
+
stacked = false,
|
|
5245
|
+
className
|
|
5246
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
5247
|
+
"dl",
|
|
5248
|
+
{
|
|
5249
|
+
className: cn(
|
|
5250
|
+
"divide-y divide-border rounded-xl border border-border bg-card",
|
|
5251
|
+
className
|
|
5252
|
+
),
|
|
5253
|
+
children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
5254
|
+
"div",
|
|
5255
|
+
{
|
|
5256
|
+
className: cn(
|
|
5257
|
+
"px-4 py-3",
|
|
5258
|
+
stacked ? "flex flex-col gap-0.5" : "flex items-center justify-between gap-4"
|
|
5259
|
+
),
|
|
5260
|
+
children: [
|
|
5261
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("dt", { className: "text-sm text-muted-foreground", children: item.label }),
|
|
5262
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
5263
|
+
"dd",
|
|
5264
|
+
{
|
|
5265
|
+
className: cn(
|
|
5266
|
+
"text-sm text-foreground",
|
|
5267
|
+
!stacked && "text-right tabular-nums"
|
|
5268
|
+
),
|
|
5269
|
+
children: item.value
|
|
5270
|
+
}
|
|
5271
|
+
)
|
|
5272
|
+
]
|
|
5273
|
+
},
|
|
5274
|
+
i
|
|
5275
|
+
))
|
|
5276
|
+
}
|
|
4658
5277
|
);
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
5278
|
+
|
|
5279
|
+
// src/app/surfaces/ExpandableSection.tsx
|
|
5280
|
+
var import_react37 = require("react");
|
|
5281
|
+
var import_react38 = require("motion/react");
|
|
5282
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
5283
|
+
var Chevron = ({ open }) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
5284
|
+
"svg",
|
|
5285
|
+
{
|
|
5286
|
+
viewBox: "0 0 24 24",
|
|
5287
|
+
className: cn(
|
|
5288
|
+
"size-4 text-muted-foreground transition-transform duration-200",
|
|
5289
|
+
open && "rotate-180"
|
|
5290
|
+
),
|
|
5291
|
+
fill: "none",
|
|
5292
|
+
stroke: "currentColor",
|
|
5293
|
+
strokeWidth: 2,
|
|
5294
|
+
strokeLinecap: "round",
|
|
5295
|
+
strokeLinejoin: "round",
|
|
5296
|
+
"aria-hidden": true,
|
|
5297
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("path", { d: "m6 9 6 6 6-6" })
|
|
5298
|
+
}
|
|
4663
5299
|
);
|
|
4664
|
-
var
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
5300
|
+
var ExpandableSection = ({
|
|
5301
|
+
title,
|
|
5302
|
+
icon,
|
|
5303
|
+
count,
|
|
5304
|
+
children,
|
|
5305
|
+
open: openProp,
|
|
5306
|
+
defaultOpen = false,
|
|
5307
|
+
onOpenChange,
|
|
5308
|
+
className
|
|
5309
|
+
}) => {
|
|
5310
|
+
const reduceMotion = (0, import_react38.useReducedMotion)();
|
|
5311
|
+
const panelId = (0, import_react37.useId)();
|
|
5312
|
+
const [internalOpen, setInternalOpen] = (0, import_react37.useState)(defaultOpen);
|
|
5313
|
+
const open = openProp ?? internalOpen;
|
|
5314
|
+
const toggle = () => {
|
|
5315
|
+
if (openProp == null) setInternalOpen((o) => !o);
|
|
5316
|
+
onOpenChange?.(!open);
|
|
5317
|
+
};
|
|
5318
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: cn("border-b border-border last:border-0", className), children: [
|
|
5319
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
|
|
5320
|
+
"button",
|
|
5321
|
+
{
|
|
5322
|
+
type: "button",
|
|
5323
|
+
onClick: toggle,
|
|
5324
|
+
"aria-expanded": open,
|
|
5325
|
+
"aria-controls": panelId,
|
|
5326
|
+
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",
|
|
5327
|
+
children: [
|
|
5328
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("span", { className: "flex min-w-0 items-center gap-3", children: [
|
|
5329
|
+
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,
|
|
5330
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "truncate text-sm font-medium text-foreground", children: title }),
|
|
5331
|
+
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
|
|
5332
|
+
] }),
|
|
5333
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Chevron, { open })
|
|
5334
|
+
]
|
|
5335
|
+
}
|
|
5336
|
+
),
|
|
5337
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react38.AnimatePresence, { initial: false, children: open ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
5338
|
+
import_react38.motion.div,
|
|
5339
|
+
{
|
|
5340
|
+
id: panelId,
|
|
5341
|
+
initial: reduceMotion ? void 0 : { height: 0, opacity: 0 },
|
|
5342
|
+
animate: { height: "auto", opacity: 1 },
|
|
5343
|
+
exit: reduceMotion ? void 0 : { height: 0, opacity: 0 },
|
|
5344
|
+
transition: { duration: 0.2, ease: "easeOut" },
|
|
5345
|
+
className: "overflow-hidden",
|
|
5346
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "bg-muted/20", children })
|
|
5347
|
+
},
|
|
5348
|
+
"body"
|
|
5349
|
+
) : null })
|
|
5350
|
+
] });
|
|
5351
|
+
};
|
|
5352
|
+
|
|
5353
|
+
// src/app/surfaces/ResourceCard.tsx
|
|
5354
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
5355
|
+
var resourceCardShellClass = cn(
|
|
5356
|
+
"flex min-h-[8.5rem] flex-col rounded-2xl p-4 text-left font-normal",
|
|
5357
|
+
TIMBAL_V2_ELEVATED_SURFACE
|
|
4668
5358
|
);
|
|
4669
|
-
var
|
|
4670
|
-
"
|
|
5359
|
+
var mediaShellClass = cn(
|
|
5360
|
+
"flex size-10 shrink-0 items-center justify-center overflow-hidden rounded-xl text-sm font-normal text-foreground",
|
|
5361
|
+
TIMBAL_V2_LOGO_TILE
|
|
4671
5362
|
);
|
|
4672
|
-
var
|
|
5363
|
+
var resourceCardInteractiveClass = cn(
|
|
5364
|
+
resourceCardShellClass,
|
|
5365
|
+
"cursor-pointer bg-transparent hover:bg-transparent active:bg-transparent",
|
|
5366
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/15 focus-visible:ring-offset-2 focus-visible:ring-offset-background"
|
|
5367
|
+
);
|
|
5368
|
+
var ResourceCard = ({
|
|
5369
|
+
title,
|
|
5370
|
+
subtitle,
|
|
5371
|
+
media,
|
|
5372
|
+
badge,
|
|
5373
|
+
footer,
|
|
5374
|
+
action,
|
|
5375
|
+
onClick,
|
|
5376
|
+
ariaLabel,
|
|
5377
|
+
className
|
|
5378
|
+
}) => {
|
|
5379
|
+
const body = /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_jsx_runtime47.Fragment, { children: [
|
|
5380
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-start gap-3", children: [
|
|
5381
|
+
media ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: mediaShellClass, children: media }) : null,
|
|
5382
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "min-w-0 flex-1 pt-0.5", children: [
|
|
5383
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("p", { className: "truncate text-sm font-normal leading-snug text-foreground", children: title }),
|
|
5384
|
+
subtitle ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("p", { className: "mt-1 line-clamp-2 text-xs font-normal text-muted-foreground", children: subtitle }) : null
|
|
5385
|
+
] }),
|
|
5386
|
+
badge ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "shrink-0 pt-0.5", children: badge }) : null
|
|
5387
|
+
] }),
|
|
5388
|
+
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: [
|
|
5389
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "min-w-0 truncate", children: footer }),
|
|
5390
|
+
action ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "shrink-0 opacity-80", children: action }) : null
|
|
5391
|
+
] }) : null
|
|
5392
|
+
] });
|
|
5393
|
+
if (onClick) {
|
|
5394
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", onClick, "aria-label": ariaLabel, className: cn(resourceCardInteractiveClass, className), children: body });
|
|
5395
|
+
}
|
|
5396
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("article", { className: cn(resourceCardShellClass, className), children: body });
|
|
5397
|
+
};
|
|
5398
|
+
|
|
5399
|
+
// src/app/settings/SettingsSection.tsx
|
|
5400
|
+
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
5401
|
+
var SettingsSectionHeader = ({
|
|
5402
|
+
title,
|
|
5403
|
+
description,
|
|
5404
|
+
className
|
|
5405
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: cn("flex flex-col", className), children: [
|
|
5406
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("h3", { className: "text-[17px] font-medium leading-tight text-foreground", children: title }),
|
|
5407
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null
|
|
5408
|
+
] });
|
|
5409
|
+
var SettingsSection = ({
|
|
5410
|
+
title,
|
|
5411
|
+
description,
|
|
5412
|
+
descriptionFooter,
|
|
5413
|
+
children,
|
|
5414
|
+
noBorderTop = false,
|
|
5415
|
+
className
|
|
5416
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
|
|
5417
|
+
"section",
|
|
5418
|
+
{
|
|
5419
|
+
className: cn(
|
|
5420
|
+
"grid grid-cols-1 gap-y-4 lg:grid-cols-[minmax(200px,280px)_minmax(0,1fr)] lg:gap-x-12 lg:gap-y-0",
|
|
5421
|
+
noBorderTop ? "pb-6" : "border-t border-border py-6",
|
|
5422
|
+
className
|
|
5423
|
+
),
|
|
5424
|
+
children: [
|
|
5425
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "min-w-0", children: [
|
|
5426
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("h2", { className: "text-sm font-medium text-foreground", children: title }),
|
|
5427
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null,
|
|
5428
|
+
descriptionFooter ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "mt-3 min-w-0", children: descriptionFooter }) : null
|
|
5429
|
+
] }),
|
|
5430
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "min-w-0 space-y-3", children })
|
|
5431
|
+
]
|
|
5432
|
+
}
|
|
5433
|
+
);
|
|
5434
|
+
|
|
5435
|
+
// src/app/settings/FieldRow.tsx
|
|
5436
|
+
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
5437
|
+
var FieldRow = ({
|
|
5438
|
+
label,
|
|
5439
|
+
children,
|
|
5440
|
+
description,
|
|
5441
|
+
inline = false,
|
|
5442
|
+
htmlFor,
|
|
5443
|
+
className
|
|
5444
|
+
}) => {
|
|
5445
|
+
if (inline) {
|
|
5446
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
|
|
5447
|
+
"div",
|
|
5448
|
+
{
|
|
5449
|
+
className: cn(
|
|
5450
|
+
"flex items-center justify-between gap-4 rounded-lg border border-border bg-card px-3.5 py-3",
|
|
5451
|
+
className
|
|
5452
|
+
),
|
|
5453
|
+
children: [
|
|
5454
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "min-w-0", children: [
|
|
5455
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
5456
|
+
"label",
|
|
5457
|
+
{
|
|
5458
|
+
htmlFor,
|
|
5459
|
+
className: "block text-sm font-medium text-foreground",
|
|
5460
|
+
children: label
|
|
5461
|
+
}
|
|
5462
|
+
),
|
|
5463
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("p", { className: "mt-0.5 text-xs text-muted-foreground", children: description }) : null
|
|
5464
|
+
] }),
|
|
5465
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "shrink-0", children })
|
|
5466
|
+
]
|
|
5467
|
+
}
|
|
5468
|
+
);
|
|
5469
|
+
}
|
|
5470
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: cn("flex flex-col gap-1.5", className), children: [
|
|
5471
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("label", { htmlFor, className: "text-sm font-medium text-foreground", children: label }),
|
|
5472
|
+
children,
|
|
5473
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("p", { className: "text-xs text-muted-foreground", children: description }) : null
|
|
5474
|
+
] });
|
|
5475
|
+
};
|
|
5476
|
+
|
|
5477
|
+
// src/app/settings/FloatingUnsavedChangesBar.tsx
|
|
5478
|
+
var import_react39 = require("react");
|
|
5479
|
+
var import_react_dom = require("react-dom");
|
|
5480
|
+
var import_react40 = require("motion/react");
|
|
5481
|
+
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
5482
|
+
var FloatingUnsavedChangesBar = ({
|
|
5483
|
+
visible,
|
|
5484
|
+
message = "Unsaved changes",
|
|
5485
|
+
discardLabel = "Discard",
|
|
5486
|
+
saveLabel = "Save changes",
|
|
5487
|
+
isSaving = false,
|
|
5488
|
+
saveDisabled = false,
|
|
5489
|
+
onDiscard,
|
|
5490
|
+
onSave,
|
|
5491
|
+
ariaLabel = "Unsaved changes",
|
|
5492
|
+
className
|
|
5493
|
+
}) => {
|
|
5494
|
+
const reduceMotion = (0, import_react40.useReducedMotion)();
|
|
5495
|
+
const [mounted, setMounted] = (0, import_react39.useState)(false);
|
|
5496
|
+
(0, import_react39.useEffect)(() => setMounted(true), []);
|
|
5497
|
+
if (!mounted || typeof document === "undefined") return null;
|
|
5498
|
+
return (0, import_react_dom.createPortal)(
|
|
5499
|
+
/* @__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)(
|
|
5500
|
+
import_react40.motion.div,
|
|
5501
|
+
{
|
|
5502
|
+
role: "region",
|
|
5503
|
+
"aria-label": ariaLabel,
|
|
5504
|
+
initial: reduceMotion ? { opacity: 0 } : { opacity: 0, y: 28, scale: 0.94 },
|
|
5505
|
+
animate: { opacity: 1, y: 0, scale: 1 },
|
|
5506
|
+
exit: reduceMotion ? { opacity: 0 } : { opacity: 0, y: 18, scale: 0.96 },
|
|
5507
|
+
transition: { type: "spring", stiffness: 420, damping: 32 },
|
|
5508
|
+
className: cn(
|
|
5509
|
+
"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",
|
|
5510
|
+
className
|
|
5511
|
+
),
|
|
5512
|
+
children: [
|
|
5513
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "text-sm text-muted-foreground", children: message }),
|
|
5514
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("span", { className: "flex items-center gap-1.5", children: [
|
|
5515
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(Button, { variant: "ghost", size: "sm", onClick: onDiscard, disabled: isSaving, children: discardLabel }),
|
|
5516
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(Button, { size: "sm", onClick: onSave, disabled: saveDisabled || isSaving, children: isSaving ? "Saving\u2026" : saveLabel })
|
|
5517
|
+
] })
|
|
5518
|
+
]
|
|
5519
|
+
}
|
|
5520
|
+
) }) : null }),
|
|
5521
|
+
document.body
|
|
5522
|
+
);
|
|
5523
|
+
};
|
|
5524
|
+
|
|
5525
|
+
// src/app/settings/DangerZone.tsx
|
|
5526
|
+
var import_jsx_runtime51 = require("react/jsx-runtime");
|
|
5527
|
+
var DangerZoneAction = ({
|
|
5528
|
+
title,
|
|
5529
|
+
description,
|
|
5530
|
+
action,
|
|
5531
|
+
className
|
|
5532
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
5533
|
+
"div",
|
|
5534
|
+
{
|
|
5535
|
+
className: cn(
|
|
5536
|
+
"flex flex-col gap-3 px-4 py-3.5 sm:flex-row sm:items-center sm:justify-between",
|
|
5537
|
+
className
|
|
5538
|
+
),
|
|
5539
|
+
children: [
|
|
5540
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "min-w-0", children: [
|
|
5541
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("p", { className: "text-sm font-medium text-foreground", children: title }),
|
|
5542
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
|
|
5543
|
+
] }),
|
|
5544
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "shrink-0", children: action })
|
|
5545
|
+
]
|
|
5546
|
+
}
|
|
5547
|
+
);
|
|
5548
|
+
var DangerZone = ({
|
|
5549
|
+
title = "Danger zone",
|
|
5550
|
+
description,
|
|
5551
|
+
children,
|
|
5552
|
+
className
|
|
5553
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
5554
|
+
"section",
|
|
5555
|
+
{
|
|
5556
|
+
className: cn(
|
|
5557
|
+
"overflow-hidden rounded-xl border border-destructive/30",
|
|
5558
|
+
className
|
|
5559
|
+
),
|
|
5560
|
+
children: [
|
|
5561
|
+
(title || description) && /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("header", { className: "border-b border-destructive/20 bg-destructive/5 px-4 py-3", children: [
|
|
5562
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("h3", { className: "text-sm font-semibold text-destructive", children: title }) : null,
|
|
5563
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
|
|
5564
|
+
] }),
|
|
5565
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "divide-y divide-border bg-card", children })
|
|
5566
|
+
]
|
|
5567
|
+
}
|
|
5568
|
+
);
|
|
5569
|
+
|
|
5570
|
+
// src/app/integrations/IntegrationCard.tsx
|
|
5571
|
+
var import_react41 = require("react");
|
|
5572
|
+
var import_jsx_runtime52 = require("react/jsx-runtime");
|
|
5573
|
+
var INTEGRATION_CATALOG_CARD_HEIGHT_CLASS = "h-[12.25rem] min-h-[12.25rem] max-h-[12.25rem]";
|
|
5574
|
+
var statusLabel = {
|
|
5575
|
+
available: null,
|
|
5576
|
+
connected: "Connected",
|
|
5577
|
+
disabled: "Disabled",
|
|
5578
|
+
locked: "Locked"
|
|
5579
|
+
};
|
|
5580
|
+
var catalogCardShellClass = cn(
|
|
5581
|
+
"group relative box-border flex flex-col overflow-hidden rounded-2xl px-4 pb-4 pt-4 text-left font-normal",
|
|
5582
|
+
INTEGRATION_CATALOG_CARD_HEIGHT_CLASS,
|
|
5583
|
+
TIMBAL_V2_ELEVATED_SURFACE,
|
|
5584
|
+
"transition-opacity duration-200 ease-out"
|
|
5585
|
+
);
|
|
5586
|
+
var catalogCardInteractiveClass = cn(
|
|
5587
|
+
catalogCardShellClass,
|
|
5588
|
+
"cursor-pointer bg-transparent hover:bg-transparent active:bg-transparent",
|
|
5589
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/15 focus-visible:ring-offset-2 focus-visible:ring-offset-background"
|
|
5590
|
+
);
|
|
5591
|
+
var catalogCardMutedClass = cn(
|
|
5592
|
+
"border-border/60 saturate-[0.72]",
|
|
5593
|
+
"from-muted/80 to-muted/50 dark:border-white/[0.06] dark:from-white/[0.04] dark:to-white/[0.02]"
|
|
5594
|
+
);
|
|
5595
|
+
var logoShellClass = cn(
|
|
5596
|
+
"relative flex size-10 shrink-0 items-center justify-center overflow-hidden rounded-xl",
|
|
5597
|
+
TIMBAL_V2_LOGO_TILE
|
|
5598
|
+
);
|
|
5599
|
+
var IntegrationCard = ({
|
|
5600
|
+
name,
|
|
5601
|
+
description,
|
|
5602
|
+
logo,
|
|
5603
|
+
badge,
|
|
5604
|
+
status = "available",
|
|
5605
|
+
action,
|
|
5606
|
+
onClick,
|
|
5607
|
+
ariaLabel,
|
|
5608
|
+
className
|
|
5609
|
+
}) => {
|
|
5610
|
+
const titleId = (0, import_react41.useId)();
|
|
5611
|
+
const locked = status === "locked";
|
|
5612
|
+
const dimmed = status === "disabled" || locked;
|
|
5613
|
+
const body = /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "flex h-full min-h-0 flex-col", children: [
|
|
5614
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "flex shrink-0 items-start gap-3 pr-2", children: [
|
|
5615
|
+
logo ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: logoShellClass, "aria-hidden": Boolean(ariaLabel), children: logo }) : null,
|
|
5616
|
+
/* @__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: [
|
|
5617
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "min-w-0", children: [
|
|
5618
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
5619
|
+
"h4",
|
|
5620
|
+
{
|
|
5621
|
+
id: onClick && !action ? void 0 : titleId,
|
|
5622
|
+
className: "truncate text-sm font-normal leading-snug text-foreground",
|
|
5623
|
+
children: name
|
|
5624
|
+
}
|
|
5625
|
+
),
|
|
5626
|
+
statusLabel[status] ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("p", { className: "mt-0.5 text-xs text-muted-foreground", children: statusLabel[status] }) : null
|
|
5627
|
+
] }),
|
|
5628
|
+
badge ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "shrink-0", children: badge }) : null
|
|
5629
|
+
] }) })
|
|
5630
|
+
] }),
|
|
5631
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
5632
|
+
"p",
|
|
5633
|
+
{
|
|
5634
|
+
className: cn(
|
|
5635
|
+
"mt-3 line-clamp-3 shrink-0 text-sm leading-relaxed text-muted-foreground",
|
|
5636
|
+
dimmed && "text-muted-foreground/80"
|
|
5637
|
+
),
|
|
5638
|
+
children: description
|
|
5639
|
+
}
|
|
5640
|
+
) : null,
|
|
5641
|
+
action ? /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_jsx_runtime52.Fragment, { children: [
|
|
5642
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "min-h-0 flex-1", "aria-hidden": true }),
|
|
5643
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "relative mt-3 shrink-0", children: action })
|
|
5644
|
+
] }) : null
|
|
5645
|
+
] });
|
|
5646
|
+
const shellClass3 = cn(
|
|
5647
|
+
catalogCardShellClass,
|
|
5648
|
+
dimmed && catalogCardMutedClass,
|
|
5649
|
+
locked && "cursor-default opacity-75",
|
|
5650
|
+
className
|
|
5651
|
+
);
|
|
5652
|
+
if (onClick && !action) {
|
|
5653
|
+
return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
5654
|
+
"button",
|
|
5655
|
+
{
|
|
5656
|
+
type: "button",
|
|
5657
|
+
onClick,
|
|
5658
|
+
disabled: locked,
|
|
5659
|
+
"aria-label": ariaLabel,
|
|
5660
|
+
className: cn(
|
|
5661
|
+
catalogCardInteractiveClass,
|
|
5662
|
+
dimmed && catalogCardMutedClass,
|
|
5663
|
+
locked && "cursor-default opacity-75",
|
|
5664
|
+
className
|
|
5665
|
+
),
|
|
5666
|
+
children: body
|
|
5667
|
+
}
|
|
5668
|
+
);
|
|
5669
|
+
}
|
|
5670
|
+
return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("article", { className: shellClass3, "aria-labelledby": titleId, children: body });
|
|
5671
|
+
};
|
|
5672
|
+
|
|
5673
|
+
// src/app/integrations/IntegrationsEmptyState.tsx
|
|
5674
|
+
var import_react42 = require("react");
|
|
5675
|
+
var import_jsx_runtime53 = require("react/jsx-runtime");
|
|
5676
|
+
var IntegrationsEmptyState = ({
|
|
5677
|
+
title = "No integrations yet",
|
|
5678
|
+
description = "Connect a provider to start syncing data and powering your workforce.",
|
|
5679
|
+
icon,
|
|
5680
|
+
action,
|
|
5681
|
+
className
|
|
5682
|
+
}) => {
|
|
5683
|
+
const titleId = (0, import_react42.useId)();
|
|
5684
|
+
return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
|
|
5685
|
+
"section",
|
|
5686
|
+
{
|
|
5687
|
+
className: cn(
|
|
5688
|
+
"flex flex-col items-center justify-center gap-3 rounded-2xl px-6 py-14 text-center",
|
|
5689
|
+
TIMBAL_V2_ELEVATED_SURFACE,
|
|
5690
|
+
className
|
|
5691
|
+
),
|
|
5692
|
+
"aria-labelledby": titleId,
|
|
5693
|
+
children: [
|
|
5694
|
+
icon ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
5695
|
+
"span",
|
|
5696
|
+
{
|
|
5697
|
+
className: cn(
|
|
5698
|
+
"flex size-14 items-center justify-center overflow-hidden rounded-2xl",
|
|
5699
|
+
TIMBAL_V2_LOGO_TILE,
|
|
5700
|
+
"text-muted-foreground"
|
|
5701
|
+
),
|
|
5702
|
+
"aria-hidden": true,
|
|
5703
|
+
children: icon
|
|
5704
|
+
}
|
|
5705
|
+
) : null,
|
|
5706
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)("h3", { id: titleId, className: "text-base font-normal text-foreground", children: title }),
|
|
5707
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { className: "max-w-sm text-sm text-muted-foreground", children: description }) : null,
|
|
5708
|
+
action ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "mt-1", children: action }) : null
|
|
5709
|
+
]
|
|
5710
|
+
}
|
|
5711
|
+
);
|
|
5712
|
+
};
|
|
5713
|
+
|
|
5714
|
+
// src/app/integrations/PlanBadge.tsx
|
|
5715
|
+
var import_jsx_runtime54 = require("react/jsx-runtime");
|
|
5716
|
+
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";
|
|
5717
|
+
var PlanBadge = ({ children, className }) => /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: cn(planBadgeClass, className), children });
|
|
5718
|
+
|
|
5719
|
+
// src/app/integrations/ConnectionRow.tsx
|
|
5720
|
+
var import_jsx_runtime55 = require("react/jsx-runtime");
|
|
5721
|
+
var logoShellClass2 = cn(
|
|
5722
|
+
"flex size-9 shrink-0 items-center justify-center overflow-hidden rounded-lg",
|
|
5723
|
+
TIMBAL_V2_LOGO_TILE
|
|
5724
|
+
);
|
|
5725
|
+
var ConnectionRow = ({
|
|
5726
|
+
name,
|
|
5727
|
+
logo,
|
|
5728
|
+
meta,
|
|
5729
|
+
badge,
|
|
5730
|
+
action,
|
|
5731
|
+
onClick,
|
|
5732
|
+
ariaLabel,
|
|
5733
|
+
className
|
|
5734
|
+
}) => {
|
|
5735
|
+
const inner = /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
|
|
5736
|
+
logo ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: logoShellClass2, children: logo }) : null,
|
|
5737
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
5738
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)("p", { className: "truncate text-sm font-normal text-foreground", children: name }),
|
|
5739
|
+
meta ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("p", { className: "truncate text-xs text-muted-foreground", children: meta }) : null
|
|
5740
|
+
] }),
|
|
5741
|
+
badge ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "shrink-0", children: badge }) : null,
|
|
5742
|
+
action ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "shrink-0", children: action }) : null
|
|
5743
|
+
] });
|
|
5744
|
+
const rowClass2 = cn(
|
|
5745
|
+
"flex w-full items-center gap-3 px-4 py-3 text-left",
|
|
5746
|
+
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",
|
|
5747
|
+
className
|
|
5748
|
+
);
|
|
5749
|
+
if (onClick) {
|
|
5750
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
5751
|
+
"button",
|
|
5752
|
+
{
|
|
5753
|
+
type: "button",
|
|
5754
|
+
role: "listitem",
|
|
5755
|
+
onClick,
|
|
5756
|
+
"aria-label": ariaLabel,
|
|
5757
|
+
className: rowClass2,
|
|
5758
|
+
children: inner
|
|
5759
|
+
}
|
|
5760
|
+
);
|
|
5761
|
+
}
|
|
5762
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { role: "listitem", className: rowClass2, children: inner });
|
|
5763
|
+
};
|
|
5764
|
+
var connectionRowListClass = cn(
|
|
5765
|
+
"overflow-hidden rounded-2xl",
|
|
5766
|
+
TIMBAL_V2_ELEVATED_SURFACE
|
|
5767
|
+
);
|
|
5768
|
+
|
|
5769
|
+
// src/app/integrations/ConnectionRowList.tsx
|
|
5770
|
+
var import_jsx_runtime56 = require("react/jsx-runtime");
|
|
5771
|
+
var ConnectionRowList = ({
|
|
5772
|
+
children,
|
|
5773
|
+
"aria-label": ariaLabel = "Connected integrations",
|
|
5774
|
+
className
|
|
5775
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
5776
|
+
"div",
|
|
5777
|
+
{
|
|
5778
|
+
role: "list",
|
|
5779
|
+
"aria-label": ariaLabel,
|
|
5780
|
+
className: cn(connectionRowListClass, "divide-y divide-border", className),
|
|
5781
|
+
children
|
|
5782
|
+
}
|
|
5783
|
+
);
|
|
5784
|
+
|
|
5785
|
+
// src/ui/pill-segmented-tabs.tsx
|
|
5786
|
+
var import_react43 = require("react");
|
|
5787
|
+
var import_react44 = require("motion/react");
|
|
5788
|
+
|
|
5789
|
+
// src/design/pill-segmented-classes.ts
|
|
5790
|
+
var pillSegmentedTrackBase = "inline-flex w-fit max-w-max shrink-0 self-start items-center rounded-full";
|
|
5791
|
+
var pillSegmentedTrackSurface = cn(
|
|
5792
|
+
"bg-pill-segmented-track border border-[var(--pill-segmented-track-border)]",
|
|
5793
|
+
"shadow-[var(--pill-segmented-track-shadow)]"
|
|
5794
|
+
);
|
|
5795
|
+
var pillSegmentedTrackClass = cn(
|
|
5796
|
+
pillSegmentedTrackBase,
|
|
5797
|
+
pillSegmentedTrackSurface,
|
|
5798
|
+
"gap-1 p-1"
|
|
5799
|
+
);
|
|
5800
|
+
var pillSegmentedTrackFlushClass = cn(
|
|
5801
|
+
pillSegmentedTrackBase,
|
|
5802
|
+
pillSegmentedTrackSurface,
|
|
5803
|
+
"h-[var(--studio-chrome-pill-height)] items-center gap-0.5 overflow-visible p-0.5"
|
|
5804
|
+
);
|
|
5805
|
+
var pillSegmentedSegmentClass = cn(
|
|
5806
|
+
"relative flex items-center gap-1.5 rounded-full px-4 py-1.5 text-xs font-normal transition-colors"
|
|
5807
|
+
);
|
|
5808
|
+
var pillSegmentedFlushSegmentClass = cn(
|
|
4673
5809
|
"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
5810
|
"text-sm font-normal leading-tight transition-colors"
|
|
4675
5811
|
);
|
|
@@ -4681,7 +5817,7 @@ var pillSegmentedActiveIndicatorClass = cn(
|
|
|
4681
5817
|
);
|
|
4682
5818
|
|
|
4683
5819
|
// src/ui/pill-segmented-tabs.tsx
|
|
4684
|
-
var
|
|
5820
|
+
var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
4685
5821
|
var PillTab = ({
|
|
4686
5822
|
tabKey,
|
|
4687
5823
|
label,
|
|
@@ -4692,10 +5828,10 @@ var PillTab = ({
|
|
|
4692
5828
|
segmentClassName,
|
|
4693
5829
|
animateIndicator
|
|
4694
5830
|
}) => {
|
|
4695
|
-
const handlePress = (0,
|
|
5831
|
+
const handlePress = (0, import_react43.useCallback)(() => {
|
|
4696
5832
|
if (!disabled) onSelect(tabKey);
|
|
4697
5833
|
}, [disabled, onSelect, tabKey]);
|
|
4698
|
-
return /* @__PURE__ */ (0,
|
|
5834
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
|
|
4699
5835
|
"button",
|
|
4700
5836
|
{
|
|
4701
5837
|
type: "button",
|
|
@@ -4708,15 +5844,15 @@ var PillTab = ({
|
|
|
4708
5844
|
!disabled && (isActive ? "text-foreground" : "text-muted-foreground hover:text-foreground")
|
|
4709
5845
|
),
|
|
4710
5846
|
children: [
|
|
4711
|
-
isActive && animateIndicator ? /* @__PURE__ */ (0,
|
|
4712
|
-
|
|
5847
|
+
isActive && animateIndicator ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
5848
|
+
import_react44.motion.div,
|
|
4713
5849
|
{
|
|
4714
5850
|
layoutId,
|
|
4715
5851
|
className: pillSegmentedActiveIndicatorClass,
|
|
4716
5852
|
transition: { type: "spring", duration: 0.3, bounce: 0.15 }
|
|
4717
5853
|
}
|
|
4718
|
-
) : isActive ? /* @__PURE__ */ (0,
|
|
4719
|
-
/* @__PURE__ */ (0,
|
|
5854
|
+
) : isActive ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: pillSegmentedActiveIndicatorClass, "aria-hidden": true }) : null,
|
|
5855
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "relative z-10 whitespace-nowrap", children: label })
|
|
4720
5856
|
]
|
|
4721
5857
|
}
|
|
4722
5858
|
);
|
|
@@ -4730,13 +5866,13 @@ var PillSegmentedTabs = ({
|
|
|
4730
5866
|
layoutId: layoutIdProp,
|
|
4731
5867
|
"aria-label": ariaLabel
|
|
4732
5868
|
}) => {
|
|
4733
|
-
const reactId = (0,
|
|
5869
|
+
const reactId = (0, import_react43.useId)();
|
|
4734
5870
|
const layoutId = layoutIdProp ?? `pill-segmented-${reactId.replace(/:/g, "")}`;
|
|
4735
|
-
const reducedMotion = (0,
|
|
5871
|
+
const reducedMotion = (0, import_react44.useReducedMotion)();
|
|
4736
5872
|
const isFlush = trackVariant === "flush";
|
|
4737
5873
|
const trackClass2 = isFlush ? pillSegmentedTrackFlushClass : pillSegmentedTrackClass;
|
|
4738
5874
|
const segmentClassName = isFlush ? pillSegmentedFlushSegmentClass : pillSegmentedSegmentClass;
|
|
4739
|
-
return /* @__PURE__ */ (0,
|
|
5875
|
+
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
5876
|
PillTab,
|
|
4741
5877
|
{
|
|
4742
5878
|
tabKey: tab.key,
|
|
@@ -4751,10 +5887,10 @@ var PillSegmentedTabs = ({
|
|
|
4751
5887
|
tab.key
|
|
4752
5888
|
)) });
|
|
4753
5889
|
};
|
|
4754
|
-
var MemoPillSegmentedTabs = (0,
|
|
5890
|
+
var MemoPillSegmentedTabs = (0, import_react43.memo)(PillSegmentedTabs);
|
|
4755
5891
|
|
|
4756
5892
|
// src/app/navigation/SubNav.tsx
|
|
4757
|
-
var
|
|
5893
|
+
var import_jsx_runtime58 = require("react/jsx-runtime");
|
|
4758
5894
|
var SubNav = ({
|
|
4759
5895
|
items,
|
|
4760
5896
|
activeId,
|
|
@@ -4763,7 +5899,7 @@ var SubNav = ({
|
|
|
4763
5899
|
"aria-label": ariaLabel = "Section navigation",
|
|
4764
5900
|
layoutId
|
|
4765
5901
|
}) => {
|
|
4766
|
-
return /* @__PURE__ */ (0,
|
|
5902
|
+
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
5903
|
PillSegmentedTabs,
|
|
4768
5904
|
{
|
|
4769
5905
|
value: activeId,
|
|
@@ -4777,13 +5913,13 @@ var SubNav = ({
|
|
|
4777
5913
|
};
|
|
4778
5914
|
|
|
4779
5915
|
// src/app/navigation/Breadcrumbs.tsx
|
|
4780
|
-
var
|
|
5916
|
+
var import_jsx_runtime59 = require("react/jsx-runtime");
|
|
4781
5917
|
var Breadcrumbs = ({ items, className }) => {
|
|
4782
|
-
return /* @__PURE__ */ (0,
|
|
5918
|
+
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
5919
|
const isLast = index === items.length - 1;
|
|
4784
|
-
return /* @__PURE__ */ (0,
|
|
4785
|
-
index > 0 ? /* @__PURE__ */ (0,
|
|
4786
|
-
isLast ? /* @__PURE__ */ (0,
|
|
5920
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("li", { className: "inline-flex items-center gap-1.5", children: [
|
|
5921
|
+
index > 0 ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "text-muted-foreground/50", "aria-hidden": true, children: "/" }) : null,
|
|
5922
|
+
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
5923
|
"button",
|
|
4788
5924
|
{
|
|
4789
5925
|
type: "button",
|
|
@@ -4797,7 +5933,7 @@ var Breadcrumbs = ({ items, className }) => {
|
|
|
4797
5933
|
};
|
|
4798
5934
|
|
|
4799
5935
|
// src/app/forms/Field.tsx
|
|
4800
|
-
var
|
|
5936
|
+
var import_jsx_runtime60 = require("react/jsx-runtime");
|
|
4801
5937
|
var Field = ({
|
|
4802
5938
|
label,
|
|
4803
5939
|
hint,
|
|
@@ -4806,11 +5942,11 @@ var Field = ({
|
|
|
4806
5942
|
className,
|
|
4807
5943
|
htmlFor
|
|
4808
5944
|
}) => {
|
|
4809
|
-
return /* @__PURE__ */ (0,
|
|
4810
|
-
/* @__PURE__ */ (0,
|
|
5945
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: cn("aui-app-field", appFieldClass, className), children: [
|
|
5946
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("label", { className: appFieldLabelClass, htmlFor, children: label }),
|
|
4811
5947
|
children,
|
|
4812
|
-
hint && !error ? /* @__PURE__ */ (0,
|
|
4813
|
-
error ? /* @__PURE__ */ (0,
|
|
5948
|
+
hint && !error ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("p", { className: appFieldHintClass, children: hint }) : null,
|
|
5949
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("p", { className: "text-xs text-destructive", role: "alert", children: error }) : null
|
|
4814
5950
|
] });
|
|
4815
5951
|
};
|
|
4816
5952
|
var FieldInput = ({
|
|
@@ -4823,7 +5959,7 @@ var FieldInput = ({
|
|
|
4823
5959
|
...inputProps
|
|
4824
5960
|
}) => {
|
|
4825
5961
|
const inputId = id ?? inputProps.name;
|
|
4826
|
-
return /* @__PURE__ */ (0,
|
|
5962
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
4827
5963
|
Field,
|
|
4828
5964
|
{
|
|
4829
5965
|
label,
|
|
@@ -4831,7 +5967,7 @@ var FieldInput = ({
|
|
|
4831
5967
|
error,
|
|
4832
5968
|
htmlFor: inputId,
|
|
4833
5969
|
className: fieldClassName,
|
|
4834
|
-
children: /* @__PURE__ */ (0,
|
|
5970
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
4835
5971
|
"input",
|
|
4836
5972
|
{
|
|
4837
5973
|
id: inputId,
|
|
@@ -4845,7 +5981,7 @@ var FieldInput = ({
|
|
|
4845
5981
|
};
|
|
4846
5982
|
|
|
4847
5983
|
// src/app/forms/FieldTextarea.tsx
|
|
4848
|
-
var
|
|
5984
|
+
var import_jsx_runtime61 = require("react/jsx-runtime");
|
|
4849
5985
|
var textareaClass = cn(
|
|
4850
5986
|
appInputClass,
|
|
4851
5987
|
"min-h-[5.5rem] resize-y py-2.5 leading-relaxed"
|
|
@@ -4860,7 +5996,7 @@ var FieldTextarea = ({
|
|
|
4860
5996
|
...props
|
|
4861
5997
|
}) => {
|
|
4862
5998
|
const textareaId = id ?? props.name;
|
|
4863
|
-
return /* @__PURE__ */ (0,
|
|
5999
|
+
return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
4864
6000
|
Field,
|
|
4865
6001
|
{
|
|
4866
6002
|
label,
|
|
@@ -4868,7 +6004,7 @@ var FieldTextarea = ({
|
|
|
4868
6004
|
error,
|
|
4869
6005
|
htmlFor: textareaId,
|
|
4870
6006
|
className: fieldClassName,
|
|
4871
|
-
children: /* @__PURE__ */ (0,
|
|
6007
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
4872
6008
|
"textarea",
|
|
4873
6009
|
{
|
|
4874
6010
|
id: textareaId,
|
|
@@ -4883,7 +6019,7 @@ var FieldTextarea = ({
|
|
|
4883
6019
|
|
|
4884
6020
|
// src/app/forms/FieldSelect.tsx
|
|
4885
6021
|
var import_lucide_react10 = require("lucide-react");
|
|
4886
|
-
var
|
|
6022
|
+
var import_jsx_runtime62 = require("react/jsx-runtime");
|
|
4887
6023
|
var selectWrapClass = "relative";
|
|
4888
6024
|
var selectClass = cn(
|
|
4889
6025
|
appInputClass,
|
|
@@ -4900,7 +6036,7 @@ var FieldSelect = ({
|
|
|
4900
6036
|
...props
|
|
4901
6037
|
}) => {
|
|
4902
6038
|
const selectId = id ?? props.name;
|
|
4903
|
-
return /* @__PURE__ */ (0,
|
|
6039
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
4904
6040
|
Field,
|
|
4905
6041
|
{
|
|
4906
6042
|
label,
|
|
@@ -4908,8 +6044,8 @@ var FieldSelect = ({
|
|
|
4908
6044
|
error,
|
|
4909
6045
|
htmlFor: selectId,
|
|
4910
6046
|
className: fieldClassName,
|
|
4911
|
-
children: /* @__PURE__ */ (0,
|
|
4912
|
-
/* @__PURE__ */ (0,
|
|
6047
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: selectWrapClass, children: [
|
|
6048
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
4913
6049
|
"select",
|
|
4914
6050
|
{
|
|
4915
6051
|
id: selectId,
|
|
@@ -4919,7 +6055,7 @@ var FieldSelect = ({
|
|
|
4919
6055
|
children
|
|
4920
6056
|
}
|
|
4921
6057
|
),
|
|
4922
|
-
/* @__PURE__ */ (0,
|
|
6058
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
4923
6059
|
import_lucide_react10.ChevronDownIcon,
|
|
4924
6060
|
{
|
|
4925
6061
|
className: "pointer-events-none absolute top-1/2 right-3 size-4 -translate-y-1/2 text-muted-foreground",
|
|
@@ -4932,7 +6068,7 @@ var FieldSelect = ({
|
|
|
4932
6068
|
};
|
|
4933
6069
|
|
|
4934
6070
|
// src/app/forms/FieldSwitch.tsx
|
|
4935
|
-
var
|
|
6071
|
+
var import_jsx_runtime63 = require("react/jsx-runtime");
|
|
4936
6072
|
var trackClass = cn(
|
|
4937
6073
|
"relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-[background,box-shadow,border-color] duration-200",
|
|
4938
6074
|
"peer-focus-visible:ring-2 peer-focus-visible:ring-foreground/10",
|
|
@@ -4953,7 +6089,7 @@ var FieldSwitch = ({
|
|
|
4953
6089
|
...props
|
|
4954
6090
|
}) => {
|
|
4955
6091
|
const inputId = id ?? props.name ?? "switch";
|
|
4956
|
-
return /* @__PURE__ */ (0,
|
|
6092
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(
|
|
4957
6093
|
"label",
|
|
4958
6094
|
{
|
|
4959
6095
|
className: cn(
|
|
@@ -4962,8 +6098,8 @@ var FieldSwitch = ({
|
|
|
4962
6098
|
),
|
|
4963
6099
|
htmlFor: inputId,
|
|
4964
6100
|
children: [
|
|
4965
|
-
/* @__PURE__ */ (0,
|
|
4966
|
-
/* @__PURE__ */ (0,
|
|
6101
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("span", { className: "relative mt-0.5", children: [
|
|
6102
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
4967
6103
|
"input",
|
|
4968
6104
|
{
|
|
4969
6105
|
id: inputId,
|
|
@@ -4973,11 +6109,11 @@ var FieldSwitch = ({
|
|
|
4973
6109
|
...props
|
|
4974
6110
|
}
|
|
4975
6111
|
),
|
|
4976
|
-
/* @__PURE__ */ (0,
|
|
6112
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: trackClass, "aria-hidden": true, children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: thumbClass }) })
|
|
4977
6113
|
] }),
|
|
4978
|
-
/* @__PURE__ */ (0,
|
|
4979
|
-
/* @__PURE__ */ (0,
|
|
4980
|
-
description ? /* @__PURE__ */ (0,
|
|
6114
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("span", { className: "flex min-w-0 flex-col gap-0.5", children: [
|
|
6115
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "text-sm font-medium text-foreground", children: label }),
|
|
6116
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "text-xs text-muted-foreground", children: description }) : null
|
|
4981
6117
|
] })
|
|
4982
6118
|
]
|
|
4983
6119
|
}
|
|
@@ -4986,13 +6122,13 @@ var FieldSwitch = ({
|
|
|
4986
6122
|
|
|
4987
6123
|
// src/app/forms/SearchInput.tsx
|
|
4988
6124
|
var import_lucide_react11 = require("lucide-react");
|
|
4989
|
-
var
|
|
6125
|
+
var import_jsx_runtime64 = require("react/jsx-runtime");
|
|
4990
6126
|
var SearchInput = ({
|
|
4991
6127
|
className,
|
|
4992
6128
|
placeholder = "Search\u2026",
|
|
4993
6129
|
...props
|
|
4994
6130
|
}) => {
|
|
4995
|
-
return /* @__PURE__ */ (0,
|
|
6131
|
+
return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(
|
|
4996
6132
|
"label",
|
|
4997
6133
|
{
|
|
4998
6134
|
className: cn(
|
|
@@ -5001,8 +6137,8 @@ var SearchInput = ({
|
|
|
5001
6137
|
className
|
|
5002
6138
|
),
|
|
5003
6139
|
children: [
|
|
5004
|
-
/* @__PURE__ */ (0,
|
|
5005
|
-
/* @__PURE__ */ (0,
|
|
6140
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_lucide_react11.SearchIcon, { className: "size-4 shrink-0 text-muted-foreground", "aria-hidden": true }),
|
|
6141
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
|
|
5006
6142
|
"input",
|
|
5007
6143
|
{
|
|
5008
6144
|
type: "search",
|
|
@@ -5017,18 +6153,18 @@ var SearchInput = ({
|
|
|
5017
6153
|
};
|
|
5018
6154
|
|
|
5019
6155
|
// src/app/forms/FormSection.tsx
|
|
5020
|
-
var
|
|
6156
|
+
var import_jsx_runtime65 = require("react/jsx-runtime");
|
|
5021
6157
|
var FormSection = ({ title, children, className }) => {
|
|
5022
|
-
return /* @__PURE__ */ (0,
|
|
5023
|
-
title ? /* @__PURE__ */ (0,
|
|
5024
|
-
/* @__PURE__ */ (0,
|
|
6158
|
+
return /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("fieldset", { className: cn("aui-app-form-section", appSectionClass, "border-0 p-0", className), children: [
|
|
6159
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("legend", { className: cn(appSectionTitleClass, "mb-3 px-0"), children: title }) : null,
|
|
6160
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("div", { className: "flex flex-col gap-4", children })
|
|
5025
6161
|
] });
|
|
5026
6162
|
};
|
|
5027
6163
|
|
|
5028
6164
|
// src/app/data/FilterBar.tsx
|
|
5029
|
-
var
|
|
6165
|
+
var import_jsx_runtime66 = require("react/jsx-runtime");
|
|
5030
6166
|
var FilterBar = ({ children, className }) => {
|
|
5031
|
-
return /* @__PURE__ */ (0,
|
|
6167
|
+
return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
|
|
5032
6168
|
"div",
|
|
5033
6169
|
{
|
|
5034
6170
|
className: cn("aui-app-filter-bar", appFilterBarClass, className),
|
|
@@ -5040,9 +6176,9 @@ var FilterBar = ({ children, className }) => {
|
|
|
5040
6176
|
};
|
|
5041
6177
|
|
|
5042
6178
|
// src/app/data/DataTable.tsx
|
|
5043
|
-
var
|
|
6179
|
+
var import_react45 = require("react");
|
|
5044
6180
|
var import_lucide_react12 = require("lucide-react");
|
|
5045
|
-
var
|
|
6181
|
+
var import_jsx_runtime67 = require("react/jsx-runtime");
|
|
5046
6182
|
var shellClass2 = "overflow-hidden rounded-xl border border-border bg-card shadow-card";
|
|
5047
6183
|
var tableClass = "w-full border-collapse bg-transparent text-sm";
|
|
5048
6184
|
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 +6218,12 @@ function SortIndicator({
|
|
|
5082
6218
|
}) {
|
|
5083
6219
|
const iconClass = "size-3.5 shrink-0 opacity-60 group-hover:opacity-100";
|
|
5084
6220
|
if (!active) {
|
|
5085
|
-
return /* @__PURE__ */ (0,
|
|
6221
|
+
return /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(import_lucide_react12.ArrowUpDownIcon, { className: iconClass, "aria-hidden": true });
|
|
5086
6222
|
}
|
|
5087
6223
|
if (direction === "desc") {
|
|
5088
|
-
return /* @__PURE__ */ (0,
|
|
6224
|
+
return /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(import_lucide_react12.ArrowDownIcon, { className: iconClass, "aria-hidden": true });
|
|
5089
6225
|
}
|
|
5090
|
-
return /* @__PURE__ */ (0,
|
|
6226
|
+
return /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(import_lucide_react12.ArrowUpIcon, { className: iconClass, "aria-hidden": true });
|
|
5091
6227
|
}
|
|
5092
6228
|
function DataTable({
|
|
5093
6229
|
columns,
|
|
@@ -5108,7 +6244,7 @@ function DataTable({
|
|
|
5108
6244
|
dense = false,
|
|
5109
6245
|
caption
|
|
5110
6246
|
}) {
|
|
5111
|
-
const [uncontrolledSort, setUncontrolledSort] = (0,
|
|
6247
|
+
const [uncontrolledSort, setUncontrolledSort] = (0, import_react45.useState)(
|
|
5112
6248
|
defaultSort
|
|
5113
6249
|
);
|
|
5114
6250
|
const isSortControlled = sortProp !== void 0;
|
|
@@ -5119,7 +6255,7 @@ function DataTable({
|
|
|
5119
6255
|
}
|
|
5120
6256
|
onSortChange?.(next);
|
|
5121
6257
|
};
|
|
5122
|
-
const sortedRows = (0,
|
|
6258
|
+
const sortedRows = (0, import_react45.useMemo)(() => {
|
|
5123
6259
|
if (!sort) return rows;
|
|
5124
6260
|
const column = columns.find((col) => col.id === sort.columnId);
|
|
5125
6261
|
if (!column?.sortable) return rows;
|
|
@@ -5138,28 +6274,28 @@ function DataTable({
|
|
|
5138
6274
|
const cellPad = dense ? "px-3 py-2" : void 0;
|
|
5139
6275
|
const headPad = dense ? "px-3 py-2" : void 0;
|
|
5140
6276
|
if (rows.length === 0 && emptyMode === "replace") {
|
|
5141
|
-
return /* @__PURE__ */ (0,
|
|
6277
|
+
return /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(EmptyState, { title: emptyTitle, description: emptyDescription, className });
|
|
5142
6278
|
}
|
|
5143
6279
|
const rowCountText = rowCountLabel?.(sortedRows.length) ?? `${sortedRows.length} row${sortedRows.length === 1 ? "" : "s"}`;
|
|
5144
6280
|
const hasFoot = Boolean((showRowCount || footer) && sortedRows.length > 0);
|
|
5145
|
-
return /* @__PURE__ */ (0,
|
|
5146
|
-
caption ? /* @__PURE__ */ (0,
|
|
5147
|
-
/* @__PURE__ */ (0,
|
|
6281
|
+
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: [
|
|
6282
|
+
caption ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("caption", { className: "sr-only", children: caption }) : null,
|
|
6283
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("thead", { className: cn(stickyHeader && stickyHeadClass), children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("tr", { children: columns.map((col) => {
|
|
5148
6284
|
const isSorted = sort?.columnId === col.id;
|
|
5149
6285
|
const ariaSort = col.sortable ? isSorted ? sort.direction === "asc" ? "ascending" : "descending" : "none" : void 0;
|
|
5150
|
-
const headerContent = col.sortable ? /* @__PURE__ */ (0,
|
|
6286
|
+
const headerContent = col.sortable ? /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(
|
|
5151
6287
|
"button",
|
|
5152
6288
|
{
|
|
5153
6289
|
type: "button",
|
|
5154
6290
|
className: sortButtonClass,
|
|
5155
6291
|
onClick: () => setSort(nextSort(sort, col.id)),
|
|
5156
6292
|
children: [
|
|
5157
|
-
/* @__PURE__ */ (0,
|
|
5158
|
-
/* @__PURE__ */ (0,
|
|
6293
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { className: "truncate", children: col.header }),
|
|
6294
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)(SortIndicator, { active: Boolean(isSorted), direction: sort?.direction })
|
|
5159
6295
|
]
|
|
5160
6296
|
}
|
|
5161
6297
|
) : col.header;
|
|
5162
|
-
return /* @__PURE__ */ (0,
|
|
6298
|
+
return /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
5163
6299
|
"th",
|
|
5164
6300
|
{
|
|
5165
6301
|
scope: "col",
|
|
@@ -5175,10 +6311,10 @@ function DataTable({
|
|
|
5175
6311
|
col.id
|
|
5176
6312
|
);
|
|
5177
6313
|
}) }) }),
|
|
5178
|
-
/* @__PURE__ */ (0,
|
|
5179
|
-
/* @__PURE__ */ (0,
|
|
5180
|
-
emptyDescription ? /* @__PURE__ */ (0,
|
|
5181
|
-
] }) }) }) : sortedRows.map((row) => /* @__PURE__ */ (0,
|
|
6314
|
+
/* @__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: [
|
|
6315
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("p", { className: "font-medium text-foreground", children: emptyTitle }),
|
|
6316
|
+
emptyDescription ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("p", { className: "max-w-sm text-muted-foreground", children: emptyDescription }) : null
|
|
6317
|
+
] }) }) }) : sortedRows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
5182
6318
|
"tr",
|
|
5183
6319
|
{
|
|
5184
6320
|
className: rowClass,
|
|
@@ -5192,7 +6328,7 @@ function DataTable({
|
|
|
5192
6328
|
} : void 0,
|
|
5193
6329
|
tabIndex: onRowClick ? 0 : void 0,
|
|
5194
6330
|
role: onRowClick ? "button" : void 0,
|
|
5195
|
-
children: columns.map((col) => /* @__PURE__ */ (0,
|
|
6331
|
+
children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
5196
6332
|
"td",
|
|
5197
6333
|
{
|
|
5198
6334
|
className: cn(
|
|
@@ -5208,7 +6344,7 @@ function DataTable({
|
|
|
5208
6344
|
},
|
|
5209
6345
|
getRowKey(row)
|
|
5210
6346
|
)) }),
|
|
5211
|
-
hasFoot ? /* @__PURE__ */ (0,
|
|
6347
|
+
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
6348
|
"div",
|
|
5213
6349
|
{
|
|
5214
6350
|
className: cn(
|
|
@@ -5216,7 +6352,7 @@ function DataTable({
|
|
|
5216
6352
|
showRowCount && footer ? "justify-between" : "justify-start"
|
|
5217
6353
|
),
|
|
5218
6354
|
children: [
|
|
5219
|
-
showRowCount ? /* @__PURE__ */ (0,
|
|
6355
|
+
showRowCount ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { children: rowCountText }) : null,
|
|
5220
6356
|
footer
|
|
5221
6357
|
]
|
|
5222
6358
|
}
|
|
@@ -5225,27 +6361,415 @@ function DataTable({
|
|
|
5225
6361
|
}
|
|
5226
6362
|
|
|
5227
6363
|
// src/app/data/ChartPanel.tsx
|
|
5228
|
-
var
|
|
5229
|
-
|
|
6364
|
+
var import_react46 = require("react");
|
|
6365
|
+
|
|
6366
|
+
// src/app/data/metrics-shared.tsx
|
|
6367
|
+
var import_jsx_runtime68 = require("react/jsx-runtime");
|
|
6368
|
+
var metricCardShellClass = cn(
|
|
6369
|
+
studioIntegrationCardClass,
|
|
6370
|
+
"aui-app-metric-card shadow-none",
|
|
6371
|
+
"flex flex-col overflow-hidden"
|
|
6372
|
+
);
|
|
6373
|
+
var metricCardHeaderClass = "flex items-start justify-between gap-3 px-4 pb-1 pt-3";
|
|
6374
|
+
var metricTilesRowClass = "grid w-full min-w-0";
|
|
6375
|
+
var metricChartRegionClass = "relative min-h-0 w-full border-t border-border/40 pt-2";
|
|
6376
|
+
var metricChartPlotRegionClass = "relative min-h-0 w-full border-t border-border/40 px-0 pt-5 pb-3";
|
|
6377
|
+
var metricCellDividerClass = "border-r border-border/40";
|
|
6378
|
+
var MetricCardHeader = ({
|
|
6379
|
+
title,
|
|
6380
|
+
titleId,
|
|
6381
|
+
description,
|
|
6382
|
+
actions
|
|
6383
|
+
}) => {
|
|
6384
|
+
if (!title && !description && !actions) return null;
|
|
6385
|
+
return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("header", { className: metricCardHeaderClass, children: [
|
|
6386
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "min-w-0", children: [
|
|
6387
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("h3", { id: titleId, className: "text-base font-normal text-foreground", children: title }) : null,
|
|
6388
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
|
|
6389
|
+
] }),
|
|
6390
|
+
actions ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "shrink-0", children: actions }) : null
|
|
6391
|
+
] });
|
|
6392
|
+
};
|
|
6393
|
+
function metricTilesGridColsClass(n) {
|
|
6394
|
+
switch (n) {
|
|
6395
|
+
case 1:
|
|
6396
|
+
return "grid-cols-1";
|
|
6397
|
+
case 2:
|
|
6398
|
+
return "grid-cols-2";
|
|
6399
|
+
case 3:
|
|
6400
|
+
return "grid-cols-3";
|
|
6401
|
+
case 5:
|
|
6402
|
+
return "grid-cols-2 sm:grid-cols-5";
|
|
6403
|
+
case 6:
|
|
6404
|
+
return "grid-cols-2 sm:grid-cols-3 lg:grid-cols-6";
|
|
6405
|
+
default:
|
|
6406
|
+
return "grid-cols-2 md:grid-cols-4";
|
|
6407
|
+
}
|
|
6408
|
+
}
|
|
6409
|
+
|
|
6410
|
+
// src/app/data/ChartPanel.tsx
|
|
6411
|
+
var import_jsx_runtime69 = require("react/jsx-runtime");
|
|
5230
6412
|
var ChartPanel = ({
|
|
5231
6413
|
title,
|
|
6414
|
+
description,
|
|
5232
6415
|
artifact,
|
|
5233
6416
|
children,
|
|
5234
6417
|
actions,
|
|
6418
|
+
height = 300,
|
|
5235
6419
|
className
|
|
5236
6420
|
}) => {
|
|
5237
|
-
const
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
|
|
6421
|
+
const titleId = (0, import_react46.useId)();
|
|
6422
|
+
const resolvedTitle = title ?? artifact?.title;
|
|
6423
|
+
const hasHeader = Boolean(resolvedTitle || description || actions);
|
|
6424
|
+
const body = children ?? (artifact ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ChartArtifactView, { artifact, embedded: true, height }) : null);
|
|
6425
|
+
return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
|
|
6426
|
+
"section",
|
|
6427
|
+
{
|
|
6428
|
+
className: cn(metricCardShellClass, "aui-app-chart-panel", className),
|
|
6429
|
+
"aria-labelledby": resolvedTitle ? titleId : void 0,
|
|
6430
|
+
children: [
|
|
6431
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
6432
|
+
MetricCardHeader,
|
|
6433
|
+
{
|
|
6434
|
+
title: resolvedTitle,
|
|
6435
|
+
titleId,
|
|
6436
|
+
description,
|
|
6437
|
+
actions
|
|
6438
|
+
}
|
|
6439
|
+
),
|
|
6440
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
6441
|
+
"div",
|
|
6442
|
+
{
|
|
6443
|
+
className: cn(
|
|
6444
|
+
"relative min-h-0 w-full",
|
|
6445
|
+
hasHeader ? metricChartPlotRegionClass : "pt-2 pb-3"
|
|
6446
|
+
),
|
|
6447
|
+
children: body ?? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
6448
|
+
"div",
|
|
6449
|
+
{
|
|
6450
|
+
className: "flex items-center justify-center text-sm font-normal text-muted-foreground",
|
|
6451
|
+
style: { minHeight: height },
|
|
6452
|
+
role: "status",
|
|
6453
|
+
children: "No chart"
|
|
6454
|
+
}
|
|
6455
|
+
)
|
|
6456
|
+
}
|
|
6457
|
+
)
|
|
6458
|
+
]
|
|
6459
|
+
}
|
|
6460
|
+
);
|
|
6461
|
+
};
|
|
6462
|
+
|
|
6463
|
+
// src/app/data/MetricTile.tsx
|
|
6464
|
+
var import_jsx_runtime70 = require("react/jsx-runtime");
|
|
6465
|
+
var trendToneClass = {
|
|
6466
|
+
up: "border-border/80 bg-muted/40 text-muted-foreground",
|
|
6467
|
+
down: "border-border/80 bg-muted/40 text-muted-foreground",
|
|
6468
|
+
neutral: "border-border/80 bg-muted/30 text-muted-foreground"
|
|
6469
|
+
};
|
|
6470
|
+
var metricTileBaseClass = "relative flex min-w-0 flex-1 flex-col gap-1 px-4 py-3 text-left font-normal";
|
|
6471
|
+
var metricTileInteractiveClass = cn(
|
|
6472
|
+
metricTileBaseClass,
|
|
6473
|
+
"bg-transparent hover:bg-transparent active:bg-transparent",
|
|
6474
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-foreground/10"
|
|
6475
|
+
);
|
|
6476
|
+
var MetricTile = ({
|
|
6477
|
+
label,
|
|
6478
|
+
value,
|
|
6479
|
+
unit,
|
|
6480
|
+
trend,
|
|
6481
|
+
trendTone = "neutral",
|
|
6482
|
+
active = false,
|
|
6483
|
+
showDivider = false,
|
|
6484
|
+
onSelect,
|
|
6485
|
+
ariaLabel,
|
|
6486
|
+
className
|
|
6487
|
+
}) => {
|
|
6488
|
+
const content = /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(import_jsx_runtime70.Fragment, { children: [
|
|
6489
|
+
active ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
6490
|
+
"span",
|
|
6491
|
+
{
|
|
6492
|
+
"aria-hidden": true,
|
|
6493
|
+
className: "absolute inset-x-0 bottom-0 h-0.5 bg-foreground dark:bg-white"
|
|
6494
|
+
}
|
|
6495
|
+
) : null,
|
|
6496
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)("span", { className: "text-xs font-normal text-muted-foreground", children: label }),
|
|
6497
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("span", { className: "flex items-center gap-2", children: [
|
|
6498
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("span", { className: "flex items-baseline gap-1", children: [
|
|
6499
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)("span", { className: "text-2xl font-normal tracking-tight text-foreground tabular-nums", children: value }),
|
|
6500
|
+
unit ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("span", { className: "text-xs font-normal text-muted-foreground", children: unit }) : null
|
|
6501
|
+
] }),
|
|
6502
|
+
trend ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
6503
|
+
"span",
|
|
6504
|
+
{
|
|
6505
|
+
className: cn(
|
|
6506
|
+
"rounded-full border px-1.5 py-0.5 text-xs font-normal",
|
|
6507
|
+
trendToneClass[trendTone]
|
|
6508
|
+
),
|
|
6509
|
+
children: trend
|
|
6510
|
+
}
|
|
6511
|
+
) : null
|
|
6512
|
+
] })
|
|
5244
6513
|
] });
|
|
6514
|
+
const divider = showDivider ? metricCellDividerClass : void 0;
|
|
6515
|
+
if (onSelect) {
|
|
6516
|
+
return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
|
|
6517
|
+
"button",
|
|
6518
|
+
{
|
|
6519
|
+
type: "button",
|
|
6520
|
+
onClick: onSelect,
|
|
6521
|
+
"aria-pressed": active,
|
|
6522
|
+
"aria-label": ariaLabel,
|
|
6523
|
+
className: cn(metricTileInteractiveClass, divider, className),
|
|
6524
|
+
children: content
|
|
6525
|
+
}
|
|
6526
|
+
);
|
|
6527
|
+
}
|
|
6528
|
+
return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { className: cn(metricTileBaseClass, divider, className), children: content });
|
|
6529
|
+
};
|
|
6530
|
+
|
|
6531
|
+
// src/app/data/MetricRow.tsx
|
|
6532
|
+
var import_react47 = require("react");
|
|
6533
|
+
var import_jsx_runtime71 = require("react/jsx-runtime");
|
|
6534
|
+
var MetricRow = ({
|
|
6535
|
+
title,
|
|
6536
|
+
description,
|
|
6537
|
+
actions,
|
|
6538
|
+
metrics,
|
|
6539
|
+
activeMetricId,
|
|
6540
|
+
defaultActiveMetricId,
|
|
6541
|
+
onMetricChange,
|
|
6542
|
+
metricsAriaLabel = "Metrics",
|
|
6543
|
+
className
|
|
6544
|
+
}) => {
|
|
6545
|
+
const titleId = (0, import_react47.useId)();
|
|
6546
|
+
const selectable = onMetricChange != null || activeMetricId != null;
|
|
6547
|
+
const [internalId, setInternalId] = (0, import_react47.useState)(
|
|
6548
|
+
defaultActiveMetricId ?? metrics[0]?.id
|
|
6549
|
+
);
|
|
6550
|
+
const activeId = activeMetricId ?? internalId;
|
|
6551
|
+
const select = (id) => {
|
|
6552
|
+
if (activeMetricId == null) setInternalId(id);
|
|
6553
|
+
onMetricChange?.(id);
|
|
6554
|
+
};
|
|
6555
|
+
return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(
|
|
6556
|
+
"section",
|
|
6557
|
+
{
|
|
6558
|
+
className: cn(metricCardShellClass, className),
|
|
6559
|
+
"aria-labelledby": title ? titleId : void 0,
|
|
6560
|
+
children: [
|
|
6561
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
6562
|
+
MetricCardHeader,
|
|
6563
|
+
{
|
|
6564
|
+
title,
|
|
6565
|
+
titleId,
|
|
6566
|
+
description,
|
|
6567
|
+
actions
|
|
6568
|
+
}
|
|
6569
|
+
),
|
|
6570
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
6571
|
+
"div",
|
|
6572
|
+
{
|
|
6573
|
+
role: selectable ? "group" : void 0,
|
|
6574
|
+
"aria-label": selectable ? metricsAriaLabel : void 0,
|
|
6575
|
+
className: cn(
|
|
6576
|
+
metricTilesRowClass,
|
|
6577
|
+
metricTilesGridColsClass(metrics.length),
|
|
6578
|
+
(title || description || actions) && "mt-3"
|
|
6579
|
+
),
|
|
6580
|
+
children: metrics.map((m, index) => /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
|
|
6581
|
+
MetricTile,
|
|
6582
|
+
{
|
|
6583
|
+
label: m.label,
|
|
6584
|
+
value: m.value,
|
|
6585
|
+
unit: m.unit,
|
|
6586
|
+
trend: m.trend,
|
|
6587
|
+
trendTone: m.trendTone,
|
|
6588
|
+
active: selectable && m.id === activeId,
|
|
6589
|
+
showDivider: index < metrics.length - 1,
|
|
6590
|
+
onSelect: selectable ? () => select(m.id) : void 0
|
|
6591
|
+
},
|
|
6592
|
+
m.id
|
|
6593
|
+
))
|
|
6594
|
+
}
|
|
6595
|
+
)
|
|
6596
|
+
]
|
|
6597
|
+
}
|
|
6598
|
+
);
|
|
6599
|
+
};
|
|
6600
|
+
|
|
6601
|
+
// src/app/data/MetricChartCard.tsx
|
|
6602
|
+
var import_react48 = require("react");
|
|
6603
|
+
var import_jsx_runtime72 = require("react/jsx-runtime");
|
|
6604
|
+
var MetricChartCard = ({
|
|
6605
|
+
title,
|
|
6606
|
+
description,
|
|
6607
|
+
actions,
|
|
6608
|
+
metrics,
|
|
6609
|
+
activeMetricId,
|
|
6610
|
+
defaultActiveMetricId,
|
|
6611
|
+
onMetricChange,
|
|
6612
|
+
xKey = "date",
|
|
6613
|
+
variant = "area",
|
|
6614
|
+
height = 300,
|
|
6615
|
+
formatX,
|
|
6616
|
+
formatValue,
|
|
6617
|
+
emptyLabel = "No data yet",
|
|
6618
|
+
metricsAriaLabel = "Metrics",
|
|
6619
|
+
className
|
|
6620
|
+
}) => {
|
|
6621
|
+
const titleId = (0, import_react48.useId)();
|
|
6622
|
+
const [internalId, setInternalId] = (0, import_react48.useState)(
|
|
6623
|
+
defaultActiveMetricId ?? metrics[0]?.id
|
|
6624
|
+
);
|
|
6625
|
+
const activeId = activeMetricId ?? internalId;
|
|
6626
|
+
const active = metrics.find((m) => m.id === activeId) ?? metrics[0];
|
|
6627
|
+
const select = (id) => {
|
|
6628
|
+
if (activeMetricId == null) setInternalId(id);
|
|
6629
|
+
onMetricChange?.(id);
|
|
6630
|
+
};
|
|
6631
|
+
const hasHeader = Boolean(title || description || actions);
|
|
6632
|
+
const chartAriaLabel = typeof active?.label === "string" ? `${active.label} over time` : "Metric chart";
|
|
6633
|
+
return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(
|
|
6634
|
+
"section",
|
|
6635
|
+
{
|
|
6636
|
+
className: cn(metricCardShellClass, className),
|
|
6637
|
+
"aria-labelledby": title ? titleId : void 0,
|
|
6638
|
+
children: [
|
|
6639
|
+
/* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
6640
|
+
MetricCardHeader,
|
|
6641
|
+
{
|
|
6642
|
+
title,
|
|
6643
|
+
titleId,
|
|
6644
|
+
description,
|
|
6645
|
+
actions
|
|
6646
|
+
}
|
|
6647
|
+
),
|
|
6648
|
+
/* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
6649
|
+
"div",
|
|
6650
|
+
{
|
|
6651
|
+
role: "group",
|
|
6652
|
+
"aria-label": metricsAriaLabel,
|
|
6653
|
+
className: cn(
|
|
6654
|
+
metricTilesRowClass,
|
|
6655
|
+
metricTilesGridColsClass(metrics.length),
|
|
6656
|
+
hasHeader && "mt-3"
|
|
6657
|
+
),
|
|
6658
|
+
children: metrics.map((m, index) => /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
6659
|
+
MetricTile,
|
|
6660
|
+
{
|
|
6661
|
+
label: m.label,
|
|
6662
|
+
value: m.value,
|
|
6663
|
+
unit: m.unit,
|
|
6664
|
+
trend: m.trend,
|
|
6665
|
+
trendTone: m.trendTone,
|
|
6666
|
+
active: m.id === active?.id,
|
|
6667
|
+
showDivider: index < metrics.length - 1,
|
|
6668
|
+
onSelect: () => select(m.id)
|
|
6669
|
+
},
|
|
6670
|
+
m.id
|
|
6671
|
+
))
|
|
6672
|
+
}
|
|
6673
|
+
),
|
|
6674
|
+
/* @__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)(
|
|
6675
|
+
LineAreaChart,
|
|
6676
|
+
{
|
|
6677
|
+
data: active.data,
|
|
6678
|
+
xKey,
|
|
6679
|
+
series: [
|
|
6680
|
+
{
|
|
6681
|
+
dataKey: active.dataKey ?? "value",
|
|
6682
|
+
label: typeof active.label === "string" ? active.label : active.id,
|
|
6683
|
+
color: active.color
|
|
6684
|
+
}
|
|
6685
|
+
],
|
|
6686
|
+
variant,
|
|
6687
|
+
layout: "flush",
|
|
6688
|
+
height,
|
|
6689
|
+
formatX,
|
|
6690
|
+
formatValue,
|
|
6691
|
+
ariaLabel: chartAriaLabel
|
|
6692
|
+
},
|
|
6693
|
+
active.id
|
|
6694
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
6695
|
+
"div",
|
|
6696
|
+
{
|
|
6697
|
+
className: "flex w-full items-center justify-center text-sm font-normal text-muted-foreground",
|
|
6698
|
+
style: { height },
|
|
6699
|
+
role: "status",
|
|
6700
|
+
children: emptyLabel
|
|
6701
|
+
}
|
|
6702
|
+
) })
|
|
6703
|
+
]
|
|
6704
|
+
}
|
|
6705
|
+
);
|
|
6706
|
+
};
|
|
6707
|
+
|
|
6708
|
+
// src/charts/sparkline.tsx
|
|
6709
|
+
var import_react49 = require("react");
|
|
6710
|
+
var import_jsx_runtime73 = require("react/jsx-runtime");
|
|
6711
|
+
var Sparkline = ({
|
|
6712
|
+
data,
|
|
6713
|
+
dataKey = "value",
|
|
6714
|
+
color = "var(--primary, #6366f1)",
|
|
6715
|
+
area = true,
|
|
6716
|
+
width = 96,
|
|
6717
|
+
height = 28,
|
|
6718
|
+
strokeWidth = 1.5,
|
|
6719
|
+
className,
|
|
6720
|
+
ariaLabel = "Trend"
|
|
6721
|
+
}) => {
|
|
6722
|
+
const uid = (0, import_react49.useId)();
|
|
6723
|
+
const values = data.map((d) => typeof d === "number" ? d : toNum(d[dataKey]));
|
|
6724
|
+
if (values.length === 0) {
|
|
6725
|
+
return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: cn("inline-block", className), style: { width, height } });
|
|
6726
|
+
}
|
|
6727
|
+
const pad = strokeWidth + 1;
|
|
6728
|
+
const min = Math.min(...values);
|
|
6729
|
+
const max = Math.max(...values);
|
|
6730
|
+
const range = max - min || 1;
|
|
6731
|
+
const innerW = width - pad * 2;
|
|
6732
|
+
const innerH = height - pad * 2;
|
|
6733
|
+
const points = values.map((v, i) => ({
|
|
6734
|
+
x: pad + (values.length > 1 ? i / (values.length - 1) * innerW : innerW / 2),
|
|
6735
|
+
y: pad + innerH - (v - min) / range * innerH
|
|
6736
|
+
}));
|
|
6737
|
+
return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
|
|
6738
|
+
"svg",
|
|
6739
|
+
{
|
|
6740
|
+
width,
|
|
6741
|
+
height,
|
|
6742
|
+
viewBox: `0 0 ${width} ${height}`,
|
|
6743
|
+
className: cn("block", className),
|
|
6744
|
+
role: "img",
|
|
6745
|
+
"aria-label": ariaLabel,
|
|
6746
|
+
preserveAspectRatio: "none",
|
|
6747
|
+
children: [
|
|
6748
|
+
area && /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(import_jsx_runtime73.Fragment, { children: [
|
|
6749
|
+
/* @__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: [
|
|
6750
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)("stop", { offset: "0%", style: { stopColor: color, stopOpacity: 0.25 } }),
|
|
6751
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)("stop", { offset: "100%", style: { stopColor: color, stopOpacity: 0 } })
|
|
6752
|
+
] }) }),
|
|
6753
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)("path", { d: monotoneAreaPath(points, height - pad), fill: `url(#${uid}-spark)` })
|
|
6754
|
+
] }),
|
|
6755
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
6756
|
+
"path",
|
|
6757
|
+
{
|
|
6758
|
+
d: monotoneLinePath(points),
|
|
6759
|
+
fill: "none",
|
|
6760
|
+
stroke: color,
|
|
6761
|
+
strokeWidth,
|
|
6762
|
+
strokeLinecap: "round",
|
|
6763
|
+
strokeLinejoin: "round"
|
|
6764
|
+
}
|
|
6765
|
+
)
|
|
6766
|
+
]
|
|
6767
|
+
}
|
|
6768
|
+
);
|
|
5245
6769
|
};
|
|
5246
6770
|
|
|
5247
6771
|
// src/chat/chat.tsx
|
|
5248
|
-
var
|
|
6772
|
+
var import_jsx_runtime74 = require("react/jsx-runtime");
|
|
5249
6773
|
function TimbalChat({
|
|
5250
6774
|
workforceId,
|
|
5251
6775
|
baseUrl,
|
|
@@ -5256,7 +6780,7 @@ function TimbalChat({
|
|
|
5256
6780
|
debug,
|
|
5257
6781
|
...threadProps
|
|
5258
6782
|
}) {
|
|
5259
|
-
return /* @__PURE__ */ (0,
|
|
6783
|
+
return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
5260
6784
|
TimbalRuntimeProvider,
|
|
5261
6785
|
{
|
|
5262
6786
|
workforceId,
|
|
@@ -5266,12 +6790,13 @@ function TimbalChat({
|
|
|
5266
6790
|
attachmentsUploadUrl,
|
|
5267
6791
|
attachmentsAccept,
|
|
5268
6792
|
debug,
|
|
5269
|
-
children: /* @__PURE__ */ (0,
|
|
6793
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(Thread, { ...threadProps })
|
|
5270
6794
|
}
|
|
5271
6795
|
);
|
|
5272
6796
|
}
|
|
5273
6797
|
// Annotate the CommonJS export names for ESM import in node:
|
|
5274
6798
|
0 && (module.exports = {
|
|
6799
|
+
APP_KIT_AGENT_INSTRUCTIONS,
|
|
5275
6800
|
AppChatPanel,
|
|
5276
6801
|
AppConfirmDialog,
|
|
5277
6802
|
AppCopilotProvider,
|
|
@@ -5279,23 +6804,47 @@ function TimbalChat({
|
|
|
5279
6804
|
AppShellChatTrigger,
|
|
5280
6805
|
AppShellTopbar,
|
|
5281
6806
|
Breadcrumbs,
|
|
6807
|
+
Button,
|
|
6808
|
+
CHART_PALETTE,
|
|
5282
6809
|
ChartArtifactView,
|
|
5283
6810
|
ChartPanel,
|
|
6811
|
+
ConnectionRow,
|
|
6812
|
+
ConnectionRowList,
|
|
6813
|
+
DangerZone,
|
|
6814
|
+
DangerZoneAction,
|
|
5284
6815
|
DataTable,
|
|
6816
|
+
DescriptionList,
|
|
5285
6817
|
EmptyState,
|
|
6818
|
+
ExpandableSection,
|
|
5286
6819
|
Field,
|
|
5287
6820
|
FieldInput,
|
|
6821
|
+
FieldRow,
|
|
5288
6822
|
FieldSelect,
|
|
5289
6823
|
FieldSwitch,
|
|
5290
6824
|
FieldTextarea,
|
|
5291
6825
|
FilterBar,
|
|
6826
|
+
FloatingUnsavedChangesBar,
|
|
5292
6827
|
FormSection,
|
|
6828
|
+
INTEGRATION_CATALOG_CARD_HEIGHT_CLASS,
|
|
6829
|
+
InfoCard,
|
|
6830
|
+
IntegrationCard,
|
|
6831
|
+
IntegrationsEmptyState,
|
|
6832
|
+
LineAreaChart,
|
|
6833
|
+
MetricChartCard,
|
|
6834
|
+
MetricRow,
|
|
6835
|
+
MetricTile,
|
|
5293
6836
|
Page,
|
|
5294
6837
|
PageHeader,
|
|
6838
|
+
PlanBadge,
|
|
6839
|
+
ResourceCard,
|
|
5295
6840
|
SearchInput,
|
|
5296
6841
|
Section,
|
|
6842
|
+
SettingsSection,
|
|
6843
|
+
SettingsSectionHeader,
|
|
6844
|
+
Sparkline,
|
|
5297
6845
|
StatTile,
|
|
5298
6846
|
StatusBadge,
|
|
6847
|
+
StatusDot,
|
|
5299
6848
|
SubNav,
|
|
5300
6849
|
SurfaceCard,
|
|
5301
6850
|
TimbalChat,
|
|
@@ -5306,6 +6855,7 @@ function TimbalChat({
|
|
|
5306
6855
|
appShellTopbarInsetClass,
|
|
5307
6856
|
appStatTileClass,
|
|
5308
6857
|
appSurfaceCardClass,
|
|
6858
|
+
connectionRowListClass,
|
|
5309
6859
|
useAppCopilotContext,
|
|
5310
6860
|
useAppShellChat
|
|
5311
6861
|
});
|