Skip to content

fix: improve block labels and aria roles#9834

Open
maribethb wants to merge 1 commit intoRaspberryPiFoundation:v13from
maribethb:block-label
Open

fix: improve block labels and aria roles#9834
maribethb wants to merge 1 commit intoRaspberryPiFoundation:v13from
maribethb:block-label

Conversation

@maribethb
Copy link
Copy Markdown
Contributor

The basics

The details

Resolves

Fixes #9802
Fixes #9804
Partially addresses #9793 (actually does fix it technically but making a follow up change related)
Fixes #9790
Fixes RaspberryPiFoundation/blockly-keyboard-experimentation#789

Proposed Changes

  • only include "replaceable" text for shadow blocks in verbose output, as requested by microbit
  • only include field type info in verbose block text, or when a field itself is focused
  • don't include custom input labels in block text. the custom labels will be used in a couple other places instead, in follow up PRs (one for move mode mike is working on and one for an issue we've discussed over chat and haven't filed yet)
  • don't include "begin stack" in the flyout or in move mode
  • fix up full-block fields markup
    • this is complex because the way we determine whether or not a block is a full-block field block is dumb. i'm making a follow up change to address that, but it's a breaking change, and i wanted to separate it out.
    • also complex because we handle this by returning the field's focusable element as the block's focusable element, which is weird. there's a bit of tomfoolery needed to make this work with the id of the field, but otherwise it's not too bad.
    • a bunch of logic to make sure we're setting the role and label correctly for these fields that are pretending they're blocks.
    • added a getFullBlockField method to facilitate checking this. this is different than what's in the design doc for reasons i put in a comment in the design doc.
    • improved the jsdoc for the isSimpleReporter method to better explain what that means.
    • since the logic for whether/how to set aria markup for full-block fields is complex, i moved it to the base field class and had subclasses override it where needed to set customized labels and other states.

Reason for Changes

Makes aria markup better

Test Coverage

Fixed the tests, removed some that assert behavior we don't actually want.
I skipped some tests related to custom input labels because I'm about to implement the custom input labels in a separate PR and I'll unskip them then.

Documentation

maybe for setting aria for custom fields, but it depends how we write the documentation.

Additional Information

@maribethb maribethb requested a review from a team as a code owner May 7, 2026 19:33
@maribethb maribethb requested a review from mikeharv May 7, 2026 19:33
@github-actions github-actions Bot added the PR: fix Fixes a bug label May 7, 2026
@@ -2002,6 +2003,7 @@ export class BlockSvg
* Updates the ARIA label, role and roledescription for this block.
*/
private recomputeAriaAttributes() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Elsewhere, these methods are called recomputeAriaContext. Worth renaming?

try {
focusableElement = this.getFocusableElement();
} catch {
// just return because the field hasn't been init yet
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Capitalize and add period if this will be around long-term.

// top-level full-block fields in the flyout need to have their
// roledescription set. this can't happen in the flyout code because
// the field hasn't been initialized yet then.
// these blocks should also have the rest of the state in this method set.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Add capital letters

aria.setRole(focusableElement, aria.Role.PRESENTATION);
aria.clearState(focusableElement, aria.State.LABEL);
return false;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Are we no longer using the button role for clickable images? It possible for an image field to become clickable after it's made? If so, would the outdated 'presentation' role need to be cleared?
If we are changing things here, we should probably also update or simplify the comment above.

let label = this.computeAriaLabel(true);

if (this.isCurrentlyEditable?.()) {
if (this.isCurrentlyEditable() && !this.getSourceBlock()?.isInFlyout) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If we're in a flyout, would we have already returned false earlier above? Not sure we need to check .isInFlyout again.


test('Blocks without inputs are properly labeled', function () {
const block = this.makeBlock('math_random_float');
const block = this.makeBlock('logic_boolean');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Any particular reason for this change?

suite('of bubbles', function () {
setup(async function () {
const commentBlock = this.workspace.newBlock('logic_boolean');
const commentBlock = this.workspace.newBlock('logic_compare');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also curious about this change.

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

Labels

PR: fix Fixes a bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants