Skip to content

fix: a11y: aria-live for draft quote & attachment#4693

Draft
WofWca wants to merge 1 commit intomainfrom
wofwca/a11y-quote-and-attachment-aria-live
Draft

fix: a11y: aria-live for draft quote & attachment#4693
WofWca wants to merge 1 commit intomainfrom
wofwca/a11y-quote-and-attachment-aria-live

Conversation

@WofWca
Copy link
Member

@WofWca WofWca commented Feb 21, 2025

This is handy for the Ctrl + Up shortcut,
and also adds confirmation for when using the regular way,
i.e. context meny -> reply.
Same for attachments.

TODO:

  • I'm testing with NVDA and it seems like aria-atomic doesn't work for some reason. It only announces the changes. E.g. if the author's name didn't change, it won't announce it.
  • NVDA doesn't announce when the quote gets removed, when using the Ctrl + Down shortcut.
  • We announce the changes, but don't announce that it's a draft quote. Can this MR still be considered an improvement?

@WofWca WofWca force-pushed the wofwca/a11y-quote-and-attachment-aria-live branch from 76640e8 to 28ac245 Compare February 21, 2025 13:50
@WofWca
Copy link
Member Author

WofWca commented Feb 24, 2025

About the politeness level: maybe we want assertive?

See https://w3c.github.io/aria/#aria-live

For example, if assistive technologies can determine that a change occurred in response to a key press or a mouse click, the assistive technologies might present that change immediately even if the value of the aria-live attribute states otherwise.

@pvagner
Copy link

pvagner commented May 13, 2025

About the politeness level: maybe we want assertive?

I don't think so.
In practice assertive causes screen reader to interupt what's currently being spoken if any and start speaking the aria-live change. I think in a chat app we definatelly like to have polite level.
I would say assertive should only be used in situations where aria live region is used as a substitution to a real accessibility implementation or when we can really justify the fact we'd like to be assertive.
For example in the past google docs used to have an offscreen aria live region and it worked like a hidden interface between the app and the screen reader. The editor was not really accessible as such and the app has been using assertive live region to force screen reader to speak what was happening within the editor.

@WofWca WofWca force-pushed the wofwca/a11y-quote-and-attachment-aria-live branch from 28ac245 to 5ad3712 Compare October 20, 2025 08:02
This is handy for the Ctrl + Up shortcut,
and also adds confirmation for when using the regular way,
i.e. context menu -> reply.
Same for attachments.
<section
// Keep in mind that this element also changes when switching
// between chats.
// We probably want such changes to be announced still.
Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm I don't think so. This is confusing and useless when switching chats, switching chats can be considered a form of "navigation", thus we must not announce the changes.

I would like to refactor useDraft such that it returns loadingDraft, which we can then use to only apply aria-live when we have finished loading the draft initially.
But there is another MR pending which deals which moves useDraft to a separate file. Let's do this later to avoid conflicts.

@WofWca WofWca force-pushed the wofwca/a11y-quote-and-attachment-aria-live branch from 5ad3712 to 13b00c6 Compare October 20, 2025 08:24
@pvagner
Copy link

pvagner commented Dec 23, 2025

Hello @WofWca ,

Today morning I've got a different idea on how to possibly resolve this issue in a different way, and I'd say it's less prone to variability of aria region implementation issues within screen readers and avoids possible timing issues.

When navigating the deltachat desktop UI the chat input entry has placeholder saying something like "Type in a message". This is also being used as a screen reader accessible label for the edit control.

When there is a content above the chat input entry such as a message I am replying to, or a different content, lets change the aria-label for the chat input entry that will notify screen reader users to the fact there is something important in there.

The downside is that this will only be accessible when the chat input is focused however that's the default use case anyways so I think that's a good trade off between reliability and usability.

What do you think?

@WofWca
Copy link
Member Author

WofWca commented Jan 3, 2026

Hi @pvagner !

Interesting idea. So basically something like aria-label="Write a message; reply; attachment"?

<textarea
className={
'message-input-area' +
(browserSupportsCSSFieldSizing
? ' use-field-sizing-css-prop'
: '')
}
style={{ '--maxLines': maxLines } as React.CSSProperties}
id='composer-textarea'
ref={this.textareaRef}
rows={1}
// intent={this.state.error ? 'danger' : 'none'}
// large
value={this.props.text}
onKeyDown={this.onKeyDown}
onChange={this.onChange}
onPaste={this.props.onPaste}
placeholder={
this.props.isMessageEditingMode
? window.static_translate('edit_message')
: window.static_translate('write_message_desktop')
}
disabled={this.props.loadingDraft}
dir={
writingDirection === 'rtl'
? 'rtl'
: 'auto' /* auto is based on content but defaults to ltr */
}
spellCheck={true}
aria-keyshortcuts='Control+M'
/>

I am afraid that changing aria-label alone will not make screen readers re-announce the input though?

Another possible way is to have the label on the wrapper region, i.e. the composer region, which wraps the attachment, reply, and the input:

aria-label={
messageEditing.isEditingModeActive
? window.static_translate('edit_message')
: window.static_translate('write_message_desktop')
// We could also add chat name here to make it extra clear
// which chat we're in,
// but the "Chat" region label
// (`id='chat-section-heading'`) is probably enough.
}

@pvagner
Copy link

pvagner commented Jan 3, 2026

Hello @WofWca

Thanks for acknowledging my idea.

My assumption goes like this and I need to verify it and look through the code you are suggesting to take a look at.

  • I will press ctrl+m to jump into the text input, screen reader will announce "Write a message". This is expected and should remain like this.
  • I will press ctrl+up arrow currently message I'm replying to displays above the text entry field. Screen reader reports nothing right now. However as an addition to displaying the message above the text entry I suggest to change the aria label for the text entry to include the same text that is displayed above. Since the text entry is now focused most screen readers are expected to read its name again as it changes.
    I will try to verify this and I'll post again.

Greetings

Peter

@pvagner
Copy link

pvagner commented Jan 3, 2026

Another possible way is to have the label on the wrapper region, i.e. the composer region, which wraps the attachment, reply, and the input:

My guess is that this won't be that usefull as the label of ancestors such as groupings and pannels are only read while navigating e.g. when focus moves from one part of the UI to the other one.

Here is an example that illustrates this feature

  • When new chat has focus, pressing the tab key moves focus to the Edit group or to the Apps and media buttons. The screen reader reads the name of that button receiving the focus and before that it reads the chat name which is part of the ancestry.
  • When chat input text entry has focus, we can use ctrl+page up and ctrl+page down to move to the previous / next chat. Label of that wrapping UI element changes however screen readers usually don't read it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants