@spatika/react 1.3.1 → 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.
- package/AGENTS.md +6 -3
- package/README.md +1 -1
- package/dist/composites/EventCalendar.d.ts +13 -2
- package/dist/composites/EventCalendar.d.ts.map +1 -1
- package/dist/composites/EventCalendar.js +13 -27
- package/dist/composites/GlassCard.d.ts +1 -1
- package/dist/composites/RichTextEditor.d.ts +1 -4
- package/dist/composites/RichTextEditor.d.ts.map +1 -1
- package/dist/composites/RichTextEditor.js +12 -19
- package/dist/composites/SurfaceCard.d.ts +1 -1
- package/dist/composites/Tag.d.ts +2 -2
- package/dist/composites/cartesian-charts.d.ts +12 -2
- package/dist/composites/cartesian-charts.d.ts.map +1 -1
- package/dist/composites/cartesian-charts.js +27 -13
- package/dist/composites/chart-composition.d.ts +19 -1
- package/dist/composites/chart-composition.d.ts.map +1 -1
- package/dist/composites/chart-composition.js +124 -62
- package/dist/composites/chart-interaction.d.ts +81 -0
- package/dist/composites/chart-interaction.d.ts.map +1 -0
- package/dist/composites/chart-interaction.js +56 -0
- package/dist/composites/chart-ui.d.ts +8 -13
- package/dist/composites/chart-ui.d.ts.map +1 -1
- package/dist/composites/chart-ui.js +9 -6
- package/dist/composites/flow-charts.d.ts +6 -1
- package/dist/composites/flow-charts.d.ts.map +1 -1
- package/dist/composites/flow-charts.js +28 -14
- package/dist/composites/radial-charts.d.ts +11 -1
- package/dist/composites/radial-charts.d.ts.map +1 -1
- package/dist/composites/radial-charts.js +33 -14
- package/dist/composites/scheduler-ui.d.ts +14 -1
- package/dist/composites/scheduler-ui.d.ts.map +1 -1
- package/dist/composites/scheduler-ui.js +23 -2
- package/dist/index.d.ts +14 -26
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -14
- package/dist/lib/breakpoints.d.ts +17 -0
- package/dist/lib/breakpoints.d.ts.map +1 -0
- package/dist/lib/breakpoints.js +23 -0
- package/dist/lib/chips.d.ts +3 -0
- package/dist/lib/chips.d.ts.map +1 -1
- package/dist/lib/chips.js +10 -0
- package/dist/lib/create-theme.d.ts +162 -0
- package/dist/lib/create-theme.d.ts.map +1 -0
- package/dist/lib/create-theme.js +138 -0
- package/dist/lib/scheduler.d.ts +12 -0
- package/dist/lib/scheduler.d.ts.map +1 -1
- package/dist/lib/scheduler.js +24 -2
- package/dist/lib/themes.d.ts +17 -7
- package/dist/lib/themes.d.ts.map +1 -1
- package/dist/lib/themes.js +22 -8
- package/dist/lib/use-media-query.d.ts +9 -0
- package/dist/lib/use-media-query.d.ts.map +1 -1
- package/dist/lib/use-media-query.js +28 -1
- package/dist/primitives/Alert.d.ts +1 -1
- package/dist/primitives/Badge.d.ts +2 -2
- package/dist/primitives/Button.d.ts +2 -2
- package/dist/primitives/Container.d.ts +2 -2
- package/dist/primitives/Fab.d.ts +4 -4
- package/dist/primitives/Grid.d.ts +2 -1
- package/dist/primitives/Grid.d.ts.map +1 -1
- package/dist/primitives/Grid.js +10 -2
- package/dist/primitives/IconButton.d.ts +2 -2
- package/dist/primitives/NativeSelect.d.ts +10 -1
- package/dist/primitives/NativeSelect.d.ts.map +1 -1
- package/dist/primitives/NativeSelect.js +2 -2
- package/dist/primitives/ToggleButton.d.ts +1 -1
- package/dist/theme/SpatikaThemeProvider.d.ts +4 -5
- package/dist/theme/SpatikaThemeProvider.d.ts.map +1 -1
- package/dist/theme/SpatikaThemeProvider.js +28 -13
- package/package.json +4 -2
- package/skills/spatika-ui/SKILL.md +28 -5
- package/src/composites/EventCalendar.test.tsx +293 -0
- package/src/composites/EventCalendar.tsx +38 -27
- package/src/composites/RichTextEditor.test.tsx +51 -0
- package/src/composites/RichTextEditor.tsx +20 -84
- package/src/composites/chart-ui.test.tsx +21 -0
- package/src/composites/scheduler-ui.tsx +128 -26
- package/src/composites/scheduler.test.tsx +0 -219
- package/src/index.test.ts +10 -0
- package/src/index.ts +148 -65
- package/src/lib/breakpoints.test.ts +29 -0
- package/src/lib/breakpoints.ts +28 -0
- package/src/lib/chips.ts +16 -0
- package/src/lib/create-theme.test.ts +79 -0
- package/src/lib/create-theme.ts +249 -0
- package/src/lib/scheduler.test.ts +26 -0
- package/src/lib/scheduler.ts +36 -2
- package/src/lib/themes.test.ts +17 -0
- package/src/lib/themes.ts +43 -12
- package/src/lib/use-media-query.test.tsx +80 -0
- package/src/lib/use-media-query.ts +35 -1
- package/src/primitives/Grid.test.tsx +55 -0
- package/src/primitives/Grid.tsx +13 -3
- package/src/primitives/NativeSelect.test.tsx +28 -0
- package/src/primitives/NativeSelect.tsx +14 -4
- package/src/primitives/mui-more.test.tsx +17 -0
- package/src/theme/SpatikaThemeProvider.test.tsx +38 -0
- package/src/theme/SpatikaThemeProvider.tsx +43 -15
- package/src/composites/ChartDataGrid.test.tsx +0 -57
- package/src/composites/ChartDataGrid.tsx +0 -196
- package/src/composites/MapChart.test.tsx +0 -39
- package/src/composites/MapChart.tsx +0 -130
- package/src/composites/ScatterWebGL.test.tsx +0 -25
- package/src/composites/ScatterWebGL.tsx +0 -79
- package/src/composites/cartesian-charts.test.tsx +0 -52
- package/src/composites/cartesian-charts.tsx +0 -1287
- package/src/composites/chart-composition.test.tsx +0 -53
- package/src/composites/chart-composition.tsx +0 -898
- package/src/composites/chart-ui.tsx +0 -328
- package/src/composites/charts-3d.test.tsx +0 -25
- package/src/composites/charts-3d.tsx +0 -318
- package/src/composites/charts.test.tsx +0 -254
- package/src/composites/flow-charts.test.tsx +0 -79
- package/src/composites/flow-charts.tsx +0 -607
- package/src/composites/radial-charts.test.tsx +0 -74
- package/src/composites/radial-charts.tsx +0 -617
- package/src/lib/chart-export.test.ts +0 -20
- package/src/lib/chart-export.ts +0 -99
- package/src/lib/charts-platform.test.ts +0 -93
- package/src/lib/charts.test.ts +0 -132
- package/src/lib/charts.ts +0 -1021
- package/src/lib/geo.test.ts +0 -42
- package/src/lib/geo.ts +0 -138
- package/src/lib/iso.test.ts +0 -22
- package/src/lib/iso.ts +0 -102
- package/src/lib/webgl-scatter.test.ts +0 -36
- package/src/lib/webgl-scatter.ts +0 -230
|
@@ -1,228 +1,9 @@
|
|
|
1
1
|
import { render, screen } from "@testing-library/react";
|
|
2
2
|
import userEvent from "@testing-library/user-event";
|
|
3
3
|
import { describe, expect, it, vi } from "vitest";
|
|
4
|
-
import { EventCalendar } from "./EventCalendar";
|
|
5
4
|
import { EventTimeline } from "./EventTimeline";
|
|
6
5
|
import type { SchedulerEvent, SchedulerResource } from "../lib/scheduler";
|
|
7
6
|
|
|
8
|
-
const resources: SchedulerResource[] = [
|
|
9
|
-
{ id: "work", title: "Work", color: "violet" },
|
|
10
|
-
{ id: "health", title: "Health", color: "teal" },
|
|
11
|
-
];
|
|
12
|
-
|
|
13
|
-
const events: SchedulerEvent[] = [
|
|
14
|
-
{
|
|
15
|
-
id: "run",
|
|
16
|
-
title: "Morning Run",
|
|
17
|
-
start: "2026-08-03T07:00:00",
|
|
18
|
-
end: "2026-08-03T07:45:00",
|
|
19
|
-
resourceId: "health",
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
id: "bday",
|
|
23
|
-
title: "Alice's Birthday",
|
|
24
|
-
start: "2026-08-06",
|
|
25
|
-
end: "2026-08-08",
|
|
26
|
-
allDay: true,
|
|
27
|
-
resourceId: "work",
|
|
28
|
-
color: "rose",
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
id: "review",
|
|
32
|
-
title: "Design Review",
|
|
33
|
-
start: "2026-08-09T14:00:00",
|
|
34
|
-
end: "2026-08-09T16:00:00",
|
|
35
|
-
resourceId: "work",
|
|
36
|
-
},
|
|
37
|
-
];
|
|
38
|
-
|
|
39
|
-
describe("EventCalendar", () => {
|
|
40
|
-
it("renders the month heading, weekday labels, and events", () => {
|
|
41
|
-
render(
|
|
42
|
-
<EventCalendar
|
|
43
|
-
defaultDate={new Date(2026, 7, 15)}
|
|
44
|
-
events={events}
|
|
45
|
-
resources={resources}
|
|
46
|
-
locale="en-US"
|
|
47
|
-
/>,
|
|
48
|
-
);
|
|
49
|
-
expect(screen.getByRole("heading", { name: /August 2026/i })).toBeInTheDocument();
|
|
50
|
-
expect(screen.getByText(/Sun/)).toBeInTheDocument();
|
|
51
|
-
expect(screen.getByText("Morning Run")).toBeInTheDocument();
|
|
52
|
-
expect(screen.getByText("Alice's Birthday")).toBeInTheDocument();
|
|
53
|
-
expect(screen.getByText("Work")).toBeInTheDocument();
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it("jumps to today from the toolbar", async () => {
|
|
57
|
-
const user = userEvent.setup();
|
|
58
|
-
const onDateChange = vi.fn();
|
|
59
|
-
render(
|
|
60
|
-
<EventCalendar
|
|
61
|
-
defaultDate={new Date(2025, 0, 1)}
|
|
62
|
-
onDateChange={onDateChange}
|
|
63
|
-
events={events}
|
|
64
|
-
/>,
|
|
65
|
-
);
|
|
66
|
-
await user.click(screen.getByRole("button", { name: "Today" }));
|
|
67
|
-
expect(onDateChange).toHaveBeenCalled();
|
|
68
|
-
const next = onDateChange.mock.calls[0][0] as Date;
|
|
69
|
-
const now = new Date();
|
|
70
|
-
expect(next.getFullYear()).toBe(now.getFullYear());
|
|
71
|
-
expect(next.getMonth()).toBe(now.getMonth());
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
it("fires onEventClick for a timed event", async () => {
|
|
75
|
-
const user = userEvent.setup();
|
|
76
|
-
const onEventClick = vi.fn();
|
|
77
|
-
render(
|
|
78
|
-
<EventCalendar
|
|
79
|
-
defaultDate={new Date(2026, 7, 15)}
|
|
80
|
-
events={events}
|
|
81
|
-
resources={resources}
|
|
82
|
-
locale="en-US"
|
|
83
|
-
onEventClick={onEventClick}
|
|
84
|
-
/>,
|
|
85
|
-
);
|
|
86
|
-
await user.click(screen.getByText("Morning Run"));
|
|
87
|
-
expect(onEventClick).toHaveBeenCalledWith(expect.objectContaining({ id: "run" }));
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
it("switches to week view from the menu", async () => {
|
|
91
|
-
const user = userEvent.setup();
|
|
92
|
-
render(
|
|
93
|
-
<EventCalendar defaultDate={new Date(2026, 7, 15)} events={events} locale="en-US" />,
|
|
94
|
-
);
|
|
95
|
-
await user.click(screen.getByRole("button", { name: /month/i }));
|
|
96
|
-
await user.click(screen.getByRole("menuitem", { name: "Week" }));
|
|
97
|
-
expect(screen.getByRole("heading", { name: /2026/ })).toBeInTheDocument();
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it("lists events in agenda view", () => {
|
|
101
|
-
render(
|
|
102
|
-
<EventCalendar
|
|
103
|
-
defaultView="agenda"
|
|
104
|
-
defaultDate={new Date(2026, 7, 3)}
|
|
105
|
-
events={events}
|
|
106
|
-
locale="en-US"
|
|
107
|
-
/>,
|
|
108
|
-
);
|
|
109
|
-
expect(screen.getByRole("heading", { name: /Aug 3/ })).toBeInTheDocument();
|
|
110
|
-
expect(screen.getAllByText("No events").length).toBeGreaterThan(0);
|
|
111
|
-
expect(screen.getByText("Morning Run")).toBeInTheDocument();
|
|
112
|
-
expect(screen.getAllByText("Alice's Birthday").length).toBeGreaterThan(0);
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
it("opens the editor and saves title changes", async () => {
|
|
116
|
-
const user = userEvent.setup();
|
|
117
|
-
const onEventChange = vi.fn();
|
|
118
|
-
render(
|
|
119
|
-
<EventCalendar
|
|
120
|
-
defaultDate={new Date(2026, 7, 15)}
|
|
121
|
-
events={events}
|
|
122
|
-
resources={resources}
|
|
123
|
-
locale="en-US"
|
|
124
|
-
onEventChange={onEventChange}
|
|
125
|
-
/>,
|
|
126
|
-
);
|
|
127
|
-
await user.click(screen.getByText("Morning Run"));
|
|
128
|
-
const title = screen.getByRole("textbox", { name: /title/i });
|
|
129
|
-
await user.clear(title);
|
|
130
|
-
await user.type(title, "Jog");
|
|
131
|
-
await user.click(screen.getByRole("button", { name: "Save" }));
|
|
132
|
-
expect(onEventChange).toHaveBeenCalledWith(
|
|
133
|
-
expect.objectContaining({ id: "run" }),
|
|
134
|
-
expect.objectContaining({ title: "Jog" }),
|
|
135
|
-
);
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
it("creates an event from a day slot", async () => {
|
|
139
|
-
const user = userEvent.setup();
|
|
140
|
-
const onEventCreate = vi.fn();
|
|
141
|
-
render(
|
|
142
|
-
<EventCalendar
|
|
143
|
-
defaultDate={new Date(2026, 7, 15)}
|
|
144
|
-
events={events}
|
|
145
|
-
locale="en-US"
|
|
146
|
-
onEventCreate={onEventCreate}
|
|
147
|
-
/>,
|
|
148
|
-
);
|
|
149
|
-
await user.click(screen.getByRole("button", { name: "15" }));
|
|
150
|
-
expect(screen.getByRole("heading", { name: "New event" })).toBeInTheDocument();
|
|
151
|
-
await user.type(screen.getByRole("textbox", { name: /title/i }), "Focus time");
|
|
152
|
-
await user.click(screen.getByRole("button", { name: "Save" }));
|
|
153
|
-
expect(onEventCreate).toHaveBeenCalledWith(expect.objectContaining({ title: "Focus time" }));
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
it("skips the built-in editor when showEventEditor is false", async () => {
|
|
157
|
-
const user = userEvent.setup();
|
|
158
|
-
const onEventClick = vi.fn();
|
|
159
|
-
const onSlotClick = vi.fn();
|
|
160
|
-
render(
|
|
161
|
-
<EventCalendar
|
|
162
|
-
defaultDate={new Date(2026, 7, 15)}
|
|
163
|
-
events={events}
|
|
164
|
-
resources={resources}
|
|
165
|
-
locale="en-US"
|
|
166
|
-
showEventEditor={false}
|
|
167
|
-
onEventClick={onEventClick}
|
|
168
|
-
onSlotClick={onSlotClick}
|
|
169
|
-
/>,
|
|
170
|
-
);
|
|
171
|
-
await user.click(screen.getByText("Morning Run"));
|
|
172
|
-
expect(onEventClick).toHaveBeenCalledWith(expect.objectContaining({ id: "run" }));
|
|
173
|
-
expect(screen.queryByRole("heading", { name: /event/i })).not.toBeInTheDocument();
|
|
174
|
-
|
|
175
|
-
await user.click(screen.getByRole("button", { name: "15" }));
|
|
176
|
-
expect(onSlotClick).toHaveBeenCalled();
|
|
177
|
-
expect(screen.queryByRole("heading", { name: "New event" })).not.toBeInTheDocument();
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
it("renders custom event chips and toolbar", async () => {
|
|
181
|
-
const user = userEvent.setup();
|
|
182
|
-
const onDateChange = vi.fn();
|
|
183
|
-
render(
|
|
184
|
-
<EventCalendar
|
|
185
|
-
defaultDate={new Date(2026, 7, 15)}
|
|
186
|
-
events={events}
|
|
187
|
-
resources={resources}
|
|
188
|
-
locale="en-US"
|
|
189
|
-
showEventEditor={false}
|
|
190
|
-
showPreferences={false}
|
|
191
|
-
toolbarTrailing={<button type="button">Jump year</button>}
|
|
192
|
-
renderEvent={(event) => <span>★ {event.title}</span>}
|
|
193
|
-
renderToolbar={({ title, onToday }) => (
|
|
194
|
-
<div>
|
|
195
|
-
<p>{title}</p>
|
|
196
|
-
<button type="button" onClick={onToday}>
|
|
197
|
-
Jump today
|
|
198
|
-
</button>
|
|
199
|
-
</div>
|
|
200
|
-
)}
|
|
201
|
-
onDateChange={onDateChange}
|
|
202
|
-
/>,
|
|
203
|
-
);
|
|
204
|
-
expect(screen.getByText("★ Morning Run")).toBeInTheDocument();
|
|
205
|
-
expect(screen.queryByRole("button", { name: "Preferences" })).not.toBeInTheDocument();
|
|
206
|
-
expect(screen.queryByRole("button", { name: "Jump year" })).not.toBeInTheDocument();
|
|
207
|
-
await user.click(screen.getByRole("button", { name: "Jump today" }));
|
|
208
|
-
expect(onDateChange).toHaveBeenCalled();
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
it("keeps toolbarTrailing on the default toolbar", () => {
|
|
212
|
-
render(
|
|
213
|
-
<EventCalendar
|
|
214
|
-
defaultDate={new Date(2026, 7, 15)}
|
|
215
|
-
events={events}
|
|
216
|
-
locale="en-US"
|
|
217
|
-
showPreferences={false}
|
|
218
|
-
toolbarTrailing={<button type="button">Jump year</button>}
|
|
219
|
-
/>,
|
|
220
|
-
);
|
|
221
|
-
expect(screen.getByRole("button", { name: "Jump year" })).toBeInTheDocument();
|
|
222
|
-
expect(screen.getByRole("heading", { name: /August 2026/i })).toBeInTheDocument();
|
|
223
|
-
});
|
|
224
|
-
});
|
|
225
|
-
|
|
226
7
|
describe("EventTimeline", () => {
|
|
227
8
|
const timelineEvents: SchedulerEvent[] = [
|
|
228
9
|
{
|
package/src/index.test.ts
CHANGED
|
@@ -7,7 +7,11 @@ import {
|
|
|
7
7
|
ChartDataGrid,
|
|
8
8
|
EventCalendar,
|
|
9
9
|
MapChart,
|
|
10
|
+
SchedulerDateJump,
|
|
10
11
|
SchedulerToolbar,
|
|
12
|
+
BREAKPOINTS,
|
|
13
|
+
calendarVisibleRange,
|
|
14
|
+
createTheme,
|
|
11
15
|
mercator,
|
|
12
16
|
} from "./index";
|
|
13
17
|
|
|
@@ -21,6 +25,12 @@ describe("@spatika/react public exports", () => {
|
|
|
21
25
|
expect(BarChart3D).toBeTypeOf("function");
|
|
22
26
|
expect(EventCalendar).toBeTypeOf("function");
|
|
23
27
|
expect(SchedulerToolbar).toBeTypeOf("function");
|
|
28
|
+
expect(SchedulerDateJump).toBeTypeOf("function");
|
|
29
|
+
expect(calendarVisibleRange).toBeTypeOf("function");
|
|
24
30
|
expect(mercator([0, 0])[0]).toBeCloseTo(0.5);
|
|
31
|
+
expect(BREAKPOINTS.md).toBe(768);
|
|
32
|
+
expect(createTheme({ id: "brand", palette: { primary: "#7c3aed" } }).vars["--primary"]).toBe(
|
|
33
|
+
"#7c3aed",
|
|
34
|
+
);
|
|
25
35
|
});
|
|
26
36
|
});
|
package/src/index.ts
CHANGED
|
@@ -37,7 +37,9 @@ export {
|
|
|
37
37
|
layoutToggleClass,
|
|
38
38
|
listRowToggleClass,
|
|
39
39
|
nativeSelectClass,
|
|
40
|
+
nativeSelectSizeClass,
|
|
40
41
|
} from "./lib/chips";
|
|
42
|
+
export type { NativeSelectSize } from "./lib/chips";
|
|
41
43
|
export {
|
|
42
44
|
duration,
|
|
43
45
|
transition,
|
|
@@ -55,8 +57,33 @@ export {
|
|
|
55
57
|
applyTheme,
|
|
56
58
|
isDarkTheme,
|
|
57
59
|
isThemeId,
|
|
60
|
+
type ApplyThemeCustom,
|
|
61
|
+
type BuiltinThemeId,
|
|
58
62
|
type ThemeId,
|
|
59
63
|
} from "./lib/themes";
|
|
64
|
+
export {
|
|
65
|
+
createTheme,
|
|
66
|
+
themeToCss,
|
|
67
|
+
injectCustomThemeStyles,
|
|
68
|
+
findCustomTheme,
|
|
69
|
+
PALETTE_CSS_VARS,
|
|
70
|
+
GLASS_CSS_VARS,
|
|
71
|
+
SHAPE_CSS_VARS,
|
|
72
|
+
type CreateThemeOptions,
|
|
73
|
+
type SpatikaTheme,
|
|
74
|
+
type ThemePalette,
|
|
75
|
+
type ThemeGlass,
|
|
76
|
+
type ThemeShape,
|
|
77
|
+
type ThemeTypography,
|
|
78
|
+
} from "./lib/create-theme";
|
|
79
|
+
export {
|
|
80
|
+
BREAKPOINTS,
|
|
81
|
+
BREAKPOINT_KEYS,
|
|
82
|
+
breakpointUp,
|
|
83
|
+
breakpointDown,
|
|
84
|
+
breakpointBetween,
|
|
85
|
+
type Breakpoint,
|
|
86
|
+
} from "./lib/breakpoints";
|
|
60
87
|
export { getAvatarColor, getAvatarFallbackHue, getInitials } from "./lib/avatar-utils";
|
|
61
88
|
export {
|
|
62
89
|
COVER_PATTERN_KINDS,
|
|
@@ -77,7 +104,13 @@ export {
|
|
|
77
104
|
coverTitleClass,
|
|
78
105
|
} from "./lib/cover-chrome";
|
|
79
106
|
export { useCoverChromeBleed, type CoverChromeInk } from "./lib/use-cover-chrome-bleed";
|
|
80
|
-
export {
|
|
107
|
+
export {
|
|
108
|
+
useIsMobile,
|
|
109
|
+
useMediaQuery,
|
|
110
|
+
useBreakpoint,
|
|
111
|
+
useBreakpointUp,
|
|
112
|
+
useBreakpointDown,
|
|
113
|
+
} from "./lib/use-media-query";
|
|
81
114
|
export {
|
|
82
115
|
SpatikaThemeProvider,
|
|
83
116
|
useSpatikaTheme,
|
|
@@ -209,7 +242,7 @@ export {
|
|
|
209
242
|
SelectTrigger,
|
|
210
243
|
SelectValue,
|
|
211
244
|
} from "./primitives/Select";
|
|
212
|
-
export { NativeSelect } from "./primitives/NativeSelect";
|
|
245
|
+
export { NativeSelect, type NativeSelectProps } from "./primitives/NativeSelect";
|
|
213
246
|
export { Spinner } from "./primitives/Spinner";
|
|
214
247
|
export { Alert, AlertTitle, AlertDescription, alertVariants } from "./primitives/Alert";
|
|
215
248
|
export { Kbd } from "./primitives/Kbd";
|
|
@@ -402,6 +435,36 @@ export {
|
|
|
402
435
|
type PhotoViewerItem,
|
|
403
436
|
} from "./composites/PhotoViewer";
|
|
404
437
|
export { RichTextEditor, type RichTextEditorProps } from "./composites/RichTextEditor";
|
|
438
|
+
export {
|
|
439
|
+
SpatikaEditor,
|
|
440
|
+
useSpatikaEditor,
|
|
441
|
+
buildSpatikaExtensions,
|
|
442
|
+
EditorToolbar,
|
|
443
|
+
EditorBubbleMenu,
|
|
444
|
+
ImageBubbleMenu,
|
|
445
|
+
SlashCommandMenu,
|
|
446
|
+
MentionMenu,
|
|
447
|
+
AiOverlay,
|
|
448
|
+
ToolbarButton,
|
|
449
|
+
createSlashCommandExtension,
|
|
450
|
+
defaultSlashCommands,
|
|
451
|
+
createMentionExtension,
|
|
452
|
+
ResizableImage,
|
|
453
|
+
createAiActionExtension,
|
|
454
|
+
} from "@spatika/editor";
|
|
455
|
+
export type {
|
|
456
|
+
SpatikaEditorProps,
|
|
457
|
+
SpatikaEditorHandle,
|
|
458
|
+
SpatikaEditorToolbarConfig,
|
|
459
|
+
SlashCommandItem,
|
|
460
|
+
MentionContact,
|
|
461
|
+
AiActionDefinition,
|
|
462
|
+
PlaceholderConfig,
|
|
463
|
+
UseSpatikaEditorOptions,
|
|
464
|
+
SlashCommandStorage,
|
|
465
|
+
MentionStorage,
|
|
466
|
+
ImageAlign,
|
|
467
|
+
} from "@spatika/editor";
|
|
405
468
|
export { HeaderIconButton, type HeaderIconButtonProps } from "./composites/HeaderIconButton";
|
|
406
469
|
export {
|
|
407
470
|
QuickFilterRail,
|
|
@@ -500,16 +563,22 @@ export {
|
|
|
500
563
|
} from "./composites/EventEditor";
|
|
501
564
|
export {
|
|
502
565
|
SchedulerToolbar,
|
|
566
|
+
SchedulerDateJump,
|
|
503
567
|
SchedulerPreferencesMenu,
|
|
504
568
|
CALENDAR_VIEW_LABEL,
|
|
505
569
|
type SchedulerToolbarProps,
|
|
570
|
+
type SchedulerToolbarDensity,
|
|
571
|
+
type SchedulerDateJumpProps,
|
|
506
572
|
} from "./composites/scheduler-ui";
|
|
507
573
|
export {
|
|
508
574
|
DEFAULT_SCHEDULER_PREFERENCES,
|
|
509
575
|
SCHEDULER_COLOR_TONES,
|
|
576
|
+
CALENDAR_AGENDA_DAYS,
|
|
577
|
+
calendarVisibleRange,
|
|
510
578
|
} from "./lib/scheduler";
|
|
511
579
|
export type {
|
|
512
580
|
CalendarView,
|
|
581
|
+
CalendarVisibleRange,
|
|
513
582
|
NormalizedEvent,
|
|
514
583
|
SchedulerColorTone,
|
|
515
584
|
SchedulerEvent,
|
|
@@ -521,26 +590,25 @@ export {
|
|
|
521
590
|
CHART_COLOR_VARS,
|
|
522
591
|
chartColor,
|
|
523
592
|
formatChartNumber,
|
|
593
|
+
formatAxisNumber,
|
|
594
|
+
resolveChartRadius,
|
|
595
|
+
categoryLabelGutter,
|
|
596
|
+
fitCategoryLabel,
|
|
524
597
|
seriesDataFromDataset,
|
|
525
598
|
axisDataFromDataset,
|
|
526
599
|
clampZoom,
|
|
527
600
|
DEFAULT_ZOOM,
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
HighlightScope,
|
|
537
|
-
SankeyLink,
|
|
538
|
-
SankeyNode,
|
|
539
|
-
TreeNode,
|
|
540
|
-
} from "./lib/charts";
|
|
541
|
-
export { serializeChartSvg, exportChart, downloadChartSvg, downloadChartPng } from "./lib/chart-export";
|
|
542
|
-
export {
|
|
601
|
+
stackSeries,
|
|
602
|
+
errorBarRange,
|
|
603
|
+
pieLabelLine,
|
|
604
|
+
seriesHasPlottableData,
|
|
605
|
+
serializeChartSvg,
|
|
606
|
+
exportChart,
|
|
607
|
+
downloadChartSvg,
|
|
608
|
+
downloadChartPng,
|
|
543
609
|
ChartContainer,
|
|
610
|
+
ComposedChart,
|
|
611
|
+
ResponsiveContainer,
|
|
544
612
|
ChartSurface,
|
|
545
613
|
ChartsGrid,
|
|
546
614
|
ChartsXAxis,
|
|
@@ -548,19 +616,16 @@ export {
|
|
|
548
616
|
ChartsLegend,
|
|
549
617
|
ChartsToolbar,
|
|
550
618
|
ChartsBrush,
|
|
619
|
+
ChartsCursor,
|
|
620
|
+
ChartsReferenceLine,
|
|
621
|
+
ChartsReferenceArea,
|
|
622
|
+
ChartsReferenceDot,
|
|
623
|
+
ChartsErrorBar,
|
|
551
624
|
BarPlot,
|
|
552
625
|
LinePlot,
|
|
553
626
|
AreaPlot,
|
|
554
627
|
ScatterPlot,
|
|
555
628
|
useChartContext,
|
|
556
|
-
} from "./composites/chart-composition";
|
|
557
|
-
export type {
|
|
558
|
-
ChartContainerProps,
|
|
559
|
-
ComposedSeries,
|
|
560
|
-
ComposedSeriesType,
|
|
561
|
-
HighlightedItem,
|
|
562
|
-
} from "./composites/chart-composition";
|
|
563
|
-
export {
|
|
564
629
|
AreaChart,
|
|
565
630
|
BarChart,
|
|
566
631
|
BoxPlotChart,
|
|
@@ -573,8 +638,60 @@ export {
|
|
|
573
638
|
ScatterChart,
|
|
574
639
|
SparkLineChart,
|
|
575
640
|
WaterfallChart,
|
|
576
|
-
|
|
641
|
+
Gauge,
|
|
642
|
+
LinearGauge,
|
|
643
|
+
PieChart,
|
|
644
|
+
PolarLineChart,
|
|
645
|
+
RadarChart,
|
|
646
|
+
RadialBarChart,
|
|
647
|
+
RadialLineChart,
|
|
648
|
+
ChordChart,
|
|
649
|
+
FunnelChart,
|
|
650
|
+
Heatmap,
|
|
651
|
+
PyramidChart,
|
|
652
|
+
SankeyChart,
|
|
653
|
+
SunburstChart,
|
|
654
|
+
Treemap,
|
|
655
|
+
MapChart,
|
|
656
|
+
BarChart3D,
|
|
657
|
+
PieChart3D,
|
|
658
|
+
ChartDataGrid,
|
|
659
|
+
renderChartCell,
|
|
660
|
+
mercator,
|
|
661
|
+
equirectangular,
|
|
662
|
+
geoPath,
|
|
663
|
+
fitFeatures,
|
|
664
|
+
featureId,
|
|
665
|
+
} from "@spatika/charts";
|
|
577
666
|
export type {
|
|
667
|
+
ChartAxisConfig,
|
|
668
|
+
ChartCurve,
|
|
669
|
+
ChartDataset,
|
|
670
|
+
ChartErrorValue,
|
|
671
|
+
ChartInteraction,
|
|
672
|
+
ChartLegendPosition,
|
|
673
|
+
ChartMargin,
|
|
674
|
+
ChartRadius,
|
|
675
|
+
ChartZoom,
|
|
676
|
+
HighlightScope,
|
|
677
|
+
SankeyLink,
|
|
678
|
+
SankeyNode,
|
|
679
|
+
StackOffset,
|
|
680
|
+
TreeNode,
|
|
681
|
+
ChartContainerProps,
|
|
682
|
+
ComposedSeries,
|
|
683
|
+
ComposedSeriesType,
|
|
684
|
+
HighlightedItem,
|
|
685
|
+
ResponsiveContainerProps,
|
|
686
|
+
ChartHover,
|
|
687
|
+
ChartItemEvent,
|
|
688
|
+
ChartMarkRenderContext,
|
|
689
|
+
ChartReferenceArea,
|
|
690
|
+
ChartReferenceDot,
|
|
691
|
+
ChartReferenceLine,
|
|
692
|
+
ChartTooltipItem,
|
|
693
|
+
ChartTooltipRenderer,
|
|
694
|
+
ChartTooltipTrigger,
|
|
578
695
|
BarChartProps,
|
|
579
696
|
BoxPlotChartProps,
|
|
580
697
|
CandleDatum,
|
|
@@ -591,17 +708,6 @@ export type {
|
|
|
591
708
|
ScatterSeries,
|
|
592
709
|
SparkLineChartProps,
|
|
593
710
|
WaterfallChartProps,
|
|
594
|
-
} from "./composites/cartesian-charts";
|
|
595
|
-
export {
|
|
596
|
-
Gauge,
|
|
597
|
-
LinearGauge,
|
|
598
|
-
PieChart,
|
|
599
|
-
PolarLineChart,
|
|
600
|
-
RadarChart,
|
|
601
|
-
RadialBarChart,
|
|
602
|
-
RadialLineChart,
|
|
603
|
-
} from "./composites/radial-charts";
|
|
604
|
-
export type {
|
|
605
711
|
GaugeProps,
|
|
606
712
|
GaugeSection,
|
|
607
713
|
LinearGaugeProps,
|
|
@@ -612,17 +718,6 @@ export type {
|
|
|
612
718
|
RadarSeries,
|
|
613
719
|
RadialBarChartProps,
|
|
614
720
|
RadialLineChartProps,
|
|
615
|
-
} from "./composites/radial-charts";
|
|
616
|
-
export {
|
|
617
|
-
ChordChart,
|
|
618
|
-
FunnelChart,
|
|
619
|
-
Heatmap,
|
|
620
|
-
PyramidChart,
|
|
621
|
-
SankeyChart,
|
|
622
|
-
SunburstChart,
|
|
623
|
-
Treemap,
|
|
624
|
-
} from "./composites/flow-charts";
|
|
625
|
-
export type {
|
|
626
721
|
ChordChartProps,
|
|
627
722
|
FunnelChartProps,
|
|
628
723
|
FunnelDatum,
|
|
@@ -633,28 +728,16 @@ export type {
|
|
|
633
728
|
SankeyChartProps,
|
|
634
729
|
SunburstChartProps,
|
|
635
730
|
TreemapProps,
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
export type { BarChart3DProps, PieChart3DProps } from "./composites/charts-3d";
|
|
641
|
-
export { ChartDataGrid, renderChartCell } from "./composites/ChartDataGrid";
|
|
642
|
-
export type {
|
|
731
|
+
MapChartProps,
|
|
732
|
+
MapShapeDatum,
|
|
733
|
+
BarChart3DProps,
|
|
734
|
+
PieChart3DProps,
|
|
643
735
|
ChartDataGridProps,
|
|
644
736
|
ChartDataGridRow,
|
|
645
737
|
ChartGridColumn,
|
|
646
738
|
ChartGridColumnType,
|
|
647
|
-
} from "./composites/ChartDataGrid";
|
|
648
|
-
export {
|
|
649
|
-
mercator,
|
|
650
|
-
equirectangular,
|
|
651
|
-
geoPath,
|
|
652
|
-
fitFeatures,
|
|
653
|
-
featureId,
|
|
654
|
-
} from "./lib/geo";
|
|
655
|
-
export type {
|
|
656
739
|
GeoJsonFeature,
|
|
657
740
|
GeoJsonFeatureCollection,
|
|
658
741
|
GeoJsonGeometry,
|
|
659
742
|
GeoProjectionKind,
|
|
660
|
-
} from "
|
|
743
|
+
} from "@spatika/charts";
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
BREAKPOINTS,
|
|
4
|
+
BREAKPOINT_KEYS,
|
|
5
|
+
breakpointBetween,
|
|
6
|
+
breakpointDown,
|
|
7
|
+
breakpointUp,
|
|
8
|
+
} from "./breakpoints";
|
|
9
|
+
|
|
10
|
+
describe("breakpoints", () => {
|
|
11
|
+
it("matches Tailwind viewport widths", () => {
|
|
12
|
+
expect(BREAKPOINTS).toEqual({ xs: 0, sm: 640, md: 768, lg: 1024, xl: 1280 });
|
|
13
|
+
expect(BREAKPOINT_KEYS).toEqual(["xs", "sm", "md", "lg", "xl"]);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("builds min-width and max-width queries", () => {
|
|
17
|
+
expect(breakpointUp("xs")).toBe("(min-width: 0px)");
|
|
18
|
+
expect(breakpointUp("md")).toBe("(min-width: 768px)");
|
|
19
|
+
expect(breakpointDown("md")).toBe("(max-width: 767px)");
|
|
20
|
+
expect(breakpointDown("xl")).toBe("(max-width: 1279px)");
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("builds an inclusive range", () => {
|
|
24
|
+
expect(breakpointBetween("sm", "lg")).toBe(
|
|
25
|
+
"(min-width: 640px) and (max-width: 1023px)",
|
|
26
|
+
);
|
|
27
|
+
expect(breakpointBetween("md")).toBe("(min-width: 768px)");
|
|
28
|
+
});
|
|
29
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** Viewport widths (px) that match Tailwind and Spatika `Grid` / `Container`. */
|
|
2
|
+
export const BREAKPOINTS = {
|
|
3
|
+
xs: 0,
|
|
4
|
+
sm: 640,
|
|
5
|
+
md: 768,
|
|
6
|
+
lg: 1024,
|
|
7
|
+
xl: 1280,
|
|
8
|
+
} as const;
|
|
9
|
+
|
|
10
|
+
export type Breakpoint = keyof typeof BREAKPOINTS;
|
|
11
|
+
|
|
12
|
+
export const BREAKPOINT_KEYS = ["xs", "sm", "md", "lg", "xl"] as const satisfies readonly Breakpoint[];
|
|
13
|
+
|
|
14
|
+
/** `(min-width: Npx)` — inclusive start of a breakpoint. `xs` is always true. */
|
|
15
|
+
export function breakpointUp(key: Breakpoint): string {
|
|
16
|
+
return `(min-width: ${BREAKPOINTS[key]}px)`;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** `(max-width: N-1px)` — viewports strictly below a breakpoint. */
|
|
20
|
+
export function breakpointDown(key: Exclude<Breakpoint, "xs">): string {
|
|
21
|
+
return `(max-width: ${BREAKPOINTS[key] - 1}px)`;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Inclusive range between two breakpoints. `end` omitted means no upper bound. */
|
|
25
|
+
export function breakpointBetween(start: Breakpoint, end?: Exclude<Breakpoint, "xs">): string {
|
|
26
|
+
if (!end) return breakpointUp(start);
|
|
27
|
+
return `${breakpointUp(start)} and ${breakpointDown(end)}`;
|
|
28
|
+
}
|
package/src/lib/chips.ts
CHANGED
|
@@ -56,3 +56,19 @@ export const nativeSelectClass = cn(
|
|
|
56
56
|
"focus:outline-none focus:border-primary/40 focus:ring-2 focus:ring-primary/20",
|
|
57
57
|
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
58
58
|
);
|
|
59
|
+
|
|
60
|
+
export type NativeSelectSize = "sm" | "default" | "touch";
|
|
61
|
+
|
|
62
|
+
/** Size recipes for NativeSelect. `sm` is for toolbars (not full width). */
|
|
63
|
+
export function nativeSelectSizeClass(size: NativeSelectSize = "default") {
|
|
64
|
+
if (size === "sm") {
|
|
65
|
+
return cn(
|
|
66
|
+
nativeSelectClass,
|
|
67
|
+
"mt-0 h-8 min-h-8 w-auto rounded-full px-2 text-[11px] font-semibold",
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
if (size === "touch") {
|
|
71
|
+
return cn(nativeSelectClass, "mt-0 min-h-11");
|
|
72
|
+
}
|
|
73
|
+
return cn(nativeSelectClass, "mt-0");
|
|
74
|
+
}
|