Browse Source

new setting bar style

pull/1607/head
jim 8 years ago
parent
commit
78a2070bdd
  1. 2
      package.json
  2. 33
      src/components/SettingDarwer/BlockChecbox.js
  3. 52
      src/components/SettingDarwer/ThemeColor.js
  4. 21
      src/components/SettingDarwer/ThemeColor.less
  5. 187
      src/components/SettingDarwer/index.js
  6. 55
      src/components/SettingDarwer/index.less
  7. 23
      src/components/Sidebar/LayoutSetting.js
  8. 52
      src/components/Sidebar/ThemeColor.js
  9. 27
      src/components/Sidebar/ThemeColor.less
  10. 206
      src/components/Sidebar/index.js
  11. 26
      src/components/Sidebar/navState.js
  12. 4
      src/layouts/BasicLayout.js
  13. 2
      webpack.config.js

2
package.json

@ -78,7 +78,7 @@
"pro-download": "^1.0.1",
"redbox-react": "^1.5.0",
"regenerator-runtime": "^0.11.1",
"roadhog": "2.3.0",
"roadhog": "^2.4.2",
"roadhog-api-doc": "^1.0.3",
"stylelint": "^9.2.1",
"stylelint-config-prettier": "^3.0.4",

33
src/components/SettingDarwer/BlockChecbox.js

@ -0,0 +1,33 @@
import { Icon } from 'antd';
import React from 'react';
import style from './index.less';
const BlockChecbox = ({ value, onChange, list }) => {
return (
<div className={style.blockChecbox} key={value}>
{list.map(item => {
return (
<div
key={item.key}
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>
);
})}
</div>
);
};
export default BlockChecbox;

52
src/components/SettingDarwer/ThemeColor.js

@ -0,0 +1,52 @@
import { Icon } from 'antd';
import React from 'react';
import styles from './ThemeColor.less';
const Tag = ({ color, check, ...rest }) => {
return (
<div
{...rest}
style={{
backgroundColor: color,
}}
>
{check ? <Icon type="check" /> : ''}
</div>
);
};
const ThemeColor = ({ colors, value, onChange }) => {
let colorList = colors;
if (!colors) {
colorList = [
'#F5222D',
'#FA541C',
'#FAAD14',
'#13C2C2',
'#52C41A',
'#1890FF',
'#2F54EB',
'#722ED1',
];
}
return (
<div className={styles.themeColor}>
<h3 className={styles.title}>主题色</h3>
<div className={styles.content}>
{colorList.map(color => {
return (
<Tag
className={styles.colorBlock}
key={color}
color={color}
check={value === color}
onClick={() => onChange && onChange(color)}
/>
);
})}
</div>
</div>
);
};
export default ThemeColor;

21
src/components/SettingDarwer/ThemeColor.less

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

187
src/components/SettingDarwer/index.js

@ -0,0 +1,187 @@
import React, { PureComponent } from 'react';
import { Select, message, List, Switch, Divider } from 'antd';
import DrawerMenu from 'rc-drawer-menu';
import { connect } from 'dva';
import styles from './index.less';
import ThemeColor from './ThemeColor';
import BlockChecbox from './BlockChecbox';
const Body = ({ children, title, style }) => (
<div
style={{
...style,
marginBottom: 24,
}}
>
<h3 className={styles.title}>{title}</h3>
{children}
</div>
);
@connect(({ setting }) => ({ setting }))
class SettingDarwer extends PureComponent {
componentDidMount() {
const { themeColor } = this.props.setting;
if (themeColor !== '#1890FF') {
this.colorChange(themeColor);
}
}
getLayOutSetting = () => {
const { grid, fixedHeader, autoHideHeader, fixSiderbar } = this.props.setting;
return [
{
title: '栅格模式',
action: [
<Select
value={grid}
size="small"
onSelect={value => this.changeSetting('grid', value)}
style={{ width: 80 }}
>
<Select.Option value="Wide">Wide</Select.Option>
<Select.Option value="Fluid">Fluid</Select.Option>
</Select>,
],
},
{
title: 'Fixed Header',
action: [
<Switch
size="small"
checked={!!fixedHeader}
onChange={checked => this.changeSetting('fixedHeader', checked)}
/>,
],
},
{
title: '下滑时隐藏 Header',
action: [
<Switch
size="small"
checked={!!autoHideHeader}
onChange={checked => this.changeSetting('autoHideHeader', checked)}
/>,
],
},
{
title: 'Fix Siderbar',
action: [
<Switch
size="small"
checked={!!fixSiderbar}
onChange={checked => this.changeSetting('fixSiderbar', checked)}
/>,
],
},
];
};
changeSetting = (key, value) => {
const nextState = { ...this.props.setting };
nextState[key] = value;
if (key === 'layout') {
if (value === 'topmenu') {
nextState.grid = 'Wide';
} else {
nextState.grid = 'Fluid';
}
}
this.setState(nextState, () => {
this.props.dispatch({
type: 'setting/changeSetting',
payload: this.state,
});
});
};
togglerContent = () => {
this.changeSetting('collapse', !this.props.setting.collapse);
};
colorChange = color => {
this.changeSetting('themeColor', color);
const hideMessage = message.loading('正在编译主题!', 0);
setTimeout(() => {
window.less
.modifyVars({
'@primary-color': color,
})
.then(() => {
hideMessage();
})
.catch(() => {
message.error(`Failed to update theme`);
});
}, 200);
};
render() {
const { collapse, silderTheme, themeColor, layout } = this.props.setting;
return (
<div className={styles.settingDarwer}>
<div className={styles.mini_bar} onClick={this.togglerContent}>
<img
alt="logo"
src="https://gw.alipayobjects.com/zos/rmsportal/ApQgLmeZDNJMomKNvavq.svg"
/>
</div>
<DrawerMenu
parent={null}
level={null}
handleChild={null}
open={collapse}
placement="right"
width="336px"
style={{
zIndex: 999,
}}
onMaskClick={this.togglerContent}
>
<div className={styles.content}>
<Body title="整体风格设置">
<BlockChecbox
list={[
{
key: 'dark',
url: 'https://gw.alipayobjects.com/zos/rmsportal/LCkqqYNmvBEbokSDscrm.svg',
},
{
key: 'light',
url: 'https://gw.alipayobjects.com/zos/rmsportal/jpRkZQMyYRryryPNtyIC.svg',
},
]}
value={silderTheme}
onChange={value => this.changeSetting('silderTheme', value)}
/>
</Body>
<ThemeColor value={themeColor} onChange={this.colorChange} />
<Divider />
<Body title="导航设置 ">
<BlockChecbox
list={[
{
key: 'sidemenu',
url: 'https://gw.alipayobjects.com/zos/rmsportal/JopDzEhOqwOjeNTXkoje.svg',
},
{
key: 'topmenu',
url: 'https://gw.alipayobjects.com/zos/rmsportal/KDNDBbriJhLwuqMoxcAr.svg',
},
]}
value={layout}
onChange={value => this.changeSetting('layout', value)}
/>
</Body>
<List
split={false}
dataSource={this.getLayOutSetting()}
renderItem={item => <List.Item actions={item.action}>{item.title}</List.Item>}
/>
</div>
</DrawerMenu>
</div>
);
}
}
export default SettingDarwer;

55
src/components/Sidebar/index.less → src/components/SettingDarwer/index.less

@ -1,4 +1,6 @@
.sidebar {
@import '~antd/lib/style/themes/default.less';
.settingDarwer {
.mini_bar {
width: 50px;
height: 45px;
@ -26,51 +28,50 @@
}
.content {
width: 336px;
width: 273px;
height: 100%;
padding: 24px;
background: #fff;
:global {
.ant-switch-checked {
background-color: #87d068;
}
.ant-list-item {
padding-top: 7px;
padding-bottom: 7px;
}
}
}
.layoutSetting {
margin: 5px;
.blockChecbox {
display: flex;
.item {
margin-right: 16px;
position: relative;
// box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1);
border-radius: 4px;
cursor: pointer;
width: 70px;
height: 44px;
text-align: center;
margin: 8px;
img {
width: 48px;
}
}
.selectIcon {
position: absolute;
top: 0;
right: 0;
width: 100%;
padding-top: 15px;
padding-left: 24px;
height: 100%;
color: @primary-color;
font-size: 14px;
font-weight: bold;
}
}
.color_block {
width: 38px;
height: 22px;
margin: 4px;
border-radius: 4px;
cursor: pointer;
margin-right: 12px;
display: inline-block;
vertical-align: middle;
background: #002140;
border-radius: 2px;
}
.color_block_title {
display: inline-block;
font-size: 14px;
color: rgba(0, 0, 0, 0.65);
line-height: 22px;
}
.bodyTitle {
.title {
font-size: 14px;
color: rgba(0, 0, 0, 0.85);
line-height: 22px;
margin-bottom: 10px;
margin-bottom: 12px;
}

23
src/components/Sidebar/LayoutSetting.js

@ -1,23 +0,0 @@
import { Tooltip } from 'antd';
import React from 'react';
import NavSate from './navState';
import style from './index.less';
const LayoutSetting = ({ value, onChange }) => {
return (
<div className={style.layoutSetting}>
{['sidemenu', 'topmenu'].map(layout => (
<div className={style.item} onClick={() => onChange && onChange(layout)} key={layout}>
<NavSate type={layout} state={value === layout ? 'active' : 'default'} alt={layout} />
</div>
))}
<Tooltip title="等待后期实现!">
<div key="topside" className={style.item}>
<NavSate type="topside" state="disable" alt="topside" />
</div>
</Tooltip>
</div>
);
};
export default LayoutSetting;

52
src/components/Sidebar/ThemeColor.js

@ -1,52 +0,0 @@
import React from 'react';
import styles from './ThemeColor.less';
const Tag = ({ color, ...rest }) => {
return (
<div
{...rest}
style={{
backgroundColor: color,
}}
/>
);
};
const ThemeColor = ({ colors, value, onChange }) => {
let colorList = colors;
if (!colors) {
colorList = [
'#F5222D',
'#FA541C',
'#FA8C16',
'#FAAD14',
'#FADB14',
'#A0D911',
'#52C41A',
'#13C2C2',
'#1890FF',
'#2F54EB',
'#722ED1',
'#EB2F96',
];
}
return (
<div className={styles.themeColor}>
<h3 className={styles.title}>主题颜色</h3>
{colorList.map(color => {
const classname =
value === color ? `${styles.colorBlock} ${styles.active}` : styles.colorBlock;
return (
<Tag
className={classname}
key={color}
color={color}
onClick={() => onChange && onChange(color)}
/>
);
})}
</div>
);
};
export default ThemeColor;

27
src/components/Sidebar/ThemeColor.less

@ -1,27 +0,0 @@
.themeColor {
overflow: hidden;
margin-top: 15px;
margin-left: -5px;
margin-right: -5px;
.title {
font-size: 14px;
color: rgba(0, 0, 0, 0.65);
line-height: 22px;
margin-bottom: 5px;
}
.colorBlock {
width: 16px;
height: 16px;
border-radius: 2px;
float: left;
cursor: pointer;
margin: 5px;
&.active {
width: 18px;
height: 18px;
margin: 4px;
border: 2px solid hsl(90, 100%, 50%);
box-shadow: 0 0 4px 0 hsl(90, 100%, 50%);
}
}
}

206
src/components/Sidebar/index.js

@ -1,206 +0,0 @@
import React, { PureComponent, Fragment } from 'react';
import { Select, message, List, Switch, Divider, Radio } from 'antd';
import DrawerMenu from 'rc-drawer-menu';
import { connect } from 'dva';
import styles from './index.less';
import ThemeColor from './ThemeColor';
import LayoutSeting from './LayoutSetting';
const RadioGroup = Radio.Group;
const ColorBlock = ({ color, title }) => (
<Fragment>
<div
className={styles.color_block}
style={{
backgroundColor: color,
}}
/>
<div className={styles.color_block_title}>{title}</div>
</Fragment>
);
const Body = ({ children, title, style }) => (
<div
style={{
padding: 15,
...style,
}}
>
<h3 className={styles.bodyTitle}>{title}</h3>
{children}
</div>
);
@connect(({ setting }) => ({ setting }))
class Sidebar extends PureComponent {
componentDidMount() {
const { themeColor } = this.props.setting;
if (themeColor !== '#1890FF') {
this.colorChange(themeColor);
}
}
getLayOutSetting = () => {
const { grid, fixedHeader, autoHideHeader, fixSiderbar, layout } = this.props.setting;
return [
{
title: '栅格模式',
isShow: true,
action: [
<Select
value={grid}
onSelect={value => this.changeSetting('grid', value)}
style={{ width: 120 }}
>
<Select.Option value="Wide">Wide</Select.Option>
<Select.Option value="Fluid">Fluid</Select.Option>
</Select>,
],
},
{
title: 'Fixed Header',
isShow: true,
action: [
<Switch
checked={!!fixedHeader}
onChange={checked => this.changeSetting('fixedHeader', checked)}
/>,
],
},
{
title: '↳ 下滑时隐藏 Header',
isShow: true,
action: [
<Switch
checked={!!autoHideHeader}
onChange={checked => this.changeSetting('autoHideHeader', checked)}
/>,
],
},
{
title: 'Fix Siderbar',
isShow: layout === 'sidemenu',
action: [<Switch checked={!!fixSiderbar} onChange={this.fixSiderbar} />],
},
].filter(item => item.isShow);
};
fixSiderbar = checked => {
this.changeSetting('fixSiderbar', checked);
};
changeSetting = (key, value) => {
const nextState = { ...this.props.setting };
nextState[key] = value;
if (key === 'layout') {
if (value === 'topmenu') {
nextState.grid = 'Wide';
} else {
nextState.grid = 'Fluid';
}
}
this.setState(nextState, () => {
this.props.dispatch({
type: 'setting/changeSetting',
payload: this.state,
});
});
};
togglerContent = () => {
this.changeSetting('collapse', !this.props.setting.collapse);
};
colorChange = color => {
this.changeSetting('themeColor', color);
const hideMessage = message.loading('正在编译主题!', 0);
window.less
.modifyVars({
'@primary-color': color,
})
.then(() => {
hideMessage();
})
.catch(() => {
message.error(`Failed to update theme`);
});
};
render() {
const radioStyle = {
display: 'block',
};
const { collapse, silderTheme, themeColor, layout, colorWeak } = this.props.setting;
return (
<div className={styles.sidebar}>
<div className={styles.mini_bar} onClick={this.togglerContent}>
<img
alt="logo"
src="https://gw.alipayobjects.com/zos/rmsportal/ApQgLmeZDNJMomKNvavq.svg"
/>
</div>
<DrawerMenu
parent={null}
level={null}
handleChild={null}
open={collapse}
placement="right"
width="336px"
onMaskClick={this.togglerContent}
>
<div className={styles.content}>
<Body
title="整体风格设置"
style={{
paddingBottom: 10,
}}
>
<RadioGroup
onChange={({ target }) => this.changeSetting('silderTheme', target.value)}
value={silderTheme}
>
<Radio style={radioStyle} value="dark">
<ColorBlock color="#002140" title="深色导航" />
</Radio>
<Radio style={radioStyle} value="light">
<ColorBlock color="#E9E9E9" title="浅色导航" />
</Radio>
</RadioGroup>
<ThemeColor value={themeColor} onChange={this.colorChange} />
</Body>
<Divider style={{ margin: 0 }} />
<Body title="导航设置 ">
<LayoutSeting
value={layout}
onChange={value => this.changeSetting('layout', value)}
/>
<List
split={false}
dataSource={this.getLayOutSetting()}
renderItem={item => <List.Item actions={item.action}>{item.title}</List.Item>}
/>
</Body>
<Divider style={{ margin: 0 }} />
<Body title="其他设置">
<List
split={false}
dataSource={[
{
title: '色弱模式',
action: [
<Select
value={colorWeak}
onSelect={value => this.changeSetting('colorWeak', value)}
style={{ width: 120 }}
>
<Select.Option value="open">打开</Select.Option>
<Select.Option value="close">关闭</Select.Option>
</Select>,
],
},
]}
renderItem={item => <List.Item actions={item.action}>{item.title}</List.Item>}
/>
</Body>
</div>
</DrawerMenu>
</div>
);
}
}
export default Sidebar;

26
src/components/Sidebar/navState.js

@ -1,26 +0,0 @@
import React from 'react';
const UrlMap = {
sidemenu: {
active: 'https://gw.alipayobjects.com/zos/rmsportal/WEqgEeCsLvecmwJwbhif.svg',
default: 'https://gw.alipayobjects.com/zos/rmsportal/bjdhEDZlJzyMlyGbFQQd.svg',
disable: 'https://gw.alipayobjects.com/zos/rmsportal/VeCtUculrOjKzkzSzrye.svg',
},
topside: {
active: 'https://gw.alipayobjects.com/zos/rmsportal/RbntcRzDHttDvYfKxsPc.svg',
default: 'https://gw.alipayobjects.com/zos/rmsportal/gqjBdnSHfVYIFvpGbLZV.svg',
disable: 'https://gw.alipayobjects.com/zos/rmsportal/VlSlQQkUGdbcOZdbUgMp.svg',
},
topmenu: {
active: 'https://gw.alipayobjects.com/zos/rmsportal/nWoQtAGvMihfwxKZEzAi.svg',
default: 'https://gw.alipayobjects.com/zos/rmsportal/tbfuZcaGaYQGyeaiTaDg.svg',
disable: 'https://gw.alipayobjects.com/zos/rmsportal/VYNKTivFAQOBBbZkkWNb.svg',
},
};
const navState = ({ alt, type, state }) => {
const url = UrlMap[type][state];
return <img src={url} alt={alt} />;
};
export default navState;

4
src/layouts/BasicLayout.js

@ -10,7 +10,7 @@ import SiderMenu from '../components/SiderMenu';
import NotFound from '../routes/Exception/404';
import { getRoutes } from '../utils/utils';
import Authorized from '../utils/Authorized';
import Sidebar from '../components/Sidebar';
import SettingDarwer from '../components/SettingDarwer';
import logo from '../assets/logo.svg';
import Footer from './Footer';
import Header from './Header';
@ -176,7 +176,7 @@ class BasicLayout extends React.PureComponent {
<Context.Provider value={this.getContext()}>
<div className={classNames(params)}>
{layout}
<Sidebar />
<SettingDarwer />
</div>
</Context.Provider>
)}

2
webpack.config.js

@ -5,7 +5,7 @@ const path = require('path');
export default webpackConfig => {
const options = {
antDir: path.join(__dirname, './node_modules/antd'),
stylesDir: path.join(__dirname, './src'),
stylesDir: path.join(__dirname, './src/'),
varFile: path.join(__dirname, './node_modules/antd/lib/style/themes/default.less'),
mainLessFile: path.join(__dirname, './src/index.less'),
themeVariables: ['@primary-color'],

Loading…
Cancel
Save