@neuravision/ng-construct 0.2.0 → 0.3.0

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.
@@ -2,6 +2,7 @@ import * as i0 from '@angular/core';
2
2
  import { input, output, signal, computed, ChangeDetectionStrategy, Component, inject, forwardRef, model, booleanAttribute, viewChild, contentChildren, effect, contentChild, ElementRef, TemplateRef, Directive, Injectable, viewChildren, Renderer2, InjectionToken, DOCUMENT, numberAttribute, Pipe } from '@angular/core';
3
3
  import { NG_VALUE_ACCESSOR } from '@angular/forms';
4
4
  import { NgTemplateOutlet } from '@angular/common';
5
+ import { RouterLink, RouterLinkActive } from '@angular/router';
5
6
 
6
7
  /**
7
8
  * Alert component for displaying contextual feedback messages.
@@ -6194,17 +6195,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
6194
6195
 
6195
6196
  let nextId = 0;
6196
6197
  /**
6197
- * Individual navigation item used within af-navbar.
6198
+ * Individual navigation item used within af-navbar or af-toolbar.
6199
+ *
6200
+ * Supports Angular Router via `routerLink`, standard links via `href`,
6201
+ * and button mode when neither is provided. Content projection allows
6202
+ * icons and custom markup inside the link.
6198
6203
  *
6199
6204
  * @example
6200
- * <af-nav-item label="Dashboard" href="/dashboard" [active]="true" />
6205
+ * <af-nav-item label="Dashboard" routerLink="/dashboard">
6206
+ * <af-icon name="dashboard" /> Dashboard
6207
+ * </af-nav-item>
6201
6208
  */
6202
6209
  class AfNavItemComponent {
6203
- /** Text label for the navigation item. */
6210
+ /** Text label shown as fallback when no content is projected. Also used by the mobile menu. */
6204
6211
  label = input.required(...(ngDevMode ? [{ debugName: "label" }] : []));
6205
6212
  /** URL for the navigation link. Renders as `<a>` when provided, `<button>` otherwise. */
6206
6213
  href = input('', ...(ngDevMode ? [{ debugName: "href" }] : []));
6207
- /** Marks this item as the currently active page. */
6214
+ /** Angular Router link. Renders as `<a>` with routerLink and auto-active detection. */
6215
+ routerLink = input(null, ...(ngDevMode ? [{ debugName: "routerLink" }] : []));
6216
+ /** Marks this item as the currently active page (used for href/button mode, routerLink auto-detects). */
6208
6217
  active = input(false, { ...(ngDevMode ? { debugName: "active" } : {}), transform: booleanAttribute });
6209
6218
  /** Disables interaction with this item. */
6210
6219
  disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : {}), transform: booleanAttribute });
@@ -6225,76 +6234,106 @@ class AfNavItemComponent {
6225
6234
  this.clicked.emit(event);
6226
6235
  }
6227
6236
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AfNavItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6228
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: AfNavItemComponent, isStandalone: true, selector: "af-nav-item", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, href: { classPropertyName: "href", publicName: "href", isSignal: true, isRequired: false, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked" }, viewQueries: [{ propertyName: "linkRef", first: true, predicate: ["linkEl"], descendants: true, isSignal: true }], ngImport: i0, template: `
6237
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: AfNavItemComponent, isStandalone: true, selector: "af-nav-item", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, href: { classPropertyName: "href", publicName: "href", isSignal: true, isRequired: false, transformFunction: null }, routerLink: { classPropertyName: "routerLink", publicName: "routerLink", isSignal: true, isRequired: false, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked" }, viewQueries: [{ propertyName: "linkRef", first: true, predicate: ["linkEl"], descendants: true, isSignal: true }], ngImport: i0, template: `
6229
6238
  <li class="ct-navbar__item" role="none">
6230
- @if (href()) {
6239
+ @if (routerLink()) {
6231
6240
  <a
6232
6241
  #linkEl
6233
6242
  class="ct-navbar__link"
6243
+ [routerLink]="routerLink()!"
6244
+ routerLinkActive="ct-navbar__link--active"
6245
+ role="menuitem"
6246
+ [attr.aria-disabled]="disabled() || null"
6247
+ [attr.tabindex]="rovingTabindex()"
6248
+ (click)="onClick($event)">
6249
+ <ng-content>{{ label() }}</ng-content>
6250
+ </a>
6251
+ } @else if (href()) {
6252
+ <a
6253
+ #linkEl
6254
+ class="ct-navbar__link"
6255
+ [class.ct-navbar__link--active]="active()"
6234
6256
  [href]="href()"
6235
6257
  role="menuitem"
6236
6258
  [attr.aria-current]="active() ? 'page' : null"
6237
6259
  [attr.aria-disabled]="disabled() || null"
6238
6260
  [attr.tabindex]="rovingTabindex()"
6239
6261
  (click)="onClick($event)">
6240
- {{ label() }}
6262
+ <ng-content>{{ label() }}</ng-content>
6241
6263
  </a>
6242
6264
  } @else {
6243
6265
  <button
6244
6266
  #linkEl
6245
6267
  class="ct-navbar__link"
6268
+ [class.ct-navbar__link--active]="active()"
6246
6269
  type="button"
6247
6270
  role="menuitem"
6248
6271
  [attr.aria-current]="active() ? 'page' : null"
6249
6272
  [attr.aria-disabled]="disabled() || null"
6250
6273
  [attr.tabindex]="rovingTabindex()"
6251
6274
  (click)="onClick($event)">
6252
- {{ label() }}
6275
+ <ng-content>{{ label() }}</ng-content>
6253
6276
  </button>
6254
6277
  }
6255
6278
  </li>
6256
- `, isInline: true, styles: [":host{display:contents}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
6279
+ `, isInline: true, styles: [":host{display:contents}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
6257
6280
  }
6258
6281
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AfNavItemComponent, decorators: [{
6259
6282
  type: Component,
6260
- args: [{ selector: 'af-nav-item', changeDetection: ChangeDetectionStrategy.OnPush, template: `
6283
+ args: [{ selector: 'af-nav-item', changeDetection: ChangeDetectionStrategy.OnPush, imports: [RouterLink, RouterLinkActive], template: `
6261
6284
  <li class="ct-navbar__item" role="none">
6262
- @if (href()) {
6285
+ @if (routerLink()) {
6286
+ <a
6287
+ #linkEl
6288
+ class="ct-navbar__link"
6289
+ [routerLink]="routerLink()!"
6290
+ routerLinkActive="ct-navbar__link--active"
6291
+ role="menuitem"
6292
+ [attr.aria-disabled]="disabled() || null"
6293
+ [attr.tabindex]="rovingTabindex()"
6294
+ (click)="onClick($event)">
6295
+ <ng-content>{{ label() }}</ng-content>
6296
+ </a>
6297
+ } @else if (href()) {
6263
6298
  <a
6264
6299
  #linkEl
6265
6300
  class="ct-navbar__link"
6301
+ [class.ct-navbar__link--active]="active()"
6266
6302
  [href]="href()"
6267
6303
  role="menuitem"
6268
6304
  [attr.aria-current]="active() ? 'page' : null"
6269
6305
  [attr.aria-disabled]="disabled() || null"
6270
6306
  [attr.tabindex]="rovingTabindex()"
6271
6307
  (click)="onClick($event)">
6272
- {{ label() }}
6308
+ <ng-content>{{ label() }}</ng-content>
6273
6309
  </a>
6274
6310
  } @else {
6275
6311
  <button
6276
6312
  #linkEl
6277
6313
  class="ct-navbar__link"
6314
+ [class.ct-navbar__link--active]="active()"
6278
6315
  type="button"
6279
6316
  role="menuitem"
6280
6317
  [attr.aria-current]="active() ? 'page' : null"
6281
6318
  [attr.aria-disabled]="disabled() || null"
6282
6319
  [attr.tabindex]="rovingTabindex()"
6283
6320
  (click)="onClick($event)">
6284
- {{ label() }}
6321
+ <ng-content>{{ label() }}</ng-content>
6285
6322
  </button>
6286
6323
  }
6287
6324
  </li>
6288
6325
  `, styles: [":host{display:contents}\n"] }]
6289
- }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], href: [{ type: i0.Input, args: [{ isSignal: true, alias: "href", required: false }] }], active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], clicked: [{ type: i0.Output, args: ["clicked"] }], linkRef: [{ type: i0.ViewChild, args: ['linkEl', { isSignal: true }] }] } });
6326
+ }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], href: [{ type: i0.Input, args: [{ isSignal: true, alias: "href", required: false }] }], routerLink: [{ type: i0.Input, args: [{ isSignal: true, alias: "routerLink", required: false }] }], active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], clicked: [{ type: i0.Output, args: ["clicked"] }], linkRef: [{ type: i0.ViewChild, args: ['linkEl', { isSignal: true }] }] } });
6290
6327
  /**
6291
6328
  * Responsive navbar with mobile menu, keyboard navigation, and ARIA landmarks.
6292
6329
  *
6293
6330
  * @example
6294
6331
  * <af-navbar ariaLabel="Main navigation">
6295
6332
  * <a brand class="ct-navbar__brand" href="/">My App</a>
6296
- * <af-nav-item label="Dashboard" href="/dashboard" [active]="true" />
6297
- * <af-nav-item label="Settings" href="/settings" />
6333
+ * <af-nav-item label="Dashboard" routerLink="/dashboard">
6334
+ * <af-icon name="dashboard" /> Dashboard
6335
+ * </af-nav-item>
6336
+ * <af-nav-item label="Settings" routerLink="/settings" />
6298
6337
  * <button actions class="ct-button">Profile</button>
6299
6338
  * </af-navbar>
6300
6339
  */
@@ -6517,7 +6556,19 @@ class AfNavbarComponent {
6517
6556
  role="menu"
6518
6557
  aria-label="Mobile navigation">
6519
6558
  @for (item of items(); track item) {
6520
- @if (item.href()) {
6559
+ @if (item.routerLink(); as rl) {
6560
+ <a
6561
+ #mobileLink
6562
+ class="ct-navbar__link"
6563
+ [routerLink]="rl"
6564
+ routerLinkActive="ct-navbar__link--active"
6565
+ role="menuitem"
6566
+ [attr.aria-disabled]="item.disabled() || null"
6567
+ [attr.tabindex]="mobileMenuOpen() ? 0 : -1"
6568
+ (click)="onMobileItemClick($event, item)">
6569
+ {{ item.label() }}
6570
+ </a>
6571
+ } @else if (item.href()) {
6521
6572
  <a
6522
6573
  #mobileLink
6523
6574
  class="ct-navbar__link"
@@ -6545,11 +6596,11 @@ class AfNavbarComponent {
6545
6596
  }
6546
6597
  </div>
6547
6598
  </header>
6548
- `, isInline: true, styles: [":host{display:block}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
6599
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
6549
6600
  }
6550
6601
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AfNavbarComponent, decorators: [{
6551
6602
  type: Component,
6552
- args: [{ selector: 'af-navbar', changeDetection: ChangeDetectionStrategy.OnPush, host: {
6603
+ args: [{ selector: 'af-navbar', changeDetection: ChangeDetectionStrategy.OnPush, imports: [RouterLink, RouterLinkActive], host: {
6553
6604
  '(keydown)': 'handleKeydown($event)',
6554
6605
  '(document:click)': 'onDocumentClick($event)',
6555
6606
  }, template: `
@@ -6590,7 +6641,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
6590
6641
  role="menu"
6591
6642
  aria-label="Mobile navigation">
6592
6643
  @for (item of items(); track item) {
6593
- @if (item.href()) {
6644
+ @if (item.routerLink(); as rl) {
6645
+ <a
6646
+ #mobileLink
6647
+ class="ct-navbar__link"
6648
+ [routerLink]="rl"
6649
+ routerLinkActive="ct-navbar__link--active"
6650
+ role="menuitem"
6651
+ [attr.aria-disabled]="item.disabled() || null"
6652
+ [attr.tabindex]="mobileMenuOpen() ? 0 : -1"
6653
+ (click)="onMobileItemClick($event, item)">
6654
+ {{ item.label() }}
6655
+ </a>
6656
+ } @else if (item.href()) {
6594
6657
  <a
6595
6658
  #mobileLink
6596
6659
  class="ct-navbar__link"