@muxima-ui/core 1.4.1 → 1.5.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 +11 -0
- package/fesm2022/muxima-ui-core-alert.mjs +5 -3
- package/fesm2022/muxima-ui-core-alert.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-breadcrumb.mjs +5 -3
- package/fesm2022/muxima-ui-core-breadcrumb.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-carousel.mjs +19 -17
- package/fesm2022/muxima-ui-core-carousel.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-chips.mjs +19 -14
- package/fesm2022/muxima-ui-core-chips.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-clipboard.mjs +10 -6
- package/fesm2022/muxima-ui-core-clipboard.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-color-picker.mjs +53 -50
- package/fesm2022/muxima-ui-core-color-picker.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-combobox.mjs +15 -12
- package/fesm2022/muxima-ui-core-combobox.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-command.mjs +21 -16
- package/fesm2022/muxima-ui-core-command.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-data-grid.mjs +50 -52
- package/fesm2022/muxima-ui-core-data-grid.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-date-picker.mjs +97 -69
- package/fesm2022/muxima-ui-core-date-picker.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-editor.mjs +25 -19
- package/fesm2022/muxima-ui-core-editor.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-file-upload.mjs +30 -25
- package/fesm2022/muxima-ui-core-file-upload.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-i18n.mjs +550 -0
- package/fesm2022/muxima-ui-core-i18n.mjs.map +1 -0
- package/fesm2022/muxima-ui-core-image-cropper.mjs +27 -24
- package/fesm2022/muxima-ui-core-image-cropper.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-kanban.mjs +22 -19
- package/fesm2022/muxima-ui-core-kanban.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-notification-center.mjs +41 -36
- package/fesm2022/muxima-ui-core-notification-center.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-pagination.mjs +29 -26
- package/fesm2022/muxima-ui-core-pagination.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-progress.mjs +5 -3
- package/fesm2022/muxima-ui-core-progress.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-rating.mjs +12 -8
- package/fesm2022/muxima-ui-core-rating.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-select.mjs +14 -11
- package/fesm2022/muxima-ui-core-select.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-sidebar.mjs +10 -7
- package/fesm2022/muxima-ui-core-sidebar.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-slider.mjs +8 -6
- package/fesm2022/muxima-ui-core-slider.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-stepper.mjs +5 -3
- package/fesm2022/muxima-ui-core-stepper.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-table.mjs +4 -4
- package/fesm2022/muxima-ui-core-table.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-time-picker.mjs +7 -5
- package/fesm2022/muxima-ui-core-time-picker.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-toast.mjs +8 -5
- package/fesm2022/muxima-ui-core-toast.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-tour.mjs +10 -11
- package/fesm2022/muxima-ui-core-tour.mjs.map +1 -1
- package/fesm2022/muxima-ui-core.mjs +1 -1
- package/fesm2022/muxima-ui-core.mjs.map +1 -1
- package/package.json +5 -1
- package/types/muxima-ui-core-alert.d.ts +3 -1
- package/types/muxima-ui-core-breadcrumb.d.ts +6 -4
- package/types/muxima-ui-core-carousel.d.ts +4 -2
- package/types/muxima-ui-core-chips.d.ts +23 -3
- package/types/muxima-ui-core-clipboard.d.ts +6 -3
- package/types/muxima-ui-core-color-picker.d.ts +40 -7
- package/types/muxima-ui-core-combobox.d.ts +6 -3
- package/types/muxima-ui-core-command.d.ts +7 -3
- package/types/muxima-ui-core-data-grid.d.ts +31 -11
- package/types/muxima-ui-core-date-picker.d.ts +59 -14
- package/types/muxima-ui-core-editor.d.ts +13 -2
- package/types/muxima-ui-core-file-upload.d.ts +22 -6
- package/types/muxima-ui-core-i18n.d.ts +322 -0
- package/types/muxima-ui-core-image-cropper.d.ts +19 -6
- package/types/muxima-ui-core-kanban.d.ts +16 -3
- package/types/muxima-ui-core-notification-center.d.ts +30 -8
- package/types/muxima-ui-core-pagination.d.ts +16 -1
- package/types/muxima-ui-core-progress.d.ts +10 -8
- package/types/muxima-ui-core-rating.d.ts +6 -2
- package/types/muxima-ui-core-select.d.ts +6 -3
- package/types/muxima-ui-core-sidebar.d.ts +6 -3
- package/types/muxima-ui-core-slider.d.ts +4 -2
- package/types/muxima-ui-core-stepper.d.ts +10 -8
- package/types/muxima-ui-core-table.d.ts +3 -3
- package/types/muxima-ui-core-time-picker.d.ts +3 -1
- package/types/muxima-ui-core-toast.d.ts +3 -0
- package/types/muxima-ui-core-tour.d.ts +6 -1
- package/types/muxima-ui-core.d.ts +1 -1
package/README.md
CHANGED
|
@@ -68,6 +68,17 @@ Cada componente tem o seu ponto de entrada, para só importares o que usas:
|
|
|
68
68
|
| `@muxima-ui/core/progress` | `MxProgress`, `MxSpinner` |
|
|
69
69
|
| `@muxima-ui/core/skeleton` | `MxSkeleton` |
|
|
70
70
|
| `@muxima-ui/core/toast` | `MxToast` |
|
|
71
|
+
| `@muxima-ui/core/i18n` | `provideMuximaI18n`, `MxI18n`, `MX_MESSAGES_PT`, `MX_MESSAGES_EN`, `injectMxMessages` |
|
|
72
|
+
|
|
73
|
+
Idiomas: os textos dos componentes vêm em português (por omissão na 1.x) e em inglês. Para escolher:
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
import { provideMuximaI18n } from '@muxima-ui/core/i18n';
|
|
77
|
+
|
|
78
|
+
providers: [provideMuximaI18n({ locale: 'en' })]
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`inject(MxI18n).setLocale('pt')` muda o idioma sem recarregar. A partir da 2.0 o inglês passa a ser o idioma por omissão.
|
|
71
82
|
|
|
72
83
|
O editor de texto usa o Tiptap, que é opcional: só é preciso se importares `@muxima-ui/core/editor`.
|
|
73
84
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { input, booleanAttribute, Directive } from '@angular/core';
|
|
3
|
+
import { injectMxMessages } from '@muxima-ui/core/i18n';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Mensagem destacada dentro da página.
|
|
@@ -42,15 +43,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
42
43
|
}] });
|
|
43
44
|
/** Botão de fechar do alerta. Esconder o alerta fica a cargo da aplicação (ex.: com @if). */
|
|
44
45
|
class MxAlertClose {
|
|
45
|
-
label = input(
|
|
46
|
+
label = input(undefined, { ...(ngDevMode ? { debugName: "label" } : /* istanbul ignore next */ {}), alias: 'aria-label' });
|
|
47
|
+
i18n = injectMxMessages();
|
|
46
48
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: MxAlertClose, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
47
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.25", type: MxAlertClose, isStandalone: true, selector: "button[mxAlertClose]", inputs: { label: { classPropertyName: "label", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "type": "button" }, properties: { "attr.aria-label": "label()" }, classAttribute: "mx-alert-close" }, ngImport: i0 });
|
|
49
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.25", type: MxAlertClose, isStandalone: true, selector: "button[mxAlertClose]", inputs: { label: { classPropertyName: "label", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "type": "button" }, properties: { "attr.aria-label": "label() ?? i18n().alert.close" }, classAttribute: "mx-alert-close" }, ngImport: i0 });
|
|
48
50
|
}
|
|
49
51
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: MxAlertClose, decorators: [{
|
|
50
52
|
type: Directive,
|
|
51
53
|
args: [{
|
|
52
54
|
selector: 'button[mxAlertClose]',
|
|
53
|
-
host: { class: 'mx-alert-close', type: 'button', '[attr.aria-label]': 'label()' },
|
|
55
|
+
host: { class: 'mx-alert-close', type: 'button', '[attr.aria-label]': 'label() ?? i18n().alert.close' },
|
|
54
56
|
}]
|
|
55
57
|
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }] } });
|
|
56
58
|
const MX_ALERT = [MxAlert, MxAlertTitle, MxAlertClose];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"muxima-ui-core-alert.mjs","sources":["../../../projects/core/alert/alert.ts","../../../projects/core/alert/muxima-ui-core-alert.ts"],"sourcesContent":["import { Directive, booleanAttribute, input } from '@angular/core';\n\nexport type MxAlertVariant = 'info' | 'success' | 'warning' | 'danger';\n\n/**\n * Mensagem destacada dentro da página.\n *\n * ```html\n * <div mxAlert variant=\"warning\">\n * <p mxAlertTitle>A sessão expira em 5 minutos</p>\n * <p>Guarda o trabalho para não perderes alterações.</p>\n * </div>\n * ```\n *\n * Por omissão não interrompe o leitor de ecrã. Com `announce`, a mensagem é lida\n * assim que aparece (role=\"alert\"); usa-o só para mensagens que surgem após uma acção.\n */\n@Directive({\n selector: '[mxAlert]',\n exportAs: 'mxAlert',\n host: {\n class: 'mx-alert',\n '[attr.data-variant]': 'variant()',\n '[attr.role]': 'announce() ? \"alert\" : null',\n },\n})\nexport class MxAlert {\n readonly variant = input<MxAlertVariant>('info');\n readonly announce = input(false, { transform: booleanAttribute });\n}\n\n@Directive({ selector: '[mxAlertTitle]', host: { class: 'mx-alert-title' } })\nexport class MxAlertTitle {}\n\n/** Botão de fechar do alerta. Esconder o alerta fica a cargo da aplicação (ex.: com @if). */\n@Directive({\n selector: 'button[mxAlertClose]',\n host: { class: 'mx-alert-close', type: 'button', '[attr.aria-label]': 'label()' },\n})\nexport class MxAlertClose {\n readonly label = input(
|
|
1
|
+
{"version":3,"file":"muxima-ui-core-alert.mjs","sources":["../../../projects/core/alert/alert.ts","../../../projects/core/alert/muxima-ui-core-alert.ts"],"sourcesContent":["import { Directive, booleanAttribute, input } from '@angular/core';\nimport { injectMxMessages } from '@muxima-ui/core/i18n';\n\nexport type MxAlertVariant = 'info' | 'success' | 'warning' | 'danger';\n\n/**\n * Mensagem destacada dentro da página.\n *\n * ```html\n * <div mxAlert variant=\"warning\">\n * <p mxAlertTitle>A sessão expira em 5 minutos</p>\n * <p>Guarda o trabalho para não perderes alterações.</p>\n * </div>\n * ```\n *\n * Por omissão não interrompe o leitor de ecrã. Com `announce`, a mensagem é lida\n * assim que aparece (role=\"alert\"); usa-o só para mensagens que surgem após uma acção.\n */\n@Directive({\n selector: '[mxAlert]',\n exportAs: 'mxAlert',\n host: {\n class: 'mx-alert',\n '[attr.data-variant]': 'variant()',\n '[attr.role]': 'announce() ? \"alert\" : null',\n },\n})\nexport class MxAlert {\n readonly variant = input<MxAlertVariant>('info');\n readonly announce = input(false, { transform: booleanAttribute });\n}\n\n@Directive({ selector: '[mxAlertTitle]', host: { class: 'mx-alert-title' } })\nexport class MxAlertTitle {}\n\n/** Botão de fechar do alerta. Esconder o alerta fica a cargo da aplicação (ex.: com @if). */\n@Directive({\n selector: 'button[mxAlertClose]',\n host: { class: 'mx-alert-close', type: 'button', '[attr.aria-label]': 'label() ?? i18n().alert.close' },\n})\nexport class MxAlertClose {\n readonly label = input<string | undefined>(undefined, { alias: 'aria-label' });\n protected readonly i18n = injectMxMessages();\n}\n\nexport const MX_ALERT = [MxAlert, MxAlertTitle, MxAlertClose] as const;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { input, Directive } from '@angular/core';
|
|
3
|
+
import { injectMxMessages } from '@muxima-ui/core/i18n';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Migalhas: mostram onde a página está na hierarquia.
|
|
@@ -17,15 +18,16 @@ import { input, Directive } from '@angular/core';
|
|
|
17
18
|
* Os separadores são desenhados em CSS, por isso o leitor de ecrã não os lê.
|
|
18
19
|
*/
|
|
19
20
|
class MxBreadcrumb {
|
|
20
|
-
ariaLabel = input(
|
|
21
|
+
ariaLabel = input(undefined, { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: 'aria-label' });
|
|
22
|
+
i18n = injectMxMessages();
|
|
21
23
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: MxBreadcrumb, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
22
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.25", type: MxBreadcrumb, isStandalone: true, selector: "nav[mxBreadcrumb]", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.aria-label": "ariaLabel()" }, classAttribute: "mx-breadcrumb" }, ngImport: i0 });
|
|
24
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.25", type: MxBreadcrumb, isStandalone: true, selector: "nav[mxBreadcrumb]", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.aria-label": "ariaLabel() ?? i18n().breadcrumb.label" }, classAttribute: "mx-breadcrumb" }, ngImport: i0 });
|
|
23
25
|
}
|
|
24
26
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: MxBreadcrumb, decorators: [{
|
|
25
27
|
type: Directive,
|
|
26
28
|
args: [{
|
|
27
29
|
selector: 'nav[mxBreadcrumb]',
|
|
28
|
-
host: { class: 'mx-breadcrumb', '[attr.aria-label]': 'ariaLabel()' },
|
|
30
|
+
host: { class: 'mx-breadcrumb', '[attr.aria-label]': 'ariaLabel() ?? i18n().breadcrumb.label' },
|
|
29
31
|
}]
|
|
30
32
|
}], propDecorators: { ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }] } });
|
|
31
33
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"muxima-ui-core-breadcrumb.mjs","sources":["../../../projects/core/breadcrumb/breadcrumb.ts","../../../projects/core/breadcrumb/muxima-ui-core-breadcrumb.ts"],"sourcesContent":["import { Directive, input } from '@angular/core';\n\n/**\n * Migalhas: mostram onde a página está na hierarquia.\n *\n * ```html\n * <nav mxBreadcrumb>\n * <ol>\n * <li><a routerLink=\"/clientes\">Clientes</a></li>\n * <li><a routerLink=\"/clientes/42\">Kianda Logística</a></li>\n * <li><span aria-current=\"page\">Facturas</span></li>\n * </ol>\n * </nav>\n * ```\n *\n * Os separadores são desenhados em CSS, por isso o leitor de ecrã não os lê.\n */\n@Directive({\n selector: 'nav[mxBreadcrumb]',\n host: { class: 'mx-breadcrumb', '[attr.aria-label]': 'ariaLabel()' },\n})\nexport class MxBreadcrumb {\n readonly ariaLabel = input(
|
|
1
|
+
{"version":3,"file":"muxima-ui-core-breadcrumb.mjs","sources":["../../../projects/core/breadcrumb/breadcrumb.ts","../../../projects/core/breadcrumb/muxima-ui-core-breadcrumb.ts"],"sourcesContent":["import { Directive, input } from '@angular/core';\nimport { injectMxMessages } from '@muxima-ui/core/i18n';\n\n/**\n * Migalhas: mostram onde a página está na hierarquia.\n *\n * ```html\n * <nav mxBreadcrumb>\n * <ol>\n * <li><a routerLink=\"/clientes\">Clientes</a></li>\n * <li><a routerLink=\"/clientes/42\">Kianda Logística</a></li>\n * <li><span aria-current=\"page\">Facturas</span></li>\n * </ol>\n * </nav>\n * ```\n *\n * Os separadores são desenhados em CSS, por isso o leitor de ecrã não os lê.\n */\n@Directive({\n selector: 'nav[mxBreadcrumb]',\n host: { class: 'mx-breadcrumb', '[attr.aria-label]': 'ariaLabel() ?? i18n().breadcrumb.label' },\n})\nexport class MxBreadcrumb {\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\n protected readonly i18n = injectMxMessages();\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAGA;;;;;;;;;;;;;;AAcG;MAKU,YAAY,CAAA;IACd,SAAS,GAAG,KAAK,CAAqB,SAAS,iFAAI,KAAK,EAAE,YAAY,EAAA,CAAG;IAC/D,IAAI,GAAG,gBAAgB,EAAE;wGAFjC,YAAY,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;4FAAZ,YAAY,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,wCAAA,EAAA,EAAA,cAAA,EAAA,eAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;4FAAZ,YAAY,EAAA,UAAA,EAAA,CAAA;kBAJxB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,mBAAmB;oBAC7B,IAAI,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,wCAAwC,EAAE;AAChG,iBAAA;;;ACrBD;;AAEG;;"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { input, inject, forwardRef, ElementRef, computed, ViewEncapsulation, ChangeDetectionStrategy, Component, model, numberAttribute, booleanAttribute, contentChildren, viewChild, signal, Injector, effect, afterNextRender, DestroyRef } from '@angular/core';
|
|
3
|
+
import { injectMxMessages } from '@muxima-ui/core/i18n';
|
|
3
4
|
|
|
4
5
|
/** Um diapositivo. O carrossel dá-lhe o nome "2 de 5" e tira do teclado os que não se vêem. */
|
|
5
6
|
class MxCarouselSlide {
|
|
@@ -9,7 +10,7 @@ class MxCarouselSlide {
|
|
|
9
10
|
el = inject(ElementRef).nativeElement;
|
|
10
11
|
index = computed(() => this.carousel.slides().indexOf(this), ...(ngDevMode ? [{ debugName: "index" }] : /* istanbul ignore next */ []));
|
|
11
12
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: MxCarouselSlide, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
12
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.25", type: MxCarouselSlide, isStandalone: true, selector: "mx-carousel-slide", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "group", "aria-roledescription": "
|
|
13
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.25", type: MxCarouselSlide, isStandalone: true, selector: "mx-carousel-slide", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "group" }, properties: { "attr.aria-roledescription": "carousel.i18n().carousel.slide", "attr.aria-label": "label() || carousel.slideLabel(index())", "attr.inert": "carousel.isVisible(index()) ? null : \"\"", "attr.aria-hidden": "carousel.isVisible(index()) ? null : \"true\"" }, classAttribute: "mx-carousel-slide" }, ngImport: i0, template: `<ng-content />`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
13
14
|
}
|
|
14
15
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: MxCarouselSlide, decorators: [{
|
|
15
16
|
type: Component,
|
|
@@ -20,7 +21,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
20
21
|
host: {
|
|
21
22
|
class: 'mx-carousel-slide',
|
|
22
23
|
role: 'group',
|
|
23
|
-
'aria-roledescription': '
|
|
24
|
+
'[attr.aria-roledescription]': 'carousel.i18n().carousel.slide',
|
|
24
25
|
'[attr.aria-label]': 'label() || carousel.slideLabel(index())',
|
|
25
26
|
'[attr.inert]': 'carousel.isVisible(index()) ? null : ""',
|
|
26
27
|
'[attr.aria-hidden]': 'carousel.isVisible(index()) ? null : "true"',
|
|
@@ -55,8 +56,9 @@ class MxCarousel {
|
|
|
55
56
|
indicators = input(true, { ...(ngDevMode ? { debugName: "indicators" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
56
57
|
/** Botões anterior e seguinte. Sem eles, dá à pessoa outra forma de mudar ([(index)]). */
|
|
57
58
|
controls = input(true, { ...(ngDevMode ? { debugName: "controls" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
58
|
-
prevLabel = input(
|
|
59
|
-
nextLabel = input(
|
|
59
|
+
prevLabel = input(...(ngDevMode ? [undefined, { debugName: "prevLabel" }] : /* istanbul ignore next */ []));
|
|
60
|
+
nextLabel = input(...(ngDevMode ? [undefined, { debugName: "nextLabel" }] : /* istanbul ignore next */ []));
|
|
61
|
+
i18n = injectMxMessages();
|
|
60
62
|
slides = contentChildren(MxCarouselSlide, ...(ngDevMode ? [{ debugName: "slides" }] : /* istanbul ignore next */ []));
|
|
61
63
|
viewport = viewChild.required('viewport');
|
|
62
64
|
reducedMotion = typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
@@ -99,7 +101,7 @@ class MxCarousel {
|
|
|
99
101
|
inject(DestroyRef).onDestroy(() => cancelAnimationFrame(this.scrollFrame));
|
|
100
102
|
}
|
|
101
103
|
slideLabel(i) {
|
|
102
|
-
return
|
|
104
|
+
return this.i18n().carousel.position(i + 1, this.slides().length);
|
|
103
105
|
}
|
|
104
106
|
isVisible(i) {
|
|
105
107
|
const start = this.index();
|
|
@@ -166,13 +168,13 @@ class MxCarousel {
|
|
|
166
168
|
});
|
|
167
169
|
}
|
|
168
170
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: MxCarousel, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
169
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: MxCarousel, isStandalone: true, selector: "mx-carousel", inputs: { index: { classPropertyName: "index", publicName: "index", isSignal: true, isRequired: false, transformFunction: null }, perView: { classPropertyName: "perView", publicName: "perView", isSignal: true, isRequired: false, transformFunction: null }, gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null }, autoplay: { classPropertyName: "autoplay", publicName: "autoplay", isSignal: true, isRequired: false, transformFunction: null }, loop: { classPropertyName: "loop", publicName: "loop", isSignal: true, isRequired: false, transformFunction: null }, indicators: { classPropertyName: "indicators", publicName: "indicators", isSignal: true, isRequired: false, transformFunction: null }, controls: { classPropertyName: "controls", publicName: "controls", isSignal: true, isRequired: false, transformFunction: null }, prevLabel: { classPropertyName: "prevLabel", publicName: "prevLabel", isSignal: true, isRequired: false, transformFunction: null }, nextLabel: { classPropertyName: "nextLabel", publicName: "nextLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { index: "indexChange" }, host: { attributes: { "role": "region"
|
|
171
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: MxCarousel, isStandalone: true, selector: "mx-carousel", inputs: { index: { classPropertyName: "index", publicName: "index", isSignal: true, isRequired: false, transformFunction: null }, perView: { classPropertyName: "perView", publicName: "perView", isSignal: true, isRequired: false, transformFunction: null }, gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null }, autoplay: { classPropertyName: "autoplay", publicName: "autoplay", isSignal: true, isRequired: false, transformFunction: null }, loop: { classPropertyName: "loop", publicName: "loop", isSignal: true, isRequired: false, transformFunction: null }, indicators: { classPropertyName: "indicators", publicName: "indicators", isSignal: true, isRequired: false, transformFunction: null }, controls: { classPropertyName: "controls", publicName: "controls", isSignal: true, isRequired: false, transformFunction: null }, prevLabel: { classPropertyName: "prevLabel", publicName: "prevLabel", isSignal: true, isRequired: false, transformFunction: null }, nextLabel: { classPropertyName: "nextLabel", publicName: "nextLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { index: "indexChange" }, host: { attributes: { "role": "region" }, listeners: { "mouseenter": "hovering.set(true)", "mouseleave": "hovering.set(false)", "focusin": "focused.set(true)", "focusout": "onFocusOut($event)" }, properties: { "attr.aria-roledescription": "i18n().carousel.carousel", "attr.data-indicators": "indicators() ? \"\" : null", "style.--mx-carousel-per-view": "perView()", "style.--mx-carousel-gap.px": "gap()" }, classAttribute: "mx-carousel" }, queries: [{ propertyName: "slides", predicate: MxCarouselSlide, isSignal: true }], viewQueries: [{ propertyName: "viewport", first: true, predicate: ["viewport"], descendants: true, isSignal: true }], exportAs: ["mxCarousel"], ngImport: i0, template: `
|
|
170
172
|
@if (autoplay()) {
|
|
171
173
|
<button
|
|
172
174
|
type="button"
|
|
173
175
|
class="mx-carousel-play"
|
|
174
176
|
[attr.aria-label]="
|
|
175
|
-
playing() ?
|
|
177
|
+
playing() ? i18n().carousel.pause : i18n().carousel.play
|
|
176
178
|
"
|
|
177
179
|
(click)="togglePlay()"
|
|
178
180
|
>
|
|
@@ -205,7 +207,7 @@ class MxCarousel {
|
|
|
205
207
|
type="button"
|
|
206
208
|
class="mx-carousel-button mx-carousel-prev"
|
|
207
209
|
[disabled]="!loop() && index() === 0"
|
|
208
|
-
[attr.aria-label]="prevLabel()"
|
|
210
|
+
[attr.aria-label]="prevLabel() ?? i18n().carousel.previous"
|
|
209
211
|
(click)="prev()"
|
|
210
212
|
>
|
|
211
213
|
<svg viewBox="0 0 16 16" aria-hidden="true">
|
|
@@ -221,12 +223,12 @@ class MxCarousel {
|
|
|
221
223
|
</button>
|
|
222
224
|
}
|
|
223
225
|
@if (indicators()) {
|
|
224
|
-
<div class="mx-carousel-dots" role="group" aria-label="
|
|
226
|
+
<div class="mx-carousel-dots" role="group" [attr.aria-label]="i18n().carousel.choose">
|
|
225
227
|
@for (p of pages(); track p) {
|
|
226
228
|
<button
|
|
227
229
|
type="button"
|
|
228
230
|
class="mx-carousel-dot"
|
|
229
|
-
[attr.aria-label]="
|
|
231
|
+
[attr.aria-label]="i18n().carousel.goTo(p + 1)"
|
|
230
232
|
[attr.aria-current]="p === index() ? 'true' : null"
|
|
231
233
|
(click)="go(p)"
|
|
232
234
|
></button>
|
|
@@ -238,7 +240,7 @@ class MxCarousel {
|
|
|
238
240
|
type="button"
|
|
239
241
|
class="mx-carousel-button mx-carousel-next"
|
|
240
242
|
[disabled]="!loop() && index() >= lastIndex()"
|
|
241
|
-
[attr.aria-label]="nextLabel()"
|
|
243
|
+
[attr.aria-label]="nextLabel() ?? i18n().carousel.next"
|
|
242
244
|
(click)="next()"
|
|
243
245
|
>
|
|
244
246
|
<svg viewBox="0 0 16 16" aria-hidden="true">
|
|
@@ -267,7 +269,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
267
269
|
host: {
|
|
268
270
|
class: 'mx-carousel',
|
|
269
271
|
role: 'region',
|
|
270
|
-
'aria-roledescription': '
|
|
272
|
+
'[attr.aria-roledescription]': 'i18n().carousel.carousel',
|
|
271
273
|
'[attr.data-indicators]': 'indicators() ? "" : null',
|
|
272
274
|
'[style.--mx-carousel-per-view]': 'perView()',
|
|
273
275
|
'[style.--mx-carousel-gap.px]': 'gap()',
|
|
@@ -282,7 +284,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
282
284
|
type="button"
|
|
283
285
|
class="mx-carousel-play"
|
|
284
286
|
[attr.aria-label]="
|
|
285
|
-
playing() ?
|
|
287
|
+
playing() ? i18n().carousel.pause : i18n().carousel.play
|
|
286
288
|
"
|
|
287
289
|
(click)="togglePlay()"
|
|
288
290
|
>
|
|
@@ -315,7 +317,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
315
317
|
type="button"
|
|
316
318
|
class="mx-carousel-button mx-carousel-prev"
|
|
317
319
|
[disabled]="!loop() && index() === 0"
|
|
318
|
-
[attr.aria-label]="prevLabel()"
|
|
320
|
+
[attr.aria-label]="prevLabel() ?? i18n().carousel.previous"
|
|
319
321
|
(click)="prev()"
|
|
320
322
|
>
|
|
321
323
|
<svg viewBox="0 0 16 16" aria-hidden="true">
|
|
@@ -331,12 +333,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
331
333
|
</button>
|
|
332
334
|
}
|
|
333
335
|
@if (indicators()) {
|
|
334
|
-
<div class="mx-carousel-dots" role="group" aria-label="
|
|
336
|
+
<div class="mx-carousel-dots" role="group" [attr.aria-label]="i18n().carousel.choose">
|
|
335
337
|
@for (p of pages(); track p) {
|
|
336
338
|
<button
|
|
337
339
|
type="button"
|
|
338
340
|
class="mx-carousel-dot"
|
|
339
|
-
[attr.aria-label]="
|
|
341
|
+
[attr.aria-label]="i18n().carousel.goTo(p + 1)"
|
|
340
342
|
[attr.aria-current]="p === index() ? 'true' : null"
|
|
341
343
|
(click)="go(p)"
|
|
342
344
|
></button>
|
|
@@ -348,7 +350,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
348
350
|
type="button"
|
|
349
351
|
class="mx-carousel-button mx-carousel-next"
|
|
350
352
|
[disabled]="!loop() && index() >= lastIndex()"
|
|
351
|
-
[attr.aria-label]="nextLabel()"
|
|
353
|
+
[attr.aria-label]="nextLabel() ?? i18n().carousel.next"
|
|
352
354
|
(click)="next()"
|
|
353
355
|
>
|
|
354
356
|
<svg viewBox="0 0 16 16" aria-hidden="true">
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"muxima-ui-core-carousel.mjs","sources":["../../../projects/core/carousel/carousel.ts","../../../projects/core/carousel/muxima-ui-core-carousel.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n Injector,\n ViewEncapsulation,\n afterNextRender,\n booleanAttribute,\n computed,\n contentChildren,\n effect,\n forwardRef,\n inject,\n input,\n model,\n numberAttribute,\n signal,\n viewChild,\n} from '@angular/core';\n\n/** Um diapositivo. O carrossel dá-lhe o nome \"2 de 5\" e tira do teclado os que não se vêem. */\n@Component({\n selector: 'mx-carousel-slide',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'mx-carousel-slide',\n role: 'group',\n 'aria-roledescription': 'diapositivo',\n '[attr.aria-label]': 'label() || carousel.slideLabel(index())',\n '[attr.inert]': 'carousel.isVisible(index()) ? null : \"\"',\n '[attr.aria-hidden]': 'carousel.isVisible(index()) ? null : \"true\"',\n },\n template: `<ng-content />`,\n})\nexport class MxCarouselSlide {\n /** Nome próprio do diapositivo; por omissão \"2 de 5\". */\n readonly label = input('');\n protected readonly carousel = inject(forwardRef(() => MxCarousel));\n readonly el = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n protected readonly index = computed(() => this.carousel.slides().indexOf(this));\n}\n\n/**\n * Carrossel acessível (padrão WAI-ARIA Carousel): botões anterior e seguinte, indicadores,\n * deslizar com o dedo (scroll nativo com snap) e, opcionalmente, rotação automática com\n * botão de pausa. A rotação pára com o rato ou o foco dentro e não arranca com\n * \"reduzir movimento\" activo.\n *\n * ```html\n * <mx-carousel aria-label=\"Novidades\" [perView]=\"1\" [autoplay]=\"6000\">\n * <mx-carousel-slide>...</mx-carousel-slide>\n * <mx-carousel-slide>...</mx-carousel-slide>\n * </mx-carousel>\n * ```\n */\n@Component({\n selector: 'mx-carousel',\n exportAs: 'mxCarousel',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'mx-carousel',\n role: 'region',\n 'aria-roledescription': 'carrossel',\n '[attr.data-indicators]': 'indicators() ? \"\" : null',\n '[style.--mx-carousel-per-view]': 'perView()',\n '[style.--mx-carousel-gap.px]': 'gap()',\n '(mouseenter)': 'hovering.set(true)',\n '(mouseleave)': 'hovering.set(false)',\n '(focusin)': 'focused.set(true)',\n '(focusout)': 'onFocusOut($event)',\n },\n template: `\n @if (autoplay()) {\n <button\n type=\"button\"\n class=\"mx-carousel-play\"\n [attr.aria-label]=\"\n playing() ? 'Parar a rotação automática' : 'Iniciar a rotação automática'\n \"\n (click)=\"togglePlay()\"\n >\n @if (playing()) {\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path\n d=\"M5.5 3.5v9M10.5 3.5v9\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.6\"\n stroke-linecap=\"round\"\n />\n </svg>\n } @else {\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path d=\"M5 3.5l7 4.5-7 4.5z\" fill=\"currentColor\" />\n </svg>\n }\n </button>\n }\n <div class=\"mx-carousel-viewport\" #viewport (scroll)=\"onScroll()\">\n <div class=\"mx-carousel-track\" [attr.aria-live]=\"running() ? 'off' : 'polite'\">\n <ng-content />\n </div>\n </div>\n @if (controls() || indicators()) {\n <div class=\"mx-carousel-nav\">\n @if (controls()) {\n <button\n type=\"button\"\n class=\"mx-carousel-button mx-carousel-prev\"\n [disabled]=\"!loop() && index() === 0\"\n [attr.aria-label]=\"prevLabel()\"\n (click)=\"prev()\"\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path\n d=\"M10 4L6 8l4 4\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n }\n @if (indicators()) {\n <div class=\"mx-carousel-dots\" role=\"group\" aria-label=\"Escolher diapositivo\">\n @for (p of pages(); track p) {\n <button\n type=\"button\"\n class=\"mx-carousel-dot\"\n [attr.aria-label]=\"'Diapositivo ' + (p + 1)\"\n [attr.aria-current]=\"p === index() ? 'true' : null\"\n (click)=\"go(p)\"\n ></button>\n }\n </div>\n }\n @if (controls()) {\n <button\n type=\"button\"\n class=\"mx-carousel-button mx-carousel-next\"\n [disabled]=\"!loop() && index() >= lastIndex()\"\n [attr.aria-label]=\"nextLabel()\"\n (click)=\"next()\"\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path\n d=\"M6 4l4 4-4 4\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n }\n </div>\n }\n `,\n})\nexport class MxCarousel {\n /** Índice do primeiro diapositivo visível. */\n readonly index = model(0);\n /** Diapositivos visíveis de cada vez. */\n readonly perView = input(1, { transform: numberAttribute });\n /** Espaço entre diapositivos, em px. */\n readonly gap = input(16, { transform: numberAttribute });\n /** Ms entre diapositivos; 0 = sem rotação automática. */\n readonly autoplay = input(0, { transform: numberAttribute });\n /** Depois do último volta ao primeiro. */\n readonly loop = input(false, { transform: booleanAttribute });\n readonly indicators = input(true, { transform: booleanAttribute });\n /** Botões anterior e seguinte. Sem eles, dá à pessoa outra forma de mudar ([(index)]). */\n readonly controls = input(true, { transform: booleanAttribute });\n readonly prevLabel = input('Diapositivo anterior');\n readonly nextLabel = input('Diapositivo seguinte');\n\n readonly slides = contentChildren(MxCarouselSlide);\n private readonly viewport = viewChild.required<ElementRef<HTMLElement>>('viewport');\n private readonly reducedMotion =\n typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches;\n\n protected readonly hovering = signal(false);\n protected readonly focused = signal(false);\n /** Rotação ligada pela pessoa (botão de pausa). */\n readonly playing = signal(true);\n /** A rodar agora: ligada, sem rato nem foco dentro, e sem reduzir movimento. */\n protected readonly running = computed(\n () =>\n !!this.autoplay() &&\n this.playing() &&\n !this.hovering() &&\n !this.focused() &&\n !this.reducedMotion,\n );\n protected readonly lastIndex = computed(() => Math.max(0, this.slides().length - this.perView()));\n protected readonly pages = computed(() =>\n Array.from({ length: this.lastIndex() + 1 }, (_, i) => i),\n );\n private scrollFrame = 0;\n private scrolling = false;\n /** O índice mudou porque a pessoa deslizou: não volta a mexer no scroll. */\n private fromScroll = false;\n private readonly injector = inject(Injector);\n\n constructor() {\n if (this.reducedMotion) this.playing.set(false);\n effect((onCleanup) => {\n if (!this.running()) return;\n const t = setInterval(() => this.next(true), this.autoplay());\n onCleanup(() => clearInterval(t));\n });\n // o índice pode mudar por [(index)]: alinha o scroll\n effect(() => {\n const i = this.index();\n if (this.fromScroll) {\n this.fromScroll = false;\n return;\n }\n if (!this.scrolling)\n afterNextRender(() => this.scrollTo(i, false), { injector: this.injector });\n });\n inject(DestroyRef).onDestroy(() => cancelAnimationFrame(this.scrollFrame));\n }\n\n slideLabel(i: number): string {\n return `${i + 1} de ${this.slides().length}`;\n }\n isVisible(i: number): boolean {\n const start = this.index();\n return i >= start && i < start + this.perView();\n }\n\n go(i: number): void {\n const target = Math.min(Math.max(i, 0), this.lastIndex());\n this.index.set(target);\n this.scrollTo(target, true);\n }\n next(auto = false): void {\n if (this.index() >= this.lastIndex()) {\n if (this.loop() || auto) this.go(0);\n return;\n }\n this.go(this.index() + 1);\n }\n prev(): void {\n if (this.index() === 0) {\n if (this.loop()) this.go(this.lastIndex());\n return;\n }\n this.go(this.index() - 1);\n }\n togglePlay(): void {\n this.playing.update((p) => !p);\n }\n\n protected onFocusOut(event: FocusEvent): void {\n const host = this.viewport().nativeElement.parentElement!;\n if (!host.contains(event.relatedTarget as Node)) this.focused.set(false);\n }\n\n private scrollTo(i: number, smooth: boolean): void {\n const vp = this.viewport().nativeElement;\n const slide = this.slides()[i]?.el;\n if (!slide) return;\n this.scrolling = true;\n const first = this.slides()[0].el;\n const left = slide.offsetLeft - first.offsetLeft;\n if (typeof vp.scrollTo === 'function')\n vp.scrollTo({ left, behavior: smooth && !this.reducedMotion ? 'smooth' : 'auto' });\n else vp.scrollLeft = left;\n setTimeout(() => (this.scrolling = false), smooth ? 450 : 0);\n }\n\n protected onScroll(): void {\n if (this.scrolling) return;\n cancelAnimationFrame(this.scrollFrame);\n this.scrollFrame = requestAnimationFrame(() => {\n const vp = this.viewport().nativeElement;\n const slides = this.slides();\n if (!slides.length) return;\n const step =\n slides.length > 1 ? slides[1].el.offsetLeft - slides[0].el.offsetLeft : vp.clientWidth;\n const i = Math.min(Math.round(vp.scrollLeft / step), this.lastIndex());\n if (i !== this.index()) {\n this.fromScroll = true;\n this.index.set(i);\n }\n });\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"muxima-ui-core-carousel.mjs","sources":["../../../projects/core/carousel/carousel.ts","../../../projects/core/carousel/muxima-ui-core-carousel.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n Injector,\n ViewEncapsulation,\n afterNextRender,\n booleanAttribute,\n computed,\n contentChildren,\n effect,\n forwardRef,\n inject,\n input,\n model,\n numberAttribute,\n signal,\n viewChild,\n} from '@angular/core';\nimport { injectMxMessages } from '@muxima-ui/core/i18n';\n\n/** Um diapositivo. O carrossel dá-lhe o nome \"2 de 5\" e tira do teclado os que não se vêem. */\n@Component({\n selector: 'mx-carousel-slide',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'mx-carousel-slide',\n role: 'group',\n '[attr.aria-roledescription]': 'carousel.i18n().carousel.slide',\n '[attr.aria-label]': 'label() || carousel.slideLabel(index())',\n '[attr.inert]': 'carousel.isVisible(index()) ? null : \"\"',\n '[attr.aria-hidden]': 'carousel.isVisible(index()) ? null : \"true\"',\n },\n template: `<ng-content />`,\n})\nexport class MxCarouselSlide {\n /** Nome próprio do diapositivo; por omissão \"2 de 5\". */\n readonly label = input('');\n protected readonly carousel = inject(forwardRef(() => MxCarousel));\n readonly el = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n protected readonly index = computed(() => this.carousel.slides().indexOf(this));\n}\n\n/**\n * Carrossel acessível (padrão WAI-ARIA Carousel): botões anterior e seguinte, indicadores,\n * deslizar com o dedo (scroll nativo com snap) e, opcionalmente, rotação automática com\n * botão de pausa. A rotação pára com o rato ou o foco dentro e não arranca com\n * \"reduzir movimento\" activo.\n *\n * ```html\n * <mx-carousel aria-label=\"Novidades\" [perView]=\"1\" [autoplay]=\"6000\">\n * <mx-carousel-slide>...</mx-carousel-slide>\n * <mx-carousel-slide>...</mx-carousel-slide>\n * </mx-carousel>\n * ```\n */\n@Component({\n selector: 'mx-carousel',\n exportAs: 'mxCarousel',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'mx-carousel',\n role: 'region',\n '[attr.aria-roledescription]': 'i18n().carousel.carousel',\n '[attr.data-indicators]': 'indicators() ? \"\" : null',\n '[style.--mx-carousel-per-view]': 'perView()',\n '[style.--mx-carousel-gap.px]': 'gap()',\n '(mouseenter)': 'hovering.set(true)',\n '(mouseleave)': 'hovering.set(false)',\n '(focusin)': 'focused.set(true)',\n '(focusout)': 'onFocusOut($event)',\n },\n template: `\n @if (autoplay()) {\n <button\n type=\"button\"\n class=\"mx-carousel-play\"\n [attr.aria-label]=\"\n playing() ? i18n().carousel.pause : i18n().carousel.play\n \"\n (click)=\"togglePlay()\"\n >\n @if (playing()) {\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path\n d=\"M5.5 3.5v9M10.5 3.5v9\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.6\"\n stroke-linecap=\"round\"\n />\n </svg>\n } @else {\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path d=\"M5 3.5l7 4.5-7 4.5z\" fill=\"currentColor\" />\n </svg>\n }\n </button>\n }\n <div class=\"mx-carousel-viewport\" #viewport (scroll)=\"onScroll()\">\n <div class=\"mx-carousel-track\" [attr.aria-live]=\"running() ? 'off' : 'polite'\">\n <ng-content />\n </div>\n </div>\n @if (controls() || indicators()) {\n <div class=\"mx-carousel-nav\">\n @if (controls()) {\n <button\n type=\"button\"\n class=\"mx-carousel-button mx-carousel-prev\"\n [disabled]=\"!loop() && index() === 0\"\n [attr.aria-label]=\"prevLabel() ?? i18n().carousel.previous\"\n (click)=\"prev()\"\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path\n d=\"M10 4L6 8l4 4\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n }\n @if (indicators()) {\n <div class=\"mx-carousel-dots\" role=\"group\" [attr.aria-label]=\"i18n().carousel.choose\">\n @for (p of pages(); track p) {\n <button\n type=\"button\"\n class=\"mx-carousel-dot\"\n [attr.aria-label]=\"i18n().carousel.goTo(p + 1)\"\n [attr.aria-current]=\"p === index() ? 'true' : null\"\n (click)=\"go(p)\"\n ></button>\n }\n </div>\n }\n @if (controls()) {\n <button\n type=\"button\"\n class=\"mx-carousel-button mx-carousel-next\"\n [disabled]=\"!loop() && index() >= lastIndex()\"\n [attr.aria-label]=\"nextLabel() ?? i18n().carousel.next\"\n (click)=\"next()\"\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path\n d=\"M6 4l4 4-4 4\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n }\n </div>\n }\n `,\n})\nexport class MxCarousel {\n /** Índice do primeiro diapositivo visível. */\n readonly index = model(0);\n /** Diapositivos visíveis de cada vez. */\n readonly perView = input(1, { transform: numberAttribute });\n /** Espaço entre diapositivos, em px. */\n readonly gap = input(16, { transform: numberAttribute });\n /** Ms entre diapositivos; 0 = sem rotação automática. */\n readonly autoplay = input(0, { transform: numberAttribute });\n /** Depois do último volta ao primeiro. */\n readonly loop = input(false, { transform: booleanAttribute });\n readonly indicators = input(true, { transform: booleanAttribute });\n /** Botões anterior e seguinte. Sem eles, dá à pessoa outra forma de mudar ([(index)]). */\n readonly controls = input(true, { transform: booleanAttribute });\n readonly prevLabel = input<string>();\n readonly nextLabel = input<string>();\n readonly i18n = injectMxMessages();\n\n readonly slides = contentChildren(MxCarouselSlide);\n private readonly viewport = viewChild.required<ElementRef<HTMLElement>>('viewport');\n private readonly reducedMotion =\n typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches;\n\n protected readonly hovering = signal(false);\n protected readonly focused = signal(false);\n /** Rotação ligada pela pessoa (botão de pausa). */\n readonly playing = signal(true);\n /** A rodar agora: ligada, sem rato nem foco dentro, e sem reduzir movimento. */\n protected readonly running = computed(\n () =>\n !!this.autoplay() &&\n this.playing() &&\n !this.hovering() &&\n !this.focused() &&\n !this.reducedMotion,\n );\n protected readonly lastIndex = computed(() => Math.max(0, this.slides().length - this.perView()));\n protected readonly pages = computed(() =>\n Array.from({ length: this.lastIndex() + 1 }, (_, i) => i),\n );\n private scrollFrame = 0;\n private scrolling = false;\n /** O índice mudou porque a pessoa deslizou: não volta a mexer no scroll. */\n private fromScroll = false;\n private readonly injector = inject(Injector);\n\n constructor() {\n if (this.reducedMotion) this.playing.set(false);\n effect((onCleanup) => {\n if (!this.running()) return;\n const t = setInterval(() => this.next(true), this.autoplay());\n onCleanup(() => clearInterval(t));\n });\n // o índice pode mudar por [(index)]: alinha o scroll\n effect(() => {\n const i = this.index();\n if (this.fromScroll) {\n this.fromScroll = false;\n return;\n }\n if (!this.scrolling)\n afterNextRender(() => this.scrollTo(i, false), { injector: this.injector });\n });\n inject(DestroyRef).onDestroy(() => cancelAnimationFrame(this.scrollFrame));\n }\n\n slideLabel(i: number): string {\n return this.i18n().carousel.position(i + 1, this.slides().length);\n }\n isVisible(i: number): boolean {\n const start = this.index();\n return i >= start && i < start + this.perView();\n }\n\n go(i: number): void {\n const target = Math.min(Math.max(i, 0), this.lastIndex());\n this.index.set(target);\n this.scrollTo(target, true);\n }\n next(auto = false): void {\n if (this.index() >= this.lastIndex()) {\n if (this.loop() || auto) this.go(0);\n return;\n }\n this.go(this.index() + 1);\n }\n prev(): void {\n if (this.index() === 0) {\n if (this.loop()) this.go(this.lastIndex());\n return;\n }\n this.go(this.index() - 1);\n }\n togglePlay(): void {\n this.playing.update((p) => !p);\n }\n\n protected onFocusOut(event: FocusEvent): void {\n const host = this.viewport().nativeElement.parentElement!;\n if (!host.contains(event.relatedTarget as Node)) this.focused.set(false);\n }\n\n private scrollTo(i: number, smooth: boolean): void {\n const vp = this.viewport().nativeElement;\n const slide = this.slides()[i]?.el;\n if (!slide) return;\n this.scrolling = true;\n const first = this.slides()[0].el;\n const left = slide.offsetLeft - first.offsetLeft;\n if (typeof vp.scrollTo === 'function')\n vp.scrollTo({ left, behavior: smooth && !this.reducedMotion ? 'smooth' : 'auto' });\n else vp.scrollLeft = left;\n setTimeout(() => (this.scrolling = false), smooth ? 450 : 0);\n }\n\n protected onScroll(): void {\n if (this.scrolling) return;\n cancelAnimationFrame(this.scrollFrame);\n this.scrollFrame = requestAnimationFrame(() => {\n const vp = this.viewport().nativeElement;\n const slides = this.slides();\n if (!slides.length) return;\n const step =\n slides.length > 1 ? slides[1].el.offsetLeft - slides[0].el.offsetLeft : vp.clientWidth;\n const i = Math.min(Math.round(vp.scrollLeft / step), this.lastIndex());\n if (i !== this.index()) {\n this.fromScroll = true;\n this.index.set(i);\n }\n });\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, booleanAttribute, output, viewChild, signal, afterRenderEffect, ViewEncapsulation, ChangeDetectionStrategy, Component, model, Directive, numberAttribute, inject, ElementRef, Injector,
|
|
2
|
+
import { input, booleanAttribute, output, computed, viewChild, signal, afterRenderEffect, ViewEncapsulation, ChangeDetectionStrategy, Component, model, Directive, numberAttribute, inject, ElementRef, Injector, afterNextRender } from '@angular/core';
|
|
3
3
|
import { LiveAnnouncer } from '@angular/cdk/a11y';
|
|
4
|
+
import { injectMxMessages } from '@muxima-ui/core/i18n';
|
|
4
5
|
import { NgControl, Validators } from '@angular/forms';
|
|
5
6
|
import { MxFormField, mxUniqueId, MX_FORM_FIELD_CONTROL } from '@muxima-ui/core/form-field';
|
|
6
7
|
|
|
@@ -21,8 +22,10 @@ class MxChip {
|
|
|
21
22
|
variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
22
23
|
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
23
24
|
/** Verbo do botão de remover, seguido do texto do chip. */
|
|
24
|
-
removeLabel = input(
|
|
25
|
+
removeLabel = input(...(ngDevMode ? [undefined, { debugName: "removeLabel" }] : /* istanbul ignore next */ []));
|
|
25
26
|
removed = output();
|
|
27
|
+
msg = computed(() => this.i18n().chips, ...(ngDevMode ? [{ debugName: "msg" }] : /* istanbul ignore next */ []));
|
|
28
|
+
i18n = injectMxMessages();
|
|
26
29
|
label = viewChild.required('label');
|
|
27
30
|
text = signal('', ...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []));
|
|
28
31
|
constructor() {
|
|
@@ -36,7 +39,7 @@ class MxChip {
|
|
|
36
39
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: MxChip, isStandalone: true, selector: "mx-chip", inputs: { removable: { classPropertyName: "removable", publicName: "removable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, removeLabel: { classPropertyName: "removeLabel", publicName: "removeLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { removed: "removed" }, host: { properties: { "attr.data-variant": "variant() === \"default\" ? null : variant()", "attr.data-size": "size() === \"md\" ? null : size()", "attr.data-disabled": "disabled() ? \"\" : null" }, classAttribute: "mx-chip" }, viewQueries: [{ propertyName: "label", first: true, predicate: ["label"], descendants: true, isSignal: true }], exportAs: ["mxChip"], ngImport: i0, template: `
|
|
37
40
|
<span class="mx-chip-label" #label><ng-content /></span>
|
|
38
41
|
@if (removable()) {
|
|
39
|
-
<button type="button" class="mx-chip-remove" [disabled]="disabled()" [attr.aria-label]="removeLabel() + ' ' + text()" (click)="removed.emit()">
|
|
42
|
+
<button type="button" class="mx-chip-remove" [disabled]="disabled()" [attr.aria-label]="(removeLabel() ?? msg().remove) + ' ' + text()" (click)="removed.emit()">
|
|
40
43
|
<svg viewBox="0 0 16 16" aria-hidden="true"><path d="M4.5 4.5l7 7M11.5 4.5l-7 7" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" /></svg>
|
|
41
44
|
</button>
|
|
42
45
|
}
|
|
@@ -58,7 +61,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
58
61
|
template: `
|
|
59
62
|
<span class="mx-chip-label" #label><ng-content /></span>
|
|
60
63
|
@if (removable()) {
|
|
61
|
-
<button type="button" class="mx-chip-remove" [disabled]="disabled()" [attr.aria-label]="removeLabel() + ' ' + text()" (click)="removed.emit()">
|
|
64
|
+
<button type="button" class="mx-chip-remove" [disabled]="disabled()" [attr.aria-label]="(removeLabel() ?? msg().remove) + ' ' + text()" (click)="removed.emit()">
|
|
62
65
|
<svg viewBox="0 0 16 16" aria-hidden="true"><path d="M4.5 4.5l7 7M11.5 4.5l-7 7" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" /></svg>
|
|
63
66
|
</button>
|
|
64
67
|
}
|
|
@@ -117,8 +120,8 @@ class MxTagInput {
|
|
|
117
120
|
/** Valida cada etiqueta antes de a acrescentar (ex.: email). Devolve a mensagem de erro ou null. */
|
|
118
121
|
validate = input(() => null, ...(ngDevMode ? [{ debugName: "validate" }] : /* istanbul ignore next */ []));
|
|
119
122
|
/** Nome da lista para o leitor de ecrã. */
|
|
120
|
-
listLabel = input(
|
|
121
|
-
helpText = input(
|
|
123
|
+
listLabel = input(...(ngDevMode ? [undefined, { debugName: "listLabel" }] : /* istanbul ignore next */ []));
|
|
124
|
+
helpText = input(...(ngDevMode ? [undefined, { debugName: "helpText" }] : /* istanbul ignore next */ []));
|
|
122
125
|
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
123
126
|
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
124
127
|
required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
@@ -130,6 +133,8 @@ class MxTagInput {
|
|
|
130
133
|
field = inject(MxFormField, { optional: true });
|
|
131
134
|
ngControl = inject(NgControl, { self: true, optional: true });
|
|
132
135
|
announcer = inject(LiveAnnouncer);
|
|
136
|
+
i18n = injectMxMessages();
|
|
137
|
+
msg = computed(() => this.i18n().chips, ...(ngDevMode ? [{ debugName: "msg" }] : /* istanbul ignore next */ []));
|
|
133
138
|
host = inject(ElementRef).nativeElement;
|
|
134
139
|
input = viewChild.required('input');
|
|
135
140
|
injector = inject(Injector);
|
|
@@ -158,20 +163,20 @@ class MxTagInput {
|
|
|
158
163
|
return false;
|
|
159
164
|
};
|
|
160
165
|
if (this.tags().length >= this.maxTags())
|
|
161
|
-
return reject(
|
|
166
|
+
return reject(this.msg().max(this.maxTags()));
|
|
162
167
|
if (!this.allowDuplicates() && this.tags().some((t) => t.toLocaleLowerCase() === tag.toLocaleLowerCase()))
|
|
163
|
-
return reject(
|
|
168
|
+
return reject(this.msg().duplicate(tag));
|
|
164
169
|
const error = this.validate()(tag);
|
|
165
170
|
if (error)
|
|
166
171
|
return reject(error);
|
|
167
172
|
this.update([...this.tags(), tag]);
|
|
168
|
-
this.announcer.announce(
|
|
173
|
+
this.announcer.announce(this.msg().added(tag));
|
|
169
174
|
return true;
|
|
170
175
|
}
|
|
171
176
|
remove(index) {
|
|
172
177
|
const tag = this.tags()[index];
|
|
173
178
|
this.update(this.tags().filter((_, i) => i !== index));
|
|
174
|
-
this.announcer.announce(
|
|
179
|
+
this.announcer.announce(this.msg().removed(tag));
|
|
175
180
|
// o foco passa para a etiqueta seguinte, ou para o campo
|
|
176
181
|
afterNextRender(() => {
|
|
177
182
|
const chips = this.host.querySelectorAll('.mx-chip-remove');
|
|
@@ -262,7 +267,7 @@ class MxTagInput {
|
|
|
262
267
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: MxTagInput, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
263
268
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: MxTagInput, isStandalone: true, selector: "mx-tag-input", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, separators: { classPropertyName: "separators", publicName: "separators", isSignal: true, isRequired: false, transformFunction: null }, maxTags: { classPropertyName: "maxTags", publicName: "maxTags", isSignal: true, isRequired: false, transformFunction: null }, allowDuplicates: { classPropertyName: "allowDuplicates", publicName: "allowDuplicates", isSignal: true, isRequired: false, transformFunction: null }, validate: { classPropertyName: "validate", publicName: "validate", isSignal: true, isRequired: false, transformFunction: null }, listLabel: { classPropertyName: "listLabel", publicName: "listLabel", isSignal: true, isRequired: false, transformFunction: null }, helpText: { classPropertyName: "helpText", publicName: "helpText", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", rejected: "rejected" }, host: { listeners: { "click": "focusInput($event)" }, properties: { "attr.data-size": "size() === \"md\" ? null : size()", "attr.data-invalid": "errorState() ? \"\" : null", "attr.data-disabled": "isDisabled() ? \"\" : null", "attr.aria-label": "null" }, classAttribute: "mx-tag-input" }, providers: [{ provide: MX_FORM_FIELD_CONTROL, useExisting: MxTagInput }], viewQueries: [{ propertyName: "input", first: true, predicate: ["input"], descendants: true, isSignal: true }], exportAs: ["mxTagInput"], ngImport: i0, template: `
|
|
264
269
|
@if (tags().length) {
|
|
265
|
-
<ul class="mx-tag-input-list" [attr.aria-label]="listLabel()">
|
|
270
|
+
<ul class="mx-tag-input-list" [attr.aria-label]="listLabel() ?? msg().list">
|
|
266
271
|
@for (t of tags(); track t; let i = $index) {
|
|
267
272
|
<li>
|
|
268
273
|
<mx-chip size="sm" [removable]="!isDisabled()" (removed)="remove(i)" (keydown)="onChipKey($event, i)">{{ t }}</mx-chip>
|
|
@@ -288,7 +293,7 @@ class MxTagInput {
|
|
|
288
293
|
(blur)="onBlur()"
|
|
289
294
|
(paste)="onPaste($event)"
|
|
290
295
|
/>
|
|
291
|
-
<span class="mx-visually-hidden" [id]="helpId">{{ helpText() }}</span>
|
|
296
|
+
<span class="mx-visually-hidden" [id]="helpId">{{ helpText() ?? msg().help }}</span>
|
|
292
297
|
`, isInline: true, dependencies: [{ kind: "component", type: MxChip, selector: "mx-chip", inputs: ["removable", "disabled", "variant", "size", "removeLabel"], outputs: ["removed"], exportAs: ["mxChip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
293
298
|
}
|
|
294
299
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: MxTagInput, decorators: [{
|
|
@@ -310,7 +315,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
310
315
|
},
|
|
311
316
|
template: `
|
|
312
317
|
@if (tags().length) {
|
|
313
|
-
<ul class="mx-tag-input-list" [attr.aria-label]="listLabel()">
|
|
318
|
+
<ul class="mx-tag-input-list" [attr.aria-label]="listLabel() ?? msg().list">
|
|
314
319
|
@for (t of tags(); track t; let i = $index) {
|
|
315
320
|
<li>
|
|
316
321
|
<mx-chip size="sm" [removable]="!isDisabled()" (removed)="remove(i)" (keydown)="onChipKey($event, i)">{{ t }}</mx-chip>
|
|
@@ -336,7 +341,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
336
341
|
(blur)="onBlur()"
|
|
337
342
|
(paste)="onPaste($event)"
|
|
338
343
|
/>
|
|
339
|
-
<span class="mx-visually-hidden" [id]="helpId">{{ helpText() }}</span>
|
|
344
|
+
<span class="mx-visually-hidden" [id]="helpId">{{ helpText() ?? msg().help }}</span>
|
|
340
345
|
`,
|
|
341
346
|
}]
|
|
342
347
|
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], separators: [{ type: i0.Input, args: [{ isSignal: true, alias: "separators", required: false }] }], maxTags: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxTags", required: false }] }], allowDuplicates: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowDuplicates", required: false }] }], validate: [{ type: i0.Input, args: [{ isSignal: true, alias: "validate", required: false }] }], listLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "listLabel", required: false }] }], helpText: [{ type: i0.Input, args: [{ isSignal: true, alias: "helpText", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], rejected: [{ type: i0.Output, args: ["rejected"] }], input: [{ type: i0.ViewChild, args: ['input', { isSignal: true }] }] } });
|