The response has been limited to 50k tokens of the smallest files in the repo. You can remove this limitation by removing the max tokens filter.
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .github
    └── FUNDING.yml
├── .gitignore
├── .stylelintrc
├── CNAME
├── LICENSE
├── README-zh_CN.md
├── README.md
├── docs
    ├── cases.md
    ├── download.md
    ├── edit
    │   ├── edit-block.md
    │   └── video.md
    ├── guide
    │   ├── banner.md
    │   ├── content.md
    │   ├── examples.md
    │   ├── header-footer.md
    │   ├── layout.md
    │   └── type.md
    ├── introduce.md
    └── use
    │   ├── create-react-app.en-US.md
    │   ├── create-react-app.zh-CN.md
    │   ├── dumi.md
    │   ├── dva-cli.md
    │   ├── getting-started.md
    │   ├── pro-1-x.md
    │   ├── pro.md
    │   └── umi.md
├── documentation.md
├── index.text
├── package.json
├── prettier
    ├── install-service-worker.js
    ├── lib
    │   ├── index.js
    │   ├── parser-babylon.js
    │   ├── parser-flow.js
    │   ├── parser-glimmer.js
    │   ├── parser-graphql.js
    │   ├── parser-markdown.js
    │   ├── parser-parse5.js
    │   ├── parser-postcss.js
    │   ├── parser-typescript.js
    │   ├── parser-vue.js
    │   └── sw-toolbox.js
    ├── service-worker.js
    └── worker.js
├── renovate.json
├── site
    ├── bisheng.common.config.js
    ├── bisheng.edit.config.js
    ├── bisheng.index.config.js
    ├── bisheng.templates.config.js
    ├── edit
    │   ├── en-US.js
    │   ├── index.js
    │   ├── static
    │   │   ├── banner-slide.less
    │   │   ├── common.less
    │   │   ├── content.less
    │   │   ├── custom.less
    │   │   ├── edit-influence.less
    │   │   ├── edit-list
    │   │   │   ├── box-model.less
    │   │   │   ├── child.less
    │   │   │   ├── collapse.less
    │   │   │   ├── common.less
    │   │   │   ├── custom.less
    │   │   │   ├── editor-bg-image.less
    │   │   │   ├── editor-color.less
    │   │   │   ├── editor-font.less
    │   │   │   ├── editor-gradient.less
    │   │   │   └── index.less
    │   │   ├── edit-stage.less
    │   │   ├── index.html
    │   │   ├── index.less
    │   │   ├── login-controller.less
    │   │   ├── nav-controller.less
    │   │   ├── other-view.less
    │   │   ├── side-menu.less
    │   │   ├── sort.less
    │   │   └── style.js
    │   ├── template
    │   │   ├── NotFound.jsx
    │   │   ├── component.config.js
    │   │   ├── components
    │   │   │   ├── EditInfluence.jsx
    │   │   │   ├── EditListController.jsx
    │   │   │   ├── EditStageController.jsx
    │   │   │   ├── Iframe.jsx
    │   │   │   ├── ListComponents
    │   │   │   │   ├── CheckboxGroup.jsx
    │   │   │   │   ├── ChildComp.jsx
    │   │   │   │   ├── EditorComp.jsx
    │   │   │   │   ├── EditorOther.jsx
    │   │   │   │   ├── InputGroup.jsx
    │   │   │   │   └── PropsComp.jsx
    │   │   │   ├── MediumEditor.jsx
    │   │   │   ├── NavController
    │   │   │   │   ├── HistoryButton.jsx
    │   │   │   │   ├── NewFileButton.jsx
    │   │   │   │   ├── PublishModal.jsx
    │   │   │   │   └── index.jsx
    │   │   │   ├── SideMenu.jsx
    │   │   │   ├── StateComponents
    │   │   │   │   ├── ButtonViewComponent
    │   │   │   │   │   ├── ContentEditView.jsx
    │   │   │   │   │   ├── ContentEditViewItem.jsx
    │   │   │   │   │   ├── ContentWrapper.jsx
    │   │   │   │   │   ├── IconComp.jsx
    │   │   │   │   │   ├── ImageComp.jsx
    │   │   │   │   │   ├── LinkComp.jsx
    │   │   │   │   │   ├── MenuComp.jsx
    │   │   │   │   │   ├── MenuEditView.jsx
    │   │   │   │   │   ├── TextyComp.jsx
    │   │   │   │   │   └── VideoComp.jsx
    │   │   │   │   ├── EditButtonView.jsx
    │   │   │   │   ├── ListSort.jsx
    │   │   │   │   └── SwitchSlideView.jsx
    │   │   │   └── saveJsZip.jsx
    │   │   ├── index.jsx
    │   │   ├── layout.jsx
    │   │   ├── template.config.js
    │   │   └── utils.jsx
    │   └── zh-CN.js
    ├── shared
    │   ├── constants.js
    │   ├── defaultTemplate.js
    │   ├── leancloud.js
    │   ├── localStorage.js
    │   ├── redux
    │   │   ├── actionTypes.js
    │   │   ├── actions.js
    │   │   ├── index.js
    │   │   ├── reducers
    │   │   │   ├── currentEditData.js
    │   │   │   ├── historyEdit.js
    │   │   │   ├── index.js
    │   │   │   ├── mediaStateSelect.js
    │   │   │   ├── templateData.js
    │   │   │   └── userIsLogin.js
    │   │   └── saga.js
    │   ├── url.js
    │   └── utils.js
    ├── templates
    │   ├── index.js
    │   ├── static
    │   │   ├── bottom-func-bar.less
    │   │   ├── common.less
    │   │   ├── content.less
    │   │   ├── custom.less
    │   │   ├── index.html
    │   │   ├── index.less
    │   │   ├── lessToString.jsx
    │   │   └── point.less
    │   └── template
    │   │   ├── BottomBar.jsx
    │   │   ├── NotFound.jsx
    │   │   ├── element
    │   │       ├── Banner0
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Banner1
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Banner2
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Banner3
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Banner4
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Banner5
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Content0
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Content1
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Content10
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Content11
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Content12
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Content13
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Content2
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Content3
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Content4
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Content5
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Content6
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Content7
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Content8
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Content9
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Feature6
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Feature7
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Feature8
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Footer0
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Footer1
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Footer2
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Nav0
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Nav1
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Nav2
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Nav3
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Pricing0
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Pricing1
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Pricing2
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Teams0
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Teams1
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Teams2
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       ├── Teams3
    │   │       │   ├── index.jsx
    │   │       │   ├── index.less
    │   │       │   └── template.config.js
    │   │       └── template.config.js
    │   │   ├── index.jsx
    │   │   ├── layout.jsx
    │   │   ├── other
    │   │       ├── Point.jsx
    │   │       └── otherToString.jsx
    │   │   └── utils.jsx
    ├── theme
    │   ├── en-US.js
    │   ├── index.js
    │   ├── static
    │   │   ├── antd.less
    │   │   ├── common.less
    │   │   ├── default.less
    │   │   ├── footer.less
    │   │   ├── header.less
    │   │   ├── home
    │   │   │   ├── banner.less
    │   │   │   ├── index.less
    │   │   │   ├── page1.less
    │   │   │   ├── page2.less
    │   │   │   ├── page3.less
    │   │   │   ├── page4.less
    │   │   │   └── responsive.less
    │   │   ├── index.less
    │   │   ├── page
    │   │   │   ├── highlight.less
    │   │   │   ├── index.less
    │   │   │   ├── markdown.less
    │   │   │   ├── page-nav.less
    │   │   │   ├── responsive.less
    │   │   │   └── toc.less
    │   │   ├── preview-img.less
    │   │   ├── responsive.less
    │   │   ├── style.js
    │   │   └── template.html
    │   ├── template
    │   │   ├── Content
    │   │   │   ├── Article.jsx
    │   │   │   ├── EditButton.jsx
    │   │   │   ├── MainContent.jsx
    │   │   │   └── index.jsx
    │   │   ├── Home
    │   │   │   ├── Banner.jsx
    │   │   │   ├── Page1.jsx
    │   │   │   ├── Page2.jsx
    │   │   │   ├── Page3.jsx
    │   │   │   ├── Page4.jsx
    │   │   │   ├── component
    │   │   │   │   ├── ImageLoadComp.jsx
    │   │   │   │   ├── Templates.jsx
    │   │   │   │   ├── WaterfallLayout.jsx
    │   │   │   │   └── data.json
    │   │   │   ├── index.jsx
    │   │   │   └── utils.jsx
    │   │   ├── Layout
    │   │   │   ├── Footer.jsx
    │   │   │   ├── Header.jsx
    │   │   │   ├── Layout.jsx
    │   │   │   ├── PhoneNav.jsx
    │   │   │   └── index.jsx
    │   │   ├── NotFound.jsx
    │   │   ├── Other
    │   │   │   ├── Cases.jsx
    │   │   │   ├── Download.jsx
    │   │   │   ├── cases.less
    │   │   │   └── download.less
    │   │   └── utils.jsx
    │   └── zh-CN.js
    └── utils.jsx
└── webpack.config.js


/.editorconfig:
--------------------------------------------------------------------------------
 1 | # http://editorconfig.org
 2 | root = true
 3 | 
 4 | [*]
 5 | indent_style = space
 6 | indent_size = 2
 7 | end_of_line = lf
 8 | charset = utf-8
 9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 | 
12 | [*.md]
13 | trim_trailing_whitespace = false
14 | 
15 | [Makefile]
16 | indent_style = tab


--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | _site
3 | 


--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 | 
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: ant-design-landing
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | custom: # Replace with a single custom sponsorship URL
9 | 


--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
 1 | *.iml
 2 | .idea/
 3 | .ipr
 4 | .iws
 5 | *~
 6 | ~*
 7 | *.diff
 8 | *.patch
 9 | *.bak
10 | .DS_Store
11 | Thumbs.db
12 | .project
13 | .*proj
14 | .svn/
15 | *.swp
16 | *.swo
17 | *.pyc
18 | *.pyo
19 | node_modules
20 | dist
21 | psd
22 | old
23 | _site
24 | .vscode


--------------------------------------------------------------------------------
/.stylelintrc:
--------------------------------------------------------------------------------
 1 | {
 2 |   "extends": "stylelint-config-standard",
 3 |   "rules": {
 4 |     "comment-empty-line-before": null,
 5 |     "declaration-empty-line-before": null,
 6 |     "function-comma-newline-after": null,
 7 |     "function-name-case": null,
 8 |     "function-parentheses-newline-inside": null,
 9 |     "function-max-empty-lines": null,
10 |     "function-whitespace-after": null,
11 |     "indentation": null,
12 |     "number-leading-zero": null,
13 |     "number-no-trailing-zeros": null,
14 |     "rule-empty-line-before": null,
15 |     "selector-combinator-space-after": null,
16 |     "selector-list-comma-newline-after": null,
17 |     "selector-pseudo-element-colon-notation": null,
18 |     "unit-no-unknown": null,
19 |     "value-list-max-empty-lines": null,
20 |     "no-descending-specificity": null
21 |   }
22 | }
23 | 


--------------------------------------------------------------------------------
/CNAME:
--------------------------------------------------------------------------------
1 | landing.ant.design


--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
 1 | MIT LICENSE
 2 | 
 3 | Copyright (c) 2015-present Alipay.com, https://www.alipay.com/
 4 | 
 5 | Permission is hereby granted, free of charge, to any person obtaining
 6 | a copy of this software and associated documentation files (the
 7 | "Software"), to deal in the Software without restriction, including
 8 | without limitation the rights to use, copy, modify, merge, publish,
 9 | distribute, sublicense, and/or sell copies of the Software, and to
10 | permit persons to whom the Software is furnished to do so, subject to
11 | the following conditions:
12 | 
13 | The above copyright notice and this permission notice shall be
14 | included in all copies or substantial portions of the Software.
15 | 
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 | 


--------------------------------------------------------------------------------
/README-zh_CN.md:
--------------------------------------------------------------------------------
 1 | <p align="center">
 2 |   <a href="http://landing.ant.design">
 3 |     <img width="150px" height="150px" src="https://gw.alipayobjects.com/zos/rmsportal/hSYPdZJwZeXAgfkktcEu.svg"/>
 4 |   </a>
 5 | </p>
 6 | <h1 align="center">Ant Design Landing</h1>
 7 | <div align="center">Ant Design 的 Landing Page 模板与设计指引</div>
 8 | 
 9 | <div align="center">
10 |   此网站的内容是从 <a href="https://motion.ant.design">Ant Motion</a> 模板区块中分离出来.
11 | </div>
12 | 
13 | <div align="center"><a href="./README.md">English</a> | 简体中文</div>
14 | 
15 | ## 什么是Landing?
16 | 
17 | Landing 是运用 Ant Motion 动效组件来搭建完成的页面模板,拥有丰富的各类首页模板,下载模板代码包,即可快速使用,也可使用首页编辑器,快速搭建一个属于你的专属首页。
18 | 
19 | ## 三大特性
20 | 
21 | - [设计指引](https://landing.ant.design/docs/introduce)
22 | - [源文件下载](https://landing.ant.design/docs/download)
23 | - [响应式布局](https://landing.ant.design/docs/guide/layout)
24 | 
25 | 
26 | ## 丰富的模板
27 | 
28 | 拥有丰富的各类首页模板提供下载。
29 | 
30 | [![](https://user-images.githubusercontent.com/6802825/47977555-ac77b080-e0f3-11e8-90f3-6aa04cce5351.jpg)](http://landing.ant.design)
31 | 
32 | ## 丰富的模块
33 | 
34 | 多样的模块,可灵活又快速的配置出你想要的首页模板。
35 | 
36 | 
37 | <div style="max-width: 600px">
38 | <img src="https://user-images.githubusercontent.com/6802825/47980280-ec459480-e101-11e8-8a94-1ada4ff61faa.jpg" width="100%">
39 | </div>
40 | 
41 | [进入编辑 😀](https://landing.ant.design/edit)
42 | 
43 | ## 脚手架里的示例
44 | 
45 | [生成首页在 dva-cli 里运行的例子](https://github.com/ant-motion/ant-motion-dva-cli-example)
46 | 
47 | [生成首页在 umi 里运行的例子](https://github.com/ant-motion/landing-umi-example)
48 | 
49 | 


--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
 1 | <p align="center">
 2 |   <a href="http://landing.ant.design">
 3 |     <img width="150px" height="150px" src="https://gw.alipayobjects.com/zos/rmsportal/hSYPdZJwZeXAgfkktcEu.svg"/>
 4 |   </a>
 5 | </p>
 6 | <h1 align="center">Ant Design Landing</h1>
 7 | 
 8 | <div align="center">
 9 |   
10 | Landing Pages of Ant Design System
11 | 
12 | [![Dependencies](https://img.shields.io/david/ant-design/ant-design-landing.svg)](https://david-dm.org/ant-design/ant-design-landing)
13 | [![DevDependencies](https://img.shields.io/david/dev/ant-design/ant-design-landing.svg)](https://david-dm.org/ant-design/ant-design-landing?type=dev)
14 | 
15 | </div>
16 | 
17 | <div align="center">English | <a href="./README-zh_CN.md">简体中文</a></div>
18 | 
19 | ## What is Landing?
20 | 
21 | Landing is a template built by Ant Motion's motion components. It has a rich homepage template, downloads the template code package, and can be used quickly. You can also use the editor to quickly build your own dedicated page.
22 | 
23 | <div align="center">
24 |   <a href="https://landing.ant.design/edit">Go Editing 📝</a>
25 | </div>
26 | 
27 | ## Features
28 | 
29 | - [Specifications](https://landing.ant.design/docs/introduce)
30 | - [Download](https://landing.ant.design/docs/download)
31 | - [Responsive](https://landing.ant.design/docs/guide/layout)
32 | 
33 | ## Templates
34 | 
35 | Has a wealth of various page templates to provide downloads.
36 | 
37 | [![](https://user-images.githubusercontent.com/6802825/47977555-ac77b080-e0f3-11e8-90f3-6aa04cce5351.jpg)](http://landing.ant.design)
38 | 
39 | ## Modules
40 | 
41 | Diverse modules, you can quickly and flexibly configure the page template you want.
42 | 
43 | <div style="max-width: 600px">
44 |   <img src="https://user-images.githubusercontent.com/6802825/47980280-ec459480-e101-11e8-8a94-1ada4ff61faa.jpg" width="100%">
45 | </div>
46 | 
47 | ## Example in scaffolding
48 | 
49 | - [dva-cli-example](https://github.com/ant-motion/ant-motion-dva-cli-example)
50 | - [umi-example](https://github.com/ant-motion/landing-umi-example)
51 | 


--------------------------------------------------------------------------------
/docs/cases.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | order: 3
 3 | title: 
 4 |   zh-CN: 实践案例
 5 |   en-US: Case
 6 | ---
 7 | 
 8 | 目前在外部也有许多产品实践,如果你的页面想在这里展现,[欢迎留言](https://github.com/ant-design/ant-motion/issues/30)。
 9 | 
10 | ```__react
11 | const casesData = [
12 |   { title: '蚂蚁科技官网', content: '蚂蚁金融科技,数字金融新原力', url: 'https://tech.antfin.com/', img: 'https://gw.alipayobjects.com/zos/rmsportal/vHQCWlZGnFSYiPOnbluw.jpg' },
13 |   { title: 'Ant Design官网', content: '服务于企业级产品的设计体系。', url: 'https://ant.design/', img: 'https://gw.alipayobjects.com/zos/rmsportal/yYQUqTuAxwHzSgGEGqkE.jpg' },
14 |   { title: '闪蝶', content: '提供专业的云上建站服务,满足不同行业的个性化需求', url: 'https://morpho.alipay.com/domain-intro', img: 'https://gw.alipayobjects.com/mdn/rms_ae7ad9/afts/img/A*YHa3S5yO6EsAAAAAAAAAAABkARQnAQ' },
15 |   { title: '智能物料设计平台', content: '花更少的时间做更专业的物料', url: 'https://chitu.alipay.com/', img: 'https://gw.alipayobjects.com/zos/rmsportal/aBwXHHpGMhIrnhUPUYVW.jpg' },
16 | ];
17 | 
18 | import React from 'react';
19 | import Demo from '../site/theme/template/Other/Cases';
20 | ReactDOM.render(<Demo data={casesData}/>, mountNode);
21 | ```


--------------------------------------------------------------------------------
/docs/download.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | order: 4
 3 | title: 
 4 |   zh-CN: 设计资源
 5 |   en-US: Download Sketch
 6 | ---
 7 | 
 8 | 这里提供以 Ant Design 设计规范完成的相关设计资源,更多设计资源正在整理和完善中。
 9 | 
10 | ```__react
11 | const downloadData = [
12 |   { title: '基础模板', content: '百搭型产品 Landing 模板,拼搭自已的专属产品 Landing Page', name: 'basic', url: 'https://github.com/ant-design/ant-design/releases/download/resource/Ant.Design.Landing.Template.sketch', img: 'https://gw.alipayobjects.com/mdn/rms_ae7ad9/afts/img/A*an5vQIKuBLgAAAAAAAAAAABkARQnAQ' },
13 |   { title: 'Ant Design Home 3.0', content: 'Ant Design 首页的源文件', name: 'antd', url: 'https://github.com/ant-design/ant-design/releases/download/resource/Ant.Design.home-3.0.sketch', img: 'https://gw.alipayobjects.com/zos/rmsportal/JhuPtNExKmpFjYKxBSZg.jpg' },
14 |   { title: 'Ant Design Landing', content: 'Ant Design Landing 首页的源文件', name: 'landing', url: 'https://github.com/ant-design/ant-design/releases/download/resource/Ant.Design.Landings.home.noImg.sketch', img: 'https://gw.alipayobjects.com/mdn/rms_ae7ad9/afts/img/A*Ke86RZXx9SkAAAAAAAAAAABjARQnAQ' },
15 | ];
16 | 
17 | import React from 'react';
18 | import Demo from '../site/theme/template/Other/Download';
19 | ReactDOM.render(<Demo data={downloadData}/>, mountNode);
20 | ```


--------------------------------------------------------------------------------
/docs/edit/video.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | order: 1
 3 | category:
 4 |   zh-CN: 编辑器教程
 5 |   en-US: Edit-help
 6 | title: 
 7 |   zh-CN: 视频教程
 8 |   en-US: Video help
 9 | ---
10 | 
11 | ```__react
12 | import React from 'react';
13 | function Demo(){
14 |   return (
15 |     <div style={{ padding: '16px', background: '#f2f4f5',  }}>
16 |       <video controls width="100%" style={{ display: 'block' }} src="https://gw.alipayobjects.com/os/rmsportal/SarwPFyWpqKjipcHkZFI.mp4" />
17 |     </div>
18 |   )
19 | }
20 | ReactDOM.render(<Demo />, mountNode);
21 | ```


--------------------------------------------------------------------------------
/docs/guide/banner.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | order: 3
 3 | category:
 4 |   zh-CN: 设计指引
 5 |   en-US: Guide
 6 | title: 
 7 |   zh-CN: Banner 首屏
 8 |   en-US: Banner
 9 | ---
10 | 
11 | Banner 是整个展示页面最重要的组成部分之一,一般介绍产品的名称和简介,并且体现整体产品的风格走向。
12 | 
13 | 高度为 750px 为例: Banner 一屏的设计尺寸为 1200\*750px,半屏的设计尺寸为 1200\*375px(多用于技术类的产品),主要由单屏和多屏滚动两种类型:
14 | 
15 | ## 单屏布局一
16 | 
17 | <img class="preview-img" align="right" alt="单屏布局一" description="" src="https://gw.alipayobjects.com/zos/rmsportal/doqiWMyWYcCPFBMrXJLn.jpg">
18 | 
19 | 1)全屏背景图;
20 | 
21 | 2)标题、文案和按钮与页面居中对齐;
22 | 
23 | ## 单屏布局二
24 | 
25 | <img class="preview-img" align="right" alt="单屏布局二" description="" src="https://gw.alipayobjects.com/zos/rmsportal/JOxMWSQxCWoKakcYZWcI.jpg">
26 | 
27 | 1)主图在页面左侧,标题、文案和按钮在页面右侧;
28 | 
29 | 2)建议文案和button部分左对齐;
30 | 
31 | ## 单屏布局三
32 | 
33 | <img class="preview-img" align="right" alt="单屏布局三" description="" src="https://gw.alipayobjects.com/zos/rmsportal/ZGjSLLsUrJFbFVrUxaft.jpg">
34 | 
35 | 1)主图在页面右侧,标题、文案和按钮在页面左侧;
36 | 
37 | 2)建议文案和button部分左对齐;
38 | 
39 | ## 单屏布局四
40 | 
41 | <img class="preview-img" align="right" alt="单屏布局四" description="" src="https://gw.alipayobjects.com/zos/rmsportal/YEneEHFzGvSNtGSFJALF.jpg">
42 | 
43 | 1)主图在页面下方;
44 | 
45 | 2)标题、文案和button与页面居中对齐;
46 | 
47 | ## 多屏滚动类
48 | 
49 | <img class="preview-img" align="right" alt="多屏滚动类" description="" src="https://gw.alipayobjects.com/zos/rmsportal/rtlntsHdPmorumOLIHVY.jpg">
50 | 
51 | 1)多屏Headers组合,底部有走马灯滚动轮播;
52 | 
53 | 2)建议滚动屏不超过5个;
54 | 
55 | 
56 | ## 半屏类型
57 | 
58 | <img class="preview-img" align="right" alt="半屏类型" description="" src="https://gw.alipayobjects.com/zos/rmsportal/ItuPxLqTgqgEhMaxexvp.jpg">
59 | 
60 | 1)半屏的设计尺寸为1200*375px;
61 | 
62 | 2)排版方式和类别与整屏的相同(在此列举其中一种);


--------------------------------------------------------------------------------
/docs/guide/content.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | order: 4
 3 | category:
 4 |   zh-CN: 设计指引
 5 |   en-US: Guide
 6 | title: 
 7 |   zh-CN: 内容区块
 8 |   en-US: Content
 9 | ---
10 | 
11 | 内容页一般用来介绍产品的功能、特性以及相关信息。展示型页面中可选择添加内容页(或多个内容页组合),也可以选择不添加。
12 | 每一屏的最小设计尺寸为 1200*375px,可以自由灵活的选择多种模板进行拼接。
13 | 
14 | > 我们将分点阐述、合作伙伴/客户、价格表、团队展示、联系我们等合称为内容区块。
15 | 
16 | 
17 | ## 全屏式
18 | 
19 | <img class="preview-img" align="right" alt="全屏式" description="" src="https://gw.alipayobjects.com/zos/rmsportal/gixQJkEyeexiuExLyvFW.jpg">
20 | 
21 | 1)全屏背景图;
22 | 
23 | 2)标题、文案和按钮与页面居中对齐;
24 | 
25 | ## 两栏式1
26 | 
27 | <img class="preview-img" align="right" alt="两栏式1" description="" src="https://gw.alipayobjects.com/zos/rmsportal/YNEYwjpXrQAXfTFjVoBE.png">
28 | 
29 | 1)主介绍图在页面左侧,标题文案在页面右侧;
30 | 
31 | 2)标题和文案内容左对齐
32 | 
33 | ## 两栏式2
34 | 
35 | <img class="preview-img" align="right" alt="两栏式2" description="" src="https://gw.alipayobjects.com/zos/rmsportal/pKbGyGLZKkyKlIDylGLL.png">
36 | 
37 | 1)主介绍图在页面右侧,标题文案在页面左侧;
38 | 
39 | 2)标题和文案内容左对齐;
40 | 
41 | ## 单行多栏式
42 | 
43 | <img class="preview-img" align="right" alt="单行多栏式" description="" src="https://gw.alipayobjects.com/zos/rmsportal/zwHaRpBbcrtKJmRCBBho.png">
44 | 
45 | 1)内容区块按栅格均分;
46 | 
47 | 2)一行可放置3~4个并列区块(建议不超过4个);
48 | 
49 | ## 双行多栏式1
50 | 
51 | <img class="preview-img" align="right" alt="双行多栏式1" description="" src="https://gw.alipayobjects.com/zos/rmsportal/AaQRpekusPmFNjxigIwJ.png">
52 | 
53 | 1)内容区块按栅格均分;
54 | 
55 | 2)一行可放置2~3个并列区块(建议不超过3个);
56 | 
57 | ## 双行多栏式2
58 | 
59 | <img class="preview-img" align="right" alt="双行多栏式2" description="" src="https://gw.alipayobjects.com/zos/rmsportal/ViVQULPluvShAolReqME.png">
60 | 
61 | 1)内容区块按栅格均分;
62 | 
63 | 2)一行可放置3~5个并列内容区(建议不超过5个);
64 | 
65 | 
66 | ## 半屏设计模板
67 | 
68 | <img class="preview-img" align="right" alt="半屏设计模板" description="" src="https://gw.alipayobjects.com/zos/rmsportal/yWBvgWQNtuTBDjcalEJe.png">
69 | 
70 | 1)半屏的设计尺寸为 1200*375px;
71 | 
72 | 2)排版方式和类别与整屏的相同(再次列举其中两种));
73 | 
74 | <img class="preview-img" align="right" alt="半屏设计模板" description="" src="https://gw.alipayobjects.com/zos/rmsportal/NKvJFXcmOrGkIMSJHZJk.png">


--------------------------------------------------------------------------------
/docs/guide/examples.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | order: 5
 3 | category:
 4 |   zh-CN: 设计指引
 5 |   en-US: Guide
 6 | title: 
 7 |   zh-CN: 组合示例
 8 |   en-US: Examples
 9 | ---
10 | 
11 | ## 示例
12 | 
13 | 我们将以上模板整合出三个模板,以供参考:
14 | 
15 | <div class="examples-wrapper">
16 |   <div class="examples-img">
17 |     <img width="100%" src="https://gw.alipayobjects.com/zos/rmsportal/aniQEcLzAFArUbkPYkyQ.png">
18 |     <p>示例1</p>
19 |   </div>
20 |   <div class="examples-img">
21 |     <img width="100%" src="https://gw.alipayobjects.com/zos/rmsportal/HCsgacmIIXZqvicZJDDZ.png">
22 |     <p>示例2</p>
23 |   </div>
24 |   <div class="examples-img">
25 |     <img width="100%" src="https://gw.alipayobjects.com/zos/rmsportal/ZrFKiApOqmIjSuYsHrpr.png">
26 |     <p>示例3</p>
27 |   </div>
28 | </div>
29 | 
30 | <style>
31 |   .examples-wrapper{
32 |     width: calc(100% + 48px);
33 |     margin-left: -24px;
34 |   }
35 |   .examples-img {
36 |     width: 33%;
37 |     display: inline-block;
38 |     padding: 0 24px;
39 |     vertical-align: top;
40 |   }
41 |   .examples-img p {
42 |     text-align: center;
43 |     margin: auto;
44 |   }
45 |   @media only screen and (max-width: 767.99px) {
46 |     .examples-wrapper{
47 |       width: 100%;
48 |       margin: auto;
49 |     }
50 |     .examples-img { 
51 |       width: 100%;
52 |       padding: 0;
53 |       margin-bottom: 16px;
54 |     }
55 |   }
56 | </style>


--------------------------------------------------------------------------------
/docs/guide/header-footer.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | order: 2
 3 | category:
 4 |   zh-CN: 设计指引
 5 |   en-US: Guide
 6 | title: 
 7 |   zh-CN: 页头与页尾
 8 |   en-US: Header and Footer
 9 | ---
10 | 
11 | 页头承载的是品牌信息与整个网站的结构信息,明确的告知我们网站里最主要的几块内容。
12 | 
13 | 页尾则是一个网站的落款,提供的相关的产品信息、友情链接与版权信息。
14 | 
15 | ## 顶部页头导航
16 | 
17 | 顶部导航高度为 64px, 主要展示 logo、基本导航内容、用户相关信息。 我们提供了三种示例供调选:
18 | 
19 | ### 基本型页头导航
20 | 
21 | <img class="preview-img" align="right" alt="基本型页头导航" description="" src="https://gw.alipayobjects.com/zos/rmsportal/mbmfZSnXKIPOUBhfQQIs.png">
22 | 
23 | 由 logo 与基本导航内容组成。
24 | 
25 | ### 用户信息页头导航
26 | 
27 | <img class="preview-img" align="right" alt="用户信息页头导航" description="" src="https://gw.alipayobjects.com/zos/rmsportal/joIcEcNcOorilRaACobU.png">
28 | 
29 | 如果有登录信息或其它信息需要在导航展现时,我们可以在导航基本内容右侧添加其它信息。
30 | 
31 | ### 单 logo 页头
32 | 
33 | <img class="preview-img" align="right" alt="单 logo 页头" description="" src="https://gw.alipayobjects.com/zos/rmsportal/arCBcBBCQEgsEGSCsKfs.png">
34 | 
35 | 如果不需要导航时,我们建议将背景设为透明,将 logo 融入首屏里。此处只展示类型。
36 | 
37 | ## 页脚
38 | 
39 | Footer(页脚)作为展示页中也非常重要的一部分,在页面的最底部,包含的信息内容为:实用导航,语言选择,社交链接,帮助和支持,版权和隐私声明等。
40 | 
41 | ### 单版权信息
42 | 
43 | <img class="preview-img" align="right" alt="单版权信息" description="" src="https://gw.alipayobjects.com/zos/rmsportal/SMzRpciAJCazFxVEazLO.png">
44 | 
45 | 页尾不需要任何信息内容时。
46 | 
47 | ### 内容较少
48 | 
49 | <img class="preview-img" align="right" alt="内容较少" description="" src="https://gw.alipayobjects.com/zos/rmsportal/pjXwqSImebEPYqQrXnBH.png">
50 | 
51 | 页尾内容比较少时。
52 | 
53 | 
54 | ### 内容较多
55 | 
56 | <img class="preview-img" align="right" alt="内容较多" description="" src="https://gw.alipayobjects.com/zos/rmsportal/YyhadUOedrCfjGRCmfqP.png">
57 | 
58 | 页尾内容比较多时。


--------------------------------------------------------------------------------
/docs/guide/layout.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | order: 1
 3 | category:
 4 |   zh-CN: 设计指引
 5 |   en-US: Guide
 6 | title: 
 7 |   zh-CN: 布局
 8 |   en-US: Layout
 9 | ---
10 | 
11 | Ant Design 目前提供了两套布局方案: [Layout](https://ant.design/components/layout-cn/) 和 [Grid](https://ant.design/components/grid-cn/), 同样 Landing 的整体布局也是以 8 的倍数来计算。我们以页面宽度来做整体布局,提供以下两种类型:
12 | 
13 | ---
14 | 
15 | ## 百分比类型
16 | 
17 | <img class="preview-img" align="right" alt="100% 类型示例" description="两边的距离为 4%" src="https://gw.alipayobjects.com/zos/rmsportal/krTDyBweacvtOdScbhVq.jpg">
18 | 
19 | 100% 类型,内容的宽度为 92%, 左右边距为 4%; 
20 | 
21 | 需要注意: 在 banner 使用百分比类型布局后,导航必需也使用百分比类型;
22 | 
23 | 
24 | ---
25 | 
26 | ## 像素类型
27 | 
28 | <img class="preview-img" align="right" alt="像素类型示例" description="两边的距离为 24px" src="https://gw.alipayobjects.com/zos/rmsportal/bWJWBtBklmyOlISZyOFi.jpg">
29 | 
30 | 以 1152px 为最大宽度为例,为在响应式方面保证更好的预览效果,我们在最大宽度外面增加了 24px 的边距, 避免屏幕尺寸在低于 1152px 的时候内容贴边, 于是需要将内容区域的最大宽度改为 1200px,再增加 24px 的内边距 `padding: 0 24px`。
31 | 


--------------------------------------------------------------------------------
/docs/guide/type.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | order: 0
 3 | category:
 4 |   zh-CN: 设计指引
 5 |   en-US: Guide
 6 | title: 
 7 |   zh-CN: 类型
 8 |   en-US: Type
 9 | ---
10 | 
11 | 展示类页面(Display Page)一般是指当用户进入某个网站时浏览到的第一个页面,也可以当作着陆页(Landing Page)来吸引用户的注意。在此,我们归纳整理了几种最常见的展示类模板,可以用于灵活的搭配组合。
12 | 
13 | 我们对 Landing Page 做了以下两种类型:
14 | 
15 | ---
16 | 
17 | ## 分步浏览
18 | 
19 | <img class="preview-img" align="right" alt="分步浏览示例" description="包含:USP (产品 logo,名称,slogan ),CTA(登录/注册栏,行动按钮),导航,分点阐述,客户展示,页尾。" src="https://gw.alipayobjects.com/zos/rmsportal/VVtazyoxkkGjvjySprqS.png">
20 | 
21 | 分步浏览展示产品的主要信息,通过精彩的视觉,动效,使用户增加产品认知,提升使用兴趣,提供试用机制,进而达到转化目的
22 | 适用产品范围较广。
23 | 
24 | 规范:
25 | 
26 | 1. 分点阐述:数量不宜过多,建议3-5条。
27 | 
28 | 2. CTA:此为转化的重要环节,一定要做的显著,且随时随地都可触达且明确告知用户付出与收获。
29 | 
30 | 3. 客户证言:用真实信息,建议有真实个人或公司照片。如非有名客户,建议具体说明帮他解决的问题和使用体验。
31 | 
32 | ---
33 | 
34 | ## 邀请注册
35 | 
36 | <img class="preview-img" align="right" alt="邀请注册示例" description="USP (产品 logo,名称,slogan ),媒体展示,CTA(登录/注册栏),导航,页尾。。" src="https://gw.alipayobjects.com/zos/rmsportal/QAdOyxYZJCCQFazUXhus.jpg">
37 | 
38 | 一屏之内展示出产品卖点或价值主张,突出显示 CTA。主要目的在于快速留住游客,是指直接转化为使用者。
39 | 
40 | 常用于功能较为单一,属于社交型、服务型等需要获取用户信息,建立用户联系的产品。
41 | 
42 | 规范:
43 | 
44 | 1. USP:一句话阐述核心竞争力,字体较大,不宜过长,力求简单好记。
45 | 
46 | 2. 媒体展示:与 USP 内容相关。如用视频,长度建议1~3分钟。
47 | 
48 | 3. CTA 登录/注册:尽量优化注册流程,或提供第三方社交账号登录。
49 | 
50 | 4. 不建议在注册前就为用户提供较多的价值和内容。


--------------------------------------------------------------------------------
/docs/introduce.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | order: 0
 3 | title: 
 4 |   zh-CN: 介绍
 5 |   en-US: Introduce
 6 | ---
 7 | 
 8 | 
 9 | 
10 | <div class="file-logo">
11 |   <div class="ant-logo">
12 |    <img src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg" height="100%"/>
13 |   </div>
14 |   <span>+</span>
15 |   <div class="landing-logo">
16 |     <img src="https://gw.alipayobjects.com/zos/rmsportal/SVDdpZEbAlWBFuRGIIIL.svg" height="100%">
17 |   </div>
18 | </div>
19 | 
20 | Ant Design Landing 是针对产品首页的解决方案,我们秉承 [Ant Design](https://ant.design) 的 [设计价值观](https://ant.design/docs/spec/introduce-cn),延用 [Ant Design](https://ant.design) 的 [设计原则](http://ant.design/docs/spec/proximity-cn),可以快速搭建出你想要的首页,进一步提升你的工作效率。随着『设计者』的不断反馈,我们将持续迭代,逐步沉淀和总结出更多首页模块的代码实现,阐述首页(Landing page)的最佳实践,也十分期待你的参与和共建。
21 | 
22 | ## 作用
23 | 
24 | - 激发用户的探索兴趣,继续深入访问。
25 | - 引导用户直接购买产品或服务。
26 | - 用户通过提供个人信息或注册来交换一些试用与服务。
27 | - 让用户分享、评论或产生其它一些互动。
28 | 
29 | ## 构成元素
30 | 
31 | - 全局导航
32 | - 首屏阐述 Banner:
33 |   > - USP(unique selling proposition) 产品卖点或价值主张: 产品 logo,名称,slogan, 媒体展示(背景,图片,视频)。
34 |   > - CTA(Call-To-Action): 行动按钮,登录/ 注册。
35 | - 分点阐述: 
36 |   > - 产品特色/优势。
37 |   > - 使用方法 + 核心功能 + 解决方案
38 | - 合作伙伴/客户: 成功案例,客户展示,客户证言。
39 | - 价格表
40 | - 团队展示
41 | - 联系我们
42 | - 全局页脚
43 | 
44 | ### 动效
45 | 
46 | 延用 [Ant Motion](https://motion.ant.design) 动画组件与规范,提供基本的动画组件与 banner 切换效果,以 `scroll-anim` 组件为基本动画框架,随滚动来完成页面的进出场效果。
47 | 
48 | - [单元素动效执行组件](https://motion.ant.design/components/tween-one)
49 | - [样式进出场组件](https://motion.ant.design/components/animate)
50 | - [队列进出场组件](https://motion.ant.design/components/queue-anim)
51 | - [文字动效组件](https://motion.ant.design/components/texty)
52 | - [随滚动执行效果组件](https://motion.ant.design/components/scroll-anim)
53 | - [Banner 切换效果组件](https://motion.ant.design/components/banner-anim)
54 | 
55 | ## 设计资源
56 | 
57 | 我们提供完善的设计规范、最佳实践和设计资源文件 Sketch,来帮助业务快速设计出高质量的产品原型。
58 | 
59 | 
60 | ## 谁在使用
61 | 
62 | 目前 Ant Design 旗下产品全部使用 Landing 搭建,如果你和你的组织使用了这个产品,欢迎到 Ant Design Landing Users 留言。
63 | 
64 | 
65 | ### For 设计者
66 | 
67 | 如果你是产品或设计师,你可以找到相关模板或各模块的 Sketch 设计资源,大幅度提升设计效率和沟通效率。
68 | 
69 | ### For 开发者
70 | 
71 | 如果你是工程师,只需将你下载的以『Home』为名的文件包替换掉你的项目里的首页即可,具体介绍请查看 [使用文档](/docs/use/getting-started)。
72 | 
73 | 
74 | ## 如何贡献
75 | 
76 | 我们欢迎任何形式的贡献,有任何建议或意见,请给我们 [提问]()。
77 | 


--------------------------------------------------------------------------------
/docs/use/dumi.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | order: 2
 3 | category:
 4 |   zh-CN: 使用教程
 5 |   en-US: Tutorial
 6 | title: 
 7 |   zh-CN: dumi 里使用
 8 |   en-US: Use in dumi
 9 | ---
10 | 
11 | [dumi](https://d.umijs.org/) 基于 [Umi](https://umijs.org/)、为组件开发场景而生的文档工具
12 | 
13 | 使用 demo 地址请查看 [dumi-example](https://github.com/ant-motion/landing-dumi-example);
14 | 
15 | ## 文件路径
16 | 
17 | 我们首先初始化一个站点模式的组件库开发脚手架, 如果没装安 dumi 的,请先查看 dumi 的[轻松上手](https://d.umijs.org/#%E8%BD%BB%E6%9D%BE%E4%B8%8A%E6%89%8B)
18 | ```
19 | $ npx @umijs/create-dumi-lib --site
20 | ```
21 | 安装完后,再将 Home 复制到 docs 里,我们的文件目录为:
22 | 
23 | ```
24 | │── docs
25 | + │── Home 
26 | | └── index.md
27 | │── src 
28 | │ │── Foo
29 | │ │── index.ts
30 | │ └── ...
31 | │── package.json
32 | │── ...
33 | ```
34 | 
35 | ## 安装依赖
36 | 
37 | 安装 dumi 里的依赖: `npm install`;
38 | 
39 | 我们组件的依赖详细参考[开始使用里的安装依赖](docs/use/getting-started#安装依赖);
40 | 
41 | ## 修改首页
42 | 
43 | 更改 index.md, 删掉全部内容,增加 gapless: true, 再在下面添加 code, 最后的 index.md 如下:
44 | 
45 | ```
46 | ---
47 | gapless: true
48 | ---
49 | 
50 | <code src="./Home/index.jsx" inline />
51 | ```
52 | ## 删除 Home 里的 md 文件
53 | 
54 | 将 documentation.md 从文件包里删除;
55 | 
56 | ## 完成
57 | 
58 | 完成以上步骤之后,我们再启动 `npm start` 即可查看在 landing 上下载的模板。
59 | 


--------------------------------------------------------------------------------
/docs/use/dva-cli.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | order: 3
 3 | category:
 4 |   zh-CN: 使用教程
 5 |   en-US: Tutorial
 6 | title: 
 7 |   zh-CN: dva-cli 里使用
 8 |   en-US: Use in dva
 9 | ---
10 | [dva](https://github.com/dvajs/dva) 脚手架为 ant design 提供的基于 redux、redux-saga 和 react-router 比较完善的轻量级前端框架,具体教程[请查看](https://github.com/sorrycc/blog/issues/18)。
11 | 
12 | 如何使用 demo 地址请查看 [dva-cli-example](https://github.com/ant-motion/ant-motion-dva-cli-example);
13 | 
14 | 基本配置请查看 [开始使用](docs/use/getting-started);
15 | 
16 | ## 文件路径
17 | 
18 | [dva-cli](https://github.com/dvajs/dva-cli) 脚手架的文件目录为 `src/routes`, 首先我们需要将下载的 Home 文件包直接复制到 routes 文件夹下。
19 | 
20 | ## 修改路由
21 | 
22 | 复制完成后,我们需要将主页入口修改成以上复制的文件目录。
23 | 
24 | ```jsx
25 | import IndexPage from './routes/Home';
26 | ```
27 | 
28 | ## CSS Modules
29 | 
30 | dva 默认使用了 `css-modules`,同样我们提供了两套解决方案。
31 | 
32 | ### 关闭 css-modules
33 | 
34 | 如果你当前项目为新项目,且对 `css-modules` 并不是太了解,可以选择关闭 `css-modules`,只需要在 `.roadhogrc` 文件里加上 `"disableCSSModules": true` 即可。
35 | ```json
36 | {
37 |   "entry": "src/index.js",
38 | +  "disableCSSModules": true, // 加在此处
39 |   "env": {
40 |     "development": {
41 |       "extraBabelPlugins": [
42 |         "dva-hmr",
43 |         "transform-runtime"
44 |       ]
45 |     },
46 |     "production": {
47 |       "extraBabelPlugins": [
48 |         "transform-runtime"
49 |       ]
50 |     }
51 |   },
52 | }
53 | ```
54 | 
55 | ### 使用 global
56 | 
57 | 使用 `css-modules` 的 `global`, 在 `index.less` 里添加 `:global`, 将样式不作转换, `global` 具体使用[请查看开始使用](/docs/use/getting-started#样式)。
58 | 
59 | 
60 | ## 按需加载
61 | 
62 | dva 里使用 `babel-plugin-import` 我们只需要 `.roadhogrc` 文件里添加 `["import", { "libraryName": "antd", "style": true }]` 即可。
63 | 
64 | ```json
65 | 
66 | {
67 |   "entry": "src/index.js",
68 |   "env": {
69 |     "development": {
70 |       "extraBabelPlugins": [
71 |         "dva-hmr",
72 |         "transform-runtime",
73 |         ["import", { "libraryName": "antd", "style": true }]
74 |       ]
75 |     },
76 |     "production": {
77 |       "extraBabelPlugins": [
78 |         "transform-runtime",
79 |         ["import", { "libraryName": "antd", "style": true }]
80 |       ]
81 |     }
82 |   },
83 | }
84 | ```
85 | 
86 | ## 完成
87 | 
88 | 完成以上频骤之后,我们再启动 `npm start` 即可查看在 landing 上下载的模板。


--------------------------------------------------------------------------------
/docs/use/pro.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | order: 4
 3 | category:
 4 |   zh-CN: 使用教程
 5 |   en-US: Tutorial
 6 | title: 
 7 |   zh-CN: pro 里使用
 8 |   en-US: Use in pro
 9 | ---
10 | 
11 | [Ant Design pro](https://pro.ant.design) 是 Ant Design 推出的一个开箱即用的中台前端/设计解决方案。
12 | 
13 | ## 文件路径
14 | 
15 | [Ant Design pro v2.x](https://pro.ant.design) 使用的为 umi 脚手架,文件目录同样为 `src/pages`, 首先我们需要将下载的 Home 文件包直接复制到 `pages` 文件夹下。
16 | 
17 | ## 修改路由
18 | 
19 | 文件目录:  `config/router.config.js`;
20 | 
21 | 修改 `dashboard` 的路由, 增加 `Home` 路由;
22 | 
23 | ```js
24 | export default [
25 | + { path: '/', component: './Home' }, // 增加 Home 路由
26 |   // user
27 |   {
28 |     path: '/user',
29 |     ...
30 |   },
31 |   // app
32 |   {
33 | -   path: '/',
34 | +   path: '/dashboard', // 更改 dashboard 路由;
35 |     component: '../layouts/BasicLayout',
36 |     Routes: ['src/pages/Authorized'],
37 |     authority: ['admin', 'user'],
38 |     ...
39 |   },
40 | ];
41 | ```
42 | 
43 | ## 安装依赖
44 | 
45 | 详细参考[开始使用里的安装依赖](docs/use/getting-started#安装依赖);
46 | 
47 | ## CSS Modules
48 | 
49 | 多方案请查看 [umi 里使用的 css module](/docs/use/umi#CSS-Modules);
50 | 
51 | 这里推荐使用 css-module 的 global;
52 | 
53 | antMotionStyle.less 如下
54 | 
55 | ```
56 | :global {
57 |   @import './common.less';
58 |   @import './custom.less';
59 |   @import './content.less';
60 |   @import './nav0.less';
61 |   @import './banner0.less';
62 |   ...
63 | }
64 | ```
65 | 
66 | ## 暂时先删除换肤插件
67 | 
68 | 由于换肤插件需要重新 build 全部的 less, 暂时不支持 landing 的 less,所以我们先暂时删除换肤插件。
69 | 
70 | 文件目录:`config/config.js`;
71 | 
72 | 删除 `webpackPlugin` 相关的代码:
73 | ```jsx
74 | // https://umijs.org/config/
75 | import os from 'os';
76 | import pageRoutes from './router.config';
77 | - import webpackPlugin from './plugin.config';
78 | import defaultSettings from '../src/defaultSettings';
79 | 
80 | ...
81 | 
82 | export default {
83 |   // add for transfer to umi
84 |   ...
85 |   manifest: {
86 |     basePath: '/',
87 |   },
88 | 
89 | - chainWebpack: webpackPlugin,
90 | };
91 | 
92 | ```


--------------------------------------------------------------------------------
/documentation.md:
--------------------------------------------------------------------------------
1 | # 如何使用:
2 | 
3 | - umi 里如何使用[请查看](https://landing.ant.design/docs/use/umi)。
4 | - 其它脚手架使用[请查看](https://landing.ant.design/docs/use/getting-started)。
5 | 


--------------------------------------------------------------------------------
/index.text:
--------------------------------------------------------------------------------
 1 | /* eslint no-undef: 0 */
 2 | /* eslint arrow-parens: 0 */
 3 | import React from 'react';
 4 | import { enquireScreen } from 'enquire-js';
 5 | &scrollAnim&
 6 | &import&
 7 | &dataSource&
 8 | import './less/antMotionStyle.less';
 9 | 
10 | let isMobile;
11 | enquireScreen((b) => {
12 |   isMobile = b;
13 | });
14 | 
15 | const { location = {} } = typeof window !== 'undefined' ? window : {};
16 | 
17 | export default class Home extends React.Component {
18 |   constructor(props) {
19 |     super(props);
20 |     this.state = {
21 |       isMobile,
22 |       show: !location.port,// 如果不是 dva 2.0 请删除
23 |     };
24 |   }
25 | 
26 |   componentDidMount() {
27 |     &scrollScreen-pragma&
28 |     // 适配手机屏幕;
29 |     enquireScreen((b) => {
30 |       this.setState({ isMobile: !!b });
31 |     });
32 |     // dva 2.0 样式在组件渲染之后动态加载,导致滚动组件不生效;线上不影响;
33 |     /* 如果不是 dva 2.0 请删除 start */
34 |     if (location.port) {
35 |       // 样式 build 时间在 200-300ms 之间;
36 |       setTimeout(() => {
37 |         this.setState({
38 |           show: true,
39 |         });
40 |         &scrollScreen&
41 |       }, 500);
42 |     }
43 |     /* 如果不是 dva 2.0 请删除 end */
44 |   }
45 | 
46 |   render() {
47 |     &children&
48 |     return (
49 |       <div className="templates-wrapper" ref={(d) => { this.dom = d; }}>
50 |         {/* 如果不是 dva 2.0 替换成 {children} start */}
51 |         {this.state.show && children}
52 |         {/* 如果不是 dva 2.0 替换成 {children} end */}
53 |       </div>
54 |     );
55 |   }
56 | }
57 | 


--------------------------------------------------------------------------------
/prettier/install-service-worker.js:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 | /* eslint-env browser */
 4 | 
 5 | if ('serviceWorker' in navigator) {
 6 |   navigator.serviceWorker.register('/service-worker.js', {
 7 |     scope: '/edit/',
 8 |   });
 9 | }
10 | 


--------------------------------------------------------------------------------
/prettier/service-worker.js:
--------------------------------------------------------------------------------
 1 | /* eslint-env serviceworker */
 2 | /* global toolbox */
 3 | 
 4 | 
 5 | importScripts('lib/sw-toolbox.js');
 6 | 
 7 | toolbox.precache([
 8 |   // Scripts
 9 |   'lib/index.js',
10 |   'lib/parser-babylon.js',
11 |   'lib/parser-postcss.js',
12 |   'lib/parser-flow.js',
13 |   'lib/parser-glimmer.js',
14 |   'lib/parser-graphql.js',
15 |   'lib/sw-toolbox.js',
16 | ]);
17 | 
18 | // Default to hit the cache only if there's a network error
19 | toolbox.router.default = toolbox.networkFirst;
20 | 
21 | // For scripts, stylesheets and images, we can use the "fastest" strategy
22 | // This means you need to reload twice to get new changes
23 | toolbox.router.get(/\.(js|css|png|svg)$/, toolbox.fastest);
24 | 


--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 |   "extends": [
3 |     "config:base"
4 |   ]
5 | }
6 | 


--------------------------------------------------------------------------------
/site/bisheng.edit.config.js:
--------------------------------------------------------------------------------
 1 | const commonConfig = require('./bisheng.common.config');
 2 | 
 3 | module.exports = { source: {},
 4 |   output: './_site/edit',
 5 |   root: '/edit/',
 6 |   entryName: 'edit',
 7 |   theme: './site/edit',
 8 |   htmlTemplate: './site/edit/static/index.html',
 9 |   port: 7112,
10 |   themeConfig: {
11 |   },
12 |   ...commonConfig };
13 | 


--------------------------------------------------------------------------------
/site/bisheng.index.config.js:
--------------------------------------------------------------------------------
 1 | const commonConfig = require('./bisheng.common.config');
 2 | 
 3 | module.exports = { port: 7111,
 4 |   root: '/',
 5 |   source: {
 6 |     docs: './docs',
 7 |   },
 8 |   theme: './site/theme',
 9 |   htmlTemplate: './site/theme/static/template.html',
10 |   themeConfig: {
11 |     root: '/',
12 |     categoryOrder: {
13 |       介绍: 0,
14 |       设计指引: 1,
15 |       编辑器教程: 2,
16 |       使用教程: 3,
17 |       实践案例: 4,
18 |       设计资源: 5,
19 |       Introduce: 0,
20 |       Guide: 1,
21 |       'Edit-help': 2,
22 |       Tutorial: 3,
23 |     },
24 |   },
25 |   ...commonConfig };
26 | 


--------------------------------------------------------------------------------
/site/bisheng.templates.config.js:
--------------------------------------------------------------------------------
 1 | const commonConfig = require('./bisheng.common.config');
 2 | 
 3 | module.exports = { source: {},
 4 |   output: './_site/templates',
 5 |   root: '/templates/',
 6 |   entryName: 'templates',
 7 |   theme: './site/templates',
 8 |   htmlTemplate: './site/templates/static/index.html',
 9 |   port: 7113,
10 |   themeConfig: {
11 |   },
12 |   ...commonConfig };
13 | 


--------------------------------------------------------------------------------
/site/edit/index.js:
--------------------------------------------------------------------------------
 1 | module.exports = {
 2 |   routes:
 3 |   {
 4 |     path: '/',
 5 |     component: './template/index',
 6 |     childRoutes: [
 7 |       {
 8 |         path: 'index-cn',
 9 |         component: './template/index',
10 |       },
11 |     ],
12 |   },
13 | };
14 | 


--------------------------------------------------------------------------------
/site/edit/static/banner-slide.less:
--------------------------------------------------------------------------------
 1 | .banner-slide {
 2 |   background: fade(@primary-color, 55);
 3 |   border-radius: 4px 4px 0 0;
 4 |   overflow: hidden;
 5 |   display: inline-block;
 6 |   padding: 4px 8px 0;
 7 |   &-wrapper {
 8 |     position: absolute;
 9 |     bottom: 0;
10 |     display: flex;
11 |     width: 100%;
12 |     justify-content: center;
13 |     cursor: auto;
14 |     opacity: 0;
15 |   }
16 |   .ant-pagination {
17 |     display: inline-block;
18 |     margin-right: 8px;
19 |   }
20 |   & .ant-pagination.mini .ant-pagination-item-link {
21 |     border-radius: 100%;
22 |     background: @primary-color;
23 |     color: @edit-text-color;
24 |     &:hover,
25 |     &:focus {
26 |       background: #597ef7;
27 |     }
28 |     &:active {
29 |       background: #1d39c4;
30 |     }
31 |   }
32 |   .ant-pagination-disabled a {
33 |     background: rgb(218, 218, 218) !important;
34 |     color: rgba(0, 0, 0, 0.25) !important;
35 |   }
36 |   .ant-pagination .ant-pagination-simple-pager {
37 |     color: @edit-text-color;
38 |     margin: 0 8px;
39 |     input {
40 |       background: transparent;
41 |       padding: 0;
42 |       margin: 0;
43 |       &:hover {
44 |         border-color: @edit-text-color;
45 |       }
46 |     }
47 |     .ant-pagination-slash {
48 |       margin: 0 5px;
49 |     }
50 |   }
51 |   .ant-btn {
52 |     vertical-align: top;
53 |   }
54 | }
55 | 
56 | .manage-wrapper {
57 |   width: 300px;
58 |   .ant-popover-inner-content {
59 |     padding: 12px 0;
60 |     position: relative;
61 |   }
62 |   .manage-button {
63 |     text-align: center;
64 |     margin: 16px 0;
65 |   }
66 | }
67 | 
68 | .list-drag-selected {
69 |   box-shadow: 0 6px 10px rgba(0, 0, 0, 0.25);
70 |   transform: scale(1.1) !important;
71 | }
72 | 


--------------------------------------------------------------------------------
/site/edit/static/common.less:
--------------------------------------------------------------------------------
 1 | html,
 2 | body {
 3 |   background: #fff;
 4 |   color: @edit-text-color;
 5 | }
 6 | 
 7 | body,
 8 | div,
 9 | dl,
10 | dt,
11 | dd,
12 | ul,
13 | ol,
14 | li,
15 | h1,
16 | h2,
17 | h3,
18 | h4,
19 | h5,
20 | h6 {
21 |   margin: 0;
22 |   padding: 0;
23 | }
24 | 
25 | .gu-mirror {
26 |   position: fixed !important;
27 |   margin: 0 !important;
28 |   z-index: 9999 !important;
29 |   opacity: 0.8;
30 |   background: fade(@primary-color, 70);
31 |   pointer-events: none;
32 | 
33 |   >div,
34 |   >p {
35 |     display: none;
36 |   }
37 | 
38 |   >.img {
39 |     display: block;
40 |   }
41 | 
42 |   &.img-wrapper {
43 |     background: none;
44 |   }
45 | }
46 | 
47 | .gu-hide {
48 |   display: none !important;
49 | }
50 | 
51 | .gu-unselectable {
52 |   -webkit-user-select: none !important;
53 |   -moz-user-select: none !important;
54 |   -ms-user-select: none !important;
55 |   user-select: none !important;
56 | }
57 | 
58 | .gu-transit {
59 |   background: fade(@primary-color, 35);
60 | 
61 |   >p {
62 |     display: none;
63 |   }
64 | }
65 | 
66 | .placeholder {
67 |   background: @primary-color;
68 |   text-align: center;
69 |   color: @edit-text-color;
70 |   font-size: 12px;
71 |   line-height: 32px;
72 |   position: absolute;
73 |   width: 100%;
74 | }
75 | 
76 | .modal-form {
77 |   .ant-form-item {
78 |     margin-bottom: 0;
79 |   }
80 | }
81 | 


--------------------------------------------------------------------------------
/site/edit/static/content.less:
--------------------------------------------------------------------------------
 1 | .edit {
 2 |   &-content-wrapper {
 3 |     height: ~"calc(100% - 64px)";
 4 |     position: relative;
 5 |   }
 6 |   &-stage-wrapper {
 7 |     display: inline-block;
 8 |     width: ~"calc(100% - 40px)";
 9 |     height: 100%;
10 |     position: absolute;
11 |     margin-left: 40px;
12 |     left: 0;
13 |     top: 0;
14 |     .edit-preview {
15 |       width: 100%;
16 |       height: ~"calc(100% - 16px)";
17 |       max-height: 100%;
18 |       border: 0;
19 |       overflow: hidden;
20 |       display: block;
21 |       margin: auto;
22 |       position: absolute;
23 |       left: 0;
24 |       right: 0;
25 |       top: 16px;
26 |       bottom: 0;
27 |       transition: width .15s @ease-in-out, max-height .15s @ease-in-out, top .15s @ease-in-out;
28 |       &.mobile {
29 |         box-shadow: 0 0 0 1px #000;
30 |       }
31 |     }
32 |     .mobile {
33 |       width: 375px;
34 |       max-height: 667px;
35 |     }
36 |   }
37 | }
38 | 


--------------------------------------------------------------------------------
/site/edit/static/custom.less:
--------------------------------------------------------------------------------
 1 | @edit-text-color: #fff;
 2 | @edit-list-text-color: fade(#fff, 55);
 3 | 
 4 | @edit-bg-color: #262626;
 5 | @edit-line-color: #000;
 6 | 
 7 | @edit-mouse-catcher-hover: #666;
 8 | 
 9 | @edit-login-text-color: #314659;
10 | 


--------------------------------------------------------------------------------
/site/edit/static/edit-influence.less:
--------------------------------------------------------------------------------
 1 | .edit-influence {
 2 |   height: 16px;
 3 |   background: black;
 4 |   >div {
 5 |     display: flex;
 6 |     justify-content: center;
 7 |     align-items: center;
 8 |     height: 100%;
 9 |   }
10 |   .ant-select {
11 |     line-height: 16px;
12 |     color: @edit-text-color;
13 |     &.ant-select-single:not(.ant-select-customize-input) .ant-select-selector {
14 |       background: transparent;
15 |       border: none;
16 |       border-radius: 0;
17 |       &:focus {
18 |         box-shadow: none;
19 |       }
20 |       &--single {
21 |         height: 16px;
22 |       }
23 |       &__rendered {
24 |         line-height: 16px;
25 |       }
26 |       &-selected-value {
27 |         padding-right: 16px;
28 |         span {
29 |           font-size: 12px;
30 |         }
31 |       }
32 |     }
33 |     &-arrow {
34 |       color: fade(@edit-text-color, 55);
35 |     }
36 |   }
37 | }
38 | 


--------------------------------------------------------------------------------
/site/edit/static/edit-list/box-model.less:
--------------------------------------------------------------------------------
 1 | .@{editorList} {
 2 |   .ant-collapse {
 3 |     .box-model-wrapper {
 4 |       width: 145px;
 5 |       height: 60px;
 6 |       margin: 20px auto;
 7 |       border: 1px solid @edit-list-text-color;
 8 |     }
 9 |     .box-model {
10 |       position: relative;
11 |       height: 100%;
12 |       .top,
13 |       .right,
14 |       .bottom,
15 |       .left,
16 |       .center,
17 |       .top-left,
18 |       .top-right,
19 |       .bottom-right,
20 |       .bottom-left {
21 |         position: absolute;
22 |         margin: auto;
23 |         width: 56px;
24 |         height: 22px;
25 |         .ant-select-selection {
26 |           background: @bgColor;
27 |           .ant-input,
28 |           .ant-select-selection__placeholder {
29 |             text-align: center;
30 |           }
31 |         }
32 |       }
33 |       .top {
34 |         top: -11px;
35 |         left: 0;
36 |         right: 0;
37 |         .editor-color-picker {
38 |           left: -85px;
39 |         }
40 |       }
41 |       .right {
42 |         right: -28px;
43 |         top: 0;
44 |         bottom: 0;
45 |         .editor-color-picker {
46 |           right: -13px;
47 |           left: auto;
48 |         }
49 |       }
50 |       .bottom {
51 |         bottom: -11px;
52 |         left: 0;
53 |         right: 0;
54 |       }
55 |       .left {
56 |         left: -28px;
57 |         top: 0;
58 |         bottom: 0;
59 |       }
60 |       .center {
61 |         top: 0;
62 |         right: 0;
63 |         bottom: 0;
64 |         left: 0;
65 |       }
66 |       .top-left {
67 |         top: -11px;
68 |         left: -28px;
69 |       }
70 |       .top-right {
71 |         top: -11px;
72 |         right: -28px;
73 |       }
74 |       .bottom-left {
75 |         bottom: -11px;
76 |         left: -28px;
77 |       }
78 |       .bottom-right {
79 |         bottom: -11px;
80 |         right: -28px;
81 |       }
82 |     }
83 |   }
84 | }
85 | 


--------------------------------------------------------------------------------
/site/edit/static/edit-list/child.less:
--------------------------------------------------------------------------------
 1 | .child-wrapper {
 2 |   .sort-manage {
 3 |     height: 32px;
 4 |     display: flex;
 5 |     align-items: center;
 6 |     transition: background .45s @ease-in-out, box-shadow .45s @ease-in-out, transform .45s @ease-in-out;
 7 |     &:hover {
 8 |       background: @heiColor;
 9 |     }
10 |     &-delete {
11 |       width: 32px;
12 |       .ant-btn {
13 |         background: transparent;
14 |         height: 32px;
15 |         width: 32px;
16 |         line-height: 32px;
17 |         color: rgba(255, 255, 255, 0.55);
18 |         border: none;
19 |       }
20 |     }
21 |     &-icon {
22 |       width: 32px;
23 |     }
24 |     &-name {
25 |       width: ~"calc(100% - 64px)";
26 |     }
27 |   }
28 |   .add-type {
29 |     border-top: 1px solid @heiColor;
30 |     padding-top: 8px;
31 |     display: flex;
32 |     align-items: center;
33 |   }
34 | }
35 | 


--------------------------------------------------------------------------------
/site/edit/static/edit-list/custom.less:
--------------------------------------------------------------------------------
 1 | @edit-list-text-color: fade(@edit-text-color, 55);
 2 | @edit-list-text-color-hover: @edit-text-color;
 3 | @input-line-color: @edit-list-text-color;
 4 | @input-line-color-hover: @edit-list-text-color-hover;
 5 | 
 6 | @heiColor: #121212;
 7 | @huiColor: #121212;
 8 | @bgColor: #262626;
 9 | 
10 | @editorList: edit-list-tab;
11 | 


--------------------------------------------------------------------------------
/site/edit/static/edit-list/editor-bg-image.less:
--------------------------------------------------------------------------------
 1 | @import "custom";
 2 | 
 3 | @bgImage: editor-bg-image;
 4 | 
 5 | .@{bgImage} {
 6 |   &-wrapper {
 7 |     border-top: 1px solid @heiColor;
 8 |     padding-top: 8px;
 9 | 
10 |     .add-button {
11 |       font-size: 14px !important;
12 |     }
13 |   }
14 | 
15 |   &-list {
16 |     display: grid;
17 |     grid-template-columns: 24px 24px auto 24px;
18 |     grid-template-rows: 32px;
19 |     gap: 0 4px;
20 |     align-items: center;
21 |     line-height: 32px;
22 |     height: 32px;
23 | 
24 |     transition: background .3s @ease-in-out;
25 | 
26 |     &-preview {
27 |       grid-column-start: 2;
28 |       background-size: cover;
29 |       background-position: center;
30 |       background-clip: content-box;
31 |       width: 24px;
32 |       height: 24px;
33 |       border: 1px solid fade(#fff, 15);
34 |     }
35 | 
36 |     &-bar {
37 |       grid-column-start: 1;
38 |       text-align: center;
39 |       outline: none;
40 |     }
41 | 
42 |     &-name {
43 |       grid-column-start: 3;
44 |       text-overflow: ellipsis;
45 |       overflow: hidden;
46 |       white-space: nowrap;
47 |       user-select: none;
48 |       color: rgba(255, 255, 255, 0.55);
49 |       &:hover {
50 |         color: rgba(255, 255, 255, 0.85);
51 |       }
52 |     }
53 | 
54 |     &-delete {
55 |       grid-column-start: 4;
56 |       text-align: center;
57 |       cursor: pointer;
58 |     }
59 | 
60 |     &:hover,
61 |     &:active {
62 |       background-color: fade(@heiColor, 70);
63 |     }
64 |   }
65 |   &-pop {
66 |     width: 248px;
67 |     padding: 16px;
68 |     &-type {
69 |       padding-bottom: 8px;
70 |       border-bottom: 1px solid @bgColor;
71 |     }
72 |   }
73 | }
74 | 


--------------------------------------------------------------------------------
/site/edit/static/edit-list/editor-color.less:
--------------------------------------------------------------------------------
 1 | @color: editor-color;
 2 | .@{color} {
 3 |   width: 100%;
 4 |   height: 22px;
 5 |   border-radius: 4px;
 6 |   cursor: pointer;
 7 |   overflow: hidden;
 8 |   display: block;
 9 |   transition: box-shadow .3s, border .3s;
10 |   border: 1px solid #a4a7a8;
11 | 
12 |   i {
13 |     width: 100%;
14 |     height: 100%;
15 |     display: block;
16 |     position: relative;
17 |     &:after {
18 |       content: '';
19 |       display: block;
20 |       position: absolute;
21 |       width: 0;
22 |       height: 0;
23 |       border-bottom: 4px solid white;
24 |       border-left: 4px solid transparent;
25 |       right: 1px;
26 |       bottom: 1px;
27 |     }
28 |   }
29 |   &.active {
30 |     border-color: @input-line-color-hover;
31 |     box-shadow: 0 0 4px @input-line-color-hover;
32 |   }
33 |   &-wrapper {
34 |     &:hover {
35 |       .color-close {
36 |         opacity: 1;
37 |       }
38 |     }
39 |     .color-close {
40 |       position: absolute;
41 |       line-height: 12px;
42 |       text-align: center;
43 |       width: 12px;
44 |       height: 12px;
45 |       top: -5px;
46 |       left: -5px;
47 |       border-radius: 100%;
48 |       background: #f00;
49 |       color: @edit-text-color;
50 |       opacity: 0;
51 |       cursor: pointer;
52 |       transition: opacity .3s @ease-out;
53 |       .anticon-close {
54 |         font-size: 12px;
55 |         transform: scale(.8);
56 |       }
57 |     }
58 |   }
59 | }
60 | 


--------------------------------------------------------------------------------
/site/edit/static/edit-list/editor-font.less:
--------------------------------------------------------------------------------
 1 | @font: editor-font;
 2 | .@{editorList} {
 3 |   .@{font} {
 4 |     &-align {
 5 |       .left,
 6 |       .center,
 7 |       .right,
 8 |       .justify {
 9 |         width: 16px;
10 |         margin: auto;
11 |         &:after,
12 |         &:before {
13 |           background: @edit-list-text-color;
14 |           box-shadow: 0 6px 0 @edit-list-text-color;
15 |           content: '';
16 |           display: block;
17 |           margin: auto;
18 |           height: 1px;
19 |         }
20 |         &:before {
21 |           margin-top: 5px;
22 |         }
23 |         &:after {
24 |           margin-top: 2px;
25 |         }
26 |       }
27 |       .left,
28 |       .center,
29 |       .right {
30 |         &:after {
31 |           width: 13px;
32 |         }
33 |         &:before {
34 |           width: 100%;
35 |         }
36 |       }
37 |       .left {
38 |         &:after {
39 |           margin-left: 0;
40 |         }
41 |       }
42 |       .right {
43 |         &:after {
44 |           margin-right: 0;
45 |         }
46 |       }
47 |       .justify {
48 |         &:after,
49 |         &:before {
50 |           width: 100%;
51 |         }
52 |       }
53 |     }
54 |   }
55 | }
56 | 


--------------------------------------------------------------------------------
/site/edit/static/edit-list/editor-gradient.less:
--------------------------------------------------------------------------------
 1 | @import "custom";
 2 | @gradient: editor-gradient;
 3 | 
 4 | .@{gradient} {
 5 |   padding-bottom: 1px;
 6 |   border-bottom: 1px solid @bgColor;
 7 |   margin-bottom: 8px;
 8 | 
 9 |   &-bar {
10 |     height: 16px;
11 |     border: 1px solid @bgColor;
12 |     cursor: crosshair;
13 |     position: relative;
14 |     background-repeat: no-repeat;
15 |     margin: 16px 0;
16 | 
17 |     &-item {
18 |       position: relative;
19 |       height: 100%;
20 |       margin-right: 8px;
21 |     }
22 |   }
23 | 
24 |   &-point {
25 |     box-shadow: @bgColor 0 0 0 1px;
26 |     height: 100%;
27 |     width: 8px;
28 |     position: absolute;
29 |     cursor: ew-resize;
30 |     transition: shadow .3s;
31 |     border-radius: 2px;
32 |     background: #eee;
33 | 
34 |     &.active {
35 |       box-shadow: @edit-list-text-color-hover 0 0 0 2px, @bgColor 0 0 0 3px, @bgColor 0 0 0 1px inset;
36 |     }
37 |   }
38 | 
39 |   &-repeat {
40 |     color: @edit-list-text-color;
41 | 
42 |     .ant-checkbox +span {
43 |       color: @edit-list-text-color;
44 |     }
45 |   }
46 | 
47 |   &-color {
48 |     .ant-row {
49 |       margin-bottom: 0 !important;
50 |     }
51 |   }
52 | }
53 | 


--------------------------------------------------------------------------------
/site/edit/static/edit-list/index.less:
--------------------------------------------------------------------------------
 1 | 
 2 | @import "common";
 3 | @import "editor-color";
 4 | @import "collapse";
 5 | @import "editor-font";
 6 | @import "editor-bg-image";
 7 | @import "editor-gradient";
 8 | @import "box-model";
 9 | @import "child";
10 | 
11 | .edit-right-view {
12 |   .edit-list-tab {
13 |     height: 100%;
14 |     text-align: left;
15 |     .tab-scroll {
16 |       overflow: auto;
17 |       height: 100%;
18 |       position: relative;
19 |     }
20 |     &s {
21 |       height: 100%;
22 |       &.ant-tabs:not(.ant-tabs-vertical) > .ant-tabs-content > .ant-tabs-tabpane-inactive {
23 |         height: 100%;
24 |       }
25 |       .ant-tabs {
26 |         &-bar {
27 |           height: 64px;
28 |           border-color: @edit-line-color;
29 |         }
30 |         &-content {
31 |           height: ~"calc(100% - 80px)";
32 |         }
33 |         &-ink-bar {
34 |           display: none !important;
35 |         }
36 |         &-tab {
37 |           margin-right: 0;
38 |           border-right: 1px solid @edit-line-color;
39 |           padding: 0 24px;
40 |           line-height: 64px;
41 |           font-size: 16px;
42 |           color: fade(@edit-text-color, 60);
43 |           height: 65px;
44 |           transition: color 0.3s @ease-in-out, background .3s @ease-in-out;
45 |           &-active {
46 |             color: @edit-text-color;
47 |             background: @edit-bg-color;
48 |           }
49 |           &:hover {
50 |             color: @edit-text-color;
51 |           }
52 |           .anticon {
53 |             margin: 0;
54 |           }
55 |         }
56 |       }
57 |     }
58 |     .props-explain {
59 |       color: @edit-text-color;
60 |       padding: 0 16px;
61 |       font-size: 12px;
62 |     }
63 |   }
64 | }
65 | 


--------------------------------------------------------------------------------
/site/edit/static/index.less:
--------------------------------------------------------------------------------
 1 | // @import '~antd/lib/style/v2-compatible-reset.less';
 2 | @import "~antd/lib/style/themes/default.less";
 3 | @import '~antd/lib/tag/style/index.css';
 4 | @import '~antd/lib/slider/style/index.css';
 5 | @import './common';
 6 | @import './custom';
 7 | @import './login-controller';
 8 | @import './edit-list/index';
 9 | @import './content';
10 | @import './edit-influence';
11 | @import './nav-controller';
12 | @import './side-menu';
13 | @import './edit-stage';
14 | @import './banner-slide';
15 | @import './other-view.less';
16 | @import './sort.less';
17 | @import '../../templates/static/point';
18 | 
19 | .edit {
20 |   &-wrapper {
21 |     width: 100%;
22 |     position: relative;
23 |     height: 100vh;
24 |     background: @edit-bg-color;
25 |     overflow: hidden;
26 |     /** {
27 |       -webkit-user-select: none;
28 |       -moz-user-select: none;
29 |       -ms-user-select: none;
30 |       user-select: none;
31 |     } */
32 |     > div {
33 |       height: 100%;
34 |       float: left;
35 |     }
36 |   }
37 |   &-left-view {
38 |     width: ~"calc(100% - 288px)";
39 |   }
40 |   &-right-view {
41 |     width: 288px;
42 |     border-left: 1px solid @edit-line-color;
43 |   }
44 | }
45 | p {
46 |   margin: 0;
47 | }
48 | 


--------------------------------------------------------------------------------
/site/edit/static/login-controller.less:
--------------------------------------------------------------------------------
 1 | .login-controller {
 2 |   background: @edit-bg-color;
 3 |   width: 100%;
 4 |   height: 100vh;
 5 |   position: absolute;
 6 |   top: 0;
 7 |   left: 0;
 8 |   color: @edit-login-text-color;
 9 |   display: flex;
10 |   justify-content: center;
11 |   align-items: center;
12 |   .login-view {
13 |     width: 360px;
14 |     padding: 24px;
15 |     background: #fff;
16 |     border-radius: 4px;
17 |     box-shadow: 0 0 16px rgba(0, 0, 0, 0.35);
18 |     .header {
19 |       font-size: 46px;
20 |       margin: 0 auto 32px;
21 |       width: 60px;
22 |       height: 60px;
23 |       line-height: 60px;
24 |       border-radius: 100%;
25 |       color: @edit-login-text-color;
26 |       background: @primary-color;
27 |       text-align: center;
28 |       display: flex;
29 |       align-items: center;
30 |       justify-content: center;
31 |     }
32 |     p {
33 |       margin-bottom: 16px;
34 |     }
35 |     &.password-no {
36 |       animation: antSwingIn .5s linear;
37 |     }
38 |   }
39 | }
40 | 
41 | @keyframes antSwingIn {
42 |   0%,
43 |   100% {
44 |     transform: translateX(0);
45 |   }
46 |   20% {
47 |     transform: translateX(-10px);
48 |   }
49 |   40% {
50 |     transform: translateX(10px);
51 |   }
52 |   60% {
53 |     transform: translateX(-5px);
54 |   }
55 |   80% {
56 |     transform: translateX(5px);
57 |   }
58 | }
59 | 


--------------------------------------------------------------------------------
/site/edit/static/other-view.less:
--------------------------------------------------------------------------------
 1 | .other {
 2 |   .ant-radio-button-wrapper {
 3 |     vertical-align: top;
 4 |     .point-radio-wrapper {
 5 |       width: 100%;
 6 |       height: 100%;
 7 |       display: flex;
 8 |       align-items: center;
 9 |       justify-content: center;
10 |       .point {
11 |         background: rgba(255, 255, 255, 0.3);
12 |         border-color: transparent;
13 |         transition: background .3s @ease-out, border .3s @ease-out;
14 |         &-stroke {
15 |           background: transparent;
16 |           border-color: rgba(255, 255, 255, 0.3);
17 |         }
18 |       }
19 |     }
20 |   }
21 |   .ant-radio-button-wrapper-checked {
22 |     .point-radio-wrapper .point {
23 |       background: rgba(255, 255, 255, 0.9);
24 |       border-color: transparent;
25 |       &-stroke {
26 |         background: transparent;
27 |         border-color: rgba(255, 255, 255, 0.9);
28 |       }
29 |     }
30 |   }
31 |   &-demo {
32 |     overflow: hidden;
33 |     border: 1px solid rgba(255, 255, 255, 0.3);
34 |     border-radius: 4px;
35 |     video,
36 |     img {
37 |       display: block;
38 |     }
39 |   }
40 | }
41 | 


--------------------------------------------------------------------------------
/site/edit/static/sort.less:
--------------------------------------------------------------------------------
 1 | .sort-manage {
 2 |   height: 48px;
 3 |   display: flex;
 4 |   align-items: center;
 5 |   transition: background .45s @ease-in-out, box-shadow .45s @ease-in-out, transform .45s @ease-in-out;
 6 |   &:hover {
 7 |     background: #e6f7ff;
 8 |   }
 9 |   &-list {
10 |     position: relative;
11 |   }
12 |   &-icon {
13 |     width: 48px;
14 |     text-align: center;
15 |     cursor: pointer;
16 |     &[disabled] {
17 |       color: rgba(0, 0, 0, 0.25) !important;
18 |       pointer-events: none;
19 |     }
20 |   }
21 |   &-delete {
22 |     text-align: center;
23 |     width: 48px;
24 |   }
25 |   &-name {
26 |     width: ~"calc(100% - 80px)";
27 |   }
28 | }
29 | 


--------------------------------------------------------------------------------
/site/edit/static/style.js:
--------------------------------------------------------------------------------
 1 | import 'rc-drawer/assets/index.css';
 2 | import 'antd/lib/auto-complete/style/index.css';
 3 | import 'medium-editor/dist/css/medium-editor.css';
 4 | import 'medium-editor/dist/css/themes/default.css';
 5 | // import 'rc-editor-list/assets/index.css';
 6 | import 'codemirror/lib/codemirror.css';
 7 | import 'codemirror/theme/ambiance.css';
 8 | import 'codemirror/addon/hint/show-hint.css';
 9 | import './index.less';
10 | 


--------------------------------------------------------------------------------
/site/edit/template/NotFound.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | 
 3 | export default function NotFound(props) {
 4 |   return (
 5 |     <div id="page-404" className={props.className}>
 6 |       <section>
 7 |         <h1>404</h1>
 8 |         <p>
 9 |           你要找的页面不存在
10 |           {' '}
11 |           <a href="/">返回首页</a>
12 |         </p>
13 |       </section>
14 |       <style
15 |         dangerouslySetInnerHTML={{
16 |           __html: '#page-404{ height: calc(100% - 199px);}',
17 |         }}
18 |       />
19 |     </div>
20 |   );
21 | }
22 | 


--------------------------------------------------------------------------------
/site/edit/template/components/EditInfluence.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import { Select } from 'antd';
 3 | import { LaptopOutlined, MobileOutlined } from '@ant-design/icons';
 4 | import * as actions from '../../../shared/redux/actions';
 5 | 
 6 | const Option = Select.Option;
 7 | 
 8 | class EditInfluence extends React.Component {
 9 |   onChange = (v) => {
10 |     const { dispatch } = this.props;
11 |     dispatch(actions.setCurrentMediaData(v));
12 |   }
13 | 
14 |   render() {
15 |     const { mediaStateSelect } = this.props;
16 |     return (
17 |       <div className="edit-influence">
18 |         <div className={mediaStateSelect}>
19 |           <Select defaultValue={mediaStateSelect} size="small" onChange={this.onChange}>
20 |             <Option value="Desktop">
21 |               <LaptopOutlined style={{ fontSize: '12px' }} />
22 |               <span style={{ marginLeft: 4 }}>
23 |                 Desktop
24 |               </span>
25 |             </Option>
26 |             <Option value="Mobile">
27 |               <MobileOutlined style={{ fontSize: '12px' }} />
28 |               <span style={{ marginLeft: 4 }}>
29 |                 Mobile
30 |               </span>
31 |             </Option>
32 |           </Select>
33 |         </div>
34 |       </div>
35 |     );
36 |   }
37 | }
38 | 
39 | export default EditInfluence;
40 | 


--------------------------------------------------------------------------------
/site/edit/template/components/ListComponents/CheckboxGroup.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import { Checkbox, Row, Col } from 'antd';
 3 | import { FormattedMessage } from 'react-intl';
 4 | 
 5 | const AntCheckboxGroup = Checkbox.Group;
 6 | 
 7 | export default class CheckboxGroup extends React.PureComponent {
 8 |   onCheckAllChange = (e) => {
 9 |     const { children } = this.props;
10 |     const checked = e.target.checked;
11 |     this.props.onChange(checked ? children.map((item) => item.key) : []);
12 |   }
13 | 
14 |   render() {
15 |     const { children, value } = this.props;
16 |     const checkAll = value.length === children.length;
17 |     const indeterminate = !!value.length && (value.length < children.length);
18 |     return (
19 |       <div>
20 |         <div>
21 |           <Checkbox
22 |             indeterminate={indeterminate}
23 |             checked={checkAll}
24 |             onChange={this.onCheckAllChange}
25 |           >
26 |             <FormattedMessage id="app.common.all" />
27 |           </Checkbox>
28 |         </div>
29 |         <div>
30 |           <AntCheckboxGroup value={value} onChange={this.props.onChange}>
31 |             <Row>
32 |               {children.map((item) => (
33 |                 <Col key={item.key} span={12}><Checkbox value={item.key}>{item.name}</Checkbox></Col>
34 |               ))}
35 |             </Row>
36 |           </AntCheckboxGroup>
37 |         </div>
38 |       </div>
39 |     );
40 |   }
41 | }
42 | 


--------------------------------------------------------------------------------
/site/edit/template/components/ListComponents/InputGroup.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import { Input, InputNumber } from 'antd';
 3 | 
 4 | const AntInputGroup = Input.Group;
 5 | 
 6 | export default class InputGroup extends React.PureComponent {
 7 |   onInputChange = (v, key) => {
 8 |     const { value } = this.props;
 9 |     const i = key === 'start' ? 0 : 1;
10 |     const newValue = Array.isArray(value) ? value : [value, value];
11 |     newValue[i] = v;
12 |     this.props.onChange(newValue);
13 |   }
14 | 
15 |   render() {
16 |     const { value } = this.props;
17 |     const newValue = Array.isArray(value) ? value : [value, value];
18 |     return (
19 |       <div>
20 |         <AntInputGroup compact>
21 |           <InputNumber
22 |             {...this.props}
23 |             size="small"
24 |             value={newValue[0]}
25 |             style={{ width: '50%' }}
26 |             onChange={(v) => { this.onInputChange(v, 'start'); }}
27 |           />
28 |           <InputNumber
29 |             {...this.props}
30 |             size="small"
31 |             value={newValue[1] || newValue[0]}
32 |             style={{ width: '50%' }}
33 |             onChange={(v) => { this.onInputChange(v, 'end'); }}
34 |           />
35 |         </AntInputGroup>
36 |       </div>
37 |     );
38 |   }
39 | }
40 | 


--------------------------------------------------------------------------------
/site/edit/template/components/MediumEditor.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import MediumEditor from 'medium-editor';
 3 | 
 4 | import { tagRep } from '../../../utils';
 5 | 
 6 | const noop = () => { };
 7 | export default class Editor extends React.Component {
 8 |   medium = null;
 9 | 
10 |   state = {
11 |     text: '',
12 |   };
13 | 
14 |   constructor(props) {
15 |     super(props);
16 |     this.state = {
17 |       text: props.text,
18 |     };
19 |   }
20 | 
21 |   componentDidMount() {
22 |     const { options } = this.props;
23 |     const { text } = this.state;
24 |     this.dom.innerHTML = text;
25 |     this.medium = new MediumEditor(this.dom, {
26 |       // paste: { cleanPastedHTML: true },
27 |       placeholder: {
28 |         text: '请输入...',
29 |       },
30 |       anchor: {
31 |         placeholderText: 'Paste or type a having (http) link.',
32 |         targetCheckbox: true,
33 |         targetCheckboxText: 'Open in new window',
34 |       },
35 |       ...options,
36 |     });
37 |     this.addChange();
38 |   }
39 | 
40 |   addChange = () => {
41 |     const { textToString } = this.props;
42 |     this.medium.subscribe('editableInput', (e, b) => {
43 |       if (b.innerHTML.match(tagRep)) {
44 |         this.setState({
45 |           text: b.innerHTML,
46 |         }, () => {
47 |           (this.props.onChange || noop)(b);
48 |         });
49 |       }
50 |     });
51 |     this.medium.subscribe('blur', (e, b) => {
52 |       e.stopPropagation();
53 |       if (b.innerHTML.match(tagRep) && e.type === 'click') {
54 |         (this.props.onBlur || noop)(textToString ? b.innerText : `<span>${b.innerHTML}</span>`);
55 |       }
56 |     });
57 |   }
58 | 
59 |   /* componentWillReceiveProps(nextProps) {
60 |     if (nextProps.text !== this.state.text) {
61 |       this.setState({
62 |         text: nextProps.text,
63 |       }, () => {
64 |         this.medium.destroy();
65 |         this.dom.innerHTML = nextProps.text;
66 |         this.medium.setup();
67 |         this.addChange();
68 |       });
69 |     }
70 |   } */
71 | 
72 |   componentWillUnmount() {
73 |     this.medium.destroy();
74 |   }
75 | 
76 |   render() {
77 |     const { options, onChange, onBlur, text, children, textToString, ...props } = this.props;
78 |     return (
79 |       <div
80 |         ref={(c) => { this.dom = c; }}
81 |         {...props}
82 |       />
83 |     );
84 |   }
85 | }
86 | 


--------------------------------------------------------------------------------
/site/edit/template/components/StateComponents/ButtonViewComponent/ContentEditView.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import { connect } from 'react-redux';
 3 | 
 4 | import { getIdsAndCurrentData } from '../../../utils';
 5 | import { mapStateToProps } from '../../../../../shared/utils';
 6 | 
 7 | import ContentEditViewItem from './ContentEditViewItem';
 8 | 
 9 | function ContentEditView({ currentEditData, templateData }) {
10 |   const { currentEditTemplateData } = getIdsAndCurrentData(currentEditData, templateData, 'Content');
11 |   if (!currentEditTemplateData.children) {
12 |     return null;
13 |   }
14 | 
15 |   return (
16 |     <div>
17 |       <div style={{ marginTop: 16, textAlign: 'center' }}>
18 |         {Object.keys(currentEditTemplateData.children).map((key) => (<ContentEditViewItem key={key} id={key} />))}
19 |       </div>
20 |     </div>
21 |   );
22 | }
23 | 
24 | export default connect(mapStateToProps)(ContentEditView);
25 | 


--------------------------------------------------------------------------------
/site/edit/template/components/StateComponents/ButtonViewComponent/ContentEditViewItem.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import { Input, Row, Col } from 'antd';
 3 | import { connect } from 'react-redux';
 4 | 
 5 | import { getIdsAndCurrentData } from '../../../utils';
 6 | import { mapStateToProps } from '../../../../../shared/utils';
 7 | import * as actions from '../../../../../shared/redux/actions';
 8 | 
 9 | function ContentEditViewItem({ id, currentEditData, templateData, dispatch }) {
10 |   const { ids, currentEditTemplateData } = getIdsAndCurrentData(currentEditData, templateData, 'Content');
11 | 
12 |   const item = currentEditTemplateData.children[id];
13 | 
14 |   const onBlur = React.useCallback((e) => {
15 |     currentEditTemplateData.children[id].children = e.target.value;
16 |     dispatch(actions.changeChild({ templateData, currentData: currentEditTemplateData, ids }));
17 |   }, [dispatch, templateData, ids, currentEditTemplateData, id]);
18 | 
19 |   return (
20 |     <Row style={{ marginBottom: 16, textAlign: 'right' }}>
21 |       <Col span={6} style={{ paddingRight: 8, lineHeight: '32px' }}>{item.name}</Col>
22 |       <Col span={18}>
23 |         <Input
24 |           defaultValue={item.children}
25 |           onBlur={onBlur}
26 |         />
27 |       </Col>
28 |     </Row>
29 |   );
30 | }
31 | 
32 | export default connect(mapStateToProps)(ContentEditViewItem);
33 | 


--------------------------------------------------------------------------------
/site/edit/template/components/StateComponents/ButtonViewComponent/ContentWrapper.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import { Button, Modal } from 'antd';
 3 | import {
 4 |   FormOutlined,
 5 | } from '@ant-design/icons';
 6 | import { FormattedMessage } from 'react-intl';
 7 | import ContentEditView from './ContentEditView';
 8 | 
 9 | export default class ContentWrapper extends React.Component {
10 |   state = {
11 |     editContentShow: false,
12 |   };
13 | 
14 |   onOpenModal = () => {
15 |     this.setState({
16 |       editContentShow: !this.state.editContentShow,
17 |     });
18 |   }
19 | 
20 |   render() {
21 |     return (
22 |       <div>
23 |         <Button type="primary" size="small" onClick={this.onOpenModal}>
24 |           <FormOutlined />
25 |         </Button>
26 |         <Modal
27 |           title={<FormattedMessage id="app.common.edit.content" />}
28 |           visible={this.state.editContentShow}
29 |           onCancel={this.onOpenModal}
30 |           footer={null}
31 |           width={400}
32 |         >
33 |           <ContentEditView {...this.props} />
34 |         </Modal>
35 |       </div>
36 |     );
37 |   }
38 | }
39 | 


--------------------------------------------------------------------------------
/site/edit/template/components/StateComponents/ButtonViewComponent/IconComp.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import { Button, Popover, Input } from 'antd';
 3 | import { FormattedMessage } from 'react-intl';
 4 | 
 5 | export default class IconComp extends React.Component {
 6 |   onIconChange = (e) => {
 7 |     this.props.setTemplateConfigData(e.target.value);
 8 |   }
 9 | 
10 |   render() {
11 |     const { editText } = this.props;
12 |     const popContent = (
13 |       <div>
14 |         <p style={{ marginBottom: 8 }}>
15 |           <FormattedMessage id="app.state.icon.only-use" />
16 |           <a href="https://ant.design/components/icon-cn/" target="_blank">
17 |             {' '}
18 |             ant design Icon
19 |             {' '}
20 |           </a>
21 |         </p>
22 |         <Input
23 |           style={{ width: 250 }}
24 |           onBlur={this.onIconChange}
25 |           defaultValue={editText}
26 |           placeholder={<FormattedMessage id="app.state.icon.paste" />}
27 |         />
28 |       </div>
29 |     );
30 |     return (
31 |       <Popover
32 |         placement="bottomRight"
33 |         title={<FormattedMessage id="app.state.icon.header" />}
34 |         content={popContent}
35 |         trigger="click"
36 |       >
37 |         <Button type="primary" size="small" onClick={this.props.closeEditText}>
38 |           Icon
39 |         </Button>
40 |       </Popover>
41 |     );
42 |   }
43 | }
44 | 


--------------------------------------------------------------------------------
/site/edit/template/components/StateComponents/ButtonViewComponent/ImageComp.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import { Button, Popover, Input } from 'antd';
 3 | import {
 4 |   PictureOutlined,
 5 | } from '@ant-design/icons';
 6 | import { FormattedMessage } from 'react-intl';
 7 | 
 8 | export default class ImageComp extends React.Component {
 9 |   onImageBtnChange = (e) => {
10 |     const value = e.target.value;
11 |     if (value !== this.props.editText) {
12 |       this.props.setTemplateConfigData(value);
13 |     }
14 |   }
15 | 
16 |   render() {
17 |     const { editText } = this.props;
18 |     return (
19 |       <Popover
20 |         placement="bottomRight"
21 |         title={<FormattedMessage id="app.state.image.header" />}
22 |         content={(
23 |           <Input
24 |             style={{ width: 250 }}
25 |             onBlur={this.onImageBtnChange}
26 |             defaultValue={editText}
27 |             placeholder={<FormattedMessage id="app.state.image.placeholder" />}
28 |           />
29 |         )}
30 |         trigger="click"
31 |       >
32 |         <Button type="primary" size="small" onClick={this.props.closeEditText}>
33 |           <PictureOutlined />
34 |         </Button>
35 |       </Popover>
36 |     );
37 |   }
38 | }
39 | 


--------------------------------------------------------------------------------
/site/edit/template/components/StateComponents/ButtonViewComponent/MenuComp.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import { Button, Modal } from 'antd';
 3 | import { BarsOutlined } from '@ant-design/icons';
 4 | import { FormattedMessage } from 'react-intl';
 5 | import MenuEditView from './MenuEditView';
 6 | 
 7 | export default class ImageComp extends React.Component {
 8 |   state = {
 9 |     editMenuShow: false,
10 |   }
11 | 
12 |   switchEditMenuFunc = () => {
13 |     this.setState({
14 |       editMenuShow: !this.state.editMenuShow,
15 |     });
16 |   }
17 | 
18 |   render() {
19 |     const { editData } = this.props;
20 |     if (typeof editData.children !== 'string') {
21 |       return null;
22 |     }
23 |     return (
24 |       <div>
25 |         <Button type="primary" size="small" onClick={this.switchEditMenuFunc}>
26 |           <BarsOutlined />
27 |         </Button>
28 |         <Modal
29 |           title={<FormattedMessage id="app.state.menu.header" />}
30 |           visible={this.state.editMenuShow}
31 |           onCancel={this.switchEditMenuFunc}
32 |           footer={null}
33 |           width={400}
34 |         >
35 |           <MenuEditView {...this.props} />
36 |         </Modal>
37 |       </div>
38 |     );
39 |   }
40 | }
41 | 


--------------------------------------------------------------------------------
/site/edit/template/components/StateComponents/ButtonViewComponent/TextyComp.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import { Button, Popover, Input } from 'antd';
 3 | import { FormattedMessage } from 'react-intl';
 4 | 
 5 | export default class TextyComp extends React.Component {
 6 |   onImageBtnChange = (e) => {
 7 |     const value = e.target.value;
 8 |     this.props.setTemplateConfigData(value);
 9 |   }
10 | 
11 |   render() {
12 |     const { editText } = this.props;
13 |     return (
14 |       <Popover
15 |         placement="bottomRight"
16 |         title={<FormattedMessage id="app.state.texty.header" />}
17 |         content={(
18 |           <Input
19 |             style={{ width: 250 }}
20 |             onBlur={this.onImageBtnChange}
21 |             defaultValue={editText || ''}
22 |             placeholder={<FormattedMessage id="app.state.texty.header" />}
23 |           />
24 |         )}
25 |         trigger="click"
26 |       >
27 |         <Button type="primary" size="small" onClick={this.props.closeEditText}>
28 |           Ty
29 |         </Button>
30 |       </Popover>
31 |     );
32 |   }
33 | }
34 | 


--------------------------------------------------------------------------------
/site/edit/template/components/StateComponents/ButtonViewComponent/VideoComp.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import { Button, Popover, Input, Row, Col } from 'antd';
 3 | import {
 4 |   VideoCameraOutlined,
 5 | } from '@ant-design/icons';
 6 | import { FormattedMessage } from 'react-intl';
 7 | import { isImg } from '../../../../../utils';
 8 | 
 9 | export default class VideoComp extends React.Component {
10 |   onVideoChange = (e, data, key) => {
11 |     data[key] = e.target.value;
12 |     this.props.setTemplateConfigData(data);
13 |   }
14 | 
15 |   render() {
16 |     const { editText } = this.props;
17 |     const popContent = (
18 |       <div style={{ width: 350, lineHeight: '32px' }}>
19 |         <Row>
20 |           <Col span={8} style={{ textAlign: 'right', paddingRight: 8 }}>
21 |             <FormattedMessage id="app.state.video.placeholder" />
22 |           </Col>
23 |           <Col span={16}>
24 |             <Input
25 |               onBlur={(e) => { this.onVideoChange(e, editText, 'video'); }}
26 |               defaultValue={editText.video}
27 |               placeholder={<FormattedMessage id="app.state.video.placeholder" />}
28 |             />
29 |           </Col>
30 |         </Row>
31 |         <Row style={{ marginTop: 16 }}>
32 |           <Col span={8} style={{ textAlign: 'right', paddingRight: 8 }}>
33 |             <FormattedMessage id="app.state.video.preview" />
34 |           </Col>
35 |           <Col span={16}>
36 |             <Input
37 |               onBlur={(e) => { this.onVideoChange(e, editText, 'image'); }}
38 |               defaultValue={editText.image && editText.image.match(isImg) ? editText.image : ''}
39 |               placeholder={<FormattedMessage id="app.state.video.preview" />}
40 |             />
41 |           </Col>
42 |         </Row>
43 |       </div>
44 |     );
45 |     return (
46 |       <Popover
47 |         placement="bottomRight"
48 |         title={<FormattedMessage id="app.state.video.header" />}
49 |         content={popContent}
50 |         trigger="click"
51 |       >
52 |         <Button type="primary" size="small">
53 |           <VideoCameraOutlined />
54 |         </Button>
55 |       </Popover>
56 |     );
57 |   }
58 | }
59 | 


--------------------------------------------------------------------------------
/site/edit/template/index.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import { Provider } from 'react-redux';
 3 | import { IntlProvider } from 'react-intl';
 4 | import { ConfigProvider } from 'antd';
 5 | import zhCN from 'antd/es/locale/zh_CN';
 6 | 
 7 | import enLocale from '../en-US';
 8 | import cnLocale from '../zh-CN';
 9 | 
10 | import Layout from './layout';
11 | 
12 | import store from '../../shared/redux';
13 | import { isZhCN } from '../../theme/template/utils';
14 | import '../static/style';
15 | 
16 | class Edit extends React.Component {
17 |   constructor(props) {
18 |     super(props);
19 |     const { pathname } = props.location;
20 |     const appLocale = isZhCN(pathname) ? cnLocale : enLocale;
21 | 
22 |     this.state = {
23 |       appLocale,
24 |     };
25 |   }
26 | 
27 |   render() {
28 |     const { appLocale } = this.state;
29 |     return (
30 |       <Provider store={store}>
31 |         <IntlProvider locale={appLocale.locale} messages={appLocale.messages}>
32 |           <ConfigProvider locale={appLocale.locale === 'zh-CN' ? zhCN : null}>
33 |             <Layout {...this.props} />
34 |           </ConfigProvider>
35 |         </IntlProvider>
36 |       </Provider>
37 |     );
38 |   }
39 | }
40 | 
41 | export default Edit;
42 | 


--------------------------------------------------------------------------------
/site/edit/template/utils.jsx:
--------------------------------------------------------------------------------
 1 | import { mergeEditDataToDefault, getDataSourceValue } from '../../utils';
 2 | import tempData from '../../templates/template/element/template.config';
 3 | 
 4 | // import { createLogger } from 'redux-logger';
 5 | const worker = new Worker('./worker.js');
 6 | 
 7 | export function formatCode({ code, cb, parser = 'babylon', key }) {
 8 |   const options = {
 9 |     useTabs: false,
10 |     tabWidth: 2,
11 |     printWidth: 80,
12 |     singleQuote: true,
13 |     trailingComma: 'es5',
14 |     bracketSpacing: true,
15 |     parser,
16 |     arrowParens: 'always',
17 |     semi: true,
18 |   };
19 |   worker.onmessage = (message) => {
20 |     cb(message.data.formatted, message.data.key);
21 |   };
22 |   worker.postMessage({
23 |     text: code,
24 |     key,
25 |     options,
26 |   });
27 | }
28 | 
29 | /* export function hasErrors(fieldsError) {
30 |   return Object.keys(fieldsError).some((field) => fieldsError[field] && fieldsError[field][0] !== 'password error'
31 |   );
32 | } */
33 | 
34 | export const getCurrentDom = (pos, data) => {
35 |   const t = data.map((item) => {
36 |     const rect = item.rect;
37 |     if (pos.x >= rect.x && pos.y >= rect.y
38 |       && pos.x <= rect.x + rect.width && pos.y <= rect.y + rect.height) {
39 |       return {
40 |         ...item,
41 |         rect,
42 |       };
43 |     }
44 |     return null;
45 |   }).filter((item) => item);
46 |   return t[t.length - 1];
47 | };
48 | 
49 | export const getIdsAndCurrentData = (currentEditData, templateData, key) => {
50 |   const { id } = currentEditData;
51 |   const ids = id.split('-');
52 |   ids[1] = key;
53 |   const cid = ids[0].split('_')[0];
54 |   const tempDataSource = tempData[cid];
55 |   const newTemplateDataSource = mergeEditDataToDefault(templateData.data.config[ids[0]],
56 |     tempDataSource);
57 |   const currentEditTemplateData = getDataSourceValue(key, newTemplateDataSource);
58 |   return { ids, currentEditTemplateData };
59 | };
60 | 


--------------------------------------------------------------------------------
/site/shared/constants.js:
--------------------------------------------------------------------------------
 1 | export const DEFAULT_USER_NAME = 'antd-landing-user-name';
 2 | 
 3 | // leancloud
 4 | export const DEFAULT_FILE_NAME = 'Edit';
 5 | export const DEFAULT_USER_AV_NAME = 'EditUser';
 6 | 
 7 | export const DEFAULT_TEMPLATE_DATA = {
 8 |   template: [
 9 |     'Nav0_0', 'Banner0_0', 'Content0_0',
10 |     'Content1_0', 'Content3_0', 'Footer0_0',
11 |   ],
12 |   config: {},
13 |   style: [],
14 |   other: {},
15 |   page: {},
16 | };
17 | 


--------------------------------------------------------------------------------
/site/shared/leancloud.js:
--------------------------------------------------------------------------------
 1 | import AV from 'leancloud-storage';
 2 | 
 3 | export const appId = 'ogaJShC9qJERt8LqGO80z2pO-gzGzoHsz';
 4 | export const appKey = '8e5H5xBF86hI9vItQI1pt4kP';
 5 | 
 6 | AV.init({
 7 |   appId,
 8 |   appKey,
 9 |   // serverURLs: 'https://avoscloud.com',
10 |   serverURLs: 'https://ogajshc9.lc-cn-n1-shared.com',
11 | });
12 | 
13 | export default AV;
14 | 


--------------------------------------------------------------------------------
/site/shared/localStorage.js:
--------------------------------------------------------------------------------
 1 | import store from 'store';
 2 | 
 3 | /**
 4 |  * Auth
 5 |  */
 6 | 
 7 | export function getUserAuthState(userId) {
 8 |   return !!store.get(`antd-landing-login-${userId}`);
 9 | }
10 | 
11 | export function setUserAuthState(userId, state) {
12 |   store.set(`antd-landing-login-${userId}`, state);
13 | }
14 | 
15 | /**
16 |  * User
17 |  */
18 | 
19 | export function getUserTemplateIds(userId) {
20 |   const value = store.get(userId, []);
21 |   return typeof value === 'string' ? value.split(',').filter((c) => c) : value;
22 | }
23 | 
24 | export function unshiftToUserTemplateIds(userId, tid) {
25 |   const ids = getUserTemplateIds(userId);
26 |   store.set(userId, [tid, ...ids]);
27 | }
28 | 
29 | export function removeUserTemplateIds(userId) {
30 |   store.remove(userId);
31 | }
32 | 
33 | export function removeUserTemplate(userId, tid) {
34 |   const ids = getUserTemplateIds(userId);
35 |   store.set(userId, ids.filter((id) => id !== tid));
36 | }
37 | 
38 | /**
39 |  * Template
40 |  */
41 | 
42 | export function getTemplate(tid) {
43 |   return store.get(tid, undefined);
44 | }
45 | 
46 | export function saveTemplate(template) {
47 |   store.set(template.id, template);
48 | }
49 | 
50 | export function removeTemplate(tid) {
51 |   store.remove(tid);
52 | }
53 | 


--------------------------------------------------------------------------------
/site/shared/redux/actionTypes.js:
--------------------------------------------------------------------------------
 1 | export const GET_USER_DATA = '[landing] GET_USER_DATA';
 2 | export const CREATE_NEW_TEMPLATE = '[landing] CREATE_NEW_TEMPLATE';
 3 | export const SET_TEMPLATE_DATA = '[landing] SET_TEMPLATE_DATA';
 4 | export const CHANGE_CHILD = '[landing] CHANGE_CHILD';
 5 | export const SET_USER_AND_TEMPLATE_DATA = '[landing] SET_USER_AND_TEMPLATE_DATA';
 6 | export const UPDATE_HISTORY = '[landing] UPDATE_HISTORY';
 7 | 
 8 | export const POST_TYPE = {
 9 |   POST_DEFAULT: '[landing] default',
10 |   POST_SET: '[landing] set',
11 |   POST_SUCCESS: '[landing] success',
12 |   POST_ERROR: '[landing] error',
13 |   SET_TEMPLATE: '[landing] setTemplate',
14 |   SET_EDIT: '[landing] setEdit',
15 |   SET_MEDIA: '[landing] setMedia',
16 |   SET_USER: '[landing] setUser',
17 |   SET_HISTORY_NUM: '[landing] setHistoryNum',
18 |   UPDATE_HISTORY_RE_NUM: '[landing] updateHistoryReNum',
19 |   SAVE_HISTORY: '[landing] saveHistory',
20 |   SET_USERTEMPLATE: '[landing] setUserTemplate',
21 | };
22 | 


--------------------------------------------------------------------------------
/site/shared/redux/actions.js:
--------------------------------------------------------------------------------
 1 | import { GET_USER_DATA, CREATE_NEW_TEMPLATE, SET_TEMPLATE_DATA, CHANGE_CHILD, POST_TYPE, SET_USER_AND_TEMPLATE_DATA } from './actionTypes';
 2 | 
 3 | export const getUserData = (data) => ({
 4 |   type: GET_USER_DATA,
 5 |   data,
 6 | });
 7 | 
 8 | export const createNewTemplate = (data) => ({
 9 |   type: CREATE_NEW_TEMPLATE,
10 |   data,
11 | });
12 | 
13 | export const setTemplateData = (data) => ({
14 |   type: SET_TEMPLATE_DATA,
15 |   data,
16 | });
17 | 
18 | export const changeChild = (data) => ({
19 |   type: CHANGE_CHILD,
20 |   data,
21 | });
22 | 
23 | export const setUserAndTemplateData = (data) => ({
24 |   type: SET_USER_AND_TEMPLATE_DATA,
25 |   data,
26 | });
27 | 
28 | // 编辑 props
29 | export const setCurrentData = (data) => {
30 |   return {
31 |     type: POST_TYPE.SET_EDIT,
32 |     data,
33 |   };
34 | };
35 | 
36 | // 编辑 media 状态
37 | export const setCurrentMediaData = (data) => {
38 |   return {
39 |     type: POST_TYPE.SET_MEDIA,
40 |     data,
41 |   };
42 | };
43 | 
44 | export const setUserData = (data) => {
45 |   return {
46 |     type: POST_TYPE.SET_USER,
47 |     data,
48 |   };
49 | };
50 | 
51 | // 记录 history 步数;
52 | export const setCurrentHistoryNum = (data) => {
53 |   return {
54 |     type: POST_TYPE.SET_HISTORY_NUM,
55 |     data,
56 |   };
57 | };
58 | // 删除之前,保存当前的
59 | export const updateHistoryReNum = (data) => {
60 |   return {
61 |     type: POST_TYPE.UPDATE_HISTORY_RE_NUM,
62 |     data,
63 |   };
64 | };
65 | 


--------------------------------------------------------------------------------
/site/shared/redux/index.js:
--------------------------------------------------------------------------------
 1 | import { createStore, applyMiddleware, compose } from 'redux';
 2 | import createSagaMiddleware from 'redux-saga';
 3 | import rootReducer from './reducers';
 4 | import rootSaga from './saga';
 5 | 
 6 | const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
 7 | const sagaMiddleware = createSagaMiddleware();
 8 | 
 9 | const store = createStore(
10 |   rootReducer,
11 |   composeEnhancers(
12 |     applyMiddleware(sagaMiddleware),
13 |   ),
14 | );
15 | 
16 | sagaMiddleware.run(rootSaga);
17 | 
18 | export default store;
19 | 


--------------------------------------------------------------------------------
/site/shared/redux/reducers/currentEditData.js:
--------------------------------------------------------------------------------
 1 | import { POST_TYPE } from '../actionTypes';
 2 | 
 3 | export default function currentEditData(state, action) {
 4 |   switch (action.type) {
 5 |     case POST_TYPE.SET_EDIT:
 6 |       return action.data || null;
 7 |     case POST_TYPE.SET_MEDIA:
 8 |       return null;
 9 |     default:
10 |       return state || null;
11 |   }
12 | }
13 | 


--------------------------------------------------------------------------------
/site/shared/redux/reducers/historyEdit.js:
--------------------------------------------------------------------------------
 1 | import { POST_TYPE } from '../actionTypes';
 2 | 
 3 | export default function historyEdit(state, action) {
 4 |   switch (action.type) {
 5 |     case POST_TYPE.SET_HISTORY_NUM:
 6 |       return {
 7 |         ...state,
 8 |         num: action.data,
 9 |       };
10 |     case POST_TYPE.UPDATE_HISTORY_RE_NUM:
11 |       return {
12 |         num: 0,
13 |         history: (state.num
14 |           ? [action.data, ...state.history.filter((c, i) => i >= state.num && c)]
15 |           : [action.data, ...state.history]).filter((c, i) => i < 30 && c), // 只记录30步
16 |       };
17 |     default:
18 |       return state || {
19 |         num: 0,
20 |         history: [],
21 |       };
22 |   }
23 | }
24 | 


--------------------------------------------------------------------------------
/site/shared/redux/reducers/index.js:
--------------------------------------------------------------------------------
 1 | import { combineReducers } from 'redux';
 2 | import templateData from './templateData';
 3 | import currentEditData from './currentEditData';
 4 | import mediaStateSelect from './mediaStateSelect';
 5 | import userIsLogin from './userIsLogin';
 6 | import historyEdit from './historyEdit';
 7 | 
 8 | const reducer = combineReducers({
 9 |   templateData,
10 |   currentEditData,
11 |   mediaStateSelect,
12 |   userIsLogin,
13 |   historyEdit,
14 | });
15 | 
16 | export default reducer;
17 | 


--------------------------------------------------------------------------------
/site/shared/redux/reducers/mediaStateSelect.js:
--------------------------------------------------------------------------------
 1 | import { POST_TYPE } from '../actionTypes';
 2 | 
 3 | export default function mediaStateSelect(state, action) {
 4 |   switch (action.type) {
 5 |     case POST_TYPE.SET_MEDIA:
 6 |       return action.data || 'Desktop';
 7 |     default:
 8 |       return state || 'Desktop';
 9 |   }
10 | }
11 | 


--------------------------------------------------------------------------------
/site/shared/redux/reducers/templateData.js:
--------------------------------------------------------------------------------
 1 | import { POST_TYPE } from '../actionTypes';
 2 | 
 3 | const TEMPLATE_TYPE = {
 4 |   DEFAULT: 'default',
 5 |   SET: 'set',
 6 |   SUCCESS: 'success',
 7 |   ERROR: 'error',
 8 | };
 9 | 
10 | function resolveTemplateType(actionType) {
11 |   switch (actionType) {
12 |     case POST_TYPE.POST_SET:
13 |       return TEMPLATE_TYPE.SET;
14 |     case POST_TYPE.POST_SUCCESS:
15 |       return TEMPLATE_TYPE.SUCCESS;
16 |     case POST_TYPE.POST_ERROR:
17 |       return TEMPLATE_TYPE.ERROR;
18 |     default:
19 |       return TEMPLATE_TYPE.DEFAULT;
20 |   }
21 | }
22 | 
23 | export default function templateData(state, action) {
24 |   switch (action.type) {
25 |     case POST_TYPE.POST_SUCCESS:
26 |     case POST_TYPE.POST_SET:
27 |     case POST_TYPE.POST_ERROR:
28 |       return {
29 |         type: resolveTemplateType(action.type),
30 |         uid: action.templateData.id,
31 |         data: action.templateData ? { ...action.templateData.attributes } : null,
32 |       };
33 |     case POST_TYPE.SET_USERTEMPLATE:
34 |       return {
35 |         ...action.data.templateData,
36 |       };
37 |     case POST_TYPE.SET_TEMPLATE:
38 |       return {
39 |         type: state.type,
40 |         uid: state.uid,
41 |         data: action.data,
42 |       };
43 |     case POST_TYPE.SET_EDIT:
44 |     case POST_TYPE.SET_MEDIA:
45 |     case POST_TYPE.SET_USER:
46 |       return state || null;
47 |     default:
48 |       return state || {
49 |         type: resolveTemplateType(action.type),
50 |         data: null,
51 |       };
52 |   }
53 | }
54 | 


--------------------------------------------------------------------------------
/site/shared/redux/reducers/userIsLogin.js:
--------------------------------------------------------------------------------
 1 | import { POST_TYPE } from '../actionTypes';
 2 | 
 3 | export default function userIsLogin(state, action) {
 4 |   switch (action.type) {
 5 |     case POST_TYPE.SET_USER:
 6 |       return action.data || false;
 7 |     case POST_TYPE.SET_USERTEMPLATE:
 8 |       return action.data.userIsLogin || false;
 9 |     case POST_TYPE.POST_SUCCESS:
10 |       return action.userIsLogin || false;
11 |     default:
12 |       return state || false;
13 |   }
14 | }
15 | 


--------------------------------------------------------------------------------
/site/shared/url.js:
--------------------------------------------------------------------------------
 1 | import qs from 'query-string';
 2 | 
 3 | // get url query object / specific query value
 4 | export function get(name) {
 5 |   const queryString = ((window && window.location.hash) || '').replace('#', '');
 6 |   const query = qs.parse(queryString);
 7 |   return name ? query[name] : query;
 8 | }
 9 | 
10 | // update url query string
11 | export function update(name, value) {
12 |   if (typeof window === 'undefined') {
13 |     return '';
14 |   }
15 | 
16 |   const urlData = get();
17 |   urlData[name] = value;
18 | 
19 |   window.location.hash = `#${qs.stringify(urlData)}`;
20 | }
21 | 


--------------------------------------------------------------------------------
/site/templates/index.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 |   routes: [
3 |     { path: '/', component: './template/index' },
4 |   ],
5 | };
6 | 


--------------------------------------------------------------------------------
/site/templates/static/bottom-func-bar.less:
--------------------------------------------------------------------------------
 1 | @bottomBar: bottom-func-bar;
 2 | .@{bottomBar} {
 3 |   position: fixed;
 4 |   bottom: 0;
 5 |   height: 32px;
 6 |   line-height: 32px;
 7 |   left: 4%;
 8 |   text-align: center;
 9 |   box-shadow: 0 -2px 6px fade(#000, 15);
10 |   transform: translateY(0%);
11 |   transition: transform .3s @ease-in-out;
12 |   ul {
13 |     display: inline-block;
14 |     border-radius: 4px 4px 0 0;
15 |     overflow: hidden;
16 |     background: @bottom-bar-bg-color;
17 |     li {
18 |       cursor: pointer;
19 |       display: inline-block;
20 |       width: 120px;
21 |       border-right: 1px solid @bottom-bar-line-color;
22 |       color: @template-text-color;
23 |       .anticon {
24 |         margin-right: 8px;
25 |       }
26 |       &:last-child {
27 |         border-right: none;
28 |       }
29 |     }
30 |   }
31 |   .bar-icon {
32 |     background: @bottom-bar-bg-color;
33 |     position: absolute;
34 |     top: -12px;
35 |     width: 32px;
36 |     height: 13px;
37 |     margin: auto;
38 |     left: 0;
39 |     right: 0;
40 |     border-radius: 4px 4px 0 0;
41 |     box-shadow: 0 -2px 6px fade(#000, 15);
42 |     cursor: pointer;
43 |     .arrow {
44 |       display: inline-block;
45 |       position: absolute;
46 |       top: 50%;
47 |       left: ~"calc(50% - 2.8px)";
48 |       svg {
49 |         display: none;
50 |       }
51 |       &:after,
52 |       &:before {
53 |         content: '';
54 |         display: block;
55 |         position: absolute;
56 |         width: 6px;
57 |         height: 2px;
58 |         background: #fff;
59 |         transition: transform .3s @ease-in-out;
60 |       }
61 |       &:after {
62 |         transform: rotate(45deg) translateX(-2px);
63 |       }
64 |       &:before {
65 |         transform: rotate(-45deg) translateX(2px);
66 |       }
67 |       transition: transform .3s @ease-in-out;
68 |     }
69 |   }
70 |   &.close {
71 |     transform: translateY(100%);
72 |     .arrow {
73 |       transform: translateY(-3px);
74 |       &:after {
75 |         transform: rotate(-45deg) translateX(-2px);
76 |       }
77 |       &:before {
78 |         transform: rotate(45deg) translateX(2px);
79 |       }
80 |     }
81 |   }
82 | }
83 | 


--------------------------------------------------------------------------------
/site/templates/static/common.less:
--------------------------------------------------------------------------------
 1 | 
 2 | // @import "~antd/lib/style/v2-compatible-reset.less";
 3 | 
 4 | body {
 5 |   word-wrap: break-word;
 6 | }
 7 | 
 8 | body,
 9 | div,
10 | dl,
11 | dt,
12 | dd,
13 | ul,
14 | ol,
15 | li,
16 | h1,
17 | h2,
18 | h3,
19 | h4,
20 | h5,
21 | h6 {
22 |   margin: 0;
23 |   padding: 0;
24 | }
25 | 
26 | /* .content-wrapper > .tween-one-leaving,
27 | .queue-anim-leaving {
28 |   // position: absolute !important;
29 |   // width: 100%;
30 | } */
31 | 
32 | .video {
33 |   max-width: 800px;
34 | }
35 | 
36 | #react-content {
37 |   min-height: 100%;
38 | }
39 | .home-page-wrapper p {
40 |   padding: 0;
41 |   margin: 0;
42 | }
43 | 


--------------------------------------------------------------------------------
/site/templates/static/content.less:
--------------------------------------------------------------------------------
 1 | @homepage: home-page;
 2 | .@{homepage}-wrapper {
 3 |   width: 100%;
 4 |   position: relative;
 5 |   overflow: hidden;
 6 |   .@{homepage} {
 7 |     height: 100%;
 8 |     max-width: 1200px;
 9 |     position: relative;
10 |     margin: auto;
11 |     will-change: transform;
12 |   }
13 |   .title-wrapper > h1, > h1 {
14 |     font-size: 32px;
15 |     color: @text-color;
16 |     margin-bottom: 16px;
17 |   }
18 |   .title-wrapper {
19 |     margin: 0 auto 64px;
20 |     text-align: center;
21 |   }
22 | }
23 | 
24 | .@{homepage} {
25 |   padding: 128px 24px;
26 | }
27 | 
28 | @media screen and (max-width: 767px) {
29 |   .@{homepage}-wrapper {
30 |     .@{homepage} {
31 |       padding: 56px 24px;
32 |       >h1 {
33 |         font-size: 24px;
34 |         margin: 0 auto 32px;
35 |         &.title-h1 {
36 |           margin-bottom: 8px;
37 |         }
38 |       }
39 |       >p {
40 |         margin-bottom: 32px;
41 |       }
42 |     }
43 |   }
44 | }
45 | 


--------------------------------------------------------------------------------
/site/templates/static/custom.less:
--------------------------------------------------------------------------------
 1 | @import "~antd/lib/style/themes/default.less";
 2 | 
 3 | @line-color: #e9e9e9;
 4 | 
 5 | @shadow-color: rgba(0, 0, 0, 0.15);
 6 | 
 7 | @bottom-bar-bg-color: #262626;
 8 | @bottom-bar-line-color: #000;
 9 | 
10 | @template-bg-color: #001529;
11 | @template-bg-color-light: #ececec;
12 | @template-nav-bg-color: #001529;
13 | @template-text-color: #ccc;
14 | @template-text-title-color: #bcbcbc;
15 | @template-text-color-light: #fff;
16 | @template-footer-text-color: #999;
17 | 
18 | @animate-duration: .45s;
19 | 
20 | /* 详细页图片或框框的样式;
21 | */
22 | .page-shadow() {
23 |   box-shadow: 0 5px 8px @shadow-color;
24 | }
25 | 
26 | .page-pro() {
27 |   border-radius: 6px;
28 |   border: 1px solid @line-color;
29 |   transform: translateY(0);
30 |   transition: transform .3s @ease-out, box-shadow .3s @ease-out;
31 |   &:hover {
32 |     .page-shadow();
33 |     transform: translateY(-5px);
34 |   }
35 | }
36 | 


--------------------------------------------------------------------------------
/site/templates/static/index.less:
--------------------------------------------------------------------------------
 1 | @import './common.less';
 2 | @import './custom.less';
 3 | @import './point.less';
 4 | @import './content.less';
 5 | @import './bottom-func-bar.less';
 6 | 
 7 | .is-edit {
 8 |   * {
 9 |     pointer-events: none;
10 |   }
11 | }
12 | 


--------------------------------------------------------------------------------
/site/templates/static/lessToString.jsx:
--------------------------------------------------------------------------------
 1 | /* eslin import/no-webpack-loader-syntax:[0] */
 2 | import point from '!raw-loader!./point.less';
 3 | import common from '!raw-loader!./common.less';
 4 | import custom from '!raw-loader!./custom.less';
 5 | import content from '!raw-loader!./content.less';
 6 | 
 7 | export default {
 8 |   common,
 9 |   custom,
10 |   point,
11 |   content,
12 | };
13 | 


--------------------------------------------------------------------------------
/site/templates/static/point.less:
--------------------------------------------------------------------------------
 1 | @import './custom.less';
 2 | @point: point;
 3 | .@{point} {
 4 |   float: left;
 5 |   width: 8px;
 6 |   height: 8px;
 7 |   opacity: .5;
 8 |   cursor: pointer;
 9 |   pointer-events: auto;
10 |   transition: opacity .3s @ease-out, background .3s @ease-out;
11 |   margin: 6px auto;
12 |   background: @primary-color;
13 |   border-radius: 100%;
14 |   &.active {
15 |     opacity: 1;
16 |     background: @primary-color;
17 |   }
18 |   &-wrapper {
19 |     position: fixed;
20 |     z-index: 9998;
21 |     top: 0;
22 |     right: 16px;
23 |     width: 10px;
24 |     display: flex;
25 |     height: 100%;
26 |     align-items: center;
27 |     pointer-events: none;
28 |   }
29 |   &-left {
30 |     left: 16px;
31 |   }
32 |   &-rect {
33 |     border-radius: 0;
34 |   }
35 |   &-prismatic {
36 |     border-radius: 0;
37 |     transform: rotate(45deg);
38 |   }
39 |   &-stroke {
40 |     border: 2px solid @primary-color;
41 |     background: transparent;
42 |   }
43 |   &-small {
44 |     width: 6px;
45 |     &.point {
46 |       height: 6px;
47 |     }
48 |   }
49 |   &-large {
50 |     width: 10px;
51 |     &.point {
52 |       height: 10px;
53 |     }
54 |   }
55 | }
56 | 
57 | @media screen and (max-width: 767px) {
58 |   .@{point}-wrapper {
59 |     display: none;
60 |   }
61 | }
62 | 


--------------------------------------------------------------------------------
/site/templates/template/BottomBar.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import { Popconfirm } from 'antd';
 3 | import Icon, {
 4 |   HomeOutlined,
 5 | } from '@ant-design/icons';
 6 | import { getNewHref, RemoveLocalStorage } from '../../utils';
 7 | import { getURLData } from '../../theme/template/utils';
 8 | 
 9 | export default class BottomBar extends React.Component {
10 |   state = {
11 |     close: false,
12 |   }
13 | 
14 |   onRemoveLocalStorage = () => {
15 |     const uid = getURLData('uid');
16 |     localStorage.removeItem(uid);
17 |     location.reload();
18 |   };
19 | 
20 |   onClose = () => {
21 |     const { close } = this.state;
22 |     this.setState({
23 |       close: !close,
24 |     });
25 |   }
26 | 
27 |   render() {
28 |     const { close } = this.state;
29 |     return (
30 |       <div className={`bottom-func-bar${close ? ' close' : ''}`}>
31 |         <div className="bar-icon" onClick={this.onClose}>
32 |           <i className="arrow" />
33 |         </div>
34 |         <ul>
35 |           <li
36 |             onClick={() => {
37 |               location.href = getNewHref('7111', null, true);
38 |             }}
39 |           >
40 |             <HomeOutlined />
41 |             返回首页
42 |           </li>
43 |           {/* <li
44 |             onClick={() => {
45 |               location.href = `${getNewHref('7112', null, true)}${location.hash}`;
46 |             }}
47 |           >
48 |             <EditOutlined />
49 |               返回编辑
50 |           </li> */}
51 |           <li>
52 |             <Popconfirm
53 |               title="清除当前缓存,重新从服务器读取最后保存的数据;如有编辑,请先保存。"
54 |               onConfirm={this.onRemoveLocalStorage}
55 |               okText="确定"
56 |               cancelText="取消"
57 |               overlayStyle={{ width: 320 }}
58 |             >
59 |               <Icon component={() => RemoveLocalStorage('14')} />
60 |               清除缓存
61 |             </Popconfirm>
62 |           </li>
63 |         </ul>
64 |       </div>
65 |     );
66 |   }
67 | }
68 | 


--------------------------------------------------------------------------------
/site/templates/template/NotFound.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | 
 3 | export default function NotFound(props) {
 4 |   return (
 5 |     <div id="page-404" className={props.className}>
 6 |       <section>
 7 |         <h1>
 8 |           404
 9 |         </h1>
10 |         <p>
11 |           你要找的页面不存在
12 |           {' '}
13 |           <a href="/">
14 |             返回首页
15 |           </a>
16 |         </p>
17 |       </section>
18 |       <style
19 |         dangerouslySetInnerHTML={{
20 |           __html: '#page-404{ height: calc(100% - 199px);}',
21 |         }}
22 |       />
23 |     </div>
24 |   );
25 | }
26 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Banner0/index.less:
--------------------------------------------------------------------------------
 1 | @import '../../../static/custom.less';
 2 | @banner0: banner0;
 3 | .@{banner0} {
 4 |   // 如果在第一屏且导航位置为 relative, 一屏为 height: calc(~"100vh - 64px");
 5 |   width: 100%;
 6 |   height: 100vh;
 7 |   position: relative;
 8 |   text-align: center;
 9 |   border-color: #666;
10 |   background-image: url("https://zos.alipayobjects.com/rmsportal/gGlUMYGEIvjDOOw.jpg");
11 |   background-size: cover;
12 |   background-attachment: fixed;
13 |   background-position: center;
14 |   & &-text-wrapper {
15 |     display: inline-block;
16 |     position: absolute;
17 |     top: 20%;
18 |     margin: auto;
19 |     left: 0;
20 |     right: 0;
21 |     font-size: 14px;
22 |     color: @template-text-color-light;
23 |     width: 550px;
24 |     >.queue-anim-leaving {
25 |       position: relative !important;
26 |     }
27 |   }
28 |   & &-title {
29 |     width: 350px;
30 |     left: 30px;
31 |     min-height: 60px;
32 |     margin: auto;
33 |     display: inline-block;
34 |     font-size: 40px;
35 |     position: relative;
36 |   }
37 |   & &-content {
38 |     margin-bottom: 20px;
39 |     word-wrap: break-word;
40 |     min-height: 24px;
41 |   }
42 |   & &-button {
43 |     border: 1px solid #fff;
44 |     color: #fff;
45 |     background: transparent;
46 |     box-shadow: 0 0 0 transparent;
47 |     font-size: 16px;
48 |     height: 40px;
49 |     transition: background .45s @ease-out, box-shadow .45s @ease-out;
50 |     &:hover {
51 |       color: #fff;
52 |       border-color: #fff;
53 |       background: rgba(255, 255, 255, 0.1);
54 |       box-shadow: 0 0 10px rgba(50, 250, 255, 0.75);
55 |     }
56 |     &:focus {
57 |       color: #fff;
58 |       border-color: #fff;
59 |     }
60 |     &.queue-anim-leaving {
61 |       width: auto;
62 |     }
63 |   }
64 |   & &-icon {
65 |     bottom: 20px;
66 |     font-size: 24px;
67 |     position: absolute;
68 |     left: 50%;
69 |     margin-left: -12px;
70 |     color: @template-text-color-light;
71 |   }
72 | }
73 | 
74 | @media screen and (max-width: 767px) {
75 |   .@{banner0} {
76 |     background-attachment: inherit;
77 |     & &-text-wrapper {
78 |       width: 90%;
79 |     }
80 |     & &-title {
81 |       width: 90%;
82 |       left: 0;
83 |     }
84 |   }
85 | }
86 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Banner0/template.config.js:
--------------------------------------------------------------------------------
 1 | import component from './index';
 2 | 
 3 | import less from '!raw-loader!./index.less';
 4 | import templateStr from '!raw-loader!./index';
 5 | 
 6 | export default {
 7 |   component,
 8 |   templateStr,
 9 |   less,
10 |   dataSource: {
11 |     wrapper: {
12 |       className: 'banner0',
13 |     },
14 |     textWrapper: {
15 |       className: 'banner0-text-wrapper',
16 |     },
17 |     title: {
18 |       className: 'banner0-title',
19 |       children: 'https://zos.alipayobjects.com/rmsportal/HqnZZjBjWRbjyMr.png',
20 |     },
21 |     content: {
22 |       className: 'banner0-content',
23 |       children: '一个高效的页面动画解决方案',
24 |     },
25 |     button: {
26 |       className: 'banner0-button',
27 |       children: 'Learn More',
28 |     },
29 |   },
30 | };
31 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Banner2/template.config.js:
--------------------------------------------------------------------------------
 1 | import component from './index';
 2 | 
 3 | import less from '!raw-loader!./index.less';
 4 | import templateStr from '!raw-loader!./index';
 5 | 
 6 | export default {
 7 |   component,
 8 |   templateStr,
 9 |   less,
10 |   dataSource: {
11 |     wrapper: {
12 |       className: 'banner2',
13 |     },
14 |     BannerAnim: {
15 |       children: [
16 |         {
17 |           name: 'elem0',
18 |           BannerElement: {
19 |             className: 'banner-user-elem',
20 |           },
21 |           page: {
22 |             className: 'home-page banner2-page',
23 |           },
24 |           textWrapper: {
25 |             className: 'banner2-text-wrapper',
26 |           },
27 |           bg: {
28 |             className: 'bg bg0',
29 |           },
30 |           title: {
31 |             className: 'banner2-title',
32 |             children: 'Ant Motion',
33 |           },
34 |           content: {
35 |             className: 'banner2-content',
36 |             children: '一个高效的页面动画解决方案',
37 |           },
38 |           button: {
39 |             className: 'banner2-button',
40 |             children: 'Learn More',
41 |           },
42 |         },
43 |       ],
44 |     },
45 |   },
46 | };
47 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Banner3/index.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import { Button } from 'antd';
 3 | import QueueAnim from 'rc-queue-anim';
 4 | import Texty from 'rc-texty';
 5 | import 'rc-texty/assets/index.css';
 6 | /* replace-start */
 7 | import './index.less';
 8 | /* replace-end */
 9 | class Banner extends React.PureComponent {
10 |   render() {
11 |     const { ...currentProps } = this.props;
12 |     const { dataSource } = currentProps;
13 |     delete currentProps.dataSource;
14 |     delete currentProps.isMobile;
15 |     const children = dataSource.textWrapper.children.map((item) => {
16 |       const { name, texty, ...$item } = item;
17 |       if (name.match('button')) {
18 |         return (
19 |           <Button
20 |             type="primary"
21 |             key={name}
22 |             {...$item}
23 |             /* replace-start */
24 |             data-edit="link,text"
25 |             /* replace-end */
26 |           >
27 |             {/* replace-start-value = item.children */
28 |               React.createElement('span', { dangerouslySetInnerHTML: { __html: item.children } })
29 |            /* replace-end-value */}
30 |           </Button>
31 |         );
32 |       }
33 |       /* replace-start */
34 |       if (texty) {
35 |         $item['data-edit'] = 'texty';
36 |       }
37 |       /* replace-end */
38 |       return (
39 |         <div
40 |           key={name}
41 |           {...$item}
42 |         >
43 |           {
44 |             texty
45 |               ? (
46 |                 <Texty type="mask-bottom">
47 |                   {item.children}
48 |                 </Texty>
49 |               )
50 |               : (
51 |                 /* replace-start-value = item.children */
52 |                 React.createElement('span', { dangerouslySetInnerHTML: { __html: item.children } })
53 |                 /* replace-end-value */
54 |               )
55 |           }
56 |         </div>
57 |       );
58 |     });
59 |     return (
60 |       <div
61 |         {...currentProps}
62 |         {...dataSource.wrapper}
63 |       >
64 |         <QueueAnim
65 |           key="QueueAnim"
66 |           type={['bottom', 'top']}
67 |           delay={200}
68 |           {...dataSource.textWrapper}
69 |         >
70 |           {children}
71 |         </QueueAnim>
72 |       </div>
73 |     );
74 |   }
75 | }
76 | export default Banner;
77 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Banner3/template.config.js:
--------------------------------------------------------------------------------
 1 | import component from './index';
 2 | 
 3 | import less from '!raw-loader!./index.less';
 4 | import templateStr from '!raw-loader!./index';
 5 | 
 6 | export default {
 7 |   component,
 8 |   templateStr,
 9 |   less,
10 |   dataSource: {
11 |     wrapper: {
12 |       className: 'banner3',
13 |     },
14 |     textWrapper: {
15 |       className: 'banner3-text-wrapper',
16 |       children: [
17 |         { name: 'nameEn', className: 'banner3-name-en', children: 'Seeking Experience & Engineering Conference' },
18 |         { name: 'slogan', className: 'banner3-slogan', children: '首届蚂蚁金服体验科技大会', texty: true },
19 |         { name: 'name', className: 'banner3-name', children: '探索极致用户体验与最佳工程实践探索' },
20 |         { name: 'button', className: 'banner3-button', children: '立即报名' },
21 |         { name: 'time', className: 'banner3-time', children: '2018.01.06 / 中国·杭州' },
22 |       ],
23 |     },
24 |   },
25 | };
26 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Banner4/index.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import QueueAnim from 'rc-queue-anim';
 3 | import TweenOne from 'rc-tween-one';
 4 | /* replace-start-value = import { getChildrenToRender } from './utils'; */
 5 | import { getChildrenToRender } from '../../utils';
 6 | /* replace-end-value */
 7 | /* replace-start */
 8 | import './index.less';
 9 | /* replace-end */
10 | class Banner4 extends React.PureComponent {
11 |   render() {
12 |     const { ...tagProps } = this.props;
13 |     const { dataSource } = tagProps;
14 |     delete tagProps.dataSource;
15 |     delete tagProps.isMobile;
16 |     const animType = {
17 |       queue: 'bottom',
18 |       one: {
19 |         y: '+=30', opacity: 0, type: 'from', ease: 'easeOutQuad',
20 |       },
21 |     };
22 |     return (
23 |       <div
24 |         {...tagProps}
25 |         {...dataSource.wrapper}
26 |       >
27 |         <div
28 |           {...dataSource.page}
29 |         >
30 |           <QueueAnim
31 |             key="text"
32 |             type={animType.queue}
33 |             leaveReverse
34 |             ease={['easeOutQuad', 'easeInQuad']}
35 |             {...dataSource.childWrapper}
36 |             componentProps={{ md: dataSource.childWrapper.md, xs: dataSource.childWrapper.xs }}
37 |             /* replace-start */
38 |             data-edit="childWrapper"
39 |           /* replace-end */
40 |           >
41 |             {
42 |               dataSource.childWrapper.children.map(getChildrenToRender)
43 |             }
44 |           </QueueAnim>
45 |           <TweenOne
46 |             animation={animType.one}
47 |             key="title"
48 |             {...dataSource.image}
49 |           >
50 |             <img src={dataSource.image.children} width="100%" alt="img" />
51 |           </TweenOne>
52 |         </div>
53 |       </div>
54 |     );
55 |   }
56 | }
57 | export default Banner4;
58 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Banner4/index.less:
--------------------------------------------------------------------------------
 1 | @import '../../../static/custom.less';
 2 | @banner4: banner4;
 3 | 
 4 | .@{banner4} {
 5 |   // 如果在第一屏且导航位置为 relative, 一屏为 height: calc(~"100vh - 64px");
 6 |   width: 100%;
 7 |   height: 100vh;
 8 |   position: relative;
 9 |   text-align: center;
10 |   background: #4b5564;
11 |   overflow: hidden;
12 | 
13 |   & &-page {
14 |     padding: 1px 0 0;
15 |   }
16 | 
17 |   &-title-wrapper {
18 |     margin-top: 64px;
19 |   }
20 | 
21 |   &-title {
22 |     color: #fff;
23 |     font-size: 48px;
24 |     line-height: 1.5;
25 |   }
26 | 
27 |   &-content {
28 |     font-size: 14px;
29 |     line-height: 20px;
30 |     color: #fff;
31 |     margin: 8px auto 16px;
32 |   }
33 | 
34 |   &-image, &-image-mobile {
35 |     width: 80%;
36 |     max-height: 60%;
37 |     overflow: hidden;
38 |     margin: auto;
39 |     position: absolute;
40 |     bottom: 0;
41 |     left: 0;
42 |     right: 0;
43 |   }
44 | }
45 | 
46 | @media screen and (max-width: 767px) {
47 |   .@{banner4} {
48 |     height: 500px;
49 |     & &-page.home-page {
50 |       padding-top: 1px;
51 |       padding-bottom: 0;
52 |     }
53 | 
54 |     &-title-wrapper {
55 |       margin-top: 96px;
56 |     }
57 |     &-title {
58 |       font-size: 3em;
59 |     }
60 |     &-image {
61 |       width: 100%;
62 |       padding: 0 24px;
63 |     }
64 |   }
65 | }
66 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Banner4/template.config.js:
--------------------------------------------------------------------------------
 1 | import component from './index';
 2 | 
 3 | import less from '!raw-loader!./index.less';
 4 | import templateStr from '!raw-loader!./index';
 5 | 
 6 | export default {
 7 |   component,
 8 |   templateStr,
 9 |   less,
10 |   dataSource: {
11 |     wrapper: {
12 |       className: 'home-page-wrapper banner4',
13 |     },
14 |     page: {
15 |       className: 'home-page banner4-page',
16 |     },
17 |     childWrapper: {
18 |       className: 'banner4-title-wrapper',
19 |       children: [
20 |         {
21 |           name: 'title',
22 |           children: 'Ant Design Pro',
23 |           className: 'banner4-title',
24 |         },
25 |         {
26 |           name: 'content',
27 |           className: 'banner4-content',
28 |           children: '开箱即用的中台前端/设计解决方案',
29 |         },
30 |         {
31 |           name: 'button',
32 |           children: {
33 |             href: '#',
34 |             type: 'primary',
35 |             children: '开始使用',
36 |           },
37 |         },
38 |       ],
39 |     },
40 |     image: {
41 |       className: 'banner4-image',
42 |       children: 'https://gw.alipayobjects.com/mdn/rms/afts/img/A*k3InRLiZDk4AAAAAAAAAAABjARQnAQ',
43 |     },
44 |   },
45 | };
46 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Banner5/index.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import QueueAnim from 'rc-queue-anim';
 3 | import TweenOne from 'rc-tween-one';
 4 | /* replace-start-value = import { getChildrenToRender } from './utils'; */
 5 | import { getChildrenToRender } from '../../utils';
 6 | /* replace-end-value */
 7 | /* replace-start */
 8 | import './index.less';
 9 | /* replace-end */
10 | class Banner5 extends React.PureComponent {
11 |   render() {
12 |     const { ...tagProps } = this.props;
13 |     const { dataSource } = tagProps;
14 |     delete tagProps.dataSource;
15 |     delete tagProps.isMobile;
16 |     const animType = {
17 |       queue: 'bottom',
18 |       one: {
19 |         y: '+=30', opacity: 0, type: 'from', ease: 'easeOutQuad',
20 |       },
21 |     };
22 |     return (
23 |       <div
24 |         {...tagProps}
25 |         {...dataSource.wrapper}
26 |       >
27 |         <div
28 |           {...dataSource.page}
29 |         >
30 |           <QueueAnim
31 |             key="text"
32 |             type={animType.queue}
33 |             leaveReverse
34 |             ease={['easeOutQuad', 'easeInQuad']}
35 |             {...dataSource.childWrapper}
36 |             componentProps={{ md: dataSource.childWrapper.md, xs: dataSource.childWrapper.xs }}
37 |             /* replace-start */
38 |             data-edit="childWrapper"
39 |           /* replace-end */
40 |           >
41 |             {
42 |               dataSource.childWrapper.children.map(getChildrenToRender)
43 |             }
44 |           </QueueAnim>
45 |           <TweenOne
46 |             animation={animType.one}
47 |             key="title"
48 |             {...dataSource.image}
49 |           >
50 |             <img src={dataSource.image.children} width="100%" alt="img" />
51 |           </TweenOne>
52 |         </div>
53 |       </div>
54 |     );
55 |   }
56 | }
57 | export default Banner5;
58 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Banner5/template.config.js:
--------------------------------------------------------------------------------
 1 | import component from './index';
 2 | 
 3 | import less from '!raw-loader!./index.less';
 4 | import templateStr from '!raw-loader!./index';
 5 | 
 6 | export default {
 7 |   component,
 8 |   templateStr,
 9 |   less,
10 |   dataSource: {
11 |     wrapper: {
12 |       className: 'home-page-wrapper banner5',
13 |     },
14 |     page: {
15 |       className: 'home-page banner5-page',
16 |     },
17 |     childWrapper: {
18 |       className: 'banner5-title-wrapper',
19 |       children: [
20 |         {
21 |           name: 'title',
22 |           children: '产品名',
23 |           className: 'banner5-title',
24 |         },
25 |         {
26 |           name: 'explain',
27 |           className: 'banner5-explain',
28 |           children: '产品标语介绍',
29 |         },
30 |         {
31 |           name: 'content',
32 |           className: 'banner5-content',
33 |           children: '产品的详细说明,如是什么东西之类的文字',
34 |         },
35 |         {
36 |           name: 'button',
37 |           className: 'banner5-button-wrapper',
38 |           children: {
39 |             href: '#',
40 |             className: 'banner5-button',
41 |             type: 'primary',
42 |             children: '开始使用',
43 |           },
44 |         },
45 |       ],
46 |     },
47 |     image: {
48 |       className: 'banner5-image',
49 |       children: 'https://gw.alipayobjects.com/mdn/rms_ae7ad9/afts/img/A*-wAhRYnWQscAAAAAAAAAAABkARQnAQ',
50 |     },
51 |   },
52 | };
53 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Content0/index.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import QueueAnim from 'rc-queue-anim';
 3 | import { Row, Col } from 'antd';
 4 | import OverPack from 'rc-scroll-anim/lib/ScrollOverPack';
 5 | /* replace-start-value = import { getChildrenToRender } from './utils'; */
 6 | import { getChildrenToRender } from '../../utils';
 7 | /* replace-end-value */
 8 | /* replace-start */
 9 | import './index.less';
10 | /* replace-end */
11 | 
12 | class Content extends React.PureComponent {
13 |   render() {
14 |     const { dataSource, isMobile, ...props } = this.props;
15 |     const { wrapper, titleWrapper, page, OverPack: overPackData, childWrapper } = dataSource;
16 |     return (
17 |       <div
18 |         {...props}
19 |         {...wrapper}
20 |       >
21 |         <div {...page}>
22 |           <div
23 |             {...titleWrapper}
24 |             /* replace-start */
25 |             data-edit="titleWrapper"
26 |           /* replace-end */
27 |           >
28 |             {
29 |               titleWrapper.children.map(getChildrenToRender)
30 |             }
31 |           </div>
32 |           <OverPack {...overPackData}>
33 |             <QueueAnim
34 |               type="bottom"
35 |               key="block"
36 |               leaveReverse
37 |               component={Row}
38 |               componentProps={childWrapper}
39 |               /* replace-start */
40 |               data-edit="Row"
41 |             /* replace-end */
42 |             >
43 |               {childWrapper.children.map((block, i) => {
44 |                 const { children: item, ...blockProps } = block;
45 |                 return (
46 |                   <Col
47 |                     key={i.toString()}
48 |                     {...blockProps}
49 |                     /* replace-start */
50 |                     data-edit="Col"
51 |                   /* replace-end */
52 |                   >
53 |                     <div
54 |                       {...item}
55 |                       /* replace-start */
56 |                       data-edit="childWrapper"
57 |                     /* replace-end */
58 |                     >
59 |                       {item.children.map(getChildrenToRender)}
60 |                     </div>
61 |                   </Col>
62 |                 );
63 |               })}
64 |             </QueueAnim>
65 |           </OverPack>
66 |         </div>
67 |       </div>
68 |     );
69 |   }
70 | }
71 | 
72 | export default Content;
73 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Content0/index.less:
--------------------------------------------------------------------------------
 1 | @import '../../../static/custom.less';
 2 | @content0: content0;
 3 | 
 4 | .@{content0}-wrapper {
 5 |   min-height: 446px;
 6 |   overflow: hidden;
 7 | 
 8 |   .@{content0} {
 9 |     height: 100%;
10 |     padding: 64px 24px;
11 | 
12 |     >.title-wrapper {
13 |       margin: 0 auto 48px;
14 |     }
15 | 
16 |     &-block {
17 |       padding: 0 4%;
18 |       display: inline-block;
19 |       text-align: center;
20 |       min-height: 200px;
21 |       margin-bottom: 24px;
22 |       img {
23 |         width: 100%;
24 |       }
25 | 
26 |       &-wrapper {
27 |         position: relative;
28 |         height: 100%;
29 |         top: 25%;
30 |         padding: 20px 0;
31 |       }
32 | 
33 |       &.queue-anim-leaving {
34 |         position: relative !important;
35 |       }
36 | 
37 |       &-icon {
38 |         width: 100px;
39 |         height: 100px;
40 |         margin: auto;
41 |       }
42 | 
43 |       &-title {
44 |         line-height: 32px;
45 |         margin: 10px auto;
46 |         font-size: 24px;
47 |       }
48 |     }
49 |   }
50 | }
51 | 
52 | @media screen and (max-width: 767px) {
53 |   .@{content0}-wrapper {
54 |     min-height: 880px;
55 |   }
56 | }
57 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Content1/index.less:
--------------------------------------------------------------------------------
 1 | @import '../../../static/custom.less';
 2 | @content1: content1;
 3 | .@{content1}-wrapper {
 4 |   height: 360px;
 5 |   .@{content1} {
 6 |     height: 100%;
 7 |     padding: 0 24px;
 8 |     &-img {
 9 |       height: 100%;
10 |       transform-origin: top;
11 |       padding: 0 32px;
12 |       display: flex;
13 |       align-items: center;
14 |       justify-content: center;
15 |       span {
16 |         display: block;
17 |         width: 250px;
18 |         img {
19 |           display: block;
20 |         }
21 |       }
22 |     }
23 |     &-text {
24 |       padding: 0 32px;
25 |       height: 100%;
26 |       .@{content1}-content,
27 |       .@{content1}-title {
28 |         position: relative !important;
29 |       }
30 |       .@{content1}-title {
31 |         font-size: 32px;
32 |         font-weight: normal;
33 |         color: #404040;
34 |         margin-top: 120px;
35 |       }
36 |       .content {
37 |         margin-top: 20px;
38 |       }
39 |     }
40 |   }
41 | }
42 | 
43 | @media screen and (max-width: 767px) {
44 |   .@{content1}-wrapper {
45 |     height: 600px;
46 |     .@{content1} {
47 |       &-img {
48 |         height: 200px;
49 |         padding: 0;
50 |         text-align: center;
51 |         margin-top: 64px;
52 |         span {
53 |           display: inline-block;
54 |           width: 180px;
55 |           height: 200px;
56 |           line-height: 200px;
57 |           margin: auto;
58 |         }
59 |       }
60 |       &-text {
61 |         height: auto;
62 |         margin-bottom: 20px;
63 |         text-align: center;
64 |         padding: 0;
65 |         .@{content1}-content,
66 |         .@{content1}-title {
67 |           width: 100%;
68 |           top: auto;
69 |         }
70 |         .@{content1}-title {
71 |           margin: 32px auto 16px;
72 |           font-size: 24px;
73 |         }
74 |       }
75 |     }
76 |   }
77 | }
78 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Content1/template.config.js:
--------------------------------------------------------------------------------
 1 | import component from './index';
 2 | 
 3 | import less from '!raw-loader!./index.less';
 4 | import templateStr from '!raw-loader!./index';
 5 | 
 6 | export default {
 7 |   component,
 8 |   templateStr,
 9 |   less,
10 |   dataSource: {
11 |     wrapper: {
12 |       className: 'home-page-wrapper content1-wrapper',
13 |     },
14 |     OverPack: {
15 |       className: 'home-page content1',
16 |       playScale: 0.3,
17 |     },
18 |     imgWrapper: {
19 |       className: 'content1-img',
20 |       md: 10,
21 |       xs: 24,
22 |     },
23 |     img: {
24 |       children: 'https://zos.alipayobjects.com/rmsportal/nLzbeGQLPyBJoli.png',
25 |     },
26 |     textWrapper: {
27 |       className: 'content1-text',
28 |       md: 14,
29 |       xs: 24,
30 |     },
31 |     title: {
32 |       className: 'content1-title',
33 |       children: '企业资源管理',
34 |     },
35 |     content: {
36 |       className: 'content1-content',
37 |       children: '云资源集中编排、弹性伸缩、持续发布和部署,高可用及容灾。'
38 |         + '云资源集中编排、弹性伸缩、持续发布和部署,高可用及容灾。'
39 |         + '云资源集中编排、弹性伸缩、持续发布和部署,高可用及容灾。',
40 |     },
41 |   },
42 | };
43 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Content10/index.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import QueueAnim from 'rc-queue-anim';
 3 | /* replace-start */
 4 | import './index.less';
 5 | /* replace-end */
 6 | 
 7 | class Content10 extends React.PureComponent {
 8 |   constructor(props) {
 9 |     super(props);
10 |     this.state = {
11 |       showInfo: props.isMobile,
12 |     };
13 |   }
14 | 
15 |   onClick = () => {
16 |     window.open(this.props.dataSource.Content.children.url.children);
17 |   }
18 | 
19 |   markerEnter = () => {
20 |     this.setState({
21 |       showInfo: true,
22 |     });
23 |   }
24 | 
25 |   markerLeave = () => {
26 |     this.setState({
27 |       showInfo: false,
28 |     });
29 |   }
30 | 
31 |   render() {
32 |     const { ...props } = this.props;
33 |     const { dataSource } = props;
34 |     delete props.dataSource;
35 |     delete props.isMobile;
36 |     return (
37 |       <div
38 |         {...props}
39 |         {...dataSource.wrapper}
40 | 
41 |       >
42 |         <div
43 |           {...dataSource.Content}
44 |           onMouseEnter={this.markerEnter}
45 |           onMouseLeave={this.markerLeave}
46 |           onClick={this.onClick}
47 |           onTouchEnd={this.onClick}
48 |           /* replace-start */
49 |           data-edit="Content"
50 |         /* replace-end */
51 |         >
52 |           <div
53 |             {...dataSource.Content.children.icon}
54 |             /* replace-start */
55 |             data-edit="Content,image"
56 |           /* replace-end */
57 |           >
58 |             <img src={dataSource.Content.children.icon.children} alt="img" />
59 |           </div>
60 |           <div
61 |             {...dataSource.Content.children.iconShadow}
62 |             /* replace-start */
63 |             data-edit="Content,image"
64 |           /* replace-end */
65 |           >
66 |             <img src={dataSource.Content.children.iconShadow.children} alt="img" />
67 |           </div>
68 |         </div>
69 |         <QueueAnim type="scale">
70 |           {this.state.showInfo && (
71 |             <div className="map-tip" key="map">
72 |               <h2>{dataSource.Content.children.title.children}</h2>
73 |               <p>{dataSource.Content.children.content.children}</p>
74 |             </div>
75 |           )}
76 |         </QueueAnim>
77 |       </div>
78 |     );
79 |   }
80 | }
81 | 
82 | export default Content10;
83 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Content10/index.less:
--------------------------------------------------------------------------------
 1 | @import '../../../static/custom.less';
 2 | @content10: content10;
 3 | .@{content10}-wrapper {
 4 |   height: 480px;
 5 |   background: url(https://gw.alipayobjects.com/os/s/prod/seeconf/c66ebea962cdf544926ca5a472dea5ea.jpg) no-repeat 50%;
 6 |   background-size: cover;
 7 |   position: relative;
 8 |   display: flex;
 9 |   justify-content: center;
10 |   align-items: center;
11 |   .icon-wrapper {
12 |     text-align: center;
13 |     position: relative;
14 |     cursor: pointer;
15 |     img {
16 |       display: block;
17 |     }
18 |   }
19 |   .icon {
20 |     position: relative;
21 |     z-index: 1;
22 |     animation: BeatAnim 2s ease-in-out infinite;
23 |   }
24 |   .icon-shadow {
25 |     display: inline-block;
26 |     position: relative;
27 |     top: -12px;
28 |     z-index: 0;
29 |     animation: ScaleAnim 2s ease-in-out infinite;
30 |     transform-origin: 50%;
31 |   }
32 |   .map-tip {
33 |     position: absolute;
34 |     width: 330px;
35 |     background: #fff;
36 |     padding: 16px;
37 |     border-radius: 4px;
38 |     box-shadow: 0 2px 8px rgba(13, 26, 38, 0.12);
39 |     left: 50%;
40 |     top: 50%;
41 |     margin-left: 30px;
42 |     margin-top: -60px;
43 |     font-size: 14px;
44 |     z-index: 10;
45 |     transform-origin: 0 50%;
46 |     text-align: left;
47 |     h2 {
48 |       font-size: 16px;
49 |       color: #0d1a26;
50 |       margin-bottom: 8px;
51 |     }
52 |   }
53 | }
54 | 
55 | @media screen and (max-width: 767px) {
56 |   .@{content10}-wrapper {
57 |     padding-bottom: 0;
58 |   }
59 | }
60 | 
61 | @keyframes BeatAnim {
62 |   0%,
63 |   25%,
64 |   35%,
65 |   45% {
66 |     transform: translateY(0);
67 |   }
68 |   15% {
69 |     transform: translateY(-30px);
70 |   }
71 |   30% {
72 |     transform: translateY(-15px);
73 |   }
74 |   40% {
75 |     transform: translateY(-7px);
76 |   }
77 | }
78 | 
79 | @keyframes ScaleAnim {
80 |   0%,
81 |   25%,
82 |   35%,
83 |   45% {
84 |     transform: scale(1);
85 |   }
86 |   15% {
87 |     transform: scale(0.5);
88 |   }
89 |   30% {
90 |     transform: scale(0.7);
91 |   }
92 |   40% {
93 |     transform: scale(0.9);
94 |   }
95 | }
96 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Content10/template.config.js:
--------------------------------------------------------------------------------
 1 | import component from './index';
 2 | import less from '!raw-loader!./index.less';
 3 | import templateStr from '!raw-loader!./index';
 4 | 
 5 | export default {
 6 |   component,
 7 |   templateStr,
 8 |   less,
 9 |   dataSource: {
10 |     wrapper: {
11 |       className: 'home-page-wrapper content10-wrapper',
12 |     },
13 |     Content: {
14 |       className: 'icon-wrapper',
15 |       children: {
16 |         icon: {
17 |           className: 'icon',
18 |           children: 'https://gw.alipayobjects.com/zos/rmsportal/zIUVomgdcKEKcnnQdOzw.svg',
19 |           name: '主要图标',
20 |         },
21 |         iconShadow: {
22 |           className: 'icon-shadow',
23 |           children: 'https://gw.alipayobjects.com/zos/rmsportal/WIePwurYppfVvDNASZRN.svg',
24 |           name: '图标影阴',
25 |         },
26 |         url: {
27 |           children: 'https://gaode.com/place/B0FFH3KPBX',
28 |           name: '跳转地址',
29 |         },
30 |         title: {
31 |           children: '大会地址',
32 |           name: '弹框标题',
33 |         },
34 |         content: {
35 |           children: '蚂蚁 Z 空间  浙江省杭州市西湖区西溪路556号',
36 |           name: '弹框内容',
37 |         },
38 |       },
39 |     },
40 |   },
41 | };
42 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Content11/index.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import OverPack from 'rc-scroll-anim/lib/ScrollOverPack';
 3 | import QueueAnim from 'rc-queue-anim';
 4 | import TweenOne from 'rc-tween-one';
 5 | import { Button } from 'antd';
 6 | /* replace-start-value = import { getChildrenToRender } from './utils'; */
 7 | import { getChildrenToRender } from '../../utils';
 8 | /* replace-end-value */
 9 | /* replace-start */
10 | import './index.less';
11 | /* replace-end */
12 | 
13 | class Content11 extends React.PureComponent {
14 |   render() {
15 |     const { ...props } = this.props;
16 |     const { dataSource } = props;
17 |     delete props.dataSource;
18 |     delete props.isMobile;
19 |     return (
20 |       <OverPack
21 |         {...props}
22 |         {...dataSource.OverPack}
23 |       >
24 |         <QueueAnim
25 |           type="bottom"
26 |           leaveReverse
27 |           key="page"
28 |           delay={[0, 100]}
29 |           {...dataSource.titleWrapper}
30 |           /* replace-start */
31 |           data-edit="titleWrapper"
32 |         /* replace-end */
33 |         >
34 |           {
35 |             dataSource.titleWrapper.children.map(getChildrenToRender)
36 |           }
37 |         </QueueAnim>
38 |         <TweenOne
39 |           key="button"
40 |           style={{ textAlign: 'center' }}
41 |           {...dataSource.button}
42 |           animation={{ y: 30, opacity: 0, type: 'from', delay: 300 }}
43 |         >
44 |           <Button
45 |             {...dataSource.button.children.a}
46 |             /* replace-start */
47 |             data-edit="link,text"
48 |           /* replace-end */
49 |           >
50 | 
51 |             {
52 |               /* replace-start-value = dataSource.button.children.a.children */
53 |               React.createElement('span', { dangerouslySetInnerHTML: { __html: dataSource.button.children.a.children } })
54 |               /* replace-end-value */
55 |             }
56 |           </Button>
57 |         </TweenOne>
58 |       </OverPack>
59 |     );
60 |   }
61 | }
62 | 
63 | export default Content11;
64 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Content11/index.less:
--------------------------------------------------------------------------------
 1 | @import '../../../static/custom.less';
 2 | @content11: content11;
 3 | .@{content11}-wrapper {
 4 |   height: 480px;
 5 |   background: url("https://gw.alipayobjects.com/zos/rmsportal/ZsWYzLOItgeaWDSsXdZd.svg") no-repeat bottom;
 6 |   background-size: cover;
 7 |   background-size: 100%;
 8 |   margin: 0 auto;
 9 |   overflow: hidden;
10 |   padding-top: 96px;
11 |   &.home-page-wrapper {
12 |     .title-wrapper {
13 |       margin-bottom: 32px;
14 |     }
15 |   }
16 |   .button {
17 |     box-shadow: 0 8px 16px #0554b7;
18 |     background: linear-gradient(to right, #05cbff, #1e5aff) !important;
19 |     height: 42px;
20 |     line-height: 42px;
21 |     font-size: 14px;
22 |     border: 0;
23 |     border-radius: 21px;
24 |     color: #fff;
25 |     width: 128px;
26 |     padding: 0 15px;
27 |     display: inline-block;
28 |     transition: transform .3s, box-shadow .3s;
29 |     &:hover {
30 |       transform: translateY(-4px);
31 |       box-shadow: 0 12px 20px #0554b7;
32 |     }
33 |     &:active {
34 |       transform: translateY(4px);
35 |       box-shadow: 0 4px 8px #0554b7;
36 |     }
37 |   }
38 |   .title-content {
39 |     line-height: 32px;
40 |   }
41 | }
42 | 
43 | @media screen and (max-width: 767px) {
44 |   .@{content11}-wrapper {
45 |     padding-bottom: 0;
46 |   }
47 | }
48 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Content11/template.config.js:
--------------------------------------------------------------------------------
 1 | import component from './index';
 2 | import less from '!raw-loader!./index.less';
 3 | import templateStr from '!raw-loader!./index';
 4 | 
 5 | export default {
 6 |   component,
 7 |   templateStr,
 8 |   less,
 9 |   dataSource: {
10 |     OverPack: {
11 |       className: 'home-page-wrapper content11-wrapper',
12 |       playScale: 0.3,
13 |     },
14 |     titleWrapper: {
15 |       className: 'title-wrapper',
16 |       children: [
17 |         {
18 |           name: 'image',
19 |           children: 'https://gw.alipayobjects.com/zos/rmsportal/PiqyziYmvbgAudYfhuBr.svg',
20 |           className: 'title-image',
21 |         },
22 |         {
23 |           name: 'title',
24 |           children: '丰富的特色展台',
25 |           className: 'title-h1',
26 |         },
27 |         {
28 |           name: 'content',
29 |           children: '特色展台包括 Ant Design 、AntV、AntG、Egg 等明星产品,更有产品专家',
30 |           className: 'title-content',
31 |         },
32 |         {
33 |           name: 'content2',
34 |           children: '现场问诊,为你答疑解难',
35 |           className: 'title-content',
36 |         },
37 |       ],
38 |     },
39 |     button: {
40 |       className: '',
41 |       children: {
42 |         a: {
43 |           className: 'button',
44 |           href: '#',
45 |           children: '立即报名',
46 |         },
47 |       },
48 |     },
49 |   },
50 | };
51 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Content12/index.less:
--------------------------------------------------------------------------------
 1 | @import '../../../static/custom.less';
 2 | @content12: content12;
 3 | .@{content12}-wrapper {
 4 |   background-color: #fafafa;
 5 |   min-height: 470px;
 6 |   .@{content12} {
 7 |     padding: 64px 24px;
 8 |     >p {
 9 |       text-align: center;
10 |     }
11 |   }
12 |   .img-wrapper {
13 |     margin: 0 auto;
14 |     left: 0;
15 |     right: 0;
16 |     .block {
17 |       margin-bottom: 40px;
18 |       .block-content {
19 |         display: flex;
20 |         border-radius: 4px;
21 |         text-align: center;
22 |         position: relative;
23 |         overflow: hidden;
24 |         border: none;
25 |         height: 64px;
26 |         align-items: center;
27 |         transition: box-shadow .3s @ease-out, transform .3s @ease-out;
28 |         & > span {
29 |           width: 100%;
30 |           display: block;
31 |         }
32 |       }
33 |     }
34 |   }
35 | }
36 | 
37 | @media screen and (max-width: 767px) {
38 |   .@{content12}-wrapper {
39 |     overflow: hidden;
40 |     .@{content12} {
41 |       ul {
42 |         li {
43 |           display: block;
44 |           width: 100%;
45 |           padding: 2%;
46 |           span {
47 |             height: 168px;
48 |           }
49 |         }
50 |       }
51 |     }
52 |   }
53 | }
54 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Content13/index.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import OverPack from 'rc-scroll-anim/lib/ScrollOverPack';
 3 | import QueueAnim from 'rc-queue-anim';
 4 | /* replace-start-value = import { getChildrenToRender } from './utils'; */
 5 | import { getChildrenToRender } from '../../utils';
 6 | /* replace-end-value */
 7 | /* replace-start */
 8 | import './index.less';
 9 | /* replace-end */
10 | 
11 | class Content13 extends React.PureComponent {
12 |   render() {
13 |     const { ...props } = this.props;
14 |     const { dataSource } = props;
15 |     delete props.dataSource;
16 |     delete props.isMobile;
17 |     return (
18 |       <OverPack
19 |         {...props}
20 |         {...dataSource.OverPack}
21 |       >
22 |         <QueueAnim
23 |           type="bottom"
24 |           leaveReverse
25 |           key="page"
26 |           delay={[0, 100]}
27 |           {...dataSource.titleWrapper}
28 |           /* replace-start */
29 |           data-edit="titleWrapper"
30 |         /* replace-end */
31 |         >
32 |           {
33 |             dataSource.titleWrapper.children.map(getChildrenToRender)
34 |           }
35 |         </QueueAnim>
36 |       </OverPack>
37 |     );
38 |   }
39 | }
40 | 
41 | export default Content13;
42 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Content13/index.less:
--------------------------------------------------------------------------------
 1 | @import '../../../static/custom.less';
 2 | @content13: content13;
 3 | .@{content13}-wrapper {
 4 |   min-height: 380px;
 5 |   background: url("https://gw.alipayobjects.com/zos/rmsportal/ZsWYzLOItgeaWDSsXdZd.svg") no-repeat bottom;
 6 |   background-size: cover;
 7 |   background-size: 100%;
 8 |   margin: 0 auto;
 9 |   overflow: hidden;
10 |   padding: 96px 0;
11 |   &.home-page-wrapper {
12 |     .title-wrapper {
13 |       margin-bottom: 32px;
14 |     }
15 |   }
16 |   .title-content {
17 |     line-height: 32px;
18 |   }
19 | }
20 | 
21 | @media screen and (max-width: 767px) {
22 |   .@{content13}-wrapper {
23 |     padding-bottom: 0;
24 |   }
25 | }
26 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Content13/template.config.js:
--------------------------------------------------------------------------------
 1 | import component from './index';
 2 | 
 3 | import less from '!raw-loader!./index.less';
 4 | import templateStr from '!raw-loader!./index';
 5 | 
 6 | export default {
 7 |   component,
 8 |   templateStr,
 9 |   less,
10 |   dataSource: {
11 |     OverPack: {
12 |       className: 'home-page-wrapper content13-wrapper',
13 |       playScale: 0.3,
14 |     },
15 |     titleWrapper: {
16 |       className: 'title-wrapper',
17 |       children: [
18 |         {
19 |           name: 'image',
20 |           children: 'https://gw.alipayobjects.com/zos/rmsportal/PiqyziYmvbgAudYfhuBr.svg',
21 |           className: 'title-image',
22 |         },
23 |         {
24 |           name: 'title',
25 |           children: '丰富的特色展台',
26 |           className: 'title-h1',
27 |         },
28 |         {
29 |           name: 'content',
30 |           children: '特色展台包括 Ant Design 、AntV、AntG、Egg 等明星产品,更有产品专家',
31 |           className: 'title-content',
32 |         },
33 |         {
34 |           name: 'content2',
35 |           children: '现场问诊,为你答疑解难',
36 |           className: 'title-content',
37 |         },
38 |       ],
39 |     },
40 |   },
41 | };
42 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Content2/index.less:
--------------------------------------------------------------------------------
 1 | @import '../../../static/custom.less';
 2 | @content2: content2;
 3 | .@{content2}-wrapper {
 4 |   height: 360px;
 5 |   .@{content2} {
 6 |     height: 100%;
 7 |     padding: 0 24px;
 8 |     &-img {
 9 |       height: 100%;
10 |       transform-origin: top;
11 |       padding: 0 32px;
12 |       display: flex;
13 |       align-items: center;
14 |       justify-content: center;
15 |       span {
16 |         display: block;
17 |         width: 250px;
18 |         img {
19 |           display: block;
20 |         }
21 |       }
22 |     }
23 |     &-text {
24 |       padding: 0 32px;
25 |       height: 100%;
26 |       .@{content2}-content,
27 |       .@{content2}-title {
28 |         position: relative !important;
29 |       }
30 |       .@{content2}-title {
31 |         font-size: 32px;
32 |         font-weight: normal;
33 |         color: #404040;
34 |         margin-top: 120px;
35 |       }
36 |       .@{content2}-content {
37 |         margin-top: 20px;
38 |       }
39 |     }
40 |   }
41 | }
42 | 
43 | @media screen and (max-width: 767px) {
44 |   .@{content2}-wrapper {
45 |     height: 600px;
46 |     .@{content2} {
47 |       &-img {
48 |         height: 200px;
49 |         padding: 0;
50 |         text-align: center;
51 |         margin-top: 64px;
52 |         span {
53 |           display: inline-block;
54 |           width: 180px;
55 |           height: 200px;
56 |           line-height: 200px;
57 |           margin: auto;
58 |         }
59 |       }
60 |       &-text {
61 |         height: auto;
62 |         margin-bottom: 20px;
63 |         text-align: center;
64 |         padding: 0;
65 |         .@{content2}-content,
66 |         .@{content2}-title {
67 |           width: 100%;
68 |           top: auto;
69 |         }
70 |         .@{content2}-title {
71 |           margin: 32px auto 16px;
72 |           font-size: 24px;
73 |         }
74 |       }
75 |     }
76 |   }
77 | }
78 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Content2/template.config.js:
--------------------------------------------------------------------------------
 1 | import component from './index';
 2 | 
 3 | import less from '!raw-loader!./index.less';
 4 | import templateStr from '!raw-loader!./index';
 5 | 
 6 | export default {
 7 |   component,
 8 |   less,
 9 |   templateStr,
10 |   dataSource: {
11 |     wrapper: {
12 |       className: 'home-page-wrapper content2-wrapper',
13 |     },
14 |     OverPack: {
15 |       className: 'home-page content2',
16 |       playScale: 0.3,
17 |     },
18 |     imgWrapper: {
19 |       className: 'content2-img',
20 |       md: 10,
21 |       xs: 24,
22 |     },
23 |     img: {
24 |       children: 'https://zos.alipayobjects.com/rmsportal/tvQTfCupGUFKSfQ.png',
25 |     },
26 |     textWrapper: {
27 |       className: 'content2-text',
28 |       md: 14,
29 |       xs: 24,
30 |     },
31 |     title: {
32 |       className: 'content2-title',
33 |       children: '分布式中间件',
34 |     },
35 |     content: {
36 |       className: 'content2-content',
37 |       children: '金融级联机交易处理中间件,大规模分布式计算机,数万笔/秒级并发能力,严格保证交易数据统一性。'
38 |       + '金融级联机交易处理中间件,大规模分布式计算机,数万笔/秒级并发能力,严格保证交易数据统一性。',
39 |     },
40 |   },
41 | };
42 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Content3/index.less:
--------------------------------------------------------------------------------
 1 | @import '../../../static/custom.less';
 2 | @content3: content3;
 3 | .@{content3}-wrapper {
 4 |   min-height: 764px;
 5 |   .@{content3} {
 6 |     height: 100%;
 7 |     overflow: hidden;
 8 |     & .title-content {
 9 |       text-align: center;
10 |     }
11 |     &-block-wrapper {
12 |       position: relative;
13 |       .@{content3}-block {
14 |         display: inline-block;
15 |         padding: 48px 24px;
16 |         vertical-align: top;
17 |         .@{content3}-icon {
18 |           display: inline-block;
19 |           width: 15%;
20 |           vertical-align: top;
21 |         }
22 |         .@{content3}-text {
23 |           width: 85%;
24 |           display: inline-block;
25 |           padding-left: 8%;
26 |         }
27 |         &.clear-both {
28 |           clear: both;
29 |         }
30 |       }
31 |     }
32 |   }
33 | }
34 | 
35 | @media screen and (max-width: 767px) {
36 |   .@{content3}-wrapper {
37 |     min-height: 1080px;
38 |     .@{content3} {
39 |       &-block-wrapper {
40 |         margin: 20px auto;
41 |         height: auto;
42 |         .@{content3}-block {
43 |           .@{content3}-title {
44 |             font-size: 20px;
45 |           }
46 |           &.queue-anim-leaving {
47 |             position: relative !important;
48 |           }
49 |         }
50 |       }
51 |     }
52 |   }
53 | }
54 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Content4/index.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import TweenOne from 'rc-tween-one';
 3 | import OverPack from 'rc-scroll-anim/lib/ScrollOverPack';
 4 | import VideoPlay from 'react-sublime-video';
 5 | /* replace-start-value = import { getChildrenToRender } from './utils'; */
 6 | import { getChildrenToRender } from '../../utils';
 7 | /* replace-end-value */
 8 | /* replace-start */
 9 | import './index.less';
10 | /* replace-end */
11 | 
12 | function Content4(props) {
13 |   const { ...tagProps } = props;
14 |   const { dataSource, isMobile } = tagProps;
15 |   delete tagProps.dataSource;
16 |   delete tagProps.isMobile;
17 |   const animation = {
18 |     y: '+=30', opacity: 0, type: 'from', ease: 'easeOutQuad',
19 |   };
20 |   const videoChildren = dataSource.video.children.video;
21 |   const videoNameArray = videoChildren.split('.');
22 |   const type = videoNameArray[videoNameArray.length - 1];
23 |   return (
24 |     <div
25 |       {...tagProps}
26 |       {...dataSource.wrapper}
27 |     >
28 |       <div
29 |         {...dataSource.page}
30 |       >
31 |         <div
32 |           key="title"
33 |           {...dataSource.titleWrapper}
34 |           /* replace-start */
35 |           data-edit="titleWrapper"
36 |           /* replace-end */
37 |         >
38 |           {
39 |             dataSource.titleWrapper.children.map(getChildrenToRender)
40 |           }
41 |         </div>
42 |         <OverPack {...dataSource.OverPack}>
43 |           <TweenOne
44 |             key="video"
45 |             animation={{ ...animation, delay: 300 }}
46 |             {...dataSource.video}
47 |             /* replace-start */
48 |             data-edit="video"
49 |           /* replace-end */
50 |           >
51 |             {isMobile
52 |               ? (
53 |                 <video width="100%" loop controls poster={dataSource.video.children.image}>
54 |                   <source src={videoChildren} type={`video/${type}`} />
55 |                   <track kind="captions" />
56 |                 </video>
57 |               )
58 |               : (
59 |                 <VideoPlay loop width="100%" poster={dataSource.video.children.image}>
60 |                   <source src={videoChildren} type={`video/${type}`} />
61 |                 </VideoPlay>
62 |               )}
63 |           </TweenOne>
64 |         </OverPack>
65 |       </div>
66 |     </div>
67 |   );
68 | }
69 | 
70 | export default Content4;
71 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Content4/index.less:
--------------------------------------------------------------------------------
 1 | @import '../../../static/custom.less';
 2 | @content4: content4;
 3 | .@{content4}-wrapper {
 4 |   min-height: 720px;
 5 |   background: #fafafa;
 6 |   .@{content4} {
 7 |     height: 100%;
 8 |     overflow: hidden;
 9 |     &-video {
10 |       border-radius: 4px;
11 |       overflow: hidden;
12 |       max-width: 800px;
13 |       margin: auto;
14 |       background: #fff;
15 |       box-shadow: 0 4px 8px rgba(0, 0, 0, .15);
16 |       video {
17 |         display: block;
18 |         margin: auto;
19 |       }
20 |     }
21 |   }
22 | }
23 | 
24 | @media screen and (max-width: 767px) {
25 |   .@{content4}-wrapper {
26 |     min-height: 350px;
27 |     .@{content4} {
28 |       overflow: hidden;
29 |       width: 90%;
30 |       margin: auto;
31 |       &-video {
32 |         top: 15%;
33 |         background: url("https://zos.alipayobjects.com/rmsportal/HZgzhugQZkqUwBVeNyfz.jpg") no-repeat center;
34 |         background-size: cover;
35 |       }
36 |     }
37 |   }
38 | }
39 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Content4/template.config.js:
--------------------------------------------------------------------------------
 1 | import component from './index';
 2 | 
 3 | import less from '!raw-loader!./index.less';
 4 | import templateStr from '!raw-loader!./index';
 5 | 
 6 | export default {
 7 |   component,
 8 |   templateStr,
 9 |   less,
10 |   dataSource: {
11 |     wrapper: {
12 |       className: 'home-page-wrapper content4-wrapper',
13 |     },
14 |     page: {
15 |       className: 'home-page content4',
16 |     },
17 |     OverPack: {
18 |       playScale: 0.3,
19 |       className: '',
20 |     },
21 |     titleWrapper: {
22 |       className: 'title-wrapper',
23 |       children: [
24 |         {
25 |           name: 'title',
26 |           children: '蚂蚁金融云提供专业的服务',
27 |           className: 'title-h1',
28 |         },
29 |         {
30 |           name: 'content',
31 |           className: 'title-content content4-title-content',
32 |           children: '科技想象力,金融创造力',
33 |         },
34 |       ],
35 |     },
36 |     video: {
37 |       className: 'content4-video',
38 | 
39 |       children: {
40 |         video: 'https://os.alipayobjects.com/rmsportal/EejaUGsyExkXyXr.mp4',
41 |         image: 'https://zos.alipayobjects.com/rmsportal/HZgzhugQZkqUwBVeNyfz.jpg',
42 |       },
43 |     },
44 |   },
45 | };
46 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Content5/index.less:
--------------------------------------------------------------------------------
 1 | @import '../../../static/custom.less';
 2 | @content5: content5;
 3 | .@{content5}-wrapper {
 4 |   background-color: #fafafa;
 5 |   min-height: 720px;
 6 |   .@{content5} {
 7 |     >p {
 8 |       text-align: center;
 9 |     }
10 |     &-img-wrapper {
11 |       margin: 0 auto;
12 |       left: 0;
13 |       right: 0;
14 |       .block {
15 |         margin-bottom: 24px;
16 |         .content5-block-content {
17 |           display: block;
18 |           background: #fff;
19 |           border-radius: 4px;
20 |           padding: 10px;
21 |           text-align: center;
22 |           position: relative;
23 |           overflow: hidden;
24 |           .page-pro();
25 |           border: none;
26 |           color: @text-color;
27 |           transition: box-shadow .3s @ease-out, transform .3s @ease-out;
28 |           & > span {
29 |             width: 100%;
30 |             height: 160px;
31 |             display: block;
32 |             background: @line-color;
33 |             padding: 5%;
34 |           }
35 |           & p {
36 |             width: 100%;
37 |             line-height: 30px;
38 |           }
39 |           &:hover {
40 |             & p {
41 |               bottom: 0;
42 |             }
43 |           }
44 |         }
45 |       }
46 |     }
47 |   }
48 | }
49 | 
50 | @media screen and (max-width: 767px) {
51 |   .@{content5}-wrapper {
52 |     height: 2000px;
53 |     overflow: hidden;
54 |     .@{content5} {
55 |       ul {
56 |         li {
57 |           display: block;
58 |           width: 100%;
59 |           padding: 2%;
60 |           span {
61 |             height: 168px;
62 |           }
63 |           p {
64 |             position: relative;
65 |             bottom: 0;
66 |           }
67 |         }
68 |       }
69 |     }
70 |   }
71 | }
72 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Content6/index.less:
--------------------------------------------------------------------------------
 1 | @import '../../../static/custom.less';
 2 | @content6: content6;
 3 | .@{content6}-wrapper {
 4 |   min-height: 720px;
 5 |   .@{content6} {
 6 |     height: 100%;
 7 |     display: flex;
 8 |     align-items: center;
 9 | 
10 |     &-text {
11 |       min-height: 424px;
12 |       >*.queue-anim-leaving {
13 |         position: relative !important;
14 |       }
15 |       .title-h1 {
16 |         position: relative;
17 |         margin: 0 0 16px;
18 |         text-align: left;
19 |         font-size: 2em;
20 |       }
21 |       .title-content {
22 |         position: relative;
23 |         margin-bottom: 64px;
24 |         text-align: left;
25 |       }
26 |       ul {
27 |         position: relative;
28 |         display: inline-block;
29 |         li {
30 |           margin-bottom: 24px;
31 |           .@{content6}-icon {
32 |             display: inline-block;
33 |             width: 30px;
34 |             height: 30px;
35 |             position: absolute;
36 |           }
37 |           .@{content6}-title,
38 |           .@{content6}-content {
39 |             margin-left: 45px;
40 |           }
41 |           .@{content6}-title {
42 |             font-size: 14px;
43 |             margin-bottom: 10px;
44 |           }
45 |         }
46 |       }
47 |     }
48 |   }
49 | }
50 | 
51 | @media screen and (max-width: 767px) {
52 |   .@{content6}-wrapper {
53 |     height: 860px;
54 |     overflow: hidden;
55 |     .@{content6} {
56 |       display: block;
57 |       &-img,
58 |       &-text {
59 |         display: block;
60 |         width: 100%;
61 |       }
62 |       &-text {
63 |         >h1,
64 |         >p {
65 |           text-align: center;
66 |         }
67 |         > h1 {
68 |           margin: 56px auto 16px;
69 |         }
70 |         p {
71 |           margin-bottom: 32px;
72 |         }
73 |       }
74 |       &-img {
75 |         margin-top: 20px;
76 |       }
77 |     }
78 |   }
79 | }
80 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Content7/index.less:
--------------------------------------------------------------------------------
 1 | @import '../../../static/custom.less';
 2 | @content7: content7;
 3 | .@{content7}-wrapper {
 4 |   min-height: 720px;
 5 |   .@{content7} {
 6 |     >h1,
 7 |     >p {
 8 |       text-align: center;
 9 |     }
10 |     &-tag {
11 |       & i {
12 |         width: 12px;
13 |         height: 14px;
14 |         display: inline-block;
15 |         vertical-align: middle;
16 |         margin-right: 5px;
17 |       }
18 |       &-name {
19 |         display: inline-block;
20 |       }
21 |     }
22 |     .ant-tabs-bar {
23 |       text-align: center;
24 |     }
25 |     .ant-tabs {
26 |       .ant-tabs-nav {
27 |         float: none;
28 |         text-align: center;
29 |       }
30 |     }
31 |     &-tabs-wrapper {
32 |       position: relative;
33 |       margin-top: 24px;
34 |     }
35 |     &-content {
36 |       display: flex;
37 |       align-items: center;
38 |     }
39 |     &-text {
40 |       padding: 24px 48px;
41 |     }
42 |     &-img {
43 |       padding: 24px 48px;
44 |     }
45 |     .ant-tabs-tabpane {
46 |       margin-top: 40px;
47 |     }
48 |   }
49 | }
50 | 
51 | @media screen and (max-width: 767px) {
52 |   .@{content7}-wrapper {
53 |     min-height: 980px;
54 |     overflow: hidden;
55 |     .@{content7} {
56 |       max-width: 100%;
57 |       &-content {
58 |         display: block;
59 |       }
60 |       &-text,
61 |       &-img {
62 |         text-align: left;
63 |         padding: 0;
64 |       }
65 |       &-img {
66 |         margin-top: 32px;
67 |       }
68 |       .ant-tabs-bar {
69 |         width: auto;
70 |         .ant-tabs-nav {
71 |           float: left;
72 |         }
73 |       }
74 |     }
75 |   }
76 | }
77 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Content8/index.less:
--------------------------------------------------------------------------------
 1 | @import '../../../static/custom.less';
 2 | @content8: content8;
 3 | .@{content8}-wrapper {
 4 |   &.home-page-wrapper {
 5 |     overflow: initial;
 6 |     width: ~"calc(100% - 112px)";
 7 |     min-height: 878px;
 8 |     margin: auto;
 9 |     border-radius: 4px;
10 |     box-shadow: 0 32px 32px rgba(34, 94, 222, 0.08);
11 |     background: #fff;
12 |     & .home-page {
13 |       margin-top: -220px;
14 |       padding: 64px 24px;
15 |       overflow: hidden;
16 |     }
17 |   }
18 |   .content-wrapper {
19 |     margin-top: 72px;
20 |     .@{content8}-block-wrapper {
21 |       margin-bottom: 60px;
22 |     }
23 |     .@{content8}-block {
24 |       width: 100%;
25 |       max-width: 192px;
26 |       margin: auto;
27 |     }
28 |     .@{content8}-img {
29 |       border-radius: 8px;
30 |       overflow: hidden;
31 |       width: 100%;
32 |       img {
33 |         width: 100%;
34 |         display: block;
35 |         &[src=""] {
36 |           background: linear-gradient(to top right, #d6defc, #fff);
37 |           padding-bottom: 100%;
38 |         }
39 |       }
40 |     }
41 |     .@{content8}-title {
42 |       font-size: 20px;
43 |       color: #0d1a26;
44 |       font-weight: 400;
45 |       margin: 24px auto 8px;
46 |       text-align: center;
47 |       white-space: nowrap;
48 |     }
49 |     .@{content8}-content {
50 |       text-align: center;
51 |       white-space: nowrap;
52 |       font-size: 14px;
53 |       color: #697b8c;
54 |     }
55 |   }
56 | }
57 | 
58 | @media screen and (max-width: 767px) {
59 |   .@{content8}-wrapper.home-page-wrapper {
60 |     padding-bottom: 0;
61 |     box-shadow: none;
62 |     width: 100%;
63 |     .@{content8} {
64 |       &.home-page {
65 |         margin: auto;
66 |         padding-bottom: 0;
67 |       }
68 |     }
69 |     .content-wrapper {
70 |       .@{content8}-block {
71 |         max-width: 240px;
72 |       }
73 |     }
74 |   }
75 | }
76 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Feature7/index.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import OverPack from 'rc-scroll-anim/lib/ScrollOverPack';
 3 | import QueueAnim from 'rc-queue-anim';
 4 | import { Row, Col } from 'antd';
 5 | 
 6 | /* replace-start-value = import { getChildrenToRender } from './utils'; */
 7 | import { getChildrenToRender } from '../../utils';
 8 | /* replace-end-value */
 9 | /* replace-start */
10 | import './index.less';
11 | /* replace-end */
12 | 
13 | function Feature7(props) {
14 |   const { dataSource, isMobile, ...tagProps } = props;
15 |   const { blockWrapper, titleWrapper } = dataSource;
16 |   const childrenToRender = blockWrapper.children.map((item, i) => (
17 |     <Col
18 |       {...item}
19 |       key={i.toString()}
20 |       /* replace-start */
21 |       data-edit="Col"
22 |     /* replace-end */
23 |     >
24 |       <a
25 |         {...item.children}
26 |         /* replace-start */
27 |         data-edit="linkA"
28 |       /* replace-end */
29 |       >
30 |         {item.children.children.map(getChildrenToRender)}
31 |       </a>
32 |     </Col>
33 |   ));
34 |   return (
35 |     <div
36 |       {...tagProps}
37 |       {...dataSource.wrapper}
38 |     >
39 |       <div {...dataSource.page}>
40 |         <div
41 |           {...dataSource.titleWrapper}
42 |           /* replace-start */
43 |           data-edit="titleWrapper"
44 |         /* replace-end */
45 |         >
46 |           {titleWrapper.children.map(getChildrenToRender)}
47 |         </div>
48 |         <OverPack {...dataSource.OverPack}>
49 |           <QueueAnim
50 |             key="queue"
51 |             type="bottom"
52 |             leaveReverse
53 |             interval={50}
54 |             component={Row}
55 |             {...blockWrapper}
56 |             /* replace-start */
57 |             data-edit="Row"
58 |           /* replace-end */
59 |           >
60 |             {childrenToRender}
61 |           </QueueAnim>
62 |         </OverPack>
63 |       </div>
64 |     </div>
65 |   );
66 | }
67 | 
68 | export default Feature7;
69 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Feature7/index.less:
--------------------------------------------------------------------------------
 1 | @import '../../../static/custom.less';
 2 | @feature7: feature7;
 3 | 
 4 | .@{feature7} {
 5 |   &-wrapper {
 6 |     min-height: 564px;
 7 |     margin: 0 auto;
 8 |     overflow: hidden;
 9 |     background-color: #f7f9fc;
10 | 
11 |     &.home-page-wrapper {
12 |       .home-page {
13 |         padding: 64px 24px;
14 |       }
15 |     }
16 |   }
17 | 
18 |   &-title {
19 | 
20 |     &-wrapper {
21 |       text-align: center;
22 |       margin-bottom: 40px;
23 |     }
24 | 
25 |     &-h1 {
26 |       font-size: 32px;
27 |       color: @text-color;
28 |     }
29 | 
30 |     &-content {
31 |       margin-top: 16px;
32 |     }
33 |   }
34 | 
35 |   &-block {
36 |     margin-top: 28px;
37 | 
38 |     &-group {
39 |       display: block;
40 |       padding: 28px 24px;
41 |       box-shadow: 0 2px 16px fade(#000, 8);
42 |       background-image: url('https://gw.alipayobjects.com/mdn/rms_ae7ad9/afts/img/A*fMOFSpRXMxsAAAAAAAAAAABkARQnAQ');
43 |       background-repeat: no-repeat;
44 |       background-position: 100% 100%;
45 |       transition: box-shadow @animate-duration @ease-in-out, transform @animate-duration @ease-in-out;
46 | 
47 |       &:hover {
48 |         transform: translateY(-5px);
49 |         box-shadow: 0 6px 16px fade(#000, 12);
50 |       }
51 |     }
52 | 
53 |     &-image {
54 |       float: left;
55 |       width: 24px;
56 |     }
57 | 
58 |     &-title {
59 |       font-size: 14px;
60 |       float: left;
61 |       margin-left: 8px;
62 |       margin-bottom: 16px;
63 |       color: @text-color;
64 |     }
65 | 
66 |     &-content {
67 |       clear: both;
68 |       color: fade(@text-color, 75);
69 |     }
70 |   }
71 | }
72 | 
73 | @media screen and (max-width: 767px) {
74 |   .@{feature7}-wrapper {
75 |     min-height: 1540px;
76 |     &.home-page-wrapper {
77 |       .home-page {
78 |         padding: 56px 24px;
79 |       }
80 |     }
81 |   }
82 | }
83 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Footer0/index.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import TweenOne from 'rc-tween-one';
 3 | import OverPack from 'rc-scroll-anim/lib/ScrollOverPack';
 4 | /* replace-start */
 5 | import './index.less';
 6 | /* replace-end */
 7 | 
 8 | class Footer extends React.PureComponent {
 9 |   render() {
10 |     const { ...props } = this.props;
11 |     const { dataSource } = props;
12 |     delete props.dataSource;
13 |     delete props.isMobile;
14 |     return (
15 |       <div {...props} {...dataSource.wrapper}>
16 |         <OverPack
17 |           {...dataSource.OverPack}
18 |         >
19 |           <TweenOne
20 |             animation={{ y: '+=30', opacity: 0, type: 'from' }}
21 |             key="footer"
22 |             {...dataSource.copyright}
23 |           >
24 |             {
25 |               /* replace-start-value = dataSource.copyright.children */
26 |               React.createElement('span', { dangerouslySetInnerHTML: { __html: dataSource.copyright.children } })
27 |               /* replace-end-value */
28 |             }
29 |           </TweenOne>
30 |         </OverPack>
31 |       </div>
32 |     );
33 |   }
34 | }
35 | 
36 | export default Footer;
37 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Footer0/index.less:
--------------------------------------------------------------------------------
 1 | @import '../../../static/custom.less';
 2 | .footer0-wrapper {
 3 |   background-color: @template-bg-color;
 4 |   height: 80px;
 5 |   overflow: hidden;
 6 |   .footer0 {
 7 |     height: 100%;
 8 |     padding: 0 24px;
 9 |     line-height: 80px;
10 |     text-align: center;
11 |     color: @template-footer-text-color;
12 |     position: relative;
13 |   }
14 | }
15 | 
16 | @media screen and (max-width: 767px) {
17 |   .footer0-wrapper {
18 |     .footer0 {
19 |       font-size: 12px;
20 |       &.home-page {
21 |         padding: 0;
22 |       }
23 |       >div {
24 |         width: 90%;
25 |         margin: auto;
26 |       }
27 |     }
28 |   }
29 | }
30 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Footer0/template.config.js:
--------------------------------------------------------------------------------
 1 | import component from './index';
 2 | 
 3 | import less from '!raw-loader!./index.less';
 4 | import templateStr from '!raw-loader!./index';
 5 | 
 6 | export default {
 7 |   component,
 8 |   templateStr,
 9 |   less,
10 |   dataSource: {
11 |     wrapper: {
12 |       className: 'home-page-wrapper footer0-wrapper',
13 |     },
14 |     OverPack: {
15 |       className: 'home-page footer0',
16 |       playScale: 0.05,
17 |     },
18 |     copyright: {
19 |       className: 'copyright',
20 |       children: '<span>©2018 <a href="https://motion.ant.design">Ant Motion</a> All Rights Reserved</span>',
21 |     },
22 |   },
23 | };
24 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Footer1/index.less:
--------------------------------------------------------------------------------
  1 | @import '../../../static/custom.less';
  2 | .footer1-wrapper {
  3 |   background: @template-bg-color;
  4 |   overflow: hidden;
  5 |   position: relative;
  6 |   min-height: 360px;
  7 |   color: @template-footer-text-color;
  8 |   .footer1 {
  9 |     .home-page {
 10 |       padding: 64px 24px 80px;
 11 |     }
 12 |   }
 13 |   .block {
 14 |     padding: 0 32px;
 15 |     .logo {
 16 |       max-width: 180px;
 17 |     }
 18 |     .slogan {
 19 |       font-size: 12px;
 20 |       margin-top: -20px;
 21 |     }
 22 |     >h2 {
 23 |       margin-bottom: 24px;
 24 |       color: @template-text-color;
 25 |     }
 26 |     a {
 27 |       color: @template-footer-text-color;
 28 |       margin-bottom: 12px;
 29 |       float: left;
 30 |       clear: both;
 31 |       &:hover {
 32 |         color: @primary-color;
 33 |       }
 34 |     }
 35 |   }
 36 |   .copyright-wrapper {
 37 |     width: 100%;
 38 |     border-top: 1px solid fade(@line-color, 10);
 39 |     .home-page {
 40 |       padding: 0 24px;
 41 |       overflow: hidden;
 42 |     }
 43 |     .copyright {
 44 |       height: 80px;
 45 |       text-align: center;
 46 |       line-height: 80px;
 47 |     }
 48 |   }
 49 | }
 50 | 
 51 | @media screen and (max-width: 767px) {
 52 |   .footer1 {
 53 |     min-height: 550px;
 54 |     &-wrapper {
 55 |       .footer1 {
 56 |         .home-page {
 57 |           padding: 64px 24px 32px;
 58 |         }
 59 |       }
 60 |     }
 61 |     .logo {
 62 |       margin: 0 auto 24px;
 63 |     }
 64 |     .block {
 65 |       text-align: center;
 66 |       margin-bottom: 32px;
 67 |       padding: 0;
 68 |     }
 69 |     >ul {
 70 |       width: 90%;
 71 |       margin: 20px auto 0;
 72 |       padding: 10px 0;
 73 |       >li {
 74 |         width: 100%;
 75 |         h2 {
 76 |           margin-bottom: 10px;
 77 |         }
 78 |         li {
 79 |           display: inline-block;
 80 |           margin-right: 10px;
 81 |         }
 82 |       }
 83 |     }
 84 |     .copyright {
 85 |       &-wrapper {
 86 |         .home-page {
 87 |           padding: 0;
 88 |           .copyright {
 89 |             font-size: 12px;
 90 |           }
 91 |         }
 92 |       }
 93 | 
 94 |       span {
 95 |         width: 90%;
 96 |       }
 97 |     }
 98 |   }
 99 | }
100 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Footer2/index.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import TweenOne from 'rc-tween-one';
 3 | import OverPack from 'rc-scroll-anim/lib/ScrollOverPack';
 4 | /* replace-start-value = import { isImg } from './utils'; */
 5 | import { isImg } from '../../../../utils';
 6 | /* replace-end-value */
 7 | /* replace-start */
 8 | import './index.less';
 9 | /* replace-end */
10 | 
11 | class Footer2 extends React.PureComponent {
12 |   render() {
13 |     const { ...props } = this.props;
14 |     const { dataSource } = props;
15 |     delete props.dataSource;
16 |     delete props.isMobile;
17 |     return (
18 |       <div {...props} {...dataSource.wrapper}>
19 |         <OverPack
20 |           {...dataSource.OverPack}
21 |         >
22 |           <TweenOne {...dataSource.links}>
23 |             {dataSource.links.children.map((item, i) => {
24 |               return (
25 |                 <a
26 |                   key={i.toString()}
27 |                   {...item}
28 |                   /* replace-start */
29 |                   data-edit="link,image"
30 |                 /* replace-end */
31 |                 >
32 |                   <img src={item.children} height="100%" alt="img" />
33 |                 </a>
34 |               );
35 |             })}
36 |           </TweenOne>
37 |           <TweenOne
38 |             animation={{ x: '+=30', opacity: 0, type: 'from' }}
39 |             key="copyright"
40 |             {...dataSource.copyright}
41 |             /* replace-start */
42 |             data-edit="textAndImage"
43 |           /* replace-end */
44 |           >
45 |             {
46 |               dataSource.copyright.children.map((item, i) => (
47 |                 React.createElement(item.name.indexOf('title') === 0 ? 'h1' : 'div', { key: i.toString(), ...item }, (
48 |                   typeof item.children === 'string' && item.children.match(isImg)
49 |                     ? React.createElement('img', { src: item.children, alt: 'img' })
50 |                     : /* replace-start-value = item.children */React.createElement('span', { dangerouslySetInnerHTML: { __html: item.children } })
51 |                   /* replace-end-value */
52 |                 ))
53 |               ))
54 |             }
55 |           </TweenOne>
56 |         </OverPack>
57 |       </div>
58 |     );
59 |   }
60 | }
61 | 
62 | export default Footer2;
63 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Footer2/index.less:
--------------------------------------------------------------------------------
 1 | @import '../../../static/custom.less';
 2 | .footer2-wrapper {
 3 |   background-color: #0d1a26;
 4 |   height: 80px;
 5 |   overflow: hidden;
 6 |   .footer2 {
 7 |     height: 100%;
 8 |     padding: 0 24px;
 9 |     line-height: 80px;
10 |     text-align: center;
11 |     color: @template-footer-text-color;
12 |     position: relative;
13 |   }
14 |   .copyright {
15 |     float: right;
16 |     >* {
17 |       display: inline-block;
18 |     }
19 |     &-logo {
20 |       width: 16px;
21 |       margin-right: 8px;
22 |       img {
23 |         width: 100%;
24 |       }
25 |     }
26 |     &-line {
27 |       padding: 0 12px;
28 |       margin: 0 12px;
29 |     }
30 |   }
31 |   .links {
32 |     float: left;
33 |     display: flex;
34 |     align-items: center;
35 |     height: 100%;
36 |     a {
37 |       height: 21px;
38 |       display: inline-block;
39 |       margin-right: 32px;
40 |       img {
41 |         display: block;
42 |       }
43 |     }
44 |   }
45 | }
46 | 
47 | @media screen and (max-width: 767px) {
48 |   .footer2-wrapper {
49 |     .footer2 {
50 |       font-size: 12px;
51 |       &.home-page {
52 |         padding: 0;
53 |       }
54 |       >div {
55 |         width: 90%;
56 |         margin: auto;
57 |       }
58 |     }
59 |   }
60 | }
61 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Nav1/template.config.js:
--------------------------------------------------------------------------------
 1 | import component from './index';
 2 | 
 3 | import less from '!raw-loader!./index.less';
 4 | import templateStr from '!raw-loader!./index';
 5 | 
 6 | export default {
 7 |   component,
 8 |   templateStr,
 9 |   less,
10 |   dataSource: {
11 |     wrapper: {
12 |       className: 'header1 home-page-wrapper',
13 |     },
14 |     page: {
15 |       className: 'home-page',
16 |     },
17 |     logo: {
18 |       className: 'header1-logo',
19 |       children: 'https://os.alipayobjects.com/rmsportal/mlcYmsRilwraoAe.svg',
20 |     },
21 |     Menu: {
22 |       className: 'header1-menu',
23 |       children: [
24 |         {
25 |           name: 'item0',
26 |           a: {
27 |             children: '导航一',
28 |             href: '',
29 |           },
30 |         },
31 |         {
32 |           name: 'item1',
33 |           a: {
34 |             children: '导航二',
35 |             href: '',
36 |           },
37 |         },
38 |         {
39 |           name: 'item2',
40 |           a: {
41 |             children: '导航三',
42 |             href: '',
43 |           },
44 |         },
45 |         {
46 |           name: 'item3',
47 |           a: {
48 |             children: '导航四',
49 |             href: '',
50 |           },
51 |         },
52 |       ],
53 |     },
54 |     mobileMenu: {
55 |       className: 'header1-mobile-menu',
56 |     },
57 |     help: {
58 |       className: 'help',
59 |       children: '帮助',
60 |     },
61 |     user: {
62 |     },
63 |   },
64 | };
65 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Nav2/template.config.js:
--------------------------------------------------------------------------------
 1 | import component from './index';
 2 | 
 3 | import less from '!raw-loader!./index.less';
 4 | import templateStr from '!raw-loader!./index';
 5 | 
 6 | export default {
 7 |   component,
 8 |   templateStr,
 9 |   less,
10 |   dataSource: {
11 |     isScrollLink: true,
12 |     wrapper: {
13 |       className: 'header2 home-page-wrapper',
14 |     },
15 |     page: {
16 |       className: 'home-page',
17 |     },
18 |     logo: {
19 |       className: 'header2-logo',
20 |       children: 'https://os.alipayobjects.com/rmsportal/mlcYmsRilwraoAe.svg',
21 |     },
22 |     LinkMenu: {
23 |       className: 'header2-menu',
24 |       children: [
25 |         {
26 |           name: 'linkNav',
27 |           to: '当前页面 ID 地址,参考如上',
28 |           children: '导航名称',
29 |           className: 'menu-item',
30 |         },
31 |       ],
32 |     },
33 |     mobileMenu: {
34 |       className: 'header2-mobile-menu',
35 |     },
36 |   },
37 | };
38 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Pricing0/index.less:
--------------------------------------------------------------------------------
 1 | @import '../../../static/custom.less';
 2 | @pricing0: pricing0;
 3 | .@{pricing0}-wrapper {
 4 |   .@{pricing0} {
 5 |     min-height: 370px;
 6 |     padding: 0 24px;
 7 |     display: flex;
 8 |     align-items: flex-end;
 9 |     &-img-wrapper {
10 |       height: 100%;
11 |       transform-origin: top;
12 |       padding: 0 32px;
13 |       .@{pricing0}-img {
14 |         display: block;
15 |         width: 100%;
16 |         max-width: 560px;
17 |         img {
18 |           display: block;
19 |         }
20 |       }
21 |     }
22 |     &-text-wrapper {
23 |       min-height: 320px;
24 |       padding: 0 40px;
25 |       max-width: 560px;
26 |       margin-bottom: 32px;
27 |       .@{pricing0}-content,
28 |       .@{pricing0}-title {
29 |         position: relative !important;
30 |       }
31 |       .@{pricing0}-title {
32 |         font-size: 24px;
33 |         font-weight: normal;
34 |         color: #404040;
35 |         margin: 72px auto 16px;
36 |       }
37 |       .@{pricing0}-content {
38 |         font-size: 12px;
39 |         color: #666;
40 |         line-height: 1.5;
41 |       }
42 |       .@{pricing0}-pricing {
43 |         font-size: 36px;
44 |         color: #404040;
45 |         margin: 32px 0 24px;
46 |       }
47 |     }
48 |   }
49 | }
50 | 
51 | @media screen and (max-width: 767px) {
52 |   .@{pricing0}-wrapper {
53 |     min-height: 720px;
54 |     .@{pricing0} {
55 |       display: block;
56 |       &-img-wrapper {
57 |         padding: 0;
58 |         text-align: center;
59 |         margin-top: 24px;
60 |         .@{pricing0}-img {
61 |           display: inline-block;
62 |           width: 80%;
63 |           margin: auto;
64 |         }
65 |       }
66 |       &-text-wrapper {
67 |         height: auto;
68 |         text-align: center;
69 |         padding: 0;
70 |         max-width: 100%;
71 |         .@{pricing0}-content,
72 |         .@{pricing0}-title {
73 |           width: 100%;
74 |           top: auto;
75 |         }
76 |         .@{pricing0}-title {
77 |           margin: 32px auto 16px;
78 |           font-size: 24px;
79 |         }
80 |       }
81 |     }
82 |   }
83 | }
84 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Pricing0/template.config.js:
--------------------------------------------------------------------------------
 1 | import component from './index';
 2 | 
 3 | import less from '!raw-loader!./index.less';
 4 | import templateStr from '!raw-loader!./index';
 5 | 
 6 | export default {
 7 |   component,
 8 |   templateStr,
 9 |   less,
10 |   dataSource: {
11 |     wrapper: {
12 |       className: 'home-page-wrapper pricing0-wrapper',
13 | 
14 |     },
15 |     OverPack: {
16 |       playScale: 0.3,
17 |       className: 'home-page pricing0',
18 |     },
19 |     imgWrapper: {
20 |       className: 'pricing0-img-wrapper',
21 |       md: 12,
22 |       xs: 24,
23 |     },
24 |     img: {
25 |       className: 'pricing0-img',
26 |       name: 'image',
27 |       children: 'https://gw.alipayobjects.com/mdn/rms_ae7ad9/afts/img/A*OnyWT4Nsxy0AAAAAAAAAAABjARQnAQ',
28 |     },
29 |     childWrapper: {
30 |       className: 'pricing0-text-wrapper',
31 |       md: 12,
32 |       xs: 24,
33 |       children: [
34 |         {
35 |           name: 'title',
36 |           children: 'OceanBase 服务器',
37 |           className: 'pricing0-title',
38 |         },
39 |         {
40 |           name: 'content',
41 |           children: `云资源集中编排、弹性伸缩、持续发布和部署,高可用及容灾。按金融企业安全要求打造的完整云上安全体系,全方位保障金融应用及数据安全。<br/>
42 | 500-5Gbps,10 GB-50TB(含),1TB流量包,国内按峰值。
43 | `,
44 |           className: 'pricing0-content',
45 |         },
46 |         {
47 |           name: 'pricing',
48 |           children: '¥2,200',
49 |           className: 'pricing0-pricing',
50 |         },
51 |         {
52 |           name: 'button',
53 |           children: {
54 |             icon: 'shopping-cart',
55 |             href: '#',
56 |             type: 'primary',
57 |             children: '立即购买',
58 |           },
59 |         },
60 |       ],
61 |     },
62 |   },
63 | };
64 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Pricing1/index.less:
--------------------------------------------------------------------------------
 1 | @import '../../../static/custom.less';
 2 | @pricing1: pricing1;
 3 | .@{pricing1}-wrapper {
 4 |   min-height: 760px;
 5 |   .@{pricing1} {
 6 |     >p {
 7 |       text-align: center;
 8 |     }
 9 |     &-content-wrapper {
10 |       min-height: 400px;
11 |     }
12 |     &-block-box {
13 |       width: 260px;
14 |       border-radius: 4px;
15 |       background: #eef0f3;
16 |       text-align: center;
17 |       color: #666;
18 |       min-height: 400px;
19 |       margin: auto;
20 |       border: 1px solid transparent;
21 |       .page-pro();
22 |       &.active {
23 |         border-color: @primary-color;
24 |         background: #fff;
25 |         .@{pricing1} {
26 |           &-top-wrapper {
27 |             background: @primary-color;
28 |           }
29 |           &-name,
30 |           &-money,
31 |           &-button {
32 |             color: #fff;
33 |           }
34 |           &-button {
35 |             background: @primary-color;
36 |           }
37 |         }
38 |       }
39 |     }
40 |     &-block {
41 |       margin-bottom: 24px;
42 |     }
43 |     &-top-wrapper {
44 |       width: 100%;
45 |       padding: 16px 24px;
46 |     }
47 |     &-name {
48 |       font-size: 14px;
49 |     }
50 |     &-money {
51 |       font-family: 'Helvetica Neue', sans-serif;
52 |       font-size: 32px;
53 |       color: #666;
54 |     }
55 |     &-content {
56 |       font-size: 12px;
57 |       line-height: 2;
58 |       font-weight: 300;
59 |       margin: 32px 24px 48px;
60 |     }
61 |     &-line {
62 |       display: block;
63 |       height: 1px;
64 |       background: #d9d9d9;
65 |       margin: 0 24px;
66 |     }
67 |     &-button-wrapper {
68 |       margin: 18px 24px;
69 |     }
70 |     &-button {
71 |       padding: 0 24px;
72 |     }
73 |   }
74 |   &.home-page-wrapper {
75 |     .@{pricing1}-title-wrapper {
76 |       margin-bottom: 64px;
77 |       text-align: center;
78 |     }
79 |   }
80 | }
81 | 
82 | @media screen and (max-width: 767px) {
83 |   .@{pricing1}-wrapper {
84 |     padding-bottom: 0;
85 |   }
86 | }
87 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Pricing2/index.less:
--------------------------------------------------------------------------------
 1 | @import '../../../static/custom.less';
 2 | @pricing2: pricing2;
 3 | 
 4 | .@{pricing2}-wrapper {
 5 |   min-height: 760px;
 6 | 
 7 |   .@{pricing2} {
 8 |     >p {
 9 |       text-align: center;
10 |     }
11 | 
12 |     &-content-wrapper {
13 |       min-height: 400px;
14 |     }
15 | 
16 |     &-table-name-block {
17 |       text-align: center;
18 |       color: #666;
19 |       width: 100%;
20 |     }
21 | 
22 |     &-table-name {
23 |       font-size: 24px;
24 |     }
25 | 
26 |     &-table-money {
27 |       font-size: 16px;
28 |       margin: 8px 0 16px;
29 |     }
30 | 
31 |     &-table-content {
32 |       text-align: center;
33 |       color: #666;
34 | 
35 |       &-name {
36 |         color: #666;
37 |         text-align: center;
38 |       }
39 |     }
40 |   }
41 | 
42 |   &.home-page-wrapper {
43 |     .@{pricing2}-title-wrapper {
44 |       margin-bottom: 64px;
45 |       text-align: center;
46 |     }
47 |   }
48 | }
49 | 
50 | @media screen and (max-width: 767px) {
51 |   .@{pricing2} {
52 |     &-wrapper {
53 |       padding-bottom: 0;
54 |     }
55 | 
56 |     &-table {
57 |       margin-bottom: 24px;
58 |     }
59 |   }
60 | }
61 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Teams0/index.less:
--------------------------------------------------------------------------------
 1 | @import '../../../static/custom.less';
 2 | @teams0: teams0;
 3 | 
 4 | .@{teams0}-wrapper {
 5 |   height: 430px;
 6 |   .@{teams0} {
 7 |     padding: 64px 24px;
 8 |     display: flex;
 9 |     align-items: flex-end;
10 |     .banner-anim {
11 |       width: 100%;
12 |       height: 100%;
13 |     }
14 |     .banner-anim-thumb {
15 |       span {
16 |         background: #e9e9e9;
17 |         box-shadow: none;
18 |         &.active {
19 |           background: @primary-color;
20 |         }
21 |       }
22 |     }
23 |     & .queue-anim-leaving {
24 |       position: relative !important;
25 |     }
26 | 
27 |     &-banner-user-elem {
28 |       height: 100%;
29 |       color: #fff;
30 |       position: relative;
31 |       overflow: hidden;
32 |     }
33 |     &-image {
34 |       width: 120px;
35 |       height: 120px;
36 |       border-radius: 100%;
37 |       overflow: hidden;
38 |       margin: auto;
39 |       display: flex;
40 |       justify-content: center;
41 |       align-items: center;
42 |       margin-bottom: 24px;
43 |       img {
44 |         height: 100%;
45 |       }
46 |     }
47 |     &-content {
48 |       font-size: 12px;
49 |       color: #919191;
50 |       text-align: center;
51 |       width: 80%;
52 |       margin: 8px auto;
53 |     }
54 |     &-h1 {
55 |       font-size: 24px;
56 |       text-align: center;
57 |       width: 80%;
58 |       margin: 24px auto 0;
59 |     }
60 |   }
61 | }
62 | 
63 | @media screen and (max-width: 767px) {
64 |   .@{teams0}-wrapper {
65 |     min-height: 480px;
66 | 
67 |     .@{teams0} {
68 |       display: block;
69 |     }
70 |   }
71 | }
72 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Teams1/index.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import QueueAnim from 'rc-queue-anim';
 3 | import { Row, Col } from 'antd';
 4 | import OverPack from 'rc-scroll-anim/lib/ScrollOverPack';
 5 | /* replace-start-value = import { getChildrenToRender, isImg } from './utils'; */
 6 | import { getChildrenToRender } from '../../utils';
 7 | /* replace-end-value */
 8 | /* replace-start */
 9 | import './index.less';
10 | /* replace-end */
11 | 
12 | class Teams1 extends React.PureComponent {
13 |   getBlockChildren = (data) => data.map((item, i) => {
14 |     const { titleWrapper, ...$item } = item;
15 |     return (
16 |       <Col
17 |         key={i.toString()}
18 |         {...$item}
19 |         /* replace-start */
20 |         data-edit="Col, titleWrapper"
21 |       /* replace-end */
22 |       >
23 |         {titleWrapper.children.map(getChildrenToRender)}
24 |       </Col>
25 |     );
26 |   });
27 | 
28 |   render() {
29 |     const { ...props } = this.props;
30 |     const { dataSource } = props;
31 |     delete props.dataSource;
32 |     delete props.isMobile;
33 |     const listChildren = this.getBlockChildren(dataSource.block.children);
34 |     return (
35 |       <div
36 |         {...props}
37 |         {...dataSource.wrapper}
38 |       >
39 |         <div {...dataSource.page}>
40 |           <div
41 |             {...dataSource.titleWrapper}
42 |             /* replace-start */
43 |             data-edit="titleWrapper"
44 |           /* replace-end */
45 |           >
46 |             {
47 |               dataSource.titleWrapper.children.map(getChildrenToRender)
48 |             }
49 |           </div>
50 |           <OverPack {...dataSource.OverPack}>
51 |             <QueueAnim
52 |               type="bottom"
53 |               key="block"
54 |               leaveReverse
55 |               {...dataSource.block}
56 |               component={Row}
57 |               /* replace-start */
58 |               data-edit="Row"
59 |             /* replace-end */
60 |             >
61 |               {listChildren}
62 |             </QueueAnim>
63 |           </OverPack>
64 |         </div>
65 |       </div>
66 |     );
67 |   }
68 | }
69 | 
70 | export default Teams1;
71 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Teams1/index.less:
--------------------------------------------------------------------------------
 1 | @import '../../../static/custom.less';
 2 | @teams1: teams1;
 3 | .@{teams1}-wrapper {
 4 |   min-height: 446px;
 5 |   overflow: hidden;
 6 |   .@{teams1} {
 7 |     overflow: hidden;
 8 |     height: 100%;
 9 |     padding: 64px 24px;
10 |     > .title-wrapper {
11 |       margin: 0 auto 48px;
12 |     }
13 |     .block-wrapper {
14 |       position: relative;
15 |       height: 100%;
16 |       overflow: hidden;
17 |       padding: 20px 0;
18 |       .block {
19 |         display: inline-block;
20 |         text-align: center;
21 |         margin-bottom: 48px;
22 |         &.queue-anim-leaving {
23 |           position: relative !important;
24 |         }
25 |       }
26 |     }
27 |     &-image, &-title, &-job, &-content {
28 |       width: 200px;
29 |       margin: auto;
30 |       line-height: 1.5;
31 |     }
32 |     &-image {
33 |       color: #404040;
34 |       img {
35 |         width: 100%;
36 |       }
37 |     }
38 |     &-title {
39 |       font-size: 24px;
40 |       margin: 24px auto 8px;
41 |     }
42 |     &-job {
43 |       margin: 8px auto;
44 |     }
45 |     &-job, &-content {
46 |       font-size: 12px;
47 |       color: #919191;
48 |     }
49 |   }
50 | }
51 | 
52 | @media screen and (max-width: 767px) {
53 |   .@{teams1}-wrapper {
54 |     min-height: 1440px;
55 |   }
56 | }
57 | 


--------------------------------------------------------------------------------
/site/templates/template/element/Teams2/index.less:
--------------------------------------------------------------------------------
 1 | @import '../../../static/custom.less';
 2 | @teams2: teams2;
 3 | 
 4 | .@{teams2}-wrapper {
 5 |   min-height: 446px;
 6 |   overflow: hidden;
 7 | 
 8 |   .@{teams2} {
 9 |     overflow: hidden;
10 |     height: 100%;
11 |     padding: 64px 24px;
12 | 
13 |     >.title-wrapper {
14 |       margin: 0 auto 48px;
15 |     }
16 | 
17 |     .block-wrapper {
18 |       position: relative;
19 |       height: 100%;
20 |       overflow: hidden;
21 |       padding: 20px 0;
22 |       min-height: 456px;
23 | 
24 |       .block {
25 |         margin-bottom: 48px;
26 |         vertical-align: text-top;
27 | 
28 |         &.queue-anim-leaving {
29 |           position: relative !important;
30 |         }
31 |       }
32 |     }
33 | 
34 |     &-image {
35 |       color: #404040;
36 |       width: 100%;
37 | 
38 |       img {
39 |         width: 100%;
40 |       }
41 |     }
42 | 
43 |     &-textWrapper {
44 |       padding-left: 16px;
45 |     }
46 | 
47 |     &-title {
48 |       font-size: 18px;
49 |       margin-bottom: 2px;
50 |     }
51 | 
52 |     &-job {
53 |       margin-bottom: 4px;
54 |     }
55 | 
56 |     &-job,
57 |     &-content {
58 |       font-size: 12px;
59 |       color: #919191;
60 |     }
61 |   }
62 | }
63 | 
64 | @media screen and (max-width: 767px) {
65 |   .@{teams2}-wrapper {
66 |     min-height: 1440px;
67 | 
68 |     .@{teams2}.home-page {
69 |       padding-bottom: 0;
70 |     }
71 |   }
72 | }
73 | 


--------------------------------------------------------------------------------
/site/templates/template/index.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import { Provider } from 'react-redux';
 3 | 
 4 | import Layout from './layout';
 5 | import store from '../../shared/redux';
 6 | import '../static/index.less';
 7 | 
 8 | function Index() {
 9 |   return (
10 |     <Provider store={store}>
11 |       <Layout />
12 |     </Provider>
13 |   );
14 | }
15 | 
16 | export default Index;
17 | 


--------------------------------------------------------------------------------
/site/templates/template/other/Point.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import Link from 'rc-scroll-anim/lib/ScrollLink';
 3 | 
 4 | export default function Point(props) {
 5 |   const { data, size, position, type, stroke } = props;
 6 |   const children = data.map((item) => {
 7 |     if (item.match('nav') || item.match('footer')) {
 8 |       return null;
 9 |     }
10 |     const className = `point ${type} ${stroke} ${size}`.trim();
11 |     return (
12 |       <Link
13 |         key={item}
14 |         className={className}
15 |         to={item}
16 |         toHash={false}
17 |       />
18 |     );
19 |   }).filter((item) => item);
20 |   const wrapperClass = `point-wrapper ${position} ${size}`.trim();
21 |   return (
22 |     <div
23 |       className={wrapperClass}
24 |     >
25 |       <div>
26 |         {children}
27 |       </div>
28 |     </div>
29 |   );
30 | }
31 | 
32 | Point.defaultProps = {
33 |   size: '',
34 |   position: '',
35 |   type: '',
36 |   stroke: '',
37 | };
38 | 


--------------------------------------------------------------------------------
/site/templates/template/other/otherToString.jsx:
--------------------------------------------------------------------------------
 1 | import index from '!raw-loader!../../../../index.text';
 2 | import documentation from '!raw-loader!../../../../documentation.md';
 3 | import point from '!raw-loader!./Point.jsx';
 4 | 
 5 | export default {
 6 |   index,
 7 |   documentation,
 8 |   point: point.replace('../static/point.less', './less/point.less'),
 9 | };
10 | 


--------------------------------------------------------------------------------
/site/theme/index.js:
--------------------------------------------------------------------------------
 1 | const path = require('path');
 2 | 
 3 | const homeTmpl = './template/Home/index';
 4 | const contentTmpl = './template/Content/index';
 5 | 
 6 | function pickerGenerator(module) {
 7 |   const tester = new RegExp(`^docs/${module || ''}`);
 8 |   return (markdownData) => {
 9 |     const { filename } = markdownData.meta;
10 |     if (tester.test(filename) && !/\/demo$/.test(path.dirname(filename))) {
11 |       return {
12 |         meta: markdownData.meta,
13 |       };
14 |     }
15 |     return null;
16 |   };
17 | }
18 | 
19 | module.exports = {
20 |   lazyLoad(nodePath, nodeValue) {
21 |     if (typeof nodeValue === 'string') {
22 |       return true;
23 |     }
24 |     return nodePath.endsWith('/demo');
25 |   },
26 |   pick: {
27 |     docs: pickerGenerator(),
28 |     'docs/guide': pickerGenerator(),
29 |     'docs/use': pickerGenerator(),
30 |     'docs/edit': pickerGenerator(),
31 |   },
32 |   plugins: [
33 |     'bisheng-plugin-description',
34 |     'bisheng-plugin-toc?maxDepth=2&keepElem',
35 |     'bisheng-plugin-antd',
36 |     'bisheng-plugin-react?lang=__react',
37 |   ],
38 |   routes: {
39 |     path: '/',
40 |     component: './template/Layout/index',
41 |     indexRoute: { component: homeTmpl },
42 |     childRoutes: [
43 |       {
44 |         path: 'index-cn',
45 |         component: homeTmpl,
46 |       },
47 |       {
48 |         path: '/docs/:children',
49 |         component: contentTmpl,
50 |       },
51 |       {
52 |         path: '/docs/:file/:children',
53 |         component: contentTmpl,
54 |       },
55 |     ],
56 |   },
57 | };
58 | 


--------------------------------------------------------------------------------
/site/theme/static/antd.less:
--------------------------------------------------------------------------------
1 | // @import "~antd/lib/style/v2-compatible-reset.less";
2 | @import "~antd/lib/style/themes/default.less";
3 | @import "~antd/lib/style/mixins/motion.less";
4 | 


--------------------------------------------------------------------------------
/site/theme/static/common.less:
--------------------------------------------------------------------------------
  1 | html,
  2 | body {
  3 |   height: 100%;
  4 | }
  5 | 
  6 | body,
  7 | div,
  8 | dl,
  9 | dt,
 10 | dd,
 11 | ul,
 12 | ol,
 13 | li,
 14 | h1,
 15 | h2,
 16 | h3,
 17 | h4,
 18 | h5,
 19 | h6 {
 20 |   margin: 0;
 21 |   padding: 0;
 22 | }
 23 | 
 24 | body {
 25 |   font-family: @font-family;
 26 |   overflow-x: hidden;
 27 |   -webkit-font-smoothing: antialiased;
 28 | }
 29 | 
 30 | a:focus {
 31 |   text-decoration: none;
 32 | }
 33 | 
 34 | #nprogress .bar {
 35 |   background: #fff;
 36 | }
 37 | 
 38 | #nprogress .spinner-icon {
 39 |   border-top-color: #fff;
 40 |   border-left-color: #fff;
 41 | }
 42 | .header-placeholder {
 43 |   background: @primary-color;
 44 |   width: 100%;
 45 |   height: 64px;
 46 |   position: absolute;
 47 |   top: 0;
 48 |   left: 0;
 49 | }
 50 | 
 51 | .page-wrapper {
 52 |   background: #fff;
 53 |   .page {
 54 |     margin: auto;
 55 |     max-width: 100%;
 56 |     transition: padding .45s @ease-out, max-width .45s @ease-out;
 57 |     padding: 0 20px;
 58 |   }
 59 | }
 60 | .drawer-content {
 61 |   padding: 40px 0;
 62 | }
 63 | 
 64 | .landing-move-motion(@className, @keyframeName) {
 65 |   .make-motion(@className, @keyframeName, .45s);
 66 |   .@{className}-enter,
 67 |   .@{className}-appear {
 68 |     opacity: 0;
 69 |     animation-timing-function: @ease-out;
 70 |     will-change: transform;
 71 |   }
 72 |   .@{className}-leave {
 73 |     animation-timing-function: @ease-out;
 74 |     position: absolute !important;
 75 |     top: 0;
 76 |     left: 0;
 77 |     width: 100%;
 78 |     z-index: 1;
 79 |     will-change: transform;
 80 |   }
 81 | }
 82 | 
 83 | .landing-move-motion(landing-move, landingMove);
 84 | 
 85 | @keyframes landingMoveIn {
 86 |   0% {
 87 |     transform: translateY(30px);
 88 |     opacity: 0;
 89 |   }
 90 |   100% {
 91 |     transform: translateY(0%);
 92 |     opacity: 1;
 93 |   }
 94 | }
 95 | 
 96 | @keyframes landingMoveOut {
 97 |   0% {
 98 |     transform: translateY(0);
 99 |     opacity: 1;
100 |   }
101 |   100% {
102 |     transform: translateY(-30px);
103 |     opacity: 0;
104 |   }
105 | }
106 | 


--------------------------------------------------------------------------------
/site/theme/static/default.less:
--------------------------------------------------------------------------------
 1 | // 导航上划线
 2 | @menu-item-border: 2px;
 3 | 
 4 | /* 首页按钮投影色 */
 5 | @home-button-shadow-color: darken(@primary-color, 20%);
 6 | 
 7 | .mouseHover(@color, @x: 0, @y: 4px, @blur: 12px) {
 8 |   transform: translateY(0);
 9 |   box-shadow: 0 0 0 fade(@color, 0);
10 |   transition: box-shadow .3s @ease-out, transform .3s @ease-out;
11 |   &:hover {
12 |     transform: translateY(-4px);
13 |     box-shadow: @x @y @blur fade(@color, 55);
14 |   }
15 | }
16 | 
17 | @site-heading-color: #0d1a26;
18 | @site-text-color: #314659;
19 | @site-text-color-secondary: #697b8c;
20 | @site-border-color-split: #ebedf0;
21 | @site-home-line: #ebedf0;
22 | 


--------------------------------------------------------------------------------
/site/theme/static/footer.less:
--------------------------------------------------------------------------------
 1 | @padding-space: 144px;
 2 | footer {
 3 |   clear: both;
 4 |   font-size: 14px;
 5 |   background-color: #000;
 6 |   position: relative;
 7 |   z-index: 100;
 8 |   color: rgba(255, 255, 255, 0.65);
 9 |   box-shadow: 0 1000px 0 1000px #fff;
10 |   .ant-row {
11 |     text-align: center;
12 |     .footer-center {
13 |       display: inline-block;
14 |       text-align: left;
15 |       > h2 {
16 |         font-size: 16px;
17 |         margin: 0 auto 24px;
18 |         font-weight: 500;
19 |         position: relative;
20 |         > .title-icon {
21 |           width: 27px;
22 |           margin-right: 16px;
23 |         }
24 |         > .anticon {
25 |           font-size: 16px;
26 |           position: absolute;
27 |           left: -22px;
28 |           top: 3px;
29 |           color: #aaa;
30 |         }
31 |       }
32 |       > div {
33 |         margin: 12px 0;
34 |       }
35 |     }
36 |   }
37 |   .footer-wrap {
38 |     position: relative;
39 |     padding: 86px @padding-space 93px @padding-space;
40 |     border-bottom: 1px solid rgba(255, 255, 255, 0.25);
41 |   }
42 |   .bottom-bar {
43 |     text-align: center;
44 |     padding: 16px 0;
45 |     margin: 0;
46 |     line-height: 32px;
47 |     overflow: hidden;
48 |     font-family: Avenir, @font-family, sans-serif;
49 |     font-size: 16px;
50 |     a {
51 |       color: rgba(255, 255, 255, 0.65);
52 |       margin-left: 4px;
53 |       &:hover {
54 |         color: #fff;
55 |       }
56 |     }
57 |     .translate-button {
58 |       text-align: left;
59 |     }
60 |     .heart {
61 |       color: #f73f51;
62 |       font-size: 22px;
63 |     }
64 |   }
65 |   a {
66 |     color: rgba(255, 255, 255, 0.9);
67 |   }
68 |   h2 {
69 |     color: rgba(255, 255, 255, 1);
70 |     & > span {
71 |       color: rgba(255, 255, 255, 1);
72 |     }
73 |   }
74 | }
75 | 
76 | .home {
77 |   footer {
78 |     .footer-wrap {
79 |       width: 100%;
80 |       padding: 0;
81 |     }
82 |     .bottom-bar {
83 |       margin: auto;
84 |       max-width: 1200px;
85 |       padding: 16px 24px;
86 |       border-top: none;
87 |     }
88 |     .footer-wrap .ant-row {
89 |       width: 100%;
90 |       max-width: 1200px;
91 |       padding: 86px 24px 93px;
92 |       margin: auto;
93 |     }
94 |   }
95 | }
96 | 


--------------------------------------------------------------------------------
/site/theme/static/header.less:
--------------------------------------------------------------------------------
 1 | .header {
 2 |   height: 64px;
 3 |   line-height: 64px;
 4 |   background: @primary-color;
 5 |   box-shadow: 0 4px 12px rgba(138, 166, 195, .45);
 6 |   transition: box-shadow .45s @ease-out;
 7 |   position: relative;
 8 |   z-index: 999;
 9 |   .logo {
10 |     display: flex;
11 |     align-items: center;
12 |     color: #fff;
13 |     font-size: 16px;
14 |     font-family: "SF UI Display", "Helvetica Neue For Number", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif;
15 |     text-decoration: none;
16 |     img {
17 |       width: 28px;
18 |       height: 28px;
19 |       margin-right: 8px;
20 |     }
21 |   }
22 |   .menu {
23 |     display: flex;
24 |     align-items: center;
25 |     justify-content: flex-end;
26 |     .ant-menu-horizontal {
27 |       color: #fff;
28 |       background: transparent;
29 |       border-bottom: none;
30 |       transition: none;
31 |       height: 64px;
32 |       >.ant-menu-item {
33 |         line-height: 60px;
34 |         height: 62px;
35 |         border-top: @menu-item-border solid transparent;
36 |         box-sizing: content-box;
37 |         border-bottom: none;
38 |         &:hover,
39 |         &.ant-menu-item-selected {
40 |           border-top-color: #fff;
41 |         }
42 |       }
43 |       a {
44 |         color: #fff;
45 |       }
46 |     }
47 |     .gitbtn {
48 |       display: inline-block;
49 |       border: 1px solid #fff;
50 |       border-radius: 28px;
51 |       height: 28px;
52 |       line-height: 28px;
53 |       color: #fff;
54 |       padding: 0 16px;
55 |       margin-left: 20px;
56 |       box-sizing: content-box;
57 |     }
58 |   }
59 | }
60 | 


--------------------------------------------------------------------------------
/site/theme/static/home/banner.less:
--------------------------------------------------------------------------------
 1 | .banner {
 2 |   background: @primary-color;
 3 |   color: #fff;
 4 |   position: relative;
 5 |   height: 682px;
 6 |   .banner-anim-elem {
 7 |     height: 100%;
 8 |     display: flex !important;
 9 |     justify-content: center;
10 |     align-items: center;
11 |     text-align: center;
12 |     .text-wrapper {
13 |       .logo-wrapper {
14 |         width: 160px;
15 |         height: 160px;
16 |         margin: auto;
17 |         position: relative;
18 |         img {
19 |           width: 100%;
20 |           height: 100%;
21 |         }
22 |         i {
23 |           background: #fff;
24 |           position: absolute;
25 |           transform-origin: top left;
26 |         }
27 |         .vertical {
28 |           height: 264px;
29 |           width: 1px;
30 |           top: -52px;
31 |         }
32 |         .horizontal {
33 |           width: 264px;
34 |           height: 1px;
35 |           left: -52px;
36 |         }
37 |         .left {
38 |           left: 31px;
39 |         }
40 |         .right {
41 |           left: 55px;
42 |         }
43 |         .top {
44 |           top: 130px;
45 |         }
46 |         .bottom {
47 |           bottom: 4px;
48 |         }
49 |       }
50 |       .introduce {
51 |         font-size: 16px;
52 |         line-height: 32px;
53 |         font-weight: 400;
54 |         max-width: 557px;
55 |         margin: 80px auto 64px;
56 |       }
57 |       .button-wrapper {
58 |         .btn-temp {
59 |           background: #fff;
60 |           color: @primary-color;
61 |         }
62 |         .btn-editor {
63 |           border: 1px solid #fff;
64 |           color: #fff;
65 |           margin-left: 24px;
66 |           transition: box-shadow .3s @ease-out, transform .3s @ease-out, color .3s @ease-out, border .3s @ease-out, background .3s @ease-out;
67 |           &:hover {
68 |             background: #fff;
69 |             color: @primary-color;
70 |             border-color: transparent;
71 |           }
72 |         }
73 |       }
74 |       .git-button {
75 |         display: flex;
76 |         justify-content: center;
77 |         margin-top: 24px;
78 |       }
79 |     }
80 |     .bg-wrapper {
81 |       position: absolute;
82 |       top: 0;
83 |       left: 0;
84 |       width: 100%;
85 |       height: 100%;
86 |       display: flex;
87 |       align-items: center;
88 |     }
89 |   }
90 | }
91 | 


--------------------------------------------------------------------------------
/site/theme/static/home/index.less:
--------------------------------------------------------------------------------
 1 | .home .page-wrapper,
 2 | .home-wrapper .home-page-wrapper {
 3 |   width: 100%;
 4 |   position: relative;
 5 |   overflow: hidden;
 6 |   .page,
 7 |   .home-page {
 8 |     padding: 128px 24px;
 9 |     max-width: 1200px;
10 |     margin: auto;
11 |   }
12 |   h1 {
13 |     font-size: 32px;
14 |     line-height: 45px;
15 |     margin: 0 auto 64px;
16 |     text-align: center;
17 |     color: @text-color;
18 |   }
19 | }
20 | .home .header.page-wrapper .page {
21 |   padding: 0 24px;
22 | }
23 | 
24 | .home {
25 |   .header {
26 |     box-shadow: 0 0 0 rgba(138, 166, 195, 0);
27 |     position: absolute;
28 |     width: 100%;
29 |     z-index: 999;
30 |   }
31 | }
32 | .home-button {
33 |   min-width: 136px;
34 |   height: 40px;
35 |   line-height: 40px;
36 |   text-align: center;
37 |   border-radius: 20px;
38 |   display: inline-block;
39 |   font-size: 16px;
40 |   box-sizing: content-box;
41 |   .mouseHover(@home-button-shadow-color);
42 | }
43 | 
44 | @media screen and (max-width: 767px) {
45 |   .home-wrapper .home-page-wrapper {
46 |     .home-page {
47 |       padding: 56px 24px;
48 |       >h1 {
49 |         font-size: 24px;
50 |         margin: 0 auto 32px;
51 |         &.title-h1 {
52 |           margin-bottom: 8px;
53 |         }
54 |       }
55 |       >p {
56 |         margin-bottom: 32px;
57 |       }
58 |     }
59 |   }
60 | }
61 | 
62 | @import './banner.less';
63 | @import './page1.less';
64 | @import './page2.less';
65 | @import './page3.less';
66 | @import './page4.less';
67 | @import './responsive.less';
68 | 


--------------------------------------------------------------------------------
/site/theme/static/home/page3.less:
--------------------------------------------------------------------------------
 1 | .page3 {
 2 |   .page {
 3 |     h1 {
 4 |       margin: 128px auto 64px;
 5 |     }
 6 |   }
 7 |   .rc-autoresponsive {
 8 |     transition: height .3s @ease-out;
 9 |   }
10 |   & &-content {
11 |     min-height: 175px;
12 |     &-header {
13 |       margin-bottom: 64px;
14 |       width: 100%;
15 |       min-height: 32px;
16 |       text-align: center;
17 |       .ant-radio-button-wrapper {
18 |         transition: border-color .3s @ease-out, box-shadow .3s @ease-out, color .3s @ease-out;
19 |         border-radius: 4px;
20 |         margin: 0 8px 8px;
21 |         width: 100px;
22 |         text-align: center;
23 |         border: 1px solid @site-home-line;
24 |         &:before {
25 |           display: none;
26 |         }
27 |       }
28 |       .ant-radio-button-wrapper-checked {
29 |         background: @primary-color;
30 |         border-color: @primary-color;
31 |         color: #fff;
32 |       }
33 |     }
34 |     &-item {
35 |       border: 1px solid @site-home-line;
36 |       border-radius: 4px;
37 |       overflow: hidden;
38 |       &.queue-anim-entering,
39 |       &.queue-anim-leaving {
40 |         transition: none !important;
41 |       }
42 |       img {
43 |         display: block;
44 |       }
45 |     }
46 |   }
47 | }
48 | 


--------------------------------------------------------------------------------
/site/theme/static/home/page4.less:
--------------------------------------------------------------------------------
 1 | .page4 {
 2 |   background: @primary-color;
 3 |   color: #fff;
 4 |   min-height: 292px;
 5 |   text-align: center;
 6 |   p {
 7 |     margin: 0 auto 40px;
 8 |     font-size: 14px;
 9 |     line-height: 20px;
10 |     max-width: 930px;
11 |   }
12 |   .home-button {
13 |     background: #fff;
14 |     .mouseHover(#0028CA, 0, 8px, 16px);
15 |     box-shadow: 0 4px 8px rgba(0, 40, 202, 0.75);
16 |   }
17 |   .bg {
18 |     width: 1440px;
19 |     height: 558px;
20 |     position: absolute;
21 |     top: 0;
22 |     left: 50%;
23 |     margin-left: -720px;
24 |     svg {
25 |       overflow: initial;
26 |     }
27 |   }
28 | }
29 | 


--------------------------------------------------------------------------------
/site/theme/static/home/responsive.less:
--------------------------------------------------------------------------------
 1 | @media only screen and (max-width: 767.99px) {
 2 |   .banner {
 3 |     height: 100vh;
 4 |     .bg-wrapper {
 5 |       #Page-1 {
 6 |         transform: translate(-30px, 80px);
 7 |       }
 8 |       #Group-8 {
 9 |         transform: translate(400px, 69px);
10 |       }
11 |     }
12 |     .text-wrapper {
13 |       padding: 0 24px;
14 |     }
15 |   }
16 |   .page1 .page1-content {
17 |     margin: 88px auto 0;
18 |     min-height: 990px;
19 |     .page1-item {
20 |       margin-bottom: 64px;
21 |     }
22 |   }
23 |   .page2 {
24 |     min-height: 330px;
25 |   }
26 |   .home-wrapper .page-wrapper .page h1 {
27 |     margin: 72px auto 64px;
28 |   }
29 | }
30 | 


--------------------------------------------------------------------------------
/site/theme/static/index.less:
--------------------------------------------------------------------------------
 1 | @import './antd.less';
 2 | @import './default.less';
 3 | @import './common.less';
 4 | @import './header.less';
 5 | @import './footer.less';
 6 | @import './responsive.less';
 7 | @import './home/index.less';
 8 | @import './page/index.less';
 9 | @import './preview-img.less';
10 | @import '~antd/lib/modal/style/index.less';
11 | 


--------------------------------------------------------------------------------
/site/theme/static/page/index.less:
--------------------------------------------------------------------------------
 1 | .main-wrapper {
 2 |   background: #fff;
 3 |   margin: 0;
 4 |   border-radius: @border-radius-base;
 5 |   padding: 40px 0 0;
 6 |   position: relative;
 7 |   &.landing-move-leave {
 8 |     margin-top: 64px;
 9 |   }
10 | }
11 | 
12 | .main-container {
13 |   padding: 0 194px 144px 64px;
14 |   margin-left: -1px;
15 |   background: #fff;
16 |   min-height: 800px;
17 |   border-left: 1px solid #e9e9e9;
18 |   position: relative;
19 |   .markdown {
20 |     background: #fff;
21 |   }
22 | }
23 | 
24 | .main-menu {
25 |   z-index: 1;
26 | }
27 | 
28 | .main-animate-wraper {
29 |   position: relative;
30 |   padding-top: 1px;
31 | }
32 | 
33 | @import './markdown.less';
34 | @import './highlight.less';
35 | @import './page-nav.less';
36 | @import './toc.less';
37 | @import './responsive.less';
38 | 


--------------------------------------------------------------------------------
/site/theme/static/page/page-nav.less:
--------------------------------------------------------------------------------
 1 | .prev-next-nav {
 2 |   position: absolute;
 3 |   bottom: 0;
 4 |   left: 0;
 5 |   width: ~"calc(100% - 194px - 64px)";
 6 |   margin-left: 64px;
 7 |   overflow: hidden;
 8 |   font-size: 14px;
 9 |   border-top: 1px solid @site-border-color-split;
10 | 
11 |   > .prev-page,
12 |   > .next-page {
13 |     padding: 0 24px;
14 |     float: left;
15 |     line-height: 72px;
16 |     height: 72px;
17 |     text-decoration: none;
18 |   }
19 | 
20 |   > a.prev-page {
21 |     i {
22 |       transform: translateX(0);
23 |       transition: transform .3s @ease-out;
24 |     }
25 |     &:hover i {
26 |       color: @primary-color;
27 |       transform: translateX(-3px);
28 |     }
29 |   }
30 |   > .next-page {
31 |     text-align: right;
32 |     float: right;
33 | 
34 |     i {
35 |       transform: translateX(0);
36 |       transition: transform .3s @ease-out;
37 |     }
38 |     &:hover i {
39 |       color: @primary-color;
40 |       transform: translateX(3px);
41 |     }
42 |   }
43 |   .chinese {
44 |     margin-left: 0.5em;
45 |   }
46 | }
47 | 


--------------------------------------------------------------------------------
/site/theme/static/page/responsive.less:
--------------------------------------------------------------------------------
 1 | @media only screen and (max-width: 767.99px) {
 2 |   .markdown .file-logo {
 3 |     .ant-logo, .landing-logo {
 4 |       width: 100px;
 5 |       height: 100px;
 6 |     }
 7 |   }
 8 |   .toc {
 9 |     display: none;
10 |   }
11 |   .main-container {
12 |     padding: 0 24px 144px;
13 |   }
14 |   .prev-next-nav {
15 |     width: ~"calc(100% - 48px)";
16 |     margin: 0 24px;
17 |   }
18 | }
19 | 


--------------------------------------------------------------------------------
/site/theme/static/page/toc.less:
--------------------------------------------------------------------------------
 1 | .toc-affix {
 2 |   position: absolute;
 3 |   top: 8px;
 4 |   right: -174px;
 5 |   .ant-affix {
 6 |     background: #fff;
 7 |   }
 8 |   .ant-anchor {
 9 |     font-size: 12px;
10 |     margin: 16px 0;
11 |     border-left: 1px solid #ebedf0;
12 |     list-style: none;
13 |     a {
14 |       padding-left: 16px;
15 |       display: block;
16 |       transition: all 0.3s ease;
17 |       white-space: nowrap;
18 |       overflow: hidden;
19 |       text-overflow: ellipsis;
20 |       color: @site-text-color;
21 |       width: 110px;
22 |     }
23 |     .ant-anchor-link-active a {
24 |       border-color: @primary-color;
25 |       color: @primary-color;
26 |     }
27 |     .ant-anchor-ink:before {
28 |       display: none;
29 |     }
30 |     .ant-anchor-link-title {
31 |       padding: 0;
32 |     }
33 |   }
34 | }
35 | 
36 | .toc-affix-bottom {
37 |   position: absolute;
38 |   bottom: 88px;
39 |   right: 20px;
40 |   .ant-affix {
41 |     background: #fff;
42 |   }
43 | }
44 | 


--------------------------------------------------------------------------------
/site/theme/static/style.js:
--------------------------------------------------------------------------------
1 | import 'rc-banner-anim/assets/index.css';
2 | import 'rc-drawer/assets/index.css';
3 | import 'react-github-button/assets/style.css';
4 | import './index.less';
5 | 


--------------------------------------------------------------------------------
/site/theme/template/Content/EditButton.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import { Tooltip } from 'antd';
 3 | import { EditOutlined } from '@ant-design/icons';
 4 | 
 5 | export default function EditButton({
 6 |   title,
 7 |   filename,
 8 |   sourcePath = 'https://github.com/ant-design/ant-design-landing/edit/master/',
 9 | }) {
10 |   return (
11 |     <Tooltip title={title}>
12 |       <a className="edit-button" target="_blank" href={`${sourcePath}${filename}`}>
13 |         <EditOutlined />
14 |       </a>
15 |     </Tooltip>
16 |   );
17 | }
18 | 


--------------------------------------------------------------------------------
/site/theme/template/Content/index.jsx:
--------------------------------------------------------------------------------
 1 | import collect from 'bisheng/collect';
 2 | import MainContent from './MainContent';
 3 | import * as utils from '../utils';
 4 | 
 5 | export default collect(async (nextProps) => {
 6 |   const pathname = nextProps.location.pathname;
 7 | 
 8 |   const path = pathname.replace('-cn', '');
 9 | 
10 |   const pageDataPath = path.split('/');
11 | 
12 |   if (/\/components/.test(path) && pageDataPath[1]) {
13 |     const str = pageDataPath[1];
14 |     pageDataPath[1] = str.charAt(0).toUpperCase() + str.slice(1);
15 |   }
16 | 
17 |   const pageData = nextProps.utils.get(nextProps.data, pageDataPath);
18 | 
19 |   // 路由跳转统一处理
20 |   if (pathname === 'components') {
21 |     location.href = '/components/AvatarList';
22 |     return;
23 |   }
24 | 
25 |   if (!pageData) {
26 |     throw 404; // eslint-disable-line no-throw-literal
27 |   }
28 |   const locale = utils.isZhCN(pathname) ? 'zh-CN' : 'en-US';
29 |   const pageDataPromise = typeof pageData === 'function'
30 |     ? pageData() : (pageData[locale] || pageData.index[locale] || pageData.index)();
31 |   const demosFetcher = nextProps.utils.get(nextProps.data, [...pageDataPath, 'demo']);
32 |   if (demosFetcher) {
33 |     const [localizedPageData, demos] = await Promise.all([pageDataPromise, demosFetcher()]);
34 |     return { localizedPageData, demos };
35 |   }
36 |   return { localizedPageData: await pageDataPromise };
37 | })(MainContent);
38 | 


--------------------------------------------------------------------------------
/site/theme/template/Home/component/ImageLoadComp.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import TweenOne from 'rc-tween-one';
 3 | import { Spin } from 'antd';
 4 | 
 5 | const imgLoadData = {};
 6 | 
 7 | export default class ImageLoadComp extends React.PureComponent {
 8 |   constructor(props) {
 9 |     super(props);
10 |     this.id = props.src;
11 |     this.state = {
12 |       isLoad: imgLoadData[this.id],
13 |       anim: null,
14 |     };
15 |   }
16 | 
17 |   onImageLoad = () => {
18 |     if (!imgLoadData[this.id] || !this.state.isLoad) {
19 |       this.setState({
20 |         isLoad: true,
21 |       }, () => {
22 |         imgLoadData[this.id] = true;
23 |       });
24 |     }
25 |   }
26 | 
27 |   onEnter = () => {
28 |     this.setState({
29 |       anim: [
30 |         {
31 |           backgroundPositionY: '100%',
32 |           duration: 4000,
33 |         },
34 |         { backgroundPositionY: '0%', duration: 4000 },
35 |       ],
36 |     });
37 |   }
38 | 
39 |   onLeave = () => {
40 |     this.setState({
41 |       anim: { backgroundPositionY: '0%' },
42 |     });
43 |   }
44 | 
45 |   render() {
46 |     const { src, className } = this.props;
47 |     const { isLoad, anim } = this.state;
48 |     const enter = Array.isArray(anim);
49 |     return (
50 |       <Spin spinning={!isLoad}>
51 |         <TweenOne
52 |           repeat={enter ? -1 : null}
53 |           animation={anim}
54 |           className={className || 'img'}
55 |           style={{ backgroundImage: `url(${src})` }}
56 |           onMouseEnter={this.onEnter}
57 |           onMouseLeave={this.onLeave}
58 |         />
59 |         <img alt="img" src={src} onLoad={this.onImageLoad} style={{ display: 'none' }} />
60 |       </Spin>
61 |     );
62 |   }
63 | }
64 | 


--------------------------------------------------------------------------------
/site/theme/template/Home/index.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import { injectIntl } from 'react-intl';
 3 | import DocumentTitle from 'react-document-title';
 4 | 
 5 | import Banner from './Banner';
 6 | import Page1 from './Page1';
 7 | import Page2 from './Page2';
 8 | import Page3 from './Page3';
 9 | import Page4 from './Page4';
10 | 
11 | function Home(props) {
12 |   return (
13 |     <DocumentTitle title={`Ant Design Landing Page - ${props.intl.formatMessage({ id: 'app.home.slogan' })}`}>
14 |       <div className="home-wrapper">
15 |         <Banner isMobile={props.isMobile} />
16 |         <Page1 isMobile={props.isMobile} />
17 |         <Page2 isMobile={props.isMobile} />
18 |         <Page3 isMobile={props.isMobile} />
19 |         <Page4 isMobile={props.isMobile} />
20 |       </div>
21 |     </DocumentTitle>
22 |   );
23 | }
24 | 
25 | export default injectIntl(Home);
26 | 


--------------------------------------------------------------------------------
/site/theme/template/Home/utils.jsx:
--------------------------------------------------------------------------------
 1 | /* eslint no-undef: 0 */
 2 | import React from 'react';
 3 | import ScrollParallax from 'rc-scroll-anim/lib/ScrollParallax';
 4 | import ticker from 'rc-tween-one/lib/ticker';
 5 | import TweenOne from 'rc-tween-one';
 6 | 
 7 | function ParallaxG(props) {
 8 |   return <ScrollParallax component="g" {...props} />;
 9 | }
10 | 
11 | export function svgBgToParallax(children, location, i = 0) {
12 |   const svgChildren = React.Children.toArray(children).map((child, ii) => (
13 |     <ParallaxG
14 |       key={ii.toString()}
15 |       location={location}
16 |       animation={{
17 |         y: (Math.random() * -200) - 80 - (i * 20),
18 |         playScale: [0, Math.random() + 2],
19 |       }}
20 |     >
21 |       {child}
22 |     </ParallaxG>
23 |   ));
24 |   return svgChildren;
25 | }
26 | export function currentScrollTop() {
27 |   return window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
28 | }
29 | export function windowHeight() {
30 |   return window.innerHeight
31 |     || document.documentElement.clientHeight || document.body.clientHeight;
32 | }
33 | 
34 | export function scrollTo(number, _scrollTop) {
35 |   const scrollTop = _scrollTop || currentScrollTop();
36 |   if (scrollTop !== number) {
37 |     const tickerId = `scrollToTop-${Date.now()}`;
38 |     const startFrame = ticker.frame;
39 |     ticker.wake(tickerId, () => {
40 |       const moment = (ticker.frame - startFrame) * ticker.perFrame;
41 |       const ratio = TweenOne.easing.easeInOutCubic(moment, scrollTop, number, 450);
42 |       window.scrollTo(window.scrollX, ratio);
43 |       if (moment >= 450) {
44 |         ticker.clear(tickerId);
45 |       }
46 |     });
47 |   }
48 | }
49 | 
50 | // 图处预加载;
51 | const div = document.createElement('div');
52 | div.style.display = 'none';
53 | document.body.appendChild(div);
54 | [
55 | ].forEach((src) => {
56 |   const img = new Image();
57 |   img.src = src;
58 |   div.appendChild(img);
59 | });
60 | 


--------------------------------------------------------------------------------
/site/theme/template/Layout/Layout.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import PropTypes from 'prop-types';
 3 | import { IntlProvider } from 'react-intl';
 4 | import { ConfigProvider } from 'antd';
 5 | import zhCN from 'antd/es/locale/zh_CN';
 6 | import { enquireScreen } from 'enquire-js';
 7 | import Animate from 'rc-animate';
 8 | 
 9 | import enLocale from '../../en-US';
10 | import cnLocale from '../../zh-CN';
11 | import * as utils from '../utils';
12 | 
13 | import Header from './Header';
14 | import Footer from './Footer';
15 | 
16 | let isMobile;
17 | enquireScreen((b) => {
18 |   isMobile = b;
19 | });
20 | class Layout extends React.PureComponent {
21 |   static contextTypes = {
22 |     router: PropTypes.object.isRequired,
23 |   }
24 | 
25 |   constructor(props) {
26 |     super(props);
27 |     const { pathname } = props.location;
28 |     const appLocale = utils.isZhCN(pathname) ? cnLocale : enLocale;
29 | 
30 |     this.state = {
31 |       appLocale,
32 |       isMobile,
33 |     };
34 |   }
35 | 
36 |   componentDidMount() {
37 |     enquireScreen((b) => {
38 |       this.setState({
39 |         isMobile: !!b,
40 |       });
41 |     });
42 |   }
43 | 
44 |   render() {
45 |     const { children, ...restProps } = this.props;
46 |     const { pathname } = this.props.location;
47 |     const { appLocale } = this.state;
48 |     const pathKey = pathname && pathname.split('/')[0];// (pathname.split('/')[1] || pathname.split('/')[0]);
49 |     const childrenToRender = React.cloneElement(children, {
50 |       ...children.props,
51 |       isMobile: this.state.isMobile,
52 |       key: pathKey,
53 |     });
54 |     return (
55 |       <IntlProvider locale={appLocale.locale} messages={appLocale.messages}>
56 |         <ConfigProvider locale={appLocale.locale === 'zh-CN' ? zhCN : null}>
57 |           <div className={(pathname === '/' || pathname === 'index-cn') ? 'home' : ''}>
58 |             <div className="header-placeholder" />
59 |             <Header {...restProps} isMobile={this.state.isMobile} />
60 |             <Animate component="div" transitionName="landing-move">
61 |               {childrenToRender}
62 |             </Animate>
63 |             <Footer {...restProps} isMobile={this.state.isMobile} />
64 |           </div>
65 |         </ConfigProvider>
66 |       </IntlProvider>
67 |     );
68 |   }
69 | }
70 | 
71 | export default Layout;
72 | 


--------------------------------------------------------------------------------
/site/theme/template/Layout/PhoneNav.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import classnames from 'classnames';
 3 | import { polyfill } from 'react-lifecycles-compat';
 4 | 
 5 | import { Popover } from 'antd';
 6 | 
 7 | class PhoneNav extends React.PureComponent {
 8 |   static getDerivedStateFromProps(props, { prevProps, show }) {
 9 |     const nextState = {
10 |       prevProps: props,
11 |     };
12 |     if (prevProps && props !== prevProps && show) {
13 |       nextState.show = false;
14 |     }
15 |     return nextState;
16 |   }
17 | 
18 |   state = {
19 |     show: false,
20 |   }
21 | 
22 |   onMenuVisibleChange = (show) => {
23 |     this.setState({
24 |       show,
25 |     });
26 |   }
27 | 
28 |   render() {
29 |     const { children } = this.props;
30 |     const { show } = this.state;
31 |     const barClassName = classnames('phone-nav-bar', {
32 |       open: show,
33 |     });
34 |     return (
35 |       <Popover
36 |         overlayClassName="popover-menu"
37 |         placement="bottomRight"
38 |         content={children}
39 |         trigger="click"
40 |         visible={show}
41 |         arrowPointAtCenter
42 |         onVisibleChange={this.onMenuVisibleChange}
43 |       >
44 |         <div className="phone-nav-bar-wrapper">
45 |           <i className={barClassName} />
46 |         </div>
47 |       </Popover>
48 |     );
49 |   }
50 | }
51 | 
52 | export default polyfill(PhoneNav);
53 | 


--------------------------------------------------------------------------------
/site/theme/template/Layout/index.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import ReactDOM from 'react-dom';
 3 | // import { createLogger } from 'redux-logger';
 4 | import Layout from './Layout';
 5 | import '../../static/style';
 6 | 
 7 | if (typeof window !== 'undefined') {
 8 |   /* eslint-disable global-require */
 9 |   require('../../static/style');
10 | 
11 |   // Expose to iframe
12 |   window.react = React;
13 |   window['react-dom'] = ReactDOM;
14 |   // window.antd = require('antd');
15 |   /* eslint-enable global-require */
16 | }
17 | 
18 | export default function Index(props) {
19 |   return (<Layout {...props} />);
20 | }
21 | 


--------------------------------------------------------------------------------
/site/theme/template/NotFound.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import { Link } from 'bisheng/router';
 3 | // import * as utils from './utils';
 4 | 
 5 | export default function NotFound() {
 6 |   return (
 7 |     <div id="page-404">
 8 |       <section>
 9 |         <h1>404</h1>
10 |         <p>
11 |           你要找的页面不存在
12 |           <Link to="dsf">返回首页</Link>
13 |         </p>
14 |       </section>
15 |       <style
16 |         dangerouslySetInnerHTML={{
17 |           __html: '#react-content { height: 100%; background-color: #fff }',
18 |         }}
19 |       />
20 |     </div>
21 |   );
22 | }
23 | 


--------------------------------------------------------------------------------
/site/theme/template/Other/Cases.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | 
 3 | import { Row, Col } from 'antd';
 4 | 
 5 | import './cases.less';
 6 | 
 7 | export default class Demo extends React.PureComponent {
 8 |   render() {
 9 |     return (
10 |       <Row gutter={24}>
11 |         {this.props.data.map((item) => (
12 |           <Col xl={12} sm={24} xs={24} key={item.title}>
13 |             <a href={item.url} target="_black" className="cases-content-wrapper">
14 |               <div className="img-wrapper"><img src={item.img} width="100%" alt="img" /></div>
15 |               <div>
16 |                 <h3>{item.title}</h3>
17 |                 <p>{item.content}</p>
18 |               </div>
19 |             </a>
20 |           </Col>
21 |         ))}
22 |       </Row>
23 |     );
24 |   }
25 | }
26 | 


--------------------------------------------------------------------------------
/site/theme/template/Other/Download.jsx:
--------------------------------------------------------------------------------
 1 | import React from 'react';
 2 | import { Row, Col } from 'antd';
 3 | import ImageLoadComp from '../Home/component/ImageLoadComp';
 4 | 
 5 | import './download.less';
 6 | 
 7 | export default function Download({ data }) {
 8 |   return (
 9 |     <Row gutter={24}>
10 |       {data.map((item) => (
11 |         <Col key={item.title} sm={24} md={12} xxl={8} className="resource-wrapper">
12 |           <a className="resource-cards"
13 |             href={item.url}
14 |             target="_blank"
15 |             onClick={() => {
16 |               if (!location.port && window.gtag) {
17 |                 window.gtag('event', `saveSKetch_${item.name}`);
18 |               }
19 |             }}
20 |           >
21 |             <ImageLoadComp className="img-wrapper" src={item.img} />
22 |             <div className="text-wrapper">
23 |               <h3>{item.title}</h3>
24 |               <p>{item.content}</p>
25 |             </div>
26 |           </a>
27 |         </Col>
28 |       ))}
29 |     </Row>
30 |   );
31 | }
32 | 


--------------------------------------------------------------------------------
/site/theme/template/Other/cases.less:
--------------------------------------------------------------------------------
 1 | @import '../../static/antd.less';
 2 | @import '../../static/default.less';
 3 | .markdown .cases-content-wrapper {
 4 |   padding: 10px;
 5 |   background: #f2f4f5;
 6 |   border-radius: 4px;
 7 |   .mouseHover(#666);
 8 |   display: block;
 9 |   will-change: transform;
10 |   margin-bottom: 24px;
11 |   .img-wrapper {
12 |     border-radius: 2px;
13 |     overflow: hidden;
14 |   }
15 |   h3 {
16 |     font-size: 16px;
17 |     margin: 16px auto 8px;
18 |     line-height: 1.5;
19 |   }
20 |   p {
21 |     margin: auto;
22 |     color: #314659;
23 |   }
24 | }
25 | 


--------------------------------------------------------------------------------
/site/theme/template/Other/download.less:
--------------------------------------------------------------------------------
 1 | @import '../../static/antd.less';
 2 | @import '../../static/default.less';
 3 | .resource-wrapper {
 4 |   margin-bottom: 24px;
 5 | }
 6 | .resource-cards {
 7 |   padding: 10px;
 8 |   background: #fff;
 9 |   border-radius: 4px;
10 |   border: 1px solid #f0f0f0;
11 |   .mouseHover(#999);
12 |   display: block;
13 |   .img-wrapper {
14 |     border-radius: 2px;
15 |     overflow: hidden;
16 |     height: 310px;
17 |     background-size: 100% auto;
18 |     background-repeat: no-repeat;
19 |     background-position: top center;
20 |     background-color: #f0f0f0;
21 |   }
22 | 
23 |   .text-wrapper {
24 |     h3 {
25 |       margin: 16px auto 8px;
26 |       line-height: 1.5;
27 |     }
28 |     p {
29 |       font-size: 12px;
30 |       margin: auto;
31 |       color: fade(@text-color, 75);
32 |     }
33 |   }
34 | }
35 | 


--------------------------------------------------------------------------------
/site/theme/zh-CN.js:
--------------------------------------------------------------------------------
 1 | module.exports = {
 2 |   locale: 'zh-CN',
 3 |   messages: {
 4 |     'app.header.menu.home': '首页',
 5 |     'app.header.menu.language': '文档',
 6 |     'app.header.menu.edit': '编辑器',
 7 |     'app.home.introduce': 'Ant Design Landing 平台拥有丰富的各类首页模板,下载模板代码包,即可快速使用,也可使用首页编辑器,快速搭建一个属于你的专属首页',
 8 |     'app.home.select-template': '丰富模板',
 9 |     'app.home.enter-editor': '进入编辑器',
10 |     'app.home.module': '丰富的模块',
11 |     'app.home.features': '三大特征',
12 |     'app.home.fatures.language': '设计指引',
13 |     'app.home.fatures.sketch': 'Sketch 资源包',
14 |     'app.home.fatures.responsive': '响应式布局',
15 |     'app.home.templates': '丰富的模板',
16 |     'app.home.preview': '预览',
17 |     'app.home.edit': '编辑',
18 |     'app.home.download': '下载',
19 |     'app.home.edit-slogen': '所有模板与模块都基于 Ant Design 设计规范设计,你可以直接下载我们的模板和源文件,也可使用我们的编辑器,快速搭建一个属于你的专属首页',
20 |     'app.home.slogan': 'Ant Design Landing 模板与规范',
21 |     'app.content.edit-page': '在 Github 上编辑此页!',
22 |     'app.footer.repo': '源码仓库',
23 |     'app.footer.template': '模板仓库',
24 |     'app.footer.chinamirror': '国内镜像站点 🇨🇳',
25 |     'app.footer.scaffolds': '脚手架市场',
26 |     'app.footer.links': '相关站点',
27 |     'app.footer.data-vis': '蚂蚁数据可视化方案',
28 |     'app.footer.eggjs': '企业级 Node Web 开发框架',
29 |     'app.footer.motion': '设计动效',
30 |     'app.footer.kitchen': 'Sketch 工具集',
31 |     'app.footer.antd-library': 'Axure 部件库',
32 |     'app.footer.umi': 'React 应用开发框架',
33 |     'app.footer.dumi': '组件/文档研发工具',
34 |     'app.footer.dva': '数据流前端框架',
35 |     'app.footer.design-platform': '蚂蚁金服设计平台',
36 |     'app.footer.antux': '页面逻辑素材',
37 |     'app.footer.community': '社区',
38 |     'app.footer.issues': '讨论列表',
39 |     'app.footer.work-with-us': '加入我们',
40 |     'app.footer.author': '蚂蚁金服体验技术部出品 @ AFX',
41 |     'app.footer.resources': '相关资源',
42 |     'app.footer.more-product': '更多产品',
43 |     'app.footer.yuque': '语雀',
44 |     'app.footer.yuque.slogan': '知识创作·协作平台',
45 |     'app.footer.fengdie': '云凤蝶',
46 |     'app.footer.fengdie.slogan': '移动建站平台',
47 |     'app.footer.seeconf': '蚂蚁体验科技大会',
48 |     'app.footer.xcloud': '蚂蚁体验云',
49 |     'app.footer.lang': 'English',
50 |     'app.layout.notification.title': '关注下 Star 数',
51 |     'app.layout.notification.content': '我们需要您的支持,请点击按钮帮助我们增加 github star。',
52 |   },
53 | };
54 | 


--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
 1 | /* eslint no-param-reassign: 0 */
 2 | // This config is for building dist files
 3 | const getWebpackConfig = require('antd-tools/lib/getWebpackConfig');
 4 | 
 5 | const { webpack } = getWebpackConfig;
 6 | 
 7 | // noParse still leave `require('./locale' + name)` in dist files
 8 | // ignore is better: http://stackoverflow.com/q/25384360
 9 | function ignoreMomentLocale(webpackConfig) {
10 |   delete webpackConfig.module.noParse;
11 |   webpackConfig.plugins.push(new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/));
12 | }
13 | 
14 | function externalMoment(config) {
15 |   config.externals.moment = {
16 |     root: 'moment',
17 |     commonjs2: 'moment',
18 |     commonjs: 'moment',
19 |     amd: 'moment',
20 |   };
21 | }
22 | 
23 | const webpackConfig = getWebpackConfig(false);
24 | if (process.env.RUN_ENV === 'PRODUCTION') {
25 |   webpackConfig.forEach((config) => {
26 |     ignoreMomentLocale(config);
27 |     externalMoment(config);
28 |   });
29 | }
30 | 
31 | module.exports = webpackConfig;
32 | 


--------------------------------------------------------------------------------