-
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
Try: Manage focus through EditableProvider #2108
Conversation
Codecov Report
@@ Coverage Diff @@
## master #2108 +/- ##
==========================================
+ Coverage 20.34% 20.94% +0.59%
==========================================
Files 135 136 +1
Lines 4237 4321 +84
Branches 722 735 +13
==========================================
+ Hits 862 905 +43
- Misses 2843 2873 +30
- Partials 532 543 +11
Continue to review full report at Codecov.
|
I was a bit sceptical about this but the fact that it's opt-in is a good thing IMO. If a block decides to explicitly handle the focus, it should opt-in (using a specific prop maybe). I think if we follow this approach, we should try to avoid the necessity of the The event emitter bothers a bit though, it's hard to follow. I wonder if we can't replace it with |
To me, requiring blocks to use This approach would also make it easier for #2296. In order to move the logic to editable, it needs to be aware of the previous and last block. With the EditableProvider I wouldn't have to pass these through all the block components. |
@iseulde These are great points I totally overlooked. If we adopted something like this, it'd be possible in most cases for block implementers to just render the block controls and not worry about focus (also prevents from implementers forgetting to include this check). Now, whether block controls are in fact separate from |
A challenge here is knowing how to associate the Fill of individual blocks with the Slot for toolbar controls, since the slot is "global". One option might be to assign a unique name for the toolbar slot of each block (maybe using its |
Going to take a different approach here. |
This pull request seeks to explore options for removing the need for block implementers to manage focus state of a block, often by passing through
focus
andsetFocus
props to the Editable component.Implementation notes:
It builds upon the
EditableProvider
introduced in #1943, which uses React context to communicate transparently between the editor infrastructure and Editable instances.This is made more difficult because it requires bidirectional communication (Editable
onFocus
-> Editor, Editorfocus
-> Editable), and detecting changes in context values is not accounted in components implementingshouldComponentUpdate
(facebook/react#2517). Taking cues from a project react-side-context, the workaround here is to create an event emitter in state which detects changes and emits achange
event to incur a forced update.In retrospect, I found that many blocks are making a conscious choice to use
focus
to determine whether block inspector or toolbar controls should be rendered. In most cases, they are primarily concerned that it is truthy ("is focussed"), and in a few cases are managing disparate focus states (quote focused in text vs. caption). The latter of these requiressetFocus
, whereas the former does not. In any case, there's not as much benefit to be gained here as I'd hoped, aside from simple cases where focus is managed outside the view of the block implementer. It could be argued that explicitness is actually favorable here, both to clarify actual behavior, and expose block implementers to available features.This all said, I'm not sure if this is something we ought to move on, but thought I'd publish all the same to invite discussion on ideas of using context or other patterns to remove concerns from the responsibility of block implementers.