Browse Source

feat: static getDesignToken (#42723)

* feat: static getDesignToken

* chore: code clean
pull/42841/head
MadCcc 1 year ago
committed by GitHub
parent
commit
596104cc68
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 55
      components/theme/__tests__/token.test.tsx
  2. 17
      components/theme/getDesignToken.ts
  3. 8
      components/theme/index.ts
  4. 36
      docs/react/customize-theme.en-US.md
  5. 38
      docs/react/customize-theme.zh-CN.md
  6. 2
      package.json

55
components/theme/__tests__/token.test.tsx

@ -3,6 +3,7 @@ import * as React from 'react';
import theme from '..';
import { render, renderHook } from '../../../tests/utils';
import ConfigProvider from '../../config-provider';
import type { ThemeConfig } from '../../config-provider/context';
import Row from '../../row';
import genRadius from '../themes/shared/genRadius';
@ -221,4 +222,58 @@ describe('Theme', () => {
expect(container.querySelector('.duration')?.textContent).toEqual('0s');
});
describe('getDesignToken', () => {
const getHookToken = (config?: ThemeConfig) => {
let token: any;
const Demo = () => {
const { token: hookToken } = useToken();
token = hookToken;
return null;
};
render(
<ConfigProvider theme={config}>
<Demo />
</ConfigProvider>,
);
delete token._hashId;
delete token._tokenKey;
return token;
};
it('default', () => {
const token = theme.getDesignToken();
const hookToken = getHookToken();
expect(token).toEqual(hookToken);
});
it('with custom token', () => {
const config: ThemeConfig = {
token: {
colorPrimary: '#189cff',
borderRadius: 8,
fontSizeLG: 20,
},
};
const token = theme.getDesignToken(config);
const hookToken = getHookToken(config);
expect(token).toEqual(hookToken);
expect(token.colorPrimary).toEqual('#189cff');
});
it('with custom algorithm', () => {
const config: ThemeConfig = {
token: {
colorPrimary: '#1677ff',
borderRadius: 8,
fontSizeLG: 20,
},
algorithm: [theme.darkAlgorithm, theme.compactAlgorithm],
};
const token = theme.getDesignToken(config);
const hookToken = getHookToken(config);
expect(token).toEqual(hookToken);
expect(token.colorPrimary).toEqual('#1668dc');
});
});
});

17
components/theme/getDesignToken.ts

@ -0,0 +1,17 @@
import { createTheme, getComputedToken } from '@ant-design/cssinjs';
import type { ThemeConfig } from '../config-provider/context';
import type { AliasToken } from './interface';
import defaultDerivative from './themes/default';
import seedToken from './themes/seed';
import formatToken from './util/alias';
const getDesignToken = (config?: ThemeConfig): AliasToken => {
const theme = config?.algorithm ? createTheme(config.algorithm) : createTheme(defaultDerivative);
const mergedToken = {
...seedToken,
...config?.token,
};
return getComputedToken(mergedToken, { override: config?.token }, theme, formatToken);
};
export default getDesignToken;

8
components/theme/index.ts

@ -1,9 +1,10 @@
/* eslint-disable import/prefer-default-export */
import { defaultConfig, useToken as useInternalToken } from './internal';
import getDesignToken from './getDesignToken';
import type { GlobalToken } from './interface';
import defaultAlgorithm from './themes/default';
import darkAlgorithm from './themes/dark';
import { defaultConfig, useToken as useInternalToken } from './internal';
import compactAlgorithm from './themes/compact';
import darkAlgorithm from './themes/dark';
import defaultAlgorithm from './themes/default';
// ZombieJ: We export as object to user but array in internal.
// This is used to minimize the bundle size for antd package but safe to refactor as object also.
@ -28,4 +29,5 @@ export default {
defaultAlgorithm,
darkAlgorithm,
compactAlgorithm,
getDesignToken,
};

36
docs/react/customize-theme.en-US.md

@ -160,9 +160,41 @@ When you need token out of React life cycle, you can use static function to get
```jsx
import { theme } from 'antd';
const { defaultAlgorithm, defaultSeed } = theme;
const { getDesignToken } = theme;
const mapToken = defaultAlgorithm(defaultSeed);
const globalToken = getDesignToken();
```
Same as ConfigProvider, `getDesignToken` could also accept a config object as `theme`:
```tsx
import type { ThemeConfig } from 'antd';
import { theme } from 'antd';
import { createRoot } from 'react-dom/client';
const { getDesignToken, useToken } = theme;
const config: ThemeConfig = {
token: {
colorPrimary: '#1890ff',
},
};
// By static function
const globalToken = getDesignToken(config);
// By hook
const App = () => {
const { token } = useToken();
return null;
};
// Example for rendering
createRoot(document.getElementById('#app')).render(
<ConfigProvider theme={config}>
<App />
</ConfigProvider>,
);
```
If you want to use in preprocess style framework like less, use less-loader for injection:

38
docs/react/customize-theme.zh-CN.md

@ -155,14 +155,46 @@ export default App;
### 静态消费(如 less)
当你需要非 React 生命周期消费 Token 变量时,可以通过静态方法将其导出:
当你需要非 React 生命周期消费 Token 变量时,可以通过静态方法 `getDesignToken` 将其导出:
```jsx
import { theme } from 'antd';
const { defaultAlgorithm, defaultSeed } = theme;
const { getDesignToken } = theme;
const mapToken = defaultAlgorithm(defaultSeed);
const globalToken = getDesignToken();
```
`getDesignToken` 和 ConfigProvider 一样,支持传入 `theme` 属性,用于获取指定主题的 Design Token。
```tsx
import type { ThemeConfig } from 'antd';
import { theme } from 'antd';
import { createRoot } from 'react-dom/client';
const { getDesignToken, useToken } = theme;
const config: ThemeConfig = {
token: {
colorPrimary: '#1890ff',
},
};
// 通过静态方法获取
const globalToken = getDesignToken(config);
// 通过 hook 获取
const App = () => {
const { token } = useToken();
return null;
};
// 渲染示意
createRoot(document.getElementById('#app')).render(
<ConfigProvider theme={config}>
<App />
</ConfigProvider>,
);
```
如果需要将其应用到静态样式编译框架,如 less 可以通过 less-loader 注入:

2
package.json

@ -109,7 +109,7 @@
],
"dependencies": {
"@ant-design/colors": "^7.0.0",
"@ant-design/cssinjs": "^1.9.1",
"@ant-design/cssinjs": "^1.10.1",
"@ant-design/icons": "^5.1.0",
"@ant-design/react-slick": "~1.0.0",
"@babel/runtime": "^7.18.3",

Loading…
Cancel
Save