@caribeng/ui 22.1.0 → 22.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -12
- package/fesm2022/caribeng-ui-accordion.mjs +2 -2
- package/fesm2022/caribeng-ui-anchor.mjs +169 -0
- package/fesm2022/caribeng-ui-autocomplete.mjs +10 -8
- package/fesm2022/caribeng-ui-avatargroup.mjs +9 -3
- package/fesm2022/caribeng-ui-blockui.mjs +12 -4
- package/fesm2022/caribeng-ui-breadcrumb.mjs +5 -2
- package/fesm2022/caribeng-ui-button.mjs +22 -2
- package/fesm2022/caribeng-ui-caribe-alert.mjs +5 -2
- package/fesm2022/caribeng-ui-caribe-animation-lottie.mjs +6 -3
- package/fesm2022/caribeng-ui-caribe-button-group.mjs +6 -3
- package/fesm2022/caribeng-ui-caribe-calendar.mjs +11 -6
- package/fesm2022/caribeng-ui-caribe-card-content.mjs +6 -3
- package/fesm2022/caribeng-ui-caribe-card-move.mjs +29 -7
- package/fesm2022/caribeng-ui-caribe-card-select.mjs +56 -14
- package/fesm2022/caribeng-ui-caribe-circle-loading.mjs +10 -7
- package/fesm2022/caribeng-ui-caribe-coachmark.mjs +42 -19
- package/fesm2022/caribeng-ui-caribe-data-table.mjs +15 -9
- package/fesm2022/caribeng-ui-caribe-dots-indicator.mjs +38 -5
- package/fesm2022/caribeng-ui-caribe-expansion-panel.mjs +16 -5
- package/fesm2022/caribeng-ui-caribe-fab-menu.mjs +56 -7
- package/fesm2022/caribeng-ui-caribe-file-download.mjs +68 -27
- package/fesm2022/caribeng-ui-caribe-file-select.mjs +22 -17
- package/fesm2022/caribeng-ui-caribe-float-menu.mjs +6 -3
- package/fesm2022/caribeng-ui-caribe-footer.mjs +8 -4
- package/fesm2022/caribeng-ui-caribe-header.mjs +6 -3
- package/fesm2022/caribeng-ui-caribe-icon-button.mjs +6 -3
- package/fesm2022/caribeng-ui-caribe-illustration.mjs +6 -3
- package/fesm2022/caribeng-ui-caribe-inline-alert.mjs +5 -2
- package/fesm2022/caribeng-ui-caribe-input-search.mjs +14 -10
- package/fesm2022/caribeng-ui-caribe-input-select.mjs +12 -10
- package/fesm2022/caribeng-ui-caribe-input-token.mjs +61 -11
- package/fesm2022/caribeng-ui-caribe-link.mjs +7 -2
- package/fesm2022/caribeng-ui-caribe-loader.mjs +8 -5
- package/fesm2022/caribeng-ui-caribe-modal.mjs +32 -16
- package/fesm2022/caribeng-ui-caribe-off-canvas.mjs +26 -12
- package/fesm2022/caribeng-ui-caribe-onboarding.mjs +44 -19
- package/fesm2022/caribeng-ui-caribe-pictogram.mjs +6 -3
- package/fesm2022/caribeng-ui-caribe-pop-over.mjs +34 -10
- package/fesm2022/caribeng-ui-caribe-preloader.mjs +9 -6
- package/fesm2022/caribeng-ui-caribe-progress-bar.mjs +5 -2
- package/fesm2022/caribeng-ui-caribe-shortcut.mjs +8 -3
- package/fesm2022/caribeng-ui-caribe-step-indicator.mjs +12 -5
- package/fesm2022/caribeng-ui-caribe-stroke.mjs +6 -3
- package/fesm2022/caribeng-ui-caribe-switch.mjs +5 -3
- package/fesm2022/caribeng-ui-caribe-tag-button.mjs +1 -1
- package/fesm2022/caribeng-ui-caribe-tracker.mjs +5 -2
- package/fesm2022/caribeng-ui-caribe-transaction-status.mjs +1 -1
- package/fesm2022/caribeng-ui-caribe-voucher.mjs +11 -8
- package/fesm2022/caribeng-ui-carousel.mjs +49 -14
- package/fesm2022/caribeng-ui-cascadeselect.mjs +22 -8
- package/fesm2022/caribeng-ui-chart.mjs +2598 -303
- package/fesm2022/caribeng-ui-chip.mjs +9 -4
- package/fesm2022/caribeng-ui-chips.mjs +9 -5
- package/fesm2022/caribeng-ui-colorpicker.mjs +9 -7
- package/fesm2022/caribeng-ui-confirmdialog.mjs +74 -9
- package/fesm2022/caribeng-ui-confirmpopup.mjs +134 -9
- package/fesm2022/caribeng-ui-contextmenu.mjs +6 -3
- package/fesm2022/caribeng-ui-dataview.mjs +211 -6
- package/fesm2022/caribeng-ui-datepicker.mjs +1630 -393
- package/fesm2022/caribeng-ui-descriptions.mjs +124 -0
- package/fesm2022/caribeng-ui-dialog.mjs +10 -7
- package/fesm2022/caribeng-ui-dock.mjs +6 -3
- package/fesm2022/caribeng-ui-drawer.mjs +10 -7
- package/fesm2022/caribeng-ui-dynamicdialog.mjs +210 -6
- package/fesm2022/caribeng-ui-editor.mjs +4392 -243
- package/fesm2022/caribeng-ui-empty.mjs +80 -0
- package/fesm2022/caribeng-ui-file-card.mjs +2 -2
- package/fesm2022/caribeng-ui-fileupload.mjs +96 -19
- package/fesm2022/caribeng-ui-floatlabel.mjs +4 -2
- package/fesm2022/caribeng-ui-folder-card.mjs +10 -3
- package/fesm2022/caribeng-ui-galleria.mjs +76 -45
- package/fesm2022/caribeng-ui-image.mjs +52 -29
- package/fesm2022/caribeng-ui-inplace.mjs +22 -6
- package/fesm2022/caribeng-ui-input-number.mjs +9 -7
- package/fesm2022/caribeng-ui-inputgroup.mjs +2 -2
- package/fesm2022/caribeng-ui-inputmask.mjs +14 -11
- package/fesm2022/caribeng-ui-inputotp.mjs +12 -6
- package/fesm2022/caribeng-ui-keyfilter.mjs +72 -0
- package/fesm2022/caribeng-ui-listbox.mjs +13 -11
- package/fesm2022/caribeng-ui-megamenu.mjs +222 -30
- package/fesm2022/caribeng-ui-menu.mjs +11 -5
- package/fesm2022/caribeng-ui-menubar.mjs +10 -5
- package/fesm2022/caribeng-ui-message.mjs +7 -4
- package/fesm2022/caribeng-ui-metergroup.mjs +29 -11
- package/fesm2022/caribeng-ui-multiselect.mjs +399 -97
- package/fesm2022/caribeng-ui-orderlist.mjs +230 -11
- package/fesm2022/caribeng-ui-organizationchart.mjs +12 -7
- package/fesm2022/caribeng-ui-paginator.mjs +18 -15
- package/fesm2022/caribeng-ui-panel.mjs +5 -2
- package/fesm2022/caribeng-ui-panelmenu.mjs +6 -3
- package/fesm2022/caribeng-ui-password.mjs +8 -6
- package/fesm2022/caribeng-ui-pdfviewer.mjs +1553 -0
- package/fesm2022/caribeng-ui-picklist.mjs +251 -14
- package/fesm2022/caribeng-ui-pricing.mjs +17 -14
- package/fesm2022/caribeng-ui-rating.mjs +7 -3
- package/fesm2022/caribeng-ui-repeater.mjs +223 -0
- package/fesm2022/caribeng-ui-result.mjs +91 -0
- package/fesm2022/caribeng-ui-scrollpanel.mjs +6 -3
- package/fesm2022/caribeng-ui-scrolltop.mjs +6 -3
- package/fesm2022/caribeng-ui-select.mjs +379 -87
- package/fesm2022/caribeng-ui-selectbutton.mjs +2 -2
- package/fesm2022/caribeng-ui-slider.mjs +171 -75
- package/fesm2022/caribeng-ui-speeddial.mjs +7 -4
- package/fesm2022/caribeng-ui-spinner.mjs +5 -2
- package/fesm2022/caribeng-ui-splitbutton.mjs +163 -0
- package/fesm2022/caribeng-ui-splitter.mjs +5 -2
- package/fesm2022/caribeng-ui-statistic.mjs +183 -0
- package/fesm2022/caribeng-ui-stepper.mjs +8 -5
- package/fesm2022/caribeng-ui-steps.mjs +6 -3
- package/fesm2022/caribeng-ui-table.mjs +708 -82
- package/fesm2022/caribeng-ui-tabmenu.mjs +6 -3
- package/fesm2022/caribeng-ui-tag.mjs +2 -2
- package/fesm2022/caribeng-ui-terminal.mjs +45 -9
- package/fesm2022/caribeng-ui-themetoggle.mjs +82 -0
- package/fesm2022/caribeng-ui-tieredmenu.mjs +9 -6
- package/fesm2022/caribeng-ui-timeline.mjs +175 -6
- package/fesm2022/caribeng-ui-toast.mjs +7 -4
- package/fesm2022/caribeng-ui-togglebutton.mjs +8 -6
- package/fesm2022/caribeng-ui-toolbar.mjs +6 -3
- package/fesm2022/caribeng-ui-tree.mjs +302 -6
- package/fesm2022/caribeng-ui-treeselect.mjs +26 -10
- package/fesm2022/caribeng-ui-treetable.mjs +269 -6
- package/fesm2022/caribeng-ui-virtualscroller.mjs +123 -10
- package/fesm2022/caribeng-ui.mjs +829 -6
- package/package.json +70 -11
- package/schematics/collection.json +10 -0
- package/schematics/ng-add/index.js +125 -0
- package/schematics/ng-add/schema.js +2 -0
- package/schematics/ng-add/schema.json +66 -0
- package/styles/caribeng.css +380 -0
- package/styles/scss/_mixins.scss +46 -0
- package/styles/scss/_overlay.scss +15 -0
- package/styles/scss/_tokens.scss +267 -0
- package/styles/scss/_utilities.scss +73 -0
- package/styles/scss/_variables.scss +33 -0
- package/styles/scss/index.scss +16 -0
- package/types/caribeng-ui-anchor.d.ts +50 -0
- package/types/caribeng-ui-autocomplete.d.ts +4 -2
- package/types/caribeng-ui-avatargroup.d.ts +3 -1
- package/types/caribeng-ui-blockui.d.ts +9 -4
- package/types/caribeng-ui-breadcrumb.d.ts +3 -0
- package/types/caribeng-ui-button.d.ts +9 -1
- package/types/caribeng-ui-caribe-alert.d.ts +3 -0
- package/types/caribeng-ui-caribe-animation-lottie.d.ts +4 -1
- package/types/caribeng-ui-caribe-button-group.d.ts +4 -1
- package/types/caribeng-ui-caribe-calendar.d.ts +5 -1
- package/types/caribeng-ui-caribe-card-content.d.ts +4 -1
- package/types/caribeng-ui-caribe-card-move.d.ts +13 -13
- package/types/caribeng-ui-caribe-card-select.d.ts +10 -1
- package/types/caribeng-ui-caribe-circle-loading.d.ts +4 -1
- package/types/caribeng-ui-caribe-coachmark.d.ts +6 -0
- package/types/caribeng-ui-caribe-data-table.d.ts +7 -2
- package/types/caribeng-ui-caribe-dots-indicator.d.ts +9 -0
- package/types/caribeng-ui-caribe-expansion-panel.d.ts +7 -10
- package/types/caribeng-ui-caribe-fab-menu.d.ts +10 -1
- package/types/caribeng-ui-caribe-file-download.d.ts +8 -10
- package/types/caribeng-ui-caribe-file-select.d.ts +7 -1
- package/types/caribeng-ui-caribe-float-menu.d.ts +4 -1
- package/types/caribeng-ui-caribe-header.d.ts +3 -0
- package/types/caribeng-ui-caribe-icon-button.d.ts +4 -1
- package/types/caribeng-ui-caribe-illustration.d.ts +4 -1
- package/types/caribeng-ui-caribe-inline-alert.d.ts +3 -0
- package/types/caribeng-ui-caribe-input-search.d.ts +4 -2
- package/types/caribeng-ui-caribe-input-select.d.ts +4 -2
- package/types/caribeng-ui-caribe-input-token.d.ts +16 -1
- package/types/caribeng-ui-caribe-link.d.ts +3 -0
- package/types/caribeng-ui-caribe-loader.d.ts +4 -1
- package/types/caribeng-ui-caribe-modal.d.ts +7 -10
- package/types/caribeng-ui-caribe-off-canvas.d.ts +6 -1
- package/types/caribeng-ui-caribe-onboarding.d.ts +6 -0
- package/types/caribeng-ui-caribe-pictogram.d.ts +4 -1
- package/types/caribeng-ui-caribe-pop-over.d.ts +7 -10
- package/types/caribeng-ui-caribe-preloader.d.ts +4 -1
- package/types/caribeng-ui-caribe-progress-bar.d.ts +3 -0
- package/types/caribeng-ui-caribe-shortcut.d.ts +3 -1
- package/types/caribeng-ui-caribe-step-indicator.d.ts +6 -0
- package/types/caribeng-ui-caribe-stroke.d.ts +4 -1
- package/types/caribeng-ui-caribe-switch.d.ts +3 -1
- package/types/caribeng-ui-caribe-tracker.d.ts +3 -0
- package/types/caribeng-ui-caribe-voucher.d.ts +5 -2
- package/types/caribeng-ui-carousel.d.ts +10 -1
- package/types/caribeng-ui-cascadeselect.d.ts +7 -2
- package/types/caribeng-ui-chart.d.ts +469 -44
- package/types/caribeng-ui-chip.d.ts +6 -0
- package/types/caribeng-ui-chips.d.ts +6 -2
- package/types/caribeng-ui-colorpicker.d.ts +3 -1
- package/types/caribeng-ui-confirmdialog.d.ts +25 -6
- package/types/caribeng-ui-confirmpopup.d.ts +37 -5
- package/types/caribeng-ui-contextmenu.d.ts +4 -1
- package/types/caribeng-ui-dataview.d.ts +63 -5
- package/types/caribeng-ui-datepicker.d.ts +186 -21
- package/types/caribeng-ui-descriptions.d.ts +63 -0
- package/types/caribeng-ui-dialog.d.ts +4 -1
- package/types/caribeng-ui-dock.d.ts +4 -1
- package/types/caribeng-ui-drawer.d.ts +4 -1
- package/types/caribeng-ui-dynamicdialog.d.ts +93 -3
- package/types/caribeng-ui-editor.d.ts +486 -13
- package/types/caribeng-ui-empty.d.ts +34 -0
- package/types/caribeng-ui-file-card.d.ts +1 -1
- package/types/caribeng-ui-fileupload.d.ts +27 -4
- package/types/caribeng-ui-folder-card.d.ts +4 -1
- package/types/caribeng-ui-galleria.d.ts +9 -0
- package/types/caribeng-ui-image.d.ts +10 -0
- package/types/caribeng-ui-inplace.d.ts +8 -0
- package/types/caribeng-ui-input-number.d.ts +3 -1
- package/types/caribeng-ui-inputmask.d.ts +5 -0
- package/types/caribeng-ui-inputotp.d.ts +7 -2
- package/types/caribeng-ui-keyfilter.d.ts +30 -0
- package/types/caribeng-ui-listbox.d.ts +5 -3
- package/types/caribeng-ui-megamenu.d.ts +26 -2
- package/types/caribeng-ui-menu.d.ts +7 -2
- package/types/caribeng-ui-menubar.d.ts +5 -1
- package/types/caribeng-ui-message.d.ts +3 -0
- package/types/caribeng-ui-metergroup.d.ts +9 -1
- package/types/caribeng-ui-multiselect.d.ts +71 -10
- package/types/caribeng-ui-orderlist.d.ts +58 -6
- package/types/caribeng-ui-organizationchart.d.ts +7 -1
- package/types/caribeng-ui-paginator.d.ts +3 -0
- package/types/caribeng-ui-panel.d.ts +3 -0
- package/types/caribeng-ui-panelmenu.d.ts +4 -1
- package/types/caribeng-ui-password.d.ts +4 -2
- package/types/caribeng-ui-pdfviewer.d.ts +258 -0
- package/types/caribeng-ui-picklist.d.ts +67 -7
- package/types/caribeng-ui-pricing.d.ts +8 -5
- package/types/caribeng-ui-rating.d.ts +6 -2
- package/types/caribeng-ui-repeater.d.ts +79 -0
- package/types/caribeng-ui-result.d.ts +35 -0
- package/types/caribeng-ui-scrollpanel.d.ts +4 -1
- package/types/caribeng-ui-scrolltop.d.ts +4 -1
- package/types/caribeng-ui-select.d.ts +73 -9
- package/types/caribeng-ui-slider.d.ts +63 -10
- package/types/caribeng-ui-speeddial.d.ts +5 -2
- package/types/caribeng-ui-spinner.d.ts +3 -0
- package/types/caribeng-ui-splitbutton.d.ts +49 -0
- package/types/caribeng-ui-splitter.d.ts +3 -0
- package/types/caribeng-ui-statistic.d.ts +65 -0
- package/types/caribeng-ui-stepper.d.ts +3 -0
- package/types/caribeng-ui-steps.d.ts +4 -1
- package/types/caribeng-ui-table.d.ts +184 -16
- package/types/caribeng-ui-tabmenu.d.ts +4 -1
- package/types/caribeng-ui-terminal.d.ts +10 -0
- package/types/caribeng-ui-themetoggle.d.ts +32 -0
- package/types/caribeng-ui-tieredmenu.d.ts +5 -2
- package/types/caribeng-ui-timeline.d.ts +63 -4
- package/types/caribeng-ui-toast.d.ts +3 -0
- package/types/caribeng-ui-togglebutton.d.ts +5 -3
- package/types/caribeng-ui-toolbar.d.ts +7 -4
- package/types/caribeng-ui-tree.d.ts +76 -4
- package/types/caribeng-ui-treeselect.d.ts +10 -2
- package/types/caribeng-ui-treetable.d.ts +68 -4
- package/types/caribeng-ui-virtualscroller.d.ts +45 -5
- package/types/caribeng-ui.d.ts +501 -12
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { injectCbTranslation } from '@caribeng/ui';
|
|
4
|
+
import { CbIcon } from '@caribeng/ui/icon';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Empty de CaribeNG: estado vacío con icono o imagen, mensaje y acciones
|
|
8
|
+
* opcionales (proyectadas). Úsalo cuando una lista, búsqueda o tabla no tiene
|
|
9
|
+
* datos.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```html
|
|
13
|
+
* <cb-empty title="Aún no tienes movimientos" description="Cuando hagas tu primera compra aparecerá aquí.">
|
|
14
|
+
* <cb-button size="sm">Hacer una transferencia</cb-button>
|
|
15
|
+
* </cb-empty>
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
class CbEmpty {
|
|
19
|
+
constructor() {
|
|
20
|
+
/** Textos de interfaz en el idioma activo (`provideCaribeNG({ locale })`). */
|
|
21
|
+
this.t = injectCbTranslation();
|
|
22
|
+
/** Mensaje principal. Por defecto, "Sin datos" del idioma activo. */
|
|
23
|
+
this.title = input(undefined, /* @ts-ignore */
|
|
24
|
+
...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
25
|
+
/** Texto de apoyo opcional. */
|
|
26
|
+
this.description = input('', /* @ts-ignore */
|
|
27
|
+
...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
|
|
28
|
+
/** Icono (se ignora si hay `image`). */
|
|
29
|
+
this.icon = input('folder', /* @ts-ignore */
|
|
30
|
+
...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
|
|
31
|
+
/** Ilustración opcional (decorativa). */
|
|
32
|
+
this.image = input('', /* @ts-ignore */
|
|
33
|
+
...(ngDevMode ? [{ debugName: "image" }] : /* istanbul ignore next */ []));
|
|
34
|
+
/** `sm` para tablas, listas y paneles pequeños. */
|
|
35
|
+
this.size = input('md', /* @ts-ignore */
|
|
36
|
+
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
37
|
+
}
|
|
38
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: CbEmpty, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
39
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: CbEmpty, isStandalone: true, selector: "cb-empty", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, image: { classPropertyName: "image", publicName: "image", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.cb-empty--sm": "size() === 'sm'" }, classAttribute: "cb-empty" }, ngImport: i0, template: `
|
|
40
|
+
@if (image()) {
|
|
41
|
+
<img class="cb-empty__image" [src]="image()" alt="" />
|
|
42
|
+
} @else {
|
|
43
|
+
<span class="cb-empty__icon" aria-hidden="true">
|
|
44
|
+
<cb-icon [name]="icon()" [size]="size() === 'sm' ? 22 : 32" />
|
|
45
|
+
</span>
|
|
46
|
+
}
|
|
47
|
+
<p class="cb-empty__title">{{ title() ?? t().noData }}</p>
|
|
48
|
+
@if (description()) {
|
|
49
|
+
<p class="cb-empty__description">{{ description() }}</p>
|
|
50
|
+
}
|
|
51
|
+
<div class="cb-empty__actions"><ng-content /></div>
|
|
52
|
+
`, isInline: true, styles: [":host{display:flex;flex-direction:column;align-items:center;gap:var(--cb-space-2, .5rem);padding:var(--cb-space-8, 2rem) var(--cb-space-4, 1rem);text-align:center;font-family:var(--cb-font-sans, inherit);color:var(--cb-color-text)}:host(.cb-empty--sm){padding:var(--cb-space-4, 1rem);gap:var(--cb-space-1, .25rem)}.cb-empty__icon{display:inline-flex;align-items:center;justify-content:center;width:4rem;height:4rem;margin-bottom:var(--cb-space-1, .25rem);color:var(--cb-color-text-muted);background-color:var(--cb-color-surface-subtle);border-radius:999px}:host(.cb-empty--sm) .cb-empty__icon{width:2.75rem;height:2.75rem}.cb-empty__image{max-width:10rem;max-height:8rem;margin-bottom:var(--cb-space-2, .5rem)}.cb-empty__title{margin:0;font-size:var(--cb-text-base, 1rem);font-weight:var(--cb-font-weight-semibold, 600);color:var(--cb-color-text-strong)}:host(.cb-empty--sm) .cb-empty__title{font-size:var(--cb-text-sm, .875rem)}.cb-empty__description{max-width:28rem;margin:0;font-size:var(--cb-text-sm, .875rem);color:var(--cb-color-text-muted)}.cb-empty__actions{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--cb-space-2, .5rem);margin-top:var(--cb-space-2, .5rem)}.cb-empty__actions:empty{display:none}\n"], dependencies: [{ kind: "component", type: CbIcon, selector: "cb-icon", inputs: ["name", "size", "spin", "ariaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
53
|
+
}
|
|
54
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: CbEmpty, decorators: [{
|
|
55
|
+
type: Component,
|
|
56
|
+
args: [{ selector: 'cb-empty', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.Emulated, imports: [CbIcon], host: { class: 'cb-empty', '[class.cb-empty--sm]': "size() === 'sm'" }, template: `
|
|
57
|
+
@if (image()) {
|
|
58
|
+
<img class="cb-empty__image" [src]="image()" alt="" />
|
|
59
|
+
} @else {
|
|
60
|
+
<span class="cb-empty__icon" aria-hidden="true">
|
|
61
|
+
<cb-icon [name]="icon()" [size]="size() === 'sm' ? 22 : 32" />
|
|
62
|
+
</span>
|
|
63
|
+
}
|
|
64
|
+
<p class="cb-empty__title">{{ title() ?? t().noData }}</p>
|
|
65
|
+
@if (description()) {
|
|
66
|
+
<p class="cb-empty__description">{{ description() }}</p>
|
|
67
|
+
}
|
|
68
|
+
<div class="cb-empty__actions"><ng-content /></div>
|
|
69
|
+
`, styles: [":host{display:flex;flex-direction:column;align-items:center;gap:var(--cb-space-2, .5rem);padding:var(--cb-space-8, 2rem) var(--cb-space-4, 1rem);text-align:center;font-family:var(--cb-font-sans, inherit);color:var(--cb-color-text)}:host(.cb-empty--sm){padding:var(--cb-space-4, 1rem);gap:var(--cb-space-1, .25rem)}.cb-empty__icon{display:inline-flex;align-items:center;justify-content:center;width:4rem;height:4rem;margin-bottom:var(--cb-space-1, .25rem);color:var(--cb-color-text-muted);background-color:var(--cb-color-surface-subtle);border-radius:999px}:host(.cb-empty--sm) .cb-empty__icon{width:2.75rem;height:2.75rem}.cb-empty__image{max-width:10rem;max-height:8rem;margin-bottom:var(--cb-space-2, .5rem)}.cb-empty__title{margin:0;font-size:var(--cb-text-base, 1rem);font-weight:var(--cb-font-weight-semibold, 600);color:var(--cb-color-text-strong)}:host(.cb-empty--sm) .cb-empty__title{font-size:var(--cb-text-sm, .875rem)}.cb-empty__description{max-width:28rem;margin:0;font-size:var(--cb-text-sm, .875rem);color:var(--cb-color-text-muted)}.cb-empty__actions{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--cb-space-2, .5rem);margin-top:var(--cb-space-2, .5rem)}.cb-empty__actions:empty{display:none}\n"] }]
|
|
70
|
+
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], image: [{ type: i0.Input, args: [{ isSignal: true, alias: "image", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
|
|
71
|
+
|
|
72
|
+
/*
|
|
73
|
+
* Public API Surface de @caribeng/ui/empty
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Generated bundle index. Do not edit.
|
|
78
|
+
*/
|
|
79
|
+
|
|
80
|
+
export { CbEmpty };
|
|
@@ -34,10 +34,10 @@ class CbFileCard {
|
|
|
34
34
|
this.valueSub = input('', /* @ts-ignore */
|
|
35
35
|
...(ngDevMode ? [{ debugName: "valueSub" }] : /* istanbul ignore next */ []));
|
|
36
36
|
}
|
|
37
|
-
/** Fondo tintado derivado del color (
|
|
37
|
+
/** Fondo tintado derivado del color (cualquier color CSS: hex, rgb(), var(--…)). */
|
|
38
38
|
tintBg() {
|
|
39
39
|
const c = this.color();
|
|
40
|
-
return c ?
|
|
40
|
+
return c ? `color-mix(in srgb, ${c} 12%, transparent)` : null;
|
|
41
41
|
}
|
|
42
42
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: CbFileCard, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
43
43
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: CbFileCard, isStandalone: true, selector: "cb-file-card", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, valueSub: { classPropertyName: "valueSub", publicName: "valueSub", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "cb-file-card" }, ngImport: i0, template: `
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { input, output, signal, viewChild, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
3
|
import { CbIcon } from '@caribeng/ui/icon';
|
|
4
|
+
import { injectCbTranslation, cbFormat } from '@caribeng/ui';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* FileUpload de CaribeNG: selector de archivos con arrastrar y soltar,
|
|
@@ -8,6 +9,10 @@ import { CbIcon } from '@caribeng/ui/icon';
|
|
|
8
9
|
*/
|
|
9
10
|
class CbFileUpload {
|
|
10
11
|
constructor() {
|
|
12
|
+
/** Textos de interfaz en el idioma activo (`provideCaribeNG({ locale })`). */
|
|
13
|
+
this.t = injectCbTranslation();
|
|
14
|
+
/** Rellena `{0}`, `{1}`… de un texto traducido. */
|
|
15
|
+
this.fmt = cbFormat;
|
|
11
16
|
this.accept = input('', /* @ts-ignore */
|
|
12
17
|
...(ngDevMode ? [{ debugName: "accept" }] : /* istanbul ignore next */ []));
|
|
13
18
|
this.multiple = input(false, /* @ts-ignore */
|
|
@@ -16,14 +21,19 @@ class CbFileUpload {
|
|
|
16
21
|
...(ngDevMode ? [{ debugName: "maxFileSize" }] : /* istanbul ignore next */ []));
|
|
17
22
|
this.disabled = input(false, /* @ts-ignore */
|
|
18
23
|
...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
19
|
-
this.chooseLabel = input(
|
|
24
|
+
this.chooseLabel = input(undefined, /* @ts-ignore */
|
|
20
25
|
...(ngDevMode ? [{ debugName: "chooseLabel" }] : /* istanbul ignore next */ []));
|
|
21
|
-
this.uploadLabel = input(
|
|
26
|
+
this.uploadLabel = input(undefined, /* @ts-ignore */
|
|
22
27
|
...(ngDevMode ? [{ debugName: "uploadLabel" }] : /* istanbul ignore next */ []));
|
|
23
28
|
this.selectFiles = output();
|
|
24
29
|
this.uploadHandler = output();
|
|
30
|
+
/** Se emite con los archivos descartados por tamaño (`maxFileSize`) o tipo (`accept`). */
|
|
31
|
+
this.rejectFiles = output();
|
|
25
32
|
this.files = signal([], /* @ts-ignore */
|
|
26
33
|
...(ngDevMode ? [{ debugName: "files" }] : /* istanbul ignore next */ []));
|
|
34
|
+
/** Archivos descartados en la última selección (se muestran como aviso). */
|
|
35
|
+
this.rejected = signal([], /* @ts-ignore */
|
|
36
|
+
...(ngDevMode ? [{ debugName: "rejected" }] : /* istanbul ignore next */ []));
|
|
27
37
|
this.dragging = signal(false, /* @ts-ignore */
|
|
28
38
|
...(ngDevMode ? [{ debugName: "dragging" }] : /* istanbul ignore next */ []));
|
|
29
39
|
this.fileInputRef = viewChild('fileInput', /* @ts-ignore */
|
|
@@ -60,10 +70,28 @@ class CbFileUpload {
|
|
|
60
70
|
this.addFiles(Array.from(dropped));
|
|
61
71
|
}
|
|
62
72
|
}
|
|
73
|
+
/** Añade archivos validando `accept` y `maxFileSize`; ignora los repetidos. */
|
|
63
74
|
addFiles(incoming) {
|
|
64
75
|
const max = this.maxFileSize();
|
|
65
|
-
const valid =
|
|
66
|
-
const
|
|
76
|
+
const valid = [];
|
|
77
|
+
const rejected = [];
|
|
78
|
+
for (const file of incoming) {
|
|
79
|
+
if (!this.isAccepted(file))
|
|
80
|
+
rejected.push({ file, reason: 'type' });
|
|
81
|
+
else if (max != null && file.size > max)
|
|
82
|
+
rejected.push({ file, reason: 'size' });
|
|
83
|
+
else
|
|
84
|
+
valid.push(file);
|
|
85
|
+
}
|
|
86
|
+
this.rejected.set(rejected);
|
|
87
|
+
if (rejected.length)
|
|
88
|
+
this.rejectFiles.emit({ files: rejected });
|
|
89
|
+
if (!valid.length)
|
|
90
|
+
return;
|
|
91
|
+
const same = (a, b) => a.name === b.name && a.size === b.size && a.lastModified === b.lastModified;
|
|
92
|
+
const next = this.multiple()
|
|
93
|
+
? [...this.files(), ...valid.filter((f, i) => !this.files().some((e) => same(e, f)) && valid.findIndex((v) => same(v, f)) === i)]
|
|
94
|
+
: valid.slice(0, 1);
|
|
67
95
|
this.files.set(next);
|
|
68
96
|
this.selectFiles.emit({ files: next });
|
|
69
97
|
}
|
|
@@ -73,6 +101,7 @@ class CbFileUpload {
|
|
|
73
101
|
}
|
|
74
102
|
clear() {
|
|
75
103
|
this.files.set([]);
|
|
104
|
+
this.rejected.set([]);
|
|
76
105
|
}
|
|
77
106
|
triggerUpload() {
|
|
78
107
|
this.uploadHandler.emit({ files: [...this.files()] });
|
|
@@ -80,10 +109,30 @@ class CbFileUpload {
|
|
|
80
109
|
formatSize(bytes) {
|
|
81
110
|
if (bytes < 1024)
|
|
82
111
|
return `${bytes} B`;
|
|
83
|
-
|
|
112
|
+
if (bytes < 1024 * 1024)
|
|
113
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
114
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
115
|
+
}
|
|
116
|
+
/** Comprueba `accept` (extensiones `.pdf`, tipos `image/png` o comodines `image/*`). */
|
|
117
|
+
isAccepted(file) {
|
|
118
|
+
const rules = this.accept()
|
|
119
|
+
.split(',')
|
|
120
|
+
.map((r) => r.trim().toLowerCase())
|
|
121
|
+
.filter(Boolean);
|
|
122
|
+
if (!rules.length)
|
|
123
|
+
return true;
|
|
124
|
+
const name = file.name.toLowerCase();
|
|
125
|
+
const type = (file.type || '').toLowerCase();
|
|
126
|
+
return rules.some((rule) => {
|
|
127
|
+
if (rule.startsWith('.'))
|
|
128
|
+
return name.endsWith(rule);
|
|
129
|
+
if (rule.endsWith('/*'))
|
|
130
|
+
return type.startsWith(rule.slice(0, -1));
|
|
131
|
+
return type === rule;
|
|
132
|
+
});
|
|
84
133
|
}
|
|
85
134
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: CbFileUpload, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
86
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: CbFileUpload, isStandalone: true, selector: "cb-file-upload", inputs: { accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, maxFileSize: { classPropertyName: "maxFileSize", publicName: "maxFileSize", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, chooseLabel: { classPropertyName: "chooseLabel", publicName: "chooseLabel", isSignal: true, isRequired: false, transformFunction: null }, uploadLabel: { classPropertyName: "uploadLabel", publicName: "uploadLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectFiles: "selectFiles", uploadHandler: "uploadHandler" }, host: { properties: { "class.cb-is-dragover": "dragging()" }, classAttribute: "cb-file-upload" }, viewQueries: [{ propertyName: "fileInputRef", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
135
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: CbFileUpload, isStandalone: true, selector: "cb-file-upload", inputs: { accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, maxFileSize: { classPropertyName: "maxFileSize", publicName: "maxFileSize", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, chooseLabel: { classPropertyName: "chooseLabel", publicName: "chooseLabel", isSignal: true, isRequired: false, transformFunction: null }, uploadLabel: { classPropertyName: "uploadLabel", publicName: "uploadLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectFiles: "selectFiles", uploadHandler: "uploadHandler", rejectFiles: "rejectFiles" }, host: { properties: { "class.cb-is-dragover": "dragging()" }, classAttribute: "cb-file-upload" }, viewQueries: [{ propertyName: "fileInputRef", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
87
136
|
<input
|
|
88
137
|
#fileInput
|
|
89
138
|
type="file"
|
|
@@ -107,7 +156,7 @@ class CbFileUpload {
|
|
|
107
156
|
(click)="openPicker()"
|
|
108
157
|
>
|
|
109
158
|
<cb-icon name="upload" [size]="15" aria-hidden="true" />
|
|
110
|
-
<span>{{ chooseLabel() }}</span>
|
|
159
|
+
<span>{{ (chooseLabel() ?? t().chooseFile) }}</span>
|
|
111
160
|
</button>
|
|
112
161
|
@if (files().length > 0) {
|
|
113
162
|
<button
|
|
@@ -117,7 +166,7 @@ class CbFileUpload {
|
|
|
117
166
|
(click)="triggerUpload()"
|
|
118
167
|
>
|
|
119
168
|
<cb-icon name="check" [size]="15" aria-hidden="true" />
|
|
120
|
-
<span>{{ uploadLabel() }}</span>
|
|
169
|
+
<span>{{ (uploadLabel() ?? t().upload) }}</span>
|
|
121
170
|
</button>
|
|
122
171
|
<button
|
|
123
172
|
type="button"
|
|
@@ -126,13 +175,27 @@ class CbFileUpload {
|
|
|
126
175
|
(click)="clear()"
|
|
127
176
|
>
|
|
128
177
|
<cb-icon name="x" [size]="15" aria-hidden="true" />
|
|
129
|
-
<span>
|
|
178
|
+
<span>{{ t().clear }}</span>
|
|
130
179
|
</button>
|
|
131
180
|
}
|
|
132
181
|
</div>
|
|
133
182
|
|
|
183
|
+
@if (rejected().length) {
|
|
184
|
+
<ul class="cb-file-upload__errors" role="alert">
|
|
185
|
+
@for (r of rejected(); track $index) {
|
|
186
|
+
<li>
|
|
187
|
+
{{
|
|
188
|
+
r.reason === 'size'
|
|
189
|
+
? fmt(t().fileTooLarge, r.file.name, formatSize(maxFileSize() ?? 0))
|
|
190
|
+
: fmt(t().fileTypeNotAllowed, r.file.name)
|
|
191
|
+
}}
|
|
192
|
+
</li>
|
|
193
|
+
}
|
|
194
|
+
</ul>
|
|
195
|
+
}
|
|
196
|
+
|
|
134
197
|
@if (files().length === 0) {
|
|
135
|
-
<p class="cb-file-upload__empty">
|
|
198
|
+
<p class="cb-file-upload__empty">{{ fmt(t().dropFiles, (chooseLabel() ?? t().chooseFile)) }}</p>
|
|
136
199
|
} @else {
|
|
137
200
|
<ul class="cb-file-upload__list">
|
|
138
201
|
@for (file of files(); track file.name + file.size; let idx = $index) {
|
|
@@ -142,7 +205,7 @@ class CbFileUpload {
|
|
|
142
205
|
<button
|
|
143
206
|
type="button"
|
|
144
207
|
class="cb-file-upload__remove"
|
|
145
|
-
[attr.aria-label]="
|
|
208
|
+
[attr.aria-label]="fmt(t().removeItem, file.name)"
|
|
146
209
|
(click)="removeAt(idx)"
|
|
147
210
|
>
|
|
148
211
|
<cb-icon name="x" [size]="14" aria-hidden="true" />
|
|
@@ -152,7 +215,7 @@ class CbFileUpload {
|
|
|
152
215
|
</ul>
|
|
153
216
|
}
|
|
154
217
|
</div>
|
|
155
|
-
`, isInline: true, styles: [":host{display:block;width:100%;font-family:var(--cb-font-sans)}.cb-file-upload__native{display:none}.cb-file-upload__dropzone{padding:var(--cb-space-4);border:1px dashed var(--cb-color-border);border-radius:var(--cb-radius-lg);background:var(--cb-color-surface);color:var(--cb-color-text);transition:border-color .14s ease,background-color .14s ease}:host(.cb-is-dragover) .cb-file-upload__dropzone{border-color:var(--cb-color-primary-500);background:color-mix(in srgb,var(--cb-color-primary-500) 8%,transparent)}.cb-file-upload__actions{display:flex;flex-wrap:wrap;gap:var(--cb-space-2);margin-bottom:var(--cb-space-3)}.cb-file-upload__btn{display:inline-flex;align-items:center;gap:.375rem;padding:.4rem .75rem;border:var(--cb-border-width) solid var(--cb-color-border);border-radius:var(--cb-radius-md);background:var(--cb-color-surface);color:var(--cb-color-text);font-family:inherit;font-size:var(--cb-text-sm);font-weight:var(--cb-font-medium);cursor:pointer}.cb-file-upload__btn--primary{background:var(--cb-color-primary-500);border-color:var(--cb-color-primary-500);color:var(--cb-color-primary-contrast, #fff)}.cb-file-upload__empty{margin:0;font-size:var(--cb-text-sm);color:var(--cb-color-text-muted)}.cb-file-upload__list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.375rem}.cb-file-upload__item{display:flex;align-items:center;justify-content:space-between;gap:var(--cb-space-2);padding:.375rem .625rem;border:var(--cb-border-width) solid var(--cb-color-border);border-radius:var(--cb-radius-md);font-size:var(--cb-text-sm)}.cb-file-upload__size{margin-left:auto;color:var(--cb-color-text-muted);font-size:.75rem}.cb-file-upload__remove{border:none;background:transparent;color:var(--cb-color-text-muted);cursor:pointer;padding:.125rem}\n"], dependencies: [{ kind: "component", type: CbIcon, selector: "cb-icon", inputs: ["name", "size", "spin", "ariaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
218
|
+
`, isInline: true, styles: [":host{display:block;width:100%;font-family:var(--cb-font-sans)}.cb-file-upload__native{display:none}.cb-file-upload__dropzone{padding:var(--cb-space-4);border:1px dashed var(--cb-color-border);border-radius:var(--cb-radius-lg);background:var(--cb-color-surface);color:var(--cb-color-text);transition:border-color .14s ease,background-color .14s ease}:host(.cb-is-dragover) .cb-file-upload__dropzone{border-color:var(--cb-color-primary-500);background:color-mix(in srgb,var(--cb-color-primary-500) 8%,transparent)}.cb-file-upload__actions{display:flex;flex-wrap:wrap;gap:var(--cb-space-2);margin-bottom:var(--cb-space-3)}.cb-file-upload__btn{display:inline-flex;align-items:center;gap:.375rem;padding:.4rem .75rem;border:var(--cb-border-width) solid var(--cb-color-border);border-radius:var(--cb-radius-md);background:var(--cb-color-surface);color:var(--cb-color-text);font-family:inherit;font-size:var(--cb-text-sm);font-weight:var(--cb-font-medium);cursor:pointer}.cb-file-upload__btn--primary{background:var(--cb-color-primary-500);border-color:var(--cb-color-primary-500);color:var(--cb-color-primary-contrast, #fff)}.cb-file-upload__errors{list-style:none;margin:0;padding:0;display:grid;gap:.25rem;font-size:var(--cb-text-sm);color:var(--cb-color-danger)}.cb-file-upload__empty{margin:0;font-size:var(--cb-text-sm);color:var(--cb-color-text-muted)}.cb-file-upload__list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.375rem}.cb-file-upload__item{display:flex;align-items:center;justify-content:space-between;gap:var(--cb-space-2);padding:.375rem .625rem;border:var(--cb-border-width) solid var(--cb-color-border);border-radius:var(--cb-radius-md);font-size:var(--cb-text-sm)}.cb-file-upload__size{margin-left:auto;color:var(--cb-color-text-muted);font-size:.75rem}.cb-file-upload__remove{border:none;background:transparent;color:var(--cb-color-text-muted);cursor:pointer;padding:.125rem}\n"], dependencies: [{ kind: "component", type: CbIcon, selector: "cb-icon", inputs: ["name", "size", "spin", "ariaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
156
219
|
}
|
|
157
220
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: CbFileUpload, decorators: [{
|
|
158
221
|
type: Component,
|
|
@@ -183,7 +246,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
183
246
|
(click)="openPicker()"
|
|
184
247
|
>
|
|
185
248
|
<cb-icon name="upload" [size]="15" aria-hidden="true" />
|
|
186
|
-
<span>{{ chooseLabel() }}</span>
|
|
249
|
+
<span>{{ (chooseLabel() ?? t().chooseFile) }}</span>
|
|
187
250
|
</button>
|
|
188
251
|
@if (files().length > 0) {
|
|
189
252
|
<button
|
|
@@ -193,7 +256,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
193
256
|
(click)="triggerUpload()"
|
|
194
257
|
>
|
|
195
258
|
<cb-icon name="check" [size]="15" aria-hidden="true" />
|
|
196
|
-
<span>{{ uploadLabel() }}</span>
|
|
259
|
+
<span>{{ (uploadLabel() ?? t().upload) }}</span>
|
|
197
260
|
</button>
|
|
198
261
|
<button
|
|
199
262
|
type="button"
|
|
@@ -202,13 +265,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
202
265
|
(click)="clear()"
|
|
203
266
|
>
|
|
204
267
|
<cb-icon name="x" [size]="15" aria-hidden="true" />
|
|
205
|
-
<span>
|
|
268
|
+
<span>{{ t().clear }}</span>
|
|
206
269
|
</button>
|
|
207
270
|
}
|
|
208
271
|
</div>
|
|
209
272
|
|
|
273
|
+
@if (rejected().length) {
|
|
274
|
+
<ul class="cb-file-upload__errors" role="alert">
|
|
275
|
+
@for (r of rejected(); track $index) {
|
|
276
|
+
<li>
|
|
277
|
+
{{
|
|
278
|
+
r.reason === 'size'
|
|
279
|
+
? fmt(t().fileTooLarge, r.file.name, formatSize(maxFileSize() ?? 0))
|
|
280
|
+
: fmt(t().fileTypeNotAllowed, r.file.name)
|
|
281
|
+
}}
|
|
282
|
+
</li>
|
|
283
|
+
}
|
|
284
|
+
</ul>
|
|
285
|
+
}
|
|
286
|
+
|
|
210
287
|
@if (files().length === 0) {
|
|
211
|
-
<p class="cb-file-upload__empty">
|
|
288
|
+
<p class="cb-file-upload__empty">{{ fmt(t().dropFiles, (chooseLabel() ?? t().chooseFile)) }}</p>
|
|
212
289
|
} @else {
|
|
213
290
|
<ul class="cb-file-upload__list">
|
|
214
291
|
@for (file of files(); track file.name + file.size; let idx = $index) {
|
|
@@ -218,7 +295,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
218
295
|
<button
|
|
219
296
|
type="button"
|
|
220
297
|
class="cb-file-upload__remove"
|
|
221
|
-
[attr.aria-label]="
|
|
298
|
+
[attr.aria-label]="fmt(t().removeItem, file.name)"
|
|
222
299
|
(click)="removeAt(idx)"
|
|
223
300
|
>
|
|
224
301
|
<cb-icon name="x" [size]="14" aria-hidden="true" />
|
|
@@ -228,8 +305,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
228
305
|
</ul>
|
|
229
306
|
}
|
|
230
307
|
</div>
|
|
231
|
-
`, styles: [":host{display:block;width:100%;font-family:var(--cb-font-sans)}.cb-file-upload__native{display:none}.cb-file-upload__dropzone{padding:var(--cb-space-4);border:1px dashed var(--cb-color-border);border-radius:var(--cb-radius-lg);background:var(--cb-color-surface);color:var(--cb-color-text);transition:border-color .14s ease,background-color .14s ease}:host(.cb-is-dragover) .cb-file-upload__dropzone{border-color:var(--cb-color-primary-500);background:color-mix(in srgb,var(--cb-color-primary-500) 8%,transparent)}.cb-file-upload__actions{display:flex;flex-wrap:wrap;gap:var(--cb-space-2);margin-bottom:var(--cb-space-3)}.cb-file-upload__btn{display:inline-flex;align-items:center;gap:.375rem;padding:.4rem .75rem;border:var(--cb-border-width) solid var(--cb-color-border);border-radius:var(--cb-radius-md);background:var(--cb-color-surface);color:var(--cb-color-text);font-family:inherit;font-size:var(--cb-text-sm);font-weight:var(--cb-font-medium);cursor:pointer}.cb-file-upload__btn--primary{background:var(--cb-color-primary-500);border-color:var(--cb-color-primary-500);color:var(--cb-color-primary-contrast, #fff)}.cb-file-upload__empty{margin:0;font-size:var(--cb-text-sm);color:var(--cb-color-text-muted)}.cb-file-upload__list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.375rem}.cb-file-upload__item{display:flex;align-items:center;justify-content:space-between;gap:var(--cb-space-2);padding:.375rem .625rem;border:var(--cb-border-width) solid var(--cb-color-border);border-radius:var(--cb-radius-md);font-size:var(--cb-text-sm)}.cb-file-upload__size{margin-left:auto;color:var(--cb-color-text-muted);font-size:.75rem}.cb-file-upload__remove{border:none;background:transparent;color:var(--cb-color-text-muted);cursor:pointer;padding:.125rem}\n"] }]
|
|
232
|
-
}], propDecorators: { accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], maxFileSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFileSize", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], chooseLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "chooseLabel", required: false }] }], uploadLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "uploadLabel", required: false }] }], selectFiles: [{ type: i0.Output, args: ["selectFiles"] }], uploadHandler: [{ type: i0.Output, args: ["uploadHandler"] }], fileInputRef: [{ type: i0.ViewChild, args: ['fileInput', { isSignal: true }] }] } });
|
|
308
|
+
`, styles: [":host{display:block;width:100%;font-family:var(--cb-font-sans)}.cb-file-upload__native{display:none}.cb-file-upload__dropzone{padding:var(--cb-space-4);border:1px dashed var(--cb-color-border);border-radius:var(--cb-radius-lg);background:var(--cb-color-surface);color:var(--cb-color-text);transition:border-color .14s ease,background-color .14s ease}:host(.cb-is-dragover) .cb-file-upload__dropzone{border-color:var(--cb-color-primary-500);background:color-mix(in srgb,var(--cb-color-primary-500) 8%,transparent)}.cb-file-upload__actions{display:flex;flex-wrap:wrap;gap:var(--cb-space-2);margin-bottom:var(--cb-space-3)}.cb-file-upload__btn{display:inline-flex;align-items:center;gap:.375rem;padding:.4rem .75rem;border:var(--cb-border-width) solid var(--cb-color-border);border-radius:var(--cb-radius-md);background:var(--cb-color-surface);color:var(--cb-color-text);font-family:inherit;font-size:var(--cb-text-sm);font-weight:var(--cb-font-medium);cursor:pointer}.cb-file-upload__btn--primary{background:var(--cb-color-primary-500);border-color:var(--cb-color-primary-500);color:var(--cb-color-primary-contrast, #fff)}.cb-file-upload__errors{list-style:none;margin:0;padding:0;display:grid;gap:.25rem;font-size:var(--cb-text-sm);color:var(--cb-color-danger)}.cb-file-upload__empty{margin:0;font-size:var(--cb-text-sm);color:var(--cb-color-text-muted)}.cb-file-upload__list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.375rem}.cb-file-upload__item{display:flex;align-items:center;justify-content:space-between;gap:var(--cb-space-2);padding:.375rem .625rem;border:var(--cb-border-width) solid var(--cb-color-border);border-radius:var(--cb-radius-md);font-size:var(--cb-text-sm)}.cb-file-upload__size{margin-left:auto;color:var(--cb-color-text-muted);font-size:.75rem}.cb-file-upload__remove{border:none;background:transparent;color:var(--cb-color-text-muted);cursor:pointer;padding:.125rem}\n"] }]
|
|
309
|
+
}], propDecorators: { accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], maxFileSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFileSize", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], chooseLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "chooseLabel", required: false }] }], uploadLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "uploadLabel", required: false }] }], selectFiles: [{ type: i0.Output, args: ["selectFiles"] }], uploadHandler: [{ type: i0.Output, args: ["uploadHandler"] }], rejectFiles: [{ type: i0.Output, args: ["rejectFiles"] }], fileInputRef: [{ type: i0.ViewChild, args: ['fileInput', { isSignal: true }] }] } });
|
|
233
310
|
|
|
234
311
|
/**
|
|
235
312
|
* Generated bundle index. Do not edit.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, ElementRef, input, signal,
|
|
2
|
+
import { inject, ElementRef, input, signal, afterEveryRender, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* FloatLabel de CaribeNG: contenedor que eleva visualmente la etiqueta `<label>`
|
|
@@ -14,7 +14,9 @@ class CbFloatLabel {
|
|
|
14
14
|
...(ngDevMode ? [{ debugName: "focused" }] : /* istanbul ignore next */ []));
|
|
15
15
|
this.filled = signal(false, /* @ts-ignore */
|
|
16
16
|
...(ngDevMode ? [{ debugName: "filled" }] : /* istanbul ignore next */ []));
|
|
17
|
-
|
|
17
|
+
// Tras cada render: detecta también valores asignados por código (p. ej. `patchValue`),
|
|
18
|
+
// que no disparan los eventos `input` / `change`.
|
|
19
|
+
afterEveryRender(() => {
|
|
18
20
|
this.checkFilled();
|
|
19
21
|
});
|
|
20
22
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { input, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
3
|
import { CbIcon } from '@caribeng/ui/icon';
|
|
4
|
+
import { injectCbTranslation } from '@caribeng/ui';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Tarjeta de carpeta de CaribeNG: icono de carpeta, nombre y una fila con
|
|
@@ -15,6 +16,8 @@ import { CbIcon } from '@caribeng/ui/icon';
|
|
|
15
16
|
*/
|
|
16
17
|
class CbFolderCard {
|
|
17
18
|
constructor() {
|
|
19
|
+
/** Textos de interfaz en el idioma activo (`provideCaribeNG({ locale })`). */
|
|
20
|
+
this.t = injectCbTranslation();
|
|
18
21
|
/** Nombre de la carpeta. */
|
|
19
22
|
this.name = input('', /* @ts-ignore */
|
|
20
23
|
...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
|
|
@@ -22,7 +25,7 @@ class CbFolderCard {
|
|
|
22
25
|
this.files = input('', /* @ts-ignore */
|
|
23
26
|
...(ngDevMode ? [{ debugName: "files" }] : /* istanbul ignore next */ []));
|
|
24
27
|
/** Etiqueta tras el número de archivos. */
|
|
25
|
-
this.filesLabel = input(
|
|
28
|
+
this.filesLabel = input(undefined, /* @ts-ignore */
|
|
26
29
|
...(ngDevMode ? [{ debugName: "filesLabel" }] : /* istanbul ignore next */ []));
|
|
27
30
|
/** Tamaño mostrado a la derecha. */
|
|
28
31
|
this.size = input('', /* @ts-ignore */
|
|
@@ -41,7 +44,9 @@ class CbFolderCard {
|
|
|
41
44
|
</div>
|
|
42
45
|
<div class="cb-folder-card__name">{{ name() }}</div>
|
|
43
46
|
<div class="cb-folder-card__meta">
|
|
44
|
-
|
|
47
|
+
@if (files() !== '') {
|
|
48
|
+
<span>{{ files() }} {{ (filesLabel() ?? t().files) }}</span>
|
|
49
|
+
}
|
|
45
50
|
@if (size()) {
|
|
46
51
|
<span>{{ size() }}</span>
|
|
47
52
|
}
|
|
@@ -59,7 +64,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
59
64
|
</div>
|
|
60
65
|
<div class="cb-folder-card__name">{{ name() }}</div>
|
|
61
66
|
<div class="cb-folder-card__meta">
|
|
62
|
-
|
|
67
|
+
@if (files() !== '') {
|
|
68
|
+
<span>{{ files() }} {{ (filesLabel() ?? t().files) }}</span>
|
|
69
|
+
}
|
|
63
70
|
@if (size()) {
|
|
64
71
|
<span>{{ size() }}</span>
|
|
65
72
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, model, computed, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
2
|
+
import { input, model, inject, ElementRef, computed, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
3
|
import { CbIcon } from '@caribeng/ui/icon';
|
|
4
|
+
import { injectCbTranslation, cbFormat } from '@caribeng/ui';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Galleria de CaribeNG: galería de imágenes con visor principal, leyenda y
|
|
@@ -8,6 +9,10 @@ import { CbIcon } from '@caribeng/ui/icon';
|
|
|
8
9
|
*/
|
|
9
10
|
class CbGalleria {
|
|
10
11
|
constructor() {
|
|
12
|
+
/** Textos de interfaz en el idioma activo (`provideCaribeNG({ locale })`). */
|
|
13
|
+
this.t = injectCbTranslation();
|
|
14
|
+
/** Rellena `{0}`, `{1}`… de un texto traducido. */
|
|
15
|
+
this.fmt = cbFormat;
|
|
11
16
|
this.value = input([], /* @ts-ignore */
|
|
12
17
|
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
13
18
|
this.showThumbnails = input(true, /* @ts-ignore */
|
|
@@ -16,6 +21,7 @@ class CbGalleria {
|
|
|
16
21
|
...(ngDevMode ? [{ debugName: "circular" }] : /* istanbul ignore next */ []));
|
|
17
22
|
this.activeIndex = model(0, /* @ts-ignore */
|
|
18
23
|
...(ngDevMode ? [{ debugName: "activeIndex" }] : /* istanbul ignore next */ []));
|
|
24
|
+
this.host = inject(ElementRef);
|
|
19
25
|
this.activeItem = computed(() => this.value()[this.activeIndex()] ?? this.value()[0] ?? null, /* @ts-ignore */
|
|
20
26
|
...(ngDevMode ? [{ debugName: "activeItem" }] : /* istanbul ignore next */ []));
|
|
21
27
|
}
|
|
@@ -39,31 +45,52 @@ class CbGalleria {
|
|
|
39
45
|
else if (this.circular())
|
|
40
46
|
this.activeIndex.set(0);
|
|
41
47
|
}
|
|
48
|
+
/** Miniaturas (patrón *tabs*): flechas, Inicio y Fin cambian de imagen y mueven el foco. */
|
|
49
|
+
onThumbKeydown(event) {
|
|
50
|
+
const last = this.value().length - 1;
|
|
51
|
+
const cur = this.activeIndex();
|
|
52
|
+
const target = event.key === 'ArrowRight' ? (cur < last ? cur + 1 : 0)
|
|
53
|
+
: event.key === 'ArrowLeft' ? (cur > 0 ? cur - 1 : last)
|
|
54
|
+
: event.key === 'Home' ? 0
|
|
55
|
+
: event.key === 'End' ? last
|
|
56
|
+
: null;
|
|
57
|
+
if (target === null)
|
|
58
|
+
return;
|
|
59
|
+
event.preventDefault();
|
|
60
|
+
this.activeIndex.set(target);
|
|
61
|
+
this.host.nativeElement.querySelectorAll('.cb-galleria__thumb')[target]?.focus();
|
|
62
|
+
}
|
|
42
63
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: CbGalleria, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
43
64
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: CbGalleria, isStandalone: true, selector: "cb-galleria", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, showThumbnails: { classPropertyName: "showThumbnails", publicName: "showThumbnails", isSignal: true, isRequired: false, transformFunction: null }, circular: { classPropertyName: "circular", publicName: "circular", isSignal: true, isRequired: false, transformFunction: null }, activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeIndex: "activeIndexChange" }, host: { classAttribute: "cb-galleria" }, ngImport: i0, template: `
|
|
44
65
|
@if (activeItem(); as current) {
|
|
45
66
|
<div class="cb-galleria__stage">
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
67
|
+
@if (value().length > 1) {
|
|
68
|
+
<button
|
|
69
|
+
type="button"
|
|
70
|
+
class="cb-galleria__nav cb-galleria__nav--prev"
|
|
71
|
+
[attr.aria-label]="t().previousImage"
|
|
72
|
+
[disabled]="!circular() && activeIndex() === 0"
|
|
73
|
+
(click)="prev()"
|
|
74
|
+
>
|
|
75
|
+
<cb-icon name="chevron-left" [size]="18" aria-hidden="true" />
|
|
76
|
+
</button>
|
|
77
|
+
}
|
|
54
78
|
<img
|
|
55
79
|
class="cb-galleria__main-img"
|
|
56
80
|
[src]="current.itemImageSrc"
|
|
57
81
|
[alt]="current.alt || current.title || ''"
|
|
58
82
|
/>
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
83
|
+
@if (value().length > 1) {
|
|
84
|
+
<button
|
|
85
|
+
type="button"
|
|
86
|
+
class="cb-galleria__nav cb-galleria__nav--next"
|
|
87
|
+
[attr.aria-label]="t().nextImage"
|
|
88
|
+
[disabled]="!circular() && activeIndex() === value().length - 1"
|
|
89
|
+
(click)="next()"
|
|
90
|
+
>
|
|
91
|
+
<cb-icon name="chevron-right" [size]="18" aria-hidden="true" />
|
|
92
|
+
</button>
|
|
93
|
+
}
|
|
67
94
|
@if (current.title) {
|
|
68
95
|
<div class="cb-galleria__caption">{{ current.title }}</div>
|
|
69
96
|
}
|
|
@@ -71,20 +98,19 @@ class CbGalleria {
|
|
|
71
98
|
}
|
|
72
99
|
@if (showThumbnails() && value().length > 1) {
|
|
73
100
|
<div class="cb-galleria__thumbs" role="tablist">
|
|
74
|
-
@for (item of value(); track
|
|
101
|
+
@for (item of value(); track $index; let idx = $index) {
|
|
75
102
|
<button
|
|
76
103
|
type="button"
|
|
77
104
|
class="cb-galleria__thumb"
|
|
78
105
|
role="tab"
|
|
79
106
|
[class.cb-is-active]="activeIndex() === idx"
|
|
80
107
|
[attr.aria-selected]="activeIndex() === idx"
|
|
81
|
-
[attr.
|
|
108
|
+
[attr.tabindex]="activeIndex() === idx ? 0 : -1"
|
|
109
|
+
[attr.aria-label]="item.title || item.alt || fmt(t().thumbnail, idx + 1)"
|
|
82
110
|
(click)="activeIndex.set(idx)"
|
|
111
|
+
(keydown)="onThumbKeydown($event)"
|
|
83
112
|
>
|
|
84
|
-
<img
|
|
85
|
-
[src]="item.thumbnailImageSrc || item.itemImageSrc"
|
|
86
|
-
[alt]="item.alt || item.title || ''"
|
|
87
|
-
/>
|
|
113
|
+
<img [src]="item.thumbnailImageSrc || item.itemImageSrc" alt="" />
|
|
88
114
|
</button>
|
|
89
115
|
}
|
|
90
116
|
</div>
|
|
@@ -96,27 +122,33 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
96
122
|
args: [{ selector: 'cb-galleria', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.Emulated, imports: [CbIcon], host: { class: 'cb-galleria' }, template: `
|
|
97
123
|
@if (activeItem(); as current) {
|
|
98
124
|
<div class="cb-galleria__stage">
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
125
|
+
@if (value().length > 1) {
|
|
126
|
+
<button
|
|
127
|
+
type="button"
|
|
128
|
+
class="cb-galleria__nav cb-galleria__nav--prev"
|
|
129
|
+
[attr.aria-label]="t().previousImage"
|
|
130
|
+
[disabled]="!circular() && activeIndex() === 0"
|
|
131
|
+
(click)="prev()"
|
|
132
|
+
>
|
|
133
|
+
<cb-icon name="chevron-left" [size]="18" aria-hidden="true" />
|
|
134
|
+
</button>
|
|
135
|
+
}
|
|
107
136
|
<img
|
|
108
137
|
class="cb-galleria__main-img"
|
|
109
138
|
[src]="current.itemImageSrc"
|
|
110
139
|
[alt]="current.alt || current.title || ''"
|
|
111
140
|
/>
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
141
|
+
@if (value().length > 1) {
|
|
142
|
+
<button
|
|
143
|
+
type="button"
|
|
144
|
+
class="cb-galleria__nav cb-galleria__nav--next"
|
|
145
|
+
[attr.aria-label]="t().nextImage"
|
|
146
|
+
[disabled]="!circular() && activeIndex() === value().length - 1"
|
|
147
|
+
(click)="next()"
|
|
148
|
+
>
|
|
149
|
+
<cb-icon name="chevron-right" [size]="18" aria-hidden="true" />
|
|
150
|
+
</button>
|
|
151
|
+
}
|
|
120
152
|
@if (current.title) {
|
|
121
153
|
<div class="cb-galleria__caption">{{ current.title }}</div>
|
|
122
154
|
}
|
|
@@ -124,20 +156,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
124
156
|
}
|
|
125
157
|
@if (showThumbnails() && value().length > 1) {
|
|
126
158
|
<div class="cb-galleria__thumbs" role="tablist">
|
|
127
|
-
@for (item of value(); track
|
|
159
|
+
@for (item of value(); track $index; let idx = $index) {
|
|
128
160
|
<button
|
|
129
161
|
type="button"
|
|
130
162
|
class="cb-galleria__thumb"
|
|
131
163
|
role="tab"
|
|
132
164
|
[class.cb-is-active]="activeIndex() === idx"
|
|
133
165
|
[attr.aria-selected]="activeIndex() === idx"
|
|
134
|
-
[attr.
|
|
166
|
+
[attr.tabindex]="activeIndex() === idx ? 0 : -1"
|
|
167
|
+
[attr.aria-label]="item.title || item.alt || fmt(t().thumbnail, idx + 1)"
|
|
135
168
|
(click)="activeIndex.set(idx)"
|
|
169
|
+
(keydown)="onThumbKeydown($event)"
|
|
136
170
|
>
|
|
137
|
-
<img
|
|
138
|
-
[src]="item.thumbnailImageSrc || item.itemImageSrc"
|
|
139
|
-
[alt]="item.alt || item.title || ''"
|
|
140
|
-
/>
|
|
171
|
+
<img [src]="item.thumbnailImageSrc || item.itemImageSrc" alt="" />
|
|
141
172
|
</button>
|
|
142
173
|
}
|
|
143
174
|
</div>
|