diff --git a/docs/renderers/Range.md b/docs/renderers/Range.md index f1204233a..d2be0aa0e 100644 --- a/docs/renderers/Range.md +++ b/docs/renderers/Range.md @@ -6,6 +6,9 @@ - `min` 最小值 - `max` 最大值 - `step` 步长 +- `multiple` 支持选择范围,默认为`false` +- `joinValuse` 默认为 `true`,选择的 `value` 会通过 `delimiter` 连接起来,否则直接将以`{min: 1, max: 100}`的形式提交,开启`multiple`时有效 +- `delimiter` 默认为 `,` ```schema:height="400" scope="form-item" { diff --git a/docs/renderers/Select.md b/docs/renderers/Select.md index b3465bcb0..564c471d2 100644 --- a/docs/renderers/Select.md +++ b/docs/renderers/Select.md @@ -16,6 +16,9 @@ - `delimiter` 默认为 `,` - `clearable` 默认为 `false`, 当设置为 `true` 时,已选中的选项右侧会有个小 `X` 用来取消设置。 - `searchable` 默认为 `false`,表示可以通过输入部分内容检索出选项。 +- `checkall` 默认为 `false` 开启后支持全选 +- `checkAllLabel` 默认为 `全选`, 全选的文字 +- `defaultCheckAll` 是否默认全选,默认为`false` - 更多配置请参考 [FormItem](./FormItem.md) 单选 diff --git a/scss/_variables.scss b/scss/_variables.scss index 5e4b78d3a..02f66de17 100644 --- a/scss/_variables.scss +++ b/scss/_variables.scss @@ -675,6 +675,7 @@ $Form-select-menu-onActive-color: $info !default; $Form-select-menu-onActive-bg: transparent !default; $Form-select-menu-onDisabled-color: $text--muted-color !default; $Form-select-menu-onDisabled-bg: transparent !default; +$Form-select-checkall-bottomBorder: #eceff8 !default; // InputGroup $InputGroup-height: $Form-input-height !default; diff --git a/scss/components/form/_range.scss b/scss/components/form/_range.scss index 38bceefb2..c358e9a73 100644 --- a/scss/components/form/_range.scss +++ b/scss/components/form/_range.scss @@ -13,12 +13,17 @@ .#{$ns}InputRange-label--mid { left: calc(50% - 60px); } + + &.is-multiple { + .#{$ns}InputRange { + width: calc(100% - 210px); + } + } } .#{$ns}InputRange { &-input { font-size: $fontSizeSm; - width: px2rem(74px); position: absolute; right: px2rem(26px); top: px2rem(12px); @@ -26,7 +31,7 @@ input { padding: px2rem(10px); - width: 100%; + width: px2rem(74px); height: 100%; &:focus { @@ -34,6 +39,11 @@ border: $borderWidth solid $info; } } + + &-separator { + display: inline-block; + padding: 0 5px; + } } &-unit { @@ -167,6 +177,10 @@ .#{$ns}InputRange.is-disabled & { background: $InputRange-track-onDisabled-bg; } + + &.is-active { + background: $InputRange-track-onActive-bg; + } } &-track--background { diff --git a/scss/components/form/_select.scss b/scss/components/form/_select.scss index 13e760c82..8e63eab0c 100644 --- a/scss/components/form/_select.scss +++ b/scss/components/form/_select.scss @@ -156,7 +156,17 @@ user-select: none; } + &-checkall { + padding: ( + $Form-select-menu-height - $Form-input-lineHeight * + $Form-input-fontSize - px2rem(2px) + )/2 $Form-select-paddingX; + border-bottom: px2rem(1px) solid $Form-select-checkall-bottomBorder; + min-width: px2rem(100px); + } + &-option { + min-width: px2rem(100px); padding: ( $Form-select-menu-height - $Form-input-lineHeight * $Form-input-fontSize - px2rem(2px) @@ -177,6 +187,10 @@ background-color: $Form-select-menu-onDisabled-bg; } + &.is-checkAll { + border-bottom: px2rem(1px) solid $Form-select-checkall-bottomBorder; + } + &--placeholder { color: $Form-input-placeholderColor; } diff --git a/src/components/Checkbox.tsx b/src/components/Checkbox.tsx index dadf9851a..5243863c8 100644 --- a/src/components/Checkbox.tsx +++ b/src/components/Checkbox.tsx @@ -1,3 +1,4 @@ + /** * @file Checkbox * @author fex @@ -6,6 +7,7 @@ import * as React from 'react'; import * as cx from 'classnames'; import {ClassNamesFn, themeable} from '../theme'; +import { autobind } from '../utils/helper'; const sizeMap = { sm: 'i-checks-sm', @@ -23,6 +25,7 @@ interface CheckboxProps { label?: string; className?: string; onChange?: (value: any) => void; + onClick?: (e:any, checked:boolean) => void; value?: any; containerClass?: string; inline?: boolean; @@ -44,13 +47,8 @@ export class Checkbox extends React.Component { type: 'checkbox', }; - constructor(props: CheckboxProps) { - super(props); - - this.hanldeCheck = this.hanldeCheck.bind(this); - } - - hanldeCheck(e: React.ChangeEvent) { + @autobind + handleCheck(e: React.ChangeEvent) { const {trueValue, falseValue, onChange} = this.props; if (!onChange) { @@ -60,6 +58,25 @@ export class Checkbox extends React.Component { onChange(e.currentTarget.checked ? trueValue : falseValue); } + @autobind + handleClick(e:any) { + const { + checked, + value, + trueValue, + onClick, + disabled + } = this.props; + + const isChecked:boolean = !!(typeof checked !== 'undefined' + ? checked + : typeof value === 'undefined' + ? value + : value == trueValue); + + disabled ? null : onClick && onClick(e, isChecked); + } + render() { let { size, @@ -88,6 +105,7 @@ export class Checkbox extends React.Component { }, className )} + onClick={this.handleClick} > { ? value : value == trueValue } - onChange={this.hanldeCheck} + onChange={this.handleCheck} disabled={disabled} readOnly={readOnly} name={name} @@ -110,4 +128,4 @@ export class Checkbox extends React.Component { } } -export default themeable(Checkbox); +export default themeable(Checkbox); \ No newline at end of file diff --git a/src/components/Range.tsx b/src/components/Range.tsx index a090beae8..f97dc7ed8 100644 --- a/src/components/Range.tsx +++ b/src/components/Range.tsx @@ -16,7 +16,10 @@ interface RangeProps extends RendererProps { className?: string; min: number; max: number; - value?: number; + value: { + min: number, + max: number + } | number; classPrefix: string; classnames: ClassNamesFn; } @@ -28,10 +31,10 @@ export class Range extends React.Component { }; render() { - const {min, max, value, className, classPrefix: ns} = this.props; + const {min, max, value, className, classPrefix: ns, multiple} = this.props; const classNames = { - activeTrack: `${ns}InputRange-track is-active`, + activeTrack: multiple ? `${ns}InputRange-track is-active` : `${ns}InputRange-track`, disabledInputRange: `${ns}InputRange is-disabled`, inputRange: `${ns}InputRange`, labelContainer: `${ns}InputRange-labelContainer`, @@ -50,7 +53,8 @@ export class Range extends React.Component { classNames={classNames} minValue={min} maxValue={max} - value={typeof value === 'number' ? value : min} + value={value} + multiple={multiple} /> ); } diff --git a/src/components/Select.tsx b/src/components/Select.tsx index b5c6ca774..92f500fcd 100644 --- a/src/components/Select.tsx +++ b/src/components/Select.tsx @@ -14,12 +14,14 @@ import Downshift, {ControllerStateAndHelpers} from 'downshift'; import * as cx from 'classnames'; import {closeIcon} from './icons'; import * as matchSorter from 'match-sorter'; -import {noop, anyChanged} from '../utils/helper'; +import {noop} from '../utils/helper'; import find = require('lodash/find'); import isPlainObject = require('lodash/isPlainObject'); +import union = require('lodash/union'); import {highlight} from '../renderers/Form/Options'; import {findDOMNode} from 'react-dom'; import {ClassNamesFn, themeable} from '../theme'; +import Checkbox from './Checkbox'; export interface Option { label?: string; @@ -64,7 +66,7 @@ export function value2array(value: OptionValue | Array, props: Part } else if (Array.isArray(value)) { value = value[0]; } - + let expandedValue = expandValue(value as OptionValue, props); return expandedValue ? [expandedValue] : []; } @@ -148,6 +150,9 @@ interface SelectProps { onNewOptionClick: (value: Option) => void; onFocus?: Function; onBlur?: Function; + checkAll?: boolean; + checkAllLabel?: string; + defaultCheckAll?: boolean; } interface SelectState { @@ -156,6 +161,8 @@ interface SelectState { inputValue: string; highlightedIndex: number; selection: Array