Browse Source

fix: global icon style (#38617)

* fix: global icon style

* chore: code clean

* feat: icon style in CP

* chore: code clean

* chore: code clean

* chore: support ss

* feat: wrapSSR only if iconPrefixCls does not equal parent

* chore: code clean

* chore: fix lint

* chore: fix lint

* chore: test

* chore: wrap children

* chore: code clean

* chore: fix lint
pull/38664/head
MadCcc 2 years ago
committed by GitHub
parent
commit
6848b23169
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 25
      components/config-provider/__tests__/cssinjs.test.tsx
  2. 17
      components/config-provider/index.tsx
  3. 18
      components/config-provider/style/index.tsx
  4. 2
      components/message/__tests__/config.test.tsx

25
components/config-provider/__tests__/cssinjs.test.tsx

@ -1,4 +1,5 @@
import * as React from 'react';
import { SmileOutlined } from '@ant-design/icons';
import ConfigProvider from '..';
import Button from '../../button';
import Divider from '../../divider';
@ -6,7 +7,7 @@ import { render } from '../../../tests/utils';
describe('ConfigProvider.DynamicTheme', () => {
beforeEach(() => {
Array.from(document.querySelectorAll('style')).forEach(style => {
Array.from(document.querySelectorAll('style')).forEach((style) => {
style.parentNode?.removeChild(style);
});
});
@ -27,7 +28,7 @@ describe('ConfigProvider.DynamicTheme', () => {
const dynamicStyles = Array.from(document.querySelectorAll('style[data-css-hash]'));
expect(
dynamicStyles.some(style => {
dynamicStyles.some((style) => {
const { innerHTML } = style;
return (
innerHTML.includes('.ant-btn-primary') && innerHTML.includes('background-color:#f00000')
@ -64,7 +65,7 @@ describe('ConfigProvider.DynamicTheme', () => {
const dynamicStyles = Array.from(document.querySelectorAll('style[data-css-hash]'));
expect(
dynamicStyles.some(style => {
dynamicStyles.some((style) => {
const { innerHTML } = style;
return (
innerHTML.includes('.ant-divider') && innerHTML.includes('border-block-start:0 blue')
@ -72,4 +73,22 @@ describe('ConfigProvider.DynamicTheme', () => {
}),
).toBeTruthy();
});
it('should support iconPrefixCls', () => {
const { container } = render(
<ConfigProvider iconPrefixCls="test-icon">
<SmileOutlined />
</ConfigProvider>,
);
expect(container.querySelector('.test-icon')).toBeTruthy();
const dynamicStyles = Array.from(document.querySelectorAll('style[data-css-hash]'));
expect(
dynamicStyles.some((style) => {
const { innerHTML } = style;
return innerHTML.includes('.test-icon');
}),
).toBeTruthy();
});
});

17
components/config-provider/index.tsx

@ -4,6 +4,7 @@ import { FormProvider as RcFormProvider } from 'rc-field-form';
import type { ValidateMessages } from 'rc-field-form/lib/interface';
import useMemo from 'rc-util/lib/hooks/useMemo';
import * as React from 'react';
import type { ReactElement } from 'react';
import type { RequiredMark } from '../form/Form';
import type { Locale } from '../locale-provider';
import LocaleProvider, { ANT_MARK } from '../locale-provider';
@ -19,6 +20,7 @@ import { DisabledContextProvider } from './DisabledContext';
import useTheme from './hooks/useTheme';
import type { SizeType } from './SizeContext';
import SizeContext, { SizeContextProvider } from './SizeContext';
import useStyle from './style';
export {
type RenderEmptyHandler,
@ -139,7 +141,7 @@ export const globalConfig = () => ({
},
});
const ProviderChildren: React.FC<ProviderChildrenProps> = props => {
const ProviderChildren: React.FC<ProviderChildrenProps> = (props) => {
const {
children,
csp: customCsp,
@ -172,8 +174,11 @@ const ProviderChildren: React.FC<ProviderChildrenProps> = props => {
);
const iconPrefixCls = customIconPrefixCls || parentContext.iconPrefixCls || defaultIconPrefixCls;
const shouldWrapSSR = iconPrefixCls !== parentContext.iconPrefixCls;
const csp = customCsp || parentContext.csp;
const wrapSSR = useStyle(iconPrefixCls);
const mergedTheme = useTheme(theme, parentContext.theme);
const config = {
@ -192,7 +197,7 @@ const ProviderChildren: React.FC<ProviderChildrenProps> = props => {
// Pass the props used by `useContext` directly with child component.
// These props should merged into `config`.
PASSED_PROPS.forEach(propName => {
PASSED_PROPS.forEach((propName) => {
const propValue = props[propName];
if (propValue) {
(config as any)[propName] = propValue;
@ -208,7 +213,7 @@ const ProviderChildren: React.FC<ProviderChildrenProps> = props => {
const currentKeys = Object.keys(currentConfig) as Array<keyof typeof config>;
return (
prevKeys.length !== currentKeys.length ||
prevKeys.some(key => prevConfig[key] !== currentConfig[key])
prevKeys.some((key) => prevConfig[key] !== currentConfig[key])
);
},
);
@ -218,7 +223,7 @@ const ProviderChildren: React.FC<ProviderChildrenProps> = props => {
[iconPrefixCls, csp],
);
let childNode = children;
let childNode = shouldWrapSSR ? wrapSSR(children as ReactElement) : children;
// Additional Form provider
let validateMessages: ValidateMessages = {};
@ -292,11 +297,11 @@ const ConfigProvider: React.FC<ConfigProviderProps> & {
ConfigContext: typeof ConfigContext;
SizeContext: typeof SizeContext;
config: typeof setGlobalConfig;
} = props => (
} = (props) => (
<LocaleReceiver>
{(_, __, legacyLocale) => (
<ConfigConsumer>
{context => (
{(context) => (
<ProviderChildren parentContext={context} legacyLocale={legacyLocale} {...props} />
)}
</ConfigConsumer>

18
components/config-provider/style/index.tsx

@ -0,0 +1,18 @@
import { useStyleRegister } from '@ant-design/cssinjs';
import { resetIcon } from '../../style';
import { useToken } from '../../theme';
const useStyle = (iconPrefixCls: string) => {
const [theme, token] = useToken();
// Generate style for icons
return useStyleRegister(
{ theme, token, hashId: '', path: ['ant-design-icons', iconPrefixCls] },
() => [
{
[`.${iconPrefixCls}`]: resetIcon(),
},
],
);
};
export default useStyle;

2
components/message/__tests__/config.test.tsx

@ -80,7 +80,7 @@ describe('message.config', () => {
const noticeWithoutLeaving = Array.from(
document.querySelectorAll('.ant-message-notice'),
).filter(ele => !ele.classList.contains('ant-message-move-up-leave'));
).filter((ele) => !ele.classList.contains('ant-message-move-up-leave'));
expect(noticeWithoutLeaving).toHaveLength(5);
expect(noticeWithoutLeaving[4].textContent).toEqual('last');

Loading…
Cancel
Save