@truenas/ui-components 0.1.26 → 0.1.28

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,24 +1,24 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, ElementRef, input, output, viewChild, signal, computed, effect, forwardRef, Component, ChangeDetectionStrategy, Injectable, ViewEncapsulation, Directive, contentChildren, ViewContainerRef, contentChild, ChangeDetectorRef, HostListener, TemplateRef, IterableDiffers, Pipe, model, afterNextRender, PLATFORM_ID, DestroyRef } from '@angular/core';
3
- import * as i1$3 from '@angular/forms';
2
+ import { inject, ElementRef, input, output, viewChild, signal, computed, effect, forwardRef, Component, model, afterNextRender, ChangeDetectionStrategy, Injectable, ViewEncapsulation, Directive, contentChildren, ViewContainerRef, contentChild, ChangeDetectorRef, HostListener, TemplateRef, IterableDiffers, Pipe, PLATFORM_ID, DestroyRef } from '@angular/core';
3
+ import * as i1$4 from '@angular/forms';
4
4
  import { NG_VALUE_ACCESSOR, FormsModule, NgControl } from '@angular/forms';
5
5
  import { ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';
6
- import * as i1$1 from '@angular/common';
7
- import { CommonModule, DOCUMENT, isPlatformBrowser } from '@angular/common';
6
+ import * as i1 from '@angular/cdk/a11y';
7
+ import { A11yModule, FocusMonitor } from '@angular/cdk/a11y';
8
+ import * as i1$2 from '@angular/common';
9
+ import { DOCUMENT, NgTemplateOutlet, CommonModule, isPlatformBrowser } from '@angular/common';
8
10
  import { mdiCheckCircle, mdiAlertCircle, mdiAlert, mdiInformation, mdiDotsVertical, mdiClose, mdiFolderOpen, mdiLock, mdiLoading, mdiFolderPlus, mdiFolderNetwork, mdiHarddisk, mdiDatabase, mdiFile, mdiFolder } from '@mdi/js';
9
- import * as i1 from '@angular/platform-browser';
11
+ import * as i1$1 from '@angular/platform-browser';
10
12
  import { DomSanitizer } from '@angular/platform-browser';
11
13
  import { HttpClient } from '@angular/common/http';
12
14
  import { firstValueFrom, BehaviorSubject, merge, Subject } from 'rxjs';
13
- import * as i1$4 from '@angular/cdk/a11y';
14
- import { FocusMonitor, A11yModule } from '@angular/cdk/a11y';
15
15
  import { Overlay, OverlayModule, OverlayPositionBuilder } from '@angular/cdk/overlay';
16
16
  import { TemplatePortal, PortalModule, ComponentPortal } from '@angular/cdk/portal';
17
17
  import { CdkMenu, CdkMenuItem, CdkMenuTrigger } from '@angular/cdk/menu';
18
18
  import { trigger, state, transition, style, animate } from '@angular/animations';
19
19
  import { SPACE, ENTER, END, HOME, DOWN_ARROW, UP_ARROW, RIGHT_ARROW, LEFT_ARROW } from '@angular/cdk/keycodes';
20
20
  import { DataSource } from '@angular/cdk/collections';
21
- import * as i1$2 from '@angular/cdk/tree';
21
+ import * as i1$3 from '@angular/cdk/tree';
22
22
  import { CdkTree, CdkTreeModule, CdkTreeNode, CDK_TREE_NODE_OUTLET_NODE, CdkTreeNodeOutlet, CdkNestedTreeNode } from '@angular/cdk/tree';
23
23
  export { FlatTreeControl } from '@angular/cdk/tree';
24
24
  import { map } from 'rxjs/operators';
@@ -455,6 +455,246 @@ class TnAutocompleteHarness extends ComponentHarness {
455
455
  }
456
456
  }
457
457
 
458
+ class TnDrawerComponent {
459
+ document = inject(DOCUMENT);
460
+ /** Whether the drawer sits alongside content ('side') or overlays it ('over') */
461
+ mode = input('side', ...(ngDevMode ? [{ debugName: "mode" }] : []));
462
+ /** Whether the drawer is open. Two-way bindable via [(opened)] */
463
+ opened = model(false, ...(ngDevMode ? [{ debugName: "opened" }] : []));
464
+ /** Prevent closing via backdrop click or Escape */
465
+ disableClose = input(false, ...(ngDevMode ? [{ debugName: "disableClose" }] : []));
466
+ /** Width of the drawer panel (must be a concrete CSS value for smooth transition) */
467
+ width = input('256px', ...(ngDevMode ? [{ debugName: "width" }] : []));
468
+ /** Which side the drawer appears on */
469
+ position = input('start', ...(ngDevMode ? [{ debugName: "position" }] : []));
470
+ /** Accessible label for the drawer panel */
471
+ ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
472
+ /** Fires after the open transition completes */
473
+ openedComplete = output();
474
+ /** Fires after the close transition completes */
475
+ closed = output();
476
+ /** Whether the component has rendered (prevents transition flash on load) */
477
+ initialized = signal(false, ...(ngDevMode ? [{ debugName: "initialized" }] : []));
478
+ /** Reference to the overlay element (portaled to body in over mode) */
479
+ overlayRef = viewChild('overlay', ...(ngDevMode ? [{ debugName: "overlayRef" }] : []));
480
+ /** Focus trap should be active only in 'over' mode when open */
481
+ trapFocus = computed(() => this.mode() === 'over' && this.opened(), ...(ngDevMode ? [{ debugName: "trapFocus" }] : []));
482
+ /** Role depends on mode: navigation for side, dialog for over */
483
+ panelRole = computed(() => this.mode() === 'over' ? 'dialog' : 'navigation', ...(ngDevMode ? [{ debugName: "panelRole" }] : []));
484
+ /** Whether to show the backdrop */
485
+ showBackdrop = computed(() => this.mode() === 'over', ...(ngDevMode ? [{ debugName: "showBackdrop" }] : []));
486
+ /** CSS classes for the drawer panel */
487
+ drawerClasses = computed(() => {
488
+ const classes = ['tn-drawer__panel'];
489
+ if (this.opened()) {
490
+ classes.push('tn-drawer__panel--open');
491
+ }
492
+ if (this.position() === 'end') {
493
+ classes.push('tn-drawer__panel--end');
494
+ }
495
+ if (this.mode() === 'over') {
496
+ classes.push('tn-drawer__panel--over');
497
+ }
498
+ if (this.initialized()) {
499
+ classes.push('tn-drawer__panel--initialized');
500
+ }
501
+ return classes;
502
+ }, ...(ngDevMode ? [{ debugName: "drawerClasses" }] : []));
503
+ /** Previous focus element for restoration (only captured in over mode) */
504
+ previousFocus = null;
505
+ constructor() {
506
+ // Capture focus before opening in over mode for later restoration
507
+ effect(() => {
508
+ if (this.mode() === 'over' && this.opened()) {
509
+ this.previousFocus = this.document.activeElement;
510
+ }
511
+ });
512
+ // Portal overlay to document.body in over mode to avoid clipping
513
+ afterNextRender(() => {
514
+ this.initialized.set(true);
515
+ const overlay = this.overlayRef()?.nativeElement;
516
+ if (overlay) {
517
+ this.document.body.appendChild(overlay);
518
+ }
519
+ });
520
+ }
521
+ ngOnDestroy() {
522
+ this.overlayRef()?.nativeElement?.remove();
523
+ }
524
+ /** Open the drawer */
525
+ open() {
526
+ this.opened.set(true);
527
+ }
528
+ /** Close the drawer */
529
+ close() {
530
+ if (this.disableClose()) {
531
+ return;
532
+ }
533
+ this.opened.set(false);
534
+ }
535
+ /** Toggle the drawer open/closed */
536
+ toggle() {
537
+ if (this.opened()) {
538
+ this.close();
539
+ }
540
+ else {
541
+ this.open();
542
+ }
543
+ }
544
+ /** Handle backdrop click */
545
+ onBackdropClick() {
546
+ if (!this.disableClose()) {
547
+ this.close();
548
+ }
549
+ }
550
+ /**
551
+ * Handle Escape key in over mode.
552
+ * Side mode drawers are persistent navigation — Escape is not expected
553
+ * to dismiss them. The header toggle button is the intended control.
554
+ */
555
+ onKeydown(event) {
556
+ if (event.key === 'Escape' && this.mode() === 'over' && this.opened() && !this.disableClose()) {
557
+ event.stopPropagation();
558
+ this.close();
559
+ }
560
+ }
561
+ /** Handle transition end — emit events and restore focus after animation completes */
562
+ onTransitionEnd(event) {
563
+ if (event.propertyName !== 'transform' || event.target !== event.currentTarget) {
564
+ return;
565
+ }
566
+ if (this.opened()) {
567
+ this.openedComplete.emit();
568
+ }
569
+ else {
570
+ this.closed.emit();
571
+ this.restoreFocus();
572
+ }
573
+ }
574
+ restoreFocus() {
575
+ if (this.previousFocus?.focus) {
576
+ this.previousFocus.focus();
577
+ this.previousFocus = null;
578
+ }
579
+ }
580
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnDrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
581
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnDrawerComponent, isStandalone: true, selector: "tn-drawer", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, opened: { classPropertyName: "opened", publicName: "opened", isSignal: true, isRequired: false, transformFunction: null }, disableClose: { classPropertyName: "disableClose", publicName: "disableClose", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { opened: "openedChange", openedComplete: "openedComplete", closed: "closed" }, host: { properties: { "class.tn-drawer--open": "opened()", "class.tn-drawer--over": "mode() === \"over\"", "class.tn-drawer--initialized": "initialized()", "style.width": "mode() !== \"over\" && opened() ? width() : null" }, classAttribute: "tn-drawer" }, viewQueries: [{ propertyName: "overlayRef", first: true, predicate: ["overlay"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Capture projected content into a reusable template -->\n<ng-template #drawerContent>\n <ng-content />\n</ng-template>\n\n<!-- Side mode: panel renders inline -->\n@if (mode() !== 'over') {\n <div\n tabindex=\"-1\"\n [class]=\"drawerClasses()\"\n [style.width]=\"width()\"\n [attr.role]=\"panelRole()\"\n [attr.aria-hidden]=\"!opened() ? 'true' : null\"\n [attr.aria-label]=\"ariaLabel()\"\n (transitionend)=\"onTransitionEnd($event)\">\n <ng-container *ngTemplateOutlet=\"drawerContent\" />\n </div>\n}\n\n<!-- Over mode: portaled to document.body to avoid clipping -->\n<div #overlay>\n @if (mode() === 'over') {\n \n <div\n class=\"tn-drawer__backdrop\"\n aria-hidden=\"true\"\n [class.tn-drawer__backdrop--visible]=\"opened()\"\n (click)=\"onBackdropClick()\"></div>\n\n <div\n tabindex=\"-1\"\n [class]=\"drawerClasses()\"\n [style.width]=\"width()\"\n [attr.role]=\"panelRole()\"\n [attr.aria-modal]=\"opened() ? 'true' : null\"\n [attr.aria-hidden]=\"!opened() ? 'true' : null\"\n [attr.aria-label]=\"ariaLabel()\"\n [cdkTrapFocus]=\"trapFocus()\"\n [cdkTrapFocusAutoCapture]=\"trapFocus()\"\n (keydown)=\"onKeydown($event)\"\n (transitionend)=\"onTransitionEnd($event)\">\n <ng-container *ngTemplateOutlet=\"drawerContent\" />\n </div>\n }\n</div>\n", styles: [":host{display:block;position:relative;height:100%;flex-shrink:0;width:0;overflow:hidden}:host.tn-drawer--initialized:not(.tn-drawer--over){transition:width .3s ease}:host.tn-drawer--over{width:0!important;overflow:visible}:host.tn-drawer--open:not(.tn-drawer--over){overflow:visible}.tn-drawer__panel{height:100%;overflow-y:auto;background-color:var(--tn-bg2);z-index:100}.tn-drawer__panel.tn-drawer__panel--initialized{transition:transform .3s ease}.tn-drawer__panel:not(.tn-drawer__panel--over){position:relative;transform:translate(-100%)}.tn-drawer__panel:not(.tn-drawer__panel--over).tn-drawer__panel--open{transform:translate(0)}.tn-drawer__panel:not(.tn-drawer__panel--over).tn-drawer__panel--end{transform:translate(100%)}.tn-drawer__panel:not(.tn-drawer__panel--over).tn-drawer__panel--end.tn-drawer__panel--open{transform:translate(0)}.tn-drawer__panel.tn-drawer__panel--over{position:fixed;top:0;bottom:0;left:0;transform:translate(-100%);z-index:1001}.tn-drawer__panel.tn-drawer__panel--over.tn-drawer__panel--open{transform:translate(0)}.tn-drawer__panel.tn-drawer__panel--over.tn-drawer__panel--end{left:auto;right:0;transform:translate(100%)}.tn-drawer__panel.tn-drawer__panel--over.tn-drawer__panel--end.tn-drawer__panel--open{transform:translate(0)}.tn-drawer__backdrop{position:fixed;inset:0;background-color:#00000080;z-index:1000;opacity:0;pointer-events:none;transition:opacity .3s ease}.tn-drawer__backdrop.tn-drawer__backdrop--visible{opacity:1;pointer-events:auto}@media(prefers-reduced-motion:reduce){:host.tn-drawer--initialized{transition:none}.tn-drawer__panel.tn-drawer__panel--initialized{transition:none}}\n"], dependencies: [{ kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i1.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
582
+ }
583
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnDrawerComponent, decorators: [{
584
+ type: Component,
585
+ args: [{ selector: 'tn-drawer', standalone: true, imports: [A11yModule, NgTemplateOutlet], host: {
586
+ 'class': 'tn-drawer',
587
+ '[class.tn-drawer--open]': 'opened()',
588
+ '[class.tn-drawer--over]': 'mode() === "over"',
589
+ '[class.tn-drawer--initialized]': 'initialized()',
590
+ '[style.width]': 'mode() !== "over" && opened() ? width() : null',
591
+ }, template: "<!-- Capture projected content into a reusable template -->\n<ng-template #drawerContent>\n <ng-content />\n</ng-template>\n\n<!-- Side mode: panel renders inline -->\n@if (mode() !== 'over') {\n <div\n tabindex=\"-1\"\n [class]=\"drawerClasses()\"\n [style.width]=\"width()\"\n [attr.role]=\"panelRole()\"\n [attr.aria-hidden]=\"!opened() ? 'true' : null\"\n [attr.aria-label]=\"ariaLabel()\"\n (transitionend)=\"onTransitionEnd($event)\">\n <ng-container *ngTemplateOutlet=\"drawerContent\" />\n </div>\n}\n\n<!-- Over mode: portaled to document.body to avoid clipping -->\n<div #overlay>\n @if (mode() === 'over') {\n \n <div\n class=\"tn-drawer__backdrop\"\n aria-hidden=\"true\"\n [class.tn-drawer__backdrop--visible]=\"opened()\"\n (click)=\"onBackdropClick()\"></div>\n\n <div\n tabindex=\"-1\"\n [class]=\"drawerClasses()\"\n [style.width]=\"width()\"\n [attr.role]=\"panelRole()\"\n [attr.aria-modal]=\"opened() ? 'true' : null\"\n [attr.aria-hidden]=\"!opened() ? 'true' : null\"\n [attr.aria-label]=\"ariaLabel()\"\n [cdkTrapFocus]=\"trapFocus()\"\n [cdkTrapFocusAutoCapture]=\"trapFocus()\"\n (keydown)=\"onKeydown($event)\"\n (transitionend)=\"onTransitionEnd($event)\">\n <ng-container *ngTemplateOutlet=\"drawerContent\" />\n </div>\n }\n</div>\n", styles: [":host{display:block;position:relative;height:100%;flex-shrink:0;width:0;overflow:hidden}:host.tn-drawer--initialized:not(.tn-drawer--over){transition:width .3s ease}:host.tn-drawer--over{width:0!important;overflow:visible}:host.tn-drawer--open:not(.tn-drawer--over){overflow:visible}.tn-drawer__panel{height:100%;overflow-y:auto;background-color:var(--tn-bg2);z-index:100}.tn-drawer__panel.tn-drawer__panel--initialized{transition:transform .3s ease}.tn-drawer__panel:not(.tn-drawer__panel--over){position:relative;transform:translate(-100%)}.tn-drawer__panel:not(.tn-drawer__panel--over).tn-drawer__panel--open{transform:translate(0)}.tn-drawer__panel:not(.tn-drawer__panel--over).tn-drawer__panel--end{transform:translate(100%)}.tn-drawer__panel:not(.tn-drawer__panel--over).tn-drawer__panel--end.tn-drawer__panel--open{transform:translate(0)}.tn-drawer__panel.tn-drawer__panel--over{position:fixed;top:0;bottom:0;left:0;transform:translate(-100%);z-index:1001}.tn-drawer__panel.tn-drawer__panel--over.tn-drawer__panel--open{transform:translate(0)}.tn-drawer__panel.tn-drawer__panel--over.tn-drawer__panel--end{left:auto;right:0;transform:translate(100%)}.tn-drawer__panel.tn-drawer__panel--over.tn-drawer__panel--end.tn-drawer__panel--open{transform:translate(0)}.tn-drawer__backdrop{position:fixed;inset:0;background-color:#00000080;z-index:1000;opacity:0;pointer-events:none;transition:opacity .3s ease}.tn-drawer__backdrop.tn-drawer__backdrop--visible{opacity:1;pointer-events:auto}@media(prefers-reduced-motion:reduce){:host.tn-drawer--initialized{transition:none}.tn-drawer__panel.tn-drawer__panel--initialized{transition:none}}\n"] }]
592
+ }], ctorParameters: () => [], propDecorators: { mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], opened: [{ type: i0.Input, args: [{ isSignal: true, alias: "opened", required: false }] }, { type: i0.Output, args: ["openedChange"] }], disableClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "disableClose", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], openedComplete: [{ type: i0.Output, args: ["openedComplete"] }], closed: [{ type: i0.Output, args: ["closed"] }], overlayRef: [{ type: i0.ViewChild, args: ['overlay', { isSignal: true }] }] } });
593
+
594
+ class TnDrawerContainerComponent {
595
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnDrawerContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
596
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.0", type: TnDrawerContainerComponent, isStandalone: true, selector: "tn-drawer-container", ngImport: i0, template: '<ng-content />', isInline: true, styles: [":host{display:flex;width:100%;height:100%;overflow:hidden;position:relative}\n"] });
597
+ }
598
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnDrawerContainerComponent, decorators: [{
599
+ type: Component,
600
+ args: [{ selector: 'tn-drawer-container', standalone: true, template: '<ng-content />', styles: [":host{display:flex;width:100%;height:100%;overflow:hidden;position:relative}\n"] }]
601
+ }] });
602
+
603
+ class TnDrawerContentComponent {
604
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnDrawerContentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
605
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.0", type: TnDrawerContentComponent, isStandalone: true, selector: "tn-drawer-content", ngImport: i0, template: '<ng-content />', isInline: true, styles: [":host{display:block;flex:1;min-width:0;overflow:auto;transition:flex .3s ease}@media(prefers-reduced-motion:reduce){:host{transition:none}}\n"] });
606
+ }
607
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnDrawerContentComponent, decorators: [{
608
+ type: Component,
609
+ args: [{ selector: 'tn-drawer-content', standalone: true, template: '<ng-content />', styles: [":host{display:block;flex:1;min-width:0;overflow:auto;transition:flex .3s ease}@media(prefers-reduced-motion:reduce){:host{transition:none}}\n"] }]
610
+ }] });
611
+
612
+ /**
613
+ * Harness for interacting with tn-drawer in tests.
614
+ *
615
+ * @example
616
+ * ```typescript
617
+ * const drawer = await loader.getHarness(TnDrawerHarness);
618
+ * expect(await drawer.isOpen()).toBe(false);
619
+ * ```
620
+ */
621
+ class TnDrawerHarness extends ComponentHarness {
622
+ static hostSelector = 'tn-drawer';
623
+ _inlinePanel = this.locatorForOptional('.tn-drawer__panel');
624
+ /**
625
+ * Checks whether the drawer panel has the open class.
626
+ * Checks both inline (side mode) and portaled (over mode) panels.
627
+ *
628
+ * @returns Promise resolving to true if the drawer is open.
629
+ *
630
+ * @example
631
+ * ```typescript
632
+ * const drawer = await loader.getHarness(TnDrawerHarness);
633
+ * expect(await drawer.isOpen()).toBe(true);
634
+ * ```
635
+ */
636
+ async isOpen() {
637
+ // Check inline panel first (side mode)
638
+ const inlinePanel = await this._inlinePanel();
639
+ if (inlinePanel) {
640
+ return inlinePanel.hasClass('tn-drawer__panel--open');
641
+ }
642
+ // Check portaled panel (over mode)
643
+ const portaledPanel = document.body.querySelector('.tn-drawer__panel--over');
644
+ return portaledPanel?.classList.contains('tn-drawer__panel--open') ?? false;
645
+ }
646
+ /**
647
+ * Checks whether the backdrop overlay is visible.
648
+ *
649
+ * @returns Promise resolving to true if the backdrop is visible.
650
+ *
651
+ * @example
652
+ * ```typescript
653
+ * const drawer = await loader.getHarness(TnDrawerHarness);
654
+ * expect(await drawer.hasBackdrop()).toBe(true);
655
+ * ```
656
+ */
657
+ async hasBackdrop() {
658
+ const backdrop = document.body.querySelector('.tn-drawer__backdrop');
659
+ return backdrop?.classList.contains('tn-drawer__backdrop--visible') ?? false;
660
+ }
661
+ /**
662
+ * Clicks the backdrop to close the drawer (only available in 'over' mode).
663
+ *
664
+ * @example
665
+ * ```typescript
666
+ * const drawer = await loader.getHarness(TnDrawerHarness);
667
+ * await drawer.clickBackdrop();
668
+ * expect(await drawer.isOpen()).toBe(false);
669
+ * ```
670
+ */
671
+ async clickBackdrop() {
672
+ const backdrop = document.body.querySelector('.tn-drawer__backdrop--visible');
673
+ if (!backdrop) {
674
+ throw new Error('No visible backdrop found — drawer may not be in "over" mode or not open.');
675
+ }
676
+ backdrop.click();
677
+ }
678
+ }
679
+ /**
680
+ * Harness for interacting with tn-drawer-container in tests.
681
+ *
682
+ * @example
683
+ * ```typescript
684
+ * const container = await loader.getHarness(TnDrawerContainerHarness);
685
+ * const drawer = await container.getDrawer();
686
+ * ```
687
+ */
688
+ class TnDrawerContainerHarness extends ComponentHarness {
689
+ static hostSelector = 'tn-drawer-container';
690
+ /**
691
+ * Gets the drawer harness within this container.
692
+ */
693
+ async getDrawer() {
694
+ return this.locatorFor(TnDrawerHarness)();
695
+ }
696
+ }
697
+
458
698
  var DiskType;
459
699
  (function (DiskType) {
460
700
  DiskType["Hdd"] = "HDD";
@@ -811,7 +1051,7 @@ class TnIconRegistryService {
811
1051
  content: this.sanitizer.bypassSecurityTrustHtml(svgContent)
812
1052
  };
813
1053
  }
814
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnIconRegistryService, deps: [{ token: i1.DomSanitizer }, { token: TnSpriteLoaderService }], target: i0.ɵɵFactoryTarget.Injectable });
1054
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnIconRegistryService, deps: [{ token: i1$1.DomSanitizer }, { token: TnSpriteLoaderService }], target: i0.ɵɵFactoryTarget.Injectable });
815
1055
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnIconRegistryService, providedIn: 'root' });
816
1056
  }
817
1057
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnIconRegistryService, decorators: [{
@@ -819,7 +1059,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImpor
819
1059
  args: [{
820
1060
  providedIn: 'root'
821
1061
  }]
822
- }], ctorParameters: () => [{ type: i1.DomSanitizer }, { type: TnSpriteLoaderService }] });
1062
+ }], ctorParameters: () => [{ type: i1$1.DomSanitizer }, { type: TnSpriteLoaderService }] });
823
1063
 
824
1064
  class TnIconComponent {
825
1065
  name = input('', ...(ngDevMode ? [{ debugName: "name" }] : []));
@@ -1134,7 +1374,7 @@ class TnBannerComponent {
1134
1374
  ];
1135
1375
  }, ...(ngDevMode ? [{ debugName: "classes" }] : []));
1136
1376
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnBannerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1137
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnBannerComponent, isStandalone: true, selector: "tn-banner", inputs: { heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: true, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "actionContent", predicate: TnBannerActionDirective, isSignal: true }], ngImport: i0, template: "<div\n aria-live=\"polite\"\n [ngClass]=\"classes()\"\n [attr.role]=\"ariaRole()\"\n>\n <div class=\"tn-banner__main\">\n <div class=\"tn-banner__icon\">\n <tn-icon\n library=\"mdi\"\n size=\"md\"\n aria-hidden=\"true\"\n [name]=\"iconName()\"\n />\n </div>\n\n <div class=\"tn-banner__content\">\n <div class=\"tn-banner__heading\">\n {{ heading() }}\n </div>\n\n @if (message()) {\n <div class=\"tn-banner__message\">\n {{ message() }}\n </div>\n }\n </div>\n </div>\n\n @if (hasAction()) {\n <div class=\"tn-banner__action\">\n <ng-content select=\"[tnBannerAction]\" />\n </div>\n }\n</div>\n", styles: [".tn-banner{display:grid;gap:8px;align-items:center;padding:16px;border-radius:6px;border-left:4px solid;transition:opacity .2s ease}@media(prefers-reduced-motion:reduce){.tn-banner{transition:none}}.tn-banner--info{border-left-color:var(--tn-info, #3b82f6);background-color:var(--tn-alt-bg1, #383838)}.tn-banner--info .tn-banner__heading,.tn-banner--info .tn-banner__icon{color:var(--tn-info, #3b82f6)}.tn-banner--warning{border-left-color:var(--tn-warning, #f59e0b);background-color:var(--tn-alt-bg1, #383838)}.tn-banner--warning .tn-banner__heading,.tn-banner--warning .tn-banner__icon{color:var(--tn-warning, #f59e0b)}.tn-banner--error{border-left-color:var(--tn-error, #ef4444);background-color:var(--tn-alt-bg1, #383838)}.tn-banner--error .tn-banner__heading,.tn-banner--error .tn-banner__icon{color:var(--tn-error, #ef4444)}.tn-banner--success{border-left-color:var(--tn-success, #10b981);background-color:var(--tn-alt-bg1, #383838)}.tn-banner--success .tn-banner__heading,.tn-banner--success .tn-banner__icon{color:var(--tn-success, #10b981)}.tn-banner__main{display:flex;align-items:flex-start;gap:12px;flex:1;min-width:0}.tn-banner__icon{flex-shrink:0;display:flex;align-items:center;justify-content:center;margin-top:2px}.tn-banner__content{flex:1;min-width:0}.tn-banner__heading{font-size:1rem;font-weight:600;line-height:1.5;margin:0}.tn-banner__message{font-size:.875rem;color:var(--tn-fg2, #6b7280);line-height:1.5;margin-top:4px}.tn-banner__action{display:flex;align-items:center;gap:8px 16px;justify-content:flex-end}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: TnIconComponent, selector: "tn-icon", inputs: ["name", "size", "color", "tooltip", "ariaLabel", "library", "fullSize", "customSize"] }] });
1377
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnBannerComponent, isStandalone: true, selector: "tn-banner", inputs: { heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: true, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "actionContent", predicate: TnBannerActionDirective, isSignal: true }], ngImport: i0, template: "<div\n aria-live=\"polite\"\n [ngClass]=\"classes()\"\n [attr.role]=\"ariaRole()\"\n>\n <div class=\"tn-banner__main\">\n <div class=\"tn-banner__icon\">\n <tn-icon\n library=\"mdi\"\n size=\"md\"\n aria-hidden=\"true\"\n [name]=\"iconName()\"\n />\n </div>\n\n <div class=\"tn-banner__content\">\n <div class=\"tn-banner__heading\">\n {{ heading() }}\n </div>\n\n @if (message()) {\n <div class=\"tn-banner__message\">\n {{ message() }}\n </div>\n }\n </div>\n </div>\n\n @if (hasAction()) {\n <div class=\"tn-banner__action\">\n <ng-content select=\"[tnBannerAction]\" />\n </div>\n }\n</div>\n", styles: [".tn-banner{display:grid;gap:8px;align-items:center;padding:16px;border-radius:6px;border-left:4px solid;transition:opacity .2s ease}@media(prefers-reduced-motion:reduce){.tn-banner{transition:none}}.tn-banner--info{border-left-color:var(--tn-info, #3b82f6);background-color:var(--tn-alt-bg1, #383838)}.tn-banner--info .tn-banner__heading,.tn-banner--info .tn-banner__icon{color:var(--tn-info, #3b82f6)}.tn-banner--warning{border-left-color:var(--tn-warning, #f59e0b);background-color:var(--tn-alt-bg1, #383838)}.tn-banner--warning .tn-banner__heading,.tn-banner--warning .tn-banner__icon{color:var(--tn-warning, #f59e0b)}.tn-banner--error{border-left-color:var(--tn-error, #ef4444);background-color:var(--tn-alt-bg1, #383838)}.tn-banner--error .tn-banner__heading,.tn-banner--error .tn-banner__icon{color:var(--tn-error, #ef4444)}.tn-banner--success{border-left-color:var(--tn-success, #10b981);background-color:var(--tn-alt-bg1, #383838)}.tn-banner--success .tn-banner__heading,.tn-banner--success .tn-banner__icon{color:var(--tn-success, #10b981)}.tn-banner__main{display:flex;align-items:flex-start;gap:12px;flex:1;min-width:0}.tn-banner__icon{flex-shrink:0;display:flex;align-items:center;justify-content:center;margin-top:2px}.tn-banner__content{flex:1;min-width:0}.tn-banner__heading{font-size:1rem;font-weight:600;line-height:1.5;margin:0}.tn-banner__message{font-size:.875rem;color:var(--tn-fg2, #6b7280);line-height:1.5;margin-top:4px}.tn-banner__action{display:flex;align-items:center;gap:8px 16px;justify-content:flex-end}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: TnIconComponent, selector: "tn-icon", inputs: ["name", "size", "color", "tooltip", "ariaLabel", "library", "fullSize", "customSize"] }] });
1138
1378
  }
1139
1379
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnBannerComponent, decorators: [{
1140
1380
  type: Component,
@@ -1247,7 +1487,7 @@ class TnButtonComponent {
1247
1487
  return ['storybook-button', `storybook-button--${this.size}`, mode];
1248
1488
  }, ...(ngDevMode ? [{ debugName: "classes" }] : []));
1249
1489
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1250
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.0", type: TnButtonComponent, isStandalone: true, selector: "tn-button", inputs: { primary: { classPropertyName: "primary", publicName: "primary", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, backgroundColor: { classPropertyName: "backgroundColor", publicName: "backgroundColor", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClick: "onClick" }, ngImport: i0, template: "<button\n type=\"button\"\n [ngClass]=\"classes()\"\n [ngStyle]=\"{ 'background-color': backgroundColor() }\"\n [disabled]=\"disabled()\"\n (click)=\"onClick.emit($event)\"\n>\n {{ label() }}\n</button>\n\n", styles: [":host{display:inline-block;width:fit-content;justify-self:center}.storybook-button{display:inline-block;cursor:pointer;border:0;font-weight:500;line-height:1;font-family:IBM Plex Sans,Helvetica Neue,Helvetica,Arial,sans-serif}.storybook-button:disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.button-primary{background-color:var(--tn-primary);color:var(--tn-primary-txt)}.button-default{box-shadow:#00000026 0 0 0 1px inset;background-color:var(--tn-btn-default-bg);color:var(--tn-btn-default-txt)}.button-outline-primary{background-color:transparent;border:1px solid var(--tn-primary);color:var(--tn-primary);transition:all .2s ease-in-out}.button-outline-primary:hover{background-color:var(--tn-primary);border:1px solid var(--tn-primary);color:var(--tn-primary-txt)}.button-outline-default{background-color:transparent;border:1px solid var(--tn-lines, #e5e7eb);color:var(--tn-fg1, #000000);transition:all .2s ease-in-out}.button-outline-default:hover{background-color:var(--tn-btn-default-bg);border:1px solid var(--tn-btn-default-bg);color:var(--tn-btn-default-txt);box-shadow:#00000026 0 0 0 1px inset}.button-warn{background-color:var(--tn-red);color:#fff}.button-outline-warn{background-color:transparent;border:1px solid var(--tn-red);color:var(--tn-red);transition:all .2s ease-in-out}.button-outline-warn:hover{background-color:var(--tn-red);border:1px solid var(--tn-red);color:#fff}.storybook-button--small{padding:10px 16px;font-size:12px}.storybook-button--medium{padding:11px 20px;font-size:14px}.storybook-button--large{padding:12px 24px;font-size:16px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
1490
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.0", type: TnButtonComponent, isStandalone: true, selector: "tn-button", inputs: { primary: { classPropertyName: "primary", publicName: "primary", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, backgroundColor: { classPropertyName: "backgroundColor", publicName: "backgroundColor", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClick: "onClick" }, ngImport: i0, template: "<button\n type=\"button\"\n [ngClass]=\"classes()\"\n [ngStyle]=\"{ 'background-color': backgroundColor() }\"\n [disabled]=\"disabled()\"\n (click)=\"onClick.emit($event)\"\n>\n {{ label() }}\n</button>\n\n", styles: [":host{display:inline-block;width:fit-content;justify-self:center}.storybook-button{display:inline-block;cursor:pointer;border:0;font-weight:500;line-height:1;font-family:IBM Plex Sans,Helvetica Neue,Helvetica,Arial,sans-serif}.storybook-button:disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.button-primary{background-color:var(--tn-primary);color:var(--tn-primary-txt)}.button-default{box-shadow:#00000026 0 0 0 1px inset;background-color:var(--tn-btn-default-bg);color:var(--tn-btn-default-txt)}.button-outline-primary{background-color:transparent;border:1px solid var(--tn-primary);color:var(--tn-primary);transition:all .2s ease-in-out}.button-outline-primary:hover{background-color:var(--tn-primary);border:1px solid var(--tn-primary);color:var(--tn-primary-txt)}.button-outline-default{background-color:transparent;border:1px solid var(--tn-lines, #e5e7eb);color:var(--tn-fg1, #000000);transition:all .2s ease-in-out}.button-outline-default:hover{background-color:var(--tn-btn-default-bg);border:1px solid var(--tn-btn-default-bg);color:var(--tn-btn-default-txt);box-shadow:#00000026 0 0 0 1px inset}.button-warn{background-color:var(--tn-red);color:#fff}.button-outline-warn{background-color:transparent;border:1px solid var(--tn-red);color:var(--tn-red);transition:all .2s ease-in-out}.button-outline-warn:hover{background-color:var(--tn-red);border:1px solid var(--tn-red);color:#fff}.storybook-button--small{padding:10px 16px;font-size:12px}.storybook-button--medium{padding:11px 20px;font-size:14px}.storybook-button--large{padding:12px 24px;font-size:16px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
1251
1491
  }
1252
1492
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnButtonComponent, decorators: [{
1253
1493
  type: Component,
@@ -1358,17 +1598,21 @@ class TnIconButtonComponent {
1358
1598
  library = input(undefined, ...(ngDevMode ? [{ debugName: "library" }] : []));
1359
1599
  onClick = output();
1360
1600
  classes = computed(() => {
1361
- return ['tn-icon-button'];
1601
+ const result = ['tn-icon-button'];
1602
+ if (this.color()) {
1603
+ result.push('tn-icon-button--custom-color');
1604
+ }
1605
+ return result;
1362
1606
  }, ...(ngDevMode ? [{ debugName: "classes" }] : []));
1363
1607
  effectiveAriaLabel = computed(() => {
1364
1608
  return this.ariaLabel() || this.name() || 'Icon button';
1365
1609
  }, ...(ngDevMode ? [{ debugName: "effectiveAriaLabel" }] : []));
1366
1610
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnIconButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1367
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.0", type: TnIconButtonComponent, isStandalone: true, selector: "tn-icon-button", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: true, isRequired: false, transformFunction: null }, library: { classPropertyName: "library", publicName: "library", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClick: "onClick" }, ngImport: i0, template: "<button\n type=\"button\"\n [ngClass]=\"classes()\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"effectiveAriaLabel()\"\n [attr.title]=\"tooltip()\"\n (click)=\"onClick.emit($event)\"\n>\n <tn-icon\n [name]=\"name()\"\n [size]=\"size()\"\n [color]=\"color()\"\n [library]=\"library()\"\n [ariaLabel]=\"effectiveAriaLabel()\" />\n</button>\n", styles: [":host{display:inline-block;width:fit-content}.tn-icon-button{display:inline-flex;align-items:center;justify-content:center;cursor:pointer;border:none;background:transparent;padding:8px;border-radius:4px;transition:background-color .2s ease,color .2s ease;color:var(--tn-fg2, #6b7280)}.tn-icon-button:hover:not(:disabled){background-color:var(--tn-bg3, #f3f4f6);color:var(--tn-fg1, #1f2937)}.tn-icon-button:active:not(:disabled){background-color:var(--tn-bg3, #e5e7eb)}.tn-icon-button:focus-visible{outline:2px solid var(--tn-primary, #2563eb);outline-offset:2px}.tn-icon-button:disabled{opacity:.5;cursor:not-allowed;pointer-events:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: TnIconComponent, selector: "tn-icon", inputs: ["name", "size", "color", "tooltip", "ariaLabel", "library", "fullSize", "customSize"] }] });
1611
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.0", type: TnIconButtonComponent, isStandalone: true, selector: "tn-icon-button", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: true, isRequired: false, transformFunction: null }, library: { classPropertyName: "library", publicName: "library", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClick: "onClick" }, ngImport: i0, template: "<button\n type=\"button\"\n [ngClass]=\"classes()\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"effectiveAriaLabel()\"\n [attr.title]=\"tooltip()\"\n (click)=\"onClick.emit($event)\"\n>\n <tn-icon\n [name]=\"name()\"\n [size]=\"size()\"\n [color]=\"color()\"\n [library]=\"library()\"\n [ariaLabel]=\"effectiveAriaLabel()\" />\n</button>\n", styles: [":host{display:inline-block;width:fit-content}.tn-icon-button{display:inline-flex;align-items:center;justify-content:center;cursor:pointer;border:none;background:transparent;padding:8px;border-radius:4px;transition:background-color .2s ease,color .2s ease;color:var(--tn-fg2, #6b7280)}.tn-icon-button:hover:not(:disabled){background-color:var(--tn-bg3, #f3f4f6);color:var(--tn-fg1, #1f2937)}.tn-icon-button:active:not(:disabled){background-color:var(--tn-bg3, #e5e7eb)}.tn-icon-button.tn-icon-button--custom-color:hover:not(:disabled),.tn-icon-button.tn-icon-button--custom-color:active:not(:disabled){background-color:#ffffff1a;color:inherit}.tn-icon-button:focus-visible{outline:2px solid var(--tn-primary, #2563eb);outline-offset:2px}.tn-icon-button:disabled{opacity:.5;cursor:not-allowed;pointer-events:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: TnIconComponent, selector: "tn-icon", inputs: ["name", "size", "color", "tooltip", "ariaLabel", "library", "fullSize", "customSize"] }] });
1368
1612
  }
1369
1613
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnIconButtonComponent, decorators: [{
1370
1614
  type: Component,
1371
- args: [{ selector: 'tn-icon-button', standalone: true, imports: [CommonModule, TnIconComponent], template: "<button\n type=\"button\"\n [ngClass]=\"classes()\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"effectiveAriaLabel()\"\n [attr.title]=\"tooltip()\"\n (click)=\"onClick.emit($event)\"\n>\n <tn-icon\n [name]=\"name()\"\n [size]=\"size()\"\n [color]=\"color()\"\n [library]=\"library()\"\n [ariaLabel]=\"effectiveAriaLabel()\" />\n</button>\n", styles: [":host{display:inline-block;width:fit-content}.tn-icon-button{display:inline-flex;align-items:center;justify-content:center;cursor:pointer;border:none;background:transparent;padding:8px;border-radius:4px;transition:background-color .2s ease,color .2s ease;color:var(--tn-fg2, #6b7280)}.tn-icon-button:hover:not(:disabled){background-color:var(--tn-bg3, #f3f4f6);color:var(--tn-fg1, #1f2937)}.tn-icon-button:active:not(:disabled){background-color:var(--tn-bg3, #e5e7eb)}.tn-icon-button:focus-visible{outline:2px solid var(--tn-primary, #2563eb);outline-offset:2px}.tn-icon-button:disabled{opacity:.5;cursor:not-allowed;pointer-events:none}\n"] }]
1615
+ args: [{ selector: 'tn-icon-button', standalone: true, imports: [CommonModule, TnIconComponent], template: "<button\n type=\"button\"\n [ngClass]=\"classes()\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"effectiveAriaLabel()\"\n [attr.title]=\"tooltip()\"\n (click)=\"onClick.emit($event)\"\n>\n <tn-icon\n [name]=\"name()\"\n [size]=\"size()\"\n [color]=\"color()\"\n [library]=\"library()\"\n [ariaLabel]=\"effectiveAriaLabel()\" />\n</button>\n", styles: [":host{display:inline-block;width:fit-content}.tn-icon-button{display:inline-flex;align-items:center;justify-content:center;cursor:pointer;border:none;background:transparent;padding:8px;border-radius:4px;transition:background-color .2s ease,color .2s ease;color:var(--tn-fg2, #6b7280)}.tn-icon-button:hover:not(:disabled){background-color:var(--tn-bg3, #f3f4f6);color:var(--tn-fg1, #1f2937)}.tn-icon-button:active:not(:disabled){background-color:var(--tn-bg3, #e5e7eb)}.tn-icon-button.tn-icon-button--custom-color:hover:not(:disabled),.tn-icon-button.tn-icon-button--custom-color:active:not(:disabled){background-color:#ffffff1a;color:inherit}.tn-icon-button:focus-visible{outline:2px solid var(--tn-primary, #2563eb);outline-offset:2px}.tn-icon-button:disabled{opacity:.5;cursor:not-allowed;pointer-events:none}\n"] }]
1372
1616
  }], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], tooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltip", required: false }] }], library: [{ type: i0.Input, args: [{ isSignal: true, alias: "library", required: false }] }], onClick: [{ type: i0.Output, args: ["onClick"] }] } });
1373
1617
 
1374
1618
  /**
@@ -2086,7 +2330,7 @@ class TnChipComponent {
2086
2330
  }
2087
2331
  }
2088
2332
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnChipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2089
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnChipComponent, isStandalone: true, selector: "tn-chip", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, testId: { classPropertyName: "testId", publicName: "testId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClose: "onClose", onClick: "onClick" }, viewQueries: [{ propertyName: "chipEl", first: true, predicate: ["chipEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n #chipEl\n role=\"button\"\n [ngClass]=\"classes()\"\n [attr.data-testid]=\"testId()\"\n [attr.aria-label]=\"label()\"\n [attr.aria-disabled]=\"disabled()\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n (click)=\"handleClick($event)\"\n (keydown)=\"handleKeyDown($event)\"\n>\n @if (icon()) {\n <tn-icon class=\"tn-chip__icon\" size=\"sm\" [name]=\"icon()!\" />\n }\n <span class=\"tn-chip__label\">{{ label() }}</span>\n @if (closable()) {\n <button\n type=\"button\"\n class=\"tn-chip__close\"\n [attr.aria-label]=\"'Remove ' + label()\"\n [disabled]=\"disabled()\"\n (click)=\"handleClose($event)\"\n >\n <span class=\"tn-chip__close-icon\">\u00D7</span>\n </button>\n }\n</div>", styles: [".tn-chip{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;border-radius:16px;font-family:var(--tn-font-family-body);font-size:14px;font-weight:500;line-height:1.2;cursor:pointer;transition:all .2s ease-in-out;border:1px solid transparent;outline:none;-webkit-user-select:none;user-select:none}.tn-chip:focus-visible{outline:2px solid var(--tn-primary);outline-offset:2px}.tn-chip:hover:not(.tn-chip--disabled){transform:translateY(-1px);box-shadow:0 2px 4px #0000001a}.tn-chip--primary{background-color:var(--tn-primary);color:var(--tn-primary-txt);border-color:var(--tn-primary)}.tn-chip--primary:hover:not(.tn-chip--disabled){background-color:var(--tn-blue);border-color:var(--tn-blue)}.tn-chip--secondary{background-color:var(--tn-alt-bg1);color:var(--tn-alt-fg2);border-color:var(--tn-alt-bg2)}.tn-chip--secondary:hover:not(.tn-chip--disabled){background-color:var(--tn-alt-bg2);border-color:var(--tn-accent)}.tn-chip--accent{background-color:var(--tn-accent);color:var(--tn-fg1);border-color:var(--tn-accent)}.tn-chip--accent:hover:not(.tn-chip--disabled){background-color:var(--tn-alt-bg2);border-color:var(--tn-alt-bg2)}.tn-chip--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.tn-chip--closable{padding-right:8px}.tn-chip__icon{display:flex;align-items:center;justify-content:center;width:16px;height:16px;font-size:12px}.tn-chip__label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:200px}.tn-chip__close{display:flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;margin:0;border:none;border-radius:50%;background-color:#fff3;color:inherit;cursor:pointer;transition:background-color .2s ease-in-out;outline:none}.tn-chip__close:hover:not(:disabled){background-color:#ffffff4d}.tn-chip__close:focus-visible{outline:1px solid currentColor;outline-offset:1px}.tn-chip__close:disabled{cursor:not-allowed;opacity:.5}.tn-chip__close-icon{font-size:14px;font-weight:700;line-height:1}.tn-dark .tn-chip--secondary .tn-chip__close{background-color:#0003}.tn-dark .tn-chip--secondary .tn-chip__close:hover:not(:disabled){background-color:#0000004d}.high-contrast .tn-chip{border-width:2px}.high-contrast .tn-chip:focus-visible{outline-width:3px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: A11yModule }, { kind: "component", type: TnIconComponent, selector: "tn-icon", inputs: ["name", "size", "color", "tooltip", "ariaLabel", "library", "fullSize", "customSize"] }] });
2333
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnChipComponent, isStandalone: true, selector: "tn-chip", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, testId: { classPropertyName: "testId", publicName: "testId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClose: "onClose", onClick: "onClick" }, viewQueries: [{ propertyName: "chipEl", first: true, predicate: ["chipEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n #chipEl\n role=\"button\"\n [ngClass]=\"classes()\"\n [attr.data-testid]=\"testId()\"\n [attr.aria-label]=\"label()\"\n [attr.aria-disabled]=\"disabled()\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n (click)=\"handleClick($event)\"\n (keydown)=\"handleKeyDown($event)\"\n>\n @if (icon()) {\n <tn-icon class=\"tn-chip__icon\" size=\"sm\" [name]=\"icon()!\" />\n }\n <span class=\"tn-chip__label\">{{ label() }}</span>\n @if (closable()) {\n <button\n type=\"button\"\n class=\"tn-chip__close\"\n [attr.aria-label]=\"'Remove ' + label()\"\n [disabled]=\"disabled()\"\n (click)=\"handleClose($event)\"\n >\n <span class=\"tn-chip__close-icon\">\u00D7</span>\n </button>\n }\n</div>", styles: [".tn-chip{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;border-radius:16px;font-family:var(--tn-font-family-body);font-size:14px;font-weight:500;line-height:1.2;cursor:pointer;transition:all .2s ease-in-out;border:1px solid transparent;outline:none;-webkit-user-select:none;user-select:none}.tn-chip:focus-visible{outline:2px solid var(--tn-primary);outline-offset:2px}.tn-chip:hover:not(.tn-chip--disabled){transform:translateY(-1px);box-shadow:0 2px 4px #0000001a}.tn-chip--primary{background-color:var(--tn-primary);color:var(--tn-primary-txt);border-color:var(--tn-primary)}.tn-chip--primary:hover:not(.tn-chip--disabled){background-color:var(--tn-blue);border-color:var(--tn-blue)}.tn-chip--secondary{background-color:var(--tn-alt-bg1);color:var(--tn-alt-fg2);border-color:var(--tn-alt-bg2)}.tn-chip--secondary:hover:not(.tn-chip--disabled){background-color:var(--tn-alt-bg2);border-color:var(--tn-accent)}.tn-chip--accent{background-color:var(--tn-accent);color:var(--tn-fg1);border-color:var(--tn-accent)}.tn-chip--accent:hover:not(.tn-chip--disabled){background-color:var(--tn-alt-bg2);border-color:var(--tn-alt-bg2)}.tn-chip--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.tn-chip--closable{padding-right:8px}.tn-chip__icon{display:flex;align-items:center;justify-content:center;width:16px;height:16px;font-size:12px}.tn-chip__label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:200px}.tn-chip__close{display:flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;margin:0;border:none;border-radius:50%;background-color:#fff3;color:inherit;cursor:pointer;transition:background-color .2s ease-in-out;outline:none}.tn-chip__close:hover:not(:disabled){background-color:#ffffff4d}.tn-chip__close:focus-visible{outline:1px solid currentColor;outline-offset:1px}.tn-chip__close:disabled{cursor:not-allowed;opacity:.5}.tn-chip__close-icon{font-size:14px;font-weight:700;line-height:1}.tn-dark .tn-chip--secondary .tn-chip__close{background-color:#0003}.tn-dark .tn-chip--secondary .tn-chip__close:hover:not(:disabled){background-color:#0000004d}.high-contrast .tn-chip{border-width:2px}.high-contrast .tn-chip:focus-visible{outline-width:3px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: A11yModule }, { kind: "component", type: TnIconComponent, selector: "tn-icon", inputs: ["name", "size", "color", "tooltip", "ariaLabel", "library", "fullSize", "customSize"] }] });
2090
2334
  }
2091
2335
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnChipComponent, decorators: [{
2092
2336
  type: Component,
@@ -2421,7 +2665,7 @@ class TnSlideToggleComponent {
2421
2665
  useExisting: forwardRef(() => TnSlideToggleComponent),
2422
2666
  multi: true
2423
2667
  }
2424
- ], viewQueries: [{ propertyName: "toggleEl", first: true, predicate: ["toggleEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div [ngClass]=\"classes()\" [attr.data-testid]=\"testId()\">\n <label class=\"tn-slide-toggle__label\" [for]=\"id\">\n\n <!-- Label before toggle -->\n @if (label() && labelPosition() === 'before') {\n <span\n class=\"tn-slide-toggle__label-text tn-slide-toggle__label-text--before\"\n tabindex=\"0\"\n role=\"button\"\n (click)=\"onLabelClick()\"\n (keydown.enter)=\"onLabelClick()\"\n (keydown.space)=\"onLabelClick()\">\n {{ label() }}\n </span>\n }\n\n <!-- Toggle track and thumb -->\n <div class=\"tn-slide-toggle__bar\">\n <input\n #toggleEl\n type=\"checkbox\"\n class=\"tn-slide-toggle__input\"\n [id]=\"id\"\n [checked]=\"effectiveChecked()\"\n [disabled]=\"isDisabled()\"\n [required]=\"required()\"\n [attr.aria-label]=\"effectiveAriaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledby()\"\n (change)=\"onToggleChange($event)\"\n />\n\n <div class=\"tn-slide-toggle__track\">\n <div class=\"tn-slide-toggle__track-fill\"></div>\n </div>\n\n <div class=\"tn-slide-toggle__thumb-container\">\n <div class=\"tn-slide-toggle__thumb\">\n <div class=\"tn-slide-toggle__ripple\"></div>\n <!-- State icon -->\n <div class=\"tn-slide-toggle__icon\">\n @if (effectiveChecked()) {\n <svg\n class=\"tn-slide-toggle__check-icon\"\n viewBox=\"0 0 24 24\"\n width=\"16\"\n height=\"16\">\n <path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z\" fill=\"currentColor\"/>\n </svg>\n }\n @if (!effectiveChecked()) {\n <svg\n class=\"tn-slide-toggle__minus-icon\"\n viewBox=\"0 0 24 24\"\n width=\"16\"\n height=\"16\">\n <path d=\"M19 13H5v-2h14v2z\" fill=\"currentColor\"/>\n </svg>\n }\n </div>\n </div>\n </div>\n </div>\n\n <!-- Label after toggle -->\n @if (label() && labelPosition() === 'after') {\n <span\n class=\"tn-slide-toggle__label-text tn-slide-toggle__label-text--after\"\n tabindex=\"0\"\n role=\"button\"\n (click)=\"onLabelClick()\"\n (keydown.enter)=\"onLabelClick()\"\n (keydown.space)=\"onLabelClick()\">\n {{ label() }}\n </span>\n }\n\n </label>\n</div>", styles: [".tn-slide-toggle{display:inline-flex;align-items:center;cursor:pointer;-webkit-user-select:none;user-select:none;line-height:1;font-family:inherit}.tn-slide-toggle__label{display:flex;align-items:center;cursor:inherit}.tn-slide-toggle__label-text{font-size:14px;line-height:1.4;color:var(--tn-fg1);transition:color .2s ease}.tn-slide-toggle__label-text--before{margin-right:8px}.tn-slide-toggle__label-text--after{margin-left:8px}.tn-slide-toggle__input{position:absolute;opacity:0;width:0;height:0;margin:0;pointer-events:none}.tn-slide-toggle__input:focus+.tn-slide-toggle__track{box-shadow:0 0 0 2px rgba(var(--tn-primary-rgb, 0, 123, 255),.2)}.tn-slide-toggle__bar{position:relative;display:flex;align-items:center;flex-shrink:0}.tn-slide-toggle__track{position:relative;width:52px;height:32px;border-radius:16px;background-color:var(--tn-lines);border:1px solid transparent;transition:background-color .2s ease,border-color .2s ease;overflow:hidden}.tn-slide-toggle__track-fill{position:absolute;inset:0;border-radius:inherit;background-color:var(--tn-primary, #007cba);opacity:0;transform:scaleX(0);transform-origin:left center;transition:opacity .2s ease,transform .2s ease}.tn-slide-toggle__thumb-container{position:absolute;top:50%;left:4px;transform:translateY(-50%);width:24px;height:24px;transition:transform .2s ease;z-index:1}.tn-slide-toggle__thumb{position:relative;width:24px;height:24px;border-radius:50%;background-color:var(--tn-bg2);border:1px solid var(--tn-lines);box-shadow:0 2px 4px #0003;transition:background-color .2s ease,border-color .2s ease,box-shadow .2s ease;display:flex;align-items:center;justify-content:center}.tn-slide-toggle__ripple{position:absolute;width:40px;height:40px;border-radius:50%;background-color:transparent;top:50%;left:50%;transform:translate(-50%,-50%);opacity:0;transition:opacity .2s ease,background-color .2s ease}.tn-slide-toggle__icon{position:relative;display:flex;align-items:center;justify-content:center;z-index:2;pointer-events:none}.tn-slide-toggle__check-icon,.tn-slide-toggle__minus-icon{transition:opacity .2s ease,transform .2s ease;color:var(--tn-fg2)}.tn-slide-toggle:hover:not(.tn-slide-toggle--disabled) .tn-slide-toggle__ripple{background-color:var(--tn-primary);opacity:.08}.tn-slide-toggle--checked .tn-slide-toggle__track{background-color:var(--tn-primary);opacity:.5}.tn-slide-toggle--checked .tn-slide-toggle__track-fill{opacity:1;transform:scaleX(1)}.tn-slide-toggle--checked .tn-slide-toggle__thumb-container{transform:translateY(-50%) translate(24px)}.tn-slide-toggle--checked .tn-slide-toggle__thumb{background-color:var(--tn-bg2);border-color:var(--tn-primary)}.tn-slide-toggle--checked .tn-slide-toggle__check-icon{color:var(--tn-primary)}.tn-slide-toggle--checked:hover:not(.tn-slide-toggle--disabled) .tn-slide-toggle__ripple{background-color:var(--tn-primary);opacity:.12}.tn-slide-toggle--disabled{cursor:not-allowed;opacity:.6}.tn-slide-toggle--disabled .tn-slide-toggle__label-text{color:var(--tn-alt-fg1)}.tn-slide-toggle--disabled .tn-slide-toggle__track{background-color:var(--tn-alt-bg1)}.tn-slide-toggle--disabled .tn-slide-toggle__thumb{background-color:var(--tn-alt-bg2);border-color:var(--tn-alt-bg1);box-shadow:none}.tn-slide-toggle--disabled.tn-slide-toggle--checked .tn-slide-toggle__track,.tn-slide-toggle--disabled.tn-slide-toggle--checked .tn-slide-toggle__track-fill{background-color:var(--tn-alt-bg1)}.tn-slide-toggle--disabled.tn-slide-toggle--checked .tn-slide-toggle__thumb{background-color:var(--tn-alt-bg2);border-color:var(--tn-alt-bg1)}.tn-slide-toggle--disabled.tn-slide-toggle--checked .tn-slide-toggle__check-icon{color:var(--tn-alt-fg1)}.tn-slide-toggle--disabled:hover .tn-slide-toggle__ripple{opacity:0}.tn-slide-toggle--accent{--tn-primary: var(--tn-accent)}.tn-slide-toggle--warn{--tn-primary: var(--tn-red)}.tn-slide-toggle .tn-slide-toggle__input:focus-visible+.tn-slide-toggle__track{outline:2px solid var(--tn-primary);outline-offset:2px}.tn-slide-toggle:active:not(.tn-slide-toggle--disabled) .tn-slide-toggle__ripple{background-color:var(--tn-primary);opacity:.16;transform:translate(-50%,-50%) scale(1.1)}@media(prefers-contrast:high){.tn-slide-toggle .tn-slide-toggle__track{border-color:var(--tn-fg1)}.tn-slide-toggle .tn-slide-toggle__thumb{border-width:2px}.tn-slide-toggle--disabled .tn-slide-toggle__track,.tn-slide-toggle--disabled .tn-slide-toggle__thumb{border-color:var(--tn-alt-fg1)}}@media(prefers-reduced-motion:reduce){.tn-slide-toggle .tn-slide-toggle__track,.tn-slide-toggle .tn-slide-toggle__track-fill,.tn-slide-toggle .tn-slide-toggle__thumb-container,.tn-slide-toggle .tn-slide-toggle__thumb,.tn-slide-toggle .tn-slide-toggle__ripple{transition:none}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: A11yModule }] });
2668
+ ], viewQueries: [{ propertyName: "toggleEl", first: true, predicate: ["toggleEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div [ngClass]=\"classes()\" [attr.data-testid]=\"testId()\">\n <label class=\"tn-slide-toggle__label\" [for]=\"id\">\n\n <!-- Label before toggle -->\n @if (label() && labelPosition() === 'before') {\n <span\n class=\"tn-slide-toggle__label-text tn-slide-toggle__label-text--before\"\n tabindex=\"0\"\n role=\"button\"\n (click)=\"onLabelClick()\"\n (keydown.enter)=\"onLabelClick()\"\n (keydown.space)=\"onLabelClick()\">\n {{ label() }}\n </span>\n }\n\n <!-- Toggle track and thumb -->\n <div class=\"tn-slide-toggle__bar\">\n <input\n #toggleEl\n type=\"checkbox\"\n class=\"tn-slide-toggle__input\"\n [id]=\"id\"\n [checked]=\"effectiveChecked()\"\n [disabled]=\"isDisabled()\"\n [required]=\"required()\"\n [attr.aria-label]=\"effectiveAriaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledby()\"\n (change)=\"onToggleChange($event)\"\n />\n\n <div class=\"tn-slide-toggle__track\">\n <div class=\"tn-slide-toggle__track-fill\"></div>\n </div>\n\n <div class=\"tn-slide-toggle__thumb-container\">\n <div class=\"tn-slide-toggle__thumb\">\n <div class=\"tn-slide-toggle__ripple\"></div>\n <!-- State icon -->\n <div class=\"tn-slide-toggle__icon\">\n @if (effectiveChecked()) {\n <svg\n class=\"tn-slide-toggle__check-icon\"\n viewBox=\"0 0 24 24\"\n width=\"16\"\n height=\"16\">\n <path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z\" fill=\"currentColor\"/>\n </svg>\n }\n @if (!effectiveChecked()) {\n <svg\n class=\"tn-slide-toggle__minus-icon\"\n viewBox=\"0 0 24 24\"\n width=\"16\"\n height=\"16\">\n <path d=\"M19 13H5v-2h14v2z\" fill=\"currentColor\"/>\n </svg>\n }\n </div>\n </div>\n </div>\n </div>\n\n <!-- Label after toggle -->\n @if (label() && labelPosition() === 'after') {\n <span\n class=\"tn-slide-toggle__label-text tn-slide-toggle__label-text--after\"\n tabindex=\"0\"\n role=\"button\"\n (click)=\"onLabelClick()\"\n (keydown.enter)=\"onLabelClick()\"\n (keydown.space)=\"onLabelClick()\">\n {{ label() }}\n </span>\n }\n\n </label>\n</div>", styles: [".tn-slide-toggle{display:inline-flex;align-items:center;cursor:pointer;-webkit-user-select:none;user-select:none;line-height:1;font-family:inherit}.tn-slide-toggle__label{display:flex;align-items:center;cursor:inherit}.tn-slide-toggle__label-text{font-size:14px;line-height:1.4;color:var(--tn-fg1);transition:color .2s ease}.tn-slide-toggle__label-text--before{margin-right:8px}.tn-slide-toggle__label-text--after{margin-left:8px}.tn-slide-toggle__input{position:absolute;opacity:0;width:0;height:0;margin:0;pointer-events:none}.tn-slide-toggle__input:focus+.tn-slide-toggle__track{box-shadow:0 0 0 2px rgba(var(--tn-primary-rgb, 0, 123, 255),.2)}.tn-slide-toggle__bar{position:relative;display:flex;align-items:center;flex-shrink:0}.tn-slide-toggle__track{position:relative;width:52px;height:32px;border-radius:16px;background-color:var(--tn-lines);border:1px solid transparent;transition:background-color .2s ease,border-color .2s ease;overflow:hidden}.tn-slide-toggle__track-fill{position:absolute;inset:0;border-radius:inherit;background-color:var(--tn-primary, #007cba);opacity:0;transform:scaleX(0);transform-origin:left center;transition:opacity .2s ease,transform .2s ease}.tn-slide-toggle__thumb-container{position:absolute;top:50%;left:4px;transform:translateY(-50%);width:24px;height:24px;transition:transform .2s ease;z-index:1}.tn-slide-toggle__thumb{position:relative;width:24px;height:24px;border-radius:50%;background-color:var(--tn-bg2);border:1px solid var(--tn-lines);box-shadow:0 2px 4px #0003;transition:background-color .2s ease,border-color .2s ease,box-shadow .2s ease;display:flex;align-items:center;justify-content:center}.tn-slide-toggle__ripple{position:absolute;width:40px;height:40px;border-radius:50%;background-color:transparent;top:50%;left:50%;transform:translate(-50%,-50%);opacity:0;transition:opacity .2s ease,background-color .2s ease}.tn-slide-toggle__icon{position:relative;display:flex;align-items:center;justify-content:center;z-index:2;pointer-events:none}.tn-slide-toggle__check-icon,.tn-slide-toggle__minus-icon{transition:opacity .2s ease,transform .2s ease;color:var(--tn-fg2)}.tn-slide-toggle:hover:not(.tn-slide-toggle--disabled) .tn-slide-toggle__ripple{background-color:var(--tn-primary);opacity:.08}.tn-slide-toggle--checked .tn-slide-toggle__track{background-color:var(--tn-primary);opacity:.5}.tn-slide-toggle--checked .tn-slide-toggle__track-fill{opacity:1;transform:scaleX(1)}.tn-slide-toggle--checked .tn-slide-toggle__thumb-container{transform:translateY(-50%) translate(24px)}.tn-slide-toggle--checked .tn-slide-toggle__thumb{background-color:var(--tn-bg2);border-color:var(--tn-primary)}.tn-slide-toggle--checked .tn-slide-toggle__check-icon{color:var(--tn-primary)}.tn-slide-toggle--checked:hover:not(.tn-slide-toggle--disabled) .tn-slide-toggle__ripple{background-color:var(--tn-primary);opacity:.12}.tn-slide-toggle--disabled{cursor:not-allowed;opacity:.6}.tn-slide-toggle--disabled .tn-slide-toggle__label-text{color:var(--tn-alt-fg1)}.tn-slide-toggle--disabled .tn-slide-toggle__track{background-color:var(--tn-alt-bg1)}.tn-slide-toggle--disabled .tn-slide-toggle__thumb{background-color:var(--tn-alt-bg2);border-color:var(--tn-alt-bg1);box-shadow:none}.tn-slide-toggle--disabled.tn-slide-toggle--checked .tn-slide-toggle__track,.tn-slide-toggle--disabled.tn-slide-toggle--checked .tn-slide-toggle__track-fill{background-color:var(--tn-alt-bg1)}.tn-slide-toggle--disabled.tn-slide-toggle--checked .tn-slide-toggle__thumb{background-color:var(--tn-alt-bg2);border-color:var(--tn-alt-bg1)}.tn-slide-toggle--disabled.tn-slide-toggle--checked .tn-slide-toggle__check-icon{color:var(--tn-alt-fg1)}.tn-slide-toggle--disabled:hover .tn-slide-toggle__ripple{opacity:0}.tn-slide-toggle--accent{--tn-primary: var(--tn-accent)}.tn-slide-toggle--warn{--tn-primary: var(--tn-red)}.tn-slide-toggle .tn-slide-toggle__input:focus-visible+.tn-slide-toggle__track{outline:2px solid var(--tn-primary);outline-offset:2px}.tn-slide-toggle:active:not(.tn-slide-toggle--disabled) .tn-slide-toggle__ripple{background-color:var(--tn-primary);opacity:.16;transform:translate(-50%,-50%) scale(1.1)}@media(prefers-contrast:high){.tn-slide-toggle .tn-slide-toggle__track{border-color:var(--tn-fg1)}.tn-slide-toggle .tn-slide-toggle__thumb{border-width:2px}.tn-slide-toggle--disabled .tn-slide-toggle__track,.tn-slide-toggle--disabled .tn-slide-toggle__thumb{border-color:var(--tn-alt-fg1)}}@media(prefers-reduced-motion:reduce){.tn-slide-toggle .tn-slide-toggle__track,.tn-slide-toggle .tn-slide-toggle__track-fill,.tn-slide-toggle .tn-slide-toggle__thumb-container,.tn-slide-toggle .tn-slide-toggle__thumb,.tn-slide-toggle .tn-slide-toggle__ripple{transition:none}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: A11yModule }] });
2425
2669
  }
2426
2670
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnSlideToggleComponent, decorators: [{
2427
2671
  type: Component,
@@ -2508,7 +2752,7 @@ class TnCardComponent {
2508
2752
  return type ? `tn-card__status--${type}` : 'tn-card__status--neutral';
2509
2753
  }
2510
2754
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2511
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnCardComponent, isStandalone: true, selector: "tn-card", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, titleLink: { classPropertyName: "titleLink", publicName: "titleLink", isSignal: true, isRequired: false, transformFunction: null }, elevation: { classPropertyName: "elevation", publicName: "elevation", isSignal: true, isRequired: false, transformFunction: null }, padding: { classPropertyName: "padding", publicName: "padding", isSignal: true, isRequired: false, transformFunction: null }, padContent: { classPropertyName: "padContent", publicName: "padContent", isSignal: true, isRequired: false, transformFunction: null }, bordered: { classPropertyName: "bordered", publicName: "bordered", isSignal: true, isRequired: false, transformFunction: null }, background: { classPropertyName: "background", publicName: "background", isSignal: true, isRequired: false, transformFunction: null }, headerStatus: { classPropertyName: "headerStatus", publicName: "headerStatus", isSignal: true, isRequired: false, transformFunction: null }, headerControl: { classPropertyName: "headerControl", publicName: "headerControl", isSignal: true, isRequired: false, transformFunction: null }, headerMenu: { classPropertyName: "headerMenu", publicName: "headerMenu", isSignal: true, isRequired: false, transformFunction: null }, primaryAction: { classPropertyName: "primaryAction", publicName: "primaryAction", isSignal: true, isRequired: false, transformFunction: null }, secondaryAction: { classPropertyName: "secondaryAction", publicName: "secondaryAction", isSignal: true, isRequired: false, transformFunction: null }, footerLink: { classPropertyName: "footerLink", publicName: "footerLink", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div [ngClass]=\"classes()\">\n <!-- Header section -->\n @if (hasHeader()) {\n <div class=\"tn-card__header\">\n <div class=\"tn-card__header-left\">\n @if (title()) {\n <h3\n class=\"tn-card__title\"\n [class.tn-card__title--link]=\"titleLink()\"\n [attr.tabindex]=\"titleLink() ? 0 : null\"\n [attr.role]=\"titleLink() ? 'button' : null\"\n (click)=\"onTitleClick()\"\n (keydown.enter)=\"onTitleClick()\"\n (keydown.space)=\"onTitleClick()\">\n {{ title() }}\n </h3>\n }\n </div>\n\n <div class=\"tn-card__header-right\">\n <!-- Header Status -->\n @if (headerStatus(); as status) {\n <div\n class=\"tn-card__status\"\n [ngClass]=\"getStatusClass(status?.type)\">\n {{ status.label }}\n </div>\n }\n\n <!-- Header Control (Slide Toggle) -->\n @if (headerControl(); as control) {\n <div class=\"tn-card__control\">\n <tn-slide-toggle\n [label]=\"control.label\"\n [checked]=\"control.checked\"\n [disabled]=\"control.disabled || false\"\n (change)=\"onControlChange($event)\" />\n </div>\n }\n\n <!-- Header Menu -->\n @if (headerMenu(); as menu) {\n @if (menu.length) {\n <div class=\"tn-card__menu\">\n <tn-icon-button\n name=\"dots-vertical\"\n library=\"mdi\"\n size=\"md\"\n ariaLabel=\"Card menu\"\n [tnMenuTriggerFor]=\"cardMenu\" />\n <tn-menu\n #cardMenu\n [items]=\"menu\"\n (menuItemClick)=\"onHeaderMenuItemClick($event)\" />\n </div>\n }\n }\n </div>\n </div>\n }\n\n <!-- Content section -->\n <div class=\"tn-card__content\">\n <ng-content />\n </div>\n\n <!-- Footer section -->\n @if (hasFooter()) {\n <div class=\"tn-card__footer\">\n <div class=\"tn-card__footer-left\">\n @if (footerLink(); as link) {\n <button\n type=\"button\"\n class=\"tn-card__footer-link\"\n (click)=\"link.handler()\">\n {{ link.label }}\n </button>\n }\n </div>\n\n <div class=\"tn-card__footer-right\">\n @if (secondaryAction(); as action) {\n <tn-button\n variant=\"outline\"\n color=\"default\"\n [label]=\"action.label\"\n [disabled]=\"action.disabled || false\"\n (click)=\"action.handler()\" />\n }\n\n @if (primaryAction(); as action) {\n <tn-button\n variant=\"filled\"\n color=\"primary\"\n [label]=\"action.label\"\n [disabled]=\"action.disabled || false\"\n (click)=\"action.handler()\" />\n }\n </div>\n </div>\n }\n</div>", styles: [".tn-card{height:100%;display:flex;flex-direction:column;border-radius:8px;transition:box-shadow .3s ease;overflow:hidden}.tn-card--elevation-none{box-shadow:none}.tn-card--elevation-low{box-shadow:0 1px 3px #0000001a}.tn-card--elevation-medium{box-shadow:0 4px 6px #0000001a}.tn-card--elevation-high{box-shadow:0 10px 15px #0000001a}.tn-card--bordered{border:1px solid var(--tn-lines, #e5e7eb)}.tn-card--background{background-color:var(--tn-bg2, #ffffff)}.tn-card--padding-small .tn-card__header{padding:12px 16px}.tn-card--padding-medium .tn-card__header{padding:16px 24px}.tn-card--padding-large .tn-card__header{padding:24px 32px}.tn-card--content-padding-none .tn-card__content{padding:0}.tn-card--content-padding-small .tn-card__content{padding:16px}.tn-card--content-padding-medium .tn-card__content{padding:24px}.tn-card--content-padding-large .tn-card__content{padding:32px}.tn-card__content{flex:1;min-height:0}.tn-card__header{display:flex;align-items:center;justify-content:space-between;gap:16px;border-bottom:1px solid var(--tn-lines, #e5e7eb)}.tn-card:not(.tn-card--bordered) .tn-card__header{border-bottom-color:#0000001a}.tn-card__header-left{flex:1;min-width:0}.tn-card__header-right{display:flex;align-items:center;gap:12px;flex-shrink:0}.tn-card__title{margin:0;font-size:1.125rem;font-weight:600;color:var(--tn-fg1, #1f2937);line-height:1.5}.tn-card__title--link{cursor:pointer;transition:color .2s ease}.tn-card__title--link:hover{color:var(--tn-primary, #2563eb)}.tn-card__status{display:inline-flex;align-items:center;padding:4px 12px;border-radius:12px;font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px}.tn-card__status--success{background-color:#10b9811a;color:var(--tn-success, #10b981)}.tn-card__status--warning{background-color:#f59e0b1a;color:var(--tn-warning, #f59e0b)}.tn-card__status--error{background-color:#ef44441a;color:var(--tn-error, #ef4444)}.tn-card__status--info{background-color:#3b82f61a;color:var(--tn-info, #3b82f6)}.tn-card__status--neutral{background-color:#6b72801a;color:var(--tn-fg2, #6b7280)}.tn-card__control,.tn-card__menu{display:flex;align-items:center}.tn-card__footer{display:flex;align-items:center;justify-content:space-between;gap:16px;border-top:1px solid var(--tn-lines, #e5e7eb);padding:16px 24px}.tn-card--padding-small .tn-card__footer{padding:12px 16px}.tn-card--padding-large .tn-card__footer{padding:24px 32px}.tn-card:not(.tn-card--bordered) .tn-card__footer{border-top-color:#0000001a}.tn-card__footer-left{flex:1;min-width:0}.tn-card__footer-right{display:flex;align-items:center;gap:8px;flex-shrink:0}.tn-card__footer-link{border:none;background:transparent;color:var(--tn-primary, #2563eb);font-size:.875rem;font-weight:600;cursor:pointer;padding:0;text-decoration:none;transition:color .2s ease}.tn-card__footer-link:hover{color:var(--tn-primary-dark, #1d4ed8);text-decoration:underline}.tn-card__footer-link:focus{outline:2px solid var(--tn-primary, #2563eb);outline-offset:2px;border-radius:2px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: TnButtonComponent, selector: "tn-button", inputs: ["primary", "color", "variant", "backgroundColor", "label", "disabled"], outputs: ["onClick"] }, { kind: "component", type: TnIconButtonComponent, selector: "tn-icon-button", inputs: ["disabled", "ariaLabel", "name", "size", "color", "tooltip", "library"], outputs: ["onClick"] }, { kind: "component", type: TnSlideToggleComponent, selector: "tn-slide-toggle", inputs: ["labelPosition", "label", "disabled", "required", "color", "testId", "ariaLabel", "ariaLabelledby", "checked"], outputs: ["change", "toggleChange"] }, { kind: "component", type: TnMenuComponent, selector: "tn-menu", inputs: ["items", "contextMenu"], outputs: ["menuItemClick", "menuOpen", "menuClose"] }, { kind: "directive", type: TnMenuTriggerDirective, selector: "[tnMenuTriggerFor]", inputs: ["tnMenuTriggerFor", "tnMenuPosition"], exportAs: ["tnMenuTrigger"] }] });
2755
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnCardComponent, isStandalone: true, selector: "tn-card", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, titleLink: { classPropertyName: "titleLink", publicName: "titleLink", isSignal: true, isRequired: false, transformFunction: null }, elevation: { classPropertyName: "elevation", publicName: "elevation", isSignal: true, isRequired: false, transformFunction: null }, padding: { classPropertyName: "padding", publicName: "padding", isSignal: true, isRequired: false, transformFunction: null }, padContent: { classPropertyName: "padContent", publicName: "padContent", isSignal: true, isRequired: false, transformFunction: null }, bordered: { classPropertyName: "bordered", publicName: "bordered", isSignal: true, isRequired: false, transformFunction: null }, background: { classPropertyName: "background", publicName: "background", isSignal: true, isRequired: false, transformFunction: null }, headerStatus: { classPropertyName: "headerStatus", publicName: "headerStatus", isSignal: true, isRequired: false, transformFunction: null }, headerControl: { classPropertyName: "headerControl", publicName: "headerControl", isSignal: true, isRequired: false, transformFunction: null }, headerMenu: { classPropertyName: "headerMenu", publicName: "headerMenu", isSignal: true, isRequired: false, transformFunction: null }, primaryAction: { classPropertyName: "primaryAction", publicName: "primaryAction", isSignal: true, isRequired: false, transformFunction: null }, secondaryAction: { classPropertyName: "secondaryAction", publicName: "secondaryAction", isSignal: true, isRequired: false, transformFunction: null }, footerLink: { classPropertyName: "footerLink", publicName: "footerLink", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div [ngClass]=\"classes()\">\n <!-- Header section -->\n @if (hasHeader()) {\n <div class=\"tn-card__header\">\n <div class=\"tn-card__header-left\">\n @if (title()) {\n <h3\n class=\"tn-card__title\"\n [class.tn-card__title--link]=\"titleLink()\"\n [attr.tabindex]=\"titleLink() ? 0 : null\"\n [attr.role]=\"titleLink() ? 'button' : null\"\n (click)=\"onTitleClick()\"\n (keydown.enter)=\"onTitleClick()\"\n (keydown.space)=\"onTitleClick()\">\n {{ title() }}\n </h3>\n }\n </div>\n\n <div class=\"tn-card__header-right\">\n <!-- Header Status -->\n @if (headerStatus(); as status) {\n <div\n class=\"tn-card__status\"\n [ngClass]=\"getStatusClass(status?.type)\">\n {{ status.label }}\n </div>\n }\n\n <!-- Header Control (Slide Toggle) -->\n @if (headerControl(); as control) {\n <div class=\"tn-card__control\">\n <tn-slide-toggle\n [label]=\"control.label\"\n [checked]=\"control.checked\"\n [disabled]=\"control.disabled || false\"\n (change)=\"onControlChange($event)\" />\n </div>\n }\n\n <!-- Header Menu -->\n @if (headerMenu(); as menu) {\n @if (menu.length) {\n <div class=\"tn-card__menu\">\n <tn-icon-button\n name=\"dots-vertical\"\n library=\"mdi\"\n size=\"md\"\n ariaLabel=\"Card menu\"\n [tnMenuTriggerFor]=\"cardMenu\" />\n <tn-menu\n #cardMenu\n [items]=\"menu\"\n (menuItemClick)=\"onHeaderMenuItemClick($event)\" />\n </div>\n }\n }\n </div>\n </div>\n }\n\n <!-- Content section -->\n <div class=\"tn-card__content\">\n <ng-content />\n </div>\n\n <!-- Footer section -->\n @if (hasFooter()) {\n <div class=\"tn-card__footer\">\n <div class=\"tn-card__footer-left\">\n @if (footerLink(); as link) {\n <button\n type=\"button\"\n class=\"tn-card__footer-link\"\n (click)=\"link.handler()\">\n {{ link.label }}\n </button>\n }\n </div>\n\n <div class=\"tn-card__footer-right\">\n @if (secondaryAction(); as action) {\n <tn-button\n variant=\"outline\"\n color=\"default\"\n [label]=\"action.label\"\n [disabled]=\"action.disabled || false\"\n (click)=\"action.handler()\" />\n }\n\n @if (primaryAction(); as action) {\n <tn-button\n variant=\"filled\"\n color=\"primary\"\n [label]=\"action.label\"\n [disabled]=\"action.disabled || false\"\n (click)=\"action.handler()\" />\n }\n </div>\n </div>\n }\n</div>", styles: [".tn-card{height:100%;display:flex;flex-direction:column;border-radius:8px;transition:box-shadow .3s ease;overflow:hidden}.tn-card--elevation-none{box-shadow:none}.tn-card--elevation-low{box-shadow:0 1px 3px #0000001a}.tn-card--elevation-medium{box-shadow:0 4px 6px #0000001a}.tn-card--elevation-high{box-shadow:0 10px 15px #0000001a}.tn-card--bordered{border:1px solid var(--tn-lines, #e5e7eb)}.tn-card--background{background-color:var(--tn-bg2, #ffffff)}.tn-card--padding-small .tn-card__header{padding:12px 16px}.tn-card--padding-medium .tn-card__header{padding:16px 24px}.tn-card--padding-large .tn-card__header{padding:24px 32px}.tn-card--content-padding-none .tn-card__content{padding:0}.tn-card--content-padding-small .tn-card__content{padding:16px}.tn-card--content-padding-medium .tn-card__content{padding:24px}.tn-card--content-padding-large .tn-card__content{padding:32px}.tn-card__content{flex:1;min-height:0}.tn-card__header{display:flex;align-items:center;justify-content:space-between;gap:16px;border-bottom:1px solid var(--tn-lines, #e5e7eb)}.tn-card:not(.tn-card--bordered) .tn-card__header{border-bottom-color:#0000001a}.tn-card__header-left{flex:1;min-width:0}.tn-card__header-right{display:flex;align-items:center;gap:12px;flex-shrink:0}.tn-card__title{margin:0;font-size:1.125rem;font-weight:600;color:var(--tn-fg1, #1f2937);line-height:1.5}.tn-card__title--link{cursor:pointer;transition:color .2s ease}.tn-card__title--link:hover{color:var(--tn-primary, #2563eb)}.tn-card__status{display:inline-flex;align-items:center;padding:4px 12px;border-radius:12px;font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px}.tn-card__status--success{background-color:#10b9811a;color:var(--tn-success, #10b981)}.tn-card__status--warning{background-color:#f59e0b1a;color:var(--tn-warning, #f59e0b)}.tn-card__status--error{background-color:#ef44441a;color:var(--tn-error, #ef4444)}.tn-card__status--info{background-color:#3b82f61a;color:var(--tn-info, #3b82f6)}.tn-card__status--neutral{background-color:#6b72801a;color:var(--tn-fg2, #6b7280)}.tn-card__control,.tn-card__menu{display:flex;align-items:center}.tn-card__footer{display:flex;align-items:center;justify-content:space-between;gap:16px;border-top:1px solid var(--tn-lines, #e5e7eb);padding:16px 24px}.tn-card--padding-small .tn-card__footer{padding:12px 16px}.tn-card--padding-large .tn-card__footer{padding:24px 32px}.tn-card:not(.tn-card--bordered) .tn-card__footer{border-top-color:#0000001a}.tn-card__footer-left{flex:1;min-width:0}.tn-card__footer-right{display:flex;align-items:center;gap:8px;flex-shrink:0}.tn-card__footer-link{border:none;background:transparent;color:var(--tn-primary, #2563eb);font-size:.875rem;font-weight:600;cursor:pointer;padding:0;text-decoration:none;transition:color .2s ease}.tn-card__footer-link:hover{color:var(--tn-primary-dark, #1d4ed8);text-decoration:underline}.tn-card__footer-link:focus{outline:2px solid var(--tn-primary, #2563eb);outline-offset:2px;border-radius:2px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: TnButtonComponent, selector: "tn-button", inputs: ["primary", "color", "variant", "backgroundColor", "label", "disabled"], outputs: ["onClick"] }, { kind: "component", type: TnIconButtonComponent, selector: "tn-icon-button", inputs: ["disabled", "ariaLabel", "name", "size", "color", "tooltip", "library"], outputs: ["onClick"] }, { kind: "component", type: TnSlideToggleComponent, selector: "tn-slide-toggle", inputs: ["labelPosition", "label", "disabled", "required", "color", "testId", "ariaLabel", "ariaLabelledby", "checked"], outputs: ["change", "toggleChange"] }, { kind: "component", type: TnMenuComponent, selector: "tn-menu", inputs: ["items", "contextMenu"], outputs: ["menuItemClick", "menuOpen", "menuClose"] }, { kind: "directive", type: TnMenuTriggerDirective, selector: "[tnMenuTriggerFor]", inputs: ["tnMenuTriggerFor", "tnMenuPosition"], exportAs: ["tnMenuTrigger"] }] });
2512
2756
  }
2513
2757
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnCardComponent, decorators: [{
2514
2758
  type: Component,
@@ -2585,7 +2829,7 @@ class TnExpansionPanelComponent {
2585
2829
  ].filter(Boolean);
2586
2830
  }, ...(ngDevMode ? [{ debugName: "classes" }] : []));
2587
2831
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnExpansionPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2588
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnExpansionPanelComponent, isStandalone: true, selector: "tn-expansion-panel", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, elevation: { classPropertyName: "elevation", publicName: "elevation", isSignal: true, isRequired: false, transformFunction: null }, padding: { classPropertyName: "padding", publicName: "padding", isSignal: true, isRequired: false, transformFunction: null }, bordered: { classPropertyName: "bordered", publicName: "bordered", isSignal: true, isRequired: false, transformFunction: null }, background: { classPropertyName: "background", publicName: "background", isSignal: true, isRequired: false, transformFunction: null }, expanded: { classPropertyName: "expanded", publicName: "expanded", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, titleStyle: { classPropertyName: "titleStyle", publicName: "titleStyle", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { expandedChange: "expandedChange", toggleEvent: "toggleEvent" }, ngImport: i0, template: "<div [ngClass]=\"classes()\">\n <button class=\"tn-expansion-panel__header\"\n [disabled]=\"disabled()\"\n [attr.aria-expanded]=\"effectiveExpanded()\"\n [attr.aria-controls]=\"contentId\"\n [attr.aria-disabled]=\"disabled()\"\n (click)=\"toggle()\">\n @if (title()) {\n <div class=\"tn-expansion-panel__title\">\n {{ title() }}\n </div>\n }\n <ng-content select=\"[slot=title]\" />\n\n <div class=\"tn-expansion-panel__indicator\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"m6 9 6 6 6-6\"/>\n </svg>\n </div>\n </button>\n\n <div class=\"tn-expansion-panel__content\"\n [id]=\"contentId\"\n [attr.aria-hidden]=\"!effectiveExpanded()\"\n [@expandCollapse]=\"effectiveExpanded() ? 'expanded' : 'collapsed'\">\n <ng-content />\n </div>\n</div>", styles: [".tn-expansion-panel{border-radius:8px;transition:box-shadow .3s ease;overflow:hidden}.tn-expansion-panel--elevation-none{box-shadow:none}.tn-expansion-panel--elevation-low{box-shadow:0 1px 3px #0000001a}.tn-expansion-panel--elevation-medium{box-shadow:0 4px 6px #0000001a}.tn-expansion-panel--elevation-high{box-shadow:0 10px 15px #0000001a}.tn-expansion-panel--bordered{border:1px solid var(--tn-lines, #e5e7eb)}.tn-expansion-panel--background{background-color:var(--tn-bg2, #ffffff)}.tn-expansion-panel--disabled{opacity:.6;cursor:not-allowed}.tn-expansion-panel--disabled .tn-expansion-panel__header{cursor:not-allowed}.tn-expansion-panel--expanded .tn-expansion-panel__indicator svg{transform:rotate(180deg)}.tn-expansion-panel--padding-small .tn-expansion-panel__header{padding:12px 16px}.tn-expansion-panel--padding-small .tn-expansion-panel__content{padding:0 16px 16px}.tn-expansion-panel--padding-medium .tn-expansion-panel__header{padding:16px 24px}.tn-expansion-panel--padding-medium .tn-expansion-panel__content{padding:0 24px 24px}.tn-expansion-panel--padding-large .tn-expansion-panel__header{padding:24px 32px}.tn-expansion-panel--padding-large .tn-expansion-panel__content{padding:0 32px 32px}.tn-expansion-panel--title-header .tn-expansion-panel__title{font-size:1.125rem;font-weight:600;color:var(--tn-fg1, #1f2937)}.tn-expansion-panel--title-header .tn-expansion-panel__indicator{color:var(--tn-fg1, #1f2937)}.tn-expansion-panel--title-body .tn-expansion-panel__title{font-size:1rem;font-weight:400;color:var(--tn-fg1, #1f2937)}.tn-expansion-panel--title-body .tn-expansion-panel__indicator{color:var(--tn-fg1, #1f2937)}.tn-expansion-panel--title-link .tn-expansion-panel__title{font-size:1rem;font-weight:400;color:var(--tn-primary, #3b82f6);text-decoration:none}.tn-expansion-panel--title-link .tn-expansion-panel__indicator{color:var(--tn-primary, #3b82f6)}.tn-expansion-panel--title-link .tn-expansion-panel__header:hover:not(:disabled) .tn-expansion-panel__title{text-decoration:underline}.tn-expansion-panel--title-link .tn-expansion-panel__header:focus .tn-expansion-panel__title{text-decoration:underline}.tn-expansion-panel__header{width:100%;background:none;border:none;display:flex;align-items:center;justify-content:space-between;cursor:pointer;font-family:inherit;text-align:left;transition:background-color .2s ease}.tn-expansion-panel--bordered .tn-expansion-panel__header,.tn-expansion-panel--bordered.tn-expansion-panel--expanded .tn-expansion-panel__header{border-bottom:1px solid var(--tn-lines, #e5e7eb)}.tn-expansion-panel__header:hover:not(:disabled){background-color:var(--tn-alt-bg1, rgba(0, 0, 0, .05))}.tn-expansion-panel__header:focus{outline:2px solid var(--tn-primary, #3b82f6);outline-offset:-2px}.tn-expansion-panel__header:disabled{cursor:not-allowed}.tn-expansion-panel__title{margin:0;line-height:1.5;flex:1;transition:text-decoration .2s ease}.tn-expansion-panel__indicator{display:flex;align-items:center;justify-content:center;margin-left:16px;transition:transform .2s ease,color .2s ease}.tn-expansion-panel__indicator svg{transition:transform .2s ease}.tn-expansion-panel__content{overflow:hidden}.tn-expansion-panel__content:not(.tn-expansion-panel--expanded){border-bottom:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], animations: [expandCollapseAnimation] });
2832
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnExpansionPanelComponent, isStandalone: true, selector: "tn-expansion-panel", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, elevation: { classPropertyName: "elevation", publicName: "elevation", isSignal: true, isRequired: false, transformFunction: null }, padding: { classPropertyName: "padding", publicName: "padding", isSignal: true, isRequired: false, transformFunction: null }, bordered: { classPropertyName: "bordered", publicName: "bordered", isSignal: true, isRequired: false, transformFunction: null }, background: { classPropertyName: "background", publicName: "background", isSignal: true, isRequired: false, transformFunction: null }, expanded: { classPropertyName: "expanded", publicName: "expanded", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, titleStyle: { classPropertyName: "titleStyle", publicName: "titleStyle", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { expandedChange: "expandedChange", toggleEvent: "toggleEvent" }, ngImport: i0, template: "<div [ngClass]=\"classes()\">\n <button class=\"tn-expansion-panel__header\"\n [disabled]=\"disabled()\"\n [attr.aria-expanded]=\"effectiveExpanded()\"\n [attr.aria-controls]=\"contentId\"\n [attr.aria-disabled]=\"disabled()\"\n (click)=\"toggle()\">\n @if (title()) {\n <div class=\"tn-expansion-panel__title\">\n {{ title() }}\n </div>\n }\n <ng-content select=\"[slot=title]\" />\n\n <div class=\"tn-expansion-panel__indicator\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"m6 9 6 6 6-6\"/>\n </svg>\n </div>\n </button>\n\n <div class=\"tn-expansion-panel__content\"\n [id]=\"contentId\"\n [attr.aria-hidden]=\"!effectiveExpanded()\"\n [@expandCollapse]=\"effectiveExpanded() ? 'expanded' : 'collapsed'\">\n <ng-content />\n </div>\n</div>", styles: [".tn-expansion-panel{border-radius:8px;transition:box-shadow .3s ease;overflow:hidden}.tn-expansion-panel--elevation-none{box-shadow:none}.tn-expansion-panel--elevation-low{box-shadow:0 1px 3px #0000001a}.tn-expansion-panel--elevation-medium{box-shadow:0 4px 6px #0000001a}.tn-expansion-panel--elevation-high{box-shadow:0 10px 15px #0000001a}.tn-expansion-panel--bordered{border:1px solid var(--tn-lines, #e5e7eb)}.tn-expansion-panel--background{background-color:var(--tn-bg2, #ffffff)}.tn-expansion-panel--disabled{opacity:.6;cursor:not-allowed}.tn-expansion-panel--disabled .tn-expansion-panel__header{cursor:not-allowed}.tn-expansion-panel--expanded .tn-expansion-panel__indicator svg{transform:rotate(180deg)}.tn-expansion-panel--padding-small .tn-expansion-panel__header{padding:12px 16px}.tn-expansion-panel--padding-small .tn-expansion-panel__content{padding:0 16px 16px}.tn-expansion-panel--padding-medium .tn-expansion-panel__header{padding:16px 24px}.tn-expansion-panel--padding-medium .tn-expansion-panel__content{padding:0 24px 24px}.tn-expansion-panel--padding-large .tn-expansion-panel__header{padding:24px 32px}.tn-expansion-panel--padding-large .tn-expansion-panel__content{padding:0 32px 32px}.tn-expansion-panel--title-header .tn-expansion-panel__title{font-size:1.125rem;font-weight:600;color:var(--tn-fg1, #1f2937)}.tn-expansion-panel--title-header .tn-expansion-panel__indicator{color:var(--tn-fg1, #1f2937)}.tn-expansion-panel--title-body .tn-expansion-panel__title{font-size:1rem;font-weight:400;color:var(--tn-fg1, #1f2937)}.tn-expansion-panel--title-body .tn-expansion-panel__indicator{color:var(--tn-fg1, #1f2937)}.tn-expansion-panel--title-link .tn-expansion-panel__title{font-size:1rem;font-weight:400;color:var(--tn-primary, #3b82f6);text-decoration:none}.tn-expansion-panel--title-link .tn-expansion-panel__indicator{color:var(--tn-primary, #3b82f6)}.tn-expansion-panel--title-link .tn-expansion-panel__header:hover:not(:disabled) .tn-expansion-panel__title{text-decoration:underline}.tn-expansion-panel--title-link .tn-expansion-panel__header:focus .tn-expansion-panel__title{text-decoration:underline}.tn-expansion-panel__header{width:100%;background:none;border:none;display:flex;align-items:center;justify-content:space-between;cursor:pointer;font-family:inherit;text-align:left;transition:background-color .2s ease}.tn-expansion-panel--bordered .tn-expansion-panel__header,.tn-expansion-panel--bordered.tn-expansion-panel--expanded .tn-expansion-panel__header{border-bottom:1px solid var(--tn-lines, #e5e7eb)}.tn-expansion-panel__header:hover:not(:disabled){background-color:var(--tn-alt-bg1, rgba(0, 0, 0, .05))}.tn-expansion-panel__header:focus{outline:2px solid var(--tn-primary, #3b82f6);outline-offset:-2px}.tn-expansion-panel__header:disabled{cursor:not-allowed}.tn-expansion-panel__title{margin:0;line-height:1.5;flex:1;transition:text-decoration .2s ease}.tn-expansion-panel__indicator{display:flex;align-items:center;justify-content:center;margin-left:16px;transition:transform .2s ease,color .2s ease}.tn-expansion-panel__indicator svg{transition:transform .2s ease}.tn-expansion-panel__content{overflow:hidden}.tn-expansion-panel__content:not(.tn-expansion-panel--expanded){border-bottom:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], animations: [expandCollapseAnimation] });
2589
2833
  }
2590
2834
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnExpansionPanelComponent, decorators: [{
2591
2835
  type: Component,
@@ -2696,7 +2940,7 @@ class TnCheckboxComponent {
2696
2940
  useExisting: forwardRef(() => TnCheckboxComponent),
2697
2941
  multi: true
2698
2942
  }
2699
- ], queries: [{ propertyName: "labelContent", predicate: TnCheckboxLabelDirective, isSignal: true }], viewQueries: [{ propertyName: "checkboxEl", first: true, predicate: ["checkboxEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div [ngClass]=\"classes()\">\n <label class=\"tn-checkbox__label\" [for]=\"id\">\n <input\n #checkboxEl\n type=\"checkbox\"\n class=\"tn-checkbox__input\"\n [id]=\"id\"\n [checked]=\"effectiveChecked()\"\n [disabled]=\"isDisabled()\"\n [required]=\"required()\"\n [indeterminate]=\"indeterminate()\"\n [attr.data-testid]=\"testId()\"\n [attr.aria-label]=\"hasProjectedLabel() ? label() : null\"\n [attr.aria-describedby]=\"error() ? id + '-error' : null\"\n [attr.aria-invalid]=\"error() ? 'true' : null\"\n (change)=\"onCheckboxChange($event)\"\n />\n <span class=\"tn-checkbox__checkmark\"></span>\n @if (!hideLabel()) {\n <span class=\"tn-checkbox__text\">\n @if (hasProjectedLabel()) {\n <ng-content select=\"[tnCheckboxLabel]\" />\n } @else {\n {{ label() }}\n }\n </span>\n }\n </label>\n\n @if (error()) {\n <div\n class=\"tn-checkbox__error\"\n role=\"alert\"\n aria-live=\"polite\"\n [id]=\"id + '-error'\"\n >\n {{ error() }}\n </div>\n }\n</div>", styles: [".tn-checkbox{display:flex;flex-direction:column;gap:4px}.tn-checkbox__label{display:flex;align-items:center;gap:8px;cursor:pointer;-webkit-user-select:none;user-select:none;font-family:var(--tn-font-family-body, \"Inter\", sans-serif);font-size:14px;line-height:1.5;color:var(--tn-fg1, #333)}.tn-checkbox__label:hover:not(.tn-checkbox--disabled) .tn-checkbox__checkmark{border-color:var(--tn-primary, #0095d5)}.tn-checkbox__input{position:absolute;opacity:0;cursor:pointer;height:0;width:0}.tn-checkbox__input:checked~.tn-checkbox__checkmark{background-color:var(--tn-primary, #0095d5);border-color:var(--tn-primary, #0095d5)}.tn-checkbox__input:checked~.tn-checkbox__checkmark:after{display:block}.tn-checkbox__input:indeterminate~.tn-checkbox__checkmark{background-color:var(--tn-primary, #0095d5);border-color:var(--tn-primary, #0095d5)}.tn-checkbox__input:indeterminate~.tn-checkbox__checkmark:after{display:block;content:\"\";left:4px;top:8px;width:8px;height:2px;background:var(--tn-primary-txt, #fff);border-radius:1px;transform:none}.tn-checkbox__input:focus~.tn-checkbox__checkmark{outline:2px solid var(--tn-primary, #0095d5);outline-offset:2px}.tn-checkbox__input:disabled~.tn-checkbox__checkmark{background-color:var(--tn-bg2, #f5f5f5);border-color:var(--tn-lines, #e0e0e0);cursor:not-allowed}.tn-checkbox__input:disabled:checked~.tn-checkbox__checkmark{background-color:var(--tn-lines, #e0e0e0);border-color:var(--tn-lines, #e0e0e0)}.tn-checkbox__checkmark{position:relative;height:16px;width:16px;background-color:var(--tn-bg1, #fff);border:1px solid var(--tn-lines, #ccc);border-radius:2px;transition:all .2s ease;flex-shrink:0}.tn-checkbox__checkmark:after{content:\"\";position:absolute;display:none;left:5px;top:2px;width:4px;height:8px;border:solid var(--tn-primary-txt, #fff);border-width:0 2px 2px 0;transform:rotate(45deg)}.tn-checkbox__text{flex:1;min-width:0}.tn-checkbox__error{color:var(--tn-red, #dc2626);font-size:12px;font-family:var(--tn-font-family-body, \"Inter\", sans-serif);margin-top:4px;display:flex;align-items:center;gap:4px}.tn-checkbox--disabled .tn-checkbox__label{cursor:not-allowed;color:var(--tn-fg2, #666);opacity:.6}.tn-checkbox--disabled .tn-checkbox__text{color:var(--tn-fg2, #666)}.tn-checkbox--error .tn-checkbox__checkmark{border-color:var(--tn-red, #dc2626)}.tn-checkbox--indeterminate .tn-checkbox__checkmark{background-color:var(--tn-primary, #0095d5);border-color:var(--tn-primary, #0095d5)}.tn-checkbox__input:focus-visible~.tn-checkbox__checkmark{outline:2px solid var(--tn-primary, #0095d5);outline-offset:2px}@media(prefers-contrast:high){.tn-checkbox__checkmark{border-width:2px}}@media(prefers-reduced-motion:reduce){.tn-checkbox__checkmark{transition:none}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: A11yModule }] });
2943
+ ], queries: [{ propertyName: "labelContent", predicate: TnCheckboxLabelDirective, isSignal: true }], viewQueries: [{ propertyName: "checkboxEl", first: true, predicate: ["checkboxEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div [ngClass]=\"classes()\">\n <label class=\"tn-checkbox__label\" [for]=\"id\">\n <input\n #checkboxEl\n type=\"checkbox\"\n class=\"tn-checkbox__input\"\n [id]=\"id\"\n [checked]=\"effectiveChecked()\"\n [disabled]=\"isDisabled()\"\n [required]=\"required()\"\n [indeterminate]=\"indeterminate()\"\n [attr.data-testid]=\"testId()\"\n [attr.aria-label]=\"hasProjectedLabel() ? label() : null\"\n [attr.aria-describedby]=\"error() ? id + '-error' : null\"\n [attr.aria-invalid]=\"error() ? 'true' : null\"\n (change)=\"onCheckboxChange($event)\"\n />\n <span class=\"tn-checkbox__checkmark\"></span>\n @if (!hideLabel()) {\n <span class=\"tn-checkbox__text\">\n @if (hasProjectedLabel()) {\n <ng-content select=\"[tnCheckboxLabel]\" />\n } @else {\n {{ label() }}\n }\n </span>\n }\n </label>\n\n @if (error()) {\n <div\n class=\"tn-checkbox__error\"\n role=\"alert\"\n aria-live=\"polite\"\n [id]=\"id + '-error'\"\n >\n {{ error() }}\n </div>\n }\n</div>", styles: [".tn-checkbox{display:flex;flex-direction:column;gap:4px}.tn-checkbox__label{display:flex;align-items:center;gap:8px;cursor:pointer;-webkit-user-select:none;user-select:none;font-family:var(--tn-font-family-body, \"Inter\", sans-serif);font-size:14px;line-height:1.5;color:var(--tn-fg1, #333)}.tn-checkbox__label:hover:not(.tn-checkbox--disabled) .tn-checkbox__checkmark{border-color:var(--tn-primary, #0095d5)}.tn-checkbox__input{position:absolute;opacity:0;cursor:pointer;height:0;width:0}.tn-checkbox__input:checked~.tn-checkbox__checkmark{background-color:var(--tn-primary, #0095d5);border-color:var(--tn-primary, #0095d5)}.tn-checkbox__input:checked~.tn-checkbox__checkmark:after{display:block}.tn-checkbox__input:indeterminate~.tn-checkbox__checkmark{background-color:var(--tn-primary, #0095d5);border-color:var(--tn-primary, #0095d5)}.tn-checkbox__input:indeterminate~.tn-checkbox__checkmark:after{display:block;content:\"\";left:4px;top:8px;width:8px;height:2px;background:var(--tn-primary-txt, #fff);border-radius:1px;transform:none}.tn-checkbox__input:focus~.tn-checkbox__checkmark{outline:2px solid var(--tn-primary, #0095d5);outline-offset:2px}.tn-checkbox__input:disabled~.tn-checkbox__checkmark{background-color:var(--tn-bg2, #f5f5f5);border-color:var(--tn-lines, #e0e0e0);cursor:not-allowed}.tn-checkbox__input:disabled:checked~.tn-checkbox__checkmark{background-color:var(--tn-lines, #e0e0e0);border-color:var(--tn-lines, #e0e0e0)}.tn-checkbox__checkmark{position:relative;height:16px;width:16px;background-color:var(--tn-bg1, #fff);border:1px solid var(--tn-lines, #ccc);border-radius:2px;transition:all .2s ease;flex-shrink:0}.tn-checkbox__checkmark:after{content:\"\";position:absolute;display:none;left:5px;top:2px;width:4px;height:8px;border:solid var(--tn-primary-txt, #fff);border-width:0 2px 2px 0;transform:rotate(45deg)}.tn-checkbox__text{flex:1;min-width:0}.tn-checkbox__error{color:var(--tn-red, #dc2626);font-size:12px;font-family:var(--tn-font-family-body, \"Inter\", sans-serif);margin-top:4px;display:flex;align-items:center;gap:4px}.tn-checkbox--disabled .tn-checkbox__label{cursor:not-allowed;color:var(--tn-fg2, #666);opacity:.6}.tn-checkbox--disabled .tn-checkbox__text{color:var(--tn-fg2, #666)}.tn-checkbox--error .tn-checkbox__checkmark{border-color:var(--tn-red, #dc2626)}.tn-checkbox--indeterminate .tn-checkbox__checkmark{background-color:var(--tn-primary, #0095d5);border-color:var(--tn-primary, #0095d5)}.tn-checkbox__input:focus-visible~.tn-checkbox__checkmark{outline:2px solid var(--tn-primary, #0095d5);outline-offset:2px}@media(prefers-contrast:high){.tn-checkbox__checkmark{border-width:2px}}@media(prefers-reduced-motion:reduce){.tn-checkbox__checkmark{transition:none}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: A11yModule }] });
2700
2944
  }
2701
2945
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnCheckboxComponent, decorators: [{
2702
2946
  type: Component,
@@ -2985,7 +3229,7 @@ class TnRadioComponent {
2985
3229
  useExisting: forwardRef(() => TnRadioComponent),
2986
3230
  multi: true
2987
3231
  }
2988
- ], viewQueries: [{ propertyName: "radioEl", first: true, predicate: ["radioEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div [ngClass]=\"classes()\">\n <label class=\"tn-radio__label\" [for]=\"id\">\n <input\n #radioEl\n type=\"radio\"\n class=\"tn-radio__input\"\n [id]=\"id\"\n [name]=\"name()\"\n [value]=\"value()\"\n [checked]=\"checked\"\n [disabled]=\"isDisabled()\"\n [required]=\"required()\"\n [attr.data-testid]=\"testId()\"\n [attr.aria-describedby]=\"error() ? id + '-error' : null\"\n [attr.aria-invalid]=\"error() ? 'true' : null\"\n (change)=\"onRadioChange($event)\"\n />\n <span class=\"tn-radio__checkmark\"></span>\n <span class=\"tn-radio__text\">{{ label() }}</span>\n </label>\n\n @if (error()) {\n <div\n class=\"tn-radio__error\"\n role=\"alert\"\n aria-live=\"polite\"\n [id]=\"id + '-error'\"\n >\n {{ error() }}\n </div>\n }\n</div>", styles: [".tn-radio{display:inline-block;margin-bottom:.5rem}.tn-radio__label{display:flex;align-items:center;cursor:pointer;-webkit-user-select:none;user-select:none;gap:.5rem}.tn-radio__label:hover .tn-radio__checkmark{border-color:var(--tn-primary, #007cba)}.tn-radio__input{position:absolute;opacity:0;cursor:pointer;height:0;width:0}.tn-radio__input:focus+.tn-radio__checkmark{outline:2px solid var(--tn-primary, #007cba);outline-offset:2px}.tn-radio__input:checked+.tn-radio__checkmark{border-color:var(--tn-primary, #007cba);background-color:var(--tn-primary, #007cba)}.tn-radio__input:checked+.tn-radio__checkmark:after{display:block}.tn-radio__input:disabled+.tn-radio__checkmark{border-color:var(--tn-lines, #e5e7eb);background-color:var(--tn-alt-bg1, #f8f9fa);cursor:not-allowed}.tn-radio__checkmark{position:relative;height:18px;width:18px;border:2px solid var(--tn-lines, #e5e7eb);border-radius:50%;background-color:transparent;transition:all .2s ease;flex-shrink:0}.tn-radio__checkmark:after{content:\"\";position:absolute;display:none;top:50%;left:50%;width:8px;height:8px;border-radius:50%;background-color:#fff;transform:translate(-50%,-50%)}.tn-radio__text{color:var(--tn-fg1, #000000);font-size:14px;line-height:1.4}.tn-radio__error{margin-top:.25rem;font-size:12px;color:var(--tn-red, #dc3545)}.tn-radio--disabled .tn-radio__label{cursor:not-allowed;opacity:.6}.tn-radio--disabled .tn-radio__text{color:var(--tn-fg2, #6c757d)}.tn-radio--error .tn-radio__checkmark{border-color:var(--tn-red, #dc3545)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: A11yModule }] });
3232
+ ], viewQueries: [{ propertyName: "radioEl", first: true, predicate: ["radioEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div [ngClass]=\"classes()\">\n <label class=\"tn-radio__label\" [for]=\"id\">\n <input\n #radioEl\n type=\"radio\"\n class=\"tn-radio__input\"\n [id]=\"id\"\n [name]=\"name()\"\n [value]=\"value()\"\n [checked]=\"checked\"\n [disabled]=\"isDisabled()\"\n [required]=\"required()\"\n [attr.data-testid]=\"testId()\"\n [attr.aria-describedby]=\"error() ? id + '-error' : null\"\n [attr.aria-invalid]=\"error() ? 'true' : null\"\n (change)=\"onRadioChange($event)\"\n />\n <span class=\"tn-radio__checkmark\"></span>\n <span class=\"tn-radio__text\">{{ label() }}</span>\n </label>\n\n @if (error()) {\n <div\n class=\"tn-radio__error\"\n role=\"alert\"\n aria-live=\"polite\"\n [id]=\"id + '-error'\"\n >\n {{ error() }}\n </div>\n }\n</div>", styles: [".tn-radio{display:inline-block;margin-bottom:.5rem}.tn-radio__label{display:flex;align-items:center;cursor:pointer;-webkit-user-select:none;user-select:none;gap:.5rem}.tn-radio__label:hover .tn-radio__checkmark{border-color:var(--tn-primary, #007cba)}.tn-radio__input{position:absolute;opacity:0;cursor:pointer;height:0;width:0}.tn-radio__input:focus+.tn-radio__checkmark{outline:2px solid var(--tn-primary, #007cba);outline-offset:2px}.tn-radio__input:checked+.tn-radio__checkmark{border-color:var(--tn-primary, #007cba);background-color:var(--tn-primary, #007cba)}.tn-radio__input:checked+.tn-radio__checkmark:after{display:block}.tn-radio__input:disabled+.tn-radio__checkmark{border-color:var(--tn-lines, #e5e7eb);background-color:var(--tn-alt-bg1, #f8f9fa);cursor:not-allowed}.tn-radio__checkmark{position:relative;height:18px;width:18px;border:2px solid var(--tn-lines, #e5e7eb);border-radius:50%;background-color:transparent;transition:all .2s ease;flex-shrink:0}.tn-radio__checkmark:after{content:\"\";position:absolute;display:none;top:50%;left:50%;width:8px;height:8px;border-radius:50%;background-color:#fff;transform:translate(-50%,-50%)}.tn-radio__text{color:var(--tn-fg1, #000000);font-size:14px;line-height:1.4}.tn-radio__error{margin-top:.25rem;font-size:12px;color:var(--tn-red, #dc3545)}.tn-radio--disabled .tn-radio__label{cursor:not-allowed;opacity:.6}.tn-radio--disabled .tn-radio__text{color:var(--tn-fg2, #6c757d)}.tn-radio--error .tn-radio__checkmark{border-color:var(--tn-red, #dc3545)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: A11yModule }] });
2989
3233
  }
2990
3234
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnRadioComponent, decorators: [{
2991
3235
  type: Component,
@@ -3042,7 +3286,7 @@ class TnTabComponent {
3042
3286
  return !!(this.hasIconContent() || this.iconTemplate() || this.icon());
3043
3287
  }, ...(ngDevMode ? [{ debugName: "hasIcon" }] : []));
3044
3288
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3045
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnTabComponent, isStandalone: true, selector: "tn-tab", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, iconTemplate: { classPropertyName: "iconTemplate", publicName: "iconTemplate", isSignal: true, isRequired: false, transformFunction: null }, testId: { classPropertyName: "testId", publicName: "testId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selected" }, queries: [{ propertyName: "iconContent", first: true, predicate: ["iconContent"], descendants: true, isSignal: true }], ngImport: i0, template: "<button\n role=\"tab\"\n type=\"button\"\n [ngClass]=\"classes()\"\n [attr.data-testid]=\"testId()\"\n [attr.aria-selected]=\"isActive()\"\n [attr.aria-disabled]=\"disabled()\"\n [attr.tabindex]=\"tabIndex()\"\n [disabled]=\"disabled()\"\n (click)=\"onClick()\"\n (keydown)=\"onKeydown($event)\"\n>\n @if (hasIcon()) {\n <span class=\"tn-tab__icon\">\n @if (iconContent()) {\n <ng-container *ngTemplateOutlet=\"iconContent()\" />\n } @else if (iconTemplate()) {\n <ng-container *ngTemplateOutlet=\"iconTemplate()\" />\n } @else {\n <span [innerHTML]=\"icon()\"></span>\n }\n </span>\n }\n <span class=\"tn-tab__label\">\n {{ label() }}\n <ng-content />\n </span>\n</button>", styles: [".tn-tab{display:flex;align-items:center;justify-content:flex-start;gap:8px;padding:12px 16px;border:none;border-bottom:none;background:transparent;color:var(--tn-fg2, #666);font-family:var(--tn-font-family-body, \"Inter\", sans-serif);font-size:14px;font-weight:500;line-height:1.5;cursor:pointer;white-space:nowrap;min-width:0;flex-shrink:0}.tn-tab:hover:not(.tn-tab--disabled):not(.tn-tab--active){background-color:var(--tn-alt-bg1, #f5f5f5);color:var(--tn-fg1, #333)}.tn-tab:focus-visible{outline:2px solid var(--tn-primary, #0095d5);outline-offset:-2px;border-radius:4px}.tn-tab--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.tn-tab__icon{display:flex;align-items:center;justify-content:center;width:16px;height:16px;font-size:14px;flex-shrink:0}.tn-tab__label{display:flex;align-items:center;min-width:0;text-overflow:ellipsis;overflow:hidden}@media(prefers-contrast:high){.tn-tab{border-width:3px}.tn-tab:focus-visible{outline-width:3px}}:host-context(.tn-tabs--vertical){width:100%}:host-context(.tn-tabs--vertical) .tn-tab{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: A11yModule }] });
3289
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnTabComponent, isStandalone: true, selector: "tn-tab", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, iconTemplate: { classPropertyName: "iconTemplate", publicName: "iconTemplate", isSignal: true, isRequired: false, transformFunction: null }, testId: { classPropertyName: "testId", publicName: "testId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selected" }, queries: [{ propertyName: "iconContent", first: true, predicate: ["iconContent"], descendants: true, isSignal: true }], ngImport: i0, template: "<button\n role=\"tab\"\n type=\"button\"\n [ngClass]=\"classes()\"\n [attr.data-testid]=\"testId()\"\n [attr.aria-selected]=\"isActive()\"\n [attr.aria-disabled]=\"disabled()\"\n [attr.tabindex]=\"tabIndex()\"\n [disabled]=\"disabled()\"\n (click)=\"onClick()\"\n (keydown)=\"onKeydown($event)\"\n>\n @if (hasIcon()) {\n <span class=\"tn-tab__icon\">\n @if (iconContent()) {\n <ng-container *ngTemplateOutlet=\"iconContent()\" />\n } @else if (iconTemplate()) {\n <ng-container *ngTemplateOutlet=\"iconTemplate()\" />\n } @else {\n <span [innerHTML]=\"icon()\"></span>\n }\n </span>\n }\n <span class=\"tn-tab__label\">\n {{ label() }}\n <ng-content />\n </span>\n</button>", styles: [".tn-tab{display:flex;align-items:center;justify-content:flex-start;gap:8px;padding:12px 16px;border:none;border-bottom:none;background:transparent;color:var(--tn-fg2, #666);font-family:var(--tn-font-family-body, \"Inter\", sans-serif);font-size:14px;font-weight:500;line-height:1.5;cursor:pointer;white-space:nowrap;min-width:0;flex-shrink:0}.tn-tab:hover:not(.tn-tab--disabled):not(.tn-tab--active){background-color:var(--tn-alt-bg1, #f5f5f5);color:var(--tn-fg1, #333)}.tn-tab:focus-visible{outline:2px solid var(--tn-primary, #0095d5);outline-offset:-2px;border-radius:4px}.tn-tab--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.tn-tab__icon{display:flex;align-items:center;justify-content:center;width:16px;height:16px;font-size:14px;flex-shrink:0}.tn-tab__label{display:flex;align-items:center;min-width:0;text-overflow:ellipsis;overflow:hidden}@media(prefers-contrast:high){.tn-tab{border-width:3px}.tn-tab:focus-visible{outline-width:3px}}:host-context(.tn-tabs--vertical){width:100%}:host-context(.tn-tabs--vertical) .tn-tab{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: A11yModule }] });
3046
3290
  }
3047
3291
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTabComponent, decorators: [{
3048
3292
  type: Component,
@@ -3080,7 +3324,7 @@ class TnTabPanelComponent {
3080
3324
  this.hasBeenActive.set(true);
3081
3325
  }
3082
3326
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTabPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3083
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnTabPanelComponent, isStandalone: true, selector: "tn-tab-panel", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, lazyLoad: { classPropertyName: "lazyLoad", publicName: "lazyLoad", isSignal: true, isRequired: false, transformFunction: null }, testId: { classPropertyName: "testId", publicName: "testId", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n role=\"tabpanel\"\n [ngClass]=\"classes()\"\n [attr.data-testid]=\"testId()\"\n [attr.aria-hidden]=\"!isActive()\"\n [attr.aria-labelledby]=\"'tab-' + index()\"\n [attr.tabindex]=\"isActive() ? 0 : -1\"\n>\n @if (shouldRender()) {\n <div class=\"tn-tab-panel__content\">\n <ng-content />\n </div>\n }\n</div>", styles: [".tn-tab-panel{display:block;width:100%;height:100%;min-width:0;background-color:var(--tn-bg1, #fff);box-sizing:border-box}.tn-tab-panel--hidden{display:none}.tn-tab-panel--active{display:block}.tn-tab-panel:focus-visible{outline:2px solid var(--tn-primary, #0095d5);outline-offset:-2px;border-radius:4px}.tn-tab-panel__content{padding:0 16px;height:100%;overflow:auto;min-height:0;display:flex;flex-direction:column}@media(prefers-reduced-motion:reduce){.tn-tab-panel{transition:none}}@media(prefers-contrast:high){.tn-tab-panel{border:1px solid var(--tn-lines, #e0e0e0)}.tn-tab-panel:focus-visible{outline-width:3px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: A11yModule }] });
3327
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnTabPanelComponent, isStandalone: true, selector: "tn-tab-panel", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, lazyLoad: { classPropertyName: "lazyLoad", publicName: "lazyLoad", isSignal: true, isRequired: false, transformFunction: null }, testId: { classPropertyName: "testId", publicName: "testId", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n role=\"tabpanel\"\n [ngClass]=\"classes()\"\n [attr.data-testid]=\"testId()\"\n [attr.aria-hidden]=\"!isActive()\"\n [attr.aria-labelledby]=\"'tab-' + index()\"\n [attr.tabindex]=\"isActive() ? 0 : -1\"\n>\n @if (shouldRender()) {\n <div class=\"tn-tab-panel__content\">\n <ng-content />\n </div>\n }\n</div>", styles: [".tn-tab-panel{display:block;width:100%;height:100%;min-width:0;background-color:var(--tn-bg1, #fff);box-sizing:border-box}.tn-tab-panel--hidden{display:none}.tn-tab-panel--active{display:block}.tn-tab-panel:focus-visible{outline:2px solid var(--tn-primary, #0095d5);outline-offset:-2px;border-radius:4px}.tn-tab-panel__content{padding:0 16px;height:100%;overflow:auto;min-height:0;display:flex;flex-direction:column}@media(prefers-reduced-motion:reduce){.tn-tab-panel{transition:none}}@media(prefers-contrast:high){.tn-tab-panel{border:1px solid var(--tn-lines, #e0e0e0)}.tn-tab-panel:focus-visible{outline-width:3px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: A11yModule }] });
3084
3328
  }
3085
3329
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTabPanelComponent, decorators: [{
3086
3330
  type: Component,
@@ -3356,7 +3600,7 @@ class TnTabsComponent {
3356
3600
  return classes.join(' ');
3357
3601
  }, ...(ngDevMode ? [{ debugName: "classes" }] : []));
3358
3602
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3359
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnTabsComponent, isStandalone: true, selector: "tn-tabs", inputs: { selectedIndex: { classPropertyName: "selectedIndex", publicName: "selectedIndex", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, highlightPosition: { classPropertyName: "highlightPosition", publicName: "highlightPosition", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedIndexChange: "selectedIndexChange", tabChange: "tabChange" }, queries: [{ propertyName: "tabs", predicate: TnTabComponent, isSignal: true }, { propertyName: "panels", predicate: TnTabPanelComponent, isSignal: true }], viewQueries: [{ propertyName: "tabHeader", first: true, predicate: ["tabHeader"], descendants: true, isSignal: true }], ngImport: i0, template: "<div role=\"tablist\" [ngClass]=\"classes()\" [attr.aria-orientation]=\"orientation()\">\n <div #tabHeader class=\"tn-tabs__header\">\n <ng-content select=\"tn-tab\" />\n @if (highlightBarVisible()) {\n <div class=\"tn-tabs__highlight-bar\"\n [style.left.px]=\"highlightBarLeft()\"\n [style.width.px]=\"highlightBarWidth()\"\n [style.top.px]=\"highlightBarTop()\"\n [style.height.px]=\"highlightBarHeight()\">\n </div>\n }\n </div>\n\n <div class=\"tn-tabs__content\">\n <ng-content select=\"tn-tab-panel\" />\n </div>\n</div>", styles: [".tn-tabs{display:flex;flex-direction:column;width:100%;height:100%;min-width:0;font-family:var(--tn-font-family-body, \"Inter\", sans-serif)}.tn-tabs--disabled{opacity:.6;pointer-events:none}.tn-tabs--vertical{flex-direction:row}.tn-tabs--vertical .tn-tabs__header{flex-direction:column;border-bottom:none;border-right:1px solid var(--tn-lines, #e0e0e0);min-width:240px;width:auto}.tn-tabs--vertical .tn-tabs__content{flex:1;min-width:0}.tn-tabs--vertical .tn-tabs__highlight-bar{bottom:auto;height:auto}.tn-tabs--vertical .tn-tab{justify-content:flex-start;text-align:left;width:100%}.tn-tabs--vertical .tn-tab:hover:not(.tn-tab--disabled){background-color:var(--tn-alt-bg1, #f5f5f5);color:var(--tn-fg1, #333)}.tn-tabs__header{display:flex;background-color:var(--tn-bg1, #fff);position:relative;border-bottom:1px solid var(--tn-lines, #e0e0e0)}.tn-tabs__highlight-bar{position:absolute;bottom:-1px;height:2px;background-color:var(--tn-primary, #0095d5);transition:left .3s ease,width .3s ease,top .3s ease,height .3s ease;z-index:1}.tn-tabs__content{flex:1;position:relative;background-color:var(--tn-bg1, #fff);min-height:0;width:100%;overflow:hidden}@media(max-width:768px){.tn-tabs__header{overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none}.tn-tabs__header::-webkit-scrollbar{display:none}.tn-tabs--vertical .tn-tabs__header{overflow-y:auto;overflow-x:visible;max-height:300px}}@media(prefers-reduced-motion:reduce){.tn-tabs__highlight-bar{transition:none}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: A11yModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3603
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnTabsComponent, isStandalone: true, selector: "tn-tabs", inputs: { selectedIndex: { classPropertyName: "selectedIndex", publicName: "selectedIndex", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, highlightPosition: { classPropertyName: "highlightPosition", publicName: "highlightPosition", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedIndexChange: "selectedIndexChange", tabChange: "tabChange" }, queries: [{ propertyName: "tabs", predicate: TnTabComponent, isSignal: true }, { propertyName: "panels", predicate: TnTabPanelComponent, isSignal: true }], viewQueries: [{ propertyName: "tabHeader", first: true, predicate: ["tabHeader"], descendants: true, isSignal: true }], ngImport: i0, template: "<div role=\"tablist\" [ngClass]=\"classes()\" [attr.aria-orientation]=\"orientation()\">\n <div #tabHeader class=\"tn-tabs__header\">\n <ng-content select=\"tn-tab\" />\n @if (highlightBarVisible()) {\n <div class=\"tn-tabs__highlight-bar\"\n [style.left.px]=\"highlightBarLeft()\"\n [style.width.px]=\"highlightBarWidth()\"\n [style.top.px]=\"highlightBarTop()\"\n [style.height.px]=\"highlightBarHeight()\">\n </div>\n }\n </div>\n\n <div class=\"tn-tabs__content\">\n <ng-content select=\"tn-tab-panel\" />\n </div>\n</div>", styles: [".tn-tabs{display:flex;flex-direction:column;width:100%;height:100%;min-width:0;font-family:var(--tn-font-family-body, \"Inter\", sans-serif)}.tn-tabs--disabled{opacity:.6;pointer-events:none}.tn-tabs--vertical{flex-direction:row}.tn-tabs--vertical .tn-tabs__header{flex-direction:column;border-bottom:none;border-right:1px solid var(--tn-lines, #e0e0e0);min-width:240px;width:auto}.tn-tabs--vertical .tn-tabs__content{flex:1;min-width:0}.tn-tabs--vertical .tn-tabs__highlight-bar{bottom:auto;height:auto}.tn-tabs--vertical .tn-tab{justify-content:flex-start;text-align:left;width:100%}.tn-tabs--vertical .tn-tab:hover:not(.tn-tab--disabled){background-color:var(--tn-alt-bg1, #f5f5f5);color:var(--tn-fg1, #333)}.tn-tabs__header{display:flex;background-color:var(--tn-bg1, #fff);position:relative;border-bottom:1px solid var(--tn-lines, #e0e0e0)}.tn-tabs__highlight-bar{position:absolute;bottom:-1px;height:2px;background-color:var(--tn-primary, #0095d5);transition:left .3s ease,width .3s ease,top .3s ease,height .3s ease;z-index:1}.tn-tabs__content{flex:1;position:relative;background-color:var(--tn-bg1, #fff);min-height:0;width:100%;overflow:hidden}@media(max-width:768px){.tn-tabs__header{overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none}.tn-tabs__header::-webkit-scrollbar{display:none}.tn-tabs--vertical .tn-tabs__header{overflow-y:auto;overflow-x:visible;max-height:300px}}@media(prefers-reduced-motion:reduce){.tn-tabs__highlight-bar{transition:none}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: A11yModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3360
3604
  }
3361
3605
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTabsComponent, decorators: [{
3362
3606
  type: Component,
@@ -5094,7 +5338,7 @@ class TnTableComponent {
5094
5338
  return row[column];
5095
5339
  }
5096
5340
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5097
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnTableComponent, isStandalone: true, selector: "tn-table", inputs: { dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: false, transformFunction: null }, displayedColumns: { classPropertyName: "displayedColumns", publicName: "displayedColumns", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "tn-table" }, queries: [{ propertyName: "columnDefs", predicate: TnTableColumnDirective, isSignal: true }], ngImport: i0, template: "<table class=\"tn-table__table\">\n <!-- Header Row -->\n <thead class=\"tn-table__header\">\n <tr class=\"tn-table__header-row\">\n @for (column of displayedColumns(); track $index) {\n <th\n class=\"tn-table__header-cell\"\n [attr.data-column]=\"column\">\n @if (getColumnDef(column)?.headerTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"getColumnDef(column)?.headerTemplate() || null\" />\n }\n @if (!getColumnDef(column)?.headerTemplate()) {\n <span>{{ column }}</span>\n }\n </th>\n }\n </tr>\n </thead>\n\n <!-- Data Rows -->\n <tbody class=\"tn-table__body\">\n @for (row of data(); track $index) {\n <tr class=\"tn-table__row\">\n @for (column of displayedColumns(); track $index) {\n <td\n class=\"tn-table__cell\"\n [attr.data-column]=\"column\">\n @if (getColumnDef(column)?.cellTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"getColumnDef(column)?.cellTemplate() || null\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column }\" />\n }\n @if (!getColumnDef(column)?.cellTemplate()) {\n <span>{{ getCellValue(row, column) }}</span>\n }\n </td>\n }\n </tr>\n }\n </tbody>\n</table>", styles: [".tn-table{display:block;width:100%;overflow-x:auto}.tn-table__table{width:100%;border-collapse:collapse;border-spacing:0;background-color:var(--tn-bg2);border-radius:4px;overflow:hidden}.tn-table__header{background-color:var(--tn-topbar);color:var(--tn-topbar-txt)}.tn-table__header-row{height:56px}.tn-table__header-cell{padding:0 16px;text-align:left;font-weight:600;font-size:14px;border-bottom:1px solid var(--tn-lines);white-space:nowrap;vertical-align:middle}.tn-table__body{background-color:var(--tn-bg2)}.tn-table__row{height:48px;transition:background-color .2s ease}.tn-table__row:hover{background-color:var(--tn-alt-bg1)}.tn-table__row:not(:last-child){border-bottom:1px solid var(--tn-lines)}.tn-table__cell{padding:0 16px;font-size:14px;color:var(--tn-fg1);vertical-align:middle;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tn-table--dense .tn-table__header-row{height:40px}.tn-table--dense .tn-table__row{height:32px}.tn-table--dense .tn-table__header-cell,.tn-table--dense .tn-table__cell{padding:0 12px;font-size:13px}@media(max-width:768px){.tn-table__table{font-size:12px}.tn-table__header-cell,.tn-table__cell{padding:0 8px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
5341
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnTableComponent, isStandalone: true, selector: "tn-table", inputs: { dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: false, transformFunction: null }, displayedColumns: { classPropertyName: "displayedColumns", publicName: "displayedColumns", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "tn-table" }, queries: [{ propertyName: "columnDefs", predicate: TnTableColumnDirective, isSignal: true }], ngImport: i0, template: "<table class=\"tn-table__table\">\n <!-- Header Row -->\n <thead class=\"tn-table__header\">\n <tr class=\"tn-table__header-row\">\n @for (column of displayedColumns(); track $index) {\n <th\n class=\"tn-table__header-cell\"\n [attr.data-column]=\"column\">\n @if (getColumnDef(column)?.headerTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"getColumnDef(column)?.headerTemplate() || null\" />\n }\n @if (!getColumnDef(column)?.headerTemplate()) {\n <span>{{ column }}</span>\n }\n </th>\n }\n </tr>\n </thead>\n\n <!-- Data Rows -->\n <tbody class=\"tn-table__body\">\n @for (row of data(); track $index) {\n <tr class=\"tn-table__row\">\n @for (column of displayedColumns(); track $index) {\n <td\n class=\"tn-table__cell\"\n [attr.data-column]=\"column\">\n @if (getColumnDef(column)?.cellTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"getColumnDef(column)?.cellTemplate() || null\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column }\" />\n }\n @if (!getColumnDef(column)?.cellTemplate()) {\n <span>{{ getCellValue(row, column) }}</span>\n }\n </td>\n }\n </tr>\n }\n </tbody>\n</table>", styles: [".tn-table{display:block;width:100%;overflow-x:auto}.tn-table__table{width:100%;border-collapse:collapse;border-spacing:0;background-color:var(--tn-bg2);border-radius:4px;overflow:hidden}.tn-table__header{background-color:var(--tn-topbar);color:var(--tn-topbar-txt)}.tn-table__header-row{height:56px}.tn-table__header-cell{padding:0 16px;text-align:left;font-weight:600;font-size:14px;border-bottom:1px solid var(--tn-lines);white-space:nowrap;vertical-align:middle}.tn-table__body{background-color:var(--tn-bg2)}.tn-table__row{height:48px;transition:background-color .2s ease}.tn-table__row:hover{background-color:var(--tn-alt-bg1)}.tn-table__row:not(:last-child){border-bottom:1px solid var(--tn-lines)}.tn-table__cell{padding:0 16px;font-size:14px;color:var(--tn-fg1);vertical-align:middle;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tn-table--dense .tn-table__header-row{height:40px}.tn-table--dense .tn-table__row{height:32px}.tn-table--dense .tn-table__header-cell,.tn-table--dense .tn-table__cell{padding:0 12px;font-size:13px}@media(max-width:768px){.tn-table__table{font-size:12px}.tn-table__header-cell,.tn-table__cell{padding:0 8px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
5098
5342
  }
5099
5343
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTableComponent, decorators: [{
5100
5344
  type: Component,
@@ -5186,7 +5430,7 @@ class TnTreeComponent extends CdkTree {
5186
5430
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTreeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5187
5431
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.0", type: TnTreeComponent, isStandalone: true, selector: "tn-tree", host: { attributes: { "role": "tree" }, classAttribute: "tn-tree" }, providers: [
5188
5432
  { provide: CdkTree, useExisting: TnTreeComponent }
5189
- ], exportAs: ["tnTree"], usesInheritance: true, ngImport: i0, template: "<ng-container cdkTreeNodeOutlet />", styles: [":host{display:block;width:100%}.tn-tree{width:100%;background-color:var(--tn-bg1);border:1px solid var(--tn-lines);border-radius:6px;overflow:hidden}\n"], dependencies: [{ kind: "ngmodule", type: CdkTreeModule }, { kind: "directive", type: i1$2.CdkTreeNodeOutlet, selector: "[cdkTreeNodeOutlet]" }], changeDetection: i0.ChangeDetectionStrategy.Default, encapsulation: i0.ViewEncapsulation.None });
5433
+ ], exportAs: ["tnTree"], usesInheritance: true, ngImport: i0, template: "<ng-container cdkTreeNodeOutlet />", styles: [":host{display:block;width:100%}.tn-tree{width:100%;background-color:var(--tn-bg1);border:1px solid var(--tn-lines);border-radius:6px;overflow:hidden}\n"], dependencies: [{ kind: "ngmodule", type: CdkTreeModule }, { kind: "directive", type: i1$3.CdkTreeNodeOutlet, selector: "[cdkTreeNodeOutlet]" }], changeDetection: i0.ChangeDetectionStrategy.Default, encapsulation: i0.ViewEncapsulation.None });
5190
5434
  }
5191
5435
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTreeComponent, decorators: [{
5192
5436
  type: Component,
@@ -5217,7 +5461,7 @@ class TnTreeNodeComponent extends CdkTreeNode {
5217
5461
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTreeNodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5218
5462
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnTreeNodeComponent, isStandalone: true, selector: "tn-tree-node", host: { attributes: { "role": "treeitem" }, properties: { "attr.aria-level": "level + 1", "attr.aria-expanded": "isExpandable ? isExpanded : null" }, classAttribute: "tn-tree-node-wrapper" }, providers: [
5219
5463
  { provide: CdkTreeNode, useExisting: TnTreeNodeComponent }
5220
- ], exportAs: ["tnTreeNode"], usesInheritance: true, ngImport: i0, template: "<div class=\"tn-tree-node\"\n cdkTreeNodeToggle\n role=\"treeitem\"\n [class.tn-tree-node--expandable]=\"isExpandable\"\n [attr.aria-level]=\"level + 1\"\n [attr.aria-expanded]=\"isExpandable ? isExpanded : null\"\n [attr.aria-selected]=\"false\"\n [style.cursor]=\"isExpandable ? 'pointer' : 'default'\">\n \n <div class=\"tn-tree-node__content\">\n <!-- Arrow icon for expandable nodes -->\n @if (isExpandable) {\n <div\n class=\"tn-tree-node__toggle\"\n [class.tn-tree-node__toggle--expanded]=\"isExpanded\">\n <tn-icon\n library=\"mdi\"\n size=\"sm\"\n style=\"transition: transform 0.2s ease;\"\n [name]=\"isExpanded ? 'chevron-down' : 'chevron-right'\" />\n </div>\n }\n\n <!-- Spacer for non-expandable nodes -->\n @if (!isExpandable) {\n <div class=\"tn-tree-node__spacer\"></div>\n }\n \n <!-- Node content -->\n <div class=\"tn-tree-node__text\">\n <ng-content />\n </div>\n </div>\n</div>", styles: [":host{display:block}.tn-tree-node{border-bottom:1px solid var(--tn-lines);transition:background-color .2s ease}.tn-tree-node:hover{background-color:var(--tn-alt-bg2)}.tn-tree-node:last-child{border-bottom:none}.tn-tree-node--expandable{cursor:pointer}.tn-tree-node--expandable:hover{background-color:var(--tn-alt-bg2)}.tn-tree-node--expandable:active{background-color:var(--tn-alt-bg1)}.tn-tree-node__content{display:flex;align-items:center;gap:8px;min-height:48px;padding:12px 16px}.tn-tree-node__toggle{display:flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;border:none;background:none;color:var(--tn-fg2);cursor:pointer;border-radius:3px;transition:all .2s ease;flex-shrink:0}.tn-tree-node__toggle:hover{background-color:var(--tn-alt-bg2);color:var(--tn-fg1)}.tn-tree-node__toggle:focus{outline:2px solid var(--tn-primary);outline-offset:1px}.tn-tree-node__toggle svg{transition:transform .2s ease;transform:rotate(0)}.tn-tree-node__toggle--expanded svg{transform:rotate(90deg)}.tn-tree-node__spacer{width:24px;height:24px;flex-shrink:0}.tn-tree-node__text{flex:1;min-width:0;color:var(--tn-fg1)}.tn-tree-node__children{padding-left:24px}.tn-tree-invisible{display:none}\n"], dependencies: [{ kind: "ngmodule", type: CdkTreeModule }, { kind: "directive", type: i1$2.CdkTreeNodeToggle, selector: "[cdkTreeNodeToggle]", inputs: ["cdkTreeNodeToggleRecursive"] }, { kind: "component", type: TnIconComponent, selector: "tn-icon", inputs: ["name", "size", "color", "tooltip", "ariaLabel", "library", "fullSize", "customSize"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5464
+ ], exportAs: ["tnTreeNode"], usesInheritance: true, ngImport: i0, template: "<div class=\"tn-tree-node\"\n cdkTreeNodeToggle\n role=\"treeitem\"\n [class.tn-tree-node--expandable]=\"isExpandable\"\n [attr.aria-level]=\"level + 1\"\n [attr.aria-expanded]=\"isExpandable ? isExpanded : null\"\n [attr.aria-selected]=\"false\"\n [style.cursor]=\"isExpandable ? 'pointer' : 'default'\">\n \n <div class=\"tn-tree-node__content\">\n <!-- Arrow icon for expandable nodes -->\n @if (isExpandable) {\n <div\n class=\"tn-tree-node__toggle\"\n [class.tn-tree-node__toggle--expanded]=\"isExpanded\">\n <tn-icon\n library=\"mdi\"\n size=\"sm\"\n style=\"transition: transform 0.2s ease;\"\n [name]=\"isExpanded ? 'chevron-down' : 'chevron-right'\" />\n </div>\n }\n\n <!-- Spacer for non-expandable nodes -->\n @if (!isExpandable) {\n <div class=\"tn-tree-node__spacer\"></div>\n }\n \n <!-- Node content -->\n <div class=\"tn-tree-node__text\">\n <ng-content />\n </div>\n </div>\n</div>", styles: [":host{display:block}.tn-tree-node{border-bottom:1px solid var(--tn-lines);transition:background-color .2s ease}.tn-tree-node:hover{background-color:var(--tn-alt-bg2)}.tn-tree-node:last-child{border-bottom:none}.tn-tree-node--expandable{cursor:pointer}.tn-tree-node--expandable:hover{background-color:var(--tn-alt-bg2)}.tn-tree-node--expandable:active{background-color:var(--tn-alt-bg1)}.tn-tree-node__content{display:flex;align-items:center;gap:8px;min-height:48px;padding:12px 16px}.tn-tree-node__toggle{display:flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;border:none;background:none;color:var(--tn-fg2);cursor:pointer;border-radius:3px;transition:all .2s ease;flex-shrink:0}.tn-tree-node__toggle:hover{background-color:var(--tn-alt-bg2);color:var(--tn-fg1)}.tn-tree-node__toggle:focus{outline:2px solid var(--tn-primary);outline-offset:1px}.tn-tree-node__toggle svg{transition:transform .2s ease;transform:rotate(0)}.tn-tree-node__toggle--expanded svg{transform:rotate(90deg)}.tn-tree-node__spacer{width:24px;height:24px;flex-shrink:0}.tn-tree-node__text{flex:1;min-width:0;color:var(--tn-fg1)}.tn-tree-node__children{padding-left:24px}.tn-tree-invisible{display:none}\n"], dependencies: [{ kind: "ngmodule", type: CdkTreeModule }, { kind: "directive", type: i1$3.CdkTreeNodeToggle, selector: "[cdkTreeNodeToggle]", inputs: ["cdkTreeNodeToggleRecursive"] }, { kind: "component", type: TnIconComponent, selector: "tn-icon", inputs: ["name", "size", "color", "tooltip", "ariaLabel", "library", "fullSize", "customSize"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5221
5465
  }
5222
5466
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTreeNodeComponent, decorators: [{
5223
5467
  type: Component,
@@ -5233,7 +5477,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImpor
5233
5477
 
5234
5478
  class TnTreeNodeOutletDirective {
5235
5479
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTreeNodeOutletDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
5236
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.0", type: TnTreeNodeOutletDirective, isStandalone: true, selector: "[tnTreeNodeOutlet]", hostDirectives: [{ directive: i1$2.CdkTreeNodeOutlet }], ngImport: i0 });
5480
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.0", type: TnTreeNodeOutletDirective, isStandalone: true, selector: "[tnTreeNodeOutlet]", hostDirectives: [{ directive: i1$3.CdkTreeNodeOutlet }], ngImport: i0 });
5237
5481
  }
5238
5482
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTreeNodeOutletDirective, decorators: [{
5239
5483
  type: Directive,
@@ -5298,7 +5542,7 @@ class TnNestedTreeNodeComponent extends CdkNestedTreeNode {
5298
5542
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnNestedTreeNodeComponent, isStandalone: true, selector: "tn-nested-tree-node", host: { attributes: { "role": "treeitem" }, properties: { "attr.aria-level": "level + 1", "attr.aria-expanded": "isExpandable ? isExpanded : null" }, classAttribute: "tn-nested-tree-node-wrapper" }, providers: [
5299
5543
  { provide: CdkNestedTreeNode, useExisting: TnNestedTreeNodeComponent },
5300
5544
  { provide: CdkTreeNode, useExisting: TnNestedTreeNodeComponent }
5301
- ], exportAs: ["tnNestedTreeNode"], usesInheritance: true, ngImport: i0, template: "<div class=\"tn-nested-tree-node__content\">\n <!-- Toggle button for expandable nodes (provided by component) -->\n @if (isExpandable) {\n <button\n class=\"tn-nested-tree-node__toggle\"\n cdkTreeNodeToggle\n type=\"button\"\n [class.tn-nested-tree-node__toggle--expanded]=\"isExpanded\"\n [attr.aria-label]=\"'Toggle node'\">\n <tn-icon\n library=\"mdi\"\n size=\"sm\"\n style=\"transition: transform 0.2s ease;\"\n [name]=\"isExpanded ? 'chevron-down' : 'chevron-right'\" />\n </button>\n }\n\n <!-- Spacer for non-expandable nodes to maintain alignment -->\n @if (!isExpandable) {\n <div class=\"tn-nested-tree-node__spacer\"></div>\n }\n\n <!-- Consumer content -->\n <ng-content />\n</div>\n\n<!-- Children container -->\n@if (isExpandable) {\n <div class=\"tn-nested-tree-node-container\" role=\"group\" [class.tn-tree-invisible]=\"!isExpanded\">\n <ng-content select=\"[slot=children]\" />\n </div>\n}", styles: [".tn-nested-tree-node-wrapper{display:block;width:100%}.tn-nested-tree-node{display:block;width:100%;font-family:var(--tn-font-family-body);font-size:.875rem;line-height:1.4;color:var(--tn-fg1)}.tn-nested-tree-node--expandable .tn-nested-tree-node__content{cursor:pointer}.tn-nested-tree-node__content{display:flex;align-items:center;gap:8px;min-height:48px;padding:12px 16px;border-bottom:1px solid var(--tn-lines);transition:background-color .2s ease}.tn-nested-tree-node__content:hover{background-color:var(--tn-alt-bg2)}.tn-nested-tree-node__content:focus-within{background-color:var(--tn-alt-bg2);outline:2px solid var(--tn-primary);outline-offset:-2px}.tn-tree-invisible{display:none}.tn-nested-tree-node__toggle{display:flex;align-items:center;justify-content:center;width:24px;height:24px;margin-right:8px;padding:0;border:none;background:transparent;border-radius:4px;cursor:pointer;color:var(--tn-fg2);transition:background-color .2s ease,color .2s ease}.tn-nested-tree-node__toggle:hover{background-color:var(--tn-bg3);color:var(--tn-fg1)}.tn-nested-tree-node__toggle:focus{outline:2px solid var(--tn-primary);outline-offset:2px}.tn-nested-tree-node__toggle svg{transition:transform .2s ease}.tn-nested-tree-node__toggle--expanded svg{transform:rotate(90deg)}.tn-nested-tree-node__spacer{width:24px;height:24px;flex-shrink:0}.tn-nested-tree-node__text{flex:1;display:flex;align-items:center;gap:8px;min-width:0;color:var(--tn-fg1)}div.tn-nested-tree-node-container{padding-left:40px}@media(prefers-reduced-motion:reduce){.tn-nested-tree-node__toggle svg,.tn-nested-tree-node__content,.tn-nested-tree-node__children{transition:none}}@media(prefers-contrast:high){.tn-nested-tree-node__content{border:1px solid transparent}.tn-nested-tree-node__content:hover,.tn-nested-tree-node__content:focus-within{border-color:var(--tn-fg1)}.tn-nested-tree-node__toggle{border:1px solid var(--tn-fg2)}.tn-nested-tree-node__toggle:hover,.tn-nested-tree-node__toggle:focus{border-color:var(--tn-fg1)}}\n"], dependencies: [{ kind: "ngmodule", type: CdkTreeModule }, { kind: "directive", type: i1$2.CdkTreeNodeToggle, selector: "[cdkTreeNodeToggle]", inputs: ["cdkTreeNodeToggleRecursive"] }, { kind: "component", type: TnIconComponent, selector: "tn-icon", inputs: ["name", "size", "color", "tooltip", "ariaLabel", "library", "fullSize", "customSize"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5545
+ ], exportAs: ["tnNestedTreeNode"], usesInheritance: true, ngImport: i0, template: "<div class=\"tn-nested-tree-node__content\">\n <!-- Toggle button for expandable nodes (provided by component) -->\n @if (isExpandable) {\n <button\n class=\"tn-nested-tree-node__toggle\"\n cdkTreeNodeToggle\n type=\"button\"\n [class.tn-nested-tree-node__toggle--expanded]=\"isExpanded\"\n [attr.aria-label]=\"'Toggle node'\">\n <tn-icon\n library=\"mdi\"\n size=\"sm\"\n style=\"transition: transform 0.2s ease;\"\n [name]=\"isExpanded ? 'chevron-down' : 'chevron-right'\" />\n </button>\n }\n\n <!-- Spacer for non-expandable nodes to maintain alignment -->\n @if (!isExpandable) {\n <div class=\"tn-nested-tree-node__spacer\"></div>\n }\n\n <!-- Consumer content -->\n <ng-content />\n</div>\n\n<!-- Children container -->\n@if (isExpandable) {\n <div class=\"tn-nested-tree-node-container\" role=\"group\" [class.tn-tree-invisible]=\"!isExpanded\">\n <ng-content select=\"[slot=children]\" />\n </div>\n}", styles: [".tn-nested-tree-node-wrapper{display:block;width:100%}.tn-nested-tree-node{display:block;width:100%;font-family:var(--tn-font-family-body);font-size:.875rem;line-height:1.4;color:var(--tn-fg1)}.tn-nested-tree-node--expandable .tn-nested-tree-node__content{cursor:pointer}.tn-nested-tree-node__content{display:flex;align-items:center;gap:8px;min-height:48px;padding:12px 16px;border-bottom:1px solid var(--tn-lines);transition:background-color .2s ease}.tn-nested-tree-node__content:hover{background-color:var(--tn-alt-bg2)}.tn-nested-tree-node__content:focus-within{background-color:var(--tn-alt-bg2);outline:2px solid var(--tn-primary);outline-offset:-2px}.tn-tree-invisible{display:none}.tn-nested-tree-node__toggle{display:flex;align-items:center;justify-content:center;width:24px;height:24px;margin-right:8px;padding:0;border:none;background:transparent;border-radius:4px;cursor:pointer;color:var(--tn-fg2);transition:background-color .2s ease,color .2s ease}.tn-nested-tree-node__toggle:hover{background-color:var(--tn-bg3);color:var(--tn-fg1)}.tn-nested-tree-node__toggle:focus{outline:2px solid var(--tn-primary);outline-offset:2px}.tn-nested-tree-node__toggle svg{transition:transform .2s ease}.tn-nested-tree-node__toggle--expanded svg{transform:rotate(90deg)}.tn-nested-tree-node__spacer{width:24px;height:24px;flex-shrink:0}.tn-nested-tree-node__text{flex:1;display:flex;align-items:center;gap:8px;min-width:0;color:var(--tn-fg1)}div.tn-nested-tree-node-container{padding-left:40px}@media(prefers-reduced-motion:reduce){.tn-nested-tree-node__toggle svg,.tn-nested-tree-node__content,.tn-nested-tree-node__children{transition:none}}@media(prefers-contrast:high){.tn-nested-tree-node__content{border:1px solid transparent}.tn-nested-tree-node__content:hover,.tn-nested-tree-node__content:focus-within{border-color:var(--tn-fg1)}.tn-nested-tree-node__toggle{border:1px solid var(--tn-fg2)}.tn-nested-tree-node__toggle:hover,.tn-nested-tree-node__toggle:focus{border-color:var(--tn-fg1)}}\n"], dependencies: [{ kind: "ngmodule", type: CdkTreeModule }, { kind: "directive", type: i1$3.CdkTreeNodeToggle, selector: "[cdkTreeNodeToggle]", inputs: ["cdkTreeNodeToggleRecursive"] }, { kind: "component", type: TnIconComponent, selector: "tn-icon", inputs: ["name", "size", "color", "tooltip", "ariaLabel", "library", "fullSize", "customSize"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5302
5546
  }
5303
5547
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnNestedTreeNodeComponent, decorators: [{
5304
5548
  type: Component,
@@ -7484,7 +7728,7 @@ class TnTimeInputComponent {
7484
7728
  useExisting: forwardRef(() => TnTimeInputComponent),
7485
7729
  multi: true
7486
7730
  }
7487
- ], ngImport: i0, template: "<tn-select\n [options]=\"timeSelectOptions()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [testId]=\"testId()\"\n [ngModel]=\"_value\"\n (selectionChange)=\"onSelectionChange($event)\" />\n", styles: [":host{display:block;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: TnSelectComponent, selector: "tn-select", inputs: ["options", "optionGroups", "placeholder", "disabled", "testId"], outputs: ["selectionChange"] }] });
7731
+ ], ngImport: i0, template: "<tn-select\n [options]=\"timeSelectOptions()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [testId]=\"testId()\"\n [ngModel]=\"_value\"\n (selectionChange)=\"onSelectionChange($event)\" />\n", styles: [":host{display:block;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: TnSelectComponent, selector: "tn-select", inputs: ["options", "optionGroups", "placeholder", "disabled", "testId"], outputs: ["selectionChange"] }] });
7488
7732
  }
7489
7733
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTimeInputComponent, decorators: [{
7490
7734
  type: Component,
@@ -8882,7 +9126,7 @@ class TnSidePanelComponent {
8882
9126
  });
8883
9127
  }
8884
9128
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnSidePanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8885
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnSidePanelComponent, isStandalone: true, selector: "tn-side-panel", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, hasBackdrop: { classPropertyName: "hasBackdrop", publicName: "hasBackdrop", isSignal: true, isRequired: false, transformFunction: null }, closeOnBackdropClick: { classPropertyName: "closeOnBackdropClick", publicName: "closeOnBackdropClick", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange", opened: "opened", closed: "closed" }, host: { properties: { "attr.data-tn-panel": "panelId" }, classAttribute: "tn-side-panel" }, queries: [{ propertyName: "actionContent", predicate: TnSidePanelActionDirective, isSignal: true }], viewQueries: [{ propertyName: "overlayRef", first: true, predicate: ["overlay"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Overlay wrapper: portaled to document.body -->\n<div\n #overlay\n class=\"tn-side-panel__overlay\"\n role=\"dialog\"\n [attr.data-tn-panel]=\"panelId\"\n [class.tn-side-panel__overlay--initialized]=\"initialized()\"\n [class.tn-side-panel__overlay--open]=\"open()\"\n [attr.aria-modal]=\"open() ? 'true' : null\"\n [attr.aria-labelledby]=\"open() ? titleId : null\"\n [attr.aria-hidden]=\"!open() ? 'true' : null\">\n\n <!-- Backdrop -->\n @if (hasBackdrop()) {\n <div\n class=\"tn-side-panel__backdrop\"\n aria-hidden=\"true\"\n (click)=\"onBackdropClick()\">\n </div>\n }\n\n <!-- Panel -->\n <div\n class=\"tn-side-panel__panel\"\n tabindex=\"-1\"\n cdkTrapFocus\n [style.width]=\"width()\"\n [cdkTrapFocusAutoCapture]=\"open()\"\n (transitionend)=\"onTransitionEnd($event)\"\n (keydown)=\"onKeydown($event)\">\n\n <!-- Header -->\n <header class=\"tn-side-panel__header\">\n <h2 class=\"tn-side-panel__title\" [id]=\"titleId\">{{ title() }}</h2>\n <div class=\"tn-side-panel__header-actions\">\n <ng-content select=\"[tnSidePanelHeaderAction]\" />\n <tn-icon-button\n name=\"close\"\n library=\"mdi\"\n size=\"sm\"\n ariaLabel=\"Dismiss\"\n (onClick)=\"dismiss()\" />\n </div>\n </header>\n\n <!-- Content -->\n <section class=\"tn-side-panel__content\">\n <ng-content />\n </section>\n\n <!-- Actions -->\n @if (hasActions()) {\n <footer class=\"tn-side-panel__actions\">\n <ng-content select=\"[tnSidePanelAction]\" />\n </footer>\n }\n </div>\n</div>\n", styles: [":host{display:contents}.tn-side-panel__overlay{position:fixed;inset:0;z-index:1000;pointer-events:none}.tn-side-panel__overlay--open{pointer-events:auto}.tn-side-panel__overlay--open .tn-side-panel__backdrop{opacity:1}.tn-side-panel__overlay--open .tn-side-panel__panel{transform:translate(0)}.tn-side-panel__backdrop{position:absolute;inset:0;background:#00000080;opacity:0}.tn-side-panel__overlay--initialized .tn-side-panel__backdrop{transition:opacity .2s ease}.tn-side-panel__panel{position:absolute;top:0;right:0;bottom:0;display:flex;flex-direction:column;max-width:100vw;background:var(--tn-bg2, #282828);color:var(--tn-fg1, #ffffff);box-shadow:-4px 0 24px #0000004d;outline:none;transform:translate(100%)}.tn-side-panel__overlay--initialized .tn-side-panel__panel{transition:transform .3s cubic-bezier(.4,0,.2,1)}.tn-side-panel__header{flex:0 0 auto;display:flex;align-items:center;gap:16px;padding:16px 24px;border-bottom:1px solid var(--tn-lines, #383838)}.tn-side-panel__title{margin:0;font-size:1.25rem;font-weight:600;line-height:1.5;color:var(--tn-fg1, #ffffff);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tn-side-panel__header-actions{display:flex;align-items:center;gap:8px;flex-shrink:0}.tn-side-panel__content{flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden;padding:var(--tn-content-padding, 24px);-webkit-overflow-scrolling:touch}.tn-side-panel__actions{flex:0 0 auto;display:flex;justify-content:flex-end;gap:12px;padding:16px 24px;border-top:1px solid var(--tn-lines, #383838)}@media(max-width:640px){.tn-side-panel__panel{width:100vw!important}}@media(prefers-reduced-motion:reduce){.tn-side-panel__panel,.tn-side-panel__backdrop{transition-duration:0ms!important}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i1$4.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "component", type: TnIconButtonComponent, selector: "tn-icon-button", inputs: ["disabled", "ariaLabel", "name", "size", "color", "tooltip", "library"], outputs: ["onClick"] }] });
9129
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnSidePanelComponent, isStandalone: true, selector: "tn-side-panel", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, hasBackdrop: { classPropertyName: "hasBackdrop", publicName: "hasBackdrop", isSignal: true, isRequired: false, transformFunction: null }, closeOnBackdropClick: { classPropertyName: "closeOnBackdropClick", publicName: "closeOnBackdropClick", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange", opened: "opened", closed: "closed" }, host: { properties: { "attr.data-tn-panel": "panelId" }, classAttribute: "tn-side-panel" }, queries: [{ propertyName: "actionContent", predicate: TnSidePanelActionDirective, isSignal: true }], viewQueries: [{ propertyName: "overlayRef", first: true, predicate: ["overlay"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Overlay wrapper: portaled to document.body -->\n<div\n #overlay\n class=\"tn-side-panel__overlay\"\n role=\"dialog\"\n [attr.data-tn-panel]=\"panelId\"\n [class.tn-side-panel__overlay--initialized]=\"initialized()\"\n [class.tn-side-panel__overlay--open]=\"open()\"\n [attr.aria-modal]=\"open() ? 'true' : null\"\n [attr.aria-labelledby]=\"open() ? titleId : null\"\n [attr.aria-hidden]=\"!open() ? 'true' : null\">\n\n <!-- Backdrop -->\n @if (hasBackdrop()) {\n <div\n class=\"tn-side-panel__backdrop\"\n aria-hidden=\"true\"\n (click)=\"onBackdropClick()\">\n </div>\n }\n\n <!-- Panel -->\n <div\n class=\"tn-side-panel__panel\"\n tabindex=\"-1\"\n cdkTrapFocus\n [style.width]=\"width()\"\n [cdkTrapFocusAutoCapture]=\"open()\"\n (transitionend)=\"onTransitionEnd($event)\"\n (keydown)=\"onKeydown($event)\">\n\n <!-- Header -->\n <header class=\"tn-side-panel__header\">\n <h2 class=\"tn-side-panel__title\" [id]=\"titleId\">{{ title() }}</h2>\n <div class=\"tn-side-panel__header-actions\">\n <ng-content select=\"[tnSidePanelHeaderAction]\" />\n <tn-icon-button\n name=\"close\"\n library=\"mdi\"\n size=\"sm\"\n ariaLabel=\"Dismiss\"\n (onClick)=\"dismiss()\" />\n </div>\n </header>\n\n <!-- Content -->\n <section class=\"tn-side-panel__content\">\n <ng-content />\n </section>\n\n <!-- Actions -->\n @if (hasActions()) {\n <footer class=\"tn-side-panel__actions\">\n <ng-content select=\"[tnSidePanelAction]\" />\n </footer>\n }\n </div>\n</div>\n", styles: [":host{display:contents}.tn-side-panel__overlay{position:fixed;inset:0;z-index:1000;pointer-events:none}.tn-side-panel__overlay--open{pointer-events:auto}.tn-side-panel__overlay--open .tn-side-panel__backdrop{opacity:1}.tn-side-panel__overlay--open .tn-side-panel__panel{transform:translate(0)}.tn-side-panel__backdrop{position:absolute;inset:0;background:#00000080;opacity:0}.tn-side-panel__overlay--initialized .tn-side-panel__backdrop{transition:opacity .2s ease}.tn-side-panel__panel{position:absolute;top:0;right:0;bottom:0;display:flex;flex-direction:column;max-width:100vw;background:var(--tn-bg2, #282828);color:var(--tn-fg1, #ffffff);box-shadow:-4px 0 24px #0000004d;outline:none;transform:translate(100%)}.tn-side-panel__overlay--initialized .tn-side-panel__panel{transition:transform .3s cubic-bezier(.4,0,.2,1)}.tn-side-panel__header{flex:0 0 auto;display:flex;align-items:center;gap:16px;padding:16px 24px;border-bottom:1px solid var(--tn-lines, #383838)}.tn-side-panel__title{margin:0;font-size:1.25rem;font-weight:600;line-height:1.5;color:var(--tn-fg1, #ffffff);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tn-side-panel__header-actions{display:flex;align-items:center;gap:8px;flex-shrink:0}.tn-side-panel__content{flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden;padding:var(--tn-content-padding, 24px);-webkit-overflow-scrolling:touch}.tn-side-panel__actions{flex:0 0 auto;display:flex;justify-content:flex-end;gap:12px;padding:16px 24px;border-top:1px solid var(--tn-lines, #383838)}@media(max-width:640px){.tn-side-panel__panel{width:100vw!important}}@media(prefers-reduced-motion:reduce){.tn-side-panel__panel,.tn-side-panel__backdrop{transition-duration:0ms!important}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i1.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "component", type: TnIconButtonComponent, selector: "tn-icon-button", inputs: ["disabled", "ariaLabel", "name", "size", "color", "tooltip", "library"], outputs: ["onClick"] }] });
8886
9130
  }
8887
9131
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnSidePanelComponent, decorators: [{
8888
9132
  type: Component,
@@ -9045,7 +9289,7 @@ class TnStepperComponent {
9045
9289
  return index;
9046
9290
  }
9047
9291
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnStepperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9048
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnStepperComponent, isStandalone: true, selector: "tn-stepper", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, linear: { classPropertyName: "linear", publicName: "linear", isSignal: true, isRequired: false, transformFunction: null }, selectedIndex: { classPropertyName: "selectedIndex", publicName: "selectedIndex", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedIndex: "selectedIndexChange", selectionChange: "selectionChange", completed: "completed" }, host: { listeners: { "window:resize": "onWindowResize($event)" } }, queries: [{ propertyName: "steps", predicate: TnStepComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"tn-stepper\"\n [class.tn-stepper--horizontal]=\"orientation() === 'horizontal' || (orientation() === 'auto' && isWideScreen())\"\n [class.tn-stepper--vertical]=\"orientation() === 'vertical' || (orientation() === 'auto' && !isWideScreen())\">\n\n <!-- Step Headers -->\n <div class=\"tn-stepper__header\">\n @for (step of steps(); track $index; let i = $index) {\n <div class=\"tn-stepper__step-header\"\n tabindex=\"0\"\n role=\"button\"\n [class.tn-stepper__step-header--active]=\"selectedIndex() === i\"\n [class.tn-stepper__step-header--completed]=\"step.completed()\"\n [class.tn-stepper__step-header--error]=\"step.hasError()\"\n [class.tn-stepper__step-header--optional]=\"step.optional()\"\n (click)=\"selectStep(i)\"\n (keydown.enter)=\"selectStep(i)\"\n (keydown.space)=\"selectStep(i)\">\n\n <!-- Step Number/Icon -->\n <div class=\"tn-stepper__step-indicator\">\n @if (step.completed() && !step.hasError()) {\n <span class=\"tn-stepper__step-check\">\u2713</span>\n }\n @if (step.hasError()) {\n <span class=\"tn-stepper__step-error\">!</span>\n }\n @if (!step.completed() && !step.hasError()) {\n @if (step.icon()) {\n <span class=\"tn-stepper__step-icon\">{{ step.icon() }}</span>\n } @else {\n <span class=\"tn-stepper__step-number\">{{ i + 1 }}</span>\n }\n }\n </div>\n\n <!-- Step Label -->\n <div class=\"tn-stepper__step-label\">\n <div class=\"tn-stepper__step-title\">{{ step.label() }}</div>\n @if (step.optional()) {\n <span class=\"tn-stepper__step-subtitle\">Optional</span>\n }\n </div>\n </div>\n\n <!-- Connector Line (except for last step) -->\n @if (i < steps().length - 1) {\n <div class=\"tn-stepper__connector\"></div>\n }\n }\n </div>\n\n <!-- Step Content -->\n <div class=\"tn-stepper__content\">\n @for (step of steps(); track $index; let i = $index) {\n @if (selectedIndex() === i) {\n <div class=\"tn-stepper__step-content\"\n [@stepTransition]=\"selectedIndex()\">\n <ng-container *ngTemplateOutlet=\"step.content()\" />\n </div>\n }\n }\n </div>\n</div>", styles: [".tn-stepper{display:flex;font-family:inherit;--step-diameter: 48px;--step-diameter-sm: 32px;--step-padding: 12px}.tn-stepper--horizontal{flex-direction:column}.tn-stepper--horizontal .tn-stepper__header{display:flex;justify-content:center;margin-bottom:32px;padding:0 16px}.tn-stepper--horizontal .tn-stepper__step-header{display:flex;flex-direction:column;align-items:center;text-align:center;cursor:pointer;transition:all .2s ease-in-out}.tn-stepper--horizontal .tn-stepper__step-header:not(.tn-stepper__step-header--active):hover .tn-stepper__step-indicator{transform:scale(.95)}.tn-stepper--horizontal .tn-stepper__connector{flex:1;height:2px;background:var(--tn-lines, #e5e7eb);margin:0 16px;position:relative;top:calc(var(--step-diameter) / 2)}.tn-stepper--vertical{flex-direction:row}.tn-stepper--vertical .tn-stepper__header{display:flex;flex-direction:column;width:280px;padding:16px;border-right:1px solid var(--tn-lines, #e5e7eb)}.tn-stepper--vertical .tn-stepper__step-header{display:flex;flex-direction:row;align-items:center;text-align:left;cursor:pointer;transition:all .2s ease-in-out;padding:var(--step-padding);border-radius:8px;margin-bottom:8px}.tn-stepper--vertical .tn-stepper__step-header:not(.tn-stepper__step-header--active):hover .tn-stepper__step-indicator{transform:scale(.95)}.tn-stepper--vertical .tn-stepper__step-header .tn-stepper__step-label{margin-left:12px;margin-top:0}.tn-stepper--vertical .tn-stepper__connector{width:2px;height:24px;background:var(--tn-lines, #e5e7eb);position:relative;left:calc(var(--step-diameter) / 2 + var(--step-padding));margin-bottom:8px}.tn-stepper--vertical .tn-stepper__content{flex:1;padding:16px}.tn-stepper__step-indicator{display:flex;align-items:center;justify-content:center;width:var(--step-diameter);height:var(--step-diameter);border-radius:50%;background:var(--tn-alt-bg1, #f8f9fa);color:var(--tn-alt-fg1, #495057);font-weight:400;font-size:14px;transition:all .2s ease-in-out;position:relative;transform:scale(.65)}.tn-stepper__step-number{font-weight:400}.tn-stepper__step-label{margin-top:8px}.tn-stepper__step-title{display:block;font-weight:400;font-size:14px;color:var(--tn-fg1, #000000);line-height:1.2}.tn-stepper__step-subtitle{display:block;font-size:12px;color:var(--tn-fg2, #6c757d);margin-top:2px}.tn-stepper__step-header--active .tn-stepper__step-indicator{background:var(--tn-primary, #007bff);color:var(--tn-primary-txt, #ffffff);transform:scale(1)}.tn-stepper__step-header--active .tn-stepper__step-title{color:var(--tn-fg2, #6c757d);font-weight:600}.tn-stepper__step-header--completed .tn-stepper__step-indicator{background:var(--tn-green, #28a745);color:#fff}.tn-stepper__step-header--completed .tn-stepper__step-check{font-size:16px;font-weight:700}.tn-stepper__step-header--error .tn-stepper__step-indicator{background:var(--tn-red, #dc3545);color:#fff}.tn-stepper__step-header--error .tn-stepper__step-error{font-size:18px;font-weight:700}.tn-stepper__step-header--error .tn-stepper__step-title{color:var(--tn-fg1, #000000)}.tn-stepper__step-header--active.tn-stepper__step-header--error .tn-stepper__step-title{color:var(--tn-fg2, #6c757d);font-weight:600}.tn-stepper__step-header--optional .tn-stepper__step-indicator{border:2px dashed var(--tn-lines, #e5e7eb);background:transparent}.tn-stepper--horizontal .tn-stepper__step-header--completed+.tn-stepper__connector{background:var(--tn-green, #28a745)}.tn-stepper--horizontal .tn-stepper__step-header--completed+.tn-stepper__connector:after{content:\"\";position:absolute;top:0;left:0;right:0;height:100%;background:var(--tn-green, #28a745);animation:progressFill .3s ease-in-out}.tn-stepper--vertical .tn-stepper__step-header--completed+.tn-stepper__connector{background:var(--tn-green, #28a745)}.tn-stepper__content{min-height:200px}.tn-stepper__step-content{padding:16px;background:var(--tn-bg1, #ffffff);border-radius:8px;border:1px solid var(--tn-lines, #e5e7eb)}@keyframes progressFill{0%{width:0}to{width:100%}}.tn-stepper__step-header:focus{outline:2px solid var(--tn-primary, #007bff);outline-offset:2px}.tn-stepper__step-header:focus:not(:focus-visible){outline:none}@media(max-width:780px){.tn-stepper--vertical .tn-stepper__header{width:180px;border-right:none;border-bottom:1px solid var(--tn-lines, #e5e7eb);padding:16px 0}.tn-stepper--vertical .tn-stepper__step-header{flex-direction:column;align-items:center;text-align:center;min-width:80px;padding:8px 4px}.tn-stepper--vertical .tn-stepper__step-header .tn-stepper__step-label{margin-left:0;margin-top:8px}.tn-stepper--vertical .tn-stepper__connector{display:none}}@media(max-width:780px){.tn-stepper .tn-stepper__step-label{display:none}.tn-stepper .tn-stepper__step-indicator{width:var(--step-diameter-sm);height:var(--step-diameter-sm);font-size:12px}.tn-stepper--horizontal .tn-stepper__header{padding:0 8px}.tn-stepper--horizontal .tn-stepper__connector{top:calc(var(--step-diameter-sm) / 2);margin:0 8px}.tn-stepper--vertical .tn-stepper__header{width:60px}.tn-stepper--vertical .tn-stepper__step-header{padding:4px;margin-bottom:4px}.tn-stepper--vertical .tn-stepper__connector{left:calc(var(--step-diameter-sm) / 2 + 4px);height:16px;margin-bottom:4px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], animations: [
9292
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnStepperComponent, isStandalone: true, selector: "tn-stepper", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, linear: { classPropertyName: "linear", publicName: "linear", isSignal: true, isRequired: false, transformFunction: null }, selectedIndex: { classPropertyName: "selectedIndex", publicName: "selectedIndex", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedIndex: "selectedIndexChange", selectionChange: "selectionChange", completed: "completed" }, host: { listeners: { "window:resize": "onWindowResize($event)" } }, queries: [{ propertyName: "steps", predicate: TnStepComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"tn-stepper\"\n [class.tn-stepper--horizontal]=\"orientation() === 'horizontal' || (orientation() === 'auto' && isWideScreen())\"\n [class.tn-stepper--vertical]=\"orientation() === 'vertical' || (orientation() === 'auto' && !isWideScreen())\">\n\n <!-- Step Headers -->\n <div class=\"tn-stepper__header\">\n @for (step of steps(); track $index; let i = $index) {\n <div class=\"tn-stepper__step-header\"\n tabindex=\"0\"\n role=\"button\"\n [class.tn-stepper__step-header--active]=\"selectedIndex() === i\"\n [class.tn-stepper__step-header--completed]=\"step.completed()\"\n [class.tn-stepper__step-header--error]=\"step.hasError()\"\n [class.tn-stepper__step-header--optional]=\"step.optional()\"\n (click)=\"selectStep(i)\"\n (keydown.enter)=\"selectStep(i)\"\n (keydown.space)=\"selectStep(i)\">\n\n <!-- Step Number/Icon -->\n <div class=\"tn-stepper__step-indicator\">\n @if (step.completed() && !step.hasError()) {\n <span class=\"tn-stepper__step-check\">\u2713</span>\n }\n @if (step.hasError()) {\n <span class=\"tn-stepper__step-error\">!</span>\n }\n @if (!step.completed() && !step.hasError()) {\n @if (step.icon()) {\n <span class=\"tn-stepper__step-icon\">{{ step.icon() }}</span>\n } @else {\n <span class=\"tn-stepper__step-number\">{{ i + 1 }}</span>\n }\n }\n </div>\n\n <!-- Step Label -->\n <div class=\"tn-stepper__step-label\">\n <div class=\"tn-stepper__step-title\">{{ step.label() }}</div>\n @if (step.optional()) {\n <span class=\"tn-stepper__step-subtitle\">Optional</span>\n }\n </div>\n </div>\n\n <!-- Connector Line (except for last step) -->\n @if (i < steps().length - 1) {\n <div class=\"tn-stepper__connector\"></div>\n }\n }\n </div>\n\n <!-- Step Content -->\n <div class=\"tn-stepper__content\">\n @for (step of steps(); track $index; let i = $index) {\n @if (selectedIndex() === i) {\n <div class=\"tn-stepper__step-content\"\n [@stepTransition]=\"selectedIndex()\">\n <ng-container *ngTemplateOutlet=\"step.content()\" />\n </div>\n }\n }\n </div>\n</div>", styles: [".tn-stepper{display:flex;font-family:inherit;--step-diameter: 48px;--step-diameter-sm: 32px;--step-padding: 12px}.tn-stepper--horizontal{flex-direction:column}.tn-stepper--horizontal .tn-stepper__header{display:flex;justify-content:center;margin-bottom:32px;padding:0 16px}.tn-stepper--horizontal .tn-stepper__step-header{display:flex;flex-direction:column;align-items:center;text-align:center;cursor:pointer;transition:all .2s ease-in-out}.tn-stepper--horizontal .tn-stepper__step-header:not(.tn-stepper__step-header--active):hover .tn-stepper__step-indicator{transform:scale(.95)}.tn-stepper--horizontal .tn-stepper__connector{flex:1;height:2px;background:var(--tn-lines, #e5e7eb);margin:0 16px;position:relative;top:calc(var(--step-diameter) / 2)}.tn-stepper--vertical{flex-direction:row}.tn-stepper--vertical .tn-stepper__header{display:flex;flex-direction:column;width:280px;padding:16px;border-right:1px solid var(--tn-lines, #e5e7eb)}.tn-stepper--vertical .tn-stepper__step-header{display:flex;flex-direction:row;align-items:center;text-align:left;cursor:pointer;transition:all .2s ease-in-out;padding:var(--step-padding);border-radius:8px;margin-bottom:8px}.tn-stepper--vertical .tn-stepper__step-header:not(.tn-stepper__step-header--active):hover .tn-stepper__step-indicator{transform:scale(.95)}.tn-stepper--vertical .tn-stepper__step-header .tn-stepper__step-label{margin-left:12px;margin-top:0}.tn-stepper--vertical .tn-stepper__connector{width:2px;height:24px;background:var(--tn-lines, #e5e7eb);position:relative;left:calc(var(--step-diameter) / 2 + var(--step-padding));margin-bottom:8px}.tn-stepper--vertical .tn-stepper__content{flex:1;padding:16px}.tn-stepper__step-indicator{display:flex;align-items:center;justify-content:center;width:var(--step-diameter);height:var(--step-diameter);border-radius:50%;background:var(--tn-alt-bg1, #f8f9fa);color:var(--tn-alt-fg1, #495057);font-weight:400;font-size:14px;transition:all .2s ease-in-out;position:relative;transform:scale(.65)}.tn-stepper__step-number{font-weight:400}.tn-stepper__step-label{margin-top:8px}.tn-stepper__step-title{display:block;font-weight:400;font-size:14px;color:var(--tn-fg1, #000000);line-height:1.2}.tn-stepper__step-subtitle{display:block;font-size:12px;color:var(--tn-fg2, #6c757d);margin-top:2px}.tn-stepper__step-header--active .tn-stepper__step-indicator{background:var(--tn-primary, #007bff);color:var(--tn-primary-txt, #ffffff);transform:scale(1)}.tn-stepper__step-header--active .tn-stepper__step-title{color:var(--tn-fg2, #6c757d);font-weight:600}.tn-stepper__step-header--completed .tn-stepper__step-indicator{background:var(--tn-green, #28a745);color:#fff}.tn-stepper__step-header--completed .tn-stepper__step-check{font-size:16px;font-weight:700}.tn-stepper__step-header--error .tn-stepper__step-indicator{background:var(--tn-red, #dc3545);color:#fff}.tn-stepper__step-header--error .tn-stepper__step-error{font-size:18px;font-weight:700}.tn-stepper__step-header--error .tn-stepper__step-title{color:var(--tn-fg1, #000000)}.tn-stepper__step-header--active.tn-stepper__step-header--error .tn-stepper__step-title{color:var(--tn-fg2, #6c757d);font-weight:600}.tn-stepper__step-header--optional .tn-stepper__step-indicator{border:2px dashed var(--tn-lines, #e5e7eb);background:transparent}.tn-stepper--horizontal .tn-stepper__step-header--completed+.tn-stepper__connector{background:var(--tn-green, #28a745)}.tn-stepper--horizontal .tn-stepper__step-header--completed+.tn-stepper__connector:after{content:\"\";position:absolute;top:0;left:0;right:0;height:100%;background:var(--tn-green, #28a745);animation:progressFill .3s ease-in-out}.tn-stepper--vertical .tn-stepper__step-header--completed+.tn-stepper__connector{background:var(--tn-green, #28a745)}.tn-stepper__content{min-height:200px}.tn-stepper__step-content{padding:16px;background:var(--tn-bg1, #ffffff);border-radius:8px;border:1px solid var(--tn-lines, #e5e7eb)}@keyframes progressFill{0%{width:0}to{width:100%}}.tn-stepper__step-header:focus{outline:2px solid var(--tn-primary, #007bff);outline-offset:2px}.tn-stepper__step-header:focus:not(:focus-visible){outline:none}@media(max-width:780px){.tn-stepper--vertical .tn-stepper__header{width:180px;border-right:none;border-bottom:1px solid var(--tn-lines, #e5e7eb);padding:16px 0}.tn-stepper--vertical .tn-stepper__step-header{flex-direction:column;align-items:center;text-align:center;min-width:80px;padding:8px 4px}.tn-stepper--vertical .tn-stepper__step-header .tn-stepper__step-label{margin-left:0;margin-top:8px}.tn-stepper--vertical .tn-stepper__connector{display:none}}@media(max-width:780px){.tn-stepper .tn-stepper__step-label{display:none}.tn-stepper .tn-stepper__step-indicator{width:var(--step-diameter-sm);height:var(--step-diameter-sm);font-size:12px}.tn-stepper--horizontal .tn-stepper__header{padding:0 8px}.tn-stepper--horizontal .tn-stepper__connector{top:calc(var(--step-diameter-sm) / 2);margin:0 8px}.tn-stepper--vertical .tn-stepper__header{width:60px}.tn-stepper--vertical .tn-stepper__step-header{padding:4px;margin-bottom:4px}.tn-stepper--vertical .tn-stepper__connector{left:calc(var(--step-diameter-sm) / 2 + 4px);height:16px;margin-bottom:4px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], animations: [
9049
9293
  trigger('stepTransition', [
9050
9294
  transition(':enter', [
9051
9295
  style({ opacity: 0, transform: 'translateX(50px)' }),
@@ -10648,5 +10892,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImpor
10648
10892
  * Generated bundle index. Do not edit.
10649
10893
  */
10650
10894
 
10651
- export { CommonShortcuts, DEFAULT_THEME, DiskIconComponent, DiskType, FileSizePipe, InputType, LIGHT_THEME, LinuxModifierKeys, LinuxShortcuts, ModifierKeys, QuickShortcuts, ShortcutBuilder, StripMntPrefixPipe, THEME_MAP, THEME_STORAGE_KEY, TN_THEME_DEFINITIONS, TnAutocompleteComponent, TnAutocompleteHarness, TnBannerActionDirective, TnBannerComponent, TnBannerHarness, TnBrandedSpinnerComponent, TnButtonComponent, TnButtonHarness, TnButtonToggleComponent, TnButtonToggleGroupComponent, TnCalendarComponent, TnCalendarHeaderComponent, TnCardComponent, TnCellDefDirective, TnCheckboxComponent, TnCheckboxHarness, TnCheckboxLabelDirective, TnChipComponent, TnConfirmDialogComponent, TnDateInputComponent, TnDateRangeInputComponent, TnDialog, TnDialogHarness, TnDialogShellComponent, TnDialogTesting, TnDividerComponent, TnDividerDirective, TnEmptyComponent, TnEmptyHarness, TnExpansionPanelComponent, TnFilePickerComponent, TnFilePickerPopupComponent, TnFormFieldComponent, TnHeaderCellDefDirective, TnIconButtonComponent, TnIconButtonHarness, TnIconComponent, TnIconHarness, TnIconRegistryService, TnIconTesting, TnInputComponent, TnInputDirective, TnInputHarness, TnKeyboardShortcutComponent, TnKeyboardShortcutService, TnListAvatarDirective, TnListComponent, TnListIconDirective, TnListItemComponent, TnListItemLineDirective, TnListItemPrimaryDirective, TnListItemSecondaryDirective, TnListItemTitleDirective, TnListItemTrailingDirective, TnListOptionComponent, TnListSubheaderComponent, TnMenuActivateHoverDirective, TnMenuComponent, TnMenuTriggerDirective, TnMonthViewComponent, TnMultiYearViewComponent, TnNestedTreeNodeComponent, TnParticleProgressBarComponent, TnProgressBarComponent, TnRadioComponent, TnSelectComponent, TnSelectHarness, TnSelectionListComponent, TnSidePanelActionDirective, TnSidePanelComponent, TnSidePanelHarness, TnSidePanelHeaderActionDirective, TnSlideToggleComponent, TnSliderComponent, TnSliderThumbDirective, TnSliderWithLabelDirective, TnSpinnerComponent, TnSpriteLoaderService, TnStepComponent, TnStepperComponent, TnTabComponent, TnTabHarness, TnTabPanelComponent, TnTabPanelHarness, TnTableColumnDirective, TnTableComponent, TnTabsComponent, TnTabsHarness, TnTheme, TnThemeService, TnTimeInputComponent, TnTooltipComponent, TnTooltipDirective, TnTreeComponent, TnTreeFlatDataSource, TnTreeFlattener, TnTreeNodeComponent, TnTreeNodeOutletDirective, TruncatePathPipe, WindowsModifierKeys, WindowsShortcuts, createLucideLibrary, createShortcut, defaultSpriteBasePath, defaultSpriteConfigPath, libIconMarker, registerLucideIcons, setupLucideIntegration, tnIconMarker };
10895
+ export { CommonShortcuts, DEFAULT_THEME, DiskIconComponent, DiskType, FileSizePipe, InputType, LIGHT_THEME, LinuxModifierKeys, LinuxShortcuts, ModifierKeys, QuickShortcuts, ShortcutBuilder, StripMntPrefixPipe, THEME_MAP, THEME_STORAGE_KEY, TN_THEME_DEFINITIONS, TnAutocompleteComponent, TnAutocompleteHarness, TnBannerActionDirective, TnBannerComponent, TnBannerHarness, TnBrandedSpinnerComponent, TnButtonComponent, TnButtonHarness, TnButtonToggleComponent, TnButtonToggleGroupComponent, TnCalendarComponent, TnCalendarHeaderComponent, TnCardComponent, TnCellDefDirective, TnCheckboxComponent, TnCheckboxHarness, TnCheckboxLabelDirective, TnChipComponent, TnConfirmDialogComponent, TnDateInputComponent, TnDateRangeInputComponent, TnDialog, TnDialogHarness, TnDialogShellComponent, TnDialogTesting, TnDividerComponent, TnDividerDirective, TnDrawerComponent, TnDrawerContainerComponent, TnDrawerContainerHarness, TnDrawerContentComponent, TnDrawerHarness, TnEmptyComponent, TnEmptyHarness, TnExpansionPanelComponent, TnFilePickerComponent, TnFilePickerPopupComponent, TnFormFieldComponent, TnHeaderCellDefDirective, TnIconButtonComponent, TnIconButtonHarness, TnIconComponent, TnIconHarness, TnIconRegistryService, TnIconTesting, TnInputComponent, TnInputDirective, TnInputHarness, TnKeyboardShortcutComponent, TnKeyboardShortcutService, TnListAvatarDirective, TnListComponent, TnListIconDirective, TnListItemComponent, TnListItemLineDirective, TnListItemPrimaryDirective, TnListItemSecondaryDirective, TnListItemTitleDirective, TnListItemTrailingDirective, TnListOptionComponent, TnListSubheaderComponent, TnMenuActivateHoverDirective, TnMenuComponent, TnMenuTriggerDirective, TnMonthViewComponent, TnMultiYearViewComponent, TnNestedTreeNodeComponent, TnParticleProgressBarComponent, TnProgressBarComponent, TnRadioComponent, TnSelectComponent, TnSelectHarness, TnSelectionListComponent, TnSidePanelActionDirective, TnSidePanelComponent, TnSidePanelHarness, TnSidePanelHeaderActionDirective, TnSlideToggleComponent, TnSliderComponent, TnSliderThumbDirective, TnSliderWithLabelDirective, TnSpinnerComponent, TnSpriteLoaderService, TnStepComponent, TnStepperComponent, TnTabComponent, TnTabHarness, TnTabPanelComponent, TnTabPanelHarness, TnTableColumnDirective, TnTableComponent, TnTabsComponent, TnTabsHarness, TnTheme, TnThemeService, TnTimeInputComponent, TnTooltipComponent, TnTooltipDirective, TnTreeComponent, TnTreeFlatDataSource, TnTreeFlattener, TnTreeNodeComponent, TnTreeNodeOutletDirective, TruncatePathPipe, WindowsModifierKeys, WindowsShortcuts, createLucideLibrary, createShortcut, defaultSpriteBasePath, defaultSpriteConfigPath, libIconMarker, registerLucideIcons, setupLucideIntegration, tnIconMarker };
10652
10896
  //# sourceMappingURL=truenas-ui-components.mjs.map