rask-ui 0.2.5 → 0.2.7

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 (200) hide show
  1. package/dist/vdom/AbstractVNode.d.ts +20 -1
  2. package/dist/vdom/AbstractVNode.d.ts.map +1 -1
  3. package/dist/vdom/AbstractVNode.js +151 -12
  4. package/dist/vdom/ComponentVNode.d.ts +2 -2
  5. package/dist/vdom/ComponentVNode.d.ts.map +1 -1
  6. package/dist/vdom/ComponentVNode.js +17 -8
  7. package/dist/vdom/ElementVNode.d.ts +6 -9
  8. package/dist/vdom/ElementVNode.d.ts.map +1 -1
  9. package/dist/vdom/ElementVNode.js +103 -34
  10. package/dist/vdom/FragmentVNode.d.ts +2 -2
  11. package/dist/vdom/FragmentVNode.d.ts.map +1 -1
  12. package/dist/vdom/FragmentVNode.js +18 -7
  13. package/dist/vdom/RootVNode.d.ts +2 -2
  14. package/dist/vdom/RootVNode.d.ts.map +1 -1
  15. package/dist/vdom/RootVNode.js +15 -6
  16. package/dist/vdom/dom-utils.d.ts +6 -1
  17. package/dist/vdom/dom-utils.d.ts.map +1 -1
  18. package/dist/vdom/dom-utils.js +20 -1
  19. package/dist/vdom/types.d.ts +12 -0
  20. package/dist/vdom/types.d.ts.map +1 -1
  21. package/package.json +1 -1
  22. package/dist/component.d.ts +0 -38
  23. package/dist/component.d.ts.map +0 -1
  24. package/dist/component.js +0 -130
  25. package/dist/context.d.ts +0 -5
  26. package/dist/context.d.ts.map +0 -1
  27. package/dist/context.js +0 -29
  28. package/dist/createAsync.test.d.ts +0 -2
  29. package/dist/createAsync.test.d.ts.map +0 -1
  30. package/dist/createAsync.test.js +0 -110
  31. package/dist/createAsyncState.d.ts +0 -16
  32. package/dist/createAsyncState.d.ts.map +0 -1
  33. package/dist/createAsyncState.js +0 -24
  34. package/dist/createContext.test.d.ts +0 -2
  35. package/dist/createContext.test.d.ts.map +0 -1
  36. package/dist/createContext.test.js +0 -136
  37. package/dist/createMutation.test.d.ts +0 -2
  38. package/dist/createMutation.test.d.ts.map +0 -1
  39. package/dist/createMutation.test.js +0 -168
  40. package/dist/createQuery.test.d.ts +0 -2
  41. package/dist/createQuery.test.d.ts.map +0 -1
  42. package/dist/createQuery.test.js +0 -156
  43. package/dist/createRef.test.d.ts +0 -2
  44. package/dist/createRef.test.d.ts.map +0 -1
  45. package/dist/createRef.test.js +0 -80
  46. package/dist/createState.test.d.ts +0 -2
  47. package/dist/createState.test.d.ts.map +0 -1
  48. package/dist/createState.test.js +0 -111
  49. package/dist/createView.test.d.ts +0 -2
  50. package/dist/createView.test.d.ts.map +0 -1
  51. package/dist/createView.test.js +0 -203
  52. package/dist/error.test.d.ts +0 -2
  53. package/dist/error.test.d.ts.map +0 -1
  54. package/dist/error.test.js +0 -144
  55. package/dist/integration.test.d.ts +0 -2
  56. package/dist/integration.test.d.ts.map +0 -1
  57. package/dist/integration.test.js +0 -155
  58. package/dist/jsx.d.ts.map +0 -1
  59. package/dist/jsx.js +0 -42
  60. package/dist/observation.test.d.ts +0 -2
  61. package/dist/observation.test.d.ts.map +0 -1
  62. package/dist/observation.test.js +0 -113
  63. package/dist/render-test.d.ts +0 -2
  64. package/dist/render-test.d.ts.map +0 -1
  65. package/dist/render-test.js +0 -21
  66. package/dist/render.d.ts +0 -7
  67. package/dist/render.d.ts.map +0 -1
  68. package/dist/render.js +0 -77
  69. package/dist/suspense.d.ts +0 -25
  70. package/dist/suspense.d.ts.map +0 -1
  71. package/dist/suspense.js +0 -97
  72. package/dist/tests/class.test.d.ts +0 -2
  73. package/dist/tests/class.test.d.ts.map +0 -1
  74. package/dist/tests/class.test.js +0 -185
  75. package/dist/tests/complex-rendering.test.d.ts +0 -2
  76. package/dist/tests/complex-rendering.test.d.ts.map +0 -1
  77. package/dist/tests/complex-rendering.test.js +0 -400
  78. package/dist/tests/component.cleanup.test.d.ts +0 -2
  79. package/dist/tests/component.cleanup.test.d.ts.map +0 -1
  80. package/dist/tests/component.cleanup.test.js +0 -325
  81. package/dist/tests/component.counter.test.d.ts +0 -2
  82. package/dist/tests/component.counter.test.d.ts.map +0 -1
  83. package/dist/tests/component.counter.test.js +0 -124
  84. package/dist/tests/component.interaction.test.d.ts +0 -2
  85. package/dist/tests/component.interaction.test.d.ts.map +0 -1
  86. package/dist/tests/component.interaction.test.js +0 -73
  87. package/dist/tests/component.props.test.d.ts +0 -2
  88. package/dist/tests/component.props.test.d.ts.map +0 -1
  89. package/dist/tests/component.props.test.js +0 -334
  90. package/dist/tests/component.return-types.test.d.ts +0 -2
  91. package/dist/tests/component.return-types.test.d.ts.map +0 -1
  92. package/dist/tests/component.return-types.test.js +0 -357
  93. package/dist/tests/component.state.test.d.ts +0 -2
  94. package/dist/tests/component.state.test.d.ts.map +0 -1
  95. package/dist/tests/component.state.test.js +0 -135
  96. package/dist/tests/component.test.d.ts +0 -2
  97. package/dist/tests/component.test.d.ts.map +0 -1
  98. package/dist/tests/component.test.js +0 -63
  99. package/dist/tests/createAsync.test.d.ts +0 -2
  100. package/dist/tests/createAsync.test.d.ts.map +0 -1
  101. package/dist/tests/createAsync.test.js +0 -110
  102. package/dist/tests/createContext.test.d.ts +0 -2
  103. package/dist/tests/createContext.test.d.ts.map +0 -1
  104. package/dist/tests/createContext.test.js +0 -141
  105. package/dist/tests/createMutation.test.d.ts +0 -2
  106. package/dist/tests/createMutation.test.d.ts.map +0 -1
  107. package/dist/tests/createMutation.test.js +0 -168
  108. package/dist/tests/createQuery.test.d.ts +0 -2
  109. package/dist/tests/createQuery.test.d.ts.map +0 -1
  110. package/dist/tests/createQuery.test.js +0 -156
  111. package/dist/tests/createRef.test.d.ts +0 -2
  112. package/dist/tests/createRef.test.d.ts.map +0 -1
  113. package/dist/tests/createRef.test.js +0 -84
  114. package/dist/tests/createState.test.d.ts +0 -2
  115. package/dist/tests/createState.test.d.ts.map +0 -1
  116. package/dist/tests/createState.test.js +0 -103
  117. package/dist/tests/createView.test.d.ts +0 -2
  118. package/dist/tests/createView.test.d.ts.map +0 -1
  119. package/dist/tests/createView.test.js +0 -203
  120. package/dist/tests/edge-cases.test.d.ts +0 -2
  121. package/dist/tests/edge-cases.test.d.ts.map +0 -1
  122. package/dist/tests/edge-cases.test.js +0 -637
  123. package/dist/tests/error-no-boundary.test.d.ts +0 -2
  124. package/dist/tests/error-no-boundary.test.d.ts.map +0 -1
  125. package/dist/tests/error-no-boundary.test.js +0 -174
  126. package/dist/tests/error.test.d.ts +0 -2
  127. package/dist/tests/error.test.d.ts.map +0 -1
  128. package/dist/tests/error.test.js +0 -199
  129. package/dist/tests/fragment.test.d.ts +0 -2
  130. package/dist/tests/fragment.test.d.ts.map +0 -1
  131. package/dist/tests/fragment.test.js +0 -618
  132. package/dist/tests/integration.test.d.ts +0 -2
  133. package/dist/tests/integration.test.d.ts.map +0 -1
  134. package/dist/tests/integration.test.js +0 -192
  135. package/dist/tests/keys.test.d.ts +0 -2
  136. package/dist/tests/keys.test.d.ts.map +0 -1
  137. package/dist/tests/keys.test.js +0 -293
  138. package/dist/tests/mount.test.d.ts +0 -2
  139. package/dist/tests/mount.test.d.ts.map +0 -1
  140. package/dist/tests/mount.test.js +0 -91
  141. package/dist/tests/observation.test.d.ts +0 -2
  142. package/dist/tests/observation.test.d.ts.map +0 -1
  143. package/dist/tests/observation.test.js +0 -113
  144. package/dist/tests/patch.test.d.ts +0 -2
  145. package/dist/tests/patch.test.d.ts.map +0 -1
  146. package/dist/tests/patch.test.js +0 -498
  147. package/dist/tests/patchChildren.test.d.ts +0 -2
  148. package/dist/tests/patchChildren.test.d.ts.map +0 -1
  149. package/dist/tests/patchChildren.test.js +0 -405
  150. package/dist/tests/primitives.test.d.ts +0 -2
  151. package/dist/tests/primitives.test.d.ts.map +0 -1
  152. package/dist/tests/primitives.test.js +0 -132
  153. package/dist/vdom/class.test.d.ts +0 -2
  154. package/dist/vdom/class.test.d.ts.map +0 -1
  155. package/dist/vdom/class.test.js +0 -143
  156. package/dist/vdom/complex-rendering.test.d.ts +0 -2
  157. package/dist/vdom/complex-rendering.test.d.ts.map +0 -1
  158. package/dist/vdom/complex-rendering.test.js +0 -400
  159. package/dist/vdom/component.cleanup.test.d.ts +0 -2
  160. package/dist/vdom/component.cleanup.test.d.ts.map +0 -1
  161. package/dist/vdom/component.cleanup.test.js +0 -323
  162. package/dist/vdom/component.counter.test.d.ts +0 -2
  163. package/dist/vdom/component.counter.test.d.ts.map +0 -1
  164. package/dist/vdom/component.counter.test.js +0 -124
  165. package/dist/vdom/component.interaction.test.d.ts +0 -2
  166. package/dist/vdom/component.interaction.test.d.ts.map +0 -1
  167. package/dist/vdom/component.interaction.test.js +0 -73
  168. package/dist/vdom/component.props.test.d.ts +0 -2
  169. package/dist/vdom/component.props.test.d.ts.map +0 -1
  170. package/dist/vdom/component.props.test.js +0 -88
  171. package/dist/vdom/component.return-types.test.d.ts +0 -2
  172. package/dist/vdom/component.return-types.test.d.ts.map +0 -1
  173. package/dist/vdom/component.return-types.test.js +0 -357
  174. package/dist/vdom/component.state.test.d.ts +0 -2
  175. package/dist/vdom/component.state.test.d.ts.map +0 -1
  176. package/dist/vdom/component.state.test.js +0 -129
  177. package/dist/vdom/component.test.d.ts +0 -2
  178. package/dist/vdom/component.test.d.ts.map +0 -1
  179. package/dist/vdom/component.test.js +0 -63
  180. package/dist/vdom/edge-cases.test.d.ts +0 -2
  181. package/dist/vdom/edge-cases.test.d.ts.map +0 -1
  182. package/dist/vdom/edge-cases.test.js +0 -637
  183. package/dist/vdom/fragment.test.d.ts +0 -2
  184. package/dist/vdom/fragment.test.d.ts.map +0 -1
  185. package/dist/vdom/fragment.test.js +0 -618
  186. package/dist/vdom/keys.test.d.ts +0 -2
  187. package/dist/vdom/keys.test.d.ts.map +0 -1
  188. package/dist/vdom/keys.test.js +0 -293
  189. package/dist/vdom/mount.test.d.ts +0 -2
  190. package/dist/vdom/mount.test.d.ts.map +0 -1
  191. package/dist/vdom/mount.test.js +0 -91
  192. package/dist/vdom/patch.test.d.ts +0 -2
  193. package/dist/vdom/patch.test.d.ts.map +0 -1
  194. package/dist/vdom/patch.test.js +0 -498
  195. package/dist/vdom/patchChildren.test.d.ts +0 -2
  196. package/dist/vdom/patchChildren.test.d.ts.map +0 -1
  197. package/dist/vdom/patchChildren.test.js +0 -392
  198. package/dist/vdom/primitives.test.d.ts +0 -2
  199. package/dist/vdom/primitives.test.d.ts.map +0 -1
  200. package/dist/vdom/primitives.test.js +0 -132
@@ -1,618 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
2
- import { jsx, render } from "./index";
3
- import { Fragment } from "./FragmentVNode";
4
- import { createState } from "../createState";
5
- describe("VDOM Fragments", () => {
6
- describe("Mounting", () => {
7
- it("should mount a simple fragment with multiple children", () => {
8
- const container = document.createElement("div");
9
- const vnode = jsx(Fragment, {
10
- children: [
11
- jsx("span", { children: ["First"] }),
12
- jsx("span", { children: ["Second"] }),
13
- jsx("span", { children: ["Third"] }),
14
- ],
15
- });
16
- render(vnode, container);
17
- expect(container.children.length).toBe(3);
18
- expect(container.children[0].tagName).toBe("SPAN");
19
- expect(container.children[0].textContent).toBe("First");
20
- expect(container.children[1].tagName).toBe("SPAN");
21
- expect(container.children[1].textContent).toBe("Second");
22
- expect(container.children[2].tagName).toBe("SPAN");
23
- expect(container.children[2].textContent).toBe("Third");
24
- });
25
- it("should mount fragment inside an element", () => {
26
- const container = document.createElement("div");
27
- const vnode = jsx("div", {
28
- className: "wrapper",
29
- children: [
30
- jsx(Fragment, {
31
- children: [
32
- jsx("span", { children: ["A"] }),
33
- jsx("span", { children: ["B"] }),
34
- ],
35
- }),
36
- ],
37
- });
38
- render(vnode, container);
39
- const wrapper = container.children[0];
40
- expect(wrapper.className).toBe("wrapper");
41
- expect(wrapper.children.length).toBe(2);
42
- expect(wrapper.children[0].textContent).toBe("A");
43
- expect(wrapper.children[1].textContent).toBe("B");
44
- });
45
- it("should mount nested fragments", () => {
46
- const container = document.createElement("div");
47
- const vnode = jsx(Fragment, {
48
- children: [
49
- jsx("span", { children: ["Before"] }),
50
- jsx(Fragment, {
51
- children: [
52
- jsx("span", { children: ["Nested 1"] }),
53
- jsx("span", { children: ["Nested 2"] }),
54
- ],
55
- }),
56
- jsx("span", { children: ["After"] }),
57
- ],
58
- });
59
- render(vnode, container);
60
- expect(container.children.length).toBe(4);
61
- expect(container.children[0].textContent).toBe("Before");
62
- expect(container.children[1].textContent).toBe("Nested 1");
63
- expect(container.children[2].textContent).toBe("Nested 2");
64
- expect(container.children[3].textContent).toBe("After");
65
- });
66
- it("should mount deeply nested fragments", () => {
67
- const container = document.createElement("div");
68
- const vnode = jsx(Fragment, {
69
- children: [
70
- jsx(Fragment, {
71
- children: [
72
- jsx(Fragment, {
73
- children: [
74
- jsx("span", { children: ["Deep 1"] }),
75
- jsx("span", { children: ["Deep 2"] }),
76
- ],
77
- }),
78
- jsx("span", { children: ["Middle"] }),
79
- ],
80
- }),
81
- jsx("span", { children: ["Outer"] }),
82
- ],
83
- });
84
- render(vnode, container);
85
- expect(container.children.length).toBe(4);
86
- expect(container.children[0].textContent).toBe("Deep 1");
87
- expect(container.children[1].textContent).toBe("Deep 2");
88
- expect(container.children[2].textContent).toBe("Middle");
89
- expect(container.children[3].textContent).toBe("Outer");
90
- });
91
- it("should mount fragment with mixed element types", () => {
92
- const container = document.createElement("div");
93
- const vnode = jsx(Fragment, {
94
- children: [
95
- jsx("div", { children: ["Div"] }),
96
- jsx("span", { children: ["Span"] }),
97
- jsx("button", { children: ["Button"] }),
98
- ],
99
- });
100
- render(vnode, container);
101
- expect(container.children.length).toBe(3);
102
- expect(container.children[0].tagName).toBe("DIV");
103
- expect(container.children[1].tagName).toBe("SPAN");
104
- expect(container.children[2].tagName).toBe("BUTTON");
105
- });
106
- });
107
- describe("Patching", () => {
108
- beforeEach(() => {
109
- vi.useFakeTimers();
110
- });
111
- afterEach(() => {
112
- vi.clearAllTimers();
113
- });
114
- it("should patch fragment by adding children", async () => {
115
- const container = document.createElement("div");
116
- let stateFn;
117
- const App = () => {
118
- const state = createState({ childCount: 1 });
119
- stateFn = state;
120
- return () => {
121
- const children = [];
122
- for (let i = 0; i < state.childCount; i++) {
123
- const labels = ["First", "Second", "Third"];
124
- children.push(jsx("span", { children: [labels[i]] }));
125
- }
126
- return jsx(Fragment, { children });
127
- };
128
- };
129
- render(jsx(App, {}), container);
130
- expect(container.children.length).toBe(1);
131
- expect(container.children[0].textContent).toBe("First");
132
- stateFn.childCount = 3;
133
- await vi.runAllTimersAsync();
134
- expect(container.children.length).toBe(3);
135
- expect(container.children[0].textContent).toBe("First");
136
- expect(container.children[1].textContent).toBe("Second");
137
- expect(container.children[2].textContent).toBe("Third");
138
- });
139
- it("should patch fragment by removing children", async () => {
140
- const container = document.createElement("div");
141
- let stateFn;
142
- const App = () => {
143
- const state = createState({ childCount: 3 });
144
- stateFn = state;
145
- return () => {
146
- const children = [];
147
- for (let i = 0; i < state.childCount; i++) {
148
- const labels = ["First", "Second", "Third"];
149
- children.push(jsx("span", { children: [labels[i]] }));
150
- }
151
- return jsx(Fragment, { children });
152
- };
153
- };
154
- render(jsx(App, {}), container);
155
- expect(container.children.length).toBe(3);
156
- stateFn.childCount = 1;
157
- await vi.runAllTimersAsync();
158
- expect(container.children.length).toBe(1);
159
- expect(container.children[0].textContent).toBe("First");
160
- });
161
- it("should patch fragment by replacing children", async () => {
162
- const container = document.createElement("div");
163
- let stateFn;
164
- const App = () => {
165
- const state = createState({ useDiv: false });
166
- stateFn = state;
167
- return () => {
168
- if (state.useDiv) {
169
- return jsx(Fragment, {
170
- children: [
171
- jsx("div", { children: ["New 1"] }),
172
- jsx("div", { children: ["New 2"] }),
173
- ],
174
- });
175
- }
176
- return jsx(Fragment, {
177
- children: [
178
- jsx("span", { children: ["Old 1"] }),
179
- jsx("span", { children: ["Old 2"] }),
180
- ],
181
- });
182
- };
183
- };
184
- render(jsx(App, {}), container);
185
- expect(container.children.length).toBe(2);
186
- expect(container.children[0].tagName).toBe("SPAN");
187
- stateFn.useDiv = true;
188
- await vi.runAllTimersAsync();
189
- expect(container.children.length).toBe(2);
190
- expect(container.children[0].tagName).toBe("DIV");
191
- expect(container.children[0].textContent).toBe("New 1");
192
- expect(container.children[1].tagName).toBe("DIV");
193
- expect(container.children[1].textContent).toBe("New 2");
194
- });
195
- it("should patch fragment inside an element", async () => {
196
- const container = document.createElement("div");
197
- let stateFn;
198
- const App = () => {
199
- const state = createState({ showC: false });
200
- stateFn = state;
201
- return () => jsx("div", {
202
- children: [
203
- jsx(Fragment, {
204
- children: [
205
- jsx("span", { children: ["A"] }),
206
- jsx("span", { children: ["B"] }),
207
- ...(state.showC ? [jsx("span", { children: ["C"] })] : []),
208
- ],
209
- }),
210
- ],
211
- });
212
- };
213
- render(jsx(App, {}), container);
214
- const wrapper = container.children[0];
215
- expect(wrapper.children.length).toBe(2);
216
- stateFn.showC = true;
217
- await vi.runAllTimersAsync();
218
- expect(wrapper.children.length).toBe(3);
219
- expect(wrapper.children[0].textContent).toBe("A");
220
- expect(wrapper.children[1].textContent).toBe("B");
221
- expect(wrapper.children[2].textContent).toBe("C");
222
- });
223
- it("should patch nested fragments", async () => {
224
- const container = document.createElement("div");
225
- let stateFn;
226
- const App = () => {
227
- const state = createState({ showInner2: false });
228
- stateFn = state;
229
- return () => jsx(Fragment, {
230
- children: [
231
- jsx("span", { children: ["Outer"] }),
232
- jsx(Fragment, {
233
- children: [
234
- jsx("span", { children: ["Inner 1"] }),
235
- ...(state.showInner2
236
- ? [jsx("span", { children: ["Inner 2"] })]
237
- : []),
238
- ],
239
- }),
240
- ],
241
- });
242
- };
243
- render(jsx(App, {}), container);
244
- expect(container.children.length).toBe(2);
245
- stateFn.showInner2 = true;
246
- await vi.runAllTimersAsync();
247
- expect(container.children.length).toBe(3);
248
- expect(container.children[0].textContent).toBe("Outer");
249
- expect(container.children[1].textContent).toBe("Inner 1");
250
- expect(container.children[2].textContent).toBe("Inner 2");
251
- });
252
- it("should patch by replacing element with fragment", async () => {
253
- const container = document.createElement("div");
254
- let stateFn;
255
- const App = () => {
256
- const state = createState({ useFragment: false });
257
- stateFn = state;
258
- return () => jsx("div", {
259
- children: [
260
- state.useFragment
261
- ? jsx(Fragment, {
262
- children: [
263
- jsx("span", { children: ["First"] }),
264
- jsx("span", { children: ["Second"] }),
265
- ],
266
- })
267
- : jsx("span", { children: ["Single"] }),
268
- ],
269
- });
270
- };
271
- render(jsx(App, {}), container);
272
- const wrapper = container.children[0];
273
- expect(wrapper.children.length).toBe(1);
274
- stateFn.useFragment = true;
275
- await vi.runAllTimersAsync();
276
- expect(wrapper.children.length).toBe(2);
277
- expect(wrapper.children[0].textContent).toBe("First");
278
- expect(wrapper.children[1].textContent).toBe("Second");
279
- });
280
- it("should patch by replacing fragment with element", async () => {
281
- const container = document.createElement("div");
282
- let stateFn;
283
- const App = () => {
284
- const state = createState({ useFragment: true });
285
- stateFn = state;
286
- return () => jsx("div", {
287
- children: [
288
- state.useFragment
289
- ? jsx(Fragment, {
290
- children: [
291
- jsx("span", { children: ["First"] }),
292
- jsx("span", { children: ["Second"] }),
293
- ],
294
- })
295
- : jsx("span", { children: ["Single"] }),
296
- ],
297
- });
298
- };
299
- render(jsx(App, {}), container);
300
- const wrapper = container.children[0];
301
- expect(wrapper.children.length).toBe(2);
302
- stateFn.useFragment = false;
303
- await vi.runAllTimersAsync();
304
- expect(wrapper.children.length).toBe(1);
305
- expect(wrapper.children[0].textContent).toBe("Single");
306
- });
307
- it("should patch deeply nested fragments", async () => {
308
- const container = document.createElement("div");
309
- let stateFn;
310
- const App = () => {
311
- const state = createState({ showDeep2: false });
312
- stateFn = state;
313
- return () => jsx(Fragment, {
314
- children: [
315
- jsx(Fragment, {
316
- children: [
317
- jsx(Fragment, {
318
- children: [
319
- jsx("span", { children: ["Deep 1"] }),
320
- ...(state.showDeep2
321
- ? [jsx("span", { children: ["Deep 2"] })]
322
- : []),
323
- ],
324
- }),
325
- ],
326
- }),
327
- ],
328
- });
329
- };
330
- render(jsx(App, {}), container);
331
- expect(container.children.length).toBe(1);
332
- expect(container.children[0].textContent).toBe("Deep 1");
333
- stateFn.showDeep2 = true;
334
- await vi.runAllTimersAsync();
335
- expect(container.children.length).toBe(2);
336
- expect(container.children[0].textContent).toBe("Deep 1");
337
- expect(container.children[1].textContent).toBe("Deep 2");
338
- });
339
- it("should patch fragment with keys", async () => {
340
- const container = document.createElement("div");
341
- let stateFn;
342
- const App = () => {
343
- const state = createState({ reordered: false });
344
- stateFn = state;
345
- return () => jsx(Fragment, {
346
- children: state.reordered
347
- ? [
348
- jsx("span", { children: ["C"] }, "c"),
349
- jsx("span", { children: ["A"] }, "a"),
350
- jsx("span", { children: ["B"] }, "b"),
351
- ]
352
- : [
353
- jsx("span", { children: ["A"] }, "a"),
354
- jsx("span", { children: ["B"] }, "b"),
355
- jsx("span", { children: ["C"] }, "c"),
356
- ],
357
- });
358
- };
359
- render(jsx(App, {}), container);
360
- const initialChildren = Array.from(container.children);
361
- const itemA = initialChildren[0];
362
- const itemB = initialChildren[1];
363
- const itemC = initialChildren[2];
364
- stateFn.reordered = true;
365
- await vi.runAllTimersAsync();
366
- const newChildren = Array.from(container.children);
367
- // Elements should be reordered, not recreated
368
- expect(newChildren[0]).toBe(itemC);
369
- expect(newChildren[1]).toBe(itemA);
370
- expect(newChildren[2]).toBe(itemB);
371
- });
372
- it("should patch complex nested structure with fragments", async () => {
373
- const container = document.createElement("div");
374
- let stateFn;
375
- const App = () => {
376
- const state = createState({ showAsides: false });
377
- stateFn = state;
378
- return () => jsx("div", {
379
- children: [
380
- jsx("header", { children: ["Header"] }),
381
- jsx(Fragment, {
382
- children: [
383
- jsx("section", { children: ["Section 1"] }),
384
- ...(state.showAsides
385
- ? [
386
- jsx(Fragment, {
387
- children: [
388
- jsx("aside", { children: ["Aside 1"] }),
389
- jsx("aside", { children: ["Aside 2"] }),
390
- ],
391
- }),
392
- ]
393
- : []),
394
- jsx("section", { children: ["Section 2"] }),
395
- ],
396
- }),
397
- jsx("footer", { children: ["Footer"] }),
398
- ],
399
- });
400
- };
401
- render(jsx(App, {}), container);
402
- const wrapper = container.children[0];
403
- expect(wrapper.children.length).toBe(4);
404
- stateFn.showAsides = true;
405
- await vi.runAllTimersAsync();
406
- expect(wrapper.children.length).toBe(6);
407
- expect(wrapper.children[0].tagName).toBe("HEADER");
408
- expect(wrapper.children[1].tagName).toBe("SECTION");
409
- expect(wrapper.children[1].textContent).toBe("Section 1");
410
- expect(wrapper.children[2].tagName).toBe("ASIDE");
411
- expect(wrapper.children[2].textContent).toBe("Aside 1");
412
- expect(wrapper.children[3].tagName).toBe("ASIDE");
413
- expect(wrapper.children[3].textContent).toBe("Aside 2");
414
- expect(wrapper.children[4].tagName).toBe("SECTION");
415
- expect(wrapper.children[4].textContent).toBe("Section 2");
416
- expect(wrapper.children[5].tagName).toBe("FOOTER");
417
- });
418
- it("should patch fragment removing all children", async () => {
419
- const container = document.createElement("div");
420
- let stateFn;
421
- const App = () => {
422
- const state = createState({ hasChildren: true });
423
- stateFn = state;
424
- return () => jsx("div", {
425
- children: [
426
- jsx(Fragment, {
427
- children: state.hasChildren
428
- ? [
429
- jsx("span", { children: ["A"] }),
430
- jsx("span", { children: ["B"] }),
431
- jsx("span", { children: ["C"] }),
432
- ]
433
- : [],
434
- }),
435
- ],
436
- });
437
- };
438
- render(jsx(App, {}), container);
439
- const wrapper = container.children[0];
440
- expect(wrapper.children.length).toBe(3);
441
- stateFn.hasChildren = false;
442
- await vi.runAllTimersAsync();
443
- expect(wrapper.children.length).toBe(0);
444
- });
445
- it("should patch multiple sequential fragment changes", async () => {
446
- const container = document.createElement("div");
447
- let stateFn;
448
- const App = () => {
449
- const state = createState({ childCount: 1 });
450
- stateFn = state;
451
- return () => {
452
- const children = [];
453
- for (let i = 0; i < state.childCount; i++) {
454
- const labels = ["One", "Two", "Three"];
455
- children.push(jsx("span", { children: [labels[i]] }));
456
- }
457
- return jsx(Fragment, { children });
458
- };
459
- };
460
- render(jsx(App, {}), container);
461
- expect(container.children.length).toBe(1);
462
- expect(container.children[0].textContent).toBe("One");
463
- // Patch 1: Add element
464
- stateFn.childCount = 2;
465
- await vi.runAllTimersAsync();
466
- expect(container.children.length).toBe(2);
467
- expect(container.children[1].textContent).toBe("Two");
468
- // Patch 2: Add another element
469
- stateFn.childCount = 3;
470
- await vi.runAllTimersAsync();
471
- expect(container.children.length).toBe(3);
472
- expect(container.children[2].textContent).toBe("Three");
473
- // Patch 3: Remove middle element (simulate by updating the logic)
474
- // We need to adjust the test to remove the middle element
475
- // Let's create a different approach for this test
476
- });
477
- it("should patch multiple sequential fragment changes with removal", async () => {
478
- const container = document.createElement("div");
479
- let stateFn;
480
- const App = () => {
481
- const state = createState({ items: ["One"] });
482
- stateFn = state;
483
- return () => jsx(Fragment, {
484
- children: state.items.map((item) => jsx("span", { children: [item] })),
485
- });
486
- };
487
- render(jsx(App, {}), container);
488
- expect(container.children.length).toBe(1);
489
- expect(container.children[0].textContent).toBe("One");
490
- // Patch 1: Add element
491
- stateFn.items = ["One", "Two"];
492
- await vi.runAllTimersAsync();
493
- expect(container.children.length).toBe(2);
494
- expect(container.children[1].textContent).toBe("Two");
495
- // Patch 2: Add another element
496
- stateFn.items = ["One", "Two", "Three"];
497
- await vi.runAllTimersAsync();
498
- expect(container.children.length).toBe(3);
499
- expect(container.children[2].textContent).toBe("Three");
500
- // Patch 3: Remove middle element
501
- stateFn.items = ["One", "Three"];
502
- await vi.runAllTimersAsync();
503
- expect(container.children.length).toBe(2);
504
- expect(container.children[0].textContent).toBe("One");
505
- expect(container.children[1].textContent).toBe("Three");
506
- });
507
- });
508
- describe("Component-Fragment interaction", () => {
509
- beforeEach(() => {
510
- vi.useFakeTimers();
511
- });
512
- afterEach(() => {
513
- vi.clearAllTimers();
514
- });
515
- it("should patch by replacing element with component returning fragment", async () => {
516
- const container = document.createElement("div");
517
- let stateFn;
518
- const FragmentComponent = () => {
519
- return () => jsx(Fragment, {
520
- children: [
521
- jsx("p", { children: ["First"] }),
522
- jsx("p", { children: ["Second"] }),
523
- ],
524
- });
525
- };
526
- const App = () => {
527
- const state = createState({ useComponent: false });
528
- stateFn = state;
529
- return () => jsx("div", {
530
- children: [
531
- state.useComponent
532
- ? jsx(FragmentComponent, {})
533
- : jsx("p", { children: ["Single"] }),
534
- ],
535
- });
536
- };
537
- render(jsx(App, {}), container);
538
- const wrapper = container.children[0];
539
- expect(wrapper.children.length).toBe(1);
540
- expect(wrapper.children[0].textContent).toBe("Single");
541
- stateFn.useComponent = true;
542
- await vi.runAllTimersAsync();
543
- expect(wrapper.children.length).toBe(2);
544
- expect(wrapper.children[0].textContent).toBe("First");
545
- expect(wrapper.children[1].textContent).toBe("Second");
546
- });
547
- it("should patch by replacing component returning fragment with element", async () => {
548
- const container = document.createElement("div");
549
- let stateFn;
550
- const FragmentComponent = () => {
551
- return () => jsx(Fragment, {
552
- children: [
553
- jsx("p", { children: ["First"] }),
554
- jsx("p", { children: ["Second"] }),
555
- ],
556
- });
557
- };
558
- const App = () => {
559
- const state = createState({ useComponent: true });
560
- stateFn = state;
561
- return () => jsx("div", {
562
- children: [
563
- state.useComponent
564
- ? jsx(FragmentComponent, {})
565
- : jsx("p", { children: ["Single"] }),
566
- ],
567
- });
568
- };
569
- render(jsx(App, {}), container);
570
- const wrapper = container.children[0];
571
- expect(wrapper.children.length).toBe(2);
572
- expect(wrapper.children[0].textContent).toBe("First");
573
- expect(wrapper.children[1].textContent).toBe("Second");
574
- stateFn.useComponent = false;
575
- await vi.runAllTimersAsync();
576
- expect(wrapper.children.length).toBe(1);
577
- expect(wrapper.children[0].textContent).toBe("Single");
578
- });
579
- it("should conditionally switch between element and component returning fragment", async () => {
580
- const container = document.createElement("div");
581
- let globalState;
582
- const FragmentComponent = () => {
583
- return () => jsx(Fragment, {
584
- children: [
585
- jsx("p", { children: ["Fragment 1"] }),
586
- jsx("p", { children: ["Fragment 2"] }),
587
- ],
588
- });
589
- };
590
- const App = () => {
591
- const state = createState({ showFragment: false });
592
- globalState = state;
593
- return () => jsx("div", {
594
- children: [
595
- state.showFragment
596
- ? jsx(FragmentComponent, {})
597
- : jsx("p", { children: ["Single"] }),
598
- ],
599
- });
600
- };
601
- render(jsx(App, {}), container);
602
- const wrapper = container.children[0];
603
- expect(wrapper.children.length).toBe(1);
604
- expect(wrapper.children[0].textContent).toBe("Single");
605
- // Switch to fragment
606
- globalState.showFragment = true;
607
- await vi.runAllTimersAsync();
608
- expect(wrapper.children.length).toBe(2);
609
- expect(wrapper.children[0].textContent).toBe("Fragment 1");
610
- expect(wrapper.children[1].textContent).toBe("Fragment 2");
611
- // Switch back to element
612
- globalState.showFragment = false;
613
- await vi.runAllTimersAsync();
614
- expect(wrapper.children.length).toBe(1);
615
- expect(wrapper.children[0].textContent).toBe("Single");
616
- });
617
- });
618
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=keys.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"keys.test.d.ts","sourceRoot":"","sources":["../../src/vdom/keys.test.tsx"],"names":[],"mappings":""}