kempo-ui 0.0.2 → 0.0.4

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 (278) hide show
  1. package/.github/copilot-instructions.md +149 -149
  2. package/.github/workflows/publish-major.yml +39 -0
  3. package/.github/workflows/publish-minor.yml +39 -0
  4. package/.github/workflows/{publish-npm.yml → publish-patch.yml} +44 -44
  5. package/.vscode/settings.json +2 -0
  6. package/CONTRIBUTING.md +149 -149
  7. package/README.md +0 -0
  8. package/dist/kempo-hljs.css +1 -0
  9. package/dist/kempo-vars.css +0 -0
  10. package/dist/src/components/Accordion.js +36 -0
  11. package/dist/src/components/Card.js +37 -0
  12. package/dist/src/components/Collapsible.js +41 -0
  13. package/dist/src/components/ContentSlider.js +44 -0
  14. package/dist/src/components/Dialog.js +113 -0
  15. package/dist/src/components/FocusCapture.js +7 -0
  16. package/dist/src/components/Icon.js +10 -0
  17. package/dist/src/components/Import.js +1 -0
  18. package/dist/src/components/PersistantCollapsible.js +1 -0
  19. package/dist/src/components/PhotoViewer.js +135 -0
  20. package/dist/src/components/Resize.js +96 -0
  21. package/dist/src/components/ShadowComponent.js +1 -0
  22. package/dist/src/components/ShowMore.js +42 -0
  23. package/dist/src/components/SideMenu.js +97 -0
  24. package/dist/src/components/Split.js +84 -0
  25. package/dist/src/components/Tabs.js +155 -0
  26. package/dist/src/components/Tags.js +69 -0
  27. package/dist/src/components/ThemeSwitcher.js +23 -0
  28. package/dist/src/components/Timestamp.js +1 -0
  29. package/dist/src/lit-all.min.js +120 -0
  30. package/dist/src/utils/debounce.js +1 -0
  31. package/dist/src/utils/drag.js +1 -0
  32. package/dist/src/utils/formatTimestamp.js +1 -0
  33. package/dist/src/utils/propConverters.js +1 -0
  34. package/dist/src/utils/watchWindowSize.js +1 -0
  35. package/docs/components/accordion.html +166 -0
  36. package/docs/components/card.html +92 -0
  37. package/docs/components/collapsible.html +198 -0
  38. package/docs/components/content-slider.html +223 -0
  39. package/docs/components/dialog.html +251 -0
  40. package/docs/components/focus-capture.html +67 -0
  41. package/docs/components/icon.html +158 -0
  42. package/docs/components/import.html +73 -0
  43. package/docs/components/persistant-collapsible.html +123 -0
  44. package/docs/components/photo-viewer.html +226 -0
  45. package/docs/components/resize.html +178 -0
  46. package/docs/components/show-more.html +129 -0
  47. package/docs/components/side-menu.html +159 -0
  48. package/docs/components/split.html +147 -0
  49. package/docs/components/table.html +312 -0
  50. package/docs/components/tableControls.html +77 -0
  51. package/docs/components/tableCustomFields.html +113 -0
  52. package/docs/components/tableFetchRecords.html +114 -0
  53. package/docs/components/tableFieldSortHide.html +75 -0
  54. package/docs/components/tablePagination.html +100 -0
  55. package/docs/components/tableRecordEditing.html +144 -0
  56. package/docs/components/tableRecordFiltering.html +88 -0
  57. package/docs/components/tableRecordHiding.html +80 -0
  58. package/docs/components/tableRecordSearching.html +75 -0
  59. package/docs/components/tableRecordSelection.html +75 -0
  60. package/docs/components/tableRowControls.html +78 -0
  61. package/docs/components/tableSorting.html +73 -0
  62. package/docs/components/tabs.html +180 -0
  63. package/docs/components/tags.html +110 -0
  64. package/docs/components/theme-switcher.html +126 -0
  65. package/docs/components/timestamp.html +82 -0
  66. package/docs/components/toast.html +319 -0
  67. package/docs/components/toggle.html +156 -0
  68. package/docs/dev.config.json +20 -0
  69. package/docs/icons/add.svg +1 -0
  70. package/docs/icons/arrow-back.svg +1 -0
  71. package/docs/icons/arrow-down-double.svg +1 -0
  72. package/docs/icons/arrow-down.svg +1 -0
  73. package/docs/icons/arrow-forward.svg +1 -0
  74. package/docs/icons/arrow-up-double.svg +1 -0
  75. package/docs/icons/arrow-up.svg +1 -0
  76. package/docs/icons/cards.svg +1 -0
  77. package/docs/icons/check.svg +1 -0
  78. package/docs/icons/chevron-left.svg +1 -0
  79. package/docs/icons/chevron-right.svg +1 -0
  80. package/docs/icons/close.svg +2 -0
  81. package/docs/icons/compare.svg +1 -0
  82. package/docs/icons/delete.svg +1 -0
  83. package/docs/icons/drag-handle.svg +1 -0
  84. package/docs/icons/drawing2.svg +124 -0
  85. package/docs/icons/edit.svg +1 -0
  86. package/docs/icons/error.svg +1 -0
  87. package/docs/icons/export-file.svg +1 -0
  88. package/docs/icons/file-text.svg +1 -0
  89. package/docs/icons/file.svg +1 -0
  90. package/docs/icons/filter-off.svg +1 -0
  91. package/docs/icons/filter.svg +1 -0
  92. package/docs/icons/first.svg +1 -0
  93. package/docs/icons/folder-clear.svg +1 -0
  94. package/docs/icons/folder-create.svg +1 -0
  95. package/docs/icons/folder-open.svg +1 -0
  96. package/docs/icons/folder.svg +1 -0
  97. package/docs/icons/hide.svg +1 -0
  98. package/docs/icons/image.svg +1 -0
  99. package/docs/icons/label-add.svg +1 -0
  100. package/docs/icons/label.svg +1 -0
  101. package/docs/icons/last.svg +1 -0
  102. package/docs/icons/menu.svg +1 -0
  103. package/docs/icons/mode-auto.svg +1 -0
  104. package/docs/icons/mode-dark.svg +1 -0
  105. package/docs/icons/mode-light.svg +1 -0
  106. package/docs/icons/open-in-browser.svg +1 -0
  107. package/docs/icons/pause.svg +1 -0
  108. package/docs/icons/play.svg +1 -0
  109. package/docs/icons/refresh.svg +1 -0
  110. package/docs/icons/remove.svg +1 -0
  111. package/docs/icons/save.svg +1 -0
  112. package/docs/icons/search.svg +1 -0
  113. package/docs/icons/settings.svg +1 -0
  114. package/docs/icons/show.svg +1 -0
  115. package/docs/icons/storage.svg +1 -0
  116. package/docs/icons/table-visibility.svg +1 -0
  117. package/docs/icons/tag.svg +1 -0
  118. package/docs/icons/tools.svg +1 -0
  119. package/docs/icons/trash-x.svg +1 -0
  120. package/docs/icons/warning.svg +1 -0
  121. package/docs/index.html +28 -21
  122. package/docs/kempo-hljs.css +1 -0
  123. package/docs/media/civic.jpg +0 -0
  124. package/docs/media/corvette.jpg +0 -0
  125. package/docs/media/evo.jpg +0 -0
  126. package/docs/media/gtr.jpg +0 -0
  127. package/docs/media/nsx.jpg +0 -0
  128. package/docs/nav.inc.html +67 -0
  129. package/docs/nav.inc.js +4 -0
  130. package/{config/production.json → docs/prod.config.json} +20 -16
  131. package/docs/src/components/Accordion.js +36 -0
  132. package/docs/src/components/Card.js +37 -0
  133. package/docs/src/components/Collapsible.js +41 -0
  134. package/docs/src/components/ContentSlider.js +44 -0
  135. package/docs/src/components/Dialog.js +113 -0
  136. package/docs/src/components/FocusCapture.js +7 -0
  137. package/docs/src/components/HybridComponent.js +1 -0
  138. package/docs/src/components/Icon.js +10 -0
  139. package/docs/src/components/Import.js +1 -0
  140. package/docs/src/components/LightComponent.js +1 -0
  141. package/docs/src/components/PersistantCollapsible.js +1 -0
  142. package/docs/src/components/PhotoViewer.js +135 -0
  143. package/docs/src/components/Resize.js +96 -0
  144. package/docs/src/components/ShadowComponent.js +1 -0
  145. package/docs/src/components/ShowMore.js +42 -0
  146. package/docs/src/components/SideMenu.js +97 -0
  147. package/docs/src/components/Split.js +84 -0
  148. package/docs/src/components/Tabs.js +155 -0
  149. package/docs/src/components/Tags.js +69 -0
  150. package/docs/src/components/ThemeSwitcher.js +23 -0
  151. package/docs/src/components/Timestamp.js +1 -0
  152. package/docs/src/lit-all.min.js +120 -0
  153. package/docs/src/utils/debounce.js +1 -0
  154. package/docs/src/utils/drag.js +1 -0
  155. package/docs/src/utils/formatTimestamp.js +1 -0
  156. package/docs/src/utils/propConverters.js +1 -0
  157. package/docs/src/utils/watchWindowSize.js +1 -0
  158. package/docs/styles.css +6 -0
  159. package/docs/utils/debounce.html +78 -0
  160. package/docs/utils/drag.html +104 -0
  161. package/docs/utils/formatTimestamp.html +114 -0
  162. package/docs/utils/propConverters.html +132 -0
  163. package/docs/utils/watchWindowSize.html +166 -0
  164. package/icons/add.svg +1 -0
  165. package/icons/arrow-back.svg +1 -0
  166. package/icons/arrow-down-double.svg +1 -0
  167. package/icons/arrow-down.svg +1 -0
  168. package/icons/arrow-forward.svg +1 -0
  169. package/icons/arrow-up-double.svg +1 -0
  170. package/icons/arrow-up.svg +1 -0
  171. package/icons/cards.svg +1 -0
  172. package/icons/check.svg +1 -0
  173. package/icons/chevron-left.svg +1 -0
  174. package/icons/chevron-right.svg +1 -0
  175. package/icons/close.svg +2 -0
  176. package/icons/compare.svg +1 -0
  177. package/icons/delete.svg +1 -0
  178. package/icons/drag-handle.svg +1 -0
  179. package/icons/drawing2.svg +124 -0
  180. package/icons/edit.svg +1 -0
  181. package/icons/error.svg +1 -0
  182. package/icons/export-file.svg +1 -0
  183. package/icons/file-text.svg +1 -0
  184. package/icons/file.svg +1 -0
  185. package/icons/filter-off.svg +1 -0
  186. package/icons/filter.svg +1 -0
  187. package/icons/first.svg +1 -0
  188. package/icons/folder-clear.svg +1 -0
  189. package/icons/folder-create.svg +1 -0
  190. package/icons/folder-open.svg +1 -0
  191. package/icons/folder.svg +1 -0
  192. package/icons/hide.svg +1 -0
  193. package/icons/image.svg +1 -0
  194. package/icons/label-add.svg +1 -0
  195. package/icons/label.svg +1 -0
  196. package/icons/last.svg +1 -0
  197. package/icons/menu.svg +1 -0
  198. package/icons/mode-auto.svg +1 -0
  199. package/icons/mode-dark.svg +1 -0
  200. package/icons/mode-light.svg +1 -0
  201. package/icons/open-in-browser.svg +1 -0
  202. package/icons/pause.svg +1 -0
  203. package/icons/play.svg +1 -0
  204. package/icons/refresh.svg +1 -0
  205. package/icons/remove.svg +1 -0
  206. package/icons/save.svg +1 -0
  207. package/icons/search.svg +1 -0
  208. package/icons/settings.svg +1 -0
  209. package/icons/show.svg +1 -0
  210. package/icons/storage.svg +1 -0
  211. package/icons/table-visibility.svg +1 -0
  212. package/icons/tag.svg +1 -0
  213. package/icons/tools.svg +1 -0
  214. package/icons/trash-x.svg +1 -0
  215. package/icons/warning.svg +1 -0
  216. package/package.json +2 -2
  217. package/scripts/build.js +109 -138
  218. package/scripts/docs.js +62 -60
  219. package/src/components/Accordion.js +229 -0
  220. package/src/components/Card.js +66 -0
  221. package/src/components/Collapsible.js +109 -0
  222. package/src/components/ContentSlider.js +205 -0
  223. package/src/components/Dialog.js +368 -0
  224. package/src/components/FocusCapture.js +23 -0
  225. package/src/components/HybridComponent.js +40 -40
  226. package/src/components/Icon.js +155 -0
  227. package/src/components/Import.js +104 -0
  228. package/src/components/LightComponent.js +32 -32
  229. package/src/components/PersistantCollapsible.js +69 -0
  230. package/src/components/PhotoViewer.js +368 -0
  231. package/src/components/Resize.js +210 -0
  232. package/src/components/ShadowComponent.js +32 -17
  233. package/src/components/ShowMore.js +109 -0
  234. package/src/components/SideMenu.js +167 -0
  235. package/src/components/Sortable.js +193 -0
  236. package/src/components/Split.js +192 -0
  237. package/src/components/Table.js +1202 -0
  238. package/src/components/Tabs.js +428 -0
  239. package/src/components/Tags.js +253 -0
  240. package/src/components/ThemeSwitcher.js +108 -0
  241. package/src/components/Timestamp.js +31 -0
  242. package/src/components/Toast.js +454 -0
  243. package/src/components/Toggle.js +173 -0
  244. package/src/components/tableControls/DeleteRecord.js +29 -0
  245. package/src/components/tableControls/Edit.js +88 -0
  246. package/src/components/tableControls/ExportCSV.js +71 -0
  247. package/src/components/tableControls/ExportJson.js +55 -0
  248. package/src/components/tableControls/FieldSortHide.js +76 -0
  249. package/src/components/tableControls/Filters.js +114 -0
  250. package/src/components/tableControls/FirstPage.js +65 -0
  251. package/src/components/tableControls/HiddenCount.js +45 -0
  252. package/src/components/tableControls/Hide.js +34 -0
  253. package/src/components/tableControls/LastPage.js +65 -0
  254. package/src/components/tableControls/NextPage.js +65 -0
  255. package/src/components/tableControls/PageSelect.js +109 -0
  256. package/src/components/tableControls/PageSize.js +68 -0
  257. package/src/components/tableControls/PrevPage.js +65 -0
  258. package/src/components/tableControls/Search.js +58 -0
  259. package/src/components/tableControls/ShowAll.js +34 -0
  260. package/src/components/tableControls/TableControl.js +105 -0
  261. package/src/kempo-hljs.css +146 -0
  262. package/src/utils/debounce.js +9 -0
  263. package/src/utils/drag.js +80 -0
  264. package/src/utils/formatTimestamp.js +27 -0
  265. package/src/utils/propConverters.js +11 -0
  266. package/src/utils/toTitleCase.js +9 -0
  267. package/src/utils/watchWindowSize.js +16 -0
  268. package/tests/HybridComponent.browser-test.js +214 -214
  269. package/tests/LightComponent.browser-test.js +169 -169
  270. package/tests/ShadowComponent.browser-test.js +130 -130
  271. package/config/development.json +0 -14
  272. package/docs/components/ShadowComponent.js +0 -1
  273. package/src/utils/cli.js +0 -43
  274. package/src/utils/fs-utils.js +0 -41
  275. /package/{docs → dist/src}/components/HybridComponent.js +0 -0
  276. /package/{docs → dist/src}/components/LightComponent.js +0 -0
  277. /package/docs/{utils → src/utils}/cli.js +0 -0
  278. /package/docs/{utils → src/utils}/fs-utils.js +0 -0
@@ -1,169 +1,169 @@
1
- import LightComponent from '/src/components/LightComponent.js';
2
- import { html } from '/src/lit-all.min.js';
3
-
4
- class TestLightComponent extends LightComponent {
5
- renderLightDom() {
6
- return html`<p>Test light content</p>`;
7
- }
8
- }
9
-
10
- customElements.define('test-light-component', TestLightComponent);
11
-
12
- export default {
13
- 'should not create shadow root': async ({pass, fail, log}) => {
14
- const component = new TestLightComponent();
15
- document.body.appendChild(component);
16
-
17
- await new Promise(resolve => setTimeout(resolve, 0));
18
-
19
- if(component.shadowRoot) {
20
- document.body.removeChild(component);
21
- fail('LightComponent should not have shadow root');
22
- return;
23
- }
24
-
25
- log('✓ No shadow root created as expected');
26
- document.body.removeChild(component);
27
- pass('LightComponent does not create shadow root');
28
- },
29
-
30
- 'should have itself as render root': async ({pass, fail, log}) => {
31
- const component = new TestLightComponent();
32
- document.body.appendChild(component);
33
-
34
- await new Promise(resolve => setTimeout(resolve, 0));
35
-
36
- if(component.renderRoot !== component) {
37
- document.body.removeChild(component);
38
- fail('Render root should be the component itself');
39
- return;
40
- }
41
-
42
- log('✓ Component is its own render root');
43
- document.body.removeChild(component);
44
- pass('LightComponent uses itself as render root');
45
- },
46
-
47
- 'should create light root container': async ({pass, fail, log}) => {
48
- const component = new TestLightComponent();
49
- document.body.appendChild(component);
50
-
51
- await new Promise(resolve => setTimeout(resolve, 0));
52
-
53
- if(!component.lightRoot) {
54
- document.body.removeChild(component);
55
- fail('Component should have lightRoot property');
56
- return;
57
- }
58
-
59
- if(component.lightRoot.tagName !== 'DIV') {
60
- document.body.removeChild(component);
61
- fail('lightRoot should be a div element');
62
- return;
63
- }
64
-
65
- if(component.lightRoot.style.display !== 'contents') {
66
- document.body.removeChild(component);
67
- fail('lightRoot should have display: contents');
68
- return;
69
- }
70
-
71
- if(component.lightRoot.parentNode !== component) {
72
- document.body.removeChild(component);
73
- fail('lightRoot should be child of component');
74
- return;
75
- }
76
-
77
- log('✓ Light root container properly configured');
78
- document.body.removeChild(component);
79
- pass('LightComponent creates proper light root container');
80
- },
81
-
82
- 'should render content in light root': async ({pass, fail, log}) => {
83
- const component = new TestLightComponent();
84
- document.body.appendChild(component);
85
-
86
- await new Promise(resolve => setTimeout(resolve, 10));
87
-
88
- const paragraph = component.lightRoot.querySelector('p');
89
- if(!paragraph) {
90
- document.body.removeChild(component);
91
- fail('Component should render paragraph in light root');
92
- return;
93
- }
94
-
95
- if(paragraph.textContent !== 'Test light content') {
96
- document.body.removeChild(component);
97
- fail(`Expected "Test light content", got "${paragraph.textContent}"`);
98
- return;
99
- }
100
-
101
- log('✓ Content rendered properly in light root');
102
- document.body.removeChild(component);
103
- pass('LightComponent renders content in light DOM');
104
- },
105
-
106
- 'should preserve natural children': async ({pass, fail, log}) => {
107
- const component = new TestLightComponent();
108
- const naturalChild = document.createElement('span');
109
- naturalChild.textContent = 'Natural child';
110
- component.appendChild(naturalChild);
111
- document.body.appendChild(component);
112
-
113
- await new Promise(resolve => setTimeout(resolve, 10));
114
-
115
- const foundNaturalChild = component.querySelector('span');
116
- if(!foundNaturalChild) {
117
- document.body.removeChild(component);
118
- fail('Natural child should be preserved');
119
- return;
120
- }
121
-
122
- if(foundNaturalChild.textContent !== 'Natural child') {
123
- document.body.removeChild(component);
124
- fail('Natural child content should be preserved');
125
- return;
126
- }
127
-
128
- const renderedContent = component.lightRoot.querySelector('p');
129
- if(!renderedContent) {
130
- document.body.removeChild(component);
131
- fail('Rendered content should also be present');
132
- return;
133
- }
134
-
135
- log('✓ Natural children preserved alongside rendered content');
136
- document.body.removeChild(component);
137
- pass('LightComponent preserves natural children');
138
- },
139
-
140
- 'should call super.updated() requirement': async ({pass, fail, log}) => {
141
- class BadLightComponent extends LightComponent {
142
- updated() {
143
- // Intentionally not calling super.updated()
144
- }
145
-
146
- renderLightDom() {
147
- return html`<p>Should not render</p>`;
148
- }
149
- }
150
-
151
- customElements.define('bad-light-component', BadLightComponent);
152
-
153
- const component = new BadLightComponent();
154
- document.body.appendChild(component);
155
-
156
- await new Promise(resolve => setTimeout(resolve, 10));
157
-
158
- const paragraph = component.lightRoot?.querySelector('p');
159
- if(paragraph) {
160
- document.body.removeChild(component);
161
- fail('Content should not render without super.updated() call');
162
- return;
163
- }
164
-
165
- log('✓ Content does not render without super.updated()');
166
- document.body.removeChild(component);
167
- pass('LightComponent requires super.updated() to function');
168
- }
169
- };
1
+ import LightComponent from '/src/components/LightComponent.js';
2
+ import { html } from '/src/lit-all.min.js';
3
+
4
+ class TestLightComponent extends LightComponent {
5
+ renderLightDom() {
6
+ return html`<p>Test light content</p>`;
7
+ }
8
+ }
9
+
10
+ customElements.define('test-light-component', TestLightComponent);
11
+
12
+ export default {
13
+ 'should not create shadow root': async ({pass, fail, log}) => {
14
+ const component = new TestLightComponent();
15
+ document.body.appendChild(component);
16
+
17
+ await new Promise(resolve => setTimeout(resolve, 0));
18
+
19
+ if(component.shadowRoot) {
20
+ document.body.removeChild(component);
21
+ fail('LightComponent should not have shadow root');
22
+ return;
23
+ }
24
+
25
+ log('✓ No shadow root created as expected');
26
+ document.body.removeChild(component);
27
+ pass('LightComponent does not create shadow root');
28
+ },
29
+
30
+ 'should have itself as render root': async ({pass, fail, log}) => {
31
+ const component = new TestLightComponent();
32
+ document.body.appendChild(component);
33
+
34
+ await new Promise(resolve => setTimeout(resolve, 0));
35
+
36
+ if(component.renderRoot !== component) {
37
+ document.body.removeChild(component);
38
+ fail('Render root should be the component itself');
39
+ return;
40
+ }
41
+
42
+ log('✓ Component is its own render root');
43
+ document.body.removeChild(component);
44
+ pass('LightComponent uses itself as render root');
45
+ },
46
+
47
+ 'should create light root container': async ({pass, fail, log}) => {
48
+ const component = new TestLightComponent();
49
+ document.body.appendChild(component);
50
+
51
+ await new Promise(resolve => setTimeout(resolve, 0));
52
+
53
+ if(!component.lightRoot) {
54
+ document.body.removeChild(component);
55
+ fail('Component should have lightRoot property');
56
+ return;
57
+ }
58
+
59
+ if(component.lightRoot.tagName !== 'DIV') {
60
+ document.body.removeChild(component);
61
+ fail('lightRoot should be a div element');
62
+ return;
63
+ }
64
+
65
+ if(component.lightRoot.style.display !== 'contents') {
66
+ document.body.removeChild(component);
67
+ fail('lightRoot should have display: contents');
68
+ return;
69
+ }
70
+
71
+ if(component.lightRoot.parentNode !== component) {
72
+ document.body.removeChild(component);
73
+ fail('lightRoot should be child of component');
74
+ return;
75
+ }
76
+
77
+ log('✓ Light root container properly configured');
78
+ document.body.removeChild(component);
79
+ pass('LightComponent creates proper light root container');
80
+ },
81
+
82
+ 'should render content in light root': async ({pass, fail, log}) => {
83
+ const component = new TestLightComponent();
84
+ document.body.appendChild(component);
85
+
86
+ await new Promise(resolve => setTimeout(resolve, 10));
87
+
88
+ const paragraph = component.lightRoot.querySelector('p');
89
+ if(!paragraph) {
90
+ document.body.removeChild(component);
91
+ fail('Component should render paragraph in light root');
92
+ return;
93
+ }
94
+
95
+ if(paragraph.textContent !== 'Test light content') {
96
+ document.body.removeChild(component);
97
+ fail(`Expected "Test light content", got "${paragraph.textContent}"`);
98
+ return;
99
+ }
100
+
101
+ log('✓ Content rendered properly in light root');
102
+ document.body.removeChild(component);
103
+ pass('LightComponent renders content in light DOM');
104
+ },
105
+
106
+ 'should preserve natural children': async ({pass, fail, log}) => {
107
+ const component = new TestLightComponent();
108
+ const naturalChild = document.createElement('span');
109
+ naturalChild.textContent = 'Natural child';
110
+ component.appendChild(naturalChild);
111
+ document.body.appendChild(component);
112
+
113
+ await new Promise(resolve => setTimeout(resolve, 10));
114
+
115
+ const foundNaturalChild = component.querySelector('span');
116
+ if(!foundNaturalChild) {
117
+ document.body.removeChild(component);
118
+ fail('Natural child should be preserved');
119
+ return;
120
+ }
121
+
122
+ if(foundNaturalChild.textContent !== 'Natural child') {
123
+ document.body.removeChild(component);
124
+ fail('Natural child content should be preserved');
125
+ return;
126
+ }
127
+
128
+ const renderedContent = component.lightRoot.querySelector('p');
129
+ if(!renderedContent) {
130
+ document.body.removeChild(component);
131
+ fail('Rendered content should also be present');
132
+ return;
133
+ }
134
+
135
+ log('✓ Natural children preserved alongside rendered content');
136
+ document.body.removeChild(component);
137
+ pass('LightComponent preserves natural children');
138
+ },
139
+
140
+ 'should call super.updated() requirement': async ({pass, fail, log}) => {
141
+ class BadLightComponent extends LightComponent {
142
+ updated() {
143
+ // Intentionally not calling super.updated()
144
+ }
145
+
146
+ renderLightDom() {
147
+ return html`<p>Should not render</p>`;
148
+ }
149
+ }
150
+
151
+ customElements.define('bad-light-component', BadLightComponent);
152
+
153
+ const component = new BadLightComponent();
154
+ document.body.appendChild(component);
155
+
156
+ await new Promise(resolve => setTimeout(resolve, 10));
157
+
158
+ const paragraph = component.lightRoot?.querySelector('p');
159
+ if(paragraph) {
160
+ document.body.removeChild(component);
161
+ fail('Content should not render without super.updated() call');
162
+ return;
163
+ }
164
+
165
+ log('✓ Content does not render without super.updated()');
166
+ document.body.removeChild(component);
167
+ pass('LightComponent requires super.updated() to function');
168
+ }
169
+ };
@@ -1,130 +1,130 @@
1
- import ShadowComponent from '/src/components/ShadowComponent.js';
2
- import { html } from '/src/lit-all.min.js';
3
-
4
- class TestShadowComponent extends ShadowComponent {
5
- render() {
6
- return html`<p>Test shadow content</p>`;
7
- }
8
- }
9
-
10
- customElements.define('test-shadow-component', TestShadowComponent);
11
-
12
- export default {
13
- 'should create shadow root with stylesheet': async ({pass, fail, log}) => {
14
- const component = new TestShadowComponent();
15
- document.body.appendChild(component);
16
-
17
- await new Promise(resolve => setTimeout(resolve, 0));
18
-
19
- if(!component.shadowRoot) {
20
- document.body.removeChild(component);
21
- fail('Component should have shadow root');
22
- return;
23
- }
24
-
25
- const stylesheetLink = component.shadowRoot.querySelector('link[href="/kempo.min.css"]');
26
- if(!stylesheetLink) {
27
- document.body.removeChild(component);
28
- fail('Shadow root should contain kempo.min.css link');
29
- return;
30
- }
31
-
32
- if(stylesheetLink.rel !== 'stylesheet') {
33
- document.body.removeChild(component);
34
- fail('Link should have rel="stylesheet"');
35
- return;
36
- }
37
-
38
- log('✓ Shadow root created with proper stylesheet');
39
- document.body.removeChild(component);
40
- pass('ShadowComponent creates shadow root with stylesheet injection');
41
- },
42
-
43
- 'should have render container as render root': async ({pass, fail, log}) => {
44
- const component = new TestShadowComponent();
45
- document.body.appendChild(component);
46
-
47
- await new Promise(resolve => setTimeout(resolve, 0));
48
-
49
- const renderRoot = component.renderRoot;
50
- if(!renderRoot) {
51
- document.body.removeChild(component);
52
- fail('Component should have render root');
53
- return;
54
- }
55
-
56
- if(renderRoot.tagName !== 'DIV') {
57
- document.body.removeChild(component);
58
- fail('Render root should be a div element');
59
- return;
60
- }
61
-
62
- if(renderRoot.parentNode !== component.shadowRoot) {
63
- document.body.removeChild(component);
64
- fail('Render root should be child of shadow root');
65
- return;
66
- }
67
-
68
- log('✓ Render root is properly configured div element');
69
- document.body.removeChild(component);
70
- pass('ShadowComponent has proper render container setup');
71
- },
72
-
73
- 'should render content inside render container': async ({pass, fail, log}) => {
74
- const component = new TestShadowComponent();
75
- document.body.appendChild(component);
76
-
77
- await new Promise(resolve => setTimeout(resolve, 10));
78
-
79
- const paragraph = component.renderRoot.querySelector('p');
80
- if(!paragraph) {
81
- document.body.removeChild(component);
82
- fail('Component should render paragraph element');
83
- return;
84
- }
85
-
86
- if(paragraph.textContent !== 'Test shadow content') {
87
- document.body.removeChild(component);
88
- fail(`Expected "Test shadow content", got "${paragraph.textContent}"`);
89
- return;
90
- }
91
-
92
- log('✓ Content rendered properly inside render container');
93
- document.body.removeChild(component);
94
- pass('ShadowComponent renders content correctly');
95
- },
96
-
97
- 'should maintain stylesheet after re-rendering': async ({pass, fail, log}) => {
98
- const component = new TestShadowComponent();
99
- document.body.appendChild(component);
100
-
101
- await new Promise(resolve => setTimeout(resolve, 0));
102
-
103
- const stylesheetBefore = component.shadowRoot.querySelector('link[href="/kempo.min.css"]');
104
- if(!stylesheetBefore) {
105
- document.body.removeChild(component);
106
- fail('Stylesheet should exist before re-render');
107
- return;
108
- }
109
-
110
- component.requestUpdate();
111
- await component.updateComplete;
112
-
113
- const stylesheetAfter = component.shadowRoot.querySelector('link[href="/kempo.min.css"]');
114
- if(!stylesheetAfter) {
115
- document.body.removeChild(component);
116
- fail('Stylesheet should persist after re-render');
117
- return;
118
- }
119
-
120
- if(stylesheetBefore !== stylesheetAfter) {
121
- document.body.removeChild(component);
122
- fail('Stylesheet should be the same element after re-render');
123
- return;
124
- }
125
-
126
- log('✓ Stylesheet persists through re-renders');
127
- document.body.removeChild(component);
128
- pass('ShadowComponent maintains stylesheet across updates');
129
- }
130
- };
1
+ import ShadowComponent from '/src/components/ShadowComponent.js';
2
+ import { html } from '/src/lit-all.min.js';
3
+
4
+ class TestShadowComponent extends ShadowComponent {
5
+ render() {
6
+ return html`<p>Test shadow content</p>`;
7
+ }
8
+ }
9
+
10
+ customElements.define('test-shadow-component', TestShadowComponent);
11
+
12
+ export default {
13
+ 'should create shadow root with stylesheet': async ({pass, fail, log}) => {
14
+ const component = new TestShadowComponent();
15
+ document.body.appendChild(component);
16
+
17
+ await new Promise(resolve => setTimeout(resolve, 0));
18
+
19
+ if(!component.shadowRoot) {
20
+ document.body.removeChild(component);
21
+ fail('Component should have shadow root');
22
+ return;
23
+ }
24
+
25
+ const stylesheetLink = component.shadowRoot.querySelector('link[href="/kempo.min.css"]');
26
+ if(!stylesheetLink) {
27
+ document.body.removeChild(component);
28
+ fail('Shadow root should contain kempo.min.css link');
29
+ return;
30
+ }
31
+
32
+ if(stylesheetLink.rel !== 'stylesheet') {
33
+ document.body.removeChild(component);
34
+ fail('Link should have rel="stylesheet"');
35
+ return;
36
+ }
37
+
38
+ log('✓ Shadow root created with proper stylesheet');
39
+ document.body.removeChild(component);
40
+ pass('ShadowComponent creates shadow root with stylesheet injection');
41
+ },
42
+
43
+ 'should have render container as render root': async ({pass, fail, log}) => {
44
+ const component = new TestShadowComponent();
45
+ document.body.appendChild(component);
46
+
47
+ await new Promise(resolve => setTimeout(resolve, 0));
48
+
49
+ const renderRoot = component.renderRoot;
50
+ if(!renderRoot) {
51
+ document.body.removeChild(component);
52
+ fail('Component should have render root');
53
+ return;
54
+ }
55
+
56
+ if(renderRoot.tagName !== 'DIV') {
57
+ document.body.removeChild(component);
58
+ fail('Render root should be a div element');
59
+ return;
60
+ }
61
+
62
+ if(renderRoot.parentNode !== component.shadowRoot) {
63
+ document.body.removeChild(component);
64
+ fail('Render root should be child of shadow root');
65
+ return;
66
+ }
67
+
68
+ log('✓ Render root is properly configured div element');
69
+ document.body.removeChild(component);
70
+ pass('ShadowComponent has proper render container setup');
71
+ },
72
+
73
+ 'should render content inside render container': async ({pass, fail, log}) => {
74
+ const component = new TestShadowComponent();
75
+ document.body.appendChild(component);
76
+
77
+ await new Promise(resolve => setTimeout(resolve, 10));
78
+
79
+ const paragraph = component.renderRoot.querySelector('p');
80
+ if(!paragraph) {
81
+ document.body.removeChild(component);
82
+ fail('Component should render paragraph element');
83
+ return;
84
+ }
85
+
86
+ if(paragraph.textContent !== 'Test shadow content') {
87
+ document.body.removeChild(component);
88
+ fail(`Expected "Test shadow content", got "${paragraph.textContent}"`);
89
+ return;
90
+ }
91
+
92
+ log('✓ Content rendered properly inside render container');
93
+ document.body.removeChild(component);
94
+ pass('ShadowComponent renders content correctly');
95
+ },
96
+
97
+ 'should maintain stylesheet after re-rendering': async ({pass, fail, log}) => {
98
+ const component = new TestShadowComponent();
99
+ document.body.appendChild(component);
100
+
101
+ await new Promise(resolve => setTimeout(resolve, 0));
102
+
103
+ const stylesheetBefore = component.shadowRoot.querySelector('link[href="/kempo.min.css"]');
104
+ if(!stylesheetBefore) {
105
+ document.body.removeChild(component);
106
+ fail('Stylesheet should exist before re-render');
107
+ return;
108
+ }
109
+
110
+ component.requestUpdate();
111
+ await component.updateComplete;
112
+
113
+ const stylesheetAfter = component.shadowRoot.querySelector('link[href="/kempo.min.css"]');
114
+ if(!stylesheetAfter) {
115
+ document.body.removeChild(component);
116
+ fail('Stylesheet should persist after re-render');
117
+ return;
118
+ }
119
+
120
+ if(stylesheetBefore !== stylesheetAfter) {
121
+ document.body.removeChild(component);
122
+ fail('Stylesheet should be the same element after re-render');
123
+ return;
124
+ }
125
+
126
+ log('✓ Stylesheet persists through re-renders');
127
+ document.body.removeChild(component);
128
+ pass('ShadowComponent maintains stylesheet across updates');
129
+ }
130
+ };
@@ -1,14 +0,0 @@
1
- {
2
- "customRoutes": {
3
- "/": "./docs/index.html",
4
- "/kempo.min.css": "./node_modules/kempo-css/dist/kempo.min.css",
5
- "/kempo-vars.css": "./src/kempo-vars.css",
6
- "/src/*": "./src/*"
7
- },
8
- "middleware": {
9
- "logging": {
10
- "enabled": true,
11
- "includeResponseTime": true
12
- }
13
- }
14
- }
@@ -1 +0,0 @@
1
- import{LitElement}from"../lit-all.min.js";export default class ShadowComponent extends LitElement{createRenderRoot(){const e=this.attachShadow({mode:"open"}),t=document.createElement("link");t.rel="stylesheet",t.href="/kempo.min.css",e.appendChild(t);const n=document.createElement("div");return e.appendChild(n),n}}
package/src/utils/cli.js DELETED
@@ -1,43 +0,0 @@
1
- import { spawn } from 'child_process';
2
-
3
- export const getArgs = mapping => {
4
- const args = {};
5
- const argv = process.argv.slice(2);
6
-
7
- for(let i = 0; i < argv.length; i++) {
8
- const arg = argv[i];
9
- if(arg.startsWith('-')) {
10
- const key = arg.replace(/^-+/, '');
11
- const mappedKey = mapping[key] || key;
12
- const nextArg = argv[i + 1];
13
-
14
- if(nextArg && !nextArg.startsWith('-')) {
15
- args[mappedKey] = nextArg;
16
- i++;
17
- } else {
18
- args[mappedKey] = true;
19
- }
20
- }
21
- }
22
-
23
- return args;
24
- };
25
-
26
- export const runChildNodeProcess = scriptPath => {
27
- const child = spawn('node', [scriptPath], {
28
- stdio: 'inherit',
29
- shell: true
30
- });
31
-
32
- return new Promise((resolve, reject) => {
33
- child.on('close', code => {
34
- if(code === 0) {
35
- resolve();
36
- } else {
37
- reject(new Error(`Process exited with code ${code}`));
38
- }
39
- });
40
-
41
- child.on('error', reject);
42
- });
43
- };