@timbal-ai/timbal-react 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -1
- package/LICENSE +201 -0
- package/README.md +20 -11
- package/dist/app.cjs +1675 -1218
- package/dist/app.d.cts +22 -6
- package/dist/app.d.ts +22 -6
- package/dist/app.esm.js +26 -8
- package/dist/{chart-artifact-BZp7nmaf.d.ts → chart-artifact-Q5QgMtbj.d.ts} +107 -28
- package/dist/{chart-artifact-CX-rh9nq.d.cts → chart-artifact-WDEW9dHT.d.cts} +107 -28
- package/dist/{chat-DCms8pJ_.d.cts → chat-ClmzWzCX.d.cts} +2 -0
- package/dist/{chat-DCms8pJ_.d.ts → chat-ClmzWzCX.d.ts} +2 -0
- package/dist/chat.cjs +868 -511
- package/dist/chat.d.cts +1 -1
- package/dist/chat.d.ts +1 -1
- package/dist/chat.esm.js +3 -3
- package/dist/{chunk-YXZ22OJN.esm.js → chunk-GQBYZRD7.esm.js} +670 -402
- package/dist/{chunk-XCM3V6RK.esm.js → chunk-OFWC4MIY.esm.js} +2 -2
- package/dist/{chunk-6HWMJNZT.esm.js → chunk-OH23AX2V.esm.js} +757 -56
- package/dist/{chunk-4AKJ6FKE.esm.js → chunk-QU7ET55D.esm.js} +120 -23
- package/dist/{chunk-FRZOEYBO.esm.js → chunk-THBA27QY.esm.js} +4 -4
- package/dist/{chunk-JEAUF54A.esm.js → chunk-UCGVL7ZY.esm.js} +1 -1
- package/dist/{chunk-P3KDAYX6.esm.js → chunk-VXMM2HX7.esm.js} +1 -1
- package/dist/{chunk-TK2AGIME.esm.js → chunk-YCXN67SD.esm.js} +565 -480
- package/dist/{pill-segmented-tabs-Ba5q0feL.d.cts → circular-progress-Ci8L-Hfa.d.cts} +230 -6
- package/dist/{pill-segmented-tabs-Ba5q0feL.d.ts → circular-progress-Ci8L-Hfa.d.ts} +230 -6
- package/dist/index.cjs +2850 -1689
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.esm.js +41 -11
- package/dist/studio.cjs +1089 -732
- package/dist/studio.d.cts +2 -2
- package/dist/studio.d.ts +2 -2
- package/dist/studio.esm.js +5 -5
- package/dist/styles.css +14 -16
- package/dist/ui.cjs +880 -71
- package/dist/ui.d.cts +1 -1
- package/dist/ui.d.ts +1 -1
- package/dist/ui.esm.js +28 -4
- package/dist/{welcome-CRqOPKMp.d.cts → welcome-BFGRoNfK.d.cts} +1 -1
- package/dist/{welcome-DlHUa3OL.d.ts → welcome-DXqsGTwH.d.ts} +1 -1
- package/package.json +1 -1
- package/vite/local-dev.d.ts +5 -1
- package/vite/local-dev.mjs +17 -13
|
@@ -15,14 +15,14 @@ import {
|
|
|
15
15
|
studioIntegrationCardClass,
|
|
16
16
|
studioTopbarPillHeightClass,
|
|
17
17
|
toNum
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-GQBYZRD7.esm.js";
|
|
19
19
|
import {
|
|
20
20
|
Checkbox,
|
|
21
21
|
Skeleton
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-UCGVL7ZY.esm.js";
|
|
23
23
|
import {
|
|
24
24
|
PillSegmentedTabs
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-VXMM2HX7.esm.js";
|
|
26
26
|
import {
|
|
27
27
|
Button,
|
|
28
28
|
Dialog,
|
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
TimbalV2Button,
|
|
36
36
|
cn,
|
|
37
37
|
controlClass
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-QU7ET55D.esm.js";
|
|
39
39
|
|
|
40
40
|
// src/design/ui-vocabulary.ts
|
|
41
41
|
var SEMANTIC_COLOR_TOKENS = [
|
|
@@ -198,8 +198,8 @@ var HOUSE_RULES = [
|
|
|
198
198
|
},
|
|
199
199
|
{
|
|
200
200
|
id: "no-data-gradient",
|
|
201
|
-
rule: "Gradients are reserved for chrome (composer, elevated surface, playground)
|
|
202
|
-
why:
|
|
201
|
+
rule: "Gradients are reserved for chrome (composer, elevated surface, playground) and built-in chart/avatar fills \u2014 never on a data card shell, stat tile, or table row background.",
|
|
202
|
+
why: `Gradient stat cards are the canonical 'AI dashboard' look; SVG bar/pie fills and AvatarFallback variant="secondary" (Action button chrome) are kit-owned exceptions.`
|
|
203
203
|
},
|
|
204
204
|
{
|
|
205
205
|
id: "compose-from-blocks",
|
|
@@ -254,7 +254,7 @@ Presentational groups \u2014 import from the package root, not from these paths:
|
|
|
254
254
|
|
|
255
255
|
Also re-exported: \`Button\`, \`TimbalChat\`, \`ChartArtifactView\`, \`APP_KIT_AGENT_INSTRUCTIONS\`.
|
|
256
256
|
|
|
257
|
-
Theming helpers (import from the package root or \`/app\`): \`createTimbalTheme\`, \`themeToCss\`, \`applyTimbalTheme\`, \`TIMBAL_THEME_PRESETS\`, \`applyThemePreset\`, \`
|
|
257
|
+
Theming helpers (import from the package root or \`/app\`): \`createTimbalTheme\`, \`themeToCss\`, \`applyTimbalTheme\`, \`TIMBAL_THEME_PRESETS\`, \`applyThemePreset\`, \`TimbalThemeStyle\`, \`THEME_AGENT_INSTRUCTIONS\`. Theming is **configured by the developer**, not surfaced as an end-user theme picker.
|
|
258
258
|
|
|
259
259
|
### Design guidelines (required)
|
|
260
260
|
|
|
@@ -263,8 +263,9 @@ Theming helpers (import from the package root or \`/app\`): \`createTimbalTheme\
|
|
|
263
263
|
| **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. |
|
|
264
264
|
| **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. |
|
|
265
265
|
| **Context** | Do not show raw JSON context in the panel header; keep context in \`AppCopilotProvider\` only. |
|
|
266
|
-
| **Theming** | Use semantic Tailwind tokens (\`bg-background\`, \`text-foreground\`, \`border-border\`, \`bg-elevated-from\`, etc.) from the host app's \`styles.css\`. To rebrand, **never hand-author OKLCH** \u2014 call \`createTimbalTheme({ brand })\` + \`themeToCss\`/\`applyTimbalTheme\`, or apply a catalog preset (\`TIMBAL_THEME_PRESETS\` / \`applyThemePreset\`).
|
|
267
|
-
| **Layout chrome** | \`Page\` \u2192 \`Section\` for main content hierarchy.
|
|
266
|
+
| **Theming** | Use semantic Tailwind tokens (\`bg-background\`, \`text-foreground\`, \`border-border\`, \`bg-elevated-from\`, etc.) from the host app's \`styles.css\`. To rebrand, **never hand-author OKLCH** \u2014 call \`createTimbalTheme({ brand })\` + \`themeToCss\`/\`applyTimbalTheme\`, or apply a catalog preset (\`TIMBAL_THEME_PRESETS\` / \`applyThemePreset\`). Apply the theme **programmatically** \u2014 do **not** add an end-user theme selector to generated apps. See \`THEME_AGENT_INSTRUCTIONS\`. |
|
|
267
|
+
| **Layout chrome** | \`Page\` \u2192 \`Section\` for main content hierarchy. Default to **no global topbar** \u2014 put account/theme/global actions in the \`Page\` \`actions\` slot (or the sidebar). Add \`AppShellTopbar\` only when a full-width global bar is explicitly requested. |
|
|
268
|
+
| **Density** | Set \`density="compact"\` on \`Page\` for tighter dashboards (full-width column, smaller section gaps, card padding, metric tiles, default chart height 220). Default is \`"default"\` (platform spacing). Wrap custom layouts with \`AppDensityProvider\` when not using \`Page\`. Per-section override: \`Section density="compact"\`. Do **not** hand-tune five layers of \`className\` padding when density covers the need. |
|
|
268
269
|
| **Data** | Prefer \`DataTable\` with typed \`columns\` / \`rows\` / \`getRowKey\`; use \`ChartPanel\` with a \`ChartArtifact\` for charts (set \`chartType\` + options \u2014 see the chart catalog). Chart colors come from the theme \`--chart-1..6\` tokens; pass \`series[].color\` / \`colors\` only to override, never raw hex on every series. |
|
|
269
270
|
| **Modals** | Use \`AppConfirmDialog\` for destructive/export confirmations. |
|
|
270
271
|
| **Metrics** | Overview KPIs \u2192 \`MetricRow\` or \`MetricChartCard\` (not four separate heavy cards). Values use **normal** font weight, not bold. |
|
|
@@ -301,8 +302,8 @@ The cause of slop is dropping **below** the curated block layer into raw primiti
|
|
|
301
302
|
| \`AppCopilotProvider\` | React context for copilot-aware tools (page, filters, selection, etc.). |
|
|
302
303
|
| \`AppChatPanel\` | Floating thread: \`workforceId\`, \`welcome\`, \`debug\`. |
|
|
303
304
|
| \`useAppShellChat\` | Custom open/close trigger when \`hideChatTrigger\` on shell. |
|
|
304
|
-
| \`Page\` | Page title, description, \`breadcrumbs\`, \`actions\`, children. |
|
|
305
|
-
| \`Section\` | Titled block inside a page. |
|
|
305
|
+
| \`Page\` | Page title, description, \`breadcrumbs\`, \`actions\`, \`density\` (\`"default"\` | \`"compact"\`), children. |
|
|
306
|
+
| \`Section\` | Titled block inside a page. Optional \`density\` overrides inherited page density. |
|
|
306
307
|
| \`SubNav\` | **Section switcher** (Overview / Reports pill bar): \`items\`, \`activeId\`, \`onChange\`. Never use Radix/shadcn \`Tabs\` \u2014 it is not in this package. Switch panels with state or the router. |
|
|
307
308
|
| **Menus** | **Select** = short list, no search. **Combobox** = searchable (same trigger as Select). **Command** only inside \`PopoverContent variant="list"\` or Combobox \u2014 never padded default Popover. See \`examples/app-kit/src/recipes/primitives-catalog.ts\`. |
|
|
308
309
|
| \`Breadcrumbs\` | Trail: \`items: [{ label, href? }]\`. |
|
|
@@ -312,8 +313,9 @@ The cause of slop is dropping **below** the curated block layer into raw primiti
|
|
|
312
313
|
| \`FilterBar\` | Horizontal filter row \u2014 bottom-aligns controls. Mix \`SearchInput\` with labeled \`FilterField\` + \`Select\` (or \`Field\` + \`Select\`); labels sit above, control baselines match. |
|
|
313
314
|
| \`FilterField\` | Optional label wrapper for a filter control inside \`FilterBar\` (severity, status, \u2026). Omit \`label\` for search-only fields. |
|
|
314
315
|
| \`SearchInput\` | Filter field with consistent app styling. |
|
|
315
|
-
| \`DataTable\` | Sortable table: \`columns\`, \`rows\`, \`getRowKey\`, optional \`sort\` / \`onSortChange\`, \`emptyTitle\`, \`showRowCount\`, \`caption
|
|
316
|
-
| \`
|
|
316
|
+
| \`DataTable\` | Sortable table: \`columns\`, \`rows\`, \`getRowKey\`, optional \`sort\` / \`onSortChange\`, \`emptyTitle\`, \`showRowCount\`, \`caption\`, \`truncate: true\` on columns with long text. **Scales:** \`pageSize\` (built-in client pager), \`selectable\` + \`onSelectionChange\` (checkbox column for bulk actions), \`loading\` (skeleton rows). \`onRowClick\` for row \u2192 detail (open a \`Sheet\`). |
|
|
317
|
+
| \`Avatar\` / \`AvatarFallback\` | User initials: \`variant="secondary"\` (or \`primary\` / \`chart\` alias) on **both** \`Avatar\` and \`AvatarFallback\` \u2014 same chrome as catalog **Action** buttons (\`Button variant="secondary"\`: elevated gradient, \`border-border\`, \`shadow-card\`, \`text-foreground\`). Never dark primary CTA fill or raw \`bg-blue-600\`. |
|
|
318
|
+
| \`ChartPanel\` | Same shell as \`MetricChartCard\`: title row (\`px-4 pt-4\`), flush plot (\`pt-2\` only) with **no axis ticks** \u2014 hover tooltips show category + value. Pass \`title\` + \`artifact\` (omit \`artifact.title\` to avoid duplicates) or \`children\`. \`loading\` renders a plot-height skeleton. Default plot height follows page \`density\` (300 default, 220 compact); pass \`height\` to override. |
|
|
317
319
|
| \`FieldInput\`, \`FieldTextarea\`, \`FieldSelect\`, \`FieldSwitch\` | Settings-style forms with labels and hints. |
|
|
318
320
|
| \`FormSection\` | Grouped form block. |
|
|
319
321
|
| \`AppConfirmDialog\` | Confirm/cancel modal: \`open\`, \`onOpenChange\`, \`title\`, \`description\`, \`onConfirm\`. |
|
|
@@ -326,14 +328,14 @@ Charts run on **recharts** with shadcn \`ChartContainer\` / \`ChartTooltipConten
|
|
|
326
328
|
|
|
327
329
|
| Component | Use for |
|
|
328
330
|
|-----------|---------|
|
|
329
|
-
| \`LineAreaChart\` | Cartesian engine (shadcn-style chrome). Props: \`data\`, \`xKey\`, \`series: [{ dataKey, label?, color? }]\`, \`variant\` (\`area\`\\|\`line\`\\|\`bar\`), \`orientation\` (\`horizontal\` for horizontal bars), \`stacked\`, \`curve
|
|
331
|
+
| \`LineAreaChart\` | Cartesian engine (shadcn-style chrome). Bar fills use theme gradients automatically. Props: \`data\`, \`xKey\`, \`series: [{ dataKey, label?, color? }]\`, \`variant\` (\`area\`\\|\`line\`\\|\`bar\`), \`orientation\` (\`horizontal\` for horizontal bars), \`stacked\`, \`curve\`, \`dots\`, \`gridLines\`, \`tooltipIndicator\`, \`layout\` (\`flush\` \u2014 hides axes by default; category + values on hover tooltip), \`showXAxis\` / \`showYAxis\` to opt back in, \`clipTicks\` (truncates long axis labels when axes are on), \`height\`, \`showLegend\`, \`formatX\`, \`formatValue\`, \`ariaLabel\`. |
|
|
330
332
|
| \`PieChart\` | Pie / donut: \`data\`, \`nameKey\`, \`dataKey\`, \`innerRadius\` (>0 = donut), \`centerValue\`/\`centerLabel\` (donut hole KPI), \`showLabels\`, \`colors\`. |
|
|
331
333
|
| \`RadialChart\` | Concentric progress rings: \`data\`, \`nameKey\`, \`dataKey\`, \`maxValue\`, \`centerValue\`/\`centerLabel\`. Good for gauges / share-of-target. |
|
|
332
334
|
| \`RadarChart\` | Spider chart (\u22653 axes): \`data\`, \`nameKey\`, \`series\`, \`maxValue\`. Compare a few metrics across entities. |
|
|
333
335
|
| \`Sparkline\` | Tiny inline trend (table cells): \`data\`, \`color\`, \`area\`. |
|
|
334
336
|
| \`MetricTile\` | Low-level KPI cell \u2014 prefer \`MetricRow\` / \`MetricChartCard\` instead of hand-wiring tiles. |
|
|
335
337
|
| \`MetricRow\` | KPI strip in one elevated card (no chart). Props: \`metrics: [{ id, label, value, unit?, trend?, trendTone? }]\`, optional \`onMetricChange\`, \`metricsAriaLabel\`, \`loading\` (skeleton tiles). |
|
|
336
|
-
| \`MetricChartCard\` | KPI strip + flush chart; tile click swaps series. Same metrics shape + \`data\` per metric. Default chart height 300. \`loading\` renders skeleton tiles + chart. |
|
|
338
|
+
| \`MetricChartCard\` | KPI strip + flush chart; tile click swaps series. Same metrics shape + \`data\` per metric. Default chart height follows page \`density\` (300 / 220); pass \`height\` to override. \`loading\` renders skeleton tiles + chart. |
|
|
337
339
|
|
|
338
340
|
#### Settings
|
|
339
341
|
|
|
@@ -396,7 +398,7 @@ Ready-made **section patterns** assembled from the components above. Each is a c
|
|
|
396
398
|
**Shells & theming**
|
|
397
399
|
- **Minimal shell** \u2014 \`AppShell\` + \`Page\` (no sidebar/chat).
|
|
398
400
|
- **Copilot overlay** \u2014 \`AppShell\` + floating \`AppChatPanel\`.
|
|
399
|
-
- **Theme presets** \u2014 \`
|
|
401
|
+
- **Theme presets** \u2014 apply a brand preset programmatically (\`applyThemePreset\` / \`applyTimbalTheme\`); never hand-author OKLCH and don't expose a theme picker to end users.
|
|
400
402
|
|
|
401
403
|
### Typical compositions
|
|
402
404
|
|
|
@@ -1281,8 +1283,7 @@ Each preset is a **full personality** (color + radius + shadows + font), not jus
|
|
|
1281
1283
|
| \`folio\` | Editorial serif (Fraunces), near-sharp corners \u2014 content / docs |
|
|
1282
1284
|
| \`carbon\` | Terminal monospace (JetBrains Mono), green accent \u2014 dev / infra |
|
|
1283
1285
|
|
|
1284
|
-
-
|
|
1285
|
-
- On selection, call \`applyThemePreset(id)\` (persists to \`localStorage\` and restores on reload).
|
|
1286
|
+
- Pick a preset at build/config time and apply it with \`applyThemePreset(id)\` (persists to \`localStorage\` and restores on reload). Theme selection is a **developer/config** choice \u2014 do **not** surface an end-user theme picker in generated apps.
|
|
1286
1287
|
|
|
1287
1288
|
### Rules
|
|
1288
1289
|
|
|
@@ -1316,17 +1317,142 @@ var TimbalThemeStyle = ({
|
|
|
1316
1317
|
] });
|
|
1317
1318
|
};
|
|
1318
1319
|
|
|
1320
|
+
// src/design/app-classes.ts
|
|
1321
|
+
var appPageColumnClass = "mx-auto w-full max-w-[100rem] px-4 md:px-6 lg:px-8";
|
|
1322
|
+
var appShellTopbarInsetClass = "w-full px-4 md:px-6";
|
|
1323
|
+
var appShellInsetTopClass = "pt-4 md:pt-6";
|
|
1324
|
+
var appShellInsetBottomClass = "pb-8 md:pb-10";
|
|
1325
|
+
var appShellTopbarRowClass = cn(
|
|
1326
|
+
studioTopbarPillHeightClass,
|
|
1327
|
+
"flex w-full items-center justify-between gap-2"
|
|
1328
|
+
);
|
|
1329
|
+
var appShellTopbarStickyClass = cn(
|
|
1330
|
+
"shrink-0 bg-background pb-2",
|
|
1331
|
+
appShellInsetTopClass
|
|
1332
|
+
);
|
|
1333
|
+
var appPageHeaderClass = cn(
|
|
1334
|
+
"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",
|
|
1335
|
+
"pb-4 pt-2"
|
|
1336
|
+
);
|
|
1337
|
+
var appSectionClass = "flex flex-col gap-4 py-4";
|
|
1338
|
+
var appSectionTitleClass = "text-lg font-semibold text-foreground";
|
|
1339
|
+
var appSectionDescriptionClass = "text-sm text-muted-foreground";
|
|
1340
|
+
var appSurfaceCardClass = cn(
|
|
1341
|
+
studioIntegrationCardClass,
|
|
1342
|
+
"p-4 md:p-5"
|
|
1343
|
+
);
|
|
1344
|
+
var appStatTileClass = cn(
|
|
1345
|
+
appSurfaceCardClass,
|
|
1346
|
+
"flex flex-col gap-1 px-4 py-3 shadow-none"
|
|
1347
|
+
);
|
|
1348
|
+
var appStatValueClass = "text-2xl font-normal tracking-tight text-foreground tabular-nums";
|
|
1349
|
+
var appStatLabelClass = "text-xs font-normal text-muted-foreground";
|
|
1350
|
+
var appFilterBarClass = "flex flex-wrap items-end gap-2";
|
|
1351
|
+
var appSearchInputClass = controlClass({}, "inline-flex items-center gap-2");
|
|
1352
|
+
var appBreadcrumbsClass = "flex flex-wrap items-center gap-1.5 text-sm text-muted-foreground";
|
|
1353
|
+
var appBreadcrumbLinkClass = "transition-colors hover:text-foreground";
|
|
1354
|
+
var appFieldClass = "flex flex-col gap-1.5";
|
|
1355
|
+
var appFieldLabelClass = "text-sm font-medium text-foreground";
|
|
1356
|
+
var appFieldHintClass = "text-xs text-muted-foreground";
|
|
1357
|
+
var appInputClass = controlClass({}, "w-full");
|
|
1358
|
+
var appEmptyStateClass = cn(
|
|
1359
|
+
appSurfaceCardClass,
|
|
1360
|
+
"flex flex-col items-center justify-center gap-2 py-12 text-center"
|
|
1361
|
+
);
|
|
1362
|
+
var appEmptyStateTitleClass = "text-base font-medium text-foreground";
|
|
1363
|
+
var appEmptyStateDescriptionClass = "max-w-sm text-sm text-muted-foreground";
|
|
1364
|
+
var appChartPanelClass = cn(appSurfaceCardClass, "flex flex-col gap-3");
|
|
1365
|
+
|
|
1366
|
+
// src/design/app-density.ts
|
|
1367
|
+
var APP_DENSITY_CHART_HEIGHT = {
|
|
1368
|
+
default: 300,
|
|
1369
|
+
compact: 220
|
|
1370
|
+
};
|
|
1371
|
+
var compactSurfaceCardClass = cn(studioIntegrationCardClass, "p-3");
|
|
1372
|
+
var compactStatTileClass = cn(
|
|
1373
|
+
compactSurfaceCardClass,
|
|
1374
|
+
"flex flex-col gap-1 px-3 py-2 shadow-none"
|
|
1375
|
+
);
|
|
1376
|
+
var compactEmptyStateClass = cn(
|
|
1377
|
+
compactSurfaceCardClass,
|
|
1378
|
+
"flex flex-col items-center justify-center gap-2 py-8 text-center"
|
|
1379
|
+
);
|
|
1380
|
+
var APP_DENSITY_CLASSES = {
|
|
1381
|
+
pageColumn: {
|
|
1382
|
+
default: appPageColumnClass,
|
|
1383
|
+
compact: "mx-auto w-full max-w-none px-3 md:px-4"
|
|
1384
|
+
},
|
|
1385
|
+
pageHeader: {
|
|
1386
|
+
default: appPageHeaderClass,
|
|
1387
|
+
compact: "flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between pb-2 pt-1"
|
|
1388
|
+
},
|
|
1389
|
+
section: {
|
|
1390
|
+
default: appSectionClass,
|
|
1391
|
+
compact: "flex flex-col gap-2 py-2"
|
|
1392
|
+
},
|
|
1393
|
+
surfaceCard: {
|
|
1394
|
+
default: appSurfaceCardClass,
|
|
1395
|
+
compact: compactSurfaceCardClass
|
|
1396
|
+
},
|
|
1397
|
+
statTile: {
|
|
1398
|
+
default: appStatTileClass,
|
|
1399
|
+
compact: compactStatTileClass
|
|
1400
|
+
},
|
|
1401
|
+
emptyState: {
|
|
1402
|
+
default: appEmptyStateClass,
|
|
1403
|
+
compact: compactEmptyStateClass
|
|
1404
|
+
},
|
|
1405
|
+
metricCardHeader: {
|
|
1406
|
+
default: "flex items-start justify-between gap-3 px-4 pb-1 pt-3",
|
|
1407
|
+
compact: "flex items-start justify-between gap-2 px-3 pb-0.5 pt-2"
|
|
1408
|
+
},
|
|
1409
|
+
metricTile: {
|
|
1410
|
+
default: "relative flex min-w-0 flex-1 flex-col gap-1 px-4 py-3 text-left font-normal",
|
|
1411
|
+
compact: "relative flex min-w-0 flex-1 flex-col gap-1 px-3 py-2 text-left font-normal"
|
|
1412
|
+
},
|
|
1413
|
+
metricChartRegion: {
|
|
1414
|
+
default: "relative min-h-0 w-full overflow-x-hidden border-t border-border/40 pt-2",
|
|
1415
|
+
compact: "relative min-h-0 w-full overflow-x-hidden border-t border-border/40 pt-1"
|
|
1416
|
+
},
|
|
1417
|
+
metricChartPlotRegion: {
|
|
1418
|
+
default: "relative min-h-0 w-full overflow-x-hidden border-t border-border/40 px-0 pt-5 pb-3",
|
|
1419
|
+
compact: "relative min-h-0 w-full overflow-x-hidden border-t border-border/40 px-0 pt-3 pb-2"
|
|
1420
|
+
},
|
|
1421
|
+
chartPanelBody: {
|
|
1422
|
+
default: "pt-2 pb-3",
|
|
1423
|
+
compact: "pt-1 pb-2"
|
|
1424
|
+
}
|
|
1425
|
+
};
|
|
1426
|
+
function appDensityClass(key, density = "default") {
|
|
1427
|
+
return APP_DENSITY_CLASSES[key][density];
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
// src/app/layout/app-density-context.tsx
|
|
1431
|
+
import { createContext, useContext } from "react";
|
|
1432
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
1433
|
+
var AppDensityContext = createContext("default");
|
|
1434
|
+
var AppDensityProvider = ({
|
|
1435
|
+
density = "default",
|
|
1436
|
+
children
|
|
1437
|
+
}) => {
|
|
1438
|
+
return /* @__PURE__ */ jsx2(AppDensityContext.Provider, { value: density, children });
|
|
1439
|
+
};
|
|
1440
|
+
function useAppDensity() {
|
|
1441
|
+
return useContext(AppDensityContext);
|
|
1442
|
+
}
|
|
1443
|
+
function useAppDensityClass(key, override) {
|
|
1444
|
+
const inherited = useAppDensity();
|
|
1445
|
+
return appDensityClass(key, override ?? inherited);
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1319
1448
|
// src/app/data/metrics-shared.tsx
|
|
1320
|
-
import { jsx as
|
|
1449
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1321
1450
|
var metricCardShellClass = cn(
|
|
1322
1451
|
studioIntegrationCardClass,
|
|
1323
1452
|
"aui-app-metric-card shadow-none",
|
|
1324
1453
|
"flex flex-col overflow-hidden"
|
|
1325
1454
|
);
|
|
1326
|
-
var metricCardHeaderClass = "flex items-start justify-between gap-3 px-4 pb-1 pt-3";
|
|
1327
1455
|
var metricTilesRowClass = "grid w-full min-w-0";
|
|
1328
|
-
var metricChartRegionClass = "relative min-h-0 w-full border-t border-border/40 pt-2";
|
|
1329
|
-
var metricChartPlotRegionClass = "relative min-h-0 w-full border-t border-border/40 px-0 pt-5 pb-3";
|
|
1330
1456
|
var metricCellDividerClass = "border-r border-border/40";
|
|
1331
1457
|
var MetricCardHeader = ({
|
|
1332
1458
|
title,
|
|
@@ -1334,13 +1460,14 @@ var MetricCardHeader = ({
|
|
|
1334
1460
|
description,
|
|
1335
1461
|
actions
|
|
1336
1462
|
}) => {
|
|
1463
|
+
const headerClass = useAppDensityClass("metricCardHeader");
|
|
1337
1464
|
if (!title && !description && !actions) return null;
|
|
1338
|
-
return /* @__PURE__ */ jsxs2("header", { className:
|
|
1465
|
+
return /* @__PURE__ */ jsxs2("header", { className: headerClass, children: [
|
|
1339
1466
|
/* @__PURE__ */ jsxs2("div", { className: "min-w-0", children: [
|
|
1340
|
-
title ? /* @__PURE__ */
|
|
1341
|
-
description ? /* @__PURE__ */
|
|
1467
|
+
title ? /* @__PURE__ */ jsx3("h3", { id: titleId, className: "text-base font-normal text-foreground", children: title }) : null,
|
|
1468
|
+
description ? /* @__PURE__ */ jsx3("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
|
|
1342
1469
|
] }),
|
|
1343
|
-
actions ? /* @__PURE__ */
|
|
1470
|
+
actions ? /* @__PURE__ */ jsx3("div", { className: "shrink-0", children: actions }) : null
|
|
1344
1471
|
] });
|
|
1345
1472
|
};
|
|
1346
1473
|
function metricTilesGridColsClass(n) {
|
|
@@ -1361,15 +1488,13 @@ function metricTilesGridColsClass(n) {
|
|
|
1361
1488
|
}
|
|
1362
1489
|
|
|
1363
1490
|
// src/app/data/MetricTile.tsx
|
|
1364
|
-
import { Fragment as Fragment2, jsx as
|
|
1491
|
+
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1365
1492
|
var trendToneClass = {
|
|
1366
1493
|
up: "border-border/80 bg-muted/40 text-muted-foreground",
|
|
1367
1494
|
down: "border-border/80 bg-muted/40 text-muted-foreground",
|
|
1368
1495
|
neutral: "border-border/80 bg-muted/30 text-muted-foreground"
|
|
1369
1496
|
};
|
|
1370
|
-
var
|
|
1371
|
-
var metricTileInteractiveClass = cn(
|
|
1372
|
-
metricTileBaseClass,
|
|
1497
|
+
var metricTileInteractiveExtraClass = cn(
|
|
1373
1498
|
"bg-transparent hover:bg-transparent active:bg-transparent",
|
|
1374
1499
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-foreground/10"
|
|
1375
1500
|
);
|
|
@@ -1385,21 +1510,22 @@ var MetricTile = ({
|
|
|
1385
1510
|
ariaLabel,
|
|
1386
1511
|
className
|
|
1387
1512
|
}) => {
|
|
1513
|
+
const metricTileBaseClass = useAppDensityClass("metricTile");
|
|
1388
1514
|
const content = /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
1389
|
-
active ? /* @__PURE__ */
|
|
1515
|
+
active ? /* @__PURE__ */ jsx4(
|
|
1390
1516
|
"span",
|
|
1391
1517
|
{
|
|
1392
1518
|
"aria-hidden": true,
|
|
1393
1519
|
className: "absolute inset-x-0 bottom-0 h-0.5 bg-foreground dark:bg-white"
|
|
1394
1520
|
}
|
|
1395
1521
|
) : null,
|
|
1396
|
-
/* @__PURE__ */
|
|
1522
|
+
/* @__PURE__ */ jsx4("span", { className: "text-xs font-normal text-muted-foreground", children: label }),
|
|
1397
1523
|
/* @__PURE__ */ jsxs3("span", { className: "flex items-center gap-2", children: [
|
|
1398
1524
|
/* @__PURE__ */ jsxs3("span", { className: "flex items-baseline gap-1", children: [
|
|
1399
|
-
/* @__PURE__ */
|
|
1400
|
-
unit ? /* @__PURE__ */
|
|
1525
|
+
/* @__PURE__ */ jsx4("span", { className: "text-2xl font-normal tracking-tight text-foreground tabular-nums", children: value }),
|
|
1526
|
+
unit ? /* @__PURE__ */ jsx4("span", { className: "text-xs font-normal text-muted-foreground", children: unit }) : null
|
|
1401
1527
|
] }),
|
|
1402
|
-
trend ? /* @__PURE__ */
|
|
1528
|
+
trend ? /* @__PURE__ */ jsx4(
|
|
1403
1529
|
"span",
|
|
1404
1530
|
{
|
|
1405
1531
|
className: cn(
|
|
@@ -1413,159 +1539,38 @@ var MetricTile = ({
|
|
|
1413
1539
|
] });
|
|
1414
1540
|
const divider = showDivider ? metricCellDividerClass : void 0;
|
|
1415
1541
|
if (onSelect) {
|
|
1416
|
-
return /* @__PURE__ */
|
|
1542
|
+
return /* @__PURE__ */ jsx4(
|
|
1417
1543
|
"button",
|
|
1418
1544
|
{
|
|
1419
1545
|
type: "button",
|
|
1420
1546
|
onClick: onSelect,
|
|
1421
1547
|
"aria-pressed": active,
|
|
1422
1548
|
"aria-label": ariaLabel,
|
|
1423
|
-
className: cn(
|
|
1549
|
+
className: cn(metricTileBaseClass, metricTileInteractiveExtraClass, divider, className),
|
|
1424
1550
|
children: content
|
|
1425
1551
|
}
|
|
1426
1552
|
);
|
|
1427
1553
|
}
|
|
1428
|
-
return /* @__PURE__ */
|
|
1554
|
+
return /* @__PURE__ */ jsx4("div", { className: cn(metricTileBaseClass, divider, className), children: content });
|
|
1429
1555
|
};
|
|
1430
1556
|
|
|
1431
1557
|
// src/app/theme/ThemePresetGallery.tsx
|
|
1432
|
-
import { jsx as
|
|
1433
|
-
var ThemePresetGallery = ({
|
|
1434
|
-
value,
|
|
1435
|
-
onSelect,
|
|
1436
|
-
presets,
|
|
1437
|
-
className
|
|
1438
|
-
}) => {
|
|
1439
|
-
const items = presets ? TIMBAL_THEME_PRESETS.filter((p) => presets.includes(p.id)) : TIMBAL_THEME_PRESETS;
|
|
1440
|
-
return /* @__PURE__ */ jsx4(
|
|
1441
|
-
"div",
|
|
1442
|
-
{
|
|
1443
|
-
role: "radiogroup",
|
|
1444
|
-
"aria-label": "Theme presets",
|
|
1445
|
-
className: cn(
|
|
1446
|
-
"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3",
|
|
1447
|
-
className
|
|
1448
|
-
),
|
|
1449
|
-
children: items.map((preset) => {
|
|
1450
|
-
const selected = value === preset.id;
|
|
1451
|
-
return /* @__PURE__ */ jsxs4("div", { "data-timbal-theme": preset.id, children: [
|
|
1452
|
-
/* @__PURE__ */ jsx4(TimbalThemeStyle, { preset: preset.id, scope: preset.id }),
|
|
1453
|
-
/* @__PURE__ */ jsxs4(
|
|
1454
|
-
"button",
|
|
1455
|
-
{
|
|
1456
|
-
type: "button",
|
|
1457
|
-
role: "radio",
|
|
1458
|
-
"aria-checked": selected,
|
|
1459
|
-
"aria-label": `${preset.label} theme`,
|
|
1460
|
-
onClick: () => onSelect?.(preset.id),
|
|
1461
|
-
className: cn(
|
|
1462
|
-
"group flex w-full flex-col gap-3 rounded-xl border bg-card p-3 text-left transition-colors",
|
|
1463
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
1464
|
-
selected ? "border-primary ring-2 ring-primary/30" : "border-border hover:border-foreground/30"
|
|
1465
|
-
),
|
|
1466
|
-
children: [
|
|
1467
|
-
/* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between gap-2", children: [
|
|
1468
|
-
/* @__PURE__ */ jsxs4("span", { className: "flex items-center gap-2", children: [
|
|
1469
|
-
/* @__PURE__ */ jsx4(
|
|
1470
|
-
"span",
|
|
1471
|
-
{
|
|
1472
|
-
"aria-hidden": true,
|
|
1473
|
-
className: "size-4 shrink-0 rounded-full ring-1 ring-black/10",
|
|
1474
|
-
style: { background: preset.swatch }
|
|
1475
|
-
}
|
|
1476
|
-
),
|
|
1477
|
-
/* @__PURE__ */ jsx4("span", { className: "text-sm font-medium text-foreground", children: preset.label })
|
|
1478
|
-
] }),
|
|
1479
|
-
selected ? /* @__PURE__ */ jsx4("span", { className: "text-xs font-medium text-primary", children: "Selected" }) : null
|
|
1480
|
-
] }),
|
|
1481
|
-
/* @__PURE__ */ jsx4("p", { className: "text-xs leading-snug text-muted-foreground", children: preset.description }),
|
|
1482
|
-
preset.font ? /* @__PURE__ */ jsxs4("span", { className: "text-[10px] uppercase tracking-wide text-muted-foreground", children: [
|
|
1483
|
-
"Aa \xB7 ",
|
|
1484
|
-
preset.font
|
|
1485
|
-
] }) : null,
|
|
1486
|
-
/* @__PURE__ */ jsxs4("div", { className: "flex flex-col gap-2 rounded-lg border border-border bg-background p-2", children: [
|
|
1487
|
-
/* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
|
|
1488
|
-
/* @__PURE__ */ jsx4(Button, { size: "xs", className: "pointer-events-none", children: "Primary" }),
|
|
1489
|
-
/* @__PURE__ */ jsx4("span", { className: "size-5 rounded-md bg-primary", "aria-hidden": true }),
|
|
1490
|
-
/* @__PURE__ */ jsx4("span", { className: "size-5 rounded-md bg-muted", "aria-hidden": true }),
|
|
1491
|
-
/* @__PURE__ */ jsx4(
|
|
1492
|
-
"span",
|
|
1493
|
-
{
|
|
1494
|
-
className: "size-5 rounded-md border border-border bg-accent",
|
|
1495
|
-
"aria-hidden": true
|
|
1496
|
-
}
|
|
1497
|
-
)
|
|
1498
|
-
] }),
|
|
1499
|
-
/* @__PURE__ */ jsx4(MetricTile, { label: "Active users", value: "1,248", trend: "+8%" })
|
|
1500
|
-
] })
|
|
1501
|
-
]
|
|
1502
|
-
}
|
|
1503
|
-
)
|
|
1504
|
-
] }, preset.id);
|
|
1505
|
-
})
|
|
1506
|
-
}
|
|
1507
|
-
);
|
|
1508
|
-
};
|
|
1509
|
-
|
|
1510
|
-
// src/design/app-classes.ts
|
|
1511
|
-
var appPageColumnClass = "mx-auto w-full max-w-6xl px-4 md:px-6";
|
|
1512
|
-
var appShellTopbarInsetClass = "w-full px-4 md:px-6";
|
|
1513
|
-
var appShellInsetTopClass = "pt-4 md:pt-6";
|
|
1514
|
-
var appShellTopbarRowClass = cn(
|
|
1515
|
-
studioTopbarPillHeightClass,
|
|
1516
|
-
"flex w-full items-center justify-between gap-2"
|
|
1517
|
-
);
|
|
1518
|
-
var appShellTopbarStickyClass = cn(
|
|
1519
|
-
"sticky top-0 z-20 shrink-0 bg-background pb-2",
|
|
1520
|
-
appShellInsetTopClass
|
|
1521
|
-
);
|
|
1522
|
-
var appPageHeaderClass = cn(
|
|
1523
|
-
"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",
|
|
1524
|
-
"pb-4 pt-2"
|
|
1525
|
-
);
|
|
1526
|
-
var appSectionClass = "flex flex-col gap-4 py-4";
|
|
1527
|
-
var appSectionTitleClass = "text-lg font-semibold text-foreground";
|
|
1528
|
-
var appSectionDescriptionClass = "text-sm text-muted-foreground";
|
|
1529
|
-
var appSurfaceCardClass = cn(
|
|
1530
|
-
studioIntegrationCardClass,
|
|
1531
|
-
"p-4 md:p-5"
|
|
1532
|
-
);
|
|
1533
|
-
var appStatTileClass = cn(
|
|
1534
|
-
appSurfaceCardClass,
|
|
1535
|
-
"flex flex-col gap-1 px-4 py-3 shadow-none"
|
|
1536
|
-
);
|
|
1537
|
-
var appStatValueClass = "text-2xl font-normal tracking-tight text-foreground tabular-nums";
|
|
1538
|
-
var appStatLabelClass = "text-xs font-normal text-muted-foreground";
|
|
1539
|
-
var appFilterBarClass = "flex flex-wrap items-end gap-2";
|
|
1540
|
-
var appSearchInputClass = controlClass({}, "inline-flex items-center gap-2");
|
|
1541
|
-
var appBreadcrumbsClass = "flex flex-wrap items-center gap-1.5 text-sm text-muted-foreground";
|
|
1542
|
-
var appBreadcrumbLinkClass = "transition-colors hover:text-foreground";
|
|
1543
|
-
var appFieldClass = "flex flex-col gap-1.5";
|
|
1544
|
-
var appFieldLabelClass = "text-sm font-medium text-foreground";
|
|
1545
|
-
var appFieldHintClass = "text-xs text-muted-foreground";
|
|
1546
|
-
var appInputClass = controlClass({}, "w-full");
|
|
1547
|
-
var appEmptyStateClass = cn(
|
|
1548
|
-
appSurfaceCardClass,
|
|
1549
|
-
"flex flex-col items-center justify-center gap-2 py-12 text-center"
|
|
1550
|
-
);
|
|
1551
|
-
var appEmptyStateTitleClass = "text-base font-medium text-foreground";
|
|
1552
|
-
var appEmptyStateDescriptionClass = "max-w-sm text-sm text-muted-foreground";
|
|
1553
|
-
var appChartPanelClass = cn(appSurfaceCardClass, "flex flex-col gap-3");
|
|
1558
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1554
1559
|
|
|
1555
1560
|
// src/app/layout/app-shell-chat-context.tsx
|
|
1556
|
-
import { createContext, useContext } from "react";
|
|
1557
|
-
var AppShellChatContext =
|
|
1561
|
+
import { createContext as createContext2, useContext as useContext2 } from "react";
|
|
1562
|
+
var AppShellChatContext = createContext2(null);
|
|
1558
1563
|
var AppShellChatProvider = AppShellChatContext.Provider;
|
|
1559
1564
|
function useAppShellChat() {
|
|
1560
|
-
return
|
|
1565
|
+
return useContext2(AppShellChatContext);
|
|
1561
1566
|
}
|
|
1562
1567
|
|
|
1563
1568
|
// src/app/layout/app-shell-nav-context.tsx
|
|
1564
|
-
import { createContext as
|
|
1565
|
-
var AppShellNavContext =
|
|
1569
|
+
import { createContext as createContext3, useContext as useContext3 } from "react";
|
|
1570
|
+
var AppShellNavContext = createContext3(null);
|
|
1566
1571
|
var AppShellNavProvider = AppShellNavContext.Provider;
|
|
1567
1572
|
function useAppShellNav() {
|
|
1568
|
-
return
|
|
1573
|
+
return useContext3(AppShellNavContext) ?? {
|
|
1569
1574
|
open: false,
|
|
1570
1575
|
setOpen: () => {
|
|
1571
1576
|
},
|
|
@@ -1577,7 +1582,7 @@ function useAppShellNav() {
|
|
|
1577
1582
|
// src/app/layout/AppShell.tsx
|
|
1578
1583
|
import { motion, useReducedMotion } from "motion/react";
|
|
1579
1584
|
import { useCallback, useMemo, useState } from "react";
|
|
1580
|
-
import { jsx as
|
|
1585
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1581
1586
|
var floatingTriggerClass = cn(
|
|
1582
1587
|
"aui-app-shell-chat-trigger-fixed fixed z-50 rounded-full px-5 py-2.5 text-sm font-medium shadow-card-elevated",
|
|
1583
1588
|
"bg-primary text-primary-foreground transition-colors hover:bg-primary/90",
|
|
@@ -1606,7 +1611,7 @@ var AppShellBody = ({
|
|
|
1606
1611
|
layoutDirection
|
|
1607
1612
|
);
|
|
1608
1613
|
const insetPadding = sidebar ? insetPaddingPx : 0;
|
|
1609
|
-
return /* @__PURE__ */
|
|
1614
|
+
return /* @__PURE__ */ jsx6(
|
|
1610
1615
|
motion.div,
|
|
1611
1616
|
{
|
|
1612
1617
|
className: "aui-app-shell-body relative z-10 flex min-h-0 min-w-0 flex-1 flex-col",
|
|
@@ -1621,8 +1626,18 @@ var AppShellBody = ({
|
|
|
1621
1626
|
!topbarContent && appShellInsetTopClass
|
|
1622
1627
|
),
|
|
1623
1628
|
children: [
|
|
1624
|
-
topbarContent ? /* @__PURE__ */
|
|
1625
|
-
/* @__PURE__ */
|
|
1629
|
+
topbarContent ? /* @__PURE__ */ jsx6("header", { className: cn("aui-app-shell-topbar-region", appShellTopbarStickyClass), children: /* @__PURE__ */ jsx6("div", { className: appShellTopbarInsetClass, children: topbarContent }) }) : null,
|
|
1630
|
+
/* @__PURE__ */ jsx6(
|
|
1631
|
+
"main",
|
|
1632
|
+
{
|
|
1633
|
+
className: cn(
|
|
1634
|
+
"aui-app-shell-main min-w-0 flex-1",
|
|
1635
|
+
appShellInsetBottomClass,
|
|
1636
|
+
mainClassName
|
|
1637
|
+
),
|
|
1638
|
+
children
|
|
1639
|
+
}
|
|
1640
|
+
)
|
|
1626
1641
|
]
|
|
1627
1642
|
}
|
|
1628
1643
|
)
|
|
@@ -1688,7 +1703,7 @@ var AppShell = ({
|
|
|
1688
1703
|
setInsetPaddingPx(insetPx);
|
|
1689
1704
|
}, []);
|
|
1690
1705
|
const insetExpanded = insetPaddingPx >= SIDEBAR_INSET_PX_EXPANDED;
|
|
1691
|
-
const shellBody = /* @__PURE__ */
|
|
1706
|
+
const shellBody = /* @__PURE__ */ jsx6(
|
|
1692
1707
|
AppShellBody,
|
|
1693
1708
|
{
|
|
1694
1709
|
sidebar,
|
|
@@ -1699,7 +1714,7 @@ var AppShell = ({
|
|
|
1699
1714
|
children
|
|
1700
1715
|
}
|
|
1701
1716
|
);
|
|
1702
|
-
const tree = /* @__PURE__ */
|
|
1717
|
+
const tree = /* @__PURE__ */ jsx6(ShellInsetProvider, { value: sidebar ? reportShellInset : null, children: /* @__PURE__ */ jsxs5(
|
|
1703
1718
|
"div",
|
|
1704
1719
|
{
|
|
1705
1720
|
className: cn(
|
|
@@ -1709,7 +1724,7 @@ var AppShell = ({
|
|
|
1709
1724
|
style: studioChromeShellStyle,
|
|
1710
1725
|
children: [
|
|
1711
1726
|
sidebar,
|
|
1712
|
-
sidebar && navOpen ? /* @__PURE__ */
|
|
1727
|
+
sidebar && navOpen ? /* @__PURE__ */ jsx6(
|
|
1713
1728
|
"button",
|
|
1714
1729
|
{
|
|
1715
1730
|
type: "button",
|
|
@@ -1719,7 +1734,7 @@ var AppShell = ({
|
|
|
1719
1734
|
}
|
|
1720
1735
|
) : null,
|
|
1721
1736
|
shellBody,
|
|
1722
|
-
hasChat && chatOpen ? /* @__PURE__ */
|
|
1737
|
+
hasChat && chatOpen ? /* @__PURE__ */ jsx6(
|
|
1723
1738
|
"div",
|
|
1724
1739
|
{
|
|
1725
1740
|
className: floatingPanelClass,
|
|
@@ -1732,7 +1747,7 @@ var AppShell = ({
|
|
|
1732
1747
|
children: chat
|
|
1733
1748
|
}
|
|
1734
1749
|
) : null,
|
|
1735
|
-
hasChat && chatCollapsible && !chatOpen && !hideChatTrigger ? /* @__PURE__ */
|
|
1750
|
+
hasChat && chatCollapsible && !chatOpen && !hideChatTrigger ? /* @__PURE__ */ jsx6(
|
|
1736
1751
|
"button",
|
|
1737
1752
|
{
|
|
1738
1753
|
type: "button",
|
|
@@ -1745,11 +1760,11 @@ var AppShell = ({
|
|
|
1745
1760
|
]
|
|
1746
1761
|
}
|
|
1747
1762
|
) });
|
|
1748
|
-
const withNav = /* @__PURE__ */
|
|
1763
|
+
const withNav = /* @__PURE__ */ jsx6(AppShellNavProvider, { value: navControls, children: tree });
|
|
1749
1764
|
if (!hasChat) {
|
|
1750
1765
|
return withNav;
|
|
1751
1766
|
}
|
|
1752
|
-
return /* @__PURE__ */
|
|
1767
|
+
return /* @__PURE__ */ jsx6(
|
|
1753
1768
|
AppShellChatProvider,
|
|
1754
1769
|
{
|
|
1755
1770
|
value: {
|
|
@@ -1764,7 +1779,7 @@ var AppShell = ({
|
|
|
1764
1779
|
};
|
|
1765
1780
|
|
|
1766
1781
|
// src/app/layout/AppShellTopbar.tsx
|
|
1767
|
-
import { jsx as
|
|
1782
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1768
1783
|
var AppShellTopbar = ({
|
|
1769
1784
|
start,
|
|
1770
1785
|
actions,
|
|
@@ -1776,12 +1791,12 @@ var AppShellTopbar = ({
|
|
|
1776
1791
|
start,
|
|
1777
1792
|
children
|
|
1778
1793
|
] }),
|
|
1779
|
-
actions ? /* @__PURE__ */
|
|
1794
|
+
actions ? /* @__PURE__ */ jsx7("div", { className: "aui-app-shell-topbar-actions flex shrink-0 items-center gap-2", children: actions }) : null
|
|
1780
1795
|
] });
|
|
1781
1796
|
};
|
|
1782
1797
|
|
|
1783
1798
|
// src/app/layout/AppShellChatTrigger.tsx
|
|
1784
|
-
import { jsx as
|
|
1799
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
1785
1800
|
var floatingPositionClass = "fixed bottom-6 right-6 z-50 max-sm:bottom-4 max-sm:right-4";
|
|
1786
1801
|
var AppShellChatTrigger = ({
|
|
1787
1802
|
className,
|
|
@@ -1790,7 +1805,7 @@ var AppShellChatTrigger = ({
|
|
|
1790
1805
|
}) => {
|
|
1791
1806
|
const shellChat = useAppShellChat();
|
|
1792
1807
|
if (!shellChat || shellChat.open) return null;
|
|
1793
|
-
return /* @__PURE__ */
|
|
1808
|
+
return /* @__PURE__ */ jsx8(
|
|
1794
1809
|
TimbalV2Button,
|
|
1795
1810
|
{
|
|
1796
1811
|
type: "button",
|
|
@@ -1811,13 +1826,13 @@ var AppShellChatTrigger = ({
|
|
|
1811
1826
|
|
|
1812
1827
|
// src/app/layout/AppShellSidebarTrigger.tsx
|
|
1813
1828
|
import { MenuIcon } from "lucide-react";
|
|
1814
|
-
import { jsx as
|
|
1829
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
1815
1830
|
var AppShellSidebarTrigger = ({
|
|
1816
1831
|
label = "Open navigation",
|
|
1817
1832
|
className
|
|
1818
1833
|
}) => {
|
|
1819
1834
|
const nav = useAppShellNav();
|
|
1820
|
-
return /* @__PURE__ */
|
|
1835
|
+
return /* @__PURE__ */ jsx9(
|
|
1821
1836
|
"button",
|
|
1822
1837
|
{
|
|
1823
1838
|
type: "button",
|
|
@@ -1829,75 +1844,96 @@ var AppShellSidebarTrigger = ({
|
|
|
1829
1844
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/10",
|
|
1830
1845
|
className
|
|
1831
1846
|
),
|
|
1832
|
-
children: /* @__PURE__ */
|
|
1847
|
+
children: /* @__PURE__ */ jsx9(MenuIcon, { className: "size-5", "aria-hidden": true })
|
|
1833
1848
|
}
|
|
1834
1849
|
);
|
|
1835
1850
|
};
|
|
1836
1851
|
|
|
1837
1852
|
// src/app/layout/PageHeader.tsx
|
|
1838
|
-
import { jsx as
|
|
1853
|
+
import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1839
1854
|
var PageHeader = ({
|
|
1840
1855
|
title,
|
|
1841
1856
|
description,
|
|
1842
1857
|
actions,
|
|
1843
1858
|
className
|
|
1844
1859
|
}) => {
|
|
1845
|
-
|
|
1860
|
+
const pageHeaderClass = useAppDensityClass("pageHeader");
|
|
1861
|
+
return /* @__PURE__ */ jsxs7("header", { className: cn("aui-app-page-header", pageHeaderClass, className), children: [
|
|
1846
1862
|
/* @__PURE__ */ jsxs7("div", { className: "min-w-0", children: [
|
|
1847
|
-
/* @__PURE__ */
|
|
1848
|
-
description ? /* @__PURE__ */
|
|
1863
|
+
/* @__PURE__ */ jsx10("h1", { className: "text-2xl font-semibold tracking-tight text-foreground", children: title }),
|
|
1864
|
+
description ? /* @__PURE__ */ jsx10("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null
|
|
1849
1865
|
] }),
|
|
1850
|
-
actions ? /* @__PURE__ */
|
|
1866
|
+
actions ? /* @__PURE__ */ jsx10("div", { className: "aui-app-page-header-actions flex shrink-0 flex-wrap items-center gap-2", children: actions }) : null
|
|
1851
1867
|
] });
|
|
1852
1868
|
};
|
|
1853
1869
|
|
|
1854
1870
|
// src/app/layout/Page.tsx
|
|
1855
|
-
import { jsx as
|
|
1871
|
+
import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1872
|
+
var PageFrame = ({
|
|
1873
|
+
children,
|
|
1874
|
+
breadcrumbs,
|
|
1875
|
+
className,
|
|
1876
|
+
...headerProps
|
|
1877
|
+
}) => {
|
|
1878
|
+
const density = useAppDensity();
|
|
1879
|
+
const pageColumnClass = useAppDensityClass("pageColumn");
|
|
1880
|
+
return /* @__PURE__ */ jsxs8(
|
|
1881
|
+
"div",
|
|
1882
|
+
{
|
|
1883
|
+
className: cn("aui-app-page", pageColumnClass, className),
|
|
1884
|
+
"data-density": density,
|
|
1885
|
+
children: [
|
|
1886
|
+
breadcrumbs,
|
|
1887
|
+
/* @__PURE__ */ jsx11(PageHeader, { ...headerProps }),
|
|
1888
|
+
children
|
|
1889
|
+
]
|
|
1890
|
+
}
|
|
1891
|
+
);
|
|
1892
|
+
};
|
|
1856
1893
|
var Page = ({
|
|
1894
|
+
density = "default",
|
|
1857
1895
|
children,
|
|
1858
1896
|
breadcrumbs,
|
|
1859
1897
|
className,
|
|
1860
1898
|
...headerProps
|
|
1861
1899
|
}) => {
|
|
1862
|
-
return /* @__PURE__ */
|
|
1863
|
-
breadcrumbs,
|
|
1864
|
-
/* @__PURE__ */ jsx10(PageHeader, { ...headerProps }),
|
|
1865
|
-
children
|
|
1866
|
-
] });
|
|
1900
|
+
return /* @__PURE__ */ jsx11(AppDensityProvider, { density, children: /* @__PURE__ */ jsx11(PageFrame, { breadcrumbs, className, ...headerProps, children }) });
|
|
1867
1901
|
};
|
|
1868
1902
|
|
|
1869
1903
|
// src/app/layout/Section.tsx
|
|
1870
|
-
import { jsx as
|
|
1904
|
+
import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1871
1905
|
var Section = ({
|
|
1872
1906
|
title,
|
|
1873
1907
|
description,
|
|
1874
1908
|
children,
|
|
1909
|
+
density,
|
|
1875
1910
|
className
|
|
1876
1911
|
}) => {
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1912
|
+
const sectionClass = useAppDensityClass("section", density);
|
|
1913
|
+
return /* @__PURE__ */ jsxs9("section", { className: cn("aui-app-section", sectionClass, className), children: [
|
|
1914
|
+
title ? /* @__PURE__ */ jsx12("h2", { className: appSectionTitleClass, children: title }) : null,
|
|
1915
|
+
description ? /* @__PURE__ */ jsx12("p", { className: appSectionDescriptionClass, children: description }) : null,
|
|
1880
1916
|
children
|
|
1881
1917
|
] });
|
|
1882
1918
|
};
|
|
1883
1919
|
|
|
1884
1920
|
// src/app/copilot/app-copilot-context.tsx
|
|
1885
|
-
import { createContext as
|
|
1886
|
-
import { jsx as
|
|
1887
|
-
var AppCopilotContext =
|
|
1921
|
+
import { createContext as createContext4, useContext as useContext4 } from "react";
|
|
1922
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
1923
|
+
var AppCopilotContext = createContext4(null);
|
|
1888
1924
|
var AppCopilotProvider = ({
|
|
1889
1925
|
value,
|
|
1890
1926
|
children
|
|
1891
1927
|
}) => {
|
|
1892
|
-
return /* @__PURE__ */
|
|
1928
|
+
return /* @__PURE__ */ jsx13(AppCopilotContext.Provider, { value, children });
|
|
1893
1929
|
};
|
|
1894
1930
|
function useAppCopilotContext() {
|
|
1895
|
-
return
|
|
1931
|
+
return useContext4(AppCopilotContext) ?? {};
|
|
1896
1932
|
}
|
|
1897
1933
|
|
|
1898
1934
|
// src/app/chat/AppChatPanel.tsx
|
|
1899
1935
|
import { XIcon } from "lucide-react";
|
|
1900
|
-
import { jsx as
|
|
1936
|
+
import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1901
1937
|
var shellClass = "aui-app-chat-panel flex h-full min-h-0 flex-col overflow-hidden";
|
|
1902
1938
|
var chromeClass = cn(
|
|
1903
1939
|
"aui-app-chat-panel-chrome relative z-20 flex min-h-10 shrink-0 items-center justify-end px-2 pt-2"
|
|
@@ -1943,17 +1979,17 @@ var AppChatPanel = ({
|
|
|
1943
1979
|
}) => {
|
|
1944
1980
|
const shellChat = useAppShellChat();
|
|
1945
1981
|
return /* @__PURE__ */ jsxs10("div", { className: cn(shellClass, className), children: [
|
|
1946
|
-
shellChat?.collapsible ? /* @__PURE__ */
|
|
1982
|
+
shellChat?.collapsible ? /* @__PURE__ */ jsx14("div", { className: chromeClass, children: /* @__PURE__ */ jsx14(
|
|
1947
1983
|
"button",
|
|
1948
1984
|
{
|
|
1949
1985
|
type: "button",
|
|
1950
1986
|
className: closeButtonClass,
|
|
1951
1987
|
onClick: () => shellChat.setOpen(false),
|
|
1952
1988
|
"aria-label": "Close assistant",
|
|
1953
|
-
children: /* @__PURE__ */
|
|
1989
|
+
children: /* @__PURE__ */ jsx14(XIcon, { className: "size-4", "aria-hidden": true })
|
|
1954
1990
|
}
|
|
1955
1991
|
) }) : null,
|
|
1956
|
-
/* @__PURE__ */
|
|
1992
|
+
/* @__PURE__ */ jsx14("div", { className: bodyClass, children: /* @__PURE__ */ jsx14(
|
|
1957
1993
|
TimbalRuntimeProvider,
|
|
1958
1994
|
{
|
|
1959
1995
|
workforceId,
|
|
@@ -1963,7 +1999,7 @@ var AppChatPanel = ({
|
|
|
1963
1999
|
attachmentsUploadUrl,
|
|
1964
2000
|
attachmentsAccept,
|
|
1965
2001
|
debug,
|
|
1966
|
-
children: /* @__PURE__ */
|
|
2002
|
+
children: /* @__PURE__ */ jsx14(
|
|
1967
2003
|
Thread,
|
|
1968
2004
|
{
|
|
1969
2005
|
variant: "panel",
|
|
@@ -1984,66 +2020,91 @@ var AppChatPanel = ({
|
|
|
1984
2020
|
};
|
|
1985
2021
|
|
|
1986
2022
|
// src/app/surfaces/SurfaceCard.tsx
|
|
1987
|
-
import { jsx as
|
|
2023
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
1988
2024
|
var SurfaceCard = ({ children, className }) => {
|
|
1989
|
-
|
|
2025
|
+
const surfaceCardClass = useAppDensityClass("surfaceCard");
|
|
2026
|
+
return /* @__PURE__ */ jsx15("div", { className: cn("aui-app-surface-card", surfaceCardClass, className), children });
|
|
1990
2027
|
};
|
|
1991
2028
|
|
|
1992
2029
|
// src/app/surfaces/StatTile.tsx
|
|
1993
|
-
import { jsx as
|
|
2030
|
+
import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1994
2031
|
var StatTile = ({ label, value, hint, className }) => {
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
/* @__PURE__ */
|
|
1998
|
-
|
|
2032
|
+
const statTileClass = useAppDensityClass("statTile");
|
|
2033
|
+
return /* @__PURE__ */ jsxs11("div", { className: cn("aui-app-stat-tile", statTileClass, className), children: [
|
|
2034
|
+
/* @__PURE__ */ jsx16("span", { className: appStatLabelClass, children: label }),
|
|
2035
|
+
/* @__PURE__ */ jsx16("span", { className: appStatValueClass, children: value }),
|
|
2036
|
+
hint ? /* @__PURE__ */ jsx16("span", { className: "text-xs text-muted-foreground", children: hint }) : null
|
|
1999
2037
|
] });
|
|
2000
2038
|
};
|
|
2001
2039
|
|
|
2002
2040
|
// src/app/surfaces/EmptyState.tsx
|
|
2003
|
-
import { jsx as
|
|
2041
|
+
import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2004
2042
|
var EmptyState = ({
|
|
2005
2043
|
title,
|
|
2006
2044
|
description,
|
|
2007
2045
|
action,
|
|
2008
2046
|
className
|
|
2009
2047
|
}) => {
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2048
|
+
const emptyStateClass = useAppDensityClass("emptyState");
|
|
2049
|
+
return /* @__PURE__ */ jsxs12("div", { className: cn("aui-app-empty-state", emptyStateClass, className), children: [
|
|
2050
|
+
/* @__PURE__ */ jsx17("p", { className: appEmptyStateTitleClass, children: title }),
|
|
2051
|
+
description ? /* @__PURE__ */ jsx17("p", { className: appEmptyStateDescriptionClass, children: description }) : null,
|
|
2013
2052
|
action
|
|
2014
2053
|
] });
|
|
2015
2054
|
};
|
|
2016
2055
|
|
|
2017
2056
|
// src/app/surfaces/StatusBadge.tsx
|
|
2018
|
-
import { jsx as
|
|
2057
|
+
import { jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2019
2058
|
var statusBadgeToneClass = {
|
|
2020
|
-
default: "bg-muted text-foreground",
|
|
2021
|
-
primary: "bg-primary/10 text-primary",
|
|
2022
|
-
success: "bg-emerald-500/10 text-emerald-
|
|
2023
|
-
warn: "bg-amber-500/10 text-amber-
|
|
2024
|
-
danger: "bg-destructive/10 text-destructive",
|
|
2025
|
-
muted: "bg-muted/
|
|
2059
|
+
default: "bg-muted text-foreground ring-border",
|
|
2060
|
+
primary: "bg-primary/10 text-primary ring-primary/20",
|
|
2061
|
+
success: "bg-emerald-500/10 text-emerald-700 ring-emerald-500/20 dark:text-emerald-400",
|
|
2062
|
+
warn: "bg-amber-500/10 text-amber-700 ring-amber-500/25 dark:text-amber-400",
|
|
2063
|
+
danger: "bg-destructive/10 text-destructive ring-destructive/20",
|
|
2064
|
+
muted: "bg-muted/70 text-muted-foreground ring-border/60"
|
|
2065
|
+
};
|
|
2066
|
+
var statusBadgeDotClass = {
|
|
2067
|
+
default: "bg-foreground/40",
|
|
2068
|
+
primary: "bg-primary",
|
|
2069
|
+
success: "bg-emerald-500",
|
|
2070
|
+
warn: "bg-amber-500",
|
|
2071
|
+
danger: "bg-destructive",
|
|
2072
|
+
muted: "bg-muted-foreground/60"
|
|
2026
2073
|
};
|
|
2027
2074
|
var StatusBadge = ({
|
|
2028
2075
|
children,
|
|
2029
2076
|
tone = "default",
|
|
2077
|
+
dot = false,
|
|
2030
2078
|
className
|
|
2031
2079
|
}) => {
|
|
2032
|
-
return /* @__PURE__ */
|
|
2080
|
+
return /* @__PURE__ */ jsxs13(
|
|
2033
2081
|
"span",
|
|
2034
2082
|
{
|
|
2035
2083
|
className: cn(
|
|
2036
|
-
"aui-app-status-badge inline-flex items-center rounded-full px-2 py-0.5
|
|
2084
|
+
"aui-app-status-badge inline-flex items-center gap-1.5 rounded-full px-2 py-0.5",
|
|
2085
|
+
"text-xs font-medium leading-none ring-1 ring-inset",
|
|
2037
2086
|
statusBadgeToneClass[tone],
|
|
2038
2087
|
className
|
|
2039
2088
|
),
|
|
2040
|
-
children
|
|
2089
|
+
children: [
|
|
2090
|
+
dot ? /* @__PURE__ */ jsx18(
|
|
2091
|
+
"span",
|
|
2092
|
+
{
|
|
2093
|
+
"aria-hidden": true,
|
|
2094
|
+
className: cn(
|
|
2095
|
+
"size-1.5 shrink-0 rounded-full",
|
|
2096
|
+
statusBadgeDotClass[tone]
|
|
2097
|
+
)
|
|
2098
|
+
}
|
|
2099
|
+
) : null,
|
|
2100
|
+
children
|
|
2101
|
+
]
|
|
2041
2102
|
}
|
|
2042
2103
|
);
|
|
2043
2104
|
};
|
|
2044
2105
|
|
|
2045
2106
|
// src/app/surfaces/AppConfirmDialog.tsx
|
|
2046
|
-
import { jsx as
|
|
2107
|
+
import { jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2047
2108
|
var bodyClass2 = "flex flex-col gap-4 p-6";
|
|
2048
2109
|
var titleClass = "pr-8";
|
|
2049
2110
|
var actionsClass = "flex flex-wrap justify-end gap-2";
|
|
@@ -2058,15 +2119,15 @@ var AppConfirmDialog = ({
|
|
|
2058
2119
|
destructive = false,
|
|
2059
2120
|
className
|
|
2060
2121
|
}) => {
|
|
2061
|
-
return /* @__PURE__ */
|
|
2122
|
+
return /* @__PURE__ */ jsx19(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsx19(
|
|
2062
2123
|
DialogContent,
|
|
2063
2124
|
{
|
|
2064
2125
|
className: cn("gap-0 p-0 sm:max-w-md", className),
|
|
2065
|
-
children: /* @__PURE__ */
|
|
2066
|
-
/* @__PURE__ */
|
|
2067
|
-
description ? /* @__PURE__ */
|
|
2068
|
-
/* @__PURE__ */
|
|
2069
|
-
/* @__PURE__ */
|
|
2126
|
+
children: /* @__PURE__ */ jsxs14("div", { className: bodyClass2, children: [
|
|
2127
|
+
/* @__PURE__ */ jsx19(DialogTitle, { className: titleClass, children: title }),
|
|
2128
|
+
description ? /* @__PURE__ */ jsx19("p", { className: "text-sm text-muted-foreground", children: description }) : null,
|
|
2129
|
+
/* @__PURE__ */ jsxs14("div", { className: actionsClass, children: [
|
|
2130
|
+
/* @__PURE__ */ jsx19(
|
|
2070
2131
|
TimbalV2Button,
|
|
2071
2132
|
{
|
|
2072
2133
|
type: "button",
|
|
@@ -2076,7 +2137,7 @@ var AppConfirmDialog = ({
|
|
|
2076
2137
|
children: cancelLabel
|
|
2077
2138
|
}
|
|
2078
2139
|
),
|
|
2079
|
-
/* @__PURE__ */
|
|
2140
|
+
/* @__PURE__ */ jsx19(
|
|
2080
2141
|
TimbalV2Button,
|
|
2081
2142
|
{
|
|
2082
2143
|
type: "button",
|
|
@@ -2096,7 +2157,7 @@ var AppConfirmDialog = ({
|
|
|
2096
2157
|
};
|
|
2097
2158
|
|
|
2098
2159
|
// src/app/surfaces/InfoCard.tsx
|
|
2099
|
-
import { jsx as
|
|
2160
|
+
import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2100
2161
|
var toneClass = {
|
|
2101
2162
|
neutral: "border-border bg-muted/40",
|
|
2102
2163
|
info: "border-primary/25 bg-primary/5",
|
|
@@ -2111,7 +2172,7 @@ var InfoCard = ({
|
|
|
2111
2172
|
action,
|
|
2112
2173
|
tone = "neutral",
|
|
2113
2174
|
className
|
|
2114
|
-
}) => /* @__PURE__ */
|
|
2175
|
+
}) => /* @__PURE__ */ jsxs15(
|
|
2115
2176
|
"div",
|
|
2116
2177
|
{
|
|
2117
2178
|
className: cn(
|
|
@@ -2120,18 +2181,18 @@ var InfoCard = ({
|
|
|
2120
2181
|
className
|
|
2121
2182
|
),
|
|
2122
2183
|
children: [
|
|
2123
|
-
icon ? /* @__PURE__ */
|
|
2124
|
-
/* @__PURE__ */
|
|
2125
|
-
title ? /* @__PURE__ */
|
|
2126
|
-
children ? /* @__PURE__ */
|
|
2184
|
+
icon ? /* @__PURE__ */ jsx20("span", { className: "mt-0.5 shrink-0 text-muted-foreground", children: icon }) : null,
|
|
2185
|
+
/* @__PURE__ */ jsxs15("div", { className: "min-w-0 flex-1", children: [
|
|
2186
|
+
title ? /* @__PURE__ */ jsx20("p", { className: "text-sm font-medium text-foreground", children: title }) : null,
|
|
2187
|
+
children ? /* @__PURE__ */ jsx20("div", { className: cn("text-sm text-muted-foreground", title && "mt-1"), children }) : null
|
|
2127
2188
|
] }),
|
|
2128
|
-
action ? /* @__PURE__ */
|
|
2189
|
+
action ? /* @__PURE__ */ jsx20("div", { className: "shrink-0", children: action }) : null
|
|
2129
2190
|
]
|
|
2130
2191
|
}
|
|
2131
2192
|
);
|
|
2132
2193
|
|
|
2133
2194
|
// src/app/surfaces/StatusDot.tsx
|
|
2134
|
-
import { jsx as
|
|
2195
|
+
import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2135
2196
|
var dotClass = {
|
|
2136
2197
|
online: "bg-emerald-500",
|
|
2137
2198
|
busy: "bg-amber-500",
|
|
@@ -2144,9 +2205,9 @@ var StatusDot = ({
|
|
|
2144
2205
|
label,
|
|
2145
2206
|
pulse = false,
|
|
2146
2207
|
className
|
|
2147
|
-
}) => /* @__PURE__ */
|
|
2148
|
-
/* @__PURE__ */
|
|
2149
|
-
pulse ? /* @__PURE__ */
|
|
2208
|
+
}) => /* @__PURE__ */ jsxs16("span", { className: cn("inline-flex items-center gap-1.5", className), children: [
|
|
2209
|
+
/* @__PURE__ */ jsxs16("span", { className: "relative flex size-2", children: [
|
|
2210
|
+
pulse ? /* @__PURE__ */ jsx21(
|
|
2150
2211
|
"span",
|
|
2151
2212
|
{
|
|
2152
2213
|
className: cn(
|
|
@@ -2155,25 +2216,25 @@ var StatusDot = ({
|
|
|
2155
2216
|
)
|
|
2156
2217
|
}
|
|
2157
2218
|
) : null,
|
|
2158
|
-
/* @__PURE__ */
|
|
2219
|
+
/* @__PURE__ */ jsx21("span", { className: cn("relative inline-flex size-2 rounded-full", dotClass[tone]) })
|
|
2159
2220
|
] }),
|
|
2160
|
-
label ? /* @__PURE__ */
|
|
2221
|
+
label ? /* @__PURE__ */ jsx21("span", { className: "text-xs text-muted-foreground", children: label }) : null
|
|
2161
2222
|
] });
|
|
2162
2223
|
|
|
2163
2224
|
// src/app/surfaces/DescriptionList.tsx
|
|
2164
|
-
import { jsx as
|
|
2225
|
+
import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2165
2226
|
var DescriptionList = ({
|
|
2166
2227
|
items,
|
|
2167
2228
|
stacked = false,
|
|
2168
2229
|
className
|
|
2169
|
-
}) => /* @__PURE__ */
|
|
2230
|
+
}) => /* @__PURE__ */ jsx22(
|
|
2170
2231
|
"dl",
|
|
2171
2232
|
{
|
|
2172
2233
|
className: cn(
|
|
2173
2234
|
"divide-y divide-border rounded-xl border border-border bg-card",
|
|
2174
2235
|
className
|
|
2175
2236
|
),
|
|
2176
|
-
children: items.map((item, i) => /* @__PURE__ */
|
|
2237
|
+
children: items.map((item, i) => /* @__PURE__ */ jsxs17(
|
|
2177
2238
|
"div",
|
|
2178
2239
|
{
|
|
2179
2240
|
className: cn(
|
|
@@ -2181,8 +2242,8 @@ var DescriptionList = ({
|
|
|
2181
2242
|
stacked ? "flex flex-col gap-0.5" : "flex items-center justify-between gap-4"
|
|
2182
2243
|
),
|
|
2183
2244
|
children: [
|
|
2184
|
-
/* @__PURE__ */
|
|
2185
|
-
/* @__PURE__ */
|
|
2245
|
+
/* @__PURE__ */ jsx22("dt", { className: "text-sm text-muted-foreground", children: item.label }),
|
|
2246
|
+
/* @__PURE__ */ jsx22(
|
|
2186
2247
|
"dd",
|
|
2187
2248
|
{
|
|
2188
2249
|
className: cn(
|
|
@@ -2202,8 +2263,8 @@ var DescriptionList = ({
|
|
|
2202
2263
|
// src/app/surfaces/ExpandableSection.tsx
|
|
2203
2264
|
import { useId, useState as useState2 } from "react";
|
|
2204
2265
|
import { AnimatePresence, motion as motion2, useReducedMotion as useReducedMotion2 } from "motion/react";
|
|
2205
|
-
import { jsx as
|
|
2206
|
-
var Chevron = ({ open }) => /* @__PURE__ */
|
|
2266
|
+
import { jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2267
|
+
var Chevron = ({ open }) => /* @__PURE__ */ jsx23(
|
|
2207
2268
|
"svg",
|
|
2208
2269
|
{
|
|
2209
2270
|
viewBox: "0 0 24 24",
|
|
@@ -2217,7 +2278,7 @@ var Chevron = ({ open }) => /* @__PURE__ */ jsx22(
|
|
|
2217
2278
|
strokeLinecap: "round",
|
|
2218
2279
|
strokeLinejoin: "round",
|
|
2219
2280
|
"aria-hidden": true,
|
|
2220
|
-
children: /* @__PURE__ */
|
|
2281
|
+
children: /* @__PURE__ */ jsx23("path", { d: "m6 9 6 6 6-6" })
|
|
2221
2282
|
}
|
|
2222
2283
|
);
|
|
2223
2284
|
var ExpandableSection = ({
|
|
@@ -2238,8 +2299,8 @@ var ExpandableSection = ({
|
|
|
2238
2299
|
if (openProp == null) setInternalOpen((o) => !o);
|
|
2239
2300
|
onOpenChange?.(!open);
|
|
2240
2301
|
};
|
|
2241
|
-
return /* @__PURE__ */
|
|
2242
|
-
/* @__PURE__ */
|
|
2302
|
+
return /* @__PURE__ */ jsxs18("div", { className: cn("border-b border-border last:border-0", className), children: [
|
|
2303
|
+
/* @__PURE__ */ jsxs18(
|
|
2243
2304
|
"button",
|
|
2244
2305
|
{
|
|
2245
2306
|
type: "button",
|
|
@@ -2248,16 +2309,16 @@ var ExpandableSection = ({
|
|
|
2248
2309
|
"aria-controls": panelId,
|
|
2249
2310
|
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",
|
|
2250
2311
|
children: [
|
|
2251
|
-
/* @__PURE__ */
|
|
2252
|
-
icon ? /* @__PURE__ */
|
|
2253
|
-
/* @__PURE__ */
|
|
2254
|
-
count != null ? /* @__PURE__ */
|
|
2312
|
+
/* @__PURE__ */ jsxs18("span", { className: "flex min-w-0 items-center gap-3", children: [
|
|
2313
|
+
icon ? /* @__PURE__ */ jsx23("span", { className: "flex size-8 items-center justify-center rounded-lg border border-border bg-muted text-muted-foreground", children: icon }) : null,
|
|
2314
|
+
/* @__PURE__ */ jsx23("span", { className: "truncate text-sm font-medium text-foreground", children: title }),
|
|
2315
|
+
count != null ? /* @__PURE__ */ jsx23("span", { className: "rounded-full border border-border bg-muted px-2 py-0.5 text-xs text-muted-foreground", children: count }) : null
|
|
2255
2316
|
] }),
|
|
2256
|
-
/* @__PURE__ */
|
|
2317
|
+
/* @__PURE__ */ jsx23(Chevron, { open })
|
|
2257
2318
|
]
|
|
2258
2319
|
}
|
|
2259
2320
|
),
|
|
2260
|
-
/* @__PURE__ */
|
|
2321
|
+
/* @__PURE__ */ jsx23(AnimatePresence, { initial: false, children: open ? /* @__PURE__ */ jsx23(
|
|
2261
2322
|
motion2.div,
|
|
2262
2323
|
{
|
|
2263
2324
|
id: panelId,
|
|
@@ -2266,7 +2327,7 @@ var ExpandableSection = ({
|
|
|
2266
2327
|
exit: reduceMotion ? void 0 : { height: 0, opacity: 0 },
|
|
2267
2328
|
transition: { duration: 0.2, ease: "easeOut" },
|
|
2268
2329
|
className: "overflow-hidden",
|
|
2269
|
-
children: /* @__PURE__ */
|
|
2330
|
+
children: /* @__PURE__ */ jsx23("div", { className: "bg-muted/20", children })
|
|
2270
2331
|
},
|
|
2271
2332
|
"body"
|
|
2272
2333
|
) : null })
|
|
@@ -2274,7 +2335,7 @@ var ExpandableSection = ({
|
|
|
2274
2335
|
};
|
|
2275
2336
|
|
|
2276
2337
|
// src/app/surfaces/ResourceCard.tsx
|
|
2277
|
-
import { Fragment as Fragment3, jsx as
|
|
2338
|
+
import { Fragment as Fragment3, jsx as jsx24, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2278
2339
|
var resourceCardShellClass = cn(
|
|
2279
2340
|
"flex min-h-[8.5rem] flex-col rounded-2xl p-4 text-left font-normal",
|
|
2280
2341
|
TIMBAL_V2_ELEVATED_SURFACE
|
|
@@ -2299,35 +2360,35 @@ var ResourceCard = ({
|
|
|
2299
2360
|
ariaLabel,
|
|
2300
2361
|
className
|
|
2301
2362
|
}) => {
|
|
2302
|
-
const body = /* @__PURE__ */
|
|
2303
|
-
/* @__PURE__ */
|
|
2304
|
-
media ? /* @__PURE__ */
|
|
2305
|
-
/* @__PURE__ */
|
|
2306
|
-
/* @__PURE__ */
|
|
2307
|
-
subtitle ? /* @__PURE__ */
|
|
2363
|
+
const body = /* @__PURE__ */ jsxs19(Fragment3, { children: [
|
|
2364
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex items-start gap-3", children: [
|
|
2365
|
+
media ? /* @__PURE__ */ jsx24("span", { className: mediaShellClass, children: media }) : null,
|
|
2366
|
+
/* @__PURE__ */ jsxs19("div", { className: "min-w-0 flex-1 pt-0.5", children: [
|
|
2367
|
+
/* @__PURE__ */ jsx24("p", { className: "truncate text-sm font-normal leading-snug text-foreground", children: title }),
|
|
2368
|
+
subtitle ? /* @__PURE__ */ jsx24("p", { className: "mt-1 line-clamp-2 text-xs font-normal text-muted-foreground", children: subtitle }) : null
|
|
2308
2369
|
] }),
|
|
2309
|
-
badge ? /* @__PURE__ */
|
|
2370
|
+
badge ? /* @__PURE__ */ jsx24("span", { className: "shrink-0 pt-0.5", children: badge }) : null
|
|
2310
2371
|
] }),
|
|
2311
|
-
footer || action ? /* @__PURE__ */
|
|
2312
|
-
/* @__PURE__ */
|
|
2313
|
-
action ? /* @__PURE__ */
|
|
2372
|
+
footer || action ? /* @__PURE__ */ jsxs19("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: [
|
|
2373
|
+
/* @__PURE__ */ jsx24("span", { className: "min-w-0 truncate", children: footer }),
|
|
2374
|
+
action ? /* @__PURE__ */ jsx24("span", { className: "shrink-0 opacity-80", children: action }) : null
|
|
2314
2375
|
] }) : null
|
|
2315
2376
|
] });
|
|
2316
2377
|
if (onClick) {
|
|
2317
|
-
return /* @__PURE__ */
|
|
2378
|
+
return /* @__PURE__ */ jsx24("button", { type: "button", onClick, "aria-label": ariaLabel, className: cn(resourceCardInteractiveClass, className), children: body });
|
|
2318
2379
|
}
|
|
2319
|
-
return /* @__PURE__ */
|
|
2380
|
+
return /* @__PURE__ */ jsx24("article", { className: cn(resourceCardShellClass, className), children: body });
|
|
2320
2381
|
};
|
|
2321
2382
|
|
|
2322
2383
|
// src/app/settings/SettingsSection.tsx
|
|
2323
|
-
import { jsx as
|
|
2384
|
+
import { jsx as jsx25, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
2324
2385
|
var SettingsSectionHeader = ({
|
|
2325
2386
|
title,
|
|
2326
2387
|
description,
|
|
2327
2388
|
className
|
|
2328
|
-
}) => /* @__PURE__ */
|
|
2329
|
-
/* @__PURE__ */
|
|
2330
|
-
description ? /* @__PURE__ */
|
|
2389
|
+
}) => /* @__PURE__ */ jsxs20("div", { className: cn("flex flex-col", className), children: [
|
|
2390
|
+
/* @__PURE__ */ jsx25("h3", { className: "text-[17px] font-medium leading-tight text-foreground", children: title }),
|
|
2391
|
+
description ? /* @__PURE__ */ jsx25("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null
|
|
2331
2392
|
] });
|
|
2332
2393
|
var SettingsSection = ({
|
|
2333
2394
|
title,
|
|
@@ -2336,7 +2397,7 @@ var SettingsSection = ({
|
|
|
2336
2397
|
children,
|
|
2337
2398
|
noBorderTop = false,
|
|
2338
2399
|
className
|
|
2339
|
-
}) => /* @__PURE__ */
|
|
2400
|
+
}) => /* @__PURE__ */ jsxs20(
|
|
2340
2401
|
"section",
|
|
2341
2402
|
{
|
|
2342
2403
|
className: cn(
|
|
@@ -2345,18 +2406,18 @@ var SettingsSection = ({
|
|
|
2345
2406
|
className
|
|
2346
2407
|
),
|
|
2347
2408
|
children: [
|
|
2348
|
-
/* @__PURE__ */
|
|
2349
|
-
/* @__PURE__ */
|
|
2350
|
-
description ? /* @__PURE__ */
|
|
2351
|
-
descriptionFooter ? /* @__PURE__ */
|
|
2409
|
+
/* @__PURE__ */ jsxs20("div", { className: "min-w-0", children: [
|
|
2410
|
+
/* @__PURE__ */ jsx25("h2", { className: "text-sm font-medium text-foreground", children: title }),
|
|
2411
|
+
description ? /* @__PURE__ */ jsx25("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null,
|
|
2412
|
+
descriptionFooter ? /* @__PURE__ */ jsx25("div", { className: "mt-3 min-w-0", children: descriptionFooter }) : null
|
|
2352
2413
|
] }),
|
|
2353
|
-
/* @__PURE__ */
|
|
2414
|
+
/* @__PURE__ */ jsx25("div", { className: "min-w-0 space-y-3", children })
|
|
2354
2415
|
]
|
|
2355
2416
|
}
|
|
2356
2417
|
);
|
|
2357
2418
|
|
|
2358
2419
|
// src/app/settings/FieldRow.tsx
|
|
2359
|
-
import { jsx as
|
|
2420
|
+
import { jsx as jsx26, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
2360
2421
|
var FieldRow = ({
|
|
2361
2422
|
label,
|
|
2362
2423
|
children,
|
|
@@ -2366,7 +2427,7 @@ var FieldRow = ({
|
|
|
2366
2427
|
className
|
|
2367
2428
|
}) => {
|
|
2368
2429
|
if (inline) {
|
|
2369
|
-
return /* @__PURE__ */
|
|
2430
|
+
return /* @__PURE__ */ jsxs21(
|
|
2370
2431
|
"div",
|
|
2371
2432
|
{
|
|
2372
2433
|
className: cn(
|
|
@@ -2374,8 +2435,8 @@ var FieldRow = ({
|
|
|
2374
2435
|
className
|
|
2375
2436
|
),
|
|
2376
2437
|
children: [
|
|
2377
|
-
/* @__PURE__ */
|
|
2378
|
-
/* @__PURE__ */
|
|
2438
|
+
/* @__PURE__ */ jsxs21("div", { className: "min-w-0", children: [
|
|
2439
|
+
/* @__PURE__ */ jsx26(
|
|
2379
2440
|
"label",
|
|
2380
2441
|
{
|
|
2381
2442
|
htmlFor,
|
|
@@ -2383,17 +2444,17 @@ var FieldRow = ({
|
|
|
2383
2444
|
children: label
|
|
2384
2445
|
}
|
|
2385
2446
|
),
|
|
2386
|
-
description ? /* @__PURE__ */
|
|
2447
|
+
description ? /* @__PURE__ */ jsx26("p", { className: "mt-0.5 text-xs text-muted-foreground", children: description }) : null
|
|
2387
2448
|
] }),
|
|
2388
|
-
/* @__PURE__ */
|
|
2449
|
+
/* @__PURE__ */ jsx26("div", { className: "shrink-0", children })
|
|
2389
2450
|
]
|
|
2390
2451
|
}
|
|
2391
2452
|
);
|
|
2392
2453
|
}
|
|
2393
|
-
return /* @__PURE__ */
|
|
2394
|
-
/* @__PURE__ */
|
|
2454
|
+
return /* @__PURE__ */ jsxs21("div", { className: cn("flex flex-col gap-1.5", className), children: [
|
|
2455
|
+
/* @__PURE__ */ jsx26("label", { htmlFor, className: "text-sm font-medium text-foreground", children: label }),
|
|
2395
2456
|
children,
|
|
2396
|
-
description ? /* @__PURE__ */
|
|
2457
|
+
description ? /* @__PURE__ */ jsx26("p", { className: "text-xs text-muted-foreground", children: description }) : null
|
|
2397
2458
|
] });
|
|
2398
2459
|
};
|
|
2399
2460
|
|
|
@@ -2401,7 +2462,7 @@ var FieldRow = ({
|
|
|
2401
2462
|
import { useEffect, useState as useState3 } from "react";
|
|
2402
2463
|
import { createPortal } from "react-dom";
|
|
2403
2464
|
import { AnimatePresence as AnimatePresence2, motion as motion3, useReducedMotion as useReducedMotion3 } from "motion/react";
|
|
2404
|
-
import { jsx as
|
|
2465
|
+
import { jsx as jsx27, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
2405
2466
|
var FloatingUnsavedChangesBar = ({
|
|
2406
2467
|
visible,
|
|
2407
2468
|
message = "Unsaved changes",
|
|
@@ -2419,7 +2480,7 @@ var FloatingUnsavedChangesBar = ({
|
|
|
2419
2480
|
useEffect(() => setMounted(true), []);
|
|
2420
2481
|
if (!mounted || typeof document === "undefined") return null;
|
|
2421
2482
|
return createPortal(
|
|
2422
|
-
/* @__PURE__ */
|
|
2483
|
+
/* @__PURE__ */ jsx27(AnimatePresence2, { children: visible ? /* @__PURE__ */ jsx27("div", { className: "pointer-events-none fixed inset-x-0 bottom-5 z-50 flex justify-center px-4", children: /* @__PURE__ */ jsxs22(
|
|
2423
2484
|
motion3.div,
|
|
2424
2485
|
{
|
|
2425
2486
|
role: "region",
|
|
@@ -2433,10 +2494,10 @@ var FloatingUnsavedChangesBar = ({
|
|
|
2433
2494
|
className
|
|
2434
2495
|
),
|
|
2435
2496
|
children: [
|
|
2436
|
-
/* @__PURE__ */
|
|
2437
|
-
/* @__PURE__ */
|
|
2438
|
-
/* @__PURE__ */
|
|
2439
|
-
/* @__PURE__ */
|
|
2497
|
+
/* @__PURE__ */ jsx27("span", { className: "text-sm text-muted-foreground", children: message }),
|
|
2498
|
+
/* @__PURE__ */ jsxs22("span", { className: "flex items-center gap-1.5", children: [
|
|
2499
|
+
/* @__PURE__ */ jsx27(Button, { variant: "ghost", size: "sm", onClick: onDiscard, disabled: isSaving, children: discardLabel }),
|
|
2500
|
+
/* @__PURE__ */ jsx27(Button, { size: "sm", onClick: onSave, disabled: saveDisabled || isSaving, children: isSaving ? "Saving\u2026" : saveLabel })
|
|
2440
2501
|
] })
|
|
2441
2502
|
]
|
|
2442
2503
|
}
|
|
@@ -2446,13 +2507,13 @@ var FloatingUnsavedChangesBar = ({
|
|
|
2446
2507
|
};
|
|
2447
2508
|
|
|
2448
2509
|
// src/app/settings/DangerZone.tsx
|
|
2449
|
-
import { jsx as
|
|
2510
|
+
import { jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
2450
2511
|
var DangerZoneAction = ({
|
|
2451
2512
|
title,
|
|
2452
2513
|
description,
|
|
2453
2514
|
action,
|
|
2454
2515
|
className
|
|
2455
|
-
}) => /* @__PURE__ */
|
|
2516
|
+
}) => /* @__PURE__ */ jsxs23(
|
|
2456
2517
|
"div",
|
|
2457
2518
|
{
|
|
2458
2519
|
className: cn(
|
|
@@ -2460,11 +2521,11 @@ var DangerZoneAction = ({
|
|
|
2460
2521
|
className
|
|
2461
2522
|
),
|
|
2462
2523
|
children: [
|
|
2463
|
-
/* @__PURE__ */
|
|
2464
|
-
/* @__PURE__ */
|
|
2465
|
-
description ? /* @__PURE__ */
|
|
2524
|
+
/* @__PURE__ */ jsxs23("div", { className: "min-w-0", children: [
|
|
2525
|
+
/* @__PURE__ */ jsx28("p", { className: "text-sm font-medium text-foreground", children: title }),
|
|
2526
|
+
description ? /* @__PURE__ */ jsx28("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
|
|
2466
2527
|
] }),
|
|
2467
|
-
/* @__PURE__ */
|
|
2528
|
+
/* @__PURE__ */ jsx28("div", { className: "shrink-0", children: action })
|
|
2468
2529
|
]
|
|
2469
2530
|
}
|
|
2470
2531
|
);
|
|
@@ -2473,7 +2534,7 @@ var DangerZone = ({
|
|
|
2473
2534
|
description,
|
|
2474
2535
|
children,
|
|
2475
2536
|
className
|
|
2476
|
-
}) => /* @__PURE__ */
|
|
2537
|
+
}) => /* @__PURE__ */ jsxs23(
|
|
2477
2538
|
"section",
|
|
2478
2539
|
{
|
|
2479
2540
|
className: cn(
|
|
@@ -2481,18 +2542,18 @@ var DangerZone = ({
|
|
|
2481
2542
|
className
|
|
2482
2543
|
),
|
|
2483
2544
|
children: [
|
|
2484
|
-
(title || description) && /* @__PURE__ */
|
|
2485
|
-
title ? /* @__PURE__ */
|
|
2486
|
-
description ? /* @__PURE__ */
|
|
2545
|
+
(title || description) && /* @__PURE__ */ jsxs23("header", { className: "border-b border-destructive/20 bg-destructive/5 px-4 py-3", children: [
|
|
2546
|
+
title ? /* @__PURE__ */ jsx28("h3", { className: "text-sm font-semibold text-destructive", children: title }) : null,
|
|
2547
|
+
description ? /* @__PURE__ */ jsx28("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
|
|
2487
2548
|
] }),
|
|
2488
|
-
/* @__PURE__ */
|
|
2549
|
+
/* @__PURE__ */ jsx28("div", { className: "divide-y divide-border bg-card", children })
|
|
2489
2550
|
]
|
|
2490
2551
|
}
|
|
2491
2552
|
);
|
|
2492
2553
|
|
|
2493
2554
|
// src/app/integrations/IntegrationCard.tsx
|
|
2494
2555
|
import { useId as useId2 } from "react";
|
|
2495
|
-
import { Fragment as Fragment4, jsx as
|
|
2556
|
+
import { Fragment as Fragment4, jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
2496
2557
|
var INTEGRATION_CATALOG_CARD_HEIGHT_CLASS = "h-[12.25rem] min-h-[12.25rem] max-h-[12.25rem]";
|
|
2497
2558
|
var statusLabel = {
|
|
2498
2559
|
available: null,
|
|
@@ -2533,12 +2594,12 @@ var IntegrationCard = ({
|
|
|
2533
2594
|
const titleId = useId2();
|
|
2534
2595
|
const locked = status === "locked";
|
|
2535
2596
|
const dimmed = status === "disabled" || locked;
|
|
2536
|
-
const body = /* @__PURE__ */
|
|
2537
|
-
/* @__PURE__ */
|
|
2538
|
-
logo ? /* @__PURE__ */
|
|
2539
|
-
/* @__PURE__ */
|
|
2540
|
-
/* @__PURE__ */
|
|
2541
|
-
/* @__PURE__ */
|
|
2597
|
+
const body = /* @__PURE__ */ jsxs24("div", { className: "flex h-full min-h-0 flex-col", children: [
|
|
2598
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex shrink-0 items-start gap-3 pr-2", children: [
|
|
2599
|
+
logo ? /* @__PURE__ */ jsx29("span", { className: logoShellClass, "aria-hidden": Boolean(ariaLabel), children: logo }) : null,
|
|
2600
|
+
/* @__PURE__ */ jsx29("div", { className: "min-w-0 flex-1 pt-0.5", children: /* @__PURE__ */ jsxs24("div", { className: "flex items-start justify-between gap-2", children: [
|
|
2601
|
+
/* @__PURE__ */ jsxs24("div", { className: "min-w-0", children: [
|
|
2602
|
+
/* @__PURE__ */ jsx29(
|
|
2542
2603
|
"h4",
|
|
2543
2604
|
{
|
|
2544
2605
|
id: onClick && !action ? void 0 : titleId,
|
|
@@ -2546,12 +2607,12 @@ var IntegrationCard = ({
|
|
|
2546
2607
|
children: name
|
|
2547
2608
|
}
|
|
2548
2609
|
),
|
|
2549
|
-
statusLabel[status] ? /* @__PURE__ */
|
|
2610
|
+
statusLabel[status] ? /* @__PURE__ */ jsx29("p", { className: "mt-0.5 text-xs text-muted-foreground", children: statusLabel[status] }) : null
|
|
2550
2611
|
] }),
|
|
2551
|
-
badge ? /* @__PURE__ */
|
|
2612
|
+
badge ? /* @__PURE__ */ jsx29("span", { className: "shrink-0", children: badge }) : null
|
|
2552
2613
|
] }) })
|
|
2553
2614
|
] }),
|
|
2554
|
-
description ? /* @__PURE__ */
|
|
2615
|
+
description ? /* @__PURE__ */ jsx29(
|
|
2555
2616
|
"p",
|
|
2556
2617
|
{
|
|
2557
2618
|
className: cn(
|
|
@@ -2561,9 +2622,9 @@ var IntegrationCard = ({
|
|
|
2561
2622
|
children: description
|
|
2562
2623
|
}
|
|
2563
2624
|
) : null,
|
|
2564
|
-
action ? /* @__PURE__ */
|
|
2565
|
-
/* @__PURE__ */
|
|
2566
|
-
/* @__PURE__ */
|
|
2625
|
+
action ? /* @__PURE__ */ jsxs24(Fragment4, { children: [
|
|
2626
|
+
/* @__PURE__ */ jsx29("div", { className: "min-h-0 flex-1", "aria-hidden": true }),
|
|
2627
|
+
/* @__PURE__ */ jsx29("div", { className: "relative mt-3 shrink-0", children: action })
|
|
2567
2628
|
] }) : null
|
|
2568
2629
|
] });
|
|
2569
2630
|
const shellClass3 = cn(
|
|
@@ -2573,7 +2634,7 @@ var IntegrationCard = ({
|
|
|
2573
2634
|
className
|
|
2574
2635
|
);
|
|
2575
2636
|
if (onClick && !action) {
|
|
2576
|
-
return /* @__PURE__ */
|
|
2637
|
+
return /* @__PURE__ */ jsx29(
|
|
2577
2638
|
"button",
|
|
2578
2639
|
{
|
|
2579
2640
|
type: "button",
|
|
@@ -2590,12 +2651,12 @@ var IntegrationCard = ({
|
|
|
2590
2651
|
}
|
|
2591
2652
|
);
|
|
2592
2653
|
}
|
|
2593
|
-
return /* @__PURE__ */
|
|
2654
|
+
return /* @__PURE__ */ jsx29("article", { className: shellClass3, "aria-labelledby": titleId, children: body });
|
|
2594
2655
|
};
|
|
2595
2656
|
|
|
2596
2657
|
// src/app/integrations/IntegrationsEmptyState.tsx
|
|
2597
2658
|
import { useId as useId3 } from "react";
|
|
2598
|
-
import { jsx as
|
|
2659
|
+
import { jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
2599
2660
|
var IntegrationsEmptyState = ({
|
|
2600
2661
|
title = "No integrations yet",
|
|
2601
2662
|
description = "Connect a provider to start syncing data and powering your workforce.",
|
|
@@ -2604,7 +2665,7 @@ var IntegrationsEmptyState = ({
|
|
|
2604
2665
|
className
|
|
2605
2666
|
}) => {
|
|
2606
2667
|
const titleId = useId3();
|
|
2607
|
-
return /* @__PURE__ */
|
|
2668
|
+
return /* @__PURE__ */ jsxs25(
|
|
2608
2669
|
"section",
|
|
2609
2670
|
{
|
|
2610
2671
|
className: cn(
|
|
@@ -2614,7 +2675,7 @@ var IntegrationsEmptyState = ({
|
|
|
2614
2675
|
),
|
|
2615
2676
|
"aria-labelledby": titleId,
|
|
2616
2677
|
children: [
|
|
2617
|
-
icon ? /* @__PURE__ */
|
|
2678
|
+
icon ? /* @__PURE__ */ jsx30(
|
|
2618
2679
|
"span",
|
|
2619
2680
|
{
|
|
2620
2681
|
className: cn(
|
|
@@ -2626,21 +2687,21 @@ var IntegrationsEmptyState = ({
|
|
|
2626
2687
|
children: icon
|
|
2627
2688
|
}
|
|
2628
2689
|
) : null,
|
|
2629
|
-
/* @__PURE__ */
|
|
2630
|
-
description ? /* @__PURE__ */
|
|
2631
|
-
action ? /* @__PURE__ */
|
|
2690
|
+
/* @__PURE__ */ jsx30("h3", { id: titleId, className: "text-base font-normal text-foreground", children: title }),
|
|
2691
|
+
description ? /* @__PURE__ */ jsx30("p", { className: "max-w-sm text-sm text-muted-foreground", children: description }) : null,
|
|
2692
|
+
action ? /* @__PURE__ */ jsx30("div", { className: "mt-1", children: action }) : null
|
|
2632
2693
|
]
|
|
2633
2694
|
}
|
|
2634
2695
|
);
|
|
2635
2696
|
};
|
|
2636
2697
|
|
|
2637
2698
|
// src/app/integrations/PlanBadge.tsx
|
|
2638
|
-
import { jsx as
|
|
2699
|
+
import { jsx as jsx31 } from "react/jsx-runtime";
|
|
2639
2700
|
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";
|
|
2640
|
-
var PlanBadge = ({ children, className }) => /* @__PURE__ */
|
|
2701
|
+
var PlanBadge = ({ children, className }) => /* @__PURE__ */ jsx31("span", { className: cn(planBadgeClass, className), children });
|
|
2641
2702
|
|
|
2642
2703
|
// src/app/integrations/ConnectionRow.tsx
|
|
2643
|
-
import { Fragment as Fragment5, jsx as
|
|
2704
|
+
import { Fragment as Fragment5, jsx as jsx32, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
2644
2705
|
var logoShellClass2 = cn(
|
|
2645
2706
|
"flex size-9 shrink-0 items-center justify-center overflow-hidden rounded-lg",
|
|
2646
2707
|
TIMBAL_V2_LOGO_TILE
|
|
@@ -2655,14 +2716,14 @@ var ConnectionRow = ({
|
|
|
2655
2716
|
ariaLabel,
|
|
2656
2717
|
className
|
|
2657
2718
|
}) => {
|
|
2658
|
-
const inner = /* @__PURE__ */
|
|
2659
|
-
logo ? /* @__PURE__ */
|
|
2660
|
-
/* @__PURE__ */
|
|
2661
|
-
/* @__PURE__ */
|
|
2662
|
-
meta ? /* @__PURE__ */
|
|
2719
|
+
const inner = /* @__PURE__ */ jsxs26(Fragment5, { children: [
|
|
2720
|
+
logo ? /* @__PURE__ */ jsx32("span", { className: logoShellClass2, children: logo }) : null,
|
|
2721
|
+
/* @__PURE__ */ jsxs26("div", { className: "min-w-0 flex-1", children: [
|
|
2722
|
+
/* @__PURE__ */ jsx32("p", { className: "truncate text-sm font-normal text-foreground", children: name }),
|
|
2723
|
+
meta ? /* @__PURE__ */ jsx32("p", { className: "truncate text-xs text-muted-foreground", children: meta }) : null
|
|
2663
2724
|
] }),
|
|
2664
|
-
badge ? /* @__PURE__ */
|
|
2665
|
-
action ? /* @__PURE__ */
|
|
2725
|
+
badge ? /* @__PURE__ */ jsx32("span", { className: "shrink-0", children: badge }) : null,
|
|
2726
|
+
action ? /* @__PURE__ */ jsx32("span", { className: "shrink-0", children: action }) : null
|
|
2666
2727
|
] });
|
|
2667
2728
|
const rowClass2 = cn(
|
|
2668
2729
|
"flex w-full items-center gap-3 px-4 py-3 text-left",
|
|
@@ -2670,7 +2731,7 @@ var ConnectionRow = ({
|
|
|
2670
2731
|
className
|
|
2671
2732
|
);
|
|
2672
2733
|
if (onClick) {
|
|
2673
|
-
return /* @__PURE__ */
|
|
2734
|
+
return /* @__PURE__ */ jsx32(
|
|
2674
2735
|
"button",
|
|
2675
2736
|
{
|
|
2676
2737
|
type: "button",
|
|
@@ -2682,7 +2743,7 @@ var ConnectionRow = ({
|
|
|
2682
2743
|
}
|
|
2683
2744
|
);
|
|
2684
2745
|
}
|
|
2685
|
-
return /* @__PURE__ */
|
|
2746
|
+
return /* @__PURE__ */ jsx32("div", { role: "listitem", className: rowClass2, children: inner });
|
|
2686
2747
|
};
|
|
2687
2748
|
var connectionRowListClass = cn(
|
|
2688
2749
|
"overflow-hidden rounded-2xl",
|
|
@@ -2690,12 +2751,12 @@ var connectionRowListClass = cn(
|
|
|
2690
2751
|
);
|
|
2691
2752
|
|
|
2692
2753
|
// src/app/integrations/ConnectionRowList.tsx
|
|
2693
|
-
import { jsx as
|
|
2754
|
+
import { jsx as jsx33 } from "react/jsx-runtime";
|
|
2694
2755
|
var ConnectionRowList = ({
|
|
2695
2756
|
children,
|
|
2696
2757
|
"aria-label": ariaLabel = "Connected integrations",
|
|
2697
2758
|
className
|
|
2698
|
-
}) => /* @__PURE__ */
|
|
2759
|
+
}) => /* @__PURE__ */ jsx33(
|
|
2699
2760
|
"div",
|
|
2700
2761
|
{
|
|
2701
2762
|
role: "list",
|
|
@@ -2706,7 +2767,7 @@ var ConnectionRowList = ({
|
|
|
2706
2767
|
);
|
|
2707
2768
|
|
|
2708
2769
|
// src/app/navigation/SubNav.tsx
|
|
2709
|
-
import { jsx as
|
|
2770
|
+
import { jsx as jsx34 } from "react/jsx-runtime";
|
|
2710
2771
|
var SubNav = ({
|
|
2711
2772
|
items,
|
|
2712
2773
|
activeId,
|
|
@@ -2715,7 +2776,7 @@ var SubNav = ({
|
|
|
2715
2776
|
"aria-label": ariaLabel = "Section navigation",
|
|
2716
2777
|
layoutId
|
|
2717
2778
|
}) => {
|
|
2718
|
-
return /* @__PURE__ */
|
|
2779
|
+
return /* @__PURE__ */ jsx34("nav", { className: cn("aui-app-sub-nav", className), "aria-label": ariaLabel, children: /* @__PURE__ */ jsx34(
|
|
2719
2780
|
PillSegmentedTabs,
|
|
2720
2781
|
{
|
|
2721
2782
|
value: activeId,
|
|
@@ -2729,13 +2790,13 @@ var SubNav = ({
|
|
|
2729
2790
|
};
|
|
2730
2791
|
|
|
2731
2792
|
// src/app/navigation/Breadcrumbs.tsx
|
|
2732
|
-
import { jsx as
|
|
2793
|
+
import { jsx as jsx35, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
2733
2794
|
var Breadcrumbs = ({ items, className }) => {
|
|
2734
|
-
return /* @__PURE__ */
|
|
2795
|
+
return /* @__PURE__ */ jsx35("nav", { className: cn("aui-app-breadcrumbs", appBreadcrumbsClass, className), "aria-label": "Breadcrumb", children: /* @__PURE__ */ jsx35("ol", { className: "flex flex-wrap items-center gap-1.5", children: items.map((item, index) => {
|
|
2735
2796
|
const isLast = index === items.length - 1;
|
|
2736
|
-
return /* @__PURE__ */
|
|
2737
|
-
index > 0 ? /* @__PURE__ */
|
|
2738
|
-
isLast ? /* @__PURE__ */
|
|
2797
|
+
return /* @__PURE__ */ jsxs27("li", { className: "inline-flex items-center gap-1.5", children: [
|
|
2798
|
+
index > 0 ? /* @__PURE__ */ jsx35("span", { className: "text-muted-foreground/50", "aria-hidden": true, children: "/" }) : null,
|
|
2799
|
+
isLast ? /* @__PURE__ */ jsx35("span", { className: "text-foreground", "aria-current": "page", children: item.label }) : item.href ? /* @__PURE__ */ jsx35("a", { href: item.href, className: appBreadcrumbLinkClass, children: item.label }) : /* @__PURE__ */ jsx35(
|
|
2739
2800
|
"button",
|
|
2740
2801
|
{
|
|
2741
2802
|
type: "button",
|
|
@@ -2749,7 +2810,7 @@ var Breadcrumbs = ({ items, className }) => {
|
|
|
2749
2810
|
};
|
|
2750
2811
|
|
|
2751
2812
|
// src/app/forms/Field.tsx
|
|
2752
|
-
import { jsx as
|
|
2813
|
+
import { jsx as jsx36, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
2753
2814
|
var Field = ({
|
|
2754
2815
|
label,
|
|
2755
2816
|
hint,
|
|
@@ -2758,11 +2819,11 @@ var Field = ({
|
|
|
2758
2819
|
className,
|
|
2759
2820
|
htmlFor
|
|
2760
2821
|
}) => {
|
|
2761
|
-
return /* @__PURE__ */
|
|
2762
|
-
/* @__PURE__ */
|
|
2822
|
+
return /* @__PURE__ */ jsxs28("div", { className: cn("aui-app-field", appFieldClass, className), children: [
|
|
2823
|
+
/* @__PURE__ */ jsx36("label", { className: appFieldLabelClass, htmlFor, children: label }),
|
|
2763
2824
|
children,
|
|
2764
|
-
hint && !error ? /* @__PURE__ */
|
|
2765
|
-
error ? /* @__PURE__ */
|
|
2825
|
+
hint && !error ? /* @__PURE__ */ jsx36("p", { className: appFieldHintClass, children: hint }) : null,
|
|
2826
|
+
error ? /* @__PURE__ */ jsx36("p", { className: "text-xs text-destructive", role: "alert", children: error }) : null
|
|
2766
2827
|
] });
|
|
2767
2828
|
};
|
|
2768
2829
|
var FieldInput = ({
|
|
@@ -2775,7 +2836,7 @@ var FieldInput = ({
|
|
|
2775
2836
|
...inputProps
|
|
2776
2837
|
}) => {
|
|
2777
2838
|
const inputId = id ?? inputProps.name;
|
|
2778
|
-
return /* @__PURE__ */
|
|
2839
|
+
return /* @__PURE__ */ jsx36(
|
|
2779
2840
|
Field,
|
|
2780
2841
|
{
|
|
2781
2842
|
label,
|
|
@@ -2783,7 +2844,7 @@ var FieldInput = ({
|
|
|
2783
2844
|
error,
|
|
2784
2845
|
htmlFor: inputId,
|
|
2785
2846
|
className: fieldClassName,
|
|
2786
|
-
children: /* @__PURE__ */
|
|
2847
|
+
children: /* @__PURE__ */ jsx36(
|
|
2787
2848
|
"input",
|
|
2788
2849
|
{
|
|
2789
2850
|
id: inputId,
|
|
@@ -2797,7 +2858,7 @@ var FieldInput = ({
|
|
|
2797
2858
|
};
|
|
2798
2859
|
|
|
2799
2860
|
// src/app/forms/FieldTextarea.tsx
|
|
2800
|
-
import { jsx as
|
|
2861
|
+
import { jsx as jsx37 } from "react/jsx-runtime";
|
|
2801
2862
|
var textareaClass = cn(
|
|
2802
2863
|
appInputClass,
|
|
2803
2864
|
"min-h-[5.5rem] resize-y py-2.5 leading-relaxed"
|
|
@@ -2812,7 +2873,7 @@ var FieldTextarea = ({
|
|
|
2812
2873
|
...props
|
|
2813
2874
|
}) => {
|
|
2814
2875
|
const textareaId = id ?? props.name;
|
|
2815
|
-
return /* @__PURE__ */
|
|
2876
|
+
return /* @__PURE__ */ jsx37(
|
|
2816
2877
|
Field,
|
|
2817
2878
|
{
|
|
2818
2879
|
label,
|
|
@@ -2820,7 +2881,7 @@ var FieldTextarea = ({
|
|
|
2820
2881
|
error,
|
|
2821
2882
|
htmlFor: textareaId,
|
|
2822
2883
|
className: fieldClassName,
|
|
2823
|
-
children: /* @__PURE__ */
|
|
2884
|
+
children: /* @__PURE__ */ jsx37(
|
|
2824
2885
|
"textarea",
|
|
2825
2886
|
{
|
|
2826
2887
|
id: textareaId,
|
|
@@ -2835,7 +2896,7 @@ var FieldTextarea = ({
|
|
|
2835
2896
|
|
|
2836
2897
|
// src/app/forms/FieldSelect.tsx
|
|
2837
2898
|
import { ChevronDownIcon } from "lucide-react";
|
|
2838
|
-
import { jsx as
|
|
2899
|
+
import { jsx as jsx38, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
2839
2900
|
var selectWrapClass = "relative";
|
|
2840
2901
|
var selectClass = cn(
|
|
2841
2902
|
appInputClass,
|
|
@@ -2852,7 +2913,7 @@ var FieldSelect = ({
|
|
|
2852
2913
|
...props
|
|
2853
2914
|
}) => {
|
|
2854
2915
|
const selectId = id ?? props.name;
|
|
2855
|
-
return /* @__PURE__ */
|
|
2916
|
+
return /* @__PURE__ */ jsx38(
|
|
2856
2917
|
Field,
|
|
2857
2918
|
{
|
|
2858
2919
|
label,
|
|
@@ -2860,8 +2921,8 @@ var FieldSelect = ({
|
|
|
2860
2921
|
error,
|
|
2861
2922
|
htmlFor: selectId,
|
|
2862
2923
|
className: fieldClassName,
|
|
2863
|
-
children: /* @__PURE__ */
|
|
2864
|
-
/* @__PURE__ */
|
|
2924
|
+
children: /* @__PURE__ */ jsxs29("div", { className: selectWrapClass, children: [
|
|
2925
|
+
/* @__PURE__ */ jsx38(
|
|
2865
2926
|
"select",
|
|
2866
2927
|
{
|
|
2867
2928
|
id: selectId,
|
|
@@ -2871,7 +2932,7 @@ var FieldSelect = ({
|
|
|
2871
2932
|
children
|
|
2872
2933
|
}
|
|
2873
2934
|
),
|
|
2874
|
-
/* @__PURE__ */
|
|
2935
|
+
/* @__PURE__ */ jsx38(
|
|
2875
2936
|
ChevronDownIcon,
|
|
2876
2937
|
{
|
|
2877
2938
|
className: "pointer-events-none absolute top-1/2 right-3 size-4 -translate-y-1/2 text-muted-foreground",
|
|
@@ -2884,7 +2945,7 @@ var FieldSelect = ({
|
|
|
2884
2945
|
};
|
|
2885
2946
|
|
|
2886
2947
|
// src/app/forms/FieldSwitch.tsx
|
|
2887
|
-
import { jsx as
|
|
2948
|
+
import { jsx as jsx39, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
2888
2949
|
var trackClass = cn(
|
|
2889
2950
|
"relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-[background,box-shadow,border-color] duration-200",
|
|
2890
2951
|
"peer-focus-visible:ring-2 peer-focus-visible:ring-foreground/10",
|
|
@@ -2905,7 +2966,7 @@ var FieldSwitch = ({
|
|
|
2905
2966
|
...props
|
|
2906
2967
|
}) => {
|
|
2907
2968
|
const inputId = id ?? props.name ?? "switch";
|
|
2908
|
-
return /* @__PURE__ */
|
|
2969
|
+
return /* @__PURE__ */ jsxs30(
|
|
2909
2970
|
"label",
|
|
2910
2971
|
{
|
|
2911
2972
|
className: cn(
|
|
@@ -2914,8 +2975,8 @@ var FieldSwitch = ({
|
|
|
2914
2975
|
),
|
|
2915
2976
|
htmlFor: inputId,
|
|
2916
2977
|
children: [
|
|
2917
|
-
/* @__PURE__ */
|
|
2918
|
-
/* @__PURE__ */
|
|
2978
|
+
/* @__PURE__ */ jsxs30("span", { className: "relative mt-0.5", children: [
|
|
2979
|
+
/* @__PURE__ */ jsx39(
|
|
2919
2980
|
"input",
|
|
2920
2981
|
{
|
|
2921
2982
|
id: inputId,
|
|
@@ -2925,11 +2986,11 @@ var FieldSwitch = ({
|
|
|
2925
2986
|
...props
|
|
2926
2987
|
}
|
|
2927
2988
|
),
|
|
2928
|
-
/* @__PURE__ */
|
|
2989
|
+
/* @__PURE__ */ jsx39("span", { className: trackClass, "aria-hidden": true, children: /* @__PURE__ */ jsx39("span", { className: thumbClass }) })
|
|
2929
2990
|
] }),
|
|
2930
|
-
/* @__PURE__ */
|
|
2931
|
-
/* @__PURE__ */
|
|
2932
|
-
description ? /* @__PURE__ */
|
|
2991
|
+
/* @__PURE__ */ jsxs30("span", { className: "flex min-w-0 flex-col gap-0.5", children: [
|
|
2992
|
+
/* @__PURE__ */ jsx39("span", { className: "text-sm font-medium text-foreground", children: label }),
|
|
2993
|
+
description ? /* @__PURE__ */ jsx39("span", { className: "text-xs text-muted-foreground", children: description }) : null
|
|
2933
2994
|
] })
|
|
2934
2995
|
]
|
|
2935
2996
|
}
|
|
@@ -2938,13 +2999,13 @@ var FieldSwitch = ({
|
|
|
2938
2999
|
|
|
2939
3000
|
// src/app/forms/SearchInput.tsx
|
|
2940
3001
|
import { SearchIcon } from "lucide-react";
|
|
2941
|
-
import { jsx as
|
|
3002
|
+
import { jsx as jsx40, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
2942
3003
|
var SearchInput = ({
|
|
2943
3004
|
className,
|
|
2944
3005
|
placeholder = "Search\u2026",
|
|
2945
3006
|
...props
|
|
2946
3007
|
}) => {
|
|
2947
|
-
return /* @__PURE__ */
|
|
3008
|
+
return /* @__PURE__ */ jsxs31(
|
|
2948
3009
|
"label",
|
|
2949
3010
|
{
|
|
2950
3011
|
className: cn(
|
|
@@ -2953,8 +3014,8 @@ var SearchInput = ({
|
|
|
2953
3014
|
className
|
|
2954
3015
|
),
|
|
2955
3016
|
children: [
|
|
2956
|
-
/* @__PURE__ */
|
|
2957
|
-
/* @__PURE__ */
|
|
3017
|
+
/* @__PURE__ */ jsx40(SearchIcon, { className: "size-4 shrink-0 text-muted-foreground", "aria-hidden": true }),
|
|
3018
|
+
/* @__PURE__ */ jsx40(
|
|
2958
3019
|
"input",
|
|
2959
3020
|
{
|
|
2960
3021
|
type: "search",
|
|
@@ -2969,18 +3030,26 @@ var SearchInput = ({
|
|
|
2969
3030
|
};
|
|
2970
3031
|
|
|
2971
3032
|
// src/app/forms/FormSection.tsx
|
|
2972
|
-
import { jsx as
|
|
3033
|
+
import { jsx as jsx41, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
2973
3034
|
var FormSection = ({ title, children, className }) => {
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
3035
|
+
const density = useAppDensity();
|
|
3036
|
+
const sectionClass = useAppDensityClass("section");
|
|
3037
|
+
return /* @__PURE__ */ jsxs32(
|
|
3038
|
+
"fieldset",
|
|
3039
|
+
{
|
|
3040
|
+
className: cn("aui-app-form-section", sectionClass, "border-0 p-0", className),
|
|
3041
|
+
children: [
|
|
3042
|
+
title ? /* @__PURE__ */ jsx41("legend", { className: cn(appSectionTitleClass, "mb-3 px-0"), children: title }) : null,
|
|
3043
|
+
/* @__PURE__ */ jsx41("div", { className: cn("flex flex-col", density === "compact" ? "gap-2" : "gap-4"), children })
|
|
3044
|
+
]
|
|
3045
|
+
}
|
|
3046
|
+
);
|
|
2978
3047
|
};
|
|
2979
3048
|
|
|
2980
3049
|
// src/app/data/FilterBar.tsx
|
|
2981
|
-
import { jsx as
|
|
3050
|
+
import { jsx as jsx42 } from "react/jsx-runtime";
|
|
2982
3051
|
var FilterBar = ({ children, className }) => {
|
|
2983
|
-
return /* @__PURE__ */
|
|
3052
|
+
return /* @__PURE__ */ jsx42(
|
|
2984
3053
|
"div",
|
|
2985
3054
|
{
|
|
2986
3055
|
className: cn("aui-app-filter-bar", appFilterBarClass, className),
|
|
@@ -2992,14 +3061,14 @@ var FilterBar = ({ children, className }) => {
|
|
|
2992
3061
|
};
|
|
2993
3062
|
|
|
2994
3063
|
// src/app/data/FilterField.tsx
|
|
2995
|
-
import { jsx as
|
|
3064
|
+
import { jsx as jsx43, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
2996
3065
|
var FilterField = ({
|
|
2997
3066
|
label,
|
|
2998
3067
|
children,
|
|
2999
3068
|
className
|
|
3000
3069
|
}) => {
|
|
3001
|
-
return /* @__PURE__ */
|
|
3002
|
-
label ? /* @__PURE__ */
|
|
3070
|
+
return /* @__PURE__ */ jsxs33("div", { className: cn("aui-app-filter-field", appFieldClass, className), children: [
|
|
3071
|
+
label ? /* @__PURE__ */ jsx43("span", { className: appFieldLabelClass, children: label }) : null,
|
|
3003
3072
|
children
|
|
3004
3073
|
] });
|
|
3005
3074
|
};
|
|
@@ -3013,19 +3082,20 @@ import {
|
|
|
3013
3082
|
ChevronLeftIcon,
|
|
3014
3083
|
ChevronRightIcon
|
|
3015
3084
|
} from "lucide-react";
|
|
3016
|
-
import { jsx as
|
|
3017
|
-
var shellClass2 = "overflow-hidden rounded-xl border border-border bg-
|
|
3085
|
+
import { jsx as jsx44, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
3086
|
+
var shellClass2 = "overflow-hidden rounded-xl border border-border bg-gradient-to-b from-elevated-from to-elevated-to shadow-card";
|
|
3018
3087
|
var tableClass = "w-full border-collapse bg-transparent text-sm";
|
|
3019
|
-
var
|
|
3088
|
+
var headRowClass = "bg-muted/40";
|
|
3089
|
+
var headCellClass = "border-b border-border/70 px-4 py-2.5 text-left text-[11px] font-semibold uppercase tracking-[0.04em] text-muted-foreground/90";
|
|
3020
3090
|
var bodyCellClass = "border-b border-border/40 bg-transparent px-4 py-2.5 text-foreground";
|
|
3021
|
-
var rowClass = "bg-transparent transition-colors hover:bg-
|
|
3022
|
-
var footCellClass = "border-t border-border/60 bg-
|
|
3091
|
+
var rowClass = "bg-transparent transition-colors hover:bg-muted/40 data-[clickable=true]:cursor-pointer data-[selected=true]:bg-primary/[0.06]";
|
|
3092
|
+
var footCellClass = "border-t border-border/60 bg-muted/20 px-4 py-2.5 text-xs text-muted-foreground";
|
|
3023
3093
|
var footInnerClass = "flex flex-wrap items-center gap-2";
|
|
3024
3094
|
var emptyCellClass = "bg-transparent px-4 py-10 text-center text-sm text-muted-foreground";
|
|
3025
|
-
var sortButtonClass = "group inline-flex min-w-0 items-center gap-1.5 rounded-md -mx-1 px-1 py-0.5 text-left font-
|
|
3026
|
-
var stickyHeadClass = "sticky top-0 z-[1] bg-
|
|
3095
|
+
var sortButtonClass = "group inline-flex min-w-0 items-center gap-1.5 rounded-md -mx-1 px-1 py-0.5 text-left font-semibold text-muted-foreground/90 transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/10";
|
|
3096
|
+
var stickyHeadClass = "sticky top-0 z-[1] bg-muted/95 shadow-[0_1px_0_0_hsl(var(--border)/0.6)] backdrop-blur-sm";
|
|
3027
3097
|
var selectCellClass = "w-10 px-4 py-2.5 align-middle";
|
|
3028
|
-
var pagerButtonClass = "inline-flex size-7 items-center justify-center rounded-md border border-border bg-
|
|
3098
|
+
var pagerButtonClass = "inline-flex size-7 items-center justify-center rounded-md border border-border bg-gradient-to-b from-elevated-from to-elevated-to text-muted-foreground shadow-card transition-colors hover:from-secondary-fill-hover-from hover:to-secondary-fill-hover-to hover:text-foreground disabled:pointer-events-none disabled:opacity-40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/10";
|
|
3029
3099
|
var alignClass = {
|
|
3030
3100
|
left: "text-left",
|
|
3031
3101
|
center: "text-center",
|
|
@@ -3055,12 +3125,12 @@ function SortIndicator({
|
|
|
3055
3125
|
}) {
|
|
3056
3126
|
const iconClass = "size-3.5 shrink-0 opacity-60 group-hover:opacity-100";
|
|
3057
3127
|
if (!active) {
|
|
3058
|
-
return /* @__PURE__ */
|
|
3128
|
+
return /* @__PURE__ */ jsx44(ArrowUpDownIcon, { className: iconClass, "aria-hidden": true });
|
|
3059
3129
|
}
|
|
3060
3130
|
if (direction === "desc") {
|
|
3061
|
-
return /* @__PURE__ */
|
|
3131
|
+
return /* @__PURE__ */ jsx44(ArrowDownIcon, { className: iconClass, "aria-hidden": true });
|
|
3062
3132
|
}
|
|
3063
|
-
return /* @__PURE__ */
|
|
3133
|
+
return /* @__PURE__ */ jsx44(ArrowUpIcon, { className: iconClass, "aria-hidden": true });
|
|
3064
3134
|
}
|
|
3065
3135
|
function DataTable({
|
|
3066
3136
|
columns,
|
|
@@ -3158,7 +3228,7 @@ function DataTable({
|
|
|
3158
3228
|
const headPad = dense ? "px-3 py-2" : void 0;
|
|
3159
3229
|
const colSpan = columns.length + (selectable ? 1 : 0);
|
|
3160
3230
|
if (!loading && rows.length === 0 && emptyMode === "replace") {
|
|
3161
|
-
return /* @__PURE__ */
|
|
3231
|
+
return /* @__PURE__ */ jsx44(EmptyState, { title: emptyTitle, description: emptyDescription, className });
|
|
3162
3232
|
}
|
|
3163
3233
|
const allKeys = sortedRows.map(getRowKey);
|
|
3164
3234
|
const allSelected = allKeys.length > 0 && allKeys.every((k) => selectedSet.has(k));
|
|
@@ -3183,10 +3253,10 @@ function DataTable({
|
|
|
3183
3253
|
const hasPager = paginated && !loading && sortedRows.length > 0;
|
|
3184
3254
|
const hasFoot = (showRowCount || footer || hasPager) && (loading || sortedRows.length > 0);
|
|
3185
3255
|
const skeletonCount = loadingRows ?? pageSize ?? 5;
|
|
3186
|
-
return /* @__PURE__ */
|
|
3187
|
-
caption ? /* @__PURE__ */
|
|
3188
|
-
/* @__PURE__ */
|
|
3189
|
-
selectable ? /* @__PURE__ */
|
|
3256
|
+
return /* @__PURE__ */ jsx44("div", { className: cn("aui-app-data-table", shellClass2, className), children: /* @__PURE__ */ jsx44("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs34("table", { className: tableClass, children: [
|
|
3257
|
+
caption ? /* @__PURE__ */ jsx44("caption", { className: "sr-only", children: caption }) : null,
|
|
3258
|
+
/* @__PURE__ */ jsx44("thead", { className: cn(headRowClass, stickyHeader && stickyHeadClass), children: /* @__PURE__ */ jsxs34("tr", { children: [
|
|
3259
|
+
selectable ? /* @__PURE__ */ jsx44("th", { scope: "col", className: cn(selectCellClass, headPad), children: /* @__PURE__ */ jsx44(
|
|
3190
3260
|
Checkbox,
|
|
3191
3261
|
{
|
|
3192
3262
|
checked: headerCheckedState,
|
|
@@ -3198,19 +3268,19 @@ function DataTable({
|
|
|
3198
3268
|
columns.map((col) => {
|
|
3199
3269
|
const isSorted = sort?.columnId === col.id;
|
|
3200
3270
|
const ariaSort = col.sortable ? isSorted ? sort.direction === "asc" ? "ascending" : "descending" : "none" : void 0;
|
|
3201
|
-
const headerContent = col.sortable ? /* @__PURE__ */
|
|
3271
|
+
const headerContent = col.sortable ? /* @__PURE__ */ jsxs34(
|
|
3202
3272
|
"button",
|
|
3203
3273
|
{
|
|
3204
3274
|
type: "button",
|
|
3205
3275
|
className: sortButtonClass,
|
|
3206
3276
|
onClick: () => setSort(nextSort(sort, col.id)),
|
|
3207
3277
|
children: [
|
|
3208
|
-
/* @__PURE__ */
|
|
3209
|
-
/* @__PURE__ */
|
|
3278
|
+
/* @__PURE__ */ jsx44("span", { className: "truncate", children: col.header }),
|
|
3279
|
+
/* @__PURE__ */ jsx44(SortIndicator, { active: Boolean(isSorted), direction: sort?.direction })
|
|
3210
3280
|
]
|
|
3211
3281
|
}
|
|
3212
3282
|
) : col.header;
|
|
3213
|
-
return /* @__PURE__ */
|
|
3283
|
+
return /* @__PURE__ */ jsx44(
|
|
3214
3284
|
"th",
|
|
3215
3285
|
{
|
|
3216
3286
|
scope: "col",
|
|
@@ -3227,9 +3297,9 @@ function DataTable({
|
|
|
3227
3297
|
);
|
|
3228
3298
|
})
|
|
3229
3299
|
] }) }),
|
|
3230
|
-
/* @__PURE__ */
|
|
3231
|
-
selectable ? /* @__PURE__ */
|
|
3232
|
-
columns.map((col) => /* @__PURE__ */
|
|
3300
|
+
/* @__PURE__ */ jsx44("tbody", { className: cn(!hasFoot && "[&_tr:last-child_td]:border-b-0"), children: loading ? Array.from({ length: skeletonCount }).map((_, rowIdx) => /* @__PURE__ */ jsxs34("tr", { className: rowClass, "aria-hidden": true, children: [
|
|
3301
|
+
selectable ? /* @__PURE__ */ jsx44("td", { className: cn(selectCellClass, cellPad), children: /* @__PURE__ */ jsx44(Skeleton, { className: "size-4 rounded-[4px]" }) }) : null,
|
|
3302
|
+
columns.map((col) => /* @__PURE__ */ jsx44(
|
|
3233
3303
|
"td",
|
|
3234
3304
|
{
|
|
3235
3305
|
className: cn(
|
|
@@ -3238,17 +3308,17 @@ function DataTable({
|
|
|
3238
3308
|
col.align && alignClass[col.align],
|
|
3239
3309
|
col.className
|
|
3240
3310
|
),
|
|
3241
|
-
children: /* @__PURE__ */
|
|
3311
|
+
children: /* @__PURE__ */ jsx44(Skeleton, { className: "h-4 w-[60%]" })
|
|
3242
3312
|
},
|
|
3243
3313
|
col.id
|
|
3244
3314
|
))
|
|
3245
|
-
] }, `skeleton-${rowIdx}`)) : visibleRows.length === 0 ? /* @__PURE__ */
|
|
3246
|
-
/* @__PURE__ */
|
|
3247
|
-
emptyDescription ? /* @__PURE__ */
|
|
3315
|
+
] }, `skeleton-${rowIdx}`)) : visibleRows.length === 0 ? /* @__PURE__ */ jsx44("tr", { children: /* @__PURE__ */ jsx44("td", { colSpan, className: emptyCellClass, children: /* @__PURE__ */ jsxs34("div", { className: "flex flex-col items-center gap-1", children: [
|
|
3316
|
+
/* @__PURE__ */ jsx44("p", { className: "font-medium text-foreground", children: emptyTitle }),
|
|
3317
|
+
emptyDescription ? /* @__PURE__ */ jsx44("p", { className: "max-w-sm text-muted-foreground", children: emptyDescription }) : null
|
|
3248
3318
|
] }) }) }) : visibleRows.map((row) => {
|
|
3249
3319
|
const key = getRowKey(row);
|
|
3250
3320
|
const isSelected = selectedSet.has(key);
|
|
3251
|
-
return /* @__PURE__ */
|
|
3321
|
+
return /* @__PURE__ */ jsxs34(
|
|
3252
3322
|
"tr",
|
|
3253
3323
|
{
|
|
3254
3324
|
className: rowClass,
|
|
@@ -3264,12 +3334,12 @@ function DataTable({
|
|
|
3264
3334
|
tabIndex: onRowClick ? 0 : void 0,
|
|
3265
3335
|
role: onRowClick ? "button" : void 0,
|
|
3266
3336
|
children: [
|
|
3267
|
-
selectable ? /* @__PURE__ */
|
|
3337
|
+
selectable ? /* @__PURE__ */ jsx44(
|
|
3268
3338
|
"td",
|
|
3269
3339
|
{
|
|
3270
3340
|
className: cn(selectCellClass, cellPad),
|
|
3271
3341
|
onClick: (event) => event.stopPropagation(),
|
|
3272
|
-
children: /* @__PURE__ */
|
|
3342
|
+
children: /* @__PURE__ */ jsx44(
|
|
3273
3343
|
Checkbox,
|
|
3274
3344
|
{
|
|
3275
3345
|
checked: isSelected,
|
|
@@ -3279,16 +3349,17 @@ function DataTable({
|
|
|
3279
3349
|
)
|
|
3280
3350
|
}
|
|
3281
3351
|
) : null,
|
|
3282
|
-
columns.map((col) => /* @__PURE__ */
|
|
3352
|
+
columns.map((col) => /* @__PURE__ */ jsx44(
|
|
3283
3353
|
"td",
|
|
3284
3354
|
{
|
|
3285
3355
|
className: cn(
|
|
3286
3356
|
bodyCellClass,
|
|
3287
3357
|
cellPad,
|
|
3358
|
+
col.truncate && "max-w-0",
|
|
3288
3359
|
col.align && alignClass[col.align],
|
|
3289
3360
|
col.className
|
|
3290
3361
|
),
|
|
3291
|
-
children: col.cell(row)
|
|
3362
|
+
children: col.truncate ? /* @__PURE__ */ jsx44("div", { className: "truncate", children: col.cell(row) }) : col.cell(row)
|
|
3292
3363
|
},
|
|
3293
3364
|
col.id
|
|
3294
3365
|
))
|
|
@@ -3297,7 +3368,7 @@ function DataTable({
|
|
|
3297
3368
|
key
|
|
3298
3369
|
);
|
|
3299
3370
|
}) }),
|
|
3300
|
-
hasFoot ? /* @__PURE__ */
|
|
3371
|
+
hasFoot ? /* @__PURE__ */ jsx44("tfoot", { children: /* @__PURE__ */ jsx44("tr", { children: /* @__PURE__ */ jsx44("td", { colSpan, className: footCellClass, children: /* @__PURE__ */ jsxs34(
|
|
3301
3372
|
"div",
|
|
3302
3373
|
{
|
|
3303
3374
|
className: cn(
|
|
@@ -3305,18 +3376,18 @@ function DataTable({
|
|
|
3305
3376
|
(showRowCount || footer || hasPager) && "justify-between"
|
|
3306
3377
|
),
|
|
3307
3378
|
children: [
|
|
3308
|
-
/* @__PURE__ */
|
|
3309
|
-
showRowCount ? /* @__PURE__ */
|
|
3379
|
+
/* @__PURE__ */ jsxs34("div", { className: footInnerClass, children: [
|
|
3380
|
+
showRowCount ? /* @__PURE__ */ jsxs34("span", { children: [
|
|
3310
3381
|
rowCountText,
|
|
3311
3382
|
selectable && selectedSet.size > 0 ? ` \xB7 ${selectedSet.size} selected` : null
|
|
3312
|
-
] }) : selectable && selectedSet.size > 0 ? /* @__PURE__ */
|
|
3383
|
+
] }) : selectable && selectedSet.size > 0 ? /* @__PURE__ */ jsxs34("span", { children: [
|
|
3313
3384
|
selectedSet.size,
|
|
3314
3385
|
" selected"
|
|
3315
3386
|
] }) : null,
|
|
3316
3387
|
footer
|
|
3317
3388
|
] }),
|
|
3318
|
-
hasPager ? /* @__PURE__ */
|
|
3319
|
-
/* @__PURE__ */
|
|
3389
|
+
hasPager ? /* @__PURE__ */ jsxs34("div", { className: "flex items-center gap-2", children: [
|
|
3390
|
+
/* @__PURE__ */ jsxs34("span", { className: "tabular-nums", children: [
|
|
3320
3391
|
pageIndex * pageSize + 1,
|
|
3321
3392
|
"\u2013",
|
|
3322
3393
|
Math.min(
|
|
@@ -3327,8 +3398,8 @@ function DataTable({
|
|
|
3327
3398
|
"of ",
|
|
3328
3399
|
sortedRows.length
|
|
3329
3400
|
] }),
|
|
3330
|
-
/* @__PURE__ */
|
|
3331
|
-
/* @__PURE__ */
|
|
3401
|
+
/* @__PURE__ */ jsxs34("div", { className: "flex items-center gap-1", children: [
|
|
3402
|
+
/* @__PURE__ */ jsx44(
|
|
3332
3403
|
"button",
|
|
3333
3404
|
{
|
|
3334
3405
|
type: "button",
|
|
@@ -3336,10 +3407,10 @@ function DataTable({
|
|
|
3336
3407
|
onClick: () => setPage(pageIndex - 1),
|
|
3337
3408
|
disabled: pageIndex <= 0,
|
|
3338
3409
|
"aria-label": "Previous page",
|
|
3339
|
-
children: /* @__PURE__ */
|
|
3410
|
+
children: /* @__PURE__ */ jsx44(ChevronLeftIcon, { className: "size-4", "aria-hidden": true })
|
|
3340
3411
|
}
|
|
3341
3412
|
),
|
|
3342
|
-
/* @__PURE__ */
|
|
3413
|
+
/* @__PURE__ */ jsx44(
|
|
3343
3414
|
"button",
|
|
3344
3415
|
{
|
|
3345
3416
|
type: "button",
|
|
@@ -3347,7 +3418,7 @@ function DataTable({
|
|
|
3347
3418
|
onClick: () => setPage(pageIndex + 1),
|
|
3348
3419
|
disabled: pageIndex >= pageCount - 1,
|
|
3349
3420
|
"aria-label": "Next page",
|
|
3350
|
-
children: /* @__PURE__ */
|
|
3421
|
+
children: /* @__PURE__ */ jsx44(ChevronRightIcon, { className: "size-4", "aria-hidden": true })
|
|
3351
3422
|
}
|
|
3352
3423
|
)
|
|
3353
3424
|
] })
|
|
@@ -3360,28 +3431,32 @@ function DataTable({
|
|
|
3360
3431
|
|
|
3361
3432
|
// src/app/data/ChartPanel.tsx
|
|
3362
3433
|
import { useId as useId4 } from "react";
|
|
3363
|
-
import { jsx as
|
|
3434
|
+
import { jsx as jsx45, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
3364
3435
|
var ChartPanel = ({
|
|
3365
3436
|
title,
|
|
3366
3437
|
description,
|
|
3367
3438
|
artifact,
|
|
3368
3439
|
children,
|
|
3369
3440
|
actions,
|
|
3370
|
-
height
|
|
3441
|
+
height: heightProp,
|
|
3371
3442
|
loading = false,
|
|
3372
3443
|
className
|
|
3373
3444
|
}) => {
|
|
3445
|
+
const density = useAppDensity();
|
|
3446
|
+
const height = heightProp ?? APP_DENSITY_CHART_HEIGHT[density];
|
|
3447
|
+
const metricChartPlotRegionClass = useAppDensityClass("metricChartPlotRegion");
|
|
3448
|
+
const chartPanelBodyClass = useAppDensityClass("chartPanelBody");
|
|
3374
3449
|
const titleId = useId4();
|
|
3375
3450
|
const resolvedTitle = title ?? artifact?.title;
|
|
3376
3451
|
const hasHeader = Boolean(resolvedTitle || description || actions);
|
|
3377
|
-
const body = loading ? /* @__PURE__ */
|
|
3378
|
-
return /* @__PURE__ */
|
|
3452
|
+
const body = loading ? /* @__PURE__ */ jsx45(Skeleton, { className: "w-full rounded-lg", style: { height }, "aria-hidden": true }) : children ?? (artifact ? /* @__PURE__ */ jsx45(ChartArtifactView, { artifact, embedded: true, height }) : null);
|
|
3453
|
+
return /* @__PURE__ */ jsxs35(
|
|
3379
3454
|
"section",
|
|
3380
3455
|
{
|
|
3381
3456
|
className: cn(metricCardShellClass, "aui-app-chart-panel", className),
|
|
3382
3457
|
"aria-labelledby": resolvedTitle ? titleId : void 0,
|
|
3383
3458
|
children: [
|
|
3384
|
-
/* @__PURE__ */
|
|
3459
|
+
/* @__PURE__ */ jsx45(
|
|
3385
3460
|
MetricCardHeader,
|
|
3386
3461
|
{
|
|
3387
3462
|
title: resolvedTitle,
|
|
@@ -3390,14 +3465,14 @@ var ChartPanel = ({
|
|
|
3390
3465
|
actions
|
|
3391
3466
|
}
|
|
3392
3467
|
),
|
|
3393
|
-
/* @__PURE__ */
|
|
3468
|
+
/* @__PURE__ */ jsx45(
|
|
3394
3469
|
"div",
|
|
3395
3470
|
{
|
|
3396
3471
|
className: cn(
|
|
3397
3472
|
"relative min-h-0 w-full",
|
|
3398
|
-
hasHeader ? metricChartPlotRegionClass :
|
|
3473
|
+
hasHeader ? metricChartPlotRegionClass : chartPanelBodyClass
|
|
3399
3474
|
),
|
|
3400
|
-
children: body ?? /* @__PURE__ */
|
|
3475
|
+
children: body ?? /* @__PURE__ */ jsx45(
|
|
3401
3476
|
"div",
|
|
3402
3477
|
{
|
|
3403
3478
|
className: "flex items-center justify-center text-sm font-normal text-muted-foreground",
|
|
@@ -3415,7 +3490,7 @@ var ChartPanel = ({
|
|
|
3415
3490
|
|
|
3416
3491
|
// src/app/data/MetricRow.tsx
|
|
3417
3492
|
import { useId as useId5, useState as useState5 } from "react";
|
|
3418
|
-
import { jsx as
|
|
3493
|
+
import { jsx as jsx46, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
3419
3494
|
var MetricRow = ({
|
|
3420
3495
|
title,
|
|
3421
3496
|
description,
|
|
@@ -3428,6 +3503,7 @@ var MetricRow = ({
|
|
|
3428
3503
|
loading = false,
|
|
3429
3504
|
className
|
|
3430
3505
|
}) => {
|
|
3506
|
+
const metricTileClass = useAppDensityClass("metricTile");
|
|
3431
3507
|
const titleId = useId5();
|
|
3432
3508
|
const selectable = onMetricChange != null || activeMetricId != null;
|
|
3433
3509
|
const [internalId, setInternalId] = useState5(
|
|
@@ -3438,13 +3514,13 @@ var MetricRow = ({
|
|
|
3438
3514
|
if (activeMetricId == null) setInternalId(id);
|
|
3439
3515
|
onMetricChange?.(id);
|
|
3440
3516
|
};
|
|
3441
|
-
return /* @__PURE__ */
|
|
3517
|
+
return /* @__PURE__ */ jsxs36(
|
|
3442
3518
|
"section",
|
|
3443
3519
|
{
|
|
3444
3520
|
className: cn(metricCardShellClass, className),
|
|
3445
3521
|
"aria-labelledby": title ? titleId : void 0,
|
|
3446
3522
|
children: [
|
|
3447
|
-
/* @__PURE__ */
|
|
3523
|
+
/* @__PURE__ */ jsx46(
|
|
3448
3524
|
MetricCardHeader,
|
|
3449
3525
|
{
|
|
3450
3526
|
title,
|
|
@@ -3453,7 +3529,7 @@ var MetricRow = ({
|
|
|
3453
3529
|
actions
|
|
3454
3530
|
}
|
|
3455
3531
|
),
|
|
3456
|
-
/* @__PURE__ */
|
|
3532
|
+
/* @__PURE__ */ jsx46(
|
|
3457
3533
|
"div",
|
|
3458
3534
|
{
|
|
3459
3535
|
role: selectable ? "group" : void 0,
|
|
@@ -3464,18 +3540,18 @@ var MetricRow = ({
|
|
|
3464
3540
|
metricTilesGridColsClass(loading ? metrics.length || 4 : metrics.length),
|
|
3465
3541
|
(title || description || actions) && "mt-3"
|
|
3466
3542
|
),
|
|
3467
|
-
children: loading ? Array.from({ length: metrics.length || 4 }).map((_, index) => /* @__PURE__ */
|
|
3543
|
+
children: loading ? Array.from({ length: metrics.length || 4 }).map((_, index) => /* @__PURE__ */ jsxs36(
|
|
3468
3544
|
"div",
|
|
3469
3545
|
{
|
|
3470
|
-
className: "flex min-w-0 flex-1 flex-col gap-2
|
|
3546
|
+
className: cn("flex min-w-0 flex-1 flex-col gap-2", metricTileClass),
|
|
3471
3547
|
"aria-hidden": true,
|
|
3472
3548
|
children: [
|
|
3473
|
-
/* @__PURE__ */
|
|
3474
|
-
/* @__PURE__ */
|
|
3549
|
+
/* @__PURE__ */ jsx46(Skeleton, { className: "h-3 w-20" }),
|
|
3550
|
+
/* @__PURE__ */ jsx46(Skeleton, { className: "h-7 w-24" })
|
|
3475
3551
|
]
|
|
3476
3552
|
},
|
|
3477
3553
|
`skeleton-${index}`
|
|
3478
|
-
)) : metrics.map((m, index) => /* @__PURE__ */
|
|
3554
|
+
)) : metrics.map((m, index) => /* @__PURE__ */ jsx46(
|
|
3479
3555
|
MetricTile,
|
|
3480
3556
|
{
|
|
3481
3557
|
label: m.label,
|
|
@@ -3498,7 +3574,7 @@ var MetricRow = ({
|
|
|
3498
3574
|
|
|
3499
3575
|
// src/app/data/MetricChartCard.tsx
|
|
3500
3576
|
import { useId as useId6, useState as useState6 } from "react";
|
|
3501
|
-
import { jsx as
|
|
3577
|
+
import { jsx as jsx47, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
3502
3578
|
var MetricChartCard = ({
|
|
3503
3579
|
title,
|
|
3504
3580
|
description,
|
|
@@ -3509,7 +3585,7 @@ var MetricChartCard = ({
|
|
|
3509
3585
|
onMetricChange,
|
|
3510
3586
|
xKey = "date",
|
|
3511
3587
|
variant = "area",
|
|
3512
|
-
height
|
|
3588
|
+
height: heightProp,
|
|
3513
3589
|
formatX,
|
|
3514
3590
|
formatValue,
|
|
3515
3591
|
emptyLabel = "No data yet",
|
|
@@ -3517,6 +3593,10 @@ var MetricChartCard = ({
|
|
|
3517
3593
|
loading = false,
|
|
3518
3594
|
className
|
|
3519
3595
|
}) => {
|
|
3596
|
+
const density = useAppDensity();
|
|
3597
|
+
const height = heightProp ?? APP_DENSITY_CHART_HEIGHT[density];
|
|
3598
|
+
const metricChartRegionClass = useAppDensityClass("metricChartRegion");
|
|
3599
|
+
const metricTileClass = useAppDensityClass("metricTile");
|
|
3520
3600
|
const titleId = useId6();
|
|
3521
3601
|
const [internalId, setInternalId] = useState6(
|
|
3522
3602
|
defaultActiveMetricId ?? metrics[0]?.id
|
|
@@ -3529,13 +3609,13 @@ var MetricChartCard = ({
|
|
|
3529
3609
|
};
|
|
3530
3610
|
const hasHeader = Boolean(title || description || actions);
|
|
3531
3611
|
const chartAriaLabel = typeof active?.label === "string" ? `${active.label} over time` : "Metric chart";
|
|
3532
|
-
return /* @__PURE__ */
|
|
3612
|
+
return /* @__PURE__ */ jsxs37(
|
|
3533
3613
|
"section",
|
|
3534
3614
|
{
|
|
3535
3615
|
className: cn(metricCardShellClass, className),
|
|
3536
3616
|
"aria-labelledby": title ? titleId : void 0,
|
|
3537
3617
|
children: [
|
|
3538
|
-
/* @__PURE__ */
|
|
3618
|
+
/* @__PURE__ */ jsx47(
|
|
3539
3619
|
MetricCardHeader,
|
|
3540
3620
|
{
|
|
3541
3621
|
title,
|
|
@@ -3544,7 +3624,7 @@ var MetricChartCard = ({
|
|
|
3544
3624
|
actions
|
|
3545
3625
|
}
|
|
3546
3626
|
),
|
|
3547
|
-
/* @__PURE__ */
|
|
3627
|
+
/* @__PURE__ */ jsx47(
|
|
3548
3628
|
"div",
|
|
3549
3629
|
{
|
|
3550
3630
|
role: "group",
|
|
@@ -3555,18 +3635,18 @@ var MetricChartCard = ({
|
|
|
3555
3635
|
metricTilesGridColsClass(loading ? metrics.length || 4 : metrics.length),
|
|
3556
3636
|
hasHeader && "mt-3"
|
|
3557
3637
|
),
|
|
3558
|
-
children: loading ? Array.from({ length: metrics.length || 4 }).map((_, index) => /* @__PURE__ */
|
|
3638
|
+
children: loading ? Array.from({ length: metrics.length || 4 }).map((_, index) => /* @__PURE__ */ jsxs37(
|
|
3559
3639
|
"div",
|
|
3560
3640
|
{
|
|
3561
|
-
className: "flex min-w-0 flex-1 flex-col gap-2
|
|
3641
|
+
className: cn("flex min-w-0 flex-1 flex-col gap-2", metricTileClass),
|
|
3562
3642
|
"aria-hidden": true,
|
|
3563
3643
|
children: [
|
|
3564
|
-
/* @__PURE__ */
|
|
3565
|
-
/* @__PURE__ */
|
|
3644
|
+
/* @__PURE__ */ jsx47(Skeleton, { className: "h-3 w-20" }),
|
|
3645
|
+
/* @__PURE__ */ jsx47(Skeleton, { className: "h-7 w-24" })
|
|
3566
3646
|
]
|
|
3567
3647
|
},
|
|
3568
3648
|
`skeleton-${index}`
|
|
3569
|
-
)) : metrics.map((m, index) => /* @__PURE__ */
|
|
3649
|
+
)) : metrics.map((m, index) => /* @__PURE__ */ jsx47(
|
|
3570
3650
|
MetricTile,
|
|
3571
3651
|
{
|
|
3572
3652
|
label: m.label,
|
|
@@ -3582,14 +3662,14 @@ var MetricChartCard = ({
|
|
|
3582
3662
|
))
|
|
3583
3663
|
}
|
|
3584
3664
|
),
|
|
3585
|
-
/* @__PURE__ */
|
|
3665
|
+
/* @__PURE__ */ jsx47("div", { className: metricChartRegionClass, "aria-live": "polite", "aria-atomic": "true", children: loading ? /* @__PURE__ */ jsx47(
|
|
3586
3666
|
Skeleton,
|
|
3587
3667
|
{
|
|
3588
3668
|
className: "w-full rounded-lg",
|
|
3589
3669
|
style: { height },
|
|
3590
3670
|
"aria-hidden": true
|
|
3591
3671
|
}
|
|
3592
|
-
) : active?.data && active.data.length > 0 ? /* @__PURE__ */
|
|
3672
|
+
) : active?.data && active.data.length > 0 ? /* @__PURE__ */ jsx47(
|
|
3593
3673
|
LineAreaChart,
|
|
3594
3674
|
{
|
|
3595
3675
|
data: active.data,
|
|
@@ -3609,7 +3689,7 @@ var MetricChartCard = ({
|
|
|
3609
3689
|
ariaLabel: chartAriaLabel
|
|
3610
3690
|
},
|
|
3611
3691
|
active.id
|
|
3612
|
-
) : /* @__PURE__ */
|
|
3692
|
+
) : /* @__PURE__ */ jsx47(
|
|
3613
3693
|
"div",
|
|
3614
3694
|
{
|
|
3615
3695
|
className: "flex w-full items-center justify-center text-sm font-normal text-muted-foreground",
|
|
@@ -3715,7 +3795,7 @@ function useLiveQuery(fetcher, options = {}) {
|
|
|
3715
3795
|
|
|
3716
3796
|
// src/charts/sparkline.tsx
|
|
3717
3797
|
import { useId as useId7 } from "react";
|
|
3718
|
-
import { Fragment as Fragment6, jsx as
|
|
3798
|
+
import { Fragment as Fragment6, jsx as jsx48, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
3719
3799
|
var Sparkline = ({
|
|
3720
3800
|
data,
|
|
3721
3801
|
dataKey = "value",
|
|
@@ -3730,7 +3810,7 @@ var Sparkline = ({
|
|
|
3730
3810
|
const uid = useId7();
|
|
3731
3811
|
const values = data.map((d) => typeof d === "number" ? d : toNum(d[dataKey]));
|
|
3732
3812
|
if (values.length === 0) {
|
|
3733
|
-
return /* @__PURE__ */
|
|
3813
|
+
return /* @__PURE__ */ jsx48("span", { className: cn("inline-block", className), style: { width, height } });
|
|
3734
3814
|
}
|
|
3735
3815
|
const pad = strokeWidth + 1;
|
|
3736
3816
|
const min = Math.min(...values);
|
|
@@ -3742,7 +3822,7 @@ var Sparkline = ({
|
|
|
3742
3822
|
x: pad + (values.length > 1 ? i / (values.length - 1) * innerW : innerW / 2),
|
|
3743
3823
|
y: pad + innerH - (v - min) / range * innerH
|
|
3744
3824
|
}));
|
|
3745
|
-
return /* @__PURE__ */
|
|
3825
|
+
return /* @__PURE__ */ jsxs38(
|
|
3746
3826
|
"svg",
|
|
3747
3827
|
{
|
|
3748
3828
|
width,
|
|
@@ -3753,14 +3833,14 @@ var Sparkline = ({
|
|
|
3753
3833
|
"aria-label": ariaLabel,
|
|
3754
3834
|
preserveAspectRatio: "none",
|
|
3755
3835
|
children: [
|
|
3756
|
-
area && /* @__PURE__ */
|
|
3757
|
-
/* @__PURE__ */
|
|
3758
|
-
/* @__PURE__ */
|
|
3759
|
-
/* @__PURE__ */
|
|
3836
|
+
area && /* @__PURE__ */ jsxs38(Fragment6, { children: [
|
|
3837
|
+
/* @__PURE__ */ jsx48("defs", { children: /* @__PURE__ */ jsxs38("linearGradient", { id: `${uid}-spark`, x1: "0", x2: "0", y1: "0", y2: "1", children: [
|
|
3838
|
+
/* @__PURE__ */ jsx48("stop", { offset: "0%", style: { stopColor: color, stopOpacity: 0.25 } }),
|
|
3839
|
+
/* @__PURE__ */ jsx48("stop", { offset: "100%", style: { stopColor: color, stopOpacity: 0 } })
|
|
3760
3840
|
] }) }),
|
|
3761
|
-
/* @__PURE__ */
|
|
3841
|
+
/* @__PURE__ */ jsx48("path", { d: monotoneAreaPath(points, height - pad), fill: `url(#${uid}-spark)` })
|
|
3762
3842
|
] }),
|
|
3763
|
-
/* @__PURE__ */
|
|
3843
|
+
/* @__PURE__ */ jsx48(
|
|
3764
3844
|
"path",
|
|
3765
3845
|
{
|
|
3766
3846
|
d: monotoneLinePath(points),
|
|
@@ -3799,8 +3879,6 @@ export {
|
|
|
3799
3879
|
getStoredThemePreset,
|
|
3800
3880
|
THEME_AGENT_INSTRUCTIONS,
|
|
3801
3881
|
TimbalThemeStyle,
|
|
3802
|
-
MetricTile,
|
|
3803
|
-
ThemePresetGallery,
|
|
3804
3882
|
appPageColumnClass,
|
|
3805
3883
|
appShellTopbarInsetClass,
|
|
3806
3884
|
appShellInsetTopClass,
|
|
@@ -3808,6 +3886,13 @@ export {
|
|
|
3808
3886
|
appStatTileClass,
|
|
3809
3887
|
appFilterBarClass,
|
|
3810
3888
|
appSearchInputClass,
|
|
3889
|
+
APP_DENSITY_CHART_HEIGHT,
|
|
3890
|
+
APP_DENSITY_CLASSES,
|
|
3891
|
+
appDensityClass,
|
|
3892
|
+
AppDensityProvider,
|
|
3893
|
+
useAppDensity,
|
|
3894
|
+
useAppDensityClass,
|
|
3895
|
+
MetricTile,
|
|
3811
3896
|
useAppShellChat,
|
|
3812
3897
|
useAppShellNav,
|
|
3813
3898
|
AppShell,
|