@altertable/data-app 0.59.1 → 0.62.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/AGENTS.md +5 -3
  2. package/CONTRIBUTING.md +16 -4
  3. package/README.md +20 -14
  4. package/dist/chunks/{contract-jksbmt5q.js → contract-3bnrf5pf.js} +27 -5
  5. package/dist/chunks/contract-3bnrf5pf.js.map +10 -0
  6. package/dist/chunks/{contract-tkkc28tg.js → contract-4vrw9zk9.js} +43 -13
  7. package/dist/chunks/contract-4vrw9zk9.js.map +12 -0
  8. package/dist/chunks/{contract-14vxdcrs.js → contract-farfe948.js} +17 -21
  9. package/dist/chunks/contract-farfe948.js.map +10 -0
  10. package/dist/chunks/contract-nt819swq.js.map +1 -1
  11. package/dist/chunks/{contract-tqrf3ykr.js → contract-rrm7s5zp.js} +61 -32
  12. package/dist/chunks/contract-rrm7s5zp.js.map +12 -0
  13. package/dist/chunks/{contract-mb5nfzwg.js → contract-xjv197ck.js} +178 -31
  14. package/dist/chunks/contract-xjv197ck.js.map +13 -0
  15. package/dist/client/index.js +6 -4
  16. package/dist/client/index.js.map +1 -1
  17. package/dist/core/appearance.js +1 -1
  18. package/dist/core/contract.js +5 -3
  19. package/dist/core/contract.js.map +1 -1
  20. package/dist/embed/index.js +42 -8
  21. package/dist/embed/index.js.map +5 -4
  22. package/dist/local.js +191 -79
  23. package/dist/local.js.map +8 -7
  24. package/dist/react/embed/index.js +84 -99
  25. package/dist/react/embed/index.js.map +4 -5
  26. package/dist/react/index.css +156 -6
  27. package/dist/react/index.js +313 -152
  28. package/dist/react/index.js.map +17 -13
  29. package/dist/server.js +172 -76
  30. package/dist/server.js.map +7 -6
  31. package/dist/types/client/iframe.d.ts +14 -0
  32. package/dist/types/client/index.d.ts +19 -13
  33. package/dist/types/core/appearance.d.ts +7 -6
  34. package/dist/types/core/contract.d.ts +3 -3
  35. package/dist/types/core/messages.d.ts +9 -3
  36. package/dist/types/core/operation.d.ts +27 -0
  37. package/dist/types/core/presentation.d.ts +7 -0
  38. package/dist/types/embed/bridge.d.ts +12 -0
  39. package/dist/types/embed/host.d.ts +10 -3
  40. package/dist/types/embed/index.d.ts +7 -4
  41. package/dist/types/embed/{shell.d.ts → source.d.ts} +5 -4
  42. package/dist/types/embed/sql.d.ts +4 -0
  43. package/dist/types/react/embed/bridge.d.ts +19 -10
  44. package/dist/types/react/embed/index.d.ts +0 -2
  45. package/dist/types/react/ui/DataAppSkeleton.d.ts +8 -0
  46. package/dist/types/react/ui/SearchInput.d.ts +1 -1
  47. package/dist/types/react/ui/index.d.ts +2 -0
  48. package/dist/types/react/ui/useAppAppearance.d.ts +3 -0
  49. package/dist/types/react/ui/useDataAppPresentation.d.ts +3 -0
  50. package/dist/types/react/view-controls.d.ts +1 -1
  51. package/dist/{bootstrap.js → worker.js} +161 -29
  52. package/docs/app-authoring.md +24 -4
  53. package/docs/appearance.md +21 -8
  54. package/docs/client.md +40 -3
  55. package/docs/contract.md +9 -7
  56. package/docs/embed.md +114 -19
  57. package/docs/react-embed.md +84 -24
  58. package/docs/react.md +51 -0
  59. package/docs/releasing.md +5 -0
  60. package/docs/server-bun.md +5 -0
  61. package/docs/starter-agent-instructions.md +4 -2
  62. package/docs/worker.md +57 -0
  63. package/package.json +9 -5
  64. package/dist/chunks/contract-14vxdcrs.js.map +0 -10
  65. package/dist/chunks/contract-jksbmt5q.js.map +0 -10
  66. package/dist/chunks/contract-mb5nfzwg.js.map +0 -12
  67. package/dist/chunks/contract-tkkc28tg.js.map +0 -12
  68. package/dist/chunks/contract-tqrf3ykr.js.map +0 -11
  69. package/dist/types/embed/standalone.d.ts +0 -1
  70. package/dist/types/react/embed/shell.d.ts +0 -10
  71. package/docs/bootstrap.md +0 -76
@@ -1,11 +1,13 @@
1
- import"../chunks/contract-jksbmt5q.js";
1
+ import"../chunks/contract-3bnrf5pf.js";
2
2
  import {
3
- DataAppError2
4
- } from "../chunks/contract-mb5nfzwg.js";
3
+ DataAppError2,
4
+ localFrameBridge,
5
+ getDataAppTransport2
6
+ } from "../chunks/contract-xjv197ck.js";
5
7
  import {
6
8
  getDataAppNavigation2,
7
9
  createDataClient2
8
- } from "../chunks/contract-tkkc28tg.js";
10
+ } from "../chunks/contract-4vrw9zk9.js";
9
11
  import {
10
12
  dataAppTitle2
11
13
  } from "../chunks/contract-wz59z8pq.js";
@@ -17,8 +19,10 @@ import {
17
19
  formatPercent2
18
20
  } from "../chunks/contract-mev09s5v.js";
19
21
  import {
22
+ parseAppearance2,
23
+ applyAppearance2,
20
24
  createThemeController2
21
- } from "../chunks/contract-14vxdcrs.js";
25
+ } from "../chunks/contract-farfe948.js";
22
26
  import {
23
27
  dimensionMemberKey,
24
28
  dimensionFilter2,
@@ -756,6 +760,7 @@ function SearchInput({
756
760
  endAction,
757
761
  loading = false,
758
762
  className,
763
+ onKeyDown,
759
764
  ...props
760
765
  }) {
761
766
  return /* @__PURE__ */ jsxs2("div", {
@@ -769,6 +774,15 @@ function SearchInput({
769
774
  }),
770
775
  /* @__PURE__ */ jsx3("input", {
771
776
  ...props,
777
+ onKeyDown: (event) => {
778
+ onKeyDown?.(event);
779
+ if (!event.defaultPrevented && event.key === "Escape" && !event.currentTarget.value) {
780
+ event.preventDefault();
781
+ event.stopPropagation();
782
+ event.currentTarget.blur();
783
+ event.currentTarget.closest('[role="dialog"]')?.focus();
784
+ }
785
+ },
772
786
  type: "search",
773
787
  className: classNames("altertable-search-input", className)
774
788
  }),
@@ -1190,15 +1204,20 @@ function RequestHint({
1190
1204
  "aria-atomic": "true",
1191
1205
  children: active && /* @__PURE__ */ jsxs5(Fragment3, {
1192
1206
  children: [
1193
- /* @__PURE__ */ jsx8(AppIcon, {
1194
- name: status.kind === "error" ? "error" : "loading",
1195
- size: 14,
1196
- className: status.kind === "updating" ? "altertable-request-hint-spinner" : undefined
1197
- }),
1198
- /* @__PURE__ */ jsx8("span", {
1199
- className: "altertable-request-hint-message",
1200
- title: message,
1201
- children: message
1207
+ /* @__PURE__ */ jsxs5("span", {
1208
+ className: "altertable-request-hint-copy",
1209
+ children: [
1210
+ /* @__PURE__ */ jsx8(AppIcon, {
1211
+ name: status.kind === "error" ? "error" : "loading",
1212
+ size: 14,
1213
+ className: status.kind === "updating" ? "altertable-request-hint-spinner" : undefined
1214
+ }),
1215
+ /* @__PURE__ */ jsx8("span", {
1216
+ className: "altertable-request-hint-message",
1217
+ title: message,
1218
+ children: message
1219
+ })
1220
+ ]
1202
1221
  }),
1203
1222
  status.kind === "error" && status.onRetry && /* @__PURE__ */ jsx8(Button, {
1204
1223
  variant: "ghost",
@@ -2100,7 +2119,7 @@ function DimensionPicker({
2100
2119
 
2101
2120
  // src/react/view-controls.tsx
2102
2121
  import { jsx as jsx16 } from "react/jsx-runtime";
2103
- function useViewVariables(definitions, loadFacet) {
2122
+ function useViewVariables(definitions, clientScope, loadFacet) {
2104
2123
  const variables = useAppVariables(definitions);
2105
2124
  const resolved = {};
2106
2125
  for (const name of Object.keys(definitions)) {
@@ -2114,7 +2133,13 @@ function useViewVariables(definitions, loadFacet) {
2114
2133
  const facet = filter.facet;
2115
2134
  const input = facet.input({ ...resolved, [name]: { kind: "all" } });
2116
2135
  return {
2117
- queryKey: ["dimension-facet", name, facet.operation, input],
2136
+ queryKey: [
2137
+ "dimension-facet",
2138
+ clientScope,
2139
+ name,
2140
+ facet.operation,
2141
+ input
2142
+ ],
2118
2143
  queryFn({ signal }) {
2119
2144
  return loadFacet(facet.operation, input, signal).then((result) => parseFacetOptions2(result, filter));
2120
2145
  },
@@ -2173,17 +2198,27 @@ function useViewVariables(definitions, loadFacet) {
2173
2198
  }
2174
2199
 
2175
2200
  // src/react/hooks.ts
2201
+ var clientScopes = new WeakMap;
2202
+ function getClientScope(client) {
2203
+ let scope = clientScopes.get(client);
2204
+ if (!scope) {
2205
+ scope = crypto.randomUUID();
2206
+ clientScopes.set(client, scope);
2207
+ }
2208
+ return scope;
2209
+ }
2176
2210
  function createDataHooks(client) {
2211
+ const clientScope = getClientScope(client);
2177
2212
  function useDataQuery(name, input, options) {
2178
2213
  const queryClient = useQueryClient();
2179
- const queryKey = ["data-operation", name, input];
2214
+ const queryKey = ["data-operation", clientScope, name, input];
2180
2215
  const query = useQuery({
2181
2216
  queryKey,
2182
2217
  queryFn({ signal }) {
2183
2218
  return client.query(name, input, { signal });
2184
2219
  },
2185
2220
  placeholderData(previousData, previousQuery) {
2186
- return previousQuery?.queryKey[1] === name ? previousData : undefined;
2221
+ return previousQuery?.queryKey[1] === clientScope && previousQuery.queryKey[2] === name ? previousData : undefined;
2187
2222
  },
2188
2223
  enabled: options?.enabled,
2189
2224
  ...options?.staleTime !== undefined && { staleTime: options.staleTime },
@@ -2202,11 +2237,11 @@ function createDataHooks(client) {
2202
2237
  function useDataView(name, input, options) {
2203
2238
  const query = useDataQuery(name, input, options);
2204
2239
  const [last, setLast] = useState6();
2205
- if (query.isSuccess && !query.isPlaceholderData && query.data && (last?.name !== name || last.response !== query.data)) {
2206
- setLast({ name, response: query.data });
2240
+ if (query.isSuccess && !query.isPlaceholderData && query.data && (last?.clientScope !== clientScope || last.name !== name || last.response !== query.data)) {
2241
+ setLast({ clientScope, name, response: query.data });
2207
2242
  }
2208
2243
  const sameInput = options.sameInput ?? ((left, right) => hashKey([left]) === hashKey([right]));
2209
- const response = query.data ?? (last?.name === name ? last.response : undefined);
2244
+ const response = query.data ?? (last?.clientScope === clientScope && last.name === name ? last.response : undefined);
2210
2245
  const snapshot = response && { data: response.data, input: response.input };
2211
2246
  const view = resolveDataView({
2212
2247
  requestedInput: input,
@@ -2272,7 +2307,7 @@ function createDataHooks(client) {
2272
2307
  return dimensionFilter2(config);
2273
2308
  }
2274
2309
  function useView(definition) {
2275
- const variables = useViewVariables(definition.variables, (operation, input, signal) => client.query(operation, input, {
2310
+ const variables = useViewVariables(definition.variables, clientScope, (operation, input, signal) => client.query(operation, input, {
2276
2311
  signal
2277
2312
  }).then((response) => response.data));
2278
2313
  const request = useDataView(definition.operation, resolveViewInput(definition, variables.resolved), {
@@ -2300,18 +2335,66 @@ function createDataHooks(client) {
2300
2335
  useView
2301
2336
  };
2302
2337
  }
2338
+ // src/react/ui/useDataAppPresentation.ts
2339
+ import { useEffect as useEffect5, useState as useState7 } from "react";
2340
+
2341
+ // src/core/presentation.ts
2342
+ function isDataAppPresentation(value) {
2343
+ if (!value || typeof value !== "object")
2344
+ return false;
2345
+ const presentation = value;
2346
+ return (presentation.surface === "embedded" || presentation.surface === "standalone") && (presentation.theme === "light" || presentation.theme === "dark");
2347
+ }
2348
+
2349
+ // src/react/ui/useDataAppPresentation.ts
2350
+ function presentationFromBridgeState(state) {
2351
+ const presentation = state && typeof state === "object" ? state.presentation : undefined;
2352
+ return isDataAppPresentation(presentation) ? presentation : undefined;
2353
+ }
2354
+ function useDataAppPresentation() {
2355
+ const [presentation, setPresentation] = useState7(() => presentationFromBridgeState(getDataAppTransport2()?.snapshot()));
2356
+ useEffect5(() => {
2357
+ let disposed = false;
2358
+ let unsubscribe;
2359
+ function attach(bridge) {
2360
+ if (disposed)
2361
+ return;
2362
+ unsubscribe = bridge.subscribe((state) => setPresentation(presentationFromBridgeState(state)));
2363
+ setPresentation(presentationFromBridgeState(bridge.snapshot()));
2364
+ }
2365
+ const bridge = getDataAppTransport2();
2366
+ if (bridge)
2367
+ attach(bridge);
2368
+ else
2369
+ localFrameBridge()?.connect?.().then(attach).catch(() => {});
2370
+ return () => {
2371
+ disposed = true;
2372
+ unsubscribe?.();
2373
+ };
2374
+ }, []);
2375
+ return presentation;
2376
+ }
2377
+
2303
2378
  // src/react/ui/DataApp.tsx
2304
- import {
2305
- useEffect as useEffect13,
2306
- useRef as useRef6,
2307
- useState as useState13
2308
- } from "react";
2379
+ import { useEffect as useEffect14, useRef as useRef6 } from "react";
2380
+
2381
+ // src/react/ui/useAppAppearance.ts
2382
+ import { useLayoutEffect, useState as useState8, useSyncExternalStore as useSyncExternalStore2 } from "react";
2383
+ function useAppAppearance(appearance, hostTheme) {
2384
+ const [controller] = useState8(() => createThemeController2(parseAppearance2(appearance).theme));
2385
+ const viewerPreference = useSyncExternalStore2(controller.subscribe, controller.getTheme, controller.getTheme);
2386
+ useLayoutEffect(() => applyAppearance2({
2387
+ ...parseAppearance2(appearance),
2388
+ theme: hostTheme ?? viewerPreference
2389
+ }), [appearance, hostTheme, viewerPreference]);
2390
+ return hostTheme ? undefined : controller;
2391
+ }
2309
2392
 
2310
2393
  // src/react/ui/AboutData.tsx
2311
2394
  import {
2312
- useEffect as useEffect9,
2395
+ useEffect as useEffect10,
2313
2396
  useRef as useRef4,
2314
- useState as useState9
2397
+ useState as useState11
2315
2398
  } from "react";
2316
2399
  import { useMergeRefs as useMergeRefs4 } from "@floating-ui/react";
2317
2400
 
@@ -2344,7 +2427,7 @@ function EmptyState({
2344
2427
  }
2345
2428
 
2346
2429
  // src/react/ui/shortcuts.ts
2347
- import { useEffect as useEffect5 } from "react";
2430
+ import { useEffect as useEffect6 } from "react";
2348
2431
  var shortcuts = {
2349
2432
  refresh: { modifier: "alt", code: "KeyR", key: "R" },
2350
2433
  aboutData: { modifier: "alt", code: "KeyI", key: "I" },
@@ -2372,7 +2455,7 @@ function isEditingTarget(target) {
2372
2455
  }
2373
2456
  function useShortcut(shortcut, action, enabled = true) {
2374
2457
  const { modifier, shift = false, code } = shortcut;
2375
- useEffect5(() => {
2458
+ useEffect6(() => {
2376
2459
  if (!enabled)
2377
2460
  return;
2378
2461
  function onKeyDown(event) {
@@ -2406,8 +2489,8 @@ function Kbd({ shortcut, children, className, ...props }) {
2406
2489
 
2407
2490
  // src/react/ui/QueryList.tsx
2408
2491
  import {
2409
- useEffect as useEffect6,
2410
- useState as useState7
2492
+ useEffect as useEffect7,
2493
+ useState as useState9
2411
2494
  } from "react";
2412
2495
  import { jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
2413
2496
  var KEYWORD = /\b(WITH|SELECT|FROM|WHERE|AND|OR|NOT|IN|AS|ON|JOIN|LEFT|RIGHT|INNER|FULL|OUTER|CROSS|GROUP BY|ORDER BY|HAVING|LIMIT|UNION|ALL|DISTINCT|CASE|WHEN|THEN|ELSE|END|NULL|TRUE|FALSE|BETWEEN|LIKE|ILIKE|EXISTS|VALUES|CAST|COUNT|SUM|AVG|MIN|MAX|QUALIFY|WINDOW|OVER|PARTITION|BY)\b/gi;
@@ -2425,8 +2508,8 @@ function SqlCode({ statement }) {
2425
2508
  });
2426
2509
  }
2427
2510
  function QueryFigure({ name, statement }) {
2428
- const [copyState, setCopyState] = useState7("idle");
2429
- useEffect6(() => {
2511
+ const [copyState, setCopyState] = useState9("idle");
2512
+ useEffect7(() => {
2430
2513
  if (copyState === "idle")
2431
2514
  return;
2432
2515
  const timer = window.setTimeout(() => setCopyState("idle"), 1500);
@@ -2482,8 +2565,8 @@ function QueryNotebook({
2482
2565
  queries,
2483
2566
  className
2484
2567
  }) {
2485
- const [copyState, setCopyState] = useState7("idle");
2486
- useEffect6(() => {
2568
+ const [copyState, setCopyState] = useState9("idle");
2569
+ useEffect7(() => {
2487
2570
  if (copyState === "idle")
2488
2571
  return;
2489
2572
  const timer = window.setTimeout(() => setCopyState("idle"), 1500);
@@ -2585,7 +2668,7 @@ function QueryList({
2585
2668
 
2586
2669
  // src/react/ui/Sheet.tsx
2587
2670
  import {
2588
- useEffect as useEffect7,
2671
+ useEffect as useEffect8,
2589
2672
  useId as useId5,
2590
2673
  useRef as useRef3
2591
2674
  } from "react";
@@ -2614,7 +2697,7 @@ function Sheet({
2614
2697
  const titleId = useId5();
2615
2698
  const descriptionId = useId5();
2616
2699
  const dialogRef = useMergeRefs3([dialog, ref]);
2617
- useEffect7(() => {
2700
+ useEffect8(() => {
2618
2701
  const element = dialog.current;
2619
2702
  if (!element)
2620
2703
  return;
@@ -2728,7 +2811,7 @@ function Sheet({
2728
2811
  }
2729
2812
 
2730
2813
  // src/react/ui/Tabs.tsx
2731
- import { useCallback as useCallback2, useEffect as useEffect8, useState as useState8 } from "react";
2814
+ import { useCallback as useCallback2, useEffect as useEffect9, useState as useState10 } from "react";
2732
2815
  import {
2733
2816
  Tabs,
2734
2817
  TabList,
@@ -2741,8 +2824,8 @@ function useViewTab(views, fallback) {
2741
2824
  const requested = searchParams().get("view");
2742
2825
  return views.includes(requested) ? requested : fallback;
2743
2826
  }, [views, fallback]);
2744
- const [selected, setSelected] = useState8(currentView);
2745
- useEffect8(() => {
2827
+ const [selected, setSelected] = useState10(currentView);
2828
+ useEffect9(() => {
2746
2829
  function sync() {
2747
2830
  const view = currentView();
2748
2831
  setSelected(view);
@@ -2871,8 +2954,8 @@ function AboutData({
2871
2954
  const hasQueries = (resolvedQueries ?? []).some((query) => !names || names.includes(query.name));
2872
2955
  const sheetId = subjectId(subject);
2873
2956
  const initialTab = resolveTab(tab ?? searchParams().get("tab"));
2874
- const [uncontrolledOpen, setUncontrolledOpen] = useState9(() => searchParams().get("about") === sheetId);
2875
- const [selectedTab, setSelectedTab] = useState9(initialTab);
2957
+ const [uncontrolledOpen, setUncontrolledOpen] = useState11(() => searchParams().get("about") === sheetId);
2958
+ const [selectedTab, setSelectedTab] = useState11(initialTab);
2876
2959
  const open = openProp ?? uncontrolledOpen;
2877
2960
  const triggerRef = useRef4(null);
2878
2961
  const mergedTrigger = useMergeRefs4([triggerRef, ref]);
@@ -2902,7 +2985,7 @@ function AboutData({
2902
2985
  if (open)
2903
2986
  writeSearch({ about: sheetId, tab: id });
2904
2987
  }
2905
- useEffect9(() => {
2988
+ useEffect10(() => {
2906
2989
  function sync() {
2907
2990
  const about = searchParams().get("about");
2908
2991
  const urlTab = searchParams().get("tab");
@@ -3331,11 +3414,11 @@ function LiveControl({
3331
3414
 
3332
3415
  // src/react/ui/PresentStory.tsx
3333
3416
  import {
3334
- useEffect as useEffect10,
3417
+ useEffect as useEffect11,
3335
3418
  useEffectEvent as useEffectEvent2,
3336
3419
  useId as useId7,
3337
3420
  useRef as useRef5,
3338
- useState as useState10
3421
+ useState as useState12
3339
3422
  } from "react";
3340
3423
  import { useMergeRefs as useMergeRefs5 } from "@floating-ui/react";
3341
3424
 
@@ -3343,10 +3426,10 @@ import { useMergeRefs as useMergeRefs5 } from "@floating-ui/react";
3343
3426
  import {
3344
3427
  useCallback as useCallback3,
3345
3428
  useId as useId6,
3346
- useSyncExternalStore as useSyncExternalStore2
3429
+ useSyncExternalStore as useSyncExternalStore3
3347
3430
  } from "react";
3348
3431
  import { jsx as jsx29, jsxs as jsxs20 } from "react/jsx-runtime";
3349
- var modes = [
3432
+ var themes = [
3350
3433
  { value: "light", label: "Light", icon: "lightTheme" },
3351
3434
  { value: "dark", label: "Dark", icon: "darkTheme" }
3352
3435
  ];
@@ -3361,10 +3444,10 @@ function useResolvedTheme(theme) {
3361
3444
  };
3362
3445
  }, [theme]);
3363
3446
  const snapshot = useCallback3(() => {
3364
- const mode = theme.getMode();
3365
- return mode === "system" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : mode;
3447
+ const preference = theme.getTheme();
3448
+ return preference === "system" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : preference;
3366
3449
  }, [theme]);
3367
- return useSyncExternalStore2(subscribe, snapshot, () => "light");
3450
+ return useSyncExternalStore3(subscribe, snapshot, () => "light");
3368
3451
  }
3369
3452
  function ThemeSelector({
3370
3453
  theme,
@@ -3382,7 +3465,7 @@ function ThemeSelector({
3382
3465
  className: "altertable-theme-legend",
3383
3466
  children: "Color theme"
3384
3467
  }),
3385
- modes.map(({ value, label, icon }) => /* @__PURE__ */ jsx29(Tooltip, {
3468
+ themes.map(({ value, label, icon }) => /* @__PURE__ */ jsx29(Tooltip, {
3386
3469
  content: `${label} theme`,
3387
3470
  children: /* @__PURE__ */ jsxs20("label", {
3388
3471
  children: [
@@ -3392,7 +3475,7 @@ function ThemeSelector({
3392
3475
  value,
3393
3476
  checked: selected === value,
3394
3477
  "aria-label": `${label} theme`,
3395
- onChange: () => theme.setMode(value)
3478
+ onChange: () => theme.setTheme(value)
3396
3479
  }),
3397
3480
  /* @__PURE__ */ jsx29(AppIcon, {
3398
3481
  name: icon,
@@ -3417,7 +3500,7 @@ function ThemeToggle({
3417
3500
  variant: "ghost",
3418
3501
  label: `Switch to ${next} theme`,
3419
3502
  portalRoot,
3420
- onClick: () => theme.setMode(next)
3503
+ onClick: () => theme.setTheme(next)
3421
3504
  });
3422
3505
  }
3423
3506
 
@@ -3494,7 +3577,7 @@ function PresentStory({
3494
3577
  const headline = useRef5(null);
3495
3578
  const headlineId = useId7();
3496
3579
  const contextId = useId7();
3497
- const [stepId, setStepId] = useState10(steps[0]?.id);
3580
+ const [stepId, setStepId] = useState12(steps[0]?.id);
3498
3581
  const triggerRef = useMergeRefs5([trigger, ref]);
3499
3582
  const dialogRef = useMergeRefs5([dialog, dialogProps?.ref]);
3500
3583
  const index = Math.max(0, steps.findIndex((step) => step.id === stepId));
@@ -3502,7 +3585,7 @@ function PresentStory({
3502
3585
  const stepIds = steps.map((item) => item.id).join("\x00");
3503
3586
  const unavailable = !steps.length || !!disabled;
3504
3587
  const currentSteps = useEffectEvent2(() => steps);
3505
- useEffect10(() => {
3588
+ useEffect11(() => {
3506
3589
  function syncFromUrl() {
3507
3590
  const params = searchParams();
3508
3591
  const availableSteps = currentSteps();
@@ -3518,7 +3601,7 @@ function PresentStory({
3518
3601
  syncFromUrl();
3519
3602
  return subscribeSearch(syncFromUrl);
3520
3603
  }, [stepIds]);
3521
- useEffect10(() => {
3604
+ useEffect11(() => {
3522
3605
  if (dialog.current?.open)
3523
3606
  headline.current?.focus({ preventScroll: true });
3524
3607
  }, [stepId]);
@@ -3754,8 +3837,8 @@ function PresentStory({
3754
3837
 
3755
3838
  // src/react/ui/RefreshControl.tsx
3756
3839
  import {
3757
- useEffect as useEffect11,
3758
- useState as useState11
3840
+ useEffect as useEffect12,
3841
+ useState as useState13
3759
3842
  } from "react";
3760
3843
  import { jsx as jsx31, jsxs as jsxs22 } from "react/jsx-runtime";
3761
3844
  function RefreshControl({
@@ -3767,13 +3850,13 @@ function RefreshControl({
3767
3850
  className,
3768
3851
  ...props
3769
3852
  }) {
3770
- const [refreshDelay, setRefreshDelay] = useState11({
3853
+ const [refreshDelay, setRefreshDelay] = useState13({
3771
3854
  refreshing,
3772
3855
  elapsed: false
3773
3856
  });
3774
3857
  if (refreshDelay.refreshing !== refreshing)
3775
3858
  setRefreshDelay({ refreshing, elapsed: false });
3776
- useEffect11(() => {
3859
+ useEffect12(() => {
3777
3860
  if (!refreshing)
3778
3861
  return;
3779
3862
  const timer = window.setTimeout(() => setRefreshDelay({ refreshing: true, elapsed: true }), 300);
@@ -3910,7 +3993,7 @@ function VariableBar({
3910
3993
  }
3911
3994
 
3912
3995
  // src/react/ui/DataViewToast.tsx
3913
- import { useEffect as useEffect12, useState as useState12 } from "react";
3996
+ import { useEffect as useEffect13, useState as useState14 } from "react";
3914
3997
  import { jsx as jsx34, jsxs as jsxs24 } from "react/jsx-runtime";
3915
3998
  function DataViewToast({
3916
3999
  view,
@@ -3918,10 +4001,10 @@ function DataViewToast({
3918
4001
  notice,
3919
4002
  onRetry
3920
4003
  }) {
3921
- const [delay, setDelay] = useState12({ kind: view.kind, elapsed: false });
4004
+ const [delay, setDelay] = useState14({ kind: view.kind, elapsed: false });
3922
4005
  if (delay.kind !== view.kind)
3923
4006
  setDelay({ kind: view.kind, elapsed: false });
3924
- useEffect12(() => {
4007
+ useEffect13(() => {
3925
4008
  if (view.kind !== "updating" && view.kind !== "stale-error")
3926
4009
  return;
3927
4010
  const kind = view.kind;
@@ -4216,9 +4299,11 @@ function DataApp(props) {
4216
4299
  footerActions,
4217
4300
  layoutProps
4218
4301
  } = props;
4219
- const [theme] = useState13(() => createThemeController2(config.appearance));
4302
+ const presentation = useDataAppPresentation();
4303
+ const isEmbedded = presentation?.surface === "embedded";
4304
+ const themeController = useAppAppearance(config.appearance, presentation?.theme);
4220
4305
  const bodyRef = useRef6(null);
4221
- useEffect13(() => {
4306
+ useEffect14(() => {
4222
4307
  if (import.meta.env?.DEV && bodyRef.current?.querySelector("h1"))
4223
4308
  console.warn("DataApp owns the page title. Use section headings (h2) in its body.");
4224
4309
  });
@@ -4228,6 +4313,28 @@ function DataApp(props) {
4228
4313
  organization: scopeLabels?.organization ?? config.scope.organization,
4229
4314
  environment: scopeLabels?.environment ?? config.scope.environment
4230
4315
  });
4316
+ const toolbar = /* @__PURE__ */ jsx39(AppToolbar, {
4317
+ requestState: request?.view.kind,
4318
+ refresh: refresh ?? request?.refresh,
4319
+ story: story && {
4320
+ ...story,
4321
+ title: config.title,
4322
+ scope,
4323
+ dataContext,
4324
+ empty: aboutEmpty,
4325
+ theme: themeController
4326
+ },
4327
+ aboutData: /* @__PURE__ */ jsx39(AboutData, {
4328
+ id: "data",
4329
+ shortcut: true,
4330
+ dataContext,
4331
+ empty: aboutEmpty,
4332
+ queries: queries ?? request?.queries,
4333
+ iconOnly: true,
4334
+ variant: "elevated"
4335
+ }),
4336
+ children: toolbarActions
4337
+ });
4231
4338
  return /* @__PURE__ */ jsx39(InspectionContext, {
4232
4339
  value: {
4233
4340
  dataContext,
@@ -4236,36 +4343,16 @@ function DataApp(props) {
4236
4343
  },
4237
4344
  children: /* @__PURE__ */ jsxs28(AppLayout, {
4238
4345
  ...layoutProps,
4239
- footerActions: footerActions ?? /* @__PURE__ */ jsx39(ThemeToggle, {
4240
- theme
4241
- }),
4346
+ footer: isEmbedded ? null : layoutProps?.footer,
4347
+ footerActions: footerActions ?? (themeController && /* @__PURE__ */ jsx39(ThemeToggle, {
4348
+ theme: themeController
4349
+ })),
4242
4350
  children: [
4243
- /* @__PURE__ */ jsx39(AppHeader, {
4351
+ isEmbedded ? toolbar : /* @__PURE__ */ jsx39(AppHeader, {
4244
4352
  scope,
4245
4353
  title: config.title,
4246
4354
  description,
4247
- toolbar: /* @__PURE__ */ jsx39(AppToolbar, {
4248
- requestState: request?.view.kind,
4249
- refresh: refresh ?? request?.refresh,
4250
- story: story && {
4251
- ...story,
4252
- title: config.title,
4253
- scope,
4254
- dataContext,
4255
- empty: aboutEmpty,
4256
- theme
4257
- },
4258
- aboutData: /* @__PURE__ */ jsx39(AboutData, {
4259
- id: "data",
4260
- shortcut: true,
4261
- dataContext,
4262
- empty: aboutEmpty,
4263
- queries: queries ?? request?.queries,
4264
- iconOnly: true,
4265
- variant: "elevated"
4266
- }),
4267
- children: toolbarActions
4268
- })
4355
+ toolbar
4269
4356
  }),
4270
4357
  (request?.controls ?? props.variables) && /* @__PURE__ */ jsx39(VariableBar, {
4271
4358
  children: request?.controls ?? props.variables
@@ -4514,21 +4601,20 @@ function DataWidgetContent({
4514
4601
  }) : children;
4515
4602
  const visual = /* @__PURE__ */ jsx44(WidgetContent, {
4516
4603
  bodyPadding: empty ? "flush" : bodyPadding,
4517
- footer,
4604
+ footer: empty ? undefined : footer,
4518
4605
  status,
4519
4606
  children: content
4520
4607
  });
4521
- const help = evidence && /* @__PURE__ */ jsx44(AboutData, {
4522
- ...evidence,
4608
+ const help = evidence && /* @__PURE__ */ jsxs30(AboutData, {
4523
4609
  id: evidence.id,
4524
4610
  references: {
4525
4611
  kind: "ids",
4526
4612
  glossaryIds: evidence.glossaryIds,
4527
4613
  queryNames: evidence.queryNames
4528
4614
  },
4529
- iconOnly: true,
4615
+ "aria-label": typeof title === "string" ? `Explore ${title}` : "Explore this widget",
4530
4616
  variant: "ghost",
4531
- className: "altertable-inspect-trigger",
4617
+ className: "altertable-widget-heading-trigger",
4532
4618
  tooltip: "Explore this widget",
4533
4619
  shortcut: false,
4534
4620
  title,
@@ -4538,9 +4624,12 @@ function DataWidgetContent({
4538
4624
  description,
4539
4625
  visual,
4540
4626
  visualKind: "widget",
4541
- children: /* @__PURE__ */ jsx44(AppIcon, {
4542
- name: "openDetails"
4543
- })
4627
+ children: [
4628
+ title,
4629
+ /* @__PURE__ */ jsx44(AppIcon, {
4630
+ name: "openDetails"
4631
+ })
4632
+ ]
4544
4633
  });
4545
4634
  return /* @__PURE__ */ jsxs30("section", {
4546
4635
  ...props,
@@ -4554,8 +4643,9 @@ function DataWidgetContent({
4554
4643
  children: [
4555
4644
  /* @__PURE__ */ jsxs30("h2", {
4556
4645
  id: titleId,
4646
+ "aria-label": typeof title === "string" ? title : undefined,
4557
4647
  children: [
4558
- title,
4648
+ help ?? title,
4559
4649
  count !== undefined && /* @__PURE__ */ jsx44("span", {
4560
4650
  className: "altertable-data-widget-count",
4561
4651
  children: formatCount2(count)
@@ -4573,8 +4663,7 @@ function DataWidgetContent({
4573
4663
  /* @__PURE__ */ jsx44(WidgetStatusControl, {
4574
4664
  status
4575
4665
  }),
4576
- action,
4577
- help
4666
+ action
4578
4667
  ]
4579
4668
  })
4580
4669
  ]
@@ -4605,7 +4694,7 @@ function WidgetContent({
4605
4694
  });
4606
4695
  }
4607
4696
  // src/react/ui/VisualizationWidget.tsx
4608
- import { useState as useState14 } from "react";
4697
+ import { useState as useState15 } from "react";
4609
4698
 
4610
4699
  // src/react/ui/widget-views.ts
4611
4700
  function validateWidgetViews(views, selected) {
@@ -4700,7 +4789,7 @@ function VisualizationWidgetWithViews({
4700
4789
  insight,
4701
4790
  ...shell
4702
4791
  }) {
4703
- const [selected, setSelected] = useState14(initialView ?? views[0]?.id ?? "");
4792
+ const [selected, setSelected] = useState15(initialView ?? views[0]?.id ?? "");
4704
4793
  validateWidgetViews(views, selected);
4705
4794
  return /* @__PURE__ */ jsx46(DataWidget, {
4706
4795
  ...shell,
@@ -4727,14 +4816,14 @@ function VisualizationWidgetWithViews({
4727
4816
  });
4728
4817
  }
4729
4818
  // src/react/ui/TableWidget.tsx
4730
- import { useState as useState17 } from "react";
4819
+ import { useState as useState18 } from "react";
4731
4820
 
4732
4821
  // src/react/ui/DateTimeTooltip.tsx
4733
- import { useEffect as useEffect14, useState as useState16 } from "react";
4822
+ import { useEffect as useEffect15, useState as useState17 } from "react";
4734
4823
 
4735
4824
  // src/react/ui/HelpPopover.tsx
4736
4825
  import {
4737
- useState as useState15
4826
+ useState as useState16
4738
4827
  } from "react";
4739
4828
  import {
4740
4829
  autoUpdate as autoUpdate2,
@@ -4767,8 +4856,8 @@ function HelpPopover({
4767
4856
  open: openProp,
4768
4857
  onOpenChange
4769
4858
  }) {
4770
- const [uncontrolledOpen, setUncontrolledOpen] = useState15(false);
4771
- const [dialogRoot, setDialogRoot] = useState15(null);
4859
+ const [uncontrolledOpen, setUncontrolledOpen] = useState16(false);
4860
+ const [dialogRoot, setDialogRoot] = useState16(null);
4772
4861
  const open = openProp ?? uncontrolledOpen;
4773
4862
  function setOpen(next) {
4774
4863
  onOpenChange?.(next);
@@ -4857,8 +4946,8 @@ function DateTimeTooltip({
4857
4946
  panelClassName,
4858
4947
  ...props
4859
4948
  }) {
4860
- const [now, setNow] = useState16(Date.now);
4861
- useEffect14(() => {
4949
+ const [now, setNow] = useState17(Date.now);
4950
+ useEffect15(() => {
4862
4951
  const interval = window.setInterval(() => setNow(Date.now()), 30000);
4863
4952
  return () => window.clearInterval(interval);
4864
4953
  }, []);
@@ -5058,7 +5147,7 @@ function TableWidgetContent({
5058
5147
  invariant(keys.every((key) => typeof key === "string" ? !!key.trim() : Number.isFinite(key)) && new Set(keys.map(String)).size === keys.length, "TableWidget row keys must be nonempty and unique.");
5059
5148
  const rowKeys = JSON.stringify(keys);
5060
5149
  const pageSize = pagination === false || limit !== undefined ? null : pagination?.pageSize ?? 10;
5061
- const [pageState, setPageState] = useState17({
5150
+ const [pageState, setPageState] = useState18({
5062
5151
  page: 0,
5063
5152
  rowKeys,
5064
5153
  searchValue: search?.value,
@@ -5115,7 +5204,7 @@ function TableWidgetContent({
5115
5204
  ]
5116
5205
  })
5117
5206
  });
5118
- const pager = pageSize && hits.length > 0 && /* @__PURE__ */ jsxs35("nav", {
5207
+ const pager = pageSize && pageCount > 1 && /* @__PURE__ */ jsxs35("nav", {
5119
5208
  className: "altertable-table-pagination",
5120
5209
  "aria-label": "Table pages",
5121
5210
  children: [
@@ -5587,11 +5676,10 @@ function MetricWidgetContent({
5587
5676
  const feedback = /* @__PURE__ */ jsx55(WidgetStatusControl, {
5588
5677
  status
5589
5678
  });
5590
- const help = evidence ? /* @__PURE__ */ jsx55(AboutData, {
5591
- ...evidence,
5592
- iconOnly: true,
5679
+ const help = evidence ? /* @__PURE__ */ jsxs40(AboutData, {
5680
+ "aria-label": `Explore ${label}`,
5593
5681
  variant: "ghost",
5594
- className: "altertable-inspect-trigger",
5682
+ className: "altertable-widget-heading-trigger",
5595
5683
  tooltip: "Explore this metric",
5596
5684
  references: {
5597
5685
  kind: "ids",
@@ -5611,9 +5699,12 @@ function MetricWidgetContent({
5611
5699
  ]
5612
5700
  }),
5613
5701
  visualKind: "metric",
5614
- children: /* @__PURE__ */ jsx55(AppIcon, {
5615
- name: "openDetails"
5616
- })
5702
+ children: [
5703
+ label,
5704
+ /* @__PURE__ */ jsx55(AppIcon, {
5705
+ name: "openDetails"
5706
+ })
5707
+ ]
5617
5708
  }) : null;
5618
5709
  return /* @__PURE__ */ jsxs40("div", {
5619
5710
  ...props,
@@ -5623,14 +5714,13 @@ function MetricWidgetContent({
5623
5714
  className: "altertable-metric-label",
5624
5715
  children: [
5625
5716
  /* @__PURE__ */ jsx55("span", {
5626
- children: label
5717
+ children: help ?? label
5627
5718
  }),
5628
5719
  /* @__PURE__ */ jsxs40("div", {
5629
5720
  className: "altertable-metric-help",
5630
5721
  children: [
5631
5722
  feedback,
5632
- action,
5633
- help
5723
+ action
5634
5724
  ]
5635
5725
  })
5636
5726
  ]
@@ -5649,7 +5739,7 @@ function MetricWidgetContent({
5649
5739
  });
5650
5740
  }
5651
5741
  // src/react/ui/SelectableBarChart.tsx
5652
- import { useLayoutEffect, useRef as useRef7, useState as useState18 } from "react";
5742
+ import { useLayoutEffect as useLayoutEffect2, useRef as useRef7, useState as useState19 } from "react";
5653
5743
  import { jsx as jsx56, jsxs as jsxs41 } from "react/jsx-runtime";
5654
5744
  function SelectableBarChart({
5655
5745
  items,
@@ -5659,10 +5749,10 @@ function SelectableBarChart({
5659
5749
  ariaLabel,
5660
5750
  formatValue = (value) => new Intl.NumberFormat().format(value)
5661
5751
  }) {
5662
- const [previewId, setPreviewId] = useState18(null);
5752
+ const [previewId, setPreviewId] = useState19(null);
5663
5753
  const scrollport = useRef7(null);
5664
5754
  const buttons = useRef7([]);
5665
- useLayoutEffect(() => {
5755
+ useLayoutEffect2(() => {
5666
5756
  const element = scrollport.current;
5667
5757
  if (element)
5668
5758
  element.scrollLeft = element.scrollWidth - element.clientWidth;
@@ -5747,15 +5837,85 @@ function SelectableBarChart({
5747
5837
  ]
5748
5838
  }, item.id))
5749
5839
  }),
5750
- /* @__PURE__ */ jsx56("p", {
5840
+ items.length > 0 && /* @__PURE__ */ jsx56("p", {
5751
5841
  className: "altertable-selectable-bars-help",
5752
5842
  children: "Select a bar to inspect its day. Use arrow keys to move; press Escape to clear."
5753
5843
  })
5754
5844
  ]
5755
5845
  });
5756
5846
  }
5847
+ // src/react/ui/DataAppSkeleton.tsx
5848
+ import { jsx as jsx57, jsxs as jsxs42 } from "react/jsx-runtime";
5849
+ var chartHeights = [40, 60, 50, 80, 60, 100, 80, 60];
5850
+ function DataAppSkeleton({
5851
+ header,
5852
+ footer,
5853
+ className,
5854
+ ...props
5855
+ }) {
5856
+ return /* @__PURE__ */ jsx57("output", {
5857
+ "aria-label": "Loading data app",
5858
+ ...props,
5859
+ "aria-busy": "true",
5860
+ className: classNames("altertable-data-app-skeleton", className),
5861
+ children: /* @__PURE__ */ jsxs42("div", {
5862
+ className: "altertable-data-app-skeleton-content",
5863
+ children: [
5864
+ header != null && header !== false && /* @__PURE__ */ jsx57("div", {
5865
+ className: "altertable-data-app-skeleton-header",
5866
+ children: header
5867
+ }),
5868
+ /* @__PURE__ */ jsxs42("div", {
5869
+ className: "altertable-data-app-skeleton-body",
5870
+ "aria-hidden": "true",
5871
+ children: [
5872
+ /* @__PURE__ */ jsx57(Grid, {
5873
+ columns: 3,
5874
+ gap: "md",
5875
+ children: [0, 1, 2].map((item) => /* @__PURE__ */ jsx57(MetricWidget, {
5876
+ label: "",
5877
+ loading: true
5878
+ }, item))
5879
+ }),
5880
+ /* @__PURE__ */ jsx57(VisualizationWidget, {
5881
+ title: /* @__PURE__ */ jsx57(Skeleton, {
5882
+ className: "altertable-data-app-skeleton-widget-title"
5883
+ }),
5884
+ visual: /* @__PURE__ */ jsx57("div", {
5885
+ className: "altertable-data-app-skeleton-chart",
5886
+ children: chartHeights.map((height, index) => /* @__PURE__ */ jsx57(Skeleton, {
5887
+ style: { height: `${height}%` }
5888
+ }, index))
5889
+ })
5890
+ }),
5891
+ /* @__PURE__ */ jsx57(DataWidget, {
5892
+ title: /* @__PURE__ */ jsx57(Skeleton, {
5893
+ className: "altertable-data-app-skeleton-widget-title"
5894
+ }),
5895
+ children: /* @__PURE__ */ jsx57("div", {
5896
+ className: "altertable-data-app-skeleton-rows",
5897
+ children: [0, 1, 2].map((row) => /* @__PURE__ */ jsxs42("div", {
5898
+ className: "altertable-data-app-skeleton-row",
5899
+ children: [
5900
+ /* @__PURE__ */ jsx57(Skeleton, {}),
5901
+ /* @__PURE__ */ jsx57(Skeleton, {}),
5902
+ /* @__PURE__ */ jsx57(Skeleton, {})
5903
+ ]
5904
+ }, row))
5905
+ })
5906
+ })
5907
+ ]
5908
+ }),
5909
+ footer != null && footer !== false && /* @__PURE__ */ jsx57("div", {
5910
+ className: "altertable-data-app-skeleton-footer",
5911
+ children: footer
5912
+ })
5913
+ ]
5914
+ })
5915
+ });
5916
+ }
5757
5917
  // src/react/ui/RefreshRegion.tsx
5758
- import { jsx as jsx57 } from "react/jsx-runtime";
5918
+ import { jsx as jsx58 } from "react/jsx-runtime";
5759
5919
  function RefreshRegion({
5760
5920
  refreshing,
5761
5921
  dimOnUpdate = false,
@@ -5764,10 +5924,10 @@ function RefreshRegion({
5764
5924
  className,
5765
5925
  ...props
5766
5926
  }) {
5767
- return /* @__PURE__ */ jsx57("div", {
5927
+ return /* @__PURE__ */ jsx58("div", {
5768
5928
  ...props,
5769
5929
  className: classNames("altertable-refresh-region", className),
5770
- children: /* @__PURE__ */ jsx57("div", {
5930
+ children: /* @__PURE__ */ jsx58("div", {
5771
5931
  ...contentProps,
5772
5932
  className: classNames("altertable-refresh-content", contentProps?.className),
5773
5933
  "data-refreshing": refreshing && dimOnUpdate,
@@ -5777,8 +5937,8 @@ function RefreshRegion({
5777
5937
  });
5778
5938
  }
5779
5939
  // src/react/ui/UpdatedAt.tsx
5780
- import { useEffect as useEffect15, useState as useState19 } from "react";
5781
- import { jsx as jsx58, jsxs as jsxs42 } from "react/jsx-runtime";
5940
+ import { useEffect as useEffect16, useState as useState20 } from "react";
5941
+ import { jsx as jsx59, jsxs as jsxs43 } from "react/jsx-runtime";
5782
5942
  function UpdatedAt({
5783
5943
  timestamp,
5784
5944
  locale,
@@ -5787,8 +5947,8 @@ function UpdatedAt({
5787
5947
  triggerClassName,
5788
5948
  ...props
5789
5949
  }) {
5790
- const [now, setNow] = useState19(Date.now);
5791
- useEffect15(() => {
5950
+ const [now, setNow] = useState20(Date.now);
5951
+ useEffect16(() => {
5792
5952
  const interval = window.setInterval(() => setNow(Date.now()), 30000);
5793
5953
  return () => window.clearInterval(interval);
5794
5954
  }, []);
@@ -5802,11 +5962,11 @@ function UpdatedAt({
5802
5962
  else if (elapsedMinutes >= 1)
5803
5963
  age = relative.format(-elapsedMinutes, "minute");
5804
5964
  const date = new Date(timestamp);
5805
- return /* @__PURE__ */ jsx58(DateTimeTooltip, {
5965
+ return /* @__PURE__ */ jsx59(DateTimeTooltip, {
5806
5966
  ...props,
5807
5967
  date,
5808
5968
  triggerClassName: ["altertable-updated-at", triggerClassName].filter(Boolean).join(" "),
5809
- children: children ?? /* @__PURE__ */ jsxs42("time", {
5969
+ children: children ?? /* @__PURE__ */ jsxs43("time", {
5810
5970
  dateTime: date.toISOString(),
5811
5971
  children: [
5812
5972
  label,
@@ -5889,7 +6049,7 @@ function createDataContext(queryNames) {
5889
6049
  return bindDataContext;
5890
6050
  }
5891
6051
  // src/react/ui/data-identifiers.tsx
5892
- import { jsx as jsx59, jsxs as jsxs43 } from "react/jsx-runtime";
6052
+ import { jsx as jsx60, jsxs as jsxs44 } from "react/jsx-runtime";
5893
6053
  function qualifiedName(definition) {
5894
6054
  const table = definition.kind === "table" ? definition : definition.table;
5895
6055
  const path = [table.catalog, table.schema, table.name].join(".");
@@ -5925,23 +6085,23 @@ function defineDataIdentifiers({ tables, columns }) {
5925
6085
  const shown = display ?? (definition.kind === "table" ? "qualified" : "short");
5926
6086
  const table = definition.kind === "table" ? definition : definition.table;
5927
6087
  const prefix = definition.kind === "table" ? [table.catalog, table.schema] : [table.catalog, table.schema, table.name];
5928
- return /* @__PURE__ */ jsxs43("code", {
6088
+ return /* @__PURE__ */ jsxs44("code", {
5929
6089
  className: "altertable-data-identifier",
5930
6090
  "data-kind": definition.kind,
5931
6091
  title: qualified,
5932
6092
  "data-identifier-id": id,
5933
6093
  children: [
5934
- shown === "qualified" && /* @__PURE__ */ jsx59("span", {
6094
+ shown === "qualified" && /* @__PURE__ */ jsx60("span", {
5935
6095
  className: "altertable-data-identifier-path",
5936
- children: prefix.map((segment, index) => /* @__PURE__ */ jsxs43("span", {
6096
+ children: prefix.map((segment, index) => /* @__PURE__ */ jsxs44("span", {
5937
6097
  children: [
5938
6098
  segment,
5939
6099
  ".",
5940
- /* @__PURE__ */ jsx59("wbr", {})
6100
+ /* @__PURE__ */ jsx60("wbr", {})
5941
6101
  ]
5942
6102
  }, index))
5943
6103
  }),
5944
- /* @__PURE__ */ jsx59("span", {
6104
+ /* @__PURE__ */ jsx60("span", {
5945
6105
  className: "altertable-data-identifier-name",
5946
6106
  children: definition.name
5947
6107
  })
@@ -5954,7 +6114,7 @@ function defineDataIdentifiers({ tables, columns }) {
5954
6114
  };
5955
6115
  }
5956
6116
  // src/react/ui/GlossaryExplanation.tsx
5957
- import { jsx as jsx60 } from "react/jsx-runtime";
6117
+ import { jsx as jsx61 } from "react/jsx-runtime";
5958
6118
  function GlossaryExplanation({
5959
6119
  entry,
5960
6120
  empty,
@@ -5966,7 +6126,7 @@ function GlossaryExplanation({
5966
6126
  className,
5967
6127
  ...props
5968
6128
  }) {
5969
- return /* @__PURE__ */ jsx60(AboutData, {
6129
+ return /* @__PURE__ */ jsx61(AboutData, {
5970
6130
  ...props,
5971
6131
  shortcut: false,
5972
6132
  iconOnly: true,
@@ -5981,28 +6141,28 @@ function GlossaryExplanation({
5981
6141
  className: className ?? "altertable-inspect-trigger",
5982
6142
  tooltip: "Explore this term",
5983
6143
  "aria-label": props["aria-label"] ?? `Explore ${entry.term}`,
5984
- children: /* @__PURE__ */ jsx60(AppIcon, {
6144
+ children: /* @__PURE__ */ jsx61(AppIcon, {
5985
6145
  name: "openDetails"
5986
6146
  })
5987
6147
  });
5988
6148
  }
5989
6149
  // src/react/ui/GlossaryDefinition.tsx
5990
- import { jsx as jsx61, jsxs as jsxs44 } from "react/jsx-runtime";
6150
+ import { jsx as jsx62, jsxs as jsxs45 } from "react/jsx-runtime";
5991
6151
  function GlossaryDefinition({
5992
6152
  entry,
5993
6153
  children
5994
6154
  }) {
5995
- return /* @__PURE__ */ jsxs44(HelpPopover, {
6155
+ return /* @__PURE__ */ jsxs45(HelpPopover, {
5996
6156
  trigger: children ?? entry.term,
5997
6157
  triggerLabel: `Explain ${entry.term}`,
5998
6158
  label: entry.term,
5999
6159
  triggerClassName: "altertable-glossary-definition-trigger",
6000
6160
  panelClassName: "altertable-glossary-definition-popover",
6001
6161
  children: [
6002
- /* @__PURE__ */ jsx61("strong", {
6162
+ /* @__PURE__ */ jsx62("strong", {
6003
6163
  children: entry.term
6004
6164
  }),
6005
- /* @__PURE__ */ jsx61("div", {
6165
+ /* @__PURE__ */ jsx62("div", {
6006
6166
  children: entry.definition
6007
6167
  })
6008
6168
  ]
@@ -6024,6 +6184,7 @@ export {
6024
6184
  ContentSkeleton,
6025
6185
  DataApp,
6026
6186
  DataAppProvider,
6187
+ DataAppSkeleton,
6027
6188
  DataBoundary,
6028
6189
  DataSection,
6029
6190
  DataTable,
@@ -6102,4 +6263,4 @@ export {
6102
6263
  writeSearch
6103
6264
  };
6104
6265
 
6105
- //# debugId=20DE22C9D34BA1BA64756E2164756E21
6266
+ //# debugId=A173C527FEF0F21F64756E2164756E21