@spatika/react 1.4.0 → 1.5.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 (93) hide show
  1. package/AGENTS.md +6 -3
  2. package/README.md +1 -1
  3. package/dist/composites/EventCalendar.js +3 -3
  4. package/dist/composites/GlassCard.d.ts +1 -1
  5. package/dist/composites/RichTextEditor.d.ts +1 -4
  6. package/dist/composites/RichTextEditor.d.ts.map +1 -1
  7. package/dist/composites/RichTextEditor.js +12 -19
  8. package/dist/composites/SurfaceCard.d.ts +1 -1
  9. package/dist/composites/Tag.d.ts +2 -2
  10. package/dist/index.d.ts +8 -22
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +5 -11
  13. package/dist/lib/breakpoints.d.ts +17 -0
  14. package/dist/lib/breakpoints.d.ts.map +1 -0
  15. package/dist/lib/breakpoints.js +23 -0
  16. package/dist/lib/create-theme.d.ts +162 -0
  17. package/dist/lib/create-theme.d.ts.map +1 -0
  18. package/dist/lib/create-theme.js +138 -0
  19. package/dist/lib/scheduler.js +2 -2
  20. package/dist/lib/themes.d.ts +17 -7
  21. package/dist/lib/themes.d.ts.map +1 -1
  22. package/dist/lib/themes.js +22 -8
  23. package/dist/lib/use-media-query.d.ts +9 -0
  24. package/dist/lib/use-media-query.d.ts.map +1 -1
  25. package/dist/lib/use-media-query.js +28 -1
  26. package/dist/primitives/Alert.d.ts +1 -1
  27. package/dist/primitives/Badge.d.ts +2 -2
  28. package/dist/primitives/Button.d.ts +2 -2
  29. package/dist/primitives/Container.d.ts +2 -2
  30. package/dist/primitives/Fab.d.ts +4 -4
  31. package/dist/primitives/Grid.d.ts +2 -1
  32. package/dist/primitives/Grid.d.ts.map +1 -1
  33. package/dist/primitives/Grid.js +10 -2
  34. package/dist/primitives/IconButton.d.ts +2 -2
  35. package/dist/primitives/ToggleButton.d.ts +1 -1
  36. package/dist/theme/SpatikaThemeProvider.d.ts +4 -5
  37. package/dist/theme/SpatikaThemeProvider.d.ts.map +1 -1
  38. package/dist/theme/SpatikaThemeProvider.js +28 -13
  39. package/package.json +4 -2
  40. package/skills/spatika-ui/SKILL.md +25 -6
  41. package/src/composites/EventCalendar.test.tsx +293 -0
  42. package/src/composites/EventCalendar.tsx +3 -3
  43. package/src/composites/RichTextEditor.test.tsx +51 -0
  44. package/src/composites/RichTextEditor.tsx +20 -84
  45. package/src/composites/chart-ui.test.tsx +21 -0
  46. package/src/composites/scheduler.test.tsx +0 -258
  47. package/src/index.test.ts +6 -0
  48. package/src/index.ts +138 -72
  49. package/src/lib/breakpoints.test.ts +29 -0
  50. package/src/lib/breakpoints.ts +28 -0
  51. package/src/lib/create-theme.test.ts +79 -0
  52. package/src/lib/create-theme.ts +249 -0
  53. package/src/lib/scheduler.test.ts +10 -0
  54. package/src/lib/scheduler.ts +2 -2
  55. package/src/lib/themes.test.ts +17 -0
  56. package/src/lib/themes.ts +43 -12
  57. package/src/lib/use-media-query.test.tsx +80 -0
  58. package/src/lib/use-media-query.ts +35 -1
  59. package/src/primitives/Grid.test.tsx +55 -0
  60. package/src/primitives/Grid.tsx +13 -3
  61. package/src/primitives/mui-more.test.tsx +17 -0
  62. package/src/theme/SpatikaThemeProvider.test.tsx +38 -0
  63. package/src/theme/SpatikaThemeProvider.tsx +43 -15
  64. package/src/composites/ChartDataGrid.test.tsx +0 -57
  65. package/src/composites/ChartDataGrid.tsx +0 -196
  66. package/src/composites/MapChart.test.tsx +0 -39
  67. package/src/composites/MapChart.tsx +0 -130
  68. package/src/composites/ScatterWebGL.test.tsx +0 -25
  69. package/src/composites/ScatterWebGL.tsx +0 -79
  70. package/src/composites/cartesian-charts.test.tsx +0 -136
  71. package/src/composites/cartesian-charts.tsx +0 -1355
  72. package/src/composites/chart-composition.test.tsx +0 -68
  73. package/src/composites/chart-composition.tsx +0 -1039
  74. package/src/composites/chart-interaction.ts +0 -136
  75. package/src/composites/chart-ui.tsx +0 -336
  76. package/src/composites/charts-3d.test.tsx +0 -25
  77. package/src/composites/charts-3d.tsx +0 -318
  78. package/src/composites/charts.test.tsx +0 -254
  79. package/src/composites/flow-charts.test.tsx +0 -98
  80. package/src/composites/flow-charts.tsx +0 -641
  81. package/src/composites/radial-charts.test.tsx +0 -89
  82. package/src/composites/radial-charts.tsx +0 -643
  83. package/src/lib/chart-export.test.ts +0 -20
  84. package/src/lib/chart-export.ts +0 -99
  85. package/src/lib/charts-platform.test.ts +0 -93
  86. package/src/lib/charts.test.ts +0 -132
  87. package/src/lib/charts.ts +0 -1021
  88. package/src/lib/geo.test.ts +0 -42
  89. package/src/lib/geo.ts +0 -138
  90. package/src/lib/iso.test.ts +0 -22
  91. package/src/lib/iso.ts +0 -102
  92. package/src/lib/webgl-scatter.test.ts +0 -36
  93. package/src/lib/webgl-scatter.ts +0 -230
@@ -1,79 +0,0 @@
1
- import { useEffect, useRef } from "react";
2
- import { createScatterGL, destroyScatterGL, drawScatterGL, type ScatterGL } from "../lib/webgl-scatter";
3
- import type { ChartLegendItem } from "./chart-ui";
4
-
5
- type ScatterSeriesLike = {
6
- data: Array<{ x: number; y: number; z?: number }>;
7
- };
8
-
9
- export function ScatterWebGLLayer({
10
- width,
11
- height,
12
- series,
13
- meta,
14
- hidden,
15
- xAt,
16
- yAt,
17
- sizeAt,
18
- bubble,
19
- onUnavailable,
20
- }: {
21
- width: number;
22
- height: number;
23
- series: ScatterSeriesLike[];
24
- meta: ChartLegendItem[];
25
- hidden: Set<string>;
26
- xAt: (value: number) => number;
27
- yAt: (value: number) => number;
28
- sizeAt: (z: number) => number;
29
- bubble: boolean;
30
- onUnavailable?: () => void;
31
- }) {
32
- const canvasRef = useRef<HTMLCanvasElement>(null);
33
- const gpuRef = useRef<ScatterGL | null>(null);
34
-
35
- useEffect(() => {
36
- const canvas = canvasRef.current;
37
- if (!canvas) return;
38
- const gpu = createScatterGL(canvas);
39
- if (!gpu) {
40
- onUnavailable?.();
41
- return;
42
- }
43
- gpuRef.current = gpu;
44
- return () => {
45
- destroyScatterGL(gpu);
46
- gpuRef.current = null;
47
- };
48
- }, [onUnavailable]);
49
-
50
- useEffect(() => {
51
- const gpu = gpuRef.current;
52
- const canvas = canvasRef.current;
53
- if (!gpu || !canvas) return;
54
- const batches = series.flatMap((item, s) => {
55
- const info = meta[s]!;
56
- if (hidden.has(info.id)) return [];
57
- return [
58
- {
59
- color: info.color,
60
- positions: item.data.map((point) => ({
61
- x: xAt(point.x),
62
- y: yAt(point.y),
63
- size: bubble ? sizeAt(point.z ?? 1) * 2 : 9,
64
- })),
65
- },
66
- ];
67
- });
68
- drawScatterGL(gpu, canvas, width, height, batches);
69
- });
70
-
71
- return (
72
- <canvas
73
- ref={canvasRef}
74
- className="spk-chart-webgl"
75
- data-slot="scatter-webgl"
76
- aria-hidden
77
- />
78
- );
79
- }
@@ -1,136 +0,0 @@
1
- import { fireEvent, render, screen } from "@testing-library/react";
2
- import { describe, expect, it, vi } from "vitest";
3
- import { AreaChart, BarChart, LineChart } from "./cartesian-charts";
4
-
5
- const months = ["Jan", "Feb", "Mar"];
6
-
7
- describe("cartesian-charts", () => {
8
- it("renders grouped bars for categorical series", () => {
9
- render(
10
- <BarChart
11
- width={360}
12
- height={220}
13
- xAxis={[{ data: months }]}
14
- series={[
15
- { label: "Views", data: [4, 3, 5] },
16
- { label: "Signups", data: [1, 2, 2] },
17
- ]}
18
- />,
19
- );
20
- expect(screen.getByRole("img", { name: /bar chart/i })).toBeInTheDocument();
21
- expect(document.querySelectorAll('[data-slot="bar-plot"] .spk-chart-mark').length).toBeGreaterThan(0);
22
- });
23
-
24
- it("renders line series from numeric data", () => {
25
- const { container } = render(
26
- <LineChart
27
- width={360}
28
- height={220}
29
- xAxis={[{ data: months }]}
30
- series={[{ label: "Revenue", data: [2, 4, 3] }]}
31
- />,
32
- );
33
- expect(container.querySelector('[data-slot="line-plot"] path')).toBeTruthy();
34
- });
35
-
36
- it("stacks area series so later layers sit on earlier totals", () => {
37
- const { container } = render(
38
- <AreaChart
39
- width={360}
40
- height={220}
41
- stacked
42
- xAxis={[{ data: months }]}
43
- series={[
44
- { label: "v1", data: [2, 3, 4] },
45
- { label: "v2", data: [1, 1, 2] },
46
- ]}
47
- />,
48
- );
49
- expect(container.querySelector('[data-slot="area-plot"]')).toBeTruthy();
50
- expect(container.querySelectorAll('[data-slot="area-plot"] path').length).toBeGreaterThanOrEqual(2);
51
- });
52
-
53
- it("fires onItemClick with the bar category and value", () => {
54
- const onItemClick = vi.fn();
55
- const { container } = render(
56
- <BarChart
57
- width={360}
58
- height={220}
59
- hideLegend
60
- xAxis={[{ data: months }]}
61
- series={[{ label: "Views", data: [4, 3, 5] }]}
62
- onItemClick={onItemClick}
63
- />,
64
- );
65
- const mark = container.querySelector(".spk-chart-mark--interactive");
66
- expect(mark).toBeTruthy();
67
- fireEvent.click(mark!);
68
- expect(onItemClick).toHaveBeenCalledWith(
69
- expect.objectContaining({ seriesLabel: "Views", dataIndex: 0, category: "Jan", value: 4 }),
70
- );
71
- });
72
-
73
- it("colors individual bars from itemColors", () => {
74
- const { container } = render(
75
- <BarChart
76
- width={360}
77
- height={220}
78
- hideLegend
79
- xAxis={[{ data: months }]}
80
- series={[{ label: "Growth", data: [2, -1, 3], itemColors: ["var(--chart-3)", "var(--chart-4)"] }]}
81
- />,
82
- );
83
- const marks = container.querySelectorAll('[data-slot="bar-plot"] .spk-chart-mark');
84
- expect(marks[0]?.getAttribute("fill")).toBe("var(--chart-3)");
85
- expect(marks[1]?.getAttribute("fill")).toBe("var(--chart-4)");
86
- });
87
-
88
- it("renders a reference line and end labels on bars", () => {
89
- const { container } = render(
90
- <BarChart
91
- width={360}
92
- height={220}
93
- hideLegend
94
- showLabels
95
- xAxis={[{ data: months }]}
96
- series={[{ label: "Views", data: [4, 3, 5] }]}
97
- referenceLines={[{ y: 4, label: "Target" }]}
98
- />,
99
- );
100
- expect(container.querySelector('[data-slot="chart-reference-lines"]')).toBeTruthy();
101
- expect(screen.getByText("Target")).toBeInTheDocument();
102
- expect(container.querySelector('[data-slot="bar-labels"]')).toBeTruthy();
103
- });
104
-
105
- it("fires onItemClick from horizontal bars", () => {
106
- const onItemClick = vi.fn();
107
- const { container } = render(
108
- <BarChart
109
- width={360}
110
- height={220}
111
- hideLegend
112
- layout="horizontal"
113
- xAxis={[{ data: months }]}
114
- series={[{ label: "Views", data: [4, 3, 5] }]}
115
- onItemClick={onItemClick}
116
- />,
117
- );
118
- fireEvent.click(container.querySelector(".spk-chart-mark--interactive")!);
119
- expect(onItemClick).toHaveBeenCalledWith(expect.objectContaining({ category: "Jan", value: 4 }));
120
- });
121
-
122
- it("renders a custom tooltip from hover", () => {
123
- const { container } = render(
124
- <BarChart
125
- width={360}
126
- height={220}
127
- hideLegend
128
- xAxis={[{ data: months }]}
129
- series={[{ label: "Views", data: [4, 3, 5] }]}
130
- renderTooltip={(hover) => <p>{hover.category} custom</p>}
131
- />,
132
- );
133
- fireEvent.mouseEnter(container.querySelector(".spk-chart-mark")!);
134
- expect(screen.getByText("Jan custom")).toBeInTheDocument();
135
- });
136
- });