Repository navigation
fix: make repeater row button names unique - #976
Conversation
|
Thanks for making the repeater friendlier for screen reader users, @Pranjal1423! The positional names ("Remove choice 2 of 3") are a big improvement and they renumber correctly on reorder. Two things on the field-label path. const slot = this.querySelector( `:scope > [slot="row-${ CSS.escape( key ) }"]` );
const name = CSS.escape( rowLabelFrom );
const field = slot?.querySelector( `[name="${ name }"], [data-field="${ name }"], #${ name }` );Also, once a label is found the position is dropped, so two rows with the same text get identical names again. Keeping the position, and routing the strings through import { __, sprintf } from '../../../i18n';
/* translators: 1: row label, 2: row position, 3: total rows. */
remove: sprintf( __( 'Remove %1$s (%2$d of %3$d)' ), label, pos, total ),Last bit: the |
…m/Pranjal1423/desktop-mode into fix/repeater-accessible-row-names
Rows and labelling fields are now found by comparing attribute values instead of building a selector, so arbitrary keys and field names (`items[0][title]`, `1st`) need no escaping and the hand-written `CSS.escape` fallback goes away. Only direct children are matched, as `:scope >` did. Row names are read from the light DOM at render time, so a `data-label` or `aria-label` written from code, a renamed field or an added row kept the old name until something else re-rendered the repeater. A MutationObserver on the rows now requests a render for those changes. A field value set from code still needs an `input` event, which the help text now says.
epeicher
left a comment
There was a problem hiding this comment.
Thanks @Pranjal1423 for addressing the comments! I pushed a small commit on top of your changes and tested it; it works as expected. Changes LGTM!
Fixes #946
In
<os-repeater>, every row's action buttons (reorder handles and remove button) were named using just the staticrow-labelattribute (e.g.aria-label="Remove choice"andaria-label="Move choice up").When tabbing through multiple rows with a screen reader, every remove button had the exact same accessible name, giving users no way to tell which row was being removed or moved without relying on visual position.
What does this change do?
Remove choice 2 of 3,Move choice 2 up,Move choice 2 down).row-label-from="<field>"is passed or a row carriesdata-label="..."/aria-label="...", that label is used instead (e.g.,Remove Drafting), falling back to positional numbering if the field is blank or new.row-label-fromis set, typing into the input updates the button's accessible name in place without stealing focus.How to test:
document.querySelector('os-repeater').keys = ['a', 'b', 'c']).#shadow-rootof the rows in DevTools:Remove choice 1 of 3,Remove choice 2 of 3,Remove choice 3 of 3).Move choice 1 up,Move choice 1 down, etc.).row-label-from="title"and provide child<input name="title" value="Draft" />:Remove Draft.Remove choice 1 of 3.##After fix
