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

feat(WCAG): Associate field descriptions to inputs #4896

Conversation

pedrobonamin
Copy link
Contributor

@pedrobonamin pedrobonamin commented Sep 5, 2023

Description

In the editor, some fields have a description in addition to just a label. This description is not associated with the field in code. This makes it harder to discover for some users, including screenreader users.

With this changes, when fields have a description, this description will be associated to the input by using aria-describedby. This is discoverable by screen readers.

Note: Couldn't make it work in portable text editor correctly, as the focused element in PTE is not the same one that receives the aria-describedby value when passing the prop , a follow up ticket will be created for this.

What to review

Is there any missing field type to consider?
To trigger the descriptions using voice over functionality you have to:

  1. Focus on the field, voiceover will let you know it has more information available.
  2. Click cmd+shift+option+/ to show the information.

Notes for release

WCAG : When fields have a description, associate them to the input by using aria-describedby.

aria-describedby.accesibility.mov

@vercel
Copy link

vercel bot commented Sep 5, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
performance-studio ✅ Ready (Inspect) Visit Preview Sep 13, 2023 2:25pm
test-studio ✅ Ready (Inspect) Visit Preview 💬 Add feedback Sep 13, 2023 2:25pm
1 Ignored Deployment
Name Status Preview Comments Updated (UTC)
studio-workshop ⬜️ Ignored (Inspect) Visit Preview Sep 13, 2023 2:25pm

@github-actions
Copy link
Contributor

github-actions bot commented Sep 5, 2023

Component Testing Report Updated Sep 13, 2023 2:31 PM (UTC)

File Status Duration Passed Skipped Failed
formBuilder/ArrayInput.spec.tsx ✅ Passed (Inspect) 6s 3 0 0
formBuilder/inputs/PortableText/Annotations.spec.tsx ✅ Passed (Inspect) 10s 3 0 0
formBuilder/inputs/PortableText/Decorators.spec.tsx ✅ Passed (Inspect) 10s 6 0 0
formBuilder/inputs/PortableText/Input.spec.tsx ✅ Passed (Inspect) 13s 9 0 0
formBuilder/inputs/PortableText/ObjectBlock.spec.tsx ✅ Passed (Inspect) 46s 18 0 0
formBuilder/inputs/PortableText/Styles.spec.tsx ✅ Passed (Inspect) 10s 6 0 0
formBuilder/inputs/PortableText/Toolbar.spec.tsx ✅ Passed (Inspect) 6s 3 0 0

@pedrobonamin pedrobonamin force-pushed the feature/edx-419-field-descriptions-not-associated-with-fields-wcag-131 branch from d9bbd02 to 39b2979 Compare September 8, 2023 06:57
@github-actions
Copy link
Contributor

github-actions bot commented Sep 8, 2023

No changes to documentation

@@ -67,6 +67,7 @@ export type PortableTextEditableProps = {
scrollSelectionIntoView?: ScrollSelectionIntoViewFunction
selection?: EditorSelection
spellCheck?: boolean
describedBy?: string
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we rather support arbitrary props forwarding here, as there are already quite a few props to this component?

That way we could send in our own HTML props whatever they might be, and don't have to be overly specific about props we don't really care about in this context.

So something like this:

      <SlateEditable
        {...props}
        autoFocus={false}
        className={props.className || 'pt-editable'}
        decorate={decorate}
        onBlur={handleOnBlur}
        onCopy={handleCopy}
        onDOMBeforeInput={handleOnBeforeInput}
        onFocus={handleOnFocus}
        onKeyDown={handleKeyDown}
        onPaste={handlePaste}
        readOnly={readOnly}
        renderElement={renderElement}
        renderLeaf={renderLeaf}
        scrollSelectionIntoView={scrollSelectionIntoViewToSlate}
      />

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be simpler, but the problem that I see doing that is that we are memoizing the component and we will need to listen to those changes in the useMemo.
If we add the props object to the useMemo, every re render will recalculate the useMemo again.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we rather support arbitrary props forwarding here

For that to work we'll also have to make PortableTextEditableProps extend ComponentProps<typeof SlateEditable>, right? I don't have the full picture, but seems nice to keep the props interface minimal here? Guess it's also something we can always consider doing later too.

On a related note: Any reason to not name it aria-describedby here? That would help us avoid ambiguity if we decided to support arbitrary props forwarding some time in the future.

* and added to the descriptive element id.
* @internal
*/
export function constructDescriptionId(
Copy link
Member

@bjoerge bjoerge Sep 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor detail, but I think it's more common for us to use create (or get) as prefix for this type of utility functions, so maybe rename to createDescriptionId if it's not too much trouble?

@@ -67,6 +67,7 @@ export type PortableTextEditableProps = {
scrollSelectionIntoView?: ScrollSelectionIntoViewFunction
selection?: EditorSelection
spellCheck?: boolean
describedBy?: string
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we rather support arbitrary props forwarding here

For that to work we'll also have to make PortableTextEditableProps extend ComponentProps<typeof SlateEditable>, right? I don't have the full picture, but seems nice to keep the props interface minimal here? Guess it's also something we can always consider doing later too.

On a related note: Any reason to not name it aria-describedby here? That would help us avoid ambiguity if we decided to support arbitrary props forwarding some time in the future.

Copy link
Member

@bjoerge bjoerge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Thank you @pedrobonamin 🙌🏼

@skogsmaskin
Copy link
Member

@bjoerge, @pedrobonamin - I have made a suggestion on how we can forward those props in a PR targeting this branch:

#4923

Copy link
Member

@skogsmaskin skogsmaskin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please consider my suggestion on how we can support whatever html props.

@bjoerge
Copy link
Member

bjoerge commented Sep 13, 2023

Please consider my #4896 (comment) on how we can support whatever html props.

I'm OK with this approach 👍🏼

This will forward html props for the editable element to the slate editable.
It will also get rid of the need of having an own wrapper div element to
put the ref on. Point it directly on the editable element.
This doesn't need to be memoed, at least not after supporting restProps here.

Debugging shows that the nodes inside are not re-rendered by removing this memo,
which is what we care about.
@pedrobonamin pedrobonamin added this pull request to the merge queue Sep 13, 2023
Merged via the queue into next with commit e7a8e32 Sep 13, 2023
16 checks passed
@pedrobonamin pedrobonamin deleted the feature/edx-419-field-descriptions-not-associated-with-fields-wcag-131 branch September 13, 2023 14:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants