@tociva/tailng-ui 0.12.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,22 +1,503 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports$1) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports$1, p)) __createBinding(exports$1, m, p);
1
+ import * as i0 from '@angular/core';
2
+ import { input, booleanAttribute, numberAttribute, computed, Component, Directive } from '@angular/core';
3
+
4
+ class TngBadge {
5
+ /* =====================
6
+ * Inputs
7
+ * ===================== */
8
+ /** Badge content (number or short text). If null/undefined -> hidden (unless dot=true). */
9
+ value = input(null, ...(ngDevMode ? [{ debugName: "value" }] : []));
10
+ /** Dot mode (ignores value display) */
11
+ dot = input(false, { ...(ngDevMode ? { debugName: "dot" } : {}), transform: booleanAttribute });
12
+ /** Hide badge forcefully */
13
+ hide = input(false, { ...(ngDevMode ? { debugName: "hide" } : {}), transform: booleanAttribute });
14
+ /** Show when value is 0 (only for numeric values) */
15
+ showZero = input(false, { ...(ngDevMode ? { debugName: "showZero" } : {}), transform: booleanAttribute });
16
+ /** Max number shown before overflow (e.g., 99+) */
17
+ max = input(99, { ...(ngDevMode ? { debugName: "max" } : {}), transform: numberAttribute });
18
+ /** Position relative to host */
19
+ position = input('top-right', ...(ngDevMode ? [{ debugName: "position" }] : []));
20
+ /** Overlap host (Material-ish). When false, badge sits outside edge a bit. */
21
+ overlap = input(true, { ...(ngDevMode ? { debugName: "overlap" } : {}), transform: booleanAttribute });
22
+ /** Visual variant */
23
+ variant = input('danger', ...(ngDevMode ? [{ debugName: "variant" }] : []));
24
+ /** Size */
25
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
26
+ /** Accessible label override (recommended when badge is meaningful) */
27
+ ariaLabel = input('', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
28
+ /* =====================
29
+ * Class hooks
30
+ * ===================== */
31
+ /** Outer wrapper (layout of projected content + badge) */
32
+ rootKlass = input('inline-flex', ...(ngDevMode ? [{ debugName: "rootKlass" }] : []));
33
+ /** The element that becomes positioning anchor */
34
+ hostKlass = input('relative inline-flex', ...(ngDevMode ? [{ debugName: "hostKlass" }] : []));
35
+ /** Badge element */
36
+ badgeKlass = input('', ...(ngDevMode ? [{ debugName: "badgeKlass" }] : []));
37
+ /* =====================
38
+ * Derived values
39
+ * ===================== */
40
+ isNumericValue = computed(() => {
41
+ const v = this.value();
42
+ return typeof v === 'number' && Number.isFinite(v);
43
+ }, ...(ngDevMode ? [{ debugName: "isNumericValue" }] : []));
44
+ displayValue = computed(() => {
45
+ const v = this.value();
46
+ if (v === null || v === undefined)
47
+ return '';
48
+ if (typeof v === 'string')
49
+ return v.trim();
50
+ // number
51
+ const n = v;
52
+ const m = this.max();
53
+ if (!Number.isFinite(n))
54
+ return '';
55
+ if (n > m)
56
+ return `${m}+`;
57
+ return String(n);
58
+ }, ...(ngDevMode ? [{ debugName: "displayValue" }] : []));
59
+ shouldShow = computed(() => {
60
+ if (this.hide())
61
+ return false;
62
+ if (this.dot())
63
+ return true;
64
+ const v = this.value();
65
+ if (v === null || v === undefined)
66
+ return false;
67
+ if (typeof v === 'string')
68
+ return v.trim().length > 0;
69
+ // number
70
+ if (!Number.isFinite(v))
71
+ return false;
72
+ if (v === 0)
73
+ return this.showZero();
74
+ return true;
75
+ }, ...(ngDevMode ? [{ debugName: "shouldShow" }] : []));
76
+ /** If user didn't provide ariaLabel, generate a basic one */
77
+ computedAriaLabel = computed(() => {
78
+ const custom = this.ariaLabel().trim();
79
+ if (custom)
80
+ return custom;
81
+ if (!this.shouldShow())
82
+ return '';
83
+ if (this.dot())
84
+ return 'New notification';
85
+ const v = this.displayValue();
86
+ if (!v)
87
+ return '';
88
+ // Simple default. Consumers can override with ariaLabel input.
89
+ return `Badge: ${v}`;
90
+ }, ...(ngDevMode ? [{ debugName: "computedAriaLabel" }] : []));
91
+ /* =====================
92
+ * Classes
93
+ * ===================== */
94
+ variantClasses = computed(() => {
95
+ switch (this.variant()) {
96
+ case 'primary':
97
+ return 'bg-primary text-on-primary';
98
+ case 'neutral':
99
+ return 'bg-alternate-background text-fg border border-border';
100
+ case 'success':
101
+ return 'bg-success text-on-primary';
102
+ case 'warning':
103
+ return 'bg-warning text-on-primary';
104
+ case 'danger':
105
+ return 'bg-danger text-on-primary';
106
+ case 'info':
107
+ return 'bg-info text-on-primary';
108
+ default:
109
+ return 'bg-danger text-on-primary';
110
+ }
111
+ }, ...(ngDevMode ? [{ debugName: "variantClasses" }] : []));
112
+ sizeClasses = computed(() => {
113
+ // Material-ish: small dot, compact numbers.
114
+ if (this.dot()) {
115
+ return this.size() === 'sm'
116
+ ? 'h-2 w-2'
117
+ : 'h-2.5 w-2.5';
118
+ }
119
+ return this.size() === 'sm'
120
+ ? 'min-w-[1.1rem] h-[1.1rem] px-1 text-[0.65rem] leading-[1.1rem]'
121
+ : 'min-w-[1.25rem] h-[1.25rem] px-1.5 text-[0.7rem] leading-[1.25rem]';
122
+ }, ...(ngDevMode ? [{ debugName: "sizeClasses" }] : []));
123
+ positionClasses = computed(() => {
124
+ const overlap = this.overlap();
125
+ // when overlap=true, sit closer to corner (on top of host)
126
+ // when overlap=false, sit slightly outside
127
+ const inset = overlap ? '-translate-y-1/2' : '-translate-y-3/4';
128
+ const insetBottom = overlap ? 'translate-y-1/2' : 'translate-y-3/4';
129
+ const insetX = overlap ? 'translate-x-1/2' : 'translate-x-3/4';
130
+ const insetXLeft = overlap ? '-translate-x-1/2' : '-translate-x-3/4';
131
+ switch (this.position()) {
132
+ case 'top-right':
133
+ return `top-0 right-0 ${inset} ${insetX}`;
134
+ case 'top-left':
135
+ return `top-0 left-0 ${inset} ${insetXLeft}`;
136
+ case 'bottom-right':
137
+ return `bottom-0 right-0 ${insetBottom} ${insetX}`;
138
+ case 'bottom-left':
139
+ return `bottom-0 left-0 ${insetBottom} ${insetXLeft}`;
140
+ default:
141
+ return `top-0 right-0 ${inset} ${insetX}`;
142
+ }
143
+ }, ...(ngDevMode ? [{ debugName: "positionClasses" }] : []));
144
+ badgeClasses = computed(() => {
145
+ const base = 'absolute z-10 inline-flex items-center justify-center ' +
146
+ 'rounded-full font-semibold select-none ' +
147
+ 'ring-2 ring-background ' + // Material-ish separation from host
148
+ 'pointer-events-none '; // badge shouldn't block clicks
149
+ const dotShape = this.dot() ? 'p-0' : '';
150
+ const cls = base +
151
+ this.variantClasses() +
152
+ ' ' +
153
+ this.sizeClasses() +
154
+ ' ' +
155
+ this.positionClasses() +
156
+ ' ' +
157
+ dotShape +
158
+ ' ' +
159
+ this.badgeKlass();
160
+ return cls.trim();
161
+ }, ...(ngDevMode ? [{ debugName: "badgeClasses" }] : []));
162
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TngBadge, deps: [], target: i0.ɵɵFactoryTarget.Component });
163
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: TngBadge, isStandalone: true, selector: "tng-badge", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, dot: { classPropertyName: "dot", publicName: "dot", isSignal: true, isRequired: false, transformFunction: null }, hide: { classPropertyName: "hide", publicName: "hide", isSignal: true, isRequired: false, transformFunction: null }, showZero: { classPropertyName: "showZero", publicName: "showZero", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, overlap: { classPropertyName: "overlap", publicName: "overlap", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, rootKlass: { classPropertyName: "rootKlass", publicName: "rootKlass", isSignal: true, isRequired: false, transformFunction: null }, hostKlass: { classPropertyName: "hostKlass", publicName: "hostKlass", isSignal: true, isRequired: false, transformFunction: null }, badgeKlass: { classPropertyName: "badgeKlass", publicName: "badgeKlass", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div [class]=\"rootKlass()\">\n <span [class]=\"hostKlass()\">\n <ng-content />\n\n @if (shouldShow()) {\n <span\n [class]=\"badgeClasses()\"\n [attr.aria-label]=\"computedAriaLabel() || null\"\n aria-hidden=\"true\"\n >\n @if (!dot()) {\n {{ displayValue() }}\n }\n </span>\n }\n </span>\n</div>\n" });
164
+ }
165
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TngBadge, decorators: [{
166
+ type: Component,
167
+ args: [{ selector: 'tng-badge', standalone: true, template: "<div [class]=\"rootKlass()\">\n <span [class]=\"hostKlass()\">\n <ng-content />\n\n @if (shouldShow()) {\n <span\n [class]=\"badgeClasses()\"\n [attr.aria-label]=\"computedAriaLabel() || null\"\n aria-hidden=\"true\"\n >\n @if (!dot()) {\n {{ displayValue() }}\n }\n </span>\n }\n </span>\n</div>\n" }]
168
+ }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], dot: [{ type: i0.Input, args: [{ isSignal: true, alias: "dot", required: false }] }], hide: [{ type: i0.Input, args: [{ isSignal: true, alias: "hide", required: false }] }], showZero: [{ type: i0.Input, args: [{ isSignal: true, alias: "showZero", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], overlap: [{ type: i0.Input, args: [{ isSignal: true, alias: "overlap", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], rootKlass: [{ type: i0.Input, args: [{ isSignal: true, alias: "rootKlass", required: false }] }], hostKlass: [{ type: i0.Input, args: [{ isSignal: true, alias: "hostKlass", required: false }] }], badgeKlass: [{ type: i0.Input, args: [{ isSignal: true, alias: "badgeKlass", required: false }] }] } });
169
+
170
+ const base = 'inline-flex items-center justify-center gap-2 font-medium select-none ' +
171
+ 'transition-colors ' +
172
+ 'focus-visible:outline-none ' +
173
+ 'focus-visible:ring-2 focus-visible:ring-primary ' +
174
+ 'focus-visible:ring-offset-2 focus-visible:ring-offset-background ' +
175
+ 'disabled:opacity-50 disabled:pointer-events-none';
176
+ const sizes = {
177
+ sm: 'h-8 px-3 text-sm rounded',
178
+ md: 'h-10 px-4 text-sm rounded-md',
179
+ lg: 'h-12 px-5 text-base rounded-lg',
180
+ };
181
+ const variants = {
182
+ solid: 'bg-primary text-on-primary hover:bg-primary-hover',
183
+ outline: 'border border-border text-fg bg-bg ' +
184
+ 'hover:bg-alternate-background',
185
+ ghost: 'text-fg hover:bg-alternate-background',
15
186
  };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./lib"), exports);
187
+ const buttonClasses = (variant, size, opts) => [
188
+ base,
189
+ sizes[size],
190
+ variants[variant],
191
+ opts?.block ? 'w-full' : '',
192
+ ]
193
+ .filter(Boolean)
194
+ .join(' ');
195
+
196
+ class TngButton {
197
+ variant = input('solid', ...(ngDevMode ? [{ debugName: "variant" }] : []));
198
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
199
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
200
+ loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
201
+ block = input(false, ...(ngDevMode ? [{ debugName: "block" }] : []));
202
+ type = input('button', ...(ngDevMode ? [{ debugName: "type" }] : []));
203
+ ariaLabel = input('', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
204
+ pressed = input(null, ...(ngDevMode ? [{ debugName: "pressed" }] : []));
205
+ klass = input('', ...(ngDevMode ? [{ debugName: "klass" }] : []));
206
+ isDisabled = computed(() => this.disabled() || this.loading(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
207
+ classes = computed(() => `${buttonClasses(this.variant(), this.size(), {
208
+ block: this.block(),
209
+ })} ${this.klass()}`.trim(), ...(ngDevMode ? [{ debugName: "classes" }] : []));
210
+ spinnerKlass = input('h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent', ...(ngDevMode ? [{ debugName: "spinnerKlass" }] : []));
211
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TngButton, deps: [], target: i0.ɵɵFactoryTarget.Component });
212
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: TngButton, isStandalone: true, selector: "tng-button", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, block: { classPropertyName: "block", publicName: "block", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, pressed: { classPropertyName: "pressed", publicName: "pressed", isSignal: true, isRequired: false, transformFunction: null }, klass: { classPropertyName: "klass", publicName: "klass", isSignal: true, isRequired: false, transformFunction: null }, spinnerKlass: { classPropertyName: "spinnerKlass", publicName: "spinnerKlass", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<button\n [attr.type]=\"type()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-disabled]=\"isDisabled() ? true : null\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-pressed]=\"pressed() !== null ? pressed() : null\"\n [attr.aria-busy]=\"loading() ? true : null\"\n [class]=\"classes()\"\n>\n @if (loading()) {\n <span [class]=\"spinnerKlass()\"></span>\n } @else {\n <ng-content />\n }\n</button>\n" });
213
+ }
214
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TngButton, decorators: [{
215
+ type: Component,
216
+ args: [{ selector: 'tng-button', standalone: true, template: "<button\n [attr.type]=\"type()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-disabled]=\"isDisabled() ? true : null\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-pressed]=\"pressed() !== null ? pressed() : null\"\n [attr.aria-busy]=\"loading() ? true : null\"\n [class]=\"classes()\"\n>\n @if (loading()) {\n <span [class]=\"spinnerKlass()\"></span>\n } @else {\n <ng-content />\n }\n</button>\n" }]
217
+ }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], block: [{ type: i0.Input, args: [{ isSignal: true, alias: "block", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], pressed: [{ type: i0.Input, args: [{ isSignal: true, alias: "pressed", required: false }] }], klass: [{ type: i0.Input, args: [{ isSignal: true, alias: "klass", required: false }] }], spinnerKlass: [{ type: i0.Input, args: [{ isSignal: true, alias: "spinnerKlass", required: false }] }] } });
218
+
219
+ class TngProgressBar {
220
+ /* =====================
221
+ * Inputs
222
+ * ===================== */
223
+ /** determinate | indeterminate */
224
+ mode = input('determinate', ...(ngDevMode ? [{ debugName: "mode" }] : []));
225
+ /** Progress value (0–max) */
226
+ value = input(0, { ...(ngDevMode ? { debugName: "value" } : {}), transform: numberAttribute });
227
+ /** Max value (default 100) */
228
+ max = input(100, { ...(ngDevMode ? { debugName: "max" } : {}), transform: numberAttribute });
229
+ /** Disable animation (useful for reduced motion) */
230
+ disableAnimation = input(false, { ...(ngDevMode ? { debugName: "disableAnimation" } : {}), transform: booleanAttribute });
231
+ /* =====================
232
+ * Klass hooks (theming)
233
+ * ===================== */
234
+ /** Root wrapper */
235
+ rootKlass = input('w-full', ...(ngDevMode ? [{ debugName: "rootKlass" }] : []));
236
+ /** Track (background) */
237
+ trackKlass = input('bg-border', ...(ngDevMode ? [{ debugName: "trackKlass" }] : []));
238
+ /** Bar (foreground) */
239
+ barKlass = input('bg-primary', ...(ngDevMode ? [{ debugName: "barKlass" }] : []));
240
+ /** Height utility (Tailwind) */
241
+ heightKlass = input('h-1', ...(ngDevMode ? [{ debugName: "heightKlass" }] : []));
242
+ /* =====================
243
+ * Computed
244
+ * ===================== */
245
+ percentage = computed(() => {
246
+ const v = this.value();
247
+ const m = this.max();
248
+ if (m <= 0)
249
+ return 0;
250
+ return Math.min(100, Math.max(0, (v / m) * 100));
251
+ }, ...(ngDevMode ? [{ debugName: "percentage" }] : []));
252
+ barStyle = computed(() => {
253
+ if (this.mode() === 'indeterminate')
254
+ return {};
255
+ return { width: `${this.percentage()}%` };
256
+ }, ...(ngDevMode ? [{ debugName: "barStyle" }] : []));
257
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TngProgressBar, deps: [], target: i0.ɵɵFactoryTarget.Component });
258
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: TngProgressBar, isStandalone: true, selector: "tng-progress-bar", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, disableAnimation: { classPropertyName: "disableAnimation", publicName: "disableAnimation", isSignal: true, isRequired: false, transformFunction: null }, rootKlass: { classPropertyName: "rootKlass", publicName: "rootKlass", isSignal: true, isRequired: false, transformFunction: null }, trackKlass: { classPropertyName: "trackKlass", publicName: "trackKlass", isSignal: true, isRequired: false, transformFunction: null }, barKlass: { classPropertyName: "barKlass", publicName: "barKlass", isSignal: true, isRequired: false, transformFunction: null }, heightKlass: { classPropertyName: "heightKlass", publicName: "heightKlass", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div [class]=\"rootKlass()\">\n <div\n role=\"progressbar\"\n class=\"relative w-full overflow-hidden rounded-full\"\n [class]=\"trackKlass() + ' ' + heightKlass()\"\n [attr.aria-valuemin]=\"mode() === 'determinate' ? 0 : null\"\n [attr.aria-valuemax]=\"mode() === 'determinate' ? max() : null\"\n [attr.aria-valuenow]=\"mode() === 'determinate' ? value() : null\"\n >\n <!-- Determinate -->\n @if (mode() === 'determinate') {\n <div\n class=\"h-full rounded-full transition-[width] duration-300 ease-out\"\n [class]=\"barKlass()\"\n [style.width.%]=\"percentage()\"\n ></div>\n }\n\n <!-- Indeterminate -->\n @if (mode() === 'indeterminate') {\n <div\n class=\"absolute inset-y-0 left-0 w-1/3 rounded-full\"\n [class]=\"\n barKlass() +\n ' ' +\n (disableAnimation() ? '' : 'tng-progress-indeterminate')\n \"\n ></div>\n }\n </div>\n</div>\n", styles: ["@keyframes tng-progress-indeterminate{0%{transform:translate(-100%)}to{transform:translate(300%)}}.tng-progress-indeterminate{animation:tng-progress-indeterminate 1.2s infinite linear}\n"] });
259
+ }
260
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TngProgressBar, decorators: [{
261
+ type: Component,
262
+ args: [{ selector: 'tng-progress-bar', standalone: true, template: "<div [class]=\"rootKlass()\">\n <div\n role=\"progressbar\"\n class=\"relative w-full overflow-hidden rounded-full\"\n [class]=\"trackKlass() + ' ' + heightKlass()\"\n [attr.aria-valuemin]=\"mode() === 'determinate' ? 0 : null\"\n [attr.aria-valuemax]=\"mode() === 'determinate' ? max() : null\"\n [attr.aria-valuenow]=\"mode() === 'determinate' ? value() : null\"\n >\n <!-- Determinate -->\n @if (mode() === 'determinate') {\n <div\n class=\"h-full rounded-full transition-[width] duration-300 ease-out\"\n [class]=\"barKlass()\"\n [style.width.%]=\"percentage()\"\n ></div>\n }\n\n <!-- Indeterminate -->\n @if (mode() === 'indeterminate') {\n <div\n class=\"absolute inset-y-0 left-0 w-1/3 rounded-full\"\n [class]=\"\n barKlass() +\n ' ' +\n (disableAnimation() ? '' : 'tng-progress-indeterminate')\n \"\n ></div>\n }\n </div>\n</div>\n", styles: ["@keyframes tng-progress-indeterminate{0%{transform:translate(-100%)}to{transform:translate(300%)}}.tng-progress-indeterminate{animation:tng-progress-indeterminate 1.2s infinite linear}\n"] }]
263
+ }], propDecorators: { mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], disableAnimation: [{ type: i0.Input, args: [{ isSignal: true, alias: "disableAnimation", required: false }] }], rootKlass: [{ type: i0.Input, args: [{ isSignal: true, alias: "rootKlass", required: false }] }], trackKlass: [{ type: i0.Input, args: [{ isSignal: true, alias: "trackKlass", required: false }] }], barKlass: [{ type: i0.Input, args: [{ isSignal: true, alias: "barKlass", required: false }] }], heightKlass: [{ type: i0.Input, args: [{ isSignal: true, alias: "heightKlass", required: false }] }] } });
264
+
265
+ class TngProgressSpinner {
266
+ /* =====================
267
+ * Inputs
268
+ * ===================== */
269
+ /** indeterminate | determinate */
270
+ mode = input('indeterminate', ...(ngDevMode ? [{ debugName: "mode" }] : []));
271
+ /** Progress value (0–max) for determinate mode */
272
+ value = input(0, { ...(ngDevMode ? { debugName: "value" } : {}), transform: numberAttribute });
273
+ /** Max value (default 100) */
274
+ max = input(100, { ...(ngDevMode ? { debugName: "max" } : {}), transform: numberAttribute });
275
+ /* =====================
276
+ * Klass hooks (theming)
277
+ * ===================== */
278
+ /** Root wrapper */
279
+ rootKlass = input('inline-flex', ...(ngDevMode ? [{ debugName: "rootKlass" }] : []));
280
+ /** SVG size (Tailwind-friendly: w-6 h-6, w-8 h-8, etc.) */
281
+ sizeKlass = input('w-6 h-6', ...(ngDevMode ? [{ debugName: "sizeKlass" }] : []));
282
+ /** Track (background circle) */
283
+ trackKlass = input('text-border', ...(ngDevMode ? [{ debugName: "trackKlass" }] : []));
284
+ /** Indicator (foreground stroke) */
285
+ indicatorKlass = input('text-primary', ...(ngDevMode ? [{ debugName: "indicatorKlass" }] : []));
286
+ /** Stroke width */
287
+ strokeWidth = input(4, { ...(ngDevMode ? { debugName: "strokeWidth" } : {}), transform: numberAttribute });
288
+ /* =====================
289
+ * Computed
290
+ * ===================== */
291
+ radius = computed(() => 50 - this.strokeWidth() / 2, ...(ngDevMode ? [{ debugName: "radius" }] : []));
292
+ circumference = computed(() => 2 * Math.PI * this.radius(), ...(ngDevMode ? [{ debugName: "circumference" }] : []));
293
+ progressOffset = computed(() => {
294
+ if (this.mode() === 'indeterminate')
295
+ return 0;
296
+ const v = this.value();
297
+ const m = this.max();
298
+ if (m <= 0)
299
+ return this.circumference();
300
+ const pct = Math.min(100, Math.max(0, (v / m) * 100));
301
+ return this.circumference() * (1 - pct / 100);
302
+ }, ...(ngDevMode ? [{ debugName: "progressOffset" }] : []));
303
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TngProgressSpinner, deps: [], target: i0.ɵɵFactoryTarget.Component });
304
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.6", type: TngProgressSpinner, isStandalone: true, selector: "tng-progress-spinner", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, rootKlass: { classPropertyName: "rootKlass", publicName: "rootKlass", isSignal: true, isRequired: false, transformFunction: null }, sizeKlass: { classPropertyName: "sizeKlass", publicName: "sizeKlass", isSignal: true, isRequired: false, transformFunction: null }, trackKlass: { classPropertyName: "trackKlass", publicName: "trackKlass", isSignal: true, isRequired: false, transformFunction: null }, indicatorKlass: { classPropertyName: "indicatorKlass", publicName: "indicatorKlass", isSignal: true, isRequired: false, transformFunction: null }, strokeWidth: { classPropertyName: "strokeWidth", publicName: "strokeWidth", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\n [class]=\"rootKlass()\"\n role=\"progressbar\"\n [attr.aria-valuemin]=\"mode() === 'determinate' ? 0 : null\"\n [attr.aria-valuemax]=\"mode() === 'determinate' ? max() : null\"\n [attr.aria-valuenow]=\"mode() === 'determinate' ? value() : null\"\n>\n <svg\n viewBox=\"0 0 100 100\"\n class=\"block\"\n [class]=\"sizeKlass()\"\n >\n <!-- Track -->\n <circle\n cx=\"50\"\n cy=\"50\"\n [attr.r]=\"radius()\"\n fill=\"none\"\n stroke=\"currentColor\"\n [attr.stroke-width]=\"strokeWidth()\"\n class=\"opacity-30\"\n [class]=\"trackKlass()\"\n ></circle>\n\n <!-- Indicator -->\n <circle\n cx=\"50\"\n cy=\"50\"\n [attr.r]=\"radius()\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-linecap=\"round\"\n [attr.stroke-width]=\"strokeWidth()\"\n [attr.stroke-dasharray]=\"circumference()\"\n [attr.stroke-dashoffset]=\"progressOffset()\"\n [class]=\"\n indicatorKlass() +\n ' ' +\n (mode() === 'indeterminate' ? 'tng-spinner-indeterminate' : '')\n \"\n ></circle>\n </svg>\n</div>\n", styles: ["@keyframes tng-spinner-rotate{to{transform:rotate(360deg)}}@keyframes tng-spinner-dash{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:100,200;stroke-dashoffset:-15}to{stroke-dasharray:100,200;stroke-dashoffset:-125}}.tng-spinner-indeterminate{transform-origin:center;animation:tng-spinner-rotate 1.4s linear infinite,tng-spinner-dash 1.4s ease-in-out infinite}\n"] });
305
+ }
306
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TngProgressSpinner, decorators: [{
307
+ type: Component,
308
+ args: [{ selector: 'tng-progress-spinner', standalone: true, template: "<div\n [class]=\"rootKlass()\"\n role=\"progressbar\"\n [attr.aria-valuemin]=\"mode() === 'determinate' ? 0 : null\"\n [attr.aria-valuemax]=\"mode() === 'determinate' ? max() : null\"\n [attr.aria-valuenow]=\"mode() === 'determinate' ? value() : null\"\n>\n <svg\n viewBox=\"0 0 100 100\"\n class=\"block\"\n [class]=\"sizeKlass()\"\n >\n <!-- Track -->\n <circle\n cx=\"50\"\n cy=\"50\"\n [attr.r]=\"radius()\"\n fill=\"none\"\n stroke=\"currentColor\"\n [attr.stroke-width]=\"strokeWidth()\"\n class=\"opacity-30\"\n [class]=\"trackKlass()\"\n ></circle>\n\n <!-- Indicator -->\n <circle\n cx=\"50\"\n cy=\"50\"\n [attr.r]=\"radius()\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-linecap=\"round\"\n [attr.stroke-width]=\"strokeWidth()\"\n [attr.stroke-dasharray]=\"circumference()\"\n [attr.stroke-dashoffset]=\"progressOffset()\"\n [class]=\"\n indicatorKlass() +\n ' ' +\n (mode() === 'indeterminate' ? 'tng-spinner-indeterminate' : '')\n \"\n ></circle>\n </svg>\n</div>\n", styles: ["@keyframes tng-spinner-rotate{to{transform:rotate(360deg)}}@keyframes tng-spinner-dash{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:100,200;stroke-dashoffset:-15}to{stroke-dasharray:100,200;stroke-dashoffset:-125}}.tng-spinner-indeterminate{transform-origin:center;animation:tng-spinner-rotate 1.4s linear infinite,tng-spinner-dash 1.4s ease-in-out infinite}\n"] }]
309
+ }], propDecorators: { mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], rootKlass: [{ type: i0.Input, args: [{ isSignal: true, alias: "rootKlass", required: false }] }], sizeKlass: [{ type: i0.Input, args: [{ isSignal: true, alias: "sizeKlass", required: false }] }], trackKlass: [{ type: i0.Input, args: [{ isSignal: true, alias: "trackKlass", required: false }] }], indicatorKlass: [{ type: i0.Input, args: [{ isSignal: true, alias: "indicatorKlass", required: false }] }], strokeWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "strokeWidth", required: false }] }] } });
310
+
311
+ class TngRipple {
312
+ el;
313
+ r;
314
+ zone;
315
+ rippleDisabled = input(false, { ...(ngDevMode ? { debugName: "rippleDisabled" } : {}), transform: booleanAttribute });
316
+ rippleCentered = input(false, { ...(ngDevMode ? { debugName: "rippleCentered" } : {}), transform: booleanAttribute });
317
+ rippleColor = input('currentColor', ...(ngDevMode ? [{ debugName: "rippleColor" }] : []));
318
+ rippleDuration = input(550, { ...(ngDevMode ? { debugName: "rippleDuration" } : {}), transform: numberAttribute });
319
+ rippleOpacity = input(0.18, { ...(ngDevMode ? { debugName: "rippleOpacity" } : {}), transform: numberAttribute });
320
+ unlistenPointerDown = null;
321
+ constructor(el, r, zone) {
322
+ this.el = el;
323
+ this.r = r;
324
+ this.zone = zone;
325
+ }
326
+ ngAfterViewInit() {
327
+ // Ensure styles after the element is in DOM and computed styles are stable
328
+ this.ensureHostStyles();
329
+ this.zone.runOutsideAngular(() => {
330
+ this.unlistenPointerDown = this.r.listen(this.el.nativeElement, 'pointerdown', (ev) => this.onPointerDown(ev));
331
+ });
332
+ }
333
+ ngOnDestroy() {
334
+ this.unlistenPointerDown?.();
335
+ this.unlistenPointerDown = null;
336
+ }
337
+ ensureHostStyles() {
338
+ const host = this.el.nativeElement;
339
+ const pos = getComputedStyle(host).position;
340
+ // Force containing block for absolute children
341
+ // If it's static/empty/unknown -> set to relative
342
+ if (!pos || pos === 'static') {
343
+ this.r.setStyle(host, 'position', 'relative');
344
+ }
345
+ // Clip ripple to rounded corners
346
+ const ov = getComputedStyle(host).overflow;
347
+ if (!ov || ov === 'visible') {
348
+ this.r.setStyle(host, 'overflow', 'hidden');
349
+ }
350
+ // Prevent weird stacking issues (optional but helpful)
351
+ this.r.setStyle(host, 'isolation', 'isolate');
352
+ // Mobile tap highlight
353
+ this.r.setStyle(host, '-webkit-tap-highlight-color', 'transparent');
354
+ }
355
+ onPointerDown(ev) {
356
+ if (this.rippleDisabled())
357
+ return;
358
+ if (ev.button !== 0)
359
+ return;
360
+ if (ev.defaultPrevented)
361
+ return;
362
+ const host = this.el.nativeElement;
363
+ if (host.disabled)
364
+ return;
365
+ const rect = host.getBoundingClientRect();
366
+ const w = rect.width;
367
+ const h = rect.height;
368
+ if (w <= 0 || h <= 0)
369
+ return;
370
+ const diameter = Math.ceil(Math.sqrt(w * w + h * h));
371
+ const x = this.rippleCentered() ? rect.left + w / 2 : ev.clientX;
372
+ const y = this.rippleCentered() ? rect.top + h / 2 : ev.clientY;
373
+ const left = Math.round(x - rect.left - diameter / 2);
374
+ const top = Math.round(y - rect.top - diameter / 2);
375
+ const ripple = this.r.createElement('span');
376
+ this.r.setStyle(ripple, 'position', 'absolute');
377
+ this.r.setStyle(ripple, 'left', `${left}px`);
378
+ this.r.setStyle(ripple, 'top', `${top}px`);
379
+ this.r.setStyle(ripple, 'width', `${diameter}px`);
380
+ this.r.setStyle(ripple, 'height', `${diameter}px`);
381
+ this.r.setStyle(ripple, 'border-radius', '9999px');
382
+ this.r.setStyle(ripple, 'pointer-events', 'none');
383
+ this.r.setStyle(ripple, 'background', this.rippleColor());
384
+ this.r.setStyle(ripple, 'opacity', String(this.rippleOpacity()));
385
+ this.r.setStyle(ripple, 'transform', 'scale(0)');
386
+ this.r.setStyle(ripple, 'will-change', 'transform, opacity');
387
+ const duration = this.rippleDuration();
388
+ this.r.setStyle(ripple, 'transition', `transform ${duration}ms ease-out, opacity ${duration}ms ease-out`);
389
+ this.r.appendChild(host, ripple);
390
+ requestAnimationFrame(() => {
391
+ this.r.setStyle(ripple, 'transform', 'scale(1)');
392
+ this.r.setStyle(ripple, 'opacity', '0');
393
+ });
394
+ window.setTimeout(() => {
395
+ try {
396
+ this.r.removeChild(host, ripple);
397
+ }
398
+ catch { }
399
+ }, duration + 40);
400
+ }
401
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TngRipple, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
402
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: TngRipple, isStandalone: true, selector: "[tngRipple]", inputs: { rippleDisabled: { classPropertyName: "rippleDisabled", publicName: "rippleDisabled", isSignal: true, isRequired: false, transformFunction: null }, rippleCentered: { classPropertyName: "rippleCentered", publicName: "rippleCentered", isSignal: true, isRequired: false, transformFunction: null }, rippleColor: { classPropertyName: "rippleColor", publicName: "rippleColor", isSignal: true, isRequired: false, transformFunction: null }, rippleDuration: { classPropertyName: "rippleDuration", publicName: "rippleDuration", isSignal: true, isRequired: false, transformFunction: null }, rippleOpacity: { classPropertyName: "rippleOpacity", publicName: "rippleOpacity", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
403
+ }
404
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TngRipple, decorators: [{
405
+ type: Directive,
406
+ args: [{
407
+ selector: '[tngRipple]',
408
+ standalone: true,
409
+ }]
410
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }], propDecorators: { rippleDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "rippleDisabled", required: false }] }], rippleCentered: [{ type: i0.Input, args: [{ isSignal: true, alias: "rippleCentered", required: false }] }], rippleColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "rippleColor", required: false }] }], rippleDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "rippleDuration", required: false }] }], rippleOpacity: [{ type: i0.Input, args: [{ isSignal: true, alias: "rippleOpacity", required: false }] }] } });
411
+
412
+ class TngSkeleton {
413
+ /* =====================
414
+ * Inputs
415
+ * ===================== */
416
+ variant = input('text', ...(ngDevMode ? [{ debugName: "variant" }] : []));
417
+ /**
418
+ * Prefer widthKlass/heightKlass for Tailwind-first usage.
419
+ * width/height are optional escape hatches for exact CSS values.
420
+ */
421
+ widthKlass = input('w-full', ...(ngDevMode ? [{ debugName: "widthKlass" }] : []));
422
+ heightKlass = input('h-4', ...(ngDevMode ? [{ debugName: "heightKlass" }] : []));
423
+ width = input('', ...(ngDevMode ? [{ debugName: "width" }] : [])); // e.g. '240px', '60%', '12rem'
424
+ height = input('', ...(ngDevMode ? [{ debugName: "height" }] : [])); // e.g. '16px'
425
+ /** shimmer=true => shimmer animation, else pulse */
426
+ shimmer = input(false, { ...(ngDevMode ? { debugName: "shimmer" } : {}), transform: booleanAttribute });
427
+ /** class hook */
428
+ klass = input('', ...(ngDevMode ? [{ debugName: "klass" }] : []));
429
+ /* =====================
430
+ * Computed
431
+ * ===================== */
432
+ shapeClasses = computed(() => {
433
+ switch (this.variant()) {
434
+ case 'circular':
435
+ return 'rounded-full';
436
+ case 'rectangular':
437
+ return 'rounded-md';
438
+ case 'text':
439
+ default:
440
+ return 'rounded'; // looks like a text line
441
+ }
442
+ }, ...(ngDevMode ? [{ debugName: "shapeClasses" }] : []));
443
+ animationClasses = computed(() => {
444
+ // prefer shimmer if enabled, else pulse
445
+ return this.shimmer() ? 'tng-skeleton-shimmer' : 'animate-pulse';
446
+ }, ...(ngDevMode ? [{ debugName: "animationClasses" }] : []));
447
+ /**
448
+ * Tailng theming: no hardcoded colors.
449
+ * Default uses border-ish token; consumers override via klass.
450
+ */
451
+ classes = computed(() => {
452
+ const base = 'relative overflow-hidden bg-slate-200/70 dark:bg-slate-700/40';
453
+ return [
454
+ base,
455
+ this.animationClasses(),
456
+ this.shapeClasses(),
457
+ this.widthKlass(),
458
+ this.heightKlass(),
459
+ this.klass(),
460
+ ]
461
+ .map((s) => s.trim())
462
+ .filter(Boolean)
463
+ .join(' ');
464
+ }, ...(ngDevMode ? [{ debugName: "classes" }] : []));
465
+ styleWidth = computed(() => (this.width().trim() ? this.width().trim() : null), ...(ngDevMode ? [{ debugName: "styleWidth" }] : []));
466
+ styleHeight = computed(() => (this.height().trim() ? this.height().trim() : null), ...(ngDevMode ? [{ debugName: "styleHeight" }] : []));
467
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TngSkeleton, deps: [], target: i0.ɵɵFactoryTarget.Component });
468
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.6", type: TngSkeleton, isStandalone: true, selector: "tng-skeleton", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, widthKlass: { classPropertyName: "widthKlass", publicName: "widthKlass", isSignal: true, isRequired: false, transformFunction: null }, heightKlass: { classPropertyName: "heightKlass", publicName: "heightKlass", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, shimmer: { classPropertyName: "shimmer", publicName: "shimmer", isSignal: true, isRequired: false, transformFunction: null }, klass: { classPropertyName: "klass", publicName: "klass", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\n [class]=\"classes()\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n aria-hidden=\"true\"\n></div>\n", styles: ["@keyframes tng-skeleton-shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}.tng-skeleton-shimmer:after{content:\"\";position:absolute;inset:0;transform:translate(-100%);animation:tng-skeleton-shimmer 1.25s infinite linear;background:linear-gradient(90deg,transparent,rgba(255,255,255,.35),transparent)}@media(prefers-reduced-motion:reduce){.tng-skeleton-shimmer:after{animation:none}.animate-pulse{animation:none}}\n"] });
469
+ }
470
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TngSkeleton, decorators: [{
471
+ type: Component,
472
+ args: [{ selector: 'tng-skeleton', standalone: true, template: "<div\n [class]=\"classes()\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n aria-hidden=\"true\"\n></div>\n", styles: ["@keyframes tng-skeleton-shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}.tng-skeleton-shimmer:after{content:\"\";position:absolute;inset:0;transform:translate(-100%);animation:tng-skeleton-shimmer 1.25s infinite linear;background:linear-gradient(90deg,transparent,rgba(255,255,255,.35),transparent)}@media(prefers-reduced-motion:reduce){.tng-skeleton-shimmer:after{animation:none}.animate-pulse{animation:none}}\n"] }]
473
+ }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], widthKlass: [{ type: i0.Input, args: [{ isSignal: true, alias: "widthKlass", required: false }] }], heightKlass: [{ type: i0.Input, args: [{ isSignal: true, alias: "heightKlass", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], shimmer: [{ type: i0.Input, args: [{ isSignal: true, alias: "shimmer", required: false }] }], klass: [{ type: i0.Input, args: [{ isSignal: true, alias: "klass", required: false }] }] } });
474
+
475
+ class TngTag {
476
+ label = input('Text', ...(ngDevMode ? [{ debugName: "label" }] : []));
477
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
478
+ color = input('default', ...(ngDevMode ? [{ debugName: "color" }] : []));
479
+ containerKlass = computed(() => {
480
+ const base = 'flex items-center rounded-md px-3 py-1 text-xs font-bold';
481
+ const disabledClass = this.disabled() ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer';
482
+ const colorMap = {
483
+ default: 'bg-gray-100 text-gray-800 hover:bg-gray-200',
484
+ primary: 'bg-blue-100 text-blue-800 hover:bg-blue-200',
485
+ success: 'bg-green-100 text-green-800 hover:bg-green-200',
486
+ danger: 'bg-red-100 text-red-800 hover:bg-red-200',
487
+ };
488
+ return `${base} ${colorMap[this.color()]} ${disabledClass}`;
489
+ }, ...(ngDevMode ? [{ debugName: "containerKlass" }] : []));
490
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TngTag, deps: [], target: i0.ɵɵFactoryTarget.Component });
491
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.6", type: TngTag, isStandalone: true, selector: "tng-tag", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<span [class]=\"containerKlass()\">\n {{ label() }}\n</span>\n" });
492
+ }
493
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TngTag, decorators: [{
494
+ type: Component,
495
+ args: [{ selector: 'tng-tag', standalone: true, template: "<span [class]=\"containerKlass()\">\n {{ label() }}\n</span>\n" }]
496
+ }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }] } });
18
497
 
19
498
  /**
20
499
  * Generated bundle index. Do not edit.
21
500
  */
501
+
502
+ export { TngBadge, TngButton, TngProgressBar, TngProgressSpinner, TngRipple, TngSkeleton, TngTag };
22
503
  //# sourceMappingURL=tociva-tailng-ui-buttons-indicators.mjs.map