forked from angular/components
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtimepicker-toggle.ts
103 lines (91 loc) · 3.23 KB
/
timepicker-toggle.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {
booleanAttribute,
ChangeDetectionStrategy,
Component,
computed,
HostAttributeToken,
inject,
input,
InputSignal,
InputSignalWithTransform,
ViewEncapsulation,
} from '@angular/core';
import {MatIconButton} from '../button';
import {MAT_TIMEPICKER_CONFIG} from './util';
import type {MatTimepicker} from './timepicker';
/** Button that can be used to open a `mat-timepicker`. */
@Component({
selector: 'mat-timepicker-toggle',
templateUrl: 'timepicker-toggle.html',
host: {
'class': 'mat-timepicker-toggle',
'[attr.tabindex]': 'null',
// Bind the `click` on the host, rather than the inner `button`, so that we can call
// `stopPropagation` on it without affecting the user's `click` handlers. We need to stop
// it so that the input doesn't get focused automatically by the form field (See #21836).
'(click)': '_open($event)',
},
exportAs: 'matTimepickerToggle',
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [MatIconButton],
})
export class MatTimepickerToggle<D> {
private _defaultConfig = inject(MAT_TIMEPICKER_CONFIG, {optional: true});
private _defaultTabIndex = (() => {
const value = inject(new HostAttributeToken('tabindex'), {optional: true});
const parsed = Number(value);
return isNaN(parsed) ? null : parsed;
})();
protected _isDisabled = computed(() => {
const timepicker = this.timepicker();
return this.disabled() || timepicker.disabled();
});
/** Timepicker instance that the button will toggle. */
readonly timepicker: InputSignal<MatTimepicker<D>> = input.required<MatTimepicker<D>>({
alias: 'for',
});
/** Screen-reader label for the button. */
readonly ariaLabel = input<string | undefined>(undefined, {
alias: 'aria-label',
});
/** Screen-reader labelled by id for the button. */
readonly ariaLabelledby = input<string | undefined>(undefined, {
alias: 'aria-labelledby',
});
/** Default aria-label for the toggle if none is provided. */
private readonly _defaultAriaLabel = 'Open timepicker options';
/** Whether the toggle button is disabled. */
readonly disabled: InputSignalWithTransform<boolean, unknown> = input(false, {
transform: booleanAttribute,
alias: 'disabled',
});
/** Tabindex for the toggle. */
readonly tabIndex: InputSignal<number | null> = input(this._defaultTabIndex);
/** Whether ripples on the toggle should be disabled. */
readonly disableRipple: InputSignalWithTransform<boolean, unknown> = input(
this._defaultConfig?.disableRipple ?? false,
{transform: booleanAttribute},
);
/** Opens the connected timepicker. */
protected _open(event: Event): void {
if (this.timepicker() && !this._isDisabled()) {
this.timepicker().open();
event.stopPropagation();
}
}
/**
* Checks for ariaLabelledby and if empty uses custom
* aria-label or defaultAriaLabel if neither is provided.
*/
getAriaLabel(): string | null {
return this.ariaLabelledby() ? null : this.ariaLabel() || this._defaultAriaLabel;
}
}