@jalvin/ui 2.0.43 → 2.0.45

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 (80) hide show
  1. package/dist/annotated-string.d.ts +2 -4
  2. package/dist/annotated-string.d.ts.map +1 -1
  3. package/dist/annotated-string.js +19 -17
  4. package/dist/annotated-string.js.map +1 -1
  5. package/dist/button.d.ts +2 -3
  6. package/dist/button.d.ts.map +1 -1
  7. package/dist/button.js +8 -12
  8. package/dist/button.js.map +1 -1
  9. package/dist/canvas.d.ts +3 -3
  10. package/dist/canvas.d.ts.map +1 -1
  11. package/dist/canvas.js +31 -40
  12. package/dist/canvas.js.map +1 -1
  13. package/dist/checkbox.d.ts +1 -2
  14. package/dist/checkbox.d.ts.map +1 -1
  15. package/dist/checkbox.js +18 -11
  16. package/dist/checkbox.js.map +1 -1
  17. package/dist/image.d.ts +4 -6
  18. package/dist/image.d.ts.map +1 -1
  19. package/dist/image.js +32 -21
  20. package/dist/image.js.map +1 -1
  21. package/dist/index.d.ts +15 -14
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +17 -19
  24. package/dist/index.js.map +1 -1
  25. package/dist/input.d.ts +1 -3
  26. package/dist/input.d.ts.map +1 -1
  27. package/dist/input.js +20 -13
  28. package/dist/input.js.map +1 -1
  29. package/dist/interaction.d.ts.map +1 -1
  30. package/dist/interaction.js +9 -27
  31. package/dist/interaction.js.map +1 -1
  32. package/dist/layout.d.ts +3 -7
  33. package/dist/layout.d.ts.map +1 -1
  34. package/dist/layout.js +10 -10
  35. package/dist/layout.js.map +1 -1
  36. package/dist/spacer.d.ts +2 -3
  37. package/dist/spacer.d.ts.map +1 -1
  38. package/dist/spacer.js +5 -5
  39. package/dist/spacer.js.map +1 -1
  40. package/dist/surface.d.ts +9 -10
  41. package/dist/surface.d.ts.map +1 -1
  42. package/dist/surface.js +30 -13
  43. package/dist/surface.js.map +1 -1
  44. package/dist/text.d.ts +3 -5
  45. package/dist/text.d.ts.map +1 -1
  46. package/dist/text.js +23 -12
  47. package/dist/text.js.map +1 -1
  48. package/dist/textarea.d.ts +1 -3
  49. package/dist/textarea.d.ts.map +1 -1
  50. package/dist/textarea.js +20 -13
  51. package/dist/textarea.js.map +1 -1
  52. package/dist/typography.d.ts +101 -129
  53. package/dist/typography.d.ts.map +1 -1
  54. package/dist/typography.js +29 -25
  55. package/dist/typography.js.map +1 -1
  56. package/package.json +1 -1
  57. package/dist/__tests__/annotated-string.test.d.ts +0 -2
  58. package/dist/__tests__/annotated-string.test.d.ts.map +0 -1
  59. package/dist/__tests__/annotated-string.test.js +0 -310
  60. package/dist/__tests__/annotated-string.test.js.map +0 -1
  61. package/dist/__tests__/interaction.test.d.ts +0 -2
  62. package/dist/__tests__/interaction.test.d.ts.map +0 -1
  63. package/dist/__tests__/interaction.test.js +0 -292
  64. package/dist/__tests__/interaction.test.js.map +0 -1
  65. package/dist/__tests__/modifier.test.d.ts +0 -2
  66. package/dist/__tests__/modifier.test.d.ts.map +0 -1
  67. package/dist/__tests__/modifier.test.js +0 -189
  68. package/dist/__tests__/modifier.test.js.map +0 -1
  69. package/dist/__tests__/setup.d.ts +0 -2
  70. package/dist/__tests__/setup.d.ts.map +0 -1
  71. package/dist/__tests__/setup.js +0 -2
  72. package/dist/__tests__/setup.js.map +0 -1
  73. package/dist/__tests__/text.test.d.ts +0 -2
  74. package/dist/__tests__/text.test.d.ts.map +0 -1
  75. package/dist/__tests__/text.test.js +0 -62
  76. package/dist/__tests__/text.test.js.map +0 -1
  77. package/dist/__tests__/windowsizeclass.test.d.ts +0 -2
  78. package/dist/__tests__/windowsizeclass.test.d.ts.map +0 -1
  79. package/dist/__tests__/windowsizeclass.test.js +0 -141
  80. package/dist/__tests__/windowsizeclass.test.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"annotated-string.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/annotated-string.test.tsx"],"names":[],"mappings":""}
@@ -1,310 +0,0 @@
1
- import React from "react";
2
- import { describe, it, expect, vi } from "vitest";
3
- import { render, screen, fireEvent } from "@testing-library/react";
4
- import { buildAnnotatedString, LinkAnnotation, TextDecoration, renderAnnotatedString, } from "../annotated-string.js";
5
- import { Text } from "../text.js";
6
- // ---------------------------------------------------------------------------
7
- // TextDecoration
8
- // ---------------------------------------------------------------------------
9
- describe("TextDecoration", () => {
10
- it("None produces no CSS value", () => {
11
- expect(TextDecoration.None.toCSSValue()).toBeUndefined();
12
- });
13
- it("Underline produces 'underline'", () => {
14
- expect(TextDecoration.Underline.toCSSValue()).toBe("underline");
15
- });
16
- it("LineThrough produces 'line-through'", () => {
17
- expect(TextDecoration.LineThrough.toCSSValue()).toBe("line-through");
18
- });
19
- it("Underline + LineThrough produces 'underline line-through'", () => {
20
- const combined = TextDecoration.Underline.plus(TextDecoration.LineThrough);
21
- expect(combined.toCSSValue()).toBe("underline line-through");
22
- });
23
- it("combining with None is a no-op", () => {
24
- const combined = TextDecoration.Underline.plus(TextDecoration.None);
25
- expect(combined.toCSSValue()).toBe("underline");
26
- });
27
- });
28
- // ---------------------------------------------------------------------------
29
- // buildAnnotatedString — builder mechanics
30
- // ---------------------------------------------------------------------------
31
- describe("buildAnnotatedString — builder mechanics", () => {
32
- it("produces plain text with no spans", () => {
33
- const ann = buildAnnotatedString(b => b.append("hello"));
34
- expect(ann.text).toBe("hello");
35
- expect(ann.spanStyles).toHaveLength(0);
36
- expect(ann.linkAnnotations).toHaveLength(0);
37
- });
38
- it("records correct start/end for withStyle", () => {
39
- const ann = buildAnnotatedString(b => {
40
- b.append("ab");
41
- b.withStyle({ color: "red" }, () => b.append("cd"));
42
- b.append("ef");
43
- });
44
- expect(ann.text).toBe("abcdef");
45
- const span = ann.spanStyles[0];
46
- expect(span.start).toBe(2);
47
- expect(span.end).toBe(4);
48
- expect(span.item.color).toBe("red");
49
- });
50
- it("records correct start/end for withLink (Url)", () => {
51
- const ann = buildAnnotatedString(b => {
52
- b.append("go ");
53
- b.withLink(LinkAnnotation.Url("https://example.com"), () => b.append("here"));
54
- });
55
- expect(ann.text).toBe("go here");
56
- const link = ann.linkAnnotations[0];
57
- expect(link.start).toBe(3);
58
- expect(link.end).toBe(7);
59
- expect(link.item.type).toBe("url");
60
- });
61
- it("records correct start/end for withLink (Clickable)", () => {
62
- const onClick = vi.fn();
63
- const ann = buildAnnotatedString(b => {
64
- b.withLink(LinkAnnotation.Clickable("tag1", onClick), () => b.append("click me"));
65
- });
66
- const link = ann.linkAnnotations[0];
67
- expect(link.start).toBe(0);
68
- expect(link.end).toBe(8);
69
- expect(link.item.type).toBe("clickable");
70
- });
71
- it("addStyle applies span to an explicit range", () => {
72
- const ann = buildAnnotatedString(b => {
73
- b.append("hello world");
74
- b.addStyle({ fontWeight: "bold" }, 6, 11);
75
- });
76
- const span = ann.spanStyles[0];
77
- expect(span.start).toBe(6);
78
- expect(span.end).toBe(11);
79
- expect(span.item.fontWeight).toBe("bold");
80
- });
81
- it("addLink applies a link to an explicit range", () => {
82
- const ann = buildAnnotatedString(b => {
83
- b.append("visit docs now");
84
- b.addLink(LinkAnnotation.Url("https://docs.example.com"), 6, 10);
85
- });
86
- const link = ann.linkAnnotations[0];
87
- expect(link.start).toBe(6);
88
- expect(link.end).toBe(10);
89
- });
90
- it("appending another AnnotatedString shifts offsets correctly", () => {
91
- const inner = buildAnnotatedString(b => {
92
- b.withStyle({ color: "blue" }, () => b.append("blue"));
93
- });
94
- const outer = buildAnnotatedString(b => {
95
- b.append("abc ");
96
- b.append(inner);
97
- });
98
- expect(outer.text).toBe("abc blue");
99
- const span = outer.spanStyles[0];
100
- expect(span.start).toBe(4);
101
- expect(span.end).toBe(8);
102
- });
103
- it("nested withStyle pushes two spans", () => {
104
- const ann = buildAnnotatedString(b => {
105
- b.withStyle({ fontWeight: "bold" }, () => {
106
- b.withStyle({ color: "red" }, () => b.append("x"));
107
- });
108
- });
109
- expect(ann.spanStyles).toHaveLength(2);
110
- });
111
- it("unclosed pushStyle is flushed on build", () => {
112
- const ann = buildAnnotatedString(b => {
113
- b.pushStyle({ color: "green" });
114
- b.append("test");
115
- // no pop() — build() should flush it
116
- });
117
- expect(ann.spanStyles).toHaveLength(1);
118
- expect(ann.spanStyles[0].end).toBe(4);
119
- });
120
- it("multiple sequential appends produce correct full text", () => {
121
- const ann = buildAnnotatedString(b => {
122
- b.append("one");
123
- b.append(" ");
124
- b.append("two");
125
- });
126
- expect(ann.text).toBe("one two");
127
- });
128
- });
129
- // ---------------------------------------------------------------------------
130
- // LinkAnnotation factory
131
- // ---------------------------------------------------------------------------
132
- describe("LinkAnnotation", () => {
133
- it("Url stores url and type", () => {
134
- const link = LinkAnnotation.Url("https://example.com");
135
- expect(link.type).toBe("url");
136
- if (link.type === "url")
137
- expect(link.url).toBe("https://example.com");
138
- });
139
- it("Url accepts optional styles", () => {
140
- const styles = { style: { color: "#00f" } };
141
- const link = LinkAnnotation.Url("https://a.com", styles);
142
- expect(link.styles).toBe(styles);
143
- });
144
- it("Clickable stores tag, type, and callback", () => {
145
- const fn = vi.fn();
146
- const link = LinkAnnotation.Clickable("my-tag", fn);
147
- expect(link.type).toBe("clickable");
148
- if (link.type === "clickable") {
149
- expect(link.tag).toBe("my-tag");
150
- expect(link.onClick).toBe(fn);
151
- }
152
- });
153
- });
154
- // ---------------------------------------------------------------------------
155
- // renderAnnotatedString
156
- // ---------------------------------------------------------------------------
157
- describe("renderAnnotatedString", () => {
158
- it("returns a single string node for plain text with no spans", () => {
159
- const ann = buildAnnotatedString(b => b.append("plain"));
160
- const nodes = renderAnnotatedString(ann);
161
- // Filters out nulls; for unstyled plain text a bare string is returned
162
- const text = nodes.join("");
163
- expect(text).toBe("plain");
164
- });
165
- it("renders a Url link as an <a> tag", () => {
166
- const ann = buildAnnotatedString(b => {
167
- b.withLink(LinkAnnotation.Url("https://example.com"), () => b.append("click"));
168
- });
169
- const { container } = render(React.createElement("span", null, ...renderAnnotatedString(ann)));
170
- const a = container.querySelector("a");
171
- expect(a).not.toBeNull();
172
- expect(a.href).toBe("https://example.com/");
173
- expect(a.target).toBe("_blank");
174
- expect(a.rel).toContain("noopener");
175
- expect(a.textContent).toBe("click");
176
- });
177
- it("renders a Clickable link as a <span role=link>", () => {
178
- const onClick = vi.fn();
179
- const ann = buildAnnotatedString(b => {
180
- b.withLink(LinkAnnotation.Clickable("open", onClick), () => b.append("open dialog"));
181
- });
182
- const { container } = render(React.createElement("span", null, ...renderAnnotatedString(ann)));
183
- const el = container.querySelector('[role="link"]');
184
- expect(el).not.toBeNull();
185
- expect(el.textContent).toBe("open dialog");
186
- });
187
- it("fires the onClick callback when a Clickable link is clicked", () => {
188
- const onClick = vi.fn();
189
- const ann = buildAnnotatedString(b => {
190
- b.withLink(LinkAnnotation.Clickable("my-tag", onClick), () => b.append("press"));
191
- });
192
- const { container } = render(React.createElement("span", null, ...renderAnnotatedString(ann)));
193
- const el = container.querySelector('[role="link"]');
194
- fireEvent.click(el);
195
- expect(onClick).toHaveBeenCalledOnce();
196
- expect(onClick).toHaveBeenCalledWith("my-tag");
197
- });
198
- it("fires the onClick callback on Enter keydown", () => {
199
- const onClick = vi.fn();
200
- const ann = buildAnnotatedString(b => {
201
- b.withLink(LinkAnnotation.Clickable("tag", onClick), () => b.append("press"));
202
- });
203
- const { container } = render(React.createElement("span", null, ...renderAnnotatedString(ann)));
204
- const el = container.querySelector('[role="link"]');
205
- fireEvent.keyDown(el, { key: "Enter" });
206
- expect(onClick).toHaveBeenCalledOnce();
207
- });
208
- it("fires the onClick callback on Space keydown", () => {
209
- const onClick = vi.fn();
210
- const ann = buildAnnotatedString(b => {
211
- b.withLink(LinkAnnotation.Clickable("tag", onClick), () => b.append("press"));
212
- });
213
- const { container } = render(React.createElement("span", null, ...renderAnnotatedString(ann)));
214
- const el = container.querySelector('[role="link"]');
215
- fireEvent.keyDown(el, { key: " " });
216
- expect(onClick).toHaveBeenCalledOnce();
217
- });
218
- it("applies SpanStyle color to a styled segment", () => {
219
- const ann = buildAnnotatedString(b => {
220
- b.withStyle({ color: "purple" }, () => b.append("colored"));
221
- });
222
- const { container } = render(React.createElement("span", null, ...renderAnnotatedString(ann)));
223
- const el = container.querySelector("span > span");
224
- expect(el.style.color).toBe("purple");
225
- });
226
- it("applies SpanStyle fontWeight to a styled segment", () => {
227
- const ann = buildAnnotatedString(b => {
228
- b.withStyle({ fontWeight: "bold" }, () => b.append("bold text"));
229
- });
230
- const { container } = render(React.createElement("span", null, ...renderAnnotatedString(ann)));
231
- const el = container.querySelector("span > span");
232
- expect(el.style.fontWeight).toBe("bold");
233
- });
234
- it("applies textDecoration from SpanStyle to a link", () => {
235
- const ann = buildAnnotatedString(b => {
236
- b.withLink(LinkAnnotation.Url("https://a.com"), () => {
237
- b.withStyle({ textDecoration: TextDecoration.Underline }, () => b.append("underlined link"));
238
- });
239
- });
240
- const { container } = render(React.createElement("span", null, ...renderAnnotatedString(ann)));
241
- const a = container.querySelector("a");
242
- expect(a.style.textDecoration).toContain("underline");
243
- });
244
- it("renders unstyled text segments without wrapping spans", () => {
245
- const ann = buildAnnotatedString(b => {
246
- b.append("plain ");
247
- b.withStyle({ color: "red" }, () => b.append("red"));
248
- b.append(" plain");
249
- });
250
- const nodes = renderAnnotatedString(ann);
251
- // First and last nodes should be bare strings, middle a React element
252
- expect(typeof nodes[0]).toBe("string");
253
- expect(typeof nodes[2]).toBe("string");
254
- });
255
- it("handles an AnnotatedString with no spans as a single text node", () => {
256
- const ann = buildAnnotatedString(b => b.append("no spans here"));
257
- const nodes = renderAnnotatedString(ann).filter(Boolean);
258
- expect(nodes).toHaveLength(1);
259
- expect(nodes[0]).toBe("no spans here");
260
- });
261
- });
262
- // ---------------------------------------------------------------------------
263
- // Text component integration
264
- // ---------------------------------------------------------------------------
265
- describe("Text + AnnotatedString integration", () => {
266
- it("renders plain string text unchanged", () => {
267
- render(React.createElement(Text, { text: "plain" }));
268
- expect(screen.getByText("plain")).toBeTruthy();
269
- });
270
- it("renders an AnnotatedString passed via text prop", () => {
271
- const ann = buildAnnotatedString(b => {
272
- b.append("Visit ");
273
- b.withLink(LinkAnnotation.Url("https://jalvin.dev"), () => b.append("Jalvin"));
274
- });
275
- const { container } = render(React.createElement(Text, { text: ann }));
276
- expect(container.querySelector("a")).not.toBeNull();
277
- expect(container.querySelector("a").textContent).toBe("Jalvin");
278
- });
279
- it("renders mixed plain + styled text inside Text", () => {
280
- const ann = buildAnnotatedString(b => {
281
- b.append("Hello ");
282
- b.withStyle({ color: "blue" }, () => b.append("world"));
283
- });
284
- const { container } = render(React.createElement(Text, { text: ann }));
285
- const spans = container.querySelectorAll("span");
286
- // Outer wrapper span + inner styled span
287
- expect(spans.length).toBeGreaterThanOrEqual(2);
288
- });
289
- it("Clickable link inside Text fires callback on click", () => {
290
- const onClick = vi.fn();
291
- const ann = buildAnnotatedString(b => {
292
- b.withLink(LinkAnnotation.Clickable("action", onClick), () => b.append("do it"));
293
- });
294
- const { container } = render(React.createElement(Text, { text: ann }));
295
- const el = container.querySelector('[role="link"]');
296
- fireEvent.click(el);
297
- expect(onClick).toHaveBeenCalledWith("action");
298
- });
299
- it("still supports children when text prop is a plain string", () => {
300
- render(React.createElement(Text, null, "child text"));
301
- expect(screen.getByText("child text")).toBeTruthy();
302
- });
303
- it("Text color prop still applied when text is an AnnotatedString", () => {
304
- const ann = buildAnnotatedString(b => b.append("hello"));
305
- const { container } = render(React.createElement(Text, { text: ann, color: "hotpink" }));
306
- const outer = container.querySelector("span");
307
- expect(outer.style.color).toBe("hotpink");
308
- });
309
- });
310
- //# sourceMappingURL=annotated-string.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"annotated-string.test.js","sourceRoot":"","sources":["../../src/__tests__/annotated-string.test.tsx"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=interaction.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"interaction.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/interaction.test.ts"],"names":[],"mappings":""}
@@ -1,292 +0,0 @@
1
- import { describe, it, expect, vi } from "vitest";
2
- import { renderHook, act } from "@testing-library/react";
3
- import { MutableInteractionSource, useMutableInteractionSource, useIsHovered, useIsPressed, useIsFocused, } from "../interaction.js";
4
- // ── MutableInteractionSource ──────────────────────────────────────────────────
5
- describe("MutableInteractionSource — hover", () => {
6
- it("starts with no active interactions", () => {
7
- const s = new MutableInteractionSource();
8
- expect(s.getInteractions()).toHaveLength(0);
9
- });
10
- it("adds hover.enter on _handleMouseEnter", () => {
11
- const s = new MutableInteractionSource();
12
- s._handleMouseEnter();
13
- expect(s.getInteractions()).toHaveLength(1);
14
- expect(s.getInteractions()[0].type).toBe("hover.enter");
15
- });
16
- it("removes hover.enter on _handleMouseLeave", () => {
17
- const s = new MutableInteractionSource();
18
- s._handleMouseEnter();
19
- s._handleMouseLeave();
20
- expect(s.getInteractions()).toHaveLength(0);
21
- });
22
- it("_handleMouseLeave is a no-op when not hovered", () => {
23
- const s = new MutableInteractionSource();
24
- s._handleMouseLeave();
25
- expect(s.getInteractions()).toHaveLength(0);
26
- });
27
- });
28
- describe("MutableInteractionSource — focus", () => {
29
- it("adds focus.focus on _handleFocus", () => {
30
- const s = new MutableInteractionSource();
31
- s._handleFocus();
32
- expect(s.getInteractions()).toHaveLength(1);
33
- expect(s.getInteractions()[0].type).toBe("focus.focus");
34
- });
35
- it("removes focus.focus on _handleBlur", () => {
36
- const s = new MutableInteractionSource();
37
- s._handleFocus();
38
- s._handleBlur();
39
- expect(s.getInteractions()).toHaveLength(0);
40
- });
41
- it("_handleBlur is a no-op when not focused", () => {
42
- const s = new MutableInteractionSource();
43
- s._handleBlur();
44
- expect(s.getInteractions()).toHaveLength(0);
45
- });
46
- });
47
- describe("MutableInteractionSource — press", () => {
48
- it("adds press.press on _handleMouseDown", () => {
49
- const s = new MutableInteractionSource();
50
- s._handleMouseDown(10, 20);
51
- expect(s.getInteractions()).toHaveLength(1);
52
- const i = s.getInteractions()[0];
53
- expect(i.type).toBe("press.press");
54
- if (i.type === "press.press") {
55
- expect(i.x).toBe(10);
56
- expect(i.y).toBe(20);
57
- }
58
- });
59
- it("removes press.press on _handleMouseUp", () => {
60
- const s = new MutableInteractionSource();
61
- s._handleMouseDown(0, 0);
62
- s._handleMouseUp();
63
- expect(s.getInteractions()).toHaveLength(0);
64
- });
65
- it("removes press.press on _handlePressCancel", () => {
66
- const s = new MutableInteractionSource();
67
- s._handleMouseDown(0, 0);
68
- s._handlePressCancel();
69
- expect(s.getInteractions()).toHaveLength(0);
70
- });
71
- it("_handleMouseUp is a no-op when not pressed", () => {
72
- const s = new MutableInteractionSource();
73
- s._handleMouseUp();
74
- expect(s.getInteractions()).toHaveLength(0);
75
- });
76
- });
77
- describe("MutableInteractionSource — multiple concurrent interactions", () => {
78
- it("tracks hover and press simultaneously", () => {
79
- const s = new MutableInteractionSource();
80
- s._handleMouseEnter();
81
- s._handleMouseDown(5, 5);
82
- expect(s.getInteractions()).toHaveLength(2);
83
- s._handleMouseUp();
84
- expect(s.getInteractions()).toHaveLength(1);
85
- expect(s.getInteractions()[0].type).toBe("hover.enter");
86
- });
87
- it("tracks hover, focus, and press simultaneously", () => {
88
- const s = new MutableInteractionSource();
89
- s._handleMouseEnter();
90
- s._handleFocus();
91
- s._handleMouseDown(0, 0);
92
- expect(s.getInteractions()).toHaveLength(3);
93
- });
94
- });
95
- describe("MutableInteractionSource — subscribe", () => {
96
- it("notifies listener on every state change", () => {
97
- const s = new MutableInteractionSource();
98
- const listener = vi.fn();
99
- s.subscribe(listener);
100
- s._handleMouseEnter();
101
- s._handleMouseLeave();
102
- expect(listener).toHaveBeenCalledTimes(2);
103
- });
104
- it("unsubscribe stops notifications", () => {
105
- const s = new MutableInteractionSource();
106
- const listener = vi.fn();
107
- const unsub = s.subscribe(listener);
108
- s._handleMouseEnter();
109
- unsub();
110
- s._handleMouseLeave();
111
- expect(listener).toHaveBeenCalledTimes(1);
112
- });
113
- it("multiple listeners are all notified", () => {
114
- const s = new MutableInteractionSource();
115
- const a = vi.fn();
116
- const b = vi.fn();
117
- s.subscribe(a);
118
- s.subscribe(b);
119
- s._handleMouseEnter();
120
- expect(a).toHaveBeenCalledTimes(1);
121
- expect(b).toHaveBeenCalledTimes(1);
122
- });
123
- });
124
- // ── useMutableInteractionSource ───────────────────────────────────────────────
125
- describe("useMutableInteractionSource", () => {
126
- it("returns a MutableInteractionSource", () => {
127
- const { result } = renderHook(() => useMutableInteractionSource());
128
- expect(result.current).toBeInstanceOf(MutableInteractionSource);
129
- });
130
- it("returns the same instance across re-renders", () => {
131
- const { result, rerender } = renderHook(() => useMutableInteractionSource());
132
- const first = result.current;
133
- rerender();
134
- expect(result.current).toBe(first);
135
- });
136
- });
137
- // ── useIsHovered ──────────────────────────────────────────────────────────────
138
- describe("useIsHovered", () => {
139
- it("starts as false", () => {
140
- const source = new MutableInteractionSource();
141
- const { result } = renderHook(() => useIsHovered(source));
142
- expect(result.current).toBe(false);
143
- });
144
- it("becomes true after _handleMouseEnter", () => {
145
- const source = new MutableInteractionSource();
146
- const { result } = renderHook(() => useIsHovered(source));
147
- act(() => { source._handleMouseEnter(); });
148
- expect(result.current).toBe(true);
149
- });
150
- it("returns to false after _handleMouseLeave", () => {
151
- const source = new MutableInteractionSource();
152
- const { result } = renderHook(() => useIsHovered(source));
153
- act(() => { source._handleMouseEnter(); });
154
- act(() => { source._handleMouseLeave(); });
155
- expect(result.current).toBe(false);
156
- });
157
- it("reflects pre-existing hover state on mount", () => {
158
- const source = new MutableInteractionSource();
159
- source._handleMouseEnter();
160
- const { result } = renderHook(() => useIsHovered(source));
161
- expect(result.current).toBe(true);
162
- });
163
- });
164
- // ── useIsFocused ──────────────────────────────────────────────────────────────
165
- describe("useIsFocused", () => {
166
- it("starts as false", () => {
167
- const source = new MutableInteractionSource();
168
- const { result } = renderHook(() => useIsFocused(source));
169
- expect(result.current).toBe(false);
170
- });
171
- it("becomes true after _handleFocus", () => {
172
- const source = new MutableInteractionSource();
173
- const { result } = renderHook(() => useIsFocused(source));
174
- act(() => { source._handleFocus(); });
175
- expect(result.current).toBe(true);
176
- });
177
- it("returns to false after _handleBlur", () => {
178
- const source = new MutableInteractionSource();
179
- const { result } = renderHook(() => useIsFocused(source));
180
- act(() => { source._handleFocus(); });
181
- act(() => { source._handleBlur(); });
182
- expect(result.current).toBe(false);
183
- });
184
- });
185
- // ── useIsPressed ──────────────────────────────────────────────────────────────
186
- describe("useIsPressed", () => {
187
- it("starts as false", () => {
188
- const source = new MutableInteractionSource();
189
- const { result } = renderHook(() => useIsPressed(source));
190
- expect(result.current).toBe(false);
191
- });
192
- it("becomes true after _handleMouseDown", () => {
193
- const source = new MutableInteractionSource();
194
- const { result } = renderHook(() => useIsPressed(source));
195
- act(() => { source._handleMouseDown(0, 0); });
196
- expect(result.current).toBe(true);
197
- });
198
- it("returns to false after _handleMouseUp", () => {
199
- const source = new MutableInteractionSource();
200
- const { result } = renderHook(() => useIsPressed(source));
201
- act(() => { source._handleMouseDown(0, 0); });
202
- act(() => { source._handleMouseUp(); });
203
- expect(result.current).toBe(false);
204
- });
205
- it("returns to false after _handlePressCancel", () => {
206
- const source = new MutableInteractionSource();
207
- const { result } = renderHook(() => useIsPressed(source));
208
- act(() => { source._handleMouseDown(0, 0); });
209
- act(() => { source._handlePressCancel(); });
210
- expect(result.current).toBe(false);
211
- });
212
- });
213
- // ── MutableInteractionSource — touch ─────────────────────────────────────────
214
- describe("MutableInteractionSource — touch (_handleTouchStart)", () => {
215
- it("adds hover.enter and press.press on touch start", () => {
216
- const s = new MutableInteractionSource();
217
- s._handleTouchStart(10, 20);
218
- const types = s.getInteractions().map(i => i.type);
219
- expect(types).toContain("hover.enter");
220
- expect(types).toContain("press.press");
221
- expect(s.getInteractions()).toHaveLength(2);
222
- });
223
- it("records the correct touch coordinates", () => {
224
- const s = new MutableInteractionSource();
225
- s._handleTouchStart(42, 84);
226
- const press = s.getInteractions().find(i => i.type === "press.press");
227
- expect(press).toBeDefined();
228
- if (press?.type === "press.press") {
229
- expect(press.x).toBe(42);
230
- expect(press.y).toBe(84);
231
- }
232
- });
233
- it("does not add a second hover.enter if already hovered", () => {
234
- const s = new MutableInteractionSource();
235
- s._handleMouseEnter(); // already hovered
236
- s._handleTouchStart(0, 0);
237
- const hoverEntries = s.getInteractions().filter(i => i.type === "hover.enter");
238
- expect(hoverEntries).toHaveLength(1);
239
- });
240
- });
241
- describe("MutableInteractionSource — touch (_handleTouchEnd)", () => {
242
- it("clears both press and hover on touch end", () => {
243
- const s = new MutableInteractionSource();
244
- s._handleTouchStart(0, 0);
245
- s._handleTouchEnd();
246
- expect(s.getInteractions()).toHaveLength(0);
247
- });
248
- it("is a no-op when called without a preceding touch start", () => {
249
- const s = new MutableInteractionSource();
250
- s._handleTouchEnd();
251
- expect(s.getInteractions()).toHaveLength(0);
252
- });
253
- });
254
- describe("MutableInteractionSource — touch (_handleTouchCancel)", () => {
255
- it("clears both press and hover on touch cancel", () => {
256
- const s = new MutableInteractionSource();
257
- s._handleTouchStart(0, 0);
258
- s._handleTouchCancel();
259
- expect(s.getInteractions()).toHaveLength(0);
260
- });
261
- it("is a no-op when called without a preceding touch start", () => {
262
- const s = new MutableInteractionSource();
263
- s._handleTouchCancel();
264
- expect(s.getInteractions()).toHaveLength(0);
265
- });
266
- });
267
- describe("MutableInteractionSource — touch (hooks)", () => {
268
- it("useIsPressed becomes true on touch start and false on touch end", () => {
269
- const source = new MutableInteractionSource();
270
- const { result } = renderHook(() => useIsPressed(source));
271
- act(() => { source._handleTouchStart(0, 0); });
272
- expect(result.current).toBe(true);
273
- act(() => { source._handleTouchEnd(); });
274
- expect(result.current).toBe(false);
275
- });
276
- it("useIsHovered becomes true on touch start and false on touch end", () => {
277
- const source = new MutableInteractionSource();
278
- const { result } = renderHook(() => useIsHovered(source));
279
- act(() => { source._handleTouchStart(0, 0); });
280
- expect(result.current).toBe(true);
281
- act(() => { source._handleTouchEnd(); });
282
- expect(result.current).toBe(false);
283
- });
284
- it("useIsPressed becomes false on touch cancel", () => {
285
- const source = new MutableInteractionSource();
286
- const { result } = renderHook(() => useIsPressed(source));
287
- act(() => { source._handleTouchStart(0, 0); });
288
- act(() => { source._handleTouchCancel(); });
289
- expect(result.current).toBe(false);
290
- });
291
- });
292
- //# sourceMappingURL=interaction.test.js.map