@timbal-ai/timbal-react 0.8.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +51 -5
- package/dist/app.cjs +1750 -1157
- package/dist/app.d.cts +2 -2
- package/dist/app.d.ts +2 -2
- package/dist/app.esm.js +27 -5
- package/dist/{button-CIKzUrJI.d.cts → button-ClSgD6OF.d.cts} +1 -1
- package/dist/{button-CIKzUrJI.d.ts → button-ClSgD6OF.d.ts} +1 -1
- package/dist/{chart-artifact-C2m891nx.d.cts → chart-artifact-DWkqIAK5.d.cts} +165 -1
- package/dist/{chart-artifact-CqqhdSR9.d.ts → chart-artifact-DwfRtQWL.d.ts} +165 -1
- package/dist/chat.esm.js +3 -3
- package/dist/{chunk-VVTTLIGT.esm.js → chunk-5ZKLPWVN.esm.js} +1 -1
- package/dist/{chunk-ZG5NBHOS.esm.js → chunk-CFU3YDTV.esm.js} +2 -2
- package/dist/{chunk-ZEDE2TWQ.esm.js → chunk-GBBLAM3G.esm.js} +954 -378
- package/dist/{chunk-YNDXBN6C.esm.js → chunk-OISVICYF.esm.js} +1 -1
- package/dist/{chunk-LSEUKTU5.esm.js → chunk-P4SN7M67.esm.js} +1 -1
- package/dist/{chunk-Z27GBSOT.esm.js → chunk-QIABF4KB.esm.js} +53 -51
- package/dist/{chunk-QKO67F4V.esm.js → chunk-QVAUCVQA.esm.js} +93 -93
- package/dist/{chunk-4AO3HCAR.esm.js → chunk-VWHHKAHN.esm.js} +5 -5
- package/dist/index.cjs +1006 -418
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.esm.js +30 -8
- package/dist/studio.cjs +3 -1
- package/dist/studio.esm.js +6 -6
- package/dist/ui.d.cts +1 -1
- package/dist/ui.d.ts +1 -1
- package/dist/ui.esm.js +3 -3
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -149,8 +149,11 @@ __export(index_exports, {
|
|
|
149
149
|
SubNav: () => SubNav,
|
|
150
150
|
Suggestions: () => Suggestions,
|
|
151
151
|
SurfaceCard: () => SurfaceCard,
|
|
152
|
+
THEME_AGENT_INSTRUCTIONS: () => THEME_AGENT_INSTRUCTIONS,
|
|
152
153
|
THREAD_DEFAULT_MAX_WIDTH: () => THREAD_DEFAULT_MAX_WIDTH,
|
|
154
|
+
TIMBAL_THEME_PRESETS: () => TIMBAL_THEME_PRESETS,
|
|
153
155
|
TableArtifactView: () => TableArtifactView,
|
|
156
|
+
ThemePresetGallery: () => ThemePresetGallery,
|
|
154
157
|
Thread: () => Thread,
|
|
155
158
|
ThreadPrimitive: () => import_react69.ThreadPrimitive,
|
|
156
159
|
TimbalChat: () => TimbalChat,
|
|
@@ -158,6 +161,7 @@ __export(index_exports, {
|
|
|
158
161
|
TimbalMark: () => TimbalMark,
|
|
159
162
|
TimbalRuntimeProvider: () => TimbalRuntimeProvider,
|
|
160
163
|
TimbalStudioShell: () => TimbalStudioShell,
|
|
164
|
+
TimbalThemeStyle: () => TimbalThemeStyle,
|
|
161
165
|
ToolArtifactFallback: () => ToolArtifactFallback,
|
|
162
166
|
ToolFallback: () => ToolFallback,
|
|
163
167
|
Tooltip: () => Tooltip,
|
|
@@ -170,13 +174,17 @@ __export(index_exports, {
|
|
|
170
174
|
UiEventProvider: () => UiEventProvider,
|
|
171
175
|
UiNodeView: () => UiNodeView,
|
|
172
176
|
WorkforceSelector: () => WorkforceSelector,
|
|
177
|
+
applyThemePreset: () => applyThemePreset,
|
|
178
|
+
applyTimbalTheme: () => applyTimbalTheme,
|
|
173
179
|
assistantMessageContentClass: () => assistantMessageContentClass,
|
|
174
180
|
assistantMessageRootClass: () => assistantMessageRootClass,
|
|
175
181
|
authFetch: () => authFetch,
|
|
182
|
+
clearTimbalTheme: () => clearTimbalTheme,
|
|
176
183
|
clearTokens: () => clearTokens,
|
|
177
184
|
cn: () => cn,
|
|
178
185
|
connectionRowListClass: () => connectionRowListClass,
|
|
179
186
|
createDefaultAttachmentAdapter: () => createDefaultAttachmentAdapter,
|
|
187
|
+
createTimbalTheme: () => createTimbalTheme,
|
|
180
188
|
createUploadAttachmentAdapter: () => createUploadAttachmentAdapter,
|
|
181
189
|
defaultArtifactRenderers: () => defaultArtifactRenderers,
|
|
182
190
|
fetchCurrentUser: () => fetchCurrentUser,
|
|
@@ -184,6 +192,8 @@ __export(index_exports, {
|
|
|
184
192
|
getAccessToken: () => getAccessToken,
|
|
185
193
|
getPath: () => getPath,
|
|
186
194
|
getRefreshToken: () => getRefreshToken,
|
|
195
|
+
getStoredThemePreset: () => getStoredThemePreset,
|
|
196
|
+
getThemePreset: () => getThemePreset,
|
|
187
197
|
isArtifact: () => isArtifact,
|
|
188
198
|
isArtifactFenceLanguage: () => isArtifactFenceLanguage,
|
|
189
199
|
isUiBinding: () => isUiBinding,
|
|
@@ -196,6 +206,7 @@ __export(index_exports, {
|
|
|
196
206
|
setPath: () => setPath,
|
|
197
207
|
setRefreshToken: () => setRefreshToken,
|
|
198
208
|
splitMarkdownByArtifacts: () => splitMarkdownByArtifacts,
|
|
209
|
+
themeToCss: () => themeToCss,
|
|
199
210
|
threadMessageColumnClass: () => threadMessageColumnClass,
|
|
200
211
|
useAppCopilotContext: () => useAppCopilotContext,
|
|
201
212
|
useAppShellChat: () => useAppShellChat,
|
|
@@ -4805,7 +4816,9 @@ var studioChromeShellStyle = {
|
|
|
4805
4816
|
var STORAGE_KEYS = {
|
|
4806
4817
|
sidebarCollapsed: "timbal-studio-sidebar-collapsed",
|
|
4807
4818
|
/** Used by `ModeToggle` in uncontrolled mode (`localStorage`). */
|
|
4808
|
-
theme: "timbal-theme"
|
|
4819
|
+
theme: "timbal-theme",
|
|
4820
|
+
/** Used by the theme preset picker to remember the selected brand preset. */
|
|
4821
|
+
themePreset: "timbal-theme-preset"
|
|
4809
4822
|
};
|
|
4810
4823
|
var DOM_IDS = {
|
|
4811
4824
|
sidebarRuntimeAnchor: "timbal-studio-sidebar-runtime-anchor",
|
|
@@ -6495,6 +6508,8 @@ Presentational groups \u2014 import from the package root, not from these paths:
|
|
|
6495
6508
|
|
|
6496
6509
|
Also re-exported: \`Button\`, \`TimbalChat\`, \`ChartArtifactView\`, \`APP_KIT_AGENT_INSTRUCTIONS\`.
|
|
6497
6510
|
|
|
6511
|
+
Theming helpers (import from the package root or \`/app\`): \`createTimbalTheme\`, \`themeToCss\`, \`applyTimbalTheme\`, \`TIMBAL_THEME_PRESETS\`, \`applyThemePreset\`, \`ThemePresetGallery\`, \`TimbalThemeStyle\`, \`THEME_AGENT_INSTRUCTIONS\`.
|
|
6512
|
+
|
|
6498
6513
|
### Design guidelines (required)
|
|
6499
6514
|
|
|
6500
6515
|
| Area | Rule |
|
|
@@ -6502,7 +6517,7 @@ Also re-exported: \`Button\`, \`TimbalChat\`, \`ChartArtifactView\`, \`APP_KIT_A
|
|
|
6502
6517
|
| **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. |
|
|
6503
6518
|
| **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. |
|
|
6504
6519
|
| **Context** | Do not show raw JSON context in the panel header; keep context in \`AppCopilotProvider\` only. |
|
|
6505
|
-
| **Theming** | Use semantic Tailwind tokens (\`bg-background\`, \`text-foreground\`, \`border-border\`, \`bg-elevated-from\`, etc.) from the host app's \`styles.css\`.
|
|
6520
|
+
| **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\`). To offer styles, render \`ThemePresetGallery\`. See \`THEME_AGENT_INSTRUCTIONS\`. |
|
|
6506
6521
|
| **Layout chrome** | \`Page\` \u2192 \`Section\` for main content hierarchy. \`AppShellTopbar\` for global actions (auth, theme). |
|
|
6507
6522
|
| **Data** | Prefer \`DataTable\` with typed \`columns\` / \`rows\` / \`getRowKey\`; use \`ChartPanel\` with \`ChartArtifact\` for charts. |
|
|
6508
6523
|
| **Modals** | Use \`AppConfirmDialog\` for destructive/export confirmations. |
|
|
@@ -6602,6 +6617,7 @@ Studio chrome (\`StudioSidebar\`, \`ModeToggle\`, \u2026) lives in \`@timbal-ai/
|
|
|
6602
6617
|
| \`resource-gallery.tsx\` | \`ResourceCard\`, \`StatusDot\`, \`Sparkline\` |
|
|
6603
6618
|
| \`charts-panel.tsx\` | \`ChartPanel\`, \`ChartArtifact\` |
|
|
6604
6619
|
| \`copilot-overlay.tsx\` | \`AppShell\`, \`AppChatPanel\` |
|
|
6620
|
+
| \`theme-presets.tsx\` | \`ThemePresetGallery\`, \`applyTimbalTheme\` |
|
|
6605
6621
|
|
|
6606
6622
|
### Typical compositions
|
|
6607
6623
|
|
|
@@ -6647,6 +6663,681 @@ import {
|
|
|
6647
6663
|
- For rich in-chat widgets, use **artifacts** (\`ARTIFACT_AGENT_INSTRUCTIONS\`) \u2014 app kit is for the **host application shell**.
|
|
6648
6664
|
`.trim();
|
|
6649
6665
|
|
|
6666
|
+
// src/design/oklch.ts
|
|
6667
|
+
var clamp = (n, min, max) => Math.min(max, Math.max(min, n));
|
|
6668
|
+
var round2 = (n, digits) => {
|
|
6669
|
+
const f = 10 ** digits;
|
|
6670
|
+
return Math.round(n * f) / f;
|
|
6671
|
+
};
|
|
6672
|
+
function srgbToLinear(channel) {
|
|
6673
|
+
const c = channel / 255;
|
|
6674
|
+
return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
|
|
6675
|
+
}
|
|
6676
|
+
function linearRgbToOklch(r, g, b, alpha) {
|
|
6677
|
+
const l = 0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b;
|
|
6678
|
+
const m = 0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b;
|
|
6679
|
+
const s = 0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b;
|
|
6680
|
+
const l_ = Math.cbrt(l);
|
|
6681
|
+
const m_ = Math.cbrt(m);
|
|
6682
|
+
const s_ = Math.cbrt(s);
|
|
6683
|
+
const labL = 0.2104542553 * l_ + 0.793617785 * m_ - 0.0040720468 * s_;
|
|
6684
|
+
const labA = 1.9779984951 * l_ - 2.428592205 * m_ + 0.4505937099 * s_;
|
|
6685
|
+
const labB = 0.0259040371 * l_ + 0.7827717662 * m_ - 0.808675766 * s_;
|
|
6686
|
+
const c = Math.sqrt(labA * labA + labB * labB);
|
|
6687
|
+
let h = Math.atan2(labB, labA) * 180 / Math.PI;
|
|
6688
|
+
if (h < 0) h += 360;
|
|
6689
|
+
return { l: labL, c, h, alpha };
|
|
6690
|
+
}
|
|
6691
|
+
function oklchToLinearRgb(color) {
|
|
6692
|
+
const hRad = color.h * Math.PI / 180;
|
|
6693
|
+
const labA = color.c * Math.cos(hRad);
|
|
6694
|
+
const labB = color.c * Math.sin(hRad);
|
|
6695
|
+
const l_ = color.l + 0.3963377774 * labA + 0.2158037573 * labB;
|
|
6696
|
+
const m_ = color.l - 0.1055613458 * labA - 0.0638541728 * labB;
|
|
6697
|
+
const s_ = color.l - 0.0894841775 * labA - 1.291485548 * labB;
|
|
6698
|
+
const l = l_ ** 3;
|
|
6699
|
+
const m = m_ ** 3;
|
|
6700
|
+
const s = s_ ** 3;
|
|
6701
|
+
return {
|
|
6702
|
+
r: 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
|
|
6703
|
+
g: -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
|
|
6704
|
+
b: -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s
|
|
6705
|
+
};
|
|
6706
|
+
}
|
|
6707
|
+
function parseHex(value) {
|
|
6708
|
+
let hex = value.trim().replace(/^#/, "");
|
|
6709
|
+
if (![3, 4, 6, 8].includes(hex.length)) return null;
|
|
6710
|
+
if (hex.length === 3 || hex.length === 4) {
|
|
6711
|
+
hex = hex.split("").map((ch) => ch + ch).join("");
|
|
6712
|
+
}
|
|
6713
|
+
const int = Number.parseInt(hex, 16);
|
|
6714
|
+
if (Number.isNaN(int)) return null;
|
|
6715
|
+
const hasAlpha = hex.length === 8;
|
|
6716
|
+
const r = int >>> (hasAlpha ? 24 : 16) & 255;
|
|
6717
|
+
const g = int >>> (hasAlpha ? 16 : 8) & 255;
|
|
6718
|
+
const b = int >>> (hasAlpha ? 8 : 0) & 255;
|
|
6719
|
+
const alpha = hasAlpha ? (int & 255) / 255 : 1;
|
|
6720
|
+
return linearRgbToOklch(
|
|
6721
|
+
srgbToLinear(r),
|
|
6722
|
+
srgbToLinear(g),
|
|
6723
|
+
srgbToLinear(b),
|
|
6724
|
+
alpha
|
|
6725
|
+
);
|
|
6726
|
+
}
|
|
6727
|
+
function parseRgb(value) {
|
|
6728
|
+
const match = value.match(
|
|
6729
|
+
/rgba?\(\s*([0-9.]+)[\s,]+([0-9.]+)[\s,]+([0-9.]+)(?:[\s,/]+([0-9.%]+))?\s*\)/i
|
|
6730
|
+
);
|
|
6731
|
+
if (!match) return null;
|
|
6732
|
+
const r = Number.parseFloat(match[1]);
|
|
6733
|
+
const g = Number.parseFloat(match[2]);
|
|
6734
|
+
const b = Number.parseFloat(match[3]);
|
|
6735
|
+
let alpha = 1;
|
|
6736
|
+
if (match[4]) {
|
|
6737
|
+
alpha = match[4].includes("%") ? Number.parseFloat(match[4]) / 100 : Number.parseFloat(match[4]);
|
|
6738
|
+
}
|
|
6739
|
+
if (![r, g, b].every(Number.isFinite)) return null;
|
|
6740
|
+
return linearRgbToOklch(
|
|
6741
|
+
srgbToLinear(r),
|
|
6742
|
+
srgbToLinear(g),
|
|
6743
|
+
srgbToLinear(b),
|
|
6744
|
+
Number.isFinite(alpha) ? alpha : 1
|
|
6745
|
+
);
|
|
6746
|
+
}
|
|
6747
|
+
function parseOklch(value) {
|
|
6748
|
+
const match = value.match(
|
|
6749
|
+
/oklch\(\s*([0-9.]+%?)\s+([0-9.]+%?)\s+([0-9.]+)(?:deg)?(?:\s*\/\s*([0-9.%]+))?\s*\)/i
|
|
6750
|
+
);
|
|
6751
|
+
if (!match) return null;
|
|
6752
|
+
const l = match[1].includes("%") ? Number.parseFloat(match[1]) / 100 : Number.parseFloat(match[1]);
|
|
6753
|
+
const c = match[2].includes("%") ? Number.parseFloat(match[2]) / 100 * 0.4 : Number.parseFloat(match[2]);
|
|
6754
|
+
const h = Number.parseFloat(match[3]);
|
|
6755
|
+
let alpha = 1;
|
|
6756
|
+
if (match[4]) {
|
|
6757
|
+
alpha = match[4].includes("%") ? Number.parseFloat(match[4]) / 100 : Number.parseFloat(match[4]);
|
|
6758
|
+
}
|
|
6759
|
+
if (![l, c, h].every(Number.isFinite)) return null;
|
|
6760
|
+
return { l, c, h, alpha: Number.isFinite(alpha) ? alpha : 1 };
|
|
6761
|
+
}
|
|
6762
|
+
function parseColor(value) {
|
|
6763
|
+
const parsed = parseOklch(value) ?? parseHex(value) ?? parseRgb(value);
|
|
6764
|
+
if (!parsed) {
|
|
6765
|
+
throw new Error(
|
|
6766
|
+
`[@timbal-ai/timbal-react] Could not parse color "${value}". Use a hex (#1E40AF), rgb()/rgba(), or oklch() string.`
|
|
6767
|
+
);
|
|
6768
|
+
}
|
|
6769
|
+
return parsed;
|
|
6770
|
+
}
|
|
6771
|
+
function lighten(color, delta) {
|
|
6772
|
+
return { ...color, l: clamp(color.l + delta, 0, 1) };
|
|
6773
|
+
}
|
|
6774
|
+
function scaleChroma(color, factor) {
|
|
6775
|
+
return { ...color, c: clamp(color.c * factor, 0, 0.4) };
|
|
6776
|
+
}
|
|
6777
|
+
function withAlpha(color, alpha) {
|
|
6778
|
+
return { ...color, alpha: clamp(alpha, 0, 1) };
|
|
6779
|
+
}
|
|
6780
|
+
function oklchToString(color) {
|
|
6781
|
+
const l = round2(clamp(color.l, 0, 1), 4);
|
|
6782
|
+
const c = round2(clamp(color.c, 0, 0.4), 4);
|
|
6783
|
+
const h = round2((color.h % 360 + 360) % 360, 2);
|
|
6784
|
+
const a = clamp(color.alpha, 0, 1);
|
|
6785
|
+
const base = `oklch(${l} ${c} ${h}`;
|
|
6786
|
+
return a >= 1 ? `${base})` : `${base} / ${round2(a, 3)})`;
|
|
6787
|
+
}
|
|
6788
|
+
function readableForeground(bg, options) {
|
|
6789
|
+
const threshold = options?.threshold ?? 0.62;
|
|
6790
|
+
const lightText = options?.light ?? "oklch(0.985 0 0)";
|
|
6791
|
+
const darkText = options?.dark ?? "oklch(0.205 0 0)";
|
|
6792
|
+
return bg.l >= threshold ? darkText : lightText;
|
|
6793
|
+
}
|
|
6794
|
+
function relativeLuminance(color) {
|
|
6795
|
+
const { r, g, b } = oklchToLinearRgb(color);
|
|
6796
|
+
const lr = clamp(r, 0, 1);
|
|
6797
|
+
const lg = clamp(g, 0, 1);
|
|
6798
|
+
const lb = clamp(b, 0, 1);
|
|
6799
|
+
return 0.2126 * lr + 0.7152 * lg + 0.0722 * lb;
|
|
6800
|
+
}
|
|
6801
|
+
|
|
6802
|
+
// src/design/theme.ts
|
|
6803
|
+
function primaryForMode(brand, mode) {
|
|
6804
|
+
if (mode === "light") {
|
|
6805
|
+
return { ...brand, l: Math.min(Math.max(brand.l, 0.42), 0.68) };
|
|
6806
|
+
}
|
|
6807
|
+
const lightened = lighten(brand, 0.06);
|
|
6808
|
+
return {
|
|
6809
|
+
...lightened,
|
|
6810
|
+
l: Math.min(Math.max(lightened.l, 0.5), 0.78),
|
|
6811
|
+
c: Math.min(brand.c, 0.22)
|
|
6812
|
+
};
|
|
6813
|
+
}
|
|
6814
|
+
function brandGradient(primary) {
|
|
6815
|
+
return {
|
|
6816
|
+
from: lighten(primary, 0.03),
|
|
6817
|
+
to: lighten(primary, -0.02),
|
|
6818
|
+
hoverFrom: lighten(primary, 0.06),
|
|
6819
|
+
hoverTo: lighten(primary, 0.01),
|
|
6820
|
+
activeFrom: lighten(primary, -0.02),
|
|
6821
|
+
activeTo: lighten(primary, -0.06)
|
|
6822
|
+
};
|
|
6823
|
+
}
|
|
6824
|
+
function neutralTints(brand) {
|
|
6825
|
+
return {
|
|
6826
|
+
lightHue: brand.h,
|
|
6827
|
+
darkHue: brand.h,
|
|
6828
|
+
lightChroma: 6e-3,
|
|
6829
|
+
darkChroma: 8e-3
|
|
6830
|
+
};
|
|
6831
|
+
}
|
|
6832
|
+
function createTimbalTheme(intent) {
|
|
6833
|
+
const brand = parseColor(intent.brand);
|
|
6834
|
+
const accent = intent.accent ? parseColor(intent.accent) : null;
|
|
6835
|
+
const light = {};
|
|
6836
|
+
const dark = {};
|
|
6837
|
+
const root = {};
|
|
6838
|
+
if (typeof intent.radius === "number") {
|
|
6839
|
+
root["--radius"] = `${intent.radius}rem`;
|
|
6840
|
+
}
|
|
6841
|
+
const primaryLight = primaryForMode(brand, "light");
|
|
6842
|
+
const primaryDark = primaryForMode(brand, "dark");
|
|
6843
|
+
light["--primary"] = oklchToString(primaryLight);
|
|
6844
|
+
light["--primary-foreground"] = readableForeground(primaryLight);
|
|
6845
|
+
light["--ring"] = oklchToString(
|
|
6846
|
+
scaleChroma({ ...primaryLight, l: 0.6 }, 0.7)
|
|
6847
|
+
);
|
|
6848
|
+
dark["--primary"] = oklchToString(primaryDark);
|
|
6849
|
+
dark["--primary-foreground"] = readableForeground(primaryDark);
|
|
6850
|
+
dark["--ring"] = oklchToString(scaleChroma({ ...primaryDark, l: 0.62 }, 0.6));
|
|
6851
|
+
const gLight = brandGradient(primaryLight);
|
|
6852
|
+
light["--primary-fill-from"] = oklchToString(gLight.from);
|
|
6853
|
+
light["--primary-fill-to"] = oklchToString(gLight.to);
|
|
6854
|
+
light["--primary-fill-hover-from"] = oklchToString(gLight.hoverFrom);
|
|
6855
|
+
light["--primary-fill-hover-to"] = oklchToString(gLight.hoverTo);
|
|
6856
|
+
light["--primary-fill-active-from"] = oklchToString(gLight.activeFrom);
|
|
6857
|
+
light["--primary-fill-active-to"] = oklchToString(gLight.activeTo);
|
|
6858
|
+
const gDark = brandGradient(primaryDark);
|
|
6859
|
+
dark["--primary-fill-from"] = oklchToString(gDark.from);
|
|
6860
|
+
dark["--primary-fill-to"] = oklchToString(gDark.to);
|
|
6861
|
+
dark["--primary-fill-hover-from"] = oklchToString(gDark.hoverFrom);
|
|
6862
|
+
dark["--primary-fill-hover-to"] = oklchToString(gDark.hoverTo);
|
|
6863
|
+
dark["--primary-fill-active-from"] = oklchToString(gDark.activeFrom);
|
|
6864
|
+
dark["--primary-fill-active-to"] = oklchToString(gDark.activeTo);
|
|
6865
|
+
if (accent) {
|
|
6866
|
+
const accentLight = { ...accent, l: Math.min(Math.max(accent.l, 0.9), 0.97) };
|
|
6867
|
+
const accentDark = { ...accent, l: 0.25, c: Math.min(accent.c, 0.04) };
|
|
6868
|
+
light["--accent"] = oklchToString(accentLight);
|
|
6869
|
+
light["--accent-foreground"] = readableForeground(accentLight);
|
|
6870
|
+
dark["--accent"] = oklchToString(accentDark);
|
|
6871
|
+
dark["--accent-foreground"] = readableForeground(accentDark);
|
|
6872
|
+
}
|
|
6873
|
+
light["--playground-from"] = oklchToString(
|
|
6874
|
+
withAlpha({ l: 0.91, c: 0.03, h: brand.h, alpha: 0.6 }, 0.6)
|
|
6875
|
+
);
|
|
6876
|
+
light["--playground-via"] = oklchToString(
|
|
6877
|
+
withAlpha({ l: 0.965, c: 0.015, h: brand.h, alpha: 0.3 }, 0.3)
|
|
6878
|
+
);
|
|
6879
|
+
dark["--playground-from"] = oklchToString({
|
|
6880
|
+
l: 0.27,
|
|
6881
|
+
c: 0.03,
|
|
6882
|
+
h: brand.h,
|
|
6883
|
+
alpha: 1
|
|
6884
|
+
});
|
|
6885
|
+
dark["--playground-via"] = oklchToString({
|
|
6886
|
+
l: 0.19,
|
|
6887
|
+
c: 0.02,
|
|
6888
|
+
h: brand.h,
|
|
6889
|
+
alpha: 1
|
|
6890
|
+
});
|
|
6891
|
+
if (intent.tintNeutrals) {
|
|
6892
|
+
const t = neutralTints(brand);
|
|
6893
|
+
light["--secondary"] = oklchToString({
|
|
6894
|
+
l: 0.975,
|
|
6895
|
+
c: t.lightChroma,
|
|
6896
|
+
h: t.lightHue,
|
|
6897
|
+
alpha: 1
|
|
6898
|
+
});
|
|
6899
|
+
light["--muted"] = light["--secondary"];
|
|
6900
|
+
light["--accent"] ?? (light["--accent"] = oklchToString({
|
|
6901
|
+
l: 0.965,
|
|
6902
|
+
c: t.lightChroma,
|
|
6903
|
+
h: t.lightHue,
|
|
6904
|
+
alpha: 1
|
|
6905
|
+
}));
|
|
6906
|
+
light["--border"] = oklchToString({
|
|
6907
|
+
l: 0.91,
|
|
6908
|
+
c: t.lightChroma,
|
|
6909
|
+
h: t.lightHue,
|
|
6910
|
+
alpha: 1
|
|
6911
|
+
});
|
|
6912
|
+
dark["--secondary"] = oklchToString({
|
|
6913
|
+
l: 0.22,
|
|
6914
|
+
c: t.darkChroma,
|
|
6915
|
+
h: t.darkHue,
|
|
6916
|
+
alpha: 1
|
|
6917
|
+
});
|
|
6918
|
+
dark["--muted"] = dark["--secondary"];
|
|
6919
|
+
dark["--border"] = oklchToString({
|
|
6920
|
+
l: 1,
|
|
6921
|
+
c: 0,
|
|
6922
|
+
h: 0,
|
|
6923
|
+
alpha: 0.1
|
|
6924
|
+
});
|
|
6925
|
+
}
|
|
6926
|
+
if (isDev2()) {
|
|
6927
|
+
const lum = relativeLuminance(primaryLight);
|
|
6928
|
+
const fgIsLight = light["--primary-foreground"].includes("0.985");
|
|
6929
|
+
const fgLum = fgIsLight ? 1 : 0.05;
|
|
6930
|
+
const ratio = (Math.max(lum, fgLum) + 0.05) / (Math.min(lum, fgLum) + 0.05);
|
|
6931
|
+
if (ratio < 3.5) {
|
|
6932
|
+
console.warn(
|
|
6933
|
+
`[@timbal-ai/timbal-react] createTimbalTheme: brand "${intent.brand}" yields a low primary/foreground contrast (~${ratio.toFixed(2)}:1). Consider a darker or more saturated brand color for buttons/CTAs.`
|
|
6934
|
+
);
|
|
6935
|
+
}
|
|
6936
|
+
}
|
|
6937
|
+
return { light, dark, root };
|
|
6938
|
+
}
|
|
6939
|
+
function declarations(map, indent) {
|
|
6940
|
+
return Object.entries(map).map(([name, value]) => `${indent}${name}: ${value};`).join("\n");
|
|
6941
|
+
}
|
|
6942
|
+
function themeToCss(theme, options = {}) {
|
|
6943
|
+
const indent = options.indent ?? " ";
|
|
6944
|
+
const blocks = [];
|
|
6945
|
+
const lightVars = { ...theme.root ?? {}, ...theme.light };
|
|
6946
|
+
if (options.scope) {
|
|
6947
|
+
const sel = `[data-timbal-theme="${options.scope}"]`;
|
|
6948
|
+
if (Object.keys(lightVars).length) {
|
|
6949
|
+
blocks.push(`${sel} {
|
|
6950
|
+
${declarations(lightVars, indent)}
|
|
6951
|
+
}`);
|
|
6952
|
+
}
|
|
6953
|
+
if (Object.keys(theme.dark).length) {
|
|
6954
|
+
blocks.push(
|
|
6955
|
+
`.dark ${sel}, ${sel}.dark {
|
|
6956
|
+
${declarations(theme.dark, indent)}
|
|
6957
|
+
}`
|
|
6958
|
+
);
|
|
6959
|
+
}
|
|
6960
|
+
} else {
|
|
6961
|
+
if (Object.keys(lightVars).length) {
|
|
6962
|
+
blocks.push(`:root {
|
|
6963
|
+
${declarations(lightVars, indent)}
|
|
6964
|
+
}`);
|
|
6965
|
+
}
|
|
6966
|
+
if (Object.keys(theme.dark).length) {
|
|
6967
|
+
blocks.push(`.dark {
|
|
6968
|
+
${declarations(theme.dark, indent)}
|
|
6969
|
+
}`);
|
|
6970
|
+
}
|
|
6971
|
+
}
|
|
6972
|
+
return blocks.join("\n\n");
|
|
6973
|
+
}
|
|
6974
|
+
var RUNTIME_STYLE_ID = "timbal-theme-runtime";
|
|
6975
|
+
function applyTimbalTheme(theme) {
|
|
6976
|
+
if (typeof document === "undefined") return () => {
|
|
6977
|
+
};
|
|
6978
|
+
let el = document.getElementById(RUNTIME_STYLE_ID);
|
|
6979
|
+
if (!el) {
|
|
6980
|
+
el = document.createElement("style");
|
|
6981
|
+
el.id = RUNTIME_STYLE_ID;
|
|
6982
|
+
el.setAttribute("data-timbal-theme-runtime", "");
|
|
6983
|
+
document.head.appendChild(el);
|
|
6984
|
+
}
|
|
6985
|
+
el.textContent = themeToCss(theme);
|
|
6986
|
+
return () => {
|
|
6987
|
+
el?.parentNode?.removeChild(el);
|
|
6988
|
+
};
|
|
6989
|
+
}
|
|
6990
|
+
function clearTimbalTheme() {
|
|
6991
|
+
if (typeof document === "undefined") return;
|
|
6992
|
+
document.getElementById(RUNTIME_STYLE_ID)?.remove();
|
|
6993
|
+
}
|
|
6994
|
+
function isDev2() {
|
|
6995
|
+
if (typeof process !== "undefined" && process.env?.NODE_ENV === "production") {
|
|
6996
|
+
return false;
|
|
6997
|
+
}
|
|
6998
|
+
return true;
|
|
6999
|
+
}
|
|
7000
|
+
|
|
7001
|
+
// src/design/theme-presets.ts
|
|
7002
|
+
var EMPTY_TOKENS = { light: {}, dark: {}, root: {} };
|
|
7003
|
+
var TIMBAL_THEME_PRESETS = [
|
|
7004
|
+
{
|
|
7005
|
+
id: "platform",
|
|
7006
|
+
label: "Platform",
|
|
7007
|
+
description: "Shipped neutral monochrome \u2014 the Timbal Platform default. Calm, brand-agnostic.",
|
|
7008
|
+
swatch: "oklch(0.205 0 0)",
|
|
7009
|
+
tokens: EMPTY_TOKENS
|
|
7010
|
+
},
|
|
7011
|
+
{
|
|
7012
|
+
id: "indigo",
|
|
7013
|
+
label: "Indigo",
|
|
7014
|
+
description: "Cool, trustworthy blue-violet \u2014 good for analytics & ops dashboards.",
|
|
7015
|
+
swatch: "#4f46e5",
|
|
7016
|
+
tokens: createTimbalTheme({ brand: "#4f46e5" })
|
|
7017
|
+
},
|
|
7018
|
+
{
|
|
7019
|
+
id: "violet",
|
|
7020
|
+
label: "Violet",
|
|
7021
|
+
description: "Vivid purple \u2014 expressive, product/marketing-leaning surfaces.",
|
|
7022
|
+
swatch: "#7c3aed",
|
|
7023
|
+
tokens: createTimbalTheme({ brand: "#7c3aed" })
|
|
7024
|
+
},
|
|
7025
|
+
{
|
|
7026
|
+
id: "forest",
|
|
7027
|
+
label: "Forest",
|
|
7028
|
+
description: "Grounded green \u2014 finance, sustainability, status-positive apps.",
|
|
7029
|
+
swatch: "#16a34a",
|
|
7030
|
+
tokens: createTimbalTheme({ brand: "#16a34a" })
|
|
7031
|
+
},
|
|
7032
|
+
{
|
|
7033
|
+
id: "warm",
|
|
7034
|
+
label: "Warm",
|
|
7035
|
+
description: "Energetic orange \u2014 consumer, creative, high-engagement tools.",
|
|
7036
|
+
swatch: "#ea580c",
|
|
7037
|
+
tokens: createTimbalTheme({ brand: "#ea580c" })
|
|
7038
|
+
},
|
|
7039
|
+
{
|
|
7040
|
+
id: "slate",
|
|
7041
|
+
label: "Slate",
|
|
7042
|
+
description: "Muted cool gray-blue with a subtle tint \u2014 understated enterprise.",
|
|
7043
|
+
swatch: "#475569",
|
|
7044
|
+
tokens: createTimbalTheme({ brand: "#475569", tintNeutrals: true })
|
|
7045
|
+
}
|
|
7046
|
+
];
|
|
7047
|
+
var PRESET_BY_ID = new Map(
|
|
7048
|
+
TIMBAL_THEME_PRESETS.map((preset) => [preset.id, preset])
|
|
7049
|
+
);
|
|
7050
|
+
function getThemePreset(id) {
|
|
7051
|
+
return PRESET_BY_ID.get(id);
|
|
7052
|
+
}
|
|
7053
|
+
function applyThemePreset(id) {
|
|
7054
|
+
const preset = PRESET_BY_ID.get(id);
|
|
7055
|
+
if (!preset) return () => {
|
|
7056
|
+
};
|
|
7057
|
+
if (typeof window !== "undefined") {
|
|
7058
|
+
try {
|
|
7059
|
+
window.localStorage.setItem(STORAGE_KEYS.themePreset, id);
|
|
7060
|
+
} catch {
|
|
7061
|
+
}
|
|
7062
|
+
}
|
|
7063
|
+
return applyTimbalTheme(preset.tokens);
|
|
7064
|
+
}
|
|
7065
|
+
function getStoredThemePreset() {
|
|
7066
|
+
if (typeof window === "undefined") return null;
|
|
7067
|
+
try {
|
|
7068
|
+
const value = window.localStorage.getItem(STORAGE_KEYS.themePreset);
|
|
7069
|
+
return value && PRESET_BY_ID.has(value) ? value : null;
|
|
7070
|
+
} catch {
|
|
7071
|
+
return null;
|
|
7072
|
+
}
|
|
7073
|
+
}
|
|
7074
|
+
|
|
7075
|
+
// src/design/theme-instructions.ts
|
|
7076
|
+
var THEME_AGENT_INSTRUCTIONS = `
|
|
7077
|
+
## Theming (@timbal-ai/timbal-react)
|
|
7078
|
+
|
|
7079
|
+
The package ships a complete light + dark token system (\`styles.css\`). Components are written against semantic Tailwind tokens (\`bg-background\`, \`text-primary\`, \`border-border\`, \`bg-elevated-from\`, \`bg-bubble-user\`, \u2026). To restyle, you change CSS variables \u2014 **never** hardcode colors in component code.
|
|
7080
|
+
|
|
7081
|
+
### Golden rule
|
|
7082
|
+
|
|
7083
|
+
**Never write \`oklch(...)\` / hex literals or hand-author paired \`:root\` + \`.dark\` blocks.** Express intent and let the package derive a complete, contrast-correct, paired palette.
|
|
7084
|
+
|
|
7085
|
+
### Pick a brand color (rebrand)
|
|
7086
|
+
|
|
7087
|
+
\`\`\`ts
|
|
7088
|
+
import { createTimbalTheme, themeToCss } from "@timbal-ai/timbal-react";
|
|
7089
|
+
|
|
7090
|
+
const theme = createTimbalTheme({ brand: "#4f46e5" /* accent?, radius?, tintNeutrals? */ });
|
|
7091
|
+
// Build-time: write once into your app CSS (paired light + dark, guaranteed in sync):
|
|
7092
|
+
const css = themeToCss(theme);
|
|
7093
|
+
\`\`\`
|
|
7094
|
+
|
|
7095
|
+
- For a real company, look up the actual brand hex first (brandfetch / "<company> brand color hex"), then pass it as \`brand\`.
|
|
7096
|
+
- \`createTimbalTheme\` derives \`--primary\`, its foreground, ring, the full button gradient, and a soft playground tint. You only supply intent.
|
|
7097
|
+
|
|
7098
|
+
### Apply a theme
|
|
7099
|
+
|
|
7100
|
+
- **Build-time / SSR:** \`themeToCss(theme)\` \u2192 paste the returned CSS into your \`index.css\` (after the \`@import "@timbal-ai/timbal-react/styles.css"\`). One block, both modes.
|
|
7101
|
+
- **Runtime / swappable:** \`applyTimbalTheme(theme)\` injects a managed \`<style>\` and returns a disposer. Works with the \`.dark\` toggle (next-themes / ModeToggle).
|
|
7102
|
+
- **Component:** render \`<TimbalThemeStyle theme={theme} />\` (or \`preset="indigo"\`) once near the app root.
|
|
7103
|
+
|
|
7104
|
+
### Offer styles to the user ("show compatible styles, then apply")
|
|
7105
|
+
|
|
7106
|
+
Use the closed preset catalog \u2014 do not invent options:
|
|
7107
|
+
|
|
7108
|
+
\`\`\`ts
|
|
7109
|
+
import { TIMBAL_THEME_PRESETS, applyThemePreset } from "@timbal-ai/timbal-react";
|
|
7110
|
+
// TIMBAL_THEME_PRESETS: { id, label, description, swatch, tokens }[]
|
|
7111
|
+
\`\`\`
|
|
7112
|
+
|
|
7113
|
+
| Preset id | Use when |
|
|
7114
|
+
|-----------|----------|
|
|
7115
|
+
| \`platform\` | Neutral monochrome default (no brand) |
|
|
7116
|
+
| \`indigo\` | Cool, trustworthy \u2014 analytics / ops dashboards |
|
|
7117
|
+
| \`violet\` | Expressive purple \u2014 product / marketing |
|
|
7118
|
+
| \`forest\` | Green \u2014 finance, sustainability, positive status |
|
|
7119
|
+
| \`warm\` | Orange \u2014 consumer / creative / high-engagement |
|
|
7120
|
+
| \`slate\` | Muted enterprise gray-blue (tinted neutrals) |
|
|
7121
|
+
|
|
7122
|
+
- To present options visually, render \`<ThemePresetGallery value={id} onSelect={setId} />\` \u2014 each swatch previews real components (Button + metric tile) scoped via \`data-timbal-theme\`, so the live app doesn't change until the user picks.
|
|
7123
|
+
- On selection, call \`applyThemePreset(id)\` (persists to \`localStorage\` and restores on reload).
|
|
7124
|
+
|
|
7125
|
+
### Rules
|
|
7126
|
+
|
|
7127
|
+
- Generated pages use **semantic Tailwind tokens only** \u2014 never literal colors or per-element \`style={{ color }}\`.
|
|
7128
|
+
- Light/dark mode stays the \`.dark\` class (\`next-themes attribute="class"\` or \`ModeToggle\`). Presets are **brand**, not a second dark-mode system.
|
|
7129
|
+
- Override individual tokens only for one-offs the generator doesn't cover; if you must, set the variable in **both** \`:root\` and \`.dark\` (a dev-only warning fires otherwise).
|
|
7130
|
+
`.trim();
|
|
7131
|
+
|
|
7132
|
+
// src/app/theme/TimbalThemeStyle.tsx
|
|
7133
|
+
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
7134
|
+
var TimbalThemeStyle = ({
|
|
7135
|
+
theme,
|
|
7136
|
+
preset,
|
|
7137
|
+
scope,
|
|
7138
|
+
nonce
|
|
7139
|
+
}) => {
|
|
7140
|
+
const tokens = theme ?? (preset ? getThemePreset(preset)?.tokens : void 0);
|
|
7141
|
+
if (!tokens) return null;
|
|
7142
|
+
const css = themeToCss(tokens, scope ? { scope } : void 0);
|
|
7143
|
+
if (!css) return null;
|
|
7144
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
7145
|
+
"style",
|
|
7146
|
+
{
|
|
7147
|
+
"data-timbal-theme-style": scope ?? "root",
|
|
7148
|
+
nonce,
|
|
7149
|
+
dangerouslySetInnerHTML: { __html: css }
|
|
7150
|
+
}
|
|
7151
|
+
);
|
|
7152
|
+
};
|
|
7153
|
+
|
|
7154
|
+
// src/app/data/metrics-shared.tsx
|
|
7155
|
+
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
7156
|
+
var metricCardShellClass = cn(
|
|
7157
|
+
studioIntegrationCardClass,
|
|
7158
|
+
"aui-app-metric-card shadow-none",
|
|
7159
|
+
"flex flex-col overflow-hidden"
|
|
7160
|
+
);
|
|
7161
|
+
var metricCardHeaderClass = "flex items-start justify-between gap-3 px-4 pb-1 pt-3";
|
|
7162
|
+
var metricTilesRowClass = "grid w-full min-w-0";
|
|
7163
|
+
var metricChartRegionClass = "relative min-h-0 w-full border-t border-border/40 pt-2";
|
|
7164
|
+
var metricChartPlotRegionClass = "relative min-h-0 w-full border-t border-border/40 px-0 pt-5 pb-3";
|
|
7165
|
+
var metricCellDividerClass = "border-r border-border/40";
|
|
7166
|
+
var MetricCardHeader = ({
|
|
7167
|
+
title,
|
|
7168
|
+
titleId,
|
|
7169
|
+
description,
|
|
7170
|
+
actions
|
|
7171
|
+
}) => {
|
|
7172
|
+
if (!title && !description && !actions) return null;
|
|
7173
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("header", { className: metricCardHeaderClass, children: [
|
|
7174
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "min-w-0", children: [
|
|
7175
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("h3", { id: titleId, className: "text-base font-normal text-foreground", children: title }) : null,
|
|
7176
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
|
|
7177
|
+
] }),
|
|
7178
|
+
actions ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "shrink-0", children: actions }) : null
|
|
7179
|
+
] });
|
|
7180
|
+
};
|
|
7181
|
+
function metricTilesGridColsClass(n) {
|
|
7182
|
+
switch (n) {
|
|
7183
|
+
case 1:
|
|
7184
|
+
return "grid-cols-1";
|
|
7185
|
+
case 2:
|
|
7186
|
+
return "grid-cols-2";
|
|
7187
|
+
case 3:
|
|
7188
|
+
return "grid-cols-3";
|
|
7189
|
+
case 5:
|
|
7190
|
+
return "grid-cols-2 sm:grid-cols-5";
|
|
7191
|
+
case 6:
|
|
7192
|
+
return "grid-cols-2 sm:grid-cols-3 lg:grid-cols-6";
|
|
7193
|
+
default:
|
|
7194
|
+
return "grid-cols-2 md:grid-cols-4";
|
|
7195
|
+
}
|
|
7196
|
+
}
|
|
7197
|
+
|
|
7198
|
+
// src/app/data/MetricTile.tsx
|
|
7199
|
+
var import_jsx_runtime51 = require("react/jsx-runtime");
|
|
7200
|
+
var trendToneClass = {
|
|
7201
|
+
up: "border-border/80 bg-muted/40 text-muted-foreground",
|
|
7202
|
+
down: "border-border/80 bg-muted/40 text-muted-foreground",
|
|
7203
|
+
neutral: "border-border/80 bg-muted/30 text-muted-foreground"
|
|
7204
|
+
};
|
|
7205
|
+
var metricTileBaseClass = "relative flex min-w-0 flex-1 flex-col gap-1 px-4 py-3 text-left font-normal";
|
|
7206
|
+
var metricTileInteractiveClass = cn(
|
|
7207
|
+
metricTileBaseClass,
|
|
7208
|
+
"bg-transparent hover:bg-transparent active:bg-transparent",
|
|
7209
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-foreground/10"
|
|
7210
|
+
);
|
|
7211
|
+
var MetricTile = ({
|
|
7212
|
+
label,
|
|
7213
|
+
value,
|
|
7214
|
+
unit,
|
|
7215
|
+
trend,
|
|
7216
|
+
trendTone = "neutral",
|
|
7217
|
+
active = false,
|
|
7218
|
+
showDivider = false,
|
|
7219
|
+
onSelect,
|
|
7220
|
+
ariaLabel,
|
|
7221
|
+
className
|
|
7222
|
+
}) => {
|
|
7223
|
+
const content = /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_jsx_runtime51.Fragment, { children: [
|
|
7224
|
+
active ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
7225
|
+
"span",
|
|
7226
|
+
{
|
|
7227
|
+
"aria-hidden": true,
|
|
7228
|
+
className: "absolute inset-x-0 bottom-0 h-0.5 bg-foreground dark:bg-white"
|
|
7229
|
+
}
|
|
7230
|
+
) : null,
|
|
7231
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "text-xs font-normal text-muted-foreground", children: label }),
|
|
7232
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("span", { className: "flex items-center gap-2", children: [
|
|
7233
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("span", { className: "flex items-baseline gap-1", children: [
|
|
7234
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "text-2xl font-normal tracking-tight text-foreground tabular-nums", children: value }),
|
|
7235
|
+
unit ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "text-xs font-normal text-muted-foreground", children: unit }) : null
|
|
7236
|
+
] }),
|
|
7237
|
+
trend ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
7238
|
+
"span",
|
|
7239
|
+
{
|
|
7240
|
+
className: cn(
|
|
7241
|
+
"rounded-full border px-1.5 py-0.5 text-xs font-normal",
|
|
7242
|
+
trendToneClass[trendTone]
|
|
7243
|
+
),
|
|
7244
|
+
children: trend
|
|
7245
|
+
}
|
|
7246
|
+
) : null
|
|
7247
|
+
] })
|
|
7248
|
+
] });
|
|
7249
|
+
const divider = showDivider ? metricCellDividerClass : void 0;
|
|
7250
|
+
if (onSelect) {
|
|
7251
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
7252
|
+
"button",
|
|
7253
|
+
{
|
|
7254
|
+
type: "button",
|
|
7255
|
+
onClick: onSelect,
|
|
7256
|
+
"aria-pressed": active,
|
|
7257
|
+
"aria-label": ariaLabel,
|
|
7258
|
+
className: cn(metricTileInteractiveClass, divider, className),
|
|
7259
|
+
children: content
|
|
7260
|
+
}
|
|
7261
|
+
);
|
|
7262
|
+
}
|
|
7263
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: cn(metricTileBaseClass, divider, className), children: content });
|
|
7264
|
+
};
|
|
7265
|
+
|
|
7266
|
+
// src/app/theme/ThemePresetGallery.tsx
|
|
7267
|
+
var import_jsx_runtime52 = require("react/jsx-runtime");
|
|
7268
|
+
var ThemePresetGallery = ({
|
|
7269
|
+
value,
|
|
7270
|
+
onSelect,
|
|
7271
|
+
presets,
|
|
7272
|
+
className
|
|
7273
|
+
}) => {
|
|
7274
|
+
const items = presets ? TIMBAL_THEME_PRESETS.filter((p) => presets.includes(p.id)) : TIMBAL_THEME_PRESETS;
|
|
7275
|
+
return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
7276
|
+
"div",
|
|
7277
|
+
{
|
|
7278
|
+
role: "radiogroup",
|
|
7279
|
+
"aria-label": "Theme presets",
|
|
7280
|
+
className: cn(
|
|
7281
|
+
"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3",
|
|
7282
|
+
className
|
|
7283
|
+
),
|
|
7284
|
+
children: items.map((preset) => {
|
|
7285
|
+
const selected = value === preset.id;
|
|
7286
|
+
return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { "data-timbal-theme": preset.id, children: [
|
|
7287
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(TimbalThemeStyle, { preset: preset.id, scope: preset.id }),
|
|
7288
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
|
|
7289
|
+
"button",
|
|
7290
|
+
{
|
|
7291
|
+
type: "button",
|
|
7292
|
+
role: "radio",
|
|
7293
|
+
"aria-checked": selected,
|
|
7294
|
+
"aria-label": `${preset.label} theme`,
|
|
7295
|
+
onClick: () => onSelect?.(preset.id),
|
|
7296
|
+
className: cn(
|
|
7297
|
+
"group flex w-full flex-col gap-3 rounded-xl border bg-card p-3 text-left transition-colors",
|
|
7298
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
7299
|
+
selected ? "border-primary ring-2 ring-primary/30" : "border-border hover:border-foreground/30"
|
|
7300
|
+
),
|
|
7301
|
+
children: [
|
|
7302
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
|
|
7303
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("span", { className: "flex items-center gap-2", children: [
|
|
7304
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
7305
|
+
"span",
|
|
7306
|
+
{
|
|
7307
|
+
"aria-hidden": true,
|
|
7308
|
+
className: "size-4 shrink-0 rounded-full ring-1 ring-black/10",
|
|
7309
|
+
style: { background: preset.swatch }
|
|
7310
|
+
}
|
|
7311
|
+
),
|
|
7312
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "text-sm font-medium text-foreground", children: preset.label })
|
|
7313
|
+
] }),
|
|
7314
|
+
selected ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "text-xs font-medium text-primary", children: "Selected" }) : null
|
|
7315
|
+
] }),
|
|
7316
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)("p", { className: "text-xs leading-snug text-muted-foreground", children: preset.description }),
|
|
7317
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "flex flex-col gap-2 rounded-lg border border-border bg-background p-2", children: [
|
|
7318
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
7319
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Button, { size: "xs", className: "pointer-events-none", children: "Primary" }),
|
|
7320
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "size-5 rounded-md bg-primary", "aria-hidden": true }),
|
|
7321
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "size-5 rounded-md bg-muted", "aria-hidden": true }),
|
|
7322
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
7323
|
+
"span",
|
|
7324
|
+
{
|
|
7325
|
+
className: "size-5 rounded-md border border-border bg-accent",
|
|
7326
|
+
"aria-hidden": true
|
|
7327
|
+
}
|
|
7328
|
+
)
|
|
7329
|
+
] }),
|
|
7330
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(MetricTile, { label: "Active users", value: "1,248", trend: "+8%" })
|
|
7331
|
+
] })
|
|
7332
|
+
]
|
|
7333
|
+
}
|
|
7334
|
+
)
|
|
7335
|
+
] }, preset.id);
|
|
7336
|
+
})
|
|
7337
|
+
}
|
|
7338
|
+
);
|
|
7339
|
+
};
|
|
7340
|
+
|
|
6650
7341
|
// src/app/layout/AppShell.tsx
|
|
6651
7342
|
var import_react55 = require("motion/react");
|
|
6652
7343
|
var import_react56 = require("react");
|
|
@@ -6713,7 +7404,7 @@ function useAppShellChat() {
|
|
|
6713
7404
|
}
|
|
6714
7405
|
|
|
6715
7406
|
// src/app/layout/AppShell.tsx
|
|
6716
|
-
var
|
|
7407
|
+
var import_jsx_runtime53 = require("react/jsx-runtime");
|
|
6717
7408
|
var floatingTriggerClass = cn(
|
|
6718
7409
|
"aui-app-shell-chat-trigger-fixed fixed z-50 rounded-full px-5 py-2.5 text-sm font-medium shadow-card-elevated",
|
|
6719
7410
|
"bg-primary text-primary-foreground transition-colors hover:bg-primary/90",
|
|
@@ -6742,14 +7433,14 @@ var AppShellBody = ({
|
|
|
6742
7433
|
layoutDirection
|
|
6743
7434
|
);
|
|
6744
7435
|
const insetPadding = sidebar ? insetPaddingPx : 0;
|
|
6745
|
-
return /* @__PURE__ */ (0,
|
|
7436
|
+
return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6746
7437
|
import_react55.motion.div,
|
|
6747
7438
|
{
|
|
6748
7439
|
className: "aui-app-shell-body relative z-10 flex min-h-0 min-w-0 flex-1 flex-col",
|
|
6749
7440
|
initial: false,
|
|
6750
7441
|
animate: { paddingLeft: insetPadding },
|
|
6751
7442
|
transition: layoutTransition,
|
|
6752
|
-
children: /* @__PURE__ */ (0,
|
|
7443
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
|
|
6753
7444
|
"div",
|
|
6754
7445
|
{
|
|
6755
7446
|
className: cn(
|
|
@@ -6757,8 +7448,8 @@ var AppShellBody = ({
|
|
|
6757
7448
|
!topbarContent && appShellInsetTopClass
|
|
6758
7449
|
),
|
|
6759
7450
|
children: [
|
|
6760
|
-
topbarContent ? /* @__PURE__ */ (0,
|
|
6761
|
-
/* @__PURE__ */ (0,
|
|
7451
|
+
topbarContent ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("header", { className: cn("aui-app-shell-topbar-region", appShellTopbarStickyClass), children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: appShellTopbarInsetClass, children: topbarContent }) }) : null,
|
|
7452
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)("main", { className: cn("aui-app-shell-main min-w-0 flex-1", mainClassName), children })
|
|
6762
7453
|
]
|
|
6763
7454
|
}
|
|
6764
7455
|
)
|
|
@@ -6806,7 +7497,7 @@ var AppShell = ({
|
|
|
6806
7497
|
setInsetPaddingPx(insetPx);
|
|
6807
7498
|
}, []);
|
|
6808
7499
|
const insetExpanded = insetPaddingPx >= SIDEBAR_INSET_PX_EXPANDED;
|
|
6809
|
-
const shellBody = /* @__PURE__ */ (0,
|
|
7500
|
+
const shellBody = /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6810
7501
|
AppShellBody,
|
|
6811
7502
|
{
|
|
6812
7503
|
sidebar,
|
|
@@ -6817,7 +7508,7 @@ var AppShell = ({
|
|
|
6817
7508
|
children
|
|
6818
7509
|
}
|
|
6819
7510
|
);
|
|
6820
|
-
const tree = /* @__PURE__ */ (0,
|
|
7511
|
+
const tree = /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(ShellInsetProvider, { value: sidebar ? reportShellInset : null, children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
|
|
6821
7512
|
"div",
|
|
6822
7513
|
{
|
|
6823
7514
|
className: cn(
|
|
@@ -6828,7 +7519,7 @@ var AppShell = ({
|
|
|
6828
7519
|
children: [
|
|
6829
7520
|
sidebar,
|
|
6830
7521
|
shellBody,
|
|
6831
|
-
hasChat && chatOpen ? /* @__PURE__ */ (0,
|
|
7522
|
+
hasChat && chatOpen ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6832
7523
|
"div",
|
|
6833
7524
|
{
|
|
6834
7525
|
className: floatingPanelClass,
|
|
@@ -6841,7 +7532,7 @@ var AppShell = ({
|
|
|
6841
7532
|
children: chat
|
|
6842
7533
|
}
|
|
6843
7534
|
) : null,
|
|
6844
|
-
hasChat && chatCollapsible && !chatOpen && !hideChatTrigger ? /* @__PURE__ */ (0,
|
|
7535
|
+
hasChat && chatCollapsible && !chatOpen && !hideChatTrigger ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6845
7536
|
"button",
|
|
6846
7537
|
{
|
|
6847
7538
|
type: "button",
|
|
@@ -6857,7 +7548,7 @@ var AppShell = ({
|
|
|
6857
7548
|
if (!hasChat) {
|
|
6858
7549
|
return tree;
|
|
6859
7550
|
}
|
|
6860
|
-
return /* @__PURE__ */ (0,
|
|
7551
|
+
return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6861
7552
|
AppShellChatProvider,
|
|
6862
7553
|
{
|
|
6863
7554
|
value: {
|
|
@@ -6872,24 +7563,24 @@ var AppShell = ({
|
|
|
6872
7563
|
};
|
|
6873
7564
|
|
|
6874
7565
|
// src/app/layout/AppShellTopbar.tsx
|
|
6875
|
-
var
|
|
7566
|
+
var import_jsx_runtime54 = require("react/jsx-runtime");
|
|
6876
7567
|
var AppShellTopbar = ({
|
|
6877
7568
|
start,
|
|
6878
7569
|
actions,
|
|
6879
7570
|
children,
|
|
6880
7571
|
className
|
|
6881
7572
|
}) => {
|
|
6882
|
-
return /* @__PURE__ */ (0,
|
|
6883
|
-
/* @__PURE__ */ (0,
|
|
7573
|
+
return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: cn("aui-app-shell-topbar", appShellTopbarRowClass, className), children: [
|
|
7574
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
6884
7575
|
start,
|
|
6885
7576
|
children
|
|
6886
7577
|
] }),
|
|
6887
|
-
actions ? /* @__PURE__ */ (0,
|
|
7578
|
+
actions ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "aui-app-shell-topbar-actions flex shrink-0 items-center gap-2", children: actions }) : null
|
|
6888
7579
|
] });
|
|
6889
7580
|
};
|
|
6890
7581
|
|
|
6891
7582
|
// src/app/layout/AppShellChatTrigger.tsx
|
|
6892
|
-
var
|
|
7583
|
+
var import_jsx_runtime55 = require("react/jsx-runtime");
|
|
6893
7584
|
var floatingPositionClass = "fixed bottom-6 right-6 z-50 max-sm:bottom-4 max-sm:right-4";
|
|
6894
7585
|
var AppShellChatTrigger = ({
|
|
6895
7586
|
className,
|
|
@@ -6898,7 +7589,7 @@ var AppShellChatTrigger = ({
|
|
|
6898
7589
|
}) => {
|
|
6899
7590
|
const shellChat = useAppShellChat();
|
|
6900
7591
|
if (!shellChat || shellChat.open) return null;
|
|
6901
|
-
return /* @__PURE__ */ (0,
|
|
7592
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
6902
7593
|
TimbalV2Button,
|
|
6903
7594
|
{
|
|
6904
7595
|
type: "button",
|
|
@@ -6918,61 +7609,61 @@ var AppShellChatTrigger = ({
|
|
|
6918
7609
|
};
|
|
6919
7610
|
|
|
6920
7611
|
// src/app/layout/PageHeader.tsx
|
|
6921
|
-
var
|
|
7612
|
+
var import_jsx_runtime56 = require("react/jsx-runtime");
|
|
6922
7613
|
var PageHeader = ({
|
|
6923
7614
|
title,
|
|
6924
7615
|
description,
|
|
6925
7616
|
actions,
|
|
6926
7617
|
className
|
|
6927
7618
|
}) => {
|
|
6928
|
-
return /* @__PURE__ */ (0,
|
|
6929
|
-
/* @__PURE__ */ (0,
|
|
6930
|
-
/* @__PURE__ */ (0,
|
|
6931
|
-
description ? /* @__PURE__ */ (0,
|
|
7619
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("header", { className: cn("aui-app-page-header", appPageHeaderClass, className), children: [
|
|
7620
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "min-w-0", children: [
|
|
7621
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("h1", { className: "text-2xl font-semibold tracking-tight text-foreground", children: title }),
|
|
7622
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null
|
|
6932
7623
|
] }),
|
|
6933
|
-
actions ? /* @__PURE__ */ (0,
|
|
7624
|
+
actions ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "aui-app-page-header-actions flex shrink-0 flex-wrap items-center gap-2", children: actions }) : null
|
|
6934
7625
|
] });
|
|
6935
7626
|
};
|
|
6936
7627
|
|
|
6937
7628
|
// src/app/layout/Page.tsx
|
|
6938
|
-
var
|
|
7629
|
+
var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
6939
7630
|
var Page = ({
|
|
6940
7631
|
children,
|
|
6941
7632
|
breadcrumbs,
|
|
6942
7633
|
className,
|
|
6943
7634
|
...headerProps
|
|
6944
7635
|
}) => {
|
|
6945
|
-
return /* @__PURE__ */ (0,
|
|
7636
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: cn("aui-app-page", appPageColumnClass, className), children: [
|
|
6946
7637
|
breadcrumbs,
|
|
6947
|
-
/* @__PURE__ */ (0,
|
|
7638
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(PageHeader, { ...headerProps }),
|
|
6948
7639
|
children
|
|
6949
7640
|
] });
|
|
6950
7641
|
};
|
|
6951
7642
|
|
|
6952
7643
|
// src/app/layout/Section.tsx
|
|
6953
|
-
var
|
|
7644
|
+
var import_jsx_runtime58 = require("react/jsx-runtime");
|
|
6954
7645
|
var Section = ({
|
|
6955
7646
|
title,
|
|
6956
7647
|
description,
|
|
6957
7648
|
children,
|
|
6958
7649
|
className
|
|
6959
7650
|
}) => {
|
|
6960
|
-
return /* @__PURE__ */ (0,
|
|
6961
|
-
title ? /* @__PURE__ */ (0,
|
|
6962
|
-
description ? /* @__PURE__ */ (0,
|
|
7651
|
+
return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("section", { className: cn("aui-app-section", appSectionClass, className), children: [
|
|
7652
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("h2", { className: appSectionTitleClass, children: title }) : null,
|
|
7653
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { className: appSectionDescriptionClass, children: description }) : null,
|
|
6963
7654
|
children
|
|
6964
7655
|
] });
|
|
6965
7656
|
};
|
|
6966
7657
|
|
|
6967
7658
|
// src/app/copilot/app-copilot-context.tsx
|
|
6968
7659
|
var import_react57 = require("react");
|
|
6969
|
-
var
|
|
7660
|
+
var import_jsx_runtime59 = require("react/jsx-runtime");
|
|
6970
7661
|
var AppCopilotContext = (0, import_react57.createContext)(null);
|
|
6971
7662
|
var AppCopilotProvider = ({
|
|
6972
7663
|
value,
|
|
6973
7664
|
children
|
|
6974
7665
|
}) => {
|
|
6975
|
-
return /* @__PURE__ */ (0,
|
|
7666
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(AppCopilotContext.Provider, { value, children });
|
|
6976
7667
|
};
|
|
6977
7668
|
function useAppCopilotContext() {
|
|
6978
7669
|
return (0, import_react57.useContext)(AppCopilotContext) ?? {};
|
|
@@ -6980,7 +7671,7 @@ function useAppCopilotContext() {
|
|
|
6980
7671
|
|
|
6981
7672
|
// src/app/chat/AppChatPanel.tsx
|
|
6982
7673
|
var import_lucide_react15 = require("lucide-react");
|
|
6983
|
-
var
|
|
7674
|
+
var import_jsx_runtime60 = require("react/jsx-runtime");
|
|
6984
7675
|
var shellClass = "aui-app-chat-panel flex h-full min-h-0 flex-col overflow-hidden";
|
|
6985
7676
|
var chromeClass = cn(
|
|
6986
7677
|
"aui-app-chat-panel-chrome relative z-20 flex min-h-10 shrink-0 items-center justify-end px-2 pt-2"
|
|
@@ -7025,18 +7716,18 @@ var AppChatPanel = ({
|
|
|
7025
7716
|
...rest
|
|
7026
7717
|
}) => {
|
|
7027
7718
|
const shellChat = useAppShellChat();
|
|
7028
|
-
return /* @__PURE__ */ (0,
|
|
7029
|
-
shellChat?.collapsible ? /* @__PURE__ */ (0,
|
|
7719
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: cn(shellClass, className), children: [
|
|
7720
|
+
shellChat?.collapsible ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: chromeClass, children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
7030
7721
|
"button",
|
|
7031
7722
|
{
|
|
7032
7723
|
type: "button",
|
|
7033
7724
|
className: closeButtonClass,
|
|
7034
7725
|
onClick: () => shellChat.setOpen(false),
|
|
7035
7726
|
"aria-label": "Close assistant",
|
|
7036
|
-
children: /* @__PURE__ */ (0,
|
|
7727
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_lucide_react15.XIcon, { className: "size-4", "aria-hidden": true })
|
|
7037
7728
|
}
|
|
7038
7729
|
) }) : null,
|
|
7039
|
-
/* @__PURE__ */ (0,
|
|
7730
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: bodyClass, children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
7040
7731
|
TimbalRuntimeProvider,
|
|
7041
7732
|
{
|
|
7042
7733
|
workforceId,
|
|
@@ -7046,7 +7737,7 @@ var AppChatPanel = ({
|
|
|
7046
7737
|
attachmentsUploadUrl,
|
|
7047
7738
|
attachmentsAccept,
|
|
7048
7739
|
debug,
|
|
7049
|
-
children: /* @__PURE__ */ (0,
|
|
7740
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
7050
7741
|
Thread,
|
|
7051
7742
|
{
|
|
7052
7743
|
variant: "panel",
|
|
@@ -7067,38 +7758,38 @@ var AppChatPanel = ({
|
|
|
7067
7758
|
};
|
|
7068
7759
|
|
|
7069
7760
|
// src/app/surfaces/SurfaceCard.tsx
|
|
7070
|
-
var
|
|
7761
|
+
var import_jsx_runtime61 = require("react/jsx-runtime");
|
|
7071
7762
|
var SurfaceCard = ({ children, className }) => {
|
|
7072
|
-
return /* @__PURE__ */ (0,
|
|
7763
|
+
return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: cn("aui-app-surface-card", appSurfaceCardClass, className), children });
|
|
7073
7764
|
};
|
|
7074
7765
|
|
|
7075
7766
|
// src/app/surfaces/StatTile.tsx
|
|
7076
|
-
var
|
|
7767
|
+
var import_jsx_runtime62 = require("react/jsx-runtime");
|
|
7077
7768
|
var StatTile = ({ label, value, hint, className }) => {
|
|
7078
|
-
return /* @__PURE__ */ (0,
|
|
7079
|
-
/* @__PURE__ */ (0,
|
|
7080
|
-
/* @__PURE__ */ (0,
|
|
7081
|
-
hint ? /* @__PURE__ */ (0,
|
|
7769
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: cn("aui-app-stat-tile", appStatTileClass, className), children: [
|
|
7770
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: appStatLabelClass, children: label }),
|
|
7771
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: appStatValueClass, children: value }),
|
|
7772
|
+
hint ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "text-xs text-muted-foreground", children: hint }) : null
|
|
7082
7773
|
] });
|
|
7083
7774
|
};
|
|
7084
7775
|
|
|
7085
7776
|
// src/app/surfaces/EmptyState.tsx
|
|
7086
|
-
var
|
|
7777
|
+
var import_jsx_runtime63 = require("react/jsx-runtime");
|
|
7087
7778
|
var EmptyState = ({
|
|
7088
7779
|
title,
|
|
7089
7780
|
description,
|
|
7090
7781
|
action,
|
|
7091
7782
|
className
|
|
7092
7783
|
}) => {
|
|
7093
|
-
return /* @__PURE__ */ (0,
|
|
7094
|
-
/* @__PURE__ */ (0,
|
|
7095
|
-
description ? /* @__PURE__ */ (0,
|
|
7784
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: cn("aui-app-empty-state", appEmptyStateClass, className), children: [
|
|
7785
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("p", { className: appEmptyStateTitleClass, children: title }),
|
|
7786
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("p", { className: appEmptyStateDescriptionClass, children: description }) : null,
|
|
7096
7787
|
action
|
|
7097
7788
|
] });
|
|
7098
7789
|
};
|
|
7099
7790
|
|
|
7100
7791
|
// src/app/surfaces/StatusBadge.tsx
|
|
7101
|
-
var
|
|
7792
|
+
var import_jsx_runtime64 = require("react/jsx-runtime");
|
|
7102
7793
|
var statusBadgeToneClass = {
|
|
7103
7794
|
default: "bg-muted text-foreground",
|
|
7104
7795
|
primary: "bg-primary/10 text-primary",
|
|
@@ -7111,7 +7802,7 @@ var StatusBadge = ({
|
|
|
7111
7802
|
tone = "default",
|
|
7112
7803
|
className
|
|
7113
7804
|
}) => {
|
|
7114
|
-
return /* @__PURE__ */ (0,
|
|
7805
|
+
return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
|
|
7115
7806
|
"span",
|
|
7116
7807
|
{
|
|
7117
7808
|
className: cn(
|
|
@@ -7125,7 +7816,7 @@ var StatusBadge = ({
|
|
|
7125
7816
|
};
|
|
7126
7817
|
|
|
7127
7818
|
// src/app/surfaces/AppConfirmDialog.tsx
|
|
7128
|
-
var
|
|
7819
|
+
var import_jsx_runtime65 = require("react/jsx-runtime");
|
|
7129
7820
|
var bodyClass2 = "flex flex-col gap-4 p-6";
|
|
7130
7821
|
var titleClass = "pr-8";
|
|
7131
7822
|
var actionsClass = "flex flex-wrap justify-end gap-2";
|
|
@@ -7140,15 +7831,15 @@ var AppConfirmDialog = ({
|
|
|
7140
7831
|
destructive = false,
|
|
7141
7832
|
className
|
|
7142
7833
|
}) => {
|
|
7143
|
-
return /* @__PURE__ */ (0,
|
|
7834
|
+
return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(Dialog, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
7144
7835
|
DialogContent,
|
|
7145
7836
|
{
|
|
7146
7837
|
className: cn("gap-0 p-0 sm:max-w-md", className),
|
|
7147
|
-
children: /* @__PURE__ */ (0,
|
|
7148
|
-
/* @__PURE__ */ (0,
|
|
7149
|
-
description ? /* @__PURE__ */ (0,
|
|
7150
|
-
/* @__PURE__ */ (0,
|
|
7151
|
-
/* @__PURE__ */ (0,
|
|
7838
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { className: bodyClass2, children: [
|
|
7839
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(DialogTitle, { className: titleClass, children: title }),
|
|
7840
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("p", { className: "text-sm text-muted-foreground", children: description }) : null,
|
|
7841
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { className: actionsClass, children: [
|
|
7842
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
7152
7843
|
TimbalV2Button,
|
|
7153
7844
|
{
|
|
7154
7845
|
type: "button",
|
|
@@ -7158,7 +7849,7 @@ var AppConfirmDialog = ({
|
|
|
7158
7849
|
children: cancelLabel
|
|
7159
7850
|
}
|
|
7160
7851
|
),
|
|
7161
|
-
/* @__PURE__ */ (0,
|
|
7852
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
7162
7853
|
TimbalV2Button,
|
|
7163
7854
|
{
|
|
7164
7855
|
type: "button",
|
|
@@ -7178,7 +7869,7 @@ var AppConfirmDialog = ({
|
|
|
7178
7869
|
};
|
|
7179
7870
|
|
|
7180
7871
|
// src/app/surfaces/InfoCard.tsx
|
|
7181
|
-
var
|
|
7872
|
+
var import_jsx_runtime66 = require("react/jsx-runtime");
|
|
7182
7873
|
var toneClass = {
|
|
7183
7874
|
neutral: "border-border bg-muted/40",
|
|
7184
7875
|
info: "border-primary/25 bg-primary/5",
|
|
@@ -7193,7 +7884,7 @@ var InfoCard = ({
|
|
|
7193
7884
|
action,
|
|
7194
7885
|
tone = "neutral",
|
|
7195
7886
|
className
|
|
7196
|
-
}) => /* @__PURE__ */ (0,
|
|
7887
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
|
|
7197
7888
|
"div",
|
|
7198
7889
|
{
|
|
7199
7890
|
className: cn(
|
|
@@ -7202,18 +7893,18 @@ var InfoCard = ({
|
|
|
7202
7893
|
className
|
|
7203
7894
|
),
|
|
7204
7895
|
children: [
|
|
7205
|
-
icon ? /* @__PURE__ */ (0,
|
|
7206
|
-
/* @__PURE__ */ (0,
|
|
7207
|
-
title ? /* @__PURE__ */ (0,
|
|
7208
|
-
children ? /* @__PURE__ */ (0,
|
|
7896
|
+
icon ? /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("span", { className: "mt-0.5 shrink-0 text-muted-foreground", children: icon }) : null,
|
|
7897
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
7898
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("p", { className: "text-sm font-medium text-foreground", children: title }) : null,
|
|
7899
|
+
children ? /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className: cn("text-sm text-muted-foreground", title && "mt-1"), children }) : null
|
|
7209
7900
|
] }),
|
|
7210
|
-
action ? /* @__PURE__ */ (0,
|
|
7901
|
+
action ? /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className: "shrink-0", children: action }) : null
|
|
7211
7902
|
]
|
|
7212
7903
|
}
|
|
7213
7904
|
);
|
|
7214
7905
|
|
|
7215
7906
|
// src/app/surfaces/StatusDot.tsx
|
|
7216
|
-
var
|
|
7907
|
+
var import_jsx_runtime67 = require("react/jsx-runtime");
|
|
7217
7908
|
var dotClass = {
|
|
7218
7909
|
online: "bg-emerald-500",
|
|
7219
7910
|
busy: "bg-amber-500",
|
|
@@ -7226,9 +7917,9 @@ var StatusDot = ({
|
|
|
7226
7917
|
label,
|
|
7227
7918
|
pulse = false,
|
|
7228
7919
|
className
|
|
7229
|
-
}) => /* @__PURE__ */ (0,
|
|
7230
|
-
/* @__PURE__ */ (0,
|
|
7231
|
-
pulse ? /* @__PURE__ */ (0,
|
|
7920
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("span", { className: cn("inline-flex items-center gap-1.5", className), children: [
|
|
7921
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("span", { className: "relative flex size-2", children: [
|
|
7922
|
+
pulse ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
7232
7923
|
"span",
|
|
7233
7924
|
{
|
|
7234
7925
|
className: cn(
|
|
@@ -7237,25 +7928,25 @@ var StatusDot = ({
|
|
|
7237
7928
|
)
|
|
7238
7929
|
}
|
|
7239
7930
|
) : null,
|
|
7240
|
-
/* @__PURE__ */ (0,
|
|
7931
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { className: cn("relative inline-flex size-2 rounded-full", dotClass[tone]) })
|
|
7241
7932
|
] }),
|
|
7242
|
-
label ? /* @__PURE__ */ (0,
|
|
7933
|
+
label ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { className: "text-xs text-muted-foreground", children: label }) : null
|
|
7243
7934
|
] });
|
|
7244
7935
|
|
|
7245
7936
|
// src/app/surfaces/DescriptionList.tsx
|
|
7246
|
-
var
|
|
7937
|
+
var import_jsx_runtime68 = require("react/jsx-runtime");
|
|
7247
7938
|
var DescriptionList = ({
|
|
7248
7939
|
items,
|
|
7249
7940
|
stacked = false,
|
|
7250
7941
|
className
|
|
7251
|
-
}) => /* @__PURE__ */ (0,
|
|
7942
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
7252
7943
|
"dl",
|
|
7253
7944
|
{
|
|
7254
7945
|
className: cn(
|
|
7255
7946
|
"divide-y divide-border rounded-xl border border-border bg-card",
|
|
7256
7947
|
className
|
|
7257
7948
|
),
|
|
7258
|
-
children: items.map((item, i) => /* @__PURE__ */ (0,
|
|
7949
|
+
children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
|
|
7259
7950
|
"div",
|
|
7260
7951
|
{
|
|
7261
7952
|
className: cn(
|
|
@@ -7263,8 +7954,8 @@ var DescriptionList = ({
|
|
|
7263
7954
|
stacked ? "flex flex-col gap-0.5" : "flex items-center justify-between gap-4"
|
|
7264
7955
|
),
|
|
7265
7956
|
children: [
|
|
7266
|
-
/* @__PURE__ */ (0,
|
|
7267
|
-
/* @__PURE__ */ (0,
|
|
7957
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)("dt", { className: "text-sm text-muted-foreground", children: item.label }),
|
|
7958
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
7268
7959
|
"dd",
|
|
7269
7960
|
{
|
|
7270
7961
|
className: cn(
|
|
@@ -7284,8 +7975,8 @@ var DescriptionList = ({
|
|
|
7284
7975
|
// src/app/surfaces/ExpandableSection.tsx
|
|
7285
7976
|
var import_react58 = require("react");
|
|
7286
7977
|
var import_react59 = require("motion/react");
|
|
7287
|
-
var
|
|
7288
|
-
var Chevron = ({ open }) => /* @__PURE__ */ (0,
|
|
7978
|
+
var import_jsx_runtime69 = require("react/jsx-runtime");
|
|
7979
|
+
var Chevron = ({ open }) => /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
7289
7980
|
"svg",
|
|
7290
7981
|
{
|
|
7291
7982
|
viewBox: "0 0 24 24",
|
|
@@ -7299,7 +7990,7 @@ var Chevron = ({ open }) => /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
|
7299
7990
|
strokeLinecap: "round",
|
|
7300
7991
|
strokeLinejoin: "round",
|
|
7301
7992
|
"aria-hidden": true,
|
|
7302
|
-
children: /* @__PURE__ */ (0,
|
|
7993
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("path", { d: "m6 9 6 6 6-6" })
|
|
7303
7994
|
}
|
|
7304
7995
|
);
|
|
7305
7996
|
var ExpandableSection = ({
|
|
@@ -7320,8 +8011,8 @@ var ExpandableSection = ({
|
|
|
7320
8011
|
if (openProp == null) setInternalOpen((o) => !o);
|
|
7321
8012
|
onOpenChange?.(!open);
|
|
7322
8013
|
};
|
|
7323
|
-
return /* @__PURE__ */ (0,
|
|
7324
|
-
/* @__PURE__ */ (0,
|
|
8014
|
+
return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: cn("border-b border-border last:border-0", className), children: [
|
|
8015
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
|
|
7325
8016
|
"button",
|
|
7326
8017
|
{
|
|
7327
8018
|
type: "button",
|
|
@@ -7330,16 +8021,16 @@ var ExpandableSection = ({
|
|
|
7330
8021
|
"aria-controls": panelId,
|
|
7331
8022
|
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",
|
|
7332
8023
|
children: [
|
|
7333
|
-
/* @__PURE__ */ (0,
|
|
7334
|
-
icon ? /* @__PURE__ */ (0,
|
|
7335
|
-
/* @__PURE__ */ (0,
|
|
7336
|
-
count != null ? /* @__PURE__ */ (0,
|
|
8024
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("span", { className: "flex min-w-0 items-center gap-3", children: [
|
|
8025
|
+
icon ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "flex size-8 items-center justify-center rounded-lg border border-border bg-muted text-muted-foreground", children: icon }) : null,
|
|
8026
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "truncate text-sm font-medium text-foreground", children: title }),
|
|
8027
|
+
count != null ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "rounded-full border border-border bg-muted px-2 py-0.5 text-xs text-muted-foreground", children: count }) : null
|
|
7337
8028
|
] }),
|
|
7338
|
-
/* @__PURE__ */ (0,
|
|
8029
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(Chevron, { open })
|
|
7339
8030
|
]
|
|
7340
8031
|
}
|
|
7341
8032
|
),
|
|
7342
|
-
/* @__PURE__ */ (0,
|
|
8033
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_react59.AnimatePresence, { initial: false, children: open ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
7343
8034
|
import_react59.motion.div,
|
|
7344
8035
|
{
|
|
7345
8036
|
id: panelId,
|
|
@@ -7348,7 +8039,7 @@ var ExpandableSection = ({
|
|
|
7348
8039
|
exit: reduceMotion ? void 0 : { height: 0, opacity: 0 },
|
|
7349
8040
|
transition: { duration: 0.2, ease: "easeOut" },
|
|
7350
8041
|
className: "overflow-hidden",
|
|
7351
|
-
children: /* @__PURE__ */ (0,
|
|
8042
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "bg-muted/20", children })
|
|
7352
8043
|
},
|
|
7353
8044
|
"body"
|
|
7354
8045
|
) : null })
|
|
@@ -7356,7 +8047,7 @@ var ExpandableSection = ({
|
|
|
7356
8047
|
};
|
|
7357
8048
|
|
|
7358
8049
|
// src/app/surfaces/ResourceCard.tsx
|
|
7359
|
-
var
|
|
8050
|
+
var import_jsx_runtime70 = require("react/jsx-runtime");
|
|
7360
8051
|
var resourceCardShellClass = cn(
|
|
7361
8052
|
"flex min-h-[8.5rem] flex-col rounded-2xl p-4 text-left font-normal",
|
|
7362
8053
|
TIMBAL_V2_ELEVATED_SURFACE
|
|
@@ -7381,35 +8072,35 @@ var ResourceCard = ({
|
|
|
7381
8072
|
ariaLabel,
|
|
7382
8073
|
className
|
|
7383
8074
|
}) => {
|
|
7384
|
-
const body = /* @__PURE__ */ (0,
|
|
7385
|
-
/* @__PURE__ */ (0,
|
|
7386
|
-
media ? /* @__PURE__ */ (0,
|
|
7387
|
-
/* @__PURE__ */ (0,
|
|
7388
|
-
/* @__PURE__ */ (0,
|
|
7389
|
-
subtitle ? /* @__PURE__ */ (0,
|
|
8075
|
+
const body = /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(import_jsx_runtime70.Fragment, { children: [
|
|
8076
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { className: "flex items-start gap-3", children: [
|
|
8077
|
+
media ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("span", { className: mediaShellClass, children: media }) : null,
|
|
8078
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { className: "min-w-0 flex-1 pt-0.5", children: [
|
|
8079
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)("p", { className: "truncate text-sm font-normal leading-snug text-foreground", children: title }),
|
|
8080
|
+
subtitle ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("p", { className: "mt-1 line-clamp-2 text-xs font-normal text-muted-foreground", children: subtitle }) : null
|
|
7390
8081
|
] }),
|
|
7391
|
-
badge ? /* @__PURE__ */ (0,
|
|
8082
|
+
badge ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("span", { className: "shrink-0 pt-0.5", children: badge }) : null
|
|
7392
8083
|
] }),
|
|
7393
|
-
footer || action ? /* @__PURE__ */ (0,
|
|
7394
|
-
/* @__PURE__ */ (0,
|
|
7395
|
-
action ? /* @__PURE__ */ (0,
|
|
8084
|
+
footer || action ? /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { className: "mt-auto flex items-center justify-between gap-3 border-t border-border/40 pt-3 text-xs font-normal text-muted-foreground", children: [
|
|
8085
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)("span", { className: "min-w-0 truncate", children: footer }),
|
|
8086
|
+
action ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("span", { className: "shrink-0 opacity-80", children: action }) : null
|
|
7396
8087
|
] }) : null
|
|
7397
8088
|
] });
|
|
7398
8089
|
if (onClick) {
|
|
7399
|
-
return /* @__PURE__ */ (0,
|
|
8090
|
+
return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("button", { type: "button", onClick, "aria-label": ariaLabel, className: cn(resourceCardInteractiveClass, className), children: body });
|
|
7400
8091
|
}
|
|
7401
|
-
return /* @__PURE__ */ (0,
|
|
8092
|
+
return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("article", { className: cn(resourceCardShellClass, className), children: body });
|
|
7402
8093
|
};
|
|
7403
8094
|
|
|
7404
8095
|
// src/app/settings/SettingsSection.tsx
|
|
7405
|
-
var
|
|
8096
|
+
var import_jsx_runtime71 = require("react/jsx-runtime");
|
|
7406
8097
|
var SettingsSectionHeader = ({
|
|
7407
8098
|
title,
|
|
7408
8099
|
description,
|
|
7409
8100
|
className
|
|
7410
|
-
}) => /* @__PURE__ */ (0,
|
|
7411
|
-
/* @__PURE__ */ (0,
|
|
7412
|
-
description ? /* @__PURE__ */ (0,
|
|
8101
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: cn("flex flex-col", className), children: [
|
|
8102
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)("h3", { className: "text-[17px] font-medium leading-tight text-foreground", children: title }),
|
|
8103
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null
|
|
7413
8104
|
] });
|
|
7414
8105
|
var SettingsSection = ({
|
|
7415
8106
|
title,
|
|
@@ -7418,7 +8109,7 @@ var SettingsSection = ({
|
|
|
7418
8109
|
children,
|
|
7419
8110
|
noBorderTop = false,
|
|
7420
8111
|
className
|
|
7421
|
-
}) => /* @__PURE__ */ (0,
|
|
8112
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(
|
|
7422
8113
|
"section",
|
|
7423
8114
|
{
|
|
7424
8115
|
className: cn(
|
|
@@ -7427,18 +8118,18 @@ var SettingsSection = ({
|
|
|
7427
8118
|
className
|
|
7428
8119
|
),
|
|
7429
8120
|
children: [
|
|
7430
|
-
/* @__PURE__ */ (0,
|
|
7431
|
-
/* @__PURE__ */ (0,
|
|
7432
|
-
description ? /* @__PURE__ */ (0,
|
|
7433
|
-
descriptionFooter ? /* @__PURE__ */ (0,
|
|
8121
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "min-w-0", children: [
|
|
8122
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)("h2", { className: "text-sm font-medium text-foreground", children: title }),
|
|
8123
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("p", { className: "mt-1 text-sm text-muted-foreground", children: description }) : null,
|
|
8124
|
+
descriptionFooter ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "mt-3 min-w-0", children: descriptionFooter }) : null
|
|
7434
8125
|
] }),
|
|
7435
|
-
/* @__PURE__ */ (0,
|
|
8126
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "min-w-0 space-y-3", children })
|
|
7436
8127
|
]
|
|
7437
8128
|
}
|
|
7438
8129
|
);
|
|
7439
8130
|
|
|
7440
8131
|
// src/app/settings/FieldRow.tsx
|
|
7441
|
-
var
|
|
8132
|
+
var import_jsx_runtime72 = require("react/jsx-runtime");
|
|
7442
8133
|
var FieldRow = ({
|
|
7443
8134
|
label,
|
|
7444
8135
|
children,
|
|
@@ -7448,7 +8139,7 @@ var FieldRow = ({
|
|
|
7448
8139
|
className
|
|
7449
8140
|
}) => {
|
|
7450
8141
|
if (inline) {
|
|
7451
|
-
return /* @__PURE__ */ (0,
|
|
8142
|
+
return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(
|
|
7452
8143
|
"div",
|
|
7453
8144
|
{
|
|
7454
8145
|
className: cn(
|
|
@@ -7456,8 +8147,8 @@ var FieldRow = ({
|
|
|
7456
8147
|
className
|
|
7457
8148
|
),
|
|
7458
8149
|
children: [
|
|
7459
|
-
/* @__PURE__ */ (0,
|
|
7460
|
-
/* @__PURE__ */ (0,
|
|
8150
|
+
/* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "min-w-0", children: [
|
|
8151
|
+
/* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
7461
8152
|
"label",
|
|
7462
8153
|
{
|
|
7463
8154
|
htmlFor,
|
|
@@ -7465,17 +8156,17 @@ var FieldRow = ({
|
|
|
7465
8156
|
children: label
|
|
7466
8157
|
}
|
|
7467
8158
|
),
|
|
7468
|
-
description ? /* @__PURE__ */ (0,
|
|
8159
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("p", { className: "mt-0.5 text-xs text-muted-foreground", children: description }) : null
|
|
7469
8160
|
] }),
|
|
7470
|
-
/* @__PURE__ */ (0,
|
|
8161
|
+
/* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "shrink-0", children })
|
|
7471
8162
|
]
|
|
7472
8163
|
}
|
|
7473
8164
|
);
|
|
7474
8165
|
}
|
|
7475
|
-
return /* @__PURE__ */ (0,
|
|
7476
|
-
/* @__PURE__ */ (0,
|
|
8166
|
+
return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: cn("flex flex-col gap-1.5", className), children: [
|
|
8167
|
+
/* @__PURE__ */ (0, import_jsx_runtime72.jsx)("label", { htmlFor, className: "text-sm font-medium text-foreground", children: label }),
|
|
7477
8168
|
children,
|
|
7478
|
-
description ? /* @__PURE__ */ (0,
|
|
8169
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("p", { className: "text-xs text-muted-foreground", children: description }) : null
|
|
7479
8170
|
] });
|
|
7480
8171
|
};
|
|
7481
8172
|
|
|
@@ -7483,7 +8174,7 @@ var FieldRow = ({
|
|
|
7483
8174
|
var import_react60 = require("react");
|
|
7484
8175
|
var import_react_dom2 = require("react-dom");
|
|
7485
8176
|
var import_react61 = require("motion/react");
|
|
7486
|
-
var
|
|
8177
|
+
var import_jsx_runtime73 = require("react/jsx-runtime");
|
|
7487
8178
|
var FloatingUnsavedChangesBar = ({
|
|
7488
8179
|
visible,
|
|
7489
8180
|
message = "Unsaved changes",
|
|
@@ -7501,7 +8192,7 @@ var FloatingUnsavedChangesBar = ({
|
|
|
7501
8192
|
(0, import_react60.useEffect)(() => setMounted(true), []);
|
|
7502
8193
|
if (!mounted || typeof document === "undefined") return null;
|
|
7503
8194
|
return (0, import_react_dom2.createPortal)(
|
|
7504
|
-
/* @__PURE__ */ (0,
|
|
8195
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)(import_react61.AnimatePresence, { children: visible ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "pointer-events-none fixed inset-x-0 bottom-5 z-50 flex justify-center px-4", children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
|
|
7505
8196
|
import_react61.motion.div,
|
|
7506
8197
|
{
|
|
7507
8198
|
role: "region",
|
|
@@ -7515,10 +8206,10 @@ var FloatingUnsavedChangesBar = ({
|
|
|
7515
8206
|
className
|
|
7516
8207
|
),
|
|
7517
8208
|
children: [
|
|
7518
|
-
/* @__PURE__ */ (0,
|
|
7519
|
-
/* @__PURE__ */ (0,
|
|
7520
|
-
/* @__PURE__ */ (0,
|
|
7521
|
-
/* @__PURE__ */ (0,
|
|
8209
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "text-sm text-muted-foreground", children: message }),
|
|
8210
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("span", { className: "flex items-center gap-1.5", children: [
|
|
8211
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)(Button, { variant: "ghost", size: "sm", onClick: onDiscard, disabled: isSaving, children: discardLabel }),
|
|
8212
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)(Button, { size: "sm", onClick: onSave, disabled: saveDisabled || isSaving, children: isSaving ? "Saving\u2026" : saveLabel })
|
|
7522
8213
|
] })
|
|
7523
8214
|
]
|
|
7524
8215
|
}
|
|
@@ -7528,13 +8219,13 @@ var FloatingUnsavedChangesBar = ({
|
|
|
7528
8219
|
};
|
|
7529
8220
|
|
|
7530
8221
|
// src/app/settings/DangerZone.tsx
|
|
7531
|
-
var
|
|
8222
|
+
var import_jsx_runtime74 = require("react/jsx-runtime");
|
|
7532
8223
|
var DangerZoneAction = ({
|
|
7533
8224
|
title,
|
|
7534
8225
|
description,
|
|
7535
8226
|
action,
|
|
7536
8227
|
className
|
|
7537
|
-
}) => /* @__PURE__ */ (0,
|
|
8228
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(
|
|
7538
8229
|
"div",
|
|
7539
8230
|
{
|
|
7540
8231
|
className: cn(
|
|
@@ -7542,11 +8233,11 @@ var DangerZoneAction = ({
|
|
|
7542
8233
|
className
|
|
7543
8234
|
),
|
|
7544
8235
|
children: [
|
|
7545
|
-
/* @__PURE__ */ (0,
|
|
7546
|
-
/* @__PURE__ */ (0,
|
|
7547
|
-
description ? /* @__PURE__ */ (0,
|
|
8236
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "min-w-0", children: [
|
|
8237
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)("p", { className: "text-sm font-medium text-foreground", children: title }),
|
|
8238
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
|
|
7548
8239
|
] }),
|
|
7549
|
-
/* @__PURE__ */ (0,
|
|
8240
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "shrink-0", children: action })
|
|
7550
8241
|
]
|
|
7551
8242
|
}
|
|
7552
8243
|
);
|
|
@@ -7555,7 +8246,7 @@ var DangerZone = ({
|
|
|
7555
8246
|
description,
|
|
7556
8247
|
children,
|
|
7557
8248
|
className
|
|
7558
|
-
}) => /* @__PURE__ */ (0,
|
|
8249
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(
|
|
7559
8250
|
"section",
|
|
7560
8251
|
{
|
|
7561
8252
|
className: cn(
|
|
@@ -7563,18 +8254,18 @@ var DangerZone = ({
|
|
|
7563
8254
|
className
|
|
7564
8255
|
),
|
|
7565
8256
|
children: [
|
|
7566
|
-
(title || description) && /* @__PURE__ */ (0,
|
|
7567
|
-
title ? /* @__PURE__ */ (0,
|
|
7568
|
-
description ? /* @__PURE__ */ (0,
|
|
8257
|
+
(title || description) && /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("header", { className: "border-b border-destructive/20 bg-destructive/5 px-4 py-3", children: [
|
|
8258
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("h3", { className: "text-sm font-semibold text-destructive", children: title }) : null,
|
|
8259
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
|
|
7569
8260
|
] }),
|
|
7570
|
-
/* @__PURE__ */ (0,
|
|
8261
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "divide-y divide-border bg-card", children })
|
|
7571
8262
|
]
|
|
7572
8263
|
}
|
|
7573
8264
|
);
|
|
7574
8265
|
|
|
7575
8266
|
// src/app/integrations/IntegrationCard.tsx
|
|
7576
8267
|
var import_react62 = require("react");
|
|
7577
|
-
var
|
|
8268
|
+
var import_jsx_runtime75 = require("react/jsx-runtime");
|
|
7578
8269
|
var INTEGRATION_CATALOG_CARD_HEIGHT_CLASS = "h-[12.25rem] min-h-[12.25rem] max-h-[12.25rem]";
|
|
7579
8270
|
var statusLabel = {
|
|
7580
8271
|
available: null,
|
|
@@ -7615,12 +8306,12 @@ var IntegrationCard = ({
|
|
|
7615
8306
|
const titleId = (0, import_react62.useId)();
|
|
7616
8307
|
const locked = status === "locked";
|
|
7617
8308
|
const dimmed = status === "disabled" || locked;
|
|
7618
|
-
const body = /* @__PURE__ */ (0,
|
|
7619
|
-
/* @__PURE__ */ (0,
|
|
7620
|
-
logo ? /* @__PURE__ */ (0,
|
|
7621
|
-
/* @__PURE__ */ (0,
|
|
7622
|
-
/* @__PURE__ */ (0,
|
|
7623
|
-
/* @__PURE__ */ (0,
|
|
8309
|
+
const body = /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "flex h-full min-h-0 flex-col", children: [
|
|
8310
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "flex shrink-0 items-start gap-3 pr-2", children: [
|
|
8311
|
+
logo ? /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { className: logoShellClass, "aria-hidden": Boolean(ariaLabel), children: logo }) : null,
|
|
8312
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)("div", { className: "min-w-0 flex-1 pt-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "flex items-start justify-between gap-2", children: [
|
|
8313
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "min-w-0", children: [
|
|
8314
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
|
|
7624
8315
|
"h4",
|
|
7625
8316
|
{
|
|
7626
8317
|
id: onClick && !action ? void 0 : titleId,
|
|
@@ -7628,12 +8319,12 @@ var IntegrationCard = ({
|
|
|
7628
8319
|
children: name
|
|
7629
8320
|
}
|
|
7630
8321
|
),
|
|
7631
|
-
statusLabel[status] ? /* @__PURE__ */ (0,
|
|
8322
|
+
statusLabel[status] ? /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("p", { className: "mt-0.5 text-xs text-muted-foreground", children: statusLabel[status] }) : null
|
|
7632
8323
|
] }),
|
|
7633
|
-
badge ? /* @__PURE__ */ (0,
|
|
8324
|
+
badge ? /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { className: "shrink-0", children: badge }) : null
|
|
7634
8325
|
] }) })
|
|
7635
8326
|
] }),
|
|
7636
|
-
description ? /* @__PURE__ */ (0,
|
|
8327
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
|
|
7637
8328
|
"p",
|
|
7638
8329
|
{
|
|
7639
8330
|
className: cn(
|
|
@@ -7643,9 +8334,9 @@ var IntegrationCard = ({
|
|
|
7643
8334
|
children: description
|
|
7644
8335
|
}
|
|
7645
8336
|
) : null,
|
|
7646
|
-
action ? /* @__PURE__ */ (0,
|
|
7647
|
-
/* @__PURE__ */ (0,
|
|
7648
|
-
/* @__PURE__ */ (0,
|
|
8337
|
+
action ? /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)(import_jsx_runtime75.Fragment, { children: [
|
|
8338
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)("div", { className: "min-h-0 flex-1", "aria-hidden": true }),
|
|
8339
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)("div", { className: "relative mt-3 shrink-0", children: action })
|
|
7649
8340
|
] }) : null
|
|
7650
8341
|
] });
|
|
7651
8342
|
const shellClass3 = cn(
|
|
@@ -7655,7 +8346,7 @@ var IntegrationCard = ({
|
|
|
7655
8346
|
className
|
|
7656
8347
|
);
|
|
7657
8348
|
if (onClick && !action) {
|
|
7658
|
-
return /* @__PURE__ */ (0,
|
|
8349
|
+
return /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
|
|
7659
8350
|
"button",
|
|
7660
8351
|
{
|
|
7661
8352
|
type: "button",
|
|
@@ -7672,12 +8363,12 @@ var IntegrationCard = ({
|
|
|
7672
8363
|
}
|
|
7673
8364
|
);
|
|
7674
8365
|
}
|
|
7675
|
-
return /* @__PURE__ */ (0,
|
|
8366
|
+
return /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("article", { className: shellClass3, "aria-labelledby": titleId, children: body });
|
|
7676
8367
|
};
|
|
7677
8368
|
|
|
7678
8369
|
// src/app/integrations/IntegrationsEmptyState.tsx
|
|
7679
8370
|
var import_react63 = require("react");
|
|
7680
|
-
var
|
|
8371
|
+
var import_jsx_runtime76 = require("react/jsx-runtime");
|
|
7681
8372
|
var IntegrationsEmptyState = ({
|
|
7682
8373
|
title = "No integrations yet",
|
|
7683
8374
|
description = "Connect a provider to start syncing data and powering your workforce.",
|
|
@@ -7686,7 +8377,7 @@ var IntegrationsEmptyState = ({
|
|
|
7686
8377
|
className
|
|
7687
8378
|
}) => {
|
|
7688
8379
|
const titleId = (0, import_react63.useId)();
|
|
7689
|
-
return /* @__PURE__ */ (0,
|
|
8380
|
+
return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
|
|
7690
8381
|
"section",
|
|
7691
8382
|
{
|
|
7692
8383
|
className: cn(
|
|
@@ -7696,7 +8387,7 @@ var IntegrationsEmptyState = ({
|
|
|
7696
8387
|
),
|
|
7697
8388
|
"aria-labelledby": titleId,
|
|
7698
8389
|
children: [
|
|
7699
|
-
icon ? /* @__PURE__ */ (0,
|
|
8390
|
+
icon ? /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
|
|
7700
8391
|
"span",
|
|
7701
8392
|
{
|
|
7702
8393
|
className: cn(
|
|
@@ -7708,21 +8399,21 @@ var IntegrationsEmptyState = ({
|
|
|
7708
8399
|
children: icon
|
|
7709
8400
|
}
|
|
7710
8401
|
) : null,
|
|
7711
|
-
/* @__PURE__ */ (0,
|
|
7712
|
-
description ? /* @__PURE__ */ (0,
|
|
7713
|
-
action ? /* @__PURE__ */ (0,
|
|
8402
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)("h3", { id: titleId, className: "text-base font-normal text-foreground", children: title }),
|
|
8403
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("p", { className: "max-w-sm text-sm text-muted-foreground", children: description }) : null,
|
|
8404
|
+
action ? /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: "mt-1", children: action }) : null
|
|
7714
8405
|
]
|
|
7715
8406
|
}
|
|
7716
8407
|
);
|
|
7717
8408
|
};
|
|
7718
8409
|
|
|
7719
8410
|
// src/app/integrations/PlanBadge.tsx
|
|
7720
|
-
var
|
|
8411
|
+
var import_jsx_runtime77 = require("react/jsx-runtime");
|
|
7721
8412
|
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";
|
|
7722
|
-
var PlanBadge = ({ children, className }) => /* @__PURE__ */ (0,
|
|
8413
|
+
var PlanBadge = ({ children, className }) => /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("span", { className: cn(planBadgeClass, className), children });
|
|
7723
8414
|
|
|
7724
8415
|
// src/app/integrations/ConnectionRow.tsx
|
|
7725
|
-
var
|
|
8416
|
+
var import_jsx_runtime78 = require("react/jsx-runtime");
|
|
7726
8417
|
var logoShellClass2 = cn(
|
|
7727
8418
|
"flex size-9 shrink-0 items-center justify-center overflow-hidden rounded-lg",
|
|
7728
8419
|
TIMBAL_V2_LOGO_TILE
|
|
@@ -7737,14 +8428,14 @@ var ConnectionRow = ({
|
|
|
7737
8428
|
ariaLabel,
|
|
7738
8429
|
className
|
|
7739
8430
|
}) => {
|
|
7740
|
-
const inner = /* @__PURE__ */ (0,
|
|
7741
|
-
logo ? /* @__PURE__ */ (0,
|
|
7742
|
-
/* @__PURE__ */ (0,
|
|
7743
|
-
/* @__PURE__ */ (0,
|
|
7744
|
-
meta ? /* @__PURE__ */ (0,
|
|
8431
|
+
const inner = /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(import_jsx_runtime78.Fragment, { children: [
|
|
8432
|
+
logo ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: logoShellClass2, children: logo }) : null,
|
|
8433
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
8434
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("p", { className: "truncate text-sm font-normal text-foreground", children: name }),
|
|
8435
|
+
meta ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("p", { className: "truncate text-xs text-muted-foreground", children: meta }) : null
|
|
7745
8436
|
] }),
|
|
7746
|
-
badge ? /* @__PURE__ */ (0,
|
|
7747
|
-
action ? /* @__PURE__ */ (0,
|
|
8437
|
+
badge ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "shrink-0", children: badge }) : null,
|
|
8438
|
+
action ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "shrink-0", children: action }) : null
|
|
7748
8439
|
] });
|
|
7749
8440
|
const rowClass2 = cn(
|
|
7750
8441
|
"flex w-full items-center gap-3 px-4 py-3 text-left",
|
|
@@ -7752,7 +8443,7 @@ var ConnectionRow = ({
|
|
|
7752
8443
|
className
|
|
7753
8444
|
);
|
|
7754
8445
|
if (onClick) {
|
|
7755
|
-
return /* @__PURE__ */ (0,
|
|
8446
|
+
return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
|
|
7756
8447
|
"button",
|
|
7757
8448
|
{
|
|
7758
8449
|
type: "button",
|
|
@@ -7764,7 +8455,7 @@ var ConnectionRow = ({
|
|
|
7764
8455
|
}
|
|
7765
8456
|
);
|
|
7766
8457
|
}
|
|
7767
|
-
return /* @__PURE__ */ (0,
|
|
8458
|
+
return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { role: "listitem", className: rowClass2, children: inner });
|
|
7768
8459
|
};
|
|
7769
8460
|
var connectionRowListClass = cn(
|
|
7770
8461
|
"overflow-hidden rounded-2xl",
|
|
@@ -7772,12 +8463,12 @@ var connectionRowListClass = cn(
|
|
|
7772
8463
|
);
|
|
7773
8464
|
|
|
7774
8465
|
// src/app/integrations/ConnectionRowList.tsx
|
|
7775
|
-
var
|
|
8466
|
+
var import_jsx_runtime79 = require("react/jsx-runtime");
|
|
7776
8467
|
var ConnectionRowList = ({
|
|
7777
8468
|
children,
|
|
7778
8469
|
"aria-label": ariaLabel = "Connected integrations",
|
|
7779
8470
|
className
|
|
7780
|
-
}) => /* @__PURE__ */ (0,
|
|
8471
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
|
|
7781
8472
|
"div",
|
|
7782
8473
|
{
|
|
7783
8474
|
role: "list",
|
|
@@ -7788,7 +8479,7 @@ var ConnectionRowList = ({
|
|
|
7788
8479
|
);
|
|
7789
8480
|
|
|
7790
8481
|
// src/app/navigation/SubNav.tsx
|
|
7791
|
-
var
|
|
8482
|
+
var import_jsx_runtime80 = require("react/jsx-runtime");
|
|
7792
8483
|
var SubNav = ({
|
|
7793
8484
|
items,
|
|
7794
8485
|
activeId,
|
|
@@ -7797,7 +8488,7 @@ var SubNav = ({
|
|
|
7797
8488
|
"aria-label": ariaLabel = "Section navigation",
|
|
7798
8489
|
layoutId
|
|
7799
8490
|
}) => {
|
|
7800
|
-
return /* @__PURE__ */ (0,
|
|
8491
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("nav", { className: cn("aui-app-sub-nav", className), "aria-label": ariaLabel, children: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
|
|
7801
8492
|
PillSegmentedTabs,
|
|
7802
8493
|
{
|
|
7803
8494
|
value: activeId,
|
|
@@ -7811,13 +8502,13 @@ var SubNav = ({
|
|
|
7811
8502
|
};
|
|
7812
8503
|
|
|
7813
8504
|
// src/app/navigation/Breadcrumbs.tsx
|
|
7814
|
-
var
|
|
8505
|
+
var import_jsx_runtime81 = require("react/jsx-runtime");
|
|
7815
8506
|
var Breadcrumbs = ({ items, className }) => {
|
|
7816
|
-
return /* @__PURE__ */ (0,
|
|
8507
|
+
return /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("nav", { className: cn("aui-app-breadcrumbs", appBreadcrumbsClass, className), "aria-label": "Breadcrumb", children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("ol", { className: "flex flex-wrap items-center gap-1.5", children: items.map((item, index) => {
|
|
7817
8508
|
const isLast = index === items.length - 1;
|
|
7818
|
-
return /* @__PURE__ */ (0,
|
|
7819
|
-
index > 0 ? /* @__PURE__ */ (0,
|
|
7820
|
-
isLast ? /* @__PURE__ */ (0,
|
|
8509
|
+
return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("li", { className: "inline-flex items-center gap-1.5", children: [
|
|
8510
|
+
index > 0 ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("span", { className: "text-muted-foreground/50", "aria-hidden": true, children: "/" }) : null,
|
|
8511
|
+
isLast ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("span", { className: "text-foreground", "aria-current": "page", children: item.label }) : item.href ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("a", { href: item.href, className: appBreadcrumbLinkClass, children: item.label }) : /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
|
|
7821
8512
|
"button",
|
|
7822
8513
|
{
|
|
7823
8514
|
type: "button",
|
|
@@ -7831,7 +8522,7 @@ var Breadcrumbs = ({ items, className }) => {
|
|
|
7831
8522
|
};
|
|
7832
8523
|
|
|
7833
8524
|
// src/app/forms/Field.tsx
|
|
7834
|
-
var
|
|
8525
|
+
var import_jsx_runtime82 = require("react/jsx-runtime");
|
|
7835
8526
|
var Field = ({
|
|
7836
8527
|
label,
|
|
7837
8528
|
hint,
|
|
@@ -7840,11 +8531,11 @@ var Field = ({
|
|
|
7840
8531
|
className,
|
|
7841
8532
|
htmlFor
|
|
7842
8533
|
}) => {
|
|
7843
|
-
return /* @__PURE__ */ (0,
|
|
7844
|
-
/* @__PURE__ */ (0,
|
|
8534
|
+
return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: cn("aui-app-field", appFieldClass, className), children: [
|
|
8535
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("label", { className: appFieldLabelClass, htmlFor, children: label }),
|
|
7845
8536
|
children,
|
|
7846
|
-
hint && !error ? /* @__PURE__ */ (0,
|
|
7847
|
-
error ? /* @__PURE__ */ (0,
|
|
8537
|
+
hint && !error ? /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("p", { className: appFieldHintClass, children: hint }) : null,
|
|
8538
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("p", { className: "text-xs text-destructive", role: "alert", children: error }) : null
|
|
7848
8539
|
] });
|
|
7849
8540
|
};
|
|
7850
8541
|
var FieldInput = ({
|
|
@@ -7857,7 +8548,7 @@ var FieldInput = ({
|
|
|
7857
8548
|
...inputProps
|
|
7858
8549
|
}) => {
|
|
7859
8550
|
const inputId = id ?? inputProps.name;
|
|
7860
|
-
return /* @__PURE__ */ (0,
|
|
8551
|
+
return /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
7861
8552
|
Field,
|
|
7862
8553
|
{
|
|
7863
8554
|
label,
|
|
@@ -7865,7 +8556,7 @@ var FieldInput = ({
|
|
|
7865
8556
|
error,
|
|
7866
8557
|
htmlFor: inputId,
|
|
7867
8558
|
className: fieldClassName,
|
|
7868
|
-
children: /* @__PURE__ */ (0,
|
|
8559
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
7869
8560
|
"input",
|
|
7870
8561
|
{
|
|
7871
8562
|
id: inputId,
|
|
@@ -7879,7 +8570,7 @@ var FieldInput = ({
|
|
|
7879
8570
|
};
|
|
7880
8571
|
|
|
7881
8572
|
// src/app/forms/FieldTextarea.tsx
|
|
7882
|
-
var
|
|
8573
|
+
var import_jsx_runtime83 = require("react/jsx-runtime");
|
|
7883
8574
|
var textareaClass = cn(
|
|
7884
8575
|
appInputClass,
|
|
7885
8576
|
"min-h-[5.5rem] resize-y py-2.5 leading-relaxed"
|
|
@@ -7894,7 +8585,7 @@ var FieldTextarea = ({
|
|
|
7894
8585
|
...props
|
|
7895
8586
|
}) => {
|
|
7896
8587
|
const textareaId = id ?? props.name;
|
|
7897
|
-
return /* @__PURE__ */ (0,
|
|
8588
|
+
return /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
|
|
7898
8589
|
Field,
|
|
7899
8590
|
{
|
|
7900
8591
|
label,
|
|
@@ -7902,7 +8593,7 @@ var FieldTextarea = ({
|
|
|
7902
8593
|
error,
|
|
7903
8594
|
htmlFor: textareaId,
|
|
7904
8595
|
className: fieldClassName,
|
|
7905
|
-
children: /* @__PURE__ */ (0,
|
|
8596
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
|
|
7906
8597
|
"textarea",
|
|
7907
8598
|
{
|
|
7908
8599
|
id: textareaId,
|
|
@@ -7917,7 +8608,7 @@ var FieldTextarea = ({
|
|
|
7917
8608
|
|
|
7918
8609
|
// src/app/forms/FieldSelect.tsx
|
|
7919
8610
|
var import_lucide_react16 = require("lucide-react");
|
|
7920
|
-
var
|
|
8611
|
+
var import_jsx_runtime84 = require("react/jsx-runtime");
|
|
7921
8612
|
var selectWrapClass = "relative";
|
|
7922
8613
|
var selectClass = cn(
|
|
7923
8614
|
appInputClass,
|
|
@@ -7934,7 +8625,7 @@ var FieldSelect = ({
|
|
|
7934
8625
|
...props
|
|
7935
8626
|
}) => {
|
|
7936
8627
|
const selectId = id ?? props.name;
|
|
7937
|
-
return /* @__PURE__ */ (0,
|
|
8628
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
7938
8629
|
Field,
|
|
7939
8630
|
{
|
|
7940
8631
|
label,
|
|
@@ -7942,8 +8633,8 @@ var FieldSelect = ({
|
|
|
7942
8633
|
error,
|
|
7943
8634
|
htmlFor: selectId,
|
|
7944
8635
|
className: fieldClassName,
|
|
7945
|
-
children: /* @__PURE__ */ (0,
|
|
7946
|
-
/* @__PURE__ */ (0,
|
|
8636
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: selectWrapClass, children: [
|
|
8637
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
7947
8638
|
"select",
|
|
7948
8639
|
{
|
|
7949
8640
|
id: selectId,
|
|
@@ -7953,7 +8644,7 @@ var FieldSelect = ({
|
|
|
7953
8644
|
children
|
|
7954
8645
|
}
|
|
7955
8646
|
),
|
|
7956
|
-
/* @__PURE__ */ (0,
|
|
8647
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
7957
8648
|
import_lucide_react16.ChevronDownIcon,
|
|
7958
8649
|
{
|
|
7959
8650
|
className: "pointer-events-none absolute top-1/2 right-3 size-4 -translate-y-1/2 text-muted-foreground",
|
|
@@ -7966,7 +8657,7 @@ var FieldSelect = ({
|
|
|
7966
8657
|
};
|
|
7967
8658
|
|
|
7968
8659
|
// src/app/forms/FieldSwitch.tsx
|
|
7969
|
-
var
|
|
8660
|
+
var import_jsx_runtime85 = require("react/jsx-runtime");
|
|
7970
8661
|
var trackClass = cn(
|
|
7971
8662
|
"relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-[background,box-shadow,border-color] duration-200",
|
|
7972
8663
|
"peer-focus-visible:ring-2 peer-focus-visible:ring-foreground/10",
|
|
@@ -7987,7 +8678,7 @@ var FieldSwitch = ({
|
|
|
7987
8678
|
...props
|
|
7988
8679
|
}) => {
|
|
7989
8680
|
const inputId = id ?? props.name ?? "switch";
|
|
7990
|
-
return /* @__PURE__ */ (0,
|
|
8681
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(
|
|
7991
8682
|
"label",
|
|
7992
8683
|
{
|
|
7993
8684
|
className: cn(
|
|
@@ -7996,8 +8687,8 @@ var FieldSwitch = ({
|
|
|
7996
8687
|
),
|
|
7997
8688
|
htmlFor: inputId,
|
|
7998
8689
|
children: [
|
|
7999
|
-
/* @__PURE__ */ (0,
|
|
8000
|
-
/* @__PURE__ */ (0,
|
|
8690
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("span", { className: "relative mt-0.5", children: [
|
|
8691
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
|
|
8001
8692
|
"input",
|
|
8002
8693
|
{
|
|
8003
8694
|
id: inputId,
|
|
@@ -8007,11 +8698,11 @@ var FieldSwitch = ({
|
|
|
8007
8698
|
...props
|
|
8008
8699
|
}
|
|
8009
8700
|
),
|
|
8010
|
-
/* @__PURE__ */ (0,
|
|
8701
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: trackClass, "aria-hidden": true, children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: thumbClass }) })
|
|
8011
8702
|
] }),
|
|
8012
|
-
/* @__PURE__ */ (0,
|
|
8013
|
-
/* @__PURE__ */ (0,
|
|
8014
|
-
description ? /* @__PURE__ */ (0,
|
|
8703
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("span", { className: "flex min-w-0 flex-col gap-0.5", children: [
|
|
8704
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "text-sm font-medium text-foreground", children: label }),
|
|
8705
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "text-xs text-muted-foreground", children: description }) : null
|
|
8015
8706
|
] })
|
|
8016
8707
|
]
|
|
8017
8708
|
}
|
|
@@ -8020,13 +8711,13 @@ var FieldSwitch = ({
|
|
|
8020
8711
|
|
|
8021
8712
|
// src/app/forms/SearchInput.tsx
|
|
8022
8713
|
var import_lucide_react17 = require("lucide-react");
|
|
8023
|
-
var
|
|
8714
|
+
var import_jsx_runtime86 = require("react/jsx-runtime");
|
|
8024
8715
|
var SearchInput = ({
|
|
8025
8716
|
className,
|
|
8026
8717
|
placeholder = "Search\u2026",
|
|
8027
8718
|
...props
|
|
8028
8719
|
}) => {
|
|
8029
|
-
return /* @__PURE__ */ (0,
|
|
8720
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(
|
|
8030
8721
|
"label",
|
|
8031
8722
|
{
|
|
8032
8723
|
className: cn(
|
|
@@ -8035,8 +8726,8 @@ var SearchInput = ({
|
|
|
8035
8726
|
className
|
|
8036
8727
|
),
|
|
8037
8728
|
children: [
|
|
8038
|
-
/* @__PURE__ */ (0,
|
|
8039
|
-
/* @__PURE__ */ (0,
|
|
8729
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)(import_lucide_react17.SearchIcon, { className: "size-4 shrink-0 text-muted-foreground", "aria-hidden": true }),
|
|
8730
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
|
|
8040
8731
|
"input",
|
|
8041
8732
|
{
|
|
8042
8733
|
type: "search",
|
|
@@ -8051,18 +8742,18 @@ var SearchInput = ({
|
|
|
8051
8742
|
};
|
|
8052
8743
|
|
|
8053
8744
|
// src/app/forms/FormSection.tsx
|
|
8054
|
-
var
|
|
8745
|
+
var import_jsx_runtime87 = require("react/jsx-runtime");
|
|
8055
8746
|
var FormSection = ({ title, children, className }) => {
|
|
8056
|
-
return /* @__PURE__ */ (0,
|
|
8057
|
-
title ? /* @__PURE__ */ (0,
|
|
8058
|
-
/* @__PURE__ */ (0,
|
|
8747
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("fieldset", { className: cn("aui-app-form-section", appSectionClass, "border-0 p-0", className), children: [
|
|
8748
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("legend", { className: cn(appSectionTitleClass, "mb-3 px-0"), children: title }) : null,
|
|
8749
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("div", { className: "flex flex-col gap-4", children })
|
|
8059
8750
|
] });
|
|
8060
8751
|
};
|
|
8061
8752
|
|
|
8062
8753
|
// src/app/data/FilterBar.tsx
|
|
8063
|
-
var
|
|
8754
|
+
var import_jsx_runtime88 = require("react/jsx-runtime");
|
|
8064
8755
|
var FilterBar = ({ children, className }) => {
|
|
8065
|
-
return /* @__PURE__ */ (0,
|
|
8756
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
8066
8757
|
"div",
|
|
8067
8758
|
{
|
|
8068
8759
|
className: cn("aui-app-filter-bar", appFilterBarClass, className),
|
|
@@ -8076,7 +8767,7 @@ var FilterBar = ({ children, className }) => {
|
|
|
8076
8767
|
// src/app/data/DataTable.tsx
|
|
8077
8768
|
var import_react64 = require("react");
|
|
8078
8769
|
var import_lucide_react18 = require("lucide-react");
|
|
8079
|
-
var
|
|
8770
|
+
var import_jsx_runtime89 = require("react/jsx-runtime");
|
|
8080
8771
|
var shellClass2 = "overflow-hidden rounded-xl border border-border bg-card shadow-card";
|
|
8081
8772
|
var tableClass = "w-full border-collapse bg-transparent text-sm";
|
|
8082
8773
|
var headCellClass = "border-b border-border/60 bg-transparent px-4 py-2.5 text-left text-xs font-medium uppercase tracking-wide text-muted-foreground";
|
|
@@ -8116,12 +8807,12 @@ function SortIndicator({
|
|
|
8116
8807
|
}) {
|
|
8117
8808
|
const iconClass = "size-3.5 shrink-0 opacity-60 group-hover:opacity-100";
|
|
8118
8809
|
if (!active) {
|
|
8119
|
-
return /* @__PURE__ */ (0,
|
|
8810
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_lucide_react18.ArrowUpDownIcon, { className: iconClass, "aria-hidden": true });
|
|
8120
8811
|
}
|
|
8121
8812
|
if (direction === "desc") {
|
|
8122
|
-
return /* @__PURE__ */ (0,
|
|
8813
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_lucide_react18.ArrowDownIcon, { className: iconClass, "aria-hidden": true });
|
|
8123
8814
|
}
|
|
8124
|
-
return /* @__PURE__ */ (0,
|
|
8815
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(import_lucide_react18.ArrowUpIcon, { className: iconClass, "aria-hidden": true });
|
|
8125
8816
|
}
|
|
8126
8817
|
function DataTable({
|
|
8127
8818
|
columns,
|
|
@@ -8172,28 +8863,28 @@ function DataTable({
|
|
|
8172
8863
|
const cellPad = dense ? "px-3 py-2" : void 0;
|
|
8173
8864
|
const headPad = dense ? "px-3 py-2" : void 0;
|
|
8174
8865
|
if (rows.length === 0 && emptyMode === "replace") {
|
|
8175
|
-
return /* @__PURE__ */ (0,
|
|
8866
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(EmptyState, { title: emptyTitle, description: emptyDescription, className });
|
|
8176
8867
|
}
|
|
8177
8868
|
const rowCountText = rowCountLabel?.(sortedRows.length) ?? `${sortedRows.length} row${sortedRows.length === 1 ? "" : "s"}`;
|
|
8178
8869
|
const hasFoot = Boolean((showRowCount || footer) && sortedRows.length > 0);
|
|
8179
|
-
return /* @__PURE__ */ (0,
|
|
8180
|
-
caption ? /* @__PURE__ */ (0,
|
|
8181
|
-
/* @__PURE__ */ (0,
|
|
8870
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: cn("aui-app-data-table", shellClass2, className), children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: "overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("table", { className: tableClass, children: [
|
|
8871
|
+
caption ? /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("caption", { className: "sr-only", children: caption }) : null,
|
|
8872
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("thead", { className: cn(stickyHeader && stickyHeadClass), children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("tr", { children: columns.map((col) => {
|
|
8182
8873
|
const isSorted = sort?.columnId === col.id;
|
|
8183
8874
|
const ariaSort = col.sortable ? isSorted ? sort.direction === "asc" ? "ascending" : "descending" : "none" : void 0;
|
|
8184
|
-
const headerContent = col.sortable ? /* @__PURE__ */ (0,
|
|
8875
|
+
const headerContent = col.sortable ? /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(
|
|
8185
8876
|
"button",
|
|
8186
8877
|
{
|
|
8187
8878
|
type: "button",
|
|
8188
8879
|
className: sortButtonClass,
|
|
8189
8880
|
onClick: () => setSort(nextSort(sort, col.id)),
|
|
8190
8881
|
children: [
|
|
8191
|
-
/* @__PURE__ */ (0,
|
|
8192
|
-
/* @__PURE__ */ (0,
|
|
8882
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { className: "truncate", children: col.header }),
|
|
8883
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)(SortIndicator, { active: Boolean(isSorted), direction: sort?.direction })
|
|
8193
8884
|
]
|
|
8194
8885
|
}
|
|
8195
8886
|
) : col.header;
|
|
8196
|
-
return /* @__PURE__ */ (0,
|
|
8887
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
8197
8888
|
"th",
|
|
8198
8889
|
{
|
|
8199
8890
|
scope: "col",
|
|
@@ -8209,10 +8900,10 @@ function DataTable({
|
|
|
8209
8900
|
col.id
|
|
8210
8901
|
);
|
|
8211
8902
|
}) }) }),
|
|
8212
|
-
/* @__PURE__ */ (0,
|
|
8213
|
-
/* @__PURE__ */ (0,
|
|
8214
|
-
emptyDescription ? /* @__PURE__ */ (0,
|
|
8215
|
-
] }) }) }) : sortedRows.map((row) => /* @__PURE__ */ (0,
|
|
8903
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("tbody", { className: cn(!hasFoot && "[&_tr:last-child_td]:border-b-0"), children: sortedRows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("td", { colSpan: columns.length, className: emptyCellClass, children: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "flex flex-col items-center gap-1", children: [
|
|
8904
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("p", { className: "font-medium text-foreground", children: emptyTitle }),
|
|
8905
|
+
emptyDescription ? /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("p", { className: "max-w-sm text-muted-foreground", children: emptyDescription }) : null
|
|
8906
|
+
] }) }) }) : sortedRows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
8216
8907
|
"tr",
|
|
8217
8908
|
{
|
|
8218
8909
|
className: rowClass,
|
|
@@ -8226,7 +8917,7 @@ function DataTable({
|
|
|
8226
8917
|
} : void 0,
|
|
8227
8918
|
tabIndex: onRowClick ? 0 : void 0,
|
|
8228
8919
|
role: onRowClick ? "button" : void 0,
|
|
8229
|
-
children: columns.map((col) => /* @__PURE__ */ (0,
|
|
8920
|
+
children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
8230
8921
|
"td",
|
|
8231
8922
|
{
|
|
8232
8923
|
className: cn(
|
|
@@ -8242,7 +8933,7 @@ function DataTable({
|
|
|
8242
8933
|
},
|
|
8243
8934
|
getRowKey(row)
|
|
8244
8935
|
)) }),
|
|
8245
|
-
hasFoot ? /* @__PURE__ */ (0,
|
|
8936
|
+
hasFoot ? /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("tfoot", { children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("td", { colSpan: columns.length, className: footCellClass, children: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(
|
|
8246
8937
|
"div",
|
|
8247
8938
|
{
|
|
8248
8939
|
className: cn(
|
|
@@ -8250,7 +8941,7 @@ function DataTable({
|
|
|
8250
8941
|
showRowCount && footer ? "justify-between" : "justify-start"
|
|
8251
8942
|
),
|
|
8252
8943
|
children: [
|
|
8253
|
-
showRowCount ? /* @__PURE__ */ (0,
|
|
8944
|
+
showRowCount ? /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { children: rowCountText }) : null,
|
|
8254
8945
|
footer
|
|
8255
8946
|
]
|
|
8256
8947
|
}
|
|
@@ -8260,53 +8951,7 @@ function DataTable({
|
|
|
8260
8951
|
|
|
8261
8952
|
// src/app/data/ChartPanel.tsx
|
|
8262
8953
|
var import_react65 = require("react");
|
|
8263
|
-
|
|
8264
|
-
// src/app/data/metrics-shared.tsx
|
|
8265
|
-
var import_jsx_runtime86 = require("react/jsx-runtime");
|
|
8266
|
-
var metricCardShellClass = cn(
|
|
8267
|
-
studioIntegrationCardClass,
|
|
8268
|
-
"aui-app-metric-card shadow-none",
|
|
8269
|
-
"flex flex-col overflow-hidden"
|
|
8270
|
-
);
|
|
8271
|
-
var metricCardHeaderClass = "flex items-start justify-between gap-3 px-4 pb-1 pt-3";
|
|
8272
|
-
var metricTilesRowClass = "grid w-full min-w-0";
|
|
8273
|
-
var metricChartRegionClass = "relative min-h-0 w-full border-t border-border/40 pt-2";
|
|
8274
|
-
var metricChartPlotRegionClass = "relative min-h-0 w-full border-t border-border/40 px-0 pt-5 pb-3";
|
|
8275
|
-
var metricCellDividerClass = "border-r border-border/40";
|
|
8276
|
-
var MetricCardHeader = ({
|
|
8277
|
-
title,
|
|
8278
|
-
titleId,
|
|
8279
|
-
description,
|
|
8280
|
-
actions
|
|
8281
|
-
}) => {
|
|
8282
|
-
if (!title && !description && !actions) return null;
|
|
8283
|
-
return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("header", { className: metricCardHeaderClass, children: [
|
|
8284
|
-
/* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "min-w-0", children: [
|
|
8285
|
-
title ? /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("h3", { id: titleId, className: "text-base font-normal text-foreground", children: title }) : null,
|
|
8286
|
-
description ? /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description }) : null
|
|
8287
|
-
] }),
|
|
8288
|
-
actions ? /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("div", { className: "shrink-0", children: actions }) : null
|
|
8289
|
-
] });
|
|
8290
|
-
};
|
|
8291
|
-
function metricTilesGridColsClass(n) {
|
|
8292
|
-
switch (n) {
|
|
8293
|
-
case 1:
|
|
8294
|
-
return "grid-cols-1";
|
|
8295
|
-
case 2:
|
|
8296
|
-
return "grid-cols-2";
|
|
8297
|
-
case 3:
|
|
8298
|
-
return "grid-cols-3";
|
|
8299
|
-
case 5:
|
|
8300
|
-
return "grid-cols-2 sm:grid-cols-5";
|
|
8301
|
-
case 6:
|
|
8302
|
-
return "grid-cols-2 sm:grid-cols-3 lg:grid-cols-6";
|
|
8303
|
-
default:
|
|
8304
|
-
return "grid-cols-2 md:grid-cols-4";
|
|
8305
|
-
}
|
|
8306
|
-
}
|
|
8307
|
-
|
|
8308
|
-
// src/app/data/ChartPanel.tsx
|
|
8309
|
-
var import_jsx_runtime87 = require("react/jsx-runtime");
|
|
8954
|
+
var import_jsx_runtime90 = require("react/jsx-runtime");
|
|
8310
8955
|
var ChartPanel = ({
|
|
8311
8956
|
title,
|
|
8312
8957
|
description,
|
|
@@ -8319,14 +8964,14 @@ var ChartPanel = ({
|
|
|
8319
8964
|
const titleId = (0, import_react65.useId)();
|
|
8320
8965
|
const resolvedTitle = title ?? artifact?.title;
|
|
8321
8966
|
const hasHeader = Boolean(resolvedTitle || description || actions);
|
|
8322
|
-
const body = children ?? (artifact ? /* @__PURE__ */ (0,
|
|
8323
|
-
return /* @__PURE__ */ (0,
|
|
8967
|
+
const body = children ?? (artifact ? /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(ChartArtifactView, { artifact, embedded: true, height }) : null);
|
|
8968
|
+
return /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)(
|
|
8324
8969
|
"section",
|
|
8325
8970
|
{
|
|
8326
8971
|
className: cn(metricCardShellClass, "aui-app-chart-panel", className),
|
|
8327
8972
|
"aria-labelledby": resolvedTitle ? titleId : void 0,
|
|
8328
8973
|
children: [
|
|
8329
|
-
/* @__PURE__ */ (0,
|
|
8974
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
|
|
8330
8975
|
MetricCardHeader,
|
|
8331
8976
|
{
|
|
8332
8977
|
title: resolvedTitle,
|
|
@@ -8335,14 +8980,14 @@ var ChartPanel = ({
|
|
|
8335
8980
|
actions
|
|
8336
8981
|
}
|
|
8337
8982
|
),
|
|
8338
|
-
/* @__PURE__ */ (0,
|
|
8983
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
|
|
8339
8984
|
"div",
|
|
8340
8985
|
{
|
|
8341
8986
|
className: cn(
|
|
8342
8987
|
"relative min-h-0 w-full",
|
|
8343
8988
|
hasHeader ? metricChartPlotRegionClass : "pt-2 pb-3"
|
|
8344
8989
|
),
|
|
8345
|
-
children: body ?? /* @__PURE__ */ (0,
|
|
8990
|
+
children: body ?? /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
|
|
8346
8991
|
"div",
|
|
8347
8992
|
{
|
|
8348
8993
|
className: "flex items-center justify-center text-sm font-normal text-muted-foreground",
|
|
@@ -8358,77 +9003,9 @@ var ChartPanel = ({
|
|
|
8358
9003
|
);
|
|
8359
9004
|
};
|
|
8360
9005
|
|
|
8361
|
-
// src/app/data/MetricTile.tsx
|
|
8362
|
-
var import_jsx_runtime88 = require("react/jsx-runtime");
|
|
8363
|
-
var trendToneClass = {
|
|
8364
|
-
up: "border-border/80 bg-muted/40 text-muted-foreground",
|
|
8365
|
-
down: "border-border/80 bg-muted/40 text-muted-foreground",
|
|
8366
|
-
neutral: "border-border/80 bg-muted/30 text-muted-foreground"
|
|
8367
|
-
};
|
|
8368
|
-
var metricTileBaseClass = "relative flex min-w-0 flex-1 flex-col gap-1 px-4 py-3 text-left font-normal";
|
|
8369
|
-
var metricTileInteractiveClass = cn(
|
|
8370
|
-
metricTileBaseClass,
|
|
8371
|
-
"bg-transparent hover:bg-transparent active:bg-transparent",
|
|
8372
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-foreground/10"
|
|
8373
|
-
);
|
|
8374
|
-
var MetricTile = ({
|
|
8375
|
-
label,
|
|
8376
|
-
value,
|
|
8377
|
-
unit,
|
|
8378
|
-
trend,
|
|
8379
|
-
trendTone = "neutral",
|
|
8380
|
-
active = false,
|
|
8381
|
-
showDivider = false,
|
|
8382
|
-
onSelect,
|
|
8383
|
-
ariaLabel,
|
|
8384
|
-
className
|
|
8385
|
-
}) => {
|
|
8386
|
-
const content = /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(import_jsx_runtime88.Fragment, { children: [
|
|
8387
|
-
active ? /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
8388
|
-
"span",
|
|
8389
|
-
{
|
|
8390
|
-
"aria-hidden": true,
|
|
8391
|
-
className: "absolute inset-x-0 bottom-0 h-0.5 bg-foreground dark:bg-white"
|
|
8392
|
-
}
|
|
8393
|
-
) : null,
|
|
8394
|
-
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", { className: "text-xs font-normal text-muted-foreground", children: label }),
|
|
8395
|
-
/* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("span", { className: "flex items-center gap-2", children: [
|
|
8396
|
-
/* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("span", { className: "flex items-baseline gap-1", children: [
|
|
8397
|
-
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", { className: "text-2xl font-normal tracking-tight text-foreground tabular-nums", children: value }),
|
|
8398
|
-
unit ? /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", { className: "text-xs font-normal text-muted-foreground", children: unit }) : null
|
|
8399
|
-
] }),
|
|
8400
|
-
trend ? /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
8401
|
-
"span",
|
|
8402
|
-
{
|
|
8403
|
-
className: cn(
|
|
8404
|
-
"rounded-full border px-1.5 py-0.5 text-xs font-normal",
|
|
8405
|
-
trendToneClass[trendTone]
|
|
8406
|
-
),
|
|
8407
|
-
children: trend
|
|
8408
|
-
}
|
|
8409
|
-
) : null
|
|
8410
|
-
] })
|
|
8411
|
-
] });
|
|
8412
|
-
const divider = showDivider ? metricCellDividerClass : void 0;
|
|
8413
|
-
if (onSelect) {
|
|
8414
|
-
return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
8415
|
-
"button",
|
|
8416
|
-
{
|
|
8417
|
-
type: "button",
|
|
8418
|
-
onClick: onSelect,
|
|
8419
|
-
"aria-pressed": active,
|
|
8420
|
-
"aria-label": ariaLabel,
|
|
8421
|
-
className: cn(metricTileInteractiveClass, divider, className),
|
|
8422
|
-
children: content
|
|
8423
|
-
}
|
|
8424
|
-
);
|
|
8425
|
-
}
|
|
8426
|
-
return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("div", { className: cn(metricTileBaseClass, divider, className), children: content });
|
|
8427
|
-
};
|
|
8428
|
-
|
|
8429
9006
|
// src/app/data/MetricRow.tsx
|
|
8430
9007
|
var import_react66 = require("react");
|
|
8431
|
-
var
|
|
9008
|
+
var import_jsx_runtime91 = require("react/jsx-runtime");
|
|
8432
9009
|
var MetricRow = ({
|
|
8433
9010
|
title,
|
|
8434
9011
|
description,
|
|
@@ -8450,13 +9027,13 @@ var MetricRow = ({
|
|
|
8450
9027
|
if (activeMetricId == null) setInternalId(id);
|
|
8451
9028
|
onMetricChange?.(id);
|
|
8452
9029
|
};
|
|
8453
|
-
return /* @__PURE__ */ (0,
|
|
9030
|
+
return /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)(
|
|
8454
9031
|
"section",
|
|
8455
9032
|
{
|
|
8456
9033
|
className: cn(metricCardShellClass, className),
|
|
8457
9034
|
"aria-labelledby": title ? titleId : void 0,
|
|
8458
9035
|
children: [
|
|
8459
|
-
/* @__PURE__ */ (0,
|
|
9036
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
|
|
8460
9037
|
MetricCardHeader,
|
|
8461
9038
|
{
|
|
8462
9039
|
title,
|
|
@@ -8465,7 +9042,7 @@ var MetricRow = ({
|
|
|
8465
9042
|
actions
|
|
8466
9043
|
}
|
|
8467
9044
|
),
|
|
8468
|
-
/* @__PURE__ */ (0,
|
|
9045
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
|
|
8469
9046
|
"div",
|
|
8470
9047
|
{
|
|
8471
9048
|
role: selectable ? "group" : void 0,
|
|
@@ -8475,7 +9052,7 @@ var MetricRow = ({
|
|
|
8475
9052
|
metricTilesGridColsClass(metrics.length),
|
|
8476
9053
|
(title || description || actions) && "mt-3"
|
|
8477
9054
|
),
|
|
8478
|
-
children: metrics.map((m, index) => /* @__PURE__ */ (0,
|
|
9055
|
+
children: metrics.map((m, index) => /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
|
|
8479
9056
|
MetricTile,
|
|
8480
9057
|
{
|
|
8481
9058
|
label: m.label,
|
|
@@ -8498,7 +9075,7 @@ var MetricRow = ({
|
|
|
8498
9075
|
|
|
8499
9076
|
// src/app/data/MetricChartCard.tsx
|
|
8500
9077
|
var import_react67 = require("react");
|
|
8501
|
-
var
|
|
9078
|
+
var import_jsx_runtime92 = require("react/jsx-runtime");
|
|
8502
9079
|
var MetricChartCard = ({
|
|
8503
9080
|
title,
|
|
8504
9081
|
description,
|
|
@@ -8528,13 +9105,13 @@ var MetricChartCard = ({
|
|
|
8528
9105
|
};
|
|
8529
9106
|
const hasHeader = Boolean(title || description || actions);
|
|
8530
9107
|
const chartAriaLabel = typeof active?.label === "string" ? `${active.label} over time` : "Metric chart";
|
|
8531
|
-
return /* @__PURE__ */ (0,
|
|
9108
|
+
return /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)(
|
|
8532
9109
|
"section",
|
|
8533
9110
|
{
|
|
8534
9111
|
className: cn(metricCardShellClass, className),
|
|
8535
9112
|
"aria-labelledby": title ? titleId : void 0,
|
|
8536
9113
|
children: [
|
|
8537
|
-
/* @__PURE__ */ (0,
|
|
9114
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
|
|
8538
9115
|
MetricCardHeader,
|
|
8539
9116
|
{
|
|
8540
9117
|
title,
|
|
@@ -8543,7 +9120,7 @@ var MetricChartCard = ({
|
|
|
8543
9120
|
actions
|
|
8544
9121
|
}
|
|
8545
9122
|
),
|
|
8546
|
-
/* @__PURE__ */ (0,
|
|
9123
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
|
|
8547
9124
|
"div",
|
|
8548
9125
|
{
|
|
8549
9126
|
role: "group",
|
|
@@ -8553,7 +9130,7 @@ var MetricChartCard = ({
|
|
|
8553
9130
|
metricTilesGridColsClass(metrics.length),
|
|
8554
9131
|
hasHeader && "mt-3"
|
|
8555
9132
|
),
|
|
8556
|
-
children: metrics.map((m, index) => /* @__PURE__ */ (0,
|
|
9133
|
+
children: metrics.map((m, index) => /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
|
|
8557
9134
|
MetricTile,
|
|
8558
9135
|
{
|
|
8559
9136
|
label: m.label,
|
|
@@ -8569,7 +9146,7 @@ var MetricChartCard = ({
|
|
|
8569
9146
|
))
|
|
8570
9147
|
}
|
|
8571
9148
|
),
|
|
8572
|
-
/* @__PURE__ */ (0,
|
|
9149
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("div", { className: metricChartRegionClass, "aria-live": "polite", "aria-atomic": "true", children: active?.data && active.data.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
|
|
8573
9150
|
LineAreaChart,
|
|
8574
9151
|
{
|
|
8575
9152
|
data: active.data,
|
|
@@ -8589,7 +9166,7 @@ var MetricChartCard = ({
|
|
|
8589
9166
|
ariaLabel: chartAriaLabel
|
|
8590
9167
|
},
|
|
8591
9168
|
active.id
|
|
8592
|
-
) : /* @__PURE__ */ (0,
|
|
9169
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
|
|
8593
9170
|
"div",
|
|
8594
9171
|
{
|
|
8595
9172
|
className: "flex w-full items-center justify-center text-sm font-normal text-muted-foreground",
|
|
@@ -8605,7 +9182,7 @@ var MetricChartCard = ({
|
|
|
8605
9182
|
|
|
8606
9183
|
// src/charts/sparkline.tsx
|
|
8607
9184
|
var import_react68 = require("react");
|
|
8608
|
-
var
|
|
9185
|
+
var import_jsx_runtime93 = require("react/jsx-runtime");
|
|
8609
9186
|
var Sparkline = ({
|
|
8610
9187
|
data,
|
|
8611
9188
|
dataKey = "value",
|
|
@@ -8620,7 +9197,7 @@ var Sparkline = ({
|
|
|
8620
9197
|
const uid = (0, import_react68.useId)();
|
|
8621
9198
|
const values = data.map((d) => typeof d === "number" ? d : toNum(d[dataKey]));
|
|
8622
9199
|
if (values.length === 0) {
|
|
8623
|
-
return /* @__PURE__ */ (0,
|
|
9200
|
+
return /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("span", { className: cn("inline-block", className), style: { width, height } });
|
|
8624
9201
|
}
|
|
8625
9202
|
const pad = strokeWidth + 1;
|
|
8626
9203
|
const min = Math.min(...values);
|
|
@@ -8632,7 +9209,7 @@ var Sparkline = ({
|
|
|
8632
9209
|
x: pad + (values.length > 1 ? i / (values.length - 1) * innerW : innerW / 2),
|
|
8633
9210
|
y: pad + innerH - (v - min) / range * innerH
|
|
8634
9211
|
}));
|
|
8635
|
-
return /* @__PURE__ */ (0,
|
|
9212
|
+
return /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)(
|
|
8636
9213
|
"svg",
|
|
8637
9214
|
{
|
|
8638
9215
|
width,
|
|
@@ -8643,14 +9220,14 @@ var Sparkline = ({
|
|
|
8643
9220
|
"aria-label": ariaLabel,
|
|
8644
9221
|
preserveAspectRatio: "none",
|
|
8645
9222
|
children: [
|
|
8646
|
-
area && /* @__PURE__ */ (0,
|
|
8647
|
-
/* @__PURE__ */ (0,
|
|
8648
|
-
/* @__PURE__ */ (0,
|
|
8649
|
-
/* @__PURE__ */ (0,
|
|
9223
|
+
area && /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)(import_jsx_runtime93.Fragment, { children: [
|
|
9224
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("linearGradient", { id: `${uid}-spark`, x1: "0", x2: "0", y1: "0", y2: "1", children: [
|
|
9225
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsx)("stop", { offset: "0%", style: { stopColor: color, stopOpacity: 0.25 } }),
|
|
9226
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsx)("stop", { offset: "100%", style: { stopColor: color, stopOpacity: 0 } })
|
|
8650
9227
|
] }) }),
|
|
8651
|
-
/* @__PURE__ */ (0,
|
|
9228
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsx)("path", { d: monotoneAreaPath(points, height - pad), fill: `url(#${uid}-spark)` })
|
|
8652
9229
|
] }),
|
|
8653
|
-
/* @__PURE__ */ (0,
|
|
9230
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
|
|
8654
9231
|
"path",
|
|
8655
9232
|
{
|
|
8656
9233
|
d: monotoneLinePath(points),
|
|
@@ -8794,7 +9371,7 @@ When you call a tool that returns an artifact (\`make_chart\`, \`ask_question\`,
|
|
|
8794
9371
|
|
|
8795
9372
|
// src/auth/guard.tsx
|
|
8796
9373
|
var import_lucide_react19 = require("lucide-react");
|
|
8797
|
-
var
|
|
9374
|
+
var import_jsx_runtime94 = require("react/jsx-runtime");
|
|
8798
9375
|
var AuthGuard = ({
|
|
8799
9376
|
children,
|
|
8800
9377
|
requireAuth = false,
|
|
@@ -8805,7 +9382,7 @@ var AuthGuard = ({
|
|
|
8805
9382
|
return children;
|
|
8806
9383
|
}
|
|
8807
9384
|
if (loading) {
|
|
8808
|
-
return /* @__PURE__ */ (0,
|
|
9385
|
+
return /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("div", { className: "flex items-center justify-center h-screen", children: /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(import_lucide_react19.Loader2, { className: "w-8 h-8 animate-spin" }) });
|
|
8809
9386
|
}
|
|
8810
9387
|
if (requireAuth && !isAuthenticated && !isEmbedded) {
|
|
8811
9388
|
const returnTo = encodeURIComponent(
|
|
@@ -8823,16 +9400,16 @@ var import_react69 = require("@assistant-ui/react");
|
|
|
8823
9400
|
// src/ui/dropdown-menu.tsx
|
|
8824
9401
|
var import_radix_ui5 = require("radix-ui");
|
|
8825
9402
|
var import_lucide_react20 = require("lucide-react");
|
|
8826
|
-
var
|
|
9403
|
+
var import_jsx_runtime95 = require("react/jsx-runtime");
|
|
8827
9404
|
function DropdownMenu({
|
|
8828
9405
|
...props
|
|
8829
9406
|
}) {
|
|
8830
|
-
return /* @__PURE__ */ (0,
|
|
9407
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(import_radix_ui5.DropdownMenu.Root, { "data-slot": "dropdown-menu", ...props });
|
|
8831
9408
|
}
|
|
8832
9409
|
function DropdownMenuTrigger({
|
|
8833
9410
|
...props
|
|
8834
9411
|
}) {
|
|
8835
|
-
return /* @__PURE__ */ (0,
|
|
9412
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
8836
9413
|
import_radix_ui5.DropdownMenu.Trigger,
|
|
8837
9414
|
{
|
|
8838
9415
|
"data-slot": "dropdown-menu-trigger",
|
|
@@ -8843,14 +9420,14 @@ function DropdownMenuTrigger({
|
|
|
8843
9420
|
function DropdownMenuGroup({
|
|
8844
9421
|
...props
|
|
8845
9422
|
}) {
|
|
8846
|
-
return /* @__PURE__ */ (0,
|
|
9423
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(import_radix_ui5.DropdownMenu.Group, { "data-slot": "dropdown-menu-group", ...props });
|
|
8847
9424
|
}
|
|
8848
9425
|
function DropdownMenuContent({
|
|
8849
9426
|
className,
|
|
8850
9427
|
sideOffset = 4,
|
|
8851
9428
|
...props
|
|
8852
9429
|
}) {
|
|
8853
|
-
return /* @__PURE__ */ (0,
|
|
9430
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(import_radix_ui5.DropdownMenu.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
8854
9431
|
import_radix_ui5.DropdownMenu.Content,
|
|
8855
9432
|
{
|
|
8856
9433
|
"data-slot": "dropdown-menu-content",
|
|
@@ -8869,7 +9446,7 @@ function DropdownMenuItem({
|
|
|
8869
9446
|
variant = "default",
|
|
8870
9447
|
...props
|
|
8871
9448
|
}) {
|
|
8872
|
-
return /* @__PURE__ */ (0,
|
|
9449
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
8873
9450
|
import_radix_ui5.DropdownMenu.Item,
|
|
8874
9451
|
{
|
|
8875
9452
|
"data-slot": "dropdown-menu-item",
|
|
@@ -8889,7 +9466,7 @@ function DropdownMenuCheckboxItem({
|
|
|
8889
9466
|
checked,
|
|
8890
9467
|
...props
|
|
8891
9468
|
}) {
|
|
8892
|
-
return /* @__PURE__ */ (0,
|
|
9469
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)(
|
|
8893
9470
|
import_radix_ui5.DropdownMenu.CheckboxItem,
|
|
8894
9471
|
{
|
|
8895
9472
|
"data-slot": "dropdown-menu-checkbox-item",
|
|
@@ -8900,7 +9477,7 @@ function DropdownMenuCheckboxItem({
|
|
|
8900
9477
|
checked,
|
|
8901
9478
|
...props,
|
|
8902
9479
|
children: [
|
|
8903
|
-
/* @__PURE__ */ (0,
|
|
9480
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(import_radix_ui5.DropdownMenu.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(import_lucide_react20.CheckIcon, { className: "size-4" }) }) }),
|
|
8904
9481
|
children
|
|
8905
9482
|
]
|
|
8906
9483
|
}
|
|
@@ -8909,7 +9486,7 @@ function DropdownMenuCheckboxItem({
|
|
|
8909
9486
|
function DropdownMenuRadioGroup({
|
|
8910
9487
|
...props
|
|
8911
9488
|
}) {
|
|
8912
|
-
return /* @__PURE__ */ (0,
|
|
9489
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
8913
9490
|
import_radix_ui5.DropdownMenu.RadioGroup,
|
|
8914
9491
|
{
|
|
8915
9492
|
"data-slot": "dropdown-menu-radio-group",
|
|
@@ -8922,7 +9499,7 @@ function DropdownMenuRadioItem({
|
|
|
8922
9499
|
children,
|
|
8923
9500
|
...props
|
|
8924
9501
|
}) {
|
|
8925
|
-
return /* @__PURE__ */ (0,
|
|
9502
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)(
|
|
8926
9503
|
import_radix_ui5.DropdownMenu.RadioItem,
|
|
8927
9504
|
{
|
|
8928
9505
|
"data-slot": "dropdown-menu-radio-item",
|
|
@@ -8932,7 +9509,7 @@ function DropdownMenuRadioItem({
|
|
|
8932
9509
|
),
|
|
8933
9510
|
...props,
|
|
8934
9511
|
children: [
|
|
8935
|
-
/* @__PURE__ */ (0,
|
|
9512
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(import_radix_ui5.DropdownMenu.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(import_lucide_react20.CircleIcon, { className: "size-2 fill-current" }) }) }),
|
|
8936
9513
|
children
|
|
8937
9514
|
]
|
|
8938
9515
|
}
|
|
@@ -8943,7 +9520,7 @@ function DropdownMenuLabel({
|
|
|
8943
9520
|
inset,
|
|
8944
9521
|
...props
|
|
8945
9522
|
}) {
|
|
8946
|
-
return /* @__PURE__ */ (0,
|
|
9523
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
8947
9524
|
import_radix_ui5.DropdownMenu.Label,
|
|
8948
9525
|
{
|
|
8949
9526
|
"data-slot": "dropdown-menu-label",
|
|
@@ -8960,7 +9537,7 @@ function DropdownMenuSeparator({
|
|
|
8960
9537
|
className,
|
|
8961
9538
|
...props
|
|
8962
9539
|
}) {
|
|
8963
|
-
return /* @__PURE__ */ (0,
|
|
9540
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
8964
9541
|
import_radix_ui5.DropdownMenu.Separator,
|
|
8965
9542
|
{
|
|
8966
9543
|
"data-slot": "dropdown-menu-separator",
|
|
@@ -8973,7 +9550,7 @@ function DropdownMenuShortcut({
|
|
|
8973
9550
|
className,
|
|
8974
9551
|
...props
|
|
8975
9552
|
}) {
|
|
8976
|
-
return /* @__PURE__ */ (0,
|
|
9553
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
8977
9554
|
"span",
|
|
8978
9555
|
{
|
|
8979
9556
|
"data-slot": "dropdown-menu-shortcut",
|
|
@@ -8988,7 +9565,7 @@ function DropdownMenuShortcut({
|
|
|
8988
9565
|
function DropdownMenuSub({
|
|
8989
9566
|
...props
|
|
8990
9567
|
}) {
|
|
8991
|
-
return /* @__PURE__ */ (0,
|
|
9568
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(import_radix_ui5.DropdownMenu.Sub, { "data-slot": "dropdown-menu-sub", ...props });
|
|
8992
9569
|
}
|
|
8993
9570
|
function DropdownMenuSubTrigger({
|
|
8994
9571
|
className,
|
|
@@ -8996,7 +9573,7 @@ function DropdownMenuSubTrigger({
|
|
|
8996
9573
|
children,
|
|
8997
9574
|
...props
|
|
8998
9575
|
}) {
|
|
8999
|
-
return /* @__PURE__ */ (0,
|
|
9576
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)(
|
|
9000
9577
|
import_radix_ui5.DropdownMenu.SubTrigger,
|
|
9001
9578
|
{
|
|
9002
9579
|
"data-slot": "dropdown-menu-sub-trigger",
|
|
@@ -9008,7 +9585,7 @@ function DropdownMenuSubTrigger({
|
|
|
9008
9585
|
...props,
|
|
9009
9586
|
children: [
|
|
9010
9587
|
children,
|
|
9011
|
-
/* @__PURE__ */ (0,
|
|
9588
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(import_lucide_react20.ChevronRightIcon, { className: "ml-auto size-4" })
|
|
9012
9589
|
]
|
|
9013
9590
|
}
|
|
9014
9591
|
);
|
|
@@ -9017,7 +9594,7 @@ function DropdownMenuSubContent({
|
|
|
9017
9594
|
className,
|
|
9018
9595
|
...props
|
|
9019
9596
|
}) {
|
|
9020
|
-
return /* @__PURE__ */ (0,
|
|
9597
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
9021
9598
|
import_radix_ui5.DropdownMenu.SubContent,
|
|
9022
9599
|
{
|
|
9023
9600
|
"data-slot": "dropdown-menu-sub-content",
|
|
@@ -9032,21 +9609,21 @@ function DropdownMenuSubContent({
|
|
|
9032
9609
|
|
|
9033
9610
|
// src/ui/popover.tsx
|
|
9034
9611
|
var import_radix_ui6 = require("radix-ui");
|
|
9035
|
-
var
|
|
9612
|
+
var import_jsx_runtime96 = require("react/jsx-runtime");
|
|
9036
9613
|
function Popover({
|
|
9037
9614
|
...props
|
|
9038
9615
|
}) {
|
|
9039
|
-
return /* @__PURE__ */ (0,
|
|
9616
|
+
return /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(import_radix_ui6.Popover.Root, { "data-slot": "popover", ...props });
|
|
9040
9617
|
}
|
|
9041
9618
|
function PopoverTrigger({
|
|
9042
9619
|
...props
|
|
9043
9620
|
}) {
|
|
9044
|
-
return /* @__PURE__ */ (0,
|
|
9621
|
+
return /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(import_radix_ui6.Popover.Trigger, { "data-slot": "popover-trigger", ...props });
|
|
9045
9622
|
}
|
|
9046
9623
|
function PopoverAnchor({
|
|
9047
9624
|
...props
|
|
9048
9625
|
}) {
|
|
9049
|
-
return /* @__PURE__ */ (0,
|
|
9626
|
+
return /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(import_radix_ui6.Popover.Anchor, { "data-slot": "popover-anchor", ...props });
|
|
9050
9627
|
}
|
|
9051
9628
|
function PopoverContent({
|
|
9052
9629
|
className,
|
|
@@ -9054,7 +9631,7 @@ function PopoverContent({
|
|
|
9054
9631
|
sideOffset = 4,
|
|
9055
9632
|
...props
|
|
9056
9633
|
}) {
|
|
9057
|
-
return /* @__PURE__ */ (0,
|
|
9634
|
+
return /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(import_radix_ui6.Popover.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(
|
|
9058
9635
|
import_radix_ui6.Popover.Content,
|
|
9059
9636
|
{
|
|
9060
9637
|
"data-slot": "popover-content",
|
|
@@ -9072,21 +9649,21 @@ function PopoverContent({
|
|
|
9072
9649
|
// src/ui/select.tsx
|
|
9073
9650
|
var import_radix_ui7 = require("radix-ui");
|
|
9074
9651
|
var import_lucide_react21 = require("lucide-react");
|
|
9075
|
-
var
|
|
9652
|
+
var import_jsx_runtime97 = require("react/jsx-runtime");
|
|
9076
9653
|
function Select({
|
|
9077
9654
|
...props
|
|
9078
9655
|
}) {
|
|
9079
|
-
return /* @__PURE__ */ (0,
|
|
9656
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(import_radix_ui7.Select.Root, { "data-slot": "select", ...props });
|
|
9080
9657
|
}
|
|
9081
9658
|
function SelectGroup({
|
|
9082
9659
|
...props
|
|
9083
9660
|
}) {
|
|
9084
|
-
return /* @__PURE__ */ (0,
|
|
9661
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(import_radix_ui7.Select.Group, { "data-slot": "select-group", ...props });
|
|
9085
9662
|
}
|
|
9086
9663
|
function SelectValue({
|
|
9087
9664
|
...props
|
|
9088
9665
|
}) {
|
|
9089
|
-
return /* @__PURE__ */ (0,
|
|
9666
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(import_radix_ui7.Select.Value, { "data-slot": "select-value", ...props });
|
|
9090
9667
|
}
|
|
9091
9668
|
function SelectTrigger({
|
|
9092
9669
|
className,
|
|
@@ -9094,7 +9671,7 @@ function SelectTrigger({
|
|
|
9094
9671
|
children,
|
|
9095
9672
|
...props
|
|
9096
9673
|
}) {
|
|
9097
|
-
return /* @__PURE__ */ (0,
|
|
9674
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)(
|
|
9098
9675
|
import_radix_ui7.Select.Trigger,
|
|
9099
9676
|
{
|
|
9100
9677
|
"data-slot": "select-trigger",
|
|
@@ -9106,7 +9683,7 @@ function SelectTrigger({
|
|
|
9106
9683
|
...props,
|
|
9107
9684
|
children: [
|
|
9108
9685
|
children,
|
|
9109
|
-
/* @__PURE__ */ (0,
|
|
9686
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(import_radix_ui7.Select.Icon, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(import_lucide_react21.ChevronDownIcon, { className: "size-4 opacity-50" }) })
|
|
9110
9687
|
]
|
|
9111
9688
|
}
|
|
9112
9689
|
);
|
|
@@ -9117,7 +9694,7 @@ function SelectContent({
|
|
|
9117
9694
|
position = "popper",
|
|
9118
9695
|
...props
|
|
9119
9696
|
}) {
|
|
9120
|
-
return /* @__PURE__ */ (0,
|
|
9697
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(import_radix_ui7.Select.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)(
|
|
9121
9698
|
import_radix_ui7.Select.Content,
|
|
9122
9699
|
{
|
|
9123
9700
|
"data-slot": "select-content",
|
|
@@ -9129,8 +9706,8 @@ function SelectContent({
|
|
|
9129
9706
|
position,
|
|
9130
9707
|
...props,
|
|
9131
9708
|
children: [
|
|
9132
|
-
/* @__PURE__ */ (0,
|
|
9133
|
-
/* @__PURE__ */ (0,
|
|
9709
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(SelectScrollUpButton, {}),
|
|
9710
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
9134
9711
|
import_radix_ui7.Select.Viewport,
|
|
9135
9712
|
{
|
|
9136
9713
|
className: cn(
|
|
@@ -9140,7 +9717,7 @@ function SelectContent({
|
|
|
9140
9717
|
children
|
|
9141
9718
|
}
|
|
9142
9719
|
),
|
|
9143
|
-
/* @__PURE__ */ (0,
|
|
9720
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(SelectScrollDownButton, {})
|
|
9144
9721
|
]
|
|
9145
9722
|
}
|
|
9146
9723
|
) });
|
|
@@ -9149,7 +9726,7 @@ function SelectLabel({
|
|
|
9149
9726
|
className,
|
|
9150
9727
|
...props
|
|
9151
9728
|
}) {
|
|
9152
|
-
return /* @__PURE__ */ (0,
|
|
9729
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
9153
9730
|
import_radix_ui7.Select.Label,
|
|
9154
9731
|
{
|
|
9155
9732
|
"data-slot": "select-label",
|
|
@@ -9163,7 +9740,7 @@ function SelectItem({
|
|
|
9163
9740
|
children,
|
|
9164
9741
|
...props
|
|
9165
9742
|
}) {
|
|
9166
|
-
return /* @__PURE__ */ (0,
|
|
9743
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)(
|
|
9167
9744
|
import_radix_ui7.Select.Item,
|
|
9168
9745
|
{
|
|
9169
9746
|
"data-slot": "select-item",
|
|
@@ -9173,8 +9750,8 @@ function SelectItem({
|
|
|
9173
9750
|
),
|
|
9174
9751
|
...props,
|
|
9175
9752
|
children: [
|
|
9176
|
-
/* @__PURE__ */ (0,
|
|
9177
|
-
/* @__PURE__ */ (0,
|
|
9753
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("span", { className: "absolute right-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(import_radix_ui7.Select.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(import_lucide_react21.CheckIcon, { className: "size-4" }) }) }),
|
|
9754
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(import_radix_ui7.Select.ItemText, { children })
|
|
9178
9755
|
]
|
|
9179
9756
|
}
|
|
9180
9757
|
);
|
|
@@ -9183,7 +9760,7 @@ function SelectSeparator({
|
|
|
9183
9760
|
className,
|
|
9184
9761
|
...props
|
|
9185
9762
|
}) {
|
|
9186
|
-
return /* @__PURE__ */ (0,
|
|
9763
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
9187
9764
|
import_radix_ui7.Select.Separator,
|
|
9188
9765
|
{
|
|
9189
9766
|
"data-slot": "select-separator",
|
|
@@ -9196,13 +9773,13 @@ function SelectScrollUpButton({
|
|
|
9196
9773
|
className,
|
|
9197
9774
|
...props
|
|
9198
9775
|
}) {
|
|
9199
|
-
return /* @__PURE__ */ (0,
|
|
9776
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
9200
9777
|
import_radix_ui7.Select.ScrollUpButton,
|
|
9201
9778
|
{
|
|
9202
9779
|
"data-slot": "select-scroll-up-button",
|
|
9203
9780
|
className: cn("flex cursor-default items-center justify-center py-1", className),
|
|
9204
9781
|
...props,
|
|
9205
|
-
children: /* @__PURE__ */ (0,
|
|
9782
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(import_lucide_react21.ChevronUpIcon, { className: "size-4" })
|
|
9206
9783
|
}
|
|
9207
9784
|
);
|
|
9208
9785
|
}
|
|
@@ -9210,13 +9787,13 @@ function SelectScrollDownButton({
|
|
|
9210
9787
|
className,
|
|
9211
9788
|
...props
|
|
9212
9789
|
}) {
|
|
9213
|
-
return /* @__PURE__ */ (0,
|
|
9790
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
9214
9791
|
import_radix_ui7.Select.ScrollDownButton,
|
|
9215
9792
|
{
|
|
9216
9793
|
"data-slot": "select-scroll-down-button",
|
|
9217
9794
|
className: cn("flex cursor-default items-center justify-center py-1", className),
|
|
9218
9795
|
...props,
|
|
9219
|
-
children: /* @__PURE__ */ (0,
|
|
9796
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(import_lucide_react21.ChevronDownIcon, { className: "size-4" })
|
|
9220
9797
|
}
|
|
9221
9798
|
);
|
|
9222
9799
|
}
|
|
@@ -9341,8 +9918,11 @@ function SelectScrollDownButton({
|
|
|
9341
9918
|
SubNav,
|
|
9342
9919
|
Suggestions,
|
|
9343
9920
|
SurfaceCard,
|
|
9921
|
+
THEME_AGENT_INSTRUCTIONS,
|
|
9344
9922
|
THREAD_DEFAULT_MAX_WIDTH,
|
|
9923
|
+
TIMBAL_THEME_PRESETS,
|
|
9345
9924
|
TableArtifactView,
|
|
9925
|
+
ThemePresetGallery,
|
|
9346
9926
|
Thread,
|
|
9347
9927
|
ThreadPrimitive,
|
|
9348
9928
|
TimbalChat,
|
|
@@ -9350,6 +9930,7 @@ function SelectScrollDownButton({
|
|
|
9350
9930
|
TimbalMark,
|
|
9351
9931
|
TimbalRuntimeProvider,
|
|
9352
9932
|
TimbalStudioShell,
|
|
9933
|
+
TimbalThemeStyle,
|
|
9353
9934
|
ToolArtifactFallback,
|
|
9354
9935
|
ToolFallback,
|
|
9355
9936
|
Tooltip,
|
|
@@ -9362,13 +9943,17 @@ function SelectScrollDownButton({
|
|
|
9362
9943
|
UiEventProvider,
|
|
9363
9944
|
UiNodeView,
|
|
9364
9945
|
WorkforceSelector,
|
|
9946
|
+
applyThemePreset,
|
|
9947
|
+
applyTimbalTheme,
|
|
9365
9948
|
assistantMessageContentClass,
|
|
9366
9949
|
assistantMessageRootClass,
|
|
9367
9950
|
authFetch,
|
|
9951
|
+
clearTimbalTheme,
|
|
9368
9952
|
clearTokens,
|
|
9369
9953
|
cn,
|
|
9370
9954
|
connectionRowListClass,
|
|
9371
9955
|
createDefaultAttachmentAdapter,
|
|
9956
|
+
createTimbalTheme,
|
|
9372
9957
|
createUploadAttachmentAdapter,
|
|
9373
9958
|
defaultArtifactRenderers,
|
|
9374
9959
|
fetchCurrentUser,
|
|
@@ -9376,6 +9961,8 @@ function SelectScrollDownButton({
|
|
|
9376
9961
|
getAccessToken,
|
|
9377
9962
|
getPath,
|
|
9378
9963
|
getRefreshToken,
|
|
9964
|
+
getStoredThemePreset,
|
|
9965
|
+
getThemePreset,
|
|
9379
9966
|
isArtifact,
|
|
9380
9967
|
isArtifactFenceLanguage,
|
|
9381
9968
|
isUiBinding,
|
|
@@ -9388,6 +9975,7 @@ function SelectScrollDownButton({
|
|
|
9388
9975
|
setPath,
|
|
9389
9976
|
setRefreshToken,
|
|
9390
9977
|
splitMarkdownByArtifacts,
|
|
9978
|
+
themeToCss,
|
|
9391
9979
|
threadMessageColumnClass,
|
|
9392
9980
|
useAppCopilotContext,
|
|
9393
9981
|
useAppShellChat,
|