From a2bc971fc94c21664de13e2d0dc4bddaecac0c23 Mon Sep 17 00:00:00 2001 From: ShanaMaid Date: Thu, 27 Sep 2018 20:43:51 +0800 Subject: [PATCH] =?UTF-8?q?feat(component):=20=E6=96=B0=E5=A2=9EGrid?= =?UTF-8?q?=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Grid/Col.tsx | 94 ++++++++++++++ components/Grid/Row.tsx | 71 +++++++++++ components/Grid/__tests__/e2e.test.tsx | 12 ++ components/Grid/__tests__/props.test.tsx | 14 +++ components/Grid/index.tsx | 8 ++ components/Grid/style/grid.less | 112 +++++++++++++++++ components/Grid/style/index.less | 117 ++++++++++++++++++ components/Grid/style/var.less | 4 + components/Slider/Slider.tsx | 42 ++++++- components/Slider/style/index.less | 3 +- components/index.tsx | 2 + components/styles/components.less | 3 +- components/styles/index.less | 2 + components/styles/mixins/clearfix.less | 13 ++ components/styles/mixins/index.less | 1 + components/styles/var.less | 33 +++++ docs/pages/components/Grid/api.tsx | 43 +++++++ docs/pages/components/Grid/demo/gridConfig.md | 2 + .../pages/components/Grid/demo/gridConfig.tsx | 51 ++++++++ docs/pages/components/Grid/demo/gridCustom.md | 2 + .../pages/components/Grid/demo/gridCustom.tsx | 22 ++++ docs/pages/components/Grid/demo/gridDemo.md | 2 + docs/pages/components/Grid/demo/gridDemo.tsx | 26 ++++ docs/pages/components/Grid/demo/gridFlex.md | 2 + docs/pages/components/Grid/demo/gridFlex.tsx | 50 ++++++++ .../components/Grid/demo/gridFlexOrder.md | 2 + .../components/Grid/demo/gridFlexOrder.tsx | 17 +++ .../components/Grid/demo/gridFlexVertical.md | 2 + .../components/Grid/demo/gridFlexVertical.tsx | 46 +++++++ docs/pages/components/Grid/demo/gridOrder.md | 2 + docs/pages/components/Grid/demo/gridOrder.tsx | 15 +++ docs/pages/components/Grid/demo/gridOther.md | 2 + docs/pages/components/Grid/demo/gridOther.tsx | 16 +++ docs/pages/components/Grid/index.less | 54 ++++++++ docs/pages/components/Grid/index.md | 11 ++ docs/pages/components/Grid/index.tsx | 68 ++++++++++ docs/pages/components/Slider/api.tsx | 6 + .../components/Slider/demo/sliderCustom.tsx | 1 + docs/pages/components/pageMenu.tsx | 10 ++ docs/pages/components/routes.tsx | 6 + package-lock.json | 60 +++++---- package.json | 5 +- 42 files changed, 1022 insertions(+), 32 deletions(-) create mode 100644 components/Grid/Col.tsx create mode 100644 components/Grid/Row.tsx create mode 100644 components/Grid/__tests__/e2e.test.tsx create mode 100644 components/Grid/__tests__/props.test.tsx create mode 100644 components/Grid/index.tsx create mode 100644 components/Grid/style/grid.less create mode 100644 components/Grid/style/index.less create mode 100644 components/Grid/style/var.less create mode 100644 components/styles/mixins/clearfix.less create mode 100644 components/styles/mixins/index.less create mode 100644 docs/pages/components/Grid/api.tsx create mode 100644 docs/pages/components/Grid/demo/gridConfig.md create mode 100644 docs/pages/components/Grid/demo/gridConfig.tsx create mode 100644 docs/pages/components/Grid/demo/gridCustom.md create mode 100644 docs/pages/components/Grid/demo/gridCustom.tsx create mode 100644 docs/pages/components/Grid/demo/gridDemo.md create mode 100644 docs/pages/components/Grid/demo/gridDemo.tsx create mode 100644 docs/pages/components/Grid/demo/gridFlex.md create mode 100644 docs/pages/components/Grid/demo/gridFlex.tsx create mode 100644 docs/pages/components/Grid/demo/gridFlexOrder.md create mode 100644 docs/pages/components/Grid/demo/gridFlexOrder.tsx create mode 100644 docs/pages/components/Grid/demo/gridFlexVertical.md create mode 100644 docs/pages/components/Grid/demo/gridFlexVertical.tsx create mode 100644 docs/pages/components/Grid/demo/gridOrder.md create mode 100644 docs/pages/components/Grid/demo/gridOrder.tsx create mode 100644 docs/pages/components/Grid/demo/gridOther.md create mode 100644 docs/pages/components/Grid/demo/gridOther.tsx create mode 100644 docs/pages/components/Grid/index.less create mode 100644 docs/pages/components/Grid/index.md create mode 100644 docs/pages/components/Grid/index.tsx diff --git a/components/Grid/Col.tsx b/components/Grid/Col.tsx new file mode 100644 index 0000000..8ebf208 --- /dev/null +++ b/components/Grid/Col.tsx @@ -0,0 +1,94 @@ + +import {Component} from 'react'; +import * as React from 'react'; +import * as classNames from 'classnames'; +import {IBaseComponent} from '../template/component'; + +export interface ICol { + offset?: number; + order?: number; + pull?: number; + push?: number; + span?: number; +} + +export interface IColProps extends IBaseComponent, ICol { + xs?: number | ICol; + sm?: number | ICol; + md?: number | ICol; + lg?: number | ICol; + xl?: number | ICol; + xxl?: number | ICol; +} + +export interface IColState { + +} + +const sizes = ['xs', 'sm', 'md', 'lg', 'xl', 'xxl']; + +/** + * **组件中文名称**-组件描述。 + */ +export class Col extends Component { + preCls = 'yoshino-col'; + + static defaultProps = { + offset: 0, + order: 0, + pull: 0, + push: 0, + }; + + render() { + const { + className, style, span, + offset, order, pull, push, children, + ...otherProps} = this.props; + const preCls = this.preCls; + let sizeCls = {}; + + sizes.forEach((size: 'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs') => { + let sizeProps: ICol = {}; + // tslint:disable-next-line + const props = this.props as any; + if (typeof props[size] === 'number') { + sizeProps.span = props[size]; + } else if (typeof props[size] === 'object') { + sizeProps = props[size] || {}; + } + + delete otherProps[size]; + + sizeCls = { + ...sizeCls, + [`${preCls}-${size}-${sizeProps.span}`]: sizeProps.span !== undefined, + [`${preCls}-${size}-order-${sizeProps.order}`]: sizeProps.order || sizeProps.order === 0, + [`${preCls}-${size}-offset-${sizeProps.offset}`]: sizeProps.offset || sizeProps.offset === 0, + [`${preCls}-${size}-push-${sizeProps.push}`]: sizeProps.push || sizeProps.push === 0, + [`${preCls}-${size}-pull-${sizeProps.pull}`]: sizeProps.pull || sizeProps.pull === 0, + }; + }); + + const clsName = classNames( + preCls, className, sizeCls, { + [`${preCls}-${span}`]: span !== undefined, + [`${preCls}-order-${order}`]: !!order, + [`${preCls}-offset-${offset}`]: !!offset, + [`${preCls}-push-${push}`]: !!push, + [`${preCls}-pull-${pull}`]: !!pull, + } + ); + return ( +
+ {children} +
+ ); + } +} + +export default Col; diff --git a/components/Grid/Row.tsx b/components/Grid/Row.tsx new file mode 100644 index 0000000..2b29ec1 --- /dev/null +++ b/components/Grid/Row.tsx @@ -0,0 +1,71 @@ +// tslint:disable no-any +import {Component} from 'react'; +import * as React from 'react'; +import * as classNames from 'classnames'; +import {IBaseComponent} from '../template/component'; + +export interface IRowProps extends IBaseComponent { + align?: 'top' | 'middle' | 'bottom'; + gutter?: number ; + justify?: 'start' | 'end' | 'center' | 'space-around' | 'space-between'; + type?: 'flex'; +} + +export interface IRowState { + screens: {[index: string]: any}; +} + +/** + * **组件中文名称**-组件描述。 + */ +export class Row extends Component { + preCls = 'yoshino-row'; + + static defaultProps = { + type: '', + gutter: 0, + justify: 'start', + align: 'top', + }; + + render() { + const { + className, style, + align = 'top', gutter = 0, justify = 'start', + type = '', children, + ...otherProps} = this.props; + const preCls = this.preCls; + const clsName = classNames( + preCls, className, { + [preCls]: !type, + [`${preCls}-${type}`]: !!type, + [`${preCls}-${type}-${justify}`]: !!type && !!justify, + [`${preCls}-${type}-${align}`]: !!type && !!align, + } + ); + const offsetStyle = gutter > 0 ? { + marginLeft: gutter / -2, + marginRight: gutter / -2, + } : {}; + const colChildren = React.Children.map(children, (child: React.ReactElement) => { + return React.cloneElement(child, { + style: { + paddingLeft: gutter / 2, + paddingRight: gutter / 2, + ...child.props.style, + }, + }); + }); + return ( +
+ {colChildren} +
+ ); + } +} + +export default Row; diff --git a/components/Grid/__tests__/e2e.test.tsx b/components/Grid/__tests__/e2e.test.tsx new file mode 100644 index 0000000..945a90a --- /dev/null +++ b/components/Grid/__tests__/e2e.test.tsx @@ -0,0 +1,12 @@ +import * as React from 'react'; +import {Simulate, renderIntoDocument, scryRenderedComponentsWithType} from 'react-dom/test-utils'; +import {findDOMNode} from 'react-dom'; +import Grid from '../index'; + +describe('多选', () => { + test('点击其中一个选项后可通过 onChange 拿到最新的值', () => { + const component = renderIntoDocument( + , + ) as Grid; + }); +}); diff --git a/components/Grid/__tests__/props.test.tsx b/components/Grid/__tests__/props.test.tsx new file mode 100644 index 0000000..3c1cd50 --- /dev/null +++ b/components/Grid/__tests__/props.test.tsx @@ -0,0 +1,14 @@ +import * as renderer from 'react-test-renderer'; +import * as React from 'react'; +import Grid from '../index'; + +describe('Props', () => { + + test('默认', () => { + const component = renderer.create( + , + ); + const tree = component.toJSON(); + expect(tree).toMatchSnapshot(); + }); +}); diff --git a/components/Grid/index.tsx b/components/Grid/index.tsx new file mode 100644 index 0000000..00c54c2 --- /dev/null +++ b/components/Grid/index.tsx @@ -0,0 +1,8 @@ +// tks for https://github.com/ant-design/ant-design/tree/master/components/grid +import Col from './Col'; +import Row from './Row'; + +export default { + Col, + Row, +}; diff --git a/components/Grid/style/grid.less b/components/Grid/style/grid.less new file mode 100644 index 0000000..2d0ea36 --- /dev/null +++ b/components/Grid/style/grid.less @@ -0,0 +1,112 @@ +// thanks for antd +// https://github.com/ant-design/ant-design/blob/master/components/grid/style/mixin.less +@import './var.less'; + +.make-row(@gutter: @grid-gutter-width) { + position: relative; + margin-left: (@gutter / -2); + margin-right: (@gutter / -2); + height: auto; + .clearfix; +} + +.make-grid-columns() { + .col(@index) { + @item: ~".@{css-prefix}-col-@{index}, .@{css-prefix}-col-xs-@{index}, .@{css-prefix}-col-sm-@{index}, .@{css-prefix}-col-md-@{index}, .@{css-prefix}-col-lg-@{index}"; + .col((@index + 1), @item); + } + .col(@index, @list) when (@index =< @grid-columns) { + @item: ~".@{css-prefix}-col-@{index}, .@{css-prefix}-col-xs-@{index}, .@{css-prefix}-col-sm-@{index}, .@{css-prefix}-col-md-@{index}, .@{css-prefix}-col-lg-@{index}"; + .col((@index + 1), ~"@{list}, @{item}"); + } + .col(@index, @list) when (@index > @grid-columns) { + @{list} { + position: relative; + // Prevent columns from collapsing when empty + min-height: 1px; + padding-left: (@grid-gutter-width / 2); + padding-right: (@grid-gutter-width / 2); + } + } + .col(1); +} + +.float-grid-columns(@class) { + .col(@index) { // initial + @item: ~".@{css-prefix}-col@{class}-@{index}"; + .col((@index + 1), @item); + } + .col(@index, @list) when (@index =< @grid-columns) { // general + @item: ~".@{css-prefix}-col@{class}-@{index}"; + .col((@index + 1), ~"@{list}, @{item}"); + } + .col(@index, @list) when (@index > @grid-columns) { // terminal + @{list} { + float: left; + flex: 0 0 auto; + } + } + .col(1); // kickstart it +} + +// lesshint false +.loop-grid-columns(@index, @class) when (@index > 0) { + .@{css-prefix}-col@{class}-@{index} { + display: block; + box-sizing: border-box; + width: percentage((@index / @grid-columns)); + } + + .@{css-prefix}-col@{class}-push-@{index} { + left: percentage((@index / @grid-columns)); + } + + .@{css-prefix}-col@{class}-pull-@{index} { + right: percentage((@index / @grid-columns)); + } + + .@{css-prefix}-col@{class}-offset-@{index} { + margin-left: percentage((@index / @grid-columns)); + } + + .@{css-prefix}-col@{class}-order-@{index} { + order: @index; + } + + .loop-grid-columns((@index - 1), @class); +} + +.loop-grid-columns(@index, @class) when (@index = 0) { + .@{css-prefix}-col@{class}-@{index} { + display: none; + } + + .@{css-prefix}-col-push-@{index} { + left: auto; + } + + .@{css-prefix}-col-pull-@{index} { + right: auto; + } + + .@{css-prefix}-col@{class}-push-@{index} { + left: auto; + } + + .@{css-prefix}-col@{class}-pull-@{index} { + right: auto; + } + + .@{css-prefix}-col@{class}-offset-@{index} { + margin-left: 0; + } + + .@{css-prefix}-col@{class}-order-@{index} { + order: 0; + } +} + +.make-grid(@class: ~'') { + .float-grid-columns(@class); + .loop-grid-columns(@grid-columns, @class); +} diff --git a/components/Grid/style/index.less b/components/Grid/style/index.less new file mode 100644 index 0000000..e355577 --- /dev/null +++ b/components/Grid/style/index.less @@ -0,0 +1,117 @@ +@import './var.less'; +@import './grid.less'; + +@grid-prefix-cls: ~"@{css-prefix}-grid"; + +.@{css-prefix}-row { + .make-row(); + + display: block; + box-sizing: border-box; +} + +.@{css-prefix}-row-flex { + display: flex; + flex-flow: row wrap; + + &::before, + &::after { + display: flex; + } +} + +// x轴原点 +.@{css-prefix}-row-flex-start { + justify-content: flex-start; +} + +// x轴居中 +.@{css-prefix}-row-flex-center { + justify-content: center; +} + +// x轴反方向 +.@{css-prefix}-row-flex-end { + justify-content: flex-end; +} + +// x轴平分 +.@{css-prefix}-row-flex-space-between { + justify-content: space-between; +} + +// x轴有间隔地平分 +.@{css-prefix}-row-flex-space-around { + justify-content: space-around; +} + +// 顶部对齐 +.@{css-prefix}-row-flex-top { + align-items: flex-start; +} + +// 居中对齐 +.@{css-prefix}-row-flex-middle { + align-items: center; +} + +// 底部对齐 +.@{css-prefix}-row-flex-bottom { + align-items: flex-end; +} + +.@{css-prefix}-col { + position: relative; + display: block; +} + +.make-grid-columns(); +.make-grid(); + +// Extra small grid +// +// Columns, offsets, pushes, and pulls for extra small devices like +// smartphones. + +.make-grid(-xs); + +// Small grid +// +// Columns, offsets, pushes, and pulls for the small device range, from phones +// to tablets. + +@media (min-width: @screen-sm-min) { + .make-grid(-sm); +} + +// Medium grid +// +// Columns, offsets, pushes, and pulls for the desktop device range. + +@media (min-width: @screen-md-min) { + .make-grid(-md); +} + +// Large grid +// +// Columns, offsets, pushes, and pulls for the large desktop device range. + +@media (min-width: @screen-lg-min) { + .make-grid(-lg); +} + +// Extra Large grid +// +// Columns, offsets, pushes, and pulls for the full hd device range. + +@media (min-width: @screen-xl-min) { + .make-grid(-xl); +} + +// Extra Extra Large grid +// +// Columns, offsets, pushes, and pulls for the full hd device range. + +@media (min-width: @screen-xxl-min) { + .make-grid(-xxl); +} diff --git a/components/Grid/style/var.less b/components/Grid/style/var.less new file mode 100644 index 0000000..e29e9ec --- /dev/null +++ b/components/Grid/style/var.less @@ -0,0 +1,4 @@ +@import '../../styles/var.less'; + +@grid-columns: 24; +@grid-gutter-width: 0; diff --git a/components/Slider/Slider.tsx b/components/Slider/Slider.tsx index 22eb886..30df001 100644 --- a/components/Slider/Slider.tsx +++ b/components/Slider/Slider.tsx @@ -29,6 +29,10 @@ export interface ISliderProps extends IBaseComponent { * 禁用 */ disabled?: boolean; + /** + * 步长 + */ + step?: number; } export interface ISliderDefaultProps extends IBaseComponent { @@ -36,6 +40,7 @@ export interface ISliderDefaultProps extends IBaseComponent { max: number; min: number; disabled: boolean; + step: number; } export interface ISliderState { @@ -54,6 +59,7 @@ export class Slider extends Component { max: 100, min: 0, disabled: false, + step: 1, }; state = { @@ -65,6 +71,13 @@ export class Slider extends Component { return value !== undefined ? value : this.state.value; } + getStepPercent = () => { + const {max, min, step} = this.props as ISliderDefaultProps; + const range = max - min; + const percent = step / range; + return +percent.toFixed(4); + } + getPercent = () => { const {max, min} = this.props as ISliderDefaultProps; const value = this.getValue(); @@ -79,8 +92,16 @@ export class Slider extends Component { const sliderRect = slider.getBoundingClientRect() as DOMRect; const sliderWidth = sliderRect.width; // 滑动条宽度 const left = e.clientX - (sliderRect.x || sliderRect.left); // 点击位置相对滑动条偏移量 - const percent = +(left / sliderWidth).toFixed(4); - this.onChangeTrigger(min + Math.round((max - min) * percent)); + const currentPercent = +(left / sliderWidth).toFixed(4); + const oldPercent = this.getPercent(); + const stepPercent = this.getStepPercent(); + const change = currentPercent - oldPercent; + const times = Math.abs(Math.round(change / stepPercent)); + if (times !== 0) { + const changePercent = times * stepPercent; + const percent = change > 0 ? oldPercent + changePercent : oldPercent - changePercent; + this.onChangeTrigger(min + Math.round((max - min) * percent)); + } this.moving = false; } @@ -97,8 +118,17 @@ export class Slider extends Component { if (left < 0 || left > sliderWidth) { return; } - const percent = +(left / sliderWidth).toFixed(4); - this.onChangeTrigger(min + Math.round((max - min) * percent)); + const currentPercent = +(left / sliderWidth).toFixed(4); + const oldPercent = this.getPercent(); + const stepPercent = this.getStepPercent(); + const change = currentPercent - oldPercent; + const times = Math.abs(Math.round(change / stepPercent)); + if (times !== 0) { + const changePercent = times * stepPercent; + const percent = change > 0 ? oldPercent + changePercent : oldPercent - changePercent; + this.onChangeTrigger(min + Math.round((max - min) * percent)); + } + // this.onChangeTrigger(min + Math.round((max - min) * percent)); }; const bodyMouseUp = () => { @@ -130,7 +160,9 @@ export class Slider extends Component { } render() { - const {className, style, children, defaultValue, disabled, onChange, ...otherProps} = this.props; + const { + className, style, children, defaultValue, + disabled, onChange, step, ...otherProps} = this.props; const preCls = 'yoshino-slider'; const clsName = classNames( preCls, diff --git a/components/Slider/style/index.less b/components/Slider/style/index.less index 9124747..e4afa39 100644 --- a/components/Slider/style/index.less +++ b/components/Slider/style/index.less @@ -6,6 +6,7 @@ position: relative; cursor: pointer; height: @slider-bar-size; + padding: (@slider-bar-size - @slider-process-height) / 2 0; &-process { width: 100%; @@ -16,7 +17,7 @@ &-bar { position: absolute; - top: 0; + top: (@slider-bar-size - @slider-process-height) / 2; left: 0; height: @slider-process-height; background: @primary-color; diff --git a/components/index.tsx b/components/index.tsx index dae1bd0..43209cf 100644 --- a/components/index.tsx +++ b/components/index.tsx @@ -11,6 +11,7 @@ import Checkbox from './Checkbox'; import Collapse from './Collapse'; import Divider from './Divider'; import Drawer from './Drawer'; +import Grid from './Grid'; import Helpers from './Helpers'; import Icon from './Icon'; import Input from './Input'; @@ -51,6 +52,7 @@ export { Collapse, Divider, Drawer, + Grid, Helpers, Icon, Input, diff --git a/components/styles/components.less b/components/styles/components.less index c10d6dd..fb16f91 100644 --- a/components/styles/components.less +++ b/components/styles/components.less @@ -35,4 +35,5 @@ @import '../Select/style/index'; @import '../Message/style/index'; @import '../Carousel/style/index'; -@import '../Tabs/style/index'; \ No newline at end of file +@import '../Tabs/style/index'; +@import '../Grid/style/index'; \ No newline at end of file diff --git a/components/styles/index.less b/components/styles/index.less index 084aae3..f463127 100644 --- a/components/styles/index.less +++ b/components/styles/index.less @@ -1,4 +1,6 @@ @import './var'; @import './common/index'; @import './animation/index'; +@import './mixins/index'; @import './components'; + diff --git a/components/styles/mixins/clearfix.less b/components/styles/mixins/clearfix.less new file mode 100644 index 0000000..0c3e94a --- /dev/null +++ b/components/styles/mixins/clearfix.less @@ -0,0 +1,13 @@ +.clearfix() { + zoom: 1; + + &::before, + &::after { + content: ""; + display: table; + } + + &::after { + clear: both; + } +} diff --git a/components/styles/mixins/index.less b/components/styles/mixins/index.less new file mode 100644 index 0000000..869ed4c --- /dev/null +++ b/components/styles/mixins/index.less @@ -0,0 +1 @@ +@import './clearfix.less'; diff --git a/components/styles/var.less b/components/styles/var.less index 744eed2..5b4a7f8 100644 --- a/components/styles/var.less +++ b/components/styles/var.less @@ -57,3 +57,36 @@ @disabled-color: rgba(0, 0, 0, 0.25); // 字体色 @disabled-background-color: #f5f5f5; // 禁用背景色 @disabled-border-color: #d9d9d9; // 禁用边框色 + + +// Media queries breakpoints +// Extra small screen / phone +@screen-xs: 480px; +@screen-xs-min: @screen-xs; + +// Small screen / tablet +@screen-sm: 576px; +@screen-sm-min: @screen-sm; + +// Medium screen / desktop +@screen-md: 768px; +@screen-md-min: @screen-md; + +// Large screen / wide desktop +@screen-lg: 992px; +@screen-lg-min: @screen-lg; + +// Extra large screen / full hd +@screen-xl: 1200px; +@screen-xl-min: @screen-xl; + +// Extra extra large screen / large descktop +@screen-xxl: 1600px; +@screen-xxl-min: @screen-xxl; + +// provide a maximum +@screen-xs-max: (@screen-sm-min - 1px); +@screen-sm-max: (@screen-md-min - 1px); +@screen-md-max: (@screen-lg-min - 1px); +@screen-lg-max: (@screen-xl-min - 1px); +@screen-xl-max: (@screen-xxl-min - 1px); diff --git a/docs/pages/components/Grid/api.tsx b/docs/pages/components/Grid/api.tsx new file mode 100644 index 0000000..424c205 --- /dev/null +++ b/docs/pages/components/Grid/api.tsx @@ -0,0 +1,43 @@ +export default [ + { + title: 'API', + json: [ + { + props: '', + intro: '', + type: '', + defaultValue: '', + }, + { + props: '', + intro: '', + type: '', + defaultValue: '', + }, + { + props: '', + intro: '', + type: '', + defaultValue: '', + }, + { + props: '', + intro: '', + type: '', + defaultValue: '', + }, + { + props: '', + intro: '', + type: '', + defaultValue: '', + }, + { + props: '', + intro: '', + type: '', + defaultValue: '', + }, + ] + } +]; diff --git a/docs/pages/components/Grid/demo/gridConfig.md b/docs/pages/components/Grid/demo/gridConfig.md new file mode 100644 index 0000000..2c5ed2f --- /dev/null +++ b/docs/pages/components/Grid/demo/gridConfig.md @@ -0,0 +1,2 @@ +#### 配置器 +简单配置几种等分栅格和间距。 \ No newline at end of file diff --git a/docs/pages/components/Grid/demo/gridConfig.tsx b/docs/pages/components/Grid/demo/gridConfig.tsx new file mode 100644 index 0000000..d728eb5 --- /dev/null +++ b/docs/pages/components/Grid/demo/gridConfig.tsx @@ -0,0 +1,51 @@ +import * as React from 'react'; +import { Grid, Slider } from '@yoshino/components/'; + +const { Row, Col } = Grid; + +export default class extends React.Component { + state = { + gutter: 8, + column: 2, + }; + + render() { + const col = []; + for (let i = 0; i < this.state.column; i++) { + col.push( +
Coloums-{i + 1}
+ ); + } + return ( +
+
+

gutter value

+ this.setState({gutter: v})} + /> +

column count

+ { + let temp = v; + if (v === 10) { + temp += 2; + } + this.setState({column: temp}); + }} + /> +
+ + {col} + +
+ ); + } +} diff --git a/docs/pages/components/Grid/demo/gridCustom.md b/docs/pages/components/Grid/demo/gridCustom.md new file mode 100644 index 0000000..9531f40 --- /dev/null +++ b/docs/pages/components/Grid/demo/gridCustom.md @@ -0,0 +1,2 @@ +#### 左右偏移 +`offset`可以将列`Col`向右侧偏移对应个数的`Col`。 \ No newline at end of file diff --git a/docs/pages/components/Grid/demo/gridCustom.tsx b/docs/pages/components/Grid/demo/gridCustom.tsx new file mode 100644 index 0000000..bb0984b --- /dev/null +++ b/docs/pages/components/Grid/demo/gridCustom.tsx @@ -0,0 +1,22 @@ +import * as React from 'react'; +import { Grid } from '@yoshino/components/'; + +const { Row, Col } = Grid; + +export default function() { + return ( +
+ + col-8 + col-8 + + + col-6 col-offset-6 + col-6 col-offset-6 + + + col-12 col-offset-6 + +
+ ); +} diff --git a/docs/pages/components/Grid/demo/gridDemo.md b/docs/pages/components/Grid/demo/gridDemo.md new file mode 100644 index 0000000..df322d5 --- /dev/null +++ b/docs/pages/components/Grid/demo/gridDemo.md @@ -0,0 +1,2 @@ +#### 基础栅格 +通过`Row`和`col`组件,并通过`Col`组件的`span`属性我们就可以自由地组合布局 \ No newline at end of file diff --git a/docs/pages/components/Grid/demo/gridDemo.tsx b/docs/pages/components/Grid/demo/gridDemo.tsx new file mode 100644 index 0000000..8865057 --- /dev/null +++ b/docs/pages/components/Grid/demo/gridDemo.tsx @@ -0,0 +1,26 @@ +import * as React from 'react'; +import { Grid } from '@yoshino/components/'; + +const { Row, Col } = Grid; + +export default function() { + return ( +
+ + col-12 + col-12 + + + col-8 + col-8 + col-8 + + + col-6 + col-6 + col-6 + col-6 + +
+ ); +} diff --git a/docs/pages/components/Grid/demo/gridFlex.md b/docs/pages/components/Grid/demo/gridFlex.md new file mode 100644 index 0000000..7903165 --- /dev/null +++ b/docs/pages/components/Grid/demo/gridFlex.md @@ -0,0 +1,2 @@ +#### Flex布局 +设置`type`为`flex`, 然后定义`justify`为`start`, `center`, `end`, `space-between`, `space-around`。 \ No newline at end of file diff --git a/docs/pages/components/Grid/demo/gridFlex.tsx b/docs/pages/components/Grid/demo/gridFlex.tsx new file mode 100644 index 0000000..9aa00e6 --- /dev/null +++ b/docs/pages/components/Grid/demo/gridFlex.tsx @@ -0,0 +1,50 @@ +import * as React from 'react'; +import { Grid } from '@yoshino/components/'; + +const { Row, Col } = Grid; + +export default function() { + return ( +
+

居左

+ + col-4 + col-4 + col-4 + col-4 + + +

居中

+ + col-4 + col-4 + col-4 + col-4 + + +

居右

+ + col-4 + col-4 + col-4 + col-4 + + +

均匀分布

+ + col-4 + col-4 + col-4 + col-4 + + +

散列分布

+ + col-4 + col-4 + col-4 + col-4 + +
+ ); +} diff --git a/docs/pages/components/Grid/demo/gridFlexOrder.md b/docs/pages/components/Grid/demo/gridFlexOrder.md new file mode 100644 index 0000000..03ed895 --- /dev/null +++ b/docs/pages/components/Grid/demo/gridFlexOrder.md @@ -0,0 +1,2 @@ +#### Flex排序 +设置`order`进行排序 \ No newline at end of file diff --git a/docs/pages/components/Grid/demo/gridFlexOrder.tsx b/docs/pages/components/Grid/demo/gridFlexOrder.tsx new file mode 100644 index 0000000..a9191d6 --- /dev/null +++ b/docs/pages/components/Grid/demo/gridFlexOrder.tsx @@ -0,0 +1,17 @@ +import * as React from 'react'; +import { Grid } from '@yoshino/components/'; + +const { Row, Col } = Grid; + +export default function() { + return ( +
+ + 1 col-order-4 + 2 col-order-3 + 3 col-order-2 + 4 col-order-1 + +
+ ); +} diff --git a/docs/pages/components/Grid/demo/gridFlexVertical.md b/docs/pages/components/Grid/demo/gridFlexVertical.md new file mode 100644 index 0000000..a9c54e3 --- /dev/null +++ b/docs/pages/components/Grid/demo/gridFlexVertical.md @@ -0,0 +1,2 @@ +#### Flex对齐 +通过设置`align`指定对齐方式。 \ No newline at end of file diff --git a/docs/pages/components/Grid/demo/gridFlexVertical.tsx b/docs/pages/components/Grid/demo/gridFlexVertical.tsx new file mode 100644 index 0000000..18cb5bc --- /dev/null +++ b/docs/pages/components/Grid/demo/gridFlexVertical.tsx @@ -0,0 +1,46 @@ +import * as React from 'react'; +import { Grid } from '@yoshino/components/'; + +const { Row, Col } = Grid; + +// tslint:disable no-any +const DemoBox = (props: any) => { + const style = { + height: props.value, + lineHeight: `${props.value}px`, + }; + + return ( +
{props.children}
+ ); +}; + +export default function() { + return ( +
+

向上对齐

+ + col-4 + col-4 + col-4 + col-4 + + +

居中对齐

+ + col-4 + col-4 + col-4 + col-4 + + +

底部对齐

+ + col-4 + col-4 + col-4 + col-4 + +
+ ); +} diff --git a/docs/pages/components/Grid/demo/gridOrder.md b/docs/pages/components/Grid/demo/gridOrder.md new file mode 100644 index 0000000..501a25e --- /dev/null +++ b/docs/pages/components/Grid/demo/gridOrder.md @@ -0,0 +1,2 @@ +#### 栅格排序 +通过`push`和`pull`进行栅格排序。 \ No newline at end of file diff --git a/docs/pages/components/Grid/demo/gridOrder.tsx b/docs/pages/components/Grid/demo/gridOrder.tsx new file mode 100644 index 0000000..0fa7450 --- /dev/null +++ b/docs/pages/components/Grid/demo/gridOrder.tsx @@ -0,0 +1,15 @@ +import * as React from 'react'; +import { Grid } from '@yoshino/components/'; + +const { Row, Col } = Grid; + +export default function() { + return ( +
+ + col-18 col-push-6 + col-6 col-pull-18 + +
+ ); +} diff --git a/docs/pages/components/Grid/demo/gridOther.md b/docs/pages/components/Grid/demo/gridOther.md new file mode 100644 index 0000000..2f40236 --- /dev/null +++ b/docs/pages/components/Grid/demo/gridOther.md @@ -0,0 +1,2 @@ +#### 其他属性 +嵌套在不同响应式布局中使用属性 \ No newline at end of file diff --git a/docs/pages/components/Grid/demo/gridOther.tsx b/docs/pages/components/Grid/demo/gridOther.tsx new file mode 100644 index 0000000..caf141a --- /dev/null +++ b/docs/pages/components/Grid/demo/gridOther.tsx @@ -0,0 +1,16 @@ +import * as React from 'react'; +import { Grid } from '@yoshino/components/'; + +const { Row, Col } = Grid; + +export default function() { + return ( +
+ + Col + Col + Col + +
+ ); +} diff --git a/docs/pages/components/Grid/index.less b/docs/pages/components/Grid/index.less new file mode 100644 index 0000000..2c0fcd5 --- /dev/null +++ b/docs/pages/components/Grid/index.less @@ -0,0 +1,54 @@ +@import '../../../../components/styles/var.less'; + +.yoshino-row > div { + text-align: center; + border-radius: 0; + margin-top: 8px; + margin-bottom: 8px; + color: #fff; + padding: 15px; +} + +.yoshino-row > div:nth-child(odd) { + background: @primary-color; + opacity: 0.8; +} + +.yoshino-row > div:nth-child(even) { + background: @primary-color; +} + +.grid-config { + .yoshino-row > div:nth-child(odd) { + background: none; + opacity: 1; + } + + .yoshino-row > div:nth-child(even) { + background: none; + } + + .yoshino-row > div > .columns { + padding: 10px 5px; + font-size: 12px; + + &:nth-child(odd) { + background: @primary-color; + opacity: 0.8; + } + + &:nth-child(even) { + background: @primary-color; + } + } + + .yoshino-row > div > div:nth-child(odd) { + background: @primary-color; + opacity: 0.8; + } + + .yoshino-row > div > div:nth-child(even) { + background: @primary-color; + } +} + diff --git a/docs/pages/components/Grid/index.md b/docs/pages/components/Grid/index.md new file mode 100644 index 0000000..0dd7c9e --- /dev/null +++ b/docs/pages/components/Grid/index.md @@ -0,0 +1,11 @@ +## Grid +`Grid`区域按照`24`等分的原则进行划分。 + +我们定义了两个概念,行row和列col,具体使用方法如下: +- 使用row在水平方向创建一行 +- 将一组col插入在row中 +- 在每个col中,键入自己的内容 +- 通过设置col的span参数,指定跨越的范围,其范围是1到24 +- 每个row中的col总和应该为24 + +## 代码演示 diff --git a/docs/pages/components/Grid/index.tsx b/docs/pages/components/Grid/index.tsx new file mode 100644 index 0000000..0eba4f5 --- /dev/null +++ b/docs/pages/components/Grid/index.tsx @@ -0,0 +1,68 @@ +import * as React from 'react'; +import { Component } from 'react'; +import * as md from './index.md'; +import Markdown from '@docs/components/Markdown/'; +import CodeBox from '@docs/components/CodeBox/'; +import ApiBox from '@docs/components/ApiBox/'; +import Api from './api'; + +import GridDemo from './demo/gridDemo'; +import * as gridDemoMd from './demo/gridDemo.md'; +const gridDemoCode = require('!raw-loader!./demo/gridDemo'); + +import GridCustom from './demo/gridCustom'; +import * as gridCustomMd from './demo/gridCustom.md'; +const gridCustomCode = require('!raw-loader!./demo/gridCustom'); + +import GridOrder from './demo/gridOrder'; +import * as gridOrderMd from './demo/gridOrder.md'; +const gridOrderCode = require('!raw-loader!./demo/gridOrder'); + +import GridFlex from './demo/gridFlex'; +import * as gridFlexMd from './demo/gridFlex.md'; +const gridFlexCode = require('!raw-loader!./demo/gridFlex'); + +import GridFlexVertical from './demo/gridFlexVertical'; +import * as gridFlexVerticalMd from './demo/gridFlexVertical.md'; +const gridFlexVerticalCode = require('!raw-loader!./demo/gridFlexVertical'); + +import GridFlexOrder from './demo/gridFlexOrder'; +import * as gridFlexOrderMd from './demo/gridFlexOrder.md'; +const gridFlexOrderCode = require('!raw-loader!./demo/gridFlexOrder'); + +import GridOther from './demo/gridOther'; +import * as gridOtherMd from './demo/gridOther.md'; +const gridOtherCode = require('!raw-loader!./demo/gridOther'); + +import GridConfig from './demo/gridConfig'; +import * as gridConfigMd from './demo/gridConfig.md'; +const gridConfigCode = require('!raw-loader!./demo/gridConfig'); + +import './index.less'; + +export default class GridPage extends Component { + render() { + return ( +
+ + } code={gridDemoCode}/> + + } code={gridCustomCode}/> + + } code={gridOrderCode}/> + + } code={gridFlexCode}/> + + } code={gridFlexVerticalCode}/> + + } code={gridFlexOrderCode}/> + + } code={gridOtherCode}/> + + } code={gridConfigCode}/> + + +
+ ); + } +} diff --git a/docs/pages/components/Slider/api.tsx b/docs/pages/components/Slider/api.tsx index 429ba50..5fc9c46 100644 --- a/docs/pages/components/Slider/api.tsx +++ b/docs/pages/components/Slider/api.tsx @@ -38,6 +38,12 @@ export default [ type: 'boolean', defaultValue: 'false', }, + { + props: 'step', + intro: '步长', + type: 'number', + defaultValue: '1', + }, ] } ]; diff --git a/docs/pages/components/Slider/demo/sliderCustom.tsx b/docs/pages/components/Slider/demo/sliderCustom.tsx index 1296e44..95d6287 100644 --- a/docs/pages/components/Slider/demo/sliderCustom.tsx +++ b/docs/pages/components/Slider/demo/sliderCustom.tsx @@ -12,6 +12,7 @@ export default class App extends React.Component { value={this.state.value} min={-100} max={100} + step={5} onChange={(value) => { console.log('当前值:', value); this.setState({value}); diff --git a/docs/pages/components/pageMenu.tsx b/docs/pages/components/pageMenu.tsx index a99b8b6..2fd34ce 100644 --- a/docs/pages/components/pageMenu.tsx +++ b/docs/pages/components/pageMenu.tsx @@ -17,6 +17,16 @@ export default [ }, ] }, + { + name: '布局', + keyId: 'layout', + children: [ + { + name: 'Grid(栅栏)', + keyId: 'grid', + }, + ] + }, { name: '交互', keyId: 'interaction', diff --git a/docs/pages/components/routes.tsx b/docs/pages/components/routes.tsx index d8ef3a6..730dba6 100644 --- a/docs/pages/components/routes.tsx +++ b/docs/pages/components/routes.tsx @@ -278,4 +278,10 @@ export default [ ), path: '/docs/components/color', }, + { + component: getComponentAsync( + () => import(/* webpackChunkName: "yoshino-grid" */ './Grid') + ), + path: '/docs/components/grid', + }, ]; diff --git a/package-lock.json b/package-lock.json index f0c90c0..659030a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3969,6 +3969,11 @@ "tapable": "1.0.0" } }, + "enquire.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/enquire.js/-/enquire.js-2.1.6.tgz", + "integrity": "sha1-PoeAybi4NQhMP2DhZtvDwqPImBQ=" + }, "entities": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", @@ -21060,23 +21065,23 @@ "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ==" }, "tslint": { - "version": "5.9.1", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.9.1.tgz", - "integrity": "sha1-ElX4ej/1frCw4fDmEKi0dIBGya4=", + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.11.0.tgz", + "integrity": "sha1-mPMMAurjzecAYgHkwzywi0hYHu0=", "dev": true, "requires": { "babel-code-frame": "6.26.0", "builtin-modules": "1.1.1", - "chalk": "2.3.2", - "commander": "2.15.0", + "chalk": "2.4.1", + "commander": "2.18.0", "diff": "3.5.0", "glob": "7.1.2", "js-yaml": "3.7.0", "minimatch": "3.0.4", - "resolve": "1.5.0", + "resolve": "1.8.1", "semver": "5.5.0", "tslib": "1.9.0", - "tsutils": "2.22.2" + "tsutils": "2.29.0" }, "dependencies": { "ansi-styles": { @@ -21089,20 +21094,20 @@ } }, "chalk": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", - "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "5.3.0" + "supports-color": "5.5.0" } }, "commander": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.0.tgz", - "integrity": "sha512-7B1ilBwtYSbetCgTY1NJFg+gVpestg0fdA1MhC1Vs4ssyfSXnCAjFr+QcQM9/RedXC0EaUx1sG8Smgw2VfgKEg==", + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz", + "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==", "dev": true }, "has-flag": { @@ -21112,22 +21117,31 @@ "dev": true }, "resolve": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", - "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", + "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", "dev": true, "requires": { "path-parse": "1.0.5" } }, "supports-color": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", - "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { "has-flag": "3.0.0" } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "1.9.0" + } } } }, @@ -21203,9 +21217,9 @@ "dev": true }, "typescript": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.8.3.tgz", - "integrity": "sha512-K7g15Bb6Ra4lKf7Iq2l/I5/En+hLIHmxWZGq3D4DIRNFxMNV6j2SHSvDOqs2tGd4UvD/fJvrwopzQXjLrT7Itw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.0.3.tgz", + "integrity": "sha512-kk80vLW9iGtjMnIv11qyxLqZm20UklzuR2tL0QAnDIygIUIemcZMxlMWudl9OOt76H3ntVzcTiddQ1/pAAJMYg==", "dev": true }, "ua-parser-js": { diff --git a/package.json b/package.json index f9123db..56f1784 100755 --- a/package.json +++ b/package.json @@ -73,6 +73,7 @@ "@types/react-dom": "^16.0.5", "@types/react-transition-group": "^2.0.8", "classnames": "*", + "enquire.js": "^2.1.6", "get-component-async": "^1.0.4", "ionicons": "^4.4.3", "postcss": "^6.0.21", @@ -133,9 +134,9 @@ "stylelint-config-standard": "^18.2.0", "ts-jest": "^22.4.4", "ts-loader": "^4.2.0", - "tslint": "^5.9.1", + "tslint": "^5.11.0", "tslint-react": "^3.5.1", - "typescript": "^2.8.3", + "typescript": "^3.0.3", "url-loader": "^1.0.1", "webpack": "^4.5.0", "webpack-cli": "^2.0.15",