-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
RichText: remove Editable & allow React to diff editable element #17779
Conversation
c7c4b11
to
931615c
Compare
It seems really promising. What's the status of this? Just needs a review? |
Yeah, this is ready for review :D |
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 I understand correctly, the changes here aren't actually leveraging React to do the rendering of the RichText record?
Even still, I think the benefits here are pretty great, and serve as a nice overall simplification.
I would be curious as well what the measurable performance difference is here, if any (seems there ought to be some improvement to key presses?).
Most of my review comments are minor nit-picks. Functionally, it works great. The only thing I'd consider really blocking is the priority with which we're applying ARIA props seems to have changed.
valueToEditableHTML={ this.valueToEditableHTML } | ||
aria-label={ placeholder } | ||
{ ...pickAriaProps( this.props ) } | ||
style={ { ...style, whiteSpace } } |
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.
While it existed previously as well, I wonder if we're incurring unnecessary work here in rendering since React will always consider props.style !== nextProps.style
on every render. I guess in real-world usage we'd be doing so anyways, since the paragraph block always passes a new object as well (though that's something on its own to consider refactoring), but even then there's the (albeit trivial) work of merging the objects.
Was it ever considered: Can we apply this style via CSS ? It avoids the whole need to merge the objects at all. I'd even be generally okay with the problem was specificity and we found ourselves needing to !important
.
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.
Can we apply this style via CSS ? It avoids the whole need to merge the objects at all.
Oh you mean the white space rule? Yes, I considered using a stylesheet, but then this would be the only rule in the stylesheet, so I picked adding it to the style object instead of creating a whole new stylesheet for this package.
I'll adjust to check the style prop.
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 React has some internal optimisations for the style
prop on an element. It's a bit strange to expect React users to optimise these style objects that are so commonly used.
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 React has some internal optimisations for the
style
prop on an element. It's a bit strange to expect React users to optimise these style objects that are so commonly used.
Yeah, I'm not sure if they do, but as a general principle this is also why I tend to avoid objects as props in the first place. ariaProps
is another good example of where this becomes needlessly difficult to manage. In retrospect, I'm not sure why we didn't just expect people to pass the specific prop they wanted to apply (aria-foo
). I seem to recall some limitation that led us down that path, but certainly made things more difficult.
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.
Right, I try to avoid them as much as possible too. Worth noting that ariaProps
is picked from props
though, there's no ariaProps
prop. The picking seems to be there to avoid passing all RichText
props to the element.
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.
Right, I try to avoid them as much as possible too. Worth noting that
ariaProps
is picked fromprops
though, there's noariaProps
prop. The picking seems to be there to avoid passing allRichText
props to the element.
Oh! You're right, I definitely mis-recalled the behavior.
So maybe the opposite is true, that we have headaches because we chose to pick props than to accept an object 😄 Maybe in the future we could just be passing through all the props, so we don't need to be doing the explicit picking?
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 think we either need to pick the props we want to pass on, or delete the props we don't want to pass on. Both of these are explicit in a way I guess, but I'm fine with trying to delete the props we don't want to pass on. :) Either way there will be some sort of picking. We can't pass any unknown props to an element.
No, it's just letting React manage the editable element, not its contents. I'd like to explore that in the future, but I ran into some problems with it. React can't seem to update a DOM tree if the current tree is not in a shape that it's expecting. Anyway, that's a different problem.
I think that, while there is a bit less work being done, the difference is negligible, especially compared to all the work that's being done outside of |
567599a
to
ba7fb6a
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.
Nice 👍
@@ -1024,6 +1041,8 @@ class RichText extends Component { | |||
onKeyUp={ this.onSelectionChange } | |||
onMouseUp={ this.onSelectionChange } | |||
onTouchEnd={ this.onSelectionChange } | |||
contentEditable |
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.
Technically we previously applied props such that someone could contentEditable
. I don't think that's a use case we want to support though 😄
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.
Right. I don't think we should support that for now. We might in the future, maybe through a disabled
or readonly
prop. But probably not by directly setting contentEditable
.
Co-Authored-By: Andrew Duthie <[email protected]>
Thanks a lot for the review @aduth! |
Description
This PR eliminates our own diffing for attributes on the content editable element.
Benefits:
aria-
attributes on every render.reversed
orstart
etc..Editable
component.shouldComponentUpdate
hack.How has this been tested?
Screenshots
Types of changes
Checklist: