mirror of
https://github.com/google/blockly.git
synced 2026-05-29 23:40:08 +02:00
feat: Adjacent label fields are combined when composing ARIA labels (#9873)
* feat: Adjacent label fields are combined when composing ARIA labels * removed unneacessary else block
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
|
||||
import type {BlockSvg} from './block_svg.js';
|
||||
import {ConnectionType} from './connection_type.js';
|
||||
import {FieldLabel} from './field_label.js';
|
||||
import type {Input} from './inputs/input.js';
|
||||
import {inputTypes} from './inputs/input_types.js';
|
||||
import {
|
||||
@@ -123,6 +124,10 @@ export function configureAriaRole(block: BlockSvg) {
|
||||
* `lookback` attribute is specified, all of the fields on the row immediately
|
||||
* above the Input will be used instead.
|
||||
*
|
||||
* If the input contains multiple adjacent FieldLabel fields, they will be
|
||||
* combined together into a singular label string so that screenreaders can
|
||||
* know to read them together as one piece of text.
|
||||
*
|
||||
* Empty field labels are excluded because they don't provide useful context.
|
||||
* Fields should generally have a helpful label, but there are exceptions, such
|
||||
* as when empty label fields are used to control the layout of a block.
|
||||
@@ -140,9 +145,32 @@ export function computeFieldRowLabel(
|
||||
verbosity = Verbosity.STANDARD,
|
||||
): string[] {
|
||||
const includeTypeInfo = verbosity >= Verbosity.LOQUACIOUS;
|
||||
let adjacentFieldLabels: Array<string> = [];
|
||||
const fieldRowLabel = input.fieldRow
|
||||
.filter((field) => field.isVisible())
|
||||
.map((field) => field.computeAriaLabel(includeTypeInfo));
|
||||
.flatMap((field, index, visibleFields) => {
|
||||
const isFieldLabel = field instanceof FieldLabel;
|
||||
if (isFieldLabel) {
|
||||
if (
|
||||
index < visibleFields.length - 1 &&
|
||||
visibleFields[index + 1] instanceof FieldLabel
|
||||
) {
|
||||
// Both this item and the next item are FieldLabels. We want to
|
||||
// combine these, so we add this one to the list for later handling.
|
||||
adjacentFieldLabels.push(field.computeAriaLabel(includeTypeInfo));
|
||||
return [];
|
||||
} else if (adjacentFieldLabels.length >= 1) {
|
||||
// There is at least one adjacent FieldLabel before this one but none
|
||||
// after. Combine the FieldLabels into one string.
|
||||
adjacentFieldLabels.push(field.computeAriaLabel(includeTypeInfo));
|
||||
const label = adjacentFieldLabels.join(' ');
|
||||
adjacentFieldLabels = [];
|
||||
return label;
|
||||
}
|
||||
}
|
||||
return field.computeAriaLabel(includeTypeInfo);
|
||||
});
|
||||
|
||||
if (!fieldRowLabel.length && lookback) {
|
||||
const inputs = input.getSourceBlock().inputList;
|
||||
const index = inputs.indexOf(input);
|
||||
|
||||
@@ -369,12 +369,29 @@ suite('Inputs', function () {
|
||||
// AriaLabelProvider and without setting the provider (the default label)
|
||||
assert.equal(labelA, labelB);
|
||||
});
|
||||
test('Field labels are comma separated', function () {
|
||||
this.block.appendDummyInput().appendField('first').appendField('second');
|
||||
test('Labels for fields are comma separated', function () {
|
||||
this.block
|
||||
.appendDummyInput()
|
||||
.appendField('first')
|
||||
.appendField(new Blockly.FieldNumber(0));
|
||||
|
||||
const label = this.block.getAriaLabel();
|
||||
|
||||
assert.include(label, 'first, second');
|
||||
assert.include(label, 'first, 0');
|
||||
});
|
||||
test('Adjacent labels for FieldLabels are combined into one field.', function () {
|
||||
this.block
|
||||
.appendDummyInput()
|
||||
.appendField('first')
|
||||
.appendField('second')
|
||||
.appendField(new Blockly.FieldNumber(0))
|
||||
.appendField('third')
|
||||
.appendField('fourth')
|
||||
.appendField('fifth');
|
||||
|
||||
const label = this.block.getAriaLabel();
|
||||
|
||||
assert.include(label, 'first second, 0, third fourth fifth');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user