@muxima-ui/core 1.4.0 → 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.
Files changed (87) hide show
  1. package/README.md +11 -0
  2. package/fesm2022/muxima-ui-core-alert.mjs +5 -3
  3. package/fesm2022/muxima-ui-core-alert.mjs.map +1 -1
  4. package/fesm2022/muxima-ui-core-breadcrumb.mjs +5 -3
  5. package/fesm2022/muxima-ui-core-breadcrumb.mjs.map +1 -1
  6. package/fesm2022/muxima-ui-core-carousel.mjs +19 -17
  7. package/fesm2022/muxima-ui-core-carousel.mjs.map +1 -1
  8. package/fesm2022/muxima-ui-core-chips.mjs +19 -14
  9. package/fesm2022/muxima-ui-core-chips.mjs.map +1 -1
  10. package/fesm2022/muxima-ui-core-clipboard.mjs +10 -6
  11. package/fesm2022/muxima-ui-core-clipboard.mjs.map +1 -1
  12. package/fesm2022/muxima-ui-core-color-picker.mjs +53 -50
  13. package/fesm2022/muxima-ui-core-color-picker.mjs.map +1 -1
  14. package/fesm2022/muxima-ui-core-combobox.mjs +15 -12
  15. package/fesm2022/muxima-ui-core-combobox.mjs.map +1 -1
  16. package/fesm2022/muxima-ui-core-command.mjs +21 -16
  17. package/fesm2022/muxima-ui-core-command.mjs.map +1 -1
  18. package/fesm2022/muxima-ui-core-data-grid.mjs +50 -52
  19. package/fesm2022/muxima-ui-core-data-grid.mjs.map +1 -1
  20. package/fesm2022/muxima-ui-core-date-picker.mjs +97 -69
  21. package/fesm2022/muxima-ui-core-date-picker.mjs.map +1 -1
  22. package/fesm2022/muxima-ui-core-editor.mjs +25 -19
  23. package/fesm2022/muxima-ui-core-editor.mjs.map +1 -1
  24. package/fesm2022/muxima-ui-core-file-upload.mjs +30 -25
  25. package/fesm2022/muxima-ui-core-file-upload.mjs.map +1 -1
  26. package/fesm2022/muxima-ui-core-i18n.mjs +550 -0
  27. package/fesm2022/muxima-ui-core-i18n.mjs.map +1 -0
  28. package/fesm2022/muxima-ui-core-image-cropper.mjs +27 -24
  29. package/fesm2022/muxima-ui-core-image-cropper.mjs.map +1 -1
  30. package/fesm2022/muxima-ui-core-kanban.mjs +22 -19
  31. package/fesm2022/muxima-ui-core-kanban.mjs.map +1 -1
  32. package/fesm2022/muxima-ui-core-notification-center.mjs +41 -36
  33. package/fesm2022/muxima-ui-core-notification-center.mjs.map +1 -1
  34. package/fesm2022/muxima-ui-core-pagination.mjs +29 -26
  35. package/fesm2022/muxima-ui-core-pagination.mjs.map +1 -1
  36. package/fesm2022/muxima-ui-core-progress.mjs +5 -3
  37. package/fesm2022/muxima-ui-core-progress.mjs.map +1 -1
  38. package/fesm2022/muxima-ui-core-rating.mjs +12 -8
  39. package/fesm2022/muxima-ui-core-rating.mjs.map +1 -1
  40. package/fesm2022/muxima-ui-core-select.mjs +14 -11
  41. package/fesm2022/muxima-ui-core-select.mjs.map +1 -1
  42. package/fesm2022/muxima-ui-core-sidebar.mjs +10 -7
  43. package/fesm2022/muxima-ui-core-sidebar.mjs.map +1 -1
  44. package/fesm2022/muxima-ui-core-slider.mjs +8 -6
  45. package/fesm2022/muxima-ui-core-slider.mjs.map +1 -1
  46. package/fesm2022/muxima-ui-core-stepper.mjs +5 -3
  47. package/fesm2022/muxima-ui-core-stepper.mjs.map +1 -1
  48. package/fesm2022/muxima-ui-core-table.mjs +4 -4
  49. package/fesm2022/muxima-ui-core-table.mjs.map +1 -1
  50. package/fesm2022/muxima-ui-core-time-picker.mjs +7 -5
  51. package/fesm2022/muxima-ui-core-time-picker.mjs.map +1 -1
  52. package/fesm2022/muxima-ui-core-toast.mjs +8 -5
  53. package/fesm2022/muxima-ui-core-toast.mjs.map +1 -1
  54. package/fesm2022/muxima-ui-core-tour.mjs +10 -11
  55. package/fesm2022/muxima-ui-core-tour.mjs.map +1 -1
  56. package/fesm2022/muxima-ui-core.mjs +1 -1
  57. package/fesm2022/muxima-ui-core.mjs.map +1 -1
  58. package/package.json +6 -2
  59. package/styles/components/data-grid.css +1 -0
  60. package/types/muxima-ui-core-alert.d.ts +3 -1
  61. package/types/muxima-ui-core-breadcrumb.d.ts +6 -4
  62. package/types/muxima-ui-core-carousel.d.ts +4 -2
  63. package/types/muxima-ui-core-chips.d.ts +23 -3
  64. package/types/muxima-ui-core-clipboard.d.ts +6 -3
  65. package/types/muxima-ui-core-color-picker.d.ts +40 -7
  66. package/types/muxima-ui-core-combobox.d.ts +6 -3
  67. package/types/muxima-ui-core-command.d.ts +7 -3
  68. package/types/muxima-ui-core-data-grid.d.ts +31 -11
  69. package/types/muxima-ui-core-date-picker.d.ts +59 -14
  70. package/types/muxima-ui-core-editor.d.ts +13 -2
  71. package/types/muxima-ui-core-file-upload.d.ts +22 -6
  72. package/types/muxima-ui-core-i18n.d.ts +322 -0
  73. package/types/muxima-ui-core-image-cropper.d.ts +19 -6
  74. package/types/muxima-ui-core-kanban.d.ts +16 -3
  75. package/types/muxima-ui-core-notification-center.d.ts +30 -8
  76. package/types/muxima-ui-core-pagination.d.ts +16 -1
  77. package/types/muxima-ui-core-progress.d.ts +10 -8
  78. package/types/muxima-ui-core-rating.d.ts +6 -2
  79. package/types/muxima-ui-core-select.d.ts +6 -3
  80. package/types/muxima-ui-core-sidebar.d.ts +6 -3
  81. package/types/muxima-ui-core-slider.d.ts +4 -2
  82. package/types/muxima-ui-core-stepper.d.ts +10 -8
  83. package/types/muxima-ui-core-table.d.ts +3 -3
  84. package/types/muxima-ui-core-time-picker.d.ts +3 -1
  85. package/types/muxima-ui-core-toast.d.ts +3 -0
  86. package/types/muxima-ui-core-tour.d.ts +6 -1
  87. 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, computed, afterNextRender, ViewEncapsulation, ChangeDetectionStrategy, Component, booleanAttribute, viewChild } from '@angular/core';
2
+ import { model, input, computed, output, inject, ElementRef, Injector, signal, afterNextRender, ViewEncapsulation, ChangeDetectionStrategy, Component, booleanAttribute, viewChild } from '@angular/core';
3
+ import { injectMxMessages, MX_MESSAGES_PT } 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
- locale = input('pt-AO', ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
43
- /** Primeiro dia da semana: 1 = segunda-feira. */
44
- firstDayOfWeek = input(1, ...(ngDevMode ? [{ debugName: "firstDayOfWeek" }] : /* istanbul ignore next */ []));
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.locale(), { day: 'numeric', month: 'long', year: 'numeric' });
65
- return r.end ? `Intervalo de ${f.format(r.start)} a ${f.format(r.end)}.` : `Início ${f.format(r.start)}. Escolhe a data de fim.`;
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.locale(), { weekday: 'narrow' });
79
- const long = new Intl.DateTimeFormat(this.locale(), { weekday: 'long' });
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.firstDayOfWeek() - 1 + i + 7) % 7));
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.firstDayOfWeek() + 7) % 7;
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.locale(), { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' });
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 label = fmt.format(date) + (isStart && isEnd ? ', início e fim do intervalo' : isStart ? ', início do intervalo' : isEnd ? ', fim do intervalo' : '');
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.locale(), { month: 'long', year: 'numeric' }).format(d);
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.firstDayOfWeek() + 7) % 7;
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]="'Mês anterior, ' + monthLabel(-1)">
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]="'Mês seguinte, ' + monthLabel(1)">
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]="'Mês anterior, ' + monthLabel(-1)">
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]="'Mês seguinte, ' + monthLabel(1)">
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,26 @@ 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
- /** Converte "dd/mm/aaaa" numa data. Aceita também "-" e "." como separadores. */
348
- function mxParseDate(text) {
349
- const m = text.trim().match(/^(\d{1,2})[/.-](\d{1,2})[/.-](\d{4})$/);
354
+ function mxParseDate(text, order = 'dmy') {
355
+ const t = text.trim();
356
+ const m = order === 'ymd'
357
+ ? t.match(/^(\d{4})[/.-](\d{1,2})[/.-](\d{1,2})$/)
358
+ : t.match(/^(\d{1,2})[/.-](\d{1,2})[/.-](\d{4})$/);
350
359
  if (!m)
351
360
  return null;
352
- const [d, mo, y] = [Number(m[1]), Number(m[2]) - 1, Number(m[3])];
361
+ const n = [Number(m[1]), Number(m[2]), Number(m[3])];
362
+ 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
363
  const date = new Date(y, mo, d);
354
364
  return date.getFullYear() === y && date.getMonth() === mo && date.getDate() === d ? date : null;
355
365
  }
356
- function mxFormatDate(d) {
366
+ function mxFormatDate(d, order = 'dmy') {
357
367
  if (!d)
358
368
  return '';
359
369
  const pad = (n) => String(n).padStart(2, '0');
360
- return `${pad(d.getDate())}/${pad(d.getMonth() + 1)}/${d.getFullYear()}`;
370
+ const [day, month, year] = [pad(d.getDate()), pad(d.getMonth() + 1), d.getFullYear()];
371
+ if (order === 'ymd')
372
+ return `${year}-${month}-${day}`;
373
+ return order === 'mdy' ? `${month}/${day}/${year}` : `${day}/${month}/${year}`;
361
374
  }
362
375
  /**
363
376
  * Campo de data: escreve-se "dd/mm/aaaa" ou escolhe-se no calendário.
@@ -378,8 +391,13 @@ class MxDatePicker {
378
391
  min = input(null, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
379
392
  max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
380
393
  dateDisabled = input(() => false, ...(ngDevMode ? [{ debugName: "dateDisabled" }] : /* istanbul ignore next */ []));
381
- locale = input('pt-AO', ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
382
- placeholder = input('dd/mm/aaaa', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
394
+ /** Locale dos nomes dos meses e dos dias; por omissão o do idioma activo. */
395
+ locale = input(...(ngDevMode ? [undefined, { debugName: "locale" }] : /* istanbul ignore next */ []));
396
+ /** Por omissão "dd/mm/aaaa" em português e "mm/dd/yyyy" em inglês. */
397
+ placeholder = input(...(ngDevMode ? [undefined, { debugName: "placeholder" }] : /* istanbul ignore next */ []));
398
+ i18n = injectMxMessages();
399
+ msg = computed(() => this.i18n().datePicker, ...(ngDevMode ? [{ debugName: "msg" }] : /* istanbul ignore next */ []));
400
+ loc = computed(() => this.locale() ?? this.i18n().intlLocale, ...(ngDevMode ? [{ debugName: "loc" }] : /* istanbul ignore next */ []));
383
401
  disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
384
402
  required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
385
403
  invalid = input(false, { ...(ngDevMode ? { debugName: "invalid" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
@@ -399,10 +417,10 @@ class MxDatePicker {
399
417
  draft = signal(null, ...(ngDevMode ? [{ debugName: "draft" }] : /* istanbul ignore next */ []));
400
418
  formDisabled = signal(false, ...(ngDevMode ? [{ debugName: "formDisabled" }] : /* istanbul ignore next */ []));
401
419
  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.locale(), { dateStyle: 'full' }).format(this.value()) : '', ...(ngDevMode ? [{ debugName: "longLabel" }] : /* istanbul ignore next */ []));
420
+ text = computed(() => this.draft() ?? mxFormatDate(this.value(), this.i18n().dateOrder), ...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []));
421
+ longLabel = computed(() => this.value() ? new Intl.DateTimeFormat(this.loc(), { dateStyle: 'full' }).format(this.value()) : '', ...(ngDevMode ? [{ debugName: "longLabel" }] : /* istanbul ignore next */ []));
404
422
  /** 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 */ []));
423
+ badFormat = computed(() => !!this.draft() && !mxParseDate(this.draft(), this.i18n().dateOrder), ...(ngDevMode ? [{ debugName: "badFormat" }] : /* istanbul ignore next */ []));
406
424
  onChange = () => { };
407
425
  onTouched = () => { };
408
426
  constructor() {
@@ -446,7 +464,7 @@ class MxDatePicker {
446
464
  }
447
465
  onInput(event) {
448
466
  const text = event.target.value;
449
- const parsed = mxParseDate(text);
467
+ const parsed = mxParseDate(text, this.i18n().dateOrder);
450
468
  if (parsed) {
451
469
  this.draft.set(null);
452
470
  this.setValue(parsed);
@@ -499,7 +517,7 @@ class MxDatePicker {
499
517
  inputmode="numeric"
500
518
  autocomplete="off"
501
519
  [id]="controlId()"
502
- [placeholder]="placeholder()"
520
+ [placeholder]="placeholder() ?? msg().placeholder"
503
521
  [value]="text()"
504
522
  [disabled]="isDisabled()"
505
523
  [attr.data-size]="size() === 'md' ? null : size()"
@@ -517,7 +535,7 @@ class MxDatePicker {
517
535
  class="mx-date-picker-toggle"
518
536
  aria-haspopup="dialog"
519
537
  [attr.aria-expanded]="isOpen()"
520
- [attr.aria-label]="value() ? 'Mudar data, ' + longLabel() : 'Escolher data'"
538
+ [attr.aria-label]="value() ? msg().change(longLabel()) : msg().choose"
521
539
  [disabled]="isDisabled()"
522
540
  (click)="toggle()"
523
541
  >
@@ -538,14 +556,14 @@ class MxDatePicker {
538
556
  (attach)="onAttach()"
539
557
  (detach)="close(false)"
540
558
  >
541
- <div class="mx-date-picker-panel" role="dialog" aria-modal="false" [attr.aria-label]="'Escolher data'">
559
+ <div class="mx-date-picker-panel" role="dialog" aria-modal="false" [attr.aria-label]="msg().choose">
542
560
  <mx-calendar
543
561
  #calendar
544
562
  [value]="value()"
545
563
  [min]="min()"
546
564
  [max]="max()"
547
565
  [dateDisabled]="dateDisabled()"
548
- [locale]="locale()"
566
+ [locale]="loc()"
549
567
  (selected)="choose($event)"
550
568
  />
551
569
  </div>
@@ -570,7 +588,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
570
588
  inputmode="numeric"
571
589
  autocomplete="off"
572
590
  [id]="controlId()"
573
- [placeholder]="placeholder()"
591
+ [placeholder]="placeholder() ?? msg().placeholder"
574
592
  [value]="text()"
575
593
  [disabled]="isDisabled()"
576
594
  [attr.data-size]="size() === 'md' ? null : size()"
@@ -588,7 +606,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
588
606
  class="mx-date-picker-toggle"
589
607
  aria-haspopup="dialog"
590
608
  [attr.aria-expanded]="isOpen()"
591
- [attr.aria-label]="value() ? 'Mudar data, ' + longLabel() : 'Escolher data'"
609
+ [attr.aria-label]="value() ? msg().change(longLabel()) : msg().choose"
592
610
  [disabled]="isDisabled()"
593
611
  (click)="toggle()"
594
612
  >
@@ -609,14 +627,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
609
627
  (attach)="onAttach()"
610
628
  (detach)="close(false)"
611
629
  >
612
- <div class="mx-date-picker-panel" role="dialog" aria-modal="false" [attr.aria-label]="'Escolher data'">
630
+ <div class="mx-date-picker-panel" role="dialog" aria-modal="false" [attr.aria-label]="msg().choose">
613
631
  <mx-calendar
614
632
  #calendar
615
633
  [value]="value()"
616
634
  [min]="min()"
617
635
  [max]="max()"
618
636
  [dateDisabled]="dateDisabled()"
619
- [locale]="locale()"
637
+ [locale]="loc()"
620
638
  (selected)="choose($event)"
621
639
  />
622
640
  </div>
@@ -629,22 +647,26 @@ const POSITIONS = [
629
647
  { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 4 },
630
648
  { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -4 },
631
649
  ];
632
- /** Atalhos comuns: últimos 7 e 30 dias, este mês e o mês passado. */
633
- function mxDefaultRangePresets() {
650
+ /**
651
+ * Atalhos comuns: últimos 7 e 30 dias, este mês e o mês passado.
652
+ * Os nomes vêm de `labels` (por omissão em português); para o idioma activo,
653
+ * usa `mxDefaultRangePresets(inject(MxI18n).messages().dateRangePicker)`.
654
+ */
655
+ function mxDefaultRangePresets(labels = MX_MESSAGES_PT.dateRangePicker) {
634
656
  const today = () => mxStartOfDay(new Date());
635
657
  const shift = (d, days) => new Date(d.getFullYear(), d.getMonth(), d.getDate() + days);
636
658
  return [
637
- { label: 'Últimos 7 dias', range: () => ({ start: shift(today(), -6), end: today() }) },
638
- { label: 'Últimos 30 dias', range: () => ({ start: shift(today(), -29), end: today() }) },
659
+ { label: labels.last7Days, range: () => ({ start: shift(today(), -6), end: today() }) },
660
+ { label: labels.last30Days, range: () => ({ start: shift(today(), -29), end: today() }) },
639
661
  {
640
- label: 'Este mês',
662
+ label: labels.thisMonth,
641
663
  range: () => {
642
664
  const t = today();
643
665
  return { start: new Date(t.getFullYear(), t.getMonth(), 1), end: new Date(t.getFullYear(), t.getMonth() + 1, 0) };
644
666
  },
645
667
  },
646
668
  {
647
- label: 'Mês passado',
669
+ label: labels.lastMonth,
648
670
  range: () => {
649
671
  const t = today();
650
672
  return { start: new Date(t.getFullYear(), t.getMonth() - 1, 1), end: new Date(t.getFullYear(), t.getMonth(), 0) };
@@ -672,10 +694,16 @@ class MxDateRangePicker {
672
694
  max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
673
695
  dateDisabled = input(() => false, ...(ngDevMode ? [{ debugName: "dateDisabled" }] : /* istanbul ignore next */ []));
674
696
  presets = input([], ...(ngDevMode ? [{ debugName: "presets" }] : /* istanbul ignore next */ []));
675
- locale = input('pt-AO', ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
676
- placeholder = input('dd/mm/aaaa', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
677
- startLabel = input('início', ...(ngDevMode ? [{ debugName: "startLabel" }] : /* istanbul ignore next */ []));
678
- endLabel = input('fim', ...(ngDevMode ? [{ debugName: "endLabel" }] : /* istanbul ignore next */ []));
697
+ /** Locale dos nomes dos meses e dos dias; por omissão o do idioma activo. */
698
+ locale = input(...(ngDevMode ? [undefined, { debugName: "locale" }] : /* istanbul ignore next */ []));
699
+ /** Por omissão "dd/mm/aaaa" em português e "mm/dd/yyyy" em inglês. */
700
+ placeholder = input(...(ngDevMode ? [undefined, { debugName: "placeholder" }] : /* istanbul ignore next */ []));
701
+ startLabel = input(...(ngDevMode ? [undefined, { debugName: "startLabel" }] : /* istanbul ignore next */ []));
702
+ endLabel = input(...(ngDevMode ? [undefined, { debugName: "endLabel" }] : /* istanbul ignore next */ []));
703
+ i18n = injectMxMessages();
704
+ msg = computed(() => this.i18n().dateRangePicker, ...(ngDevMode ? [{ debugName: "msg" }] : /* istanbul ignore next */ []));
705
+ loc = computed(() => this.locale() ?? this.i18n().intlLocale, ...(ngDevMode ? [{ debugName: "loc" }] : /* istanbul ignore next */ []));
706
+ placeholderText = computed(() => this.placeholder() ?? this.i18n().datePicker.placeholder, ...(ngDevMode ? [{ debugName: "placeholderText" }] : /* istanbul ignore next */ []));
679
707
  disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
680
708
  required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
681
709
  invalid = input(false, { ...(ngDevMode ? { debugName: "invalid" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
@@ -701,20 +729,20 @@ class MxDateRangePicker {
701
729
  draftText = signal({ start: null, end: null }, ...(ngDevMode ? [{ debugName: "draftText" }] : /* istanbul ignore next */ []));
702
730
  formDisabled = signal(false, ...(ngDevMode ? [{ debugName: "formDisabled" }] : /* istanbul ignore next */ []));
703
731
  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 */ []));
732
+ startText = computed(() => this.draftText().start ?? mxFormatDate(this.value()?.start ?? null, this.i18n().dateOrder), ...(ngDevMode ? [{ debugName: "startText" }] : /* istanbul ignore next */ []));
733
+ endText = computed(() => this.draftText().end ?? mxFormatDate(this.value()?.end ?? null, this.i18n().dateOrder), ...(ngDevMode ? [{ debugName: "endText" }] : /* istanbul ignore next */ []));
706
734
  /** true quando há texto que não é data, ou o fim é anterior ao início. */
707
735
  badFormat = computed(() => {
708
736
  const d = this.draftText();
709
737
  const v = this.value();
710
- return (!!d.start && !mxParseDate(d.start)) || (!!d.end && !mxParseDate(d.end)) || (!!v?.start && !!v?.end && v.end < v.start);
738
+ 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
739
  }, ...(ngDevMode ? [{ debugName: "badFormat" }] : /* istanbul ignore next */ []));
712
740
  toggleLabel = computed(() => {
713
741
  const v = this.value();
714
742
  if (!v?.start || !v?.end)
715
- return 'Escolher intervalo';
716
- const f = new Intl.DateTimeFormat(this.locale(), { day: 'numeric', month: 'long', year: 'numeric' });
717
- return `Mudar intervalo, ${f.format(v.start)} a ${f.format(v.end)}`;
743
+ return this.msg().choose;
744
+ const f = new Intl.DateTimeFormat(this.loc(), { day: 'numeric', month: 'long', year: 'numeric' });
745
+ return this.msg().change(f.format(v.start), f.format(v.end));
718
746
  }, ...(ngDevMode ? [{ debugName: "toggleLabel" }] : /* istanbul ignore next */ []));
719
747
  onChange = () => { };
720
748
  onTouched = () => { };
@@ -772,7 +800,7 @@ class MxDateRangePicker {
772
800
  }
773
801
  onInput(part, event) {
774
802
  const text = event.target.value;
775
- const parsed = mxParseDate(text);
803
+ const parsed = mxParseDate(text, this.i18n().dateOrder);
776
804
  this.draftText.update((d) => ({ ...d, [part]: parsed || !text ? null : text }));
777
805
  const current = this.value() ?? { start: null, end: null };
778
806
  const next = { ...current, [part]: parsed };
@@ -826,7 +854,7 @@ class MxDateRangePicker {
826
854
  inputmode="numeric"
827
855
  autocomplete="off"
828
856
  [id]="controlId()"
829
- [placeholder]="placeholder()"
857
+ [placeholder]="placeholderText()"
830
858
  [value]="startText()"
831
859
  [disabled]="isDisabled()"
832
860
  [attr.aria-labelledby]="labelledBy(startLabelId)"
@@ -843,7 +871,7 @@ class MxDateRangePicker {
843
871
  type="text"
844
872
  inputmode="numeric"
845
873
  autocomplete="off"
846
- [placeholder]="placeholder()"
874
+ [placeholder]="placeholderText()"
847
875
  [value]="endText()"
848
876
  [disabled]="isDisabled()"
849
877
  [attr.aria-labelledby]="labelledBy(endLabelId)"
@@ -854,8 +882,8 @@ class MxDateRangePicker {
854
882
  (blur)="onTouched()"
855
883
  (keydown.alt.arrowdown)="$event.preventDefault(); open()"
856
884
  />
857
- <span class="mx-visually-hidden" [id]="startLabelId">{{ startLabel() }}</span>
858
- <span class="mx-visually-hidden" [id]="endLabelId">{{ endLabel() }}</span>
885
+ <span class="mx-visually-hidden" [id]="startLabelId">{{ startLabel() ?? msg().start }}</span>
886
+ <span class="mx-visually-hidden" [id]="endLabelId">{{ endLabel() ?? msg().end }}</span>
859
887
  @if (!field?.labelId()) {
860
888
  <span class="mx-visually-hidden" [id]="nameId">{{ nameText() }}</span>
861
889
  }
@@ -886,9 +914,9 @@ class MxDateRangePicker {
886
914
  (attach)="onAttach()"
887
915
  (detach)="close(false)"
888
916
  >
889
- <div class="mx-date-picker-panel mx-date-range-panel" role="dialog" aria-modal="false" aria-label="Escolher intervalo">
917
+ <div class="mx-date-picker-panel mx-date-range-panel" role="dialog" aria-modal="false" [attr.aria-label]="msg().choose">
890
918
  @if (presets().length) {
891
- <ul class="mx-date-range-presets" aria-label="Atalhos">
919
+ <ul class="mx-date-range-presets" [attr.aria-label]="msg().presets">
892
920
  @for (p of presets(); track p.label) {
893
921
  <li><button type="button" class="mx-date-range-preset" (click)="applyPreset(p)">{{ p.label }}</button></li>
894
922
  }
@@ -901,7 +929,7 @@ class MxDateRangePicker {
901
929
  [min]="min()"
902
930
  [max]="max()"
903
931
  [dateDisabled]="dateDisabled()"
904
- [locale]="locale()"
932
+ [locale]="loc()"
905
933
  (rangeSelected)="choose($event)"
906
934
  />
907
935
  </div>
@@ -933,7 +961,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
933
961
  inputmode="numeric"
934
962
  autocomplete="off"
935
963
  [id]="controlId()"
936
- [placeholder]="placeholder()"
964
+ [placeholder]="placeholderText()"
937
965
  [value]="startText()"
938
966
  [disabled]="isDisabled()"
939
967
  [attr.aria-labelledby]="labelledBy(startLabelId)"
@@ -950,7 +978,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
950
978
  type="text"
951
979
  inputmode="numeric"
952
980
  autocomplete="off"
953
- [placeholder]="placeholder()"
981
+ [placeholder]="placeholderText()"
954
982
  [value]="endText()"
955
983
  [disabled]="isDisabled()"
956
984
  [attr.aria-labelledby]="labelledBy(endLabelId)"
@@ -961,8 +989,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
961
989
  (blur)="onTouched()"
962
990
  (keydown.alt.arrowdown)="$event.preventDefault(); open()"
963
991
  />
964
- <span class="mx-visually-hidden" [id]="startLabelId">{{ startLabel() }}</span>
965
- <span class="mx-visually-hidden" [id]="endLabelId">{{ endLabel() }}</span>
992
+ <span class="mx-visually-hidden" [id]="startLabelId">{{ startLabel() ?? msg().start }}</span>
993
+ <span class="mx-visually-hidden" [id]="endLabelId">{{ endLabel() ?? msg().end }}</span>
966
994
  @if (!field?.labelId()) {
967
995
  <span class="mx-visually-hidden" [id]="nameId">{{ nameText() }}</span>
968
996
  }
@@ -993,9 +1021,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
993
1021
  (attach)="onAttach()"
994
1022
  (detach)="close(false)"
995
1023
  >
996
- <div class="mx-date-picker-panel mx-date-range-panel" role="dialog" aria-modal="false" aria-label="Escolher intervalo">
1024
+ <div class="mx-date-picker-panel mx-date-range-panel" role="dialog" aria-modal="false" [attr.aria-label]="msg().choose">
997
1025
  @if (presets().length) {
998
- <ul class="mx-date-range-presets" aria-label="Atalhos">
1026
+ <ul class="mx-date-range-presets" [attr.aria-label]="msg().presets">
999
1027
  @for (p of presets(); track p.label) {
1000
1028
  <li><button type="button" class="mx-date-range-preset" (click)="applyPreset(p)">{{ p.label }}</button></li>
1001
1029
  }
@@ -1008,7 +1036,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
1008
1036
  [min]="min()"
1009
1037
  [max]="max()"
1010
1038
  [dateDisabled]="dateDisabled()"
1011
- [locale]="locale()"
1039
+ [locale]="loc()"
1012
1040
  (rangeSelected)="choose($event)"
1013
1041
  />
1014
1042
  </div>