Skip to content

Commit ec7219d

Browse files
authored
fix(datepicker): placeholder not behaving correctly in legacy form field (#19595)
- Fixes the date range picker's placeholder not behaving correctly when it's placed inside of a form field with the `legacy` appearance. - Fixes several range picker examples that were setting `matInput` on `matStartDate` and `matEndDate` which isn't required.
1 parent 908fe5f commit ec7219d

File tree

12 files changed

+52
-30
lines changed

12 files changed

+52
-30
lines changed

src/components-examples/material/datepicker/date-range-picker-comparison/date-range-picker-comparison-example.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
[rangePicker]="campaignOnePicker"
66
[comparisonStart]="campaignTwo.value.start"
77
[comparisonEnd]="campaignTwo.value.end">
8-
<input matStartDate matInput placeholder="Start date" formControlName="start">
9-
<input matEndDate matInput placeholder="End date" formControlName="end">
8+
<input matStartDate placeholder="Start date" formControlName="start">
9+
<input matEndDate placeholder="End date" formControlName="end">
1010
</mat-date-range-input>
1111
<mat-datepicker-toggle matSuffix [for]="campaignOnePicker"></mat-datepicker-toggle>
1212
<mat-date-range-picker #campaignOnePicker></mat-date-range-picker>
@@ -19,8 +19,8 @@
1919
[rangePicker]="campaignTwoPicker"
2020
[comparisonStart]="campaignOne.value.start"
2121
[comparisonEnd]="campaignOne.value.end">
22-
<input matStartDate matInput placeholder="Start date" formControlName="start">
23-
<input matEndDate matInput placeholder="End date" formControlName="end">
22+
<input matStartDate placeholder="Start date" formControlName="start">
23+
<input matEndDate placeholder="End date" formControlName="end">
2424
</mat-date-range-input>
2525
<mat-datepicker-toggle matSuffix [for]="campaignTwoPicker"></mat-datepicker-toggle>
2626
<mat-date-range-picker #campaignTwoPicker></mat-date-range-picker>

src/components-examples/material/datepicker/date-range-picker-forms/date-range-picker-forms-example.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<mat-form-field>
22
<mat-label>Enter a date range</mat-label>
33
<mat-date-range-input [formGroup]="range" [rangePicker]="picker">
4-
<input matStartDate matInput formControlName="start" placeholder="Start date">
5-
<input matEndDate matInput formControlName="end" placeholder="End date">
4+
<input matStartDate formControlName="start" placeholder="Start date">
5+
<input matEndDate formControlName="end" placeholder="End date">
66
</mat-date-range-input>
77
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
88
<mat-date-range-picker #picker></mat-date-range-picker>

src/components-examples/material/datepicker/date-range-picker-overview/date-range-picker-overview-example.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<mat-form-field>
22
<mat-label>Enter a date range</mat-label>
33
<mat-date-range-input [rangePicker]="picker">
4-
<input matStartDate matInput placeholder="Start date">
5-
<input matEndDate matInput placeholder="End date">
4+
<input matStartDate placeholder="Start date">
5+
<input matEndDate placeholder="End date">
66
</mat-date-range-input>
77
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
88
<mat-date-range-picker #picker></mat-date-range-picker>

src/components-examples/material/datepicker/date-range-picker-selection-strategy/date-range-picker-selection-strategy-example.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<mat-form-field>
22
<mat-label>Enter a date range</mat-label>
33
<mat-date-range-input [rangePicker]="picker">
4-
<input matStartDate matInput placeholder="Start date">
5-
<input matEndDate matInput placeholder="End date">
4+
<input matStartDate placeholder="Start date">
5+
<input matEndDate placeholder="End date">
66
</mat-date-range-input>
77
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
88
<mat-date-range-picker #picker></mat-date-range-picker>

src/dev-app/datepicker/datepicker-demo.html

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,7 @@ <h2>Datepicker with custom header extending the default header</h2>
173173
<h2>Range picker</h2>
174174

175175
<div class="demo-range-group">
176-
<mat-form-field>
177-
<mat-label>Enter a date range</mat-label>
176+
<mat-form-field appearance="legacy">
178177
<mat-date-range-input
179178
[formGroup]="range1"
180179
[rangePicker]="range1Picker"
@@ -184,8 +183,8 @@ <h2>Range picker</h2>
184183
[comparisonStart]="comparisonStart"
185184
[comparisonEnd]="comparisonEnd"
186185
[dateFilter]="filterOdd ? dateFilter : undefined">
187-
<input matStartDate formControlName="start" placeholder="Start date"/>
188-
<input matEndDate formControlName="end" placeholder="End date"/>
186+
<input matStartDate formControlName="start"/>
187+
<input matEndDate formControlName="end"/>
189188
</mat-date-range-input>
190189
<mat-datepicker-toggle [for]="range1Picker" matSuffix></mat-datepicker-toggle>
191190
<mat-date-range-picker

src/material/datepicker/date-range-input-parts.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,11 @@ abstract class MatDateRangeInputPartBase<D>
125125
return this._elementRef.nativeElement.value.length === 0;
126126
}
127127

128+
/** Gets the placeholder of the input. */
129+
_getPlaceholder() {
130+
return this._elementRef.nativeElement.placeholder;
131+
}
132+
128133
/** Focuses the input. */
129134
focus(): void {
130135
this._elementRef.nativeElement.focus();

src/material/datepicker/date-range-input.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
aria-hidden="true">{{_getInputMirrorValue()}}</span>
1010
</div>
1111

12-
<span class="mat-date-range-input-separator">{{separator}}</span>
12+
<span
13+
class="mat-date-range-input-separator"
14+
[class.mat-date-range-input-separator-hidden]="_shouldHideSeparator()">{{separator}}</span>
1315

1416
<div class="mat-date-range-input-end-wrapper">
1517
<ng-content select="input[matEndDate]"></ng-content>

src/material/datepicker/date-range-input.scss

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ $mat-date-range-input-placeholder-transition:
2222
.mat-date-range-input-separator {
2323
margin: 0 $mat-date-range-input-separator-spacing;
2424
transition: $mat-date-range-input-placeholder-transition;
25+
}
2526

26-
.mat-form-field-hide-placeholder & {
27-
// Disable text selection, because the user can click
28-
// through the main label when the input is disabled.
29-
@include user-select(none);
30-
color: transparent;
31-
transition: none;
32-
}
27+
.mat-date-range-input-separator-hidden {
28+
// Disable text selection, because the user can click
29+
// through the main label when the input is disabled.
30+
@include user-select(none);
31+
color: transparent;
32+
transition: none;
3333
}
3434

3535
// Underlying input inside the range input.

src/material/datepicker/date-range-input.spec.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,12 @@ describe('MatDateRangeInput', () => {
503503
expect(start.nativeElement.focus).not.toHaveBeenCalled();
504504
});
505505

506+
it('should be able to get the input placeholder', () => {
507+
const fixture = createComponent(StandardRangePicker);
508+
fixture.detectChanges();
509+
expect(fixture.componentInstance.rangeInput.placeholder).toBe('Start date – End date');
510+
});
511+
506512
});
507513

508514
@Component({

src/material/datepicker/date-range-input.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,15 @@ export class MatDateRangeInput<D> implements MatFormFieldControl<DateRange<D>>,
8080
controlType = 'mat-date-range-input';
8181

8282
/**
83-
* Implemented as a part of `MatFormFieldControl`, but not used.
83+
* Implemented as a part of `MatFormFieldControl`.
8484
* Set the placeholder attribute on `matStartDate` and `matEndDate`.
8585
* @docs-private
8686
*/
87-
placeholder: string;
87+
get placeholder() {
88+
const start = this._startInput?._getPlaceholder() || '';
89+
const end = this._endInput?._getPlaceholder() || '';
90+
return (start || end) ? `${start} ${this.separator} ${end}` : '';
91+
}
8892

8993
/** The range picker that this input is associated with. */
9094
@Input()
@@ -297,6 +301,11 @@ export class MatDateRangeInput<D> implements MatFormFieldControl<DateRange<D>>,
297301
}
298302
}
299303

304+
/** Whether the separate text should be hidden. */
305+
_shouldHideSeparator() {
306+
return (!this._formField || this._formField._hideControlPlaceholder()) && this.empty;
307+
}
308+
300309
/**
301310
* @param obj The object to check.
302311
* @returns The given object if it is both a date instance and valid, otherwise null.

src/material/datepicker/datepicker.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ property on the text input.
1111
There is also an optional datepicker toggle button that gives the user an easy way to open the datepicker pop-up.
1212

1313
<!-- example({"example":"datepicker-overview",
14-
"file":"datepicker-overview-example.html",
14+
"file":"datepicker-overview-example.html",
1515
"region":"toggle"}) -->
1616

1717
This works exactly the same with an input that is part of an `<mat-form-field>` and the toggle
@@ -36,8 +36,8 @@ respectively:
3636

3737
```html
3838
<mat-date-range-input>
39-
<input matStartDate matInput placeholder="Start date">
40-
<input matEndDate matInput placeholder="End date">
39+
<input matStartDate placeholder="Start date">
40+
<input matEndDate placeholder="End date">
4141
</mat-date-range-input>
4242
```
4343

@@ -52,8 +52,8 @@ Connect the range picker and range input using the `rangePicker` property:
5252

5353
```html
5454
<mat-date-range-input [rangePicker]="picker">
55-
<input matStartDate matInput placeholder="Start date">
56-
<input matEndDate matInput placeholder="End date">
55+
<input matStartDate placeholder="Start date">
56+
<input matEndDate placeholder="End date">
5757
</mat-date-range-input>
5858

5959
<mat-date-range-picker #picker></mat-date-range-picker>

tools/public_api_guard/material/datepicker.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ export declare class MatDateRangeInput<D> implements MatFormFieldControl<DateRan
308308
get min(): D | null;
309309
set min(value: D | null);
310310
ngControl: NgControl | null;
311-
placeholder: string;
311+
get placeholder(): string;
312312
get rangePicker(): MatDateRangePicker<D>;
313313
set rangePicker(rangePicker: MatDateRangePicker<D>);
314314
get required(): boolean;
@@ -322,6 +322,7 @@ export declare class MatDateRangeInput<D> implements MatFormFieldControl<DateRan
322322
_handleChildValueChange(): void;
323323
_openDatepicker(): void;
324324
_shouldHidePlaceholders(): boolean;
325+
_shouldHideSeparator(): boolean;
325326
getConnectedOverlayOrigin(): ElementRef;
326327
getStartValue(): D | null;
327328
getThemePalette(): ThemePalette;

0 commit comments

Comments
 (0)