@solcre-org/core-ui 2.11.43 → 2.12.1

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.
@@ -0,0 +1,236 @@
1
+ /* ******************************************** */
2
+ /** COMPONENT: IMAGE CAROUSEL
3
+ /* ******************************************** */
4
+
5
+
6
+ .c-img-carousel {
7
+ --_br: 10px;
8
+ --_controls-size: var(--controls-size,2rem);
9
+ --_controls-color: var(--color-neutral-100);
10
+ --_controls-bg-hsl: var(--color-neutral-900-hsl);
11
+ --_controls-bottom: 2rem;
12
+ --_controls-offset-x: var(--controls-offset,1rem);
13
+ --_nav-color-hsl: var(--color-neutral-100-hsl);
14
+
15
+ position: relative;
16
+ }
17
+
18
+ .c-img-carousel__viewport{
19
+ position: relative;
20
+ overflow: hidden;
21
+ border-radius: var(--_br);
22
+ background: var(--color-neutral-200);
23
+ touch-action: pan-y;
24
+ user-select: none;
25
+ -webkit-user-drag: none;
26
+ }
27
+
28
+ .c-img-carousel[data-per-view]{
29
+ border-radius: 0;
30
+ }
31
+
32
+ .c-img-carousel[data-per-view] .c-img-carousel__slide{
33
+ padding-inline: calc(var(--items-gap)/2);
34
+ }
35
+ .c-img-carousel[data-per-view] .c-img-carousel__slide-inner{
36
+ border-radius: var(--_br);
37
+ overflow: hidden;
38
+ }
39
+
40
+ .c-img-carousel__holder {
41
+ display: flex;
42
+ transition: transform 350ms ease;
43
+ will-change: transform;
44
+ }
45
+
46
+ .c-img-carousel[data-per-view] .c-img-carousel__holder{
47
+ margin-inline: calc(var(--items-gap)/-2);
48
+ }
49
+
50
+ .c-img-carousel__slide {
51
+ position: relative;
52
+ flex: 0 0 calc(100% / var(--per-view, 1));
53
+ }
54
+
55
+ .c-img-carousel__slide-inner::before{
56
+ content: "";
57
+ display: block;
58
+ height: 0;
59
+ padding-bottom: 56.25%;
60
+ }
61
+
62
+ .c-img-carousel__slide-inner{
63
+ position: relative;
64
+ width: 100%;
65
+ height: 100%;
66
+ }
67
+
68
+ .c-img-carousel__slide img {
69
+ position: absolute;
70
+ top: 0;
71
+ left: 0;
72
+ width: 100%;
73
+ height: 100%;
74
+ object-fit: cover;
75
+ }
76
+
77
+ .c-img-carousel__btn--prev {
78
+ left: var(--_controls-offset-x);
79
+ }
80
+ .c-img-carousel__btn--next {
81
+ right: var(--_controls-offset-x);
82
+ }
83
+
84
+ .c-img-carousel--arrows-out .c-img-carousel__btn--prev {
85
+ left: calc(var(--_controls-offset-x)*-1);
86
+ }
87
+
88
+ .c-img-carousel--arrows-out .c-img-carousel__btn--next {
89
+ right: calc(var(--_controls-offset-x)*-1);
90
+ }
91
+
92
+ .c-img-carousel__btn {
93
+ position: absolute;
94
+ top: 50%;
95
+ transform: translateY(-50%);
96
+ border: none;
97
+ background: hsl(var(--_controls-bg-hsl)/40%);
98
+ padding: calc(var(--_controls-size)/2);
99
+ border-radius: 50%;
100
+ color: var(--_controls-color);
101
+ font-size: var(--_controls-size);
102
+ cursor: pointer;
103
+ transition: opacity var(--trs-duration-400) ease-out, color var(--trs-duration-400) ease-out;
104
+ z-index: 1;
105
+ }
106
+
107
+ .c-img-carousel__btn:disabled {
108
+ opacity: .4;
109
+ transition: opacity var(--trs-duration-400) ease-out, color var(--trs-duration-400) ease-out;
110
+ }
111
+
112
+ .c-img-carousel__dots {
113
+ position: absolute;
114
+ display: flex;
115
+ gap: 1rem;
116
+ left: 50%;
117
+ bottom: var(--_controls-bottom);
118
+ transform: translateX(-50%);
119
+ z-index: 1;
120
+ }
121
+
122
+ .c-img-carousel__dot {
123
+ width: 15px;
124
+ height: 15px;
125
+ border-radius: 50%;
126
+ border: 0;
127
+ background: hsl(var(--_nav-color-hsl)/100%);
128
+ opacity: 60%;
129
+ cursor: pointer;
130
+ }
131
+ .c-img-carousel__dot[aria-current="true"] {
132
+ opacity: 1;
133
+ pointer-events: none;
134
+ }
135
+
136
+
137
+ /* ********************** MEDIA HOVER ********************** */
138
+
139
+ @media (hover: hover) {
140
+
141
+ .c-img-carousel__dot:not([aria-current="true"]):hover{
142
+ background-color: var(--color-hover);
143
+ }
144
+
145
+ .c-img-carousel__btn{
146
+ transition: background-color var(--trs-duration-400) ease-out;
147
+ }
148
+
149
+ .c-img-carousel__btn:hover{
150
+ background-color: hsl(var(--color-hover-hsl)/50%);
151
+ transition: background-color var(--trs-duration-400) ease-out;
152
+ }
153
+
154
+ }
155
+
156
+
157
+
158
+ /* ********************** SHORT MOBILE ********************** */
159
+
160
+ @media (max-width: 22.4375rem) { /* 359px */
161
+ }
162
+
163
+
164
+
165
+
166
+
167
+ /* ********************** TALL MOBILE PORTRAIT ********************** */
168
+
169
+ @media (max-width: 47.9375rem) and (min-height: 45.625rem) { /* 767px, 730px */
170
+ }
171
+
172
+
173
+
174
+
175
+
176
+ /* ********************** MOBILE LANDSCAPE ********************** */
177
+
178
+ @media (orientation: landscape) and (min-width: 31.25rem) and (max-width: 47.9375rem) { /* 500px, 767px */
179
+ }
180
+
181
+
182
+
183
+
184
+
185
+ /* ********************** de Mobile a TABLET ********************** */
186
+
187
+ @media (min-width: 48rem) { /* 768px */
188
+ }
189
+ @media (min-width: 48rem) and (orientation: portrait) {
190
+ }
191
+
192
+
193
+
194
+
195
+ /* ********************** de Tablet a DESKTOP ********************** */
196
+
197
+ @media (min-width: 61.25rem) { /* 980px */
198
+ }
199
+
200
+
201
+
202
+
203
+ /* ********************** de Desktop a DESKTOP 2 ********************** */
204
+
205
+ @media (min-width: 75rem) { /* 1200px */
206
+ }
207
+ @media (min-width: 75rem) and (min-height: 45rem) { /* 1200, 720 */
208
+ }
209
+
210
+
211
+
212
+
213
+ /* ********************** de Desktop 2 a HD ********************** */
214
+
215
+ @media (min-width: 87.5rem) { /* 1400px */
216
+ }
217
+ @media (min-width: 87.5rem) and (min-height: 49.375rem) { /* 1400px, 790px */
218
+ }
219
+
220
+
221
+
222
+
223
+ /* ********************** de Hd a FULL HD ********************** */
224
+
225
+ @media (min-width: 100rem) { /* 1600px */
226
+ }
227
+
228
+ @media (min-width: 100rem) and (min-height: 49.375rem) { /* 1600px, 790px */
229
+ }
230
+ @media (min-width: 100rem) and (min-height: 56.25rem) { /* 1600px, 900px */
231
+ }
232
+
233
+ @media (min-width: 112.5rem) { /* 1800px */
234
+ }
235
+ @media (min-width: 112.5rem) and (min-height: 56.25rem) { /* 1800px, 900px */
236
+ }
@@ -2,9 +2,9 @@
2
2
  /** COMPONENT: IMAGE PREVIEW
3
3
  /* ******************************************** */
4
4
 
5
- *:has(> .c-img-preview){
5
+ /* *:has(> .c-img-preview){
6
6
  position: relative;
7
- }
7
+ } */
8
8
 
9
9
  .c-img-preview{
10
10
  cursor: pointer;
@@ -67,6 +67,7 @@
67
67
  /* ❌ */ @import url(inc/components/bottom-nav.css); /* !(test) */
68
68
  /* ⭐️ */ @import url(inc/components/calendar.css);
69
69
  /* ⭐️ */ @import url(inc/components/progressbar.css);
70
+ /* ✅ */ @import url(inc/components/image-carousel.css); /* !(new) */
70
71
 
71
72
 
72
73
  /* Utilities */
@@ -969,6 +969,7 @@ class ImagePreviewComponent {
969
969
  borderRadius = input('4px');
970
970
  cursor = input('pointer');
971
971
  loading = input('lazy');
972
+ isRelative = input(false);
972
973
  onImageClick() {
973
974
  this.imageModalService.openImageModal({
974
975
  src: this.src(),
@@ -977,7 +978,7 @@ class ImagePreviewComponent {
977
978
  });
978
979
  }
979
980
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: ImagePreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
980
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.0.6", type: ImagePreviewComponent, isStandalone: true, selector: "core-image-preview", inputs: { src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: true, transformFunction: null }, alt: { classPropertyName: "alt", publicName: "alt", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, objectFit: { classPropertyName: "objectFit", publicName: "objectFit", isSignal: true, isRequired: false, transformFunction: null }, borderRadius: { classPropertyName: "borderRadius", publicName: "borderRadius", isSignal: true, isRequired: false, transformFunction: null }, cursor: { classPropertyName: "cursor", publicName: "cursor", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"c-img-preview\" \n (click)=\"onImageClick()\">\n <img \n [src]=\"src()\" \n [alt]=\"alt()\"\n [title]=\"title()\"\n [loading]=\"loading()\"\n [style.object-fit]=\"objectFit()\"\n [style.border-radius]=\"borderRadius()\"\n [style.cursor]=\"cursor()\">\n</div>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
981
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.0.6", type: ImagePreviewComponent, isStandalone: true, selector: "core-image-preview", inputs: { src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: true, transformFunction: null }, alt: { classPropertyName: "alt", publicName: "alt", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, objectFit: { classPropertyName: "objectFit", publicName: "objectFit", isSignal: true, isRequired: false, transformFunction: null }, borderRadius: { classPropertyName: "borderRadius", publicName: "borderRadius", isSignal: true, isRequired: false, transformFunction: null }, cursor: { classPropertyName: "cursor", publicName: "cursor", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, isRelative: { classPropertyName: "isRelative", publicName: "isRelative", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"c-img-preview\" \n (click)=\"onImageClick()\">\n <img \n [src]=\"src()\" \n [alt]=\"alt()\"\n [title]=\"title()\"\n [loading]=\"loading()\"\n [style.object-fit]=\"objectFit()\"\n [style.border-radius]=\"borderRadius()\"\n [style.cursor]=\"cursor()\">\n</div>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
981
982
  }
982
983
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: ImagePreviewComponent, decorators: [{
983
984
  type: Component,
@@ -1469,7 +1470,7 @@ class FileFieldComponent extends BaseFieldComponent {
1469
1470
  this.onBlur();
1470
1471
  }
1471
1472
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: FileFieldComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1472
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: FileFieldComponent, isStandalone: true, selector: "core-file-field", usesInheritance: true, hostDirectives: [{ directive: CoreHostDirective }], ngImport: i0, template: "<label class=\"c-entry-item\" [class.c-entry-item--inline]=\"field().inline\">\n @if (field().label) {\n <span class=\"c-entry-text\">\n {{ field().label | translate }}\n @if (hasRequiredValidators()) {\n <span class=\"c-required\">*</span>\n }\n </span>\n }\n <div class=\"c-entry-file\" [class.has-error]=\"hasError()\">\n @if(fieldConfig().multiple || isEditMode() || allFiles().length === 0) {\n <label class=\"c-entry-file__label\">\n <span class=\"icon-upload c-entry-file__icon\"></span>\n <input\n type=\"file\"\n class=\"c-entry-file__input\"\n (change)=\"onFileSelected($event)\"\n [accept]=\"fieldConfig().accept\"\n [multiple]=\"fieldConfig().multiple\"\n (blur)=\"onBlurInput()\"\n [readonly]=\"isReadonly()\"\n >\n {{ fieldConfig().placeholder ?? fieldConfig().label | translate }}\n @if(fieldConfig().acceptString) {\n <br>\n <span class=\"c-entry-file__filename\" id=\"file-name\">{{ fieldConfig().acceptString }}</span>\n }\n </label>\n }\n\n @if (allFiles().length > 0) {\n <div class=\"c-attachments\">\n <p class=\"c-entry-text\">{{ 'files.attachedFiles' | translate }}</p>\n \n <ul class=\"c-attachments__list\">\n @for (file of allFiles(); track $index; let i = $index) {\n <li class=\"c-attachments__item\">\n <div class=\"c-bulleted-text\">\n @if(!isServerFile(file)) {\n <time>{{ getCurrentDate() }}</time>\n <span>{{ getCurrentUser() }}</span>\n }\n </div>\n \n <div class=\"c-attachments__holder\">\n @if(!isServerFile(file) && file.type.startsWith('image/') && fieldConfig().showPreview !== false) {\n <div class=\"c-attachments__content\">\n <div class=\"c-attachments__pic\">\n @if(isPreviewFile(file) && getOriginalUrl(file)) {\n <core-image-preview\n [src]=\"getOriginalUrl(file)!\"\n [alt]=\"file.name\"\n ></core-image-preview>\n } @else if(getPreviewUrl(file)) {\n <core-image-preview\n [src]=\"getPreviewUrl(file)!\"\n [alt]=\"file.name\"\n ></core-image-preview>\n }\n </div>\n <div class=\"c-attachments__text\">\n <span class=\"c-attachments__name-file\">{{ file.name }}</span>\n <span class=\"c-attachments__file-size\">({{ formatFileSize(file.size) }})</span>\n </div>\n </div>\n } @else {\n <a class=\"c-attachments__content\">\n @if(isServerFile(file)) {\n <span class=\"icon-file\"></span>\n {{ file.filename }}\n } @else {\n <span [class]=\"getFileIcon(file)\"></span>\n <div class=\"c-attachments__text\">\n <span class=\"c-attachments__name-file\">{{ file.name }}</span>\n <span class=\"c-attachments__file-size\">({{ formatFileSize(file.size) }})</span>\n </div>\n }\n </a>\n }\n\n <div class=\"c-attachments__actions u-flex u-flex--wrap\">\n <button \n type=\"button\" \n class=\"c-link context:error\" \n (click)=\"removeFile(i)\"\n [title]=\"'files.remove' | translate\"\n >\n <span class=\"icon-delete\"></span>\n {{ 'files.remove' | translate }}\n </button>\n\n @if(fieldConfig().customActions) {\n @for(action of fieldConfig().customActions; track action.id) {\n <button \n type=\"button\"\n class=\"c-link c-link--underlined\" \n (click)=\"action.action(file)\"\n [title]=\"action.label | translate\"\n >\n {{ action.label | translate }}\n <span [ngClass]=\"action.icon | coreIconCompat\"></span>\n </button>\n }\n }\n </div>\n </div>\n </li>\n }\n </ul>\n </div>\n }\n </div>\n <core-field-errors [errors]=\"errors()\" />\n @if(displayErrorMessage()) {\n <span class=\"c-entry-error\">{{ displayErrorMessage()!.key | translate:displayErrorMessage()!.params }}</span>\n }\n</label>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: FieldErrorsComponent, selector: "core-field-errors", inputs: ["errors"] }, { kind: "pipe", type: IconCompatPipe, name: "coreIconCompat" }, { kind: "component", type: ImagePreviewComponent, selector: "core-image-preview", inputs: ["src", "alt", "title", "width", "height", "objectFit", "borderRadius", "cursor", "loading"] }] });
1473
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: FileFieldComponent, isStandalone: true, selector: "core-file-field", usesInheritance: true, hostDirectives: [{ directive: CoreHostDirective }], ngImport: i0, template: "<label class=\"c-entry-item\" [class.c-entry-item--inline]=\"field().inline\">\n @if (field().label) {\n <span class=\"c-entry-text\">\n {{ field().label | translate }}\n @if (hasRequiredValidators()) {\n <span class=\"c-required\">*</span>\n }\n </span>\n }\n <div class=\"c-entry-file\" [class.has-error]=\"hasError()\">\n @if(fieldConfig().multiple || isEditMode() || allFiles().length === 0) {\n <label class=\"c-entry-file__label\">\n <span class=\"icon-upload c-entry-file__icon\"></span>\n <input\n type=\"file\"\n class=\"c-entry-file__input\"\n (change)=\"onFileSelected($event)\"\n [accept]=\"fieldConfig().accept\"\n [multiple]=\"fieldConfig().multiple\"\n (blur)=\"onBlurInput()\"\n [readonly]=\"isReadonly()\"\n >\n {{ fieldConfig().placeholder ?? fieldConfig().label | translate }}\n @if(fieldConfig().acceptString) {\n <br>\n <span class=\"c-entry-file__filename\" id=\"file-name\">{{ fieldConfig().acceptString }}</span>\n }\n </label>\n }\n\n @if (allFiles().length > 0) {\n <div class=\"c-attachments\">\n <p class=\"c-entry-text\">{{ 'files.attachedFiles' | translate }}</p>\n \n <ul class=\"c-attachments__list\">\n @for (file of allFiles(); track $index; let i = $index) {\n <li class=\"c-attachments__item\">\n <div class=\"c-bulleted-text\">\n @if(!isServerFile(file)) {\n <time>{{ getCurrentDate() }}</time>\n <span>{{ getCurrentUser() }}</span>\n }\n </div>\n \n <div class=\"c-attachments__holder\">\n @if(!isServerFile(file) && file.type.startsWith('image/') && fieldConfig().showPreview !== false) {\n <div class=\"c-attachments__content\">\n <div class=\"c-attachments__pic\">\n @if(isPreviewFile(file) && getOriginalUrl(file)) {\n <core-image-preview\n [src]=\"getOriginalUrl(file)!\"\n [alt]=\"file.name\"\n ></core-image-preview>\n } @else if(getPreviewUrl(file)) {\n <core-image-preview\n [src]=\"getPreviewUrl(file)!\"\n [alt]=\"file.name\"\n ></core-image-preview>\n }\n </div>\n <div class=\"c-attachments__text\">\n <span class=\"c-attachments__name-file\">{{ file.name }}</span>\n <span class=\"c-attachments__file-size\">({{ formatFileSize(file.size) }})</span>\n </div>\n </div>\n } @else {\n <a class=\"c-attachments__content\">\n @if(isServerFile(file)) {\n <span class=\"icon-file\"></span>\n {{ file.filename }}\n } @else {\n <span [class]=\"getFileIcon(file)\"></span>\n <div class=\"c-attachments__text\">\n <span class=\"c-attachments__name-file\">{{ file.name }}</span>\n <span class=\"c-attachments__file-size\">({{ formatFileSize(file.size) }})</span>\n </div>\n }\n </a>\n }\n\n <div class=\"c-attachments__actions u-flex u-flex--wrap\">\n <button \n type=\"button\" \n class=\"c-link context:error\" \n (click)=\"removeFile(i)\"\n [title]=\"'files.remove' | translate\"\n >\n <span class=\"icon-delete\"></span>\n {{ 'files.remove' | translate }}\n </button>\n\n @if(fieldConfig().customActions) {\n @for(action of fieldConfig().customActions; track action.id) {\n <button \n type=\"button\"\n class=\"c-link c-link--underlined\" \n (click)=\"action.action(file)\"\n [title]=\"action.label | translate\"\n >\n {{ action.label | translate }}\n <span [ngClass]=\"action.icon | coreIconCompat\"></span>\n </button>\n }\n }\n </div>\n </div>\n </li>\n }\n </ul>\n </div>\n }\n </div>\n <core-field-errors [errors]=\"errors()\" />\n @if(displayErrorMessage()) {\n <span class=\"c-entry-error\">{{ displayErrorMessage()!.key | translate:displayErrorMessage()!.params }}</span>\n }\n</label>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: FieldErrorsComponent, selector: "core-field-errors", inputs: ["errors"] }, { kind: "pipe", type: IconCompatPipe, name: "coreIconCompat" }, { kind: "component", type: ImagePreviewComponent, selector: "core-image-preview", inputs: ["src", "alt", "title", "width", "height", "objectFit", "borderRadius", "cursor", "loading", "isRelative"] }] });
1473
1474
  }
1474
1475
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: FileFieldComponent, decorators: [{
1475
1476
  type: Component,
@@ -10830,11 +10831,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
10830
10831
  // Este archivo es generado automáticamente por scripts/update-version.js
10831
10832
  // No edites manualmente este archivo
10832
10833
  const VERSION = {
10833
- full: '2.11.43',
10834
+ full: '2.12.1',
10834
10835
  major: 2,
10835
- minor: 11,
10836
- patch: 43,
10837
- timestamp: '2025-09-02T18:32:21.979Z',
10836
+ minor: 12,
10837
+ patch: 1,
10838
+ timestamp: '2025-09-02T20:43:25.016Z',
10838
10839
  buildDate: '2/9/2025'
10839
10840
  };
10840
10841
 
@@ -12732,6 +12733,153 @@ var SliderNavigationType;
12732
12733
  SliderNavigationType["COUNTER"] = "counter";
12733
12734
  })(SliderNavigationType || (SliderNavigationType = {}));
12734
12735
 
12736
+ class CarouselComponent {
12737
+ images = input([]);
12738
+ config = input({});
12739
+ carouselHolder = viewChild('carouselHolder');
12740
+ carouselViewport = viewChild('carouselViewport');
12741
+ currentIndex = signal(0);
12742
+ timer = signal(null);
12743
+ autoplay = computed(() => this.config().autoplay ?? false);
12744
+ interval = computed(() => this.config().interval ?? 3000);
12745
+ perView = computed(() => Math.max(1, this.config().perView ?? 1));
12746
+ step = computed(() => Math.max(1, this.config().step ?? this.perView()));
12747
+ showDots = computed(() => this.config().showDots ?? true);
12748
+ showArrows = computed(() => this.config().showArrows ?? true);
12749
+ arrowsOutside = computed(() => this.config().arrowsOutside ?? false);
12750
+ itemsGap = computed(() => this.config().itemsGap ?? '10px');
12751
+ controlsOffset = computed(() => this.config().controlsOffset ?? '2rem');
12752
+ controlsSize = computed(() => this.config().controlsSize ?? '2.5rem');
12753
+ ariaLabel = computed(() => this.config().ariaLabel ?? 'Galería de imágenes');
12754
+ maxIndex = computed(() => Math.max(0, this.images().length - this.perView()));
12755
+ pagesLength = computed(() => Math.max(1, Math.ceil(this.images().length / this.perView())));
12756
+ dots = computed(() => Array.from({ length: this.pagesLength() }, (_, i) => i));
12757
+ currentPage = computed(() => Math.min(this.pagesLength() - 1, Math.floor(this.currentIndex() / this.perView())));
12758
+ carouselClasses = computed(() => {
12759
+ const classes = ['c-img-carousel', 'js-img-carousel'];
12760
+ if (this.arrowsOutside()) {
12761
+ classes.push('c-img-carousel--arrows-out');
12762
+ }
12763
+ return classes;
12764
+ });
12765
+ constructor() {
12766
+ effect(() => {
12767
+ const viewport = this.carouselViewport();
12768
+ if (viewport) {
12769
+ const element = viewport.nativeElement;
12770
+ element.style.setProperty('--per-view', this.perView().toString());
12771
+ element.style.setProperty('--items-gap', this.itemsGap());
12772
+ element.style.setProperty('--controls-offset', this.controlsOffset());
12773
+ element.style.setProperty('--controls-size', this.controlsSize());
12774
+ }
12775
+ });
12776
+ effect(() => {
12777
+ const shouldAutoplay = this.autoplay() && this.images().length > 1;
12778
+ const currentTimer = this.timer();
12779
+ if (shouldAutoplay && !currentTimer) {
12780
+ this.startAutoplay();
12781
+ }
12782
+ else if (!shouldAutoplay && currentTimer) {
12783
+ this.stopAutoplay();
12784
+ }
12785
+ });
12786
+ effect(() => {
12787
+ const holder = this.carouselHolder();
12788
+ const index = this.currentIndex();
12789
+ if (holder) {
12790
+ const element = holder.nativeElement;
12791
+ const percentage = -(index * (100 / this.perView()));
12792
+ element.style.transform = `translateX(${percentage}%)`;
12793
+ }
12794
+ });
12795
+ }
12796
+ ngAfterViewInit() {
12797
+ this.goToSlide(0, false);
12798
+ }
12799
+ ngOnDestroy() {
12800
+ this.stopAutoplay();
12801
+ }
12802
+ goToSlide(index, animate = true, fromAutoplay = false) {
12803
+ if (index < 0) {
12804
+ index = this.maxIndex();
12805
+ }
12806
+ else if (index > this.maxIndex()) {
12807
+ index = 0;
12808
+ }
12809
+ const holder = this.carouselHolder();
12810
+ if (holder) {
12811
+ holder.nativeElement.style.transition = animate ? 'transform 350ms ease' : 'none';
12812
+ }
12813
+ this.currentIndex.set(index);
12814
+ if (!fromAutoplay && this.autoplay()) {
12815
+ this.restartAutoplay();
12816
+ }
12817
+ }
12818
+ goToPage(pageIndex) {
12819
+ const targetSlide = Math.min(this.maxIndex(), Math.max(0, pageIndex * this.perView()));
12820
+ this.goToSlide(targetSlide, true, false);
12821
+ }
12822
+ goToNextSlide(fromAutoplay = false) {
12823
+ this.goToSlide(this.currentIndex() + this.step(), true, fromAutoplay);
12824
+ }
12825
+ goToPrevSlide() {
12826
+ this.goToSlide(this.currentIndex() - this.step(), true, false);
12827
+ }
12828
+ isDotActive(dotIndex) {
12829
+ return dotIndex === this.currentPage();
12830
+ }
12831
+ startAutoplay() {
12832
+ const currentTimer = this.timer();
12833
+ if (currentTimer) {
12834
+ clearInterval(currentTimer);
12835
+ }
12836
+ const intervalId = setInterval(() => {
12837
+ this.goToNextSlide(true);
12838
+ }, this.interval());
12839
+ this.timer.set(intervalId);
12840
+ }
12841
+ stopAutoplay() {
12842
+ const timerId = this.timer();
12843
+ if (timerId) {
12844
+ clearInterval(timerId);
12845
+ this.timer.set(null);
12846
+ }
12847
+ }
12848
+ restartAutoplay() {
12849
+ if (this.autoplay()) {
12850
+ this.startAutoplay();
12851
+ }
12852
+ }
12853
+ onResize() {
12854
+ this.goToSlide(this.currentIndex(), false);
12855
+ }
12856
+ onKeyDown(event) {
12857
+ if (event.key === 'ArrowLeft') {
12858
+ this.goToPrevSlide();
12859
+ }
12860
+ else if (event.key === 'ArrowRight') {
12861
+ this.goToNextSlide();
12862
+ }
12863
+ }
12864
+ getSlideStyle(index) {
12865
+ return {
12866
+ 'flex': `0 0 ${100 / this.perView()}%`
12867
+ };
12868
+ }
12869
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: CarouselComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12870
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: CarouselComponent, isStandalone: true, selector: "core-carousel", inputs: { images: { classPropertyName: "images", publicName: "images", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "window:resize": "onResize()", "keydown": "onKeyDown($event)" } }, viewQueries: [{ propertyName: "carouselHolder", first: true, predicate: ["carouselHolder"], descendants: true, isSignal: true }, { propertyName: "carouselViewport", first: true, predicate: ["carouselViewport"], descendants: true, isSignal: true }], ngImport: i0, template: "<div \n [ngClass]=\"carouselClasses()\"\n [attr.aria-label]=\"ariaLabel()\"\n tabindex=\"0\"\n #carouselViewport>\n \n <div class=\"c-img-carousel__viewport\">\n <div class=\"c-img-carousel__holder js-img-carousel-holder\" #carouselHolder>\n <div \n *ngFor=\"let image of images(); let i = index\"\n class=\"c-img-carousel__slide js-img-carousel-slide\">\n <div class=\"c-img-carousel__slide-inner\">\n <div>\n <core-image-preview\n [src]=\"image.url\"\n [alt]=\"image.alt || 'Image ' + (i + 1)\"\n [title]=\"image.title || image.alt || 'Image ' + (i + 1)\">\n </core-image-preview>\n </div>\n </div>\n </div>\n </div>\n \n @if (!config().arrowsOutside) {\n <button \n *ngIf=\"showArrows()\"\n class=\"c-img-carousel__btn c-img-carousel__btn--prev icon-arrow-left\"\n type=\"button\"\n (click)=\"goToPrevSlide()\"\n [attr.aria-label]=\"'Anterior'\"\n data-control=\"prevBtn\">\n </button>\n \n <button \n *ngIf=\"showArrows()\"\n class=\"c-img-carousel__btn c-img-carousel__btn--next icon-arrow-right\"\n type=\"button\"\n (click)=\"goToNextSlide()\"\n [attr.aria-label]=\"'Siguiente'\"\n data-control=\"nextBtn\">\n </button>\n }\n \n <div \n *ngIf=\"showDots()\"\n class=\"c-img-carousel__dots js-img-carousel-nav\"\n aria-label=\"Navegaci\u00F3n\">\n <button\n *ngFor=\"let page of dots(); let i = index\"\n class=\"c-img-carousel__dot js-img-carousel-dot\"\n type=\"button\"\n (click)=\"goToPage(i)\"\n [class.c-img-carousel__dot--active]=\"currentPage() === i\"\n [attr.aria-label]=\"'Ir a p\u00E1gina ' + (i + 1)\"\n [attr.aria-current]=\"currentPage() === i ? 'true' : 'false'\">\n </button>\n </div>\n </div>\n @if(config().arrowsOutside) {\n <button \n *ngIf=\"showArrows()\"\n class=\"c-img-carousel__btn c-img-carousel__btn--prev icon-arrow-left\"\n type=\"button\"\n (click)=\"goToPrevSlide()\"\n [attr.aria-label]=\"'Anterior'\"\n data-control=\"prevBtn\">\n </button>\n \n <button \n *ngIf=\"showArrows()\"\n class=\"c-img-carousel__btn c-img-carousel__btn--next icon-arrow-right\"\n type=\"button\"\n (click)=\"goToNextSlide()\"\n [attr.aria-label]=\"'Siguiente'\"\n data-control=\"nextBtn\">\n </button>\n }\n</div>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ImagePreviewComponent, selector: "core-image-preview", inputs: ["src", "alt", "title", "width", "height", "objectFit", "borderRadius", "cursor", "loading", "isRelative"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
12871
+ }
12872
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: CarouselComponent, decorators: [{
12873
+ type: Component,
12874
+ args: [{ selector: 'core-carousel', standalone: true, imports: [CommonModule, ImagePreviewComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div \n [ngClass]=\"carouselClasses()\"\n [attr.aria-label]=\"ariaLabel()\"\n tabindex=\"0\"\n #carouselViewport>\n \n <div class=\"c-img-carousel__viewport\">\n <div class=\"c-img-carousel__holder js-img-carousel-holder\" #carouselHolder>\n <div \n *ngFor=\"let image of images(); let i = index\"\n class=\"c-img-carousel__slide js-img-carousel-slide\">\n <div class=\"c-img-carousel__slide-inner\">\n <div>\n <core-image-preview\n [src]=\"image.url\"\n [alt]=\"image.alt || 'Image ' + (i + 1)\"\n [title]=\"image.title || image.alt || 'Image ' + (i + 1)\">\n </core-image-preview>\n </div>\n </div>\n </div>\n </div>\n \n @if (!config().arrowsOutside) {\n <button \n *ngIf=\"showArrows()\"\n class=\"c-img-carousel__btn c-img-carousel__btn--prev icon-arrow-left\"\n type=\"button\"\n (click)=\"goToPrevSlide()\"\n [attr.aria-label]=\"'Anterior'\"\n data-control=\"prevBtn\">\n </button>\n \n <button \n *ngIf=\"showArrows()\"\n class=\"c-img-carousel__btn c-img-carousel__btn--next icon-arrow-right\"\n type=\"button\"\n (click)=\"goToNextSlide()\"\n [attr.aria-label]=\"'Siguiente'\"\n data-control=\"nextBtn\">\n </button>\n }\n \n <div \n *ngIf=\"showDots()\"\n class=\"c-img-carousel__dots js-img-carousel-nav\"\n aria-label=\"Navegaci\u00F3n\">\n <button\n *ngFor=\"let page of dots(); let i = index\"\n class=\"c-img-carousel__dot js-img-carousel-dot\"\n type=\"button\"\n (click)=\"goToPage(i)\"\n [class.c-img-carousel__dot--active]=\"currentPage() === i\"\n [attr.aria-label]=\"'Ir a p\u00E1gina ' + (i + 1)\"\n [attr.aria-current]=\"currentPage() === i ? 'true' : 'false'\">\n </button>\n </div>\n </div>\n @if(config().arrowsOutside) {\n <button \n *ngIf=\"showArrows()\"\n class=\"c-img-carousel__btn c-img-carousel__btn--prev icon-arrow-left\"\n type=\"button\"\n (click)=\"goToPrevSlide()\"\n [attr.aria-label]=\"'Anterior'\"\n data-control=\"prevBtn\">\n </button>\n \n <button \n *ngIf=\"showArrows()\"\n class=\"c-img-carousel__btn c-img-carousel__btn--next icon-arrow-right\"\n type=\"button\"\n (click)=\"goToNextSlide()\"\n [attr.aria-label]=\"'Siguiente'\"\n data-control=\"nextBtn\">\n </button>\n }\n</div>" }]
12875
+ }], ctorParameters: () => [], propDecorators: { onResize: [{
12876
+ type: HostListener,
12877
+ args: ['window:resize']
12878
+ }], onKeyDown: [{
12879
+ type: HostListener,
12880
+ args: ['keydown', ['$event']]
12881
+ }] } });
12882
+
12735
12883
  class CacheBustingInterceptor {
12736
12884
  intercept(req, next) {
12737
12885
  if (req.url.includes('/assets/i18n/') && req.url.endsWith('.json')) {
@@ -13059,5 +13207,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
13059
13207
  * Generated bundle index. Do not edit.
13060
13208
  */
13061
13209
 
13062
- export { ActiveFiltersComponent, AlertComponent, AlertContainerComponent, AlertService, AlertType, ApiConfigurationProvider, BaseFieldComponent, ButtonContext, ButtonSize, ButtonType, CacheBustingInterceptor, CardComponent, CheckboxFieldComponent, ConfigurationModel, ConfirmationDialogComponent, ConfirmationDialogService, CoreHostDirective, CoreUiHttpLoaderFactory, CoreUiTranslateLoader, CoreUiTranslateService, DataListComponent, DataListItemComponent, DateFieldComponent, DateUtility, DatetimeFieldComponent, DialogActions, DocumentAction, DocumentDisplayMode, DropdownComponent, DropdownDirection, DropdownService, DynamicFieldDirective, FieldErrorsComponent, FieldType, FileFieldComponent, FileModel, FileTemplateModel, FileTemplateType, FileType, FileTypeModel, FileUploadService, FilterModalComponent, FilterService, FilterType, GenericButtonComponent, GenericDocumentationComponent, GenericModalComponent, GenericPaginationComponent, GenericRatingComponent, GenericSidebarComponent, GenericSliderComponent, GenericStepsComponent, GenericTableComponent, GenericTabsComponent, GenericTimelineComponent, GlobalApiConfigService, HeaderComponent, HeaderConfigurationService, HeaderElementType, HeaderService, HttpLoaderFactory, ImageModalComponent, ImageModalService, ImagePreviewComponent, LayoutAuth, LayoutBreakpoint, LayoutComponent, LayoutService, LayoutStateService, LayoutType, LoaderComponent, LoaderService, MainNavComponent, MainNavService, ModalMode, ModelApiService, MultiEntryFieldComponent, MultiEntryOutputFormat, NumberFieldComponent, NumberFieldConfigType, NumberFieldType, NumberRange, PERMISSION_ACTIONS_PROVIDER, PERMISSION_PROVIDER, PERMISSION_RESOURCES_PROVIDER, PaginationService, PasswordFieldComponent, PermissionEnumsService, PermissionModel, PermissionService, PermissionWrapperService, PermissionsActions, PermissionsInterceptor, PermissionsResources, ProgressBarComponent, ProgressBarSize, RatingService, RatingSize, RatingType, ResetPasswordModel, RoleModel, SelectFieldComponent, ServerSelectFieldComponent, ServerSelectService, SidebarCustomModalComponent, SidebarCustomModalService, SidebarHeight, SidebarMobileModalService, SidebarMobileType, SidebarPosition, SidebarService, SidebarState, SidebarTemplateRegistryService, SidebarVisibility, SidebarWidth, SliderActionType, SliderDirection, SliderNavigationType, SliderService, SliderTransition, SmartFieldComponent, StepSize, StepStatus, StepType, StepsService, SwitchFieldComponent, TableAction, TableActionService, TableDataService, TextAreaFieldComponent, TextFieldComponent, TimeFieldComponent, TimeInterval, TimelineService, TimelineStatus, TimelineType, TranslationMergeService, UsersModel, VERSION, equalToValidator, isSameDate, provideCoreUiTranslateLoader, providePermissionActions, providePermissionEnums, providePermissionResources, providePermissionService, providePermissionServiceFactory, provideTranslateLoader };
13210
+ export { ActiveFiltersComponent, AlertComponent, AlertContainerComponent, AlertService, AlertType, ApiConfigurationProvider, BaseFieldComponent, ButtonContext, ButtonSize, ButtonType, CacheBustingInterceptor, CardComponent, CarouselComponent, CheckboxFieldComponent, ConfigurationModel, ConfirmationDialogComponent, ConfirmationDialogService, CoreHostDirective, CoreUiHttpLoaderFactory, CoreUiTranslateLoader, CoreUiTranslateService, DataListComponent, DataListItemComponent, DateFieldComponent, DateUtility, DatetimeFieldComponent, DialogActions, DocumentAction, DocumentDisplayMode, DropdownComponent, DropdownDirection, DropdownService, DynamicFieldDirective, FieldErrorsComponent, FieldType, FileFieldComponent, FileModel, FileTemplateModel, FileTemplateType, FileType, FileTypeModel, FileUploadService, FilterModalComponent, FilterService, FilterType, GenericButtonComponent, GenericDocumentationComponent, GenericModalComponent, GenericPaginationComponent, GenericRatingComponent, GenericSidebarComponent, GenericSliderComponent, GenericStepsComponent, GenericTableComponent, GenericTabsComponent, GenericTimelineComponent, GlobalApiConfigService, HeaderComponent, HeaderConfigurationService, HeaderElementType, HeaderService, HttpLoaderFactory, ImageModalComponent, ImageModalService, ImagePreviewComponent, LayoutAuth, LayoutBreakpoint, LayoutComponent, LayoutService, LayoutStateService, LayoutType, LoaderComponent, LoaderService, MainNavComponent, MainNavService, ModalMode, ModelApiService, MultiEntryFieldComponent, MultiEntryOutputFormat, NumberFieldComponent, NumberFieldConfigType, NumberFieldType, NumberRange, PERMISSION_ACTIONS_PROVIDER, PERMISSION_PROVIDER, PERMISSION_RESOURCES_PROVIDER, PaginationService, PasswordFieldComponent, PermissionEnumsService, PermissionModel, PermissionService, PermissionWrapperService, PermissionsActions, PermissionsInterceptor, PermissionsResources, ProgressBarComponent, ProgressBarSize, RatingService, RatingSize, RatingType, ResetPasswordModel, RoleModel, SelectFieldComponent, ServerSelectFieldComponent, ServerSelectService, SidebarCustomModalComponent, SidebarCustomModalService, SidebarHeight, SidebarMobileModalService, SidebarMobileType, SidebarPosition, SidebarService, SidebarState, SidebarTemplateRegistryService, SidebarVisibility, SidebarWidth, SliderActionType, SliderDirection, SliderNavigationType, SliderService, SliderTransition, SmartFieldComponent, StepSize, StepStatus, StepType, StepsService, SwitchFieldComponent, TableAction, TableActionService, TableDataService, TextAreaFieldComponent, TextFieldComponent, TimeFieldComponent, TimeInterval, TimelineService, TimelineStatus, TimelineType, TranslationMergeService, UsersModel, VERSION, equalToValidator, isSameDate, provideCoreUiTranslateLoader, providePermissionActions, providePermissionEnums, providePermissionResources, providePermissionService, providePermissionServiceFactory, provideTranslateLoader };
13063
13211
  //# sourceMappingURL=solcre-org-core-ui.mjs.map