@dhutaryan/ngx-mat-timepicker
Version:
Angular timepicker to add time which is based on material design and Angular material.
2,813 lines • 182 kB
JavaScript
import * as i0 from '@angular/core';
import { InjectionToken, Injectable, Directive, Component, ViewEncapsulation, ChangeDetectionStrategy, Attribute, Input, ContentChild, EventEmitter, Inject, Output, inject, LOCALE_ID, Optional, NgModule, HostListener, SkipSelf, ViewChild, booleanAttribute, forwardRef, TemplateRef, signal } from '@angular/core';
import * as i1$1 from '@angular/cdk/overlay';
import { Overlay, FlexibleConnectedPositionStrategy, OverlayConfig, OverlayModule } from '@angular/cdk/overlay';
import * as i3$1 from '@angular/cdk/portal';
import { PortalModule, ComponentPortal, TemplatePortal } from '@angular/cdk/portal';
import { CdkScrollableModule } from '@angular/cdk/scrolling';
import * as i4$1 from '@angular/cdk/a11y';
import { A11yModule } from '@angular/cdk/a11y';
import * as i2 from '@angular/material/button';
import { MatButtonModule, MAT_FAB_DEFAULT_OPTIONS } from '@angular/material/button';
import * as i1 from '@angular/common';
import { CommonModule, DOCUMENT } from '@angular/common';
import { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';
import { Subject, Subscription, of, merge, fromEvent, debounceTime, take, BehaviorSubject, first, filter } from 'rxjs';
import { PlatformModule, _getFocusedElementPierceShadowDom } from '@angular/cdk/platform';
import { DOWN_ARROW, UP_ARROW, PAGE_UP, PAGE_DOWN, ESCAPE, hasModifierKey } from '@angular/cdk/keycodes';
import { trigger, transition, animate, keyframes, style, state } from '@angular/animations';
import * as i2$1 from '@angular/material/divider';
import { MatDividerModule } from '@angular/material/divider';
import * as i3 from '@angular/material/core';
import { MatRippleModule } from '@angular/material/core';
import * as i4 from '@angular/material/form-field';
import { MatFormFieldModule, MAT_FORM_FIELD } from '@angular/material/form-field';
import * as i5 from '@angular/material/input';
import { MatInputModule, MAT_INPUT_VALUE_ACCESSOR } from '@angular/material/input';
import { NG_VALUE_ACCESSOR, NG_VALIDATORS, Validators } from '@angular/forms';
/** Injection token that determines the scroll handling while the timepicker is open. */
const MAT_TIMEPICKER_SCROLL_STRATEGY = new InjectionToken('mat-timepicker-scroll-strategy');
/** Timepicker scroll strategy factory. */
function MAT_TIMEPICKER_SCROLL_STRATEGY_FACTORY(overlay) {
return () => overlay.scrollStrategies.reposition();
}
/** Timepicker scroll strategy provider. */
const MAT_TIMEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER = {
provide: MAT_TIMEPICKER_SCROLL_STRATEGY,
deps: [Overlay],
useFactory: MAT_TIMEPICKER_SCROLL_STRATEGY_FACTORY,
};
class MatTimepickerIntl {
constructor() {
/**
* Stream that emits whenever the labels here are changed. Use this to notify
* components if the labels have changed after initialization.
*/
this.changes = new Subject();
/** A label for inputs title. */
this.inputsTitle = 'Enter time';
/** A label for dials title. */
this.dialsTitle = 'Select time';
/** A label for hour input hint. */
this.hourInputHint = 'Hour';
/** A label for minute input hint. */
this.minuteInputHint = 'Minute';
/** Label for the button used to open the timepicker popup (used by screen readers). */
this.openTimepickerLabel = 'Open timepicker';
/** Label for the button used to close the timepicker popup (used by screen readers). */
this.closeTimepickerLabel = 'Close timepicker';
/** A label for OK button to apply time. */
this.okButton = 'OK';
/** A label for cancel button to close timepicker. */
this.cancelButton = 'Cancel';
/** A label for am text. */
this.am = 'AM';
/** A label for am text. */
this.pm = 'PM';
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerIntl, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerIntl, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerIntl, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}] });
class MatTimepickerToggleIcon {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerToggleIcon, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.1", type: MatTimepickerToggleIcon, isStandalone: true, selector: "[matTimepickerToggleIcon]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerToggleIcon, decorators: [{
type: Directive,
args: [{ selector: '[matTimepickerToggleIcon]', standalone: true }]
}] });
class MatTimepickerToggle {
/** Whether the toggle button is disabled. */
get disabled() {
if (this._disabled === undefined && this.timepicker) {
return this.timepicker.disabled;
}
return !!this._disabled;
}
set disabled(value) {
this._disabled = coerceBooleanProperty(value);
}
constructor(defaultTabIndex, _intl, _cdr) {
this._intl = _intl;
this._cdr = _cdr;
this._stateChanges = Subscription.EMPTY;
const parsedTabIndex = Number(defaultTabIndex);
this.tabIndex =
parsedTabIndex || parsedTabIndex === 0 ? parsedTabIndex : null;
}
ngOnChanges(changes) {
if (changes['timepicker']) {
this._watchStateChanges();
}
}
ngOnDestroy() {
this._stateChanges.unsubscribe();
}
/** Opens timepicker. */
open(event) {
if (this.timepicker && !this.disabled) {
this.timepicker.open();
event.stopPropagation();
}
}
_watchStateChanges() {
const timepickerStateChanged = this.timepicker
? this.timepicker.stateChanges
: of();
const inputStateChanged = this.timepicker && this.timepicker.timepickerInput
? this.timepicker.timepickerInput.stateChanges
: of();
const timepickerToggled = this.timepicker
? merge(this.timepicker.openedStream, this.timepicker.closedStream)
: of();
this._stateChanges.unsubscribe();
this._stateChanges = merge(this._intl.changes, timepickerStateChanged, inputStateChanged, timepickerToggled).subscribe(() => this._cdr.markForCheck());
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerToggle, deps: [{ token: 'tabindex', attribute: true }, { token: MatTimepickerIntl }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.1", type: MatTimepickerToggle, isStandalone: true, selector: "mat-timepicker-toggle", inputs: { timepicker: ["for", "timepicker"], disabled: "disabled", disableRipple: "disableRipple", tabIndex: "tabIndex", ariaLabel: ["aria-label", "ariaLabel"] }, host: { listeners: { "click": "open($event)" }, properties: { "attr.tabindex": "null", "class.mat-timepicker-toggle-active": "timepicker && timepicker.opened", "class.mat-accent": "timepicker && timepicker.color === \"accent\"", "class.mat-warn": "timepicker && timepicker.color === \"warn\"" }, classAttribute: "mat-timepicker-toggle" }, queries: [{ propertyName: "customIcon", first: true, predicate: MatTimepickerToggleIcon, descendants: true }], exportAs: ["matTimepickerToggle"], usesOnChanges: true, ngImport: i0, template: "<button\n type=\"button\"\n #button\n mat-icon-button\n [attr.aria-haspopup]=\"timepicker ? 'dialog' : null\"\n [attr.aria-label]=\"ariaLabel || _intl.openTimepickerLabel\"\n [attr.tabindex]=\"disabled ? -1 : tabIndex\"\n [disabled]=\"disabled\"\n [disableRipple]=\"disableRipple\"\n>\n @if (!customIcon) {\n <svg\n class=\"mat-timepicker-toggle-default-icon\"\n viewBox=\"0 0 24 24\"\n width=\"24\"\n height=\"24\"\n fill=\"currentColor\"\n focusable=\"false\"\n >\n <path\n d=\"M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10s10-4.5,10-10S17.5,2,12,2z M12,20c-4.41,0-8-3.59-8-8s3.59-8,8-8s8,3.59,8,8 S16.41,20,12,20z M12.5,7H11v6l5.2,3.2l0.8-1.3l-4.5-2.7V7z\"\n />\n </svg>\n }\n\n <ng-content select=\"[matTimepickerToggleIcon]\"></ng-content>\n</button>\n", styles: [".mat-form-field .mat-form-field-prefix .mat-timepicker-toggle-default-icon,.mat-form-field .mat-form-field-suffix .mat-timepicker-toggle-default-icon{display:block;width:1.5em;height:1.5em}.mat-form-field .mat-form-field-prefix .mat-icon-button .mat-timepicker-toggle-default-icon,.mat-form-field .mat-form-field-suffix .mat-icon-button .mat-timepicker-toggle-default-icon{margin:auto}.mat-timepicker-toggle{color:var(--mat-timepicker-toggle-color, var(--mat-sys-on-surface-variant))}.mat-timepicker-toggle.mat-timepicker-toggle-active button{color:var(--mat-timepicker-toggle-active-color, var(--mat-sys-primary))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerToggle, decorators: [{
type: Component,
args: [{ selector: 'mat-timepicker-toggle', standalone: true, imports: [CommonModule, MatButtonModule], exportAs: 'matTimepickerToggle', host: {
class: 'mat-timepicker-toggle',
'[attr.tabindex]': 'null',
'[class.mat-timepicker-toggle-active]': 'timepicker && timepicker.opened',
'[class.mat-accent]': 'timepicker && timepicker.color === "accent"',
'[class.mat-warn]': 'timepicker && timepicker.color === "warn"',
'(click)': 'open($event)',
}, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<button\n type=\"button\"\n #button\n mat-icon-button\n [attr.aria-haspopup]=\"timepicker ? 'dialog' : null\"\n [attr.aria-label]=\"ariaLabel || _intl.openTimepickerLabel\"\n [attr.tabindex]=\"disabled ? -1 : tabIndex\"\n [disabled]=\"disabled\"\n [disableRipple]=\"disableRipple\"\n>\n @if (!customIcon) {\n <svg\n class=\"mat-timepicker-toggle-default-icon\"\n viewBox=\"0 0 24 24\"\n width=\"24\"\n height=\"24\"\n fill=\"currentColor\"\n focusable=\"false\"\n >\n <path\n d=\"M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10s10-4.5,10-10S17.5,2,12,2z M12,20c-4.41,0-8-3.59-8-8s3.59-8,8-8s8,3.59,8,8 S16.41,20,12,20z M12.5,7H11v6l5.2,3.2l0.8-1.3l-4.5-2.7V7z\"\n />\n </svg>\n }\n\n <ng-content select=\"[matTimepickerToggleIcon]\"></ng-content>\n</button>\n", styles: [".mat-form-field .mat-form-field-prefix .mat-timepicker-toggle-default-icon,.mat-form-field .mat-form-field-suffix .mat-timepicker-toggle-default-icon{display:block;width:1.5em;height:1.5em}.mat-form-field .mat-form-field-prefix .mat-icon-button .mat-timepicker-toggle-default-icon,.mat-form-field .mat-form-field-suffix .mat-icon-button .mat-timepicker-toggle-default-icon{margin:auto}.mat-timepicker-toggle{color:var(--mat-timepicker-toggle-color, var(--mat-sys-on-surface-variant))}.mat-timepicker-toggle.mat-timepicker-toggle-active button{color:var(--mat-timepicker-toggle-active-color, var(--mat-sys-primary))}\n"] }]
}], ctorParameters: () => [{ type: undefined, decorators: [{
type: Attribute,
args: ['tabindex']
}] }, { type: MatTimepickerIntl }, { type: i0.ChangeDetectorRef }], propDecorators: { timepicker: [{
type: Input,
args: ['for']
}], disabled: [{
type: Input
}], disableRipple: [{
type: Input
}], tabIndex: [{
type: Input
}], customIcon: [{
type: ContentChild,
args: [MatTimepickerToggleIcon]
}], ariaLabel: [{
type: Input,
args: ['aria-label']
}] } });
/** Animations used by the timepicker. */
const matTimepickerAnimations = {
/** Transforms the height of the timepicker's. */
transformPanel: trigger('transformPanel', [
transition('void => enter-dropdown', animate('120ms cubic-bezier(0, 0, 0.2, 1)', keyframes([
style({ opacity: 0, transform: 'scale(1, 0.8)' }),
style({ opacity: 1, transform: 'scale(1, 1)' }),
]))),
transition('void => enter-dialog', animate('150ms cubic-bezier(0, 0, 0.2, 1)', keyframes([
style({ opacity: 0, transform: 'scale(0.7)' }),
style({ transform: 'none', opacity: 1 }),
]))),
transition('* => void', animate('100ms linear', style({ opacity: 0 }))),
]),
/** Fades in the content of the timepicker. */
fadeInTimepicker: trigger('fadeInTimepicker', [
state('void', style({ opacity: 0 })),
state('enter', style({ opacity: 1 })),
]),
};
const TOUCH_UI_MULTIPLIER = 1.25;
const TOUCH_UI_TICK_MULTIPLIER = 1.5;
const CLOCK_RADIUS = 128;
const CLOCK_TICK_RADIUS = 16;
const CLOCK_OUTER_RADIUS = 100;
function getClockRadius(touchUi) {
return touchUi ? CLOCK_RADIUS * TOUCH_UI_MULTIPLIER : CLOCK_RADIUS;
}
function getClockTickRadius(touchUi) {
return touchUi
? CLOCK_TICK_RADIUS * TOUCH_UI_TICK_MULTIPLIER
: CLOCK_TICK_RADIUS;
}
function getClockCorrectedRadius(touchUi) {
return getClockRadius(touchUi) - getClockTickRadius(touchUi);
}
function getClockOuterRadius(touchUi) {
return touchUi
? CLOCK_OUTER_RADIUS * TOUCH_UI_MULTIPLIER
: CLOCK_OUTER_RADIUS;
}
function getClockInnerRadius(touchUi) {
return getClockOuterRadius(touchUi) - getClockTickRadius(touchUi) * 2;
}
const ALL_MINUTES = Array(60)
.fill(null)
.map((_, i) => i);
class MatMinutesClockDial {
/** Selected minute. */
get selectedMinute() {
return this._selectedMinute;
}
set selectedMinute(value) {
this._selectedMinute = value;
}
/** Step over minutes. */
get interval() {
return this._interval;
}
set interval(value) {
this._interval = coerceNumberProperty(value) || 1;
}
get availableMinutes() {
return this._availableMinutes;
}
set availableMinutes(value) {
this._availableMinutes = value;
this._initMinutes();
}
/** Whether the timepicker UI is in touch mode. */
get touchUi() {
return this._touchUi;
}
set touchUi(value) {
this._touchUi = value;
}
get disabled() {
return !this.availableMinutes.includes(this.selectedMinute);
}
get isMinutePoint() {
return !!this.minutes.find((hour) => hour.value === this.selectedMinute);
}
constructor(_element, _cdr, _document) {
this._element = _element;
this._cdr = _cdr;
this._document = _document;
this._selectedMinute = 0;
this._interval = 1;
this._availableMinutes = [];
/** Emits selected minute. */
this.selectedChange = new EventEmitter();
this.minutes = [];
}
ngOnInit() {
this._initMinutes();
}
/** Hand styles based on selected minute. */
_handStyles() {
const deg = Math.round(this._selectedMinute * (360 / 60));
const height = getClockOuterRadius(this.touchUi);
const marginTop = getClockRadius(this.touchUi) - getClockOuterRadius(this.touchUi);
return {
transform: `rotate(${deg}deg)`,
height: `${height}px`,
'margin-top': `${marginTop}px`,
};
}
/** Handles mouse and touch events on dial and document. */
_onUserAction(event) {
if (event.cancelable) {
event.preventDefault();
}
this._setMinute(event);
const eventsSubscription = merge(fromEvent(this._document, 'mousemove'), fromEvent(this._document, 'touchmove'))
.pipe(debounceTime(0))
.subscribe({
next: (event) => {
event.preventDefault();
this._setMinute(event);
},
});
merge(fromEvent(this._document, 'mouseup'), fromEvent(this._document, 'touchend'))
.pipe(take(1))
.subscribe({
next: () => {
eventsSubscription.unsubscribe();
},
});
}
_isActiveCell(minute) {
return this.selectedMinute === minute;
}
_setMinute(event) {
const element = this._element.nativeElement;
const window = this._getWindow();
const elementRect = element.getBoundingClientRect();
const width = element.offsetWidth;
const height = element.offsetHeight;
const pageX = event instanceof MouseEvent ? event.pageX : event.touches[0].pageX;
const pageY = event instanceof MouseEvent ? event.pageY : event.touches[0].pageY;
const x = width / 2 - (pageX - elementRect.left - window.scrollX);
const y = height / 2 - (pageY - elementRect.top - window.scrollY);
const unit = Math.PI / (30 / this.interval);
const atan2 = Math.atan2(-x, y);
const radian = atan2 < 0 ? Math.PI * 2 + atan2 : atan2;
const initialValue = Math.round(radian / unit) * this.interval;
const value = initialValue === 60 ? 0 : initialValue;
if (this.availableMinutes.includes(value) && this.availableMinutes.includes(value)) {
this.selectedMinute = value;
this.selectedChange.emit(this.selectedMinute);
}
this._cdr.detectChanges();
}
/** Creates list of minutes. */
_initMinutes() {
this.minutes = ALL_MINUTES.filter((minute) => minute % 5 === 0).map((minute) => {
const radian = (minute / 30) * Math.PI;
const displayValue = minute === 0 ? '00' : String(minute);
return {
value: minute,
displayValue,
left: getClockCorrectedRadius(this.touchUi) +
Math.sin(radian) * getClockOuterRadius(this.touchUi),
top: getClockCorrectedRadius(this.touchUi) -
Math.cos(radian) * getClockOuterRadius(this.touchUi),
disabled: !this.availableMinutes.includes(minute),
};
});
}
/** Use defaultView of injected document if available or fallback to global window reference */
_getWindow() {
return this._document.defaultView || window;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatMinutesClockDial, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.1", type: MatMinutesClockDial, isStandalone: true, selector: "mat-minutes-clock-dial", inputs: { selectedMinute: "selectedMinute", interval: "interval", availableMinutes: "availableMinutes", color: "color", touchUi: "touchUi" }, outputs: { selectedChange: "selectedChange" }, host: { listeners: { "mousedown": "_onUserAction($event)", "touchstart": "_onUserAction($event)" }, classAttribute: "mat-clock-dial mat-clock-dial-minutes" }, exportAs: ["matMinutesClockDial"], ngImport: i0, template: "<div\n class=\"mat-clock-dial-hand\"\n [class.mat-clock-dial-hand-pointless]=\"isMinutePoint\"\n [class.mat-clock-dial-hand-disabled]=\"disabled\"\n [ngStyle]=\"_handStyles()\"\n>\n <div class=\"mat-clock-dial-hand-point\" tabindex=\"0\"></div>\n</div>\n@for (minute of minutes; track minute.value) {\n <button\n class=\"mat-clock-dial-cell\"\n mat-mini-fab\n disableRipple\n [tabIndex]=\"_isActiveCell(minute.value) ? 0 : -1\"\n [style.left.px]=\"minute.left\"\n [style.top.px]=\"minute.top\"\n [class.mat-clock-dial-cell-active]=\"_isActiveCell(minute.value)\"\n [class.mat-clock-dial-cell-disabled]=\"minute.disabled\"\n [color]=\"_isActiveCell(minute.value) ? color : undefined\"\n [attr.aria-disabled]=\"minute.disabled || null\"\n >\n {{ minute.displayValue }}\n </button>\n}\n", styles: [".mat-clock-dial{position:relative;display:block;width:16rem;height:16rem;margin:0 auto;border-radius:50%;background-color:var(--mat-timepicker-clock-dial-background-color, var(--mat-sys-surface-container-highest))}.mat-clock-dial:before{position:absolute;top:50%;left:50%;width:.4375rem;height:.4375rem;border-radius:50%;transform:translate(-50%,-50%);content:\"\";background-color:var(--mat-timepicker-clock-dial-center-point-color, var(--mat-sys-primary))}[mat-mini-fab].mat-clock-dial-cell{position:absolute;display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;border-radius:50%;box-shadow:none}[mat-mini-fab].mat-clock-dial-cell:disabled{pointer-events:none}[mat-mini-fab].mat-clock-dial-cell:focus,[mat-mini-fab].mat-clock-dial-cell:hover,[mat-mini-fab].mat-clock-dial-cell:active,[mat-mini-fab].mat-clock-dial-cell:focus:active{box-shadow:none}[mat-mini-fab].mat-clock-dial-cell.mat-clock-dial-cell-disabled.mat-clock-dial-cell-active{background-color:var(--mat-timepicker-clock-dial-cell-active-disabled-color, color-mix(in srgb, var(--mat-sys-primary) 40%, transparent));color:var(--mat-timepicker-clock-dial-cell-active-text-color, var(--mat-sys-on-primary))}.mat-clock-dial-cell:not(.mat-primary):not(.mat-accent):not(.mat-warn){background:var(--mat-timepicker-clock-dial-cell-unthemable-color, transparent)}.mat-clock-dial-cell.mat-clock-dial-cell-active{color:var(--mat-timepicker-clock-dial-cell-active-text-color, var(--mat-sys-on-primary));background-color:var(--mat-timepicker-clock-dial-cell-active-background-color, var(--mat-sys-primary))}.mat-clock-dial-cell.mat-clock-dial-cell-disabled{color:var(--mat-timepicker-clock-dial-cell-disabled-text-color, color-mix(in srgb, var(--mat-sys-on-surface) 40%, transparent))}.mat-clock-dial-cell.mat-clock-dial-cell-disabled .mat-mdc-button-persistent-ripple:before{background-color:var(--mat-timepicker-clock-dial-cell-disabled-background-color, transparent)}.mat-timepicker-content-touch .mat-clock-dial{width:20rem;height:20rem}.mat-timepicker-content-touch [mat-mini-fab].mat-clock-dial-cell{width:3rem;height:3rem;font-size:1.125rem}.mat-clock-dial-hand{position:absolute;inset:0;width:1px;margin:0 auto;transform-origin:bottom}.mat-clock-dial-hand:before{position:absolute;top:-.25rem;left:-.25rem;width:calc(.5rem + 1px);height:calc(.5rem + 1px);border-radius:50%;content:\"\"}.mat-clock-dial-hand.mat-clock-dial-hand-disabled{background-color:var(--mat-timepicker-clock-dial-hand-disabled-color, transparent)}.mat-clock-dial-hand.mat-clock-dial-hand-disabled:before{background-color:var(--mat-timepicker-clock-dial-hand-value-point-disabled-color, color-mix(in srgb, var(--mat-sys-primary) 40%, transparent))}.mat-clock-dial-hand:not(.mat-clock-dial-hand-disabled){background-color:var(--mat-timepicker-clock-dial-hand-color, var(--mat-sys-primary))}.mat-clock-dial-hand:not(.mat-clock-dial-hand-disabled):before{background-color:var(--mat-timepicker-clock-dial-hand-value-point-color, var(--mat-sys-primary))}.mat-clock-dial-hand.mat-clock-dial-hand-pointless:before{content:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatMiniFabButton, selector: "button[mat-mini-fab]", exportAs: ["matButton"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatMinutesClockDial, decorators: [{
type: Component,
args: [{ selector: 'mat-minutes-clock-dial', standalone: true, imports: [CommonModule, MatButtonModule], exportAs: 'matMinutesClockDial', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
class: 'mat-clock-dial mat-clock-dial-minutes',
'(mousedown)': '_onUserAction($event)',
'(touchstart)': '_onUserAction($event)',
}, template: "<div\n class=\"mat-clock-dial-hand\"\n [class.mat-clock-dial-hand-pointless]=\"isMinutePoint\"\n [class.mat-clock-dial-hand-disabled]=\"disabled\"\n [ngStyle]=\"_handStyles()\"\n>\n <div class=\"mat-clock-dial-hand-point\" tabindex=\"0\"></div>\n</div>\n@for (minute of minutes; track minute.value) {\n <button\n class=\"mat-clock-dial-cell\"\n mat-mini-fab\n disableRipple\n [tabIndex]=\"_isActiveCell(minute.value) ? 0 : -1\"\n [style.left.px]=\"minute.left\"\n [style.top.px]=\"minute.top\"\n [class.mat-clock-dial-cell-active]=\"_isActiveCell(minute.value)\"\n [class.mat-clock-dial-cell-disabled]=\"minute.disabled\"\n [color]=\"_isActiveCell(minute.value) ? color : undefined\"\n [attr.aria-disabled]=\"minute.disabled || null\"\n >\n {{ minute.displayValue }}\n </button>\n}\n", styles: [".mat-clock-dial{position:relative;display:block;width:16rem;height:16rem;margin:0 auto;border-radius:50%;background-color:var(--mat-timepicker-clock-dial-background-color, var(--mat-sys-surface-container-highest))}.mat-clock-dial:before{position:absolute;top:50%;left:50%;width:.4375rem;height:.4375rem;border-radius:50%;transform:translate(-50%,-50%);content:\"\";background-color:var(--mat-timepicker-clock-dial-center-point-color, var(--mat-sys-primary))}[mat-mini-fab].mat-clock-dial-cell{position:absolute;display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;border-radius:50%;box-shadow:none}[mat-mini-fab].mat-clock-dial-cell:disabled{pointer-events:none}[mat-mini-fab].mat-clock-dial-cell:focus,[mat-mini-fab].mat-clock-dial-cell:hover,[mat-mini-fab].mat-clock-dial-cell:active,[mat-mini-fab].mat-clock-dial-cell:focus:active{box-shadow:none}[mat-mini-fab].mat-clock-dial-cell.mat-clock-dial-cell-disabled.mat-clock-dial-cell-active{background-color:var(--mat-timepicker-clock-dial-cell-active-disabled-color, color-mix(in srgb, var(--mat-sys-primary) 40%, transparent));color:var(--mat-timepicker-clock-dial-cell-active-text-color, var(--mat-sys-on-primary))}.mat-clock-dial-cell:not(.mat-primary):not(.mat-accent):not(.mat-warn){background:var(--mat-timepicker-clock-dial-cell-unthemable-color, transparent)}.mat-clock-dial-cell.mat-clock-dial-cell-active{color:var(--mat-timepicker-clock-dial-cell-active-text-color, var(--mat-sys-on-primary));background-color:var(--mat-timepicker-clock-dial-cell-active-background-color, var(--mat-sys-primary))}.mat-clock-dial-cell.mat-clock-dial-cell-disabled{color:var(--mat-timepicker-clock-dial-cell-disabled-text-color, color-mix(in srgb, var(--mat-sys-on-surface) 40%, transparent))}.mat-clock-dial-cell.mat-clock-dial-cell-disabled .mat-mdc-button-persistent-ripple:before{background-color:var(--mat-timepicker-clock-dial-cell-disabled-background-color, transparent)}.mat-timepicker-content-touch .mat-clock-dial{width:20rem;height:20rem}.mat-timepicker-content-touch [mat-mini-fab].mat-clock-dial-cell{width:3rem;height:3rem;font-size:1.125rem}.mat-clock-dial-hand{position:absolute;inset:0;width:1px;margin:0 auto;transform-origin:bottom}.mat-clock-dial-hand:before{position:absolute;top:-.25rem;left:-.25rem;width:calc(.5rem + 1px);height:calc(.5rem + 1px);border-radius:50%;content:\"\"}.mat-clock-dial-hand.mat-clock-dial-hand-disabled{background-color:var(--mat-timepicker-clock-dial-hand-disabled-color, transparent)}.mat-clock-dial-hand.mat-clock-dial-hand-disabled:before{background-color:var(--mat-timepicker-clock-dial-hand-value-point-disabled-color, color-mix(in srgb, var(--mat-sys-primary) 40%, transparent))}.mat-clock-dial-hand:not(.mat-clock-dial-hand-disabled){background-color:var(--mat-timepicker-clock-dial-hand-color, var(--mat-sys-primary))}.mat-clock-dial-hand:not(.mat-clock-dial-hand-disabled):before{background-color:var(--mat-timepicker-clock-dial-hand-value-point-color, var(--mat-sys-primary))}.mat-clock-dial-hand.mat-clock-dial-hand-pointless:before{content:none}\n"] }]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: Document, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }], propDecorators: { selectedMinute: [{
type: Input
}], interval: [{
type: Input
}], availableMinutes: [{
type: Input
}], color: [{
type: Input
}], touchUi: [{
type: Input
}], selectedChange: [{
type: Output
}] } });
const ALL_HOURS = Array(24)
.fill(null)
.map((_, i) => i);
class MatHoursClockDial {
/** Selected hour. */
get selectedHour() {
return this._selectedHour;
}
set selectedHour(value) {
this._selectedHour = value;
}
/** Whether the clock uses 12 hour format. */
get isMeridiem() {
return this._isMeridiem;
}
set isMeridiem(value) {
this._isMeridiem = value;
}
get availableHours() {
return this._availableHours;
}
set availableHours(value) {
this._availableHours = value;
this._initHours();
}
/** Whether the timepicker UI is in touch mode. */
get touchUi() {
return this._touchUi;
}
set touchUi(value) {
this._touchUi = value;
this._initHours();
}
get disabledHand() {
return !this.availableHours.includes(this.selectedHour);
}
get isHour() {
return !!this.hours.find((hour) => hour.value === this.selectedHour);
}
constructor(_element, _cdr, _document) {
this._element = _element;
this._cdr = _cdr;
this._document = _document;
this._availableHours = [];
/** Emits selected hour. */
this.selectedChange = new EventEmitter();
this.hours = [];
}
ngOnInit() {
this._initHours();
}
/** Hand styles based on selected hour. */
_handStyles() {
const deg = Math.round(this.selectedHour * (360 / (24 / 2)));
const radius = this._getRadius(this.selectedHour);
const height = radius;
const marginTop = getClockRadius(this.touchUi) - radius;
return {
transform: `rotate(${deg}deg)`,
height: `${height}px`,
'margin-top': `${marginTop}px`,
};
}
/** Handles mouse and touch events on dial and document. */
_onUserAction(event) {
if (event.cancelable) {
event.preventDefault();
}
this._setHour(event);
const eventsSubscription = merge(fromEvent(this._document, 'mousemove'), fromEvent(this._document, 'touchmove'))
.pipe(debounceTime(0))
.subscribe({
next: (event) => {
event.preventDefault();
this._setHour(event);
},
});
merge(fromEvent(this._document, 'mouseup'), fromEvent(this._document, 'touchend'))
.pipe(take(1))
.subscribe({
next: () => {
eventsSubscription.unsubscribe();
this.selectedChange.emit({
hour: this.selectedHour,
changeView: true,
});
},
});
}
_isActiveCell(hour) {
return this.selectedHour === hour;
}
/** Changes selected hour based on coordinates. */
_setHour(event) {
const element = this._element.nativeElement;
const window = this._getWindow();
const elementRect = element.getBoundingClientRect();
const width = element.offsetWidth;
const height = element.offsetHeight;
const pageX = event instanceof MouseEvent ? event.pageX : event.touches[0].pageX;
const pageY = event instanceof MouseEvent ? event.pageY : event.touches[0].pageY;
const x = width / 2 - (pageX - elementRect.left - window.scrollX);
const y = height / 2 - (pageY - elementRect.top - window.scrollY);
const unit = Math.PI / 6;
const atan2 = Math.atan2(-x, y);
const radian = atan2 < 0 ? Math.PI * 2 + atan2 : atan2;
const initialValue = Math.round(radian / unit);
const z = Math.sqrt(x * x + y * y);
const outer = z > getClockOuterRadius(this.touchUi) - getClockTickRadius(this.touchUi);
const value = this._getHourValue(initialValue, outer);
if (this.availableHours.includes(value)) {
this.selectedHour = value;
this.selectedChange.emit({
hour: this.selectedHour,
});
}
this._cdr.detectChanges();
}
/** Return value of hour. */
_getHourValue(value, outer) {
const edgeValue = value === 0 || value === 12;
if (this.isMeridiem) {
return edgeValue ? 12 : value;
}
if (outer) {
return edgeValue ? 0 : value;
}
return edgeValue ? 12 : value + 12;
}
/** Creates list of hours. */
_initHours() {
const initialHours = this.isMeridiem ? ALL_HOURS.slice(1, 13) : ALL_HOURS;
this.hours = initialHours.map((hour) => {
const radian = (hour / 6) * Math.PI;
const radius = this._getRadius(hour);
return {
value: hour,
displayValue: hour === 0 ? '00' : String(hour),
left: getClockCorrectedRadius(this.touchUi) + Math.sin(radian) * radius,
top: getClockCorrectedRadius(this.touchUi) - Math.cos(radian) * radius,
disabled: !this.availableHours.includes(hour),
};
});
}
/** Returns radius based on hour */
_getRadius(hour) {
if (this.isMeridiem) {
return getClockOuterRadius(this.touchUi);
}
const outer = hour >= 0 && hour < 12;
const radius = outer ? getClockOuterRadius(this.touchUi) : getClockInnerRadius(this.touchUi);
return radius;
}
/** Use defaultView of injected document if available or fallback to global window reference */
_getWindow() {
return this._document.defaultView || window;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatHoursClockDial, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.1", type: MatHoursClockDial, isStandalone: true, selector: "mat-hours-clock-dial", inputs: { selectedHour: "selectedHour", isMeridiem: "isMeridiem", availableHours: "availableHours", color: "color", touchUi: "touchUi" }, outputs: { selectedChange: "selectedChange" }, host: { listeners: { "mousedown": "_onUserAction($event)", "touchstart": "_onUserAction($event)" }, classAttribute: "mat-clock-dial mat-clock-dial-hours" }, exportAs: ["matHoursClockDial"], ngImport: i0, template: "<div\n class=\"mat-clock-dial-hand\"\n [class.mat-clock-dial-hand-pointless]=\"isHour\"\n [class.mat-clock-dial-hand-disabled]=\"disabledHand\"\n [ngStyle]=\"_handStyles()\"\n></div>\n@for (hour of hours; track hour.value) {\n <button\n class=\"mat-clock-dial-cell\"\n mat-mini-fab\n disableRipple\n [tabIndex]=\"_isActiveCell(hour.value) ? 0 : -1\"\n [style.left.px]=\"hour.left\"\n [style.top.px]=\"hour.top\"\n [class.mat-clock-dial-cell-active]=\"_isActiveCell(hour.value)\"\n [class.mat-clock-dial-cell-disabled]=\"hour.disabled\"\n [color]=\"_isActiveCell(hour.value) ? color : undefined\"\n [attr.aria-disabled]=\"hour.disabled || null\"\n >\n {{ hour.displayValue }}\n </button>\n}\n", styles: [".mat-clock-dial{position:relative;display:block;width:16rem;height:16rem;margin:0 auto;border-radius:50%;background-color:var(--mat-timepicker-clock-dial-background-color, var(--mat-sys-surface-container-highest))}.mat-clock-dial:before{position:absolute;top:50%;left:50%;width:.4375rem;height:.4375rem;border-radius:50%;transform:translate(-50%,-50%);content:\"\";background-color:var(--mat-timepicker-clock-dial-center-point-color, var(--mat-sys-primary))}[mat-mini-fab].mat-clock-dial-cell{position:absolute;display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;border-radius:50%;box-shadow:none}[mat-mini-fab].mat-clock-dial-cell:disabled{pointer-events:none}[mat-mini-fab].mat-clock-dial-cell:focus,[mat-mini-fab].mat-clock-dial-cell:hover,[mat-mini-fab].mat-clock-dial-cell:active,[mat-mini-fab].mat-clock-dial-cell:focus:active{box-shadow:none}[mat-mini-fab].mat-clock-dial-cell.mat-clock-dial-cell-disabled.mat-clock-dial-cell-active{background-color:var(--mat-timepicker-clock-dial-cell-active-disabled-color, color-mix(in srgb, var(--mat-sys-primary) 40%, transparent));color:var(--mat-timepicker-clock-dial-cell-active-text-color, var(--mat-sys-on-primary))}.mat-clock-dial-cell:not(.mat-primary):not(.mat-accent):not(.mat-warn){background:var(--mat-timepicker-clock-dial-cell-unthemable-color, transparent)}.mat-clock-dial-cell.mat-clock-dial-cell-active{color:var(--mat-timepicker-clock-dial-cell-active-text-color, var(--mat-sys-on-primary));background-color:var(--mat-timepicker-clock-dial-cell-active-background-color, var(--mat-sys-primary))}.mat-clock-dial-cell.mat-clock-dial-cell-disabled{color:var(--mat-timepicker-clock-dial-cell-disabled-text-color, color-mix(in srgb, var(--mat-sys-on-surface) 40%, transparent))}.mat-clock-dial-cell.mat-clock-dial-cell-disabled .mat-mdc-button-persistent-ripple:before{background-color:var(--mat-timepicker-clock-dial-cell-disabled-background-color, transparent)}.mat-timepicker-content-touch .mat-clock-dial{width:20rem;height:20rem}.mat-timepicker-content-touch [mat-mini-fab].mat-clock-dial-cell{width:3rem;height:3rem;font-size:1.125rem}.mat-clock-dial-hand{position:absolute;inset:0;width:1px;margin:0 auto;transform-origin:bottom}.mat-clock-dial-hand:before{position:absolute;top:-.25rem;left:-.25rem;width:calc(.5rem + 1px);height:calc(.5rem + 1px);border-radius:50%;content:\"\"}.mat-clock-dial-hand.mat-clock-dial-hand-disabled{background-color:var(--mat-timepicker-clock-dial-hand-disabled-color, transparent)}.mat-clock-dial-hand.mat-clock-dial-hand-disabled:before{background-color:var(--mat-timepicker-clock-dial-hand-value-point-disabled-color, color-mix(in srgb, var(--mat-sys-primary) 40%, transparent))}.mat-clock-dial-hand:not(.mat-clock-dial-hand-disabled){background-color:var(--mat-timepicker-clock-dial-hand-color, var(--mat-sys-primary))}.mat-clock-dial-hand:not(.mat-clock-dial-hand-disabled):before{background-color:var(--mat-timepicker-clock-dial-hand-value-point-color, var(--mat-sys-primary))}.mat-clock-dial-hand.mat-clock-dial-hand-pointless:before{content:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatMiniFabButton, selector: "button[mat-mini-fab]", exportAs: ["matButton"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatHoursClockDial, decorators: [{
type: Component,
args: [{ selector: 'mat-hours-clock-dial', standalone: true, imports: [CommonModule, MatButtonModule], exportAs: 'matHoursClockDial', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
class: 'mat-clock-dial mat-clock-dial-hours',
'(mousedown)': '_onUserAction($event)',
'(touchstart)': '_onUserAction($event)',
}, template: "<div\n class=\"mat-clock-dial-hand\"\n [class.mat-clock-dial-hand-pointless]=\"isHour\"\n [class.mat-clock-dial-hand-disabled]=\"disabledHand\"\n [ngStyle]=\"_handStyles()\"\n></div>\n@for (hour of hours; track hour.value) {\n <button\n class=\"mat-clock-dial-cell\"\n mat-mini-fab\n disableRipple\n [tabIndex]=\"_isActiveCell(hour.value) ? 0 : -1\"\n [style.left.px]=\"hour.left\"\n [style.top.px]=\"hour.top\"\n [class.mat-clock-dial-cell-active]=\"_isActiveCell(hour.value)\"\n [class.mat-clock-dial-cell-disabled]=\"hour.disabled\"\n [color]=\"_isActiveCell(hour.value) ? color : undefined\"\n [attr.aria-disabled]=\"hour.disabled || null\"\n >\n {{ hour.displayValue }}\n </button>\n}\n", styles: [".mat-clock-dial{position:relative;display:block;width:16rem;height:16rem;margin:0 auto;border-radius:50%;background-color:var(--mat-timepicker-clock-dial-background-color, var(--mat-sys-surface-container-highest))}.mat-clock-dial:before{position:absolute;top:50%;left:50%;width:.4375rem;height:.4375rem;border-radius:50%;transform:translate(-50%,-50%);content:\"\";background-color:var(--mat-timepicker-clock-dial-center-point-color, var(--mat-sys-primary))}[mat-mini-fab].mat-clock-dial-cell{position:absolute;display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;border-radius:50%;box-shadow:none}[mat-mini-fab].mat-clock-dial-cell:disabled{pointer-events:none}[mat-mini-fab].mat-clock-dial-cell:focus,[mat-mini-fab].mat-clock-dial-cell:hover,[mat-mini-fab].mat-clock-dial-cell:active,[mat-mini-fab].mat-clock-dial-cell:focus:active{box-shadow:none}[mat-mini-fab].mat-clock-dial-cell.mat-clock-dial-cell-disabled.mat-clock-dial-cell-active{background-color:var(--mat-timepicker-clock-dial-cell-active-disabled-color, color-mix(in srgb, var(--mat-sys-primary) 40%, transparent));color:var(--mat-timepicker-clock-dial-cell-active-text-color, var(--mat-sys-on-primary))}.mat-clock-dial-cell:not(.mat-primary):not(.mat-accent):not(.mat-warn){background:var(--mat-timepicker-clock-dial-cell-unthemable-color, transparent)}.mat-clock-dial-cell.mat-clock-dial-cell-active{color:var(--mat-timepicker-clock-dial-cell-active-text-color, var(--mat-sys-on-primary));background-color:var(--mat-timepicker-clock-dial-cell-active-background-color, var(--mat-sys-primary))}.mat-clock-dial-cell.mat-clock-dial-cell-disabled{color:var(--mat-timepicker-clock-dial-cell-disabled-text-color, color-mix(in srgb, var(--mat-sys-on-surface) 40%, transparent))}.mat-clock-dial-cell.mat-clock-dial-cell-disabled .mat-mdc-button-persistent-ripple:before{background-color:var(--mat-timepicker-clock-dial-cell-disabled-background-color, transparent)}.mat-timepicker-content-touch .mat-clock-dial{width:20rem;height:20rem}.mat-timepicker-content-touch [mat-mini-fab].mat-clock-dial-cell{width:3rem;height:3rem;font-size:1.125rem}.mat-clock-dial-hand{position:absolute;inset:0;width:1px;margin:0 auto;transform-origin:bottom}.mat-clock-dial-hand:before{position:absolute;top:-.25rem;left:-.25rem;width:calc(.5rem + 1px);height:calc(.5rem + 1px);border-radius:50%;content:\"\"}.mat-clock-dial-hand.mat-clock-dial-hand-disabled{background-color:var(--mat-timepicker-clock-dial-hand-disabled-color, transparent)}.mat-clock-dial-hand.mat-clock-dial-hand-disabled:before{background-color:var(--mat-timepicker-clock-dial-hand-value-point-disabled-color, color-mix(in srgb, var(--mat-sys-primary) 40%, transparent))}.mat-clock-dial-hand:not(.mat-clock-dial-hand-disabled){background-color:var(--mat-timepicker-clock-dial-hand-color, var(--mat-sys-primary))}.mat-clock-dial-hand:not(.mat-clock-dial-hand-disabled):before{background-color:var(--mat-timepicker-clock-dial-hand-value-point-color, var(--mat-sys-primary))}.mat-clock-dial-hand.mat-clock-dial-hand-pointless:before{content:none}\n"] }]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: Document, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }], propDecorators: { selectedHour: [{
type: Input
}], isMeridiem: [{
type: Input
}], availableHours: [{
type: Input
}], color: [{
type: Input
}], touchUi: [{
type: Input
}], selectedChange: [{
type: Output
}] } });
/** InjectionToken for timepicker that can be used to override default locale code. */
const MAT_TIME_LOCALE = new InjectionToken('MAT_TIME_LOCALE', {
providedIn: 'root',
factory: MAT_DATE_TIME_LOCALE_FACTORY,
});
function MAT_DATE_TIME_LOCALE_FACTORY() {
return inject(LOCALE_ID);
}
/**
* No longer needed since MAT_TIME_LOCALE has been changed to a scoped injectable.
* If you are importing and providing this in your code you can simply remove it.
* @deprecated
* @breaking-change 18.0.0
*/
const MAT_TIME_LOCALE_PROVIDER = {
provide: MAT_TIME_LOCALE,
useExisting: LOCALE_ID,
};
class TimeAdapter {
/**
* Given a potential time object, returns that same time object if it is
* a valid time, or `null` if it's not a valid time.
* @param obj The object to check.
* @returns A time or `null`.
*/
getValidTimeOrNull(obj) {
return this.isTimeInstance(obj) && this.isValid(obj)
? obj
: null;
}
/**
* Attempts to deserialize a value to a valid time object. The `<mat-timepicker>` will call this
* method on all of its `@Input()` properties that accept time. It is therefore possible to
* support passing values from your backend directly to these properties by overriding this method
* to also deserialize the format used by your backend.
* @param value The value to be deserialized into a time object.
* @returns The deserialized time object, either a valid time, null if the value can be
* deserialized into a null time (e.g. the empty string), or an invalid date.
*/
deserialize(value) {
if (value == null || (this.isTimeInstance(value) && this.isValid(value))) {
return value;
}
return this.invalid();
}
/**
* Sets the locale used for all time.
* @param locale The new locale.
*/
setLocale(locale) {
this.locale = locale;
}
/**
* Checks if two time are equal.
* @param first The first time to check.
* @param second The second time to check.
* @returns Whether the two time are equal.
* Null time are considered equal to other null time.
*/
sameTime(first, second) {
if (first && second) {
let firstValid = this.isValid(first);
let secondValid = this.isValid(second);
if (firstValid && secondValid) {
return !this.compareTime(first, second);
}
return firstValid == secondValid;
}
return first == second;
}
/**
* Clamp the given time between min and max time.
* @param time The time to clamp.
* @param min The minimum value to allow. If null or omitted no min is enforced.
* @param max The maximum value to allow. If null or omitted no max is enforced.
* @returns `min` if `time` is less than `min`, `max` if time is greater than `max`,
* otherwise `time`.
*/
clampTime(time, min, max) {
if (min && this.compareTime(time, min) < 0) {
return min;
}
if (max && this.compareTime(time, max) > 0) {
return max;
}
return time;
}
}
/**
* Matches strings that have the form of a valid RFC 3339 string
* (https://tools.ietf.org/html/rfc3339). Note that the string may not actually be a valid date
* because the regex will match strings an with out of bounds month, date, etc.
*/
const ISO_8601_REGEX = /^\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|(?:(?:\+|-)\d{2}:\d{2}))?)?$/;
/** Adapts the native JS Date for components that work with time. */
class NativeDateTimeAdapter extends TimeAdapter {
constructor(matTimeLocale) {
super();
this._matTimeLocale = inject(MAT_TIME_LOCALE, { optional: true });
if (matTimeLocale !== undefined) {
this._matTimeLocale = matTimeLocale;
}
super.setLocale(this._matTimeLocale);
}
now() {
return new Date();
}
parse(value, parseFormat) {
// We have no way using the native JS Date to set the parse format or locale, so we ignore these
// parameters.
if (typeof value == 'number') {
return new Date(value);
}
const { hour, minute, meridiem } = this.parseTime(value);
// hour should be in 24h format
// so, if meridiem is 'pm' and hour is less than 12, add 12 to hour
const correctedHour = meridiem === 'pm' && hour < 12 ? hour + 12 : hour;
const date = new Date();
date.setHours(correctedHour);
date.setMinutes(minute);
return value ? new Date(date) : null;
}
parseTime(value) {
const time = value.replace(/(\sam|\spm|\sAM|\sPM|am|pm|AM|PM)/g, '');
const meridiem = value.replace(time, '').trim().toLowerCase();
const [hour, minute] = time.split(':');
return { hour: Number(hour), minute: Number(minute), meridiem };
}
getHour(date) {
return date.getHours();
}
getMinute(date) {
return date.getMinutes();
}
updateHour(date, hour) {
const copy = new Date(date.getTime());
copy.setHours(hour);
return copy;
}
updateMinute(date, minute) {
const copy = new Date(date.getTime());
copy.setMinutes(minute);
return copy;
}
getPeriod(date) {
return date.getHours() < 12 ? 'am' : 'pm';
}
format(date, displayFormat) {
if (!this.isValid(date)) {
throw Error('NativeDateTimeAdapter: Cannot format invalid date.');
}
const dtf = new Intl.DateTimeFormat(this.locale, {
...displayFormat,
timeZone: 'utc',
});
return this._format(dtf, date);
}
/**
* Returns the given value if given a valid Date or null. Deserializes valid ISO 8601 strings
* (https://www.ietf.org/rfc/rfc3339.txt) into valid Dates and empty string into null. Returns an
* invalid date for all other values.
*/
deserialize(value) {
if (typeof value === 'string') {
if (!value) {
return null;
}
// The `Date` constructor accepts formats other than ISO 8601, so we need to make sure the
// string is the right format first.
if (ISO_8601_REGEX.test(value)) {
const date = new Date(value);
if (this.isValid(date)) {
return date;
}
}
}
return super.deserialize(value);
}
isTimeInstance(obj) {
return obj instanceof Date;
}
isValid(date) {
return !isNaN(date.getTime());
}
invalid() {
return new Date(NaN);
}
compareTime(first, second) {
return (first.getHours() - second.getHours() ||
first.getMinutes() - second.getMinutes());
}
/**
* When converting Date object to string, javascript built-in functions may return wrong
* results because it applies its internal DST rules. The DST rules around the world change
* very frequently, and the current valid rule is not always valid in previous years though.
* We work around this problem building a new Date object which has its internal UTC
* representation with the local date and time.
* @param dtf Intl.DateTimeFormat object, containing the desired string format. It must have
* timeZone set to 'utc' to work fine.
* @param date Date from which we want to get the string representation according to dtf
* @returns A Date object with its UTC representation based on the passed in date info
*/
_format(dtf, date) {
// Passing the year to the constructor causes year numbers <100 to be converted to 19xx.
// To work around this we use `setUTCFullYear` and `setUTCHours` instead.
const d = new Date();
d.setUTCFullYear(date.getFullYear(), date.getMonth(), date.getDate());
d.setUTCHours(date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds());
return dtf.format(d);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: NativeDateTimeAdapter, deps: [{ token: MAT_TIME_LOCALE, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: NativeDateTimeAdapter }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: NativeDateTimeAdapter, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [MAT_TIME_LOCALE]
}] }] });
class NativeDateTimeModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: NativeDateTimeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.1", ngImport: i0, type: NativeDateTimeModule, imports: [PlatformModule] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: NativeDateTimeModule, providers: [{ provide: TimeAdapter, useClass: NativeDateTimeAdapter }], imports: [PlatformModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: NativeDateTimeModule, decorators: [{
type: NgModule,
args: [{
imports: [PlatformModule],
providers: [{ provide: TimeAdapter, useClass: NativeDateTimeAdapter }],
}]
}] });
class MatNativeDateTimeModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatNativeDateTimeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.1", ngImport: i0, type: MatNativeDateTimeModule }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatNativeDateTimeModule, providers: [provideNativeDateTimeAdapter()] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatNativeDateTimeModule, decorators: [{
type: NgModule,
args: [{
providers: [provideNativeDateTimeAdapter()],
}]
}] });
function provideNativeDateTimeAdapter() {
return { provide: TimeAdapter, useClass: NativeDateTimeAdapter };
}
class MatTimeFaceBase {
/** The currently selected time. */
get selected() {
return this._selected;
}
set selected(value) {
this._selected = this._timeAdapter.getValidTimeOrNull(this._timeAdapter.deserialize(value));
if (!this._selected) {
return;
}
const hour = this._timeAdapter.getHour(this._selected);
this.selectedHour = hour > 12 && this.isMeridiem ? hour - 12 : hour;
if (hour === 0 && this.isMeridiem) {
this.selectedHour = 12;
}
this.selectedMinute = this._timeAdapter.getMinute(this._selected);
this.availableHours = ALL_HOURS;
if (this.isMeridiem) {
this.period = this._timeAdapter.getPeriod(this._selected);
}
this.availableMinutes = ALL_MINUTES;
this._setMinHour();
this._setMaxHour();
this._setMinMinute();
this._setMaxMinute();
this._moveFocusOnNextTick = this.isMeridiem;
}
/** The minimum selectable time. */
get minTime() {
return this._minTime;
}
set minTime(value) {
this._minTime = this._timeAdapter.getValidTimeOrNull(this._timeAdapter.deserialize(value));
if (value) {
this._setMinHour();
this._setMinMinute();
this._setDisabledPeriod();
}
}
/** The maximum selectable time. */
get maxTime() {
return this._maxTime;
}
set maxTime(value) {
this._maxTime = this._timeAdapter.getValidTimeOrNull(this._timeAdapter.deserialize(value));
if (value) {
this._setMaxHour();
this._setMaxMinute();
this._setDisabledPeriod();
}
}
/** Step over minutes. */
get minuteInterval() {
return this._minuteInterval;
}
set minuteInterval(value) {
this._minuteInterval = coerceNumberProperty(value) || 1;
}
constructor(_timeAdapter) {
this._timeAdapter = _timeAdapter;
this._minuteInterval = 1;
/** Color palette. */
this.color = 'primary';
/** Emits when any hour, minute or period is selected. */
this._userSelection = new EventEmitter();
this.selectedChange = new EventEmitter();
this.selectedHour = 0;
this.selectedMinute = 0;
this.disabledPeriod = null;
this.availableMinutes = ALL_MINUTES;
this.availableHours = ALL_HOURS;
/**
* Used for scheduling that focus should be moved to the active cell on the next tick.
* We need to schedule it, rather than do it immediately, because we have to wait
* for Angular to re-evaluate the view children.
*/
this._moveFocusOnNextTick = false;
}
ngAfterContentInit() {
if (!this.selected) {
this.selected = this._timeAdapter.clampTime(this._timeAdapter.now(), this.minTime, this.maxTime);
this._userSelection.emit(this.selected);
}
}
ngAfterViewChecked() {
if (this._moveFocusOnNextTick) {
this._moveFocusOnNextTick = false;
this.focusActiveCell();
}
}
/** Handles hour selection. */
_onHourSelected(hour) {
this.selectedHour = hour;
const selected = this._timeAdapter.updateHour(this.selected, this._getHourBasedOnPeriod(hour));
this._timeSelected(selected);
}
/** Handles minute selection. */
_onMinuteSelected(minute) {
this.selectedMinute = minute;
const selected = this._timeAdapter.updateMinute(this.selected, minute);
this._timeSelected(selected);
}
/** Handles period changing. */
_onPeriodChanged(period) {
this.period = period;
const selected = this._timeAdapter.updateHour(this.selected, this._getHourBasedOnPeriod(this.selectedHour));
this._timeSelected(selected);
}
_getAvailableHours() {
if (this.isMeridiem) {
return this.availableHours
.filter((h) => {
if (this.period === 'am') {
return h < 12;
}
if (this.period === 'pm') {
return h >= 12;
}
return h;
})
.map((h) => {
if (h > 12) {
return h - 12;
}
if (h === 0) {
return 12;
}
return h;
});
}
return this.availableHours;
}
_onKeydown(event, view) {
switch (view) {
case 'hour':
this._handleHourKeydown(event);
break;
case 'minute':
this._handleMinuteKeydown(event);
break;
}
}
_handleHourKeydown(event) {
const hours = this._getAvailableHours();
const selectedHourIndex = hours.findIndex((hour) => hour === this.selectedHour);
if (!hours.length) {
return;
}
switch (event.keyCode) {
case UP_ARROW:
if (selectedHourIndex + 1 >= hours.length || selectedHourIndex < 0) {
this._onHourSelected(hours[0]);
}
else {
this._onHourSelected(hours[selectedHourIndex + 1]);
}
break;
case DOWN_ARROW:
if (selectedHourIndex - 1 < 0 || selectedHourIndex < 0) {
this._onHourSelected(hours[hours.length - 1]);
}
else {
this._onHourSelected(hours[selectedHourIndex - 1]);
}
break;
default:
break;
}
}
_handleMinuteKeydown(event) {
const minutes = this.availableMinutes;
const selectedMinuteIndex = minutes.findIndex((minute) => minute === this.selectedMinute);
if (!minutes.length) {
return;
}
switch (event.keyCode) {
case UP_ARROW:
if (selectedMinuteIndex + this.minuteInterval >= minutes.length ||
selectedMinuteIndex < 0) {
const difference = 60 - this.selectedMinute + Math.min(...this.availableMinutes);
const count = Math.ceil(difference / this.minuteInterval);
const differenceForValid = count * this.minuteInterval;
const nextValidValue = this.selectedMinute + differenceForValid;
const correctIndex = minutes.findIndex((minute) => minute === nextValidValue - 60 // amount of mins
);
this._onMinuteSelected(minutes[correctIndex]);
}
else {
this._onMinuteSelected(minutes[selectedMinuteIndex + this.minuteInterval]);
}
break;
case DOWN_ARROW:
if (selectedMinuteIndex - this.minuteInterval < 0 ||
selectedMinuteIndex < 0) {
const difference = 60 + this.selectedMinute - Math.max(...this.availableMinutes);
const count = Math.ceil(difference / this.minuteInterval);
const differenceForValid = count * this.minuteInterval;
const nextValidValue = this.selectedMinute - differenceForValid;
const correctIndex = minutes.findIndex((minute) => minute === nextValidValue + 60 // amount of mins
);
this._onMinuteSelected(minutes[correctIndex]);
}
else {
this._onMinuteSelected(minutes[selectedMinuteIndex - this.minuteInterval]);
}
break;
default:
break;
}
}
/** Gets a correct hours based on meridiem and period. */
_getHourBasedOnPeriod(hour) {
const afterNoon = this.isMeridiem && this.period === 'pm';
const beforeNoon = this.isMeridiem && this.period === 'am';
if (afterNoon) {
return hour === 12 ? hour : hour + 12;
}
if (beforeNoon) {
return hour === 12 ? 0 : hour;
}
return hour;
}
_timeSelected(value) {
if (value && !this._timeAdapter.sameTime(value, this.selected)) {
this.selectedChange.emit(value);
}
this._userSelection.emit(value);
}
/** Sets min hour. */
_setMinHour() {
if (!this.minTime) {
return;
}
const minHour = this._timeAdapter.getHour(this.minTime);
this.availableHours = this.availableHours.filter((h) => h >= minHour);
}
/** Sets max hour. */
_setMaxHour() {
if (!this.maxTime) {
return;
}
const maxHour = this._timeAdapter.getHour(this.maxTime);
this.availableHours = this.availableHours.filter((h) => h <= maxHour);
}
/** Sets min minute. */
_setMinMinute() {
if (!this.selected || !this.minTime) {
return;
}
const selectedHour = this._timeAdapter.getHour(this.selected);
const minHour = this._timeAdapter.getHour(this.minTime);
const minMinute = selectedHour > minHour ? 0 : this._timeAdapter.getMinute(this.minTime);
this.availableMinutes = this.availableMinutes.filter((minute) => minute >= minMinute);
if (selectedHour < minHour) {
this.availableMinutes = [];
}
}
/** Sets max minute. */
_setMaxMinute() {
if (!this.selected || !this.maxTime) {
return;
}
const selectedHour = this._timeAdapter.getHour(this.selected);
const maxHour = this._timeAdapter.getHour(this.maxTime);
const maxMinute = selectedHour < maxHour ? 59 : this._timeAdapter.getMinute(this.maxTime);
this.availableMinutes = this.availableMinutes.filter((minute) => minute <= maxMinute);
if (selectedHour > maxHour) {
this.availableMinutes = [];
}
}
/** Sets disabled period. */
_setDisabledPeriod() {
if (this.minTime) {
const minHour = this._timeAdapter.getHour(this.minTime);
if (minHour >= 12) {
this.disabledPeriod = 'am';
}
}
if (this.maxTime) {
const maxHour = this._timeAdapter.getHour(this.maxTime);
const maxMinute = this._timeAdapter.getHour(this.maxTime);
if (maxHour < 12 || (maxHour === 12 && maxMinute === 0)) {
this.disabledPeriod = 'pm';
}
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimeFaceBase, deps: [{ token: TimeAdapter, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.1", type: MatTimeFaceBase, isStandalone: true, inputs: { selected: "selected", minTime: "minTime", maxTime: "maxTime", minuteInterval: "minuteInterval", isMeridiem: "isMeridiem", color: "color" }, outputs: { _userSelection: "_userSelection", selectedChange: "selectedChange" }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimeFaceBase, decorators: [{
type: Directive
}], ctorParameters: () => [{ type: TimeAdapter, decorators: [{
type: Optional
}] }], propDecorators: { selected: [{
type: Input
}], minTime: [{
type: Input
}], maxTime: [{
type: Input
}], minuteInterval: [{
type: Input
}], isMeridiem: [{
type: Input
}], color: [{
type: Input
}], _userSelection: [{
type: Output
}], selectedChange: [{
type: Output
}] } });
function withZeroPrefix(value) {
return value < 10 ? `0${value}` : `${value}`;
}
function withZeroPrefixMeridiem(value, isMeridiem) {
const newValue = isMeridiem && value === 0 ? 12 : value;
return withZeroPrefix(newValue);
}
const DIGIT_KEYS = Array.from({ length: 10 }, (_, i) => `${i}`);
const SPECIAL_KEYS = ['Backspace', 'Delete', 'ArrowLeft', 'ArrowRight', 'Tab'];
class MatTimeInputBase {
get value() {
return this._value;
}
set value(value) {
this._value = value;
if (!this.hasFocus) {
this.setInputValue(this._value);
}
// we need timeout here to set placeholder first time
setTimeout(() => {
this.setInputPlaceholder(this._value);
}, 0);
}
_keydown(event) {
const isAllow = (DIGIT_KEYS.includes(event.key) && !event.shiftKey) ||
SPECIAL_KEYS.includes(event.code);
if (!isAllow) {
event.preventDefault();
}
}
get inputElement() {
return this.element.nativeElement;
}
get hasFocus() {
return this.element?.nativeElement === this._document.activeElement;
}
constructor(element, _cdr, _document) {
this.element = element;
this._cdr = _cdr;
this._document = _document;
this.timeChanged = new EventEmitter();
}
focus() {
this.setInputValue(null);
}
blur() {
const isNumber = !isNaN(Number(this.inputElement.value));
const value = this._formatValue(isNumber ? Number(this.inputElement.value || this._value) : this.value);
this.setInputValue(value);
this.setInputPlaceholder(value);
this.timeChanged.emit(value);
}
setInputValue(value) {
if (value !== null) {
this.inputElement.value = this._withZeroPrefix(value);
}
else {
this.inputElement.value = '';
}
this._cdr.markForCheck();
}
setInputPlaceholder(value) {
this.inputElement.placeholder = this._withZeroPrefix(value);
this._cdr.markForCheck();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimeInputBase, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.1", type: MatTimeInputBase, isStandalone: true, inputs: { value: "value" }, outputs: { timeChanged: "timeChanged" }, host: { listeners: { "keydown": "_keydown($event)" } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimeInputBase, decorators: [{
type: Directive
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: Document, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }], propDecorators: { value: [{
type: Input
}], timeChanged: [{
type: Output
}], _keydown: [{
type: HostListener,
args: ['keydown', ['$event']]
}] } });
const visible = { transform: 'scale(1)', opacity: 1, visibility: 'visible' };
const hidden = { transform: 'scale(1.05)', opacity: 0, visibility: 'hidden' };
const enterLeaveAnimation = trigger('enterLeaveAnimation', [
transition(':enter', [
style(hidden),
animate('0.1s ease-out', style(visible)),
]),
transition(':leave', [style(visible), animate('0s ease-in', style(hidden))]),
]);
class MatTimepickerContentLayout {
constructor() {
/** Layout orientation. */
this.orientation = 'vertical';
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerContentLayout, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.1", type: MatTimepickerContentLayout, isStandalone: true, selector: "mat-timepicker-content-layout", inputs: { title: "title", orientation: "orientation" }, host: { properties: { "class.mat-timepicker-content-layout-horizontal": "orientation === \"horizontal\"", "class.mat-timepicker-content-layout-vertical": "orientation === \"vertical\"" }, classAttribute: "mat-timepicker-content-layout" }, exportAs: ["matTimepickerContent"], ngImport: i0, template: "<h6 class=\"mat-timepicker-content-layout-title\">{{ title }}</h6>\n\n<div class=\"mat-timepicker-content-layout-container\">\n <div class=\"mat-timepicker-content-layout-values\">\n <div class=\"mat-timepicker-content-layout-hours\">\n <ng-content select=\"[hours]\"></ng-content>\n </div>\n <span class=\"mat-timepicker-content-layout-separator\">:</span>\n <div class=\"mat-timepicker-content-layout-minutes\">\n <ng-content select=\"[minutes]\"></ng-content>\n </div>\n\n <ng-content select=\"[mat-time-period]\"></ng-content>\n </div>\n\n <ng-content></ng-content>\n</div>\n", styles: [".mat-timepicker-content-layout-title{color:var(--mat-timepicker-content-layout-title-color, var(--mat-sys-on-surface-variant));font-size:var(--mat-timepicker-content-layout-title-font-size, 12px);font-weight:var(--mat-timepicker-content-layout-title-font-weight, var(--mat-sys-title-medium-weight))}h6.mat-timepicker-content-layout-title{margin-top:0rem;margin-bottom:1.25rem;letter-spacing:.05rem}.mat-timepicker-content-layout-values{display:flex;justify-content:center}.mat-time-period{margin-left:.75rem}.mat-timepicker-content-layout-horizontal h6.mat-timepicker-content-layout-title{margin-bottom:0}.mat-timepicker-content-layout-horizontal .mat-timepicker-content-layout-container{display:flex;gap:4rem;align-items:center}.mat-timepicker-content-layout-horizontal .mat-timepicker-content-layout-values{flex-wrap:wrap}.mat-timepicker-content-layout-horizontal .mat-time-period{margin-top:.75rem;margin-left:0}.mat-timepicker-content-layout-hours,.mat-timepicker-content-layout-minutes{width:6rem}.mat-timepicker-content-layout-separator{display:flex;justify-content:center;align-self:center;width:1.5rem;height:1.75rem;font-weight:500;font-size:var(--mat-timepicker-content-layout-separator-font-size, 3rem);content-layout-separator-line-height:var(--mat-timepicker-content-layout-title-color, 1.25rem)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerContentLayout, decorators: [{
type: Component,
args: [{ selector: 'mat-timepicker-content-layout', standalone: true, exportAs: 'matTimepickerContent', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
class: 'mat-timepicker-content-layout',
'[class.mat-timepicker-content-layout-horizontal]': 'orientation === "horizontal"',
'[class.mat-timepicker-content-layout-vertical]': 'orientation === "vertical"',
}, template: "<h6 class=\"mat-timepicker-content-layout-title\">{{ title }}</h6>\n\n<div class=\"mat-timepicker-content-layout-container\">\n <div class=\"mat-timepicker-content-layout-values\">\n <div class=\"mat-timepicker-content-layout-hours\">\n <ng-content select=\"[hours]\"></ng-content>\n </div>\n <span class=\"mat-timepicker-content-layout-separator\">:</span>\n <div class=\"mat-timepicker-content-layout-minutes\">\n <ng-content select=\"[minutes]\"></ng-content>\n </div>\n\n <ng-content select=\"[mat-time-period]\"></ng-content>\n </div>\n\n <ng-content></ng-content>\n</div>\n", styles: [".mat-timepicker-content-layout-title{color:var(--mat-timepicker-content-layout-title-color, var(--mat-sys-on-surface-variant));font-size:var(--mat-timepicker-content-layout-title-font-size, 12px);font-weight:var(--mat-timepicker-content-layout-title-font-weight, var(--mat-sys-title-medium-weight))}h6.mat-timepicker-content-layout-title{margin-top:0rem;margin-bottom:1.25rem;letter-spacing:.05rem}.mat-timepicker-content-layout-values{display:flex;justify-content:center}.mat-time-period{margin-left:.75rem}.mat-timepicker-content-layout-horizontal h6.mat-timepicker-content-layout-title{margin-bottom:0}.mat-timepicker-content-layout-horizontal .mat-timepicker-content-layout-container{display:flex;gap:4rem;align-items:center}.mat-timepicker-content-layout-horizontal .mat-timepicker-content-layout-values{flex-wrap:wrap}.mat-timepicker-content-layout-horizontal .mat-time-period{margin-top:.75rem;margin-left:0}.mat-timepicker-content-layout-hours,.mat-timepicker-content-layout-minutes{width:6rem}.mat-timepicker-content-layout-separator{display:flex;justify-content:center;align-self:center;width:1.5rem;height:1.75rem;font-weight:500;font-size:var(--mat-timepicker-content-layout-separator-font-size, 3rem);content-layout-separator-line-height:var(--mat-timepicker-content-layout-title-color, 1.25rem)}\n"] }]
}], propDecorators: { title: [{
type: Input
}], orientation: [{
type: Input
}] } });
class MatTimePeriod {
/** Whether the time period is vertically aligned. */
get vertical() {
return this._vertical;
}
set vertical(value) {
this._vertical = coerceBooleanProperty(value);
}
get period() {
return this._period;
}
set period(value) {
this._period = value || 'am';
}
get disabledPeriod() {
return this._disabledPeriod;
}
set disabledPeriod(value) {
this._disabledPeriod = value;
}
constructor(_intl) {
this._intl = _intl;
this._vertical = true;
this._period = 'am';
this._disabledPeriod = null;
this.periodChanged = new EventEmitter();
}
setPeriod(event, period) {
event.preventDefault();
this.period = period;
this.periodChanged.emit(period);
}
_isPeriodDisabled(period) {
if (!this.disabledPeriod) {
return false;
}
return this.disabledPeriod === period;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimePeriod, deps: [{ token: MatTimepickerIntl }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.1", type: MatTimePeriod, isStandalone: true, selector: "mat-time-period", inputs: { vertical: "vertical", period: "period", disabledPeriod: "disabledPeriod" }, outputs: { periodChanged: "periodChanged" }, host: { properties: { "class.mat-time-period-vertical": "vertical", "class.mat-time-period-horizontal": "!vertical", "attr.aria-orientation": "vertical ? \"vertical\" : \"horizontal\"" }, classAttribute: "mat-time-period" }, ngImport: i0, template: "<div\n tabindex=\"0\"\n class=\"mat-time-period-item\"\n matRipple\n [class.mat-time-period-item-active]=\"period === 'am'\"\n [class.mat-time-period-item-disabled]=\"_isPeriodDisabled('am')\"\n (click)=\"setPeriod($event, 'am')\"\n (keydown.space)=\"setPeriod($event, 'am')\"\n>\n {{ _intl.am }}\n</div>\n<mat-divider [vertical]=\"!vertical\"></mat-divider>\n<div\n tabindex=\"0\"\n class=\"mat-time-period-item\"\n matRipple\n [class.mat-time-period-item-active]=\"period === 'pm'\"\n [class.mat-time-period-item-disabled]=\"_isPeriodDisabled('pm')\"\n (click)=\"setPeriod($event, 'pm')\"\n (keydown.space)=\"setPeriod($event, 'pm')\"\n>\n {{ _intl.pm }}\n</div>\n", styles: [".mat-time-period{display:flex;text-align:center;border-width:1px;border-style:solid;border-radius:.25rem;box-sizing:border-box;border-color:var(--mat-timepicker-time-period-border-color, var(--mat-sys-outline))}.mat-time-period-vertical{flex-direction:column;width:3.25rem;height:4.5rem}.mat-time-period-vertical .mat-time-period-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.mat-time-period-vertical .mat-time-period-item:last-child{border-bottom-left-radius:inherit;border-bottom-right-radius:inherit}.mat-time-period-horizontal{flex-direction:row;max-width:13.5rem;width:100%;height:2.5rem}.mat-time-period-horizontal .mat-time-period-item:first-child{border-top-left-radius:inherit;border-bottom-left-radius:inherit}.mat-time-period-horizontal .mat-time-period-item:last-child{border-top-right-radius:inherit;border-bottom-right-radius:inherit}.mat-time-period-item{display:flex;flex-direction:column;justify-content:center;flex-grow:1;height:100%;font-size:.875rem;font-weight:500;cursor:pointer}.mat-time-period-item-active{color:var(--mat-timepicker-time-period-active-text-color, var(--mat-sys-on-tertiary-container));background-color:var(--mat-timepicker-time-period-active-background-color, var(--mat-sys-tertiary-container))}.mat-time-period-item-disabled{pointer-events:none;color:var(--mat-timepicker-time-period-disabled-text-color, var(--mat-sys-on-surface-variant));background-color:var(--mat-timepicker-time-period-disabled-background-color, color-mix(in srgb, var(--mat-sys-on-surface) 20%, transparent))}\n"], dependencies: [{ kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i2$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatRippleModule }, { kind: "directive", type: i3.MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimePeriod, decorators: [{
type: Component,
args: [{ selector: 'mat-time-period', standalone: true, imports: [MatDividerModule, MatRippleModule], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
class: 'mat-time-period',
'[class.mat-time-period-vertical]': 'vertical',
'[class.mat-time-period-horizontal]': '!vertical',
'[attr.aria-orientation]': 'vertical ? "vertical" : "horizontal"',
}, template: "<div\n tabindex=\"0\"\n class=\"mat-time-period-item\"\n matRipple\n [class.mat-time-period-item-active]=\"period === 'am'\"\n [class.mat-time-period-item-disabled]=\"_isPeriodDisabled('am')\"\n (click)=\"setPeriod($event, 'am')\"\n (keydown.space)=\"setPeriod($event, 'am')\"\n>\n {{ _intl.am }}\n</div>\n<mat-divider [vertical]=\"!vertical\"></mat-divider>\n<div\n tabindex=\"0\"\n class=\"mat-time-period-item\"\n matRipple\n [class.mat-time-period-item-active]=\"period === 'pm'\"\n [class.mat-time-period-item-disabled]=\"_isPeriodDisabled('pm')\"\n (click)=\"setPeriod($event, 'pm')\"\n (keydown.space)=\"setPeriod($event, 'pm')\"\n>\n {{ _intl.pm }}\n</div>\n", styles: [".mat-time-period{display:flex;text-align:center;border-width:1px;border-style:solid;border-radius:.25rem;box-sizing:border-box;border-color:var(--mat-timepicker-time-period-border-color, var(--mat-sys-outline))}.mat-time-period-vertical{flex-direction:column;width:3.25rem;height:4.5rem}.mat-time-period-vertical .mat-time-period-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.mat-time-period-vertical .mat-time-period-item:last-child{border-bottom-left-radius:inherit;border-bottom-right-radius:inherit}.mat-time-period-horizontal{flex-direction:row;max-width:13.5rem;width:100%;height:2.5rem}.mat-time-period-horizontal .mat-time-period-item:first-child{border-top-left-radius:inherit;border-bottom-left-radius:inherit}.mat-time-period-horizontal .mat-time-period-item:last-child{border-top-right-radius:inherit;border-bottom-right-radius:inherit}.mat-time-period-item{display:flex;flex-direction:column;justify-content:center;flex-grow:1;height:100%;font-size:.875rem;font-weight:500;cursor:pointer}.mat-time-period-item-active{color:var(--mat-timepicker-time-period-active-text-color, var(--mat-sys-on-tertiary-container));background-color:var(--mat-timepicker-time-period-active-background-color, var(--mat-sys-tertiary-container))}.mat-time-period-item-disabled{pointer-events:none;color:var(--mat-timepicker-time-period-disabled-text-color, var(--mat-sys-on-surface-variant));background-color:var(--mat-timepicker-time-period-disabled-background-color, color-mix(in srgb, var(--mat-sys-on-surface) 20%, transparent))}\n"] }]
}], ctorParameters: () => [{ type: MatTimepickerIntl }], propDecorators: { vertical: [{
type: Input
}], period: [{
type: Input
}], disabledPeriod: [{
type: Input
}], periodChanged: [{
type: Output
}] } });
class MatClockDials extends MatTimeFaceBase {
constructor(_intl, _timeAdapter, _ngZone, _elementRef, _cdr) {
super(_timeAdapter);
this._intl = _intl;
this._ngZone = _ngZone;
this._elementRef = _elementRef;
this._cdr = _cdr;
this.isHoursView = true;
/** Specifies the view of clock dial. */
this._view = new BehaviorSubject('hours');
this._viewSubscription = Subscription.EMPTY;
}
ngOnInit() {
this._viewSubscription = this._view.subscribe((view) => (this.isHoursView = view === 'hours'));
}
ngOnDestroy() {
this._viewSubscription?.unsubscribe();
this._viewSubscription = null;
}
/** Changes clock dial view. */
onViewChange(event, view) {
event.preventDefault();
this._view.next(view);
}
focusActiveCell() {
this._ngZone.runOutsideAngular(() => {
this._ngZone.onStable.pipe(take(1)).subscribe(() => {
const activeCell = this._elementRef.nativeElement.querySelector('.mat-timepicker-content .mat-clock-dial-cell-active');
if (activeCell) {
activeCell.focus();
return;
}
const activePoint = this._elementRef.nativeElement.querySelector('.mat-timepicker-content .mat-clock-dial-hand-point');
if (activePoint) {
// if no active cell we need to focus a small dot
activePoint.focus();
}
});
});
}
_withZeroPrefix(value) {
if (value === 0) {
return '00';
}
return withZeroPrefixMeridiem(value, this.isMeridiem);
}
_onMinuteSelected(minute) {
super._onMinuteSelected(minute);
this._cdr.detectChanges();
}
/** Handles hour selection. */
_onHourChanged({ hour, changeView = false, }) {
if (changeView) {
this._view.next('minutes');
}
this._onHourSelected(hour);
this._cdr.detectChanges();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatClockDials, deps: [{ token: MatTimepickerIntl }, { token: TimeAdapter, optional: true }, { token: i0.NgZone }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.1", type: MatClockDials, isStandalone: true, selector: "mat-clock-dials", inputs: { orientation: "orientation", touchUi: "touchUi" }, host: { attributes: { "role": "dial" }, classAttribute: "mat-clock-dials" }, exportAs: ["matClockDials"], usesInheritance: true, ngImport: i0, template: "<mat-timepicker-content-layout [title]=\"_intl.dialsTitle\" [orientation]=\"orientation\">\n <div\n tabindex=\"0\"\n class=\"mat-clock-dial-value\"\n hours\n [class.mat-clock-dial-value-active]=\"isHoursView\"\n (click)=\"onViewChange($event, 'hours')\"\n (keydown.space)=\"onViewChange($event, 'hours')\"\n >\n {{ _withZeroPrefix(selectedHour) }}\n </div>\n <div\n tabindex=\"0\"\n class=\"mat-clock-dial-value\"\n minutes\n [class.mat-clock-dial-value-active]=\"!isHoursView\"\n (click)=\"onViewChange($event, 'minutes')\"\n (keydown.space)=\"onViewChange($event, 'minutes')\"\n >\n {{ _withZeroPrefix(selectedMinute) }}\n </div>\n\n <ng-template mat-time-period [ngIf]=\"isMeridiem\">\n <mat-time-period\n [period]=\"period\"\n [disabledPeriod]=\"disabledPeriod\"\n [vertical]=\"orientation === 'vertical'\"\n (periodChanged)=\"_onPeriodChanged($event)\"\n ></mat-time-period>\n </ng-template>\n\n <div\n class=\"mat-clock-dial-faces\"\n [class.mat-clock-dial-faces-horizontal]=\"orientation === 'horizontal'\"\n >\n @if (isHoursView) {\n <mat-hours-clock-dial\n [@enterLeaveAnimation]\n [color]=\"color\"\n [selectedHour]=\"selectedHour\"\n [isMeridiem]=\"isMeridiem\"\n [availableHours]=\"_getAvailableHours()\"\n [touchUi]=\"touchUi\"\n (selectedChange)=\"_onHourChanged($event)\"\n (keydown)=\"_onKeydown($event, 'hour')\"\n ></mat-hours-clock-dial>\n }\n\n @if (!isHoursView) {\n <mat-minutes-clock-dial\n [@enterLeaveAnimation]\n [color]=\"color\"\n [selectedMinute]=\"selectedMinute\"\n [interval]=\"minuteInterval\"\n [availableMinutes]=\"availableMinutes\"\n [touchUi]=\"touchUi\"\n (selectedChange)=\"_onMinuteSelected($event)\"\n (keydown)=\"_onKeydown($event, 'minute')\"\n ></mat-minutes-clock-dial>\n }\n </div>\n</mat-timepicker-content-layout>\n", styles: [".mat-clock-dial-values{display:flex;width:100%}.mat-clock-dial-value{display:flex;align-items:center;justify-content:center;height:4.5rem;border-radius:.25rem;cursor:pointer;background-color:var(--mat-timepicker-clock-dial-value-background-color, var(--mat-sys-surface-container-highest));font-family:var(--mat-timepicker-clock-dial-value-font-family, var(--mat-sys-body-medium-font));font-size:var(--mat-timepicker-clock-dial-value-font-size, 2rem);letter-spacing:var(--mat-timepicker-clock-dial-value-letter-spacing, .5px)}.mat-clock-dial-value.mat-clock-dial-value-active{color:var(--mat-timepicker-clock-dial-value-active-text-color, var(--mat-sys-on-surface-variant));background-color:var(--mat-timepicker-clock-dial-value-active-background-color, var(--mat-sys-primary-container))}.mat-clock-dial-faces{margin-top:2.25rem}.mat-clock-dial-faces.mat-clock-dial-faces-horizontal{margin-top:0}.mat-clock-dial-cell.mat-clock-dial-cell-disabled:hover{cursor:default}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: MatTimepickerContentLayout, selector: "mat-timepicker-content-layout", inputs: ["title", "orientation"], exportAs: ["matTimepickerContent"] }, { kind: "component", type: MatHoursClockDial, selector: "mat-hours-clock-dial", inputs: ["selectedHour", "isMeridiem", "availableHours", "color", "touchUi"], outputs: ["selectedChange"], exportAs: ["matHoursClockDial"] }, { kind: "component", type: MatMinutesClockDial, selector: "mat-minutes-clock-dial", inputs: ["selectedMinute", "interval", "availableMinutes", "color", "touchUi"], outputs: ["selectedChange"], exportAs: ["matMinutesClockDial"] }, { kind: "component", type: MatTimePeriod, selector: "mat-time-period", inputs: ["vertical", "period", "disabledPeriod"], outputs: ["periodChanged"] }], animations: [enterLeaveAnimation], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatClockDials, decorators: [{
type: Component,
args: [{ selector: 'mat-clock-dials', standalone: true, imports: [
CommonModule,
MatTimepickerContentLayout,
MatHoursClockDial,
MatMinutesClockDial,
MatTimePeriod,
], exportAs: 'matClockDials', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
role: 'dial',
class: 'mat-clock-dials',
}, animations: [enterLeaveAnimation], template: "<mat-timepicker-content-layout [title]=\"_intl.dialsTitle\" [orientation]=\"orientation\">\n <div\n tabindex=\"0\"\n class=\"mat-clock-dial-value\"\n hours\n [class.mat-clock-dial-value-active]=\"isHoursView\"\n (click)=\"onViewChange($event, 'hours')\"\n (keydown.space)=\"onViewChange($event, 'hours')\"\n >\n {{ _withZeroPrefix(selectedHour) }}\n </div>\n <div\n tabindex=\"0\"\n class=\"mat-clock-dial-value\"\n minutes\n [class.mat-clock-dial-value-active]=\"!isHoursView\"\n (click)=\"onViewChange($event, 'minutes')\"\n (keydown.space)=\"onViewChange($event, 'minutes')\"\n >\n {{ _withZeroPrefix(selectedMinute) }}\n </div>\n\n <ng-template mat-time-period [ngIf]=\"isMeridiem\">\n <mat-time-period\n [period]=\"period\"\n [disabledPeriod]=\"disabledPeriod\"\n [vertical]=\"orientation === 'vertical'\"\n (periodChanged)=\"_onPeriodChanged($event)\"\n ></mat-time-period>\n </ng-template>\n\n <div\n class=\"mat-clock-dial-faces\"\n [class.mat-clock-dial-faces-horizontal]=\"orientation === 'horizontal'\"\n >\n @if (isHoursView) {\n <mat-hours-clock-dial\n [@enterLeaveAnimation]\n [color]=\"color\"\n [selectedHour]=\"selectedHour\"\n [isMeridiem]=\"isMeridiem\"\n [availableHours]=\"_getAvailableHours()\"\n [touchUi]=\"touchUi\"\n (selectedChange)=\"_onHourChanged($event)\"\n (keydown)=\"_onKeydown($event, 'hour')\"\n ></mat-hours-clock-dial>\n }\n\n @if (!isHoursView) {\n <mat-minutes-clock-dial\n [@enterLeaveAnimation]\n [color]=\"color\"\n [selectedMinute]=\"selectedMinute\"\n [interval]=\"minuteInterval\"\n [availableMinutes]=\"availableMinutes\"\n [touchUi]=\"touchUi\"\n (selectedChange)=\"_onMinuteSelected($event)\"\n (keydown)=\"_onKeydown($event, 'minute')\"\n ></mat-minutes-clock-dial>\n }\n </div>\n</mat-timepicker-content-layout>\n", styles: [".mat-clock-dial-values{display:flex;width:100%}.mat-clock-dial-value{display:flex;align-items:center;justify-content:center;height:4.5rem;border-radius:.25rem;cursor:pointer;background-color:var(--mat-timepicker-clock-dial-value-background-color, var(--mat-sys-surface-container-highest));font-family:var(--mat-timepicker-clock-dial-value-font-family, var(--mat-sys-body-medium-font));font-size:var(--mat-timepicker-clock-dial-value-font-size, 2rem);letter-spacing:var(--mat-timepicker-clock-dial-value-letter-spacing, .5px)}.mat-clock-dial-value.mat-clock-dial-value-active{color:var(--mat-timepicker-clock-dial-value-active-text-color, var(--mat-sys-on-surface-variant));background-color:var(--mat-timepicker-clock-dial-value-active-background-color, var(--mat-sys-primary-container))}.mat-clock-dial-faces{margin-top:2.25rem}.mat-clock-dial-faces.mat-clock-dial-faces-horizontal{margin-top:0}.mat-clock-dial-cell.mat-clock-dial-cell-disabled:hover{cursor:default}\n"] }]
}], ctorParameters: () => [{ type: MatTimepickerIntl }, { type: TimeAdapter, decorators: [{
type: Optional
}] }, { type: i0.NgZone }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }], propDecorators: { orientation: [{
type: Input
}], touchUi: [{
type: Input
}] } });
class MatHourInput extends MatTimeInputBase {
get availableHours() {
return this._availableHours;
}
set availableHours(value) {
this._availableHours = value;
}
constructor(element, _cdr, _document) {
super(element, _cdr, _document);
this._availableHours = [];
}
_withZeroPrefix(value) {
return withZeroPrefixMeridiem(value, this.isMeridiem);
}
_formatValue(hour) {
const getValue = () => {
if (this.isMeridiem) {
if (hour === 0 || hour === 24) {
return 12;
}
}
if (hour === 24) {
return 0;
}
return this.isMeridiem && hour > 12 ? hour - 12 : hour;
};
const value = getValue();
if (this.isMeridiem) {
if (!this.availableHours.length) {
return this.value;
}
if (value === 12 && this.availableHours.includes(12)) {
return 12;
}
if (value === 12 && !this.availableHours.includes(12)) {
return Math.min(...this.availableHours);
}
if (value >= 1 && value < 12) {
// the last item is max becuase 12 at the beginning is kinda "min"
const maxHour = this.availableHours[this.availableHours.length - 1];
return Math.min(Math.max(value, Math.min(...this.availableHours)), maxHour);
}
}
return Math.min(Math.max(value, Math.min(...this.availableHours)), Math.max(...this.availableHours));
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatHourInput, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.1", type: MatHourInput, isStandalone: true, selector: "input[matHourInput]", inputs: { availableHours: "availableHours", isMeridiem: "isMeridiem" }, host: { listeners: { "focus": "focus($event)", "blur": "blur($event)" }, classAttribute: "mat-time-input" }, exportAs: ["matTimeInput"], usesInheritance: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatHourInput, decorators: [{
type: Directive,
args: [{
selector: 'input[matHourInput]',
standalone: true,
exportAs: 'matTimeInput',
host: {
class: 'mat-time-input',
'(focus)': 'focus($event)',
'(blur)': 'blur($event)',
},
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: Document, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }], propDecorators: { availableHours: [{
type: Input
}], isMeridiem: [{
type: Input
}] } });
class MatMinuteInput extends MatTimeInputBase {
/** Step over minutes. */
get interval() {
return this._interval;
}
set interval(value) {
this._interval = coerceNumberProperty(value) || 1;
}
get availableMinutes() {
return this._availableMinutes;
}
set availableMinutes(value) {
this._availableMinutes = value;
}
constructor(element, _cdr, _document) {
super(element, _cdr, _document);
this._interval = 1;
this._availableMinutes = [];
}
_withZeroPrefix(value) {
return withZeroPrefix(value);
}
_formatValue(value) {
if (!this.availableMinutes.length) {
return this.value;
}
const roundedValue = Math.round(value / this.interval) * this.interval;
return Math.min(Math.max(roundedValue, Math.min(...this.availableMinutes)), Math.max(...this.availableMinutes));
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatMinuteInput, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.1", type: MatMinuteInput, isStandalone: true, selector: "input[matMinuteInput]", inputs: { interval: "interval", availableMinutes: "availableMinutes" }, host: { listeners: { "focus": "focus($event)", "blur": "blur($event)" }, classAttribute: "mat-time-input" }, exportAs: ["matTimeInput"], usesInheritance: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatMinuteInput, decorators: [{
type: Directive,
args: [{
selector: 'input[matMinuteInput]',
standalone: true,
exportAs: 'matTimeInput',
host: {
class: 'mat-time-input',
'(focus)': 'focus($event)',
'(blur)': 'blur($event)',
},
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: Document, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }], propDecorators: { interval: [{
type: Input
}], availableMinutes: [{
type: Input
}] } });
class MatTimeInputs extends MatTimeFaceBase {
constructor(_intl, _timeAdapter, _ngZone, _elementRef) {
super(_timeAdapter);
this._intl = _intl;
this._ngZone = _ngZone;
this._elementRef = _elementRef;
/**
* Using for skipping that focus shouldn't be moved to the active cell on the next tick.
* We need to use it to avoid focusing input for input mode.
*/
this._skipNextTickFocus = false;
}
focusActiveCell() {
this._ngZone.runOutsideAngular(() => {
this._ngZone.onStable.pipe(take(1)).subscribe(() => {
const activeCell = this._elementRef.nativeElement.querySelector('.mat-timepicker-content input');
if (activeCell && !this._skipNextTickFocus) {
activeCell.focus();
this._skipNextTickFocus = true;
}
});
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimeInputs, deps: [{ token: MatTimepickerIntl }, { token: TimeAdapter, optional: true }, { token: i0.NgZone }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.1", type: MatTimeInputs, isStandalone: true, selector: "mat-time-inputs", host: { classAttribute: "mat-time-inputs" }, usesInheritance: true, ngImport: i0, template: "<mat-timepicker-content-layout [title]=\"_intl.inputsTitle\">\n <mat-form-field\n class=\"mat-time-inputs-field\"\n appearance=\"outline\"\n hours\n [color]=\"color\"\n >\n <input\n type=\"text\"\n inputmode=\"numeric\"\n maxlength=\"2\"\n matInput\n matHourInput\n [isMeridiem]=\"isMeridiem\"\n [value]=\"selectedHour\"\n [availableHours]=\"_getAvailableHours()\"\n (timeChanged)=\"_onHourSelected($event)\"\n (keydown)=\"_onKeydown($event, 'hour')\"\n />\n <mat-hint>{{_intl.hourInputHint}}</mat-hint>\n </mat-form-field>\n <mat-form-field\n class=\"mat-time-inputs-field\"\n appearance=\"outline\"\n minutes\n [color]=\"color\"\n >\n <input\n type=\"text\"\n inputmode=\"numeric\"\n maxlength=\"2\"\n matInput\n matMinuteInput\n [value]=\"selectedMinute\"\n [interval]=\"minuteInterval\"\n [availableMinutes]=\"availableMinutes\"\n (timeChanged)=\"_onMinuteSelected($event)\"\n (keydown)=\"_onKeydown($event, 'minute')\"\n />\n <mat-hint>{{_intl.minuteInputHint}}</mat-hint>\n </mat-form-field>\n\n <ng-template mat-time-period [ngIf]=\"isMeridiem\">\n <mat-time-period\n [period]=\"period\"\n [disabledPeriod]=\"disabledPeriod\"\n (periodChanged)=\"_onPeriodChanged($event)\"\n ></mat-time-period>\n </ng-template>\n</mat-timepicker-content-layout>\n", styles: [".mat-time-inputs{display:block}.mat-time-inputs .mat-timepicker-content-layout-separator{margin-top:-1.5rem}.mat-time-inputs-field{display:block}.mat-time-inputs-field.mat-form-field-appearance-outline .mat-mdc-form-field-flex{margin:0}.mat-time-inputs-field.mat-form-field-appearance-outline .mat-mdc-text-field-wrapper{top:0;margin:0;background-color:var(--mat-timepicker-time-inputs-field-background-color, var(--mat-sys-surface-container-highest))}.mat-time-inputs-field.mat-form-field-appearance-outline:not(.mat-focused) .mdc-notched-outline__leading,.mat-time-inputs-field.mat-form-field-appearance-outline:not(.mat-focused) .mdc-notched-outline__notch,.mat-time-inputs-field.mat-form-field-appearance-outline:not(.mat-focused) .mdc-notched-outline__trailing{border-style:none}.mat-time-inputs-field.mat-form-field-appearance-outline .mat-mdc-form-field-subscript-wrapper{margin-top:.75rem;line-height:1;letter-spacing:.05rem}.mat-time-inputs-field.mat-form-field-appearance-outline .mat-mdc-form-field-subscript-wrapper .mat-mdc-form-field-hint-wrapper{padding-left:0}.mat-time-inputs-field.mat-form-field-appearance-outline input.mat-mdc-input-element{font-size:var(--mat-timepicker-time-inputs-field-font-size, 2rem);line-height:var(--mat-timepicker-time-inputs-field-line-height, 1.25)}.mat-time-inputs-field .mat-mdc-form-field-bottom-align:before{height:0}.mat-time-inputs-field .mat-mdc-form-field-infix{border-top:none;text-align:center}.mat-time-inputs-field input.mat-mdc-input-element{margin-top:0;text-align:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: MatTimepickerContentLayout, selector: "mat-timepicker-content-layout", inputs: ["title", "orientation"], exportAs: ["matTimepickerContent"] }, { kind: "directive", type: MatHourInput, selector: "input[matHourInput]", inputs: ["availableHours", "isMeridiem"], exportAs: ["matTimeInput"] }, { kind: "directive", type: MatMinuteInput, selector: "input[matMinuteInput]", inputs: ["interval", "availableMinutes"], exportAs: ["matTimeInput"] }, { kind: "component", type: MatTimePeriod, selector: "mat-time-period", inputs: ["vertical", "period", "disabledPeriod"], outputs: ["periodChanged"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimeInputs, decorators: [{
type: Component,
args: [{ selector: 'mat-time-inputs', standalone: true, imports: [
CommonModule,
MatFormFieldModule,
MatInputModule,
MatTimepickerContentLayout,
MatHourInput,
MatMinuteInput,
MatTimePeriod,
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
class: 'mat-time-inputs',
}, template: "<mat-timepicker-content-layout [title]=\"_intl.inputsTitle\">\n <mat-form-field\n class=\"mat-time-inputs-field\"\n appearance=\"outline\"\n hours\n [color]=\"color\"\n >\n <input\n type=\"text\"\n inputmode=\"numeric\"\n maxlength=\"2\"\n matInput\n matHourInput\n [isMeridiem]=\"isMeridiem\"\n [value]=\"selectedHour\"\n [availableHours]=\"_getAvailableHours()\"\n (timeChanged)=\"_onHourSelected($event)\"\n (keydown)=\"_onKeydown($event, 'hour')\"\n />\n <mat-hint>{{_intl.hourInputHint}}</mat-hint>\n </mat-form-field>\n <mat-form-field\n class=\"mat-time-inputs-field\"\n appearance=\"outline\"\n minutes\n [color]=\"color\"\n >\n <input\n type=\"text\"\n inputmode=\"numeric\"\n maxlength=\"2\"\n matInput\n matMinuteInput\n [value]=\"selectedMinute\"\n [interval]=\"minuteInterval\"\n [availableMinutes]=\"availableMinutes\"\n (timeChanged)=\"_onMinuteSelected($event)\"\n (keydown)=\"_onKeydown($event, 'minute')\"\n />\n <mat-hint>{{_intl.minuteInputHint}}</mat-hint>\n </mat-form-field>\n\n <ng-template mat-time-period [ngIf]=\"isMeridiem\">\n <mat-time-period\n [period]=\"period\"\n [disabledPeriod]=\"disabledPeriod\"\n (periodChanged)=\"_onPeriodChanged($event)\"\n ></mat-time-period>\n </ng-template>\n</mat-timepicker-content-layout>\n", styles: [".mat-time-inputs{display:block}.mat-time-inputs .mat-timepicker-content-layout-separator{margin-top:-1.5rem}.mat-time-inputs-field{display:block}.mat-time-inputs-field.mat-form-field-appearance-outline .mat-mdc-form-field-flex{margin:0}.mat-time-inputs-field.mat-form-field-appearance-outline .mat-mdc-text-field-wrapper{top:0;margin:0;background-color:var(--mat-timepicker-time-inputs-field-background-color, var(--mat-sys-surface-container-highest))}.mat-time-inputs-field.mat-form-field-appearance-outline:not(.mat-focused) .mdc-notched-outline__leading,.mat-time-inputs-field.mat-form-field-appearance-outline:not(.mat-focused) .mdc-notched-outline__notch,.mat-time-inputs-field.mat-form-field-appearance-outline:not(.mat-focused) .mdc-notched-outline__trailing{border-style:none}.mat-time-inputs-field.mat-form-field-appearance-outline .mat-mdc-form-field-subscript-wrapper{margin-top:.75rem;line-height:1;letter-spacing:.05rem}.mat-time-inputs-field.mat-form-field-appearance-outline .mat-mdc-form-field-subscript-wrapper .mat-mdc-form-field-hint-wrapper{padding-left:0}.mat-time-inputs-field.mat-form-field-appearance-outline input.mat-mdc-input-element{font-size:var(--mat-timepicker-time-inputs-field-font-size, 2rem);line-height:var(--mat-timepicker-time-inputs-field-line-height, 1.25)}.mat-time-inputs-field .mat-mdc-form-field-bottom-align:before{height:0}.mat-time-inputs-field .mat-mdc-form-field-infix{border-top:none;text-align:center}.mat-time-inputs-field input.mat-mdc-input-element{margin-top:0;text-align:center}\n"] }]
}], ctorParameters: () => [{ type: MatTimepickerIntl }, { type: TimeAdapter, decorators: [{
type: Optional
}] }, { type: i0.NgZone }, { type: i0.ElementRef }] });
/**
* A selection model containing a time selection.
*/
class MatTimeSelectionModel {
/**
* Updates the current selection in the model.
* @param value New selection that should be assigned.
* @param source Object that triggered the selection change.
*/
updateSelection(value, source) {
const oldValue = this.selection;
this.selection = value;
this._selectionChanged.next({ selection: value, source, oldValue });
}
constructor(_adapter) {
this._adapter = _adapter;
this._selectionChanged = new Subject();
/** Emits when the selection has changed. */
this.selectionChanged = this._selectionChanged;
// this.selection = selection;
}
ngOnDestroy() {
this._selectionChanged.complete();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimeSelectionModel, deps: [{ token: TimeAdapter }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimeSelectionModel }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimeSelectionModel, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: TimeAdapter }] });
/**
* A selection model that contains a single time.
*/
class MatSingleTimeSelectionModel extends MatTimeSelectionModel {
constructor(adapter) {
super(adapter);
}
/**
* Adds a time to the current selection. In the case of a single time selection, the added time
* simply overwrites the previous selection
*/
add(time) {
super.updateSelection(time, this);
}
/** Clones the selection model. */
clone() {
const clone = new MatSingleTimeSelectionModel(this._adapter);
clone.updateSelection(this.selection, this);
return clone;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatSingleTimeSelectionModel, deps: [{ token: TimeAdapter }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatSingleTimeSelectionModel }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatSingleTimeSelectionModel, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: TimeAdapter }] });
function MAT_SINGLE_TIME_SELECTION_MODEL_FACTORY(parent, adapter) {
return parent || new MatSingleTimeSelectionModel(adapter);
}
/**
* Used to provide a single selection model to a component.
*/
const MAT_SINGLE_TIME_SELECTION_MODEL_PROVIDER = {
provide: MatTimeSelectionModel,
deps: [
[new Optional(), new SkipSelf(), MatSingleTimeSelectionModel],
TimeAdapter,
],
useFactory: MAT_SINGLE_TIME_SELECTION_MODEL_FACTORY,
};
class MatTimepickerContent {
constructor(intl, _globalModel, _changeDetectorRef) {
this._globalModel = _globalModel;
this._changeDetectorRef = _changeDetectorRef;
/** Portal with projected action buttons. */
this._actionsPortal = null;
/** Whether there is an in-progress animation. */
this._isAnimating = false;
/** Emits when an animation has finished. */
this._animationDone = new Subject();
this._subscriptions = new Subscription();
this._closeButtonText = intl.closeTimepickerLabel;
}
ngOnInit() {
this._animationState =
this.timepicker.openAs === 'dialog' ? 'enter-dialog' : 'enter-dropdown';
}
ngAfterViewInit() {
this._subscriptions.add(this.timepicker.stateChanges.subscribe(() => {
this._changeDetectorRef.markForCheck();
}));
(this._dials || this._inputs)?.focusActiveCell();
}
ngOnDestroy() {
this._subscriptions.unsubscribe();
this._animationDone.complete();
}
/** Changes animation state while closing timepicker content. */
_startExitAnimation() {
this._animationState = 'void';
this._changeDetectorRef.markForCheck();
}
_handleAnimationEvent(event) {
this._isAnimating = event.phaseName === 'start';
if (!this._isAnimating) {
this._animationDone.next();
}
}
onToggleMode(mode) {
this.mode = mode;
}
_getSelected() {
return this._model?.selection;
}
/** Applies the current pending selection to the global model. */
_applyPendingSelection() {
if (this._model !== this._globalModel) {
this._globalModel.updateSelection(this._model.selection, this);
}
}
/**
* Assigns a new portal containing the timepicker actions.
* @param portal Portal with the actions to be assigned.
* @param forceRerender Whether a re-render of the portal should be triggered. This isn't
* necessary if the portal is assigned during initialization, but it may be required if it's
* added at a later point.
*/
_assignActions(portal, forceRerender) {
// As we have actions, clone the model so that we have the ability to cancel the selection.
// Note that we want to assign this as soon as possible,
// but `_actionsPortal` isn't available in the constructor so we do it in `ngOnInit`.
this._model = this._globalModel.clone();
this._actionsPortal = portal;
if (forceRerender) {
this._changeDetectorRef.detectChanges();
}
}
_handleUserSelection(event) {
const value = event;
this._model.add(value);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerContent, deps: [{ token: MatTimepickerIntl }, { token: MatTimeSelectionModel }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.1", type: MatTimepickerContent, isStandalone: true, selector: "mat-timepicker-content", host: { listeners: { "@transformPanel.start": "_handleAnimationEvent($event)", "@transformPanel.done": "_handleAnimationEvent($event)" }, properties: { "class": "color ? \"mat-\" + color : \"\"", "@transformPanel": "_animationState", "class.mat-timepicker-content-touch": "timepicker.touchUi" }, classAttribute: "mat-timepicker-content" }, viewQueries: [{ propertyName: "_dials", first: true, predicate: MatClockDials, descendants: true }, { propertyName: "_inputs", first: true, predicate: MatTimeInputs, descendants: true }], exportAs: ["matTimepickerContent"], ngImport: i0, template: "<div\n cdkTrapFocus\n role=\"dialog\"\n class=\"mat-timepicker-content-container\"\n [attr.aria-modal]=\"true\"\n [attr.aria-labelledby]=\"_dialogLabelId ?? undefined\"\n>\n @switch (mode) {\n @case ('input') {\n <mat-time-inputs\n [id]=\"timepicker.id\"\n [color]=\"color\"\n [isMeridiem]=\"isMeridiem\"\n [selected]=\"_getSelected()\"\n [minTime]=\"timepicker._getMinTime()\"\n [maxTime]=\"timepicker._getMaxTime()\"\n [minuteInterval]=\"minuteInterval\"\n (_userSelection)=\"_handleUserSelection($event)\"\n ></mat-time-inputs>\n\n <div class=\"mat-timepicker-content-actions\">\n @if (showToggleModeButton) {\n <button\n class=\"mat-time-toggle-mode-button\"\n mat-icon-button\n (click)=\"onToggleMode('dial')\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n height=\"24\"\n width=\"24\"\n viewBox=\"0 0 24 24\"\n >\n <path\n d=\"m15.175 16.625 1.475-1.45-3.6-3.6V7.1h-2.075v5.3ZM12 21.95q-2.075 0-3.887-.787-1.813-.788-3.15-2.125-1.338-1.338-2.125-3.151Q2.05 14.075 2.05 12t.788-3.887q.787-1.813 2.125-3.15Q6.3 3.625 8.113 2.837 9.925 2.05 12 2.05t3.887.787q1.813.788 3.151 2.126 1.337 1.337 2.125 3.15.787 1.812.787 3.887t-.787 3.887q-.788 1.813-2.125 3.151-1.338 1.337-3.151 2.125-1.812.787-3.887.787ZM12 12Zm0 7.8q3.225 0 5.513-2.275Q19.8 15.25 19.8 12q0-3.25-2.287-5.525Q15.225 4.2 12 4.2T6.488 6.475Q4.2 8.75 4.2 12q0 3.25 2.288 5.525Q8.775 19.8 12 19.8Z\"\n />\n </svg>\n </button>\n }\n\n <ng-template [cdkPortalOutlet]=\"_actionsPortal\"></ng-template>\n </div>\n }\n\n @case ('dial') {\n <mat-clock-dials\n [id]=\"timepicker.id\"\n [color]=\"color\"\n [isMeridiem]=\"isMeridiem\"\n [selected]=\"_getSelected()\"\n [minTime]=\"timepicker._getMinTime()\"\n [maxTime]=\"timepicker._getMaxTime()\"\n [minuteInterval]=\"minuteInterval\"\n [orientation]=\"orientation\"\n [touchUi]=\"timepicker.touchUi\"\n (_userSelection)=\"_handleUserSelection($event)\"\n ></mat-clock-dials>\n\n <div class=\"mat-timepicker-content-actions\">\n @if (showToggleModeButton) {\n <button\n class=\"mat-time-toggle-mode-button\"\n mat-icon-button\n (click)=\"onToggleMode('input')\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n height=\"24\"\n width=\"24\"\n viewBox=\"0 0 24 24\"\n >\n <path\n d=\"M4 19q-.825 0-1.412-.587Q2 17.825 2 17V7q0-.825.588-1.412Q3.175 5 4 5h16q.825 0 1.413.588Q22 6.175 22 7v10q0 .825-.587 1.413Q20.825 19 20 19Zm0-2h16V7H4v10Zm4-1h8v-2H8Zm-3-3h2v-2H5Zm3 0h2v-2H8Zm3 0h2v-2h-2Zm3 0h2v-2h-2Zm3 0h2v-2h-2ZM5 10h2V8H5Zm3 0h2V8H8Zm3 0h2V8h-2Zm3 0h2V8h-2Zm3 0h2V8h-2ZM4 17V7v10Z\"\n />\n </svg>\n </button>\n }\n\n <ng-template [cdkPortalOutlet]=\"_actionsPortal\"></ng-template>\n </div>\n }\n }\n\n <!-- Invisible close button for screen reader users. -->\n <button\n type=\"button\"\n class=\"mat-timepicker-close-button\"\n mat-raised-button\n [color]=\"color || 'primary'\"\n [class.cdk-visually-hidden]=\"!_closeButtonFocused\"\n (focus)=\"_closeButtonFocused = true\"\n (blur)=\"_closeButtonFocused = false\"\n (click)=\"timepicker.close()\"\n >\n {{ _closeButtonText }}\n </button>\n</div>\n", styles: [".mat-timepicker-content{color:var(--mat-timepicker-content-text-color, var(--mat-sys-on-surface));background-color:var(--mat-timepicker-content-background-color, var(--mat-sys-surface-container-high));border-radius:var(--mat-timepicker-content-border-radius, var(--mat-sys-corner-large))}.mat-timepicker-content-container{position:relative;display:flex;flex-direction:column;padding:1rem 1.5rem}.mat-timepicker-content-actions{display:flex;justify-content:space-between;margin-right:-1rem;margin-top:1.5rem}.mat-time-toggle-mode-button{display:flex;align-items:center;justify-content:center;width:3.25rem;height:3.25rem;margin-left:-.75rem;margin-bottom:-.25rem}.mat-time-toggle-mode-button svg{fill:var(--mat-timepicker-toggle-mode-button-color, var(--mat-sys-on-surface-variant))}button.mat-timepicker-close-button{position:absolute;top:100%;left:0;margin-top:.5rem}.ng-animating button.mat-timepicker-close-button{display:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: PortalModule }, { kind: "directive", type: i3$1.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }, { kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i4$1.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "component", type: MatTimeInputs, selector: "mat-time-inputs" }, { kind: "component", type: MatClockDials, selector: "mat-clock-dials", inputs: ["orientation", "touchUi"], exportAs: ["matClockDials"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }], animations: [
matTimepickerAnimations.transformPanel,
matTimepickerAnimations.fadeInTimepicker,
], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerContent, decorators: [{
type: Component,
args: [{ selector: 'mat-timepicker-content', standalone: true, imports: [
CommonModule,
PortalModule,
A11yModule,
MatTimeInputs,
MatClockDials,
MatButtonModule,
], exportAs: 'matTimepickerContent', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
class: 'mat-timepicker-content',
'[class]': 'color ? "mat-" + color : ""',
'[@transformPanel]': '_animationState',
'(@transformPanel.start)': '_handleAnimationEvent($event)',
'(@transformPanel.done)': '_handleAnimationEvent($event)',
'[class.mat-timepicker-content-touch]': 'timepicker.touchUi',
}, animations: [
matTimepickerAnimations.transformPanel,
matTimepickerAnimations.fadeInTimepicker,
], template: "<div\n cdkTrapFocus\n role=\"dialog\"\n class=\"mat-timepicker-content-container\"\n [attr.aria-modal]=\"true\"\n [attr.aria-labelledby]=\"_dialogLabelId ?? undefined\"\n>\n @switch (mode) {\n @case ('input') {\n <mat-time-inputs\n [id]=\"timepicker.id\"\n [color]=\"color\"\n [isMeridiem]=\"isMeridiem\"\n [selected]=\"_getSelected()\"\n [minTime]=\"timepicker._getMinTime()\"\n [maxTime]=\"timepicker._getMaxTime()\"\n [minuteInterval]=\"minuteInterval\"\n (_userSelection)=\"_handleUserSelection($event)\"\n ></mat-time-inputs>\n\n <div class=\"mat-timepicker-content-actions\">\n @if (showToggleModeButton) {\n <button\n class=\"mat-time-toggle-mode-button\"\n mat-icon-button\n (click)=\"onToggleMode('dial')\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n height=\"24\"\n width=\"24\"\n viewBox=\"0 0 24 24\"\n >\n <path\n d=\"m15.175 16.625 1.475-1.45-3.6-3.6V7.1h-2.075v5.3ZM12 21.95q-2.075 0-3.887-.787-1.813-.788-3.15-2.125-1.338-1.338-2.125-3.151Q2.05 14.075 2.05 12t.788-3.887q.787-1.813 2.125-3.15Q6.3 3.625 8.113 2.837 9.925 2.05 12 2.05t3.887.787q1.813.788 3.151 2.126 1.337 1.337 2.125 3.15.787 1.812.787 3.887t-.787 3.887q-.788 1.813-2.125 3.151-1.338 1.337-3.151 2.125-1.812.787-3.887.787ZM12 12Zm0 7.8q3.225 0 5.513-2.275Q19.8 15.25 19.8 12q0-3.25-2.287-5.525Q15.225 4.2 12 4.2T6.488 6.475Q4.2 8.75 4.2 12q0 3.25 2.288 5.525Q8.775 19.8 12 19.8Z\"\n />\n </svg>\n </button>\n }\n\n <ng-template [cdkPortalOutlet]=\"_actionsPortal\"></ng-template>\n </div>\n }\n\n @case ('dial') {\n <mat-clock-dials\n [id]=\"timepicker.id\"\n [color]=\"color\"\n [isMeridiem]=\"isMeridiem\"\n [selected]=\"_getSelected()\"\n [minTime]=\"timepicker._getMinTime()\"\n [maxTime]=\"timepicker._getMaxTime()\"\n [minuteInterval]=\"minuteInterval\"\n [orientation]=\"orientation\"\n [touchUi]=\"timepicker.touchUi\"\n (_userSelection)=\"_handleUserSelection($event)\"\n ></mat-clock-dials>\n\n <div class=\"mat-timepicker-content-actions\">\n @if (showToggleModeButton) {\n <button\n class=\"mat-time-toggle-mode-button\"\n mat-icon-button\n (click)=\"onToggleMode('input')\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n height=\"24\"\n width=\"24\"\n viewBox=\"0 0 24 24\"\n >\n <path\n d=\"M4 19q-.825 0-1.412-.587Q2 17.825 2 17V7q0-.825.588-1.412Q3.175 5 4 5h16q.825 0 1.413.588Q22 6.175 22 7v10q0 .825-.587 1.413Q20.825 19 20 19Zm0-2h16V7H4v10Zm4-1h8v-2H8Zm-3-3h2v-2H5Zm3 0h2v-2H8Zm3 0h2v-2h-2Zm3 0h2v-2h-2Zm3 0h2v-2h-2ZM5 10h2V8H5Zm3 0h2V8H8Zm3 0h2V8h-2Zm3 0h2V8h-2Zm3 0h2V8h-2ZM4 17V7v10Z\"\n />\n </svg>\n </button>\n }\n\n <ng-template [cdkPortalOutlet]=\"_actionsPortal\"></ng-template>\n </div>\n }\n }\n\n <!-- Invisible close button for screen reader users. -->\n <button\n type=\"button\"\n class=\"mat-timepicker-close-button\"\n mat-raised-button\n [color]=\"color || 'primary'\"\n [class.cdk-visually-hidden]=\"!_closeButtonFocused\"\n (focus)=\"_closeButtonFocused = true\"\n (blur)=\"_closeButtonFocused = false\"\n (click)=\"timepicker.close()\"\n >\n {{ _closeButtonText }}\n </button>\n</div>\n", styles: [".mat-timepicker-content{color:var(--mat-timepicker-content-text-color, var(--mat-sys-on-surface));background-color:var(--mat-timepicker-content-background-color, var(--mat-sys-surface-container-high));border-radius:var(--mat-timepicker-content-border-radius, var(--mat-sys-corner-large))}.mat-timepicker-content-container{position:relative;display:flex;flex-direction:column;padding:1rem 1.5rem}.mat-timepicker-content-actions{display:flex;justify-content:space-between;margin-right:-1rem;margin-top:1.5rem}.mat-time-toggle-mode-button{display:flex;align-items:center;justify-content:center;width:3.25rem;height:3.25rem;margin-left:-.75rem;margin-bottom:-.25rem}.mat-time-toggle-mode-button svg{fill:var(--mat-timepicker-toggle-mode-button-color, var(--mat-sys-on-surface-variant))}button.mat-timepicker-close-button{position:absolute;top:100%;left:0;margin-top:.5rem}.ng-animating button.mat-timepicker-close-button{display:none}\n"] }]
}], ctorParameters: () => [{ type: MatTimepickerIntl }, { type: MatTimeSelectionModel }, { type: i0.ChangeDetectorRef }], propDecorators: { _dials: [{
type: ViewChild,
args: [MatClockDials]
}], _inputs: [{
type: ViewChild,
args: [MatTimeInputs]
}] } });
const MAT_DEFAULT_ACITONS = new InjectionToken('MAT_DEFAULT_ACITONS');
/**
* Injection token that can be used to configure the
* default options for all timepickers within an app.
*/
const MAT_TIMEPICKER_DEFAULT_OPTIONS = new InjectionToken('MAT_TIMEPICKER_DEFAULT_OPTIONS');
/** Default open as used by the timepicker. */
const DEFAULT_OPEN_AS = 'popup';
/** Default mode used by the timepicker. */
const DEFAULT_MODE = 'dial';
/** Default format used by the timepicker. */
const DEFAULT_FORMAT = '12h';
/** Used to generate a unique ID for each timepicker instance. */
let timepickerUid = 0;
class MatTimepickerBase {
/** Whether the timepicker pop-up should be disabled. */
get disabled() {
return this._disabled === undefined && this.timepickerInput
? this.timepickerInput.disabled
: !!this._disabled;
}
set disabled(value) {
const newValue = coerceBooleanProperty(value);
if (newValue !== this._disabled) {
this._disabled = newValue;
this.stateChanges.next(undefined);
}
}
/** Whether the timepicker is open. */
get opened() {
return this._opened;
}
set opened(value) {
coerceBooleanProperty(value) ? this.open() : this.close();
}
/** Whether the timepicker mode which determines what the timepicker will be opened as. */
get openAs() {
return this._openAs || this._defaults?.openAs || DEFAULT_OPEN_AS;
}
set openAs(value) {
this._openAs = value;
}
/** Color palette to use on the timepicker's content. */
get color() {
return (this._color ||
this._defaults?.color ||
(this.timepickerInput
? this.timepickerInput.getThemePalette()
: undefined));
}
set color(value) {
this._color = value;
}
/** Timepicker display mode. */
get mode() {
return this._mode || this._defaults?.mode || DEFAULT_MODE;
}
set mode(value) {
this._mode = value;
}
/** Timepicker period format. */
get format() {
return this._format || this._defaults?.format || DEFAULT_FORMAT;
}
set format(value) {
this._format = value;
}
/** Show or hide toggle button between dial and input. */
get showToggleModeButton() {
return this._showToggleModeButton;
}
set showToggleModeButton(value) {
this._showToggleModeButton = value;
}
/** Step for minutes. */
get minuteInterval() {
return this._minuteInterval || this._defaults?.minuteInterval || 1;
}
set minuteInterval(value) {
this._minuteInterval = coerceNumberProperty(value);
}
/** Orientation for dial mode. */
get orientation() {
return this._orientation || this._defaults?.orientation || 'vertical';
}
set orientation(value) {
this._orientation = value;
}
/**
* Whether the timepicker UI is in touch mode. In touch mode elements are larger for bigger touch targets.
*/
get touchUi() {
return this._touchUi;
}
set touchUi(value) {
this._touchUi = coerceBooleanProperty(value);
if (value) {
this.openAs = 'dialog';
}
}
/** The minimum selectable time. */
_getMinTime() {
return this.timepickerInput && this.timepickerInput.min;
}
/** The maximum selectable time. */
_getMaxTime() {
return this.timepickerInput && this.timepickerInput.max;
}
constructor(_viewContainerRef, _overlay, _ngZone, scrollStrategy, _defaultActionsComponent, _model, _defaults) {
this._viewContainerRef = _viewContainerRef;
this._overlay = _overlay;
this._ngZone = _ngZone;
this._defaultActionsComponent = _defaultActionsComponent;
this._model = _model;
this._defaults = _defaults;
this._opened = false;
this._showToggleModeButton = true;
this._touchUi = false;
/** Preferred position of the timepicker in the X axis. */
this.xPosition = 'start';
/** Preferred position of the timepicker in the Y axis. */
this.yPosition = 'below';
/**
* Whether to restore focus to the previously-focused element when the timepicker is closed.
* Note that automatic focus restoration is an accessibility feature and it is recommended that
* you provide your own equivalent, if you decide to turn it off.
*/
this.restoreFocus = true;
/** Emits when the timepicker has been opened. */
this.openedStream = new EventEmitter();
/** Emits when the timepicker has been closed. */
this.closedStream = new EventEmitter();
/** The id for the timepicker. */
this.id = `mat-timepicker-${timepickerUid++}`;
/** Portal with projected action buttons. */
this._actionsPortal = null;
/** Emits when the timepicker's state changes. */
this.stateChanges = new Subject();
/** Unique class that will be added to the backdrop so that the test harnesses can look it up. */
this._backdropHarnessClass = `${this.id}-backdrop`;
/** The element that was focused before the timepicker was opened. */
this._focusedElementBeforeOpen = null;
this._document = inject(DOCUMENT);
this._scrollStrategy = scrollStrategy;
if (_defaults) {
this.showToggleModeButton =
_defaults.showToggleModeButton !== undefined
? _defaults.showToggleModeButton
: true;
}
}
ngOnChanges(changes) {
const positionChange = changes['xPosition'] || changes['yPosition'];
if (positionChange && !positionChange.firstChange && this._overlayRef) {
const positionStrategy = this._overlayRef.getConfig().positionStrategy;
if (positionStrategy instanceof FlexibleConnectedPositionStrategy) {
this._setConnectedPositions(positionStrategy);
if (this.opened) {
this._overlayRef.updatePosition();
}
}
}
this.stateChanges.next(undefined);
}
ngOnDestroy() {
this._destroyOverlay();
this.close();
this.stateChanges.complete();
}
/** Opens the timepicker. */
open() {
if (this._opened ||
this.disabled ||
this._componentRef?.instance._isAnimating) {
return;
}
if (!this.timepickerInput) {
throw Error('Attempted to open an MatTimepicker with no associated input.');
}
this._focusedElementBeforeOpen = _getFocusedElementPierceShadowDom();
this._openOverlay();
this._opened = true;
this.openedStream.emit();
}
/** Closes the timepicker. */
close() {
if (!this._opened || this._componentRef?.instance._isAnimating) {
return;
}
const canRestoreFocus = this.restoreFocus &&
this._focusedElementBeforeOpen &&
typeof this._focusedElementBeforeOpen.focus === 'function';
const completeClose = () => {
// The `_opened` could've been reset already if
// we got two events in quick succession.
if (this._opened) {
this._opened = false;
this.closedStream.emit();
}
};
if (this._componentRef) {
const { instance, location } = this._componentRef;
instance._startExitAnimation();
instance._animationDone.pipe(take(1)).subscribe(() => {
const activeElement = this._document.activeElement;
// Since we restore focus after the exit animation, we have to check that
// the user didn't move focus themselves inside the `close` handler.
if (canRestoreFocus &&
(!activeElement ||
activeElement === this._document.activeElement ||
location.nativeElement.contains(activeElement))) {
this._focusedElementBeforeOpen.focus();
}
this._focusedElementBeforeOpen = null;
this._destroyOverlay();
});
if (canRestoreFocus) {
setTimeout(completeClose);
}
else {
completeClose();
}
}
}
/**
* Register an input with this timepicker.
* @param input The timepicker input to register with this timepicker.
* @returns Selection model that the input should hook itself up to.
*/
registerInput(input) {
if (this.timepickerInput) {
throw Error('A MatTimepicker can only be associated with a single input.');
}
this.timepickerInput = input;
return this._model;
}
/**
* Registers a portal containing action buttons with the timepicker.
* @param portal Portal to be registered.
*/
registerActions(portal) {
if (this._actionsPortal) {
throw Error('A MatTimepicker can only be associated with a single actions row.');
}
this._actionsPortal = portal;
this._componentRef?.instance._assignActions(portal, true);
}
/**
* Removes a portal containing action buttons from the timepicker.
* @param portal Portal to be removed.
*/
removeActions(portal) {
if (portal === this._actionsPortal) {
this._actionsPortal = null;
this._componentRef?.instance._assignActions(null, true);
}
}
/** Applies the current pending selection on the overlay to the model. */
_applyPendingSelection() {
this._componentRef?.instance?._applyPendingSelection();
}
/** Forwards relevant values from the timepicker to the timepicker content inside the overlay. */
_forwardContentValues(instance) {
const defaultPortal = new ComponentPortal(this._defaultActionsComponent);
instance.timepicker = this;
instance.color = this.color;
instance.mode = this.mode;
instance.isMeridiem = this.format === '12h';
instance.showToggleModeButton = this.showToggleModeButton;
instance.minuteInterval = this.minuteInterval;
instance.orientation = this.orientation;
instance._dialogLabelId = this.timepickerInput.getOverlayLabelId();
instance._assignActions(this._actionsPortal || defaultPortal, false);
}
/** Opens the overlay with the timepicker. */
_openOverlay() {
this._destroyOverlay();
const isDialog = this.openAs === 'dialog';
const portal = new ComponentPortal(MatTimepickerContent, this._viewContainerRef);
const overlayRef = (this._overlayRef = this._overlay.create(new OverlayConfig({
positionStrategy: isDialog
? this._getDialogStrategy()
: this._getDropdownStrategy(),
hasBackdrop: true,
backdropClass: [
isDialog
? 'cdk-overlay-dark-backdrop'
: 'mat-overlay-transparent-backdrop',
this._backdropHarnessClass,
],
direction: 'ltr',
scrollStrategy: isDialog
? this._overlay.scrollStrategies.block()
: this._scrollStrategy(),
panelClass: `mat-timepicker-${this.openAs}`,
})));
this._getCloseStream(overlayRef).subscribe((event) => {
if (event) {
event.preventDefault();
}
this.close();
});
// The `preventDefault` call happens inside the timepicker as well, however focus moves into
// it inside a timeout which can give browsers a chance to fire off a keyboard event in-between
// that can scroll the page. Always block default actions of arrow keys for the
// entire overlay so the page doesn't get scrolled by accident.
overlayRef.keydownEvents().subscribe((event) => {
const keyCode = event.keyCode;
if (keyCode === UP_ARROW ||
keyCode === DOWN_ARROW ||
keyCode === PAGE_UP ||
keyCode === PAGE_DOWN) {
event.preventDefault();
}
});
this._componentRef = overlayRef.attach(portal);
this._forwardContentValues(this._componentRef.instance);
// Update the position once the timepicker has rendered. Only relevant in dropdown mode.
if (!isDialog) {
this._ngZone.onStable
.pipe(first())
.subscribe(() => overlayRef.updatePosition());
}
}
/** Destroys the current overlay. */
_destroyOverlay() {
if (this._overlayRef) {
this._overlayRef.dispose();
this._overlayRef = this._componentRef = null;
}
}
/** Gets a position strategy that will open the timepicker as a dropdown. */
_getDialogStrategy() {
return this._overlay
.position()
.global()
.centerHorizontally()
.centerVertically();
}
/** Gets a position strategy that will open the timepicker as a dropdown. */
_getDropdownStrategy() {
const strategy = this._overlay
.position()
.flexibleConnectedTo(this.timepickerInput.getConnectedOverlayOrigin())
.withTransformOriginOn('.mat-timepicker-content')
.withFlexibleDimensions(false)
.withViewportMargin(8)
.withLockedPosition();
return this._setConnectedPositions(strategy);
}
/** Sets the positions of the timepicker in dropdown mode based on the current configuration. */
_setConnectedPositions(strategy) {
const primaryX = this.xPosition === 'end' ? 'end' : 'start';
const secondaryX = primaryX === 'start' ? 'end' : 'start';
const primaryY = this.yPosition === 'above' ? 'bottom' : 'top';
const secondaryY = primaryY === 'top' ? 'bottom' : 'top';
return strategy.withPositions([
{
originX: primaryX,
originY: secondaryY,
overlayX: primaryX,
overlayY: primaryY,
},
{
originX: primaryX,
originY: primaryY,
overlayX: primaryX,
overlayY: secondaryY,
},
{
originX: secondaryX,
originY: secondaryY,
overlayX: secondaryX,
overlayY: primaryY,
},
{
originX: secondaryX,
originY: primaryY,
overlayX: secondaryX,
overlayY: secondaryY,
},
]);
}
/** Gets an observable that will emit when the overlay is supposed to be closed. */
_getCloseStream(overlayRef) {
return merge(overlayRef.backdropClick(), overlayRef.detachments(), overlayRef.keydownEvents().pipe(filter((event) => {
// Closing on alt + up is only valid when there's an input associated with the timepicker.
return ((event.keyCode === ESCAPE && !hasModifierKey(event)) ||
(this.timepickerInput &&
hasModifierKey(event, 'altKey') &&
event.keyCode === UP_ARROW));
})));
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerBase, deps: [{ token: i0.ViewContainerRef }, { token: i1$1.Overlay }, { token: i0.NgZone }, { token: MAT_TIMEPICKER_SCROLL_STRATEGY }, { token: MAT_DEFAULT_ACITONS }, { token: MatTimeSelectionModel }, { token: MAT_TIMEPICKER_DEFAULT_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "19.0.1", type: MatTimepickerBase, isStandalone: true, inputs: { disabled: "disabled", opened: "opened", openAs: "openAs", color: "color", mode: "mode", format: "format", showToggleModeButton: "showToggleModeButton", minuteInterval: "minuteInterval", orientation: "orientation", touchUi: ["touchUi", "touchUi", booleanAttribute], xPosition: "xPosition", yPosition: "yPosition", restoreFocus: ["restoreFocus", "restoreFocus", booleanAttribute] }, outputs: { openedStream: "opened", closedStream: "closed" }, usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerBase, decorators: [{
type: Directive
}], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: i1$1.Overlay }, { type: i0.NgZone }, { type: undefined, decorators: [{
type: Inject,
args: [MAT_TIMEPICKER_SCROLL_STRATEGY]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [MAT_DEFAULT_ACITONS]
}] }, { type: MatTimeSelectionModel }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [MAT_TIMEPICKER_DEFAULT_OPTIONS]
}] }], propDecorators: { disabled: [{
type: Input
}], opened: [{
type: Input
}], openAs: [{
type: Input
}], color: [{
type: Input
}], mode: [{
type: Input
}], format: [{
type: Input
}], showToggleModeButton: [{
type: Input
}], minuteInterval: [{
type: Input
}], orientation: [{
type: Input
}], touchUi: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], xPosition: [{
type: Input
}], yPosition: [{
type: Input
}], restoreFocus: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], openedStream: [{
type: Output,
args: ['opened']
}], closedStream: [{
type: Output,
args: ['closed']
}] } });
class MatTimepicker extends MatTimepickerBase {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepicker, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.1", type: MatTimepicker, isStandalone: true, selector: "mat-timepicker", host: { properties: { "class.mat-primary": "color !== \"accent\" && color !== \"warn\"", "class.mat-accent": "color === \"accent\"", "class.mat-warn": "color === \"warn\"" }, classAttribute: "mat-timepicker" }, providers: [
MAT_SINGLE_TIME_SELECTION_MODEL_PROVIDER,
{ provide: MatTimepickerBase, useExisting: MatTimepicker },
], exportAs: ["matTimepicker"], usesInheritance: true, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepicker, decorators: [{
type: Component,
args: [{
selector: 'mat-timepicker',
standalone: true,
template: '',
exportAs: 'matTimepicker',
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
host: {
class: 'mat-timepicker',
'[class.mat-primary]': 'color !== "accent" && color !== "warn"',
'[class.mat-accent]': 'color === "accent"',
'[class.mat-warn]': 'color === "warn"',
},
providers: [
MAT_SINGLE_TIME_SELECTION_MODEL_PROVIDER,
{ provide: MatTimepickerBase, useExisting: MatTimepicker },
],
}]
}] });
/**
* An event used for timepicker input and change events. We don't always have access to a native
* input or change event because the event may have been triggered by the user clicking on the
* clock popup. For consistency, we always use MatTimepickerInputEvent instead.
*/
class MatTimepickerInputEvent {
constructor(
/** Reference to the timepicker input component that emitted the event. */
target,
/** Reference to the native input element associated with the timepicker input. */
targetElement) {
this.target = target;
this.targetElement = targetElement;
this.value = this.target.value;
}
}
const TIME_FORMATS = { hour: '2-digit', minute: '2-digit' };
class MatTimepickerInputBase {
/** The value of the input. */
get value() {
return this._model
? this._getValueFromModel(this._model.selection)
: this._pendingValue;
}
set value(value) {
this._assignValueProgrammatically(value);
}
/** Whether the timepicker-input is disabled. */
get disabled() {
return !!this._disabled;
}
set disabled(value) {
const newValue = coerceBooleanProperty(value);
const element = this._elementRef.nativeElement;
if (this._disabled !== newValue) {
this._disabled = newValue;
this.stateChanges.next(undefined);
}
// We need to null check the `blur` method, because it's undefined during SSR.
// In Ivy static bindings are invoked earlier, before the element is attached to the DOM.
// This can cause an error to be thrown in some browsers (IE/Edge) which assert that the
// element has been inserted.
if (newValue && this._isInitialized && element.blur) {
// Normally, native input elements automatically blur if they turn disabled. This behavior
// is problematic, because it would mean that it triggers another change detection cycle,
// which then causes a changed after checked error if the input element was focused before.
element.blur();
}
}
constructor(_elementRef, _timeAdapter) {
this._elementRef = _elementRef;
this._timeAdapter = _timeAdapter;
/** Emits when a change event is fired on this <input>. */
this.timeChange = new EventEmitter();
/** Emits when an input event is fired on this <input>. */
this.timeInput = new EventEmitter();
/** Emits when the internal state has changed */
this.stateChanges = new Subject();
this._onTouched = () => { };
this._validatorOnChange = () => { };
this._cvaOnChange = () => { };
this._valueChangesSubscription = Subscription.EMPTY;
/** Whether the last value set on the input was valid. */
this._lastValueValid = false;
/** The form control validator for whether the input parses. */
this._parseValidator = () => {
return this._lastValueValid
? null
: { matTimepickerParse: { text: this._elementRef.nativeElement.value } };
};
/** The form control validator for the min time. */
this._minValidator = (control) => {
const controlValue = this._timeAdapter.getValidTimeOrNull(this._timeAdapter.deserialize(control.value));
const min = this._getMinTime();
return !min ||
!controlValue ||
this._timeAdapter.compareTime(min, controlValue) <= 0
? null
: { matTimepickerMin: { min, actual: controlValue } };
};
/** The form control validator for the max time. */
this._maxValidator = (control) => {
const controlValue = this._timeAdapter.getValidTimeOrNull(this._timeAdapter.deserialize(control.value));
const max = this._getMaxTime();
return !max ||
!controlValue ||
this._timeAdapter.compareTime(max, controlValue) >= 0
? null
: { matTimepickerMax: { max, actual: controlValue } };
};
}
ngOnChanges(changes) {
if (timeInputsHaveChanged(changes, this._timeAdapter)) {
this.stateChanges.next(undefined);
}
}
ngOnDestroy() {
this._valueChangesSubscription.unsubscribe();
this.stateChanges.complete();
}
/** Registers a time selection model with the input. */
_registerModel(model) {
this._model = model;
this._valueChangesSubscription.unsubscribe();
if (this._pendingValue) {
this._assignValue(this._pendingValue);
}
this._valueChangesSubscription = this._model.selectionChanged.subscribe((event) => {
if (this._shouldHandleChangeEvent(event)) {
const value = this._getValueFromModel(event.selection);
this._lastValueValid = this._isValidValue(value);
this._cvaOnChange(value);
this._onTouched();
this._formatValue(value);
this.timeInput.emit(new MatTimepickerInputEvent(this, this._elementRef.nativeElement));
this.timeChange.emit(new MatTimepickerInputEvent(this, this._elementRef.nativeElement));
}
});
}
_onInput(value) {
const lastValueWasValid = this._lastValueValid;
let time = this._timeAdapter.parse(value, TIME_FORMATS);
this._lastValueValid = this._isValidValue(time);
time = this._timeAdapter.getValidTimeOrNull(time);
const hasChanged = !this._timeAdapter.sameTime(time, this.value);
// We need to fire the CVA change event for all
// nulls, otherwise the validators won't run.
if (!time || hasChanged) {
this._cvaOnChange(time);
}
else {
// Call the CVA change handler for invalid values
// since this is what marks the control as dirty.
if (value && !this.value) {
this._cvaOnChange(time);
}
if (lastValueWasValid !== this._lastValueValid) {
this._validatorOnChange();
}
}
if (hasChanged) {
this._assignValue(time);
this.timeInput.emit(new MatTimepickerInputEvent(this, this._elementRef.nativeElement));
}
}
/** Handles change event on the input. */
_onChange() {
this.timeChange.emit(new MatTimepickerInputEvent(this, this._elementRef.nativeElement));
}
/** Handles blur event on the input. */
_onBlur() {
// Reformat the input only if we have a valid value.
if (this.value) {
this._formatValue(this.value);
}
this._onTouched();
}
/** Implemented as part of ControlValueAccessor. */
writeValue(value) {
this.value = value;
}
/** Implemented as part of ControlValueAccessor. */
registerOnChange(fn) {
this._cvaOnChange = fn;
}
/** Implemented as part of ControlValueAccessor. */
registerOnTouched(fn) {
this._onTouched = fn;
}
/** Implemented as part of ControlValueAccessor. */
setDisabledState(isDisabled) {
this.disabled = isDisabled;
}
registerOnValidatorChange(fn) {
this._validatorOnChange = fn;
}
validate(c) {
return this._validator ? this._validator(c) : null;
}
/** Programmatically assigns a value to the input. */
_assignValueProgrammatically(value) {
value = this._timeAdapter.deserialize(value);
this._lastValueValid = this._isValidValue(value);
value = this._timeAdapter.getValidTimeOrNull(value);
this._assignValue(value);
this._formatValue(value);
}
/** Formats a value and sets it on the input element. */
_formatValue(value) {
this._elementRef.nativeElement.value =
value != null ? this._timeAdapter.format(value, TIME_FORMATS) : '';
}
/** Gets the base validator functions. */
_getValidators() {
return [this._parseValidator, this._minValidator, this._maxValidator];
}
/** Whether a value is considered valid. */
_isValidValue(value) {
return !value || this._timeAdapter.isValid(value);
}
/** Assigns a value to the model. */
_assignValue(value) {
// We may get some incoming values before the model was
// assigned. Save the value so that we can assign it later.
if (this._model) {
this._assignValueToModel(value);
this._pendingValue = null;
}
else {
this._pendingValue = value;
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerInputBase, deps: [{ token: i0.ElementRef }, { token: TimeAdapter, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.1", type: MatTimepickerInputBase, isStandalone: true, inputs: { value: "value", disabled: "disabled" }, outputs: { timeChange: "timeChange", timeInput: "timeInput" }, usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerInputBase, decorators: [{
type: Directive
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: TimeAdapter, decorators: [{
type: Optional
}] }], propDecorators: { value: [{
type: Input
}], disabled: [{
type: Input
}], timeChange: [{
type: Output
}], timeInput: [{
type: Output
}] } });
/**
* Checks whether the `SimpleChanges` object from an `ngOnChanges`
* callback has any changes, accounting for time objects.
*/
function timeInputsHaveChanged(changes, adapter) {
const keys = Object.keys(changes);
for (const key of keys) {
const { previousValue, currentValue } = changes[key];
if (adapter.isTimeInstance(previousValue) &&
adapter.isTimeInstance(currentValue)) {
if (!adapter.sameTime(previousValue, currentValue)) {
return true;
}
}
else {
return true;
}
}
return false;
}
const MAT_TIMEPICKER_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => MatTimepickerInput),
multi: true,
};
const MAT_TIMEPICKER_VALIDATORS = {
provide: NG_VALIDATORS,
useExisting: forwardRef(() => MatTimepickerInput),
multi: true,
};
/** Directive used to connect an input to a MatTimepicker. */
class MatTimepickerInput extends MatTimepickerInputBase {
/** The timepicker that this input is associated with. */
set matTimepicker(timepicker) {
if (timepicker) {
this._timepicker = timepicker;
this._registerModel(timepicker.registerInput(this));
}
}
/** The minimum valid date. */
get min() {
return this._min;
}
set min(value) {
const validValue = this._timeAdapter.getValidTimeOrNull(this._timeAdapter.deserialize(value));
if (!this._timeAdapter.sameTime(validValue, this._min)) {
this._min = validValue;
this._validatorOnChange();
}
}
/** The maximum valid date. */
get max() {
return this._max;
}
set max(value) {
const validValue = this._timeAdapter.getValidTimeOrNull(this._timeAdapter.deserialize(value));
if (!this._timeAdapter.sameTime(validValue, this._max)) {
this._max = validValue;
this._validatorOnChange();
}
}
constructor(elementRef, timeAdapter, _formField) {
super(elementRef, timeAdapter);
this._formField = _formField;
this._validator = Validators.compose(super._getValidators());
}
/**
* Gets the element that the timepicker popup should be connected to.
* @return The element to connect the popup to.
*/
getConnectedOverlayOrigin() {
return this._formField ? this._formField.getConnectedOverlayOrigin() : this._elementRef;
}
/** Returns the palette used by the input's form field, if any. */
getThemePalette() {
return this._formField ? this._formField.color : undefined;
}
/** Gets the ID of an element that should be used a description for the timepicker overlay. */
getOverlayLabelId() {
if (this._formField) {
return this._formField.getLabelId();
}
return this._elementRef.nativeElement.getAttribute('aria-labelledby');
}
/** Gets the input's minimum time. */
_getMinTime() {
return this._min;
}
/** Gets the input's maximum time. */
_getMaxTime() {
return this._max;
}
_assignValueToModel(value) {
if (this._model) {
this._model.updateSelection(value, this);
}
}
_getValueFromModel(modelValue) {
return modelValue;
}
_shouldHandleChangeEvent(event) {
return event.source !== this;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerInput, deps: [{ token: i0.ElementRef }, { token: TimeAdapter, optional: true }, { token: MAT_FORM_FIELD, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.1", type: MatTimepickerInput, isStandalone: true, selector: "input[matTimepicker]", inputs: { matTimepicker: "matTimepicker", min: "min", max: "max" }, host: { listeners: { "input": "_onInput($event.target.value)", "change": "_onChange()", "blur": "_onBlur()" }, properties: { "attr.aria-haspopup": "_timepicker ? \"dialog\" : null", "attr.aria-owns": "(_timepicker?.opened && _timepicker.id) || null", "attr.min": "min || null", "attr.max": "max || null", "disabled": "disabled" }, classAttribute: "mat-timepicker-input" }, providers: [
MAT_TIMEPICKER_VALUE_ACCESSOR,
MAT_TIMEPICKER_VALIDATORS,
{ provide: MAT_INPUT_VALUE_ACCESSOR, useExisting: MatTimepickerInput },
], exportAs: ["matTimepickerInput"], usesInheritance: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerInput, decorators: [{
type: Directive,
args: [{
selector: 'input[matTimepicker]',
standalone: true,
exportAs: 'matTimepickerInput',
providers: [
MAT_TIMEPICKER_VALUE_ACCESSOR,
MAT_TIMEPICKER_VALIDATORS,
{ provide: MAT_INPUT_VALUE_ACCESSOR, useExisting: MatTimepickerInput },
],
host: {
class: 'mat-timepicker-input',
'[attr.aria-haspopup]': '_timepicker ? "dialog" : null',
'[attr.aria-owns]': '(_timepicker?.opened && _timepicker.id) || null',
'[attr.min]': 'min || null',
'[attr.max]': 'max || null',
'[disabled]': 'disabled',
'(input)': '_onInput($event.target.value)',
'(change)': '_onChange()',
'(blur)': '_onBlur()',
},
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: TimeAdapter, decorators: [{
type: Optional
}] }, { type: i4.MatFormField, decorators: [{
type: Optional
}, {
type: Inject,
args: [MAT_FORM_FIELD]
}] }], propDecorators: { matTimepicker: [{
type: Input
}], min: [{
type: Input
}], max: [{
type: Input
}] } });
/** Button that will close the timepicker and assign the current selection to the data model. */
class MatTimepickerApply {
constructor(_timepicker) {
this._timepicker = _timepicker;
}
_applySelection() {
this._timepicker._applyPendingSelection();
this._timepicker.close();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerApply, deps: [{ token: MatTimepickerBase }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.1", type: MatTimepickerApply, isStandalone: true, selector: "[matTimepickerApply]", host: { listeners: { "click": "_applySelection()" } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerApply, decorators: [{
type: Directive,
args: [{
selector: '[matTimepickerApply]',
standalone: true,
host: {
'(click)': '_applySelection()',
},
}]
}], ctorParameters: () => [{ type: MatTimepickerBase }] });
/** Button that will close the timepicker and discard the current selection. */
class MatTimepickerCancel {
constructor(_timepicker) {
this._timepicker = _timepicker;
}
close() {
this._timepicker.close();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerCancel, deps: [{ token: MatTimepickerBase }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.1", type: MatTimepickerCancel, isStandalone: true, selector: "[matTimepickerCancel]", host: { listeners: { "click": "close()" } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerCancel, decorators: [{
type: Directive,
args: [{
selector: '[matTimepickerCancel]',
standalone: true,
host: {
'(click)': 'close()',
},
}]
}], ctorParameters: () => [{ type: MatTimepickerBase }] });
/**
* Container that can be used to project a row of action buttons
* to the bottom of a timepicker.
*/
class MatTimepickerActions {
constructor(_timepicker, _viewContainerRef) {
this._timepicker = _timepicker;
this._viewContainerRef = _viewContainerRef;
}
ngAfterViewInit() {
this._portal = new TemplatePortal(this._template, this._viewContainerRef);
this._timepicker.registerActions(this._portal);
}
ngOnDestroy() {
this._timepicker.removeActions(this._portal);
// Needs to be null checked since we initialize it in `ngAfterViewInit`.
if (this._portal && this._portal.isAttached) {
this._portal?.detach();
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerActions, deps: [{ token: MatTimepickerBase }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.1", type: MatTimepickerActions, isStandalone: true, selector: "mat-timepicker-actions", host: { classAttribute: "mat-timepicker-actions-container" }, viewQueries: [{ propertyName: "_template", first: true, predicate: TemplateRef, descendants: true }], ngImport: i0, template: `
<ng-template>
<div class="mat-timepicker-actions">
<ng-content></ng-content>
</div>
</ng-template>
`, isInline: true, styles: [".mat-timepicker-actions-container{margin-left:auto}.mat-timepicker-actions{display:flex;gap:.5rem;align-items:center;margin-top:.5rem}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerActions, decorators: [{
type: Component,
args: [{ selector: 'mat-timepicker-actions', standalone: true, template: `
<ng-template>
<div class="mat-timepicker-actions">
<ng-content></ng-content>
</div>
</ng-template>
`, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
class: 'mat-timepicker-actions-container',
}, styles: [".mat-timepicker-actions-container{margin-left:auto}.mat-timepicker-actions{display:flex;gap:.5rem;align-items:center;margin-top:.5rem}\n"] }]
}], ctorParameters: () => [{ type: MatTimepickerBase }, { type: i0.ViewContainerRef }], propDecorators: { _template: [{
type: ViewChild,
args: [TemplateRef]
}] } });
/**
* Default action buttons to the bottom of a timepicker.
*/
class MatTimepickerDefaultActions {
constructor(_timepicker, _intl) {
this._timepicker = _timepicker;
this._intl = _intl;
this.color = signal(undefined);
}
ngOnInit() {
this.color.set(this._timepicker.color);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerDefaultActions, deps: [{ token: MatTimepickerBase }, { token: MatTimepickerIntl }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.1", type: MatTimepickerDefaultActions, isStandalone: true, selector: "mat-timepicker-default-actions", host: { classAttribute: "mat-timepicker-actions-container" }, ngImport: i0, template: `
<div class="mat-timepicker-actions">
<ng-content></ng-content>
<button [color]="color()" mat-button matTimepickerCancel>
{{ _intl.cancelButton }}
</button>
<button [color]="color()" mat-button matTimepickerApply>
{{ _intl.okButton }}
</button>
</div>
`, isInline: true, styles: [".mat-timepicker-actions-container{margin-left:auto}.mat-timepicker-actions{display:flex;gap:.5rem;align-items:center;margin-top:.5rem}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: MatTimepickerApply, selector: "[matTimepickerApply]" }, { kind: "directive", type: MatTimepickerCancel, selector: "[matTimepickerCancel]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerDefaultActions, decorators: [{
type: Component,
args: [{ selector: 'mat-timepicker-default-actions', standalone: true, imports: [MatButtonModule, MatTimepickerApply, MatTimepickerCancel], template: `
<div class="mat-timepicker-actions">
<ng-content></ng-content>
<button [color]="color()" mat-button matTimepickerCancel>
{{ _intl.cancelButton }}
</button>
<button [color]="color()" mat-button matTimepickerApply>
{{ _intl.okButton }}
</button>
</div>
`, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
class: 'mat-timepicker-actions-container',
}, styles: [".mat-timepicker-actions-container{margin-left:auto}.mat-timepicker-actions{display:flex;gap:.5rem;align-items:center;margin-top:.5rem}\n"] }]
}], ctorParameters: () => [{ type: MatTimepickerBase }, { type: MatTimepickerIntl }] });
class MatTimepickerModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerModule, imports: [OverlayModule,
PortalModule,
A11yModule,
MatTimepicker,
MatTimepickerToggle,
MatTimepickerToggleIcon,
MatTimepickerContent,
MatTimepickerContentLayout,
MatTimepickerInput,
MatTimeInputs,
MatHourInput,
MatMinuteInput,
MatClockDials,
MatHoursClockDial,
MatMinutesClockDial,
MatTimePeriod,
MatTimepickerActions,
MatTimepickerDefaultActions,
MatTimepickerApply,
MatTimepickerCancel], exports: [CdkScrollableModule,
MatTimepicker,
MatTimepickerToggle,
MatTimepickerToggleIcon,
MatTimepickerContent,
MatTimepickerContentLayout,
MatTimepickerInput,
MatTimeInputs,
MatHourInput,
MatMinuteInput,
MatClockDials,
MatHoursClockDial,
MatMinutesClockDial,
MatTimePeriod,
MatTimepickerActions,
MatTimepickerDefaultActions,
MatTimepickerApply,
MatTimepickerCancel] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerModule, providers: [
MatTimepickerIntl,
MAT_TIMEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER,
{ provide: MAT_DEFAULT_ACITONS, useValue: MatTimepickerDefaultActions },
{
provide: MAT_FAB_DEFAULT_OPTIONS,
useValue: { color: 'unthemed' },
},
], imports: [OverlayModule,
PortalModule,
A11yModule,
MatTimepickerToggle,
MatTimepickerContent,
MatTimeInputs,
MatClockDials,
MatHoursClockDial,
MatMinutesClockDial,
MatTimePeriod,
MatTimepickerDefaultActions, CdkScrollableModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: MatTimepickerModule, decorators: [{
type: NgModule,
args: [{
declarations: [],
imports: [
OverlayModule,
PortalModule,
A11yModule,
MatTimepicker,
MatTimepickerToggle,
MatTimepickerToggleIcon,
MatTimepickerContent,
MatTimepickerContentLayout,
MatTimepickerInput,
MatTimeInputs,
MatHourInput,
MatMinuteInput,
MatClockDials,
MatHoursClockDial,
MatMinutesClockDial,
MatTimePeriod,
MatTimepickerActions,
MatTimepickerDefaultActions,
MatTimepickerApply,
MatTimepickerCancel,
],
exports: [
CdkScrollableModule,
MatTimepicker,
MatTimepickerToggle,
MatTimepickerToggleIcon,
MatTimepickerContent,
MatTimepickerContentLayout,
MatTimepickerInput,
MatTimeInputs,
MatHourInput,
MatMinuteInput,
MatClockDials,
MatHoursClockDial,
MatMinutesClockDial,
MatTimePeriod,
MatTimepickerActions,
MatTimepickerDefaultActions,
MatTimepickerApply,
MatTimepickerCancel,
],
providers: [
MatTimepickerIntl,
MAT_TIMEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER,
{ provide: MAT_DEFAULT_ACITONS, useValue: MatTimepickerDefaultActions },
{
provide: MAT_FAB_DEFAULT_OPTIONS,
useValue: { color: 'unthemed' },
},
],
}]
}] });
/*
* Public API Surface of mat-timepicker
*/
/**
* Generated bundle index. Do not edit.
*/
export { ALL_HOURS, ALL_MINUTES, MAT_DATE_TIME_LOCALE_FACTORY, MAT_DEFAULT_ACITONS, MAT_TIMEPICKER_DEFAULT_OPTIONS, MAT_TIMEPICKER_SCROLL_STRATEGY, MAT_TIMEPICKER_SCROLL_STRATEGY_FACTORY, MAT_TIMEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER, MAT_TIMEPICKER_VALIDATORS, MAT_TIMEPICKER_VALUE_ACCESSOR, MAT_TIME_LOCALE, MAT_TIME_LOCALE_PROVIDER, MatClockDials, MatHourInput, MatHoursClockDial, MatMinuteInput, MatMinutesClockDial, MatNativeDateTimeModule, MatTimeInputs, MatTimePeriod, MatTimepicker, MatTimepickerActions, MatTimepickerApply, MatTimepickerBase, MatTimepickerCancel, MatTimepickerContent, MatTimepickerContentLayout, MatTimepickerDefaultActions, MatTimepickerInput, MatTimepickerInputBase, MatTimepickerInputEvent, MatTimepickerIntl, MatTimepickerModule, MatTimepickerToggle, MatTimepickerToggleIcon, NativeDateTimeAdapter, NativeDateTimeModule, TimeAdapter, provideNativeDateTimeAdapter, timeInputsHaveChanged };
//# sourceMappingURL=dhutaryan-ngx-mat-timepicker.mjs.map