@kubex/zinc 1.0.112 → 1.0.114
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/eleventy_build.yml +5 -5
- package/.github/workflows/js_build_and_deploy.yaml +1 -1
- package/dist/custom-elements.json +2417 -188
- package/dist/vscode.html-custom-data.json +85 -5
- package/dist/web-types.json +246 -9
- package/dist/zn.d.ts +519 -338
- package/dist/zn.min.css +1 -1
- package/dist/zn.min.js +944 -865
- package/docs/eleventy.config.cjs +4 -2
- package/docs/pages/components/header.md +13 -0
- package/docs/pages/components/inline-edit.md +20 -0
- package/docs/pages/components/item.md +12 -1
- package/docs/pages/components/page.md +149 -0
- package/docs/pages/components/progress-bar.md +16 -0
- package/docs/pages/components/select.md +25 -0
- package/docs/pages/components/split-pane.md +6 -7
- package/docs/pages/components/tabs.md +59 -9
- package/package.json +8 -5
- package/scripts/build.js +40 -19
- package/scss/_global-spacing.scss +12 -1
- package/scss/_root.scss +34 -2
- package/scss/shared/layout.scss +15 -2
- package/scss/themes/_light.scss +1 -1
- package/src/components/absolute-container/absolute-container.component.ts +9 -25
- package/src/components/animated-button/animated-button.test.ts +8 -8
- package/src/components/button/button.component.ts +3 -1
- package/src/components/button/button.scss +5 -0
- package/src/components/button-menu/button-menu.component.ts +36 -21
- package/src/components/button-menu/button-menu.test.ts +55 -1
- package/src/components/chart/builders.ts +2 -1
- package/src/components/chart/chart.component.ts +7 -7
- package/src/components/collapsible/collapsible.component.ts +7 -14
- package/src/components/cols/cols.scss +1 -1
- package/src/components/content-block/content-block.component.ts +11 -33
- package/src/components/data-select/data-select.component.ts +7 -11
- package/src/components/data-table/data-table.component.ts +10 -14
- package/src/components/editor/modules/toolbar/toolbar.component.ts +5 -9
- package/src/components/expanding-action/expanding-action.component.ts +37 -43
- package/src/components/form-group/form-group.component.ts +8 -3
- package/src/components/header/header.component.ts +6 -5
- package/src/components/header/header.scss +31 -25
- package/src/components/inline-edit/inline-edit.component.ts +13 -1
- package/src/components/inline-edit/inline-edit.test.ts +50 -0
- package/src/components/input/input.test.ts +77 -0
- package/src/components/input-group/input-group.test.ts +2 -10
- package/src/components/item/item.component.ts +12 -6
- package/src/components/item/item.scss +1 -1
- package/src/components/item/item.test.ts +8 -0
- package/src/components/navbar/navbar.component.ts +242 -40
- package/src/components/navbar/navbar.scss +134 -21
- package/src/components/navbar/navbar.test.ts +157 -1
- package/src/components/option/option.scss +5 -7
- package/src/components/option/option.test.ts +30 -0
- package/src/components/page/index.ts +13 -0
- package/src/components/page/page.component.ts +406 -0
- package/src/components/page/page.scss +325 -0
- package/src/components/page/page.test.ts +397 -0
- package/src/components/page-nav/page-nav.scss +7 -5
- package/src/components/pane/pane.component.ts +2 -2
- package/src/components/pane/pane.scss +0 -1
- package/src/components/pane/pane.test.ts +31 -0
- package/src/components/panel/panel.scss +1 -0
- package/src/components/progress-bar/progress-bar.component.ts +5 -2
- package/src/components/progress-bar/progress-bar.scss +17 -1
- package/src/components/progress-bar/progress-bar.test.ts +12 -0
- package/src/components/scroll-container/scroll-container.component.ts +22 -21
- package/src/components/select/select.component.ts +240 -38
- package/src/components/select/select.scss +15 -0
- package/src/components/select/select.test.ts +477 -0
- package/src/components/settings-container/settings-container.component.ts +15 -19
- package/src/components/settings-container/settings-container.scss +8 -8
- package/src/components/sidebar/sidebar.component.ts +11 -11
- package/src/components/simple-chart/simple-chart.component.ts +7 -7
- package/src/components/sp/sp.scss +46 -15
- package/src/components/sp/sp.test.ts +15 -0
- package/src/components/split-pane/split-pane.component.ts +153 -26
- package/src/components/split-pane/split-pane.scss +89 -13
- package/src/components/split-pane/split-pane.test.ts +187 -0
- package/src/components/style/style.component.ts +8 -0
- package/src/components/tab/index.ts +13 -0
- package/src/components/tab/tab.component.ts +25 -0
- package/src/components/tab/tab.scss +7 -0
- package/src/components/table/table.component.ts +7 -2
- package/src/components/tabs/tabs.component.ts +75 -70
- package/src/components/tabs/tabs.scss +1 -1
- package/src/components/textarea/textarea.component.ts +5 -8
- package/src/components/translation-group/translation-group.component.ts +15 -14
- package/src/components/translations/translations.component.ts +18 -17
- package/src/components/translations/translations.scss +1 -0
- package/src/components/translations/translations.test.ts +3 -2
- package/src/internal/form.ts +234 -0
- package/src/internal/theme.ts +26 -46
- package/src/internal/zinc-element.ts +12 -7
- package/src/utilities/form.ts +1 -0
- package/src/wc.scss +1 -1
- package/src/zinc.ts +3 -0
|
@@ -51,8 +51,11 @@ export default class ZnItem extends ZincElement {
|
|
|
51
51
|
|
|
52
52
|
@property({type: Boolean}) grid: boolean;
|
|
53
53
|
|
|
54
|
+
//@deprecated
|
|
54
55
|
@property({type: Boolean, attribute: 'no-padding'}) noPadding: boolean;
|
|
55
56
|
|
|
57
|
+
@property({type: Boolean, attribute: 'flush'}) flush: boolean;
|
|
58
|
+
|
|
56
59
|
// align items to the right
|
|
57
60
|
@property({type: Boolean, attribute: 'align-end'}) alignEnd: boolean;
|
|
58
61
|
|
|
@@ -62,6 +65,9 @@ export default class ZnItem extends ZincElement {
|
|
|
62
65
|
connectedCallback() {
|
|
63
66
|
super.connectedCallback();
|
|
64
67
|
this.setAttribute('role', 'listitem');
|
|
68
|
+
if (this.flush) {
|
|
69
|
+
this.noPadding = true;
|
|
70
|
+
}
|
|
65
71
|
}
|
|
66
72
|
|
|
67
73
|
protected updated(_changedProperties: PropertyValues) {
|
|
@@ -91,15 +97,15 @@ export default class ZnItem extends ZincElement {
|
|
|
91
97
|
|
|
92
98
|
const headings = html`
|
|
93
99
|
<div class="item__headings">
|
|
94
|
-
<div class
|
|
100
|
+
<div class="${classMap({
|
|
95
101
|
'item__caption': true,
|
|
96
102
|
'item__caption--required': this._hasRequiredSlot(),
|
|
97
103
|
'item__caption--has-help': hasHelpTooltip
|
|
98
|
-
})} part="caption">${this.caption}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
104
|
+
})}" part="caption">${this.caption}
|
|
105
|
+
${hasHelpTooltip ? html`
|
|
106
|
+
<zn-tooltip class="item__help-tooltip" content="${this.helpTooltip}">
|
|
107
|
+
<zn-icon src="info"></zn-icon>
|
|
108
|
+
</zn-tooltip>` : ''}
|
|
103
109
|
</div>
|
|
104
110
|
${this.description ? html`
|
|
105
111
|
<div class="item__description">${this.description}</div>` : ''}
|
|
@@ -7,4 +7,12 @@ describe('<zn-item>', () => {
|
|
|
7
7
|
|
|
8
8
|
expect(el).to.exist;
|
|
9
9
|
});
|
|
10
|
+
|
|
11
|
+
it('right aligns content when align-end is set', async () => {
|
|
12
|
+
const el = await fixture(html` <zn-item align-end caption="Total">$100.00</zn-item> `);
|
|
13
|
+
const content = el.shadowRoot?.querySelector<HTMLElement>('.item__content-inner');
|
|
14
|
+
|
|
15
|
+
expect(content).to.exist;
|
|
16
|
+
expect(getComputedStyle(content!).textAlign).to.equal('right');
|
|
17
|
+
});
|
|
10
18
|
});
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import {classMap} from "lit/directives/class-map.js";
|
|
2
2
|
import {type CSSResultGroup, html, type PropertyValues, unsafeCSS} from 'lit';
|
|
3
3
|
import {ifDefined} from "lit/directives/if-defined.js";
|
|
4
|
+
import {MutationController} from '@lit-labs/observers/mutation-controller.js';
|
|
4
5
|
import {property} from 'lit/decorators.js';
|
|
6
|
+
import {ResizeController} from '@lit-labs/observers/resize-controller.js';
|
|
5
7
|
import {Store} from "../../internal/storage";
|
|
6
8
|
import ZincElement from '../../internal/zinc-element';
|
|
7
9
|
import ZnDropdown from "../dropdown";
|
|
@@ -14,6 +16,8 @@ interface StoredTab {
|
|
|
14
16
|
title: string;
|
|
15
17
|
}
|
|
16
18
|
|
|
19
|
+
const NAVBAR_MIN_WIDTH = 200;
|
|
20
|
+
|
|
17
21
|
/**
|
|
18
22
|
* @summary Short summary of the component's intended use.
|
|
19
23
|
* @documentation https://zinc.style/components/navbar
|
|
@@ -25,7 +29,8 @@ interface StoredTab {
|
|
|
25
29
|
* @event zn-event-name - Emitted as an example.
|
|
26
30
|
*
|
|
27
31
|
* @slot - The default slot.
|
|
28
|
-
* @slot
|
|
32
|
+
* @slot expand - Expanding action panels rendered alongside the navbar items.
|
|
33
|
+
* @slot bottom - Content rendered below the navbar row (e.g. chips, filters).
|
|
29
34
|
*
|
|
30
35
|
* @csspart base - The component's base wrapper.
|
|
31
36
|
*
|
|
@@ -59,32 +64,107 @@ export default class ZnNavbar extends ZincElement {
|
|
|
59
64
|
private _postItems: NodeListOf<Element>;
|
|
60
65
|
@property()
|
|
61
66
|
private _appended: Element[];
|
|
62
|
-
private _expanding:
|
|
67
|
+
private _expanding: Element[] = [];
|
|
63
68
|
private _openedTabs: string[] = [];
|
|
64
|
-
|
|
69
|
+
|
|
70
|
+
private readonly _itemsObserver = new MutationController(this, {
|
|
71
|
+
target: null,
|
|
72
|
+
config: {childList: true},
|
|
73
|
+
callback: () => this._updateVisibility(),
|
|
74
|
+
});
|
|
65
75
|
|
|
66
76
|
private _navItems: HTMLElement | null = null;
|
|
67
77
|
private _expandable: HTMLElement | null = null;
|
|
68
78
|
private _extendedMenu: HTMLElement | null = null;
|
|
79
|
+
private readonly _cloneSources = new WeakMap<HTMLElement, HTMLElement>();
|
|
69
80
|
private _navItemsGap: number = 0;
|
|
70
81
|
private _expandableMargin: number = 0;
|
|
71
82
|
private _totalItemWidth: number = 0;
|
|
83
|
+
private _resizeFrame: number | null = null;
|
|
84
|
+
private _resizeController: ResizeController;
|
|
72
85
|
|
|
73
86
|
protected _store: Store;
|
|
74
87
|
|
|
75
88
|
appendItem(item: Element) {
|
|
76
|
-
this._appended = this._appended || [];
|
|
77
|
-
|
|
89
|
+
this._appended = [...(this._appended || []), item];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
addExpandingAction(action: Element) {
|
|
93
|
+
if (!this._expanding.includes(action)) {
|
|
94
|
+
this._expanding = [...this._expanding, action];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (action.parentElement !== this) {
|
|
98
|
+
this.appendChild(action);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
this.requestUpdate();
|
|
102
|
+
this._updateVisibility();
|
|
103
|
+
this._observeExpandingAction(action);
|
|
104
|
+
this._scheduleResize();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
constructor() {
|
|
108
|
+
super();
|
|
109
|
+
this._resizeController = new ResizeController(this, {
|
|
110
|
+
callback: () => this._scheduleResize(),
|
|
111
|
+
});
|
|
112
|
+
// eslint-disable-next-line no-new
|
|
113
|
+
new MutationController(this, {
|
|
114
|
+
config: {childList: true},
|
|
115
|
+
callback: mutations => this._adoptNewLightItems(mutations),
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
private readonly _expandingActionObserver = new MutationController(this, {
|
|
120
|
+
target: null,
|
|
121
|
+
config: {attributes: true, attributeFilter: ['open', 'method', 'basis']},
|
|
122
|
+
callback: () => this._scheduleResize(),
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
private _scheduleResize = () => {
|
|
126
|
+
if (this._resizeFrame !== null) {
|
|
127
|
+
cancelAnimationFrame(this._resizeFrame);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
this._resizeFrame = requestAnimationFrame(() => {
|
|
131
|
+
this._resizeFrame = null;
|
|
132
|
+
this.handleResize();
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
private _observeExpandingAction(action: Element) {
|
|
137
|
+
this._expandingActionObserver.observe(action);
|
|
138
|
+
this._resizeController.observe(action);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
private _adoptNewLightItems(mutations: MutationRecord[]) {
|
|
142
|
+
const ul = this.shadowRoot?.querySelector('ul');
|
|
143
|
+
if (!ul) return;
|
|
144
|
+
const moreItem = ul.querySelector('li.more');
|
|
145
|
+
for (const m of mutations) {
|
|
146
|
+
for (const node of Array.from(m.addedNodes)) {
|
|
147
|
+
if (node instanceof Element && node.tagName === 'ZN-EXPANDING-ACTION') {
|
|
148
|
+
this.addExpandingAction(node);
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (!(node instanceof HTMLLIElement)) continue;
|
|
153
|
+
if (node.hasAttribute('suffix')) continue;
|
|
154
|
+
if (moreItem) {
|
|
155
|
+
ul.insertBefore(node, moreItem);
|
|
156
|
+
} else {
|
|
157
|
+
ul.appendChild(node);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
78
161
|
}
|
|
79
162
|
|
|
80
163
|
connectedCallback() {
|
|
81
164
|
super.connectedCallback();
|
|
82
165
|
this._preItems = this.querySelectorAll('li:not([suffix])');
|
|
83
166
|
this._postItems = this.querySelectorAll('li[suffix]');
|
|
84
|
-
this._expanding = this.querySelectorAll('zn-expanding-action');
|
|
85
|
-
|
|
86
|
-
this.resizeObserver = new ResizeObserver(this.handleResize.bind(this));
|
|
87
|
-
this.resizeObserver.observe(this as HTMLElement); // Observe the parent node
|
|
167
|
+
this._expanding = Array.from(this.querySelectorAll('zn-expanding-action'));
|
|
88
168
|
|
|
89
169
|
if (!this.masterId) {
|
|
90
170
|
this.masterId = this.storeKey || Math.floor(Math.random() * 1000000).toString();
|
|
@@ -97,21 +177,26 @@ export default class ZnNavbar extends ZincElement {
|
|
|
97
177
|
this._store = new Store(this.localStorage ? window.localStorage : window.sessionStorage, "znnav:", this.storeTtl);
|
|
98
178
|
}
|
|
99
179
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
// If we can't do anything with the nav items, we just return
|
|
180
|
+
private _updateVisibility = () => {
|
|
181
|
+
if (this._expanding.length > 0) {
|
|
182
|
+
this.style.display = '';
|
|
104
183
|
return;
|
|
105
184
|
}
|
|
106
185
|
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
this.
|
|
112
|
-
return
|
|
186
|
+
const itemCount = this.itemCount()
|
|
187
|
+
if (itemCount === 0 || (itemCount < 2 && this.hideOne)) {
|
|
188
|
+
this.style.display = 'none';
|
|
189
|
+
} else {
|
|
190
|
+
this.style.display = '';
|
|
113
191
|
}
|
|
192
|
+
};
|
|
114
193
|
|
|
194
|
+
itemCount(): number {
|
|
195
|
+
const items = this._navItems?.querySelectorAll(':scope > li:not(.more):not(#dropdown-item)') || [];
|
|
196
|
+
return items.length;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
private _resolveAvailableWidth(): number {
|
|
115
200
|
let parent = this.parentElement;
|
|
116
201
|
let availableWidth = this.offsetWidth || parent?.offsetWidth || 0;
|
|
117
202
|
|
|
@@ -122,7 +207,102 @@ export default class ZnNavbar extends ZincElement {
|
|
|
122
207
|
availableWidth = parent.offsetWidth || 0;
|
|
123
208
|
}
|
|
124
209
|
|
|
125
|
-
availableWidth
|
|
210
|
+
return availableWidth;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
private _measureTotalItemWidth(): number {
|
|
214
|
+
const items = this._navItems?.querySelectorAll(':scope > li') || [];
|
|
215
|
+
let totalWidth = 0;
|
|
216
|
+
|
|
217
|
+
for (const item of items) {
|
|
218
|
+
if (item.classList.contains('more') || !(item instanceof HTMLElement)) {
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
totalWidth += this._getItemWidth(item);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return totalWidth;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
private _getItemWidth(item: HTMLElement): number {
|
|
229
|
+
return (item.getBoundingClientRect().width || item.offsetWidth || 0) + this._navItemsGap + 5;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
private _getHorizontalSpacing(element: HTMLElement): number {
|
|
233
|
+
const computed = getComputedStyle(element);
|
|
234
|
+
return (parseFloat(computed.paddingLeft) || 0) + (parseFloat(computed.paddingRight) || 0);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
private _getMoreItemWidth(): number {
|
|
238
|
+
const moreItem = this._navItems?.querySelector<HTMLElement>(':scope > li.more');
|
|
239
|
+
if (!moreItem || !this._navItems) {
|
|
240
|
+
return 0;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
let moreWidth = this._getItemWidth(moreItem);
|
|
244
|
+
if (moreWidth > 0) {
|
|
245
|
+
return moreWidth;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const hadHidden = this._navItems.classList.contains('has-hidden');
|
|
249
|
+
this._navItems.classList.add('has-hidden');
|
|
250
|
+
moreWidth = this._getItemWidth(moreItem);
|
|
251
|
+
this._navItems.classList.toggle('has-hidden', hadHidden);
|
|
252
|
+
|
|
253
|
+
return moreWidth;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
private _getExpandableWidth(containerWidth: number): number {
|
|
257
|
+
const expandableWidth = this._expandableMargin + (this._expandable?.getBoundingClientRect().width || this._expandable?.offsetWidth || 0);
|
|
258
|
+
let fillWidth = 0;
|
|
259
|
+
|
|
260
|
+
for (const action of this._expanding) {
|
|
261
|
+
if (!(action instanceof HTMLElement)) {
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const method = (action as HTMLElement & {method?: string}).method || action.getAttribute('method') || 'drop';
|
|
266
|
+
const open = Boolean((action as HTMLElement & {open?: boolean}).open || action.hasAttribute('open'));
|
|
267
|
+
|
|
268
|
+
if (method !== 'fill' || !open) {
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const panel = action.shadowRoot?.querySelector<HTMLElement>('.expanding-action--fill');
|
|
273
|
+
const panelWidth = panel?.getBoundingClientRect().width || 0;
|
|
274
|
+
fillWidth = Math.max(fillWidth, panelWidth, Math.min(containerWidth, 800));
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return Math.max(expandableWidth, fillWidth);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
handleResize = () => {
|
|
281
|
+
if (this._extendedMenu === null || this.iconBar || this.stacked) {
|
|
282
|
+
// If we can't do anything with the nav items, we just return
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const availableContainerWidth = this._resolveAvailableWidth();
|
|
287
|
+
const expandWidth = this._getExpandableWidth(availableContainerWidth);
|
|
288
|
+
this._totalItemWidth = this._measureTotalItemWidth();
|
|
289
|
+
if (this._totalItemWidth === 0) {
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
let hasHidden = (this._navItems?.querySelectorAll('li.hidden').length || 0) > 0
|
|
294
|
+
|
|
295
|
+
const navSpacing = this._navItems ? this._getHorizontalSpacing(this._navItems) : 0;
|
|
296
|
+
const availableWidth = Math.max(availableContainerWidth - expandWidth, NAVBAR_MIN_WIDTH);
|
|
297
|
+
const availableWithoutMore = availableWidth - navSpacing;
|
|
298
|
+
|
|
299
|
+
if (!hasHidden && this._totalItemWidth <= availableWithoutMore) {
|
|
300
|
+
this._navItems?.classList.toggle('has-hidden', false)
|
|
301
|
+
return
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const moreWidth = this._getMoreItemWidth();
|
|
305
|
+
const availableWithMore = availableWithoutMore - moreWidth;
|
|
126
306
|
// reduce the items
|
|
127
307
|
let takenWidth = 0;
|
|
128
308
|
let hideRemaining = false;
|
|
@@ -132,10 +312,11 @@ export default class ZnNavbar extends ZincElement {
|
|
|
132
312
|
if (item.classList.contains('more') || !(item instanceof HTMLElement)) {
|
|
133
313
|
continue;
|
|
134
314
|
}
|
|
135
|
-
const itemWidth =
|
|
136
|
-
if (hideRemaining || ((itemWidth + takenWidth) >
|
|
315
|
+
const itemWidth = this._getItemWidth(item);
|
|
316
|
+
if (hideRemaining || ((itemWidth + takenWidth) > availableWithMore)) {
|
|
137
317
|
const extMenu = item.cloneNode(true) as HTMLElement;
|
|
138
318
|
extMenu.classList.remove('hidden');
|
|
319
|
+
this._cloneSources.set(extMenu, item);
|
|
139
320
|
extMenu.addEventListener('click', () => {
|
|
140
321
|
item.click();
|
|
141
322
|
(this.shadowRoot?.querySelector('#extended-dropdown') as ZnDropdown || null)?.hide()
|
|
@@ -152,6 +333,18 @@ export default class ZnNavbar extends ZincElement {
|
|
|
152
333
|
this._navItems?.classList.toggle('has-hidden', hasHidden && hideRemaining)
|
|
153
334
|
}
|
|
154
335
|
|
|
336
|
+
// Clones in the extended menu are static snapshots, so mirror the active
|
|
337
|
+
// state of their source items each time the dropdown opens.
|
|
338
|
+
private _syncExtendedActive = () => {
|
|
339
|
+
const clones = this._extendedMenu?.querySelectorAll<HTMLElement>(':scope > li') || [];
|
|
340
|
+
for (const clone of clones) {
|
|
341
|
+
const source = this._cloneSources.get(clone);
|
|
342
|
+
if (!source) continue;
|
|
343
|
+
clone.classList.toggle('active', source.classList.contains('active'));
|
|
344
|
+
clone.classList.toggle('zn-tb-active', source.classList.contains('zn-tb-active'));
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
|
|
155
348
|
public addItem(item: Element, persist: boolean = true): void {
|
|
156
349
|
const tabUri = item.getAttribute('tab-uri');
|
|
157
350
|
if (typeof tabUri !== 'string' || this._openedTabs.includes(tabUri)) {
|
|
@@ -174,21 +367,26 @@ export default class ZnNavbar extends ZincElement {
|
|
|
174
367
|
} else {
|
|
175
368
|
ul?.appendChild(item);
|
|
176
369
|
}
|
|
370
|
+
|
|
371
|
+
this._updateVisibility();
|
|
177
372
|
}
|
|
178
373
|
|
|
179
374
|
protected firstUpdated(_changedProperties: PropertyValues) {
|
|
180
375
|
super.firstUpdated(_changedProperties);
|
|
181
376
|
|
|
182
377
|
this._extendedMenu = this.shadowRoot?.querySelector('#extended-menu') as HTMLElement || null;
|
|
378
|
+
this.shadowRoot?.querySelector('#extended-dropdown')?.addEventListener('zn-show', this._syncExtendedActive);
|
|
183
379
|
this._expandable = this.shadowRoot?.querySelector('.navbar__container > div.expandables') as HTMLElement || null;
|
|
184
380
|
if (this._expandable) {
|
|
185
381
|
const computed = getComputedStyle(this._expandable);
|
|
186
|
-
this._expandableMargin =
|
|
382
|
+
this._expandableMargin = (parseFloat(computed.marginLeft) || 0) + (parseFloat(computed.marginRight) || 0);
|
|
383
|
+
this._resizeController.observe(this._expandable);
|
|
187
384
|
}
|
|
188
385
|
this._navItems = this.shadowRoot?.querySelector('.navbar__container > ul') as HTMLElement || null;
|
|
189
386
|
if (this._navItems) {
|
|
190
387
|
const computed = getComputedStyle(this._navItems);
|
|
191
|
-
this._navItemsGap =
|
|
388
|
+
this._navItemsGap = parseFloat(computed.columnGap) || 0;
|
|
389
|
+
this._resizeController.observe(this._navItems);
|
|
192
390
|
|
|
193
391
|
this._navItems.addEventListener('click', (e) => {
|
|
194
392
|
const target = (e.target as HTMLElement).closest('li[tab-uri]');
|
|
@@ -204,12 +402,13 @@ export default class ZnNavbar extends ZincElement {
|
|
|
204
402
|
// Load persisted tabs before calculating widths
|
|
205
403
|
this._loadStoredTabs();
|
|
206
404
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
405
|
+
if (this._navItems) {
|
|
406
|
+
this._itemsObserver.observe(this._navItems);
|
|
407
|
+
}
|
|
408
|
+
this._expanding.forEach(action => this._observeExpandingAction(action));
|
|
409
|
+
this._updateVisibility();
|
|
212
410
|
|
|
411
|
+
setTimeout(() => {
|
|
213
412
|
this.handleResize();
|
|
214
413
|
}, 100)
|
|
215
414
|
|
|
@@ -297,19 +496,20 @@ export default class ZnNavbar extends ZincElement {
|
|
|
297
496
|
}
|
|
298
497
|
};
|
|
299
498
|
|
|
499
|
+
protected updated(_changedProperties: PropertyValues) {
|
|
500
|
+
super.updated(_changedProperties);
|
|
501
|
+
if (_changedProperties.has('hideOne') || _changedProperties.has('navigation') || _changedProperties.has('_appended')) {
|
|
502
|
+
this._updateVisibility();
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
300
506
|
render() {
|
|
301
507
|
if (!this.navigation) {
|
|
302
508
|
this.navigation = [];
|
|
303
509
|
}
|
|
304
|
-
const itemCount = this.navigation?.length + this._preItems?.length + this._postItems?.length;
|
|
305
|
-
if (this._expanding.length === 0) {
|
|
306
|
-
if (itemCount === 0 || (itemCount < 2 && this.hideOne)) {
|
|
307
|
-
this.style.display = 'none';
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
510
|
|
|
311
511
|
return html`
|
|
312
|
-
<div class="${classMap({
|
|
512
|
+
<div part="container" class="${classMap({
|
|
313
513
|
'navbar__container': true,
|
|
314
514
|
'navbar__container--stacked': this.stacked,
|
|
315
515
|
'navbar__container--icon-bar': this.iconBar
|
|
@@ -332,10 +532,11 @@ export default class ZnNavbar extends ZincElement {
|
|
|
332
532
|
}
|
|
333
533
|
if (item.path != undefined) {
|
|
334
534
|
return html`
|
|
335
|
-
<li class="${classMap({'active': item.active})}" part="navbar-item" tab-uri="${item.path}">${content}
|
|
535
|
+
<li class="${classMap({'active': item.active})}" part="navbar-item" tab-uri="${item.path}">${content}
|
|
536
|
+
</li>`;
|
|
336
537
|
}
|
|
337
538
|
return html`
|
|
338
|
-
<li class="${classMap({
|
|
539
|
+
<li class="${classMap({'active': item.active})}"
|
|
339
540
|
part="navbar-item"
|
|
340
541
|
tab="${ifDefined(!this.isolated ? item.tab : undefined)}"
|
|
341
542
|
data-tab="${ifDefined(this.isolated ? item.tab : undefined)}">
|
|
@@ -345,7 +546,7 @@ export default class ZnNavbar extends ZincElement {
|
|
|
345
546
|
<li class="more">
|
|
346
547
|
<zn-dropdown placement="bottom-end" id="extended-dropdown">
|
|
347
548
|
<zn-button slot="trigger" text color="transparent">
|
|
348
|
-
<zn-icon src="
|
|
549
|
+
<zn-icon src="arrow_right_alt" size="16"></zn-icon>
|
|
349
550
|
</zn-button>
|
|
350
551
|
<ul id="extended-menu">
|
|
351
552
|
</ul>
|
|
@@ -369,6 +570,7 @@ export default class ZnNavbar extends ZincElement {
|
|
|
369
570
|
<slot name="expand"></slot>
|
|
370
571
|
</div>
|
|
371
572
|
` : ''}
|
|
372
|
-
</div
|
|
573
|
+
</div>
|
|
574
|
+
<slot name="bottom" part="bottom"></slot>`;
|
|
373
575
|
}
|
|
374
576
|
}
|