tecnualng 21.0.27 → 21.1.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.
- package/fesm2022/tecnualng.mjs +219 -1
- package/fesm2022/tecnualng.mjs.map +1 -1
- package/package.json +9 -1
- package/types/tecnualng.d.ts +87 -2
package/fesm2022/tecnualng.mjs
CHANGED
|
@@ -2199,6 +2199,224 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
|
|
|
2199
2199
|
args: ['window:touchend']
|
|
2200
2200
|
}] } });
|
|
2201
2201
|
|
|
2202
|
+
class TngLoaderComponent {
|
|
2203
|
+
type = input('spinner', ...(ngDevMode ? [{ debugName: "type" }] : []));
|
|
2204
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
|
|
2205
|
+
duration = input(null, ...(ngDevMode ? [{ debugName: "duration" }] : []));
|
|
2206
|
+
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
2207
|
+
progress = input(null, ...(ngDevMode ? [{ debugName: "progress" }] : []));
|
|
2208
|
+
fullscreen = input(false, ...(ngDevMode ? [{ debugName: "fullscreen" }] : []));
|
|
2209
|
+
inline = input(false, ...(ngDevMode ? [{ debugName: "inline" }] : []));
|
|
2210
|
+
hidden = input(false, ...(ngDevMode ? [{ debugName: "hidden" }] : []));
|
|
2211
|
+
color = input(null, ...(ngDevMode ? [{ debugName: "color" }] : []));
|
|
2212
|
+
hostClasses = computed(() => {
|
|
2213
|
+
const classes = [];
|
|
2214
|
+
if (this.fullscreen()) {
|
|
2215
|
+
classes.push('tng-loader--fullscreen');
|
|
2216
|
+
}
|
|
2217
|
+
if (this.inline()) {
|
|
2218
|
+
classes.push('tng-loader--inline');
|
|
2219
|
+
}
|
|
2220
|
+
if (this.hidden()) {
|
|
2221
|
+
classes.push('tng-loader--hidden');
|
|
2222
|
+
}
|
|
2223
|
+
if (this.color()) {
|
|
2224
|
+
classes.push(`tng-loader--${this.color()}`);
|
|
2225
|
+
}
|
|
2226
|
+
classes.push(`tng-loader--type-${this.type()}`);
|
|
2227
|
+
classes.push(`tng-loader--size-${this.size()}`);
|
|
2228
|
+
return classes.join(' ');
|
|
2229
|
+
}, ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
|
|
2230
|
+
// Helper for dynamic styles like duration
|
|
2231
|
+
containerStyles = computed(() => {
|
|
2232
|
+
const styles = {};
|
|
2233
|
+
if (this.duration()) {
|
|
2234
|
+
styles['--tng-loader-duration'] = this.duration();
|
|
2235
|
+
}
|
|
2236
|
+
return styles;
|
|
2237
|
+
}, ...(ngDevMode ? [{ debugName: "containerStyles" }] : []));
|
|
2238
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngLoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2239
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.0", type: TngLoaderComponent, isStandalone: true, selector: "tng-loader", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, duration: { classPropertyName: "duration", publicName: "duration", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, progress: { classPropertyName: "progress", publicName: "progress", isSignal: true, isRequired: false, transformFunction: null }, fullscreen: { classPropertyName: "fullscreen", publicName: "fullscreen", isSignal: true, isRequired: false, transformFunction: null }, inline: { classPropertyName: "inline", publicName: "inline", isSignal: true, isRequired: false, transformFunction: null }, hidden: { classPropertyName: "hidden", publicName: "hidden", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()", "attr.role": "\"status\"", "attr.aria-label": "label() || \"Loading\"", "attr.aria-hidden": "hidden() ? \"true\" : \"false\"" }, classAttribute: "tng-loader" }, ngImport: i0, template: "@if (!hidden()) {\n <div class=\"tng-loader__container\" [style]=\"containerStyles()\">\n \n @switch (type()) {\n @case ('spinner') {\n <svg class=\"tng-loader__spinner\" viewBox=\"0 0 50 50\">\n <circle class=\"tng-loader__spinner-path\" cx=\"25\" cy=\"25\" r=\"20\" fill=\"none\" stroke-width=\"5\"></circle>\n </svg>\n }\n \n @case ('bar') {\n <div class=\"tng-loader__bar\">\n <div class=\"tng-loader__bar-track\"></div>\n <div class=\"tng-loader__bar-fill\" \n [style.width.%]=\"progress() || 0\"\n [class.tng-loader__bar-fill--indeterminate]=\"progress() === null\">\n </div>\n </div>\n }\n \n @case ('dots') {\n <div class=\"tng-loader__dots\">\n <div class=\"tng-loader__dot\"></div>\n <div class=\"tng-loader__dot\"></div>\n <div class=\"tng-loader__dot\"></div>\n </div>\n }\n \n @case ('pulse') {\n <div class=\"tng-loader__pulse\"></div>\n }\n }\n\n @if (label()) {\n <div class=\"tng-loader__label\">{{ label() }}</div>\n }\n </div>\n}\n", styles: [".tng-loader{display:block;box-sizing:border-box;--tng-loader-size: 48px;--tng-loader-color: var(--tng-primary, #6200ee);--tng-loader-duration: 1.5s}.tng-loader--inline{display:inline-block;vertical-align:middle}.tng-loader--hidden{display:none!important}.tng-loader--fullscreen{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#0006;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:9999;display:flex;align-items:center;justify-content:center}.tng-loader--fullscreen .tng-loader__container{background:var(--tng-surface, white);padding:32px;border-radius:16px;box-shadow:0 4px 20px #00000026;display:flex;flex-direction:column;align-items:center;gap:16px}.tng-loader__container{display:flex;align-items:center;justify-content:center;flex-direction:column;gap:8px;color:var(--tng-loader-color)}.tng-loader__label{font-size:.875rem;font-weight:500;font-family:inherit;color:currentColor;opacity:.8}.tng-loader--size-sm{--tng-loader-size: 24px}.tng-loader--size-md{--tng-loader-size: 48px}.tng-loader--size-lg{--tng-loader-size: 72px}.tng-loader--size-xl{--tng-loader-size: 96px}.tng-loader--primary{--tng-loader-color: var(--tng-primary)}.tng-loader--secondary{--tng-loader-color: var(--tng-secondary)}.tng-loader--accent{--tng-loader-color: var(--tng-accent, #00e5ff)}.tng-loader--warn{--tng-loader-color: var(--tng-error, #b00020)}.tng-loader--type-spinner .tng-loader__spinner{width:var(--tng-loader-size);height:var(--tng-loader-size);animation:tng-rotate var(--tng-loader-duration) linear infinite}.tng-loader--type-spinner .tng-loader__spinner-path{stroke:currentColor;stroke-linecap:round;animation:tng-dash var(--tng-loader-duration) ease-in-out infinite}.tng-loader__bar{width:100%;min-width:200px;height:4px;background-color:color-mix(in srgb,currentColor,transparent 80%);border-radius:4px;overflow:hidden;position:relative}.tng-loader__bar-track{position:absolute;top:0;left:0;width:100%;height:100%}.tng-loader__bar-fill{height:100%;background-color:currentColor;transition:width .3s ease}.tng-loader__bar-fill--indeterminate{width:30%;position:absolute;animation:tng-indeterminate-bar var(--tng-loader-duration) infinite linear}.tng-loader--size-sm .tng-loader__bar{height:2px;min-width:100px}.tng-loader--size-lg .tng-loader__bar{height:6px;min-width:300px}.tng-loader--size-xl .tng-loader__bar{height:8px;min-width:400px}.tng-loader__dots{display:flex;gap:calc(var(--tng-loader-size) / 6);height:var(--tng-loader-size);align-items:center}.tng-loader__dots .tng-loader__dot{width:calc(var(--tng-loader-size) / 4);height:calc(var(--tng-loader-size) / 4);background-color:currentColor;border-radius:50%;animation:tng-bounce var(--tng-loader-duration) infinite ease-in-out both}.tng-loader__dots .tng-loader__dot:nth-child(1){animation-delay:-.32s}.tng-loader__dots .tng-loader__dot:nth-child(2){animation-delay:-.16s}.tng-loader__pulse{width:var(--tng-loader-size);height:var(--tng-loader-size);background-color:currentColor;border-radius:50%;animation:tng-pulse var(--tng-loader-duration) infinite ease-in-out}@keyframes tng-rotate{to{transform:rotate(360deg)}}@keyframes tng-dash{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}to{stroke-dasharray:90,150;stroke-dashoffset:-124}}@keyframes tng-indeterminate-bar{0%{left:-30%}to{left:100%}}@keyframes tng-bounce{0%,80%,to{transform:scale(0)}40%{transform:scale(1)}}@keyframes tng-pulse{0%{transform:scale(0);opacity:1}to{transform:scale(1);opacity:0}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
2240
|
+
}
|
|
2241
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngLoaderComponent, decorators: [{
|
|
2242
|
+
type: Component,
|
|
2243
|
+
args: [{ selector: 'tng-loader', imports: [], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
2244
|
+
'class': 'tng-loader',
|
|
2245
|
+
'[class]': 'hostClasses()',
|
|
2246
|
+
'[attr.role]': '"status"',
|
|
2247
|
+
'[attr.aria-label]': 'label() || "Loading"',
|
|
2248
|
+
'[attr.aria-hidden]': 'hidden() ? "true" : "false"',
|
|
2249
|
+
}, template: "@if (!hidden()) {\n <div class=\"tng-loader__container\" [style]=\"containerStyles()\">\n \n @switch (type()) {\n @case ('spinner') {\n <svg class=\"tng-loader__spinner\" viewBox=\"0 0 50 50\">\n <circle class=\"tng-loader__spinner-path\" cx=\"25\" cy=\"25\" r=\"20\" fill=\"none\" stroke-width=\"5\"></circle>\n </svg>\n }\n \n @case ('bar') {\n <div class=\"tng-loader__bar\">\n <div class=\"tng-loader__bar-track\"></div>\n <div class=\"tng-loader__bar-fill\" \n [style.width.%]=\"progress() || 0\"\n [class.tng-loader__bar-fill--indeterminate]=\"progress() === null\">\n </div>\n </div>\n }\n \n @case ('dots') {\n <div class=\"tng-loader__dots\">\n <div class=\"tng-loader__dot\"></div>\n <div class=\"tng-loader__dot\"></div>\n <div class=\"tng-loader__dot\"></div>\n </div>\n }\n \n @case ('pulse') {\n <div class=\"tng-loader__pulse\"></div>\n }\n }\n\n @if (label()) {\n <div class=\"tng-loader__label\">{{ label() }}</div>\n }\n </div>\n}\n", styles: [".tng-loader{display:block;box-sizing:border-box;--tng-loader-size: 48px;--tng-loader-color: var(--tng-primary, #6200ee);--tng-loader-duration: 1.5s}.tng-loader--inline{display:inline-block;vertical-align:middle}.tng-loader--hidden{display:none!important}.tng-loader--fullscreen{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#0006;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:9999;display:flex;align-items:center;justify-content:center}.tng-loader--fullscreen .tng-loader__container{background:var(--tng-surface, white);padding:32px;border-radius:16px;box-shadow:0 4px 20px #00000026;display:flex;flex-direction:column;align-items:center;gap:16px}.tng-loader__container{display:flex;align-items:center;justify-content:center;flex-direction:column;gap:8px;color:var(--tng-loader-color)}.tng-loader__label{font-size:.875rem;font-weight:500;font-family:inherit;color:currentColor;opacity:.8}.tng-loader--size-sm{--tng-loader-size: 24px}.tng-loader--size-md{--tng-loader-size: 48px}.tng-loader--size-lg{--tng-loader-size: 72px}.tng-loader--size-xl{--tng-loader-size: 96px}.tng-loader--primary{--tng-loader-color: var(--tng-primary)}.tng-loader--secondary{--tng-loader-color: var(--tng-secondary)}.tng-loader--accent{--tng-loader-color: var(--tng-accent, #00e5ff)}.tng-loader--warn{--tng-loader-color: var(--tng-error, #b00020)}.tng-loader--type-spinner .tng-loader__spinner{width:var(--tng-loader-size);height:var(--tng-loader-size);animation:tng-rotate var(--tng-loader-duration) linear infinite}.tng-loader--type-spinner .tng-loader__spinner-path{stroke:currentColor;stroke-linecap:round;animation:tng-dash var(--tng-loader-duration) ease-in-out infinite}.tng-loader__bar{width:100%;min-width:200px;height:4px;background-color:color-mix(in srgb,currentColor,transparent 80%);border-radius:4px;overflow:hidden;position:relative}.tng-loader__bar-track{position:absolute;top:0;left:0;width:100%;height:100%}.tng-loader__bar-fill{height:100%;background-color:currentColor;transition:width .3s ease}.tng-loader__bar-fill--indeterminate{width:30%;position:absolute;animation:tng-indeterminate-bar var(--tng-loader-duration) infinite linear}.tng-loader--size-sm .tng-loader__bar{height:2px;min-width:100px}.tng-loader--size-lg .tng-loader__bar{height:6px;min-width:300px}.tng-loader--size-xl .tng-loader__bar{height:8px;min-width:400px}.tng-loader__dots{display:flex;gap:calc(var(--tng-loader-size) / 6);height:var(--tng-loader-size);align-items:center}.tng-loader__dots .tng-loader__dot{width:calc(var(--tng-loader-size) / 4);height:calc(var(--tng-loader-size) / 4);background-color:currentColor;border-radius:50%;animation:tng-bounce var(--tng-loader-duration) infinite ease-in-out both}.tng-loader__dots .tng-loader__dot:nth-child(1){animation-delay:-.32s}.tng-loader__dots .tng-loader__dot:nth-child(2){animation-delay:-.16s}.tng-loader__pulse{width:var(--tng-loader-size);height:var(--tng-loader-size);background-color:currentColor;border-radius:50%;animation:tng-pulse var(--tng-loader-duration) infinite ease-in-out}@keyframes tng-rotate{to{transform:rotate(360deg)}}@keyframes tng-dash{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}to{stroke-dasharray:90,150;stroke-dashoffset:-124}}@keyframes tng-indeterminate-bar{0%{left:-30%}to{left:100%}}@keyframes tng-bounce{0%,80%,to{transform:scale(0)}40%{transform:scale(1)}}@keyframes tng-pulse{0%{transform:scale(0);opacity:1}to{transform:scale(1);opacity:0}}\n"] }]
|
|
2250
|
+
}], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], duration: [{ type: i0.Input, args: [{ isSignal: true, alias: "duration", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], progress: [{ type: i0.Input, args: [{ isSignal: true, alias: "progress", required: false }] }], fullscreen: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullscreen", required: false }] }], inline: [{ type: i0.Input, args: [{ isSignal: true, alias: "inline", required: false }] }], hidden: [{ type: i0.Input, args: [{ isSignal: true, alias: "hidden", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }] } });
|
|
2251
|
+
|
|
2252
|
+
class TngNotificationService {
|
|
2253
|
+
notifications = signal([], ...(ngDevMode ? [{ debugName: "notifications" }] : []));
|
|
2254
|
+
timers = new Map();
|
|
2255
|
+
remainingTimes = new Map();
|
|
2256
|
+
startTimes = new Map();
|
|
2257
|
+
activeNotifications = this.notifications.asReadonly();
|
|
2258
|
+
show(message, options = {}) {
|
|
2259
|
+
const id = options.id || this.generateId();
|
|
2260
|
+
const duration = options.duration ?? 3000;
|
|
2261
|
+
const config = {
|
|
2262
|
+
id,
|
|
2263
|
+
message,
|
|
2264
|
+
type: options.type || 'default',
|
|
2265
|
+
position: options.position || 'top-right',
|
|
2266
|
+
duration,
|
|
2267
|
+
clipboard: options.clipboard,
|
|
2268
|
+
closable: options.closable ?? true,
|
|
2269
|
+
icon: options.icon,
|
|
2270
|
+
pauseOnHover: options.pauseOnHover ?? true,
|
|
2271
|
+
};
|
|
2272
|
+
this.notifications.update(current => [...current, config]);
|
|
2273
|
+
if (duration > 0) {
|
|
2274
|
+
this.startTimer(id, duration);
|
|
2275
|
+
}
|
|
2276
|
+
return id;
|
|
2277
|
+
}
|
|
2278
|
+
success(message, options) {
|
|
2279
|
+
return this.show(message, { ...options, type: 'success' });
|
|
2280
|
+
}
|
|
2281
|
+
error(message, options) {
|
|
2282
|
+
return this.show(message, { ...options, type: 'error' });
|
|
2283
|
+
}
|
|
2284
|
+
warning(message, options) {
|
|
2285
|
+
return this.show(message, { ...options, type: 'warning' });
|
|
2286
|
+
}
|
|
2287
|
+
info(message, options) {
|
|
2288
|
+
return this.show(message, { ...options, type: 'info' });
|
|
2289
|
+
}
|
|
2290
|
+
remove(id) {
|
|
2291
|
+
this.clearTimer(id);
|
|
2292
|
+
this.notifications.update(current => current.filter(n => n.id !== id));
|
|
2293
|
+
}
|
|
2294
|
+
clear() {
|
|
2295
|
+
this.timers.forEach((timer) => clearTimeout(timer));
|
|
2296
|
+
this.timers.clear();
|
|
2297
|
+
this.remainingTimes.clear();
|
|
2298
|
+
this.startTimes.clear();
|
|
2299
|
+
this.notifications.set([]);
|
|
2300
|
+
}
|
|
2301
|
+
pauseTimer(id) {
|
|
2302
|
+
const notification = this.notifications().find(n => n.id === id);
|
|
2303
|
+
if (!notification?.pauseOnHover || !this.timers.has(id))
|
|
2304
|
+
return;
|
|
2305
|
+
clearTimeout(this.timers.get(id));
|
|
2306
|
+
this.timers.delete(id);
|
|
2307
|
+
const elapsed = Date.now() - (this.startTimes.get(id) || 0);
|
|
2308
|
+
const duration = notification.duration || 3000;
|
|
2309
|
+
const remaining = this.remainingTimes.has(id)
|
|
2310
|
+
? this.remainingTimes.get(id) - elapsed
|
|
2311
|
+
: duration - elapsed;
|
|
2312
|
+
this.remainingTimes.set(id, remaining > 0 ? remaining : 0);
|
|
2313
|
+
}
|
|
2314
|
+
resumeTimer(id) {
|
|
2315
|
+
const notification = this.notifications().find(n => n.id === id);
|
|
2316
|
+
if (!notification?.pauseOnHover || !this.remainingTimes.has(id))
|
|
2317
|
+
return;
|
|
2318
|
+
const remaining = this.remainingTimes.get(id) || 0;
|
|
2319
|
+
if (remaining > 0) {
|
|
2320
|
+
this.startTimer(id, remaining);
|
|
2321
|
+
}
|
|
2322
|
+
else {
|
|
2323
|
+
this.remove(id);
|
|
2324
|
+
}
|
|
2325
|
+
}
|
|
2326
|
+
startTimer(id, duration) {
|
|
2327
|
+
this.startTimes.set(id, Date.now());
|
|
2328
|
+
const timerId = setTimeout(() => {
|
|
2329
|
+
this.remove(id);
|
|
2330
|
+
}, duration);
|
|
2331
|
+
this.timers.set(id, timerId);
|
|
2332
|
+
}
|
|
2333
|
+
clearTimer(id) {
|
|
2334
|
+
if (this.timers.has(id)) {
|
|
2335
|
+
clearTimeout(this.timers.get(id));
|
|
2336
|
+
this.timers.delete(id);
|
|
2337
|
+
}
|
|
2338
|
+
this.remainingTimes.delete(id);
|
|
2339
|
+
this.startTimes.delete(id);
|
|
2340
|
+
}
|
|
2341
|
+
generateId() {
|
|
2342
|
+
return Math.random().toString(36).substring(2, 9);
|
|
2343
|
+
}
|
|
2344
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngNotificationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2345
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngNotificationService, providedIn: 'root' });
|
|
2346
|
+
}
|
|
2347
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngNotificationService, decorators: [{
|
|
2348
|
+
type: Injectable,
|
|
2349
|
+
args: [{
|
|
2350
|
+
providedIn: 'root'
|
|
2351
|
+
}]
|
|
2352
|
+
}] });
|
|
2353
|
+
|
|
2354
|
+
class TngToastComponent {
|
|
2355
|
+
config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
|
|
2356
|
+
service = inject(TngNotificationService);
|
|
2357
|
+
onMouseEnter() {
|
|
2358
|
+
this.service.pauseTimer(this.config().id);
|
|
2359
|
+
}
|
|
2360
|
+
onMouseLeave() {
|
|
2361
|
+
this.service.resumeTimer(this.config().id);
|
|
2362
|
+
}
|
|
2363
|
+
close() {
|
|
2364
|
+
this.service.remove(this.config().id);
|
|
2365
|
+
}
|
|
2366
|
+
// Copied tooltip state
|
|
2367
|
+
showCopiedTooltip = signal(false, ...(ngDevMode ? [{ debugName: "showCopiedTooltip" }] : []));
|
|
2368
|
+
copyToClipboard() {
|
|
2369
|
+
const text = this.config().clipboard;
|
|
2370
|
+
if (text) {
|
|
2371
|
+
navigator.clipboard.writeText(text).then(() => {
|
|
2372
|
+
// Show tooltip
|
|
2373
|
+
this.showCopiedTooltip.set(true);
|
|
2374
|
+
console.log('Copied to clipboard');
|
|
2375
|
+
// Hide after 4 seconds
|
|
2376
|
+
setTimeout(() => {
|
|
2377
|
+
this.showCopiedTooltip.set(false);
|
|
2378
|
+
}, 4000);
|
|
2379
|
+
});
|
|
2380
|
+
}
|
|
2381
|
+
}
|
|
2382
|
+
get iconClass() {
|
|
2383
|
+
const type = this.config().type;
|
|
2384
|
+
const customIcon = this.config().icon;
|
|
2385
|
+
if (customIcon)
|
|
2386
|
+
return customIcon;
|
|
2387
|
+
switch (type) {
|
|
2388
|
+
case 'success': return 'fa fa-check-circle';
|
|
2389
|
+
case 'error': return 'fa fa-exclamation-circle';
|
|
2390
|
+
case 'warning': return 'fa fa-exclamation-triangle';
|
|
2391
|
+
case 'info': return 'fa fa-info-circle';
|
|
2392
|
+
default: return 'fa fa-bell';
|
|
2393
|
+
}
|
|
2394
|
+
}
|
|
2395
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngToastComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2396
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.0", type: TngToastComponent, isStandalone: true, selector: "tng-toast", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div \n class=\"tng-toast\" \n [class]=\"'tng-toast--' + config().type\"\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\">\n \n <div class=\"tng-toast__icon\">\n <i [class]=\"iconClass\"></i>\n </div>\n\n <div class=\"tng-toast__content\">\n <div class=\"tng-toast__message\">{{ config().message }}</div>\n </div>\n\n <div class=\"tng-toast__actions\">\n @if (config().clipboard) {\n <div class=\"tng-toast__action-wrapper\">\n <button class=\"tng-toast__action-btn\" (click)=\"copyToClipboard()\" aria-label=\"Copy to clipboard\">\n <i class=\"fa fa-copy\"></i>\n </button>\n @if (showCopiedTooltip()) {\n <div class=\"tng-toast__tooltip\">\u00A1Texto copiado al portapapeles!</div>\n }\n </div>\n }\n \n @if (config().closable) {\n <button class=\"tng-toast__close-btn\" (click)=\"close()\" aria-label=\"Close notification\">\n <i class=\"fa fa-times\"></i>\n </button>\n }\n </div>\n\n @if (config().duration! > 0) {\n <div class=\"tng-toast__progress\" [style.animation-duration]=\"config().duration + 'ms'\"></div>\n }\n</div>\n", styles: [".tng-toast{position:relative;display:flex;align-items:center;padding:12px 16px;border-radius:8px;background:var(--tng-surface, white);box-shadow:var(--tng-shadow-md, 0 4px 6px -1px rgba(0, 0, 0, .1));min-width:300px;max-width:400px;gap:12px;pointer-events:auto;border-left:4px solid transparent;color:var(--tng-text, #333);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);font-family:inherit;font-size:.875rem;line-height:1.4;margin-bottom:8px;animation:tng-toast-fade-in .3s ease-out forwards}.tng-toast__icon{flex-shrink:0;font-size:1.25rem;display:flex;align-items:center}.tng-toast__content{flex:1;word-break:break-word}.tng-toast__actions{display:flex;gap:8px;margin-left:8px}.tng-toast__action-btn,.tng-toast__close-btn{background:transparent;border:none;cursor:pointer;padding:4px;color:inherit;opacity:.6;transition:opacity .2s;border-radius:4px}.tng-toast__action-btn:hover,.tng-toast__close-btn:hover{opacity:1;background:#0000000d}.tng-toast--success{border-left-color:var(--tng-success, #2e7d32)}.tng-toast--success .tng-toast__icon{color:var(--tng-success, #2e7d32)}.tng-toast--error{border-left-color:var(--tng-error, #d32f2f)}.tng-toast--error .tng-toast__icon{color:var(--tng-error, #d32f2f)}.tng-toast--warning{border-left-color:var(--tng-warning, #ed6c02)}.tng-toast--warning .tng-toast__icon{color:var(--tng-warning, #ed6c02)}.tng-toast--info{border-left-color:var(--tng-info, #0288d1)}.tng-toast--info .tng-toast__icon{color:var(--tng-info, #0288d1)}.tng-toast--default{border-left-color:var(--tng-separator, #e0e0e0)}.tng-toast--default .tng-toast__icon{color:var(--tng-text-secondary, #757575)}@keyframes tng-toast-fade-in{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.tng-toast__action-wrapper{position:relative;display:inline-block}.tng-toast__tooltip{position:absolute;bottom:100%;right:50%;transform:translate(50%);background-color:#333;color:#fff;padding:4px 8px;border-radius:4px;font-size:.75rem;white-space:nowrap;opacity:0;animation:tng-tooltip-fade .3s ease forwards;pointer-events:none;margin-bottom:8px;z-index:10}.tng-toast__tooltip:after{content:\"\";position:absolute;top:100%;left:50%;margin-left:-4px;border-width:4px;border-style:solid;border-color:#333 transparent transparent transparent}.tng-toast__progress{position:absolute;bottom:0;left:0;height:4px;background-color:var(--tng-toast-color, #ccc);width:100%;transform-origin:left;animation:tng-toast-progress linear forwards;border-bottom-left-radius:8px;border-bottom-right-radius:8px}.tng-toast--success{--tng-toast-color: var(--tng-success, #2e7d32)}.tng-toast--error{--tng-toast-color: var(--tng-error, #d32f2f)}.tng-toast--warning{--tng-toast-color: var(--tng-warning, #ed6c02)}.tng-toast--info{--tng-toast-color: var(--tng-info, #0288d1)}.tng-toast--default{--tng-toast-color: var(--tng-text-secondary, #757575)}.tng-toast:hover .tng-toast__progress{animation-play-state:paused}@keyframes tng-toast-progress{0%{width:100%}to{width:0%}}@keyframes tng-tooltip-fade{0%{opacity:0;transform:translate(50%) translateY(4px)}to{opacity:1;transform:translate(50%) translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
2397
|
+
}
|
|
2398
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngToastComponent, decorators: [{
|
|
2399
|
+
type: Component,
|
|
2400
|
+
args: [{ selector: 'tng-toast', standalone: true, imports: [CommonModule], template: "<div \n class=\"tng-toast\" \n [class]=\"'tng-toast--' + config().type\"\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\">\n \n <div class=\"tng-toast__icon\">\n <i [class]=\"iconClass\"></i>\n </div>\n\n <div class=\"tng-toast__content\">\n <div class=\"tng-toast__message\">{{ config().message }}</div>\n </div>\n\n <div class=\"tng-toast__actions\">\n @if (config().clipboard) {\n <div class=\"tng-toast__action-wrapper\">\n <button class=\"tng-toast__action-btn\" (click)=\"copyToClipboard()\" aria-label=\"Copy to clipboard\">\n <i class=\"fa fa-copy\"></i>\n </button>\n @if (showCopiedTooltip()) {\n <div class=\"tng-toast__tooltip\">\u00A1Texto copiado al portapapeles!</div>\n }\n </div>\n }\n \n @if (config().closable) {\n <button class=\"tng-toast__close-btn\" (click)=\"close()\" aria-label=\"Close notification\">\n <i class=\"fa fa-times\"></i>\n </button>\n }\n </div>\n\n @if (config().duration! > 0) {\n <div class=\"tng-toast__progress\" [style.animation-duration]=\"config().duration + 'ms'\"></div>\n }\n</div>\n", styles: [".tng-toast{position:relative;display:flex;align-items:center;padding:12px 16px;border-radius:8px;background:var(--tng-surface, white);box-shadow:var(--tng-shadow-md, 0 4px 6px -1px rgba(0, 0, 0, .1));min-width:300px;max-width:400px;gap:12px;pointer-events:auto;border-left:4px solid transparent;color:var(--tng-text, #333);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);font-family:inherit;font-size:.875rem;line-height:1.4;margin-bottom:8px;animation:tng-toast-fade-in .3s ease-out forwards}.tng-toast__icon{flex-shrink:0;font-size:1.25rem;display:flex;align-items:center}.tng-toast__content{flex:1;word-break:break-word}.tng-toast__actions{display:flex;gap:8px;margin-left:8px}.tng-toast__action-btn,.tng-toast__close-btn{background:transparent;border:none;cursor:pointer;padding:4px;color:inherit;opacity:.6;transition:opacity .2s;border-radius:4px}.tng-toast__action-btn:hover,.tng-toast__close-btn:hover{opacity:1;background:#0000000d}.tng-toast--success{border-left-color:var(--tng-success, #2e7d32)}.tng-toast--success .tng-toast__icon{color:var(--tng-success, #2e7d32)}.tng-toast--error{border-left-color:var(--tng-error, #d32f2f)}.tng-toast--error .tng-toast__icon{color:var(--tng-error, #d32f2f)}.tng-toast--warning{border-left-color:var(--tng-warning, #ed6c02)}.tng-toast--warning .tng-toast__icon{color:var(--tng-warning, #ed6c02)}.tng-toast--info{border-left-color:var(--tng-info, #0288d1)}.tng-toast--info .tng-toast__icon{color:var(--tng-info, #0288d1)}.tng-toast--default{border-left-color:var(--tng-separator, #e0e0e0)}.tng-toast--default .tng-toast__icon{color:var(--tng-text-secondary, #757575)}@keyframes tng-toast-fade-in{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.tng-toast__action-wrapper{position:relative;display:inline-block}.tng-toast__tooltip{position:absolute;bottom:100%;right:50%;transform:translate(50%);background-color:#333;color:#fff;padding:4px 8px;border-radius:4px;font-size:.75rem;white-space:nowrap;opacity:0;animation:tng-tooltip-fade .3s ease forwards;pointer-events:none;margin-bottom:8px;z-index:10}.tng-toast__tooltip:after{content:\"\";position:absolute;top:100%;left:50%;margin-left:-4px;border-width:4px;border-style:solid;border-color:#333 transparent transparent transparent}.tng-toast__progress{position:absolute;bottom:0;left:0;height:4px;background-color:var(--tng-toast-color, #ccc);width:100%;transform-origin:left;animation:tng-toast-progress linear forwards;border-bottom-left-radius:8px;border-bottom-right-radius:8px}.tng-toast--success{--tng-toast-color: var(--tng-success, #2e7d32)}.tng-toast--error{--tng-toast-color: var(--tng-error, #d32f2f)}.tng-toast--warning{--tng-toast-color: var(--tng-warning, #ed6c02)}.tng-toast--info{--tng-toast-color: var(--tng-info, #0288d1)}.tng-toast--default{--tng-toast-color: var(--tng-text-secondary, #757575)}.tng-toast:hover .tng-toast__progress{animation-play-state:paused}@keyframes tng-toast-progress{0%{width:100%}to{width:0%}}@keyframes tng-tooltip-fade{0%{opacity:0;transform:translate(50%) translateY(4px)}to{opacity:1;transform:translate(50%) translateY(0)}}\n"] }]
|
|
2401
|
+
}], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }] } });
|
|
2402
|
+
|
|
2403
|
+
class TngNotificationContainerComponent {
|
|
2404
|
+
service = inject(TngNotificationService);
|
|
2405
|
+
notifications = this.service.activeNotifications;
|
|
2406
|
+
topLeft = computed(() => this.notifications().filter(n => n.position === 'top-left'), ...(ngDevMode ? [{ debugName: "topLeft" }] : []));
|
|
2407
|
+
topRight = computed(() => this.notifications().filter(n => n.position === 'top-right' || !n.position), ...(ngDevMode ? [{ debugName: "topRight" }] : []));
|
|
2408
|
+
topCenter = computed(() => this.notifications().filter(n => n.position === 'top-center'), ...(ngDevMode ? [{ debugName: "topCenter" }] : []));
|
|
2409
|
+
bottomLeft = computed(() => this.notifications().filter(n => n.position === 'bottom-left'), ...(ngDevMode ? [{ debugName: "bottomLeft" }] : []));
|
|
2410
|
+
bottomRight = computed(() => this.notifications().filter(n => n.position === 'bottom-right'), ...(ngDevMode ? [{ debugName: "bottomRight" }] : []));
|
|
2411
|
+
bottomCenter = computed(() => this.notifications().filter(n => n.position === 'bottom-center'), ...(ngDevMode ? [{ debugName: "bottomCenter" }] : []));
|
|
2412
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngNotificationContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2413
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.0", type: TngNotificationContainerComponent, isStandalone: true, selector: "tng-notification-container", ngImport: i0, template: "<div class=\"tng-notification-container tng-notification-container--top-left\">\n @for (notification of topLeft(); track notification.id) {\n <tng-toast [config]=\"notification\"></tng-toast>\n }\n</div>\n\n<div class=\"tng-notification-container tng-notification-container--top-right\">\n @for (notification of topRight(); track notification.id) {\n <tng-toast [config]=\"notification\"></tng-toast>\n }\n</div>\n\n<div class=\"tng-notification-container tng-notification-container--top-center\">\n @for (notification of topCenter(); track notification.id) {\n <tng-toast [config]=\"notification\"></tng-toast>\n }\n</div>\n\n<div class=\"tng-notification-container tng-notification-container--bottom-left\">\n @for (notification of bottomLeft(); track notification.id) {\n <tng-toast [config]=\"notification\"></tng-toast>\n }\n</div>\n\n<div class=\"tng-notification-container tng-notification-container--bottom-right\">\n @for (notification of bottomRight(); track notification.id) {\n <tng-toast [config]=\"notification\"></tng-toast>\n }\n</div>\n\n<div class=\"tng-notification-container tng-notification-container--bottom-center\">\n @for (notification of bottomCenter(); track notification.id) {\n <tng-toast [config]=\"notification\"></tng-toast>\n }\n</div>\n", styles: [".tng-notification-container{position:fixed;z-index:9999;display:flex;flex-direction:column;pointer-events:none;padding:16px;gap:12px;max-width:100vw;box-sizing:border-box}.tng-notification-container--top-left{top:0;left:0;align-items:flex-start}.tng-notification-container--top-right{top:0;right:0;align-items:flex-end}.tng-notification-container--top-center{top:0;left:50%;transform:translate(-50%);align-items:center}.tng-notification-container--bottom-left{bottom:0;left:0;flex-direction:column-reverse;align-items:flex-start}.tng-notification-container--bottom-right{bottom:0;right:0;flex-direction:column-reverse;align-items:flex-end}.tng-notification-container--bottom-center{bottom:0;left:50%;transform:translate(-50%);flex-direction:column-reverse;align-items:center}@media(max-width:600px){.tng-notification-container{width:100%;padding:12px}.tng-notification-container--top-left,.tng-notification-container--top-right,.tng-notification-container--top-center,.tng-notification-container--bottom-left,.tng-notification-container--bottom-right,.tng-notification-container--bottom-center{left:0;right:0;transform:none;align-items:center}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: TngToastComponent, selector: "tng-toast", inputs: ["config"] }] });
|
|
2414
|
+
}
|
|
2415
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngNotificationContainerComponent, decorators: [{
|
|
2416
|
+
type: Component,
|
|
2417
|
+
args: [{ selector: 'tng-notification-container', standalone: true, imports: [CommonModule, TngToastComponent], template: "<div class=\"tng-notification-container tng-notification-container--top-left\">\n @for (notification of topLeft(); track notification.id) {\n <tng-toast [config]=\"notification\"></tng-toast>\n }\n</div>\n\n<div class=\"tng-notification-container tng-notification-container--top-right\">\n @for (notification of topRight(); track notification.id) {\n <tng-toast [config]=\"notification\"></tng-toast>\n }\n</div>\n\n<div class=\"tng-notification-container tng-notification-container--top-center\">\n @for (notification of topCenter(); track notification.id) {\n <tng-toast [config]=\"notification\"></tng-toast>\n }\n</div>\n\n<div class=\"tng-notification-container tng-notification-container--bottom-left\">\n @for (notification of bottomLeft(); track notification.id) {\n <tng-toast [config]=\"notification\"></tng-toast>\n }\n</div>\n\n<div class=\"tng-notification-container tng-notification-container--bottom-right\">\n @for (notification of bottomRight(); track notification.id) {\n <tng-toast [config]=\"notification\"></tng-toast>\n }\n</div>\n\n<div class=\"tng-notification-container tng-notification-container--bottom-center\">\n @for (notification of bottomCenter(); track notification.id) {\n <tng-toast [config]=\"notification\"></tng-toast>\n }\n</div>\n", styles: [".tng-notification-container{position:fixed;z-index:9999;display:flex;flex-direction:column;pointer-events:none;padding:16px;gap:12px;max-width:100vw;box-sizing:border-box}.tng-notification-container--top-left{top:0;left:0;align-items:flex-start}.tng-notification-container--top-right{top:0;right:0;align-items:flex-end}.tng-notification-container--top-center{top:0;left:50%;transform:translate(-50%);align-items:center}.tng-notification-container--bottom-left{bottom:0;left:0;flex-direction:column-reverse;align-items:flex-start}.tng-notification-container--bottom-right{bottom:0;right:0;flex-direction:column-reverse;align-items:flex-end}.tng-notification-container--bottom-center{bottom:0;left:50%;transform:translate(-50%);flex-direction:column-reverse;align-items:center}@media(max-width:600px){.tng-notification-container{width:100%;padding:12px}.tng-notification-container--top-left,.tng-notification-container--top-right,.tng-notification-container--top-center,.tng-notification-container--bottom-left,.tng-notification-container--bottom-right,.tng-notification-container--bottom-center{left:0;right:0;transform:none;align-items:center}}\n"] }]
|
|
2418
|
+
}] });
|
|
2419
|
+
|
|
2202
2420
|
/*
|
|
2203
2421
|
* Public API Surface of tecnualng
|
|
2204
2422
|
*/
|
|
@@ -2207,5 +2425,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
|
|
|
2207
2425
|
* Generated bundle index. Do not edit.
|
|
2208
2426
|
*/
|
|
2209
2427
|
|
|
2210
|
-
export { TecnualDatepickerComponent, TecnualInputComponent, TecnualTableComponent, ThemeService, TngButton, TngCardComponent, TngExpansionPanelComponent, TngFormFieldComponent, TngInputDirective, TngMenuComponent, TngMenuGroupComponent, TngMenuItemComponent, TngSelectComponent, TngSelectDirective, TngSelectPanelComponent, TngSidebarComponent, TngSliderComponent, TngTabComponent, TngTabsComponent, TngTextareaComponent, TngTextareaDirective, TngToolbarComponent, TngTooltipComponent, TngTooltipDirective };
|
|
2428
|
+
export { TecnualDatepickerComponent, TecnualInputComponent, TecnualTableComponent, ThemeService, TngButton, TngCardComponent, TngExpansionPanelComponent, TngFormFieldComponent, TngInputDirective, TngLoaderComponent, TngMenuComponent, TngMenuGroupComponent, TngMenuItemComponent, TngNotificationContainerComponent, TngNotificationService, TngSelectComponent, TngSelectDirective, TngSelectPanelComponent, TngSidebarComponent, TngSliderComponent, TngTabComponent, TngTabsComponent, TngTextareaComponent, TngTextareaDirective, TngToastComponent, TngToolbarComponent, TngTooltipComponent, TngTooltipDirective };
|
|
2211
2429
|
//# sourceMappingURL=tecnualng.mjs.map
|