kempo 2.15.2 → 3.1.0

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 (66) hide show
  1. package/dist/components/Import.js +1 -1
  2. package/dist/components/PhotoViewer.js +1 -0
  3. package/dist/kempo-vars.css +1 -1
  4. package/docs/components/_template.html +3 -1
  5. package/docs/components/accordion.html +3 -1
  6. package/docs/components/card.html +3 -1
  7. package/docs/components/component.html +3 -1
  8. package/docs/components/content-slider.html +3 -1
  9. package/docs/components/dialog.html +3 -1
  10. package/docs/components/directory-viewer.html +3 -1
  11. package/docs/components/focus-capture.html +3 -1
  12. package/docs/components/import.html +3 -1
  13. package/docs/components/lazy-component.html +3 -1
  14. package/docs/components/reactive-component.html +3 -1
  15. package/docs/components/reactive-lazy-component.html +3 -1
  16. package/docs/components/resize.html +3 -1
  17. package/docs/components/search.html +3 -1
  18. package/docs/components/show-more.html +3 -1
  19. package/docs/components/side-menu.html +3 -1
  20. package/docs/components/sortable.html +3 -1
  21. package/docs/components/split.html +3 -1
  22. package/docs/components/table.html +3 -1
  23. package/docs/components/tableControls.html +3 -1
  24. package/docs/components/tableCustomFields.html +3 -1
  25. package/docs/components/tableFetchRecords.html +3 -1
  26. package/docs/components/tableFieldSortHide.html +3 -1
  27. package/docs/components/tablePagination.html +3 -1
  28. package/docs/components/tableRecordEditing.html +3 -1
  29. package/docs/components/tableRecordFiltering.html +3 -1
  30. package/docs/components/tableRecordHiding.html +3 -1
  31. package/docs/components/tableRecordSearching.html +3 -1
  32. package/docs/components/tableRecordSelection.html +3 -1
  33. package/docs/components/tableRowControls.html +3 -1
  34. package/docs/components/tableSorting.html +3 -1
  35. package/docs/components/tabs.html +3 -1
  36. package/docs/components/tags.html +3 -1
  37. package/docs/components/theme-switcher.html +3 -1
  38. package/docs/components/timestamp.html +3 -1
  39. package/docs/components/toggle.html +3 -1
  40. package/docs/js/nav.inc.js +4 -0
  41. package/docs/kempo/components/Import.js +1 -1
  42. package/docs/kempo/components/PhotoViewer.js +1 -0
  43. package/docs/kempo/kempo-vars.css +1 -1
  44. package/docs/nav.inc.html +1 -6
  45. package/docs/styles/_template.html +3 -1
  46. package/docs/styles/borders-spacing.html +3 -1
  47. package/docs/styles/buttons.html +3 -1
  48. package/docs/styles/colors.html +3 -1
  49. package/docs/styles/displays-layouts.html +3 -1
  50. package/docs/styles/embed-1.html +2 -0
  51. package/docs/styles/inputs.html +3 -1
  52. package/docs/styles/tables.html +3 -1
  53. package/docs/styles/typography.html +3 -1
  54. package/docs/utils/_template.html +3 -1
  55. package/docs/utils/cli.html +3 -1
  56. package/docs/utils/cookie.html +3 -1
  57. package/docs/utils/debounce.html +3 -1
  58. package/docs/utils/drag.html +3 -1
  59. package/docs/utils/element.html +3 -1
  60. package/docs/utils/format-timestamp.html +3 -1
  61. package/docs/utils/fuzzy-match.html +1 -1
  62. package/package.json +1 -1
  63. package/src/components/Import.js +19 -24
  64. package/src/components/PhotoViewer.js +358 -0
  65. package/src/kempo-vars.css +42 -42
  66. package/docs/nav-1.inc.html +0 -84
@@ -0,0 +1,358 @@
1
+ import Component from './Component.js';
2
+ import './Icon.js';
3
+ import {
4
+ onEvent,
5
+ offEvent,
6
+ dispatchEvent
7
+ } from '../utils/element.js';
8
+
9
+ const openHandler = Symbol(),
10
+ closeHandler = Symbol(),
11
+ overlayHandler = Symbol(),
12
+ prevHandler = Symbol(),
13
+ nextHandler = Symbol(),
14
+ keyboardHandler = Symbol(),
15
+ imgKeyboardHandler = Symbol();
16
+ export default class PhotoViewer extends Component {
17
+ constructor(src = '', alt = '', options = {}){
18
+ super();
19
+ const {
20
+ keyboardControls = true,
21
+ global = false
22
+ } = options;
23
+
24
+ this.registerAttributes({
25
+ src,
26
+ alt,
27
+ fullscreen: false,
28
+ keyboardControls,
29
+ global
30
+ });
31
+ }
32
+ /* Lifecycle Callbacks */
33
+ attributeChangedCallback(n, oV, nV){
34
+ super.attributeChangedCallback(n, oV, nV);
35
+ if(this.rendered && n === 'src' && oV !== nV){
36
+ this.shadowRoot.getElementById('img').src = nV;
37
+ this.shadowRoot.getElementById('fullscreen-img').src = nV;
38
+ } else if(this.rendered && n === 'alt' && oV !== nV){
39
+ this.shadowRoot.getElementById('img').alt = nV;
40
+ this.shadowRoot.getElementById('fullscreen-img').alt = nV;
41
+ } else if(this.rendered && n === 'fullscreen' && oV !== nV){
42
+ dispatchEvent(this, `fullscreenchange ${nV?' fullscreen':' fullscreenclose'}`);
43
+ this.updateNavigationState();
44
+ if(this.keyboardControls) {
45
+ if(nV) {
46
+ document.addEventListener('keydown', this[keyboardHandler]);
47
+ } else {
48
+ document.removeEventListener('keydown', this[keyboardHandler]);
49
+ }
50
+ }
51
+ }
52
+ }
53
+ async render(force){
54
+ if(await super.render(force)){
55
+ const $img = this.shadowRoot.getElementById('img')
56
+ $img.src = this.src;
57
+ $img.alt = this.alt;
58
+ const $fullImg = this.shadowRoot.getElementById('fullscreen-img')
59
+ $fullImg.src = this.src;
60
+ $fullImg.alt = this.alt;
61
+
62
+ // Handle fullscreen caption
63
+ const fullscreenSlot = this.shadowRoot.querySelector('slot[name="fullscreen-caption"]');
64
+ if (fullscreenSlot && !fullscreenSlot.assignedNodes().length) {
65
+ const defaultSlot = this.shadowRoot.querySelector('slot:not([name])');
66
+ const contents = defaultSlot.assignedNodes();
67
+ contents.forEach(node => {
68
+ const clone = node.cloneNode(true);
69
+ this.appendChild(clone).slot = 'fullscreen-caption';
70
+ });
71
+ }
72
+
73
+ onEvent($img, 'click', this[openHandler]);
74
+ onEvent($img, 'keydown', this[imgKeyboardHandler]);
75
+ onEvent(this.shadowRoot.getElementById('close'), 'click', this[closeHandler]);
76
+ onEvent(this.shadowRoot.getElementById('fullscreen-overlay'), 'click', this[overlayHandler]);
77
+ onEvent(this.shadowRoot.getElementById('prev'), 'click', this[prevHandler]);
78
+ onEvent(this.shadowRoot.getElementById('next'), 'click', this[nextHandler]);
79
+ this.updateNavigationState();
80
+ return true;
81
+ }
82
+ return false;
83
+ }
84
+ disconnectedCallback(){
85
+ super.disconnectedCallback();
86
+ offEvent(this.shadowRoot.getElementById('img'), 'click', this[openHandler]);
87
+ offEvent(this.shadowRoot.getElementById('img'), 'keydown', this[imgKeyboardHandler]);
88
+ offEvent(this.shadowRoot.getElementById('close'), 'click', this[closeHandler]);
89
+ offEvent(this.shadowRoot.getElementById('fullscreen-overlay'), 'click', this[overlayHandler]);
90
+ offEvent(this.shadowRoot.getElementById('prev'), 'click', this[prevHandler]);
91
+ offEvent(this.shadowRoot.getElementById('next'), 'click', this[nextHandler]);
92
+ if(this.keyboardControls) {
93
+ document.removeEventListener('keydown', this[keyboardHandler]);
94
+ }
95
+ }
96
+
97
+ /* Private Methods */
98
+ [imgKeyboardHandler] = (e) => {
99
+ if(e.key === 'Enter' && !this.fullscreen) {
100
+ this.open();
101
+ }
102
+ }
103
+ [openHandler] = () => {
104
+ this.open();
105
+ }
106
+ [closeHandler] = () => {
107
+ this.close();
108
+ }
109
+ [overlayHandler] = (e) => {
110
+ if (e.target === e.currentTarget) {
111
+ this.close();
112
+ }
113
+ }
114
+ [prevHandler] = (e) => {
115
+ e.stopPropagation();
116
+ const prev = this.getPrevSibling();
117
+ if(prev) {
118
+ this.close();
119
+ prev.open();
120
+ }
121
+ }
122
+ [nextHandler] = (e) => {
123
+ e.stopPropagation();
124
+ const next = this.getNextSibling();
125
+ if(next) {
126
+ this.close();
127
+ next.open();
128
+ }
129
+ }
130
+ [keyboardHandler] = (e) => {
131
+ if(e.key === 'Escape') {
132
+ this.close();
133
+ } else if(e.key === 'ArrowLeft') {
134
+ const prev = this.getPrevSibling();
135
+ if(prev) {
136
+ this.close();
137
+ prev.open();
138
+ }
139
+ } else if(e.key === 'ArrowRight') {
140
+ const next = this.getNextSibling();
141
+ if(next) {
142
+ this.close();
143
+ next.open();
144
+ }
145
+ }
146
+ }
147
+ getPrevSibling() {
148
+ if (this.global) {
149
+ // Find any PhotoViewer in document
150
+ const viewers = Array.from(document.getElementsByTagName('k-photo-viewer'));
151
+ const index = viewers.indexOf(this);
152
+ if (index === -1) return null;
153
+ return viewers[index === 0 ? viewers.length - 1 : index - 1];
154
+ } else {
155
+ // Only look at direct siblings
156
+ let prev = this.previousElementSibling;
157
+ while (prev && prev.tagName !== 'K-PHOTO-VIEWER') {
158
+ prev = prev.previousElementSibling;
159
+ }
160
+ if (!prev && this.hasPhotoSiblings()) {
161
+ prev = this.parentElement.lastElementChild;
162
+ while (prev && prev.tagName !== 'K-PHOTO-VIEWER') {
163
+ prev = prev.previousElementSibling;
164
+ }
165
+ }
166
+ return prev;
167
+ }
168
+ }
169
+
170
+ getNextSibling() {
171
+ if (this.global) {
172
+ // Find any PhotoViewer in document
173
+ const viewers = Array.from(document.getElementsByTagName('k-photo-viewer'));
174
+ const index = viewers.indexOf(this);
175
+ if (index === -1) return null;
176
+ return viewers[index === viewers.length - 1 ? 0 : index + 1];
177
+ } else {
178
+ // Only look at direct siblings
179
+ let next = this.nextElementSibling;
180
+ while (next && next.tagName !== 'K-PHOTO-VIEWER') {
181
+ next = next.nextElementSibling;
182
+ }
183
+ if (!next && this.hasPhotoSiblings()) {
184
+ next = this.parentElement.firstElementChild;
185
+ while (next && next.tagName !== 'K-PHOTO-VIEWER') {
186
+ next = next.nextElementSibling;
187
+ }
188
+ }
189
+ return next;
190
+ }
191
+ }
192
+
193
+ hasPhotoSiblings() {
194
+ if (this.global) {
195
+ return document.getElementsByTagName('k-photo-viewer').length > 1;
196
+ }
197
+ return Array.from(this.parentElement.children)
198
+ .filter(el => el !== this && el.tagName === 'K-PHOTO-VIEWER')
199
+ .length > 0;
200
+ }
201
+
202
+ updateNavigationState() {
203
+ const hasNavigation = this.fullscreen && this.hasPhotoSiblings();
204
+ const nav = this.shadowRoot.querySelectorAll('.nav-btn');
205
+ nav.forEach(btn => btn.classList.toggle('d-n', !hasNavigation));
206
+ }
207
+
208
+ /* Public Methods */
209
+ open(){
210
+ this.fullscreen = true;
211
+ }
212
+ close(){
213
+ this.fullscreen = false;
214
+ }
215
+ toggle(){
216
+ this.fullscreen = !this.fullscreen;
217
+ }
218
+
219
+ /* Shadow DOM */
220
+ get shadowTemplate(){
221
+ return /*html*/`
222
+ <div id="wrapper">
223
+ <img id="img" tabindex="0" />
224
+ <div class="caption">
225
+ <slot></slot>
226
+ </div>
227
+ <div id="fullscreen-overlay">
228
+ <button id="close" class="no-btn">
229
+ <slot name="close">
230
+ <k-icon name="close"></k-icon>
231
+ </slot>
232
+ </button>
233
+ <button id="prev" class="nav-btn no-btn">
234
+ <slot name="prev">
235
+ <k-icon name="chevron-left"></k-icon>
236
+ </slot>
237
+ </button>
238
+ <button id="next" class="nav-btn no-btn">
239
+ <slot name="next">
240
+ <k-icon name="chevron-right"></k-icon>
241
+ </slot>
242
+ </button>
243
+ <div class="content">
244
+ <img id="fullscreen-img" />
245
+ <div class="caption">
246
+ <slot name="fullscreen-caption"></slot>
247
+ </div>
248
+ </div>
249
+ </div>
250
+ </div>
251
+ `;
252
+ }
253
+ get shadowStyles(){
254
+ return /*css*/`
255
+ ${super.shadowStyles}
256
+ :host {
257
+ display: block;
258
+ }
259
+ #wrapper {
260
+ position: relative;
261
+ width: 100%;
262
+ height: 100%;
263
+ }
264
+ #img {
265
+ max-width: 100%;
266
+ height: auto;
267
+ cursor: pointer;
268
+ outline: none;
269
+ border-radius: var(--img_radius, 0);
270
+ }
271
+ #img:focus {
272
+ box-shadow: var(--focus_shadow);
273
+ }
274
+ #fullscreen-overlay {
275
+ position: fixed;
276
+ top: 0;
277
+ left: 0;
278
+ right: 0;
279
+ bottom: 0;
280
+ z-index: 9999;
281
+ background: rgba(0,0,0,0.9);
282
+ padding: 2rem;
283
+ display: none;
284
+ }
285
+ :host([fullscreen]) #fullscreen-overlay {
286
+ display: flex;
287
+ align-items: center;
288
+ justify-content: center;
289
+ }
290
+ .content {
291
+ position: relative;
292
+ max-width: 100%;
293
+ max-height: 90vh;
294
+ }
295
+ #fullscreen-img {
296
+ max-height: 75vh;
297
+ max-width: 100%;
298
+ object-fit: contain;
299
+ cursor: default;
300
+ }
301
+ #close {
302
+ position: absolute;
303
+ top: 1rem;
304
+ right: 1rem;
305
+ z-index: 1;
306
+ background: none;
307
+ border: none;
308
+ color: white;
309
+ cursor: pointer;
310
+ }
311
+ .nav-btn {
312
+ position: fixed;
313
+ top: 50%;
314
+ transform: translateY(-50%);
315
+ z-index: 1;
316
+ background: none;
317
+ border: none;
318
+ color: white;
319
+ cursor: pointer;
320
+ padding: 1rem;
321
+ opacity: 0.7;
322
+ font-size: 3rem;
323
+ -webkit-text-stroke: 1px black;
324
+ text-stroke: 1px black;
325
+ text-shadow: 0 0 3px rgba(0,0,0,0.8);
326
+ }
327
+ .nav-btn::slotted(*),
328
+ .nav-btn k-icon {
329
+ filter: drop-shadow(0 0 2px rgba(0,0,0,1)) drop-shadow(0 0 2px rgba(0,0,0,1));
330
+ }
331
+ .nav-btn:hover {
332
+ opacity: 1;
333
+ }
334
+ #prev {
335
+ left: 1rem;
336
+ }
337
+ #next {
338
+ right: 1rem;
339
+ }
340
+ .caption {
341
+ text-align: center;
342
+ max-width: 600px;
343
+ width: fit-content;
344
+ margin: 1rem auto 0;
345
+ }
346
+ #fullscreen-overlay .caption {
347
+ color: white;
348
+ }
349
+ :host([fullscreen]) .caption {
350
+ color: white;
351
+ }
352
+ `;
353
+ }
354
+
355
+ /* Static Members */
356
+ static observedAttributes = [...super.observedAttributes, 'src', 'alt', 'fullscreen', 'keyboard-controls', 'global'];
357
+ }
358
+ window.customElements.define('k-photo-viewer', PhotoViewer);
@@ -31,23 +31,23 @@
31
31
  :root,
32
32
  [theme="light"] {
33
33
  color-scheme: light;
34
- --c_bg: #f9f9f9;
35
- --c_bg__inv: #333;
36
- --c_bg__alt: #eee;
37
- --c_overscroll: white;
38
- --c_border: #ccc;
34
+ --c_bg: rgb(249, 249, 249);
35
+ --c_bg__inv: rgb(51, 51, 51);
36
+ --c_bg__alt: rgb(238, 238, 238);
37
+ --c_overscroll: rgb(255, 255, 255);
38
+ --c_border: rgb(204, 204, 204);
39
39
  --c_border__inv: var(--d_c_bg_border);
40
- --c_primary: #36f;
41
- --c_primary__hover: #14d;
42
- --c_secondary: #93f;
43
- --c_secondary__hover: #71d;
44
- --c_success: #080;
45
- --c_success__hover: #060;
46
- --c_warning: #f60;
47
- --c_warning__hover: #d40;
48
- --c_danger: #f03;
49
- --c_danger__hover: #d01;
50
- --c_input_accent: #36f;
40
+ --c_primary: rgb(51, 102, 255);
41
+ --c_primary__hover: rgb(17, 68, 221);
42
+ --c_secondary: rgb(153, 51, 255);
43
+ --c_secondary__hover: rgb(119, 17, 221);
44
+ --c_success: rgb(0, 136, 0);
45
+ --c_success__hover: rgb(0, 102, 0);
46
+ --c_warning: rgb(255, 102, 0);
47
+ --c_warning__hover: rgb(221, 68, 0);
48
+ --c_danger: rgb(255, 0, 51);
49
+ --c_danger__hover: rgb(221, 0, 17);
50
+ --c_input_accent: rgb(51, 102, 255);
51
51
  --c_highlight: rgba(41, 100, 210, 0.25);
52
52
  --tc: rgba(0, 0, 0, 0.93);
53
53
  --tc_dark: var(--tc);
@@ -68,8 +68,8 @@
68
68
  --btn_box_shadow: 0 0 0 transparent;
69
69
  --btn_box_shadow__hover: 0 0 0 transparent;
70
70
  --btn_border: transparent;
71
- --btn_bg: #ddd;
72
- --btn_bg__hover: #ccc;
71
+ --btn_bg: rgb(221, 221, 221);
72
+ --btn_bg__hover: rgb(204, 204, 204);
73
73
  --btn_tc: rgba(0, 0, 0, 0.93);
74
74
  --btn_transparent__hover: rgba(0, 0, 0, 0.05);
75
75
  --tc_link: var(--tc_primary);
@@ -85,23 +85,23 @@
85
85
  [auto-theme="dark"]:not([theme="light"]),
86
86
  [theme="dark"] {
87
87
  color-scheme: dark;
88
- --c_bg: #333;
89
- --c_bg__inv: #f9f9f9;
90
- --c_bg__alt: #222;
91
- --c_overscroll: black;
92
- --c_border: #777;
93
- --c_border__inv: #ccc;
94
- --c_primary: #36f;
95
- --c_primary__hover: #14d;
96
- --c_secondary: #93f;
97
- --c_secondary__hover: #71d;
98
- --c_success: #080;
99
- --c_success__hover: #060;
100
- --c_warning: #f60;
101
- --c_warning__hover: #d40;
102
- --c_danger: #f03;
103
- --c_danger__hover: #d01;
104
- --c_input_accent: #36f;
88
+ --c_bg: rgb(51, 51, 51);
89
+ --c_bg__inv: rgb(249, 249, 249);
90
+ --c_bg__alt: rgb(34, 34, 34);
91
+ --c_overscroll: rgb(0, 0, 0);
92
+ --c_border: rgb(119, 119, 119);
93
+ --c_border__inv: rgb(204, 204, 204);
94
+ --c_primary: rgb(51, 102, 255);
95
+ --c_primary__hover: rgb(17, 68, 221);
96
+ --c_secondary: rgb(153, 51, 255);
97
+ --c_secondary__hover: rgb(119, 17, 221);
98
+ --c_success: rgb(0, 136, 0);
99
+ --c_success__hover: rgb(0, 102, 0);
100
+ --c_warning: rgb(255, 102, 0);
101
+ --c_warning__hover: rgb(221, 68, 0);
102
+ --c_danger: rgb(255, 0, 51);
103
+ --c_danger__hover: rgb(221, 0, 17);
104
+ --c_input_accent: rgb(51, 102, 255);
105
105
  --c_highlight: rgba(0, 89, 255, 0.25);
106
106
  --tc: rgba(255, 255, 255, 0.93);
107
107
  --tc_dark: rgba(0, 0, 0, 0.93);
@@ -114,13 +114,13 @@
114
114
  --tc_on_warning: var(--tc);
115
115
  --tc_on_danger: var(--tc);
116
116
  --c_overlay: rgba(0, 0, 0, 0.5);
117
- --tc_primary: #8ab4f8;
118
- --tc_secondary: #b6f;
119
- --tc_success: #6b6;
120
- --tc_warning: #f93;
121
- --tc_danger: #f57;
122
- --btn_bg: #aaa;
123
- --btn_bg__hover: #bbb;
117
+ --tc_primary: rgb(138, 180, 248);
118
+ --tc_secondary: rgb(187, 102, 255);
119
+ --tc_success: rgb(102, 187, 102);
120
+ --tc_warning: rgb(255, 153, 51);
121
+ --tc_danger: rgb(255, 85, 119);
122
+ --btn_bg: rgb(170, 170, 170);
123
+ --btn_bg__hover: rgb(187, 187, 187);
124
124
  --btn_tc: rgba(0, 0, 0, 0.93);
125
125
  --btn_transparent__hover: rgba(255, 255, 255, 0.05);
126
126
  --btn_box_shadow: 0 0 0 transparent;
@@ -1,84 +0,0 @@
1
- <nav
2
- class="d-f bg-primary fixed"
3
- >
4
- <button
5
- id="open-side-menu"
6
- class="link"
7
- >
8
- <k-icon name="menu"></k-icon>
9
- </button>
10
- <a href="../">Home</a>
11
- <k-search
12
- class="flex mr"
13
- style="min-width:10rem;max-width:24rem"
14
- ></k-search>
15
- <div class="flex"></div>
16
- <k-theme-switcher></k-theme-switcher>
17
- </nav>
18
- <div style="width: 100%; height: 4rem;"></div>
19
- <k-side-menu
20
- id="side-menu"
21
- >
22
- <h1>Kempo Docs</h1>
23
- <menu>
24
- <a href="../" class="h5 pl0 mb">Home</a>
25
- <h5 class="mb0">Styles</h5>
26
- <div class="pl mb">
27
- <a href="../styles/typography.html">Typography</a>
28
- <a href="../styles/displays-layouts.html">Displays and Layouts</a>
29
- <a href="../styles/borders-spacing.html">Borders and Spacing</a>
30
- <a href="../styles/inputs.html">Inputs</a>
31
- <a href="../styles/buttons.html">Buttons</a>
32
- <a href="../styles/tables.html">Tables</a>
33
- <a href="../styles/colors.html">Colors</a>
34
- </div>
35
- <h5 class="mb0">Components</h5>
36
- <div class="pl mb">
37
- <a href="../components/component.html">Component</a>
38
- <a href="../components/lazy-component.html">LazyComponent</a>
39
- <a href="../components/reactivecomponent.html">ReactiveComponent</a>
40
- <a href="../components/reactivelazy-component.html">ReactiveLazyComponent</a>
41
- <a href="../components/focuscapture.html">FocusCapture</a>
42
- <hr />
43
- <a href="../components/accordion.html">Accordion</a>
44
- <a href="../components/card.html">Card</a>
45
- <a href="../components/content-slider.html">Content Slider</a>
46
- <a href="../components/dialog.html">Dialog</a>
47
- <a href="../components/directory-viewer.html">Directory Viewer</a>
48
- <a href="../components/icon.html">Icon</a>
49
- <a href="../components/import.html">Import</a>
50
- <a href="../components/resize.html">Resize</a>
51
- <a href="../components/search.html">Search</a>
52
- <a href="../components/show-more.html">Show More</a>
53
- <a href="../components/side-menu.html">Side Menu</a>
54
- <a href="../components/split.html">Split</a>
55
- <a href="../components/table.html">Table</a>
56
- <a href="../components/tabs.html">Tabs</a>
57
- <a href="../components/tags.html">Tags</a>
58
- <a href="../components/theme-switcher.html">Theme Switcher</a>
59
- <a href="../components/timestamp.html">Timestamp</a>
60
- <a href="../components/toggle.html">Toggle</a>
61
- </div>
62
-
63
- <h5 class="mb0">Utils</h5>
64
- <div class="pl mb">
65
- <a href="../utils/cli.html">CLI</a>
66
- <a href="../utils/cookie.html">Cookie</a>
67
- <a href="../utils/debounce.html">Debounce</a>
68
- <a href="../utils/drag.html">Drag</a>
69
- <a href="../utils/element.html">Element</a>
70
- <a href="../utils/format-timestamp.html">Format Timestamp</a>
71
- <a href="../utils/fuzzy-match.html">Fuzzy Match</a>
72
- </div>
73
- </menu>
74
- </k-side-menu>
75
- <script>
76
- document.getElementById('open-side-menu').addEventListener('click', async () => {
77
- await window.customElements.whenDefined('k-side-menu');
78
- document.getElementById('side-menu').open();
79
- });
80
- </script>
81
- <script src="../kempo/components/SideMenu.js" type="module"></script>
82
- <script src="../kempo/components/Icon.js" type="module"></script>
83
- <script src="../kempo/components/ThemeSwitcher.js" type="module"></script>
84
- <script src="../kempo/components/Search.js" type="module"></script>