diff --git a/packages/devextreme/js/__internal/ui/list/list.base.ts b/packages/devextreme/js/__internal/ui/list/list.base.ts index 80dad79b1d6c..354c83b8d304 100644 --- a/packages/devextreme/js/__internal/ui/list/list.base.ts +++ b/packages/devextreme/js/__internal/ui/list/list.base.ts @@ -1003,7 +1003,14 @@ export class ListBase extends CollectionWidget { }; this.setAria(elementAria, this.$element()); - this.setAria({ role: 'application' }, this._focusTarget()); + + const { items } = this.option(); + + if (items?.length) { + this.setAria({ role: 'application' }, this._focusTarget()); + } else { + this._focusTarget().removeAttr('role'); + } this._setListAria(); } diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.editors/lookup.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.editors/lookup.tests.js index 1aba58ab1675..7c7672347992 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.editors/lookup.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.editors/lookup.tests.js @@ -3734,7 +3734,6 @@ if(devices.real().deviceType === 'desktop') { const listItemContainerAttributes = { tabindex: searchEnabled ? '-1' : '0', - role: 'application', }; let fieldAttributes = { @@ -3891,7 +3890,7 @@ if(devices.real().deviceType === 'desktop') { const $scrollView = $list.find(`.${SCROLL_VIEW_CONTENT_CLASS}`); const $itemsContainer = $list.find(`.${LIST_ITEMS_CLASS}`); - helper.checkAttributes($scrollView, { tabindex: '-1', role: 'application' }); + helper.checkAttributes($scrollView, { tabindex: '-1' }); helper.checkAttributes($itemsContainer, { }); helper.widget.option(dataSourcePropertyName, [1, 2, 3]); @@ -3899,7 +3898,7 @@ if(devices.real().deviceType === 'desktop') { helper.checkAttributes($itemsContainer, { 'aria-label': 'Items', role: 'listbox' }); helper.widget.option(dataSourcePropertyName, []); - helper.checkAttributes($scrollView, { tabindex: '-1', role: 'application' }); + helper.checkAttributes($scrollView, { tabindex: '-1' }); helper.checkAttributes($itemsContainer, { }); }); }); diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.editors/selectBox.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.editors/selectBox.tests.js index 420efeba5a61..fc4136ec5b1f 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.editors/selectBox.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.editors/selectBox.tests.js @@ -6150,7 +6150,7 @@ if(devices.real().deviceType === 'desktop') { helper.checkAttributes(helper.widget._list.$element(), listAttributes, localizedRoleDescription); const $listItemContainer = helper.widget._list.$element().find(`.${SCROLLVIEW_CONTENT_CLASS}`); - helper.checkAttributes($listItemContainer, { role: 'application' }, 'scrollview content'); + helper.checkAttributes($listItemContainer, { }, 'scrollview content'); const inputAttributes = { autocomplete: 'off', @@ -6183,7 +6183,7 @@ if(devices.real().deviceType === 'desktop') { listAttributes.id = helper.widget._listId; helper.checkAttributes(helper.widget._list.$element(), listAttributes, 'list'); - helper.checkAttributes($listItemContainer, { role: 'application' }, 'scrollview content'); + helper.checkAttributes($listItemContainer, { }, 'scrollview content'); inputAttributes['aria-controls'] = helper.widget._listId; inputAttributes['aria-owns'] = helper.widget._popupContentId; diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets/listParts/commonTests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets/listParts/commonTests.js index 035f743a5a45..4206fe19307e 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets/listParts/commonTests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets/listParts/commonTests.js @@ -5276,4 +5276,45 @@ QUnit.module('Accessibility', () => { 'checkbox aria-label updated after runtime change'); }); + QUnit.module('Empty list cannot have role on scrollview content (T1329047)', () => { + const POPULATED_ITEMS = ['Item 1']; + + const createList = (options) => $('#list').dxList(options).dxList('instance'); + + const getScrollViewContent = (instance) => + instance.$element().find(`.${SCROLLVIEW_CONTENT_CLASS}`).get(0); + + const getScrollViewContentRole = (instance) => + getScrollViewContent(instance).getAttribute('role'); + + QUnit.test('scrollview-content should not have role when list is empty on init', function(assert) { + const instance = createList({ items: [] }); + + assert.strictEqual(getScrollViewContentRole(instance), null); + }); + + QUnit.test('scrollview-content should have role="application" when list has items', function(assert) { + const instance = createList({ items: POPULATED_ITEMS }); + + assert.strictEqual(getScrollViewContentRole(instance), 'application'); + }); + + QUnit.test('scrollview-content role should be removed when items change from populated to empty', function(assert) { + const instance = createList({ items: POPULATED_ITEMS }); + + instance.option('items', []); + + assert.strictEqual(getScrollViewContentRole(instance), null); + }); + + QUnit.test('scrollview-content role should be restored when items change from empty to populated', function(assert) { + const instance = createList({ items: [] }); + + instance.option('items', POPULATED_ITEMS); + + assert.strictEqual(getScrollViewContentRole(instance), 'application'); + }); + }); + + });