@kubex/zinc 1.0.3 → 1.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.
- package/.github/workflows/js_build_and_deploy.yaml +1 -1
- package/dist/custom-elements.json +25150 -0
- package/dist/vscode.html-custom-data.json +2874 -0
- package/dist/web-types.json +6611 -0
- package/dist/zn.d.ts +6664 -0
- package/dist/zn.min.css +1 -0
- package/dist/zn.min.js +4740 -0
- 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/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/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/confirm/confirm.component.ts +1 -2
- package/src/components/content-block/content-block.component.ts +25 -1
- 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 +361 -422
- 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 +28 -3
- package/src/components/inline-edit/inline-edit.scss +4 -1
- package/src/components/input/input.scss +1 -1
- package/src/components/item/item.component.ts +30 -19
- package/src/components/item/item.scss +56 -14
- 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 +92 -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 +18 -0
- 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
|
@@ -0,0 +1,738 @@
|
|
|
1
|
+
import {colorDataProvider} from "../../../data-select/providers/color-data-provider";
|
|
2
|
+
import {type CSSResultGroup, html, type PropertyValues, unsafeCSS} from "lit";
|
|
3
|
+
import {property, query, queryAll} from "lit/decorators.js";
|
|
4
|
+
import ZincElement from "../../../../internal/zinc-element";
|
|
5
|
+
import ZnButton from "../../../button";
|
|
6
|
+
import ZnEditorTool from "./tool";
|
|
7
|
+
import ZnMenu from "../../../menu";
|
|
8
|
+
import ZnMenuItem from "../../../menu-item";
|
|
9
|
+
|
|
10
|
+
import styles from './toolbar.scss';
|
|
11
|
+
|
|
12
|
+
export default class ToolbarComponent extends ZincElement {
|
|
13
|
+
static styles: CSSResultGroup = unsafeCSS(styles);
|
|
14
|
+
|
|
15
|
+
@property({type: Number})
|
|
16
|
+
public containerWidth: number;
|
|
17
|
+
|
|
18
|
+
@query('.toolbar') private _toolbarEl!: HTMLElement;
|
|
19
|
+
|
|
20
|
+
@queryAll('.toolbar__group') private _groups!: HTMLElement[];
|
|
21
|
+
|
|
22
|
+
@query('.toolbar__overflow-menu') private _overflowMenu!: HTMLElement;
|
|
23
|
+
@query('.toolbar__group--overflow') private _overflowGroup!: HTMLElement;
|
|
24
|
+
|
|
25
|
+
private _resizeObserver: ResizeObserver | null = null;
|
|
26
|
+
private _resizeId: number | null = null;
|
|
27
|
+
|
|
28
|
+
// Tracks DOM nodes (e.g. emoji/date pickers) temporarily moved into the overflow submenu so we can restore them
|
|
29
|
+
private _movedContent: Map<HTMLElement, { placeholder: Comment; originalParent: HTMLElement }> = new Map();
|
|
30
|
+
|
|
31
|
+
connectedCallback() {
|
|
32
|
+
super.connectedCallback();
|
|
33
|
+
this.containerWidth = this.offsetWidth;
|
|
34
|
+
|
|
35
|
+
this._resizeObserver = new ResizeObserver(this.handleResize.bind(this));
|
|
36
|
+
if (this.parentElement) {
|
|
37
|
+
this._resizeObserver.observe(this.parentElement);
|
|
38
|
+
}
|
|
39
|
+
this._resizeObserver.observe(this as HTMLElement);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
disconnectedCallback() {
|
|
43
|
+
super.disconnectedCallback();
|
|
44
|
+
|
|
45
|
+
if (this._resizeObserver) {
|
|
46
|
+
this._resizeObserver.disconnect();
|
|
47
|
+
this._resizeObserver = null;
|
|
48
|
+
}
|
|
49
|
+
if (this._resizeId !== null) {
|
|
50
|
+
cancelAnimationFrame(this._resizeId);
|
|
51
|
+
this._resizeId = null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Make sure any content we moved into the overflow is restored on disconnect
|
|
55
|
+
this.restoreMovedContent();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
protected firstUpdated(_changedProperties: PropertyValues) {
|
|
59
|
+
super.firstUpdated(_changedProperties);
|
|
60
|
+
|
|
61
|
+
this.containerWidth = this.getToolbarWidth();
|
|
62
|
+
this.updateEmptyGroups();
|
|
63
|
+
|
|
64
|
+
const slotElement = this.renderRoot?.querySelector('slot') as HTMLSlotElement | null;
|
|
65
|
+
slotElement?.addEventListener('slotchange', () => this.calculateOverflow());
|
|
66
|
+
|
|
67
|
+
this.updateComplete.then(() => this.calculateOverflow());
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
handleResize = () => {
|
|
71
|
+
this.containerWidth = this.getToolbarWidth();
|
|
72
|
+
if (this._resizeId !== null) {
|
|
73
|
+
cancelAnimationFrame(this._resizeId);
|
|
74
|
+
}
|
|
75
|
+
this._resizeId = requestAnimationFrame(() => {
|
|
76
|
+
this.calculateOverflow();
|
|
77
|
+
this._resizeId = null;
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
private getToolbarWidth() {
|
|
82
|
+
const host = this as unknown as HTMLElement;
|
|
83
|
+
let width = host.getBoundingClientRect?.().width || host.offsetWidth || 0;
|
|
84
|
+
if ((!width || width <= 0) && this._toolbarEl) {
|
|
85
|
+
const bounds = this._toolbarEl.getBoundingClientRect();
|
|
86
|
+
width = bounds.width;
|
|
87
|
+
}
|
|
88
|
+
return width;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
private getOverflowGroupWidth() {
|
|
92
|
+
let width = 50;
|
|
93
|
+
const overflowGroup = this._overflowGroup as HTMLElement | undefined;
|
|
94
|
+
if (!overflowGroup) return width;
|
|
95
|
+
|
|
96
|
+
const prevDisplay = overflowGroup.style.display;
|
|
97
|
+
const prevVisibility = overflowGroup.style.visibility;
|
|
98
|
+
|
|
99
|
+
overflowGroup.style.display = 'flex';
|
|
100
|
+
overflowGroup.style.visibility = 'hidden';
|
|
101
|
+
|
|
102
|
+
width = overflowGroup.offsetWidth || width;
|
|
103
|
+
|
|
104
|
+
overflowGroup.style.visibility = prevVisibility;
|
|
105
|
+
overflowGroup.style.display = prevDisplay || 'none';
|
|
106
|
+
|
|
107
|
+
return width;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
private restoreMovedContent() {
|
|
111
|
+
this._movedContent.forEach(({placeholder, originalParent}, el) => {
|
|
112
|
+
if (placeholder.parentNode) {
|
|
113
|
+
originalParent.insertBefore(el, placeholder);
|
|
114
|
+
placeholder.parentNode.removeChild(placeholder);
|
|
115
|
+
} else {
|
|
116
|
+
originalParent.appendChild(el);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
this._movedContent.clear();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
private moveContentTo(element: HTMLElement, target: HTMLElement) {
|
|
123
|
+
if (this._movedContent.has(element)) {
|
|
124
|
+
if (element.parentElement !== target) target.appendChild(element);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const originalParent = element.parentElement as HTMLElement | null;
|
|
129
|
+
if (!originalParent) return;
|
|
130
|
+
|
|
131
|
+
const placeholder = document.createComment('toolbar-overflow-placeholder');
|
|
132
|
+
originalParent.insertBefore(placeholder, element);
|
|
133
|
+
|
|
134
|
+
target.appendChild(element);
|
|
135
|
+
this._movedContent.set(element, {placeholder, originalParent});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
private isGroupEmpty(group: HTMLElement): boolean {
|
|
139
|
+
const slotElement = group.querySelector('slot') as HTMLSlotElement | null;
|
|
140
|
+
if (slotElement) {
|
|
141
|
+
const assigned = slotElement.assignedElements({flatten: true});
|
|
142
|
+
return assigned.length === 0;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return group.childElementCount === 0;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
private updateEmptyGroups() {
|
|
149
|
+
const groups = Array.from(this._groups || []);
|
|
150
|
+
groups.forEach(group => {
|
|
151
|
+
const empty = this.isGroupEmpty(group);
|
|
152
|
+
group.classList.toggle('toolbar__group--empty', empty);
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
private _updateDividerClasses() {
|
|
157
|
+
const groups = Array.from(this._groups || []);
|
|
158
|
+
let seenVisible = false;
|
|
159
|
+
groups.forEach(group => {
|
|
160
|
+
const isEmpty = group.classList.contains('toolbar__group--empty');
|
|
161
|
+
const isHidden = (group as HTMLElement).style.display === 'none';
|
|
162
|
+
const isVisible = !isEmpty && !isHidden;
|
|
163
|
+
|
|
164
|
+
group.classList.toggle('toolbar__group--has-prev-visible', isVisible && seenVisible);
|
|
165
|
+
if (isVisible) {
|
|
166
|
+
seenVisible = true;
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
private calculateOverflow() {
|
|
172
|
+
const groups = Array.from(this._groups || []);
|
|
173
|
+
if (!groups.length) return;
|
|
174
|
+
|
|
175
|
+
this.restoreMovedContent();
|
|
176
|
+
this.updateEmptyGroups();
|
|
177
|
+
|
|
178
|
+
const nonOverflowGroups = groups.filter(group => !group.classList.contains('toolbar__group--overflow') && !group.classList.contains('toolbar__group--empty'));
|
|
179
|
+
|
|
180
|
+
nonOverflowGroups.forEach(group => {
|
|
181
|
+
group.style.display = 'flex';
|
|
182
|
+
group.classList.remove('toolbar__group--hidden', 'toolbar__group--has-prev-visible');
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
if (this._overflowGroup) {
|
|
186
|
+
this._overflowGroup.style.display = 'none';
|
|
187
|
+
this._overflowGroup.classList.remove('toolbar__group--hidden', 'toolbar__group--has-prev-visible');
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const containerWidth = this.getToolbarWidth();
|
|
191
|
+
|
|
192
|
+
if (!containerWidth || containerWidth <= 0) {
|
|
193
|
+
nonOverflowGroups.forEach(group => (group.style.display = 'flex'));
|
|
194
|
+
if (this._overflowGroup) {
|
|
195
|
+
this._overflowGroup.style.display = 'none';
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
this.restoreMovedContent();
|
|
199
|
+
if (this._overflowMenu) {
|
|
200
|
+
this._overflowMenu.innerHTML = '';
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
this._updateDividerClasses();
|
|
204
|
+
this._dispatchOverflowEvent();
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
let used = 0;
|
|
209
|
+
let visibleCount = 0;
|
|
210
|
+
|
|
211
|
+
for (const group of nonOverflowGroups) {
|
|
212
|
+
const width = group.offsetWidth;
|
|
213
|
+
if (used + width <= containerWidth) {
|
|
214
|
+
used += width;
|
|
215
|
+
visibleCount++;
|
|
216
|
+
} else {
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (visibleCount >= nonOverflowGroups.length) {
|
|
222
|
+
nonOverflowGroups.forEach(group => (group.style.display = 'flex'));
|
|
223
|
+
if (this._overflowGroup) {
|
|
224
|
+
this._overflowGroup.style.display = 'none';
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
this.restoreMovedContent();
|
|
228
|
+
if (this._overflowMenu) {
|
|
229
|
+
this._overflowMenu.innerHTML = '';
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
this._updateDividerClasses();
|
|
233
|
+
this._dispatchOverflowEvent();
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const overflowTriggerWidth = this.getOverflowGroupWidth();
|
|
238
|
+
used = 0;
|
|
239
|
+
visibleCount = 0;
|
|
240
|
+
for (const group of nonOverflowGroups) {
|
|
241
|
+
const width = group.offsetWidth;
|
|
242
|
+
if (used + width + overflowTriggerWidth <= containerWidth) {
|
|
243
|
+
used += width;
|
|
244
|
+
visibleCount++;
|
|
245
|
+
} else {
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
nonOverflowGroups.forEach((group, index) => {
|
|
251
|
+
group.style.display = index < visibleCount ? 'flex' : 'none';
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
nonOverflowGroups.forEach((group, index) => {
|
|
255
|
+
const hidden = index >= visibleCount;
|
|
256
|
+
group.classList.toggle('toolbar__group--hidden', hidden);
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
if (this._overflowGroup) {
|
|
260
|
+
this._overflowGroup.style.display = 'flex';
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
this._updateDividerClasses();
|
|
264
|
+
|
|
265
|
+
const hiddenGroups = nonOverflowGroups.slice(visibleCount);
|
|
266
|
+
this.populateOverflowMenu(hiddenGroups);
|
|
267
|
+
|
|
268
|
+
this._dispatchOverflowEvent();
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
private _dispatchOverflowEvent() {
|
|
272
|
+
this.dispatchEvent(new CustomEvent('zn-toolbar-overflow-updated', {bubbles: true, composed: true}));
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
private populateOverflowMenu(hiddenGroups: HTMLElement[]) {
|
|
276
|
+
const menu = this._overflowMenu as HTMLElement | null;
|
|
277
|
+
if (!menu) return;
|
|
278
|
+
|
|
279
|
+
this.restoreMovedContent();
|
|
280
|
+
|
|
281
|
+
menu.innerHTML = '';
|
|
282
|
+
|
|
283
|
+
const addMenuItemTo = (targetMenu: HTMLElement, label: string, icon?: string, onClick?: () => void, attrs: {
|
|
284
|
+
[k: string]: string;
|
|
285
|
+
} = {}) => {
|
|
286
|
+
const item = document.createElement('zn-menu-item') as ZnMenuItem;
|
|
287
|
+
item.innerText = label;
|
|
288
|
+
|
|
289
|
+
Object.keys(attrs).forEach(key => item.setAttribute(key, attrs[key]));
|
|
290
|
+
|
|
291
|
+
if (icon) {
|
|
292
|
+
const iconEl = document.createElement('zn-icon');
|
|
293
|
+
iconEl.setAttribute('src', icon);
|
|
294
|
+
iconEl.setAttribute('size', '18');
|
|
295
|
+
iconEl.setAttribute('slot', 'prefix');
|
|
296
|
+
item.appendChild(iconEl);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
if (onClick) {
|
|
300
|
+
item.addEventListener('click', (e: Event) => {
|
|
301
|
+
e.preventDefault();
|
|
302
|
+
e.stopPropagation();
|
|
303
|
+
onClick();
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
targetMenu.appendChild(item);
|
|
307
|
+
return item as ZnMenuItem;
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
const makeProxyClone = (original: ZnMenuItem) => {
|
|
311
|
+
const cloned = document.createElement('zn-menu-item') as ZnMenuItem;
|
|
312
|
+
for (const a of original.attributes) {
|
|
313
|
+
if (a.name === 'id') continue;
|
|
314
|
+
cloned.setAttribute(a.name, a.value);
|
|
315
|
+
}
|
|
316
|
+
cloned.innerHTML = original.innerHTML;
|
|
317
|
+
return cloned;
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
const getDropdownIcon = (dropdown: HTMLElement) => {
|
|
321
|
+
const triggerBtn = dropdown.querySelector('zn-button[slot="trigger"]') as ZnButton | undefined;
|
|
322
|
+
const iconEl = triggerBtn?.querySelector('zn-icon') as HTMLElement | null;
|
|
323
|
+
return iconEl?.getAttribute('src');
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
const buttonLabelMap: Record<string, string> = {
|
|
327
|
+
bold: 'Bold',
|
|
328
|
+
italic: 'Italic',
|
|
329
|
+
underline: 'Underline',
|
|
330
|
+
undo: 'Undo',
|
|
331
|
+
redo: 'Redo'
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
const dropdownLabelMap: Record<string, string> = {
|
|
335
|
+
'toolbar__header-dropdown': 'Text',
|
|
336
|
+
'toolbar__format-dropdown': 'Format',
|
|
337
|
+
'toolbar__color-dropdown': 'Color',
|
|
338
|
+
'toolbar__list-dropdown': 'Lists',
|
|
339
|
+
'toolbar__file-dropdown': 'Insert',
|
|
340
|
+
'toolbar__emoji-dropdown': 'Emoji',
|
|
341
|
+
'toolbar__date-dropdown': 'Date'
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
hiddenGroups.forEach((group) => {
|
|
345
|
+
// 1) Dropdowns → nested submenu
|
|
346
|
+
const dropdowns = Array.from(group.querySelectorAll('zn-dropdown')) as HTMLElement[];
|
|
347
|
+
dropdowns.forEach((dropdown: HTMLElement) => {
|
|
348
|
+
let label = '';
|
|
349
|
+
for (const className in dropdownLabelMap) {
|
|
350
|
+
if (dropdown.classList.contains(className)) {
|
|
351
|
+
label = dropdownLabelMap[className];
|
|
352
|
+
break;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
if (!label) {
|
|
356
|
+
label = dropdown.getAttribute('aria-label') || dropdown.getAttribute('title') || 'More';
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
const icon = getDropdownIcon(dropdown) || '';
|
|
360
|
+
const parentItem = addMenuItemTo(menu, label, icon);
|
|
361
|
+
// Mark overflow items by source to allow programmatic access (e.g. opening Date from context menu)
|
|
362
|
+
if (dropdown.classList.contains('toolbar__date-dropdown')) {
|
|
363
|
+
parentItem.setAttribute('data-overflow-source', 'date');
|
|
364
|
+
}
|
|
365
|
+
const submenu = document.createElement('zn-menu');
|
|
366
|
+
submenu.setAttribute('slot', 'submenu');
|
|
367
|
+
|
|
368
|
+
const items = dropdown.querySelectorAll<ZnMenuItem>('zn-menu-item');
|
|
369
|
+
if (items.length) {
|
|
370
|
+
items.forEach((original: ZnMenuItem) => {
|
|
371
|
+
const clone = makeProxyClone(original);
|
|
372
|
+
submenu.appendChild(clone);
|
|
373
|
+
});
|
|
374
|
+
} else {
|
|
375
|
+
// No menu items: embed dropdown content (e.g. emoji/date pickers)
|
|
376
|
+
// Move the original content elements to preserve event listeners and third-party initialization.
|
|
377
|
+
const contentCandidates = Array.from(dropdown.children).filter((element: Element) => {
|
|
378
|
+
const isTrigger = (element as HTMLElement).getAttribute('slot') === 'trigger' || element instanceof ZnButton;
|
|
379
|
+
const isMenu = element instanceof ZnMenu || element instanceof ZnMenuItem;
|
|
380
|
+
return !isTrigger && !isMenu;
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
const wrapper = document.createElement('div');
|
|
384
|
+
wrapper.className = 'toolbar__submenu-content';
|
|
385
|
+
contentCandidates.forEach((element: HTMLElement) => this.moveContentTo(element, wrapper));
|
|
386
|
+
submenu.appendChild(wrapper);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
parentItem.appendChild(submenu);
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
// 2) Direct action buttons (exclude dropdown triggers)
|
|
393
|
+
const buttons = group.querySelectorAll<ZnButton>(
|
|
394
|
+
'zn-button.toolbar__format-button, zn-button.toolbar__action-button'
|
|
395
|
+
);
|
|
396
|
+
|
|
397
|
+
buttons.forEach((button: ZnButton) => {
|
|
398
|
+
const icon = button.getAttribute('icon') ?? '';
|
|
399
|
+
const format = button.getAttribute('data-format') ?? '';
|
|
400
|
+
const text =
|
|
401
|
+
button.getAttribute('data-text') ??
|
|
402
|
+
buttonLabelMap[format] ??
|
|
403
|
+
(format
|
|
404
|
+
? format.charAt(0).toUpperCase() + format.slice(1)
|
|
405
|
+
: button.getAttribute('aria-label') ??
|
|
406
|
+
button.textContent?.trim() ??
|
|
407
|
+
'Action');
|
|
408
|
+
|
|
409
|
+
const attrs: Record<string, string> = {'data-format': format};
|
|
410
|
+
const typeVal = button.getAttribute('data-format-type') ?? '';
|
|
411
|
+
if (typeVal) {
|
|
412
|
+
attrs['data-format-type'] = typeVal;
|
|
413
|
+
}
|
|
414
|
+
if (icon) {
|
|
415
|
+
attrs['data-icon'] = icon;
|
|
416
|
+
}
|
|
417
|
+
if (text) {
|
|
418
|
+
attrs['data-text'] = text;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
addMenuItemTo(menu, text, icon, undefined, attrs);
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
// 3) Standalone menu items not inside dropdowns
|
|
425
|
+
const standaloneItems = Array.from(group.querySelectorAll<ZnMenuItem>('zn-menu-item')).filter(item => !item.closest('zn-dropdown'));
|
|
426
|
+
standaloneItems.forEach((original: ZnMenuItem) => {
|
|
427
|
+
const clone = makeProxyClone(original);
|
|
428
|
+
menu.appendChild(clone);
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
// 4) Slotted elements (when slot group is hidden)
|
|
432
|
+
if (group.querySelector('slot')) {
|
|
433
|
+
const slotElement = group.querySelector('slot') as HTMLSlotElement | null;
|
|
434
|
+
const assigned = slotElement ? slotElement.assignedElements({flatten: true}) : [];
|
|
435
|
+
if (!assigned.length) return;
|
|
436
|
+
|
|
437
|
+
assigned.forEach((element: Element) => {
|
|
438
|
+
if (element instanceof ZnEditorTool) {
|
|
439
|
+
const icon = element.icon;
|
|
440
|
+
const text = element.label;
|
|
441
|
+
const format = element.handler || 'dialog';
|
|
442
|
+
const uri = element.uri || '';
|
|
443
|
+
const key = element.key || '';
|
|
444
|
+
|
|
445
|
+
const attrs: Record<string, string> = {'data-format': format};
|
|
446
|
+
if (uri) attrs['data-format-type'] = uri;
|
|
447
|
+
if (key) attrs['data-toolbar-key'] = key;
|
|
448
|
+
if (icon) attrs['data-icon'] = icon;
|
|
449
|
+
if (text) attrs['data-text'] = text;
|
|
450
|
+
|
|
451
|
+
addMenuItemTo(menu, text, icon, undefined, attrs);
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
render() {
|
|
459
|
+
return html`
|
|
460
|
+
<div class="toolbar">
|
|
461
|
+
<div class="toolbar__group">${this._textOptions()}</div>
|
|
462
|
+
<div class="toolbar__group">${this._formatOptions()}</div>
|
|
463
|
+
<div class="toolbar__group">${this._historyOptions()}</div>
|
|
464
|
+
<div class="toolbar__group">${this._colorOptions()}</div>
|
|
465
|
+
<div class="toolbar__group">${this._listOptions()}</div>
|
|
466
|
+
<div class="toolbar__group">
|
|
467
|
+
${this._insertOptions()}
|
|
468
|
+
${this._dateOption()}
|
|
469
|
+
${this._emojiOptions()}
|
|
470
|
+
</div>
|
|
471
|
+
<div class="toolbar__group">
|
|
472
|
+
<slot></slot>
|
|
473
|
+
</div>
|
|
474
|
+
<div class="toolbar__group toolbar__group--overflow">
|
|
475
|
+
<zn-dropdown class="toolbar__overflow" placement="bottom-end">
|
|
476
|
+
<zn-button slot="trigger"
|
|
477
|
+
class="toolbar__overflow-trigger"
|
|
478
|
+
color="transparent"
|
|
479
|
+
size="content"
|
|
480
|
+
icon="more_horiz"
|
|
481
|
+
icon-size="18"
|
|
482
|
+
icon-position="right"></zn-button>
|
|
483
|
+
<zn-menu class="toolbar__overflow-menu"></zn-menu>
|
|
484
|
+
</zn-dropdown>
|
|
485
|
+
</div>
|
|
486
|
+
</div>
|
|
487
|
+
`;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
private _textOptions() {
|
|
491
|
+
return html`
|
|
492
|
+
<zn-dropdown class="toolbar__header-dropdown" placement="bottom-end">
|
|
493
|
+
<zn-button slot="trigger"
|
|
494
|
+
class="toolbar__dropdown-trigger toolbar__header-dropdown-trigger"
|
|
495
|
+
color="transparent"
|
|
496
|
+
icon="arrow_drop_down"
|
|
497
|
+
icon-size="18"
|
|
498
|
+
icon-position="right">
|
|
499
|
+
<zn-icon src="match_case" size="18" color="primary"></zn-icon>
|
|
500
|
+
</zn-button>
|
|
501
|
+
<zn-menu>
|
|
502
|
+
<zn-menu-item type="checkbox"
|
|
503
|
+
checked-position="right"
|
|
504
|
+
data-format="header"
|
|
505
|
+
data-format-type="1"
|
|
506
|
+
data-icon="format_h1">
|
|
507
|
+
<zn-icon src="format_h1" size="18" slot="prefix"></zn-icon>
|
|
508
|
+
Heading 1
|
|
509
|
+
</zn-menu-item>
|
|
510
|
+
<zn-menu-item type="checkbox"
|
|
511
|
+
checked-position="right"
|
|
512
|
+
data-format="header"
|
|
513
|
+
data-format-type="2"
|
|
514
|
+
data-icon="format_h2">
|
|
515
|
+
<zn-icon src="format_h2" size="18" slot="prefix"></zn-icon>
|
|
516
|
+
Heading 2
|
|
517
|
+
</zn-menu-item>
|
|
518
|
+
<zn-menu-item type="checkbox"
|
|
519
|
+
checked-position="right"
|
|
520
|
+
data-format="header"
|
|
521
|
+
data-format-type=""
|
|
522
|
+
data-icon="match_case"
|
|
523
|
+
checked>
|
|
524
|
+
<zn-icon src="match_case" size="18" slot="prefix"></zn-icon>
|
|
525
|
+
Normal
|
|
526
|
+
</zn-menu-item>
|
|
527
|
+
</zn-menu>
|
|
528
|
+
</zn-dropdown>`;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
private _formatOptions() {
|
|
532
|
+
return html`
|
|
533
|
+
${this._commonFormatOptions()}
|
|
534
|
+
|
|
535
|
+
<zn-dropdown class="toolbar__format-dropdown" placement="bottom-end">
|
|
536
|
+
<zn-button slot="trigger"
|
|
537
|
+
class="toolbar__dropdown-trigger toolbar__format-dropdown-trigger"
|
|
538
|
+
color="transparent"
|
|
539
|
+
icon="arrow_drop_down"
|
|
540
|
+
icon-size="18"
|
|
541
|
+
icon-position="right">
|
|
542
|
+
<zn-icon src="format_color_text" size="18"></zn-icon>
|
|
543
|
+
</zn-button>
|
|
544
|
+
<zn-menu>
|
|
545
|
+
<zn-menu-item type="checkbox" checked-position="right" data-format="strike">
|
|
546
|
+
<zn-icon src="format_strikethrough" size="18" slot="prefix"></zn-icon>
|
|
547
|
+
Strikethrough
|
|
548
|
+
</zn-menu-item>
|
|
549
|
+
<zn-menu-item type="checkbox" checked-position="right" data-format="blockquote">
|
|
550
|
+
<zn-icon src="format_quote" size="18" slot="prefix"></zn-icon>
|
|
551
|
+
Quote
|
|
552
|
+
</zn-menu-item>
|
|
553
|
+
<zn-menu-item type="checkbox" checked-position="right" data-format="code">
|
|
554
|
+
<zn-icon src="code" size="18" slot="prefix"></zn-icon>
|
|
555
|
+
Code
|
|
556
|
+
</zn-menu-item>
|
|
557
|
+
<zn-menu-item type="checkbox" checked-position="right" data-format="code-block">
|
|
558
|
+
<zn-icon src="code_blocks" size="18" slot="prefix"></zn-icon>
|
|
559
|
+
Code Block
|
|
560
|
+
</zn-menu-item>
|
|
561
|
+
<zn-menu-item data-format="clean">
|
|
562
|
+
<zn-icon src="format_clear" size="18" slot="prefix"></zn-icon>
|
|
563
|
+
Clear Formatting
|
|
564
|
+
</zn-menu-item>
|
|
565
|
+
</zn-menu>
|
|
566
|
+
</zn-dropdown>`;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
private _commonFormatOptions() {
|
|
570
|
+
return html`
|
|
571
|
+
<zn-button class="toolbar__format-button"
|
|
572
|
+
color="transparent"
|
|
573
|
+
icon="format_bold"
|
|
574
|
+
icon-size="18"
|
|
575
|
+
data-format="bold"></zn-button>
|
|
576
|
+
<zn-button class="toolbar__format-button"
|
|
577
|
+
color="transparent"
|
|
578
|
+
icon="format_italic"
|
|
579
|
+
icon-size="18"
|
|
580
|
+
data-format="italic"></zn-button>
|
|
581
|
+
<zn-button class="toolbar__format-button"
|
|
582
|
+
color="transparent"
|
|
583
|
+
icon="format_underlined"
|
|
584
|
+
icon-size="18"
|
|
585
|
+
data-format="underline"></zn-button>`;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
private _historyOptions() {
|
|
589
|
+
return html`
|
|
590
|
+
<zn-button class="toolbar__format-button"
|
|
591
|
+
color="transparent"
|
|
592
|
+
icon="undo"
|
|
593
|
+
icon-size="18"
|
|
594
|
+
data-format="undo"></zn-button>
|
|
595
|
+
<zn-button class="toolbar__format-button"
|
|
596
|
+
color="transparent"
|
|
597
|
+
icon="redo"
|
|
598
|
+
icon-size="18"
|
|
599
|
+
data-format="redo"></zn-button>`;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
private _colorOptions() {
|
|
603
|
+
return html`
|
|
604
|
+
<zn-dropdown class="toolbar__color-dropdown" placement="bottom-end">
|
|
605
|
+
<zn-button slot="trigger"
|
|
606
|
+
class="toolbar__dropdown-trigger toolbar__color-dropdown-trigger"
|
|
607
|
+
color="transparent"
|
|
608
|
+
icon="arrow_drop_down"
|
|
609
|
+
icon-size="18"
|
|
610
|
+
icon-position="right">
|
|
611
|
+
<zn-icon src="colors" size="18"></zn-icon>
|
|
612
|
+
</zn-button>
|
|
613
|
+
<zn-menu>
|
|
614
|
+
<zn-menu-item data-format="color" data-format-type="">
|
|
615
|
+
<zn-icon slot="prefix" class="color-icon--unset" src="format_color_reset" size="18"></zn-icon>
|
|
616
|
+
Unset
|
|
617
|
+
</zn-menu-item>
|
|
618
|
+
${colorDataProvider.getData.map((opt) => html`
|
|
619
|
+
<zn-menu-item data-format="color" data-format-type="${opt.key}">
|
|
620
|
+
<div slot="prefix" class="color-icon color-icon--${opt.key}"></div>
|
|
621
|
+
${opt.value}
|
|
622
|
+
</zn-menu-item>
|
|
623
|
+
`)}
|
|
624
|
+
</zn-menu>
|
|
625
|
+
</zn-dropdown>`;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
private _listOptions() {
|
|
629
|
+
return html`
|
|
630
|
+
<zn-dropdown class="toolbar__list-dropdown" placement="bottom-end">
|
|
631
|
+
<zn-button slot="trigger"
|
|
632
|
+
class="toolbar__dropdown-trigger toolbar__list-dropdown-trigger"
|
|
633
|
+
color="transparent"
|
|
634
|
+
icon="arrow_drop_down"
|
|
635
|
+
icon-size="18"
|
|
636
|
+
icon-position="right">
|
|
637
|
+
<zn-icon src="lists" size="18"></zn-icon>
|
|
638
|
+
</zn-button>
|
|
639
|
+
<zn-menu>
|
|
640
|
+
<zn-menu-item type="checkbox"
|
|
641
|
+
checked-position="right"
|
|
642
|
+
data-format="list"
|
|
643
|
+
data-format-type="bullet"
|
|
644
|
+
data-text="Bulleted List"
|
|
645
|
+
data-icon="format_list_bulleted">
|
|
646
|
+
<zn-icon src="format_list_bulleted" size="18" slot="prefix"></zn-icon>
|
|
647
|
+
Bulleted
|
|
648
|
+
</zn-menu-item>
|
|
649
|
+
<zn-menu-item type="checkbox"
|
|
650
|
+
checked-position="right"
|
|
651
|
+
data-format="list"
|
|
652
|
+
data-format-type="ordered"
|
|
653
|
+
data-text="Numbered List"
|
|
654
|
+
data-icon="format_list_numbered">
|
|
655
|
+
<zn-icon src="format_list_numbered" size="18" slot="prefix"></zn-icon>
|
|
656
|
+
Numbered
|
|
657
|
+
</zn-menu-item>
|
|
658
|
+
<zn-menu-item type="checkbox"
|
|
659
|
+
checked-position="right"
|
|
660
|
+
data-format="list"
|
|
661
|
+
data-format-type="checked"
|
|
662
|
+
data-text="Checked List"
|
|
663
|
+
data-icon="checklist">
|
|
664
|
+
<zn-icon src="checklist" size="18" slot="prefix"></zn-icon>
|
|
665
|
+
Checked
|
|
666
|
+
</zn-menu-item>
|
|
667
|
+
</zn-menu>
|
|
668
|
+
</zn-dropdown>`;
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
private _insertOptions() {
|
|
672
|
+
return html`
|
|
673
|
+
<zn-dropdown class="toolbar__file-dropdown" placement="bottom-end">
|
|
674
|
+
<zn-button slot="trigger"
|
|
675
|
+
class="toolbar__dropdown-trigger toolbar__file-dropdown-trigger"
|
|
676
|
+
color="transparent"
|
|
677
|
+
icon="arrow_drop_down"
|
|
678
|
+
icon-size="18"
|
|
679
|
+
icon-position="right">
|
|
680
|
+
<zn-icon src="add" size="18"></zn-icon>
|
|
681
|
+
</zn-button>
|
|
682
|
+
<zn-menu>
|
|
683
|
+
<zn-menu-item checked-position="right" data-format="divider">
|
|
684
|
+
<zn-icon src="horizontal_rule" size="18" slot="prefix"></zn-icon>
|
|
685
|
+
Divider
|
|
686
|
+
</zn-menu-item>
|
|
687
|
+
<zn-menu-item checked-position="right" data-format="link">
|
|
688
|
+
<zn-icon src="link" size="18" slot="prefix"></zn-icon>
|
|
689
|
+
Link
|
|
690
|
+
</zn-menu-item>
|
|
691
|
+
<zn-menu-item checked-position="right" data-format="attachment">
|
|
692
|
+
<zn-icon src="attachment" size="18" slot="prefix"></zn-icon>
|
|
693
|
+
Attachment
|
|
694
|
+
</zn-menu-item>
|
|
695
|
+
<zn-menu-item checked-position="right" data-format="image">
|
|
696
|
+
<zn-icon src="image" size="18" slot="prefix"></zn-icon>
|
|
697
|
+
Image
|
|
698
|
+
</zn-menu-item>
|
|
699
|
+
<zn-menu-item checked-position="right" data-format="video">
|
|
700
|
+
<zn-icon src="video_camera_back" size="18" slot="prefix"></zn-icon>
|
|
701
|
+
Video
|
|
702
|
+
</zn-menu-item>
|
|
703
|
+
</zn-menu>
|
|
704
|
+
</zn-dropdown>`;
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
private _emojiOptions() {
|
|
708
|
+
return html`
|
|
709
|
+
<zn-dropdown class="toolbar__emoji-dropdown" placement="bottom-end">
|
|
710
|
+
<zn-button slot="trigger"
|
|
711
|
+
class="toolbar__dropdown-trigger toolbar__emoji-dropdown-trigger"
|
|
712
|
+
color="transparent"
|
|
713
|
+
icon="arrow_drop_down"
|
|
714
|
+
icon-size="18"
|
|
715
|
+
icon-position="right">
|
|
716
|
+
<zn-icon src="insert_emoticon" size="18"></zn-icon>
|
|
717
|
+
</zn-button>
|
|
718
|
+
<div class="emoji-picker"></div>
|
|
719
|
+
</zn-dropdown>`;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
private _dateOption() {
|
|
723
|
+
return html`
|
|
724
|
+
<zn-dropdown class="toolbar__date-dropdown" placement="bottom-end">
|
|
725
|
+
<zn-button slot="trigger"
|
|
726
|
+
class="toolbar__dropdown-trigger toolbar__date-dropdown-trigger"
|
|
727
|
+
color="transparent"
|
|
728
|
+
icon="arrow_drop_down"
|
|
729
|
+
icon-size="18"
|
|
730
|
+
icon-position="right">
|
|
731
|
+
<zn-icon src="calendar_today" size="18"></zn-icon>
|
|
732
|
+
</zn-button>
|
|
733
|
+
<div class="date-picker"></div>
|
|
734
|
+
</zn-dropdown>`;
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
ToolbarComponent.define('zn-toolbar');
|