@parallelworks/ui 0.84.2 → 0.86.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 (39) hide show
  1. package/README.md +1 -1
  2. package/dist/ai/components/ChatMessage.js +6 -0
  3. package/dist/ai/core/ChatProvider.js +16 -5
  4. package/dist/components/CopyButton.d.ts +7 -2
  5. package/dist/components/CopyButton.js +11 -52
  6. package/dist/components/PageHeaderAction.d.ts +12 -5
  7. package/dist/components/PageHeaderAction.js +10 -9
  8. package/dist/components/Pagination.d.ts +4 -2
  9. package/dist/components/Pagination.js +54 -17
  10. package/dist/components/Provider.d.ts +4 -0
  11. package/dist/components/Provider.js +5 -1
  12. package/dist/components/RunStatusIcon.js +14 -17
  13. package/dist/components/StatusBadge.d.ts +10 -1
  14. package/dist/components/StatusBadge.js +27 -15
  15. package/dist/components/StatusIcons.d.ts +2 -0
  16. package/dist/components/StatusIcons.js +5 -3
  17. package/dist/components/Tabs.js +31 -2
  18. package/dist/components/Tag.d.ts +2 -1
  19. package/dist/components/Tag.js +5 -4
  20. package/dist/components/chart.d.ts +57 -10
  21. package/dist/components/chart.js +117 -22
  22. package/dist/components/scrollFade.d.ts +13 -0
  23. package/dist/components/scrollFade.js +51 -0
  24. package/dist/file-explorer/FileExplorer.js +8 -0
  25. package/dist/icons.d.ts +14 -1
  26. package/dist/icons.js +104 -1
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.js +2 -2
  29. package/dist/list/ListPage.d.ts +4 -1
  30. package/dist/list/ListPage.js +96 -14
  31. package/dist/list/ListTable.d.ts +1 -0
  32. package/dist/list/ListTable.js +1 -1
  33. package/dist/list/ListViewControls.d.ts +1 -1
  34. package/dist/list/ListViewControls.js +2 -1
  35. package/dist/list/index.js +2 -2
  36. package/dist/list/listView.d.ts +15 -3
  37. package/dist/list/listView.js +11 -4
  38. package/dist/styles.css +1 -1
  39. package/package.json +1 -1
@@ -1,12 +1,14 @@
1
1
  import { cx } from "../cx.js";
2
- import { ErrorIcon, SuccessIcon } from "../icons.js";
2
+ import { FailFilledIcon, SuccessFilledIcon } from "../icons.js";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  //#region src/components/StatusIcons.tsx
5
+ /** Something done: a solid disc in the success tone with a check cut out of it. */
5
6
  function SuccessCheckmark({ className, colored = true }) {
6
- return /* @__PURE__ */ jsx(SuccessIcon, { className: cx(colored && "text-(--theme-success)", className) });
7
+ return /* @__PURE__ */ jsx(SuccessFilledIcon, { className: cx(colored && "text-(--theme-success)", className) });
7
8
  }
9
+ /** Something failed: a solid disc in the error tone with an x cut out of it. */
8
10
  function ErrorCheckmark({ className, colored = true }) {
9
- return /* @__PURE__ */ jsx(ErrorIcon, { className: cx(colored && "text-(--theme-error)", className) });
11
+ return /* @__PURE__ */ jsx(FailFilledIcon, { className: cx(colored && "text-(--theme-error)", className) });
10
12
  }
11
13
  //#endregion
12
14
  export { ErrorCheckmark, SuccessCheckmark };
@@ -2,8 +2,9 @@ import { cx } from "../cx.js";
2
2
  import { useStickyTop } from "./stickyTop.js";
3
3
  import { Tooltip } from "./Tooltip.js";
4
4
  import { AppLink } from "./AppLink.js";
5
+ import { fadeMask, useHiddenEnds } from "./scrollFade.js";
5
6
  import { SegmentContent, segmentClassName, segmentGroupClassName } from "./segmented.js";
6
- import { useState } from "react";
7
+ import { useLayoutEffect, useRef, useState } from "react";
7
8
  import { jsx, jsxs } from "react/jsx-runtime";
8
9
  import { Tabs } from "@base-ui/react/tabs";
9
10
  //#region src/components/Tabs.tsx
@@ -26,6 +27,31 @@ function Tabs$1({ label, items, value, defaultValue, onValueChange, variant = "l
26
27
  const showRow = items.length > 1 || !!end;
27
28
  const [row, setRow] = useState(null);
28
29
  useStickyTop(row, !!sticky);
30
+ const scroller = useHiddenEnds(!segmented && showRow);
31
+ const scrolled = useRef(false);
32
+ useLayoutEffect(() => {
33
+ const list = scroller.ref.current;
34
+ const tab = list?.querySelector("[aria-selected=\"true\"]");
35
+ if (!list || !tab || segmented) return;
36
+ const margin = 24;
37
+ const left = tab.offsetLeft;
38
+ const right = left + tab.offsetWidth;
39
+ let to;
40
+ if (left - margin < list.scrollLeft) to = Math.max(0, left - margin);
41
+ else if (right + margin > list.scrollLeft + list.clientWidth) to = right + margin - list.clientWidth;
42
+ if (to !== void 0) {
43
+ const smooth = scrolled.current && !globalThis.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
44
+ list.scrollTo?.({
45
+ left: to,
46
+ behavior: smooth ? "smooth" : "instant"
47
+ });
48
+ }
49
+ scrolled.current = true;
50
+ }, [
51
+ current,
52
+ segmented,
53
+ scroller.ref
54
+ ]);
29
55
  const tabs = items.map((item) => {
30
56
  const tab = /* @__PURE__ */ jsx(Tabs.Tab, {
31
57
  value: item.value,
@@ -61,7 +87,10 @@ function Tabs$1({ label, items, value, defaultValue, onValueChange, variant = "l
61
87
  className: cx("flex items-center justify-between gap-2", !segmented && "border-b border-(--theme-border)", sticky && "sticky top-0 z-(--layer-sticky) bg-(--theme-app-bg)", className),
62
88
  children: [/* @__PURE__ */ jsxs(Tabs.List, {
63
89
  "aria-label": label,
64
- className: cx(segmented ? segmentGroupClassName(layout) : "relative flex min-w-0 overflow-x-auto"),
90
+ ref: segmented ? void 0 : scroller.ref,
91
+ onScroll: segmented ? void 0 : scroller.onScroll,
92
+ style: segmented ? void 0 : fadeMask(scroller.ends),
93
+ className: cx(segmented ? segmentGroupClassName(layout) : "relative flex min-w-0 overflow-x-auto rtl:[--fade-end:left]"),
65
94
  children: [tabs, !segmented && /* @__PURE__ */ jsx(Tabs.Indicator, { className: "absolute bottom-0 left-0 h-0.5 w-(--active-tab-width) translate-x-(--active-tab-left) bg-(--theme-link) transition-[translate,width] duration-200 ease-in-out motion-reduce:transition-none" })]
66
95
  }), end]
67
96
  }), children]
@@ -6,7 +6,8 @@ export interface TagStyle {
6
6
  caps?: boolean | undefined;
7
7
  }
8
8
  /** The one tag look: a pill with a hairline border and 11px text. Another component's chip,
9
- * such as a picker's chosen value, uses it to look the same. */
9
+ * such as a picker's chosen value, uses it to look the same. It has the panel's fill, so its
10
+ * edge shows on a hovered or selected row too, whose fill can match the border. */
10
11
  export declare function tagClasses({ mono, caps }?: TagStyle): string;
11
12
  /** Any other attribute and the ref reach the tag's element, its link with `href` and no `onRemove`,
12
13
  * so it can be a Tooltip's or a popover's direct child. */
@@ -7,9 +7,10 @@ import { useLayoutEffect, useRef, useState } from "react";
7
7
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
8
8
  //#region src/components/Tag.tsx
9
9
  /** The one tag look: a pill with a hairline border and 11px text. Another component's chip,
10
- * such as a picker's chosen value, uses it to look the same. */
10
+ * such as a picker's chosen value, uses it to look the same. It has the panel's fill, so its
11
+ * edge shows on a hovered or selected row too, whose fill can match the border. */
11
12
  function tagClasses({ mono = false, caps = false } = {}) {
12
- return cx("inline-flex h-5 max-w-full min-w-0 shrink-0 items-center gap-1 rounded-full border border-(--theme-border) px-2 text-[11px] leading-none whitespace-nowrap text-(--theme-app)", mono ? "font-mono" : "font-sans", caps && "text-[10px] font-medium tracking-wide uppercase");
13
+ return cx("inline-flex h-5 max-w-full min-w-0 shrink-0 items-center gap-1 rounded-full border border-(--theme-border) bg-(--theme-panel-bg) px-2 text-[11px] leading-none whitespace-nowrap text-(--theme-app)", mono ? "font-mono" : "font-sans", caps && "text-[10px] font-medium tracking-wide uppercase");
13
14
  }
14
15
  /** A tag or label on a thing: a pill with an optional color dot, a link with `href`, and an ×
15
16
  * with `onRemove`. */
@@ -27,7 +28,7 @@ function Tag({ children, color, href, onRemove, removeLabel, title, mono, caps,
27
28
  mono,
28
29
  caps
29
30
  }), className);
30
- const hover = "transition-colors hover:bg-(--theme-hover)";
31
+ const hover = "transition-colors hover:bg-(--theme-muted-panel-bg)";
31
32
  if (!onRemove) return href ? /* @__PURE__ */ jsx(AppLink, {
32
33
  ...rest,
33
34
  ref,
@@ -173,7 +174,7 @@ function MoreTags({ tags, ...style }) {
173
174
  trigger: /* @__PURE__ */ jsxs("button", {
174
175
  type: "button",
175
176
  "aria-label": `${common.moreCount(tags.length)}: ${names.join(", ")}`,
176
- className: cx(tagClasses(style), "cursor-pointer text-(--theme-muted-text-color) tabular-nums hover:bg-(--theme-hover) hover:text-(--theme-app) focus-visible:outline-2 focus-visible:outline-(--theme-focus) data-popup-open:bg-(--theme-hover)"),
177
+ className: cx(tagClasses(style), "cursor-pointer text-(--theme-muted-text-color) tabular-nums hover:bg-(--theme-muted-panel-bg) hover:text-(--theme-app) focus-visible:outline-2 focus-visible:outline-(--theme-focus) data-popup-open:bg-(--theme-muted-panel-bg)"),
177
178
  children: ["+", count]
178
179
  }),
179
180
  children: /* @__PURE__ */ jsx("ul", {
@@ -1,14 +1,28 @@
1
1
  import { type CSSProperties, type ReactNode } from 'react';
2
- /** A series' mark color for palette slot 1–8: the theme's category hue, between the slot's
3
- * soft fill and its text and twice as saturated, so a bar or a line stands out from the page
4
- * in light and dark alike and keeps the hue the slot has everywhere else. */
5
- export declare function seriesSlotColor(slot: number): string;
6
- /** A series' color by its key, any CSS color for a fill, a stroke or a style: the same key
7
- * gets the same color on every chart, as `categoryOf` gives a name its avatar color. */
8
- export declare function seriesColor(key: string): string;
9
- /** Colors for a chart's series, each key its `seriesColor` unless another key took that slot
10
- * first, when it moves to the next free one: up to eight series never share a color. */
2
+ /** How many series a chart colors: a series past the eighth folds into "Other" (`foldSeries`)
3
+ * rather than taking a hue made up for it. */
4
+ export declare const SERIES_LIMIT: 8;
5
+ /** The key `foldSeries` gives the series that sums those past the limit. */
6
+ export declare const OTHER_SERIES_KEY = "__other__";
7
+ /** The mark color of the "Other" series: a neutral gray, so it never reads as one more series. */
8
+ export declare const OTHER_SERIES_COLOR = "color-mix(in oklch, var(--theme-muted-text-color) 75%, var(--theme-panel-bg))";
9
+ /** The color of a chart's nth series, 1–8: the theme's category hue, between the slot's soft
10
+ * fill and its text and twice as saturated, so a bar or a line stands out from the page in
11
+ * light and dark alike. Past the eighth it is the "Other" gray; a hue is never repeated. */
12
+ export declare function seriesSlotColor(position: number): string;
13
+ /** Colors for a chart's series by their place in `keys`: the first takes the first color, the
14
+ * second the next, so the first few are always the most distinct. Pass every key the chart can
15
+ * show, in an order that doesn't depend on the data shown, such as by name or as configured:
16
+ * a filter that hides a series then leaves the others their colors. `OTHER_SERIES_KEY`, and any
17
+ * key past the eighth, is the "Other" gray; fold them first with `foldSeries`. */
11
18
  export declare function seriesColors(keys: readonly string[]): Record<string, string>;
19
+ /** Splits a chart's series at the limit: up to eight show as they are, and more keep the first
20
+ * seven and fold the rest into one "Other" series, `OTHER_SERIES_KEY`, whose value at a point
21
+ * is the sum of `folded`. Name it with the `chart.other` string. */
22
+ export declare function foldSeries(keys: readonly string[], limit?: number): {
23
+ keys: string[];
24
+ folded: string[];
25
+ };
12
26
  export type SeriesSwatchShape = 'square' | 'dot' | 'line';
13
27
  /** A series' color as a mark, for a legend or a tooltip's row. Only seen: the series' name
14
28
  * beside it says which it is. */
@@ -64,6 +78,39 @@ export declare function ChartTooltipContent({ label, items, formatValue, total,
64
78
  /** Lists the largest value first; on by default. */
65
79
  sort?: boolean | undefined;
66
80
  className?: string | undefined;
67
- /** Places it, such as beside the point it describes. */
81
+ /** Places it; `ChartTooltipBeside` places it beside a crosshair. */
68
82
  style?: CSSProperties | undefined;
69
83
  }): import("react").JSX.Element;
84
+ export interface ChartTooltipPlacement {
85
+ /** The tooltip's left edge. */
86
+ left: number;
87
+ side: 'left' | 'right';
88
+ /** A width to hold it to when neither side has room for all of it, its names truncating. */
89
+ maxWidth: number | null;
90
+ }
91
+ /** Where a chart's tooltip goes beside a crosshair at `x`, so it never covers the column under
92
+ * the pointer: `gap` to the `prefer` side, or the other when it doesn't fit between `x` and
93
+ * that edge, or held to the wider side when neither fits. `start` and `end` bound it, in the
94
+ * same coordinates as `x`, such as the chart's box or the viewport. A charting library's
95
+ * tooltip takes `left` as its position. */
96
+ export declare function chartTooltipPlacement({ x, width, start, end, gap, prefer, }: {
97
+ x: number;
98
+ width: number;
99
+ start: number;
100
+ end: number;
101
+ gap?: number | undefined;
102
+ prefer?: 'left' | 'right' | undefined;
103
+ }): ChartTooltipPlacement;
104
+ /** Holds a chart's tooltip beside its crosshair, inside a positioned box around the plot: `x`
105
+ * is the crosshair in that box, and the tooltip sits `top` from its top, to the crosshair's
106
+ * inline end, or its start where the box has no room. When neither side of the box has room,
107
+ * as on a phone, it may reach past the box to the viewport's edge, and is held narrower when
108
+ * even that is too small. It never covers the hovered column or the pointer on it. Nothing
109
+ * shows while `x` is null. */
110
+ export declare function ChartTooltipBeside({ x, top, gap, className, children, }: {
111
+ x: number | null;
112
+ top?: number | undefined;
113
+ gap?: number | undefined;
114
+ className?: string | undefined;
115
+ children: ReactNode;
116
+ }): import("react").JSX.Element | null;
@@ -1,36 +1,65 @@
1
1
  import { cx } from "../cx.js";
2
2
  import { useLocale, useStrings } from "./Provider.js";
3
- import { CATEGORY_CLASSES, categoryOf } from "./category.js";
4
- import { useCallback, useMemo, useState } from "react";
3
+ import { CATEGORY_CLASSES } from "./category.js";
4
+ import { useCallback, useLayoutEffect, useMemo, useRef, useState } from "react";
5
5
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
6
6
  //#region src/components/chart.tsx
7
- var SLOTS = CATEGORY_CLASSES.length;
8
- /** A series' mark color for palette slot 1–8: the theme's category hue, between the slot's
9
- * soft fill and its text and twice as saturated, so a bar or a line stands out from the page
10
- * in light and dark alike and keeps the hue the slot has everywhere else. */
11
- function seriesSlotColor(slot) {
12
- const n = ((slot - 1) % SLOTS + SLOTS) % SLOTS + 1;
7
+ /** How many series a chart colors: a series past the eighth folds into "Other" (`foldSeries`)
8
+ * rather than taking a hue made up for it. */
9
+ var SERIES_LIMIT = CATEGORY_CLASSES.length;
10
+ /** The theme's category slots in the order series take them. Each run from the first — three,
11
+ * four or all eight — keeps neighbors apart in hue and lightness, for color-blind readers too,
12
+ * in light and dark, where the theme's own order steps through neighboring hues. */
13
+ var SERIES_ORDER = [
14
+ 5,
15
+ 2,
16
+ 8,
17
+ 3,
18
+ 6,
19
+ 4,
20
+ 7,
21
+ 1
22
+ ];
23
+ /** The key `foldSeries` gives the series that sums those past the limit. */
24
+ var OTHER_SERIES_KEY = "__other__";
25
+ /** The mark color of the "Other" series: a neutral gray, so it never reads as one more series. */
26
+ var OTHER_SERIES_COLOR = "color-mix(in oklch, var(--theme-muted-text-color) 75%, var(--theme-panel-bg))";
27
+ /** The color of a chart's nth series, 1–8: the theme's category hue, between the slot's soft
28
+ * fill and its text and twice as saturated, so a bar or a line stands out from the page in
29
+ * light and dark alike. Past the eighth it is the "Other" gray; a hue is never repeated. */
30
+ function seriesSlotColor(position) {
31
+ const n = SERIES_ORDER[position - 1];
32
+ if (n === void 0) return OTHER_SERIES_COLOR;
13
33
  return `oklch(from color-mix(in oklch, var(--theme-category-${n}), var(--theme-category-${n}-text)) l calc(c * 2) h)`;
14
34
  }
15
- /** A series' color by its key, any CSS color for a fill, a stroke or a style: the same key
16
- * gets the same color on every chart, as `categoryOf` gives a name its avatar color. */
17
- function seriesColor(key) {
18
- return seriesSlotColor(categoryOf(key));
19
- }
20
- /** Colors for a chart's series, each key its `seriesColor` unless another key took that slot
21
- * first, when it moves to the next free one: up to eight series never share a color. */
35
+ /** Colors for a chart's series by their place in `keys`: the first takes the first color, the
36
+ * second the next, so the first few are always the most distinct. Pass every key the chart can
37
+ * show, in an order that doesn't depend on the data shown, such as by name or as configured:
38
+ * a filter that hides a series then leaves the others their colors. `OTHER_SERIES_KEY`, and any
39
+ * key past the eighth, is the "Other" gray; fold them first with `foldSeries`. */
22
40
  function seriesColors(keys) {
23
- const taken = /* @__PURE__ */ new Set();
24
41
  const colors = {};
42
+ let position = 0;
25
43
  for (const key of keys) {
26
44
  if (key in colors) continue;
27
- let slot = categoryOf(key);
28
- if (taken.size < SLOTS) while (taken.has(slot)) slot = slot % SLOTS + 1;
29
- taken.add(slot);
30
- colors[key] = seriesSlotColor(slot);
45
+ colors[key] = key === "__other__" ? OTHER_SERIES_COLOR : seriesSlotColor(++position);
31
46
  }
32
47
  return colors;
33
48
  }
49
+ /** Splits a chart's series at the limit: up to eight show as they are, and more keep the first
50
+ * seven and fold the rest into one "Other" series, `OTHER_SERIES_KEY`, whose value at a point
51
+ * is the sum of `folded`. Name it with the `chart.other` string. */
52
+ function foldSeries(keys, limit = SERIES_LIMIT) {
53
+ const unique = [...new Set(keys)];
54
+ if (unique.length <= limit) return {
55
+ keys: unique,
56
+ folded: []
57
+ };
58
+ return {
59
+ keys: [...unique.slice(0, limit - 1), OTHER_SERIES_KEY],
60
+ folded: unique.slice(limit - 1)
61
+ };
62
+ }
34
63
  /** A series' color as a mark, for a legend or a tooltip's row. Only seen: the series' name
35
64
  * beside it says which it is. */
36
65
  function SeriesSwatch({ color, shape = "square", className }) {
@@ -107,7 +136,7 @@ function ChartTooltipContent({ label, items, formatValue, total, highlighted, hi
107
136
  const sum = rows.reduce((acc, item) => acc + item.value, 0);
108
137
  const showTotal = total ?? rows.length > 1;
109
138
  return /* @__PURE__ */ jsxs("div", {
110
- className: cx("min-w-40 rounded-lg border border-(--theme-border) bg-(--theme-panel-bg) p-3 text-xs text-(--theme-app) shadow-(--theme-shadow-lg)", className),
139
+ className: cx("min-w-[var(--chart-tooltip-min,10rem)] rounded-lg border border-(--theme-border) bg-(--theme-panel-bg) p-3 text-xs text-(--theme-app) shadow-(--theme-shadow-lg)", className),
111
140
  style,
112
141
  children: [
113
142
  label != null && label !== "" && /* @__PURE__ */ jsx("div", {
@@ -141,5 +170,71 @@ function ChartTooltipContent({ label, items, formatValue, total, highlighted, hi
141
170
  ]
142
171
  });
143
172
  }
173
+ /** Where a chart's tooltip goes beside a crosshair at `x`, so it never covers the column under
174
+ * the pointer: `gap` to the `prefer` side, or the other when it doesn't fit between `x` and
175
+ * that edge, or held to the wider side when neither fits. `start` and `end` bound it, in the
176
+ * same coordinates as `x`, such as the chart's box or the viewport. A charting library's
177
+ * tooltip takes `left` as its position. */
178
+ function chartTooltipPlacement({ x, width, start, end, gap = 12, prefer = "right" }) {
179
+ const room = {
180
+ left: x - gap - start,
181
+ right: end - x - gap
182
+ };
183
+ let side = (prefer === "right" ? ["right", "left"] : ["left", "right"]).find((s) => width <= room[s]);
184
+ let maxWidth = null;
185
+ if (side === void 0) {
186
+ side = room.right >= room.left ? "right" : "left";
187
+ maxWidth = Math.max(0, room[side]);
188
+ }
189
+ const shown = maxWidth ?? width;
190
+ return {
191
+ left: side === "right" ? x + gap : x - gap - shown,
192
+ side,
193
+ maxWidth
194
+ };
195
+ }
196
+ /** Keeps a tooltip clear of the viewport's edge by this much. */
197
+ var VIEWPORT_MARGIN = 8;
198
+ /** Holds a chart's tooltip beside its crosshair, inside a positioned box around the plot: `x`
199
+ * is the crosshair in that box, and the tooltip sits `top` from its top, to the crosshair's
200
+ * inline end, or its start where the box has no room. When neither side of the box has room,
201
+ * as on a phone, it may reach past the box to the viewport's edge, and is held narrower when
202
+ * even that is too small. It never covers the hovered column or the pointer on it. Nothing
203
+ * shows while `x` is null. */
204
+ function ChartTooltipBeside({ x, top = 0, gap = 12, className, children }) {
205
+ const ref = useRef(null);
206
+ useLayoutEffect(() => {
207
+ const el = ref.current;
208
+ if (!el || x === null) return;
209
+ el.style.maxWidth = "";
210
+ el.style.removeProperty("--chart-tooltip-min");
211
+ const width = el.offsetWidth;
212
+ const box = el.offsetParent;
213
+ const origin = box ? box.getBoundingClientRect().left + box.clientLeft : 0;
214
+ const view = document.documentElement.clientWidth || window.innerWidth;
215
+ const place = (start, end) => chartTooltipPlacement({
216
+ x,
217
+ width,
218
+ start,
219
+ end,
220
+ gap,
221
+ prefer: getComputedStyle(el).direction === "rtl" ? "left" : "right"
222
+ });
223
+ let placement = box ? place(0, box.clientWidth) : null;
224
+ if (placement === null || placement.maxWidth !== null) placement = place(VIEWPORT_MARGIN - origin, view - VIEWPORT_MARGIN - origin);
225
+ el.style.left = `${placement.left}px`;
226
+ if (placement.maxWidth !== null) {
227
+ el.style.maxWidth = `${placement.maxWidth}px`;
228
+ el.style.setProperty("--chart-tooltip-min", "0px");
229
+ }
230
+ });
231
+ if (x === null) return null;
232
+ return /* @__PURE__ */ jsx("div", {
233
+ ref,
234
+ className: cx("pointer-events-none absolute z-10 w-max", className),
235
+ style: { top },
236
+ children
237
+ });
238
+ }
144
239
  //#endregion
145
- export { ChartLegendList, ChartTooltipContent, SeriesSwatch, seriesColor, seriesColors, seriesOpacity, seriesSlotColor, useSeriesHighlight };
240
+ export { ChartLegendList, ChartTooltipBeside, ChartTooltipContent, OTHER_SERIES_COLOR, OTHER_SERIES_KEY, SERIES_LIMIT, SeriesSwatch, chartTooltipPlacement, foldSeries, seriesColors, seriesOpacity, seriesSlotColor, useSeriesHighlight };
@@ -0,0 +1,13 @@
1
+ import { type CSSProperties } from 'react';
2
+ /** Which ends of a sideways scroller hide some of its content, kept up to date as it
3
+ * scrolls or resizes. */
4
+ export type HiddenEnds = {
5
+ start: boolean;
6
+ end: boolean;
7
+ };
8
+ export declare function useHiddenEnds(active: boolean): {
9
+ ref: import("react").RefObject<HTMLElement | null>;
10
+ ends: HiddenEnds;
11
+ onScroll: () => void;
12
+ };
13
+ export declare function fadeMask({ start, end }: HiddenEnds): CSSProperties | undefined;
@@ -0,0 +1,51 @@
1
+ import { useEffectEvent, useLayoutEffect, useRef, useState } from "react";
2
+ //#region src/components/scrollFade.ts
3
+ var NO_ENDS = {
4
+ start: false,
5
+ end: false
6
+ };
7
+ function useHiddenEnds(active) {
8
+ const ref = useRef(null);
9
+ const [ends, setEnds] = useState(NO_ENDS);
10
+ const measureNow = () => {
11
+ const el = ref.current;
12
+ if (!el || !active) {
13
+ setEnds(NO_ENDS);
14
+ return;
15
+ }
16
+ const scrolled = Math.abs(el.scrollLeft);
17
+ const start = scrolled > 1;
18
+ const end = scrolled + el.clientWidth < el.scrollWidth - 1;
19
+ setEnds((was) => was.start === start && was.end === end ? was : {
20
+ start,
21
+ end
22
+ });
23
+ };
24
+ const measure = useEffectEvent(measureNow);
25
+ useLayoutEffect(() => {
26
+ measure();
27
+ });
28
+ useLayoutEffect(() => {
29
+ const el = ref.current;
30
+ if (!el || !active || typeof ResizeObserver === "undefined") return;
31
+ const observer = new ResizeObserver(() => measure());
32
+ observer.observe(el);
33
+ return () => observer.disconnect();
34
+ }, [active]);
35
+ return {
36
+ ref,
37
+ ends,
38
+ onScroll: measureNow
39
+ };
40
+ }
41
+ var FADE = "1.25rem";
42
+ function fadeMask({ start, end }) {
43
+ if (!start && !end) return;
44
+ const image = `linear-gradient(to var(--fade-end, right), ${start ? `transparent, #000 ${FADE}` : "#000"}, ${end ? `#000 calc(100% - ${FADE}), transparent` : "#000"})`;
45
+ return {
46
+ maskImage: image,
47
+ WebkitMaskImage: image
48
+ };
49
+ }
50
+ //#endregion
51
+ export { fadeMask, useHiddenEnds };
@@ -551,6 +551,14 @@ function FileExplorer({ storages, onRefresh, refreshKey, onOpenFile, showUserHie
551
551
  const triggerBrowserDownload = (url, filename) => {
552
552
  const href = safeUrl(url);
553
553
  if (!href) return;
554
+ if (new URL(href, window.location.href).origin !== window.location.origin) {
555
+ const frame = document.createElement("iframe");
556
+ frame.hidden = true;
557
+ frame.src = href;
558
+ document.body.appendChild(frame);
559
+ setTimeout(() => frame.remove(), 6e4);
560
+ return;
561
+ }
554
562
  const a = document.createElement("a");
555
563
  a.href = href;
556
564
  a.download = filename;
package/dist/icons.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ReactNode, SVGProps } from 'react';
1
+ import { type ReactNode, type SVGProps } from 'react';
2
2
  export interface IconProps extends Omit<SVGProps<SVGSVGElement>, 'ref'> {
3
3
  /** Width and height; the text's size by default. */
4
4
  size?: string | number | undefined;
@@ -284,6 +284,19 @@ export declare const WorkspaceMountIcon: IconType;
284
284
  export declare const ZipIcon: IconType;
285
285
  export declare const ZoomInIcon: IconType;
286
286
  export declare const ZoomOutIcon: IconType;
287
+ /** Done: a solid disc with a check cut out of it. */
288
+ export declare const SuccessFilledIcon: IconType;
289
+ /** Failed: a solid disc with an x cut out of it. */
290
+ export declare const FailFilledIcon: IconType;
291
+ /** Canceled: a solid disc with a dash cut out of it. */
292
+ export declare const CancelFilledIcon: IconType;
293
+ /** Done with problems: a solid triangle with an exclamation mark cut out of it. */
294
+ export declare const WarningFilledIcon: IconType;
295
+ /** Under way: a faint track, a quarter arc that turns around it and a center dot that breathes.
296
+ * Both hold still for a reader who asks for reduced motion. */
297
+ export declare function RunningRingIcon({ children, color, ...props }: IconProps): import("react").JSX.Element;
298
+ /** Waiting to start: a dashed ring, eight even dashes around it. */
299
+ export declare const PendingRingIcon: IconType;
287
300
  export { ErrorCheckmark, SuccessCheckmark } from './components/StatusIcons.js';
288
301
  /** @deprecated Renamed NamespaceIcon, which says what it means. */
289
302
  export declare const KubernetesNamespaceIcon: IconType;
package/dist/icons.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { ErrorCheckmark, SuccessCheckmark } from "./components/StatusIcons.js";
2
+ import { useId } from "react";
2
3
  import { jsx, jsxs } from "react/jsx-runtime";
3
4
  //#region src/icons.tsx
4
5
  var STROKE_WIDTH = 1.5;
@@ -306,6 +307,108 @@ var WorkspaceMountIcon = /* @__PURE__ */ drawn("M2 4.5A1.5 1.5 0 0 1 3.5 3h2.6l1
306
307
  var ZipIcon = /* @__PURE__ */ drawn("M9.5 1.75h-5a1 1 0 0 0-1 1v10.5a1 1 0 0 0 1 1h7a1 1 0 0 0 1-1V4.75ZM9.5 1.75v3h3M6.5 4h.01M6.5 6.5h.01M6.5 8.75v1.25M6.5 12.5a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5Z");
307
308
  var ZoomInIcon = /* @__PURE__ */ drawn("M7 12A5 5 0 1 0 7 2a5 5 0 0 0 0 10ZM14 14l-3.5-3.5M7 5v4M5 7h4");
308
309
  var ZoomOutIcon = /* @__PURE__ */ drawn("M7 12A5 5 0 1 0 7 2a5 5 0 0 0 0 10ZM14 14l-3.5-3.5M5 7h4");
310
+ var DISC = "M8 14.75A6.75 6.75 0 1 0 8 1.25a6.75 6.75 0 0 0 0 13.5Z";
311
+ var TRIANGLE = "M7.13 1.9a1 1 0 0 1 1.74 0l6.1 10.6a1 1 0 0 1-.87 1.5H1.9a1 1 0 0 1-.87-1.5Z";
312
+ var KNOCKOUT_WIDTH = 1.6;
313
+ /** The `svg` every status icon shares: the 16px grid at the text's size, hidden from assistive
314
+ * technology unless a title or label names it. */
315
+ function StatusSvg({ title, children, size = "1em", color = "currentColor", strokeWidth = STROKE_WIDTH, ...props }) {
316
+ const named = Boolean(title || props["aria-label"] || props["aria-labelledby"]);
317
+ return /* @__PURE__ */ jsxs("svg", {
318
+ xmlns: "http://www.w3.org/2000/svg",
319
+ viewBox: "0 0 16 16",
320
+ width: size,
321
+ height: size,
322
+ fill: "none",
323
+ stroke: color,
324
+ strokeWidth,
325
+ strokeLinecap: "round",
326
+ strokeLinejoin: "round",
327
+ ...named ? { role: "img" } : { "aria-hidden": true },
328
+ ...props,
329
+ children: [title && /* @__PURE__ */ jsx("title", { children: title }), children]
330
+ });
331
+ }
332
+ /** A solid `shape` with `mark` cut out of it. The mask's id is the instance's own, so two on a
333
+ * page never borrow each other's. */
334
+ function knockedOut(shape, mark) {
335
+ function Icon({ children, color = "currentColor", ...props }) {
336
+ const id = `status-mask-${useId().replace(/[^\w-]/g, "")}`;
337
+ return /* @__PURE__ */ jsxs(StatusSvg, {
338
+ color,
339
+ "data-status-icon": "filled",
340
+ ...props,
341
+ children: [
342
+ /* @__PURE__ */ jsxs("mask", {
343
+ id,
344
+ maskUnits: "userSpaceOnUse",
345
+ x: "0",
346
+ y: "0",
347
+ width: "16",
348
+ height: "16",
349
+ children: [/* @__PURE__ */ jsx("rect", {
350
+ width: "16",
351
+ height: "16",
352
+ fill: "#fff",
353
+ stroke: "none"
354
+ }), /* @__PURE__ */ jsx("path", {
355
+ d: mark,
356
+ stroke: "#000",
357
+ strokeWidth: KNOCKOUT_WIDTH
358
+ })]
359
+ }),
360
+ /* @__PURE__ */ jsx("path", {
361
+ d: shape,
362
+ fill: color,
363
+ stroke: "none",
364
+ mask: `url(#${id})`
365
+ }),
366
+ children
367
+ ]
368
+ });
369
+ }
370
+ return Icon;
371
+ }
372
+ /** Done: a solid disc with a check cut out of it. */
373
+ var SuccessFilledIcon = /* @__PURE__ */ knockedOut(DISC, "M5.25 8.25 7 10l3.5-4");
374
+ /** Failed: a solid disc with an x cut out of it. */
375
+ var FailFilledIcon = /* @__PURE__ */ knockedOut(DISC, "M6 6l4 4M10 6l-4 4");
376
+ /** Canceled: a solid disc with a dash cut out of it. */
377
+ var CancelFilledIcon = /* @__PURE__ */ knockedOut(DISC, "M5.5 8h5");
378
+ /** Done with problems: a solid triangle with an exclamation mark cut out of it. */
379
+ var WarningFilledIcon = /* @__PURE__ */ knockedOut(TRIANGLE, "M8 6v3M8 11.4h.01");
380
+ /** Under way: a faint track, a quarter arc that turns around it and a center dot that breathes.
381
+ * Both hold still for a reader who asks for reduced motion. */
382
+ function RunningRingIcon({ children, color = "currentColor", ...props }) {
383
+ return /* @__PURE__ */ jsxs(StatusSvg, {
384
+ color,
385
+ "data-status-icon": "ring",
386
+ ...props,
387
+ children: [
388
+ /* @__PURE__ */ jsx("circle", {
389
+ cx: "8",
390
+ cy: "8",
391
+ r: "6",
392
+ opacity: "0.25"
393
+ }),
394
+ /* @__PURE__ */ jsx("path", {
395
+ d: "M8 2a6 6 0 0 1 6 6",
396
+ className: "origin-center [transform-box:view-box] motion-safe:animate-[spin_1.6s_linear_infinite]"
397
+ }),
398
+ /* @__PURE__ */ jsx("circle", {
399
+ cx: "8",
400
+ cy: "8",
401
+ r: "2.6",
402
+ fill: color,
403
+ stroke: "none",
404
+ className: "motion-safe:animate-pulse"
405
+ }),
406
+ children
407
+ ]
408
+ });
409
+ }
410
+ /** Waiting to start: a dashed ring, eight even dashes around it. */
411
+ var PendingRingIcon = /* @__PURE__ */ drawn("M8 14A6 6 0 1 0 8 2a6 6 0 0 0 0 12Z", { strokeDasharray: "2.2 2.5124" });
309
412
  /** @deprecated Renamed NamespaceIcon, which says what it means. */
310
413
  var KubernetesNamespaceIcon = NamespaceIcon;
311
414
  /** @deprecated Renamed CommandShellIcon, which says what it means. */
@@ -313,4 +416,4 @@ var PowershellIcon = CommandShellIcon;
313
416
  /** @deprecated Renamed QuickActionIcon, which says what it means. */
314
417
  var ZapIcon = QuickActionIcon;
315
418
  //#endregion
316
- export { APIIcon, AccessIcon, AddAllocationIcon, AddIcon, AddProjectIcon, AddUserIcon, AgentIcon, AiProviderIcon, AllocationIcon, ArchiveIcon, ArrowDownIcon, ArrowLeftIcon, ArrowRightIcon, ArrowUpIcon, ArticleIcon, AttachmentIcon, AuthenticationIcon, BannerIcon, BillingIcon, BranchIcon, BriefcaseIcon, BucketIcon, BuildWorkflowIcon, CalendarIcon, CancelIcon, CelebrateIcon, CertificateIcon, ChangesRequestedIcon, ChartIcon, ChatIcon, CheckIcon, ChevronDoubleDownIcon, ChevronDoubleUpIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, ClipboardCheckIcon, ClockIcon, CloseIcon, CloudIcon, CloudNetworkIcon, ClusterIcon, CodeIcon, CollapseIcon, ColumnsIcon, CommandShellIcon, CommentIcon, CommitIcon, ComputeIcon, ConfigIcon, ConnectIcon, ContractIcon, CopyIcon, CustomizeIcon, DefaultIcon, DefinitionIcon, DeprovisionIcon, DesktopIcon, DestroyIcon, DeviceIcon, DirectoryIcon, DirectorySyncIcon, DisableCostIcon, DisableUserIcon, DisconnectIcon, DiskIcon, DisplayIcon, DownloadIcon, DragHandleIcon, DuplicateIcon, EditIcon, EditorIcon, EducationIcon, EnableCostIcon, EnableUserIcon, EndpointIcon, ErrorCheckmark, ErrorIcon, EventsIcon, ExpandIcon, ExpandVerticalIcon, ExpiredIcon, ExpiringIcon, ExpressionIcon, ExternalLinkIcon, EyeIcon, EyeOffIcon, FailIcon, FavoriteIcon, FavoriteOutlineIcon, FeaturedIcon, FileIcon, FileTextIcon, FilesIcon, FilesystemIcon, FilterClearIcon, FilterIcon, FlaggedIcon, FlaskIcon, FolderIcon, FolderOpenIcon, FolderTreeIcon, ForbiddenIcon, ForkIcon, GearsIcon, GlobeIcon, GovernmentIcon, GraphIcon, GridIcon, HealthMonitoringIcon, HelpIcon, HistoryIcon, HomeIcon, IdCardIcon, ImageIcon, ImpersonateIcon, InboxIcon, IndexIcon, InfoIcon, InfrastructureLayersIcon, InputFormIcon, InstallIcon, InstanceIcon, InstanceTypeIcon, IpAddressIcon, IssueIcon, JobIcon, JsonIcon, KeyIcon, KeyboardIcon, KubernetesNamespaceIcon, LanguageIcon, LegalIcon, LibraryIcon, LicenseIcon, LinkIcon, ListViewIcon, LoadingIcon, LockIcon, LogsIcon, MFAIcon, MachineImageIcon, MailFailedIcon, MailIcon, MailVerifiedIcon, MapPinIcon, MarketplaceIcon, MatrixIcon, MegaphoneIcon, MigrationIcon, MinimizeIcon, MinusIcon, MlIcon, MoneyIcon, MoonIcon, MoreIcon, MusicIcon, MuteIcon, NamespaceIcon, NavigationIcon, NetworkInterfaceIcon, NetworkShareIcon, NewChatIcon, NodeIcon, NotRunningIcon, NotebookIcon, NotificationIcon, OnboardingIcon, OpenInNewGraphIcon, OrganizationIcon, OwnerIcon, PartnerIcon, PasswordIcon, PauseIcon, PdfIcon, PendingIcon, PhoneIcon, PieChartIcon, PinFilledIcon, PinIcon, PowerIcon, PowershellIcon, PreviewIcon, PrintIcon, ProjectIcon, ProvisionIcon, PublishIcon, PullRequestIcon, QRCodeIcon, QueueIcon, QuickActionIcon, QuotaIcon, RedoIcon, RefreshIcon, ReleaseIcon, RemoveIcon, RemoveUserIcon, RenameIcon, RenewIcon, ReportIcon, RepositoryIcon, ResetIcon, ResetLayoutIcon, ResourceGroupIcon, ResourceIcon, RestartIcon, RestoreIcon, RetryIcon, RevokeIcon, RoleIcon, RollbackIcon, RunWorkflowIcon, RunningIcon, RunsIcon, SaveIcon, SchedulerIcon, ScriptIcon, SearchIcon, SendIcon, ServiceIcon, SessionIcon, SettingsIcon, ShareIcon, SharedIcon, ShieldIcon, ShieldOffIcon, ShrinkIcon, SidebarCloseIcon, SidebarIcon, SidebarOpenIcon, SignInIcon, SignOutIcon, SkipIcon, SnapshotIcon, SortDownIcon, SortUnsortedIcon, SortUpIcon, SparklesIcon, SplitIcon, SpreadsheetIcon, StartIcon, StopIcon, StorageIcon, SubdomainIcon, SuccessCheckmark, SuccessIcon, SummaryIcon, SunIcon, SupportIcon, SwapIcon, TagIcon, TerminalIcon, ThinkingIcon, TodoIcon, TokenIcon, ToolsIcon, TrashIcon, TunnelIcon, UndoIcon, UnfavoriteIcon, UnlinkIcon, UnmuteIcon, UnsplitIcon, UploadIcon, UserIcon, UserWorkspaceIcon, UsersIcon, VariableIcon, VerifiedIcon, VideoIcon, WarningIcon, WebhookIcon, WorkerIcon, WorkflowIcon, WorkloadIcon, WorkspaceMountIcon, ZapIcon, ZipIcon, ZoomInIcon, ZoomOutIcon };
419
+ export { APIIcon, AccessIcon, AddAllocationIcon, AddIcon, AddProjectIcon, AddUserIcon, AgentIcon, AiProviderIcon, AllocationIcon, ArchiveIcon, ArrowDownIcon, ArrowLeftIcon, ArrowRightIcon, ArrowUpIcon, ArticleIcon, AttachmentIcon, AuthenticationIcon, BannerIcon, BillingIcon, BranchIcon, BriefcaseIcon, BucketIcon, BuildWorkflowIcon, CalendarIcon, CancelFilledIcon, CancelIcon, CelebrateIcon, CertificateIcon, ChangesRequestedIcon, ChartIcon, ChatIcon, CheckIcon, ChevronDoubleDownIcon, ChevronDoubleUpIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, ClipboardCheckIcon, ClockIcon, CloseIcon, CloudIcon, CloudNetworkIcon, ClusterIcon, CodeIcon, CollapseIcon, ColumnsIcon, CommandShellIcon, CommentIcon, CommitIcon, ComputeIcon, ConfigIcon, ConnectIcon, ContractIcon, CopyIcon, CustomizeIcon, DefaultIcon, DefinitionIcon, DeprovisionIcon, DesktopIcon, DestroyIcon, DeviceIcon, DirectoryIcon, DirectorySyncIcon, DisableCostIcon, DisableUserIcon, DisconnectIcon, DiskIcon, DisplayIcon, DownloadIcon, DragHandleIcon, DuplicateIcon, EditIcon, EditorIcon, EducationIcon, EnableCostIcon, EnableUserIcon, EndpointIcon, ErrorCheckmark, ErrorIcon, EventsIcon, ExpandIcon, ExpandVerticalIcon, ExpiredIcon, ExpiringIcon, ExpressionIcon, ExternalLinkIcon, EyeIcon, EyeOffIcon, FailFilledIcon, FailIcon, FavoriteIcon, FavoriteOutlineIcon, FeaturedIcon, FileIcon, FileTextIcon, FilesIcon, FilesystemIcon, FilterClearIcon, FilterIcon, FlaggedIcon, FlaskIcon, FolderIcon, FolderOpenIcon, FolderTreeIcon, ForbiddenIcon, ForkIcon, GearsIcon, GlobeIcon, GovernmentIcon, GraphIcon, GridIcon, HealthMonitoringIcon, HelpIcon, HistoryIcon, HomeIcon, IdCardIcon, ImageIcon, ImpersonateIcon, InboxIcon, IndexIcon, InfoIcon, InfrastructureLayersIcon, InputFormIcon, InstallIcon, InstanceIcon, InstanceTypeIcon, IpAddressIcon, IssueIcon, JobIcon, JsonIcon, KeyIcon, KeyboardIcon, KubernetesNamespaceIcon, LanguageIcon, LegalIcon, LibraryIcon, LicenseIcon, LinkIcon, ListViewIcon, LoadingIcon, LockIcon, LogsIcon, MFAIcon, MachineImageIcon, MailFailedIcon, MailIcon, MailVerifiedIcon, MapPinIcon, MarketplaceIcon, MatrixIcon, MegaphoneIcon, MigrationIcon, MinimizeIcon, MinusIcon, MlIcon, MoneyIcon, MoonIcon, MoreIcon, MusicIcon, MuteIcon, NamespaceIcon, NavigationIcon, NetworkInterfaceIcon, NetworkShareIcon, NewChatIcon, NodeIcon, NotRunningIcon, NotebookIcon, NotificationIcon, OnboardingIcon, OpenInNewGraphIcon, OrganizationIcon, OwnerIcon, PartnerIcon, PasswordIcon, PauseIcon, PdfIcon, PendingIcon, PendingRingIcon, PhoneIcon, PieChartIcon, PinFilledIcon, PinIcon, PowerIcon, PowershellIcon, PreviewIcon, PrintIcon, ProjectIcon, ProvisionIcon, PublishIcon, PullRequestIcon, QRCodeIcon, QueueIcon, QuickActionIcon, QuotaIcon, RedoIcon, RefreshIcon, ReleaseIcon, RemoveIcon, RemoveUserIcon, RenameIcon, RenewIcon, ReportIcon, RepositoryIcon, ResetIcon, ResetLayoutIcon, ResourceGroupIcon, ResourceIcon, RestartIcon, RestoreIcon, RetryIcon, RevokeIcon, RoleIcon, RollbackIcon, RunWorkflowIcon, RunningIcon, RunningRingIcon, RunsIcon, SaveIcon, SchedulerIcon, ScriptIcon, SearchIcon, SendIcon, ServiceIcon, SessionIcon, SettingsIcon, ShareIcon, SharedIcon, ShieldIcon, ShieldOffIcon, ShrinkIcon, SidebarCloseIcon, SidebarIcon, SidebarOpenIcon, SignInIcon, SignOutIcon, SkipIcon, SnapshotIcon, SortDownIcon, SortUnsortedIcon, SortUpIcon, SparklesIcon, SplitIcon, SpreadsheetIcon, StartIcon, StopIcon, StorageIcon, SubdomainIcon, SuccessCheckmark, SuccessFilledIcon, SuccessIcon, SummaryIcon, SunIcon, SupportIcon, SwapIcon, TagIcon, TerminalIcon, ThinkingIcon, TodoIcon, TokenIcon, ToolsIcon, TrashIcon, TunnelIcon, UndoIcon, UnfavoriteIcon, UnlinkIcon, UnmuteIcon, UnsplitIcon, UploadIcon, UserIcon, UserWorkspaceIcon, UsersIcon, VariableIcon, VerifiedIcon, VideoIcon, WarningFilledIcon, WarningIcon, WebhookIcon, WorkerIcon, WorkflowIcon, WorkloadIcon, WorkspaceMountIcon, ZapIcon, ZipIcon, ZoomInIcon, ZoomOutIcon };
package/dist/index.d.ts CHANGED
@@ -15,7 +15,7 @@ export { ContextMenuProvider, type MenuCloseTrigger, type MenuOpener, type OpenM
15
15
  export { CopyButton, type CopyButtonProps, CopyCodeBlock, type CopyCodeBlockProps, } from './components/CopyButton.js';
16
16
  export { CreateModal, CreateModalSelect, CreateModalSwitch, } from './components/CreateModal.js';
17
17
  export { categoryClasses, categoryOf } from './components/category.js';
18
- export { type ChartLegendItem, ChartLegendList, ChartTooltipContent, type ChartTooltipItem, SeriesSwatch, type SeriesSwatchShape, seriesColor, seriesColors, seriesOpacity, seriesSlotColor, useSeriesHighlight, } from './components/chart.js';
18
+ export { type ChartLegendItem, ChartLegendList, ChartTooltipBeside, ChartTooltipContent, type ChartTooltipItem, type ChartTooltipPlacement, chartTooltipPlacement, foldSeries, OTHER_SERIES_COLOR, OTHER_SERIES_KEY, SERIES_LIMIT, SeriesSwatch, type SeriesSwatchShape, seriesColors, seriesOpacity, seriesSlotColor, useSeriesHighlight, } from './components/chart.js';
19
19
  export { Calendar, type CalendarProps, DatePicker, type DatePickerProps, } from './components/DatePicker.js';
20
20
  export { DescriptionListGroup, DescriptionListItem, type DescriptionListItemProps, type DescriptionListProps, type DescriptionListSize, type DescriptionListVariant, default as DescriptionList, } from './components/DescriptionList.js';
21
21
  export { collapsePanelClassName, Disclosure, DisclosurePanel, type DisclosureProps, } from './components/Disclosure.js';