@kubex/zinc 1.0.8 → 1.0.9
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.
- package/dist/custom-elements.json +94 -74
- package/dist/vscode.html-custom-data.json +12 -11
- package/dist/web-types.json +25 -23
- package/dist/zn.d.ts +4 -0
- package/dist/zn.min.css +1 -1
- package/dist/zn.min.js +268 -272
- package/docs/pages/components/button.md +14 -0
- package/package.json +1 -1
- package/scss/themes/_light.scss +1 -1
- package/src/components/button/button.component.ts +12 -20
- package/src/components/button/button.scss +3 -33
- package/src/components/content-block/content-block.scss +54 -0
- package/src/components/data-table/data-table.component.ts +22 -3
- package/src/components/editor/editor.scss +0 -1
- package/src/components/panel/panel.component.ts +5 -1
- package/src/components/panel/panel.scss +4 -0
- package/src/components/settings-container/settings-container.component.ts +1 -1
- package/src/components/tabs/tabs.component.ts +24 -6
- package/src/internal/form.ts +41 -3
|
@@ -34,6 +34,20 @@ The `auto-click` attribute can be added to a button to make it automatically cli
|
|
|
34
34
|
color="transparent"
|
|
35
35
|
></zn-button>
|
|
36
36
|
</zn-button auto-click>
|
|
37
|
+
|
|
38
|
+
<br>
|
|
39
|
+
<br>
|
|
40
|
+
|
|
41
|
+
<zn-button color="success" auto-click auto-click-delay="10000" loading-text="Accepting">
|
|
42
|
+
Test Auto Button
|
|
43
|
+
<zn-style slot="cancel" margin="l">
|
|
44
|
+
<zn-button
|
|
45
|
+
icon="call_end"
|
|
46
|
+
icon-size="18"
|
|
47
|
+
type="button"
|
|
48
|
+
color="error"
|
|
49
|
+
></zn-button></zn-style>
|
|
50
|
+
</zn-button>
|
|
37
51
|
```
|
|
38
52
|
|
|
39
53
|
### Variants
|
package/package.json
CHANGED
package/scss/themes/_light.scss
CHANGED
|
@@ -361,26 +361,7 @@ export default class ZnButton extends ZincElement implements ZincFormControl {
|
|
|
361
361
|
${this.content}
|
|
362
362
|
</slot>
|
|
363
363
|
${this.iconPosition === 'right' ? icon : ''}
|
|
364
|
-
${this.
|
|
365
|
-
<div class="button--loading-container">
|
|
366
|
-
<span
|
|
367
|
-
class=${classMap({
|
|
368
|
-
'button--loading-text-bottom': true,
|
|
369
|
-
'button--loading-text-bottom-transparent': this.color === 'transparent',
|
|
370
|
-
[`button--loading-text-bottom-${this.loadingTextPosition}`]: !!this.loadingTextPosition,
|
|
371
|
-
})}>
|
|
372
|
-
${this.loadingText}<span class="loading-countdown"></span>
|
|
373
|
-
</span>
|
|
374
|
-
<span
|
|
375
|
-
class=${classMap({
|
|
376
|
-
'button--loading-text-top': true,
|
|
377
|
-
'button--loading-text-top-transparent': this.color === 'transparent',
|
|
378
|
-
[`button--loading-text-top-${this.loadingTextPosition}`]: !!this.loadingTextPosition,
|
|
379
|
-
})}>
|
|
380
|
-
${this.loadingText}<span class="loading-countdown"></span>
|
|
381
|
-
</span>
|
|
382
|
-
</div>
|
|
383
|
-
` : null}
|
|
364
|
+
${this._getLoadingContainer()}
|
|
384
365
|
</${tag}>`;
|
|
385
366
|
|
|
386
367
|
let content = this.autoClick ? html`
|
|
@@ -401,4 +382,15 @@ export default class ZnButton extends ZincElement implements ZincFormControl {
|
|
|
401
382
|
|
|
402
383
|
return content;
|
|
403
384
|
}
|
|
385
|
+
|
|
386
|
+
private _getLoadingContainer() {
|
|
387
|
+
return html`
|
|
388
|
+
${this.loading ? html`
|
|
389
|
+
<div class="button--loading-container">
|
|
390
|
+
<span class="button--loading-text">
|
|
391
|
+
${this.loadingText}<span class="loading-countdown"></span>
|
|
392
|
+
</span>
|
|
393
|
+
</div>
|
|
394
|
+
` : null}`;
|
|
395
|
+
}
|
|
404
396
|
}
|
|
@@ -312,8 +312,6 @@
|
|
|
312
312
|
}
|
|
313
313
|
|
|
314
314
|
.button--loading-bg {
|
|
315
|
-
background-color: #e0e0e0;
|
|
316
|
-
|
|
317
315
|
&-transparent {
|
|
318
316
|
background-color: transparent;
|
|
319
317
|
}
|
|
@@ -347,7 +345,8 @@
|
|
|
347
345
|
pointer-events: none;
|
|
348
346
|
}
|
|
349
347
|
|
|
350
|
-
&-text
|
|
348
|
+
&-text {
|
|
349
|
+
z-index: 5;
|
|
351
350
|
width: 100%;
|
|
352
351
|
height: 100%;
|
|
353
352
|
display: flex;
|
|
@@ -357,9 +356,8 @@
|
|
|
357
356
|
font-weight: inherit;
|
|
358
357
|
user-select: none;
|
|
359
358
|
position: absolute;
|
|
360
|
-
top: 0;
|
|
361
|
-
left: 0;
|
|
362
359
|
pointer-events: none;
|
|
360
|
+
color: inherit;
|
|
363
361
|
|
|
364
362
|
.loading-countdown {
|
|
365
363
|
margin-left: 3px;
|
|
@@ -375,25 +373,6 @@
|
|
|
375
373
|
padding-inline-end: 7px;
|
|
376
374
|
}
|
|
377
375
|
}
|
|
378
|
-
|
|
379
|
-
&-text-bottom {
|
|
380
|
-
z-index: 2;
|
|
381
|
-
color: rgba(var(--btn-color), .85);
|
|
382
|
-
|
|
383
|
-
&-transparent {
|
|
384
|
-
color: inherit;
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
&-text-top {
|
|
389
|
-
z-index: 3;
|
|
390
|
-
color: inherit;
|
|
391
|
-
/* Animate the reveal from left to right using a mask */
|
|
392
|
-
mask-image: linear-gradient(90deg, #000 0%, #000 100%);
|
|
393
|
-
mask-size: 0 100%;
|
|
394
|
-
mask-repeat: no-repeat;
|
|
395
|
-
animation: loading-text-reveal var(--loading-duration, 2s) linear forwards;
|
|
396
|
-
}
|
|
397
376
|
}
|
|
398
377
|
|
|
399
378
|
.button--relative-wrapper {
|
|
@@ -412,15 +391,6 @@
|
|
|
412
391
|
}
|
|
413
392
|
}
|
|
414
393
|
|
|
415
|
-
@keyframes loading-text-reveal {
|
|
416
|
-
from {
|
|
417
|
-
mask-size: 0 100%;
|
|
418
|
-
}
|
|
419
|
-
to {
|
|
420
|
-
mask-size: 100% 100%;
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
|
|
424
394
|
:host([vertical-align="center"]) {
|
|
425
395
|
align-self: center;
|
|
426
396
|
}
|
|
@@ -72,3 +72,57 @@ zn-panel:not(.content-block--short) zn-header::part(header-description) {
|
|
|
72
72
|
.hidden {
|
|
73
73
|
display: none;
|
|
74
74
|
}
|
|
75
|
+
|
|
76
|
+
li[data-list="ordered"] {
|
|
77
|
+
counter-increment: list-0 1;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
@supports (counter-set:none) {
|
|
81
|
+
li[data-list] {
|
|
82
|
+
counter-set: list-1 0 list-2 0 list-3 0 list-4 0 list-5 0 list-6 0 list-7 0 list-8 0 list-9 0;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
li[data-list=bullet] > .ql-ui:before {
|
|
87
|
+
content: "•";
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
li[data-list=checked] > .ql-ui:before {
|
|
91
|
+
content: "☑";
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
li[data-list=unchecked] > .ql-ui:before {
|
|
95
|
+
content: "☐";
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
li[data-list="ordered"] > .ql-ui::before {
|
|
99
|
+
content: counter(list-0) ". ";
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
ol {
|
|
103
|
+
padding: 0;
|
|
104
|
+
margin: 0;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
li[data-list=checked] > .ql-ui, li[data-list=unchecked] > .ql-ui {
|
|
108
|
+
color: #777;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.ql-ui {
|
|
112
|
+
position: absolute;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
li {
|
|
116
|
+
list-style-type: none;
|
|
117
|
+
padding-left: 1em;
|
|
118
|
+
position: relative;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
li > .ql-ui::before {
|
|
122
|
+
display: inline-block;
|
|
123
|
+
margin-left: -1.5em;
|
|
124
|
+
margin-right: 0.3em;
|
|
125
|
+
text-align: right;
|
|
126
|
+
white-space: nowrap;
|
|
127
|
+
width: 1.2em;
|
|
128
|
+
}
|
|
@@ -90,6 +90,8 @@ interface HeaderConfig {
|
|
|
90
90
|
default?: boolean;
|
|
91
91
|
sortable?: boolean;
|
|
92
92
|
filterable?: boolean;
|
|
93
|
+
hideHeader?: boolean;
|
|
94
|
+
hideColumn?: boolean;
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
interface DataRequest {
|
|
@@ -427,6 +429,13 @@ export default class ZnDataTable extends ZincElement {
|
|
|
427
429
|
}
|
|
428
430
|
});
|
|
429
431
|
|
|
432
|
+
// remove empty groups
|
|
433
|
+
Object.keys(groupedRows).forEach((groupKey) => {
|
|
434
|
+
if (groupedRows[groupKey].length === 0) {
|
|
435
|
+
delete groupedRows[groupKey];
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
|
|
430
439
|
// render a table for each group
|
|
431
440
|
return html`
|
|
432
441
|
<zn-sp flush>
|
|
@@ -449,7 +458,10 @@ export default class ZnDataTable extends ZincElement {
|
|
|
449
458
|
}
|
|
450
459
|
|
|
451
460
|
public renderTableData(data: any) {
|
|
452
|
-
const filteredHeaders = Object.values(this.headers).filter((header) => {
|
|
461
|
+
const filteredHeaders = Object.values(this.headers).filter((header: HeaderConfig) => {
|
|
462
|
+
if (header.hideHeader || header.hideColumn) {
|
|
463
|
+
return false;
|
|
464
|
+
}
|
|
453
465
|
return !Object.values(this.hiddenColumns).includes(header.key);
|
|
454
466
|
});
|
|
455
467
|
|
|
@@ -608,7 +620,7 @@ export default class ZnDataTable extends ZincElement {
|
|
|
608
620
|
|| this.hasSlotController.test(ActionSlots.modify.valueOf())
|
|
609
621
|
|| this.hasSlotController.test(ActionSlots.create.valueOf());
|
|
610
622
|
|
|
611
|
-
if(!hasSlots) {
|
|
623
|
+
if (!hasSlots) {
|
|
612
624
|
return [];
|
|
613
625
|
}
|
|
614
626
|
|
|
@@ -909,6 +921,13 @@ export default class ZnDataTable extends ZincElement {
|
|
|
909
921
|
}
|
|
910
922
|
|
|
911
923
|
private renderCellBody(index: number, value: Cell) {
|
|
924
|
+
const filteredHeaders = Object.values(this.headers).filter((header: HeaderConfig) => {
|
|
925
|
+
if (header.hideHeader || header.hideColumn) {
|
|
926
|
+
return false;
|
|
927
|
+
}
|
|
928
|
+
return !Object.values(this.hiddenColumns).includes(header.key);
|
|
929
|
+
});
|
|
930
|
+
|
|
912
931
|
const headerKeys: string[] = Object.keys(this.headers).filter(
|
|
913
932
|
(key) => !Object.values(this.hiddenColumns).includes(key)
|
|
914
933
|
);
|
|
@@ -920,7 +939,7 @@ export default class ZnDataTable extends ZincElement {
|
|
|
920
939
|
class="${classMap({
|
|
921
940
|
'table__cell': true,
|
|
922
941
|
'table__cell--wide': headerKey === this.wideColumn,
|
|
923
|
-
'table__cell--last':
|
|
942
|
+
'table__cell--last': index === filteredHeaders.length - 1,
|
|
924
943
|
})}">
|
|
925
944
|
<div>${this.renderCell(value)}</div>
|
|
926
945
|
</td>`;
|
|
@@ -31,6 +31,7 @@ export default class ZnPanel extends ZincElement {
|
|
|
31
31
|
@property() icon: string;
|
|
32
32
|
@property() description: string;
|
|
33
33
|
@property({type: Boolean}) tabbed: boolean;
|
|
34
|
+
@property({attribute: 'header-underline', type: Boolean}) underlineHeader: boolean;
|
|
34
35
|
@property({type: Boolean}) cosmic: boolean;
|
|
35
36
|
@property({type: Boolean}) flush: boolean;
|
|
36
37
|
@property({attribute: 'flush-x', type: Boolean}) flushX: boolean;
|
|
@@ -94,7 +95,10 @@ export default class ZnPanel extends ZincElement {
|
|
|
94
95
|
|
|
95
96
|
<div class="panel__inner">
|
|
96
97
|
${hasHeader ? html`
|
|
97
|
-
<zn-header class="
|
|
98
|
+
<zn-header class="${classMap({
|
|
99
|
+
"panel__header": true,
|
|
100
|
+
"panel__header--underline": this.underlineHeader,
|
|
101
|
+
})}"
|
|
98
102
|
icon="${this.icon}"
|
|
99
103
|
caption="${this.caption}"
|
|
100
104
|
description="${ifDefined(this.description)}"
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {classMap} from "lit/directives/class-map.js";
|
|
2
2
|
import {type CSSResultGroup, html, unsafeCSS} from 'lit';
|
|
3
|
+
import {deepQuerySelectorAll} from "../../utilities/query";
|
|
3
4
|
import {property, state} from "lit/decorators.js";
|
|
4
5
|
import {Store} from "../../internal/storage";
|
|
5
6
|
import {type ZnChangeEvent} from "../../events/zn-change";
|
|
@@ -7,7 +8,6 @@ import ZincElement from '../../internal/zinc-element';
|
|
|
7
8
|
import type ZnCheckbox from "../checkbox";
|
|
8
9
|
|
|
9
10
|
import styles from './settings-container.scss';
|
|
10
|
-
import {deepQuerySelectorAll} from "../../utilities/query";
|
|
11
11
|
|
|
12
12
|
interface SettingsContainerFilter {
|
|
13
13
|
attribute: string;
|
|
@@ -295,7 +295,6 @@ export default class ZnTabs extends ZincElement {
|
|
|
295
295
|
let hasActive = false;
|
|
296
296
|
this._tabs.forEach(tab => {
|
|
297
297
|
|
|
298
|
-
|
|
299
298
|
if (tab.hasAttribute('tab-uri') && this._knownUri.has(tab.getAttribute('tab-uri')!)) {
|
|
300
299
|
tab.setAttribute('tab', this._knownUri.get(tab.getAttribute('tab-uri')!)!);
|
|
301
300
|
}
|
|
@@ -407,19 +406,38 @@ export default class ZnTabs extends ZincElement {
|
|
|
407
406
|
}
|
|
408
407
|
|
|
409
408
|
removeTabAndPanel(tabId: string) {
|
|
410
|
-
if (this.
|
|
411
|
-
this.
|
|
409
|
+
if (this._current === tabId) {
|
|
410
|
+
this.setActiveTab('', true, false);
|
|
412
411
|
}
|
|
413
412
|
|
|
414
413
|
for (const tab of this._tabs) {
|
|
415
414
|
if (tab.getAttribute('tab') === tabId) {
|
|
416
|
-
|
|
415
|
+
|
|
416
|
+
if (tab.hasAttribute('tab-uri')) {
|
|
417
|
+
const tabUri = tab.getAttribute('tab-uri')!;
|
|
418
|
+
if (this._knownUri.has(tabUri)) {
|
|
419
|
+
this._knownUri.delete(tabUri);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
//tab.remove();
|
|
424
|
+
tab.parentElement?.removeChild(tab)
|
|
417
425
|
this._tabs.splice(this._tabs.indexOf(tab), 1);
|
|
418
426
|
}
|
|
419
427
|
}
|
|
420
428
|
|
|
421
|
-
if (this.
|
|
422
|
-
this.
|
|
429
|
+
if (this._panels.has(tabId)) {
|
|
430
|
+
const panel = this._panels.get(tabId);
|
|
431
|
+
if (panel instanceof HTMLElement) {
|
|
432
|
+
panel.remove();
|
|
433
|
+
} else if (panel instanceof Array) {
|
|
434
|
+
panel.forEach((item) => {
|
|
435
|
+
if (item instanceof HTMLElement) {
|
|
436
|
+
item.remove();
|
|
437
|
+
}
|
|
438
|
+
})
|
|
439
|
+
}
|
|
440
|
+
this._panels.delete(tabId);
|
|
423
441
|
}
|
|
424
442
|
}
|
|
425
443
|
|
package/src/internal/form.ts
CHANGED
|
@@ -235,12 +235,50 @@ export class FormControlController implements ReactiveController {
|
|
|
235
235
|
name.length > 0 &&
|
|
236
236
|
typeof value !== 'undefined'
|
|
237
237
|
) {
|
|
238
|
-
|
|
238
|
+
const appendPrimitive = (val: string | number | boolean) => {
|
|
239
|
+
event.formData.append(name, val.toString());
|
|
240
|
+
};
|
|
241
|
+
const appendFile = (file: Blob, filename?: string) => {
|
|
242
|
+
// If a filename is provided or it's a File (has name), FormData will use it properly
|
|
243
|
+
const maybeFile = file as unknown as File;
|
|
244
|
+
const fname = filename ?? (typeof maybeFile.name === 'string' ? maybeFile.name : undefined);
|
|
245
|
+
// Overloads: append(name, blob, filename?)
|
|
246
|
+
if (typeof fname === 'string') {
|
|
247
|
+
event.formData.append(name, file, fname);
|
|
248
|
+
} else {
|
|
249
|
+
event.formData.append(name, file);
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
const isFileList = (val: unknown): val is FileList => typeof FileList !== 'undefined' && val instanceof FileList;
|
|
254
|
+
const isBlob = (val: unknown): val is Blob => typeof Blob !== 'undefined' && val instanceof Blob;
|
|
255
|
+
|
|
256
|
+
if (isFileList(value)) {
|
|
257
|
+
// Match native input[type=file] behavior: append each File; if empty, append nothing
|
|
258
|
+
if (value.length > 0) {
|
|
259
|
+
for (let i = 0; i < value.length; i++) {
|
|
260
|
+
const f = value.item(i);
|
|
261
|
+
if (f) appendFile(f, f.name);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
} else if (isBlob(value)) {
|
|
265
|
+
appendFile(value, (value as unknown as File).name);
|
|
266
|
+
} else if (Array.isArray(value)) {
|
|
239
267
|
(value as unknown[]).forEach(val => {
|
|
240
|
-
|
|
268
|
+
if (isBlob(val)) {
|
|
269
|
+
appendFile(val as Blob, (val as unknown as File).name);
|
|
270
|
+
} else if (isFileList(val)) {
|
|
271
|
+
const fl = val as FileList;
|
|
272
|
+
for (let i = 0; i < fl.length; i++) {
|
|
273
|
+
const f = fl.item(i);
|
|
274
|
+
if (f) appendFile(f, f.name);
|
|
275
|
+
}
|
|
276
|
+
} else {
|
|
277
|
+
appendPrimitive(val as string | number | boolean);
|
|
278
|
+
}
|
|
241
279
|
});
|
|
242
280
|
} else {
|
|
243
|
-
|
|
281
|
+
appendPrimitive(value as string | number | boolean);
|
|
244
282
|
}
|
|
245
283
|
|
|
246
284
|
this.host.dispatchEvent(new CustomEvent('zn-formdata', {bubbles: true, composed: true}));
|