index.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. import React, { PureComponent, Fragment } from 'react';
  2. import { Select, message, List, Switch, Divider, Radio } from 'antd';
  3. import DrawerMenu from 'rc-drawer-menu';
  4. import styles from './index.less';
  5. import ThemeColor from './ThemeColor';
  6. import LayoutSeting from './LayoutSetting';
  7. const RadioGroup = Radio.Group;
  8. const ColorBlock = ({ color, title }) => (
  9. <Fragment>
  10. <div
  11. className={styles.color_block}
  12. style={{
  13. backgroundColor: color,
  14. }}
  15. />
  16. <div className={styles.color_block_title}>{title}</div>
  17. </Fragment>
  18. );
  19. const Body = ({ children, title, style }) => (
  20. <div
  21. style={{
  22. padding: 15,
  23. ...style,
  24. }}
  25. >
  26. <h3 className={styles.bodyTitle}>{title}</h3>
  27. {children}
  28. </div>
  29. );
  30. class Sidebar extends PureComponent {
  31. static getDerivedStateFromProps(nextProps, prevState) {
  32. const nextState = {};
  33. Object.keys(nextProps).forEach(key => {
  34. if (nextProps[key] && prevState[key] !== undefined) {
  35. nextState[key] = nextProps[key];
  36. }
  37. });
  38. return nextState;
  39. }
  40. constructor(props) {
  41. super(props);
  42. this.defaultstate = {
  43. collapse: false,
  44. silderTheme: 'dark',
  45. themeColor: '#1890FF',
  46. layout: 'sidemenu',
  47. grid: 'Fluid',
  48. fixedHeader: false,
  49. autoHideHeader: false,
  50. fixSiderbar: false,
  51. colorWeak: 'close',
  52. };
  53. const propsState = this.propsToState(props);
  54. this.state = { ...this.defaultstate, ...propsState };
  55. }
  56. componentDidMount() {
  57. this.colorChange(this.state.themeColor);
  58. }
  59. getLayOutSetting = () => {
  60. const { layout } = this.state;
  61. return [
  62. {
  63. title: '栅格模式',
  64. isShow: true,
  65. action: [
  66. <Select
  67. value={this.state.grid}
  68. onSelect={value => this.changeSetting('grid', value)}
  69. style={{ width: 120 }}
  70. >
  71. <Select.Option value="Wide">Wide</Select.Option>
  72. <Select.Option value="Fluid">Fluid</Select.Option>
  73. </Select>,
  74. ],
  75. },
  76. {
  77. title: 'Fixed Header',
  78. isShow: true,
  79. action: [
  80. <Switch
  81. checked={!!this.state.fixedHeader}
  82. onChange={checked => this.changeSetting('fixedHeader', checked)}
  83. />,
  84. ],
  85. },
  86. {
  87. title: '↳ 下滑时隐藏 Header',
  88. isShow: true,
  89. action: [
  90. <Switch
  91. checked={!!this.state.autoHideHeader}
  92. onChange={checked => this.changeSetting('autoHideHeader', checked)}
  93. />,
  94. ],
  95. },
  96. {
  97. title: 'Fix Siderbar',
  98. isShow: layout === 'sidemenu',
  99. action: [<Switch checked={!!this.state.fixSiderbar} onChange={this.fixSiderbar} />],
  100. },
  101. ].filter(item => item.isShow);
  102. };
  103. fixSiderbar = checked => {
  104. this.changeSetting('fixSiderbar', checked);
  105. };
  106. changeSetting = (key, value) => {
  107. const nextState = {};
  108. nextState[key] = value;
  109. if (key === 'layout') {
  110. if (value === 'topmenu') {
  111. nextState.grid = 'Wide';
  112. } else {
  113. nextState.grid = 'Fluid';
  114. }
  115. }
  116. this.setState(nextState, () => {
  117. if (this.props.onChange) {
  118. this.props.onChange(this.state);
  119. }
  120. });
  121. };
  122. propsToState = props => {
  123. const nextState = {};
  124. Object.keys(props).forEach(key => {
  125. if (props[key] && this.defaultstate[key] !== undefined) {
  126. nextState[key] = props[key];
  127. }
  128. });
  129. return nextState;
  130. };
  131. togglerContent = () => {
  132. this.changeSetting('collapse', !this.state.collapse);
  133. };
  134. colorChange = color => {
  135. this.changeSetting('themeColor', color);
  136. this.setState(
  137. {
  138. themeColor: color,
  139. },
  140. () => {
  141. const hideMessage = message.loading('正在编译主题!', 0);
  142. window.less
  143. .modifyVars({
  144. '@primary-color': color,
  145. })
  146. .then(() => {
  147. hideMessage();
  148. })
  149. .catch(() => {
  150. message.error(`Failed to update theme`);
  151. });
  152. }
  153. );
  154. };
  155. render() {
  156. const radioStyle = {
  157. display: 'block',
  158. };
  159. return (
  160. <div className={styles.sidebar}>
  161. <div className={styles.mini_bar} onClick={this.togglerContent}>
  162. <img
  163. alt="logo"
  164. src="https://gw.alipayobjects.com/zos/rmsportal/ApQgLmeZDNJMomKNvavq.svg"
  165. />
  166. </div>
  167. <DrawerMenu
  168. parent={null}
  169. level={null}
  170. iconChild={null}
  171. open={this.state.collapse}
  172. placement="right"
  173. width="336px"
  174. onMaskClick={this.togglerContent}
  175. >
  176. <div className={styles.content}>
  177. <Body
  178. title="整体风格设置"
  179. style={{
  180. paddingBottom: 10,
  181. }}
  182. >
  183. <RadioGroup
  184. onChange={({ target }) => this.changeSetting('silderTheme', target.value)}
  185. value={this.state.silderTheme}
  186. >
  187. <Radio style={radioStyle} value="dark">
  188. <ColorBlock color="#002140" title="深色导航" />
  189. </Radio>
  190. <Radio style={radioStyle} value="ligth">
  191. <ColorBlock color="#E9E9E9" title="浅色导航" />
  192. </Radio>
  193. </RadioGroup>
  194. <ThemeColor value={this.state.themeColor} onChange={this.colorChange} />
  195. </Body>
  196. <Divider style={{ margin: 0 }} />
  197. <Body title="导航设置 ">
  198. <LayoutSeting
  199. value={this.state.layout}
  200. onChange={layout => this.changeSetting('layout', layout)}
  201. />
  202. <List
  203. split={false}
  204. dataSource={this.getLayOutSetting()}
  205. renderItem={item => <List.Item actions={item.action}>{item.title}</List.Item>}
  206. />
  207. </Body>
  208. <Divider style={{ margin: 0 }} />
  209. <Body title="其他设置">
  210. <List
  211. split={false}
  212. dataSource={[
  213. {
  214. title: '色弱模式',
  215. action: [
  216. <Select
  217. value={this.state.colorWeak}
  218. onSelect={value => this.changeSetting('colorWeak', value)}
  219. style={{ width: 120 }}
  220. >
  221. <Select.Option value="open">打开</Select.Option>
  222. <Select.Option value="colse">关闭</Select.Option>
  223. </Select>,
  224. ],
  225. },
  226. ]}
  227. renderItem={item => <List.Item actions={item.action}>{item.title}</List.Item>}
  228. />
  229. </Body>
  230. </div>
  231. </DrawerMenu>
  232. </div>
  233. );
  234. }
  235. }
  236. export default Sidebar;