Skip to content

Commit

Permalink
feat: make statistic component support html role and data-* and aria-…
Browse files Browse the repository at this point in the history
…* attributes (#47149)

* feat: make statistic component support html attributes

* fix: types

* chore: improve

* feat: use pickAttrs for data-* and aria-* and role
  • Loading branch information
vagusX committed Jan 26, 2024
1 parent 119f8aa commit 2aca1ff
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 9 deletions.
5 changes: 5 additions & 0 deletions components/_util/aria-data-attrs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type * as React from 'react';

export type HTMLAriaDataAttributes = React.AriaAttributes & {
[key: `data-${string}`]: unknown;
} & Pick<React.HTMLAttributes<HTMLDivElement>, 'role'>;
5 changes: 2 additions & 3 deletions components/statistic/Countdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { formatCountdown } from './utils';
const REFRESH_INTERVAL = 1000 / 30;

export interface CountdownProps extends StatisticProps {
value?: valueType;
format?: string;
onFinish?: () => void;
onChange?: (value?: valueType) => void;
Expand All @@ -20,7 +19,7 @@ function getTime(value?: valueType) {
}

const Countdown: React.FC<CountdownProps> = (props) => {
const { value, format = 'HH:mm:ss', onChange, onFinish } = props;
const { value, format = 'HH:mm:ss', onChange, onFinish, ...rest } = props;

const forceUpdate = useForceUpdate();

Expand Down Expand Up @@ -63,7 +62,7 @@ const Countdown: React.FC<CountdownProps> = (props) => {
const valueRender = (node: React.ReactElement<HTMLDivElement>) =>
cloneElement(node, { title: undefined });

return <Statistic {...props} valueRender={valueRender} formatter={formatter} />;
return <Statistic {...rest} value={value} valueRender={valueRender} formatter={formatter} />;
};

export default React.memo(Countdown);
1 change: 1 addition & 0 deletions components/statistic/Number.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { FormatConfig, valueType } from './utils';

interface NumberProps extends FormatConfig {
value: valueType;
prefixCls?: string;
}

const StatisticNumber: React.FC<NumberProps> = (props) => {
Expand Down
24 changes: 19 additions & 5 deletions components/statistic/Statistic.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import classNames from 'classnames';
import * as React from 'react';
import pickAttrs from 'rc-util/lib/pickAttrs';

import type { ConfigConsumerProps } from '../config-provider';
import { ConfigContext } from '../config-provider';
import Skeleton from '../skeleton';
import StatisticNumber from './Number';
import useStyle from './style';
import type { FormatConfig, valueType } from './utils';
import type { HTMLAriaDataAttributes } from '../_util/aria-data-attrs';

export interface StatisticProps extends FormatConfig {
interface StatisticReactProps extends FormatConfig {
prefixCls?: string;
className?: string;
rootClassName?: string;
Expand All @@ -23,7 +26,9 @@ export interface StatisticProps extends FormatConfig {
onMouseLeave?: React.MouseEventHandler<HTMLDivElement>;
}

const Statistic: React.FC<StatisticProps> = (props) => {
export type StatisticProps = HTMLAriaDataAttributes & StatisticReactProps;

const Statistic: React.FC<StatisticProps & HTMLAriaDataAttributes> = (props) => {
const {
prefixCls: customizePrefixCls,
className,
Expand All @@ -36,10 +41,15 @@ const Statistic: React.FC<StatisticProps> = (props) => {
prefix,
suffix,
loading = false,
onMouseEnter,
onMouseLeave,
/* --- FormatConfig starts --- */
formatter,
precision,
decimalSeparator = '.',
groupSeparator = ',',
/* --- FormatConfig starts --- */
onMouseEnter,
onMouseLeave,
...rest
} = props;

const { getPrefixCls, direction, statistic } =
Expand All @@ -54,7 +64,8 @@ const Statistic: React.FC<StatisticProps> = (props) => {
decimalSeparator={decimalSeparator}
groupSeparator={groupSeparator}
prefixCls={prefixCls}
{...props}
formatter={formatter}
precision={precision}
value={value}
/>
);
Expand All @@ -71,8 +82,11 @@ const Statistic: React.FC<StatisticProps> = (props) => {
cssVarCls,
);

const restProps = pickAttrs(rest, { aria: true, data: true });

return wrapCSSVar(
<div
{...restProps}
className={cls}
style={{ ...statistic?.style, ...style }}
onMouseEnter={onMouseEnter}
Expand Down
22 changes: 22 additions & 0 deletions components/statistic/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,28 @@ describe('Statistic', () => {
expect(container.querySelectorAll('.ant-statistic-content')).toHaveLength(0);
});

it('data attrs', () => {
const { container } = render(
<Statistic value={1128} data-abc="1" aria-label="2" role="status" />,
);
expect(container.querySelector('.ant-statistic')!.getAttribute('data-abc')).toEqual('1');
expect(container.querySelector('.ant-statistic')!.getAttribute('aria-label')).toEqual('2');
expect(container.querySelector('.ant-statistic')!.getAttribute('role')).toEqual('status');

const { container: countdownContainer } = render(
<Statistic.Countdown data-xyz="x" aria-label="y" role="contentinfo" />,
);
expect(countdownContainer.querySelector('.ant-statistic')!.getAttribute('data-xyz')).toEqual(
'x',
);
expect(countdownContainer.querySelector('.ant-statistic')!.getAttribute('aria-label')).toEqual(
'y',
);
expect(countdownContainer.querySelector('.ant-statistic')!.getAttribute('role')).toEqual(
'contentinfo',
);
});

describe('Countdown', () => {
it('render correctly', () => {
const now = dayjs()
Expand Down
1 change: 0 additions & 1 deletion components/statistic/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export interface FormatConfig {
decimalSeparator?: string;
groupSeparator?: string;
precision?: number;
prefixCls?: string;
}

export interface CountdownFormatConfig extends FormatConfig {
Expand Down

0 comments on commit 2aca1ff

Please sign in to comment.