@muxima-ui/core 1.4.1 → 2.0.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 +102 -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 +32 -27
- package/fesm2022/muxima-ui-core-file-upload.mjs.map +1 -1
- package/fesm2022/muxima-ui-core-form-field.mjs +2 -2
- package/fesm2022/muxima-ui-core-form-field.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 +42 -37
- 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 +10 -8
- 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 +6 -12
- 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 +30 -10
- package/types/muxima-ui-core-date-picker.d.ts +64 -15
- package/types/muxima-ui-core-editor.d.ts +13 -2
- package/types/muxima-ui-core-file-upload.d.ts +23 -7
- package/types/muxima-ui-core-form-field.d.ts +2 -2
- 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 +31 -9
- 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 +6 -4
- 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 +3 -3
- package/types/muxima-ui-core.d.ts +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { model, input, output, inject, ElementRef, Injector, signal,
|
|
2
|
+
import { model, input, computed, output, inject, ElementRef, Injector, signal, afterNextRender, ViewEncapsulation, ChangeDetectionStrategy, Component, booleanAttribute, viewChild } from '@angular/core';
|
|
3
|
+
import { injectMxMessages, MX_MESSAGES_EN } from '@muxima-ui/core/i18n';
|
|
3
4
|
import { mxUniqueId, MxFormField, MX_FORM_FIELD_CONTROL } from '@muxima-ui/core/form-field';
|
|
4
5
|
import { CdkOverlayOrigin, CdkConnectedOverlay } from '@angular/cdk/overlay';
|
|
5
6
|
import { NgControl, Validators } from '@angular/forms';
|
|
@@ -39,9 +40,14 @@ class MxCalendar {
|
|
|
39
40
|
max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
|
|
40
41
|
/** Dias que não se podem escolher (ex.: fins-de-semana). */
|
|
41
42
|
dateDisabled = input(() => false, ...(ngDevMode ? [{ debugName: "dateDisabled" }] : /* istanbul ignore next */ []));
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
/** Locale dos nomes dos meses e dos dias; por omissão o do idioma activo. */
|
|
44
|
+
locale = input(...(ngDevMode ? [undefined, { debugName: "locale" }] : /* istanbul ignore next */ []));
|
|
45
|
+
/** Primeiro dia da semana: 0 = domingo, 1 = segunda-feira. Por omissão o do idioma activo. */
|
|
46
|
+
firstDayOfWeek = input(...(ngDevMode ? [undefined, { debugName: "firstDayOfWeek" }] : /* istanbul ignore next */ []));
|
|
47
|
+
i18n = injectMxMessages();
|
|
48
|
+
msg = computed(() => this.i18n().calendar, ...(ngDevMode ? [{ debugName: "msg" }] : /* istanbul ignore next */ []));
|
|
49
|
+
loc = computed(() => this.locale() ?? this.i18n().intlLocale, ...(ngDevMode ? [{ debugName: "loc" }] : /* istanbul ignore next */ []));
|
|
50
|
+
firstDay = computed(() => this.firstDayOfWeek() ?? this.i18n().firstDayOfWeek, ...(ngDevMode ? [{ debugName: "firstDay" }] : /* istanbul ignore next */ []));
|
|
45
51
|
selected = output();
|
|
46
52
|
/** `single` escolhe um dia; `range` escolhe um intervalo em [(range)]. */
|
|
47
53
|
mode = input('single', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
|
|
@@ -61,8 +67,8 @@ class MxCalendar {
|
|
|
61
67
|
const r = this.range();
|
|
62
68
|
if (!r?.start)
|
|
63
69
|
return '';
|
|
64
|
-
const f = new Intl.DateTimeFormat(this.
|
|
65
|
-
return r.end ?
|
|
70
|
+
const f = new Intl.DateTimeFormat(this.loc(), { day: 'numeric', month: 'long', year: 'numeric' });
|
|
71
|
+
return r.end ? this.msg().rangeHint(f.format(r.start), f.format(r.end)) : this.msg().rangeStartHint(f.format(r.start));
|
|
66
72
|
}, ...(ngDevMode ? [{ debugName: "rangeHint" }] : /* istanbul ignore next */ []));
|
|
67
73
|
/** Início e fim efectivos (com pré-visualização), ordenados. */
|
|
68
74
|
bounds = computed(() => {
|
|
@@ -75,21 +81,21 @@ class MxCalendar {
|
|
|
75
81
|
return r.start <= end ? [r.start, end] : [end, r.start];
|
|
76
82
|
}, ...(ngDevMode ? [{ debugName: "bounds" }] : /* istanbul ignore next */ []));
|
|
77
83
|
weekdays = computed(() => {
|
|
78
|
-
const short = new Intl.DateTimeFormat(this.
|
|
79
|
-
const long = new Intl.DateTimeFormat(this.
|
|
84
|
+
const short = new Intl.DateTimeFormat(this.loc(), { weekday: 'narrow' });
|
|
85
|
+
const long = new Intl.DateTimeFormat(this.loc(), { weekday: 'long' });
|
|
80
86
|
// 2024-01-01 foi segunda-feira
|
|
81
87
|
return Array.from({ length: 7 }, (_, i) => {
|
|
82
|
-
const d = new Date(2024, 0, 1 + ((this.
|
|
88
|
+
const d = new Date(2024, 0, 1 + ((this.firstDay() - 1 + i + 7) % 7));
|
|
83
89
|
return { short: short.format(d).toUpperCase(), long: long.format(d) };
|
|
84
90
|
});
|
|
85
91
|
}, ...(ngDevMode ? [{ debugName: "weekdays" }] : /* istanbul ignore next */ []));
|
|
86
92
|
weeks = computed(() => {
|
|
87
93
|
const focus = this.focusDate();
|
|
88
94
|
const first = new Date(focus.getFullYear(), focus.getMonth(), 1);
|
|
89
|
-
const offset = (first.getDay() - this.
|
|
95
|
+
const offset = (first.getDay() - this.firstDay() + 7) % 7;
|
|
90
96
|
const start = addDays(first, -offset);
|
|
91
97
|
const today = mxStartOfDay(new Date());
|
|
92
|
-
const fmt = new Intl.DateTimeFormat(this.
|
|
98
|
+
const fmt = new Intl.DateTimeFormat(this.loc(), { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' });
|
|
93
99
|
const bounds = this.bounds();
|
|
94
100
|
const isRange = this.mode() === 'range';
|
|
95
101
|
const weeks = [];
|
|
@@ -102,7 +108,8 @@ class MxCalendar {
|
|
|
102
108
|
const inRange = !!bounds && date > bounds[0] && date < bounds[1];
|
|
103
109
|
const isStart = isRange && mxSameDay(date, this.range()?.start);
|
|
104
110
|
const isEnd = isRange && mxSameDay(date, this.range()?.end);
|
|
105
|
-
const
|
|
111
|
+
const t = this.msg();
|
|
112
|
+
const label = fmt.format(date) + (isStart && isEnd ? `, ${t.rangeStartEnd}` : isStart ? `, ${t.rangeStart}` : isEnd ? `, ${t.rangeEnd}` : '');
|
|
106
113
|
row.push({
|
|
107
114
|
date,
|
|
108
115
|
key: `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`,
|
|
@@ -140,7 +147,7 @@ class MxCalendar {
|
|
|
140
147
|
}
|
|
141
148
|
monthLabel(delta) {
|
|
142
149
|
const d = addMonths(this.focusDate(), delta);
|
|
143
|
-
const s = new Intl.DateTimeFormat(this.
|
|
150
|
+
const s = new Intl.DateTimeFormat(this.loc(), { month: 'long', year: 'numeric' }).format(d);
|
|
144
151
|
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
145
152
|
}
|
|
146
153
|
moveMonth(delta) {
|
|
@@ -173,7 +180,7 @@ class MxCalendar {
|
|
|
173
180
|
}
|
|
174
181
|
onKeydown(event) {
|
|
175
182
|
const f = this.focusDate();
|
|
176
|
-
const dow = (f.getDay() - this.
|
|
183
|
+
const dow = (f.getDay() - this.firstDay() + 7) % 7;
|
|
177
184
|
const moves = {
|
|
178
185
|
ArrowLeft: () => addDays(f, -1),
|
|
179
186
|
ArrowRight: () => addDays(f, 1),
|
|
@@ -222,11 +229,11 @@ class MxCalendar {
|
|
|
222
229
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: MxCalendar, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
223
230
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: MxCalendar, isStandalone: true, selector: "mx-calendar", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, dateDisabled: { classPropertyName: "dateDisabled", publicName: "dateDisabled", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, firstDayOfWeek: { classPropertyName: "firstDayOfWeek", publicName: "firstDayOfWeek", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, range: { classPropertyName: "range", publicName: "range", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", selected: "selected", range: "rangeChange", rangeSelected: "rangeSelected" }, host: { classAttribute: "mx-calendar" }, exportAs: ["mxCalendar"], ngImport: i0, template: `
|
|
224
231
|
<div class="mx-calendar-header">
|
|
225
|
-
<button type="button" class="mx-calendar-nav" (click)="moveMonth(-1)" [attr.aria-label]="
|
|
232
|
+
<button type="button" class="mx-calendar-nav" (click)="moveMonth(-1)" [attr.aria-label]="msg().previousMonth(monthLabel(-1))">
|
|
226
233
|
<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>
|
|
227
234
|
</button>
|
|
228
235
|
<p class="mx-calendar-title" [id]="titleId" aria-live="polite">{{ monthLabel(0) }}</p>
|
|
229
|
-
<button type="button" class="mx-calendar-nav" (click)="moveMonth(1)" [attr.aria-label]="
|
|
236
|
+
<button type="button" class="mx-calendar-nav" (click)="moveMonth(1)" [attr.aria-label]="msg().nextMonth(monthLabel(1))">
|
|
230
237
|
<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>
|
|
231
238
|
</button>
|
|
232
239
|
</div>
|
|
@@ -285,11 +292,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
285
292
|
host: { class: 'mx-calendar' },
|
|
286
293
|
template: `
|
|
287
294
|
<div class="mx-calendar-header">
|
|
288
|
-
<button type="button" class="mx-calendar-nav" (click)="moveMonth(-1)" [attr.aria-label]="
|
|
295
|
+
<button type="button" class="mx-calendar-nav" (click)="moveMonth(-1)" [attr.aria-label]="msg().previousMonth(monthLabel(-1))">
|
|
289
296
|
<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>
|
|
290
297
|
</button>
|
|
291
298
|
<p class="mx-calendar-title" [id]="titleId" aria-live="polite">{{ monthLabel(0) }}</p>
|
|
292
|
-
<button type="button" class="mx-calendar-nav" (click)="moveMonth(1)" [attr.aria-label]="
|
|
299
|
+
<button type="button" class="mx-calendar-nav" (click)="moveMonth(1)" [attr.aria-label]="msg().nextMonth(monthLabel(1))">
|
|
293
300
|
<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>
|
|
294
301
|
</button>
|
|
295
302
|
</div>
|
|
@@ -344,20 +351,31 @@ const POSITIONS$1 = [
|
|
|
344
351
|
{ originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 4 },
|
|
345
352
|
{ originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -4 },
|
|
346
353
|
];
|
|
347
|
-
/**
|
|
348
|
-
|
|
349
|
-
|
|
354
|
+
/**
|
|
355
|
+
* Converte uma data escrita (por omissão "mm/dd/aaaa"; "dmy" para "dd/mm/aaaa").
|
|
356
|
+
* Aceita também "-" e "." como separadores.
|
|
357
|
+
*/
|
|
358
|
+
function mxParseDate(text, order = 'mdy') {
|
|
359
|
+
const t = text.trim();
|
|
360
|
+
const m = order === 'ymd'
|
|
361
|
+
? t.match(/^(\d{4})[/.-](\d{1,2})[/.-](\d{1,2})$/)
|
|
362
|
+
: t.match(/^(\d{1,2})[/.-](\d{1,2})[/.-](\d{4})$/);
|
|
350
363
|
if (!m)
|
|
351
364
|
return null;
|
|
352
|
-
const
|
|
365
|
+
const n = [Number(m[1]), Number(m[2]), Number(m[3])];
|
|
366
|
+
const [d, mo, y] = order === 'ymd' ? [n[2], n[1] - 1, n[0]] : order === 'mdy' ? [n[1], n[0] - 1, n[2]] : [n[0], n[1] - 1, n[2]];
|
|
353
367
|
const date = new Date(y, mo, d);
|
|
354
368
|
return date.getFullYear() === y && date.getMonth() === mo && date.getDate() === d ? date : null;
|
|
355
369
|
}
|
|
356
|
-
|
|
370
|
+
/** Escreve a data na ordem indicada (por omissão "mm/dd/aaaa"). */
|
|
371
|
+
function mxFormatDate(d, order = 'mdy') {
|
|
357
372
|
if (!d)
|
|
358
373
|
return '';
|
|
359
374
|
const pad = (n) => String(n).padStart(2, '0');
|
|
360
|
-
|
|
375
|
+
const [day, month, year] = [pad(d.getDate()), pad(d.getMonth() + 1), d.getFullYear()];
|
|
376
|
+
if (order === 'ymd')
|
|
377
|
+
return `${year}-${month}-${day}`;
|
|
378
|
+
return order === 'mdy' ? `${month}/${day}/${year}` : `${day}/${month}/${year}`;
|
|
361
379
|
}
|
|
362
380
|
/**
|
|
363
381
|
* Campo de data: escreve-se "dd/mm/aaaa" ou escolhe-se no calendário.
|
|
@@ -378,8 +396,13 @@ class MxDatePicker {
|
|
|
378
396
|
min = input(null, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
|
|
379
397
|
max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
|
|
380
398
|
dateDisabled = input(() => false, ...(ngDevMode ? [{ debugName: "dateDisabled" }] : /* istanbul ignore next */ []));
|
|
381
|
-
|
|
382
|
-
|
|
399
|
+
/** Locale dos nomes dos meses e dos dias; por omissão o do idioma activo. */
|
|
400
|
+
locale = input(...(ngDevMode ? [undefined, { debugName: "locale" }] : /* istanbul ignore next */ []));
|
|
401
|
+
/** Por omissão "dd/mm/aaaa" em português e "mm/dd/yyyy" em inglês. */
|
|
402
|
+
placeholder = input(...(ngDevMode ? [undefined, { debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
403
|
+
i18n = injectMxMessages();
|
|
404
|
+
msg = computed(() => this.i18n().datePicker, ...(ngDevMode ? [{ debugName: "msg" }] : /* istanbul ignore next */ []));
|
|
405
|
+
loc = computed(() => this.locale() ?? this.i18n().intlLocale, ...(ngDevMode ? [{ debugName: "loc" }] : /* istanbul ignore next */ []));
|
|
383
406
|
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
384
407
|
required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
385
408
|
invalid = input(false, { ...(ngDevMode ? { debugName: "invalid" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
@@ -399,10 +422,10 @@ class MxDatePicker {
|
|
|
399
422
|
draft = signal(null, ...(ngDevMode ? [{ debugName: "draft" }] : /* istanbul ignore next */ []));
|
|
400
423
|
formDisabled = signal(false, ...(ngDevMode ? [{ debugName: "formDisabled" }] : /* istanbul ignore next */ []));
|
|
401
424
|
isDisabled = computed(() => this.disabled() || this.formDisabled(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
402
|
-
text = computed(() => this.draft() ?? mxFormatDate(this.value()), ...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []));
|
|
403
|
-
longLabel = computed(() => this.value() ? new Intl.DateTimeFormat(this.
|
|
425
|
+
text = computed(() => this.draft() ?? mxFormatDate(this.value(), this.i18n().dateOrder), ...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []));
|
|
426
|
+
longLabel = computed(() => this.value() ? new Intl.DateTimeFormat(this.loc(), { dateStyle: 'full' }).format(this.value()) : '', ...(ngDevMode ? [{ debugName: "longLabel" }] : /* istanbul ignore next */ []));
|
|
404
427
|
/** true quando há texto que não é uma data válida. */
|
|
405
|
-
badFormat = computed(() => !!this.draft() && !mxParseDate(this.draft()), ...(ngDevMode ? [{ debugName: "badFormat" }] : /* istanbul ignore next */ []));
|
|
428
|
+
badFormat = computed(() => !!this.draft() && !mxParseDate(this.draft(), this.i18n().dateOrder), ...(ngDevMode ? [{ debugName: "badFormat" }] : /* istanbul ignore next */ []));
|
|
406
429
|
onChange = () => { };
|
|
407
430
|
onTouched = () => { };
|
|
408
431
|
constructor() {
|
|
@@ -446,7 +469,7 @@ class MxDatePicker {
|
|
|
446
469
|
}
|
|
447
470
|
onInput(event) {
|
|
448
471
|
const text = event.target.value;
|
|
449
|
-
const parsed = mxParseDate(text);
|
|
472
|
+
const parsed = mxParseDate(text, this.i18n().dateOrder);
|
|
450
473
|
if (parsed) {
|
|
451
474
|
this.draft.set(null);
|
|
452
475
|
this.setValue(parsed);
|
|
@@ -499,7 +522,7 @@ class MxDatePicker {
|
|
|
499
522
|
inputmode="numeric"
|
|
500
523
|
autocomplete="off"
|
|
501
524
|
[id]="controlId()"
|
|
502
|
-
[placeholder]="placeholder()"
|
|
525
|
+
[placeholder]="placeholder() ?? msg().placeholder"
|
|
503
526
|
[value]="text()"
|
|
504
527
|
[disabled]="isDisabled()"
|
|
505
528
|
[attr.data-size]="size() === 'md' ? null : size()"
|
|
@@ -517,7 +540,7 @@ class MxDatePicker {
|
|
|
517
540
|
class="mx-date-picker-toggle"
|
|
518
541
|
aria-haspopup="dialog"
|
|
519
542
|
[attr.aria-expanded]="isOpen()"
|
|
520
|
-
[attr.aria-label]="value() ?
|
|
543
|
+
[attr.aria-label]="value() ? msg().change(longLabel()) : msg().choose"
|
|
521
544
|
[disabled]="isDisabled()"
|
|
522
545
|
(click)="toggle()"
|
|
523
546
|
>
|
|
@@ -538,14 +561,14 @@ class MxDatePicker {
|
|
|
538
561
|
(attach)="onAttach()"
|
|
539
562
|
(detach)="close(false)"
|
|
540
563
|
>
|
|
541
|
-
<div class="mx-date-picker-panel" role="dialog" aria-modal="false" [attr.aria-label]="
|
|
564
|
+
<div class="mx-date-picker-panel" role="dialog" aria-modal="false" [attr.aria-label]="msg().choose">
|
|
542
565
|
<mx-calendar
|
|
543
566
|
#calendar
|
|
544
567
|
[value]="value()"
|
|
545
568
|
[min]="min()"
|
|
546
569
|
[max]="max()"
|
|
547
570
|
[dateDisabled]="dateDisabled()"
|
|
548
|
-
[locale]="
|
|
571
|
+
[locale]="loc()"
|
|
549
572
|
(selected)="choose($event)"
|
|
550
573
|
/>
|
|
551
574
|
</div>
|
|
@@ -570,7 +593,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
570
593
|
inputmode="numeric"
|
|
571
594
|
autocomplete="off"
|
|
572
595
|
[id]="controlId()"
|
|
573
|
-
[placeholder]="placeholder()"
|
|
596
|
+
[placeholder]="placeholder() ?? msg().placeholder"
|
|
574
597
|
[value]="text()"
|
|
575
598
|
[disabled]="isDisabled()"
|
|
576
599
|
[attr.data-size]="size() === 'md' ? null : size()"
|
|
@@ -588,7 +611,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
588
611
|
class="mx-date-picker-toggle"
|
|
589
612
|
aria-haspopup="dialog"
|
|
590
613
|
[attr.aria-expanded]="isOpen()"
|
|
591
|
-
[attr.aria-label]="value() ?
|
|
614
|
+
[attr.aria-label]="value() ? msg().change(longLabel()) : msg().choose"
|
|
592
615
|
[disabled]="isDisabled()"
|
|
593
616
|
(click)="toggle()"
|
|
594
617
|
>
|
|
@@ -609,14 +632,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
609
632
|
(attach)="onAttach()"
|
|
610
633
|
(detach)="close(false)"
|
|
611
634
|
>
|
|
612
|
-
<div class="mx-date-picker-panel" role="dialog" aria-modal="false" [attr.aria-label]="
|
|
635
|
+
<div class="mx-date-picker-panel" role="dialog" aria-modal="false" [attr.aria-label]="msg().choose">
|
|
613
636
|
<mx-calendar
|
|
614
637
|
#calendar
|
|
615
638
|
[value]="value()"
|
|
616
639
|
[min]="min()"
|
|
617
640
|
[max]="max()"
|
|
618
641
|
[dateDisabled]="dateDisabled()"
|
|
619
|
-
[locale]="
|
|
642
|
+
[locale]="loc()"
|
|
620
643
|
(selected)="choose($event)"
|
|
621
644
|
/>
|
|
622
645
|
</div>
|
|
@@ -629,22 +652,26 @@ const POSITIONS = [
|
|
|
629
652
|
{ originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 4 },
|
|
630
653
|
{ originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -4 },
|
|
631
654
|
];
|
|
632
|
-
/**
|
|
633
|
-
|
|
655
|
+
/**
|
|
656
|
+
* Atalhos comuns: últimos 7 e 30 dias, este mês e o mês passado.
|
|
657
|
+
* Os nomes vêm de `labels` (por omissão em inglês); para o idioma activo,
|
|
658
|
+
* usa `mxDefaultRangePresets(inject(MxI18n).messages().dateRangePicker)`.
|
|
659
|
+
*/
|
|
660
|
+
function mxDefaultRangePresets(labels = MX_MESSAGES_EN.dateRangePicker) {
|
|
634
661
|
const today = () => mxStartOfDay(new Date());
|
|
635
662
|
const shift = (d, days) => new Date(d.getFullYear(), d.getMonth(), d.getDate() + days);
|
|
636
663
|
return [
|
|
637
|
-
{ label:
|
|
638
|
-
{ label:
|
|
664
|
+
{ label: labels.last7Days, range: () => ({ start: shift(today(), -6), end: today() }) },
|
|
665
|
+
{ label: labels.last30Days, range: () => ({ start: shift(today(), -29), end: today() }) },
|
|
639
666
|
{
|
|
640
|
-
label:
|
|
667
|
+
label: labels.thisMonth,
|
|
641
668
|
range: () => {
|
|
642
669
|
const t = today();
|
|
643
670
|
return { start: new Date(t.getFullYear(), t.getMonth(), 1), end: new Date(t.getFullYear(), t.getMonth() + 1, 0) };
|
|
644
671
|
},
|
|
645
672
|
},
|
|
646
673
|
{
|
|
647
|
-
label:
|
|
674
|
+
label: labels.lastMonth,
|
|
648
675
|
range: () => {
|
|
649
676
|
const t = today();
|
|
650
677
|
return { start: new Date(t.getFullYear(), t.getMonth() - 1, 1), end: new Date(t.getFullYear(), t.getMonth(), 0) };
|
|
@@ -672,10 +699,16 @@ class MxDateRangePicker {
|
|
|
672
699
|
max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
|
|
673
700
|
dateDisabled = input(() => false, ...(ngDevMode ? [{ debugName: "dateDisabled" }] : /* istanbul ignore next */ []));
|
|
674
701
|
presets = input([], ...(ngDevMode ? [{ debugName: "presets" }] : /* istanbul ignore next */ []));
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
702
|
+
/** Locale dos nomes dos meses e dos dias; por omissão o do idioma activo. */
|
|
703
|
+
locale = input(...(ngDevMode ? [undefined, { debugName: "locale" }] : /* istanbul ignore next */ []));
|
|
704
|
+
/** Por omissão "dd/mm/aaaa" em português e "mm/dd/yyyy" em inglês. */
|
|
705
|
+
placeholder = input(...(ngDevMode ? [undefined, { debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
706
|
+
startLabel = input(...(ngDevMode ? [undefined, { debugName: "startLabel" }] : /* istanbul ignore next */ []));
|
|
707
|
+
endLabel = input(...(ngDevMode ? [undefined, { debugName: "endLabel" }] : /* istanbul ignore next */ []));
|
|
708
|
+
i18n = injectMxMessages();
|
|
709
|
+
msg = computed(() => this.i18n().dateRangePicker, ...(ngDevMode ? [{ debugName: "msg" }] : /* istanbul ignore next */ []));
|
|
710
|
+
loc = computed(() => this.locale() ?? this.i18n().intlLocale, ...(ngDevMode ? [{ debugName: "loc" }] : /* istanbul ignore next */ []));
|
|
711
|
+
placeholderText = computed(() => this.placeholder() ?? this.i18n().datePicker.placeholder, ...(ngDevMode ? [{ debugName: "placeholderText" }] : /* istanbul ignore next */ []));
|
|
679
712
|
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
680
713
|
required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
681
714
|
invalid = input(false, { ...(ngDevMode ? { debugName: "invalid" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
@@ -701,20 +734,20 @@ class MxDateRangePicker {
|
|
|
701
734
|
draftText = signal({ start: null, end: null }, ...(ngDevMode ? [{ debugName: "draftText" }] : /* istanbul ignore next */ []));
|
|
702
735
|
formDisabled = signal(false, ...(ngDevMode ? [{ debugName: "formDisabled" }] : /* istanbul ignore next */ []));
|
|
703
736
|
isDisabled = computed(() => this.disabled() || this.formDisabled(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
704
|
-
startText = computed(() => this.draftText().start ?? mxFormatDate(this.value()?.start ?? null), ...(ngDevMode ? [{ debugName: "startText" }] : /* istanbul ignore next */ []));
|
|
705
|
-
endText = computed(() => this.draftText().end ?? mxFormatDate(this.value()?.end ?? null), ...(ngDevMode ? [{ debugName: "endText" }] : /* istanbul ignore next */ []));
|
|
737
|
+
startText = computed(() => this.draftText().start ?? mxFormatDate(this.value()?.start ?? null, this.i18n().dateOrder), ...(ngDevMode ? [{ debugName: "startText" }] : /* istanbul ignore next */ []));
|
|
738
|
+
endText = computed(() => this.draftText().end ?? mxFormatDate(this.value()?.end ?? null, this.i18n().dateOrder), ...(ngDevMode ? [{ debugName: "endText" }] : /* istanbul ignore next */ []));
|
|
706
739
|
/** true quando há texto que não é data, ou o fim é anterior ao início. */
|
|
707
740
|
badFormat = computed(() => {
|
|
708
741
|
const d = this.draftText();
|
|
709
742
|
const v = this.value();
|
|
710
|
-
return (!!d.start && !mxParseDate(d.start)) || (!!d.end && !mxParseDate(d.end)) || (!!v?.start && !!v?.end && v.end < v.start);
|
|
743
|
+
return (!!d.start && !mxParseDate(d.start, this.i18n().dateOrder)) || (!!d.end && !mxParseDate(d.end, this.i18n().dateOrder)) || (!!v?.start && !!v?.end && v.end < v.start);
|
|
711
744
|
}, ...(ngDevMode ? [{ debugName: "badFormat" }] : /* istanbul ignore next */ []));
|
|
712
745
|
toggleLabel = computed(() => {
|
|
713
746
|
const v = this.value();
|
|
714
747
|
if (!v?.start || !v?.end)
|
|
715
|
-
return
|
|
716
|
-
const f = new Intl.DateTimeFormat(this.
|
|
717
|
-
return
|
|
748
|
+
return this.msg().choose;
|
|
749
|
+
const f = new Intl.DateTimeFormat(this.loc(), { day: 'numeric', month: 'long', year: 'numeric' });
|
|
750
|
+
return this.msg().change(f.format(v.start), f.format(v.end));
|
|
718
751
|
}, ...(ngDevMode ? [{ debugName: "toggleLabel" }] : /* istanbul ignore next */ []));
|
|
719
752
|
onChange = () => { };
|
|
720
753
|
onTouched = () => { };
|
|
@@ -772,7 +805,7 @@ class MxDateRangePicker {
|
|
|
772
805
|
}
|
|
773
806
|
onInput(part, event) {
|
|
774
807
|
const text = event.target.value;
|
|
775
|
-
const parsed = mxParseDate(text);
|
|
808
|
+
const parsed = mxParseDate(text, this.i18n().dateOrder);
|
|
776
809
|
this.draftText.update((d) => ({ ...d, [part]: parsed || !text ? null : text }));
|
|
777
810
|
const current = this.value() ?? { start: null, end: null };
|
|
778
811
|
const next = { ...current, [part]: parsed };
|
|
@@ -826,7 +859,7 @@ class MxDateRangePicker {
|
|
|
826
859
|
inputmode="numeric"
|
|
827
860
|
autocomplete="off"
|
|
828
861
|
[id]="controlId()"
|
|
829
|
-
[placeholder]="
|
|
862
|
+
[placeholder]="placeholderText()"
|
|
830
863
|
[value]="startText()"
|
|
831
864
|
[disabled]="isDisabled()"
|
|
832
865
|
[attr.aria-labelledby]="labelledBy(startLabelId)"
|
|
@@ -843,7 +876,7 @@ class MxDateRangePicker {
|
|
|
843
876
|
type="text"
|
|
844
877
|
inputmode="numeric"
|
|
845
878
|
autocomplete="off"
|
|
846
|
-
[placeholder]="
|
|
879
|
+
[placeholder]="placeholderText()"
|
|
847
880
|
[value]="endText()"
|
|
848
881
|
[disabled]="isDisabled()"
|
|
849
882
|
[attr.aria-labelledby]="labelledBy(endLabelId)"
|
|
@@ -854,8 +887,8 @@ class MxDateRangePicker {
|
|
|
854
887
|
(blur)="onTouched()"
|
|
855
888
|
(keydown.alt.arrowdown)="$event.preventDefault(); open()"
|
|
856
889
|
/>
|
|
857
|
-
<span class="mx-visually-hidden" [id]="startLabelId">{{ startLabel() }}</span>
|
|
858
|
-
<span class="mx-visually-hidden" [id]="endLabelId">{{ endLabel() }}</span>
|
|
890
|
+
<span class="mx-visually-hidden" [id]="startLabelId">{{ startLabel() ?? msg().start }}</span>
|
|
891
|
+
<span class="mx-visually-hidden" [id]="endLabelId">{{ endLabel() ?? msg().end }}</span>
|
|
859
892
|
@if (!field?.labelId()) {
|
|
860
893
|
<span class="mx-visually-hidden" [id]="nameId">{{ nameText() }}</span>
|
|
861
894
|
}
|
|
@@ -886,9 +919,9 @@ class MxDateRangePicker {
|
|
|
886
919
|
(attach)="onAttach()"
|
|
887
920
|
(detach)="close(false)"
|
|
888
921
|
>
|
|
889
|
-
<div class="mx-date-picker-panel mx-date-range-panel" role="dialog" aria-modal="false" aria-label="
|
|
922
|
+
<div class="mx-date-picker-panel mx-date-range-panel" role="dialog" aria-modal="false" [attr.aria-label]="msg().choose">
|
|
890
923
|
@if (presets().length) {
|
|
891
|
-
<ul class="mx-date-range-presets" aria-label="
|
|
924
|
+
<ul class="mx-date-range-presets" [attr.aria-label]="msg().presets">
|
|
892
925
|
@for (p of presets(); track p.label) {
|
|
893
926
|
<li><button type="button" class="mx-date-range-preset" (click)="applyPreset(p)">{{ p.label }}</button></li>
|
|
894
927
|
}
|
|
@@ -901,7 +934,7 @@ class MxDateRangePicker {
|
|
|
901
934
|
[min]="min()"
|
|
902
935
|
[max]="max()"
|
|
903
936
|
[dateDisabled]="dateDisabled()"
|
|
904
|
-
[locale]="
|
|
937
|
+
[locale]="loc()"
|
|
905
938
|
(rangeSelected)="choose($event)"
|
|
906
939
|
/>
|
|
907
940
|
</div>
|
|
@@ -933,7 +966,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
933
966
|
inputmode="numeric"
|
|
934
967
|
autocomplete="off"
|
|
935
968
|
[id]="controlId()"
|
|
936
|
-
[placeholder]="
|
|
969
|
+
[placeholder]="placeholderText()"
|
|
937
970
|
[value]="startText()"
|
|
938
971
|
[disabled]="isDisabled()"
|
|
939
972
|
[attr.aria-labelledby]="labelledBy(startLabelId)"
|
|
@@ -950,7 +983,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
950
983
|
type="text"
|
|
951
984
|
inputmode="numeric"
|
|
952
985
|
autocomplete="off"
|
|
953
|
-
[placeholder]="
|
|
986
|
+
[placeholder]="placeholderText()"
|
|
954
987
|
[value]="endText()"
|
|
955
988
|
[disabled]="isDisabled()"
|
|
956
989
|
[attr.aria-labelledby]="labelledBy(endLabelId)"
|
|
@@ -961,8 +994,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
961
994
|
(blur)="onTouched()"
|
|
962
995
|
(keydown.alt.arrowdown)="$event.preventDefault(); open()"
|
|
963
996
|
/>
|
|
964
|
-
<span class="mx-visually-hidden" [id]="startLabelId">{{ startLabel() }}</span>
|
|
965
|
-
<span class="mx-visually-hidden" [id]="endLabelId">{{ endLabel() }}</span>
|
|
997
|
+
<span class="mx-visually-hidden" [id]="startLabelId">{{ startLabel() ?? msg().start }}</span>
|
|
998
|
+
<span class="mx-visually-hidden" [id]="endLabelId">{{ endLabel() ?? msg().end }}</span>
|
|
966
999
|
@if (!field?.labelId()) {
|
|
967
1000
|
<span class="mx-visually-hidden" [id]="nameId">{{ nameText() }}</span>
|
|
968
1001
|
}
|
|
@@ -993,9 +1026,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
993
1026
|
(attach)="onAttach()"
|
|
994
1027
|
(detach)="close(false)"
|
|
995
1028
|
>
|
|
996
|
-
<div class="mx-date-picker-panel mx-date-range-panel" role="dialog" aria-modal="false" aria-label="
|
|
1029
|
+
<div class="mx-date-picker-panel mx-date-range-panel" role="dialog" aria-modal="false" [attr.aria-label]="msg().choose">
|
|
997
1030
|
@if (presets().length) {
|
|
998
|
-
<ul class="mx-date-range-presets" aria-label="
|
|
1031
|
+
<ul class="mx-date-range-presets" [attr.aria-label]="msg().presets">
|
|
999
1032
|
@for (p of presets(); track p.label) {
|
|
1000
1033
|
<li><button type="button" class="mx-date-range-preset" (click)="applyPreset(p)">{{ p.label }}</button></li>
|
|
1001
1034
|
}
|
|
@@ -1008,7 +1041,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
1008
1041
|
[min]="min()"
|
|
1009
1042
|
[max]="max()"
|
|
1010
1043
|
[dateDisabled]="dateDisabled()"
|
|
1011
|
-
[locale]="
|
|
1044
|
+
[locale]="loc()"
|
|
1012
1045
|
(rangeSelected)="choose($event)"
|
|
1013
1046
|
/>
|
|
1014
1047
|
</div>
|