diff --git a/packages/devextreme/js/__internal/ui/chat/messagebox.ts b/packages/devextreme/js/__internal/ui/chat/messagebox.ts index f0b3ec4c61fa..48579a876bd9 100644 --- a/packages/devextreme/js/__internal/ui/chat/messagebox.ts +++ b/packages/devextreme/js/__internal/ui/chat/messagebox.ts @@ -152,7 +152,7 @@ class MessageBox extends DOMComponent { _updateAria(value: string | null): void { $(this._textArea.$element()) .find(`.${TEXTEDITOR_INPUT_CLASS}`) - .attr('aria-describedby', value); + .attr('aria-labelledby', value); } _isValuableTextEntered(): boolean { diff --git a/packages/devextreme/js/__internal/ui/chat/messagelist.ts b/packages/devextreme/js/__internal/ui/chat/messagelist.ts index 716787d7799c..06cdcecfb94e 100644 --- a/packages/devextreme/js/__internal/ui/chat/messagelist.ts +++ b/packages/devextreme/js/__internal/ui/chat/messagelist.ts @@ -61,10 +61,9 @@ class MessageList extends Widget { super._initMarkup(); this._renderScrollable(); - this._renderMessageListContent(); - this._attachResizeObserverSubscription(); + this._updateAria(); this._suppressResizeHandling = true; } @@ -243,12 +242,6 @@ class MessageList extends Widget { return $(this._scrollable.container()).get(0); } - _clean(): void { - this._messageGroups = []; - - super._clean(); - } - _isMessageAddedToEnd(value: Message[], previousValue: Message[]): boolean { const valueLength = value.length; const previousValueLength = previousValue.length; @@ -286,6 +279,24 @@ class MessageList extends Widget { } } + _updateAria(): void { + const aria = { + role: 'log', + atomic: 'false', + label: 'Message list', + live: 'polite', + relevant: 'additions', + }; + + this.setAria(aria); + } + + _clean(): void { + this._messageGroups = []; + + super._clean(); + } + _optionChanged(args: OptionChanged): void { const { name, value, previousValue } = args; diff --git a/packages/devextreme/playground/jquery.html b/packages/devextreme/playground/jquery.html index f28a06634a6a..63b82eef0f99 100644 --- a/packages/devextreme/playground/jquery.html +++ b/packages/devextreme/playground/jquery.html @@ -53,7 +53,7 @@

Te diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets/chatParts/chat.markup.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets/chatParts/chat.markup.tests.js index afd3d457a4ad..f43020c0d858 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets/chatParts/chat.markup.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets/chatParts/chat.markup.tests.js @@ -102,11 +102,11 @@ QUnit.module('Chat', moduleConfig, () => { }, ].forEach(({ attribute, expectedValue }) => { QUnit.test(`root element should have correct ${attribute}`, function(assert) { - assert.strictEqual(this.$element.attr(attribute), expectedValue); + assert.strictEqual(this.$element.attr(attribute), expectedValue, `${attribute} is correct`); }); }); - QUnit.test('textarea should not have aria-describedby attribute if there are items', function(assert) { + QUnit.test('textarea should not have aria-labelledby attribute if there are items', function(assert) { this.reinit({ items: [ { text: '1' }, @@ -116,17 +116,17 @@ QUnit.module('Chat', moduleConfig, () => { const $textArea = this.$element.find(`.${TEXTEDITOR_INPUT_CLASS}`); - assert.strictEqual($textArea.attr('aria-describedby'), undefined); + assert.strictEqual($textArea.attr('aria-labelledby'), undefined); }); - QUnit.test('textarea should have correct aria-describedby attribute if there are not items', function(assert) { + QUnit.test('textarea should have correct aria-labelledby attribute if there are not items', function(assert) { const $textArea = this.$element.find(`.${TEXTEDITOR_INPUT_CLASS}`); const $emptyView = this.$element.find(`.${CHAT_MESSAGELIST_EMPTY_VIEW_CLASS}`); - assert.strictEqual($textArea.attr('aria-describedby'), $emptyView.attr('id')); + assert.strictEqual($textArea.attr('aria-labelledby'), $emptyView.attr('id')); }); - QUnit.test('textarea should get rid of aria-describedby attribute if items has been added in runtime', function(assert) { + QUnit.test('textarea should get rid of aria-labelledby attribute if items has been added in runtime', function(assert) { this.instance.option({ items: [ { text: '1' }, @@ -136,10 +136,10 @@ QUnit.module('Chat', moduleConfig, () => { const $textArea = this.$element.find(`.${TEXTEDITOR_INPUT_CLASS}`); - assert.strictEqual($textArea.attr('aria-describedby'), undefined); + assert.strictEqual($textArea.attr('aria-labelledby'), undefined); }); - QUnit.test('textarea should get aria-describedby attribute if items has been removed in runtime', function(assert) { + QUnit.test('textarea should get aria-labelledby attribute if items has been removed in runtime', function(assert) { this.reinit({ items: [ { text: '1' }, @@ -152,7 +152,7 @@ QUnit.module('Chat', moduleConfig, () => { const $textArea = this.$element.find(`.${TEXTEDITOR_INPUT_CLASS}`); const $emptyView = this.$element.find(`.${CHAT_MESSAGELIST_EMPTY_VIEW_CLASS}`); - assert.strictEqual($textArea.attr('aria-describedby'), $emptyView.attr('id')); + assert.strictEqual($textArea.attr('aria-labelledby'), $emptyView.attr('id')); }); }); }); diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets/chatParts/messageList.markup.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets/chatParts/messageList.markup.tests.js index eeeb17077e83..71ae32be874c 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets/chatParts/messageList.markup.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets/chatParts/messageList.markup.tests.js @@ -51,13 +51,6 @@ QUnit.module('MessageList', moduleConfig, () => { assert.strictEqual(this.$element.find(`.${CHAT_MESSAGELIST_EMPTY_VIEW_CLASS}`).length, 1); }); - QUnit.test('container should be have id attribute', function(assert) { - const id = this.$element.find(`.${CHAT_MESSAGELIST_EMPTY_VIEW_CLASS}`).attr('id'); - - assert.strictEqual(id !== undefined, true); - assert.strictEqual(id !== '', true); - }); - QUnit.test('container should not be rendered if there are messages', function(assert) { this.reinit({ items: [{}] @@ -94,4 +87,40 @@ QUnit.module('MessageList', moduleConfig, () => { assert.strictEqual($emptyView.find(`.${CHAT_MESSAGELIST_EMPTY_PROMPT_CLASS}`).length, 1); }); }); + + QUnit.module('Accessibility', () => { + QUnit.test('container should be have id attribute', function(assert) { + const id = this.$element.find(`.${CHAT_MESSAGELIST_EMPTY_VIEW_CLASS}`).attr('id'); + + assert.strictEqual(id !== undefined, true); + assert.strictEqual(id !== '', true); + }); + + [ + { + attribute: 'role', + expectedValue: 'log', + }, + { + attribute: 'aria-atomic', + expectedValue: 'false', + }, + { + attribute: 'aria-label', + expectedValue: 'Message list', + }, + { + attribute: 'aria-live', + expectedValue: 'polite', + }, + { + attribute: 'aria-relevant', + expectedValue: 'additions', + }, + ].forEach(({ attribute, expectedValue }) => { + QUnit.test(`element should have correct attribute ${attribute}`, function(assert) { + assert.strictEqual(this.$element.attr(attribute), expectedValue, `${attribute} is correct`); + }); + }); + }); });