@truenas/ui-components 0.1.60 → 0.1.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, inject, Renderer2, ElementRef, input, effect, Directive, output, viewChild, signal, computed, forwardRef, Component, model, afterNextRender, ChangeDetectionStrategy, Injectable, isDevMode, ViewEncapsulation, contentChildren, ViewContainerRef, contentChild, ChangeDetectorRef,
|
|
2
|
+
import { InjectionToken, inject, Renderer2, ElementRef, input, effect, Directive, output, viewChild, signal, computed, forwardRef, Component, model, afterNextRender, ChangeDetectionStrategy, Injectable, isDevMode, ViewEncapsulation, contentChildren, ViewContainerRef, HostListener, contentChild, ChangeDetectorRef, TemplateRef, DestroyRef, isSignal, untracked, IterableDiffers, Pipe, ApplicationRef, EnvironmentInjector, createComponent, PLATFORM_ID } from '@angular/core';
|
|
3
3
|
import * as i2 from '@angular/forms';
|
|
4
4
|
import { NG_VALUE_ACCESSOR, FormsModule, NgControl } from '@angular/forms';
|
|
5
5
|
import { ComponentHarness, HarnessPredicate, TestKey } from '@angular/cdk/testing';
|
|
@@ -13,8 +13,8 @@ import { DomSanitizer } from '@angular/platform-browser';
|
|
|
13
13
|
import { HttpClient } from '@angular/common/http';
|
|
14
14
|
import { firstValueFrom, BehaviorSubject, merge, Subject } from 'rxjs';
|
|
15
15
|
import { RouterLink } from '@angular/router';
|
|
16
|
-
import { Overlay,
|
|
17
|
-
import { TemplatePortal, PortalModule
|
|
16
|
+
import { Overlay, OverlayPositionBuilder, OverlayModule } from '@angular/cdk/overlay';
|
|
17
|
+
import { ComponentPortal, TemplatePortal, PortalModule } from '@angular/cdk/portal';
|
|
18
18
|
import { CdkMenu, CdkMenuItem, CdkMenuTrigger } from '@angular/cdk/menu';
|
|
19
19
|
import { trigger, state, transition, style, animate } from '@angular/animations';
|
|
20
20
|
import { SPACE, ENTER, END, HOME, DOWN_ARROW, UP_ARROW, RIGHT_ARROW, LEFT_ARROW } from '@angular/cdk/keycodes';
|
|
@@ -1785,10 +1785,244 @@ class TnButtonHarness extends ComponentHarness {
|
|
|
1785
1785
|
}
|
|
1786
1786
|
}
|
|
1787
1787
|
|
|
1788
|
+
class TnTooltipComponent {
|
|
1789
|
+
message = input('', ...(ngDevMode ? [{ debugName: "message" }] : []));
|
|
1790
|
+
id = input('', ...(ngDevMode ? [{ debugName: "id" }] : []));
|
|
1791
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1792
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.0", type: TnTooltipComponent, isStandalone: true, selector: "tn-tooltip", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "tn-tooltip-component" }, ngImport: i0, template: "<div\n class=\"tn-tooltip\"\n role=\"tooltip\"\n [id]=\"id()\"\n [attr.aria-hidden]=\"false\">\n {{ message() }}\n</div>\n", styles: [":host{display:block;pointer-events:none;z-index:1200}.tn-tooltip{background:#373737e6;color:#fff;padding:6px 8px;border-radius:4px;font-size:12px;font-weight:500;line-height:1.4;max-width:200px;word-wrap:break-word;white-space:pre-line;box-shadow:0 2px 8px #0003;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);animation:tn-tooltip-show .15s cubic-bezier(0,0,.2,1) forwards;transform-origin:center bottom}@keyframes tn-tooltip-show{0%{opacity:0;transform:scale(.8)}to{opacity:1;transform:scale(1)}}.tn-tooltip{position:relative}.tn-tooltip:after{content:\"\";position:absolute;width:0;height:0;border-style:solid;z-index:1}:host-context(.tn-tooltip-panel-above) .tn-tooltip:after{top:100%;left:50%;transform:translate(-50%);border-width:6px 6px 0 6px;border-color:rgba(55,55,55,.9) transparent transparent transparent}:host-context(.tn-tooltip-panel-below) .tn-tooltip:after{bottom:100%;left:50%;transform:translate(-50%);border-width:0 6px 6px 6px;border-color:transparent transparent rgba(55,55,55,.9) transparent}:host-context(.tn-tooltip-panel-left) .tn-tooltip:after,:host-context(.tn-tooltip-panel-before) .tn-tooltip:after{top:50%;left:100%;transform:translateY(-50%);border-width:6px 0 6px 6px;border-color:transparent transparent transparent rgba(55,55,55,.9)}:host-context(.tn-tooltip-panel-right) .tn-tooltip:after,:host-context(.tn-tooltip-panel-after) .tn-tooltip:after{top:50%;right:100%;transform:translateY(-50%);border-width:6px 6px 6px 0;border-color:transparent rgba(55,55,55,.9) transparent transparent}@media(prefers-contrast:high){.tn-tooltip{background:var(--tn-fg1, #000);color:var(--tn-bg1, #fff);border:1px solid var(--tn-lines, #999)}:host-context(.tn-tooltip-panel-above) .tn-tooltip:after{border-top-color:var(--tn-fg1, #000)}:host-context(.tn-tooltip-panel-below) .tn-tooltip:after{border-bottom-color:var(--tn-fg1, #000)}:host-context(.tn-tooltip-panel-left) .tn-tooltip:after,:host-context(.tn-tooltip-panel-before) .tn-tooltip:after{border-left-color:var(--tn-fg1, #000)}:host-context(.tn-tooltip-panel-right) .tn-tooltip:after,:host-context(.tn-tooltip-panel-after) .tn-tooltip:after{border-right-color:var(--tn-fg1, #000)}}:host-context(.tn-slider-thumb-label) .tn-tooltip{font-size:11px;padding:4px 6px;font-weight:600;min-width:24px;text-align:center;background:#373737f2}@media(prefers-reduced-motion:reduce){.tn-tooltip{animation:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1793
|
+
}
|
|
1794
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTooltipComponent, decorators: [{
|
|
1795
|
+
type: Component,
|
|
1796
|
+
args: [{ selector: 'tn-tooltip', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
1797
|
+
'class': 'tn-tooltip-component'
|
|
1798
|
+
}, template: "<div\n class=\"tn-tooltip\"\n role=\"tooltip\"\n [id]=\"id()\"\n [attr.aria-hidden]=\"false\">\n {{ message() }}\n</div>\n", styles: [":host{display:block;pointer-events:none;z-index:1200}.tn-tooltip{background:#373737e6;color:#fff;padding:6px 8px;border-radius:4px;font-size:12px;font-weight:500;line-height:1.4;max-width:200px;word-wrap:break-word;white-space:pre-line;box-shadow:0 2px 8px #0003;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);animation:tn-tooltip-show .15s cubic-bezier(0,0,.2,1) forwards;transform-origin:center bottom}@keyframes tn-tooltip-show{0%{opacity:0;transform:scale(.8)}to{opacity:1;transform:scale(1)}}.tn-tooltip{position:relative}.tn-tooltip:after{content:\"\";position:absolute;width:0;height:0;border-style:solid;z-index:1}:host-context(.tn-tooltip-panel-above) .tn-tooltip:after{top:100%;left:50%;transform:translate(-50%);border-width:6px 6px 0 6px;border-color:rgba(55,55,55,.9) transparent transparent transparent}:host-context(.tn-tooltip-panel-below) .tn-tooltip:after{bottom:100%;left:50%;transform:translate(-50%);border-width:0 6px 6px 6px;border-color:transparent transparent rgba(55,55,55,.9) transparent}:host-context(.tn-tooltip-panel-left) .tn-tooltip:after,:host-context(.tn-tooltip-panel-before) .tn-tooltip:after{top:50%;left:100%;transform:translateY(-50%);border-width:6px 0 6px 6px;border-color:transparent transparent transparent rgba(55,55,55,.9)}:host-context(.tn-tooltip-panel-right) .tn-tooltip:after,:host-context(.tn-tooltip-panel-after) .tn-tooltip:after{top:50%;right:100%;transform:translateY(-50%);border-width:6px 6px 6px 0;border-color:transparent rgba(55,55,55,.9) transparent transparent}@media(prefers-contrast:high){.tn-tooltip{background:var(--tn-fg1, #000);color:var(--tn-bg1, #fff);border:1px solid var(--tn-lines, #999)}:host-context(.tn-tooltip-panel-above) .tn-tooltip:after{border-top-color:var(--tn-fg1, #000)}:host-context(.tn-tooltip-panel-below) .tn-tooltip:after{border-bottom-color:var(--tn-fg1, #000)}:host-context(.tn-tooltip-panel-left) .tn-tooltip:after,:host-context(.tn-tooltip-panel-before) .tn-tooltip:after{border-left-color:var(--tn-fg1, #000)}:host-context(.tn-tooltip-panel-right) .tn-tooltip:after,:host-context(.tn-tooltip-panel-after) .tn-tooltip:after{border-right-color:var(--tn-fg1, #000)}}:host-context(.tn-slider-thumb-label) .tn-tooltip{font-size:11px;padding:4px 6px;font-weight:600;min-width:24px;text-align:center;background:#373737f2}@media(prefers-reduced-motion:reduce){.tn-tooltip{animation:none}}\n"] }]
|
|
1799
|
+
}], propDecorators: { message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }] } });
|
|
1800
|
+
|
|
1801
|
+
/* eslint-disable @angular-eslint/no-input-rename */
|
|
1802
|
+
// Input aliasing is intentional for directive API consistency (e.g., ixTooltip, ixTooltipPosition)
|
|
1803
|
+
// This follows the standard Angular pattern used by Material and other directive-based components
|
|
1804
|
+
class TnTooltipDirective {
|
|
1805
|
+
message = input('', { ...(ngDevMode ? { debugName: "message" } : {}), alias: 'tnTooltip' });
|
|
1806
|
+
position = input('above', { ...(ngDevMode ? { debugName: "position" } : {}), alias: 'tnTooltipPosition' });
|
|
1807
|
+
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : {}), alias: 'tnTooltipDisabled' });
|
|
1808
|
+
showDelay = input(0, { ...(ngDevMode ? { debugName: "showDelay" } : {}), alias: 'tnTooltipShowDelay' });
|
|
1809
|
+
hideDelay = input(0, { ...(ngDevMode ? { debugName: "hideDelay" } : {}), alias: 'tnTooltipHideDelay' });
|
|
1810
|
+
tooltipClass = input('', { ...(ngDevMode ? { debugName: "tooltipClass" } : {}), alias: 'tnTooltipClass' });
|
|
1811
|
+
_overlayRef = null;
|
|
1812
|
+
_tooltipInstance = null;
|
|
1813
|
+
_showTimeout = null;
|
|
1814
|
+
_hideTimeout = null;
|
|
1815
|
+
_isTooltipVisible = false;
|
|
1816
|
+
_positionSub = null;
|
|
1817
|
+
_tooltipId = '';
|
|
1818
|
+
/**
|
|
1819
|
+
* Only point `aria-describedby` at the tooltip when there is actually a message to
|
|
1820
|
+
* describe. Otherwise every host (e.g. an icon button with no tooltip) would carry a
|
|
1821
|
+
* dangling reference to a tooltip element that is never rendered.
|
|
1822
|
+
*/
|
|
1823
|
+
get _ariaDescribedBy() {
|
|
1824
|
+
return !this.disabled() && this.message() ? this._tooltipId : null;
|
|
1825
|
+
}
|
|
1826
|
+
_overlay = inject(Overlay);
|
|
1827
|
+
_elementRef = inject((ElementRef));
|
|
1828
|
+
_viewContainerRef = inject(ViewContainerRef);
|
|
1829
|
+
_overlayPositionBuilder = inject(OverlayPositionBuilder);
|
|
1830
|
+
ngOnInit() {
|
|
1831
|
+
// Generate unique ID for aria-describedby
|
|
1832
|
+
this._tooltipId = `tn-tooltip-${Math.random().toString(36).substr(2, 9)}`;
|
|
1833
|
+
}
|
|
1834
|
+
ngOnDestroy() {
|
|
1835
|
+
this._clearTimeouts();
|
|
1836
|
+
this.hide(0);
|
|
1837
|
+
this._positionSub?.unsubscribe();
|
|
1838
|
+
if (this._overlayRef) {
|
|
1839
|
+
this._overlayRef.dispose();
|
|
1840
|
+
this._overlayRef = null;
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
_onMouseEnter() {
|
|
1844
|
+
if (!this.disabled() && this.message()) {
|
|
1845
|
+
this.show(this.showDelay());
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
_onMouseLeave() {
|
|
1849
|
+
this.hide(this.hideDelay());
|
|
1850
|
+
}
|
|
1851
|
+
_onFocus() {
|
|
1852
|
+
if (!this.disabled() && this.message()) {
|
|
1853
|
+
this.show(this.showDelay());
|
|
1854
|
+
}
|
|
1855
|
+
}
|
|
1856
|
+
_onBlur() {
|
|
1857
|
+
this.hide(this.hideDelay());
|
|
1858
|
+
}
|
|
1859
|
+
_onKeydown(event) {
|
|
1860
|
+
if (event.key === 'Escape' && this._isTooltipVisible) {
|
|
1861
|
+
this.hide(0);
|
|
1862
|
+
}
|
|
1863
|
+
}
|
|
1864
|
+
/** Shows the tooltip */
|
|
1865
|
+
show(delay = 0) {
|
|
1866
|
+
if (this.disabled() || !this.message() || this._isTooltipVisible) {
|
|
1867
|
+
return;
|
|
1868
|
+
}
|
|
1869
|
+
this._clearTimeouts();
|
|
1870
|
+
this._showTimeout = setTimeout(() => {
|
|
1871
|
+
if (!this._overlayRef) {
|
|
1872
|
+
this._createOverlay();
|
|
1873
|
+
}
|
|
1874
|
+
this._attachTooltip();
|
|
1875
|
+
}, delay);
|
|
1876
|
+
}
|
|
1877
|
+
/** Hides the tooltip */
|
|
1878
|
+
hide(delay = 0) {
|
|
1879
|
+
this._clearTimeouts();
|
|
1880
|
+
this._hideTimeout = setTimeout(() => {
|
|
1881
|
+
if (this._tooltipInstance) {
|
|
1882
|
+
this._tooltipInstance.destroy();
|
|
1883
|
+
this._tooltipInstance = null;
|
|
1884
|
+
this._isTooltipVisible = false;
|
|
1885
|
+
}
|
|
1886
|
+
}, delay);
|
|
1887
|
+
}
|
|
1888
|
+
/** Toggle the tooltip visibility */
|
|
1889
|
+
toggle() {
|
|
1890
|
+
this._isTooltipVisible ? this.hide() : this.show();
|
|
1891
|
+
}
|
|
1892
|
+
_createOverlay() {
|
|
1893
|
+
const positions = this._getPositions();
|
|
1894
|
+
const positionStrategy = this._overlayPositionBuilder
|
|
1895
|
+
.flexibleConnectedTo(this._elementRef)
|
|
1896
|
+
.withPositions(positions)
|
|
1897
|
+
.withFlexibleDimensions(false)
|
|
1898
|
+
.withViewportMargin(8)
|
|
1899
|
+
.withScrollableContainers([]);
|
|
1900
|
+
this._overlayRef = this._overlay.create({
|
|
1901
|
+
positionStrategy,
|
|
1902
|
+
scrollStrategy: this._overlay.scrollStrategies.reposition({ scrollThrottle: 20 }),
|
|
1903
|
+
panelClass: ['tn-tooltip-panel', `tn-tooltip-panel-${this.position()}`, this.tooltipClass()].filter(Boolean),
|
|
1904
|
+
});
|
|
1905
|
+
this._positionSub = positionStrategy.positionChanges
|
|
1906
|
+
.subscribe((change) => {
|
|
1907
|
+
// The position panelClass is applied to the overlay pane (overlayElement), so the
|
|
1908
|
+
// resolved-position class must be toggled on that same element. Updating the parent
|
|
1909
|
+
// instead left the stale initial class on the pane, so after a flip both the original
|
|
1910
|
+
// and resolved classes matched :host-context and the arrow rendered incorrectly.
|
|
1911
|
+
const panel = this._overlayRef?.overlayElement;
|
|
1912
|
+
if (!panel) {
|
|
1913
|
+
return;
|
|
1914
|
+
}
|
|
1915
|
+
const actual = this._resolvePosition(change.connectionPair);
|
|
1916
|
+
const allPositionClasses = [
|
|
1917
|
+
'tn-tooltip-panel-above', 'tn-tooltip-panel-below',
|
|
1918
|
+
'tn-tooltip-panel-left', 'tn-tooltip-panel-right',
|
|
1919
|
+
'tn-tooltip-panel-before', 'tn-tooltip-panel-after',
|
|
1920
|
+
];
|
|
1921
|
+
panel.classList.remove(...allPositionClasses);
|
|
1922
|
+
panel.classList.add(`tn-tooltip-panel-${actual}`);
|
|
1923
|
+
});
|
|
1924
|
+
}
|
|
1925
|
+
_resolvePosition(pair) {
|
|
1926
|
+
if (pair.overlayY === 'bottom') {
|
|
1927
|
+
return 'above';
|
|
1928
|
+
}
|
|
1929
|
+
if (pair.overlayY === 'top') {
|
|
1930
|
+
return 'below';
|
|
1931
|
+
}
|
|
1932
|
+
if (pair.overlayX === 'end') {
|
|
1933
|
+
return 'left';
|
|
1934
|
+
}
|
|
1935
|
+
return 'right';
|
|
1936
|
+
}
|
|
1937
|
+
_attachTooltip() {
|
|
1938
|
+
if (!this._overlayRef) {
|
|
1939
|
+
return;
|
|
1940
|
+
}
|
|
1941
|
+
if (!this._tooltipInstance) {
|
|
1942
|
+
const portal = new ComponentPortal(TnTooltipComponent, this._viewContainerRef);
|
|
1943
|
+
this._tooltipInstance = this._overlayRef.attach(portal);
|
|
1944
|
+
this._tooltipInstance.setInput('message', this.message());
|
|
1945
|
+
this._tooltipInstance.setInput('id', this._tooltipId);
|
|
1946
|
+
this._isTooltipVisible = true;
|
|
1947
|
+
}
|
|
1948
|
+
}
|
|
1949
|
+
_getPositions() {
|
|
1950
|
+
switch (this.position()) {
|
|
1951
|
+
case 'above':
|
|
1952
|
+
return [
|
|
1953
|
+
{ originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom', offsetY: -12 },
|
|
1954
|
+
{ originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top', offsetY: 12 },
|
|
1955
|
+
];
|
|
1956
|
+
case 'below':
|
|
1957
|
+
return [
|
|
1958
|
+
{ originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top', offsetY: 12 },
|
|
1959
|
+
{ originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom', offsetY: -12 },
|
|
1960
|
+
];
|
|
1961
|
+
case 'left':
|
|
1962
|
+
case 'before':
|
|
1963
|
+
return [
|
|
1964
|
+
{ originX: 'start', originY: 'center', overlayX: 'end', overlayY: 'center', offsetX: -12 },
|
|
1965
|
+
{ originX: 'end', originY: 'center', overlayX: 'start', overlayY: 'center', offsetX: 12 },
|
|
1966
|
+
];
|
|
1967
|
+
case 'right':
|
|
1968
|
+
case 'after':
|
|
1969
|
+
return [
|
|
1970
|
+
{ originX: 'end', originY: 'center', overlayX: 'start', overlayY: 'center', offsetX: 12 },
|
|
1971
|
+
{ originX: 'start', originY: 'center', overlayX: 'end', overlayY: 'center', offsetX: -12 },
|
|
1972
|
+
];
|
|
1973
|
+
default:
|
|
1974
|
+
return [
|
|
1975
|
+
{ originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top', offsetY: 12 },
|
|
1976
|
+
];
|
|
1977
|
+
}
|
|
1978
|
+
}
|
|
1979
|
+
_clearTimeouts() {
|
|
1980
|
+
if (this._showTimeout) {
|
|
1981
|
+
clearTimeout(this._showTimeout);
|
|
1982
|
+
this._showTimeout = null;
|
|
1983
|
+
}
|
|
1984
|
+
if (this._hideTimeout) {
|
|
1985
|
+
clearTimeout(this._hideTimeout);
|
|
1986
|
+
this._hideTimeout = null;
|
|
1987
|
+
}
|
|
1988
|
+
}
|
|
1989
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTooltipDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1990
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.0", type: TnTooltipDirective, isStandalone: true, selector: "[tnTooltip]", inputs: { message: { classPropertyName: "message", publicName: "tnTooltip", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "tnTooltipPosition", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "tnTooltipDisabled", isSignal: true, isRequired: false, transformFunction: null }, showDelay: { classPropertyName: "showDelay", publicName: "tnTooltipShowDelay", isSignal: true, isRequired: false, transformFunction: null }, hideDelay: { classPropertyName: "hideDelay", publicName: "tnTooltipHideDelay", isSignal: true, isRequired: false, transformFunction: null }, tooltipClass: { classPropertyName: "tooltipClass", publicName: "tnTooltipClass", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mouseenter": "_onMouseEnter()", "mouseleave": "_onMouseLeave()", "focus": "_onFocus()", "blur": "_onBlur()", "keydown": "_onKeydown($event)" }, properties: { "attr.aria-describedby": "_ariaDescribedBy" } }, ngImport: i0 });
|
|
1991
|
+
}
|
|
1992
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTooltipDirective, decorators: [{
|
|
1993
|
+
type: Directive,
|
|
1994
|
+
args: [{
|
|
1995
|
+
selector: '[tnTooltip]',
|
|
1996
|
+
standalone: true,
|
|
1997
|
+
host: {
|
|
1998
|
+
'[attr.aria-describedby]': '_ariaDescribedBy',
|
|
1999
|
+
}
|
|
2000
|
+
}]
|
|
2001
|
+
}], propDecorators: { message: [{ type: i0.Input, args: [{ isSignal: true, alias: "tnTooltip", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "tnTooltipPosition", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "tnTooltipDisabled", required: false }] }], showDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "tnTooltipShowDelay", required: false }] }], hideDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "tnTooltipHideDelay", required: false }] }], tooltipClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "tnTooltipClass", required: false }] }], _onMouseEnter: [{
|
|
2002
|
+
type: HostListener,
|
|
2003
|
+
args: ['mouseenter']
|
|
2004
|
+
}], _onMouseLeave: [{
|
|
2005
|
+
type: HostListener,
|
|
2006
|
+
args: ['mouseleave']
|
|
2007
|
+
}], _onFocus: [{
|
|
2008
|
+
type: HostListener,
|
|
2009
|
+
args: ['focus']
|
|
2010
|
+
}], _onBlur: [{
|
|
2011
|
+
type: HostListener,
|
|
2012
|
+
args: ['blur']
|
|
2013
|
+
}], _onKeydown: [{
|
|
2014
|
+
type: HostListener,
|
|
2015
|
+
args: ['keydown', ['$event']]
|
|
2016
|
+
}] } });
|
|
2017
|
+
|
|
1788
2018
|
class TnIconButtonComponent {
|
|
1789
2019
|
// Button-related inputs
|
|
1790
2020
|
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
2021
|
+
/** Compact variant with reduced padding, for dense contexts like toolbars. */
|
|
2022
|
+
dense = input(false, ...(ngDevMode ? [{ debugName: "dense" }] : []));
|
|
1791
2023
|
ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
|
|
2024
|
+
/** Reflects an expanded/collapsed state (e.g. toggling a panel) onto the inner button. */
|
|
2025
|
+
ariaExpanded = input(undefined, ...(ngDevMode ? [{ debugName: "ariaExpanded" }] : []));
|
|
1792
2026
|
/**
|
|
1793
2027
|
* Test-id applied to the rendered `<button>` element. Rendered under whichever attribute
|
|
1794
2028
|
* name is configured via `TN_TEST_ATTR` (default `data-testid`).
|
|
@@ -1799,7 +2033,11 @@ class TnIconButtonComponent {
|
|
|
1799
2033
|
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
|
|
1800
2034
|
color = input(undefined, ...(ngDevMode ? [{ debugName: "color" }] : []));
|
|
1801
2035
|
tooltip = input(undefined, ...(ngDevMode ? [{ debugName: "tooltip" }] : []));
|
|
2036
|
+
/** Position of the styled tooltip relative to the button. */
|
|
2037
|
+
tooltipPosition = input('above', ...(ngDevMode ? [{ debugName: "tooltipPosition" }] : []));
|
|
1802
2038
|
library = input(undefined, ...(ngDevMode ? [{ debugName: "library" }] : []));
|
|
2039
|
+
/** Extra class(es) applied to the inner icon, e.g. for animations or state colors. */
|
|
2040
|
+
iconClass = input('', ...(ngDevMode ? [{ debugName: "iconClass" }] : []));
|
|
1803
2041
|
onClick = output();
|
|
1804
2042
|
hostRef = inject((ElementRef));
|
|
1805
2043
|
buttonRef = viewChild.required('button');
|
|
@@ -1808,6 +2046,9 @@ class TnIconButtonComponent {
|
|
|
1808
2046
|
if (this.color()) {
|
|
1809
2047
|
result.push('tn-icon-button--custom-color');
|
|
1810
2048
|
}
|
|
2049
|
+
if (this.dense()) {
|
|
2050
|
+
result.push('tn-icon-button--dense');
|
|
2051
|
+
}
|
|
1811
2052
|
return result;
|
|
1812
2053
|
}, ...(ngDevMode ? [{ debugName: "classes" }] : []));
|
|
1813
2054
|
effectiveAriaLabel = computed(() => {
|
|
@@ -1842,12 +2083,12 @@ class TnIconButtonComponent {
|
|
|
1842
2083
|
host.focus = (options) => inner.focus(options);
|
|
1843
2084
|
}
|
|
1844
2085
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnIconButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1845
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.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 }, testId: { classPropertyName: "testId", publicName: "testId", 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" }, viewQueries: [{ propertyName: "buttonRef", first: true, predicate: ["button"], descendants: true, isSignal: true }], ngImport: i0, template: "<button\n #button\n type=\"button\"\n [ngClass]=\"classes()\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"effectiveAriaLabel()\"\n [attr.
|
|
2086
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.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 }, dense: { classPropertyName: "dense", publicName: "dense", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaExpanded: { classPropertyName: "ariaExpanded", publicName: "ariaExpanded", isSignal: true, isRequired: false, transformFunction: null }, testId: { classPropertyName: "testId", publicName: "testId", 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 }, tooltipPosition: { classPropertyName: "tooltipPosition", publicName: "tooltipPosition", isSignal: true, isRequired: false, transformFunction: null }, library: { classPropertyName: "library", publicName: "library", isSignal: true, isRequired: false, transformFunction: null }, iconClass: { classPropertyName: "iconClass", publicName: "iconClass", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClick: "onClick" }, viewQueries: [{ propertyName: "buttonRef", first: true, predicate: ["button"], descendants: true, isSignal: true }], ngImport: i0, template: "<button\n #button\n type=\"button\"\n [ngClass]=\"classes()\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"effectiveAriaLabel()\"\n [attr.aria-expanded]=\"ariaExpanded()\"\n [tnTestId]=\"testId()\"\n [tnTooltip]=\"tooltip() || ''\"\n [tnTooltipPosition]=\"tooltipPosition()\"\n (click)=\"onClick.emit($event)\"\n>\n <tn-icon\n [name]=\"name()\"\n [size]=\"size()\"\n [color]=\"color()\"\n [library]=\"library()\"\n [ngClass]=\"iconClass()\"\n [ariaLabel]=\"effectiveAriaLabel()\" />\n <ng-content />\n</button>\n", styles: [":host{display:inline-block;width:fit-content}.tn-icon-button{position:relative;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--dense{padding:3px}.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"] }, { kind: "directive", type: TnTestIdDirective, selector: "[tnTestId]", inputs: ["tnTestId"] }, { kind: "directive", type: TnTooltipDirective, selector: "[tnTooltip]", inputs: ["tnTooltip", "tnTooltipPosition", "tnTooltipDisabled", "tnTooltipShowDelay", "tnTooltipHideDelay", "tnTooltipClass"] }] });
|
|
1846
2087
|
}
|
|
1847
2088
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnIconButtonComponent, decorators: [{
|
|
1848
2089
|
type: Component,
|
|
1849
|
-
args: [{ selector: 'tn-icon-button', standalone: true, imports: [CommonModule, TnIconComponent, TnTestIdDirective], template: "<button\n #button\n type=\"button\"\n [ngClass]=\"classes()\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"effectiveAriaLabel()\"\n [attr.
|
|
1850
|
-
}], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], testId: [{ type: i0.Input, args: [{ isSignal: true, alias: "testId", 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"] }], buttonRef: [{ type: i0.ViewChild, args: ['button', { isSignal: true }] }] } });
|
|
2090
|
+
args: [{ selector: 'tn-icon-button', standalone: true, imports: [CommonModule, TnIconComponent, TnTestIdDirective, TnTooltipDirective], template: "<button\n #button\n type=\"button\"\n [ngClass]=\"classes()\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"effectiveAriaLabel()\"\n [attr.aria-expanded]=\"ariaExpanded()\"\n [tnTestId]=\"testId()\"\n [tnTooltip]=\"tooltip() || ''\"\n [tnTooltipPosition]=\"tooltipPosition()\"\n (click)=\"onClick.emit($event)\"\n>\n <tn-icon\n [name]=\"name()\"\n [size]=\"size()\"\n [color]=\"color()\"\n [library]=\"library()\"\n [ngClass]=\"iconClass()\"\n [ariaLabel]=\"effectiveAriaLabel()\" />\n <ng-content />\n</button>\n", styles: [":host{display:inline-block;width:fit-content}.tn-icon-button{position:relative;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--dense{padding:3px}.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"] }]
|
|
2091
|
+
}], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], dense: [{ type: i0.Input, args: [{ isSignal: true, alias: "dense", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaExpanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaExpanded", required: false }] }], testId: [{ type: i0.Input, args: [{ isSignal: true, alias: "testId", 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 }] }], tooltipPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipPosition", required: false }] }], library: [{ type: i0.Input, args: [{ isSignal: true, alias: "library", required: false }] }], iconClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconClass", required: false }] }], onClick: [{ type: i0.Output, args: ["onClick"] }], buttonRef: [{ type: i0.ViewChild, args: ['button', { isSignal: true }] }] } });
|
|
1851
2092
|
|
|
1852
2093
|
/**
|
|
1853
2094
|
* Harness for interacting with tn-icon-button in tests.
|
|
@@ -3245,7 +3486,7 @@ class TnCardComponent {
|
|
|
3245
3486
|
return type ? `tn-card__status--${type}` : 'tn-card__status--neutral';
|
|
3246
3487
|
}
|
|
3247
3488
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3248
|
-
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 }, headerMenuTriggerTestId: { classPropertyName: "headerMenuTriggerTestId", publicName: "headerMenuTriggerTestId", 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 } }, queries: [{ propertyName: "projectedHeader", first: true, predicate: TnCardHeaderDirective, descendants: true, isSignal: true }], 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 <ng-content select=\"[tnCardHeader]\" />\n @if (!projectedHeader() && 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 @if (hasHeaderRight()) {\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 [tnTestId]=\"status.testId\">\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 [testId]=\"control.testId\"\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 [testId]=\"headerMenuTriggerTestId()\"\n [tnMenuTriggerFor]=\"cardMenu\" />\n <tn-menu\n #cardMenu\n [items]=\"menu\"\n (menuItemClick)=\"onHeaderMenuItemClick($event)\" />\n </div>\n }\n }\n </div>\n }\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 [tnTestId]=\"link.testId\"\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 [testId]=\"action.testId\"\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 [testId]=\"action.testId\"\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;font-size:14px}.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:1rem;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", "testId", "href", "routerLink", "queryParams", "fragment", "target", "rel", "ariaLabel"], outputs: ["onClick"] }, { kind: "component", type: TnIconButtonComponent, selector: "tn-icon-button", inputs: ["disabled", "ariaLabel", "testId", "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"] }, { kind: "directive", type: TnTestIdDirective, selector: "[tnTestId]", inputs: ["tnTestId"] }] });
|
|
3489
|
+
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 }, headerMenuTriggerTestId: { classPropertyName: "headerMenuTriggerTestId", publicName: "headerMenuTriggerTestId", 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 } }, queries: [{ propertyName: "projectedHeader", first: true, predicate: TnCardHeaderDirective, descendants: true, isSignal: true }], 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 <ng-content select=\"[tnCardHeader]\" />\n @if (!projectedHeader() && 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 @if (hasHeaderRight()) {\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 [tnTestId]=\"status.testId\">\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 [testId]=\"control.testId\"\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 [testId]=\"headerMenuTriggerTestId()\"\n [tnMenuTriggerFor]=\"cardMenu\" />\n <tn-menu\n #cardMenu\n [items]=\"menu\"\n (menuItemClick)=\"onHeaderMenuItemClick($event)\" />\n </div>\n }\n }\n </div>\n }\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 [tnTestId]=\"link.testId\"\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 [testId]=\"action.testId\"\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 [testId]=\"action.testId\"\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;font-size:14px}.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:1rem;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", "testId", "href", "routerLink", "queryParams", "fragment", "target", "rel", "ariaLabel"], outputs: ["onClick"] }, { kind: "component", type: TnIconButtonComponent, selector: "tn-icon-button", inputs: ["disabled", "dense", "ariaLabel", "ariaExpanded", "testId", "name", "size", "color", "tooltip", "tooltipPosition", "library", "iconClass"], 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"] }, { kind: "directive", type: TnTestIdDirective, selector: "[tnTestId]", inputs: ["tnTestId"] }] });
|
|
3249
3490
|
}
|
|
3250
3491
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnCardComponent, decorators: [{
|
|
3251
3492
|
type: Component,
|
|
@@ -7926,7 +8167,7 @@ class TnTablePagerComponent {
|
|
|
7926
8167
|
provider.setPagination(pagination);
|
|
7927
8168
|
}
|
|
7928
8169
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTablePagerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7929
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnTablePagerComponent, isStandalone: true, selector: "tn-table-pager", inputs: { currentPage: { classPropertyName: "currentPage", publicName: "currentPage", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, totalItems: { classPropertyName: "totalItems", publicName: "totalItems", isSignal: true, isRequired: false, transformFunction: null }, dataProvider: { classPropertyName: "dataProvider", publicName: "dataProvider", isSignal: true, isRequired: false, transformFunction: null }, itemsPerPageLabel: { classPropertyName: "itemsPerPageLabel", publicName: "itemsPerPageLabel", isSignal: true, isRequired: false, transformFunction: null }, ofLabel: { classPropertyName: "ofLabel", publicName: "ofLabel", isSignal: true, isRequired: false, transformFunction: null }, firstPageLabel: { classPropertyName: "firstPageLabel", publicName: "firstPageLabel", isSignal: true, isRequired: false, transformFunction: null }, previousPageLabel: { classPropertyName: "previousPageLabel", publicName: "previousPageLabel", isSignal: true, isRequired: false, transformFunction: null }, nextPageLabel: { classPropertyName: "nextPageLabel", publicName: "nextPageLabel", isSignal: true, isRequired: false, transformFunction: null }, lastPageLabel: { classPropertyName: "lastPageLabel", publicName: "lastPageLabel", isSignal: true, isRequired: false, transformFunction: null }, tablePaginationLabel: { classPropertyName: "tablePaginationLabel", publicName: "tablePaginationLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { currentPage: "currentPageChange", pageSize: "pageSizeChange", pageChange: "pageChange", pageSizeChange: "pageSizeChange" }, host: { attributes: { "role": "navigation" }, properties: { "attr.aria-label": "resolvedTablePaginationLabel()" }, classAttribute: "tn-table-pager" }, hostDirectives: [{ directive: TnTestIdDirective, inputs: ["tnTestId", "testId"] }], ngImport: i0, template: "<div class=\"tn-table-pager__page-size\">\n <span class=\"tn-table-pager__label\">{{ resolvedItemsPerPageLabel() }}:</span>\n <tn-select\n class=\"tn-table-pager__size-select\"\n [options]=\"pageSizeSelectOptions()\"\n [ariaLabel]=\"resolvedItemsPerPageLabel()\"\n [ngModel]=\"pageSize()\"\n (ngModelChange)=\"onPageSizeChange($event)\" />\n</div>\n\n<span class=\"tn-table-pager__range\">\n @if (effectiveTotalItems() === 0) {\n \u2013 {{ resolvedOfLabel() }} 0\n } @else if (lastItemOnPage() > firstItemOnPage()) {\n {{ firstItemOnPage() }} \u2013 {{ lastItemOnPage() }} {{ resolvedOfLabel() }} {{ effectiveTotalItems() }}\n } @else {\n {{ lastItemOnPage() }} {{ resolvedOfLabel() }} {{ effectiveTotalItems() }}\n }\n</span>\n\n<div class=\"tn-table-pager__buttons\">\n <tn-icon-button\n name=\"page-first\"\n library=\"mdi\"\n [ariaLabel]=\"resolvedFirstPageLabel()\"\n [disabled]=\"isFirstPageDisabled()\"\n (onClick)=\"goToPage(1)\" />\n <tn-icon-button\n name=\"chevron-left\"\n library=\"mdi\"\n [ariaLabel]=\"resolvedPreviousPageLabel()\"\n [disabled]=\"isFirstPageDisabled()\"\n (onClick)=\"previousPage()\" />\n <tn-icon-button\n name=\"chevron-right\"\n library=\"mdi\"\n [ariaLabel]=\"resolvedNextPageLabel()\"\n [disabled]=\"isLastPageDisabled()\"\n (onClick)=\"nextPage()\" />\n <tn-icon-button\n name=\"page-last\"\n library=\"mdi\"\n [ariaLabel]=\"resolvedLastPageLabel()\"\n [disabled]=\"isLastPageDisabled()\"\n (onClick)=\"goToPage(totalPages())\" />\n</div>\n", styles: [":host{display:flex;align-items:center;justify-content:flex-end;gap:16px;padding:10px;background-color:var(--tn-bg2);border:1px solid var(--tn-lines);color:var(--tn-fg2)}.tn-table-pager__page-size{display:flex;align-items:center;flex-wrap:wrap;gap:8px}.tn-table-pager__label{white-space:nowrap}.tn-table-pager__size-select{min-width:84px}.tn-table-pager__range{white-space:nowrap}.tn-table-pager__buttons{display:flex;align-items:center;gap:4px}@media(max-width:600px){:host{gap:8px}.tn-table-pager__page-size{gap:4px}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: TnIconButtonComponent, selector: "tn-icon-button", inputs: ["disabled", "ariaLabel", "testId", "name", "size", "color", "tooltip", "library"], outputs: ["onClick"] }, { kind: "component", type: TnSelectComponent, selector: "tn-select", inputs: ["options", "optionGroups", "placeholder", "ariaLabel", "noOptionsLabel", "disabled", "testId", "multiple", "compareWith"], outputs: ["selectionChange", "multiSelectionChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
8170
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnTablePagerComponent, isStandalone: true, selector: "tn-table-pager", inputs: { currentPage: { classPropertyName: "currentPage", publicName: "currentPage", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, totalItems: { classPropertyName: "totalItems", publicName: "totalItems", isSignal: true, isRequired: false, transformFunction: null }, dataProvider: { classPropertyName: "dataProvider", publicName: "dataProvider", isSignal: true, isRequired: false, transformFunction: null }, itemsPerPageLabel: { classPropertyName: "itemsPerPageLabel", publicName: "itemsPerPageLabel", isSignal: true, isRequired: false, transformFunction: null }, ofLabel: { classPropertyName: "ofLabel", publicName: "ofLabel", isSignal: true, isRequired: false, transformFunction: null }, firstPageLabel: { classPropertyName: "firstPageLabel", publicName: "firstPageLabel", isSignal: true, isRequired: false, transformFunction: null }, previousPageLabel: { classPropertyName: "previousPageLabel", publicName: "previousPageLabel", isSignal: true, isRequired: false, transformFunction: null }, nextPageLabel: { classPropertyName: "nextPageLabel", publicName: "nextPageLabel", isSignal: true, isRequired: false, transformFunction: null }, lastPageLabel: { classPropertyName: "lastPageLabel", publicName: "lastPageLabel", isSignal: true, isRequired: false, transformFunction: null }, tablePaginationLabel: { classPropertyName: "tablePaginationLabel", publicName: "tablePaginationLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { currentPage: "currentPageChange", pageSize: "pageSizeChange", pageChange: "pageChange", pageSizeChange: "pageSizeChange" }, host: { attributes: { "role": "navigation" }, properties: { "attr.aria-label": "resolvedTablePaginationLabel()" }, classAttribute: "tn-table-pager" }, hostDirectives: [{ directive: TnTestIdDirective, inputs: ["tnTestId", "testId"] }], ngImport: i0, template: "<div class=\"tn-table-pager__page-size\">\n <span class=\"tn-table-pager__label\">{{ resolvedItemsPerPageLabel() }}:</span>\n <tn-select\n class=\"tn-table-pager__size-select\"\n [options]=\"pageSizeSelectOptions()\"\n [ariaLabel]=\"resolvedItemsPerPageLabel()\"\n [ngModel]=\"pageSize()\"\n (ngModelChange)=\"onPageSizeChange($event)\" />\n</div>\n\n<span class=\"tn-table-pager__range\">\n @if (effectiveTotalItems() === 0) {\n \u2013 {{ resolvedOfLabel() }} 0\n } @else if (lastItemOnPage() > firstItemOnPage()) {\n {{ firstItemOnPage() }} \u2013 {{ lastItemOnPage() }} {{ resolvedOfLabel() }} {{ effectiveTotalItems() }}\n } @else {\n {{ lastItemOnPage() }} {{ resolvedOfLabel() }} {{ effectiveTotalItems() }}\n }\n</span>\n\n<div class=\"tn-table-pager__buttons\">\n <tn-icon-button\n name=\"page-first\"\n library=\"mdi\"\n [ariaLabel]=\"resolvedFirstPageLabel()\"\n [disabled]=\"isFirstPageDisabled()\"\n (onClick)=\"goToPage(1)\" />\n <tn-icon-button\n name=\"chevron-left\"\n library=\"mdi\"\n [ariaLabel]=\"resolvedPreviousPageLabel()\"\n [disabled]=\"isFirstPageDisabled()\"\n (onClick)=\"previousPage()\" />\n <tn-icon-button\n name=\"chevron-right\"\n library=\"mdi\"\n [ariaLabel]=\"resolvedNextPageLabel()\"\n [disabled]=\"isLastPageDisabled()\"\n (onClick)=\"nextPage()\" />\n <tn-icon-button\n name=\"page-last\"\n library=\"mdi\"\n [ariaLabel]=\"resolvedLastPageLabel()\"\n [disabled]=\"isLastPageDisabled()\"\n (onClick)=\"goToPage(totalPages())\" />\n</div>\n", styles: [":host{display:flex;align-items:center;justify-content:flex-end;gap:16px;padding:10px;background-color:var(--tn-bg2);border:1px solid var(--tn-lines);color:var(--tn-fg2)}.tn-table-pager__page-size{display:flex;align-items:center;flex-wrap:wrap;gap:8px}.tn-table-pager__label{white-space:nowrap}.tn-table-pager__size-select{min-width:84px}.tn-table-pager__range{white-space:nowrap}.tn-table-pager__buttons{display:flex;align-items:center;gap:4px}@media(max-width:600px){:host{gap:8px}.tn-table-pager__page-size{gap:4px}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: TnIconButtonComponent, selector: "tn-icon-button", inputs: ["disabled", "dense", "ariaLabel", "ariaExpanded", "testId", "name", "size", "color", "tooltip", "tooltipPosition", "library", "iconClass"], outputs: ["onClick"] }, { kind: "component", type: TnSelectComponent, selector: "tn-select", inputs: ["options", "optionGroups", "placeholder", "ariaLabel", "noOptionsLabel", "disabled", "testId", "multiple", "compareWith"], outputs: ["selectionChange", "multiSelectionChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
7930
8171
|
}
|
|
7931
8172
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTablePagerComponent, decorators: [{
|
|
7932
8173
|
type: Component,
|
|
@@ -11625,232 +11866,30 @@ class TnButtonToggleGroupHarness extends ComponentHarness {
|
|
|
11625
11866
|
}
|
|
11626
11867
|
}
|
|
11627
11868
|
|
|
11628
|
-
|
|
11629
|
-
message = input('', ...(ngDevMode ? [{ debugName: "message" }] : []));
|
|
11630
|
-
id = input('', ...(ngDevMode ? [{ debugName: "id" }] : []));
|
|
11631
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
11632
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.0", type: TnTooltipComponent, isStandalone: true, selector: "tn-tooltip", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "tn-tooltip-component" }, ngImport: i0, template: "<div\n class=\"tn-tooltip\"\n role=\"tooltip\"\n [id]=\"id()\"\n [attr.aria-hidden]=\"false\">\n {{ message() }}\n</div>\n", styles: [":host{display:block;pointer-events:none;z-index:1200}.tn-tooltip{background:#373737e6;color:#fff;padding:6px 8px;border-radius:4px;font-size:12px;font-weight:500;line-height:1.4;max-width:200px;word-wrap:break-word;white-space:pre-line;box-shadow:0 2px 8px #0003;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);animation:tn-tooltip-show .15s cubic-bezier(0,0,.2,1) forwards;transform-origin:center bottom}@keyframes tn-tooltip-show{0%{opacity:0;transform:scale(.8)}to{opacity:1;transform:scale(1)}}.tn-tooltip{position:relative}.tn-tooltip:after{content:\"\";position:absolute;width:0;height:0;border-style:solid;z-index:1}:host-context(.tn-tooltip-panel-above) .tn-tooltip:after{top:100%;left:50%;transform:translate(-50%);border-width:6px 6px 0 6px;border-color:rgba(55,55,55,.9) transparent transparent transparent}:host-context(.tn-tooltip-panel-below) .tn-tooltip:after{bottom:100%;left:50%;transform:translate(-50%);border-width:0 6px 6px 6px;border-color:transparent transparent rgba(55,55,55,.9) transparent}:host-context(.tn-tooltip-panel-left) .tn-tooltip:after,:host-context(.tn-tooltip-panel-before) .tn-tooltip:after{top:50%;left:100%;transform:translateY(-50%);border-width:6px 0 6px 6px;border-color:transparent transparent transparent rgba(55,55,55,.9)}:host-context(.tn-tooltip-panel-right) .tn-tooltip:after,:host-context(.tn-tooltip-panel-after) .tn-tooltip:after{top:50%;right:100%;transform:translateY(-50%);border-width:6px 6px 6px 0;border-color:transparent rgba(55,55,55,.9) transparent transparent}@media(prefers-contrast:high){.tn-tooltip{background:var(--tn-fg1, #000);color:var(--tn-bg1, #fff);border:1px solid var(--tn-lines, #999)}:host-context(.tn-tooltip-panel-above) .tn-tooltip:after{border-top-color:var(--tn-fg1, #000)}:host-context(.tn-tooltip-panel-below) .tn-tooltip:after{border-bottom-color:var(--tn-fg1, #000)}:host-context(.tn-tooltip-panel-left) .tn-tooltip:after,:host-context(.tn-tooltip-panel-before) .tn-tooltip:after{border-left-color:var(--tn-fg1, #000)}:host-context(.tn-tooltip-panel-right) .tn-tooltip:after,:host-context(.tn-tooltip-panel-after) .tn-tooltip:after{border-right-color:var(--tn-fg1, #000)}}:host-context(.tn-slider-thumb-label) .tn-tooltip{font-size:11px;padding:4px 6px;font-weight:600;min-width:24px;text-align:center;background:#373737f2}@media(prefers-reduced-motion:reduce){.tn-tooltip{animation:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
11633
|
-
}
|
|
11634
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTooltipComponent, decorators: [{
|
|
11635
|
-
type: Component,
|
|
11636
|
-
args: [{ selector: 'tn-tooltip', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
11637
|
-
'class': 'tn-tooltip-component'
|
|
11638
|
-
}, template: "<div\n class=\"tn-tooltip\"\n role=\"tooltip\"\n [id]=\"id()\"\n [attr.aria-hidden]=\"false\">\n {{ message() }}\n</div>\n", styles: [":host{display:block;pointer-events:none;z-index:1200}.tn-tooltip{background:#373737e6;color:#fff;padding:6px 8px;border-radius:4px;font-size:12px;font-weight:500;line-height:1.4;max-width:200px;word-wrap:break-word;white-space:pre-line;box-shadow:0 2px 8px #0003;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);animation:tn-tooltip-show .15s cubic-bezier(0,0,.2,1) forwards;transform-origin:center bottom}@keyframes tn-tooltip-show{0%{opacity:0;transform:scale(.8)}to{opacity:1;transform:scale(1)}}.tn-tooltip{position:relative}.tn-tooltip:after{content:\"\";position:absolute;width:0;height:0;border-style:solid;z-index:1}:host-context(.tn-tooltip-panel-above) .tn-tooltip:after{top:100%;left:50%;transform:translate(-50%);border-width:6px 6px 0 6px;border-color:rgba(55,55,55,.9) transparent transparent transparent}:host-context(.tn-tooltip-panel-below) .tn-tooltip:after{bottom:100%;left:50%;transform:translate(-50%);border-width:0 6px 6px 6px;border-color:transparent transparent rgba(55,55,55,.9) transparent}:host-context(.tn-tooltip-panel-left) .tn-tooltip:after,:host-context(.tn-tooltip-panel-before) .tn-tooltip:after{top:50%;left:100%;transform:translateY(-50%);border-width:6px 0 6px 6px;border-color:transparent transparent transparent rgba(55,55,55,.9)}:host-context(.tn-tooltip-panel-right) .tn-tooltip:after,:host-context(.tn-tooltip-panel-after) .tn-tooltip:after{top:50%;right:100%;transform:translateY(-50%);border-width:6px 6px 6px 0;border-color:transparent rgba(55,55,55,.9) transparent transparent}@media(prefers-contrast:high){.tn-tooltip{background:var(--tn-fg1, #000);color:var(--tn-bg1, #fff);border:1px solid var(--tn-lines, #999)}:host-context(.tn-tooltip-panel-above) .tn-tooltip:after{border-top-color:var(--tn-fg1, #000)}:host-context(.tn-tooltip-panel-below) .tn-tooltip:after{border-bottom-color:var(--tn-fg1, #000)}:host-context(.tn-tooltip-panel-left) .tn-tooltip:after,:host-context(.tn-tooltip-panel-before) .tn-tooltip:after{border-left-color:var(--tn-fg1, #000)}:host-context(.tn-tooltip-panel-right) .tn-tooltip:after,:host-context(.tn-tooltip-panel-after) .tn-tooltip:after{border-right-color:var(--tn-fg1, #000)}}:host-context(.tn-slider-thumb-label) .tn-tooltip{font-size:11px;padding:4px 6px;font-weight:600;min-width:24px;text-align:center;background:#373737f2}@media(prefers-reduced-motion:reduce){.tn-tooltip{animation:none}}\n"] }]
|
|
11639
|
-
}], propDecorators: { message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }] } });
|
|
11640
|
-
|
|
11641
|
-
/* eslint-disable @angular-eslint/no-input-rename */
|
|
11642
|
-
// Input aliasing is intentional for directive API consistency (e.g., ixTooltip, ixTooltipPosition)
|
|
11643
|
-
// This follows the standard Angular pattern used by Material and other directive-based components
|
|
11644
|
-
class TnTooltipDirective {
|
|
11645
|
-
message = input('', { ...(ngDevMode ? { debugName: "message" } : {}), alias: 'tnTooltip' });
|
|
11646
|
-
position = input('above', { ...(ngDevMode ? { debugName: "position" } : {}), alias: 'tnTooltipPosition' });
|
|
11647
|
-
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : {}), alias: 'tnTooltipDisabled' });
|
|
11648
|
-
showDelay = input(0, { ...(ngDevMode ? { debugName: "showDelay" } : {}), alias: 'tnTooltipShowDelay' });
|
|
11649
|
-
hideDelay = input(0, { ...(ngDevMode ? { debugName: "hideDelay" } : {}), alias: 'tnTooltipHideDelay' });
|
|
11650
|
-
tooltipClass = input('', { ...(ngDevMode ? { debugName: "tooltipClass" } : {}), alias: 'tnTooltipClass' });
|
|
11651
|
-
_overlayRef = null;
|
|
11652
|
-
_tooltipInstance = null;
|
|
11653
|
-
_showTimeout = null;
|
|
11654
|
-
_hideTimeout = null;
|
|
11655
|
-
_isTooltipVisible = false;
|
|
11656
|
-
_positionSub = null;
|
|
11657
|
-
_ariaDescribedBy = null;
|
|
11658
|
-
_overlay = inject(Overlay);
|
|
11659
|
-
_elementRef = inject((ElementRef));
|
|
11660
|
-
_viewContainerRef = inject(ViewContainerRef);
|
|
11661
|
-
_overlayPositionBuilder = inject(OverlayPositionBuilder);
|
|
11662
|
-
ngOnInit() {
|
|
11663
|
-
// Generate unique ID for aria-describedby
|
|
11664
|
-
this._ariaDescribedBy = `tn-tooltip-${Math.random().toString(36).substr(2, 9)}`;
|
|
11665
|
-
}
|
|
11666
|
-
ngOnDestroy() {
|
|
11667
|
-
this._clearTimeouts();
|
|
11668
|
-
this.hide(0);
|
|
11669
|
-
this._positionSub?.unsubscribe();
|
|
11670
|
-
if (this._overlayRef) {
|
|
11671
|
-
this._overlayRef.dispose();
|
|
11672
|
-
this._overlayRef = null;
|
|
11673
|
-
}
|
|
11674
|
-
}
|
|
11675
|
-
_onMouseEnter() {
|
|
11676
|
-
if (!this.disabled() && this.message()) {
|
|
11677
|
-
this.show(this.showDelay());
|
|
11678
|
-
}
|
|
11679
|
-
}
|
|
11680
|
-
_onMouseLeave() {
|
|
11681
|
-
this.hide(this.hideDelay());
|
|
11682
|
-
}
|
|
11683
|
-
_onFocus() {
|
|
11684
|
-
if (!this.disabled() && this.message()) {
|
|
11685
|
-
this.show(this.showDelay());
|
|
11686
|
-
}
|
|
11687
|
-
}
|
|
11688
|
-
_onBlur() {
|
|
11689
|
-
this.hide(this.hideDelay());
|
|
11690
|
-
}
|
|
11691
|
-
_onKeydown(event) {
|
|
11692
|
-
if (event.key === 'Escape' && this._isTooltipVisible) {
|
|
11693
|
-
this.hide(0);
|
|
11694
|
-
}
|
|
11695
|
-
}
|
|
11696
|
-
/** Shows the tooltip */
|
|
11697
|
-
show(delay = 0) {
|
|
11698
|
-
if (this.disabled() || !this.message() || this._isTooltipVisible) {
|
|
11699
|
-
return;
|
|
11700
|
-
}
|
|
11701
|
-
this._clearTimeouts();
|
|
11702
|
-
this._showTimeout = setTimeout(() => {
|
|
11703
|
-
if (!this._overlayRef) {
|
|
11704
|
-
this._createOverlay();
|
|
11705
|
-
}
|
|
11706
|
-
this._attachTooltip();
|
|
11707
|
-
}, delay);
|
|
11708
|
-
}
|
|
11709
|
-
/** Hides the tooltip */
|
|
11710
|
-
hide(delay = 0) {
|
|
11711
|
-
this._clearTimeouts();
|
|
11712
|
-
this._hideTimeout = setTimeout(() => {
|
|
11713
|
-
if (this._tooltipInstance) {
|
|
11714
|
-
this._tooltipInstance.destroy();
|
|
11715
|
-
this._tooltipInstance = null;
|
|
11716
|
-
this._isTooltipVisible = false;
|
|
11717
|
-
}
|
|
11718
|
-
}, delay);
|
|
11719
|
-
}
|
|
11720
|
-
/** Toggle the tooltip visibility */
|
|
11721
|
-
toggle() {
|
|
11722
|
-
this._isTooltipVisible ? this.hide() : this.show();
|
|
11723
|
-
}
|
|
11724
|
-
_createOverlay() {
|
|
11725
|
-
const positions = this._getPositions();
|
|
11726
|
-
const positionStrategy = this._overlayPositionBuilder
|
|
11727
|
-
.flexibleConnectedTo(this._elementRef)
|
|
11728
|
-
.withPositions(positions)
|
|
11729
|
-
.withFlexibleDimensions(false)
|
|
11730
|
-
.withViewportMargin(8)
|
|
11731
|
-
.withScrollableContainers([]);
|
|
11732
|
-
this._overlayRef = this._overlay.create({
|
|
11733
|
-
positionStrategy,
|
|
11734
|
-
scrollStrategy: this._overlay.scrollStrategies.reposition({ scrollThrottle: 20 }),
|
|
11735
|
-
panelClass: ['tn-tooltip-panel', `tn-tooltip-panel-${this.position()}`, this.tooltipClass()].filter(Boolean),
|
|
11736
|
-
});
|
|
11737
|
-
this._positionSub = positionStrategy.positionChanges
|
|
11738
|
-
.subscribe((change) => {
|
|
11739
|
-
const panel = this._overlayRef?.overlayElement?.parentElement;
|
|
11740
|
-
if (!panel) {
|
|
11741
|
-
return;
|
|
11742
|
-
}
|
|
11743
|
-
const actual = this._resolvePosition(change.connectionPair);
|
|
11744
|
-
const allPositionClasses = [
|
|
11745
|
-
'tn-tooltip-panel-above', 'tn-tooltip-panel-below',
|
|
11746
|
-
'tn-tooltip-panel-left', 'tn-tooltip-panel-right',
|
|
11747
|
-
'tn-tooltip-panel-before', 'tn-tooltip-panel-after',
|
|
11748
|
-
];
|
|
11749
|
-
panel.classList.remove(...allPositionClasses);
|
|
11750
|
-
panel.classList.add(`tn-tooltip-panel-${actual}`);
|
|
11751
|
-
});
|
|
11752
|
-
}
|
|
11753
|
-
_resolvePosition(pair) {
|
|
11754
|
-
if (pair.overlayY === 'bottom') {
|
|
11755
|
-
return 'above';
|
|
11756
|
-
}
|
|
11757
|
-
if (pair.overlayY === 'top') {
|
|
11758
|
-
return 'below';
|
|
11759
|
-
}
|
|
11760
|
-
if (pair.overlayX === 'end') {
|
|
11761
|
-
return 'left';
|
|
11762
|
-
}
|
|
11763
|
-
return 'right';
|
|
11764
|
-
}
|
|
11765
|
-
_attachTooltip() {
|
|
11766
|
-
if (!this._overlayRef) {
|
|
11767
|
-
return;
|
|
11768
|
-
}
|
|
11769
|
-
if (!this._tooltipInstance) {
|
|
11770
|
-
const portal = new ComponentPortal(TnTooltipComponent, this._viewContainerRef);
|
|
11771
|
-
this._tooltipInstance = this._overlayRef.attach(portal);
|
|
11772
|
-
this._tooltipInstance.setInput('message', this.message());
|
|
11773
|
-
this._tooltipInstance.setInput('id', this._ariaDescribedBy);
|
|
11774
|
-
this._isTooltipVisible = true;
|
|
11775
|
-
}
|
|
11776
|
-
}
|
|
11777
|
-
_getPositions() {
|
|
11778
|
-
switch (this.position()) {
|
|
11779
|
-
case 'above':
|
|
11780
|
-
return [
|
|
11781
|
-
{ originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom', offsetY: -12 },
|
|
11782
|
-
{ originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top', offsetY: 12 },
|
|
11783
|
-
];
|
|
11784
|
-
case 'below':
|
|
11785
|
-
return [
|
|
11786
|
-
{ originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top', offsetY: 12 },
|
|
11787
|
-
{ originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom', offsetY: -12 },
|
|
11788
|
-
];
|
|
11789
|
-
case 'left':
|
|
11790
|
-
case 'before':
|
|
11791
|
-
return [
|
|
11792
|
-
{ originX: 'start', originY: 'center', overlayX: 'end', overlayY: 'center', offsetX: -12 },
|
|
11793
|
-
{ originX: 'end', originY: 'center', overlayX: 'start', overlayY: 'center', offsetX: 12 },
|
|
11794
|
-
];
|
|
11795
|
-
case 'right':
|
|
11796
|
-
case 'after':
|
|
11797
|
-
return [
|
|
11798
|
-
{ originX: 'end', originY: 'center', overlayX: 'start', overlayY: 'center', offsetX: 12 },
|
|
11799
|
-
{ originX: 'start', originY: 'center', overlayX: 'end', overlayY: 'center', offsetX: -12 },
|
|
11800
|
-
];
|
|
11801
|
-
default:
|
|
11802
|
-
return [
|
|
11803
|
-
{ originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top', offsetY: 12 },
|
|
11804
|
-
];
|
|
11805
|
-
}
|
|
11806
|
-
}
|
|
11807
|
-
_clearTimeouts() {
|
|
11808
|
-
if (this._showTimeout) {
|
|
11809
|
-
clearTimeout(this._showTimeout);
|
|
11810
|
-
this._showTimeout = null;
|
|
11811
|
-
}
|
|
11812
|
-
if (this._hideTimeout) {
|
|
11813
|
-
clearTimeout(this._hideTimeout);
|
|
11814
|
-
this._hideTimeout = null;
|
|
11815
|
-
}
|
|
11816
|
-
}
|
|
11817
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTooltipDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
11818
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.0", type: TnTooltipDirective, isStandalone: true, selector: "[tnTooltip]", inputs: { message: { classPropertyName: "message", publicName: "tnTooltip", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "tnTooltipPosition", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "tnTooltipDisabled", isSignal: true, isRequired: false, transformFunction: null }, showDelay: { classPropertyName: "showDelay", publicName: "tnTooltipShowDelay", isSignal: true, isRequired: false, transformFunction: null }, hideDelay: { classPropertyName: "hideDelay", publicName: "tnTooltipHideDelay", isSignal: true, isRequired: false, transformFunction: null }, tooltipClass: { classPropertyName: "tooltipClass", publicName: "tnTooltipClass", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mouseenter": "_onMouseEnter()", "mouseleave": "_onMouseLeave()", "focus": "_onFocus()", "blur": "_onBlur()", "keydown": "_onKeydown($event)" }, properties: { "attr.aria-describedby": "_ariaDescribedBy" } }, ngImport: i0 });
|
|
11819
|
-
}
|
|
11820
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTooltipDirective, decorators: [{
|
|
11821
|
-
type: Directive,
|
|
11822
|
-
args: [{
|
|
11823
|
-
selector: '[tnTooltip]',
|
|
11824
|
-
standalone: true,
|
|
11825
|
-
host: {
|
|
11826
|
-
'[attr.aria-describedby]': '_ariaDescribedBy',
|
|
11827
|
-
}
|
|
11828
|
-
}]
|
|
11829
|
-
}], propDecorators: { message: [{ type: i0.Input, args: [{ isSignal: true, alias: "tnTooltip", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "tnTooltipPosition", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "tnTooltipDisabled", required: false }] }], showDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "tnTooltipShowDelay", required: false }] }], hideDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "tnTooltipHideDelay", required: false }] }], tooltipClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "tnTooltipClass", required: false }] }], _onMouseEnter: [{
|
|
11830
|
-
type: HostListener,
|
|
11831
|
-
args: ['mouseenter']
|
|
11832
|
-
}], _onMouseLeave: [{
|
|
11833
|
-
type: HostListener,
|
|
11834
|
-
args: ['mouseleave']
|
|
11835
|
-
}], _onFocus: [{
|
|
11836
|
-
type: HostListener,
|
|
11837
|
-
args: ['focus']
|
|
11838
|
-
}], _onBlur: [{
|
|
11839
|
-
type: HostListener,
|
|
11840
|
-
args: ['blur']
|
|
11841
|
-
}], _onKeydown: [{
|
|
11842
|
-
type: HostListener,
|
|
11843
|
-
args: ['keydown', ['$event']]
|
|
11844
|
-
}] } });
|
|
11845
|
-
|
|
11869
|
+
let nextUniqueId = 0;
|
|
11846
11870
|
class TnDialogShellComponent {
|
|
11847
11871
|
title = input('', ...(ngDevMode ? [{ debugName: "title" }] : []));
|
|
11848
11872
|
showFullscreenButton = input(false, ...(ngDevMode ? [{ debugName: "showFullscreenButton" }] : []));
|
|
11873
|
+
/** Stable id for the title heading, referenced by the dialog's aria-labelledby. */
|
|
11874
|
+
titleId = `tn-dialog-title-${nextUniqueId++}`;
|
|
11849
11875
|
isFullscreen = signal(false, ...(ngDevMode ? [{ debugName: "isFullscreen" }] : []));
|
|
11850
11876
|
originalStyles = {};
|
|
11851
11877
|
ref = inject(DialogRef);
|
|
11852
11878
|
document = inject(DOCUMENT);
|
|
11879
|
+
host = inject(ElementRef);
|
|
11853
11880
|
data = inject(DIALOG_DATA, { optional: true });
|
|
11881
|
+
constructor() {
|
|
11882
|
+
// Give the CDK dialog container an accessible name by pointing its
|
|
11883
|
+
// aria-labelledby at the visible title heading. Tracked in an effect so a
|
|
11884
|
+
// title set after init is still reflected.
|
|
11885
|
+
effect(() => {
|
|
11886
|
+
if (!this.title()) {
|
|
11887
|
+
return;
|
|
11888
|
+
}
|
|
11889
|
+
const container = this.host.nativeElement.closest('cdk-dialog-container');
|
|
11890
|
+
container?.setAttribute('aria-labelledby', this.titleId);
|
|
11891
|
+
});
|
|
11892
|
+
}
|
|
11854
11893
|
ngOnInit() {
|
|
11855
11894
|
// Check if dialog was opened in fullscreen mode by looking for existing fullscreen class
|
|
11856
11895
|
setTimeout(() => {
|
|
@@ -11908,14 +11947,14 @@ class TnDialogShellComponent {
|
|
|
11908
11947
|
}
|
|
11909
11948
|
}
|
|
11910
11949
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnDialogShellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
11911
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnDialogShellComponent, isStandalone: true, selector: "tn-dialog-shell", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, showFullscreenButton: { classPropertyName: "showFullscreenButton", publicName: "showFullscreenButton", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "tn-dialog-shell" }, ngImport: i0, template: "<header class=\"tn-dialog__header\">\n <h2 class=\"tn-dialog__title\">{{ title() }}</h2>\n @if (showFullscreenButton()) {\n <button\n type=\"button\"\n class=\"tn-dialog__fullscreen\"\n
|
|
11950
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnDialogShellComponent, isStandalone: true, selector: "tn-dialog-shell", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, showFullscreenButton: { classPropertyName: "showFullscreenButton", publicName: "showFullscreenButton", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "tn-dialog-shell" }, ngImport: i0, template: "<header class=\"tn-dialog__header\">\n <h2 class=\"tn-dialog__title\" [id]=\"titleId\">{{ title() }}</h2>\n @if (showFullscreenButton()) {\n <button\n type=\"button\"\n class=\"tn-dialog__fullscreen\"\n [attr.aria-label]=\"isFullscreen() ? 'Exit fullscreen' : 'Enter fullscreen'\"\n (click)=\"toggleFullscreen()\">\n <span class=\"tn-dialog__fullscreen-icon\" aria-hidden=\"true\">{{ isFullscreen() ? '\u2913' : '\u2922' }}</span>\n </button>\n }\n <button type=\"button\" class=\"tn-dialog__close\" aria-label=\"Close dialog\" (click)=\"close()\">\n <span class=\"tn-dialog__close-icon\" aria-hidden=\"true\">\u2715</span>\n </button>\n</header>\n\n<section class=\"tn-dialog__content\" cdkDialogContent>\n <ng-content />\n</section>\n\n<footer class=\"tn-dialog__actions\" cdkDialogActions>\n <ng-content select=\"[tnDialogAction]\" />\n</footer>\n" });
|
|
11912
11951
|
}
|
|
11913
11952
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnDialogShellComponent, decorators: [{
|
|
11914
11953
|
type: Component,
|
|
11915
11954
|
args: [{ selector: 'tn-dialog-shell', standalone: true, imports: [], host: {
|
|
11916
11955
|
'class': 'tn-dialog-shell'
|
|
11917
|
-
}, template: "<header class=\"tn-dialog__header\">\n <h2 class=\"tn-dialog__title\">{{ title() }}</h2>\n @if (showFullscreenButton()) {\n <button\n type=\"button\"\n class=\"tn-dialog__fullscreen\"\n
|
|
11918
|
-
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], showFullscreenButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFullscreenButton", required: false }] }] } });
|
|
11956
|
+
}, template: "<header class=\"tn-dialog__header\">\n <h2 class=\"tn-dialog__title\" [id]=\"titleId\">{{ title() }}</h2>\n @if (showFullscreenButton()) {\n <button\n type=\"button\"\n class=\"tn-dialog__fullscreen\"\n [attr.aria-label]=\"isFullscreen() ? 'Exit fullscreen' : 'Enter fullscreen'\"\n (click)=\"toggleFullscreen()\">\n <span class=\"tn-dialog__fullscreen-icon\" aria-hidden=\"true\">{{ isFullscreen() ? '\u2913' : '\u2922' }}</span>\n </button>\n }\n <button type=\"button\" class=\"tn-dialog__close\" aria-label=\"Close dialog\" (click)=\"close()\">\n <span class=\"tn-dialog__close-icon\" aria-hidden=\"true\">\u2715</span>\n </button>\n</header>\n\n<section class=\"tn-dialog__content\" cdkDialogContent>\n <ng-content />\n</section>\n\n<footer class=\"tn-dialog__actions\" cdkDialogActions>\n <ng-content select=\"[tnDialogAction]\" />\n</footer>\n" }]
|
|
11957
|
+
}], ctorParameters: () => [], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], showFullscreenButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFullscreenButton", required: false }] }] } });
|
|
11919
11958
|
|
|
11920
11959
|
class TnConfirmDialogComponent {
|
|
11921
11960
|
ref = inject((DialogRef));
|
|
@@ -12096,6 +12135,26 @@ class TnDialogHarness extends ComponentHarness {
|
|
|
12096
12135
|
const closeBtn = await this._closeButton();
|
|
12097
12136
|
await closeBtn.click();
|
|
12098
12137
|
}
|
|
12138
|
+
/**
|
|
12139
|
+
* Gets the `tabindex` attribute of the close button, or null if unset.
|
|
12140
|
+
* A null/non-negative value means the button is reachable via the Tab key.
|
|
12141
|
+
*
|
|
12142
|
+
* @returns Promise resolving to the tabindex attribute value.
|
|
12143
|
+
*/
|
|
12144
|
+
async getCloseButtonTabIndex() {
|
|
12145
|
+
const closeBtn = await this._closeButton();
|
|
12146
|
+
return closeBtn.getAttribute('tabindex');
|
|
12147
|
+
}
|
|
12148
|
+
/**
|
|
12149
|
+
* Gets the `tabindex` attribute of the fullscreen button, or null if unset
|
|
12150
|
+
* or if the dialog has no fullscreen button.
|
|
12151
|
+
*
|
|
12152
|
+
* @returns Promise resolving to the tabindex attribute value.
|
|
12153
|
+
*/
|
|
12154
|
+
async getFullscreenButtonTabIndex() {
|
|
12155
|
+
const btn = await this._fullscreenButton();
|
|
12156
|
+
return btn ? btn.getAttribute('tabindex') : null;
|
|
12157
|
+
}
|
|
12099
12158
|
/**
|
|
12100
12159
|
* Clicks an action button in the dialog footer by its label.
|
|
12101
12160
|
* Only matches buttons inside the `tnDialogAction` footer area, not buttons in content.
|
|
@@ -12346,7 +12405,7 @@ class TnSidePanelComponent {
|
|
|
12346
12405
|
});
|
|
12347
12406
|
}
|
|
12348
12407
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnSidePanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
12349
|
-
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 }, testId: { classPropertyName: "testId", publicName: "testId", isSignal: true, isRequired: false, transformFunction: null }, closeButtonTestId: { classPropertyName: "closeButtonTestId", publicName: "closeButtonTestId", 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 [tnTestId]=\"testId()\"\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 [testId]=\"closeButtonTestId()\"\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", "testId", "name", "size", "color", "tooltip", "library"], outputs: ["onClick"] }, { kind: "directive", type: TnTestIdDirective, selector: "[tnTestId]", inputs: ["tnTestId"] }] });
|
|
12408
|
+
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 }, testId: { classPropertyName: "testId", publicName: "testId", isSignal: true, isRequired: false, transformFunction: null }, closeButtonTestId: { classPropertyName: "closeButtonTestId", publicName: "closeButtonTestId", 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 [tnTestId]=\"testId()\"\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 [testId]=\"closeButtonTestId()\"\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", "dense", "ariaLabel", "ariaExpanded", "testId", "name", "size", "color", "tooltip", "tooltipPosition", "library", "iconClass"], outputs: ["onClick"] }, { kind: "directive", type: TnTestIdDirective, selector: "[tnTestId]", inputs: ["tnTestId"] }] });
|
|
12350
12409
|
}
|
|
12351
12410
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnSidePanelComponent, decorators: [{
|
|
12352
12411
|
type: Component,
|
|
@@ -13509,16 +13568,19 @@ var TnToastPosition;
|
|
|
13509
13568
|
TnToastPosition["Bottom"] = "bottom";
|
|
13510
13569
|
})(TnToastPosition || (TnToastPosition = {}));
|
|
13511
13570
|
|
|
13512
|
-
//
|
|
13571
|
+
// Material icons render via the `material-icons` CSS font (see icon.component.ts),
|
|
13572
|
+
// so they don't need sprite scanning — the literal `mat-` prefix matches what
|
|
13573
|
+
// the runtime icon resolver would produce from a Material library name.
|
|
13513
13574
|
const TOAST_ICONS = {
|
|
13514
|
-
[TnToastType.Info]:
|
|
13515
|
-
[TnToastType.Success]:
|
|
13516
|
-
[TnToastType.Warning]:
|
|
13517
|
-
[TnToastType.Error]:
|
|
13575
|
+
[TnToastType.Info]: 'mat-info',
|
|
13576
|
+
[TnToastType.Success]: 'mat-check_circle',
|
|
13577
|
+
[TnToastType.Warning]: 'mat-warning',
|
|
13578
|
+
[TnToastType.Error]: 'mat-error',
|
|
13518
13579
|
};
|
|
13519
13580
|
class TnToastComponent {
|
|
13520
13581
|
message = signal('', ...(ngDevMode ? [{ debugName: "message" }] : []));
|
|
13521
13582
|
action = signal(null, ...(ngDevMode ? [{ debugName: "action" }] : []));
|
|
13583
|
+
actionTestId = signal(undefined, ...(ngDevMode ? [{ debugName: "actionTestId" }] : []));
|
|
13522
13584
|
type = signal(TnToastType.Info, ...(ngDevMode ? [{ debugName: "type" }] : []));
|
|
13523
13585
|
position = signal(TnToastPosition.Top, ...(ngDevMode ? [{ debugName: "position" }] : []));
|
|
13524
13586
|
visible = signal(false, ...(ngDevMode ? [{ debugName: "visible" }] : []));
|
|
@@ -13526,14 +13588,14 @@ class TnToastComponent {
|
|
|
13526
13588
|
onAction = () => { };
|
|
13527
13589
|
onDismiss = () => { };
|
|
13528
13590
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnToastComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
13529
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnToastComponent, isStandalone: true, selector: "tn-toast", host: { properties: { "class.tn-toast--top": "position() === \"top\"", "class.tn-toast--bottom": "position() === \"bottom\"" } }, ngImport: i0, template: "<div\n class=\"tn-toast\"\n role=\"alert\"\n aria-live=\"polite\"\n [class.tn-toast--visible]=\"visible()\"\n [class.tn-toast--info]=\"type() === 'info'\"\n [class.tn-toast--success]=\"type() === 'success'\"\n [class.tn-toast--warning]=\"type() === 'warning'\"\n [class.tn-toast--error]=\"type() === 'error'\">\n <tn-icon class=\"tn-toast__icon\" size=\"sm\" [name]=\"icon()\" />\n <span class=\"tn-toast__message\">{{ message() }}</span>\n @if (action()) {\n <button\n class=\"tn-toast__action\"\n type=\"button\"\n (click)=\"onAction()\">\n {{ action() }}\n </button>\n }\n</div>\n", styles: ["tn-toast{position:fixed;left:50%;transform:translate(-50%);z-index:10000;pointer-events:none}tn-toast.tn-toast--bottom{bottom:1.5rem}tn-toast.tn-toast--top{top:1.5rem}.tn-toast{display:flex;align-items:center;gap:.75rem;padding:.75rem 1.25rem;border-radius:.5rem;font-family:var(--tn-font-family-body, \"Inter\"),sans-serif;font-size:1rem;line-height:1.4;pointer-events:auto;background-color:var(--tn-bg2, #333);color:var(--tn-fg1, #fff);border-left:3px solid transparent;box-shadow:0 8px 24px #0000004d;opacity:0;transform:translateY(1rem);transition:opacity .2s ease-out,transform .2s ease-out;max-width:560px}.tn-toast.tn-toast--visible{opacity:1;transform:translateY(0)}.tn-toast.tn-toast--info{border-left-color:var(--tn-info, #3b82f6)}.tn-toast.tn-toast--success{border-left-color:var(--tn-success, #10b981)}.tn-toast.tn-toast--warning{border-left-color:var(--tn-warning, #f59e0b)}.tn-toast.tn-toast--error{border-left-color:var(--tn-error, #ef4444)}.tn-toast__icon{flex-shrink:0}.tn-toast--info .tn-toast__icon{color:var(--tn-info, #3b82f6)}.tn-toast--success .tn-toast__icon{color:var(--tn-success, #10b981)}.tn-toast--warning .tn-toast__icon{color:var(--tn-warning, #f59e0b)}.tn-toast--error .tn-toast__icon{color:var(--tn-error, #ef4444)}.tn-toast__message{flex:1}.tn-toast__action{background:none;border:none;color:var(--tn-primary, #3b82f6);font-family:inherit;font-size:1rem;font-weight:600;cursor:pointer;padding:.25rem .5rem;border-radius:.25rem;white-space:nowrap;transition:background-color .15s ease}.tn-toast__action:hover{background-color:#ffffff1a}@media(prefers-reduced-motion:reduce){.tn-toast{transition:none}}\n"], dependencies: [{ kind: "component", type: TnIconComponent, selector: "tn-icon", inputs: ["name", "size", "color", "tooltip", "ariaLabel", "library", "fullSize", "customSize"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
13591
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnToastComponent, isStandalone: true, selector: "tn-toast", host: { properties: { "class.tn-toast--top": "position() === \"top\"", "class.tn-toast--bottom": "position() === \"bottom\"" } }, ngImport: i0, template: "<div\n class=\"tn-toast\"\n role=\"alert\"\n aria-live=\"polite\"\n [class.tn-toast--visible]=\"visible()\"\n [class.tn-toast--info]=\"type() === 'info'\"\n [class.tn-toast--success]=\"type() === 'success'\"\n [class.tn-toast--warning]=\"type() === 'warning'\"\n [class.tn-toast--error]=\"type() === 'error'\">\n <tn-icon class=\"tn-toast__icon\" size=\"sm\" [name]=\"icon()\" />\n <span class=\"tn-toast__message\">{{ message() }}</span>\n @if (action()) {\n <button\n class=\"tn-toast__action\"\n type=\"button\"\n [tnTestId]=\"actionTestId()\"\n (click)=\"onAction()\">\n {{ action() }}\n </button>\n }\n</div>\n", styles: ["tn-toast{position:fixed;left:50%;transform:translate(-50%);z-index:10000;pointer-events:none}tn-toast.tn-toast--bottom{bottom:1.5rem}tn-toast.tn-toast--top{top:1.5rem}.tn-toast{display:flex;align-items:center;gap:.75rem;padding:.75rem 1.25rem;border-radius:.5rem;font-family:var(--tn-font-family-body, \"Inter\"),sans-serif;font-size:1rem;line-height:1.4;pointer-events:auto;background-color:var(--tn-bg2, #333);color:var(--tn-fg1, #fff);border-left:3px solid transparent;box-shadow:0 8px 24px #0000004d;opacity:0;transform:translateY(1rem);transition:opacity .2s ease-out,transform .2s ease-out;max-width:560px}.tn-toast.tn-toast--visible{opacity:1;transform:translateY(0)}.tn-toast.tn-toast--info{border-left-color:var(--tn-info, #3b82f6)}.tn-toast.tn-toast--success{border-left-color:var(--tn-success, #10b981)}.tn-toast.tn-toast--warning{border-left-color:var(--tn-warning, #f59e0b)}.tn-toast.tn-toast--error{border-left-color:var(--tn-error, #ef4444)}.tn-toast__icon{flex-shrink:0}.tn-toast--info .tn-toast__icon{color:var(--tn-info, #3b82f6)}.tn-toast--success .tn-toast__icon{color:var(--tn-success, #10b981)}.tn-toast--warning .tn-toast__icon{color:var(--tn-warning, #f59e0b)}.tn-toast--error .tn-toast__icon{color:var(--tn-error, #ef4444)}.tn-toast__message{flex:1}.tn-toast__action{background:none;border:none;color:var(--tn-primary, #3b82f6);font-family:inherit;font-size:1rem;font-weight:600;cursor:pointer;padding:.25rem .5rem;border-radius:.25rem;white-space:nowrap;transition:background-color .15s ease}.tn-toast__action:hover{background-color:#ffffff1a}@media(prefers-reduced-motion:reduce){.tn-toast{transition:none}}\n"], dependencies: [{ kind: "component", type: TnIconComponent, selector: "tn-icon", inputs: ["name", "size", "color", "tooltip", "ariaLabel", "library", "fullSize", "customSize"] }, { kind: "directive", type: TnTestIdDirective, selector: "[tnTestId]", inputs: ["tnTestId"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
13530
13592
|
}
|
|
13531
13593
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnToastComponent, decorators: [{
|
|
13532
13594
|
type: Component,
|
|
13533
|
-
args: [{ selector: 'tn-toast', standalone: true, imports: [TnIconComponent], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
13595
|
+
args: [{ selector: 'tn-toast', standalone: true, imports: [TnIconComponent, TnTestIdDirective], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
13534
13596
|
'[class.tn-toast--top]': 'position() === "top"',
|
|
13535
13597
|
'[class.tn-toast--bottom]': 'position() === "bottom"',
|
|
13536
|
-
}, template: "<div\n class=\"tn-toast\"\n role=\"alert\"\n aria-live=\"polite\"\n [class.tn-toast--visible]=\"visible()\"\n [class.tn-toast--info]=\"type() === 'info'\"\n [class.tn-toast--success]=\"type() === 'success'\"\n [class.tn-toast--warning]=\"type() === 'warning'\"\n [class.tn-toast--error]=\"type() === 'error'\">\n <tn-icon class=\"tn-toast__icon\" size=\"sm\" [name]=\"icon()\" />\n <span class=\"tn-toast__message\">{{ message() }}</span>\n @if (action()) {\n <button\n class=\"tn-toast__action\"\n type=\"button\"\n (click)=\"onAction()\">\n {{ action() }}\n </button>\n }\n</div>\n", styles: ["tn-toast{position:fixed;left:50%;transform:translate(-50%);z-index:10000;pointer-events:none}tn-toast.tn-toast--bottom{bottom:1.5rem}tn-toast.tn-toast--top{top:1.5rem}.tn-toast{display:flex;align-items:center;gap:.75rem;padding:.75rem 1.25rem;border-radius:.5rem;font-family:var(--tn-font-family-body, \"Inter\"),sans-serif;font-size:1rem;line-height:1.4;pointer-events:auto;background-color:var(--tn-bg2, #333);color:var(--tn-fg1, #fff);border-left:3px solid transparent;box-shadow:0 8px 24px #0000004d;opacity:0;transform:translateY(1rem);transition:opacity .2s ease-out,transform .2s ease-out;max-width:560px}.tn-toast.tn-toast--visible{opacity:1;transform:translateY(0)}.tn-toast.tn-toast--info{border-left-color:var(--tn-info, #3b82f6)}.tn-toast.tn-toast--success{border-left-color:var(--tn-success, #10b981)}.tn-toast.tn-toast--warning{border-left-color:var(--tn-warning, #f59e0b)}.tn-toast.tn-toast--error{border-left-color:var(--tn-error, #ef4444)}.tn-toast__icon{flex-shrink:0}.tn-toast--info .tn-toast__icon{color:var(--tn-info, #3b82f6)}.tn-toast--success .tn-toast__icon{color:var(--tn-success, #10b981)}.tn-toast--warning .tn-toast__icon{color:var(--tn-warning, #f59e0b)}.tn-toast--error .tn-toast__icon{color:var(--tn-error, #ef4444)}.tn-toast__message{flex:1}.tn-toast__action{background:none;border:none;color:var(--tn-primary, #3b82f6);font-family:inherit;font-size:1rem;font-weight:600;cursor:pointer;padding:.25rem .5rem;border-radius:.25rem;white-space:nowrap;transition:background-color .15s ease}.tn-toast__action:hover{background-color:#ffffff1a}@media(prefers-reduced-motion:reduce){.tn-toast{transition:none}}\n"] }]
|
|
13598
|
+
}, template: "<div\n class=\"tn-toast\"\n role=\"alert\"\n aria-live=\"polite\"\n [class.tn-toast--visible]=\"visible()\"\n [class.tn-toast--info]=\"type() === 'info'\"\n [class.tn-toast--success]=\"type() === 'success'\"\n [class.tn-toast--warning]=\"type() === 'warning'\"\n [class.tn-toast--error]=\"type() === 'error'\">\n <tn-icon class=\"tn-toast__icon\" size=\"sm\" [name]=\"icon()\" />\n <span class=\"tn-toast__message\">{{ message() }}</span>\n @if (action()) {\n <button\n class=\"tn-toast__action\"\n type=\"button\"\n [tnTestId]=\"actionTestId()\"\n (click)=\"onAction()\">\n {{ action() }}\n </button>\n }\n</div>\n", styles: ["tn-toast{position:fixed;left:50%;transform:translate(-50%);z-index:10000;pointer-events:none}tn-toast.tn-toast--bottom{bottom:1.5rem}tn-toast.tn-toast--top{top:1.5rem}.tn-toast{display:flex;align-items:center;gap:.75rem;padding:.75rem 1.25rem;border-radius:.5rem;font-family:var(--tn-font-family-body, \"Inter\"),sans-serif;font-size:1rem;line-height:1.4;pointer-events:auto;background-color:var(--tn-bg2, #333);color:var(--tn-fg1, #fff);border-left:3px solid transparent;box-shadow:0 8px 24px #0000004d;opacity:0;transform:translateY(1rem);transition:opacity .2s ease-out,transform .2s ease-out;max-width:560px}.tn-toast.tn-toast--visible{opacity:1;transform:translateY(0)}.tn-toast.tn-toast--info{border-left-color:var(--tn-info, #3b82f6)}.tn-toast.tn-toast--success{border-left-color:var(--tn-success, #10b981)}.tn-toast.tn-toast--warning{border-left-color:var(--tn-warning, #f59e0b)}.tn-toast.tn-toast--error{border-left-color:var(--tn-error, #ef4444)}.tn-toast__icon{flex-shrink:0}.tn-toast--info .tn-toast__icon{color:var(--tn-info, #3b82f6)}.tn-toast--success .tn-toast__icon{color:var(--tn-success, #10b981)}.tn-toast--warning .tn-toast__icon{color:var(--tn-warning, #f59e0b)}.tn-toast--error .tn-toast__icon{color:var(--tn-error, #ef4444)}.tn-toast__message{flex:1}.tn-toast__action{background:none;border:none;color:var(--tn-primary, #3b82f6);font-family:inherit;font-size:1rem;font-weight:600;cursor:pointer;padding:.25rem .5rem;border-radius:.25rem;white-space:nowrap;transition:background-color .15s ease}.tn-toast__action:hover{background-color:#ffffff1a}@media(prefers-reduced-motion:reduce){.tn-toast{transition:none}}\n"] }]
|
|
13537
13599
|
}] });
|
|
13538
13600
|
|
|
13539
13601
|
class TnToastRef {
|