@timbal-ai/timbal-react 1.2.0 → 1.4.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 +38 -0
- package/LICENSE +201 -0
- package/README.md +17 -4
- package/dist/app.cjs +1299 -1137
- package/dist/app.d.cts +21 -5
- package/dist/app.d.ts +21 -5
- package/dist/app.esm.js +17 -7
- package/dist/{chart-artifact-E58ve76I.d.cts → chart-artifact-C8-Py6lc.d.cts} +97 -27
- package/dist/{chart-artifact-_PEJgCpQ.d.ts → chart-artifact-CMnDys2t.d.ts} +97 -27
- package/dist/chat.esm.js +3 -3
- package/dist/{chunk-UY7AKWJL.esm.js → chunk-GQBYZRD7.esm.js} +1 -1
- package/dist/{chunk-AGJKK6R7.esm.js → chunk-OFWC4MIY.esm.js} +2 -2
- package/dist/{chunk-4VULP3CJ.esm.js → chunk-OH23AX2V.esm.js} +757 -56
- package/dist/{chunk-BMXFXLVV.esm.js → chunk-QU7ET55D.esm.js} +0 -1
- package/dist/{chunk-MTYXREHK.esm.js → chunk-THBA27QY.esm.js} +4 -4
- package/dist/{chunk-FEYZUVBM.esm.js → chunk-UCGVL7ZY.esm.js} +1 -1
- package/dist/{chunk-XDIY2WSL.esm.js → chunk-VOWNCS3F.esm.js} +649 -494
- package/dist/{chunk-NAMKO2MU.esm.js → chunk-VXMM2HX7.esm.js} +1 -1
- package/dist/{pill-segmented-tabs-BsIOW1Lo.d.ts → circular-progress-Ci8L-Hfa.d.cts} +199 -3
- package/dist/{pill-segmented-tabs-BsIOW1Lo.d.cts → circular-progress-Ci8L-Hfa.d.ts} +199 -3
- package/dist/index.cjs +1797 -938
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.esm.js +28 -10
- package/dist/studio.esm.js +5 -5
- package/dist/ui.cjs +758 -49
- package/dist/ui.d.cts +1 -1
- package/dist/ui.d.ts +1 -1
- package/dist/ui.esm.js +24 -4
- package/package.json +1 -1
|
@@ -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 = [
|
|
@@ -239,6 +239,40 @@ You are **not** required to copy any example layout, page title, section order,
|
|
|
239
239
|
|
|
240
240
|
When in doubt: compose from the **component menu** + **guidelines**, then adapt creatively to the request.
|
|
241
241
|
|
|
242
|
+
### Layout archetypes \u2014 pick the shape that fits (don't default to one)
|
|
243
|
+
|
|
244
|
+
The most common failure is shipping the **same** layout every time: sidebar + topbar + \`Page\` + one \`MetricRow\` + one full-width \`DataTable\`. That is *one* archetype, not *the* layout. Choose deliberately \u2014 different domains want different shapes, and varying the shell/page composition is encouraged.
|
|
245
|
+
|
|
246
|
+
| Archetype | When | Compose |
|
|
247
|
+
|-----------|------|---------|
|
|
248
|
+
| **Sidebar dashboard** | Multi-section product (CRM, billing, ops) with nav | \`StudioSidebar\` in \`AppShell.sidebar\` + \`Page\` \u2192 \`Section\` |
|
|
249
|
+
| **Focused / no-chrome** | A single tool or one-screen utility | \`AppShell\` (no sidebar) + \`Page\` (optionally just \`AppShellTopbar\`); or a centered narrow column |
|
|
250
|
+
| **Bento overview** | Home / at-a-glance dashboards | \`Page\` + an **asymmetric grid** of \`SurfaceCard\` / \`ChartPanel\` / \`StatTile\` spanning different widths (not a uniform row + table) |
|
|
251
|
+
| **Split master\u2013detail** | Inbox, triage queue, record browser, log explorer | \`AppShell contentFill\` + \`Page fill\` + a two-column flex row, each pane \`min-h-0 overflow-y-auto\` |
|
|
252
|
+
| **Full-page chat / canvas** | Chat-first app, editor, map, single full-bleed surface | \`AppShell contentFill\` + headerless \`Page fill\` + a \`min-h-0 flex-1\` child (e.g. \`TimbalChat\`) |
|
|
253
|
+
| **Copilot overlay** | A data app that also wants an assistant | any of the above + \`AppShell chat={<AppChatPanel />}\` (floating, never a second column) |
|
|
254
|
+
| **Section-switcher** | One page, several views | \`SubNav\` / \`PillSegmentedTabs\` (\`trackVariant="flush"\`) switching panels with state/router |
|
|
255
|
+
|
|
256
|
+
Mix them: vary the grid columns, density, header placement (\`Page\` actions vs. a global \`AppShellTopbar\`), and whether there's a sidebar at all. Two dashboards for two domains should not look identical.
|
|
257
|
+
|
|
258
|
+
### Full-height pages (chat, canvas, split views)
|
|
259
|
+
|
|
260
|
+
The content region is a **padded scroll area** by default \u2014 great for stacked \`Page\` \u2192 \`Section\` content, wrong for a surface that must fill the viewport. For full-bleed pages:
|
|
261
|
+
|
|
262
|
+
- Pass **\`contentFill\`** to \`AppShell\` \u2192 the content region becomes a bounded, non-scrolling flex column (clipped, no bottom padding).
|
|
263
|
+
- Pass **\`fill\`** to \`Page\` \u2192 the page becomes a \`min-h-0 flex-1\` flex column.
|
|
264
|
+
- Give the filling child **\`min-h-0 flex-1\`** (or \`h-full\`) so its own scroll/footer resolves \u2014 e.g. \`<TimbalChat className="min-h-0 flex-1" />\`, or a two-pane row where each pane is \`min-h-0 overflow-y-auto\`.
|
|
265
|
+
|
|
266
|
+
\`\`\`tsx
|
|
267
|
+
<AppShell contentFill topbar={<AppShellTopbar actions={<ModeToggle />} />}>
|
|
268
|
+
<Page fill> {/* headerless: omit title */}
|
|
269
|
+
<TimbalChat workforceId="\u2026" className="min-h-0 flex-1" />
|
|
270
|
+
</Page>
|
|
271
|
+
</AppShell>
|
|
272
|
+
\`\`\`
|
|
273
|
+
|
|
274
|
+
**Don't** size full-height content with \`h-[calc(100dvh-\u2026)]\` (guesses chrome height \u2192 spurious scrollbar) or \`min-h-[\u2026]\` (free-growing floor \u2192 a pinned footer like the chat composer rides down on scroll). Let \`contentFill\` + \`fill\` provide the bounded height. \`Page\` with no \`title\` renders **no header** \u2014 you don't need to abandon \`Page\` to drop a heading.
|
|
275
|
+
|
|
242
276
|
### Module layout (source folders)
|
|
243
277
|
|
|
244
278
|
Presentational groups \u2014 import from the package root, not from these paths:
|
|
@@ -254,7 +288,7 @@ Presentational groups \u2014 import from the package root, not from these paths:
|
|
|
254
288
|
|
|
255
289
|
Also re-exported: \`Button\`, \`TimbalChat\`, \`ChartArtifactView\`, \`APP_KIT_AGENT_INSTRUCTIONS\`.
|
|
256
290
|
|
|
257
|
-
Theming helpers (import from the package root or \`/app\`): \`createTimbalTheme\`, \`themeToCss\`, \`applyTimbalTheme\`, \`TIMBAL_THEME_PRESETS\`, \`applyThemePreset\`, \`
|
|
291
|
+
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
292
|
|
|
259
293
|
### Design guidelines (required)
|
|
260
294
|
|
|
@@ -263,8 +297,9 @@ Theming helpers (import from the package root or \`/app\`): \`createTimbalTheme\
|
|
|
263
297
|
| **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
298
|
| **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
299
|
| **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.
|
|
300
|
+
| **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\`. |
|
|
301
|
+
| **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. |
|
|
302
|
+
| **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
303
|
| **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
304
|
| **Modals** | Use \`AppConfirmDialog\` for destructive/export confirmations. |
|
|
270
305
|
| **Metrics** | Overview KPIs \u2192 \`MetricRow\` or \`MetricChartCard\` (not four separate heavy cards). Values use **normal** font weight, not bold. |
|
|
@@ -296,13 +331,13 @@ The cause of slop is dropping **below** the curated block layer into raw primiti
|
|
|
296
331
|
|
|
297
332
|
| Component | Use for |
|
|
298
333
|
|-----------|---------|
|
|
299
|
-
| \`AppShell\` | Shell: optional \`sidebar\`, \`topbar\`, main \`children\`, optional floating \`chat\`. Props: \`chatTriggerLabel\`, \`chatCollapsible\`, \`chatWidth\`, \`chatHeight\`, controlled \`chatOpen
|
|
334
|
+
| \`AppShell\` | Shell: optional \`sidebar\`, \`topbar\`, main \`children\`, optional floating \`chat\`. Props: \`chatTriggerLabel\`, \`chatCollapsible\`, \`chatWidth\`, \`chatHeight\`, controlled \`chatOpen\`, **\`contentFill\`** (bounded non-scrolling content region for full-bleed pages \u2014 chat/canvas/split view). |
|
|
300
335
|
| \`AppShellTopbar\` | Full-width top bar: \`start\`, \`actions\` slots. |
|
|
301
336
|
| \`AppCopilotProvider\` | React context for copilot-aware tools (page, filters, selection, etc.). |
|
|
302
337
|
| \`AppChatPanel\` | Floating thread: \`workforceId\`, \`welcome\`, \`debug\`. |
|
|
303
338
|
| \`useAppShellChat\` | Custom open/close trigger when \`hideChatTrigger\` on shell. |
|
|
304
|
-
| \`Page\` | Page title, description, \`breadcrumbs\`, \`actions\`, children. |
|
|
305
|
-
| \`Section\` | Titled block inside a page. |
|
|
339
|
+
| \`Page\` | Page title, description, \`breadcrumbs\`, \`actions\`, \`density\` (\`"default"\` | \`"compact"\`), children. **\`title\` is optional** \u2014 omit it for a headerless page (no \`<h1>\`). **\`fill\`** makes it a \`min-h-0 flex-1\` column for full-height content (pair with \`AppShell contentFill\`). |
|
|
340
|
+
| \`Section\` | Titled block inside a page. Optional \`density\` overrides inherited page density. |
|
|
306
341
|
| \`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
342
|
| **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
343
|
| \`Breadcrumbs\` | Trail: \`items: [{ label, href? }]\`. |
|
|
@@ -314,7 +349,7 @@ The cause of slop is dropping **below** the curated block layer into raw primiti
|
|
|
314
349
|
| \`SearchInput\` | Filter field with consistent app styling. |
|
|
315
350
|
| \`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\`). |
|
|
316
351
|
| \`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\`. |
|
|
317
|
-
| \`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. |
|
|
352
|
+
| \`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. |
|
|
318
353
|
| \`FieldInput\`, \`FieldTextarea\`, \`FieldSelect\`, \`FieldSwitch\` | Settings-style forms with labels and hints. |
|
|
319
354
|
| \`FormSection\` | Grouped form block. |
|
|
320
355
|
| \`AppConfirmDialog\` | Confirm/cancel modal: \`open\`, \`onOpenChange\`, \`title\`, \`description\`, \`onConfirm\`. |
|
|
@@ -334,7 +369,7 @@ Charts run on **recharts** with shadcn \`ChartContainer\` / \`ChartTooltipConten
|
|
|
334
369
|
| \`Sparkline\` | Tiny inline trend (table cells): \`data\`, \`color\`, \`area\`. |
|
|
335
370
|
| \`MetricTile\` | Low-level KPI cell \u2014 prefer \`MetricRow\` / \`MetricChartCard\` instead of hand-wiring tiles. |
|
|
336
371
|
| \`MetricRow\` | KPI strip in one elevated card (no chart). Props: \`metrics: [{ id, label, value, unit?, trend?, trendTone? }]\`, optional \`onMetricChange\`, \`metricsAriaLabel\`, \`loading\` (skeleton tiles). |
|
|
337
|
-
| \`MetricChartCard\` | KPI strip + flush chart; tile click swaps series. Same metrics shape + \`data\` per metric. Default chart height 300. \`loading\` renders skeleton tiles + chart. |
|
|
372
|
+
| \`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. |
|
|
338
373
|
|
|
339
374
|
#### Settings
|
|
340
375
|
|
|
@@ -394,10 +429,13 @@ Ready-made **section patterns** assembled from the components above. Each is a c
|
|
|
394
429
|
- **Empty states** \u2014 no-data / no-results / first-run. Compose \`EmptyState\` + \`Card\` + \`Button\`.
|
|
395
430
|
- **Sign-in card** \u2014 centered auth entry. Compose \`Card\` + \`Input\` + \`Label\` + \`Button\`.
|
|
396
431
|
|
|
397
|
-
**Shells &
|
|
432
|
+
**Shells & layouts**
|
|
398
433
|
- **Minimal shell** \u2014 \`AppShell\` + \`Page\` (no sidebar/chat).
|
|
434
|
+
- **Bento dashboard** \u2014 \`Page\` + an asymmetric grid of \`SurfaceCard\` / \`ChartPanel\` / \`StatTile\` (varied spans) for overview/home screens.
|
|
435
|
+
- **Split view** \u2014 master\u2013detail: \`AppShell contentFill\` + \`Page fill\` + a two-pane flex row (list + detail), each pane \`min-h-0 overflow-y-auto\`.
|
|
436
|
+
- **Full-page chat** \u2014 \`AppShell contentFill\` + headerless \`Page fill\` + \`TimbalChat className="min-h-0 flex-1"\` (composer pinned; no \`h-[calc(...)]\`).
|
|
399
437
|
- **Copilot overlay** \u2014 \`AppShell\` + floating \`AppChatPanel\`.
|
|
400
|
-
- **Theme presets** \u2014 \`
|
|
438
|
+
- **Theme presets** \u2014 apply a brand preset programmatically (\`applyThemePreset\` / \`applyTimbalTheme\`); never hand-author OKLCH and don't expose a theme picker to end users.
|
|
401
439
|
|
|
402
440
|
### Typical compositions
|
|
403
441
|
|
|
@@ -1282,8 +1320,7 @@ Each preset is a **full personality** (color + radius + shadows + font), not jus
|
|
|
1282
1320
|
| \`folio\` | Editorial serif (Fraunces), near-sharp corners \u2014 content / docs |
|
|
1283
1321
|
| \`carbon\` | Terminal monospace (JetBrains Mono), green accent \u2014 dev / infra |
|
|
1284
1322
|
|
|
1285
|
-
-
|
|
1286
|
-
- On selection, call \`applyThemePreset(id)\` (persists to \`localStorage\` and restores on reload).
|
|
1323
|
+
- 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.
|
|
1287
1324
|
|
|
1288
1325
|
### Rules
|
|
1289
1326
|
|
|
@@ -1317,17 +1354,142 @@ var TimbalThemeStyle = ({
|
|
|
1317
1354
|
] });
|
|
1318
1355
|
};
|
|
1319
1356
|
|
|
1357
|
+
// src/design/app-classes.ts
|
|
1358
|
+
var appPageColumnClass = "mx-auto w-full max-w-[100rem] px-4 md:px-6 lg:px-8";
|
|
1359
|
+
var appShellTopbarInsetClass = "w-full px-4 md:px-6";
|
|
1360
|
+
var appShellInsetTopClass = "pt-4 md:pt-6";
|
|
1361
|
+
var appShellInsetBottomClass = "pb-8 md:pb-10";
|
|
1362
|
+
var appShellTopbarRowClass = cn(
|
|
1363
|
+
studioTopbarPillHeightClass,
|
|
1364
|
+
"flex w-full items-center justify-between gap-2"
|
|
1365
|
+
);
|
|
1366
|
+
var appShellTopbarStickyClass = cn(
|
|
1367
|
+
"shrink-0 bg-background pb-2",
|
|
1368
|
+
appShellInsetTopClass
|
|
1369
|
+
);
|
|
1370
|
+
var appPageHeaderClass = cn(
|
|
1371
|
+
"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",
|
|
1372
|
+
"pb-4 pt-2"
|
|
1373
|
+
);
|
|
1374
|
+
var appSectionClass = "flex flex-col gap-4 py-4";
|
|
1375
|
+
var appSectionTitleClass = "text-lg font-semibold text-foreground";
|
|
1376
|
+
var appSectionDescriptionClass = "text-sm text-muted-foreground";
|
|
1377
|
+
var appSurfaceCardClass = cn(
|
|
1378
|
+
studioIntegrationCardClass,
|
|
1379
|
+
"p-4 md:p-5"
|
|
1380
|
+
);
|
|
1381
|
+
var appStatTileClass = cn(
|
|
1382
|
+
appSurfaceCardClass,
|
|
1383
|
+
"flex flex-col gap-1 px-4 py-3 shadow-none"
|
|
1384
|
+
);
|
|
1385
|
+
var appStatValueClass = "text-2xl font-normal tracking-tight text-foreground tabular-nums";
|
|
1386
|
+
var appStatLabelClass = "text-xs font-normal text-muted-foreground";
|
|
1387
|
+
var appFilterBarClass = "flex flex-wrap items-end gap-2";
|
|
1388
|
+
var appSearchInputClass = controlClass({}, "inline-flex items-center gap-2");
|
|
1389
|
+
var appBreadcrumbsClass = "flex flex-wrap items-center gap-1.5 text-sm text-muted-foreground";
|
|
1390
|
+
var appBreadcrumbLinkClass = "transition-colors hover:text-foreground";
|
|
1391
|
+
var appFieldClass = "flex flex-col gap-1.5";
|
|
1392
|
+
var appFieldLabelClass = "text-sm font-medium text-foreground";
|
|
1393
|
+
var appFieldHintClass = "text-xs text-muted-foreground";
|
|
1394
|
+
var appInputClass = controlClass({}, "w-full");
|
|
1395
|
+
var appEmptyStateClass = cn(
|
|
1396
|
+
appSurfaceCardClass,
|
|
1397
|
+
"flex flex-col items-center justify-center gap-2 py-12 text-center"
|
|
1398
|
+
);
|
|
1399
|
+
var appEmptyStateTitleClass = "text-base font-medium text-foreground";
|
|
1400
|
+
var appEmptyStateDescriptionClass = "max-w-sm text-sm text-muted-foreground";
|
|
1401
|
+
var appChartPanelClass = cn(appSurfaceCardClass, "flex flex-col gap-3");
|
|
1402
|
+
|
|
1403
|
+
// src/design/app-density.ts
|
|
1404
|
+
var APP_DENSITY_CHART_HEIGHT = {
|
|
1405
|
+
default: 300,
|
|
1406
|
+
compact: 220
|
|
1407
|
+
};
|
|
1408
|
+
var compactSurfaceCardClass = cn(studioIntegrationCardClass, "p-3");
|
|
1409
|
+
var compactStatTileClass = cn(
|
|
1410
|
+
compactSurfaceCardClass,
|
|
1411
|
+
"flex flex-col gap-1 px-3 py-2 shadow-none"
|
|
1412
|
+
);
|
|
1413
|
+
var compactEmptyStateClass = cn(
|
|
1414
|
+
compactSurfaceCardClass,
|
|
1415
|
+
"flex flex-col items-center justify-center gap-2 py-8 text-center"
|
|
1416
|
+
);
|
|
1417
|
+
var APP_DENSITY_CLASSES = {
|
|
1418
|
+
pageColumn: {
|
|
1419
|
+
default: appPageColumnClass,
|
|
1420
|
+
compact: "mx-auto w-full max-w-none px-3 md:px-4"
|
|
1421
|
+
},
|
|
1422
|
+
pageHeader: {
|
|
1423
|
+
default: appPageHeaderClass,
|
|
1424
|
+
compact: "flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between pb-2 pt-1"
|
|
1425
|
+
},
|
|
1426
|
+
section: {
|
|
1427
|
+
default: appSectionClass,
|
|
1428
|
+
compact: "flex flex-col gap-2 py-2"
|
|
1429
|
+
},
|
|
1430
|
+
surfaceCard: {
|
|
1431
|
+
default: appSurfaceCardClass,
|
|
1432
|
+
compact: compactSurfaceCardClass
|
|
1433
|
+
},
|
|
1434
|
+
statTile: {
|
|
1435
|
+
default: appStatTileClass,
|
|
1436
|
+
compact: compactStatTileClass
|
|
1437
|
+
},
|
|
1438
|
+
emptyState: {
|
|
1439
|
+
default: appEmptyStateClass,
|
|
1440
|
+
compact: compactEmptyStateClass
|
|
1441
|
+
},
|
|
1442
|
+
metricCardHeader: {
|
|
1443
|
+
default: "flex items-start justify-between gap-3 px-4 pb-1 pt-3",
|
|
1444
|
+
compact: "flex items-start justify-between gap-2 px-3 pb-0.5 pt-2"
|
|
1445
|
+
},
|
|
1446
|
+
metricTile: {
|
|
1447
|
+
default: "relative flex min-w-0 flex-1 flex-col gap-1 px-4 py-3 text-left font-normal",
|
|
1448
|
+
compact: "relative flex min-w-0 flex-1 flex-col gap-1 px-3 py-2 text-left font-normal"
|
|
1449
|
+
},
|
|
1450
|
+
metricChartRegion: {
|
|
1451
|
+
default: "relative min-h-0 w-full overflow-x-hidden border-t border-border/40 pt-2",
|
|
1452
|
+
compact: "relative min-h-0 w-full overflow-x-hidden border-t border-border/40 pt-1"
|
|
1453
|
+
},
|
|
1454
|
+
metricChartPlotRegion: {
|
|
1455
|
+
default: "relative min-h-0 w-full overflow-x-hidden border-t border-border/40 px-0 pt-5 pb-3",
|
|
1456
|
+
compact: "relative min-h-0 w-full overflow-x-hidden border-t border-border/40 px-0 pt-3 pb-2"
|
|
1457
|
+
},
|
|
1458
|
+
chartPanelBody: {
|
|
1459
|
+
default: "pt-2 pb-3",
|
|
1460
|
+
compact: "pt-1 pb-2"
|
|
1461
|
+
}
|
|
1462
|
+
};
|
|
1463
|
+
function appDensityClass(key, density = "default") {
|
|
1464
|
+
return APP_DENSITY_CLASSES[key][density];
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
// src/app/layout/app-density-context.tsx
|
|
1468
|
+
import { createContext, useContext } from "react";
|
|
1469
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
1470
|
+
var AppDensityContext = createContext("default");
|
|
1471
|
+
var AppDensityProvider = ({
|
|
1472
|
+
density = "default",
|
|
1473
|
+
children
|
|
1474
|
+
}) => {
|
|
1475
|
+
return /* @__PURE__ */ jsx2(AppDensityContext.Provider, { value: density, children });
|
|
1476
|
+
};
|
|
1477
|
+
function useAppDensity() {
|
|
1478
|
+
return useContext(AppDensityContext);
|
|
1479
|
+
}
|
|
1480
|
+
function useAppDensityClass(key, override) {
|
|
1481
|
+
const inherited = useAppDensity();
|
|
1482
|
+
return appDensityClass(key, override ?? inherited);
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1320
1485
|
// src/app/data/metrics-shared.tsx
|
|
1321
|
-
import { jsx as
|
|
1486
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1322
1487
|
var metricCardShellClass = cn(
|
|
1323
1488
|
studioIntegrationCardClass,
|
|
1324
1489
|
"aui-app-metric-card shadow-none",
|
|
1325
1490
|
"flex flex-col overflow-hidden"
|
|
1326
1491
|
);
|
|
1327
|
-
var metricCardHeaderClass = "flex items-start justify-between gap-3 px-4 pb-1 pt-3";
|
|
1328
1492
|
var metricTilesRowClass = "grid w-full min-w-0";
|
|
1329
|
-
var metricChartRegionClass = "relative min-h-0 w-full overflow-x-hidden border-t border-border/40 pt-2";
|
|
1330
|
-
var metricChartPlotRegionClass = "relative min-h-0 w-full overflow-x-hidden border-t border-border/40 px-0 pt-5 pb-3";
|
|
1331
1493
|
var metricCellDividerClass = "border-r border-border/40";
|
|
1332
1494
|
var MetricCardHeader = ({
|
|
1333
1495
|
title,
|
|
@@ -1335,13 +1497,14 @@ var MetricCardHeader = ({
|
|
|
1335
1497
|
description,
|
|
1336
1498
|
actions
|
|
1337
1499
|
}) => {
|
|
1500
|
+
const headerClass = useAppDensityClass("metricCardHeader");
|
|
1338
1501
|
if (!title && !description && !actions) return null;
|
|
1339
|
-
return /* @__PURE__ */ jsxs2("header", { className:
|
|
1502
|
+
return /* @__PURE__ */ jsxs2("header", { className: headerClass, children: [
|
|
1340
1503
|
/* @__PURE__ */ jsxs2("div", { className: "min-w-0", children: [
|
|
1341
|
-
title ? /* @__PURE__ */
|
|
1342
|
-
description ? /* @__PURE__ */
|
|
1504
|
+
title ? /* @__PURE__ */ jsx3("h3", { id: titleId, className: "text-base font-normal text-foreground", children: title }) : null,
|
|
1505
|
+
description ? /* @__PURE__ */ jsx3("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
|
|
1343
1506
|
] }),
|
|
1344
|
-
actions ? /* @__PURE__ */
|
|
1507
|
+
actions ? /* @__PURE__ */ jsx3("div", { className: "shrink-0", children: actions }) : null
|
|
1345
1508
|
] });
|
|
1346
1509
|
};
|
|
1347
1510
|
function metricTilesGridColsClass(n) {
|
|
@@ -1362,15 +1525,13 @@ function metricTilesGridColsClass(n) {
|
|
|
1362
1525
|
}
|
|
1363
1526
|
|
|
1364
1527
|
// src/app/data/MetricTile.tsx
|
|
1365
|
-
import { Fragment as Fragment2, jsx as
|
|
1528
|
+
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1366
1529
|
var trendToneClass = {
|
|
1367
1530
|
up: "border-border/80 bg-muted/40 text-muted-foreground",
|
|
1368
1531
|
down: "border-border/80 bg-muted/40 text-muted-foreground",
|
|
1369
1532
|
neutral: "border-border/80 bg-muted/30 text-muted-foreground"
|
|
1370
1533
|
};
|
|
1371
|
-
var
|
|
1372
|
-
var metricTileInteractiveClass = cn(
|
|
1373
|
-
metricTileBaseClass,
|
|
1534
|
+
var metricTileInteractiveExtraClass = cn(
|
|
1374
1535
|
"bg-transparent hover:bg-transparent active:bg-transparent",
|
|
1375
1536
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-foreground/10"
|
|
1376
1537
|
);
|
|
@@ -1386,21 +1547,22 @@ var MetricTile = ({
|
|
|
1386
1547
|
ariaLabel,
|
|
1387
1548
|
className
|
|
1388
1549
|
}) => {
|
|
1550
|
+
const metricTileBaseClass = useAppDensityClass("metricTile");
|
|
1389
1551
|
const content = /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
1390
|
-
active ? /* @__PURE__ */
|
|
1552
|
+
active ? /* @__PURE__ */ jsx4(
|
|
1391
1553
|
"span",
|
|
1392
1554
|
{
|
|
1393
1555
|
"aria-hidden": true,
|
|
1394
1556
|
className: "absolute inset-x-0 bottom-0 h-0.5 bg-foreground dark:bg-white"
|
|
1395
1557
|
}
|
|
1396
1558
|
) : null,
|
|
1397
|
-
/* @__PURE__ */
|
|
1559
|
+
/* @__PURE__ */ jsx4("span", { className: "text-xs font-normal text-muted-foreground", children: label }),
|
|
1398
1560
|
/* @__PURE__ */ jsxs3("span", { className: "flex items-center gap-2", children: [
|
|
1399
1561
|
/* @__PURE__ */ jsxs3("span", { className: "flex items-baseline gap-1", children: [
|
|
1400
|
-
/* @__PURE__ */
|
|
1401
|
-
unit ? /* @__PURE__ */
|
|
1562
|
+
/* @__PURE__ */ jsx4("span", { className: "text-2xl font-normal tracking-tight text-foreground tabular-nums", children: value }),
|
|
1563
|
+
unit ? /* @__PURE__ */ jsx4("span", { className: "text-xs font-normal text-muted-foreground", children: unit }) : null
|
|
1402
1564
|
] }),
|
|
1403
|
-
trend ? /* @__PURE__ */
|
|
1565
|
+
trend ? /* @__PURE__ */ jsx4(
|
|
1404
1566
|
"span",
|
|
1405
1567
|
{
|
|
1406
1568
|
className: cn(
|
|
@@ -1414,159 +1576,38 @@ var MetricTile = ({
|
|
|
1414
1576
|
] });
|
|
1415
1577
|
const divider = showDivider ? metricCellDividerClass : void 0;
|
|
1416
1578
|
if (onSelect) {
|
|
1417
|
-
return /* @__PURE__ */
|
|
1579
|
+
return /* @__PURE__ */ jsx4(
|
|
1418
1580
|
"button",
|
|
1419
1581
|
{
|
|
1420
1582
|
type: "button",
|
|
1421
1583
|
onClick: onSelect,
|
|
1422
1584
|
"aria-pressed": active,
|
|
1423
1585
|
"aria-label": ariaLabel,
|
|
1424
|
-
className: cn(
|
|
1586
|
+
className: cn(metricTileBaseClass, metricTileInteractiveExtraClass, divider, className),
|
|
1425
1587
|
children: content
|
|
1426
1588
|
}
|
|
1427
1589
|
);
|
|
1428
1590
|
}
|
|
1429
|
-
return /* @__PURE__ */
|
|
1591
|
+
return /* @__PURE__ */ jsx4("div", { className: cn(metricTileBaseClass, divider, className), children: content });
|
|
1430
1592
|
};
|
|
1431
1593
|
|
|
1432
1594
|
// src/app/theme/ThemePresetGallery.tsx
|
|
1433
|
-
import { jsx as
|
|
1434
|
-
var ThemePresetGallery = ({
|
|
1435
|
-
value,
|
|
1436
|
-
onSelect,
|
|
1437
|
-
presets,
|
|
1438
|
-
className
|
|
1439
|
-
}) => {
|
|
1440
|
-
const items = presets ? TIMBAL_THEME_PRESETS.filter((p) => presets.includes(p.id)) : TIMBAL_THEME_PRESETS;
|
|
1441
|
-
return /* @__PURE__ */ jsx4(
|
|
1442
|
-
"div",
|
|
1443
|
-
{
|
|
1444
|
-
role: "radiogroup",
|
|
1445
|
-
"aria-label": "Theme presets",
|
|
1446
|
-
className: cn(
|
|
1447
|
-
"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3",
|
|
1448
|
-
className
|
|
1449
|
-
),
|
|
1450
|
-
children: items.map((preset) => {
|
|
1451
|
-
const selected = value === preset.id;
|
|
1452
|
-
return /* @__PURE__ */ jsxs4("div", { "data-timbal-theme": preset.id, children: [
|
|
1453
|
-
/* @__PURE__ */ jsx4(TimbalThemeStyle, { preset: preset.id, scope: preset.id }),
|
|
1454
|
-
/* @__PURE__ */ jsxs4(
|
|
1455
|
-
"button",
|
|
1456
|
-
{
|
|
1457
|
-
type: "button",
|
|
1458
|
-
role: "radio",
|
|
1459
|
-
"aria-checked": selected,
|
|
1460
|
-
"aria-label": `${preset.label} theme`,
|
|
1461
|
-
onClick: () => onSelect?.(preset.id),
|
|
1462
|
-
className: cn(
|
|
1463
|
-
"group flex w-full flex-col gap-3 rounded-xl border bg-card p-3 text-left transition-colors",
|
|
1464
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
1465
|
-
selected ? "border-primary ring-2 ring-primary/30" : "border-border hover:border-foreground/30"
|
|
1466
|
-
),
|
|
1467
|
-
children: [
|
|
1468
|
-
/* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between gap-2", children: [
|
|
1469
|
-
/* @__PURE__ */ jsxs4("span", { className: "flex items-center gap-2", children: [
|
|
1470
|
-
/* @__PURE__ */ jsx4(
|
|
1471
|
-
"span",
|
|
1472
|
-
{
|
|
1473
|
-
"aria-hidden": true,
|
|
1474
|
-
className: "size-4 shrink-0 rounded-full ring-1 ring-black/10",
|
|
1475
|
-
style: { background: preset.swatch }
|
|
1476
|
-
}
|
|
1477
|
-
),
|
|
1478
|
-
/* @__PURE__ */ jsx4("span", { className: "text-sm font-medium text-foreground", children: preset.label })
|
|
1479
|
-
] }),
|
|
1480
|
-
selected ? /* @__PURE__ */ jsx4("span", { className: "text-xs font-medium text-primary", children: "Selected" }) : null
|
|
1481
|
-
] }),
|
|
1482
|
-
/* @__PURE__ */ jsx4("p", { className: "text-xs leading-snug text-muted-foreground", children: preset.description }),
|
|
1483
|
-
preset.font ? /* @__PURE__ */ jsxs4("span", { className: "text-[10px] uppercase tracking-wide text-muted-foreground", children: [
|
|
1484
|
-
"Aa \xB7 ",
|
|
1485
|
-
preset.font
|
|
1486
|
-
] }) : null,
|
|
1487
|
-
/* @__PURE__ */ jsxs4("div", { className: "flex flex-col gap-2 rounded-lg border border-border bg-background p-2", children: [
|
|
1488
|
-
/* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
|
|
1489
|
-
/* @__PURE__ */ jsx4(Button, { size: "xs", className: "pointer-events-none", children: "Primary" }),
|
|
1490
|
-
/* @__PURE__ */ jsx4("span", { className: "size-5 rounded-md bg-primary", "aria-hidden": true }),
|
|
1491
|
-
/* @__PURE__ */ jsx4("span", { className: "size-5 rounded-md bg-muted", "aria-hidden": true }),
|
|
1492
|
-
/* @__PURE__ */ jsx4(
|
|
1493
|
-
"span",
|
|
1494
|
-
{
|
|
1495
|
-
className: "size-5 rounded-md border border-border bg-accent",
|
|
1496
|
-
"aria-hidden": true
|
|
1497
|
-
}
|
|
1498
|
-
)
|
|
1499
|
-
] }),
|
|
1500
|
-
/* @__PURE__ */ jsx4(MetricTile, { label: "Active users", value: "1,248", trend: "+8%" })
|
|
1501
|
-
] })
|
|
1502
|
-
]
|
|
1503
|
-
}
|
|
1504
|
-
)
|
|
1505
|
-
] }, preset.id);
|
|
1506
|
-
})
|
|
1507
|
-
}
|
|
1508
|
-
);
|
|
1509
|
-
};
|
|
1510
|
-
|
|
1511
|
-
// src/design/app-classes.ts
|
|
1512
|
-
var appPageColumnClass = "mx-auto w-full max-w-6xl px-4 md:px-6";
|
|
1513
|
-
var appShellTopbarInsetClass = "w-full px-4 md:px-6";
|
|
1514
|
-
var appShellInsetTopClass = "pt-4 md:pt-6";
|
|
1515
|
-
var appShellTopbarRowClass = cn(
|
|
1516
|
-
studioTopbarPillHeightClass,
|
|
1517
|
-
"flex w-full items-center justify-between gap-2"
|
|
1518
|
-
);
|
|
1519
|
-
var appShellTopbarStickyClass = cn(
|
|
1520
|
-
"shrink-0 bg-background pb-2",
|
|
1521
|
-
appShellInsetTopClass
|
|
1522
|
-
);
|
|
1523
|
-
var appPageHeaderClass = cn(
|
|
1524
|
-
"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",
|
|
1525
|
-
"pb-4 pt-2"
|
|
1526
|
-
);
|
|
1527
|
-
var appSectionClass = "flex flex-col gap-4 py-4";
|
|
1528
|
-
var appSectionTitleClass = "text-lg font-semibold text-foreground";
|
|
1529
|
-
var appSectionDescriptionClass = "text-sm text-muted-foreground";
|
|
1530
|
-
var appSurfaceCardClass = cn(
|
|
1531
|
-
studioIntegrationCardClass,
|
|
1532
|
-
"p-4 md:p-5"
|
|
1533
|
-
);
|
|
1534
|
-
var appStatTileClass = cn(
|
|
1535
|
-
appSurfaceCardClass,
|
|
1536
|
-
"flex flex-col gap-1 px-4 py-3 shadow-none"
|
|
1537
|
-
);
|
|
1538
|
-
var appStatValueClass = "text-2xl font-normal tracking-tight text-foreground tabular-nums";
|
|
1539
|
-
var appStatLabelClass = "text-xs font-normal text-muted-foreground";
|
|
1540
|
-
var appFilterBarClass = "flex flex-wrap items-end gap-2";
|
|
1541
|
-
var appSearchInputClass = controlClass({}, "inline-flex items-center gap-2");
|
|
1542
|
-
var appBreadcrumbsClass = "flex flex-wrap items-center gap-1.5 text-sm text-muted-foreground";
|
|
1543
|
-
var appBreadcrumbLinkClass = "transition-colors hover:text-foreground";
|
|
1544
|
-
var appFieldClass = "flex flex-col gap-1.5";
|
|
1545
|
-
var appFieldLabelClass = "text-sm font-medium text-foreground";
|
|
1546
|
-
var appFieldHintClass = "text-xs text-muted-foreground";
|
|
1547
|
-
var appInputClass = controlClass({}, "w-full");
|
|
1548
|
-
var appEmptyStateClass = cn(
|
|
1549
|
-
appSurfaceCardClass,
|
|
1550
|
-
"flex flex-col items-center justify-center gap-2 py-12 text-center"
|
|
1551
|
-
);
|
|
1552
|
-
var appEmptyStateTitleClass = "text-base font-medium text-foreground";
|
|
1553
|
-
var appEmptyStateDescriptionClass = "max-w-sm text-sm text-muted-foreground";
|
|
1554
|
-
var appChartPanelClass = cn(appSurfaceCardClass, "flex flex-col gap-3");
|
|
1595
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1555
1596
|
|
|
1556
1597
|
// src/app/layout/app-shell-chat-context.tsx
|
|
1557
|
-
import { createContext, useContext } from "react";
|
|
1558
|
-
var AppShellChatContext =
|
|
1598
|
+
import { createContext as createContext2, useContext as useContext2 } from "react";
|
|
1599
|
+
var AppShellChatContext = createContext2(null);
|
|
1559
1600
|
var AppShellChatProvider = AppShellChatContext.Provider;
|
|
1560
1601
|
function useAppShellChat() {
|
|
1561
|
-
return
|
|
1602
|
+
return useContext2(AppShellChatContext);
|
|
1562
1603
|
}
|
|
1563
1604
|
|
|
1564
1605
|
// src/app/layout/app-shell-nav-context.tsx
|
|
1565
|
-
import { createContext as
|
|
1566
|
-
var AppShellNavContext =
|
|
1606
|
+
import { createContext as createContext3, useContext as useContext3 } from "react";
|
|
1607
|
+
var AppShellNavContext = createContext3(null);
|
|
1567
1608
|
var AppShellNavProvider = AppShellNavContext.Provider;
|
|
1568
1609
|
function useAppShellNav() {
|
|
1569
|
-
return
|
|
1610
|
+
return useContext3(AppShellNavContext) ?? {
|
|
1570
1611
|
open: false,
|
|
1571
1612
|
setOpen: () => {
|
|
1572
1613
|
},
|
|
@@ -1578,7 +1619,7 @@ function useAppShellNav() {
|
|
|
1578
1619
|
// src/app/layout/AppShell.tsx
|
|
1579
1620
|
import { motion, useReducedMotion } from "motion/react";
|
|
1580
1621
|
import { useCallback, useMemo, useState } from "react";
|
|
1581
|
-
import { jsx as
|
|
1622
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1582
1623
|
var floatingTriggerClass = cn(
|
|
1583
1624
|
"aui-app-shell-chat-trigger-fixed fixed z-50 rounded-full px-5 py-2.5 text-sm font-medium shadow-card-elevated",
|
|
1584
1625
|
"bg-primary text-primary-foreground transition-colors hover:bg-primary/90",
|
|
@@ -1596,6 +1637,7 @@ var AppShellBody = ({
|
|
|
1596
1637
|
sidebar,
|
|
1597
1638
|
topbarContent,
|
|
1598
1639
|
mainClassName,
|
|
1640
|
+
contentFill = false,
|
|
1599
1641
|
insetPaddingPx,
|
|
1600
1642
|
insetExpanded,
|
|
1601
1643
|
children
|
|
@@ -1607,7 +1649,7 @@ var AppShellBody = ({
|
|
|
1607
1649
|
layoutDirection
|
|
1608
1650
|
);
|
|
1609
1651
|
const insetPadding = sidebar ? insetPaddingPx : 0;
|
|
1610
|
-
return /* @__PURE__ */
|
|
1652
|
+
return /* @__PURE__ */ jsx6(
|
|
1611
1653
|
motion.div,
|
|
1612
1654
|
{
|
|
1613
1655
|
className: "aui-app-shell-body relative z-10 flex min-h-0 min-w-0 flex-1 flex-col",
|
|
@@ -1618,12 +1660,28 @@ var AppShellBody = ({
|
|
|
1618
1660
|
"div",
|
|
1619
1661
|
{
|
|
1620
1662
|
className: cn(
|
|
1621
|
-
"aui-app-shell-scroll flex min-h-0 flex-1 flex-col
|
|
1663
|
+
"aui-app-shell-scroll flex min-h-0 flex-1 flex-col",
|
|
1664
|
+
// Padded scroll region by default; a full-bleed page (chat / canvas) owns
|
|
1665
|
+
// its own scroll, so clip here and let the bounded `main` fill exactly.
|
|
1666
|
+
contentFill ? "overflow-hidden" : "overflow-y-auto",
|
|
1622
1667
|
!topbarContent && appShellInsetTopClass
|
|
1623
1668
|
),
|
|
1624
1669
|
children: [
|
|
1625
|
-
topbarContent ? /* @__PURE__ */
|
|
1626
|
-
/* @__PURE__ */
|
|
1670
|
+
topbarContent ? /* @__PURE__ */ jsx6("header", { className: cn("aui-app-shell-topbar-region", appShellTopbarStickyClass), children: /* @__PURE__ */ jsx6("div", { className: appShellTopbarInsetClass, children: topbarContent }) }) : null,
|
|
1671
|
+
/* @__PURE__ */ jsx6(
|
|
1672
|
+
"main",
|
|
1673
|
+
{
|
|
1674
|
+
className: cn(
|
|
1675
|
+
// Bounded flex column by default so `h-full` / `flex-1 min-h-0` children
|
|
1676
|
+
// (full-page chat, canvas) resolve a height without `mainClassName` surgery.
|
|
1677
|
+
"aui-app-shell-main flex min-h-0 min-w-0 flex-1 flex-col",
|
|
1678
|
+
// Bottom breathing room for scrolling content; full-bleed pages skip it.
|
|
1679
|
+
!contentFill && appShellInsetBottomClass,
|
|
1680
|
+
mainClassName
|
|
1681
|
+
),
|
|
1682
|
+
children
|
|
1683
|
+
}
|
|
1684
|
+
)
|
|
1627
1685
|
]
|
|
1628
1686
|
}
|
|
1629
1687
|
)
|
|
@@ -1648,7 +1706,8 @@ var AppShell = ({
|
|
|
1648
1706
|
defaultNavOpen = false,
|
|
1649
1707
|
onNavOpenChange,
|
|
1650
1708
|
className,
|
|
1651
|
-
mainClassName
|
|
1709
|
+
mainClassName,
|
|
1710
|
+
contentFill = false
|
|
1652
1711
|
}) => {
|
|
1653
1712
|
const topbarContent = topbar ?? header;
|
|
1654
1713
|
const hasChat = Boolean(chat);
|
|
@@ -1689,18 +1748,19 @@ var AppShell = ({
|
|
|
1689
1748
|
setInsetPaddingPx(insetPx);
|
|
1690
1749
|
}, []);
|
|
1691
1750
|
const insetExpanded = insetPaddingPx >= SIDEBAR_INSET_PX_EXPANDED;
|
|
1692
|
-
const shellBody = /* @__PURE__ */
|
|
1751
|
+
const shellBody = /* @__PURE__ */ jsx6(
|
|
1693
1752
|
AppShellBody,
|
|
1694
1753
|
{
|
|
1695
1754
|
sidebar,
|
|
1696
1755
|
topbarContent,
|
|
1697
1756
|
mainClassName,
|
|
1757
|
+
contentFill,
|
|
1698
1758
|
insetPaddingPx,
|
|
1699
1759
|
insetExpanded,
|
|
1700
1760
|
children
|
|
1701
1761
|
}
|
|
1702
1762
|
);
|
|
1703
|
-
const tree = /* @__PURE__ */
|
|
1763
|
+
const tree = /* @__PURE__ */ jsx6(ShellInsetProvider, { value: sidebar ? reportShellInset : null, children: /* @__PURE__ */ jsxs5(
|
|
1704
1764
|
"div",
|
|
1705
1765
|
{
|
|
1706
1766
|
className: cn(
|
|
@@ -1710,7 +1770,7 @@ var AppShell = ({
|
|
|
1710
1770
|
style: studioChromeShellStyle,
|
|
1711
1771
|
children: [
|
|
1712
1772
|
sidebar,
|
|
1713
|
-
sidebar && navOpen ? /* @__PURE__ */
|
|
1773
|
+
sidebar && navOpen ? /* @__PURE__ */ jsx6(
|
|
1714
1774
|
"button",
|
|
1715
1775
|
{
|
|
1716
1776
|
type: "button",
|
|
@@ -1720,7 +1780,7 @@ var AppShell = ({
|
|
|
1720
1780
|
}
|
|
1721
1781
|
) : null,
|
|
1722
1782
|
shellBody,
|
|
1723
|
-
hasChat && chatOpen ? /* @__PURE__ */
|
|
1783
|
+
hasChat && chatOpen ? /* @__PURE__ */ jsx6(
|
|
1724
1784
|
"div",
|
|
1725
1785
|
{
|
|
1726
1786
|
className: floatingPanelClass,
|
|
@@ -1733,7 +1793,7 @@ var AppShell = ({
|
|
|
1733
1793
|
children: chat
|
|
1734
1794
|
}
|
|
1735
1795
|
) : null,
|
|
1736
|
-
hasChat && chatCollapsible && !chatOpen && !hideChatTrigger ? /* @__PURE__ */
|
|
1796
|
+
hasChat && chatCollapsible && !chatOpen && !hideChatTrigger ? /* @__PURE__ */ jsx6(
|
|
1737
1797
|
"button",
|
|
1738
1798
|
{
|
|
1739
1799
|
type: "button",
|
|
@@ -1746,11 +1806,11 @@ var AppShell = ({
|
|
|
1746
1806
|
]
|
|
1747
1807
|
}
|
|
1748
1808
|
) });
|
|
1749
|
-
const withNav = /* @__PURE__ */
|
|
1809
|
+
const withNav = /* @__PURE__ */ jsx6(AppShellNavProvider, { value: navControls, children: tree });
|
|
1750
1810
|
if (!hasChat) {
|
|
1751
1811
|
return withNav;
|
|
1752
1812
|
}
|
|
1753
|
-
return /* @__PURE__ */
|
|
1813
|
+
return /* @__PURE__ */ jsx6(
|
|
1754
1814
|
AppShellChatProvider,
|
|
1755
1815
|
{
|
|
1756
1816
|
value: {
|
|
@@ -1765,7 +1825,7 @@ var AppShell = ({
|
|
|
1765
1825
|
};
|
|
1766
1826
|
|
|
1767
1827
|
// src/app/layout/AppShellTopbar.tsx
|
|
1768
|
-
import { jsx as
|
|
1828
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1769
1829
|
var AppShellTopbar = ({
|
|
1770
1830
|
start,
|
|
1771
1831
|
actions,
|
|
@@ -1777,12 +1837,12 @@ var AppShellTopbar = ({
|
|
|
1777
1837
|
start,
|
|
1778
1838
|
children
|
|
1779
1839
|
] }),
|
|
1780
|
-
actions ? /* @__PURE__ */
|
|
1840
|
+
actions ? /* @__PURE__ */ jsx7("div", { className: "aui-app-shell-topbar-actions flex shrink-0 items-center gap-2", children: actions }) : null
|
|
1781
1841
|
] });
|
|
1782
1842
|
};
|
|
1783
1843
|
|
|
1784
1844
|
// src/app/layout/AppShellChatTrigger.tsx
|
|
1785
|
-
import { jsx as
|
|
1845
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
1786
1846
|
var floatingPositionClass = "fixed bottom-6 right-6 z-50 max-sm:bottom-4 max-sm:right-4";
|
|
1787
1847
|
var AppShellChatTrigger = ({
|
|
1788
1848
|
className,
|
|
@@ -1791,7 +1851,7 @@ var AppShellChatTrigger = ({
|
|
|
1791
1851
|
}) => {
|
|
1792
1852
|
const shellChat = useAppShellChat();
|
|
1793
1853
|
if (!shellChat || shellChat.open) return null;
|
|
1794
|
-
return /* @__PURE__ */
|
|
1854
|
+
return /* @__PURE__ */ jsx8(
|
|
1795
1855
|
TimbalV2Button,
|
|
1796
1856
|
{
|
|
1797
1857
|
type: "button",
|
|
@@ -1812,13 +1872,13 @@ var AppShellChatTrigger = ({
|
|
|
1812
1872
|
|
|
1813
1873
|
// src/app/layout/AppShellSidebarTrigger.tsx
|
|
1814
1874
|
import { MenuIcon } from "lucide-react";
|
|
1815
|
-
import { jsx as
|
|
1875
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
1816
1876
|
var AppShellSidebarTrigger = ({
|
|
1817
1877
|
label = "Open navigation",
|
|
1818
1878
|
className
|
|
1819
1879
|
}) => {
|
|
1820
1880
|
const nav = useAppShellNav();
|
|
1821
|
-
return /* @__PURE__ */
|
|
1881
|
+
return /* @__PURE__ */ jsx9(
|
|
1822
1882
|
"button",
|
|
1823
1883
|
{
|
|
1824
1884
|
type: "button",
|
|
@@ -1830,75 +1890,114 @@ var AppShellSidebarTrigger = ({
|
|
|
1830
1890
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/10",
|
|
1831
1891
|
className
|
|
1832
1892
|
),
|
|
1833
|
-
children: /* @__PURE__ */
|
|
1893
|
+
children: /* @__PURE__ */ jsx9(MenuIcon, { className: "size-5", "aria-hidden": true })
|
|
1834
1894
|
}
|
|
1835
1895
|
);
|
|
1836
1896
|
};
|
|
1837
1897
|
|
|
1838
1898
|
// src/app/layout/PageHeader.tsx
|
|
1839
|
-
import { jsx as
|
|
1899
|
+
import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1840
1900
|
var PageHeader = ({
|
|
1841
1901
|
title,
|
|
1842
1902
|
description,
|
|
1843
1903
|
actions,
|
|
1844
1904
|
className
|
|
1845
1905
|
}) => {
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1906
|
+
const pageHeaderClass = useAppDensityClass("pageHeader");
|
|
1907
|
+
if (title == null && description == null && actions == null) {
|
|
1908
|
+
return null;
|
|
1909
|
+
}
|
|
1910
|
+
return /* @__PURE__ */ jsxs7("header", { className: cn("aui-app-page-header", pageHeaderClass, className), children: [
|
|
1911
|
+
title != null || description != null ? /* @__PURE__ */ jsxs7("div", { className: "min-w-0", children: [
|
|
1912
|
+
title != null ? /* @__PURE__ */ jsx10("h1", { className: "text-2xl font-semibold tracking-tight text-foreground", children: title }) : null,
|
|
1913
|
+
description ? /* @__PURE__ */ jsx10("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null
|
|
1914
|
+
] }) : null,
|
|
1915
|
+
actions ? /* @__PURE__ */ jsx10("div", { className: "aui-app-page-header-actions flex shrink-0 flex-wrap items-center gap-2", children: actions }) : null
|
|
1852
1916
|
] });
|
|
1853
1917
|
};
|
|
1854
1918
|
|
|
1855
1919
|
// src/app/layout/Page.tsx
|
|
1856
|
-
import { jsx as
|
|
1920
|
+
import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1921
|
+
var PageFrame = ({
|
|
1922
|
+
children,
|
|
1923
|
+
breadcrumbs,
|
|
1924
|
+
fill = false,
|
|
1925
|
+
className,
|
|
1926
|
+
...headerProps
|
|
1927
|
+
}) => {
|
|
1928
|
+
const density = useAppDensity();
|
|
1929
|
+
const pageColumnClass = useAppDensityClass("pageColumn");
|
|
1930
|
+
return /* @__PURE__ */ jsxs8(
|
|
1931
|
+
"div",
|
|
1932
|
+
{
|
|
1933
|
+
className: cn(
|
|
1934
|
+
"aui-app-page",
|
|
1935
|
+
fill ? "flex min-h-0 min-w-0 flex-1 flex-col" : pageColumnClass,
|
|
1936
|
+
className
|
|
1937
|
+
),
|
|
1938
|
+
"data-density": density,
|
|
1939
|
+
children: [
|
|
1940
|
+
breadcrumbs,
|
|
1941
|
+
/* @__PURE__ */ jsx11(PageHeader, { ...headerProps }),
|
|
1942
|
+
children
|
|
1943
|
+
]
|
|
1944
|
+
}
|
|
1945
|
+
);
|
|
1946
|
+
};
|
|
1857
1947
|
var Page = ({
|
|
1948
|
+
density = "default",
|
|
1858
1949
|
children,
|
|
1859
1950
|
breadcrumbs,
|
|
1951
|
+
fill = false,
|
|
1860
1952
|
className,
|
|
1861
1953
|
...headerProps
|
|
1862
1954
|
}) => {
|
|
1863
|
-
return /* @__PURE__ */
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1955
|
+
return /* @__PURE__ */ jsx11(AppDensityProvider, { density, children: /* @__PURE__ */ jsx11(
|
|
1956
|
+
PageFrame,
|
|
1957
|
+
{
|
|
1958
|
+
breadcrumbs,
|
|
1959
|
+
fill,
|
|
1960
|
+
className,
|
|
1961
|
+
...headerProps,
|
|
1962
|
+
children
|
|
1963
|
+
}
|
|
1964
|
+
) });
|
|
1868
1965
|
};
|
|
1869
1966
|
|
|
1870
1967
|
// src/app/layout/Section.tsx
|
|
1871
|
-
import { jsx as
|
|
1968
|
+
import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1872
1969
|
var Section = ({
|
|
1873
1970
|
title,
|
|
1874
1971
|
description,
|
|
1875
1972
|
children,
|
|
1973
|
+
density,
|
|
1876
1974
|
className
|
|
1877
1975
|
}) => {
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1976
|
+
const sectionClass = useAppDensityClass("section", density);
|
|
1977
|
+
return /* @__PURE__ */ jsxs9("section", { className: cn("aui-app-section", sectionClass, className), children: [
|
|
1978
|
+
title ? /* @__PURE__ */ jsx12("h2", { className: appSectionTitleClass, children: title }) : null,
|
|
1979
|
+
description ? /* @__PURE__ */ jsx12("p", { className: appSectionDescriptionClass, children: description }) : null,
|
|
1881
1980
|
children
|
|
1882
1981
|
] });
|
|
1883
1982
|
};
|
|
1884
1983
|
|
|
1885
1984
|
// src/app/copilot/app-copilot-context.tsx
|
|
1886
|
-
import { createContext as
|
|
1887
|
-
import { jsx as
|
|
1888
|
-
var AppCopilotContext =
|
|
1985
|
+
import { createContext as createContext4, useContext as useContext4 } from "react";
|
|
1986
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
1987
|
+
var AppCopilotContext = createContext4(null);
|
|
1889
1988
|
var AppCopilotProvider = ({
|
|
1890
1989
|
value,
|
|
1891
1990
|
children
|
|
1892
1991
|
}) => {
|
|
1893
|
-
return /* @__PURE__ */
|
|
1992
|
+
return /* @__PURE__ */ jsx13(AppCopilotContext.Provider, { value, children });
|
|
1894
1993
|
};
|
|
1895
1994
|
function useAppCopilotContext() {
|
|
1896
|
-
return
|
|
1995
|
+
return useContext4(AppCopilotContext) ?? {};
|
|
1897
1996
|
}
|
|
1898
1997
|
|
|
1899
1998
|
// src/app/chat/AppChatPanel.tsx
|
|
1900
1999
|
import { XIcon } from "lucide-react";
|
|
1901
|
-
import { jsx as
|
|
2000
|
+
import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1902
2001
|
var shellClass = "aui-app-chat-panel flex h-full min-h-0 flex-col overflow-hidden";
|
|
1903
2002
|
var chromeClass = cn(
|
|
1904
2003
|
"aui-app-chat-panel-chrome relative z-20 flex min-h-10 shrink-0 items-center justify-end px-2 pt-2"
|
|
@@ -1944,17 +2043,17 @@ var AppChatPanel = ({
|
|
|
1944
2043
|
}) => {
|
|
1945
2044
|
const shellChat = useAppShellChat();
|
|
1946
2045
|
return /* @__PURE__ */ jsxs10("div", { className: cn(shellClass, className), children: [
|
|
1947
|
-
shellChat?.collapsible ? /* @__PURE__ */
|
|
2046
|
+
shellChat?.collapsible ? /* @__PURE__ */ jsx14("div", { className: chromeClass, children: /* @__PURE__ */ jsx14(
|
|
1948
2047
|
"button",
|
|
1949
2048
|
{
|
|
1950
2049
|
type: "button",
|
|
1951
2050
|
className: closeButtonClass,
|
|
1952
2051
|
onClick: () => shellChat.setOpen(false),
|
|
1953
2052
|
"aria-label": "Close assistant",
|
|
1954
|
-
children: /* @__PURE__ */
|
|
2053
|
+
children: /* @__PURE__ */ jsx14(XIcon, { className: "size-4", "aria-hidden": true })
|
|
1955
2054
|
}
|
|
1956
2055
|
) }) : null,
|
|
1957
|
-
/* @__PURE__ */
|
|
2056
|
+
/* @__PURE__ */ jsx14("div", { className: bodyClass, children: /* @__PURE__ */ jsx14(
|
|
1958
2057
|
TimbalRuntimeProvider,
|
|
1959
2058
|
{
|
|
1960
2059
|
workforceId,
|
|
@@ -1964,7 +2063,7 @@ var AppChatPanel = ({
|
|
|
1964
2063
|
attachmentsUploadUrl,
|
|
1965
2064
|
attachmentsAccept,
|
|
1966
2065
|
debug,
|
|
1967
|
-
children: /* @__PURE__ */
|
|
2066
|
+
children: /* @__PURE__ */ jsx14(
|
|
1968
2067
|
Thread,
|
|
1969
2068
|
{
|
|
1970
2069
|
variant: "panel",
|
|
@@ -1985,66 +2084,91 @@ var AppChatPanel = ({
|
|
|
1985
2084
|
};
|
|
1986
2085
|
|
|
1987
2086
|
// src/app/surfaces/SurfaceCard.tsx
|
|
1988
|
-
import { jsx as
|
|
2087
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
1989
2088
|
var SurfaceCard = ({ children, className }) => {
|
|
1990
|
-
|
|
2089
|
+
const surfaceCardClass = useAppDensityClass("surfaceCard");
|
|
2090
|
+
return /* @__PURE__ */ jsx15("div", { className: cn("aui-app-surface-card", surfaceCardClass, className), children });
|
|
1991
2091
|
};
|
|
1992
2092
|
|
|
1993
2093
|
// src/app/surfaces/StatTile.tsx
|
|
1994
|
-
import { jsx as
|
|
2094
|
+
import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1995
2095
|
var StatTile = ({ label, value, hint, className }) => {
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
/* @__PURE__ */
|
|
1999
|
-
|
|
2096
|
+
const statTileClass = useAppDensityClass("statTile");
|
|
2097
|
+
return /* @__PURE__ */ jsxs11("div", { className: cn("aui-app-stat-tile", statTileClass, className), children: [
|
|
2098
|
+
/* @__PURE__ */ jsx16("span", { className: appStatLabelClass, children: label }),
|
|
2099
|
+
/* @__PURE__ */ jsx16("span", { className: appStatValueClass, children: value }),
|
|
2100
|
+
hint ? /* @__PURE__ */ jsx16("span", { className: "text-xs text-muted-foreground", children: hint }) : null
|
|
2000
2101
|
] });
|
|
2001
2102
|
};
|
|
2002
2103
|
|
|
2003
2104
|
// src/app/surfaces/EmptyState.tsx
|
|
2004
|
-
import { jsx as
|
|
2105
|
+
import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2005
2106
|
var EmptyState = ({
|
|
2006
2107
|
title,
|
|
2007
2108
|
description,
|
|
2008
2109
|
action,
|
|
2009
2110
|
className
|
|
2010
2111
|
}) => {
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2112
|
+
const emptyStateClass = useAppDensityClass("emptyState");
|
|
2113
|
+
return /* @__PURE__ */ jsxs12("div", { className: cn("aui-app-empty-state", emptyStateClass, className), children: [
|
|
2114
|
+
/* @__PURE__ */ jsx17("p", { className: appEmptyStateTitleClass, children: title }),
|
|
2115
|
+
description ? /* @__PURE__ */ jsx17("p", { className: appEmptyStateDescriptionClass, children: description }) : null,
|
|
2014
2116
|
action
|
|
2015
2117
|
] });
|
|
2016
2118
|
};
|
|
2017
2119
|
|
|
2018
2120
|
// src/app/surfaces/StatusBadge.tsx
|
|
2019
|
-
import { jsx as
|
|
2121
|
+
import { jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2020
2122
|
var statusBadgeToneClass = {
|
|
2021
|
-
default: "bg-muted text-foreground",
|
|
2022
|
-
primary: "bg-primary/10 text-primary",
|
|
2023
|
-
success: "bg-emerald-500/10 text-emerald-
|
|
2024
|
-
warn: "bg-amber-500/10 text-amber-
|
|
2025
|
-
danger: "bg-destructive/10 text-destructive",
|
|
2026
|
-
muted: "bg-muted/
|
|
2123
|
+
default: "bg-muted text-foreground ring-border",
|
|
2124
|
+
primary: "bg-primary/10 text-primary ring-primary/20",
|
|
2125
|
+
success: "bg-emerald-500/10 text-emerald-700 ring-emerald-500/20 dark:text-emerald-400",
|
|
2126
|
+
warn: "bg-amber-500/10 text-amber-700 ring-amber-500/25 dark:text-amber-400",
|
|
2127
|
+
danger: "bg-destructive/10 text-destructive ring-destructive/20",
|
|
2128
|
+
muted: "bg-muted/70 text-muted-foreground ring-border/60"
|
|
2129
|
+
};
|
|
2130
|
+
var statusBadgeDotClass = {
|
|
2131
|
+
default: "bg-foreground/40",
|
|
2132
|
+
primary: "bg-primary",
|
|
2133
|
+
success: "bg-emerald-500",
|
|
2134
|
+
warn: "bg-amber-500",
|
|
2135
|
+
danger: "bg-destructive",
|
|
2136
|
+
muted: "bg-muted-foreground/60"
|
|
2027
2137
|
};
|
|
2028
2138
|
var StatusBadge = ({
|
|
2029
2139
|
children,
|
|
2030
2140
|
tone = "default",
|
|
2141
|
+
dot = false,
|
|
2031
2142
|
className
|
|
2032
2143
|
}) => {
|
|
2033
|
-
return /* @__PURE__ */
|
|
2144
|
+
return /* @__PURE__ */ jsxs13(
|
|
2034
2145
|
"span",
|
|
2035
2146
|
{
|
|
2036
2147
|
className: cn(
|
|
2037
|
-
"aui-app-status-badge inline-flex items-center rounded-full px-2 py-0.5
|
|
2148
|
+
"aui-app-status-badge inline-flex items-center gap-1.5 rounded-full px-2 py-0.5",
|
|
2149
|
+
"text-xs font-medium leading-none ring-1 ring-inset",
|
|
2038
2150
|
statusBadgeToneClass[tone],
|
|
2039
2151
|
className
|
|
2040
2152
|
),
|
|
2041
|
-
children
|
|
2153
|
+
children: [
|
|
2154
|
+
dot ? /* @__PURE__ */ jsx18(
|
|
2155
|
+
"span",
|
|
2156
|
+
{
|
|
2157
|
+
"aria-hidden": true,
|
|
2158
|
+
className: cn(
|
|
2159
|
+
"size-1.5 shrink-0 rounded-full",
|
|
2160
|
+
statusBadgeDotClass[tone]
|
|
2161
|
+
)
|
|
2162
|
+
}
|
|
2163
|
+
) : null,
|
|
2164
|
+
children
|
|
2165
|
+
]
|
|
2042
2166
|
}
|
|
2043
2167
|
);
|
|
2044
2168
|
};
|
|
2045
2169
|
|
|
2046
2170
|
// src/app/surfaces/AppConfirmDialog.tsx
|
|
2047
|
-
import { jsx as
|
|
2171
|
+
import { jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2048
2172
|
var bodyClass2 = "flex flex-col gap-4 p-6";
|
|
2049
2173
|
var titleClass = "pr-8";
|
|
2050
2174
|
var actionsClass = "flex flex-wrap justify-end gap-2";
|
|
@@ -2059,15 +2183,15 @@ var AppConfirmDialog = ({
|
|
|
2059
2183
|
destructive = false,
|
|
2060
2184
|
className
|
|
2061
2185
|
}) => {
|
|
2062
|
-
return /* @__PURE__ */
|
|
2186
|
+
return /* @__PURE__ */ jsx19(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsx19(
|
|
2063
2187
|
DialogContent,
|
|
2064
2188
|
{
|
|
2065
2189
|
className: cn("gap-0 p-0 sm:max-w-md", className),
|
|
2066
|
-
children: /* @__PURE__ */
|
|
2067
|
-
/* @__PURE__ */
|
|
2068
|
-
description ? /* @__PURE__ */
|
|
2069
|
-
/* @__PURE__ */
|
|
2070
|
-
/* @__PURE__ */
|
|
2190
|
+
children: /* @__PURE__ */ jsxs14("div", { className: bodyClass2, children: [
|
|
2191
|
+
/* @__PURE__ */ jsx19(DialogTitle, { className: titleClass, children: title }),
|
|
2192
|
+
description ? /* @__PURE__ */ jsx19("p", { className: "text-sm text-muted-foreground", children: description }) : null,
|
|
2193
|
+
/* @__PURE__ */ jsxs14("div", { className: actionsClass, children: [
|
|
2194
|
+
/* @__PURE__ */ jsx19(
|
|
2071
2195
|
TimbalV2Button,
|
|
2072
2196
|
{
|
|
2073
2197
|
type: "button",
|
|
@@ -2077,7 +2201,7 @@ var AppConfirmDialog = ({
|
|
|
2077
2201
|
children: cancelLabel
|
|
2078
2202
|
}
|
|
2079
2203
|
),
|
|
2080
|
-
/* @__PURE__ */
|
|
2204
|
+
/* @__PURE__ */ jsx19(
|
|
2081
2205
|
TimbalV2Button,
|
|
2082
2206
|
{
|
|
2083
2207
|
type: "button",
|
|
@@ -2097,7 +2221,7 @@ var AppConfirmDialog = ({
|
|
|
2097
2221
|
};
|
|
2098
2222
|
|
|
2099
2223
|
// src/app/surfaces/InfoCard.tsx
|
|
2100
|
-
import { jsx as
|
|
2224
|
+
import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2101
2225
|
var toneClass = {
|
|
2102
2226
|
neutral: "border-border bg-muted/40",
|
|
2103
2227
|
info: "border-primary/25 bg-primary/5",
|
|
@@ -2112,7 +2236,7 @@ var InfoCard = ({
|
|
|
2112
2236
|
action,
|
|
2113
2237
|
tone = "neutral",
|
|
2114
2238
|
className
|
|
2115
|
-
}) => /* @__PURE__ */
|
|
2239
|
+
}) => /* @__PURE__ */ jsxs15(
|
|
2116
2240
|
"div",
|
|
2117
2241
|
{
|
|
2118
2242
|
className: cn(
|
|
@@ -2121,18 +2245,18 @@ var InfoCard = ({
|
|
|
2121
2245
|
className
|
|
2122
2246
|
),
|
|
2123
2247
|
children: [
|
|
2124
|
-
icon ? /* @__PURE__ */
|
|
2125
|
-
/* @__PURE__ */
|
|
2126
|
-
title ? /* @__PURE__ */
|
|
2127
|
-
children ? /* @__PURE__ */
|
|
2248
|
+
icon ? /* @__PURE__ */ jsx20("span", { className: "mt-0.5 shrink-0 text-muted-foreground", children: icon }) : null,
|
|
2249
|
+
/* @__PURE__ */ jsxs15("div", { className: "min-w-0 flex-1", children: [
|
|
2250
|
+
title ? /* @__PURE__ */ jsx20("p", { className: "text-sm font-medium text-foreground", children: title }) : null,
|
|
2251
|
+
children ? /* @__PURE__ */ jsx20("div", { className: cn("text-sm text-muted-foreground", title && "mt-1"), children }) : null
|
|
2128
2252
|
] }),
|
|
2129
|
-
action ? /* @__PURE__ */
|
|
2253
|
+
action ? /* @__PURE__ */ jsx20("div", { className: "shrink-0", children: action }) : null
|
|
2130
2254
|
]
|
|
2131
2255
|
}
|
|
2132
2256
|
);
|
|
2133
2257
|
|
|
2134
2258
|
// src/app/surfaces/StatusDot.tsx
|
|
2135
|
-
import { jsx as
|
|
2259
|
+
import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2136
2260
|
var dotClass = {
|
|
2137
2261
|
online: "bg-emerald-500",
|
|
2138
2262
|
busy: "bg-amber-500",
|
|
@@ -2145,9 +2269,9 @@ var StatusDot = ({
|
|
|
2145
2269
|
label,
|
|
2146
2270
|
pulse = false,
|
|
2147
2271
|
className
|
|
2148
|
-
}) => /* @__PURE__ */
|
|
2149
|
-
/* @__PURE__ */
|
|
2150
|
-
pulse ? /* @__PURE__ */
|
|
2272
|
+
}) => /* @__PURE__ */ jsxs16("span", { className: cn("inline-flex items-center gap-1.5", className), children: [
|
|
2273
|
+
/* @__PURE__ */ jsxs16("span", { className: "relative flex size-2", children: [
|
|
2274
|
+
pulse ? /* @__PURE__ */ jsx21(
|
|
2151
2275
|
"span",
|
|
2152
2276
|
{
|
|
2153
2277
|
className: cn(
|
|
@@ -2156,25 +2280,25 @@ var StatusDot = ({
|
|
|
2156
2280
|
)
|
|
2157
2281
|
}
|
|
2158
2282
|
) : null,
|
|
2159
|
-
/* @__PURE__ */
|
|
2283
|
+
/* @__PURE__ */ jsx21("span", { className: cn("relative inline-flex size-2 rounded-full", dotClass[tone]) })
|
|
2160
2284
|
] }),
|
|
2161
|
-
label ? /* @__PURE__ */
|
|
2285
|
+
label ? /* @__PURE__ */ jsx21("span", { className: "text-xs text-muted-foreground", children: label }) : null
|
|
2162
2286
|
] });
|
|
2163
2287
|
|
|
2164
2288
|
// src/app/surfaces/DescriptionList.tsx
|
|
2165
|
-
import { jsx as
|
|
2289
|
+
import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2166
2290
|
var DescriptionList = ({
|
|
2167
2291
|
items,
|
|
2168
2292
|
stacked = false,
|
|
2169
2293
|
className
|
|
2170
|
-
}) => /* @__PURE__ */
|
|
2294
|
+
}) => /* @__PURE__ */ jsx22(
|
|
2171
2295
|
"dl",
|
|
2172
2296
|
{
|
|
2173
2297
|
className: cn(
|
|
2174
2298
|
"divide-y divide-border rounded-xl border border-border bg-card",
|
|
2175
2299
|
className
|
|
2176
2300
|
),
|
|
2177
|
-
children: items.map((item, i) => /* @__PURE__ */
|
|
2301
|
+
children: items.map((item, i) => /* @__PURE__ */ jsxs17(
|
|
2178
2302
|
"div",
|
|
2179
2303
|
{
|
|
2180
2304
|
className: cn(
|
|
@@ -2182,8 +2306,8 @@ var DescriptionList = ({
|
|
|
2182
2306
|
stacked ? "flex flex-col gap-0.5" : "flex items-center justify-between gap-4"
|
|
2183
2307
|
),
|
|
2184
2308
|
children: [
|
|
2185
|
-
/* @__PURE__ */
|
|
2186
|
-
/* @__PURE__ */
|
|
2309
|
+
/* @__PURE__ */ jsx22("dt", { className: "text-sm text-muted-foreground", children: item.label }),
|
|
2310
|
+
/* @__PURE__ */ jsx22(
|
|
2187
2311
|
"dd",
|
|
2188
2312
|
{
|
|
2189
2313
|
className: cn(
|
|
@@ -2203,8 +2327,8 @@ var DescriptionList = ({
|
|
|
2203
2327
|
// src/app/surfaces/ExpandableSection.tsx
|
|
2204
2328
|
import { useId, useState as useState2 } from "react";
|
|
2205
2329
|
import { AnimatePresence, motion as motion2, useReducedMotion as useReducedMotion2 } from "motion/react";
|
|
2206
|
-
import { jsx as
|
|
2207
|
-
var Chevron = ({ open }) => /* @__PURE__ */
|
|
2330
|
+
import { jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2331
|
+
var Chevron = ({ open }) => /* @__PURE__ */ jsx23(
|
|
2208
2332
|
"svg",
|
|
2209
2333
|
{
|
|
2210
2334
|
viewBox: "0 0 24 24",
|
|
@@ -2218,7 +2342,7 @@ var Chevron = ({ open }) => /* @__PURE__ */ jsx22(
|
|
|
2218
2342
|
strokeLinecap: "round",
|
|
2219
2343
|
strokeLinejoin: "round",
|
|
2220
2344
|
"aria-hidden": true,
|
|
2221
|
-
children: /* @__PURE__ */
|
|
2345
|
+
children: /* @__PURE__ */ jsx23("path", { d: "m6 9 6 6 6-6" })
|
|
2222
2346
|
}
|
|
2223
2347
|
);
|
|
2224
2348
|
var ExpandableSection = ({
|
|
@@ -2239,8 +2363,8 @@ var ExpandableSection = ({
|
|
|
2239
2363
|
if (openProp == null) setInternalOpen((o) => !o);
|
|
2240
2364
|
onOpenChange?.(!open);
|
|
2241
2365
|
};
|
|
2242
|
-
return /* @__PURE__ */
|
|
2243
|
-
/* @__PURE__ */
|
|
2366
|
+
return /* @__PURE__ */ jsxs18("div", { className: cn("border-b border-border last:border-0", className), children: [
|
|
2367
|
+
/* @__PURE__ */ jsxs18(
|
|
2244
2368
|
"button",
|
|
2245
2369
|
{
|
|
2246
2370
|
type: "button",
|
|
@@ -2249,16 +2373,16 @@ var ExpandableSection = ({
|
|
|
2249
2373
|
"aria-controls": panelId,
|
|
2250
2374
|
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",
|
|
2251
2375
|
children: [
|
|
2252
|
-
/* @__PURE__ */
|
|
2253
|
-
icon ? /* @__PURE__ */
|
|
2254
|
-
/* @__PURE__ */
|
|
2255
|
-
count != null ? /* @__PURE__ */
|
|
2376
|
+
/* @__PURE__ */ jsxs18("span", { className: "flex min-w-0 items-center gap-3", children: [
|
|
2377
|
+
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,
|
|
2378
|
+
/* @__PURE__ */ jsx23("span", { className: "truncate text-sm font-medium text-foreground", children: title }),
|
|
2379
|
+
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
|
|
2256
2380
|
] }),
|
|
2257
|
-
/* @__PURE__ */
|
|
2381
|
+
/* @__PURE__ */ jsx23(Chevron, { open })
|
|
2258
2382
|
]
|
|
2259
2383
|
}
|
|
2260
2384
|
),
|
|
2261
|
-
/* @__PURE__ */
|
|
2385
|
+
/* @__PURE__ */ jsx23(AnimatePresence, { initial: false, children: open ? /* @__PURE__ */ jsx23(
|
|
2262
2386
|
motion2.div,
|
|
2263
2387
|
{
|
|
2264
2388
|
id: panelId,
|
|
@@ -2267,7 +2391,7 @@ var ExpandableSection = ({
|
|
|
2267
2391
|
exit: reduceMotion ? void 0 : { height: 0, opacity: 0 },
|
|
2268
2392
|
transition: { duration: 0.2, ease: "easeOut" },
|
|
2269
2393
|
className: "overflow-hidden",
|
|
2270
|
-
children: /* @__PURE__ */
|
|
2394
|
+
children: /* @__PURE__ */ jsx23("div", { className: "bg-muted/20", children })
|
|
2271
2395
|
},
|
|
2272
2396
|
"body"
|
|
2273
2397
|
) : null })
|
|
@@ -2275,7 +2399,7 @@ var ExpandableSection = ({
|
|
|
2275
2399
|
};
|
|
2276
2400
|
|
|
2277
2401
|
// src/app/surfaces/ResourceCard.tsx
|
|
2278
|
-
import { Fragment as Fragment3, jsx as
|
|
2402
|
+
import { Fragment as Fragment3, jsx as jsx24, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2279
2403
|
var resourceCardShellClass = cn(
|
|
2280
2404
|
"flex min-h-[8.5rem] flex-col rounded-2xl p-4 text-left font-normal",
|
|
2281
2405
|
TIMBAL_V2_ELEVATED_SURFACE
|
|
@@ -2300,35 +2424,35 @@ var ResourceCard = ({
|
|
|
2300
2424
|
ariaLabel,
|
|
2301
2425
|
className
|
|
2302
2426
|
}) => {
|
|
2303
|
-
const body = /* @__PURE__ */
|
|
2304
|
-
/* @__PURE__ */
|
|
2305
|
-
media ? /* @__PURE__ */
|
|
2306
|
-
/* @__PURE__ */
|
|
2307
|
-
/* @__PURE__ */
|
|
2308
|
-
subtitle ? /* @__PURE__ */
|
|
2427
|
+
const body = /* @__PURE__ */ jsxs19(Fragment3, { children: [
|
|
2428
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex items-start gap-3", children: [
|
|
2429
|
+
media ? /* @__PURE__ */ jsx24("span", { className: mediaShellClass, children: media }) : null,
|
|
2430
|
+
/* @__PURE__ */ jsxs19("div", { className: "min-w-0 flex-1 pt-0.5", children: [
|
|
2431
|
+
/* @__PURE__ */ jsx24("p", { className: "truncate text-sm font-normal leading-snug text-foreground", children: title }),
|
|
2432
|
+
subtitle ? /* @__PURE__ */ jsx24("p", { className: "mt-1 line-clamp-2 text-xs font-normal text-muted-foreground", children: subtitle }) : null
|
|
2309
2433
|
] }),
|
|
2310
|
-
badge ? /* @__PURE__ */
|
|
2434
|
+
badge ? /* @__PURE__ */ jsx24("span", { className: "shrink-0 pt-0.5", children: badge }) : null
|
|
2311
2435
|
] }),
|
|
2312
|
-
footer || action ? /* @__PURE__ */
|
|
2313
|
-
/* @__PURE__ */
|
|
2314
|
-
action ? /* @__PURE__ */
|
|
2436
|
+
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: [
|
|
2437
|
+
/* @__PURE__ */ jsx24("span", { className: "min-w-0 truncate", children: footer }),
|
|
2438
|
+
action ? /* @__PURE__ */ jsx24("span", { className: "shrink-0 opacity-80", children: action }) : null
|
|
2315
2439
|
] }) : null
|
|
2316
2440
|
] });
|
|
2317
2441
|
if (onClick) {
|
|
2318
|
-
return /* @__PURE__ */
|
|
2442
|
+
return /* @__PURE__ */ jsx24("button", { type: "button", onClick, "aria-label": ariaLabel, className: cn(resourceCardInteractiveClass, className), children: body });
|
|
2319
2443
|
}
|
|
2320
|
-
return /* @__PURE__ */
|
|
2444
|
+
return /* @__PURE__ */ jsx24("article", { className: cn(resourceCardShellClass, className), children: body });
|
|
2321
2445
|
};
|
|
2322
2446
|
|
|
2323
2447
|
// src/app/settings/SettingsSection.tsx
|
|
2324
|
-
import { jsx as
|
|
2448
|
+
import { jsx as jsx25, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
2325
2449
|
var SettingsSectionHeader = ({
|
|
2326
2450
|
title,
|
|
2327
2451
|
description,
|
|
2328
2452
|
className
|
|
2329
|
-
}) => /* @__PURE__ */
|
|
2330
|
-
/* @__PURE__ */
|
|
2331
|
-
description ? /* @__PURE__ */
|
|
2453
|
+
}) => /* @__PURE__ */ jsxs20("div", { className: cn("flex flex-col", className), children: [
|
|
2454
|
+
/* @__PURE__ */ jsx25("h3", { className: "text-[17px] font-medium leading-tight text-foreground", children: title }),
|
|
2455
|
+
description ? /* @__PURE__ */ jsx25("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null
|
|
2332
2456
|
] });
|
|
2333
2457
|
var SettingsSection = ({
|
|
2334
2458
|
title,
|
|
@@ -2337,7 +2461,7 @@ var SettingsSection = ({
|
|
|
2337
2461
|
children,
|
|
2338
2462
|
noBorderTop = false,
|
|
2339
2463
|
className
|
|
2340
|
-
}) => /* @__PURE__ */
|
|
2464
|
+
}) => /* @__PURE__ */ jsxs20(
|
|
2341
2465
|
"section",
|
|
2342
2466
|
{
|
|
2343
2467
|
className: cn(
|
|
@@ -2346,18 +2470,18 @@ var SettingsSection = ({
|
|
|
2346
2470
|
className
|
|
2347
2471
|
),
|
|
2348
2472
|
children: [
|
|
2349
|
-
/* @__PURE__ */
|
|
2350
|
-
/* @__PURE__ */
|
|
2351
|
-
description ? /* @__PURE__ */
|
|
2352
|
-
descriptionFooter ? /* @__PURE__ */
|
|
2473
|
+
/* @__PURE__ */ jsxs20("div", { className: "min-w-0", children: [
|
|
2474
|
+
/* @__PURE__ */ jsx25("h2", { className: "text-sm font-medium text-foreground", children: title }),
|
|
2475
|
+
description ? /* @__PURE__ */ jsx25("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null,
|
|
2476
|
+
descriptionFooter ? /* @__PURE__ */ jsx25("div", { className: "mt-3 min-w-0", children: descriptionFooter }) : null
|
|
2353
2477
|
] }),
|
|
2354
|
-
/* @__PURE__ */
|
|
2478
|
+
/* @__PURE__ */ jsx25("div", { className: "min-w-0 space-y-3", children })
|
|
2355
2479
|
]
|
|
2356
2480
|
}
|
|
2357
2481
|
);
|
|
2358
2482
|
|
|
2359
2483
|
// src/app/settings/FieldRow.tsx
|
|
2360
|
-
import { jsx as
|
|
2484
|
+
import { jsx as jsx26, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
2361
2485
|
var FieldRow = ({
|
|
2362
2486
|
label,
|
|
2363
2487
|
children,
|
|
@@ -2367,7 +2491,7 @@ var FieldRow = ({
|
|
|
2367
2491
|
className
|
|
2368
2492
|
}) => {
|
|
2369
2493
|
if (inline) {
|
|
2370
|
-
return /* @__PURE__ */
|
|
2494
|
+
return /* @__PURE__ */ jsxs21(
|
|
2371
2495
|
"div",
|
|
2372
2496
|
{
|
|
2373
2497
|
className: cn(
|
|
@@ -2375,8 +2499,8 @@ var FieldRow = ({
|
|
|
2375
2499
|
className
|
|
2376
2500
|
),
|
|
2377
2501
|
children: [
|
|
2378
|
-
/* @__PURE__ */
|
|
2379
|
-
/* @__PURE__ */
|
|
2502
|
+
/* @__PURE__ */ jsxs21("div", { className: "min-w-0", children: [
|
|
2503
|
+
/* @__PURE__ */ jsx26(
|
|
2380
2504
|
"label",
|
|
2381
2505
|
{
|
|
2382
2506
|
htmlFor,
|
|
@@ -2384,17 +2508,17 @@ var FieldRow = ({
|
|
|
2384
2508
|
children: label
|
|
2385
2509
|
}
|
|
2386
2510
|
),
|
|
2387
|
-
description ? /* @__PURE__ */
|
|
2511
|
+
description ? /* @__PURE__ */ jsx26("p", { className: "mt-0.5 text-xs text-muted-foreground", children: description }) : null
|
|
2388
2512
|
] }),
|
|
2389
|
-
/* @__PURE__ */
|
|
2513
|
+
/* @__PURE__ */ jsx26("div", { className: "shrink-0", children })
|
|
2390
2514
|
]
|
|
2391
2515
|
}
|
|
2392
2516
|
);
|
|
2393
2517
|
}
|
|
2394
|
-
return /* @__PURE__ */
|
|
2395
|
-
/* @__PURE__ */
|
|
2518
|
+
return /* @__PURE__ */ jsxs21("div", { className: cn("flex flex-col gap-1.5", className), children: [
|
|
2519
|
+
/* @__PURE__ */ jsx26("label", { htmlFor, className: "text-sm font-medium text-foreground", children: label }),
|
|
2396
2520
|
children,
|
|
2397
|
-
description ? /* @__PURE__ */
|
|
2521
|
+
description ? /* @__PURE__ */ jsx26("p", { className: "text-xs text-muted-foreground", children: description }) : null
|
|
2398
2522
|
] });
|
|
2399
2523
|
};
|
|
2400
2524
|
|
|
@@ -2402,7 +2526,7 @@ var FieldRow = ({
|
|
|
2402
2526
|
import { useEffect, useState as useState3 } from "react";
|
|
2403
2527
|
import { createPortal } from "react-dom";
|
|
2404
2528
|
import { AnimatePresence as AnimatePresence2, motion as motion3, useReducedMotion as useReducedMotion3 } from "motion/react";
|
|
2405
|
-
import { jsx as
|
|
2529
|
+
import { jsx as jsx27, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
2406
2530
|
var FloatingUnsavedChangesBar = ({
|
|
2407
2531
|
visible,
|
|
2408
2532
|
message = "Unsaved changes",
|
|
@@ -2420,7 +2544,7 @@ var FloatingUnsavedChangesBar = ({
|
|
|
2420
2544
|
useEffect(() => setMounted(true), []);
|
|
2421
2545
|
if (!mounted || typeof document === "undefined") return null;
|
|
2422
2546
|
return createPortal(
|
|
2423
|
-
/* @__PURE__ */
|
|
2547
|
+
/* @__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(
|
|
2424
2548
|
motion3.div,
|
|
2425
2549
|
{
|
|
2426
2550
|
role: "region",
|
|
@@ -2434,10 +2558,10 @@ var FloatingUnsavedChangesBar = ({
|
|
|
2434
2558
|
className
|
|
2435
2559
|
),
|
|
2436
2560
|
children: [
|
|
2437
|
-
/* @__PURE__ */
|
|
2438
|
-
/* @__PURE__ */
|
|
2439
|
-
/* @__PURE__ */
|
|
2440
|
-
/* @__PURE__ */
|
|
2561
|
+
/* @__PURE__ */ jsx27("span", { className: "text-sm text-muted-foreground", children: message }),
|
|
2562
|
+
/* @__PURE__ */ jsxs22("span", { className: "flex items-center gap-1.5", children: [
|
|
2563
|
+
/* @__PURE__ */ jsx27(Button, { variant: "ghost", size: "sm", onClick: onDiscard, disabled: isSaving, children: discardLabel }),
|
|
2564
|
+
/* @__PURE__ */ jsx27(Button, { size: "sm", onClick: onSave, disabled: saveDisabled || isSaving, children: isSaving ? "Saving\u2026" : saveLabel })
|
|
2441
2565
|
] })
|
|
2442
2566
|
]
|
|
2443
2567
|
}
|
|
@@ -2447,13 +2571,13 @@ var FloatingUnsavedChangesBar = ({
|
|
|
2447
2571
|
};
|
|
2448
2572
|
|
|
2449
2573
|
// src/app/settings/DangerZone.tsx
|
|
2450
|
-
import { jsx as
|
|
2574
|
+
import { jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
2451
2575
|
var DangerZoneAction = ({
|
|
2452
2576
|
title,
|
|
2453
2577
|
description,
|
|
2454
2578
|
action,
|
|
2455
2579
|
className
|
|
2456
|
-
}) => /* @__PURE__ */
|
|
2580
|
+
}) => /* @__PURE__ */ jsxs23(
|
|
2457
2581
|
"div",
|
|
2458
2582
|
{
|
|
2459
2583
|
className: cn(
|
|
@@ -2461,11 +2585,11 @@ var DangerZoneAction = ({
|
|
|
2461
2585
|
className
|
|
2462
2586
|
),
|
|
2463
2587
|
children: [
|
|
2464
|
-
/* @__PURE__ */
|
|
2465
|
-
/* @__PURE__ */
|
|
2466
|
-
description ? /* @__PURE__ */
|
|
2588
|
+
/* @__PURE__ */ jsxs23("div", { className: "min-w-0", children: [
|
|
2589
|
+
/* @__PURE__ */ jsx28("p", { className: "text-sm font-medium text-foreground", children: title }),
|
|
2590
|
+
description ? /* @__PURE__ */ jsx28("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
|
|
2467
2591
|
] }),
|
|
2468
|
-
/* @__PURE__ */
|
|
2592
|
+
/* @__PURE__ */ jsx28("div", { className: "shrink-0", children: action })
|
|
2469
2593
|
]
|
|
2470
2594
|
}
|
|
2471
2595
|
);
|
|
@@ -2474,7 +2598,7 @@ var DangerZone = ({
|
|
|
2474
2598
|
description,
|
|
2475
2599
|
children,
|
|
2476
2600
|
className
|
|
2477
|
-
}) => /* @__PURE__ */
|
|
2601
|
+
}) => /* @__PURE__ */ jsxs23(
|
|
2478
2602
|
"section",
|
|
2479
2603
|
{
|
|
2480
2604
|
className: cn(
|
|
@@ -2482,18 +2606,18 @@ var DangerZone = ({
|
|
|
2482
2606
|
className
|
|
2483
2607
|
),
|
|
2484
2608
|
children: [
|
|
2485
|
-
(title || description) && /* @__PURE__ */
|
|
2486
|
-
title ? /* @__PURE__ */
|
|
2487
|
-
description ? /* @__PURE__ */
|
|
2609
|
+
(title || description) && /* @__PURE__ */ jsxs23("header", { className: "border-b border-destructive/20 bg-destructive/5 px-4 py-3", children: [
|
|
2610
|
+
title ? /* @__PURE__ */ jsx28("h3", { className: "text-sm font-semibold text-destructive", children: title }) : null,
|
|
2611
|
+
description ? /* @__PURE__ */ jsx28("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
|
|
2488
2612
|
] }),
|
|
2489
|
-
/* @__PURE__ */
|
|
2613
|
+
/* @__PURE__ */ jsx28("div", { className: "divide-y divide-border bg-card", children })
|
|
2490
2614
|
]
|
|
2491
2615
|
}
|
|
2492
2616
|
);
|
|
2493
2617
|
|
|
2494
2618
|
// src/app/integrations/IntegrationCard.tsx
|
|
2495
2619
|
import { useId as useId2 } from "react";
|
|
2496
|
-
import { Fragment as Fragment4, jsx as
|
|
2620
|
+
import { Fragment as Fragment4, jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
2497
2621
|
var INTEGRATION_CATALOG_CARD_HEIGHT_CLASS = "h-[12.25rem] min-h-[12.25rem] max-h-[12.25rem]";
|
|
2498
2622
|
var statusLabel = {
|
|
2499
2623
|
available: null,
|
|
@@ -2534,12 +2658,12 @@ var IntegrationCard = ({
|
|
|
2534
2658
|
const titleId = useId2();
|
|
2535
2659
|
const locked = status === "locked";
|
|
2536
2660
|
const dimmed = status === "disabled" || locked;
|
|
2537
|
-
const body = /* @__PURE__ */
|
|
2538
|
-
/* @__PURE__ */
|
|
2539
|
-
logo ? /* @__PURE__ */
|
|
2540
|
-
/* @__PURE__ */
|
|
2541
|
-
/* @__PURE__ */
|
|
2542
|
-
/* @__PURE__ */
|
|
2661
|
+
const body = /* @__PURE__ */ jsxs24("div", { className: "flex h-full min-h-0 flex-col", children: [
|
|
2662
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex shrink-0 items-start gap-3 pr-2", children: [
|
|
2663
|
+
logo ? /* @__PURE__ */ jsx29("span", { className: logoShellClass, "aria-hidden": Boolean(ariaLabel), children: logo }) : null,
|
|
2664
|
+
/* @__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: [
|
|
2665
|
+
/* @__PURE__ */ jsxs24("div", { className: "min-w-0", children: [
|
|
2666
|
+
/* @__PURE__ */ jsx29(
|
|
2543
2667
|
"h4",
|
|
2544
2668
|
{
|
|
2545
2669
|
id: onClick && !action ? void 0 : titleId,
|
|
@@ -2547,12 +2671,12 @@ var IntegrationCard = ({
|
|
|
2547
2671
|
children: name
|
|
2548
2672
|
}
|
|
2549
2673
|
),
|
|
2550
|
-
statusLabel[status] ? /* @__PURE__ */
|
|
2674
|
+
statusLabel[status] ? /* @__PURE__ */ jsx29("p", { className: "mt-0.5 text-xs text-muted-foreground", children: statusLabel[status] }) : null
|
|
2551
2675
|
] }),
|
|
2552
|
-
badge ? /* @__PURE__ */
|
|
2676
|
+
badge ? /* @__PURE__ */ jsx29("span", { className: "shrink-0", children: badge }) : null
|
|
2553
2677
|
] }) })
|
|
2554
2678
|
] }),
|
|
2555
|
-
description ? /* @__PURE__ */
|
|
2679
|
+
description ? /* @__PURE__ */ jsx29(
|
|
2556
2680
|
"p",
|
|
2557
2681
|
{
|
|
2558
2682
|
className: cn(
|
|
@@ -2562,9 +2686,9 @@ var IntegrationCard = ({
|
|
|
2562
2686
|
children: description
|
|
2563
2687
|
}
|
|
2564
2688
|
) : null,
|
|
2565
|
-
action ? /* @__PURE__ */
|
|
2566
|
-
/* @__PURE__ */
|
|
2567
|
-
/* @__PURE__ */
|
|
2689
|
+
action ? /* @__PURE__ */ jsxs24(Fragment4, { children: [
|
|
2690
|
+
/* @__PURE__ */ jsx29("div", { className: "min-h-0 flex-1", "aria-hidden": true }),
|
|
2691
|
+
/* @__PURE__ */ jsx29("div", { className: "relative mt-3 shrink-0", children: action })
|
|
2568
2692
|
] }) : null
|
|
2569
2693
|
] });
|
|
2570
2694
|
const shellClass3 = cn(
|
|
@@ -2574,7 +2698,7 @@ var IntegrationCard = ({
|
|
|
2574
2698
|
className
|
|
2575
2699
|
);
|
|
2576
2700
|
if (onClick && !action) {
|
|
2577
|
-
return /* @__PURE__ */
|
|
2701
|
+
return /* @__PURE__ */ jsx29(
|
|
2578
2702
|
"button",
|
|
2579
2703
|
{
|
|
2580
2704
|
type: "button",
|
|
@@ -2591,12 +2715,12 @@ var IntegrationCard = ({
|
|
|
2591
2715
|
}
|
|
2592
2716
|
);
|
|
2593
2717
|
}
|
|
2594
|
-
return /* @__PURE__ */
|
|
2718
|
+
return /* @__PURE__ */ jsx29("article", { className: shellClass3, "aria-labelledby": titleId, children: body });
|
|
2595
2719
|
};
|
|
2596
2720
|
|
|
2597
2721
|
// src/app/integrations/IntegrationsEmptyState.tsx
|
|
2598
2722
|
import { useId as useId3 } from "react";
|
|
2599
|
-
import { jsx as
|
|
2723
|
+
import { jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
2600
2724
|
var IntegrationsEmptyState = ({
|
|
2601
2725
|
title = "No integrations yet",
|
|
2602
2726
|
description = "Connect a provider to start syncing data and powering your workforce.",
|
|
@@ -2605,7 +2729,7 @@ var IntegrationsEmptyState = ({
|
|
|
2605
2729
|
className
|
|
2606
2730
|
}) => {
|
|
2607
2731
|
const titleId = useId3();
|
|
2608
|
-
return /* @__PURE__ */
|
|
2732
|
+
return /* @__PURE__ */ jsxs25(
|
|
2609
2733
|
"section",
|
|
2610
2734
|
{
|
|
2611
2735
|
className: cn(
|
|
@@ -2615,7 +2739,7 @@ var IntegrationsEmptyState = ({
|
|
|
2615
2739
|
),
|
|
2616
2740
|
"aria-labelledby": titleId,
|
|
2617
2741
|
children: [
|
|
2618
|
-
icon ? /* @__PURE__ */
|
|
2742
|
+
icon ? /* @__PURE__ */ jsx30(
|
|
2619
2743
|
"span",
|
|
2620
2744
|
{
|
|
2621
2745
|
className: cn(
|
|
@@ -2627,21 +2751,21 @@ var IntegrationsEmptyState = ({
|
|
|
2627
2751
|
children: icon
|
|
2628
2752
|
}
|
|
2629
2753
|
) : null,
|
|
2630
|
-
/* @__PURE__ */
|
|
2631
|
-
description ? /* @__PURE__ */
|
|
2632
|
-
action ? /* @__PURE__ */
|
|
2754
|
+
/* @__PURE__ */ jsx30("h3", { id: titleId, className: "text-base font-normal text-foreground", children: title }),
|
|
2755
|
+
description ? /* @__PURE__ */ jsx30("p", { className: "max-w-sm text-sm text-muted-foreground", children: description }) : null,
|
|
2756
|
+
action ? /* @__PURE__ */ jsx30("div", { className: "mt-1", children: action }) : null
|
|
2633
2757
|
]
|
|
2634
2758
|
}
|
|
2635
2759
|
);
|
|
2636
2760
|
};
|
|
2637
2761
|
|
|
2638
2762
|
// src/app/integrations/PlanBadge.tsx
|
|
2639
|
-
import { jsx as
|
|
2763
|
+
import { jsx as jsx31 } from "react/jsx-runtime";
|
|
2640
2764
|
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";
|
|
2641
|
-
var PlanBadge = ({ children, className }) => /* @__PURE__ */
|
|
2765
|
+
var PlanBadge = ({ children, className }) => /* @__PURE__ */ jsx31("span", { className: cn(planBadgeClass, className), children });
|
|
2642
2766
|
|
|
2643
2767
|
// src/app/integrations/ConnectionRow.tsx
|
|
2644
|
-
import { Fragment as Fragment5, jsx as
|
|
2768
|
+
import { Fragment as Fragment5, jsx as jsx32, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
2645
2769
|
var logoShellClass2 = cn(
|
|
2646
2770
|
"flex size-9 shrink-0 items-center justify-center overflow-hidden rounded-lg",
|
|
2647
2771
|
TIMBAL_V2_LOGO_TILE
|
|
@@ -2656,14 +2780,14 @@ var ConnectionRow = ({
|
|
|
2656
2780
|
ariaLabel,
|
|
2657
2781
|
className
|
|
2658
2782
|
}) => {
|
|
2659
|
-
const inner = /* @__PURE__ */
|
|
2660
|
-
logo ? /* @__PURE__ */
|
|
2661
|
-
/* @__PURE__ */
|
|
2662
|
-
/* @__PURE__ */
|
|
2663
|
-
meta ? /* @__PURE__ */
|
|
2783
|
+
const inner = /* @__PURE__ */ jsxs26(Fragment5, { children: [
|
|
2784
|
+
logo ? /* @__PURE__ */ jsx32("span", { className: logoShellClass2, children: logo }) : null,
|
|
2785
|
+
/* @__PURE__ */ jsxs26("div", { className: "min-w-0 flex-1", children: [
|
|
2786
|
+
/* @__PURE__ */ jsx32("p", { className: "truncate text-sm font-normal text-foreground", children: name }),
|
|
2787
|
+
meta ? /* @__PURE__ */ jsx32("p", { className: "truncate text-xs text-muted-foreground", children: meta }) : null
|
|
2664
2788
|
] }),
|
|
2665
|
-
badge ? /* @__PURE__ */
|
|
2666
|
-
action ? /* @__PURE__ */
|
|
2789
|
+
badge ? /* @__PURE__ */ jsx32("span", { className: "shrink-0", children: badge }) : null,
|
|
2790
|
+
action ? /* @__PURE__ */ jsx32("span", { className: "shrink-0", children: action }) : null
|
|
2667
2791
|
] });
|
|
2668
2792
|
const rowClass2 = cn(
|
|
2669
2793
|
"flex w-full items-center gap-3 px-4 py-3 text-left",
|
|
@@ -2671,7 +2795,7 @@ var ConnectionRow = ({
|
|
|
2671
2795
|
className
|
|
2672
2796
|
);
|
|
2673
2797
|
if (onClick) {
|
|
2674
|
-
return /* @__PURE__ */
|
|
2798
|
+
return /* @__PURE__ */ jsx32(
|
|
2675
2799
|
"button",
|
|
2676
2800
|
{
|
|
2677
2801
|
type: "button",
|
|
@@ -2683,7 +2807,7 @@ var ConnectionRow = ({
|
|
|
2683
2807
|
}
|
|
2684
2808
|
);
|
|
2685
2809
|
}
|
|
2686
|
-
return /* @__PURE__ */
|
|
2810
|
+
return /* @__PURE__ */ jsx32("div", { role: "listitem", className: rowClass2, children: inner });
|
|
2687
2811
|
};
|
|
2688
2812
|
var connectionRowListClass = cn(
|
|
2689
2813
|
"overflow-hidden rounded-2xl",
|
|
@@ -2691,12 +2815,12 @@ var connectionRowListClass = cn(
|
|
|
2691
2815
|
);
|
|
2692
2816
|
|
|
2693
2817
|
// src/app/integrations/ConnectionRowList.tsx
|
|
2694
|
-
import { jsx as
|
|
2818
|
+
import { jsx as jsx33 } from "react/jsx-runtime";
|
|
2695
2819
|
var ConnectionRowList = ({
|
|
2696
2820
|
children,
|
|
2697
2821
|
"aria-label": ariaLabel = "Connected integrations",
|
|
2698
2822
|
className
|
|
2699
|
-
}) => /* @__PURE__ */
|
|
2823
|
+
}) => /* @__PURE__ */ jsx33(
|
|
2700
2824
|
"div",
|
|
2701
2825
|
{
|
|
2702
2826
|
role: "list",
|
|
@@ -2707,7 +2831,7 @@ var ConnectionRowList = ({
|
|
|
2707
2831
|
);
|
|
2708
2832
|
|
|
2709
2833
|
// src/app/navigation/SubNav.tsx
|
|
2710
|
-
import { jsx as
|
|
2834
|
+
import { jsx as jsx34 } from "react/jsx-runtime";
|
|
2711
2835
|
var SubNav = ({
|
|
2712
2836
|
items,
|
|
2713
2837
|
activeId,
|
|
@@ -2716,7 +2840,7 @@ var SubNav = ({
|
|
|
2716
2840
|
"aria-label": ariaLabel = "Section navigation",
|
|
2717
2841
|
layoutId
|
|
2718
2842
|
}) => {
|
|
2719
|
-
return /* @__PURE__ */
|
|
2843
|
+
return /* @__PURE__ */ jsx34("nav", { className: cn("aui-app-sub-nav", className), "aria-label": ariaLabel, children: /* @__PURE__ */ jsx34(
|
|
2720
2844
|
PillSegmentedTabs,
|
|
2721
2845
|
{
|
|
2722
2846
|
value: activeId,
|
|
@@ -2730,13 +2854,13 @@ var SubNav = ({
|
|
|
2730
2854
|
};
|
|
2731
2855
|
|
|
2732
2856
|
// src/app/navigation/Breadcrumbs.tsx
|
|
2733
|
-
import { jsx as
|
|
2857
|
+
import { jsx as jsx35, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
2734
2858
|
var Breadcrumbs = ({ items, className }) => {
|
|
2735
|
-
return /* @__PURE__ */
|
|
2859
|
+
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) => {
|
|
2736
2860
|
const isLast = index === items.length - 1;
|
|
2737
|
-
return /* @__PURE__ */
|
|
2738
|
-
index > 0 ? /* @__PURE__ */
|
|
2739
|
-
isLast ? /* @__PURE__ */
|
|
2861
|
+
return /* @__PURE__ */ jsxs27("li", { className: "inline-flex items-center gap-1.5", children: [
|
|
2862
|
+
index > 0 ? /* @__PURE__ */ jsx35("span", { className: "text-muted-foreground/50", "aria-hidden": true, children: "/" }) : null,
|
|
2863
|
+
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(
|
|
2740
2864
|
"button",
|
|
2741
2865
|
{
|
|
2742
2866
|
type: "button",
|
|
@@ -2750,7 +2874,8 @@ var Breadcrumbs = ({ items, className }) => {
|
|
|
2750
2874
|
};
|
|
2751
2875
|
|
|
2752
2876
|
// src/app/forms/Field.tsx
|
|
2753
|
-
import {
|
|
2877
|
+
import { useId as useId4 } from "react";
|
|
2878
|
+
import { jsx as jsx36, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
2754
2879
|
var Field = ({
|
|
2755
2880
|
label,
|
|
2756
2881
|
hint,
|
|
@@ -2759,11 +2884,11 @@ var Field = ({
|
|
|
2759
2884
|
className,
|
|
2760
2885
|
htmlFor
|
|
2761
2886
|
}) => {
|
|
2762
|
-
return /* @__PURE__ */
|
|
2763
|
-
/* @__PURE__ */
|
|
2887
|
+
return /* @__PURE__ */ jsxs28("div", { className: cn("aui-app-field", appFieldClass, className), children: [
|
|
2888
|
+
/* @__PURE__ */ jsx36("label", { className: appFieldLabelClass, htmlFor, children: label }),
|
|
2764
2889
|
children,
|
|
2765
|
-
hint && !error ? /* @__PURE__ */
|
|
2766
|
-
error ? /* @__PURE__ */
|
|
2890
|
+
hint && !error ? /* @__PURE__ */ jsx36("p", { className: appFieldHintClass, children: hint }) : null,
|
|
2891
|
+
error ? /* @__PURE__ */ jsx36("p", { className: "text-xs text-destructive", role: "alert", children: error }) : null
|
|
2767
2892
|
] });
|
|
2768
2893
|
};
|
|
2769
2894
|
var FieldInput = ({
|
|
@@ -2775,8 +2900,9 @@ var FieldInput = ({
|
|
|
2775
2900
|
id,
|
|
2776
2901
|
...inputProps
|
|
2777
2902
|
}) => {
|
|
2778
|
-
const
|
|
2779
|
-
|
|
2903
|
+
const autoId = useId4();
|
|
2904
|
+
const inputId = id ?? inputProps.name ?? autoId;
|
|
2905
|
+
return /* @__PURE__ */ jsx36(
|
|
2780
2906
|
Field,
|
|
2781
2907
|
{
|
|
2782
2908
|
label,
|
|
@@ -2784,7 +2910,7 @@ var FieldInput = ({
|
|
|
2784
2910
|
error,
|
|
2785
2911
|
htmlFor: inputId,
|
|
2786
2912
|
className: fieldClassName,
|
|
2787
|
-
children: /* @__PURE__ */
|
|
2913
|
+
children: /* @__PURE__ */ jsx36(
|
|
2788
2914
|
"input",
|
|
2789
2915
|
{
|
|
2790
2916
|
id: inputId,
|
|
@@ -2798,7 +2924,8 @@ var FieldInput = ({
|
|
|
2798
2924
|
};
|
|
2799
2925
|
|
|
2800
2926
|
// src/app/forms/FieldTextarea.tsx
|
|
2801
|
-
import {
|
|
2927
|
+
import { useId as useId5 } from "react";
|
|
2928
|
+
import { jsx as jsx37 } from "react/jsx-runtime";
|
|
2802
2929
|
var textareaClass = cn(
|
|
2803
2930
|
appInputClass,
|
|
2804
2931
|
"min-h-[5.5rem] resize-y py-2.5 leading-relaxed"
|
|
@@ -2812,8 +2939,9 @@ var FieldTextarea = ({
|
|
|
2812
2939
|
id,
|
|
2813
2940
|
...props
|
|
2814
2941
|
}) => {
|
|
2815
|
-
const
|
|
2816
|
-
|
|
2942
|
+
const autoId = useId5();
|
|
2943
|
+
const textareaId = id ?? props.name ?? autoId;
|
|
2944
|
+
return /* @__PURE__ */ jsx37(
|
|
2817
2945
|
Field,
|
|
2818
2946
|
{
|
|
2819
2947
|
label,
|
|
@@ -2821,7 +2949,7 @@ var FieldTextarea = ({
|
|
|
2821
2949
|
error,
|
|
2822
2950
|
htmlFor: textareaId,
|
|
2823
2951
|
className: fieldClassName,
|
|
2824
|
-
children: /* @__PURE__ */
|
|
2952
|
+
children: /* @__PURE__ */ jsx37(
|
|
2825
2953
|
"textarea",
|
|
2826
2954
|
{
|
|
2827
2955
|
id: textareaId,
|
|
@@ -2835,8 +2963,9 @@ var FieldTextarea = ({
|
|
|
2835
2963
|
};
|
|
2836
2964
|
|
|
2837
2965
|
// src/app/forms/FieldSelect.tsx
|
|
2966
|
+
import { useId as useId6 } from "react";
|
|
2838
2967
|
import { ChevronDownIcon } from "lucide-react";
|
|
2839
|
-
import { jsx as
|
|
2968
|
+
import { jsx as jsx38, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
2840
2969
|
var selectWrapClass = "relative";
|
|
2841
2970
|
var selectClass = cn(
|
|
2842
2971
|
appInputClass,
|
|
@@ -2852,8 +2981,9 @@ var FieldSelect = ({
|
|
|
2852
2981
|
id,
|
|
2853
2982
|
...props
|
|
2854
2983
|
}) => {
|
|
2855
|
-
const
|
|
2856
|
-
|
|
2984
|
+
const autoId = useId6();
|
|
2985
|
+
const selectId = id ?? props.name ?? autoId;
|
|
2986
|
+
return /* @__PURE__ */ jsx38(
|
|
2857
2987
|
Field,
|
|
2858
2988
|
{
|
|
2859
2989
|
label,
|
|
@@ -2861,8 +2991,8 @@ var FieldSelect = ({
|
|
|
2861
2991
|
error,
|
|
2862
2992
|
htmlFor: selectId,
|
|
2863
2993
|
className: fieldClassName,
|
|
2864
|
-
children: /* @__PURE__ */
|
|
2865
|
-
/* @__PURE__ */
|
|
2994
|
+
children: /* @__PURE__ */ jsxs29("div", { className: selectWrapClass, children: [
|
|
2995
|
+
/* @__PURE__ */ jsx38(
|
|
2866
2996
|
"select",
|
|
2867
2997
|
{
|
|
2868
2998
|
id: selectId,
|
|
@@ -2872,7 +3002,7 @@ var FieldSelect = ({
|
|
|
2872
3002
|
children
|
|
2873
3003
|
}
|
|
2874
3004
|
),
|
|
2875
|
-
/* @__PURE__ */
|
|
3005
|
+
/* @__PURE__ */ jsx38(
|
|
2876
3006
|
ChevronDownIcon,
|
|
2877
3007
|
{
|
|
2878
3008
|
className: "pointer-events-none absolute top-1/2 right-3 size-4 -translate-y-1/2 text-muted-foreground",
|
|
@@ -2885,7 +3015,8 @@ var FieldSelect = ({
|
|
|
2885
3015
|
};
|
|
2886
3016
|
|
|
2887
3017
|
// src/app/forms/FieldSwitch.tsx
|
|
2888
|
-
import {
|
|
3018
|
+
import { useId as useId7 } from "react";
|
|
3019
|
+
import { jsx as jsx39, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
2889
3020
|
var trackClass = cn(
|
|
2890
3021
|
"relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-[background,box-shadow,border-color] duration-200",
|
|
2891
3022
|
"peer-focus-visible:ring-2 peer-focus-visible:ring-foreground/10",
|
|
@@ -2905,8 +3036,9 @@ var FieldSwitch = ({
|
|
|
2905
3036
|
id,
|
|
2906
3037
|
...props
|
|
2907
3038
|
}) => {
|
|
2908
|
-
const
|
|
2909
|
-
|
|
3039
|
+
const autoId = useId7();
|
|
3040
|
+
const inputId = id ?? props.name ?? autoId;
|
|
3041
|
+
return /* @__PURE__ */ jsxs30(
|
|
2910
3042
|
"label",
|
|
2911
3043
|
{
|
|
2912
3044
|
className: cn(
|
|
@@ -2915,8 +3047,8 @@ var FieldSwitch = ({
|
|
|
2915
3047
|
),
|
|
2916
3048
|
htmlFor: inputId,
|
|
2917
3049
|
children: [
|
|
2918
|
-
/* @__PURE__ */
|
|
2919
|
-
/* @__PURE__ */
|
|
3050
|
+
/* @__PURE__ */ jsxs30("span", { className: "relative mt-0.5", children: [
|
|
3051
|
+
/* @__PURE__ */ jsx39(
|
|
2920
3052
|
"input",
|
|
2921
3053
|
{
|
|
2922
3054
|
id: inputId,
|
|
@@ -2926,11 +3058,11 @@ var FieldSwitch = ({
|
|
|
2926
3058
|
...props
|
|
2927
3059
|
}
|
|
2928
3060
|
),
|
|
2929
|
-
/* @__PURE__ */
|
|
3061
|
+
/* @__PURE__ */ jsx39("span", { className: trackClass, "aria-hidden": true, children: /* @__PURE__ */ jsx39("span", { className: thumbClass }) })
|
|
2930
3062
|
] }),
|
|
2931
|
-
/* @__PURE__ */
|
|
2932
|
-
/* @__PURE__ */
|
|
2933
|
-
description ? /* @__PURE__ */
|
|
3063
|
+
/* @__PURE__ */ jsxs30("span", { className: "flex min-w-0 flex-col gap-0.5", children: [
|
|
3064
|
+
/* @__PURE__ */ jsx39("span", { className: "text-sm font-medium text-foreground", children: label }),
|
|
3065
|
+
description ? /* @__PURE__ */ jsx39("span", { className: "text-xs text-muted-foreground", children: description }) : null
|
|
2934
3066
|
] })
|
|
2935
3067
|
]
|
|
2936
3068
|
}
|
|
@@ -2939,13 +3071,13 @@ var FieldSwitch = ({
|
|
|
2939
3071
|
|
|
2940
3072
|
// src/app/forms/SearchInput.tsx
|
|
2941
3073
|
import { SearchIcon } from "lucide-react";
|
|
2942
|
-
import { jsx as
|
|
3074
|
+
import { jsx as jsx40, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
2943
3075
|
var SearchInput = ({
|
|
2944
3076
|
className,
|
|
2945
3077
|
placeholder = "Search\u2026",
|
|
2946
3078
|
...props
|
|
2947
3079
|
}) => {
|
|
2948
|
-
return /* @__PURE__ */
|
|
3080
|
+
return /* @__PURE__ */ jsxs31(
|
|
2949
3081
|
"label",
|
|
2950
3082
|
{
|
|
2951
3083
|
className: cn(
|
|
@@ -2954,8 +3086,8 @@ var SearchInput = ({
|
|
|
2954
3086
|
className
|
|
2955
3087
|
),
|
|
2956
3088
|
children: [
|
|
2957
|
-
/* @__PURE__ */
|
|
2958
|
-
/* @__PURE__ */
|
|
3089
|
+
/* @__PURE__ */ jsx40(SearchIcon, { className: "size-4 shrink-0 text-muted-foreground", "aria-hidden": true }),
|
|
3090
|
+
/* @__PURE__ */ jsx40(
|
|
2959
3091
|
"input",
|
|
2960
3092
|
{
|
|
2961
3093
|
type: "search",
|
|
@@ -2970,18 +3102,26 @@ var SearchInput = ({
|
|
|
2970
3102
|
};
|
|
2971
3103
|
|
|
2972
3104
|
// src/app/forms/FormSection.tsx
|
|
2973
|
-
import { jsx as
|
|
3105
|
+
import { jsx as jsx41, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
2974
3106
|
var FormSection = ({ title, children, className }) => {
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
3107
|
+
const density = useAppDensity();
|
|
3108
|
+
const sectionClass = useAppDensityClass("section");
|
|
3109
|
+
return /* @__PURE__ */ jsxs32(
|
|
3110
|
+
"fieldset",
|
|
3111
|
+
{
|
|
3112
|
+
className: cn("aui-app-form-section", sectionClass, "border-0 p-0", className),
|
|
3113
|
+
children: [
|
|
3114
|
+
title ? /* @__PURE__ */ jsx41("legend", { className: cn(appSectionTitleClass, "mb-3 px-0"), children: title }) : null,
|
|
3115
|
+
/* @__PURE__ */ jsx41("div", { className: cn("flex flex-col", density === "compact" ? "gap-2" : "gap-4"), children })
|
|
3116
|
+
]
|
|
3117
|
+
}
|
|
3118
|
+
);
|
|
2979
3119
|
};
|
|
2980
3120
|
|
|
2981
3121
|
// src/app/data/FilterBar.tsx
|
|
2982
|
-
import { jsx as
|
|
3122
|
+
import { jsx as jsx42 } from "react/jsx-runtime";
|
|
2983
3123
|
var FilterBar = ({ children, className }) => {
|
|
2984
|
-
return /* @__PURE__ */
|
|
3124
|
+
return /* @__PURE__ */ jsx42(
|
|
2985
3125
|
"div",
|
|
2986
3126
|
{
|
|
2987
3127
|
className: cn("aui-app-filter-bar", appFilterBarClass, className),
|
|
@@ -2993,14 +3133,14 @@ var FilterBar = ({ children, className }) => {
|
|
|
2993
3133
|
};
|
|
2994
3134
|
|
|
2995
3135
|
// src/app/data/FilterField.tsx
|
|
2996
|
-
import { jsx as
|
|
3136
|
+
import { jsx as jsx43, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
2997
3137
|
var FilterField = ({
|
|
2998
3138
|
label,
|
|
2999
3139
|
children,
|
|
3000
3140
|
className
|
|
3001
3141
|
}) => {
|
|
3002
|
-
return /* @__PURE__ */
|
|
3003
|
-
label ? /* @__PURE__ */
|
|
3142
|
+
return /* @__PURE__ */ jsxs33("div", { className: cn("aui-app-filter-field", appFieldClass, className), children: [
|
|
3143
|
+
label ? /* @__PURE__ */ jsx43("span", { className: appFieldLabelClass, children: label }) : null,
|
|
3004
3144
|
children
|
|
3005
3145
|
] });
|
|
3006
3146
|
};
|
|
@@ -3014,19 +3154,20 @@ import {
|
|
|
3014
3154
|
ChevronLeftIcon,
|
|
3015
3155
|
ChevronRightIcon
|
|
3016
3156
|
} from "lucide-react";
|
|
3017
|
-
import { jsx as
|
|
3018
|
-
var shellClass2 = "overflow-hidden rounded-xl border border-border bg-
|
|
3157
|
+
import { jsx as jsx44, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
3158
|
+
var shellClass2 = "overflow-hidden rounded-xl border border-border bg-gradient-to-b from-elevated-from to-elevated-to shadow-card";
|
|
3019
3159
|
var tableClass = "w-full border-collapse bg-transparent text-sm";
|
|
3020
|
-
var
|
|
3160
|
+
var headRowClass = "bg-muted/40";
|
|
3161
|
+
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";
|
|
3021
3162
|
var bodyCellClass = "border-b border-border/40 bg-transparent px-4 py-2.5 text-foreground";
|
|
3022
|
-
var rowClass = "bg-transparent transition-colors hover:bg-
|
|
3023
|
-
var footCellClass = "border-t border-border/60 bg-
|
|
3163
|
+
var rowClass = "bg-transparent transition-colors hover:bg-muted/40 data-[clickable=true]:cursor-pointer data-[selected=true]:bg-primary/[0.06]";
|
|
3164
|
+
var footCellClass = "border-t border-border/60 bg-muted/20 px-4 py-2.5 text-xs text-muted-foreground";
|
|
3024
3165
|
var footInnerClass = "flex flex-wrap items-center gap-2";
|
|
3025
3166
|
var emptyCellClass = "bg-transparent px-4 py-10 text-center text-sm text-muted-foreground";
|
|
3026
|
-
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-
|
|
3027
|
-
var stickyHeadClass = "sticky top-0 z-[1] bg-
|
|
3167
|
+
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";
|
|
3168
|
+
var stickyHeadClass = "sticky top-0 z-[1] bg-muted/95 shadow-[0_1px_0_0_hsl(var(--border)/0.6)] backdrop-blur-sm";
|
|
3028
3169
|
var selectCellClass = "w-10 px-4 py-2.5 align-middle";
|
|
3029
|
-
var pagerButtonClass = "inline-flex size-7 items-center justify-center rounded-md border border-border bg-
|
|
3170
|
+
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";
|
|
3030
3171
|
var alignClass = {
|
|
3031
3172
|
left: "text-left",
|
|
3032
3173
|
center: "text-center",
|
|
@@ -3056,12 +3197,12 @@ function SortIndicator({
|
|
|
3056
3197
|
}) {
|
|
3057
3198
|
const iconClass = "size-3.5 shrink-0 opacity-60 group-hover:opacity-100";
|
|
3058
3199
|
if (!active) {
|
|
3059
|
-
return /* @__PURE__ */
|
|
3200
|
+
return /* @__PURE__ */ jsx44(ArrowUpDownIcon, { className: iconClass, "aria-hidden": true });
|
|
3060
3201
|
}
|
|
3061
3202
|
if (direction === "desc") {
|
|
3062
|
-
return /* @__PURE__ */
|
|
3203
|
+
return /* @__PURE__ */ jsx44(ArrowDownIcon, { className: iconClass, "aria-hidden": true });
|
|
3063
3204
|
}
|
|
3064
|
-
return /* @__PURE__ */
|
|
3205
|
+
return /* @__PURE__ */ jsx44(ArrowUpIcon, { className: iconClass, "aria-hidden": true });
|
|
3065
3206
|
}
|
|
3066
3207
|
function DataTable({
|
|
3067
3208
|
columns,
|
|
@@ -3159,7 +3300,7 @@ function DataTable({
|
|
|
3159
3300
|
const headPad = dense ? "px-3 py-2" : void 0;
|
|
3160
3301
|
const colSpan = columns.length + (selectable ? 1 : 0);
|
|
3161
3302
|
if (!loading && rows.length === 0 && emptyMode === "replace") {
|
|
3162
|
-
return /* @__PURE__ */
|
|
3303
|
+
return /* @__PURE__ */ jsx44(EmptyState, { title: emptyTitle, description: emptyDescription, className });
|
|
3163
3304
|
}
|
|
3164
3305
|
const allKeys = sortedRows.map(getRowKey);
|
|
3165
3306
|
const allSelected = allKeys.length > 0 && allKeys.every((k) => selectedSet.has(k));
|
|
@@ -3184,10 +3325,10 @@ function DataTable({
|
|
|
3184
3325
|
const hasPager = paginated && !loading && sortedRows.length > 0;
|
|
3185
3326
|
const hasFoot = (showRowCount || footer || hasPager) && (loading || sortedRows.length > 0);
|
|
3186
3327
|
const skeletonCount = loadingRows ?? pageSize ?? 5;
|
|
3187
|
-
return /* @__PURE__ */
|
|
3188
|
-
caption ? /* @__PURE__ */
|
|
3189
|
-
/* @__PURE__ */
|
|
3190
|
-
selectable ? /* @__PURE__ */
|
|
3328
|
+
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: [
|
|
3329
|
+
caption ? /* @__PURE__ */ jsx44("caption", { className: "sr-only", children: caption }) : null,
|
|
3330
|
+
/* @__PURE__ */ jsx44("thead", { className: cn(headRowClass, stickyHeader && stickyHeadClass), children: /* @__PURE__ */ jsxs34("tr", { children: [
|
|
3331
|
+
selectable ? /* @__PURE__ */ jsx44("th", { scope: "col", className: cn(selectCellClass, headPad), children: /* @__PURE__ */ jsx44(
|
|
3191
3332
|
Checkbox,
|
|
3192
3333
|
{
|
|
3193
3334
|
checked: headerCheckedState,
|
|
@@ -3199,19 +3340,19 @@ function DataTable({
|
|
|
3199
3340
|
columns.map((col) => {
|
|
3200
3341
|
const isSorted = sort?.columnId === col.id;
|
|
3201
3342
|
const ariaSort = col.sortable ? isSorted ? sort.direction === "asc" ? "ascending" : "descending" : "none" : void 0;
|
|
3202
|
-
const headerContent = col.sortable ? /* @__PURE__ */
|
|
3343
|
+
const headerContent = col.sortable ? /* @__PURE__ */ jsxs34(
|
|
3203
3344
|
"button",
|
|
3204
3345
|
{
|
|
3205
3346
|
type: "button",
|
|
3206
3347
|
className: sortButtonClass,
|
|
3207
3348
|
onClick: () => setSort(nextSort(sort, col.id)),
|
|
3208
3349
|
children: [
|
|
3209
|
-
/* @__PURE__ */
|
|
3210
|
-
/* @__PURE__ */
|
|
3350
|
+
/* @__PURE__ */ jsx44("span", { className: "truncate", children: col.header }),
|
|
3351
|
+
/* @__PURE__ */ jsx44(SortIndicator, { active: Boolean(isSorted), direction: sort?.direction })
|
|
3211
3352
|
]
|
|
3212
3353
|
}
|
|
3213
3354
|
) : col.header;
|
|
3214
|
-
return /* @__PURE__ */
|
|
3355
|
+
return /* @__PURE__ */ jsx44(
|
|
3215
3356
|
"th",
|
|
3216
3357
|
{
|
|
3217
3358
|
scope: "col",
|
|
@@ -3228,9 +3369,9 @@ function DataTable({
|
|
|
3228
3369
|
);
|
|
3229
3370
|
})
|
|
3230
3371
|
] }) }),
|
|
3231
|
-
/* @__PURE__ */
|
|
3232
|
-
selectable ? /* @__PURE__ */
|
|
3233
|
-
columns.map((col) => /* @__PURE__ */
|
|
3372
|
+
/* @__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: [
|
|
3373
|
+
selectable ? /* @__PURE__ */ jsx44("td", { className: cn(selectCellClass, cellPad), children: /* @__PURE__ */ jsx44(Skeleton, { className: "size-4 rounded-[4px]" }) }) : null,
|
|
3374
|
+
columns.map((col) => /* @__PURE__ */ jsx44(
|
|
3234
3375
|
"td",
|
|
3235
3376
|
{
|
|
3236
3377
|
className: cn(
|
|
@@ -3239,17 +3380,17 @@ function DataTable({
|
|
|
3239
3380
|
col.align && alignClass[col.align],
|
|
3240
3381
|
col.className
|
|
3241
3382
|
),
|
|
3242
|
-
children: /* @__PURE__ */
|
|
3383
|
+
children: /* @__PURE__ */ jsx44(Skeleton, { className: "h-4 w-[60%]" })
|
|
3243
3384
|
},
|
|
3244
3385
|
col.id
|
|
3245
3386
|
))
|
|
3246
|
-
] }, `skeleton-${rowIdx}`)) : visibleRows.length === 0 ? /* @__PURE__ */
|
|
3247
|
-
/* @__PURE__ */
|
|
3248
|
-
emptyDescription ? /* @__PURE__ */
|
|
3387
|
+
] }, `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: [
|
|
3388
|
+
/* @__PURE__ */ jsx44("p", { className: "font-medium text-foreground", children: emptyTitle }),
|
|
3389
|
+
emptyDescription ? /* @__PURE__ */ jsx44("p", { className: "max-w-sm text-muted-foreground", children: emptyDescription }) : null
|
|
3249
3390
|
] }) }) }) : visibleRows.map((row) => {
|
|
3250
3391
|
const key = getRowKey(row);
|
|
3251
3392
|
const isSelected = selectedSet.has(key);
|
|
3252
|
-
return /* @__PURE__ */
|
|
3393
|
+
return /* @__PURE__ */ jsxs34(
|
|
3253
3394
|
"tr",
|
|
3254
3395
|
{
|
|
3255
3396
|
className: rowClass,
|
|
@@ -3265,12 +3406,12 @@ function DataTable({
|
|
|
3265
3406
|
tabIndex: onRowClick ? 0 : void 0,
|
|
3266
3407
|
role: onRowClick ? "button" : void 0,
|
|
3267
3408
|
children: [
|
|
3268
|
-
selectable ? /* @__PURE__ */
|
|
3409
|
+
selectable ? /* @__PURE__ */ jsx44(
|
|
3269
3410
|
"td",
|
|
3270
3411
|
{
|
|
3271
3412
|
className: cn(selectCellClass, cellPad),
|
|
3272
3413
|
onClick: (event) => event.stopPropagation(),
|
|
3273
|
-
children: /* @__PURE__ */
|
|
3414
|
+
children: /* @__PURE__ */ jsx44(
|
|
3274
3415
|
Checkbox,
|
|
3275
3416
|
{
|
|
3276
3417
|
checked: isSelected,
|
|
@@ -3280,7 +3421,7 @@ function DataTable({
|
|
|
3280
3421
|
)
|
|
3281
3422
|
}
|
|
3282
3423
|
) : null,
|
|
3283
|
-
columns.map((col) => /* @__PURE__ */
|
|
3424
|
+
columns.map((col) => /* @__PURE__ */ jsx44(
|
|
3284
3425
|
"td",
|
|
3285
3426
|
{
|
|
3286
3427
|
className: cn(
|
|
@@ -3290,7 +3431,7 @@ function DataTable({
|
|
|
3290
3431
|
col.align && alignClass[col.align],
|
|
3291
3432
|
col.className
|
|
3292
3433
|
),
|
|
3293
|
-
children: col.truncate ? /* @__PURE__ */
|
|
3434
|
+
children: col.truncate ? /* @__PURE__ */ jsx44("div", { className: "truncate", children: col.cell(row) }) : col.cell(row)
|
|
3294
3435
|
},
|
|
3295
3436
|
col.id
|
|
3296
3437
|
))
|
|
@@ -3299,7 +3440,7 @@ function DataTable({
|
|
|
3299
3440
|
key
|
|
3300
3441
|
);
|
|
3301
3442
|
}) }),
|
|
3302
|
-
hasFoot ? /* @__PURE__ */
|
|
3443
|
+
hasFoot ? /* @__PURE__ */ jsx44("tfoot", { children: /* @__PURE__ */ jsx44("tr", { children: /* @__PURE__ */ jsx44("td", { colSpan, className: footCellClass, children: /* @__PURE__ */ jsxs34(
|
|
3303
3444
|
"div",
|
|
3304
3445
|
{
|
|
3305
3446
|
className: cn(
|
|
@@ -3307,18 +3448,18 @@ function DataTable({
|
|
|
3307
3448
|
(showRowCount || footer || hasPager) && "justify-between"
|
|
3308
3449
|
),
|
|
3309
3450
|
children: [
|
|
3310
|
-
/* @__PURE__ */
|
|
3311
|
-
showRowCount ? /* @__PURE__ */
|
|
3451
|
+
/* @__PURE__ */ jsxs34("div", { className: footInnerClass, children: [
|
|
3452
|
+
showRowCount ? /* @__PURE__ */ jsxs34("span", { children: [
|
|
3312
3453
|
rowCountText,
|
|
3313
3454
|
selectable && selectedSet.size > 0 ? ` \xB7 ${selectedSet.size} selected` : null
|
|
3314
|
-
] }) : selectable && selectedSet.size > 0 ? /* @__PURE__ */
|
|
3455
|
+
] }) : selectable && selectedSet.size > 0 ? /* @__PURE__ */ jsxs34("span", { children: [
|
|
3315
3456
|
selectedSet.size,
|
|
3316
3457
|
" selected"
|
|
3317
3458
|
] }) : null,
|
|
3318
3459
|
footer
|
|
3319
3460
|
] }),
|
|
3320
|
-
hasPager ? /* @__PURE__ */
|
|
3321
|
-
/* @__PURE__ */
|
|
3461
|
+
hasPager ? /* @__PURE__ */ jsxs34("div", { className: "flex items-center gap-2", children: [
|
|
3462
|
+
/* @__PURE__ */ jsxs34("span", { className: "tabular-nums", children: [
|
|
3322
3463
|
pageIndex * pageSize + 1,
|
|
3323
3464
|
"\u2013",
|
|
3324
3465
|
Math.min(
|
|
@@ -3329,8 +3470,8 @@ function DataTable({
|
|
|
3329
3470
|
"of ",
|
|
3330
3471
|
sortedRows.length
|
|
3331
3472
|
] }),
|
|
3332
|
-
/* @__PURE__ */
|
|
3333
|
-
/* @__PURE__ */
|
|
3473
|
+
/* @__PURE__ */ jsxs34("div", { className: "flex items-center gap-1", children: [
|
|
3474
|
+
/* @__PURE__ */ jsx44(
|
|
3334
3475
|
"button",
|
|
3335
3476
|
{
|
|
3336
3477
|
type: "button",
|
|
@@ -3338,10 +3479,10 @@ function DataTable({
|
|
|
3338
3479
|
onClick: () => setPage(pageIndex - 1),
|
|
3339
3480
|
disabled: pageIndex <= 0,
|
|
3340
3481
|
"aria-label": "Previous page",
|
|
3341
|
-
children: /* @__PURE__ */
|
|
3482
|
+
children: /* @__PURE__ */ jsx44(ChevronLeftIcon, { className: "size-4", "aria-hidden": true })
|
|
3342
3483
|
}
|
|
3343
3484
|
),
|
|
3344
|
-
/* @__PURE__ */
|
|
3485
|
+
/* @__PURE__ */ jsx44(
|
|
3345
3486
|
"button",
|
|
3346
3487
|
{
|
|
3347
3488
|
type: "button",
|
|
@@ -3349,7 +3490,7 @@ function DataTable({
|
|
|
3349
3490
|
onClick: () => setPage(pageIndex + 1),
|
|
3350
3491
|
disabled: pageIndex >= pageCount - 1,
|
|
3351
3492
|
"aria-label": "Next page",
|
|
3352
|
-
children: /* @__PURE__ */
|
|
3493
|
+
children: /* @__PURE__ */ jsx44(ChevronRightIcon, { className: "size-4", "aria-hidden": true })
|
|
3353
3494
|
}
|
|
3354
3495
|
)
|
|
3355
3496
|
] })
|
|
@@ -3361,29 +3502,33 @@ function DataTable({
|
|
|
3361
3502
|
}
|
|
3362
3503
|
|
|
3363
3504
|
// src/app/data/ChartPanel.tsx
|
|
3364
|
-
import { useId as
|
|
3365
|
-
import { jsx as
|
|
3505
|
+
import { useId as useId8 } from "react";
|
|
3506
|
+
import { jsx as jsx45, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
3366
3507
|
var ChartPanel = ({
|
|
3367
3508
|
title,
|
|
3368
3509
|
description,
|
|
3369
3510
|
artifact,
|
|
3370
3511
|
children,
|
|
3371
3512
|
actions,
|
|
3372
|
-
height
|
|
3513
|
+
height: heightProp,
|
|
3373
3514
|
loading = false,
|
|
3374
3515
|
className
|
|
3375
3516
|
}) => {
|
|
3376
|
-
const
|
|
3517
|
+
const density = useAppDensity();
|
|
3518
|
+
const height = heightProp ?? APP_DENSITY_CHART_HEIGHT[density];
|
|
3519
|
+
const metricChartPlotRegionClass = useAppDensityClass("metricChartPlotRegion");
|
|
3520
|
+
const chartPanelBodyClass = useAppDensityClass("chartPanelBody");
|
|
3521
|
+
const titleId = useId8();
|
|
3377
3522
|
const resolvedTitle = title ?? artifact?.title;
|
|
3378
3523
|
const hasHeader = Boolean(resolvedTitle || description || actions);
|
|
3379
|
-
const body = loading ? /* @__PURE__ */
|
|
3380
|
-
return /* @__PURE__ */
|
|
3524
|
+
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);
|
|
3525
|
+
return /* @__PURE__ */ jsxs35(
|
|
3381
3526
|
"section",
|
|
3382
3527
|
{
|
|
3383
3528
|
className: cn(metricCardShellClass, "aui-app-chart-panel", className),
|
|
3384
3529
|
"aria-labelledby": resolvedTitle ? titleId : void 0,
|
|
3385
3530
|
children: [
|
|
3386
|
-
/* @__PURE__ */
|
|
3531
|
+
/* @__PURE__ */ jsx45(
|
|
3387
3532
|
MetricCardHeader,
|
|
3388
3533
|
{
|
|
3389
3534
|
title: resolvedTitle,
|
|
@@ -3392,14 +3537,14 @@ var ChartPanel = ({
|
|
|
3392
3537
|
actions
|
|
3393
3538
|
}
|
|
3394
3539
|
),
|
|
3395
|
-
/* @__PURE__ */
|
|
3540
|
+
/* @__PURE__ */ jsx45(
|
|
3396
3541
|
"div",
|
|
3397
3542
|
{
|
|
3398
3543
|
className: cn(
|
|
3399
3544
|
"relative min-h-0 w-full",
|
|
3400
|
-
hasHeader ? metricChartPlotRegionClass :
|
|
3545
|
+
hasHeader ? metricChartPlotRegionClass : chartPanelBodyClass
|
|
3401
3546
|
),
|
|
3402
|
-
children: body ?? /* @__PURE__ */
|
|
3547
|
+
children: body ?? /* @__PURE__ */ jsx45(
|
|
3403
3548
|
"div",
|
|
3404
3549
|
{
|
|
3405
3550
|
className: "flex items-center justify-center text-sm font-normal text-muted-foreground",
|
|
@@ -3416,8 +3561,8 @@ var ChartPanel = ({
|
|
|
3416
3561
|
};
|
|
3417
3562
|
|
|
3418
3563
|
// src/app/data/MetricRow.tsx
|
|
3419
|
-
import { useId as
|
|
3420
|
-
import { jsx as
|
|
3564
|
+
import { useId as useId9, useState as useState5 } from "react";
|
|
3565
|
+
import { jsx as jsx46, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
3421
3566
|
var MetricRow = ({
|
|
3422
3567
|
title,
|
|
3423
3568
|
description,
|
|
@@ -3430,7 +3575,8 @@ var MetricRow = ({
|
|
|
3430
3575
|
loading = false,
|
|
3431
3576
|
className
|
|
3432
3577
|
}) => {
|
|
3433
|
-
const
|
|
3578
|
+
const metricTileClass = useAppDensityClass("metricTile");
|
|
3579
|
+
const titleId = useId9();
|
|
3434
3580
|
const selectable = onMetricChange != null || activeMetricId != null;
|
|
3435
3581
|
const [internalId, setInternalId] = useState5(
|
|
3436
3582
|
defaultActiveMetricId ?? metrics[0]?.id
|
|
@@ -3440,13 +3586,13 @@ var MetricRow = ({
|
|
|
3440
3586
|
if (activeMetricId == null) setInternalId(id);
|
|
3441
3587
|
onMetricChange?.(id);
|
|
3442
3588
|
};
|
|
3443
|
-
return /* @__PURE__ */
|
|
3589
|
+
return /* @__PURE__ */ jsxs36(
|
|
3444
3590
|
"section",
|
|
3445
3591
|
{
|
|
3446
3592
|
className: cn(metricCardShellClass, className),
|
|
3447
3593
|
"aria-labelledby": title ? titleId : void 0,
|
|
3448
3594
|
children: [
|
|
3449
|
-
/* @__PURE__ */
|
|
3595
|
+
/* @__PURE__ */ jsx46(
|
|
3450
3596
|
MetricCardHeader,
|
|
3451
3597
|
{
|
|
3452
3598
|
title,
|
|
@@ -3455,7 +3601,7 @@ var MetricRow = ({
|
|
|
3455
3601
|
actions
|
|
3456
3602
|
}
|
|
3457
3603
|
),
|
|
3458
|
-
/* @__PURE__ */
|
|
3604
|
+
/* @__PURE__ */ jsx46(
|
|
3459
3605
|
"div",
|
|
3460
3606
|
{
|
|
3461
3607
|
role: selectable ? "group" : void 0,
|
|
@@ -3466,18 +3612,18 @@ var MetricRow = ({
|
|
|
3466
3612
|
metricTilesGridColsClass(loading ? metrics.length || 4 : metrics.length),
|
|
3467
3613
|
(title || description || actions) && "mt-3"
|
|
3468
3614
|
),
|
|
3469
|
-
children: loading ? Array.from({ length: metrics.length || 4 }).map((_, index) => /* @__PURE__ */
|
|
3615
|
+
children: loading ? Array.from({ length: metrics.length || 4 }).map((_, index) => /* @__PURE__ */ jsxs36(
|
|
3470
3616
|
"div",
|
|
3471
3617
|
{
|
|
3472
|
-
className: "flex min-w-0 flex-1 flex-col gap-2
|
|
3618
|
+
className: cn("flex min-w-0 flex-1 flex-col gap-2", metricTileClass),
|
|
3473
3619
|
"aria-hidden": true,
|
|
3474
3620
|
children: [
|
|
3475
|
-
/* @__PURE__ */
|
|
3476
|
-
/* @__PURE__ */
|
|
3621
|
+
/* @__PURE__ */ jsx46(Skeleton, { className: "h-3 w-20" }),
|
|
3622
|
+
/* @__PURE__ */ jsx46(Skeleton, { className: "h-7 w-24" })
|
|
3477
3623
|
]
|
|
3478
3624
|
},
|
|
3479
3625
|
`skeleton-${index}`
|
|
3480
|
-
)) : metrics.map((m, index) => /* @__PURE__ */
|
|
3626
|
+
)) : metrics.map((m, index) => /* @__PURE__ */ jsx46(
|
|
3481
3627
|
MetricTile,
|
|
3482
3628
|
{
|
|
3483
3629
|
label: m.label,
|
|
@@ -3499,8 +3645,8 @@ var MetricRow = ({
|
|
|
3499
3645
|
};
|
|
3500
3646
|
|
|
3501
3647
|
// src/app/data/MetricChartCard.tsx
|
|
3502
|
-
import { useId as
|
|
3503
|
-
import { jsx as
|
|
3648
|
+
import { useId as useId10, useState as useState6 } from "react";
|
|
3649
|
+
import { jsx as jsx47, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
3504
3650
|
var MetricChartCard = ({
|
|
3505
3651
|
title,
|
|
3506
3652
|
description,
|
|
@@ -3511,7 +3657,7 @@ var MetricChartCard = ({
|
|
|
3511
3657
|
onMetricChange,
|
|
3512
3658
|
xKey = "date",
|
|
3513
3659
|
variant = "area",
|
|
3514
|
-
height
|
|
3660
|
+
height: heightProp,
|
|
3515
3661
|
formatX,
|
|
3516
3662
|
formatValue,
|
|
3517
3663
|
emptyLabel = "No data yet",
|
|
@@ -3519,7 +3665,11 @@ var MetricChartCard = ({
|
|
|
3519
3665
|
loading = false,
|
|
3520
3666
|
className
|
|
3521
3667
|
}) => {
|
|
3522
|
-
const
|
|
3668
|
+
const density = useAppDensity();
|
|
3669
|
+
const height = heightProp ?? APP_DENSITY_CHART_HEIGHT[density];
|
|
3670
|
+
const metricChartRegionClass = useAppDensityClass("metricChartRegion");
|
|
3671
|
+
const metricTileClass = useAppDensityClass("metricTile");
|
|
3672
|
+
const titleId = useId10();
|
|
3523
3673
|
const [internalId, setInternalId] = useState6(
|
|
3524
3674
|
defaultActiveMetricId ?? metrics[0]?.id
|
|
3525
3675
|
);
|
|
@@ -3531,13 +3681,13 @@ var MetricChartCard = ({
|
|
|
3531
3681
|
};
|
|
3532
3682
|
const hasHeader = Boolean(title || description || actions);
|
|
3533
3683
|
const chartAriaLabel = typeof active?.label === "string" ? `${active.label} over time` : "Metric chart";
|
|
3534
|
-
return /* @__PURE__ */
|
|
3684
|
+
return /* @__PURE__ */ jsxs37(
|
|
3535
3685
|
"section",
|
|
3536
3686
|
{
|
|
3537
3687
|
className: cn(metricCardShellClass, className),
|
|
3538
3688
|
"aria-labelledby": title ? titleId : void 0,
|
|
3539
3689
|
children: [
|
|
3540
|
-
/* @__PURE__ */
|
|
3690
|
+
/* @__PURE__ */ jsx47(
|
|
3541
3691
|
MetricCardHeader,
|
|
3542
3692
|
{
|
|
3543
3693
|
title,
|
|
@@ -3546,7 +3696,7 @@ var MetricChartCard = ({
|
|
|
3546
3696
|
actions
|
|
3547
3697
|
}
|
|
3548
3698
|
),
|
|
3549
|
-
/* @__PURE__ */
|
|
3699
|
+
/* @__PURE__ */ jsx47(
|
|
3550
3700
|
"div",
|
|
3551
3701
|
{
|
|
3552
3702
|
role: "group",
|
|
@@ -3557,18 +3707,18 @@ var MetricChartCard = ({
|
|
|
3557
3707
|
metricTilesGridColsClass(loading ? metrics.length || 4 : metrics.length),
|
|
3558
3708
|
hasHeader && "mt-3"
|
|
3559
3709
|
),
|
|
3560
|
-
children: loading ? Array.from({ length: metrics.length || 4 }).map((_, index) => /* @__PURE__ */
|
|
3710
|
+
children: loading ? Array.from({ length: metrics.length || 4 }).map((_, index) => /* @__PURE__ */ jsxs37(
|
|
3561
3711
|
"div",
|
|
3562
3712
|
{
|
|
3563
|
-
className: "flex min-w-0 flex-1 flex-col gap-2
|
|
3713
|
+
className: cn("flex min-w-0 flex-1 flex-col gap-2", metricTileClass),
|
|
3564
3714
|
"aria-hidden": true,
|
|
3565
3715
|
children: [
|
|
3566
|
-
/* @__PURE__ */
|
|
3567
|
-
/* @__PURE__ */
|
|
3716
|
+
/* @__PURE__ */ jsx47(Skeleton, { className: "h-3 w-20" }),
|
|
3717
|
+
/* @__PURE__ */ jsx47(Skeleton, { className: "h-7 w-24" })
|
|
3568
3718
|
]
|
|
3569
3719
|
},
|
|
3570
3720
|
`skeleton-${index}`
|
|
3571
|
-
)) : metrics.map((m, index) => /* @__PURE__ */
|
|
3721
|
+
)) : metrics.map((m, index) => /* @__PURE__ */ jsx47(
|
|
3572
3722
|
MetricTile,
|
|
3573
3723
|
{
|
|
3574
3724
|
label: m.label,
|
|
@@ -3584,14 +3734,14 @@ var MetricChartCard = ({
|
|
|
3584
3734
|
))
|
|
3585
3735
|
}
|
|
3586
3736
|
),
|
|
3587
|
-
/* @__PURE__ */
|
|
3737
|
+
/* @__PURE__ */ jsx47("div", { className: metricChartRegionClass, "aria-live": "polite", "aria-atomic": "true", children: loading ? /* @__PURE__ */ jsx47(
|
|
3588
3738
|
Skeleton,
|
|
3589
3739
|
{
|
|
3590
3740
|
className: "w-full rounded-lg",
|
|
3591
3741
|
style: { height },
|
|
3592
3742
|
"aria-hidden": true
|
|
3593
3743
|
}
|
|
3594
|
-
) : active?.data && active.data.length > 0 ? /* @__PURE__ */
|
|
3744
|
+
) : active?.data && active.data.length > 0 ? /* @__PURE__ */ jsx47(
|
|
3595
3745
|
LineAreaChart,
|
|
3596
3746
|
{
|
|
3597
3747
|
data: active.data,
|
|
@@ -3611,7 +3761,7 @@ var MetricChartCard = ({
|
|
|
3611
3761
|
ariaLabel: chartAriaLabel
|
|
3612
3762
|
},
|
|
3613
3763
|
active.id
|
|
3614
|
-
) : /* @__PURE__ */
|
|
3764
|
+
) : /* @__PURE__ */ jsx47(
|
|
3615
3765
|
"div",
|
|
3616
3766
|
{
|
|
3617
3767
|
className: "flex w-full items-center justify-center text-sm font-normal text-muted-foreground",
|
|
@@ -3716,8 +3866,8 @@ function useLiveQuery(fetcher, options = {}) {
|
|
|
3716
3866
|
}
|
|
3717
3867
|
|
|
3718
3868
|
// src/charts/sparkline.tsx
|
|
3719
|
-
import { useId as
|
|
3720
|
-
import { Fragment as Fragment6, jsx as
|
|
3869
|
+
import { useId as useId11 } from "react";
|
|
3870
|
+
import { Fragment as Fragment6, jsx as jsx48, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
3721
3871
|
var Sparkline = ({
|
|
3722
3872
|
data,
|
|
3723
3873
|
dataKey = "value",
|
|
@@ -3729,10 +3879,10 @@ var Sparkline = ({
|
|
|
3729
3879
|
className,
|
|
3730
3880
|
ariaLabel = "Trend"
|
|
3731
3881
|
}) => {
|
|
3732
|
-
const uid =
|
|
3882
|
+
const uid = useId11();
|
|
3733
3883
|
const values = data.map((d) => typeof d === "number" ? d : toNum(d[dataKey]));
|
|
3734
3884
|
if (values.length === 0) {
|
|
3735
|
-
return /* @__PURE__ */
|
|
3885
|
+
return /* @__PURE__ */ jsx48("span", { className: cn("inline-block", className), style: { width, height } });
|
|
3736
3886
|
}
|
|
3737
3887
|
const pad = strokeWidth + 1;
|
|
3738
3888
|
const min = Math.min(...values);
|
|
@@ -3744,7 +3894,7 @@ var Sparkline = ({
|
|
|
3744
3894
|
x: pad + (values.length > 1 ? i / (values.length - 1) * innerW : innerW / 2),
|
|
3745
3895
|
y: pad + innerH - (v - min) / range * innerH
|
|
3746
3896
|
}));
|
|
3747
|
-
return /* @__PURE__ */
|
|
3897
|
+
return /* @__PURE__ */ jsxs38(
|
|
3748
3898
|
"svg",
|
|
3749
3899
|
{
|
|
3750
3900
|
width,
|
|
@@ -3755,14 +3905,14 @@ var Sparkline = ({
|
|
|
3755
3905
|
"aria-label": ariaLabel,
|
|
3756
3906
|
preserveAspectRatio: "none",
|
|
3757
3907
|
children: [
|
|
3758
|
-
area && /* @__PURE__ */
|
|
3759
|
-
/* @__PURE__ */
|
|
3760
|
-
/* @__PURE__ */
|
|
3761
|
-
/* @__PURE__ */
|
|
3908
|
+
area && /* @__PURE__ */ jsxs38(Fragment6, { children: [
|
|
3909
|
+
/* @__PURE__ */ jsx48("defs", { children: /* @__PURE__ */ jsxs38("linearGradient", { id: `${uid}-spark`, x1: "0", x2: "0", y1: "0", y2: "1", children: [
|
|
3910
|
+
/* @__PURE__ */ jsx48("stop", { offset: "0%", style: { stopColor: color, stopOpacity: 0.25 } }),
|
|
3911
|
+
/* @__PURE__ */ jsx48("stop", { offset: "100%", style: { stopColor: color, stopOpacity: 0 } })
|
|
3762
3912
|
] }) }),
|
|
3763
|
-
/* @__PURE__ */
|
|
3913
|
+
/* @__PURE__ */ jsx48("path", { d: monotoneAreaPath(points, height - pad), fill: `url(#${uid}-spark)` })
|
|
3764
3914
|
] }),
|
|
3765
|
-
/* @__PURE__ */
|
|
3915
|
+
/* @__PURE__ */ jsx48(
|
|
3766
3916
|
"path",
|
|
3767
3917
|
{
|
|
3768
3918
|
d: monotoneLinePath(points),
|
|
@@ -3801,8 +3951,6 @@ export {
|
|
|
3801
3951
|
getStoredThemePreset,
|
|
3802
3952
|
THEME_AGENT_INSTRUCTIONS,
|
|
3803
3953
|
TimbalThemeStyle,
|
|
3804
|
-
MetricTile,
|
|
3805
|
-
ThemePresetGallery,
|
|
3806
3954
|
appPageColumnClass,
|
|
3807
3955
|
appShellTopbarInsetClass,
|
|
3808
3956
|
appShellInsetTopClass,
|
|
@@ -3810,6 +3958,13 @@ export {
|
|
|
3810
3958
|
appStatTileClass,
|
|
3811
3959
|
appFilterBarClass,
|
|
3812
3960
|
appSearchInputClass,
|
|
3961
|
+
APP_DENSITY_CHART_HEIGHT,
|
|
3962
|
+
APP_DENSITY_CLASSES,
|
|
3963
|
+
appDensityClass,
|
|
3964
|
+
AppDensityProvider,
|
|
3965
|
+
useAppDensity,
|
|
3966
|
+
useAppDensityClass,
|
|
3967
|
+
MetricTile,
|
|
3813
3968
|
useAppShellChat,
|
|
3814
3969
|
useAppShellNav,
|
|
3815
3970
|
AppShell,
|