@kind-ui/charts 0.1.1 → 0.3.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 (117) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +683 -1
  3. package/dist/activity-rings.d.ts +2 -1
  4. package/dist/activity-rings.js +6 -3
  5. package/dist/animation.d.ts +11 -3
  6. package/dist/animation.js +18 -10
  7. package/dist/area-chart.d.ts +3 -1
  8. package/dist/area-chart.js +15 -10
  9. package/dist/area-series.d.ts +9 -1
  10. package/dist/area-series.js +35 -8
  11. package/dist/bar-chart.d.ts +10 -3
  12. package/dist/bar-chart.js +17 -4
  13. package/dist/bar-material.js +2 -3
  14. package/dist/bar-series.d.ts +11 -1
  15. package/dist/bar-series.js +65 -13
  16. package/dist/box-plot.js +2 -2
  17. package/dist/category-cells.d.ts +7 -1
  18. package/dist/category-cells.js +32 -2
  19. package/dist/chart-background-pattern.d.ts +23 -0
  20. package/dist/chart-background-pattern.js +31 -0
  21. package/dist/chart-context.d.ts +6 -2
  22. package/dist/chart-interaction.d.ts +94 -0
  23. package/dist/chart-interaction.js +224 -0
  24. package/dist/combo-chart.d.ts +8 -5
  25. package/dist/combo-chart.js +14 -12
  26. package/dist/configured-line-chart.d.ts +5 -1
  27. package/dist/configured-line-chart.js +8 -5
  28. package/dist/emphasis.d.ts +5 -2
  29. package/dist/emphasis.js +18 -4
  30. package/dist/fill-pattern.d.ts +25 -0
  31. package/dist/fill-pattern.js +23 -0
  32. package/dist/heatmap.d.ts +4 -2
  33. package/dist/heatmap.js +34 -12
  34. package/dist/histogram-chart.js +10 -3
  35. package/dist/histogram-material.js +1 -2
  36. package/dist/index.d.ts +12 -3
  37. package/dist/index.js +8 -1
  38. package/dist/legend.d.ts +2 -0
  39. package/dist/legend.js +28 -7
  40. package/dist/line-chart.d.ts +13 -3
  41. package/dist/line-chart.js +54 -34
  42. package/dist/line-dash.d.ts +8 -0
  43. package/dist/line-dash.js +18 -0
  44. package/dist/line-material.d.ts +1 -1
  45. package/dist/line-material.js +1 -1
  46. package/dist/line-series.d.ts +9 -1
  47. package/dist/line-series.js +37 -11
  48. package/dist/loading-cartesian-designs.d.ts +6 -0
  49. package/dist/loading-cartesian-designs.js +123 -0
  50. package/dist/loading-motion.d.ts +37 -0
  51. package/dist/loading-motion.js +88 -0
  52. package/dist/loading-polar-designs.d.ts +6 -0
  53. package/dist/loading-polar-designs.js +95 -0
  54. package/dist/loading-skeleton.d.ts +29 -0
  55. package/dist/loading-skeleton.js +143 -0
  56. package/dist/loading-standalone-designs.d.ts +5 -0
  57. package/dist/loading-standalone-designs.js +126 -0
  58. package/dist/percent-stack.d.ts +18 -0
  59. package/dist/percent-stack.js +33 -0
  60. package/dist/pie-chart.d.ts +7 -3
  61. package/dist/pie-chart.js +37 -6
  62. package/dist/pie-material.js +1 -1
  63. package/dist/pie-pin-identity.d.ts +4 -0
  64. package/dist/pie-pin-identity.js +10 -0
  65. package/dist/pie-series.d.ts +4 -0
  66. package/dist/pie-series.js +138 -15
  67. package/dist/pie-tooltip-pin.d.ts +4 -0
  68. package/dist/pie-tooltip-pin.js +52 -0
  69. package/dist/point-marker.d.ts +19 -0
  70. package/dist/point-marker.js +19 -0
  71. package/dist/polar-chart.d.ts +14 -5
  72. package/dist/polar-chart.js +41 -10
  73. package/dist/polar-material.js +1 -1
  74. package/dist/polar-series.js +68 -22
  75. package/dist/radar-interaction.js +10 -4
  76. package/dist/radial-category.d.ts +2 -0
  77. package/dist/reveal-clip.d.ts +16 -0
  78. package/dist/reveal-clip.js +18 -0
  79. package/dist/root.d.ts +5 -9
  80. package/dist/root.js +46 -11
  81. package/dist/sankey-chart.d.ts +5 -1
  82. package/dist/sankey-chart.js +64 -13
  83. package/dist/sankey-colors.d.ts +3 -0
  84. package/dist/sankey-finish.d.ts +1 -1
  85. package/dist/sankey-finish.js +1 -1
  86. package/dist/sankey-interaction.d.ts +8 -0
  87. package/dist/sankey-interaction.js +32 -0
  88. package/dist/sankey-legend.d.ts +2 -1
  89. package/dist/sankey-legend.js +18 -3
  90. package/dist/sankey-node-label.d.ts +22 -0
  91. package/dist/sankey-node-label.js +34 -0
  92. package/dist/scatter-chart.d.ts +5 -3
  93. package/dist/scatter-chart.js +14 -4
  94. package/dist/scatter-material.js +1 -1
  95. package/dist/scatter-series.js +5 -3
  96. package/dist/series-color.d.ts +10 -0
  97. package/dist/series-color.js +48 -0
  98. package/dist/series-interaction.d.ts +12 -0
  99. package/dist/series-interaction.js +82 -0
  100. package/dist/series-label.d.ts +7 -0
  101. package/dist/series-label.js +18 -0
  102. package/dist/series-paint.d.ts +8 -0
  103. package/dist/series-paint.js +27 -0
  104. package/dist/styles.css +151 -6
  105. package/dist/stylesheet-warning.d.ts +2 -0
  106. package/dist/stylesheet-warning.js +86 -0
  107. package/dist/surface-material.js +1 -1
  108. package/dist/tooltip-content.d.ts +8 -1
  109. package/dist/tooltip-content.js +15 -4
  110. package/dist/tooltip.d.ts +3 -1
  111. package/dist/tooltip.js +8 -5
  112. package/dist/types.d.ts +11 -2
  113. package/dist/waterfall-chart.d.ts +4 -0
  114. package/dist/waterfall-chart.js +7 -0
  115. package/package.json +2 -2
  116. package/dist/bar-paper.d.ts +0 -2
  117. package/dist/bar-paper.js +0 -6
@@ -1,13 +1,18 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { Children, Fragment, isValidElement, use, useCallback, useId, useLayoutEffect, useRef, useState, } from "react";
3
+ import { Children, cloneElement, Fragment, isValidElement, memo, use, useCallback, useId, useLayoutEffect, useMemo, useRef, useState, } from "react";
4
4
  import { Cell, Pie, Sector } from "recharts";
5
- import { categoryCells } from "./category-cells.js";
5
+ import { categoryCells, filterCategoryRows } from "./category-cells.js";
6
6
  import { useChart } from "./chart-context.js";
7
+ import { useChartInteraction, useInteractionFocus } from "./chart-interaction.js";
7
8
  import { EmphasisMark } from "./emphasis.js";
8
9
  import { useChartKeyboard, useLineInteraction } from "./line-chart.js";
9
10
  import { PieMotion } from "./pie-chart.js";
10
11
  import { PieMaterialFilter } from "./pie-material.js";
12
+ import { registerPiePinComponent } from "./pie-pin-identity.js";
13
+ // Native Pie keys its animation subtree by props identity even with animation disabled.
14
+ // Pointer/pin context updates must not replace an unchanged pressed native sector.
15
+ const StablePie = memo(Pie);
11
16
  // Recharts also supports Cell props as data when neither the chart nor Pie supplies rows.
12
17
  function cellProps(children) {
13
18
  const result = [];
@@ -30,11 +35,45 @@ function sameCells(previous, next) {
30
35
  Object.keys(props).every((key) => Object.is(old[key], props[key])));
31
36
  }));
32
37
  }
38
+ // Capture original rendered identity before an inner Cell handler can commit new rows.
39
+ function captureCellIdentity(children, keyAt, identities) {
40
+ let index = 0;
41
+ function capture(parts) {
42
+ return Children.map(parts, (child) => {
43
+ if (!isValidElement(child))
44
+ return child;
45
+ if (child.type === Fragment)
46
+ return cloneElement(child, {}, capture(child.props.children));
47
+ if (child.type !== Cell)
48
+ return child;
49
+ const key = keyAt(index++);
50
+ if (key === undefined)
51
+ return child;
52
+ return cloneElement(child, {
53
+ onClick: (event) => {
54
+ identities.set(event.nativeEvent, key);
55
+ child.props.onClick?.(event);
56
+ },
57
+ });
58
+ });
59
+ }
60
+ return capture(children);
61
+ }
33
62
  // One chart-level angular window reveals unchanged native sectors.
34
- function EntranceSector({ material, emphasisKey, scope, enabled, seriesStartAngle, seriesEndAngle, ...props }) {
63
+ function EntranceSector({ material, emphasisKey, scope, enabled, interactionKey, seriesStartAngle, seriesEndAngle, ...props }) {
35
64
  const keyboard = useChartKeyboard();
65
+ const interaction = useChartInteraction();
36
66
  const { reveal, progress, direction } = use(PieMotion);
37
- const semantic = emphasisKey ? emphasisKey(props.payload) : props.name;
67
+ const semantic = interactionKey
68
+ ? interactionKey(props.index ?? -1)
69
+ : emphasisKey
70
+ ? emphasisKey(props.payload)
71
+ : props.name;
72
+ const interactive = interactionKey !== undefined &&
73
+ interaction.interactive &&
74
+ interaction.markActivation &&
75
+ interaction.eligible.includes(String(semantic));
76
+ const focusRef = useInteractionFocus(String(semantic), interactive);
38
77
  const generatedId = useId();
39
78
  const sourceId = `kind-ui-pie-${generatedId.replace(/[^a-zA-Z0-9_-]/g, "_")}-paint`;
40
79
  const maskId = `${sourceId}-alpha`;
@@ -45,7 +84,7 @@ function EntranceSector({ material, emphasisKey, scope, enabled, seriesStartAngl
45
84
  const markGroup = useRef(null);
46
85
  const [paintFilter, setPaintFilter] = useState("none");
47
86
  const [paintClip, setPaintClip] = useState("none");
48
- // Measure native ownership before attaching paint, including the first non-Plain render.
87
+ // Measure native ownership before attaching paint, including the first non-default render.
49
88
  const [cssTransformOwned, setCssTransformOwned] = useState();
50
89
  const [clipTransform, setClipTransform] = useState({ forward: "", inverse: "" });
51
90
  const [paintBounds, setPaintBounds] = useState();
@@ -151,25 +190,102 @@ function EntranceSector({ material, emphasisKey, scope, enabled, seriesStartAngl
151
190
  const revealStart = fromStart ? seriesStartAngle : seriesStartAngle + nativeSpan;
152
191
  const revealSpan = Math.abs(nativeSpan) * (clockwise ? -1 : 1);
153
192
  const { className, cornerRadius, onClick, onMouseDown, onMouseUp, onMouseMove, onMouseOver, onMouseOut, onMouseEnter, onMouseLeave, ...sector } = props;
154
- return (_jsx(EmphasisMark, { enabled: enabled &&
155
- (emphasisKey !== undefined ? semantic !== undefined : typeof semantic === "string"), target: { kind: "sector", key: String(semantic), scope, seriesKey: String(semantic) }, keyboardActive: keyboard && props.isActive, children: _jsxs("g", { ref: markGroup, children: [maskEntrance && (_jsx("defs", { children: _jsx("mask", { id: entranceId, maskUnits: "userSpaceOnUse", x: props.cx - props.outerRadius - margin, y: props.cy - props.outerRadius - margin, width: (props.outerRadius + margin) * 2, height: (props.outerRadius + margin) * 2, style: { maskType: "alpha" }, children: _jsx(Sector, { fill: "white", "data-kind-ui": "pie-entrance-window", "data-direction": direction, "data-progress": progress, cx: props.cx, cy: props.cy, innerRadius: 0, outerRadius: props.outerRadius + margin, startAngle: revealStart, endAngle: revealStart + revealSpan * progress }) }) })), _jsxs("g", { mask: maskEntrance ? `url(#${entranceId})` : undefined, children: [materialized && (_jsxs("defs", { "data-kind-ui": "pie-material", "data-material": material, pointerEvents: "none", children: [_jsx(PieMaterialFilter, { material: material, id: filterId, strokeWidth: Math.max(0, Number.isFinite(resolvedStroke) ? resolvedStroke : 0, paintStroke), cx: props.cx, cy: props.cy, radius: props.outerRadius, thickness: props.outerRadius - props.innerRadius, bounds: paintBounds }), inset && (_jsx("mask", { id: maskId, maskUnits: "userSpaceOnUse", x: paintBounds?.x ?? Math.floor(props.cx - props.outerRadius - margin), y: paintBounds?.y ?? Math.floor(props.cy - props.outerRadius - margin), width: paintBounds?.width ?? Math.ceil(props.outerRadius * 2 + margin * 2) + 1, height: paintBounds?.height ?? Math.ceil(props.outerRadius * 2 + margin * 2) + 1, style: { maskType: "alpha" }, children: _jsx("use", { href: `#${sourceId}` }) }))] })), materialized && material === "glow" && (
193
+ return (_jsx(EmphasisMark, { ref: focusRef, "data-interaction-focus-key": interactive ? String(semantic) : undefined, persistent: interactionKey !== undefined, enabled: enabled &&
194
+ (emphasisKey !== undefined ? semantic !== undefined : typeof semantic === "string"), target: { kind: "sector", key: String(semantic), scope, seriesKey: String(semantic) }, keyboardActive: keyboard && props.isActive === true, role: interactive ? "button" : undefined, tabIndex: interactive ? 0 : undefined, "aria-label": interactive
195
+ ? `${interaction.mode === "focus" ? "Highlight" : "Toggle"} ${String(semantic)}`
196
+ : undefined, "aria-pressed": interactive
197
+ ? interaction.mode === "focus"
198
+ ? interaction.selected === semantic
199
+ : true
200
+ : undefined, onKeyDown: (event) => {
201
+ if (interactive &&
202
+ event.target === event.currentTarget &&
203
+ !event.defaultPrevented &&
204
+ (event.key === "Enter" || event.key === " ")) {
205
+ if (!event.repeat)
206
+ interaction.activate({ kind: "category", key: String(semantic) }, "mark", event);
207
+ event.preventDefault();
208
+ }
209
+ }, children: _jsxs("g", { ref: markGroup, children: [maskEntrance && (_jsx("defs", { children: _jsx("mask", { id: entranceId, maskUnits: "userSpaceOnUse", x: props.cx - props.outerRadius - margin, y: props.cy - props.outerRadius - margin, width: (props.outerRadius + margin) * 2, height: (props.outerRadius + margin) * 2, style: { maskType: "alpha" }, children: _jsx(Sector, { fill: "white", "data-kind-ui": "pie-entrance-window", "data-direction": direction, "data-progress": progress, cx: props.cx, cy: props.cy, innerRadius: 0, outerRadius: props.outerRadius + margin, startAngle: revealStart, endAngle: revealStart + revealSpan * progress }) }) })), _jsxs("g", { mask: maskEntrance ? `url(#${entranceId})` : undefined, children: [materialized && (_jsxs("defs", { "data-kind-ui": "pie-material", "data-material": material, pointerEvents: "none", children: [_jsx(PieMaterialFilter, { material: material, id: filterId, strokeWidth: Math.max(0, Number.isFinite(resolvedStroke) ? resolvedStroke : 0, paintStroke), cx: props.cx, cy: props.cy, radius: props.outerRadius, thickness: props.outerRadius - props.innerRadius, bounds: paintBounds }), inset && (_jsx("mask", { id: maskId, maskUnits: "userSpaceOnUse", x: paintBounds?.x ?? Math.floor(props.cx - props.outerRadius - margin), y: paintBounds?.y ?? Math.floor(props.cy - props.outerRadius - margin), width: paintBounds?.width ?? Math.ceil(props.outerRadius * 2 + margin * 2) + 1, height: paintBounds?.height ?? Math.ceil(props.outerRadius * 2 + margin * 2) + 1, style: { maskType: "alpha" }, children: _jsx("use", { href: `#${sourceId}` }) }))] })), materialized && material === "glow" && (
156
210
  // biome-ignore lint/a11y/noAriaHiddenOnFocusable: SVG decoration is explicitly nonfocusable and ignores pointer events.
157
- _jsx("g", { pointerEvents: "none", focusable: "false", "aria-hidden": "true", "data-kind-ui": "pie-halo", style: { clipPath: paintClip }, transform: paintClip !== "none" ? clipTransform.forward : undefined, children: _jsx("g", { transform: paintClip !== "none" ? clipTransform.inverse : undefined, filter: `url(#${filterId})`, children: _jsx("use", { href: `#${sourceId}` }) }) })), _jsx("g", { ...(inset ? { filter: `url(#${filterId})` } : {}), ...(inset ? { mask: `url(#${maskId})` } : {}), children: _jsxs("g", { id: sourceId, children: [materialized && (_jsx("rect", { x: paintBounds?.x ?? props.cx - props.outerRadius - margin, y: paintBounds?.y ?? props.cy - props.outerRadius - margin, width: paintBounds?.width ?? props.outerRadius * 2 + margin * 2, height: paintBounds?.height ?? props.outerRadius * 2 + margin * 2, fill: "white", fillOpacity: 0, pointerEvents: "none" })), _jsx(Sector, { ...sector, ...(onClick ? { onClick } : {}), ...(onMouseDown ? { onMouseDown } : {}), ...(onMouseUp ? { onMouseUp } : {}), ...(onMouseMove ? { onMouseMove } : {}), ...(onMouseOver ? { onMouseOver } : {}), ...(onMouseOut ? { onMouseOut } : {}), ...(onMouseEnter ? { onMouseEnter } : {}), ...(onMouseLeave ? { onMouseLeave } : {}), ...(className !== undefined ? { className } : {}), ...(cornerRadius !== undefined ? { cornerRadius } : {}), "data-kind-ui": "pie-sector", "data-reveal": maskEntrance ? "on" : "off" })] }) })] })] }) }));
211
+ _jsx("g", { pointerEvents: "none", focusable: "false", "aria-hidden": "true", "data-kind-ui": "pie-halo", style: { clipPath: paintClip }, transform: paintClip !== "none" ? clipTransform.forward : undefined, children: _jsx("g", { transform: paintClip !== "none" ? clipTransform.inverse : undefined, filter: `url(#${filterId})`, children: _jsx("use", { href: `#${sourceId}` }) }) })), _jsx("g", { ...(inset ? { filter: `url(#${filterId})` } : {}), ...(inset ? { mask: `url(#${maskId})` } : {}), children: _jsxs("g", { id: sourceId, children: [materialized && (_jsx("rect", { x: paintBounds?.x ?? props.cx - props.outerRadius - margin, y: paintBounds?.y ?? props.cy - props.outerRadius - margin, width: paintBounds?.width ?? props.outerRadius * 2 + margin * 2, height: paintBounds?.height ?? props.outerRadius * 2 + margin * 2, fill: "white", fillOpacity: 0, pointerEvents: "none" })), _jsx(Sector, { ...sector, ...(onClick ? { onClick } : {}), ...(onMouseDown ? { onMouseDown } : {}), ...(onMouseUp ? { onMouseUp } : {}), ...(onMouseMove ? { onMouseMove } : {}), ...(onMouseOver ? { onMouseOver } : {}), ...(onMouseOut ? { onMouseOut } : {}), ...(onMouseEnter ? { onMouseEnter } : {}), ...(onMouseLeave ? { onMouseLeave } : {}), ...(className !== undefined ? { className } : {}), ...(cornerRadius !== undefined ? { cornerRadius } : {}), "data-kind-ui": "pie-sector", "data-sector-span": props.endAngle - props.startAngle, "data-reveal": maskEntrance ? "on" : "off" })] }) })] })] }) }));
158
212
  }
159
213
  /** A native Pie. Use innerRadius for donuts; category data, Cells and visibility are consumer-owned. */
160
214
  export function PieSeries(props) {
161
- const { material = "plain", emphasisKey, categoryKey, ...nativeProps } = props;
162
- const { config } = useChart();
163
- const children = categoryKey === undefined
164
- ? props.children
165
- : categoryCells(props.data, categoryKey, config, props.children, props.fill);
215
+ const { material = "plain", glowCategories, emphasisKey, categoryKey, interactionBinding, ...nativeProps } = props;
216
+ const interaction = useChartInteraction();
217
+ if (interactionBinding &&
218
+ (interaction.kind !== "category" || categoryKey === undefined || props.data === undefined))
219
+ throw new Error("PieSeries Root interaction binding requires category-kind Root, categoryKey and explicit data");
220
+ const filtered = useMemo(() => interactionBinding && props.data && categoryKey !== undefined
221
+ ? filterCategoryRows(props.data, categoryKey, interaction.visible, props.children)
222
+ : undefined, [interactionBinding, props.data, categoryKey, interaction.visible, props.children]);
223
+ const data = filtered?.data ?? props.data;
224
+ const originalChildren = filtered?.children ?? props.children;
225
+ const resolveInteractionKey = useCallback((index) => {
226
+ // Cell props can override native payload fields; native index still addresses our rendered rows.
227
+ const row = data?.[index];
228
+ if (row === undefined)
229
+ return undefined;
230
+ if (typeof categoryKey === "function")
231
+ return categoryKey(row);
232
+ if (categoryKey !== undefined &&
233
+ typeof row === "object" &&
234
+ row !== null &&
235
+ Object.hasOwn(row, categoryKey))
236
+ return String(row[categoryKey]);
237
+ throw new Error("PieSeries interaction requires a stable category key");
238
+ }, [categoryKey, data]);
239
+ const interactionKey = interactionBinding ? resolveInteractionKey : undefined;
240
+ const { config, paints } = useChart();
241
+ const children = useMemo(() => categoryKey === undefined
242
+ ? originalChildren
243
+ : categoryCells(data, categoryKey, config, paints, originalChildren, props.fill), [categoryKey, data, config, paints, originalChildren, props.fill]);
244
+ const identities = useRef(new WeakMap());
245
+ const boundChildren = useMemo(() => interactionKey && interaction.interactive && interaction.markActivation
246
+ ? captureCellIdentity(children, interactionKey, identities.current)
247
+ : children, [children, interactionKey, interaction.interactive, interaction.markActivation]);
248
+ const latestClick = useRef({ handler: props.onClick, interactionKey, interaction });
249
+ useLayoutEffect(() => {
250
+ latestClick.current = { handler: props.onClick, interactionKey, interaction };
251
+ });
252
+ const activate = useCallback((...args) => {
253
+ // Capture the pressed row before a consumer can synchronously reorder/filter the data.
254
+ const pressed = latestClick.current;
255
+ const key = identities.current.get(args[2].nativeEvent) ?? pressed.interactionKey?.(args[1]);
256
+ pressed.handler?.(...args);
257
+ if (key !== undefined)
258
+ latestClick.current.interaction.activate({ kind: "category", key }, "mark", args[2]);
259
+ }, []);
260
+ const onClick = interactionBinding && interaction.interactive && interaction.markActivation
261
+ ? activate
262
+ : props.onClick;
263
+ if (glowCategories !== undefined && categoryKey === undefined)
264
+ throw new Error("glowCategories requires categoryKey and explicit series data");
265
+ // Native sector indices align with explicit data, but membership uses the original
266
+ // row identity, before native Cell props can override payload fields.
267
+ const glowRows = useMemo(() => {
268
+ if (categoryKey === undefined || glowCategories === undefined)
269
+ return undefined;
270
+ const glowing = new Set(glowCategories);
271
+ return data?.map((row) => {
272
+ const key = typeof categoryKey === "function"
273
+ ? categoryKey(row)
274
+ : row !== null && typeof row === "object" && Object.hasOwn(row, categoryKey)
275
+ ? row[categoryKey]
276
+ : undefined;
277
+ return typeof key === "string" && glowing.has(key);
278
+ });
279
+ }, [data, categoryKey, glowCategories]);
166
280
  const seriesId = useId();
167
281
  const { invalidate, emphasisScope } = useLineInteraction();
168
282
  const scope = `${emphasisScope}/${seriesId}`;
169
- const sectorShape = useCallback((sector) => (_jsx(EntranceSector, { ...sector, material: material, scope: scope, emphasisKey: emphasisKey, enabled: props.activeShape === undefined && props.inactiveShape === undefined, seriesStartAngle: props.startAngle ?? 0, seriesEndAngle: props.endAngle ?? 360 })), [
283
+ const sectorShape = useCallback((sector) => (_jsx(EntranceSector, { ...sector, material: sector.index !== undefined && glowRows?.[sector.index] ? "glow" : material, interactionKey: interactionKey, scope: scope, emphasisKey: emphasisKey, enabled: props.activeShape === undefined && props.inactiveShape === undefined, seriesStartAngle: props.startAngle ?? 0, seriesEndAngle: props.endAngle ?? 360 })), [
170
284
  material,
285
+ glowRows,
171
286
  scope,
172
287
  emphasisKey,
288
+ interactionKey,
173
289
  props.activeShape,
174
290
  props.inactiveShape,
175
291
  props.startAngle,
@@ -193,6 +309,8 @@ export function PieSeries(props) {
193
309
  props.activeShape,
194
310
  props.inactiveShape,
195
311
  material,
312
+ categoryKey,
313
+ glowCategories,
196
314
  ];
197
315
  const cells = cellProps(props.children);
198
316
  const previousCells = useRef(cells);
@@ -204,5 +322,10 @@ export function PieSeries(props) {
204
322
  previousCells.current = cells;
205
323
  previous.current = inputs;
206
324
  });
207
- return (_jsx(Pie, { ...nativeProps, stroke: props.stroke ?? "none", shape: props.shape ?? sectorShape, isAnimationActive: false, children: children }));
325
+ return (_jsx(StablePie, { ...nativeProps, ...(data !== undefined ? { data } : {}), ...(onClick !== undefined ? { onClick } : {}), stroke: props.stroke ?? "none", shape: props.shape ?? sectorShape, ...(interactionBinding && props.shape === undefined && props.activeShape === undefined
326
+ ? { activeShape: sectorShape }
327
+ : {}), ...(interactionBinding && props.shape === undefined && props.inactiveShape === undefined
328
+ ? { inactiveShape: sectorShape }
329
+ : {}), isAnimationActive: false, children: boundChildren }));
208
330
  }
331
+ registerPiePinComponent(PieSeries, "series");
@@ -0,0 +1,4 @@
1
+ import { type ReactNode } from "react";
2
+ export declare const PieTooltipPin: import("react").Context<number | undefined>;
3
+ /** Resolve against current rows; the returned index is never retained as identity. */
4
+ export declare function pinnedPieIndex(children: ReactNode, category: string, visibleSeries?: readonly string[]): number | undefined;
@@ -0,0 +1,52 @@
1
+ "use client";
2
+ import { Children, createContext, Fragment, isValidElement } from "react";
3
+ import { piePinComponentKind } from "./pie-pin-identity.js";
4
+ export const PieTooltipPin = createContext(undefined);
5
+ /** Resolve against current rows; the returned index is never retained as identity. */
6
+ export function pinnedPieIndex(children, category, visibleSeries) {
7
+ const series = [];
8
+ let tooltips = 0;
9
+ let unsupported = false;
10
+ function collect(nodes) {
11
+ Children.forEach(nodes, (child) => {
12
+ if (!isValidElement(child)) {
13
+ if (child !== null && child !== undefined && typeof child !== "boolean")
14
+ unsupported = true;
15
+ return;
16
+ }
17
+ if (child.type === Fragment)
18
+ collect(child.props.children);
19
+ else if (piePinComponentKind(child.type) === "series")
20
+ series.push(child.props);
21
+ else if (piePinComponentKind(child.type) === "tooltip")
22
+ tooltips += 1;
23
+ else
24
+ unsupported = true;
25
+ });
26
+ }
27
+ collect(children);
28
+ const candidate = series[0];
29
+ if (series.length !== 1 ||
30
+ tooltips !== 1 ||
31
+ unsupported ||
32
+ !candidate?.data ||
33
+ candidate.categoryKey === undefined)
34
+ throw new Error("defaultPinnedCategory requires one direct PieSeries with explicit data and categoryKey, and one direct Tooltip");
35
+ const { data, categoryKey, hide } = candidate;
36
+ if (hide)
37
+ return undefined;
38
+ const keys = data.map((row) => typeof categoryKey === "function"
39
+ ? categoryKey(row)
40
+ : row !== null && typeof row === "object" && Object.hasOwn(row, categoryKey)
41
+ ? row[categoryKey]
42
+ : undefined);
43
+ // Ambiguous identities are never silently resolved by position, including hidden rows.
44
+ if (keys.filter((key) => key === category).length !== 1)
45
+ return undefined;
46
+ // Only a bound Pie filters its native data. Unbound composition keeps its original indices.
47
+ const renderedKeys = candidate.interactionBinding === "root" && visibleSeries !== undefined
48
+ ? keys.filter((key) => typeof key === "string" && visibleSeries.includes(key))
49
+ : keys;
50
+ const index = renderedKeys.indexOf(category);
51
+ return index < 0 ? undefined : index;
52
+ }
@@ -0,0 +1,19 @@
1
+ import { type DotProps } from "recharts";
2
+ export type PointStyle = "default" | "border" | "colored-border";
3
+ export type PointMarkerProps = DotProps & {
4
+ variant?: PointStyle | undefined;
5
+ };
6
+ /** Paint only: native coordinates, radius, events and inspection remain owned by Recharts. */
7
+ export declare function markerPaint(variant: PointStyle, color: string | undefined): {
8
+ fill?: never;
9
+ stroke?: never;
10
+ strokeWidth?: never;
11
+ strokeDasharray?: never;
12
+ } | {
13
+ fill: string | undefined;
14
+ stroke: string | undefined;
15
+ strokeWidth: number;
16
+ strokeDasharray: string;
17
+ };
18
+ /** Native Dot renderer: variant paint wins engine paint; SVG style remains consumer-owned. */
19
+ export declare function PointMarker({ variant, ...props }: PointMarkerProps): import("react").JSX.Element;
@@ -0,0 +1,19 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { Dot } from "recharts";
4
+ /** Paint only: native coordinates, radius, events and inspection remain owned by Recharts. */
5
+ export function markerPaint(variant, color) {
6
+ if (variant === "default")
7
+ return {};
8
+ const surface = "var(--kind-ui-chart-marker-surface, var(--card, white))";
9
+ return {
10
+ fill: variant === "border" ? color : surface,
11
+ stroke: variant === "border" ? surface : color,
12
+ strokeWidth: 2,
13
+ strokeDasharray: "none",
14
+ };
15
+ }
16
+ /** Native Dot renderer: variant paint wins engine paint; SVG style remains consumer-owned. */
17
+ export function PointMarker({ variant = "default", ...props }) {
18
+ return (_jsx(Dot, { ...props, ...markerPaint(variant, props.stroke ?? props.fill), "data-kind-ui": "point-marker", "data-point-style": variant }));
19
+ }
@@ -1,17 +1,22 @@
1
1
  import { type ComponentProps } from "react";
2
2
  import { RadarChart as EngineRadarChart, RadialBarChart as EngineRadialBarChart } from "recharts";
3
- import { type LineAnimation } from "./animation.js";
3
+ import { type BaseAnimation } from "./animation.js";
4
4
  import type { CategoryKey } from "./category-cells.js";
5
5
  import { type RadarSelectionProps } from "./radar-interaction.js";
6
- export type RadarAnimation = LineAnimation;
7
- export type RadialBarAnimation = LineAnimation;
6
+ export type RadarAnimation = BaseAnimation;
7
+ export type RadialBarAnimation = BaseAnimation;
8
8
  export type RadarChartProps<DataPoint = unknown> = ComponentProps<typeof EngineRadarChart<DataPoint>> & RadarSelectionProps & {
9
9
  animate?: boolean | RadarAnimation | undefined;
10
+ loading?: boolean | undefined;
11
+ loadingLabel?: string | undefined;
10
12
  };
11
13
  export type RadialBarChartProps<DataPoint = unknown> = ComponentProps<typeof EngineRadialBarChart<DataPoint>> & {
12
14
  /** Opt-in category colors from Root.config, resolved from original chart rows. */
13
15
  categoryKey?: CategoryKey<DataPoint> | undefined;
16
+ interactionBinding?: "root";
14
17
  animate?: boolean | RadialBarAnimation | undefined;
18
+ loading?: boolean | undefined;
19
+ loadingLabel?: string | undefined;
15
20
  /** Entrance direction only; native chart and axis angles stay consumer-owned. */
16
21
  animationDirection?: "clockwise" | "anticlockwise" | undefined;
17
22
  };
@@ -29,5 +34,9 @@ export declare const RadialMotion: import("react").Context<{
29
34
  direction: "clockwise" | "anticlockwise";
30
35
  }>;
31
36
  /** Native polar composition with shared metadata, interaction and optional Motion. */
32
- export declare function RadarChart<DataPoint = unknown>({ animate, selection, selectedSeries, onSelectedSeriesChange, children, ...props }: RadarChartProps<DataPoint>): import("react").JSX.Element;
33
- export declare function RadialBarChart<DataPoint = unknown>({ animate, animationDirection, categoryKey, children, ...props }: RadialBarChartProps<DataPoint>): import("react").JSX.Element;
37
+ export declare function RadarChart<DataPoint = unknown>({ animate, loading, loadingLabel, selection, selectedSeries, onSelectedSeriesChange, children, ...props }: RadarChartProps<DataPoint>): import("react").JSX.Element;
38
+ export declare function RadialBarChart<DataPoint = unknown>(props: RadialBarChartProps<DataPoint>): import("react").JSX.Element;
39
+ /** Private recipe integration; the public chart keeps its native prop contract. */
40
+ export declare function RadialBarChartFrame<DataPoint = unknown>({ skeletonFamily, animate, loading, loadingLabel, animationDirection, categoryKey, interactionBinding, children, ...props }: RadialBarChartProps<DataPoint> & {
41
+ skeletonFamily?: "radial-bar" | "activity-rings";
42
+ }): import("react").JSX.Element;
@@ -4,7 +4,10 @@ import { animate as animateValue } from "motion/react";
4
4
  import { createContext, useCallback, useLayoutEffect, useRef, useState, useSyncExternalStore, } from "react";
5
5
  import { RadarChart as EngineRadarChart, RadialBarChart as EngineRadialBarChart } from "recharts";
6
6
  import { MotionContext } from "./animation.js";
7
+ import { filterCategoryRows } from "./category-cells.js";
8
+ import { useChartInteraction } from "./chart-interaction.js";
7
9
  import { LineChartFrame, useLineInteraction } from "./line-chart.js";
10
+ import { PolarLoadingDesign } from "./loading-polar-designs.js";
8
11
  import { RadarSelectionProvider } from "./radar-interaction.js";
9
12
  import { RadialCategory } from "./radial-category.js";
10
13
  export const PolarMotion = createContext({
@@ -26,11 +29,18 @@ function subscribe(change) {
26
29
  const snapshot = () => window.matchMedia(query).matches;
27
30
  const serverSnapshot = () => true;
28
31
  const defaultHover = { type: "spring", stiffness: 210, damping: 28, mass: 0.8 };
29
- function usePolarMotion(animate) {
32
+ function usePolarMotion(animate, loading) {
30
33
  const reduced = useSyncExternalStore(subscribe, snapshot, serverSnapshot);
31
34
  const [finished, setFinished] = useState(false);
32
- const interrupt = useCallback(() => setFinished(true), []);
33
- const enabled = animate !== false && !reduced;
35
+ const interrupt = useCallback(() => {
36
+ if (!loading)
37
+ setFinished(true);
38
+ }, [loading]);
39
+ useLayoutEffect(() => {
40
+ if (loading)
41
+ setFinished(false);
42
+ }, [loading]);
43
+ const enabled = animate !== false && !reduced && !loading;
34
44
  const options = typeof animate === "object" ? animate : {};
35
45
  return { enabled, options, reveal: enabled && !finished, interrupt };
36
46
  }
@@ -62,12 +72,16 @@ function PolarLifecycle({ layout, cx, cy, innerRadius, outerRadius, startAngle,
62
72
  return null;
63
73
  }
64
74
  /** Native polar composition with shared metadata, interaction and optional Motion. */
65
- export function RadarChart({ animate = false, selection, selectedSeries, onSelectedSeriesChange, children, ...props }) {
66
- const { enabled, options, reveal, interrupt } = usePolarMotion(animate);
75
+ export function RadarChart({ animate = false, loading, loadingLabel, selection, selectedSeries, onSelectedSeriesChange, children, ...props }) {
76
+ const { enabled, options, reveal, interrupt } = usePolarMotion(animate, loading);
67
77
  const [progress, setProgress] = useState(1);
68
78
  const duration = options.revealDurationMs ?? 1000;
69
79
  const easing = options.revealEasing ?? "easeOut";
70
80
  const started = useRef(false);
81
+ useLayoutEffect(() => {
82
+ if (loading)
83
+ started.current = false;
84
+ }, [loading]);
71
85
  const previous = useRef([duration, easing]);
72
86
  const previousEnabled = useRef(enabled);
73
87
  useLayoutEffect(() => {
@@ -93,15 +107,28 @@ export function RadarChart({ animate = false, selection, selectedSeries, onSelec
93
107
  });
94
108
  return () => controls.stop();
95
109
  }, [reveal, duration, easing, interrupt]);
96
- return (_jsx(MotionContext, { value: { enabled, transition: options.hoverTransition ?? defaultHover }, children: _jsx(RadarMotion, { value: { reveal, progress }, children: _jsx(PolarMotion, { value: { reveal, options }, children: _jsx(RadarSelectionProvider, { selection: selection, selectedSeries: selectedSeries, onSelectedSeriesChange: onSelectedSeriesChange, children: _jsxs(LineChartFrame, { engine: (EngineRadarChart), chartProps: props, motionEnabled: enabled, interrupt: interrupt, children: [_jsx(PolarLifecycle, { ...props, children: children }), children] }) }) }) }) }));
110
+ return (_jsx(MotionContext, { value: { enabled, transition: options.hoverTransition ?? defaultHover }, children: _jsx(RadarMotion, { value: { reveal, progress }, children: _jsx(PolarMotion, { value: { reveal, options }, children: _jsx(RadarSelectionProvider, { selection: selection, selectedSeries: selectedSeries, onSelectedSeriesChange: onSelectedSeriesChange, children: _jsxs(LineChartFrame, { engine: (EngineRadarChart), loading: loading, loadingLabel: loadingLabel, loadingSkeleton: "radar", loadingDesign: (seed) => _jsx(PolarLoadingDesign, { family: "radar", seed: seed }), loadingAnimation: options, chartProps: props, motionEnabled: enabled, interrupt: interrupt, children: [_jsx(PolarLifecycle, { ...props, children: children }), children] }) }) }) }) }));
97
111
  }
98
- export function RadialBarChart({ animate = false, animationDirection = "clockwise", categoryKey, children, ...props }) {
112
+ export function RadialBarChart(props) {
113
+ return _jsx(RadialBarChartFrame, { ...props });
114
+ }
115
+ /** Private recipe integration; the public chart keeps its native prop contract. */
116
+ export function RadialBarChartFrame({ skeletonFamily = "radial-bar", animate = false, loading, loadingLabel, animationDirection = "clockwise", categoryKey, interactionBinding, children, ...props }) {
117
+ const interaction = useChartInteraction();
118
+ if (interactionBinding &&
119
+ (interaction.kind !== "category" || categoryKey === undefined || props.data === undefined))
120
+ throw new Error("RadialBarChart Root interaction binding requires category-kind Root, categoryKey and explicit data");
121
+ const filtered = interactionBinding && categoryKey !== undefined && props.data
122
+ ? filterCategoryRows(props.data, categoryKey, interaction.visible, null)
123
+ : undefined;
99
124
  if (categoryKey !== undefined && props.data === undefined)
100
125
  throw new Error("RadialBarChart categoryKey requires explicit chart data");
101
126
  const categories = categoryKey === undefined
102
127
  ? null
103
128
  : {
104
- data: props.data ?? [],
129
+ data: filtered?.data ?? props.data ?? [],
130
+ originalData: props.data ?? [],
131
+ bound: interactionBinding === "root",
105
132
  key: (row) => {
106
133
  if (typeof categoryKey === "function")
107
134
  return categoryKey(row);
@@ -110,11 +137,15 @@ export function RadialBarChart({ animate = false, animationDirection = "clockwis
110
137
  : "";
111
138
  },
112
139
  };
113
- const { enabled, options, reveal, interrupt } = usePolarMotion(animate);
140
+ const { enabled, options, reveal, interrupt } = usePolarMotion(animate, loading);
114
141
  const [progress, setProgress] = useState(1);
115
142
  const duration = options.revealDurationMs ?? 1000;
116
143
  const easing = options.revealEasing ?? "easeOut";
117
144
  const started = useRef(false);
145
+ useLayoutEffect(() => {
146
+ if (loading)
147
+ started.current = false;
148
+ }, [loading]);
118
149
  const previous = useRef([duration, easing, animationDirection]);
119
150
  const previousEnabled = useRef(enabled);
120
151
  useLayoutEffect(() => {
@@ -141,5 +172,5 @@ export function RadialBarChart({ animate = false, animationDirection = "clockwis
141
172
  });
142
173
  return () => controls.stop();
143
174
  }, [reveal, duration, easing, interrupt]);
144
- return (_jsx(RadialCategory, { value: categories, children: _jsx(MotionContext, { value: { enabled, transition: options.hoverTransition ?? defaultHover }, children: _jsx(RadialMotion, { value: { reveal, progress, direction: animationDirection }, children: _jsx(PolarMotion, { value: { reveal, options }, children: _jsxs(LineChartFrame, { engine: (EngineRadialBarChart), chartProps: props, motionEnabled: enabled, interrupt: interrupt, children: [_jsx(PolarLifecycle, { ...props, children: children }), children] }) }) }) }) }));
175
+ return (_jsx(RadialCategory, { value: categories, children: _jsx(MotionContext, { value: { enabled, transition: options.hoverTransition ?? defaultHover }, children: _jsx(RadialMotion, { value: { reveal, progress, direction: animationDirection }, children: _jsx(PolarMotion, { value: { reveal, options }, children: _jsxs(LineChartFrame, { engine: (EngineRadialBarChart), loading: loading, loadingLabel: loadingLabel, loadingSkeleton: skeletonFamily, loadingDesign: (seed) => _jsx(PolarLoadingDesign, { family: skeletonFamily, seed: seed }), loadingAnimation: { ...options, direction: animationDirection }, chartProps: { ...props, ...(filtered ? { data: filtered.data } : {}) }, motionEnabled: enabled, interrupt: interrupt, children: [_jsx(PolarLifecycle, { ...props, children: children }), children] }) }) }) }) }));
145
176
  }
@@ -5,5 +5,5 @@ import { useChartHeight, useChartWidth } from "recharts";
5
5
  export function PolarMaterialFilter({ material, id, }) {
6
6
  const width = useChartWidth();
7
7
  const height = useChartHeight();
8
- return (_jsx("defs", { "data-kind-ui": "polar-material", "data-material": material, pointerEvents: "none", children: _jsxs("filter", { id: id, filterUnits: "userSpaceOnUse", x: -16, y: -16, width: (width ?? 0) + 32, height: (height ?? 0) + 32, colorInterpolationFilters: "sRGB", children: [_jsx("feComponentTransfer", { in: "SourceAlpha", result: "footprint", children: _jsx("feFuncA", { type: "linear", slope: 100000 }) }), material === "paper" ? (_jsxs(_Fragment, { children: [_jsx("feTurbulence", { type: "fractalNoise", baseFrequency: "0.65 0.3", numOctaves: 1, seed: 7, result: "fiber" }), _jsx("feFlood", { floodColor: "var(--kind-ui-polar-paper-fiber, #fff)", floodOpacity: "var(--kind-ui-polar-paper-grain, 0.14)" }), _jsx("feComposite", { in2: "fiber", operator: "in", result: "texture" }), _jsx("feComposite", { in: "texture", in2: "SourceGraphic", operator: "atop", result: "paper" }), _jsx("feMorphology", { in: "footprint", operator: "erode", radius: 1.2, result: "inside" }), _jsx("feComposite", { in: "footprint", in2: "inside", operator: "arithmetic", k2: 1, k3: -1, result: "edge" }), _jsx("feTurbulence", { type: "fractalNoise", baseFrequency: "0.08 0.2", numOctaves: 1, seed: 11, result: "pencil" }), _jsx("feColorMatrix", { in: "pencil", type: "luminanceToAlpha", result: "pencilMask" }), _jsx("feComponentTransfer", { in: "pencilMask", result: "sketch", children: _jsx("feFuncA", { type: "linear", slope: 1.6, intercept: -0.15 }) }), _jsx("feComposite", { in: "edge", in2: "sketch", operator: "in", result: "sketchEdge" }), _jsx("feColorMatrix", { in: "SourceGraphic", type: "matrix", values: "0.35 0 0 0 0 0 0.35 0 0 0 0 0 0.35 0 0 0 0 0 1 0", result: "ink" }), _jsx("feComposite", { in: "ink", in2: "sketchEdge", operator: "in", result: "contour" }), _jsx("feComposite", { in: "contour", in2: "paper", operator: "atop" })] })) : material === "clay" ? (_jsxs(_Fragment, { children: [_jsx("feOffset", { in: "footprint", dx: 4, dy: 4, result: "lower" }), _jsx("feComposite", { in: "footprint", in2: "lower", operator: "arithmetic", k2: 1, k3: -1, result: "top" }), _jsx("feGaussianBlur", { in: "top", stdDeviation: 3, result: "softTop" }), _jsx("feFlood", { floodColor: "var(--kind-ui-polar-clay-light, #fff)", floodOpacity: "var(--kind-ui-polar-clay-highlight, 0.55)" }), _jsx("feComposite", { in2: "softTop", operator: "in", result: "light" }), _jsx("feOffset", { in: "footprint", dx: -4, dy: -4, result: "upper" }), _jsx("feComposite", { in: "footprint", in2: "upper", operator: "arithmetic", k2: 1, k3: -1, result: "bottom" }), _jsx("feGaussianBlur", { in: "bottom", stdDeviation: 3, result: "softBottom" }), _jsx("feFlood", { floodColor: "var(--kind-ui-polar-clay-shade, #17212b)", floodOpacity: "var(--kind-ui-polar-clay-shadow, 0.32)" }), _jsx("feComposite", { in2: "softBottom", operator: "in", result: "shade" }), _jsx("feComposite", { in: "shade", in2: "SourceGraphic", operator: "atop", result: "shaded" }), _jsx("feComposite", { in: "light", in2: "shaded", operator: "atop", result: "body" }), _jsx("feTurbulence", { type: "fractalNoise", baseFrequency: 0.7, numOctaves: 1, seed: 17, result: "grain" }), _jsx("feFlood", { floodColor: "var(--kind-ui-polar-clay-light, #fff)", floodOpacity: 0.025 }), _jsx("feComposite", { in2: "grain", operator: "in", result: "texture" }), _jsx("feComposite", { in: "texture", in2: "body", operator: "atop" })] })) : (_jsxs(_Fragment, { children: [_jsx("feColorMatrix", { in: "SourceGraphic", type: "matrix", values: "0.6 0 0 0 0.4 0 0.6 0 0 0.4 0 0 0.6 0 0.4 0 0 0 1 0", result: "luminousPaint" }), _jsx("feGaussianBlur", { in: "luminousPaint", stdDeviation: 3, result: "halo" }), _jsx("feFlood", { floodOpacity: "var(--kind-ui-polar-glow-opacity, 0.65)", result: "strength" }), _jsx("feComposite", { in: "halo", in2: "strength", operator: "in", result: "softHalo" }), _jsx("feMorphology", { in: "footprint", operator: "dilate", radius: 1, result: "haloGuard" }), _jsx("feComposite", { in: "softHalo", in2: "haloGuard", operator: "out", result: "exterior" }), _jsx("feMorphology", { in: "footprint", operator: "erode", radius: 2.2, result: "inside" }), _jsx("feComposite", { in: "footprint", in2: "inside", operator: "arithmetic", k2: 1, k3: -1, result: "edge" }), _jsx("feFlood", { floodColor: "var(--kind-ui-polar-glow-light, #fff)", floodOpacity: 0.8 }), _jsx("feComposite", { in2: "edge", operator: "in", result: "light" }), _jsx("feComposite", { in: "light", in2: "SourceGraphic", operator: "atop", result: "body" }), _jsxs("feMerge", { children: [_jsx("feMergeNode", { in: "exterior" }), _jsx("feMergeNode", { in: "body" })] })] }))] }) }));
8
+ return (_jsx("defs", { "data-kind-ui": "polar-material", "data-material": material, pointerEvents: "none", children: _jsxs("filter", { id: id, filterUnits: "userSpaceOnUse", x: -16, y: -16, width: (width ?? 0) + 32, height: (height ?? 0) + 32, colorInterpolationFilters: "sRGB", children: [_jsx("feComponentTransfer", { in: "SourceAlpha", result: "footprint", children: _jsx("feFuncA", { type: "linear", slope: 100000 }) }), material === "clay" ? (_jsxs(_Fragment, { children: [_jsx("feOffset", { in: "footprint", dx: 4, dy: 4, result: "lower" }), _jsx("feComposite", { in: "footprint", in2: "lower", operator: "arithmetic", k2: 1, k3: -1, result: "top" }), _jsx("feGaussianBlur", { in: "top", stdDeviation: 3, result: "softTop" }), _jsx("feFlood", { floodColor: "var(--kind-ui-polar-clay-light, #fff)", floodOpacity: "var(--kind-ui-polar-clay-highlight, 0.55)" }), _jsx("feComposite", { in2: "softTop", operator: "in", result: "light" }), _jsx("feOffset", { in: "footprint", dx: -4, dy: -4, result: "upper" }), _jsx("feComposite", { in: "footprint", in2: "upper", operator: "arithmetic", k2: 1, k3: -1, result: "bottom" }), _jsx("feGaussianBlur", { in: "bottom", stdDeviation: 3, result: "softBottom" }), _jsx("feFlood", { floodColor: "var(--kind-ui-polar-clay-shade, #17212b)", floodOpacity: "var(--kind-ui-polar-clay-shadow, 0.32)" }), _jsx("feComposite", { in2: "softBottom", operator: "in", result: "shade" }), _jsx("feComposite", { in: "shade", in2: "SourceGraphic", operator: "atop", result: "shaded" }), _jsx("feComposite", { in: "light", in2: "shaded", operator: "atop", result: "body" }), _jsx("feTurbulence", { type: "fractalNoise", baseFrequency: 0.7, numOctaves: 1, seed: 17, result: "grain" }), _jsx("feFlood", { floodColor: "var(--kind-ui-polar-clay-light, #fff)", floodOpacity: 0.025 }), _jsx("feComposite", { in2: "grain", operator: "in", result: "texture" }), _jsx("feComposite", { in: "texture", in2: "body", operator: "atop" })] })) : (_jsxs(_Fragment, { children: [_jsx("feColorMatrix", { in: "SourceGraphic", type: "matrix", values: "0.6 0 0 0 0.4 0 0.6 0 0 0.4 0 0 0.6 0 0.4 0 0 0 1 0", result: "luminousPaint" }), _jsx("feGaussianBlur", { in: "luminousPaint", stdDeviation: 3, result: "halo" }), _jsx("feFlood", { floodOpacity: "var(--kind-ui-polar-glow-opacity, 0.65)", result: "strength" }), _jsx("feComposite", { in: "halo", in2: "strength", operator: "in", result: "softHalo" }), _jsx("feMorphology", { in: "footprint", operator: "dilate", radius: 1, result: "haloGuard" }), _jsx("feComposite", { in: "softHalo", in2: "haloGuard", operator: "out", result: "exterior" }), _jsx("feMorphology", { in: "footprint", operator: "erode", radius: 2.2, result: "inside" }), _jsx("feComposite", { in: "footprint", in2: "inside", operator: "arithmetic", k2: 1, k3: -1, result: "edge" }), _jsx("feFlood", { floodColor: "var(--kind-ui-polar-glow-light, #fff)", floodOpacity: 0.8 }), _jsx("feComposite", { in2: "edge", operator: "in", result: "light" }), _jsx("feComposite", { in: "light", in2: "SourceGraphic", operator: "atop", result: "body" }), _jsxs("feMerge", { children: [_jsx("feMergeNode", { in: "exterior" }), _jsx("feMergeNode", { in: "body" })] })] }))] }) }));
9
9
  }