Merge branch 'master' into feature-merge-master

This commit is contained in:
栗嘉男 2023-10-29 14:04:47 +08:00
commit 661f3e8323
60 changed files with 3474 additions and 4301 deletions

View File

@ -7,7 +7,7 @@ version: 2.1
jobs: jobs:
test-argos-ci: test-argos-ci:
docker: docker:
- image: cimg/node:21.0-browsers - image: cimg/node:21.1-browsers
environment: environment:
NODE_OPTIONS: --openssl-legacy-provider NODE_OPTIONS: --openssl-legacy-provider
steps: steps:

View File

@ -36,7 +36,8 @@ const useStyle = () => {
position: absolute; position: absolute;
inset: 0; inset: 0;
backdrop-filter: blur(4px); backdrop-filter: blur(4px);
transition: all 1s ease; opacity: 1;
transition: opacity 1s ease;
`); `);
return { return {
@ -54,7 +55,7 @@ const useStyle = () => {
row-gap: ${token.marginXL}px; row-gap: ${token.marginXL}px;
&:hover .${mask} { &:hover .${mask} {
backdrop-filter: none; opacity: 0;
} }
`, `,

View File

@ -1,7 +1,6 @@
import type { CSSProperties } from 'react'; import type { CSSProperties } from 'react';
import React, { useCallback, useMemo, useState } from 'react'; import React, { useCallback, useMemo, useState } from 'react';
import Icon, * as AntdIcons from '@ant-design/icons'; import Icon, * as AntdIcons from '@ant-design/icons';
import type { IntlShape } from 'react-intl';
import { createStyles, useTheme } from 'antd-style'; import { createStyles, useTheme } from 'antd-style';
import { useIntl } from 'dumi'; import { useIntl } from 'dumi';
import debounce from 'lodash/debounce'; import debounce from 'lodash/debounce';
@ -28,21 +27,23 @@ const useStyle = createStyles(({ css }) => ({
`, `,
})); }));
const options = (intl: IntlShape): SegmentedProps['options'] => [ const options = (
formatMessage: (values: Record<string, string>) => React.ReactNode,
): SegmentedProps['options'] => [
{ {
value: ThemeType.Outlined, value: ThemeType.Outlined,
icon: <Icon component={OutlinedIcon} />, icon: <Icon component={OutlinedIcon} />,
label: intl.formatMessage({ id: 'app.docs.components.icon.outlined' }), label: formatMessage({ id: 'app.docs.components.icon.outlined' }),
}, },
{ {
value: ThemeType.Filled, value: ThemeType.Filled,
icon: <Icon component={FilledIcon} />, icon: <Icon component={FilledIcon} />,
label: intl.formatMessage({ id: 'app.docs.components.icon.filled' }), label: formatMessage({ id: 'app.docs.components.icon.filled' }),
}, },
{ {
value: ThemeType.TwoTone, value: ThemeType.TwoTone,
icon: <Icon component={TwoToneIcon} />, icon: <Icon component={TwoToneIcon} />,
label: intl.formatMessage({ id: 'app.docs.components.icon.two-tone' }), label: formatMessage({ id: 'app.docs.components.icon.two-tone' }),
}, },
]; ];
@ -66,7 +67,7 @@ const IconSearch: React.FC = () => {
setDisplayState((prevState) => ({ ...prevState, searchKey: e.target.value })); setDisplayState((prevState) => ({ ...prevState, searchKey: e.target.value }));
}, 300); }, 300);
const handleChangeTheme = useCallback((value) => { const handleChangeTheme = useCallback((value: ThemeType) => {
setDisplayState((prevState) => ({ ...prevState, theme: value as ThemeType })); setDisplayState((prevState) => ({ ...prevState, theme: value as ThemeType }));
}, []); }, []);
@ -111,7 +112,7 @@ const IconSearch: React.FC = () => {
return categoriesResult.length ? categoriesResult : <Empty style={{ margin: '2em 0' }} />; return categoriesResult.length ? categoriesResult : <Empty style={{ margin: '2em 0' }} />;
}, [displayState.searchKey, displayState.theme]); }, [displayState.searchKey, displayState.theme]);
const [searchBarAffixed, setSearchBarAffixed] = useState<boolean>(false); const [searchBarAffixed, setSearchBarAffixed] = useState<boolean | undefined>(false);
const { borderRadius, colorBgContainer, anchorTop } = token; const { borderRadius, colorBgContainer, anchorTop } = token;
const affixedStyle: CSSProperties = { const affixedStyle: CSSProperties = {
@ -129,7 +130,7 @@ const IconSearch: React.FC = () => {
<Segmented <Segmented
size="large" size="large"
value={displayState.theme} value={displayState.theme}
options={options(intl)} options={options(intl.formatMessage)}
onChange={handleChangeTheme} onChange={handleChangeTheme}
/> />
<Input.Search <Input.Search

View File

@ -5,7 +5,7 @@
# 4. Then the new tag will trigger this current action # 4. Then the new tag will trigger this current action
# 5. The action will generate a new release, and publish DingDing notification at the same time # 5. The action will generate a new release, and publish DingDing notification at the same time
name: Release Helper name: DingTalk Release Notification
on: on:
create create
@ -20,7 +20,7 @@ jobs:
if: github.event.ref_type == 'tag' if: github.event.ref_type == 'tag'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: release antd - name: Send to Ant Design DingGroup
uses: actions-cool/release-helper@v2 uses: actions-cool/release-helper@v2
with: with:
trigger: 'tag' trigger: 'tag'
@ -36,7 +36,7 @@ jobs:
prettier: true prettier: true
prerelease-filter: '-, a, b, A, B' prerelease-filter: '-, a, b, A, B'
- name: notice bigfish - name: Send to Bigfish DingGroup
uses: actions-cool/release-helper@v2 uses: actions-cool/release-helper@v2
with: with:
trigger: 'tag' trigger: 'tag'

22
.github/workflows/release-tweet.yml vendored Normal file
View File

@ -0,0 +1,22 @@
name: 🐦 Release to Tweet
on:
release:
types: [published]
permissions:
contents: read
jobs:
tweet:
runs-on: ubuntu-latest
steps:
- name: Tweet
uses: nearform-actions/github-action-notify-twitter@v1
with:
message: |
Ant Design (antd@${{ github.event.release.tag_name }}) has been released ~ 🎊🎊🎊 Check out the release notes: ${{ github.event.release.html_url }}
twitter-app-key: ${{ secrets.TWITTER_API_KEY }}
twitter-app-secret: ${{ secrets.TWITTER_API_SECRET_KEY }}
twitter-access-token: ${{ secrets.TWITTER_ACCESS_TOKEN }}
twitter-access-token-secret: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}

View File

@ -84,7 +84,7 @@ pnpm add antd
## 🔨 示例 ## 🔨 示例
```jsx ```tsx
import React from 'react'; import React from 'react';
import { Button, DatePicker } from 'antd'; import { Button, DatePicker } from 'antd';
@ -94,6 +94,8 @@ const App = () => (
<DatePicker /> <DatePicker />
</> </>
); );
export default App;
``` ```
### 🌈 定制主题 ### 🌈 定制主题

View File

@ -84,7 +84,7 @@ pnpm add antd
## 🔨 Usage ## 🔨 Usage
```jsx ```tsx
import React from 'react'; import React from 'react';
import { Button, DatePicker } from 'antd'; import { Button, DatePicker } from 'antd';
@ -94,6 +94,8 @@ const App = () => (
<DatePicker placeholder="select date" /> <DatePicker placeholder="select date" />
</> </>
); );
export default App;
``` ```
### TypeScript ### TypeScript

View File

@ -1,12 +1,13 @@
import React from 'react'; import React from 'react';
import type { MessageInstance, ConfigOptions as MessageConfig } from '../message/interface';
import type { NotificationInstance, NotificationConfig } from '../notification/interface';
import type { HookAPI as ModalHookAPI } from '../modal/useModal';
export type AppConfig = { import type { ConfigOptions as MessageConfig, MessageInstance } from '../message/interface';
import type { HookAPI as ModalHookAPI } from '../modal/useModal';
import type { NotificationConfig, NotificationInstance } from '../notification/interface';
export interface AppConfig {
message?: MessageConfig; message?: MessageConfig;
notification?: NotificationConfig; notification?: NotificationConfig;
}; }
export const AppConfigContext = React.createContext<AppConfig>({}); export const AppConfigContext = React.createContext<AppConfig>({});

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,14 @@
import React from 'react'; import React from 'react';
import { Button, Space } from 'antd'; import { Button, Flex } from 'antd';
const App: React.FC = () => ( const App: React.FC = () => (
<Space wrap> <Flex gap="small" wrap="wrap">
<Button type="primary">Primary Button</Button> <Button type="primary">Primary Button</Button>
<Button>Default Button</Button> <Button>Default Button</Button>
<Button type="dashed">Dashed Button</Button> <Button type="dashed">Dashed Button</Button>
<Button type="text">Text Button</Button> <Button type="text">Text Button</Button>
<Button type="link">Link Button</Button> <Button type="link">Link Button</Button>
</Space> </Flex>
); );
export default App; export default App;

View File

@ -1,8 +1,8 @@
import React from 'react'; import React from 'react';
import { Button, Space } from 'antd'; import { Button, Flex } from 'antd';
const App: React.FC = () => ( const App: React.FC = () => (
<Space direction="vertical" style={{ width: '100%' }}> <Flex vertical gap="small" style={{ width: '100%' }}>
<Button type="primary" block> <Button type="primary" block>
Primary Primary
</Button> </Button>
@ -19,7 +19,7 @@ const App: React.FC = () => (
<Button type="link" block> <Button type="link" block>
Link Link
</Button> </Button>
</Space> </Flex>
); );
export default App; export default App;

View File

@ -1,14 +1,13 @@
// @ts-nocheck
import { PoweroffOutlined } from '@ant-design/icons';
import React from 'react'; import React from 'react';
import { Button, Space } from 'antd'; import { PoweroffOutlined } from '@ant-design/icons';
import { Button, Flex } from 'antd';
const Text1 = () => '部署'; const Text1 = () => '部署';
const Text2 = () => <span></span>; const Text2 = () => <span></span>;
const Text3 = () => 'Submit'; const Text3 = () => 'Submit';
const App: React.FC = () => ( const App: React.FC = () => (
<Space wrap> <Flex wrap="wrap" gap="small">
<Button> <Button>
<span> <span>
<span></span> <span></span>
@ -28,7 +27,7 @@ const App: React.FC = () => (
<Text1 /> <Text1 />
</Button> </Button>
<Button loading></Button> <Button loading></Button>
</Space> </Flex>
); );
export default App; export default App;

View File

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { Button, ConfigProvider, Space } from 'antd'; import { Button, ConfigProvider, Flex } from 'antd';
const App: React.FC = () => ( const App: React.FC = () => (
<ConfigProvider <ConfigProvider
@ -10,7 +10,7 @@ const App: React.FC = () => (
colorPrimary: '#1976d2', colorPrimary: '#1976d2',
controlHeight: 36, controlHeight: 36,
primaryShadow: primaryShadow:
'0px 3px 1px -2px rgba(0,0,0,0.2), 0px 2px 2px 0px rgba(0,0,0,0.14), 0px 1px 5px 0px rgba(0,0,0,0.12)', '0 3px 1px -2px rgba(0,0,0,0.2), 0 2px 2px 0 rgba(0,0,0,0.14), 0 1px 5px 0 rgba(0,0,0,0.12)',
fontWeight: 500, fontWeight: 500,
defaultBorderColor: 'rgba(25, 118, 210, 0.5)', defaultBorderColor: 'rgba(25, 118, 210, 0.5)',
colorText: '#1976d2', colorText: '#1976d2',
@ -22,13 +22,13 @@ const App: React.FC = () => (
}, },
}} }}
> >
<Space direction="vertical"> <Flex gap="small" vertical>
<Space wrap> <Flex wrap="wrap" gap="small">
<Button type="text">TEXT</Button> <Button type="text">TEXT</Button>
<Button type="primary">CONTAINED</Button> <Button type="primary">CONTAINED</Button>
<Button>OUTLINED</Button> <Button>OUTLINED</Button>
</Space> </Flex>
<Space wrap> <Flex wrap="wrap" gap="small">
<Button type="text" disabled> <Button type="text" disabled>
TEXT TEXT
</Button> </Button>
@ -36,8 +36,8 @@ const App: React.FC = () => (
CONTAINED CONTAINED
</Button> </Button>
<Button disabled>OUTLINED</Button> <Button disabled>OUTLINED</Button>
</Space> </Flex>
</Space> </Flex>
</ConfigProvider> </ConfigProvider>
); );

View File

@ -1,8 +1,8 @@
import React from 'react'; import React from 'react';
import { Button, Space } from 'antd'; import { Button, Flex } from 'antd';
const App: React.FC = () => ( const App: React.FC = () => (
<Space wrap> <Flex wrap="wrap" gap="small">
<Button type="primary" danger> <Button type="primary" danger>
Primary Primary
</Button> </Button>
@ -16,7 +16,7 @@ const App: React.FC = () => (
<Button type="link" danger> <Button type="link" danger>
Link Link
</Button> </Button>
</Space> </Flex>
); );
export default App; export default App;

View File

@ -1,11 +1,10 @@
import React from 'react';
import { SearchOutlined } from '@ant-design/icons'; import { SearchOutlined } from '@ant-design/icons';
import React, { useState } from 'react'; import { Button, ConfigProvider, Divider, Flex, Radio, Tooltip } from 'antd';
import { Button, ConfigProvider, Divider, Radio, Space, Tooltip } from 'antd';
import type { SizeType } from 'antd/es/config-provider/SizeContext'; import type { SizeType } from 'antd/es/config-provider/SizeContext';
const App: React.FC = () => { const App: React.FC = () => {
const [size, setSize] = useState<SizeType>('large'); const [size, setSize] = React.useState<SizeType>('large');
return ( return (
<> <>
<Radio.Group value={size} onChange={(e) => setSize(e.target.value)}> <Radio.Group value={size} onChange={(e) => setSize(e.target.value)}>
@ -17,8 +16,8 @@ const App: React.FC = () => {
Preview Preview
</Divider> </Divider>
<ConfigProvider componentSize={size}> <ConfigProvider componentSize={size}>
<Space direction="vertical"> <Flex gap="small" vertical>
<Space wrap> <Flex gap="small" wrap="wrap">
<Tooltip title="search"> <Tooltip title="search">
<Button type="primary" shape="circle" icon={<SearchOutlined />} /> <Button type="primary" shape="circle" icon={<SearchOutlined />} />
</Tooltip> </Tooltip>
@ -32,8 +31,8 @@ const App: React.FC = () => {
<Button shape="circle" icon={<SearchOutlined />} /> <Button shape="circle" icon={<SearchOutlined />} />
</Tooltip> </Tooltip>
<Button icon={<SearchOutlined />}>Search</Button> <Button icon={<SearchOutlined />}>Search</Button>
</Space> </Flex>
<Space wrap> <Flex gap="small" wrap="wrap">
<Tooltip title="search"> <Tooltip title="search">
<Button shape="circle" icon={<SearchOutlined />} /> <Button shape="circle" icon={<SearchOutlined />} />
</Tooltip> </Tooltip>
@ -49,8 +48,8 @@ const App: React.FC = () => {
<SearchOutlined /> <SearchOutlined />
Search Search
</Button> </Button>
</Space> </Flex>
</Space> </Flex>
</ConfigProvider> </ConfigProvider>
</> </>
); );

View File

@ -1,73 +1,73 @@
import React from 'react'; import React from 'react';
import { Button, Space } from 'antd'; import { Button, Flex } from 'antd';
const App: React.FC = () => ( const App: React.FC = () => (
<Space direction="vertical"> <Flex gap="small" align="flex-start" vertical>
<Space> <Flex gap="small">
<Button type="primary">Primary</Button> <Button type="primary">Primary</Button>
<Button type="primary" disabled> <Button type="primary" disabled>
Primary(disabled) Primary(disabled)
</Button> </Button>
</Space> </Flex>
<Space> <Flex gap="small">
<Button>Default</Button> <Button>Default</Button>
<Button disabled>Default(disabled)</Button> <Button disabled>Default(disabled)</Button>
</Space> </Flex>
<Space> <Flex gap="small">
<Button type="dashed">Dashed</Button> <Button type="dashed">Dashed</Button>
<Button type="dashed" disabled> <Button type="dashed" disabled>
Dashed(disabled) Dashed(disabled)
</Button> </Button>
</Space> </Flex>
<Space> <Flex gap="small">
<Button type="text">Text</Button> <Button type="text">Text</Button>
<Button type="text" disabled> <Button type="text" disabled>
Text(disabled) Text(disabled)
</Button> </Button>
</Space> </Flex>
<Space> <Flex gap="small">
<Button type="link">Link</Button> <Button type="link">Link</Button>
<Button type="link" disabled> <Button type="link" disabled>
Link(disabled) Link(disabled)
</Button> </Button>
</Space> </Flex>
<Space> <Flex gap="small">
<Button type="primary" href='https://ant.design/index-cn'> <Button type="primary" href="https://ant.design/index-cn">
Href Primary Href Primary
</Button> </Button>
<Button type="primary" href='https://ant.design/index-cn' disabled> <Button type="primary" href="https://ant.design/index-cn" disabled>
Href Primary(disabled) Href Primary(disabled)
</Button> </Button>
</Space> </Flex>
<Space> <Flex gap="small">
<Button danger>Danger Default</Button> <Button danger>Danger Default</Button>
<Button danger disabled> <Button danger disabled>
Danger Default(disabled) Danger Default(disabled)
</Button> </Button>
</Space> </Flex>
<Space> <Flex gap="small">
<Button danger type="text"> <Button danger type="text">
Danger Text Danger Text
</Button> </Button>
<Button danger type="text" disabled> <Button danger type="text" disabled>
Danger Text(disabled) Danger Text(disabled)
</Button> </Button>
</Space> </Flex>
<Space> <Flex gap="small">
<Button type="link" danger> <Button type="link" danger>
Danger Link Danger Link
</Button> </Button>
<Button type="link" danger disabled> <Button type="link" danger disabled>
Danger Link(disabled) Danger Link(disabled)
</Button> </Button>
</Space> </Flex>
<Space className="site-button-ghost-wrapper"> <Flex gap="small" className="site-button-ghost-wrapper">
<Button ghost>Ghost</Button> <Button ghost>Ghost</Button>
<Button ghost disabled> <Button ghost disabled>
Ghost(disabled) Ghost(disabled)
</Button> </Button>
</Space> </Flex>
</Space> </Flex>
); );
export default App; export default App;

View File

@ -1,8 +1,8 @@
import React from 'react'; import React from 'react';
import { Button, Space } from 'antd'; import { Button, Flex } from 'antd';
const App: React.FC = () => ( const App: React.FC = () => (
<Space className="site-button-ghost-wrapper" wrap> <Flex wrap="wrap" gap="small" className="site-button-ghost-wrapper">
<Button type="primary" ghost> <Button type="primary" ghost>
Primary Primary
</Button> </Button>
@ -13,7 +13,7 @@ const App: React.FC = () => (
<Button type="primary" danger ghost> <Button type="primary" danger ghost>
Danger Danger
</Button> </Button>
</Space> </Flex>
); );
export default App; export default App;

View File

@ -1,10 +1,10 @@
import React from 'react'; import React from 'react';
import { SearchOutlined } from '@ant-design/icons'; import { SearchOutlined } from '@ant-design/icons';
import { Button, Tooltip, Space } from 'antd'; import { Button, Flex, Tooltip } from 'antd';
const App: React.FC = () => ( const App: React.FC = () => (
<Space direction="vertical"> <Flex gap="small" vertical>
<Space wrap> <Flex wrap="wrap" gap="small">
<Tooltip title="search"> <Tooltip title="search">
<Button type="primary" shape="circle" icon={<SearchOutlined />} /> <Button type="primary" shape="circle" icon={<SearchOutlined />} />
</Tooltip> </Tooltip>
@ -18,8 +18,8 @@ const App: React.FC = () => (
<Button shape="circle" icon={<SearchOutlined />} /> <Button shape="circle" icon={<SearchOutlined />} />
</Tooltip> </Tooltip>
<Button icon={<SearchOutlined />}>Search</Button> <Button icon={<SearchOutlined />}>Search</Button>
</Space> </Flex>
<Space wrap> <Flex wrap="wrap" gap="small">
<Tooltip title="search"> <Tooltip title="search">
<Button shape="circle" icon={<SearchOutlined />} /> <Button shape="circle" icon={<SearchOutlined />} />
</Tooltip> </Tooltip>
@ -31,8 +31,8 @@ const App: React.FC = () => (
Search Search
</Button> </Button>
<Button icon={<SearchOutlined />} href="https://www.google.com" /> <Button icon={<SearchOutlined />} href="https://www.google.com" />
</Space> </Flex>
</Space> </Flex>
); );
export default App; export default App;

View File

@ -1,6 +1,6 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { PoweroffOutlined } from '@ant-design/icons'; import { PoweroffOutlined } from '@ant-design/icons';
import { Button, Space } from 'antd'; import { Button, Flex } from 'antd';
const App: React.FC = () => { const App: React.FC = () => {
const [loadings, setLoadings] = useState<boolean[]>([]); const [loadings, setLoadings] = useState<boolean[]>([]);
@ -22,8 +22,8 @@ const App: React.FC = () => {
}; };
return ( return (
<Space direction="vertical"> <Flex gap="small" vertical>
<Space wrap> <Flex gap="small" align="center" wrap="wrap">
<Button type="primary" loading> <Button type="primary" loading>
Loading Loading
</Button> </Button>
@ -31,9 +31,8 @@ const App: React.FC = () => {
Loading Loading
</Button> </Button>
<Button type="primary" icon={<PoweroffOutlined />} loading /> <Button type="primary" icon={<PoweroffOutlined />} loading />
</Space> </Flex>
<Flex gap="small" wrap="wrap">
<Space wrap>
<Button type="primary" loading={loadings[0]} onClick={() => enterLoading(0)}> <Button type="primary" loading={loadings[0]} onClick={() => enterLoading(0)}>
Click me! Click me!
</Button> </Button>
@ -51,8 +50,8 @@ const App: React.FC = () => {
loading={loadings[2]} loading={loadings[2]}
onClick={() => enterLoading(2)} onClick={() => enterLoading(2)}
/> />
</Space> </Flex>
</Space> </Flex>
); );
}; };

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import type { MenuProps } from 'antd'; import type { MenuProps } from 'antd';
import { Button, Dropdown, Space } from 'antd'; import { Button, Dropdown, Flex } from 'antd';
const onMenuClick: MenuProps['onClick'] = (e) => { const onMenuClick: MenuProps['onClick'] = (e) => {
console.log('click', e); console.log('click', e);
@ -22,11 +22,11 @@ const items = [
]; ];
const App: React.FC = () => ( const App: React.FC = () => (
<Space direction="vertical"> <Flex align="flex-start" gap="small" vertical>
<Button type="primary">primary</Button> <Button type="primary">primary</Button>
<Button>secondary</Button> <Button>secondary</Button>
<Dropdown.Button menu={{ items, onClick: onMenuClick }}>Actions</Dropdown.Button> <Dropdown.Button menu={{ items, onClick: onMenuClick }}>Actions</Dropdown.Button>
</Space> </Flex>
); );
export default App; export default App;

View File

@ -1,11 +1,10 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { DownloadOutlined } from '@ant-design/icons'; import { DownloadOutlined } from '@ant-design/icons';
import { Button, Radio, Space, Divider } from 'antd'; import { Button, Divider, Flex, Radio } from 'antd';
import type { SizeType } from 'antd/es/config-provider/SizeContext'; import type { SizeType } from 'antd/es/config-provider/SizeContext';
const App: React.FC = () => { const App: React.FC = () => {
const [size, setSize] = useState<SizeType>('large'); // default is 'middle' const [size, setSize] = useState<SizeType>('large'); // default is 'middle'
return ( return (
<> <>
<Radio.Group value={size} onChange={(e) => setSize(e.target.value)}> <Radio.Group value={size} onChange={(e) => setSize(e.target.value)}>
@ -16,8 +15,8 @@ const App: React.FC = () => {
<Divider orientation="left" plain> <Divider orientation="left" plain>
Preview Preview
</Divider> </Divider>
<Space direction="vertical"> <Flex gap="small" align="flex-start" vertical>
<Space wrap> <Flex gap="small" wrap="wrap">
<Button type="primary" size={size}> <Button type="primary" size={size}>
Primary Primary
</Button> </Button>
@ -25,11 +24,11 @@ const App: React.FC = () => {
<Button type="dashed" size={size}> <Button type="dashed" size={size}>
Dashed Dashed
</Button> </Button>
</Space> </Flex>
<Button type="link" size={size}> <Button type="link" size={size}>
Link Link
</Button> </Button>
<Space wrap> <Flex gap="small" wrap="wrap">
<Button type="primary" icon={<DownloadOutlined />} size={size} /> <Button type="primary" icon={<DownloadOutlined />} size={size} />
<Button type="primary" shape="circle" icon={<DownloadOutlined />} size={size} /> <Button type="primary" shape="circle" icon={<DownloadOutlined />} size={size} />
<Button type="primary" shape="round" icon={<DownloadOutlined />} size={size} /> <Button type="primary" shape="round" icon={<DownloadOutlined />} size={size} />
@ -39,8 +38,8 @@ const App: React.FC = () => {
<Button type="primary" icon={<DownloadOutlined />} size={size}> <Button type="primary" icon={<DownloadOutlined />} size={size}>
Download Download
</Button> </Button>
</Space> </Flex>
</Space> </Flex>
</> </>
); );
}; };

View File

@ -920,6 +920,31 @@ export const genPanelStyle = (token: SharedPickerToken): CSSObject => {
transition: `background ${motionDurationMid}`, transition: `background ${motionDurationMid}`,
overflowX: 'hidden', overflowX: 'hidden',
'&::-webkit-scrollbar': {
width: '7px',
backgroundColor: ' #f1f1f1',
},
'&::-webkit-scrollbar-thumb': {
backgroundColor: '#b6b2b2',
borderRadius: '5px',
},
'&::-webkit-scrollbar-thumb:hover': {
backgroundColor: '#7a7a7a',
},
// 兼容firefox
'&': {
scrollbarWidth: 'thin',
scrollbarColor: `#b6b2b2 #f1f1f1`,
},
'&::-moz-scrollbar-thumb': {
backgroundColor: '#b6b2b2',
},
'&::-moz-scrollbar-track': {
backgroundColor: ' #f1f1f1',
},
'&::after': { '&::after': {
display: 'block', display: 'block',
height: timeColumnHeight - timeCellHeight, height: timeColumnHeight - timeCellHeight,

View File

@ -267,7 +267,6 @@ describe('Dropdown', () => {
it('should trigger open event when click on item', () => { it('should trigger open event when click on item', () => {
const onOpenChange = jest.fn(); const onOpenChange = jest.fn();
render( render(
<Dropdown <Dropdown
onOpenChange={onOpenChange} onOpenChange={onOpenChange}
@ -288,4 +287,41 @@ describe('Dropdown', () => {
fireEvent.click(document.body.querySelector('.bamboo')!); fireEvent.click(document.body.querySelector('.bamboo')!);
expect(onOpenChange).toHaveBeenCalledWith(false, { source: 'menu' }); expect(onOpenChange).toHaveBeenCalledWith(false, { source: 'menu' });
}); });
it('is still open after selection in multiple mode', () => {
jest.useFakeTimers();
const { container } = render(
<Dropdown
trigger={['click']}
menu={{
selectable: true,
multiple: true,
items: [
{ label: '1', key: 1 },
{ label: '2', key: 2 },
],
}}
>
<a />
</Dropdown>,
);
// Open
fireEvent.click(container.querySelector('a')!);
act(() => {
jest.runAllTimers();
});
// Selecting item
fireEvent.click(container.querySelector('.ant-dropdown-menu-item')!);
// Force Motion move on
for (let i = 0; i < 10; i += 1) {
act(() => {
jest.runAllTimers();
});
}
expect(container.querySelector('.ant-dropdown-hidden')).toBeFalsy();
jest.useRealTimers();
});
}); });

View File

@ -215,9 +215,12 @@ const Dropdown: CompoundedComponent = (props) => {
}); });
const onMenuClick = React.useCallback(() => { const onMenuClick = React.useCallback(() => {
if (menu?.selectable && menu?.multiple) {
return;
}
onOpenChange?.(false, { source: 'menu' }); onOpenChange?.(false, { source: 'menu' });
setOpen(false); setOpen(false);
}, []); }, [menu?.selectable, menu?.multiple]);
const renderOverlay = () => { const renderOverlay = () => {
// rc-dropdown already can process the function of overlay, but we have check logic here. // rc-dropdown already can process the function of overlay, but we have check logic here.

View File

@ -2,7 +2,6 @@ import React, { useContext, useEffect, useState } from 'react';
import VerticalAlignTopOutlined from '@ant-design/icons/VerticalAlignTopOutlined'; import VerticalAlignTopOutlined from '@ant-design/icons/VerticalAlignTopOutlined';
import classNames from 'classnames'; import classNames from 'classnames';
import CSSMotion from 'rc-motion'; import CSSMotion from 'rc-motion';
import { composeRef } from 'rc-util/lib/ref';
import getScroll from '../_util/getScroll'; import getScroll from '../_util/getScroll';
import scrollTo from '../_util/scrollTo'; import scrollTo from '../_util/scrollTo';
@ -14,7 +13,7 @@ import FloatButton, { floatButtonPrefixCls } from './FloatButton';
import type { BackTopProps, FloatButtonProps, FloatButtonRef, FloatButtonShape } from './interface'; import type { BackTopProps, FloatButtonProps, FloatButtonRef, FloatButtonShape } from './interface';
import useStyle from './style'; import useStyle from './style';
const BackTop = React.forwardRef<FloatButtonRef['nativeElement'], BackTopProps>((props, ref) => { const BackTop = React.forwardRef<FloatButtonRef, BackTopProps>((props, ref) => {
const { const {
prefixCls: customizePrefixCls, prefixCls: customizePrefixCls,
className, className,
@ -32,7 +31,9 @@ const BackTop = React.forwardRef<FloatButtonRef['nativeElement'], BackTopProps>(
const internalRef = React.useRef<FloatButtonRef['nativeElement']>(null); const internalRef = React.useRef<FloatButtonRef['nativeElement']>(null);
const mergedRef = composeRef<FloatButtonRef['nativeElement']>(ref, internalRef); React.useImperativeHandle(ref, () => ({
nativeElement: internalRef.current,
}));
const getDefaultTarget = (): HTMLElement | Document | Window => const getDefaultTarget = (): HTMLElement | Document | Window =>
internalRef.current && internalRef.current.ownerDocument internalRef.current && internalRef.current.ownerDocument
@ -78,7 +79,7 @@ const BackTop = React.forwardRef<FloatButtonRef['nativeElement'], BackTopProps>(
<CSSMotion visible={visible} motionName={`${rootPrefixCls}-fade`}> <CSSMotion visible={visible} motionName={`${rootPrefixCls}-fade`}>
{({ className: motionClassName }) => ( {({ className: motionClassName }) => (
<FloatButton <FloatButton
ref={mergedRef} ref={internalRef}
{...contentProps} {...contentProps}
onClick={scrollToTop} onClick={scrollToTop}
className={classNames(className, motionClassName)} className={classNames(className, motionClassName)}

View File

@ -7,7 +7,7 @@ import type Group from './FloatButtonGroup';
import type PurePanel from './PurePanel'; import type PurePanel from './PurePanel';
export interface FloatButtonRef { export interface FloatButtonRef {
nativeElement: HTMLAnchorElement & HTMLButtonElement; nativeElement: (HTMLAnchorElement & HTMLButtonElement) | null;
} }
export type FloatButtonType = 'default' | 'primary'; export type FloatButtonType = 'default' | 'primary';

View File

@ -8,7 +8,7 @@ import type { Options } from 'scroll-into-view-if-needed';
import { ConfigContext } from '../config-provider'; import { ConfigContext } from '../config-provider';
import DisabledContext, { DisabledContextProvider } from '../config-provider/DisabledContext'; import DisabledContext, { DisabledContextProvider } from '../config-provider/DisabledContext';
import type { SizeType } from '../config-provider/SizeContext'; import type { SizeType } from '../config-provider/SizeContext';
import { SizeContextProvider } from '../config-provider/SizeContext'; import SizeContext from '../config-provider/SizeContext';
import useSize from '../config-provider/hooks/useSize'; import useSize from '../config-provider/hooks/useSize';
import type { ColProps } from '../grid/col'; import type { ColProps } from '../grid/col';
import type { FormContextProps } from './context'; import type { FormContextProps } from './context';
@ -179,7 +179,7 @@ const InternalForm: React.ForwardRefRenderFunction<FormInstance, FormProps> = (p
return wrapSSR( return wrapSSR(
<DisabledContextProvider disabled={disabled}> <DisabledContextProvider disabled={disabled}>
<SizeContextProvider size={mergedSize}> <SizeContext.Provider value={mergedSize}>
<FormProvider <FormProvider
{...{ {...{
// This is not list in API, we pass with spread // This is not list in API, we pass with spread
@ -198,7 +198,7 @@ const InternalForm: React.ForwardRefRenderFunction<FormInstance, FormProps> = (p
/> />
</FormContext.Provider> </FormContext.Provider>
</FormProvider> </FormProvider>
</SizeContextProvider> </SizeContext.Provider>
</DisabledContextProvider>, </DisabledContextProvider>,
); );
}; };

View File

@ -203,7 +203,7 @@ One of the Table `columns` prop for describing the table's columns, Column has t
| shouldCellUpdate | Control cell render logic | (record, prevRecord) => boolean | - | 4.3.0 | | shouldCellUpdate | Control cell render logic | (record, prevRecord) => boolean | - | 4.3.0 |
| showSorterTooltip | If header show next sorter direction tooltip, override `showSorterTooltip` in table | boolean \| [Tooltip props](/components/tooltip/) | true | | | showSorterTooltip | If header show next sorter direction tooltip, override `showSorterTooltip` in table | boolean \| [Tooltip props](/components/tooltip/) | true | |
| sortDirections | Supported sort way, override `sortDirections` in `Table`, could be `ascend`, `descend` | Array | \[`ascend`, `descend`] | | | sortDirections | Supported sort way, override `sortDirections` in `Table`, could be `ascend`, `descend` | Array | \[`ascend`, `descend`] | |
| sorter | Sort function for local sort, see [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)'s compareFunction. If you need sort buttons only, set to `true` | function \| boolean \| { compare: function, multiple: number } | - | | | sorter | Sort function for local sort, see [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)'s compareFunction. If it is server-side sorting, set to `true`, but if you want to support multi-column sorting, you can set it to `{ multiple: number }` | function \| boolean \| { compare: function, multiple: number } | - | |
| sortOrder | Order of sorted values: `ascend` `descend` `null` | `ascend` \| `descend` \| null | - | | | sortOrder | Order of sorted values: `ascend` `descend` `null` | `ascend` \| `descend` \| null | - | |
| sortIcon | Customized sort icon | (props: { sortOrder }) => ReactNode | - | 5.6.0 | | sortIcon | Customized sort icon | (props: { sortOrder }) => ReactNode | - | 5.6.0 |
| title | Title of this column | ReactNode \| ({ sortOrder, sortColumn, filters }) => ReactNode | - | | | title | Title of this column | ReactNode \| ({ sortOrder, sortColumn, filters }) => ReactNode | - | |

View File

@ -196,7 +196,7 @@ const columns = [
| filterMode | 指定筛选菜单的用户界面 | 'menu' \| 'tree' | 'menu' | 4.17.0 | | filterMode | 指定筛选菜单的用户界面 | 'menu' \| 'tree' | 'menu' | 4.17.0 |
| filterSearch | 筛选菜单项是否可搜索 | boolean \| function(input, record):boolean | false | boolean:4.17.0 function:4.19.0 | | filterSearch | 筛选菜单项是否可搜索 | boolean \| function(input, record):boolean | false | boolean:4.17.0 function:4.19.0 |
| filters | 表头的筛选菜单项 | object\[] | - | | | filters | 表头的筛选菜单项 | object\[] | - | |
| fixed | IE 下无效)列是否固定,可选 true (等效于 left) `left` `right` | boolean \| string | false | | | fixed | IE 下无效)列是否固定,可选 `true` (等效于 `left`) `left` `right` | boolean \| string | false | |
| key | React 需要的 key如果已经设置了唯一的 `dataIndex`,可以忽略这个属性 | string | - | | | key | React 需要的 key如果已经设置了唯一的 `dataIndex`,可以忽略这个属性 | string | - | |
| render | 生成复杂数据的渲染函数,参数分别为当前行的值,当前行数据,行索引 | function(text, record, index) {} | - | | | render | 生成复杂数据的渲染函数,参数分别为当前行的值,当前行数据,行索引 | function(text, record, index) {} | - | |
| responsive | 响应式 breakpoint 配置列表。未设置则始终可见。 | [Breakpoint](https://github.com/ant-design/ant-design/blob/015109b42b85c63146371b4e32b883cf97b088e8/components/_util/responsiveObserve.ts#L1)\[] | - | 4.2.0 | | responsive | 响应式 breakpoint 配置列表。未设置则始终可见。 | [Breakpoint](https://github.com/ant-design/ant-design/blob/015109b42b85c63146371b4e32b883cf97b088e8/components/_util/responsiveObserve.ts#L1)\[] | - | 4.2.0 |
@ -204,7 +204,7 @@ const columns = [
| shouldCellUpdate | 自定义单元格渲染时机 | (record, prevRecord) => boolean | - | 4.3.0 | | shouldCellUpdate | 自定义单元格渲染时机 | (record, prevRecord) => boolean | - | 4.3.0 |
| showSorterTooltip | 表头显示下一次排序的 tooltip 提示, 覆盖 table 中 `showSorterTooltip` | boolean \| [Tooltip props](/components/tooltip-cn/#api) | true | | | showSorterTooltip | 表头显示下一次排序的 tooltip 提示, 覆盖 table 中 `showSorterTooltip` | boolean \| [Tooltip props](/components/tooltip-cn/#api) | true | |
| sortDirections | 支持的排序方式,覆盖 `Table``sortDirections` 取值为 `ascend` `descend` | Array | \[`ascend`, `descend`] | | | sortDirections | 支持的排序方式,覆盖 `Table``sortDirections` 取值为 `ascend` `descend` | Array | \[`ascend`, `descend`] | |
| sorter | 排序函数,本地排序使用一个函数(参考 [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) 的 compareFunction),需要服务端排序可设为 true | function \| boolean \| { compare: function, multiple: number } | - | | | sorter | 排序函数,本地排序使用一个函数(参考 [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) 的 compareFunction)。需要服务端排序可设为 `true`(单列排序) 或 `{ multiple: number }`(多列排序) | function \| boolean \| { compare: function, multiple: number } | - | |
| sortOrder | 排序的受控属性,外界可用此控制列的排序,可设置为 `ascend` `descend` `null` | `ascend` \| `descend` \| null | - | | | sortOrder | 排序的受控属性,外界可用此控制列的排序,可设置为 `ascend` `descend` `null` | `ascend` \| `descend` \| null | - | |
| sortIcon | 自定义 sort 图标 | (props: { sortOrder }) => ReactNode | - | 5.6.0 | | sortIcon | 自定义 sort 图标 | (props: { sortOrder }) => ReactNode | - | 5.6.0 |
| title | 列头显示文字(函数用法 `3.10.0` 后支持) | ReactNode \| ({ sortOrder, sortColumn, filters }) => ReactNode | - | | | title | 列头显示文字(函数用法 `3.10.0` 后支持) | ReactNode \| ({ sortOrder, sortColumn, filters }) => ReactNode | - | |
@ -246,7 +246,7 @@ const columns = [
| expandedRowRender | 额外的展开行 | function(record, index, indent, expanded): ReactNode | - | | | expandedRowRender | 额外的展开行 | function(record, index, indent, expanded): ReactNode | - | |
| expandIcon | 自定义展开图标,参考[示例](https://codesandbox.io/s/fervent-bird-nuzpr) | function(props): ReactNode | - | | | expandIcon | 自定义展开图标,参考[示例](https://codesandbox.io/s/fervent-bird-nuzpr) | function(props): ReactNode | - | |
| expandRowByClick | 通过点击行来展开子行 | boolean | false | | | expandRowByClick | 通过点击行来展开子行 | boolean | false | |
| fixed | 控制展开图标是否固定,可选 true `left` `right` | boolean \| string | false | 4.16.0 | | fixed | 控制展开图标是否固定,可选 `true` `'left'` `'right'` | boolean \| string | false | 4.16.0 |
| indentSize | 展示树形数据时,每层缩进的宽度,以 px 为单位 | number | 15 | | | indentSize | 展示树形数据时,每层缩进的宽度,以 px 为单位 | number | 15 | |
| rowExpandable | 设置是否允许行展开 | (record) => boolean | - | | | rowExpandable | 设置是否允许行展开 | (record) => boolean | - | |
| showExpandColumn | 设置是否展示行展开列 | boolean | true | 4.18.0 | | showExpandColumn | 设置是否展示行展开列 | boolean | true | 4.18.0 |
@ -284,7 +284,7 @@ const columns = [
| 参数 | 说明 | 类型 | 默认值 | | 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| scrollToFirstRowOnChange | 当分页、排序、筛选变化后是否滚动到表格顶部 | boolean | - | | scrollToFirstRowOnChange | 当分页、排序、筛选变化后是否滚动到表格顶部 | boolean | - |
| x | 设置横向滚动也可用于指定滚动区域的宽可以设置为像素值百分比true 和 ['max-content'](https://developer.mozilla.org/zh-CN/docs/Web/CSS/width#max-content) | string \| number \| true | - | | x | 设置横向滚动,也可用于指定滚动区域的宽,可以设置为像素值,百分比,`true` 和 ['max-content'](https://developer.mozilla.org/zh-CN/docs/Web/CSS/width#max-content) | string \| number \| true | - |
| y | 设置纵向滚动,也可用于指定滚动区域的高,可以设置为像素值 | string \| number | - | | y | 设置纵向滚动,也可用于指定滚动区域的高,可以设置为像素值 | string \| number | - |
### selection ### selection

View File

@ -42,6 +42,9 @@ function getSizeDiff<T>(prev: Set<T>, next: Set<T>) {
return prev.size === next.size ? prev : next; return prev.size === next.size ? prev : next;
} }
const DEFAULT_GAP_X = 100;
const DEFAULT_GAP_Y = 100;
const Watermark: React.FC<WatermarkProps> = (props) => { const Watermark: React.FC<WatermarkProps> = (props) => {
const { const {
/** /**
@ -58,7 +61,7 @@ const Watermark: React.FC<WatermarkProps> = (props) => {
style, style,
className, className,
rootClassName, rootClassName,
gap = [100, 100], gap = [DEFAULT_GAP_X, DEFAULT_GAP_Y],
offset, offset,
children, children,
inherit = true, inherit = true,
@ -73,7 +76,7 @@ const Watermark: React.FC<WatermarkProps> = (props) => {
textAlign = 'center', textAlign = 'center',
} = font; } = font;
const [gapX, gapY] = gap; const [gapX = DEFAULT_GAP_X, gapY = DEFAULT_GAP_Y] = gap;
const gapXCenter = gapX / 2; const gapXCenter = gapX / 2;
const gapYCenter = gapY / 2; const gapYCenter = gapY / 2;
const offsetLeft = offset?.[0] ?? gapXCenter; const offsetLeft = offset?.[0] ?? gapXCenter;

View File

@ -13,7 +13,7 @@ Ant Design 支持最近 2 个版本的现代浏览器。如果你需要兼容旧
## `:where` 选择器 ## `:where` 选择器
Ant Design 的 CSS-in-JS 默认通过 `:where` 选择器降低 CSS Selector 优先级,以减少用户升级时额外调整自定义样式成本,不过 `:where` 语法的[兼容性](https://developer.mozilla.org/en-US/docs/Web/CSS/:where#browser_compatibility)在低版本浏览器比较差。在某些场景下你如果需要支持旧版浏览器(或者如 TailwindCSS 优先级冲突),你可以使用 `@ant-design/cssinjs` 取消默认的降权操作(请注意版本保持与 antd 一致): Ant Design 的 CSS-in-JS 默认通过 `:where` 选择器降低 CSS Selector 优先级,以减少用户升级时额外调整自定义样式成本,不过 `:where` 语法的[兼容性](https://developer.mozilla.org/en-US/docs/Web/CSS/:where#browser_compatibility)在低版本浏览器比较差。在某些场景下你如果需要支持旧版浏览器(或者如 TailwindCSS 优先级冲突),你可以使用 `@ant-design/cssinjs` 取消默认的降权操作(请注意版本保持与 antd 一致):
```tsx ```tsx
import { StyleProvider } from '@ant-design/cssinjs'; import { StyleProvider } from '@ant-design/cssinjs';
@ -56,7 +56,7 @@ export default () => (
为了统一 LTR 和 RTL 样式Ant Design 使用了 CSS 逻辑属性。例如原 `margin-left` 使用 `margin-inline-start` 代替,使其在 LTR 和 RTL 下都为起始位置间距。如果你需要兼容旧版浏览器(如 360 浏览器、QQ 浏览器 等等),可以通过 `@ant-design/cssinjs``StyleProvider` 配置 `transformers` 将其转换: 为了统一 LTR 和 RTL 样式Ant Design 使用了 CSS 逻辑属性。例如原 `margin-left` 使用 `margin-inline-start` 代替,使其在 LTR 和 RTL 下都为起始位置间距。如果你需要兼容旧版浏览器(如 360 浏览器、QQ 浏览器 等等),可以通过 `@ant-design/cssinjs``StyleProvider` 配置 `transformers` 将其转换:
```tsx ```tsx
import { StyleProvider, legacyLogicalPropertiesTransformer } from '@ant-design/cssinjs'; import { legacyLogicalPropertiesTransformer, StyleProvider } from '@ant-design/cssinjs';
// `transformers` 提供预处理功能将样式进行转换 // `transformers` 提供预处理功能将样式进行转换
export default () => ( export default () => (
@ -83,7 +83,7 @@ export default () => (
在响应式网页开发中,需要一种方便且灵活的方式来实现页面的适配和响应式设计。`px2remTransformer` 转换器可以快速而准确地将样式表中的像素单位转换为相对于根元素HTML 标签)的 rem 单位,实现页面的自适应和响应式布局。 在响应式网页开发中,需要一种方便且灵活的方式来实现页面的适配和响应式设计。`px2remTransformer` 转换器可以快速而准确地将样式表中的像素单位转换为相对于根元素HTML 标签)的 rem 单位,实现页面的自适应和响应式布局。
```tsx ```tsx
import { StyleProvider, px2remTransformer } from '@ant-design/cssinjs'; import { px2remTransformer, StyleProvider } from '@ant-design/cssinjs';
const px2rem = px2remTransformer({ const px2rem = px2remTransformer({
rootValue: 32, // 32px = 1rem; @default 16 rootValue: 32, // 32px = 1rem; @default 16

View File

@ -6,7 +6,7 @@ title: 贡献指南
toc: false toc: false
--- ---
这篇指南会指导你如何为 Ant Design 贡献一份自己的力量,请在你要提 issue 或者 pull request 之前花几分钟来阅读一遍这篇指南。 这篇指南会指导你如何为 Ant Design 贡献自己的一份力量,请你在提 issue 或者 pull request 之前花几分钟来阅读一遍这篇指南。
## 行为准则 ## 行为准则
@ -18,11 +18,11 @@ toc: false
## 分支管理 ## 分支管理
基于我们的 [发布周期](/changelog),我们长期维护两个分支 `master``feature`。如果你要修一个 bug那么请发 pull request 到 `master`,我们会每周从 master 发布一个 patch 版本;如果你要提一个增加新功能的 pull request那么请基于 `feature` 分支来做,每月末我们会合并 feature 到 master并发布一个包含新特性的 minor 版本。 基于我们的 [发布周期](/changelog),我们长期维护两个分支 `master``feature`。如果你要修一个 bug那么请发 pull request 到 `master`每周我们会从 master 发布一个 patch 版本;如果你要提一个增加新功能的 pull request那么请基于 `feature` 分支来做,每月末我们会合并 feature 到 master并发布一个包含新特性的 minor 版本。
## Bugs ## Bugs
我们使用 [GitHub Issues](https://github.com/ant-design/ant-design/issues) 来做 bug 追踪。 如果你想要你发现的 bug 被快速解决,最好的办法就是通过我们提供的 [issue 小助手](http://new-issue.ant.design) 来提 issue并且能使用这个 [模板](https://u.ant.design/codesandbox-repro) 来提供重现。 我们使用 [GitHub Issues](https://github.com/ant-design/ant-design/issues) 来做 bug 追踪。 如果你想要你发现的 bug 被快速解决,最好的办法就是通过我们提供的 [issue 小助手](http://new-issue.ant.design) 来提 issue并且能使用这个 [模板](https://u.ant.design/codesandbox-repro) 来提供重现。
在你报告一个 bug 之前,请先确保已经搜索过已有的 issue 和阅读了我们的 [常见问题](/docs/react/faq)。 在你报告一个 bug 之前,请先确保已经搜索过已有的 issue 和阅读了我们的 [常见问题](/docs/react/faq)。
@ -52,20 +52,20 @@ Ant Design 团队会关注所有的 pull request我们会 review 以及合并
1. 基于 [正确的分支](#分支管理) 做修改。 1. 基于 [正确的分支](#分支管理) 做修改。
2. 在项目根目录下运行了 `npm install` 2. 在项目根目录下运行了 `npm install`
3. 如果你修复了一个 bug 或者新增了一个功能,请确保写了相应的测试,这很重要。 3. 如果你修复了一个 bug 或者新增了一个功能,请确保写了相应的测试,这很重要。
4. 确认所有的测试都是通过的 `npm run test`小贴士:开发过程中可以用 `npm test -- --watch TestName` 来运行指定的测试。 4. 确认所有的测试都通过了 `npm run test`小贴士:开发过程中可以用 `npm test -- --watch TestName` 来运行指定的测试。
5. 运行 `npm test -- -u` 来更新 [jest snapshot](https://jestjs.io/zh-Hans/docs/snapshot-testing) 并且把这些更新也提交上来(如果有的话)。 5. 运行 `npm test -- -u` 来更新 [jest snapshot](https://jestjs.io/zh-Hans/docs/snapshot-testing) 并且把这些更新也提交上来(如果有的话)。
6. 确认所有的 UI 改动通过 `npm run test-image`,可以运行 `npm run test-image -- -u` 更新 UI 快照并且把这些更新也提交上来(如果有的话),**UI 测试基于 [Docker](https://docs.docker.com/get-docker/),根据平台下载对应的安装程序。** 6. 确认所有的 UI 改动通过 `npm run test-image`,可以运行 `npm run test-image -- -u` 更新 UI 快照并且把这些更新也提交上来(如果有的话),**UI 测试基于 [Docker](https://docs.docker.com/get-docker/),根据平台下载对应的安装程序。**
7. 确保你的代码通过了 lint 检查 `npm run lint`. 小贴士: Lint 会在你 `git commit` 的时候自动运行(通过[Git Hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks))。 7. 确保你的代码通过了 lint 检查 `npm run lint`小贴士: Lint 会在你 `git commit` 的时候自动运行(通过[Git Hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks))。
8. 最后请确保所有 GitHub CI 检查通过,如果失败,可点击 `detail` 进入详情查看原因。 8. 最后请确保所有 GitHub CI 检查通过,如果失败,可点击 `detail` 进入详情查看原因。
给 [react-component](https://github.com/react-component/) 发送 pull request 给 [react-component](https://github.com/react-component/) 发送 pull request
由于 antd 的大部分组件都是基于 react-component 的,所以有时候你可能需要给相应的 react-component 仓库发送 pull request。如果你修复了某个 bug那么我们在合并你的修改后会尽快发布一个 patch 版本,然后你只要重新安装你的依赖就可以使用新发布的版本了。如果你的 pull request 是新增了某个功能,那么在你的修改合并并且发布版本后,你还需要发送一个 pull request 到 [Ant Design](https://github.com/ant-design/ant-design/) 来升级相应的依赖、文档以及 TypeScript 的类型定义。 由于 antd 的大部分组件都是基于 react-component 的,所以有时候你需要给相应的 react-component 仓库发送 pull request。如果你修复了某个 bug那么我们在合并你的修改后会尽快发布一个 patch 版本,然后你只要重新安装你的依赖就可以使用新发布的版本了。如果你的 pull request 是新增了某个功能,那么在你的修改合并并且发布版本后,你还需要发送一个 pull request 到 [Ant Design](https://github.com/ant-design/ant-design/) 来升级相应的依赖、文档以及 TypeScript 的类型定义。
## 开发流程 ## 开发流程
推荐使用 `npm``yarn` 作为包管理工具 推荐使用 `npm``yarn` 作为包管理工具
在你 clone 了 antd 的代码并且使用 在你 clone 了 antd 的代码并且使用
@ -85,7 +85,7 @@ Ant Design 团队会关注所有的 pull request我们会 review 以及合并
### 运行测试用例 ### 运行测试用例
运行测试。(在运行测试前请确保 `NODE_ENV` 环境变量没有被设定,否则可能会引发一些问题) 运行测试。在运行测试前请确保 `NODE_ENV` 环境变量没有被设定,否则可能会引发一些问题
<InstallDependencies npm='$ npm test' yarn='$ yarn test'></InstallDependencies> <InstallDependencies npm='$ npm test' yarn='$ yarn test'></InstallDependencies>
@ -103,12 +103,12 @@ Ant Design 团队会关注所有的 pull request我们会 review 以及合并
## 配套开发工具 ## 配套开发工具
- CSS in JS 样式提示插件https://marketplace.visualstudio.com/items?itemName=shezhangzhang.antd-design-token - CSS-in-JS 样式提示插件https://marketplace.visualstudio.com/items?itemName=shezhangzhang.antd-design-token
- 组件属性提示插件https://github.com/fi3ework/vscode-antd-rush - 组件属性提示插件https://github.com/fi3ework/vscode-antd-rush
## 加入社区 ## 加入社区
如果你贡献度足够活跃,希望和 Ant Design 团队一起参与维护工作,你可以[申请成为社区协作者](https://github.com/ant-design/ant-design/wiki/Collaborators#how-to-apply-for-being-a-collaborator)。 如果你的贡献度足够高,并且希望和 Ant Design 团队一起参与维护工作,你可以[申请成为社区协作者](https://github.com/ant-design/ant-design/wiki/Collaborators#how-to-apply-for-being-a-collaborator)。
你还可以参考下面三篇社区成员写的贡献指南,一步一步成为 antd 的贡献者吧: 你还可以参考下面三篇社区成员写的贡献指南,一步一步成为 antd 的贡献者吧:

View File

@ -18,7 +18,7 @@ Ant Design 设计规范和技术上支持灵活的样式定制,以满足业务
## 配置主题 ## 配置主题
在 5.0 版本中我们把影响主题的最小元素称为 **Design Token**。通过修改 Design Token我们可以呈现出各种各样的主题或者组件。通过在 `ConfigProvider` 中传入 `theme` 属性,可以配置主题。在升级 v5 后,将默认使用 v5 的主题. 在 5.0 版本中我们把影响主题的最小元素称为 **Design Token**。通过修改 Design Token我们可以呈现出各种各样的主题或者组件。通过在 `ConfigProvider` 中传入 `theme` 属性,可以配置主题。在升级 v5 后,将默认使用 v5 的主题
<!-- prettier-ignore --> <!-- prettier-ignore -->
:::warning :::warning
@ -30,7 +30,7 @@ Ant Design 设计规范和技术上支持灵活的样式定制,以满足业务
### 修改主题变量 ### 修改主题变量
通过 `theme` 中的 `token` 属性,可以修改一些主题变量。部分主题变量会引起其他主题变量的变化,我们把这些主题变量为 Seed Token。 通过 `theme` 中的 `token` 属性,可以修改一些主题变量。部分主题变量会引起其他主题变量的变化,我们把这些主题变量为 Seed Token。
```sandpack ```sandpack
const sandpackConfig = { const sandpackConfig = {
@ -329,9 +329,9 @@ const globalToken = getDesignToken();
`getDesignToken` 和 ConfigProvider 一样,支持传入 `theme` 属性,用于获取指定主题的 Design Token。 `getDesignToken` 和 ConfigProvider 一样,支持传入 `theme` 属性,用于获取指定主题的 Design Token。
```tsx ```tsx
import { createRoot } from 'react-dom/client';
import type { ThemeConfig } from 'antd'; import type { ThemeConfig } from 'antd';
import { theme } from 'antd'; import { theme } from 'antd';
import { createRoot } from 'react-dom/client';
const { getDesignToken, useToken } = theme; const { getDesignToken, useToken } = theme;
@ -377,7 +377,7 @@ createRoot(document.getElementById('#app')).render(
我们提供了帮助用户调试主题的工具:[主题编辑器](/theme-editor-cn) 我们提供了帮助用户调试主题的工具:[主题编辑器](/theme-editor-cn)
你可以使用此工具自由地修改 Design Token以达到对主题的期望。 你可以使用此工具自由地修改 Design Token以达到对主题的期望。
## 基本概念 ## 基本概念

View File

@ -47,12 +47,15 @@ export default App;
```jsx ```jsx
import React, { useState } from 'react'; import React, { useState } from 'react';
import { createRoot } from 'react-dom/client';
import { ConfigProvider, DatePicker, message } from 'antd'; import { ConfigProvider, DatePicker, message } from 'antd';
// 由于 antd 组件的默认文案是英文,所以需要修改为中文 // 由于 antd 组件的默认文案是英文,所以需要修改为中文
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { createRoot } from 'react-dom/client';
import 'dayjs/locale/zh-cn'; import 'dayjs/locale/zh-cn';
import zhCN from 'antd/locale/zh_CN'; import zhCN from 'antd/locale/zh_CN';
import './index.css'; import './index.css';
dayjs.locale('zh-cn'); dayjs.locale('zh-cn');
@ -109,7 +112,7 @@ createRoot(document.getElementById('root')).render(<App />);
### 4. 下一步 ### 4. 下一步
实际项目开发中,你会需要构建、调试、代理、打包部署等一系列工程化的需求。您可以阅读后面的文档或者使用以下脚手架和范例: 在实际项目开发中,你会遇到构建、调试、代理、打包部署等一系列工程化的需求。你可以阅读后面的文档或者使用以下脚手架和范例:
- [Ant Design Pro](https://pro.ant.design/) - [Ant Design Pro](https://pro.ant.design/)
- [create-next-app](https://github.com/ant-design/ant-design-examples/tree/main/examples/with-nextjs-inline-style) - [create-next-app](https://github.com/ant-design/ant-design-examples/tree/main/examples/with-nextjs-inline-style)

View File

@ -81,7 +81,7 @@ export default App;
### TypeScript ### TypeScript
`antd` 使用 TypeScript 进行书写并提供了完整的定义文件(不要引用 `@types/antd`)。 `antd` 使用 TypeScript 进行书写并提供了完整的定义文件(不要引用 `@types/antd`)。
## 链接 ## 链接
@ -124,7 +124,7 @@ export default App;
## 如何贡献 ## 如何贡献
在任何形式的参与前,请先阅读 [贡献者文档](https://github.com/ant-design/ant-design/blob/master/.github/CONTRIBUTING.md)。如果你希望参与贡献,欢迎 [Pull Request](https://github.com/ant-design/ant-design/pulls),或给我们 [报告 Bug](http://new-issue.ant.design/)。 在任何形式的参与前,请先阅读 [贡献者文档](https://github.com/ant-design/ant-design/blob/master/.github/CONTRIBUTING.md)。如果你希望参与贡献,欢迎提交 [Pull Request](https://github.com/ant-design/ant-design/pulls),或给我们 [报告 Bug](http://new-issue.ant.design/)。
> 强烈推荐阅读 [《提问的智慧》](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way)、[《如何向开源社区提问题》](https://github.com/seajs/seajs/issues/545) 和 [《如何有效地报告 Bug》](http://www.chiark.greenend.org.uk/%7Esgtatham/bugs-cn.html)、[《如何向开源项目提交无法解答的问题》](https://zhuanlan.zhihu.com/p/25795393),更好的问题更容易获得帮助。 > 强烈推荐阅读 [《提问的智慧》](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way)、[《如何向开源社区提问题》](https://github.com/seajs/seajs/issues/545) 和 [《如何有效地报告 Bug》](http://www.chiark.greenend.org.uk/%7Esgtatham/bugs-cn.html)、[《如何向开源项目提交无法解答的问题》](https://zhuanlan.zhihu.com/p/25795393),更好的问题更容易获得帮助。
@ -137,5 +137,5 @@ export default App;
通过 Stack Overflow 或者 Segment Fault 提问时,建议加上 `antd` 标签。 通过 Stack Overflow 或者 Segment Fault 提问时,建议加上 `antd` 标签。
1. [GitHub Discussions](https://github.com/ant-design/ant-design/discussions) 1. [GitHub Discussions](https://github.com/ant-design/ant-design/discussions)
2. [<img alt="Stack Overflow" src="https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.svg?v=2bb144720a66" width="140" />](http://stackoverflow.com/questions/tagged/antd)(English) 2. [<img alt="Stack Overflow" src="https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.svg?v=2bb144720a66" width="140" />](http://stackoverflow.com/questions/tagged/antd) (English)
3. [<img alt="Segment Fault" src="https://gw.alipayobjects.com/zos/rmsportal/hfYFfCvHTQTUKntlJbMF.svg" width="100" />](https://segmentfault.com/t/antd)(中文) 3. [<img alt="Segment Fault" src="https://gw.alipayobjects.com/zos/rmsportal/hfYFfCvHTQTUKntlJbMF.svg" width="100" />](https://segmentfault.com/t/antd)(中文)

View File

@ -5,9 +5,9 @@ order: 2
title: 在 Umi 中使用 title: 在 Umi 中使用
--- ---
在真实项目开发中,除了 Ant Design 这样的 UI 库你可能会还会需要构建工具、路由方案、CSS 方案、数据流方案、请求库和请求方案、国际化方案、权限方案、Icons 方案等等,才能完成一个完整的项目。我们基于业务场景的场景,推出了基于 React 的企业级应用框架 [Umi](https://umijs.org/),推荐你在项目中使用。 在真实项目开发中,除了 Ant Design 这样的 UI 库你可能会还会需要构建工具、路由方案、CSS 方案、数据流方案、请求库和请求方案、国际化方案、权限方案、Icons 方案等等,才能完成一个完整的项目。我们基于业务场景,推出了基于 React 的企业级应用框架 [Umi](https://umijs.org/),推荐你在项目中使用。
Umi中文发音为「乌米」是可扩展的企业级前端应用框架也是蚂蚁集团的底层前端框架已直接或间接地服务了 10000+ 应用。Umi 以路由为基础,同时支持配置式路由和约定式路由,保证路由的功能完备,并以此进行功能扩展。然后配以生命周期完善的插件体系,覆盖从源码到构建产物的每个生命周期,支持各种功能扩展和业务需求。 Umi中文发音为「乌米」是可扩展的企业级前端应用框架也是蚂蚁集团的底层前端框架已直接或间接地服务了 10000+ 应用。Umi 以路由为基础,同时支持配置式路由和约定式路由,保证路由的功能完备,并以此进行功能扩展。然后配以生命周期完善的插件体系,覆盖从源码到构建产物的每个生命周期,支持各种功能扩展和业务需求。
本文会引导你使用 Umi、Ant Design 和 [Ant Design Pro](https://pro.ant.design/) 从 0 开始创建一个简单应用。 本文会引导你使用 Umi、Ant Design 和 [Ant Design Pro](https://pro.ant.design/) 从 0 开始创建一个简单应用。
@ -20,7 +20,7 @@ $ mkdir myapp && cd myapp
$ pnpm create umi $ pnpm create umi
``` ```
> 如果你使用 npm可执行  `npm create umi`,效果一致;如果你使用 yarn可执行  `yarn create umi`,效果也一致;如果你使用 bun那说明你是个非常潮的人可执行 `bunx create-umi`注意create 和 umi 之间有个 `-`)。 > 如果你使用 npm可执行  `npm create umi`,效果一致;如果你使用 yarn可执行  `yarn create umi`,效果也一致;如果你使用 bun那说明你是个非常潮的人可执行 `bunx create-umi`(注意,`create``umi` 之间有个 `-`)。
这里选「Simple App」因为我们要从 “0” 开始。 这里选「Simple App」因为我们要从 “0” 开始。
@ -50,7 +50,7 @@ $ pnpm create umi
taobao taobao
``` ```
然后工具会自动安装依赖,并执行 umi 的初始化脚本。 然后工具会自动安装依赖,并执行 Umi 的初始化脚本。
在启动项目之前,我们再安装一些本教程会用到的依赖。 在启动项目之前,我们再安装一些本教程会用到的依赖。
@ -76,7 +76,7 @@ ready - ║ > Network: http://*********:8000 ║
╚════════════════════════════════════════════════════╝ ╚════════════════════════════════════════════════════╝
``` ```
跟着提示点击命令行里的 Url会自动打开浏览器。如果顺利你会看到如下界面。 跟着提示点击命令行里的 url会自动打开浏览器。如果顺利你会看到如下界面。
![](https://img.alicdn.com/imgextra/i2/O1CN01hWo9eO1ji9BZ1YHju_!!6000000004581-2-tps-774-928.png) ![](https://img.alicdn.com/imgextra/i2/O1CN01hWo9eO1ji9BZ1YHju_!!6000000004581-2-tps-774-928.png)
@ -126,13 +126,13 @@ export default defineConfig({
## 实现 Product UI 组件 ## 实现 Product UI 组件
随着应用的发展,你会需要在多个页面分享 UI 元素 (或在一个页面使用多次),在 Umi 里你可以把这部分抽成 component 。我们来编写一个 ProductList component,这样就能在不同的地方显示产品列表了。 随着应用的发展,你会需要在多个页面分享 UI 元素(或在一个页面使用多次),在 Umi 里你可以把这部分抽成 component 。我们来编写一个 ProductList 组件,这样就能在不同的地方显示产品列表了。
新建 `src/components/ProductList.tsx` 文件,内容如下。 新建 `src/components/ProductList.tsx` 文件,内容如下。
```tsx ```tsx
import { Button, Popconfirm, Table } from 'antd';
import React from 'react'; import React from 'react';
import { Button, Popconfirm, Table } from 'antd';
const ProductList: React.FC<{ products: { name: string }[]; onDelete: (id: string) => void }> = ({ const ProductList: React.FC<{ products: { name: string }[]; onDelete: (id: string) => void }> = ({
onDelete, onDelete,
@ -162,7 +162,7 @@ export default ProductList;
## 准备 Mock 数据 ## 准备 Mock 数据
假设我们已经和后端约定好了 API 接口,那现在就可以使用 Mock 数据来在本地模拟出 API 应该返回的数据,这样一来前后端开发就可以同时进行,不会因为后端 API 还在开发而导致前端的工作被阻塞。Umi 提供了开箱即用的 [Mock 功能](https://umijs.org/docs/guides/mock),能够用方便简单的方式来完成 Mock 数据的设置。 假设我们已经和后端约定好了 API 接口,那现在就可以使用 Mock 数据来在本地模拟出 API 应该返回的数据,这样一来前后端开发就可以同时进行,不会因为后端 API 还在开发而导致前端的工作被阻塞。Umi 提供了开箱即用的 [Mock 功能](https://umijs.org/docs/guides/mock),能够用方便简单的方式来完成 Mock 数据的设置。
创建 `mock` 目录,并在此目录下新增 `products.ts` 文件,内容如下。 创建 `mock` 目录,并在此目录下新增 `products.ts` 文件,内容如下。
@ -221,11 +221,12 @@ export default defineConfig({
再编辑 `src/pages/products.tsx`,内容如下。 再编辑 `src/pages/products.tsx`,内容如下。
```tsx ```tsx
import ProductList from '@/components/ProductList';
import axios from 'axios';
import React from 'react'; import React from 'react';
import axios from 'axios';
import { useMutation, useQuery, useQueryClient } from 'umi'; import { useMutation, useQuery, useQueryClient } from 'umi';
import styles from './products.less'; import styles from './products.less';
import ProductList from '@/components/ProductList';
export default function Page() { export default function Page() {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
@ -265,7 +266,7 @@ export default function Page() {
## ProLayout ## ProLayout
一个标准的中后台页面,一般都需要一个布局,这个布局很多时候都是高度雷同的,[ProLayout](https://procomponents.ant.design/components/layout/) 封装了常用的菜单,面包屑,页头等功能,提供了一个不依赖的框架且开箱即用的高级布局组件。并且支持  `side`, `mix`, `top`  三种模式,更是内置了菜单选中,菜单生成面包屑,自动设置页面标题的逻辑。 一个标准的中后台页面,一般都需要一个布局,这个布局很多时候都是高度雷同的,[ProLayout](https://procomponents.ant.design/components/layout/) 封装了常用的菜单、面包屑、页头等功能,提供了一个不依赖的框架且开箱即用的高级布局组件。并且支持  `side`, `mix`, `top`  三种模式,更是内置了菜单选中、菜单生成面包屑、自动设置页面标题的逻辑。
先修改配置,为每个路由新增 name 字段,用于给 ProLayout 做菜单渲染使用。 先修改配置,为每个路由新增 name 字段,用于给 ProLayout 做菜单渲染使用。
@ -321,9 +322,9 @@ export default function Layout() {
} }
``` ```
这里先用 umi 的 `useAppData` 拿到全局客户端路由 `clientRoutes`,这是一份嵌套结构的路由表,我们把 `clientRoutes[0]` 传给 ProLayout再通过 `useLocation()` 拿到 location 信息,也传给 ProLayout 来决定哪个菜单应该高亮;同时我们希望点击菜单时做路由跳转,需要定制 ProLayout 的 menuItemRender 方法。 这里先用 Umi 的 `useAppData` 拿到全局客户端路由 `clientRoutes`,这是一份嵌套结构的路由表,我们把 `clientRoutes[0]` 传给 ProLayout再通过 `useLocation()` 拿到 location 信息,也传给 ProLayout 来决定哪个菜单应该高亮;同时我们希望点击菜单时做路由跳转,需要定制 ProLayout 的 `menuItemRender` 方法。
聪明的你可能已经发现 `src/layouts/index.less` 已经没地方引用他了,为了保持项目文件的整洁,可以选择删掉他 聪明的你可能已经发现 `src/layouts/index.less` 已经不再被引用了。为了保持项目文件的整洁,可以选择将其删除
此时浏览器会自动刷新,如果顺利,你会看到如下界面。 此时浏览器会自动刷新,如果顺利,你会看到如下界面。
@ -348,14 +349,14 @@ info - File sizes after gzip:
event - Build index.html event - Build index.html
``` ```
构建会打包所有的资源,包含 JavaScript, CSS, Web Fonts, 图片, Html 等。你可以在  `dist/`  目录下找到这些文件。 构建会打包所有的资源,包含 JavaScript, CSS, Web Fonts, 图片, HTML 等。你可以在  `dist/`  目录下找到这些文件。
## 下一步 ## 下一步
我们已经完成了一个简单应用,你可能还有很多疑问,比如: 我们已经完成了一个简单应用,你可能还有很多疑问,比如:
- 如何统一处理出错? - 如何统一处理出错?
- 如何处理更多路由,比如动态路由,嵌套路由,权限路由等? - 如何处理更多路由,比如动态路由、嵌套路由、权限路由等?
- 如何使用数据流方案? - 如何使用数据流方案?
- 如何修改 webpack 配置或切换到 vite 构建模式? - 如何修改 webpack 配置或切换到 vite 构建模式?
- 等等 - 等等

View File

@ -49,7 +49,7 @@ title: 按钮
常规按钮类型呈现出不同的**强调程度**,使用者可以据此变化出合适的按钮类型: 常规按钮类型呈现出不同的**强调程度**,使用者可以据此变化出合适的按钮类型:
### Do&Don't ### Do & Don't
<ImagePreview> <ImagePreview>
<img class="preview-img no-padding bad" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*di8jS5EWYSIAAAAAAAAAAABkARQnAQ" alt="错误示范" description="不要在一个按钮区放置超过一个主按钮。"> <img class="preview-img no-padding bad" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*di8jS5EWYSIAAAAAAAAAAABkARQnAQ" alt="错误示范" description="不要在一个按钮区放置超过一个主按钮。">
@ -201,7 +201,7 @@ title: 按钮
<img class="preview-img no-padding" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*x7YsTafH5osAAAAAAAAAAABkARQnAQ"> <img class="preview-img no-padding" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*x7YsTafH5osAAAAAAAAAAABkARQnAQ">
</ImagePreview> </ImagePreview>
**按主次折叠部分按钮** **按主次折叠部分按钮**
<br /> <br />

View File

@ -70,8 +70,8 @@ title: 文案
<img class="preview-img no-padding" src="https://gw.alipayobjects.com/zos/rmsportal/sNqQYWEJCAzCxcYCBGYD.png" alt="操作名称和目标页面的标题一致。"> <img class="preview-img no-padding" src="https://gw.alipayobjects.com/zos/rmsportal/sNqQYWEJCAzCxcYCBGYD.png" alt="操作名称和目标页面的标题一致。">
</ImagePreview> </ImagePreview>
- 描述同一个事物的词汇要保持统一; - 描述同一个事物的词汇要保持统一
- 上下文的语法、语种、语序要保持统一; - 上下文的语法、语种、语序要保持统一
- 操作的名称和目标页面标题的名称保持一致。 - 操作的名称和目标页面标题的名称保持一致。
### 重要的信息放在显著位置 ### 重要的信息放在显著位置
@ -85,7 +85,7 @@ title: 文案
> 注:如考虑安全性问题时,隐私信息也可调整为「点击后可见」的方式。 > 注:如考虑安全性问题时,隐私信息也可调整为「点击后可见」的方式。
### 完整、直接阐述信息 ### 完整、直接阐述信息
<ImagePreview> <ImagePreview>
<img class="preview-img no-padding good" src="https://gw.alipayobjects.com/zos/rmsportal/ioBKvBqCNzUwQDyjMiIa.png" alt="正确示范" description="用户可以从中了解了设置后会有什么好处。"> <img class="preview-img no-padding good" src="https://gw.alipayobjects.com/zos/rmsportal/ioBKvBqCNzUwQDyjMiIa.png" alt="正确示范" description="用户可以从中了解了设置后会有什么好处。">
@ -192,7 +192,7 @@ title: 文案
<ImagePreview> <ImagePreview>
<img class="preview-img no-padding good" src="https://gw.alipayobjects.com/zos/rmsportal/SiyDiAnuljqDrZgcFiXn.png" alt="正确示范" description="引导用户正确输入内容。"> <img class="preview-img no-padding good" src="https://gw.alipayobjects.com/zos/rmsportal/SiyDiAnuljqDrZgcFiXn.png" alt="正确示范" description="引导用户正确输入内容。">
<img class="preview-img no-padding bad" src="https://gw.alipayobjects.com/zos/rmsportal/ZSgEJWJJeOYBDDsenOuS.png" alt="错误示范" description="不能、不要、请勿都给人命令或强迫的感觉。"> <img class="preview-img no-padding bad" src="https://gw.alipayobjects.com/zos/rmsportal/ZSgEJWJJeOYBDDsenOuS.png" alt="错误示范" description="不能不要请勿都给人命令或强迫的感觉。">
</ImagePreview> </ImagePreview>
多给用户支持与鼓励,不要命令和强迫用户。 多给用户支持与鼓励,不要命令和强迫用户。

View File

@ -79,7 +79,7 @@ title: 数据格式
| 格式 | 如何使用及何时使用 | 例子 | | 格式 | 如何使用及何时使用 | 例子 |
| --- | --- | --- | | --- | --- | --- |
| 年、月、日 | 中国默认使用 `yyyy-mm-dd` 格式。([其它国家参考链接)](https://zh.wikipedia.org/wiki/%E5%90%84%E5%9C%B0%E6%97%A5%E6%9C%9F%E5%92%8C%E6%97%B6%E9%97%B4%E8%A1%A8%E7%A4%BA%E6%B3%95)。 | 2019-12-08 | | 年、月、日 | 中国默认使用 `yyyy-mm-dd` 格式。([其它国家参考链接)](https://zh.wikipedia.org/wiki/%E5%90%84%E5%9C%B0%E6%97%A5%E6%9C%9F%E5%92%8C%E6%97%B6%E9%97%B4%E8%A1%A8%E7%A4%BA%E6%B3%95)。 | 2019-12-08 |
| 专用名词 | 含有月日的专用名词采用阿拉伯数字表示时,应采用间隔号 `·` 将月、日分开,并在数字前后加引号。 | 6.1 儿童节 | | 专用名词 | 含有月日的专用名词采用阿拉伯数字表示时,应采用间隔号 `·` 将月、日分开,并在数字前后加引号。 | “6·1” 儿童节 |
| 日期范围 | 在日期或时间范围之间显示一个波浪号 (前后需要空格)。 | 2018-12-08 2019-12-07 | | 日期范围 | 在日期或时间范围之间显示一个波浪号 (前后需要空格)。 | 2018-12-08 2019-12-07 |
**时间格式**:默认使用二十四小时制: **时间格式**:默认使用二十四小时制:

View File

@ -5,7 +5,7 @@ order: 3
title: 详情页 title: 详情页
--- ---
详情页向用户展示一个对象的完整信息,主要用信息浏览,允许对该对象发起编辑等操作。 详情页向用户展示一个对象的完整信息,主要用信息浏览,允许对该对象发起编辑等操作。
--- ---
@ -59,7 +59,7 @@ title: 详情页
**什么时候使用** **什么时候使用**
需要展示内容量少复杂度低的信息。 需要展示内容量少复杂度低的信息。
#### 模板 - 单据详情 #### 模板 - 单据详情
@ -97,7 +97,7 @@ title: 详情页
**什么时候使用** **什么时候使用**
当详情页内容量大复杂度高时,不得不拆分为多个页签,作为辅助导航引导用户浏览信息。 当详情页内容量大复杂度高时,不得不拆分为多个页签,作为辅助导航引导用户浏览信息。
#### 模板 - 发布流程 #### 模板 - 发布流程
@ -127,7 +127,7 @@ title: 详情页
<img class="preview-img no-padding" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*3jPZSa8n2g4AAAAAAAAAAABkARQnAQ"> <img class="preview-img no-padding" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*3jPZSa8n2g4AAAAAAAAAAABkARQnAQ">
</ImagePreview> </ImagePreview>
根据各个信息之间的相关性,判断各个信息模块之间的亲密度通常情况下,相关性强的内容尽量靠近,相关性弱的的内容尽量拉开层次。 根据各个信息之间的相关性,判断各个信息模块之间的亲密度通常情况下,相关性强的内容尽量靠近,相关性弱的的内容尽量拉开层次。
- 不通栏分割线:将相关内容分开; - 不通栏分割线:将相关内容分开;
- 通栏分割线:将内容分成多个部分; - 通栏分割线:将内容分成多个部分;

View File

@ -5,7 +5,7 @@ order: 5
title: 直截了当 title: 直截了当
--- ---
正如 Alan Cooper 所言:「需要在哪里输出,就要允许在哪里输入」。这就是直接操作的原理。eg:不要为了编辑内容而打开另一个页面,应该直接在上下文中实现编辑。 正如 Alan Cooper 所言:「需要在哪里输出,就要允许在哪里输入」。这就是直接操作的原理。例如:不要为了编辑内容而打开另一个页面,应该直接在上下文中实现编辑。
--- ---

View File

@ -6,7 +6,7 @@ title: 图标
图标是 UI 设计中必不可少的组成。通常我们理解图标设计的含义是将某个概念转换成清晰易读的图形从而降低用户的理解成本提升界面的美观度。在我们的企业级应用设计范围中图标在界面设计的诸多元素中往往只占了很小的比重在调用时也会被缩到比设计稿小很多倍的尺寸加上在图形素材极度丰富并且便于获取的今天在产品设计体系中实现一套美观、一致、易用、便于延展的图标体系往往会被不小心忽略掉。Ant Design 相信一整套优质的图标对于设计质量的影响是非常巨大的,这考验着设计师的协作能力,以及对图形塑造的系统性思维,同时也能反映一个团队对于细节的追求。 图标是 UI 设计中必不可少的组成。通常我们理解图标设计的含义是将某个概念转换成清晰易读的图形从而降低用户的理解成本提升界面的美观度。在我们的企业级应用设计范围中图标在界面设计的诸多元素中往往只占了很小的比重在调用时也会被缩到比设计稿小很多倍的尺寸加上在图形素材极度丰富并且便于获取的今天在产品设计体系中实现一套美观、一致、易用、便于延展的图标体系往往会被不小心忽略掉。Ant Design 相信一整套优质的图标对于设计质量的影响是非常巨大的,这考验着设计师的协作能力,以及对图形塑造的系统性思维,同时也能反映一个团队对于细节的追求。
Ant Design 在"确定"和"自然"的设计价值观影响之下,对全套的基础系统图标进行了改造,现在大家可以在我们网站上直接查看并使用新版的图标,同时在这里将我们的系统性思路分享给大家,抛砖引玉,期待有更多的设计师参与到这个寂寞的微观世界中来,一起把图形设计这件事做好。 Ant Design 在「确定」和「自然」的设计价值观影响之下,对全套的基础系统图标进行了改造,现在大家可以在我们网站上直接查看并使用新版的图标,同时在这里将我们的系统性思路分享给大家,抛砖引玉,期待有更多的设计师参与到这个寂寞的微观世界中来,一起把图形设计这件事做好。
[查看图标库](/components/icon-cn) [查看图标库](/components/icon-cn)
@ -18,7 +18,7 @@ Ant Design 在"确定"和"自然"的设计价值观影响之下,对全套的
## 设计原则 ## 设计原则
Ant Design 的图标设计原则源自"确定"和"自然",落实到图标设计领域,一共有四个,他们分别为: Ant Design 的图标设计原则源自「确定」和「自然」,落实到图标设计领域,一共有四个,他们分别为:
- **准确:** 设计造型准确的图标(保持偶数原则,去小数点);选择表意准确的图标,不对用户的认知造成困扰。 - **准确:** 设计造型准确的图标(保持偶数原则,去小数点);选择表意准确的图标,不对用户的认知造成困扰。
- **简单:** 在表意清晰准确的基础上,尽量保持图形的简洁,不做多余的修饰。 - **简单:** 在表意清晰准确的基础上,尽量保持图形的简洁,不做多余的修饰。
@ -57,7 +57,7 @@ Ant Design 的图标设计对于设计稿的分层也有一定的要求,其目
## 图标设计指引 ## 图标设计指引
根据"确定性"和"自然"的价值观当构图含义明确之后图标设计所追求的便是秩序之美。Ant Design 的图标主要通过四方面去实现"秩序美",分别是:形式、韵律、平衡以及辨识。 根据「确定性」和「自然」的价值观当构图含义明确之后图标设计所追求的便是秩序之美。Ant Design 的图标主要通过四方面去实现「秩序美」,分别是:形式、韵律、平衡以及辨识。
### 1、形式 ### 1、形式
@ -91,7 +91,7 @@ Ant Design 图标的韵律感通过两个方面来体现:元素的韵律和构
<img class="preview-img no-padding" src="https://gw.alipayobjects.com/zos/rmsportal/EycXTskdagLPlYMTvfdC.png" alt="圆角"> <img class="preview-img no-padding" src="https://gw.alipayobjects.com/zos/rmsportal/EycXTskdagLPlYMTvfdC.png" alt="圆角">
</div> </div>
- **三角:** 新版图标的角度受到美式战斗机 F-14 tomcat 的启发,将常用的角度定在约 76 度。在日常设计中,多数系统图标的角度都可以从 76 度这个数值出发,根据实际情况进行灵活的应用。 - **三角:** 新版图标的角度受到美式战斗机 F-14 Tomcat 的启发,将常用的角度定在约 76 度。在日常设计中,多数系统图标的角度都可以从 76 度这个数值出发,根据实际情况进行灵活的应用。
<div> <div>
<img class="preview-img no-padding" src="https://gw.alipayobjects.com/zos/rmsportal/WWnwBEQKIOhIeqbsIHZe.png" alt="三角"> <img class="preview-img no-padding" src="https://gw.alipayobjects.com/zos/rmsportal/WWnwBEQKIOhIeqbsIHZe.png" alt="三角">
@ -154,7 +154,7 @@ Ant Design 图标的韵律感通过两个方面来体现:元素的韵律和构
### 4、辨识 ### 4、辨识
辨识度是一套图标具备的可被感知的特色通常和系统本身的品牌基因相关。Ant Design 的系统图标在这一次除了遵循"确定"和"自然"这两块价值观,在辨识度这一块也做了两处小尝试。 辨识度是一套图标具备的可被感知的特色通常和系统本身的品牌基因相关。Ant Design 的系统图标在这一次除了遵循「确定」和「自然」这两块价值观,在辨识度这一块也做了两处小尝试。
- **让科技有温度:** 通过对于图形圆角的定义将过于圆润的圆角72调整至32在视觉效果上令图标看起来更为坚硬和理性对应科技感但又不至于太过尖锐有温度 - **让科技有温度:** 通过对于图形圆角的定义将过于圆润的圆角72调整至32在视觉效果上令图标看起来更为坚硬和理性对应科技感但又不至于太过尖锐有温度
@ -198,4 +198,4 @@ Ant Design 图标的韵律感通过两个方面来体现:元素的韵律和构
## 写在最后 ## 写在最后
图标的设计是 UI 设计中非常容易被忽略的环节,建立优秀的图形体系也不是一、二个设计人员的事,需要整个团队在设计前、设计中以及设计后都能够达成共识并且通力合作去完成共建。本次图标的升级,仅仅是一个开始。我们建议在调用图标时,考虑具体业务对于图形化寄予的期望,以及用户操作时的心智模型等因素,结合实际情况做调用和适当的二次设计。 图标的设计是 UI 设计中非常容易被忽略的环节,建立优秀的图形体系也不是一个设计人员的事,需要整个团队在设计前、设计中以及设计后都能够达成共识并且通力合作去完成共建。本次图标的升级,仅仅是一个开始。我们建议在调用图标时,考虑具体业务对于图形化寄予的期望,以及用户操作时的心智模型等因素,结合实际情况做调用和适当的二次设计。

View File

@ -9,7 +9,7 @@ title: 图形化
## 项目背景 ## 项目背景
图形化是品牌识别度的关键核心元素,在互联网产品,线下物料中使用中无处不在。与单纯的文案信息不同,图形化在直观描述固有信息的同时塑造情感背景,使用户更具沉浸感和共情性。提升产品用户体验的同时来完成商业目标。图形化的风格缤纷复杂,插画师的个人风格明显,不同的设计师在图形化的工作协同中,风格很难复现,而单纯由一名插画师去完成整体业务的图形化也存在一定风险。所以图形化体系在保持品牌一致性和提升工作效率规避风险上显得尤为重要。 图形化是品牌识别度的关键核心元素,在互联网产品、线下物料中无处不在。与单纯的文案信息不同,图形化在直观描述固有信息的同时塑造情感背景,使用户更具沉浸感和共情性。提升产品用户体验的同时来完成商业目标。图形化的风格缤纷复杂,插画师的个人风格明显,不同的设计师在图形化的工作协同中,风格很难复现,而单纯由一名插画师去完成整体业务的图形化也存在一定风险。所以图形化体系在保持品牌一致性和提升工作效率规避风险上显得尤为重要。
<div style="text-align:center;"> <div style="text-align:center;">
<img alt="Background" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*rSUBTL8hv9sAAAAAAAAAAABkARQnAQ" /> <img alt="Background" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*rSUBTL8hv9sAAAAAAAAAAABkARQnAQ" />
@ -17,7 +17,7 @@ title: 图形化
## 设计原则 ## 设计原则
从最底层的设计价值观到最层的设计方法HiTu 沿袭了 Ant Design 的 ETCG 的设计思路,将图形化资产组件化,分可形成模板,合则可拼搭成案例。为设计值提供强大的灵活性和定制性。 从最底层的设计价值观到最层的设计方法HiTu 沿袭了 Ant Design 的 ETCG 的设计思路,将图形化资产组件化,分可形成模板,合则可拼搭成案例。为设计值提供强大的灵活性和定制性。
<div style="text-align:center;"> <div style="text-align:center;">
<img alt="Design principle" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*WKEzS5-_zYAAAAAAAAAAAABkARQnAQ" /> <img alt="Design principle" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*WKEzS5-_zYAAAAAAAAAAAABkARQnAQ" />
@ -25,7 +25,7 @@ title: 图形化
#### HiTu 金字塔模型 #### HiTu 金字塔模型
基于科技,确定,自然,未来的四层品牌策略,我们将抽象的概念具象化。代表的技术底层的科技能力为产品体验和未来提供技术支撑和可能性。所以图例一一对应,我们具象化了人物和产品,体验及未来之间的关系。他们之间不同的组合方式可以满足不同的业务场景诉求。 基于科技、确定、自然、未来的四层品牌策略,我们将抽象的概念具象化。代表的技术底层的科技能力为产品体验和未来提供技术支撑和可能性。所以图例一一对应,我们具象化了人物和产品,体验及未来之间的关系。他们之间不同的组合方式可以满足不同的业务场景诉求。
<div style="text-align:center;"> <div style="text-align:center;">
<img alt="Pyramid model" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*gCoSS5DaCNEAAAAAAAAAAABkARQnAQ" /> <img alt="Pyramid model" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*gCoSS5DaCNEAAAAAAAAAAABkARQnAQ" />
@ -47,7 +47,7 @@ title: 图形化
<img class="preview-img no-padding" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*0Dv9Rrp7GtMAAAAAAAAAAAAAARQnAQ" /> <img class="preview-img no-padding" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*0Dv9Rrp7GtMAAAAAAAAAAAAAARQnAQ" />
</ImagePreview> </ImagePreview>
通过搜资调研,我们发现在企业级产品中。色彩的使用上蓝色,白色会占很大的比重。我们选取了色板中最具科技感,且代表着探索钻研感的极客蓝作为我们的主色。 通过搜资调研,我们发现在企业级产品中。色彩的使用上蓝色,白色会占很大的比重。我们选取了色板中最具科技感,且代表着探索钻研感的极客蓝作为我们的主色。
<br /> <br />
@ -67,7 +67,7 @@ title: 图形化
<img class="preview-img" alt="基于自然的人物头身比例" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*rm9JRIqTmPgAAAAAAAAAAABkARQnAQ" /> <img class="preview-img" alt="基于自然的人物头身比例" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*rm9JRIqTmPgAAAAAAAAAAABkARQnAQ" />
</ImagePreview> </ImagePreview>
基于自然的设计原则,我们不推荐使用 Q 版卡通和过于夸张艺术化的设计风格。相比之下,接近自然真人头人比例的风格更是我们所推荐的。 基于自然的设计原则,我们不推荐使用 Q 版卡通和过于夸张艺术化的设计风格。相比之下,接近自然真人头人比例的风格是我们更加推荐的。
<br /> <br />
@ -105,7 +105,7 @@ title: 图形化
<img class="preview-img" alt="根据业务场景设计的元素组件" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*Z8oxS5ym3PIAAAAAAAAAAABkARQnAQ" /> <img class="preview-img" alt="根据业务场景设计的元素组件" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*Z8oxS5ym3PIAAAAAAAAAAABkARQnAQ" />
</ImagePreview> </ImagePreview>
记忆点源于与众不同,专业感源于整齐划一。元素组件指代的是业务场景中一些业务元素,状态元素图形化的世界缤纷多变,我们希望在保持统一性的同时不去限设计者的创意空间,元素组件的设计上,我们为了保持一定的韵律感,推荐设计师在 1024\*1024 的网格中绘制组件,且圆角的大小保持 8 的倍数关系。 记忆点源于与众不同,专业感源于整齐划一。元素组件指代的是业务场景中一些业务元素,状态元素图形化的世界缤纷多变,我们希望在保持统一性的同时不去限设计者的创意空间,元素组件的设计上,我们为了保持一定的韵律感,推荐设计师在 1024\*1024 的网格中绘制组件,且圆角的大小保持 8 的倍数关系。
<br /> <br />

View File

@ -10,7 +10,7 @@ title: 介绍
<img src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*P0S-QIRUbsUAAAAAAAAAAABkARQnAQ"> <img src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*P0S-QIRUbsUAAAAAAAAAAABkARQnAQ">
</div> </div>
蚂蚁集团的企业级产品是一个庞大且复杂的系统,数量多且功能复杂,而且变动和并发频繁,常常需要设计者与开发者能快速做出响应。同时这类产品中存在很多类似的页面以及组件,可以通过抽象得到一些稳定且高复用性的内容。 蚂蚁集团的企业级产品是一个庞大且复杂的系统,数量多且功能复杂,而且变动和并发频繁,常常需要设计者与开发者能快速做出响应。同时这类产品中存在很多类似的页面以及组件,我们可以通过抽象得到一些稳定且高复用性的内容。
随着商业化的趋势,越来越多的企业级产品对更好的用户体验有了进一步的要求。带着这样的一个终极目标,我们(蚂蚁集团体验技术部)经过大量项目实践和总结,逐步打磨出一个服务于企业级产品的设计体系 —— Ant Design。基于「自然」、「确定性」、「意义感」、「生长性」四大[设计价值观](/docs/spec/values),通过模块化解决方案,降低冗余的生产成本,让设计者专注于更好的用户体验。 随着商业化的趋势,越来越多的企业级产品对更好的用户体验有了进一步的要求。带着这样的一个终极目标,我们(蚂蚁集团体验技术部)经过大量项目实践和总结,逐步打磨出一个服务于企业级产品的设计体系 —— Ant Design。基于「自然」、「确定性」、「意义感」、「生长性」四大[设计价值观](/docs/spec/values),通过模块化解决方案,降低冗余的生产成本,让设计者专注于更好的用户体验。

View File

@ -5,11 +5,11 @@ order: 8
title: 提供邀请 title: 提供邀请
--- ---
很多富交互模式(eg:「拖放」、「行内编辑」、「上下文工具」)都有一个共同问题,就是缺少易发现性。所以「提供邀请」是成功完成人机交互的关键所在。 很多富交互模式(例如:「拖放」、「行内编辑」、「上下文工具」)都有一个共同问题,就是缺少易发现性。所以「提供邀请」是成功完成人机交互的关键所在。
邀请就是引导用户进入下一个交互层次的提醒和暗示,通常包括意符(eg实时的提示信息和可供性以表明在下一个界面可以做什么。当可供性中可感知的部分Perceived Affordance表现为意符时人机交互的过程往往更加自然、顺畅。 邀请就是引导用户进入下一个交互层次的提醒和暗示,通常包括意符(例如实时的提示信息和可供性以表明在下一个界面可以做什么。当可供性中可感知的部分Perceived Affordance表现为意符时人机交互的过程往往更加自然、顺畅。
> **意符Signifiers**:一种额外的提示,告诉用户可以采取什么行为,以及应该怎么操作;必须是可感知(eg:视觉、听觉、触觉等)。——摘自《设计心理学 1 》 > **意符Signifiers**:一种额外的提示,告诉用户可以采取什么行为,以及应该怎么操作;必须是可感知(例如:视觉、听觉、触觉等)。——摘自《设计心理学 1 》
> **可供性Affordance**:也被翻译成「示能」,由 James J. Gibson 提出,定义为物品的特性与决定物品用途的主体能力之间的关系;其中部分可感知(此部分定义为 Perceived Affordance部分不可感知。——摘自《设计心理学 1 》 > **可供性Affordance**:也被翻译成「示能」,由 James J. Gibson 提出,定义为物品的特性与决定物品用途的主体能力之间的关系;其中部分可感知(此部分定义为 Perceived Affordance部分不可感知。——摘自《设计心理学 1 》

View File

@ -5,9 +5,9 @@ order: 7
title: 简化交互 title: 简化交互
--- ---
根据费茨法则Fitts's Law所描述的,如果用户鼠标移动距离越少、对象相对目标越大,那么用户越容易操作。通过运用上下文工具(即:放在内容中的操作工具),使内容和操作融合,从而简化交互。 根据费茨法则Fitts's Law,用户鼠标移动距离越短、对象相对目标越大,用户越容易操作。通过运用上下文工具(即:放在内容中的操作工具),使内容和操作融合,从而简化交互。
> **费茨法则** :到达目标的时间是到达目标的距离与目标大小的函数,具体:<img src="https://os.alipayobjects.com/rmsportal/wAcbQmeqTWDqsnu.png" width="150" />其中1.设备当前位置和目标位置的距离D2.目标的大小W。距离越长,所用时间越长;目标越大,所用时间越短。 > **费茨法则** :到达目标的时间是到达目标的距离与目标大小的函数,具体:<img src="https://os.alipayobjects.com/rmsportal/wAcbQmeqTWDqsnu.png" width="150" />其中1. D 为设备当前位置和目标位置的距离2. W 为目标的大小。距离越长,所用时间越长;目标越大,所用时间越短。
--- ---
@ -59,6 +59,6 @@ title: 简化交互
<img class="preview-img" alt="按钮热区示例" description="鼠标移入按钮附近,即可激活 Hover 状态。" src="https://gw.alipayobjects.com/zos/rmsportal/BlUnqNCHsgUnhnRjMTnX.png"> <img class="preview-img" alt="按钮热区示例" description="鼠标移入按钮附近,即可激活 Hover 状态。" src="https://gw.alipayobjects.com/zos/rmsportal/BlUnqNCHsgUnhnRjMTnX.png">
</ImagePreview> </ImagePreview>
当需要增强按钮的响应性时,可以通过增加用户点击热区的范围,而不是增大按钮形状,从而增强响应性,又不缺失美感。 当需要增强按钮的响应性时,可以通过增加用户点击热区的范围,而不是增大按钮形状,来增强响应性,又不降低美感。
> 注:在移动端尤其适用。 > 注:在移动端尤其适用。

View File

@ -36,7 +36,7 @@ const text = [
{ {
title: '自然', title: '自然',
img: 'https://gw.alipayobjects.com/zos/rmsportal/LyTPSGknLUlxiVdwMWyu.gif', img: 'https://gw.alipayobjects.com/zos/rmsportal/LyTPSGknLUlxiVdwMWyu.gif',
content: '自然运动规律,保证视觉连,让用户感知到动作是成立的', content: '自然运动规律,保证视觉连,让用户感知到动作是成立的',
}, },
{ {
title: '高效', title: '高效',
@ -46,12 +46,12 @@ const text = [
{ {
title: '克制', title: '克制',
img: 'https://gw.alipayobjects.com/zos/rmsportal/OkIXkscKxywYLSrilPIf.gif', img: 'https://gw.alipayobjects.com/zos/rmsportal/OkIXkscKxywYLSrilPIf.gif',
content: '做有意义的动效,不去做太多的修饰干扰用户', content: '做有意义的动效,不去做太多的修饰干扰用户',
}, },
]; ];
function Principle() { function Principle() {
const childrenToRender = text.map(item => ( const childrenToRender = text.map((item) => (
<Col key={item.title} sm={24} md={8}> <Col key={item.title} sm={24} md={8}>
<div className="principle"> <div className="principle">
<div> <div>
@ -76,7 +76,7 @@ export default Principle;
### 自然 ### 自然
自然的动效背后体现的是自然运动规律。这就要求动效在转换时保证视觉上的连性,让用户感知到这个动作是成立的,是能够引起共鸣的。 自然的动效背后体现的是自然运动规律。这就要求动效在转换时保证视觉上的连性,让用户感知到这个动作是成立的,是能够引起共鸣的。
<video class="motion-video-min" src="https://gw.alipayobjects.com/os/rmsportal/NTMlQdLIkPjOACXsdRrq.mp4" loop="true"></video> <video class="motion-video-min" src="https://gw.alipayobjects.com/os/rmsportal/NTMlQdLIkPjOACXsdRrq.mp4" loop="true"></video>

View File

@ -31,6 +31,6 @@ title: 概览
我们与工程师合作,将设计模式转化为可重用的代码,最大限度地提高您的生产力和沟通效率。 我们与工程师合作,将设计模式转化为可重用的代码,最大限度地提高您的生产力和沟通效率。
- [Ant Design Pro](https://pro.ant.design/):具有 20 多个模板和 10 多个业务组件的开箱即用解决方案 - [Ant Design Pro](https://pro.ant.design/):具有 20 多个模板和 10 多个业务组件的开箱即用解决方案
- [React 官方实现](/components/overview-cn)Ant Design 的 React UI 库拥有 60 多个基础组件。 - [React 官方实现](/components/overview-cn)Ant Design 的 React UI 库拥有 60 多个基础组件。
- [Axure 设计库](http://library.ant.design/):代码中包含 Axure 资源包,使您的原型看起来像一个视觉草稿,包括模板、组件等。 - [Axure 设计库](http://library.ant.design/):代码中包含 Axure 资源包,使您的原型看起来像一个视觉草稿,包括模板、组件等。

View File

@ -34,7 +34,7 @@ title: 空状态
</div> </div>
</div> </div>
### Do&Dont ### Do & Dont
<ImagePreview> <ImagePreview>
<img class="preview-img no-padding good" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*Bh_yRKPOByUAAAAAAAAAAABkARQnAQ" alt="正确示范" description="展示明确空状态提示。"> <img class="preview-img no-padding good" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*Bh_yRKPOByUAAAAAAAAAAABkARQnAQ" alt="正确示范" description="展示明确空状态提示。">
@ -51,7 +51,7 @@ title: 空状态
<img class="preview-img no-padding" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*UyVCTaiJ3icAAAAAAAAAAABkARQnAQ"> <img class="preview-img no-padding" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*UyVCTaiJ3icAAAAAAAAAAABkARQnAQ">
</ImagePreview> </ImagePreview>
一般来说,新用户希望空状态具有帮助说明和推荐操作。首次使用应用或功能场景的空状态非常有用,因为它向用户展示了该功能和流程,并且可以帮助用户快速上手。为了帮助首次使用新用户,空状态可以使用功能引导、帮助文档等方式填充原本为空的页面。 一般来说,新用户希望空状态具有帮助说明和推荐操作。首次使用应用或功能场景的空状态非常有用,因为它向用户展示了该功能和流程,并且可以帮助用户快速上手。为了帮助首次使用新用户,空状态可以使用功能引导、帮助文档等方式填充原本为空的页面。
#### 使用引导变形 #### 使用引导变形

View File

@ -39,9 +39,9 @@ title: 表单页
</div> </div>
</div> </div>
### Do&Dont ### Do & Dont
在表单页中组织呈现各表单项时要注意简洁表达高效准确,避免增加用户录入信息的成本。 在表单页中组织呈现各表单项时要注意简洁表达高效准确,避免增加用户录入信息的成本。
<ImagePreview> <ImagePreview>
<img class="preview-img no-padding bad" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*k9DyRYLzjcoAAAAAAAAAAABkARQnAQ" alt="错误示范" /> <img class="preview-img no-padding bad" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*k9DyRYLzjcoAAAAAAAAAAABkARQnAQ" alt="错误示范" />

View File

@ -11,7 +11,7 @@ title: 列表页
## 设计目标 ## 设计目标
帮助用户更高效查看、处理、查找条目。 帮助用户更高效查看、处理、查找条目。
## 设计原则 ## 设计原则
@ -42,7 +42,7 @@ title: 列表页
<img class="preview-img no-padding" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*c0iNQIBusPMAAAAAAAAAAABkARQnAQ"> <img class="preview-img no-padding" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*c0iNQIBusPMAAAAAAAAAAABkARQnAQ">
</ImagePreview> </ImagePreview>
从上往下堆叠,数据过滤模块在最上方,过滤数据后,用户再由总体到具体的浏览逻辑理解和分析。 从上往下堆叠,数据过滤模块在最上方,过滤数据后,用户再由总体到具体的浏览逻辑理解和分析。
#### 双栏布局 #### 双栏布局
@ -60,7 +60,7 @@ title: 列表页
**什么时候使用** **什么时候使用**
条条目需要都需要露出很多字段;用户在搜寻条目时有准确的查询范围时使用。 个条目都需要露出很多字段;用户在搜寻条目时有准确的查询范围时使用。
#### 模版 - 标准列表 #### 模版 - 标准列表
@ -70,7 +70,7 @@ title: 列表页
**什么时候使用** **什么时候使用**
提供每条目的概览信息,点击列表可导航至条目详情。页面内常提供统计功能,供用户了解总体进展。可作为简易版的工作台使用。 提供每条目的概览信息,点击列表可导航至条目详情。页面内常提供统计功能,供用户了解总体进展。可作为简易版的工作台使用。
#### [模板 - 卡片列表](https://preview.pro.ant.design/list/card-list) #### [模板 - 卡片列表](https://preview.pro.ant.design/list/card-list)

View File

@ -178,7 +178,7 @@ title: 导航
> 此处的数据库是一种信息架构形式,各页面内容独立,但都遵循一致的形式/格式。 > 此处的数据库是一种信息架构形式,各页面内容独立,但都遵循一致的形式/格式。
<ImagePreview> <ImagePreview>
<img class="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*jYG0T7S-SjsAAAAAAAAAAABkARQnAQ"> <img class="preview-img no-padding" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*jYG0T7S-SjsAAAAAAAAAAABkARQnAQ">
</ImagePreview> </ImagePreview>
#### 沉浸式导航 #### 沉浸式导航

View File

@ -9,7 +9,7 @@ title: 结果页
## 何时使用 ## 何时使用
当完成一个流程操作后,需给用户明确的结果反馈时,例如分步表单的最后一步。<br/> 当有大量的信息需要在结果页展示时。 当完成一个流程操作后,需给用户明确的结果反馈时,例如分步表单的最后一步。<br/> 当有大量的信息需要在结果页展示时。
## 设计目标 ## 设计目标

View File

@ -20,7 +20,7 @@ title: 阴影
<img class="preview-img no-padding" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*li3zQbxRuOMAAAAAAAAAAABkARQnAQ" alt="高度"> <img class="preview-img no-padding" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*li3zQbxRuOMAAAAAAAAAAABkARQnAQ" alt="高度">
</div> </div>
**第 1 层**: 物体位于低层级,此时物体被操作(悬停、点击等)触发为悬浮状态,当操作完成或取消时,悬停状态反馈也跟随消失,物体回归到原有的层级中,如:卡片 hover 等; **第 1 层**: 物体位于低层级,此时物体被操作(悬停、点击等)触发为悬浮状态,当操作完成或取消时,悬停状态反馈也跟随消失,物体回归到原有的层级中,如:卡片 hover 等;
<div> <div>
<img class="preview-img no-padding" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*mXnoSI8MWuEAAAAAAAAAAABkARQnAQ" alt="高度"> <img class="preview-img no-padding" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*mXnoSI8MWuEAAAAAAAAAAABkARQnAQ" alt="高度">
@ -61,7 +61,7 @@ title: 阴影
- 阴影向左:主要应用于右边导航栏、抽屉组件或固定表格栏 - 阴影向左:主要应用于右边导航栏、抽屉组件或固定表格栏
- 阴影向右:主要应用于左边导航栏、抽屉组件或固定表格栏 - 阴影向右:主要应用于左边导航栏、抽屉组件或固定表格栏
阴影是模拟的真实世界的反馈Ant Design 为了更符合真实阴影,在 4.0 中采用了三层阴影的表达方式,让阴影更柔和,更符合真实状态 阴影是模拟的真实世界的反馈Ant Design 为了更符合真实阴影,在 4.0 中采用了三层阴影的表达方式,让阴影更柔和,更符合真实状态
<div> <div>
<img class="preview-img no-padding" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*1oijTJh2HEIAAAAAAAAAAABkARQnAQ" alt="阴影值"> <img class="preview-img no-padding" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*1oijTJh2HEIAAAAAAAAAAABkARQnAQ" alt="阴影值">

View File

@ -5,10 +5,10 @@ order: 9
title: 巧用过渡 title: 巧用过渡
--- ---
人脑灰质Gray Matter会对动态的事物eg移动、形变、色变等保持敏感。在界面中适当的加入一些过渡效果,能让界面保持生动,同时也能增强用户和界面的沟通。 人脑灰质Gray Matter会对动态的事物例如:移动、形变、色变等)保持敏感。在界面中,适当地加入一些过渡效果,能让界面保持生动,同时也能增强用户和界面的沟通。
- Adding: 新加入的信息元素应被告知如何使用,从页面转变的信息元素需被重新识别。 - Adding: 新加入的信息元素应被告知如何使用,从页面转变的信息元素需被重新识别。
- Receding:  与当前页无关的信息元素应采用适当方式移除。 - Receding: 与当前页无关的信息元素应采用适当方式移除。
- Normal: 指那些从转场开始到结束都没有发生变化的信息元素。 - Normal: 指那些从转场开始到结束都没有发生变化的信息元素。
--- ---

View File

@ -34,7 +34,7 @@ Ant Design 设计价值观为设计者提供评价设计好坏的内在标准,
界面是用户与系统交互的媒介,是手段而非目的。在追求「自然」交互基础上,通过 Ant Design 创造的产品界面应是高确定性、低合作熵的状态。 界面是用户与系统交互的媒介,是手段而非目的。在追求「自然」交互基础上,通过 Ant Design 创造的产品界面应是高确定性、低合作熵的状态。
- **设计者确定**:企业级产品都是分工合作的产物,参与者越多合作熵越高,这是一切设计工作低效、产品系统不易维护的来源。通过探索设计规律、模块化设计思路,来为设计者提供足够精简的设计规则、组件、模式等,赋能设计者、降低合作熵。 - **设计者确定**:企业级产品都是分工合作的产物,参与者越多合作熵越高,这是一切设计工作低效、产品系统不易维护的来源。通过探索设计规律、模块化设计思路,来为设计者提供足够精简的设计规则、组件、模式等,赋能设计者、降低合作熵。
- 保持克制: 能做,但想清楚了不做。设计者应当聚焦在最有价值产品功能打磨,并用尽可能少的设计元素将其表达。正如 Antoine de St.Exupery 所说:完美不在于无以复加,而在于无可删减,万事莫不如此。 - 保持克制: 能做,但想清楚了不做。设计者应当聚焦在最有价值产品功能打磨,并用尽可能少的设计元素将其表达。正如 Antoine de Saint-Exupéry 所说:完美不在于无以复加,而在于无可删减,万事莫不如此。
- 面向对象的方法: 探索设计规律,并将其抽象成「对象」,增强界面设计的灵活性和可维护性,同时也减少「设计者」的主观干扰,从而降低系统的不确定性。例如:色值换算、间距排版。 - 面向对象的方法: 探索设计规律,并将其抽象成「对象」,增强界面设计的灵活性和可维护性,同时也减少「设计者」的主观干扰,从而降低系统的不确定性。例如:色值换算、间距排版。
- 模块化设计: 将复杂或者重复出现的局部封装成模块,提供有限接口与其他模块互动,最终全面减少系统的复杂度,进而增进可靠性以及可维护性。设计者可运用现有的组件/模板或者自行抽象可复用的组件/模板,节约无谓的设计且保持系统一致性,让「设计者」把创造力专注在最需要的地方。 - 模块化设计: 将复杂或者重复出现的局部封装成模块,提供有限接口与其他模块互动,最终全面减少系统的复杂度,进而增进可靠性以及可维护性。设计者可运用现有的组件/模板或者自行抽象可复用的组件/模板,节约无谓的设计且保持系统一致性,让「设计者」把创造力专注在最需要的地方。
- **用户确定**:用户日常工作是通过诸多企业级产品的协同来完成的,除了考虑单一产品的设计一致性,更应当在跨产品、跨终端、跨系统间保持良好的确定性。一致的外观和交互,保持面向用户的熟悉感,能提升易学性,降低认知和操作成本,提升工作效率。 - **用户确定**:用户日常工作是通过诸多企业级产品的协同来完成的,除了考虑单一产品的设计一致性,更应当在跨产品、跨终端、跨系统间保持良好的确定性。一致的外观和交互,保持面向用户的熟悉感,能提升易学性,降低认知和操作成本,提升工作效率。
@ -45,7 +45,7 @@ Ant Design 设计价值观为设计者提供评价设计好坏的内在标准,
<img src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*xOYlR4e8ihIAAAAAAAAAAABkARQnAQ" alt="意义感" /> <img src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*xOYlR4e8ihIAAAAAAAAAAABkARQnAQ" alt="意义感" />
</div> </div>
一个产品或功能被设计者创造出来不只是用户的需要,而更多是承载用户的某个工作使命。产品设计应充分站在工作视角,促成用户使命的达成;同时,在「自然」、「确定」之上,兼顾用户的人性需求,为工作过程创造富有意义感的人机交互。 一个产品或功能被设计者创造出来不只是出于用户的需要,而更多是承载用户的某个工作使命。产品设计应充分站在工作视角,促成用户使命的达成;同时,在「自然」、「确定」之上,兼顾用户的人性需求,为工作过程创造富有意义感的人机交互。
- **结果的意义:明确目标,即时反馈**。洞悉工作目标,根据使用流程拆解明确的子目标,让每个交互行为都围绕着主目标的达成;为每个行为,辅以恰当、即时的反馈,让用户对操作结果了然于胸。此外,可通过情感化设计,适度安抚用户负面情感,强化用户正面情感。 - **结果的意义:明确目标,即时反馈**。洞悉工作目标,根据使用流程拆解明确的子目标,让每个交互行为都围绕着主目标的达成;为每个行为,辅以恰当、即时的反馈,让用户对操作结果了然于胸。此外,可通过情感化设计,适度安抚用户负面情感,强化用户正面情感。
- **过程的意义:挑战适中,全情投入**。调整不同场景下的工作难度,让功能适时适地触发,以匹配用户能力;如无必要,勿增实体,不分散用户注意力,让用户专注于任务达成,而非界面。让当下的工作既不过于简单,亦不过于复杂,挑战适中,并随着用户能力的成长提出更高的挑战,能让用户持续沉浸在工作的心流中,获得富有成就感的工作体验。 - **过程的意义:挑战适中,全情投入**。调整不同场景下的工作难度,让功能适时适地触发,以匹配用户能力;如无必要,勿增实体,不分散用户注意力,让用户专注于任务达成,而非界面。让当下的工作既不过于简单,亦不过于复杂,挑战适中,并随着用户能力的成长提出更高的挑战,能让用户持续沉浸在工作的心流中,获得富有成就感的工作体验。
@ -58,5 +58,5 @@ Ant Design 设计价值观为设计者提供评价设计好坏的内在标准,
企业级产品功能的增长与用户系统角色的演变相生相伴。设计者应为自己创造的产品负责,提升功能、价值的可发现性。用发展的眼光做设计,充分考虑人、机两端的共同生长。 企业级产品功能的增长与用户系统角色的演变相生相伴。设计者应为自己创造的产品负责,提升功能、价值的可发现性。用发展的眼光做设计,充分考虑人、机两端的共同生长。
- **价值连接**:产品的增长依赖于用户的群体扩大和深度使用,而用户的成长又依赖于产品功能的壮大。设计者应建立系统设计思维,洞悉产品功能的价值,探索用户在不同场景下的需求,在价值和需求间建立连接。让产品价值被发现,帮助用户建立更有效、更高效的工作方式。 - **价值连接**:产品的增长依赖于用户的群体扩大和深度使用,而用户的成长又依赖于产品功能的完善。设计者应建立系统设计思维,洞悉产品功能的价值,探索用户在不同场景下的需求,在价值和需求间建立连接。让产品价值被发现,帮助用户建立更有效、更高效的工作方式。
- **人机共生**:产品功能和用户需求的更多连接,让人机互动更加紧密,用户和系统共生。产品设计时,不应将用户和系统独立开来,应作为一个动态发展的共同体来思考,确保其足够的灵活、包容,充满生命力。 - **人机共生**:产品功能和用户需求的更多连接,让人机互动更加紧密,用户和系统共生。在进行产品设计时,不应将用户和系统独立开来,将两者作为一个动态发展的共同体来思考,确保其足够的灵活、包容,充满生命力。

View File

@ -22,12 +22,12 @@ title: 可视化
### 了解用户 ### 了解用户
用户是谁他们要从可视化作品上获取什么信息在企业级产品中用户可能是公司高层、BI 分析师、运营、数据开发等不同角色,不一样的角色在使用可视化作品时,其目的以及使用路径会有所不同。建议在设计开始前对使用者进行充分剖析,以便完整地讲述你的数据故事,准确呈现你的数据见解。 用户是谁他们要从可视化作品上获取什么信息在企业级产品中用户可能是公司高层、BI 分析师、运营、数据开发等不同角色。不同角色在使用可视化作品时,其目的以及使用路径会有所不同。建议在设计开始前对使用者进行充分剖析,以便完整地讲述你的数据故事,准确呈现你的数据见解。
### 设计原则 ### 设计原则
- 准确:从数据转化到可视表达时不歪曲,不误导,不遗漏,忠实反映数据里包含的信息; - 准确:从数据转化到可视表达时不歪曲、不误导、不遗漏,忠实反映数据里包含的信息;
- 有效:信息传达有重点,克制不冗余,避免信息过载,用最适量的数据-油墨比Data-ink Ratio表达对用户最有用的信息 - 有效:信息传达有重点,克制不冗余,避免信息过载,用最适量的数据-油墨比Data-ink Ratio表达对用户最有用的信息
- 清晰:表现方式清楚易读,具条理性,可以帮助用户快速达成目标,在最少的时间内获取更多的信息; - 清晰:表现方式清楚易读,具条理性,可以帮助用户快速达成目标,在最少的时间内获取更多的信息;
- 美:对数据的完美表达,合理利用视觉元素进行艺术创作,不过度修饰,给用户优雅的体验。 - 美:对数据的完美表达,合理利用视觉元素进行艺术创作,不过度修饰,给用户优雅的体验。
@ -35,7 +35,7 @@ title: 可视化
### 选择正确的图表类型 ### 选择正确的图表类型
我们提供了完整的图表用法说明,帮助您更正确地选择图表类型。 我们提供了完整的图表用法说明,帮助您更合理地选择图表类型。
#### 时间类 #### 时间类
@ -167,7 +167,7 @@ AntV 提供了一套默认的图表颜色,包括颜色的用法,
区别于传统数据报表相对静态的表现形式,交互式图表并不停留在信息展示层面。用户通过与图不断产生交互,从数据中获取更深层次的分析和信息。 区别于传统数据报表相对静态的表现形式,交互式图表并不停留在信息展示层面。用户通过与图不断产生交互,从数据中获取更深层次的分析和信息。
在数据可视化中,我们根据用户的意识层次及每层次对应的目标,将交互动作拆解成“数据获取、信息加工、知识流转”三层。其匹配“概览第一,聚焦过滤,再按需查看详情”的可视化信息检索箴言。亦符合人类寻求信息的基本逻辑:先大体,再局部,然后聚焦兴趣点进行探索,这是一个由表及里的过程。 在数据可视化中,我们根据用户的意识层次及每层次对应的目标,将交互动作拆解成「数据获取」、「信息加工」、「知识流转」三层。其匹配「概览第一,聚焦过滤,再按需查看详情」的可视化信息检索箴言。亦符合人类寻求信息的基本逻辑:先大体,再局部,然后聚焦兴趣点进行探索,这是一个由表及里的过程。
更多交互式图表内容请前往 [AntV -- 设计语言 -- 交互](https://antv.vision/zh/docs/specification/language/interact) 更多交互式图表内容请前往 [AntV -- 设计语言 -- 交互](https://antv.vision/zh/docs/specification/language/interact)

View File

@ -9,7 +9,7 @@ title: 数据可视化页
## 设计目标 ## 设计目标
让使用者快速、清晰地理解数据意义,快速进行分析趋势,驱动决策。 让使用者快速、清晰地理解数据意义,快速分析趋势,驱动决策。
--- ---
@ -39,7 +39,7 @@ title: 数据可视化页
</div> </div>
</div> </div>
### Do&Dont ### Do & Dont
<ImagePreview> <ImagePreview>
<img class="preview-img no-padding good" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*D4AHQ434LjgAAAAAAAAAAABkARQnAQ" alt="正确示范"> <img class="preview-img no-padding good" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*D4AHQ434LjgAAAAAAAAAAABkARQnAQ" alt="正确示范">
@ -62,7 +62,7 @@ title: 数据可视化页
<img class="preview-img no-padding good" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*Ym8CSoOMN1EAAAAAAAAAAABkARQnAQ" alt="正确示范"> <img class="preview-img no-padding good" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*Ym8CSoOMN1EAAAAAAAAAAABkARQnAQ" alt="正确示范">
</ImagePreview> </ImagePreview>
善于使用筛选、过滤功能,可以让用户在观察全局的同时,还可以查看数据细节,用户在有疑问时能够快速得到方向。 善于使用筛选、过滤功能,让用户在观察全局的同时,还可以查看数据细节,从而让用户在有疑问时能够快速找到方向。
## 典型模板 ## 典型模板

View File

@ -164,7 +164,7 @@
"@ant-design/happy-work-theme": "^1.0.0", "@ant-design/happy-work-theme": "^1.0.0",
"@ant-design/tools": "^17.3.2", "@ant-design/tools": "^17.3.2",
"@antv/g6": "^4.8.13", "@antv/g6": "^4.8.13",
"@argos-ci/core": "^0.12.0", "@argos-ci/core": "^1.0.0",
"@babel/eslint-plugin": "^7.19.1", "@babel/eslint-plugin": "^7.19.1",
"@biomejs/biome": "^1.0.0", "@biomejs/biome": "^1.0.0",
"@codesandbox/sandpack-react": "^2.9.0", "@codesandbox/sandpack-react": "^2.9.0",
@ -176,7 +176,7 @@
"@emotion/server": "^11.4.0", "@emotion/server": "^11.4.0",
"@ianvs/prettier-plugin-sort-imports": "^4.1.0", "@ianvs/prettier-plugin-sort-imports": "^4.1.0",
"@qixian.cs/github-contributors-list": "^1.1.0", "@qixian.cs/github-contributors-list": "^1.1.0",
"@size-limit/file": "^9.0.0", "@size-limit/file": "^10.0.0",
"@stackblitz/sdk": "^1.3.0", "@stackblitz/sdk": "^1.3.0",
"@testing-library/dom": "^9.0.0", "@testing-library/dom": "^9.0.0",
"@testing-library/jest-dom": "^6.0.0", "@testing-library/jest-dom": "^6.0.0",
@ -199,7 +199,7 @@
"@types/prismjs": "^1.26.0", "@types/prismjs": "^1.26.0",
"@types/progress": "^2.0.5", "@types/progress": "^2.0.5",
"@types/qs": "^6.9.7", "@types/qs": "^6.9.7",
"@types/react": "18.2.31", "@types/react": "18.2.33",
"@types/react-copy-to-clipboard": "^5.0.0", "@types/react-copy-to-clipboard": "^5.0.0",
"@types/react-dom": "^18.0.0", "@types/react-dom": "^18.0.0",
"@types/react-highlight-words": "^0.16.4", "@types/react-highlight-words": "^0.16.4",
@ -296,7 +296,7 @@
"runes2": "^1.1.2", "runes2": "^1.1.2",
"semver": "^7.3.5", "semver": "^7.3.5",
"simple-git": "^3.0.0", "simple-git": "^3.0.0",
"size-limit": "^9.0.0", "size-limit": "^10.0.0",
"stylelint": "^15.1.0", "stylelint": "^15.1.0",
"stylelint-config-rational-order": "^0.1.2", "stylelint-config-rational-order": "^0.1.2",
"stylelint-config-standard": "^34.0.0", "stylelint-config-standard": "^34.0.0",