refactor(qr-code): improve a11y attributes handling in QRCode component (#51421)

* refactor(qr-code): improve a11y attributes handling in QRCode component

* test: update snapshot

* feat(qr-code): improve a11y attributes handling in QRCode component

* chore: remove useless code

* test: add test case

* chore: remove data attr and update test cases

* chore: omit a11yProps from props
This commit is contained in:
Jony J 2024-11-04 14:50:00 +08:00 committed by GitHub
parent 6380fc7a95
commit a03e2024d4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 48 additions and 5 deletions

View File

@ -155,4 +155,38 @@ describe('QRCode test', () => {
).toBe('Scanned');
expect(container).toMatchSnapshot();
});
it('should pass aria and data props to qrcode element', () => {
const { container } = render(<QRCode value="test" aria-label="Test QR Code" />);
const qrcodeElement = container.querySelector('.ant-qrcode canvas');
expect(qrcodeElement).toHaveAttribute('aria-label', 'Test QR Code');
});
it('should not pass other props to qrcode element', () => {
const { container } = render(
<QRCode
value="test"
aria-label="Test QR Code"
title="qr-title" // This prop should not be passed to canvas
/>,
);
const qrcodeElement = container.querySelector('.ant-qrcode canvas');
expect(qrcodeElement).toHaveAttribute('aria-label', 'Test QR Code');
expect(qrcodeElement).not.toHaveAttribute('title', 'qr-title');
});
it('should work with both canvas and svg type', () => {
const ariaLabel = 'Test QR Code';
// test canvas type
const { container: canvasContainer } = render(
<QRCode value="test" type="canvas" aria-label={ariaLabel} />,
);
expect(canvasContainer.querySelector('canvas')).toHaveAttribute('aria-label', ariaLabel);
// test svg type
const { container: svgContainer } = render(
<QRCode value="test" type="svg" aria-label={ariaLabel} />,
);
expect(svgContainer.querySelector('svg')).toHaveAttribute('aria-label', ariaLabel);
});
});

View File

@ -1,6 +1,8 @@
import React, { useContext } from 'react';
import React, { useContext, type AriaAttributes } from 'react';
import { QRCodeCanvas, QRCodeSVG } from '@rc-component/qrcode';
import classNames from 'classnames';
import omit from 'rc-util/lib/omit';
import pickAttrs from 'rc-util/lib/pickAttrs';
import { devUseWarning } from '../_util/warning';
import type { ConfigConsumerProps } from '../config-provider';
@ -8,8 +10,8 @@ import { ConfigContext } from '../config-provider';
import { useLocale } from '../locale';
import { useToken } from '../theme/internal';
import type { QRCodeProps, QRProps } from './interface';
import useStyle from './style/index';
import QRcodeStatus from './QrcodeStatus';
import useStyle from './style/index';
const QRCode: React.FC<QRCodeProps> = (props) => {
const [, token] = useToken();
@ -41,12 +43,18 @@ const QRCode: React.FC<QRCodeProps> = (props) => {
src: icon,
x: undefined,
y: undefined,
height: typeof iconSize === 'number' ? iconSize : iconSize?.height ?? 40,
width: typeof iconSize === 'number' ? iconSize : iconSize?.width ?? 40,
height: typeof iconSize === 'number' ? iconSize : (iconSize?.height ?? 40),
width: typeof iconSize === 'number' ? iconSize : (iconSize?.width ?? 40),
excavate: true,
crossOrigin: 'anonymous',
};
const a11yProps = pickAttrs(rest, true);
const restProps = omit<React.HTMLAttributes<HTMLDivElement>, keyof AriaAttributes>(
rest,
Object.keys(a11yProps) as Array<keyof AriaAttributes>,
);
const qrCodeProps = {
value,
size,
@ -55,6 +63,7 @@ const QRCode: React.FC<QRCodeProps> = (props) => {
fgColor: color,
style: { width: style?.width, height: style?.height },
imageSettings: icon ? imageSettings : undefined,
...a11yProps,
};
const [locale] = useLocale('QRCode');
@ -87,7 +96,7 @@ const QRCode: React.FC<QRCodeProps> = (props) => {
};
return wrapCSSVar(
<div {...rest} className={mergedCls} style={mergedStyle}>
<div {...restProps} className={mergedCls} style={mergedStyle}>
{status !== 'active' && (
<div className={`${prefixCls}-mask`}>
<QRcodeStatus