, 'children'>` | 主题提供者。 |
+| styled | `StyledConfig` | `styled-components` 配置项。 |
diff --git a/docs/api/style-provider.md b/docs/api/style-provider.md
index cb475f49..b8869438 100644
--- a/docs/api/style-provider.md
+++ b/docs/api/style-provider.md
@@ -4,27 +4,39 @@ description: 用于全局管理样式插入相关的配置
order: 2
group: 容器组件
demo:
- cols: 2
tocDepth: 4
---
## 修改 container
-指定 `container` 为 dom 节点,即可使得所有生成的样式(antd、antd-style)均插入到该节点下。
+指定 `container` 即可使得所有生成的样式(antd、antd-style)均插入到该节点下。
-### 修改样式注入点
+## 修改样式注入点
-TBD
+一般情况下不太需要用到,如果你需要兼容组件覆写样式的需求时,可以考虑设定组件样式的注入点,使得其在该节点之后注入。
-### 开启 speedy 极速模式
+
-TBD
+## 开启 speedy 极速模式
+
+开启 emotion 的 speedy 模式。建议独立应用可以开启。
+
+
+
+:::info{title=Speedy模式}
+
+早期的 cssinjs 方案中,样式的插入是一个 style 标签对应一个样式,浏览器解析较慢,但便于修改与调试。
+
+目前 emotion 默认使用现代化的 CSSOM api 插入样式,会把一堆 css 放到一个 标签里,插入后移除相应的内容。这种方式性能很好,支持万级别的样式插入。但与微应用(qiankun)兼容性较差。
+
+antd-style 中默认关闭了 speedy 模式,如果需要,配置 `speedy` 为 `true` 即可。
+:::
## API
-继承 `ant-design/cssinjs` 的 [StyleProvider](https://github.com/ant-design/cssinjs#styleprovider) api ,其余 api 如下:
+继承 `ant-design/cssinjs` 的 [StyleProvider](https://github.com/ant-design/cssinjs#styleprovider) ,其余 API 如下:
| 属性名 | 类型 | 描述 |
| --------------- | -------------------------------------- | -------------------------------------------------------------------- |
diff --git a/docs/api/use-responsive.md b/docs/api/use-responsive.md
index 744a5dd9..76e5a491 100644
--- a/docs/api/use-responsive.md
+++ b/docs/api/use-responsive.md
@@ -8,34 +8,25 @@ group: Hooks
获取响应式媒体查询的结果。基于 antd 的 [Grid.useBreakpoint](https://ant.design/components/grid-cn#components-grid-demo-usebreakpoint) 封装。
-
-
## 用法
-```ts
+```tsx | pure
import { useResponsive } from 'antd-style';
function Theme() {
const { mobile } = useResponsive();
- useEffect(() => {
- console.log(theme);
- }, [theme]);
-
- return null;
+ // 使用 js 来区分显示移动端
+ return mobile ? mobile
: desktop
;
}
```
-## Typescript
+## 示例
-```ts
-useTheme = () => Theme;
-```
+
+
+## 自定义断点
-### 返回值
+通过传入 antd 的断点配置,来自定义响应断点。
-| 参数 | 说明 | 类型 | 默认值 |
-| ---------- | -------------- | ---------------------- | ------- |
-| themeMode | 主题模式 | `dark / light / auto` | `light` |
-| appearance | 显示外观 | `dark / light` | `light` |
-| isDarkMode | 是否为暗色模式 | `boolean` | `false` |
+
diff --git a/docs/demos/StyleProvider/insertpoint.tsx b/docs/demos/StyleProvider/insertpoint.tsx
new file mode 100644
index 00000000..7fdacc4b
--- /dev/null
+++ b/docs/demos/StyleProvider/insertpoint.tsx
@@ -0,0 +1,25 @@
+/**
+ * iframe: 50
+ */
+import { createStyles, css, StyleProvider } from 'antd-style';
+
+const useStyles = createStyles({
+ text: css`
+ color: hotpink;
+ `,
+});
+
+const Text = () => {
+ const { styles } = useStyles();
+ return 插入的 style 节点在第一个 meta 标签之后
;
+};
+
+export default () => {
+ const firstMeta = document.getElementsByTagName('meta')[0];
+
+ return (
+
+
+
+ );
+};
diff --git a/docs/demos/StyleProvider/speedy.tsx b/docs/demos/StyleProvider/speedy.tsx
new file mode 100644
index 00000000..9afdc97f
--- /dev/null
+++ b/docs/demos/StyleProvider/speedy.tsx
@@ -0,0 +1,23 @@
+/**
+ * iframe: 50
+ */
+import { createStyles, css, StyleProvider } from 'antd-style';
+
+const useStyles = createStyles({
+ text: css`
+ color: blue;
+ `,
+});
+
+const Text = () => {
+ const { styles } = useStyles();
+ return 开启 speedy 模式后,style 标签中将不存在具体样式
;
+};
+
+export default () => {
+ return (
+
+
+
+ );
+};
diff --git a/docs/demos/api/createInstance/createInstanceWithContainer.tsx b/docs/demos/api/createInstance/withContainer.tsx
similarity index 96%
rename from docs/demos/api/createInstance/createInstanceWithContainer.tsx
rename to docs/demos/api/createInstance/withContainer.tsx
index 28a11d35..7f73f781 100644
--- a/docs/demos/api/createInstance/createInstanceWithContainer.tsx
+++ b/docs/demos/api/createInstance/withContainer.tsx
@@ -1,5 +1,5 @@
/**
- * iframe: true
+ * iframe: 100
*/
import { Button } from 'antd';
import { createInstance } from 'antd-style';
diff --git a/docs/demos/api/createInstance/createInstanceWithStyleProviderContainer.tsx b/docs/demos/api/createInstance/withStyleProviderContainer.tsx
similarity index 82%
rename from docs/demos/api/createInstance/createInstanceWithStyleProviderContainer.tsx
rename to docs/demos/api/createInstance/withStyleProviderContainer.tsx
index bf76a386..b22dc1cb 100644
--- a/docs/demos/api/createInstance/createInstanceWithStyleProviderContainer.tsx
+++ b/docs/demos/api/createInstance/withStyleProviderContainer.tsx
@@ -1,7 +1,8 @@
/**
- * iframe: true
+ * iframe: 150
*/
-import { Button } from 'antd';
+
+import { Button, Divider } from 'antd';
import { createInstance } from 'antd-style';
const { css, StyleProvider, createStyles } = createInstance({
@@ -26,6 +27,7 @@ export default () => {
+ 下方 style 插入在 head
>
);
diff --git a/docs/demos/api/useResponsive/DisplayTag.tsx b/docs/demos/api/useResponsive/Demo/DisplayTag.tsx
similarity index 100%
rename from docs/demos/api/useResponsive/DisplayTag.tsx
rename to docs/demos/api/useResponsive/Demo/DisplayTag.tsx
diff --git a/docs/demos/api/useResponsive/index.tsx b/docs/demos/api/useResponsive/Demo/index.tsx
similarity index 85%
rename from docs/demos/api/useResponsive/index.tsx
rename to docs/demos/api/useResponsive/Demo/index.tsx
index 33cd34f3..008130d9 100644
--- a/docs/demos/api/useResponsive/index.tsx
+++ b/docs/demos/api/useResponsive/Demo/index.tsx
@@ -1,12 +1,9 @@
-/**
- * compact: true
- */
-import { Divider, Tooltip } from 'antd';
-import { Breakpoint, ThemeProvider, useResponsive, useTheme } from 'antd-style';
+import { Tooltip } from 'antd';
+import { Breakpoint, useResponsive, useTheme } from 'antd-style';
import { Flexbox } from 'react-layout-kit';
+import { Label } from '../style';
import { DisplayTag } from './DisplayTag';
-import { Container, Label } from './style';
const Demo = () => {
const responsive = useResponsive();
@@ -81,14 +78,4 @@ const Demo = () => {
);
};
-export default () => {
- return (
-
-
-
-
-
-
-
- );
-};
+export default Demo;
diff --git a/docs/demos/api/useResponsive/custom.tsx b/docs/demos/api/useResponsive/custom.tsx
new file mode 100644
index 00000000..f98583ba
--- /dev/null
+++ b/docs/demos/api/useResponsive/custom.tsx
@@ -0,0 +1,25 @@
+/**
+ * compact: true
+ */
+
+import { ThemeProvider } from 'antd-style';
+import Demo from './Demo';
+import { Container } from './style';
+
+export default () => {
+ return (
+
+
+
+
+
+ );
+};
diff --git a/docs/demos/api/useResponsive/default.tsx b/docs/demos/api/useResponsive/default.tsx
new file mode 100644
index 00000000..f5b498cb
--- /dev/null
+++ b/docs/demos/api/useResponsive/default.tsx
@@ -0,0 +1,18 @@
+/**
+ * compact: true
+ */
+
+import Demo from './Demo';
+import { Container } from './style';
+
+export default () => {
+ return (
+
+
+ {/**/}
+ {/**/}
+ {/* */}
+ {/**/}
+
+ );
+};
diff --git a/package.json b/package.json
index fd685b67..631d9fd7 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "antd-style",
- "version": "3.2.2",
+ "version": "3.3.0-beta.2",
"description": "a css-in-js solution for application combine with antd v5 token system and emotion",
"keywords": [
"antd",
@@ -85,7 +85,7 @@
"@emotion/babel-plugin": "^11",
"@emotion/jest": "^11",
"@emotion/styled": "^11",
- "@floating-ui/react": "^0.17",
+ "@floating-ui/react": "^0.24",
"@react-three/fiber": "^8",
"@testing-library/jest-dom": "^5",
"@testing-library/react": "^13",
diff --git a/src/core/CacheManager.ts b/src/core/CacheManager.ts
index 64be7176..e9408b6f 100644
--- a/src/core/CacheManager.ts
+++ b/src/core/CacheManager.ts
@@ -10,7 +10,11 @@ export class CacheManager {
this._cacheList.push(cache);
}
- private hasCache(cache: EmotionCache) {
+ delete(cache: EmotionCache) {
+ this._cacheList = this._cacheList.filter((c) => c.key !== cache.key);
+ }
+
+ hasCache(cache: EmotionCache) {
return this._cacheList.some((c) => c.key === cache.key);
}
diff --git a/src/factories/createThemeProvider/ThemeSwitcher.tsx b/src/factories/createThemeProvider/ThemeSwitcher.tsx
index 0b4a14d6..378397cc 100644
--- a/src/factories/createThemeProvider/ThemeSwitcher.tsx
+++ b/src/factories/createThemeProvider/ThemeSwitcher.tsx
@@ -4,6 +4,7 @@ import useMergeValue from 'use-merge-value';
import { ThemeModeContext } from '@/context';
import { BrowserPrefers, ThemeAppearance, ThemeMode, UseTheme } from '@/types';
import { matchBrowserPrefers } from '@/utils/matchBrowserPrefers';
+import { safeStartTransition } from '@/utils/safeStartTransition';
let darkThemeMatch: MediaQueryList;
@@ -32,7 +33,9 @@ const ThemeObserver: FC<{
useLayoutEffect(() => {
// 如果不是自动,就明确设定亮暗色
if (themeMode !== 'auto') {
- setAppearance(themeMode);
+ safeStartTransition(() => {
+ setAppearance(themeMode);
+ });
return;
}
// 如果是自动的话,则去做一次匹配,并开始监听
@@ -48,7 +51,7 @@ const ThemeObserver: FC<{
};
}, [themeMode]);
- useEffect(() => {
+ useLayoutEffect(() => {
if (!darkThemeMatch) {
darkThemeMatch = matchBrowserPrefers('dark');
}
@@ -117,7 +120,10 @@ const ThemeSwitcher: FC = memo(
// Wait until after client-side hydration to show
useEffect(() => {
- setStartObserver(true);
+ // 兼容 React18 的 Suspense 问题
+ safeStartTransition(() => {
+ setStartObserver(true);
+ });
}, []);
return (
diff --git a/src/utils/matchBrowserPrefers.test.ts b/src/utils/matchBrowserPrefers.test.ts
index d2e1a309..dc919d2f 100644
--- a/src/utils/matchBrowserPrefers.test.ts
+++ b/src/utils/matchBrowserPrefers.test.ts
@@ -1,3 +1,4 @@
+import { ThemeAppearance } from 'antd-style';
import { vi } from 'vitest';
import { matchBrowserPrefers } from './matchBrowserPrefers';
@@ -36,4 +37,17 @@ describe('matchBrowserPrefers', () => {
// 还原全局变量
global.window = originalWindow;
});
+ it('should return a MediaQueryList-like object when window object is undefined', () => {
+ const tempWin = window;
+ // eslint-disable-next-line no-global-assign,no-native-reassign
+ window = undefined as any;
+
+ const mode: ThemeAppearance = 'dark';
+ const result = matchBrowserPrefers(mode);
+
+ expect(result.matches).toBe(false);
+
+ // eslint-disable-next-line no-global-assign,no-native-reassign
+ window = tempWin;
+ });
});
diff --git a/src/utils/safeStartTransition.ts b/src/utils/safeStartTransition.ts
new file mode 100644
index 00000000..d2ef0e71
--- /dev/null
+++ b/src/utils/safeStartTransition.ts
@@ -0,0 +1,9 @@
+import { startTransition, TransitionFunction } from 'react';
+
+export const safeStartTransition = (func: TransitionFunction) => {
+ if (typeof startTransition === 'function') {
+ startTransition(func);
+ } else {
+ func();
+ }
+};