@jalvin/ui 2.0.46 → 2.0.47
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/dist/__tests__/annotated-string.test.d.ts +2 -0
- package/dist/__tests__/annotated-string.test.d.ts.map +1 -0
- package/dist/__tests__/annotated-string.test.js +297 -0
- package/dist/__tests__/annotated-string.test.js.map +1 -0
- package/dist/__tests__/children-signature.test.d.ts +2 -0
- package/dist/__tests__/children-signature.test.d.ts.map +1 -0
- package/dist/__tests__/children-signature.test.js +106 -0
- package/dist/__tests__/children-signature.test.js.map +1 -0
- package/dist/__tests__/interaction.test.d.ts +2 -0
- package/dist/__tests__/interaction.test.d.ts.map +1 -0
- package/dist/__tests__/interaction.test.js +309 -0
- package/dist/__tests__/interaction.test.js.map +1 -0
- package/dist/__tests__/modifier.test.d.ts +2 -0
- package/dist/__tests__/modifier.test.d.ts.map +1 -0
- package/dist/__tests__/modifier.test.js +189 -0
- package/dist/__tests__/modifier.test.js.map +1 -0
- package/dist/__tests__/setup.d.ts +2 -0
- package/dist/__tests__/setup.d.ts.map +1 -0
- package/dist/__tests__/setup.js +2 -0
- package/dist/__tests__/setup.js.map +1 -0
- package/dist/__tests__/text.test.d.ts +2 -0
- package/dist/__tests__/text.test.d.ts.map +1 -0
- package/dist/__tests__/text.test.js +68 -0
- package/dist/__tests__/text.test.js.map +1 -0
- package/dist/__tests__/windowsizeclass.test.d.ts +2 -0
- package/dist/__tests__/windowsizeclass.test.d.ts.map +1 -0
- package/dist/__tests__/windowsizeclass.test.js +132 -0
- package/dist/__tests__/windowsizeclass.test.js.map +1 -0
- package/dist/canvas.d.ts +2 -1
- package/dist/canvas.d.ts.map +1 -1
- package/dist/canvas.js +51 -28
- package/dist/canvas.js.map +1 -1
- package/dist/image.d.ts +6 -4
- package/dist/image.d.ts.map +1 -1
- package/dist/image.js +22 -29
- package/dist/image.js.map +1 -1
- package/dist/layout.d.ts +7 -5
- package/dist/layout.d.ts.map +1 -1
- package/dist/layout.js +9 -3
- package/dist/layout.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from "vitest";
|
|
2
|
+
import { MutableInteractionSource, useMutableInteractionSource, useIsHovered, useIsPressed, useIsFocused, } from "../interaction.js";
|
|
3
|
+
import { render } from "@jalvin/runtime";
|
|
4
|
+
/** Simple helper to test Jalvin hooks in a reactive context. */
|
|
5
|
+
function renderJalvinHook(hook) {
|
|
6
|
+
let lastValue;
|
|
7
|
+
const container = document.createElement("div");
|
|
8
|
+
render(() => {
|
|
9
|
+
lastValue = hook();
|
|
10
|
+
return document.createElement("div");
|
|
11
|
+
}, container);
|
|
12
|
+
return {
|
|
13
|
+
get current() { return lastValue; }
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
// ── MutableInteractionSource ──────────────────────────────────────────────────
|
|
17
|
+
describe("MutableInteractionSource — hover", () => {
|
|
18
|
+
it("starts with no active interactions", () => {
|
|
19
|
+
const s = new MutableInteractionSource();
|
|
20
|
+
expect(s.getInteractions()).toHaveLength(0);
|
|
21
|
+
});
|
|
22
|
+
it("adds hover.enter on _handleMouseEnter", () => {
|
|
23
|
+
const s = new MutableInteractionSource();
|
|
24
|
+
s._handleMouseEnter();
|
|
25
|
+
expect(s.getInteractions()).toHaveLength(1);
|
|
26
|
+
expect(s.getInteractions()[0].type).toBe("hover.enter");
|
|
27
|
+
});
|
|
28
|
+
it("removes hover.enter on _handleMouseLeave", () => {
|
|
29
|
+
const s = new MutableInteractionSource();
|
|
30
|
+
s._handleMouseEnter();
|
|
31
|
+
s._handleMouseLeave();
|
|
32
|
+
expect(s.getInteractions()).toHaveLength(0);
|
|
33
|
+
});
|
|
34
|
+
it("_handleMouseLeave is a no-op when not hovered", () => {
|
|
35
|
+
const s = new MutableInteractionSource();
|
|
36
|
+
s._handleMouseLeave();
|
|
37
|
+
expect(s.getInteractions()).toHaveLength(0);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
describe("MutableInteractionSource — focus", () => {
|
|
41
|
+
it("adds focus.focus on _handleFocus", () => {
|
|
42
|
+
const s = new MutableInteractionSource();
|
|
43
|
+
s._handleFocus();
|
|
44
|
+
expect(s.getInteractions()).toHaveLength(1);
|
|
45
|
+
expect(s.getInteractions()[0].type).toBe("focus.focus");
|
|
46
|
+
});
|
|
47
|
+
it("removes focus.focus on _handleBlur", () => {
|
|
48
|
+
const s = new MutableInteractionSource();
|
|
49
|
+
s._handleFocus();
|
|
50
|
+
s._handleBlur();
|
|
51
|
+
expect(s.getInteractions()).toHaveLength(0);
|
|
52
|
+
});
|
|
53
|
+
it("_handleBlur is a no-op when not focused", () => {
|
|
54
|
+
const s = new MutableInteractionSource();
|
|
55
|
+
s._handleBlur();
|
|
56
|
+
expect(s.getInteractions()).toHaveLength(0);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
describe("MutableInteractionSource — press", () => {
|
|
60
|
+
it("adds press.press on _handleMouseDown", () => {
|
|
61
|
+
const s = new MutableInteractionSource();
|
|
62
|
+
s._handleMouseDown(10, 20);
|
|
63
|
+
expect(s.getInteractions()).toHaveLength(1);
|
|
64
|
+
const i = s.getInteractions()[0];
|
|
65
|
+
expect(i.type).toBe("press.press");
|
|
66
|
+
if (i.type === "press.press") {
|
|
67
|
+
expect(i.x).toBe(10);
|
|
68
|
+
expect(i.y).toBe(20);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
it("removes press.press on _handleMouseUp", () => {
|
|
72
|
+
const s = new MutableInteractionSource();
|
|
73
|
+
s._handleMouseDown(0, 0);
|
|
74
|
+
s._handleMouseUp();
|
|
75
|
+
expect(s.getInteractions()).toHaveLength(0);
|
|
76
|
+
});
|
|
77
|
+
it("removes press.press on _handlePressCancel", () => {
|
|
78
|
+
const s = new MutableInteractionSource();
|
|
79
|
+
s._handleMouseDown(0, 0);
|
|
80
|
+
s._handlePressCancel();
|
|
81
|
+
expect(s.getInteractions()).toHaveLength(0);
|
|
82
|
+
});
|
|
83
|
+
it("_handleMouseUp is a no-op when not pressed", () => {
|
|
84
|
+
const s = new MutableInteractionSource();
|
|
85
|
+
s._handleMouseUp();
|
|
86
|
+
expect(s.getInteractions()).toHaveLength(0);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
describe("MutableInteractionSource — multiple concurrent interactions", () => {
|
|
90
|
+
it("tracks hover and press simultaneously", () => {
|
|
91
|
+
const s = new MutableInteractionSource();
|
|
92
|
+
s._handleMouseEnter();
|
|
93
|
+
s._handleMouseDown(5, 5);
|
|
94
|
+
expect(s.getInteractions()).toHaveLength(2);
|
|
95
|
+
s._handleMouseUp();
|
|
96
|
+
expect(s.getInteractions()).toHaveLength(1);
|
|
97
|
+
expect(s.getInteractions()[0].type).toBe("hover.enter");
|
|
98
|
+
});
|
|
99
|
+
it("tracks hover, focus, and press simultaneously", () => {
|
|
100
|
+
const s = new MutableInteractionSource();
|
|
101
|
+
s._handleMouseEnter();
|
|
102
|
+
s._handleFocus();
|
|
103
|
+
s._handleMouseDown(0, 0);
|
|
104
|
+
expect(s.getInteractions()).toHaveLength(3);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
describe("MutableInteractionSource — subscribe", () => {
|
|
108
|
+
it("notifies listener on every state change", () => {
|
|
109
|
+
const s = new MutableInteractionSource();
|
|
110
|
+
const listener = vi.fn();
|
|
111
|
+
s.subscribe(listener);
|
|
112
|
+
s._handleMouseEnter();
|
|
113
|
+
s._handleMouseLeave();
|
|
114
|
+
expect(listener).toHaveBeenCalledTimes(2);
|
|
115
|
+
});
|
|
116
|
+
it("unsubscribe stops notifications", () => {
|
|
117
|
+
const s = new MutableInteractionSource();
|
|
118
|
+
const listener = vi.fn();
|
|
119
|
+
const unsub = s.subscribe(listener);
|
|
120
|
+
s._handleMouseEnter();
|
|
121
|
+
unsub();
|
|
122
|
+
s._handleMouseLeave();
|
|
123
|
+
expect(listener).toHaveBeenCalledTimes(1);
|
|
124
|
+
});
|
|
125
|
+
it("multiple listeners are all notified", () => {
|
|
126
|
+
const s = new MutableInteractionSource();
|
|
127
|
+
const a = vi.fn();
|
|
128
|
+
const b = vi.fn();
|
|
129
|
+
s.subscribe(a);
|
|
130
|
+
s.subscribe(b);
|
|
131
|
+
s._handleMouseEnter();
|
|
132
|
+
expect(a).toHaveBeenCalledTimes(1);
|
|
133
|
+
expect(b).toHaveBeenCalledTimes(1);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
// ── useMutableInteractionSource ───────────────────────────────────────────────
|
|
137
|
+
describe("useMutableInteractionSource", () => {
|
|
138
|
+
it("returns a MutableInteractionSource", () => {
|
|
139
|
+
const result = renderJalvinHook(() => useMutableInteractionSource());
|
|
140
|
+
expect(result.current).toBeInstanceOf(MutableInteractionSource);
|
|
141
|
+
});
|
|
142
|
+
it("returns the same instance across re-renders", () => {
|
|
143
|
+
// In our vanilla runtime, remember() just returns the value for now,
|
|
144
|
+
// but a real implementation would need to track this.
|
|
145
|
+
// For the sake of this test, we verify current behavior.
|
|
146
|
+
const result = renderJalvinHook(() => useMutableInteractionSource());
|
|
147
|
+
const first = result.current;
|
|
148
|
+
// Force a "re-render" by just calling it again if we were using a real render loop.
|
|
149
|
+
// Since we don't have a way to force re-render from outside easily without state change,
|
|
150
|
+
// we'll just check that it's stable if we did.
|
|
151
|
+
expect(result.current).toBe(first);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
// ── useIsHovered ──────────────────────────────────────────────────────────────
|
|
155
|
+
describe("useIsHovered", () => {
|
|
156
|
+
it("starts as false", () => {
|
|
157
|
+
const source = new MutableInteractionSource();
|
|
158
|
+
const result = renderJalvinHook(() => useIsHovered(source));
|
|
159
|
+
expect(result.current).toBe(false);
|
|
160
|
+
});
|
|
161
|
+
it("becomes true after _handleMouseEnter", () => {
|
|
162
|
+
const source = new MutableInteractionSource();
|
|
163
|
+
const result = renderJalvinHook(() => useIsHovered(source));
|
|
164
|
+
source._handleMouseEnter();
|
|
165
|
+
expect(result.current).toBe(true);
|
|
166
|
+
});
|
|
167
|
+
it("returns to false after _handleMouseLeave", () => {
|
|
168
|
+
const source = new MutableInteractionSource();
|
|
169
|
+
const result = renderJalvinHook(() => useIsHovered(source));
|
|
170
|
+
source._handleMouseEnter();
|
|
171
|
+
source._handleMouseLeave();
|
|
172
|
+
expect(result.current).toBe(false);
|
|
173
|
+
});
|
|
174
|
+
it("reflects pre-existing hover state on mount", () => {
|
|
175
|
+
const source = new MutableInteractionSource();
|
|
176
|
+
source._handleMouseEnter();
|
|
177
|
+
const result = renderJalvinHook(() => useIsHovered(source));
|
|
178
|
+
expect(result.current).toBe(true);
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
// ── useIsFocused ──────────────────────────────────────────────────────────────
|
|
182
|
+
describe("useIsFocused", () => {
|
|
183
|
+
it("starts as false", () => {
|
|
184
|
+
const source = new MutableInteractionSource();
|
|
185
|
+
const result = renderJalvinHook(() => useIsFocused(source));
|
|
186
|
+
expect(result.current).toBe(false);
|
|
187
|
+
});
|
|
188
|
+
it("becomes true after _handleFocus", () => {
|
|
189
|
+
const source = new MutableInteractionSource();
|
|
190
|
+
const result = renderJalvinHook(() => useIsFocused(source));
|
|
191
|
+
source._handleFocus();
|
|
192
|
+
expect(result.current).toBe(true);
|
|
193
|
+
});
|
|
194
|
+
it("returns to false after _handleBlur", () => {
|
|
195
|
+
const source = new MutableInteractionSource();
|
|
196
|
+
const result = renderJalvinHook(() => useIsFocused(source));
|
|
197
|
+
source._handleFocus();
|
|
198
|
+
source._handleBlur();
|
|
199
|
+
expect(result.current).toBe(false);
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
// ── useIsPressed ──────────────────────────────────────────────────────────────
|
|
203
|
+
describe("useIsPressed", () => {
|
|
204
|
+
it("starts as false", () => {
|
|
205
|
+
const source = new MutableInteractionSource();
|
|
206
|
+
const result = renderJalvinHook(() => useIsPressed(source));
|
|
207
|
+
expect(result.current).toBe(false);
|
|
208
|
+
});
|
|
209
|
+
it("becomes true after _handleMouseDown", () => {
|
|
210
|
+
const source = new MutableInteractionSource();
|
|
211
|
+
const result = renderJalvinHook(() => useIsPressed(source));
|
|
212
|
+
source._handleMouseDown(0, 0);
|
|
213
|
+
expect(result.current).toBe(true);
|
|
214
|
+
});
|
|
215
|
+
it("returns to false after _handleMouseUp", () => {
|
|
216
|
+
const source = new MutableInteractionSource();
|
|
217
|
+
const result = renderJalvinHook(() => useIsPressed(source));
|
|
218
|
+
source._handleMouseDown(0, 0);
|
|
219
|
+
source._handleMouseUp();
|
|
220
|
+
expect(result.current).toBe(false);
|
|
221
|
+
});
|
|
222
|
+
it("returns to false after _handlePressCancel", () => {
|
|
223
|
+
const source = new MutableInteractionSource();
|
|
224
|
+
const result = renderJalvinHook(() => useIsPressed(source));
|
|
225
|
+
source._handleMouseDown(0, 0);
|
|
226
|
+
source._handlePressCancel();
|
|
227
|
+
expect(result.current).toBe(false);
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
// ── MutableInteractionSource — touch ─────────────────────────────────────────
|
|
231
|
+
describe("MutableInteractionSource — touch (_handleTouchStart)", () => {
|
|
232
|
+
it("adds hover.enter and press.press on touch start", () => {
|
|
233
|
+
const s = new MutableInteractionSource();
|
|
234
|
+
s._handleTouchStart(10, 20);
|
|
235
|
+
const types = s.getInteractions().map(i => i.type);
|
|
236
|
+
expect(types).toContain("hover.enter");
|
|
237
|
+
expect(types).toContain("press.press");
|
|
238
|
+
expect(s.getInteractions()).toHaveLength(2);
|
|
239
|
+
});
|
|
240
|
+
it("records the correct touch coordinates", () => {
|
|
241
|
+
const s = new MutableInteractionSource();
|
|
242
|
+
s._handleTouchStart(42, 84);
|
|
243
|
+
const press = s.getInteractions().find(i => i.type === "press.press");
|
|
244
|
+
expect(press).toBeDefined();
|
|
245
|
+
if (press?.type === "press.press") {
|
|
246
|
+
expect(press.x).toBe(42);
|
|
247
|
+
expect(press.y).toBe(84);
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
it("does not add a second hover.enter if already hovered", () => {
|
|
251
|
+
const s = new MutableInteractionSource();
|
|
252
|
+
s._handleMouseEnter(); // already hovered
|
|
253
|
+
s._handleTouchStart(0, 0);
|
|
254
|
+
const hoverEntries = s.getInteractions().filter(i => i.type === "hover.enter");
|
|
255
|
+
expect(hoverEntries).toHaveLength(1);
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
describe("MutableInteractionSource — touch (_handleTouchEnd)", () => {
|
|
259
|
+
it("clears both press and hover on touch end", () => {
|
|
260
|
+
const s = new MutableInteractionSource();
|
|
261
|
+
s._handleTouchStart(0, 0);
|
|
262
|
+
s._handleTouchEnd();
|
|
263
|
+
expect(s.getInteractions()).toHaveLength(0);
|
|
264
|
+
});
|
|
265
|
+
it("is a no-op when called without a preceding touch start", () => {
|
|
266
|
+
const s = new MutableInteractionSource();
|
|
267
|
+
s._handleTouchEnd();
|
|
268
|
+
expect(s.getInteractions()).toHaveLength(0);
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
describe("MutableInteractionSource — touch (_handleTouchCancel)", () => {
|
|
272
|
+
it("clears both press and hover on touch cancel", () => {
|
|
273
|
+
const s = new MutableInteractionSource();
|
|
274
|
+
s._handleTouchStart(0, 0);
|
|
275
|
+
s._handleTouchCancel();
|
|
276
|
+
expect(s.getInteractions()).toHaveLength(0);
|
|
277
|
+
});
|
|
278
|
+
it("is a no-op when called without a preceding touch start", () => {
|
|
279
|
+
const s = new MutableInteractionSource();
|
|
280
|
+
s._handleTouchCancel();
|
|
281
|
+
expect(s.getInteractions()).toHaveLength(0);
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
describe("MutableInteractionSource — touch (hooks)", () => {
|
|
285
|
+
it("useIsPressed becomes true on touch start and false on touch end", () => {
|
|
286
|
+
const source = new MutableInteractionSource();
|
|
287
|
+
const result = renderJalvinHook(() => useIsPressed(source));
|
|
288
|
+
source._handleTouchStart(0, 0);
|
|
289
|
+
expect(result.current).toBe(true);
|
|
290
|
+
source._handleTouchEnd();
|
|
291
|
+
expect(result.current).toBe(false);
|
|
292
|
+
});
|
|
293
|
+
it("useIsHovered becomes true on touch start and false on touch end", () => {
|
|
294
|
+
const source = new MutableInteractionSource();
|
|
295
|
+
const result = renderJalvinHook(() => useIsHovered(source));
|
|
296
|
+
source._handleTouchStart(0, 0);
|
|
297
|
+
expect(result.current).toBe(true);
|
|
298
|
+
source._handleTouchEnd();
|
|
299
|
+
expect(result.current).toBe(false);
|
|
300
|
+
});
|
|
301
|
+
it("useIsPressed becomes false on touch cancel", () => {
|
|
302
|
+
const source = new MutableInteractionSource();
|
|
303
|
+
const result = renderJalvinHook(() => useIsPressed(source));
|
|
304
|
+
source._handleTouchStart(0, 0);
|
|
305
|
+
source._handleTouchCancel();
|
|
306
|
+
expect(result.current).toBe(false);
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
//# sourceMappingURL=interaction.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interaction.test.js","sourceRoot":"","sources":["../../src/__tests__/interaction.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modifier.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/modifier.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { Modifier } from "../modifier.js";
|
|
3
|
+
import { MutableInteractionSource } from "../interaction.js";
|
|
4
|
+
// ── Basic styles (regression guard) ──────────────────────────────────────────
|
|
5
|
+
describe("Modifier — basic styles", () => {
|
|
6
|
+
it("Default produces empty props", () => {
|
|
7
|
+
const props = Modifier.Default.toProps();
|
|
8
|
+
expect(props.style).toBeUndefined();
|
|
9
|
+
expect(props.className).toBeUndefined();
|
|
10
|
+
});
|
|
11
|
+
it("fillMaxWidth sets width 100%", () => {
|
|
12
|
+
expect(Modifier.fillMaxWidth().toProps().style?.width).toBe("100%");
|
|
13
|
+
});
|
|
14
|
+
it("padding with number appends px", () => {
|
|
15
|
+
expect(Modifier.padding(16).toProps().style?.padding).toBe("16px");
|
|
16
|
+
});
|
|
17
|
+
it("padding with string passes through", () => {
|
|
18
|
+
expect(Modifier.padding("1rem").toProps().style?.padding).toBe("1rem");
|
|
19
|
+
});
|
|
20
|
+
it("background sets backgroundColor", () => {
|
|
21
|
+
expect(Modifier.background("#fff").toProps().style?.backgroundColor).toBe("#fff");
|
|
22
|
+
});
|
|
23
|
+
it("className is recorded", () => {
|
|
24
|
+
expect(Modifier.className("foo").toProps().className).toBe("foo");
|
|
25
|
+
});
|
|
26
|
+
it("then() merges styles, later wins", () => {
|
|
27
|
+
const m = Modifier.background("#aaa").then(Modifier.background("#bbb"));
|
|
28
|
+
expect(m.toProps().style?.backgroundColor).toBe("#bbb");
|
|
29
|
+
});
|
|
30
|
+
it("then() concatenates classNames", () => {
|
|
31
|
+
const m = Modifier.className("a").then(Modifier.className("b"));
|
|
32
|
+
expect(m.toProps().className).toBe("a b");
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
// ── hoverable ─────────────────────────────────────────────────────────────────
|
|
36
|
+
describe("Modifier.hoverable", () => {
|
|
37
|
+
it("toProps exposes onMouseEnter and onMouseLeave", () => {
|
|
38
|
+
const source = new MutableInteractionSource();
|
|
39
|
+
const props = Modifier.hoverable(source).toProps();
|
|
40
|
+
expect(typeof props.onMouseEnter).toBe("function");
|
|
41
|
+
expect(typeof props.onMouseLeave).toBe("function");
|
|
42
|
+
});
|
|
43
|
+
it("onMouseEnter triggers _handleMouseEnter on the source", () => {
|
|
44
|
+
const source = new MutableInteractionSource();
|
|
45
|
+
const { onMouseEnter } = Modifier.hoverable(source).toProps();
|
|
46
|
+
onMouseEnter();
|
|
47
|
+
expect(source.getInteractions()[0]?.type).toBe("hover.enter");
|
|
48
|
+
});
|
|
49
|
+
it("onMouseLeave triggers _handleMouseLeave on the source", () => {
|
|
50
|
+
const source = new MutableInteractionSource();
|
|
51
|
+
const { onMouseEnter, onMouseLeave } = Modifier.hoverable(source).toProps();
|
|
52
|
+
onMouseEnter();
|
|
53
|
+
onMouseLeave();
|
|
54
|
+
expect(source.getInteractions()).toHaveLength(0);
|
|
55
|
+
});
|
|
56
|
+
it("does not expose focus or press handlers", () => {
|
|
57
|
+
const source = new MutableInteractionSource();
|
|
58
|
+
const props = Modifier.hoverable(source).toProps();
|
|
59
|
+
expect(props.onFocus).toBeUndefined();
|
|
60
|
+
expect(props.onBlur).toBeUndefined();
|
|
61
|
+
expect(props.onMouseDown).toBeUndefined();
|
|
62
|
+
expect(props.onMouseUp).toBeUndefined();
|
|
63
|
+
});
|
|
64
|
+
it("static factory produces same result as instance method", () => {
|
|
65
|
+
const source = new MutableInteractionSource();
|
|
66
|
+
const a = Modifier.hoverable(source).toProps();
|
|
67
|
+
const b = Modifier.Default.hoverable(source).toProps();
|
|
68
|
+
expect(typeof a.onMouseEnter).toBe(typeof b.onMouseEnter);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
// ── focusable ─────────────────────────────────────────────────────────────────
|
|
72
|
+
describe("Modifier.focusable", () => {
|
|
73
|
+
it("toProps exposes onFocus and onBlur", () => {
|
|
74
|
+
const source = new MutableInteractionSource();
|
|
75
|
+
const props = Modifier.focusable(source).toProps();
|
|
76
|
+
expect(typeof props.onFocus).toBe("function");
|
|
77
|
+
expect(typeof props.onBlur).toBe("function");
|
|
78
|
+
});
|
|
79
|
+
it("onFocus triggers _handleFocus", () => {
|
|
80
|
+
const source = new MutableInteractionSource();
|
|
81
|
+
const { onFocus } = Modifier.focusable(source).toProps();
|
|
82
|
+
onFocus();
|
|
83
|
+
expect(source.getInteractions()[0]?.type).toBe("focus.focus");
|
|
84
|
+
});
|
|
85
|
+
it("onBlur triggers _handleBlur", () => {
|
|
86
|
+
const source = new MutableInteractionSource();
|
|
87
|
+
const { onFocus, onBlur } = Modifier.focusable(source).toProps();
|
|
88
|
+
onFocus();
|
|
89
|
+
onBlur();
|
|
90
|
+
expect(source.getInteractions()).toHaveLength(0);
|
|
91
|
+
});
|
|
92
|
+
it("does not expose hover or press handlers", () => {
|
|
93
|
+
const source = new MutableInteractionSource();
|
|
94
|
+
const props = Modifier.focusable(source).toProps();
|
|
95
|
+
expect(props.onMouseEnter).toBeUndefined();
|
|
96
|
+
expect(props.onMouseLeave).toBeUndefined();
|
|
97
|
+
expect(props.onMouseDown).toBeUndefined();
|
|
98
|
+
expect(props.onMouseUp).toBeUndefined();
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
// ── pressable ─────────────────────────────────────────────────────────────────
|
|
102
|
+
describe("Modifier.pressable", () => {
|
|
103
|
+
it("toProps exposes onMouseDown and onMouseUp", () => {
|
|
104
|
+
const source = new MutableInteractionSource();
|
|
105
|
+
const props = Modifier.pressable(source).toProps();
|
|
106
|
+
expect(typeof props.onMouseDown).toBe("function");
|
|
107
|
+
expect(typeof props.onMouseUp).toBe("function");
|
|
108
|
+
});
|
|
109
|
+
it("onMouseDown triggers _handleMouseDown with coordinates", () => {
|
|
110
|
+
const source = new MutableInteractionSource();
|
|
111
|
+
const { onMouseDown } = Modifier.pressable(source).toProps();
|
|
112
|
+
onMouseDown({ clientX: 42, clientY: 7 });
|
|
113
|
+
const i = source.getInteractions()[0];
|
|
114
|
+
expect(i.type).toBe("press.press");
|
|
115
|
+
if (i.type === "press.press") {
|
|
116
|
+
expect(i.x).toBe(42);
|
|
117
|
+
expect(i.y).toBe(7);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
it("onMouseUp triggers _handleMouseUp", () => {
|
|
121
|
+
const source = new MutableInteractionSource();
|
|
122
|
+
const { onMouseDown, onMouseUp } = Modifier.pressable(source).toProps();
|
|
123
|
+
onMouseDown({ clientX: 0, clientY: 0 });
|
|
124
|
+
onMouseUp();
|
|
125
|
+
expect(source.getInteractions()).toHaveLength(0);
|
|
126
|
+
});
|
|
127
|
+
it("onMouseLeave also cancels the press", () => {
|
|
128
|
+
const source = new MutableInteractionSource();
|
|
129
|
+
const { onMouseDown, onMouseLeave } = Modifier.pressable(source).toProps();
|
|
130
|
+
onMouseDown({ clientX: 0, clientY: 0 });
|
|
131
|
+
onMouseLeave();
|
|
132
|
+
expect(source.getInteractions()).toHaveLength(0);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
// ── combining modifiers on one source ─────────────────────────────────────────
|
|
136
|
+
describe("Modifier — combining hoverable + focusable + pressable on one source", () => {
|
|
137
|
+
it("all three handlers are present", () => {
|
|
138
|
+
const source = new MutableInteractionSource();
|
|
139
|
+
const props = Modifier.hoverable(source).focusable(source).pressable(source).toProps();
|
|
140
|
+
expect(typeof props.onMouseEnter).toBe("function");
|
|
141
|
+
expect(typeof props.onMouseLeave).toBe("function");
|
|
142
|
+
expect(typeof props.onFocus).toBe("function");
|
|
143
|
+
expect(typeof props.onBlur).toBe("function");
|
|
144
|
+
expect(typeof props.onMouseDown).toBe("function");
|
|
145
|
+
expect(typeof props.onMouseUp).toBe("function");
|
|
146
|
+
});
|
|
147
|
+
it("onMouseLeave cancels both hover and press when both are active", () => {
|
|
148
|
+
const source = new MutableInteractionSource();
|
|
149
|
+
const props = Modifier.hoverable(source).pressable(source).toProps();
|
|
150
|
+
props.onMouseEnter();
|
|
151
|
+
props.onMouseDown({ clientX: 0, clientY: 0 });
|
|
152
|
+
expect(source.getInteractions()).toHaveLength(2);
|
|
153
|
+
props.onMouseLeave();
|
|
154
|
+
expect(source.getInteractions()).toHaveLength(0);
|
|
155
|
+
});
|
|
156
|
+
it("interaction source is preserved through style chain", () => {
|
|
157
|
+
const source = new MutableInteractionSource();
|
|
158
|
+
const props = Modifier.hoverable(source).background("#fff").padding(8).toProps();
|
|
159
|
+
expect(typeof props.onMouseEnter).toBe("function");
|
|
160
|
+
expect(props.style?.backgroundColor).toBe("#fff");
|
|
161
|
+
expect(props.style?.padding).toBe("8px");
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
// ── then() with interaction sources ──────────────────────────────────────────
|
|
165
|
+
describe("Modifier.then — interaction source merging", () => {
|
|
166
|
+
it("then() inherits interaction source from left when right has none", () => {
|
|
167
|
+
const source = new MutableInteractionSource();
|
|
168
|
+
const merged = Modifier.hoverable(source).then(Modifier.background("#fff"));
|
|
169
|
+
const props = merged.toProps();
|
|
170
|
+
expect(typeof props.onMouseEnter).toBe("function");
|
|
171
|
+
});
|
|
172
|
+
it("then() prefers right-hand interaction source", () => {
|
|
173
|
+
const a = new MutableInteractionSource();
|
|
174
|
+
const b = new MutableInteractionSource();
|
|
175
|
+
const merged = Modifier.hoverable(a).then(Modifier.hoverable(b));
|
|
176
|
+
const props = merged.toProps();
|
|
177
|
+
props.onMouseEnter();
|
|
178
|
+
expect(b.getInteractions()[0]?.type).toBe("hover.enter");
|
|
179
|
+
expect(a.getInteractions()).toHaveLength(0);
|
|
180
|
+
});
|
|
181
|
+
it("then() merges flags from both sides", () => {
|
|
182
|
+
const source = new MutableInteractionSource();
|
|
183
|
+
const merged = Modifier.hoverable(source).then(Modifier.focusable(source));
|
|
184
|
+
const props = merged.toProps();
|
|
185
|
+
expect(typeof props.onMouseEnter).toBe("function");
|
|
186
|
+
expect(typeof props.onFocus).toBe("function");
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
//# sourceMappingURL=modifier.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modifier.test.js","sourceRoot":"","sources":["../../src/__tests__/modifier.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/__tests__/setup.ts"],"names":[],"mappings":"AAAA,OAAO,2BAA2B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/__tests__/setup.ts"],"names":[],"mappings":"AAAA,OAAO,2BAA2B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/text.test.ts"],"names":[],"mappings":"AAEA,OAAO,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { screen } from "@testing-library/dom";
|
|
3
|
+
import "@testing-library/jest-dom";
|
|
4
|
+
import { Text } from "../text.js";
|
|
5
|
+
import { TextStyle } from "../typography.js";
|
|
6
|
+
/** Helper to render a node to the document body for testing. */
|
|
7
|
+
function render(node) {
|
|
8
|
+
document.body.innerHTML = "";
|
|
9
|
+
document.body.appendChild(node);
|
|
10
|
+
return { container: document.body };
|
|
11
|
+
}
|
|
12
|
+
describe("Text", () => {
|
|
13
|
+
it("renders a span by default", () => {
|
|
14
|
+
const { container } = render(Text({ text: "hello" }));
|
|
15
|
+
expect(container.querySelector("span")).not.toBeNull();
|
|
16
|
+
});
|
|
17
|
+
it("renders text from the text prop", () => {
|
|
18
|
+
render(Text({ text: "hello world" }));
|
|
19
|
+
expect(screen.getByText("hello world")).toBeTruthy();
|
|
20
|
+
});
|
|
21
|
+
it("renders text from children", () => {
|
|
22
|
+
render(Text({ children: [document.createTextNode("from children")] }));
|
|
23
|
+
expect(screen.getByText("from children")).toBeTruthy();
|
|
24
|
+
});
|
|
25
|
+
it("text prop takes priority over children when both provided", () => {
|
|
26
|
+
render(Text({ text: "explicit", children: [document.createTextNode("child")] }));
|
|
27
|
+
expect(screen.getByText("explicit")).toBeTruthy();
|
|
28
|
+
expect(screen.queryByText("child")).toBeNull();
|
|
29
|
+
});
|
|
30
|
+
it("applies color prop as inline style", () => {
|
|
31
|
+
const { container } = render(Text({ text: "hi", color: "red" }));
|
|
32
|
+
const el = container.querySelector("span");
|
|
33
|
+
expect(el.style.color).toBe("red");
|
|
34
|
+
});
|
|
35
|
+
it("applies TextStyle.headlineLarge typography via style prop", () => {
|
|
36
|
+
const { container } = render(Text({ text: "headline", style: TextStyle.headlineLarge }));
|
|
37
|
+
const el = container.querySelector("span");
|
|
38
|
+
expect(el.style.fontSize).toBe("32px");
|
|
39
|
+
expect(el.style.lineHeight).toBe("40px");
|
|
40
|
+
});
|
|
41
|
+
it("applies TextStyle.bodyLarge via style prop", () => {
|
|
42
|
+
const { container } = render(Text({ text: "body", style: TextStyle.bodyLarge }));
|
|
43
|
+
const el = container.querySelector("span");
|
|
44
|
+
expect(el.style.fontSize).toBe("16px");
|
|
45
|
+
});
|
|
46
|
+
it("applies maxLines clamp styles", () => {
|
|
47
|
+
const { container } = render(Text({ text: "clamp me", maxLines: 2 }));
|
|
48
|
+
const el = container.querySelector("span");
|
|
49
|
+
expect(el.style.overflow).toBe("hidden");
|
|
50
|
+
expect(el.style.webkitLineClamp).toBe("2");
|
|
51
|
+
});
|
|
52
|
+
it("color prop overrides style color", () => {
|
|
53
|
+
const { container } = render(Text({
|
|
54
|
+
text: "hi",
|
|
55
|
+
style: { fontSize: "1rem", fontWeight: 400, lineHeight: "1.5rem", color: "blue" },
|
|
56
|
+
color: "green",
|
|
57
|
+
}));
|
|
58
|
+
const el = container.querySelector("span");
|
|
59
|
+
expect(el.style.color).toBe("green");
|
|
60
|
+
});
|
|
61
|
+
it("does not render any tag other than span", () => {
|
|
62
|
+
const { container } = render(Text({ text: "x" }));
|
|
63
|
+
expect(container.querySelector("p")).toBeNull();
|
|
64
|
+
expect(container.querySelector("h1")).toBeNull();
|
|
65
|
+
expect(container.querySelector("pre")).toBeNull();
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
//# sourceMappingURL=text.test.js.map
|