feat: add `aria-required` attributes to WC form fields (#48371)

* feat: add `aria-required` attributes to WC form fields

* Add changefile(s) from automation for the following project(s): woocommerce

* added tests for radio fields

* WIP

* WIP

* yoda, space

* Update functions.php

* WIP

* WIP

* Add changefile(s) from automation for the following project(s): woocommerce

* Add changefile(s) from automation for the following project(s): woocommerce

* Update plugins/woocommerce/tests/legacy/unit-tests/templates/functions.php

Co-authored-by: Alex Florisca <alex.florisca@automattic.com>

* fix checkbox required attribute, add tests

* lint

* Add changefile(s) from automation for the following project(s): woocommerce

* importing changes from Thomas' branch, aria-hidden on abbr

* Add changefile(s) from automation for the following project(s): woocommerce

* added hidden also on JS changes

* template number change

* forgot to commit these changes

* porting of changes from selectWoo repository

* undo unwanted changes

* Update checkout e2e to stop looking for * in field labels

* removed aria-hidden to abbr, to avoid regressions across multiple repos

* lint

---------

Co-authored-by: github-actions <github-actions@github.com>
Co-authored-by: Alex Florisca <alex.florisca@automattic.com>
Co-authored-by: Thomas Roberts <thomas.roberts@automattic.com>
This commit is contained in:
Francesco 2024-07-30 12:41:23 +02:00 committed by GitHub
parent d080f44c17
commit 81d20d8d32
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 109 additions and 1 deletions

View File

@ -0,0 +1,4 @@
Significance: patch
Type: update
feat: add `aria-required` attributes to WC form fields

View File

@ -60,6 +60,7 @@ jQuery( function( $ ) {
var select2_args = $.extend({
placeholder: $this.attr( 'data-placeholder' ) || $this.attr( 'placeholder' ) || '',
label: $this.attr( 'data-label' ) || null,
required: $this.attr( 'aria-required' ) === 'true' || null,
width: '100%'
}, getEnhancedSelectFormatString() );

View File

@ -1392,9 +1392,14 @@ S2.define('select2/selection/base',[
var id = container.id + '-container';
var resultsId = container.id + '-results';
var searchHidden = this.options.get('minimumResultsForSearch') === Infinity;
var isRequired = this.options.get('required') === true;
this.container = container;
if (isRequired) {
this.$selection.attr('aria-required', 'true')
}
this.$selection.on('focus', function (evt) {
self.trigger('focus', evt);
});
@ -1553,6 +1558,11 @@ S2.define('select2/selection/single',[
var id = container.id + '-container';
var isRequired = this.options.get('required') === true;
if (isRequired) {
this.$selection.find('.select2-selection__rendered').attr('aria-required', 'true')
}
this.$selection.find('.select2-selection__rendered')
.attr('id', id)
.attr('role', 'textbox')
@ -5069,6 +5079,10 @@ S2.define('select2/options',[
this.options.disabled = $e.prop('disabled');
}
if (!this.options.required) {
this.options.required = $e.prop('required');
}
if (this.options.language == null) {
if ($e.prop('lang')) {
this.options.language = $e.prop('lang').toLowerCase();

View File

@ -2864,6 +2864,12 @@ if ( ! function_exists( 'woocommerce_form_field' ) ) {
}
if ( $args['required'] ) {
// hidden inputs are the only kind of inputs that don't need an `aria-required` attribute.
// checkboxes apply the `custom_attributes` to the label - we need to apply the attribute on the input itself, instead.
if ( ! in_array( $args['type'], array( 'hidden', 'checkbox' ), true ) ) {
$args['custom_attributes']['aria-required'] = 'true';
}
$args['class'][] = 'validate-required';
$required = '&nbsp;<abbr class="required" title="' . esc_attr__( 'required', 'woocommerce' ) . '">*</abbr>';
} else {
@ -2988,12 +2994,13 @@ if ( ! function_exists( 'woocommerce_form_field' ) ) {
}
$field .= sprintf(
'<input type="checkbox" name="%1$s" id="%2$s" value="%3$s" class="%4$s" %5$s /> %6$s',
'<input type="checkbox" name="%1$s" id="%2$s" value="%3$s" class="%4$s" %5$s%6$s /> %7$s',
esc_attr( $key ),
esc_attr( $args['id'] ),
esc_attr( $args['checked_value'] ),
esc_attr( 'input-checkbox ' . implode( ' ', $args['input_class'] ) ),
checked( $value, $args['checked_value'], false ),
$args['required'] ? ' aria-required="true"' : '',
wp_kses_post( $args['label'] )
);

View File

@ -193,4 +193,86 @@ class WC_Tests_Template_Functions extends WC_Unit_Test_Case {
$this->assertEquals( $expected_html, $actual_html );
}
/**
* Test: test_radio_not_required_field.
*/
public function test_radio_not_required_field() {
$actual_html = woocommerce_form_field(
'test',
array(
'type' => 'radio',
'id' => 'test',
'required' => false,
'options' => array(
'1' => 'Option 1',
'2' => 'Option 2',
),
'return' => true,
),
'1'
);
$this->assertStringNotContainsString( 'aria-required', $actual_html );
}
/**
* Test: test_radio_required_field.
*/
public function test_radio_required_field() {
$actual_html = woocommerce_form_field(
'test',
array(
'type' => 'radio',
'id' => 'test_radio',
'required' => true,
'options' => array(
'1' => 'Option 1',
'2' => 'Option 2',
),
'return' => true,
),
'1'
);
$expected_html = '<p class="form-row validate-required" id="test_radio_field" data-priority=""><span class="woocommerce-input-wrapper"><input type="radio" class="input-radio " value="1" name="test" aria-required="true" id="test_radio_1" checked=\'checked\' /><label for="test_radio_1" class="radio ">Option 1</label><input type="radio" class="input-radio " value="2" name="test" aria-required="true" id="test_radio_2" /><label for="test_radio_2" class="radio ">Option 2</label></span></p>';
$this->assertEquals( $expected_html, $actual_html );
}
/**
* Test: test_checkbox_not_required_field.
*/
public function test_checkbox_not_required_field() {
$actual_html = woocommerce_form_field(
'test',
array(
'type' => 'checkbox',
'required' => false,
'label' => 'Checkbox',
'return' => true,
),
'1'
);
$this->assertStringNotContainsString( 'aria-required', $actual_html );
}
/**
* Test: test_checkbox_required_field.
*/
public function test_checkbox_required_field() {
$actual_html = woocommerce_form_field(
'test',
array(
'type' => 'checkbox',
'required' => true,
'label' => 'Checkbox',
'return' => true,
),
'1'
);
$expected_html = '<p class="form-row validate-required" id="test_field" data-priority=""><span class="woocommerce-input-wrapper"><label class="checkbox " ><input type="checkbox" name="test" id="test" value="1" class="input-checkbox " checked=\'checked\' aria-required="true" /> Checkbox&nbsp;<abbr class="required" title="required">*</abbr></label></span></p>';
$this->assertEquals( $expected_html, $actual_html );
}
}