kempo-ui 0.1.6 → 0.2.2

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 (119) hide show
  1. package/.github/skills/highlight-code/SKILL.md +22 -6
  2. package/.github/skills/new-component/SKILL.md +68 -4
  3. package/AGENTS.md +11 -0
  4. package/bin/highlight_code.js +7 -15
  5. package/dist/components/Aside.js +326 -0
  6. package/dist/components/Dialog.js +1 -1
  7. package/dist/components/Dropdown.js +1 -1
  8. package/dist/components/Main.js +2 -2
  9. package/dist/components/Nav.js +27 -0
  10. package/dist/components/PhotoViewer.js +1 -1
  11. package/dist/components/ShadowComponent.js +1 -1
  12. package/dist/components/ThemeSwitcher.js +1 -0
  13. package/dist/components/Toast.js +1 -1
  14. package/docs/components/accordion.html +4 -3
  15. package/docs/components/aside-items.html +43 -0
  16. package/docs/components/aside-menu.html +43 -0
  17. package/docs/components/aside-push.html +26 -0
  18. package/docs/components/aside.html +567 -0
  19. package/docs/components/card.html +4 -3
  20. package/docs/components/color-picker.html +4 -3
  21. package/docs/components/content-slider.html +4 -3
  22. package/docs/components/dialog.html +4 -3
  23. package/docs/components/dropdown.html +4 -3
  24. package/docs/components/filter-list.html +4 -3
  25. package/docs/components/focus-capture.html +6 -5
  26. package/docs/components/html-editor.html +5 -4
  27. package/docs/components/hybrid-component.html +5 -4
  28. package/docs/components/icon.html +4 -3
  29. package/docs/components/import.html +5 -4
  30. package/docs/components/light-component.html +4 -3
  31. package/docs/components/nav.html +117 -0
  32. package/docs/components/photo-viewer.html +5 -4
  33. package/docs/components/resize.html +5 -4
  34. package/docs/components/shadow-component.html +4 -3
  35. package/docs/components/show-more.html +5 -4
  36. package/docs/components/sortable.html +4 -3
  37. package/docs/components/spinner.html +4 -3
  38. package/docs/components/split.html +5 -4
  39. package/docs/components/table.html +4 -3
  40. package/docs/components/tableControls.html +4 -3
  41. package/docs/components/tableCustomFields.html +4 -3
  42. package/docs/components/tableFetchRecords.html +5 -4
  43. package/docs/components/tableFieldSortHide.html +5 -4
  44. package/docs/components/tablePagination.html +4 -3
  45. package/docs/components/tableRecordEditing.html +4 -3
  46. package/docs/components/tableRecordFiltering.html +5 -4
  47. package/docs/components/tableRecordHiding.html +4 -3
  48. package/docs/components/tableRecordSearching.html +5 -4
  49. package/docs/components/tableRecordSelection.html +4 -3
  50. package/docs/components/tableRowControls.html +4 -3
  51. package/docs/components/tableServerSync.html +5 -4
  52. package/docs/components/tableSorting.html +5 -4
  53. package/docs/components/tabs.html +4 -3
  54. package/docs/components/tags.html +4 -3
  55. package/docs/components/theme-select.html +4 -3
  56. package/docs/components/theme-switcher.html +5 -4
  57. package/docs/components/timestamp.html +4 -3
  58. package/docs/components/toast.html +4 -3
  59. package/docs/components/toggle.html +5 -4
  60. package/docs/components/tree.html +5 -4
  61. package/docs/index.html +22 -21
  62. package/docs/nav-1.inc.html +18 -12
  63. package/docs/nav.inc.html +20 -13
  64. package/docs/nav.inc.js +1 -1
  65. package/docs/src/components/Aside.js +326 -0
  66. package/docs/src/components/Dialog.js +1 -1
  67. package/docs/src/components/Dropdown.js +1 -1
  68. package/docs/src/components/Main.js +2 -2
  69. package/docs/src/components/Nav.js +27 -0
  70. package/docs/src/components/PhotoViewer.js +1 -1
  71. package/docs/src/components/ShadowComponent.js +1 -1
  72. package/docs/src/components/ThemeSwitcher.js +1 -0
  73. package/docs/src/components/Toast.js +1 -1
  74. package/docs/utils/context.html +4 -3
  75. package/docs/utils/cookie.html +4 -3
  76. package/docs/utils/debounce.html +4 -3
  77. package/docs/utils/drag.html +4 -3
  78. package/docs/utils/elevation.html +156 -0
  79. package/docs/utils/formatTimestamp.html +4 -3
  80. package/docs/utils/object.html +4 -3
  81. package/docs/utils/propConverters.html +4 -3
  82. package/docs/utils/string.html +4 -3
  83. package/docs/utils/theme.html +4 -3
  84. package/docs/utils/toTitleCase.html +4 -3
  85. package/docs/utils/type.html +4 -3
  86. package/docs/utils/wait.html +4 -3
  87. package/llm.txt +247 -0
  88. package/package.json +3 -4
  89. package/src/components/Aside.js +726 -0
  90. package/src/components/Dialog.js +1 -1
  91. package/src/components/Dropdown.js +1 -1
  92. package/src/components/Main.js +34 -30
  93. package/src/components/Nav.js +53 -0
  94. package/src/components/PhotoViewer.js +1 -1
  95. package/src/components/ShadowComponent.js +1 -1
  96. package/src/components/ThemeSwitcher.js +1 -0
  97. package/src/components/Toast.js +1 -1
  98. package/tests/bin/get_icon.node-test.js +26 -0
  99. package/tests/bin/highlight_code.node-test.js +108 -0
  100. package/tests/bin/list_icons.node-test.js +26 -0
  101. package/tests/components/Aside.browser-test.js +778 -0
  102. package/tests/components/Main.browser-test.js +115 -283
  103. package/dist/components/SideMenu.js +0 -97
  104. package/dist/components/SidePanel.js +0 -236
  105. package/docs/components/side-menu.html +0 -189
  106. package/docs/components/side-panel-basic.html +0 -44
  107. package/docs/components/side-panel-dual.html +0 -70
  108. package/docs/components/side-panel-menu.html +0 -50
  109. package/docs/components/side-panel-persistent.html +0 -90
  110. package/docs/components/side-panel-scroll.html +0 -176
  111. package/docs/components/side-panel.html +0 -245
  112. package/docs/src/components/SideMenu.js +0 -97
  113. package/docs/src/components/SidePanel.js +0 -236
  114. package/scripts/update-kempo-css.js +0 -53
  115. package/src/components/SideMenu.js +0 -178
  116. package/src/components/SidePanel.js +0 -513
  117. package/tests/components/SideMenu.browser-test.js +0 -667
  118. package/tests/components/SidePanel.browser-test.js +0 -520
  119. package/tools/highlight.js +0 -51
@@ -1,5 +1,5 @@
1
1
  import '../../src/components/Main.js';
2
- import '../../src/components/SidePanel.js';
2
+ import '../../src/components/Aside.js';
3
3
 
4
4
  const createMain = async () => {
5
5
  const main = document.createElement('k-main');
@@ -8,15 +8,6 @@ const createMain = async () => {
8
8
  return main;
9
9
  };
10
10
 
11
- const createPanel = async (options = {}) => {
12
- const panel = document.createElement('k-side-panel');
13
- if(options.collapsed !== undefined) panel.collapsed = options.collapsed;
14
- if(options.side) panel.side = options.side;
15
- document.body.appendChild(panel);
16
- await panel.updateComplete;
17
- return panel;
18
- };
19
-
20
11
  const cleanup = (...elements) => {
21
12
  elements.forEach(el => {
22
13
  if(el && el.parentNode) {
@@ -25,282 +16,194 @@ const cleanup = (...elements) => {
25
16
  });
26
17
  };
27
18
 
19
+ const getCssVar = (el, name) => getComputedStyle(el).getPropertyValue(name).trim();
20
+
28
21
  export default {
29
22
  /*
30
- Main - Properties
23
+ Main - Default State
31
24
  */
32
- 'should have default leftPanelWidth as 0px': async ({pass, fail}) => {
33
- const main = await createMain();
34
- if(main.leftPanelWidth !== '0px') {
35
- cleanup(main);
36
- return fail(`Expected leftPanelWidth to be "0px", got "${main.leftPanelWidth}"`);
37
- }
38
- cleanup(main);
39
- pass('Default leftPanelWidth is 0px');
40
- },
41
-
42
- 'should have default rightPanelWidth as 0px': async ({pass, fail}) => {
25
+ 'should have default left-panel-width as 0px': async ({pass, fail}) => {
43
26
  const main = await createMain();
44
- if(main.rightPanelWidth !== '0px') {
27
+ const val = getCssVar(main, '--left-panel-width');
28
+ if(val !== '0px') {
45
29
  cleanup(main);
46
- return fail(`Expected rightPanelWidth to be "0px", got "${main.rightPanelWidth}"`);
30
+ return fail(`Expected --left-panel-width "0px", got "${val}"`);
47
31
  }
48
32
  cleanup(main);
49
- pass('Default rightPanelWidth is 0px');
33
+ pass('Default --left-panel-width is 0px');
50
34
  },
51
35
 
52
- 'should not reflect state properties to attributes': async ({pass, fail}) => {
36
+ 'should have default right-panel-width as 0px': async ({pass, fail}) => {
53
37
  const main = await createMain();
54
- main.leftPanelWidth = '16rem';
55
- await main.updateComplete;
56
- if(main.hasAttribute('leftPanelWidth')) {
38
+ const val = getCssVar(main, '--right-panel-width');
39
+ if(val !== '0px') {
57
40
  cleanup(main);
58
- return fail('leftPanelWidth should not reflect to attribute (it is a state property)');
41
+ return fail(`Expected --right-panel-width "0px", got "${val}"`);
59
42
  }
60
43
  cleanup(main);
61
- pass('State properties do not reflect to attributes');
44
+ pass('Default --right-panel-width is 0px');
62
45
  },
63
46
 
64
47
  /*
65
48
  Main - Window Event Handling
66
49
  */
67
- 'should listen for side-panel-change event for left panel': async ({pass, fail}) => {
68
- const main = await createMain();
69
- window.dispatchEvent(new CustomEvent('side-panel-change', {
70
- detail: {
71
- collapsed: false,
72
- width: '16rem',
73
- side: 'left'
74
- }
75
- }));
76
- await main.updateComplete;
77
- if(main.leftPanelWidth !== '16rem') {
78
- cleanup(main);
79
- return fail(`Expected leftPanelWidth "16rem", got "${main.leftPanelWidth}"`);
80
- }
81
- cleanup(main);
82
- pass('Listens for side-panel-change event for left panel');
83
- },
84
-
85
- 'should listen for side-panel-change event for right panel': async ({pass, fail}) => {
50
+ 'should respond to aside_state_change event for left aside': async ({pass, fail}) => {
86
51
  const main = await createMain();
87
- window.dispatchEvent(new CustomEvent('side-panel-change', {
88
- detail: {
89
- collapsed: false,
90
- width: '16rem',
91
- side: 'right'
92
- }
52
+ const aside = document.createElement('k-aside');
53
+ aside.side = 'left';
54
+ aside.main = 'push';
55
+ window.dispatchEvent(new CustomEvent('aside_state_change', {
56
+ detail: { aside, state: 'expanded', main: 'push', width: 256 }
93
57
  }));
94
- await main.updateComplete;
95
- if(main.rightPanelWidth !== '16rem') {
58
+ const val = getCssVar(main, '--left-panel-width');
59
+ if(val !== '256px') {
96
60
  cleanup(main);
97
- return fail(`Expected rightPanelWidth "16rem", got "${main.rightPanelWidth}"`);
61
+ return fail(`Expected --left-panel-width "256px", got "${val}"`);
98
62
  }
99
63
  cleanup(main);
100
- pass('Listens for side-panel-change event for right panel');
64
+ pass('Responds to aside_state_change for left aside');
101
65
  },
102
66
 
103
- 'should update leftPanelWidth from event detail': async ({pass, fail}) => {
67
+ 'should respond to aside_state_change event for right aside': async ({pass, fail}) => {
104
68
  const main = await createMain();
105
- window.dispatchEvent(new CustomEvent('side-panel-change', {
106
- detail: {
107
- collapsed: true,
108
- width: '3.5rem',
109
- side: 'left'
110
- }
69
+ const aside = document.createElement('k-aside');
70
+ aside.side = 'right';
71
+ aside.main = 'push';
72
+ window.dispatchEvent(new CustomEvent('aside_state_change', {
73
+ detail: { aside, state: 'expanded', main: 'push', width: 256 }
111
74
  }));
112
- await main.updateComplete;
113
- if(main.leftPanelWidth !== '3.5rem') {
75
+ const val = getCssVar(main, '--right-panel-width');
76
+ if(val !== '256px') {
114
77
  cleanup(main);
115
- return fail(`Expected leftPanelWidth "3.5rem", got "${main.leftPanelWidth}"`);
78
+ return fail(`Expected --right-panel-width "256px", got "${val}"`);
116
79
  }
117
80
  cleanup(main);
118
- pass('Updates leftPanelWidth from event');
81
+ pass('Responds to aside_state_change for right aside');
119
82
  },
120
83
 
121
- 'should update rightPanelWidth from event detail': async ({pass, fail}) => {
84
+ 'should handle multiple events for same side': async ({pass, fail}) => {
122
85
  const main = await createMain();
123
- window.dispatchEvent(new CustomEvent('side-panel-change', {
124
- detail: {
125
- collapsed: false,
126
- width: '16rem',
127
- side: 'right'
128
- }
86
+ const aside = document.createElement('k-aside');
87
+ aside.side = 'left';
88
+ aside.main = 'push';
89
+ window.dispatchEvent(new CustomEvent('aside_state_change', {
90
+ detail: { aside, state: 'expanded', main: 'push', width: 256 }
129
91
  }));
130
- await main.updateComplete;
131
- if(main.rightPanelWidth !== '16rem') {
132
- cleanup(main);
133
- return fail(`Expected rightPanelWidth "16rem", got "${main.rightPanelWidth}"`);
134
- }
135
- cleanup(main);
136
- pass('Updates rightPanelWidth from event');
137
- },
138
-
139
- 'should handle multiple panel change events for same side': async ({pass, fail}) => {
140
- const main = await createMain();
141
- window.dispatchEvent(new CustomEvent('side-panel-change', {
142
- detail: { collapsed: false, width: '16rem', side: 'left' }
143
- }));
144
- await main.updateComplete;
145
- if(main.leftPanelWidth !== '16rem') {
92
+ if(getCssVar(main, '--left-panel-width') !== '256px') {
146
93
  cleanup(main);
147
94
  return fail('Should update on first event');
148
95
  }
149
- window.dispatchEvent(new CustomEvent('side-panel-change', {
150
- detail: { collapsed: true, width: '3.5rem', side: 'left' }
96
+ window.dispatchEvent(new CustomEvent('aside_state_change', {
97
+ detail: { aside, state: 'collapsed', main: 'push', width: 56 }
151
98
  }));
152
- await main.updateComplete;
153
- if(main.leftPanelWidth !== '3.5rem') {
99
+ if(getCssVar(main, '--left-panel-width') !== '56px') {
154
100
  cleanup(main);
155
101
  return fail('Should update on second event');
156
102
  }
157
103
  cleanup(main);
158
- pass('Handles multiple panel change events for same side');
104
+ pass('Handles multiple events for same side');
159
105
  },
160
106
 
161
- 'should handle events for both left and right panels independently': async ({pass, fail}) => {
107
+ 'should handle events for both sides independently': async ({pass, fail}) => {
162
108
  const main = await createMain();
163
- window.dispatchEvent(new CustomEvent('side-panel-change', {
164
- detail: { collapsed: false, width: '16rem', side: 'left' }
109
+ const asideL = document.createElement('k-aside');
110
+ asideL.side = 'left';
111
+ asideL.main = 'push';
112
+ const asideR = document.createElement('k-aside');
113
+ asideR.side = 'right';
114
+ asideR.main = 'push';
115
+ window.dispatchEvent(new CustomEvent('aside_state_change', {
116
+ detail: { aside: asideL, state: 'expanded', main: 'push', width: 256 }
165
117
  }));
166
- await main.updateComplete;
167
- window.dispatchEvent(new CustomEvent('side-panel-change', {
168
- detail: { collapsed: true, width: '3.5rem', side: 'right' }
118
+ window.dispatchEvent(new CustomEvent('aside_state_change', {
119
+ detail: { aside: asideR, state: 'expanded', main: 'push', width: 56 }
169
120
  }));
170
- await main.updateComplete;
171
- if(main.leftPanelWidth !== '16rem' || main.rightPanelWidth !== '3.5rem') {
121
+ const l = getCssVar(main, '--left-panel-width');
122
+ const r = getCssVar(main, '--right-panel-width');
123
+ if(l !== '256px' || r !== '56px') {
172
124
  cleanup(main);
173
- return fail(`Expected leftPanelWidth "16rem" and rightPanelWidth "3.5rem", got "${main.leftPanelWidth}" and "${main.rightPanelWidth}"`);
125
+ return fail(`Expected left "256px" and right "56px", got "${l}" and "${r}"`);
174
126
  }
175
127
  cleanup(main);
176
- pass('Handles events for both panels independently');
128
+ pass('Handles events for both sides independently');
177
129
  },
178
130
 
179
- /*
180
- Main - Existing Panel Detection
181
- */
182
- 'should detect existing collapsed left panel on connection': async ({pass, fail}) => {
183
- const panel = await createPanel({ collapsed: true, side: 'left' });
131
+ 'should take max width from multiple sources on same side': async ({pass, fail}) => {
184
132
  const main = await createMain();
185
- if(main.leftPanelWidth !== '3.5rem') {
186
- cleanup(main, panel);
187
- return fail(`Expected leftPanelWidth "3.5rem", got "${main.leftPanelWidth}"`);
188
- }
189
- cleanup(main, panel);
190
- pass('Detects existing collapsed left panel');
191
- },
192
-
193
- 'should detect existing expanded left panel on connection': async ({pass, fail}) => {
194
- const panel = await createPanel({ collapsed: false, side: 'left' });
195
- const main = await createMain();
196
- if(main.leftPanelWidth !== '16rem') {
197
- cleanup(main, panel);
198
- return fail(`Expected leftPanelWidth "16rem", got "${main.leftPanelWidth}"`);
199
- }
200
- cleanup(main, panel);
201
- pass('Detects existing expanded left panel');
202
- },
203
-
204
- 'should detect existing right panel on connection': async ({pass, fail}) => {
205
- const panel = await createPanel({ collapsed: false, side: 'right' });
206
- const main = await createMain();
207
- if(main.rightPanelWidth !== '16rem') {
208
- cleanup(main, panel);
209
- return fail(`Expected rightPanelWidth "16rem", got "${main.rightPanelWidth}"`);
210
- }
211
- cleanup(main, panel);
212
- pass('Detects existing right panel');
213
- },
214
-
215
- 'should detect both left and right panels on connection': async ({pass, fail}) => {
216
- const leftPanel = await createPanel({ collapsed: false, side: 'left' });
217
- const rightPanel = await createPanel({ collapsed: true, side: 'right' });
218
- const main = await createMain();
219
- if(main.leftPanelWidth !== '16rem' || main.rightPanelWidth !== '3.5rem') {
220
- cleanup(main, leftPanel, rightPanel);
221
- return fail(`Expected leftPanelWidth "16rem" and rightPanelWidth "3.5rem", got "${main.leftPanelWidth}" and "${main.rightPanelWidth}"`);
222
- }
223
- cleanup(main, leftPanel, rightPanel);
224
- pass('Detects both left and right panels');
225
- },
226
-
227
- 'should not error when no panel exists': async ({pass, fail}) => {
228
- const main = await createMain();
229
- if(main.leftPanelWidth !== '0px' || main.rightPanelWidth !== '0px') {
230
- cleanup(main);
231
- return fail('Should have default values when no panel exists');
232
- }
233
- cleanup(main);
234
- pass('Does not error when no panel exists');
235
- },
236
-
237
- /*
238
- Main - CSS Variable Updates
239
- */
240
- 'should set --left-panel-width CSS variable': async ({pass, fail}) => {
241
- const main = await createMain();
242
- main.leftPanelWidth = '16rem';
243
- await main.updateComplete;
244
- const computedStyle = getComputedStyle(main);
245
- const panelWidth = computedStyle.getPropertyValue('--left-panel-width').trim();
246
- if(panelWidth !== '16rem') {
133
+ const aside1 = document.createElement('k-aside');
134
+ aside1.side = 'left';
135
+ aside1.main = 'push';
136
+ const aside2 = document.createElement('k-aside');
137
+ aside2.side = 'left';
138
+ aside2.main = 'push';
139
+ window.dispatchEvent(new CustomEvent('aside_state_change', {
140
+ detail: { aside: aside1, state: 'expanded', main: 'push', width: 100 }
141
+ }));
142
+ window.dispatchEvent(new CustomEvent('aside_state_change', {
143
+ detail: { aside: aside2, state: 'expanded', main: 'push', width: 320 }
144
+ }));
145
+ const val = getCssVar(main, '--left-panel-width');
146
+ if(val !== '320px') {
247
147
  cleanup(main);
248
- return fail(`Expected --left-panel-width "16rem", got "${panelWidth}"`);
148
+ return fail(`Expected max width "320px", got "${val}"`);
249
149
  }
250
150
  cleanup(main);
251
- pass('Sets --left-panel-width CSS variable');
151
+ pass('Takes max width from multiple sources on same side');
252
152
  },
253
153
 
254
- 'should set --right-panel-width CSS variable': async ({pass, fail}) => {
154
+ 'should remove source when aside goes offscreen': async ({pass, fail}) => {
255
155
  const main = await createMain();
256
- main.rightPanelWidth = '16rem';
257
- await main.updateComplete;
258
- const computedStyle = getComputedStyle(main);
259
- const panelWidth = computedStyle.getPropertyValue('--right-panel-width').trim();
260
- if(panelWidth !== '16rem') {
156
+ const aside1 = document.createElement('k-aside');
157
+ aside1.side = 'left';
158
+ aside1.main = 'push';
159
+ const aside2 = document.createElement('k-aside');
160
+ aside2.side = 'left';
161
+ aside2.main = 'push';
162
+ window.dispatchEvent(new CustomEvent('aside_state_change', {
163
+ detail: { aside: aside1, state: 'expanded', main: 'push', width: 100 }
164
+ }));
165
+ window.dispatchEvent(new CustomEvent('aside_state_change', {
166
+ detail: { aside: aside2, state: 'expanded', main: 'push', width: 320 }
167
+ }));
168
+ window.dispatchEvent(new CustomEvent('aside_state_change', {
169
+ detail: { aside: aside2, state: 'offscreen', main: 'push' }
170
+ }));
171
+ const val = getCssVar(main, '--left-panel-width');
172
+ if(val !== '100px') {
261
173
  cleanup(main);
262
- return fail(`Expected --right-panel-width "16rem", got "${panelWidth}"`);
174
+ return fail(`Expected "100px" after removing larger source, got "${val}"`);
263
175
  }
264
176
  cleanup(main);
265
- pass('Sets --right-panel-width CSS variable');
177
+ pass('Removes source when aside goes offscreen');
266
178
  },
267
179
 
268
- 'should update --left-panel-width when leftPanelWidth changes': async ({pass, fail}) => {
180
+ 'should ignore overlay asides': async ({pass, fail}) => {
269
181
  const main = await createMain();
270
- main.leftPanelWidth = '16rem';
271
- await main.updateComplete;
272
- let computedStyle = getComputedStyle(main);
273
- let panelWidth = computedStyle.getPropertyValue('--left-panel-width').trim();
274
- if(panelWidth !== '16rem') {
275
- cleanup(main);
276
- return fail('Should set initial --left-panel-width');
277
- }
278
- main.leftPanelWidth = '3.5rem';
279
- await main.updateComplete;
280
- computedStyle = getComputedStyle(main);
281
- panelWidth = computedStyle.getPropertyValue('--left-panel-width').trim();
282
- if(panelWidth !== '3.5rem') {
182
+ const aside = document.createElement('k-aside');
183
+ aside.side = 'left';
184
+ aside.main = 'overlay';
185
+ window.dispatchEvent(new CustomEvent('aside_state_change', {
186
+ detail: { aside, state: 'expanded', main: 'overlay', width: 256 }
187
+ }));
188
+ const val = getCssVar(main, '--left-panel-width');
189
+ if(val !== '0px') {
283
190
  cleanup(main);
284
- return fail(`Expected updated --left-panel-width "3.5rem", got "${panelWidth}"`);
191
+ return fail(`Expected "0px" for overlay aside, got "${val}"`);
285
192
  }
286
193
  cleanup(main);
287
- pass('Updates --left-panel-width when leftPanelWidth changes');
194
+ pass('Ignores overlay asides');
288
195
  },
289
196
 
290
- 'should maintain both panel widths independently': async ({pass, fail}) => {
197
+ 'should not error when no aside exists': async ({pass, fail}) => {
291
198
  const main = await createMain();
292
- main.leftPanelWidth = '16rem';
293
- main.rightPanelWidth = '3.5rem';
294
- await main.updateComplete;
295
- const computedStyle = getComputedStyle(main);
296
- const leftWidth = computedStyle.getPropertyValue('--left-panel-width').trim();
297
- const rightWidth = computedStyle.getPropertyValue('--right-panel-width').trim();
298
- if(leftWidth !== '16rem' || rightWidth !== '3.5rem') {
199
+ const l = getCssVar(main, '--left-panel-width');
200
+ const r = getCssVar(main, '--right-panel-width');
201
+ if(l !== '0px' || r !== '0px') {
299
202
  cleanup(main);
300
- return fail(`Expected left "16rem" and right "3.5rem", got "${leftWidth}" and "${rightWidth}"`);
203
+ return fail('Should have default values when no aside exists');
301
204
  }
302
205
  cleanup(main);
303
- pass('Maintains both panel widths independently');
206
+ pass('Does not error when no aside exists');
304
207
  },
305
208
 
306
209
  /*
@@ -331,76 +234,5 @@ export default {
331
234
  }
332
235
  cleanup(main);
333
236
  pass('Renders default slot');
334
- },
335
-
336
- /*
337
- Main - Integration with SidePanel
338
- */
339
- 'should update when left panel toggles': async ({pass, fail}) => {
340
- const panel = await createPanel({ collapsed: false, side: 'left' });
341
- const main = await createMain();
342
- if(main.leftPanelWidth !== '16rem') {
343
- cleanup(main, panel);
344
- return fail('Should detect initial expanded state');
345
- }
346
- panel.collapse();
347
- await panel.updateComplete;
348
- await main.updateComplete;
349
- if(main.leftPanelWidth !== '3.5rem') {
350
- cleanup(main, panel);
351
- return fail(`Expected leftPanelWidth "3.5rem" after collapse, got "${main.leftPanelWidth}"`);
352
- }
353
- cleanup(main, panel);
354
- pass('Updates when left panel toggles');
355
- },
356
-
357
- 'should update when right panel toggles': async ({pass, fail}) => {
358
- const panel = await createPanel({ collapsed: false, side: 'right' });
359
- const main = await createMain();
360
- if(main.rightPanelWidth !== '16rem') {
361
- cleanup(main, panel);
362
- return fail('Should detect initial expanded state');
363
- }
364
- panel.collapse();
365
- await panel.updateComplete;
366
- await main.updateComplete;
367
- if(main.rightPanelWidth !== '3.5rem') {
368
- cleanup(main, panel);
369
- return fail(`Expected rightPanelWidth "3.5rem" after collapse, got "${main.rightPanelWidth}"`);
370
- }
371
- cleanup(main, panel);
372
- pass('Updates when right panel toggles');
373
- },
374
-
375
- 'should handle dual panels toggling independently': async ({pass, fail}) => {
376
- const leftPanel = await createPanel({ collapsed: false, side: 'left' });
377
- const rightPanel = await createPanel({ collapsed: false, side: 'right' });
378
- const main = await createMain();
379
-
380
- if(main.leftPanelWidth !== '16rem' || main.rightPanelWidth !== '16rem') {
381
- cleanup(main, leftPanel, rightPanel);
382
- return fail('Should detect both expanded panels');
383
- }
384
-
385
- leftPanel.collapse();
386
- await leftPanel.updateComplete;
387
- await main.updateComplete;
388
-
389
- if(main.leftPanelWidth !== '3.5rem' || main.rightPanelWidth !== '16rem') {
390
- cleanup(main, leftPanel, rightPanel);
391
- return fail('Left panel should collapse while right stays expanded');
392
- }
393
-
394
- rightPanel.collapse();
395
- await rightPanel.updateComplete;
396
- await main.updateComplete;
397
-
398
- if(main.leftPanelWidth !== '3.5rem' || main.rightPanelWidth !== '3.5rem') {
399
- cleanup(main, leftPanel, rightPanel);
400
- return fail('Both panels should be collapsed');
401
- }
402
-
403
- cleanup(main, leftPanel, rightPanel);
404
- pass('Handles dual panels toggling independently');
405
237
  }
406
238
  };
@@ -1,97 +0,0 @@
1
- import ShadowComponent from"./ShadowComponent.js";import{html,css}from"../lit-all.min.js";import{boolTrueFalse}from"../utils/propConverters.js";import"./FocusCapture.js";import"./Icon.js";export default class SideMenu extends ShadowComponent{static properties={opened:{type:Boolean,reflect:!0},overlayClose:{type:Boolean,reflect:!0,attribute:"overlay-close",converter:boolTrueFalse},escClose:{type:Boolean,reflect:!0,attribute:"esc-close",converter:boolTrueFalse},side:{type:String,reflect:!0}};constructor(){super(),this.opened=!1,this.overlayClose=!0,this.escClose=!0,this.side="left"}overlayClick=()=>{this.overlayClose&&this.close()};handleKeyDown=e=>{this.escClose&&"Escape"===e.key&&this.close()};updated(e){super.updated(e),e.has("opened")&&(this.opened?(document.body.classList.add("no-scroll"),document.addEventListener("keydown",this.handleKeyDown),this.dispatchEvent(new CustomEvent("change",{detail:"open"})),this.dispatchEvent(new CustomEvent("open"))):(document.body.classList.remove("no-scroll"),document.removeEventListener("keydown",this.handleKeyDown),this.dispatchEvent(new CustomEvent("change",{detail:"close"})),this.dispatchEvent(new CustomEvent("close"))))}open(){this.opened=!0}close(){this.opened=!1}toggle(){this.opened?this.close():this.open(),this.dispatchEvent(new CustomEvent("toggle"))}render(){return html`
2
- <k-focus-capture>
3
- <div id="container">
4
- <button id="overlay" @click=${this.overlayClick}>
5
- <div id="overlay-x"><k-icon name="close"></k-icon></div>
6
- </button>
7
- <div id="menu">
8
- <slot></slot>
9
- </div>
10
- </div>
11
- </k-focus-capture>
12
- `}static styles=css`
13
- :host {
14
- --bg: var(--c_bg);
15
- --width: 20rem;
16
-
17
- position: fixed;
18
- top: 0;
19
- left: 0;
20
- width: 100vw;
21
- max-width: 100%;
22
- height: 100vh;
23
- z-index: 100;
24
- pointer-events: none;
25
- }
26
- :host([opened]) {
27
- pointer-events: auto;
28
- }
29
- k-focus-capture {
30
- width: 100%;
31
- height: 100%;
32
- }
33
- #container {
34
- position: relative;
35
- width: 100%;
36
- height: 100%;
37
- opacity: 0;
38
- transition: opacity var(--animation_ms, 256ms);
39
- }
40
- :host([opened]) #container {
41
- opacity: 1;
42
- }
43
- #overlay {
44
- position: absolute;
45
- width: 100%;
46
- height: 100%;
47
- left: 0;
48
- top: 0;
49
- background: var(--overlay, rgba(0, 0, 0, 0.5));
50
- border: none;
51
- padding: 0;
52
- cursor: pointer;
53
- z-index: 1;
54
- }
55
- #overlay-x {
56
- position: absolute;
57
- top: var(--spacer_h);
58
- right: var(--spacer_h);
59
- font-size: 1.75rem;
60
- cursor: pointer;
61
- color: var(--tc_light);
62
- }
63
- :host([overlay-close="false"]) #overlay-x {
64
- display: none;
65
- }
66
- :host([overlay-close="false"]) #overlay {
67
- cursor: default;
68
- }
69
- #menu {
70
- position: absolute;
71
- width: var(--width);
72
- max-width: calc(100vw - 6rem);
73
- height: 100vh;
74
- overflow-y: auto;
75
- left: calc(var(--width) * -1);
76
- top: 0;
77
- background: var(--bg);
78
- transition: left var(--animation_ms, 256ms);
79
- padding: var(--menu_padding, var(--spacer));
80
- z-index: 2;
81
- }
82
- :host([opened]) #menu {
83
- left: 0;
84
- }
85
- :host([side="right"]) #menu {
86
- left: auto;
87
- transition: right var(--animation_ms, 256ms);
88
- right: calc(var(--width) * -1);
89
- }
90
- :host([opened][side="right"]) #menu {
91
- right: 0;
92
- }
93
- :host([side="right"]) #overlay-x {
94
- right: auto;
95
- left: var(--spacer_h);
96
- }
97
- `}window.customElements.define("k-side-menu",SideMenu);