diff --git a/scss/_variables.scss b/scss/_variables.scss index 8f488e10..b59fc382 100644 --- a/scss/_variables.scss +++ b/scss/_variables.scss @@ -1351,4 +1351,11 @@ $Carousel--light-control: white !default; $Carousel--dark-control: black !default; $Carousel-transitionDuration: 0.3s !default; $Carousel-imageTitle-bottom: px2rem(45px) !default; -$Carousel-imageDescription-bottom: px2rem(25px) !default; \ No newline at end of file +$Carousel-imageDescription-bottom: px2rem(25px) !default; + +// Picker +$Picker-iconColor: $gray600 !default; +$Picker-onHover-iconColor: darken($Picker-iconColor, 10%) !default; +$Picker-btn-vendor: "FontAwesome" !default; +$Picker-btn-fontSize: $Form-fontSize !default; +$Picker-btn-icon: "\f2d2" !default; \ No newline at end of file diff --git a/scss/components/form/_picker.scss b/scss/components/form/_picker.scss index 3609dcc5..c87a0ba0 100644 --- a/scss/components/form/_picker.scss +++ b/scss/components/form/_picker.scss @@ -1,17 +1,55 @@ .#{$ns}Picker { - &-values { - display: inline-block; - margin-top: -$gap-xs; - padding: ( - $Form-input-height - $Form-input-lineHeight * - $Form-input-fontSize - px2rem(2px) - )/2 0; + @include input-text(); + outline: none; + + &.is-focus > &-input { + border-color: $Form-input-onFocused-borderColor; + box-shadow: $Form-input-boxShadow; + + @if $Form-input-onFocused-bg !=$Form-input-bg { + background-color: $Form-input-onFocused-bg; + } } - &-value { + &-placeholder { + color: $Form-input-placeholderColor; + user-select: none; + position: absolute; + // margin-top: 2 * $Form-input-borderWidth; + line-height: $Form-input-lineHeight; + } + + &-input { + min-height: $Form-input-height; + height: auto; + } + + .#{$ns}Picker-values { + display: inline; + } + + &-valueWrap { + flex-grow: 1; + position: relative; + + > input { + width: 1rem; + display: inline-block; + } + } + + .#{$ns}Picker-valueWrap { + margin-bottom: -$gap-xs; + line-height: 1; + } + + .#{$ns}Picker-value { cursor: pointer; user-select: none; - line-height: $Form-input-lineHeight * $Form-input-fontSize - px2rem(2px); + white-space: nowrap; + vertical-align: middle; + line-height: $Form-input-lineHeight * $Form-input-fontSize - + px2rem(2px); display: inline-block; font-size: $Form-selectValue-fontSize; color: $Form-selectValue-color; @@ -19,11 +57,7 @@ border: px2rem(1px) solid $Form-selectValue-borderColor; border-radius: 2px; margin-right: $gap-xs; - margin-top: $gap-xs; - - &:hover { - background-color: darken($Form-selectValue-bg, 5%); - } + margin-bottom: $gap-xs; &.is-disabled { pointer-events: none; @@ -31,7 +65,7 @@ } } - &-valueIcon { + .#{$ns}Picker-valueIcon { cursor: pointer; border-right: px2rem(1px) solid $Form-selectValue-borderColor; padding: 1px 5px; @@ -41,9 +75,34 @@ } } - &-valueLabel { + .#{$ns}Picker-valueLabel { padding: 0 $gap-xs; } + + &-btn { + cursor: pointer; + color: $Picker-iconColor; + + &:hover { + color: $Picker-onHover-iconColor; + } + + &:before { + line-height: 1; + color: inherit; + content: $Picker-btn-icon; + display: inline-block; + font-size: $Picker-btn-fontSize; + font-family: $Picker-btn-vendor; + } + } + + &-clear { + display: inline-block; + @include input-clear(); + line-height: 1; + margin-right: $gap-xs; + } } .#{$ns}PickerControl { diff --git a/src/renderers/Form/Picker.tsx b/src/renderers/Form/Picker.tsx index 725e04f3..866103c4 100644 --- a/src/renderers/Form/Picker.tsx +++ b/src/renderers/Form/Picker.tsx @@ -12,10 +12,11 @@ import { Action } from '../../types'; import find = require('lodash/find'); -import {anyChanged, autobind, getVariable} from '../../utils/helper'; +import {anyChanged, autobind, getVariable, noop} from '../../utils/helper'; import findIndex = require('lodash/findIndex'); import Html from '../../components/Html'; import { filter } from '../../utils/tpl'; +import { closeIcon } from '../../components/icons'; export interface PickerProps extends OptionsControlProps { modalMode: 'dialog' | 'drawer'; @@ -25,6 +26,7 @@ export interface PickerProps extends OptionsControlProps { export interface PickerState { isOpened: boolean; + isFocused: boolean; schema: SchemaNode; }; @@ -39,6 +41,7 @@ export default class PickerControl extends React.PureComponent "inline", "multiple", "embed", + "resetValue" ]; static defaultProps: Partial = { modalMode: 'dialog', @@ -54,9 +57,12 @@ export default class PickerControl extends React.PureComponent state: PickerState = { isOpened: false, - schema: this.buildSchema(this.props) + schema: this.buildSchema(this.props), + isFocused: false }; + input: React.RefObject = React.createRef(); + componentWillReceiveProps(nextProps: PickerProps) { const props = this.props; @@ -169,6 +175,46 @@ export default class PickerControl extends React.PureComponent onChange(value); } + @autobind + handleKeyPress(e:React.KeyboardEvent) { + const selectedOptions = this.props.selectedOptions; + + if (e.key === ' ') { + this.open(); + } else if (selectedOptions.length && e.key == "Backspace") { + this.removeItem(selectedOptions.length - 1); + } + } + + @autobind + handleFocus() { + this.setState({ + isFocused: true + }); + } + + @autobind + handleBlur() { + this.setState({ + isFocused: false + }); + } + + @autobind + handleClick() { + this.input.current && this.input.current.focus(); + } + + @autobind + clearValue() { + const { + onChange, + resetValue + } = this.props; + + onChange(resetValue !== void 0 ? resetValue : '') + } + renderValues() { const { classPrefix: ns, @@ -218,39 +264,55 @@ export default class PickerControl extends React.PureComponent render() { const { className, - classPrefix: ns, + classnames: cx, disabled, render, modalMode, source, size, env, - embed + clearable, + multiple, + inline, + embed, + value } = this.props; return ( -
+
{embed ? ( -
+
{this.renderBody()}
) : ( -
- {this.renderValues()} +
+
+
+ {this.renderValues()} + + +
- + {clearable && !disabled && value && value.length ? ({closeIcon}) : null} + +
+ + {render('modal', { title: '请选择', size: size, @@ -266,6 +328,38 @@ export default class PickerControl extends React.PureComponent show: this.state.isOpened })}
+ //
+ // {this.renderValues()} + + // + + // {render('modal', { + // title: '请选择', + // size: size, + // type: modalMode, + // body: { + // children: this.renderBody + // } + // }, { + // key: 'modal', + // lazyRender: !!source, + // onConfirm: this.handleModalConfirm, + // onClose: this.close, + // show: this.state.isOpened + // })} + //
)}
);