(Go: >> BACK << -|- >> HOME <<)

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Mix style framework support #48229

Merged
merged 9 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 69 additions & 60 deletions .dumi/theme/common/styles/Common.tsx
Original file line number Diff line number Diff line change
@@ -1,77 +1,86 @@
import { css, Global } from '@emotion/react';
import React from 'react';
import { css, Global } from '@emotion/react';
import { useTheme } from 'antd-style';
import { updateCSS } from 'rc-util/lib/Dom/dynamicCSS';

export default () => {
const { anchorTop } = useTheme();

React.useInsertionEffect(() => {
updateCSS(`@layer global, antd;`, 'site-global', {
prepend: true,
});
}, []);

return (
<Global
styles={css`
body,
div,
dl,
dt,
dd,
ul,
ol,
li,
h1,
h2,
h3,
h4,
h5,
h6,
pre,
code,
form,
fieldset,
legend,
input,
textarea,
p,
blockquote,
th,
td,
hr,
button,
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
margin: 0;
padding: 0;
}
@layer global {
body,
div,
dl,
dt,
dd,
ul,
ol,
li,
h1,
h2,
h3,
h4,
h5,
h6,
pre,
code,
form,
fieldset,
legend,
input,
textarea,
p,
blockquote,
th,
td,
hr,
button,
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
margin: 0;
padding: 0;
}

ul,
ol {
list-style: none;
}
ul,
ol {
list-style: none;
}

img {
vertical-align: middle;
border-style: none;
}
img {
vertical-align: middle;
border-style: none;
}

[id] {
scroll-margin-top: ${anchorTop}px;
}
[id] {
scroll-margin-top: ${anchorTop}px;
}

[data-prefers-color='dark'] {
color-scheme: dark;
}
[data-prefers-color='dark'] {
color-scheme: dark;
}

[data-prefers-color='light'] {
color-scheme: light;
}
`}
[data-prefers-color='light'] {
color-scheme: light;
}
}
`}
/>
);
};
1 change: 1 addition & 0 deletions .dumi/theme/layouts/GlobalLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ const GlobalLayout: React.FC = () => {
<StyleProvider
cache={styleCache}
linters={[legacyNotSelectorLinter, parentSelectorLinter, NaNLinter]}
layer
>
<SiteContext.Provider value={siteContextValue}>
<SiteThemeProvider theme={themeConfig}>
Expand Down
3 changes: 2 additions & 1 deletion .dumi/theme/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ const RoutesPlugin = (api: IApi) => {
const matchRegex = /<style data-type="antd-cssinjs">([\S\s]+?)<\/style>/;
const matchList = file.content.match(matchRegex) || [];

let antdStyle = '';
// Init to order the `@layer`
let antdStyle = '@layer global, antd;';

matchList.forEach((text) => {
file.content = file.content.replace(text, '');
Expand Down
15 changes: 14 additions & 1 deletion components/date-picker/locale/ru_RU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,20 @@ const locale: PickerLocale = {
rangeMonthPlaceholder: ['Начальный месяц', 'Конечный месяц'],
rangeWeekPlaceholder: ['Начальная неделя', 'Конечная неделя'],
shortWeekDays: ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'],
shortMonths: ['Янв', 'Фев', 'Мар', 'Апр', 'Май', 'Июн', 'Июл', 'Авг', 'Сен', 'Окт', 'Ноя', 'Дек'],
shortMonths: [
'Янв',
'Фев',
'Мар',
'Апр',
'Май',
'Июн',
'Июл',
'Авг',
'Сен',
'Окт',
'Ноя',
'Дек',
],
...CalendarLocale,
},
timePickerLocale: {
Expand Down
4 changes: 2 additions & 2 deletions components/form/demo/basic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ type FieldType = {
remember?: string;
};

const onFinish: FormProps<FieldType>["onFinish"] = (values) => {
const onFinish: FormProps<FieldType>['onFinish'] = (values) => {
console.log('Success:', values);
};

const onFinishFailed: FormProps<FieldType>["onFinishFailed"] = (errorInfo) => {
const onFinishFailed: FormProps<FieldType>['onFinishFailed'] = (errorInfo) => {
console.log('Failed:', errorInfo);
};

Expand Down
4 changes: 3 additions & 1 deletion components/table/hooks/useFilter/FilterDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,9 @@ function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
tablePrefixCls={tablePrefixCls}
locale={locale}
/>
{isEmpty ? empty : (
{isEmpty ? (
empty
) : (
<Menu
selectable
multiple={filterMultiple}
Expand Down
3 changes: 3 additions & 0 deletions components/theme/util/genComponentStyleHook.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ export default function genComponentStyleHook<C extends OverrideComponent>(
hashId,
nonce: () => csp?.nonce!,
clientOnly: options.clientOnly,
layer: {
name: 'antd',
},

// antd is always at top of styles
order: options.order || -999,
Expand Down
6 changes: 5 additions & 1 deletion components/theme/util/useResetIconStyle.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useStyleRegister } from '@ant-design/cssinjs';
import { resetIcon } from '../../style';

import type { CSPConfig } from '../../config-provider';
import { resetIcon } from '../../style';
import useToken from '../useToken';

const useResetIconStyle = (iconPrefixCls: string, csp?: CSPConfig) => {
Expand All @@ -14,6 +15,9 @@ const useResetIconStyle = (iconPrefixCls: string, csp?: CSPConfig) => {
hashId: '',
path: ['ant-design-icons', iconPrefixCls],
nonce: () => csp?.nonce!,
layer: {
name: 'antd',
},
},
() => [
{
Expand Down
114 changes: 113 additions & 1 deletion docs/react/compatible-style.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,33 @@ Ant Design supports the last 2 versions of modern browsers. If you need to be co

Please ref [`@ant-design/cssinjs`](https://github.com/ant-design/cssinjs#styleprovider).

## `layer` Downgrade

Ant Design supports configuring `layer` for unified downgrade since `5.17.0`. After the downgrade, the style of antd will always be lower than the default CSS selector priority, so that users can override the style (please be sure to check the browser compatibility of `@layer`):

```tsx
import { StyleProvider } from '@ant-design/cssinjs';

export default () => (
<StyleProvider layer>
<MyApp />
</StyleProvider>
);
```

antd styles will be encapsulated in `@layer` to lower the priority:

```diff
++ @layer antd {
:where(.css-bAMboO).ant-btn {
color: #fff;
}
++ }
```

## Compatible adjustment

The CSS-in-JS feature of Ant Design uses the ":where" selector by default to lower the CSS selector specificity, reducing the additional cost of adjusting custom styles when upgrading for users. However, the compatibility of the ":where" syntax is relatively poor in older browsers ([compatibility](https://developer.mozilla.org/en-US/docs/Web/CSS/:where#browser_compatibility)). In certain scenarios, if you need to support older browsers (or encounter priority conflicts like TailwindCSS), you can use `@ant-design/cssinjs` to disable the default lowering of specificity (please ensure version consistency with antd).
The CSS-in-JS feature of Ant Design uses the ":where" selector by default to lower the CSS selector specificity, reducing the additional cost of adjusting custom styles when upgrading for users. However, the compatibility of the ":where" syntax is relatively poor in older browsers ([compatibility](https://developer.mozilla.org/en-US/docs/Web/CSS/:where#browser_compatibility)). In certain scenarios, if you need to support older browsers, you can use `@ant-design/cssinjs` to disable the default lowering of specificity (please ensure version consistency with antd).

```tsx
import { StyleProvider } from '@ant-design/cssinjs';
Expand Down Expand Up @@ -147,3 +171,91 @@ root.render(
</StyleProvider>,
);
```

## Compatible with Third-party Style Libraries

In some cases, you may need antd to coexist with other style libraries, such as `Tailwind CSS`, `Emotion`, `styled-components`, etc. Unlike traditional CSS solutions, these third-party libraries are often not easy to override antd styles by increasing CSS selector priority. You can configure `@layer` for antd to lower its CSS selector weight, and arrange `@layer` order to solve style override problems:

### antd config `@layer`

```tsx
import { StyleProvider } from '@ant-design/cssinjs';

export default () => (
<StyleProvider layer>
<MyApp />
</StyleProvider>
);
```

### TailwindCSS Arrange `@layer`

In global.css, adjust `@layer` to control the order of style override. Place `tailwind-base` before `antd`:

```less
@layer tailwind-base, antd;

@layer tailwind-base {
@tailwind base;
}
@tailwind components;
@tailwind utilities;
```

### reset.css

If you use antd's `reset.css` style, you need to specify `@layer` for it to prevent the style from overriding antd:

```less
@layer reset, antd;

@import url(reset.css) layer(reset);
```

### With other CSS-in-JS libraries

After configuring `@layer` for antd, you don't need to do any additional configuration for other CSS-in-JS libraries. Your CSS-in-JS can completely override antd styles.

### SSR Scene

When using SSR, styles are often rendered inline in HTML through `<style />`. At this time, please make sure that the styles with the specified `@layer` priority order are loaded before `@layer` is used.

#### ❌ Wrong

```html
<head>
<!-- SSR Injection style -->
<style>
@layer antd {
/** ... */
}
</style>

<!-- css file contains @layer xxx, antd; -->
<link rel="stylesheet" href="/b9a0m0b9o0o3.css" />
<!-- or write @layer xxx, antd; in html directly -->
<style>
@layer xxx, antd;
</style>
</head>
```

#### ✅ Correct

```html
<head>
<!-- css file contains @layer xxx, antd; -->
<link rel="stylesheet" href="/b9a0m0b9o0o3.css" />
<!-- or write @layer xxx, antd; in html directly -->
<style>
@layer xxx, antd;
</style>

<!-- SSR Injection style -->
<style>
@layer antd {
/** ... */
}
</style>
</head>
```
Loading
Loading