@kubex/zinc 1.0.4 → 1.0.6
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 +1278 -191
- package/dist/vscode.html-custom-data.json +93 -16
- package/dist/web-types.json +235 -25
- package/dist/zn.d.ts +1313 -941
- package/dist/zn.min.css +1 -1
- package/dist/zn.min.js +2049 -931
- package/docs/_includes/default.njk +1 -0
- package/docs/assets/scripts/docs.js +4 -5
- package/docs/assets/scripts/search.js +0 -9
- package/docs/assets/styles/docs.css +3 -3
- package/docs/data/data-table.json +79 -0
- package/docs/data/products-table.json +36 -0
- package/docs/eleventy.config.cjs +3 -0
- package/docs/pages/components/data-select.md +10 -0
- package/docs/pages/components/data-table.md +84 -45
- package/docs/pages/components/dialog.md +1 -1
- package/docs/pages/components/editor.md +1 -3
- package/docs/pages/components/filter-wrapper.md +20 -0
- package/docs/pages/components/icon.md +2 -0
- package/docs/pages/components/item.md +2 -2
- package/docs/pages/components/menu-item.md +12 -3
- package/docs/pages/components/panel.md +17 -0
- package/docs/pages/components/progress-tile.md +17 -1
- package/docs/pages/components/settings-container.md +137 -0
- package/docs/pages/components/textarea.md +1 -1
- package/package.json +3 -1
- package/scss/_root.scss +26 -0
- package/scss/boot.scss +27 -1
- package/scss/mixins/index.scss +30 -1
- package/scss/shared/_base.scss +1 -1
- package/scss/shared/_button.scss +1 -1
- package/scss/shared/layout.scss +7 -0
- package/scss/themes/_dark.scss +5 -5
- package/scss/themes/_light.scss +6 -5
- package/scss/variables/index.scss +9 -0
- package/src/components/alert/alert.component.ts +1 -1
- package/src/components/alert/alert.scss +18 -4
- package/src/components/bulk-actions/bulk-actions.component.ts +152 -84
- package/src/components/bulk-actions/bulk-actions.scss +2 -0
- package/src/components/button/button.component.ts +6 -2
- package/src/components/button/button.scss +16 -1
- package/src/components/button-menu/button-menu.component.ts +23 -15
- package/src/components/button-menu/button-menu.scss +4 -4
- package/src/components/chart/chart.component.ts +14 -12
- package/src/components/checkbox/checkbox.component.ts +5 -1
- package/src/components/checkbox/checkbox.scss +1 -1
- package/src/components/chip/chip.component.ts +7 -3
- package/src/components/chip/chip.scss +9 -1
- package/src/components/collapsible/collapsible.component.ts +48 -2
- package/src/components/cols/cols.component.ts +7 -3
- package/src/components/cols/cols.scss +22 -14
- package/src/components/confirm/confirm.component.ts +1 -2
- package/src/components/content-block/content-block.component.ts +104 -14
- package/src/components/content-block/content-block.scss +8 -0
- package/src/components/data-select/data-select.component.ts +1 -1
- package/src/components/data-table/data-table.component.ts +394 -430
- package/src/components/data-table/data-table.scss +6 -1
- package/src/components/datepicker/datepicker.scss +1 -1
- package/src/components/dialog/dialog.component.ts +52 -33
- package/src/components/dialog/dialog.scss +15 -1
- package/src/components/dropdown/dropdown.component.ts +1 -1
- package/src/components/editor/editor.component.ts +196 -158
- package/src/components/editor/editor.scss +25 -5
- package/src/components/editor/modules/ai/index.ts +281 -0
- package/src/components/editor/modules/ai/panel/ai-panel.component.ts +102 -0
- package/src/components/editor/modules/ai/panel/ai-panel.scss +83 -0
- package/src/components/editor/modules/ai/tooltip/ai-tooltip.component.ts +30 -0
- package/src/components/editor/modules/ai/tooltip/ai-tooltip.scss +28 -0
- package/src/components/editor/modules/{attachment-module.ts → attachment/attachment.ts} +7 -7
- package/src/components/editor/modules/context-menu/context-menu-component.ts +115 -0
- package/src/components/editor/modules/context-menu/context-menu.scss +49 -0
- package/src/components/editor/modules/context-menu/context-menu.ts +296 -0
- package/src/components/editor/modules/context-menu/quick-action/index.ts +12 -0
- package/src/components/editor/modules/context-menu/quick-action/quick-action.component.ts +18 -0
- package/src/components/editor/modules/date-picker/date-picker.ts +77 -0
- package/src/components/editor/modules/dialog/dialog.component.ts +115 -0
- package/src/components/editor/modules/dialog/dialog.scss +43 -0
- package/src/components/editor/modules/dialog/dialog.ts +46 -0
- package/src/components/editor/modules/{drag-drop-module.ts → drag-drop/drag-drop.ts} +6 -6
- package/src/components/editor/modules/emoji/emoji.ts +106 -0
- package/src/components/editor/modules/emoji/headless/headless-emoji.component.ts +122 -0
- package/src/components/editor/modules/emoji/headless/headless-emoji.scss +52 -0
- package/src/components/editor/modules/emoji/headless/headless-emoji.ts +223 -0
- package/src/components/editor/modules/{image-resize-module/image-resize-module.ts → image-resize/image-resize.ts} +5 -5
- package/src/components/editor/modules/{time-tracking-module.ts → time-tracking/time-tracking.ts} +5 -5
- package/src/components/editor/modules/toolbar/tool/index.ts +12 -0
- package/src/components/editor/modules/toolbar/tool/tool.component.ts +30 -0
- package/src/components/editor/modules/toolbar/tool/tool.scss +5 -0
- package/src/components/editor/modules/toolbar/toolbar.component.ts +738 -0
- package/src/components/editor/modules/toolbar/toolbar.scss +98 -0
- package/src/components/editor/modules/toolbar/toolbar.ts +328 -0
- package/src/components/expanding-action/expanding-action.component.ts +2 -2
- package/src/components/expanding-action/expanding-action.scss +2 -2
- package/src/components/filter-wrapper/filter-wrapper.component.ts +91 -0
- package/src/components/filter-wrapper/filter-wrapper.scss +11 -0
- package/src/components/filter-wrapper/filter-wrapper.test.ts +10 -0
- package/src/components/filter-wrapper/index.ts +12 -0
- package/src/components/header/header.component.ts +1 -1
- package/src/components/header/header.scss +8 -1
- package/src/components/hover-container/hover-container.scss +39 -36
- package/src/components/icon/icon.component.ts +11 -5
- package/src/components/icon/icon.scss +15 -2
- package/src/components/inline-edit/inline-edit.component.ts +52 -6
- package/src/components/inline-edit/inline-edit.scss +15 -2
- package/src/components/input/input.scss +1 -1
- package/src/components/item/item.component.ts +30 -19
- package/src/components/item/item.scss +57 -23
- package/src/components/linked-select/linked-select.component.ts +5 -1
- package/src/components/menu/menu.component.ts +1 -0
- package/src/components/menu/menu.scss +1 -1
- package/src/components/menu-item/menu-item.component.ts +22 -4
- package/src/components/menu-item/menu-item.scss +54 -7
- package/src/components/navbar/navbar.component.ts +7 -1
- package/src/components/navbar/navbar.scss +26 -16
- package/src/components/option/option.component.ts +4 -1
- package/src/components/option/option.scss +9 -0
- package/src/components/page-nav/page-nav.component.ts +2 -2
- package/src/components/page-nav/page-nav.scss +4 -4
- package/src/components/panel/panel.component.ts +20 -9
- package/src/components/panel/panel.scss +5 -1
- package/src/components/popup/popup.component.ts +16 -2
- package/src/components/progress-tile/progress-tile.component.ts +10 -4
- package/src/components/progress-tile/progress-tile.scss +7 -4
- package/src/components/query-builder/query-builder.component.ts +1 -1
- package/src/components/radio/radio.scss +1 -1
- package/src/components/scroll-container/scroll-container.component.ts +56 -9
- package/src/components/scroll-container/scroll-container.scss +37 -2
- package/src/components/select/select.component.ts +3 -0
- package/src/components/select/select.scss +1 -1
- package/src/components/settings-container/index.ts +12 -0
- package/src/components/settings-container/settings-container.component.ts +226 -0
- package/src/components/settings-container/settings-container.scss +99 -0
- package/src/components/settings-container/settings-container.test.ts +10 -0
- package/src/components/skeleton/skeleton.scss +5 -4
- package/src/components/sp/sp.component.ts +2 -0
- package/src/components/sp/sp.scss +2 -0
- package/src/components/split-button/split-button.component.ts +24 -18
- package/src/components/split-pane/split-pane.component.ts +5 -5
- package/src/components/stat/stat.component.ts +5 -1
- package/src/components/stat/stat.scss +24 -1
- package/src/components/style/style.component.ts +25 -1
- package/src/components/tabs/tabs.component.ts +12 -1
- package/src/components/textarea/textarea.component.ts +3 -1
- package/src/components/textarea/textarea.scss +21 -2
- package/src/components/vertical-stepper/vertical-stepper.scss +1 -1
- package/src/internal/form.ts +3 -1
- package/src/internal/slot.ts +29 -3
- package/src/utilities/on.ts +7 -8
- package/src/utilities/query.ts +5 -1
- package/src/wc.scss +7 -0
- package/src/zinc.ts +5 -0
- package/src/components/editor/modules/dialog-module/dialog-module.component.ts +0 -289
- package/src/components/editor/modules/dialog-module/dialog-module.scss +0 -115
- package/src/components/editor/modules/dialog-module/dialog-module.ts +0 -99
- package/src/components/editor/modules/events/zn-show-canned-response-dialog.ts +0 -15
- package/src/components/editor/modules/menu-module/menu-module.component.ts +0 -149
- package/src/components/editor/modules/menu-module/menu-module.scss +0 -17
- package/src/components/editor/modules/menu-module/menu-module.ts +0 -203
|
@@ -32,6 +32,7 @@ export default class ZnStatsTile extends ZincElement {
|
|
|
32
32
|
@property() previous = '0';
|
|
33
33
|
@property() currency = '';
|
|
34
34
|
@property({type: Boolean, attribute: 'show-delta'}) showDelta = false;
|
|
35
|
+
@property() color: 'primary' | 'error' | 'info' | 'warning' | 'success' | 'neutral' = 'primary';
|
|
35
36
|
|
|
36
37
|
calcPercentageDifference() {
|
|
37
38
|
const previous = parseFloat(this.previous);
|
|
@@ -100,7 +101,10 @@ export default class ZnStatsTile extends ZincElement {
|
|
|
100
101
|
|
|
101
102
|
render() {
|
|
102
103
|
return html`
|
|
103
|
-
<div class="${classMap({
|
|
104
|
+
<div class="${classMap({
|
|
105
|
+
'stat-tile': true,
|
|
106
|
+
[`stat-tile--${this.color}`]: true
|
|
107
|
+
})}">
|
|
104
108
|
<div class="container">
|
|
105
109
|
<div class="left">
|
|
106
110
|
<div>
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
.caption {
|
|
15
|
-
color: rgb(var(--zn-primary));
|
|
16
15
|
margin-bottom: var(--zn-spacing-x-small);
|
|
17
16
|
font-size: var(--zn-font-size-medium);
|
|
18
17
|
}
|
|
@@ -79,6 +78,30 @@
|
|
|
79
78
|
}
|
|
80
79
|
}
|
|
81
80
|
|
|
81
|
+
&--primary {
|
|
82
|
+
color: rgb(var(--zn-primary));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
&--error {
|
|
86
|
+
color: rgb(var(--zn-color-error));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
&--info {
|
|
90
|
+
color: rgb(var(--zn-color-info));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
&--warning {
|
|
94
|
+
color: rgb(var(--zn-color-warning));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
&--success {
|
|
98
|
+
color: rgb(var(--zn-color-success));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
&--neutral {
|
|
102
|
+
color: rgb(var(--zn-text));
|
|
103
|
+
}
|
|
104
|
+
|
|
82
105
|
@container (max-width:550px) {
|
|
83
106
|
::slotted(.zn-col-1) {
|
|
84
107
|
flex-basis: 170px;
|
|
@@ -19,6 +19,10 @@ export default class ZnStyle extends ZincElement {
|
|
|
19
19
|
@property({type: Boolean}) warning = false;
|
|
20
20
|
@property({type: Boolean}) primary = false;
|
|
21
21
|
@property({type: Boolean}) accent = false;
|
|
22
|
+
@property({type: Boolean}) center = false;
|
|
23
|
+
@property() font = '';
|
|
24
|
+
@property() width = '';
|
|
25
|
+
@property() height = '';
|
|
22
26
|
@property() pad = '';
|
|
23
27
|
@property() margin = '';
|
|
24
28
|
@property({attribute: 'a-margin'}) autoMargin = '';
|
|
@@ -47,6 +51,27 @@ export default class ZnStyle extends ZincElement {
|
|
|
47
51
|
this.classList.toggle('zn-' + this.color, true);
|
|
48
52
|
}
|
|
49
53
|
|
|
54
|
+
|
|
55
|
+
if (this.center) {
|
|
56
|
+
display = "flex"
|
|
57
|
+
this.classList.toggle('flex-mid', true);
|
|
58
|
+
this.classList.toggle('flex-jc', true);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (this.font) {
|
|
62
|
+
if (this.font === 'mono') {
|
|
63
|
+
this.classList.toggle('zn-mono', true);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (this.width === "f") {
|
|
68
|
+
this.classList.toggle('w-full', true);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (this.height === "f") {
|
|
72
|
+
this.classList.toggle('h-full', true);
|
|
73
|
+
}
|
|
74
|
+
|
|
50
75
|
if (this.border) {
|
|
51
76
|
display = 'inline-block'
|
|
52
77
|
this.classList.toggle('zn-border', true);
|
|
@@ -140,7 +165,6 @@ export default class ZnStyle extends ZincElement {
|
|
|
140
165
|
}
|
|
141
166
|
}
|
|
142
167
|
|
|
143
|
-
|
|
144
168
|
this.style.display = display;
|
|
145
169
|
}
|
|
146
170
|
|
|
@@ -54,6 +54,7 @@ export default class ZnTabs extends ZincElement {
|
|
|
54
54
|
protected _activeClicks = 0;
|
|
55
55
|
private _panel: Element | null | undefined;
|
|
56
56
|
private _panels: Map<string, Element[]>;
|
|
57
|
+
private _activeTab: Element | null = null;
|
|
57
58
|
private _tabs: HTMLElement[] = [];
|
|
58
59
|
private _actions: HTMLElement[] = [];
|
|
59
60
|
private _knownUri: Map<string, string> = new Map<string, string>();
|
|
@@ -261,6 +262,7 @@ export default class ZnTabs extends ZincElement {
|
|
|
261
262
|
if (!target.hasAttribute('tab') && target.hasAttribute('tab-uri')) {
|
|
262
263
|
const tabUri: string | null = target.getAttribute("tab-uri") ?? "";
|
|
263
264
|
this._createUriPanel(target, tabUri, this._uriToId(tabUri));
|
|
265
|
+
target.setAttribute('tab-id', this._uriToId(tabUri));
|
|
264
266
|
}
|
|
265
267
|
}
|
|
266
268
|
|
|
@@ -320,6 +322,9 @@ export default class ZnTabs extends ZincElement {
|
|
|
320
322
|
}
|
|
321
323
|
|
|
322
324
|
_setTabEleActive(ele: Element, active: boolean) {
|
|
325
|
+
if (active) {
|
|
326
|
+
this._activeTab = ele
|
|
327
|
+
}
|
|
323
328
|
ele.classList.toggle('zn-tb-active', active);
|
|
324
329
|
ele.classList.toggle('active', active);
|
|
325
330
|
}
|
|
@@ -349,8 +354,14 @@ export default class ZnTabs extends ZincElement {
|
|
|
349
354
|
}
|
|
350
355
|
element.toggleAttribute('selected', isActive);
|
|
351
356
|
if (isActive && refresh) {
|
|
357
|
+
let uri = "";
|
|
358
|
+
let gaid = "";
|
|
359
|
+
if (this._activeTab && this._activeTab.hasAttribute('tab-uri')) {
|
|
360
|
+
uri = this._activeTab.getAttribute('tab-uri')!;
|
|
361
|
+
gaid = this._activeTab.getAttribute('gaid')!;
|
|
362
|
+
}
|
|
352
363
|
document.dispatchEvent(new CustomEvent('zn-refresh-element', {
|
|
353
|
-
detail: {element: element}
|
|
364
|
+
detail: {element: element, uri: uri, gaid: gaid}
|
|
354
365
|
}));
|
|
355
366
|
}
|
|
356
367
|
});
|
|
@@ -141,6 +141,7 @@ export default class ZnTextarea extends ZincElement implements ZincFormControl {
|
|
|
141
141
|
/** The default value of the form control. Primarily used for resetting the form control. */
|
|
142
142
|
@defaultValue() defaultValue = '';
|
|
143
143
|
|
|
144
|
+
@property({type: Boolean}) transparent = false;
|
|
144
145
|
|
|
145
146
|
/** Gets the validity state object */
|
|
146
147
|
get validity() {
|
|
@@ -373,7 +374,8 @@ export default class ZnTextarea extends ZincElement implements ZincFormControl {
|
|
|
373
374
|
'textarea--empty': !this.value,
|
|
374
375
|
'textarea--resize-none': this.resize === 'none',
|
|
375
376
|
'textarea--resize-vertical': this.resize === 'vertical',
|
|
376
|
-
'textarea--resize-auto': this.resize === 'auto'
|
|
377
|
+
'textarea--resize-auto': this.resize === 'auto',
|
|
378
|
+
'textarea--transparent': this.transparent
|
|
377
379
|
})}>
|
|
378
380
|
<textarea
|
|
379
381
|
part="textarea"
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
align-items: center;
|
|
17
17
|
position: relative;
|
|
18
18
|
width: 100%;
|
|
19
|
-
box-shadow: var(--zn-shadow-
|
|
19
|
+
box-shadow: var(--zn-shadow-x-small);
|
|
20
20
|
font-family: var(--zn-input-font-family);
|
|
21
21
|
font-weight: var(--zn-input-font-weight);
|
|
22
22
|
line-height: var(--zn-line-height-normal);
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
color: var(--zn-input-color);
|
|
80
80
|
border: none;
|
|
81
81
|
background: none;
|
|
82
|
-
box-shadow: var(--zn-shadow-small);
|
|
82
|
+
box-shadow: var(--zn-shadow-x-small);
|
|
83
83
|
cursor: inherit;
|
|
84
84
|
-webkit-appearance: none;
|
|
85
85
|
height: 100%;
|
|
@@ -150,3 +150,22 @@
|
|
|
150
150
|
resize: none;
|
|
151
151
|
overflow-y: hidden;
|
|
152
152
|
}
|
|
153
|
+
|
|
154
|
+
.form-control-input {
|
|
155
|
+
margin: 0 !important;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.textarea--transparent {
|
|
159
|
+
background-color: transparent;
|
|
160
|
+
box-shadow: none !important;
|
|
161
|
+
border: none !important;
|
|
162
|
+
|
|
163
|
+
&:hover {
|
|
164
|
+
background-color: transparent !important;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
&.textarea--focused {
|
|
168
|
+
border: none !important;
|
|
169
|
+
background-color: transparent !important;
|
|
170
|
+
}
|
|
171
|
+
}
|
package/src/internal/form.ts
CHANGED
|
@@ -267,7 +267,9 @@ export class FormControlController implements ReactiveController {
|
|
|
267
267
|
setTimeout(() => {
|
|
268
268
|
// disable duplicate submit
|
|
269
269
|
submitButton.disabled = true;
|
|
270
|
-
submitButton.innerHTML = this.form?.
|
|
270
|
+
submitButton.innerHTML = !this.form?.hasAttribute('data-no-loading-text')
|
|
271
|
+
? this.form?.getAttribute('data-loading-text') || 'Processing...'
|
|
272
|
+
: content;
|
|
271
273
|
}, 20);
|
|
272
274
|
}
|
|
273
275
|
|
package/src/internal/slot.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {ReactiveController, ReactiveControllerHost} from 'lit';
|
|
2
2
|
|
|
3
3
|
/** A reactive controller that determines when slots exist. */
|
|
4
4
|
export class HasSlotController implements ReactiveController {
|
|
@@ -55,6 +55,32 @@ export class HasSlotController implements ReactiveController {
|
|
|
55
55
|
return this.host.querySelector(`:scope > [slot="${slotName}"]`)!;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
getDefaultSlot() {
|
|
59
|
+
// Get all child nodes that do not have a slot attribute
|
|
60
|
+
return [...this.host.childNodes].filter(node => {
|
|
61
|
+
if (node.nodeType === node.TEXT_NODE && node.textContent!.trim() !== '') {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (node.nodeType === node.ELEMENT_NODE) {
|
|
66
|
+
const el = node as HTMLElement;
|
|
67
|
+
const tagName = el.tagName.toLowerCase();
|
|
68
|
+
|
|
69
|
+
// Ignore visually hidden elements since they aren't rendered
|
|
70
|
+
if (tagName === 'zn-visually-hidden') {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// If it doesn't have a slot attribute, it's part of the default slot
|
|
75
|
+
if (!el.hasAttribute('slot')) {
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return false;
|
|
81
|
+
}) as HTMLElement[];
|
|
82
|
+
}
|
|
83
|
+
|
|
58
84
|
getSlots(slotName: string) {
|
|
59
85
|
return this.host.querySelectorAll(`:scope > [slot="${slotName}"]`) as NodeListOf<HTMLElement>;
|
|
60
86
|
}
|
|
@@ -73,7 +99,7 @@ export class HasSlotController implements ReactiveController {
|
|
|
73
99
|
* HTML as a string. This is useful because we can't use slot.innerHTML as an alternative.
|
|
74
100
|
*/
|
|
75
101
|
export function getInnerHTML(slot: HTMLSlotElement): string {
|
|
76
|
-
const nodes = slot.assignedNodes({
|
|
102
|
+
const nodes = slot.assignedNodes({flatten: true});
|
|
77
103
|
let html = '';
|
|
78
104
|
|
|
79
105
|
[...nodes].forEach(node => {
|
|
@@ -97,7 +123,7 @@ export function getTextContent(slot: HTMLSlotElement | undefined | null): string
|
|
|
97
123
|
if (!slot) {
|
|
98
124
|
return '';
|
|
99
125
|
}
|
|
100
|
-
const nodes = slot.assignedNodes({
|
|
126
|
+
const nodes = slot.assignedNodes({flatten: true});
|
|
101
127
|
let text = '';
|
|
102
128
|
|
|
103
129
|
[...nodes].forEach(node => {
|
package/src/utilities/on.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
type OnEvent = Event & { selectedTarget: EventTarget; path: EventTarget[] };
|
|
1
|
+
export type OnEvent = Event & { selectedTarget: EventTarget; path: EventTarget[] };
|
|
2
2
|
|
|
3
3
|
interface OnEventListener {
|
|
4
4
|
(evt: OnEvent): void;
|
|
@@ -6,20 +6,19 @@ interface OnEventListener {
|
|
|
6
6
|
|
|
7
7
|
export function on(delegate: EventTarget, eventName: string, targetSelector: string, callback: OnEventListener) {
|
|
8
8
|
function _fn(e: OnEvent) {
|
|
9
|
-
const path = e.path ||
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if (
|
|
13
|
-
e.selectedTarget =
|
|
9
|
+
const path = e.composedPath?.() || e.path || [e.target];
|
|
10
|
+
|
|
11
|
+
for (const node of path) {
|
|
12
|
+
if (node instanceof Element && node.matches(targetSelector)) {
|
|
13
|
+
e.selectedTarget = node;
|
|
14
14
|
return callback(e);
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
// stop traversing up the dom once we reach the delegate
|
|
18
|
-
if (
|
|
18
|
+
if (node === delegate) {
|
|
19
19
|
break;
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
-
while ((t = t.parentElement));
|
|
23
22
|
|
|
24
23
|
return false;
|
|
25
24
|
}
|
package/src/utilities/query.ts
CHANGED
|
@@ -2,8 +2,12 @@ export function deepQuerySelectorAll(selector: string, element: Element, stopSel
|
|
|
2
2
|
const arr: Element[] = [];
|
|
3
3
|
|
|
4
4
|
const traverser = (node: Element, sub: boolean) => {
|
|
5
|
+
if (!node) {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
|
|
5
9
|
// 1. decline all nodes that are not elements
|
|
6
|
-
if (node.nodeType !== Node.ELEMENT_NODE || (sub && stopSelector && node.matches(stopSelector))) {
|
|
10
|
+
if ((node.nodeType !== Node.ELEMENT_NODE) || (sub && stopSelector && node.matches(stopSelector))) {
|
|
7
11
|
return;
|
|
8
12
|
}
|
|
9
13
|
|
package/src/wc.scss
CHANGED
package/src/zinc.ts
CHANGED
|
@@ -46,6 +46,9 @@ export {default as ProgressBar} from './components/progress-bar';
|
|
|
46
46
|
export {default as OrderTable} from './components/order-table';
|
|
47
47
|
export {default as BulkActions} from './components/bulk-actions';
|
|
48
48
|
export {default as Editor} from './components/editor';
|
|
49
|
+
export {default as EditorTool} from './components/editor/modules/toolbar/tool';
|
|
50
|
+
export {default as EditorQuickAction} from './components/editor/modules/context-menu/quick-action';
|
|
51
|
+
export {default as EditorDialog} from './components/editor/modules/dialog/dialog.component';
|
|
49
52
|
export {default as Toggle} from './components/toggle';
|
|
50
53
|
export {default as Input} from './components/input';
|
|
51
54
|
export {default as Select} from './components/select';
|
|
@@ -75,6 +78,8 @@ export {default as SplitButton} from './components/split-button';
|
|
|
75
78
|
export {default as Skeleton} from './components/skeleton';
|
|
76
79
|
export {default as Style} from './components/style';
|
|
77
80
|
export {default as ContentBlock} from './components/content-block';
|
|
81
|
+
export {default as FilterWrapper} from './components/filter-wrapper';
|
|
82
|
+
export { default as SettingsContainer } from './components/settings-container';
|
|
78
83
|
/* plop:component */
|
|
79
84
|
|
|
80
85
|
// Utilities
|
|
@@ -1,289 +0,0 @@
|
|
|
1
|
-
import {classMap} from "lit/directives/class-map.js";
|
|
2
|
-
import {type CSSResultGroup, html, nothing, type PropertyValues, type TemplateResult, unsafeCSS} from "lit";
|
|
3
|
-
import {property, query, state} from "lit/decorators.js";
|
|
4
|
-
import {repeat} from "lit/directives/repeat.js";
|
|
5
|
-
import {watch} from "../../../../internal/watch";
|
|
6
|
-
import ZincElement from "../../../../internal/zinc-element";
|
|
7
|
-
import type {CannedResponse} from "../../editor.component";
|
|
8
|
-
import type {ZnInputEvent} from "../../../../events/zn-input";
|
|
9
|
-
import type ZnInput from "../../../input";
|
|
10
|
-
|
|
11
|
-
import styles from './dialog-module.scss';
|
|
12
|
-
|
|
13
|
-
export default class DialogModuleComponent extends ZincElement {
|
|
14
|
-
static styles: CSSResultGroup = unsafeCSS(styles);
|
|
15
|
-
|
|
16
|
-
@state() private hasFocus = false;
|
|
17
|
-
@state() private isSearching = false;
|
|
18
|
-
|
|
19
|
-
@query('dialog') dialogEl!: HTMLDialogElement;
|
|
20
|
-
|
|
21
|
-
@query('zn-input#search-input') searchInput!: ZnInput;
|
|
22
|
-
@query('.dialog-module__content') commandList!: HTMLElement;
|
|
23
|
-
|
|
24
|
-
@query('.dialog-module') dialogModule!: HTMLElement;
|
|
25
|
-
|
|
26
|
-
@property({type: Array}) allCommands: CannedResponse[] = [];
|
|
27
|
-
@property({type: Array, reflect: true}) commands: CannedResponse[] = [];
|
|
28
|
-
@property({type: Boolean, reflect: true}) open = false;
|
|
29
|
-
|
|
30
|
-
private closeWatcher: CloseWatcher | null;
|
|
31
|
-
|
|
32
|
-
connectedCallback() {
|
|
33
|
-
super.connectedCallback();
|
|
34
|
-
this.addEventListener('keydown', this.handleKeyDown);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
disconnectedCallback() {
|
|
38
|
-
super.disconnectedCallback();
|
|
39
|
-
this.removeEventListener('keydown', this.handleKeyDown);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
protected firstUpdated(_changedProperties: PropertyValues) {
|
|
43
|
-
super.firstUpdated(_changedProperties);
|
|
44
|
-
|
|
45
|
-
this.dialogEl.addEventListener("close", () => {
|
|
46
|
-
this.open = false;
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
private handleKeyDown(event: KeyboardEvent) {
|
|
51
|
-
if (event.key === 'Enter') {
|
|
52
|
-
const item = this.getCurrentItem();
|
|
53
|
-
event.preventDefault();
|
|
54
|
-
event.stopPropagation();
|
|
55
|
-
|
|
56
|
-
// Simulate a click to support @click handlers on menu items that also work with the keyboard
|
|
57
|
-
item?.click();
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Move the selection when pressing down or up
|
|
61
|
-
else if (['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) {
|
|
62
|
-
const items = this.getAllItems();
|
|
63
|
-
const activeItem = this.getCurrentItem();
|
|
64
|
-
let index = activeItem ? items.indexOf(activeItem) : 0;
|
|
65
|
-
|
|
66
|
-
if (!activeItem) {
|
|
67
|
-
this.setCurrentItem(items[0]);
|
|
68
|
-
items[0].focus();
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if (items.length > 0) {
|
|
73
|
-
event.preventDefault();
|
|
74
|
-
event.stopPropagation();
|
|
75
|
-
|
|
76
|
-
if (event.key === 'ArrowDown') {
|
|
77
|
-
index++;
|
|
78
|
-
} else if (event.key === 'ArrowUp') {
|
|
79
|
-
index--;
|
|
80
|
-
} else if (event.key === 'Home') {
|
|
81
|
-
index = 0;
|
|
82
|
-
} else if (event.key === 'End') {
|
|
83
|
-
index = items.length - 1;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (index < 0) {
|
|
87
|
-
index = items.length - 1;
|
|
88
|
-
}
|
|
89
|
-
if (index > items.length - 1) {
|
|
90
|
-
index = 0;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
this.setCurrentItem(items[index]);
|
|
94
|
-
items[index].focus();
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
getAllItems() {
|
|
100
|
-
if (!this.commandList) {
|
|
101
|
-
return [];
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return [...this.commandList.children].filter((el: HTMLElement) => {
|
|
105
|
-
return el.getAttribute('data-command') !== null;
|
|
106
|
-
}) as HTMLElement[];
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
getCurrentItem() {
|
|
110
|
-
return this.getAllItems().find(i => i.getAttribute('tabindex') === '0');
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
setCurrentItem(item: HTMLElement) {
|
|
114
|
-
const items = this.getAllItems();
|
|
115
|
-
|
|
116
|
-
// Update tab indexes
|
|
117
|
-
items.forEach(i => {
|
|
118
|
-
i.setAttribute('tabindex', i === item ? '0' : '-1');
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
focus() {
|
|
123
|
-
this.searchInput.focus();
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
@watch('open', {waitUntilFirstUpdate: true})
|
|
127
|
-
handleOpenChange() {
|
|
128
|
-
if (this.open) {
|
|
129
|
-
this.addOpenListeners();
|
|
130
|
-
setTimeout(() => this.focus(), 0);
|
|
131
|
-
} else {
|
|
132
|
-
this.removeOpenListeners();
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
private addOpenListeners() {
|
|
137
|
-
if ('CloseWatcher' in window) {
|
|
138
|
-
this.closeWatcher?.destroy();
|
|
139
|
-
this.closeWatcher = new CloseWatcher();
|
|
140
|
-
this.closeWatcher.onclose = () => this.requestClose('keyboard');
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
private removeOpenListeners() {
|
|
145
|
-
this.closeWatcher?.destroy();
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
private requestClose(source: 'close-button' | 'keyboard' | 'overlay') {
|
|
149
|
-
const znRequestClose = this.emit('zn-request-close', {
|
|
150
|
-
cancelable: true,
|
|
151
|
-
detail: {source}
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
if (znRequestClose.defaultPrevented) {
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
this.dialogEl.close();
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
private handleClick = (event: MouseEvent) => {
|
|
162
|
-
const item = (event.target as HTMLElement).closest('.command__wrapper');
|
|
163
|
-
if (!item) return;
|
|
164
|
-
this.emit('zn-command-select', {detail: {item: item as HTMLElement}});
|
|
165
|
-
this.emit('zn-editor-update');
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
private _createCommand(command: CannedResponse): TemplateResult {
|
|
169
|
-
const labels: string[] = [];
|
|
170
|
-
if (command.labels) {
|
|
171
|
-
command.labels.forEach((label: string) => {
|
|
172
|
-
if (label.includes(',')) {
|
|
173
|
-
labels.push(...label.split(',').map((l: string) => l.trim()));
|
|
174
|
-
} else {
|
|
175
|
-
labels.push(label);
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
return html`
|
|
181
|
-
<div data-command="${command.title}" class="command__wrapper" @click="${this.handleClick}">
|
|
182
|
-
<div class="command__left">
|
|
183
|
-
<div class="command__command">
|
|
184
|
-
${'/' + (command.command ? command.command :
|
|
185
|
-
command.title.toLowerCase().replace(' ', '-'))}
|
|
186
|
-
</div>
|
|
187
|
-
<div class="command__labels">
|
|
188
|
-
${repeat(labels, (label: string) => html`
|
|
189
|
-
<zn-chip class="command__labels__label" size="small"># ${label}</zn-label>
|
|
190
|
-
`)}
|
|
191
|
-
</div>
|
|
192
|
-
</div>
|
|
193
|
-
<div class="command__right">
|
|
194
|
-
<div class="command__title">
|
|
195
|
-
${command.title}
|
|
196
|
-
</div>
|
|
197
|
-
<div class="command__snippet">
|
|
198
|
-
${command.content.length > 50 ? command.content.substring(0, 50) + '...' : command.content}
|
|
199
|
-
</div>
|
|
200
|
-
</div>
|
|
201
|
-
</div>`
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
private isFuzzyMatch(target: string, search: string): boolean {
|
|
205
|
-
let tIdx = 0;
|
|
206
|
-
let sIdx = 0;
|
|
207
|
-
target = target.toLowerCase();
|
|
208
|
-
search = search.toLowerCase();
|
|
209
|
-
while (tIdx < target.length && sIdx < search.length) {
|
|
210
|
-
if (target[tIdx] === search[sIdx]) sIdx++;
|
|
211
|
-
tIdx++;
|
|
212
|
-
}
|
|
213
|
-
return sIdx === search.length;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
handleSearch(event: ZnInputEvent) {
|
|
217
|
-
const target = event.target as HTMLInputElement | HTMLSelectElement;
|
|
218
|
-
const searchValue = target.value.trim().toLowerCase();
|
|
219
|
-
this.isSearching = !!searchValue;
|
|
220
|
-
if (!searchValue) {
|
|
221
|
-
this.commands = [...this.allCommands];
|
|
222
|
-
return;
|
|
223
|
-
}
|
|
224
|
-
this.commands = this.allCommands.filter(command =>
|
|
225
|
-
this.isFuzzyMatch(command.title, searchValue) ||
|
|
226
|
-
this.isFuzzyMatch(command.content, searchValue) ||
|
|
227
|
-
(command.labels && command.labels.some(label => this.isFuzzyMatch(label, searchValue)))
|
|
228
|
-
);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
render() {
|
|
232
|
-
const visibleCommands = this.isSearching
|
|
233
|
-
? this.commands
|
|
234
|
-
: this.commands.sort((a, b) => parseInt(b.count) - parseInt(a.count))
|
|
235
|
-
.slice(0, 5);
|
|
236
|
-
return html`
|
|
237
|
-
<dialog closedby="any"
|
|
238
|
-
open="${this.open || nothing}"
|
|
239
|
-
class="${classMap({
|
|
240
|
-
'dialog-module': true,
|
|
241
|
-
'dialog-module--has-focus': this.hasFocus,
|
|
242
|
-
'dialog-module--has-results': visibleCommands.length > 0,
|
|
243
|
-
})}">
|
|
244
|
-
|
|
245
|
-
<div class="dialog-module__header">
|
|
246
|
-
<div class="dialog-module__header--caption">
|
|
247
|
-
Canned Responses
|
|
248
|
-
</div>
|
|
249
|
-
|
|
250
|
-
<div class="dialog-module__header--search">
|
|
251
|
-
<zn-input id="search-input"
|
|
252
|
-
type="search"
|
|
253
|
-
placeholder="Search..."
|
|
254
|
-
class="search-input"
|
|
255
|
-
autocomplete="off"
|
|
256
|
-
autocorrect="off"
|
|
257
|
-
@zn-input="${this.handleSearch}">
|
|
258
|
-
<zn-icon src="search" slot="prefix"></zn-icon>
|
|
259
|
-
</zn-input>
|
|
260
|
-
</div>
|
|
261
|
-
</div>
|
|
262
|
-
|
|
263
|
-
<div class="dialog-module__body">
|
|
264
|
-
<div class="dialog-module__content">
|
|
265
|
-
${repeat(visibleCommands, (command: CannedResponse) => this._createCommand(command))}
|
|
266
|
-
</div>
|
|
267
|
-
|
|
268
|
-
<slot></slot>
|
|
269
|
-
</div>
|
|
270
|
-
|
|
271
|
-
<div class="dialog-module__footer">
|
|
272
|
-
<div>
|
|
273
|
-
Showing ${visibleCommands.length} of ${this.allCommands.length} responses
|
|
274
|
-
</div>
|
|
275
|
-
<zn-button class="dialog-module__close-button"
|
|
276
|
-
size="medium"
|
|
277
|
-
color="secondary"
|
|
278
|
-
@click="${() => this.requestClose('close-button')}">
|
|
279
|
-
Close
|
|
280
|
-
</zn-button>
|
|
281
|
-
</div>
|
|
282
|
-
|
|
283
|
-
</dialog>
|
|
284
|
-
`;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
DialogModuleComponent.define('zn-dialog-module');
|