@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.
Files changed (89) 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 +102 -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 +32 -27
  25. package/fesm2022/muxima-ui-core-file-upload.mjs.map +1 -1
  26. package/fesm2022/muxima-ui-core-form-field.mjs +2 -2
  27. package/fesm2022/muxima-ui-core-form-field.mjs.map +1 -1
  28. package/fesm2022/muxima-ui-core-i18n.mjs +550 -0
  29. package/fesm2022/muxima-ui-core-i18n.mjs.map +1 -0
  30. package/fesm2022/muxima-ui-core-image-cropper.mjs +27 -24
  31. package/fesm2022/muxima-ui-core-image-cropper.mjs.map +1 -1
  32. package/fesm2022/muxima-ui-core-kanban.mjs +22 -19
  33. package/fesm2022/muxima-ui-core-kanban.mjs.map +1 -1
  34. package/fesm2022/muxima-ui-core-notification-center.mjs +42 -37
  35. package/fesm2022/muxima-ui-core-notification-center.mjs.map +1 -1
  36. package/fesm2022/muxima-ui-core-pagination.mjs +29 -26
  37. package/fesm2022/muxima-ui-core-pagination.mjs.map +1 -1
  38. package/fesm2022/muxima-ui-core-progress.mjs +5 -3
  39. package/fesm2022/muxima-ui-core-progress.mjs.map +1 -1
  40. package/fesm2022/muxima-ui-core-rating.mjs +12 -8
  41. package/fesm2022/muxima-ui-core-rating.mjs.map +1 -1
  42. package/fesm2022/muxima-ui-core-select.mjs +14 -11
  43. package/fesm2022/muxima-ui-core-select.mjs.map +1 -1
  44. package/fesm2022/muxima-ui-core-sidebar.mjs +10 -7
  45. package/fesm2022/muxima-ui-core-sidebar.mjs.map +1 -1
  46. package/fesm2022/muxima-ui-core-slider.mjs +10 -8
  47. package/fesm2022/muxima-ui-core-slider.mjs.map +1 -1
  48. package/fesm2022/muxima-ui-core-stepper.mjs +5 -3
  49. package/fesm2022/muxima-ui-core-stepper.mjs.map +1 -1
  50. package/fesm2022/muxima-ui-core-table.mjs +4 -4
  51. package/fesm2022/muxima-ui-core-table.mjs.map +1 -1
  52. package/fesm2022/muxima-ui-core-time-picker.mjs +7 -5
  53. package/fesm2022/muxima-ui-core-time-picker.mjs.map +1 -1
  54. package/fesm2022/muxima-ui-core-toast.mjs +8 -5
  55. package/fesm2022/muxima-ui-core-toast.mjs.map +1 -1
  56. package/fesm2022/muxima-ui-core-tour.mjs +6 -12
  57. package/fesm2022/muxima-ui-core-tour.mjs.map +1 -1
  58. package/fesm2022/muxima-ui-core.mjs +1 -1
  59. package/fesm2022/muxima-ui-core.mjs.map +1 -1
  60. package/package.json +5 -1
  61. package/types/muxima-ui-core-alert.d.ts +3 -1
  62. package/types/muxima-ui-core-breadcrumb.d.ts +6 -4
  63. package/types/muxima-ui-core-carousel.d.ts +4 -2
  64. package/types/muxima-ui-core-chips.d.ts +23 -3
  65. package/types/muxima-ui-core-clipboard.d.ts +6 -3
  66. package/types/muxima-ui-core-color-picker.d.ts +40 -7
  67. package/types/muxima-ui-core-combobox.d.ts +6 -3
  68. package/types/muxima-ui-core-command.d.ts +7 -3
  69. package/types/muxima-ui-core-data-grid.d.ts +30 -10
  70. package/types/muxima-ui-core-date-picker.d.ts +64 -15
  71. package/types/muxima-ui-core-editor.d.ts +13 -2
  72. package/types/muxima-ui-core-file-upload.d.ts +23 -7
  73. package/types/muxima-ui-core-form-field.d.ts +2 -2
  74. package/types/muxima-ui-core-i18n.d.ts +322 -0
  75. package/types/muxima-ui-core-image-cropper.d.ts +19 -6
  76. package/types/muxima-ui-core-kanban.d.ts +16 -3
  77. package/types/muxima-ui-core-notification-center.d.ts +31 -9
  78. package/types/muxima-ui-core-pagination.d.ts +16 -1
  79. package/types/muxima-ui-core-progress.d.ts +10 -8
  80. package/types/muxima-ui-core-rating.d.ts +6 -2
  81. package/types/muxima-ui-core-select.d.ts +6 -3
  82. package/types/muxima-ui-core-sidebar.d.ts +6 -3
  83. package/types/muxima-ui-core-slider.d.ts +6 -4
  84. package/types/muxima-ui-core-stepper.d.ts +10 -8
  85. package/types/muxima-ui-core-table.d.ts +3 -3
  86. package/types/muxima-ui-core-time-picker.d.ts +3 -1
  87. package/types/muxima-ui-core-toast.d.ts +3 -0
  88. package/types/muxima-ui-core-tour.d.ts +3 -3
  89. 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_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
- 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,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
- /** 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
+ /**
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 [d, mo, y] = [Number(m[1]), Number(m[2]) - 1, Number(m[3])];
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
- function mxFormatDate(d) {
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
- return `${pad(d.getDate())}/${pad(d.getMonth() + 1)}/${d.getFullYear()}`;
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
- locale = input('pt-AO', ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
382
- placeholder = input('dd/mm/aaaa', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
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.locale(), { dateStyle: 'full' }).format(this.value()) : '', ...(ngDevMode ? [{ debugName: "longLabel" }] : /* istanbul ignore next */ []));
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() ? 'Mudar data, ' + longLabel() : 'Escolher data'"
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]="'Escolher data'">
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]="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() ? 'Mudar data, ' + longLabel() : 'Escolher data'"
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]="'Escolher data'">
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]="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
- /** Atalhos comuns: últimos 7 e 30 dias, este mês e o mês passado. */
633
- function mxDefaultRangePresets() {
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: 'Últimos 7 dias', range: () => ({ start: shift(today(), -6), end: today() }) },
638
- { label: 'Últimos 30 dias', range: () => ({ start: shift(today(), -29), end: today() }) },
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: 'Este mês',
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: 'Mês passado',
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
- 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 */ []));
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 '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)}`;
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]="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]="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="Escolher intervalo">
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="Atalhos">
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]="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]="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]="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="Escolher intervalo">
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="Atalhos">
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]="locale()"
1044
+ [locale]="loc()"
1012
1045
  (rangeSelected)="choose($event)"
1013
1046
  />
1014
1047
  </div>