@neuravision/ng-construct 0.3.3 → 0.3.6
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, output, signal, computed, ChangeDetectionStrategy, Component, inject, forwardRef, model, booleanAttribute, viewChild, contentChildren, effect, contentChild, ElementRef, TemplateRef, Directive, Injectable, viewChildren, Renderer2, InjectionToken,
|
|
2
|
+
import { input, output, signal, computed, ChangeDetectionStrategy, Component, inject, forwardRef, model, booleanAttribute, viewChild, contentChildren, effect, DOCUMENT, contentChild, ElementRef, TemplateRef, Directive, Injectable, viewChildren, Renderer2, InjectionToken, numberAttribute, Pipe } from '@angular/core';
|
|
3
3
|
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
4
4
|
import { NgTemplateOutlet } from '@angular/common';
|
|
5
5
|
import { RouterLink, RouterLinkActive } from '@angular/router';
|
|
@@ -354,6 +354,464 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
|
|
|
354
354
|
`, styles: [":host{display:block}\n"] }]
|
|
355
355
|
}], propDecorators: { multi: [{ type: i0.Input, args: [{ isSignal: true, alias: "multi", required: false }] }], bordered: [{ type: i0.Input, args: [{ isSignal: true, alias: "bordered", required: false }] }], items: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => AfAccordionItemComponent), { isSignal: true }] }] } });
|
|
356
356
|
|
|
357
|
+
/**
|
|
358
|
+
* Skip-link component for keyboard-only navigation bypass.
|
|
359
|
+
*
|
|
360
|
+
* Renders an anchor that is visually hidden off-screen and slides into view
|
|
361
|
+
* when focused. On activation it moves focus to the target element, allowing
|
|
362
|
+
* keyboard users to skip repetitive navigation blocks.
|
|
363
|
+
*
|
|
364
|
+
* Must be placed as the first focusable element in the document.
|
|
365
|
+
*
|
|
366
|
+
* @example
|
|
367
|
+
* <af-skip-link target="main-content" />
|
|
368
|
+
* <nav>…</nav>
|
|
369
|
+
* <main id="main-content" tabindex="-1">…</main>
|
|
370
|
+
*/
|
|
371
|
+
class AfSkipLinkComponent {
|
|
372
|
+
/** ID of the element to skip to (without the leading `#`). */
|
|
373
|
+
target = input.required(...(ngDevMode ? [{ debugName: "target" }] : []));
|
|
374
|
+
/** Visible label text shown when the link receives focus. */
|
|
375
|
+
label = input('Skip to main content', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
376
|
+
document = inject(DOCUMENT);
|
|
377
|
+
/**
|
|
378
|
+
* Moves focus to the target element so keyboard navigation
|
|
379
|
+
* continues from there instead of the top of the page.
|
|
380
|
+
*/
|
|
381
|
+
focusTarget(event) {
|
|
382
|
+
event.preventDefault();
|
|
383
|
+
const el = this.document.getElementById(this.target());
|
|
384
|
+
if (!el) {
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
if (!el.hasAttribute('tabindex')) {
|
|
388
|
+
el.setAttribute('tabindex', '-1');
|
|
389
|
+
}
|
|
390
|
+
el.focus();
|
|
391
|
+
}
|
|
392
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AfSkipLinkComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
393
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.2", type: AfSkipLinkComponent, isStandalone: true, selector: "af-skip-link", inputs: { target: { classPropertyName: "target", publicName: "target", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
394
|
+
<a
|
|
395
|
+
class="ct-skip-link"
|
|
396
|
+
[attr.href]="'#' + target()"
|
|
397
|
+
(click)="focusTarget($event)"
|
|
398
|
+
>
|
|
399
|
+
{{ label() }}
|
|
400
|
+
</a>
|
|
401
|
+
`, isInline: true, styles: [":host{display:contents}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
402
|
+
}
|
|
403
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AfSkipLinkComponent, decorators: [{
|
|
404
|
+
type: Component,
|
|
405
|
+
args: [{ selector: 'af-skip-link', changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
406
|
+
<a
|
|
407
|
+
class="ct-skip-link"
|
|
408
|
+
[attr.href]="'#' + target()"
|
|
409
|
+
(click)="focusTarget($event)"
|
|
410
|
+
>
|
|
411
|
+
{{ label() }}
|
|
412
|
+
</a>
|
|
413
|
+
`, styles: [":host{display:contents}\n"] }]
|
|
414
|
+
}], propDecorators: { target: [{ type: i0.Input, args: [{ isSignal: true, alias: "target", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }] } });
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Page header rendered inside the main content area of an App Shell.
|
|
418
|
+
*
|
|
419
|
+
* Displays breadcrumbs, page title, and actions in a flex row.
|
|
420
|
+
* Place inside `<af-app-shell>` without any slot attribute so it
|
|
421
|
+
* projects into the main area.
|
|
422
|
+
*
|
|
423
|
+
* @example
|
|
424
|
+
* <af-app-shell>
|
|
425
|
+
* <af-app-shell-page-header sticky>
|
|
426
|
+
* <nav aria-label="Breadcrumb">Home / Dashboard</nav>
|
|
427
|
+
* <h1>Dashboard</h1>
|
|
428
|
+
* <button class="ct-button">New Item</button>
|
|
429
|
+
* </af-app-shell-page-header>
|
|
430
|
+
* <p>Main content…</p>
|
|
431
|
+
* </af-app-shell>
|
|
432
|
+
*/
|
|
433
|
+
class AfAppShellPageHeaderComponent {
|
|
434
|
+
/** Pin the page header to the top of the scrollable main area. */
|
|
435
|
+
sticky = input(false, { ...(ngDevMode ? { debugName: "sticky" } : {}), transform: booleanAttribute });
|
|
436
|
+
classes = computed(() => {
|
|
437
|
+
const c = ['ct-app-shell__page-header'];
|
|
438
|
+
if (this.sticky()) {
|
|
439
|
+
c.push('ct-app-shell__page-header--sticky');
|
|
440
|
+
}
|
|
441
|
+
return c.join(' ');
|
|
442
|
+
}, ...(ngDevMode ? [{ debugName: "classes" }] : []));
|
|
443
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AfAppShellPageHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
444
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.2", type: AfAppShellPageHeaderComponent, isStandalone: true, selector: "af-app-shell-page-header", inputs: { sticky: { classPropertyName: "sticky", publicName: "sticky", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
445
|
+
<div [class]="classes()">
|
|
446
|
+
<ng-content />
|
|
447
|
+
</div>
|
|
448
|
+
`, isInline: true, styles: [":host{display:contents}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
449
|
+
}
|
|
450
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AfAppShellPageHeaderComponent, decorators: [{
|
|
451
|
+
type: Component,
|
|
452
|
+
args: [{ selector: 'af-app-shell-page-header', changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
453
|
+
<div [class]="classes()">
|
|
454
|
+
<ng-content />
|
|
455
|
+
</div>
|
|
456
|
+
`, styles: [":host{display:contents}\n"] }]
|
|
457
|
+
}], propDecorators: { sticky: [{ type: i0.Input, args: [{ isSignal: true, alias: "sticky", required: false }] }] } });
|
|
458
|
+
/**
|
|
459
|
+
* Classic CSS-Grid App Shell that orchestrates header, sidebar,
|
|
460
|
+
* main content, optional panel, and footer.
|
|
461
|
+
*
|
|
462
|
+
* Wraps the `ct-app-shell` CSS component from the Construct Design System.
|
|
463
|
+
* Sidebar and panel states are two-way bindable via `model()` signals.
|
|
464
|
+
*
|
|
465
|
+
* Content projection slots:
|
|
466
|
+
* - `[header]` — Navbar / top bar
|
|
467
|
+
* - `[sidebar]` — Navigation sidebar
|
|
468
|
+
* - `[panel]` — Right-side contextual panel
|
|
469
|
+
* - `[footer]` — Footer area
|
|
470
|
+
* - `[bottomNav]` — Mobile bottom navigation (requires `bottomNav` modifier)
|
|
471
|
+
* - *(default)* — Main content (including `<af-app-shell-page-header>`)
|
|
472
|
+
*
|
|
473
|
+
* @example
|
|
474
|
+
* <af-app-shell [(sidebarState)]="sidebarState" [(panelState)]="panelState" sidebarFullHeight>
|
|
475
|
+
* <af-navbar header ariaLabel="Main">…</af-navbar>
|
|
476
|
+
* <af-sidebar sidebar ariaLabel="Navigation">…</af-sidebar>
|
|
477
|
+
* <af-app-shell-page-header sticky>
|
|
478
|
+
* <h1>Dashboard</h1>
|
|
479
|
+
* </af-app-shell-page-header>
|
|
480
|
+
* <p>Content goes here</p>
|
|
481
|
+
* <div panel>Inspector</div>
|
|
482
|
+
* <footer footer>© 2026</footer>
|
|
483
|
+
* </af-app-shell>
|
|
484
|
+
*/
|
|
485
|
+
class AfAppShellComponent {
|
|
486
|
+
/** Current sidebar state — two-way bindable. */
|
|
487
|
+
sidebarState = model('expanded', ...(ngDevMode ? [{ debugName: "sidebarState" }] : []));
|
|
488
|
+
/** Current panel state — two-way bindable. */
|
|
489
|
+
panelState = model('closed', ...(ngDevMode ? [{ debugName: "panelState" }] : []));
|
|
490
|
+
/** Remove the sidebar column entirely. */
|
|
491
|
+
noSidebar = input(false, { ...(ngDevMode ? { debugName: "noSidebar" } : {}), transform: booleanAttribute });
|
|
492
|
+
/** Place the sidebar on the right side. */
|
|
493
|
+
sidebarRight = input(false, { ...(ngDevMode ? { debugName: "sidebarRight" } : {}), transform: booleanAttribute });
|
|
494
|
+
/** Sidebar spans the full viewport height (header sits beside it). */
|
|
495
|
+
sidebarFullHeight = input(false, { ...(ngDevMode ? { debugName: "sidebarFullHeight" } : {}), transform: booleanAttribute });
|
|
496
|
+
/** Stick the footer to the bottom with a top border. */
|
|
497
|
+
footerSticky = input(false, { ...(ngDevMode ? { debugName: "footerSticky" } : {}), transform: booleanAttribute });
|
|
498
|
+
/** Enable bottom navigation on mobile (hides sidebar and footer). */
|
|
499
|
+
bottomNav = input(false, { ...(ngDevMode ? { debugName: "bottomNav" } : {}), transform: booleanAttribute });
|
|
500
|
+
/** Accessible label for the sidebar landmark. */
|
|
501
|
+
sidebarLabel = input('Site navigation', ...(ngDevMode ? [{ debugName: "sidebarLabel" }] : []));
|
|
502
|
+
/** Accessible label for the panel landmark. */
|
|
503
|
+
panelLabel = input('Details', ...(ngDevMode ? [{ debugName: "panelLabel" }] : []));
|
|
504
|
+
/** ID of the main content element (used by skip-link). */
|
|
505
|
+
mainId = input('main-content', ...(ngDevMode ? [{ debugName: "mainId" }] : []));
|
|
506
|
+
/** Visible text of the skip-link. */
|
|
507
|
+
skipLinkLabel = input('Skip to content', ...(ngDevMode ? [{ debugName: "skipLinkLabel" }] : []));
|
|
508
|
+
shellClasses = computed(() => {
|
|
509
|
+
const classes = ['ct-app-shell'];
|
|
510
|
+
if (this.noSidebar()) {
|
|
511
|
+
classes.push('ct-app-shell--no-sidebar');
|
|
512
|
+
}
|
|
513
|
+
if (this.sidebarRight()) {
|
|
514
|
+
classes.push('ct-app-shell--sidebar-right');
|
|
515
|
+
}
|
|
516
|
+
if (this.sidebarFullHeight()) {
|
|
517
|
+
classes.push('ct-app-shell--sidebar-full-height');
|
|
518
|
+
}
|
|
519
|
+
if (this.footerSticky()) {
|
|
520
|
+
classes.push('ct-app-shell--footer-sticky');
|
|
521
|
+
}
|
|
522
|
+
if (this.bottomNav()) {
|
|
523
|
+
classes.push('ct-app-shell--bottom-nav');
|
|
524
|
+
}
|
|
525
|
+
return classes.join(' ');
|
|
526
|
+
}, ...(ngDevMode ? [{ debugName: "shellClasses" }] : []));
|
|
527
|
+
/** Dismiss the mobile sidebar overlay. */
|
|
528
|
+
onBackdropClick() {
|
|
529
|
+
this.sidebarState.set('hidden');
|
|
530
|
+
}
|
|
531
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AfAppShellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
532
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.2", type: AfAppShellComponent, isStandalone: true, selector: "af-app-shell", inputs: { sidebarState: { classPropertyName: "sidebarState", publicName: "sidebarState", isSignal: true, isRequired: false, transformFunction: null }, panelState: { classPropertyName: "panelState", publicName: "panelState", isSignal: true, isRequired: false, transformFunction: null }, noSidebar: { classPropertyName: "noSidebar", publicName: "noSidebar", isSignal: true, isRequired: false, transformFunction: null }, sidebarRight: { classPropertyName: "sidebarRight", publicName: "sidebarRight", isSignal: true, isRequired: false, transformFunction: null }, sidebarFullHeight: { classPropertyName: "sidebarFullHeight", publicName: "sidebarFullHeight", isSignal: true, isRequired: false, transformFunction: null }, footerSticky: { classPropertyName: "footerSticky", publicName: "footerSticky", isSignal: true, isRequired: false, transformFunction: null }, bottomNav: { classPropertyName: "bottomNav", publicName: "bottomNav", isSignal: true, isRequired: false, transformFunction: null }, sidebarLabel: { classPropertyName: "sidebarLabel", publicName: "sidebarLabel", isSignal: true, isRequired: false, transformFunction: null }, panelLabel: { classPropertyName: "panelLabel", publicName: "panelLabel", isSignal: true, isRequired: false, transformFunction: null }, mainId: { classPropertyName: "mainId", publicName: "mainId", isSignal: true, isRequired: false, transformFunction: null }, skipLinkLabel: { classPropertyName: "skipLinkLabel", publicName: "skipLinkLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sidebarState: "sidebarStateChange", panelState: "panelStateChange" }, ngImport: i0, template: `
|
|
533
|
+
<div
|
|
534
|
+
[class]="shellClasses()"
|
|
535
|
+
[attr.data-sidebar-state]="sidebarState()"
|
|
536
|
+
[attr.data-panel-state]="panelState()">
|
|
537
|
+
<af-skip-link [target]="mainId()" [label]="skipLinkLabel()" />
|
|
538
|
+
|
|
539
|
+
<header class="ct-app-shell__header">
|
|
540
|
+
<ng-content select="[header]" />
|
|
541
|
+
</header>
|
|
542
|
+
|
|
543
|
+
<aside class="ct-app-shell__sidebar" [attr.aria-label]="sidebarLabel()">
|
|
544
|
+
<ng-content select="[sidebar]" />
|
|
545
|
+
</aside>
|
|
546
|
+
|
|
547
|
+
<main class="ct-app-shell__main" [id]="mainId()" tabindex="0">
|
|
548
|
+
<ng-content />
|
|
549
|
+
</main>
|
|
550
|
+
|
|
551
|
+
<aside class="ct-app-shell__panel" [attr.aria-label]="panelLabel()">
|
|
552
|
+
<ng-content select="[panel]" />
|
|
553
|
+
</aside>
|
|
554
|
+
|
|
555
|
+
<footer class="ct-app-shell__footer">
|
|
556
|
+
<ng-content select="[footer]" />
|
|
557
|
+
</footer>
|
|
558
|
+
|
|
559
|
+
<div class="ct-app-shell__bottom-nav">
|
|
560
|
+
<ng-content select="[bottomNav]" />
|
|
561
|
+
</div>
|
|
562
|
+
|
|
563
|
+
<div
|
|
564
|
+
class="ct-app-shell__backdrop"
|
|
565
|
+
(click)="onBackdropClick()"
|
|
566
|
+
aria-hidden="true"></div>
|
|
567
|
+
</div>
|
|
568
|
+
`, isInline: true, styles: [":host{display:contents}\n"], dependencies: [{ kind: "component", type: AfSkipLinkComponent, selector: "af-skip-link", inputs: ["target", "label"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
569
|
+
}
|
|
570
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AfAppShellComponent, decorators: [{
|
|
571
|
+
type: Component,
|
|
572
|
+
args: [{ selector: 'af-app-shell', changeDetection: ChangeDetectionStrategy.OnPush, imports: [AfSkipLinkComponent], template: `
|
|
573
|
+
<div
|
|
574
|
+
[class]="shellClasses()"
|
|
575
|
+
[attr.data-sidebar-state]="sidebarState()"
|
|
576
|
+
[attr.data-panel-state]="panelState()">
|
|
577
|
+
<af-skip-link [target]="mainId()" [label]="skipLinkLabel()" />
|
|
578
|
+
|
|
579
|
+
<header class="ct-app-shell__header">
|
|
580
|
+
<ng-content select="[header]" />
|
|
581
|
+
</header>
|
|
582
|
+
|
|
583
|
+
<aside class="ct-app-shell__sidebar" [attr.aria-label]="sidebarLabel()">
|
|
584
|
+
<ng-content select="[sidebar]" />
|
|
585
|
+
</aside>
|
|
586
|
+
|
|
587
|
+
<main class="ct-app-shell__main" [id]="mainId()" tabindex="0">
|
|
588
|
+
<ng-content />
|
|
589
|
+
</main>
|
|
590
|
+
|
|
591
|
+
<aside class="ct-app-shell__panel" [attr.aria-label]="panelLabel()">
|
|
592
|
+
<ng-content select="[panel]" />
|
|
593
|
+
</aside>
|
|
594
|
+
|
|
595
|
+
<footer class="ct-app-shell__footer">
|
|
596
|
+
<ng-content select="[footer]" />
|
|
597
|
+
</footer>
|
|
598
|
+
|
|
599
|
+
<div class="ct-app-shell__bottom-nav">
|
|
600
|
+
<ng-content select="[bottomNav]" />
|
|
601
|
+
</div>
|
|
602
|
+
|
|
603
|
+
<div
|
|
604
|
+
class="ct-app-shell__backdrop"
|
|
605
|
+
(click)="onBackdropClick()"
|
|
606
|
+
aria-hidden="true"></div>
|
|
607
|
+
</div>
|
|
608
|
+
`, styles: [":host{display:contents}\n"] }]
|
|
609
|
+
}], propDecorators: { sidebarState: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarState", required: false }] }, { type: i0.Output, args: ["sidebarStateChange"] }], panelState: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelState", required: false }] }, { type: i0.Output, args: ["panelStateChange"] }], noSidebar: [{ type: i0.Input, args: [{ isSignal: true, alias: "noSidebar", required: false }] }], sidebarRight: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarRight", required: false }] }], sidebarFullHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarFullHeight", required: false }] }], footerSticky: [{ type: i0.Input, args: [{ isSignal: true, alias: "footerSticky", required: false }] }], bottomNav: [{ type: i0.Input, args: [{ isSignal: true, alias: "bottomNav", required: false }] }], sidebarLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarLabel", required: false }] }], panelLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelLabel", required: false }] }], mainId: [{ type: i0.Input, args: [{ isSignal: true, alias: "mainId", required: false }] }], skipLinkLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "skipLinkLabel", required: false }] }] } });
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* Toolbar rendered inside the main content area of an App Shell V2.
|
|
613
|
+
*
|
|
614
|
+
* Replaces the classic full-width page header with a toolbar row
|
|
615
|
+
* for breadcrumbs, page title, and actions. Place inside
|
|
616
|
+
* `<af-app-shell-v2>` without any slot attribute so it projects
|
|
617
|
+
* into the main area.
|
|
618
|
+
*
|
|
619
|
+
* @example
|
|
620
|
+
* <af-app-shell-v2>
|
|
621
|
+
* <af-app-shell-v2-toolbar sticky>
|
|
622
|
+
* <nav aria-label="Breadcrumb">Home / Dashboard</nav>
|
|
623
|
+
* <div>
|
|
624
|
+
* <button class="ct-button">Export</button>
|
|
625
|
+
* </div>
|
|
626
|
+
* </af-app-shell-v2-toolbar>
|
|
627
|
+
* <p>Main content…</p>
|
|
628
|
+
* </af-app-shell-v2>
|
|
629
|
+
*/
|
|
630
|
+
class AfAppShellV2ToolbarComponent {
|
|
631
|
+
/** Pin the toolbar to the top of the scrollable main area. */
|
|
632
|
+
sticky = input(false, { ...(ngDevMode ? { debugName: "sticky" } : {}), transform: booleanAttribute });
|
|
633
|
+
classes = computed(() => {
|
|
634
|
+
const c = ['ct-app-shell-v2__toolbar'];
|
|
635
|
+
if (this.sticky()) {
|
|
636
|
+
c.push('ct-app-shell-v2__toolbar--sticky');
|
|
637
|
+
}
|
|
638
|
+
return c.join(' ');
|
|
639
|
+
}, ...(ngDevMode ? [{ debugName: "classes" }] : []));
|
|
640
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AfAppShellV2ToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
641
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.2", type: AfAppShellV2ToolbarComponent, isStandalone: true, selector: "af-app-shell-v2-toolbar", inputs: { sticky: { classPropertyName: "sticky", publicName: "sticky", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
642
|
+
<div [class]="classes()">
|
|
643
|
+
<ng-content />
|
|
644
|
+
</div>
|
|
645
|
+
`, isInline: true, styles: [":host{display:contents}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
646
|
+
}
|
|
647
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AfAppShellV2ToolbarComponent, decorators: [{
|
|
648
|
+
type: Component,
|
|
649
|
+
args: [{ selector: 'af-app-shell-v2-toolbar', changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
650
|
+
<div [class]="classes()">
|
|
651
|
+
<ng-content />
|
|
652
|
+
</div>
|
|
653
|
+
`, styles: [":host{display:contents}\n"] }]
|
|
654
|
+
}], propDecorators: { sticky: [{ type: i0.Input, args: [{ isSignal: true, alias: "sticky", required: false }] }] } });
|
|
655
|
+
/**
|
|
656
|
+
* Floating-canvas App Shell with elevated surfaces, rounded corners,
|
|
657
|
+
* and optional glass/branded modifiers.
|
|
658
|
+
*
|
|
659
|
+
* Wraps the `ct-app-shell-v2` CSS component from the Construct Design System.
|
|
660
|
+
* Sidebar and panel states are two-way bindable via `model()` signals.
|
|
661
|
+
*
|
|
662
|
+
* Content projection slots:
|
|
663
|
+
* - `[header]` — Optional floating header bar (requires `withHeader` input)
|
|
664
|
+
* - `[sidebar]` — Floating sidebar surface
|
|
665
|
+
* - `[panel]` — Right-side contextual panel (inside body flex container)
|
|
666
|
+
* - `[footer]` — Footer inside the main area
|
|
667
|
+
* - *(default)* — Main content (including `<af-app-shell-v2-toolbar>`)
|
|
668
|
+
*
|
|
669
|
+
* @example
|
|
670
|
+
* <af-app-shell-v2
|
|
671
|
+
* [(sidebarState)]="sidebarState"
|
|
672
|
+
* [(panelState)]="panelState"
|
|
673
|
+
* withHeader
|
|
674
|
+
* sidebarBranded
|
|
675
|
+
* glass>
|
|
676
|
+
* <af-navbar header ariaLabel="Main">…</af-navbar>
|
|
677
|
+
* <af-sidebar sidebar ariaLabel="Navigation">…</af-sidebar>
|
|
678
|
+
* <af-app-shell-v2-toolbar sticky>
|
|
679
|
+
* <h1>Dashboard</h1>
|
|
680
|
+
* </af-app-shell-v2-toolbar>
|
|
681
|
+
* <p>Content goes here</p>
|
|
682
|
+
* <div panel>Inspector</div>
|
|
683
|
+
* <footer footer>© 2026</footer>
|
|
684
|
+
* </af-app-shell-v2>
|
|
685
|
+
*/
|
|
686
|
+
class AfAppShellV2Component {
|
|
687
|
+
/** Current sidebar state — two-way bindable. */
|
|
688
|
+
sidebarState = model('expanded', ...(ngDevMode ? [{ debugName: "sidebarState" }] : []));
|
|
689
|
+
/** Current panel state — two-way bindable. */
|
|
690
|
+
panelState = model('closed', ...(ngDevMode ? [{ debugName: "panelState" }] : []));
|
|
691
|
+
/** Remove the sidebar entirely. */
|
|
692
|
+
noSidebar = input(false, { ...(ngDevMode ? { debugName: "noSidebar" } : {}), transform: booleanAttribute });
|
|
693
|
+
/** Place the sidebar on the right side. */
|
|
694
|
+
sidebarRight = input(false, { ...(ngDevMode ? { debugName: "sidebarRight" } : {}), transform: booleanAttribute });
|
|
695
|
+
/** Sidebar spans the full viewport height (header sits beside it). */
|
|
696
|
+
sidebarFullHeight = input(false, { ...(ngDevMode ? { debugName: "sidebarFullHeight" } : {}), transform: booleanAttribute });
|
|
697
|
+
/** Show the optional floating header bar. */
|
|
698
|
+
withHeader = input(false, { ...(ngDevMode ? { debugName: "withHeader" } : {}), transform: booleanAttribute });
|
|
699
|
+
/** Dark-branded sidebar (Slack / Linear / Discord aesthetic). */
|
|
700
|
+
sidebarBranded = input(false, { ...(ngDevMode ? { debugName: "sidebarBranded" } : {}), transform: booleanAttribute });
|
|
701
|
+
/** Frosted glass morphism effect on all floating surfaces. */
|
|
702
|
+
glass = input(false, { ...(ngDevMode ? { debugName: "glass" } : {}), transform: booleanAttribute });
|
|
703
|
+
/** Accessible label for the sidebar landmark. */
|
|
704
|
+
sidebarLabel = input('Site navigation', ...(ngDevMode ? [{ debugName: "sidebarLabel" }] : []));
|
|
705
|
+
/** Accessible label for the panel landmark. */
|
|
706
|
+
panelLabel = input('Details', ...(ngDevMode ? [{ debugName: "panelLabel" }] : []));
|
|
707
|
+
/** ID of the main content element (used by skip-link). */
|
|
708
|
+
mainId = input('main-content', ...(ngDevMode ? [{ debugName: "mainId" }] : []));
|
|
709
|
+
/** Visible text of the skip-link. */
|
|
710
|
+
skipLinkLabel = input('Skip to content', ...(ngDevMode ? [{ debugName: "skipLinkLabel" }] : []));
|
|
711
|
+
shellClasses = computed(() => {
|
|
712
|
+
const classes = ['ct-app-shell-v2'];
|
|
713
|
+
if (this.noSidebar()) {
|
|
714
|
+
classes.push('ct-app-shell-v2--no-sidebar');
|
|
715
|
+
}
|
|
716
|
+
if (this.sidebarRight()) {
|
|
717
|
+
classes.push('ct-app-shell-v2--sidebar-right');
|
|
718
|
+
}
|
|
719
|
+
if (this.sidebarFullHeight()) {
|
|
720
|
+
classes.push('ct-app-shell-v2--sidebar-full-height');
|
|
721
|
+
}
|
|
722
|
+
if (this.withHeader()) {
|
|
723
|
+
classes.push('ct-app-shell-v2--with-header');
|
|
724
|
+
}
|
|
725
|
+
if (this.sidebarBranded()) {
|
|
726
|
+
classes.push('ct-app-shell-v2--sidebar-branded');
|
|
727
|
+
}
|
|
728
|
+
if (this.glass()) {
|
|
729
|
+
classes.push('ct-app-shell-v2--glass');
|
|
730
|
+
}
|
|
731
|
+
return classes.join(' ');
|
|
732
|
+
}, ...(ngDevMode ? [{ debugName: "shellClasses" }] : []));
|
|
733
|
+
/** Dismiss the mobile sidebar overlay. */
|
|
734
|
+
onBackdropClick() {
|
|
735
|
+
this.sidebarState.set('hidden');
|
|
736
|
+
}
|
|
737
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AfAppShellV2Component, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
738
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: AfAppShellV2Component, isStandalone: true, selector: "af-app-shell-v2", inputs: { sidebarState: { classPropertyName: "sidebarState", publicName: "sidebarState", isSignal: true, isRequired: false, transformFunction: null }, panelState: { classPropertyName: "panelState", publicName: "panelState", isSignal: true, isRequired: false, transformFunction: null }, noSidebar: { classPropertyName: "noSidebar", publicName: "noSidebar", isSignal: true, isRequired: false, transformFunction: null }, sidebarRight: { classPropertyName: "sidebarRight", publicName: "sidebarRight", isSignal: true, isRequired: false, transformFunction: null }, sidebarFullHeight: { classPropertyName: "sidebarFullHeight", publicName: "sidebarFullHeight", isSignal: true, isRequired: false, transformFunction: null }, withHeader: { classPropertyName: "withHeader", publicName: "withHeader", isSignal: true, isRequired: false, transformFunction: null }, sidebarBranded: { classPropertyName: "sidebarBranded", publicName: "sidebarBranded", isSignal: true, isRequired: false, transformFunction: null }, glass: { classPropertyName: "glass", publicName: "glass", isSignal: true, isRequired: false, transformFunction: null }, sidebarLabel: { classPropertyName: "sidebarLabel", publicName: "sidebarLabel", isSignal: true, isRequired: false, transformFunction: null }, panelLabel: { classPropertyName: "panelLabel", publicName: "panelLabel", isSignal: true, isRequired: false, transformFunction: null }, mainId: { classPropertyName: "mainId", publicName: "mainId", isSignal: true, isRequired: false, transformFunction: null }, skipLinkLabel: { classPropertyName: "skipLinkLabel", publicName: "skipLinkLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sidebarState: "sidebarStateChange", panelState: "panelStateChange" }, ngImport: i0, template: `
|
|
739
|
+
<div
|
|
740
|
+
[class]="shellClasses()"
|
|
741
|
+
[attr.data-sidebar-state]="sidebarState()"
|
|
742
|
+
[attr.data-panel-state]="panelState()">
|
|
743
|
+
<af-skip-link [target]="mainId()" [label]="skipLinkLabel()" />
|
|
744
|
+
|
|
745
|
+
@if (withHeader()) {
|
|
746
|
+
<header class="ct-app-shell-v2__header">
|
|
747
|
+
<ng-content select="[header]" />
|
|
748
|
+
</header>
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
<aside class="ct-app-shell-v2__sidebar" [attr.aria-label]="sidebarLabel()">
|
|
752
|
+
<ng-content select="[sidebar]" />
|
|
753
|
+
</aside>
|
|
754
|
+
|
|
755
|
+
<div class="ct-app-shell-v2__body">
|
|
756
|
+
<main class="ct-app-shell-v2__main" [id]="mainId()" tabindex="0">
|
|
757
|
+
<ng-content />
|
|
758
|
+
<div class="ct-app-shell-v2__footer">
|
|
759
|
+
<ng-content select="[footer]" />
|
|
760
|
+
</div>
|
|
761
|
+
</main>
|
|
762
|
+
|
|
763
|
+
<aside class="ct-app-shell-v2__panel" [attr.aria-label]="panelLabel()">
|
|
764
|
+
<ng-content select="[panel]" />
|
|
765
|
+
</aside>
|
|
766
|
+
</div>
|
|
767
|
+
|
|
768
|
+
<div
|
|
769
|
+
class="ct-app-shell-v2__backdrop"
|
|
770
|
+
(click)="onBackdropClick()"
|
|
771
|
+
aria-hidden="true"></div>
|
|
772
|
+
</div>
|
|
773
|
+
`, isInline: true, styles: [":host{display:contents}\n"], dependencies: [{ kind: "component", type: AfSkipLinkComponent, selector: "af-skip-link", inputs: ["target", "label"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
774
|
+
}
|
|
775
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AfAppShellV2Component, decorators: [{
|
|
776
|
+
type: Component,
|
|
777
|
+
args: [{ selector: 'af-app-shell-v2', changeDetection: ChangeDetectionStrategy.OnPush, imports: [AfSkipLinkComponent], template: `
|
|
778
|
+
<div
|
|
779
|
+
[class]="shellClasses()"
|
|
780
|
+
[attr.data-sidebar-state]="sidebarState()"
|
|
781
|
+
[attr.data-panel-state]="panelState()">
|
|
782
|
+
<af-skip-link [target]="mainId()" [label]="skipLinkLabel()" />
|
|
783
|
+
|
|
784
|
+
@if (withHeader()) {
|
|
785
|
+
<header class="ct-app-shell-v2__header">
|
|
786
|
+
<ng-content select="[header]" />
|
|
787
|
+
</header>
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
<aside class="ct-app-shell-v2__sidebar" [attr.aria-label]="sidebarLabel()">
|
|
791
|
+
<ng-content select="[sidebar]" />
|
|
792
|
+
</aside>
|
|
793
|
+
|
|
794
|
+
<div class="ct-app-shell-v2__body">
|
|
795
|
+
<main class="ct-app-shell-v2__main" [id]="mainId()" tabindex="0">
|
|
796
|
+
<ng-content />
|
|
797
|
+
<div class="ct-app-shell-v2__footer">
|
|
798
|
+
<ng-content select="[footer]" />
|
|
799
|
+
</div>
|
|
800
|
+
</main>
|
|
801
|
+
|
|
802
|
+
<aside class="ct-app-shell-v2__panel" [attr.aria-label]="panelLabel()">
|
|
803
|
+
<ng-content select="[panel]" />
|
|
804
|
+
</aside>
|
|
805
|
+
</div>
|
|
806
|
+
|
|
807
|
+
<div
|
|
808
|
+
class="ct-app-shell-v2__backdrop"
|
|
809
|
+
(click)="onBackdropClick()"
|
|
810
|
+
aria-hidden="true"></div>
|
|
811
|
+
</div>
|
|
812
|
+
`, styles: [":host{display:contents}\n"] }]
|
|
813
|
+
}], propDecorators: { sidebarState: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarState", required: false }] }, { type: i0.Output, args: ["sidebarStateChange"] }], panelState: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelState", required: false }] }, { type: i0.Output, args: ["panelStateChange"] }], noSidebar: [{ type: i0.Input, args: [{ isSignal: true, alias: "noSidebar", required: false }] }], sidebarRight: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarRight", required: false }] }], sidebarFullHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarFullHeight", required: false }] }], withHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "withHeader", required: false }] }], sidebarBranded: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarBranded", required: false }] }], glass: [{ type: i0.Input, args: [{ isSignal: true, alias: "glass", required: false }] }], sidebarLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarLabel", required: false }] }], panelLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelLabel", required: false }] }], mainId: [{ type: i0.Input, args: [{ isSignal: true, alias: "mainId", required: false }] }], skipLinkLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "skipLinkLabel", required: false }] }] } });
|
|
814
|
+
|
|
357
815
|
/**
|
|
358
816
|
* Avatar component displaying a user image with fallback to initials.
|
|
359
817
|
*
|
|
@@ -2526,6 +2984,10 @@ class AfDropdownComponent {
|
|
|
2526
2984
|
label = input('Actions', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
2527
2985
|
/** Trigger button size. */
|
|
2528
2986
|
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
|
|
2987
|
+
/** Horizontal alignment of the menu relative to the trigger. */
|
|
2988
|
+
align = input('start', ...(ngDevMode ? [{ debugName: "align" }] : []));
|
|
2989
|
+
/** Which side of the trigger the menu opens on. */
|
|
2990
|
+
side = input('bottom', ...(ngDevMode ? [{ debugName: "side" }] : []));
|
|
2529
2991
|
/** Menu items. */
|
|
2530
2992
|
items = input([], ...(ngDevMode ? [{ debugName: "items" }] : []));
|
|
2531
2993
|
/** Emits the selected item's value. */
|
|
@@ -2712,8 +3174,8 @@ class AfDropdownComponent {
|
|
|
2712
3174
|
}
|
|
2713
3175
|
}
|
|
2714
3176
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AfDropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2715
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: AfDropdownComponent, isStandalone: true, selector: "af-dropdown", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemSelected: "itemSelected" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, viewQueries: [{ propertyName: "triggerRef", first: true, predicate: ["trigger"], descendants: true, isSignal: true }, { propertyName: "menuRef", first: true, predicate: ["menu"], descendants: true, isSignal: true }, { propertyName: "itemButtons", predicate: ["itemButton"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
2716
|
-
<div class="ct-dropdown" [attr.data-state]="isOpen() ? 'open' : 'closed'">
|
|
3177
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: AfDropdownComponent, isStandalone: true, selector: "af-dropdown", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, side: { classPropertyName: "side", publicName: "side", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemSelected: "itemSelected" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, viewQueries: [{ propertyName: "triggerRef", first: true, predicate: ["trigger"], descendants: true, isSignal: true }, { propertyName: "menuRef", first: true, predicate: ["menu"], descendants: true, isSignal: true }, { propertyName: "itemButtons", predicate: ["itemButton"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
3178
|
+
<div class="ct-dropdown" [attr.data-state]="isOpen() ? 'open' : 'closed'" [attr.data-align]="align()" [attr.data-side]="side()">
|
|
2717
3179
|
<button
|
|
2718
3180
|
#trigger
|
|
2719
3181
|
[id]="triggerId"
|
|
@@ -2761,7 +3223,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
|
|
|
2761
3223
|
args: [{ selector: 'af-dropdown', changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
2762
3224
|
'(document:click)': 'onDocumentClick($event)',
|
|
2763
3225
|
}, template: `
|
|
2764
|
-
<div class="ct-dropdown" [attr.data-state]="isOpen() ? 'open' : 'closed'">
|
|
3226
|
+
<div class="ct-dropdown" [attr.data-state]="isOpen() ? 'open' : 'closed'" [attr.data-align]="align()" [attr.data-side]="side()">
|
|
2765
3227
|
<button
|
|
2766
3228
|
#trigger
|
|
2767
3229
|
[id]="triggerId"
|
|
@@ -2803,7 +3265,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
|
|
|
2803
3265
|
}
|
|
2804
3266
|
</div>
|
|
2805
3267
|
`, styles: [":host{display:inline-block}\n"] }]
|
|
2806
|
-
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], itemSelected: [{ type: i0.Output, args: ["itemSelected"] }], triggerRef: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }], menuRef: [{ type: i0.ViewChild, args: ['menu', { isSignal: true }] }], itemButtons: [{ type: i0.ViewChildren, args: ['itemButton', { isSignal: true }] }] } });
|
|
3268
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], side: [{ type: i0.Input, args: [{ isSignal: true, alias: "side", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], itemSelected: [{ type: i0.Output, args: ["itemSelected"] }], triggerRef: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }], menuRef: [{ type: i0.ViewChild, args: ['menu', { isSignal: true }] }], itemButtons: [{ type: i0.ViewChildren, args: ['itemButton', { isSignal: true }] }] } });
|
|
2807
3269
|
|
|
2808
3270
|
/**
|
|
2809
3271
|
* Pagination component
|
|
@@ -6253,6 +6715,10 @@ class AfNavItemComponent {
|
|
|
6253
6715
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AfNavItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6254
6716
|
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: `
|
|
6255
6717
|
<li class="ct-navbar__item" role="none">
|
|
6718
|
+
<ng-template #contentTpl>
|
|
6719
|
+
<ng-content>{{ label() }}</ng-content>
|
|
6720
|
+
</ng-template>
|
|
6721
|
+
|
|
6256
6722
|
@if (routerLink()) {
|
|
6257
6723
|
<a
|
|
6258
6724
|
#linkEl
|
|
@@ -6263,7 +6729,7 @@ class AfNavItemComponent {
|
|
|
6263
6729
|
[attr.aria-disabled]="disabled() || null"
|
|
6264
6730
|
[attr.tabindex]="rovingTabindex()"
|
|
6265
6731
|
(click)="onClick($event)">
|
|
6266
|
-
<ng-
|
|
6732
|
+
<ng-container [ngTemplateOutlet]="contentTpl" />
|
|
6267
6733
|
</a>
|
|
6268
6734
|
} @else if (href()) {
|
|
6269
6735
|
<a
|
|
@@ -6276,7 +6742,7 @@ class AfNavItemComponent {
|
|
|
6276
6742
|
[attr.aria-disabled]="disabled() || null"
|
|
6277
6743
|
[attr.tabindex]="rovingTabindex()"
|
|
6278
6744
|
(click)="onClick($event)">
|
|
6279
|
-
<ng-
|
|
6745
|
+
<ng-container [ngTemplateOutlet]="contentTpl" />
|
|
6280
6746
|
</a>
|
|
6281
6747
|
} @else {
|
|
6282
6748
|
<button
|
|
@@ -6289,16 +6755,20 @@ class AfNavItemComponent {
|
|
|
6289
6755
|
[attr.aria-disabled]="disabled() || null"
|
|
6290
6756
|
[attr.tabindex]="rovingTabindex()"
|
|
6291
6757
|
(click)="onClick($event)">
|
|
6292
|
-
<ng-
|
|
6758
|
+
<ng-container [ngTemplateOutlet]="contentTpl" />
|
|
6293
6759
|
</button>
|
|
6294
6760
|
}
|
|
6295
6761
|
</li>
|
|
6296
|
-
`, 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 });
|
|
6762
|
+
`, 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"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
6297
6763
|
}
|
|
6298
6764
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AfNavItemComponent, decorators: [{
|
|
6299
6765
|
type: Component,
|
|
6300
|
-
args: [{ selector: 'af-nav-item', changeDetection: ChangeDetectionStrategy.OnPush, imports: [RouterLink, RouterLinkActive], template: `
|
|
6766
|
+
args: [{ selector: 'af-nav-item', changeDetection: ChangeDetectionStrategy.OnPush, imports: [RouterLink, RouterLinkActive, NgTemplateOutlet], template: `
|
|
6301
6767
|
<li class="ct-navbar__item" role="none">
|
|
6768
|
+
<ng-template #contentTpl>
|
|
6769
|
+
<ng-content>{{ label() }}</ng-content>
|
|
6770
|
+
</ng-template>
|
|
6771
|
+
|
|
6302
6772
|
@if (routerLink()) {
|
|
6303
6773
|
<a
|
|
6304
6774
|
#linkEl
|
|
@@ -6309,7 +6779,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
|
|
|
6309
6779
|
[attr.aria-disabled]="disabled() || null"
|
|
6310
6780
|
[attr.tabindex]="rovingTabindex()"
|
|
6311
6781
|
(click)="onClick($event)">
|
|
6312
|
-
<ng-
|
|
6782
|
+
<ng-container [ngTemplateOutlet]="contentTpl" />
|
|
6313
6783
|
</a>
|
|
6314
6784
|
} @else if (href()) {
|
|
6315
6785
|
<a
|
|
@@ -6322,7 +6792,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
|
|
|
6322
6792
|
[attr.aria-disabled]="disabled() || null"
|
|
6323
6793
|
[attr.tabindex]="rovingTabindex()"
|
|
6324
6794
|
(click)="onClick($event)">
|
|
6325
|
-
<ng-
|
|
6795
|
+
<ng-container [ngTemplateOutlet]="contentTpl" />
|
|
6326
6796
|
</a>
|
|
6327
6797
|
} @else {
|
|
6328
6798
|
<button
|
|
@@ -6335,7 +6805,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
|
|
|
6335
6805
|
[attr.aria-disabled]="disabled() || null"
|
|
6336
6806
|
[attr.tabindex]="rovingTabindex()"
|
|
6337
6807
|
(click)="onClick($event)">
|
|
6338
|
-
<ng-
|
|
6808
|
+
<ng-container [ngTemplateOutlet]="contentTpl" />
|
|
6339
6809
|
</button>
|
|
6340
6810
|
}
|
|
6341
6811
|
</li>
|
|
@@ -6537,7 +7007,9 @@ class AfNavbarComponent {
|
|
|
6537
7007
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AfNavbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6538
7008
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: AfNavbarComponent, isStandalone: true, selector: "af-navbar", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, center: { classPropertyName: "center", publicName: "center", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "keydown": "handleKeydown($event)", "document:click": "onDocumentClick($event)" } }, queries: [{ propertyName: "items", predicate: AfNavItemComponent, isSignal: true }], viewQueries: [{ propertyName: "toggleRef", first: true, predicate: ["toggleBtn"], descendants: true, isSignal: true }, { propertyName: "mobileLinks", predicate: ["mobileLink"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
6539
7009
|
<header [class]="navbarClasses()">
|
|
6540
|
-
<
|
|
7010
|
+
<div class="ct-navbar__brand-wrapper">
|
|
7011
|
+
<ng-content select="[brand]" />
|
|
7012
|
+
</div>
|
|
6541
7013
|
|
|
6542
7014
|
<button
|
|
6543
7015
|
#toggleBtn
|
|
@@ -6622,7 +7094,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
|
|
|
6622
7094
|
'(document:click)': 'onDocumentClick($event)',
|
|
6623
7095
|
}, template: `
|
|
6624
7096
|
<header [class]="navbarClasses()">
|
|
6625
|
-
<
|
|
7097
|
+
<div class="ct-navbar__brand-wrapper">
|
|
7098
|
+
<ng-content select="[brand]" />
|
|
7099
|
+
</div>
|
|
6626
7100
|
|
|
6627
7101
|
<button
|
|
6628
7102
|
#toggleBtn
|
|
@@ -7117,65 +7591,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
|
|
|
7117
7591
|
`, styles: [":host{display:contents}\n"] }]
|
|
7118
7592
|
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], dismissible: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissible", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], full: [{ type: i0.Input, args: [{ isSignal: true, alias: "full", required: false }] }], autoClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoClose", required: false }] }], closeAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeAriaLabel", required: false }] }], dismissed: [{ type: i0.Output, args: ["dismissed"] }] } });
|
|
7119
7593
|
|
|
7120
|
-
/**
|
|
7121
|
-
* Skip-link component for keyboard-only navigation bypass.
|
|
7122
|
-
*
|
|
7123
|
-
* Renders an anchor that is visually hidden off-screen and slides into view
|
|
7124
|
-
* when focused. On activation it moves focus to the target element, allowing
|
|
7125
|
-
* keyboard users to skip repetitive navigation blocks.
|
|
7126
|
-
*
|
|
7127
|
-
* Must be placed as the first focusable element in the document.
|
|
7128
|
-
*
|
|
7129
|
-
* @example
|
|
7130
|
-
* <af-skip-link target="main-content" />
|
|
7131
|
-
* <nav>…</nav>
|
|
7132
|
-
* <main id="main-content" tabindex="-1">…</main>
|
|
7133
|
-
*/
|
|
7134
|
-
class AfSkipLinkComponent {
|
|
7135
|
-
/** ID of the element to skip to (without the leading `#`). */
|
|
7136
|
-
target = input.required(...(ngDevMode ? [{ debugName: "target" }] : []));
|
|
7137
|
-
/** Visible label text shown when the link receives focus. */
|
|
7138
|
-
label = input('Skip to main content', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
7139
|
-
document = inject(DOCUMENT);
|
|
7140
|
-
/**
|
|
7141
|
-
* Moves focus to the target element so keyboard navigation
|
|
7142
|
-
* continues from there instead of the top of the page.
|
|
7143
|
-
*/
|
|
7144
|
-
focusTarget(event) {
|
|
7145
|
-
event.preventDefault();
|
|
7146
|
-
const el = this.document.getElementById(this.target());
|
|
7147
|
-
if (!el) {
|
|
7148
|
-
return;
|
|
7149
|
-
}
|
|
7150
|
-
if (!el.hasAttribute('tabindex')) {
|
|
7151
|
-
el.setAttribute('tabindex', '-1');
|
|
7152
|
-
}
|
|
7153
|
-
el.focus();
|
|
7154
|
-
}
|
|
7155
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AfSkipLinkComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7156
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.2", type: AfSkipLinkComponent, isStandalone: true, selector: "af-skip-link", inputs: { target: { classPropertyName: "target", publicName: "target", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
7157
|
-
<a
|
|
7158
|
-
class="ct-skip-link"
|
|
7159
|
-
[attr.href]="'#' + target()"
|
|
7160
|
-
(click)="focusTarget($event)"
|
|
7161
|
-
>
|
|
7162
|
-
{{ label() }}
|
|
7163
|
-
</a>
|
|
7164
|
-
`, isInline: true, styles: [":host{display:contents}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
7165
|
-
}
|
|
7166
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AfSkipLinkComponent, decorators: [{
|
|
7167
|
-
type: Component,
|
|
7168
|
-
args: [{ selector: 'af-skip-link', changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
7169
|
-
<a
|
|
7170
|
-
class="ct-skip-link"
|
|
7171
|
-
[attr.href]="'#' + target()"
|
|
7172
|
-
(click)="focusTarget($event)"
|
|
7173
|
-
>
|
|
7174
|
-
{{ label() }}
|
|
7175
|
-
</a>
|
|
7176
|
-
`, styles: [":host{display:contents}\n"] }]
|
|
7177
|
-
}], propDecorators: { target: [{ type: i0.Input, args: [{ isSignal: true, alias: "target", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }] } });
|
|
7178
|
-
|
|
7179
7594
|
/**
|
|
7180
7595
|
* Empty state component for displaying placeholder content when no data is available.
|
|
7181
7596
|
*
|
|
@@ -7738,5 +8153,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
|
|
|
7738
8153
|
* Generated bundle index. Do not edit.
|
|
7739
8154
|
*/
|
|
7740
8155
|
|
|
7741
|
-
export { AfAccordionComponent, AfAccordionItemComponent, AfAlertComponent, AfAvatarComponent, AfBadgeComponent, AfBannerComponent, AfBreadcrumbsComponent, AfButtonComponent, AfCardComponent, AfCellDefDirective, AfCheckboxComponent, AfChipInputComponent, AfComboboxComponent, AfDataTableComponent, AfDatepickerComponent, AfDividerComponent, AfDrawerComponent, AfDropdownComponent, AfEmptyStateComponent, AfFieldComponent, AfFileUploadComponent, AfFormatLabelPipe, AfIconComponent, AfInputComponent, AfModalComponent, AfNavItemComponent, AfNavbarComponent, AfPaginationComponent, AfPopoverComponent, AfPopoverTriggerDirective, AfProgressBarComponent, AfRadioComponent, AfRadioGroupComponent, AfSelectComponent, AfSelectMenuComponent, AfSidebarComponent, AfSkeletonComponent, AfSkipLinkComponent, AfSliderComponent, AfSpinnerComponent, AfSwitchComponent, AfTabPanelComponent, AfTableBodyComponent, AfTableCellComponent, AfTableComponent, AfTableHeaderCellComponent, AfTableHeaderComponent, AfTableRowComponent, AfTabsComponent, AfTextareaComponent, AfToastContainerComponent, AfToastService, AfToggleGroupComponent, AfToolbarComponent, AfTooltipDirective };
|
|
8156
|
+
export { AfAccordionComponent, AfAccordionItemComponent, AfAlertComponent, AfAppShellComponent, AfAppShellPageHeaderComponent, AfAppShellV2Component, AfAppShellV2ToolbarComponent, AfAvatarComponent, AfBadgeComponent, AfBannerComponent, AfBreadcrumbsComponent, AfButtonComponent, AfCardComponent, AfCellDefDirective, AfCheckboxComponent, AfChipInputComponent, AfComboboxComponent, AfDataTableComponent, AfDatepickerComponent, AfDividerComponent, AfDrawerComponent, AfDropdownComponent, AfEmptyStateComponent, AfFieldComponent, AfFileUploadComponent, AfFormatLabelPipe, AfIconComponent, AfInputComponent, AfModalComponent, AfNavItemComponent, AfNavbarComponent, AfPaginationComponent, AfPopoverComponent, AfPopoverTriggerDirective, AfProgressBarComponent, AfRadioComponent, AfRadioGroupComponent, AfSelectComponent, AfSelectMenuComponent, AfSidebarComponent, AfSkeletonComponent, AfSkipLinkComponent, AfSliderComponent, AfSpinnerComponent, AfSwitchComponent, AfTabPanelComponent, AfTableBodyComponent, AfTableCellComponent, AfTableComponent, AfTableHeaderCellComponent, AfTableHeaderComponent, AfTableRowComponent, AfTabsComponent, AfTextareaComponent, AfToastContainerComponent, AfToastService, AfToggleGroupComponent, AfToolbarComponent, AfTooltipDirective };
|
|
7742
8157
|
//# sourceMappingURL=neuravision-ng-construct.mjs.map
|