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,143 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { jsx, render } from "./index";
3
- import { createState } from "../createState";
4
- describe("Class Property Support", () => {
5
- it("should map string class to className", () => {
6
- const container = document.createElement("div");
7
- render(jsx("div", { class: "test-class" }), container);
8
- const div = container.querySelector("div");
9
- expect(div?.className).toBe("test-class");
10
- });
11
- it("should handle multiple classes as string", () => {
12
- const container = document.createElement("div");
13
- render(jsx("div", { class: "class-1 class-2 class-3" }), container);
14
- const div = container.querySelector("div");
15
- expect(div?.className).toBe("class-1 class-2 class-3");
16
- });
17
- it("should handle object notation with true values", () => {
18
- const container = document.createElement("div");
19
- render(jsx("div", {
20
- class: {
21
- "active": true,
22
- "visible": true,
23
- "hidden": false,
24
- },
25
- }), container);
26
- const div = container.querySelector("div");
27
- expect(div?.classList.contains("active")).toBe(true);
28
- expect(div?.classList.contains("visible")).toBe(true);
29
- expect(div?.classList.contains("hidden")).toBe(false);
30
- });
31
- it("should handle mixed object notation", () => {
32
- const container = document.createElement("div");
33
- render(jsx("div", {
34
- class: {
35
- "class-1": true,
36
- "class-2": false,
37
- "class-3": true,
38
- "class-4": false,
39
- },
40
- }), container);
41
- const div = container.querySelector("div");
42
- expect(div?.className).toBe("class-1 class-3");
43
- });
44
- it("should handle empty object notation", () => {
45
- const container = document.createElement("div");
46
- render(jsx("div", { class: {} }), container);
47
- const div = container.querySelector("div");
48
- expect(div?.className).toBe("");
49
- });
50
- it("should handle all false object notation", () => {
51
- const container = document.createElement("div");
52
- render(jsx("div", {
53
- class: {
54
- "class-1": false,
55
- "class-2": false,
56
- },
57
- }), container);
58
- const div = container.querySelector("div");
59
- expect(div?.className).toBe("");
60
- });
61
- it("should update classes when object notation changes", async () => {
62
- const container = document.createElement("div");
63
- let stateFn;
64
- const App = () => {
65
- const state = createState({ isActive: true, isVisible: false });
66
- stateFn = state;
67
- return () => jsx("div", {
68
- class: {
69
- active: state.isActive,
70
- visible: state.isVisible,
71
- },
72
- });
73
- };
74
- render(jsx(App, {}), container);
75
- const div = container.querySelector("div");
76
- expect(div?.classList.contains("active")).toBe(true);
77
- expect(div?.classList.contains("visible")).toBe(false);
78
- stateFn.isActive = false;
79
- stateFn.isVisible = true;
80
- await new Promise((resolve) => setTimeout(resolve, 0));
81
- expect(div?.classList.contains("active")).toBe(false);
82
- expect(div?.classList.contains("visible")).toBe(true);
83
- });
84
- it("should handle hyphenated class names in object notation", () => {
85
- const container = document.createElement("div");
86
- render(jsx("div", {
87
- class: {
88
- "my-custom-class": true,
89
- "another-class-name": true,
90
- "disabled-class": false,
91
- },
92
- }), container);
93
- const div = container.querySelector("div");
94
- expect(div?.classList.contains("my-custom-class")).toBe(true);
95
- expect(div?.classList.contains("another-class-name")).toBe(true);
96
- expect(div?.classList.contains("disabled-class")).toBe(false);
97
- });
98
- it("should prefer class over className when both provided", () => {
99
- const container = document.createElement("div");
100
- render(jsx("div", { class: "from-class", className: "from-className" }), container);
101
- const div = container.querySelector("div");
102
- // class should take precedence
103
- expect(div?.className).toBe("from-class");
104
- });
105
- it("should work with nested components", () => {
106
- const container = document.createElement("div");
107
- const Child = () => {
108
- return () => jsx("span", { class: "child-class" });
109
- };
110
- const Parent = () => {
111
- return () => jsx("div", {
112
- class: "parent-class",
113
- children: jsx(Child, {}),
114
- });
115
- };
116
- render(jsx(Parent, {}), container);
117
- const parentDiv = container.querySelector("div");
118
- const childSpan = container.querySelector("span");
119
- expect(parentDiv?.className).toBe("parent-class");
120
- expect(childSpan?.className).toBe("child-class");
121
- });
122
- it("should handle undefined and null class values", () => {
123
- const container = document.createElement("div");
124
- render(jsx("div", { class: undefined }), container);
125
- const div = container.querySelector("div");
126
- expect(div?.className).toBe("");
127
- });
128
- it("should handle dynamic string class updates", async () => {
129
- const container = document.createElement("div");
130
- let stateFn;
131
- const App = () => {
132
- const state = createState({ className: "initial" });
133
- stateFn = state;
134
- return () => jsx("div", { class: state.className });
135
- };
136
- render(jsx(App, {}), container);
137
- const div = container.querySelector("div");
138
- expect(div?.className).toBe("initial");
139
- stateFn.className = "updated";
140
- await new Promise((resolve) => setTimeout(resolve, 0));
141
- expect(div?.className).toBe("updated");
142
- });
143
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=complex-rendering.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"complex-rendering.test.d.ts","sourceRoot":"","sources":["../../src/vdom/complex-rendering.test.tsx"],"names":[],"mappings":""}
@@ -1,400 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
2
- import { jsx, render } from "./index";
3
- import { createState } from "../createState";
4
- import { Fragment } from "./FragmentVNode";
5
- describe("Complex Rendering", () => {
6
- beforeEach(() => {
7
- vi.useFakeTimers();
8
- });
9
- afterEach(() => {
10
- vi.clearAllTimers();
11
- });
12
- it("should handle deeply nested elements, fragments and components", () => {
13
- const NestedComponent = () => {
14
- return () => jsx(Fragment, {
15
- children: [
16
- jsx("span", { children: "Nested" }),
17
- jsx("strong", { children: "Component" }),
18
- ],
19
- });
20
- };
21
- const MiddleComponent = () => {
22
- return () => jsx("div", {
23
- class: "middle",
24
- children: [
25
- jsx("p", { children: "Fragment in middle" }),
26
- jsx(NestedComponent, {}),
27
- jsx("ul", {
28
- children: [
29
- jsx("li", { children: "Item 1" }),
30
- jsx("li", { children: "Item 2" }),
31
- ],
32
- }),
33
- ],
34
- });
35
- };
36
- const App = () => {
37
- return () => jsx(Fragment, {
38
- children: [
39
- jsx("header", {
40
- children: [
41
- jsx("h1", { children: "Header" }),
42
- jsx(MiddleComponent, {}),
43
- ],
44
- }),
45
- jsx("main", {
46
- children: jsx("section", {
47
- children: jsx("div", { children: jsx(NestedComponent, {}) }),
48
- }),
49
- }),
50
- ],
51
- });
52
- };
53
- const container = document.createElement("div");
54
- render(jsx(App, {}), container);
55
- expect(container.querySelector("header h1")?.textContent).toBe("Header");
56
- expect(container.querySelector(".middle p")?.textContent).toBe("Fragment in middle");
57
- expect(container.querySelector(".middle span")?.textContent).toBe("Nested");
58
- expect(container.querySelector(".middle strong")?.textContent).toBe("Component");
59
- expect(container.querySelectorAll("li").length).toBe(2);
60
- expect(container.querySelector("main span")?.textContent).toBe("Nested");
61
- expect(container.querySelector("main strong")?.textContent).toBe("Component");
62
- });
63
- it("should handle multiple fragments and components at same level", () => {
64
- const Component1 = () => () => jsx("span", { children: "C1" });
65
- const Component2 = () => () => jsx("span", { children: "C2" });
66
- const Component3 = () => () => jsx("span", { children: "C3" });
67
- const App = () => {
68
- return () => jsx("div", {
69
- children: [
70
- jsx(Component1, {}),
71
- jsx("strong", { children: "Between" }),
72
- jsx(Component2, {}),
73
- jsx("em", { children: "Middle" }),
74
- jsx(Component3, {}),
75
- jsx("i", { children: "End" }),
76
- ],
77
- });
78
- };
79
- const container = document.createElement("div");
80
- render(jsx(App, {}), container);
81
- const spans = container.querySelectorAll("span");
82
- expect(spans.length).toBe(3);
83
- expect(spans[0].textContent).toBe("C1");
84
- expect(spans[1].textContent).toBe("C2");
85
- expect(spans[2].textContent).toBe("C3");
86
- expect(container.querySelector("strong")?.textContent).toBe("Between");
87
- expect(container.querySelector("em")?.textContent).toBe("Middle");
88
- expect(container.querySelector("i")?.textContent).toBe("End");
89
- });
90
- it("should update multiple nested components when state changes", async () => {
91
- let globalCount;
92
- const Counter = () => {
93
- return () => jsx("span", { class: "counter", children: globalCount.value });
94
- };
95
- const DoubleCounter = () => {
96
- return () => jsx("span", { class: "double", children: globalCount.value * 2 });
97
- };
98
- const NestedCounters = () => {
99
- return () => jsx(Fragment, {
100
- children: [
101
- jsx(Counter, {}),
102
- jsx("div", {
103
- children: [jsx(DoubleCounter, {}), jsx(Counter, {})],
104
- }),
105
- ],
106
- });
107
- };
108
- const App = () => {
109
- const state = createState({ value: 0 });
110
- globalCount = state;
111
- return () => jsx("div", {
112
- children: [
113
- jsx(NestedCounters, {}),
114
- jsx("section", {
115
- children: [
116
- jsx(DoubleCounter, {}),
117
- jsx(Counter, {}),
118
- jsx(NestedCounters, {}),
119
- ],
120
- }),
121
- ],
122
- });
123
- };
124
- const container = document.createElement("div");
125
- render(jsx(App, {}), container);
126
- // Initial state: count = 0
127
- let counters = container.querySelectorAll(".counter");
128
- let doubles = container.querySelectorAll(".double");
129
- expect(counters.length).toBe(5);
130
- expect(doubles.length).toBe(3);
131
- counters.forEach((counter) => {
132
- expect(counter.textContent).toBe("0");
133
- });
134
- doubles.forEach((double) => {
135
- expect(double.textContent).toBe("0");
136
- });
137
- // Update state to 5
138
- globalCount.value = 5;
139
- await vi.runAllTimersAsync();
140
- counters = container.querySelectorAll(".counter");
141
- doubles = container.querySelectorAll(".double");
142
- counters.forEach((counter) => {
143
- expect(counter.textContent).toBe("5");
144
- });
145
- doubles.forEach((double) => {
146
- expect(double.textContent).toBe("10");
147
- });
148
- // Update state to 10
149
- globalCount.value = 10;
150
- await vi.runAllTimersAsync();
151
- counters = container.querySelectorAll(".counter");
152
- doubles = container.querySelectorAll(".double");
153
- counters.forEach((counter) => {
154
- expect(counter.textContent).toBe("10");
155
- });
156
- doubles.forEach((double) => {
157
- expect(double.textContent).toBe("20");
158
- });
159
- });
160
- it("should handle components that change their return structure based on state", async () => {
161
- let globalState;
162
- const DynamicComponent = () => {
163
- return () => {
164
- const currentMode = globalState.mode;
165
- if (currentMode === "list") {
166
- return jsx("ul", {
167
- class: "list",
168
- children: [
169
- jsx("li", { children: "Item 1" }),
170
- jsx("li", { children: "Item 2" }),
171
- jsx("li", { children: "Item 3" }),
172
- ],
173
- });
174
- }
175
- if (currentMode === "grid") {
176
- return jsx("div", {
177
- class: "grid",
178
- children: [
179
- jsx("div", { class: "card", children: "Card 1" }),
180
- jsx("div", { class: "card", children: "Card 2" }),
181
- jsx("div", { class: "card", children: "Card 3" }),
182
- ],
183
- });
184
- }
185
- return jsx("table", {
186
- class: "table",
187
- children: jsx("tbody", {
188
- children: jsx("tr", {
189
- children: [
190
- jsx("td", { children: "Cell 1" }),
191
- jsx("td", { children: "Cell 2" }),
192
- jsx("td", { children: "Cell 3" }),
193
- ],
194
- }),
195
- }),
196
- });
197
- };
198
- };
199
- const NestedDynamic = () => {
200
- return () => jsx(Fragment, {
201
- children: [
202
- jsx("h2", { children: `Mode: ${globalState.mode}` }),
203
- jsx(DynamicComponent, {}),
204
- ],
205
- });
206
- };
207
- const App = () => {
208
- const state = createState({
209
- mode: "list",
210
- });
211
- globalState = state;
212
- return () => jsx("div", {
213
- children: [
214
- jsx(NestedDynamic, {}),
215
- jsx("footer", {
216
- children: jsx(DynamicComponent, {}),
217
- }),
218
- ],
219
- });
220
- };
221
- const container = document.createElement("div");
222
- render(jsx(App, {}), container);
223
- // Initial state: list mode
224
- expect(container.querySelector("h2")?.textContent).toBe("Mode: list");
225
- expect(container.querySelectorAll(".list").length).toBe(2);
226
- expect(container.querySelectorAll("li").length).toBe(6);
227
- expect(container.querySelector(".grid")).toBeNull();
228
- expect(container.querySelector(".table")).toBeNull();
229
- // Switch to grid mode
230
- globalState.mode = "grid";
231
- await vi.runAllTimersAsync();
232
- expect(container.querySelector("h2")?.textContent).toBe("Mode: grid");
233
- expect(container.querySelectorAll(".grid").length).toBe(2);
234
- expect(container.querySelectorAll(".card").length).toBe(6);
235
- expect(container.querySelector(".list")).toBeNull();
236
- expect(container.querySelector(".table")).toBeNull();
237
- // Switch to table mode
238
- globalState.mode = "table";
239
- await vi.runAllTimersAsync();
240
- return;
241
- expect(container.querySelector("h2")?.textContent).toBe("Mode: table");
242
- expect(container.querySelectorAll(".table").length).toBe(2);
243
- expect(container.querySelectorAll("td").length).toBe(6);
244
- expect(container.querySelector(".list")).toBeNull();
245
- expect(container.querySelector(".grid")).toBeNull();
246
- // Switch back to list
247
- globalState.mode = "list";
248
- await vi.runAllTimersAsync();
249
- expect(container.querySelector("h2")?.textContent).toBe("Mode: list");
250
- expect(container.querySelectorAll(".list").length).toBe(2);
251
- expect(container.querySelectorAll("li").length).toBe(6);
252
- });
253
- it("should handle deeply nested state changes with fragments", async () => {
254
- let globalUser;
255
- const UserName = () => {
256
- return () => jsx("span", { class: "name", children: globalUser.name });
257
- };
258
- const UserAge = () => {
259
- return () => jsx("span", { class: "age", children: globalUser.age });
260
- };
261
- const UserRole = () => {
262
- return () => jsx("span", { class: "role", children: globalUser.role });
263
- };
264
- const UserInfo = () => {
265
- return () => jsx(Fragment, {
266
- children: [
267
- jsx(UserName, {}),
268
- jsx("div", {
269
- class: "details",
270
- children: [jsx(UserAge, {}), jsx(UserRole, {})],
271
- }),
272
- ],
273
- });
274
- };
275
- const UserCard = () => {
276
- return () => jsx("div", {
277
- class: "card",
278
- children: [
279
- jsx("h3", { children: "User Profile" }),
280
- jsx(UserInfo, {}),
281
- jsx("footer", { children: ["Role: ", jsx(UserRole, {})] }),
282
- ],
283
- });
284
- };
285
- const App = () => {
286
- const state = createState({ name: "John", age: 30, role: "admin" });
287
- globalUser = state;
288
- return () => jsx(Fragment, {
289
- children: [
290
- jsx(UserCard, {}),
291
- jsx("aside", {
292
- children: [
293
- jsx(UserName, {}),
294
- " is ",
295
- jsx(UserAge, {}),
296
- " years old",
297
- ],
298
- }),
299
- ],
300
- });
301
- };
302
- const container = document.createElement("div");
303
- render(jsx(App, {}), container);
304
- expect(container.querySelector(".name")?.textContent).toBe("John");
305
- expect(container.querySelectorAll(".age")[0].textContent).toBe("30");
306
- expect(container.querySelectorAll(".role").length).toBe(2);
307
- expect(container.querySelector("aside")?.textContent).toBe("John is 30 years old");
308
- // Update user
309
- globalUser.name = "Jane";
310
- globalUser.age = 25;
311
- globalUser.role = "user";
312
- await vi.runAllTimersAsync();
313
- expect(container.querySelector(".name")?.textContent).toBe("Jane");
314
- expect(container.querySelectorAll(".age")[0].textContent).toBe("25");
315
- const roles = container.querySelectorAll(".role");
316
- roles.forEach((role) => {
317
- expect(role.textContent).toBe("user");
318
- });
319
- expect(container.querySelector("aside")?.textContent).toBe("Jane is 25 years old");
320
- // Update user again
321
- globalUser.name = "Bob";
322
- globalUser.age = 40;
323
- globalUser.role = "moderator";
324
- await vi.runAllTimersAsync();
325
- expect(container.querySelector(".name")?.textContent).toBe("Bob");
326
- expect(container.querySelectorAll(".age")[0].textContent).toBe("40");
327
- const newRoles = container.querySelectorAll(".role");
328
- newRoles.forEach((role) => {
329
- expect(role.textContent).toBe("moderator");
330
- });
331
- expect(container.querySelector("aside")?.textContent).toBe("Bob is 40 years old");
332
- });
333
- it("should handle mixed nested updates with conditional rendering", async () => {
334
- let globalState;
335
- const Details = () => {
336
- return () => jsx(Fragment, {
337
- children: [
338
- jsx("p", { children: `Count: ${globalState.count}` }),
339
- jsx("p", { children: `Double: ${globalState.count * 2}` }),
340
- ],
341
- });
342
- };
343
- const Card = () => {
344
- return () => jsx("div", {
345
- class: "card",
346
- children: [
347
- jsx("h4", { children: `Card ${globalState.count}` }),
348
- globalState.showDetails
349
- ? jsx(Details, {})
350
- : jsx("p", { children: "No details" }),
351
- ],
352
- });
353
- };
354
- const App = () => {
355
- const state = createState({ showDetails: false, count: 0 });
356
- globalState = state;
357
- return () => jsx(Fragment, {
358
- children: [
359
- jsx(Card, {}),
360
- jsx("div", {
361
- children: [
362
- jsx(Card, {}),
363
- jsx("span", { children: `Total: ${state.count}` }),
364
- ],
365
- }),
366
- ],
367
- });
368
- };
369
- const container = document.createElement("div");
370
- render(jsx(App, {}), container);
371
- // Initial state
372
- expect(container.querySelectorAll(".card h4")[0].textContent).toBe("Card 0");
373
- expect(container.querySelectorAll(".card h4")[1].textContent).toBe("Card 0");
374
- expect(container.querySelectorAll("p").length).toBe(2);
375
- expect(container.querySelectorAll("p")[0].textContent).toBe("No details");
376
- expect(container.querySelector("span")?.textContent).toBe("Total: 0");
377
- // Show details
378
- globalState.showDetails = true;
379
- await vi.runAllTimersAsync();
380
- expect(container.querySelectorAll("p").length).toBe(4);
381
- expect(container.querySelectorAll("p")[0].textContent).toBe("Count: 0");
382
- expect(container.querySelectorAll("p")[1].textContent).toBe("Double: 0");
383
- // Increment count
384
- globalState.count = 5;
385
- await vi.runAllTimersAsync();
386
- expect(container.querySelectorAll(".card h4")[0].textContent).toBe("Card 5");
387
- expect(container.querySelectorAll(".card h4")[1].textContent).toBe("Card 5");
388
- expect(container.querySelectorAll("p")[0].textContent).toBe("Count: 5");
389
- expect(container.querySelectorAll("p")[1].textContent).toBe("Double: 10");
390
- expect(container.querySelector("span")?.textContent).toBe("Total: 5");
391
- // Hide details and increment
392
- globalState.showDetails = false;
393
- globalState.count = 10;
394
- await vi.runAllTimersAsync();
395
- expect(container.querySelectorAll(".card h4")[0].textContent).toBe("Card 10");
396
- expect(container.querySelectorAll("p").length).toBe(2);
397
- expect(container.querySelectorAll("p")[0].textContent).toBe("No details");
398
- expect(container.querySelector("span")?.textContent).toBe("Total: 10");
399
- });
400
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=component.cleanup.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"component.cleanup.test.d.ts","sourceRoot":"","sources":["../../src/vdom/component.cleanup.test.tsx"],"names":[],"mappings":""}