@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
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { model, input, booleanAttribute, computed, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { injectMxMessages } from '@muxima-ui/core/i18n';
|
|
3
4
|
import { mxUniqueId } from '@muxima-ui/core/form-field';
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -31,18 +32,20 @@ class MxPagination {
|
|
|
31
32
|
variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
32
33
|
/** Páginas mostradas de cada lado da actual (variante default). */
|
|
33
34
|
siblings = input(1, ...(ngDevMode ? [{ debugName: "siblings" }] : /* istanbul ignore next */ []));
|
|
34
|
-
ariaLabel = input(
|
|
35
|
+
ariaLabel = input(undefined, { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: 'aria-label' });
|
|
36
|
+
i18n = injectMxMessages();
|
|
37
|
+
msg = computed(() => this.i18n().pagination, ...(ngDevMode ? [{ debugName: "msg" }] : /* istanbul ignore next */ []));
|
|
35
38
|
sizeId = mxUniqueId('mx-pagination-size');
|
|
36
39
|
pageCount = computed(() => Math.max(1, Math.ceil(this.total() / this.pageSize())), ...(ngDevMode ? [{ debugName: "pageCount" }] : /* istanbul ignore next */ []));
|
|
37
40
|
current = computed(() => Math.min(Math.max(this.page(), 1), this.pageCount()), ...(ngDevMode ? [{ debugName: "current" }] : /* istanbul ignore next */ []));
|
|
38
41
|
rangeText = computed(() => {
|
|
39
42
|
const total = this.total();
|
|
40
43
|
if (!total)
|
|
41
|
-
return
|
|
44
|
+
return this.msg().noResults;
|
|
42
45
|
const from = (this.current() - 1) * this.pageSize() + 1;
|
|
43
46
|
const to = Math.min(this.current() * this.pageSize(), total);
|
|
44
|
-
const fmt = new Intl.NumberFormat(
|
|
45
|
-
return
|
|
47
|
+
const fmt = new Intl.NumberFormat(this.i18n().intlLocale);
|
|
48
|
+
return this.msg().range(fmt.format(from), fmt.format(to), fmt.format(total));
|
|
46
49
|
}, ...(ngDevMode ? [{ debugName: "rangeText" }] : /* istanbul ignore next */ []));
|
|
47
50
|
slots = computed(() => {
|
|
48
51
|
const count = this.pageCount();
|
|
@@ -85,7 +88,7 @@ class MxPagination {
|
|
|
85
88
|
<div class="mx-pagination-info">
|
|
86
89
|
@if (pageSizeOptions().length) {
|
|
87
90
|
<label class="mx-pagination-size" [for]="sizeId">
|
|
88
|
-
<span>
|
|
91
|
+
<span>{{ msg().rowsPerPage }}</span>
|
|
89
92
|
<span class="mx-pagination-select-wrap">
|
|
90
93
|
<select class="mx-pagination-select" [id]="sizeId" (change)="changeSize($event)">
|
|
91
94
|
@for (o of pageSizeOptions(); track o) {
|
|
@@ -100,20 +103,20 @@ class MxPagination {
|
|
|
100
103
|
}
|
|
101
104
|
</div>
|
|
102
105
|
}
|
|
103
|
-
<nav [attr.aria-label]="ariaLabel()">
|
|
106
|
+
<nav [attr.aria-label]="ariaLabel() ?? msg().label">
|
|
104
107
|
<ul class="mx-pagination-list">
|
|
105
108
|
@if (variant() === 'compact') {
|
|
106
109
|
<li>
|
|
107
|
-
<button type="button" class="mx-pagination-button" [disabled]="current() <= 1" (click)="go(1)" aria-label="
|
|
110
|
+
<button type="button" class="mx-pagination-button" [disabled]="current() <= 1" (click)="go(1)" [attr.aria-label]="msg().first">
|
|
108
111
|
<svg viewBox="0 0 16 16" aria-hidden="true"><path d="M11 4L7 8l4 4M5 4v8" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg>
|
|
109
112
|
</button>
|
|
110
113
|
</li>
|
|
111
114
|
}
|
|
112
115
|
<li>
|
|
113
|
-
<button type="button" class="mx-pagination-button mx-pagination-edge" [disabled]="current() <= 1" (click)="go(current() - 1)" aria-label="
|
|
116
|
+
<button type="button" class="mx-pagination-button mx-pagination-edge" [disabled]="current() <= 1" (click)="go(current() - 1)" [attr.aria-label]="msg().previous">
|
|
114
117
|
<svg viewBox="0 0 16 16" aria-hidden="true"><path d="M10 4L6 8l4 4" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg>
|
|
115
118
|
@if (variant() !== 'compact') {
|
|
116
|
-
<span class="mx-pagination-edge-label" aria-hidden="true">
|
|
119
|
+
<span class="mx-pagination-edge-label" aria-hidden="true">{{ msg().previousShort }}</span>
|
|
117
120
|
}
|
|
118
121
|
</button>
|
|
119
122
|
</li>
|
|
@@ -125,7 +128,7 @@ class MxPagination {
|
|
|
125
128
|
type="button"
|
|
126
129
|
class="mx-pagination-button"
|
|
127
130
|
[attr.aria-current]="s.page === current() ? 'page' : null"
|
|
128
|
-
[attr.aria-label]="
|
|
131
|
+
[attr.aria-label]="msg().page(s.page)"
|
|
129
132
|
(click)="go(s.page)"
|
|
130
133
|
>
|
|
131
134
|
{{ s.page }}
|
|
@@ -138,24 +141,24 @@ class MxPagination {
|
|
|
138
141
|
} @else {
|
|
139
142
|
<li class="mx-pagination-status" aria-current="page">
|
|
140
143
|
@if (variant() === 'simple') {
|
|
141
|
-
|
|
144
|
+
{{ msg().pageOf(current(), pageCount()) }}
|
|
142
145
|
} @else {
|
|
143
146
|
<span aria-hidden="true">{{ current() }} / {{ pageCount() }}</span>
|
|
144
|
-
<span class="mx-visually-hidden">
|
|
147
|
+
<span class="mx-visually-hidden">{{ msg().pageOf(current(), pageCount()) }}</span>
|
|
145
148
|
}
|
|
146
149
|
</li>
|
|
147
150
|
}
|
|
148
151
|
<li>
|
|
149
|
-
<button type="button" class="mx-pagination-button mx-pagination-edge" [disabled]="current() >= pageCount()" (click)="go(current() + 1)" aria-label="
|
|
152
|
+
<button type="button" class="mx-pagination-button mx-pagination-edge" [disabled]="current() >= pageCount()" (click)="go(current() + 1)" [attr.aria-label]="msg().next">
|
|
150
153
|
@if (variant() !== 'compact') {
|
|
151
|
-
<span class="mx-pagination-edge-label" aria-hidden="true">
|
|
154
|
+
<span class="mx-pagination-edge-label" aria-hidden="true">{{ msg().nextShort }}</span>
|
|
152
155
|
}
|
|
153
156
|
<svg viewBox="0 0 16 16" aria-hidden="true"><path d="M6 4l4 4-4 4" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg>
|
|
154
157
|
</button>
|
|
155
158
|
</li>
|
|
156
159
|
@if (variant() === 'compact') {
|
|
157
160
|
<li>
|
|
158
|
-
<button type="button" class="mx-pagination-button" [disabled]="current() >= pageCount()" (click)="go(pageCount())" aria-label="
|
|
161
|
+
<button type="button" class="mx-pagination-button" [disabled]="current() >= pageCount()" (click)="go(pageCount())" [attr.aria-label]="msg().last">
|
|
159
162
|
<svg viewBox="0 0 16 16" aria-hidden="true"><path d="M5 4l4 4-4 4M11 4v8" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg>
|
|
160
163
|
</button>
|
|
161
164
|
</li>
|
|
@@ -182,7 +185,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
182
185
|
<div class="mx-pagination-info">
|
|
183
186
|
@if (pageSizeOptions().length) {
|
|
184
187
|
<label class="mx-pagination-size" [for]="sizeId">
|
|
185
|
-
<span>
|
|
188
|
+
<span>{{ msg().rowsPerPage }}</span>
|
|
186
189
|
<span class="mx-pagination-select-wrap">
|
|
187
190
|
<select class="mx-pagination-select" [id]="sizeId" (change)="changeSize($event)">
|
|
188
191
|
@for (o of pageSizeOptions(); track o) {
|
|
@@ -197,20 +200,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
197
200
|
}
|
|
198
201
|
</div>
|
|
199
202
|
}
|
|
200
|
-
<nav [attr.aria-label]="ariaLabel()">
|
|
203
|
+
<nav [attr.aria-label]="ariaLabel() ?? msg().label">
|
|
201
204
|
<ul class="mx-pagination-list">
|
|
202
205
|
@if (variant() === 'compact') {
|
|
203
206
|
<li>
|
|
204
|
-
<button type="button" class="mx-pagination-button" [disabled]="current() <= 1" (click)="go(1)" aria-label="
|
|
207
|
+
<button type="button" class="mx-pagination-button" [disabled]="current() <= 1" (click)="go(1)" [attr.aria-label]="msg().first">
|
|
205
208
|
<svg viewBox="0 0 16 16" aria-hidden="true"><path d="M11 4L7 8l4 4M5 4v8" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg>
|
|
206
209
|
</button>
|
|
207
210
|
</li>
|
|
208
211
|
}
|
|
209
212
|
<li>
|
|
210
|
-
<button type="button" class="mx-pagination-button mx-pagination-edge" [disabled]="current() <= 1" (click)="go(current() - 1)" aria-label="
|
|
213
|
+
<button type="button" class="mx-pagination-button mx-pagination-edge" [disabled]="current() <= 1" (click)="go(current() - 1)" [attr.aria-label]="msg().previous">
|
|
211
214
|
<svg viewBox="0 0 16 16" aria-hidden="true"><path d="M10 4L6 8l4 4" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg>
|
|
212
215
|
@if (variant() !== 'compact') {
|
|
213
|
-
<span class="mx-pagination-edge-label" aria-hidden="true">
|
|
216
|
+
<span class="mx-pagination-edge-label" aria-hidden="true">{{ msg().previousShort }}</span>
|
|
214
217
|
}
|
|
215
218
|
</button>
|
|
216
219
|
</li>
|
|
@@ -222,7 +225,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
222
225
|
type="button"
|
|
223
226
|
class="mx-pagination-button"
|
|
224
227
|
[attr.aria-current]="s.page === current() ? 'page' : null"
|
|
225
|
-
[attr.aria-label]="
|
|
228
|
+
[attr.aria-label]="msg().page(s.page)"
|
|
226
229
|
(click)="go(s.page)"
|
|
227
230
|
>
|
|
228
231
|
{{ s.page }}
|
|
@@ -235,24 +238,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
235
238
|
} @else {
|
|
236
239
|
<li class="mx-pagination-status" aria-current="page">
|
|
237
240
|
@if (variant() === 'simple') {
|
|
238
|
-
|
|
241
|
+
{{ msg().pageOf(current(), pageCount()) }}
|
|
239
242
|
} @else {
|
|
240
243
|
<span aria-hidden="true">{{ current() }} / {{ pageCount() }}</span>
|
|
241
|
-
<span class="mx-visually-hidden">
|
|
244
|
+
<span class="mx-visually-hidden">{{ msg().pageOf(current(), pageCount()) }}</span>
|
|
242
245
|
}
|
|
243
246
|
</li>
|
|
244
247
|
}
|
|
245
248
|
<li>
|
|
246
|
-
<button type="button" class="mx-pagination-button mx-pagination-edge" [disabled]="current() >= pageCount()" (click)="go(current() + 1)" aria-label="
|
|
249
|
+
<button type="button" class="mx-pagination-button mx-pagination-edge" [disabled]="current() >= pageCount()" (click)="go(current() + 1)" [attr.aria-label]="msg().next">
|
|
247
250
|
@if (variant() !== 'compact') {
|
|
248
|
-
<span class="mx-pagination-edge-label" aria-hidden="true">
|
|
251
|
+
<span class="mx-pagination-edge-label" aria-hidden="true">{{ msg().nextShort }}</span>
|
|
249
252
|
}
|
|
250
253
|
<svg viewBox="0 0 16 16" aria-hidden="true"><path d="M6 4l4 4-4 4" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg>
|
|
251
254
|
</button>
|
|
252
255
|
</li>
|
|
253
256
|
@if (variant() === 'compact') {
|
|
254
257
|
<li>
|
|
255
|
-
<button type="button" class="mx-pagination-button" [disabled]="current() >= pageCount()" (click)="go(pageCount())" aria-label="
|
|
258
|
+
<button type="button" class="mx-pagination-button" [disabled]="current() >= pageCount()" (click)="go(pageCount())" [attr.aria-label]="msg().last">
|
|
256
259
|
<svg viewBox="0 0 16 16" aria-hidden="true"><path d="M5 4l4 4-4 4M11 4v8" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg>
|
|
257
260
|
</button>
|
|
258
261
|
</li>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"muxima-ui-core-pagination.mjs","sources":["../../../projects/core/pagination/pagination.ts","../../../projects/core/pagination/muxima-ui-core-pagination.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, ViewEncapsulation, booleanAttribute, computed, input, model } from '@angular/core';\nimport { mxUniqueId } from '@muxima-ui/core/form-field';\n\ntype Slot = { type: 'page'; page: number } | { type: 'gap'; key: string };\n\nexport type MxPaginationVariant = 'default' | 'simple' | 'compact';\n\n/**\n * Navegação entre páginas de resultados.\n *\n * ```html\n * <mx-pagination [(page)]=\"pagina\" [total]=\"236\" [pageSize]=\"20\" />\n * <mx-pagination variant=\"simple\" [(page)]=\"pagina\" [total]=\"236\" />\n * <mx-pagination [(page)]=\"pagina\" [(pageSize)]=\"linhas\" [pageSizeOptions]=\"[10, 20, 50]\" showRange [total]=\"236\" />\n * ```\n *\n * - default: números das páginas, com reticências.\n * - simple: Anterior, \"Página 3 de 12\", Seguinte.\n * - compact: primeira, anterior, \"3 / 12\", seguinte e última, só com ícones (para barras estreitas).\n *\n * A página actual tem aria-current=\"page\"; os botões nas pontas ficam desactivados.\n */\n@Component({\n selector: 'mx-pagination',\n exportAs: 'mxPagination',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'mx-pagination',\n '[attr.data-variant]': 'variant() === \"default\" ? null : variant()',\n '[attr.data-extras]': 'pageSizeOptions().length || showRange() ? \"\" : null',\n '[attr.aria-label]': 'null',\n },\n template: `\n @if (pageSizeOptions().length || showRange()) {\n <div class=\"mx-pagination-info\">\n @if (pageSizeOptions().length) {\n <label class=\"mx-pagination-size\" [for]=\"sizeId\">\n <span>Linhas por página</span>\n <span class=\"mx-pagination-select-wrap\">\n <select class=\"mx-pagination-select\" [id]=\"sizeId\" (change)=\"changeSize($event)\">\n @for (o of pageSizeOptions(); track o) {\n <option [value]=\"o\" [selected]=\"o === pageSize()\">{{ o }}</option>\n }\n </select>\n </span>\n </label>\n }\n @if (showRange()) {\n <span class=\"mx-pagination-range\" aria-live=\"polite\">{{ rangeText() }}</span>\n }\n </div>\n }\n <nav [attr.aria-label]=\"ariaLabel()\">\n <ul class=\"mx-pagination-list\">\n @if (variant() === 'compact') {\n <li>\n <button type=\"button\" class=\"mx-pagination-button\" [disabled]=\"current() <= 1\" (click)=\"go(1)\" aria-label=\"Primeira página\">\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M11 4L7 8l4 4M5 4v8\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /></svg>\n </button>\n </li>\n }\n <li>\n <button type=\"button\" class=\"mx-pagination-button mx-pagination-edge\" [disabled]=\"current() <= 1\" (click)=\"go(current() - 1)\" aria-label=\"Página anterior\">\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M10 4L6 8l4 4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /></svg>\n @if (variant() !== 'compact') {\n <span class=\"mx-pagination-edge-label\" aria-hidden=\"true\">Anterior</span>\n }\n </button>\n </li>\n @if (variant() === 'default') {\n @for (s of slots(); track s.type === 'page' ? s.page : s.key) {\n <li>\n @if (s.type === 'page') {\n <button\n type=\"button\"\n class=\"mx-pagination-button\"\n [attr.aria-current]=\"s.page === current() ? 'page' : null\"\n [attr.aria-label]=\"'Página ' + s.page\"\n (click)=\"go(s.page)\"\n >\n {{ s.page }}\n </button>\n } @else {\n <span class=\"mx-pagination-gap\" aria-hidden=\"true\">…</span>\n }\n </li>\n }\n } @else {\n <li class=\"mx-pagination-status\" aria-current=\"page\">\n @if (variant() === 'simple') {\n Página {{ current() }} de {{ pageCount() }}\n } @else {\n <span aria-hidden=\"true\">{{ current() }} / {{ pageCount() }}</span>\n <span class=\"mx-visually-hidden\">Página {{ current() }} de {{ pageCount() }}</span>\n }\n </li>\n }\n <li>\n <button type=\"button\" class=\"mx-pagination-button mx-pagination-edge\" [disabled]=\"current() >= pageCount()\" (click)=\"go(current() + 1)\" aria-label=\"Página seguinte\">\n @if (variant() !== 'compact') {\n <span class=\"mx-pagination-edge-label\" aria-hidden=\"true\">Seguinte</span>\n }\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M6 4l4 4-4 4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /></svg>\n </button>\n </li>\n @if (variant() === 'compact') {\n <li>\n <button type=\"button\" class=\"mx-pagination-button\" [disabled]=\"current() >= pageCount()\" (click)=\"go(pageCount())\" aria-label=\"Última página\">\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M5 4l4 4-4 4M11 4v8\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /></svg>\n </button>\n </li>\n }\n </ul>\n </nav>\n `,\n})\nexport class MxPagination {\n /** Página actual, a começar em 1. */\n readonly page = model(1);\n /** Número total de itens. */\n readonly total = input.required<number>();\n /** Itens por página. Aceita [(pageSize)] quando há pageSizeOptions. */\n readonly pageSize = model(10);\n /** Opções de \"Linhas por página\". Vazio = sem escolha. */\n readonly pageSizeOptions = input<number[]>([]);\n /** Mostra \"21–40 de 236\". */\n readonly showRange = input(false, { transform: booleanAttribute });\n readonly variant = input<MxPaginationVariant>('default');\n /** Páginas mostradas de cada lado da actual (variante default). */\n readonly siblings = input(1);\n readonly ariaLabel = input('Paginação', { alias: 'aria-label' });\n\n protected readonly sizeId = mxUniqueId('mx-pagination-size');\n readonly pageCount = computed(() => Math.max(1, Math.ceil(this.total() / this.pageSize())));\n protected readonly current = computed(() => Math.min(Math.max(this.page(), 1), this.pageCount()));\n\n protected readonly rangeText = computed(() => {\n const total = this.total();\n if (!total) return '0 resultados';\n const from = (this.current() - 1) * this.pageSize() + 1;\n const to = Math.min(this.current() * this.pageSize(), total);\n const fmt = new Intl.NumberFormat('pt-AO');\n return `${fmt.format(from)}–${fmt.format(to)} de ${fmt.format(total)}`;\n });\n\n protected readonly slots = computed<Slot[]>(() => {\n const count = this.pageCount();\n const current = this.current();\n const s = this.siblings();\n const pages = new Set<number>([1, count]);\n for (let p = current - s; p <= current + s; p++) if (p >= 1 && p <= count) pages.add(p);\n // evita um \"…\" que esconde só uma página\n const sorted = [...pages].sort((a, b) => a - b);\n const out: Slot[] = [];\n sorted.forEach((p, i) => {\n const prev = sorted[i - 1];\n if (prev !== undefined) {\n if (p - prev === 2) out.push({ type: 'page', page: p - 1 });\n else if (p - prev > 2) out.push({ type: 'gap', key: `gap-${prev}` });\n }\n out.push({ type: 'page', page: p });\n });\n return out;\n });\n\n go(p: number): void {\n const next = Math.min(Math.max(p, 1), this.pageCount());\n if (next !== this.page()) this.page.set(next);\n }\n\n protected changeSize(event: Event): void {\n const size = Number((event.target as HTMLSelectElement).value);\n // mantém o primeiro item visível na nova página\n const first = (this.current() - 1) * this.pageSize();\n this.pageSize.set(size);\n this.page.set(Math.floor(first / size) + 1);\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-pagination.mjs","sources":["../../../projects/core/pagination/pagination.ts","../../../projects/core/pagination/muxima-ui-core-pagination.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, ViewEncapsulation, booleanAttribute, computed, input, model } from '@angular/core';\nimport { injectMxMessages } from '@muxima-ui/core/i18n';\nimport { mxUniqueId } from '@muxima-ui/core/form-field';\n\ntype Slot = { type: 'page'; page: number } | { type: 'gap'; key: string };\n\nexport type MxPaginationVariant = 'default' | 'simple' | 'compact';\n\n/**\n * Navegação entre páginas de resultados.\n *\n * ```html\n * <mx-pagination [(page)]=\"pagina\" [total]=\"236\" [pageSize]=\"20\" />\n * <mx-pagination variant=\"simple\" [(page)]=\"pagina\" [total]=\"236\" />\n * <mx-pagination [(page)]=\"pagina\" [(pageSize)]=\"linhas\" [pageSizeOptions]=\"[10, 20, 50]\" showRange [total]=\"236\" />\n * ```\n *\n * - default: números das páginas, com reticências.\n * - simple: Anterior, \"Página 3 de 12\", Seguinte.\n * - compact: primeira, anterior, \"3 / 12\", seguinte e última, só com ícones (para barras estreitas).\n *\n * A página actual tem aria-current=\"page\"; os botões nas pontas ficam desactivados.\n */\n@Component({\n selector: 'mx-pagination',\n exportAs: 'mxPagination',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'mx-pagination',\n '[attr.data-variant]': 'variant() === \"default\" ? null : variant()',\n '[attr.data-extras]': 'pageSizeOptions().length || showRange() ? \"\" : null',\n '[attr.aria-label]': 'null',\n },\n template: `\n @if (pageSizeOptions().length || showRange()) {\n <div class=\"mx-pagination-info\">\n @if (pageSizeOptions().length) {\n <label class=\"mx-pagination-size\" [for]=\"sizeId\">\n <span>{{ msg().rowsPerPage }}</span>\n <span class=\"mx-pagination-select-wrap\">\n <select class=\"mx-pagination-select\" [id]=\"sizeId\" (change)=\"changeSize($event)\">\n @for (o of pageSizeOptions(); track o) {\n <option [value]=\"o\" [selected]=\"o === pageSize()\">{{ o }}</option>\n }\n </select>\n </span>\n </label>\n }\n @if (showRange()) {\n <span class=\"mx-pagination-range\" aria-live=\"polite\">{{ rangeText() }}</span>\n }\n </div>\n }\n <nav [attr.aria-label]=\"ariaLabel() ?? msg().label\">\n <ul class=\"mx-pagination-list\">\n @if (variant() === 'compact') {\n <li>\n <button type=\"button\" class=\"mx-pagination-button\" [disabled]=\"current() <= 1\" (click)=\"go(1)\" [attr.aria-label]=\"msg().first\">\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M11 4L7 8l4 4M5 4v8\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /></svg>\n </button>\n </li>\n }\n <li>\n <button type=\"button\" class=\"mx-pagination-button mx-pagination-edge\" [disabled]=\"current() <= 1\" (click)=\"go(current() - 1)\" [attr.aria-label]=\"msg().previous\">\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M10 4L6 8l4 4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /></svg>\n @if (variant() !== 'compact') {\n <span class=\"mx-pagination-edge-label\" aria-hidden=\"true\">{{ msg().previousShort }}</span>\n }\n </button>\n </li>\n @if (variant() === 'default') {\n @for (s of slots(); track s.type === 'page' ? s.page : s.key) {\n <li>\n @if (s.type === 'page') {\n <button\n type=\"button\"\n class=\"mx-pagination-button\"\n [attr.aria-current]=\"s.page === current() ? 'page' : null\"\n [attr.aria-label]=\"msg().page(s.page)\"\n (click)=\"go(s.page)\"\n >\n {{ s.page }}\n </button>\n } @else {\n <span class=\"mx-pagination-gap\" aria-hidden=\"true\">…</span>\n }\n </li>\n }\n } @else {\n <li class=\"mx-pagination-status\" aria-current=\"page\">\n @if (variant() === 'simple') {\n {{ msg().pageOf(current(), pageCount()) }}\n } @else {\n <span aria-hidden=\"true\">{{ current() }} / {{ pageCount() }}</span>\n <span class=\"mx-visually-hidden\">{{ msg().pageOf(current(), pageCount()) }}</span>\n }\n </li>\n }\n <li>\n <button type=\"button\" class=\"mx-pagination-button mx-pagination-edge\" [disabled]=\"current() >= pageCount()\" (click)=\"go(current() + 1)\" [attr.aria-label]=\"msg().next\">\n @if (variant() !== 'compact') {\n <span class=\"mx-pagination-edge-label\" aria-hidden=\"true\">{{ msg().nextShort }}</span>\n }\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M6 4l4 4-4 4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /></svg>\n </button>\n </li>\n @if (variant() === 'compact') {\n <li>\n <button type=\"button\" class=\"mx-pagination-button\" [disabled]=\"current() >= pageCount()\" (click)=\"go(pageCount())\" [attr.aria-label]=\"msg().last\">\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M5 4l4 4-4 4M11 4v8\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /></svg>\n </button>\n </li>\n }\n </ul>\n </nav>\n `,\n})\nexport class MxPagination {\n /** Página actual, a começar em 1. */\n readonly page = model(1);\n /** Número total de itens. */\n readonly total = input.required<number>();\n /** Itens por página. Aceita [(pageSize)] quando há pageSizeOptions. */\n readonly pageSize = model(10);\n /** Opções de \"Linhas por página\". Vazio = sem escolha. */\n readonly pageSizeOptions = input<number[]>([]);\n /** Mostra \"21–40 de 236\". */\n readonly showRange = input(false, { transform: booleanAttribute });\n readonly variant = input<MxPaginationVariant>('default');\n /** Páginas mostradas de cada lado da actual (variante default). */\n readonly siblings = input(1);\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\n private readonly i18n = injectMxMessages();\n protected readonly msg = computed(() => this.i18n().pagination);\n\n protected readonly sizeId = mxUniqueId('mx-pagination-size');\n readonly pageCount = computed(() => Math.max(1, Math.ceil(this.total() / this.pageSize())));\n protected readonly current = computed(() => Math.min(Math.max(this.page(), 1), this.pageCount()));\n\n protected readonly rangeText = computed(() => {\n const total = this.total();\n if (!total) return this.msg().noResults;\n const from = (this.current() - 1) * this.pageSize() + 1;\n const to = Math.min(this.current() * this.pageSize(), total);\n const fmt = new Intl.NumberFormat(this.i18n().intlLocale);\n return this.msg().range(fmt.format(from), fmt.format(to), fmt.format(total));\n });\n\n protected readonly slots = computed<Slot[]>(() => {\n const count = this.pageCount();\n const current = this.current();\n const s = this.siblings();\n const pages = new Set<number>([1, count]);\n for (let p = current - s; p <= current + s; p++) if (p >= 1 && p <= count) pages.add(p);\n // evita um \"…\" que esconde só uma página\n const sorted = [...pages].sort((a, b) => a - b);\n const out: Slot[] = [];\n sorted.forEach((p, i) => {\n const prev = sorted[i - 1];\n if (prev !== undefined) {\n if (p - prev === 2) out.push({ type: 'page', page: p - 1 });\n else if (p - prev > 2) out.push({ type: 'gap', key: `gap-${prev}` });\n }\n out.push({ type: 'page', page: p });\n });\n return out;\n });\n\n go(p: number): void {\n const next = Math.min(Math.max(p, 1), this.pageCount());\n if (next !== this.page()) this.page.set(next);\n }\n\n protected changeSize(event: Event): void {\n const size = Number((event.target as HTMLSelectElement).value);\n // mantém o primeiro item visível na nova página\n const first = (this.current() - 1) * this.pageSize();\n this.pageSize.set(size);\n this.page.set(Math.floor(first / size) + 1);\n }\n}\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
|
* Barra de progresso sobre o `<progress>` nativo. Sem `value` fica indeterminada.
|
|
@@ -28,11 +29,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
28
29
|
* ("A carregar" por omissão); dentro de um botão, usa antes `loading` no botão.
|
|
29
30
|
*/
|
|
30
31
|
class MxSpinner {
|
|
31
|
-
label = input(
|
|
32
|
+
label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : /* istanbul ignore next */ []));
|
|
33
|
+
i18n = injectMxMessages();
|
|
32
34
|
/** sm 14 px, md 20 px, lg 28 px. */
|
|
33
35
|
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
34
36
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: MxSpinner, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
35
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.25", type: MxSpinner, isStandalone: true, selector: "[mxSpinner]", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "status" }, properties: { "attr.aria-label": "label()", "attr.data-size": "size() === \"md\" ? null : size()" }, classAttribute: "mx-spinner" }, ngImport: i0 });
|
|
37
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.25", type: MxSpinner, isStandalone: true, selector: "[mxSpinner]", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "status" }, properties: { "attr.aria-label": "label() ?? i18n().progress.label", "attr.data-size": "size() === \"md\" ? null : size()" }, classAttribute: "mx-spinner" }, ngImport: i0 });
|
|
36
38
|
}
|
|
37
39
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: MxSpinner, decorators: [{
|
|
38
40
|
type: Directive,
|
|
@@ -41,7 +43,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
41
43
|
host: {
|
|
42
44
|
class: 'mx-spinner',
|
|
43
45
|
role: 'status',
|
|
44
|
-
'[attr.aria-label]': 'label()',
|
|
46
|
+
'[attr.aria-label]': 'label() ?? i18n().progress.label',
|
|
45
47
|
'[attr.data-size]': 'size() === "md" ? null : size()',
|
|
46
48
|
},
|
|
47
49
|
}]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"muxima-ui-core-progress.mjs","sources":["../../../projects/core/progress/progress.ts","../../../projects/core/progress/muxima-ui-core-progress.ts"],"sourcesContent":["import { Directive, input } from '@angular/core';\n\n/**\n * Barra de progresso sobre o `<progress>` nativo. Sem `value` fica indeterminada.\n * Dá-lhe um nome com `<label for>` ou aria-label.\n *\n * ```html\n * <label for=\"envio\">A enviar facturas</label>\n * <progress id=\"envio\" mxProgress [value]=\"42\" max=\"100\">42%</progress>\n * ```\n */\n@Directive({\n selector: 'progress[mxProgress]',\n host: { class: 'mx-progress', '[attr.data-size]': 'size() === \"md\" ? null : size()' },\n})\nexport class MxProgress {\n /** Espessura: sm 4 px, md 8 px, lg 12 px. */\n readonly size = input<'sm' | 'md' | 'lg'>('md');\n}\n\n/**\n * Indicador circular para esperas curtas. Tem role=\"status\" e um nome acessível\n * (\"A carregar\" por omissão); dentro de um botão, usa antes `loading` no botão.\n */\n@Directive({\n selector: '[mxSpinner]',\n host: {\n class: 'mx-spinner',\n role: 'status',\n '[attr.aria-label]': 'label()',\n '[attr.data-size]': 'size() === \"md\" ? null : size()',\n },\n})\nexport class MxSpinner {\n readonly label = input(
|
|
1
|
+
{"version":3,"file":"muxima-ui-core-progress.mjs","sources":["../../../projects/core/progress/progress.ts","../../../projects/core/progress/muxima-ui-core-progress.ts"],"sourcesContent":["import { Directive, input } from '@angular/core';\nimport { injectMxMessages } from '@muxima-ui/core/i18n';\n\n/**\n * Barra de progresso sobre o `<progress>` nativo. Sem `value` fica indeterminada.\n * Dá-lhe um nome com `<label for>` ou aria-label.\n *\n * ```html\n * <label for=\"envio\">A enviar facturas</label>\n * <progress id=\"envio\" mxProgress [value]=\"42\" max=\"100\">42%</progress>\n * ```\n */\n@Directive({\n selector: 'progress[mxProgress]',\n host: { class: 'mx-progress', '[attr.data-size]': 'size() === \"md\" ? null : size()' },\n})\nexport class MxProgress {\n /** Espessura: sm 4 px, md 8 px, lg 12 px. */\n readonly size = input<'sm' | 'md' | 'lg'>('md');\n}\n\n/**\n * Indicador circular para esperas curtas. Tem role=\"status\" e um nome acessível\n * (\"A carregar\" por omissão); dentro de um botão, usa antes `loading` no botão.\n */\n@Directive({\n selector: '[mxSpinner]',\n host: {\n class: 'mx-spinner',\n role: 'status',\n '[attr.aria-label]': 'label() ?? i18n().progress.label',\n '[attr.data-size]': 'size() === \"md\" ? null : size()',\n },\n})\nexport class MxSpinner {\n readonly label = input<string>();\n protected readonly i18n = injectMxMessages();\n /** sm 14 px, md 20 px, lg 28 px. */\n readonly size = input<'sm' | 'md' | 'lg'>('md');\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAGA;;;;;;;;AAQG;MAKU,UAAU,CAAA;;AAEZ,IAAA,IAAI,GAAG,KAAK,CAAqB,IAAI,2EAAC;wGAFpC,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;4FAAV,UAAU,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,sBAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,gBAAA,EAAA,mCAAA,EAAA,EAAA,cAAA,EAAA,aAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;4FAAV,UAAU,EAAA,UAAA,EAAA,CAAA;kBAJtB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,sBAAsB;oBAChC,IAAI,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,iCAAiC,EAAE;AACtF,iBAAA;;AAMD;;;AAGG;MAUU,SAAS,CAAA;IACX,KAAK,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,OAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAU;IACb,IAAI,GAAG,gBAAgB,EAAE;;AAEnC,IAAA,IAAI,GAAG,KAAK,CAAqB,IAAI,2EAAC;wGAJpC,SAAS,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;4FAAT,SAAS,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,kCAAA,EAAA,gBAAA,EAAA,mCAAA,EAAA,EAAA,cAAA,EAAA,YAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;4FAAT,SAAS,EAAA,UAAA,EAAA,CAAA;kBATrB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,aAAa;AACvB,oBAAA,IAAI,EAAE;AACJ,wBAAA,KAAK,EAAE,YAAY;AACnB,wBAAA,IAAI,EAAE,QAAQ;AACd,wBAAA,mBAAmB,EAAE,kCAAkC;AACvD,wBAAA,kBAAkB,EAAE,iCAAiC;AACtD,qBAAA;AACF,iBAAA;;;ACjCD;;AAEG;;"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { model, input, numberAttribute, booleanAttribute, inject, computed, signal, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { injectMxMessages } from '@muxima-ui/core/i18n';
|
|
3
4
|
import { NgControl, Validators } from '@angular/forms';
|
|
4
5
|
import { MxFormField, mxUniqueId, MX_FORM_FIELD_CONTROL } from '@muxima-ui/core/form-field';
|
|
5
6
|
|
|
@@ -25,8 +26,11 @@ class MxRating {
|
|
|
25
26
|
clearable = input(false, { ...(ngDevMode ? { debugName: "clearable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
26
27
|
/** Mostra o número ao lado ("4,5"). */
|
|
27
28
|
showValue = input(false, { ...(ngDevMode ? { debugName: "showValue" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
/** Nome de cada estrela; por omissão "1 estrela", "2 estrelas" no idioma activo. */
|
|
30
|
+
starLabel = input(...(ngDevMode ? [undefined, { debugName: "starLabel" }] : /* istanbul ignore next */ []));
|
|
31
|
+
/** Locale dos números; por omissão o do idioma activo. */
|
|
32
|
+
locale = input(...(ngDevMode ? [undefined, { debugName: "locale" }] : /* istanbul ignore next */ []));
|
|
33
|
+
i18n = injectMxMessages();
|
|
30
34
|
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
31
35
|
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
32
36
|
required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
@@ -44,8 +48,8 @@ class MxRating {
|
|
|
44
48
|
isDisabled = computed(() => this.disabled() || this.formDisabled(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
45
49
|
stars = computed(() => Array.from({ length: this.max() }, (_, i) => i + 1), ...(ngDevMode ? [{ debugName: "stars" }] : /* istanbul ignore next */ []));
|
|
46
50
|
shown = computed(() => this.hover() || this.value() || 0, ...(ngDevMode ? [{ debugName: "shown" }] : /* istanbul ignore next */ []));
|
|
47
|
-
valueText = computed(() => new Intl.NumberFormat(this.locale(), { maximumFractionDigits: 1 }).format(this.value() ?? 0), ...(ngDevMode ? [{ debugName: "valueText" }] : /* istanbul ignore next */ []));
|
|
48
|
-
readonlyLabel = computed(() =>
|
|
51
|
+
valueText = computed(() => new Intl.NumberFormat(this.locale() ?? this.i18n().intlLocale, { maximumFractionDigits: 1 }).format(this.value() ?? 0), ...(ngDevMode ? [{ debugName: "valueText" }] : /* istanbul ignore next */ []));
|
|
52
|
+
readonlyLabel = computed(() => this.i18n().rating.summary(this.valueText(), this.max()), ...(ngDevMode ? [{ debugName: "readonlyLabel" }] : /* istanbul ignore next */ []));
|
|
49
53
|
onChange = () => { };
|
|
50
54
|
onTouched = () => { };
|
|
51
55
|
constructor() {
|
|
@@ -109,7 +113,7 @@ class MxRating {
|
|
|
109
113
|
class="mx-rating-stars"
|
|
110
114
|
role="radiogroup"
|
|
111
115
|
[attr.aria-labelledby]="field?.labelId() ?? null"
|
|
112
|
-
[attr.aria-label]="field?.labelId() ? null : (ariaLabel() ??
|
|
116
|
+
[attr.aria-label]="field?.labelId() ? null : (ariaLabel() ?? i18n().rating.label)"
|
|
113
117
|
[attr.aria-describedby]="field?.describedBy() ?? null"
|
|
114
118
|
[attr.aria-required]="isRequired() ? 'true' : null"
|
|
115
119
|
[attr.aria-invalid]="errorState() ? 'true' : null"
|
|
@@ -129,7 +133,7 @@ class MxRating {
|
|
|
129
133
|
(click)="onClick(s)"
|
|
130
134
|
(blur)="onTouched()"
|
|
131
135
|
/>
|
|
132
|
-
<span class="mx-visually-hidden">{{ starLabel()(s) }}</span>
|
|
136
|
+
<span class="mx-visually-hidden">{{ (starLabel() ?? i18n().rating.star)(s) }}</span>
|
|
133
137
|
<svg viewBox="0 0 24 24" aria-hidden="true"><path [attr.d]="star" /></svg>
|
|
134
138
|
</label>
|
|
135
139
|
}
|
|
@@ -171,7 +175,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
171
175
|
class="mx-rating-stars"
|
|
172
176
|
role="radiogroup"
|
|
173
177
|
[attr.aria-labelledby]="field?.labelId() ?? null"
|
|
174
|
-
[attr.aria-label]="field?.labelId() ? null : (ariaLabel() ??
|
|
178
|
+
[attr.aria-label]="field?.labelId() ? null : (ariaLabel() ?? i18n().rating.label)"
|
|
175
179
|
[attr.aria-describedby]="field?.describedBy() ?? null"
|
|
176
180
|
[attr.aria-required]="isRequired() ? 'true' : null"
|
|
177
181
|
[attr.aria-invalid]="errorState() ? 'true' : null"
|
|
@@ -191,7 +195,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
191
195
|
(click)="onClick(s)"
|
|
192
196
|
(blur)="onTouched()"
|
|
193
197
|
/>
|
|
194
|
-
<span class="mx-visually-hidden">{{ starLabel()(s) }}</span>
|
|
198
|
+
<span class="mx-visually-hidden">{{ (starLabel() ?? i18n().rating.star)(s) }}</span>
|
|
195
199
|
<svg viewBox="0 0 24 24" aria-hidden="true"><path [attr.d]="star" /></svg>
|
|
196
200
|
</label>
|
|
197
201
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"muxima-ui-core-rating.mjs","sources":["../../../projects/core/rating/rating.ts","../../../projects/core/rating/muxima-ui-core-rating.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n booleanAttribute,\n computed,\n inject,\n input,\n model,\n numberAttribute,\n signal,\n} from '@angular/core';\nimport { ControlValueAccessor, NgControl, Validators } from '@angular/forms';\nimport { MX_FORM_FIELD_CONTROL, MxFormField, MxFormFieldControl, mxUniqueId } from '@muxima-ui/core/form-field';\n\nconst STAR = 'M12 3.2l2.7 5.6 6.1.8-4.5 4.2 1.1 6.1L12 17l-5.4 2.9 1.1-6.1-4.5-4.2 6.1-.8z';\n\n/**\n * Avaliação com estrelas. Para escolher, são botões de rádio nativos (setas mudam a nota,\n * Tab sai do grupo); em `readonly` é uma imagem com o texto \"4 de 5 estrelas\".\n *\n * ```html\n * <mx-form-field>\n * <label mxLabel>Como correu o atendimento?</label>\n * <mx-rating formControlName=\"nota\" />\n * </mx-form-field>\n * <mx-rating [value]=\"4.5\" readonly />\n * ```\n */\n@Component({\n selector: 'mx-rating',\n exportAs: 'mxRating',\n providers: [{ provide: MX_FORM_FIELD_CONTROL, useExisting: MxRating }],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'mx-rating',\n '[attr.data-size]': 'size() === \"md\" ? null : size()',\n '[attr.data-readonly]': 'readonly() ? \"\" : null',\n '[attr.data-disabled]': 'isDisabled() ? \"\" : null',\n '[attr.data-invalid]': 'errorState() ? \"\" : null',\n '[attr.aria-label]': 'null',\n },\n template: `\n @if (readonly()) {\n <span class=\"mx-rating-stars\" role=\"img\" [attr.aria-label]=\"readonlyLabel()\">\n @for (s of stars(); track s) {\n <span class=\"mx-rating-star\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\"><path [attr.d]=\"star\" /></svg>\n <span class=\"mx-rating-star-fill\" [style.width.%]=\"fillPct(s)\"><svg viewBox=\"0 0 24 24\"><path [attr.d]=\"star\" /></svg></span>\n </span>\n }\n </span>\n } @else {\n <div\n class=\"mx-rating-stars\"\n role=\"radiogroup\"\n [attr.aria-labelledby]=\"field?.labelId() ?? null\"\n [attr.aria-label]=\"field?.labelId() ? null : (ariaLabel() ?? 'Avaliação')\"\n [attr.aria-describedby]=\"field?.describedBy() ?? null\"\n [attr.aria-required]=\"isRequired() ? 'true' : null\"\n [attr.aria-invalid]=\"errorState() ? 'true' : null\"\n (mouseleave)=\"hover.set(0)\"\n >\n @for (s of stars(); track s) {\n <label class=\"mx-rating-star\" [attr.data-on]=\"s <= shown() ? '' : null\" (mouseenter)=\"hover.set(isDisabled() ? 0 : s)\">\n <input\n type=\"radio\"\n class=\"mx-rating-input\"\n [id]=\"s === 1 ? controlId() : null\"\n [name]=\"name\"\n [value]=\"s\"\n [checked]=\"value() === s\"\n [disabled]=\"isDisabled()\"\n (change)=\"choose(s)\"\n (click)=\"onClick(s)\"\n (blur)=\"onTouched()\"\n />\n <span class=\"mx-visually-hidden\">{{ starLabel()(s) }}</span>\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path [attr.d]=\"star\" /></svg>\n </label>\n }\n </div>\n }\n @if (showValue() && (readonly() || value())) {\n <span class=\"mx-rating-value\" aria-hidden=\"true\">{{ valueText() }}</span>\n }\n `,\n})\nexport class MxRating implements ControlValueAccessor, MxFormFieldControl {\n readonly value = model<number | null>(null);\n readonly max = input(5, { transform: numberAttribute });\n /** Só mostra a nota (aceita meias estrelas, ex.: 4,5). */\n readonly readonly = input(false, { transform: booleanAttribute });\n /** Carregar outra vez na nota escolhida limpa a avaliação. */\n readonly clearable = input(false, { transform: booleanAttribute });\n /** Mostra o número ao lado (\"4,5\"). */\n readonly showValue = input(false, { transform: booleanAttribute });\n readonly starLabel = input<(n: number) => string>((n) => (n === 1 ? '1 estrela' : `${n} estrelas`));\n readonly locale = input('pt-AO');\n readonly size = input<'sm' | 'md' | 'lg'>('md');\n readonly disabled = input(false, { transform: booleanAttribute });\n readonly required = input(false, { transform: booleanAttribute });\n readonly invalid = input(false, { transform: booleanAttribute });\n readonly id = input<string | undefined>(undefined);\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\n\n protected readonly field = inject(MxFormField, { optional: true });\n private readonly ngControl = inject(NgControl, { self: true, optional: true });\n protected readonly star = STAR;\n protected readonly name = mxUniqueId('mx-rating');\n private readonly generatedId = mxUniqueId('mx-rating-input');\n readonly controlId = computed(() => this.id() ?? this.generatedId);\n protected readonly hover = signal(0);\n private readonly formDisabled = signal(false);\n protected readonly isDisabled = computed(() => this.disabled() || this.formDisabled());\n protected readonly stars = computed(() => Array.from({ length: this.max() }, (_, i) => i + 1));\n protected readonly shown = computed(() => this.hover() || this.value() || 0);\n protected readonly valueText = computed(() =>\n new Intl.NumberFormat(this.locale(), { maximumFractionDigits: 1 }).format(this.value() ?? 0),\n );\n protected readonly readonlyLabel = computed(() => `${this.valueText()} de ${this.max()} estrelas`);\n\n private onChange: (value: number | null) => void = () => {};\n protected onTouched: () => void = () => {};\n\n constructor() {\n if (this.ngControl) this.ngControl.valueAccessor = this;\n }\n\n protected fillPct(s: number): number {\n const v = this.value() ?? 0;\n return Math.max(0, Math.min(1, v - (s - 1))) * 100;\n }\n\n protected choose(s: number): void {\n this.set(s);\n }\n\n protected onClick(s: number): void {\n // um clique na nota já escolhida não dispara \"change\": limpa se clearable\n if (this.clearable() && this.value() === s) {\n this.set(null);\n this.hover.set(0);\n }\n }\n\n private set(v: number | null): void {\n this.value.set(v);\n this.onChange(v);\n }\n\n // ---- MxFormFieldControl ----\n errorState(): boolean {\n if (this.invalid()) return true;\n const c = this.ngControl;\n return !!c && !!c.invalid && !!(c.touched || c.dirty);\n }\n isRequired(): boolean {\n return this.required() || !!this.ngControl?.control?.hasValidator?.(Validators.required);\n }\n\n // ---- ControlValueAccessor ----\n writeValue(value: number | null): void {\n this.value.set(value ?? null);\n }\n registerOnChange(fn: (value: number | null) => void): void {\n this.onChange = fn;\n }\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n setDisabledState(isDisabled: boolean): void {\n this.formDisabled.set(isDisabled);\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-rating.mjs","sources":["../../../projects/core/rating/rating.ts","../../../projects/core/rating/muxima-ui-core-rating.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n booleanAttribute,\n computed,\n inject,\n input,\n model,\n numberAttribute,\n signal,\n} from '@angular/core';\nimport { injectMxMessages } from '@muxima-ui/core/i18n';\nimport { ControlValueAccessor, NgControl, Validators } from '@angular/forms';\nimport { MX_FORM_FIELD_CONTROL, MxFormField, MxFormFieldControl, mxUniqueId } from '@muxima-ui/core/form-field';\n\nconst STAR = 'M12 3.2l2.7 5.6 6.1.8-4.5 4.2 1.1 6.1L12 17l-5.4 2.9 1.1-6.1-4.5-4.2 6.1-.8z';\n\n/**\n * Avaliação com estrelas. Para escolher, são botões de rádio nativos (setas mudam a nota,\n * Tab sai do grupo); em `readonly` é uma imagem com o texto \"4 de 5 estrelas\".\n *\n * ```html\n * <mx-form-field>\n * <label mxLabel>Como correu o atendimento?</label>\n * <mx-rating formControlName=\"nota\" />\n * </mx-form-field>\n * <mx-rating [value]=\"4.5\" readonly />\n * ```\n */\n@Component({\n selector: 'mx-rating',\n exportAs: 'mxRating',\n providers: [{ provide: MX_FORM_FIELD_CONTROL, useExisting: MxRating }],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'mx-rating',\n '[attr.data-size]': 'size() === \"md\" ? null : size()',\n '[attr.data-readonly]': 'readonly() ? \"\" : null',\n '[attr.data-disabled]': 'isDisabled() ? \"\" : null',\n '[attr.data-invalid]': 'errorState() ? \"\" : null',\n '[attr.aria-label]': 'null',\n },\n template: `\n @if (readonly()) {\n <span class=\"mx-rating-stars\" role=\"img\" [attr.aria-label]=\"readonlyLabel()\">\n @for (s of stars(); track s) {\n <span class=\"mx-rating-star\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\"><path [attr.d]=\"star\" /></svg>\n <span class=\"mx-rating-star-fill\" [style.width.%]=\"fillPct(s)\"><svg viewBox=\"0 0 24 24\"><path [attr.d]=\"star\" /></svg></span>\n </span>\n }\n </span>\n } @else {\n <div\n class=\"mx-rating-stars\"\n role=\"radiogroup\"\n [attr.aria-labelledby]=\"field?.labelId() ?? null\"\n [attr.aria-label]=\"field?.labelId() ? null : (ariaLabel() ?? i18n().rating.label)\"\n [attr.aria-describedby]=\"field?.describedBy() ?? null\"\n [attr.aria-required]=\"isRequired() ? 'true' : null\"\n [attr.aria-invalid]=\"errorState() ? 'true' : null\"\n (mouseleave)=\"hover.set(0)\"\n >\n @for (s of stars(); track s) {\n <label class=\"mx-rating-star\" [attr.data-on]=\"s <= shown() ? '' : null\" (mouseenter)=\"hover.set(isDisabled() ? 0 : s)\">\n <input\n type=\"radio\"\n class=\"mx-rating-input\"\n [id]=\"s === 1 ? controlId() : null\"\n [name]=\"name\"\n [value]=\"s\"\n [checked]=\"value() === s\"\n [disabled]=\"isDisabled()\"\n (change)=\"choose(s)\"\n (click)=\"onClick(s)\"\n (blur)=\"onTouched()\"\n />\n <span class=\"mx-visually-hidden\">{{ (starLabel() ?? i18n().rating.star)(s) }}</span>\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path [attr.d]=\"star\" /></svg>\n </label>\n }\n </div>\n }\n @if (showValue() && (readonly() || value())) {\n <span class=\"mx-rating-value\" aria-hidden=\"true\">{{ valueText() }}</span>\n }\n `,\n})\nexport class MxRating implements ControlValueAccessor, MxFormFieldControl {\n readonly value = model<number | null>(null);\n readonly max = input(5, { transform: numberAttribute });\n /** Só mostra a nota (aceita meias estrelas, ex.: 4,5). */\n readonly readonly = input(false, { transform: booleanAttribute });\n /** Carregar outra vez na nota escolhida limpa a avaliação. */\n readonly clearable = input(false, { transform: booleanAttribute });\n /** Mostra o número ao lado (\"4,5\"). */\n readonly showValue = input(false, { transform: booleanAttribute });\n /** Nome de cada estrela; por omissão \"1 estrela\", \"2 estrelas\" no idioma activo. */\n readonly starLabel = input<(n: number) => string>();\n /** Locale dos números; por omissão o do idioma activo. */\n readonly locale = input<string>();\n protected readonly i18n = injectMxMessages();\n readonly size = input<'sm' | 'md' | 'lg'>('md');\n readonly disabled = input(false, { transform: booleanAttribute });\n readonly required = input(false, { transform: booleanAttribute });\n readonly invalid = input(false, { transform: booleanAttribute });\n readonly id = input<string | undefined>(undefined);\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\n\n protected readonly field = inject(MxFormField, { optional: true });\n private readonly ngControl = inject(NgControl, { self: true, optional: true });\n protected readonly star = STAR;\n protected readonly name = mxUniqueId('mx-rating');\n private readonly generatedId = mxUniqueId('mx-rating-input');\n readonly controlId = computed(() => this.id() ?? this.generatedId);\n protected readonly hover = signal(0);\n private readonly formDisabled = signal(false);\n protected readonly isDisabled = computed(() => this.disabled() || this.formDisabled());\n protected readonly stars = computed(() => Array.from({ length: this.max() }, (_, i) => i + 1));\n protected readonly shown = computed(() => this.hover() || this.value() || 0);\n protected readonly valueText = computed(() =>\n new Intl.NumberFormat(this.locale() ?? this.i18n().intlLocale, { maximumFractionDigits: 1 }).format(this.value() ?? 0),\n );\n protected readonly readonlyLabel = computed(() => this.i18n().rating.summary(this.valueText(), this.max()));\n\n private onChange: (value: number | null) => void = () => {};\n protected onTouched: () => void = () => {};\n\n constructor() {\n if (this.ngControl) this.ngControl.valueAccessor = this;\n }\n\n protected fillPct(s: number): number {\n const v = this.value() ?? 0;\n return Math.max(0, Math.min(1, v - (s - 1))) * 100;\n }\n\n protected choose(s: number): void {\n this.set(s);\n }\n\n protected onClick(s: number): void {\n // um clique na nota já escolhida não dispara \"change\": limpa se clearable\n if (this.clearable() && this.value() === s) {\n this.set(null);\n this.hover.set(0);\n }\n }\n\n private set(v: number | null): void {\n this.value.set(v);\n this.onChange(v);\n }\n\n // ---- MxFormFieldControl ----\n errorState(): boolean {\n if (this.invalid()) return true;\n const c = this.ngControl;\n return !!c && !!c.invalid && !!(c.touched || c.dirty);\n }\n isRequired(): boolean {\n return this.required() || !!this.ngControl?.control?.hasValidator?.(Validators.required);\n }\n\n // ---- ControlValueAccessor ----\n writeValue(value: number | null): void {\n this.value.set(value ?? null);\n }\n registerOnChange(fn: (value: number | null) => void): void {\n this.onChange = fn;\n }\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n setDisabledState(isDisabled: boolean): void {\n this.formDisabled.set(isDisabled);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@ import { ActiveDescendantKeyManager } from '@angular/cdk/a11y';
|
|
|
2
2
|
import { CdkOverlayOrigin, CdkConnectedOverlay } from '@angular/cdk/overlay';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
4
|
import { input, booleanAttribute, signal, inject, ElementRef, computed, ChangeDetectionStrategy, ViewEncapsulation, Component, model, output, contentChildren, Injector, DestroyRef } from '@angular/core';
|
|
5
|
+
import { injectMxMessages } from '@muxima-ui/core/i18n';
|
|
5
6
|
import { NgControl, Validators } from '@angular/forms';
|
|
6
7
|
import { mxUniqueId, MxFormField, MX_FORM_FIELD_CONTROL } from '@muxima-ui/core/form-field';
|
|
7
8
|
|
|
@@ -78,7 +79,9 @@ class MxSelect {
|
|
|
78
79
|
value = model(null, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
79
80
|
/** Escolha múltipla: o valor passa a ser uma lista e o painel não fecha ao escolher. */
|
|
80
81
|
multiple = input(false, { ...(ngDevMode ? { debugName: "multiple" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
81
|
-
placeholder = input(
|
|
82
|
+
placeholder = input(...(ngDevMode ? [undefined, { debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
83
|
+
i18n = injectMxMessages();
|
|
84
|
+
placeholderText = computed(() => this.placeholder() ?? this.i18n().select.placeholder, ...(ngDevMode ? [{ debugName: "placeholderText" }] : /* istanbul ignore next */ []));
|
|
82
85
|
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
83
86
|
required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
84
87
|
/** Força o estado de erro (sem formulário). Com Reactive Forms o erro vem do controlo. */
|
|
@@ -86,10 +89,10 @@ class MxSelect {
|
|
|
86
89
|
/** Altura: sm 32 px, md 36 px, lg 40 px. */
|
|
87
90
|
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
88
91
|
/** Texto mostrado quando não há opções. */
|
|
89
|
-
emptyText = input(
|
|
92
|
+
emptyText = input(...(ngDevMode ? [undefined, { debugName: "emptyText" }] : /* istanbul ignore next */ []));
|
|
90
93
|
/** Opções a carregar (ex.: de um servidor): mostra um indicador no botão e no painel. */
|
|
91
94
|
loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
92
|
-
loadingText = input(
|
|
95
|
+
loadingText = input(...(ngDevMode ? [undefined, { debugName: "loadingText" }] : /* istanbul ignore next */ []));
|
|
93
96
|
id = input(undefined, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
94
97
|
/** Nome acessível quando não existe um `label[mxLabel]` no campo. */
|
|
95
98
|
ariaLabel = input(undefined, { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: 'aria-label' });
|
|
@@ -305,7 +308,7 @@ class MxSelect {
|
|
|
305
308
|
(blur)="onTriggerBlur()"
|
|
306
309
|
>
|
|
307
310
|
<span class="mx-select-value" [class.mx-select-placeholder]="!selectedLabel()">
|
|
308
|
-
{{ selectedLabel() ||
|
|
311
|
+
{{ selectedLabel() || placeholderText() }}
|
|
309
312
|
</span>
|
|
310
313
|
@if (loading()) {
|
|
311
314
|
<span class="mx-spinner mx-select-spinner" aria-hidden="true"></span>
|
|
@@ -332,13 +335,13 @@ class MxSelect {
|
|
|
332
335
|
[attr.aria-busy]="loading() ? 'true' : null"
|
|
333
336
|
[id]="panelId"
|
|
334
337
|
[attr.aria-labelledby]="field?.labelId() ?? null"
|
|
335
|
-
[attr.aria-label]="field?.labelId() ? null : (ariaLabel() ??
|
|
338
|
+
[attr.aria-label]="field?.labelId() ? null : (ariaLabel() ?? placeholderText())"
|
|
336
339
|
>
|
|
337
340
|
<ng-content />
|
|
338
341
|
@if (loading()) {
|
|
339
|
-
<div class="mx-select-empty mx-select-loading" role="option" aria-disabled="true" aria-selected="false"><span class="mx-spinner mx-select-spinner" aria-hidden="true"></span>{{ loadingText() }}</div>
|
|
342
|
+
<div class="mx-select-empty mx-select-loading" role="option" aria-disabled="true" aria-selected="false"><span class="mx-spinner mx-select-spinner" aria-hidden="true"></span>{{ loadingText() ?? i18n().select.loading }}</div>
|
|
340
343
|
} @else if (optionCount() === 0) {
|
|
341
|
-
<div class="mx-select-empty" role="option" aria-disabled="true" aria-selected="false">{{ emptyText() }}</div>
|
|
344
|
+
<div class="mx-select-empty" role="option" aria-disabled="true" aria-selected="false">{{ emptyText() ?? i18n().select.empty }}</div>
|
|
342
345
|
}
|
|
343
346
|
</div>
|
|
344
347
|
</ng-template>
|
|
@@ -378,7 +381,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
378
381
|
(blur)="onTriggerBlur()"
|
|
379
382
|
>
|
|
380
383
|
<span class="mx-select-value" [class.mx-select-placeholder]="!selectedLabel()">
|
|
381
|
-
{{ selectedLabel() ||
|
|
384
|
+
{{ selectedLabel() || placeholderText() }}
|
|
382
385
|
</span>
|
|
383
386
|
@if (loading()) {
|
|
384
387
|
<span class="mx-spinner mx-select-spinner" aria-hidden="true"></span>
|
|
@@ -405,13 +408,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
405
408
|
[attr.aria-busy]="loading() ? 'true' : null"
|
|
406
409
|
[id]="panelId"
|
|
407
410
|
[attr.aria-labelledby]="field?.labelId() ?? null"
|
|
408
|
-
[attr.aria-label]="field?.labelId() ? null : (ariaLabel() ??
|
|
411
|
+
[attr.aria-label]="field?.labelId() ? null : (ariaLabel() ?? placeholderText())"
|
|
409
412
|
>
|
|
410
413
|
<ng-content />
|
|
411
414
|
@if (loading()) {
|
|
412
|
-
<div class="mx-select-empty mx-select-loading" role="option" aria-disabled="true" aria-selected="false"><span class="mx-spinner mx-select-spinner" aria-hidden="true"></span>{{ loadingText() }}</div>
|
|
415
|
+
<div class="mx-select-empty mx-select-loading" role="option" aria-disabled="true" aria-selected="false"><span class="mx-spinner mx-select-spinner" aria-hidden="true"></span>{{ loadingText() ?? i18n().select.loading }}</div>
|
|
413
416
|
} @else if (optionCount() === 0) {
|
|
414
|
-
<div class="mx-select-empty" role="option" aria-disabled="true" aria-selected="false">{{ emptyText() }}</div>
|
|
417
|
+
<div class="mx-select-empty" role="option" aria-disabled="true" aria-selected="false">{{ emptyText() ?? i18n().select.empty }}</div>
|
|
415
418
|
}
|
|
416
419
|
</div>
|
|
417
420
|
</ng-template>
|