le-kit 0.2.1 → 0.2.3
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/cjs/le-icon.cjs.entry.js +3 -1
- package/dist/cjs/le-kit.cjs.js +1 -1
- package/dist/cjs/le-navigation.cjs.entry.js +109 -37
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/collection/components/le-icon/le-icon.js +3 -1
- package/dist/collection/components/le-icon/le-icon.js.map +1 -1
- package/dist/collection/components/le-navigation/le-navigation.css +4 -0
- package/dist/collection/components/le-navigation/le-navigation.js +152 -36
- package/dist/collection/components/le-navigation/le-navigation.js.map +1 -1
- package/dist/collection/dist/components/assets/custom-elements.json +5149 -5001
- package/dist/collection/dist/components/assets/icons/ellipsis-horizontal.json +14 -0
- package/dist/collection/dist/components/assets/icons/ellipsis-vertical.json +14 -0
- package/dist/collection/dist/components/assets/icons/hamburger.json +14 -0
- package/dist/collection/types/options.js.map +1 -1
- package/dist/components/assets/custom-elements.json +5149 -5001
- package/dist/components/assets/icons/ellipsis-horizontal.json +14 -0
- package/dist/components/assets/icons/ellipsis-vertical.json +14 -0
- package/dist/components/assets/icons/hamburger.json +14 -0
- package/dist/components/le-icon2.js +3 -1
- package/dist/components/le-icon2.js.map +1 -1
- package/dist/components/le-navigation.js +112 -37
- package/dist/components/le-navigation.js.map +1 -1
- package/dist/docs.json +95 -6
- package/dist/esm/le-icon.entry.js +3 -1
- package/dist/esm/le-icon.entry.js.map +1 -1
- package/dist/esm/le-kit.js +1 -1
- package/dist/esm/le-navigation.entry.js +109 -37
- package/dist/esm/le-navigation.entry.js.map +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/le-kit/dist/components/assets/custom-elements.json +5149 -5001
- package/dist/le-kit/dist/components/assets/icons/ellipsis-horizontal.json +14 -0
- package/dist/le-kit/dist/components/assets/icons/ellipsis-vertical.json +14 -0
- package/dist/le-kit/dist/components/assets/icons/hamburger.json +14 -0
- package/dist/le-kit/le-kit.esm.js +1 -1
- package/dist/le-kit/p-409db53a.entry.js +2 -0
- package/dist/le-kit/p-409db53a.entry.js.map +1 -0
- package/dist/le-kit/p-b78ae198.entry.js +2 -0
- package/dist/le-kit/p-b78ae198.entry.js.map +1 -0
- package/dist/types/components/le-navigation/le-navigation.d.ts +17 -0
- package/dist/types/components.d.ts +20 -0
- package/dist/types/types/options.d.ts +5 -0
- package/package.json +2 -2
- package/dist/le-kit/dist/components/themes/base.css +0 -89
- package/dist/le-kit/dist/components/themes/dark.css +0 -103
- package/dist/le-kit/dist/components/themes/default.css +0 -111
- package/dist/le-kit/dist/components/themes/gradient.css +0 -103
- package/dist/le-kit/dist/components/themes/index.css +0 -76
- package/dist/le-kit/dist/components/themes/minimal.css +0 -103
- package/dist/le-kit/dist/components/themes/warm.css +0 -103
- package/dist/le-kit/p-bb160082.entry.js +0 -2
- package/dist/le-kit/p-bb160082.entry.js.map +0 -1
- package/dist/le-kit/p-f2fa3bf5.entry.js +0 -2
- package/dist/le-kit/p-f2fa3bf5.entry.js.map +0 -1
- /package/dist/collection/dist/{components/themes → themes}/base.css +0 -0
- /package/dist/collection/dist/{components/themes → themes}/dark.css +0 -0
- /package/dist/collection/dist/{components/themes → themes}/default.css +0 -0
- /package/dist/collection/dist/{components/themes → themes}/gradient.css +0 -0
- /package/dist/collection/dist/{components/themes → themes}/index.css +0 -0
- /package/dist/collection/dist/{components/themes → themes}/minimal.css +0 -0
- /package/dist/collection/dist/{components/themes → themes}/warm.css +0 -0
- /package/dist/{components → le-kit/dist}/themes/base.css +0 -0
- /package/dist/{components → le-kit/dist}/themes/dark.css +0 -0
- /package/dist/{components → le-kit/dist}/themes/default.css +0 -0
- /package/dist/{components → le-kit/dist}/themes/gradient.css +0 -0
- /package/dist/{components → le-kit/dist}/themes/index.css +0 -0
- /package/dist/{components → le-kit/dist}/themes/minimal.css +0 -0
- /package/dist/{components → le-kit/dist}/themes/warm.css +0 -0
|
@@ -7,6 +7,9 @@ import { classnames, generateId } from "../../utils/utils";
|
|
|
7
7
|
* - Supports hierarchical items via `children`.
|
|
8
8
|
* - Supports persisted expansion via `open` on items.
|
|
9
9
|
*
|
|
10
|
+
* @slot hamburger-trigger - Custom trigger contents for the hamburger button
|
|
11
|
+
* @slot more-trigger - Custom trigger contents for the "More" button
|
|
12
|
+
*
|
|
10
13
|
* @cmsEditable true
|
|
11
14
|
* @cmsCategory Navigation
|
|
12
15
|
*/
|
|
@@ -32,6 +35,15 @@ export class LeNavigation {
|
|
|
32
35
|
* - hamburger: turns the whole nav into a hamburger popover
|
|
33
36
|
*/
|
|
34
37
|
overflowMode = 'more';
|
|
38
|
+
/**
|
|
39
|
+
* Minimum number of visible top-level items required to use the "More" overflow.
|
|
40
|
+
* If fewer would be visible, the navigation falls back to hamburger.
|
|
41
|
+
*/
|
|
42
|
+
minVisibleItemsForMore = 2;
|
|
43
|
+
/**
|
|
44
|
+
* Alignment of the hamburger trigger within the row.
|
|
45
|
+
*/
|
|
46
|
+
hamburgerAlign = 'start';
|
|
35
47
|
/**
|
|
36
48
|
* Active url for automatic selection.
|
|
37
49
|
*/
|
|
@@ -67,14 +79,30 @@ export class LeNavigation {
|
|
|
67
79
|
openState = {};
|
|
68
80
|
overflowIds = [];
|
|
69
81
|
hamburgerActive = false;
|
|
82
|
+
fallbackHamburger = false;
|
|
70
83
|
submenuQueries = {};
|
|
71
84
|
navContainerEl;
|
|
72
85
|
measureEl;
|
|
73
86
|
measureMoreEl;
|
|
74
87
|
topItemEls = new Map();
|
|
75
88
|
popoverRefs = new Map();
|
|
89
|
+
moreTriggerEl;
|
|
90
|
+
hamburgerPopoverEl;
|
|
91
|
+
morePopoverEl;
|
|
76
92
|
resizeObserver;
|
|
77
93
|
instanceId = generateId('le-nav');
|
|
94
|
+
partFromOptionPart(base, part) {
|
|
95
|
+
const raw = (part ?? '').trim();
|
|
96
|
+
if (!raw)
|
|
97
|
+
return base;
|
|
98
|
+
const tokens = raw
|
|
99
|
+
.split(/\s+/)
|
|
100
|
+
.map(t => t.replace(/[^a-zA-Z0-9_-]/g, ''))
|
|
101
|
+
.filter(Boolean);
|
|
102
|
+
if (tokens.length === 0)
|
|
103
|
+
return base;
|
|
104
|
+
return [base, ...tokens.map(t => `${base}-${t}`)].join(' ');
|
|
105
|
+
}
|
|
78
106
|
handleLayoutInputsChange() {
|
|
79
107
|
this.scheduleOverflowRecalc();
|
|
80
108
|
}
|
|
@@ -229,10 +257,12 @@ export class LeNavigation {
|
|
|
229
257
|
computeOverflow() {
|
|
230
258
|
// Only applies to horizontal, non-wrapping navs.
|
|
231
259
|
if (this.orientation !== 'horizontal' || this.wrap) {
|
|
232
|
-
if (this.overflowIds.length)
|
|
260
|
+
if (!this.overflowIds || this.overflowIds.length)
|
|
233
261
|
this.overflowIds = [];
|
|
234
262
|
if (this.hamburgerActive)
|
|
235
263
|
this.hamburgerActive = false;
|
|
264
|
+
if (this.fallbackHamburger)
|
|
265
|
+
this.fallbackHamburger = false;
|
|
236
266
|
return;
|
|
237
267
|
}
|
|
238
268
|
const container = this.navContainerEl;
|
|
@@ -247,12 +277,34 @@ export class LeNavigation {
|
|
|
247
277
|
if (shouldHamburger !== this.hamburgerActive) {
|
|
248
278
|
this.hamburgerActive = shouldHamburger;
|
|
249
279
|
}
|
|
250
|
-
if (this.overflowIds.length)
|
|
280
|
+
if (!this.overflowIds || this.overflowIds.length)
|
|
251
281
|
this.overflowIds = [];
|
|
282
|
+
if (this.fallbackHamburger)
|
|
283
|
+
this.fallbackHamburger = false;
|
|
252
284
|
return;
|
|
253
285
|
}
|
|
254
286
|
// overflowMode === 'more'
|
|
255
|
-
this.
|
|
287
|
+
if (this.hamburgerActive)
|
|
288
|
+
this.hamburgerActive = false;
|
|
289
|
+
const computedOverflow = this.computeOverflowMoreByWrap(availableWidth);
|
|
290
|
+
if (!computedOverflow)
|
|
291
|
+
return;
|
|
292
|
+
// Fallback to hamburger when "More" would leave too few items visible
|
|
293
|
+
// or when the trigger itself cannot fit the row.
|
|
294
|
+
const visibleCount = this.parsedItems.length - computedOverflow.length;
|
|
295
|
+
const moreWidth = this.moreTriggerEl?.getBoundingClientRect().width ?? 0;
|
|
296
|
+
const minVisible = Math.max(0, Number(this.minVisibleItemsForMore) || 0);
|
|
297
|
+
const shouldFallback = (computedOverflow.length > 0 && visibleCount < minVisible) ||
|
|
298
|
+
(moreWidth > 0 && moreWidth > availableWidth);
|
|
299
|
+
if (shouldFallback !== this.fallbackHamburger) {
|
|
300
|
+
this.fallbackHamburger = shouldFallback;
|
|
301
|
+
}
|
|
302
|
+
const nextOverflow = shouldFallback ? [] : computedOverflow;
|
|
303
|
+
const same = nextOverflow.length === this.overflowIds?.length &&
|
|
304
|
+
nextOverflow.every((v, i) => v === this.overflowIds[i]);
|
|
305
|
+
if (!same) {
|
|
306
|
+
this.overflowIds = nextOverflow;
|
|
307
|
+
}
|
|
256
308
|
}
|
|
257
309
|
computeOverflowMoreByWrap(availableWidth) {
|
|
258
310
|
const container = this.navContainerEl;
|
|
@@ -260,9 +312,17 @@ export class LeNavigation {
|
|
|
260
312
|
const measureMore = this.measureMoreEl;
|
|
261
313
|
const items = this.parsedItems;
|
|
262
314
|
if (!container || !measure)
|
|
263
|
-
return;
|
|
315
|
+
return null;
|
|
264
316
|
// Ensure measurement container matches visible container width.
|
|
265
317
|
measure.style.width = `${availableWidth}px`;
|
|
318
|
+
// Keep the measured "More" width aligned with the real trigger width (supports slotted content).
|
|
319
|
+
const realMoreWidth = this.moreTriggerEl?.getBoundingClientRect().width;
|
|
320
|
+
if (measureMore && realMoreWidth && realMoreWidth > 0) {
|
|
321
|
+
const btn = measureMore.querySelector('button');
|
|
322
|
+
if (btn) {
|
|
323
|
+
btn.style.width = `${realMoreWidth}px`;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
266
326
|
const allIds = this.getTopLevelIds(items);
|
|
267
327
|
const itemEls = allIds
|
|
268
328
|
.map(id => measure.querySelector(`[data-nav-id="${CSS.escape(id)}"]`))
|
|
@@ -275,10 +335,7 @@ export class LeNavigation {
|
|
|
275
335
|
measureMore.style.display = 'none';
|
|
276
336
|
}
|
|
277
337
|
if (itemEls.length === 0) {
|
|
278
|
-
|
|
279
|
-
this.overflowIds = [];
|
|
280
|
-
}
|
|
281
|
-
return;
|
|
338
|
+
return [];
|
|
282
339
|
}
|
|
283
340
|
const firstRowTop = Math.min(...itemEls.map(el => el.offsetTop));
|
|
284
341
|
const overflowSet = new Set();
|
|
@@ -291,10 +348,7 @@ export class LeNavigation {
|
|
|
291
348
|
overflowSet.add(id);
|
|
292
349
|
});
|
|
293
350
|
if (overflowSet.size === 0) {
|
|
294
|
-
|
|
295
|
-
this.overflowIds = [];
|
|
296
|
-
}
|
|
297
|
-
return;
|
|
351
|
+
return [];
|
|
298
352
|
}
|
|
299
353
|
// Pass 2: show "More" and iteratively move items into overflow until "More" fits on row 1.
|
|
300
354
|
if (measureMore) {
|
|
@@ -325,11 +379,7 @@ export class LeNavigation {
|
|
|
325
379
|
overflowSet.add(lastId);
|
|
326
380
|
}
|
|
327
381
|
const overflowIds = allIds.filter(id => overflowSet.has(id));
|
|
328
|
-
|
|
329
|
-
overflowIds.every((v, i) => v === this.overflowIds[i]);
|
|
330
|
-
if (!same) {
|
|
331
|
-
this.overflowIds = overflowIds;
|
|
332
|
-
}
|
|
382
|
+
return overflowIds;
|
|
333
383
|
}
|
|
334
384
|
renderHorizontalMeasureItem(item, index) {
|
|
335
385
|
const id = this.getItemId(item, String(index));
|
|
@@ -342,9 +392,9 @@ export class LeNavigation {
|
|
|
342
392
|
if (!hasChildren) {
|
|
343
393
|
return (h("div", { class: "h-item", ref: setRef, "data-nav-id": id }, h("span", { class: "h-link" }, item.iconStart && (h("span", { class: "nav-icon", "aria-hidden": "true" }, item.iconStart)), h("span", { class: "h-label" }, item.label), item.iconEnd && (h("span", { class: "nav-icon nav-icon-end", "aria-hidden": "true" }, item.iconEnd)))));
|
|
344
394
|
}
|
|
345
|
-
return (h("div", { class: "h-item", ref: setRef, "data-nav-id": id }, h("span", { class: "h-trigger" }, h("span", { class: "h-link" }, item.iconStart && (h("span", { class: "nav-icon", "aria-hidden": "true" }, item.iconStart)), h("span", { class: "h-label" }, item.label)), h("span", { class: "h-submenu-toggle", "aria-hidden": "true" }, h("
|
|
395
|
+
return (h("div", { class: "h-item", ref: setRef, "data-nav-id": id }, h("span", { class: "h-trigger" }, h("span", { class: "h-link" }, item.iconStart && (h("span", { class: "nav-icon", "aria-hidden": "true" }, item.iconStart)), h("span", { class: "h-label" }, item.label)), h("span", { class: "h-submenu-toggle", "aria-hidden": "true" }, h("le-icon", { name: "chevron-down" })))));
|
|
346
396
|
}
|
|
347
|
-
renderVerticalList(items, { depth, pathPrefix, autoOpenIds, searchable, searchQuery, searchPlaceholder, emptyText, submenuId, }) {
|
|
397
|
+
renderVerticalList(items, { depth, pathPrefix, autoOpenIds, searchable, searchQuery, searchPlaceholder, emptyText, submenuId, closePopover, }) {
|
|
348
398
|
const query = searchQuery ?? '';
|
|
349
399
|
const openFromSearch = autoOpenIds ?? new Set();
|
|
350
400
|
const filtered = query ? this.filterTree(items, query, pathPrefix, openFromSearch) : items;
|
|
@@ -359,21 +409,28 @@ export class LeNavigation {
|
|
|
359
409
|
const attrs = TagType === 'a'
|
|
360
410
|
? { href: item.href, role: 'treeitem' }
|
|
361
411
|
: { type: 'button', role: 'treeitem' };
|
|
412
|
+
const itemPart = this.partFromOptionPart('item', item.part);
|
|
362
413
|
return (h("li", { class: classnames('nav-node', {
|
|
363
414
|
'disabled': item.disabled,
|
|
364
415
|
'selected': item.selected || (this.activeUrl && item.href === this.activeUrl),
|
|
365
416
|
open,
|
|
366
417
|
'has-children': hasChildren,
|
|
367
|
-
}), key: id, role: "none" }, h("div", { class: "nav-row", style: { paddingLeft } }, hasChildren ? (h("button", { type: "button", class: "nav-toggle", "aria-label": open ? 'Collapse' : 'Expand', "aria-expanded": open ? 'true' : 'false', onClick: (e) => this.handleToggle(e, item, id), disabled: item.disabled }, h("le-icon", { name: "chevron-down", class: "nav-chevron", "aria-hidden": "true" }))) : (h("span", { class: "nav-toggle-spacer", "aria-hidden": "true" })), h(TagType, { class: "nav-item", ...attrs, "aria-disabled": item.disabled ? 'true' : undefined, onClick: (e) => {
|
|
418
|
+
}), key: id, role: "none" }, h("div", { class: "nav-row", style: { paddingLeft } }, hasChildren ? (h("button", { type: "button", class: "nav-toggle", "aria-label": open ? 'Collapse' : 'Expand', "aria-expanded": open ? 'true' : 'false', onClick: (e) => this.handleToggle(e, item, id), disabled: item.disabled }, h("le-icon", { name: "chevron-down", class: "nav-chevron", "aria-hidden": "true" }))) : (h("span", { class: "nav-toggle-spacer", "aria-hidden": "true" })), h(TagType, { class: "nav-item", part: itemPart, ...attrs, "aria-disabled": item.disabled ? 'true' : undefined, onClick: (e) => {
|
|
368
419
|
// For buttons, also toggle if this is a purely structural node.
|
|
369
420
|
this.handleItemSelect(e, item, id);
|
|
370
421
|
if (!item.href && hasChildren && !item.disabled) {
|
|
371
422
|
this.handleToggle(e, item, id);
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
if (!item.disabled && closePopover) {
|
|
426
|
+
closePopover();
|
|
372
427
|
}
|
|
373
428
|
} }, item.iconStart && (h("span", { class: "nav-icon", "aria-hidden": "true" }, item.iconStart)), h("span", { class: "nav-text" }, h("span", { class: "nav-label" }, item.label), item.description && (h("span", { class: "nav-description" }, item.description))), item.iconEnd && (h("span", { class: "nav-icon nav-icon-end", "aria-hidden": "true" }, item.iconEnd)))), hasChildren && (h("le-collapse", { class: "nav-children", closed: !open, noFading: true, role: "group" }, this.renderVerticalList(children, {
|
|
374
429
|
depth: depth + 1,
|
|
375
430
|
pathPrefix: path,
|
|
376
431
|
autoOpenIds: openFromSearch,
|
|
432
|
+
submenuId,
|
|
433
|
+
closePopover,
|
|
377
434
|
})))));
|
|
378
435
|
})))));
|
|
379
436
|
}
|
|
@@ -386,25 +443,28 @@ export class LeNavigation {
|
|
|
386
443
|
const attrs = TagType === 'a'
|
|
387
444
|
? { href: item.href, role: 'menuitem' }
|
|
388
445
|
: { type: 'button', role: 'menuitem' };
|
|
446
|
+
const itemPart = this.partFromOptionPart('item', item.part);
|
|
389
447
|
return (h("div", { class: "h-item" }, h(TagType, { class: classnames('h-link', {
|
|
390
448
|
disabled: item.disabled,
|
|
391
449
|
selected: item.selected || (this.activeUrl && item.href === this.activeUrl),
|
|
392
|
-
}), ...attrs, "aria-disabled": item.disabled ? 'true' : undefined, onClick: (e) => this.handleItemSelect(e, item, id) }, item.iconStart && (h("span", { class: "nav-icon", "aria-hidden": "true" }, item.iconStart)), h("span", { class: "h-label" }, item.label), item.iconEnd && (h("span", { class: "nav-icon nav-icon-end", "aria-hidden": "true" }, item.iconEnd)))));
|
|
450
|
+
}), part: itemPart, ...attrs, "aria-disabled": item.disabled ? 'true' : undefined, onClick: (e) => this.handleItemSelect(e, item, id) }, item.iconStart && (h("span", { class: "nav-icon", "aria-hidden": "true" }, item.iconStart)), h("span", { class: "h-label" }, item.label), item.iconEnd && (h("span", { class: "nav-icon nav-icon-end", "aria-hidden": "true" }, item.iconEnd)))));
|
|
393
451
|
}
|
|
394
452
|
const submenuId = id;
|
|
453
|
+
const itemPart = this.partFromOptionPart('item', item.part);
|
|
395
454
|
return (h("div", { class: "h-item" }, h("le-popover", { ref: el => {
|
|
396
455
|
if (el)
|
|
397
456
|
this.popoverRefs.set(submenuId, el);
|
|
398
457
|
}, mode: "default", showClose: false, closeOnClickOutside: true, closeOnEscape: true, position: "bottom", align: "start", minWidth: "240px" }, h("div", { slot: "trigger", class: classnames('h-trigger', {
|
|
399
458
|
disabled: item.disabled,
|
|
400
459
|
selected: item.selected || (this.activeUrl && item.href === this.activeUrl),
|
|
401
|
-
}), role: "menuitem", "aria-disabled": item.disabled ? 'true' : undefined, onClick: (e) => {
|
|
460
|
+
}), part: itemPart, role: "menuitem", "aria-disabled": item.disabled ? 'true' : undefined, onClick: (e) => {
|
|
402
461
|
// Don’t let le-popover auto-toggle from its internal wrapper.
|
|
403
462
|
e.stopPropagation();
|
|
404
463
|
if (item.disabled)
|
|
405
464
|
return;
|
|
406
465
|
if (item.href) {
|
|
407
466
|
this.handleItemSelect(e, item, id);
|
|
467
|
+
this.popoverRefs.get(submenuId)?.hide();
|
|
408
468
|
}
|
|
409
469
|
else {
|
|
410
470
|
this.popoverRefs.get(submenuId)?.toggle();
|
|
@@ -412,18 +472,12 @@ export class LeNavigation {
|
|
|
412
472
|
} }, item.href ? (h("a", { class: "h-link", href: item.href, onClick: (e) => {
|
|
413
473
|
e.stopPropagation();
|
|
414
474
|
this.handleItemSelect(e, item, id);
|
|
415
|
-
} }, item.iconStart && (h("span", { class: "nav-icon", "aria-hidden": "true" }, item.iconStart)), h("span", { class: "h-label" }, item.label))) : (h("button", { type: "button", class: "h-link", onClick: (e) => {
|
|
475
|
+
} }, item.iconStart && (h("span", { class: "nav-icon", "aria-hidden": "true" }, item.iconStart)), h("span", { class: "h-label" }, item.label), h("span", { class: "nav-chevron", "aria-hidden": "true" }, h("le-icon", { name: "chevron-down" })))) : (h("button", { type: "button", class: "h-link", onClick: (e) => {
|
|
416
476
|
e.stopPropagation();
|
|
417
477
|
if (item.disabled)
|
|
418
478
|
return;
|
|
419
479
|
this.popoverRefs.get(submenuId)?.toggle();
|
|
420
|
-
} }, item.iconStart && (h("span", { class: "nav-icon", "aria-hidden": "true" }, item.iconStart)), h("span", { class: "h-label" }, item.label)
|
|
421
|
-
e.preventDefault();
|
|
422
|
-
e.stopPropagation();
|
|
423
|
-
if (item.disabled)
|
|
424
|
-
return;
|
|
425
|
-
this.popoverRefs.get(submenuId)?.toggle();
|
|
426
|
-
} }, h("span", { class: "nav-chevron", "aria-hidden": "true" }, h("le-icon", { name: "chevron-down" })))), h("div", { class: "popover-menu" }, this.renderVerticalList(children, {
|
|
480
|
+
} }, item.iconStart && (h("span", { class: "nav-icon", "aria-hidden": "true" }, item.iconStart)), h("span", { class: "h-label" }, item.label), h("span", { class: "nav-chevron", "aria-hidden": "true" }, h("le-icon", { name: "chevron-down" }))))), h("div", { class: "popover-menu" }, this.renderVerticalList(children, {
|
|
427
481
|
depth: 0,
|
|
428
482
|
pathPrefix: String(index),
|
|
429
483
|
searchable: this.submenuSearchable,
|
|
@@ -431,6 +485,7 @@ export class LeNavigation {
|
|
|
431
485
|
searchPlaceholder: this.searchPlaceholder,
|
|
432
486
|
emptyText: this.emptyText,
|
|
433
487
|
submenuId,
|
|
488
|
+
closePopover: () => this.popoverRefs.get(submenuId)?.hide(),
|
|
434
489
|
})))));
|
|
435
490
|
}
|
|
436
491
|
renderHorizontal() {
|
|
@@ -443,24 +498,35 @@ export class LeNavigation {
|
|
|
443
498
|
overflowItems.push(item);
|
|
444
499
|
}
|
|
445
500
|
});
|
|
446
|
-
|
|
447
|
-
|
|
501
|
+
const showHamburger = !this.wrap &&
|
|
502
|
+
((this.overflowMode === 'hamburger' && this.hamburgerActive) ||
|
|
503
|
+
(this.overflowMode === 'more' && this.fallbackHamburger));
|
|
504
|
+
// Hamburger mode: show a single trigger if anything overflows (or when forced for "more").
|
|
505
|
+
if (showHamburger) {
|
|
448
506
|
return (h("div", { class: "nav-horizontal-shell" }, h("div", { class: "nav-horizontal-measure", "aria-hidden": "true", ref: el => {
|
|
449
507
|
this.measureEl = el;
|
|
450
508
|
} }, items.map((item, index) => this.renderHorizontalMeasureItem(item, index)), h("div", { class: "h-item", ref: el => {
|
|
451
509
|
this.measureMoreEl = el;
|
|
452
|
-
} }, h("button", { type: "button", class: "overflow-trigger" }, "More"))), h("div", { class:
|
|
510
|
+
} }, h("button", { type: "button", class: "overflow-trigger" }, "More"))), h("div", { class: classnames('nav-horizontal', {
|
|
511
|
+
'hamburger-align-end': this.hamburgerAlign === 'end',
|
|
512
|
+
}), ref: el => {
|
|
453
513
|
this.navContainerEl = el;
|
|
454
514
|
this.setupResizeObserver();
|
|
455
515
|
this.observeContainer(this.navContainerEl);
|
|
456
|
-
} }, h("le-popover", {
|
|
516
|
+
} }, h("le-popover", { ref: el => {
|
|
517
|
+
this.hamburgerPopoverEl = el;
|
|
518
|
+
}, mode: "default", showClose: false, closeOnClickOutside: true, closeOnEscape: true, position: "bottom", align: "end", minWidth: "260px" }, h("button", { slot: "trigger", type: "button", class: "overflow-trigger", part: "hamburger-trigger", "aria-label": "Open menu" }, h("slot", { name: "hamburger-trigger" }, h("le-icon", { name: "hamburger" }))), h("div", { class: "popover-menu" }, this.renderVerticalList(items, {
|
|
519
|
+
depth: 0,
|
|
520
|
+
pathPrefix: '',
|
|
521
|
+
closePopover: () => this.hamburgerPopoverEl?.hide(),
|
|
522
|
+
}))))));
|
|
457
523
|
}
|
|
458
524
|
const showMore = !this.wrap && this.overflowMode === 'more' && overflowItems.length > 0;
|
|
459
525
|
return (h("div", { class: "nav-horizontal-shell", role: "menubar" }, h("div", { class: "nav-horizontal-measure", "aria-hidden": "true", ref: el => {
|
|
460
526
|
this.measureEl = el;
|
|
461
527
|
} }, items.map((item, index) => this.renderHorizontalMeasureItem(item, index)), h("div", { class: "h-item", ref: el => {
|
|
462
528
|
this.measureMoreEl = el;
|
|
463
|
-
} }, h("button", { type: "button", class: "overflow-trigger" }, "
|
|
529
|
+
} }, h("button", { type: "button", class: "overflow-trigger" }, h("le-icon", { name: "ellipsis-horizontal" })))), h("div", { class: classnames('nav-horizontal', {
|
|
464
530
|
wrap: this.wrap,
|
|
465
531
|
nowrap: !this.wrap,
|
|
466
532
|
}), ref: el => {
|
|
@@ -476,7 +542,16 @@ export class LeNavigation {
|
|
|
476
542
|
}), h("div", { class: classnames('more-trigger-wrap', {
|
|
477
543
|
'is-visible': showMore,
|
|
478
544
|
'is-measure': !showMore,
|
|
479
|
-
}) }, h("le-popover", {
|
|
545
|
+
}) }, h("le-popover", { ref: el => {
|
|
546
|
+
this.morePopoverEl = el;
|
|
547
|
+
}, mode: "default", position: "bottom", align: "end", minWidth: "260px", showClose: false }, h("button", { slot: "trigger", type: "button", class: "overflow-trigger", part: "more-trigger", "aria-label": "More", ref: el => {
|
|
548
|
+
if (el)
|
|
549
|
+
this.moreTriggerEl = el;
|
|
550
|
+
} }, h("slot", { name: "more-trigger" }, h("le-icon", { name: "ellipsis-horizontal" }))), h("div", { class: "popover-menu" }, this.renderVerticalList(overflowItems, {
|
|
551
|
+
depth: 0,
|
|
552
|
+
pathPrefix: '',
|
|
553
|
+
closePopover: () => this.morePopoverEl?.hide(),
|
|
554
|
+
})))))));
|
|
480
555
|
}
|
|
481
556
|
render() {
|
|
482
557
|
const items = this.parsedItems;
|
|
@@ -592,6 +667,46 @@ export class LeNavigation {
|
|
|
592
667
|
"attribute": "overflow-mode",
|
|
593
668
|
"defaultValue": "'more'"
|
|
594
669
|
},
|
|
670
|
+
"minVisibleItemsForMore": {
|
|
671
|
+
"type": "number",
|
|
672
|
+
"mutable": false,
|
|
673
|
+
"complexType": {
|
|
674
|
+
"original": "number",
|
|
675
|
+
"resolved": "number",
|
|
676
|
+
"references": {}
|
|
677
|
+
},
|
|
678
|
+
"required": false,
|
|
679
|
+
"optional": false,
|
|
680
|
+
"docs": {
|
|
681
|
+
"tags": [],
|
|
682
|
+
"text": "Minimum number of visible top-level items required to use the \"More\" overflow.\nIf fewer would be visible, the navigation falls back to hamburger."
|
|
683
|
+
},
|
|
684
|
+
"getter": false,
|
|
685
|
+
"setter": false,
|
|
686
|
+
"reflect": false,
|
|
687
|
+
"attribute": "min-visible-items-for-more",
|
|
688
|
+
"defaultValue": "2"
|
|
689
|
+
},
|
|
690
|
+
"hamburgerAlign": {
|
|
691
|
+
"type": "string",
|
|
692
|
+
"mutable": false,
|
|
693
|
+
"complexType": {
|
|
694
|
+
"original": "'start' | 'end'",
|
|
695
|
+
"resolved": "\"end\" | \"start\"",
|
|
696
|
+
"references": {}
|
|
697
|
+
},
|
|
698
|
+
"required": false,
|
|
699
|
+
"optional": false,
|
|
700
|
+
"docs": {
|
|
701
|
+
"tags": [],
|
|
702
|
+
"text": "Alignment of the hamburger trigger within the row."
|
|
703
|
+
},
|
|
704
|
+
"getter": false,
|
|
705
|
+
"setter": false,
|
|
706
|
+
"reflect": true,
|
|
707
|
+
"attribute": "hamburger-align",
|
|
708
|
+
"defaultValue": "'start'"
|
|
709
|
+
},
|
|
595
710
|
"activeUrl": {
|
|
596
711
|
"type": "string",
|
|
597
712
|
"mutable": false,
|
|
@@ -700,6 +815,7 @@ export class LeNavigation {
|
|
|
700
815
|
"openState": {},
|
|
701
816
|
"overflowIds": {},
|
|
702
817
|
"hamburgerActive": {},
|
|
818
|
+
"fallbackHamburger": {},
|
|
703
819
|
"submenuQueries": {}
|
|
704
820
|
};
|
|
705
821
|
}
|