@catarina-ds/angular 0.1.1 → 0.1.3
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/catarina-ds-angular.mjs +242 -728
- package/fesm2022/catarina-ds-angular.mjs.map +1 -1
- package/index.d.ts +90 -61
- package/package.json +1 -1
|
@@ -1,218 +1,19 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { isPlatformBrowser, NgClass, NgIf } from '@angular/common';
|
|
2
|
+
import { Component, EventEmitter, TemplateRef, HostBinding, Output, Input, ViewChild, ContentChildren, inject, ElementRef, PLATFORM_ID, Optional, Self, Directive, forwardRef, HostListener, DOCUMENT, Inject, ViewContainerRef, ChangeDetectorRef, Injectable, input, effect } from '@angular/core';
|
|
3
|
+
import { NgComponentOutlet, NgTemplateOutlet, NgClass, NgIf, isPlatformBrowser } from '@angular/common';
|
|
5
4
|
import { NgControl, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
6
5
|
import { Overlay } from '@angular/cdk/overlay';
|
|
7
6
|
import { TemplatePortal } from '@angular/cdk/portal';
|
|
8
|
-
import { BehaviorSubject } from 'rxjs';
|
|
9
|
-
|
|
10
|
-
const ICON_PROVIDER = new InjectionToken('ICON_PROVIDER', {
|
|
11
|
-
providedIn: 'root',
|
|
12
|
-
factory: () => ({
|
|
13
|
-
// Proporciona un fallback por defecto si no se configura
|
|
14
|
-
getPath: (name) => `icons/${name}.svg`
|
|
15
|
-
})
|
|
16
|
-
});
|
|
7
|
+
import { BehaviorSubject, Subject, Subscription } from 'rxjs';
|
|
17
8
|
|
|
18
9
|
class Icon {
|
|
19
|
-
sanitizer = inject(DomSanitizer);
|
|
20
|
-
platformId = inject(PLATFORM_ID);
|
|
21
|
-
iconProvider = inject(ICON_PROVIDER);
|
|
22
|
-
abortController;
|
|
23
|
-
svgContent = signal('', ...(ngDevMode ? [{ debugName: "svgContent" }] : []));
|
|
24
|
-
isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
|
|
25
|
-
isVisible = signal(false, ...(ngDevMode ? [{ debugName: "isVisible" }] : []));
|
|
26
|
-
size = '1em';
|
|
27
|
-
color = 'currentColor';
|
|
28
|
-
ngOnDestroy() {
|
|
29
|
-
this.abortController?.abort();
|
|
30
|
-
}
|
|
31
|
-
// Usa el nombre del icono con el provider configurado
|
|
32
|
-
set name(iconName) {
|
|
33
|
-
if (!iconName) {
|
|
34
|
-
this.isVisible.set(false);
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
const path = this.iconProvider.getPath(iconName);
|
|
38
|
-
// Cancela la petición anterior si existe
|
|
39
|
-
this.abortController?.abort();
|
|
40
|
-
// Si el path es el fallback por defecto (icons/), no muestra nada
|
|
41
|
-
if (!path || path.startsWith('icons/')) {
|
|
42
|
-
this.isVisible.set(false);
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
this.loadSvg(path);
|
|
46
|
-
}
|
|
47
|
-
// Usa el path directo del icono
|
|
48
|
-
set src(path) {
|
|
49
|
-
if (!path) {
|
|
50
|
-
this.isVisible.set(false);
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
// Cancela la petición anterior si existe
|
|
54
|
-
this.abortController?.abort();
|
|
55
|
-
this.loadSvg(path);
|
|
56
|
-
}
|
|
57
|
-
loadSvg(path) {
|
|
58
|
-
// En SSR, no muestra nada
|
|
59
|
-
if (!isPlatformBrowser(this.platformId)) {
|
|
60
|
-
this.isVisible.set(false);
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
// Limpia el contenido y oculta el icono mientras carga
|
|
64
|
-
this.isLoading.set(true);
|
|
65
|
-
this.svgContent.set('');
|
|
66
|
-
this.isVisible.set(false);
|
|
67
|
-
// Crea un nuevo AbortController para esta petición
|
|
68
|
-
this.abortController = new AbortController();
|
|
69
|
-
fetch(path, {
|
|
70
|
-
signal: this.abortController.signal,
|
|
71
|
-
mode: 'cors',
|
|
72
|
-
cache: 'default'
|
|
73
|
-
})
|
|
74
|
-
.then(response => {
|
|
75
|
-
if (!response.ok) {
|
|
76
|
-
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
77
|
-
}
|
|
78
|
-
return response.text();
|
|
79
|
-
})
|
|
80
|
-
.then(svg => {
|
|
81
|
-
// Verifica que el contenido sea un SVG válido
|
|
82
|
-
if (!this.isValidSvg(svg)) {
|
|
83
|
-
console.error(`Invalid SVG received from ${path}. Response is not valid SVG.`);
|
|
84
|
-
this.isVisible.set(false);
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
const processed = this.processSvg(svg);
|
|
88
|
-
if (processed) {
|
|
89
|
-
this.svgContent.set(this.sanitizer.bypassSecurityTrustHtml(processed));
|
|
90
|
-
this.isVisible.set(true);
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
this.isVisible.set(false);
|
|
94
|
-
}
|
|
95
|
-
})
|
|
96
|
-
.catch((error) => {
|
|
97
|
-
// Ignora el error de abort
|
|
98
|
-
if (error.name === 'AbortError') {
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
console.error(`Error loading icon from ${path}:`, error.message);
|
|
102
|
-
this.isVisible.set(false);
|
|
103
|
-
})
|
|
104
|
-
.finally(() => {
|
|
105
|
-
this.isLoading.set(false);
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
isValidSvg(content) {
|
|
109
|
-
// Realiza validaciones estrictas para asegurar que sea SVG
|
|
110
|
-
const trimmed = content.trim();
|
|
111
|
-
// 1. Verifica que comience con <svg (ignorando espacios y declaraciones XML)
|
|
112
|
-
const svgRegex = /^\s*(<\?xml[^>]*>\s*)?<\s*svg\b/i;
|
|
113
|
-
if (!svgRegex.test(trimmed)) {
|
|
114
|
-
return false;
|
|
115
|
-
}
|
|
116
|
-
// 2. Verifica que termine con </svg>
|
|
117
|
-
if (!trimmed.includes('</svg>')) {
|
|
118
|
-
return false;
|
|
119
|
-
}
|
|
120
|
-
// 3. Verifica que no contenga <html>, <head>, <body> (indicaría HTML completo)
|
|
121
|
-
const htmlTags = ['<html', '<head', '<body', '<!DOCTYPE html'];
|
|
122
|
-
for (const tag of htmlTags) {
|
|
123
|
-
if (trimmed.toLowerCase().includes(tag.toLowerCase())) {
|
|
124
|
-
return false;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
// 4. Verifica que tenga un tamaño razonable para un icono (máximo 100KB)
|
|
128
|
-
if (content.length > 100 * 1024) {
|
|
129
|
-
console.warn('SVG file is too large for an icon:', content.length, 'bytes');
|
|
130
|
-
return false;
|
|
131
|
-
}
|
|
132
|
-
return true;
|
|
133
|
-
}
|
|
134
|
-
processSvg(svg) {
|
|
135
|
-
// Valida el SVG antes de procesarlo
|
|
136
|
-
if (!this.isValidSvg(svg)) {
|
|
137
|
-
return null;
|
|
138
|
-
}
|
|
139
|
-
// En SSR, usa procesamiento simple con regex (no hay DOMParser)
|
|
140
|
-
if (!isPlatformBrowser(this.platformId)) {
|
|
141
|
-
return this.processSvgWithRegex(svg);
|
|
142
|
-
}
|
|
143
|
-
// En Browser, usa DOMParser para procesamiento robusto
|
|
144
|
-
try {
|
|
145
|
-
const parser = new DOMParser();
|
|
146
|
-
const doc = parser.parseFromString(svg, 'image/svg+xml');
|
|
147
|
-
// Verifica que no haya errores de parseo
|
|
148
|
-
const parserError = doc.querySelector('parsererror');
|
|
149
|
-
if (parserError) {
|
|
150
|
-
console.error('SVG parsing error:', parserError.textContent);
|
|
151
|
-
return null;
|
|
152
|
-
}
|
|
153
|
-
const svgElement = doc.querySelector('svg');
|
|
154
|
-
if (!svgElement) {
|
|
155
|
-
return null;
|
|
156
|
-
}
|
|
157
|
-
// Verifica que sea realmente un elemento SVG
|
|
158
|
-
if (svgElement.tagName.toLowerCase() !== 'svg') {
|
|
159
|
-
return null;
|
|
160
|
-
}
|
|
161
|
-
// Modifica solo el elemento <svg> raíz
|
|
162
|
-
svgElement.removeAttribute('width');
|
|
163
|
-
svgElement.removeAttribute('height');
|
|
164
|
-
// Cambia fill y stroke solo si no son "none"
|
|
165
|
-
const currentFill = svgElement.getAttribute('fill');
|
|
166
|
-
if (currentFill && currentFill !== 'none') {
|
|
167
|
-
svgElement.setAttribute('fill', 'currentColor');
|
|
168
|
-
}
|
|
169
|
-
const currentStroke = svgElement.getAttribute('stroke');
|
|
170
|
-
if (currentStroke && currentStroke !== 'none') {
|
|
171
|
-
svgElement.setAttribute('stroke', 'currentColor');
|
|
172
|
-
}
|
|
173
|
-
// Asegura el viewBox (requerido para escalado)
|
|
174
|
-
if (!svgElement.hasAttribute('viewBox')) {
|
|
175
|
-
svgElement.setAttribute('viewBox', '0 0 24 24');
|
|
176
|
-
}
|
|
177
|
-
// Serializa el SVG de vuelta a string
|
|
178
|
-
return new XMLSerializer().serializeToString(svgElement);
|
|
179
|
-
}
|
|
180
|
-
catch (error) {
|
|
181
|
-
console.error('Error processing SVG:', error);
|
|
182
|
-
return null;
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
processSvgWithRegex(svg) {
|
|
186
|
-
// Realiza procesamiento simple con regex para SSR (donde no hay DOMParser)
|
|
187
|
-
let processed = svg;
|
|
188
|
-
// Remueve width y height solo del tag <svg> de apertura
|
|
189
|
-
processed = processed.replace(/(<svg[^>]*?)\s+width="[^"]*"/i, '$1');
|
|
190
|
-
processed = processed.replace(/(<svg[^>]*?)\s+height="[^"]*"/i, '$1');
|
|
191
|
-
// Cambia fill a currentColor si existe y no es "none"
|
|
192
|
-
processed = processed.replace(/(<svg[^>]*?\s+fill=")(?!none)([^"]*)(")/i, '$1currentColor$3');
|
|
193
|
-
// Cambia stroke a currentColor si existe y no es "none"
|
|
194
|
-
processed = processed.replace(/(<svg[^>]*?\s+stroke=")(?!none)([^"]*)(")/i, '$1currentColor$3');
|
|
195
|
-
// Asegura el viewBox si no existe
|
|
196
|
-
if (!/viewBox=/i.test(processed)) {
|
|
197
|
-
processed = processed.replace(/(<svg[^>]*?)>/i, '$1 viewBox="0 0 24 24">');
|
|
198
|
-
}
|
|
199
|
-
return processed;
|
|
200
|
-
}
|
|
201
10
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: Icon, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
202
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
11
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: Icon, isStandalone: true, selector: "cat-icon", ngImport: i0, template: "<ng-content></ng-content>\n", styles: [":host{display:inline-flex;align-items:center;justify-content:center;width:1em;height:1em;font-size:24px;overflow:hidden}:host :deep(svg),:host :deep(img){width:100%;height:100%;object-fit:contain}\n"] });
|
|
203
12
|
}
|
|
204
13
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: Icon, decorators: [{
|
|
205
14
|
type: Component,
|
|
206
|
-
args: [{ selector: 'cat-icon', imports: [], template: "
|
|
207
|
-
}]
|
|
208
|
-
type: Input
|
|
209
|
-
}], color: [{
|
|
210
|
-
type: Input
|
|
211
|
-
}], name: [{
|
|
212
|
-
type: Input
|
|
213
|
-
}], src: [{
|
|
214
|
-
type: Input
|
|
215
|
-
}] } });
|
|
15
|
+
args: [{ selector: 'cat-icon', imports: [], template: "<ng-content></ng-content>\n", styles: [":host{display:inline-flex;align-items:center;justify-content:center;width:1em;height:1em;font-size:24px;overflow:hidden}:host :deep(svg),:host :deep(img){width:100%;height:100%;object-fit:contain}\n"] }]
|
|
16
|
+
}] });
|
|
216
17
|
|
|
217
18
|
class Button {
|
|
218
19
|
variant = 'primary';
|
|
@@ -231,6 +32,9 @@ class Button {
|
|
|
231
32
|
const sizes = { sm: '16px', md: '20px', lg: '24px' };
|
|
232
33
|
return sizes[this.size];
|
|
233
34
|
}
|
|
35
|
+
isTemplateRef(content) {
|
|
36
|
+
return content instanceof TemplateRef;
|
|
37
|
+
}
|
|
234
38
|
get dataCustomClass() {
|
|
235
39
|
return this.customClass;
|
|
236
40
|
}
|
|
@@ -240,11 +44,11 @@ class Button {
|
|
|
240
44
|
}
|
|
241
45
|
}
|
|
242
46
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: Button, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
243
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: Button, isStandalone: true, selector: "cat-button", inputs: { variant: "variant", size: "size", disabled: "disabled", type: "type", iconLeft: "iconLeft", iconCenter: "iconCenter", iconRight: "iconRight", customClass: "customClass" }, outputs: { clicked: "clicked" }, host: { properties: { "attr.data-button-class": "this.dataCustomClass" } }, ngImport: i0, template: "<button [class]=\"buttonClasses\" [disabled]=\"disabled\" [type]=\"type\" (click)=\"handleClick($event)\">\n @if (iconLeft) {\n <cat-icon
|
|
47
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: Button, isStandalone: true, selector: "cat-button", inputs: { variant: "variant", size: "size", disabled: "disabled", type: "type", iconLeft: "iconLeft", iconCenter: "iconCenter", iconRight: "iconRight", customClass: "customClass" }, outputs: { clicked: "clicked" }, host: { properties: { "attr.data-button-class": "this.dataCustomClass" } }, ngImport: i0, template: "<button [class]=\"buttonClasses\" [disabled]=\"disabled\" [type]=\"type\" (click)=\"handleClick($event)\">\n @if (iconLeft) {\n <cat-icon class=\"icon-left\">\n @if (isTemplateRef(iconLeft)) {\n <ng-container [ngTemplateOutlet]=\"iconLeft\"></ng-container>\n } @else {\n <ng-container *ngComponentOutlet=\"iconLeft\"></ng-container>\n }\n </cat-icon>\n }\n\n <span class=\"button-content\">\n @if (iconCenter) {\n <cat-icon class=\"icon-center\">\n @if (isTemplateRef(iconCenter)) {\n <ng-container [ngTemplateOutlet]=\"iconCenter\"></ng-container>\n } @else {\n <ng-container *ngComponentOutlet=\"iconCenter\"></ng-container>\n }\n </cat-icon>\n }\n <ng-content></ng-content>\n </span>\n\n @if (iconRight) {\n <cat-icon class=\"icon-right\">\n @if (isTemplateRef(iconRight)) {\n <ng-container [ngTemplateOutlet]=\"iconRight\"></ng-container>\n } @else {\n <ng-container *ngComponentOutlet=\"iconRight\"></ng-container>\n }\n </cat-icon>\n }\n</button>\n", styles: [".cat-button.primary{background-color:var(--primary-color-0);color:#fff}.cat-button.primary:hover:not(:disabled){background-color:var(--primary-color-1)}.cat-button.primary:active:not(:disabled){background-color:var(--primary-color-2)}.cat-button.secondary{background-color:var(--neutral-color-0);color:var(--neutral-color-9)}.cat-button.secondary:hover:not(:disabled){background-color:var(--neutral-color-1)}.cat-button.secondary:active:not(:disabled){background-color:var(--neutral-color-2)}.cat-button.contrast{background-color:var(--neutral-color-9);color:var(--neutral-color-0)}.cat-button.contrast:hover:not(:disabled){background-color:var(--neutral-color-8)}.cat-button.contrast:active:not(:disabled){background-color:var(--neutral-color-2);color:var(--neutral-color-9)}.cat-button.ghost{background-color:transparent;color:var(--primary-color-0)}.cat-button.ghost:hover:not(:disabled){background-color:color-mix(in srgb,var(--primary-color-0) 10%,transparent)}.cat-button.ghost:active:not(:disabled){background-color:color-mix(in srgb,var(--primary-color-0) 30%,transparent)}.cat-button.outline{background-color:transparent;color:var(--primary-color-0);border:2px solid var(--primary-color-1)}.cat-button.outline:hover:not(:disabled){background-color:var(--primary-color-0);color:#fff}.cat-button.outline:active:not(:disabled){border:2px solid var(--primary-color-2);background-color:var(--primary-color-1)}.cat-button.success{background-color:var(--success-color-default);color:var(--neutral-color-0)}.cat-button.success:hover:not(:disabled){background-color:var(--success-color-hover)}.cat-button.success:active:not(:disabled){background-color:var(--success-color-active)}.cat-button.danger{background-color:var(--danger-color-default);color:var(--neutral-color-0)}.cat-button.danger:hover:not(:disabled){background-color:var(--danger-color-hover)}.cat-button.danger:active:not(:disabled){background-color:var(--danger-color-active)}.cat-button.warn{background-color:var(--warn-color-default);color:var(--neutral-color-0)}.cat-button.warn:hover:not(:disabled){background-color:var(--warn-color-hover)}.cat-button.warn:active:not(:disabled){background-color:var(--warn-color-active)}.cat-button.info{background-color:var(--info-color-default);color:var(--neutral-color-0)}.cat-button.info:hover:not(:disabled){background-color:var(--info-color-hover)}.cat-button.info:active:not(:disabled){background-color:var(--info-color-active)}.cat-button{display:inline-flex;align-items:center;gap:.5rem;padding:8px 16px;border:none;border-radius:18px;font-family:inherit;font-size:1rem;font-weight:500;cursor:pointer;transition:all .2s;white-space:nowrap;box-sizing:border-box}.cat-button:disabled{opacity:.5;cursor:not-allowed}.cat-button.sm{padding:.25rem .75rem;font-size:.875rem}.cat-button.md{padding:.5rem 1rem;font-size:1rem}.cat-button.lg{padding:.75rem 1.5rem;font-size:1.125rem}.cat-button .icon-left,.cat-button .icon-right,.cat-button .icon-center{display:inline-flex}.cat-button .icon-center{margin:auto}.cat-button .icon-right{margin-left:auto}.cat-button .button-content{display:inline-flex;align-items:center;width:100%}\n"], dependencies: [{ kind: "component", type: Icon, selector: "cat-icon" }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
|
|
244
48
|
}
|
|
245
49
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: Button, decorators: [{
|
|
246
50
|
type: Component,
|
|
247
|
-
args: [{ selector: 'cat-button', imports: [Icon], template: "<button [class]=\"buttonClasses\" [disabled]=\"disabled\" [type]=\"type\" (click)=\"handleClick($event)\">\n @if (iconLeft) {\n <cat-icon
|
|
51
|
+
args: [{ selector: 'cat-button', imports: [Icon, NgComponentOutlet, NgTemplateOutlet], template: "<button [class]=\"buttonClasses\" [disabled]=\"disabled\" [type]=\"type\" (click)=\"handleClick($event)\">\n @if (iconLeft) {\n <cat-icon class=\"icon-left\">\n @if (isTemplateRef(iconLeft)) {\n <ng-container [ngTemplateOutlet]=\"iconLeft\"></ng-container>\n } @else {\n <ng-container *ngComponentOutlet=\"iconLeft\"></ng-container>\n }\n </cat-icon>\n }\n\n <span class=\"button-content\">\n @if (iconCenter) {\n <cat-icon class=\"icon-center\">\n @if (isTemplateRef(iconCenter)) {\n <ng-container [ngTemplateOutlet]=\"iconCenter\"></ng-container>\n } @else {\n <ng-container *ngComponentOutlet=\"iconCenter\"></ng-container>\n }\n </cat-icon>\n }\n <ng-content></ng-content>\n </span>\n\n @if (iconRight) {\n <cat-icon class=\"icon-right\">\n @if (isTemplateRef(iconRight)) {\n <ng-container [ngTemplateOutlet]=\"iconRight\"></ng-container>\n } @else {\n <ng-container *ngComponentOutlet=\"iconRight\"></ng-container>\n }\n </cat-icon>\n }\n</button>\n", styles: [".cat-button.primary{background-color:var(--primary-color-0);color:#fff}.cat-button.primary:hover:not(:disabled){background-color:var(--primary-color-1)}.cat-button.primary:active:not(:disabled){background-color:var(--primary-color-2)}.cat-button.secondary{background-color:var(--neutral-color-0);color:var(--neutral-color-9)}.cat-button.secondary:hover:not(:disabled){background-color:var(--neutral-color-1)}.cat-button.secondary:active:not(:disabled){background-color:var(--neutral-color-2)}.cat-button.contrast{background-color:var(--neutral-color-9);color:var(--neutral-color-0)}.cat-button.contrast:hover:not(:disabled){background-color:var(--neutral-color-8)}.cat-button.contrast:active:not(:disabled){background-color:var(--neutral-color-2);color:var(--neutral-color-9)}.cat-button.ghost{background-color:transparent;color:var(--primary-color-0)}.cat-button.ghost:hover:not(:disabled){background-color:color-mix(in srgb,var(--primary-color-0) 10%,transparent)}.cat-button.ghost:active:not(:disabled){background-color:color-mix(in srgb,var(--primary-color-0) 30%,transparent)}.cat-button.outline{background-color:transparent;color:var(--primary-color-0);border:2px solid var(--primary-color-1)}.cat-button.outline:hover:not(:disabled){background-color:var(--primary-color-0);color:#fff}.cat-button.outline:active:not(:disabled){border:2px solid var(--primary-color-2);background-color:var(--primary-color-1)}.cat-button.success{background-color:var(--success-color-default);color:var(--neutral-color-0)}.cat-button.success:hover:not(:disabled){background-color:var(--success-color-hover)}.cat-button.success:active:not(:disabled){background-color:var(--success-color-active)}.cat-button.danger{background-color:var(--danger-color-default);color:var(--neutral-color-0)}.cat-button.danger:hover:not(:disabled){background-color:var(--danger-color-hover)}.cat-button.danger:active:not(:disabled){background-color:var(--danger-color-active)}.cat-button.warn{background-color:var(--warn-color-default);color:var(--neutral-color-0)}.cat-button.warn:hover:not(:disabled){background-color:var(--warn-color-hover)}.cat-button.warn:active:not(:disabled){background-color:var(--warn-color-active)}.cat-button.info{background-color:var(--info-color-default);color:var(--neutral-color-0)}.cat-button.info:hover:not(:disabled){background-color:var(--info-color-hover)}.cat-button.info:active:not(:disabled){background-color:var(--info-color-active)}.cat-button{display:inline-flex;align-items:center;gap:.5rem;padding:8px 16px;border:none;border-radius:18px;font-family:inherit;font-size:1rem;font-weight:500;cursor:pointer;transition:all .2s;white-space:nowrap;box-sizing:border-box}.cat-button:disabled{opacity:.5;cursor:not-allowed}.cat-button.sm{padding:.25rem .75rem;font-size:.875rem}.cat-button.md{padding:.5rem 1rem;font-size:1rem}.cat-button.lg{padding:.75rem 1.5rem;font-size:1.125rem}.cat-button .icon-left,.cat-button .icon-right,.cat-button .icon-center{display:inline-flex}.cat-button .icon-center{margin:auto}.cat-button .icon-right{margin-left:auto}.cat-button .button-content{display:inline-flex;align-items:center;width:100%}\n"] }]
|
|
248
52
|
}], propDecorators: { variant: [{
|
|
249
53
|
type: Input
|
|
250
54
|
}], size: [{
|
|
@@ -365,7 +169,6 @@ class Accordion {
|
|
|
365
169
|
forceStatus(newStatus) {
|
|
366
170
|
this.status = newStatus;
|
|
367
171
|
}
|
|
368
|
-
;
|
|
369
172
|
get dataCustomClass() {
|
|
370
173
|
return this.customClass;
|
|
371
174
|
}
|
|
@@ -373,11 +176,11 @@ class Accordion {
|
|
|
373
176
|
return `${this.variant} ${this.customClass} ${this.scrolleable ? 'scrolleable' : undefined}`;
|
|
374
177
|
}
|
|
375
178
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: Accordion, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
376
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: Accordion, isStandalone: true, selector: "cat-accordion", inputs: { accordionId: "accordionId", status: "status", label: "label", disabled: "disabled", customClass: "customClass", buttonVariant: "buttonVariant", buttonSize: "buttonSize", iconLeft: "iconLeft", iconCenter: "iconCenter", iconRight: "iconRight", scrolleable: "scrolleable", variant: "variant" }, outputs: { updateAccordionGroupStatusOutput: "updateAccordionGroupStatusOutput" }, host: { properties: { "attr.data-accordion-class": "this.dataCustomClass" } }, viewQueries: [{ propertyName: "buttonRef", first: true, predicate: ["buttonRef"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<section class=\"accordion\">\n
|
|
179
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: Accordion, isStandalone: true, selector: "cat-accordion", inputs: { accordionId: "accordionId", status: "status", label: "label", disabled: "disabled", customClass: "customClass", buttonVariant: "buttonVariant", buttonSize: "buttonSize", iconLeft: "iconLeft", iconCenter: "iconCenter", iconRight: "iconRight", scrolleable: "scrolleable", variant: "variant" }, outputs: { updateAccordionGroupStatusOutput: "updateAccordionGroupStatusOutput" }, host: { properties: { "attr.data-accordion-class": "this.dataCustomClass" } }, viewQueries: [{ propertyName: "buttonRef", first: true, predicate: ["buttonRef"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<ng-template #collapsedIcon>\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"M12 5v14M5 12h14\"></path>\n </svg>\n</ng-template>\n<ng-template #expandedIcon>\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"M5 12h14\"></path>\n </svg>\n</ng-template>\n\n<section class=\"accordion\">\n <div>\n <cat-button\n [iconLeft]=\"\n iconLeft === true ? (status ? expandedIcon : collapsedIcon) : iconLeft || undefined\n \"\n [iconCenter]=\"\n iconCenter === true ? (status ? expandedIcon : collapsedIcon) : iconCenter || undefined\n \"\n [iconRight]=\"\n iconRight === true ? (status ? expandedIcon : collapsedIcon) : iconRight || undefined\n \"\n (clicked)=\"updateAccordionGroupStatus()\"\n [variant]=\"buttonVariant\"\n [size]=\"buttonSize\"\n customClass=\"accordion-button\"\n [disabled]=\"disabled\"\n >\n {{ label }}\n </cat-button>\n </div>\n <div\n [class]=\"panelClasses\"\n [ngClass]=\"status ? 'accordion-panel-active' : 'accordion-panel-unactive'\"\n >\n <ng-content *ngIf=\"status\"></ng-content>\n </div>\n</section>\n", styles: [":host{display:inline-block;max-width:100%}.accordion{margin:0;padding:0;width:100%;box-sizing:border-box;border-radius:8px}.accordion-panel-active{box-sizing:border-box;padding:.5em;min-height:5em;background-color:var(--neutral-color-0);width:100%;transition:.25s;border-radius:18px}.accordion-panel-unactive{display:none;transition:.15s}cat-button[data-button-class=accordion-button]{width:100%;display:block}cat-button[data-button-class=accordion-button] ::ng-deep button{width:100%;justify-content:space-between}.scrolleable{height:7em;overflow-y:auto}.scrolleable::-webkit-scrollbar{width:8px;height:8px}.scrolleable::-webkit-scrollbar-track{background:transparent}.scrolleable::-webkit-scrollbar-thumb{background:#888;border-radius:4px}.scrolleable::-webkit-scrollbar-thumb:hover{background:#555}.surface{background-color:var(--element-color-4)}.elevated{background-color:var(--neutral-color-0)}.outlined{background-color:var(--element-color-3);border:1px solid var(--neutral-color-6)}\n"], dependencies: [{ kind: "component", type: Button, selector: "cat-button", inputs: ["variant", "size", "disabled", "type", "iconLeft", "iconCenter", "iconRight", "customClass"], outputs: ["clicked"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
377
180
|
}
|
|
378
181
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: Accordion, decorators: [{
|
|
379
182
|
type: Component,
|
|
380
|
-
args: [{ selector: 'cat-accordion', imports: [Button, NgClass, NgIf], template: "<section class=\"accordion\">\n
|
|
183
|
+
args: [{ selector: 'cat-accordion', imports: [Button, NgClass, NgIf], template: "<ng-template #collapsedIcon>\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"M12 5v14M5 12h14\"></path>\n </svg>\n</ng-template>\n<ng-template #expandedIcon>\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"M5 12h14\"></path>\n </svg>\n</ng-template>\n\n<section class=\"accordion\">\n <div>\n <cat-button\n [iconLeft]=\"\n iconLeft === true ? (status ? expandedIcon : collapsedIcon) : iconLeft || undefined\n \"\n [iconCenter]=\"\n iconCenter === true ? (status ? expandedIcon : collapsedIcon) : iconCenter || undefined\n \"\n [iconRight]=\"\n iconRight === true ? (status ? expandedIcon : collapsedIcon) : iconRight || undefined\n \"\n (clicked)=\"updateAccordionGroupStatus()\"\n [variant]=\"buttonVariant\"\n [size]=\"buttonSize\"\n customClass=\"accordion-button\"\n [disabled]=\"disabled\"\n >\n {{ label }}\n </cat-button>\n </div>\n <div\n [class]=\"panelClasses\"\n [ngClass]=\"status ? 'accordion-panel-active' : 'accordion-panel-unactive'\"\n >\n <ng-content *ngIf=\"status\"></ng-content>\n </div>\n</section>\n", styles: [":host{display:inline-block;max-width:100%}.accordion{margin:0;padding:0;width:100%;box-sizing:border-box;border-radius:8px}.accordion-panel-active{box-sizing:border-box;padding:.5em;min-height:5em;background-color:var(--neutral-color-0);width:100%;transition:.25s;border-radius:18px}.accordion-panel-unactive{display:none;transition:.15s}cat-button[data-button-class=accordion-button]{width:100%;display:block}cat-button[data-button-class=accordion-button] ::ng-deep button{width:100%;justify-content:space-between}.scrolleable{height:7em;overflow-y:auto}.scrolleable::-webkit-scrollbar{width:8px;height:8px}.scrolleable::-webkit-scrollbar-track{background:transparent}.scrolleable::-webkit-scrollbar-thumb{background:#888;border-radius:4px}.scrolleable::-webkit-scrollbar-thumb:hover{background:#555}.surface{background-color:var(--element-color-4)}.elevated{background-color:var(--neutral-color-0)}.outlined{background-color:var(--element-color-3);border:1px solid var(--neutral-color-6)}\n"] }]
|
|
381
184
|
}], propDecorators: { accordionId: [{
|
|
382
185
|
type: Input
|
|
383
186
|
}], status: [{
|
|
@@ -578,6 +381,9 @@ class ColorInput {
|
|
|
578
381
|
size = '2em';
|
|
579
382
|
onChange = (value) => { };
|
|
580
383
|
onTouched = () => { };
|
|
384
|
+
isTemplateRef(content) {
|
|
385
|
+
return content instanceof TemplateRef;
|
|
386
|
+
}
|
|
581
387
|
onInput(event) {
|
|
582
388
|
const newValue = event.target.value;
|
|
583
389
|
this.value = newValue;
|
|
@@ -594,19 +400,23 @@ class ColorInput {
|
|
|
594
400
|
this.onTouched = fn;
|
|
595
401
|
}
|
|
596
402
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ColorInput, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
597
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ColorInput, isStandalone: true, selector: "cat-color-input", inputs: { icon: "icon", size: "size" }, providers: [
|
|
403
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ColorInput, isStandalone: true, selector: "cat-color-input", inputs: { icon: "icon", size: "size" }, providers: [
|
|
404
|
+
{
|
|
598
405
|
provide: NG_VALUE_ACCESSOR,
|
|
599
406
|
useExisting: forwardRef(() => ColorInput),
|
|
600
|
-
multi: true
|
|
601
|
-
}
|
|
407
|
+
multi: true,
|
|
408
|
+
},
|
|
409
|
+
], ngImport: i0, template: "<style>\n div {\n position: relative;\n aspect-ratio: 1/1;\n }\n\n div:hover {\n cursor: grab;\n }\n\n input {\n width: 100%;\n aspect-ratio: 1/1;\n top: 0;\n left: 0;\n }\n\n cat-icon {\n position: absolute;\n top: 0;\n left: 0;\n pointer-events: none;\n }\n</style>\n<!-- input-color.html -->\n<div [style.height]=\"size\">\n <input type=\"color\" [style]=\"icon ? 'opacity: 0;' : 'opacity: 100%;'\" [value]=\"value\" (input)=\"onInput($event)\"\n (blur)=\"onTouched()\" />\n @if (icon) {\n <cat-icon style=\"width: 100%; height: 100%;\">\n @if (icon === true) {\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <g id=\"SVGRepo_iconCarrier\">\n <path d=\"M10.5 10.5c.002 2.762-2.237 5-5 5s-5.002-2.238-5-5c-.002-2.76 2.237-5 5-5s5.002 2.24 5 5z\"\n color=\"#000000\" fill=\"#ff15a1\" stroke=\"#373737\" stroke-width=\".49999682600000006\"></path>\n <path\n d=\"M8 1.401a4.998 4.998 0 0 0-2.488 9.334c-.004-.078-.012-.155-.012-.234a4.998 4.998 0 0 1 7.488-4.334A4.994 4.994 0 0 0 8 1.4z\"\n fill=\"#1583ff\"></path>\n <path\n d=\"M10.5 5.5a4.998 4.998 0 0 0-5 5c0 .08.008.157.012.235A4.998 4.998 0 0 0 13 6.401c0-.079-.008-.156-.012-.234A4.975 4.975 0 0 0 10.5 5.5z\"\n fill=\"#00cf2d\"></path>\n <path\n d=\"M12.988 6.167c.004.078.012.155.012.234a4.998 4.998 0 0 1-7.489 4.334 4.994 4.994 0 0 0 4.989 4.766 4.998 4.998 0 0 0 2.488-9.334z\"\n fill=\"#f8ff15\"></path>\n <path\n d=\"M5.512 10.735a4.996 4.996 0 0 0 2.486 4.093 4.987 4.987 0 0 0 2.49-4.091A4.978 4.978 0 0 1 8 11.4a4.975 4.975 0 0 1-2.488-.666z\"\n fill=\"#ef0000\"></path>\n <path\n d=\"M7.998 6.173A4.991 4.991 0 0 0 5.5 10.5c0 .079.008.156.012.234a4.978 4.978 0 0 0 4.977.002c.003-.079.011-.157.011-.236a4.99 4.99 0 0 0-2.502-4.328z\"\n fill=\"#383027\"></path>\n <path\n d=\"M5.5 5.5c-.91 0-1.76.247-2.494.67a4.99 4.99 0 0 0 2.506 4.564c-.004-.077-.012-.154-.012-.233a4.991 4.991 0 0 1 2.498-4.328A4.975 4.975 0 0 0 5.5 5.5z\"\n fill=\"#5100cc\"></path>\n <path\n d=\"M8 1.401a4.998 4.998 0 0 0-4.994 4.77 4.998 4.998 0 1 0 4.992 8.658 4.998 4.998 0 1 0 4.99-8.662A4.994 4.994 0 0 0 8 1.4z\"\n fill=\"none\" stroke=\"#373737\" stroke-width=\".9999936520000001\"></path>\n </g>\n </svg>\n } @else if (isTemplateRef(icon)) {\n <ng-container [ngTemplateOutlet]=\"icon\"></ng-container>\n } @else {\n <ng-container *ngComponentOutlet=\"icon\"></ng-container>\n }\n </cat-icon>\n }\n</div>", styles: ["", "div{position:relative;aspect-ratio:1/1}div:hover{cursor:grab}input{width:100%;aspect-ratio:1/1;top:0;left:0}cat-icon{position:absolute;top:0;left:0;pointer-events:none}\n"], dependencies: [{ kind: "component", type: Icon, selector: "cat-icon" }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
|
|
602
410
|
}
|
|
603
411
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ColorInput, decorators: [{
|
|
604
412
|
type: Component,
|
|
605
|
-
args: [{ selector: 'cat-color-input', imports: [Icon], providers: [
|
|
413
|
+
args: [{ selector: 'cat-color-input', imports: [Icon, NgComponentOutlet, NgTemplateOutlet], providers: [
|
|
414
|
+
{
|
|
606
415
|
provide: NG_VALUE_ACCESSOR,
|
|
607
416
|
useExisting: forwardRef(() => ColorInput),
|
|
608
|
-
multi: true
|
|
609
|
-
}
|
|
417
|
+
multi: true,
|
|
418
|
+
},
|
|
419
|
+
], template: "<style>\n div {\n position: relative;\n aspect-ratio: 1/1;\n }\n\n div:hover {\n cursor: grab;\n }\n\n input {\n width: 100%;\n aspect-ratio: 1/1;\n top: 0;\n left: 0;\n }\n\n cat-icon {\n position: absolute;\n top: 0;\n left: 0;\n pointer-events: none;\n }\n</style>\n<!-- input-color.html -->\n<div [style.height]=\"size\">\n <input type=\"color\" [style]=\"icon ? 'opacity: 0;' : 'opacity: 100%;'\" [value]=\"value\" (input)=\"onInput($event)\"\n (blur)=\"onTouched()\" />\n @if (icon) {\n <cat-icon style=\"width: 100%; height: 100%;\">\n @if (icon === true) {\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <g id=\"SVGRepo_iconCarrier\">\n <path d=\"M10.5 10.5c.002 2.762-2.237 5-5 5s-5.002-2.238-5-5c-.002-2.76 2.237-5 5-5s5.002 2.24 5 5z\"\n color=\"#000000\" fill=\"#ff15a1\" stroke=\"#373737\" stroke-width=\".49999682600000006\"></path>\n <path\n d=\"M8 1.401a4.998 4.998 0 0 0-2.488 9.334c-.004-.078-.012-.155-.012-.234a4.998 4.998 0 0 1 7.488-4.334A4.994 4.994 0 0 0 8 1.4z\"\n fill=\"#1583ff\"></path>\n <path\n d=\"M10.5 5.5a4.998 4.998 0 0 0-5 5c0 .08.008.157.012.235A4.998 4.998 0 0 0 13 6.401c0-.079-.008-.156-.012-.234A4.975 4.975 0 0 0 10.5 5.5z\"\n fill=\"#00cf2d\"></path>\n <path\n d=\"M12.988 6.167c.004.078.012.155.012.234a4.998 4.998 0 0 1-7.489 4.334 4.994 4.994 0 0 0 4.989 4.766 4.998 4.998 0 0 0 2.488-9.334z\"\n fill=\"#f8ff15\"></path>\n <path\n d=\"M5.512 10.735a4.996 4.996 0 0 0 2.486 4.093 4.987 4.987 0 0 0 2.49-4.091A4.978 4.978 0 0 1 8 11.4a4.975 4.975 0 0 1-2.488-.666z\"\n fill=\"#ef0000\"></path>\n <path\n d=\"M7.998 6.173A4.991 4.991 0 0 0 5.5 10.5c0 .079.008.156.012.234a4.978 4.978 0 0 0 4.977.002c.003-.079.011-.157.011-.236a4.99 4.99 0 0 0-2.502-4.328z\"\n fill=\"#383027\"></path>\n <path\n d=\"M5.5 5.5c-.91 0-1.76.247-2.494.67a4.99 4.99 0 0 0 2.506 4.564c-.004-.077-.012-.154-.012-.233a4.991 4.991 0 0 1 2.498-4.328A4.975 4.975 0 0 0 5.5 5.5z\"\n fill=\"#5100cc\"></path>\n <path\n d=\"M8 1.401a4.998 4.998 0 0 0-4.994 4.77 4.998 4.998 0 1 0 4.992 8.658 4.998 4.998 0 1 0 4.99-8.662A4.994 4.994 0 0 0 8 1.4z\"\n fill=\"none\" stroke=\"#373737\" stroke-width=\".9999936520000001\"></path>\n </g>\n </svg>\n } @else if (isTemplateRef(icon)) {\n <ng-container [ngTemplateOutlet]=\"icon\"></ng-container>\n } @else {\n <ng-container *ngComponentOutlet=\"icon\"></ng-container>\n }\n </cat-icon>\n }\n</div>", styles: ["div{position:relative;aspect-ratio:1/1}div:hover{cursor:grab}input{width:100%;aspect-ratio:1/1;top:0;left:0}cat-icon{position:absolute;top:0;left:0;pointer-events:none}\n"] }]
|
|
610
420
|
}], propDecorators: { icon: [{
|
|
611
421
|
type: Input
|
|
612
422
|
}], size: [{
|
|
@@ -774,7 +584,8 @@ class Dialog {
|
|
|
774
584
|
// Referencia al overlay creado
|
|
775
585
|
overlayRef;
|
|
776
586
|
variant = 'surface';
|
|
777
|
-
|
|
587
|
+
width = '300px';
|
|
588
|
+
height = '200px';
|
|
778
589
|
customClass = '';
|
|
779
590
|
closs = new EventEmitter();
|
|
780
591
|
// Referencia al template que contiene el ng-content
|
|
@@ -828,14 +639,16 @@ class Dialog {
|
|
|
828
639
|
this.closeDialog();
|
|
829
640
|
}
|
|
830
641
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: Dialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
831
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: Dialog, isStandalone: true, selector: "cat-dialog", inputs: { variant: "variant",
|
|
642
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: Dialog, isStandalone: true, selector: "cat-dialog", inputs: { variant: "variant", width: "width", height: "height", customClass: "customClass" }, outputs: { closs: "closs" }, viewQueries: [{ propertyName: "dialogTemplate", first: true, predicate: ["dialogTemplate"], descendants: true, static: true }], ngImport: i0, template: "<!-- Template que se renderiza dentro del overlay del CDK -->\n<ng-template #dialogTemplate>\n <section [style]=\"`height: ${height}; width: ${width};`\" CDrag [class]=\"dialogClasses\">\n <ng-content></ng-content>\n </section>\n</ng-template>\n", styles: ["section{position:relative;border-radius:18px;overflow:auto;padding:.75rem 1.5rem;box-sizing:border-box;min-width:7em;min-height:7em;cursor:grab;-webkit-user-select:none;user-select:none}.surface{background-color:var(--element-color-4)}.elevated{background-color:var(--neutral-color-0)}.outlined{background-color:var(--element-color-3);border:2px solid var(--neutral-color-9)}\n"], dependencies: [{ kind: "directive", type: Drag, selector: "[CDrag]" }] });
|
|
832
643
|
}
|
|
833
644
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: Dialog, decorators: [{
|
|
834
645
|
type: Component,
|
|
835
|
-
args: [{ selector: 'cat-dialog', imports: [Drag], template: "<!-- Template que se renderiza dentro del overlay del CDK -->\n<ng-template #dialogTemplate>\n <section
|
|
646
|
+
args: [{ selector: 'cat-dialog', imports: [Drag], template: "<!-- Template que se renderiza dentro del overlay del CDK -->\n<ng-template #dialogTemplate>\n <section [style]=\"`height: ${height}; width: ${width};`\" CDrag [class]=\"dialogClasses\">\n <ng-content></ng-content>\n </section>\n</ng-template>\n", styles: ["section{position:relative;border-radius:18px;overflow:auto;padding:.75rem 1.5rem;box-sizing:border-box;min-width:7em;min-height:7em;cursor:grab;-webkit-user-select:none;user-select:none}.surface{background-color:var(--element-color-4)}.elevated{background-color:var(--neutral-color-0)}.outlined{background-color:var(--element-color-3);border:2px solid var(--neutral-color-9)}\n"] }]
|
|
836
647
|
}], propDecorators: { variant: [{
|
|
837
648
|
type: Input
|
|
838
|
-
}],
|
|
649
|
+
}], width: [{
|
|
650
|
+
type: Input
|
|
651
|
+
}], height: [{
|
|
839
652
|
type: Input
|
|
840
653
|
}], customClass: [{
|
|
841
654
|
type: Input
|
|
@@ -924,11 +737,11 @@ class Drawer {
|
|
|
924
737
|
this.closeDrawer();
|
|
925
738
|
}
|
|
926
739
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: Drawer, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
927
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: Drawer, isStandalone: true, selector: "cat-drawer", inputs: { side: "side", variant: "variant", customClass: "customClass" }, outputs: { closs: "closs" }, viewQueries: [{ propertyName: "drawerTemplate", first: true, predicate: ["drawerTemplate"], descendants: true, static: true }], ngImport: i0, template: "<!-- Template que se renderiza dentro del overlay del CDK -->\n<ng-template #drawerTemplate>\n <section [class]=\"drawerClasses\">\n
|
|
740
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: Drawer, isStandalone: true, selector: "cat-drawer", inputs: { side: "side", variant: "variant", customClass: "customClass" }, outputs: { closs: "closs" }, viewQueries: [{ propertyName: "drawerTemplate", first: true, predicate: ["drawerTemplate"], descendants: true, static: true }], ngImport: i0, template: "<!-- Template que se renderiza dentro del overlay del CDK -->\n<ng-template #drawerTemplate>\n <ng-template #closeIcon>\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m6 6 12 12M18 6 6 18\"></path>\n </svg>\n </ng-template>\n <section [class]=\"drawerClasses\">\n <cat-button\n [iconCenter]=\"closeIcon\"\n variant=\"contrast\"\n class=\"close-button\"\n (clicked)=\"closeDrawer()\"\n ></cat-button>\n <ng-content></ng-content>\n </section>\n</ng-template>\n", styles: ["section{position:relative;overflow:auto;box-sizing:border-box;padding:.25rem .75rem;transition:.25s;-webkit-user-select:none;user-select:none}.surface{background-color:var(--element-color-4)}.elevated{background-color:var(--neutral-color-0)}.outlined{background-color:var(--element-color-3);border:2px solid var(--neutral-color-9)}.close-button{position:absolute}.left,.right{width:30vw;height:100vh}.left .close-button,.right .close-button{right:.25rem}.top,.bottom{width:100vw;min-height:10em}.top .close-button,.bottom .close-button{right:.25rem}@media screen and (max-width: 1024px){.left,.right{width:50vw}.top,.bottom{height:50vh}}@media screen and (orientation: portrait) and (max-width: 600px){.left,.right{width:80vw}.top,.bottom{height:70vh}}\n"], dependencies: [{ kind: "component", type: Button, selector: "cat-button", inputs: ["variant", "size", "disabled", "type", "iconLeft", "iconCenter", "iconRight", "customClass"], outputs: ["clicked"] }] });
|
|
928
741
|
}
|
|
929
742
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: Drawer, decorators: [{
|
|
930
743
|
type: Component,
|
|
931
|
-
args: [{ selector: 'cat-drawer', imports: [Button], template: "<!-- Template que se renderiza dentro del overlay del CDK -->\n<ng-template #drawerTemplate>\n <section [class]=\"drawerClasses\">\n
|
|
744
|
+
args: [{ selector: 'cat-drawer', imports: [Button], template: "<!-- Template que se renderiza dentro del overlay del CDK -->\n<ng-template #drawerTemplate>\n <ng-template #closeIcon>\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m6 6 12 12M18 6 6 18\"></path>\n </svg>\n </ng-template>\n <section [class]=\"drawerClasses\">\n <cat-button\n [iconCenter]=\"closeIcon\"\n variant=\"contrast\"\n class=\"close-button\"\n (clicked)=\"closeDrawer()\"\n ></cat-button>\n <ng-content></ng-content>\n </section>\n</ng-template>\n", styles: ["section{position:relative;overflow:auto;box-sizing:border-box;padding:.25rem .75rem;transition:.25s;-webkit-user-select:none;user-select:none}.surface{background-color:var(--element-color-4)}.elevated{background-color:var(--neutral-color-0)}.outlined{background-color:var(--element-color-3);border:2px solid var(--neutral-color-9)}.close-button{position:absolute}.left,.right{width:30vw;height:100vh}.left .close-button,.right .close-button{right:.25rem}.top,.bottom{width:100vw;min-height:10em}.top .close-button,.bottom .close-button{right:.25rem}@media screen and (max-width: 1024px){.left,.right{width:50vw}.top,.bottom{height:50vh}}@media screen and (orientation: portrait) and (max-width: 600px){.left,.right{width:80vw}.top,.bottom{height:70vh}}\n"] }]
|
|
932
745
|
}], propDecorators: { side: [{
|
|
933
746
|
type: Input
|
|
934
747
|
}], variant: [{
|
|
@@ -942,202 +755,133 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
942
755
|
args: ['drawerTemplate', { static: true }]
|
|
943
756
|
}] } });
|
|
944
757
|
|
|
945
|
-
class
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
}
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
ngAfterViewInit() {
|
|
966
|
-
if (!isPlatformBrowser(this.platformId))
|
|
967
|
-
return;
|
|
968
|
-
setTimeout(() => {
|
|
969
|
-
this.checkOverflow();
|
|
970
|
-
this.setupObservers();
|
|
971
|
-
}, 0);
|
|
972
|
-
}
|
|
973
|
-
ngOnDestroy() {
|
|
974
|
-
this.resizeObserver?.disconnect();
|
|
975
|
-
this.mutationObserver?.disconnect();
|
|
976
|
-
if (isPlatformBrowser(this.platformId)) {
|
|
977
|
-
document.removeEventListener('click', this.handleOutsideClick);
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
setupObservers() {
|
|
981
|
-
if (!isPlatformBrowser(this.platformId))
|
|
982
|
-
return;
|
|
983
|
-
this.resizeObserver = new ResizeObserver(() => {
|
|
984
|
-
this.checkOverflow();
|
|
758
|
+
class MenuDropdown {
|
|
759
|
+
items = [];
|
|
760
|
+
panelContainer;
|
|
761
|
+
activeIndex = 0;
|
|
762
|
+
get isSingle() {
|
|
763
|
+
return this.items.length === 1;
|
|
764
|
+
}
|
|
765
|
+
isTemplateRef(value) {
|
|
766
|
+
return value instanceof TemplateRef;
|
|
767
|
+
}
|
|
768
|
+
setActive(index) {
|
|
769
|
+
// Oculta el panel activo actual
|
|
770
|
+
this.items[this.activeIndex]?.element.style.setProperty('display', 'none');
|
|
771
|
+
this.activeIndex = index;
|
|
772
|
+
// Muestra el nuevo panel activo
|
|
773
|
+
this.items[this.activeIndex]?.element.style.removeProperty('display');
|
|
774
|
+
}
|
|
775
|
+
showActivePanel() {
|
|
776
|
+
this.items.forEach((item, i) => {
|
|
777
|
+
item.element.style.setProperty('display', i === this.activeIndex ? '' : 'none');
|
|
985
778
|
});
|
|
986
|
-
this.resizeObserver.observe(this.menuContent.nativeElement);
|
|
987
|
-
document.addEventListener('click', this.handleOutsideClick);
|
|
988
779
|
}
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
//
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
const firstRowItems = [];
|
|
1036
|
-
const overflowItems = [];
|
|
1037
|
-
menuItems.forEach(item => {
|
|
1038
|
-
const itemTop = item.getBoundingClientRect().top;
|
|
1039
|
-
// Usa tolerancia de 1px para manejar diferencias de redondeo
|
|
1040
|
-
if (Math.abs(itemTop - firstItemTop) <= 1) {
|
|
1041
|
-
firstRowItems.push(item);
|
|
1042
|
-
}
|
|
1043
|
-
else {
|
|
1044
|
-
overflowItems.push(item);
|
|
1045
|
-
}
|
|
1046
|
-
});
|
|
1047
|
-
// Si hay elementos en overflow, muestra el botón More y oculta los elementos overflow
|
|
1048
|
-
const needsMoreButton = overflowItems.length > 0;
|
|
1049
|
-
this.showMoreButton.set(needsMoreButton);
|
|
1050
|
-
// Oculta elementos que están en la segunda fila o más
|
|
1051
|
-
overflowItems.forEach(item => {
|
|
1052
|
-
item.style.display = 'none';
|
|
1053
|
-
});
|
|
1054
|
-
// Mantiene visibles solo los elementos de la primera fila
|
|
1055
|
-
firstRowItems.forEach(item => {
|
|
1056
|
-
item.style.display = '';
|
|
1057
|
-
});
|
|
1058
|
-
if (needsMoreButton) {
|
|
1059
|
-
this.overflowItems.set(overflowItems);
|
|
1060
|
-
}
|
|
1061
|
-
else {
|
|
1062
|
-
this.overflowItems.set([]);
|
|
780
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MenuDropdown, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
781
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: MenuDropdown, isStandalone: true, selector: "cat-menu-dropdown", inputs: { items: "items" }, viewQueries: [{ propertyName: "panelContainer", first: true, predicate: ["panelContainer"], descendants: true, static: true }], ngImport: i0, template: "@if (!isSingle) {\n <!-- Tabs: solo cuando hay m\u00FAltiples paneles -->\n <div class=\"dropdown-tabs\">\n @for (item of items; track $index) {\n @if (isTemplateRef(item.label)) {\n <cat-button\n variant=\"secondary\"\n [iconCenter]=\"item.label\"\n [customClass]=\"activeIndex === $index ? 'tab-active' : ''\"\n (clicked)=\"setActive($index)\"\n ></cat-button>\n } @else {\n <cat-button\n variant=\"secondary\"\n [customClass]=\"activeIndex === $index ? 'tab-active' : ''\"\n (clicked)=\"setActive($index)\"\n >{{ item.label }}</cat-button>\n }\n }\n </div>\n}\n\n<!-- Contenedor donde el Menu mueve los nodos DOM de cat-menu-panel -->\n<div class=\"dropdown-content\" #panelContainer></div>\n", styles: [":host{display:block;background-color:rgb(var(--element-color-4) / .95);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border-radius:24px;border:1px var(--neutral-color-7) solid;padding:1rem;min-width:200px;box-shadow:0 8px 24px #00000026;animation:dropdownSlide .2s ease-out}@keyframes dropdownSlide{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.dropdown-tabs{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:.75rem;padding-bottom:.75rem;border-bottom:1px solid var(--neutral-color-7)}.dropdown-tabs ::ng-deep cat-button.tab-active button{background-color:var(--neutral-color-7)}.dropdown-content{display:flex;flex-direction:column;gap:.5rem}.dropdown-content ::ng-deep>cat-button,.dropdown-content ::ng-deep>button{width:100%}\n"], dependencies: [{ kind: "component", type: Button, selector: "cat-button", inputs: ["variant", "size", "disabled", "type", "iconLeft", "iconCenter", "iconRight", "customClass"], outputs: ["clicked"] }] });
|
|
782
|
+
}
|
|
783
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MenuDropdown, decorators: [{
|
|
784
|
+
type: Component,
|
|
785
|
+
args: [{ selector: 'cat-menu-dropdown', imports: [NgTemplateOutlet, Button], template: "@if (!isSingle) {\n <!-- Tabs: solo cuando hay m\u00FAltiples paneles -->\n <div class=\"dropdown-tabs\">\n @for (item of items; track $index) {\n @if (isTemplateRef(item.label)) {\n <cat-button\n variant=\"secondary\"\n [iconCenter]=\"item.label\"\n [customClass]=\"activeIndex === $index ? 'tab-active' : ''\"\n (clicked)=\"setActive($index)\"\n ></cat-button>\n } @else {\n <cat-button\n variant=\"secondary\"\n [customClass]=\"activeIndex === $index ? 'tab-active' : ''\"\n (clicked)=\"setActive($index)\"\n >{{ item.label }}</cat-button>\n }\n }\n </div>\n}\n\n<!-- Contenedor donde el Menu mueve los nodos DOM de cat-menu-panel -->\n<div class=\"dropdown-content\" #panelContainer></div>\n", styles: [":host{display:block;background-color:rgb(var(--element-color-4) / .95);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border-radius:24px;border:1px var(--neutral-color-7) solid;padding:1rem;min-width:200px;box-shadow:0 8px 24px #00000026;animation:dropdownSlide .2s ease-out}@keyframes dropdownSlide{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.dropdown-tabs{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:.75rem;padding-bottom:.75rem;border-bottom:1px solid var(--neutral-color-7)}.dropdown-tabs ::ng-deep cat-button.tab-active button{background-color:var(--neutral-color-7)}.dropdown-content{display:flex;flex-direction:column;gap:.5rem}.dropdown-content ::ng-deep>cat-button,.dropdown-content ::ng-deep>button{width:100%}\n"] }]
|
|
786
|
+
}], propDecorators: { items: [{
|
|
787
|
+
type: Input
|
|
788
|
+
}], panelContainer: [{
|
|
789
|
+
type: ViewChild,
|
|
790
|
+
args: ['panelContainer', { static: true }]
|
|
791
|
+
}] } });
|
|
792
|
+
|
|
793
|
+
class MenuPanel {
|
|
794
|
+
elementRef;
|
|
795
|
+
label;
|
|
796
|
+
constructor(elementRef) {
|
|
797
|
+
this.elementRef = elementRef;
|
|
798
|
+
}
|
|
799
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MenuPanel, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
800
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: MenuPanel, isStandalone: true, selector: "cat-menu-panel", inputs: { label: "label" }, ngImport: i0, template: "<ng-content></ng-content>\n" });
|
|
801
|
+
}
|
|
802
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MenuPanel, decorators: [{
|
|
803
|
+
type: Component,
|
|
804
|
+
args: [{ selector: 'cat-menu-panel', template: "<ng-content></ng-content>\n" }]
|
|
805
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { label: [{
|
|
806
|
+
type: Input
|
|
807
|
+
}] } });
|
|
808
|
+
|
|
809
|
+
class Menu {
|
|
810
|
+
panels;
|
|
811
|
+
panelsHost;
|
|
812
|
+
dropdownRef;
|
|
813
|
+
cdr = inject(ChangeDetectorRef);
|
|
814
|
+
// Controla si los cat-menu-panel están colapsados hacia el dropdown
|
|
815
|
+
isDropdownActive = false;
|
|
816
|
+
// Controla si el panel del dropdown está visible
|
|
817
|
+
isPanelOpen = false;
|
|
818
|
+
// Flag para ejecutar el move de paneles en el próximo AfterViewChecked
|
|
819
|
+
pendingPanelMove = false;
|
|
820
|
+
ngAfterContentInit() { }
|
|
821
|
+
ngAfterViewChecked() {
|
|
822
|
+
// Ejecuta el move cuando el dropdownRef ya está disponible en el DOM
|
|
823
|
+
if (this.pendingPanelMove && this.dropdownRef) {
|
|
824
|
+
this.pendingPanelMove = false;
|
|
825
|
+
this.executePanelMove();
|
|
1063
826
|
}
|
|
1064
827
|
}
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
const dropdown = menuWrapper.querySelector('.dropdown');
|
|
1071
|
-
if (!dropdown) {
|
|
1072
|
-
return;
|
|
1073
|
-
}
|
|
1074
|
-
const dropdownContent = dropdown.querySelector('.dropdown-content');
|
|
1075
|
-
if (!dropdownContent) {
|
|
1076
|
-
return;
|
|
828
|
+
// Llamado por el consumidor via referencia de template
|
|
829
|
+
toggleContent() {
|
|
830
|
+
this.isDropdownActive = !this.isDropdownActive;
|
|
831
|
+
if (!this.isDropdownActive) {
|
|
832
|
+
this.restorePanels();
|
|
1077
833
|
}
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
834
|
+
this.cdr.markForCheck();
|
|
835
|
+
}
|
|
836
|
+
// Llamado por el botón chevron
|
|
837
|
+
togglePanel() {
|
|
838
|
+
this.isPanelOpen = !this.isPanelOpen;
|
|
839
|
+
if (this.isPanelOpen) {
|
|
840
|
+
// Marca el move pendiente — se ejecutará cuando dropdownRef esté disponible
|
|
841
|
+
this.pendingPanelMove = true;
|
|
1083
842
|
}
|
|
1084
|
-
//const menuContent = this.menuContent.nativeElement; //No se usa porque los elementos ya están en el dropdown
|
|
1085
|
-
overflowItems.forEach(item => {
|
|
1086
|
-
// Mueve el elemento real al dropdown
|
|
1087
|
-
// El elemento ya está oculto (display: none), así que lo hace visible y lo mueve al dropdown
|
|
1088
|
-
item.style.display = '';
|
|
1089
|
-
item.style.visibility = 'visible';
|
|
1090
|
-
// Mueve el elemento al dropdown
|
|
1091
|
-
dropdownContent.appendChild(item);
|
|
1092
|
-
});
|
|
1093
843
|
}
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
const
|
|
1098
|
-
const
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
menuContent.appendChild(item);
|
|
1106
|
-
}
|
|
844
|
+
executePanelMove() {
|
|
845
|
+
if (!this.dropdownRef)
|
|
846
|
+
return;
|
|
847
|
+
const container = this.dropdownRef.panelContainer.nativeElement;
|
|
848
|
+
const items = this.panels.map((panel) => ({
|
|
849
|
+
label: panel.label,
|
|
850
|
+
element: panel.elementRef.nativeElement,
|
|
851
|
+
}));
|
|
852
|
+
items.forEach((item, i) => {
|
|
853
|
+
item.element.style.display = i === 0 ? '' : 'none';
|
|
854
|
+
container.appendChild(item.element);
|
|
1107
855
|
});
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
// Esperar a que el dropdown esté en el DOM antes de actualizar
|
|
1121
|
-
//this.waitForDropdownAndUpdate();
|
|
1122
|
-
this.updateDropdownContent();
|
|
1123
|
-
}, 0);
|
|
856
|
+
this.dropdownRef.items = items;
|
|
857
|
+
this.dropdownRef.activeIndex = 0;
|
|
858
|
+
this.cdr.detectChanges();
|
|
859
|
+
}
|
|
860
|
+
restorePanels() {
|
|
861
|
+
this.isPanelOpen = false;
|
|
862
|
+
if (this.panelsHost) {
|
|
863
|
+
this.panels.forEach((panel) => {
|
|
864
|
+
const el = panel.elementRef.nativeElement;
|
|
865
|
+
el.style.display = '';
|
|
866
|
+
this.panelsHost.nativeElement.appendChild(el);
|
|
867
|
+
});
|
|
1124
868
|
}
|
|
1125
869
|
}
|
|
1126
870
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: Menu, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1127
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: Menu, isStandalone: true, selector: "cat-menu",
|
|
871
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: Menu, isStandalone: true, selector: "cat-menu", queries: [{ propertyName: "panels", predicate: MenuPanel }], viewQueries: [{ propertyName: "panelsHost", first: true, predicate: ["panelsHost"], descendants: true }, { propertyName: "dropdownRef", first: true, predicate: ["dropdownRef"], descendants: true }], ngImport: i0, template: "<div class=\"menu-wrapper\">\n <div class=\"menu\">\n <!-- Contenido est\u00E1tico: todo lo que NO sea cat-menu-panel -->\n <div class=\"menu-static\">\n <ng-content select=\":not(cat-menu-panel)\"></ng-content>\n </div>\n\n <!-- Host de los cat-menu-panel: visible en estado inicial, oculto cuando el dropdown est\u00E1 activo -->\n <div\n #panelsHost\n class=\"menu-panels-host\"\n [style.display]=\"isDropdownActive ? 'none' : 'contents'\"\n >\n <ng-content select=\"cat-menu-panel\"></ng-content>\n </div>\n\n <!-- Bot\u00F3n chevron: visible cuando isDropdownActive es true -->\n @if (isDropdownActive) {\n <div class=\"menu-toggle\">\n <cat-button variant=\"secondary\" (clicked)=\"togglePanel()\">\n @if (isPanelOpen) {\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\"\n stroke=\"currentColor\"\n style=\"width: 20px; height: 20px\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m4.5 15.75 7.5-7.5 7.5 7.5\" />\n </svg>\n } @else {\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\"\n stroke=\"currentColor\"\n style=\"width: 20px; height: 20px\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m19.5 8.25-7.5 7.5-7.5-7.5\" />\n </svg>\n }\n </cat-button>\n </div>\n }\n\n <!-- Dropdown: siempre en el DOM cuando isDropdownActive, visible solo cuando isPanelOpen -->\n @if (isDropdownActive) {\n <cat-menu-dropdown\n #dropdownRef\n [style.display]=\"isPanelOpen ? 'block' : 'none'\"\n ></cat-menu-dropdown>\n }\n </div>\n</div>\n", styles: [":host{display:block;width:100%;box-sizing:border-box}.menu-wrapper{position:relative;width:100%;padding-top:.75rem;padding-bottom:.75rem;box-sizing:border-box}.menu{height:auto;background-color:rgb(var(--element-color-4) / .7);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);padding:1.75rem 2.5rem;margin:auto;border-radius:52px;border:1px var(--neutral-color-7) solid;display:flex;gap:1em;align-items:center;position:relative;width:100%;box-sizing:border-box}.menu-static{display:flex;gap:1em;align-items:center;flex:1;flex-wrap:wrap;min-width:0}.menu-toggle{flex-shrink:0;margin-left:auto}cat-menu-dropdown{position:absolute;top:calc(100% - .75rem);right:.75rem;z-index:2}@media (max-width: 600px){:host{max-width:100vw}.menu-wrapper{max-width:100vw;padding:.5rem}.menu{padding:1rem 1.5rem;max-width:calc(100vw - 1rem);width:calc(100% - 1rem)}cat-menu-dropdown{right:.5rem;left:.5rem}}@media (min-width: 601px){:host{max-width:100%}.menu-wrapper{max-width:100%}.menu{max-width:calc(100% - 1.5rem)}}\n"], dependencies: [{ kind: "component", type: Button, selector: "cat-button", inputs: ["variant", "size", "disabled", "type", "iconLeft", "iconCenter", "iconRight", "customClass"], outputs: ["clicked"] }, { kind: "component", type: MenuDropdown, selector: "cat-menu-dropdown", inputs: ["items"] }] });
|
|
1128
872
|
}
|
|
1129
873
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: Menu, decorators: [{
|
|
1130
874
|
type: Component,
|
|
1131
|
-
args: [{ selector: 'cat-menu', imports: [
|
|
1132
|
-
}], propDecorators: {
|
|
1133
|
-
type:
|
|
1134
|
-
args: [
|
|
1135
|
-
}],
|
|
875
|
+
args: [{ selector: 'cat-menu', imports: [Button, MenuDropdown], template: "<div class=\"menu-wrapper\">\n <div class=\"menu\">\n <!-- Contenido est\u00E1tico: todo lo que NO sea cat-menu-panel -->\n <div class=\"menu-static\">\n <ng-content select=\":not(cat-menu-panel)\"></ng-content>\n </div>\n\n <!-- Host de los cat-menu-panel: visible en estado inicial, oculto cuando el dropdown est\u00E1 activo -->\n <div\n #panelsHost\n class=\"menu-panels-host\"\n [style.display]=\"isDropdownActive ? 'none' : 'contents'\"\n >\n <ng-content select=\"cat-menu-panel\"></ng-content>\n </div>\n\n <!-- Bot\u00F3n chevron: visible cuando isDropdownActive es true -->\n @if (isDropdownActive) {\n <div class=\"menu-toggle\">\n <cat-button variant=\"secondary\" (clicked)=\"togglePanel()\">\n @if (isPanelOpen) {\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\"\n stroke=\"currentColor\"\n style=\"width: 20px; height: 20px\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m4.5 15.75 7.5-7.5 7.5 7.5\" />\n </svg>\n } @else {\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\"\n stroke=\"currentColor\"\n style=\"width: 20px; height: 20px\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m19.5 8.25-7.5 7.5-7.5-7.5\" />\n </svg>\n }\n </cat-button>\n </div>\n }\n\n <!-- Dropdown: siempre en el DOM cuando isDropdownActive, visible solo cuando isPanelOpen -->\n @if (isDropdownActive) {\n <cat-menu-dropdown\n #dropdownRef\n [style.display]=\"isPanelOpen ? 'block' : 'none'\"\n ></cat-menu-dropdown>\n }\n </div>\n</div>\n", styles: [":host{display:block;width:100%;box-sizing:border-box}.menu-wrapper{position:relative;width:100%;padding-top:.75rem;padding-bottom:.75rem;box-sizing:border-box}.menu{height:auto;background-color:rgb(var(--element-color-4) / .7);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);padding:1.75rem 2.5rem;margin:auto;border-radius:52px;border:1px var(--neutral-color-7) solid;display:flex;gap:1em;align-items:center;position:relative;width:100%;box-sizing:border-box}.menu-static{display:flex;gap:1em;align-items:center;flex:1;flex-wrap:wrap;min-width:0}.menu-toggle{flex-shrink:0;margin-left:auto}cat-menu-dropdown{position:absolute;top:calc(100% - .75rem);right:.75rem;z-index:2}@media (max-width: 600px){:host{max-width:100vw}.menu-wrapper{max-width:100vw;padding:.5rem}.menu{padding:1rem 1.5rem;max-width:calc(100vw - 1rem);width:calc(100% - 1rem)}cat-menu-dropdown{right:.5rem;left:.5rem}}@media (min-width: 601px){:host{max-width:100%}.menu-wrapper{max-width:100%}.menu{max-width:calc(100% - 1.5rem)}}\n"] }]
|
|
876
|
+
}], propDecorators: { panels: [{
|
|
877
|
+
type: ContentChildren,
|
|
878
|
+
args: [MenuPanel]
|
|
879
|
+
}], panelsHost: [{
|
|
1136
880
|
type: ViewChild,
|
|
1137
|
-
args: ['
|
|
1138
|
-
}],
|
|
881
|
+
args: ['panelsHost']
|
|
882
|
+
}], dropdownRef: [{
|
|
1139
883
|
type: ViewChild,
|
|
1140
|
-
args: ['
|
|
884
|
+
args: ['dropdownRef']
|
|
1141
885
|
}] } });
|
|
1142
886
|
|
|
1143
887
|
class Theming {
|
|
@@ -1271,332 +1015,102 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
1271
1015
|
}]
|
|
1272
1016
|
}] });
|
|
1273
1017
|
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
'archive-box',
|
|
1280
|
-
'archive-box-arrow-down',
|
|
1281
|
-
'archive-box-x-mark',
|
|
1282
|
-
'arrow-down',
|
|
1283
|
-
'arrow-down-circle',
|
|
1284
|
-
'arrow-down-left',
|
|
1285
|
-
'arrow-down-on-square',
|
|
1286
|
-
'arrow-down-on-square-stack',
|
|
1287
|
-
'arrow-down-right',
|
|
1288
|
-
'arrow-down-tray',
|
|
1289
|
-
'arrow-left',
|
|
1290
|
-
'arrow-left-circle',
|
|
1291
|
-
'arrow-left-end-on-rectangle',
|
|
1292
|
-
'arrow-left-start-on-rectangle',
|
|
1293
|
-
'arrow-long-down',
|
|
1294
|
-
'arrow-long-left',
|
|
1295
|
-
'arrow-long-right',
|
|
1296
|
-
'arrow-long-up',
|
|
1297
|
-
'arrow-path',
|
|
1298
|
-
'arrow-path-rounded-square',
|
|
1299
|
-
'arrow-right',
|
|
1300
|
-
'arrow-right-circle',
|
|
1301
|
-
'arrow-right-end-on-rectangle',
|
|
1302
|
-
'arrow-right-start-on-rectangle',
|
|
1303
|
-
'arrow-top-right-on-square',
|
|
1304
|
-
'arrow-trending-down',
|
|
1305
|
-
'arrow-trending-up',
|
|
1306
|
-
'arrow-turn-down-left',
|
|
1307
|
-
'arrow-turn-down-right',
|
|
1308
|
-
'arrow-turn-left-down',
|
|
1309
|
-
'arrow-turn-left-up',
|
|
1310
|
-
'arrow-turn-right-down',
|
|
1311
|
-
'arrow-turn-right-up',
|
|
1312
|
-
'arrow-turn-up-left',
|
|
1313
|
-
'arrow-turn-up-right',
|
|
1314
|
-
'arrow-up',
|
|
1315
|
-
'arrow-up-circle',
|
|
1316
|
-
'arrow-up-left',
|
|
1317
|
-
'arrow-up-on-square',
|
|
1318
|
-
'arrow-up-on-square-stack',
|
|
1319
|
-
'arrow-up-right',
|
|
1320
|
-
'arrow-up-tray',
|
|
1321
|
-
'arrow-uturn-down',
|
|
1322
|
-
'arrow-uturn-left',
|
|
1323
|
-
'arrow-uturn-right',
|
|
1324
|
-
'arrow-uturn-up',
|
|
1325
|
-
'arrows-pointing-in',
|
|
1326
|
-
'arrows-pointing-out',
|
|
1327
|
-
'arrows-right-left',
|
|
1328
|
-
'arrows-up-down',
|
|
1329
|
-
'at-symbol',
|
|
1330
|
-
'backspace',
|
|
1331
|
-
'backward',
|
|
1332
|
-
'banknotes',
|
|
1333
|
-
'bars-2',
|
|
1334
|
-
'bars-3',
|
|
1335
|
-
'bars-3-bottom-left',
|
|
1336
|
-
'bars-3-bottom-right',
|
|
1337
|
-
'bars-3-center-left',
|
|
1338
|
-
'bars-4',
|
|
1339
|
-
'bars-arrow-down',
|
|
1340
|
-
'bars-arrow-up',
|
|
1341
|
-
'battery-0',
|
|
1342
|
-
'battery-100',
|
|
1343
|
-
'battery-50',
|
|
1344
|
-
'beaker',
|
|
1345
|
-
'bell',
|
|
1346
|
-
'bell-alert',
|
|
1347
|
-
'bell-slash',
|
|
1348
|
-
'bell-snooze',
|
|
1349
|
-
'bold',
|
|
1350
|
-
'bolt',
|
|
1351
|
-
'bolt-slash',
|
|
1352
|
-
'book-open',
|
|
1353
|
-
'bookmark',
|
|
1354
|
-
'bookmark-slash',
|
|
1355
|
-
'bookmark-square',
|
|
1356
|
-
'briefcase',
|
|
1357
|
-
'bug-ant',
|
|
1358
|
-
'building-library',
|
|
1359
|
-
'building-office',
|
|
1360
|
-
'building-office-2',
|
|
1361
|
-
'building-storefront',
|
|
1362
|
-
'cake',
|
|
1363
|
-
'calculator',
|
|
1364
|
-
'calendar',
|
|
1365
|
-
'calendar-date-range',
|
|
1366
|
-
'calendar-days',
|
|
1367
|
-
'camera',
|
|
1368
|
-
'chart-bar',
|
|
1369
|
-
'chart-bar-square',
|
|
1370
|
-
'chart-pie',
|
|
1371
|
-
'chat-bubble-bottom-center',
|
|
1372
|
-
'chat-bubble-bottom-center-text',
|
|
1373
|
-
'chat-bubble-left',
|
|
1374
|
-
'chat-bubble-left-ellipsis',
|
|
1375
|
-
'chat-bubble-left-right',
|
|
1376
|
-
'chat-bubble-oval-left',
|
|
1377
|
-
'chat-bubble-oval-left-ellipsis',
|
|
1378
|
-
'check',
|
|
1379
|
-
'check-badge',
|
|
1380
|
-
'check-circle',
|
|
1381
|
-
'chevron-double-down',
|
|
1382
|
-
'chevron-double-left',
|
|
1383
|
-
'chevron-double-right',
|
|
1384
|
-
'chevron-double-up',
|
|
1385
|
-
'chevron-down',
|
|
1386
|
-
'chevron-left',
|
|
1387
|
-
'chevron-right',
|
|
1388
|
-
'chevron-up',
|
|
1389
|
-
'chevron-up-down',
|
|
1390
|
-
'circle-stack',
|
|
1391
|
-
'clipboard',
|
|
1392
|
-
'clipboard-document',
|
|
1393
|
-
'clipboard-document-check',
|
|
1394
|
-
'clipboard-document-list',
|
|
1395
|
-
'clock',
|
|
1396
|
-
'cloud',
|
|
1397
|
-
'cloud-arrow-down',
|
|
1398
|
-
'cloud-arrow-up',
|
|
1399
|
-
'code-bracket',
|
|
1400
|
-
'code-bracket-square',
|
|
1401
|
-
'cog',
|
|
1402
|
-
'cog-6-tooth',
|
|
1403
|
-
'cog-8-tooth',
|
|
1404
|
-
'command-line',
|
|
1405
|
-
'computer-desktop',
|
|
1406
|
-
'cpu-chip',
|
|
1407
|
-
'credit-card',
|
|
1408
|
-
'cube',
|
|
1409
|
-
'cube-transparent',
|
|
1410
|
-
'currency-bangladeshi',
|
|
1411
|
-
'currency-dollar',
|
|
1412
|
-
'currency-euro',
|
|
1413
|
-
'currency-pound',
|
|
1414
|
-
'currency-rupee',
|
|
1415
|
-
'currency-yen',
|
|
1416
|
-
'cursor-arrow-rays',
|
|
1417
|
-
'cursor-arrow-ripple',
|
|
1418
|
-
'device-phone-mobile',
|
|
1419
|
-
'device-tablet',
|
|
1420
|
-
'divide',
|
|
1421
|
-
'document',
|
|
1422
|
-
'document-arrow-down',
|
|
1423
|
-
'document-arrow-up',
|
|
1424
|
-
'document-chart-bar',
|
|
1425
|
-
'document-check',
|
|
1426
|
-
'document-currency-bangladeshi',
|
|
1427
|
-
'document-currency-dollar',
|
|
1428
|
-
'document-currency-euro',
|
|
1429
|
-
'document-currency-pound',
|
|
1430
|
-
'document-currency-rupee',
|
|
1431
|
-
'document-currency-yen',
|
|
1432
|
-
'document-duplicate',
|
|
1433
|
-
'document-magnifying-glass',
|
|
1434
|
-
'document-minus',
|
|
1435
|
-
'document-plus',
|
|
1436
|
-
'document-text',
|
|
1437
|
-
'ellipsis-horizontal',
|
|
1438
|
-
'ellipsis-horizontal-circle',
|
|
1439
|
-
'ellipsis-vertical',
|
|
1440
|
-
'email',
|
|
1441
|
-
'envelope',
|
|
1442
|
-
'envelope-open',
|
|
1443
|
-
'equals',
|
|
1444
|
-
'exclamation-circle',
|
|
1445
|
-
'exclamation-triangle',
|
|
1446
|
-
'eye',
|
|
1447
|
-
'eye-dropper',
|
|
1448
|
-
'eye-slash',
|
|
1449
|
-
'face-frown',
|
|
1450
|
-
'face-smile',
|
|
1451
|
-
'film',
|
|
1452
|
-
'finger-print',
|
|
1453
|
-
'fire',
|
|
1454
|
-
'flag',
|
|
1455
|
-
'folder',
|
|
1456
|
-
'folder-arrow-down',
|
|
1457
|
-
'folder-minus',
|
|
1458
|
-
'folder-open',
|
|
1459
|
-
'folder-plus',
|
|
1460
|
-
'forward',
|
|
1461
|
-
'funnel',
|
|
1462
|
-
'gif',
|
|
1463
|
-
'gift',
|
|
1464
|
-
'gift-top',
|
|
1465
|
-
'github',
|
|
1466
|
-
'globe-alt',
|
|
1467
|
-
'globe-americas',
|
|
1468
|
-
'globe-asia-australia',
|
|
1469
|
-
'globe-europe-africa',
|
|
1470
|
-
'h1',
|
|
1471
|
-
'h2',
|
|
1472
|
-
'h3',
|
|
1473
|
-
'hand-raised',
|
|
1474
|
-
'hand-thumb-down',
|
|
1475
|
-
'hand-thumb-up',
|
|
1476
|
-
'hashtag',
|
|
1477
|
-
'heart',
|
|
1478
|
-
'home',
|
|
1479
|
-
'home-modern',
|
|
1480
|
-
'identification',
|
|
1481
|
-
'inbox',
|
|
1482
|
-
'inbox-arrow-down',
|
|
1483
|
-
'inbox-stack',
|
|
1484
|
-
'information-circle',
|
|
1485
|
-
'italic',
|
|
1486
|
-
'key',
|
|
1487
|
-
'language',
|
|
1488
|
-
'lifebuoy',
|
|
1489
|
-
'light-bulb',
|
|
1490
|
-
'link',
|
|
1491
|
-
'link-slash',
|
|
1492
|
-
'linkedin',
|
|
1493
|
-
'list-bullet',
|
|
1494
|
-
'lock-closed',
|
|
1495
|
-
'lock-open',
|
|
1496
|
-
'magnifying-glass',
|
|
1497
|
-
'magnifying-glass-circle',
|
|
1498
|
-
'magnifying-glass-minus',
|
|
1499
|
-
'magnifying-glass-plus',
|
|
1500
|
-
'map',
|
|
1501
|
-
'map-pin',
|
|
1502
|
-
'megaphone',
|
|
1503
|
-
'microphone',
|
|
1504
|
-
'minus',
|
|
1505
|
-
'minus-circle',
|
|
1506
|
-
'moon',
|
|
1507
|
-
'musical-note',
|
|
1508
|
-
'newspaper',
|
|
1509
|
-
'no-symbol',
|
|
1510
|
-
'numbered-list',
|
|
1511
|
-
'paint-brush',
|
|
1512
|
-
'palette',
|
|
1513
|
-
'paper-airplane',
|
|
1514
|
-
'paper-clip',
|
|
1515
|
-
'pause',
|
|
1516
|
-
'pause-circle',
|
|
1517
|
-
'pencil',
|
|
1518
|
-
'pencil-square',
|
|
1519
|
-
'percent-badge',
|
|
1520
|
-
'phone',
|
|
1521
|
-
'phone-arrow-down-left',
|
|
1522
|
-
'phone-arrow-up-right',
|
|
1523
|
-
'phone-x-mark',
|
|
1524
|
-
'photo',
|
|
1525
|
-
'play',
|
|
1526
|
-
'play-circle',
|
|
1527
|
-
'play-pause',
|
|
1528
|
-
'plus',
|
|
1529
|
-
'plus-circle',
|
|
1530
|
-
'power',
|
|
1531
|
-
'presentation-chart-bar',
|
|
1532
|
-
'presentation-chart-line',
|
|
1533
|
-
'printer',
|
|
1534
|
-
'puzzle-piece',
|
|
1535
|
-
'qr-code',
|
|
1536
|
-
'question-mark-circle',
|
|
1537
|
-
'queue-list',
|
|
1538
|
-
'radio',
|
|
1539
|
-
'receipt-percent',
|
|
1540
|
-
'receipt-refund',
|
|
1541
|
-
'rectangle-group',
|
|
1542
|
-
'rectangle-stack',
|
|
1543
|
-
'rocket-launch',
|
|
1544
|
-
'rss',
|
|
1545
|
-
'scale',
|
|
1546
|
-
'scissors',
|
|
1547
|
-
'server',
|
|
1548
|
-
'server-stack',
|
|
1549
|
-
'share',
|
|
1550
|
-
'shield-check',
|
|
1551
|
-
'shield-exclamation',
|
|
1552
|
-
'shopping-bag',
|
|
1553
|
-
'shopping-cart',
|
|
1554
|
-
'signal',
|
|
1555
|
-
'signal-slash',
|
|
1556
|
-
'slash',
|
|
1557
|
-
'sparkles',
|
|
1558
|
-
'speaker-wave',
|
|
1559
|
-
'speaker-x-mark',
|
|
1560
|
-
'square-2-stack',
|
|
1561
|
-
'square-3-stack-3d',
|
|
1562
|
-
'squares-2x2',
|
|
1563
|
-
'squares-plus',
|
|
1564
|
-
'star',
|
|
1565
|
-
'stop',
|
|
1566
|
-
'stop-circle',
|
|
1567
|
-
'strikethrough',
|
|
1568
|
-
'sun',
|
|
1569
|
-
'swatch',
|
|
1570
|
-
'table-cells',
|
|
1571
|
-
'tag',
|
|
1572
|
-
'ticket',
|
|
1573
|
-
'trash',
|
|
1574
|
-
'trophy',
|
|
1575
|
-
'truck',
|
|
1576
|
-
'tv',
|
|
1577
|
-
'underline',
|
|
1578
|
-
'user',
|
|
1579
|
-
'user-circle',
|
|
1580
|
-
'user-group',
|
|
1581
|
-
'user-minus',
|
|
1582
|
-
'user-plus',
|
|
1583
|
-
'users',
|
|
1584
|
-
'variable',
|
|
1585
|
-
'video-camera',
|
|
1586
|
-
'video-camera-slash',
|
|
1587
|
-
'view-columns',
|
|
1588
|
-
'viewfinder-circle',
|
|
1589
|
-
'wallet',
|
|
1590
|
-
'wifi',
|
|
1591
|
-
'window',
|
|
1592
|
-
'wrench',
|
|
1593
|
-
'wrench-screwdriver',
|
|
1594
|
-
'x-circle',
|
|
1595
|
-
'x-mark',
|
|
1596
|
-
];
|
|
1597
|
-
function getIconPath(name) {
|
|
1598
|
-
return `${ICON_BASE_PATH}/${name}.svg`;
|
|
1018
|
+
class DynamicBackgroundService {
|
|
1019
|
+
setImages$ = new Subject();
|
|
1020
|
+
setBackgroundImage$ = new Subject();
|
|
1021
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DynamicBackgroundService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1022
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DynamicBackgroundService });
|
|
1599
1023
|
}
|
|
1024
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DynamicBackgroundService, decorators: [{
|
|
1025
|
+
type: Injectable
|
|
1026
|
+
}] });
|
|
1027
|
+
|
|
1028
|
+
class DynamicBackground {
|
|
1029
|
+
el;
|
|
1030
|
+
renderer;
|
|
1031
|
+
bgService;
|
|
1032
|
+
showControls = input(true, ...(ngDevMode ? [{ debugName: "showControls" }] : []));
|
|
1033
|
+
images = input(...(ngDevMode ? [undefined, { debugName: "images" }] : []));
|
|
1034
|
+
/** Label shown in the navigation controls next to the image counter. */
|
|
1035
|
+
controlsLabel = input('Background Image', ...(ngDevMode ? [{ debugName: "controlsLabel" }] : []));
|
|
1036
|
+
/** Slideshow interval in milliseconds. 0 = disabled. */
|
|
1037
|
+
slideshowInterval = input(0, ...(ngDevMode ? [{ debugName: "slideshowInterval" }] : []));
|
|
1038
|
+
backgroundElement;
|
|
1039
|
+
resolvedImages = [];
|
|
1040
|
+
imageIndex = 0;
|
|
1041
|
+
slideshowTimer;
|
|
1042
|
+
subscriptions = new Subscription();
|
|
1043
|
+
constructor(el, renderer, bgService) {
|
|
1044
|
+
this.el = el;
|
|
1045
|
+
this.renderer = renderer;
|
|
1046
|
+
this.bgService = bgService;
|
|
1047
|
+
effect(() => {
|
|
1048
|
+
this.startSlideshow(this.slideshowInterval());
|
|
1049
|
+
});
|
|
1050
|
+
if (this.bgService) {
|
|
1051
|
+
this.subscriptions.add(this.bgService.setImages$.subscribe((urls) => {
|
|
1052
|
+
this.resolvedImages = urls;
|
|
1053
|
+
this.applyBackground();
|
|
1054
|
+
this.startSlideshow(this.slideshowInterval());
|
|
1055
|
+
}));
|
|
1056
|
+
this.subscriptions.add(this.bgService.setBackgroundImage$.subscribe((index) => {
|
|
1057
|
+
this.imageIndex = Math.max(0, Math.min(index, this.resolvedImages.length - 1));
|
|
1058
|
+
this.applyBackground();
|
|
1059
|
+
}));
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
ngAfterViewInit() {
|
|
1063
|
+
this.backgroundElement = this.el.nativeElement.querySelector('.generalBackground');
|
|
1064
|
+
this.resolvedImages = this.images() ?? [];
|
|
1065
|
+
this.applyBackground();
|
|
1066
|
+
this.startSlideshow(this.slideshowInterval());
|
|
1067
|
+
}
|
|
1068
|
+
ngOnDestroy() {
|
|
1069
|
+
this.subscriptions.unsubscribe();
|
|
1070
|
+
this.stopSlideshow();
|
|
1071
|
+
}
|
|
1072
|
+
applyBackground() {
|
|
1073
|
+
if (!this.backgroundElement || !this.resolvedImages.length)
|
|
1074
|
+
return;
|
|
1075
|
+
this.renderer.setAttribute(this.backgroundElement, 'style', `background-image: url(${this.resolvedImages[this.imageIndex]});`);
|
|
1076
|
+
}
|
|
1077
|
+
startSlideshow(interval) {
|
|
1078
|
+
this.stopSlideshow();
|
|
1079
|
+
if (interval <= 0 || !this.resolvedImages.length)
|
|
1080
|
+
return;
|
|
1081
|
+
this.slideshowTimer = setInterval(() => this.changeImageIndex(true), interval);
|
|
1082
|
+
}
|
|
1083
|
+
stopSlideshow() {
|
|
1084
|
+
if (this.slideshowTimer) {
|
|
1085
|
+
clearInterval(this.slideshowTimer);
|
|
1086
|
+
this.slideshowTimer = undefined;
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
changeImageIndex(increment) {
|
|
1090
|
+
if (!this.resolvedImages.length)
|
|
1091
|
+
return;
|
|
1092
|
+
this.imageIndex += increment ? 1 : -1;
|
|
1093
|
+
if (this.imageIndex < 0)
|
|
1094
|
+
this.imageIndex = this.resolvedImages.length - 1;
|
|
1095
|
+
if (this.imageIndex >= this.resolvedImages.length)
|
|
1096
|
+
this.imageIndex = 0;
|
|
1097
|
+
this.applyBackground();
|
|
1098
|
+
}
|
|
1099
|
+
get currentIndex() {
|
|
1100
|
+
return this.imageIndex;
|
|
1101
|
+
}
|
|
1102
|
+
get totalImages() {
|
|
1103
|
+
return this.resolvedImages.length;
|
|
1104
|
+
}
|
|
1105
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DynamicBackground, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: DynamicBackgroundService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
1106
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DynamicBackground, isStandalone: true, selector: "cat-dynamic-background", inputs: { showControls: { classPropertyName: "showControls", publicName: "showControls", isSignal: true, isRequired: false, transformFunction: null }, images: { classPropertyName: "images", publicName: "images", isSignal: true, isRequired: false, transformFunction: null }, controlsLabel: { classPropertyName: "controlsLabel", publicName: "controlsLabel", isSignal: true, isRequired: false, transformFunction: null }, slideshowInterval: { classPropertyName: "slideshowInterval", publicName: "slideshowInterval", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ng-template #chevronRight>\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"size-6\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m8.25 4.5 7.5 7.5-7.5 7.5\" />\n</svg>\n</ng-template>\n<ng-template #chevronLeft>\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"size-6\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15.75 19.5 8.25 12l7.5-7.5\" />\n</svg>\n</ng-template>\n\n<section class=\"generalBackground\"></section>\n\n@if (showControls()) {\n<div class=\"multimedia-themes-controler\">\n <div>\n <cat-button\n variant=\"secondary\"\n (clicked)=\"changeImageIndex(false)\"\n [iconCenter]=\"chevronLeft\"\n >\n </cat-button>\n </div>\n <div>\n <p>\n <b>{{ controlsLabel() }} {{ currentIndex + 1 }} / {{ totalImages }}</b>\n </p>\n </div>\n <div>\n <cat-button\n variant=\"secondary\"\n (clicked)=\"changeImageIndex(true)\"\n [iconCenter]=\"chevronRight\"\n ></cat-button>\n </div>\n</div>\n}\n", styles: [".generalBackground{position:fixed;top:0;left:0;z-index:-1;background-size:cover;background-position:center 70%;background-repeat:no-repeat;min-height:100vh;height:100%;width:100%;padding-top:7em}.multimedia-themes-controler{position:fixed;z-index:10;bottom:1em;left:1em;width:auto;max-width:33%;min-width:23%;height:auto;min-height:3em;background-color:var(--neutral-color-0);border-radius:16px;display:flex;justify-content:space-between;align-items:center;gap:1em}.multimedia-themes-controler>div{width:auto;height:100%}@media screen and (orientation: portrait) and (max-width: 600px){.multimedia-themes-controler{max-width:100%;width:80%;left:50%;transform:translate(-50%)}}\n"], dependencies: [{ kind: "component", type: Button, selector: "cat-button", inputs: ["variant", "size", "disabled", "type", "iconLeft", "iconCenter", "iconRight", "customClass"], outputs: ["clicked"] }] });
|
|
1107
|
+
}
|
|
1108
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DynamicBackground, decorators: [{
|
|
1109
|
+
type: Component,
|
|
1110
|
+
args: [{ selector: 'cat-dynamic-background', imports: [Button], template: "<ng-template #chevronRight>\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"size-6\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m8.25 4.5 7.5 7.5-7.5 7.5\" />\n</svg>\n</ng-template>\n<ng-template #chevronLeft>\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"size-6\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15.75 19.5 8.25 12l7.5-7.5\" />\n</svg>\n</ng-template>\n\n<section class=\"generalBackground\"></section>\n\n@if (showControls()) {\n<div class=\"multimedia-themes-controler\">\n <div>\n <cat-button\n variant=\"secondary\"\n (clicked)=\"changeImageIndex(false)\"\n [iconCenter]=\"chevronLeft\"\n >\n </cat-button>\n </div>\n <div>\n <p>\n <b>{{ controlsLabel() }} {{ currentIndex + 1 }} / {{ totalImages }}</b>\n </p>\n </div>\n <div>\n <cat-button\n variant=\"secondary\"\n (clicked)=\"changeImageIndex(true)\"\n [iconCenter]=\"chevronRight\"\n ></cat-button>\n </div>\n</div>\n}\n", styles: [".generalBackground{position:fixed;top:0;left:0;z-index:-1;background-size:cover;background-position:center 70%;background-repeat:no-repeat;min-height:100vh;height:100%;width:100%;padding-top:7em}.multimedia-themes-controler{position:fixed;z-index:10;bottom:1em;left:1em;width:auto;max-width:33%;min-width:23%;height:auto;min-height:3em;background-color:var(--neutral-color-0);border-radius:16px;display:flex;justify-content:space-between;align-items:center;gap:1em}.multimedia-themes-controler>div{width:auto;height:100%}@media screen and (orientation: portrait) and (max-width: 600px){.multimedia-themes-controler{max-width:100%;width:80%;left:50%;transform:translate(-50%)}}\n"] }]
|
|
1111
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: DynamicBackgroundService, decorators: [{
|
|
1112
|
+
type: Optional
|
|
1113
|
+
}] }], propDecorators: { showControls: [{ type: i0.Input, args: [{ isSignal: true, alias: "showControls", required: false }] }], images: [{ type: i0.Input, args: [{ isSignal: true, alias: "images", required: false }] }], controlsLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "controlsLabel", required: false }] }], slideshowInterval: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideshowInterval", required: false }] }] } });
|
|
1600
1114
|
|
|
1601
1115
|
/*
|
|
1602
1116
|
* Public API Surface of catarina
|
|
@@ -1607,5 +1121,5 @@ function getIconPath(name) {
|
|
|
1607
1121
|
* Generated bundle index. Do not edit.
|
|
1608
1122
|
*/
|
|
1609
1123
|
|
|
1610
|
-
export { Accordion, AccordionGroup, Button, Card, CatInput, ColorInput, Dialog, Drag, Drawer,
|
|
1124
|
+
export { Accordion, AccordionGroup, Button, Card, CatInput, ColorInput, Dialog, Drag, Drawer, DynamicBackground, DynamicBackgroundService, Icon, Menu, MenuDropdown, MenuPanel, SelectInput, Theming };
|
|
1611
1125
|
//# sourceMappingURL=catarina-ds-angular.mjs.map
|