@pattern-stack/frontend-patterns 0.2.0-alpha.16 → 0.2.0-alpha.19

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 (87) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/dist/atoms/components/data/Duration/Duration.d.ts +11 -0
  3. package/dist/atoms/components/data/Duration/Duration.d.ts.map +1 -0
  4. package/dist/atoms/components/data/Duration/index.d.ts +2 -0
  5. package/dist/atoms/components/data/Duration/index.d.ts.map +1 -0
  6. package/dist/atoms/components/data/LiveIndicator/LiveIndicator.d.ts +12 -0
  7. package/dist/atoms/components/data/LiveIndicator/LiveIndicator.d.ts.map +1 -0
  8. package/dist/atoms/components/data/LiveIndicator/index.d.ts +2 -0
  9. package/dist/atoms/components/data/LiveIndicator/index.d.ts.map +1 -0
  10. package/dist/atoms/components/data/Sparkline/Sparkline.d.ts +16 -0
  11. package/dist/atoms/components/data/Sparkline/Sparkline.d.ts.map +1 -0
  12. package/dist/atoms/components/data/Sparkline/index.d.ts +2 -0
  13. package/dist/atoms/components/data/Sparkline/index.d.ts.map +1 -0
  14. package/dist/atoms/components/data/Timestamp/Timestamp.d.ts +13 -0
  15. package/dist/atoms/components/data/Timestamp/Timestamp.d.ts.map +1 -0
  16. package/dist/atoms/components/data/Timestamp/index.d.ts +2 -0
  17. package/dist/atoms/components/data/Timestamp/index.d.ts.map +1 -0
  18. package/dist/atoms/components/data/index.d.ts +4 -0
  19. package/dist/atoms/components/data/index.d.ts.map +1 -1
  20. package/dist/frontend-patterns.css +1 -1
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.es.js +299 -42
  24. package/dist/index.es.js.map +1 -1
  25. package/dist/index.js +299 -42
  26. package/dist/index.js.map +1 -1
  27. package/dist/swebrain/SweBrainShowcase.d.ts +8 -0
  28. package/dist/swebrain/SweBrainShowcase.d.ts.map +1 -0
  29. package/dist/swebrain/atoms/Card.d.ts +15 -0
  30. package/dist/swebrain/atoms/Card.d.ts.map +1 -0
  31. package/dist/swebrain/atoms/Chip.d.ts +17 -0
  32. package/dist/swebrain/atoms/Chip.d.ts.map +1 -0
  33. package/dist/swebrain/atoms/Duration.d.ts +7 -0
  34. package/dist/swebrain/atoms/Duration.d.ts.map +1 -0
  35. package/dist/swebrain/atoms/EmptyCell.d.ts +5 -0
  36. package/dist/swebrain/atoms/EmptyCell.d.ts.map +1 -0
  37. package/dist/swebrain/atoms/Hand.d.ts +8 -0
  38. package/dist/swebrain/atoms/Hand.d.ts.map +1 -0
  39. package/dist/swebrain/atoms/ID.d.ts +9 -0
  40. package/dist/swebrain/atoms/ID.d.ts.map +1 -0
  41. package/dist/swebrain/atoms/IdTag.d.ts +9 -0
  42. package/dist/swebrain/atoms/IdTag.d.ts.map +1 -0
  43. package/dist/swebrain/atoms/KV.d.ts +7 -0
  44. package/dist/swebrain/atoms/KV.d.ts.map +1 -0
  45. package/dist/swebrain/atoms/LiveIndicator.d.ts +7 -0
  46. package/dist/swebrain/atoms/LiveIndicator.d.ts.map +1 -0
  47. package/dist/swebrain/atoms/PoolChip.d.ts +14 -0
  48. package/dist/swebrain/atoms/PoolChip.d.ts.map +1 -0
  49. package/dist/swebrain/atoms/Row.d.ts +10 -0
  50. package/dist/swebrain/atoms/Row.d.ts.map +1 -0
  51. package/dist/swebrain/atoms/Sparkline.d.ts +11 -0
  52. package/dist/swebrain/atoms/Sparkline.d.ts.map +1 -0
  53. package/dist/swebrain/atoms/StatusBadge.d.ts +11 -0
  54. package/dist/swebrain/atoms/StatusBadge.d.ts.map +1 -0
  55. package/dist/swebrain/atoms/StatusDot.d.ts +11 -0
  56. package/dist/swebrain/atoms/StatusDot.d.ts.map +1 -0
  57. package/dist/swebrain/atoms/Timestamp.d.ts +8 -0
  58. package/dist/swebrain/atoms/Timestamp.d.ts.map +1 -0
  59. package/dist/swebrain/atoms/index.d.ts +34 -0
  60. package/dist/swebrain/atoms/index.d.ts.map +1 -0
  61. package/dist/swebrain/atoms/pool-tokens.d.ts +14 -0
  62. package/dist/swebrain/atoms/pool-tokens.d.ts.map +1 -0
  63. package/dist/swebrain/atoms/tokens.d.ts +96 -0
  64. package/dist/swebrain/atoms/tokens.d.ts.map +1 -0
  65. package/dist/swebrain/index.d.ts +4 -0
  66. package/dist/swebrain/index.d.ts.map +1 -0
  67. package/dist/swebrain/lib/favs.d.ts +5 -0
  68. package/dist/swebrain/lib/favs.d.ts.map +1 -0
  69. package/dist/swebrain/lib/vendors.d.ts +14 -0
  70. package/dist/swebrain/lib/vendors.d.ts.map +1 -0
  71. package/dist/swebrain/molecules/PoolLegend.d.ts +8 -0
  72. package/dist/swebrain/molecules/PoolLegend.d.ts.map +1 -0
  73. package/dist/swebrain/molecules/SearchInput.d.ts +17 -0
  74. package/dist/swebrain/molecules/SearchInput.d.ts.map +1 -0
  75. package/dist/swebrain/molecules/StatCard.d.ts +11 -0
  76. package/dist/swebrain/molecules/StatCard.d.ts.map +1 -0
  77. package/dist/swebrain/molecules/TimeRangePicker.d.ts +18 -0
  78. package/dist/swebrain/molecules/TimeRangePicker.d.ts.map +1 -0
  79. package/dist/swebrain/molecules/index.d.ts +9 -0
  80. package/dist/swebrain/molecules/index.d.ts.map +1 -0
  81. package/dist/sync/createEntityHooks.d.ts.map +1 -1
  82. package/dist/sync/index.d.ts +1 -1
  83. package/dist/sync/index.d.ts.map +1 -1
  84. package/dist/sync/types.d.ts +110 -23
  85. package/dist/sync/types.d.ts.map +1 -1
  86. package/dist/templates/factory.d.ts.map +1 -1
  87. package/package.json +2 -1
package/dist/index.es.js CHANGED
@@ -7750,6 +7750,201 @@ const TruncatedText = ({
7750
7750
  }
7751
7751
  );
7752
7752
  };
7753
+ function formatAuto(ms) {
7754
+ if (ms < 1e3) {
7755
+ return { visible: `${ms}ms`, spoken: `${ms} milliseconds` };
7756
+ }
7757
+ if (ms < 6e4) {
7758
+ const secs = ms / 1e3;
7759
+ return {
7760
+ visible: `${secs.toFixed(1)}s`,
7761
+ spoken: `${secs.toFixed(1)} seconds`
7762
+ };
7763
+ }
7764
+ if (ms < 36e5) {
7765
+ const m = Math.floor(ms / 6e4);
7766
+ const s = Math.round(ms % 6e4 / 1e3);
7767
+ return { visible: `${m}m ${s}s`, spoken: `${m} minutes ${s} seconds` };
7768
+ }
7769
+ if (ms < 864e5) {
7770
+ const h2 = Math.floor(ms / 36e5);
7771
+ const m = Math.round(ms % 36e5 / 6e4);
7772
+ return { visible: `${h2}h ${m}m`, spoken: `${h2} hours ${m} minutes` };
7773
+ }
7774
+ const d = Math.floor(ms / 864e5);
7775
+ const h = Math.round(ms % 864e5 / 36e5);
7776
+ return { visible: `${d}d ${h}h`, spoken: `${d} days ${h} hours` };
7777
+ }
7778
+ function formatS(ms) {
7779
+ const secs = ms / 1e3;
7780
+ return {
7781
+ visible: `${secs.toFixed(1)}s`,
7782
+ spoken: `${secs.toFixed(1)} seconds`
7783
+ };
7784
+ }
7785
+ function formatMs(ms) {
7786
+ return { visible: `${ms}ms`, spoken: `${ms} milliseconds` };
7787
+ }
7788
+ function Duration({ ms, precision = "auto", className }) {
7789
+ const { visible, spoken } = precision === "s" ? formatS(ms) : precision === "ms" ? formatMs(ms) : formatAuto(ms);
7790
+ return /* @__PURE__ */ jsx(
7791
+ "span",
7792
+ {
7793
+ "aria-label": spoken,
7794
+ className: cn("font-mono text-xs text-muted-foreground", className),
7795
+ children: visible
7796
+ }
7797
+ );
7798
+ }
7799
+ function toDate(v) {
7800
+ return v instanceof Date ? v : new Date(v);
7801
+ }
7802
+ function formatRelative(date, now) {
7803
+ const diffMs = now.getTime() - date.getTime();
7804
+ const abs = Math.abs(diffMs);
7805
+ const suffix = diffMs >= 0 ? "ago" : "from now";
7806
+ if (abs < 6e4) return "just now";
7807
+ if (abs < 36e5) {
7808
+ const m = Math.floor(abs / 6e4);
7809
+ return `${m}m ${suffix}`;
7810
+ }
7811
+ if (abs < 864e5) {
7812
+ const h = Math.floor(abs / 36e5);
7813
+ return `${h}h ${suffix}`;
7814
+ }
7815
+ if (abs < 6048e5) {
7816
+ const d = Math.floor(abs / 864e5);
7817
+ return d === 1 ? "yesterday" : `${d}d ${suffix}`;
7818
+ }
7819
+ return date.toLocaleDateString(void 0);
7820
+ }
7821
+ function formatAbsolute(date, tz) {
7822
+ return date.toLocaleString(void 0, {
7823
+ dateStyle: "short",
7824
+ timeStyle: "short",
7825
+ timeZone: tz
7826
+ });
7827
+ }
7828
+ function Timestamp({
7829
+ value,
7830
+ format = "relative",
7831
+ tz,
7832
+ className
7833
+ }) {
7834
+ const date = toDate(value);
7835
+ const iso = date.toISOString();
7836
+ const [now, setNow] = useState(() => /* @__PURE__ */ new Date());
7837
+ useEffect(() => {
7838
+ if (format === "absolute") return;
7839
+ const id = setInterval(() => setNow(/* @__PURE__ */ new Date()), 3e4);
7840
+ return () => clearInterval(id);
7841
+ }, [format]);
7842
+ const absolute = formatAbsolute(date, tz);
7843
+ const relative = formatRelative(date, now);
7844
+ const display = format === "relative" ? relative : absolute;
7845
+ const title = format === "both" ? relative : void 0;
7846
+ return /* @__PURE__ */ jsx(
7847
+ "time",
7848
+ {
7849
+ dateTime: iso,
7850
+ title,
7851
+ className: cn("font-mono text-xs text-muted-foreground", className),
7852
+ children: display
7853
+ }
7854
+ );
7855
+ }
7856
+ function Sparkline({
7857
+ data,
7858
+ width = 140,
7859
+ height = 28,
7860
+ color = "hsl(var(--muted-foreground))",
7861
+ fill,
7862
+ strokeWidth = 1.2,
7863
+ markLast = false
7864
+ }) {
7865
+ if (data.length < 2) {
7866
+ return /* @__PURE__ */ jsx("svg", { width, height, "aria-hidden": true });
7867
+ }
7868
+ const min = Math.min(...data);
7869
+ const max = Math.max(...data);
7870
+ const range = max - min || 1;
7871
+ const pad = strokeWidth;
7872
+ const innerW = width - pad * 2;
7873
+ const innerH = height - pad * 2;
7874
+ const points = data.map((v, i) => {
7875
+ const x = pad + i / (data.length - 1) * innerW;
7876
+ const y = pad + innerH - (v - min) / range * innerH;
7877
+ return [x, y];
7878
+ });
7879
+ const polyline = points.map(([x, y]) => `${x.toFixed(2)},${y.toFixed(2)}`).join(" ");
7880
+ const firstPt = points[0];
7881
+ const lastPt = points[points.length - 1];
7882
+ let fillPath;
7883
+ if (fill) {
7884
+ fillPath = [
7885
+ `${firstPt[0].toFixed(2)},${(pad + innerH).toFixed(2)}`,
7886
+ ...points.map(([x, y]) => `${x.toFixed(2)},${y.toFixed(2)}`),
7887
+ `${lastPt[0].toFixed(2)},${(pad + innerH).toFixed(2)}`
7888
+ ].join(" ");
7889
+ }
7890
+ return /* @__PURE__ */ jsxs(
7891
+ "svg",
7892
+ {
7893
+ width,
7894
+ height,
7895
+ viewBox: `0 0 ${width} ${height}`,
7896
+ "aria-hidden": true,
7897
+ style: { display: "block", overflow: "visible" },
7898
+ children: [
7899
+ fillPath && /* @__PURE__ */ jsx("polygon", { points: fillPath, fill, stroke: "none" }),
7900
+ /* @__PURE__ */ jsx(
7901
+ "polyline",
7902
+ {
7903
+ points: polyline,
7904
+ fill: "none",
7905
+ stroke: color,
7906
+ strokeWidth,
7907
+ strokeLinejoin: "round",
7908
+ strokeLinecap: "round"
7909
+ }
7910
+ ),
7911
+ markLast && /* @__PURE__ */ jsx("circle", { cx: lastPt[0], cy: lastPt[1], r: strokeWidth * 2, fill: color })
7912
+ ]
7913
+ }
7914
+ );
7915
+ }
7916
+ function LiveIndicator({
7917
+ active,
7918
+ label = "Live",
7919
+ className
7920
+ }) {
7921
+ const ariaLabel = active ? `${label} — connected` : `${label} — paused`;
7922
+ return /* @__PURE__ */ jsxs(
7923
+ "span",
7924
+ {
7925
+ role: "status",
7926
+ "aria-live": "polite",
7927
+ "aria-label": ariaLabel,
7928
+ className: cn(
7929
+ "inline-flex items-center gap-2 text-xs font-mono",
7930
+ active ? "text-primary" : "text-muted-foreground",
7931
+ className
7932
+ ),
7933
+ children: [
7934
+ /* @__PURE__ */ jsx(
7935
+ "span",
7936
+ {
7937
+ className: cn(
7938
+ "inline-block w-2 h-2 rounded-full",
7939
+ active ? "bg-primary animate-pulse" : "bg-muted-foreground/40"
7940
+ )
7941
+ }
7942
+ ),
7943
+ label
7944
+ ]
7945
+ }
7946
+ );
7947
+ }
7753
7948
  const defaultActivityIconMap = {
7754
7949
  user: {
7755
7950
  icon: Users,
@@ -10601,7 +10796,7 @@ const SidebarButton = ({
10601
10796
  "span",
10602
10797
  {
10603
10798
  className: cn(
10604
- "text-sm font-medium flex-1 text-left",
10799
+ "text-sm font-medium flex-1 text-left whitespace-nowrap",
10605
10800
  active ? `text-category-${category}` : "text-foreground"
10606
10801
  ),
10607
10802
  children: label
@@ -15697,14 +15892,12 @@ function createReactApp(config) {
15697
15892
  if (enableRouting) {
15698
15893
  tree = /* @__PURE__ */ jsx(NavigationProvider, { initialNavigation: navigation, children: /* @__PURE__ */ jsx(SidebarProvider, { children: tree }) });
15699
15894
  }
15700
- if (enableAuth) {
15701
- const authMode = (auth == null ? void 0 : auth.mode) || "pattern-stack";
15702
- if (authMode === "none") {
15703
- setGlobalAuthService(null);
15704
- tree = /* @__PURE__ */ jsx(NoAuthProvider, { children: tree });
15705
- } else {
15706
- tree = /* @__PURE__ */ jsx(AuthProvider, { config: auth, children: tree });
15707
- }
15895
+ const authMode = (auth == null ? void 0 : auth.mode) || "pattern-stack";
15896
+ if (enableAuth && authMode !== "none") {
15897
+ tree = /* @__PURE__ */ jsx(AuthProvider, { config: auth, children: tree });
15898
+ } else {
15899
+ setGlobalAuthService(null);
15900
+ tree = /* @__PURE__ */ jsx(NoAuthProvider, { children: tree });
15708
15901
  }
15709
15902
  if (enableQuery) {
15710
15903
  tree = /* @__PURE__ */ jsxs(QueryClientProvider, { client: queryClient, children: [
@@ -18854,20 +19047,50 @@ function createEntityHooks(config) {
18854
19047
  /** Key for a specific entity detail query */
18855
19048
  detail: (id) => [...keys.details(), id]
18856
19049
  };
18857
- function useListSync(filters) {
19050
+ const DEFAULT_PAGE_SIZE = 50;
19051
+ function toPage(raw, requestedPage, requestedPageSize) {
19052
+ if (Array.isArray(raw)) {
19053
+ const items2 = raw;
19054
+ return {
19055
+ items: items2,
19056
+ page: requestedPage,
19057
+ pageCount: 1,
19058
+ total: items2.length,
19059
+ pageSize: requestedPageSize || items2.length || DEFAULT_PAGE_SIZE,
19060
+ nextCursor: null
19061
+ };
19062
+ }
19063
+ const env2 = raw ?? {};
19064
+ const items = Array.isArray(env2.items) ? env2.items : [];
19065
+ const pageSize = typeof env2.pageSize === "number" && env2.pageSize > 0 ? env2.pageSize : requestedPageSize || DEFAULT_PAGE_SIZE;
19066
+ const total = typeof env2.total === "number" ? env2.total : items.length;
19067
+ const pageCount = typeof env2.pageCount === "number" ? env2.pageCount : Math.max(1, Math.ceil(total / Math.max(1, pageSize)));
19068
+ return {
19069
+ items,
19070
+ page: typeof env2.page === "number" ? env2.page : requestedPage,
19071
+ pageCount,
19072
+ total,
19073
+ pageSize,
19074
+ nextCursor: env2.nextCursor ?? null
19075
+ };
19076
+ }
19077
+ function useListSync(params, requestedPage, requestedPageSize) {
18858
19078
  const query = useQuery({
18859
- queryKey: keys.list(filters),
18860
- queryFn: () => api.list(filters),
19079
+ queryKey: keys.list(params),
19080
+ queryFn: () => api.list(params),
18861
19081
  staleTime
18862
19082
  });
19083
+ const pageEnvelope = useMemo(
19084
+ () => query.data === void 0 ? void 0 : toPage(query.data, requestedPage, requestedPageSize),
19085
+ [query.data, requestedPage, requestedPageSize]
19086
+ );
18863
19087
  useEffect(() => {
18864
19088
  var _a, _b;
18865
- if (query.data) {
18866
- const items = Array.isArray(query.data) ? query.data : query.data.items || [];
18867
- (_b = (_a = collection.utils) == null ? void 0 : _a.writeUpsert) == null ? void 0 : _b.call(_a, items);
19089
+ if (pageEnvelope) {
19090
+ (_b = (_a = collection.utils) == null ? void 0 : _a.writeUpsert) == null ? void 0 : _b.call(_a, pageEnvelope.items);
18868
19091
  }
18869
- }, [query.data]);
18870
- return query;
19092
+ }, [pageEnvelope]);
19093
+ return { query, pageEnvelope };
18871
19094
  }
18872
19095
  function useGetSync(id) {
18873
19096
  const query = useQuery({
@@ -18885,41 +19108,71 @@ function createEntityHooks(config) {
18885
19108
  return query;
18886
19109
  }
18887
19110
  function useList(options = {}) {
18888
- const { where, orderBy, enabled = true } = options;
18889
- const sync = useListSync(enabled ? where : void 0);
19111
+ const { where, orderBy, enabled = true, pageSize, cursor } = options;
19112
+ const [page, setPageState] = useState(() => Math.max(1, options.page ?? 1));
19113
+ const params = useMemo(() => {
19114
+ if (!enabled) return void 0;
19115
+ const p = { page };
19116
+ if (pageSize !== void 0) p.pageSize = pageSize;
19117
+ if (cursor !== void 0) p.cursor = cursor;
19118
+ if (orderBy) {
19119
+ p.sort_by = orderBy.field;
19120
+ p.sort_order = orderBy.direction;
19121
+ }
19122
+ if (where) Object.assign(p, where);
19123
+ return p;
19124
+ }, [enabled, page, pageSize, cursor, orderBy, where]);
19125
+ const { query: sync, pageEnvelope } = useListSync(params, page, pageSize ?? DEFAULT_PAGE_SIZE);
19126
+ const pageIds = useMemo(() => {
19127
+ if (!pageEnvelope) return [];
19128
+ return pageEnvelope.items.map((item) => item.id).filter((id) => typeof id === "string");
19129
+ }, [pageEnvelope]);
18890
19130
  const liveResult = useLiveQuery(collection);
18891
19131
  const data = useMemo(() => {
18892
- let items = liveResult.data ?? [];
18893
- if (where) {
18894
- items = items.filter((item) => {
18895
- return Object.entries(where).every(([key, value]) => {
18896
- if (value === void 0) return true;
18897
- const itemValue = item[key];
18898
- if (Array.isArray(value)) {
18899
- return value.includes(itemValue);
18900
- }
18901
- return itemValue === value;
18902
- });
18903
- });
19132
+ var _a, _b;
19133
+ const live = liveResult.data ?? [];
19134
+ const byId = /* @__PURE__ */ new Map();
19135
+ for (const row of live) {
19136
+ const id = row.id;
19137
+ if (typeof id === "string") byId.set(id, row);
18904
19138
  }
18905
- if (orderBy) {
18906
- items = [...items].sort((a, b) => {
18907
- const aVal = a[orderBy.field];
18908
- const bVal = b[orderBy.field];
18909
- if (aVal < bVal) return orderBy.direction === "asc" ? -1 : 1;
18910
- if (aVal > bVal) return orderBy.direction === "asc" ? 1 : -1;
18911
- return 0;
18912
- });
19139
+ const rows = [];
19140
+ for (const id of pageIds) {
19141
+ const row = byId.get(id) ?? // eslint-disable-next-line @typescript-eslint/no-explicit-any
19142
+ ((_b = (_a = collection.state) == null ? void 0 : _a.get) == null ? void 0 : _b.call(_a, id));
19143
+ if (row !== void 0) rows.push(row);
18913
19144
  }
18914
- return items;
18915
- }, [liveResult.data, where, orderBy]);
19145
+ return rows;
19146
+ }, [liveResult.data, pageIds]);
19147
+ const pageCount = (pageEnvelope == null ? void 0 : pageEnvelope.pageCount) ?? 1;
19148
+ const total = (pageEnvelope == null ? void 0 : pageEnvelope.total) ?? data.length;
19149
+ const resolvedPageSize = (pageEnvelope == null ? void 0 : pageEnvelope.pageSize) ?? pageSize ?? DEFAULT_PAGE_SIZE;
19150
+ const currentPage = (pageEnvelope == null ? void 0 : pageEnvelope.page) ?? page;
19151
+ const setPage = useCallback(
19152
+ (next2) => {
19153
+ const clamped = Math.max(1, pageCount > 0 ? Math.min(next2, pageCount) : next2);
19154
+ setPageState(clamped);
19155
+ },
19156
+ [pageCount]
19157
+ );
19158
+ const next = useCallback(() => setPage(page + 1), [setPage, page]);
19159
+ const prev = useCallback(() => setPage(page - 1), [setPage, page]);
18916
19160
  return {
18917
19161
  data,
18918
19162
  isLoading: sync.isLoading || liveResult.isLoading,
18919
19163
  isError: sync.isError,
18920
19164
  error: sync.error,
18921
19165
  refetch: sync.refetch,
18922
- collection
19166
+ collection,
19167
+ page: currentPage,
19168
+ pageCount,
19169
+ total,
19170
+ pageSize: resolvedPageSize,
19171
+ setPage,
19172
+ next,
19173
+ prev,
19174
+ hasNext: currentPage < pageCount,
19175
+ hasPrev: currentPage > 1
18923
19176
  };
18924
19177
  }
18925
19178
  function useGet(id, options = {}) {
@@ -19171,6 +19424,7 @@ export {
19171
19424
  DropdownMenuSubContent,
19172
19425
  DropdownMenuSubTrigger,
19173
19426
  DropdownMenuTrigger,
19427
+ Duration,
19174
19428
  EmptyState,
19175
19429
  EnhancedDataTemplate,
19176
19430
  EntityIcon,
@@ -19190,6 +19444,7 @@ export {
19190
19444
  ListCard,
19191
19445
  ListPageTemplate,
19192
19446
  ListToolbar,
19447
+ LiveIndicator,
19193
19448
  Loading,
19194
19449
  LoginForm,
19195
19450
  LogoutButton,
@@ -19234,6 +19489,7 @@ export {
19234
19489
  SkeletonButton,
19235
19490
  SkeletonCard,
19236
19491
  SkeletonText,
19492
+ Sparkline,
19237
19493
  Spinner,
19238
19494
  StatCard,
19239
19495
  StyleGuide,
@@ -19251,6 +19507,7 @@ export {
19251
19507
  TabsContent,
19252
19508
  TabsList,
19253
19509
  TabsTrigger,
19510
+ Timestamp,
19254
19511
  Toast,
19255
19512
  ToastContainer,
19256
19513
  Tooltip,