matcha-components 20.277.0 → 20.279.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/fesm2022/matcha-components.mjs +1065 -26
- package/fesm2022/matcha-components.mjs.map +1 -1
- package/index.d.ts +332 -7
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ import { InjectionToken, HostListener, Input, Directive, EventEmitter, forwardRe
|
|
|
3
3
|
import * as i1 from '@angular/common';
|
|
4
4
|
import { CommonModule, DOCUMENT, isPlatformBrowser } from '@angular/common';
|
|
5
5
|
import * as i2 from '@angular/forms';
|
|
6
|
-
import { NG_VALUE_ACCESSOR, NgControl, FormControlName, NG_VALIDATORS, ReactiveFormsModule, FormsModule } from '@angular/forms';
|
|
6
|
+
import { NG_VALUE_ACCESSOR, NgControl, FormControlName, NG_VALIDATORS, ReactiveFormsModule, FormsModule, FormGroup, FormControl } from '@angular/forms';
|
|
7
7
|
import { Subject, Subscription, fromEvent, BehaviorSubject, of } from 'rxjs';
|
|
8
8
|
import { filter, debounceTime, distinctUntilChanged, takeUntil, startWith, map } from 'rxjs/operators';
|
|
9
9
|
import { animation, style, animate, trigger, transition, useAnimation, state, query, stagger, animateChild, sequence, group } from '@angular/animations';
|
|
@@ -425,12 +425,25 @@ class MatchaPanelComponent {
|
|
|
425
425
|
if (!this.open)
|
|
426
426
|
return;
|
|
427
427
|
const target = event.target;
|
|
428
|
+
// IMPORTANTE: o nó clicado pode ter sido REMOVIDO do DOM pelo próprio
|
|
429
|
+
// handler do clique antes deste listener rodar — o zone.js dispara
|
|
430
|
+
// change detection entre os listeners de um mesmo evento. Ex: trocar
|
|
431
|
+
// de view no matcha-calendar-picker (dias -> anos/meses) recria os
|
|
432
|
+
// botões via *ngIf, destruindo o botão clicado. Nesse caso
|
|
433
|
+
// `contains(target)` retorna false e o painel fechava indevidamente.
|
|
434
|
+
//
|
|
435
|
+
// Usamos `composedPath()`, capturado no início do dispatch, para saber
|
|
436
|
+
// ONDE o clique originou — robusto a remoções de nós durante o evento.
|
|
437
|
+
const path = (typeof event.composedPath === 'function'
|
|
438
|
+
? event.composedPath()
|
|
439
|
+
: []);
|
|
428
440
|
// Verificar se clicou dentro do painel (via ViewChild pois *ngIf recria)
|
|
429
441
|
const panelEl = this.panelRef?.nativeElement;
|
|
430
|
-
const isInsidePanel = panelEl
|
|
431
|
-
const isInsideTrigger = this.triggerElement
|
|
442
|
+
const isInsidePanel = !!panelEl && (path.includes(panelEl) || panelEl.contains(target));
|
|
443
|
+
const isInsideTrigger = !!this.triggerElement
|
|
444
|
+
&& (path.includes(this.triggerElement) || this.triggerElement.contains(target));
|
|
432
445
|
// Verificar se clicou dentro de um elemento ignorado (ex: submenu)
|
|
433
|
-
const isInsideIgnored = this.ignoreClickOutsideElements.some(el => el
|
|
446
|
+
const isInsideIgnored = this.ignoreClickOutsideElements.some(el => !!el && (path.includes(el) || el.contains(target)));
|
|
434
447
|
if (!isInsidePanel && !isInsideTrigger && !isInsideIgnored) {
|
|
435
448
|
this.closePanel();
|
|
436
449
|
}
|
|
@@ -1881,11 +1894,13 @@ class MatchaSelectComponent {
|
|
|
1881
1894
|
});
|
|
1882
1895
|
// Notificar a diretiva sobre a seleção
|
|
1883
1896
|
this.notifyDirectiveOfSelection(option.value);
|
|
1884
|
-
//
|
|
1885
|
-
|
|
1886
|
-
//
|
|
1897
|
+
// Notificar o Angular Forms sobre a mudança ANTES de emitir o evento:
|
|
1898
|
+
// consumidores que leem o valor atual do formulário no handler de
|
|
1899
|
+
// selectionChange precisam já enxergar o novo valor.
|
|
1887
1900
|
this.onChange(option.value);
|
|
1888
1901
|
this.onTouched();
|
|
1902
|
+
// Emitir evento de mudança de seleção (compatível com MatSelectChange)
|
|
1903
|
+
this.selectionChange.emit({ source: this, value: option.value });
|
|
1889
1904
|
// Forçar detecção de mudanças
|
|
1890
1905
|
this.cdr.detectChanges();
|
|
1891
1906
|
}
|
|
@@ -1942,11 +1957,13 @@ class MatchaSelectComponent {
|
|
|
1942
1957
|
});
|
|
1943
1958
|
// Notificar a diretiva sobre a seleção antes de fechar o painel
|
|
1944
1959
|
this.notifyDirectiveOfSelection(option.value);
|
|
1945
|
-
//
|
|
1946
|
-
|
|
1947
|
-
//
|
|
1960
|
+
// Notificar o Angular Forms sobre a mudança ANTES de emitir o evento:
|
|
1961
|
+
// consumidores que leem o valor atual do formulário no handler de
|
|
1962
|
+
// selectionChange precisam já enxergar o novo valor.
|
|
1948
1963
|
this.onChange(option.value);
|
|
1949
1964
|
this.onTouched();
|
|
1965
|
+
// Emitir evento de mudança de seleção (compatível com MatSelectChange)
|
|
1966
|
+
this.selectionChange.emit({ source: this, value: option.value });
|
|
1950
1967
|
// Fechamos painel automaticamente
|
|
1951
1968
|
this.closePanel();
|
|
1952
1969
|
// Forçar detecção de mudanças para garantir que o painel seja fechado
|
|
@@ -2807,9 +2824,12 @@ class MatchaSelectMultipleComponent {
|
|
|
2807
2824
|
}
|
|
2808
2825
|
emitChange() {
|
|
2809
2826
|
const value = [...this.selectedValues];
|
|
2810
|
-
|
|
2827
|
+
// Atualiza o FormControl ANTES de emitir o evento: consumidores que leem o
|
|
2828
|
+
// valor atual do formulário no handler de selectionChange precisam já
|
|
2829
|
+
// enxergar o novo valor.
|
|
2811
2830
|
this.onChange(value);
|
|
2812
2831
|
this.onTouched();
|
|
2832
|
+
this.selectionChange.emit({ source: this, value });
|
|
2813
2833
|
}
|
|
2814
2834
|
// ===== Ordenação / navegação =====
|
|
2815
2835
|
/** Retorna as opções com as marcadas primeiro, preservando a ordem de declaração. */
|
|
@@ -9249,13 +9269,412 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
9249
9269
|
args: [NgControl, { descendants: true }]
|
|
9250
9270
|
}] } });
|
|
9251
9271
|
|
|
9252
|
-
|
|
9272
|
+
/**
|
|
9273
|
+
* Serviço de internacionalização do matcha-calendar-picker.
|
|
9274
|
+
* Inspirado no MatchaPaginatorIntl, porém registrado APENAS via
|
|
9275
|
+
* `providedIn: 'root'` — nunca em `providers:` de módulo. Isso garante uma
|
|
9276
|
+
* única instância em todo o app mesmo com lazy loading (o registro em
|
|
9277
|
+
* `providers` de um módulo lazy criaria uma instância separada no injector
|
|
9278
|
+
* daquele módulo, e as alterações de label não chegariam ao componente).
|
|
9279
|
+
*
|
|
9280
|
+
* Uso no app consumidor:
|
|
9281
|
+
* constructor(private calendarIntl: MatchaCalendarIntl) {}
|
|
9282
|
+
* setEnglish() {
|
|
9283
|
+
* this.calendarIntl.monthNames = ['January', ...];
|
|
9284
|
+
* this.calendarIntl.changes.next();
|
|
9285
|
+
* }
|
|
9286
|
+
*/
|
|
9287
|
+
class MatchaCalendarIntl {
|
|
9253
9288
|
constructor() {
|
|
9289
|
+
/** Emite quando os labels mudam. O picker reconstrói as células ao receber. */
|
|
9290
|
+
this.changes = new Subject();
|
|
9291
|
+
/** Nomes completos dos meses (view de meses). Índice 0 = Janeiro. */
|
|
9292
|
+
this.monthNames = [
|
|
9293
|
+
'Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho',
|
|
9294
|
+
'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'
|
|
9295
|
+
];
|
|
9296
|
+
/** Nomes abreviados dos meses (cabeçalho da view de dias). Índice 0 = Jan. */
|
|
9297
|
+
this.monthNamesShort = [
|
|
9298
|
+
'Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun',
|
|
9299
|
+
'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'
|
|
9300
|
+
];
|
|
9301
|
+
/** Abreviações dos dias da semana (cabeçalho do grid). Índice 0 = Domingo. */
|
|
9302
|
+
this.weekdayNamesShort = ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab'];
|
|
9303
|
+
}
|
|
9304
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MatchaCalendarIntl, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
9305
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MatchaCalendarIntl, providedIn: 'root' }); }
|
|
9306
|
+
}
|
|
9307
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MatchaCalendarIntl, decorators: [{
|
|
9308
|
+
type: Injectable,
|
|
9309
|
+
args: [{ providedIn: 'root' }]
|
|
9310
|
+
}] });
|
|
9311
|
+
|
|
9312
|
+
/**
|
|
9313
|
+
* Calendário/datepicker apresentacional com três views (dias, meses, anos).
|
|
9314
|
+
*
|
|
9315
|
+
* É um componente "burro": recebe `value`/`min`/`max` (todos no formato
|
|
9316
|
+
* 'YYYY-MM-DD') e emite `dateChange` com a data selecionada. Não implementa
|
|
9317
|
+
* ControlValueAccessor — o host (ex: matcha-date) é quem mantém o valor.
|
|
9318
|
+
*
|
|
9319
|
+
* Tradução via {@link MatchaCalendarIntl} (global) ou pelos @Inputs de label
|
|
9320
|
+
* (override por instância). Os arrays de label são CACHEADOS dentro das
|
|
9321
|
+
* células, por isso reconstruímos as células quando `intl.changes` emite.
|
|
9322
|
+
*/
|
|
9323
|
+
class MatchaCalendarPickerComponent {
|
|
9324
|
+
constructor(intl, cdr) {
|
|
9325
|
+
this.intl = intl;
|
|
9326
|
+
this.cdr = cdr;
|
|
9327
|
+
/** Data selecionada no formato 'YYYY-MM-DD' (ou null). */
|
|
9328
|
+
this.value = null;
|
|
9329
|
+
/** Limite inferior 'YYYY-MM-DD' (ou '' para sem limite). */
|
|
9330
|
+
this.min = '';
|
|
9331
|
+
/** Limite superior 'YYYY-MM-DD' (ou '' para sem limite). */
|
|
9332
|
+
this.max = '';
|
|
9333
|
+
/** Emite a data selecionada no formato 'YYYY-MM-DD'. */
|
|
9334
|
+
this.dateChange = new EventEmitter();
|
|
9335
|
+
// Expor o tipo para o template
|
|
9336
|
+
this.view = 'day';
|
|
9337
|
+
// Caches reconstruídos a cada mudança de input/intl
|
|
9338
|
+
this.weekdayHeaders = [];
|
|
9339
|
+
this.dayCells = [];
|
|
9340
|
+
this.monthCells = [];
|
|
9341
|
+
this.yearCells = [];
|
|
9342
|
+
this.selectedDate = null;
|
|
9343
|
+
this.minDate = null;
|
|
9344
|
+
this.maxDate = null;
|
|
9345
|
+
this.userNavigated = false;
|
|
9346
|
+
this.intlSub = this.intl.changes.subscribe(() => {
|
|
9347
|
+
// Labels ficam cacheados nas células: reconstruir, não só markForCheck.
|
|
9348
|
+
this.rebuildAll();
|
|
9349
|
+
this.cdr.markForCheck();
|
|
9350
|
+
});
|
|
9351
|
+
this.initActiveFromToday();
|
|
9352
|
+
}
|
|
9353
|
+
ngOnChanges(changes) {
|
|
9354
|
+
if (changes['min'] || changes['max']) {
|
|
9355
|
+
this.parseBounds();
|
|
9356
|
+
}
|
|
9357
|
+
if (changes['value']) {
|
|
9358
|
+
this.parseSelection();
|
|
9359
|
+
// Só re-sincroniza o período exibido com a seleção se o usuário ainda
|
|
9360
|
+
// não navegou manualmente (evita "voltar" a tela ao re-vincular value).
|
|
9361
|
+
if (!this.userNavigated) {
|
|
9362
|
+
this.syncActiveToSelection();
|
|
9363
|
+
}
|
|
9364
|
+
}
|
|
9365
|
+
this.rebuildAll();
|
|
9366
|
+
}
|
|
9367
|
+
ngOnDestroy() {
|
|
9368
|
+
this.intlSub?.unsubscribe();
|
|
9369
|
+
}
|
|
9370
|
+
// ---------------------------------------------------------------------------
|
|
9371
|
+
// Labels (híbrido: @Input tem prioridade sobre o serviço)
|
|
9372
|
+
// ---------------------------------------------------------------------------
|
|
9373
|
+
get months() {
|
|
9374
|
+
return this.monthNames ?? this.intl.monthNames;
|
|
9375
|
+
}
|
|
9376
|
+
get monthsShort() {
|
|
9377
|
+
return this.monthNamesShort ?? this.intl.monthNamesShort;
|
|
9378
|
+
}
|
|
9379
|
+
get weekdays() {
|
|
9380
|
+
return this.weekdayNamesShort ?? this.intl.weekdayNamesShort;
|
|
9381
|
+
}
|
|
9382
|
+
get activeMonthLabelShort() {
|
|
9383
|
+
return this.monthsShort[this.activeMonth] ?? '';
|
|
9384
|
+
}
|
|
9385
|
+
get decadeLabel() {
|
|
9386
|
+
return `${this.decadeStart}-${this.decadeStart + 9}`;
|
|
9387
|
+
}
|
|
9388
|
+
// ---------------------------------------------------------------------------
|
|
9389
|
+
// Parse / format (timezone-safe: sempre componentes locais)
|
|
9390
|
+
// ---------------------------------------------------------------------------
|
|
9391
|
+
parseYmd(s) {
|
|
9392
|
+
if (!s || !/^\d{4}-\d{2}-\d{2}$/.test(s)) {
|
|
9393
|
+
return null;
|
|
9394
|
+
}
|
|
9395
|
+
const [y, m, d] = s.split('-').map(Number);
|
|
9396
|
+
const dt = new Date(y, m - 1, d);
|
|
9397
|
+
if (dt.getFullYear() !== y || dt.getMonth() + 1 !== m || dt.getDate() !== d) {
|
|
9398
|
+
return null;
|
|
9399
|
+
}
|
|
9400
|
+
return { y, m: m - 1, d };
|
|
9401
|
+
}
|
|
9402
|
+
formatYmd(y, m0, d) {
|
|
9403
|
+
return `${y}-${String(m0 + 1).padStart(2, '0')}-${String(d).padStart(2, '0')}`;
|
|
9404
|
+
}
|
|
9405
|
+
parseSelection() {
|
|
9406
|
+
this.selectedDate = this.parseYmd(this.value);
|
|
9407
|
+
}
|
|
9408
|
+
parseBounds() {
|
|
9409
|
+
const min = this.parseYmd(this.min);
|
|
9410
|
+
const max = this.parseYmd(this.max);
|
|
9411
|
+
this.minDate = min ? new Date(min.y, min.m, min.d) : null;
|
|
9412
|
+
this.maxDate = max ? new Date(max.y, max.m, max.d) : null;
|
|
9413
|
+
}
|
|
9414
|
+
// ---------------------------------------------------------------------------
|
|
9415
|
+
// Inicialização do período exibido
|
|
9416
|
+
// ---------------------------------------------------------------------------
|
|
9417
|
+
initActiveFromToday() {
|
|
9418
|
+
const now = new Date();
|
|
9419
|
+
this.activeYear = now.getFullYear();
|
|
9420
|
+
this.activeMonth = now.getMonth();
|
|
9421
|
+
this.decadeStart = Math.floor(this.activeYear / 10) * 10;
|
|
9422
|
+
}
|
|
9423
|
+
/** Posiciona o período exibido na seleção, ou hoje, clampando para [min,max]. */
|
|
9424
|
+
syncActiveToSelection() {
|
|
9425
|
+
let y;
|
|
9426
|
+
let m0;
|
|
9427
|
+
if (this.selectedDate) {
|
|
9428
|
+
y = this.selectedDate.y;
|
|
9429
|
+
m0 = this.selectedDate.m;
|
|
9430
|
+
}
|
|
9431
|
+
else {
|
|
9432
|
+
const now = new Date();
|
|
9433
|
+
y = now.getFullYear();
|
|
9434
|
+
m0 = now.getMonth();
|
|
9435
|
+
}
|
|
9436
|
+
// Clampar para o mês válido mais próximo quando o alvo cai fora de [min,max].
|
|
9437
|
+
const target = new Date(y, m0, 1);
|
|
9438
|
+
if (this.minDate && target.getTime() < new Date(this.minDate.getFullYear(), this.minDate.getMonth(), 1).getTime()) {
|
|
9439
|
+
y = this.minDate.getFullYear();
|
|
9440
|
+
m0 = this.minDate.getMonth();
|
|
9441
|
+
}
|
|
9442
|
+
else if (this.maxDate && target.getTime() > new Date(this.maxDate.getFullYear(), this.maxDate.getMonth(), 1).getTime()) {
|
|
9443
|
+
y = this.maxDate.getFullYear();
|
|
9444
|
+
m0 = this.maxDate.getMonth();
|
|
9445
|
+
}
|
|
9446
|
+
this.activeYear = y;
|
|
9447
|
+
this.activeMonth = m0;
|
|
9448
|
+
this.decadeStart = Math.floor(this.activeYear / 10) * 10;
|
|
9449
|
+
}
|
|
9450
|
+
/** Reposiciona a view ao reabrir (chamado pelo host). */
|
|
9451
|
+
resetView() {
|
|
9452
|
+
this.view = 'day';
|
|
9453
|
+
this.userNavigated = false;
|
|
9454
|
+
this.syncActiveToSelection();
|
|
9455
|
+
this.rebuildAll();
|
|
9456
|
+
this.cdr.markForCheck();
|
|
9457
|
+
}
|
|
9458
|
+
// ---------------------------------------------------------------------------
|
|
9459
|
+
// Construção das grids / labels
|
|
9460
|
+
// ---------------------------------------------------------------------------
|
|
9461
|
+
rebuildAll() {
|
|
9462
|
+
this.weekdayHeaders = [...this.weekdays];
|
|
9463
|
+
this.buildDayGrid();
|
|
9464
|
+
this.buildMonthGrid();
|
|
9465
|
+
this.buildYearGrid();
|
|
9466
|
+
}
|
|
9467
|
+
buildDayGrid() {
|
|
9468
|
+
const firstOfMonth = new Date(this.activeYear, this.activeMonth, 1);
|
|
9469
|
+
const leading = firstOfMonth.getDay(); // 0..6 (Domingo = 0)
|
|
9470
|
+
const gridStart = new Date(this.activeYear, this.activeMonth, 1 - leading);
|
|
9471
|
+
const cells = [];
|
|
9472
|
+
for (let i = 0; i < 42; i++) {
|
|
9473
|
+
const dt = new Date(gridStart.getFullYear(), gridStart.getMonth(), gridStart.getDate() + i);
|
|
9474
|
+
const y = dt.getFullYear();
|
|
9475
|
+
const m0 = dt.getMonth();
|
|
9476
|
+
const d = dt.getDate();
|
|
9477
|
+
cells.push({
|
|
9478
|
+
date: this.formatYmd(y, m0, d),
|
|
9479
|
+
day: d,
|
|
9480
|
+
inCurrentMonth: m0 === this.activeMonth,
|
|
9481
|
+
selected: this.isSelected(y, m0, d),
|
|
9482
|
+
disabled: this.isDateDisabled(dt),
|
|
9483
|
+
isToday: this.isToday(y, m0, d)
|
|
9484
|
+
});
|
|
9485
|
+
}
|
|
9486
|
+
this.dayCells = cells;
|
|
9487
|
+
}
|
|
9488
|
+
buildMonthGrid() {
|
|
9489
|
+
this.monthCells = this.months.map((label, m0) => ({
|
|
9490
|
+
month: m0,
|
|
9491
|
+
label,
|
|
9492
|
+
selected: !!this.selectedDate && this.selectedDate.y === this.activeYear && this.selectedDate.m === m0,
|
|
9493
|
+
disabled: this.isMonthFullyOutOfRange(this.activeYear, m0)
|
|
9494
|
+
}));
|
|
9495
|
+
}
|
|
9496
|
+
buildYearGrid() {
|
|
9497
|
+
this.decadeStart = Math.floor(this.activeYear / 10) * 10;
|
|
9498
|
+
const cells = [];
|
|
9499
|
+
for (let i = 0; i < 12; i++) {
|
|
9500
|
+
const yr = this.decadeStart + i;
|
|
9501
|
+
cells.push({
|
|
9502
|
+
year: yr,
|
|
9503
|
+
selected: !!this.selectedDate && this.selectedDate.y === yr,
|
|
9504
|
+
disabled: this.isYearFullyOutOfRange(yr)
|
|
9505
|
+
});
|
|
9506
|
+
}
|
|
9507
|
+
this.yearCells = cells;
|
|
9508
|
+
}
|
|
9509
|
+
// ---------------------------------------------------------------------------
|
|
9510
|
+
// Predicados
|
|
9511
|
+
// ---------------------------------------------------------------------------
|
|
9512
|
+
isSelected(y, m0, d) {
|
|
9513
|
+
return !!this.selectedDate
|
|
9514
|
+
&& this.selectedDate.y === y
|
|
9515
|
+
&& this.selectedDate.m === m0
|
|
9516
|
+
&& this.selectedDate.d === d;
|
|
9517
|
+
}
|
|
9518
|
+
isToday(y, m0, d) {
|
|
9519
|
+
const now = new Date();
|
|
9520
|
+
return now.getFullYear() === y && now.getMonth() === m0 && now.getDate() === d;
|
|
9521
|
+
}
|
|
9522
|
+
isDateDisabled(dt) {
|
|
9523
|
+
const t = dt.getTime();
|
|
9524
|
+
if (this.minDate && t < this.minDate.getTime()) {
|
|
9525
|
+
return true;
|
|
9526
|
+
}
|
|
9527
|
+
if (this.maxDate && t > this.maxDate.getTime()) {
|
|
9528
|
+
return true;
|
|
9529
|
+
}
|
|
9530
|
+
return false;
|
|
9531
|
+
}
|
|
9532
|
+
isMonthFullyOutOfRange(y, m0) {
|
|
9533
|
+
const first = new Date(y, m0, 1);
|
|
9534
|
+
const last = new Date(y, m0 + 1, 0); // último dia do mês
|
|
9535
|
+
if (this.maxDate && first.getTime() > this.maxDate.getTime()) {
|
|
9536
|
+
return true;
|
|
9537
|
+
}
|
|
9538
|
+
if (this.minDate && last.getTime() < this.minDate.getTime()) {
|
|
9539
|
+
return true;
|
|
9540
|
+
}
|
|
9541
|
+
return false;
|
|
9542
|
+
}
|
|
9543
|
+
isYearFullyOutOfRange(y) {
|
|
9544
|
+
const jan1 = new Date(y, 0, 1);
|
|
9545
|
+
const dec31 = new Date(y, 11, 31);
|
|
9546
|
+
if (this.maxDate && jan1.getTime() > this.maxDate.getTime()) {
|
|
9547
|
+
return true;
|
|
9548
|
+
}
|
|
9549
|
+
if (this.minDate && dec31.getTime() < this.minDate.getTime()) {
|
|
9550
|
+
return true;
|
|
9551
|
+
}
|
|
9552
|
+
return false;
|
|
9553
|
+
}
|
|
9554
|
+
// ---------------------------------------------------------------------------
|
|
9555
|
+
// Navegação (setas)
|
|
9556
|
+
// ---------------------------------------------------------------------------
|
|
9557
|
+
prev() {
|
|
9558
|
+
this.shift(-1);
|
|
9559
|
+
}
|
|
9560
|
+
next() {
|
|
9561
|
+
this.shift(1);
|
|
9562
|
+
}
|
|
9563
|
+
shift(dir) {
|
|
9564
|
+
this.userNavigated = true;
|
|
9565
|
+
if (this.view === 'day') {
|
|
9566
|
+
const dt = new Date(this.activeYear, this.activeMonth + dir, 1);
|
|
9567
|
+
this.activeYear = dt.getFullYear();
|
|
9568
|
+
this.activeMonth = dt.getMonth();
|
|
9569
|
+
}
|
|
9570
|
+
else if (this.view === 'month') {
|
|
9571
|
+
this.activeYear += dir;
|
|
9572
|
+
}
|
|
9573
|
+
else {
|
|
9574
|
+
this.activeYear += dir * 10;
|
|
9575
|
+
}
|
|
9576
|
+
this.rebuildAll();
|
|
9577
|
+
}
|
|
9578
|
+
// ---------------------------------------------------------------------------
|
|
9579
|
+
// Troca de view (toggles do cabeçalho)
|
|
9580
|
+
// ---------------------------------------------------------------------------
|
|
9581
|
+
openMonthView() {
|
|
9582
|
+
this.userNavigated = true;
|
|
9583
|
+
this.view = 'month';
|
|
9584
|
+
this.rebuildAll();
|
|
9585
|
+
}
|
|
9586
|
+
openYearView() {
|
|
9587
|
+
this.userNavigated = true;
|
|
9588
|
+
this.view = 'year';
|
|
9589
|
+
this.rebuildAll();
|
|
9590
|
+
}
|
|
9591
|
+
// ---------------------------------------------------------------------------
|
|
9592
|
+
// Seleção
|
|
9593
|
+
// ---------------------------------------------------------------------------
|
|
9594
|
+
selectDay(cell) {
|
|
9595
|
+
if (cell.disabled) {
|
|
9596
|
+
return;
|
|
9597
|
+
}
|
|
9598
|
+
this.dateChange.emit(cell.date);
|
|
9599
|
+
}
|
|
9600
|
+
selectMonth(cell) {
|
|
9601
|
+
if (cell.disabled) {
|
|
9602
|
+
return;
|
|
9603
|
+
}
|
|
9604
|
+
this.activeMonth = cell.month;
|
|
9605
|
+
this.view = 'day';
|
|
9606
|
+
this.rebuildAll();
|
|
9607
|
+
}
|
|
9608
|
+
selectYear(cell) {
|
|
9609
|
+
if (cell.disabled) {
|
|
9610
|
+
return;
|
|
9611
|
+
}
|
|
9612
|
+
this.activeYear = cell.year;
|
|
9613
|
+
this.view = 'month';
|
|
9614
|
+
this.rebuildAll();
|
|
9615
|
+
}
|
|
9616
|
+
/** trackBy para os grids (evita recriar nós ao reconstruir). */
|
|
9617
|
+
trackByDate(_, cell) {
|
|
9618
|
+
return cell.date;
|
|
9619
|
+
}
|
|
9620
|
+
trackByMonth(_, cell) {
|
|
9621
|
+
return cell.month;
|
|
9622
|
+
}
|
|
9623
|
+
trackByYear(_, cell) {
|
|
9624
|
+
return cell.year;
|
|
9625
|
+
}
|
|
9626
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MatchaCalendarPickerComponent, deps: [{ token: MatchaCalendarIntl }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
9627
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: MatchaCalendarPickerComponent, isStandalone: false, selector: "matcha-calendar-picker", inputs: { value: "value", min: "min", max: "max", monthNames: "monthNames", monthNamesShort: "monthNamesShort", weekdayNamesShort: "weekdayNamesShort" }, outputs: { dateChange: "dateChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"w-100-p p-8 background-surface color-text flex-column gap-md-16 gap-8\">\n <!-- Cabe\u00E7alho -->\n <div class=\"d-flex flex-align-center flex-space-between\">\n <div class=\"min-w-0 d-flex flex-align-center gap-8\">\n <!-- View de dias: toggle de ano + toggle de m\u00EAs -->\n <ng-container *ngIf=\"view === 'day'\">\n <button type=\"button\" matcha-button size=\"tiny\" class=\"px-8--force\" (click)=\"openYearView()\">\n <span class=\"color-label\">\n {{ activeYear }}\n </span>\n <matcha-icon name=\"action_arrow_down\" color=\"label\" size=\"medium\"></matcha-icon>\n </button>\n <button type=\"button\" matcha-button size=\"tiny\" class=\"px-8--force\" (click)=\"openMonthView()\">\n <span class=\"color-label\">\n {{ activeMonthLabelShort }}\n </span>\n <matcha-icon name=\"action_arrow_down\" color=\"label\" size=\"medium\"></matcha-icon>\n </button>\n </ng-container>\n\n <!-- View de meses: toggle de ano -->\n <button type=\"button\" matcha-button size=\"tiny\" class=\"px-8--force\" *ngIf=\"view === 'month'\" (click)=\"openYearView()\">\n <span class=\"color-label\">\n {{ activeYear }}\n </span>\n <matcha-icon name=\"action_arrow_down\" color=\"label\" size=\"medium\"></matcha-icon>\n </button>\n\n <!-- View de anos: r\u00F3tulo da d\u00E9cada -->\n <button type=\"button\" matcha-button size=\"tiny\" class=\"px-8--force\" *ngIf=\"view === 'year'\">\n <span class=\"color-label\">\n {{ decadeLabel }}\n </span>\n </button>\n </div>\n\n <div class=\"d-sm-flex--force flex-sm-align-center d-none\">\n <button type=\"button\" matcha-button link basic icon size=\"tiny\" color=\"accent\" (click)=\"prev()\" aria-label=\"Anterior\">\n <matcha-icon name=\"chevron-left\"></matcha-icon>\n </button>\n <button type=\"button\" matcha-button link basic icon size=\"tiny\" color=\"accent\" (click)=\"next()\" aria-label=\"Pr\u00F3ximo\">\n <matcha-icon name=\"chevron-right\"></matcha-icon>\n </button>\n </div>\n </div>\n\n <matcha-divider></matcha-divider>\n\n <!-- View de dias -->\n <div *ngIf=\"view === 'day'\">\n <div class=\"matcha-calendar-weekdays\">\n <span class=\"matcha-calendar-weekday\" *ngFor=\"let wd of weekdayHeaders\">{{ wd }}</span>\n </div>\n <div class=\"matcha-calendar-days\">\n <button type=\"button\" class=\"matcha-calendar-day\" *ngFor=\"let cell of dayCells; trackBy: trackByDate\" [class.matcha-calendar-day-outside]=\"!cell.inCurrentMonth\" [class.matcha-calendar-day-selected]=\"cell.selected\" [class.matcha-calendar-day-today]=\"cell.isToday && !cell.selected\" [disabled]=\"cell.disabled\" [attr.aria-label]=\"cell.date\" [attr.aria-selected]=\"cell.selected\" (click)=\"selectDay(cell)\">\n {{ cell.day }}\n </button>\n </div>\n </div>\n\n <!-- View de meses -->\n <div class=\"matcha-calendar-month-view\" *ngIf=\"view === 'month'\">\n <button type=\"button\" matcha-button color=\"surface\" *ngFor=\"let cell of monthCells; trackBy: trackByMonth\" [class.matcha-calendar-month-selected]=\"cell.selected\" [disabled]=\"cell.disabled\" [attr.aria-selected]=\"cell.selected\" (click)=\"selectMonth(cell)\">\n <span class=\"color-label fw-400 fs-12\">\n {{ cell.label }}\n </span>\n </button>\n </div>\n\n <!-- View de anos -->\n <div class=\"matcha-calendar-year-view\" *ngIf=\"view === 'year'\">\n <button type=\"button\" matcha-button color=\"surface\" class=\"h-36--force\" *ngFor=\"let cell of yearCells; trackBy: trackByYear\" [class.matcha-calendar-year-selected]=\"cell.selected\" [disabled]=\"cell.disabled\" [attr.aria-selected]=\"cell.selected\" (click)=\"selectYear(cell)\">\n <span class=\"color-label fw-400 fs-12\">\n {{ cell.year }}\n </span>\n </button>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: MatchaIconComponent, selector: "matcha-icon", inputs: ["name", "size", "color", "class", "loading"] }, { kind: "component", type: MatchaDividerComponent, selector: "matcha-divider", inputs: ["gap", "gap-sm", "gap-md", "gap-lg", "gap-xl", "direction"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
9628
|
+
}
|
|
9629
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MatchaCalendarPickerComponent, decorators: [{
|
|
9630
|
+
type: Component,
|
|
9631
|
+
args: [{ selector: 'matcha-calendar-picker', encapsulation: ViewEncapsulation.None, standalone: false, template: "<div class=\"w-100-p p-8 background-surface color-text flex-column gap-md-16 gap-8\">\n <!-- Cabe\u00E7alho -->\n <div class=\"d-flex flex-align-center flex-space-between\">\n <div class=\"min-w-0 d-flex flex-align-center gap-8\">\n <!-- View de dias: toggle de ano + toggle de m\u00EAs -->\n <ng-container *ngIf=\"view === 'day'\">\n <button type=\"button\" matcha-button size=\"tiny\" class=\"px-8--force\" (click)=\"openYearView()\">\n <span class=\"color-label\">\n {{ activeYear }}\n </span>\n <matcha-icon name=\"action_arrow_down\" color=\"label\" size=\"medium\"></matcha-icon>\n </button>\n <button type=\"button\" matcha-button size=\"tiny\" class=\"px-8--force\" (click)=\"openMonthView()\">\n <span class=\"color-label\">\n {{ activeMonthLabelShort }}\n </span>\n <matcha-icon name=\"action_arrow_down\" color=\"label\" size=\"medium\"></matcha-icon>\n </button>\n </ng-container>\n\n <!-- View de meses: toggle de ano -->\n <button type=\"button\" matcha-button size=\"tiny\" class=\"px-8--force\" *ngIf=\"view === 'month'\" (click)=\"openYearView()\">\n <span class=\"color-label\">\n {{ activeYear }}\n </span>\n <matcha-icon name=\"action_arrow_down\" color=\"label\" size=\"medium\"></matcha-icon>\n </button>\n\n <!-- View de anos: r\u00F3tulo da d\u00E9cada -->\n <button type=\"button\" matcha-button size=\"tiny\" class=\"px-8--force\" *ngIf=\"view === 'year'\">\n <span class=\"color-label\">\n {{ decadeLabel }}\n </span>\n </button>\n </div>\n\n <div class=\"d-sm-flex--force flex-sm-align-center d-none\">\n <button type=\"button\" matcha-button link basic icon size=\"tiny\" color=\"accent\" (click)=\"prev()\" aria-label=\"Anterior\">\n <matcha-icon name=\"chevron-left\"></matcha-icon>\n </button>\n <button type=\"button\" matcha-button link basic icon size=\"tiny\" color=\"accent\" (click)=\"next()\" aria-label=\"Pr\u00F3ximo\">\n <matcha-icon name=\"chevron-right\"></matcha-icon>\n </button>\n </div>\n </div>\n\n <matcha-divider></matcha-divider>\n\n <!-- View de dias -->\n <div *ngIf=\"view === 'day'\">\n <div class=\"matcha-calendar-weekdays\">\n <span class=\"matcha-calendar-weekday\" *ngFor=\"let wd of weekdayHeaders\">{{ wd }}</span>\n </div>\n <div class=\"matcha-calendar-days\">\n <button type=\"button\" class=\"matcha-calendar-day\" *ngFor=\"let cell of dayCells; trackBy: trackByDate\" [class.matcha-calendar-day-outside]=\"!cell.inCurrentMonth\" [class.matcha-calendar-day-selected]=\"cell.selected\" [class.matcha-calendar-day-today]=\"cell.isToday && !cell.selected\" [disabled]=\"cell.disabled\" [attr.aria-label]=\"cell.date\" [attr.aria-selected]=\"cell.selected\" (click)=\"selectDay(cell)\">\n {{ cell.day }}\n </button>\n </div>\n </div>\n\n <!-- View de meses -->\n <div class=\"matcha-calendar-month-view\" *ngIf=\"view === 'month'\">\n <button type=\"button\" matcha-button color=\"surface\" *ngFor=\"let cell of monthCells; trackBy: trackByMonth\" [class.matcha-calendar-month-selected]=\"cell.selected\" [disabled]=\"cell.disabled\" [attr.aria-selected]=\"cell.selected\" (click)=\"selectMonth(cell)\">\n <span class=\"color-label fw-400 fs-12\">\n {{ cell.label }}\n </span>\n </button>\n </div>\n\n <!-- View de anos -->\n <div class=\"matcha-calendar-year-view\" *ngIf=\"view === 'year'\">\n <button type=\"button\" matcha-button color=\"surface\" class=\"h-36--force\" *ngFor=\"let cell of yearCells; trackBy: trackByYear\" [class.matcha-calendar-year-selected]=\"cell.selected\" [disabled]=\"cell.disabled\" [attr.aria-selected]=\"cell.selected\" (click)=\"selectYear(cell)\">\n <span class=\"color-label fw-400 fs-12\">\n {{ cell.year }}\n </span>\n </button>\n </div>\n</div>\n" }]
|
|
9632
|
+
}], ctorParameters: () => [{ type: MatchaCalendarIntl }, { type: i0.ChangeDetectorRef }], propDecorators: { value: [{
|
|
9633
|
+
type: Input
|
|
9634
|
+
}], min: [{
|
|
9635
|
+
type: Input
|
|
9636
|
+
}], max: [{
|
|
9637
|
+
type: Input
|
|
9638
|
+
}], monthNames: [{
|
|
9639
|
+
type: Input
|
|
9640
|
+
}], monthNamesShort: [{
|
|
9641
|
+
type: Input
|
|
9642
|
+
}], weekdayNamesShort: [{
|
|
9643
|
+
type: Input
|
|
9644
|
+
}], dateChange: [{
|
|
9645
|
+
type: Output
|
|
9646
|
+
}] } });
|
|
9647
|
+
|
|
9648
|
+
class MatchaDateComponent {
|
|
9649
|
+
constructor(elRef, cdr) {
|
|
9650
|
+
this.elRef = elRef;
|
|
9651
|
+
this.cdr = cdr;
|
|
9254
9652
|
this.placeholder = '__/__/____';
|
|
9255
9653
|
this.min = '';
|
|
9256
9654
|
this.max = '';
|
|
9257
9655
|
this.disabled = false;
|
|
9258
9656
|
this.showNativePicker = true; // Mostrar botão para abrir datepicker nativo
|
|
9657
|
+
/**
|
|
9658
|
+
* Define o que o botão de calendário faz ao ser clicado.
|
|
9659
|
+
* - true (padrão): abre o datepicker nativo do navegador (comportamento histórico).
|
|
9660
|
+
* - false: NÃO abre o nativo. A abertura passa a ser responsabilidade do
|
|
9661
|
+
* matcha-calendar-picker (Parte 2), que conterá essa lógica.
|
|
9662
|
+
*/
|
|
9663
|
+
this.useNativePicker = true;
|
|
9664
|
+
/**
|
|
9665
|
+
* Quando true, o painel do matcha-calendar-picker NÃO dispara o evento global
|
|
9666
|
+
* que fecha os demais painéis. Use quando este matcha-date estiver ANINHADO
|
|
9667
|
+
* dentro de outro matcha-panel (ex: o modo "Personalizado" do matcha-period),
|
|
9668
|
+
* para que abrir o calendário não feche o painel pai.
|
|
9669
|
+
*/
|
|
9670
|
+
this.suppressPanelGlobalClose = false;
|
|
9671
|
+
/**
|
|
9672
|
+
* Emite o elemento do painel do calendário quando ele abre/fecha. O painel
|
|
9673
|
+
* pai (quando aninhado) usa esses elementos em `ignoreClickOutsideElements`
|
|
9674
|
+
* para não fechar ao clicar dentro do calendário.
|
|
9675
|
+
*/
|
|
9676
|
+
this.calendarPanelOpened = new EventEmitter();
|
|
9677
|
+
this.calendarPanelClosed = new EventEmitter();
|
|
9259
9678
|
this.value = '';
|
|
9260
9679
|
this.displayValue = '';
|
|
9261
9680
|
this.isDisabled = false;
|
|
@@ -9263,6 +9682,18 @@ class MatchaDateComponent {
|
|
|
9263
9682
|
this.onChange = (value) => { };
|
|
9264
9683
|
this.onTouched = () => { };
|
|
9265
9684
|
}
|
|
9685
|
+
ngAfterViewInit() {
|
|
9686
|
+
// Quando o picker nativo está desligado, ancoramos o painel do calendário
|
|
9687
|
+
// ao matcha-form-field (ou ao próprio host) — mesmo padrão do matcha-period.
|
|
9688
|
+
if (!this.useNativePicker && this.calendarPanel) {
|
|
9689
|
+
this.calendarPanel.attachTo(this.panelAnchor());
|
|
9690
|
+
}
|
|
9691
|
+
}
|
|
9692
|
+
/** Elemento âncora do painel: o matcha-form-field envolvente, ou o host. */
|
|
9693
|
+
panelAnchor() {
|
|
9694
|
+
const formField = this.elRef.nativeElement.closest('matcha-form-field');
|
|
9695
|
+
return formField || this.elRef.nativeElement;
|
|
9696
|
+
}
|
|
9266
9697
|
writeValue(value) {
|
|
9267
9698
|
if (value) {
|
|
9268
9699
|
// Se for um objeto Date, converter para YYYY-MM-DD (usando componentes locais)
|
|
@@ -9470,7 +9901,30 @@ class MatchaDateComponent {
|
|
|
9470
9901
|
}
|
|
9471
9902
|
}
|
|
9472
9903
|
openNativeDatePicker() {
|
|
9473
|
-
if (this.
|
|
9904
|
+
if (this.disabled || this.isDisabled) {
|
|
9905
|
+
return;
|
|
9906
|
+
}
|
|
9907
|
+
// Picker nativo desligado: abrir o matcha-calendar-picker no painel.
|
|
9908
|
+
if (!this.useNativePicker) {
|
|
9909
|
+
if (this.calendarPanel) {
|
|
9910
|
+
this.calendarPanel.attachTo(this.panelAnchor());
|
|
9911
|
+
if (this.calendarPanel.open) {
|
|
9912
|
+
this.calendarPanel.closePanel();
|
|
9913
|
+
}
|
|
9914
|
+
else {
|
|
9915
|
+
// Reposiciona a view na seleção atual ao (re)abrir.
|
|
9916
|
+
this.calendarPicker?.resetView();
|
|
9917
|
+
this.calendarPanel.openPanel();
|
|
9918
|
+
// Avisa o painel pai (quando aninhado) sobre o overlay do calendário.
|
|
9919
|
+
this.lastCalendarPane = this.calendarPanel.paneRef?.nativeElement;
|
|
9920
|
+
if (this.lastCalendarPane) {
|
|
9921
|
+
this.calendarPanelOpened.emit(this.lastCalendarPane);
|
|
9922
|
+
}
|
|
9923
|
+
}
|
|
9924
|
+
}
|
|
9925
|
+
return;
|
|
9926
|
+
}
|
|
9927
|
+
if (this.nativeDateInput?.nativeElement) {
|
|
9474
9928
|
// Verificar se showPicker está disponível (suporte moderno)
|
|
9475
9929
|
if (typeof this.nativeDateInput.nativeElement.showPicker === 'function') {
|
|
9476
9930
|
this.nativeDateInput.nativeElement.showPicker();
|
|
@@ -9482,6 +9936,29 @@ class MatchaDateComponent {
|
|
|
9482
9936
|
}
|
|
9483
9937
|
}
|
|
9484
9938
|
}
|
|
9939
|
+
/** Dia selecionado no matcha-calendar-picker (recebe 'YYYY-MM-DD'). */
|
|
9940
|
+
onCalendarDateSelected(ymd) {
|
|
9941
|
+
this.value = ymd;
|
|
9942
|
+
this.displayValue = this.formatDateForDisplay(ymd);
|
|
9943
|
+
if (this.nativeDateInput?.nativeElement) {
|
|
9944
|
+
this.nativeDateInput.nativeElement.value = ymd;
|
|
9945
|
+
}
|
|
9946
|
+
if (this.textInput?.nativeElement) {
|
|
9947
|
+
this.textInput.nativeElement.value = this.displayValue;
|
|
9948
|
+
}
|
|
9949
|
+
this.onChange(ymd);
|
|
9950
|
+
this.onTouched();
|
|
9951
|
+
this.calendarPanel?.closePanel();
|
|
9952
|
+
this.cdr.detectChanges();
|
|
9953
|
+
}
|
|
9954
|
+
onCalendarPanelClosed() {
|
|
9955
|
+
this.onTouched();
|
|
9956
|
+
// Libera o overlay registrado no painel pai (quando aninhado).
|
|
9957
|
+
if (this.lastCalendarPane) {
|
|
9958
|
+
this.calendarPanelClosed.emit(this.lastCalendarPane);
|
|
9959
|
+
this.lastCalendarPane = undefined;
|
|
9960
|
+
}
|
|
9961
|
+
}
|
|
9485
9962
|
isValidDateFormat(date, format) {
|
|
9486
9963
|
if (format === 'DD/MM/YYYY') {
|
|
9487
9964
|
return /^\d{2}\/\d{2}\/\d{4}$/.test(date);
|
|
@@ -9512,14 +9989,14 @@ class MatchaDateComponent {
|
|
|
9512
9989
|
const [year, month, day] = yyyyMMdd.split('-');
|
|
9513
9990
|
return `${day}/${month}/${year}`;
|
|
9514
9991
|
}
|
|
9515
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MatchaDateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
9516
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: MatchaDateComponent, isStandalone: false, selector: "matcha-date", inputs: { placeholder: "placeholder", min: "min", max: "max", disabled: "disabled", showNativePicker: "showNativePicker" }, providers: [
|
|
9992
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MatchaDateComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
9993
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: MatchaDateComponent, isStandalone: false, selector: "matcha-date", inputs: { placeholder: "placeholder", min: "min", max: "max", disabled: "disabled", showNativePicker: "showNativePicker", useNativePicker: "useNativePicker", suppressPanelGlobalClose: "suppressPanelGlobalClose" }, outputs: { calendarPanelOpened: "calendarPanelOpened", calendarPanelClosed: "calendarPanelClosed" }, providers: [
|
|
9517
9994
|
{
|
|
9518
9995
|
provide: NG_VALUE_ACCESSOR,
|
|
9519
9996
|
useExisting: forwardRef(() => MatchaDateComponent),
|
|
9520
9997
|
multi: true
|
|
9521
9998
|
}
|
|
9522
|
-
], viewQueries: [{ propertyName: "textInput", first: true, predicate: ["textInput"], descendants: true }, { propertyName: "nativeDateInput", first: true, predicate: ["nativeDateInput"], descendants: true }], ngImport: i0, template: "<div class=\"matcha-date-container\">\n <input\n #textInput\n type=\"text\"\n class=\"matcha-date-input\"\n [value]=\"displayValue\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled || isDisabled\"\n maxlength=\"10\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onBlur()\"\n (keydown)=\"onKeyDown($event)\"\n />\n\n <!-- Input nativo de data (hidden) para usar o datepicker nativo -->\n <input\n #nativeDateInput\n type=\"date\"\n class=\"matcha-date-native-input\"\n [value]=\"value\"\n [min]=\"min\"\n [max]=\"max\"\n [disabled]=\"disabled || isDisabled\"\n (change)=\"onNativeDateChange($event)\"\n tabindex=\"-1\"\n />\n\n <!-- Bot\u00E3o para abrir
|
|
9999
|
+
], viewQueries: [{ propertyName: "textInput", first: true, predicate: ["textInput"], descendants: true }, { propertyName: "nativeDateInput", first: true, predicate: ["nativeDateInput"], descendants: true }, { propertyName: "calendarPanel", first: true, predicate: MatchaPanelComponent, descendants: true }, { propertyName: "calendarPicker", first: true, predicate: MatchaCalendarPickerComponent, descendants: true }], ngImport: i0, template: "<div class=\"matcha-date-container\">\n <input\n #textInput\n type=\"text\"\n class=\"matcha-date-input\"\n [value]=\"displayValue\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled || isDisabled\"\n maxlength=\"10\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onBlur()\"\n (keydown)=\"onKeyDown($event)\"\n />\n\n <!-- Input nativo de data (hidden) para usar o datepicker nativo -->\n <input\n #nativeDateInput\n type=\"date\"\n class=\"matcha-date-native-input\"\n [value]=\"value\"\n [min]=\"min\"\n [max]=\"max\"\n [disabled]=\"disabled || isDisabled\"\n (change)=\"onNativeDateChange($event)\"\n tabindex=\"-1\"\n />\n\n <!-- Bot\u00E3o para abrir o seletor (nativo ou matcha-calendar-picker) -->\n <button\n *ngIf=\"(showNativePicker || !useNativePicker) && !disabled && !isDisabled\"\n type=\"button\"\n class=\"matcha-date-picker-button mr--12\"\n (click)=\"openNativeDatePicker()\"\n [disabled]=\"disabled || isDisabled\"\n aria-label=\"Abrir seletor de data\"\n tabindex=\"0\"\n >\n <span class=\"i-matcha-calendar color-grey\"></span>\n </button>\n\n <!-- Calend\u00E1rio customizado (usado quando useNativePicker=false) -->\n <matcha-panel\n *ngIf=\"!useNativePicker\"\n [portalToBody]=\"true\"\n [minWidth]=\"260\"\n [maxHeight]=\"380\"\n placement=\"auto\"\n [suppressGlobalClose]=\"suppressPanelGlobalClose\"\n (closed)=\"onCalendarPanelClosed()\"\n >\n <matcha-calendar-picker\n [value]=\"value || null\"\n [min]=\"min\"\n [max]=\"max\"\n (dateChange)=\"onCalendarDateSelected($event)\"\n ></matcha-calendar-picker>\n </matcha-panel>\n</div>\n\n", styles: [".matcha-date-container{position:relative;display:flex;align-items:center;width:100%}.matcha-date-input{width:100%}.matcha-date-native-input{position:absolute;right:0;bottom:0;opacity:0;pointer-events:none;width:0;height:0;border:none;padding:0;margin:0}.matcha-date-picker-button{position:absolute;right:8px;background:none;border:none;cursor:pointer;padding:4px;display:flex;align-items:center;justify-content:center;color:var(--matcha-color-primary, #333);z-index:1}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: MatchaPanelComponent, selector: "matcha-panel", inputs: ["placement", "maxHeight", "minWidth", "widthMode", "offset", "triggerElement", "open", "hasOverlay", "ignoreClickOutsideElements", "suppressGlobalClose", "portalToBody"], outputs: ["opened", "closed"] }, { kind: "component", type: MatchaCalendarPickerComponent, selector: "matcha-calendar-picker", inputs: ["value", "min", "max", "monthNames", "monthNamesShort", "weekdayNamesShort"], outputs: ["dateChange"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
9523
10000
|
}
|
|
9524
10001
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MatchaDateComponent, decorators: [{
|
|
9525
10002
|
type: Component,
|
|
@@ -9529,8 +10006,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
9529
10006
|
useExisting: forwardRef(() => MatchaDateComponent),
|
|
9530
10007
|
multi: true
|
|
9531
10008
|
}
|
|
9532
|
-
], template: "<div class=\"matcha-date-container\">\n <input\n #textInput\n type=\"text\"\n class=\"matcha-date-input\"\n [value]=\"displayValue\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled || isDisabled\"\n maxlength=\"10\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onBlur()\"\n (keydown)=\"onKeyDown($event)\"\n />\n\n <!-- Input nativo de data (hidden) para usar o datepicker nativo -->\n <input\n #nativeDateInput\n type=\"date\"\n class=\"matcha-date-native-input\"\n [value]=\"value\"\n [min]=\"min\"\n [max]=\"max\"\n [disabled]=\"disabled || isDisabled\"\n (change)=\"onNativeDateChange($event)\"\n tabindex=\"-1\"\n />\n\n <!-- Bot\u00E3o para abrir
|
|
9533
|
-
}], propDecorators: { placeholder: [{
|
|
10009
|
+
], template: "<div class=\"matcha-date-container\">\n <input\n #textInput\n type=\"text\"\n class=\"matcha-date-input\"\n [value]=\"displayValue\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled || isDisabled\"\n maxlength=\"10\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onBlur()\"\n (keydown)=\"onKeyDown($event)\"\n />\n\n <!-- Input nativo de data (hidden) para usar o datepicker nativo -->\n <input\n #nativeDateInput\n type=\"date\"\n class=\"matcha-date-native-input\"\n [value]=\"value\"\n [min]=\"min\"\n [max]=\"max\"\n [disabled]=\"disabled || isDisabled\"\n (change)=\"onNativeDateChange($event)\"\n tabindex=\"-1\"\n />\n\n <!-- Bot\u00E3o para abrir o seletor (nativo ou matcha-calendar-picker) -->\n <button\n *ngIf=\"(showNativePicker || !useNativePicker) && !disabled && !isDisabled\"\n type=\"button\"\n class=\"matcha-date-picker-button mr--12\"\n (click)=\"openNativeDatePicker()\"\n [disabled]=\"disabled || isDisabled\"\n aria-label=\"Abrir seletor de data\"\n tabindex=\"0\"\n >\n <span class=\"i-matcha-calendar color-grey\"></span>\n </button>\n\n <!-- Calend\u00E1rio customizado (usado quando useNativePicker=false) -->\n <matcha-panel\n *ngIf=\"!useNativePicker\"\n [portalToBody]=\"true\"\n [minWidth]=\"260\"\n [maxHeight]=\"380\"\n placement=\"auto\"\n [suppressGlobalClose]=\"suppressPanelGlobalClose\"\n (closed)=\"onCalendarPanelClosed()\"\n >\n <matcha-calendar-picker\n [value]=\"value || null\"\n [min]=\"min\"\n [max]=\"max\"\n (dateChange)=\"onCalendarDateSelected($event)\"\n ></matcha-calendar-picker>\n </matcha-panel>\n</div>\n\n", styles: [".matcha-date-container{position:relative;display:flex;align-items:center;width:100%}.matcha-date-input{width:100%}.matcha-date-native-input{position:absolute;right:0;bottom:0;opacity:0;pointer-events:none;width:0;height:0;border:none;padding:0;margin:0}.matcha-date-picker-button{position:absolute;right:8px;background:none;border:none;cursor:pointer;padding:4px;display:flex;align-items:center;justify-content:center;color:var(--matcha-color-primary, #333);z-index:1}\n"] }]
|
|
10010
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }], propDecorators: { placeholder: [{
|
|
9534
10011
|
type: Input
|
|
9535
10012
|
}], min: [{
|
|
9536
10013
|
type: Input
|
|
@@ -9540,20 +10017,69 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
9540
10017
|
type: Input
|
|
9541
10018
|
}], showNativePicker: [{
|
|
9542
10019
|
type: Input
|
|
10020
|
+
}], useNativePicker: [{
|
|
10021
|
+
type: Input
|
|
10022
|
+
}], suppressPanelGlobalClose: [{
|
|
10023
|
+
type: Input
|
|
10024
|
+
}], calendarPanelOpened: [{
|
|
10025
|
+
type: Output
|
|
10026
|
+
}], calendarPanelClosed: [{
|
|
10027
|
+
type: Output
|
|
9543
10028
|
}], textInput: [{
|
|
9544
10029
|
type: ViewChild,
|
|
9545
10030
|
args: ['textInput']
|
|
9546
10031
|
}], nativeDateInput: [{
|
|
9547
10032
|
type: ViewChild,
|
|
9548
10033
|
args: ['nativeDateInput']
|
|
10034
|
+
}], calendarPanel: [{
|
|
10035
|
+
type: ViewChild,
|
|
10036
|
+
args: [MatchaPanelComponent]
|
|
10037
|
+
}], calendarPicker: [{
|
|
10038
|
+
type: ViewChild,
|
|
10039
|
+
args: [MatchaCalendarPickerComponent]
|
|
9549
10040
|
}] } });
|
|
9550
10041
|
|
|
10042
|
+
class MatchaCalendarPickerModule {
|
|
10043
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MatchaCalendarPickerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
10044
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: MatchaCalendarPickerModule, declarations: [MatchaCalendarPickerComponent], imports: [CommonModule,
|
|
10045
|
+
MatchaCardModule,
|
|
10046
|
+
MatchaIconModule,
|
|
10047
|
+
MatchaDividerModule], exports: [MatchaCalendarPickerComponent] }); }
|
|
10048
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MatchaCalendarPickerModule, imports: [CommonModule,
|
|
10049
|
+
MatchaCardModule,
|
|
10050
|
+
MatchaIconModule,
|
|
10051
|
+
MatchaDividerModule] }); }
|
|
10052
|
+
}
|
|
10053
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MatchaCalendarPickerModule, decorators: [{
|
|
10054
|
+
type: NgModule,
|
|
10055
|
+
args: [{
|
|
10056
|
+
declarations: [
|
|
10057
|
+
MatchaCalendarPickerComponent
|
|
10058
|
+
],
|
|
10059
|
+
imports: [
|
|
10060
|
+
CommonModule,
|
|
10061
|
+
MatchaCardModule,
|
|
10062
|
+
MatchaIconModule,
|
|
10063
|
+
MatchaDividerModule
|
|
10064
|
+
],
|
|
10065
|
+
exports: [
|
|
10066
|
+
MatchaCalendarPickerComponent
|
|
10067
|
+
]
|
|
10068
|
+
// MatchaCalendarIntl é providedIn: 'root' — NÃO declarar em providers aqui
|
|
10069
|
+
// (evita instância duplicada em módulos lazy).
|
|
10070
|
+
}]
|
|
10071
|
+
}] });
|
|
10072
|
+
|
|
9551
10073
|
class MatchaDateModule {
|
|
9552
10074
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MatchaDateModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
9553
10075
|
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: MatchaDateModule, declarations: [MatchaDateComponent], imports: [CommonModule,
|
|
9554
|
-
FormsModule
|
|
10076
|
+
FormsModule,
|
|
10077
|
+
MatchaPanelModule,
|
|
10078
|
+
MatchaCalendarPickerModule], exports: [MatchaDateComponent] }); }
|
|
9555
10079
|
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MatchaDateModule, imports: [CommonModule,
|
|
9556
|
-
FormsModule
|
|
10080
|
+
FormsModule,
|
|
10081
|
+
MatchaPanelModule,
|
|
10082
|
+
MatchaCalendarPickerModule] }); }
|
|
9557
10083
|
}
|
|
9558
10084
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MatchaDateModule, decorators: [{
|
|
9559
10085
|
type: NgModule,
|
|
@@ -9563,7 +10089,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
9563
10089
|
],
|
|
9564
10090
|
imports: [
|
|
9565
10091
|
CommonModule,
|
|
9566
|
-
FormsModule
|
|
10092
|
+
FormsModule,
|
|
10093
|
+
MatchaPanelModule,
|
|
10094
|
+
MatchaCalendarPickerModule
|
|
9567
10095
|
],
|
|
9568
10096
|
exports: [
|
|
9569
10097
|
MatchaDateComponent
|
|
@@ -9597,6 +10125,488 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
9597
10125
|
}]
|
|
9598
10126
|
}] });
|
|
9599
10127
|
|
|
10128
|
+
class MatchaPeriodComponent {
|
|
10129
|
+
constructor(elRef, cdr) {
|
|
10130
|
+
this.elRef = elRef;
|
|
10131
|
+
this.cdr = cdr;
|
|
10132
|
+
/** Lista de presets exibidos. Cada preset é auto-contido (ver matcha-period.types). */
|
|
10133
|
+
this.presets = [];
|
|
10134
|
+
/** Habilita a opção "Personalizado" (com Data início / Data fim). */
|
|
10135
|
+
this.allowCustom = true;
|
|
10136
|
+
/** Texto exibido no gatilho quando não há valor. */
|
|
10137
|
+
this.placeholder = 'Selecione o período';
|
|
10138
|
+
/** Rótulo da opção de período personalizado. */
|
|
10139
|
+
this.customLabel = 'Personalizado';
|
|
10140
|
+
/** Formato do intervalo exibido no gatilho. */
|
|
10141
|
+
this.displayFormat = 'dd/MM/yy';
|
|
10142
|
+
this.disabled = false;
|
|
10143
|
+
// Repasse ao matcha-panel
|
|
10144
|
+
this.placement = 'auto';
|
|
10145
|
+
this.maxHeight = 360;
|
|
10146
|
+
this.minWidth = 240;
|
|
10147
|
+
/** Emite sempre que um intervalo é definido (preset selecionado ou "Aplicar" do custom). */
|
|
10148
|
+
this.periodChange = new EventEmitter();
|
|
10149
|
+
this.opened = new EventEmitter();
|
|
10150
|
+
this.closed = new EventEmitter();
|
|
10151
|
+
this.openedChange = new EventEmitter();
|
|
10152
|
+
this.value = null;
|
|
10153
|
+
this.open = false;
|
|
10154
|
+
this.showingCustom = false;
|
|
10155
|
+
/**
|
|
10156
|
+
* Overlays dos calendários (matcha-date aninhados no modo personalizado).
|
|
10157
|
+
* Repassados ao painel via `ignoreClickOutsideElements` para que clicar
|
|
10158
|
+
* dentro de um calendário não feche o painel do período.
|
|
10159
|
+
*/
|
|
10160
|
+
this.calendarOverlays = [];
|
|
10161
|
+
// Modo personalizado: formulário consumido por matcha-date-range + matcha-date.
|
|
10162
|
+
// Cada matcha-date escreve 'YYYY-MM-DD' (ou null quando incompleto/ inválido).
|
|
10163
|
+
this.customForm = new FormGroup({
|
|
10164
|
+
start: new FormControl(null),
|
|
10165
|
+
end: new FormControl(null)
|
|
10166
|
+
});
|
|
10167
|
+
this.customError = '';
|
|
10168
|
+
// Navegação por teclado (índice na lista lógica: presets + opção custom)
|
|
10169
|
+
this.activeIndex = -1;
|
|
10170
|
+
this.onChange = () => { };
|
|
10171
|
+
this.onTouched = () => { };
|
|
10172
|
+
this.isDisabledByForm = false;
|
|
10173
|
+
// Limpa o erro de validação assim que o usuário edita os campos de data.
|
|
10174
|
+
this.customForm.valueChanges.subscribe(() => {
|
|
10175
|
+
if (this.customError) {
|
|
10176
|
+
this.customError = '';
|
|
10177
|
+
}
|
|
10178
|
+
});
|
|
10179
|
+
}
|
|
10180
|
+
get isCurrentlyDisabled() {
|
|
10181
|
+
return this.disabled || this.isDisabledByForm;
|
|
10182
|
+
}
|
|
10183
|
+
get hostDisabledClass() {
|
|
10184
|
+
return this.isCurrentlyDisabled;
|
|
10185
|
+
}
|
|
10186
|
+
get hostDisabledAttr() {
|
|
10187
|
+
return this.isCurrentlyDisabled ? '' : null;
|
|
10188
|
+
}
|
|
10189
|
+
/** Quantidade total de itens navegáveis (presets + custom, se habilitado). */
|
|
10190
|
+
get navCount() {
|
|
10191
|
+
return this.presets.length + (this.allowCustom ? 1 : 0);
|
|
10192
|
+
}
|
|
10193
|
+
ngAfterViewInit() {
|
|
10194
|
+
const formField = this.elRef.nativeElement.closest('matcha-form-field');
|
|
10195
|
+
const anchor = formField || this.elRef.nativeElement;
|
|
10196
|
+
if (this.panel) {
|
|
10197
|
+
this.panel.attachTo(anchor);
|
|
10198
|
+
}
|
|
10199
|
+
this.triggerElement = this.elRef.nativeElement.querySelector('.matcha-period-trigger') || undefined;
|
|
10200
|
+
this.cdr.detectChanges();
|
|
10201
|
+
}
|
|
10202
|
+
// ---------------------------------------------------------------------------
|
|
10203
|
+
// Exibição
|
|
10204
|
+
// ---------------------------------------------------------------------------
|
|
10205
|
+
/** Rótulo exibido no gatilho: intervalo formatado ou placeholder. */
|
|
10206
|
+
get triggerLabel() {
|
|
10207
|
+
if (!this.value) {
|
|
10208
|
+
return this.placeholder;
|
|
10209
|
+
}
|
|
10210
|
+
return `${this.formatDate(this.value.start)} - ${this.formatDate(this.value.end)}`;
|
|
10211
|
+
}
|
|
10212
|
+
get hasValue() {
|
|
10213
|
+
return this.value !== null;
|
|
10214
|
+
}
|
|
10215
|
+
isPresetSelected(preset) {
|
|
10216
|
+
return !!this.value && this.value.presetKey === preset.key;
|
|
10217
|
+
}
|
|
10218
|
+
get isCustomSelected() {
|
|
10219
|
+
return !!this.value && this.value.presetKey === null;
|
|
10220
|
+
}
|
|
10221
|
+
// Limites recíprocos do modo personalizado (formato 'YYYY-MM-DD' esperado pelo matcha-date):
|
|
10222
|
+
// a data de início não pode passar da data de fim, e a de fim não pode ser anterior à de início.
|
|
10223
|
+
// Desabilita as datas inválidas diretamente no seletor nativo via min/max.
|
|
10224
|
+
get customStartMax() {
|
|
10225
|
+
return this.customForm.value.end ?? '';
|
|
10226
|
+
}
|
|
10227
|
+
get customEndMin() {
|
|
10228
|
+
return this.customForm.value.start ?? '';
|
|
10229
|
+
}
|
|
10230
|
+
formatDate(date) {
|
|
10231
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
10232
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
10233
|
+
const year = date.getFullYear();
|
|
10234
|
+
return this.displayFormat === 'dd/MM/yyyy'
|
|
10235
|
+
? `${day}/${month}/${year}`
|
|
10236
|
+
: `${day}/${month}/${String(year).slice(-2)}`;
|
|
10237
|
+
}
|
|
10238
|
+
// ---------------------------------------------------------------------------
|
|
10239
|
+
// Abertura / fechamento do painel
|
|
10240
|
+
// ---------------------------------------------------------------------------
|
|
10241
|
+
onTriggerClick() {
|
|
10242
|
+
if (this.isCurrentlyDisabled) {
|
|
10243
|
+
return;
|
|
10244
|
+
}
|
|
10245
|
+
this.open ? this.closePanel() : this.openPanel();
|
|
10246
|
+
}
|
|
10247
|
+
openPanel() {
|
|
10248
|
+
if (this.isCurrentlyDisabled) {
|
|
10249
|
+
return;
|
|
10250
|
+
}
|
|
10251
|
+
const formField = this.elRef.nativeElement.closest('matcha-form-field');
|
|
10252
|
+
const anchor = formField || this.elRef.nativeElement;
|
|
10253
|
+
this.open = true;
|
|
10254
|
+
this.calendarOverlays = [];
|
|
10255
|
+
// Reabre já no modo personalizado se o valor atual for custom
|
|
10256
|
+
this.showingCustom = this.isCustomSelected;
|
|
10257
|
+
if (this.showingCustom) {
|
|
10258
|
+
this.syncCustomInputsFromValue();
|
|
10259
|
+
}
|
|
10260
|
+
this.activeIndex = -1;
|
|
10261
|
+
this.cdr.detectChanges();
|
|
10262
|
+
this.panel.attachTo(anchor);
|
|
10263
|
+
this.panel.openPanel();
|
|
10264
|
+
if (this.showingCustom) {
|
|
10265
|
+
this.scrollCustomIntoView();
|
|
10266
|
+
}
|
|
10267
|
+
this.opened.emit();
|
|
10268
|
+
this.openedChange.emit(true);
|
|
10269
|
+
}
|
|
10270
|
+
closePanel() {
|
|
10271
|
+
if (!this.open) {
|
|
10272
|
+
return;
|
|
10273
|
+
}
|
|
10274
|
+
this.open = false;
|
|
10275
|
+
this.activeIndex = -1;
|
|
10276
|
+
this.calendarOverlays = [];
|
|
10277
|
+
this.panel.closePanel();
|
|
10278
|
+
this.closed.emit();
|
|
10279
|
+
this.openedChange.emit(false);
|
|
10280
|
+
this.onTouched();
|
|
10281
|
+
this.cdr.detectChanges();
|
|
10282
|
+
}
|
|
10283
|
+
// ---------------------------------------------------------------------------
|
|
10284
|
+
// Seleção
|
|
10285
|
+
// ---------------------------------------------------------------------------
|
|
10286
|
+
selectPreset(preset) {
|
|
10287
|
+
const range = preset.getRange();
|
|
10288
|
+
this.commitValue({ start: range.start, end: range.end, presetKey: preset.key });
|
|
10289
|
+
this.showingCustom = false;
|
|
10290
|
+
this.customError = '';
|
|
10291
|
+
this.closePanel();
|
|
10292
|
+
}
|
|
10293
|
+
/**
|
|
10294
|
+
* Registra o overlay de um calendário aninhado (ao abrir) para ignorá-lo no
|
|
10295
|
+
* click-outside do painel do período.
|
|
10296
|
+
*
|
|
10297
|
+
* NÃO removemos o overlay quando o calendário fecha: selecionar uma data fecha
|
|
10298
|
+
* o calendário no MESMO clique que ainda propaga até o listener de click-outside
|
|
10299
|
+
* do período. Como o `composedPath()` desse clique ainda contém o pane (mesmo já
|
|
10300
|
+
* destruído), mantê-lo na lista evita que o período feche junto. Panes destruídos
|
|
10301
|
+
* são inofensivos (nunca casam com cliques futuros) e a lista é zerada ao abrir/
|
|
10302
|
+
* fechar o período.
|
|
10303
|
+
*/
|
|
10304
|
+
registerCalendarOverlay(el) {
|
|
10305
|
+
if (el && !this.calendarOverlays.includes(el)) {
|
|
10306
|
+
this.calendarOverlays = [...this.calendarOverlays, el];
|
|
10307
|
+
this.cdr.detectChanges();
|
|
10308
|
+
}
|
|
10309
|
+
}
|
|
10310
|
+
/** Abre/realça a área de período personalizado, mantendo o painel aberto. */
|
|
10311
|
+
toggleCustom() {
|
|
10312
|
+
this.showingCustom = true;
|
|
10313
|
+
this.customError = '';
|
|
10314
|
+
this.syncCustomInputsFromValue();
|
|
10315
|
+
this.cdr.detectChanges();
|
|
10316
|
+
this.scrollCustomIntoView();
|
|
10317
|
+
}
|
|
10318
|
+
/**
|
|
10319
|
+
* Rola o editor personalizado para dentro da área visível do painel.
|
|
10320
|
+
*
|
|
10321
|
+
* O painel tem scroll interno limitado por `maxHeight`; ao expandir o editor
|
|
10322
|
+
* (que é inserido no fim da lista) o conteúdo novo pode ficar abaixo da dobra.
|
|
10323
|
+
* Sem isso, o usuário precisaria rolar manualmente para ver os campos de data.
|
|
10324
|
+
*
|
|
10325
|
+
* `block: 'nearest'` garante o mínimo de rolagem necessária e evita mexer no
|
|
10326
|
+
* scroll da página. Adiado por rAF para rodar após a renderização do *ngIf e
|
|
10327
|
+
* o reposicionamento do painel (ResizeObserver).
|
|
10328
|
+
*/
|
|
10329
|
+
scrollCustomIntoView() {
|
|
10330
|
+
if (typeof requestAnimationFrame === 'undefined') {
|
|
10331
|
+
return;
|
|
10332
|
+
}
|
|
10333
|
+
requestAnimationFrame(() => {
|
|
10334
|
+
this.customEditorRef?.nativeElement.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
|
10335
|
+
});
|
|
10336
|
+
}
|
|
10337
|
+
applyCustom() {
|
|
10338
|
+
const start = this.parseDate(this.customForm.value.start ?? null);
|
|
10339
|
+
const end = this.parseDate(this.customForm.value.end ?? null);
|
|
10340
|
+
if (!start || !end) {
|
|
10341
|
+
this.customError = 'Informe datas válidas no formato DD/MM/AAAA.';
|
|
10342
|
+
this.cdr.detectChanges();
|
|
10343
|
+
return;
|
|
10344
|
+
}
|
|
10345
|
+
if (start.getTime() > end.getTime()) {
|
|
10346
|
+
this.customError = 'A data de início não pode ser posterior à data de fim.';
|
|
10347
|
+
this.cdr.detectChanges();
|
|
10348
|
+
return;
|
|
10349
|
+
}
|
|
10350
|
+
this.customError = '';
|
|
10351
|
+
this.commitValue({ start, end, presetKey: null });
|
|
10352
|
+
this.closePanel();
|
|
10353
|
+
}
|
|
10354
|
+
commitValue(value) {
|
|
10355
|
+
this.value = value;
|
|
10356
|
+
// Atualiza o FormControl ANTES de emitir o evento: consumidores que leem o
|
|
10357
|
+
// valor atual do formulário dentro do handler de `periodChange` precisam já
|
|
10358
|
+
// enxergar o novo valor. Emitir antes do `onChange` faria o handler ler o
|
|
10359
|
+
// valor anterior.
|
|
10360
|
+
this.onChange(value);
|
|
10361
|
+
this.onTouched();
|
|
10362
|
+
this.periodChange.emit(value);
|
|
10363
|
+
this.cdr.detectChanges();
|
|
10364
|
+
}
|
|
10365
|
+
// ---------------------------------------------------------------------------
|
|
10366
|
+
// Campos do modo personalizado (delegados a matcha-date-range + matcha-date)
|
|
10367
|
+
// ---------------------------------------------------------------------------
|
|
10368
|
+
/** Converte uma string 'YYYY-MM-DD' válida em Date; retorna null caso contrário. */
|
|
10369
|
+
parseDate(value) {
|
|
10370
|
+
if (!value || !/^\d{4}-\d{2}-\d{2}$/.test(value)) {
|
|
10371
|
+
return null;
|
|
10372
|
+
}
|
|
10373
|
+
const [year, month, day] = value.split('-').map(Number);
|
|
10374
|
+
const date = new Date(year, month - 1, day);
|
|
10375
|
+
// Garante que a data existe (rejeita 31/02, etc.)
|
|
10376
|
+
if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
|
|
10377
|
+
return null;
|
|
10378
|
+
}
|
|
10379
|
+
return date;
|
|
10380
|
+
}
|
|
10381
|
+
syncCustomInputsFromValue() {
|
|
10382
|
+
if (this.value) {
|
|
10383
|
+
this.customForm.setValue({
|
|
10384
|
+
start: this.toInputValue(this.value.start),
|
|
10385
|
+
end: this.toInputValue(this.value.end)
|
|
10386
|
+
}, { emitEvent: false });
|
|
10387
|
+
}
|
|
10388
|
+
}
|
|
10389
|
+
/** Formata um Date para o formato consumido pelo matcha-date ('YYYY-MM-DD'). */
|
|
10390
|
+
toInputValue(date) {
|
|
10391
|
+
const year = date.getFullYear();
|
|
10392
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
10393
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
10394
|
+
return `${year}-${month}-${day}`;
|
|
10395
|
+
}
|
|
10396
|
+
// ---------------------------------------------------------------------------
|
|
10397
|
+
// Navegação por teclado
|
|
10398
|
+
// ---------------------------------------------------------------------------
|
|
10399
|
+
onTriggerKeyDown(event) {
|
|
10400
|
+
if (this.isCurrentlyDisabled) {
|
|
10401
|
+
return;
|
|
10402
|
+
}
|
|
10403
|
+
switch (event.key) {
|
|
10404
|
+
case 'ArrowDown':
|
|
10405
|
+
event.preventDefault();
|
|
10406
|
+
if (!this.open) {
|
|
10407
|
+
this.openPanel();
|
|
10408
|
+
}
|
|
10409
|
+
else {
|
|
10410
|
+
this.moveActive(1);
|
|
10411
|
+
}
|
|
10412
|
+
break;
|
|
10413
|
+
case 'ArrowUp':
|
|
10414
|
+
event.preventDefault();
|
|
10415
|
+
if (this.open) {
|
|
10416
|
+
this.moveActive(-1);
|
|
10417
|
+
}
|
|
10418
|
+
break;
|
|
10419
|
+
case 'Enter':
|
|
10420
|
+
case ' ':
|
|
10421
|
+
event.preventDefault();
|
|
10422
|
+
if (!this.open) {
|
|
10423
|
+
this.openPanel();
|
|
10424
|
+
}
|
|
10425
|
+
else {
|
|
10426
|
+
this.activateCurrent();
|
|
10427
|
+
}
|
|
10428
|
+
break;
|
|
10429
|
+
case 'Escape':
|
|
10430
|
+
if (this.open) {
|
|
10431
|
+
event.preventDefault();
|
|
10432
|
+
this.closePanel();
|
|
10433
|
+
}
|
|
10434
|
+
break;
|
|
10435
|
+
default:
|
|
10436
|
+
break;
|
|
10437
|
+
}
|
|
10438
|
+
}
|
|
10439
|
+
moveActive(delta) {
|
|
10440
|
+
const count = this.navCount;
|
|
10441
|
+
if (count === 0) {
|
|
10442
|
+
return;
|
|
10443
|
+
}
|
|
10444
|
+
if (this.activeIndex < 0) {
|
|
10445
|
+
this.activeIndex = delta > 0 ? 0 : count - 1;
|
|
10446
|
+
}
|
|
10447
|
+
else {
|
|
10448
|
+
this.activeIndex = (this.activeIndex + delta + count) % count;
|
|
10449
|
+
}
|
|
10450
|
+
this.cdr.detectChanges();
|
|
10451
|
+
}
|
|
10452
|
+
isActiveIndex(index) {
|
|
10453
|
+
return this.activeIndex === index;
|
|
10454
|
+
}
|
|
10455
|
+
get isCustomActive() {
|
|
10456
|
+
return this.allowCustom && this.activeIndex === this.presets.length;
|
|
10457
|
+
}
|
|
10458
|
+
activateCurrent() {
|
|
10459
|
+
if (this.activeIndex < 0) {
|
|
10460
|
+
return;
|
|
10461
|
+
}
|
|
10462
|
+
if (this.activeIndex < this.presets.length) {
|
|
10463
|
+
this.selectPreset(this.presets[this.activeIndex]);
|
|
10464
|
+
}
|
|
10465
|
+
else if (this.allowCustom) {
|
|
10466
|
+
this.toggleCustom();
|
|
10467
|
+
}
|
|
10468
|
+
}
|
|
10469
|
+
// ---------------------------------------------------------------------------
|
|
10470
|
+
// ControlValueAccessor
|
|
10471
|
+
// ---------------------------------------------------------------------------
|
|
10472
|
+
writeValue(value) {
|
|
10473
|
+
this.value = this.normalizeValue(value);
|
|
10474
|
+
this.showingCustom = this.isCustomSelected;
|
|
10475
|
+
if (this.showingCustom) {
|
|
10476
|
+
this.syncCustomInputsFromValue();
|
|
10477
|
+
}
|
|
10478
|
+
this.cdr.detectChanges();
|
|
10479
|
+
}
|
|
10480
|
+
registerOnChange(fn) {
|
|
10481
|
+
this.onChange = fn;
|
|
10482
|
+
}
|
|
10483
|
+
registerOnTouched(fn) {
|
|
10484
|
+
this.onTouched = fn;
|
|
10485
|
+
}
|
|
10486
|
+
setDisabledState(isDisabled) {
|
|
10487
|
+
this.isDisabledByForm = isDisabled;
|
|
10488
|
+
if (isDisabled && this.open) {
|
|
10489
|
+
this.closePanel();
|
|
10490
|
+
}
|
|
10491
|
+
this.cdr.detectChanges();
|
|
10492
|
+
}
|
|
10493
|
+
/** Garante que start/end sejam Date (aceita strings/ISO vindas do FormControl). */
|
|
10494
|
+
normalizeValue(value) {
|
|
10495
|
+
if (!value || value.start == null || value.end == null) {
|
|
10496
|
+
return null;
|
|
10497
|
+
}
|
|
10498
|
+
const start = value.start instanceof Date ? value.start : new Date(value.start);
|
|
10499
|
+
const end = value.end instanceof Date ? value.end : new Date(value.end);
|
|
10500
|
+
if (isNaN(start.getTime()) || isNaN(end.getTime())) {
|
|
10501
|
+
return null;
|
|
10502
|
+
}
|
|
10503
|
+
return { start, end, presetKey: value.presetKey ?? null };
|
|
10504
|
+
}
|
|
10505
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MatchaPeriodComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
10506
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: MatchaPeriodComponent, isStandalone: false, selector: "matcha-period", inputs: { presets: "presets", allowCustom: "allowCustom", placeholder: "placeholder", customLabel: "customLabel", displayFormat: "displayFormat", disabled: "disabled", placement: "placement", maxHeight: "maxHeight", minWidth: "minWidth" }, outputs: { periodChange: "periodChange", opened: "opened", closed: "closed", openedChange: "openedChange" }, host: { properties: { "class.matcha-period-disabled": "this.hostDisabledClass", "attr.disabled": "this.hostDisabledAttr" } }, providers: [
|
|
10507
|
+
{
|
|
10508
|
+
provide: NG_VALUE_ACCESSOR,
|
|
10509
|
+
useExisting: forwardRef(() => MatchaPeriodComponent),
|
|
10510
|
+
multi: true
|
|
10511
|
+
}
|
|
10512
|
+
], viewQueries: [{ propertyName: "panel", first: true, predicate: MatchaPanelComponent, descendants: true }, { propertyName: "customEditorRef", first: true, predicate: ["customEditor"], descendants: true }], ngImport: i0, template: "<div class=\"position-relative d-inline-block w-100-p\">\n <div class=\"matcha-period-trigger d-flex flex-align-center flex-space-between cursor-pointer\"\n [class.matcha-period-disabled]=\"isCurrentlyDisabled\" (click)=\"onTriggerClick()\"\n (keydown)=\"onTriggerKeyDown($event)\" [attr.tabindex]=\"isCurrentlyDisabled ? -1 : 0\" role=\"combobox\"\n [attr.aria-expanded]=\"open\" [attr.aria-haspopup]=\"true\" [attr.aria-disabled]=\"isCurrentlyDisabled\">\n\n <span class=\"matcha-period-value\" [class.matcha-period-placeholder]=\"!hasValue\">\n {{ triggerLabel }}\n </span>\n\n <span class=\"matcha-period-arrow\" [class.matcha-period-arrow-open]=\"open\">\n <span class=\"i-matcha-action_arrow_down\"></span>\n </span>\n </div>\n\n <matcha-panel #panel [placement]=\"placement\" [maxHeight]=\"maxHeight\" [minWidth]=\"minWidth\" [open]=\"open\"\n [portalToBody]=\"true\" [ignoreClickOutsideElements]=\"calendarOverlays\" (closed)=\"closePanel()\">\n\n <div class=\"py-4\" role=\"listbox\">\n <!-- Lista de presets -->\n <div *ngFor=\"let preset of presets; let i = index\" class=\"matcha-period-option\" role=\"option\"\n [class.matcha-period-option-selected]=\"isPresetSelected(preset)\"\n [class.matcha-period-option-active]=\"isActiveIndex(i)\" [attr.aria-selected]=\"isPresetSelected(preset)\"\n (click)=\"selectPreset(preset)\">\n {{ preset.label }}\n </div>\n\n <!-- Op\u00E7\u00E3o \"Personalizado\" -->\n <ng-container *ngIf=\"allowCustom\">\n <matcha-divider gap=\"8\"></matcha-divider>\n\n <div class=\"matcha-period-option\" role=\"option\"\n [class.matcha-period-option-selected]=\"isCustomSelected || showingCustom\"\n [class.matcha-period-option-active]=\"isCustomActive\" [attr.aria-selected]=\"isCustomSelected\"\n (click)=\"toggleCustom()\">\n {{ customLabel }}\n </div>\n\n <!-- Editor de per\u00EDodo personalizado (reaproveita matcha-date-range + matcha-date) -->\n <div #customEditor class=\"pt-8 px-16 pb-12\" *ngIf=\"showingCustom\" [formGroup]=\"customForm\">\n <matcha-date-range>\n <matcha-form-field>\n <matcha-label>Data in\u00EDcio</matcha-label>\n <matcha-date formControlName=\"start\" placeholder=\"__/__/____\" [useNativePicker]=\"false\"\n [max]=\"customStartMax\" [suppressPanelGlobalClose]=\"true\"\n (calendarPanelOpened)=\"registerCalendarOverlay($event)\"></matcha-date>\n </matcha-form-field>\n <matcha-form-field>\n <matcha-label>Data fim</matcha-label>\n <matcha-date formControlName=\"end\" placeholder=\"__/__/____\" [useNativePicker]=\"false\"\n [min]=\"customEndMin\" [suppressPanelGlobalClose]=\"true\"\n (calendarPanelOpened)=\"registerCalendarOverlay($event)\"></matcha-date>\n </matcha-form-field>\n </matcha-date-range>\n\n <div class=\"color-red fs-12 mt-8\" *ngIf=\"customError\">{{ customError }}</div>\n\n <button matcha-button color=\"accent\" size=\"small\" type=\"button\" class=\"w-100-p mt-12\"\n (click)=\"applyCustom()\">\n Aplicar\n </button>\n </div>\n </ng-container>\n </div>\n </matcha-panel>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: MatchaPanelComponent, selector: "matcha-panel", inputs: ["placement", "maxHeight", "minWidth", "widthMode", "offset", "triggerElement", "open", "hasOverlay", "ignoreClickOutsideElements", "suppressGlobalClose", "portalToBody"], outputs: ["opened", "closed"] }, { kind: "component", type: MatchaButtonComponent, selector: "[matcha-button]", inputs: ["size", "size-xs", "size-sm", "size-md", "size-lg", "size-xl", "gap", "color", "basic", "outline", "alpha", "pill", "link", "icon", "badge"] }, { kind: "component", type: MatchaDividerComponent, selector: "matcha-divider", inputs: ["gap", "gap-sm", "gap-md", "gap-lg", "gap-xl", "direction"] }, { kind: "component", type: MatchaDateComponent, selector: "matcha-date", inputs: ["placeholder", "min", "max", "disabled", "showNativePicker", "useNativePicker", "suppressPanelGlobalClose"], outputs: ["calendarPanelOpened", "calendarPanelClosed"] }, { kind: "component", type: MatchaDateRangeComponent, selector: "matcha-date-range" }, { kind: "component", type: MatchaFormFieldComponent, selector: "matcha-form-field", inputs: ["color", "size", "size-xs", "size-sm", "size-md", "size-lg", "size-xl"] }, { kind: "component", type: MatchaLabelComponent, selector: "matcha-label", inputs: ["color"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
10513
|
+
}
|
|
10514
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MatchaPeriodComponent, decorators: [{
|
|
10515
|
+
type: Component,
|
|
10516
|
+
args: [{ selector: 'matcha-period', encapsulation: ViewEncapsulation.None, standalone: false, providers: [
|
|
10517
|
+
{
|
|
10518
|
+
provide: NG_VALUE_ACCESSOR,
|
|
10519
|
+
useExisting: forwardRef(() => MatchaPeriodComponent),
|
|
10520
|
+
multi: true
|
|
10521
|
+
}
|
|
10522
|
+
], template: "<div class=\"position-relative d-inline-block w-100-p\">\n <div class=\"matcha-period-trigger d-flex flex-align-center flex-space-between cursor-pointer\"\n [class.matcha-period-disabled]=\"isCurrentlyDisabled\" (click)=\"onTriggerClick()\"\n (keydown)=\"onTriggerKeyDown($event)\" [attr.tabindex]=\"isCurrentlyDisabled ? -1 : 0\" role=\"combobox\"\n [attr.aria-expanded]=\"open\" [attr.aria-haspopup]=\"true\" [attr.aria-disabled]=\"isCurrentlyDisabled\">\n\n <span class=\"matcha-period-value\" [class.matcha-period-placeholder]=\"!hasValue\">\n {{ triggerLabel }}\n </span>\n\n <span class=\"matcha-period-arrow\" [class.matcha-period-arrow-open]=\"open\">\n <span class=\"i-matcha-action_arrow_down\"></span>\n </span>\n </div>\n\n <matcha-panel #panel [placement]=\"placement\" [maxHeight]=\"maxHeight\" [minWidth]=\"minWidth\" [open]=\"open\"\n [portalToBody]=\"true\" [ignoreClickOutsideElements]=\"calendarOverlays\" (closed)=\"closePanel()\">\n\n <div class=\"py-4\" role=\"listbox\">\n <!-- Lista de presets -->\n <div *ngFor=\"let preset of presets; let i = index\" class=\"matcha-period-option\" role=\"option\"\n [class.matcha-period-option-selected]=\"isPresetSelected(preset)\"\n [class.matcha-period-option-active]=\"isActiveIndex(i)\" [attr.aria-selected]=\"isPresetSelected(preset)\"\n (click)=\"selectPreset(preset)\">\n {{ preset.label }}\n </div>\n\n <!-- Op\u00E7\u00E3o \"Personalizado\" -->\n <ng-container *ngIf=\"allowCustom\">\n <matcha-divider gap=\"8\"></matcha-divider>\n\n <div class=\"matcha-period-option\" role=\"option\"\n [class.matcha-period-option-selected]=\"isCustomSelected || showingCustom\"\n [class.matcha-period-option-active]=\"isCustomActive\" [attr.aria-selected]=\"isCustomSelected\"\n (click)=\"toggleCustom()\">\n {{ customLabel }}\n </div>\n\n <!-- Editor de per\u00EDodo personalizado (reaproveita matcha-date-range + matcha-date) -->\n <div #customEditor class=\"pt-8 px-16 pb-12\" *ngIf=\"showingCustom\" [formGroup]=\"customForm\">\n <matcha-date-range>\n <matcha-form-field>\n <matcha-label>Data in\u00EDcio</matcha-label>\n <matcha-date formControlName=\"start\" placeholder=\"__/__/____\" [useNativePicker]=\"false\"\n [max]=\"customStartMax\" [suppressPanelGlobalClose]=\"true\"\n (calendarPanelOpened)=\"registerCalendarOverlay($event)\"></matcha-date>\n </matcha-form-field>\n <matcha-form-field>\n <matcha-label>Data fim</matcha-label>\n <matcha-date formControlName=\"end\" placeholder=\"__/__/____\" [useNativePicker]=\"false\"\n [min]=\"customEndMin\" [suppressPanelGlobalClose]=\"true\"\n (calendarPanelOpened)=\"registerCalendarOverlay($event)\"></matcha-date>\n </matcha-form-field>\n </matcha-date-range>\n\n <div class=\"color-red fs-12 mt-8\" *ngIf=\"customError\">{{ customError }}</div>\n\n <button matcha-button color=\"accent\" size=\"small\" type=\"button\" class=\"w-100-p mt-12\"\n (click)=\"applyCustom()\">\n Aplicar\n </button>\n </div>\n </ng-container>\n </div>\n </matcha-panel>\n</div>\n" }]
|
|
10523
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }], propDecorators: { panel: [{
|
|
10524
|
+
type: ViewChild,
|
|
10525
|
+
args: [MatchaPanelComponent]
|
|
10526
|
+
}], customEditorRef: [{
|
|
10527
|
+
type: ViewChild,
|
|
10528
|
+
args: ['customEditor']
|
|
10529
|
+
}], presets: [{
|
|
10530
|
+
type: Input
|
|
10531
|
+
}], allowCustom: [{
|
|
10532
|
+
type: Input
|
|
10533
|
+
}], placeholder: [{
|
|
10534
|
+
type: Input
|
|
10535
|
+
}], customLabel: [{
|
|
10536
|
+
type: Input
|
|
10537
|
+
}], displayFormat: [{
|
|
10538
|
+
type: Input
|
|
10539
|
+
}], disabled: [{
|
|
10540
|
+
type: Input
|
|
10541
|
+
}], placement: [{
|
|
10542
|
+
type: Input
|
|
10543
|
+
}], maxHeight: [{
|
|
10544
|
+
type: Input
|
|
10545
|
+
}], minWidth: [{
|
|
10546
|
+
type: Input
|
|
10547
|
+
}], periodChange: [{
|
|
10548
|
+
type: Output
|
|
10549
|
+
}], opened: [{
|
|
10550
|
+
type: Output
|
|
10551
|
+
}], closed: [{
|
|
10552
|
+
type: Output
|
|
10553
|
+
}], openedChange: [{
|
|
10554
|
+
type: Output
|
|
10555
|
+
}], hostDisabledClass: [{
|
|
10556
|
+
type: HostBinding,
|
|
10557
|
+
args: ['class.matcha-period-disabled']
|
|
10558
|
+
}], hostDisabledAttr: [{
|
|
10559
|
+
type: HostBinding,
|
|
10560
|
+
args: ['attr.disabled']
|
|
10561
|
+
}] } });
|
|
10562
|
+
|
|
10563
|
+
class MatchaPeriodModule {
|
|
10564
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MatchaPeriodModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
10565
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: MatchaPeriodModule, declarations: [MatchaPeriodComponent], imports: [CommonModule,
|
|
10566
|
+
FormsModule,
|
|
10567
|
+
ReactiveFormsModule,
|
|
10568
|
+
MatchaPanelModule,
|
|
10569
|
+
MatchaButtonModule,
|
|
10570
|
+
MatchaIconModule,
|
|
10571
|
+
MatchaDividerModule,
|
|
10572
|
+
MatchaDateModule,
|
|
10573
|
+
MatchaDateRangeModule,
|
|
10574
|
+
MatchaFormFieldModule], exports: [MatchaPeriodComponent] }); }
|
|
10575
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MatchaPeriodModule, imports: [CommonModule,
|
|
10576
|
+
FormsModule,
|
|
10577
|
+
ReactiveFormsModule,
|
|
10578
|
+
MatchaPanelModule,
|
|
10579
|
+
MatchaButtonModule,
|
|
10580
|
+
MatchaIconModule,
|
|
10581
|
+
MatchaDividerModule,
|
|
10582
|
+
MatchaDateModule,
|
|
10583
|
+
MatchaDateRangeModule,
|
|
10584
|
+
MatchaFormFieldModule] }); }
|
|
10585
|
+
}
|
|
10586
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MatchaPeriodModule, decorators: [{
|
|
10587
|
+
type: NgModule,
|
|
10588
|
+
args: [{
|
|
10589
|
+
declarations: [
|
|
10590
|
+
MatchaPeriodComponent
|
|
10591
|
+
],
|
|
10592
|
+
imports: [
|
|
10593
|
+
CommonModule,
|
|
10594
|
+
FormsModule,
|
|
10595
|
+
ReactiveFormsModule,
|
|
10596
|
+
MatchaPanelModule,
|
|
10597
|
+
MatchaButtonModule,
|
|
10598
|
+
MatchaIconModule,
|
|
10599
|
+
MatchaDividerModule,
|
|
10600
|
+
MatchaDateModule,
|
|
10601
|
+
MatchaDateRangeModule,
|
|
10602
|
+
MatchaFormFieldModule
|
|
10603
|
+
],
|
|
10604
|
+
exports: [
|
|
10605
|
+
MatchaPeriodComponent
|
|
10606
|
+
]
|
|
10607
|
+
}]
|
|
10608
|
+
}] });
|
|
10609
|
+
|
|
9600
10610
|
class MatchaTimeComponent {
|
|
9601
10611
|
constructor() {
|
|
9602
10612
|
this.placeholder = '__:__';
|
|
@@ -14396,9 +15406,12 @@ class MatchaSliderComponent {
|
|
|
14396
15406
|
this.isDragging = false;
|
|
14397
15407
|
this.draggingPointer = null;
|
|
14398
15408
|
this.removeVisualFeedback();
|
|
14399
|
-
|
|
15409
|
+
// Atualiza o FormControl ANTES de emitir o evento de interação:
|
|
15410
|
+
// consumidores que leem o valor atual do formulário no handler de
|
|
15411
|
+
// `userChangeEnd` precisam já enxergar o novo valor.
|
|
14400
15412
|
this.onChange(this.isRange ? [this.value, this.highValue] : this.value);
|
|
14401
15413
|
this.onTouched();
|
|
15414
|
+
this.userChangeEnd.emit(this.value);
|
|
14402
15415
|
}
|
|
14403
15416
|
this.cleanupEventListeners();
|
|
14404
15417
|
this.cancelAnimationFrame();
|
|
@@ -14480,9 +15493,13 @@ class MatchaSliderComponent {
|
|
|
14480
15493
|
const clampedValue = Math.max(floor, Math.min(ceil, newValue));
|
|
14481
15494
|
if (clampedValue !== this.value) {
|
|
14482
15495
|
this.value = clampedValue;
|
|
15496
|
+
// `valueChange` é o output de two-way binding ([(value)]); permanece antes
|
|
15497
|
+
// do `onChange`, espelhando o comportamento do Angular Material. Já o
|
|
15498
|
+
// `userChange` (evento de interação) é emitido DEPOIS de atualizar o
|
|
15499
|
+
// FormControl, para que o handler leia o novo valor.
|
|
14483
15500
|
this.valueChange.emit(this.value);
|
|
14484
|
-
this.userChange.emit(this.value);
|
|
14485
15501
|
this.onChange(this.value);
|
|
15502
|
+
this.userChange.emit(this.value);
|
|
14486
15503
|
this.cdr.markForCheck();
|
|
14487
15504
|
}
|
|
14488
15505
|
}
|
|
@@ -14516,9 +15533,12 @@ class MatchaSliderComponent {
|
|
|
14516
15533
|
}
|
|
14517
15534
|
if (clampedValue !== this.value) {
|
|
14518
15535
|
this.value = clampedValue;
|
|
15536
|
+
// `valueChange` (two-way binding) permanece antes do `onChange`; o
|
|
15537
|
+
// `userChange` (evento de interação) é emitido depois de atualizar o
|
|
15538
|
+
// FormControl.
|
|
14519
15539
|
this.valueChange.emit(this.value);
|
|
14520
|
-
this.userChange.emit(this.value);
|
|
14521
15540
|
this.onChange([this.value, this.highValue]);
|
|
15541
|
+
this.userChange.emit(this.value);
|
|
14522
15542
|
this.cdr.markForCheck();
|
|
14523
15543
|
}
|
|
14524
15544
|
}
|
|
@@ -14539,9 +15559,12 @@ class MatchaSliderComponent {
|
|
|
14539
15559
|
}
|
|
14540
15560
|
if (clampedValue !== this.highValue) {
|
|
14541
15561
|
this.highValue = clampedValue;
|
|
15562
|
+
// `highValueChange` (two-way binding) permanece antes do `onChange`; o
|
|
15563
|
+
// `userChange` (evento de interação) é emitido depois de atualizar o
|
|
15564
|
+
// FormControl.
|
|
14542
15565
|
this.highValueChange.emit(this.highValue);
|
|
14543
|
-
this.userChange.emit(this.highValue);
|
|
14544
15566
|
this.onChange([this.value, this.highValue]);
|
|
15567
|
+
this.userChange.emit(this.highValue);
|
|
14545
15568
|
this.cdr.markForCheck();
|
|
14546
15569
|
}
|
|
14547
15570
|
}
|
|
@@ -15841,6 +16864,8 @@ class MatchaComponentsModule {
|
|
|
15841
16864
|
MatchaTitleModule,
|
|
15842
16865
|
MatchaTooltipModule,
|
|
15843
16866
|
MatchaDateRangeModule,
|
|
16867
|
+
MatchaPeriodModule,
|
|
16868
|
+
MatchaCalendarPickerModule,
|
|
15844
16869
|
MatchaTimeModule,
|
|
15845
16870
|
MatchaTimeRangeModule,
|
|
15846
16871
|
MatchaDropListModule,
|
|
@@ -15886,6 +16911,8 @@ class MatchaComponentsModule {
|
|
|
15886
16911
|
MatchaTitleModule,
|
|
15887
16912
|
MatchaTooltipModule,
|
|
15888
16913
|
MatchaDateRangeModule,
|
|
16914
|
+
MatchaPeriodModule,
|
|
16915
|
+
MatchaCalendarPickerModule,
|
|
15889
16916
|
MatchaTimeModule,
|
|
15890
16917
|
MatchaTimeRangeModule,
|
|
15891
16918
|
MatchaDropListModule,
|
|
@@ -15936,6 +16963,8 @@ class MatchaComponentsModule {
|
|
|
15936
16963
|
MatchaTitleModule,
|
|
15937
16964
|
MatchaTooltipModule,
|
|
15938
16965
|
MatchaDateRangeModule,
|
|
16966
|
+
MatchaPeriodModule,
|
|
16967
|
+
MatchaCalendarPickerModule,
|
|
15939
16968
|
MatchaTimeModule,
|
|
15940
16969
|
MatchaTimeRangeModule,
|
|
15941
16970
|
MatchaDropListModule,
|
|
@@ -15981,6 +17010,8 @@ class MatchaComponentsModule {
|
|
|
15981
17010
|
MatchaTitleModule,
|
|
15982
17011
|
MatchaTooltipModule,
|
|
15983
17012
|
MatchaDateRangeModule,
|
|
17013
|
+
MatchaPeriodModule,
|
|
17014
|
+
MatchaCalendarPickerModule,
|
|
15984
17015
|
MatchaTimeModule,
|
|
15985
17016
|
MatchaTimeRangeModule,
|
|
15986
17017
|
MatchaDropListModule,
|
|
@@ -16037,6 +17068,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
16037
17068
|
MatchaTitleModule,
|
|
16038
17069
|
MatchaTooltipModule,
|
|
16039
17070
|
MatchaDateRangeModule,
|
|
17071
|
+
MatchaPeriodModule,
|
|
17072
|
+
MatchaCalendarPickerModule,
|
|
16040
17073
|
MatchaTimeModule,
|
|
16041
17074
|
MatchaTimeRangeModule,
|
|
16042
17075
|
MatchaDropListModule,
|
|
@@ -16084,6 +17117,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
16084
17117
|
MatchaTitleModule,
|
|
16085
17118
|
MatchaTooltipModule,
|
|
16086
17119
|
MatchaDateRangeModule,
|
|
17120
|
+
MatchaPeriodModule,
|
|
17121
|
+
MatchaCalendarPickerModule,
|
|
16087
17122
|
MatchaTimeModule,
|
|
16088
17123
|
MatchaTimeRangeModule,
|
|
16089
17124
|
MatchaDropListModule,
|
|
@@ -16131,6 +17166,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
16131
17166
|
}]
|
|
16132
17167
|
}] });
|
|
16133
17168
|
|
|
17169
|
+
/**
|
|
17170
|
+
* Tipagem pública do componente matcha-period (seletor de período / presets).
|
|
17171
|
+
*/
|
|
17172
|
+
|
|
16134
17173
|
class MatchaGridComponent {
|
|
16135
17174
|
getStringSplited(inputValue) {
|
|
16136
17175
|
const stringWithoutSpaces = inputValue.replace(/\s+/g, '');
|
|
@@ -17213,5 +18252,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
17213
18252
|
* Generated bundle index. Do not edit.
|
|
17214
18253
|
*/
|
|
17215
18254
|
|
|
17216
|
-
export { CopyButtonComponent, INITIAL_CONFIG, MATCHA_MASK_CONFIG, MATCHA_OPTION_PARENT, MatchaAccordionComponent, MatchaAccordionContentComponent, MatchaAccordionHeaderComponent, MatchaAccordionItemComponent, MatchaAccordionModule, MatchaAutocompleteComponent, MatchaAutocompleteModule, MatchaAutocompleteTriggerDirective, MatchaAvatarComponent, MatchaAvatarModule, MatchaBreakpointObservableModule, MatchaBreakpointObserver, MatchaButtonComponent, MatchaButtonModule, MatchaButtonToggleComponent, MatchaButtonToggleModule, MatchaCardComponent, MatchaCardModule, MatchaCheckboxComponent, MatchaCheckboxModule, MatchaChipComponent, MatchaChipListComponent, MatchaChipModule, MatchaComponentsModule, MatchaDateComponent, MatchaDateModule, MatchaDateRangeComponent, MatchaDateRangeModule, MatchaDividerComponent, MatchaDividerModule, MatchaDragDirective, MatchaDragHandleDirective, MatchaDrawerComponent, MatchaDrawerContainerComponent, MatchaDrawerContentComponent, MatchaDrawerModule, MatchaDropListComponent, MatchaDropListModule, MatchaDropListService, MatchaDropZoneDirective, MatchaElevationDirective, MatchaElevationModule, MatchaErrorComponent, MatchaFormFieldComponent, MatchaFormFieldModule, MatchaGridComponent, MatchaGridModule, MatchaHighlightComponent, MatchaHighlightModule, MatchaHintTextComponent, MatchaHintTextModule, MatchaIconComponent, MatchaIconModule, MatchaInfiniteScrollComponent, MatchaInfiniteScrollDataComponent, MatchaInfiniteScrollModule, MatchaInputPhoneComponent, MatchaInputPhoneModule, MatchaLabelComponent, MatchaLazyloadComponent, MatchaLazyloadDataComponent, MatchaLazyloadModule, MatchaListComponent, MatchaListItemComponent, MatchaListModule, MatchaMaskApplierService, MatchaMaskCompatibleDirective, MatchaMaskModule, MatchaMaskPipe, MatchaMaskService, MatchaMasonryComponent, MatchaMasonryModule, MatchaMenuComponent, MatchaMenuItemDirective, MatchaMenuModule, MatchaMenuTriggerDirective, MatchaModalComponent, MatchaModalContentComponent, MatchaModalFooterComponent, MatchaModalHeaderComponent, MatchaModalModule, MatchaModalOptionsComponent, MatchaModalService, MatchaMsgBoxActionsComponent, MatchaMsgBoxComponent, MatchaMsgBoxModule, MatchaOptionComponent, MatchaOptionModule, MatchaOverlayService, MatchaPageBuilderComponent, MatchaPageBuilderModule, MatchaPageLayoutComponent, MatchaPageLayoutModule, MatchaPaginatorComponent, MatchaPaginatorIntl, MatchaPaginatorModule, MatchaPanelComponent, MatchaPanelModule, MatchaProgressBarComponent, MatchaProgressBarModule, MatchaRadioComponent, MatchaRadioGroupComponent, MatchaRadioModule, MatchaRippleDirective, MatchaRippleModule, MatchaSelectComponent, MatchaSelectModule, MatchaSelectMultipleComponent, MatchaSelectMultipleModule, MatchaSelectTriggerDirective, MatchaSkeletonComponent, MatchaSkeletonModule, MatchaSlideToggleComponent, MatchaSlideToggleModule, MatchaSliderComponent, MatchaSliderModule, MatchaSnackBarComponent, MatchaSnackBarModule, MatchaSnackBarService, MatchaSpinComponent, MatchaSpinModule, MatchaSpinnerComponent, MatchaSpinnerModule, MatchaStepperComponent, MatchaStepperContentComponent, MatchaStepperControllerComponent, MatchaStepperModule, MatchaStepperStateService, MatchaSubmenuTriggerDirective, MatchaTabItemComponent, MatchaTableComponent, MatchaTableModule, MatchaTabsComponent, MatchaTabsModule, MatchaTextEditorComponent, MatchaTextEditorModule, MatchaTimeComponent, MatchaTimeModule, MatchaTimeRangeComponent, MatchaTimeRangeModule, MatchaTitleComponent, MatchaTitleModule, MatchaToolbarButtonComponent, MatchaToolbarComponent, MatchaToolbarContentComponent, MatchaToolbarCustomButtonComponent, MatchaToolbarMainButtonComponent, MatchaToolbarModule, MatchaTooltipDirective, MatchaTooltipModule, NEW_CONFIG, NextStepDirective, PrevStepDirective, StepComponent, StepContentDirective, buildSunEditorConfig, compatibleOptions, initialConfig, timeMasks, withoutValidation };
|
|
18255
|
+
export { CopyButtonComponent, INITIAL_CONFIG, MATCHA_MASK_CONFIG, MATCHA_OPTION_PARENT, MatchaAccordionComponent, MatchaAccordionContentComponent, MatchaAccordionHeaderComponent, MatchaAccordionItemComponent, MatchaAccordionModule, MatchaAutocompleteComponent, MatchaAutocompleteModule, MatchaAutocompleteTriggerDirective, MatchaAvatarComponent, MatchaAvatarModule, MatchaBreakpointObservableModule, MatchaBreakpointObserver, MatchaButtonComponent, MatchaButtonModule, MatchaButtonToggleComponent, MatchaButtonToggleModule, MatchaCalendarIntl, MatchaCalendarPickerComponent, MatchaCalendarPickerModule, MatchaCardComponent, MatchaCardModule, MatchaCheckboxComponent, MatchaCheckboxModule, MatchaChipComponent, MatchaChipListComponent, MatchaChipModule, MatchaComponentsModule, MatchaDateComponent, MatchaDateModule, MatchaDateRangeComponent, MatchaDateRangeModule, MatchaDividerComponent, MatchaDividerModule, MatchaDragDirective, MatchaDragHandleDirective, MatchaDrawerComponent, MatchaDrawerContainerComponent, MatchaDrawerContentComponent, MatchaDrawerModule, MatchaDropListComponent, MatchaDropListModule, MatchaDropListService, MatchaDropZoneDirective, MatchaElevationDirective, MatchaElevationModule, MatchaErrorComponent, MatchaFormFieldComponent, MatchaFormFieldModule, MatchaGridComponent, MatchaGridModule, MatchaHighlightComponent, MatchaHighlightModule, MatchaHintTextComponent, MatchaHintTextModule, MatchaIconComponent, MatchaIconModule, MatchaInfiniteScrollComponent, MatchaInfiniteScrollDataComponent, MatchaInfiniteScrollModule, MatchaInputPhoneComponent, MatchaInputPhoneModule, MatchaLabelComponent, MatchaLazyloadComponent, MatchaLazyloadDataComponent, MatchaLazyloadModule, MatchaListComponent, MatchaListItemComponent, MatchaListModule, MatchaMaskApplierService, MatchaMaskCompatibleDirective, MatchaMaskModule, MatchaMaskPipe, MatchaMaskService, MatchaMasonryComponent, MatchaMasonryModule, MatchaMenuComponent, MatchaMenuItemDirective, MatchaMenuModule, MatchaMenuTriggerDirective, MatchaModalComponent, MatchaModalContentComponent, MatchaModalFooterComponent, MatchaModalHeaderComponent, MatchaModalModule, MatchaModalOptionsComponent, MatchaModalService, MatchaMsgBoxActionsComponent, MatchaMsgBoxComponent, MatchaMsgBoxModule, MatchaOptionComponent, MatchaOptionModule, MatchaOverlayService, MatchaPageBuilderComponent, MatchaPageBuilderModule, MatchaPageLayoutComponent, MatchaPageLayoutModule, MatchaPaginatorComponent, MatchaPaginatorIntl, MatchaPaginatorModule, MatchaPanelComponent, MatchaPanelModule, MatchaPeriodComponent, MatchaPeriodModule, MatchaProgressBarComponent, MatchaProgressBarModule, MatchaRadioComponent, MatchaRadioGroupComponent, MatchaRadioModule, MatchaRippleDirective, MatchaRippleModule, MatchaSelectComponent, MatchaSelectModule, MatchaSelectMultipleComponent, MatchaSelectMultipleModule, MatchaSelectTriggerDirective, MatchaSkeletonComponent, MatchaSkeletonModule, MatchaSlideToggleComponent, MatchaSlideToggleModule, MatchaSliderComponent, MatchaSliderModule, MatchaSnackBarComponent, MatchaSnackBarModule, MatchaSnackBarService, MatchaSpinComponent, MatchaSpinModule, MatchaSpinnerComponent, MatchaSpinnerModule, MatchaStepperComponent, MatchaStepperContentComponent, MatchaStepperControllerComponent, MatchaStepperModule, MatchaStepperStateService, MatchaSubmenuTriggerDirective, MatchaTabItemComponent, MatchaTableComponent, MatchaTableModule, MatchaTabsComponent, MatchaTabsModule, MatchaTextEditorComponent, MatchaTextEditorModule, MatchaTimeComponent, MatchaTimeModule, MatchaTimeRangeComponent, MatchaTimeRangeModule, MatchaTitleComponent, MatchaTitleModule, MatchaToolbarButtonComponent, MatchaToolbarComponent, MatchaToolbarContentComponent, MatchaToolbarCustomButtonComponent, MatchaToolbarMainButtonComponent, MatchaToolbarModule, MatchaTooltipDirective, MatchaTooltipModule, NEW_CONFIG, NextStepDirective, PrevStepDirective, StepComponent, StepContentDirective, buildSunEditorConfig, compatibleOptions, initialConfig, timeMasks, withoutValidation };
|
|
17217
18256
|
//# sourceMappingURL=matcha-components.mjs.map
|