diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..e20ce7e1 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,2 @@ +node_modules/ +_site diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 1d56b46d..00000000 --- a/.eslintrc +++ /dev/null @@ -1,34 +0,0 @@ -{ - "extends": "eslint-config-airbnb", - "parser": "babel-eslint", - "rules": { - "import/no-unresolved": 0, - "no-mixed-operators": 0, - "react/prefer-stateless-function": 0, - "jsx-a11y/no-static-element-interactions": 0, - "react/no-multi-comp": 0, - "react/forbid-prop-types": 0, - "no-undef": 0, - "react/no-find-dom-node": 0, - "react/no-danger": 0, - "react/jsx-no-target-blank": 0, - "jsx-a11y/anchor-has-content": 0, - "no-useless-escape": 0, - "import/no-webpack-loader-syntax": 0, - "comma-dangle": ["error", "always-multiline"], - "react/no-unescaped-entities": 0, - "jsx-a11y/alt-text": 0, - "jsx-a11y/click-events-have-key-events": 0, - "react/no-array-index-key": 0, - "prefer-destructuring": 0, - "react/jsx-closing-tag-location": 0, - "jsx-a11y/anchor-is-valid": 0, - "react/require-default-props": 0, - "jsx-a11y/iframe-has-title": 0, - "jsx-a11y/media-has-caption": 0, - "jsx-a11y/no-noninteractive-element-interactions": 0, - "no-restricted-globals": 0, - "jsx-a11y/accessible-emoji": 0 - // "no-unused-expressions": 0 - } -} diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000..38168c66 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,83 @@ +const eslintrc = { + extends: ['eslint-config-airbnb'], + env: { + browser: true, + node: true, + jasmine: true, + jest: true, + es6: true, + }, + parser: 'babel-eslint', + parserOptions: { + ecmaVersion: 6, + ecmaFeatures: { + jsx: true, + experimentalObjectRestSpread: true, + }, + }, + plugins: [ + 'markdown', + 'react', + 'babel', + ], + rules: { + 'func-names': 0, + 'arrow-body-style': 0, + 'react/sort-comp': 0, + 'react/prop-types': 0, + 'react/jsx-first-prop-new-line': 0, + 'react/jsx-filename-extension': [1, { extensions: ['.js', '.jsx', '.md'] }], + 'import/extensions': 0, + 'import/no-unresolved': 0, + 'import/no-extraneous-dependencies': 0, + 'prefer-destructuring': 0, + 'no-param-reassign': 0, + 'no-return-assign': 0, + 'max-len': 0, + 'consistent-return': 0, + 'no-redeclare': 0, + 'react/require-extension': 0, + 'jsx-a11y/no-static-element-interactions': 0, + 'jsx-a11y/anchor-has-content': 0, + 'jsx-a11y/click-events-have-key-events': 0, + 'jsx-a11y/no-noninteractive-element-interactions': 0, + 'jsx-a11y/anchor-is-valid': 0, + 'react/no-danger': 0, + 'comma-dangle': ['error', 'always-multiline'], + 'function-paren-newline': 0, + 'object-curly-newline': 0, + 'no-restricted-globals': 0, + 'jsx-a11y/mouse-events-have-key-events': 0, + 'react/jsx-no-target-blank': 0, + 'react/no-find-dom-node': 0, + 'react/no-unescaped-entities': 0, + 'react/prefer-stateless-function': 0, + 'import/no-webpack-loader-syntax': 0, + 'react/forbid-prop-types': 0, + 'react/destructuring-assignment': 0, + 'react/no-access-state-in-setstate': 0, + 'react/require-default-props': 0, + 'jsx-a11y/accessible-emoji': 0 + }, +}; + +if (process.env.RUN_ENV === 'DEMO') { + eslintrc.globals = { + React: true, + ReactDOM: true, + mountNode: true, + }; + + Object.assign(eslintrc.rules, { + indent: 0, + 'no-console': 0, + 'no-plusplus': 0, + 'eol-last': 0, + 'prefer-rest-params': 0, + 'react/no-multi-comp': 0, + 'jsx-a11y/href-no-hash': 0, + 'import/newline-after-import': 0, + }); +} + +module.exports = eslintrc; \ No newline at end of file diff --git a/.stylelintrc b/.stylelintrc new file mode 100644 index 00000000..352dc098 --- /dev/null +++ b/.stylelintrc @@ -0,0 +1,22 @@ +{ + "extends": "stylelint-config-standard", + "rules": { + "comment-empty-line-before": null, + "declaration-empty-line-before": null, + "function-comma-newline-after": null, + "function-name-case": null, + "function-parentheses-newline-inside": null, + "function-max-empty-lines": null, + "function-whitespace-after": null, + "indentation": null, + "number-leading-zero": null, + "number-no-trailing-zeros": null, + "rule-empty-line-before": null, + "selector-combinator-space-after": null, + "selector-list-comma-newline-after": null, + "selector-pseudo-element-colon-notation": null, + "unit-no-unknown": null, + "value-list-max-empty-lines": null, + "no-descending-specificity": null + } +} diff --git a/components/animate/demo/appear.md b/components/animate/demo/appear.md index 531d12c7..026fd230 100644 --- a/components/animate/demo/appear.md +++ b/components/animate/demo/appear.md @@ -1,9 +1,15 @@ --- order: 2 -title: 开始的进场 +title: + zh-CN: 开始的进场 + en-US: Appear --- -开始的进场动画, css样式查看第一个demo。 +## zh-CN +开始的进场动画, css 样式查看第一个 demo。 + +## en-US +Appear the opening animation, css style to view the first demo. ```jsx import Animate from 'rc-animate'; diff --git a/components/animate/demo/remove.md b/components/animate/demo/remove.md index c64c4cc2..56dbd684 100644 --- a/components/animate/demo/remove.md +++ b/components/animate/demo/remove.md @@ -1,10 +1,18 @@ --- order: 1 -title: 删除子级 +title: + zh-CN: 删除子级 + en-US: Remove Child --- +## zh-CN + 动画出场后将子级删除掉。 +## en-US +The child is deleted after the animation leave. + + ```jsx import Animate from 'rc-animate'; import Button from 'antd/lib/button'; diff --git a/components/animate/demo/simple.md b/components/animate/demo/simple.md index 33fd3687..bb035fcc 100644 --- a/components/animate/demo/simple.md +++ b/components/animate/demo/simple.md @@ -1,10 +1,15 @@ --- order: 0 -title: 简单的例子 +title: + zh-CN: 简单的例子 + en-US: Simple --- - +## zh-CN 同时支持进场和离场动画。 +## en-US +Both enter and leave animations are supported. + ```jsx import Animate from 'rc-animate'; import Button from 'antd/lib/button'; diff --git a/components/animate/index.en-US.md b/components/animate/index.en-US.md new file mode 100644 index 00000000..4f78ec40 --- /dev/null +++ b/components/animate/index.en-US.md @@ -0,0 +1,52 @@ +--- +order: 1 +title: Animate +--- + +Animate the individual elements according to the state, and use them together with css or other third-party animation classes; specific ref [API](/api/animate) + +## When To Use + +- When the element state is switched; + +--- + +## How To Use + +### Install + +```bash +$ npm install rc-animate --save +``` + +### Usage + +```jsx +var Animate = require('rc-animate'); +var ReactDOM = require('react-dom'); +ReactDOM.render(( + + {show ?
demo
: null} +
+), container); +``` +> [Detailed use](https://github.com/react-component/animate/blob/master/docs/zh-cn/intro.md) + +## API + +### props + +| name | type | default | description | +|-----------|----------|------------|-------------------| +| showProp | String | null | using prop for show and hide. [demo](http://react-component.github.io/animate/examples/hide-todo.html) | +| exclusive | Boolean | false | whether allow only one set of animations(enter and leave) at the same time. | +| transitionName | String | null | specify corresponding css, see ReactCSSTransitionGroup | +| transitionAppear | Boolean | false | whether support transition appear animate | +| transitionEnter | Boolean | true | whether support transition enter animate | +| transitionLeave | Boolean | true | whether support transition leave animate | +| onEnd | Func | true | animation end callback, callBack(key: String, exists: Boolean); | +| animation | Object | {} | to animate with js. see animation format below. | +| component | React.Element/String | `span` | wrap dom node or component for children. set to '' if you do not wrap for only one child | +| componentProps | Object | {} | extra props that will be passed to component | + +> `animation` case to see [demo](http://react-component.github.io/animate/) diff --git a/components/animate/index.md b/components/animate/index.zh-CN.md similarity index 97% rename from components/animate/index.md rename to components/animate/index.zh-CN.md index 6e372f5f..94ce8bd5 100644 --- a/components/animate/index.md +++ b/components/animate/index.zh-CN.md @@ -1,7 +1,8 @@ --- order: 1 -chinese: Css样式动画 -english: Animate +title: + zh-CN: Css样式动画 + en-US: Animate --- 对单个元素根据状态进行动画显示隐藏,需结合 css 或其它第三方动画类一起使用;具体参数请参见 [API](/api/animate) diff --git a/components/banner-anim/index.md b/components/banner-anim/index.md index c9c0ad8a..5fae2f81 100644 --- a/components/banner-anim/index.md +++ b/components/banner-anim/index.md @@ -1,8 +1,9 @@ --- order: 5 -chinese: Banner动画 -english: BannerAnim vertical: true +title: + zh-CN: Banner动画 + en-US: BannerAnim --- 通过简单的配置, 就能让你的 banner 动起来。 具体参数请参见 [API](/api/banner-anim) diff --git a/components/queue-anim/demo/simple.md b/components/queue-anim/demo/simple.md index a7d19178..2aefef64 100644 --- a/components/queue-anim/demo/simple.md +++ b/components/queue-anim/demo/simple.md @@ -1,10 +1,16 @@ --- order: 0 -title: 简单的例子 +title: + zh-CN: 简单的例子 + en-US: Simple example --- +## zh-CN 最简单的进场例子。 +## en-US +The simplest example of entry. + ````jsx import QueueAnim from 'rc-queue-anim'; diff --git a/components/queue-anim/index.md b/components/queue-anim/index.md index 24523103..735a3a56 100644 --- a/components/queue-anim/index.md +++ b/components/queue-anim/index.md @@ -1,9 +1,10 @@ --- -chinese: 进出场动画 cols: 2 order: 2 -english: QueueAnim vertical: true +title: + zh-CN: 进出场动画 + en-US: QueueAnim --- 通过简单的配置对一组元素添加串行的进场动画效果。具体参数请参见 [API](/api/queue-anim) diff --git a/components/scroll-anim/index.md b/components/scroll-anim/index.md index e97ae5fc..a3e87be2 100644 --- a/components/scroll-anim/index.md +++ b/components/scroll-anim/index.md @@ -1,8 +1,9 @@ --- -chinese: 页面滚动动画 order: 4 -english: ScrollAnim vertical: true +title: + zh-CN: 页面滚动动画 + en-US: ScrollAnim --- 通过简单的配置,对页面里的元素添加随滚动条滚动的动画。具体参数请参见 [API](/api/scroll-anim) diff --git a/components/texty/index.md b/components/texty/index.md index 5109fc83..429239ba 100644 --- a/components/texty/index.md +++ b/components/texty/index.md @@ -1,7 +1,8 @@ --- order: 3 -chinese: 文字动画 -english: TextyAnim +title: + zh-CN: 文字动画 + en-US: TextyAnim --- 一个针对文字标题的进行进出场动画的组件,提供非富的动画效果,也可以随自已的需求来配置完成不同的效果,具体参数请参见 [API](/api/texty); diff --git a/components/tween-one/demo/bezier.md b/components/tween-one/demo/bezier.md index 149a5514..9b1911a1 100644 --- a/components/tween-one/demo/bezier.md +++ b/components/tween-one/demo/bezier.md @@ -1,12 +1,17 @@ --- order: 8 -title: 曲线动画 +title: + zh-CN: 曲线动画 + en-US: Curve Animate mouseEnter: true vertical: true --- +## zh-CN 贝赛尔曲线动画。 gsap 的 BezierPlugin 曲线动画; +## en-US +Bezier curve animation. ref Gzap BezierPlugin curve animation; ```jsx import PropTypes from 'prop-types'; diff --git a/components/tween-one/demo/children.md b/components/tween-one/demo/children.md index e2c4e849..b2b7b6c0 100644 --- a/components/tween-one/demo/children.md +++ b/components/tween-one/demo/children.md @@ -1,10 +1,16 @@ --- order: 4 -title: 数值变化 +title: + zh-CN: 数值变化 + en-US: Number Change --- +## zh-CN 输入与当前不同的数值,再点开始,不输入将过渡到 10000。 +## en-US +Enter a different value from the current one, then click Start. No input will transition to 10000. + ```jsx import PropTypes from 'prop-types'; import { InputNumber, Button, Checkbox } from 'antd'; @@ -78,7 +84,7 @@ class Demo extends React.Component { style={{ marginBottom: 32 }} onClick={this.onClick} > - 开始 + Start diff --git a/components/tween-one/demo/control.md b/components/tween-one/demo/control.md index 2be52742..7676bbe2 100644 --- a/components/tween-one/demo/control.md +++ b/components/tween-one/demo/control.md @@ -1,11 +1,17 @@ --- order: 2 -title: 变更动画参数 +title: + zh-CN: 变更动画参数 + en-US: Change Param mouseEnter: true --- +## zh-CN 可操作型变更动画。 +## en-US +Operational change animation. + ```jsx import PropTypes from 'prop-types'; import TweenOne from 'rc-tween-one'; diff --git a/components/tween-one/demo/easingPath.md b/components/tween-one/demo/easingPath.md index 9cc7e3e3..9c15460b 100644 --- a/components/tween-one/demo/easingPath.md +++ b/components/tween-one/demo/easingPath.md @@ -1,11 +1,16 @@ --- order: 3 -title: 路径缓动 +title: + zh-CN: 路径缓动 + en-US: Path Easing + mouseEnter: true --- - +## zh-CN 鼠标经过或手指按下可查看旋转效果。 +## en-US +Mouse hover or touch see the animation. ```jsx import PropTypes from 'prop-types'; diff --git a/components/tween-one/demo/path.md b/components/tween-one/demo/path.md index 5544e0db..003af773 100644 --- a/components/tween-one/demo/path.md +++ b/components/tween-one/demo/path.md @@ -1,12 +1,16 @@ --- order: 7 -title: 曲线路径动画 +title: + zh-CN: 曲线路径动画 + en-US: Curve Path Animation mouseEnter: true --- - +## zh-CN 曲线路径动画。 +## en-US +Mouse hover or touch see the animation. Curve Path Animation. ```jsx import PropTypes from 'prop-types'; diff --git a/components/tween-one/demo/position.md b/components/tween-one/demo/position.md index ec621f6d..59155513 100644 --- a/components/tween-one/demo/position.md +++ b/components/tween-one/demo/position.md @@ -1,10 +1,16 @@ --- order: 0 -title: 基本动画效果 +title: + zh-CN: 基本动画效果 + en-US: Basic Animate mouseEnter: true --- -鼠标经过或手指按下可查看位移效果。如 x, y, z, scale, rotate, blur, marign等, 更多参数参考 [动画术语](language/animate-term); +## zh-CN +鼠标经过或手指按下可查看位移效果。如 `x, y, z, scale, rotate, blur, marign`等, 更多参数参考 [动画术语](language/animate-term); + +## en-US +Mouse hover or touch see the animation. For: `x, y, z, scale, rotate, blur, marign` etc, more ref [Animate term](language/animate-term); ```jsx diff --git a/components/tween-one/demo/svgDraw.md b/components/tween-one/demo/svgDraw.md index ca3e1f8d..39037d26 100644 --- a/components/tween-one/demo/svgDraw.md +++ b/components/tween-one/demo/svgDraw.md @@ -1,10 +1,15 @@ --- order: 5 -title: svg 线性动画 +title: + zh-CN: SVG 线性动画 + en-US: SVG Linear Animate --- -点击切换线效果。 +## zh-CN +基本线性生成与消失的动态效果。 +## en-US +Basic linear generation and disappearing dynamic effects. ```jsx import TweenOne from 'rc-tween-one'; @@ -37,7 +42,7 @@ class Demo extends React.Component { return (
-

当前参数:{this.state.tweenData}

+

Current Param: {this.state.tweenData}

); } diff --git a/components/tween-one/demo/svgMorph.md b/components/tween-one/demo/svgMorph.md index ef62d502..9cc3c225 100644 --- a/components/tween-one/demo/svgMorph.md +++ b/components/tween-one/demo/svgMorph.md @@ -1,11 +1,16 @@ --- order: 6 -title: svg 形变动画 +title: + zh-CN: SVG 形变动画 + en-US: SVG Deformation Animate mouseEnter: true --- -点击切换线效果。 +## zh-CN +SVG 图形形状变化的动态效果。 +## en-US +The dynamic effect of SVG graphic shape changes. ```jsx import TweenOne from 'rc-tween-one'; diff --git a/components/tween-one/demo/timeline.md b/components/tween-one/demo/timeline.md index ada5ba9b..193236ef 100644 --- a/components/tween-one/demo/timeline.md +++ b/components/tween-one/demo/timeline.md @@ -1,11 +1,15 @@ --- order: 1 -title: 时间轴效果 +title: + zh-CN: 时间轴效果 + en-US: Timeline mouseEnter: true --- - +## zh-CN 鼠标经过或手指按下可查看时间轴效果, 时间轴效果,无限循环时间轴效果。 +## en-US +Mouse hover or touch see the animation. Timeline effects, infinite loop timeline effects. ```jsx import TweenOne from 'rc-tween-one'; diff --git a/components/tween-one/index.en-US.md b/components/tween-one/index.en-US.md new file mode 100644 index 00000000..b1ae9168 --- /dev/null +++ b/components/tween-one/index.en-US.md @@ -0,0 +1,218 @@ +--- +order: 0 +title: TweenOne + +--- + +This is a component that works on a single element label. It can perform all style and label attribute animations, including `transform3d, blur` etc., and can also complete Bezier animation. See the specific ref [API](/api/tween-one) + +## When To Use + +- When element changes the style. +- When an element completes a different timeline animation for a certain period of time. +- When the number changes. +- When SVG is linearly grown or deformed. +- The element needs to be animated on the specified path. + +--- + +## How To Use + +### Install + +```bash +$ npm install rc-tween-one --save +``` +### Usage + +```jsx +import TweenOne from 'rc-tween-one'; +ReactDOM.render(, mountNode); +``` + +### TweenOneGroup +```js +import TweenOne from 'rc-tween-one'; +var TweenOneGroup = TweenOne.TweenOneGroup; +React.render( +
demo
+
, container); +``` + + +## API + +| name | type | default | description | +| -------------- | -------------------- | ------- | --------------------- | +| animation | object / array | null | animate configure parameters. | +| paused | boolean | false | animate pause. | +| reverse | boolean | false | animate revers. | +| reverseDelay | number | 0 | animate revers start delay. | +| repeat | number | 0 | `animation` all data repeat, To repeat indefinitely, use -1 | +| yoyo | boolean | false | `animation` all data alternating backward and forward on each repeat. | +| onChange | function | null | when the animation change called, callback({ moment, target, index, mode, timelineMode }) | +| moment | number | null | Set the moment at the current animation timeline, please set it back to null after setting. | +| attr | string | `style` | `style` or `attr`, `attr` is tag attribute. when morph SVG must be. | +| resetStyle | boolean | false | update animation data, reset init style. | +| component | React.Element/String | `div` | component tag | +| componentProps | object | null | `component` is React.Element, component tag props, not add style | + +### animation + +> Basic animation param. please view[animation terms](/language/animate-term); + +**Cannot be used at the same time reverse and repeat: -1.** + +| name | type | default | description | +| ----------- | ------------------ | --------------- | -------------- | +| type | string | `to` | Play type, `to` for normal play, `from` for reverse play, `set` is the same as { duration: 0 }. | +| duration | number | 450 | animate duration. | +| delay | number | 0 | animate delay. | +| repeat | number | 0 | animate repeat, To repeat indefinitely, use -1.| +| repeatDelay | number | 0 | repeat start delay. | +| appearTo | number | null | Add to the specified time. | +| yoyo | boolean | false | `true`: alternating backward and forward on each repeat. | +| ease | string / function | `easeInOutQuad` | animate ease. [refer](http://easings.net/zh-cn);
function: TweenOne.easing.path(path, param) Details are as follows | +| onStart | function | null | Callback when the animation is begin, callback(e), e: { index, target }. | +| onUpdate | function | null | Callback when the animation is update, callback(e), e: { index, target, ratio }. | +| onComplete | function | null | Callback when the animation is complete, callback(e), e: { index, target }. +| onRepeat | function | null | Callback every time the animation is repeat, callback(e), e: { index, target }. | + +- The plugin parameters refer to the following plugin. Such as `bezier`, `SVGDraw`, `path`, `Children` etc. + +> `animation` equal to `array` is timeline animation, ref: `animation={[{ x: 10 }, { y: 10 }]}`; + + +### TweenOne.easing.path + +```jsx + +const path = 'M0,100 C30,60 0,20 50,50 C70,70 60,0 100,0'; +const ease = TweenOne.easing.path(path); + +``` +#### path +The value of `d` in the path of the SVG path; +#### param +| name | type | default | description | +| ----------- | ------ | ---- | ------------------------------ | +| rect | number | 100 | Draw the square size of the easing path. | +| lengthPixel | number | 1500 | The entire path is divided into 1500 pixels to take points. | + +## Plugins + +### SvgDrawPlugin + +SVGDraw = string or number; + +SVG Linear animation + +``` jsx +import SvgDrawPlugin from 'rc-tween-one/lib/plugin/SvgDrawPlugin'; +TweenOne.plugins.push(SvgDrawPlugin); + + + +``` +`{ SVGDraw: 30 }` or `{ SVGDraw: 'start end' }` 值可以为 `%`; + +### SvgMorphPlugin + +Svg path deformation animation, such as `{ d: 'M0 0L100 100' }` + +> Note: `SvgMorphPlugin` must be set `attr: 'attr'` + +``` jsx +import SvgMorphPlugin from 'rc-tween-one/lib/plugin/SvgMorphPlugin'; +TweenOne.plugins.push(SvgMorphPlugin); + + + +``` + +### PathPlugin + +``` jsx +import PathPlugin from 'rc-tween-one/lib/plugin/PathPlugin'; +TweenOne.plugins.push(PathPlugin); +const path = 'M0,100 C30,60 0,20 50,50 C70,70 60,0 100,0'; + + + 或 + + +``` + +path: string or object; + +string: Default band `x, y, rotate`; + +object: Customizable required `x, y, rotate`. + +### BezierPlugin + +```jsx +import BezierPlugin from 'rc-tween-one/lib/plugin/BezierPlugin'; +TweenOne.plugins.push(BezierPlugin); + +``` +| name | type | default | description | +| ---------- | ------- | ------ | -------------------------------------- | +| type | string | `soft` | type: `thru` `soft` `quadratic` `cubic` | +| autoRotate | boolean | false | Following rotation | +| vars | array | null | Bezier point location, such as `{ x:100, y:100}` | + +> Bezier API ref [gsap BezierPlugin](http://greensock.com/docs/#/HTML5/GSAP/Plugins/BezierPlugin/) + +### ChildrenPlugin + +```jsx +import ChildrenPlugin from 'rc-tween-one/lib/plugin/ChildrenPlugin'; +TweenOne.plugins.push(ChildrenPlugin); + +``` +| name | type | default | description | +| ----------- | ------------------------------- | ----- | -------------------------------------------- | +| value | number | null | value. | +| floatLength | number | null | The length of the float (after the decimal point). | +| formatMoney | boolean / { thousand, decimal } | false | Format the value as a money character, you can customize the punctuation in the middle of the money sign. | + +#### formatMoney = { thousand, decimal } +| name | type | default | description | +| -------- | ------ | ---- | ------------ | +| thousand | string | `,` | Hundreds of symbols. | +| decimal | string | `.` | Decimal point symbol. | + +## TweenOneGroup API + +| name | type | default | description | +| ----------- | --------------- | --------------------- | -------------------------------- | +| appear | boolean | true | Whether the element has an initial appear animation. | +| enter | object / array / func | { x: 30, opacity: 0, type: 'from' } | Enter the tween-one animation data, if the array is tween-one timeline. func reference queue-anim, callbac({key,index}) | +| leave | object / array / func | { x: 30, opacity: 0 }| Leave the tween-one animation data, same as above. | +| onEnd | func | - | Callback after each animation ends. | +| animatingClassName | array | `['tween-one-entering', 'tween-one-leaving']` | The style of entering and leaving, if it is a component form, you need to bring the className to your component. | +| resetStyle | boolean | true | TweenOne's `resetStyle`, resets the initial style when switching animations. | +| exclusive | boolean | false | Whether to allow new animations to be executed immediately upon switching. `enter => leave`: execute leaving animation immediately. | +| component | React.Element/String | div | - | diff --git a/components/tween-one/index.md b/components/tween-one/index.zh-CN.md similarity index 93% rename from components/tween-one/index.md rename to components/tween-one/index.zh-CN.md index efcd9908..5445c945 100644 --- a/components/tween-one/index.md +++ b/components/tween-one/index.zh-CN.md @@ -1,14 +1,20 @@ --- -chinese: 单元素动画 order: 0 -english: TweenOne +title: + zh-CN: 单元素动画 + en-US: TweenOne + --- -这是个对单个元素标签做动效的组件,可以执行所有样式动画,包括 transform3d,模糊等效果,还可以完成贝塞尔曲线动画,具体参数请参见 [API](/api/tween-one) +这是个对单个元素标签做动效的组件,可以执行所有样式和标签上的属性动画,包括 transform3d,模糊等效果,还可以完成贝塞尔曲线动画,具体参数请参见 [API](/api/tween-one) ## 何时使用 -- 在单个元素需要过渡到另外一点时使用 +- 元素在样式发生变化时。 +- 元素在某个时间段完成不同的时间轴动画时。 +- 数字发生变化时。 +- SVG 线性生长或形变时。 +- 元素需要在指定的路径引导上动画时。 --- @@ -57,6 +63,8 @@ React.render( > 基本动画参数请查看[动画术语](/language/animate-term); +**不能同时使用 reverse 和 repeat:-1。** + | 参数 | 类型 | 默认 | 说明 | | ----------- | ------------------ | --------------- | ---------------------------------------------- | | type | string | `to` | 播放类型,`to` 为正常播放, `from` 反向播放, `set` 相同于 duration 等于 0, 直接到值. | @@ -74,7 +82,7 @@ React.render( - 插件参数参考下面插件的写法。 如 bezier, SVGDraw, path, Children 等。 -> `animation` 等于 `array` 时为时间轴动画 +> `animation` 等于 `array` 时为时间轴动画,ref: `animation={[{ x: 10 }, { y: 10 }]}`; ### TweenOne.easing.path diff --git a/exhibition/demo/carousel3d.md b/exhibition/demo/carousel3d.md index 39206884..ad865a82 100644 --- a/exhibition/demo/carousel3d.md +++ b/exhibition/demo/carousel3d.md @@ -1,18 +1,26 @@ --- order: 7 -chinese: 卡片旋转 -english: carousel +title: + zh-CN: 卡片旋转 + en-US: Carousel +content: + zh-CN: Carousel 3d 卡片的旋转效果。 + en-US: Rotation effect of carousel 3D card. image: https://gw.alipayobjects.com/zos/rmsportal/HOmyKwEoPKktzFyEsKOG.jpg --- -carousel 3d 卡片的旋转效果。 - ---- +## zh-CN 支付宝客户端里的小钱袋产品的心愿卡片菜单,手机上的一种卡片的收纳方式。 > 模糊比较耗性能,手机上不建议开启。 +## en-US + +A way of displaying a card on the wireless side. + +> mobile is not recommended to open blur. + ```jsx import PropTypes from 'prop-types'; diff --git a/exhibition/demo/detail-switch.md b/exhibition/demo/detail-switch.md index 4683117a..b57ac6a7 100644 --- a/exhibition/demo/detail-switch.md +++ b/exhibition/demo/detail-switch.md @@ -1,16 +1,22 @@ --- order: 2 -chinese: 详细说明切换 -english: detailSwitch +title: + zh-CN: 详细说明切换 + en-US: Detail Switch +content: + zh-CN: 页面里的详细说明间的走马灯切换效果。 + en-US: The effect of street light switching between the detailed instructions on the page. image: https://zos.alipayobjects.com/rmsportal/cvLbMZkjkNvqbVF.png --- -页面里的详细说明间的走马灯切换效果。 - ---- +## zh-CN 图片动画效果参考于 [dribbble](https://dribbble.com/shots/2595631-Wine-catalog-browsing-animation-design); +## en-US + +Picture animation effect ref [dribbble](https://dribbble.com/shots/2595631-Wine-catalog-browsing-animation-design); + ```jsx import BannerAnim from 'rc-banner-anim'; import QueueAnim from 'rc-queue-anim'; diff --git a/exhibition/demo/list-anim.md b/exhibition/demo/list-anim.md index 16375365..cb46d080 100644 --- a/exhibition/demo/list-anim.md +++ b/exhibition/demo/list-anim.md @@ -1,17 +1,25 @@ --- order: 3 -chinese: 列表动画 -english: ListAnim +title: + zh-CN: 列表动画 + en-US: List Animate +content: + zh-CN: 在页面里,当我们想对区块内容进行动画时,需要解决元素的先后顺序与基本动画的属性。 + en-US: In the page, when we want to animate block content, we need to solve the sequence of elements and the attributes of basic animation. image: https://zos.alipayobjects.com/rmsportal/ivfCWzEWHsTPWMW.png --- +## zh-CN +出场请拖动上面的列表往左,出现删除按扭后点击删除。 -在页面里,当我们想对区块内容进行动画时,需要解决元素的先后顺序与基本动画的属性。 +拖动的动画效果以 CSS(rc-animate) 实现的在文件包里,[查看 Demo](https://github.com/ant-design/ant-motion/tree/master/exhibition/js/); ---- +## en-US + +please drag the list above to the left, and click the delete button. + +Drag animation effects in CSS (rc-animate) in the file package,[Demo](https://github.com/ant-design/ant-motion/tree/master/exhibition/js/); -出场请拖动上面的列表往左,出现删除按扭后点击删除。 -拖动的动画效果以 CSS(rc-animate) 实现的在文件包里,[查看 Demo](https://github.com/ant-design/ant-motion/tree/master/exhibition/js/); ````jsx import QueueAnim from 'rc-queue-anim'; diff --git a/exhibition/demo/list-sort.md b/exhibition/demo/list-sort.md index 5f692c20..a6413c85 100644 --- a/exhibition/demo/list-sort.md +++ b/exhibition/demo/list-sort.md @@ -1,20 +1,24 @@ --- order: 1 -chinese: 列表交换位置 -english: ListSort +title: + zh-CN: 列表交换位置 + en-US: List Sort +content: + zh-CN: 页面里的 List 拖动来重新排列顺序。 + en-US: Drag the List on the page to rearrange the order. image: https://zos.alipayobjects.com/rmsportal/BgYxbsXLrUfkkRT.png --- +## zh-CN +ListSort 组件地址: [地址](https://github.com/ant-design/ant-motion/blob/master/src/edit/template/components/ListSort.jsx) -页面里的 List 拖动来重新排列顺序。 - ---- +## en-US -ListSort 组件地址: [地址](https://github.com/ant-design/ant-motion/blob/master/src/edit/template/components/ListSort.jsx) +ListSort: [Component URL](https://github.com/ant-design/ant-motion/blob/master/src/edit/template/components/ListSort.jsx) ```jsx import Icon from 'antd/lib/icon'; import PropTypes from 'prop-types'; -import ListSort from '../../src/edit/template/components/ListSort'; +import ListSort from '../../site/theme/template/other/ListSort'; const dataArray = [ { diff --git a/exhibition/demo/logo-gather-anim.md b/exhibition/demo/logo-gather-anim.md index e55fbba8..16bb9e46 100644 --- a/exhibition/demo/logo-gather-anim.md +++ b/exhibition/demo/logo-gather-anim.md @@ -1,19 +1,27 @@ --- order: 5 -chinese: logo 聚集与散开 -english: logoGather +title: + zh-CN: Logo 聚集与散开 + en-US: Logo Gather +content: + zh-CN: 以圆点散开与聚集来展示 logo 的一个小动画。 + en-US: Show a little logo animation by scattering and gathering dots. image: https://zos.alipayobjects.com/rmsportal/YsRZqQwpiAVgWrX.png --- +## zh-CN +首页 logo 动画的实现代码, 提供三个logo的样式, 还可自已添加 logo,如果需定制个性化的东西,请在 LogoGather 里修改。 -以圆点散开与聚集来展示 logo 的一个小动画 +图片默认尺寸为 300 * 300; ---- +图片取点像素为控制点的个数,以图片宽度除以像素点来决定点的个数, 默认为 20, 每行每列为15个取点。 -首页 logo 动画的实现代码, 提供三个logo的样式, 还可自已添加 logo,如果需定制个性化的东西,请在 LogoGather 里修改。 +## en-US -图片默认尺寸为 300 * 300; +The implementation code of the home logo animation. + +The default size of the image is 300 * 300; -图片取点像素为控制点的个数,以图片宽度除以像素点来决定点的个数, 默认为 20, 每行每排为15个取点。 +The width of the image is divided by the number of pixels to determine the number of points, default 20。 ```jsx @@ -290,7 +298,7 @@ class Edit extends React.Component { )}
    -
  • 图片:
  • +
  • Image:
  • @@ -312,7 +320,7 @@ class Edit extends React.Component { /> - 其它 + Other @@ -331,7 +339,7 @@ class Edit extends React.Component {
  • -
  • 图片取点像素:
  • +
  • 取点像素(pixel):
  • -
  • 点的宽加随机:
  • +
  • 宽加随机(width):
  • - +
- 注:图片尺寸为正方形的PNG或SVG,请确保图片开启跨域;像数点的数值越大则点越少,为流畅最小值为15 + 注:图片尺寸为正方形的PNG或SVG,请确保图片开启跨域;像数点的数值越大则点越少,为流畅最小值为15. +
+ Note: The picture size is square PNG or SVG, please make sure the image is open across domains;
diff --git a/exhibition/demo/pic-details-anim.md b/exhibition/demo/pic-details-anim.md index 24a81e62..f644b6b2 100644 --- a/exhibition/demo/pic-details-anim.md +++ b/exhibition/demo/pic-details-anim.md @@ -1,16 +1,19 @@ --- order: 0 -chinese: 图片详细切换 -english: PicDetailsAnim +title: + zh-CN: 图片详细切换 + en-US: Pic Details Animate +content: + zh-CN: 从图片缩略图到详细说明的一个过场效果。 + en-US: From a picture thumbnail to a detailed illustration of a passing effect. image: https://zos.alipayobjects.com/rmsportal/RJoNICBzRCkOsMv.png --- - -从图片缩略图到详细说明的一个过场效果。。 - ---- - +## zh-CN 图片动画效果参考于 [dribbble](https://dribbble.com/shots/1908087-Card-Interaction); +## en-US +Picture animation effect ref [dribbble](https://dribbble.com/shots/1908087-Card-Interaction); + ```jsx import QueueAnim from 'rc-queue-anim'; import PropTypes from 'prop-types'; diff --git a/exhibition/demo/snow.md b/exhibition/demo/snow.md index 3bd91d7b..e55bc965 100644 --- a/exhibition/demo/snow.md +++ b/exhibition/demo/snow.md @@ -1,17 +1,24 @@ --- order: 6 -chinese: 掉落效果 -english: snow +title: + zh-CN: 掉落效果 + en-US: Snow +content: + zh-CN: 元素从上往下掉落的一个效果。 + en-US: An effect of falling elements from top to bottom. image: https://gw.alipayobjects.com/zos/rmsportal/CdkOMmURLntHGuuqFXnj.jpg --- +## zh-CN +支付宝客户端里的小钱袋产品的金钱发生变化时的金币掉落效果,重看点刷新按钮。 -元素从上往下掉落的一个效果。 +[money.less 请查看这里](https://github.com/ant-design/ant-motion/tree/master/exhibition/js/money.less); ---- +## en-US -支付宝客户端里的小钱袋产品的金钱发生变化时的金币掉落效果,重看点刷新按钮。 +Gold coin drop effect, replay click refresh button. + +[money.less](https://github.com/ant-design/ant-motion/tree/master/exhibition/js/money.less); -[money.less 请查看这里](https://github.com/ant-design/ant-motion/tree/master/exhibition/js/money.less); ```jsx diff --git a/exhibition/demo/table-enter-leave.md b/exhibition/demo/table-enter-leave.md index 3956adb7..70bc6131 100644 --- a/exhibition/demo/table-enter-leave.md +++ b/exhibition/demo/table-enter-leave.md @@ -1,13 +1,16 @@ --- order: 4 -chinese: 表格信息增删动画 -english: TableAddAndDelete +title: + zh-CN: 表格信息增删动画 + en-US: Table Add And Delete +content: + zh-CN: 对表格里的信息进行操作后的一个动画效果。 + en-US: An animation effect after manipulating the information in the table. image: https://zos.alipayobjects.com/rmsportal/wJDizWNyyxVhULT.png --- +## zh-CN -对表格里的信息进行操作后的一个动画效果。 - ---- +> 由于 antd 表格组件调整,动画失效,后续我们会尽快解决。。 点击 Add 按钮为添加,Delete 为删除。 @@ -15,6 +18,14 @@ image: https://zos.alipayobjects.com/rmsportal/wJDizWNyyxVhULT.png 此效果为设计语言里的对象增加与对象删除的实现。[查看视频演示](/language/interact) +## en-US + +> Due to the adjustment of the antd table component, the animation fails, and we will solve it as soon as possible.. + +Since the proximity video demo requires a varying height, so this example breaks the layout of the table, if you don't want to break the layout of the table, you can remove the animation of height or view it [animate demo](http://react-component.github.io/table/examples/animation.html) + +This effect adds an implementation of object deletion to objects in the design language.[Video](/language/interact) + ```jsx import Table from 'antd/lib/table'; import Button from 'antd/lib/button'; diff --git a/language/animate-term.md b/language/animate-term.md index ac85bf55..355aa19b 100644 --- a/language/animate-term.md +++ b/language/animate-term.md @@ -1,8 +1,11 @@ --- order: 6 -chinese: 动画术语 -english: animate term -category: 动效参数 +title: + zh-CN: 动画术语 + en-US: animate term +category: + zh-CN: 动效参数 + en-US: TweenOne param --- ## 动画基本参数术语说明 diff --git a/language/basic.en-US.md b/language/basic.en-US.md new file mode 100644 index 00000000..b4ba201f --- /dev/null +++ b/language/basic.en-US.md @@ -0,0 +1,24 @@ +--- +order: 0 +title: Motion +--- + +Interface dynamics enhance user awareness and increase vitality. + +## Motion Values + +- **Increase experience comfort:** Make the user's cognitive process more natural. + +- **Increase interface vigor:** The first time to attract attention and highlight the key points. + +- **Describe the hierarchical relationship:** Reflects the hierarchical and spatial relationship between elements. + +- **Provide feedback and clear intentions:** Boost the interactive experience. + +## Meaningful animation + +To measure whether a animation makes sense, we can assess it by the following criteria: + +- **Is the existence of an animation reasonable:** Whether it has a clear purpose, boost the interactive experience, there is no extra animation. + +- **Animation and performance:** There can be no large frame loss, and the animation experience must be smooth and does not affect the performance of the product. diff --git a/language/basic.md b/language/basic.zh-CN.md similarity index 94% rename from language/basic.md rename to language/basic.zh-CN.md index a8ff01a2..47e3e75d 100644 --- a/language/basic.md +++ b/language/basic.zh-CN.md @@ -1,7 +1,8 @@ --- order: 0 -chinese: 动效 -english: Motion +title: + zh-CN: 动效 + en-US: Motion --- 界面动效能加强用户认知且增加活力。 diff --git a/language/combined.md b/language/combined.md index 9cdb020a..b937c652 100644 --- a/language/combined.md +++ b/language/combined.md @@ -1,7 +1,8 @@ --- order: 4 -chinese: 组合 -english: Combined +title: + zh-CN: 组合 + en-US: Combined --- 组合动效是将多种动画效果组合起来运用在单个元素或者界面中的表现方式,吸引用户的注意,让用户快速了解信息的主次关系。ant design 最常用的组合动效有以下三种: diff --git a/language/principle.md b/language/principle.md index 17a99c8b..b3926ca2 100644 --- a/language/principle.md +++ b/language/principle.md @@ -1,7 +1,8 @@ --- order: 1 -chinese: 原则 -english: Principle +title: + zh-CN: 原则 + en-US: Principle --- 在企业级应用的产品设计中,使用动效和前台类产品有很大的不同,助力交互行为和增强信息认知显得尤为重要,在 ant design 设计价值观的基础之上,我们衍生出动效设计的三原则: @@ -9,7 +10,7 @@ english: Principle
```__react -import Principle from '../src/theme/template/other/Principle'; +import Principle from '../site/theme/template/other/Principle'; ReactDOM.render(, mountNode); ``` diff --git a/language/space.md b/language/space.md index 6faaf779..38710140 100644 --- a/language/space.md +++ b/language/space.md @@ -1,7 +1,8 @@ --- order: 3 -chinese: 空间 -english: Space +title: + zh-CN: 空间 + en-US: Space --- 现实空间里,物体存在远小近大的原则,运动则有远慢近快。在动效设计时,处理和空间相关的话题时,我们需要考虑两方面的因素: diff --git a/language/speed.md b/language/speed.md index 4063441e..02b42956 100644 --- a/language/speed.md +++ b/language/speed.md @@ -1,7 +1,8 @@ --- order: 2 -chinese: 速度 -english: Speed +title: + zh-CN: 速度 + en-US: Speed --- 速度的快或慢取决于时间与缓动,相同的距离,时间越短速度则越快,而缓动则是能将同一段时间划分快与慢的区域。 @@ -70,7 +71,7 @@ english: Speed > 需要注意:如果在可视窗口中消失的,属于点到点之间的运动,建议使用前后缓动,同理可视窗口中出现也一样。 ```__react -import EaseExplain from '../src/theme/template/other/EaseExplain'; +import EaseExplain from '../site/theme/template/other/EaseExplain'; ReactDOM.render( 过渡是更复杂的组合动画效果,组合动画是针对当前的元素进行的一个进出场效果,而过渡往往需要多个不同的动画来完成一段多个页面中间的过渡。 diff --git a/package.json b/package.json index 3899652e..3741834a 100644 --- a/package.json +++ b/package.json @@ -1,69 +1,70 @@ { "name": "ant-motion", "version": "1.6.3", + "title": "Ant Motion", + "description": "react animation component", + "homepage": "http://motion.ant.design/", + "repository": { + "type": "git", + "url": "https://github.com/ant-design/ant-motion" + }, + "license": "MIT", "dependencies": { - "antd": "~3.6.2", - "deepcopy": "^0.6.3", - "enquire-js": "^0.1.1", - "file-saver": "^1.3.3", - "jsonml-to-react-component": "^0.2.6", - "jsonml.js": "^0.1.0", - "jszip": "^3.1.4", - "less-loader": "^4.0.5", - "prop-types": "15.5.x", - "raw-js-loader": "^1.4.0", - "raw-loader": "^0.5.1", - "rc-animate": "~2.4.4", - "rc-banner-anim": "~2.0.0", - "rc-drawer": "^1.5.0", + "rc-animate": "^2.6.0", + "rc-banner-anim": "^2.2.0", + "rc-drawer": "^1.7.0", "rc-queue-anim": "~1.6.0", "rc-scroll-anim": "~2.5.0", "rc-texty": "^0.1.0", - "rc-tween-one": "~2.2.12", + "rc-tween-one": "^2.3.0" + }, + "devDependencies": { + "antd": "^3.13.2", + "antd-tools": "^7.0.0", + "babel-eslint": "^10.0.1", + "bisheng": "^1.1.0", + "bisheng-plugin-antd": "^1.0.0", + "bisheng-plugin-description": "^0.1.4", + "bisheng-plugin-react": "^1.0.0", + "bisheng-plugin-toc": "^0.4.4", + "core-js": "^2.5.7", + "cross-env": "^5.1.1", + "enquire-js": "^0.1.1", + "eslint": "^5.4.0", + "eslint-config-airbnb": "^17.0.0", + "eslint-loader": "^2.1.1", + "eslint-plugin-babel": "^5.1.0", + "eslint-plugin-compat": "^2.6.2", + "eslint-plugin-import": "^2.14.0", + "eslint-plugin-jsx-a11y": "^6.1.2", + "eslint-plugin-markdown": "^1.0.0-beta.6", + "eslint-plugin-react": "^7.11.1", + "eslint-tinker": "^0.5.0", + "jsonml.js": "^0.1.0", + "pre-commit": "1.x", + "prop-types": "15.5.x", "react": "^16.4.0", - "react-color": "^2.13.8", - "react-copy-to-clipboard": "~5.0.0", "react-document-title": "^2.0.1", "react-dom": "^16.4.0", + "react-github-button": "^0.1.11", + "react-intl": "^2.8.0", "react-router": "~3.0.0", "react-sublime-video": "^0.2.0", - "to-style": "^1.3.3", - "tween-functions": "^1.2.0" - }, - "devDependencies": { - "babel-eslint": "^8.0.1", - "babel-plugin-import": "^1.6.2", - "babel-plugin-transform-runtime": "^6.23.0", - "bisheng": "^0.26.0", - "bisheng-plugin-antd": "^0.15.0", - "bisheng-plugin-description": "^0.1.1", - "bisheng-plugin-react": "^0.5.0", - "bisheng-plugin-toc": "^0.4.0", - "bluebird": "^3.5.0", - "concurrently": "^3.5.0", - "dora-plugin-upload": "^0.3.1", - "eslint": "^4.9.0", - "eslint-config-airbnb": "^16.1.0", - "eslint-plugin-babel": "^4.1.2", - "eslint-plugin-import": "^2.7.0", - "eslint-plugin-jsx-a11y": "^6.0.2", - "eslint-plugin-markdown": "*", - "eslint-plugin-react": "^7.4.0", - "eslint-tinker": "^0.4.0", - "pre-commit": "1.x" + "stylelint": "^9.7.1", + "stylelint-config-standard": "^18.2.0" }, "pre-commit": [ "lint" ], "scripts": { - "start": "concurrently \"bisheng start -c ./src/bisheng.index.config.js --no-livereload\" \"bisheng start -c ./src/bisheng.edit.config.js --no-livereload\" \"bisheng start -c ./src/bisheng.templates.config.js --no-livereload\"", - "site": "concurrently \"bisheng build -c ./src/bisheng.index.config.js\" \"bisheng build -c ./src/bisheng.edit.config.js\" \"bisheng build -c ./src/bisheng.templates.config.js\"", - "re-site": "rm -rf _site && mkdir -p _site", - "deploy": "npm run re-site && npm run site && bisheng gh-pages --push-only", - "lint": "eslint ./src ./exhibition --ext '.js,.jsx'", - "demolint": "RUN_ENV=DEMO eslint components/*/demo/*.md --ext '.md'", - "eslint-fix": "eslint --fix ./src ./exhibition --ext '.js,.jsx'", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "theme": "./theme.js" + "start": "rm -rf _site && cross-env NODE_ENV=development bisheng start -c ./site/bisheng.config.js", + "build": "rm -rf _site && cross-env NODE_ENV=production bisheng build -c ./site/bisheng.config.js", + "site": "npm run build", + "deploy": "npm run site && bisheng gh-pages --push-only", + "lint": "npm run lint:es && npm run lint:style", + "lint:es": "eslint --fix --ext '.js,.jsx' site", + "lint:style": "stylelint --fix \"site/**/*.less\" --syntax less", + "lint:demo": "cross-env RUN_ENV=DEMO eslint ./ --ext '.md' -c ./.eslintrc.js", + "test": "npm run lint" + } } diff --git a/site/bisheng.config.js b/site/bisheng.config.js new file mode 100644 index 00000000..08c8b942 --- /dev/null +++ b/site/bisheng.config.js @@ -0,0 +1,86 @@ + +const path = require('path'); +const replaceLib = require('antd-tools/lib/replaceLib'); + +const isDev = process.env.NODE_ENV === 'development'; + +const antdImport = ['import', { libraryName: 'antd', style: true }]; + +function alertBabelConfig(rules) { + rules.forEach((rule) => { + if (rule.loader && rule.loader.indexOf('babel-loader') >= 0) { + if (rule.options.plugins.indexOf(replaceLib) === -1) { + rule.options.plugins.push(replaceLib); + } + if (rule.options.plugins.indexOf(antdImport) === -1) { + rule.options.plugins.push(antdImport); + } + /* rule.options.plugins = rule.options.plugins.filter(plugin => + !plugin.indexOf || plugin.indexOf('babel-plugin-add-module-exports') === -1 + ); */ + } else if (rule.use) { + alertBabelConfig(rule.use); + } + }); +} + +module.exports = { + source: { + language: './language', + components: './components', + exhibition: './exhibition', + }, + theme: './site/theme', + themeConfig: { + root: '/', + language: { + 动效: 0, + Motion: 0, + }, + }, + htmlTemplate: './site/theme/static/index.html', + port: 8111, + filePathMapper(filePath) { + if (filePath === '/index.html') { + return ['/index.html', '/index-cn.html']; + } + if (filePath.endsWith('/index.html')) { + return [filePath, filePath.replace(/\/index\.html$/, '-cn/index.html')]; + } + if (filePath !== '/404.html' && filePath !== '/index-cn.html') { + return [filePath, filePath.replace(/\.html$/, '-cn.html')]; + } + return filePath; + }, + doraConfig: { + verbose: true, + }, + lessConfig: { + javascriptEnabled: true, + }, + webpackConfig(config) { + config.resolve.alias = { + site: path.join(process.cwd(), 'site'), + 'react-router': 'react-router/umd/ReactRouter', + }; + + // eslint-disable-next-line + config.externals = { + 'react-router-dom': 'ReactRouterDOM', + }; + if (isDev) { + // eslint-disable-next-line + config.devtool = 'source-map'; + } + alertBabelConfig(config.module.rules); + return config; + }, + devServerConfig: { + public: process.env.DEV_HOST || 'localhost', + disableHostCheck: !!process.env.DEV_HOST, + }, + + htmlTemplateExtraData: { + isDev, + }, +}; diff --git a/site/theme/en-US.js b/site/theme/en-US.js new file mode 100644 index 00000000..ce3f9ee9 --- /dev/null +++ b/site/theme/en-US.js @@ -0,0 +1,53 @@ +const appLocaleData = require('react-intl/locale-data/zh'); + +module.exports = { + locale: 'en-US', + data: appLocaleData, + messages: { + 'app.header.menu.exhibition': 'Exhibition', + 'app.header.menu.language': 'Language', + 'app.header.menu.components': 'Components', + 'app.header.menu.templates': 'Templates', + 'app.header.lang': '中文', + 'app.home.introduce': 'Use Ant Motion to quickly use animations in the React framework.', + 'app.home.introduce2': 'We offer single, combined and complete animations solutions.', + 'app.home.learn-more': 'Learn More', + 'app.home.enter-editor': 'Enter Editor', + 'app.home.page1.title': 'Animation easier', + 'app.home.page1.content': 'In the React framework, you only need a simple piece of code to achieve animation effects, \nwhich can improve your work efficiency.', + 'app.home.page2.content': 'With Ant Motion, you can quickly achieve animation effects.\n With different interaction modes, you can apply directly to your project.', + 'app.home.page2.learn-more': 'More', + 'app.home.page3.title': 'Add interesting animatiion to your product', + 'app.home.page3.content': 'With more friendly interaction, let the animate shuttle between different elements,\n so that the product can better talk to the user.', + 'app.home.page3.button': 'Quick Start', + 'app.details.code': 'Code Snippet', + 'app.content.edit-page': 'Edit this page on GitHub!', + 'app.content.components-exp': 'Example', + 'app.footer.repo': 'GitHub', + 'app.footer.template': 'Template GitHub', + 'app.footer.chinamirror': 'China Mirror 🇨🇳', + 'app.footer.scaffolds': 'Scaffold Market', + 'app.footer.links': 'Sites', + 'app.footer.data-vis': 'Data Visualization', + 'app.footer.eggjs': 'Enterprise Node Framework', + 'app.footer.landing': 'Landing Templates', + 'app.footer.kitchen': 'Sketch Toolkit', + 'app.footer.umi': 'React Application Framework', + 'app.footer.dva': 'Data Flow Framework', + 'app.footer.antd-library': 'Axure library', + 'app.footer.design-platform': 'Ant Financial Design Platform', + 'app.footer.antux': 'Sitemap Template', + 'app.footer.community': 'Community', + 'app.footer.issues': 'Issues', + 'app.footer.work-with-us': 'Work with Us', + 'app.footer.author': 'Created by AFX', + 'app.footer.resources': 'Resources', + 'app.footer.more-product': 'More Products', + 'app.footer.yuque': 'YuQue', + 'app.footer.yuque.slogan': 'Write your document as a team', + 'app.footer.fengdie': 'FengDie', + 'app.footer.fengdie.slogan': 'Mobile web app builder', + 'app.footer.seeconf': 'Seeking Experience & Engineering Conference', + 'app.footer.xcloud': 'Ant Experience Cloud', + }, +}; diff --git a/site/theme/index.js b/site/theme/index.js new file mode 100644 index 00000000..ae9558ca --- /dev/null +++ b/site/theme/index.js @@ -0,0 +1,81 @@ +const Article = './template/Content/Article'; +const ComponentDoc = './template/Content/ComponentDoc'; +const Exhibition = './template/Exhibition/index'; +const Details = './template/Exhibition/Details'; +const path = require('path'); + +const homeTmpl = './template/Home/index'; +// const contentTmpl = './template/Content/index'; + +function pickerGenerator(module = 'language/') { + const tester = new RegExp(`^${module}`); + return (markdownData) => { + const { filename } = markdownData.meta; + if (tester.test(filename) && !/\/demo$/.test(path.dirname(filename))) { + return { + meta: markdownData.meta, + }; + } + return null; + }; +} + +module.exports = { + lazyLoad(nodePath, nodeValue) { + if (typeof nodeValue === 'string') { + return true; + } + return nodePath.endsWith('/demo'); + }, + pick: { + language: pickerGenerator(), + components: pickerGenerator('components'), + api: pickerGenerator('components'), + }, + plugins: [ + 'bisheng-plugin-description', + 'bisheng-plugin-toc?maxDepth=2&keepElem', + 'bisheng-plugin-antd', + 'bisheng-plugin-react?lang=__react', + ], + routes: { + path: '/', + component: './template/Layout/index', + indexRoute: { component: homeTmpl }, + childRoutes: [ + { + path: 'index-cn', + component: homeTmpl, + }, + { + path: '/exhibition/', + component: Exhibition, + }, + { + path: '/exhibition-cn/', + component: Exhibition, + }, + { + path: '/exhibition/demo/:children', + component: Details, + }, + { path: '/language/:children', component: Article }, + { + path: '/components/:children', + component: ComponentDoc, + }, + { path: '/api/:children', component: Article }, + /* { path: '/exhibition/', component: Exhibition }, + { path: '/exhibition/demo/:contentName', component: Details }, + { path: '/getting/:contentName', component: Article }, + { path: '/components/:contentName', component: ComponentDoc }, + { path: '/language/:contentName', component: Article }, + { path: '/api/tween-one', component: Article }, + { path: '/api/animate', component: Article }, + { path: '/api/queue-anim', component: Article }, + { path: '/api/scroll-anim', component: Article }, + { path: '/api/banner-anim', component: Article }, + { path: '/api/texty', component: Article }, */ + ], + }, +}; diff --git a/site/theme/static/common.less b/site/theme/static/common.less new file mode 100644 index 00000000..61b3700d --- /dev/null +++ b/site/theme/static/common.less @@ -0,0 +1,330 @@ +@import 'custom'; +@import 'global'; +html, +body { + background: #fff; +} + +@header: header; +.@{header}-wrapper { + height: 64px; + position: relative; + z-index: 10000; + background: @nav-color; + width: 100%; + transition: background .3s @ease-out, border @animate-duration @ease-out; + .@{header} { + width: 100%; + padding: 0 24px; + max-width: 1200px; + margin: auto; + position: relative; + transition: transform @animate-duration @ease-out; + &-logo { + display: inline-block; + margin: 17px 0; + height: 30px; + position: relative; + z-index: 1000; + & img { + vertical-align: middle; + display: inline-block; + &:last-child { + margin-left: 15px; + } + } + & a { + display: block; // transition: filter .4s; + } + } + .web-nav { + // float: right; + line-height: 64px; + position: absolute; + right: 24px; + top: 0; + height: 64px; + & ul { + display: inline-block; + overflow: hidden; + position: relative; + & li { + float: left; + margin-left: 48px; + transition: margin .3s; + } + } + a { + height: 100%; + } + .git-btn-li { + margin-left: 12px; + min-width: 120px; + } + .lang-btn { + display: flex; + align-items: center; + height: 64px; + margin-right: 12px; + position: relative; + button { + border-color: @nav-link-color; + &:hover, + &.active { + border-color: @nav-link-active-color; + } + &[disabled] { + border-color: @nav-link-active-color; + } + } + &:before { + content: ''; + display: block; + position: absolute; + top: 0; + bottom: 0; + margin: auto; + height: 16px; + width: 1px; + background: @nav-link-color; + transition: background @animate-duration @ease-out; + opacity: 0.75; + left: -24px; + } + } + a, + button { + width: 100%; + font-size: 14px; + display: block; + color: @nav-link-color; + letter-spacing: 0.5px; + transition: color @animate-duration @ease-out, border-color @animate-duration @ease-out; + text-decoration: none; + &:hover, + &.active { + color: @nav-link-active-color; + } + &[disabled] { + color: @nav-link-active-color; + } + } + } + .phone-nav { + display: none; + } + .git-btn { + + display: inline-block; + vertical-align: middle; + .github-btn { + display: block; + height: 24px; + } + .gh-btn, + .gh-count { + width: auto; + font-family: "PingFang SC", "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", "\5FAE\8F6F\96C5\9ED1", Arial, sans-serif; + font-weight: normal; + background: transparent; + padding: 0 7px; + height: 100%; + line-height: 24px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 4px; + color: @nav-link-color; + border-color: @nav-link-color; + transition: color @animate-duration @ease-out, border-color @animate-duration @ease-out; + &:hover { + color: @nav-link-active-color; + border-color: @nav-link-active-color; + .gh-ico { + opacity: 1; + } + } + .gh-text { + font-size: 14px; + font-weight: normal; + } + .gh-ico { + filter: brightness(5); + opacity: 0.5; + transition: opacity @animate-duration @ease-out; + } + } + .gh-count { + margin-left: 6px; + &:after { + left: -5px; + border-right-color: @nav-link-color; + transition: border-right-color @animate-duration @ease-out; + } + &:before { + display: none; + } + &:hover { + &:after { + border-right-color: @nav-link-active-color; + } + } + } + } + } +} + +.home { + .@{header}-wrapper { + background: transparent; + border-color: transparent; + .@{header} { + transform: translateY(50%); + &-logo { + .logo-img { + filter: grayscale(1) brightness(3); + } + } + .web-nav { + a, + .lang-btn button { + color: #fff; + border-color: #fff; + } + .lang-btn:before { + background: @nav-link-active-color; + } + } + .git-btn { + .gh-btn, + .gh-count { + color: #fff; + border-color: #fff; + &:after { + border-right-color: @nav-link-active-color; + } + .gh-ico { + opacity: 1; + } + } + } + } + } + & .content-wrapper { + background: transparent; + } + /* .@{footer} { + background: @nav-color; + border-top-color: transparent; + & h2 { + color: #999 + } + } */ +} + +.content-wrapper { + background-color: #fff; +} + +.content-wrapper >.tween-one-leaving, +.page-content >.tween-one-leaving { + position: absolute !important; + width: 100%; +} + +/* .content-wrapper>.tween-one-leaving, +.page-content>.tween-one-leaving, +.content-wrapper>.tween-one-entering, +.page-content>.tween-one-entering { + overflow: hidden; + height: 100vh; +} */ + +.home .queue-anim-leaving { + position: relative !important; + width: auto; +} + +.video { + max-width: 800px; + width: 100%; +} + +.video-min, +.video-min-m { + max-width: 390px; + width: 100%; + display: inline-block; +} + +.video-min-m { + max-width: 195px; +} + +.video-margin-left { + margin-left: 20px; +} + +.preview-image-title { + text-align: center; + line-height: 48px; +} + +// 修改弹出框动画 +.ant-modal.zoom-appear, +.ant-modal.zoom-enter, +.ant-modal.zoom-leave { + animation-duration: .35s; +} + +@keyframes antZoomIn { + 0% { + opacity: 0; + transform: scale(0.3); + } + 100% { + opacity: 1; + transform: scale(1); + } +} + +@keyframes antZoomOut { + 0% { + transform: scale(1); + } + 100% { + opacity: 0; + transform: scale(0.3); + } +} + +.templates-wrapper { + display: inline; + overflow: unset; + user-select: none; +} + +.replay-button { + width: 32px; + height: 32px; + background: #fff; + border-radius: 100%; + box-shadow: 0 5px 20px fade(#000, 15); + position: absolute; + bottom: 20px; + right: 20px; + transition: transform .45s @ease-out, box-shadow .45s @ease-out; + cursor: pointer; + & i { + background: url("https://zos.alipayobjects.com/rmsportal/XInKafGVjnFqZcM.svg") no-repeat center; + width: 20px; + height: 20px; + display: block; + margin: 6px auto; + } + &:active, + &:visited { + transform: translateY(2px); + box-shadow: 0 3px 15px fade(#000, 15); + } +} diff --git a/src/theme/static/custom.less b/site/theme/static/custom.less similarity index 87% rename from src/theme/static/custom.less rename to site/theme/static/custom.less index a7e5f845..3232d8cc 100644 --- a/src/theme/static/custom.less +++ b/site/theme/static/custom.less @@ -13,10 +13,13 @@ @footer-bg-color: @bar-color; @footer-link-color: #8A8A8A; -@link-color : @primary-color; -@link-hover-color : tint(@link-color, 20%); -@link-active-color : shade(@link-color, 5%); -@link-hover-decoration : none; +@link-color: @primary-color; + +@link-hover-color: tint(@link-color, 20%); + +@link-active-color: shade(@link-color, 5%); + +@link-hover-decoration: none; @line-color: #E8E8E8; @line-deep-color: #979797; @@ -60,7 +63,7 @@ .page-pro() { border-radius: 6px; border: 1px solid @line-color; - transform: translateY(0px); + transform: translateY(0); position: relative; will-change: transform, box-shadow; transition: transform .3s @ease-out, box-shadow .3s @ease-out; @@ -69,5 +72,3 @@ transform: translateY(-4px); } } - - diff --git a/src/theme/static/demo.less b/site/theme/static/demo.less similarity index 97% rename from src/theme/static/demo.less rename to site/theme/static/demo.less index a2c043c9..995bdf4f 100644 --- a/src/theme/static/demo.less +++ b/site/theme/static/demo.less @@ -37,7 +37,7 @@ .demo-bezier-shape { width: 5px; height: 5px; - background: #7569FF; + background: #7569ff; position: absolute; top: 0; } @@ -137,7 +137,7 @@ & .logo { display: inline-block; margin-left: 10px; - & img:nth-child(2){ + & img:nth-child(2) { margin-left: 5px; } } @@ -146,14 +146,14 @@ & li { width: 50px; height: 8px; - background: #4D5C76; + background: #4d5c76; display: inline-block; margin-right: 10px; } } } .demo-banner { - background: #364D79; + background: #364d79; height: 87px; position: relative; & .point { @@ -226,7 +226,6 @@ right: 0; bottom: 0; margin: auto; - } &:nth-child(2):before { transform: rotate(45deg); @@ -247,14 +246,14 @@ &:before, &:after { content: ""; display: block; - background: #4D5C76; + background: #4d5c76; height: 4px; margin: 8px auto; } - &:before{ + &:before { width: 180px; } - &:after{ + &:after { width: 50px; } } diff --git a/src/theme/static/demolayout.less b/site/theme/static/demolayout.less similarity index 99% rename from src/theme/static/demolayout.less rename to site/theme/static/demolayout.less index bbaa0d0a..dc541d33 100644 --- a/src/theme/static/demolayout.less +++ b/site/theme/static/demolayout.less @@ -65,7 +65,6 @@ line-height: 20px; cursor: pointer; } - } &.vertical { .@{code} { diff --git a/src/theme/static/exhibition.less b/site/theme/static/exhibition.less similarity index 99% rename from src/theme/static/exhibition.less rename to site/theme/static/exhibition.less index 6f2df220..dd1302d6 100644 --- a/src/theme/static/exhibition.less +++ b/site/theme/static/exhibition.less @@ -45,4 +45,3 @@ margin: 1em 0 .6em 0; } } - diff --git a/src/theme/static/footer.less b/site/theme/static/footer.less similarity index 96% rename from src/theme/static/footer.less rename to site/theme/static/footer.less index d0350657..5d48ac5e 100644 --- a/src/theme/static/footer.less +++ b/site/theme/static/footer.less @@ -10,7 +10,7 @@ footer.dark { } h2 { color: rgba(255, 255, 255, 1); - &>span { + & >span { color: rgba(255, 255, 255, 1); } } @@ -69,7 +69,7 @@ footer { margin: 0; line-height: 32px; overflow: hidden; - font-family: Avenir, @font-family; + font-family: "Avenir", @font-family, sans-serif; font-size: 16px; a { color: rgba(255, 255, 255, 0.65); diff --git a/src/theme/static/global.less b/site/theme/static/global.less similarity index 97% rename from src/theme/static/global.less rename to site/theme/static/global.less index 27cd7f3f..3228a246 100644 --- a/src/theme/static/global.less +++ b/site/theme/static/global.less @@ -25,7 +25,7 @@ a { } h1, h2, h3, h4 { - color: @title-color + color: @title-color; } #react-content { diff --git a/src/theme/static/highlight.less b/site/theme/static/highlight.less similarity index 95% rename from src/theme/static/highlight.less rename to site/theme/static/highlight.less index 3a3e1826..66de1257 100644 --- a/src/theme/static/highlight.less +++ b/site/theme/static/highlight.less @@ -7,7 +7,7 @@ pre code { display: block; background: white; - color: #8A8A8A; + color: #8a8a8a; line-height: 1.7; padding: 10px 15px; border-radius: 6px; @@ -103,7 +103,7 @@ pre[class*="language-"] { .token.constant, .token.symbol, .token.deleted { - color: #FF4848; + color: #ff4848; } .token.selector, @@ -112,7 +112,7 @@ pre[class*="language-"] { .token.char, .token.builtin, .token.inserted { - color: #6FCAA7; + color: #6fcaa7; } .token.operator, @@ -120,18 +120,18 @@ pre[class*="language-"] { .token.url, .language-css .token.string, .style .token.string { - color: #DAA232; + color: #daa232; background: hsla(0, 0%, 100%, .5); } .token.atrule, .token.attr-value, .token.keyword { - color: #00ADF3; + color: #00adf3; } .token.function { - color: #F06351; + color: #f06351; } .token.regex, diff --git a/src/theme/static/home.less b/site/theme/static/home.less similarity index 95% rename from src/theme/static/home.less rename to site/theme/static/home.less index 11ce9d51..86892c4a 100644 --- a/src/theme/static/home.less +++ b/site/theme/static/home.less @@ -10,6 +10,7 @@ } & p { font-weight: lighter; + white-space: pre-line; } .nav-wrapper { position: fixed; @@ -66,7 +67,7 @@ } & h1, & h3 { font-weight: lighter; - color: @text-color-light + color: @text-color-light; } & p { margin: 16px 0 40px; @@ -101,7 +102,7 @@ &:hover { background: fade(@text-color-light, 15); - box-shadow: 0 0px 6px fade(@text-color-light, 35); + box-shadow: 0 0 6px fade(@text-color-light, 35); } &.template { margin-left: 10px; @@ -202,7 +203,7 @@ left: 0; right: 0; height: 55%; - box-shadow: 0 5px 20px fade(#B9B9B9, 50); + box-shadow: 0 5px 20px fade(#b9b9b9, 50); .code { height: 100%; position: relative; @@ -221,16 +222,16 @@ border: 1px solid; margin-left: 10px; &:first-child { - background: #FF6158; - border-color: #D94940; + background: #ff6158; + border-color: #d94940; } &:nth-child(2) { - background: #FFBD2E; - border-color: #D69E23; + background: #ffbd2e; + border-color: #d69e23; } &:last-child { - background: #29CB41; - border-color: #1DAD2C; + background: #29cb41; + border-color: #1dad2c; } } } @@ -293,7 +294,7 @@ .page2 { height: 1200px; position: relative; - .page{ + .page { height: 100%; } .home-anim-demo { @@ -341,7 +342,7 @@ } } } - .home-button{ + .home-button { position: absolute; width: 106px; margin: auto; @@ -364,5 +365,4 @@ margin-top: 30px; } } - } diff --git a/site/theme/static/index.html b/site/theme/static/index.html new file mode 100644 index 00000000..2790b6df --- /dev/null +++ b/site/theme/static/index.html @@ -0,0 +1,230 @@ + + + + + + + + + + + Ant Motion - Ant Design 的动效规范与组件 + + + + + + + + + + + +
+
+ + + + + + + + + +
    +
+ + + + + + + + + \ No newline at end of file diff --git a/src/theme/static/logo-demo.less b/site/theme/static/logo-demo.less similarity index 100% rename from src/theme/static/logo-demo.less rename to site/theme/static/logo-demo.less diff --git a/src/theme/static/markdown.less b/site/theme/static/markdown.less similarity index 93% rename from src/theme/static/markdown.less rename to site/theme/static/markdown.less index bbb537a2..1988c615 100644 --- a/src/theme/static/markdown.less +++ b/site/theme/static/markdown.less @@ -5,6 +5,10 @@ section.markdown { } .markdown section, .markdown { + .github-btn { + display: inline-block; + margin-left: 8px; + } .text-center { text-align: center; } @@ -14,8 +18,8 @@ section.markdown { & .toc { font-size: 14px; margin: 20px 0; - background: #F6F7F8; - border-left: 1px solid #E8E8E8; + background: #f6f7f8; + border-left: 1px solid #e8e8e8; padding: 8px 0 8px 10px; & a { color: @text-color; @@ -43,7 +47,7 @@ section.markdown { margin: 0 auto 10px; & > .subtitle, & > i { font-style: normal; - margin: 0 5px; + margin-left: 8px; font-size: 20px; } } @@ -76,7 +80,7 @@ section.markdown { border-radius: 3px; font-size: .8rem; border: 1px solid #e9e9e9; - background: #F7F7F7; + background: #f7f7f7; } & pre { margin: 1em 0; @@ -206,17 +210,17 @@ section.markdown { border-collapse: collapse; border-spacing: 0; empty-cells: show; - border: 1px solid #E8E8E8; + border: 1px solid #e8e8e8; width: 100%; margin-bottom: 24px; & th { - background: rgba(0,0,0,.02); + background: rgba(0, 0, 0, .02); white-space: nowrap; - color: #5C6B77; + color: #5c6b77; font-weight: 600; } & th, & td { - border: 1px solid #E8E8E8; + border: 1px solid #e8e8e8; padding: 8px 16px; text-align: left; } @@ -283,7 +287,6 @@ section.markdown { td:first-child { font-weight: 500; color: @blue-9; - } td:nth-child(2) { font-size: @font-size-base - 1px; @@ -313,12 +316,12 @@ section.markdown { display: none; } > tbody { - border-bottom: 3px solid #E8E8E8; + border-bottom: 3px solid #e8e8e8; tr { - border-top: 3px solid #E8E8E8; + border-top: 3px solid #e8e8e8; td { border: none; - border-bottom: 1px solid #E8E8E8; + border-bottom: 1px solid #e8e8e8; display: block; &:before { display: inline-block; @@ -346,4 +349,3 @@ section.markdown { } } } - diff --git a/src/theme/static/page.less b/site/theme/static/page.less similarity index 98% rename from src/theme/static/page.less rename to site/theme/static/page.less index 8a59572c..b8b8ff40 100644 --- a/src/theme/static/page.less +++ b/site/theme/static/page.less @@ -10,7 +10,7 @@ position: relative; .@{contentPage}-nav { background: #fff; - box-shadow: 0 1px 0 #EEE; + box-shadow: 0 1px 0 #eee; overflow: hidden; height: 80px; position: relative; @@ -138,4 +138,4 @@ height: 32px; } } -} \ No newline at end of file +} diff --git a/src/theme/static/responsive.less b/site/theme/static/responsive.less similarity index 96% rename from src/theme/static/responsive.less rename to site/theme/static/responsive.less index 4f389bfa..6d4574e1 100644 --- a/src/theme/static/responsive.less +++ b/site/theme/static/responsive.less @@ -1,4 +1,5 @@ @import './custom'; + @media only screen and (max-width: 767.99px) { .home .header-wrapper .header { transform: none; @@ -13,13 +14,10 @@ .web-nav { display: none; } - .git-but { + .git-btn { margin: 0 0 0 10px; - float: none; position: relative; - right: auto; display: inline-block; - transform: translateY(8px); } .phone-nav { width: 16px; @@ -39,7 +37,7 @@ display: block; width: 100%; height: 2px; - background: #FFF; + background: #fff; margin-top: 4px; } :first-child { @@ -63,7 +61,7 @@ ul { li { margin: 40px 0 40px 5%; - :only-child { + > :only-child { margin-left: 37px; } &.queue-anim-leaving { @@ -117,7 +115,7 @@ .list-bg { width: 100%; height: 100%; - background: fade(#000000, 30); + background: fade(#000, 30); position: fixed; top: 0; z-index: 1001; @@ -189,7 +187,7 @@ text-align: center; margin-bottom: 16px; } - >div>span { + >div >span { display: block; &:nth-child(1), &:nth-child(2) { @@ -198,7 +196,8 @@ } } } - .video-min, .video-min-m { + .video-min, + .video-min-m { width: 100%; max-width: none; margin: 0 auto; @@ -354,4 +353,4 @@ } } } -} \ No newline at end of file +} diff --git a/src/theme/static/splicing.less b/site/theme/static/splicing.less similarity index 99% rename from src/theme/static/splicing.less rename to site/theme/static/splicing.less index 8c97a19c..755507c4 100644 --- a/src/theme/static/splicing.less +++ b/site/theme/static/splicing.less @@ -59,7 +59,7 @@ padding: 0 10px; line-height: 150px; text-align: center; - font-size: 0px; + font-size: 0; position: relative; overflow: hidden; background: #fff; diff --git a/src/theme/static/style.js b/site/theme/static/style.js similarity index 91% rename from src/theme/static/style.js rename to site/theme/static/style.js index 03f88905..63abf905 100644 --- a/src/theme/static/style.js +++ b/site/theme/static/style.js @@ -3,6 +3,7 @@ import 'antd/lib/table/style'; import 'antd/lib/input/style'; import 'antd/lib/input-number/style'; import 'rc-drawer/assets/index.css'; +import 'react-github-button/assets/style.css'; import './global.less'; import './common.less'; import './highlight.less'; diff --git a/site/theme/template/Content/Article.jsx b/site/theme/template/Content/Article.jsx new file mode 100644 index 00000000..ddeae009 --- /dev/null +++ b/site/theme/template/Content/Article.jsx @@ -0,0 +1,77 @@ +import React from 'react'; +import { getChildren } from 'jsonml.js/lib/utils'; +import DocumentTitle from 'react-document-title'; +import { Alert } from 'antd'; +import * as utils from '../utils'; + +class Article extends React.PureComponent { + render() { + const { ...props } = this.props; + const { locale } = props.intl; + const pageData = props.pageData; + if (!pageData) { + return ( +
+

你要找的页面不存在!!!

+ 返回首页 +
+ ); + } + const { + meta, content, toc, api, + } = pageData; + const { + title, subtitle, + } = meta; + const tocItem = props.utils.toReactComponent(toc); + const tocChildren = utils.toArrayChildren(tocItem.props.children).map((item) => { + const itemChildren = utils.toArrayChildren(item.props.children).map(cItem => React.cloneElement(cItem, { + onClick: utils.scrollClick, + })); + return React.cloneElement(item, item.props, itemChildren); + }); + const isNotTranslated = locale === 'en-US' && typeof title === 'object'; + const isZhCN = locale === 'zh-CN'; + return ( + +
+ {isNotTranslated && ( + + This article has not been translated yet. Wan't to help us out? + {' '} + + See this issue on GitHub. + + + )} + style={{ marginBottom: 24 }} + /> + )} +

+ {isZhCN ? subtitle || title['en-US'] || title : subtitle || title[locale] || title} + {isZhCN && {title['zh-CN'] || ''}} +

+ {!toc || toc.length <= 1 ? null + : ( +
+ {React.cloneElement(tocItem, tocItem.props, tocChildren)} +
+ )} + {!content ? null + : props.utils.toReactComponent(['section', { className: 'markdown' }] + .concat(getChildren(content)))} + {api ? props.utils.toReactComponent(['section', { + className: 'markdown api-container', + }].concat(getChildren(api))) : null} +
+
+ ); + } +} +Article.propTypes = {}; + +Article.defaultProps = {}; +export default Article; diff --git a/site/theme/template/Content/ComponentDoc.jsx b/site/theme/template/Content/ComponentDoc.jsx new file mode 100644 index 00000000..4a104ea9 --- /dev/null +++ b/site/theme/template/Content/ComponentDoc.jsx @@ -0,0 +1,137 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import ReactDOM from 'react-dom'; +import DocumentTitle from 'react-document-title'; +import GitHubButton from 'react-github-button'; +import { Alert } from 'antd'; +import DemoLayout, { Item } from './DemoLayout'; + +class ComponentDoc extends React.PureComponent { + componentDidMount() { + const props = this.props; + const { location } = props; + this.hash = location.hash; + if (window.addEventListener) { + window.addEventListener('scroll', this.onScroll); + } else { + window.attachEvent('onscroll', this.onScroll); + } + } + + componentWillUnmount() { + if (window.addEventListener) { + window.removeEventListener('scroll', this.onScroll); + } else { + window.detachEvent('onscroll', this.onScroll); + } + } + + onScroll = () => { + const tops = this.demoIds.map((item) => { + const dom = document.getElementById(item); + let top = dom.getBoundingClientRect().top; + if (top < 0) { + top = -top; + } + return top; + }); + const t = Math.min.apply(null, tops); + const id = this.demoIds[tops.indexOf(t)]; + const link = `#${id}`; + if (this.hash !== link) { + /* eslint-disable no-restricted-globals */ + history.pushState(null, window.title, `#${id}`); + /* eslint-enable no-restricted-globals */ + // cWindow.location.hash = `#${id}`; + this.hash = link; + } + }; + + render() { + const { ...props } = this.props; + const { pageData, demos } = props; + const { locale } = props.intl; + const isZhCN = locale === 'zh-CN'; + if (!pageData) { + return ( +
+

你要找的页面不存在!!!

+ 返回首页 +
+ ); + } + const demosToChild = Object.keys(demos).map(key => demos[key]) + .filter(item => !item.meta.hidden) + .sort((a, b) => a.meta.order - b.meta.order) + .map((item, i) => { + const content = props.utils.toReactComponent(['div'].concat(item.content[locale] || item.content)); + const comp = item.preview; + return ( + + {comp(React, ReactDOM)} + + ); + }); + const { meta, description } = pageData; + const { + title, subtitle, + } = meta; + this.demoIds = demosToChild.map(item => item.props.id); + + const isNotTranslated = locale === 'en-US' && typeof title === 'object'; + return ( + +
+ {isNotTranslated && ( + + This article has not been translated yet. Wan't to help us out? + {' '} + + See this issue on GitHub. + + + )} + style={{ marginBottom: 24 }} + /> + )} +

+ {isZhCN ? subtitle || title['en-US'] || title : subtitle || title[locale] || title} + {isZhCN && {title['zh-CN'] || ''}} + +

+ {description ? props.utils.toReactComponent(description) : null} + + {demosToChild} + +
+
+ ); + } +} + +ComponentDoc.propTypes = { + params: PropTypes.any, +}; + +ComponentDoc.defaultProps = {}; +export default ComponentDoc; diff --git a/src/theme/template/Content/DemoItem.jsx b/site/theme/template/Content/DemoItem.jsx similarity index 50% rename from src/theme/template/Content/DemoItem.jsx rename to site/theme/template/Content/DemoItem.jsx index d0edb276..6cbcd56f 100644 --- a/src/theme/template/Content/DemoItem.jsx +++ b/site/theme/template/Content/DemoItem.jsx @@ -57,60 +57,64 @@ class Item extends React.PureComponent { } const animate = this.state.codeHeight && this.state.codeOpen ? { height: this.state.codeHeight, duration: 300, - } : this.state.codeHeight && { height: 220, duration: 300 } || {}; + } : (this.state.codeHeight && { height: 220, duration: 300 }) || {}; const styleAnimate = this.state.styleHeight && this.state.codeOpen ? { height: this.state.styleHeight, duration: 300, - } : this.state.styleHeight && { height: 220, duration: 300 } || {}; + } : (this.state.styleHeight && { height: 220, duration: 300 }) || {}; const iconAnimate = this.state.codeHeight && this.state.codeOpen ? { rotate: 180, y: -2, duration: 300, - } : this.state.codeHeight && { rotate: 0, y: 0, duration: 300 } || {}; - return (
  • -

    {this.props.title}

    -
    {this.props.content}
    -
    -
    - {children} - {this.props.cStyle ? - - - -
    -
    - - - - - - - - - -
      -
    - - - - - - diff --git a/src/edit/static/list-view.less b/src/edit/static/list-view.less deleted file mode 100644 index 1f878ebd..00000000 --- a/src/edit/static/list-view.less +++ /dev/null @@ -1,204 +0,0 @@ -@import 'custom'; - -@listView: list-view; -.@{listView} { - height: 100%; - padding: 1px; - * { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - } - &-content{ - height: calc(~"100% - 114px"); - width: calc(~"100% + 32px"); - margin-left: -16px; - padding: 0 16px; - overflow: auto; - position: relative; // ListSort 必须设定以顶级 div 为相对的位置; - } - ul { - overflow: hidden; - img { - pointer-events: none; - } - li { - padding: 10px; - border-radius: 6px; - background: @edit-list-bg; - text-align: center; - font-size: 14px; - color: @edit-list-text-color; - margin-bottom: 20px; - .page-shadow(); - cursor: move; - overflow: hidden; - transition: box-shadow .5s, transform .5s; - position: relative; - &.close-wrapper{ - cursor: auto; - } - .close{ - position: absolute; - top: 5px; - right: 5px; - cursor: pointer; - & > span{ - width: 25px; - height: 25px; - background: red; - display: block; - border-radius: 50%; - line-height: 25px; - font-size: 18px; - font-weight: bold; - } - } - } - } - &-drag-selected { - box-shadow: 0 10px 20px fade(#000, 35) !important; - transform: scale(1.05) !important; - } - & .handle { - width: 100%; - margin: 10px auto 16px; - & > div { - display: inline-block; - width: 48%; - height: 40px; - font-size: 14px; - line-height: 40px; - color: #fff; - background: @edit-list-bg; - border-radius: 4px; - text-align: center; - .page-pro(); - cursor: pointer; - border: none; - box-shadow: 0 4px 6px @shadow-color; - &:last-child { - margin-left: 4%; - } - &:hover { - transform: translateY(-2px); - } - &:active { - transform: translateY(1px); - box-shadow: 0 0 0 @shadow-color; - } - i { - margin-right: 5px; - font-size: 16px; - vertical-align: middle; - } - } - & > p{ - line-height: 24px; - - } - } -} - -.@{listView}-modal { - h2 { - font-size: 18px; - margin: 10px 0; - p { - font-size: 14px; - display: inline-block; - margin-left: 10px; - i { - color: #FAC450; - margin-right: 5px; - } - } - } -} - -.@{listView}-img-wrapper ul { - width: calc(~"100% + 20px"); - margin-left: -10px; - li { - padding: 10px; - display: inline-block; - border: 1px solid @line-color; - border-radius: 4px; - margin: 10px; - vertical-align: top; - position: relative; - // .page-pro(); - .img-wrapper { - height: 146px; - width: 250px; - text-align: center; - font-size: 0; - position: relative; - overflow: hidden; - display: flex; - align-items: center; - background: @bg-color; - & img { - margin: 0; - border: 0; - padding: 0; - } - } - .text-wrapper { - line-height: 24px; - height: 24px; - margin-top: 5px; - display: inline-block; - } - &[disabled] { - pointer-events: none; - overflow: hidden; - // Retina 下遮不住,在 disabled-test 里加了个 p - & .disabled-test { - position: absolute; - overflow: hidden; - z-index: 50; - height: 100%; - width: 100%; - line-height: 80px; - font-size: 12px; - margin: -10px; - border-radius: 4px; - & > p { - transform: rotate(-45deg); - width: 100px; - height: 50px; - text-align: center; - top: -13px; - left: -38px; - position: relative; - background: @template-text-color; - color: @template-text-color-light; - box-shadow: 0 3px 5px rgba(0, 0, 0, .2); - } - } - & * { - filter: grayscale(100%); - } - } - .select-wrapper { - float: right; - height: 24px; - line-height: 24px; - margin-top: 5px; - .ant-checkbox-inner { - width: 20px; - height: 20px; - &:after { - width: 7px; - height: 12px; - left: 6px - } - } - .ant-input-number { - width: 50px; - } - } - } -} diff --git a/src/edit/static/nav-controller.less b/src/edit/static/nav-controller.less deleted file mode 100644 index 5142b89d..00000000 --- a/src/edit/static/nav-controller.less +++ /dev/null @@ -1,72 +0,0 @@ -@import 'custom'; - -.edit-nav { - width: 100%; - position: fixed; - top: 0; - z-index: 981; - pointer-events: none; - & * { - pointer-events: auto; - } - &-remark { - & i { - margin-right: 5px; - color: #FAC450 - } - } - &-bar { - height: 64px; - background: @edit-bar-color; - box-shadow: 0 5px 5px @edit-shadow-color; - ul { - float: right; - margin-right: 16px; - & li { - float: left; - padding: 0 10px; - line-height: 64px; - & a { - color: @template-text-color-light; - &:hover { - color: @link-hover-color; - } - &[disabled] { - color: @edit-disabled-color; - } - } - } - &.type-switch { - float: left; - margin-left: 16px; - font-size: 16px; - color: @text-color-light; - li { - &.active { - color: @text-color-dark; - background: @bar-color; - } - padding: 0 20px; - border-left: 1px solid @disabled-color; - cursor: pointer; - transition: color .3s @ease-in-out, background .3s @ease-in-out; - &:last-child { - border-right: 1px solid @disabled-color; - } - } - } - } - } -} - -.purple { - color: @primary-color !important; -} - -.ant-modal-container .copy { - display: block; - width: 60px; - height: 30px; - margin: -4px -15px -5px -15px; - line-height: 30px; -} diff --git a/src/edit/static/other-view.less b/src/edit/static/other-view.less deleted file mode 100644 index 9d213ec7..00000000 --- a/src/edit/static/other-view.less +++ /dev/null @@ -1,32 +0,0 @@ -@import 'custom'; - -@otherView: other-view; -.@{otherView} { - position: relative; - ul { - overflow: hidden; - img { - pointer-events: none; - } - li { - padding: 10px; - border-radius: 6px; - background: @edit-list-bg; - text-align: center; - font-size: 14px; - color: @edit-list-text-color; - margin-bottom: 20px; - .page-shadow(); - cursor: pointer; - overflow: hidden; - transition: box-shadow .5s, transform .5s; - position: relative; - div{ - text-align: left; - label{ - float: right; - } - } - } - } -} diff --git a/src/edit/static/preview.less b/src/edit/static/preview.less deleted file mode 100644 index 70968e38..00000000 --- a/src/edit/static/preview.less +++ /dev/null @@ -1,118 +0,0 @@ -@import 'custom'; - -.preview-wrapper { - float: left; - width: calc(~"100% - 320px"); - height: 100%; - box-shadow: 5px 0 5px @edit-shadow-color; - z-index: 11; - background: #363b3e; - position: relative; - div { - width: 100%; - height: 100%; - } - .edit-cover { - position: relative; - box-shadow: 0 0 30px fade(#000, 65); - > div { - margin: auto; - } - &.edit-phone { - width: 320px; - top: 0; - bottom: 0; - left: 0; - right: 0; - height: calc(~"100% - 60px"); - max-height: 688px; - margin: auto; - border-radius: 25px; - position: absolute; - - .phone-head, .phone-footer { - height: 60px; - background: #000; - position: relative; - em { - display: block; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - margin: auto; - } - } - .phone-head { - border-radius: 25px 25px 0 0; - .camera { - width: 10px; - height: 10px; - border-radius: 10px; - background: #175f6e; - border: 3px solid fade(#222222, 70); - transform: translateX(-50px); - } - .receiver { - width: 70px; - height: 8px; - background: #000; - border-radius: 10px; - border: 2px solid #222222; - } - } - .phone-footer { - border-radius: 0 0 25px 25px; - .home-key { - width: 40px; - height: 40px; - border-radius: 40px; - background: #000; - border: 4px solid #222222; - } - } - .edit-iframe-wrapper { - height: calc(~"100% - 120px"); - max-height: 568px; - position: relative; - } - - } - - .preview-container { - overflow: auto; - position: relative; - z-index: 11; - iframe { - width: 100%; - height: 100%; - border: 0; - position: absolute; - top: 0; - } - } - .edit-state-wrapper { - position: absolute; - pointer-events: none; - overflow-y: auto; - overflow-x: hidden; - user-select: none; - z-index: 12; - top: 0; - .edit-state { - position: absolute; - width: 100%; - } - .enter-box { - border: 2px dotted fade(@line-deep-color, 65); - position: absolute; - color: @primary-color; - } - .layout { - border: 2px solid @primary-color; - position: absolute; - } - } - } -} diff --git a/src/edit/static/style.js b/src/edit/static/style.js deleted file mode 100644 index c99f6142..00000000 --- a/src/edit/static/style.js +++ /dev/null @@ -1,8 +0,0 @@ -import './common.less'; -import './nav-controller.less'; -import './edit-controls.less'; -import './edit-view.less'; -import './list-view.less'; -import './other-view.less'; -import './preview.less'; - diff --git a/src/edit/template/NotFound.jsx b/src/edit/template/NotFound.jsx deleted file mode 100644 index b30e95a7..00000000 --- a/src/edit/template/NotFound.jsx +++ /dev/null @@ -1,22 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - -export default function NotFound(props) { - return ( -
    -
    -

    404

    -

    你要找的页面不存在 返回首页

    -
    - - - -
    -
    - - - - - - - - - -
      -
    - - - - - - diff --git a/src/templates/static/lessToString.jsx b/src/templates/static/lessToString.jsx deleted file mode 100644 index 3180bfa7..00000000 --- a/src/templates/static/lessToString.jsx +++ /dev/null @@ -1,19 +0,0 @@ -let point = require('!raw!./point.less'); - -point = point.replace('../../../static/custom.less', './custom.less'); - -const global = require('!raw!../../theme/static/global.less'); -let common = require('!raw!./common.less'); - -common = common.replace('../../theme/static/global', './global'); - -const custom = require('!raw!./custom.less'); -const content = require('!raw!./content.less'); - -export default { - global, - common, - custom, - point, - content, -}; diff --git a/src/templates/static/point.less b/src/templates/static/point.less deleted file mode 100644 index c42ceac4..00000000 --- a/src/templates/static/point.less +++ /dev/null @@ -1,36 +0,0 @@ -@import './custom.less'; - -@point: templates-list; -.@{point}-wrapper { - position: fixed; - z-index: 9998; - top: 0; - right: 20px; - width: 8px; - display: flex; - height: 100%; - align-items: center; - pointer-events: none -} - -.@{point} { - width: 8px; - height: 8px; - background: @primary-color; - border-radius: 6px; - float: left; - margin: 4px auto; - opacity: .5; - cursor: pointer; - pointer-events: auto; - transition: opacity .3s; - &.active{ - opacity: 1; - } -} - -@media screen and (max-width: 767px) { - .@{point}-wrapper { - display: none; - } -} \ No newline at end of file diff --git a/src/templates/template.config.js b/src/templates/template.config.js deleted file mode 100644 index 86524291..00000000 --- a/src/templates/template.config.js +++ /dev/null @@ -1,96 +0,0 @@ -import deepCopy from 'deepcopy'; - -import { isColorFuc } from './template/utils'; - -const Nav0 = require('./template/element/Nav0/template.config'); -const Nav1 = require('./template/element/Nav1/template.config'); -const Content0 = require('./template/element/Content0/template.config'); -const Content1 = require('./template/element/Content1/template.config'); -const Content2 = require('./template/element/Content2/template.config'); -const Content3 = require('./template/element/Content3/template.config'); -const Content4 = require('./template/element/Content4/template.config'); -const Content5 = require('./template/element/Content5/template.config'); -const Content6 = require('./template/element/Content6/template.config'); -const Content7 = require('./template/element/Content7/template.config'); -const Content8 = require('./template/element/Content8/template.config'); -const Content9 = require('./template/element/Content9/template.config'); -const Content10 = require('./template/element/Content10/template.config'); -const Footer0 = require('./template/element/Footer0/template.config'); -const Footer1 = require('./template/element/Footer1/template.config'); - -function addTypeToStyle(d) { - const data = d; - Object.keys(data).forEach((key) => { - const item = data[key]; - if (typeof item === 'object') { - if ('value' in item) { - const isNumber = parseFloat(item.value) || parseFloat(item.value) === 0; - const isColor = isColorFuc(item.value); - if (item.type) { - return; - } - if (isNumber) { - item.type = 'number'; - } - if (isColor) { - item.type = 'color'; - } - } else { - addTypeToStyle(item); - } - } - }); -} - -// 增加 phoneStyle; -function addData(data) { - const dataSource = data.dataSource; - addTypeToStyle(dataSource); - Object.keys(dataSource).forEach((key) => { - const item = dataSource[key]; - if (typeof item === 'object' && !('stylePhone' in item) && 'style' in item) { - const styleObj = Object.keys(item.style); - const isCssArray = styleObj.filter(k => k.match(/\$/)); - isCssArray.forEach((cKey) => { - const cItem = item.style[cKey]; - if (typeof cItem === 'object' && !('stylePhone' in cItem) && 'style' in cItem) { - item.style[cKey].stylePhone = deepCopy(item.style[cKey].style); - } - }); - item.stylePhone = deepCopy(item.style); - } - }); -} - -addData(Nav0); -addData(Nav1); -addData(Content0); -addData(Content1); -addData(Content2); -addData(Content3); -addData(Content4); -addData(Content5); -addData(Content6); -addData(Content7); -addData(Content8); -addData(Content9); -addData(Content10); -addData(Footer0); -addData(Footer1); -export default { - Nav0, - Nav1, - Content0, - Content1, - Content2, - Content3, - Content4, - Content5, - Content6, - Content7, - Content8, - Content9, - Content10, - Footer0, - Footer1, -}; diff --git a/src/templates/template/NotFound.jsx b/src/templates/template/NotFound.jsx deleted file mode 100644 index b30e95a7..00000000 --- a/src/templates/template/NotFound.jsx +++ /dev/null @@ -1,22 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - -export default function NotFound(props) { - return ( -
    -
    -

    404

    -

    你要找的页面不存在 返回首页

    -
    - - - -
    -
    - - - - - - - - - -
      -
    - - - - - - - - diff --git a/src/theme/template/Content/Article.jsx b/src/theme/template/Content/Article.jsx deleted file mode 100644 index 67e615a8..00000000 --- a/src/theme/template/Content/Article.jsx +++ /dev/null @@ -1,54 +0,0 @@ -import React from 'react'; -import { getChildren } from 'jsonml.js/lib/utils'; -import DocumentTitle from 'react-document-title'; -import * as utils from '../utils'; - -class Article extends React.PureComponent { - render() { - const props = this.props; - const pageData = props.pageData; - if (!pageData) { - return (
    -

    你要找的页面不存在!!!

    - 返回首页 -
    ); - } - const { - meta, content, toc, api, - } = pageData; - const { - title, subtitle, chinese, english, - } = meta; - const tocItem = props.utils.toReactComponent(toc); - const tocChildren = utils.toArrayChildren(tocItem.props.children).map((item) => { - const itemChildren = utils.toArrayChildren(item.props.children).map(cItem => - React.cloneElement(cItem, { - onClick: utils.scrollClick, - })); - return React.cloneElement(item, item.props, itemChildren); - }); - return ( -
    -

    - {title || english} - {(!subtitle && !chinese) ? null : {subtitle || chinese}} -

    - {!toc || toc.length <= 1 ? null : - (
    - {React.cloneElement(tocItem, tocItem.props, tocChildren)} -
    )} - {!content ? null : - props.utils.toReactComponent(['section', { className: 'markdown' }] - .concat(getChildren(content)))} - {api ? props.utils.toReactComponent(['section', { - className: 'markdown api-container', - }].concat(getChildren(api))) : null} -
    -
    ); - } -} -Article.propTypes = {}; - -Article.defaultProps = {}; -export default Article; - diff --git a/src/theme/template/Content/ComponentDoc.jsx b/src/theme/template/Content/ComponentDoc.jsx deleted file mode 100644 index 1d3f75e9..00000000 --- a/src/theme/template/Content/ComponentDoc.jsx +++ /dev/null @@ -1,112 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import ReactDOM from 'react-dom'; -import DocumentTitle from 'react-document-title'; -import DemoLayout, { Item } from './DemoLayout'; - -class ComponentDoc extends React.PureComponent { - componentDidMount() { - const props = this.props; - const { location } = props; - this.hash = location.hash; - if (window.addEventListener) { - window.addEventListener('scroll', this.onScroll); - } else { - window.attachEvent('onscroll', this.onScroll); - } - } - - componentWillUnmount() { - if (window.addEventListener) { - window.removeEventListener('scroll', this.onScroll); - } else { - window.detachEvent('onscroll', this.onScroll); - } - } - - onScroll = () => { - const tops = this.demoIds.map((item) => { - const dom = document.getElementById(item); - let top = dom.getBoundingClientRect().top; - if (top < 0) { - top = -top; - } - return top; - }); - const t = Math.min.apply(null, tops); - const id = this.demoIds[tops.indexOf(t)]; - const link = `#${id}`; - if (this.hash !== link) { - /* eslint-disable no-restricted-globals */ - history.pushState(null, window.title, `#${id}`); - /* eslint-enable no-restricted-globals */ - // cWindow.location.hash = `#${id}`; - this.hash = link; - } - }; - - render() { - const props = this.props; - const { pageData } = props; - if (!pageData) { - return (
    -

    你要找的页面不存在!!!

    - 返回首页 -
    ); - } - const demosToChild = Object.keys(pageData.demo).map(key => pageData.demo[key]) - .filter(item => !item.meta.hidden) - .sort((a, b) => a.meta.order - b.meta.order) - .map((item, i) => { - const content = props.utils.toReactComponent(['div'].concat(item.content)); - const comp = item.preview; - return ( - {comp(React, ReactDOM)} - ); - }); - const { meta, description } = pageData.index; - const { - title, subtitle, chinese, english, - } = meta; - this.demoIds = demosToChild.map(item => item.props.id); - return ( -
    -

    {title || english} - {subtitle || chinese} -