mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-27 20:49:53 +08:00
commit
0b780574ae
@ -76,54 +76,46 @@ const items: MenuProps['items'] = [
|
||||
},
|
||||
];
|
||||
|
||||
class SiderDemo extends React.Component {
|
||||
state = {
|
||||
collapsed: true,
|
||||
export default () => {
|
||||
const [collapsed, setCollapsed] = React.useState(true);
|
||||
|
||||
const toggle = () => {
|
||||
setCollapsed(!collapsed);
|
||||
};
|
||||
|
||||
toggle = () => {
|
||||
this.setState({
|
||||
collapsed: !this.state.collapsed,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
return (
|
||||
<Layout>
|
||||
<Sider trigger={null} collapsible collapsed={collapsed}>
|
||||
<div className="logo" />
|
||||
<Menu
|
||||
theme="dark"
|
||||
mode="inline"
|
||||
defaultSelectedKeys={['3']}
|
||||
defaultOpenKeys={['sub1']}
|
||||
items={items}
|
||||
/>
|
||||
</Sider>
|
||||
<Layout>
|
||||
<Sider trigger={null} collapsible collapsed={this.state.collapsed}>
|
||||
<div className="logo" />
|
||||
<Menu
|
||||
theme="dark"
|
||||
mode="inline"
|
||||
defaultSelectedKeys={['3']}
|
||||
defaultOpenKeys={['sub1']}
|
||||
items={items}
|
||||
/>
|
||||
</Sider>
|
||||
<Layout>
|
||||
<Header className="site-layout-background" style={{ padding: 0 }}>
|
||||
{React.createElement(this.state.collapsed ? MenuUnfoldOutlined : MenuFoldOutlined, {
|
||||
className: 'trigger',
|
||||
onClick: this.toggle,
|
||||
})}
|
||||
</Header>
|
||||
<Content
|
||||
className="site-layout-background"
|
||||
style={{
|
||||
margin: '24px 16px',
|
||||
padding: 24,
|
||||
minHeight: 280,
|
||||
}}
|
||||
>
|
||||
Content
|
||||
</Content>
|
||||
</Layout>
|
||||
<Header className="site-layout-background" style={{ padding: 0 }}>
|
||||
{React.createElement(collapsed ? MenuUnfoldOutlined : MenuFoldOutlined, {
|
||||
className: 'trigger',
|
||||
onClick: toggle,
|
||||
})}
|
||||
</Header>
|
||||
<Content
|
||||
className="site-layout-background"
|
||||
style={{
|
||||
margin: '24px 16px',
|
||||
padding: 24,
|
||||
minHeight: 280,
|
||||
}}
|
||||
>
|
||||
Content
|
||||
</Content>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default () => <SiderDemo />;
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
```css
|
||||
|
@ -25,69 +25,61 @@ import {
|
||||
|
||||
const { Header, Sider, Content } = Layout;
|
||||
|
||||
class SiderDemo extends React.Component {
|
||||
state = {
|
||||
collapsed: false,
|
||||
export default () => {
|
||||
const [collapsed, setCollapsed] = React.useState(false);
|
||||
|
||||
const toggle = () => {
|
||||
setCollapsed(!collapsed);
|
||||
};
|
||||
|
||||
toggle = () => {
|
||||
this.setState({
|
||||
collapsed: !this.state.collapsed,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Layout>
|
||||
<Sider trigger={null} collapsible collapsed={this.state.collapsed}>
|
||||
<div className="logo" />
|
||||
<Menu
|
||||
theme="dark"
|
||||
mode="inline"
|
||||
defaultSelectedKeys={['1']}
|
||||
items={[
|
||||
{
|
||||
key: '1',
|
||||
icon: <UserOutlined />,
|
||||
label: 'nav 1',
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
icon: <VideoCameraOutlined />,
|
||||
label: 'nav 2',
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
icon: <UploadOutlined />,
|
||||
label: 'nav 3',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</Sider>
|
||||
<Layout className="site-layout">
|
||||
<Header className="site-layout-background" style={{ padding: 0 }}>
|
||||
{React.createElement(this.state.collapsed ? MenuUnfoldOutlined : MenuFoldOutlined, {
|
||||
className: 'trigger',
|
||||
onClick: this.toggle,
|
||||
})}
|
||||
</Header>
|
||||
<Content
|
||||
className="site-layout-background"
|
||||
style={{
|
||||
margin: '24px 16px',
|
||||
padding: 24,
|
||||
minHeight: 280,
|
||||
}}
|
||||
>
|
||||
Content
|
||||
</Content>
|
||||
</Layout>
|
||||
return (
|
||||
<Layout>
|
||||
<Sider trigger={null} collapsible collapsed={collapsed}>
|
||||
<div className="logo" />
|
||||
<Menu
|
||||
theme="dark"
|
||||
mode="inline"
|
||||
defaultSelectedKeys={['1']}
|
||||
items={[
|
||||
{
|
||||
key: '1',
|
||||
icon: <UserOutlined />,
|
||||
label: 'nav 1',
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
icon: <VideoCameraOutlined />,
|
||||
label: 'nav 2',
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
icon: <UploadOutlined />,
|
||||
label: 'nav 3',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</Sider>
|
||||
<Layout className="site-layout">
|
||||
<Header className="site-layout-background" style={{ padding: 0 }}>
|
||||
{React.createElement(collapsed ? MenuUnfoldOutlined : MenuFoldOutlined, {
|
||||
className: 'trigger',
|
||||
onClick: toggle,
|
||||
})}
|
||||
</Header>
|
||||
<Content
|
||||
className="site-layout-background"
|
||||
style={{
|
||||
margin: '24px 16px',
|
||||
padding: 24,
|
||||
minHeight: 280,
|
||||
}}
|
||||
>
|
||||
Content
|
||||
</Content>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default () => <SiderDemo />;
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
```css
|
||||
|
@ -63,43 +63,36 @@ const items: MenuItem[] = [
|
||||
getItem('Files', '9', <FileOutlined />),
|
||||
];
|
||||
|
||||
class SiderDemo extends React.Component {
|
||||
state = {
|
||||
collapsed: false,
|
||||
export default () => {
|
||||
const [collapsed, setCollapsed] = React.useState(false);
|
||||
|
||||
const onCollapse = (isCollapsed: boolean) => {
|
||||
console.log(isCollapsed);
|
||||
setCollapsed(isCollapsed);
|
||||
};
|
||||
|
||||
onCollapse = (collapsed: boolean) => {
|
||||
console.log(collapsed);
|
||||
this.setState({ collapsed });
|
||||
};
|
||||
|
||||
render() {
|
||||
const { collapsed } = this.state;
|
||||
return (
|
||||
<Layout style={{ minHeight: '100vh' }}>
|
||||
<Sider collapsible collapsed={collapsed} onCollapse={this.onCollapse}>
|
||||
<div className="logo" />
|
||||
<Menu theme="dark" defaultSelectedKeys={['1']} mode="inline" items={items} />
|
||||
</Sider>
|
||||
<Layout className="site-layout">
|
||||
<Header className="site-layout-background" style={{ padding: 0 }} />
|
||||
<Content style={{ margin: '0 16px' }}>
|
||||
<Breadcrumb style={{ margin: '16px 0' }}>
|
||||
<Breadcrumb.Item>User</Breadcrumb.Item>
|
||||
<Breadcrumb.Item>Bill</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
<div className="site-layout-background" style={{ padding: 24, minHeight: 360 }}>
|
||||
Bill is a cat.
|
||||
</div>
|
||||
</Content>
|
||||
<Footer style={{ textAlign: 'center' }}>Ant Design ©2018 Created by Ant UED</Footer>
|
||||
</Layout>
|
||||
return (
|
||||
<Layout style={{ minHeight: '100vh' }}>
|
||||
<Sider collapsible collapsed={collapsed} onCollapse={onCollapse}>
|
||||
<div className="logo" />
|
||||
<Menu theme="dark" defaultSelectedKeys={['1']} mode="inline" items={items} />
|
||||
</Sider>
|
||||
<Layout className="site-layout">
|
||||
<Header className="site-layout-background" style={{ padding: 0 }} />
|
||||
<Content style={{ margin: '0 16px' }}>
|
||||
<Breadcrumb style={{ margin: '16px 0' }}>
|
||||
<Breadcrumb.Item>User</Breadcrumb.Item>
|
||||
<Breadcrumb.Item>Bill</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
<div className="site-layout-background" style={{ padding: 24, minHeight: 360 }}>
|
||||
Bill is a cat.
|
||||
</div>
|
||||
</Content>
|
||||
<Footer style={{ textAlign: 'center' }}>Ant Design ©2018 Created by Ant UED</Footer>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default () => <SiderDemo />;
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
```css
|
||||
|
@ -14,101 +14,86 @@ title:
|
||||
Load more list with `loadMore` property.
|
||||
|
||||
```jsx
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { List, Avatar, Button, Skeleton } from 'antd';
|
||||
|
||||
const count = 3;
|
||||
const fakeDataUrl = `https://randomuser.me/api/?results=${count}&inc=name,gender,email,nat,picture&noinfo`;
|
||||
|
||||
class LoadMoreList extends React.Component {
|
||||
state = {
|
||||
initLoading: true,
|
||||
loading: false,
|
||||
data: [],
|
||||
list: [],
|
||||
};
|
||||
export default () => {
|
||||
const [initLoading, setInitLoading] = useState(true);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [data, setData] = useState([]);
|
||||
|
||||
componentDidMount() {
|
||||
useEffect(() => {
|
||||
fetch(fakeDataUrl)
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
this.setState({
|
||||
initLoading: false,
|
||||
data: res.results,
|
||||
list: res.results,
|
||||
});
|
||||
setInitLoading(false);
|
||||
setData(res.results);
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
onLoadMore = () => {
|
||||
this.setState({
|
||||
loading: true,
|
||||
list: this.state.data.concat(
|
||||
[...new Array(count)].map(() => ({ loading: true, name: {}, picture: {} })),
|
||||
),
|
||||
});
|
||||
fetch(fakeDataUrl)
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
const data = this.state.data.concat(res.results);
|
||||
this.setState(
|
||||
{
|
||||
data,
|
||||
list: data,
|
||||
loading: false,
|
||||
},
|
||||
() => {
|
||||
// Resetting window's offsetTop so as to display react-virtualized demo underfloor.
|
||||
// In real scene, you can using public method of react-virtualized:
|
||||
// https://stackoverflow.com/questions/46700726/how-to-use-public-method-updateposition-of-react-virtualized
|
||||
window.dispatchEvent(new Event('resize'));
|
||||
},
|
||||
);
|
||||
});
|
||||
};
|
||||
useEffect(() => {
|
||||
// Resetting window's offsetTop so as to display react-virtualized demo underfloor.
|
||||
// In real scene, you can using public method of react-virtualized:
|
||||
// https://stackoverflow.com/questions/46700726/how-to-use-public-method-updateposition-of-react-virtualized
|
||||
window.dispatchEvent(new Event('resize'));
|
||||
}, [JSON.stringify(data)]);
|
||||
|
||||
render() {
|
||||
const { initLoading, loading, list } = this.state;
|
||||
const loadMore =
|
||||
!initLoading && !loading ? (
|
||||
<div
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
marginTop: 12,
|
||||
height: 32,
|
||||
lineHeight: '32px',
|
||||
}}
|
||||
>
|
||||
<Button onClick={this.onLoadMore}>loading more</Button>
|
||||
</div>
|
||||
) : null;
|
||||
|
||||
return (
|
||||
<List
|
||||
className="demo-loadmore-list"
|
||||
loading={initLoading}
|
||||
itemLayout="horizontal"
|
||||
loadMore={loadMore}
|
||||
dataSource={list}
|
||||
renderItem={item => (
|
||||
<List.Item
|
||||
actions={[<a key="list-loadmore-edit">edit</a>, <a key="list-loadmore-more">more</a>]}
|
||||
>
|
||||
<Skeleton avatar title={false} loading={item.loading} active>
|
||||
<List.Item.Meta
|
||||
avatar={<Avatar src={item.picture.large} />}
|
||||
title={<a href="https://ant.design">{item.name.last}</a>}
|
||||
description="Ant Design, a design language for background applications, is refined by Ant UED Team"
|
||||
/>
|
||||
<div>content</div>
|
||||
</Skeleton>
|
||||
</List.Item>
|
||||
)}
|
||||
/>
|
||||
const onLoadMore = () => {
|
||||
setLoading(true);
|
||||
const newData = data.concat(
|
||||
[...new Array(count)].map(() => ({ loading: true, name: {}, picture: {} })),
|
||||
);
|
||||
}
|
||||
}
|
||||
setData(newData);
|
||||
|
||||
export default () => <LoadMoreList />;
|
||||
fetch(fakeDataUrl)
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
setLoading(false);
|
||||
setData(data.concat(res.results));
|
||||
});
|
||||
};
|
||||
|
||||
const loadMore =
|
||||
!initLoading && !loading ? (
|
||||
<div
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
marginTop: 12,
|
||||
height: 32,
|
||||
lineHeight: '32px',
|
||||
}}
|
||||
>
|
||||
<Button onClick={onLoadMore}>loading more</Button>
|
||||
</div>
|
||||
) : null;
|
||||
|
||||
return (
|
||||
<List
|
||||
className="demo-loadmore-list"
|
||||
loading={initLoading}
|
||||
itemLayout="horizontal"
|
||||
loadMore={loadMore}
|
||||
dataSource={data}
|
||||
renderItem={item => (
|
||||
<List.Item
|
||||
actions={[<a key="list-loadmore-edit">edit</a>, <a key="list-loadmore-more">more</a>]}
|
||||
>
|
||||
<Skeleton avatar title={false} loading={item.loading} active>
|
||||
<List.Item.Meta
|
||||
avatar={<Avatar src={item.picture.large} />}
|
||||
title={<a href="https://ant.design">{item.name.last}</a>}
|
||||
description="Ant Design, a design language for background applications, is refined by Ant UED Team"
|
||||
/>
|
||||
<div>content</div>
|
||||
</Skeleton>
|
||||
</List.Item>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
```css
|
||||
|
@ -14,68 +14,55 @@ title:
|
||||
async
|
||||
|
||||
```jsx
|
||||
import React, { useState, useRef, useMemo } from 'react';
|
||||
import { Mentions } from 'antd';
|
||||
import debounce from 'lodash/debounce';
|
||||
|
||||
const { Option } = Mentions;
|
||||
|
||||
class AsyncMention extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
export default () => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [users, setUsers] = useState([]);
|
||||
const searchRef = useRef();
|
||||
|
||||
this.loadGithubUsers = debounce(this.loadGithubUsers, 800);
|
||||
}
|
||||
const loadGithubUsers = useMemo(
|
||||
() =>
|
||||
debounce(key => {
|
||||
if (!key) {
|
||||
setUsers([]);
|
||||
return;
|
||||
}
|
||||
|
||||
state = {
|
||||
search: '',
|
||||
loading: false,
|
||||
users: [],
|
||||
};
|
||||
fetch(`https://api.github.com/search/users?q=${key}`)
|
||||
.then(res => res.json())
|
||||
.then(({ items = [] }) => {
|
||||
if (searchRef.current !== key) return;
|
||||
setLoading(false);
|
||||
setUsers(items.slice(0, 10));
|
||||
});
|
||||
}, 800),
|
||||
[],
|
||||
);
|
||||
|
||||
onSearch = search => {
|
||||
this.setState({ search, loading: !!search, users: [] });
|
||||
const onSearch = search => {
|
||||
setLoading(!!search);
|
||||
setUsers([]);
|
||||
searchRef.current = search;
|
||||
console.log('Search:', search);
|
||||
this.loadGithubUsers(search);
|
||||
loadGithubUsers(search);
|
||||
};
|
||||
|
||||
loadGithubUsers(key) {
|
||||
if (!key) {
|
||||
this.setState({
|
||||
users: [],
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
fetch(`https://api.github.com/search/users?q=${key}`)
|
||||
.then(res => res.json())
|
||||
.then(({ items = [] }) => {
|
||||
const { search } = this.state;
|
||||
if (search !== key) return;
|
||||
|
||||
this.setState({
|
||||
users: items.slice(0, 10),
|
||||
loading: false,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { users, loading } = this.state;
|
||||
|
||||
return (
|
||||
<Mentions style={{ width: '100%' }} loading={loading} onSearch={this.onSearch}>
|
||||
{users.map(({ login, avatar_url: avatar }) => (
|
||||
<Option key={login} value={login} className="antd-demo-dynamic-option">
|
||||
<img src={avatar} alt={login} />
|
||||
<span>{login}</span>
|
||||
</Option>
|
||||
))}
|
||||
</Mentions>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default () => <AsyncMention />;
|
||||
return (
|
||||
<Mentions style={{ width: '100%' }} loading={loading} onSearch={onSearch}>
|
||||
{users.map(({ login, avatar_url: avatar }) => (
|
||||
<Option key={login} value={login} className="antd-demo-dynamic-option">
|
||||
<img src={avatar} alt={login} />
|
||||
<span>{login}</span>
|
||||
</Option>
|
||||
))}
|
||||
</Mentions>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
<style>
|
||||
|
@ -23,34 +23,26 @@ const MOCK_DATA = {
|
||||
'#': ['1.0', '2.0', '3.0'],
|
||||
};
|
||||
|
||||
class App extends React.Component {
|
||||
state = {
|
||||
prefix: '@',
|
||||
export default () => {
|
||||
const [prefix, setPrefix] = React.useState('@');
|
||||
|
||||
const onSearch = (_, prefixValue) => {
|
||||
setPrefix(prefixValue);
|
||||
};
|
||||
|
||||
onSearch = (_, prefix) => {
|
||||
this.setState({ prefix });
|
||||
};
|
||||
|
||||
render() {
|
||||
const { prefix } = this.state;
|
||||
|
||||
return (
|
||||
<Mentions
|
||||
style={{ width: '100%' }}
|
||||
placeholder="input @ to mention people, # to mention tag"
|
||||
prefix={['@', '#']}
|
||||
onSearch={this.onSearch}
|
||||
>
|
||||
{(MOCK_DATA[prefix] || []).map(value => (
|
||||
<Option key={value} value={value}>
|
||||
{value}
|
||||
</Option>
|
||||
))}
|
||||
</Mentions>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default App;
|
||||
return (
|
||||
<Mentions
|
||||
style={{ width: '100%' }}
|
||||
placeholder="input @ to mention people, # to mention tag"
|
||||
prefix={['@', '#']}
|
||||
onSearch={onSearch}
|
||||
>
|
||||
{(MOCK_DATA[prefix] || []).map(value => (
|
||||
<Option key={value} value={value}>
|
||||
{value}
|
||||
</Option>
|
||||
))}
|
||||
</Mentions>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
@ -167,7 +167,7 @@ const PageHeader: React.FC<PageHeaderProps> = props => {
|
||||
const defaultBreadcrumbDom = getDefaultBreadcrumbDom();
|
||||
|
||||
const isBreadcrumbComponent = breadcrumb && 'props' in breadcrumb;
|
||||
// support breadcrumbRender function
|
||||
// support breadcrumbRender function
|
||||
const breadcrumbRenderDomFromProps =
|
||||
breadcrumbRender?.(props, defaultBreadcrumbDom) ?? defaultBreadcrumbDom;
|
||||
|
||||
|
@ -269,7 +269,7 @@
|
||||
@notification-padding-vertical: 12px;
|
||||
@notification-padding-horizontal: 16px;
|
||||
|
||||
// Result
|
||||
// Result
|
||||
// ---
|
||||
@result-title-font-size: 20px;
|
||||
@result-icon-font-size: 64px;
|
||||
|
@ -1053,7 +1053,7 @@
|
||||
@notification-padding-vertical: 16px;
|
||||
@notification-padding-horizontal: 24px;
|
||||
|
||||
// Result
|
||||
// Result
|
||||
// ---
|
||||
@result-title-font-size: 24px;
|
||||
@result-subtitle-font-size: @font-size-base;
|
||||
|
@ -1108,7 +1108,7 @@
|
||||
@notification-padding-vertical: 16px;
|
||||
@notification-padding-horizontal: 24px;
|
||||
|
||||
// Result
|
||||
// Result
|
||||
// ---
|
||||
@result-title-font-size: 24px;
|
||||
@result-subtitle-font-size: @font-size-base;
|
||||
|
@ -129,7 +129,8 @@
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
&-scrollbar {
|
||||
// https://github.com/ant-design/ant-design/issues/35577
|
||||
&-scrollbar:not([rowspan]) {
|
||||
box-shadow: 0 @border-width-base 0 @border-width-base @table-header-bg;
|
||||
}
|
||||
}
|
||||
|
@ -161,7 +161,7 @@
|
||||
"devDependencies": {
|
||||
"@ant-design/bisheng-plugin": "^3.2.0",
|
||||
"@ant-design/hitu": "^0.0.0-alpha.13",
|
||||
"@ant-design/tools": "^15.0.1",
|
||||
"@ant-design/tools": "^15.0.2",
|
||||
"@docsearch/css": "^3.0.0",
|
||||
"@qixian.cs/github-contributors-list": "^1.0.3",
|
||||
"@stackblitz/sdk": "^1.3.0",
|
||||
|
Loading…
Reference in New Issue
Block a user