fix(table): aria-label should be use the first text content in element when column title is ReactElement in table (#38160)

* fix: aria-lable should be use the first text content in element when title is ReactElement

* fix: aria-label should be use the first text content in element when title is ReactElement

* feat: optimize code

* feat: optimize code

* feat: optimize code

* feat: optimize code

* feat: update snapshots

* feat: update snapshots

Co-authored-by: tangwenhui <tangwenhui@rd.netease.com>
This commit is contained in:
kiner-tang(文辉) 2022-10-23 15:28:26 +08:00 committed by GitHub
parent 70232ab10b
commit 21c4bcf40a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 0 deletions

View File

@ -108,6 +108,32 @@ describe('Table.sorter', () => {
expect(getNameColumn()?.getAttribute('aria-label')).toEqual('Name sortable');
});
it('aria-label should be use the first text content in element when title is ReactElement', () => {
const { container } = render(
createTable(
{
sortDirections: ['descend', 'ascend'],
},
{
title: (
<span>
<em>Name</em>
<b>kiner</b>
</span>
),
defaultSortOrder: 'descend',
},
),
);
const getNameColumn = () => container.querySelector('th');
fireEvent.click(container.querySelector('.ant-table-column-sorters')!);
expect(getNameColumn()?.getAttribute('aria-sort')).toEqual('ascending');
expect(getNameColumn()?.getAttribute('aria-label')).toEqual(null);
fireEvent.click(container.querySelector('.ant-table-column-sorters')!);
expect(getNameColumn()?.getAttribute('aria-label')).toEqual('Name sortable');
});
it('sort records', () => {
const { container } = render(createTable());
const getNameColumn = () => container.querySelector('th');

View File

@ -1,4 +1,5 @@
/* eslint-disable import/prefer-default-export */
import React from 'react';
import type { ColumnTitle, ColumnTitleProps, ColumnType, Key } from './interface';
export function getColumnKey<RecordType>(column: ColumnType<RecordType>, defaultKey: string): Key {
@ -16,6 +17,22 @@ export function getColumnPos(index: number, pos?: string) {
return pos ? `${pos}-${index}` : `${index}`;
}
/**
* Get first text content in Element
*
* @param node
* @returns
*/
function getElementFirstTextContent(node: React.ReactElement): string {
if (!node || !node.props || !node.props.children) return '';
if (typeof node.props.children === 'string') return node.props.children;
return (
node.props.children?.map?.((item: React.ReactElement) =>
getElementFirstTextContent(item),
)?.[0] || ''
);
}
export function renderColumnTitle<RecordType>(
title: ColumnTitle<RecordType>,
props: ColumnTitleProps<RecordType>,
@ -23,6 +40,12 @@ export function renderColumnTitle<RecordType>(
if (typeof title === 'function') {
return title(props);
}
// fix: #38155
if (React.isValidElement(title)) {
// if title is a React Element, we should get first text content as result,
// if there has not text content in React Element, return origin title
return getElementFirstTextContent(title) || title;
}
return title;
}