初始化 antd-pro

This commit is contained in:
sin
2019-02-27 11:06:55 +08:00
parent 9f4fdb7f6e
commit b2068ae44b
458 changed files with 28090 additions and 2 deletions

View File

@@ -0,0 +1,25 @@
import React from 'react';
import { Tooltip, Icon } from 'antd';
import style from './index.less';
const BlockChecbox = ({ value, onChange, list }) => (
<div className={style.blockChecbox} key={value}>
{list.map(item => (
<Tooltip title={item.title} key={item.key}>
<div className={style.item} onClick={() => onChange(item.key)}>
<img src={item.url} alt={item.key} />
<div
className={style.selectIcon}
style={{
display: value === item.key ? 'block' : 'none',
}}
>
<Icon type="check" />
</div>
</div>
</Tooltip>
))}
</div>
);
export default BlockChecbox;

View File

@@ -0,0 +1,74 @@
import React from 'react';
import { Tooltip, Icon } from 'antd';
import { formatMessage } from 'umi/locale';
import styles from './ThemeColor.less';
const Tag = ({ color, check, ...rest }) => (
<div
{...rest}
style={{
backgroundColor: color,
}}
>
{check ? <Icon type="check" /> : ''}
</div>
);
const ThemeColor = ({ colors, title, value, onChange }) => {
let colorList = colors;
if (!colors) {
colorList = [
{
key: 'dust',
color: '#F5222D',
},
{
key: 'volcano',
color: '#FA541C',
},
{
key: 'sunset',
color: '#FAAD14',
},
{
key: 'cyan',
color: '#13C2C2',
},
{
key: 'green',
color: '#52C41A',
},
{
key: 'daybreak',
color: '#1890FF',
},
{
key: 'geekblue',
color: '#2F54EB',
},
{
key: 'purple',
color: '#722ED1',
},
];
}
return (
<div className={styles.themeColor}>
<h3 className={styles.title}>{title}</h3>
<div className={styles.content}>
{colorList.map(({ key, color }) => (
<Tooltip key={color} title={formatMessage({ id: `app.setting.themecolor.${key}` })}>
<Tag
className={styles.colorBlock}
color={color}
check={value === color}
onClick={() => onChange && onChange(color)}
/>
</Tooltip>
))}
</div>
</div>
);
};
export default ThemeColor;

View File

@@ -0,0 +1,21 @@
.themeColor {
margin-top: 24px;
overflow: hidden;
.title {
margin-bottom: 12px;
color: rgba(0, 0, 0, 0.65);
font-size: 14px;
line-height: 22px;
}
.colorBlock {
float: left;
width: 20px;
height: 20px;
margin-right: 8px;
color: #fff;
font-weight: bold;
text-align: center;
border-radius: 2px;
cursor: pointer;
}
}

View File

@@ -0,0 +1,253 @@
import React, { PureComponent } from 'react';
import { Select, message, Drawer, List, Switch, Divider, Icon, Button, Alert, Tooltip } from 'antd';
import { formatMessage } from 'umi/locale';
import { CopyToClipboard } from 'react-copy-to-clipboard';
import { connect } from 'dva';
import omit from 'omit.js';
import styles from './index.less';
import ThemeColor from './ThemeColor';
import BlockCheckbox from './BlockCheckbox';
const { Option } = Select;
const Body = ({ children, title, style }) => (
<div
style={{
...style,
marginBottom: 24,
}}
>
<h3 className={styles.title}>{title}</h3>
{children}
</div>
);
@connect(({ setting }) => ({ setting }))
class SettingDrawer extends PureComponent {
state = {
collapse: false,
};
getLayoutSetting = () => {
const {
setting: { contentWidth, fixedHeader, layout, autoHideHeader, fixSiderbar },
} = this.props;
return [
{
title: formatMessage({ id: 'app.setting.content-width' }),
action: (
<Select
value={contentWidth}
size="small"
onSelect={value => this.changeSetting('contentWidth', value)}
style={{ width: 80 }}
>
{layout === 'sidemenu' ? null : (
<Option value="Fixed">
{formatMessage({ id: 'app.setting.content-width.fixed' })}
</Option>
)}
<Option value="Fluid">
{formatMessage({ id: 'app.setting.content-width.fluid' })}
</Option>
</Select>
),
},
{
title: formatMessage({ id: 'app.setting.fixedheader' }),
action: (
<Switch
size="small"
checked={!!fixedHeader}
onChange={checked => this.changeSetting('fixedHeader', checked)}
/>
),
},
{
title: formatMessage({ id: 'app.setting.hideheader' }),
disabled: !fixedHeader,
disabledReason: formatMessage({ id: 'app.setting.hideheader.hint' }),
action: (
<Switch
size="small"
checked={!!autoHideHeader}
onChange={checked => this.changeSetting('autoHideHeader', checked)}
/>
),
},
{
title: formatMessage({ id: 'app.setting.fixedsidebar' }),
disabled: layout === 'topmenu',
disabledReason: formatMessage({ id: 'app.setting.fixedsidebar.hint' }),
action: (
<Switch
size="small"
checked={!!fixSiderbar}
onChange={checked => this.changeSetting('fixSiderbar', checked)}
/>
),
},
];
};
changeSetting = (key, value) => {
const { setting } = this.props;
const nextState = { ...setting };
nextState[key] = value;
if (key === 'layout') {
nextState.contentWidth = value === 'topmenu' ? 'Fixed' : 'Fluid';
} else if (key === 'fixedHeader' && !value) {
nextState.autoHideHeader = false;
}
this.setState(nextState, () => {
const { dispatch } = this.props;
dispatch({
type: 'setting/changeSetting',
payload: this.state,
});
});
};
togglerContent = () => {
const { collapse } = this.state;
this.setState({ collapse: !collapse });
};
renderLayoutSettingItem = item => {
const action = React.cloneElement(item.action, {
disabled: item.disabled,
});
return (
<Tooltip title={item.disabled ? item.disabledReason : ''} placement="left">
<List.Item actions={[action]}>
<span style={{ opacity: item.disabled ? '0.5' : '' }}>{item.title}</span>
</List.Item>
</Tooltip>
);
};
render() {
const { setting } = this.props;
const { navTheme, primaryColor, layout, colorWeak } = setting;
const { collapse } = this.state;
return (
<Drawer
visible={collapse}
width={300}
onClose={this.togglerContent}
placement="right"
handler={
<div className={styles.handle} onClick={this.togglerContent}>
<Icon
type={collapse ? 'close' : 'setting'}
style={{
color: '#fff',
fontSize: 20,
}}
/>
</div>
}
style={{
zIndex: 999,
}}
>
<div className={styles.content}>
<Body title={formatMessage({ id: 'app.setting.pagestyle' })}>
<BlockCheckbox
list={[
{
key: 'dark',
url: 'https://gw.alipayobjects.com/zos/rmsportal/LCkqqYNmvBEbokSDscrm.svg',
title: formatMessage({ id: 'app.setting.pagestyle.dark' }),
},
{
key: 'light',
url: 'https://gw.alipayobjects.com/zos/rmsportal/jpRkZQMyYRryryPNtyIC.svg',
title: formatMessage({ id: 'app.setting.pagestyle.light' }),
},
]}
value={navTheme}
onChange={value => this.changeSetting('navTheme', value)}
/>
</Body>
<ThemeColor
title={formatMessage({ id: 'app.setting.themecolor' })}
value={primaryColor}
onChange={color => this.changeSetting('primaryColor', color)}
/>
<Divider />
<Body title={formatMessage({ id: 'app.setting.navigationmode' })}>
<BlockCheckbox
list={[
{
key: 'sidemenu',
url: 'https://gw.alipayobjects.com/zos/rmsportal/JopDzEhOqwOjeNTXkoje.svg',
title: formatMessage({ id: 'app.setting.sidemenu' }),
},
{
key: 'topmenu',
url: 'https://gw.alipayobjects.com/zos/rmsportal/KDNDBbriJhLwuqMoxcAr.svg',
title: formatMessage({ id: 'app.setting.topmenu' }),
},
]}
value={layout}
onChange={value => this.changeSetting('layout', value)}
/>
</Body>
<List
split={false}
dataSource={this.getLayoutSetting()}
renderItem={this.renderLayoutSettingItem}
/>
<Divider />
<Body title={formatMessage({ id: 'app.setting.othersettings' })}>
<List.Item
actions={[
<Switch
size="small"
checked={!!colorWeak}
onChange={checked => this.changeSetting('colorWeak', checked)}
/>,
]}
>
{formatMessage({ id: 'app.setting.weakmode' })}
</List.Item>
</Body>
<Divider />
<CopyToClipboard
text={JSON.stringify(omit(setting, ['colorWeak']), null, 2)}
onCopy={() => message.success(formatMessage({ id: 'app.setting.copyinfo' }))}
>
<Button block icon="copy">
{formatMessage({ id: 'app.setting.copy' })}
</Button>
</CopyToClipboard>
<Alert
type="warning"
className={styles.productionHint}
message={
<div>
{formatMessage({ id: 'app.setting.production.hint' })}{' '}
<a
href="https://u.ant.design/pro-v2-default-settings"
target="_blank"
rel="noopener noreferrer"
>
src/defaultSettings.js
</a>
</div>
}
/>
</div>
</Drawer>
);
}
}
export default SettingDrawer;

View File

@@ -0,0 +1,74 @@
@import '~antd/lib/style/themes/default.less';
.content {
position: relative;
min-height: 100%;
background: #fff;
}
.blockChecbox {
display: flex;
.item {
position: relative;
margin-right: 16px;
// box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1);
border-radius: @border-radius-base;
cursor: pointer;
img {
width: 48px;
}
}
.selectIcon {
position: absolute;
top: 0;
right: 0;
width: 100%;
height: 100%;
padding-top: 15px;
padding-left: 24px;
color: @primary-color;
font-weight: bold;
font-size: 14px;
}
}
.color_block {
display: inline-block;
width: 38px;
height: 22px;
margin: 4px;
margin-right: 12px;
vertical-align: middle;
border-radius: 4px;
cursor: pointer;
}
.title {
margin-bottom: 12px;
color: @heading-color;
font-size: 14px;
line-height: 22px;
}
.handle {
position: absolute;
top: 240px;
right: 300px;
z-index: 0;
display: flex;
justify-content: center;
align-items: center;
width: 48px;
height: 48px;
font-size: 16px;
text-align: center;
background: @primary-color;
border-radius: 4px 0 0 4px;
cursor: pointer;
pointer-events: auto;
}
.productionHint {
margin-top: 16px;
font-size: 12px;
}