kempo-ui 0.0.3 → 0.0.5

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 (193) hide show
  1. package/.github/workflows/publish-major.yml +39 -0
  2. package/.github/workflows/publish-minor.yml +39 -0
  3. package/.github/workflows/{publish-npm.yml → publish-patch.yml} +1 -1
  4. package/.vscode/settings.json +2 -0
  5. package/dist/kempo-hljs.css +1 -0
  6. package/dist/src/components/Accordion.js +36 -0
  7. package/dist/src/components/Card.js +37 -0
  8. package/dist/src/components/Collapsible.js +41 -0
  9. package/dist/src/components/ContentSlider.js +44 -0
  10. package/dist/src/components/Dialog.js +120 -0
  11. package/dist/src/components/Icon.js +2 -2
  12. package/dist/src/components/PersistantCollapsible.js +1 -0
  13. package/dist/src/components/PhotoViewer.js +135 -0
  14. package/dist/src/components/Resize.js +96 -0
  15. package/dist/src/components/ShadowComponent.js +1 -1
  16. package/dist/src/components/ShowMore.js +42 -0
  17. package/dist/src/components/SideMenu.js +1 -1
  18. package/dist/src/components/Sortable.js +45 -0
  19. package/dist/src/components/Split.js +84 -0
  20. package/dist/src/components/Table.js +151 -0
  21. package/dist/src/components/Tabs.js +155 -0
  22. package/dist/src/components/Tags.js +69 -0
  23. package/dist/src/components/ThemeSwitcher.js +23 -0
  24. package/dist/src/components/Timestamp.js +1 -0
  25. package/dist/src/components/Toast.js +141 -0
  26. package/dist/src/components/Toggle.js +74 -0
  27. package/dist/src/components/tableControls/DeleteRecord.js +7 -0
  28. package/dist/src/components/tableControls/Edit.js +18 -0
  29. package/dist/src/components/tableControls/ExportCSV.js +8 -0
  30. package/dist/src/components/tableControls/ExportJson.js +8 -0
  31. package/dist/src/components/tableControls/FieldSortHide.js +26 -0
  32. package/dist/src/components/tableControls/Filters.js +47 -0
  33. package/dist/src/components/tableControls/FirstPage.js +9 -0
  34. package/dist/src/components/tableControls/HiddenCount.js +3 -0
  35. package/dist/src/components/tableControls/Hide.js +5 -0
  36. package/dist/src/components/tableControls/LastPage.js +9 -0
  37. package/dist/src/components/tableControls/NextPage.js +9 -0
  38. package/dist/src/components/tableControls/PageSelect.js +22 -0
  39. package/dist/src/components/tableControls/PageSize.js +5 -0
  40. package/dist/src/components/tableControls/PrevPage.js +9 -0
  41. package/dist/src/components/tableControls/Search.js +9 -0
  42. package/dist/src/components/tableControls/ShowAll.js +5 -0
  43. package/dist/src/components/tableControls/TableControl.js +16 -0
  44. package/dist/src/utils/debounce.js +1 -0
  45. package/dist/src/utils/drag.js +1 -0
  46. package/dist/src/utils/formatTimestamp.js +1 -0
  47. package/dist/src/utils/propConverters.js +1 -0
  48. package/dist/src/utils/toTitleCase.js +1 -0
  49. package/dist/src/utils/watchWindowSize.js +1 -0
  50. package/docs/components/accordion.html +69 -25
  51. package/docs/components/card.html +6 -5
  52. package/docs/components/collapsible.html +198 -0
  53. package/docs/components/content-slider.html +56 -26
  54. package/docs/components/dialog.html +54 -48
  55. package/docs/components/focus-capture.html +59 -15
  56. package/docs/components/hybrid-component.html +112 -0
  57. package/docs/components/icon.html +5 -10
  58. package/docs/components/import.html +1 -6
  59. package/docs/components/light-component.html +99 -0
  60. package/docs/components/persistant-collapsible.html +123 -0
  61. package/docs/components/photo-viewer.html +226 -0
  62. package/docs/components/resize.html +44 -18
  63. package/docs/components/shadow-component.html +88 -0
  64. package/docs/components/show-more.html +12 -6
  65. package/docs/components/side-menu.html +3 -12
  66. package/docs/components/sortable.html +91 -55
  67. package/docs/components/split.html +26 -5
  68. package/docs/components/tablePagination.html +4 -4
  69. package/docs/components/tableRecordFiltering.html +16 -3
  70. package/docs/components/tableRecordSelection.html +2 -2
  71. package/docs/components/tabs.html +24 -7
  72. package/docs/components/tags.html +24 -8
  73. package/docs/components/theme-switcher.html +3 -6
  74. package/docs/components/timestamp.html +20 -24
  75. package/docs/components/toast.html +23 -32
  76. package/docs/components/toggle.html +4 -3
  77. package/docs/icons/error.svg +1 -1
  78. package/docs/icons/warning.svg +1 -1
  79. package/docs/index.html +197 -5
  80. package/docs/kempo-hljs.css +1 -0
  81. package/docs/kempo.min.css +1 -1
  82. package/docs/media/civic.jpg +0 -0
  83. package/docs/media/corvette.jpg +0 -0
  84. package/docs/media/evo.jpg +0 -0
  85. package/docs/media/gtr.jpg +0 -0
  86. package/docs/media/nsx.jpg +0 -0
  87. package/docs/nav.inc.html +19 -24
  88. package/docs/src/components/Accordion.js +36 -0
  89. package/docs/src/components/Card.js +37 -0
  90. package/docs/src/components/Collapsible.js +41 -0
  91. package/docs/src/components/ContentSlider.js +44 -0
  92. package/docs/src/components/Dialog.js +120 -0
  93. package/docs/src/components/Icon.js +2 -2
  94. package/docs/src/components/PersistantCollapsible.js +1 -0
  95. package/docs/src/components/PhotoViewer.js +135 -0
  96. package/docs/src/components/Resize.js +96 -0
  97. package/docs/src/components/ShadowComponent.js +1 -1
  98. package/docs/src/components/ShowMore.js +42 -0
  99. package/docs/src/components/SideMenu.js +1 -1
  100. package/docs/src/components/Sortable.js +45 -0
  101. package/docs/src/components/Split.js +84 -0
  102. package/docs/src/components/Table.js +151 -0
  103. package/docs/src/components/Tabs.js +155 -0
  104. package/docs/src/components/Tags.js +69 -0
  105. package/docs/src/components/ThemeSwitcher.js +23 -0
  106. package/docs/src/components/Timestamp.js +1 -0
  107. package/docs/src/components/Toast.js +141 -0
  108. package/docs/src/components/Toggle.js +74 -0
  109. package/docs/src/components/tableControls/DeleteRecord.js +7 -0
  110. package/docs/src/components/tableControls/Edit.js +18 -0
  111. package/docs/src/components/tableControls/ExportCSV.js +8 -0
  112. package/docs/src/components/tableControls/ExportJson.js +8 -0
  113. package/docs/src/components/tableControls/FieldSortHide.js +26 -0
  114. package/docs/src/components/tableControls/Filters.js +47 -0
  115. package/docs/src/components/tableControls/FirstPage.js +9 -0
  116. package/docs/src/components/tableControls/HiddenCount.js +3 -0
  117. package/docs/src/components/tableControls/Hide.js +5 -0
  118. package/docs/src/components/tableControls/LastPage.js +9 -0
  119. package/docs/src/components/tableControls/NextPage.js +9 -0
  120. package/docs/src/components/tableControls/PageSelect.js +22 -0
  121. package/docs/src/components/tableControls/PageSize.js +5 -0
  122. package/docs/src/components/tableControls/PrevPage.js +9 -0
  123. package/docs/src/components/tableControls/Search.js +9 -0
  124. package/docs/src/components/tableControls/ShowAll.js +5 -0
  125. package/docs/src/components/tableControls/TableControl.js +16 -0
  126. package/docs/src/utils/debounce.js +1 -0
  127. package/docs/src/utils/drag.js +1 -0
  128. package/docs/src/utils/formatTimestamp.js +1 -0
  129. package/docs/src/utils/propConverters.js +1 -0
  130. package/docs/src/utils/toTitleCase.js +1 -0
  131. package/docs/src/utils/watchWindowSize.js +1 -0
  132. package/docs/utils/debounce.html +78 -0
  133. package/docs/utils/drag.html +89 -0
  134. package/docs/utils/formatTimestamp.html +114 -0
  135. package/docs/utils/propConverters.html +132 -0
  136. package/docs/utils/toTitleCase.html +71 -0
  137. package/docs/utils/watchWindowSize.html +166 -0
  138. package/icons/error.svg +1 -1
  139. package/icons/warning.svg +1 -1
  140. package/package.json +1 -1
  141. package/scripts/build.js +4 -1
  142. package/scripts/docs.js +4 -2
  143. package/src/components/Accordion.js +229 -0
  144. package/src/components/Collapsible.js +109 -0
  145. package/src/components/ContentSlider.js +205 -0
  146. package/src/components/Dialog.js +376 -0
  147. package/src/components/PersistantCollapsible.js +69 -0
  148. package/src/components/PhotoViewer.js +368 -0
  149. package/src/components/Resize.js +210 -0
  150. package/src/components/ShadowComponent.js +3 -1
  151. package/src/components/ShowMore.js +109 -0
  152. package/src/components/Sortable.js +193 -0
  153. package/src/components/Split.js +192 -0
  154. package/src/components/Table.js +1202 -0
  155. package/src/components/Tabs.js +428 -0
  156. package/src/components/Tags.js +253 -0
  157. package/src/components/Timestamp.js +31 -0
  158. package/src/components/Toast.js +454 -0
  159. package/src/components/Toggle.js +173 -0
  160. package/src/components/tableControls/DeleteRecord.js +29 -0
  161. package/src/components/tableControls/Edit.js +88 -0
  162. package/src/components/tableControls/ExportCSV.js +71 -0
  163. package/src/components/tableControls/ExportJson.js +55 -0
  164. package/src/components/tableControls/FieldSortHide.js +76 -0
  165. package/src/components/tableControls/Filters.js +114 -0
  166. package/src/components/tableControls/FirstPage.js +65 -0
  167. package/src/components/tableControls/HiddenCount.js +45 -0
  168. package/src/components/tableControls/Hide.js +34 -0
  169. package/src/components/tableControls/LastPage.js +65 -0
  170. package/src/components/tableControls/NextPage.js +65 -0
  171. package/src/components/tableControls/PageSelect.js +109 -0
  172. package/src/components/tableControls/PageSize.js +68 -0
  173. package/src/components/tableControls/PrevPage.js +65 -0
  174. package/src/components/tableControls/Search.js +58 -0
  175. package/src/components/tableControls/ShowAll.js +34 -0
  176. package/src/components/tableControls/TableControl.js +105 -0
  177. package/src/utils/debounce.js +9 -0
  178. package/src/utils/drag.js +80 -0
  179. package/src/utils/formatTimestamp.js +27 -0
  180. package/src/utils/toTitleCase.js +9 -0
  181. package/src/utils/watchWindowSize.js +16 -0
  182. package/dist/src/utils/cli.js +0 -1
  183. package/dist/src/utils/fs-utils.js +0 -1
  184. package/docs/components/component.html +0 -90
  185. package/docs/components/directory-viewer.html +0 -90
  186. package/docs/components/lazy-component.html +0 -84
  187. package/docs/components/reactive-component.html +0 -69
  188. package/docs/components/reactive-lazy-component.html +0 -69
  189. package/docs/components/search.html +0 -102
  190. package/docs/src/utils/cli.js +0 -1
  191. package/docs/src/utils/fs-utils.js +0 -1
  192. package/src/utils/cli.js +0 -43
  193. package/src/utils/fs-utils.js +0 -41
@@ -0,0 +1,368 @@
1
+ import ShadowComponent from './ShadowComponent.js';
2
+ import { html, css } from '../lit-all.min.js';
3
+ import { boolExists } from '../utils/propConverters.js';
4
+ import './Icon.js';
5
+
6
+ export default class PhotoViewer extends ShadowComponent {
7
+ /*
8
+ Properties
9
+ */
10
+ static properties = {
11
+ src: { type: String, reflect: true },
12
+ alt: { type: String, reflect: true },
13
+ fullscreen: { type: Boolean, reflect: true, converter: boolExists },
14
+ keyboardControls: { type: Boolean, reflect: true, attribute: 'keyboard-controls', converter: boolExists },
15
+ global: { type: Boolean, reflect: true, converter: boolExists }
16
+ };
17
+
18
+ constructor() {
19
+ super();
20
+ this.src = '';
21
+ this.alt = '';
22
+ this.fullscreen = false;
23
+ this.keyboardControls = true;
24
+ this.global = false;
25
+ }
26
+
27
+ /*
28
+ Event Handlers
29
+ */
30
+ handleImageClick = () => {
31
+ this.open();
32
+ }
33
+
34
+ handleImageKeydown = event => {
35
+ if(event.key === 'Enter' && !this.fullscreen) {
36
+ this.open();
37
+ }
38
+ }
39
+
40
+ handleCloseClick = () => {
41
+ this.close();
42
+ }
43
+
44
+ handleOverlayClick = event => {
45
+ if(event.target === event.currentTarget) {
46
+ this.close();
47
+ }
48
+ }
49
+
50
+ handlePrevClick = event => {
51
+ event.stopPropagation();
52
+ const prev = this.getPrevSibling();
53
+ if(prev) {
54
+ this.close();
55
+ prev.open();
56
+ }
57
+ }
58
+
59
+ handleNextClick = event => {
60
+ event.stopPropagation();
61
+ const next = this.getNextSibling();
62
+ if(next) {
63
+ this.close();
64
+ next.open();
65
+ }
66
+ }
67
+
68
+ handleKeydown = event => {
69
+ if(event.key === 'Escape') {
70
+ this.close();
71
+ } else if(event.key === 'ArrowLeft') {
72
+ const prev = this.getPrevSibling();
73
+ if(prev) {
74
+ this.close();
75
+ prev.open();
76
+ }
77
+ } else if(event.key === 'ArrowRight') {
78
+ const next = this.getNextSibling();
79
+ if(next) {
80
+ this.close();
81
+ next.open();
82
+ }
83
+ }
84
+ }
85
+
86
+ /*
87
+ Lifecycle Callbacks
88
+ */
89
+ connectedCallback() {
90
+ super.connectedCallback();
91
+ }
92
+
93
+ disconnectedCallback() {
94
+ super.disconnectedCallback();
95
+ if(this.keyboardControls) {
96
+ document.removeEventListener('keydown', this.handleKeydown);
97
+ }
98
+ }
99
+
100
+ updated(changedProperties) {
101
+ super.updated(changedProperties);
102
+
103
+ if(changedProperties.has('fullscreen')) {
104
+ this.dispatchEvent(new CustomEvent(`fullscreenchange`, {
105
+ detail: { fullscreen: this.fullscreen }
106
+ }));
107
+ this.dispatchEvent(new CustomEvent(this.fullscreen ? 'fullscreen' : 'fullscreenclose'));
108
+ this.updateNavigationState();
109
+
110
+ if(this.keyboardControls) {
111
+ if(this.fullscreen) {
112
+ document.addEventListener('keydown', this.handleKeydown);
113
+ } else {
114
+ document.removeEventListener('keydown', this.handleKeydown);
115
+ }
116
+ }
117
+ }
118
+
119
+ if(changedProperties.has('src') || changedProperties.has('alt')) {
120
+ this.handleFullscreenCaption();
121
+ }
122
+ }
123
+
124
+ firstUpdated() {
125
+ this.handleFullscreenCaption();
126
+ }
127
+
128
+ /*
129
+ Public Methods
130
+ */
131
+ open() {
132
+ this.fullscreen = true;
133
+ }
134
+
135
+ close() {
136
+ this.fullscreen = false;
137
+ }
138
+
139
+ toggle() {
140
+ this.fullscreen = !this.fullscreen;
141
+ }
142
+
143
+ /*
144
+ Private Methods
145
+ */
146
+ getPrevSibling() {
147
+ if(this.global) {
148
+ const viewers = Array.from(document.getElementsByTagName('k-photo-viewer'));
149
+ const index = viewers.indexOf(this);
150
+ if(index === -1) return null;
151
+ return viewers[index === 0 ? viewers.length - 1 : index - 1];
152
+ } else {
153
+ let prev = this.previousElementSibling;
154
+ while(prev && prev.tagName !== 'K-PHOTO-VIEWER') {
155
+ prev = prev.previousElementSibling;
156
+ }
157
+ if(!prev && this.hasPhotoSiblings()) {
158
+ prev = this.parentElement.lastElementChild;
159
+ while(prev && prev.tagName !== 'K-PHOTO-VIEWER') {
160
+ prev = prev.previousElementSibling;
161
+ }
162
+ }
163
+ return prev;
164
+ }
165
+ }
166
+
167
+ getNextSibling() {
168
+ if(this.global) {
169
+ const viewers = Array.from(document.getElementsByTagName('k-photo-viewer'));
170
+ const index = viewers.indexOf(this);
171
+ if(index === -1) return null;
172
+ return viewers[index === viewers.length - 1 ? 0 : index + 1];
173
+ } else {
174
+ let next = this.nextElementSibling;
175
+ while(next && next.tagName !== 'K-PHOTO-VIEWER') {
176
+ next = next.nextElementSibling;
177
+ }
178
+ if(!next && this.hasPhotoSiblings()) {
179
+ next = this.parentElement.firstElementChild;
180
+ while(next && next.tagName !== 'K-PHOTO-VIEWER') {
181
+ next = next.nextElementSibling;
182
+ }
183
+ }
184
+ return next;
185
+ }
186
+ }
187
+
188
+ hasPhotoSiblings() {
189
+ if(this.global) {
190
+ return document.getElementsByTagName('k-photo-viewer').length > 1;
191
+ }
192
+ return Array.from(this.parentElement.children)
193
+ .filter(el => el !== this && el.tagName === 'K-PHOTO-VIEWER')
194
+ .length > 0;
195
+ }
196
+
197
+ updateNavigationState() {
198
+ const hasNavigation = this.fullscreen && this.hasPhotoSiblings();
199
+ const navButtons = this.shadowRoot.querySelectorAll('.nav-btn');
200
+ navButtons.forEach(btn => {
201
+ btn.style.display = hasNavigation ? '' : 'none';
202
+ });
203
+ }
204
+
205
+ async handleFullscreenCaption() {
206
+ await this.updateComplete;
207
+ const fullscreenSlot = this.shadowRoot.querySelector('slot[name="fullscreen-caption"]');
208
+ if(fullscreenSlot && !fullscreenSlot.assignedNodes().length) {
209
+ const defaultSlot = this.shadowRoot.querySelector('slot:not([name])');
210
+ const contents = defaultSlot ? defaultSlot.assignedNodes() : [];
211
+ contents.forEach(node => {
212
+ if(node.nodeType === Node.ELEMENT_NODE) {
213
+ const clone = node.cloneNode(true);
214
+ clone.slot = 'fullscreen-caption';
215
+ this.appendChild(clone);
216
+ }
217
+ });
218
+ }
219
+ }
220
+
221
+ /*
222
+ Styles
223
+ */
224
+ static styles = css`
225
+ :host {
226
+ display: block;
227
+ }
228
+ #wrapper {
229
+ position: relative;
230
+ width: 100%;
231
+ height: 100%;
232
+ }
233
+ #img {
234
+ max-width: 100%;
235
+ height: auto;
236
+ cursor: pointer;
237
+ outline: none;
238
+ border-radius: var(--img_radius, 0);
239
+ }
240
+ #img:focus {
241
+ box-shadow: var(--focus_shadow);
242
+ }
243
+ #fullscreen-overlay {
244
+ position: fixed;
245
+ top: 0;
246
+ left: 0;
247
+ right: 0;
248
+ bottom: 0;
249
+ z-index: 9999;
250
+ background: rgba(0,0,0,0.9);
251
+ padding: 2rem;
252
+ display: none;
253
+ }
254
+ :host([fullscreen]) #fullscreen-overlay {
255
+ display: flex;
256
+ align-items: center;
257
+ justify-content: center;
258
+ }
259
+ .content {
260
+ position: relative;
261
+ max-width: 100%;
262
+ max-height: 90vh;
263
+ }
264
+ #fullscreen-img {
265
+ max-height: 75vh;
266
+ max-width: 100%;
267
+ object-fit: contain;
268
+ cursor: default;
269
+ }
270
+ #close {
271
+ position: absolute;
272
+ top: 1rem;
273
+ right: 1rem;
274
+ z-index: 1;
275
+ background: none;
276
+ border: none;
277
+ color: white;
278
+ cursor: pointer;
279
+ }
280
+ .nav-btn {
281
+ position: fixed;
282
+ top: 50%;
283
+ transform: translateY(-50%);
284
+ z-index: 1;
285
+ background: none;
286
+ border: none;
287
+ color: white;
288
+ cursor: pointer;
289
+ padding: 1rem;
290
+ opacity: 0.7;
291
+ font-size: 3rem;
292
+ -webkit-text-stroke: 1px black;
293
+ text-stroke: 1px black;
294
+ text-shadow: 0 0 3px rgba(0,0,0,0.8);
295
+ }
296
+ .nav-btn::slotted(*),
297
+ .nav-btn k-icon {
298
+ filter: drop-shadow(0 0 2px rgba(0,0,0,1)) drop-shadow(0 0 2px rgba(0,0,0,1));
299
+ }
300
+ .nav-btn:hover {
301
+ opacity: 1;
302
+ }
303
+ #prev {
304
+ left: 1rem;
305
+ }
306
+ #next {
307
+ right: 1rem;
308
+ }
309
+ .caption {
310
+ text-align: center;
311
+ max-width: 600px;
312
+ width: fit-content;
313
+ margin: 1rem auto 0;
314
+ }
315
+ #fullscreen-overlay .caption {
316
+ color: white;
317
+ }
318
+ :host([fullscreen]) .caption {
319
+ color: white;
320
+ }
321
+ `;
322
+
323
+ /*
324
+ Rendering
325
+ */
326
+ render() {
327
+ return html`
328
+ <div id="wrapper">
329
+ <img
330
+ id="img"
331
+ src="${this.src}"
332
+ alt="${this.alt}"
333
+ tabindex="0"
334
+ @click=${this.handleImageClick}
335
+ @keydown=${this.handleImageKeydown}
336
+ />
337
+ <div class="caption">
338
+ <slot></slot>
339
+ </div>
340
+ <div id="fullscreen-overlay" @click=${this.handleOverlayClick}>
341
+ <button id="close" class="no-btn" @click=${this.handleCloseClick}>
342
+ <slot name="close">
343
+ <k-icon name="close"></k-icon>
344
+ </slot>
345
+ </button>
346
+ <button id="prev" class="nav-btn no-btn" @click=${this.handlePrevClick}>
347
+ <slot name="prev">
348
+ <k-icon name="chevron-left"></k-icon>
349
+ </slot>
350
+ </button>
351
+ <button id="next" class="nav-btn no-btn" @click=${this.handleNextClick}>
352
+ <slot name="next">
353
+ <k-icon name="chevron-right"></k-icon>
354
+ </slot>
355
+ </button>
356
+ <div class="content">
357
+ <img id="fullscreen-img" src="${this.src}" alt="${this.alt}" />
358
+ <div class="caption">
359
+ <slot name="fullscreen-caption"></slot>
360
+ </div>
361
+ </div>
362
+ </div>
363
+ </div>
364
+ `;
365
+ }
366
+ }
367
+
368
+ customElements.define('k-photo-viewer', PhotoViewer);
@@ -0,0 +1,210 @@
1
+ import { LitElement, html, css } from '../lit-all.min.js';
2
+ import ShadowComponent from './ShadowComponent.js';
3
+ import Icon from './Icon.js';
4
+ import drag from '../utils/drag.js';
5
+
6
+ export default class Resize extends ShadowComponent {
7
+ /*
8
+ Properties
9
+ */
10
+ static properties = {
11
+ resizing: { type: String, reflect: true },
12
+ dimention: { type: String, reflect: true }
13
+ };
14
+
15
+ /*
16
+ Lifecycle Callbacks
17
+ */
18
+ constructor() {
19
+ super();
20
+ this.resizing = '';
21
+ this.dimension = '';
22
+ this.startSize = { width: 0, height: 0 };
23
+ this.cleanupFuncs = [];
24
+ }
25
+
26
+ firstUpdated() {
27
+ super.firstUpdated();
28
+ this.setupDragHandlers();
29
+ }
30
+
31
+ disconnectedCallback() {
32
+ super.disconnectedCallback();
33
+ this.cleanupFuncs.forEach(cleanup => cleanup());
34
+ }
35
+
36
+ /*
37
+ Event Handlers
38
+ */
39
+ dragStartHandler = ({ element }) => {
40
+ const { width, height } = this.getBoundingClientRect();
41
+ this.startSize.width = width;
42
+ this.startSize.height = height;
43
+ this.resizing = element.id;
44
+ };
45
+
46
+ dragEndHandler = () => {
47
+ this.resizing = '';
48
+ };
49
+
50
+ dragSideHandler = ({ x }) => {
51
+ this.style.width = this.startSize.width + x + 'px';
52
+ };
53
+
54
+ dragBottomHandler = ({ y }) => {
55
+ this.style.height = this.startSize.height + y + 'px';
56
+ };
57
+
58
+ dragCornerHandler = ({ x, y }) => {
59
+ this.style.width = this.startSize.width + x + 'px';
60
+ this.style.height = this.startSize.height + y + 'px';
61
+ };
62
+
63
+ /*
64
+ Utility Methods
65
+ */
66
+ setupDragHandlers() {
67
+ const sideHandle = this.shadowRoot.getElementById('side');
68
+ const bottomHandle = this.shadowRoot.getElementById('bottom');
69
+ const cornerHandle = this.shadowRoot.getElementById('corner');
70
+
71
+ if(sideHandle) {
72
+ this.cleanupFuncs.push(drag({
73
+ element: sideHandle,
74
+ startCallback: this.dragStartHandler,
75
+ endCallback: this.dragEndHandler,
76
+ callback: this.dragSideHandler,
77
+ preventScroll: true
78
+ }));
79
+ }
80
+
81
+ if(bottomHandle) {
82
+ this.cleanupFuncs.push(drag({
83
+ element: bottomHandle,
84
+ startCallback: this.dragStartHandler,
85
+ endCallback: this.dragEndHandler,
86
+ callback: this.dragBottomHandler,
87
+ preventScroll: true
88
+ }));
89
+ }
90
+
91
+ if(cornerHandle) {
92
+ this.cleanupFuncs.push(drag({
93
+ element: cornerHandle,
94
+ startCallback: this.dragStartHandler,
95
+ endCallback: this.dragEndHandler,
96
+ callback: this.dragCornerHandler,
97
+ preventScroll: true
98
+ }));
99
+ }
100
+ }
101
+
102
+ /*
103
+ Styles
104
+ */
105
+ static styles = css`
106
+ :host {
107
+ --handle_size: 1rem;
108
+
109
+ display: grid;
110
+ grid-template-columns: 1fr var(--handle_size);
111
+ grid-template-rows: 1fr var(--handle_size);
112
+ border: 1px solid var(--c_border);
113
+ border-radius: var(--radius);
114
+ min-width: 10rem;
115
+ max-width: 100%;
116
+ min-height: 10rem;
117
+ max-height: 100%;
118
+ }
119
+ :host([dimension="height"]) {
120
+ grid-template-columns: 1fr;
121
+ }
122
+ :host([dimension="width"]) {
123
+ grid-template-rows: 1fr;
124
+ }
125
+ #main {
126
+ grid-row: 1;
127
+ grid-column: 1;
128
+ overflow: auto;
129
+ }
130
+ #side {
131
+ grid-row: 1;
132
+ grid-column: 2;
133
+ cursor: ew-resize;
134
+ }
135
+ #bottom {
136
+ grid-row: 2;
137
+ grid-column: 1;
138
+ text-align: center;
139
+ cursor: ns-resize;
140
+ }
141
+ #corner {
142
+ grid-row: 2;
143
+ grid-column: 2;
144
+ overflow: hidden;
145
+ cursor: nwse-resize;
146
+ }
147
+ .handle {
148
+ display: flex;
149
+ align-items: center;
150
+ justify-content: center;
151
+ }
152
+ .handle svg {
153
+ transform: scale(0.5);
154
+ }
155
+ #bottom svg {
156
+ height: var(--handle_size);
157
+ }
158
+ #side svg {
159
+ width: var(--handle_size);
160
+ }
161
+ #corner svg {
162
+ width: var(--handle_size);
163
+ height: var(--handle_size);
164
+ }
165
+ :host(:not([resizing=""])) #main {
166
+ pointer-events: none;
167
+ }
168
+ :host([resizing="side"]) #side,
169
+ :host([resizing="corner"]) #side,
170
+ :host([resizing="corner"]) #corner,
171
+ :host([resizing="corner"]) #bottom,
172
+ :host([resizing="bottom"]) #bottom {
173
+ background-color: var(--c_highlight);
174
+ }
175
+ :host([dimension="height"]) #side,
176
+ :host([dimension="height"]) #corner,
177
+ :host([dimension="width"]) #bottom,
178
+ :host([dimension="width"]) #corner {
179
+ display: none;
180
+ }
181
+ `;
182
+
183
+ /*
184
+ Rendering
185
+ */
186
+ render() {
187
+ return html`
188
+ <div id="main">
189
+ <slot></slot>
190
+ </div>
191
+ <div id="side" class="handle">
192
+ <svg viewBox="0 0 15 64" xmlns="http://www.w3.org/2000/svg">
193
+ <path fill="currentColor" d="m 15.000001,3 c 0,-1.661998 -1.115001,-3 -2.5,-3 -1.384999,0 -2.5,1.338002 -2.5,3 v 58 c 0,1.661998 1.115001,3 2.5,3 1.384999,0 2.5,-1.338002 2.5,-3 z M 5.0000008,3 c 0,-1.661998 -1.115001,-3 -2.5,-3 C 1.1150018,0 7.5891117e-7,1.338002 7.5891117e-7,3 v 58 c 0,1.661998 1.11500104108883,3 2.50000004108883,3 1.384999,0 2.5,-1.338002 2.5,-3 z" />
194
+ </svg>
195
+ </div>
196
+ <div id="bottom" class="handle">
197
+ <svg viewBox="0 0 64 15" xmlns="http://www.w3.org/2000/svg">
198
+ <path fill="currentColor" d="M 3,0 C 1.3380017,0 0,1.1150014 0,2.5 0,3.8849986 1.3380017,5 3,5 H 61 C 62.661998,5 64,3.8849986 64,2.5 64,1.1150014 62.661998,0 61,0 Z M 3,10 C 1.3380017,10 0,11.115001 0,12.5 0,13.884999 1.3380017,15 3,15 h 58 c 1.661998,0 3,-1.115001 3,-2.5 C 64,11.115001 62.661998,10 61,10 Z" />
199
+ </svg>
200
+ </div>
201
+ <div id="corner" class="handle">
202
+ <svg version="1.1" viewBox="0 0 15 15" xmlns="http://www.w3.org/2000/svg">
203
+ <path fill="currentColor" d="m12.735 3.0095e-4c-0.77288 0.011702-1.6098 0.36368-2.2773 1.0313l-9.4258 9.4258c-1.1868 1.1868-1.3772 2.908-0.42773 3.8574 0.94943 0.94943 2.6687 0.7571 3.8555-0.42969l9.4258-9.4258c1.1868-1.1868 1.3772-2.906 0.42774-3.8555-0.41537-0.41537-0.977-0.61262-1.5781-0.60352zm0 8.5684c-0.77288 0.011702-1.6098 0.36564-2.2773 1.0332l-0.85744 0.85546c-1.1868 1.1868-1.3772 2.908-0.42773 3.8574 0.94943 0.94943 2.6687 0.7571 3.8555-0.42969l0.85742-0.85742c1.1868-1.1868 1.3772-2.906 0.42773-3.8555-0.41537-0.41537-0.977-0.61262-1.5781-0.60352z" />
204
+ </svg>
205
+ </div>
206
+ `;
207
+ }
208
+ }
209
+
210
+ customElements.define('k-resize', Resize);
@@ -1,12 +1,14 @@
1
1
  import { LitElement } from '../lit-all.min.js';
2
2
 
3
3
  export default class ShadowComponent extends LitElement {
4
+ static stylesheetPath = '/kempo.min.css';
5
+
4
6
  createRenderRoot() {
5
7
  const shadowRoot = this.attachShadow({ mode: 'open' });
6
8
 
7
9
  const link = document.createElement('link');
8
10
  link.rel = 'stylesheet';
9
- link.href = '/kempo.min.css';
11
+ link.href = this.constructor.stylesheetPath;
10
12
  shadowRoot.appendChild(link);
11
13
 
12
14
  // Inject component styles if they exist
@@ -0,0 +1,109 @@
1
+ import { LitElement, html, css } from '../lit-all.min.js';
2
+ import ShadowComponent from './ShadowComponent.js';
3
+ import Icon from './Icon.js';
4
+ import { boolExists } from '../utils/propConverters.js';
5
+
6
+ export default class ShowMore extends ShadowComponent {
7
+ /*
8
+ Properties
9
+ */
10
+ static properties = {
11
+ opened: { type: Boolean, converter: boolExists, reflect: true }
12
+ };
13
+
14
+ /*
15
+ Lifecycle Callbacks
16
+ */
17
+ constructor() {
18
+ super();
19
+ this.opened = false;
20
+ }
21
+
22
+ updated(changedProperties) {
23
+ super.updated(changedProperties);
24
+
25
+ if(changedProperties.has('opened')) {
26
+ this.dispatchEvent(new CustomEvent('change', {
27
+ detail: { opened: this.opened }
28
+ }));
29
+ this.dispatchEvent(new CustomEvent(this.opened ? 'opened' : 'closed'));
30
+ }
31
+ }
32
+
33
+ /*
34
+ Event Handlers
35
+ */
36
+ handleToggleClick = () => {
37
+ this.toggle();
38
+ };
39
+
40
+ /*
41
+ Public Methods
42
+ */
43
+ more() {
44
+ this.opened = true;
45
+ }
46
+
47
+ less() {
48
+ this.opened = false;
49
+ }
50
+
51
+ toggle() {
52
+ this.opened = !this.opened;
53
+ }
54
+
55
+ /*
56
+ Styles
57
+ */
58
+ static styles = css`
59
+ :host {
60
+ --closed_height: 7rem;
61
+
62
+ display: block;
63
+ }
64
+ :host(:not([opened])) #content {
65
+ height: var(--closed_height);
66
+ overflow-y: hidden;
67
+ }
68
+ :host(:not([opened])) #content {
69
+ margin-bottom: calc(var(--closed_height) * -0.9);
70
+ }
71
+ :host(:not([opened])) #toggle {
72
+ padding-top: calc(var(--closed_height) - 2rem);
73
+ background: linear-gradient(to bottom, transparent 0%, var(--c_bg) 95%);
74
+ }
75
+ #toggle {
76
+ width: 100%;
77
+ padding: var(--spacer_h);
78
+ text-align: center;
79
+ background: var(--c_bg);
80
+ }
81
+ :host([opened]) #more,
82
+ :host(:not([opened])) #less {
83
+ display: none;
84
+ }
85
+ `;
86
+
87
+ /*
88
+ Rendering
89
+ */
90
+ render() {
91
+ return html`
92
+ <div id="wrapper">
93
+ <div id="content">
94
+ <slot></slot>
95
+ </div>
96
+ <button id="toggle" @click=${this.handleToggleClick} class="no-btn">
97
+ <span id="more">
98
+ <slot name="more">Show More <k-icon name="arrow-down-double"></k-icon></slot>
99
+ </span>
100
+ <span id="less">
101
+ <slot name="less">Show Less <k-icon name="arrow-up-double"></k-icon></slot>
102
+ </span>
103
+ </button>
104
+ </div>
105
+ `;
106
+ }
107
+ }
108
+
109
+ customElements.define('k-show-more', ShowMore);