structra-ui 0.2.54 → 0.2.55
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/fesm2022/structra-ui.mjs +351 -56
- package/fesm2022/structra-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/types/structra-ui.d.ts +47 -6
package/fesm2022/structra-ui.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import '../structra-ui.css';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { signal, booleanAttribute, Input, HostBinding, ChangeDetectionStrategy, Component, ElementRef, ViewChild, inject, ChangeDetectorRef, Injector, DestroyRef, EventEmitter, Output, Directive, numberAttribute, computed, Injectable, input, output, HostListener, ViewChildren, forwardRef, ApplicationRef,
|
|
3
|
+
import { signal, booleanAttribute, Input, HostBinding, ChangeDetectionStrategy, Component, ElementRef, ViewChild, inject, ChangeDetectorRef, Injector, DestroyRef, EventEmitter, Output, Directive, numberAttribute, computed, Injectable, input, output, afterNextRender, HostListener, ViewChildren, forwardRef, ApplicationRef, ContentChildren, NgZone, Renderer2, effect, TemplateRef, ContentChild } from '@angular/core';
|
|
4
4
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
5
5
|
import * as i1 from '@angular/forms';
|
|
6
6
|
import { Validators, FormGroupDirective, NgForm, NgControl, NG_VALUE_ACCESSOR, FormsModule, FormGroup, FormArray, FormControl } from '@angular/forms';
|
|
@@ -1186,6 +1186,19 @@ function buildMenuRows(nodes) {
|
|
|
1186
1186
|
}
|
|
1187
1187
|
return rows;
|
|
1188
1188
|
}
|
|
1189
|
+
/**
|
|
1190
|
+
* Compara ids de itens do menu (rotas, chaves de navegação).
|
|
1191
|
+
* Evita falhas quando o modelo usa `string` e o estado activo vem como `number` (ou o contrário).
|
|
1192
|
+
*/
|
|
1193
|
+
function menuItemIdsEqual(a, b) {
|
|
1194
|
+
if (Object.is(a, b)) {
|
|
1195
|
+
return true;
|
|
1196
|
+
}
|
|
1197
|
+
if (a == null || b == null) {
|
|
1198
|
+
return false;
|
|
1199
|
+
}
|
|
1200
|
+
return String(a) === String(b);
|
|
1201
|
+
}
|
|
1189
1202
|
function focusableActionCount(rows) {
|
|
1190
1203
|
return rows.filter((r) => (r.kind === 'action' || r.kind === 'submenu') && r.focusIndex !== null).length;
|
|
1191
1204
|
}
|
|
@@ -1199,7 +1212,7 @@ function menuNodeTreeContainsId(items, selectedId) {
|
|
|
1199
1212
|
continue;
|
|
1200
1213
|
}
|
|
1201
1214
|
if (node.kind === 'item') {
|
|
1202
|
-
if (node.id
|
|
1215
|
+
if (menuItemIdsEqual(node.id, selectedId)) {
|
|
1203
1216
|
return true;
|
|
1204
1217
|
}
|
|
1205
1218
|
}
|
|
@@ -1233,7 +1246,7 @@ function collectGroupIdsContainingSelectedItem(nodes, selectedId) {
|
|
|
1233
1246
|
}
|
|
1234
1247
|
}
|
|
1235
1248
|
else if (n.kind === 'item') {
|
|
1236
|
-
if (n.id
|
|
1249
|
+
if (menuItemIdsEqual(n.id, selectedId)) {
|
|
1237
1250
|
hit = true;
|
|
1238
1251
|
}
|
|
1239
1252
|
}
|
|
@@ -1342,8 +1355,17 @@ function purgeMenuGroupExpansionStorageAfterReload() {
|
|
|
1342
1355
|
}
|
|
1343
1356
|
class MenuListBodyComponent {
|
|
1344
1357
|
constructor(cdr, hostRef) {
|
|
1358
|
+
this.destroyRef = inject(DestroyRef);
|
|
1359
|
+
this.injector = inject(Injector);
|
|
1345
1360
|
/** Igual a `[appTheme]` na lib; omitir = tema global (ex.: propagado por `app-sidebar`). */
|
|
1346
1361
|
this.appTheme = input(...(ngDevMode ? [undefined, { debugName: "appTheme" }] : /* istanbul ignore next */ []));
|
|
1362
|
+
/**
|
|
1363
|
+
* Emitido após sincronizar expansão de grupos / submenu com `selectedItemId` no próximo render.
|
|
1364
|
+
* A sidebar usa isto para voltar a correr o scroll até ao `--selected` (ex.: drawer mobile `@if (open)`).
|
|
1365
|
+
*/
|
|
1366
|
+
this.selectionScrollHint = output();
|
|
1367
|
+
/** Invalida callbacks `afterNextRender` pendentes do hint de scroll. */
|
|
1368
|
+
this.selectionLayoutHintGen = 0;
|
|
1347
1369
|
this.items = [];
|
|
1348
1370
|
/** Prefixo dos `id` das opções focáveis (`${menuId}-opt-${focusIndex}`). */
|
|
1349
1371
|
this.menuId = 'app-menu';
|
|
@@ -1411,6 +1433,12 @@ class MenuListBodyComponent {
|
|
|
1411
1433
|
this.cdr = cdr;
|
|
1412
1434
|
this.hostRef = hostRef;
|
|
1413
1435
|
this.effectiveThemeId = injectEffectiveThemeId(this.appTheme);
|
|
1436
|
+
this.destroyRef.onDestroy(() => {
|
|
1437
|
+
this.selectionLayoutHintGen++;
|
|
1438
|
+
});
|
|
1439
|
+
}
|
|
1440
|
+
ngAfterViewInit() {
|
|
1441
|
+
this.scheduleSelectionLayoutHintAfterRender();
|
|
1414
1442
|
}
|
|
1415
1443
|
overlayPanelClasses() {
|
|
1416
1444
|
return [...getThemeClassList(this.effectiveThemeId()), 'menu-submenu__cdk-panel'];
|
|
@@ -1459,18 +1487,13 @@ class MenuListBodyComponent {
|
|
|
1459
1487
|
this.activeIndex = this.focusableCount - 1;
|
|
1460
1488
|
}
|
|
1461
1489
|
}
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
}
|
|
1470
|
-
else if (this.activeIndex >= this.focusableCount) {
|
|
1471
|
-
this.activeIndex = this.focusableCount - 1;
|
|
1472
|
-
}
|
|
1473
|
-
}
|
|
1490
|
+
/**
|
|
1491
|
+
* Fim da cadeia `if / else if`: mudanças só em `selectedItemId` já não tinham ramo próprio e,
|
|
1492
|
+
* em alguns ciclos, `selectedItemId` combinava com `groupCollapsible` / outros — o ramo errado
|
|
1493
|
+
* impedia `ensureExpandedGroupsForSelection`. Reconciliar sempre que o caminho da selecção importa.
|
|
1494
|
+
*/
|
|
1495
|
+
if (this.shouldReconcileSelectionPath(changes)) {
|
|
1496
|
+
this.reconcileSelectionPathSync();
|
|
1474
1497
|
}
|
|
1475
1498
|
if (changes['selectedItemId'] ||
|
|
1476
1499
|
changes['items'] ||
|
|
@@ -1484,6 +1507,71 @@ class MenuListBodyComponent {
|
|
|
1484
1507
|
changes['persistGroupExpansion']) {
|
|
1485
1508
|
this.cdr.markForCheck();
|
|
1486
1509
|
}
|
|
1510
|
+
if (this.shouldScheduleSelectionScrollHint(changes)) {
|
|
1511
|
+
this.scheduleSelectionLayoutHintAfterRender();
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
shouldReconcileSelectionPath(changes) {
|
|
1515
|
+
return !!(changes['selectedItemId'] ||
|
|
1516
|
+
changes['items'] ||
|
|
1517
|
+
changes['expandAllGroupsInitially'] ||
|
|
1518
|
+
changes['compressText'] ||
|
|
1519
|
+
changes['groupCollapsible'] ||
|
|
1520
|
+
changes['groupDefaultExpansion'] ||
|
|
1521
|
+
changes['persistGroupExpansion'] ||
|
|
1522
|
+
changes['clickToOpen']);
|
|
1523
|
+
}
|
|
1524
|
+
shouldScheduleSelectionScrollHint(changes) {
|
|
1525
|
+
return this.shouldReconcileSelectionPath(changes);
|
|
1526
|
+
}
|
|
1527
|
+
/**
|
|
1528
|
+
* Garante expansão + submenu para a rota activa depois do {@link MenuListComponent} ter referência
|
|
1529
|
+
* ao `ViewChild` (caso típico do drawer mobile).
|
|
1530
|
+
*/
|
|
1531
|
+
syncRouteSelectionExpansion() {
|
|
1532
|
+
if ((this.items?.length ?? 0) > 0 && !this.rows.length) {
|
|
1533
|
+
this.rebuildRowsFromItems();
|
|
1534
|
+
this.selectionScrollHint.emit();
|
|
1535
|
+
return;
|
|
1536
|
+
}
|
|
1537
|
+
this.reconcileSelectionPathSync();
|
|
1538
|
+
this.selectionScrollHint.emit();
|
|
1539
|
+
}
|
|
1540
|
+
/** Abre grupos no caminho da rota activa e submenu em modo clique — síncrono após inputs. */
|
|
1541
|
+
reconcileSelectionPathSync() {
|
|
1542
|
+
if (!this.rows.length) {
|
|
1543
|
+
if ((this.items?.length ?? 0) > 0) {
|
|
1544
|
+
this.rebuildRowsFromItems();
|
|
1545
|
+
}
|
|
1546
|
+
return;
|
|
1547
|
+
}
|
|
1548
|
+
let touched = false;
|
|
1549
|
+
if (this.ensureExpandedGroupsForSelection()) {
|
|
1550
|
+
this.syncDisplayRows();
|
|
1551
|
+
touched = true;
|
|
1552
|
+
}
|
|
1553
|
+
if (this.ensureSubmenuOpenForSelection()) {
|
|
1554
|
+
touched = true;
|
|
1555
|
+
}
|
|
1556
|
+
if (touched) {
|
|
1557
|
+
if (this.focusableCount === 0) {
|
|
1558
|
+
this.activeIndex = -1;
|
|
1559
|
+
}
|
|
1560
|
+
else if (this.activeIndex >= this.focusableCount) {
|
|
1561
|
+
this.activeIndex = this.focusableCount - 1;
|
|
1562
|
+
}
|
|
1563
|
+
this.cdr.markForCheck();
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
scheduleSelectionLayoutHintAfterRender() {
|
|
1567
|
+
const gen = ++this.selectionLayoutHintGen;
|
|
1568
|
+
afterNextRender(() => {
|
|
1569
|
+
if (gen !== this.selectionLayoutHintGen) {
|
|
1570
|
+
return;
|
|
1571
|
+
}
|
|
1572
|
+
this.reconcileSelectionPathSync();
|
|
1573
|
+
this.selectionScrollHint.emit();
|
|
1574
|
+
}, { injector: this.injector });
|
|
1487
1575
|
}
|
|
1488
1576
|
getRowsSourceItems() {
|
|
1489
1577
|
return [...(this.items ?? [])];
|
|
@@ -1505,6 +1593,7 @@ class MenuListBodyComponent {
|
|
|
1505
1593
|
this.activeIndex = -1;
|
|
1506
1594
|
}
|
|
1507
1595
|
this.applySearchSubmenuAutoOpen();
|
|
1596
|
+
this.ensureSubmenuOpenForSelection();
|
|
1508
1597
|
}
|
|
1509
1598
|
/**
|
|
1510
1599
|
* Com pesquisa activa (lista filtrada), abre o primeiro submenu deste nível que
|
|
@@ -1626,13 +1715,11 @@ class MenuListBodyComponent {
|
|
|
1626
1715
|
}
|
|
1627
1716
|
/**
|
|
1628
1717
|
* Abre todos os grupos no caminho até ao item com `selectedItemId` (árvore alinhada a {@link buildMenuRows}).
|
|
1629
|
-
*
|
|
1718
|
+
* Corre também com `compressText` activo para `expandedGroupIds` ficar correcto quando o rail termina;
|
|
1719
|
+
* com texto comprimido, {@link isGroupExpanded} continua a mostrar todas as linhas na lista.
|
|
1630
1720
|
*/
|
|
1631
1721
|
ensureExpandedGroupsForSelection() {
|
|
1632
|
-
if (this.selectedItemId == null ||
|
|
1633
|
-
!this.groupCollapsible ||
|
|
1634
|
-
this.compressText ||
|
|
1635
|
-
this.expandAllGroupsInitially) {
|
|
1722
|
+
if (this.selectedItemId == null || !this.groupCollapsible) {
|
|
1636
1723
|
return false;
|
|
1637
1724
|
}
|
|
1638
1725
|
const gids = collectGroupIdsContainingSelectedItem(this.getRowsSourceItems(), this.selectedItemId);
|
|
@@ -1652,6 +1739,45 @@ class MenuListBodyComponent {
|
|
|
1652
1739
|
}
|
|
1653
1740
|
return changed;
|
|
1654
1741
|
}
|
|
1742
|
+
/**
|
|
1743
|
+
* Com `clickToOpen`, após remount ou mudança de `selectedItemId`, abre o submenu que contém a folha activa
|
|
1744
|
+
* para o realce ficar visível. Em modo rail (`compressText`) os grupos parecem sempre abertos, mas
|
|
1745
|
+
* `expandedGroupIds` ainda precisa do caminho para quando o texto deixa de estar comprimido.
|
|
1746
|
+
* Fecha o painel se a selecção já não estiver sob nenhum submenu deste nível.
|
|
1747
|
+
*/
|
|
1748
|
+
ensureSubmenuOpenForSelection() {
|
|
1749
|
+
if (!this.clickToOpen) {
|
|
1750
|
+
return false;
|
|
1751
|
+
}
|
|
1752
|
+
if (this.selectedItemId == null) {
|
|
1753
|
+
if (this.openSubmenuKey !== null) {
|
|
1754
|
+
this.openSubmenuKey = null;
|
|
1755
|
+
return true;
|
|
1756
|
+
}
|
|
1757
|
+
return false;
|
|
1758
|
+
}
|
|
1759
|
+
for (let i = 0; i < this.displayRows.length; i++) {
|
|
1760
|
+
const row = this.displayRows[i];
|
|
1761
|
+
if (row.kind !== 'submenu' || row.item.disabled) {
|
|
1762
|
+
continue;
|
|
1763
|
+
}
|
|
1764
|
+
if (!menuNodeTreeContainsId(row.item.items, this.selectedItemId)) {
|
|
1765
|
+
continue;
|
|
1766
|
+
}
|
|
1767
|
+
const key = this.submenuRowKey(row, i);
|
|
1768
|
+
if (this.openSubmenuKey === key) {
|
|
1769
|
+
return false;
|
|
1770
|
+
}
|
|
1771
|
+
this.openSubmenuKey = key;
|
|
1772
|
+
this.queueFocusNestedFirst();
|
|
1773
|
+
return true;
|
|
1774
|
+
}
|
|
1775
|
+
if (this.openSubmenuKey !== null) {
|
|
1776
|
+
this.openSubmenuKey = null;
|
|
1777
|
+
return true;
|
|
1778
|
+
}
|
|
1779
|
+
return false;
|
|
1780
|
+
}
|
|
1655
1781
|
syncDisplayRows() {
|
|
1656
1782
|
const visible = this.rows.filter((r) => this.isRowVisible(r));
|
|
1657
1783
|
let fi = 0;
|
|
@@ -1907,10 +2033,10 @@ class MenuListBodyComponent {
|
|
|
1907
2033
|
return false;
|
|
1908
2034
|
}
|
|
1909
2035
|
if (row.kind === 'action') {
|
|
1910
|
-
return row.item.id
|
|
2036
|
+
return menuItemIdsEqual(row.item.id, this.selectedItemId);
|
|
1911
2037
|
}
|
|
1912
2038
|
if (row.kind === 'submenu') {
|
|
1913
|
-
return (row.item.id
|
|
2039
|
+
return (menuItemIdsEqual(row.item.id, this.selectedItemId) ||
|
|
1914
2040
|
menuNodeTreeContainsId(row.item.items, this.selectedItemId));
|
|
1915
2041
|
}
|
|
1916
2042
|
return false;
|
|
@@ -2065,7 +2191,7 @@ class MenuListBodyComponent {
|
|
|
2065
2191
|
}
|
|
2066
2192
|
}
|
|
2067
2193
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: MenuListBodyComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2068
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: MenuListBodyComponent, isStandalone: true, selector: "app-menu-list-body", inputs: { appTheme: { classPropertyName: "appTheme", publicName: "appTheme", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: false, isRequired: true, transformFunction: null }, menuId: { classPropertyName: "menuId", publicName: "menuId", isSignal: false, isRequired: false, transformFunction: null }, dense: { classPropertyName: "dense", publicName: "dense", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, nested: { classPropertyName: "nested", publicName: "nested", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, selectedItemId: { classPropertyName: "selectedItemId", publicName: "selectedItemId", isSignal: false, isRequired: false, transformFunction: null }, compressText: { classPropertyName: "compressText", publicName: "compressText", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, clickToOpen: { classPropertyName: "clickToOpen", publicName: "clickToOpen", isSignal: false, isRequired: false, transformFunction: null }, groupCollapsible: { classPropertyName: "groupCollapsible", publicName: "groupCollapsible", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, groupDefaultExpansion: { classPropertyName: "groupDefaultExpansion", publicName: "groupDefaultExpansion", isSignal: false, isRequired: false, transformFunction: null }, persistGroupExpansion: { classPropertyName: "persistGroupExpansion", publicName: "persistGroupExpansion", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, expandAllGroupsInitially: { classPropertyName: "expandAllGroupsInitially", publicName: "expandAllGroupsInitially", isSignal: false, isRequired: false, transformFunction: booleanAttribute } }, outputs: { itemSelect: "itemSelect", closeRequest: "closeRequest", submenuBack: "submenuBack", groupToggled: "groupToggled" }, host: { listeners: { "focusin": "onFocusIn($event)", "keydown": "onKeydown($event)" } }, viewQueries: [{ propertyName: "nestedLists", predicate: MenuListBodyComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"menu-list\" [class.menu-list--nested]=\"nested\" [class.menu-list--dense]=\"dense\"\n [class.menu-list--compress-text]=\"compressText\" tabindex=\"-1\" (mouseleave)=\"onMenuSurfaceLeave()\">\n <div class=\"menu-list__toolbar\">\n <ng-content />\n </div>\n <div class=\"menu-list__viewport\" cdkScrollable tabindex=\"-1\">\n <div class=\"menu-list__items\" role=\"menu\" [attr.aria-labelledby]=\"null\" tabindex=\"-1\">\n @for (row of displayRows; track trackDisplayRow($index, row); let idx = $index) {\n @switch (row.kind) {\n @case ('divider') {\n <app-menu-divider (mouseenter)=\"onNonOptionSurfaceEnter()\" />\n }\n @case ('group') {\n <div class=\"menu-list__group-row\" [class.menu-list__group-row--pinned]=\"row.alwaysExpanded\"\n [attr.data-structra-group-id]=\"row.groupId\" (mouseenter)=\"onNonOptionSurfaceEnter()\">\n <app-menu-group [label]=\"row.label\" [hideLabel]=\"compressText\"\n [collapsible]=\"groupCollapsible && !compressText && !row.alwaysExpanded\"\n [expanded]=\"isGroupExpanded(row.groupId)\" (toggleExpand)=\"toggleGroup(row.groupId)\" />\n </div>\n }\n @case ('submenu') {\n <div class=\"menu-list__submenu-wrap\" cdkOverlayOrigin #subOrigin=\"cdkOverlayOrigin\"\n (mouseenter)=\"onSubmenuTriggerEnter(row, idx)\" (mouseleave)=\"onSubmenuTriggerLeave(row, idx)\">\n <div class=\"menu-list__option menu-list__option--submenu\" role=\"menuitem\" [attr.aria-haspopup]=\"'true'\"\n [attr.aria-expanded]=\"isSubmenuOpen(row, idx)\" [id]=\"row.focusIndex !== null ? optionId(row.focusIndex) : null\"\n [attr.tabindex]=\"row.focusIndex !== null && !row.item.disabled ? (isActiveRow(row) ? 0 : -1) : -1\"\n [attr.aria-disabled]=\"row.item.disabled ? true : null\" [attr.title]=\"compressText ? row.item.label : null\"\n [attr.aria-label]=\"compressText ? row.item.label : null\" [class.menu-list__option--disabled]=\"row.item.disabled\"\n [class.menu-list__option--active]=\"isActiveRow(row)\" [class.menu-list__option--selected]=\"isRowSelected(row)\"\n (click)=\"onSubmenuRowClick($event, row, idx)\" (mouseenter)=\"onRowMouseEnter(row)\">\n @if (row.item.icon?.trim()) {\n <span class=\"menu-list__icon\" aria-hidden=\"true\">\n <i [ngClass]=\"row.item.icon\"></i>\n </span>\n }\n <span class=\"menu-list__text\">\n <span class=\"menu-list__label\">{{ row.item.label }}</span>\n @if (row.item.description?.trim()) {\n <span class=\"menu-list__description\">{{ row.item.description }}</span>\n }\n </span>\n <span class=\"menu-list__submenu-chevron\" aria-hidden=\"true\">\n @if (isSubmenuOpen(row, idx)) {\n <i class=\"fa-solid fa-chevron-right\"></i>\n } @else {\n <i class=\"fa-solid fa-chevron-down\"></i>\n }\n </span>\n </div>\n <ng-template cdkConnectedOverlay [cdkConnectedOverlayOrigin]=\"subOrigin\"\n [cdkConnectedOverlayOpen]=\"isSubmenuOpen(row, idx)\" [cdkConnectedOverlayPositions]=\"submenuPositions\"\n [cdkConnectedOverlayPush]=\"true\" [cdkConnectedOverlayPanelClass]=\"overlayPanelClasses()\"\n [cdkConnectedOverlayMinWidth]=\"200\" (overlayOutsideClick)=\"onSubmenuOutsideClick(row, idx)\">\n <div class=\"menu-submenu__panel\" [ngClass]=\"panelThemeNgClass()\" (mouseenter)=\"onSubmenuPanelEnter()\"\n (mouseleave)=\"onSubmenuPanelLeave(row, idx)\" (click)=\"$event.stopPropagation()\">\n <app-menu-list-body [items]=\"row.item.items\" [menuId]=\"submenuMenuId(row)\" [nested]=\"true\" [dense]=\"dense\"\n [compressText]=\"compressText\" [groupCollapsible]=\"groupCollapsible\"\n [groupDefaultExpansion]=\"groupDefaultExpansion\" [persistGroupExpansion]=\"persistGroupExpansion\"\n [expandAllGroupsInitially]=\"expandAllGroupsInitially\"\n [clickToOpen]=\"clickToOpen\" [selectedItemId]=\"selectedItemId\" [appTheme]=\"appTheme()\"\n (itemSelect)=\"onNestedItemSelect($event)\" (closeRequest)=\"closeRequest.emit()\"\n (submenuBack)=\"closeOpenSubmenu()\" />\n </div>\n </ng-template>\n </div>\n }\n @case ('action') {\n <div class=\"menu-list__option\" role=\"menuitem\" [id]=\"row.focusIndex !== null ? optionId(row.focusIndex) : null\"\n [attr.tabindex]=\"row.focusIndex !== null && !row.item.disabled ? (isActiveRow(row) ? 0 : -1) : -1\"\n [attr.aria-disabled]=\"row.item.disabled ? true : null\" [attr.aria-busy]=\"row.item.loading ? true : null\"\n [attr.title]=\"compressText ? row.item.label : null\" [attr.aria-label]=\"compressText ? row.item.label : null\"\n [class.menu-list__option--disabled]=\"row.item.disabled\" [class.menu-list__option--loading]=\"row.item.loading\"\n [class.menu-list__option--danger]=\"row.item.danger\" [class.menu-list__option--active]=\"isActiveRow(row)\"\n [class.menu-list__option--selected]=\"isRowSelected(row)\" (click)=\"onItemClick($event, row.item)\"\n (mouseenter)=\"onRowMouseEnter(row)\">\n @if (row.item.loading) {\n <span class=\"menu-list__icon menu-list__icon--spin\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-spinner\"></i>\n </span>\n } @else if (row.item.icon?.trim()) {\n <span class=\"menu-list__icon\" aria-hidden=\"true\">\n <i [ngClass]=\"row.item.icon\"></i>\n </span>\n }\n <span class=\"menu-list__text\">\n <span class=\"menu-list__label\">{{ row.item.label }}</span>\n @if (row.item.description?.trim()) {\n <span class=\"menu-list__description\">{{ row.item.description }}</span>\n }\n </span>\n </div>\n }\n }\n }\n </div>\n </div>\n</div>", styles: ["@charset \"UTF-8\";@keyframes app-sidebar-nav-reveal-in{0%{opacity:0;transform:translate3d(-.45rem,0,0)}to{opacity:1;transform:translateZ(0)}}:host{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;min-width:0;box-sizing:border-box;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.menu-list{background:var(--app-color-surface, #ffffff);border:1px solid var(--app-color-border-subtle, rgba(26, 47, 69, .12));border-radius:10px;box-shadow:0 10px 28px -14px #0f172a29;max-height:min(70vh,22rem);overflow-x:hidden;overflow-y:auto;display:flex;flex-direction:column;flex:1 1 auto;min-height:0;min-width:0;overflow:hidden;gap:.35rem;padding:.45rem 0;outline:none;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.menu-list--dense{padding:.2rem 0;gap:0}.menu-list--dense .menu-list__items{gap:0}.menu-list--dense.menu-list--compress-text .menu-list__items{gap:.25rem}.menu-list__toolbar{flex:0 0 auto;min-width:0}.menu-list__viewport{flex:1 1 auto;min-height:0;min-width:0;overflow-x:hidden;overflow-y:auto;-webkit-overflow-scrolling:touch;outline:none;scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--app-color-text-primary, #1a2f45) 34%,transparent) transparent}.menu-list__viewport::-webkit-scrollbar{width:4px;height:4px}.menu-list__viewport::-webkit-scrollbar-track{background:transparent}.menu-list__viewport::-webkit-scrollbar-thumb{border-radius:999px;background:color-mix(in srgb,var(--app-color-text-primary, #1a2f45) 40%,transparent)}.menu-list__viewport::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--app-color-text-primary, #1a2f45) 55%,transparent)}.menu-list__items{display:flex;flex-direction:column;gap:.12rem;min-width:0}.menu-list__search{margin:0 .35rem .12rem;min-width:0;user-select:text;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text}.menu-list__search-field{display:block;width:100%}.menu-list__search-empty{margin:-.05rem .75rem 0;padding:0 0 .15rem;font-size:.75rem;line-height:1.35;font-weight:400;color:var(--app-color-text-muted, #6b8299);opacity:.88}.menu-list__group-row{display:block;width:100%}.menu-list__group-row--pinned .menu-list__group-label{color:var(--app-color-nav-group-heading, #9ca3af)}.menu-list__submenu-wrap{position:relative;display:block}.menu-list__option{display:flex;align-items:center;box-sizing:border-box;gap:.6875rem;margin:0 .25rem;padding:.5625rem .65rem;border-radius:8px;cursor:pointer;color:var(--app-color-text-primary, #1a2f45);background:transparent;border:1px solid transparent;text-align:left;font:inherit;line-height:1.25;transition:background-color .18s ease,color .18s ease,box-shadow .18s ease,border-color .18s ease}.menu-list__option:focus-visible{outline:2px solid var(--app-color-focus-ring-strong, rgba(43, 127, 217, .45));outline-offset:1px}.menu-list__option:hover:not(.menu-list__option--disabled):not(.menu-list__option--loading){background:#0f172a0b}.menu-list__option.menu-list__option--active:not(.menu-list__option--disabled):not(.menu-list__option--loading){background:#0f172a0e;border-color:transparent}.menu-list__option.menu-list__option--active:not(.menu-list__option--disabled):not(.menu-list__option--loading):not(.menu-list__option--selected){box-shadow:none}.menu-list__option.menu-list__option--disabled{cursor:not-allowed;color:var(--app-color-text-muted, #6b8299);background:transparent;opacity:.72}.menu-list__option.menu-list__option--loading{cursor:wait;opacity:.92;pointer-events:none}.menu-list__option.menu-list__option--danger:not(.menu-list__option--disabled):not(.menu-list__option--loading){color:var(--app-color-error, #b91c1c)}.menu-list__option.menu-list__option--danger:not(.menu-list__option--disabled):not(.menu-list__option--loading):hover,.menu-list__option.menu-list__option--danger:not(.menu-list__option--disabled):not(.menu-list__option--loading).menu-list__option--active{background:var(--app-color-error-bg-subtle, rgba(185, 28, 28, .12));border-color:transparent;box-shadow:inset 2px 0 0 0 var(--app-color-error-border, #dc2626)}.menu-list__option--submenu{padding-right:.35rem}.menu-list__option--selected:not(.menu-list__option--disabled){background:color-mix(in srgb,var(--app-color-primary) 10%,transparent);border-radius:8px;border-color:transparent;box-shadow:inset 2px 0 0 0 var(--app-color-primary, #2b7fd9)}.menu-list__option--selected:not(.menu-list__option--disabled) .menu-list__label{color:color-mix(in srgb,var(--app-color-primary, #2b7fd9) 88%,var(--app-color-nav-option-label, #374151));font-weight:500}.menu-list__option--selected:not(.menu-list__option--disabled) .menu-list__icon{color:var(--app-color-primary, #2b7fd9)}.menu-list__option:not(.menu-list__option--danger):not(.menu-list__option--disabled):not(.menu-list__option--selected) .menu-list__label{color:var(--app-color-nav-option-label, #374151)}.menu-list--compress-text .menu-list__label,.menu-list--compress-text .menu-list__description{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.menu-list--compress-text .menu-list__text,.menu-list--compress-text .menu-list__submenu-chevron{display:none}.menu-list--compress-text .menu-list__submenu-wrap{width:100%}.menu-list--compress-text .menu-list__option{justify-content:center;align-items:center;text-align:center;width:calc(100% - .5rem);max-width:100%;box-sizing:border-box;margin-left:.25rem;margin-right:.25rem;padding:.5rem .35rem}.menu-list--compress-text .menu-list__option--submenu{padding-left:.35rem;padding-right:.35rem}.menu-list--compress-text .menu-list__icon{flex:0 0 auto;width:auto;min-width:1.75rem;display:inline-flex;align-items:center;justify-content:center;padding-top:0}.menu-list__submenu-chevron{flex:0 0 auto;margin-left:auto;padding-left:.35rem;font-size:1rem;line-height:1;color:var(--app-color-text-muted, #6b8299);opacity:.85;display:inline-flex;align-items:center;justify-content:center}.menu-list__submenu-chevron i{font-size:.68rem;line-height:1}.menu-list__icon{flex:0 0 auto;width:1.25rem;height:1.25rem;min-height:1.25rem;display:inline-flex;align-items:center;justify-content:center;text-align:center;color:color-mix(in srgb,var(--app-color-primary, #2b7fd9) 78%,var(--app-color-text-muted, #6b8299));line-height:1;transition:color .18s ease,opacity .18s ease}.menu-list__icon i{display:flex;align-items:center;justify-content:center;width:100%;height:100%;line-height:1;font-size:.95rem;margin-block:auto;flex-shrink:0}.menu-list__option--disabled .menu-list__icon{opacity:.55}.menu-list__icon--spin i{animation:menu-list-spin .8s linear infinite}.menu-list__text{display:flex;flex-direction:column;gap:.1rem;min-width:0;flex:1}.menu-list__label{font-size:.875rem;font-weight:400;line-height:1.25rem;display:inline-flex;align-items:center;min-height:1.25rem;box-sizing:border-box;padding-top:.5rem!important}.menu-list--nested .menu-list__label{font-weight:400;padding-top:.5rem!important}.menu-list--nested .menu-list__icon{transform:translateY(.125rem)}.menu-list__description{font-size:.75rem;color:var(--app-color-text-muted, #6b8299);line-height:1.3}.menu-list:not(.menu-list--compress-text){animation:app-sidebar-nav-reveal-in .45s cubic-bezier(.16,1,.32,1) both}@media(prefers-reduced-motion:reduce){.menu-list:not(.menu-list--compress-text){animation:none}}:host-context(.app-drawer__body) .menu-list__label{padding-top:.5rem!important}:host-context(.app-drawer__body) .menu-list__icon{transform:translateY(.1875rem)}@media(max-width:767.98px){.menu-list.menu-list--nested .menu-list__label{padding-top:.4rem!important}.menu-list.menu-list--nested .menu-list__icon{transform:translateY(.1875rem)}}.menu-submenu__panel{box-sizing:border-box;min-width:0;padding:0;background:transparent;border:none;box-shadow:none;border-radius:10px;overflow:hidden}@keyframes menu-list-spin{to{transform:rotate(360deg)}}:host ::ng-deep .menu-submenu__cdk-panel{background:transparent;box-shadow:none;border-radius:10px}\n"], dependencies: [{ kind: "component", type: i0.forwardRef(() => MenuListBodyComponent), selector: "app-menu-list-body", inputs: ["appTheme", "items", "menuId", "dense", "nested", "selectedItemId", "compressText", "clickToOpen", "groupCollapsible", "groupDefaultExpansion", "persistGroupExpansion", "expandAllGroupsInitially"], outputs: ["itemSelect", "closeRequest", "submenuBack", "groupToggled"] }, { kind: "directive", type: i0.forwardRef(() => NgClass), selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i0.forwardRef(() => CdkConnectedOverlay), selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation", "cdkConnectedOverlayUsePopover", "cdkConnectedOverlayMatchWidth", "cdkConnectedOverlay"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i0.forwardRef(() => CdkOverlayOrigin), selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "directive", type: i0.forwardRef(() => CdkScrollable), selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "component", type: i0.forwardRef(() => MenuDividerComponent), selector: "app-menu-divider" }, { kind: "component", type: i0.forwardRef(() => MenuGroupComponent), selector: "app-menu-group", inputs: ["label", "hideLabel", "collapsible", "expanded"], outputs: ["toggleExpand"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2194
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: MenuListBodyComponent, isStandalone: true, selector: "app-menu-list-body", inputs: { appTheme: { classPropertyName: "appTheme", publicName: "appTheme", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: false, isRequired: true, transformFunction: null }, menuId: { classPropertyName: "menuId", publicName: "menuId", isSignal: false, isRequired: false, transformFunction: null }, dense: { classPropertyName: "dense", publicName: "dense", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, nested: { classPropertyName: "nested", publicName: "nested", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, selectedItemId: { classPropertyName: "selectedItemId", publicName: "selectedItemId", isSignal: false, isRequired: false, transformFunction: null }, compressText: { classPropertyName: "compressText", publicName: "compressText", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, clickToOpen: { classPropertyName: "clickToOpen", publicName: "clickToOpen", isSignal: false, isRequired: false, transformFunction: null }, groupCollapsible: { classPropertyName: "groupCollapsible", publicName: "groupCollapsible", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, groupDefaultExpansion: { classPropertyName: "groupDefaultExpansion", publicName: "groupDefaultExpansion", isSignal: false, isRequired: false, transformFunction: null }, persistGroupExpansion: { classPropertyName: "persistGroupExpansion", publicName: "persistGroupExpansion", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, expandAllGroupsInitially: { classPropertyName: "expandAllGroupsInitially", publicName: "expandAllGroupsInitially", isSignal: false, isRequired: false, transformFunction: booleanAttribute } }, outputs: { selectionScrollHint: "selectionScrollHint", itemSelect: "itemSelect", closeRequest: "closeRequest", submenuBack: "submenuBack", groupToggled: "groupToggled" }, host: { listeners: { "focusin": "onFocusIn($event)", "keydown": "onKeydown($event)" } }, viewQueries: [{ propertyName: "nestedLists", predicate: MenuListBodyComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"menu-list\" [class.menu-list--nested]=\"nested\" [class.menu-list--dense]=\"dense\"\n [class.menu-list--compress-text]=\"compressText\" tabindex=\"-1\" (mouseleave)=\"onMenuSurfaceLeave()\">\n <div class=\"menu-list__toolbar\">\n <ng-content />\n </div>\n <div class=\"menu-list__viewport\" cdkScrollable tabindex=\"-1\">\n <div class=\"menu-list__items\" role=\"menu\" [attr.aria-labelledby]=\"null\" tabindex=\"-1\">\n @for (row of displayRows; track trackDisplayRow($index, row); let idx = $index) {\n @switch (row.kind) {\n @case ('divider') {\n <app-menu-divider (mouseenter)=\"onNonOptionSurfaceEnter()\" />\n }\n @case ('group') {\n <div class=\"menu-list__group-row\" [class.menu-list__group-row--pinned]=\"row.alwaysExpanded\"\n [attr.data-structra-group-id]=\"row.groupId\" (mouseenter)=\"onNonOptionSurfaceEnter()\">\n <app-menu-group [label]=\"row.label\" [hideLabel]=\"compressText\"\n [collapsible]=\"groupCollapsible && !compressText && !row.alwaysExpanded\"\n [expanded]=\"isGroupExpanded(row.groupId)\" (toggleExpand)=\"toggleGroup(row.groupId)\" />\n </div>\n }\n @case ('submenu') {\n <div class=\"menu-list__submenu-wrap\" cdkOverlayOrigin #subOrigin=\"cdkOverlayOrigin\"\n (mouseenter)=\"onSubmenuTriggerEnter(row, idx)\" (mouseleave)=\"onSubmenuTriggerLeave(row, idx)\">\n <div class=\"menu-list__option menu-list__option--submenu\" role=\"menuitem\" [attr.aria-haspopup]=\"'true'\"\n [attr.aria-expanded]=\"isSubmenuOpen(row, idx)\" [id]=\"row.focusIndex !== null ? optionId(row.focusIndex) : null\"\n [attr.tabindex]=\"row.focusIndex !== null && !row.item.disabled ? (isActiveRow(row) ? 0 : -1) : -1\"\n [attr.aria-disabled]=\"row.item.disabled ? true : null\" [attr.title]=\"compressText ? row.item.label : null\"\n [attr.aria-label]=\"compressText ? row.item.label : null\" [class.menu-list__option--disabled]=\"row.item.disabled\"\n [class.menu-list__option--active]=\"isActiveRow(row)\" [class.menu-list__option--selected]=\"isRowSelected(row)\"\n (click)=\"onSubmenuRowClick($event, row, idx)\" (mouseenter)=\"onRowMouseEnter(row)\">\n @if (row.item.icon?.trim()) {\n <span class=\"menu-list__icon\" aria-hidden=\"true\">\n <i [ngClass]=\"row.item.icon\"></i>\n </span>\n }\n <span class=\"menu-list__text\">\n <span class=\"menu-list__label\">{{ row.item.label }}</span>\n @if (row.item.description?.trim()) {\n <span class=\"menu-list__description\">{{ row.item.description }}</span>\n }\n </span>\n <span class=\"menu-list__submenu-chevron\" aria-hidden=\"true\">\n @if (isSubmenuOpen(row, idx)) {\n <i class=\"fa-solid fa-chevron-right\"></i>\n } @else {\n <i class=\"fa-solid fa-chevron-down\"></i>\n }\n </span>\n </div>\n <ng-template cdkConnectedOverlay [cdkConnectedOverlayOrigin]=\"subOrigin\"\n [cdkConnectedOverlayOpen]=\"isSubmenuOpen(row, idx)\" [cdkConnectedOverlayPositions]=\"submenuPositions\"\n [cdkConnectedOverlayPush]=\"true\" [cdkConnectedOverlayPanelClass]=\"overlayPanelClasses()\"\n [cdkConnectedOverlayMinWidth]=\"200\" (overlayOutsideClick)=\"onSubmenuOutsideClick(row, idx)\">\n <div class=\"menu-submenu__panel\" [ngClass]=\"panelThemeNgClass()\" (mouseenter)=\"onSubmenuPanelEnter()\"\n (mouseleave)=\"onSubmenuPanelLeave(row, idx)\" (click)=\"$event.stopPropagation()\">\n <app-menu-list-body [items]=\"row.item.items\" [menuId]=\"submenuMenuId(row)\" [nested]=\"true\" [dense]=\"dense\"\n [compressText]=\"compressText\" [groupCollapsible]=\"groupCollapsible\"\n [groupDefaultExpansion]=\"groupDefaultExpansion\" [persistGroupExpansion]=\"persistGroupExpansion\"\n [expandAllGroupsInitially]=\"expandAllGroupsInitially\"\n [clickToOpen]=\"clickToOpen\" [selectedItemId]=\"selectedItemId\" [appTheme]=\"appTheme()\"\n (itemSelect)=\"onNestedItemSelect($event)\" (closeRequest)=\"closeRequest.emit()\"\n (submenuBack)=\"closeOpenSubmenu()\" />\n </div>\n </ng-template>\n </div>\n }\n @case ('action') {\n <div class=\"menu-list__option\" role=\"menuitem\" [id]=\"row.focusIndex !== null ? optionId(row.focusIndex) : null\"\n [attr.tabindex]=\"row.focusIndex !== null && !row.item.disabled ? (isActiveRow(row) ? 0 : -1) : -1\"\n [attr.aria-disabled]=\"row.item.disabled ? true : null\" [attr.aria-busy]=\"row.item.loading ? true : null\"\n [attr.title]=\"compressText ? row.item.label : null\" [attr.aria-label]=\"compressText ? row.item.label : null\"\n [class.menu-list__option--disabled]=\"row.item.disabled\" [class.menu-list__option--loading]=\"row.item.loading\"\n [class.menu-list__option--danger]=\"row.item.danger\" [class.menu-list__option--active]=\"isActiveRow(row)\"\n [class.menu-list__option--selected]=\"isRowSelected(row)\" (click)=\"onItemClick($event, row.item)\"\n (mouseenter)=\"onRowMouseEnter(row)\">\n @if (row.item.loading) {\n <span class=\"menu-list__icon menu-list__icon--spin\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-spinner\"></i>\n </span>\n } @else if (row.item.icon?.trim()) {\n <span class=\"menu-list__icon\" aria-hidden=\"true\">\n <i [ngClass]=\"row.item.icon\"></i>\n </span>\n }\n <span class=\"menu-list__text\">\n <span class=\"menu-list__label\">{{ row.item.label }}</span>\n @if (row.item.description?.trim()) {\n <span class=\"menu-list__description\">{{ row.item.description }}</span>\n }\n </span>\n </div>\n }\n }\n }\n </div>\n </div>\n</div>", styles: ["@charset \"UTF-8\";@keyframes app-sidebar-nav-reveal-in{0%{opacity:0;transform:translate3d(-.45rem,0,0)}to{opacity:1;transform:translateZ(0)}}:host{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;min-width:0;box-sizing:border-box;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.menu-list{background:var(--app-color-surface, #ffffff);border:1px solid var(--app-color-border-subtle, rgba(26, 47, 69, .12));border-radius:10px;box-shadow:0 10px 28px -14px #0f172a29;max-height:min(70vh,22rem);overflow-x:hidden;overflow-y:auto;display:flex;flex-direction:column;flex:1 1 auto;min-height:0;min-width:0;overflow:hidden;gap:.35rem;padding:.45rem 0;outline:none;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.menu-list--dense{padding:.2rem 0;gap:0}.menu-list--dense .menu-list__items{gap:0}.menu-list--dense.menu-list--compress-text .menu-list__items{gap:.25rem}.menu-list__toolbar{flex:0 0 auto;min-width:0}.menu-list__viewport{flex:1 1 auto;min-height:0;min-width:0;overflow-x:hidden;overflow-y:auto;-webkit-overflow-scrolling:touch;outline:none;scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--app-color-text-primary, #1a2f45) 34%,transparent) transparent}.menu-list__viewport::-webkit-scrollbar{width:4px;height:4px}.menu-list__viewport::-webkit-scrollbar-track{background:transparent}.menu-list__viewport::-webkit-scrollbar-thumb{border-radius:999px;background:color-mix(in srgb,var(--app-color-text-primary, #1a2f45) 40%,transparent)}.menu-list__viewport::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--app-color-text-primary, #1a2f45) 55%,transparent)}.menu-list__items{display:flex;flex-direction:column;gap:.12rem;min-width:0}.menu-list__search{margin:0 .35rem .12rem;min-width:0;user-select:text;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text}.menu-list__search-field{display:block;width:100%}.menu-list__search-empty{margin:-.05rem .75rem 0;padding:0 0 .15rem;font-size:.75rem;line-height:1.35;font-weight:400;color:var(--app-color-text-muted, #6b8299);opacity:.88}.menu-list__group-row{display:block;width:100%}.menu-list__group-row--pinned .menu-list__group-label{color:var(--app-color-nav-group-heading, #9ca3af)}.menu-list__submenu-wrap{position:relative;display:block}.menu-list__option{display:flex;align-items:center;box-sizing:border-box;gap:.6875rem;margin:0 .25rem;padding:.5625rem .65rem;border-radius:8px;cursor:pointer;color:var(--app-color-text-primary, #1a2f45);background:transparent;border:1px solid transparent;text-align:left;font:inherit;line-height:1.25;transition:background-color .18s ease,color .18s ease,box-shadow .18s ease,border-color .18s ease}.menu-list__option:focus-visible{outline:2px solid var(--app-color-focus-ring-strong, rgba(43, 127, 217, .45));outline-offset:1px}.menu-list__option:hover:not(.menu-list__option--disabled):not(.menu-list__option--loading){background:#0f172a0b}.menu-list__option.menu-list__option--active:not(.menu-list__option--disabled):not(.menu-list__option--loading){background:#0f172a0e;border-color:transparent}.menu-list__option.menu-list__option--active:not(.menu-list__option--disabled):not(.menu-list__option--loading):not(.menu-list__option--selected){box-shadow:none}.menu-list__option.menu-list__option--disabled{cursor:not-allowed;color:var(--app-color-text-muted, #6b8299);background:transparent;opacity:.72}.menu-list__option.menu-list__option--loading{cursor:wait;opacity:.92;pointer-events:none}.menu-list__option.menu-list__option--danger:not(.menu-list__option--disabled):not(.menu-list__option--loading){color:var(--app-color-error, #b91c1c)}.menu-list__option.menu-list__option--danger:not(.menu-list__option--disabled):not(.menu-list__option--loading):hover,.menu-list__option.menu-list__option--danger:not(.menu-list__option--disabled):not(.menu-list__option--loading).menu-list__option--active{background:var(--app-color-error-bg-subtle, rgba(185, 28, 28, .12));border-color:transparent;box-shadow:inset 2px 0 0 0 var(--app-color-error-border, #dc2626)}.menu-list__option--submenu{padding-right:.35rem}.menu-list__option--selected:not(.menu-list__option--disabled){background:color-mix(in srgb,var(--app-color-primary) 10%,transparent);border-radius:8px;border-color:transparent;box-shadow:inset 2px 0 0 0 var(--app-color-primary, #2b7fd9)}.menu-list__option--selected:not(.menu-list__option--disabled) .menu-list__label{color:color-mix(in srgb,var(--app-color-primary, #2b7fd9) 88%,var(--app-color-nav-option-label, #374151));font-weight:500}.menu-list__option--selected:not(.menu-list__option--disabled) .menu-list__icon{color:var(--app-color-primary, #2b7fd9)}.menu-list__option:not(.menu-list__option--danger):not(.menu-list__option--disabled):not(.menu-list__option--selected) .menu-list__label{color:var(--app-color-nav-option-label, #374151)}.menu-list--compress-text .menu-list__label,.menu-list--compress-text .menu-list__description{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.menu-list--compress-text .menu-list__text,.menu-list--compress-text .menu-list__submenu-chevron{display:none}.menu-list--compress-text .menu-list__submenu-wrap{width:100%}.menu-list--compress-text .menu-list__option{justify-content:center;align-items:center;text-align:center;width:calc(100% - .5rem);max-width:100%;box-sizing:border-box;margin-left:.25rem;margin-right:.25rem;padding:.5rem .35rem}.menu-list--compress-text .menu-list__option--submenu{padding-left:.35rem;padding-right:.35rem}.menu-list--compress-text .menu-list__icon{flex:0 0 auto;width:auto;min-width:1.75rem;display:inline-flex;align-items:center;justify-content:center;padding-top:0}.menu-list__submenu-chevron{flex:0 0 auto;margin-left:auto;padding-left:.35rem;font-size:1rem;line-height:1;color:var(--app-color-text-muted, #6b8299);opacity:.85;display:inline-flex;align-items:center;justify-content:center}.menu-list__submenu-chevron i{font-size:.68rem;line-height:1}.menu-list__icon{flex:0 0 auto;width:1.25rem;height:1.25rem;min-height:1.25rem;display:inline-flex;align-items:center;justify-content:center;text-align:center;color:color-mix(in srgb,var(--app-color-primary, #2b7fd9) 78%,var(--app-color-text-muted, #6b8299));line-height:1;transition:color .18s ease,opacity .18s ease}.menu-list__icon i{display:flex;align-items:center;justify-content:center;width:100%;height:100%;line-height:1;font-size:.95rem;margin-block:auto;flex-shrink:0}.menu-list__option--disabled .menu-list__icon{opacity:.55}.menu-list__icon--spin i{animation:menu-list-spin .8s linear infinite}.menu-list__text{display:flex;flex-direction:column;gap:.1rem;min-width:0;flex:1}.menu-list__label{font-size:.875rem;font-weight:400;line-height:1.25rem;display:inline-flex;align-items:center;min-height:1.25rem;box-sizing:border-box;padding-top:.5rem!important}.menu-list--nested .menu-list__label{font-weight:400;padding-top:.5rem!important}.menu-list--nested .menu-list__icon{transform:translateY(.125rem)}.menu-list__description{font-size:.75rem;color:var(--app-color-text-muted, #6b8299);line-height:1.3}.menu-list:not(.menu-list--compress-text){animation:app-sidebar-nav-reveal-in .45s cubic-bezier(.16,1,.32,1) both}@media(prefers-reduced-motion:reduce){.menu-list:not(.menu-list--compress-text){animation:none}}:host-context(.app-drawer__body) .menu-list__label{padding-top:.5rem!important}:host-context(.app-drawer__body) .menu-list__icon{transform:translateY(.1875rem)}@media(max-width:767.98px){.menu-list.menu-list--nested .menu-list__label{padding-top:.4rem!important}.menu-list.menu-list--nested .menu-list__icon{transform:translateY(.1875rem)}}.menu-submenu__panel{box-sizing:border-box;min-width:0;padding:0;background:transparent;border:none;box-shadow:none;border-radius:10px;overflow:hidden}@keyframes menu-list-spin{to{transform:rotate(360deg)}}:host ::ng-deep .menu-submenu__cdk-panel{background:transparent;box-shadow:none;border-radius:10px}\n"], dependencies: [{ kind: "component", type: i0.forwardRef(() => MenuListBodyComponent), selector: "app-menu-list-body", inputs: ["appTheme", "items", "menuId", "dense", "nested", "selectedItemId", "compressText", "clickToOpen", "groupCollapsible", "groupDefaultExpansion", "persistGroupExpansion", "expandAllGroupsInitially"], outputs: ["selectionScrollHint", "itemSelect", "closeRequest", "submenuBack", "groupToggled"] }, { kind: "directive", type: i0.forwardRef(() => NgClass), selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i0.forwardRef(() => CdkConnectedOverlay), selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation", "cdkConnectedOverlayUsePopover", "cdkConnectedOverlayMatchWidth", "cdkConnectedOverlay"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i0.forwardRef(() => CdkOverlayOrigin), selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "directive", type: i0.forwardRef(() => CdkScrollable), selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "component", type: i0.forwardRef(() => MenuDividerComponent), selector: "app-menu-divider" }, { kind: "component", type: i0.forwardRef(() => MenuGroupComponent), selector: "app-menu-group", inputs: ["label", "hideLabel", "collapsible", "expanded"], outputs: ["toggleExpand"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2069
2195
|
}
|
|
2070
2196
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: MenuListBodyComponent, decorators: [{
|
|
2071
2197
|
type: Component,
|
|
@@ -2078,7 +2204,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
2078
2204
|
MenuDividerComponent,
|
|
2079
2205
|
MenuGroupComponent,
|
|
2080
2206
|
], template: "<div class=\"menu-list\" [class.menu-list--nested]=\"nested\" [class.menu-list--dense]=\"dense\"\n [class.menu-list--compress-text]=\"compressText\" tabindex=\"-1\" (mouseleave)=\"onMenuSurfaceLeave()\">\n <div class=\"menu-list__toolbar\">\n <ng-content />\n </div>\n <div class=\"menu-list__viewport\" cdkScrollable tabindex=\"-1\">\n <div class=\"menu-list__items\" role=\"menu\" [attr.aria-labelledby]=\"null\" tabindex=\"-1\">\n @for (row of displayRows; track trackDisplayRow($index, row); let idx = $index) {\n @switch (row.kind) {\n @case ('divider') {\n <app-menu-divider (mouseenter)=\"onNonOptionSurfaceEnter()\" />\n }\n @case ('group') {\n <div class=\"menu-list__group-row\" [class.menu-list__group-row--pinned]=\"row.alwaysExpanded\"\n [attr.data-structra-group-id]=\"row.groupId\" (mouseenter)=\"onNonOptionSurfaceEnter()\">\n <app-menu-group [label]=\"row.label\" [hideLabel]=\"compressText\"\n [collapsible]=\"groupCollapsible && !compressText && !row.alwaysExpanded\"\n [expanded]=\"isGroupExpanded(row.groupId)\" (toggleExpand)=\"toggleGroup(row.groupId)\" />\n </div>\n }\n @case ('submenu') {\n <div class=\"menu-list__submenu-wrap\" cdkOverlayOrigin #subOrigin=\"cdkOverlayOrigin\"\n (mouseenter)=\"onSubmenuTriggerEnter(row, idx)\" (mouseleave)=\"onSubmenuTriggerLeave(row, idx)\">\n <div class=\"menu-list__option menu-list__option--submenu\" role=\"menuitem\" [attr.aria-haspopup]=\"'true'\"\n [attr.aria-expanded]=\"isSubmenuOpen(row, idx)\" [id]=\"row.focusIndex !== null ? optionId(row.focusIndex) : null\"\n [attr.tabindex]=\"row.focusIndex !== null && !row.item.disabled ? (isActiveRow(row) ? 0 : -1) : -1\"\n [attr.aria-disabled]=\"row.item.disabled ? true : null\" [attr.title]=\"compressText ? row.item.label : null\"\n [attr.aria-label]=\"compressText ? row.item.label : null\" [class.menu-list__option--disabled]=\"row.item.disabled\"\n [class.menu-list__option--active]=\"isActiveRow(row)\" [class.menu-list__option--selected]=\"isRowSelected(row)\"\n (click)=\"onSubmenuRowClick($event, row, idx)\" (mouseenter)=\"onRowMouseEnter(row)\">\n @if (row.item.icon?.trim()) {\n <span class=\"menu-list__icon\" aria-hidden=\"true\">\n <i [ngClass]=\"row.item.icon\"></i>\n </span>\n }\n <span class=\"menu-list__text\">\n <span class=\"menu-list__label\">{{ row.item.label }}</span>\n @if (row.item.description?.trim()) {\n <span class=\"menu-list__description\">{{ row.item.description }}</span>\n }\n </span>\n <span class=\"menu-list__submenu-chevron\" aria-hidden=\"true\">\n @if (isSubmenuOpen(row, idx)) {\n <i class=\"fa-solid fa-chevron-right\"></i>\n } @else {\n <i class=\"fa-solid fa-chevron-down\"></i>\n }\n </span>\n </div>\n <ng-template cdkConnectedOverlay [cdkConnectedOverlayOrigin]=\"subOrigin\"\n [cdkConnectedOverlayOpen]=\"isSubmenuOpen(row, idx)\" [cdkConnectedOverlayPositions]=\"submenuPositions\"\n [cdkConnectedOverlayPush]=\"true\" [cdkConnectedOverlayPanelClass]=\"overlayPanelClasses()\"\n [cdkConnectedOverlayMinWidth]=\"200\" (overlayOutsideClick)=\"onSubmenuOutsideClick(row, idx)\">\n <div class=\"menu-submenu__panel\" [ngClass]=\"panelThemeNgClass()\" (mouseenter)=\"onSubmenuPanelEnter()\"\n (mouseleave)=\"onSubmenuPanelLeave(row, idx)\" (click)=\"$event.stopPropagation()\">\n <app-menu-list-body [items]=\"row.item.items\" [menuId]=\"submenuMenuId(row)\" [nested]=\"true\" [dense]=\"dense\"\n [compressText]=\"compressText\" [groupCollapsible]=\"groupCollapsible\"\n [groupDefaultExpansion]=\"groupDefaultExpansion\" [persistGroupExpansion]=\"persistGroupExpansion\"\n [expandAllGroupsInitially]=\"expandAllGroupsInitially\"\n [clickToOpen]=\"clickToOpen\" [selectedItemId]=\"selectedItemId\" [appTheme]=\"appTheme()\"\n (itemSelect)=\"onNestedItemSelect($event)\" (closeRequest)=\"closeRequest.emit()\"\n (submenuBack)=\"closeOpenSubmenu()\" />\n </div>\n </ng-template>\n </div>\n }\n @case ('action') {\n <div class=\"menu-list__option\" role=\"menuitem\" [id]=\"row.focusIndex !== null ? optionId(row.focusIndex) : null\"\n [attr.tabindex]=\"row.focusIndex !== null && !row.item.disabled ? (isActiveRow(row) ? 0 : -1) : -1\"\n [attr.aria-disabled]=\"row.item.disabled ? true : null\" [attr.aria-busy]=\"row.item.loading ? true : null\"\n [attr.title]=\"compressText ? row.item.label : null\" [attr.aria-label]=\"compressText ? row.item.label : null\"\n [class.menu-list__option--disabled]=\"row.item.disabled\" [class.menu-list__option--loading]=\"row.item.loading\"\n [class.menu-list__option--danger]=\"row.item.danger\" [class.menu-list__option--active]=\"isActiveRow(row)\"\n [class.menu-list__option--selected]=\"isRowSelected(row)\" (click)=\"onItemClick($event, row.item)\"\n (mouseenter)=\"onRowMouseEnter(row)\">\n @if (row.item.loading) {\n <span class=\"menu-list__icon menu-list__icon--spin\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-spinner\"></i>\n </span>\n } @else if (row.item.icon?.trim()) {\n <span class=\"menu-list__icon\" aria-hidden=\"true\">\n <i [ngClass]=\"row.item.icon\"></i>\n </span>\n }\n <span class=\"menu-list__text\">\n <span class=\"menu-list__label\">{{ row.item.label }}</span>\n @if (row.item.description?.trim()) {\n <span class=\"menu-list__description\">{{ row.item.description }}</span>\n }\n </span>\n </div>\n }\n }\n }\n </div>\n </div>\n</div>", styles: ["@charset \"UTF-8\";@keyframes app-sidebar-nav-reveal-in{0%{opacity:0;transform:translate3d(-.45rem,0,0)}to{opacity:1;transform:translateZ(0)}}:host{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;min-width:0;box-sizing:border-box;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.menu-list{background:var(--app-color-surface, #ffffff);border:1px solid var(--app-color-border-subtle, rgba(26, 47, 69, .12));border-radius:10px;box-shadow:0 10px 28px -14px #0f172a29;max-height:min(70vh,22rem);overflow-x:hidden;overflow-y:auto;display:flex;flex-direction:column;flex:1 1 auto;min-height:0;min-width:0;overflow:hidden;gap:.35rem;padding:.45rem 0;outline:none;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.menu-list--dense{padding:.2rem 0;gap:0}.menu-list--dense .menu-list__items{gap:0}.menu-list--dense.menu-list--compress-text .menu-list__items{gap:.25rem}.menu-list__toolbar{flex:0 0 auto;min-width:0}.menu-list__viewport{flex:1 1 auto;min-height:0;min-width:0;overflow-x:hidden;overflow-y:auto;-webkit-overflow-scrolling:touch;outline:none;scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--app-color-text-primary, #1a2f45) 34%,transparent) transparent}.menu-list__viewport::-webkit-scrollbar{width:4px;height:4px}.menu-list__viewport::-webkit-scrollbar-track{background:transparent}.menu-list__viewport::-webkit-scrollbar-thumb{border-radius:999px;background:color-mix(in srgb,var(--app-color-text-primary, #1a2f45) 40%,transparent)}.menu-list__viewport::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--app-color-text-primary, #1a2f45) 55%,transparent)}.menu-list__items{display:flex;flex-direction:column;gap:.12rem;min-width:0}.menu-list__search{margin:0 .35rem .12rem;min-width:0;user-select:text;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text}.menu-list__search-field{display:block;width:100%}.menu-list__search-empty{margin:-.05rem .75rem 0;padding:0 0 .15rem;font-size:.75rem;line-height:1.35;font-weight:400;color:var(--app-color-text-muted, #6b8299);opacity:.88}.menu-list__group-row{display:block;width:100%}.menu-list__group-row--pinned .menu-list__group-label{color:var(--app-color-nav-group-heading, #9ca3af)}.menu-list__submenu-wrap{position:relative;display:block}.menu-list__option{display:flex;align-items:center;box-sizing:border-box;gap:.6875rem;margin:0 .25rem;padding:.5625rem .65rem;border-radius:8px;cursor:pointer;color:var(--app-color-text-primary, #1a2f45);background:transparent;border:1px solid transparent;text-align:left;font:inherit;line-height:1.25;transition:background-color .18s ease,color .18s ease,box-shadow .18s ease,border-color .18s ease}.menu-list__option:focus-visible{outline:2px solid var(--app-color-focus-ring-strong, rgba(43, 127, 217, .45));outline-offset:1px}.menu-list__option:hover:not(.menu-list__option--disabled):not(.menu-list__option--loading){background:#0f172a0b}.menu-list__option.menu-list__option--active:not(.menu-list__option--disabled):not(.menu-list__option--loading){background:#0f172a0e;border-color:transparent}.menu-list__option.menu-list__option--active:not(.menu-list__option--disabled):not(.menu-list__option--loading):not(.menu-list__option--selected){box-shadow:none}.menu-list__option.menu-list__option--disabled{cursor:not-allowed;color:var(--app-color-text-muted, #6b8299);background:transparent;opacity:.72}.menu-list__option.menu-list__option--loading{cursor:wait;opacity:.92;pointer-events:none}.menu-list__option.menu-list__option--danger:not(.menu-list__option--disabled):not(.menu-list__option--loading){color:var(--app-color-error, #b91c1c)}.menu-list__option.menu-list__option--danger:not(.menu-list__option--disabled):not(.menu-list__option--loading):hover,.menu-list__option.menu-list__option--danger:not(.menu-list__option--disabled):not(.menu-list__option--loading).menu-list__option--active{background:var(--app-color-error-bg-subtle, rgba(185, 28, 28, .12));border-color:transparent;box-shadow:inset 2px 0 0 0 var(--app-color-error-border, #dc2626)}.menu-list__option--submenu{padding-right:.35rem}.menu-list__option--selected:not(.menu-list__option--disabled){background:color-mix(in srgb,var(--app-color-primary) 10%,transparent);border-radius:8px;border-color:transparent;box-shadow:inset 2px 0 0 0 var(--app-color-primary, #2b7fd9)}.menu-list__option--selected:not(.menu-list__option--disabled) .menu-list__label{color:color-mix(in srgb,var(--app-color-primary, #2b7fd9) 88%,var(--app-color-nav-option-label, #374151));font-weight:500}.menu-list__option--selected:not(.menu-list__option--disabled) .menu-list__icon{color:var(--app-color-primary, #2b7fd9)}.menu-list__option:not(.menu-list__option--danger):not(.menu-list__option--disabled):not(.menu-list__option--selected) .menu-list__label{color:var(--app-color-nav-option-label, #374151)}.menu-list--compress-text .menu-list__label,.menu-list--compress-text .menu-list__description{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.menu-list--compress-text .menu-list__text,.menu-list--compress-text .menu-list__submenu-chevron{display:none}.menu-list--compress-text .menu-list__submenu-wrap{width:100%}.menu-list--compress-text .menu-list__option{justify-content:center;align-items:center;text-align:center;width:calc(100% - .5rem);max-width:100%;box-sizing:border-box;margin-left:.25rem;margin-right:.25rem;padding:.5rem .35rem}.menu-list--compress-text .menu-list__option--submenu{padding-left:.35rem;padding-right:.35rem}.menu-list--compress-text .menu-list__icon{flex:0 0 auto;width:auto;min-width:1.75rem;display:inline-flex;align-items:center;justify-content:center;padding-top:0}.menu-list__submenu-chevron{flex:0 0 auto;margin-left:auto;padding-left:.35rem;font-size:1rem;line-height:1;color:var(--app-color-text-muted, #6b8299);opacity:.85;display:inline-flex;align-items:center;justify-content:center}.menu-list__submenu-chevron i{font-size:.68rem;line-height:1}.menu-list__icon{flex:0 0 auto;width:1.25rem;height:1.25rem;min-height:1.25rem;display:inline-flex;align-items:center;justify-content:center;text-align:center;color:color-mix(in srgb,var(--app-color-primary, #2b7fd9) 78%,var(--app-color-text-muted, #6b8299));line-height:1;transition:color .18s ease,opacity .18s ease}.menu-list__icon i{display:flex;align-items:center;justify-content:center;width:100%;height:100%;line-height:1;font-size:.95rem;margin-block:auto;flex-shrink:0}.menu-list__option--disabled .menu-list__icon{opacity:.55}.menu-list__icon--spin i{animation:menu-list-spin .8s linear infinite}.menu-list__text{display:flex;flex-direction:column;gap:.1rem;min-width:0;flex:1}.menu-list__label{font-size:.875rem;font-weight:400;line-height:1.25rem;display:inline-flex;align-items:center;min-height:1.25rem;box-sizing:border-box;padding-top:.5rem!important}.menu-list--nested .menu-list__label{font-weight:400;padding-top:.5rem!important}.menu-list--nested .menu-list__icon{transform:translateY(.125rem)}.menu-list__description{font-size:.75rem;color:var(--app-color-text-muted, #6b8299);line-height:1.3}.menu-list:not(.menu-list--compress-text){animation:app-sidebar-nav-reveal-in .45s cubic-bezier(.16,1,.32,1) both}@media(prefers-reduced-motion:reduce){.menu-list:not(.menu-list--compress-text){animation:none}}:host-context(.app-drawer__body) .menu-list__label{padding-top:.5rem!important}:host-context(.app-drawer__body) .menu-list__icon{transform:translateY(.1875rem)}@media(max-width:767.98px){.menu-list.menu-list--nested .menu-list__label{padding-top:.4rem!important}.menu-list.menu-list--nested .menu-list__icon{transform:translateY(.1875rem)}}.menu-submenu__panel{box-sizing:border-box;min-width:0;padding:0;background:transparent;border:none;box-shadow:none;border-radius:10px;overflow:hidden}@keyframes menu-list-spin{to{transform:rotate(360deg)}}:host ::ng-deep .menu-submenu__cdk-panel{background:transparent;box-shadow:none;border-radius:10px}\n"] }]
|
|
2081
|
-
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }], propDecorators: { appTheme: [{ type: i0.Input, args: [{ isSignal: true, alias: "appTheme", required: false }] }], items: [{
|
|
2207
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }], propDecorators: { appTheme: [{ type: i0.Input, args: [{ isSignal: true, alias: "appTheme", required: false }] }], selectionScrollHint: [{ type: i0.Output, args: ["selectionScrollHint"] }], items: [{
|
|
2082
2208
|
type: Input,
|
|
2083
2209
|
args: [{ required: true }]
|
|
2084
2210
|
}], menuId: [{
|
|
@@ -2188,7 +2314,7 @@ class DropdownMenuComponent {
|
|
|
2188
2314
|
this.setOpen(false);
|
|
2189
2315
|
}
|
|
2190
2316
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DropdownMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2191
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "21.2.9", type: DropdownMenuComponent, isStandalone: true, selector: "app-dropdown-menu", inputs: { items: "items", placement: "placement", minWidthPx: "minWidthPx", matchTriggerWidth: ["matchTriggerWidth", "matchTriggerWidth", booleanAttribute], menuId: "menuId" }, outputs: { itemSelect: "itemSelect", openChange: "openChange" }, viewQueries: [{ propertyName: "panelTpl", first: true, predicate: ["panelTpl"], descendants: true, static: true }, { propertyName: "menuList", first: true, predicate: MenuListBodyComponent, descendants: true }], ngImport: i0, template: "<app-dropdown-base\r\n class=\"dropdown-menu\"\r\n [open]=\"open\"\r\n (openChange)=\"onBaseOpenChange($event)\"\r\n [panelTemplate]=\"panelTpl\"\r\n [panelWidthPx]=\"effectivePanelWidth\"\r\n [connectedPositions]=\"connectedPositions\"\r\n [pushConnectedOverlay]=\"true\"\r\n [hasBackdrop]=\"true\"\r\n [closeOnEscape]=\"true\"\r\n [bareOverlayPanel]=\"true\"\r\n>\r\n <span\r\n class=\"dropdown-menu__trigger-slot\"\r\n appDropdownTrigger\r\n (click)=\"onTriggerClick($event)\"\r\n [attr.aria-expanded]=\"open\"\r\n aria-haspopup=\"menu\"\r\n >\r\n <ng-content />\r\n </span>\r\n</app-dropdown-base>\r\n\r\n<ng-template #panelTpl>\r\n <div class=\"dropdown-menu__panel-inner\">\r\n <app-menu-list-body\r\n [items]=\"items\"\r\n [menuId]=\"resolvedMenuId\"\r\n [clickToOpen]=\"false\"\r\n (itemSelect)=\"onItemSelect($event)\"\r\n (closeRequest)=\"onCloseRequest()\"\r\n />\r\n </div>\r\n</ng-template>\r\n", styles: [":host{display:inline-block;max-width:100%;vertical-align:middle}.dropdown-menu{display:inline-flex;max-width:100%;min-width:0}.dropdown-menu__trigger-slot{display:inline-flex;max-width:100%;min-width:0;cursor:pointer}.dropdown-menu__panel-inner{box-sizing:border-box;min-width:0}\n"], dependencies: [{ kind: "component", type: DropdownBaseComponent, selector: "app-dropdown-base", inputs: ["open", "panelTemplate", "panelWidthPx", "closeOnEscape", "hasBackdrop", "connectedPositions", "pushConnectedOverlay", "scrollStrategy", "bareOverlayPanel"], outputs: ["openChange"] }, { kind: "component", type: MenuListBodyComponent, selector: "app-menu-list-body", inputs: ["appTheme", "items", "menuId", "dense", "nested", "selectedItemId", "compressText", "clickToOpen", "groupCollapsible", "groupDefaultExpansion", "persistGroupExpansion", "expandAllGroupsInitially"], outputs: ["itemSelect", "closeRequest", "submenuBack", "groupToggled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2317
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "21.2.9", type: DropdownMenuComponent, isStandalone: true, selector: "app-dropdown-menu", inputs: { items: "items", placement: "placement", minWidthPx: "minWidthPx", matchTriggerWidth: ["matchTriggerWidth", "matchTriggerWidth", booleanAttribute], menuId: "menuId" }, outputs: { itemSelect: "itemSelect", openChange: "openChange" }, viewQueries: [{ propertyName: "panelTpl", first: true, predicate: ["panelTpl"], descendants: true, static: true }, { propertyName: "menuList", first: true, predicate: MenuListBodyComponent, descendants: true }], ngImport: i0, template: "<app-dropdown-base\r\n class=\"dropdown-menu\"\r\n [open]=\"open\"\r\n (openChange)=\"onBaseOpenChange($event)\"\r\n [panelTemplate]=\"panelTpl\"\r\n [panelWidthPx]=\"effectivePanelWidth\"\r\n [connectedPositions]=\"connectedPositions\"\r\n [pushConnectedOverlay]=\"true\"\r\n [hasBackdrop]=\"true\"\r\n [closeOnEscape]=\"true\"\r\n [bareOverlayPanel]=\"true\"\r\n>\r\n <span\r\n class=\"dropdown-menu__trigger-slot\"\r\n appDropdownTrigger\r\n (click)=\"onTriggerClick($event)\"\r\n [attr.aria-expanded]=\"open\"\r\n aria-haspopup=\"menu\"\r\n >\r\n <ng-content />\r\n </span>\r\n</app-dropdown-base>\r\n\r\n<ng-template #panelTpl>\r\n <div class=\"dropdown-menu__panel-inner\">\r\n <app-menu-list-body\r\n [items]=\"items\"\r\n [menuId]=\"resolvedMenuId\"\r\n [clickToOpen]=\"false\"\r\n (itemSelect)=\"onItemSelect($event)\"\r\n (closeRequest)=\"onCloseRequest()\"\r\n />\r\n </div>\r\n</ng-template>\r\n", styles: [":host{display:inline-block;max-width:100%;vertical-align:middle}.dropdown-menu{display:inline-flex;max-width:100%;min-width:0}.dropdown-menu__trigger-slot{display:inline-flex;max-width:100%;min-width:0;cursor:pointer}.dropdown-menu__panel-inner{box-sizing:border-box;min-width:0}\n"], dependencies: [{ kind: "component", type: DropdownBaseComponent, selector: "app-dropdown-base", inputs: ["open", "panelTemplate", "panelWidthPx", "closeOnEscape", "hasBackdrop", "connectedPositions", "pushConnectedOverlay", "scrollStrategy", "bareOverlayPanel"], outputs: ["openChange"] }, { kind: "component", type: MenuListBodyComponent, selector: "app-menu-list-body", inputs: ["appTheme", "items", "menuId", "dense", "nested", "selectedItemId", "compressText", "clickToOpen", "groupCollapsible", "groupDefaultExpansion", "persistGroupExpansion", "expandAllGroupsInitially"], outputs: ["selectionScrollHint", "itemSelect", "closeRequest", "submenuBack", "groupToggled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2192
2318
|
}
|
|
2193
2319
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DropdownMenuComponent, decorators: [{
|
|
2194
2320
|
type: Component,
|
|
@@ -10121,7 +10247,10 @@ function filterOneNode(node, qNormalized, rawQuery) {
|
|
|
10121
10247
|
class MenuListComponent {
|
|
10122
10248
|
constructor() {
|
|
10123
10249
|
this.cdr = inject(ChangeDetectorRef);
|
|
10250
|
+
this.injector = inject(Injector);
|
|
10251
|
+
this.destroyRef = inject(DestroyRef);
|
|
10124
10252
|
this.appTheme = input(...(ngDevMode ? [undefined, { debugName: "appTheme" }] : /* istanbul ignore next */ []));
|
|
10253
|
+
this.bodyRouteSyncGen = 0;
|
|
10125
10254
|
this.items = [];
|
|
10126
10255
|
this.menuId = 'app-menu';
|
|
10127
10256
|
this.dense = false;
|
|
@@ -10143,8 +10272,16 @@ class MenuListComponent {
|
|
|
10143
10272
|
this.closeRequest = new EventEmitter();
|
|
10144
10273
|
this.submenuBack = new EventEmitter();
|
|
10145
10274
|
this.groupToggled = output();
|
|
10275
|
+
/** Ver {@link MenuListBodyComponent.selectionScrollHint}. */
|
|
10276
|
+
this.selectionScrollHint = output();
|
|
10146
10277
|
this.searchQuery = '';
|
|
10147
10278
|
this.displayItems = [];
|
|
10279
|
+
this.destroyRef.onDestroy(() => {
|
|
10280
|
+
this.bodyRouteSyncGen++;
|
|
10281
|
+
});
|
|
10282
|
+
}
|
|
10283
|
+
ngAfterViewInit() {
|
|
10284
|
+
this.scheduleBodyRouteSelectionSync();
|
|
10148
10285
|
}
|
|
10149
10286
|
get showSearchField() {
|
|
10150
10287
|
return this.searchable && !this.nested && !this.compressText;
|
|
@@ -10180,6 +10317,30 @@ class MenuListComponent {
|
|
|
10180
10317
|
changes['persistGroupExpansion']) {
|
|
10181
10318
|
this.cdr.markForCheck();
|
|
10182
10319
|
}
|
|
10320
|
+
if (changes['selectedItemId'] ||
|
|
10321
|
+
changes['items'] ||
|
|
10322
|
+
changes['searchable'] ||
|
|
10323
|
+
changes['compressText'] ||
|
|
10324
|
+
changes['nested'] ||
|
|
10325
|
+
changes['groupCollapsible'] ||
|
|
10326
|
+
changes['groupDefaultExpansion'] ||
|
|
10327
|
+
changes['persistGroupExpansion'] ||
|
|
10328
|
+
changes['clickToOpen']) {
|
|
10329
|
+
this.scheduleBodyRouteSelectionSync();
|
|
10330
|
+
}
|
|
10331
|
+
}
|
|
10332
|
+
/**
|
|
10333
|
+
* O corpo do menu só existe após o primeiro render; no drawer mobile isso atrasa `ensureExpanded`
|
|
10334
|
+
* relativamente ao `ngOnChanges` do corpo — repetimos após `afterNextRender`.
|
|
10335
|
+
*/
|
|
10336
|
+
scheduleBodyRouteSelectionSync() {
|
|
10337
|
+
const gen = ++this.bodyRouteSyncGen;
|
|
10338
|
+
afterNextRender(() => {
|
|
10339
|
+
if (gen !== this.bodyRouteSyncGen) {
|
|
10340
|
+
return;
|
|
10341
|
+
}
|
|
10342
|
+
this.body?.syncRouteSelectionExpansion();
|
|
10343
|
+
}, { injector: this.injector });
|
|
10183
10344
|
}
|
|
10184
10345
|
onSearchQueryInput(value) {
|
|
10185
10346
|
this.searchQuery = value ?? '';
|
|
@@ -10193,6 +10354,17 @@ class MenuListComponent {
|
|
|
10193
10354
|
focusFirstOption() {
|
|
10194
10355
|
this.body?.focusFirstOption();
|
|
10195
10356
|
}
|
|
10357
|
+
/**
|
|
10358
|
+
* Usado pela `app-sidebar` ao abrir o drawer móvel: garante {@link MenuListBodyComponent.syncRouteSelectionExpansion}
|
|
10359
|
+
* antes do scroll (grupos fechados em `sessionStorage` passam a abrir no caminho do item activo).
|
|
10360
|
+
*/
|
|
10361
|
+
syncSelectionForMobileDrawerOpen() {
|
|
10362
|
+
if (this.body) {
|
|
10363
|
+
this.body.syncRouteSelectionExpansion();
|
|
10364
|
+
return;
|
|
10365
|
+
}
|
|
10366
|
+
this.scheduleBodyRouteSelectionSync();
|
|
10367
|
+
}
|
|
10196
10368
|
syncDisplayItems() {
|
|
10197
10369
|
if (!this.searchable || this.nested || this.compressText) {
|
|
10198
10370
|
this.displayItems = [...(this.items ?? [])];
|
|
@@ -10202,12 +10374,12 @@ class MenuListComponent {
|
|
|
10202
10374
|
}
|
|
10203
10375
|
}
|
|
10204
10376
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: MenuListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
10205
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: MenuListComponent, isStandalone: true, selector: "app-menu-list", inputs: { appTheme: { classPropertyName: "appTheme", publicName: "appTheme", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: false, isRequired: true, transformFunction: null }, menuId: { classPropertyName: "menuId", publicName: "menuId", isSignal: false, isRequired: false, transformFunction: null }, dense: { classPropertyName: "dense", publicName: "dense", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, nested: { classPropertyName: "nested", publicName: "nested", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, selectedItemId: { classPropertyName: "selectedItemId", publicName: "selectedItemId", isSignal: false, isRequired: false, transformFunction: null }, compressText: { classPropertyName: "compressText", publicName: "compressText", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, clickToOpen: { classPropertyName: "clickToOpen", publicName: "clickToOpen", isSignal: false, isRequired: false, transformFunction: null }, groupCollapsible: { classPropertyName: "groupCollapsible", publicName: "groupCollapsible", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, groupDefaultExpansion: { classPropertyName: "groupDefaultExpansion", publicName: "groupDefaultExpansion", isSignal: false, isRequired: false, transformFunction: null }, persistGroupExpansion: { classPropertyName: "persistGroupExpansion", publicName: "persistGroupExpansion", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { itemSelect: "itemSelect", closeRequest: "closeRequest", submenuBack: "submenuBack", groupToggled: "groupToggled" }, viewQueries: [{ propertyName: "body", first: true, predicate: MenuListBodyComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<app-menu-list-body\n [items]=\"displayItems\"\n [menuId]=\"menuId\"\n [nested]=\"nested\"\n [dense]=\"dense\"\n [compressText]=\"compressText\"\n [groupCollapsible]=\"groupCollapsible\"\n [groupDefaultExpansion]=\"groupDefaultExpansion\"\n [persistGroupExpansion]=\"persistGroupExpansion\"\n [clickToOpen]=\"clickToOpen\"\n [selectedItemId]=\"selectedItemId\"\n [appTheme]=\"appTheme()\"\n [expandAllGroupsInitially]=\"expandAllGroupsWhenSearching\"\n (itemSelect)=\"itemSelect.emit($event)\"\n (closeRequest)=\"closeRequest.emit()\"\n (submenuBack)=\"submenuBack.emit()\"\n (groupToggled)=\"groupToggled.emit($event)\"\n>\n @if (showSearchField) {\n <div class=\"menu-list__search\" role=\"search\">\n <app-text-field\n class=\"menu-list__search-field\"\n [id]=\"menuId + '-search'\"\n [name]=\"menuId + '-menu-search'\"\n size=\"sm\"\n [ngModel]=\"searchQuery\"\n (ngModelChange)=\"onSearchQueryInput($event)\"\n [placeholder]=\"searchPlaceholder\"\n [label]=\"''\"\n [showPrefixIcon]=\"true\"\n prefixIcon=\"fa-solid fa-magnifying-glass\"\n [clearable]=\"true\"\n [autocomplete]=\"false\"\n />\n </div>\n }\n @if (showSearchNoResults) {\n <p class=\"menu-list__search-empty\">Nenhum item encontrado</p>\n }\n</app-menu-list-body>\n", styles: ["@charset \"UTF-8\";@keyframes app-sidebar-nav-reveal-in{0%{opacity:0;transform:translate3d(-.45rem,0,0)}to{opacity:1;transform:translateZ(0)}}:host{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;min-width:0;box-sizing:border-box;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.menu-list{background:var(--app-color-surface, #ffffff);border:1px solid var(--app-color-border-subtle, rgba(26, 47, 69, .12));border-radius:10px;box-shadow:0 10px 28px -14px #0f172a29;max-height:min(70vh,22rem);overflow-x:hidden;overflow-y:auto;display:flex;flex-direction:column;flex:1 1 auto;min-height:0;min-width:0;overflow:hidden;gap:.35rem;padding:.45rem 0;outline:none;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.menu-list--dense{padding:.2rem 0;gap:0}.menu-list--dense .menu-list__items{gap:0}.menu-list--dense.menu-list--compress-text .menu-list__items{gap:.25rem}.menu-list__toolbar{flex:0 0 auto;min-width:0}.menu-list__viewport{flex:1 1 auto;min-height:0;min-width:0;overflow-x:hidden;overflow-y:auto;-webkit-overflow-scrolling:touch;outline:none;scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--app-color-text-primary, #1a2f45) 34%,transparent) transparent}.menu-list__viewport::-webkit-scrollbar{width:4px;height:4px}.menu-list__viewport::-webkit-scrollbar-track{background:transparent}.menu-list__viewport::-webkit-scrollbar-thumb{border-radius:999px;background:color-mix(in srgb,var(--app-color-text-primary, #1a2f45) 40%,transparent)}.menu-list__viewport::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--app-color-text-primary, #1a2f45) 55%,transparent)}.menu-list__items{display:flex;flex-direction:column;gap:.12rem;min-width:0}.menu-list__search{margin:0 .35rem .12rem;min-width:0;user-select:text;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text}.menu-list__search-field{display:block;width:100%}.menu-list__search-empty{margin:-.05rem .75rem 0;padding:0 0 .15rem;font-size:.75rem;line-height:1.35;font-weight:400;color:var(--app-color-text-muted, #6b8299);opacity:.88}.menu-list__group-row{display:block;width:100%}.menu-list__group-row--pinned .menu-list__group-label{color:var(--app-color-nav-group-heading, #9ca3af)}.menu-list__submenu-wrap{position:relative;display:block}.menu-list__option{display:flex;align-items:center;box-sizing:border-box;gap:.6875rem;margin:0 .25rem;padding:.5625rem .65rem;border-radius:8px;cursor:pointer;color:var(--app-color-text-primary, #1a2f45);background:transparent;border:1px solid transparent;text-align:left;font:inherit;line-height:1.25;transition:background-color .18s ease,color .18s ease,box-shadow .18s ease,border-color .18s ease}.menu-list__option:focus-visible{outline:2px solid var(--app-color-focus-ring-strong, rgba(43, 127, 217, .45));outline-offset:1px}.menu-list__option:hover:not(.menu-list__option--disabled):not(.menu-list__option--loading){background:#0f172a0b}.menu-list__option.menu-list__option--active:not(.menu-list__option--disabled):not(.menu-list__option--loading){background:#0f172a0e;border-color:transparent}.menu-list__option.menu-list__option--active:not(.menu-list__option--disabled):not(.menu-list__option--loading):not(.menu-list__option--selected){box-shadow:none}.menu-list__option.menu-list__option--disabled{cursor:not-allowed;color:var(--app-color-text-muted, #6b8299);background:transparent;opacity:.72}.menu-list__option.menu-list__option--loading{cursor:wait;opacity:.92;pointer-events:none}.menu-list__option.menu-list__option--danger:not(.menu-list__option--disabled):not(.menu-list__option--loading){color:var(--app-color-error, #b91c1c)}.menu-list__option.menu-list__option--danger:not(.menu-list__option--disabled):not(.menu-list__option--loading):hover,.menu-list__option.menu-list__option--danger:not(.menu-list__option--disabled):not(.menu-list__option--loading).menu-list__option--active{background:var(--app-color-error-bg-subtle, rgba(185, 28, 28, .12));border-color:transparent;box-shadow:inset 2px 0 0 0 var(--app-color-error-border, #dc2626)}.menu-list__option--submenu{padding-right:.35rem}.menu-list__option--selected:not(.menu-list__option--disabled){background:color-mix(in srgb,var(--app-color-primary) 10%,transparent);border-radius:8px;border-color:transparent;box-shadow:inset 2px 0 0 0 var(--app-color-primary, #2b7fd9)}.menu-list__option--selected:not(.menu-list__option--disabled) .menu-list__label{color:color-mix(in srgb,var(--app-color-primary, #2b7fd9) 88%,var(--app-color-nav-option-label, #374151));font-weight:500}.menu-list__option--selected:not(.menu-list__option--disabled) .menu-list__icon{color:var(--app-color-primary, #2b7fd9)}.menu-list__option:not(.menu-list__option--danger):not(.menu-list__option--disabled):not(.menu-list__option--selected) .menu-list__label{color:var(--app-color-nav-option-label, #374151)}.menu-list--compress-text .menu-list__label,.menu-list--compress-text .menu-list__description{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.menu-list--compress-text .menu-list__text,.menu-list--compress-text .menu-list__submenu-chevron{display:none}.menu-list--compress-text .menu-list__submenu-wrap{width:100%}.menu-list--compress-text .menu-list__option{justify-content:center;align-items:center;text-align:center;width:calc(100% - .5rem);max-width:100%;box-sizing:border-box;margin-left:.25rem;margin-right:.25rem;padding:.5rem .35rem}.menu-list--compress-text .menu-list__option--submenu{padding-left:.35rem;padding-right:.35rem}.menu-list--compress-text .menu-list__icon{flex:0 0 auto;width:auto;min-width:1.75rem;display:inline-flex;align-items:center;justify-content:center;padding-top:0}.menu-list__submenu-chevron{flex:0 0 auto;margin-left:auto;padding-left:.35rem;font-size:1rem;line-height:1;color:var(--app-color-text-muted, #6b8299);opacity:.85;display:inline-flex;align-items:center;justify-content:center}.menu-list__submenu-chevron i{font-size:.68rem;line-height:1}.menu-list__icon{flex:0 0 auto;width:1.25rem;height:1.25rem;min-height:1.25rem;display:inline-flex;align-items:center;justify-content:center;text-align:center;color:color-mix(in srgb,var(--app-color-primary, #2b7fd9) 78%,var(--app-color-text-muted, #6b8299));line-height:1;transition:color .18s ease,opacity .18s ease}.menu-list__icon i{display:flex;align-items:center;justify-content:center;width:100%;height:100%;line-height:1;font-size:.95rem;margin-block:auto;flex-shrink:0}.menu-list__option--disabled .menu-list__icon{opacity:.55}.menu-list__icon--spin i{animation:menu-list-spin .8s linear infinite}.menu-list__text{display:flex;flex-direction:column;gap:.1rem;min-width:0;flex:1}.menu-list__label{font-size:.875rem;font-weight:400;line-height:1.25rem;display:inline-flex;align-items:center;min-height:1.25rem;box-sizing:border-box;padding-top:.5rem!important}.menu-list--nested .menu-list__label{font-weight:400;padding-top:.5rem!important}.menu-list--nested .menu-list__icon{transform:translateY(.125rem)}.menu-list__description{font-size:.75rem;color:var(--app-color-text-muted, #6b8299);line-height:1.3}.menu-list:not(.menu-list--compress-text){animation:app-sidebar-nav-reveal-in .45s cubic-bezier(.16,1,.32,1) both}@media(prefers-reduced-motion:reduce){.menu-list:not(.menu-list--compress-text){animation:none}}:host-context(.app-drawer__body) .menu-list__label{padding-top:.5rem!important}:host-context(.app-drawer__body) .menu-list__icon{transform:translateY(.1875rem)}@media(max-width:767.98px){.menu-list.menu-list--nested .menu-list__label{padding-top:.4rem!important}.menu-list.menu-list--nested .menu-list__icon{transform:translateY(.1875rem)}}.menu-submenu__panel{box-sizing:border-box;min-width:0;padding:0;background:transparent;border:none;box-shadow:none;border-radius:10px;overflow:hidden}@keyframes menu-list-spin{to{transform:rotate(360deg)}}:host ::ng-deep .menu-submenu__cdk-panel{background:transparent;box-shadow:none;border-radius:10px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: TextFieldComponent, selector: "app-text-field", inputs: ["maxLength"] }, { kind: "component", type: MenuListBodyComponent, selector: "app-menu-list-body", inputs: ["appTheme", "items", "menuId", "dense", "nested", "selectedItemId", "compressText", "clickToOpen", "groupCollapsible", "groupDefaultExpansion", "persistGroupExpansion", "expandAllGroupsInitially"], outputs: ["itemSelect", "closeRequest", "submenuBack", "groupToggled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
10377
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: MenuListComponent, isStandalone: true, selector: "app-menu-list", inputs: { appTheme: { classPropertyName: "appTheme", publicName: "appTheme", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: false, isRequired: true, transformFunction: null }, menuId: { classPropertyName: "menuId", publicName: "menuId", isSignal: false, isRequired: false, transformFunction: null }, dense: { classPropertyName: "dense", publicName: "dense", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, nested: { classPropertyName: "nested", publicName: "nested", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, selectedItemId: { classPropertyName: "selectedItemId", publicName: "selectedItemId", isSignal: false, isRequired: false, transformFunction: null }, compressText: { classPropertyName: "compressText", publicName: "compressText", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, clickToOpen: { classPropertyName: "clickToOpen", publicName: "clickToOpen", isSignal: false, isRequired: false, transformFunction: null }, groupCollapsible: { classPropertyName: "groupCollapsible", publicName: "groupCollapsible", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, groupDefaultExpansion: { classPropertyName: "groupDefaultExpansion", publicName: "groupDefaultExpansion", isSignal: false, isRequired: false, transformFunction: null }, persistGroupExpansion: { classPropertyName: "persistGroupExpansion", publicName: "persistGroupExpansion", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { itemSelect: "itemSelect", closeRequest: "closeRequest", submenuBack: "submenuBack", groupToggled: "groupToggled", selectionScrollHint: "selectionScrollHint" }, viewQueries: [{ propertyName: "body", first: true, predicate: MenuListBodyComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<app-menu-list-body\n [items]=\"displayItems\"\n [menuId]=\"menuId\"\n [nested]=\"nested\"\n [dense]=\"dense\"\n [compressText]=\"compressText\"\n [groupCollapsible]=\"groupCollapsible\"\n [groupDefaultExpansion]=\"groupDefaultExpansion\"\n [persistGroupExpansion]=\"persistGroupExpansion\"\n [clickToOpen]=\"clickToOpen\"\n [selectedItemId]=\"selectedItemId\"\n [appTheme]=\"appTheme()\"\n [expandAllGroupsInitially]=\"expandAllGroupsWhenSearching\"\n (itemSelect)=\"itemSelect.emit($event)\"\n (closeRequest)=\"closeRequest.emit()\"\n (submenuBack)=\"submenuBack.emit()\"\n (groupToggled)=\"groupToggled.emit($event)\"\n (selectionScrollHint)=\"selectionScrollHint.emit()\"\n>\n @if (showSearchField) {\n <div class=\"menu-list__search\" role=\"search\">\n <app-text-field\n class=\"menu-list__search-field\"\n [id]=\"menuId + '-search'\"\n [name]=\"menuId + '-menu-search'\"\n size=\"sm\"\n [ngModel]=\"searchQuery\"\n (ngModelChange)=\"onSearchQueryInput($event)\"\n [placeholder]=\"searchPlaceholder\"\n [label]=\"''\"\n [showPrefixIcon]=\"true\"\n prefixIcon=\"fa-solid fa-magnifying-glass\"\n [clearable]=\"true\"\n [autocomplete]=\"false\"\n />\n </div>\n }\n @if (showSearchNoResults) {\n <p class=\"menu-list__search-empty\">Nenhum item encontrado</p>\n }\n</app-menu-list-body>\n", styles: ["@charset \"UTF-8\";@keyframes app-sidebar-nav-reveal-in{0%{opacity:0;transform:translate3d(-.45rem,0,0)}to{opacity:1;transform:translateZ(0)}}:host{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;min-width:0;box-sizing:border-box;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.menu-list{background:var(--app-color-surface, #ffffff);border:1px solid var(--app-color-border-subtle, rgba(26, 47, 69, .12));border-radius:10px;box-shadow:0 10px 28px -14px #0f172a29;max-height:min(70vh,22rem);overflow-x:hidden;overflow-y:auto;display:flex;flex-direction:column;flex:1 1 auto;min-height:0;min-width:0;overflow:hidden;gap:.35rem;padding:.45rem 0;outline:none;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.menu-list--dense{padding:.2rem 0;gap:0}.menu-list--dense .menu-list__items{gap:0}.menu-list--dense.menu-list--compress-text .menu-list__items{gap:.25rem}.menu-list__toolbar{flex:0 0 auto;min-width:0}.menu-list__viewport{flex:1 1 auto;min-height:0;min-width:0;overflow-x:hidden;overflow-y:auto;-webkit-overflow-scrolling:touch;outline:none;scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--app-color-text-primary, #1a2f45) 34%,transparent) transparent}.menu-list__viewport::-webkit-scrollbar{width:4px;height:4px}.menu-list__viewport::-webkit-scrollbar-track{background:transparent}.menu-list__viewport::-webkit-scrollbar-thumb{border-radius:999px;background:color-mix(in srgb,var(--app-color-text-primary, #1a2f45) 40%,transparent)}.menu-list__viewport::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--app-color-text-primary, #1a2f45) 55%,transparent)}.menu-list__items{display:flex;flex-direction:column;gap:.12rem;min-width:0}.menu-list__search{margin:0 .35rem .12rem;min-width:0;user-select:text;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text}.menu-list__search-field{display:block;width:100%}.menu-list__search-empty{margin:-.05rem .75rem 0;padding:0 0 .15rem;font-size:.75rem;line-height:1.35;font-weight:400;color:var(--app-color-text-muted, #6b8299);opacity:.88}.menu-list__group-row{display:block;width:100%}.menu-list__group-row--pinned .menu-list__group-label{color:var(--app-color-nav-group-heading, #9ca3af)}.menu-list__submenu-wrap{position:relative;display:block}.menu-list__option{display:flex;align-items:center;box-sizing:border-box;gap:.6875rem;margin:0 .25rem;padding:.5625rem .65rem;border-radius:8px;cursor:pointer;color:var(--app-color-text-primary, #1a2f45);background:transparent;border:1px solid transparent;text-align:left;font:inherit;line-height:1.25;transition:background-color .18s ease,color .18s ease,box-shadow .18s ease,border-color .18s ease}.menu-list__option:focus-visible{outline:2px solid var(--app-color-focus-ring-strong, rgba(43, 127, 217, .45));outline-offset:1px}.menu-list__option:hover:not(.menu-list__option--disabled):not(.menu-list__option--loading){background:#0f172a0b}.menu-list__option.menu-list__option--active:not(.menu-list__option--disabled):not(.menu-list__option--loading){background:#0f172a0e;border-color:transparent}.menu-list__option.menu-list__option--active:not(.menu-list__option--disabled):not(.menu-list__option--loading):not(.menu-list__option--selected){box-shadow:none}.menu-list__option.menu-list__option--disabled{cursor:not-allowed;color:var(--app-color-text-muted, #6b8299);background:transparent;opacity:.72}.menu-list__option.menu-list__option--loading{cursor:wait;opacity:.92;pointer-events:none}.menu-list__option.menu-list__option--danger:not(.menu-list__option--disabled):not(.menu-list__option--loading){color:var(--app-color-error, #b91c1c)}.menu-list__option.menu-list__option--danger:not(.menu-list__option--disabled):not(.menu-list__option--loading):hover,.menu-list__option.menu-list__option--danger:not(.menu-list__option--disabled):not(.menu-list__option--loading).menu-list__option--active{background:var(--app-color-error-bg-subtle, rgba(185, 28, 28, .12));border-color:transparent;box-shadow:inset 2px 0 0 0 var(--app-color-error-border, #dc2626)}.menu-list__option--submenu{padding-right:.35rem}.menu-list__option--selected:not(.menu-list__option--disabled){background:color-mix(in srgb,var(--app-color-primary) 10%,transparent);border-radius:8px;border-color:transparent;box-shadow:inset 2px 0 0 0 var(--app-color-primary, #2b7fd9)}.menu-list__option--selected:not(.menu-list__option--disabled) .menu-list__label{color:color-mix(in srgb,var(--app-color-primary, #2b7fd9) 88%,var(--app-color-nav-option-label, #374151));font-weight:500}.menu-list__option--selected:not(.menu-list__option--disabled) .menu-list__icon{color:var(--app-color-primary, #2b7fd9)}.menu-list__option:not(.menu-list__option--danger):not(.menu-list__option--disabled):not(.menu-list__option--selected) .menu-list__label{color:var(--app-color-nav-option-label, #374151)}.menu-list--compress-text .menu-list__label,.menu-list--compress-text .menu-list__description{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.menu-list--compress-text .menu-list__text,.menu-list--compress-text .menu-list__submenu-chevron{display:none}.menu-list--compress-text .menu-list__submenu-wrap{width:100%}.menu-list--compress-text .menu-list__option{justify-content:center;align-items:center;text-align:center;width:calc(100% - .5rem);max-width:100%;box-sizing:border-box;margin-left:.25rem;margin-right:.25rem;padding:.5rem .35rem}.menu-list--compress-text .menu-list__option--submenu{padding-left:.35rem;padding-right:.35rem}.menu-list--compress-text .menu-list__icon{flex:0 0 auto;width:auto;min-width:1.75rem;display:inline-flex;align-items:center;justify-content:center;padding-top:0}.menu-list__submenu-chevron{flex:0 0 auto;margin-left:auto;padding-left:.35rem;font-size:1rem;line-height:1;color:var(--app-color-text-muted, #6b8299);opacity:.85;display:inline-flex;align-items:center;justify-content:center}.menu-list__submenu-chevron i{font-size:.68rem;line-height:1}.menu-list__icon{flex:0 0 auto;width:1.25rem;height:1.25rem;min-height:1.25rem;display:inline-flex;align-items:center;justify-content:center;text-align:center;color:color-mix(in srgb,var(--app-color-primary, #2b7fd9) 78%,var(--app-color-text-muted, #6b8299));line-height:1;transition:color .18s ease,opacity .18s ease}.menu-list__icon i{display:flex;align-items:center;justify-content:center;width:100%;height:100%;line-height:1;font-size:.95rem;margin-block:auto;flex-shrink:0}.menu-list__option--disabled .menu-list__icon{opacity:.55}.menu-list__icon--spin i{animation:menu-list-spin .8s linear infinite}.menu-list__text{display:flex;flex-direction:column;gap:.1rem;min-width:0;flex:1}.menu-list__label{font-size:.875rem;font-weight:400;line-height:1.25rem;display:inline-flex;align-items:center;min-height:1.25rem;box-sizing:border-box;padding-top:.5rem!important}.menu-list--nested .menu-list__label{font-weight:400;padding-top:.5rem!important}.menu-list--nested .menu-list__icon{transform:translateY(.125rem)}.menu-list__description{font-size:.75rem;color:var(--app-color-text-muted, #6b8299);line-height:1.3}.menu-list:not(.menu-list--compress-text){animation:app-sidebar-nav-reveal-in .45s cubic-bezier(.16,1,.32,1) both}@media(prefers-reduced-motion:reduce){.menu-list:not(.menu-list--compress-text){animation:none}}:host-context(.app-drawer__body) .menu-list__label{padding-top:.5rem!important}:host-context(.app-drawer__body) .menu-list__icon{transform:translateY(.1875rem)}@media(max-width:767.98px){.menu-list.menu-list--nested .menu-list__label{padding-top:.4rem!important}.menu-list.menu-list--nested .menu-list__icon{transform:translateY(.1875rem)}}.menu-submenu__panel{box-sizing:border-box;min-width:0;padding:0;background:transparent;border:none;box-shadow:none;border-radius:10px;overflow:hidden}@keyframes menu-list-spin{to{transform:rotate(360deg)}}:host ::ng-deep .menu-submenu__cdk-panel{background:transparent;box-shadow:none;border-radius:10px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: TextFieldComponent, selector: "app-text-field", inputs: ["maxLength"] }, { kind: "component", type: MenuListBodyComponent, selector: "app-menu-list-body", inputs: ["appTheme", "items", "menuId", "dense", "nested", "selectedItemId", "compressText", "clickToOpen", "groupCollapsible", "groupDefaultExpansion", "persistGroupExpansion", "expandAllGroupsInitially"], outputs: ["selectionScrollHint", "itemSelect", "closeRequest", "submenuBack", "groupToggled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
10206
10378
|
}
|
|
10207
10379
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: MenuListComponent, decorators: [{
|
|
10208
10380
|
type: Component,
|
|
10209
|
-
args: [{ selector: 'app-menu-list', changeDetection: ChangeDetectionStrategy.OnPush, imports: [FormsModule, TextFieldComponent, MenuListBodyComponent], template: "<app-menu-list-body\n [items]=\"displayItems\"\n [menuId]=\"menuId\"\n [nested]=\"nested\"\n [dense]=\"dense\"\n [compressText]=\"compressText\"\n [groupCollapsible]=\"groupCollapsible\"\n [groupDefaultExpansion]=\"groupDefaultExpansion\"\n [persistGroupExpansion]=\"persistGroupExpansion\"\n [clickToOpen]=\"clickToOpen\"\n [selectedItemId]=\"selectedItemId\"\n [appTheme]=\"appTheme()\"\n [expandAllGroupsInitially]=\"expandAllGroupsWhenSearching\"\n (itemSelect)=\"itemSelect.emit($event)\"\n (closeRequest)=\"closeRequest.emit()\"\n (submenuBack)=\"submenuBack.emit()\"\n (groupToggled)=\"groupToggled.emit($event)\"\n>\n @if (showSearchField) {\n <div class=\"menu-list__search\" role=\"search\">\n <app-text-field\n class=\"menu-list__search-field\"\n [id]=\"menuId + '-search'\"\n [name]=\"menuId + '-menu-search'\"\n size=\"sm\"\n [ngModel]=\"searchQuery\"\n (ngModelChange)=\"onSearchQueryInput($event)\"\n [placeholder]=\"searchPlaceholder\"\n [label]=\"''\"\n [showPrefixIcon]=\"true\"\n prefixIcon=\"fa-solid fa-magnifying-glass\"\n [clearable]=\"true\"\n [autocomplete]=\"false\"\n />\n </div>\n }\n @if (showSearchNoResults) {\n <p class=\"menu-list__search-empty\">Nenhum item encontrado</p>\n }\n</app-menu-list-body>\n", styles: ["@charset \"UTF-8\";@keyframes app-sidebar-nav-reveal-in{0%{opacity:0;transform:translate3d(-.45rem,0,0)}to{opacity:1;transform:translateZ(0)}}:host{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;min-width:0;box-sizing:border-box;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.menu-list{background:var(--app-color-surface, #ffffff);border:1px solid var(--app-color-border-subtle, rgba(26, 47, 69, .12));border-radius:10px;box-shadow:0 10px 28px -14px #0f172a29;max-height:min(70vh,22rem);overflow-x:hidden;overflow-y:auto;display:flex;flex-direction:column;flex:1 1 auto;min-height:0;min-width:0;overflow:hidden;gap:.35rem;padding:.45rem 0;outline:none;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.menu-list--dense{padding:.2rem 0;gap:0}.menu-list--dense .menu-list__items{gap:0}.menu-list--dense.menu-list--compress-text .menu-list__items{gap:.25rem}.menu-list__toolbar{flex:0 0 auto;min-width:0}.menu-list__viewport{flex:1 1 auto;min-height:0;min-width:0;overflow-x:hidden;overflow-y:auto;-webkit-overflow-scrolling:touch;outline:none;scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--app-color-text-primary, #1a2f45) 34%,transparent) transparent}.menu-list__viewport::-webkit-scrollbar{width:4px;height:4px}.menu-list__viewport::-webkit-scrollbar-track{background:transparent}.menu-list__viewport::-webkit-scrollbar-thumb{border-radius:999px;background:color-mix(in srgb,var(--app-color-text-primary, #1a2f45) 40%,transparent)}.menu-list__viewport::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--app-color-text-primary, #1a2f45) 55%,transparent)}.menu-list__items{display:flex;flex-direction:column;gap:.12rem;min-width:0}.menu-list__search{margin:0 .35rem .12rem;min-width:0;user-select:text;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text}.menu-list__search-field{display:block;width:100%}.menu-list__search-empty{margin:-.05rem .75rem 0;padding:0 0 .15rem;font-size:.75rem;line-height:1.35;font-weight:400;color:var(--app-color-text-muted, #6b8299);opacity:.88}.menu-list__group-row{display:block;width:100%}.menu-list__group-row--pinned .menu-list__group-label{color:var(--app-color-nav-group-heading, #9ca3af)}.menu-list__submenu-wrap{position:relative;display:block}.menu-list__option{display:flex;align-items:center;box-sizing:border-box;gap:.6875rem;margin:0 .25rem;padding:.5625rem .65rem;border-radius:8px;cursor:pointer;color:var(--app-color-text-primary, #1a2f45);background:transparent;border:1px solid transparent;text-align:left;font:inherit;line-height:1.25;transition:background-color .18s ease,color .18s ease,box-shadow .18s ease,border-color .18s ease}.menu-list__option:focus-visible{outline:2px solid var(--app-color-focus-ring-strong, rgba(43, 127, 217, .45));outline-offset:1px}.menu-list__option:hover:not(.menu-list__option--disabled):not(.menu-list__option--loading){background:#0f172a0b}.menu-list__option.menu-list__option--active:not(.menu-list__option--disabled):not(.menu-list__option--loading){background:#0f172a0e;border-color:transparent}.menu-list__option.menu-list__option--active:not(.menu-list__option--disabled):not(.menu-list__option--loading):not(.menu-list__option--selected){box-shadow:none}.menu-list__option.menu-list__option--disabled{cursor:not-allowed;color:var(--app-color-text-muted, #6b8299);background:transparent;opacity:.72}.menu-list__option.menu-list__option--loading{cursor:wait;opacity:.92;pointer-events:none}.menu-list__option.menu-list__option--danger:not(.menu-list__option--disabled):not(.menu-list__option--loading){color:var(--app-color-error, #b91c1c)}.menu-list__option.menu-list__option--danger:not(.menu-list__option--disabled):not(.menu-list__option--loading):hover,.menu-list__option.menu-list__option--danger:not(.menu-list__option--disabled):not(.menu-list__option--loading).menu-list__option--active{background:var(--app-color-error-bg-subtle, rgba(185, 28, 28, .12));border-color:transparent;box-shadow:inset 2px 0 0 0 var(--app-color-error-border, #dc2626)}.menu-list__option--submenu{padding-right:.35rem}.menu-list__option--selected:not(.menu-list__option--disabled){background:color-mix(in srgb,var(--app-color-primary) 10%,transparent);border-radius:8px;border-color:transparent;box-shadow:inset 2px 0 0 0 var(--app-color-primary, #2b7fd9)}.menu-list__option--selected:not(.menu-list__option--disabled) .menu-list__label{color:color-mix(in srgb,var(--app-color-primary, #2b7fd9) 88%,var(--app-color-nav-option-label, #374151));font-weight:500}.menu-list__option--selected:not(.menu-list__option--disabled) .menu-list__icon{color:var(--app-color-primary, #2b7fd9)}.menu-list__option:not(.menu-list__option--danger):not(.menu-list__option--disabled):not(.menu-list__option--selected) .menu-list__label{color:var(--app-color-nav-option-label, #374151)}.menu-list--compress-text .menu-list__label,.menu-list--compress-text .menu-list__description{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.menu-list--compress-text .menu-list__text,.menu-list--compress-text .menu-list__submenu-chevron{display:none}.menu-list--compress-text .menu-list__submenu-wrap{width:100%}.menu-list--compress-text .menu-list__option{justify-content:center;align-items:center;text-align:center;width:calc(100% - .5rem);max-width:100%;box-sizing:border-box;margin-left:.25rem;margin-right:.25rem;padding:.5rem .35rem}.menu-list--compress-text .menu-list__option--submenu{padding-left:.35rem;padding-right:.35rem}.menu-list--compress-text .menu-list__icon{flex:0 0 auto;width:auto;min-width:1.75rem;display:inline-flex;align-items:center;justify-content:center;padding-top:0}.menu-list__submenu-chevron{flex:0 0 auto;margin-left:auto;padding-left:.35rem;font-size:1rem;line-height:1;color:var(--app-color-text-muted, #6b8299);opacity:.85;display:inline-flex;align-items:center;justify-content:center}.menu-list__submenu-chevron i{font-size:.68rem;line-height:1}.menu-list__icon{flex:0 0 auto;width:1.25rem;height:1.25rem;min-height:1.25rem;display:inline-flex;align-items:center;justify-content:center;text-align:center;color:color-mix(in srgb,var(--app-color-primary, #2b7fd9) 78%,var(--app-color-text-muted, #6b8299));line-height:1;transition:color .18s ease,opacity .18s ease}.menu-list__icon i{display:flex;align-items:center;justify-content:center;width:100%;height:100%;line-height:1;font-size:.95rem;margin-block:auto;flex-shrink:0}.menu-list__option--disabled .menu-list__icon{opacity:.55}.menu-list__icon--spin i{animation:menu-list-spin .8s linear infinite}.menu-list__text{display:flex;flex-direction:column;gap:.1rem;min-width:0;flex:1}.menu-list__label{font-size:.875rem;font-weight:400;line-height:1.25rem;display:inline-flex;align-items:center;min-height:1.25rem;box-sizing:border-box;padding-top:.5rem!important}.menu-list--nested .menu-list__label{font-weight:400;padding-top:.5rem!important}.menu-list--nested .menu-list__icon{transform:translateY(.125rem)}.menu-list__description{font-size:.75rem;color:var(--app-color-text-muted, #6b8299);line-height:1.3}.menu-list:not(.menu-list--compress-text){animation:app-sidebar-nav-reveal-in .45s cubic-bezier(.16,1,.32,1) both}@media(prefers-reduced-motion:reduce){.menu-list:not(.menu-list--compress-text){animation:none}}:host-context(.app-drawer__body) .menu-list__label{padding-top:.5rem!important}:host-context(.app-drawer__body) .menu-list__icon{transform:translateY(.1875rem)}@media(max-width:767.98px){.menu-list.menu-list--nested .menu-list__label{padding-top:.4rem!important}.menu-list.menu-list--nested .menu-list__icon{transform:translateY(.1875rem)}}.menu-submenu__panel{box-sizing:border-box;min-width:0;padding:0;background:transparent;border:none;box-shadow:none;border-radius:10px;overflow:hidden}@keyframes menu-list-spin{to{transform:rotate(360deg)}}:host ::ng-deep .menu-submenu__cdk-panel{background:transparent;box-shadow:none;border-radius:10px}\n"] }]
|
|
10210
|
-
}], propDecorators: { appTheme: [{ type: i0.Input, args: [{ isSignal: true, alias: "appTheme", required: false }] }], items: [{
|
|
10381
|
+
args: [{ selector: 'app-menu-list', changeDetection: ChangeDetectionStrategy.OnPush, imports: [FormsModule, TextFieldComponent, MenuListBodyComponent], template: "<app-menu-list-body\n [items]=\"displayItems\"\n [menuId]=\"menuId\"\n [nested]=\"nested\"\n [dense]=\"dense\"\n [compressText]=\"compressText\"\n [groupCollapsible]=\"groupCollapsible\"\n [groupDefaultExpansion]=\"groupDefaultExpansion\"\n [persistGroupExpansion]=\"persistGroupExpansion\"\n [clickToOpen]=\"clickToOpen\"\n [selectedItemId]=\"selectedItemId\"\n [appTheme]=\"appTheme()\"\n [expandAllGroupsInitially]=\"expandAllGroupsWhenSearching\"\n (itemSelect)=\"itemSelect.emit($event)\"\n (closeRequest)=\"closeRequest.emit()\"\n (submenuBack)=\"submenuBack.emit()\"\n (groupToggled)=\"groupToggled.emit($event)\"\n (selectionScrollHint)=\"selectionScrollHint.emit()\"\n>\n @if (showSearchField) {\n <div class=\"menu-list__search\" role=\"search\">\n <app-text-field\n class=\"menu-list__search-field\"\n [id]=\"menuId + '-search'\"\n [name]=\"menuId + '-menu-search'\"\n size=\"sm\"\n [ngModel]=\"searchQuery\"\n (ngModelChange)=\"onSearchQueryInput($event)\"\n [placeholder]=\"searchPlaceholder\"\n [label]=\"''\"\n [showPrefixIcon]=\"true\"\n prefixIcon=\"fa-solid fa-magnifying-glass\"\n [clearable]=\"true\"\n [autocomplete]=\"false\"\n />\n </div>\n }\n @if (showSearchNoResults) {\n <p class=\"menu-list__search-empty\">Nenhum item encontrado</p>\n }\n</app-menu-list-body>\n", styles: ["@charset \"UTF-8\";@keyframes app-sidebar-nav-reveal-in{0%{opacity:0;transform:translate3d(-.45rem,0,0)}to{opacity:1;transform:translateZ(0)}}:host{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;min-width:0;box-sizing:border-box;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.menu-list{background:var(--app-color-surface, #ffffff);border:1px solid var(--app-color-border-subtle, rgba(26, 47, 69, .12));border-radius:10px;box-shadow:0 10px 28px -14px #0f172a29;max-height:min(70vh,22rem);overflow-x:hidden;overflow-y:auto;display:flex;flex-direction:column;flex:1 1 auto;min-height:0;min-width:0;overflow:hidden;gap:.35rem;padding:.45rem 0;outline:none;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.menu-list--dense{padding:.2rem 0;gap:0}.menu-list--dense .menu-list__items{gap:0}.menu-list--dense.menu-list--compress-text .menu-list__items{gap:.25rem}.menu-list__toolbar{flex:0 0 auto;min-width:0}.menu-list__viewport{flex:1 1 auto;min-height:0;min-width:0;overflow-x:hidden;overflow-y:auto;-webkit-overflow-scrolling:touch;outline:none;scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--app-color-text-primary, #1a2f45) 34%,transparent) transparent}.menu-list__viewport::-webkit-scrollbar{width:4px;height:4px}.menu-list__viewport::-webkit-scrollbar-track{background:transparent}.menu-list__viewport::-webkit-scrollbar-thumb{border-radius:999px;background:color-mix(in srgb,var(--app-color-text-primary, #1a2f45) 40%,transparent)}.menu-list__viewport::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--app-color-text-primary, #1a2f45) 55%,transparent)}.menu-list__items{display:flex;flex-direction:column;gap:.12rem;min-width:0}.menu-list__search{margin:0 .35rem .12rem;min-width:0;user-select:text;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text}.menu-list__search-field{display:block;width:100%}.menu-list__search-empty{margin:-.05rem .75rem 0;padding:0 0 .15rem;font-size:.75rem;line-height:1.35;font-weight:400;color:var(--app-color-text-muted, #6b8299);opacity:.88}.menu-list__group-row{display:block;width:100%}.menu-list__group-row--pinned .menu-list__group-label{color:var(--app-color-nav-group-heading, #9ca3af)}.menu-list__submenu-wrap{position:relative;display:block}.menu-list__option{display:flex;align-items:center;box-sizing:border-box;gap:.6875rem;margin:0 .25rem;padding:.5625rem .65rem;border-radius:8px;cursor:pointer;color:var(--app-color-text-primary, #1a2f45);background:transparent;border:1px solid transparent;text-align:left;font:inherit;line-height:1.25;transition:background-color .18s ease,color .18s ease,box-shadow .18s ease,border-color .18s ease}.menu-list__option:focus-visible{outline:2px solid var(--app-color-focus-ring-strong, rgba(43, 127, 217, .45));outline-offset:1px}.menu-list__option:hover:not(.menu-list__option--disabled):not(.menu-list__option--loading){background:#0f172a0b}.menu-list__option.menu-list__option--active:not(.menu-list__option--disabled):not(.menu-list__option--loading){background:#0f172a0e;border-color:transparent}.menu-list__option.menu-list__option--active:not(.menu-list__option--disabled):not(.menu-list__option--loading):not(.menu-list__option--selected){box-shadow:none}.menu-list__option.menu-list__option--disabled{cursor:not-allowed;color:var(--app-color-text-muted, #6b8299);background:transparent;opacity:.72}.menu-list__option.menu-list__option--loading{cursor:wait;opacity:.92;pointer-events:none}.menu-list__option.menu-list__option--danger:not(.menu-list__option--disabled):not(.menu-list__option--loading){color:var(--app-color-error, #b91c1c)}.menu-list__option.menu-list__option--danger:not(.menu-list__option--disabled):not(.menu-list__option--loading):hover,.menu-list__option.menu-list__option--danger:not(.menu-list__option--disabled):not(.menu-list__option--loading).menu-list__option--active{background:var(--app-color-error-bg-subtle, rgba(185, 28, 28, .12));border-color:transparent;box-shadow:inset 2px 0 0 0 var(--app-color-error-border, #dc2626)}.menu-list__option--submenu{padding-right:.35rem}.menu-list__option--selected:not(.menu-list__option--disabled){background:color-mix(in srgb,var(--app-color-primary) 10%,transparent);border-radius:8px;border-color:transparent;box-shadow:inset 2px 0 0 0 var(--app-color-primary, #2b7fd9)}.menu-list__option--selected:not(.menu-list__option--disabled) .menu-list__label{color:color-mix(in srgb,var(--app-color-primary, #2b7fd9) 88%,var(--app-color-nav-option-label, #374151));font-weight:500}.menu-list__option--selected:not(.menu-list__option--disabled) .menu-list__icon{color:var(--app-color-primary, #2b7fd9)}.menu-list__option:not(.menu-list__option--danger):not(.menu-list__option--disabled):not(.menu-list__option--selected) .menu-list__label{color:var(--app-color-nav-option-label, #374151)}.menu-list--compress-text .menu-list__label,.menu-list--compress-text .menu-list__description{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.menu-list--compress-text .menu-list__text,.menu-list--compress-text .menu-list__submenu-chevron{display:none}.menu-list--compress-text .menu-list__submenu-wrap{width:100%}.menu-list--compress-text .menu-list__option{justify-content:center;align-items:center;text-align:center;width:calc(100% - .5rem);max-width:100%;box-sizing:border-box;margin-left:.25rem;margin-right:.25rem;padding:.5rem .35rem}.menu-list--compress-text .menu-list__option--submenu{padding-left:.35rem;padding-right:.35rem}.menu-list--compress-text .menu-list__icon{flex:0 0 auto;width:auto;min-width:1.75rem;display:inline-flex;align-items:center;justify-content:center;padding-top:0}.menu-list__submenu-chevron{flex:0 0 auto;margin-left:auto;padding-left:.35rem;font-size:1rem;line-height:1;color:var(--app-color-text-muted, #6b8299);opacity:.85;display:inline-flex;align-items:center;justify-content:center}.menu-list__submenu-chevron i{font-size:.68rem;line-height:1}.menu-list__icon{flex:0 0 auto;width:1.25rem;height:1.25rem;min-height:1.25rem;display:inline-flex;align-items:center;justify-content:center;text-align:center;color:color-mix(in srgb,var(--app-color-primary, #2b7fd9) 78%,var(--app-color-text-muted, #6b8299));line-height:1;transition:color .18s ease,opacity .18s ease}.menu-list__icon i{display:flex;align-items:center;justify-content:center;width:100%;height:100%;line-height:1;font-size:.95rem;margin-block:auto;flex-shrink:0}.menu-list__option--disabled .menu-list__icon{opacity:.55}.menu-list__icon--spin i{animation:menu-list-spin .8s linear infinite}.menu-list__text{display:flex;flex-direction:column;gap:.1rem;min-width:0;flex:1}.menu-list__label{font-size:.875rem;font-weight:400;line-height:1.25rem;display:inline-flex;align-items:center;min-height:1.25rem;box-sizing:border-box;padding-top:.5rem!important}.menu-list--nested .menu-list__label{font-weight:400;padding-top:.5rem!important}.menu-list--nested .menu-list__icon{transform:translateY(.125rem)}.menu-list__description{font-size:.75rem;color:var(--app-color-text-muted, #6b8299);line-height:1.3}.menu-list:not(.menu-list--compress-text){animation:app-sidebar-nav-reveal-in .45s cubic-bezier(.16,1,.32,1) both}@media(prefers-reduced-motion:reduce){.menu-list:not(.menu-list--compress-text){animation:none}}:host-context(.app-drawer__body) .menu-list__label{padding-top:.5rem!important}:host-context(.app-drawer__body) .menu-list__icon{transform:translateY(.1875rem)}@media(max-width:767.98px){.menu-list.menu-list--nested .menu-list__label{padding-top:.4rem!important}.menu-list.menu-list--nested .menu-list__icon{transform:translateY(.1875rem)}}.menu-submenu__panel{box-sizing:border-box;min-width:0;padding:0;background:transparent;border:none;box-shadow:none;border-radius:10px;overflow:hidden}@keyframes menu-list-spin{to{transform:rotate(360deg)}}:host ::ng-deep .menu-submenu__cdk-panel{background:transparent;box-shadow:none;border-radius:10px}\n"] }]
|
|
10382
|
+
}], ctorParameters: () => [], propDecorators: { appTheme: [{ type: i0.Input, args: [{ isSignal: true, alias: "appTheme", required: false }] }], items: [{
|
|
10211
10383
|
type: Input,
|
|
10212
10384
|
args: [{ required: true }]
|
|
10213
10385
|
}], menuId: [{
|
|
@@ -10244,7 +10416,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
10244
10416
|
type: Output
|
|
10245
10417
|
}], submenuBack: [{
|
|
10246
10418
|
type: Output
|
|
10247
|
-
}], groupToggled: [{ type: i0.Output, args: ["groupToggled"] }], body: [{
|
|
10419
|
+
}], groupToggled: [{ type: i0.Output, args: ["groupToggled"] }], selectionScrollHint: [{ type: i0.Output, args: ["selectionScrollHint"] }], body: [{
|
|
10248
10420
|
type: ViewChild,
|
|
10249
10421
|
args: [MenuListBodyComponent]
|
|
10250
10422
|
}] } });
|
|
@@ -10327,7 +10499,7 @@ class ContextMenuComponent {
|
|
|
10327
10499
|
this.disposeOverlay();
|
|
10328
10500
|
}
|
|
10329
10501
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ContextMenuComponent, deps: [{ token: i1$1.Overlay }, { token: i0.ViewContainerRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
10330
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: ContextMenuComponent, isStandalone: true, selector: "app-context-menu", inputs: { appTheme: { classPropertyName: "appTheme", publicName: "appTheme", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: false, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, menuId: { classPropertyName: "menuId", publicName: "menuId", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { itemSelect: "itemSelect" }, viewQueries: [{ propertyName: "menuTpl", first: true, predicate: ["menuTpl"], descendants: true, static: true }, { propertyName: "menuList", first: true, predicate: MenuListComponent, descendants: true }], ngImport: i0, template: "<span class=\"context-menu__host\" (contextmenu)=\"onContextMenu($event)\">\r\n <ng-content />\r\n</span>\r\n\r\n<ng-template #menuTpl>\r\n <div class=\"context-menu__surface\" [ngClass]=\"panelThemeNgClass()\" (click)=\"$event.stopPropagation()\">\r\n <app-menu-list\r\n [appTheme]=\"effectiveThemeId()\"\r\n [items]=\"items\"\r\n [menuId]=\"resolvedMenuId\"\r\n [clickToOpen]=\"false\"\r\n (itemSelect)=\"onItemSelect($event)\"\r\n (closeRequest)=\"onCloseRequest()\"\r\n />\r\n </div>\r\n</ng-template>\r\n", styles: [":host{display:contents}.context-menu__host{display:contents}.context-menu__surface{box-sizing:border-box;min-width:12.5rem;max-width:min(100vw - 1rem,22rem)}\n"], dependencies: [{ kind: "component", type: MenuListComponent, selector: "app-menu-list", inputs: ["appTheme", "items", "menuId", "dense", "nested", "selectedItemId", "compressText", "clickToOpen", "groupCollapsible", "groupDefaultExpansion", "persistGroupExpansion", "searchable", "searchPlaceholder"], outputs: ["itemSelect", "closeRequest", "submenuBack", "groupToggled"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
10502
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: ContextMenuComponent, isStandalone: true, selector: "app-context-menu", inputs: { appTheme: { classPropertyName: "appTheme", publicName: "appTheme", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: false, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, menuId: { classPropertyName: "menuId", publicName: "menuId", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { itemSelect: "itemSelect" }, viewQueries: [{ propertyName: "menuTpl", first: true, predicate: ["menuTpl"], descendants: true, static: true }, { propertyName: "menuList", first: true, predicate: MenuListComponent, descendants: true }], ngImport: i0, template: "<span class=\"context-menu__host\" (contextmenu)=\"onContextMenu($event)\">\r\n <ng-content />\r\n</span>\r\n\r\n<ng-template #menuTpl>\r\n <div class=\"context-menu__surface\" [ngClass]=\"panelThemeNgClass()\" (click)=\"$event.stopPropagation()\">\r\n <app-menu-list\r\n [appTheme]=\"effectiveThemeId()\"\r\n [items]=\"items\"\r\n [menuId]=\"resolvedMenuId\"\r\n [clickToOpen]=\"false\"\r\n (itemSelect)=\"onItemSelect($event)\"\r\n (closeRequest)=\"onCloseRequest()\"\r\n />\r\n </div>\r\n</ng-template>\r\n", styles: [":host{display:contents}.context-menu__host{display:contents}.context-menu__surface{box-sizing:border-box;min-width:12.5rem;max-width:min(100vw - 1rem,22rem)}\n"], dependencies: [{ kind: "component", type: MenuListComponent, selector: "app-menu-list", inputs: ["appTheme", "items", "menuId", "dense", "nested", "selectedItemId", "compressText", "clickToOpen", "groupCollapsible", "groupDefaultExpansion", "persistGroupExpansion", "searchable", "searchPlaceholder"], outputs: ["itemSelect", "closeRequest", "submenuBack", "groupToggled", "selectionScrollHint"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
10331
10503
|
}
|
|
10332
10504
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ContextMenuComponent, decorators: [{
|
|
10333
10505
|
type: Component,
|
|
@@ -11196,6 +11368,7 @@ class AppSidebarComponent {
|
|
|
11196
11368
|
this.cdr = inject(ChangeDetectorRef);
|
|
11197
11369
|
this.destroyRef = inject(DestroyRef);
|
|
11198
11370
|
this.hostEl = inject((ElementRef));
|
|
11371
|
+
this.injector = inject(Injector);
|
|
11199
11372
|
this.renderer = inject(Renderer2);
|
|
11200
11373
|
/** Igual a `[appTheme]` / {@link ThemeDirective}: paleta explícita no host; omitir = herdar / serviço. */
|
|
11201
11374
|
this.appTheme = input(...(ngDevMode ? [undefined, { debugName: "appTheme" }] : /* istanbul ignore next */ []));
|
|
@@ -11204,6 +11377,12 @@ class AppSidebarComponent {
|
|
|
11204
11377
|
this.selectedItemId = null;
|
|
11205
11378
|
/** Modo estreito: só ícones + `compressText` na lista (rótulos via `title` / `aria-label`). */
|
|
11206
11379
|
this.collapsed = false;
|
|
11380
|
+
/**
|
|
11381
|
+
* Ligado ao estado do drawer no telemóvel (ex.: `mobileNavOpen` do `app-shell`).
|
|
11382
|
+
* Em cada transição para `true`, volta a agendar o scroll até ao item activo — útil porque `selectedItemId`
|
|
11383
|
+
* pode não mudar entre aberturas e o menu pode ser recriado dentro do `@if (open)` do drawer.
|
|
11384
|
+
*/
|
|
11385
|
+
this.mobileNavOpenPulse = false;
|
|
11207
11386
|
/** Repassado a {@link MenuListComponent.searchable}: campo de pesquisa na lista da lateral. */
|
|
11208
11387
|
this.searchable = false;
|
|
11209
11388
|
/**
|
|
@@ -11230,7 +11409,15 @@ class AppSidebarComponent {
|
|
|
11230
11409
|
this.listCompressText = signal(false, ...(ngDevMode ? [{ debugName: "listCompressText" }] : /* istanbul ignore next */ []));
|
|
11231
11410
|
this.listRevealTimeoutId = null;
|
|
11232
11411
|
this.scrollRestoreTimeoutId = null;
|
|
11233
|
-
|
|
11412
|
+
/** Invalida tentativas de scroll pendentes (ex.: novo agendamento ou destroy). */
|
|
11413
|
+
this.scrollToSelectedGeneration = 0;
|
|
11414
|
+
/** `setTimeout` extra ao abrir o drawer — animação (~240ms) e flex podem atrasar métricas do scroll. */
|
|
11415
|
+
this.drawerScrollAssistTimeouts = [];
|
|
11416
|
+
this.destroyRef.onDestroy(() => {
|
|
11417
|
+
this.clearListRevealTimeout();
|
|
11418
|
+
this.clearDrawerScrollAssistTimeouts();
|
|
11419
|
+
this.scrollToSelectedGeneration++;
|
|
11420
|
+
});
|
|
11234
11421
|
effect(() => {
|
|
11235
11422
|
applyOptionalThemeHostClasses(this.renderer, this.hostEl.nativeElement, this.appTheme());
|
|
11236
11423
|
});
|
|
@@ -11242,6 +11429,8 @@ class AppSidebarComponent {
|
|
|
11242
11429
|
}
|
|
11243
11430
|
ngAfterViewInit() {
|
|
11244
11431
|
this.scheduleSidebarHeadLayoutGuards();
|
|
11432
|
+
/** Drawer mobile `@if (open)` remonta a sidebar — após a vista, alinhar scroll como no desktop. */
|
|
11433
|
+
this.scheduleScrollToSelected();
|
|
11245
11434
|
}
|
|
11246
11435
|
ngOnChanges(changes) {
|
|
11247
11436
|
if (changes['selectedItemId'] || changes['items']) {
|
|
@@ -11250,15 +11439,30 @@ class AppSidebarComponent {
|
|
|
11250
11439
|
if (changes['collapsed']) {
|
|
11251
11440
|
this.scheduleSidebarHeadLayoutGuards();
|
|
11252
11441
|
}
|
|
11253
|
-
/**
|
|
11254
|
-
|
|
11255
|
-
|
|
11256
|
-
|
|
11257
|
-
|
|
11258
|
-
|
|
11259
|
-
|
|
11260
|
-
|
|
11261
|
-
}
|
|
11442
|
+
/**
|
|
11443
|
+
* Lista expandida: evita scroll durante `listCompressText` transitório (animação de largura).
|
|
11444
|
+
* Modo rail (`collapsed`): ícones continuam em `.menu-list__viewport` — faz scroll para o `--selected`
|
|
11445
|
+
* ficar inteiro (ícone «cortado» ao clicar ou ao mudar a rota).
|
|
11446
|
+
*/
|
|
11447
|
+
if (changes['selectedItemId'] || changes['items']) {
|
|
11448
|
+
if (this.collapsed || !this.listCompressText()) {
|
|
11449
|
+
this.scheduleScrollToSelected();
|
|
11450
|
+
}
|
|
11451
|
+
}
|
|
11452
|
+
const pulseCh = changes['mobileNavOpenPulse'];
|
|
11453
|
+
if (pulseCh &&
|
|
11454
|
+
this.mobileNavOpenPulse &&
|
|
11455
|
+
pulseCh.previousValue !== true) {
|
|
11456
|
+
/**
|
|
11457
|
+
* Primeiro expandir grupos no caminho da selecção (persistidos fechados); `syncRouteSelectionExpansion`
|
|
11458
|
+
* emite `selectionScrollHint` e só então o scroll encontra `.menu-list__option--selected`.
|
|
11459
|
+
*/
|
|
11460
|
+
afterNextRender(() => {
|
|
11461
|
+
this.menuList?.syncSelectionForMobileDrawerOpen();
|
|
11462
|
+
if (!this.menuList) {
|
|
11463
|
+
this.scheduleScrollToSelected();
|
|
11464
|
+
}
|
|
11465
|
+
}, { injector: this.injector });
|
|
11262
11466
|
}
|
|
11263
11467
|
const collapsedCh = changes['collapsed'];
|
|
11264
11468
|
if (!collapsedCh) {
|
|
@@ -11284,27 +11488,110 @@ class AppSidebarComponent {
|
|
|
11284
11488
|
/** Depois da animação de largura (~120ms) + reflow dos rótulos — mesma ordem que `_sidebar-reveal.scss`. */
|
|
11285
11489
|
this.scrollRestoreTimeoutId = setTimeout(() => {
|
|
11286
11490
|
this.scrollRestoreTimeoutId = null;
|
|
11287
|
-
|
|
11288
|
-
requestAnimationFrame(() => this.scrollSidebarToSelectedItem());
|
|
11289
|
-
});
|
|
11491
|
+
this.scheduleScrollToSelected();
|
|
11290
11492
|
}, APP_SIDEBAR_LAYOUT_TRANSITION_MS);
|
|
11291
11493
|
}, APP_SIDEBAR_NAV_REVEAL_TOTAL_MS);
|
|
11292
11494
|
}
|
|
11293
11495
|
/**
|
|
11294
|
-
*
|
|
11295
|
-
*
|
|
11496
|
+
* Agenda scroll até ao `--selected` depois do próximo render (filhos OnPush) e reintenta em `rAF`
|
|
11497
|
+
* até o elemento existir — necessário no drawer mobile, onde o menu acaba de montar.
|
|
11296
11498
|
*/
|
|
11297
|
-
|
|
11499
|
+
/**
|
|
11500
|
+
* Repete o scroll quando o utilizador clica num item já activo mas «cortado» (`selectedItemId` não muda).
|
|
11501
|
+
*/
|
|
11502
|
+
onSidebarItemSelect(id) {
|
|
11503
|
+
this.itemSelect.emit(id);
|
|
11504
|
+
this.scheduleScrollToSelected();
|
|
11505
|
+
}
|
|
11506
|
+
/** Também ligado a `(selectionScrollHint)` em `app-menu-list` para o drawer mobile. */
|
|
11507
|
+
scheduleScrollToSelected() {
|
|
11508
|
+
this.clearDrawerScrollAssistTimeouts();
|
|
11509
|
+
const gen = ++this.scrollToSelectedGeneration;
|
|
11510
|
+
afterNextRender(() => {
|
|
11511
|
+
if (gen !== this.scrollToSelectedGeneration) {
|
|
11512
|
+
return;
|
|
11513
|
+
}
|
|
11514
|
+
/**
|
|
11515
|
+
* Os timeouts do drawer **têm** de ser registados aqui — não no instante inicial da chamada:
|
|
11516
|
+
* antes do próximo render o host pode ainda não estar sob `.app-drawer__body`, e na 2.ª abertura
|
|
11517
|
+
* do menu o `closest` falhava no schedule e os pulsos deixavam de existir.
|
|
11518
|
+
*/
|
|
11519
|
+
if (this.isInsideMobileDrawer()) {
|
|
11520
|
+
const delaysMs = [90, 260, 420, 600];
|
|
11521
|
+
for (const ms of delaysMs) {
|
|
11522
|
+
const tid = window.setTimeout(() => {
|
|
11523
|
+
if (gen !== this.scrollToSelectedGeneration) {
|
|
11524
|
+
return;
|
|
11525
|
+
}
|
|
11526
|
+
queueMicrotask(() => {
|
|
11527
|
+
requestAnimationFrame(() => {
|
|
11528
|
+
this.runScrollToSelectedRetry(gen, 0);
|
|
11529
|
+
});
|
|
11530
|
+
});
|
|
11531
|
+
}, ms);
|
|
11532
|
+
this.drawerScrollAssistTimeouts.push(tid);
|
|
11533
|
+
}
|
|
11534
|
+
}
|
|
11535
|
+
queueMicrotask(() => {
|
|
11536
|
+
requestAnimationFrame(() => {
|
|
11537
|
+
requestAnimationFrame(() => {
|
|
11538
|
+
this.runScrollToSelectedRetry(gen, 0);
|
|
11539
|
+
});
|
|
11540
|
+
});
|
|
11541
|
+
});
|
|
11542
|
+
}, { injector: this.injector });
|
|
11543
|
+
}
|
|
11544
|
+
static { this.SCROLL_TO_SELECTED_MAX_ATTEMPTS = 48; }
|
|
11545
|
+
static { this.SCROLL_TO_SELECTED_MAX_ATTEMPTS_DRAWER = 96; }
|
|
11546
|
+
/** Sidebar projectada em `.app-drawer__body` — animação do painel e `overflow` do shell afectam o layout. */
|
|
11547
|
+
isInsideMobileDrawer() {
|
|
11548
|
+
return !!this.hostEl.nativeElement.closest('.app-drawer__body');
|
|
11549
|
+
}
|
|
11550
|
+
clearDrawerScrollAssistTimeouts() {
|
|
11551
|
+
for (const tid of this.drawerScrollAssistTimeouts) {
|
|
11552
|
+
clearTimeout(tid);
|
|
11553
|
+
}
|
|
11554
|
+
this.drawerScrollAssistTimeouts = [];
|
|
11555
|
+
}
|
|
11556
|
+
runScrollToSelectedRetry(gen, attempt) {
|
|
11557
|
+
if (gen !== this.scrollToSelectedGeneration) {
|
|
11558
|
+
return;
|
|
11559
|
+
}
|
|
11560
|
+
if (this.selectedItemId == null) {
|
|
11561
|
+
return;
|
|
11562
|
+
}
|
|
11563
|
+
/** Rail: `compressText` fica activo com `collapsed`; ainda assim queremos scroll até ao ícone. */
|
|
11564
|
+
if (!this.collapsed && this.listCompressText()) {
|
|
11565
|
+
return;
|
|
11566
|
+
}
|
|
11567
|
+
const maxAttempts = this.isInsideMobileDrawer()
|
|
11568
|
+
? AppSidebarComponent.SCROLL_TO_SELECTED_MAX_ATTEMPTS_DRAWER
|
|
11569
|
+
: AppSidebarComponent.SCROLL_TO_SELECTED_MAX_ATTEMPTS;
|
|
11298
11570
|
const scroll = this.getSidebarMenuListViewport();
|
|
11299
|
-
if (!scroll
|
|
11571
|
+
if (!scroll) {
|
|
11572
|
+
if (attempt < maxAttempts) {
|
|
11573
|
+
requestAnimationFrame(() => this.runScrollToSelectedRetry(gen, attempt + 1));
|
|
11574
|
+
}
|
|
11575
|
+
return;
|
|
11576
|
+
}
|
|
11577
|
+
/** Flex / animação do drawer: viewport pode ainda ter altura 0 no primeiro frame. */
|
|
11578
|
+
if (scroll.clientHeight < 4 && attempt < maxAttempts) {
|
|
11579
|
+
requestAnimationFrame(() => this.runScrollToSelectedRetry(gen, attempt + 1));
|
|
11300
11580
|
return;
|
|
11301
11581
|
}
|
|
11302
11582
|
const matches = scroll.querySelectorAll('.menu-list__option--selected');
|
|
11303
11583
|
if (matches.length === 0) {
|
|
11584
|
+
if (attempt < maxAttempts) {
|
|
11585
|
+
requestAnimationFrame(() => this.runScrollToSelectedRetry(gen, attempt + 1));
|
|
11586
|
+
}
|
|
11304
11587
|
return;
|
|
11305
11588
|
}
|
|
11306
11589
|
const selected = matches[matches.length - 1];
|
|
11307
11590
|
this.scrollSidebarScrollAreaToElement(scroll, selected);
|
|
11591
|
+
if (this.isInsideMobileDrawer()) {
|
|
11592
|
+
/** Reforço nativo após cálculo manual — durante `transform` do painel o layout pode mentir um frame. */
|
|
11593
|
+
selected.scrollIntoView({ block: 'nearest', behavior: 'auto' });
|
|
11594
|
+
}
|
|
11308
11595
|
}
|
|
11309
11596
|
/** Após clicar num grupo colapsável: leva o cabeçalho do grupo para a zona visível (como o item seleccionado). */
|
|
11310
11597
|
onMenuGroupToggled(groupId) {
|
|
@@ -11332,17 +11619,18 @@ class AppSidebarComponent {
|
|
|
11332
11619
|
return this.hostEl.nativeElement.querySelector('.menu-list__viewport');
|
|
11333
11620
|
}
|
|
11334
11621
|
scrollSidebarScrollAreaToElement(scroll, target) {
|
|
11335
|
-
if (this.collapsed) {
|
|
11336
|
-
return;
|
|
11337
|
-
}
|
|
11338
11622
|
const marginCss = 10;
|
|
11623
|
+
/** No rail os ícones são densos — um pouco mais de folga no topo evita meio-ícone «cortado». */
|
|
11624
|
+
const topPadExtra = this.collapsed ? 8 : 0;
|
|
11625
|
+
/** Folga inferior — no drawer em lista completa puxamos mais para o item não ficar no limite. */
|
|
11626
|
+
const bottomComfortPx = Math.max(marginCss, this.collapsed ? marginCss : this.isInsideMobileDrawer() ? 52 : 44);
|
|
11339
11627
|
const basePeek = this.getMenuNeighborPeekHalfHeights(target);
|
|
11340
11628
|
/** Cabeçalhos de grupo: mais folga vertical (~vizinho + boost) para não ficarem «apertados». */
|
|
11341
11629
|
const groupPeekBoost = target.classList.contains('menu-list__group-row') ? 22 : 0;
|
|
11342
11630
|
const peekAbove = basePeek.peekAbove + groupPeekBoost;
|
|
11343
11631
|
const peekBelow = basePeek.peekBelow + groupPeekBoost;
|
|
11344
11632
|
/** Cabeçalho está fora do scroll — só margem no topo da viewport de scroll. */
|
|
11345
|
-
const topPad = marginCss;
|
|
11633
|
+
const topPad = marginCss + topPadExtra;
|
|
11346
11634
|
const scrRect = scroll.getBoundingClientRect();
|
|
11347
11635
|
const elRect = target.getBoundingClientRect();
|
|
11348
11636
|
const elTop = scroll.scrollTop + (elRect.top - scrRect.top);
|
|
@@ -11354,8 +11642,8 @@ class AppSidebarComponent {
|
|
|
11354
11642
|
if (elTop < viewTop + topPad) {
|
|
11355
11643
|
nextTop = elTop - topPad - peekAbove;
|
|
11356
11644
|
}
|
|
11357
|
-
else if (elBottom > viewBottom -
|
|
11358
|
-
nextTop = elBottom - scroll.clientHeight +
|
|
11645
|
+
else if (elBottom > viewBottom - bottomComfortPx) {
|
|
11646
|
+
nextTop = elBottom - scroll.clientHeight + bottomComfortPx + peekBelow;
|
|
11359
11647
|
}
|
|
11360
11648
|
else {
|
|
11361
11649
|
return;
|
|
@@ -11365,7 +11653,8 @@ class AppSidebarComponent {
|
|
|
11365
11653
|
if (Math.abs(nextTop - scroll.scrollTop) < 1) {
|
|
11366
11654
|
return;
|
|
11367
11655
|
}
|
|
11368
|
-
|
|
11656
|
+
const behavior = this.isInsideMobileDrawer() ? 'auto' : 'smooth';
|
|
11657
|
+
scroll.scrollTo({ top: nextTop, behavior });
|
|
11369
11658
|
}
|
|
11370
11659
|
/**
|
|
11371
11660
|
* Metade da altura da linha vizinha (opção ou cabeçalho de grupo) na mesma lista (fallback em px).
|
|
@@ -11496,11 +11785,11 @@ class AppSidebarComponent {
|
|
|
11496
11785
|
}
|
|
11497
11786
|
}
|
|
11498
11787
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AppSidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
11499
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: AppSidebarComponent, isStandalone: true, selector: "app-sidebar", inputs: { appTheme: { classPropertyName: "appTheme", publicName: "appTheme", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: false, isRequired: true, transformFunction: null }, menuId: { classPropertyName: "menuId", publicName: "menuId", isSignal: false, isRequired: false, transformFunction: null }, selectedItemId: { classPropertyName: "selectedItemId", publicName: "selectedItemId", isSignal: false, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, clickToOpen: { classPropertyName: "clickToOpen", publicName: "clickToOpen", isSignal: false, isRequired: false, transformFunction: null }, groupCollapsible: { classPropertyName: "groupCollapsible", publicName: "groupCollapsible", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, groupDefaultExpansion: { classPropertyName: "groupDefaultExpansion", publicName: "groupDefaultExpansion", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { itemSelect: "itemSelect" }, usesOnChanges: true, ngImport: i0, template: "<nav class=\"app-sidebar app-nav-surface\" [class.app-sidebar--collapsed]=\"collapsed\"\r\n [attr.aria-label]=\"'Navega\u00E7\u00E3o principal'\">\r\n <!-- Cabe\u00E7alho fixo; pesquisa fixa em `.menu-list__toolbar`; barra s\u00F3 em `.menu-list__viewport`. -->\r\n <div class=\"app-sidebar__head\" data-app-sidebar-head=\"\" translate=\"no\">\r\n <div class=\"app-sidebar__brand\"><ng-content select=\"[appSidebarBrand]\" /></div>\r\n <div class=\"app-sidebar__toolbar\"><ng-content select=\"[appSidebarToolbar]\" /></div>\r\n </div>\r\n <div class=\"app-sidebar__scroll\">\r\n <app-menu-list\r\n class=\"app-sidebar__list\"\r\n [appTheme]=\"appTheme()\"\r\n [items]=\"items\"\r\n [menuId]=\"menuId\"\r\n [dense]=\"collapsed\"\r\n [compressText]=\"listCompressText()\"\r\n [searchable]=\"searchable\"\r\n [clickToOpen]=\"clickToOpen\"\r\n [groupCollapsible]=\"groupCollapsible\"\r\n [groupDefaultExpansion]=\"groupDefaultExpansion\"\r\n [selectedItemId]=\"selectedItemId\"\r\n (itemSelect)=\"
|
|
11788
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: AppSidebarComponent, isStandalone: true, selector: "app-sidebar", inputs: { appTheme: { classPropertyName: "appTheme", publicName: "appTheme", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: false, isRequired: true, transformFunction: null }, menuId: { classPropertyName: "menuId", publicName: "menuId", isSignal: false, isRequired: false, transformFunction: null }, selectedItemId: { classPropertyName: "selectedItemId", publicName: "selectedItemId", isSignal: false, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, mobileNavOpenPulse: { classPropertyName: "mobileNavOpenPulse", publicName: "mobileNavOpenPulse", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, clickToOpen: { classPropertyName: "clickToOpen", publicName: "clickToOpen", isSignal: false, isRequired: false, transformFunction: null }, groupCollapsible: { classPropertyName: "groupCollapsible", publicName: "groupCollapsible", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, groupDefaultExpansion: { classPropertyName: "groupDefaultExpansion", publicName: "groupDefaultExpansion", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { itemSelect: "itemSelect" }, viewQueries: [{ propertyName: "menuList", first: true, predicate: MenuListComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<nav class=\"app-sidebar app-nav-surface\" [class.app-sidebar--collapsed]=\"collapsed\"\r\n [attr.aria-label]=\"'Navega\u00E7\u00E3o principal'\">\r\n <!-- Cabe\u00E7alho fixo; pesquisa fixa em `.menu-list__toolbar`; barra s\u00F3 em `.menu-list__viewport`. -->\r\n <div class=\"app-sidebar__head\" data-app-sidebar-head=\"\" translate=\"no\">\r\n <div class=\"app-sidebar__brand\"><ng-content select=\"[appSidebarBrand]\" /></div>\r\n <div class=\"app-sidebar__toolbar\"><ng-content select=\"[appSidebarToolbar]\" /></div>\r\n </div>\r\n <div class=\"app-sidebar__scroll\">\r\n <app-menu-list\r\n class=\"app-sidebar__list\"\r\n [appTheme]=\"appTheme()\"\r\n [items]=\"items\"\r\n [menuId]=\"menuId\"\r\n [dense]=\"collapsed\"\r\n [compressText]=\"listCompressText()\"\r\n [searchable]=\"searchable\"\r\n [clickToOpen]=\"clickToOpen\"\r\n [groupCollapsible]=\"groupCollapsible\"\r\n [groupDefaultExpansion]=\"groupDefaultExpansion\"\r\n [selectedItemId]=\"selectedItemId\"\r\n (itemSelect)=\"onSidebarItemSelect($event)\"\r\n (groupToggled)=\"onMenuGroupToggled($event)\"\r\n (selectionScrollHint)=\"scheduleScrollToSelected()\"\r\n />\r\n </div>\r\n</nav>\r\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;flex:1 1 auto;align-self:stretch;min-width:0;min-height:0;box-sizing:border-box;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.app-sidebar{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;box-sizing:border-box;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;padding:.65rem .35rem .65rem .5rem;background:var(--app-color-nav-shell-bg);border-right:1px solid var(--app-color-nav-border-subtle)}.app-sidebar--collapsed{padding-inline:.425rem}.app-sidebar__head[data-app-sidebar-head]{flex:0 0 auto;display:flex;flex-direction:row;align-items:center;justify-content:flex-start;gap:.35rem;width:100%;min-height:2.35rem;background:var(--app-color-nav-shell-bg);padding:0 .1rem .45rem;padding-inline-start:.85rem!important;padding-inline-end:calc(.1rem + 4px)!important;box-sizing:border-box;direction:ltr;unicode-bidi:isolate;flex-direction:row!important;justify-content:flex-start!important;direction:ltr!important}.app-sidebar--collapsed .app-sidebar__head[data-app-sidebar-head]{justify-content:center!important;padding-inline-start:0!important;padding-inline-end:4px!important;gap:0}.app-sidebar__brand{order:0;flex:1 1 0%;min-width:0;align-self:center;display:flex;justify-content:flex-start;align-items:center;padding:0;box-sizing:border-box;font-size:.95rem;font-weight:700;line-height:1.25;color:var(--app-color-text-primary, #1a2f45);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start!important}.app-sidebar__brand>*{text-align:inherit!important;margin-inline:0!important;margin-inline-start:0!important;margin-inline-end:0!important;padding-inline-start:0!important;padding-inline-end:0!important;box-sizing:border-box;min-width:0;align-self:center;max-width:100%}.app-sidebar__brand ::ng-deep [appSidebarBrand]{display:inline-flex!important;flex-direction:row!important;justify-content:flex-start!important;align-items:center!important;align-self:center!important;margin-inline-start:0!important;margin-inline-end:auto!important;margin-left:0!important;margin-right:auto!important;text-align:start!important;width:auto!important;max-width:100%!important;min-width:0!important;flex:1 1 0%!important;box-sizing:border-box}.app-sidebar__brand:empty{display:none}.app-sidebar--collapsed .app-sidebar__brand:not(:empty){display:none}.app-sidebar__toolbar{order:1;flex:0 0 auto;flex-shrink:0;display:flex;justify-content:flex-end;align-items:center;align-self:stretch;min-width:0;padding:0;box-sizing:border-box;margin-inline-start:auto!important}.app-sidebar__toolbar:empty{display:none}.app-sidebar--collapsed .app-sidebar__toolbar:not(:empty){flex:1 1 auto!important;width:100%!important;min-width:0!important;margin-inline-start:0!important;justify-content:center!important}.app-sidebar--collapsed .app-sidebar__toolbar ::ng-deep [appSidebarToolbar]:not(app-shell-sidebar-toggle)>:not(app-shell-sidebar-toggle){display:none!important}.app-sidebar__scroll{flex:1 1 auto;min-height:0;overflow:hidden;display:flex;flex-direction:column}.app-sidebar__list{flex:1 1 auto;min-height:0;width:100%;display:flex;flex-direction:column;overflow:hidden;box-sizing:border-box}@media(min-width:52.0625rem){.app-sidebar .app-sidebar__head[data-app-sidebar-head]{padding-top:.2rem}.app-sidebar .app-sidebar__brand ::ng-deep [appSidebarBrand]{min-height:2.35rem!important;height:2.35rem!important;line-height:1!important}}:host-context(.app-drawer__body) .app-sidebar__head[data-app-sidebar-head]{justify-content:flex-start!important;align-items:center!important;padding-top:0!important;padding-bottom:.35rem!important;z-index:1!important}:host-context(.app-drawer__body) .app-sidebar__brand{justify-content:flex-start!important;flex:1 1 0%!important;min-width:0!important;text-align:start!important}:host-context(.app-drawer__body) .app-sidebar__toolbar:not(:empty){margin-inline-start:auto!important;justify-content:flex-end!important;align-self:stretch!important}:host-context(.app-drawer__body) .app-sidebar__brand ::ng-deep [appSidebarBrand]{justify-content:flex-start!important;margin-inline-start:0!important;margin-inline-end:auto!important;min-height:auto!important;height:auto!important;line-height:1.25!important}:host-context(.app-drawer__body) ::ng-deep app-menu-list .menu-list__label{padding-top:.72rem!important}:host-context(.app-drawer__body) ::ng-deep app-menu-list .menu-list__icon{transform:translateY(.1875rem)}:host-context(.app-shell__sidebar) .app-sidebar__brand ::ng-deep [appSidebarBrand]{justify-content:flex-start!important;margin-inline-start:0!important;margin-inline-end:auto!important;text-align:start!important}\n"], dependencies: [{ kind: "component", type: MenuListComponent, selector: "app-menu-list", inputs: ["appTheme", "items", "menuId", "dense", "nested", "selectedItemId", "compressText", "clickToOpen", "groupCollapsible", "groupDefaultExpansion", "persistGroupExpansion", "searchable", "searchPlaceholder"], outputs: ["itemSelect", "closeRequest", "submenuBack", "groupToggled", "selectionScrollHint"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
11500
11789
|
}
|
|
11501
11790
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AppSidebarComponent, decorators: [{
|
|
11502
11791
|
type: Component,
|
|
11503
|
-
args: [{ selector: 'app-sidebar', imports: [MenuListComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav class=\"app-sidebar app-nav-surface\" [class.app-sidebar--collapsed]=\"collapsed\"\r\n [attr.aria-label]=\"'Navega\u00E7\u00E3o principal'\">\r\n <!-- Cabe\u00E7alho fixo; pesquisa fixa em `.menu-list__toolbar`; barra s\u00F3 em `.menu-list__viewport`. -->\r\n <div class=\"app-sidebar__head\" data-app-sidebar-head=\"\" translate=\"no\">\r\n <div class=\"app-sidebar__brand\"><ng-content select=\"[appSidebarBrand]\" /></div>\r\n <div class=\"app-sidebar__toolbar\"><ng-content select=\"[appSidebarToolbar]\" /></div>\r\n </div>\r\n <div class=\"app-sidebar__scroll\">\r\n <app-menu-list\r\n class=\"app-sidebar__list\"\r\n [appTheme]=\"appTheme()\"\r\n [items]=\"items\"\r\n [menuId]=\"menuId\"\r\n [dense]=\"collapsed\"\r\n [compressText]=\"listCompressText()\"\r\n [searchable]=\"searchable\"\r\n [clickToOpen]=\"clickToOpen\"\r\n [groupCollapsible]=\"groupCollapsible\"\r\n [groupDefaultExpansion]=\"groupDefaultExpansion\"\r\n [selectedItemId]=\"selectedItemId\"\r\n (itemSelect)=\"
|
|
11792
|
+
args: [{ selector: 'app-sidebar', imports: [MenuListComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav class=\"app-sidebar app-nav-surface\" [class.app-sidebar--collapsed]=\"collapsed\"\r\n [attr.aria-label]=\"'Navega\u00E7\u00E3o principal'\">\r\n <!-- Cabe\u00E7alho fixo; pesquisa fixa em `.menu-list__toolbar`; barra s\u00F3 em `.menu-list__viewport`. -->\r\n <div class=\"app-sidebar__head\" data-app-sidebar-head=\"\" translate=\"no\">\r\n <div class=\"app-sidebar__brand\"><ng-content select=\"[appSidebarBrand]\" /></div>\r\n <div class=\"app-sidebar__toolbar\"><ng-content select=\"[appSidebarToolbar]\" /></div>\r\n </div>\r\n <div class=\"app-sidebar__scroll\">\r\n <app-menu-list\r\n class=\"app-sidebar__list\"\r\n [appTheme]=\"appTheme()\"\r\n [items]=\"items\"\r\n [menuId]=\"menuId\"\r\n [dense]=\"collapsed\"\r\n [compressText]=\"listCompressText()\"\r\n [searchable]=\"searchable\"\r\n [clickToOpen]=\"clickToOpen\"\r\n [groupCollapsible]=\"groupCollapsible\"\r\n [groupDefaultExpansion]=\"groupDefaultExpansion\"\r\n [selectedItemId]=\"selectedItemId\"\r\n (itemSelect)=\"onSidebarItemSelect($event)\"\r\n (groupToggled)=\"onMenuGroupToggled($event)\"\r\n (selectionScrollHint)=\"scheduleScrollToSelected()\"\r\n />\r\n </div>\r\n</nav>\r\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;flex:1 1 auto;align-self:stretch;min-width:0;min-height:0;box-sizing:border-box;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.app-sidebar{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;box-sizing:border-box;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;padding:.65rem .35rem .65rem .5rem;background:var(--app-color-nav-shell-bg);border-right:1px solid var(--app-color-nav-border-subtle)}.app-sidebar--collapsed{padding-inline:.425rem}.app-sidebar__head[data-app-sidebar-head]{flex:0 0 auto;display:flex;flex-direction:row;align-items:center;justify-content:flex-start;gap:.35rem;width:100%;min-height:2.35rem;background:var(--app-color-nav-shell-bg);padding:0 .1rem .45rem;padding-inline-start:.85rem!important;padding-inline-end:calc(.1rem + 4px)!important;box-sizing:border-box;direction:ltr;unicode-bidi:isolate;flex-direction:row!important;justify-content:flex-start!important;direction:ltr!important}.app-sidebar--collapsed .app-sidebar__head[data-app-sidebar-head]{justify-content:center!important;padding-inline-start:0!important;padding-inline-end:4px!important;gap:0}.app-sidebar__brand{order:0;flex:1 1 0%;min-width:0;align-self:center;display:flex;justify-content:flex-start;align-items:center;padding:0;box-sizing:border-box;font-size:.95rem;font-weight:700;line-height:1.25;color:var(--app-color-text-primary, #1a2f45);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start!important}.app-sidebar__brand>*{text-align:inherit!important;margin-inline:0!important;margin-inline-start:0!important;margin-inline-end:0!important;padding-inline-start:0!important;padding-inline-end:0!important;box-sizing:border-box;min-width:0;align-self:center;max-width:100%}.app-sidebar__brand ::ng-deep [appSidebarBrand]{display:inline-flex!important;flex-direction:row!important;justify-content:flex-start!important;align-items:center!important;align-self:center!important;margin-inline-start:0!important;margin-inline-end:auto!important;margin-left:0!important;margin-right:auto!important;text-align:start!important;width:auto!important;max-width:100%!important;min-width:0!important;flex:1 1 0%!important;box-sizing:border-box}.app-sidebar__brand:empty{display:none}.app-sidebar--collapsed .app-sidebar__brand:not(:empty){display:none}.app-sidebar__toolbar{order:1;flex:0 0 auto;flex-shrink:0;display:flex;justify-content:flex-end;align-items:center;align-self:stretch;min-width:0;padding:0;box-sizing:border-box;margin-inline-start:auto!important}.app-sidebar__toolbar:empty{display:none}.app-sidebar--collapsed .app-sidebar__toolbar:not(:empty){flex:1 1 auto!important;width:100%!important;min-width:0!important;margin-inline-start:0!important;justify-content:center!important}.app-sidebar--collapsed .app-sidebar__toolbar ::ng-deep [appSidebarToolbar]:not(app-shell-sidebar-toggle)>:not(app-shell-sidebar-toggle){display:none!important}.app-sidebar__scroll{flex:1 1 auto;min-height:0;overflow:hidden;display:flex;flex-direction:column}.app-sidebar__list{flex:1 1 auto;min-height:0;width:100%;display:flex;flex-direction:column;overflow:hidden;box-sizing:border-box}@media(min-width:52.0625rem){.app-sidebar .app-sidebar__head[data-app-sidebar-head]{padding-top:.2rem}.app-sidebar .app-sidebar__brand ::ng-deep [appSidebarBrand]{min-height:2.35rem!important;height:2.35rem!important;line-height:1!important}}:host-context(.app-drawer__body) .app-sidebar__head[data-app-sidebar-head]{justify-content:flex-start!important;align-items:center!important;padding-top:0!important;padding-bottom:.35rem!important;z-index:1!important}:host-context(.app-drawer__body) .app-sidebar__brand{justify-content:flex-start!important;flex:1 1 0%!important;min-width:0!important;text-align:start!important}:host-context(.app-drawer__body) .app-sidebar__toolbar:not(:empty){margin-inline-start:auto!important;justify-content:flex-end!important;align-self:stretch!important}:host-context(.app-drawer__body) .app-sidebar__brand ::ng-deep [appSidebarBrand]{justify-content:flex-start!important;margin-inline-start:0!important;margin-inline-end:auto!important;min-height:auto!important;height:auto!important;line-height:1.25!important}:host-context(.app-drawer__body) ::ng-deep app-menu-list .menu-list__label{padding-top:.72rem!important}:host-context(.app-drawer__body) ::ng-deep app-menu-list .menu-list__icon{transform:translateY(.1875rem)}:host-context(.app-shell__sidebar) .app-sidebar__brand ::ng-deep [appSidebarBrand]{justify-content:flex-start!important;margin-inline-start:0!important;margin-inline-end:auto!important;text-align:start!important}\n"] }]
|
|
11504
11793
|
}], ctorParameters: () => [], propDecorators: { appTheme: [{ type: i0.Input, args: [{ isSignal: true, alias: "appTheme", required: false }] }], items: [{
|
|
11505
11794
|
type: Input,
|
|
11506
11795
|
args: [{ required: true }]
|
|
@@ -11511,6 +11800,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
11511
11800
|
}], collapsed: [{
|
|
11512
11801
|
type: Input,
|
|
11513
11802
|
args: [{ transform: booleanAttribute }]
|
|
11803
|
+
}], mobileNavOpenPulse: [{
|
|
11804
|
+
type: Input,
|
|
11805
|
+
args: [{ transform: booleanAttribute }]
|
|
11514
11806
|
}], searchable: [{
|
|
11515
11807
|
type: Input,
|
|
11516
11808
|
args: [{ transform: booleanAttribute }]
|
|
@@ -11523,6 +11815,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
11523
11815
|
type: Input
|
|
11524
11816
|
}], itemSelect: [{
|
|
11525
11817
|
type: Output
|
|
11818
|
+
}], menuList: [{
|
|
11819
|
+
type: ViewChild,
|
|
11820
|
+
args: [MenuListComponent]
|
|
11526
11821
|
}] } });
|
|
11527
11822
|
|
|
11528
11823
|
/**
|