-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Fix/date picker 24hour tab order #11863
Fix/date picker 24hour tab order #11863
Conversation
…ds and use some logic to determine logical order
I also find it strange that this logic is based upon the time format. Shouldn't it be based upon the date format instead? Besides that basis, I think the logic itself is a nice way to resolve this tabbing order issue. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey, thanks for looking into this and coming up with a fix. The React warning is something that'll need to be solved, but it seems to be on the right track.
render() { | ||
const { is12Hour } = this.props; | ||
const { day, month, year, minutes, hours, am } = this.state; | ||
const renderMonthDay = [ this.renderMonth( month ), this.renderDay( day ) ]; | ||
const renderDayMonth = [ this.renderDay( day ), this.renderMonth( month ) ]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code is creates 4 elements by calling renderDay twice and renderMonth twice, but then only two of those elements are used.
React also warns that the elements in the array don't have keys.
Would be great to solve both things. I wouldn't be shy about extracting the day/month code out into separate component(s) if it aids clarity. It's already halfway there with the renderDay/renderMonth methods.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hadn't considered it initializing those elements when the variable is assigned. I'll have to find a way to make it so that only one is instantiated when necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if doing something like:
renderDayMonthFormat(is12Hour) {
const { day, month } = this.state;
const layout = [ this.renderDay( day ), this.renderMonth( month ) ];
return is12Hour ? layout : layout.reverse();
}
And thus:
{ this.renderDayMonthFormat(is12Hour) }
Would work better. This would cut down rendering the elements to only once. Where were you seeing React warning about the elements in the array?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I like the idea of using reverse
.
The warning is In the browser console—you'll need SCRIPT_DEBUG enabled in your dev environment to see it:
https://codex.wordpress.org/Debugging_in_WordPress
Some details about the particular warning from React's docs:
https://reactjs.org/docs/lists-and-keys.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @talldan I'll look into this and see what is going on! I appreciate all the help.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've made a few changes and I believe I also fixed the issue with the array keys. I looked at a few other components and created a simple key for each root element that is returned for both the day and month render methods.
@LukePettway - thanks for addressing the feedback 😄 It looks like there's a test failing that's related to these changes:
Are you able to take a look at that? Thanks. |
Sure thing! I was having issues getting unit tests to run so I'm currently looking into why that is and once I figure out the issue, I can update the failing tests. |
Cool, let me know if you need a hand with anything. |
@talldan I do have one question about the tests for this. It currently fails because it expects that class to be added which I removed since all it was doing was using flexbox to change the order. Now that it can render the markup in two different ways, should I write test cases for each of those? Or is simply having it check that it renders at all more than suitable enough for now? |
@LukePettway Replacing the tests with new ones to make sure the rendered order of the components is correct would be great. Are you familiar with snapshot tests? That might be the easiest way to go:
One test case where 12 hour is true, and one where it's false will catch any potential future regressions. |
Yep! I am very familiar with snapshots, I can make these two test cases. Thanks very much |
@talldan For some reason I can't seem to get any of the tests to work. When I run |
@LukePettway Maybe use There are quite a few other places that linting is checked (commit hooks, CI jobs, code reviews) so I wouldn't be concerned that there are any formatting errors, it's probably something related to how eslint is configured on your system. edit: Sorry, just re-read your message and see that you've probably tried |
@talldan Thanks for the suggestion. I tried this along with a few other things and I still run into the same problem. The output I get is as follows:
I wonder if I just need to do a fresh install of Gutenberg at this point. |
@LukePettway Ah yes, I remember this error message, it was related to the removal of the mobile submodule. IIRC the solution is to remove the gutenberg-mobile folder. Though I would've expected Some discussion on slack happened back here if it helps: |
@talldan removing that directory worked! Not sure how it was created but the tests are working and I can finally work on getting the tests updated. Thank you so much for all your time on this. |
@talldan I've been trying to come up with a way to test this and it's proving to be harder than I thought. Any ideas on what would be the best way to test something like this? At first I figured I could just look at the render order, but there doesn't seem to be a simple way of testing that without doing a lot of querying through the node tree to see which control is rendered first. I also want to avoid adding class names just for the sake of testing. |
Hey @LukePettway - how did it go with the snapshot tests? Expanding on the example from an earlier comment (#11863 (comment)), something like this should do the job:
The |
@talldan I was able to achieve what I think works for testing this. I think I was trying to make it more complicated than it needed to be. Thanks 👍 ! |
Thanks for the hard work on this @LukePettway! |
Merging this now as there's no further comments. |
* removed is24hour class, move markup for month and day to render methods and use some logic to determine logical order * update snapshots to test the is12Hour boolean.
* removed is24hour class, move markup for month and day to render methods and use some logic to determine logical order * update snapshots to test the is12Hour boolean.
Description
In #11566 it is mentioned that when you choose a date format such as
j. F Y
or13 November 2018
the post publish date and time picker displays the order correctly to user but the tab order isn't logical. This is a result of flexbox being used to change the visual order of the input controls on the page.The easiest and most likely "best" way to fix this is to render the markup in the logical order instead of relying on flexbox styling. It does create a little more code and logic within the component but completely mitigates the issues that could be associated with doing something like juggling the
tabindex
value for each input.For some reason I couldn't get unit tests to run, I kept getting an error when trying to update snapshot tests. I think I may need to reinstall my dependencies to resolve that problem.
I also find it strange that I need to set the time format to 24 hour to get the date to display in this order, does that sound right?
I'm open to suggestions about how to better handle swapping the order of the date and month within the React component render cycle. I toyed with the idea of just reversing the array of render methods to change the order but opted to be a little more verbose.
How has this been tested?
I tested this in multiple browsers by changing the date format back and forth between the US and rest of the worlds standard formats. Then I used my keyboard to tab through the inputs to make sure the order is correct. Finally I changed the date multiple times to make sure none of the functionality was lost.
Screenshots
Here is the tab order of the non-US date format displayed in the correct order and tabbing correctly
Types of changes
Bug fix
Checklist: