-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Add paste handling to #39303 #40168
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
Add paste handling to #39303 #40168
Conversation
Co-authored-by: Marco Ciampini <[email protected]>
Co-authored-by: Aaron Robertshaw <[email protected]>
| type={ isPressEnterToChange ? 'text' : 'number' } | ||
| type="text" |
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.
To support conventional behavior of pasting at the caret or selection the type of the input had to change to text. A number type input does not provide selectionStart/selectionEnd.
If there were a strong reason to keep the type=number the paste handling could be simplified to replace the whole input value anytime a unit is included in the paste. It might even be more convenient that way but you'd have to discover that behavior and it's unconventional.
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.
From the initial conversation around this change, I initially though that we were considering to change the type to always be number in order to enjoy native browser validation.
This PR is taking the opposite approach (always set the type to text) — I'm just wondering if this change is going to impact the way users interact with the component (since the native browser validation is never going to be enforced).
If we decide to go down this route, I agree with @stokesman and @mirka that we'd really need to be careful with how the new UX works, and add as many unit tests as possible.
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.
If there were a strong reason to keep the
type=numberthe paste handling could be simplified to replace the whole input value anytime a unit is included in the paste. It might even be more convenient that way but you'd have to discover that behavior and it's unconventional.
Would it be hard to experiment with always having the input being type="number" ? Would that also mean that we'd need to remove the isPressEnterToChange functionality?
|
Size Change: +222 B (0%) Total Size: 1.22 MB
ℹ️ View Unchanged
|
d26feec to
b313d11
Compare
mirka
left a comment
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.
Really great attention to user interaction details! With sufficient test coverage, the added complexity seems acceptable to me.
| units | ||
| ); | ||
| // If no unit parsed, returns early to let the default paste happen. | ||
| if ( ! parsed[ 1 ] ) return; |
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.
Nit: This is really Prettier territory so just my two cents, but I find it hard to scan when single-line early return statements don't have an empty line below it. It's pretty easy to misread as the beginning of an if block on a quick glance!
| onChangeProp?.( `${ value }${ unitPasted }`, changeProps ); | ||
| } | ||
| // Moves focus to the UnitSelectControl. | ||
| refInputSuffix.current?.focus(); | ||
|
|
||
| if ( unitPasted === parsedUnit ) return; | ||
| onUnitChange?.( unitPasted, changeProps ); | ||
| setUnit( unitPasted ); |
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.
Is it possible to do the onChangeProp/onUnitChange/setUnit calls via the designated handlers (handleOnQuantityChange/handleOnUnitChange) or do they need to be called "à la carte" like this?
| refInputSuffix.current?.focus(); | ||
| } | ||
| }; | ||
| onPaste = ( event: ClipboardEvent< HTMLInputElement > ) => { |
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.
It might be worth extracting this as a helper function with dependency injection so it's easier to unit test the logic.
| } | ||
| }; | ||
| onPaste = ( event: ClipboardEvent< HTMLInputElement > ) => { | ||
| props.onPaste?.( event ); |
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.
Just a thought that I don't think we never discussed before — should we call props.onPaste at the start or at the end of the internal callback? The same reasoning should probably be applied to other callbacks (e.g. onChange)
| // If no unit parsed, returns early to let the default paste happen. | ||
| if ( ! parsed[ 1 ] ) return; | ||
| const [ quantityPasted, unitPasted ] = parsed; | ||
| event.preventDefault(); |
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.
Out of curiosity, what would happen if we didn't preventDefault() ?
| const parsed = parseQuantityAndUnitFromRawValue( | ||
| pastedText, | ||
| units | ||
| ); |
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.
Do we check at all if the pasted unit is in the list of allowed units?
And what happens if it's not an allowed unit? Maybe we should adopt the same strategy used to parse the value ?
2f66c6f to
8069575
Compare
929d872 to
86c1ccb
Compare
009d7c2 to
6a96ecd
Compare
|
There might be something to glean here if demand for unit-switching from pastes in |
Drafted because
some tests need fixed andwe probably want to add new tests to cover the paste handling.What?
Enables changing the unit of
UnitControlby pasting a string with units into its text input. In trunk it's already possible ifisPressEnterToChangeistrueand this PR enables it regardless of that prop. Builds on #39303.Why?
In #39303, the proposed revamp of a convenience feature had the undesired effect of removing the ability to change the unit by pasting. This restores it.
How?
Adds an
onPastehandler to the text input that parses the pasted string and handles updating the quantity and unit if a valid unit was contained in the pasted string.Testing Instructions
3%,2vw,1rem.111in the input.Screenshots or screencast
TBD