@kind-ui/charts 0.1.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 (121) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/LICENSE +21 -0
  3. package/README.md +966 -0
  4. package/dist/activity-rings.d.ts +47 -0
  5. package/dist/activity-rings.js +55 -0
  6. package/dist/animation.d.ts +27 -0
  7. package/dist/animation.js +102 -0
  8. package/dist/area-chart.d.ts +9 -0
  9. package/dist/area-chart.js +33 -0
  10. package/dist/area-clay.d.ts +2 -0
  11. package/dist/area-clay.js +6 -0
  12. package/dist/area-material.d.ts +8 -0
  13. package/dist/area-material.js +66 -0
  14. package/dist/area-series.d.ts +11 -0
  15. package/dist/area-series.js +34 -0
  16. package/dist/bar-category.d.ts +5 -0
  17. package/dist/bar-category.js +35 -0
  18. package/dist/bar-chart.d.ts +17 -0
  19. package/dist/bar-chart.js +42 -0
  20. package/dist/bar-clay.d.ts +4 -0
  21. package/dist/bar-clay.js +6 -0
  22. package/dist/bar-material.d.ts +8 -0
  23. package/dist/bar-material.js +19 -0
  24. package/dist/bar-paper.d.ts +2 -0
  25. package/dist/bar-paper.js +6 -0
  26. package/dist/bar-series.d.ts +13 -0
  27. package/dist/bar-series.js +178 -0
  28. package/dist/box-material.d.ts +14 -0
  29. package/dist/box-material.js +30 -0
  30. package/dist/box-plot.d.ts +50 -0
  31. package/dist/box-plot.js +218 -0
  32. package/dist/category-cells.d.ts +6 -0
  33. package/dist/category-cells.js +41 -0
  34. package/dist/chart-context.d.ts +11 -0
  35. package/dist/chart-context.js +9 -0
  36. package/dist/combo-chart.d.ts +16 -0
  37. package/dist/combo-chart.js +64 -0
  38. package/dist/configured-line-chart.d.ts +79 -0
  39. package/dist/configured-line-chart.js +77 -0
  40. package/dist/emphasis.d.ts +44 -0
  41. package/dist/emphasis.js +128 -0
  42. package/dist/heatmap-model.d.ts +38 -0
  43. package/dist/heatmap-model.js +73 -0
  44. package/dist/heatmap.d.ts +56 -0
  45. package/dist/heatmap.js +366 -0
  46. package/dist/histogram-chart.d.ts +14 -0
  47. package/dist/histogram-chart.js +27 -0
  48. package/dist/histogram-data.d.ts +17 -0
  49. package/dist/histogram-data.js +66 -0
  50. package/dist/histogram-material.d.ts +13 -0
  51. package/dist/histogram-material.js +8 -0
  52. package/dist/histogram-series.d.ts +16 -0
  53. package/dist/histogram-series.js +67 -0
  54. package/dist/index.d.ts +45 -0
  55. package/dist/index.js +36 -0
  56. package/dist/legend.d.ts +16 -0
  57. package/dist/legend.js +30 -0
  58. package/dist/line-chart.d.ts +41 -0
  59. package/dist/line-chart.js +160 -0
  60. package/dist/line-material.d.ts +9 -0
  61. package/dist/line-material.js +24 -0
  62. package/dist/line-series.d.ts +15 -0
  63. package/dist/line-series.js +40 -0
  64. package/dist/pie-chart.d.ts +17 -0
  65. package/dist/pie-chart.js +68 -0
  66. package/dist/pie-material.d.ts +19 -0
  67. package/dist/pie-material.js +16 -0
  68. package/dist/pie-series.d.ts +14 -0
  69. package/dist/pie-series.js +208 -0
  70. package/dist/polar-chart.d.ts +33 -0
  71. package/dist/polar-chart.js +145 -0
  72. package/dist/polar-material.d.ts +7 -0
  73. package/dist/polar-material.js +9 -0
  74. package/dist/polar-series.d.ts +17 -0
  75. package/dist/polar-series.js +169 -0
  76. package/dist/radar-interaction.d.ts +29 -0
  77. package/dist/radar-interaction.js +138 -0
  78. package/dist/radial-bar-label.d.ts +15 -0
  79. package/dist/radial-bar-label.js +136 -0
  80. package/dist/radial-category.d.ts +4 -0
  81. package/dist/radial-category.js +4 -0
  82. package/dist/root.d.ts +14 -0
  83. package/dist/root.js +29 -0
  84. package/dist/sankey-chart.d.ts +33 -0
  85. package/dist/sankey-chart.js +142 -0
  86. package/dist/sankey-colors.d.ts +10 -0
  87. package/dist/sankey-colors.js +6 -0
  88. package/dist/sankey-data.d.ts +30 -0
  89. package/dist/sankey-data.js +65 -0
  90. package/dist/sankey-finish.d.ts +13 -0
  91. package/dist/sankey-finish.js +10 -0
  92. package/dist/sankey-legend.d.ts +14 -0
  93. package/dist/sankey-legend.js +9 -0
  94. package/dist/sankey-marks.d.ts +31 -0
  95. package/dist/sankey-marks.js +67 -0
  96. package/dist/sankey-table.d.ts +11 -0
  97. package/dist/sankey-table.js +8 -0
  98. package/dist/scatter-chart.d.ts +16 -0
  99. package/dist/scatter-chart.js +64 -0
  100. package/dist/scatter-material.d.ts +8 -0
  101. package/dist/scatter-material.js +39 -0
  102. package/dist/scatter-series.d.ts +11 -0
  103. package/dist/scatter-series.js +74 -0
  104. package/dist/scatter-tooltip.d.ts +24 -0
  105. package/dist/scatter-tooltip.js +96 -0
  106. package/dist/styles.css +443 -0
  107. package/dist/surface-material.d.ts +13 -0
  108. package/dist/surface-material.js +7 -0
  109. package/dist/tooltip-content.d.ts +19 -0
  110. package/dist/tooltip-content.js +60 -0
  111. package/dist/tooltip-number.d.ts +4 -0
  112. package/dist/tooltip-number.js +68 -0
  113. package/dist/tooltip.d.ts +29 -0
  114. package/dist/tooltip.js +73 -0
  115. package/dist/types.d.ts +11 -0
  116. package/dist/types.js +1 -0
  117. package/dist/waterfall-data.d.ts +24 -0
  118. package/dist/waterfall-data.js +45 -0
  119. package/dist/waterfall-series.d.ts +15 -0
  120. package/dist/waterfall-series.js +35 -0
  121. package/package.json +49 -0
@@ -0,0 +1,73 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { cloneElement, createElement, isValidElement, useCallback, useLayoutEffect, useState, } from "react";
4
+ import { Tooltip as EngineTooltip, useChartHeight, useChartWidth, } from "recharts";
5
+ import { useChart } from "./chart-context.js";
6
+ import { useLineInteraction } from "./line-chart.js";
7
+ import { TooltipContent } from "./tooltip-content.js";
8
+ export function StaticTooltipFrame({ x, y, ref, style, frameProps, children }) {
9
+ return (_jsx("div", { ...frameProps, "data-kind-ui": "tooltip-frame", ref: ref, style: { ...style, ...frameProps?.style, transform: `translate(${x}px, ${y}px)` }, children: children }));
10
+ }
11
+ function PositionedContent({ consumerContent, itemKey, valueAnimation, maxWidth, frameProps, frameRef, Frame, ...tooltip }) {
12
+ const { pointer, seriesKeys } = useLineInteraction();
13
+ const { visibleSeries } = useChart();
14
+ // Exiting strokes can remain painted briefly; hidden series leave all tooltip content immediately.
15
+ const payload = visibleSeries === undefined
16
+ ? tooltip.payload
17
+ : tooltip.payload.filter((entry) => {
18
+ const key = itemKey?.(entry) ??
19
+ (entry.graphicalItemId ? seriesKeys.get(entry.graphicalItemId) : undefined) ??
20
+ String(entry.dataKey ?? entry.name);
21
+ return visibleSeries.includes(key);
22
+ });
23
+ const contentProps = { ...tooltip, payload };
24
+ const width = useChartWidth() ?? 0;
25
+ const height = useChartHeight() ?? 0;
26
+ const [node, setNode] = useState(null);
27
+ const attachRef = useCallback((element) => {
28
+ setNode(element);
29
+ if (typeof frameRef === "function")
30
+ return frameRef(element);
31
+ if (frameRef)
32
+ frameRef.current = element;
33
+ }, [frameRef]);
34
+ const [size, setSize] = useState({ width: 0, height: 0 });
35
+ useLayoutEffect(() => {
36
+ if (!node)
37
+ return;
38
+ const measure = (entry) => {
39
+ const box = entry?.borderBoxSize[0];
40
+ const next = {
41
+ width: box?.inlineSize ?? node.offsetWidth,
42
+ height: box?.blockSize ?? node.offsetHeight,
43
+ };
44
+ setSize((old) => (old.width === next.width && old.height === next.height ? old : next));
45
+ };
46
+ measure();
47
+ const observer = new ResizeObserver(([entry]) => measure(entry));
48
+ observer.observe(node);
49
+ return () => observer.disconnect();
50
+ }, [node]);
51
+ const anchor = pointer ?? tooltip.coordinate ?? { x: 0, y: 0 };
52
+ const offset = tooltip.offset ?? 12;
53
+ const offsetX = typeof offset === "number" ? offset : offset.x;
54
+ const offsetY = typeof offset === "number" ? offset : offset.y;
55
+ const maxX = Math.max(0, width - size.width);
56
+ const maxY = Math.max(0, height - size.height);
57
+ const children = isValidElement(consumerContent) ? (cloneElement(consumerContent, contentProps)) : typeof consumerContent === "function" ? (createElement(consumerContent, contentProps)) : (_jsx(TooltipContent, { tooltip: contentProps, ...(itemKey ? { itemKey } : {}), ...(valueAnimation ? { valueAnimation } : {}) }));
58
+ return (_jsx(Frame, { x: Math.max(0, Math.min(anchor.x + offsetX, maxX)), y: Math.max(0, Math.min(anchor.y + offsetY, maxY)), maxX: maxX, maxY: maxY, ref: attachRef, style: {
59
+ width: "max-content",
60
+ maxWidth: Math.min(Math.max(0, maxWidth), width),
61
+ maxHeight: height,
62
+ overflow: "auto",
63
+ boxSizing: "border-box",
64
+ }, frameProps: frameProps, children: children }));
65
+ }
66
+ export function TooltipBase({ ref, content, frameProps, maxWidth = 180, itemKey, valueAnimation, Frame = StaticTooltipFrame, ...props }) {
67
+ useLineInteraction();
68
+ return (_jsx(EngineTooltip, { cursor: false, offset: 12, filterNull: false, ...props, position: { x: 0, y: 0 }, isAnimationActive: false, content: _jsx(PositionedContent, { active: false, payload: [], coordinate: undefined, activeIndex: undefined, accessibilityLayer: false, consumerContent: content, itemKey: itemKey, valueAnimation: valueAnimation, maxWidth: maxWidth, frameProps: frameProps, frameRef: ref, Frame: Frame }) }));
69
+ }
70
+ /** Measured and bounded content; the engine owns payload, selection and Escape dismissal. */
71
+ export function Tooltip(props) {
72
+ return _jsx(TooltipBase, { ...props });
73
+ }
@@ -0,0 +1,11 @@
1
+ import type { ComponentProps, ComponentType, ReactNode } from "react";
2
+ import type { Symbols, TooltipValueType } from "recharts";
3
+ export type SeriesConfig = Readonly<Record<string, {
4
+ label: string;
5
+ color: string;
6
+ /** Decorative glyph shared by built-in legend and tooltip content. */
7
+ icon?: ComponentType;
8
+ /** Explicit legend-only native symbol; reuse this value for ScatterSeries.shape. */
9
+ legendShape?: NonNullable<ComponentProps<typeof Symbols>["type"]>;
10
+ formatValue?: (value: TooltipValueType) => ReactNode;
11
+ }>>;
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,24 @@
1
+ export type WaterfallEntry = {
2
+ id: string;
3
+ label: string;
4
+ } & ({
5
+ kind: "start" | "total" | "end" | "delta";
6
+ value: number | null;
7
+ } | {
8
+ kind: "subtotal";
9
+ value?: never;
10
+ });
11
+ export type WaterfallDatum = {
12
+ id: string;
13
+ label: string;
14
+ kind: WaterfallEntry["kind"];
15
+ /** Original delta/checkpoint value; the computed balance for a subtotal. */
16
+ value: number | null;
17
+ /** Directed numeric endpoints. Unknown geometry stays null. */
18
+ start: number | null;
19
+ end: number | null;
20
+ balance: number | null;
21
+ range: [number, number] | null;
22
+ };
23
+ /** Pure, ordered arithmetic. A missing change poisons the balance until a known checkpoint. */
24
+ export declare function computeWaterfallData(entries: readonly WaterfallEntry[], initialBalance?: number | null): WaterfallDatum[];
@@ -0,0 +1,45 @@
1
+ /** Pure, ordered arithmetic. A missing change poisons the balance until a known checkpoint. */
2
+ export function computeWaterfallData(entries, initialBalance = 0) {
3
+ const valid = (value) => value === null || (typeof value === "number" && Number.isFinite(value));
4
+ if (!valid(initialBalance))
5
+ throw new Error("Waterfall initialBalance must be finite or null");
6
+ let balance = initialBalance;
7
+ const ids = new Set();
8
+ return entries.map((entry) => {
9
+ if (!entry.id || ids.has(entry.id))
10
+ throw new Error("Waterfall requires unique nonempty ids");
11
+ ids.add(entry.id);
12
+ if (!["start", "total", "end", "delta", "subtotal"].includes(entry.kind))
13
+ throw new Error("Unknown Waterfall kind");
14
+ if (entry.kind === "subtotal" ? entry.value !== undefined : !valid(entry.value))
15
+ throw new Error("Waterfall values must be finite or null; subtotals have no supplied value");
16
+ let start;
17
+ let end;
18
+ if (entry.kind === "delta") {
19
+ start = balance;
20
+ end = balance === null || entry.value === null ? null : balance + entry.value;
21
+ if (end !== null && !Number.isFinite(end))
22
+ throw new Error("Waterfall balance overflow");
23
+ balance = end;
24
+ }
25
+ else if (entry.kind === "subtotal") {
26
+ start = balance === null ? null : 0;
27
+ end = balance;
28
+ }
29
+ else {
30
+ balance = entry.value;
31
+ start = balance === null ? null : 0;
32
+ end = balance;
33
+ }
34
+ return {
35
+ id: entry.id,
36
+ label: entry.label,
37
+ kind: entry.kind,
38
+ value: entry.kind === "subtotal" ? balance : entry.value,
39
+ start,
40
+ end,
41
+ balance,
42
+ range: start === null || end === null ? null : [Math.min(start, end), Math.max(start, end)],
43
+ };
44
+ });
45
+ }
@@ -0,0 +1,15 @@
1
+ import type { ComponentProps } from "react";
2
+ import { ReferenceLine } from "recharts";
3
+ import { type BarSeriesProps } from "./bar-series.js";
4
+ import type { WaterfallDatum } from "./waterfall-data.js";
5
+ export type WaterfallSeriesProps = Omit<BarSeriesProps, "dataKey" | "data" | "stackId" | "minPointSize">;
6
+ /** Native numeric range Bar. Children, shape, cells, labels, refs and events stay native. */
7
+ export declare function WaterfallSeries(props: WaterfallSeriesProps): import("react").JSX.Element;
8
+ export type WaterfallConnectorsProps = Omit<ComponentProps<typeof ReferenceLine>, "x" | "y" | "segment" | "children"> & {
9
+ data: readonly WaterfallDatum[];
10
+ /** Match the WaterfallSeries metadata key and native hide state. */
11
+ seriesKey?: string;
12
+ hide?: boolean;
13
+ };
14
+ /** Native axis-scaled connectors. Place before bars so the center endpoints sit underneath. */
15
+ export declare function WaterfallConnectors({ data, seriesKey, hide, ...props }: WaterfallConnectorsProps): import("react").JSX.Element | null;
@@ -0,0 +1,35 @@
1
+ "use client";
2
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { ReferenceLine, useChartLayout } from "recharts";
4
+ import { BarSeries } from "./bar-series.js";
5
+ import { useChart } from "./chart-context.js";
6
+ /** Native numeric range Bar. Children, shape, cells, labels, refs and events stay native. */
7
+ export function WaterfallSeries(props) {
8
+ for (const key of ["dataKey", "data", "stackId", "minPointSize"])
9
+ if (key in props)
10
+ throw new Error(`WaterfallSeries does not accept ${key}`);
11
+ return _jsx(BarSeries, { ...props, dataKey: "range", minPointSize: 0 });
12
+ }
13
+ /** Native axis-scaled connectors. Place before bars so the center endpoints sit underneath. */
14
+ export function WaterfallConnectors({ data, seriesKey = "range", hide, ...props }) {
15
+ const { visibleSeries } = useChart();
16
+ const horizontal = useChartLayout() === "vertical";
17
+ if (hide || (visibleSeries !== undefined && !visibleSeries.includes(seriesKey)))
18
+ return null;
19
+ return (_jsx(_Fragment, { children: data.slice(1).map((next, index) => {
20
+ const previous = data[index];
21
+ const incoming = next.kind === "delta" ? next.start : next.balance;
22
+ if (!previous ||
23
+ previous.range === null ||
24
+ next.range === null ||
25
+ previous.balance === null ||
26
+ previous.balance !== incoming)
27
+ return null;
28
+ return (_jsx(ReferenceLine, { stroke: "currentColor", strokeDasharray: "3 3", ifOverflow: "discard", zIndex: 100, ...props, pointerEvents: "none", segment: [
29
+ horizontal
30
+ ? { x: previous.balance, y: previous.id }
31
+ : { x: previous.id, y: previous.balance },
32
+ horizontal ? { x: incoming, y: next.id } : { x: next.id, y: incoming },
33
+ ] }, JSON.stringify([previous.id, next.id])));
34
+ }) }));
35
+ }
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@kind-ui/charts",
3
+ "version": "0.1.0",
4
+ "description": "Composable React chart components built on Recharts and Motion.",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/bhaveshchow20/kind-ui.git",
8
+ "directory": "packages/charts"
9
+ },
10
+ "homepage": "https://github.com/bhaveshchow20/kind-ui/tree/main/packages/charts#readme",
11
+ "bugs": {
12
+ "url": "https://github.com/bhaveshchow20/kind-ui/issues"
13
+ },
14
+ "keywords": [
15
+ "react",
16
+ "charts",
17
+ "recharts",
18
+ "motion",
19
+ "typescript"
20
+ ],
21
+ "type": "module",
22
+ "sideEffects": [
23
+ "**/*.css"
24
+ ],
25
+ "license": "MIT",
26
+ "scripts": {
27
+ "prepack": "node ../../scripts/prepare-package.mjs"
28
+ },
29
+ "exports": {
30
+ ".": {
31
+ "types": "./dist/index.d.ts",
32
+ "import": "./dist/index.js"
33
+ },
34
+ "./styles.css": "./dist/styles.css"
35
+ },
36
+ "types": "./dist/index.d.ts",
37
+ "files": [
38
+ "CHANGELOG.md",
39
+ "dist/**/*.js",
40
+ "dist/**/*.d.ts",
41
+ "dist/styles.css"
42
+ ],
43
+ "peerDependencies": {
44
+ "react": "^19.3.0",
45
+ "react-dom": "^19.3.0",
46
+ "recharts": "^3.10.1",
47
+ "motion": "^13.4.6"
48
+ }
49
+ }