Browse Source

feat: add style/className/styles/classNames to ConfigProvider (#42623)

* feat: add style/className/styles/classNames to ConfigProvider

* chore: better code

* Update components/config-provider/index.en-US.md

Co-authored-by: lijianan <574980606@qq.com>

* Update components/config-provider/index.zh-CN.md

Co-authored-by: lijianan <574980606@qq.com>

---------

Co-authored-by: 歆其 <luzhenjie.lzj@antgroup.com>
Co-authored-by: MadCcc <1075746765@qq.com>
Co-authored-by: lijianan <574980606@qq.com>
pull/42659/head
LuZhenJie1999 2 years ago
committed by GitHub
parent
commit
b6442fe285
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 15
      components/button/button.tsx
  2. 53
      components/config-provider/__tests__/button.test.tsx
  3. 15
      components/config-provider/context.ts
  4. 1
      components/config-provider/index.en-US.md
  5. 3
      components/config-provider/index.tsx
  6. 1
      components/config-provider/index.zh-CN.md

15
components/button/button.tsx

@ -18,12 +18,12 @@ import DisabledContext from '../config-provider/DisabledContext';
import type { SizeType } from '../config-provider/SizeContext';
import useSize from '../config-provider/hooks/useSize';
import { useCompactItemContext } from '../space/Compact';
import IconWrapper from './IconWrapper';
import LoadingIcon from './LoadingIcon';
import Group, { GroupSizeContext } from './button-group';
import type { ButtonHTMLType, ButtonShape, ButtonType } from './buttonHelpers';
import { isTwoCNChar, isUnBorderedButtonType, spaceChildren } from './buttonHelpers';
import useStyle from './style';
import IconWrapper from './IconWrapper';
export type LegacyButtonType = ButtonType | 'danger';
@ -121,10 +121,11 @@ const InternalButton: React.ForwardRefRenderFunction<
// React does not recognize the `htmlType` prop on a DOM element. Here we pick it out of `rest`.
htmlType = 'button',
classNames: customClassNames,
style: customStyle = {},
...rest
} = props;
const { getPrefixCls, autoInsertSpaceInButton, direction } = useContext(ConfigContext);
const { getPrefixCls, autoInsertSpaceInButton, direction, button } = useContext(ConfigContext);
const prefixCls = getPrefixCls('btn', customizePrefixCls);
const [wrapSSR, hashId] = useStyle(prefixCls);
@ -238,11 +239,17 @@ const InternalButton: React.ForwardRefRenderFunction<
compactItemClassnames,
className,
rootClassName,
button?.className,
);
const fullStyle = { ...button?.style, ...customStyle };
const iconClasses = classNames(customClassNames?.icon, button?.classNames?.icon);
const iconStyle = { ...(styles?.icon || {}), ...(button?.styles?.icon || {}) };
const iconNode =
icon && !innerLoading ? (
<IconWrapper prefixCls={prefixCls} className={customClassNames?.icon} style={styles?.icon}>
<IconWrapper prefixCls={prefixCls} className={iconClasses} style={iconStyle}>
{icon}
</IconWrapper>
) : (
@ -257,6 +264,7 @@ const InternalButton: React.ForwardRefRenderFunction<
<a
{...linkButtonRestProps}
className={classes}
style={fullStyle}
onClick={handleClick}
ref={buttonRef as React.Ref<HTMLAnchorElement>}
>
@ -271,6 +279,7 @@ const InternalButton: React.ForwardRefRenderFunction<
{...(rest as NativeButtonProps)}
type={htmlType}
className={classes}
style={fullStyle}
onClick={handleClick}
disabled={mergedDisabled}
ref={buttonRef as React.Ref<HTMLButtonElement>}

53
components/config-provider/__tests__/button.test.tsx

@ -0,0 +1,53 @@
import { SearchOutlined } from '@ant-design/icons';
import Button from 'antd/es/button';
import React from 'react';
import ConfigProvider from '..';
import { render } from '../../../tests/utils';
describe('ConfigProvider.button', () => {
beforeEach(() => {
(global as any).triggerProps = null;
});
it('ConfigProvider button style', () => {
const { container } = render(
<ConfigProvider>
<Button style={{ fontSize: '14px' }} />
</ConfigProvider>,
);
const item = container.querySelector('button') as HTMLElement;
expect(getComputedStyle(item)?.fontSize).toBe('14px');
});
it('ConfigProvider button className', () => {
const { container } = render(
<ConfigProvider>
<Button className="custom-class" />
</ConfigProvider>,
);
expect(container.querySelector('button')?.className.includes('custom-class')).toBe(true);
});
it('ConfigProvider button styles', () => {
const { container } = render(
<ConfigProvider button={{ styles: { icon: { color: '#333' } } }}>
<Button icon={<SearchOutlined />} />
</ConfigProvider>,
);
const item = container.querySelector('.ant-btn-icon') as HTMLElement;
expect(getComputedStyle(item)?.fontSize).toBe('14px');
});
it('ConfigProvider button classNames', () => {
const { container } = render(
<ConfigProvider button={{ classNames: { icon: 'icon-custom-class' } }}>
<Button icon={<SearchOutlined />} />
</ConfigProvider>,
);
expect(container.querySelector('.ant-btn-icon')?.className.includes('custom-class')).toBe(true);
});
});

15
components/config-provider/context.ts

@ -1,11 +1,12 @@
import * as React from 'react';
import type { DerivativeFunc } from '@ant-design/cssinjs';
import * as React from 'react';
import type { Options } from 'scroll-into-view-if-needed';
import type { ButtonProps } from '../button';
import type { RequiredMark } from '../form/Form';
import type { Locale } from '../locale';
import type { AliasToken, MapToken, OverrideToken, SeedToken } from '../theme/interface';
import type { RenderEmptyHandler } from './defaultRenderEmpty';
import type { SizeType } from './SizeContext';
import type { RenderEmptyHandler } from './defaultRenderEmpty';
export const defaultIconPrefixCls = 'anticon';
@ -34,6 +35,15 @@ export interface ThemeConfig {
inherit?: boolean;
}
interface componentStyleConfig {
className?: string;
style?: React.CSSProperties;
classNames?: ButtonProps['classNames'];
styles?: ButtonProps['styles'];
}
export interface ButtonConfig extends componentStyleConfig {}
export type PopupOverflow = 'viewport' | 'scroll';
export interface ConfigConsumerProps {
@ -71,6 +81,7 @@ export interface ConfigConsumerProps {
select?: {
showSearch?: boolean;
};
button?: ButtonConfig;
}
const defaultGetPrefixCls = (suffixCls?: string, customizePrefixCls?: string) => {

1
components/config-provider/index.en-US.md

@ -63,6 +63,7 @@ Some components use dynamic style to support wave effect. You can config `csp` p
| iconPrefixCls | Set icon prefix className | string | `anticon` | 4.11.0 |
| input | Set Input common props | { autoComplete?: string } | - | 4.2.0 |
| select | Set Select common props | { showSearch?: boolean } | - | |
| button | Set Select common props | { className?: string, style?: React.CSSProperties, classNames?: { icon: string }, styles?: { icon: React.CSSProperties } } | - | 5.6.0 |
| locale | Language package setting, you can find the packages in [antd/locale](http://unpkg.com/antd/locale/) | object | - | |
| prefixCls | Set prefix className | string | `ant` | |
| renderEmpty | Set empty content of components. Ref [Empty](/components/empty/) | function(componentName: string): ReactNode | - | |

3
components/config-provider/index.tsx

@ -17,6 +17,7 @@ import defaultLocale from '../locale/en_US';
import { DesignTokenContext } from '../theme/internal';
import defaultSeedToken from '../theme/themes/seed';
import type {
ButtonConfig,
ConfigConsumerProps,
CSPConfig,
DirectionType,
@ -86,6 +87,7 @@ const PASSED_PROPS: Exclude<keyof ConfigConsumerProps, 'rootPrefixCls' | 'getPre
'pagination',
'form',
'select',
'button',
];
export interface ConfigProviderProps {
@ -128,6 +130,7 @@ export interface ConfigProviderProps {
popupMatchSelectWidth?: boolean;
popupOverflow?: PopupOverflow;
theme?: ThemeConfig;
button?: ButtonConfig;
}
interface ProviderChildrenProps extends ConfigProviderProps {

1
components/config-provider/index.zh-CN.md

@ -64,6 +64,7 @@ export default Demo;
| iconPrefixCls | 设置图标统一样式前缀 | string | `anticon` | 4.11.0 |
| input | 设置 Input 组件的通用属性 | { autoComplete?: string } | - | 4.2.0 |
| select | 设置 Select 组件的通用属性 | { showSearch?: boolean } | - | |
| button | 设置 Button 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?: { icon: string }, styles?: { icon: React.CSSProperties } } | - | 5.6.0 |
| locale | 语言包配置,语言包可到 [antd/locale](http://unpkg.com/antd/locale/) 目录下寻找 | object | - | |
| prefixCls | 设置统一样式前缀 | string | `ant` | |
| renderEmpty | 自定义组件空状态。参考 [空状态](/components/empty-cn) | function(componentName: string): ReactNode | - | |

Loading…
Cancel
Save