diff --git a/goldens/material/timepicker/index.api.md b/goldens/material/timepicker/index.api.md index f563743b636f..e63bc279182b 100644 --- a/goldens/material/timepicker/index.api.md +++ b/goldens/material/timepicker/index.api.md @@ -94,6 +94,7 @@ export class MatTimepickerInput implements ControlValueAccessor, Validator, O readonly min: InputSignalWithTransform; // (undocumented) ngOnDestroy(): void; + readonly openOnClick: InputSignalWithTransform; registerOnChange(fn: (value: any) => void): void; registerOnTouched(fn: () => void): void; registerOnValidatorChange(fn: () => void): void; @@ -103,7 +104,7 @@ export class MatTimepickerInput implements ControlValueAccessor, Validator, O readonly value: ModelSignal; writeValue(value: any): void; // (undocumented) - static ɵdir: i0.ɵɵDirectiveDeclaration, "input[matTimepicker]", ["matTimepickerInput"], { "value": { "alias": "value"; "required": false; "isSignal": true; }; "timepicker": { "alias": "matTimepicker"; "required": true; "isSignal": true; }; "min": { "alias": "matTimepickerMin"; "required": false; "isSignal": true; }; "max": { "alias": "matTimepickerMax"; "required": false; "isSignal": true; }; "disabledInput": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>; + static ɵdir: i0.ɵɵDirectiveDeclaration, "input[matTimepicker]", ["matTimepickerInput"], { "value": { "alias": "value"; "required": false; "isSignal": true; }; "timepicker": { "alias": "matTimepicker"; "required": true; "isSignal": true; }; "min": { "alias": "matTimepickerMin"; "required": false; "isSignal": true; }; "max": { "alias": "matTimepickerMax"; "required": false; "isSignal": true; }; "openOnClick": { "alias": "matTimepickerOpenOnClick"; "required": false; "isSignal": true; }; "disabledInput": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration, never>; } diff --git a/src/material/timepicker/timepicker-input.ts b/src/material/timepicker/timepicker-input.ts index 3912a236e2d8..93e695139fde 100644 --- a/src/material/timepicker/timepicker-input.ts +++ b/src/material/timepicker/timepicker-input.ts @@ -140,6 +140,16 @@ export class MatTimepickerInput implements ControlValueAccessor, Validator, O transform: (value: unknown) => this._transformDateInput(value), }); + /** + * Whether to open the timepicker overlay when clicking on the input. Enabled by default. + * Note that when disabling this option, you'll have to provide your own logic for opening + * the overlay. + */ + readonly openOnClick: InputSignalWithTransform = input(true, { + alias: 'matTimepickerOpenOnClick', + transform: booleanAttribute, + }); + /** Whether the input is disabled. */ readonly disabled: Signal = computed( () => this.disabledInput() || this._accessorDisabled(), @@ -254,7 +264,7 @@ export class MatTimepickerInput implements ControlValueAccessor, Validator, O /** Handles clicks on the input or the containing form field. */ private _handleClick = (): void => { - if (!this.disabled()) { + if (!this.disabled() && this.openOnClick()) { this.timepicker().open(); } }; diff --git a/src/material/timepicker/timepicker.spec.ts b/src/material/timepicker/timepicker.spec.ts index baf1d2ee7df1..3fa080efb157 100644 --- a/src/material/timepicker/timepicker.spec.ts +++ b/src/material/timepicker/timepicker.spec.ts @@ -480,6 +480,15 @@ describe('MatTimepicker', () => { fixture.detectChanges(); expect(getPanel()).toBeTruthy(); })); + + it('should be able to opt out of opening on click', () => { + const fixture = TestBed.createComponent(StandaloneTimepicker); + fixture.componentInstance.openOnClick.set(false); + fixture.detectChanges(); + getInput(fixture).click(); + fixture.detectChanges(); + expect(getPanel()).toBeFalsy(); + }); }); // Note: these tests intentionally don't cover the full option generation logic @@ -1313,6 +1322,7 @@ describe('MatTimepicker', () => { [disabled]="disabled()" [matTimepickerMin]="min()" [matTimepickerMax]="max()" + [matTimepickerOpenOnClick]="openOnClick()" [value]="value()"/> (false); readonly toggleTabIndex = signal(0); readonly customOptions = signal[] | null>(null); + readonly openOnClick = signal(true); readonly openedSpy = jasmine.createSpy('opened'); readonly closedSpy = jasmine.createSpy('closed'); readonly selectedSpy = jasmine.createSpy('selected');