优化select 多选代码

This commit is contained in:
catchonme 2019-05-27 12:22:01 +08:00
parent a65748cd54
commit 7e5e1e71cd
3 changed files with 43 additions and 62 deletions

View File

@ -156,13 +156,17 @@
user-select: none; user-select: none;
} }
&-checkall { &-checkAll {
padding: ( padding: (
$Form-select-menu-height - $Form-input-lineHeight * $Form-select-menu-height - $Form-input-lineHeight *
$Form-input-fontSize - px2rem(2px) $Form-input-fontSize - px2rem(2px)
)/2 $Form-select-paddingX; )/2 $Form-select-paddingX;
border-bottom: px2rem(1px) solid $Form-select-checkall-bottomBorder; border-bottom: px2rem(1px) solid $Form-select-checkall-bottomBorder;
min-width: px2rem(100px); min-width: px2rem(100px);
label {
display: block;
}
} }
&-option { &-option {
@ -187,10 +191,6 @@
background-color: $Form-select-menu-onDisabled-bg; background-color: $Form-select-menu-onDisabled-bg;
} }
&.is-checkAll {
border-bottom: px2rem(1px) solid $Form-select-checkall-bottomBorder;
}
&--placeholder { &--placeholder {
color: $Form-input-placeholderColor; color: $Form-input-placeholderColor;
} }

View File

@ -1,4 +1,3 @@
/** /**
* @file Checkbox * @file Checkbox
* @author fex * @author fex
@ -7,7 +6,7 @@
import * as React from 'react'; import * as React from 'react';
import * as cx from 'classnames'; import * as cx from 'classnames';
import {ClassNamesFn, themeable} from '../theme'; import {ClassNamesFn, themeable} from '../theme';
import { autobind } from '../utils/helper'; import {autobind} from '../utils/helper';
const sizeMap = { const sizeMap = {
sm: 'i-checks-sm', sm: 'i-checks-sm',
@ -25,7 +24,6 @@ interface CheckboxProps {
label?: string; label?: string;
className?: string; className?: string;
onChange?: (value: any) => void; onChange?: (value: any) => void;
onClick?: (e:any, checked:boolean) => void;
value?: any; value?: any;
containerClass?: string; containerClass?: string;
inline?: boolean; inline?: boolean;
@ -58,25 +56,6 @@ export class Checkbox extends React.Component<CheckboxProps, any> {
onChange(e.currentTarget.checked ? trueValue : falseValue); 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 || onClick && onClick(e, isChecked);
}
render() { render() {
let { let {
size, size,
@ -105,7 +84,6 @@ export class Checkbox extends React.Component<CheckboxProps, any> {
}, },
className className
)} )}
onClick={this.handleClick}
> >
<input <input
type={type} type={type}

View File

@ -188,6 +188,7 @@ export class Select extends React.Component<SelectProps, SelectState> {
input: HTMLInputElement; input: HTMLInputElement;
target: HTMLElement; target: HTMLElement;
menu: React.RefObject<HTMLDivElement> = React.createRef();
constructor(props: SelectProps) { constructor(props: SelectProps) {
super(props); super(props);
@ -252,7 +253,11 @@ export class Select extends React.Component<SelectProps, SelectState> {
}); });
} }
toggle() { toggle(e?: React.MouseEvent<HTMLDivElement>) {
if (e && this.menu.current && this.menu.current.contains(e.target as HTMLElement)) {
return;
}
this.props.disabled || this.props.disabled ||
this.setState({ this.setState({
isOpen: !this.state.isOpen, isOpen: !this.state.isOpen,
@ -336,7 +341,7 @@ export class Select extends React.Component<SelectProps, SelectState> {
} }
handleChange(selectItem: any) { handleChange(selectItem: any) {
const {onChange, multiple, onNewOptionClick, checkAll} = this.props; const {onChange, multiple, onNewOptionClick} = this.props;
let {selection} = this.state; let {selection} = this.state;
if (selectItem.isNew) { if (selectItem.isNew) {
@ -345,18 +350,14 @@ export class Select extends React.Component<SelectProps, SelectState> {
} }
if (multiple) { if (multiple) {
if (checkAll && selectItem.__all) { selection = selection.concat();
this.toggleCheckAll(); const idx = selection.indexOf(selectItem);
if (~idx) {
selection.splice(idx, 1);
} else { } else {
selection = selection.concat(); selection.push(selectItem);
const idx = selection.indexOf(selectItem);
if (~idx) {
selection.splice(idx, 1);
} else {
selection.push(selectItem);
}
onChange(selection);
} }
onChange(selection);
} else { } else {
onChange(selectItem); onChange(selectItem);
} }
@ -471,7 +472,6 @@ export class Select extends React.Component<SelectProps, SelectState> {
if (multiple) { if (multiple) {
if (checkAll) { if (checkAll) {
filtedOptions.unshift({label: checkAllLabel, value: 'all', __all: true});
const optionsValues = options.map(option => option.value); const optionsValues = options.map(option => option.value);
const selectionValues = selection.map(select => select.value); const selectionValues = selection.map(select => select.value);
checkedAll = optionsValues.every(option => selectionValues.indexOf(option) > -1); checkedAll = optionsValues.every(option => selectionValues.indexOf(option) > -1);
@ -499,7 +499,18 @@ export class Select extends React.Component<SelectProps, SelectState> {
} }
const menu = ( const menu = (
<div className={cx('Select-menu')}> <div ref={this.menu} className={cx('Select-menu')}>
{multiple && checkAll ? (
<div className={cx('Select-checkAll')}>
<Checkbox
checked={checkedPartial}
partial={checkedPartial && !checkedAll}
onChange={this.toggleCheckAll}
>
{checkAllLabel}
</Checkbox>
</div>
) : null}
{filtedOptions.length ? ( {filtedOptions.length ? (
filtedOptions.map((item, index) => { filtedOptions.map((item, index) => {
const checked = checkAll ? selection.some((o:Option) => o.value == item.value) : false; const checked = checkAll ? selection.some((o:Option) => o.value == item.value) : false;
@ -515,31 +526,23 @@ export class Select extends React.Component<SelectProps, SelectState> {
className={cx(`Select-option`, { className={cx(`Select-option`, {
'is-disabled': item.disabled, 'is-disabled': item.disabled,
'is-highlight': highlightedIndex === index, 'is-highlight': highlightedIndex === index,
'is-checkAll': checkAll && index === 0,
'is-active': 'is-active':
selectedItem === item || selectedItem === item ||
(Array.isArray(selectedItem) && ~selectedItem.indexOf(item)), (Array.isArray(selectedItem) && ~selectedItem.indexOf(item)),
})} })}
> >
{checkAll ? {checkAll ? (
index === 0 ? ( <Checkbox
<Checkbox checked={checked}
checked={checkedPartial} trueValue={item.value}
partial={checkedPartial && !checkedAll} onChange={() => this.handleChange(item)}
> >
{checkAllLabel} {item.isNew
</Checkbox> ? promptTextCreator(item.label as string)
) : ( : item.disabled
<Checkbox ? item[labelField]
checked={checked} : highlight(item[labelField], inputValue as string, cx('Select-option-hl'))}
trueValue={item.value} </Checkbox>
>
{item.isNew
? promptTextCreator(item.label as string)
: item.disabled
? item[labelField]
: highlight(item[labelField], inputValue as string, cx('Select-option-hl'))}
</Checkbox>
) : ( ) : (
item.isNew item.isNew
? promptTextCreator(item.label as string) ? promptTextCreator(item.label as string)