提交 f2663c4f13aa122cce52a1c6c4bcf89d9d2268f2

作者 愚道
1 个父辈 3267ac28

init pro block serach list layout

  1 +/yarn.lock
  2 +/package-lock.json
  3 +/dist
  4 +/node_modules
  5 +
  6 +.umi
  7 +.umi-production
  1 +export default {
  2 + plugins: [
  3 + ['umi-plugin-block-dev', {}],
  4 + ['umi-plugin-react', {
  5 + dva: true,
  6 + locale: true,
  7 + antd: true,
  8 + }]
  9 + ],
  10 +}
  1 +import React, { PureComponent } from 'react';
  2 +import { connect } from 'dva';
  3 +import styles from './GridContent.less';
  4 +
  5 +class GridContent extends PureComponent {
  6 + render() {
  7 + const { contentWidth, children } = this.props;
  8 + let className = `${styles.main}`;
  9 + if (contentWidth === 'Fixed') {
  10 + className = `${styles.main} ${styles.wide}`;
  11 + }
  12 + return <div className={className}>{children}</div>;
  13 + }
  14 +}
  15 +
  16 +export default connect(({ setting }) => ({
  17 + contentWidth: setting.contentWidth,
  18 +}))(GridContent);
  1 +.main {
  2 + width: 100%;
  3 + height: 100%;
  4 + min-height: 100%;
  5 + transition: 0.3s;
  6 + &.wide {
  7 + max-width: 1200px;
  8 + margin: 0 auto;
  9 + }
  10 +}
  1 +import React from 'react';
  2 +import { FormattedMessage } from 'umi/locale';
  3 +import Link from 'umi/link';
  4 +import PageHeader from 'ant-design-pro/lib/PageHeader';
  5 +import { connect } from 'dva';
  6 +import GridContent from './GridContent';
  7 +import styles from './index.less';
  8 +import MenuContext from '@/layouts/MenuContext';
  9 +
  10 +const PageHeaderWrapper = ({ children, contentWidth, wrapperClassName, top, ...restProps }) => (
  11 + <div style={{ margin: '-24px -24px 0' }} className={wrapperClassName}>
  12 + {top}
  13 + <MenuContext.Consumer>
  14 + {value => (
  15 + <PageHeader
  16 + wide={contentWidth === 'Fixed'}
  17 + home={<FormattedMessage id="menu.home" defaultMessage="Home" />}
  18 + {...value}
  19 + key="pageheader"
  20 + {...restProps}
  21 + linkElement={Link}
  22 + itemRender={item => {
  23 + if (item.locale) {
  24 + return <FormattedMessage id={item.locale} defaultMessage={item.title} />;
  25 + }
  26 + return item.title;
  27 + }}
  28 + />
  29 + )}
  30 + </MenuContext.Consumer>
  31 + {children ? (
  32 + <div className={styles.content}>
  33 + <GridContent>{children}</GridContent>
  34 + </div>
  35 + ) : null}
  36 + </div>
  37 +);
  38 +
  39 +export default connect(({ setting }) => ({
  40 + contentWidth: setting.contentWidth,
  41 +}))(PageHeaderWrapper);
  1 +@import '~antd/lib/style/themes/default.less';
  2 +
  3 +.content {
  4 + margin: 24px 24px 0;
  5 +}
  6 +
  7 +@media screen and (max-width: @screen-sm) {
  8 + .content {
  9 + margin: 24px 0 0;
  10 + }
  11 +}
  1 +import { createContext } from 'react';
  2 +
  3 +export default createContext();
  1 +# @umi-material/searchlist
  2 +
  3 +SearchList
  4 +
  5 +## Usage
  6 +
  7 +```sh
  8 +umi block https://github.com/umijs/umi-blocks/tree/master/searchlist
  9 +```
  10 +
  11 +## LICENSE
  12 +
  13 +MIT
  1 +{
  2 + "name": "@umi-block/searchlist",
  3 + "version": "0.0.1",
  4 + "description": "SearchList",
  5 + "main": "src/index.js",
  6 + "scripts": {
  7 + "dev": "umi dev"
  8 + },
  9 + "repository": {
  10 + "type": "git",
  11 + "url": "https://github.com/umijs/umi-blocks/searchlist"
  12 + },
  13 + "dependencies": {
  14 + "react": "^16.6.3",
  15 + "dva": "^2.4.0",
  16 + "antd": "^3.10.9",
  17 + "ant-design-pro": "^2.1.1"
  18 + },
  19 + "devDependencies": {
  20 + "umi": "^2.3.0-beta.1",
  21 + "umi-plugin-react": "^1.3.0-beta.1",
  22 + "umi-plugin-block-dev": "^1.0.0"
  23 + },
  24 + "license": "ISC"
  25 +}
  1 +module.exports = {
  2 + navTheme: 'dark', // theme for nav menu
  3 + primaryColor: '#1890FF', // primary color of ant design
  4 + layout: 'sidemenu', // nav menu position: sidemenu or topmenu
  5 + contentWidth: 'Fluid', // layout of content: Fluid or Fixed, only works when layout is topmenu
  6 + fixedHeader: false, // sticky header
  7 + autoHideHeader: false, // auto hide header
  8 + fixSiderbar: false, // sticky siderbar
  9 +};
  1 +import React, { Component } from 'react';
  2 +import router from 'umi/router';
  3 +import { connect } from 'dva';
  4 +import { Input } from 'antd';
  5 +import PageHeaderWrapper from '@/components/PageHeaderWrapper';
  6 +
  7 +@connect()
  8 +class SearchList extends Component {
  9 + handleTabChange = key => {
  10 + const { match } = this.props;
  11 + switch (key) {
  12 + case 'articles':
  13 + router.push(`${match.url}/articles`);
  14 + break;
  15 + case 'applications':
  16 + router.push(`${match.url}/applications`);
  17 + break;
  18 + case 'projects':
  19 + router.push(`${match.url}/projects`);
  20 + break;
  21 + default:
  22 + break;
  23 + }
  24 + };
  25 +
  26 + handleFormSubmit = value => {
  27 + // eslint-disable-next-line
  28 + console.log(value);
  29 + };
  30 +
  31 + render() {
  32 + const tabList = [
  33 + {
  34 + key: 'articles',
  35 + tab: '文章',
  36 + },
  37 + {
  38 + key: 'projects',
  39 + tab: '项目',
  40 + },
  41 + {
  42 + key: 'applications',
  43 + tab: '应用',
  44 + },
  45 + ];
  46 +
  47 + const mainSearch = (
  48 + <div style={{ textAlign: 'center' }}>
  49 + <Input.Search
  50 + placeholder="请输入"
  51 + enterButton="搜索"
  52 + size="large"
  53 + onSearch={this.handleFormSubmit}
  54 + style={{ width: 522 }}
  55 + />
  56 + </div>
  57 + );
  58 +
  59 + const { match, children, location } = this.props;
  60 +
  61 + return (
  62 + <PageHeaderWrapper
  63 + title="搜索列表"
  64 + content={mainSearch}
  65 + tabList={tabList}
  66 + tabActiveKey={location.pathname.replace(`${match.path}/`, '')}
  67 + onTabChange={this.handleTabChange}
  68 + >
  69 + {children}
  70 + {/* <Switch>
  71 + {routes.map(item => (
  72 + <Route key={item.key} path={item.path} component={item.component} exact={item.exact} />
  73 + ))}
  74 + </Switch> */}
  75 + </PageHeaderWrapper>
  76 + );
  77 + }
  78 +}
  79 +
  80 +export default SearchList;
  1 +import { message } from 'antd';
  2 +import defaultSettings from '../defaultSettings';
  3 +
  4 +let lessNodesAppended;
  5 +const updateTheme = primaryColor => {
  6 + // Don't compile less in production!
  7 + if (APP_TYPE !== 'site') {
  8 + return;
  9 + }
  10 + // Determine if the component is remounted
  11 + if (!primaryColor) {
  12 + return;
  13 + }
  14 + const hideMessage = message.loading('正在编译主题!', 0);
  15 + function buildIt() {
  16 + if (!window.less) {
  17 + return;
  18 + }
  19 + setTimeout(() => {
  20 + window.less
  21 + .modifyVars({
  22 + '@primary-color': primaryColor,
  23 + })
  24 + .then(() => {
  25 + hideMessage();
  26 + })
  27 + .catch(() => {
  28 + message.error('Failed to update theme');
  29 + hideMessage();
  30 + });
  31 + }, 200);
  32 + }
  33 + if (!lessNodesAppended) {
  34 + // insert less.js and color.less
  35 + const lessStyleNode = document.createElement('link');
  36 + const lessConfigNode = document.createElement('script');
  37 + const lessScriptNode = document.createElement('script');
  38 + lessStyleNode.setAttribute('rel', 'stylesheet/less');
  39 + lessStyleNode.setAttribute('href', '/color.less');
  40 + lessConfigNode.innerHTML = `
  41 + window.less = {
  42 + async: true,
  43 + env: 'production',
  44 + javascriptEnabled: true
  45 + };
  46 + `;
  47 + lessScriptNode.src = 'https://gw.alipayobjects.com/os/lib/less.js/3.8.1/less.min.js';
  48 + lessScriptNode.async = true;
  49 + lessScriptNode.onload = () => {
  50 + buildIt();
  51 + lessScriptNode.onload = null;
  52 + };
  53 + document.body.appendChild(lessStyleNode);
  54 + document.body.appendChild(lessConfigNode);
  55 + document.body.appendChild(lessScriptNode);
  56 + lessNodesAppended = true;
  57 + } else {
  58 + buildIt();
  59 + }
  60 +};
  61 +
  62 +const updateColorWeak = colorWeak => {
  63 + document.body.className = colorWeak ? 'colorWeak' : '';
  64 +};
  65 +
  66 +export default {
  67 + namespace: 'setting',
  68 + state: defaultSettings,
  69 + reducers: {
  70 + getSetting(state) {
  71 + const setting = {};
  72 + const urlParams = new URL(window.location.href);
  73 + Object.keys(state).forEach(key => {
  74 + if (urlParams.searchParams.has(key)) {
  75 + const value = urlParams.searchParams.get(key);
  76 + setting[key] = value === '1' ? true : value;
  77 + }
  78 + });
  79 + const { primaryColor, colorWeak } = setting;
  80 + if (state.primaryColor !== primaryColor) {
  81 + updateTheme(primaryColor);
  82 + }
  83 + updateColorWeak(colorWeak);
  84 + return {
  85 + ...state,
  86 + ...setting,
  87 + };
  88 + },
  89 + changeSetting(state, { payload }) {
  90 + const urlParams = new URL(window.location.href);
  91 + Object.keys(defaultSettings).forEach(key => {
  92 + if (urlParams.searchParams.has(key)) {
  93 + urlParams.searchParams.delete(key);
  94 + }
  95 + });
  96 + Object.keys(payload).forEach(key => {
  97 + if (key === 'collapse') {
  98 + return;
  99 + }
  100 + let value = payload[key];
  101 + if (value === true) {
  102 + value = 1;
  103 + }
  104 + if (defaultSettings[key] !== value) {
  105 + urlParams.searchParams.set(key, value);
  106 + }
  107 + });
  108 + const { primaryColor, colorWeak, contentWidth } = payload;
  109 + if (state.primaryColor !== primaryColor) {
  110 + updateTheme(primaryColor);
  111 + }
  112 + if (state.contentWidth !== contentWidth && window.dispatchEvent) {
  113 + window.dispatchEvent(new Event('resize'));
  114 + }
  115 + updateColorWeak(colorWeak);
  116 + window.history.replaceState(null, 'setting', urlParams.href);
  117 + return {
  118 + ...state,
  119 + ...payload,
  120 + };
  121 + },
  122 + },
  123 +};
注册登录 后发表评论