Skip to content

Commit

Permalink
fix(Token): prevent focus on cross (#3361)
Browse files Browse the repository at this point in the history
  • Loading branch information
JackUait committed Feb 21, 2024
1 parent ae423b1 commit 757899c
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 3 deletions.
6 changes: 3 additions & 3 deletions packages/react-ui/components/Token/Token.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { AriaAttributes } from 'react';

import { locale } from '../../lib/locale/decorators';
import { CrossIcon } from '../../internal/icons/CrossIcon';
import { emptyHandler } from '../../lib/utils';
import { emptyHandler, getChildrenText } from '../../lib/utils';
import { ThemeContext } from '../../lib/theming/ThemeContext';
import { Theme } from '../../lib/theming/Theme';
import { CommonProps, CommonWrapper } from '../../internal/CommonWrapper';
Expand Down Expand Up @@ -97,10 +97,10 @@ export class Token extends React.Component<TokenProps> {
const theme = this.theme;

const validation = getValidation(error, warning);
const removeButtonAriaLabel = this.locale.removeButtonAriaLabel + ' ' + children;
const removeButtonAriaLabel = this.locale.removeButtonAriaLabel + ' ' + getChildrenText(children);

const icon = isTheme2022(theme) ? (
<CloseButtonIcon side={16} color="inherit" colorHover="inherit" role="none" />
<CloseButtonIcon side={16} color="inherit" colorHover="inherit" role="none" tabbable={false} />
) : (
<CrossIcon />
);
Expand Down
46 changes: 46 additions & 0 deletions packages/react-ui/components/Token/__tests__/Token-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,5 +81,51 @@ describe('Token', () => {

expect(screen.getByRole('button')).toHaveAttribute('aria-label', customAriaLabel + ' ' + tokenName);
});

it('can find text inside nested children', () => {
const tokenName = 'name';
render(
<Token>
<div>{tokenName}</div>
</Token>,
);

expect(screen.getByRole('button')).toHaveAttribute(
'aria-label',
TokenLocalesRu.removeButtonAriaLabel + ' ' + tokenName,
);
});

it('can find text inside several nested children', () => {
const tokenNameFirst = 'name 1';
const tokenNameSecond = 'name 2';
render(
<Token>
<div>{tokenNameFirst}</div>
<div>{tokenNameSecond}</div>
</Token>,
);

expect(screen.getByRole('button')).toHaveAttribute(
'aria-label',
TokenLocalesRu.removeButtonAriaLabel + ' ' + tokenNameFirst + tokenNameSecond,
);
});

it('can work with token without text', () => {
render(<Token></Token>);

expect(screen.getByRole('button')).toHaveAttribute('aria-label', TokenLocalesRu.removeButtonAriaLabel + ' ');
});

it('can work with tag without text', () => {
render(
<Token>
<div></div>
</Token>,
);

expect(screen.getByRole('button')).toHaveAttribute('aria-label', TokenLocalesRu.removeButtonAriaLabel + ' ');
});
});
});
23 changes: 23 additions & 0 deletions packages/react-ui/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,26 @@ export const isInputLike =
export const isKonturIcon = (icon: React.ReactElement) => {
return Object.prototype.hasOwnProperty.call(icon?.type, '__KONTUR_ICON__');
};

/**
* Allows to get text of all nested children as a string
*
* @param children React's children
* @returns Nested child text or an empty string
*/
export function getChildrenText(children: React.ReactNode): string {
if (typeof children === 'string' || typeof children === 'number') {
return children.toString();
}

if (Array.isArray(children)) {
return children.map((entry) => getChildrenText(entry)).join('');
}

const nextChild = (children as React.ReactElement)?.props.children;
if (!nextChild) {
return '';
}

return getChildrenText(nextChild);
}

0 comments on commit 757899c

Please sign in to comment.