-
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
Rewrite DatePicker, TimePicker and DateTimePicker in TypeScript #40775
Rewrite DatePicker, TimePicker and DateTimePicker in TypeScript #40775
Conversation
7728df6
to
fce95e2
Compare
2d24470
to
383ea01
Compare
383ea01
to
9bcc66e
Compare
Size Change: +63 B (0%) Total Size: 1.24 MB
ℹ️ View Unchanged
|
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.
Nice work @noisysocks 👍
Everything is looking pretty good so far.
✅ Unit tests are still passing
✅ No typing errors reported
✅ DateTimePickers etc function as expected
I left a few small comments though. Mainly just passing on advice, requests or preferences I've been given while working on other components. Hopefully, these will help make our typing here a little more consistent with other components.
Not that it should happen in this PR but are we planning to also connect this component to the component context system?
P.S. This will also need a changelog entry
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.
Great work, @noisysocks!
This PR is already in a great shape — I only left a few minor inline comments.
In addition to those, it would be great if you could also add a CHANGELOG entry.
Thank you!
function update( name: 'date' | 'month' | 'year' | 'hours' | 'minutes' ) { | ||
return ( value: number ) => { |
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.
We usually try not to introduce runtime changes — is there a particular reason why we're doing so here?
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.
So if you go with function update( name: string, value: number )
then you'll get an error because it can't be guaranteed that name
will be a valid method in the moment object.
const newDate = date.clone()[ name ]( adjustedValue );
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Moment'.
No index signature with a parameter of type 'string' was found on type 'Moment'.
If you go with function update( name: 'date' | 'month' | 'year' | 'hours' | 'minutes', value: number )
then you'll get an error because it can't be guaranteed that input
will get back to you with a name
that is one of date
, month
, year
, hours
, or minutes
.
onUpdate={ update }
Type '(name: "date" | "month" | "year" | "hours" | "minutes", value: number) => void' is not assignable to type '(name: string, value: number) => void'.
Types of parameters 'name' and 'name' are incompatible.
Type 'string' is not assignable to type '"date" | "month" | "year" | "hours" | "minutes"'.
One solution could be to paramatize UpdateOnBlurAsIntegerFieldProps
.
type UpdateOnBlurAsIntegerFieldProps< T extends string > = {
name: T;
onUpdate: ( name: T, value: number ) => void;
};
I think that is overly complex, though, so I went with changing update
to be a partial function since that's a very common pattern and it's also how updateAmPm
(immediately below this function) works.
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.
Thank you for the explanation — it makes sense to keep your changes
Feedback addressed. Let's see if it compiles. Thanks for the reviews @aaronrobertshaw and @ciampo! |
618e1f9
to
0270b76
Compare
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.
Thank you for working on this, @noisysocks ! All feedback so far has been addressed 🚀
Next up, we may want to look at rewriting Storybook examples and unit tests to TypeScript too (which can be done in 2 separate follow-ups) . Although I'm probably not going to be able to help with reviews until next Wednesday (May 18th), so no rush there!
I noticed that the WordPressComponentProps
type is being only used for the UpdateOnBlurAsIntegerField
component — we may want to look into using it for the remaining components too, but that can be also done in a follow-up PR (and with an even lower priority than the storybook and tests TS refactor).
Unless I'm misunderstanding what |
What?
Rewrites the component JavaScript in
packages/components/date-time
in TypeScript.Part of #35744
Why?
We're gradually converting all of
@wordpress/components
, and I'm about to do some work onDateTimePicker
, so I thought I'd be a good citizen and help convert these components.How?
I followed steps 1-9 in this guide.
I'll convert the unit tests and storybooks in follow-up PRs as I ran into some issues there and this PR is big enough already.
The only real obstacle I ran into was getting
DayPickerSingleDateController
fromreact-dates
to work properly because the types are inreact-dates
but we importreact-dates/lib/components/DayPickerSingleDateController
for performance reasons.Runtime changes were mostly minimal: I added some null checks here and there and I changed the
update
function inTimePicker
to be a partial function as that's easier to type.Testing Instructions
#40754 added tests. You can also play around with the Publish popover in the post sidebar to check that there is nothing off.
I'm a total noob at this so go easy on me and let me know if I missed anything! 😅 🙏