@galaxy-io/dls 2.7.0 → 2.8.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.
@@ -274,7 +274,7 @@ function BarChartInner(props, ref) {
274
274
  y: activeBand.y,
275
275
  width: activeBand.width,
276
276
  height: activeBand.height,
277
- className: "gx-ChartPrimitives-CHART_CURSOR_BAND_CSS-c1iaray"
277
+ className: "gx-ChartPrimitives-CHART_CURSOR_BAND_CSS-cz6jod1"
278
278
  }),
279
279
  geometry.rects.map((rect) => /* @__PURE__ */ jsx("path", {
280
280
  d: roundedRectPath(rect.x, rect.y, rect.width, rect.height, rect.radius, rect.corners),
@@ -0,0 +1,66 @@
1
+ import { type AriaAttributes, type CSSProperties, type ReactNode } from "react";
2
+ /** Tile fill (Constitution V surface set: containers). */
3
+ export declare enum BigNumberVariant {
4
+ /** The canvas fill, `background.base`. */
5
+ BASE = "BASE",
6
+ /** A panel fill, `background.primary`. The default (1.x). */
7
+ PRIMARY = "PRIMARY",
8
+ /** A raised fill, `background.secondary`. */
9
+ SECONDARY = "SECONDARY",
10
+ /** The most elevated fill, `background.tertiary`. */
11
+ TERTIARY = "TERTIARY"
12
+ }
13
+ /**
14
+ * Which slot of a `BigNumberGroup` a tile sits in.
15
+ * @internal
16
+ */
17
+ export declare enum BigNumberGroupSlot {
18
+ /** The lead tiles on the left, on the frame's own surface: no fill, no border. */
19
+ PRIMARY = "PRIMARY",
20
+ /** The scrolling strip on the right: bordered by default, the tile's own fill. */
21
+ SECONDARY = "SECONDARY"
22
+ }
23
+ /**
24
+ * The slot a tile renders in; `null` outside a `BigNumberGroup`. Set by `BigNumberGroup` around
25
+ * each of its two slots.
26
+ * @internal
27
+ */
28
+ export declare const BigNumberGroupContext: import("react").Context<BigNumberGroupSlot | null>;
29
+ export interface BigNumberProps extends AriaAttributes {
30
+ /** What the number means. Small, tertiary, one line above the value. */
31
+ label: string;
32
+ /** The headline figure. A string or number renders as `body_lg` medium with tabular numerals; pass a node for a value with a unit or a custom treatment. */
33
+ value: ReactNode;
34
+ /** One short line under the value: the comparison or context ("+4% vs last week"). */
35
+ description?: string;
36
+ /** Pinned 8px after the number, vertically centered, however wide the tile: a status `Square`, a small `Icon`, a unit. */
37
+ suffix?: ReactNode;
38
+ /** At the far end of the value row, vertically centered: a `Sparkline`, a `Chip`, a delta. */
39
+ trailing?: ReactNode;
40
+ /**
41
+ * Surface fill of the tile. Ignored in a `BigNumberGroup`'s primary slot, which draws no fill.
42
+ * @default BigNumberVariant.PRIMARY
43
+ */
44
+ variant?: BigNumberVariant;
45
+ /**
46
+ * Adds the 1px hairline. Use it for tiles on a page; leave it off inside an already-bordered container. In a `BigNumberGroup`'s strip it defaults to `true`.
47
+ * @default false
48
+ */
49
+ hasBorder?: boolean;
50
+ /**
51
+ * Replaces `value` with a `Skeleton` line and hides `description`, `suffix` and `trailing`; the label stays. Sets `aria-busy`.
52
+ * @default false
53
+ */
54
+ isLoading?: boolean;
55
+ /** DOM id on the root. */
56
+ id?: string;
57
+ /** Any `data-*` attribute, forwarded to the root. */
58
+ [dataAttribute: `data-${string}`]: string | number | boolean | undefined;
59
+ /** Extra class on the root. */
60
+ className?: string;
61
+ /** Inline style on the root; only for setting CSS custom properties. */
62
+ style?: CSSProperties;
63
+ }
64
+ /** A KPI tile: label, headline value, optional description, suffix mark and trailing trend. */
65
+ declare const BigNumber: import("react").ForwardRefExoticComponent<BigNumberProps & import("react").RefAttributes<HTMLElement>>;
66
+ export default BigNumber;
@@ -5,41 +5,64 @@ import Flex, { AlignItems, FlexDirection } from "../layout/Flex.js";
5
5
  import Box, { BoxVariant } from "../layout/Box.js";
6
6
  import FlexItem from "../layout/FlexItem.js";
7
7
  /* empty css */
8
- import { forwardRef } from "react";
8
+ import { createContext, forwardRef, useContext } from "react";
9
9
  import { jsx, jsxs } from "react/jsx-runtime";
10
10
  import { cx } from "@linaria/core";
11
- //#region src/charts/StatChart.tsx
11
+ //#region src/charts/BigNumber.tsx
12
12
  /**
13
- * StatChart is the KPI tile: one number with its label, on a quiet surface, sized so a row of them
13
+ * BigNumber is the KPI tile: one number with its label, on a quiet surface, sized so a row of them
14
14
  * lines up. A `label` ("Active users"), a `value` ("1,284"), an optional `description` under the
15
- * value ("+4% vs last week") and an optional `trailing` slot at the end of the value row for a
15
+ * value ("+4% vs last week"), an optional `suffix` pinned 8px after the number (a status `Square`,
16
+ * a small `Icon`, a unit) and an optional `trailing` slot at the far end of the value row for a
16
17
  * `Sparkline` or a `Chip`. The tile is a `Box`: `variant` picks its surface step and `hasBorder`
17
18
  * adds the hairline. `isLoading` swaps the value for a `Skeleton` line of the same height.
18
19
  *
20
+ * Inside a `BigNumberGroup` the tile takes its slot's defaults through `BigNumberGroupContext`: in
21
+ * the primary slot no fill and no border (the frame's own surface), in the strip a hairline. An
22
+ * explicit `hasBorder` always wins.
23
+ *
19
24
  * It draws no chart itself and imports no chart code (no d3). It is not a card with a header and
20
- * actions (`Widget`) and not a list of label/value pairs (`DescriptionList`).
25
+ * actions (`Widget`) and not a list of label/value pairs (`DescriptionList`). Renamed from 1.x
26
+ * `StatChart`.
21
27
  */
22
28
  /** Tile fill (Constitution V surface set: containers). */
23
- var StatChartVariant = /* @__PURE__ */ function(StatChartVariant) {
29
+ var BigNumberVariant = /* @__PURE__ */ function(BigNumberVariant) {
24
30
  /** The canvas fill, `background.base`. */
25
- StatChartVariant["BASE"] = "BASE";
31
+ BigNumberVariant["BASE"] = "BASE";
26
32
  /** A panel fill, `background.primary`. The default (1.x). */
27
- StatChartVariant["PRIMARY"] = "PRIMARY";
33
+ BigNumberVariant["PRIMARY"] = "PRIMARY";
28
34
  /** A raised fill, `background.secondary`. */
29
- StatChartVariant["SECONDARY"] = "SECONDARY";
35
+ BigNumberVariant["SECONDARY"] = "SECONDARY";
30
36
  /** The most elevated fill, `background.tertiary`. */
31
- StatChartVariant["TERTIARY"] = "TERTIARY";
32
- return StatChartVariant;
37
+ BigNumberVariant["TERTIARY"] = "TERTIARY";
38
+ return BigNumberVariant;
39
+ }({});
40
+ /**
41
+ * Which slot of a `BigNumberGroup` a tile sits in.
42
+ * @internal
43
+ */
44
+ var BigNumberGroupSlot = /* @__PURE__ */ function(BigNumberGroupSlot) {
45
+ /** The lead tiles on the left, on the frame's own surface: no fill, no border. */
46
+ BigNumberGroupSlot["PRIMARY"] = "PRIMARY";
47
+ /** The scrolling strip on the right: bordered by default, the tile's own fill. */
48
+ BigNumberGroupSlot["SECONDARY"] = "SECONDARY";
49
+ return BigNumberGroupSlot;
33
50
  }({});
51
+ /**
52
+ * The slot a tile renders in; `null` outside a `BigNumberGroup`. Set by `BigNumberGroup` around
53
+ * each of its two slots.
54
+ * @internal
55
+ */
56
+ var BigNumberGroupContext = createContext(null);
34
57
  /** Identity by member name: `Box` owns the fill and the hairline. */
35
- var STAT_CHART_VARIANT_TO_BOX_VARIANT_MAP = {
58
+ var BIG_NUMBER_VARIANT_TO_BOX_VARIANT_MAP = {
36
59
  ["BASE"]: BoxVariant.BASE,
37
60
  ["PRIMARY"]: BoxVariant.PRIMARY,
38
61
  ["SECONDARY"]: BoxVariant.SECONDARY,
39
62
  ["TERTIARY"]: BoxVariant.TERTIARY
40
63
  };
41
64
  /** Tiles in a `Flex` row keep their width; in a `Grid` they stretch to the track (1.x). */
42
- var ROOT_CSS = "gx-StatChart-ROOT_CSS-rlaxlp8";
65
+ var ROOT_CSS = "gx-BigNumber-ROOT_CSS-r1lifffw";
43
66
  /** A string or number as the headline figure; a node as given. */
44
67
  function renderValue(value) {
45
68
  if (typeof value === "string" || typeof value === "number") return /* @__PURE__ */ jsx(Text, {
@@ -51,15 +74,17 @@ function renderValue(value) {
51
74
  });
52
75
  return value;
53
76
  }
54
- /** A KPI tile: label, headline value, optional description and trailing trend. */
55
- var StatChart = forwardRef(function StatChart({ label, value, description, trailing, variant = "PRIMARY", hasBorder = false, isLoading = false, id, className, style, ...rest }, ref) {
77
+ /** A KPI tile: label, headline value, optional description, suffix mark and trailing trend. */
78
+ var BigNumber = forwardRef(function BigNumber({ label, value, description, suffix, trailing, variant = "PRIMARY", hasBorder, isLoading = false, id, className, style, ...rest }, ref) {
79
+ const slot = useContext(BigNumberGroupContext);
80
+ const isPrimarySlot = slot === "PRIMARY";
56
81
  return /* @__PURE__ */ jsx(Box, {
57
82
  ...rest,
58
83
  ...isLoading ? { "aria-busy": true } : {},
59
84
  ref,
60
85
  ...id === void 0 ? {} : { id },
61
- variant: STAT_CHART_VARIANT_TO_BOX_VARIANT_MAP[variant],
62
- hasBorder,
86
+ ...isPrimarySlot ? {} : { variant: BIG_NUMBER_VARIANT_TO_BOX_VARIANT_MAP[variant] },
87
+ hasBorder: hasBorder ?? slot === "SECONDARY",
63
88
  radius: Radius.LG,
64
89
  padding: [12, 16],
65
90
  minWidth: 140,
@@ -88,7 +113,19 @@ var StatChart = forwardRef(function StatChart({ label, value, description, trail
88
113
  children: [/* @__PURE__ */ jsx(FlexItem, {
89
114
  grow: 1,
90
115
  minWidth: 0,
91
- children: renderValue(value)
116
+ children: suffix === void 0 || suffix === null || suffix === false ? renderValue(value) : /* @__PURE__ */ jsxs(Flex, {
117
+ alignItems: AlignItems.CENTER,
118
+ gap: 8,
119
+ minWidth: 0,
120
+ children: [/* @__PURE__ */ jsx(FlexItem, {
121
+ minWidth: 0,
122
+ children: renderValue(value)
123
+ }), /* @__PURE__ */ jsx(Flex, {
124
+ alignItems: AlignItems.CENTER,
125
+ shrink: 0,
126
+ children: suffix
127
+ })]
128
+ })
92
129
  }), trailing]
93
130
  }), description ? /* @__PURE__ */ jsx(Text, {
94
131
  size: TextSize.BODY_SM,
@@ -100,6 +137,6 @@ var StatChart = forwardRef(function StatChart({ label, value, description, trail
100
137
  })
101
138
  });
102
139
  });
103
- StatChart.displayName = "StatChart";
140
+ BigNumber.displayName = "BigNumber";
104
141
  //#endregion
105
- export { StatChartVariant, StatChart as default };
142
+ export { BigNumberGroupContext, BigNumberGroupSlot, BigNumberVariant, BigNumber as default };
@@ -0,0 +1,51 @@
1
+ import { type AriaAttributes, type CSSProperties, type ReactNode } from "react";
2
+ /** Frame fill (surface set: containers). Leave `variant` unset for no fill. */
3
+ export declare enum BigNumberGroupVariant {
4
+ /** The canvas fill, `background.base`. */
5
+ BASE = "BASE",
6
+ /** A panel fill, `background.primary`. */
7
+ PRIMARY = "PRIMARY",
8
+ /** A raised fill, `background.secondary`. */
9
+ SECONDARY = "SECONDARY",
10
+ /** The most elevated fill, `background.tertiary`. */
11
+ TERTIARY = "TERTIARY"
12
+ }
13
+ export interface BigNumberGroupProps extends AriaAttributes {
14
+ /** The strip's `BigNumber` tiles, right of `primary`. Bordered by default; each keeps its own `variant`. */
15
+ children?: ReactNode;
16
+ /** One or more lead `BigNumber` tiles on the left, on the frame's own surface with no fill and no border. */
17
+ primary?: ReactNode;
18
+ /**
19
+ * Surface fill of the frame. Unset draws no fill: the parent shows through.
20
+ * @default undefined (no fill)
21
+ */
22
+ variant?: BigNumberGroupVariant;
23
+ /**
24
+ * Adds the 1px hairline around the frame. Leave it off inside an already-bordered container (a `Widget`).
25
+ * @default false
26
+ */
27
+ hasBorder?: boolean;
28
+ /**
29
+ * Span the parent's width; the primary tiles take the spare width and the strip sits at the far end. Off: the frame hugs its tiles.
30
+ * @default false
31
+ */
32
+ fillWidth?: boolean;
33
+ /**
34
+ * Fade the strip toward each edge that has more tiles beyond it.
35
+ * @default false
36
+ */
37
+ hasFadeEdges?: boolean;
38
+ /** Names the scrolling strip (`role="region"`), announced when it takes focus. */
39
+ ariaLabel?: string;
40
+ /** DOM id on the root. */
41
+ id?: string;
42
+ /** Any `data-*` attribute, forwarded to the root. */
43
+ [dataAttribute: `data-${string}`]: string | number | boolean | undefined;
44
+ /** Extra class on the root. */
45
+ className?: string;
46
+ /** Inline style on the root; only for setting CSS custom properties. */
47
+ style?: CSSProperties;
48
+ }
49
+ /** A row of KPI tiles: lead tiles on the left, a sideways-scrolling strip of the rest on the right. */
50
+ declare const BigNumberGroup: import("react").ForwardRefExoticComponent<BigNumberGroupProps & import("react").RefAttributes<HTMLElement>>;
51
+ export default BigNumberGroup;
@@ -0,0 +1,112 @@
1
+ import { Radius } from "../theme/enums.js";
2
+ import Flex, { AlignItems } from "../layout/Flex.js";
3
+ import Box, { BoxVariant } from "../layout/Box.js";
4
+ import ScrollArea from "../layout/ScrollArea.js";
5
+ import FlexItem from "../layout/FlexItem.js";
6
+ import { BigNumberGroupContext, BigNumberGroupSlot } from "./BigNumber.js";
7
+ /* empty css */
8
+ import { forwardRef } from "react";
9
+ import { jsx, jsxs } from "react/jsx-runtime";
10
+ import { cx } from "@linaria/core";
11
+ //#region src/charts/BigNumberGroup.tsx
12
+ /**
13
+ * BigNumberGroup is a row of `BigNumber` tiles in one frame: the lead figure on the left and the
14
+ * breakdown in a strip on the right that scrolls sideways when the row is wider than its parent
15
+ * (the Filament observability summary). `primary` holds one or more tiles on the frame's own
16
+ * surface, borderless; `children` are the strip's tiles, bordered by default and filled with
17
+ * whatever `variant` each was given (`TERTIARY` reads raised). The slots set those defaults through
18
+ * `BigNumberGroupContext`; an explicit `hasBorder` on a tile always wins.
19
+ *
20
+ * The frame is a `Box` (radius `lg`, overflow hidden): `variant` picks its surface step and
21
+ * `hasBorder` adds the hairline. It hugs its tiles by default, so the strip only scrolls when the
22
+ * parent is narrower than the row; `fillWidth` spans the parent and gives the spare width to the
23
+ * primary tiles, pushing the strip to the far end. `hasFadeEdges` fades the strip toward each edge
24
+ * with more tiles beyond it. An overflowing strip is a tab stop (arrow keys scroll it); a strip
25
+ * that fits is not.
26
+ *
27
+ * Not a grid of equal cards (`Grid` of bordered `BigNumber`s), not a card with a header (`Widget`).
28
+ */
29
+ /** Frame fill (surface set: containers). Leave `variant` unset for no fill. */
30
+ var BigNumberGroupVariant = /* @__PURE__ */ function(BigNumberGroupVariant) {
31
+ /** The canvas fill, `background.base`. */
32
+ BigNumberGroupVariant["BASE"] = "BASE";
33
+ /** A panel fill, `background.primary`. */
34
+ BigNumberGroupVariant["PRIMARY"] = "PRIMARY";
35
+ /** A raised fill, `background.secondary`. */
36
+ BigNumberGroupVariant["SECONDARY"] = "SECONDARY";
37
+ /** The most elevated fill, `background.tertiary`. */
38
+ BigNumberGroupVariant["TERTIARY"] = "TERTIARY";
39
+ return BigNumberGroupVariant;
40
+ }({});
41
+ /** Identity by member name: `Box` owns the fill and the hairline. */
42
+ var BIG_NUMBER_GROUP_VARIANT_TO_BOX_VARIANT_MAP = {
43
+ ["BASE"]: BoxVariant.BASE,
44
+ ["PRIMARY"]: BoxVariant.PRIMARY,
45
+ ["SECONDARY"]: BoxVariant.SECONDARY,
46
+ ["TERTIARY"]: BoxVariant.TERTIARY
47
+ };
48
+ /** Hugging: as wide as the tiles, never wider than the parent (then the strip scrolls). */
49
+ var HUG_CSS = "gx-BigNumberGroup-HUG_CSS-h10zwtj7";
50
+ /** A row of KPI tiles: lead tiles on the left, a sideways-scrolling strip of the rest on the right. */
51
+ var BigNumberGroup = forwardRef(function BigNumberGroup({ children, primary, variant, hasBorder = false, fillWidth = false, hasFadeEdges = false, ariaLabel, id, className, style, ...rest }, ref) {
52
+ const hasPrimary = primary !== void 0 && primary !== null && primary !== false;
53
+ return /* @__PURE__ */ jsx(Box, {
54
+ ...rest,
55
+ ref,
56
+ ...id === void 0 ? {} : { id },
57
+ ...variant === void 0 ? {} : { variant: BIG_NUMBER_GROUP_VARIANT_TO_BOX_VARIANT_MAP[variant] },
58
+ hasBorder,
59
+ radius: Radius.LG,
60
+ overflow: "hidden",
61
+ fillWidth,
62
+ className: cx(!fillWidth && HUG_CSS, className),
63
+ ...style === void 0 ? {} : { style },
64
+ children: /* @__PURE__ */ jsxs(Flex, {
65
+ alignItems: AlignItems.CENTER,
66
+ gap: 16,
67
+ padding: [
68
+ 0,
69
+ 0,
70
+ 0,
71
+ 12
72
+ ],
73
+ children: [hasPrimary ? /* @__PURE__ */ jsx(FlexItem, {
74
+ grow: 1,
75
+ shrink: 0,
76
+ children: /* @__PURE__ */ jsx(Flex, {
77
+ gap: 12,
78
+ padding: [12, 0],
79
+ children: /* @__PURE__ */ jsx(BigNumberGroupContext.Provider, {
80
+ value: BigNumberGroupSlot.PRIMARY,
81
+ children: primary
82
+ })
83
+ })
84
+ }) : null, /* @__PURE__ */ jsx(FlexItem, {
85
+ grow: 0,
86
+ shrink: 1,
87
+ minWidth: 0,
88
+ children: /* @__PURE__ */ jsx(ScrollArea, {
89
+ canScrollHorizontally: true,
90
+ hasFadeEdges,
91
+ ...ariaLabel === void 0 ? {} : { ariaLabel },
92
+ children: /* @__PURE__ */ jsx(Flex, {
93
+ gap: 12,
94
+ padding: [
95
+ 12,
96
+ 12,
97
+ 12,
98
+ 0
99
+ ],
100
+ children: /* @__PURE__ */ jsx(BigNumberGroupContext.Provider, {
101
+ value: BigNumberGroupSlot.SECONDARY,
102
+ children
103
+ })
104
+ })
105
+ })
106
+ })]
107
+ })
108
+ });
109
+ });
110
+ BigNumberGroup.displayName = "BigNumberGroup";
111
+ //#endregion
112
+ export { BigNumberGroupVariant, BigNumberGroup as default };
@@ -12,7 +12,7 @@ import { cx } from "@linaria/core";
12
12
  */
13
13
  /** @internal The category hit layer. */
14
14
  function ChartCategoryTargets({ targets, onEnter, onLeave, onSelect }) {
15
- const className = cx(CHART_HIT_TARGET_CSS, onSelect && "gx-ChartPrimitives-CHART_HIT_TARGET_CLICKABLE_CSS-cjirv6a");
15
+ const className = cx(CHART_HIT_TARGET_CSS, onSelect && "gx-ChartPrimitives-CHART_HIT_TARGET_CLICKABLE_CSS-c1armna5");
16
16
  return /* @__PURE__ */ jsx(Fragment, { children: targets.map((target, index) => {
17
17
  const handlers = {
18
18
  onMouseEnter: () => onEnter(index),
@@ -1,4 +1,3 @@
1
- import Skeleton, { SkeletonVariant } from "../feedback/Skeleton.js";
2
1
  import { ChartKind, ChartLegendPlacement } from "./types.js";
3
2
  import { CHART_LEGEND_FILTER_EXTENT, CHART_LEGEND_SIDE_GAP } from "./constants.js";
4
3
  import Chip, { ChipSize } from "../chips/Chip.js";
@@ -18,8 +17,9 @@ import { FunnelSimpleIcon } from "@phosphor-icons/react";
18
17
  /**
19
18
  * @internal The shell every chart renders into: the root (sizing, legend placement, passthrough),
20
19
  * the measured plot box (one tab stop when interactive), the SVG and its inset translate, axes,
21
- * marks, hit targets, the in-chart tooltip, the empty and loading overlays, the live region and
22
- * the legend. On a filterable chart dismissible filter chips follow the legend entries while
20
+ * marks, hit targets, the in-chart tooltip, the empty overlay, the loading pulse (the whole plot
21
+ * fades in and out while the legend holds, so a loading chart still reads as a chart), the live
22
+ * region and the legend. On a filterable chart dismissible filter chips follow the legend entries while
23
23
  * something is pinned. One pin shows a chip per part ("06:00" and "Failed" for one segment): a
24
24
  * chip's × drops that part and keeps the other. Several pins collapse into one "3 filters" chip
25
25
  * (the list in its tooltip) whose × clears them all. It knows nothing about scales or geometry: axes and marks arrive as nodes, and every
@@ -58,8 +58,12 @@ var Overlay = /*#__PURE__*/ styled("div")({
58
58
  class: "gx-ChartFrame-Overlay-o1itt7vl",
59
59
  propsAsIs: false
60
60
  });
61
- /** A standalone `Skeleton RECT` that takes the whole plot box. */
62
- var LOADING_SKELETON_CSS = "gx-ChartFrame-LOADING_SKELETON_CSS-l1oi7u1q";
61
+ /**
62
+ * The loading pulse on the plot box: axes, marks and the plot overlay fade together, 1 → 0.25 → 1
63
+ * on the Skeleton's 2.4s curve, while the legend holds. Under `REDUCED_MOTION` the plot rests at
64
+ * half strength instead. The keyframes are global, so the name is `gx-` prefixed.
65
+ */
66
+ var PLOT_LOADING_CSS = "gx-ChartFrame-PLOT_LOADING_CSS-p1oi7u1q";
63
67
  /**
64
68
  * A chart's own legend (Heatmap's steps) with the filter chip after it. Both carry the legend's 12px
65
69
  * top padding and center on each other, so the chip centers on the legend's text line.
@@ -209,7 +213,6 @@ function ChartFrame({ rootRef, plotRef, id, className, style, rest, dimensions,
209
213
  role: "img",
210
214
  "aria-label": resolvedAriaLabel
211
215
  };
212
- const isSkeleton = isLoading && isEmpty;
213
216
  const isSideLegend = legendPlacement === ChartLegendPlacement.RIGHT;
214
217
  const categoryLabel = (key) => formatCategoryKey?.(key) ?? key;
215
218
  const seriesLabel = (key) => legendItems.find((item) => item.key === key)?.label ?? key;
@@ -244,7 +247,7 @@ function ChartFrame({ rootRef, plotRef, id, className, style, rest, dimensions,
244
247
  tooltip: part.key === "all" ? interaction.selection.map(describePin).join(", ") : "",
245
248
  onDismiss: () => handleFilterDismiss(part.rest)
246
249
  }, part.key));
247
- const legendNode = !hasLegend || isSkeleton ? null : legend ?? /* @__PURE__ */ jsx(ChartLegend, {
250
+ const legendNode = !hasLegend ? null : legend ?? /* @__PURE__ */ jsx(ChartLegend, {
248
251
  items: legendItems,
249
252
  placement: legendPlacement,
250
253
  swatch,
@@ -275,9 +278,9 @@ function ChartFrame({ rootRef, plotRef, id, className, style, rest, dimensions,
275
278
  ...plotAriaRest,
276
279
  ...plotA11yProps,
277
280
  ref: plotRef,
278
- className: cx(isInteractive && PLOT_INTERACTIVE_CSS, plotClassName),
281
+ className: cx(isInteractive && PLOT_INTERACTIVE_CSS, isLoading && PLOT_LOADING_CSS, plotClassName),
279
282
  children: [
280
- isMeasured && !isSkeleton && /* @__PURE__ */ jsx(ChartSvg, {
283
+ isMeasured && /* @__PURE__ */ jsx(ChartSvg, {
281
284
  "aria-hidden": "true",
282
285
  width,
283
286
  height,
@@ -303,17 +306,13 @@ function ChartFrame({ rootRef, plotRef, id, className, style, rest, dimensions,
303
306
  ]
304
307
  })
305
308
  }),
306
- isMeasured && !isSkeleton && plotOverlay,
309
+ isMeasured && plotOverlay,
307
310
  isMeasured && isEmpty && !isLoading && /* @__PURE__ */ jsx(Overlay, { children: /* @__PURE__ */ jsx(EmptyState, {
308
311
  size: EmptyStateSize.SMALL,
309
312
  header: placeholder,
310
313
  role: "status"
311
314
  }) }),
312
- isSkeleton && /* @__PURE__ */ jsx(Skeleton, {
313
- variant: SkeletonVariant.RECT,
314
- className: LOADING_SKELETON_CSS
315
- }),
316
- isMeasured && hasTooltip && !isSkeleton && /* @__PURE__ */ jsx(ChartTooltip, {
315
+ isMeasured && hasTooltip && /* @__PURE__ */ jsx(ChartTooltip, {
317
316
  model: tooltipModel,
318
317
  containerWidth: width,
319
318
  containerHeight: height,
@@ -13,6 +13,11 @@ export declare const CHART_AREA_STACKED_CSS: import("@linaria/core").LinariaClas
13
13
  export declare const CHART_BAR_CSS: import("@linaria/core").LinariaClassName;
14
14
  /** @internal A pie arc. */
15
15
  export declare const CHART_ARC_CSS: import("@linaria/core").LinariaClassName;
16
+ /**
17
+ * @internal The track a loading pie with no slices draws at its radii: the grid hairline bent into
18
+ * a ring, so the pulse has the shape of the chart it is about to be.
19
+ */
20
+ export declare const CHART_PIE_TRACK_CSS: import("@linaria/core").LinariaClassName;
16
21
  /** @internal A point dot, haloed by the canvas so it reads over the line. */
17
22
  export declare const CHART_POINT_CSS: import("@linaria/core").LinariaClassName;
18
23
  /** @internal A filled heatmap cell: its ramp step arrives as `--gx-chart-mark-color`. */
@@ -24,36 +24,41 @@ var CHART_AREA_STACKED_CSS = "gx-ChartPrimitives-CHART_AREA_STACKED_CSS-c1ob2op2
24
24
  var CHART_BAR_CSS = "gx-ChartPrimitives-CHART_BAR_CSS-c8c506o";
25
25
  /** @internal A pie arc. */
26
26
  var CHART_ARC_CSS = "gx-ChartPrimitives-CHART_ARC_CSS-ceqlpek";
27
+ /**
28
+ * @internal The track a loading pie with no slices draws at its radii: the grid hairline bent into
29
+ * a ring, so the pulse has the shape of the chart it is about to be.
30
+ */
31
+ var CHART_PIE_TRACK_CSS = "gx-ChartPrimitives-CHART_PIE_TRACK_CSS-c1fcbddl";
27
32
  /** @internal A point dot, haloed by the canvas so it reads over the line. */
28
- var CHART_POINT_CSS = "gx-ChartPrimitives-CHART_POINT_CSS-c1fcbddl";
33
+ var CHART_POINT_CSS = "gx-ChartPrimitives-CHART_POINT_CSS-cpcxr59";
29
34
  /** @internal A filled heatmap cell: its ramp step arrives as `--gx-chart-mark-color`. */
30
- var HEATMAP_CELL_CSS = "gx-ChartPrimitives-HEATMAP_CELL_CSS-hpcxr59";
35
+ var HEATMAP_CELL_CSS = "gx-ChartPrimitives-HEATMAP_CELL_CSS-h1wvzvu4";
31
36
  /** @internal An empty heatmap cell (no reading): a hairline outline, distinct from the lowest step. */
32
- var HEATMAP_EMPTY_CELL_CSS = "gx-ChartPrimitives-HEATMAP_EMPTY_CELL_CSS-h1wvzvu4";
37
+ var HEATMAP_EMPTY_CELL_CSS = "gx-ChartPrimitives-HEATMAP_EMPTY_CELL_CSS-h17guewt";
33
38
  /** @internal The engaged heatmap cell: an outline, so the rest keep their color for comparison. */
34
- var HEATMAP_ACTIVE_CELL_CSS = "gx-ChartPrimitives-HEATMAP_ACTIVE_CELL_CSS-h17guewt";
39
+ var HEATMAP_ACTIVE_CELL_CSS = "gx-ChartPrimitives-HEATMAP_ACTIVE_CELL_CSS-hblgiyf";
35
40
  /** @internal Emphasis of a mark. No transition: emphasis is feedback and snaps. */
36
41
  var CHART_MARK_STATE_TO_CSS_MAP = {
37
- [ChartMarkState.ACTIVE]: "gx-ChartPrimitives-ChartMarkState_ACTIVE-cblgiyf",
38
- [ChartMarkState.MUTED]: "gx-ChartPrimitives-ChartMarkState_MUTED-c1lr03cc",
39
- [ChartMarkState.DIMMED]: "gx-ChartPrimitives-ChartMarkState_DIMMED-cizy1s8"
42
+ [ChartMarkState.ACTIVE]: "gx-ChartPrimitives-ChartMarkState_ACTIVE-c1lr03cc",
43
+ [ChartMarkState.MUTED]: "gx-ChartPrimitives-ChartMarkState_MUTED-cizy1s8",
44
+ [ChartMarkState.DIMMED]: "gx-ChartPrimitives-ChartMarkState_DIMMED-c1ukq11d"
40
45
  };
41
46
  /** @internal A value grid hairline, drawn at every tick including zero. */
42
- var CHART_GRID_LINE_CSS = "gx-ChartPrimitives-CHART_GRID_LINE_CSS-c1ukq11d";
47
+ var CHART_GRID_LINE_CSS = "gx-ChartPrimitives-CHART_GRID_LINE_CSS-cwcko2m";
43
48
  /** @internal The rule at the engaged category (LineChart, AreaChart): one crisp pixel column. */
44
- var CHART_CURSOR_LINE_CSS = "gx-ChartPrimitives-CHART_CURSOR_LINE_CSS-cwcko2m";
49
+ var CHART_CURSOR_LINE_CSS = "gx-ChartPrimitives-CHART_CURSOR_LINE_CSS-cqwhvyz";
45
50
  /** @internal The rule held at a selected category: one step firmer on the same neutral ramp. */
46
- var CHART_CURSOR_LINE_SELECTED_CSS = "gx-ChartPrimitives-CHART_CURSOR_LINE_SELECTED_CSS-cqwhvyz";
51
+ var CHART_CURSOR_LINE_SELECTED_CSS = "gx-ChartPrimitives-CHART_CURSOR_LINE_SELECTED_CSS-c1iaray";
47
52
  /** @internal The band behind the engaged category (BarChart). */
48
- var CHART_CURSOR_BAND_CSS = "gx-ChartPrimitives-CHART_CURSOR_BAND_CSS-c1iaray";
53
+ var CHART_CURSOR_BAND_CSS = "gx-ChartPrimitives-CHART_CURSOR_BAND_CSS-cz6jod1";
49
54
  /** @internal The band held at a selected category. */
50
- var CHART_CURSOR_BAND_SELECTED_CSS = "gx-ChartPrimitives-CHART_CURSOR_BAND_SELECTED_CSS-cz6jod1";
55
+ var CHART_CURSOR_BAND_SELECTED_CSS = "gx-ChartPrimitives-CHART_CURSOR_BAND_SELECTED_CSS-c1de5mqk";
51
56
  /** @internal A transparent hit target above the marks. */
52
- var CHART_HIT_TARGET_CSS = "gx-ChartPrimitives-CHART_HIT_TARGET_CSS-c1de5mqk";
57
+ var CHART_HIT_TARGET_CSS = "gx-ChartPrimitives-CHART_HIT_TARGET_CSS-cjirv6a";
53
58
  /** @internal A hit target that reports a click (`onSelect` set). */
54
- var CHART_HIT_TARGET_CLICKABLE_CSS = "gx-ChartPrimitives-CHART_HIT_TARGET_CLICKABLE_CSS-cjirv6a";
59
+ var CHART_HIT_TARGET_CLICKABLE_CSS = "gx-ChartPrimitives-CHART_HIT_TARGET_CLICKABLE_CSS-c1armna5";
55
60
  /** @internal A `foreignObject` holding an axis label (`Text`). */
56
- var CHART_AXIS_LABEL_BOX_CSS = "gx-ChartPrimitives-CHART_AXIS_LABEL_BOX_CSS-c1armna5";
61
+ var CHART_AXIS_LABEL_BOX_CSS = "gx-ChartPrimitives-CHART_AXIS_LABEL_BOX_CSS-cgd77rv";
57
62
  /**
58
63
  * @internal A target's `mouseleave`: calls `onLeave` only when the pointer left the target layers,
59
64
  * not when it crossed into a neighbouring target, so the engaged category never flickers through
@@ -62,8 +67,8 @@ var CHART_AXIS_LABEL_BOX_CSS = "gx-ChartPrimitives-CHART_AXIS_LABEL_BOX_CSS-c1ar
62
67
  function leaveUnlessTarget(event, onLeave) {
63
68
  const next = event.relatedTarget;
64
69
  const layers = event.currentTarget.parentElement;
65
- if (next instanceof Element && layers?.contains(next) && next.classList.contains("gx-ChartPrimitives-CHART_HIT_TARGET_CSS-c1de5mqk")) return;
70
+ if (next instanceof Element && layers?.contains(next) && next.classList.contains("gx-ChartPrimitives-CHART_HIT_TARGET_CSS-cjirv6a")) return;
66
71
  onLeave();
67
72
  }
68
73
  //#endregion
69
- export { CHART_ARC_CSS, CHART_AREA_CSS, CHART_AREA_OVERLAP_CSS, CHART_AREA_STACKED_CSS, CHART_AXIS_LABEL_BOX_CSS, CHART_BAR_CSS, CHART_CURSOR_BAND_CSS, CHART_CURSOR_BAND_SELECTED_CSS, CHART_CURSOR_LINE_CSS, CHART_CURSOR_LINE_SELECTED_CSS, CHART_GRID_LINE_CSS, CHART_HIT_TARGET_CLICKABLE_CSS, CHART_HIT_TARGET_CSS, CHART_LINE_CSS, CHART_LINE_DASHED_CSS, CHART_MARK_STATE_TO_CSS_MAP, CHART_POINT_CSS, HEATMAP_ACTIVE_CELL_CSS, HEATMAP_CELL_CSS, HEATMAP_EMPTY_CELL_CSS, leaveUnlessTarget };
74
+ export { CHART_ARC_CSS, CHART_AREA_CSS, CHART_AREA_OVERLAP_CSS, CHART_AREA_STACKED_CSS, CHART_AXIS_LABEL_BOX_CSS, CHART_BAR_CSS, CHART_CURSOR_BAND_CSS, CHART_CURSOR_BAND_SELECTED_CSS, CHART_CURSOR_LINE_CSS, CHART_CURSOR_LINE_SELECTED_CSS, CHART_GRID_LINE_CSS, CHART_HIT_TARGET_CLICKABLE_CSS, CHART_HIT_TARGET_CSS, CHART_LINE_CSS, CHART_LINE_DASHED_CSS, CHART_MARK_STATE_TO_CSS_MAP, CHART_PIE_TRACK_CSS, CHART_POINT_CSS, HEATMAP_ACTIVE_CELL_CSS, HEATMAP_CELL_CSS, HEATMAP_EMPTY_CELL_CSS, leaveUnlessTarget };
@@ -288,14 +288,14 @@ var Heatmap = forwardRef(function Heatmap(props, ref) {
288
288
  categoryIndex: index,
289
289
  seriesKey: cell.row
290
290
  });
291
- if (state === ChartMarkState.MUTED && !isLoading) state = ChartMarkState.DIMMED;
291
+ if (state === ChartMarkState.MUTED) state = ChartMarkState.DIMMED;
292
292
  return /* @__PURE__ */ jsx("rect", {
293
293
  x: cell.x,
294
294
  y: cell.y,
295
295
  width: cell.width,
296
296
  height: cell.height,
297
297
  rx: HEATMAP_CELL_RADIUS,
298
- className: cx(cell.step === null ? HEATMAP_EMPTY_CELL_CSS : HEATMAP_CELL_CSS, interaction.activeIndex === index && "gx-ChartPrimitives-HEATMAP_ACTIVE_CELL_CSS-h17guewt", CHART_MARK_STATE_TO_CSS_MAP[state]),
298
+ className: cx(cell.step === null ? HEATMAP_EMPTY_CELL_CSS : HEATMAP_CELL_CSS, interaction.activeIndex === index && "gx-ChartPrimitives-HEATMAP_ACTIVE_CELL_CSS-hblgiyf", CHART_MARK_STATE_TO_CSS_MAP[state]),
299
299
  style: cell.step === null ? void 0 : { "--gx-chart-mark-color": stepColor(cell) }
300
300
  }, cell.id);
301
301
  })
@@ -238,7 +238,7 @@ function LineChartRootInner(props, ref) {
238
238
  x2: activeColumn.x,
239
239
  y1: 0,
240
240
  y2: plotHeight,
241
- className: "gx-ChartPrimitives-CHART_CURSOR_LINE_CSS-cwcko2m"
241
+ className: "gx-ChartPrimitives-CHART_CURSOR_LINE_CSS-cqwhvyz"
242
242
  }),
243
243
  !isEmpty && geometry.paths.map((path) => /* @__PURE__ */ jsx("path", {
244
244
  d: path.path,
@@ -13,7 +13,7 @@ import { PIE_MIN_SLICE_SHARE, buildPieChartGeometry, resolvePieChartSlices } fro
13
13
  /* empty css */
14
14
  import { styled } from "@linaria/react";
15
15
  import { forwardRef, useCallback, useMemo, useRef } from "react";
16
- import { jsx } from "react/jsx-runtime";
16
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
17
17
  import { cx } from "@linaria/core";
18
18
  //#region src/charts/PieChart.tsx
19
19
  /**
@@ -191,16 +191,22 @@ function PieChartInner(props, ref) {
191
191
  legendItems,
192
192
  legendPlacement: ChartLegendPlacement.RIGHT,
193
193
  swatch,
194
- children: /* @__PURE__ */ jsx("g", {
194
+ children: /* @__PURE__ */ jsxs("g", {
195
195
  transform: centerTransform,
196
- children: geometry.arcs.map((item, index) => /* @__PURE__ */ jsx("path", {
196
+ children: [isLoading && isEmpty && geometry.outerRadius > 0 && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("circle", {
197
+ r: geometry.outerRadius,
198
+ className: "gx-ChartPrimitives-CHART_PIE_TRACK_CSS-c1fcbddl"
199
+ }), geometry.innerRadius > 0 && /* @__PURE__ */ jsx("circle", {
200
+ r: geometry.innerRadius,
201
+ className: "gx-ChartPrimitives-CHART_PIE_TRACK_CSS-c1fcbddl"
202
+ })] }), geometry.arcs.map((item, index) => /* @__PURE__ */ jsx("path", {
197
203
  d: item.path,
198
204
  className: cx(CHART_ARC_CSS, CHART_MARK_STATE_TO_CSS_MAP[interaction.getMarkState({
199
205
  categoryIndex: index,
200
206
  seriesKey: item.id
201
207
  })]),
202
208
  style: { "--gx-chart-mark-color": item.color.color }
203
- }, item.id))
209
+ }, item.id))]
204
210
  })
205
211
  });
206
212
  }
@@ -9,7 +9,7 @@ import { cx } from "@linaria/core";
9
9
  //#region src/charts/Sparkline.tsx
10
10
  /**
11
11
  * Sparkline is a word-sized trend: a tiny line or row of bars with no axes, legend, tooltip or
12
- * interaction, set beside the number it summarizes in a table cell, a list row, a `StatChart` or a
12
+ * interaction, set beside the number it summarizes in a table cell, a list row, a `BigNumber` or a
13
13
  * sentence. It shows shape (rising, falling, spiky), not values; a chart to read values from is
14
14
  * `LineChart` / `BarChart`.
15
15
  *
@@ -284,7 +284,7 @@ export interface BaseChartProps<TKey extends string> extends AriaAttributes {
284
284
  /** Replaces the tooltip body; positioning stays with the chart. Never called with empty rows. */
285
285
  renderTooltip?: ChartTooltipRenderer;
286
286
  /**
287
- * With no data yet, a `Skeleton` fills the plot; with data, marks recede and interaction pauses until it clears. Sets `aria-busy`.
287
+ * The plot (axes and marks) pulses between opaque and faint while the legend holds; interaction pauses until it clears. Sets `aria-busy`.
288
288
  * @default false
289
289
  */
290
290
  isLoading?: boolean;
@@ -173,7 +173,6 @@ function useChartInteraction({ categoryCount, seriesKeys, categoryKeys, enableGr
173
173
  categoryKeys
174
174
  ]);
175
175
  const getMarkState = useCallback(({ categoryIndex, seriesKey }) => {
176
- if (isLoading) return ChartMarkState.MUTED;
177
176
  if (seriesKey !== void 0 && safeHoveredSeries !== null) return seriesKey === safeHoveredSeries ? ChartMarkState.ACTIVE : ChartMarkState.MUTED;
178
177
  if (!matchesSelection({
179
178
  categoryIndex,
@@ -182,7 +181,6 @@ function useChartInteraction({ categoryCount, seriesKeys, categoryKeys, enableGr
182
181
  if (hasSelection) return ChartMarkState.ACTIVE;
183
182
  return categoryIndex !== void 0 && activeIndex !== null && categoryIndex !== activeIndex ? categoryMuteState : ChartMarkState.ACTIVE;
184
183
  }, [
185
- isLoading,
186
184
  matchesSelection,
187
185
  safeHoveredSeries,
188
186
  hasSelection,