Skip to content
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

Introduce a way to manage focus on the RichText editor #9740

Closed
afercia opened this issue Sep 10, 2018 · 25 comments
Closed

Introduce a way to manage focus on the RichText editor #9740

afercia opened this issue Sep 10, 2018 · 25 comments
Labels
[Feature] Block API API that allows to express the block paradigm. [Feature] Rich Text Related to the Rich Text component that allows developers to render a contenteditable [Feature] Writing Flow Block selection, navigation, splitting, merging, deletion... [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). [Package] Editor /packages/editor
Milestone

Comments

@afercia
Copy link
Contributor

afercia commented Sep 10, 2018

See discussion on Slack: https://wordpress.slack.com/archives/C02QB2JS7/p1536570671000100

In 4.0 the RichText onSetup prop will be deprecated and changed to unstableOnSetup. To my understanding, unstableOnSetup won't be removed so soon, see #9106, because it's still necessary in current implementations of core blocks.

However, in the future there will still be the need to access the editor instance. Simple use case: managing focus. Imagine a custom block that uses one or more RichText components and needs to manage focus programmatically depending on specific workflows.

As mentioned in the Slack discussion, one option could be introducing a focus function to the RichText component. Definitely not my area of expertise, there are probably other options and considerations to explore. /Cc @iseulde @aduth

@afercia afercia added the [Package] Editor /packages/editor label Sep 10, 2018
@aduth aduth added the [Feature] Rich Text Related to the Rich Text component that allows developers to render a contenteditable label Sep 10, 2018
@aduth
Copy link
Member

aduth commented Sep 10, 2018

There are internal mechanisms with a block's context including isSelected and setFocusedElement which serve a purpose of coordinating multiple RichText in the same block. As best I can tell, they were designed to be used internal to the RichText component itself. I don't recall if it was undesirable or even possible to surface this up as an option to the block implementer.

Adding a focus function to the component interface seems reasonable enough. The main caveat is that it would be an imperative statement in its usage, vs. traditional React declarative / state-driven representation. Given the intention of focus changes to be a one-off action, this seems okay.

Related: Maybe worth noting that there is an unstableOnFocus event handler which is used by a few core blocks, maybe complementary (and thus desirable to "stabilize") as part of an introduction of a focus function. Part of its prior marking as being unstable was the desire for it to not be passing the TinyMCE-specific event object as an argument.

@aduth
Copy link
Member

aduth commented Sep 10, 2018

Related: #6419

@ellatrix
Copy link
Member

Maybe onSelect?

Additionally there's no way currently to set the focus at the end of the field.

@ellatrix
Copy link
Member

I think this needs to be addressed before API freeze. I tried to make a block with multiple RichText fields and it is impossible to manage focus, even with unstableOnFocus. Passing isSelected={ true } does nothing to focus the field if requested.

@ellatrix ellatrix added this to the 4.2 - API freeze milestone Oct 18, 2018
@ellatrix ellatrix self-assigned this Oct 18, 2018
@ellatrix
Copy link
Member

Plus we are still using unstableOnFocus in some blocks.

@aduth
Copy link
Member

aduth commented Oct 18, 2018

Imagine a custom block that uses one or more RichText components and needs to manage focus programmatically depending on specific workflows.

I tried to make a block with multiple RichText fields and it is impossible to manage focus

The use-cases here are quite vague, or I'm not sufficiently imaginative. What is such a block trying to achieve with programmatically managing focus?

@ellatrix ellatrix added the [Feature] Block API API that allows to express the block paradigm. label Oct 18, 2018
@ellatrix
Copy link
Member

E.g. When you have multiple RichText fields in a block and you'd like to manage split and merge behaviour. Currently this is all possible, except for setting focus to the correct field. The block in question I was working on is the list blocks (with multiple RichText fields), but I can imaging this being useful for many kinds of blocks with Rich input fields.

@ellatrix
Copy link
Member

At the very least I would like to see our own blocks not using unstableOnFocus.

@ellatrix
Copy link
Member

Or maybe it should be kept (call on contentEditable focus for a stable result) and be renamed to e.g. onSelect which could go together with isSelected to set focus on the field.

This could also be revised as part of the focus setting we do currently in compontentDidUpdate, which is not really the greatest logic we have in RichText. :/

@ellatrix
Copy link
Member

Related: #6419

I tried to use setFocusedElement where we currently use unstableOnFocus in the table block, but that didn't seem to work. Cc @gziolo.

@gziolo
Copy link
Member

gziolo commented Oct 24, 2018

I tried to use setFocusedElement where we currently use unstableOnFocus in the table block, but that didn't seem to work.

Yes, it was a quite complex use case. I need to refresh my memory to figure out what was blocking us from using setFocusedElement.

@gziolo
Copy link
Member

gziolo commented Oct 24, 2018

This is my previous attempt #6871 to fix it without using onFocus prop which was renamed later to unstableOnFocus as we decided to avoid landing this PR. It still needs some tinkering how to make it work in a more automated way. I think the biggest blocker was mentioned by @youknowriad in #6871 (comment):

The issue is that sometimes RichText loses the focus but we still want to keep it selected. (Link modal, toolbar buttons), It's probably doable but not simple because of the fact that popovers show outside the RichText's node.

@afercia
Copy link
Contributor Author

afercia commented Dec 5, 2018

Quoting from the duplicate issue #12587

Looks like with the removal of unstableOnSetup in #10744 there isn't a built-in way to manage focus on the RichText editable area any longer.

Managing focus is essential in some flows, especially for custom block types with multiple RichText instances. While the removal of unstableOnSetup was expected to happen without notice, a new, alternative, method was expected as well.

Other editors expose a focus method: for example, Draft.js explains very well why this is needed, see https://draftjs.org/docs/advanced-topics-managing-focus

Discussed a bit this issue with our technical team at Yoast and we'd tend to think that also all use-cases that were offered by a reference to TinyMCE would need to be offered by the wrapper, RichText in this case.

@afercia afercia added the [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). label Dec 5, 2018
@atimmer
Copy link
Member

atimmer commented Dec 6, 2018

I think this is essential functionality for an editable field component, which RichText is. I understand the choice to not expose the TinyMCE instance, but focusing an editable field is core functionality.

@youknowriad youknowriad added this to the Future: 5.x milestone Jan 9, 2019
@ellatrix ellatrix added the [Feature] Writing Flow Block selection, navigation, splitting, merging, deletion... label Jan 29, 2019
@ellatrix ellatrix removed their assignment Jan 29, 2019
@hypest
Copy link
Contributor

hypest commented May 30, 2019

👋 , with #14640 the selection logic has received a significant update, including how components (RichText in particular) get focused. I wonder if this ticket needs some updating so we better understand the current state of things. Wdyt @ellatrix ?

@chrisvanpatten
Copy link
Member

chrisvanpatten commented Jun 29, 2019

Does this relate to the situation where a RichText component within a block receives focus when a block is inserted? I'd love to have a flag to prevent that behavior (so the user has to explicitly select the RichText area to focus it) but I'm not sure if that counts as part of this issue, or in another issue :)

Could look essentially like focusOnInsert={ false }, defaulting to true to keep the current behavior.

@afercia
Copy link
Contributor Author

afercia commented Jul 4, 2019

No this is unrelated. It's about introducing a way to set focus programmatically on the contenteditable. Currently, there's no way to get a block editor (TinyMCE) instance, see original description and linked references.

@talldan
Copy link
Contributor

talldan commented Jul 18, 2019

A related issue for the table block is potentially #14904. I can think of a workaround using event handlers and element.focus(), but it'd be great if there was a way to forward focus from the surrounding td to the child RichText.

At some point I also want to introduce the ability to navigate the table block using arrow keys, which might be another use case, but also something that could use element.focus() as an intermediate step.

@afercia
Copy link
Contributor Author

afercia commented Sep 13, 2019

Update: current state of the RichText component with regards to focus management after one year this issue was created:

To recap the nature of this issue: seems to me all these changes fit only with the internal needs of Gutenberg. They don't take into consideration custom usages of RichText outside of the Gutenberg ones. Instead, plugins may need to implement their own focus management mechanisms.

Consider for example a block that uses multiple RichText components like the one below: each highlighted area is a RichText:

Screenshot 2019-09-13 at 12 08 02

One year ago, managing focus within such a block was pretty simple. Unfortunately, all the changes in the last year made it more and more challenging. At the point that providing basic keyboard accessibility is now very hard.

To me, it appears clear that Gutenberg should provide a mechanism to manage focus on the RichText instances within a block. Gutenberg removed features that made this kind of focus management possible: now, it's a Gutenberg responsibility to provide equivalent features.

@ellatrix
Copy link
Member

@afercia Looking into focus and rich text right now as I'm refactoring things internally. What do you need?

  1. There's currently a way to know when rich text receives focus through unstableOnFocus, which will be made stable with the event exposed.
  2. You can set focus by passing a ref to rich text and calling ref.current.focus() (the normal element method).

What more do you need?

If there's anything more, could you update the issue description or create a new issue? It's a bit outdated now.

@mtias mtias closed this as completed Jul 2, 2024
@afercia
Copy link
Contributor Author

afercia commented Jul 4, 2024

@mtias for history and documentation, can you please add a comment pointing to where this issue was fixed?
I think it's important in an open source project to clarify why an issue gets closed, much like it's expected on Trac, where the 'resolution' status and a comment are pretty the norm when closing a ticket.

@emeaguiar
Copy link

I am also curious to know how this is resolved now, do we have a way to set focus to a RichText component?

@mtias
Copy link
Member

mtias commented Jul 12, 2024

Given @ellatrix articulated how to focus rich text and there were no further comments on what else might be needed closing seemed appropriate to help keep the repository in shape.

@afercia
Copy link
Contributor Author

afercia commented Jul 15, 2024

Given @ellatrix articulated how to focus rich text and there were no further comments on what else might be needed closing seemed appropriate to help keep the repository in shape.

I'm not sure the feedback from @ellatrix is up to date, given unstableOnFocus is now only used in a few native files. At least, that's my understanding. I don't see any documentation about unstableOnFocus as well.

Anyways, the point is more about process. This is an open source project. Please don't close issues without a comment to explain why you are closing it. Thanks.

@ellatrix
Copy link
Member

I believe onFocus has been made stable a long time ago and works like any other React event

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Block API API that allows to express the block paradigm. [Feature] Rich Text Related to the Rich Text component that allows developers to render a contenteditable [Feature] Writing Flow Block selection, navigation, splitting, merging, deletion... [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). [Package] Editor /packages/editor