@acorex/components 20.7.12 → 20.7.13

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,9 +1,9 @@
1
1
  {
2
2
  "name": "@acorex/components",
3
- "version": "20.7.12",
3
+ "version": "20.7.13",
4
4
  "peerDependencies": {
5
- "@acorex/core": "20.7.12",
6
- "@acorex/cdk": "20.7.12",
5
+ "@acorex/core": "20.7.13",
6
+ "@acorex/cdk": "20.7.13",
7
7
  "polytype": ">=0.17.0",
8
8
  "angular-imask": ">=7.6.1",
9
9
  "gridstack": ">=12.0.0",
@@ -60,6 +60,10 @@
60
60
  "types": "./accordion/index.d.ts",
61
61
  "default": "./fesm2022/acorex-components-accordion.mjs"
62
62
  },
63
+ "./action-sheet": {
64
+ "types": "./action-sheet/index.d.ts",
65
+ "default": "./fesm2022/acorex-components-action-sheet.mjs"
66
+ },
63
67
  "./alert": {
64
68
  "types": "./alert/index.d.ts",
65
69
  "default": "./fesm2022/acorex-components-alert.mjs"
@@ -68,10 +72,6 @@
68
72
  "types": "./aspect-ratio/index.d.ts",
69
73
  "default": "./fesm2022/acorex-components-aspect-ratio.mjs"
70
74
  },
71
- "./action-sheet": {
72
- "types": "./action-sheet/index.d.ts",
73
- "default": "./fesm2022/acorex-components-action-sheet.mjs"
74
- },
75
75
  "./audio-wave": {
76
76
  "types": "./audio-wave/index.d.ts",
77
77
  "default": "./fesm2022/acorex-components-audio-wave.mjs"
@@ -396,6 +396,10 @@
396
396
  "types": "./select-box/index.d.ts",
397
397
  "default": "./fesm2022/acorex-components-select-box.mjs"
398
398
  },
399
+ "./selection-list": {
400
+ "types": "./selection-list/index.d.ts",
401
+ "default": "./fesm2022/acorex-components-selection-list.mjs"
402
+ },
399
403
  "./selection-list-2": {
400
404
  "types": "./selection-list-2/index.d.ts",
401
405
  "default": "./fesm2022/acorex-components-selection-list-2.mjs"
@@ -483,10 +487,6 @@
483
487
  "./wysiwyg": {
484
488
  "types": "./wysiwyg/index.d.ts",
485
489
  "default": "./fesm2022/acorex-components-wysiwyg.mjs"
486
- },
487
- "./selection-list": {
488
- "types": "./selection-list/index.d.ts",
489
- "default": "./fesm2022/acorex-components-selection-list.mjs"
490
490
  }
491
491
  }
492
492
  }
@@ -1,4 +1,5 @@
1
1
  import * as _angular_core from '@angular/core';
2
+ import { Signal, ElementRef } from '@angular/core';
2
3
  import * as i2 from '@acorex/cdk/common';
3
4
  import { MXInteractiveComponent, AXClickEvent, NXComponent } from '@acorex/cdk/common';
4
5
  import * as i5 from '@angular/router';
@@ -8,6 +9,15 @@ import * as i3 from '@acorex/components/loading';
8
9
  import * as i4 from '@acorex/core/translation';
9
10
  import * as i6 from '@acorex/components/decorators';
10
11
 
12
+ /**
13
+ * DI token for the parent `ax-side-menu`. Child `ax-side-menu-item`s inject this
14
+ * to read shared state (e.g. the current display mode) without creating a
15
+ * circular import on the concrete `AXSideMenuComponent` class.
16
+ */
17
+ declare abstract class AXSideMenuBase {
18
+ abstract readonly mode: Signal<'full' | 'compact'>;
19
+ }
20
+
11
21
  declare class AXSideMenuItemClickEvent extends AXClickEvent {
12
22
  handled: boolean;
13
23
  }
@@ -18,7 +28,23 @@ declare class AXSideMenuItemComponent extends MXInteractiveComponent {
18
28
  isLoading: _angular_core.ModelSignal<boolean>;
19
29
  isCollapsed: _angular_core.ModelSignal<boolean>;
20
30
  onClick: _angular_core.OutputEmitterRef<AXSideMenuItemClickEvent>;
31
+ tooltipStatus: _angular_core.WritableSignal<boolean>;
32
+ tooltipText: _angular_core.InputSignal<string>;
21
33
  private elem;
34
+ private document;
35
+ private platformId;
36
+ private destroyRef;
37
+ private childObserver;
38
+ private childrenPopover;
39
+ protected menuItemTrigger: _angular_core.Signal<ElementRef<HTMLElement>>;
40
+ /** Synced from the parent `ax-side-menu` (source of truth for full vs compact). */
41
+ private menuMode;
42
+ /** True when this item should use compact flyout popovers (rail or inside a flyout). */
43
+ protected isCompactMode: _angular_core.Signal<boolean>;
44
+ /** Called by `ax-side-menu` so items always know the current display mode. */
45
+ syncMenuMode(mode: 'full' | 'compact'): void;
46
+ /** Top-level rail button in compact mode (icon only, opens flyout). */
47
+ protected isFirstLevel: _angular_core.Signal<boolean>;
22
48
  readonly toggleOnClick: _angular_core.InputSignal<boolean>;
23
49
  readonly href: _angular_core.InputSignal<string>;
24
50
  readonly routerLink: _angular_core.InputSignal<string | any[] | UrlTree>;
@@ -27,14 +53,51 @@ declare class AXSideMenuItemComponent extends MXInteractiveComponent {
27
53
  exact: boolean;
28
54
  } | IsActiveMatchOptions>;
29
55
  readonly target: _angular_core.InputSignal<"_blank" | "_self" | "_parent" | "_top">;
56
+ private childItems;
57
+ private childrenSlot;
58
+ private popoverSlot;
30
59
  protected hasChild: _angular_core.WritableSignal<boolean>;
60
+ /**
61
+ * Walks up the DOM to find the enclosing `<ax-side-menu>` host element and
62
+ * reads its component instance from `__axContext__`. Needed because items
63
+ * rendered inside `ngTemplateOutlet` embedded views cannot inject the
64
+ * `AXSideMenuBase` token (DI scope is the template's declaration site).
65
+ */
66
+ private resolveMenuHostElement;
67
+ /**
68
+ * Moves any `<ax-side-menu-item>` that belongs to this item (its nearest
69
+ * `<ax-side-menu-item>` ancestor in the projected DOM is this host) but is
70
+ * NOT inside our own `.ax-side-children-content` container. Without this
71
+ * step a content-projection edge case in Angular 21+ leaves recursive items
72
+ * stranded inside `.ax-inside-text` (the catch-all `<ng-content>` slot) and
73
+ * the submenu cannot expand.
74
+ */
75
+ private getActiveChildrenSlot;
76
+ private reparentOrphanedChildren;
77
+ private syncCompactPopover;
78
+ /** Restores submenu nodes to the inline slot before the overlay is disposed. */
79
+ private closeCompactFlyout;
80
+ /** Closes other top-level compact flyouts when a rail item is opened. */
81
+ private closeSiblingCompactPopovers;
82
+ /**
83
+ * Moves projected submenu nodes into the popover panel when opening in compact mode.
84
+ * They are not moved back to the inline slot on close (that caused a full-mode flash below the rail).
85
+ */
86
+ private relocateChildren;
87
+ /**
88
+ * Pulls direct submenu nodes back into the inline slot from the popover host and
89
+ * from any open flyout overlay panel so they are not destroyed on overlay dispose.
90
+ */
91
+ private moveChildrenToInlineSlot;
92
+ protected _handlePopoverClosed(): void;
31
93
  private checkForChildren;
94
+ private hasNestedMenuItems;
32
95
  protected _handleClickEvent(e: MouseEvent): void;
33
96
  toggle(): void;
34
97
  open(): void;
35
98
  close(): void;
36
99
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXSideMenuItemComponent, never>;
37
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXSideMenuItemComponent, "ax-side-menu-item", never, { "disabled": { "alias": "disabled"; "required": false; }; "text": { "alias": "text"; "required": false; "isSignal": true; }; "active": { "alias": "active"; "required": false; "isSignal": true; }; "isLoading": { "alias": "isLoading"; "required": false; "isSignal": true; }; "isCollapsed": { "alias": "isCollapsed"; "required": false; "isSignal": true; }; "toggleOnClick": { "alias": "toggleOnClick"; "required": false; "isSignal": true; }; "href": { "alias": "href"; "required": false; "isSignal": true; }; "routerLink": { "alias": "routerLink"; "required": false; "isSignal": true; }; "routerLinkActive": { "alias": "routerLinkActive"; "required": false; "isSignal": true; }; "routerLinkActiveOptions": { "alias": "routerLinkActiveOptions"; "required": false; "isSignal": true; }; "target": { "alias": "target"; "required": false; "isSignal": true; }; }, { "text": "textChange"; "active": "activeChange"; "isLoading": "isLoadingChange"; "isCollapsed": "isCollapsedChange"; "onClick": "onClick"; }, never, ["ax-title", "ax-side-menu-item, ng-container", "ax-divider", "ax-prefix", "ax-text", "*", "ax-suffix"], true, never>;
100
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXSideMenuItemComponent, "ax-side-menu-item", never, { "disabled": { "alias": "disabled"; "required": false; }; "text": { "alias": "text"; "required": false; "isSignal": true; }; "active": { "alias": "active"; "required": false; "isSignal": true; }; "isLoading": { "alias": "isLoading"; "required": false; "isSignal": true; }; "isCollapsed": { "alias": "isCollapsed"; "required": false; "isSignal": true; }; "tooltipText": { "alias": "tooltipText"; "required": false; "isSignal": true; }; "toggleOnClick": { "alias": "toggleOnClick"; "required": false; "isSignal": true; }; "href": { "alias": "href"; "required": false; "isSignal": true; }; "routerLink": { "alias": "routerLink"; "required": false; "isSignal": true; }; "routerLinkActive": { "alias": "routerLinkActive"; "required": false; "isSignal": true; }; "routerLinkActiveOptions": { "alias": "routerLinkActiveOptions"; "required": false; "isSignal": true; }; "target": { "alias": "target"; "required": false; "isSignal": true; }; }, { "text": "textChange"; "active": "activeChange"; "isLoading": "isLoadingChange"; "isCollapsed": "isCollapsedChange"; "onClick": "onClick"; }, ["childItems"], ["ax-title", "ax-side-menu-item, ng-container, [ngTemplateOutlet]", "ax-divider", "ax-prefix", "*", "ax-suffix"], true, never>;
38
101
  }
39
102
 
40
103
  type AXSideMenuLook = 'pills' | 'with-line' | 'with-line-color' | 'default';
@@ -63,15 +126,45 @@ type AXSideMenuItem = {
63
126
  * @category
64
127
  * A component for displaying a side menu with customizable content.
65
128
  */
66
- declare class AXSideMenuComponent extends NXComponent {
129
+ declare class AXSideMenuComponent extends NXComponent implements AXSideMenuBase {
130
+ #private;
67
131
  items: _angular_core.ModelSignal<AXSideMenuItem[]>;
68
132
  readonly look: _angular_core.InputSignal<AXSideMenuLook>;
69
133
  readonly location: _angular_core.InputSignal<AXSideMenuLocation>;
70
- children: _angular_core.Signal<readonly AXSideMenuItemComponent[]>;
134
+ readonly mode: _angular_core.InputSignal<"full" | "compact">;
135
+ private elementRef;
136
+ /**
137
+ * All `ax-side-menu-item` instances discovered by walking the host DOM.
138
+ *
139
+ * We use DOM discovery (instead of `contentChildren`) because Angular content
140
+ * queries do **not** traverse embedded views created by `ngTemplateOutlet`,
141
+ * and the `AXSideMenuBase` DI token is not reachable from inside those views
142
+ * either (they inherit injection from the template's declaration site, not
143
+ * the insertion site). Walking the DOM works for direct projection,
144
+ * structural directives, and recursive `ngTemplateOutlet`-based templates
145
+ * uniformly.
146
+ */
147
+ private _items;
148
+ /** Read-only signal exposing every discovered `ax-side-menu-item` instance. */
149
+ readonly children: _angular_core.Signal<AXSideMenuItemComponent[]>;
150
+ private platformId;
151
+ private destroyRef;
152
+ hostElement: HTMLElement;
153
+ /**
154
+ * Walks the host DOM to discover every nested `ax-side-menu-item`, looks up
155
+ * the component instance through the `__axContext__` property that
156
+ * `MXBaseComponent.ngOnInit` attaches to each host element, and updates the
157
+ * internal items signal and `.first-level` CSS class accordingly.
158
+ *
159
+ * Triggered both initially and from a `MutationObserver` so recursive
160
+ * templates that add/remove items at runtime stay in sync.
161
+ */
162
+ private refreshItemsFromDom;
163
+ private addFirstLevelClass;
71
164
  /** @ignore */
72
165
  private get __hostClass();
73
166
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXSideMenuComponent, never>;
74
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXSideMenuComponent, "ax-side-menu", never, { "items": { "alias": "items"; "required": false; "isSignal": true; }; "look": { "alias": "look"; "required": false; "isSignal": true; }; "location": { "alias": "location"; "required": false; "isSignal": true; }; }, { "items": "itemsChange"; }, never, ["ax-side-menu-item,ax-title,ng-container,ng-content"], true, never>;
167
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AXSideMenuComponent, "ax-side-menu", never, { "items": { "alias": "items"; "required": false; "isSignal": true; }; "look": { "alias": "look"; "required": false; "isSignal": true; }; "location": { "alias": "location"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; }, { "items": "itemsChange"; }, never, ["ax-side-menu-item,ax-title,ng-container,[ngTemplateOutlet]"], true, never>;
75
168
  }
76
169
 
77
170
  declare class AXOutlineSideMenuDirective {
@@ -100,5 +193,5 @@ declare class AXSideMenuModule {
100
193
  static ɵinj: _angular_core.ɵɵInjectorDeclaration<AXSideMenuModule>;
101
194
  }
102
195
 
103
- export { AXOutlineSideMenuDirective, AXSideMenuComponent, AXSideMenuItemClickEvent, AXSideMenuItemComponent, AXSideMenuModule };
196
+ export { AXOutlineSideMenuDirective, AXSideMenuBase, AXSideMenuComponent, AXSideMenuItemClickEvent, AXSideMenuItemComponent, AXSideMenuModule };
104
197
  export type { AXSideMenuItem, AXSideMenuLocation, AXSideMenuLook };