Skip to content

refactor(datepicker): move keyboard events handlers into the views #9775

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Feb 18, 2018
Merged

refactor(datepicker): move keyboard events handlers into the views #9775

merged 6 commits into from
Feb 18, 2018

Conversation

julianobrasil
Copy link
Contributor

@julianobrasil julianobrasil commented Feb 4, 2018

This should be blocked until #9727 is merged.

@mmalerba, as #9727 hasn't been merged yet, I can merge this into that one.

There are a few things to discuss before though. Originally the keyboard events (basically (keydown)) were listened to at this markup:

https://github.com/angular/material2/blob/c7201984d4570e2bf17fbf4afce0dc4400f863f5/src/lib/datepicker/calendar.html#L23-L24

As now the events are being handled inside each view, I moved the listening part to each view markup, like the snippet below, from month-view.html

<table class="mat-calendar-table">
  <thead class="mat-calendar-table-header">
    <tr><th *ngFor="let day of _weekdays" [attr.aria-label]="day.long">{{day.narrow}}</th></tr>
    <tr><th class="mat-calendar-table-header-divider" colspan="7" aria-hidden="true"></th></tr>
  </thead>
  <tbody mat-calendar-body
         [label]="_monthLabel"
         [rows]="_weeks"
         [todayValue]="_todayDate"
         [selectedValue]="_selectedDate"
         [labelMinRequiredCells]="3"
         [activeCell]="_dateAdapter.getDate(activeDate) - 1"
         (selectedValueChange)="_dateSelected($event)"
         (keydown)="_handleCalendarBodyKeydown($event)"> <------- HERE IS THE LISTENER NOW
  </tbody>
</table>

Also, I thought it'd be better to move the a11y tests from calendar.spec.ts to each view spec file.

As a consequence... well, I'm with this feeling that we're replicating too much code (just a feeling).

Another possible approach would be to keep the listener in calendar.html (its original place) and pass through keydown event to each view, but I thought it'd be a little bit awkward.

@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label Feb 4, 2018
@julianobrasil julianobrasil changed the title refac(datepicker): move keyboard hanlders into the views refacor(datepicker): move keyboard hanlders into the views Feb 4, 2018
@julianobrasil julianobrasil changed the title refacor(datepicker): move keyboard hanlders into the views refactor(datepicker): move keyboard hanlders into the views Feb 4, 2018
@julianobrasil julianobrasil changed the title refactor(datepicker): move keyboard hanlders into the views refactor(datepicker): move keyboard events handlers into the views Feb 4, 2018
Copy link
Contributor

@mmalerba mmalerba left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels much better to me, having logic for each of the views mixed into the calendar definitely felt wrong

this._getValidDateOrNull(this._dateAdapter.deserialize(value)) || this._dateAdapter.today();
const oldActiveDate = this._activeDate;
const validDate =
this._getValidDateOrNull(this._dateAdapter.deserialize(value)) || this._dateAdapter.today();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: indent continuation lines by 4

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I didn't know that was the rule. 😃

this._userSelection.emit();
}

/** Focuses the active cell after the microtask queue is empty. */
_focusActiveCell() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we move this logic to the calendar table instead of repeating it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea.

this._userSelected();
}

_userSelected(): void {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I don't think this needs to be its own function, this._userSelected() is only a couple characters shorter than this._userSelection.emit()

@mmalerba mmalerba added the target: major This PR is targeted for the next major release label Feb 15, 2018
Copy link
Contributor

@mmalerba mmalerba left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs rebase

@@ -81,6 +83,10 @@ export class MatCalendarBody {
/** Emits when a new value is selected. */
@Output() readonly selectedValueChange: EventEmitter<number> = new EventEmitter<number>();

constructor(private _elementRef: ElementRef,
private _ngZone: NgZone) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like this will fit on one line?

if (!this._hasSameMonthAndYear(oldActiveDate, this._activeDate)) {
this._init();
}
if (this._dateAdapter.compareDate(oldActiveDate, this._activeDate)) {
this.activeDateChange.emit(this._activeDate);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we sure we want to emit here? it seems strange to emit in response to the @Input() changing. I would have expected it to only emit if the active date changed due to user interaction (click, keyboard, etc)

Copy link
Contributor Author

@julianobrasil julianobrasil Feb 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's here for convenience (just because there was a single line above saving the previous activeDate 😸), but you're right. This is far from being the best place to put it. I'll move it.

@mmalerba mmalerba added pr: lgtm action: merge The PR is ready for merge by the caretaker labels Feb 16, 2018
@jelbourn jelbourn merged commit 8e3ab8d into angular:master Feb 18, 2018
@julianobrasil julianobrasil deleted the refacDatePicker2 branch March 30, 2018 11:07
devversion added a commit to devversion/material2 that referenced this pull request Sep 4, 2018
Instead of just checking the length of the constructor arguments, we now check the types of the constructor or super call. This means that we can *way* better report invalid signatures for constructor changes like for the `MatCalendar` (angular#9775). Just relying on the length of arguments means that *order*  is being ignored.

This also makes maintaining the constructor signature changes easier (there are a lot of instances for V7).
devversion added a commit to devversion/material2 that referenced this pull request Sep 4, 2018
Instead of just checking the length of the constructor arguments, we now check the types of the constructor or super call. This means that we can *way* better report invalid signatures for constructor changes like for the `MatCalendar` (angular#9775). Just relying on the length of arguments means that *order*  is being ignored.

This also makes maintaining the constructor signature changes easier (there are a lot of instances for V7).
devversion added a commit to devversion/material2 that referenced this pull request Sep 4, 2018
Instead of just checking the length of the constructor arguments, we now check the types of the constructor or super call. This means that we can *way* better report invalid signatures for constructor changes like for the `MatCalendar` (angular#9775). Just relying on the length of arguments means that *order*  is being ignored.

This also makes maintaining the constructor signature changes easier (there are a lot of instances for V7).
jelbourn pushed a commit that referenced this pull request Sep 5, 2018
…12970)

Instead of just checking the length of the constructor arguments, we now check the types of the constructor or super call. This means that we can *way* better report invalid signatures for constructor changes like for the `MatCalendar` (#9775). Just relying on the length of arguments means that *order*  is being ignored.

This also makes maintaining the constructor signature changes easier (there are a lot of instances for V7).
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 8, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker cla: yes PR author has agreed to Google's Contributor License Agreement target: major This PR is targeted for the next major release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants