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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "structra-ui",
3
- "version": "0.2.54",
3
+ "version": "0.2.55",
4
4
  "description": "Biblioteca de componentes Angular da StructraLab (UI reutilizável).",
5
5
  "homepage": "https://structralab.com/",
6
6
  "license": "MIT",
@@ -3090,9 +3090,12 @@ declare class DrawerComponent implements OnChanges, OnDestroy {
3090
3090
  static ngAcceptInputType_showCloseButton: unknown;
3091
3091
  }
3092
3092
 
3093
- declare class MenuListComponent<T = string> implements OnChanges {
3093
+ declare class MenuListComponent<T = string> implements OnChanges, AfterViewInit {
3094
3094
  private readonly cdr;
3095
+ private readonly injector;
3096
+ private readonly destroyRef;
3095
3097
  readonly appTheme: i0.InputSignal<"blue" | "green" | "purple" | "orange" | "white" | "gray" | "sepia" | "black" | AppTheme | undefined>;
3098
+ private bodyRouteSyncGen;
3096
3099
  items: readonly MenuNodeItem<T>[];
3097
3100
  menuId: string;
3098
3101
  dense: boolean;
@@ -3114,19 +3117,33 @@ declare class MenuListComponent<T = string> implements OnChanges {
3114
3117
  readonly closeRequest: EventEmitter<void>;
3115
3118
  readonly submenuBack: EventEmitter<void>;
3116
3119
  readonly groupToggled: i0.OutputEmitterRef<number>;
3120
+ /** Ver {@link MenuListBodyComponent.selectionScrollHint}. */
3121
+ readonly selectionScrollHint: i0.OutputEmitterRef<void>;
3117
3122
  private body?;
3118
3123
  searchQuery: string;
3124
+ constructor();
3125
+ ngAfterViewInit(): void;
3119
3126
  displayItems: MenuNodeItem<T>[];
3120
3127
  get showSearchField(): boolean;
3121
3128
  get expandAllGroupsWhenSearching(): boolean;
3122
3129
  get showSearchNoResults(): boolean;
3123
3130
  ngOnChanges(changes: SimpleChanges): void;
3131
+ /**
3132
+ * O corpo do menu só existe após o primeiro render; no drawer mobile isso atrasa `ensureExpanded`
3133
+ * relativamente ao `ngOnChanges` do corpo — repetimos após `afterNextRender`.
3134
+ */
3135
+ private scheduleBodyRouteSelectionSync;
3124
3136
  onSearchQueryInput(value: string | null): void;
3125
3137
  resetHighlight(): void;
3126
3138
  focusFirstOption(): void;
3139
+ /**
3140
+ * Usado pela `app-sidebar` ao abrir o drawer móvel: garante {@link MenuListBodyComponent.syncRouteSelectionExpansion}
3141
+ * antes do scroll (grupos fechados em `sessionStorage` passam a abrir no caminho do item activo).
3142
+ */
3143
+ syncSelectionForMobileDrawerOpen(): void;
3127
3144
  private syncDisplayItems;
3128
3145
  static ɵfac: i0.ɵɵFactoryDeclaration<MenuListComponent<any>, never>;
3129
- static ɵcmp: i0.ɵɵComponentDeclaration<MenuListComponent<any>, "app-menu-list", never, { "appTheme": { "alias": "appTheme"; "required": false; "isSignal": true; }; "items": { "alias": "items"; "required": true; }; "menuId": { "alias": "menuId"; "required": false; }; "dense": { "alias": "dense"; "required": false; }; "nested": { "alias": "nested"; "required": false; }; "selectedItemId": { "alias": "selectedItemId"; "required": false; }; "compressText": { "alias": "compressText"; "required": false; }; "clickToOpen": { "alias": "clickToOpen"; "required": false; }; "groupCollapsible": { "alias": "groupCollapsible"; "required": false; }; "groupDefaultExpansion": { "alias": "groupDefaultExpansion"; "required": false; }; "persistGroupExpansion": { "alias": "persistGroupExpansion"; "required": false; }; "searchable": { "alias": "searchable"; "required": false; }; "searchPlaceholder": { "alias": "searchPlaceholder"; "required": false; }; }, { "itemSelect": "itemSelect"; "closeRequest": "closeRequest"; "submenuBack": "submenuBack"; "groupToggled": "groupToggled"; }, never, never, true, never>;
3146
+ static ɵcmp: i0.ɵɵComponentDeclaration<MenuListComponent<any>, "app-menu-list", never, { "appTheme": { "alias": "appTheme"; "required": false; "isSignal": true; }; "items": { "alias": "items"; "required": true; }; "menuId": { "alias": "menuId"; "required": false; }; "dense": { "alias": "dense"; "required": false; }; "nested": { "alias": "nested"; "required": false; }; "selectedItemId": { "alias": "selectedItemId"; "required": false; }; "compressText": { "alias": "compressText"; "required": false; }; "clickToOpen": { "alias": "clickToOpen"; "required": false; }; "groupCollapsible": { "alias": "groupCollapsible"; "required": false; }; "groupDefaultExpansion": { "alias": "groupDefaultExpansion"; "required": false; }; "persistGroupExpansion": { "alias": "persistGroupExpansion"; "required": false; }; "searchable": { "alias": "searchable"; "required": false; }; "searchPlaceholder": { "alias": "searchPlaceholder"; "required": false; }; }, { "itemSelect": "itemSelect"; "closeRequest": "closeRequest"; "submenuBack": "submenuBack"; "groupToggled": "groupToggled"; "selectionScrollHint": "selectionScrollHint"; }, never, never, true, never>;
3130
3147
  static ngAcceptInputType_dense: unknown;
3131
3148
  static ngAcceptInputType_nested: unknown;
3132
3149
  static ngAcceptInputType_compressText: unknown;
@@ -3429,6 +3446,7 @@ declare class AppSidebarComponent<T extends string = string> implements OnChange
3429
3446
  private readonly cdr;
3430
3447
  private readonly destroyRef;
3431
3448
  private readonly hostEl;
3449
+ private readonly injector;
3432
3450
  private readonly renderer;
3433
3451
  /** Igual a `[appTheme]` / {@link ThemeDirective}: paleta explícita no host; omitir = herdar / serviço. */
3434
3452
  readonly appTheme: i0.InputSignal<"blue" | "green" | "purple" | "orange" | "white" | "gray" | "sepia" | "black" | AppTheme | undefined>;
@@ -3438,6 +3456,12 @@ declare class AppSidebarComponent<T extends string = string> implements OnChange
3438
3456
  selectedItemId: T | null;
3439
3457
  /** Modo estreito: só ícones + `compressText` na lista (rótulos via `title` / `aria-label`). */
3440
3458
  collapsed: boolean;
3459
+ /**
3460
+ * Ligado ao estado do drawer no telemóvel (ex.: `mobileNavOpen` do `app-shell`).
3461
+ * Em cada transição para `true`, volta a agendar o scroll até ao item activo — útil porque `selectedItemId`
3462
+ * pode não mudar entre aberturas e o menu pode ser recriado dentro do `@if (open)` do drawer.
3463
+ */
3464
+ mobileNavOpenPulse: boolean;
3441
3465
  /** Repassado a {@link MenuListComponent.searchable}: campo de pesquisa na lista da lateral. */
3442
3466
  searchable: boolean;
3443
3467
  /**
@@ -3455,6 +3479,7 @@ declare class AppSidebarComponent<T extends string = string> implements OnChange
3455
3479
  */
3456
3480
  groupDefaultExpansion: 'all' | 'first';
3457
3481
  readonly itemSelect: EventEmitter<T>;
3482
+ private menuList?;
3458
3483
  /**
3459
3484
  * Valor efectivo de `compressText` em `app-menu-list`: ao expandir a partir do modo rail,
3460
3485
  * mantém-se comprimido até a animação de largura terminar (evita flicker de texto).
@@ -3464,14 +3489,29 @@ declare class AppSidebarComponent<T extends string = string> implements OnChange
3464
3489
  readonly listCompressText: i0.WritableSignal<boolean>;
3465
3490
  private listRevealTimeoutId;
3466
3491
  private scrollRestoreTimeoutId;
3492
+ /** Invalida tentativas de scroll pendentes (ex.: novo agendamento ou destroy). */
3493
+ private scrollToSelectedGeneration;
3494
+ /** `setTimeout` extra ao abrir o drawer — animação (~240ms) e flex podem atrasar métricas do scroll. */
3495
+ private drawerScrollAssistTimeouts;
3467
3496
  constructor();
3468
3497
  ngAfterViewInit(): void;
3469
3498
  ngOnChanges(changes: SimpleChanges): void;
3470
3499
  /**
3471
- * Garante que o item `--selected` fica inteiro na área útil (margem + cabeçalho sticky),
3472
- * com da opção vizinha visível quando scroll, e movimento suave.
3500
+ * Agenda scroll até ao `--selected` depois do próximo render (filhos OnPush) e reintenta em `rAF`
3501
+ * até o elemento existir necessário no drawer mobile, onde o menu acaba de montar.
3502
+ */
3503
+ /**
3504
+ * Repete o scroll quando o utilizador clica num item já activo mas «cortado» (`selectedItemId` não muda).
3473
3505
  */
3474
- private scrollSidebarToSelectedItem;
3506
+ onSidebarItemSelect(id: T): void;
3507
+ /** Também ligado a `(selectionScrollHint)` em `app-menu-list` para o drawer mobile. */
3508
+ scheduleScrollToSelected(): void;
3509
+ private static readonly SCROLL_TO_SELECTED_MAX_ATTEMPTS;
3510
+ private static readonly SCROLL_TO_SELECTED_MAX_ATTEMPTS_DRAWER;
3511
+ /** Sidebar projectada em `.app-drawer__body` — animação do painel e `overflow` do shell afectam o layout. */
3512
+ private isInsideMobileDrawer;
3513
+ private clearDrawerScrollAssistTimeouts;
3514
+ private runScrollToSelectedRetry;
3475
3515
  /** Após clicar num grupo colapsável: leva o cabeçalho do grupo para a zona visível (como o item seleccionado). */
3476
3516
  onMenuGroupToggled(groupId: number): void;
3477
3517
  /** Área com scroll dos itens (`cdkScrollable`), não o cabeçalho nem a pesquisa. */
@@ -3485,8 +3525,9 @@ declare class AppSidebarComponent<T extends string = string> implements OnChange
3485
3525
  private scheduleSidebarHeadLayoutGuards;
3486
3526
  private applySidebarHeadLayoutGuards;
3487
3527
  static ɵfac: i0.ɵɵFactoryDeclaration<AppSidebarComponent<any>, never>;
3488
- static ɵcmp: i0.ɵɵComponentDeclaration<AppSidebarComponent<any>, "app-sidebar", never, { "appTheme": { "alias": "appTheme"; "required": false; "isSignal": true; }; "items": { "alias": "items"; "required": true; }; "menuId": { "alias": "menuId"; "required": false; }; "selectedItemId": { "alias": "selectedItemId"; "required": false; }; "collapsed": { "alias": "collapsed"; "required": false; }; "searchable": { "alias": "searchable"; "required": false; }; "clickToOpen": { "alias": "clickToOpen"; "required": false; }; "groupCollapsible": { "alias": "groupCollapsible"; "required": false; }; "groupDefaultExpansion": { "alias": "groupDefaultExpansion"; "required": false; }; }, { "itemSelect": "itemSelect"; }, never, ["[appSidebarBrand]", "[appSidebarToolbar]"], true, never>;
3528
+ static ɵcmp: i0.ɵɵComponentDeclaration<AppSidebarComponent<any>, "app-sidebar", never, { "appTheme": { "alias": "appTheme"; "required": false; "isSignal": true; }; "items": { "alias": "items"; "required": true; }; "menuId": { "alias": "menuId"; "required": false; }; "selectedItemId": { "alias": "selectedItemId"; "required": false; }; "collapsed": { "alias": "collapsed"; "required": false; }; "mobileNavOpenPulse": { "alias": "mobileNavOpenPulse"; "required": false; }; "searchable": { "alias": "searchable"; "required": false; }; "clickToOpen": { "alias": "clickToOpen"; "required": false; }; "groupCollapsible": { "alias": "groupCollapsible"; "required": false; }; "groupDefaultExpansion": { "alias": "groupDefaultExpansion"; "required": false; }; }, { "itemSelect": "itemSelect"; }, never, ["[appSidebarBrand]", "[appSidebarToolbar]"], true, never>;
3489
3529
  static ngAcceptInputType_collapsed: unknown;
3530
+ static ngAcceptInputType_mobileNavOpenPulse: unknown;
3490
3531
  static ngAcceptInputType_searchable: unknown;
3491
3532
  static ngAcceptInputType_groupCollapsible: unknown;
3492
3533
  }